├── .gitignore ├── src ├── components │ ├── game │ │ ├── index.js │ │ ├── GameArea.jsx │ │ └── Engine.js │ ├── blocky │ │ ├── index.jsx │ │ ├── custom │ │ │ ├── playerX │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── playerY │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── canvasWidth │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── canvasHeight │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── gameEndGame │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── overWrite.js │ │ │ ├── gameTarget │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── gameObstacle │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── playerDeadDuck │ │ │ │ ├── index.js │ │ │ │ └── definition.js │ │ │ ├── setPlayerIcon │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── textSize │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── gameMoveTargetX │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── gameMoveTargetY │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── gameMoveObstacleX │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── gameMoveObstacleY │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── canvasSetTextColor │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── backgroundColor │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── gameSetPlayerPositionX │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── gameSetPlayerPositionY │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── playerDuck │ │ │ │ ├── index.js │ │ │ │ └── definition.js │ │ │ ├── playerChicken │ │ │ │ ├── index.js │ │ │ │ └── definition.js │ │ │ ├── playerDeadChicken │ │ │ │ ├── index.js │ │ │ │ └── definition.js │ │ │ ├── canvasSetTextAlign │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── canvasSetCursor │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── gameSetPlayerPosition │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── canvasDrawRectangle │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ ├── gameSetup │ │ │ │ ├── definition.js │ │ │ │ └── index.js │ │ │ └── index.js │ │ ├── initialize.js │ │ ├── BlocklyEditor.jsx │ │ └── toolbox.js │ ├── Wrapper.jsx │ ├── ContentWrapper.jsx │ ├── Navigator.jsx │ └── Settings.jsx ├── WorkspaceContext.js ├── constants.js ├── utils │ └── debounce.js ├── main.jsx ├── favicon.svg ├── App.jsx ├── logo.svg └── index.css ├── public └── images │ ├── duck.png │ ├── chicken.png │ ├── deadDuck.png │ ├── deadChicken.png │ ├── deadDuck.svg │ ├── duck.svg │ ├── chicken.svg │ └── deadChicken.svg ├── README.md ├── vite.config.js ├── index.html ├── package.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local -------------------------------------------------------------------------------- /src/components/game/index.js: -------------------------------------------------------------------------------- 1 | export { GameArea } from './GameArea'; 2 | -------------------------------------------------------------------------------- /src/components/blocky/index.jsx: -------------------------------------------------------------------------------- 1 | export { BlocklyEditor } from './BlocklyEditor'; 2 | -------------------------------------------------------------------------------- /public/images/duck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/blockly-game-creator/main/public/images/duck.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # blockly game creator 2 | 3 | A blockly based game engine for teaching entry level coding classes 4 | -------------------------------------------------------------------------------- /public/images/chicken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/blockly-game-creator/main/public/images/chicken.png -------------------------------------------------------------------------------- /public/images/deadDuck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/blockly-game-creator/main/public/images/deadDuck.png -------------------------------------------------------------------------------- /public/images/deadChicken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/blockly-game-creator/main/public/images/deadChicken.png -------------------------------------------------------------------------------- /src/WorkspaceContext.js: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | export const WorkspaceContext = createContext(); 4 | -------------------------------------------------------------------------------- /src/components/Wrapper.jsx: -------------------------------------------------------------------------------- 1 | export const Wrapper = ({ children }) => { 2 | return
{children}
; 3 | }; 4 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | export const PAGE_CODE = 0; 2 | export const PAGE_MIX = 1; 3 | export const PAGE_APP = 2; 4 | export const PAGE_SETTINGS = 3; 5 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerX/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'player_x', 3 | message0: 'PLAYER_X', 4 | output: null, 5 | colour: '#FFAABB', 6 | tooltip: '', 7 | helpUrl: '', 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerY/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'player_y', 3 | message0: 'PLAYER_Y', 4 | output: null, 5 | colour: '#FFAABB', 6 | tooltip: '', 7 | helpUrl: '', 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasWidth/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'canvas_width', 3 | message0: 'CANVAS_WIDTH', 4 | output: null, 5 | colour: '#6600cc', 6 | tooltip: '', 7 | helpUrl: '', 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasHeight/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'canvas_height', 3 | message0: 'CANVAS_HEIGHT', 4 | output: null, 5 | colour: '#6600cc', 6 | tooltip: '', 7 | helpUrl: '', 8 | }; 9 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | base: '/blockly-player/', 8 | }); 9 | -------------------------------------------------------------------------------- /src/utils/debounce.js: -------------------------------------------------------------------------------- 1 | export function debounce(func, timeout = 300) { 2 | let timer; 3 | return (...args) => { 4 | clearTimeout(timer); 5 | timer = setTimeout(() => { 6 | func.apply(this, args); 7 | }, timeout); 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameEndGame/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'game_end_game', 3 | message0: 'end game', 4 | previousStatement: null, 5 | nextStatement: null, 6 | colour: '#FFAABB', 7 | tooltip: '', 8 | helpUrl: '', 9 | }; 10 | -------------------------------------------------------------------------------- /src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import './index.css' 4 | import App from './App' 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById('root') 11 | ) 12 | -------------------------------------------------------------------------------- /src/components/blocky/custom/overWrite.js: -------------------------------------------------------------------------------- 1 | export function overWrite(Blockly) { 2 | Blockly.JavaScript['text_print'] = function (block) { 3 | const msg = Blockly.JavaScript.valueToCode(block, 'TEXT', Blockly.JavaScript.ORDER_NONE) || "''"; 4 | return `engine.writeText(${msg});\n`; 5 | }; 6 | } 7 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameTarget/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: "game_target", 3 | message0: "Target %1", 4 | args0: [ 5 | { 6 | type: "input_statement", 7 | name: "target", 8 | }, 9 | ], 10 | previousStatement: null, 11 | nextStatement: null, 12 | colour: "#FFAABB", 13 | tooltip: "", 14 | helpUrl: "", 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameObstacle/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'game_obstacle', 3 | message0: 'Obstacle %1', 4 | args0: [ 5 | { 6 | type: 'input_statement', 7 | name: 'obstacle', 8 | }, 9 | ], 10 | previousStatement: null, 11 | nextStatement: null, 12 | colour: '#FFAABB', 13 | tooltip: '', 14 | helpUrl: '', 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerDeadDuck/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from "./definition"; 2 | export const playerDeadDuck = (Blockly) => { 3 | Blockly.Blocks["game_dead_duck"] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | Blockly.JavaScript["game_dead_duck"] = function (block) { 9 | return "PLAYER_DEAD_DUCK"; 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameEndGame/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | 3 | export const gameEndGame = (Blockly) => { 4 | Blockly.Blocks['game_end_game'] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript['game_end_game'] = function (block) { 10 | return `engine.endGame();\n`; 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /src/components/blocky/custom/setPlayerIcon/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: "game_set_player_icon", 3 | message0: "set player icon %1", 4 | args0: [ 5 | { 6 | type: "input_statement", 7 | name: "playerIcon", 8 | }, 9 | ], 10 | previousStatement: null, 11 | nextStatement: null, 12 | colour: "#FFAABB", 13 | tooltip: "", 14 | helpUrl: "", 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/blocky/custom/textSize/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'canvas_text_size', 3 | message0: 'Text size %1', 4 | args0: [ 5 | { 6 | type: 'input_value', 7 | name: 'textSize', 8 | check: 'Number', 9 | }, 10 | ], 11 | previousStatement: null, 12 | nextStatement: null, 13 | colour: '#6600cc', 14 | tooltip: '', 15 | helpUrl: '', 16 | }; 17 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameMoveTargetX/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: "game_move_target_x", 3 | message0: "move target x %1", 4 | args0: [ 5 | { 6 | type: "input_value", 7 | name: "x", 8 | check: "Number", 9 | }, 10 | ], 11 | previousStatement: null, 12 | nextStatement: null, 13 | colour: "#FFAABB", 14 | tooltip: "", 15 | helpUrl: "", 16 | }; 17 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameMoveTargetY/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: "game_move_target_y", 3 | message0: "move target y %1", 4 | args0: [ 5 | { 6 | type: "input_value", 7 | name: "y", 8 | check: "Number", 9 | }, 10 | ], 11 | previousStatement: null, 12 | nextStatement: null, 13 | colour: "#FFAABB", 14 | tooltip: "", 15 | helpUrl: "", 16 | }; 17 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameMoveObstacleX/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'game_move_obstacle_x', 3 | message0: 'move obstacle x %1', 4 | args0: [ 5 | { 6 | type: 'input_value', 7 | name: 'x', 8 | check: 'Number', 9 | }, 10 | ], 11 | previousStatement: null, 12 | nextStatement: null, 13 | colour: '#FFAABB', 14 | tooltip: '', 15 | helpUrl: '', 16 | }; 17 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameMoveObstacleY/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'game_move_obstacle_y', 3 | message0: 'move obstacle y %1', 4 | args0: [ 5 | { 6 | type: 'input_value', 7 | name: 'y', 8 | check: 'Number', 9 | }, 10 | ], 11 | previousStatement: null, 12 | nextStatement: null, 13 | colour: '#FFAABB', 14 | tooltip: '', 15 | helpUrl: '', 16 | }; 17 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasSetTextColor/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'canvas_set_text_color', 3 | message0: 'text color %1', 4 | args0: [ 5 | { 6 | type: 'input_value', 7 | name: 'textColor', 8 | check: 'Colour', 9 | }, 10 | ], 11 | previousStatement: null, 12 | nextStatement: null, 13 | colour: '#6600cc', 14 | tooltip: '', 15 | helpUrl: '', 16 | }; 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blocky-app", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview --host" 8 | }, 9 | "dependencies": { 10 | "blockly": "^6.20210701.0", 11 | "react": "^17.0.0", 12 | "react-dom": "^17.0.0" 13 | }, 14 | "devDependencies": { 15 | "@vitejs/plugin-react": "^1.0.0", 16 | "vite": "^2.6.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/components/blocky/custom/backgroundColor/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'canvas_background_color', 3 | message0: 'background color %1', 4 | args0: [ 5 | { 6 | type: 'input_value', 7 | name: 'backgroundColor', 8 | check: 'Colour', 9 | }, 10 | ], 11 | previousStatement: null, 12 | nextStatement: null, 13 | colour: '#6600cc', 14 | tooltip: '', 15 | helpUrl: '', 16 | }; 17 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameSetPlayerPositionX/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: "game_set_player_position_x", 3 | message0: "Set Player position X %1", 4 | args0: [ 5 | { 6 | type: "input_value", 7 | name: "x", 8 | check: "Number", 9 | }, 10 | ], 11 | colour: "#FFAABB", 12 | tooltip: "", 13 | helpUrl: "", 14 | previousStatement: null, 15 | nextStatement: null, 16 | }; 17 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameSetPlayerPositionY/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: "game_set_player_position_y", 3 | message0: "Set Player position Y %1", 4 | args0: [ 5 | { 6 | type: "input_value", 7 | name: "y", 8 | check: "Number", 9 | }, 10 | ], 11 | colour: "#FFAABB", 12 | tooltip: "", 13 | helpUrl: "", 14 | previousStatement: null, 15 | nextStatement: null, 16 | }; 17 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerDuck/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | export const playerDuck = (Blockly) => { 3 | Blockly.Blocks['game_duck'] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | Blockly.JavaScript['game_duck'] = function (block) { 9 | // TODO: Assemble JavaScript into code variable. 10 | var code = 'PLAYER_DUCK'; 11 | return code; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerChicken/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | export const playerChicken = (Blockly) => { 3 | Blockly.Blocks['game_chicken'] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | Blockly.JavaScript['game_chicken'] = function (block) { 9 | // TODO: Assemble JavaScript into code variable. 10 | var code = 'PLAYER_CHICKEN'; 11 | return code; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /src/components/ContentWrapper.jsx: -------------------------------------------------------------------------------- 1 | import { PAGE_APP, PAGE_CODE, PAGE_MIX, PAGE_SETTINGS } from '../constants'; 2 | 3 | export const ContentWrapper = ({ children, currentPage }) => { 4 | const classMap = { 5 | [PAGE_APP]: 'is-app', 6 | [PAGE_CODE]: 'is-code', 7 | [PAGE_MIX]: 'is-mix', 8 | [PAGE_SETTINGS]: 'is-settings', 9 | }; 10 | let className = `content-wrapper ${classMap[currentPage]}`; 11 | return
{children}
; 12 | }; 13 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerChicken/definition.js: -------------------------------------------------------------------------------- 1 | import src from '/images/chicken.png'; 2 | 3 | export const definition = { 4 | type: 'game_chicken', 5 | message0: 'Chicken %1', 6 | args0: [ 7 | { 8 | type: 'field_image', 9 | src, 10 | width: 40, 11 | height: 40, 12 | alt: 'chicken', 13 | flipRtl: false, 14 | }, 15 | ], 16 | colour: '#FFAABB', 17 | tooltip: '', 18 | helpUrl: '', 19 | previousStatement: null, 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerDeadChicken/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from "./definition"; 2 | export const playerDeadChicken = (Blockly) => { 3 | Blockly.Blocks["game_dead_chicken"] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | Blockly.JavaScript["game_dead_chicken"] = function (block) { 9 | // TODO: Assemble JavaScript into code variable. 10 | var code = "PLAYER_DEAD_CHICKEN"; 11 | return code; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerDuck/definition.js: -------------------------------------------------------------------------------- 1 | import duckImage from "/images/duck.svg"; 2 | 3 | export const definition = { 4 | type: "game_duck", 5 | message0: "Duck %1", 6 | args0: [ 7 | { 8 | type: "field_image", 9 | src: duckImage, 10 | width: 40, 11 | height: 40, 12 | alt: "duck", 13 | flipRtl: false, 14 | }, 15 | ], 16 | colour: "#FFAABB", 17 | tooltip: "", 18 | helpUrl: "", 19 | previousStatement: null, 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/blocky/custom/setPlayerIcon/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from "./definition"; 2 | export const setPlayerIcon = (Blockly) => { 3 | Blockly.Blocks["game_set_player_icon"] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | 9 | Blockly.JavaScript["game_set_player_icon"] = function (block) { 10 | const avatar = Blockly.JavaScript.statementToCode(block, "playerIcon"); 11 | return `engine.setAvatar(${avatar});\n`; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerDeadChicken/definition.js: -------------------------------------------------------------------------------- 1 | import src from "/images/deadChicken.svg"; 2 | 3 | export const definition = { 4 | type: "game_dead_chicken", 5 | message0: "Dead Chicken %1", 6 | args0: [ 7 | { 8 | type: "field_image", 9 | src, 10 | width: 40, 11 | height: 40, 12 | alt: "dead chicken", 13 | flipRtl: false, 14 | }, 15 | ], 16 | colour: "#FFAABB", 17 | tooltip: "", 18 | helpUrl: "", 19 | previousStatement: null, 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerDeadDuck/definition.js: -------------------------------------------------------------------------------- 1 | import duckImage from "/images/deadDuck.svg"; 2 | 3 | export const definition = { 4 | type: "game_dead_duck", 5 | message0: "Dead Duck %1", 6 | args0: [ 7 | { 8 | type: "field_image", 9 | src: duckImage, 10 | width: 40, 11 | height: 40, 12 | alt: "dead duck", 13 | flipRtl: false, 14 | }, 15 | ], 16 | colour: "#FFAABB", 17 | tooltip: "", 18 | helpUrl: "", 19 | previousStatement: null, 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasSetTextAlign/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'canvas_set_text_align', 3 | message0: 'setTextAlign %1', 4 | args0: [ 5 | { 6 | type: 'field_dropdown', 7 | name: 'align', 8 | options: [ 9 | ['left', 'left'], 10 | ['right', 'right'], 11 | ['center', 'center'], 12 | ], 13 | }, 14 | ], 15 | previousStatement: null, 16 | nextStatement: null, 17 | colour: '#6600cc', 18 | tooltip: '', 19 | helpUrl: '', 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasSetTextAlign/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | export const canvasSetTextAlign = (Blockly) => { 3 | Blockly.Blocks['canvas_set_text_align'] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | Blockly.JavaScript['canvas_set_text_align'] = function (block) { 9 | // TODO: Assemble JavaScript into code variable. 10 | const align = block.getFieldValue('align'); 11 | return `engine.setTextAlign('${align}');\n`; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerX/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | 3 | export const playerX = (Blockly) => { 4 | Blockly.Blocks['player_x'] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript['player_x'] = function (block) { 10 | // TODO: Assemble JavaScript into code variable. 11 | const code = 'engine.getPlayerX()'; 12 | // TODO: Change ORDER_NONE to the correct strength. 13 | return [code, Blockly.JavaScript.ORDER_NONE]; 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/blocky/custom/playerY/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | 3 | export const playerY = (Blockly) => { 4 | Blockly.Blocks['player_y'] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript['player_y'] = function (block) { 10 | // TODO: Assemble JavaScript into code variable. 11 | const code = 'engine.getPlayerY()'; 12 | // TODO: Change ORDER_NONE to the correct strength. 13 | return [code, Blockly.JavaScript.ORDER_NONE]; 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasWidth/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | 3 | export const canvasWidth = (Blockly) => { 4 | Blockly.Blocks['canvas_width'] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript['canvas_width'] = function (block) { 10 | // TODO: Assemble JavaScript into code variable. 11 | const code = 'canvas.width'; 12 | // TODO: Change ORDER_NONE to the correct strength. 13 | return [code, Blockly.JavaScript.ORDER_NONE]; 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasHeight/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | 3 | export const canvasHeight = (Blockly) => { 4 | Blockly.Blocks['canvas_height'] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript['canvas_height'] = function (block) { 10 | // TODO: Assemble JavaScript into code variable. 11 | const code = 'canvas.width'; 12 | // TODO: Change ORDER_NONE to the correct strength. 13 | return [code, Blockly.JavaScript.ORDER_NONE]; 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasSetCursor/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'canvas_set_cursor', 3 | message0: 'Set Text Cursor %1 X %2 Y %3', 4 | args0: [ 5 | { 6 | type: 'input_dummy', 7 | }, 8 | { 9 | type: 'input_value', 10 | name: 'x', 11 | check: 'Number', 12 | }, 13 | { 14 | type: 'input_value', 15 | name: 'y', 16 | check: 'Number', 17 | }, 18 | ], 19 | colour: '#6600cc', 20 | tooltip: '', 21 | helpUrl: '', 22 | previousStatement: null, 23 | nextStatement: null, 24 | }; 25 | -------------------------------------------------------------------------------- /src/components/blocky/custom/textSize/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | export const textSize = (Blockly) => { 3 | Blockly.Blocks['canvas_text_size'] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | Blockly.JavaScript['canvas_text_size'] = function (block) { 9 | // TODO: Assemble JavaScript into code variable. 10 | const size = Blockly.JavaScript.valueToCode(block, 'textSize', Blockly.JavaScript.ORDER_NONE) || "''"; 11 | var code = `engine.setTextSize(${size});\n`; 12 | return code; 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameSetPlayerPosition/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'game_set_player_position', 3 | message0: 'Set Player position %1 X %2 Y %3', 4 | args0: [ 5 | { 6 | type: 'input_dummy', 7 | }, 8 | { 9 | type: 'input_value', 10 | name: 'x', 11 | check: 'Number', 12 | }, 13 | { 14 | type: 'input_value', 15 | name: 'y', 16 | check: 'Number', 17 | }, 18 | ], 19 | colour: '#FFAABB', 20 | tooltip: '', 21 | helpUrl: '', 22 | previousStatement: null, 23 | nextStatement: null, 24 | }; 25 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasSetCursor/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | export const canvasSetCursor = (Blockly) => { 3 | Blockly.Blocks['canvas_set_cursor'] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | 9 | Blockly.JavaScript['canvas_set_cursor'] = function (block) { 10 | const x = Blockly.JavaScript.valueToCode(block, 'x', Blockly.JavaScript.ORDER_ATOMIC) || 0; 11 | const y = Blockly.JavaScript.valueToCode(block, 'y', Blockly.JavaScript.ORDER_ATOMIC) || 0; 12 | return `engine.setCursor(${x}, ${y});\n`; 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameSetPlayerPositionX/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from "./definition"; 2 | export const gameSetPlayerPositionX = (Blockly) => { 3 | Blockly.Blocks["game_set_player_position_x"] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | 9 | Blockly.JavaScript["game_set_player_position_x"] = function (block) { 10 | const x = 11 | Blockly.JavaScript.valueToCode( 12 | block, 13 | "x", 14 | Blockly.JavaScript.ORDER_ATOMIC 15 | ) || 0; 16 | 17 | return `engine.setPlayerPosition(${x});\n`; 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasSetTextColor/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | export const canvasSetTextColor = (Blockly) => { 3 | Blockly.Blocks['canvas_set_text_color'] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | Blockly.JavaScript['canvas_set_text_color'] = function (block) { 9 | // TODO: Assemble JavaScript into code variable. 10 | const color = Blockly.JavaScript.valueToCode(block, 'textColor', Blockly.JavaScript.ORDER_NONE) || "''"; 11 | var code = `engine.setTextColor(${color});\n`; 12 | return code; 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /src/components/blocky/custom/backgroundColor/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | export const backgroundColor = (Blockly) => { 3 | Blockly.Blocks['canvas_background_color'] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | Blockly.JavaScript['canvas_background_color'] = function (block) { 9 | // TODO: Assemble JavaScript into code variable. 10 | const color = Blockly.JavaScript.valueToCode(block, 'backgroundColor', Blockly.JavaScript.ORDER_NONE) || "''"; 11 | var code = `engine.drawBackground(${color});\n`; 12 | return code; 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameSetPlayerPositionY/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from "./definition"; 2 | export const gameSetPlayerPositionY = (Blockly) => { 3 | Blockly.Blocks["game_set_player_position_y"] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | 9 | Blockly.JavaScript["game_set_player_position_y"] = function (block) { 10 | const y = 11 | Blockly.JavaScript.valueToCode( 12 | block, 13 | "y", 14 | Blockly.JavaScript.ORDER_ATOMIC 15 | ) || 0; 16 | 17 | return `engine.setPlayerPosition(undefined,${y});\n`; 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameMoveObstacleX/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | 3 | export const gameMoveObstacleX = (Blockly) => { 4 | Blockly.Blocks['game_move_obstacle_x'] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript['game_move_obstacle_x'] = function (block) { 10 | // TODO: Assemble JavaScript into code variable. 11 | const x = Blockly.JavaScript.valueToCode(block, 'x', Blockly.JavaScript.ORDER_ATOMIC); 12 | // TODO: Change ORDER_NONE to the correct strength. 13 | return `engine.moveObstacleX(${x});`; 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameTarget/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from "./definition"; 2 | 3 | export const gameTarget = (Blockly) => { 4 | Blockly.Blocks["game_target"] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript["game_target"] = function (block) { 10 | // TODO: Assemble JavaScript into code variable. 11 | const target = Blockly.JavaScript.statementToCode(block, "target"); 12 | // TODO: Assemble JavaScript into code variable. 13 | return ` 14 | engine.setTarget(() => { 15 | ${target} 16 | }) 17 | ;\n`; 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameSetPlayerPosition/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | export const gameSetPlayerPosition = (Blockly) => { 3 | Blockly.Blocks['game_set_player_position'] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | 9 | Blockly.JavaScript['game_set_player_position'] = function (block) { 10 | const x = Blockly.JavaScript.valueToCode(block, 'x', Blockly.JavaScript.ORDER_ATOMIC) || 0; 11 | const y = Blockly.JavaScript.valueToCode(block, 'y', Blockly.JavaScript.ORDER_ATOMIC) || 0; 12 | return `engine.setPlayerPosition(${x}, ${y});\n`; 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameObstacle/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | 3 | export const gameObstacle = (Blockly) => { 4 | Blockly.Blocks['game_obstacle'] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript['game_obstacle'] = function (block) { 10 | // TODO: Assemble JavaScript into code variable. 11 | const obstacles = Blockly.JavaScript.statementToCode(block, 'obstacle'); 12 | // TODO: Assemble JavaScript into code variable. 13 | return ` 14 | engine.setObstacles(() => { 15 | ${obstacles} 16 | }) 17 | ;\n`; 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameMoveTargetX/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from "./definition"; 2 | 3 | export const gameMoveTargetX = (Blockly) => { 4 | Blockly.Blocks["game_move_target_x"] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript["game_move_target_x"] = function (block) { 10 | // TODO: Assemble JavaScript into code variable. 11 | const x = Blockly.JavaScript.valueToCode( 12 | block, 13 | "x", 14 | Blockly.JavaScript.ORDER_ATOMIC 15 | ); 16 | // TODO: Change ORDER_NONE to the correct strength. 17 | return `engine.moveTargetX(${x});`; 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameMoveTargetY/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from "./definition"; 2 | 3 | export const gameMoveTargetY = (Blockly) => { 4 | Blockly.Blocks["game_move_target_y"] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript["game_move_target_y"] = function (block) { 10 | // TODO: Assemble JavaScript into code variable. 11 | const y = Blockly.JavaScript.valueToCode( 12 | block, 13 | "y", 14 | Blockly.JavaScript.ORDER_ATOMIC 15 | ); 16 | // TODO: Change ORDER_NONE to the correct strength. 17 | return `engine.moveTargetY(${y});`; 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameMoveObstacleY/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from "./definition"; 2 | 3 | export const gameMoveObstacleY = (Blockly) => { 4 | Blockly.Blocks["game_move_obstacle_y"] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript["game_move_obstacle_y"] = function (block) { 10 | // TODO: Assemble JavaScript into code variable. 11 | const y = Blockly.JavaScript.valueToCode( 12 | block, 13 | "y", 14 | Blockly.JavaScript.ORDER_ATOMIC 15 | ); 16 | // TODO: Change ORDER_NONE to the correct strength. 17 | return `engine.moveObstacleY(${y});`; 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /src/components/Navigator.jsx: -------------------------------------------------------------------------------- 1 | import { PAGE_APP, PAGE_CODE, PAGE_MIX, PAGE_SETTINGS } from '../constants'; 2 | 3 | export const Navigator = ({ onCode, onMix, onApp, onSettings, currentPage }) => { 4 | return ( 5 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasDrawRectangle/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: 'canvas_draw_rectangle', 3 | message0: 'drawRectangle %1 x %2 y %3 width %4 height %5 Colour %6', 4 | args0: [ 5 | { 6 | type: 'input_dummy', 7 | }, 8 | { 9 | type: 'input_value', 10 | name: 'x', 11 | check: 'Number', 12 | }, 13 | { 14 | type: 'input_value', 15 | name: 'y', 16 | check: 'Number', 17 | }, 18 | { 19 | type: 'input_value', 20 | name: 'width', 21 | check: 'Number', 22 | }, 23 | { 24 | type: 'input_value', 25 | name: 'height', 26 | check: 'Number', 27 | }, 28 | { 29 | type: 'input_value', 30 | name: 'color', 31 | check: 'Colour', 32 | }, 33 | ], 34 | colour: '#6600cc', 35 | tooltip: '', 36 | helpUrl: '', 37 | previousStatement: null, 38 | nextStatement: null, 39 | }; 40 | -------------------------------------------------------------------------------- /src/components/blocky/custom/canvasDrawRectangle/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from './definition'; 2 | 3 | export const canvasDrawRectangle = (Blockly) => { 4 | Blockly.Blocks['canvas_draw_rectangle'] = { 5 | init: function () { 6 | this.jsonInit(definition); 7 | }, 8 | }; 9 | Blockly.JavaScript['canvas_draw_rectangle'] = function (block) { 10 | const x = Blockly.JavaScript.valueToCode(block, 'x', Blockly.JavaScript.ORDER_ATOMIC); 11 | const y = Blockly.JavaScript.valueToCode(block, 'y', Blockly.JavaScript.ORDER_ATOMIC); 12 | const width = Blockly.JavaScript.valueToCode(block, 'width', Blockly.JavaScript.ORDER_ATOMIC); 13 | const height = Blockly.JavaScript.valueToCode(block, 'height', Blockly.JavaScript.ORDER_ATOMIC); 14 | const color = Blockly.JavaScript.valueToCode(block, 'color', Blockly.JavaScript.ORDER_ATOMIC); 15 | return `engine.drawRectangle(${x || 0}, ${y || 0}, ${width || 0}, ${height || 0}, ${color})`; 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /src/components/blocky/initialize.js: -------------------------------------------------------------------------------- 1 | import { initializeCustomBlocks } from "./custom"; 2 | import { toolbox } from "./toolbox"; 3 | import Blockly from "blockly/core"; 4 | import "blockly"; 5 | import "blockly/javascript"; 6 | import "blockly/blocks"; 7 | 8 | import locale from "blockly/msg/en"; 9 | import { debounce } from "../../utils/debounce"; 10 | 11 | export function initialize( 12 | editor, 13 | setGetJsCode, 14 | setWorkspaceXml, 15 | { initialXml, ...props } 16 | ) { 17 | initializeCustomBlocks(Blockly); 18 | console.log(`initializing blockly`); 19 | Blockly.setLocale(locale); 20 | 21 | const workspace = Blockly.inject(editor, { 22 | toolbox, 23 | ...props, 24 | }); 25 | const localStorageKey = "blockly_saved_workspace"; // 'blocklySavedWorkspace' 26 | 27 | const onChange = (event) => { 28 | const xml = Blockly.Xml.workspaceToDom(workspace); 29 | const text = Blockly.Xml.domToText(xml); 30 | setWorkspaceXml(text); 31 | localStorage.setItem(localStorageKey, text); 32 | setGetJsCode(Blockly.JavaScript.workspaceToCode(workspace)); 33 | }; 34 | const savedXML = localStorage.getItem(localStorageKey); 35 | setWorkspaceXml(savedXML); 36 | workspace.addChangeListener(debounce(onChange, 500)); 37 | Blockly.Xml.domToWorkspace( 38 | Blockly.Xml.textToDom(savedXML || initialXml), 39 | workspace 40 | ); 41 | setGetJsCode(Blockly.JavaScript.workspaceToCode(workspace)); 42 | 43 | return workspace; 44 | } 45 | -------------------------------------------------------------------------------- /src/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/components/blocky/BlocklyEditor.jsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect, useContext } from 'react'; 2 | import { WorkspaceContext } from '../../WorkspaceContext'; 3 | import Blockly from 'blockly/core'; 4 | import { initialize } from './initialize'; 5 | 6 | export const BlocklyEditor = ({ currentPage, children: toolBox, ...props }) => { 7 | const editorRef = useRef(); 8 | const containerRef = useRef(); 9 | let workspaceRef = useRef(); 10 | const { setGetJsCode, setWorkspaceXml } = useContext(WorkspaceContext); 11 | function resizeBlockly() { 12 | if (!workspaceRef.current || !containerRef.current) { 13 | return; 14 | } 15 | 16 | Blockly.svgResize(workspaceRef.current); 17 | // TODO!: Possible blockly bug, might want to conttribute, resize does not always resize height 18 | const { height, width } = containerRef.current.getBoundingClientRect(); 19 | console.info(`Resizing blockly to ${height}`); 20 | if (!height) { 21 | return; 22 | } 23 | editorRef.current.querySelector('.blocklySvg').setAttribute('height', `${height}px`); 24 | editorRef.current.querySelector('.blocklySvg').setAttribute('width', `${width}px`); 25 | } 26 | useEffect(() => { 27 | if (workspaceRef.current) return; 28 | workspaceRef.current = initialize(editorRef.current, setGetJsCode, setWorkspaceXml, props); 29 | 30 | new ResizeObserver(resizeBlockly).observe(containerRef.current); 31 | }); 32 | 33 | useEffect(() => {}, [currentPage]); 34 | return ( 35 |
36 |
37 |
38 | ); 39 | }; 40 | -------------------------------------------------------------------------------- /src/components/Settings.jsx: -------------------------------------------------------------------------------- 1 | import { WorkspaceContext } from '../WorkspaceContext'; 2 | import { useContext } from 'react'; 3 | 4 | export const Settings = () => { 5 | const { getWorkspaceXml } = useContext(WorkspaceContext); 6 | 7 | const showFile = async (e) => { 8 | e.preventDefault(); 9 | const reader = new FileReader(); 10 | reader.onload = async (e) => { 11 | const text = e.target.result; 12 | localStorage.setItem('blockly_saved_workspace', text); 13 | }; 14 | reader.readAsText(e.target.files[0]); 15 | }; 16 | 17 | const exportFile = () => { 18 | const blob = new Blob([getWorkspaceXml], { type: 'application/xml' }); 19 | const dlink = document.createElement('a'); 20 | dlink.download = 'munich_coding_club.xml'; 21 | dlink.href = window.URL.createObjectURL(blob); 22 | dlink.onclick = function (e) { 23 | const that = this; 24 | setTimeout(function () { 25 | window.URL.revokeObjectURL(that.href); 26 | }, 1500); 27 | }; 28 | dlink.click(); 29 | dlink.remove(); 30 | }; 31 | return ( 32 |
33 |

Settings

34 | 35 |
36 |
37 | Import 38 |

Select a file that was previously exported

39 |
40 | 41 | 42 |
43 |
44 |
45 | Export 46 |

Click here to export your current code and use it later

47 | 48 |
49 |
50 |
51 | ); 52 | }; 53 | -------------------------------------------------------------------------------- /src/components/game/GameArea.jsx: -------------------------------------------------------------------------------- 1 | import { useContext, useEffect, useRef, useState } from 'react'; 2 | import { PAGE_CODE } from '../../constants'; 3 | import { WorkspaceContext } from '../../WorkspaceContext'; 4 | import { Engine } from './Engine'; 5 | 6 | export const GameArea = ({ currentPage }) => { 7 | const containerRef = useRef(); 8 | const canvasRef = useRef(); 9 | const engineRef = useRef(); 10 | const [isGameRunning,setGameRunning] = useState(false) 11 | const { getJsCode } = useContext(WorkspaceContext); 12 | 13 | useEffect(() => { 14 | if (!engineRef.current) { 15 | 16 | return 17 | }; 18 | if (isGameRunning) { 19 | engineRef.current.onGameUpdated() 20 | } 21 | engineRef.current.proccessBlocks(getJsCode); 22 | }, [getJsCode]); 23 | 24 | function resizeCanvas() { 25 | const { height, width } = containerRef.current.getBoundingClientRect(); 26 | if (!width && !height) { 27 | return; 28 | } 29 | engineRef.current.resize(width, height); 30 | } 31 | useEffect(() => { 32 | if (engineRef.current) { 33 | return 34 | } 35 | engineRef.current = new Engine(canvasRef.current, () => setGameRunning(true), () => setGameRunning(false)); 36 | resizeCanvas(); 37 | engineRef.current.proccessBlocks(getJsCode); 38 | 39 | return () => { 40 | engineRef.current.tearDown(); 41 | }; 42 | 43 | // engineRef.current.drawImage(duckImage, 10, 10, 50, 50); 44 | }, [getJsCode]); 45 | const info = isGameRunning ? 'Game Running' : 'Game stopped. Press enter to play' 46 | useEffect(() => { 47 | window.addEventListener('resize', resizeCanvas); 48 | return () => window.removeEventListener('resize', resizeCanvas); 49 | }, []); 50 | useEffect(() => { 51 | if (!containerRef.current) return; 52 | resizeCanvas(); 53 | }, [currentPage]); 54 | return ( 55 |
56 |

{info}

57 |
58 | console.log(`blur`)} 61 | > 62 |
63 | 64 |
65 | ); 66 | }; 67 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameSetup/definition.js: -------------------------------------------------------------------------------- 1 | export const definition = { 2 | type: "game_setup", 3 | colour: "#FFAABB", 4 | hat: "cap", 5 | message0: 6 | "Game setup %1 initial speed %2 Enemy generation speed %3 target generation speed %4 %5 player %6 on start %7 on update %8 onEnemyGeneration %9 on end %10 on colision %11 on up key %12 on down key %13 on forward key %14 on back key %15 on obstacle outside %16 on target generation %17 on target grabbed %18", 7 | args0: [ 8 | { 9 | type: "input_dummy", 10 | }, 11 | { 12 | type: "input_value", 13 | name: "initialSpeedDefault", 14 | }, 15 | { 16 | type: "input_value", 17 | name: "enemyGenerationSpeed", 18 | check: "Number", 19 | }, 20 | { 21 | type: "input_value", 22 | name: "targetGenerationSpeed", 23 | check: "Number", 24 | }, 25 | { 26 | type: "input_dummy", 27 | }, 28 | { 29 | type: "input_statement", 30 | name: "player", 31 | check: [ 32 | "game_duck", 33 | "game_chicken", 34 | "game_dead_duck", 35 | "game_dead_chicken", 36 | ], 37 | }, 38 | { 39 | type: "input_statement", 40 | name: "onStart", 41 | }, 42 | { 43 | type: "input_statement", 44 | name: "onUpdate", 45 | }, 46 | { 47 | type: "input_statement", 48 | name: "onEnemyGeneration", 49 | }, 50 | { 51 | type: "input_statement", 52 | name: "onEnd", 53 | }, 54 | { 55 | type: "input_statement", 56 | name: "onColision", 57 | }, 58 | { 59 | type: "input_statement", 60 | name: "onUp", 61 | }, 62 | { 63 | type: "input_statement", 64 | name: "onDown", 65 | }, 66 | { 67 | type: "input_statement", 68 | name: "onForward", 69 | }, 70 | { 71 | type: "input_statement", 72 | name: "onBackward", 73 | }, 74 | { 75 | type: "input_statement", 76 | name: "onObstacleOutside", 77 | }, 78 | { 79 | type: "input_statement", 80 | name: "onTargetGenerated", 81 | }, 82 | { 83 | type: "input_statement", 84 | name: "onTargetGrabbed", 85 | }, 86 | ], 87 | inputsInline: false, 88 | previousStatement: null, 89 | nextStatement: null, 90 | tooltip: "Configures the game settings", 91 | helpUrl: "", 92 | }; 93 | -------------------------------------------------------------------------------- /src/components/blocky/custom/index.js: -------------------------------------------------------------------------------- 1 | import { gameSetup } from "./gameSetup"; 2 | import { playerDuck } from "./playerDuck"; 3 | import { playerDeadDuck } from "./playerDeadDuck"; 4 | import { playerDeadChicken } from "./playerDeadChicken"; 5 | import { playerChicken } from "./playerChicken"; 6 | import { overWrite } from "./overWrite"; 7 | import { backgroundColor } from "./backgroundColor"; 8 | import { textSize } from "./textSize"; 9 | import { canvasWidth } from "./canvasWidth"; 10 | import { canvasHeight } from "./canvasHeight"; 11 | import { canvasSetTextColor } from "./canvasSetTextColor"; 12 | import { canvasSetCursor } from "./canvasSetCursor"; 13 | import { canvasDrawRectangle } from "./canvasDrawRectangle"; 14 | import { canvasSetTextAlign } from "./canvasSetTextAlign"; 15 | import { playerX } from "./playerX"; 16 | import { playerY } from "./playerY"; 17 | import { gameObstacle } from "./gameObstacle"; 18 | import { gameTarget } from "./gameTarget"; 19 | import { gameSetPlayerPosition } from "./gameSetPlayerPosition"; 20 | import { gameSetPlayerPositionX } from "./gameSetPlayerPositionX"; 21 | import { gameSetPlayerPositionY } from "./gameSetPlayerPositionY"; 22 | import { gameMoveObstacleX } from "./gameMoveObstacleX"; 23 | import { gameMoveObstacleY } from "./gameMoveObstacleY"; 24 | import { gameMoveTargetX } from "./gameMoveTargetX"; 25 | import { gameMoveTargetY } from "./gameMoveTargetY"; 26 | import { gameEndGame } from "./gameEndGame"; 27 | import { setPlayerIcon } from "./setPlayerIcon"; 28 | 29 | // TODO avoid this 30 | export function initializeCustomBlocks(Blockly) { 31 | gameSetup(Blockly); 32 | playerDuck(Blockly); 33 | playerChicken(Blockly); 34 | overWrite(Blockly); 35 | backgroundColor(Blockly); 36 | textSize(Blockly); 37 | canvasWidth(Blockly); 38 | canvasHeight(Blockly); 39 | canvasSetCursor(Blockly); 40 | canvasSetTextAlign(Blockly); 41 | canvasSetTextColor(Blockly); 42 | canvasDrawRectangle(Blockly); 43 | playerY(Blockly); 44 | playerX(Blockly); 45 | gameSetPlayerPosition(Blockly); 46 | gameSetPlayerPositionX(Blockly); 47 | gameSetPlayerPositionY(Blockly); 48 | gameObstacle(Blockly); 49 | gameTarget(Blockly); 50 | gameMoveObstacleX(Blockly); 51 | gameMoveObstacleY(Blockly); 52 | gameMoveTargetX(Blockly); 53 | gameMoveTargetY(Blockly); 54 | gameEndGame(Blockly); 55 | playerDeadDuck(Blockly); 56 | playerDeadChicken(Blockly); 57 | setPlayerIcon(Blockly); 58 | } 59 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import { Wrapper } from './components/Wrapper'; 3 | import { Navigator } from './components/Navigator'; 4 | import { GameArea } from './components/game'; 5 | import { Settings } from './components/Settings'; 6 | import { ContentWrapper } from './components/ContentWrapper'; 7 | import { BlocklyEditor } from './components/blocky'; 8 | import { PAGE_APP, PAGE_CODE, PAGE_MIX, PAGE_SETTINGS } from './constants'; 9 | import { WorkspaceContext } from './WorkspaceContext'; 10 | 11 | function App() { 12 | const [currentPage, setCurrentPage] = useState(PAGE_MIX); 13 | const [getJsCode, setGetJsCode] = useState(() => ''); 14 | const [getWorkspaceXml, setWorkspaceXml] = useState(() => ''); 15 | 16 | return ( 17 | 18 | 19 | setCurrentPage(PAGE_APP)} 21 | onCode={() => setCurrentPage(PAGE_CODE)} 22 | onMix={() => setCurrentPage(PAGE_MIX)} 23 | onSettings={() => setCurrentPage(PAGE_SETTINGS)} 24 | currentPage={currentPage} 25 | /> 26 | 27 | {(currentPage === PAGE_MIX || currentPage === PAGE_CODE) && ( 28 | 44 | #33ccffOlá 45 | `} 46 | > 47 | )} 48 | {(currentPage === PAGE_MIX || currentPage === PAGE_APP) && } 49 | {currentPage === PAGE_SETTINGS && } 50 | 51 | 52 | 53 | ); 54 | } 55 | 56 | export default App; 57 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body, 2 | html { 3 | margin: 0; 4 | height: 100%; 5 | } 6 | #root { 7 | width: 100%; 8 | height: 100%; 9 | min-height: 100vh; 10 | } 11 | .wrapper { 12 | width: 100%; 13 | height: 100%; 14 | position: relative; 15 | display: flex; 16 | flex-direction: column; 17 | } 18 | 19 | .navigator { 20 | display: flex; 21 | justify-content: space-evenly; 22 | } 23 | .menu-item { 24 | flex-grow: 1; 25 | text-align: center; 26 | } 27 | .menu-item[data-is-current="true"] { 28 | font-weight: bold; 29 | } 30 | .menu-item:hover { 31 | cursor: pointer; 32 | } 33 | 34 | .content-wrapper { 35 | flex-grow: 1; 36 | display: grid; 37 | grid-template-rows: 1fr 1fr 1fr 1fr; 38 | grid-template-columns: 1fr 1fr 1fr 1fr; 39 | } 40 | .blockly-container { 41 | height: 100%; 42 | width: 100%; 43 | grid-area: blockly; 44 | position: relative; 45 | } 46 | #blocklyDiv { 47 | position: absolute; 48 | width: 100%; 49 | height: 100%; 50 | } 51 | 52 | .game-area { 53 | height: 100%; 54 | width: 100%; 55 | grid-area: game; 56 | display: grid; 57 | background-color: whitesmoke; 58 | grid-template-columns: 1fr; 59 | grid-template-rows: min-content 1fr; 60 | } 61 | 62 | .settings { 63 | height: 100%; 64 | width: 100%; 65 | grid-area: settings; 66 | background-color: whitesmoke; 67 | } 68 | .content-wrapper.is-code { 69 | grid-template-areas: 70 | "blockly blockly blockly blockly" 71 | "blockly blockly blockly blockly" 72 | "blockly blockly blockly blockly" 73 | "blockly blockly blockly blockly"; 74 | } 75 | .content-wrapper.is-settings { 76 | grid-template-areas: 77 | "settings settings settings settings" 78 | "settings settings settings settings" 79 | "settings settings settings settings" 80 | "settings settings settings settings"; 81 | } 82 | .content-wrapper.is-app { 83 | grid-template-areas: 84 | "game game game game" 85 | "game game game game" 86 | "game game game game" 87 | "game game game game"; 88 | } 89 | 90 | .content-wrapper.is-mix { 91 | grid-template-areas: 92 | "blockly blockly game game" 93 | "blockly blockly game game" 94 | "blockly blockly game game" 95 | "blockly blockly game game"; 96 | } 97 | * { 98 | box-sizing: border-box; 99 | } 100 | canvas { 101 | background-color: black; 102 | } 103 | label { 104 | min-width: 10rem; 105 | padding-right: 0.5rem; 106 | text-align: right; 107 | font-weight: bold; 108 | } 109 | 110 | .innerWrapper { 111 | width: 100%; 112 | margin: 0 auto; 113 | display: flex; 114 | flex-direction: column; 115 | max-width: 20rem; 116 | } 117 | 118 | .settings { 119 | position: relative; 120 | } 121 | -------------------------------------------------------------------------------- /src/components/blocky/custom/gameSetup/index.js: -------------------------------------------------------------------------------- 1 | import { definition } from "./definition"; 2 | export const gameSetup = (Blockly) => { 3 | Blockly.Blocks["game_setup"] = { 4 | init: function () { 5 | this.jsonInit(definition); 6 | }, 7 | }; 8 | Blockly.JavaScript["game_setup"] = function (block) { 9 | const initialSpeed = Blockly.JavaScript.valueToCode( 10 | block, 11 | "initialSpeedDefault", 12 | Blockly.JavaScript.ORDER_ATOMIC 13 | ); 14 | const enemyGenerationSpeed = Blockly.JavaScript.valueToCode( 15 | block, 16 | "enemyGenerationSpeed", 17 | Blockly.JavaScript.ORDER_ATOMIC 18 | ); 19 | const targetGenerationSpeed = Blockly.JavaScript.valueToCode( 20 | block, 21 | "targetGenerationSpeed", 22 | Blockly.JavaScript.ORDER_ATOMIC 23 | ); 24 | 25 | const player = Blockly.JavaScript.statementToCode(block, "player"); 26 | var onStart = Blockly.JavaScript.statementToCode(block, "onStart"); 27 | var onUpdate = Blockly.JavaScript.statementToCode(block, "onUpdate"); 28 | var onEnd = Blockly.JavaScript.statementToCode(block, "onEnd"); 29 | const onUpKey = Blockly.JavaScript.statementToCode(block, "onUp"); 30 | const onDownKey = Blockly.JavaScript.statementToCode(block, "onDown"); 31 | const onForwardKey = Blockly.JavaScript.statementToCode(block, "onForward"); 32 | const onBackwardKey = Blockly.JavaScript.statementToCode( 33 | block, 34 | "onBackward" 35 | ); 36 | const onColision = Blockly.JavaScript.statementToCode(block, "onColision"); 37 | const onEnemyGeneration = Blockly.JavaScript.statementToCode( 38 | block, 39 | "onEnemyGeneration" 40 | ); 41 | const onObstacleOutside = Blockly.JavaScript.statementToCode( 42 | block, 43 | "onObstacleOutside" 44 | ); 45 | const onTargetGrabbed = Blockly.JavaScript.statementToCode( 46 | block, 47 | "onTargetGrabbed" 48 | ); 49 | const onTargetGenerated = Blockly.JavaScript.statementToCode( 50 | block, 51 | "onTargetGenerated" 52 | ); 53 | 54 | // TODO: Assemble JavaScript into code variable. 55 | const code = `engine.setScenario( 56 | { 57 | initialSpeed: ${initialSpeed || 500}, 58 | enemyGenerationSpeed: ${enemyGenerationSpeed || 500}, 59 | targetGenerationSpeed: ${targetGenerationSpeed || 500}, 60 | player: ${player || "null"}, 61 | onStart: () => { 62 | ${onStart} 63 | }, 64 | onUpdate: () => { 65 | ${onUpdate} 66 | }, 67 | onEnd: () => { 68 | ${onEnd} 69 | }, 70 | onEnemyGeneration: () => { 71 | ${onEnemyGeneration} 72 | }, 73 | onUpKey: () => { 74 | ${onUpKey} 75 | }, 76 | onDownKey: () => { 77 | ${onDownKey} 78 | }, 79 | onForwardKey: () => { 80 | ${onForwardKey} 81 | }, 82 | onBackwardKey: () => { 83 | ${onBackwardKey} 84 | }, 85 | onColision: () => { 86 | ${onColision} 87 | }, 88 | onObstacleOutside: () => { 89 | ${onObstacleOutside} 90 | }, 91 | onTargetGrabbed: () => { 92 | ${onTargetGrabbed} 93 | }, 94 | onTargetGenerated: () => { 95 | ${onTargetGenerated} 96 | } 97 | });\n`; 98 | return code; 99 | }; 100 | }; 101 | -------------------------------------------------------------------------------- /public/images/deadDuck.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 19 | 38 | 43 | 46 | 50 | 55 | 59 | 63 | 64 | 65 | 67 | 68 | 69 | image/svg+xml 70 | 72 | 74 | 75 | 77 | Openclipart 78 | 79 | 80 | 2010-08-01T19:10:36 81 | 82 | https://openclipart.org/detail/75889/duck-outline-by-gammillian 83 | 84 | 85 | gammillian 86 | 87 | 88 | 89 | 90 | animal 91 | black and white 92 | coloring page 93 | duck 94 | outline 95 | 96 | 97 | 98 | 100 | 102 | 104 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /public/images/duck.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 38 | 44 | 48 | 53 | 59 | 70 | 72 | 74 | 76 | 78 | 80 | image/svg+xml 83 | 86 | 89 | 91 | 94 | Openclipart 97 | 99 | 101 | Duck Outline 104 | 2010-08-01T19:10:36 107 | 109 | https://openclipart.org/detail/75889/duck-outline-by-gammillian 112 | 114 | 116 | gammillian 119 | 121 | 123 | 125 | 127 | animal 130 | black and white 133 | coloring page 136 | duck 139 | outline 142 | 144 | 146 | 148 | 151 | 154 | 157 | 160 | 162 | 164 | 166 | 168 | -------------------------------------------------------------------------------- /public/images/chicken.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 41 | 44 | 46 | 48 | 52 | 56 | 60 | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | 96 | 100 | 101 | 107 | 110 | 113 | 116 | 119 | 122 | 125 | 128 | 131 | 134 | 137 | 140 | 143 | 146 | 149 | 152 | 155 | 158 | 161 | 164 | 167 | 170 | 173 | 176 | 179 | 180 | 181 | 182 | image/svg+xmlOpenclipart 191 | -------------------------------------------------------------------------------- /src/components/game/Engine.js: -------------------------------------------------------------------------------- 1 | import duckImage from "/images/duck.png"; 2 | import chickenImage from "/images/chicken.png"; 3 | import deadDuckImage from "/images/deadDuck.png"; 4 | import deadChickenImage from "/images/deadChicken.png"; 5 | 6 | const PLAYER_DUCK = Symbol("PLAYER_DUCK"); 7 | const PLAYER_CHICKEN = Symbol("PLAYER_CHICKEN"); 8 | const PLAYER_DEAD_DUCK = Symbol("PLAYER_DEAD_DUCK"); 9 | const PLAYER_DEAD_CHICKEN = Symbol("PLAYER_DEAD_CHICKEN"); 10 | 11 | const imageMap = { 12 | [PLAYER_DUCK]: duckImage, 13 | [PLAYER_CHICKEN]: chickenImage, 14 | [PLAYER_DEAD_DUCK]: deadDuckImage, 15 | [PLAYER_DEAD_CHICKEN]: deadChickenImage, 16 | }; 17 | export class Engine { 18 | canvas; 19 | ctx; 20 | textSizeInPercentage = 5; 21 | textCursor = [0, 0]; 22 | textColor = "black"; 23 | textAlign = "left"; 24 | customCursor = false; 25 | scenario = {}; 26 | currentScenario = {}; 27 | currentCode; 28 | isGameRunning = false; 29 | playerPosition = [10, 10]; 30 | playerSize = 10; 31 | withinObstacleGuard = false; 32 | withinTargetGuard = false; 33 | obstacles = []; 34 | targets = []; 35 | gameHud = []; 36 | gameInterval; 37 | enemyInterval; 38 | onGameStart = () => {}; 39 | onGameEnd = () => {}; 40 | handleStart() { 41 | console.log(`Will start interactions`); 42 | this.proccessBlocks(this.currentCode); 43 | } 44 | startGame() { 45 | console.log(`Should start the game with `, this.currentScenario); 46 | this.scenario = { ...this.currentScenario }; 47 | if (!this.scenario || this.isGameRunning || !this.scenario?.onStart) { 48 | return; 49 | } 50 | this.onGameStart(); 51 | console.log(`Starting game`); 52 | this.isGameRunning = true; 53 | this.obstacles = []; 54 | this.targets = []; 55 | this.gameHud = []; 56 | try { 57 | console.log(`Calling onStart`, this.scenario.onStart); 58 | this.intepretCode(this.scenario.onStart()); 59 | this.renderFrame(); 60 | this.gameInterval = setInterval(() => { 61 | this.gameHud = []; 62 | this.intepretCode(this.scenario.onUpdate()); 63 | // this.renderFrame(); 64 | }, this.scenario.initialSpeed || 500); 65 | this.renderInterval = setInterval(() => { 66 | this.renderFrame(); 67 | }, this.scenario.initialSpeed || 100); 68 | this.enemyInterval = setInterval(() => { 69 | this.intepretCode(this.scenario?.onEnemyGeneration()); 70 | //this.renderFrame(); 71 | }, this.scenario.enemyGenerationSpeed || 500); 72 | this.targetGenerationInterval = setInterval(() => { 73 | this.intepretCode(this.scenario?.onTargetGenerated()); 74 | //this.renderFrame(); 75 | }, this.scenario.targetGenerationSpeed || 500); 76 | } catch (error) { 77 | console.error(error); 78 | } 79 | } 80 | listenToKeys(ev) { 81 | if (ev.code === "Enter") { 82 | this.startGame(); 83 | } 84 | const { scenario } = this; 85 | if (!this.isGameRunning) return; 86 | try { 87 | if (ev.code === "ArrowUp") { 88 | this.intepretCode(scenario.onUpKey()); 89 | } 90 | if (ev.code === "ArrowDown") { 91 | this.intepretCode(scenario.onDownKey()); 92 | } 93 | if (ev.code === "ArrowRight") { 94 | this.intepretCode(scenario.onForwardKey()); 95 | } 96 | if (ev.code === "ArrowLeft") { 97 | this.intepretCode(scenario.onBackwardKey()); 98 | } 99 | } catch (error) { 100 | console.error(error); 101 | } 102 | } 103 | resize(width, height) { 104 | if (!width && !height) { 105 | return; 106 | } 107 | const newSize = 100 * Math.floor(Math.min(height, width) / 100); 108 | if (newSize === this.size) return; 109 | this.size = newSize; 110 | console.log(`Resizing canvas to ${newSize}`); 111 | this.canvas.setAttribute("width", `${newSize}px`); 112 | this.canvas.setAttribute("height", `${newSize}px`); 113 | this.proccessBlocks(this.currentCode); 114 | } 115 | constructor(canvas, onGameStart, onGameEnd) { 116 | this.canvas = canvas; 117 | this.onGameStart = onGameStart; 118 | this.onGameEnd = onGameEnd; 119 | this.ctx = canvas.getContext("2d"); 120 | this.ctx.font = "20px arial"; 121 | document.addEventListener("keydown", this.listenToKeys.bind(this)); 122 | } 123 | 124 | tearDown() { 125 | console.log(`Tearing game down`); 126 | this.clearGameLoop(); 127 | document.removeEventListener("keydown", this.listenToKeys.bind(this)); 128 | } 129 | clearGameLoop() { 130 | this.isGameRunning = false; 131 | window.clearInterval(this.renderInterval); 132 | window.clearInterval(this.gameInterval); 133 | window.clearInterval(this.targetGenerationInterval); 134 | window.clearInterval(this.enemyInterval); 135 | } 136 | drawImage(src, x, y, width = undefined, height = undefined) { 137 | const drawing = new Image(); 138 | drawing.src = src; // can also be a remote URL e.g. http:// 139 | drawing.onload = () => { 140 | this.ctx.drawImage( 141 | drawing, 142 | 0, 143 | 0, 144 | drawing.width, 145 | drawing.height, 146 | x, 147 | y, 148 | width, 149 | height 150 | ); 151 | }; 152 | } 153 | 154 | proccessBlocks(code) { 155 | this.currentCode = code; 156 | console.log(`Interpreting code \n${code}`); 157 | this.textSizeInPercentage = 5; 158 | this.textCursor = [0, 0]; 159 | this.textColor = "black"; 160 | this.textAlign = "left"; 161 | this.customCursor = false; 162 | this.playerPosition = [10, 10]; 163 | this.playerSize = 10; 164 | this.intepretCode(code); 165 | } 166 | intepretCode(code) { 167 | if (!code) return; 168 | ("use strict"); 169 | 170 | const engine = this; 171 | const canvas = this.canvas; 172 | if (engine && canvas) { 173 | // Useless if so optimization does not stip it 174 | try { 175 | eval(code); 176 | } catch (error) { 177 | console.error(error); 178 | } 179 | } 180 | } 181 | 182 | drawBackground(color) { 183 | if (!color) { 184 | color = this.backgroundColor; 185 | } 186 | if (!color) { 187 | return; 188 | } 189 | const { ctx, size } = this; 190 | ctx.fillStyle = color; 191 | this.backgroundColor = color; 192 | ctx.fillRect(0, 0, size, size); 193 | } 194 | 195 | writeText(text, isHud) { 196 | // So hackish 197 | if (this.isGameRunning && !isHud) { 198 | this.gameHud.push(() => this.writeText(text, true)); 199 | return; 200 | } 201 | const { ctx, canvas } = this; 202 | const textSize = (canvas.height * this.textSizeInPercentage) / 100; 203 | ctx.font = `${textSize}px Arial`; 204 | ctx.fillStyle = this.textColor; 205 | ctx.textAlign = this.textAlign; 206 | const [x, y] = this.textCursor; 207 | 208 | let xPos = x; 209 | if (!this.customCursor) { 210 | switch (this.textAlign) { 211 | case "left": 212 | xPos = 0; 213 | break; 214 | case "center": 215 | xPos = canvas.width / 2; 216 | break; 217 | case "right": 218 | xPos = canvas.width; 219 | break; 220 | } 221 | } 222 | ctx.fillText(text, xPos, y + textSize); 223 | this.textCursor[1] = y + textSize; 224 | 225 | this.customCursor = false; 226 | } 227 | setTextSize(size, isHud) { 228 | // So hackish 229 | if (this.isGameRunning && !isHud) { 230 | this.gameHud.push(() => this.setTextSize(size, true)); 231 | return; 232 | } 233 | this.textSizeInPercentage = size; 234 | } 235 | setTextAlign(align, isHud) { 236 | // SO HACKISH 237 | if (this.isGameRunning && !isHud) { 238 | this.gameHud.push(() => this.setTextAlign(align, true)); 239 | return; 240 | } 241 | this.textAlign = align; 242 | } 243 | setCursor(x = 0, y = 0, isHud) { 244 | // SO HACKISH 245 | if (this.isGameRunning && !isHud) { 246 | this.gameHud.push(() => this.setCursor(x, y, true)); 247 | return; 248 | } 249 | this.textCursor = [x, y]; 250 | } 251 | 252 | setTextColor(color, isHud) { 253 | // SO HACKISH 254 | if (this.isGameRunning && !isHud) { 255 | this.gameHud.push(() => this.setTextColor(color, true)); 256 | return; 257 | } 258 | this.textColor = color; 259 | } 260 | 261 | setPlayer(player) { 262 | this.player = player; 263 | } 264 | 265 | setScenario(scenario) { 266 | console.log(`settign scenario`, scenario); 267 | this.currentScenario = { ...scenario }; 268 | const { player } = scenario; 269 | console.log({ player }); 270 | this.renderGame(this.currentScenario); 271 | } 272 | 273 | renderGame(scenarioToRender) { 274 | try { 275 | const { player } = scenarioToRender; 276 | console.log(`rendering the game`, scenarioToRender); 277 | if (!player) { 278 | console.log(`No game without a player`); 279 | return; 280 | } 281 | this.renderFrame(scenarioToRender); 282 | } catch (error) { 283 | console.error(error); 284 | } 285 | } 286 | getPlayerX() { 287 | return this.playerPosition[0]; 288 | } 289 | getPlayerY() { 290 | return this.playerPosition[1]; 291 | } 292 | setPlayerPosition(x, y) { 293 | if (typeof x === "undefined") { 294 | x = this.getPlayerX(); 295 | } 296 | if (typeof y === "undefined") { 297 | y = this.getPlayerY(); 298 | } 299 | this.playerPosition = [x, y]; 300 | console.log(`Setting player to ${(x, y)}`); 301 | this.renderFrame(); 302 | } 303 | renderPlayer(scenarioToRender) { 304 | const { player } = scenarioToRender || this.scenario; 305 | 306 | const { canvas, ctx } = this; 307 | 308 | const size = (canvas.height * this.playerSize) / 100; 309 | const [percentX, percentY] = this.playerPosition; 310 | // position is always in porcentages 311 | const x = Math.min( 312 | canvas.width, 313 | Math.max(0, (canvas.width * percentX) / 100 - size / 2) 314 | ); 315 | const y = Math.min( 316 | canvas.height, 317 | Math.max(0, (canvas.height * percentY) / 100 - size / 2) 318 | ); 319 | this.drawImage(imageMap[player], x, y, size, size); 320 | } 321 | setAvatar(newAvatar) { 322 | this.scenario.player = newAvatar; 323 | } 324 | 325 | renderFrame(scenarioToRender, isRerender) { 326 | const { ctx, canvas } = this; 327 | this.clearFrame(); 328 | this.drawBackground(); 329 | 330 | this.renderPlayer(scenarioToRender); 331 | this.obstacles.forEach(({ x, y, recWidth, recHeight, color }) => { 332 | this.drawRectangle( 333 | x, 334 | y, 335 | recWidth, 336 | recHeight, 337 | color, 338 | true, 339 | false, 340 | isRerender 341 | ); 342 | }); 343 | this.targets = this.targets.filter( 344 | ({ x, y, recWidth, recHeight, color }) => { 345 | const collided = this.drawRectangle( 346 | x, 347 | y, 348 | recWidth, 349 | recHeight, 350 | color, 351 | false, 352 | true, 353 | isRerender 354 | ); 355 | return !collided; 356 | } 357 | ); 358 | this.gameHud.forEach((fn, index) => { 359 | fn(); 360 | }); 361 | } 362 | clearFrame() { 363 | const { ctx, canvas } = this; 364 | 365 | ctx.clearRect(0, 0, canvas.width, canvas.height); 366 | ctx.beginPath(); 367 | ctx.moveTo(0, 0); 368 | ctx.lineTo(canvas.width, canvas.height); 369 | ctx.stroke(); 370 | } 371 | drawRectangle( 372 | x, 373 | y, 374 | recWidth, 375 | recHeight, 376 | color, 377 | forceObstacle, 378 | forceTarget, 379 | isRerender 380 | ) { 381 | const { ctx, canvas } = this; 382 | const { height, width } = canvas; 383 | const isObstacle = forceObstacle || this.withinObstacleGuard; 384 | const isTarget = forceTarget || this.withinObstacleGuard; 385 | ctx.fillStyle = color; 386 | if (this.withinObstacleGuard) { 387 | this.obstacles.push({ x, y, recWidth, recHeight, color }); 388 | } 389 | if (this.withinTargetGuard) { 390 | this.targets.push({ x, y, recWidth, recHeight, color }); 391 | } 392 | const absoluteX = (x * width) / 100; 393 | const absoluteY = (y * height) / 100; 394 | const absoluteWidth = (recWidth * width) / 100; 395 | const absoluteHeight = (recHeight * height) / 100; 396 | ctx.fillRect(absoluteX, absoluteY, absoluteWidth, absoluteHeight); 397 | let collided = false; 398 | if (!isRerender) { 399 | collided = this.checkColision( 400 | absoluteX, 401 | absoluteY, 402 | absoluteWidth, 403 | absoluteHeight 404 | ); 405 | } 406 | 407 | if (collided) { 408 | if (isObstacle) { 409 | this.intepretCode(this.scenario?.onColision()); 410 | } else if (isTarget) { 411 | this.intepretCode(this.scenario?.onTargetGrabbed()); 412 | this.renderFrame(this.scenario, true); 413 | } 414 | } 415 | return collided; 416 | } 417 | 418 | checkColision(obstacleX, obstacleY, obstacleWidth, obstacleHeight) { 419 | if (!this.isGameRunning) { 420 | return false; 421 | } 422 | const { canvas } = this; 423 | const size = (canvas.height * this.playerSize) / 100; 424 | const [percentX, percentY] = this.playerPosition; 425 | // position is always in porcentages 426 | const x = Math.min( 427 | canvas.width, 428 | Math.max(0, (canvas.width * percentX) / 100 - size / 2) 429 | ); 430 | const y = Math.min( 431 | canvas.height, 432 | Math.max(0, (canvas.height * percentY) / 100 - size / 2) 433 | ); 434 | 435 | if ( 436 | x < obstacleX + obstacleWidth && 437 | x + size > obstacleX && 438 | y < obstacleY + obstacleHeight && 439 | size + y > obstacleY 440 | ) { 441 | return true; 442 | } 443 | return false; 444 | } 445 | setObstacles(obstacleRender) { 446 | if (!obstacleRender) return; 447 | this.withinObstacleGuard = true; 448 | obstacleRender(); 449 | this.withinObstacleGuard = false; 450 | } 451 | setTarget(targetRenderer) { 452 | if (!targetRenderer) return; 453 | this.withinTargetGuard = true; 454 | targetRenderer(); 455 | this.withinTargetGuard = false; 456 | } 457 | moveObstacleX(deltaX) { 458 | const { width } = this.canvas; 459 | 460 | const newObstacles = []; 461 | this.obstacles.forEach(({ x, recWidth, ...other }, index) => { 462 | const obstacle = { x: x + deltaX, recWidth, ...other }; 463 | const absoluteX = (x * width) / 100; 464 | const absoluteWidth = (recWidth * width) / 100; 465 | if (absoluteX + absoluteWidth > 0) { 466 | newObstacles.push(obstacle); 467 | } else { 468 | this.scenario?.onObstacleOutside(); 469 | console.log(`removing obstacle`); 470 | } 471 | }); 472 | this.obstacles = newObstacles; 473 | } 474 | 475 | moveObstacleY(deltaY) { 476 | const { height } = this.canvas; 477 | 478 | const newObstacles = []; 479 | this.obstacles.forEach(({ y, recHeight, ...other }, index) => { 480 | const obstacle = { y: y + deltaY, recHeight, ...other }; 481 | const absoluteY = (y * height) / 100; 482 | const absoluteHeight = (recHeight * height) / 100; 483 | if (absoluteY + absoluteHeight > 0) { 484 | newObstacles.push(obstacle); 485 | } else { 486 | console.log(`removing obstacle`); 487 | } 488 | }); 489 | this.obstacles = newObstacles; 490 | } 491 | moveTargetX(deltaX) { 492 | const { width } = this.canvas; 493 | 494 | const newTargets = []; 495 | this.targets.forEach((originalTarget, index) => { 496 | const { x, recWidth, ...other } = originalTarget; 497 | const target = { x: x + deltaX, recWidth, ...other }; 498 | const absoluteX = (x * width) / 100; 499 | const absoluteWidth = (recWidth * width) / 100; 500 | console.log({ absoluteX, absoluteWidth, deltaX, x, recWidth }); 501 | if (absoluteX + absoluteWidth > 0) { 502 | newTargets.push(target); 503 | } else { 504 | console.log(`removing target, ${absoluteX + absoluteWidth}`, { 505 | absoluteX, 506 | absoluteWidth, 507 | deltaX, 508 | x, 509 | recWidth, 510 | originalTarget, 511 | }); 512 | } 513 | }); 514 | this.targets = newTargets; 515 | } 516 | moveTargetY(deltaY) { 517 | const { height } = this.canvas; 518 | console.log(`Move target y ${deltaY}`); 519 | const newTargets = []; 520 | this.targets.forEach(({ y, recHeight, ...other }, index) => { 521 | const target = { y: y + deltaY, recHeight, ...other }; 522 | const absoluteY = (y * height) / 100; 523 | const absoluteHeight = (recHeight * height) / 100; 524 | if (absoluteY + absoluteHeight > 0) { 525 | newTargets.push(target); 526 | } else { 527 | console.log(`removing target`); 528 | } 529 | }); 530 | this.targets = newTargets; 531 | } 532 | endGame() { 533 | this.clearGameLoop(); 534 | window.setTimeout(() => { 535 | this.intepretCode(this.scenario.onEnd()); 536 | this.renderFrame(this.scenario, true); 537 | }, 100); 538 | 539 | this.onGameEnd(); 540 | } 541 | 542 | onGameUpdated() { 543 | if (this.isGameRunning) { 544 | this.clearGameLoop(); 545 | this.onGameEnd(); 546 | } 547 | } 548 | } 549 | -------------------------------------------------------------------------------- /public/images/deadChicken.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 41 | 47 | 49 | 51 | 55 | 59 | 63 | 67 | 71 | 75 | 79 | 83 | 87 | 91 | 95 | 99 | 103 | 104 | 110 | 113 | 116 | 119 | 120 | 123 | 126 | 129 | 132 | 135 | 138 | 141 | 144 | 147 | 150 | 153 | 156 | 159 | 162 | 165 | 168 | 171 | 174 | 177 | 180 | 181 | 196 | 197 | image/svg+xmlOpenclipart 206 | -------------------------------------------------------------------------------- /src/components/blocky/toolbox.js: -------------------------------------------------------------------------------- 1 | export const toolbox = { 2 | kind: "categoryToolbox", 3 | contents: [ 4 | { 5 | kind: "category", 6 | name: "Loops", 7 | colour: "#5ba55b", 8 | contents: [ 9 | { 10 | kind: "block", 11 | blockxml: ` 12 | 13 | 14 | 10 15 | 16 | 17 | `, 18 | }, 19 | { 20 | kind: "block", 21 | blockxml: ` 22 | WHILE 23 | `, 24 | }, 25 | { 26 | kind: "block", 27 | blockxml: ` 28 | i 29 | 30 | 31 | 1 32 | 33 | 34 | 35 | 36 | 10 37 | 38 | 39 | 40 | 41 | 1 42 | 43 | 44 | `, 45 | }, 46 | { 47 | kind: "block", 48 | blockxml: ` 49 | j 50 | `, 51 | }, 52 | { 53 | kind: "block", 54 | blockxml: ` 55 | 56 | BREAK 57 | `, 58 | }, 59 | ], 60 | }, 61 | { 62 | kind: "category", 63 | name: "logic", 64 | colour: "210", 65 | contents: [ 66 | { 67 | kind: "block", 68 | type: "controls_if", 69 | }, 70 | { 71 | kind: "block", 72 | type: "controls_whileUntil", 73 | }, 74 | { 75 | kind: "block", 76 | blockxml: ` 77 | EQ 78 | `, 79 | }, 80 | { 81 | kind: "block", 82 | blockxml: ` 83 | AND 84 | `, 85 | }, 86 | { 87 | kind: "block", 88 | blockxml: ` 89 | TRUE 90 | `, 91 | }, 92 | { kind: "block", type: "logic_negate" }, 93 | { kind: "block", type: "logic_null" }, 94 | { kind: "block", type: "logic_ternary" }, 95 | ], 96 | }, 97 | { 98 | kind: "category", 99 | name: "Math", 100 | colour: "#5b67a5", 101 | contents: [ 102 | { 103 | kind: "block", 104 | blockxml: ` 105 | 0 106 | `, 107 | }, 108 | { 109 | kind: "block", 110 | blockxml: ` 111 | ADD 112 | 113 | 114 | 1 115 | 116 | 117 | 118 | 119 | 1 120 | 121 | 122 | `, 123 | }, 124 | { 125 | kind: "block", 126 | blockxml: ` 127 | ROOT 128 | 129 | 130 | 9 131 | 132 | 133 | `, 134 | }, 135 | { 136 | kind: "block", 137 | blockxml: ` 138 | SIN 139 | 140 | 141 | 45 142 | 143 | 144 | `, 145 | }, 146 | { 147 | kind: "block", 148 | blockxml: ` 149 | PI 150 | `, 151 | }, 152 | { 153 | kind: "block", 154 | blockxml: ` 155 | 156 | EVEN 157 | 158 | 159 | 0 160 | 161 | 162 | `, 163 | }, 164 | { 165 | kind: "block", 166 | blockxml: ` 167 | ROUND 168 | 169 | 170 | 3.1 171 | 172 | 173 | `, 174 | }, 175 | { 176 | kind: "block", 177 | blockxml: ` 178 | 179 | SUM 180 | `, 181 | }, 182 | { 183 | kind: "block", 184 | blockxml: ` 185 | 186 | 187 | 64 188 | 189 | 190 | 191 | 192 | 10 193 | 194 | 195 | `, 196 | }, 197 | { 198 | kind: "block", 199 | blockxml: ` 200 | 201 | 202 | 50 203 | 204 | 205 | 206 | 207 | 1 208 | 209 | 210 | 211 | 212 | 100 213 | 214 | 215 | `, 216 | }, 217 | { 218 | kind: "block", 219 | blockxml: ` 220 | 221 | 222 | 1 223 | 224 | 225 | 226 | 227 | 100 228 | 229 | 230 | `, 231 | }, 232 | { kind: "block", type: "math_random_float" }, 233 | ], 234 | }, 235 | { 236 | kind: "category", 237 | name: "text", 238 | colour: "#5ba58c", 239 | contents: [ 240 | { 241 | kind: "block", 242 | blockxml: ` 243 | 244 | `, 245 | }, 246 | { 247 | kind: "block", 248 | blockxml: ` 249 | 250 | 251 | `, 252 | }, 253 | { 254 | kind: "block", 255 | blockxml: ` 256 | item 257 | 258 | 259 | 260 | 261 | 262 | `, 263 | }, 264 | { 265 | kind: "block", 266 | blockxml: ` 267 | 268 | 269 | 270 | abc 271 | 272 | 273 | `, 274 | }, 275 | { 276 | kind: "block", 277 | blockxml: ` 278 | 279 | 280 | 281 | 282 | 283 | 284 | `, 285 | }, 286 | { 287 | kind: "block", 288 | blockxml: ` 289 | FIRST 290 | 291 | 292 | text 293 | 294 | 295 | 296 | 297 | abc 298 | 299 | 300 | `, 301 | }, 302 | { 303 | kind: "block", 304 | blockxml: ` 305 | 306 | FROM_START 307 | 308 | 309 | text 310 | 311 | 312 | `, 313 | }, 314 | { 315 | kind: "block", 316 | blockxml: ` 317 | 318 | FROM_START 319 | FROM_START 320 | 321 | 322 | text 323 | 324 | 325 | `, 326 | }, 327 | { 328 | kind: "block", 329 | blockxml: ` 330 | UPPERCASE 331 | 332 | 333 | abc 334 | 335 | 336 | `, 337 | }, 338 | { 339 | kind: "block", 340 | blockxml: ` 341 | BOTH 342 | 343 | 344 | abc 345 | 346 | 347 | `, 348 | }, 349 | { 350 | kind: "block", 351 | blockxml: ` 352 | 353 | 354 | abc 355 | 356 | 357 | `, 358 | }, 359 | /* { 360 | kind: 'block', 361 | blockxml: ` 362 | 363 | TEXT 364 | 365 | 366 | abc 367 | 368 | 369 | `, 370 | }, */ 371 | ], 372 | }, 373 | { 374 | kind: "category", 375 | name: "Lists", 376 | colour: "#745ba5", 377 | contents: [ 378 | { 379 | kind: "block", 380 | blockxml: ` 381 | 382 | `, 383 | }, 384 | { 385 | kind: "block", 386 | blockxml: ` 387 | 388 | `, 389 | }, 390 | { 391 | kind: "block", 392 | blockxml: ` 393 | 394 | 395 | 5 396 | 397 | 398 | `, 399 | }, 400 | { kind: "block", type: "lists_length" }, 401 | { 402 | kind: "block", 403 | blockxml: ` 404 | FIRST 405 | 406 | 407 | list 408 | 409 | 410 | `, 411 | }, 412 | { 413 | kind: "block", 414 | blockxml: ` 415 | 416 | GET 417 | FROM_START 418 | 419 | 420 | list 421 | 422 | 423 | `, 424 | }, 425 | { 426 | kind: "block", 427 | blockxml: ` 428 | 429 | SET 430 | FROM_START 431 | 432 | 433 | list 434 | 435 | 436 | `, 437 | }, 438 | { 439 | kind: "block", 440 | blockxml: ` 441 | 442 | FROM_START 443 | FROM_START 444 | 445 | 446 | list 447 | 448 | 449 | `, 450 | }, 451 | { 452 | kind: "block", 453 | blockxml: ` 454 | 455 | SPLIT 456 | 457 | 458 | , 459 | 460 | 461 | `, 462 | }, 463 | { 464 | kind: "block", 465 | blockxml: ` 466 | NUMERIC 467 | 1 468 | `, 469 | }, 470 | ], 471 | }, 472 | { 473 | kind: "category", 474 | name: "Colour", 475 | colour: "#a5745b", 476 | contents: [ 477 | { 478 | kind: "block", 479 | blockxml: ` 480 | #ff0000 481 | `, 482 | }, 483 | { kind: "block", type: "colour_random" }, 484 | { 485 | kind: "block", 486 | blockxml: ` 487 | 488 | 489 | 100 490 | 491 | 492 | 493 | 494 | 50 495 | 496 | 497 | 498 | 499 | 0 500 | 501 | 502 | `, 503 | }, 504 | { 505 | kind: "block", 506 | blockxml: ` 507 | 508 | 509 | #ff0000 510 | 511 | 512 | 513 | 514 | #3333ff 515 | 516 | 517 | 518 | 519 | 0.5 520 | 521 | 522 | `, 523 | }, 524 | ], 525 | }, 526 | { kind: "sep" }, 527 | { 528 | kind: "category", 529 | name: "Variables", 530 | colour: "#a55b80", 531 | custom: "VARIABLE", 532 | }, 533 | { 534 | kind: "category", 535 | name: "Procedures", 536 | colour: "#995ba5", 537 | custom: "PROCEDURE", 538 | }, 539 | { kind: "sep" }, 540 | { 541 | kind: "category", 542 | name: "canvas", 543 | colour: "#6600cc", 544 | contents: [ 545 | { 546 | kind: "block", 547 | blockxml: ` 548 | 549 | 550 | #33ccff 551 | 552 | 553 | `, 554 | }, 555 | { 556 | kind: "block", 557 | blockxml: ` 558 | 559 | 560 | #000000 561 | 562 | 563 | `, 564 | }, 565 | { kind: "block", type: "canvas_set_text_align" }, 566 | { 567 | kind: "block", 568 | blockxml: ` 569 | 570 | 571 | 3 572 | 573 | 574 | 575 | `, 576 | }, 577 | { 578 | kind: "block", 579 | blockxml: ` 580 | 581 | 582 | #00FF00 583 | 584 | 585 | 586 | 587 | 588 | 0 589 | 590 | 591 | 592 | 593 | 0 594 | 595 | 596 | 597 | 598 | 5 599 | 600 | 601 | 602 | 603 | 35 604 | 605 | 606 | `, 607 | }, 608 | { kind: "block", type: "canvas_width" }, 609 | { kind: "block", type: "canvas_height" }, 610 | { 611 | kind: "block", 612 | blockxml: ` 613 | 614 | 615 | 0 616 | 617 | 618 | 619 | 620 | 621 | 0 622 | 623 | 624 | 625 | `, 626 | }, 627 | ], 628 | }, 629 | { 630 | kind: "category", 631 | name: "game", 632 | colour: "#FFAABB", 633 | contents: [ 634 | { 635 | kind: "block", 636 | 637 | blockxml: ` 638 | 639 | 640 | 500 641 | 642 | 643 | 644 | 645 | 900 646 | 647 | 648 | 649 | 650 | 651 | 2000 652 | 653 | 654 | 655 | `, 656 | }, 657 | { kind: "block", type: "game_duck" }, 658 | { kind: "block", type: "game_dead_duck" }, 659 | { kind: "block", type: "game_chicken" }, 660 | { kind: "block", type: "game_dead_chicken" }, 661 | 662 | { kind: "block", type: "player_x" }, 663 | { kind: "block", type: "player_y" }, 664 | { kind: "block", type: "game_set_player_position" }, 665 | { kind: "block", type: "game_set_player_position_x" }, 666 | { kind: "block", type: "game_set_player_position_y" }, 667 | { kind: "block", type: "game_set_player_icon" }, 668 | { kind: "block", type: "game_obstacle" }, 669 | { kind: "block", type: "game_target" }, 670 | { kind: "block", type: "game_move_obstacle_x" }, 671 | { kind: "block", type: "game_move_obstacle_y" }, 672 | { kind: "block", type: "game_move_target_x" }, 673 | { kind: "block", type: "game_move_target_y" }, 674 | { kind: "block", type: "game_end_game" }, 675 | ], 676 | }, 677 | ], 678 | }; 679 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.15.8": 6 | version "7.15.8" 7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.15.8.tgz#45990c47adadb00c03677baa89221f7cc23d2503" 8 | integrity sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg== 9 | dependencies: 10 | "@babel/highlight" "^7.14.5" 11 | 12 | "@babel/compat-data@^7.15.0": 13 | version "7.15.0" 14 | resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" 15 | integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== 16 | 17 | "@babel/core@^7.15.5": 18 | version "7.15.8" 19 | resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.8.tgz#195b9f2bffe995d2c6c159e72fe525b4114e8c10" 20 | integrity sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og== 21 | dependencies: 22 | "@babel/code-frame" "^7.15.8" 23 | "@babel/generator" "^7.15.8" 24 | "@babel/helper-compilation-targets" "^7.15.4" 25 | "@babel/helper-module-transforms" "^7.15.8" 26 | "@babel/helpers" "^7.15.4" 27 | "@babel/parser" "^7.15.8" 28 | "@babel/template" "^7.15.4" 29 | "@babel/traverse" "^7.15.4" 30 | "@babel/types" "^7.15.6" 31 | convert-source-map "^1.7.0" 32 | debug "^4.1.0" 33 | gensync "^1.0.0-beta.2" 34 | json5 "^2.1.2" 35 | semver "^6.3.0" 36 | source-map "^0.5.0" 37 | 38 | "@babel/generator@^7.15.4", "@babel/generator@^7.15.8": 39 | version "7.15.8" 40 | resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.8.tgz#fa56be6b596952ceb231048cf84ee499a19c0cd1" 41 | integrity sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g== 42 | dependencies: 43 | "@babel/types" "^7.15.6" 44 | jsesc "^2.5.1" 45 | source-map "^0.5.0" 46 | 47 | "@babel/helper-annotate-as-pure@^7.14.5": 48 | version "7.15.4" 49 | resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz#3d0e43b00c5e49fdb6c57e421601a7a658d5f835" 50 | integrity sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA== 51 | dependencies: 52 | "@babel/types" "^7.15.4" 53 | 54 | "@babel/helper-compilation-targets@^7.15.4": 55 | version "7.15.4" 56 | resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9" 57 | integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ== 58 | dependencies: 59 | "@babel/compat-data" "^7.15.0" 60 | "@babel/helper-validator-option" "^7.14.5" 61 | browserslist "^4.16.6" 62 | semver "^6.3.0" 63 | 64 | "@babel/helper-function-name@^7.15.4": 65 | version "7.15.4" 66 | resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" 67 | integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== 68 | dependencies: 69 | "@babel/helper-get-function-arity" "^7.15.4" 70 | "@babel/template" "^7.15.4" 71 | "@babel/types" "^7.15.4" 72 | 73 | "@babel/helper-get-function-arity@^7.15.4": 74 | version "7.15.4" 75 | resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" 76 | integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA== 77 | dependencies: 78 | "@babel/types" "^7.15.4" 79 | 80 | "@babel/helper-hoist-variables@^7.15.4": 81 | version "7.15.4" 82 | resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" 83 | integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA== 84 | dependencies: 85 | "@babel/types" "^7.15.4" 86 | 87 | "@babel/helper-member-expression-to-functions@^7.15.4": 88 | version "7.15.4" 89 | resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz#bfd34dc9bba9824a4658b0317ec2fd571a51e6ef" 90 | integrity sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA== 91 | dependencies: 92 | "@babel/types" "^7.15.4" 93 | 94 | "@babel/helper-module-imports@^7.14.5", "@babel/helper-module-imports@^7.15.4": 95 | version "7.15.4" 96 | resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f" 97 | integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA== 98 | dependencies: 99 | "@babel/types" "^7.15.4" 100 | 101 | "@babel/helper-module-transforms@^7.15.8": 102 | version "7.15.8" 103 | resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz#d8c0e75a87a52e374a8f25f855174786a09498b2" 104 | integrity sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg== 105 | dependencies: 106 | "@babel/helper-module-imports" "^7.15.4" 107 | "@babel/helper-replace-supers" "^7.15.4" 108 | "@babel/helper-simple-access" "^7.15.4" 109 | "@babel/helper-split-export-declaration" "^7.15.4" 110 | "@babel/helper-validator-identifier" "^7.15.7" 111 | "@babel/template" "^7.15.4" 112 | "@babel/traverse" "^7.15.4" 113 | "@babel/types" "^7.15.6" 114 | 115 | "@babel/helper-optimise-call-expression@^7.15.4": 116 | version "7.15.4" 117 | resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171" 118 | integrity sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw== 119 | dependencies: 120 | "@babel/types" "^7.15.4" 121 | 122 | "@babel/helper-plugin-utils@^7.14.5": 123 | version "7.14.5" 124 | resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" 125 | integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== 126 | 127 | "@babel/helper-replace-supers@^7.15.4": 128 | version "7.15.4" 129 | resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz#52a8ab26ba918c7f6dee28628b07071ac7b7347a" 130 | integrity sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw== 131 | dependencies: 132 | "@babel/helper-member-expression-to-functions" "^7.15.4" 133 | "@babel/helper-optimise-call-expression" "^7.15.4" 134 | "@babel/traverse" "^7.15.4" 135 | "@babel/types" "^7.15.4" 136 | 137 | "@babel/helper-simple-access@^7.15.4": 138 | version "7.15.4" 139 | resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b" 140 | integrity sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg== 141 | dependencies: 142 | "@babel/types" "^7.15.4" 143 | 144 | "@babel/helper-split-export-declaration@^7.15.4": 145 | version "7.15.4" 146 | resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257" 147 | integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw== 148 | dependencies: 149 | "@babel/types" "^7.15.4" 150 | 151 | "@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.15.7": 152 | version "7.15.7" 153 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" 154 | integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== 155 | 156 | "@babel/helper-validator-option@^7.14.5": 157 | version "7.14.5" 158 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" 159 | integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== 160 | 161 | "@babel/helpers@^7.15.4": 162 | version "7.15.4" 163 | resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.4.tgz#5f40f02050a3027121a3cf48d497c05c555eaf43" 164 | integrity sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ== 165 | dependencies: 166 | "@babel/template" "^7.15.4" 167 | "@babel/traverse" "^7.15.4" 168 | "@babel/types" "^7.15.4" 169 | 170 | "@babel/highlight@^7.14.5": 171 | version "7.14.5" 172 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" 173 | integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== 174 | dependencies: 175 | "@babel/helper-validator-identifier" "^7.14.5" 176 | chalk "^2.0.0" 177 | js-tokens "^4.0.0" 178 | 179 | "@babel/parser@^7.15.4", "@babel/parser@^7.15.8": 180 | version "7.15.8" 181 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016" 182 | integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA== 183 | 184 | "@babel/plugin-syntax-jsx@^7.14.5": 185 | version "7.14.5" 186 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz#000e2e25d8673cce49300517a3eda44c263e4201" 187 | integrity sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw== 188 | dependencies: 189 | "@babel/helper-plugin-utils" "^7.14.5" 190 | 191 | "@babel/plugin-transform-react-jsx-development@^7.14.5": 192 | version "7.14.5" 193 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.14.5.tgz#1a6c73e2f7ed2c42eebc3d2ad60b0c7494fcb9af" 194 | integrity sha512-rdwG/9jC6QybWxVe2UVOa7q6cnTpw8JRRHOxntG/h6g/guAOe6AhtQHJuJh5FwmnXIT1bdm5vC2/5huV8ZOorQ== 195 | dependencies: 196 | "@babel/plugin-transform-react-jsx" "^7.14.5" 197 | 198 | "@babel/plugin-transform-react-jsx-self@^7.14.9": 199 | version "7.14.9" 200 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.14.9.tgz#33041e665453391eb6ee54a2ecf3ba1d46bd30f4" 201 | integrity sha512-Fqqu0f8zv9W+RyOnx29BX/RlEsBRANbOf5xs5oxb2aHP4FKbLXxIaVPUiCti56LAR1IixMH4EyaixhUsKqoBHw== 202 | dependencies: 203 | "@babel/helper-plugin-utils" "^7.14.5" 204 | 205 | "@babel/plugin-transform-react-jsx-source@^7.14.5": 206 | version "7.14.5" 207 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.14.5.tgz#79f728e60e6dbd31a2b860b0bf6c9765918acf1d" 208 | integrity sha512-1TpSDnD9XR/rQ2tzunBVPThF5poaYT9GqP+of8fAtguYuI/dm2RkrMBDemsxtY0XBzvW7nXjYM0hRyKX9QYj7Q== 209 | dependencies: 210 | "@babel/helper-plugin-utils" "^7.14.5" 211 | 212 | "@babel/plugin-transform-react-jsx@^7.14.5", "@babel/plugin-transform-react-jsx@^7.14.9": 213 | version "7.14.9" 214 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.9.tgz#3314b2163033abac5200a869c4de242cd50a914c" 215 | integrity sha512-30PeETvS+AeD1f58i1OVyoDlVYQhap/K20ZrMjLmmzmC2AYR/G43D4sdJAaDAqCD3MYpSWbmrz3kES158QSLjw== 216 | dependencies: 217 | "@babel/helper-annotate-as-pure" "^7.14.5" 218 | "@babel/helper-module-imports" "^7.14.5" 219 | "@babel/helper-plugin-utils" "^7.14.5" 220 | "@babel/plugin-syntax-jsx" "^7.14.5" 221 | "@babel/types" "^7.14.9" 222 | 223 | "@babel/template@^7.15.4": 224 | version "7.15.4" 225 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" 226 | integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== 227 | dependencies: 228 | "@babel/code-frame" "^7.14.5" 229 | "@babel/parser" "^7.15.4" 230 | "@babel/types" "^7.15.4" 231 | 232 | "@babel/traverse@^7.15.4": 233 | version "7.15.4" 234 | resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" 235 | integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== 236 | dependencies: 237 | "@babel/code-frame" "^7.14.5" 238 | "@babel/generator" "^7.15.4" 239 | "@babel/helper-function-name" "^7.15.4" 240 | "@babel/helper-hoist-variables" "^7.15.4" 241 | "@babel/helper-split-export-declaration" "^7.15.4" 242 | "@babel/parser" "^7.15.4" 243 | "@babel/types" "^7.15.4" 244 | debug "^4.1.0" 245 | globals "^11.1.0" 246 | 247 | "@babel/types@^7.14.9", "@babel/types@^7.15.4", "@babel/types@^7.15.6": 248 | version "7.15.6" 249 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" 250 | integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== 251 | dependencies: 252 | "@babel/helper-validator-identifier" "^7.14.9" 253 | to-fast-properties "^2.0.0" 254 | 255 | "@rollup/pluginutils@^4.1.1": 256 | version "4.1.1" 257 | resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.1.tgz#1d4da86dd4eded15656a57d933fda2b9a08d47ec" 258 | integrity sha512-clDjivHqWGXi7u+0d2r2sBi4Ie6VLEAzWMIkvJLnDmxoOhBYOTfzGbOQBA32THHm11/LiJbd01tJUpJsbshSWQ== 259 | dependencies: 260 | estree-walker "^2.0.1" 261 | picomatch "^2.2.2" 262 | 263 | "@vitejs/plugin-react@^1.0.0": 264 | version "1.0.2" 265 | resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-1.0.2.tgz#08147baff5bcc0c66740209823169103d73437b3" 266 | integrity sha512-nhB4LkAzhOy2T+8fsYuK+4DQWTueMvzfC0+MMMaX9qVvKqGQMOgz1nF3qTMl9ht9ZzhDnR++4XZmHWI/MytgeA== 267 | dependencies: 268 | "@babel/core" "^7.15.5" 269 | "@babel/plugin-transform-react-jsx" "^7.14.9" 270 | "@babel/plugin-transform-react-jsx-development" "^7.14.5" 271 | "@babel/plugin-transform-react-jsx-self" "^7.14.9" 272 | "@babel/plugin-transform-react-jsx-source" "^7.14.5" 273 | "@rollup/pluginutils" "^4.1.1" 274 | react-refresh "^0.10.0" 275 | resolve "^1.20.0" 276 | 277 | abab@^2.0.0: 278 | version "2.0.5" 279 | resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" 280 | integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== 281 | 282 | acorn-globals@^4.3.2: 283 | version "4.3.4" 284 | resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" 285 | integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== 286 | dependencies: 287 | acorn "^6.0.1" 288 | acorn-walk "^6.0.1" 289 | 290 | acorn-walk@^6.0.1: 291 | version "6.2.0" 292 | resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" 293 | integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== 294 | 295 | acorn@^6.0.1: 296 | version "6.4.2" 297 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" 298 | integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== 299 | 300 | acorn@^7.1.0: 301 | version "7.4.1" 302 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" 303 | integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== 304 | 305 | ajv@^6.12.3: 306 | version "6.12.6" 307 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 308 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 309 | dependencies: 310 | fast-deep-equal "^3.1.1" 311 | fast-json-stable-stringify "^2.0.0" 312 | json-schema-traverse "^0.4.1" 313 | uri-js "^4.2.2" 314 | 315 | ansi-styles@^3.2.1: 316 | version "3.2.1" 317 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 318 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 319 | dependencies: 320 | color-convert "^1.9.0" 321 | 322 | array-equal@^1.0.0: 323 | version "1.0.0" 324 | resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" 325 | integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= 326 | 327 | asn1@~0.2.3: 328 | version "0.2.4" 329 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" 330 | integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== 331 | dependencies: 332 | safer-buffer "~2.1.0" 333 | 334 | assert-plus@1.0.0, assert-plus@^1.0.0: 335 | version "1.0.0" 336 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" 337 | integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= 338 | 339 | asynckit@^0.4.0: 340 | version "0.4.0" 341 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 342 | integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= 343 | 344 | aws-sign2@~0.7.0: 345 | version "0.7.0" 346 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" 347 | integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= 348 | 349 | aws4@^1.8.0: 350 | version "1.11.0" 351 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" 352 | integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== 353 | 354 | bcrypt-pbkdf@^1.0.0: 355 | version "1.0.2" 356 | resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" 357 | integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= 358 | dependencies: 359 | tweetnacl "^0.14.3" 360 | 361 | blockly@^6.20210701.0: 362 | version "6.20210701.0" 363 | resolved "https://registry.yarnpkg.com/blockly/-/blockly-6.20210701.0.tgz#578dbdc59a61339a6ba29a69d0dc7bebeb8a19d1" 364 | integrity sha512-cNrwFOAxXE5Pbs1FJAyLTlSRzpNW/C+0gPT2rGQDOJVVKcyF3vhFC1StgnxvQNsv//ueuksKWIXxDuSWh1VI4w== 365 | dependencies: 366 | jsdom "15.2.1" 367 | 368 | browser-process-hrtime@^1.0.0: 369 | version "1.0.0" 370 | resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" 371 | integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== 372 | 373 | browserslist@^4.16.6: 374 | version "4.17.3" 375 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.3.tgz#2844cd6eebe14d12384b0122d217550160d2d624" 376 | integrity sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ== 377 | dependencies: 378 | caniuse-lite "^1.0.30001264" 379 | electron-to-chromium "^1.3.857" 380 | escalade "^3.1.1" 381 | node-releases "^1.1.77" 382 | picocolors "^0.2.1" 383 | 384 | caniuse-lite@^1.0.30001264: 385 | version "1.0.30001265" 386 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz#0613c9e6c922e422792e6fcefdf9a3afeee4f8c3" 387 | integrity sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw== 388 | 389 | caseless@~0.12.0: 390 | version "0.12.0" 391 | resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" 392 | integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= 393 | 394 | chalk@^2.0.0: 395 | version "2.4.2" 396 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 397 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 398 | dependencies: 399 | ansi-styles "^3.2.1" 400 | escape-string-regexp "^1.0.5" 401 | supports-color "^5.3.0" 402 | 403 | color-convert@^1.9.0: 404 | version "1.9.3" 405 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 406 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 407 | dependencies: 408 | color-name "1.1.3" 409 | 410 | color-name@1.1.3: 411 | version "1.1.3" 412 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 413 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 414 | 415 | combined-stream@^1.0.6, combined-stream@~1.0.6: 416 | version "1.0.8" 417 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 418 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 419 | dependencies: 420 | delayed-stream "~1.0.0" 421 | 422 | convert-source-map@^1.7.0: 423 | version "1.8.0" 424 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" 425 | integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== 426 | dependencies: 427 | safe-buffer "~5.1.1" 428 | 429 | core-util-is@1.0.2: 430 | version "1.0.2" 431 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 432 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 433 | 434 | cssom@^0.4.1: 435 | version "0.4.4" 436 | resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" 437 | integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== 438 | 439 | cssom@~0.3.6: 440 | version "0.3.8" 441 | resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" 442 | integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== 443 | 444 | cssstyle@^2.0.0: 445 | version "2.3.0" 446 | resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" 447 | integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== 448 | dependencies: 449 | cssom "~0.3.6" 450 | 451 | dashdash@^1.12.0: 452 | version "1.14.1" 453 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" 454 | integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= 455 | dependencies: 456 | assert-plus "^1.0.0" 457 | 458 | data-urls@^1.1.0: 459 | version "1.1.0" 460 | resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" 461 | integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== 462 | dependencies: 463 | abab "^2.0.0" 464 | whatwg-mimetype "^2.2.0" 465 | whatwg-url "^7.0.0" 466 | 467 | debug@^4.1.0: 468 | version "4.3.2" 469 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" 470 | integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== 471 | dependencies: 472 | ms "2.1.2" 473 | 474 | deep-is@~0.1.3: 475 | version "0.1.4" 476 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" 477 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== 478 | 479 | delayed-stream@~1.0.0: 480 | version "1.0.0" 481 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 482 | integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= 483 | 484 | domexception@^1.0.1: 485 | version "1.0.1" 486 | resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" 487 | integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== 488 | dependencies: 489 | webidl-conversions "^4.0.2" 490 | 491 | ecc-jsbn@~0.1.1: 492 | version "0.1.2" 493 | resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" 494 | integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= 495 | dependencies: 496 | jsbn "~0.1.0" 497 | safer-buffer "^2.1.0" 498 | 499 | electron-to-chromium@^1.3.857: 500 | version "1.3.861" 501 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.861.tgz#981e37a79af7a7b29bbaeed36376f4795527de13" 502 | integrity sha512-GZyflmpMnZRdZ1e2yAyvuFwz1MPSVQelwHX4TJZyXypB8NcxdPvPNwy5lOTxnlkrK13EiQzyTPugRSnj6cBgKg== 503 | 504 | esbuild-android-arm64@0.13.4: 505 | version "0.13.4" 506 | resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.4.tgz#5178a20d2b7aba741a31c19609f9e67b346996b9" 507 | integrity sha512-elDJt+jNyoHFId0/dKsuVYUPke3EcquIyUwzJCH17a3ERglN3A9aMBI5zbz+xNZ+FbaDNdpn0RaJHCFLbZX+fA== 508 | 509 | esbuild-darwin-64@0.13.4: 510 | version "0.13.4" 511 | resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.13.4.tgz#7a3e66c8e1271b650541b25eed65c84f3564a69d" 512 | integrity sha512-zJQGyHRAdZUXlRzbN7W+7ykmEiGC+bq3Gc4GxKYjjWTgDRSEly98ym+vRNkDjXwXYD3gGzSwvH35+MiHAtWvLA== 513 | 514 | esbuild-darwin-arm64@0.13.4: 515 | version "0.13.4" 516 | resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.4.tgz#793feca6032b2a57ef291eb9b2d33768d60a49d6" 517 | integrity sha512-r8oYvAtqSGq8HNTZCAx4TdLE7jZiGhX9ooGi5AQAey37MA6XNaP8ZNlw9OCpcgpx3ryU2WctXwIqPzkHO7a8dg== 518 | 519 | esbuild-freebsd-64@0.13.4: 520 | version "0.13.4" 521 | resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.4.tgz#294aec3c2cf4b41fb6900212fc9c33dd8fbbb4a2" 522 | integrity sha512-u9DRGkn09EN8+lCh6z7FKle7awi17PJRBuAKdRNgSo5ZrH/3m+mYaJK2PR2URHMpAfXiwJX341z231tSdVe3Yw== 523 | 524 | esbuild-freebsd-arm64@0.13.4: 525 | version "0.13.4" 526 | resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.4.tgz#09fe66c751c12f9b976976b1d83f3de594cb2787" 527 | integrity sha512-q3B2k68Uf6gfjATjcK16DqxvjqRQkHL8aPoOfj4op+lSqegdXvBacB1d8jw8PxbWJ8JHpdTLdAVUYU80kotQXA== 528 | 529 | esbuild-linux-32@0.13.4: 530 | version "0.13.4" 531 | resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.13.4.tgz#a9f0793d7bcc9cef4f4ffa4398c525877fba5839" 532 | integrity sha512-UUYJPHSiKAO8KoN3Ls/iZtgDLZvK5HarES96aolDPWZnq9FLx4dIHM/x2z4Rxv9IYqQ/DxlPoE2Co1UPBIYYeA== 533 | 534 | esbuild-linux-64@0.13.4: 535 | version "0.13.4" 536 | resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.13.4.tgz#c0d0b4c9d62e3bbf8bdf2cece37403aa6d60fc2e" 537 | integrity sha512-+RnohAKiiUW4UHLGRkNR1AnENW1gCuDWuygEtd4jxTNPIoeC7lbXGor7rtgjj9AdUzFgOEvAXyNNX01kJ8NueQ== 538 | 539 | esbuild-linux-arm64@0.13.4: 540 | version "0.13.4" 541 | resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.4.tgz#1292d97bfa64a08d12728f8a7837bf92776c779b" 542 | integrity sha512-+A188cAdd6QuSRxMIwRrWLjgphQA0LDAQ/ECVlrPVJwnx+1i64NjDZivoqPYLOTkSPIKntiWwMhhf0U5/RrPHQ== 543 | 544 | esbuild-linux-arm@0.13.4: 545 | version "0.13.4" 546 | resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.13.4.tgz#186cd9b8885ac132b9953a4a0afe668168debd10" 547 | integrity sha512-BH5gKve4jglS7UPSsfwHSX79I5agC/lm4eKoRUEyo8lwQs89frQSRp2Xup+6SFQnxt3md5EsKcd2Dbkqeb3gPA== 548 | 549 | esbuild-linux-mips64le@0.13.4: 550 | version "0.13.4" 551 | resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.4.tgz#42049bf72bc586817b4a51cc9e32148d13e5e807" 552 | integrity sha512-0xkwtPaUkG5xMTFGaQPe1AadSe5QAiQuD4Gix1O9k5Xo/U8xGIkw9UFUTvfEUeu71vFb6ZgsIacfP1NLoFjWNw== 553 | 554 | esbuild-linux-ppc64le@0.13.4: 555 | version "0.13.4" 556 | resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.4.tgz#adf1ce2ef2302757c4383887da6ac4dd25be9d4f" 557 | integrity sha512-E1+oJPP7A+j23GPo3CEpBhGwG1bni4B8IbTA3/3rvzjURwUMZdcN3Fhrz24rnjzdLSHmULtOE4VsbT42h1Om4Q== 558 | 559 | esbuild-openbsd-64@0.13.4: 560 | version "0.13.4" 561 | resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.4.tgz#1c8122101898c52a20c8786935cf3eb7a19b83b4" 562 | integrity sha512-xEkI1o5HYxDzbv9jSox0EsDxpwraG09SRiKKv0W8pH6O3bt+zPSlnoK7+I7Q69tkvONkpIq5n2o+c55uq0X7cw== 563 | 564 | esbuild-sunos-64@0.13.4: 565 | version "0.13.4" 566 | resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.13.4.tgz#4ec95faa14a60f295fe485bebffefff408739337" 567 | integrity sha512-bjXUMcODMnB6hQicLBBmmnBl7OMDyVpFahKvHGXJfDChIi5udiIRKCmFUFIRn+AUAKVlfrofRKdyPC7kBsbvGQ== 568 | 569 | esbuild-windows-32@0.13.4: 570 | version "0.13.4" 571 | resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.13.4.tgz#3182c380487b797b04d0ec2c80c2945666869080" 572 | integrity sha512-z4CH07pfyVY0XF98TCsGmLxKCl0kyvshKDbdpTekW9f2d+dJqn5mmoUyWhpSVJ0SfYWJg86FoD9nMbbaMVyGdg== 573 | 574 | esbuild-windows-64@0.13.4: 575 | version "0.13.4" 576 | resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.13.4.tgz#b9e995f92d81f433a04f33611e603e82f9232e69" 577 | integrity sha512-uVL11vORRPjocGLYam67rwFLd0LvkrHEs+JG+1oJN4UD9MQmNGZPa4gBHo6hDpF+kqRJ9kXgQSeDqUyRy0tj/Q== 578 | 579 | esbuild-windows-arm64@0.13.4: 580 | version "0.13.4" 581 | resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.4.tgz#fb239532f07b764d158f4cc787178ef4c6fadb5c" 582 | integrity sha512-vA6GLvptgftRcDcWngD5cMlL4f4LbL8JjU2UMT9yJ0MT5ra6hdZNFWnOeOoEtY4GtJ6OjZ0i+81sTqhAB0fMkg== 583 | 584 | esbuild@^0.13.2: 585 | version "0.13.4" 586 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.13.4.tgz#ce2deb56c4fb360938311cbfc67f8e467bb6841b" 587 | integrity sha512-wMA5eUwpavTBiNl+It6j8OQuKVh69l6z4DKDLzoTIqC+gChnPpcmqdA8WNHptUHRnfyML+mKEQPlW7Mybj8gHg== 588 | optionalDependencies: 589 | esbuild-android-arm64 "0.13.4" 590 | esbuild-darwin-64 "0.13.4" 591 | esbuild-darwin-arm64 "0.13.4" 592 | esbuild-freebsd-64 "0.13.4" 593 | esbuild-freebsd-arm64 "0.13.4" 594 | esbuild-linux-32 "0.13.4" 595 | esbuild-linux-64 "0.13.4" 596 | esbuild-linux-arm "0.13.4" 597 | esbuild-linux-arm64 "0.13.4" 598 | esbuild-linux-mips64le "0.13.4" 599 | esbuild-linux-ppc64le "0.13.4" 600 | esbuild-openbsd-64 "0.13.4" 601 | esbuild-sunos-64 "0.13.4" 602 | esbuild-windows-32 "0.13.4" 603 | esbuild-windows-64 "0.13.4" 604 | esbuild-windows-arm64 "0.13.4" 605 | 606 | escalade@^3.1.1: 607 | version "3.1.1" 608 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 609 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 610 | 611 | escape-string-regexp@^1.0.5: 612 | version "1.0.5" 613 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 614 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 615 | 616 | escodegen@^1.11.1: 617 | version "1.14.3" 618 | resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" 619 | integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== 620 | dependencies: 621 | esprima "^4.0.1" 622 | estraverse "^4.2.0" 623 | esutils "^2.0.2" 624 | optionator "^0.8.1" 625 | optionalDependencies: 626 | source-map "~0.6.1" 627 | 628 | esprima@^4.0.1: 629 | version "4.0.1" 630 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 631 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 632 | 633 | estraverse@^4.2.0: 634 | version "4.3.0" 635 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" 636 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== 637 | 638 | estree-walker@^2.0.1: 639 | version "2.0.2" 640 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" 641 | integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== 642 | 643 | esutils@^2.0.2: 644 | version "2.0.3" 645 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 646 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 647 | 648 | extend@~3.0.2: 649 | version "3.0.2" 650 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" 651 | integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== 652 | 653 | extsprintf@1.3.0: 654 | version "1.3.0" 655 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" 656 | integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= 657 | 658 | extsprintf@^1.2.0: 659 | version "1.4.0" 660 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" 661 | integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= 662 | 663 | fast-deep-equal@^3.1.1: 664 | version "3.1.3" 665 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 666 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 667 | 668 | fast-json-stable-stringify@^2.0.0: 669 | version "2.1.0" 670 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 671 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 672 | 673 | fast-levenshtein@~2.0.6: 674 | version "2.0.6" 675 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 676 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 677 | 678 | forever-agent@~0.6.1: 679 | version "0.6.1" 680 | resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" 681 | integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= 682 | 683 | form-data@~2.3.2: 684 | version "2.3.3" 685 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" 686 | integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== 687 | dependencies: 688 | asynckit "^0.4.0" 689 | combined-stream "^1.0.6" 690 | mime-types "^2.1.12" 691 | 692 | fsevents@~2.3.2: 693 | version "2.3.2" 694 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 695 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 696 | 697 | function-bind@^1.1.1: 698 | version "1.1.1" 699 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 700 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 701 | 702 | gensync@^1.0.0-beta.2: 703 | version "1.0.0-beta.2" 704 | resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" 705 | integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== 706 | 707 | getpass@^0.1.1: 708 | version "0.1.7" 709 | resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" 710 | integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= 711 | dependencies: 712 | assert-plus "^1.0.0" 713 | 714 | globals@^11.1.0: 715 | version "11.12.0" 716 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" 717 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== 718 | 719 | har-schema@^2.0.0: 720 | version "2.0.0" 721 | resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" 722 | integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= 723 | 724 | har-validator@~5.1.3: 725 | version "5.1.5" 726 | resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" 727 | integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== 728 | dependencies: 729 | ajv "^6.12.3" 730 | har-schema "^2.0.0" 731 | 732 | has-flag@^3.0.0: 733 | version "3.0.0" 734 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 735 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 736 | 737 | has@^1.0.3: 738 | version "1.0.3" 739 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 740 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 741 | dependencies: 742 | function-bind "^1.1.1" 743 | 744 | html-encoding-sniffer@^1.0.2: 745 | version "1.0.2" 746 | resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" 747 | integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== 748 | dependencies: 749 | whatwg-encoding "^1.0.1" 750 | 751 | http-signature@~1.2.0: 752 | version "1.2.0" 753 | resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" 754 | integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= 755 | dependencies: 756 | assert-plus "^1.0.0" 757 | jsprim "^1.2.2" 758 | sshpk "^1.7.0" 759 | 760 | iconv-lite@0.4.24: 761 | version "0.4.24" 762 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 763 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 764 | dependencies: 765 | safer-buffer ">= 2.1.2 < 3" 766 | 767 | ip-regex@^2.1.0: 768 | version "2.1.0" 769 | resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" 770 | integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= 771 | 772 | is-core-module@^2.2.0: 773 | version "2.7.0" 774 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" 775 | integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== 776 | dependencies: 777 | has "^1.0.3" 778 | 779 | is-typedarray@~1.0.0: 780 | version "1.0.0" 781 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 782 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= 783 | 784 | isstream@~0.1.2: 785 | version "0.1.2" 786 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" 787 | integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= 788 | 789 | "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: 790 | version "4.0.0" 791 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 792 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 793 | 794 | jsbn@~0.1.0: 795 | version "0.1.1" 796 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" 797 | integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= 798 | 799 | jsdom@15.2.1: 800 | version "15.2.1" 801 | resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" 802 | integrity sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g== 803 | dependencies: 804 | abab "^2.0.0" 805 | acorn "^7.1.0" 806 | acorn-globals "^4.3.2" 807 | array-equal "^1.0.0" 808 | cssom "^0.4.1" 809 | cssstyle "^2.0.0" 810 | data-urls "^1.1.0" 811 | domexception "^1.0.1" 812 | escodegen "^1.11.1" 813 | html-encoding-sniffer "^1.0.2" 814 | nwsapi "^2.2.0" 815 | parse5 "5.1.0" 816 | pn "^1.1.0" 817 | request "^2.88.0" 818 | request-promise-native "^1.0.7" 819 | saxes "^3.1.9" 820 | symbol-tree "^3.2.2" 821 | tough-cookie "^3.0.1" 822 | w3c-hr-time "^1.0.1" 823 | w3c-xmlserializer "^1.1.2" 824 | webidl-conversions "^4.0.2" 825 | whatwg-encoding "^1.0.5" 826 | whatwg-mimetype "^2.3.0" 827 | whatwg-url "^7.0.0" 828 | ws "^7.0.0" 829 | xml-name-validator "^3.0.0" 830 | 831 | jsesc@^2.5.1: 832 | version "2.5.2" 833 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" 834 | integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== 835 | 836 | json-schema-traverse@^0.4.1: 837 | version "0.4.1" 838 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 839 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 840 | 841 | json-schema@0.2.3: 842 | version "0.2.3" 843 | resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" 844 | integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= 845 | 846 | json-stringify-safe@~5.0.1: 847 | version "5.0.1" 848 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 849 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= 850 | 851 | json5@^2.1.2: 852 | version "2.2.0" 853 | resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" 854 | integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== 855 | dependencies: 856 | minimist "^1.2.5" 857 | 858 | jsprim@^1.2.2: 859 | version "1.4.1" 860 | resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" 861 | integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= 862 | dependencies: 863 | assert-plus "1.0.0" 864 | extsprintf "1.3.0" 865 | json-schema "0.2.3" 866 | verror "1.10.0" 867 | 868 | levn@~0.3.0: 869 | version "0.3.0" 870 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" 871 | integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= 872 | dependencies: 873 | prelude-ls "~1.1.2" 874 | type-check "~0.3.2" 875 | 876 | lodash.sortby@^4.7.0: 877 | version "4.7.0" 878 | resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" 879 | integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= 880 | 881 | lodash@^4.17.19: 882 | version "4.17.21" 883 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 884 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 885 | 886 | loose-envify@^1.1.0: 887 | version "1.4.0" 888 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" 889 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== 890 | dependencies: 891 | js-tokens "^3.0.0 || ^4.0.0" 892 | 893 | mime-db@1.50.0: 894 | version "1.50.0" 895 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" 896 | integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== 897 | 898 | mime-types@^2.1.12, mime-types@~2.1.19: 899 | version "2.1.33" 900 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" 901 | integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g== 902 | dependencies: 903 | mime-db "1.50.0" 904 | 905 | minimist@^1.2.5: 906 | version "1.2.5" 907 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" 908 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 909 | 910 | ms@2.1.2: 911 | version "2.1.2" 912 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 913 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 914 | 915 | nanoid@^3.1.28: 916 | version "3.1.29" 917 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.29.tgz#214fb2d7a33e1a5bef4757b779dfaeb6a4e5aeb4" 918 | integrity sha512-dW2pUSGZ8ZnCFIlBIA31SV8huOGCHb6OwzVCc7A69rb/a+SgPBwfmLvK5TKQ3INPbRkcI8a/Owo0XbiTNH19wg== 919 | 920 | node-releases@^1.1.77: 921 | version "1.1.77" 922 | resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e" 923 | integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ== 924 | 925 | nwsapi@^2.2.0: 926 | version "2.2.0" 927 | resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" 928 | integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== 929 | 930 | oauth-sign@~0.9.0: 931 | version "0.9.0" 932 | resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" 933 | integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== 934 | 935 | object-assign@^4.1.1: 936 | version "4.1.1" 937 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 938 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 939 | 940 | optionator@^0.8.1: 941 | version "0.8.3" 942 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" 943 | integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== 944 | dependencies: 945 | deep-is "~0.1.3" 946 | fast-levenshtein "~2.0.6" 947 | levn "~0.3.0" 948 | prelude-ls "~1.1.2" 949 | type-check "~0.3.2" 950 | word-wrap "~1.2.3" 951 | 952 | parse5@5.1.0: 953 | version "5.1.0" 954 | resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" 955 | integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== 956 | 957 | path-parse@^1.0.6: 958 | version "1.0.7" 959 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 960 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 961 | 962 | performance-now@^2.1.0: 963 | version "2.1.0" 964 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" 965 | integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= 966 | 967 | picocolors@^0.2.1: 968 | version "0.2.1" 969 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" 970 | integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== 971 | 972 | picomatch@^2.2.2: 973 | version "2.3.0" 974 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" 975 | integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== 976 | 977 | pn@^1.1.0: 978 | version "1.1.0" 979 | resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" 980 | integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== 981 | 982 | postcss@^8.3.8: 983 | version "8.3.9" 984 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.9.tgz#98754caa06c4ee9eb59cc48bd073bb6bd3437c31" 985 | integrity sha512-f/ZFyAKh9Dnqytx5X62jgjhhzttjZS7hMsohcI7HEI5tjELX/HxCy3EFhsRxyzGvrzFF+82XPvCS8T9TFleVJw== 986 | dependencies: 987 | nanoid "^3.1.28" 988 | picocolors "^0.2.1" 989 | source-map-js "^0.6.2" 990 | 991 | prelude-ls@~1.1.2: 992 | version "1.1.2" 993 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" 994 | integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= 995 | 996 | psl@^1.1.28: 997 | version "1.8.0" 998 | resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" 999 | integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== 1000 | 1001 | punycode@^2.1.0, punycode@^2.1.1: 1002 | version "2.1.1" 1003 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 1004 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 1005 | 1006 | qs@~6.5.2: 1007 | version "6.5.2" 1008 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" 1009 | integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== 1010 | 1011 | react-dom@^17.0.0: 1012 | version "17.0.2" 1013 | resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" 1014 | integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== 1015 | dependencies: 1016 | loose-envify "^1.1.0" 1017 | object-assign "^4.1.1" 1018 | scheduler "^0.20.2" 1019 | 1020 | react-refresh@^0.10.0: 1021 | version "0.10.0" 1022 | resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.10.0.tgz#2f536c9660c0b9b1d500684d9e52a65e7404f7e3" 1023 | integrity sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ== 1024 | 1025 | react@^17.0.0: 1026 | version "17.0.2" 1027 | resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" 1028 | integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== 1029 | dependencies: 1030 | loose-envify "^1.1.0" 1031 | object-assign "^4.1.1" 1032 | 1033 | request-promise-core@1.1.4: 1034 | version "1.1.4" 1035 | resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" 1036 | integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== 1037 | dependencies: 1038 | lodash "^4.17.19" 1039 | 1040 | request-promise-native@^1.0.7: 1041 | version "1.0.9" 1042 | resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" 1043 | integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== 1044 | dependencies: 1045 | request-promise-core "1.1.4" 1046 | stealthy-require "^1.1.1" 1047 | tough-cookie "^2.3.3" 1048 | 1049 | request@^2.88.0: 1050 | version "2.88.2" 1051 | resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" 1052 | integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== 1053 | dependencies: 1054 | aws-sign2 "~0.7.0" 1055 | aws4 "^1.8.0" 1056 | caseless "~0.12.0" 1057 | combined-stream "~1.0.6" 1058 | extend "~3.0.2" 1059 | forever-agent "~0.6.1" 1060 | form-data "~2.3.2" 1061 | har-validator "~5.1.3" 1062 | http-signature "~1.2.0" 1063 | is-typedarray "~1.0.0" 1064 | isstream "~0.1.2" 1065 | json-stringify-safe "~5.0.1" 1066 | mime-types "~2.1.19" 1067 | oauth-sign "~0.9.0" 1068 | performance-now "^2.1.0" 1069 | qs "~6.5.2" 1070 | safe-buffer "^5.1.2" 1071 | tough-cookie "~2.5.0" 1072 | tunnel-agent "^0.6.0" 1073 | uuid "^3.3.2" 1074 | 1075 | resolve@^1.20.0: 1076 | version "1.20.0" 1077 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" 1078 | integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== 1079 | dependencies: 1080 | is-core-module "^2.2.0" 1081 | path-parse "^1.0.6" 1082 | 1083 | rollup@^2.57.0: 1084 | version "2.58.0" 1085 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.58.0.tgz#a643983365e7bf7f5b7c62a8331b983b7c4c67fb" 1086 | integrity sha512-NOXpusKnaRpbS7ZVSzcEXqxcLDOagN6iFS8p45RkoiMqPHDLwJm758UF05KlMoCRbLBTZsPOIa887gZJ1AiXvw== 1087 | optionalDependencies: 1088 | fsevents "~2.3.2" 1089 | 1090 | safe-buffer@^5.0.1, safe-buffer@^5.1.2: 1091 | version "5.2.1" 1092 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1093 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1094 | 1095 | safe-buffer@~5.1.1: 1096 | version "5.1.2" 1097 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 1098 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 1099 | 1100 | "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: 1101 | version "2.1.2" 1102 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 1103 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 1104 | 1105 | saxes@^3.1.9: 1106 | version "3.1.11" 1107 | resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" 1108 | integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== 1109 | dependencies: 1110 | xmlchars "^2.1.1" 1111 | 1112 | scheduler@^0.20.2: 1113 | version "0.20.2" 1114 | resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" 1115 | integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== 1116 | dependencies: 1117 | loose-envify "^1.1.0" 1118 | object-assign "^4.1.1" 1119 | 1120 | semver@^6.3.0: 1121 | version "6.3.0" 1122 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" 1123 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 1124 | 1125 | source-map-js@^0.6.2: 1126 | version "0.6.2" 1127 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" 1128 | integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== 1129 | 1130 | source-map@^0.5.0: 1131 | version "0.5.7" 1132 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 1133 | integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= 1134 | 1135 | source-map@~0.6.1: 1136 | version "0.6.1" 1137 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 1138 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1139 | 1140 | sshpk@^1.7.0: 1141 | version "1.16.1" 1142 | resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" 1143 | integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== 1144 | dependencies: 1145 | asn1 "~0.2.3" 1146 | assert-plus "^1.0.0" 1147 | bcrypt-pbkdf "^1.0.0" 1148 | dashdash "^1.12.0" 1149 | ecc-jsbn "~0.1.1" 1150 | getpass "^0.1.1" 1151 | jsbn "~0.1.0" 1152 | safer-buffer "^2.0.2" 1153 | tweetnacl "~0.14.0" 1154 | 1155 | stealthy-require@^1.1.1: 1156 | version "1.1.1" 1157 | resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" 1158 | integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= 1159 | 1160 | supports-color@^5.3.0: 1161 | version "5.5.0" 1162 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1163 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1164 | dependencies: 1165 | has-flag "^3.0.0" 1166 | 1167 | symbol-tree@^3.2.2: 1168 | version "3.2.4" 1169 | resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" 1170 | integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== 1171 | 1172 | to-fast-properties@^2.0.0: 1173 | version "2.0.0" 1174 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" 1175 | integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= 1176 | 1177 | tough-cookie@^2.3.3, tough-cookie@~2.5.0: 1178 | version "2.5.0" 1179 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" 1180 | integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== 1181 | dependencies: 1182 | psl "^1.1.28" 1183 | punycode "^2.1.1" 1184 | 1185 | tough-cookie@^3.0.1: 1186 | version "3.0.1" 1187 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" 1188 | integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== 1189 | dependencies: 1190 | ip-regex "^2.1.0" 1191 | psl "^1.1.28" 1192 | punycode "^2.1.1" 1193 | 1194 | tr46@^1.0.1: 1195 | version "1.0.1" 1196 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" 1197 | integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= 1198 | dependencies: 1199 | punycode "^2.1.0" 1200 | 1201 | tunnel-agent@^0.6.0: 1202 | version "0.6.0" 1203 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 1204 | integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= 1205 | dependencies: 1206 | safe-buffer "^5.0.1" 1207 | 1208 | tweetnacl@^0.14.3, tweetnacl@~0.14.0: 1209 | version "0.14.5" 1210 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" 1211 | integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= 1212 | 1213 | type-check@~0.3.2: 1214 | version "0.3.2" 1215 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" 1216 | integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= 1217 | dependencies: 1218 | prelude-ls "~1.1.2" 1219 | 1220 | uri-js@^4.2.2: 1221 | version "4.4.1" 1222 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 1223 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1224 | dependencies: 1225 | punycode "^2.1.0" 1226 | 1227 | uuid@^3.3.2: 1228 | version "3.4.0" 1229 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 1230 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 1231 | 1232 | verror@1.10.0: 1233 | version "1.10.0" 1234 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" 1235 | integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= 1236 | dependencies: 1237 | assert-plus "^1.0.0" 1238 | core-util-is "1.0.2" 1239 | extsprintf "^1.2.0" 1240 | 1241 | vite@^2.6.4: 1242 | version "2.6.4" 1243 | resolved "https://registry.yarnpkg.com/vite/-/vite-2.6.4.tgz#b932735f1ecdf69256ce6eaae0d41a7b15d77599" 1244 | integrity sha512-zNGZgjKGprdLKJ1g1taAvNt51JbGAdrAUU9hpLzgtlks+cXBxTZUsEAGEtLbF3UvlYOVAPXS8r9E9gxYAv6z+A== 1245 | dependencies: 1246 | esbuild "^0.13.2" 1247 | postcss "^8.3.8" 1248 | resolve "^1.20.0" 1249 | rollup "^2.57.0" 1250 | optionalDependencies: 1251 | fsevents "~2.3.2" 1252 | 1253 | w3c-hr-time@^1.0.1: 1254 | version "1.0.2" 1255 | resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" 1256 | integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== 1257 | dependencies: 1258 | browser-process-hrtime "^1.0.0" 1259 | 1260 | w3c-xmlserializer@^1.1.2: 1261 | version "1.1.2" 1262 | resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" 1263 | integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== 1264 | dependencies: 1265 | domexception "^1.0.1" 1266 | webidl-conversions "^4.0.2" 1267 | xml-name-validator "^3.0.0" 1268 | 1269 | webidl-conversions@^4.0.2: 1270 | version "4.0.2" 1271 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" 1272 | integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== 1273 | 1274 | whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: 1275 | version "1.0.5" 1276 | resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" 1277 | integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== 1278 | dependencies: 1279 | iconv-lite "0.4.24" 1280 | 1281 | whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: 1282 | version "2.3.0" 1283 | resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" 1284 | integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== 1285 | 1286 | whatwg-url@^7.0.0: 1287 | version "7.1.0" 1288 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" 1289 | integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== 1290 | dependencies: 1291 | lodash.sortby "^4.7.0" 1292 | tr46 "^1.0.1" 1293 | webidl-conversions "^4.0.2" 1294 | 1295 | word-wrap@~1.2.3: 1296 | version "1.2.3" 1297 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" 1298 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== 1299 | 1300 | ws@^7.0.0: 1301 | version "7.5.5" 1302 | resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" 1303 | integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== 1304 | 1305 | xml-name-validator@^3.0.0: 1306 | version "3.0.0" 1307 | resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" 1308 | integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== 1309 | 1310 | xmlchars@^2.1.1: 1311 | version "2.2.0" 1312 | resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" 1313 | integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== 1314 | --------------------------------------------------------------------------------