From 88de302ab87ec7b1544c7147ed189062e04a6e40 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Tue, 15 Feb 2022 11:36:14 -0800 Subject: [PATCH] Fix central node positioning issue --- .../persistence/Beta2PelaMigrator.ts | 2 +- .../persistence/Pela2TangoMigrator.ts | 4 +- .../persistence/XMLSerializerFactory.ts | 3 +- .../persistence/XMLSerializerPela.ts | 519 ------------------ .../persistence/XMLSerializerTango.ts | 505 ++++++++++++++++- .../test/unit/export/expected/bug2.wxml | 2 +- .../test/unit/export/expected/complex.wxml | 4 +- .../test/unit/export/expected/emptyNodes.wxml | 2 +- .../test/unit/export/expected/enc.wxml | 6 +- .../test/unit/export/expected/i18n.wxml | 2 +- .../test/unit/export/expected/i18n2.wxml | 2 +- .../test/unit/export/expected/issue.wxml | 2 +- .../test/unit/export/expected/process.wxml | 2 +- .../test/unit/export/expected/welcome.wxml | 2 +- yarn.lock | 205 +------ 15 files changed, 524 insertions(+), 738 deletions(-) delete mode 100644 packages/mindplot/src/components/persistence/XMLSerializerPela.ts diff --git a/packages/mindplot/src/components/persistence/Beta2PelaMigrator.ts b/packages/mindplot/src/components/persistence/Beta2PelaMigrator.ts index 86a216d1..93129c30 100644 --- a/packages/mindplot/src/components/persistence/Beta2PelaMigrator.ts +++ b/packages/mindplot/src/components/persistence/Beta2PelaMigrator.ts @@ -20,7 +20,7 @@ import { Mindmap } from '../..'; import NodeModel from '../model/NodeModel'; import ModelCodeName from './ModelCodeName'; import XMLMindmapSerializer from './XMLMindmapSerializer'; -import XMLSerializerPela from './XMLSerializerPela'; +import XMLSerializerPela from './XMLSerializerTango'; class Beta2PelaMigrator implements XMLMindmapSerializer { private _betaSerializer: XMLMindmapSerializer; diff --git a/packages/mindplot/src/components/persistence/Pela2TangoMigrator.ts b/packages/mindplot/src/components/persistence/Pela2TangoMigrator.ts index c5b5ddfa..40ce6134 100644 --- a/packages/mindplot/src/components/persistence/Pela2TangoMigrator.ts +++ b/packages/mindplot/src/components/persistence/Pela2TangoMigrator.ts @@ -72,7 +72,7 @@ class Pela2TangoMigrator implements XMLMindmapSerializer { } } - private _fixPosition(mindmap: Mindmap) { + private _fixPosition(mindmap: Mindmap): void { // Position was not required in previous versions. Try to synthesize one . const centralNode = mindmap.getBranches()[0]; const children = centralNode.getChildren(); @@ -83,7 +83,7 @@ class Pela2TangoMigrator implements XMLMindmapSerializer { } } - _fixNodePosition(node: NodeModel, parentPosition: {x:number, y:number}) { + private _fixNodePosition(node: NodeModel, parentPosition: { x: number, y: number }): void { // Position was not required in previous versions. Try to synthesize one . let position = node.getPosition(); if (!position) { diff --git a/packages/mindplot/src/components/persistence/XMLSerializerFactory.ts b/packages/mindplot/src/components/persistence/XMLSerializerFactory.ts index f72b2285..0919bc63 100644 --- a/packages/mindplot/src/components/persistence/XMLSerializerFactory.ts +++ b/packages/mindplot/src/components/persistence/XMLSerializerFactory.ts @@ -20,7 +20,6 @@ import ModelCodeName from './ModelCodeName'; import Beta2PelaMigrator from './Beta2PelaMigrator'; import Pela2TangoMigrator from './Pela2TangoMigrator'; import XMLSerializerBeta from './XMLSerializerBeta'; -import XMLSerializerPela from './XMLSerializerPela'; import XMLSerializerTango from './XMLSerializerTango'; import Mindmap from '../model/Mindmap'; import XMLMindmapSerializer from './XMLMindmapSerializer'; @@ -35,7 +34,7 @@ const codeToSerializer: { codeName: string, serializer, migrator }[] = [ }, { codeName: ModelCodeName.PELA, - serializer: XMLSerializerPela, + serializer: XMLSerializerTango, migrator: Beta2PelaMigrator, }, { diff --git a/packages/mindplot/src/components/persistence/XMLSerializerPela.ts b/packages/mindplot/src/components/persistence/XMLSerializerPela.ts deleted file mode 100644 index d374ae42..00000000 --- a/packages/mindplot/src/components/persistence/XMLSerializerPela.ts +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright [2021] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { $assert, $defined, createDocument } from '@wisemapping/core-js'; -import { Point } from '@wisemapping/web2d'; -import Mindmap from '../model/Mindmap'; -import { TopicShape } from '../model/INodeModel'; -import ConnectionLine from '../ConnectionLine'; -import FeatureModelFactory from '../model/FeatureModelFactory'; -import NodeModel from '../model/NodeModel'; -import RelationshipModel from '../model/RelationshipModel'; -import XMLMindmapSerializer from './XMLMindmapSerializer'; -import FeatureType from '../model/FeatureType'; - -class XMLSerializerPela implements XMLMindmapSerializer { - private static MAP_ROOT_NODE = 'map'; - - private _idsMap: Record; - - toXML(mindmap: Mindmap): Document { - $assert(mindmap, 'Can not save a null mindmap'); - - const document = createDocument(); - - // Store map attributes ... - const mapElem = document.createElement('map'); - const name = mindmap.getId(); - if ($defined(name)) { - mapElem.setAttribute('name', this._rmXmlInv(name)); - } - const version = mindmap.getVersion(); - if ($defined(version)) { - mapElem.setAttribute('version', version); - } - - document.appendChild(mapElem); - - // Create branches ... - const topics = mindmap.getBranches(); - topics.forEach((topic) => { - const topicDom = this._topicToXML(document, topic); - mapElem.appendChild(topicDom); - }); - - // Create Relationships - const relationships = mindmap.getRelationships(); - relationships.forEach((relationship) => { - if ( - mindmap.findNodeById(relationship.getFromNode()) !== null - && mindmap.findNodeById(relationship.getToNode()) !== null - ) { - // Isolated relationships are not persisted .... - const relationDom = XMLSerializerPela._relationshipToXML(document, relationship); - mapElem.appendChild(relationDom); - } - }); - - return document; - } - - protected _topicToXML(document: Document, topic: NodeModel) { - const parentTopic = document.createElement('topic'); - - // Set topic attributes... - if (topic.getType() === 'CentralTopic') { - parentTopic.setAttribute('central', 'true'); - } else { - const pos = topic.getPosition(); - parentTopic.setAttribute('position', `${pos.x},${pos.y}`); - - const order = topic.getOrder(); - if (typeof order === 'number' && Number.isFinite(order)) { - parentTopic.setAttribute('order', order.toString()); - } - } - - const text = topic.getText(); - if ($defined(text)) { - this._noteTextToXML(document, parentTopic, text); - } - - const shape = topic.getShapeType(); - if ($defined(shape)) { - parentTopic.setAttribute('shape', shape); - - if (shape === TopicShape.IMAGE) { - const size = topic.getImageSize(); - parentTopic.setAttribute( - 'image', - `${size.width},${size.height}:${topic.getImageUrl()}`, - ); - } - } - - if (topic.areChildrenShrunken() && topic.getType() !== 'CentralTopic') { - parentTopic.setAttribute('shrink', 'true'); - } - - // Font properties ... - const id = topic.getId(); - parentTopic.setAttribute('id', id.toString()); - - let font = ''; - - const fontFamily = topic.getFontFamily(); - font += `${fontFamily || ''};`; - - const fontSize = topic.getFontSize(); - font += `${fontSize || ''};`; - - const fontColor = topic.getFontColor(); - font += `${fontColor || ''};`; - - const fontWeight = topic.getFontWeight(); - font += `${fontWeight || ''};`; - - const fontStyle = topic.getFontStyle(); - font += `${fontStyle || ''};`; - - if ( - $defined(fontFamily) - || $defined(fontSize) - || $defined(fontColor) - || $defined(fontWeight) - || $defined(fontStyle) - ) { - parentTopic.setAttribute('fontStyle', font); - } - - const bgColor = topic.getBackgroundColor(); - if ($defined(bgColor)) { - parentTopic.setAttribute('bgColor', bgColor); - } - - const brColor = topic.getBorderColor(); - if ($defined(brColor)) { - parentTopic.setAttribute('brColor', brColor); - } - - const metadata = topic.getMetadata(); - if ($defined(metadata)) { - parentTopic.setAttribute('metadata', metadata); - } - - // Serialize features ... - const features = topic.getFeatures(); - features.forEach((feature) => { - const featureType = feature.getType(); - const featureDom = document.createElement(featureType); - const attributes = feature.getAttributes(); - - const attributesKeys = Object.keys(attributes); - for (let attrIndex = 0; attrIndex < attributesKeys.length; attrIndex++) { - const key = attributesKeys[attrIndex]; - const value = attributes[key]; - if (key === 'text') { - const cdata = document.createCDATASection(this._rmXmlInv(value)); - featureDom.appendChild(cdata); - } else { - featureDom.setAttribute(key, this._rmXmlInv(value)); - } - } - parentTopic.appendChild(featureDom); - }); - - // CHILDREN TOPICS - const childTopics = topic.getChildren(); - childTopics.forEach((childTopic) => { - const childDom = this._topicToXML(document, childTopic); - parentTopic.appendChild(childDom); - }); - - return parentTopic; - } - - protected _noteTextToXML(document: Document, elem: Element, text: string) { - if (text.indexOf('\n') === -1) { - elem.setAttribute('text', this._rmXmlInv(text)); - } else { - const textDom = document.createElement('text'); - const cdata = document.createCDATASection(this._rmXmlInv(text)); - textDom.appendChild(cdata); - elem.appendChild(textDom); - } - } - - static _relationshipToXML(document: Document, relationship: RelationshipModel) { - const result = document.createElement('relationship'); - result.setAttribute('srcTopicId', relationship.getFromNode().toString()); - result.setAttribute('destTopicId', relationship.getToNode().toString()); - - const lineType = relationship.getLineType(); - result.setAttribute('lineType', lineType.toString()); - if (lineType === ConnectionLine.CURVED || lineType === ConnectionLine.SIMPLE_CURVED) { - if ($defined(relationship.getSrcCtrlPoint())) { - const srcPoint = relationship.getSrcCtrlPoint(); - result.setAttribute( - 'srcCtrlPoint', - `${Math.round(srcPoint.x)},${Math.round(srcPoint.y)}`, - ); - } - if ($defined(relationship.getDestCtrlPoint())) { - const destPoint = relationship.getDestCtrlPoint(); - result.setAttribute( - 'destCtrlPoint', - `${Math.round(destPoint.x)},${Math.round(destPoint.y)}`, - ); - } - } - result.setAttribute('endArrow', String(relationship.getEndArrow())); - result.setAttribute('startArrow', String(relationship.getStartArrow())); - return result; - } - - loadFromDom(dom: Document, mapId: string) { - $assert(dom, 'dom can not be null'); - $assert(mapId, 'mapId can not be null'); - - const rootElem = dom.documentElement; - - // Is a wisemap?. - $assert( - rootElem.tagName === XMLSerializerPela.MAP_ROOT_NODE, - `This seem not to be a map document. Found tag: ${rootElem.tagName}`, - ); - - this._idsMap = {}; - // Start the loading process ... - const version = rootElem.getAttribute('version') || 'pela'; - const mindmap = new Mindmap(mapId, version); - - // Add all the topics nodes ... - const childNodes = Array.from(rootElem.childNodes); - const topicsNodes = childNodes - .filter( - (child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'topic', - ) - .map((c) => c as Element); - topicsNodes.forEach((child) => { - const topic = this._deserializeNode(child, mindmap); - mindmap.addBranch(topic); - }); - - // Then all relationshops, they are connected to topics ... - const relationshipsNodes = childNodes - .filter( - (child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'relationship', - ) - .map((c) => c as Element); - relationshipsNodes.forEach((child) => { - try { - const relationship = XMLSerializerPela._deserializeRelationship(child, mindmap); - mindmap.addRelationship(relationship); - } catch (e) { - console.error(e); - } - }); - - // Clean up from the recursion ... - this._idsMap = null; - mindmap.setId(mapId); - return mindmap; - } - - protected _deserializeNode(domElem: Element, mindmap: Mindmap) { - const type = domElem.getAttribute('central') != null ? 'CentralTopic' : 'MainTopic'; - - // Load attributes... - let id: number | null = null; - if ($defined(domElem.getAttribute('id'))) { - id = Number.parseInt(domElem.getAttribute('id'), 10); - } - - if (this._idsMap[id]) { - id = null; - } else { - this._idsMap[id] = domElem; - } - - const topic = mindmap.createNode(type, id); - - // Set text property is it;s defined... - const text = domElem.getAttribute('text'); - if ($defined(text) && text) { - topic.setText(text); - } - - const fontStyle = domElem.getAttribute('fontStyle'); - if ($defined(fontStyle) && fontStyle) { - const font = fontStyle.split(';'); - - if (font[0]) { - topic.setFontFamily(font[0]); - } - - if (font[1]) { - topic.setFontSize(Number.parseInt(font[1], 10)); - } - - if (font[2]) { - topic.setFontColor(font[2]); - } - - if (font[3]) { - topic.setFontWeight(font[3]); - } - - if (font[4]) { - topic.setFontStyle(font[4]); - } - } - - const shape = domElem.getAttribute('shape'); - if ($defined(shape)) { - topic.setShapeType(shape); - - if (shape === TopicShape.IMAGE) { - const image = domElem.getAttribute('image'); - const size = image.substring(0, image.indexOf(':')); - const url = image.substring(image.indexOf(':') + 1, image.length); - topic.setImageUrl(url); - - const split = size.split(','); - topic.setImageSize(Number.parseInt(split[0], 10), Number.parseInt(split[1], 10)); - } - } - - const bgColor = domElem.getAttribute('bgColor'); - if ($defined(bgColor)) { - topic.setBackgroundColor(bgColor); - } - - const borderColor = domElem.getAttribute('brColor'); - if ($defined(borderColor)) { - topic.setBorderColor(borderColor); - } - - const order = domElem.getAttribute('order'); - if ($defined(order) && order !== 'NaN') { - // Hack for broken maps ... - topic.setOrder(parseInt(order, 10)); - } - - const isShrink = domElem.getAttribute('shrink'); - // Hack: Some production maps has been stored with the central topic collapsed. This is a bug. - if ($defined(isShrink) && type !== 'CentralTopic') { - topic.setChildrenShrunken(Boolean(isShrink)); - } - - const position = domElem.getAttribute('position'); - if ($defined(position)) { - const pos = position.split(','); - topic.setPosition(Number.parseInt(pos[0], 10), Number.parseInt(pos[1], 10)); - } - - const metadata = domElem.getAttribute('metadata'); - if ($defined(metadata)) { - topic.setMetadata(metadata); - } - - // Creating icons and children nodes - const children = Array.from(domElem.childNodes); - children.forEach((child) => { - if (child.nodeType === Node.ELEMENT_NODE) { - const elem = child as Element; - if (elem.tagName === 'topic') { - const childTopic = this._deserializeNode(elem, mindmap); - childTopic.connectTo(topic); - } else if (FeatureModelFactory.isSupported(elem.tagName)) { - // Load attributes ... - const namedNodeMap = elem.attributes; - const attributes: Record = {}; - - for (let j = 0; j < namedNodeMap.length; j++) { - const attribute = namedNodeMap.item(j); - attributes[attribute.name] = attribute.value; - } - - // Has text node ?. - const textAttr = XMLSerializerPela._deserializeTextAttr(elem); - if (textAttr) { - attributes.text = textAttr; - } - - // Create a new element .... - const featureType = elem.tagName as FeatureType; - const feature = FeatureModelFactory.createModel(featureType, attributes); - topic.addFeature(feature); - } else if (elem.tagName === 'text') { - const nodeText = XMLSerializerPela._deserializeNodeText(child); - topic.setText(nodeText); - } - } - }); - - // Workaround: for some reason, some saved maps have holes in the order. - topic - .getChildren() - .forEach((child, index) => { - if (child.getOrder() !== index) { - child.setOrder(index); - console.log('Toppic with order sequence hole. Introducing auto recovery sequence fix.'); - } - }); - - return topic; - } - - static _deserializeTextAttr(domElem: Element): string { - let value = domElem.getAttribute('text'); - if (!$defined(value)) { - const children = domElem.childNodes; - for (let i = 0; i < children.length; i++) { - const child = children[i]; - if (child.nodeType === Node.CDATA_SECTION_NODE) { - value = child.nodeValue; - } - } - } else { - // Notes must be decoded ... - value = unescape(value); - - // Hack for empty nodes ... - if (value === '') { - value = ' '; - } - } - - return value; - } - - static _deserializeNodeText(domElem) { - const children = domElem.childNodes; - let value = null; - for (let i = 0; i < children.length; i++) { - const child = children[i]; - if (child.nodeType === Node.CDATA_SECTION_NODE) { - value = child.nodeValue; - } - } - return value; - } - - static _deserializeRelationship(domElement, mindmap) { - const srcId = Number.parseInt(domElement.getAttribute('srcTopicId'), 10); - const destId = Number.parseInt(domElement.getAttribute('destTopicId'), 10); - const lineType = Number.parseInt(domElement.getAttribute('lineType'), 10); - const srcCtrlPoint = domElement.getAttribute('srcCtrlPoint'); - const destCtrlPoint = domElement.getAttribute('destCtrlPoint'); - - // If for some reason a relationship lines has source and dest nodes the same, don't import it. - if (srcId === destId) { - throw new Error('Invalid relationship, dest and source are equals'); - } - // Is the connections points valid ?. If it's not, do not load the relationship ... - if (mindmap.findNodeById(srcId) == null || mindmap.findNodeById(destId) == null) { - throw new Error('Transition could not created, missing node for relationship'); - } - - const model = mindmap.createRelationship(srcId, destId); - model.setLineType(lineType); - if ($defined(srcCtrlPoint) && srcCtrlPoint !== '') { - model.setSrcCtrlPoint(Point.fromString(srcCtrlPoint)); - } - if ($defined(destCtrlPoint) && destCtrlPoint !== '') { - model.setDestCtrlPoint(Point.fromString(destCtrlPoint)); - } - model.setEndArrow('false'); - model.setStartArrow('true'); - return model; - } - - /** - * This method ensures that the output String has only - * valid XML unicode characters as specified by the - * XML 1.0 standard. For reference, please see - * the - * standard. This method will return an empty - * String if the input is null or empty. - * - * @param in The String whose non-valid characters we want to remove. - * @return The in String, stripped of non-valid characters. - */ - protected _rmXmlInv(str: string) { - if (str == null || str === undefined) return null; - - let result = ''; - for (let i = 0; i < str.length; i++) { - const c = str.charCodeAt(i); - if ( - c === 0x9 - || c === 0xa - || c === 0xd - || (c >= 0x20 && c <= 0xd7ff) - || (c >= 0xe000 && c <= 0xfffd) - || (c >= 0x10000 && c <= 0x10ffff) - ) { - result += str.charAt(i); - } - } - return result; - } -} - -export default XMLSerializerPela; diff --git a/packages/mindplot/src/components/persistence/XMLSerializerTango.ts b/packages/mindplot/src/components/persistence/XMLSerializerTango.ts index c9bde900..b7551016 100644 --- a/packages/mindplot/src/components/persistence/XMLSerializerTango.ts +++ b/packages/mindplot/src/components/persistence/XMLSerializerTango.ts @@ -15,13 +15,506 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import XMLSerializerPela from './XMLSerializerPela'; +import { $assert, $defined, createDocument } from '@wisemapping/core-js'; +import { Point } from '@wisemapping/web2d'; +import Mindmap from '../model/Mindmap'; +import { TopicShape } from '../model/INodeModel'; +import ConnectionLine from '../ConnectionLine'; +import FeatureModelFactory from '../model/FeatureModelFactory'; +import NodeModel from '../model/NodeModel'; +import RelationshipModel from '../model/RelationshipModel'; +import XMLMindmapSerializer from './XMLMindmapSerializer'; +import FeatureType from '../model/FeatureType'; -/** - * This serializer works exactly the same way as for the former version Pela - */ -class XMLSerializerTango extends XMLSerializerPela { +class XMLSerializerTango implements XMLMindmapSerializer { + private static MAP_ROOT_NODE = 'map'; + + private _idsMap: Record; + + toXML(mindmap: Mindmap): Document { + $assert(mindmap, 'Can not save a null mindmap'); + + const document = createDocument(); + + // Store map attributes ... + const mapElem = document.createElement('map'); + const name = mindmap.getId(); + if ($defined(name)) { + mapElem.setAttribute('name', this._rmXmlInv(name)); + } + const version = mindmap.getVersion(); + if ($defined(version)) { + mapElem.setAttribute('version', version); + } + + document.appendChild(mapElem); + + // Create branches ... + const topics = mindmap.getBranches(); + topics.forEach((topic) => { + const topicDom = this._topicToXML(document, topic); + mapElem.appendChild(topicDom); + }); + + // Create Relationships + const relationships = mindmap.getRelationships(); + relationships.forEach((relationship) => { + if ( + mindmap.findNodeById(relationship.getFromNode()) !== null + && mindmap.findNodeById(relationship.getToNode()) !== null + ) { + // Isolated relationships are not persisted .... + const relationDom = XMLSerializerTango._relationshipToXML(document, relationship); + mapElem.appendChild(relationDom); + } + }); + + return document; + } + + protected _topicToXML(document: Document, topic: NodeModel) { + const parentTopic = document.createElement('topic'); + + // Set topic attributes... + if (topic.getType() === 'CentralTopic') { + parentTopic.setAttribute('central', 'true'); + } else { + const pos = topic.getPosition(); + parentTopic.setAttribute('position', `${pos.x},${pos.y}`); + + const order = topic.getOrder(); + if (typeof order === 'number' && Number.isFinite(order)) { + parentTopic.setAttribute('order', order.toString()); + } + } + + const text = topic.getText(); + if ($defined(text)) { + this._noteTextToXML(document, parentTopic, text); + } + + const shape = topic.getShapeType(); + if ($defined(shape)) { + parentTopic.setAttribute('shape', shape); + + if (shape === TopicShape.IMAGE) { + const size = topic.getImageSize(); + parentTopic.setAttribute( + 'image', + `${size.width},${size.height}:${topic.getImageUrl()}`, + ); + } + } + + if (topic.areChildrenShrunken() && topic.getType() !== 'CentralTopic') { + parentTopic.setAttribute('shrink', 'true'); + } + + // Font properties ... + const id = topic.getId(); + parentTopic.setAttribute('id', id.toString()); + + let font = ''; + + const fontFamily = topic.getFontFamily(); + font += `${fontFamily || ''};`; + + const fontSize = topic.getFontSize(); + font += `${fontSize || ''};`; + + const fontColor = topic.getFontColor(); + font += `${fontColor || ''};`; + + const fontWeight = topic.getFontWeight(); + font += `${fontWeight || ''};`; + + const fontStyle = topic.getFontStyle(); + font += `${fontStyle || ''};`; + + if ( + $defined(fontFamily) + || $defined(fontSize) + || $defined(fontColor) + || $defined(fontWeight) + || $defined(fontStyle) + ) { + parentTopic.setAttribute('fontStyle', font); + } + + const bgColor = topic.getBackgroundColor(); + if ($defined(bgColor)) { + parentTopic.setAttribute('bgColor', bgColor); + } + + const brColor = topic.getBorderColor(); + if ($defined(brColor)) { + parentTopic.setAttribute('brColor', brColor); + } + + const metadata = topic.getMetadata(); + if ($defined(metadata)) { + parentTopic.setAttribute('metadata', metadata); + } + + // Serialize features ... + const features = topic.getFeatures(); + features.forEach((feature) => { + const featureType = feature.getType(); + const featureDom = document.createElement(featureType); + const attributes = feature.getAttributes(); + + const attributesKeys = Object.keys(attributes); + for (let attrIndex = 0; attrIndex < attributesKeys.length; attrIndex++) { + const key = attributesKeys[attrIndex]; + const value = attributes[key]; + if (key === 'text') { + const cdata = document.createCDATASection(this._rmXmlInv(value)); + featureDom.appendChild(cdata); + } else { + featureDom.setAttribute(key, this._rmXmlInv(value)); + } + } + parentTopic.appendChild(featureDom); + }); + + // CHILDREN TOPICS + const childTopics = topic.getChildren(); + childTopics.forEach((childTopic) => { + const childDom = this._topicToXML(document, childTopic); + parentTopic.appendChild(childDom); + }); + + return parentTopic; + } + + protected _noteTextToXML(document: Document, elem: Element, text: string) { + if (text.indexOf('\n') === -1) { + elem.setAttribute('text', this._rmXmlInv(text)); + } else { + const textDom = document.createElement('text'); + const cdata = document.createCDATASection(this._rmXmlInv(text)); + textDom.appendChild(cdata); + elem.appendChild(textDom); + } + } + + static _relationshipToXML(document: Document, relationship: RelationshipModel) { + const result = document.createElement('relationship'); + result.setAttribute('srcTopicId', relationship.getFromNode().toString()); + result.setAttribute('destTopicId', relationship.getToNode().toString()); + + const lineType = relationship.getLineType(); + result.setAttribute('lineType', lineType.toString()); + if (lineType === ConnectionLine.CURVED || lineType === ConnectionLine.SIMPLE_CURVED) { + if ($defined(relationship.getSrcCtrlPoint())) { + const srcPoint = relationship.getSrcCtrlPoint(); + result.setAttribute( + 'srcCtrlPoint', + `${Math.round(srcPoint.x)},${Math.round(srcPoint.y)}`, + ); + } + if ($defined(relationship.getDestCtrlPoint())) { + const destPoint = relationship.getDestCtrlPoint(); + result.setAttribute( + 'destCtrlPoint', + `${Math.round(destPoint.x)},${Math.round(destPoint.y)}`, + ); + } + } + result.setAttribute('endArrow', String(relationship.getEndArrow())); + result.setAttribute('startArrow', String(relationship.getStartArrow())); + return result; + } + + loadFromDom(dom: Document, mapId: string) { + $assert(dom, 'dom can not be null'); + $assert(mapId, 'mapId can not be null'); + + const rootElem = dom.documentElement; + + // Is a wisemap?. + $assert( + rootElem.tagName === XMLSerializerTango.MAP_ROOT_NODE, + `This seem not to be a map document. Found tag: ${rootElem.tagName}`, + ); + + this._idsMap = {}; + // Start the loading process ... + const version = rootElem.getAttribute('version') || 'pela'; + const mindmap = new Mindmap(mapId, version); + + // Add all the topics nodes ... + const childNodes = Array.from(rootElem.childNodes); + const topicsNodes = childNodes + .filter( + (child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'topic', + ) + .map((c) => c as Element); + topicsNodes.forEach((child) => { + const topic = this._deserializeNode(child, mindmap); + mindmap.addBranch(topic); + }); + + // Then all relationshops, they are connected to topics ... + const relationshipsNodes = childNodes + .filter( + (child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'relationship', + ) + .map((c) => c as Element); + relationshipsNodes.forEach((child) => { + try { + const relationship = XMLSerializerTango._deserializeRelationship(child, mindmap); + mindmap.addRelationship(relationship); + } catch (e) { + console.error(e); + } + }); + + // Clean up from the recursion ... + this._idsMap = null; + mindmap.setId(mapId); + return mindmap; + } + + protected _deserializeNode(domElem: Element, mindmap: Mindmap) { + const type = domElem.getAttribute('central') != null ? 'CentralTopic' : 'MainTopic'; + + // Load attributes... + let id: number | null = null; + if ($defined(domElem.getAttribute('id'))) { + id = Number.parseInt(domElem.getAttribute('id'), 10); + } + + if (this._idsMap[id]) { + id = null; + } else { + this._idsMap[id] = domElem; + } + + const topic = mindmap.createNode(type, id); + + // Set text property is it;s defined... + const text = domElem.getAttribute('text'); + if ($defined(text) && text) { + topic.setText(text); + } + + const fontStyle = domElem.getAttribute('fontStyle'); + if ($defined(fontStyle) && fontStyle) { + const font = fontStyle.split(';'); + + if (font[0]) { + topic.setFontFamily(font[0]); + } + + if (font[1]) { + topic.setFontSize(Number.parseInt(font[1], 10)); + } + + if (font[2]) { + topic.setFontColor(font[2]); + } + + if (font[3]) { + topic.setFontWeight(font[3]); + } + + if (font[4]) { + topic.setFontStyle(font[4]); + } + } + + const shape = domElem.getAttribute('shape'); + if ($defined(shape)) { + topic.setShapeType(shape); + + if (shape === TopicShape.IMAGE) { + const image = domElem.getAttribute('image'); + const size = image.substring(0, image.indexOf(':')); + const url = image.substring(image.indexOf(':') + 1, image.length); + topic.setImageUrl(url); + + const split = size.split(','); + topic.setImageSize(Number.parseInt(split[0], 10), Number.parseInt(split[1], 10)); + } + } + + const bgColor = domElem.getAttribute('bgColor'); + if ($defined(bgColor)) { + topic.setBackgroundColor(bgColor); + } + + const borderColor = domElem.getAttribute('brColor'); + if ($defined(borderColor)) { + topic.setBorderColor(borderColor); + } + + const order = domElem.getAttribute('order'); + if ($defined(order) && order !== 'NaN') { + // Hack for broken maps ... + topic.setOrder(parseInt(order, 10)); + } + + const isShrink = domElem.getAttribute('shrink'); + // Hack: Some production maps has been stored with the central topic collapsed. This is a bug. + if ($defined(isShrink) && type !== 'CentralTopic') { + topic.setChildrenShrunken(Boolean(isShrink)); + } + + const position = domElem.getAttribute('position'); + if ($defined(position)) { + const pos = position.split(','); + topic.setPosition(Number.parseInt(pos[0], 10), Number.parseInt(pos[1], 10)); + } + + const metadata = domElem.getAttribute('metadata'); + if ($defined(metadata)) { + topic.setMetadata(metadata); + } + + // Creating icons and children nodes + const children = Array.from(domElem.childNodes); + children.forEach((child) => { + if (child.nodeType === Node.ELEMENT_NODE) { + const elem = child as Element; + if (elem.tagName === 'topic') { + const childTopic = this._deserializeNode(elem, mindmap); + childTopic.connectTo(topic); + } else if (FeatureModelFactory.isSupported(elem.tagName)) { + // Load attributes ... + const namedNodeMap = elem.attributes; + const attributes: Record = {}; + + for (let j = 0; j < namedNodeMap.length; j++) { + const attribute = namedNodeMap.item(j); + attributes[attribute.name] = attribute.value; + } + + // Has text node ?. + const textAttr = XMLSerializerTango._deserializeTextAttr(elem); + if (textAttr) { + attributes.text = textAttr; + } + + // Create a new element .... + const featureType = elem.tagName as FeatureType; + const feature = FeatureModelFactory.createModel(featureType, attributes); + topic.addFeature(feature); + } else if (elem.tagName === 'text') { + const nodeText = XMLSerializerTango._deserializeNodeText(child); + topic.setText(nodeText); + } + } + }); + + // Workaround: for some reason, some saved maps have holes in the order. + if (topic.getType() !== 'CentralTopic') { + topic + .getChildren() + .forEach((child, index) => { + if (child.getOrder() !== index) { + child.setOrder(index); + console.log('Toppic with order sequence hole. Introducing auto recovery sequence fix.'); + } + }); + } + return topic; + } + + static _deserializeTextAttr(domElem: Element): string { + let value = domElem.getAttribute('text'); + if (!$defined(value)) { + const children = domElem.childNodes; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + if (child.nodeType === Node.CDATA_SECTION_NODE) { + value = child.nodeValue; + } + } + } else { + // Notes must be decoded ... + value = unescape(value); + + // Hack for empty nodes ... + if (value === '') { + value = ' '; + } + } + + return value; + } + + static _deserializeNodeText(domElem) { + const children = domElem.childNodes; + let value = null; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + if (child.nodeType === Node.CDATA_SECTION_NODE) { + value = child.nodeValue; + } + } + return value; + } + + static _deserializeRelationship(domElement, mindmap) { + const srcId = Number.parseInt(domElement.getAttribute('srcTopicId'), 10); + const destId = Number.parseInt(domElement.getAttribute('destTopicId'), 10); + const lineType = Number.parseInt(domElement.getAttribute('lineType'), 10); + const srcCtrlPoint = domElement.getAttribute('srcCtrlPoint'); + const destCtrlPoint = domElement.getAttribute('destCtrlPoint'); + + // If for some reason a relationship lines has source and dest nodes the same, don't import it. + if (srcId === destId) { + throw new Error('Invalid relationship, dest and source are equals'); + } + // Is the connections points valid ?. If it's not, do not load the relationship ... + if (mindmap.findNodeById(srcId) == null || mindmap.findNodeById(destId) == null) { + throw new Error('Transition could not created, missing node for relationship'); + } + + const model = mindmap.createRelationship(srcId, destId); + model.setLineType(lineType); + if ($defined(srcCtrlPoint) && srcCtrlPoint !== '') { + model.setSrcCtrlPoint(Point.fromString(srcCtrlPoint)); + } + if ($defined(destCtrlPoint) && destCtrlPoint !== '') { + model.setDestCtrlPoint(Point.fromString(destCtrlPoint)); + } + model.setEndArrow('false'); + model.setStartArrow('true'); + return model; + } + + /** + * This method ensures that the output String has only + * valid XML unicode characters as specified by the + * XML 1.0 standard. For reference, please see + * the + * standard. This method will return an empty + * String if the input is null or empty. + * + * @param in The String whose non-valid characters we want to remove. + * @return The in String, stripped of non-valid characters. + */ + protected _rmXmlInv(str: string) { + if (str == null || str === undefined) return null; + + let result = ''; + for (let i = 0; i < str.length; i++) { + const c = str.charCodeAt(i); + if ( + c === 0x9 + || c === 0xa + || c === 0xd + || (c >= 0x20 && c <= 0xd7ff) + || (c >= 0xe000 && c <= 0xfffd) + || (c >= 0x10000 && c <= 0x10ffff) + ) { + result += str.charAt(i); + } + } + return result; + } } -// eslint-disable-next-line camelcase export default XMLSerializerTango; diff --git a/packages/mindplot/test/unit/export/expected/bug2.wxml b/packages/mindplot/test/unit/export/expected/bug2.wxml index cd834c95..227024c2 100644 --- a/packages/mindplot/test/unit/export/expected/bug2.wxml +++ b/packages/mindplot/test/unit/export/expected/bug2.wxml @@ -1,4 +1,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/packages/mindplot/test/unit/export/expected/enc.wxml b/packages/mindplot/test/unit/export/expected/enc.wxml index f3125a36..b4136958 100644 --- a/packages/mindplot/test/unit/export/expected/enc.wxml +++ b/packages/mindplot/test/unit/export/expected/enc.wxml @@ -1,4 +1,4 @@ - \ No newline at end of file +]]> \ No newline at end of file diff --git a/packages/mindplot/test/unit/export/expected/i18n.wxml b/packages/mindplot/test/unit/export/expected/i18n.wxml index 2d070367..ba46f4c7 100644 --- a/packages/mindplot/test/unit/export/expected/i18n.wxml +++ b/packages/mindplot/test/unit/export/expected/i18n.wxml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/packages/mindplot/test/unit/export/expected/i18n2.wxml b/packages/mindplot/test/unit/export/expected/i18n2.wxml index 88926136..29489ecd 100644 --- a/packages/mindplot/test/unit/export/expected/i18n2.wxml +++ b/packages/mindplot/test/unit/export/expected/i18n2.wxml @@ -1,2 +1,2 @@ - \ No newline at end of file diff --git a/packages/mindplot/test/unit/export/expected/issue.wxml b/packages/mindplot/test/unit/export/expected/issue.wxml index 01f0ef64..60133dc8 100644 --- a/packages/mindplot/test/unit/export/expected/issue.wxml +++ b/packages/mindplot/test/unit/export/expected/issue.wxml @@ -8,7 +8,7 @@ BD, Disco duro, Memoria flash.]]> \ No newline at end of file + \ No newline at end of file diff --git a/packages/mindplot/test/unit/export/expected/welcome.wxml b/packages/mindplot/test/unit/export/expected/welcome.wxml index bc5b8724..7808c874 100644 --- a/packages/mindplot/test/unit/export/expected/welcome.wxml +++ b/packages/mindplot/test/unit/export/expected/welcome.wxml @@ -1,3 +1,3 @@ \ No newline at end of file +Sibling]]> \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index d4c8eea0..23021650 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1089,43 +1089,6 @@ dependencies: "@date-io/core" "^2.13.1" -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@cypress/request@^2.88.10", "@cypress/request@^2.88.6": - version "2.88.10" - resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.10.tgz#b66d76b07f860d3a4b8d7a0604d020c662752cce" - integrity sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - http-signature "~1.3.6" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^8.3.2" - -"@cypress/xvfb@^1.2.4": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" - integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== - dependencies: - debug "^3.1.0" - lodash.once "^4.1.1" - "@discoveryjs/json-ext@^0.5.0": version "0.5.6" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" @@ -5315,13 +5278,6 @@ cookie@0.4.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== -copy-anything@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.3.tgz#842407ba02466b0df844819bbe3baebbe5d45d87" - integrity sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ== - dependencies: - is-what "^3.12.0" - copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -5425,14 +5381,6 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" -create-react-context@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c" - integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw== - dependencies: - gud "^1.0.0" - warning "^4.0.3" - create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -6245,7 +6193,7 @@ err-code@^1.0.0: resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= -errno@^0.1.1, errno@^0.1.3: +errno@^0.1.3: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== @@ -6608,7 +6556,7 @@ eslint@^7.14.0: ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" - debug "^4.3.2" + debug "^4.0.1" doctrine "^3.0.0" enquirer "^2.3.5" escape-string-regexp "^4.0.0" @@ -6627,7 +6575,7 @@ eslint@^7.14.0: import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^4.1.0" + js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" @@ -6635,9 +6583,9 @@ eslint@^7.14.0: natural-compare "^1.4.0" optionator "^0.9.1" progress "^2.0.0" - regexpp "^3.2.0" + regexpp "^3.1.0" semver "^7.2.1" - strip-ansi "^6.0.1" + strip-ansi "^6.0.0" strip-json-comments "^3.1.0" table "^6.0.9" text-table "^0.2.0" @@ -6838,49 +6786,6 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@4.1.0, execa@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" - integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - -execa@5.1.1, execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -7777,11 +7682,6 @@ growl@1.10.5: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== -gud@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" - integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== - gzip-size@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" @@ -8074,15 +7974,6 @@ http-proxy-agent@^4.0.1: agent-base "6" debug "4" -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - http-proxy-middleware@0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" @@ -8185,7 +8076,7 @@ hyphenate-style-name@^1.0.3: resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== -iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: +iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -8711,18 +8602,6 @@ is-number-object@^1.0.4: dependencies: has-tostringtag "^1.0.0" -is-npm@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" - integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== - -is-number-object@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" - integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== - dependencies: - has-tostringtag "^1.0.0" - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -10032,7 +9911,7 @@ loglevel@^1.6.8: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.0.tgz#e7ec73a57e1e7b419cb6c6ac06bf050b67356114" integrity sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: +loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -10354,7 +10233,7 @@ mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, dependencies: mime-db "1.51.0" -mime@1.6.0, mime@^1.4.1: +mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== @@ -10647,15 +10526,6 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -needle@^2.5.2: - version "2.9.1" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684" - integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -11373,11 +11243,6 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse-node-version@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" - integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== - parse-path@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.3.tgz#82d81ec3e071dcc4ab49aa9f2c9c0b8966bb22bf" @@ -11772,11 +11637,6 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -promise-polyfill@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.0.tgz#30059da54d1358ce905ac581f287e184aedf995d" - integrity sha512-OzSf6gcCUQ01byV4BgwyUCswlaQQ6gzXc23aLQWhicvfX9kfsUiUhgt3CCQej8jDnl8/PhGF31JdHX2/MzF3WA== - promise-retry@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" @@ -11800,7 +11660,7 @@ promzard@^0.3.0: dependencies: read "1" -prop-types@^15.0.0, prop-types@^15.5.0, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.0, prop-types@^15.6.2, prop-types@^15.7.2: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -11918,13 +11778,6 @@ qs@6.9.6: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== -qs@^6.9.4: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== - dependencies: - side-channel "^1.0.4" - qs@^6.9.4: version "6.10.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.2.tgz#c1431bea37fc5b24c5bdbafa20f16bdf2a4b9ffe" @@ -11947,16 +11800,6 @@ query-string@^6.13.8: split-on-first "^1.0.0" strict-uri-encode "^2.0.0" -query-string@^6.13.8: - version "6.14.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" - integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== - dependencies: - decode-uri-component "^0.2.0" - filter-obj "^1.1.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" @@ -12041,16 +11884,6 @@ react-dom@^17.0.0: object-assign "^4.1.1" scheduler "^0.20.2" -react-form-validator-core@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/react-form-validator-core/-/react-form-validator-core-1.1.1.tgz#d084b94b9ef66bed3847fa8851b45cc2f8960a5c" - integrity sha512-5SG9pKrRptrhrt/dZg0bL28VvyGeuXftfhx6qwJLNdUqs2GgEnrV07BBtGpWyoBKXmO+fplD+O70DbI03CMqUQ== - dependencies: - create-react-context "^0.3.0" - promise-polyfill "8.1.0" - prop-types "^15.0.0" - react-lifecycles-compat "^3.0.2" - react-ga@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/react-ga/-/react-ga-3.3.0.tgz#c91f407198adcb3b49e2bc5c12b3fe460039b3ca" @@ -12092,19 +11925,6 @@ react-is@^17.0.1, react-is@^17.0.2: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-lifecycles-compat@^3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - -react-material-ui-form-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/react-material-ui-form-validator/-/react-material-ui-form-validator-3.0.0.tgz#9cc732147fab0062535d41a8b158537d6794e684" - integrity sha512-WoQvsGCV6cxxGlTvoKOZoLvWtg5KWMRVD9EFfMfJBYYUAZBOR9yXg1OSlu/MgOP7sPiiIUAwPLYVWIds7oLXKQ== - dependencies: - prop-types "^15.0.0" - react-form-validator-core "1.1.1" - react-query@^3.6.0: version "3.34.12" resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.34.12.tgz#dcaaf7b629f0868aae8afef9fb7692f6ea7643bf" @@ -14496,13 +14316,6 @@ walker@^1.0.7: dependencies: makeerror "1.0.12" -warning@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" - integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== - dependencies: - loose-envify "^1.0.0" - watchpack@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25"