diff --git a/frontend/stepper/js/BlocklyEditor.tsx b/frontend/stepper/js/BlocklyEditor.tsx index 3e5f08b7..466a7f2a 100644 --- a/frontend/stepper/js/BlocklyEditor.tsx +++ b/frontend/stepper/js/BlocklyEditor.tsx @@ -11,6 +11,7 @@ import {bufferResetToDefaultSourceCode} from '../../buffers/buffer_actions'; import {ComputedSourceHighlight, SourceHighlightBlock} from '../index'; import {callPlatformLog} from '../../submission/submission_actions'; import {selectGroupByCategory} from './index'; +import * as Blockly from 'blockly/core'; export interface BlocklyEditorProps { name?: string, @@ -58,7 +59,7 @@ export const BlocklyEditor = (props: BlocklyEditorProps) => { } log.getLogger('editor').debug('imported content', context.blocklyHelper.programs[0].blockly); - context.blocklyHelper.reloading = true; + // context.blocklyHelper.reloading = true; // Check that all blocks exist and program is valid. Otherwise, reload default answer and cancel try { @@ -66,7 +67,8 @@ export const BlocklyEditor = (props: BlocklyEditorProps) => { context.blocklyHelper.loadPrograms(); context.blocklyHelper.programs[0].blocklyJS = context.blocklyHelper.getCode("javascript"); if (0 === context.blocklyHelper.programs[0].blocklyJS.trim().length) { - throw new Error("The reloaded answer is empty"); + // TODO Blockly: re-enable this warning + // throw new Error("The reloaded answer is empty"); } } catch (e) { console.error(e); @@ -144,14 +146,13 @@ export const BlocklyEditor = (props: BlocklyEditorProps) => { const onBlocklyEvent = (event) => { log.getLogger('editor').debug('blockly event', event); - const eventType = event ? event.constructor : null; - - let isBlockEvent = event ? ( - eventType === window.Blockly.Events.Create || - eventType === window.Blockly.Events.Delete || - eventType === window.Blockly.Events.Move || - eventType === window.Blockly.Events.Change) : true; + let isBlockEvent = [ + Blockly.Events.BLOCK_DRAG, + Blockly.Events.BLOCK_MOVE, + Blockly.Events.BLOCK_CREATE, + Blockly.Events.BLOCK_CHANGE, + ].includes(event.type); if ('selected' === event.element) { if (event.newValue !== selectedBlockId.current) { log.getLogger('editor').debug('is selected'); @@ -163,7 +164,7 @@ export const BlocklyEditor = (props: BlocklyEditorProps) => { if (isBlockEvent) { const blocklyHelper = context.blocklyHelper; - log.getLogger('editor').debug('on editor change'); + log.getLogger('editor').debug('on editor change', loaded.current, blocklyHelper.reloading, blocklyHelper.languages); if (blocklyHelper.languages && blocklyHelper.languages.length && loaded.current && !blocklyHelper.reloading) { blocklyHelper.savePrograms(); const answer = {...blocklyHelper.programs[0]}; @@ -173,8 +174,8 @@ export const BlocklyEditor = (props: BlocklyEditorProps) => { log.getLogger('editor').debug('new value', answer); props.onEditPlain(document); - if (eventType !== window.Blockly.Events.Create && (eventType === window.Blockly.Events.Change || event.oldCoordinate)) { - const details = `block_update;${eventType.prototype.type};${documentToString(document)}`; + if (event.type !== Blockly.Events.BLOCK_CREATE && (event.type === Blockly.Events.BLOCK_CHANGE || event.oldCoordinate)) { + const details = `block_update;${event.type.prototype.type};${documentToString(document)}`; dispatch(callPlatformLog(['activity', details])); } @@ -312,6 +313,10 @@ export const BlocklyEditor = (props: BlocklyEditorProps) => { return; } + // TODO Blockly: Change Blockly selected block + + return; + window.Blockly.selected = null; clearHighlights('blocklySelected'); diff --git a/frontend/stepper/js/blockly.scss b/frontend/stepper/js/blockly.scss index ccea1f4e..8c58af34 100644 --- a/frontend/stepper/js/blockly.scss +++ b/frontend/stepper/js/blockly.scss @@ -11,6 +11,10 @@ height: 100%; } +.blocklyToolbox { + z-index: 15; +} + .blocklyDropDownDiv { position: fixed; left: 0; diff --git a/frontend/stepper/js/blockly_helper.ts b/frontend/stepper/js/blockly_helper.ts index 67069d08..8abe774d 100644 --- a/frontend/stepper/js/blockly_helper.ts +++ b/frontend/stepper/js/blockly_helper.ts @@ -5,6 +5,7 @@ import {getStandardBlocklyBlocks} from './standard_blockly_blocks'; import {getStandardScratchBlocks} from './standard_scratch_blocks'; import {Block, BlockType} from '../../task/blocks/block_types'; import {QuickAlgoLibrary} from '../../task/libs/quickalgo_library'; +import * as Blockly from 'blockly/core'; let blocklySets = { allDefault: { @@ -161,7 +162,8 @@ export class BlocklyHelper { load(locale, display, nbTestCases, options) { this.unloaded = false; - window.FioiBlockly.loadLanguage(locale); + // TODO Blockly: re-enable FioiBlockly + // window.FioiBlockly.loadLanguage(locale); if (this.scratchMode) { this.fixScratch(); @@ -175,15 +177,17 @@ export class BlocklyHelper { this.strings.startingBlockName = options.startingBlockName; } - if (options.maxListSize) { - window.FioiBlockly.maxListSize = options.maxListSize; - } + // TODO Blockly: re-enable FioiBlockly + // if (options.maxListSize) { + // window.FioiBlockly.maxListSize = options.maxListSize; + // } this.placeholderBlocks = options.placeholderBlocks; this.options = options; addExtraBlocks(this.strings, this.getDefaultColours(), !this.mainContext.infos || !this.mainContext.infos.showIfMutator, this.scratchMode); - this.createSimpleGeneratorsAndBlocks(); + // TODO Blockly: write code generators + // this.createSimpleGeneratorsAndBlocks(); this.display = display; @@ -229,7 +233,8 @@ export class BlocklyHelper { } // Clean events if the previous unload wasn't done properly - window.Blockly.removeEvents(); + // TODO Blockly: events + // window.Blockly.removeEvents(); // Inject Blockly this.workspace = window.Blockly.inject(this.divId, wsConfig); @@ -263,12 +268,13 @@ export class BlocklyHelper { this.programs[iCode] = {blockly: null, blocklyJS: "", blocklyPython: "", javascript: ""}; this.languages[iCode] = "blockly"; this.setCodeId(iCode); - if (this.startingBlock || options.startingExample) { - let xml = this.getDefaultContent(); - window.Blockly.Events.recordUndo = false; - window.Blockly.Xml.domToWorkspace(window.Blockly.Xml.textToDom(xml), this.workspace); - window.Blockly.Events.recordUndo = true; - } + // TODO Blockly: 2-way sync + // if (this.startingBlock || options.startingExample) { + // let xml = this.getDefaultContent(); + // window.Blockly.Events.recordUndo = false; + // window.Blockly.Xml.domToWorkspace(window.Blockly.Xml.textToDom(xml), this.workspace); + // window.Blockly.Events.recordUndo = true; + // } this.savePrograms(); } @@ -368,8 +374,8 @@ export class BlocklyHelper { } } - let xml = window.Blockly.Xml.textToDom(this.getEmptyContent()) - window.Blockly.Xml.domToWorkspace(xml, this.workspace); + let xml = Blockly.utils.xml.textToDom(this.getEmptyContent()) + Blockly.Xml.domToWorkspace(xml, this.workspace); } getOrigin() { @@ -400,7 +406,9 @@ export class BlocklyHelper { this.programs[this.codeId].javascript = window.jQuery("#program").val(); if (this.workspace != null) { let xml = window.Blockly.Xml.workspaceToDom(this.workspace); - this.cleanBlockAttributes(xml); + + // TODO Blockly: 2-way sync + // this.cleanBlockAttributes(xml); // The additional variable contain all additional things that we can save, for example quickpi sensors, // subject title when edition is enabled... @@ -421,9 +429,9 @@ export class BlocklyHelper { loadPrograms() { if (this.workspace != null) { - let xml = window.Blockly.Xml.textToDom(this.programs[this.codeId].blockly); + let xml = Blockly.utils.xml.textToDom(this.programs[this.codeId].blockly); this.workspace.clear(); - this.cleanBlockAttributes(xml, this.getOrigin()); + // this.cleanBlockAttributes(xml, this.getOrigin()); window.Blockly.Xml.domToWorkspace(xml, this.workspace); let additionalXML = xml.getElementsByTagName("additional"); @@ -649,6 +657,9 @@ export class BlocklyHelper { } getCode(language, codeWorkspace = undefined, noReportValue = false, noConstraintCheck = false) { + // TODO Blockly: write code generators + return ''; + if (codeWorkspace == undefined) { codeWorkspace = this.workspace; } @@ -1079,8 +1090,9 @@ export class BlocklyHelper { this.completeBlockHandler(blockInfo, generatorName, this.mainContext); this.completeBlockJson(blockInfo, generatorName, category, this.mainContext); /* category.category is category name */ this.completeBlockXml(blockInfo); - this.completeCodeGenerators(blockInfo, generatorName); - this.applyCodeGenerators(blockInfo); + // TODO Blockly: write code geneators + // this.completeCodeGenerators(blockInfo, generatorName); + // this.applyCodeGenerators(blockInfo); this.createBlock(blockInfo); this.applyBlockOptions(blockInfo); } @@ -1088,8 +1100,9 @@ export class BlocklyHelper { getDefaultColours() { - window.Blockly.HSV_SATURATION = 0.65; - window.Blockly.HSV_VALUE = 0.80; + //TODO Blockly: Blockly.utils.colour.setHsvSaturation + // window.Blockly.HSV_SATURATION = 0.65; + // window.Blockly.HSV_VALUE = 0.80; let colours = { categories: { actuator: 212, @@ -1112,18 +1125,18 @@ export class BlocklyHelper { blocks: {} }; - if (typeof this.mainContext.provideBlocklyColours == "function") { - let providedColours = this.mainContext.provideBlocklyColours(); - - for (let group in providedColours) { - if (!(group in colours)) { - colours[group] = {}; - } - for (let name in providedColours[group]) { - colours[group][name] = providedColours[group][name]; - } - } - } + // if (typeof this.mainContext.provideBlocklyColours == "function") { + // let providedColours = this.mainContext.provideBlocklyColours(); + // + // for (let group in providedColours) { + // if (!(group in colours)) { + // colours[group] = {}; + // } + // for (let name in providedColours[group]) { + // colours[group][name] = providedColours[group][name]; + // } + // } + // } return colours; } @@ -1191,18 +1204,21 @@ export class BlocklyHelper { if (!this.scratchMode) { let defCat = ["logic", "loops", "math", "texts", "lists", "colour"]; for (let iCat in defCat) { - window.Blockly.Blocks[defCat[iCat]].HUE = colours.categories[defCat[iCat]]; + // TODO Blockly: colors + // window.Blockly.Blocks[defCat[iCat]].HUE = colours.categories[defCat[iCat]]; } } } getToolboxXml() { + // TODO Blockly: define toolbox + let categoriesInfos = {}; let colours = this.getDefaultColours(); // Reset the flyoutOptions for the variables and the procedures - window.Blockly.Variables.resetFlyoutOptions(); - window.Blockly.Procedures.resetFlyoutOptions(); + // window.Blockly.Variables.resetFlyoutOptions(); + // window.Blockly.Procedures.resetFlyoutOptions(); // Initialize allBlocksAllowed this.allBlocksAllowed = []; @@ -1236,28 +1252,28 @@ export class BlocklyHelper { if (!this.scratchMode) { let defCat = ["logic", "loops", "math", "texts", "lists", "colour"]; for (let iCat in defCat) { - window.Blockly.Blocks[defCat[iCat]].HUE = colours.categories[defCat[iCat]]; + // window.Blockly.Blocks[defCat[iCat]].HUE = colours.categories[defCat[iCat]]; } } } - // if (this.includeBlocks.generatedBlocks && 'singleBlocks' in this.includeBlocks.generatedBlocks) { - // for (let blockType in this.includeBlocks.generatedBlocks.singleBlocks) { - // this.addBlocksAndCategories( - // this.includeBlocks.generatedBlocks.singleBlocks[blockType], - // this.mainContext.customBlocks[blockType], - // categoriesInfos - // ); - // } - // } - // for (let blockType in this.includeBlocks.generatedBlocks) { - // if (blockType == 'wholeCategories' || blockType == 'singleBlocks') continue; - // this.addBlocksAndCategories( - // this.includeBlocks.generatedBlocks[blockType], - // this.mainContext.customBlocks[blockType], - // categoriesInfos - // ); - // } + if (this.includeBlocks.generatedBlocks && 'singleBlocks' in this.includeBlocks.generatedBlocks) { + for (let blockType in this.includeBlocks.generatedBlocks.singleBlocks) { + this.addBlocksAndCategories( + this.includeBlocks.generatedBlocks.singleBlocks[blockType], + this.mainContext.customBlocks[blockType], + categoriesInfos + ); + } + } + for (let blockType in this.includeBlocks.generatedBlocks) { + if (blockType == 'wholeCategories' || blockType == 'singleBlocks') continue; + this.addBlocksAndCategories( + this.includeBlocks.generatedBlocks[blockType], + this.mainContext.customBlocks[blockType], + categoriesInfos + ); + } for (let genName in this.simpleGenerators) { for (let iGen = 0; iGen < this.simpleGenerators[genName].length; iGen++) { @@ -1337,13 +1353,13 @@ export class BlocklyHelper { blocksXml: [] }; } - if (categoryName == 'variables') { - window.Blockly.Variables.flyoutOptions.any = true; - continue; - } else if (categoryName == 'functions') { - window.Blockly.Procedures.flyoutOptions.includedBlocks = {noret: true, ret: true, ifret: true, noifret: true}; - continue; - } + // if (categoryName == 'variables') { + // window.Blockly.Variables.flyoutOptions.any = true; + // continue; + // } else if (categoryName == 'functions') { + // window.Blockly.Procedures.flyoutOptions.includedBlocks = {noret: true, ret: true, ifret: true, noifret: true}; + // continue; + // } let blocks = stdBlocks[categoryName]; if (blocks) { if (!(blocks instanceof Array)) { // just for now, maintain backwards compatibility @@ -1361,114 +1377,114 @@ export class BlocklyHelper { } } - let proceduresOptions = this.includeBlocks.procedures; - if (typeof proceduresOptions !== 'undefined') { - if (proceduresOptions.noret) { - window.Blockly.Procedures.flyoutOptions.includedBlocks['noret'] = true; - } - if (proceduresOptions.ret) { - window.Blockly.Procedures.flyoutOptions.includedBlocks['ret'] = true; - } - if (proceduresOptions.ifret) { - window.Blockly.Procedures.flyoutOptions.includedBlocks['ifret'] = true; - } - if (proceduresOptions.noifret) { - window.Blockly.Procedures.flyoutOptions.includedBlocks['noifret'] = true; - } - window.Blockly.Procedures.flyoutOptions.disableArgs = !!proceduresOptions.disableArgs; - } - + // let proceduresOptions = this.includeBlocks.procedures; + // if (typeof proceduresOptions !== 'undefined') { + // if (proceduresOptions.noret) { + // window.Blockly.Procedures.flyoutOptions.includedBlocks['noret'] = true; + // } + // if (proceduresOptions.ret) { + // window.Blockly.Procedures.flyoutOptions.includedBlocks['ret'] = true; + // } + // if (proceduresOptions.ifret) { + // window.Blockly.Procedures.flyoutOptions.includedBlocks['ifret'] = true; + // } + // if (proceduresOptions.noifret) { + // window.Blockly.Procedures.flyoutOptions.includedBlocks['noifret'] = true; + // } + // window.Blockly.Procedures.flyoutOptions.disableArgs = !!proceduresOptions.disableArgs; + // } + // let singleBlocks = stdInclude.singleBlocks; - for (let iBlock = 0; iBlock < singleBlocks.length; iBlock++) { - let blockName = singleBlocks[iBlock]; - if (blockName == 'procedures_defnoreturn') { - window.Blockly.Procedures.flyoutOptions.includedBlocks['noret'] = true; - } else if (blockName == 'procedures_defreturn') { - window.Blockly.Procedures.flyoutOptions.includedBlocks['ret'] = true; - } else if (blockName == 'procedures_ifreturn') { - window.Blockly.Procedures.flyoutOptions.includedBlocks['ifret'] = true; - } else if (blockName == 'procedures_return') { - window.Blockly.Procedures.flyoutOptions.includedBlocks['noifret'] = true; - } else { - continue; - } - // If we're here, a block has been found - this.addBlocksAllowed([blockName, 'procedures_callnoreturn', 'procedures_callreturn']); - singleBlocks.splice(iBlock, 1); - iBlock--; - } - if (window.Blockly.Procedures.flyoutOptions.includedBlocks['noret'] - || window.Blockly.Procedures.flyoutOptions.includedBlocks['ret'] - || window.Blockly.Procedures.flyoutOptions.includedBlocks['ifret'] - || window.Blockly.Procedures.flyoutOptions.includedBlocks['noifret']) { - if (window.Blockly.Procedures.flyoutOptions.includedBlocks['noret']) { - this.addBlocksAllowed(['procedures_defnoreturn', 'procedures_callnoreturn']); - } - if (window.Blockly.Procedures.flyoutOptions.includedBlocks['ret']) { - this.addBlocksAllowed(['procedures_defreturn', 'procedures_callreturn']); - } - if (window.Blockly.Procedures.flyoutOptions.includedBlocks['ifret']) { - this.addBlocksAllowed(['procedures_ifreturn', 'procedures_return']); - } - if (window.Blockly.Procedures.flyoutOptions.includedBlocks['noifret']) { - this.addBlocksAllowed(['procedures_return']); - } - categoriesInfos['functions'] = { - blocksXml: [] - }; - if (this.scratchMode && !window.arrayContains(singleBlocks, 'math_number')) { - singleBlocks.push('math_number'); // TODO :: temporary - } - if (!this.groupByCategory) { - console.error('Task configuration error: groupByCategory must be activated for functions.'); - } - } + // for (let iBlock = 0; iBlock < singleBlocks.length; iBlock++) { + // let blockName = singleBlocks[iBlock]; + // if (blockName == 'procedures_defnoreturn') { + // window.Blockly.Procedures.flyoutOptions.includedBlocks['noret'] = true; + // } else if (blockName == 'procedures_defreturn') { + // window.Blockly.Procedures.flyoutOptions.includedBlocks['ret'] = true; + // } else if (blockName == 'procedures_ifreturn') { + // window.Blockly.Procedures.flyoutOptions.includedBlocks['ifret'] = true; + // } else if (blockName == 'procedures_return') { + // window.Blockly.Procedures.flyoutOptions.includedBlocks['noifret'] = true; + // } else { + // continue; + // } + // // If we're here, a block has been found + // this.addBlocksAllowed([blockName, 'procedures_callnoreturn', 'procedures_callreturn']); + // singleBlocks.splice(iBlock, 1); + // iBlock--; + // } + // if (window.Blockly.Procedures.flyoutOptions.includedBlocks['noret'] + // || window.Blockly.Procedures.flyoutOptions.includedBlocks['ret'] + // || window.Blockly.Procedures.flyoutOptions.includedBlocks['ifret'] + // || window.Blockly.Procedures.flyoutOptions.includedBlocks['noifret']) { + // if (window.Blockly.Procedures.flyoutOptions.includedBlocks['noret']) { + // this.addBlocksAllowed(['procedures_defnoreturn', 'procedures_callnoreturn']); + // } + // if (window.Blockly.Procedures.flyoutOptions.includedBlocks['ret']) { + // this.addBlocksAllowed(['procedures_defreturn', 'procedures_callreturn']); + // } + // if (window.Blockly.Procedures.flyoutOptions.includedBlocks['ifret']) { + // this.addBlocksAllowed(['procedures_ifreturn', 'procedures_return']); + // } + // if (window.Blockly.Procedures.flyoutOptions.includedBlocks['noifret']) { + // this.addBlocksAllowed(['procedures_return']); + // } + // categoriesInfos['functions'] = { + // blocksXml: [] + // }; + // if (this.scratchMode && !window.arrayContains(singleBlocks, 'math_number')) { + // singleBlocks.push('math_number'); // TODO :: temporary + // } + // if (!this.groupByCategory) { + // console.error('Task configuration error: groupByCategory must be activated for functions.'); + // } + // } this.addBlocksAndCategories(singleBlocks, stdBlocks, categoriesInfos); // Handle variable blocks, which are normally automatically added with // the VARIABLES category but can be customized here - window.Blockly.Variables.flyoutOptions.anyButton = !!this.groupByCategory; + // window.Blockly.Variables.flyoutOptions.anyButton = !!this.groupByCategory; if (typeof this.includeBlocks.variables !== 'undefined') { - window.Blockly.Variables.flyoutOptions.fixed = (this.includeBlocks.variables.length > 0) ? this.includeBlocks.variables : []; - if (typeof this.includeBlocks.variablesOnlyBlocks !== 'undefined') { - window.Blockly.Variables.flyoutOptions.includedBlocks = {get: false, set: false, incr: false}; - for (let iBlock = 0; iBlock < this.includeBlocks.variablesOnlyBlocks.length; iBlock++) { - window.Blockly.Variables.flyoutOptions.includedBlocks[this.includeBlocks.variablesOnlyBlocks[iBlock]] = true; - } - } - - let varAnyIdx = window.Blockly.Variables.flyoutOptions.fixed.indexOf('*'); - if (varAnyIdx > -1) { - window.Blockly.Variables.flyoutOptions.fixed.splice(varAnyIdx, 1); - window.Blockly.Variables.flyoutOptions.any = true; - } - - let blocksXml = window.Blockly.Variables.flyoutCategory(); - let xmlSer = new XMLSerializer(); - for (let i = 0; i < blocksXml.length; i++) { - blocksXml[i] = xmlSer.serializeToString(blocksXml[i]); - } - - categoriesInfos["variables"] = { - blocksXml: blocksXml, - colour: 330 - } - } - - if (window.Blockly.Variables.flyoutOptions.includedBlocks['get']) { - this.addBlocksAllowed(['variables_get']); - } - if (window.Blockly.Variables.flyoutOptions.includedBlocks['set']) { - this.addBlocksAllowed(['variables_set']); - } - if (window.Blockly.Variables.flyoutOptions.includedBlocks['incr']) { - this.addBlocksAllowed(['math_change']); - } + // window.Blockly.Variables.flyoutOptions.fixed = (this.includeBlocks.variables.length > 0) ? this.includeBlocks.variables : []; + // if (typeof this.includeBlocks.variablesOnlyBlocks !== 'undefined') { + // window.Blockly.Variables.flyoutOptions.includedBlocks = {get: false, set: false, incr: false}; + // for (let iBlock = 0; iBlock < this.includeBlocks.variablesOnlyBlocks.length; iBlock++) { + // window.Blockly.Variables.flyoutOptions.includedBlocks[this.includeBlocks.variablesOnlyBlocks[iBlock]] = true; + // } + // } + + // let varAnyIdx = window.Blockly.Variables.flyoutOptions.fixed.indexOf('*'); + // if (varAnyIdx > -1) { + // window.Blockly.Variables.flyoutOptions.fixed.splice(varAnyIdx, 1); + // window.Blockly.Variables.flyoutOptions.any = true; + // } + + // let blocksXml = window.Blockly.Variables.flyoutCategory(); + // let xmlSer = new XMLSerializer(); + // for (let i = 0; i < blocksXml.length; i++) { + // blocksXml[i] = xmlSer.serializeToString(blocksXml[i]); + // } + // + // categoriesInfos["variables"] = { + // blocksXml: blocksXml, + // colour: 330 + // } + } + + // if (window.Blockly.Variables.flyoutOptions.includedBlocks['get']) { + // this.addBlocksAllowed(['variables_get']); + // } + // if (window.Blockly.Variables.flyoutOptions.includedBlocks['set']) { + // this.addBlocksAllowed(['variables_set']); + // } + // if (window.Blockly.Variables.flyoutOptions.includedBlocks['incr']) { + // this.addBlocksAllowed(['math_change']); + // } // Disable arguments in procedures if variables are not allowed - if (!window.Blockly.Variables.flyoutOptions.any && proceduresOptions && typeof proceduresOptions.disableArgs == 'undefined') { - window.Blockly.Procedures.flyoutOptions.disableArgs = true; - } + // if (!window.Blockly.Variables.flyoutOptions.any && proceduresOptions && typeof proceduresOptions.disableArgs == 'undefined') { + // window.Blockly.Procedures.flyoutOptions.disableArgs = true; + // } let orderedCategories = []; if (this.includeBlocks.blocksOrder) { @@ -1661,7 +1677,7 @@ export class BlocklyHelper { getStartingExampleIds(xml) { this.startingExampleIds = []; - let blockList = window.Blockly.Xml.textToDom(xml).getElementsByTagName('block'); + let blockList = Blockly.utils.xml.textToDom(xml).getElementsByTagName('block'); for (let i = 0; i < blockList.length; i++) { let block = blockList[i]; let blockId = block.getAttribute('id'); diff --git a/frontend/stepper/js/blockly_runner.ts b/frontend/stepper/js/blockly_runner.ts index 12dbe293..dc189c58 100644 --- a/frontend/stepper/js/blockly_runner.ts +++ b/frontend/stepper/js/blockly_runner.ts @@ -71,7 +71,8 @@ export default class BlocklyRunner extends AbstractRunner { this.context = context; this.scratchMode = context.blocklyHelper ? context.blocklyHelper.scratchMode : false; this.delayFactory = new window.DelayFactory(); - adaptJsBlocks(window.Blockly); + // TODO Blockly: write code generators + // adaptJsBlocks(window.Blockly); } public static hasBlocks(): boolean { diff --git a/frontend/stepper/js/extra_blocks.ts b/frontend/stepper/js/extra_blocks.ts index f7746386..02936f96 100644 --- a/frontend/stepper/js/extra_blocks.ts +++ b/frontend/stepper/js/extra_blocks.ts @@ -1,4 +1,21 @@ export function addExtraBlocks(strings, defaultColors, showIfMutator, scratchMode ) { + window.Blockly.Blocks['robot_start'] = { + init: function () { + this.appendDummyInput() + .appendField(strings.startingBlockName); + this.setNextStatement(true); + this.setColour(210); + this.setTooltip(''); + this.deletable_ = false; + this.editable_ = false; + this.movable_ = false; + // this.setHelpUrl('http://www.example.com/'); + } + }; + + // TODO Blockly: write code generators + return; + window.Blockly.Blocks['controls_untilWhile'] = window.Blockly.Blocks['controls_whileUntil']; window.Blockly.JavaScript['controls_untilWhile'] = window.Blockly.JavaScript['controls_whileUntil']; window.Blockly.Python['controls_untilWhile'] = window.Blockly.Python['controls_whileUntil']; diff --git a/frontend/stepper/js/index.ts b/frontend/stepper/js/index.ts index a5dbf7d0..e689f302 100644 --- a/frontend/stepper/js/index.ts +++ b/frontend/stepper/js/index.ts @@ -16,6 +16,13 @@ import {quickAlgoLibraries} from '../../task/libs/quick_algo_libraries_model'; import {LayoutType} from '../../task/layout/layout_types'; import {Document, BlockDocument} from '../../buffers/buffer_types'; import {BlocklyHelper} from './blockly_helper'; +import * as Blockly from 'blockly/core'; +import 'blockly/blocks'; +import 'blockly/javascript'; + +// TODO Blockly: don't expose Blockly to all window +window.Blockly = Blockly; +console.log({Blockly}) let originalFireNow; let originalSetBackgroundPathVertical_; @@ -56,11 +63,13 @@ export function* loadBlocklyHelperSaga(context: QuickAlgoLibrary) { const languageTranslations: any = availableLanguages[path]; const isMobile = yield* appSelect(state => LayoutType.MobileVertical === state.layout.type || LayoutType.MobileHorizontal === state.layout.type); - window.goog.provide('Blockly.Msg.' + language); - window.Blockly.Msg = {...window.Blockly.Msg, ...languageTranslations.Msg}; + for (const key in languageTranslations.Msg) { + Blockly.Msg[key] = languageTranslations.Msg[key]; + } - window.Blockly.JavaScript.STATEMENT_PREFIX = 'highlightBlock(%1);\n'; - window.Blockly.JavaScript.addReservedWords('highlightBlock'); + // TODO Blockly: write code generators + // window.Blockly.JavaScript.STATEMENT_PREFIX = 'highlightBlock(%1);\n'; + // window.Blockly.JavaScript.addReservedWords('highlightBlock'); if (!window.quickAlgoInterface) { window.quickAlgoInterface = { @@ -89,12 +98,13 @@ export function* loadBlocklyHelperSaga(context: QuickAlgoLibrary) { // We overload this function to catch the Blockly firing event instant so that we know when the program // is successfully reloaded and that the events won't trigger an editor content update which would trigger // a stepper.exit - if ('main' === state.environment) { - window.Blockly.Events.fireNow_ = () => { - originalFireNow(); - context.blocklyHelper.reloading = false; - }; - } + // TODO Blockly: check if it's still necessary + // if ('main' === state.environment) { + // window.Blockly.Events.fireNow_ = () => { + // originalFireNow(); + // context.blocklyHelper.reloading = false; + // }; + // } if (groupByCategory && 'tralalere' === options.app) { overrideBlocklyFlyoutForCategories(isMobile); @@ -317,6 +327,9 @@ export function blocklyCount(blocks: any[], context: QuickAlgoLibrary): number { } const getBlocksFromXml = function (state: AppStore, context: QuickAlgoLibrary, xmlText: string) { + // TODO Blockly: 2-way sync + return []; + const xml = window.Blockly.Xml.textToDom(xmlText); const blocklyHelper = createBlocklyHelper(context, state); @@ -397,13 +410,14 @@ export async function getBlocklyCodeFromXml(document: BlockDocument, lang: strin blocklyHelper.programs[0].blockly = blocklyXmlCode; log.getLogger('blockly_runner').debug('xml code', blocklyXmlCode); - blocklyHelper.reloading = true; + // TODO Blockly: check if it's still necessary + // blocklyHelper.reloading = true; blocklyHelper.loadPrograms(); // Wait that program is loaded (Blockly fires some event including an onChange event - if ('main' === state.environment) { - await delay(0); - } - blocklyHelper.reloading = false; + // if ('main' === state.environment) { + // await delay(0); + // } + // blocklyHelper.reloading = false; return blocklyHelper.getCode(lang, null, true, true); } diff --git a/frontend/task/libs/import_modules.ts b/frontend/task/libs/import_modules.ts index 60fb217f..c784b038 100644 --- a/frontend/task/libs/import_modules.ts +++ b/frontend/task/libs/import_modules.ts @@ -337,8 +337,8 @@ export async function importPlatformModules(platform, modulesPath) { jsLibLoaded = platform; const modulesToImport = { - blockly: ['fonts-loader-1.0', 'acorn', 'acorn-walk', 'interpreter', 'blockly', 'blockly_blocks', 'blockly_javascript', 'blockly_python', 'blockly_fioi', 'quickAlgo_utils', 'quickAlgo_blockly_blocks', 'quickAlgo_blockly_interface', 'quickAlgo_i18n'], - scratch: ['fonts-loader-1.0', 'acorn', 'acorn-walk', 'interpreter', 'scratch', 'scratch_blocks_common', 'scratch_blocks', 'blockly_javascript', 'blockly_python', 'blockly_fioi', 'scratch_fixes', 'scratch_procedures', 'quickAlgo_utils', 'quickAlgo_blockly_blocks', 'quickAlgo_blockly_interface', 'quickAlgo_i18n'], + blockly: ['fonts-loader-1.0', 'acorn', 'acorn-walk', 'interpreter', 'quickAlgo_utils', 'quickAlgo_i18n'], + scratch: ['fonts-loader-1.0', 'acorn', 'acorn-walk', 'interpreter', 'scratch', 'scratch_blocks_common', 'scratch_blocks', 'blockly_javascript', 'blockly_python', 'blockly_fioi', 'scratch_fixes', 'scratch_procedures', 'quickAlgo_utils', 'quickAlgo_i18n'], } await importModules(modulesToImport[platform], modulesPath); diff --git a/package.json b/package.json index 85d4dd22..e0da1036 100644 --- a/package.json +++ b/package.json @@ -140,6 +140,7 @@ "@typescript-eslint/parser": "^8.55.0", "@vitejs/plugin-react": "^6.0.1", "babel-loader": "10.0.0", + "blockly": "^12.5.1", "circular-dependency-plugin": "^5.2.2", "copy-webpack-plugin": "^13.0.1", "crypto-browserify": "^3.12.0", diff --git a/yarn.lock b/yarn.lock index 0b459b62..61e2d8f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,17 @@ # yarn lockfile v1 +"@asamuzakjp/css-color@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@asamuzakjp/css-color/-/css-color-3.2.0.tgz#cc42f5b85c593f79f1fa4f25d2b9b321e61d1794" + integrity sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw== + dependencies: + "@csstools/css-calc" "^2.1.3" + "@csstools/css-color-parser" "^3.0.9" + "@csstools/css-parser-algorithms" "^3.0.4" + "@csstools/css-tokenizer" "^3.0.3" + lru-cache "^10.4.3" + "@aws-crypto/crc32@5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-5.2.0.tgz#cfcc22570949c98c6689cfcbd2d693d36cdae2e1" @@ -1611,6 +1622,34 @@ classnames "^2.3.1" tslib "~2.6.2" +"@csstools/color-helpers@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.1.0.tgz#106c54c808cabfd1ab4c602d8505ee584c2996ef" + integrity sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA== + +"@csstools/css-calc@^2.1.3", "@csstools/css-calc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-2.1.4.tgz#8473f63e2fcd6e459838dd412401d5948f224c65" + integrity sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ== + +"@csstools/css-color-parser@^3.0.9": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz#4e386af3a99dd36c46fef013cfe4c1c341eed6f0" + integrity sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA== + dependencies: + "@csstools/color-helpers" "^5.1.0" + "@csstools/css-calc" "^2.1.4" + +"@csstools/css-parser-algorithms@^3.0.4": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz#5755370a9a29abaec5515b43c8b3f2cf9c2e3076" + integrity sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ== + +"@csstools/css-tokenizer@^3.0.3": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz#333fedabc3fd1a8e5d0100013731cf19e6a8c5d3" + integrity sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw== + "@discoveryjs/json-ext@0.5.7": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" @@ -3560,6 +3599,11 @@ adt@^0.7.2: resolved "https://registry.yarnpkg.com/adt/-/adt-0.7.2.tgz#824bb725fe3632c8c35ec24985df610f97d98244" integrity sha512-OT2n6eZPje9hJfGV5XhNxA3HBBUwdmcA6LQ4opC35KK8DHVtIDfPLKhyOpo/xNlMG8cue7HmBJweWsyWQZG0LA== +agent-base@^7.1.0, agent-base@^7.1.2: + version "7.1.4" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8" + integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== + ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -4033,6 +4077,13 @@ blacklist@^1.1.4: resolved "https://registry.yarnpkg.com/blacklist/-/blacklist-1.1.4.tgz#b2dd09d6177625b2caa69835a37b28995fa9a2f2" integrity sha512-DWdfwimA1WQxVC69Vs1Fy525NbYwisMSCdYQmW9zyzOByz9OB/tQwrKZ3T3pbTkuFjnkJFlJuyiDjPiXL5kzew== +blockly@^12.5.1: + version "12.5.1" + resolved "https://registry.yarnpkg.com/blockly/-/blockly-12.5.1.tgz#5e63b65382861cc75a6a36a85d71346ea768f8e8" + integrity sha512-etXLpUtEkcRibHGwIJ4BsvnIzMJJs0C0yPIjE/W0NCtj8ACha/a7Q9n7Ib6+j7N4EzQ0p28YPZMnypi5pNIj1g== + dependencies: + jsdom "26.1.0" + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: version "4.12.2" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.2.tgz#3d8fed6796c24e177737f7cc5172ee04ef39ec99" @@ -4772,6 +4823,14 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +cssstyle@^4.2.1: + version "4.6.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-4.6.0.tgz#ea18007024e3167f4f105315f3ec2d982bf48ed9" + integrity sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg== + dependencies: + "@asamuzakjp/css-color" "^3.2.0" + rrweb-cssom "^0.8.0" + csstype@^3.0.2, csstype@^3.2.2: version "3.2.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" @@ -4784,6 +4843,14 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +data-urls@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-5.0.0.tgz#2f76906bce1824429ffecb6920f45a0b30f00dde" + integrity sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg== + dependencies: + whatwg-mimetype "^4.0.0" + whatwg-url "^14.0.0" + data-view-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz#211a03ba95ecaf7798a8c7198d79536211f88570" @@ -4828,6 +4895,13 @@ debounce@^1.2.1: resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== +debug@4, debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.7, debug@^4.4.0, debug@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + debug@4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -4842,19 +4916,12 @@ debug@^2.2.0, debug@~2.6.9: dependencies: ms "2.0.0" -debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.7, debug@^4.4.0, debug@^4.4.3: - version "4.4.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== - dependencies: - ms "^2.1.3" - decibels@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/decibels/-/decibels-2.0.0.tgz#0d064574319b263c1878c5effb9ad272610a7e8d" integrity sha512-SyNQWYUSrouIXs2JevCbtcl57GTIOhhRilqkCC0d5u6W4NjLBm61KWmR1+MQWIdjVzlu373ajzHvzvAkyidhTw== -decimal.js@^10.6.0: +decimal.js@^10.5.0, decimal.js@^10.6.0: version "10.6.0" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.6.0.tgz#e649a43e3ab953a72192ff5983865e509f37ed9a" integrity sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg== @@ -5175,6 +5242,11 @@ entities@^4.2.0, entities@^4.4.0: resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== +entities@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.1.tgz#c28c34a43379ca7f61d074130b2f5f7020a30694" + integrity sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g== + envinfo@^7.14.0: version "7.21.0" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.21.0.tgz#04a251be79f92548541f37d13c8b6f22940c3bae" @@ -6203,6 +6275,13 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" +html-encoding-sniffer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz#696df529a7cfd82446369dc5193e590a3735b448" + integrity sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ== + dependencies: + whatwg-encoding "^3.1.1" + html-entities@^2.1.0: version "2.6.0" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" @@ -6249,6 +6328,14 @@ http-errors@^2.0.0, http-errors@^2.0.1, http-errors@~2.0.1: statuses "~2.0.2" toidentifier "~1.0.1" +http-proxy-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" + integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -6263,12 +6350,20 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== +https-proxy-agent@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" + integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== + dependencies: + agent-base "^7.1.2" + debug "4" + hyperdyperid@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/hyperdyperid/-/hyperdyperid-1.2.0.tgz#59668d323ada92228d2a869d3e474d5a33b69e6b" integrity sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A== -iconv-lite@^0.6.3: +iconv-lite@0.6.3, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -6640,6 +6735,11 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + is-promise@^2.0.0: version "2.2.2" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" @@ -6819,6 +6919,32 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== +jsdom@26.1.0: + version "26.1.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-26.1.0.tgz#ab5f1c1cafc04bd878725490974ea5e8bf0c72b3" + integrity sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg== + dependencies: + cssstyle "^4.2.1" + data-urls "^5.0.0" + decimal.js "^10.5.0" + html-encoding-sniffer "^4.0.0" + http-proxy-agent "^7.0.2" + https-proxy-agent "^7.0.6" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.16" + parse5 "^7.2.1" + rrweb-cssom "^0.8.0" + saxes "^6.0.0" + symbol-tree "^3.2.4" + tough-cookie "^5.1.1" + w3c-xmlserializer "^5.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^3.1.1" + whatwg-mimetype "^4.0.0" + whatwg-url "^14.1.1" + ws "^8.18.0" + xml-name-validator "^5.0.0" + jsesc@^3.0.2, jsesc@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" @@ -7167,6 +7293,11 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lru-cache@^10.4.3: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^11.0.0: version "11.2.6" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.2.6.tgz#356bf8a29e88a7a2945507b31f6429a65a192c58" @@ -7886,6 +8017,11 @@ nu-stream@>=3.1.0, nu-stream@^3.3.1: resolved "https://registry.yarnpkg.com/nu-stream/-/nu-stream-3.3.1.tgz#d9ab5037bfd00c86e76bbe28686727063b91b3af" integrity sha512-d/0WL0EwGg+UNYYaiUPxqXKvqzs/UXtMLV4CzAkI5u6ljUIXjyDrGV3vAi3CVAlgTI/1QpubvRxsEvx5ibIyog== +nwsapi@^2.2.16: + version "2.2.23" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.23.tgz#59712c3a88e6de2bb0b6ccc1070397267019cf6c" + integrity sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ== + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -8159,6 +8295,13 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== +parse5@^7.2.1: + version "7.3.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.3.0.tgz#d7e224fa72399c7a175099f45fc2ad024b05ec05" + integrity sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw== + dependencies: + entities "^6.0.0" + parseurl@^1.3.3, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -9311,6 +9454,11 @@ router@^2.2.0: parseurl "^1.3.3" path-to-regexp "^8.0.0" +rrweb-cssom@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz#3021d1b4352fbf3b614aaeed0bc0d5739abe0bc2" + integrity sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw== + s3-browser-direct-upload@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/s3-browser-direct-upload/-/s3-browser-direct-upload-0.1.2.tgz#e3acccc62edc5643ee5b23fe3397fc08b2926503" @@ -9398,6 +9546,13 @@ sax@>=0.6.0: resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.4.tgz#f29c2bba80ce5b86f4343b4c2be9f2b96627cf8b" integrity sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw== +saxes@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" + integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA== + dependencies: + xmlchars "^2.2.0" + scheduler@^0.27.0: version "0.27.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.27.0.tgz#0c4ef82d67d1e5c1e359e8fc76d3a87f045fe5bd" @@ -9977,6 +10132,11 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + tapable@^2.2.1, tapable@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" @@ -10038,6 +10198,18 @@ tinyglobby@^0.2.12, tinyglobby@^0.2.15: fdir "^6.5.0" picomatch "^4.0.3" +tldts-core@^6.1.86: + version "6.1.86" + resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-6.1.86.tgz#a93e6ed9d505cb54c542ce43feb14c73913265d8" + integrity sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA== + +tldts@^6.1.32: + version "6.1.86" + resolved "https://registry.yarnpkg.com/tldts/-/tldts-6.1.86.tgz#087e0555b31b9725ee48ca7e77edc56115cd82f7" + integrity sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ== + dependencies: + tldts-core "^6.1.86" + to-array-buffer@^2.0.0: version "2.2.2" resolved "https://registry.yarnpkg.com/to-array-buffer/-/to-array-buffer-2.2.2.tgz#f9dc6b5a18f232636cf1515b7ca146fdaf88d442" @@ -10093,6 +10265,13 @@ tough-cookie@^4.1.3: universalify "^0.2.0" url-parse "^1.5.3" +tough-cookie@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-5.1.2.tgz#66d774b4a1d9e12dc75089725af3ac75ec31bed7" + integrity sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A== + dependencies: + tldts "^6.1.32" + tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -10101,6 +10280,13 @@ tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +tr46@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-5.1.1.tgz#96ae867cddb8fdb64a49cc3059a8d428bcf238ca" + integrity sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw== + dependencies: + punycode "^2.3.1" + transformation-matrix@^2.16.1: version "2.16.1" resolved "https://registry.yarnpkg.com/transformation-matrix/-/transformation-matrix-2.16.1.tgz#4a2de06331b94ae953193d1b9a5ba002ec5f658a" @@ -10617,6 +10803,13 @@ vscode-debugprotocol@^1.51.0: resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.51.0.tgz#c03168dac778b6c24ce17b3511cb61e89c11b2df" integrity sha512-dzKWTMMyebIMPF1VYMuuQj7gGFq7guR8AFya0mKacu+ayptJfaRuM0mdHCqiOth4FnRP8mPhEroFPx6Ift8wHA== +w3c-xmlserializer@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz#f925ba26855158594d907313cedd1476c5967f6c" + integrity sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA== + dependencies: + xml-name-validator "^5.0.0" + walkdir@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.4.1.tgz#dc119f83f4421df52e3061e514228a2db20afa39" @@ -10642,6 +10835,11 @@ wav-decoder@^1.1.0: resolved "https://registry.yarnpkg.com/wav-decoder/-/wav-decoder-1.3.0.tgz#1d0bf7195f623661bd182464c434a3e8bc42eb0e" integrity sha512-4U6O/JNb1dPO90CO2YMTQ5N2plJcntm39vNMvRq9VZ4Vy5FzS7Lnx95N2QcYUyKYcZfCbhI//W3dSHA8YnOQyQ== +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + webpack-bundle-analyzer@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-5.2.0.tgz#9bcf0e7cc8c86632a96bf7092300287dc284c3d7" @@ -10744,6 +10942,26 @@ webpack@^5.87.0: watchpack "^2.5.1" webpack-sources "^3.3.3" +whatwg-encoding@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz#d0f4ef769905d426e1688f3e34381a99b60b76e5" + integrity sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ== + dependencies: + iconv-lite "0.6.3" + +whatwg-mimetype@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz#bc1bf94a985dc50388d54a9258ac405c3ca2fc0a" + integrity sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg== + +whatwg-url@^14.0.0, whatwg-url@^14.1.1: + version "14.2.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-14.2.0.tgz#4ee02d5d725155dae004f6ae95c73e7ef5d95663" + integrity sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw== + dependencies: + tr46 "^5.1.0" + webidl-conversions "^7.0.0" + which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz#d76ec27df7fa165f18d5808374a5fe23c29b176e" @@ -10846,11 +11064,21 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +ws@^8.18.0: + version "8.20.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.20.0.tgz#4cd9532358eba60bc863aad1623dfb045a4d4af8" + integrity sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA== + ws@^8.19.0: version "8.19.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.19.0.tgz#ddc2bdfa5b9ad860204f5a72a4863a8895fd8c8b" integrity sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg== +xml-name-validator@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz#82be9b957f7afdacf961e5980f1bf227c0bf7673" + integrity sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg== + xml2js@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499" @@ -10864,6 +11092,11 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + xmldom@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.6.0.tgz#43a96ecb8beece991cef382c08397d82d4d0c46f"