import {
    Graph
} from '@antv/x6'

// transverse  vertical
//   横           纵

const weight = 3;
const fontsize = 12;
const nodeSize = {};
const blueIconWidth = 24;
const blueIconHeight = 18;

const registerRootNode = () => {
    const shapeName = "root-node";
    Graph.registerNode(shapeName, {
        width: 0,
        height: weight,
        markup: [{
                tagName: 'text',
                selector: 'label',
            },
            {
                tagName: 'rect',
                selector: 'line',
            },
        ],
        attrs: {
            label: {
                fill: '#D0D0D0',
                y: -fontsize,
                fontSize: fontsize,
            },
            line: {
                height: weight,
                stroke: "transparent",
            },
        },
    }, true);
}

// 断路器纵向断开
const registerCircuitBreakerVerticalBreak = () => {
    const width = 100;
    const height = 30;
    const shapeName = "circuit-breaker-vertical-break";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [{
                    tagName: 'text',
                    selector: 'label',
                },
                {
                    tagName: 'rect',
                    selector: 'line',
                },
            ],
            attrs: {
                label: {
                    fill: '#D0D0D0',
                    fontSize: fontsize,
                },
                line: {
                    width: weight,
                    height: height / 3,
                    x: -(weight / 2),
                    fill: "#b30461",
                    stroke: "transparent",
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        option.attrs.label.refX = -15;
        option.attrs.label['text-anchor'] = 'end';
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        option.attrs.label.refX = 15;
        option.attrs.label['text-anchor'] = 'start';
        return option;
    }
    const topOption = (option) => {
        option.attrs.label.refY = weight;
        option.attrs.line.y = height / 3 * 2;
    }
    const bottomOption = (option) => {
        option.attrs.label.refY = weight + height / 3;
        option.attrs.line.y = 0;
    }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 长断路器纵向断开
const registerLongCircuitBreakerVerticalBreak = () => {
    const width = 100;
    const height = 50;
    const shapeName = "long-circuit-breaker-vertical-break";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [{
                    tagName: 'text',
                    selector: 'label',
                },
                {
                    tagName: 'rect',
                    selector: 'line',
                },
            ],
            attrs: {
                label: {
                    fill: '#D0D0D0',
                    fontSize: fontsize,
                },
                line: {
                    width: weight,
                    height: height / 5 * 3,
                    x: -(weight / 2),
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        option.attrs.label.refX = -15;
        option.attrs.label['text-anchor'] = 'end';
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        option.attrs.label.refX = 15;
        option.attrs.label['text-anchor'] = 'start';
        return option;
    }
    const topOption = (option) => {
        option.attrs.label.refY = weight;
        option.attrs.line.y = height / 3 * 2;
    }
    const bottomOption = (option) => {
        option.attrs.label.refY = weight + height / 5 * 3;
        option.attrs.line.y = 0;
    }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 长断路器纵向连接
const registerLongCircuitBreakerVerticalLink = () => {
    const width = 100;
    const height = 50;
    const shapeName = "long-circuit-breaker-vertical-link";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [{
                    tagName: 'text',
                    selector: 'label',
                },
                {
                    tagName: 'rect',
                    selector: 'line',
                },
            ],
            attrs: {
                label: {
                    fill: '#D0D0D0',
                    fontSize: fontsize,
                },
                line: {
                    width: weight,
                    height: height,
                    x: -(weight / 2),
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        option.attrs.label.refX = -15;
        option.attrs.label['text-anchor'] = 'end';
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        option.attrs.label.refX = 15;
        option.attrs.label['text-anchor'] = 'start';
        return option;
    }
    const topOption = (option) => {
        option.attrs.label.refY = weight;
        option.attrs.line.y = height / 3 * 2;
    }
    const bottomOption = (option) => {
        option.attrs.label.refY = weight + height / 5 * 3;
        option.attrs.line.y = 0;
    }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 接地隔离开关横向断开
const registerEarthingDisconnectorTransverseBreak = () => {
    const width = 300;
    const height = 15;
    const shapeName = "earthing-disconnector-transverse-break";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [{
                    tagName: 'text',
                    selector: 'label',
                },
                {
                    tagName: 'rect',
                    selector: 'verticalLine',
                },
                {
                    tagName: 'rect',
                    selector: 'transverseLine',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineS',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineM',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineL',
                },
                {
                    tagName: 'rect',
                    selector: 'iconTransverseLine',
                },
            ],
            attrs: {
                label: {
                    fill: '#D0D0D0',
                    fontSize: fontsize,
                    "alignment-baseline": "middle"
                },
                verticalLine: {
                    width: weight,
                    height: height,
                    x: -(weight / 2),
                    y: 0,
                    fill: "#b30461",
                    stroke: "transparent",
                },
                transverseLine: {
                    width: height / 3 * 4,
                    height: weight,
                    fill: "#b30461",
                    stroke: "transparent",
                },
                iconVerticalLineS: {
                    width: weight,
                    height: blueIconHeight / 2,
                    y: blueIconHeight / 4,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconVerticalLineM: {
                    width: weight,
                    height: blueIconHeight / 3 * 2,
                    y: blueIconHeight / 6,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconVerticalLineL: {
                    width: weight,
                    height: blueIconHeight,
                    y: 0,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconTransverseLine: {
                    width: blueIconWidth - weight * 4,
                    height: weight,
                    y: (blueIconHeight - weight) / 2,
                    fill: "#2acabe",
                    stroke: "transparent",
                }
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        option.attrs.label.x = -(height * 6);
        option.attrs.label['text-anchor'] = 'end';
        option.attrs.transverseLine.x = -(height / 3 * 4);

        option.attrs.iconVerticalLineS.x = 0;
        option.attrs.iconVerticalLineM.x = weight / 2 * 3;
        option.attrs.iconVerticalLineL.x = weight * 3;
        option.attrs.iconTransverseLine.x = weight * 4;

        option.attrs.iconVerticalLineS.x -= height * 5;
        option.attrs.iconVerticalLineM.x -= height * 5;
        option.attrs.iconVerticalLineL.x -= height * 5;
        option.attrs.iconTransverseLine.x -= height * 5;
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        option.attrs.label.x = height * 6;
        option.attrs.label['text-anchor'] = 'start';
        option.attrs.transverseLine.x = 0;

        option.attrs.iconVerticalLineS.x = 0;
        option.attrs.iconVerticalLineM.x = -(weight / 2 * 3);
        option.attrs.iconVerticalLineL.x = -(weight * 3);
        option.attrs.iconTransverseLine.x = weight - blueIconWidth;

        option.attrs.iconVerticalLineS.x += height * 5;
        option.attrs.iconVerticalLineM.x += height * 5;
        option.attrs.iconVerticalLineL.x += height * 5;
        option.attrs.iconTransverseLine.x += height * 5;
        return option;
    }
    const topOption = (option) => {
        option.attrs.label.y = fontsize / 2;
        option.attrs.transverseLine.y = 0;
        option.attrs.iconVerticalLineS.y -= blueIconHeight / 2 - weight / 2;
        option.attrs.iconVerticalLineM.y -= blueIconHeight / 2 - weight / 2;
        option.attrs.iconVerticalLineL.y -= blueIconHeight / 2 - weight / 2;
        option.attrs.iconTransverseLine.y -= blueIconHeight / 2 - weight / 2;
    }
    const bottomOption = (option) => {
        option.attrs.label.y = height - weight + fontsize / 2;
        option.attrs.transverseLine.y = height - weight;
        option.attrs.iconVerticalLineS.y += height - weight / 2 - blueIconHeight / 2;
        option.attrs.iconVerticalLineM.y += height - weight / 2 - blueIconHeight / 2;
        option.attrs.iconVerticalLineL.y += height - weight / 2 - blueIconHeight / 2;
        option.attrs.iconTransverseLine.y += height - weight / 2 - blueIconHeight / 2;
    }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 接地隔离开关横向断开
const registerEarthingDisconnectorTransverseYBreak = () => {
    const width = 300;
    const height = 15;
    const shapeName = "earthing-disconnector-transverse-y-break";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [{
                    tagName: 'text',
                    selector: 'label',
                },
                {
                    tagName: 'rect',
                    selector: 'verticalLine',
                },
                {
                    tagName: 'rect',
                    selector: 'transverseLine',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineS',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineM',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineL',
                },
                {
                    tagName: 'rect',
                    selector: 'iconTransverseLine',
                },
            ],
            attrs: {
                label: {
                    fill: '#D0D0D0',
                    fontSize: fontsize,
                    "alignment-baseline": "middle"
                },
                verticalLine: {
                    width: weight,
                    height: height,
                    x: -(weight / 2),
                    y: 0,
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
                transverseLine: {
                    width: height / 3 * 4,
                    height: weight,
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
                iconVerticalLineS: {
                    width: weight,
                    height: blueIconHeight / 2,
                    y: blueIconHeight / 4,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconVerticalLineM: {
                    width: weight,
                    height: blueIconHeight / 3 * 2,
                    y: blueIconHeight / 6,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconVerticalLineL: {
                    width: weight,
                    height: blueIconHeight,
                    y: 0,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconTransverseLine: {
                    width: blueIconWidth - weight * 4,
                    height: weight,
                    y: (blueIconHeight - weight) / 2,
                    fill: "#2acabe",
                    stroke: "transparent",
                }
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        option.attrs.label.x = -(height * 6);
        option.attrs.label['text-anchor'] = 'end';
        option.attrs.transverseLine.x = -(height / 3 * 4);

        option.attrs.iconVerticalLineS.x = 0;
        option.attrs.iconVerticalLineM.x = weight / 2 * 3;
        option.attrs.iconVerticalLineL.x = weight * 3;
        option.attrs.iconTransverseLine.x = weight * 4;

        option.attrs.iconVerticalLineS.x -= height * 5;
        option.attrs.iconVerticalLineM.x -= height * 5;
        option.attrs.iconVerticalLineL.x -= height * 5;
        option.attrs.iconTransverseLine.x -= height * 5;
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        option.attrs.label.x = height * 6;
        option.attrs.label['text-anchor'] = 'start';
        option.attrs.transverseLine.x = 0;

        option.attrs.iconVerticalLineS.x = 0;
        option.attrs.iconVerticalLineM.x = -(weight / 2 * 3);
        option.attrs.iconVerticalLineL.x = -(weight * 3);
        option.attrs.iconTransverseLine.x = weight - blueIconWidth;

        option.attrs.iconVerticalLineS.x += height * 5;
        option.attrs.iconVerticalLineM.x += height * 5;
        option.attrs.iconVerticalLineL.x += height * 5;
        option.attrs.iconTransverseLine.x += height * 5;
        return option;
    }
    const topOption = (option) => {
        option.attrs.label.y = fontsize / 2;
        option.attrs.transverseLine.y = 0;
        option.attrs.iconVerticalLineS.y -= blueIconHeight / 2 - weight / 2;
        option.attrs.iconVerticalLineM.y -= blueIconHeight / 2 - weight / 2;
        option.attrs.iconVerticalLineL.y -= blueIconHeight / 2 - weight / 2;
        option.attrs.iconTransverseLine.y -= blueIconHeight / 2 - weight / 2;
    }
    const bottomOption = (option) => {
        option.attrs.label.y = height - weight + fontsize / 2;
        option.attrs.transverseLine.y = height - weight;
        option.attrs.iconVerticalLineS.y += height - weight / 2 - blueIconHeight / 2;
        option.attrs.iconVerticalLineM.y += height - weight / 2 - blueIconHeight / 2;
        option.attrs.iconVerticalLineL.y += height - weight / 2 - blueIconHeight / 2;
        option.attrs.iconTransverseLine.y += height - weight / 2 - blueIconHeight / 2;
    }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 接地隔离开关横向断开o
const registerEarthingDisconnectorTransverseYoBreak = () => {
    const width = 300;
    const height = 15;
    const shapeName = "earthing-disconnector-transverse-yo-break";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [{
                    tagName: 'text',
                    selector: 'label',
                },
                {
                    tagName: 'rect',
                    selector: 'verticalLine',
                },
                {
                    tagName: 'rect',
                    selector: 'transverseLine',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineS',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineM',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineL',
                },
                {
                    tagName: 'rect',
                    selector: 'iconTransverseLine',
                },
            ],
            attrs: {
                label: {
                    fill: '#D0D0D0',
                    fontSize: fontsize,
                    "alignment-baseline": "middle",
                    opacity: 0,
                },
                verticalLine: {
                    width: weight,
                    height: height,
                    x: -(weight / 2),
                    y: 0,
                    fill: "#cbaa07",
                    stroke: "transparent",
                    opacity: 0,
                },
                transverseLine: {
                    width: height / 3 * 4,
                    height: weight,
                    fill: "#cbaa07",
                    stroke: "transparent",
                    opacity: 0,
                },
                iconVerticalLineS: {
                    width: weight,
                    height: blueIconHeight / 2,
                    y: blueIconHeight / 4,
                    fill: "#2acabe",
                    stroke: "transparent",
                    opacity: 0,
                },
                iconVerticalLineM: {
                    width: weight,
                    height: blueIconHeight / 3 * 2,
                    y: blueIconHeight / 6,
                    fill: "#2acabe",
                    stroke: "transparent",
                    opacity: 0,
                },
                iconVerticalLineL: {
                    width: weight,
                    height: blueIconHeight,
                    y: 0,
                    fill: "#2acabe",
                    stroke: "transparent",
                    opacity: 0,
                },
                iconTransverseLine: {
                    width: blueIconWidth - weight * 4,
                    height: weight,
                    y: (blueIconHeight - weight) / 2,
                    fill: "#2acabe",
                    stroke: "transparent",
                    opacity: 0,
                }
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        option.attrs.label.x = -(height * 6);
        option.attrs.label['text-anchor'] = 'end';
        option.attrs.transverseLine.x = -(height / 3 * 4);

        option.attrs.iconVerticalLineS.x = 0;
        option.attrs.iconVerticalLineM.x = weight / 2 * 3;
        option.attrs.iconVerticalLineL.x = weight * 3;
        option.attrs.iconTransverseLine.x = weight * 4;

        option.attrs.iconVerticalLineS.x -= height * 5;
        option.attrs.iconVerticalLineM.x -= height * 5;
        option.attrs.iconVerticalLineL.x -= height * 5;
        option.attrs.iconTransverseLine.x -= height * 5;
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        option.attrs.label.x = height * 6;
        option.attrs.label['text-anchor'] = 'start';
        option.attrs.transverseLine.x = 0;

        option.attrs.iconVerticalLineS.x = 0;
        option.attrs.iconVerticalLineM.x = -(weight / 2 * 3);
        option.attrs.iconVerticalLineL.x = -(weight * 3);
        option.attrs.iconTransverseLine.x = weight - blueIconWidth;

        option.attrs.iconVerticalLineS.x += height * 5;
        option.attrs.iconVerticalLineM.x += height * 5;
        option.attrs.iconVerticalLineL.x += height * 5;
        option.attrs.iconTransverseLine.x += height * 5;
        return option;
    }
    const topOption = (option) => {
        option.attrs.label.y = fontsize / 2;
        option.attrs.transverseLine.y = 0;
        option.attrs.iconVerticalLineS.y -= blueIconHeight / 2 - weight / 2;
        option.attrs.iconVerticalLineM.y -= blueIconHeight / 2 - weight / 2;
        option.attrs.iconVerticalLineL.y -= blueIconHeight / 2 - weight / 2;
        option.attrs.iconTransverseLine.y -= blueIconHeight / 2 - weight / 2;
    }
    const bottomOption = (option) => {
        option.attrs.label.y = height - weight + fontsize / 2;
        option.attrs.transverseLine.y = height - weight;
        option.attrs.iconVerticalLineS.y += height - weight / 2 - blueIconHeight / 2;
        option.attrs.iconVerticalLineM.y += height - weight / 2 - blueIconHeight / 2;
        option.attrs.iconVerticalLineL.y += height - weight / 2 - blueIconHeight / 2;
        option.attrs.iconTransverseLine.y += height - weight / 2 - blueIconHeight / 2;
    }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 接地隔离开关横向断开2
const registerEarthingDisconnectorTransverse2Break = () => {
    const width = 300;
    const height = 0;
    const h = 15;
    const shapeName = "earthing-disconnector-transverse2-break";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [{
                    tagName: 'text',
                    selector: 'label',
                },
                {
                    tagName: 'rect',
                    selector: 'transverseLine',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineS',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineM',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineL',
                },
                {
                    tagName: 'rect',
                    selector: 'iconTransverseLine',
                },
            ],
            attrs: {
                label: {
                    fill: '#D0D0D0',
                    fontSize: fontsize,
                    "alignment-baseline": "middle"
                },
                transverseLine: {
                    width: h / 3 * 4,
                    height: weight,
                    y: -weight/2,
                    fill: "#b30461",
                    stroke: "transparent",
                },
                iconVerticalLineS: {
                    width: weight,
                    height: blueIconHeight / 2,
                    y: blueIconHeight / 4 - blueIconHeight / 2,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconVerticalLineM: {
                    width: weight,
                    height: blueIconHeight / 3 * 2,
                    y: blueIconHeight / 6 - blueIconHeight / 2,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconVerticalLineL: {
                    width: weight,
                    height: blueIconHeight,
                    y: 0 - blueIconHeight / 2,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconTransverseLine: {
                    width: blueIconWidth - weight * 4,
                    height: weight,
                    y: (blueIconHeight - weight) / 2 - blueIconHeight / 2,
                    fill: "#2acabe",
                    stroke: "transparent",
                }
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        option.attrs.label.x = -(h * 6);
        option.attrs.label['text-anchor'] = 'end';
        option.attrs.transverseLine.x = -(h / 3 * 4);

        option.attrs.iconVerticalLineS.x = 0;
        option.attrs.iconVerticalLineM.x = weight / 2 * 3;
        option.attrs.iconVerticalLineL.x = weight * 3;
        option.attrs.iconTransverseLine.x = weight * 4;

        option.attrs.iconVerticalLineS.x -= h * 5;
        option.attrs.iconVerticalLineM.x -= h * 5;
        option.attrs.iconVerticalLineL.x -= h * 5;
        option.attrs.iconTransverseLine.x -= h * 5;
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        option.attrs.label.x = h * 6;
        option.attrs.label['text-anchor'] = 'start';
        option.attrs.transverseLine.x = 0;

        option.attrs.iconVerticalLineS.x = 0;
        option.attrs.iconVerticalLineM.x = -(weight / 2 * 3);
        option.attrs.iconVerticalLineL.x = -(weight * 3);
        option.attrs.iconTransverseLine.x = weight - blueIconWidth;

        option.attrs.iconVerticalLineS.x += h * 5;
        option.attrs.iconVerticalLineM.x += h * 5;
        option.attrs.iconVerticalLineL.x += h * 5;
        option.attrs.iconTransverseLine.x += h * 5;
        return option;
    }
    const topOption = (option) => {
        option.attrs.label.y = fontsize / 2;
    }
    const bottomOption = (option) => {
        option.attrs.label.y = h - weight + fontsize / 2;
    }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 接地隔离开关纵向断开
const registerEarthingDisconnectorVerticalBreak = () => {
    const width = 300;
    const height = 20;
    const shapeName = "earthing-disconnector-vertical-break";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [{
                    tagName: 'text',
                    selector: 'label',
                },
                {
                    tagName: 'rect',
                    selector: 'verticalLine1',
                },
                {
                    tagName: 'rect',
                    selector: 'verticalLine',
                },
                {
                    tagName: 'rect',
                    selector: 'transverseLine',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineS',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineM',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineL',
                },
                {
                    tagName: 'rect',
                    selector: 'iconTransverseLine',
                },
            ],
            attrs: {
                label: {
                    fill: '#D0D0D0',
                    fontSize: fontsize,
                    y: height * 3 + fontsize + blueIconWidth + 9,
                    "alignment-baseline": "middle", 
                    "text-anchor": "middle",
                },
                verticalLine1: {
                    width: weight,
                    height: height,
                    x: -(weight / 2),
                    y: 0,
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
                verticalLine: {
                    width: weight,
                    height: height,
                    y: height,
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
                transverseLine: {
                    width: height,
                    height: weight,
                    y: height - weight,
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
                iconVerticalLineS: {
                    width: blueIconHeight / 2,
                    height: weight,
                    x: blueIconHeight / 4,
                    y: blueIconHeight + height * 3,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconVerticalLineM: {
                    width: blueIconHeight / 3 * 2,
                    height: weight,
                    x: blueIconHeight / 6,
                    y: blueIconHeight - weight / 2 * 3 + height * 3,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconVerticalLineL: {
                    width: blueIconHeight,
                    height: weight,
                    x: 0,
                    y: blueIconHeight - weight * 3 + height * 3,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconTransverseLine: {
                    width: weight,
                    height: blueIconWidth - weight * 4,
                    x: (blueIconHeight - weight) / 2,
                    y:  height * 3,
                    fill: "#2acabe",
                    stroke: "transparent",
                }
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        option.attrs.label.x = -height;
        option.attrs.transverseLine.x = -height;
        option.attrs.verticalLine.x = -height;
        option.attrs.iconVerticalLineS.x -= height / 2 * 3 - weight / 2;
        option.attrs.iconVerticalLineM.x -= height / 2 * 3 - weight / 2;
        option.attrs.iconVerticalLineL.x -= height / 2 * 3 - weight / 2;
        option.attrs.iconTransverseLine.x -= height / 2 * 3 - weight / 2;
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        option.attrs.label.x = height;
        option.attrs.transverseLine.x = 0;
        option.attrs.verticalLine.x = height - weight;
        option.attrs.iconVerticalLineS.x += height / 2 - weight / 2;
        option.attrs.iconVerticalLineM.x += height / 2 - weight / 2;
        option.attrs.iconVerticalLineL.x += height / 2 - weight / 2;
        option.attrs.iconTransverseLine.x += height / 2 - weight / 2;
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 注册上下箭头
const registerArrowVertical = () => {
    const width = weight;
    const height = 0;
    const arrowWidth = 13;
    const arrowHeight = 15;
    const shapeName = "arrow-vertical";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'rect',
                    selector: 'line',
                },
                {
                    tagName: 'polygon',
                    selector: 'arrow',
                },
            ],
            attrs: {
                line: {
                    width: weight,
                    x: -(weight / 2),
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
                arrow: {
                    x: -(weight / 2),
                    fill: "#cbaa07",
                    stroke: "transparent",
                }
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => {
        option.attrs.line.y = arrowHeight;
        option.attrs.arrow.refY = 0;
        option.attrs.arrow.points = `0,0 ${-(arrowWidth/2)},${arrowHeight} ${arrowWidth/2},${arrowHeight}`;
    }
    const bottomOption = (option) => {
        option.attrs.line.y = 0;
        option.attrs.arrow.points = `${-(arrowWidth/2)},0 ${arrowWidth/2},0 0,${arrowHeight}`;
    }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 注册一条竖线
const registerLineVertical = () => {
    const width = weight;
    const height = 0;
    const shapeName = "line-vertical";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'rect',
                    selector: 'line',
                },
            ],
            attrs: {
                line: {
                    width: weight,
                    x: -(weight / 2),
                    y: 0,
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 竖着的电抗器
const registerReactorVertical = () => {
    const width = weight;
    const height = 70;
    const r = 10;
    const shapeName = "reactor-vertical";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'reactor',
                },
            ],
            attrs: {
                reactor: {
                    d: `M0,0 l0,${height-r*2} a${r} ${r} 0 1 0 ${r} ${r} l-${r},0 l0,${r}`,
                    x: -(weight / 2),
                    y: 0,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": weight,
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 竖着的电容
const registerCapacitanceVertical = () => {
    const width = 16;
    const height = 50;
    const shapeName = "capacitance-vertical";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'reactor',
                },
            ],
            attrs: {
                reactor: {
                    d: `M0,0 l0,${height*0.4} m-${width/2},0 l${width},0 m0,${height*0.2-weight} l-${width},0 m${width/2},0 l0,${height*0.4+weight}`,
                    x: -(weight / 2),
                    y: 0,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": weight,
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 竖着的电阻
const registerResistanceVertical = () => {
    const width = 16;
    const height = 100;
    const shapeName = "resistance-vertical";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'reactor',
                },
            ],
            attrs: {
                reactor: {
                    d: `M0,0 l0,${height} m-${width/2},-${height*0.3} l${width},0 l0,-${height*0.4} l-${width},0 l0,${height*0.4}`,
                    x: -(weight / 2),
                    y: 0,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": weight,
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 电压互感器 3 Voltage transformer 
const registerVoltageTransformer = () => {
    const width = 16;
    const height = 50;
    const r = height / 5;
    const w = weight / 3 * 2;
    const shapeName = "voltage-transformer";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'rect',
                    selector: 'line',
                },
                {
                    tagName: 'circle',
                    selector: 'circle1',
                },
                {
                    tagName: 'circle',
                    selector: 'circle2',
                },
                {
                    tagName: 'circle',
                    selector: 'circle3',
                },
                {
                    tagName: 'path',
                    selector: 'path',
                },
            ],
            attrs: {
                line: {
                    x: -(weight / 2),
                    y: 0,
                    width: weight,
                    height: r + weight*2,
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
                circle1: {
                    cx: 0,
                    cy: 2*r+weight*2,
                    r: r,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": w,
                },
                circle2: {
                    cx: 0,
                    cy: 4*r,
                    r: r,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": w,
                },
                circle3: {
                    cx: Math.sqrt(weight*(2*r-weight)) + r - 3,
                    cy: 3*r+weight,
                    r: r,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": w,
                },
                path: {
                    d: `M0,${2*r+weight*2} l-${r/2},-${r/2} m${r/2},${r/2} l${r/2},-${r/2} m-${r/2},${r/2} l0,${r/2}
                        M0,${4*r} l-${r/2},-${r/2} m${r/2},${r/2} l${r/2},-${r/2} m-${r/2},${r/2} l0,${r/2}
                        M${Math.sqrt(weight*(2*r-weight))+r-3},${3*r+weight} m-1,0 l-${r/3},${r/3} l${r},0 l-${r/3},-${r/3}`,
                    x: -(weight / 2),
                    y: 0,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": w,
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 电压互感器3
const registerVoltage3Transformer = () => {
    const width = 50;
    const height = 0;
    const r = width / 5;
    const w = weight / 3 * 2;
    const shapeName = "voltage3-transformer";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'rect',
                    selector: 'line',
                },
                {
                    tagName: 'circle',
                    selector: 'circle1',
                },
                {
                    tagName: 'circle',
                    selector: 'circle2',
                },
                {
                    tagName: 'circle',
                    selector: 'circle3',
                },
                {
                    tagName: 'path',
                    selector: 'path',
                },
            ],
            attrs: {
                line: {
                    x: -width + weight,
                    y: -r*2,
                    width: weight,
                    height: r*2,
                    fill: "#b30461",
                    stroke: "transparent",
                },
                circle1: {
                    cx: -width + weight*3/2,
                    cy: -r*3,
                    r: r,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                circle2: {
                    cx: -width + weight*3/2 - Math.sqrt(weight*(r*2-weight)),
                    cy: -r*4 - (r - weight*2),
                    r: r,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                circle3: {
                    cx: -width + weight*3/2 + Math.sqrt(weight*(r*2-weight)),
                    cy: -r*4 - (r - weight*2),
                    r: r,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                path: {
                    d: `M${-width+weight*3/2},${-r*3} l-${r/2},${r/2} m${r/2},-${r/2} l${r/2},${r/2} m-${r/2},-${r/2} l0,-${r/2}
                        M${-width+weight*3/2-Math.sqrt(weight*(r*2-weight))},${-r*4-(r-weight*2)} l-${r/2},${r/2} m${r/2},-${r/2} l${r/2},${r/2} m-${r/2},-${r/2} l0,-${r/2}
                        M${-width+weight*3/2+Math.sqrt(weight*(r*2-weight))},${-r*4-(r-weight*2)} l-${r/2},${r/2} m${r/2},-${r/2} l${r/2},${r/2} m-${r/2},-${r/2} l0,-${r/2}`,
                    x: -(weight / 2),
                    y: 0,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 电压互感器5
const registerVoltage5Transformer = () => {
    const width = 50;
    const height = 0;
    const r = width / 5;
    const w = weight / 3 * 2;
    const shapeName = "voltage5-transformer";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'rect',
                    selector: 'line',
                },
                {
                    tagName: 'circle',
                    selector: 'circle1',
                },
                {
                    tagName: 'circle',
                    selector: 'circle2',
                },
                {
                    tagName: 'circle',
                    selector: 'circle3',
                },
                {
                    tagName: 'circle',
                    selector: 'circle4',
                },
                {
                    tagName: 'circle',
                    selector: 'circle5',
                },
                {
                    tagName: 'path',
                    selector: 'path',
                },
            ],
            attrs: {
                line: {
                    x: -width + weight,
                    y: 0,
                    width: weight,
                    height: r*2,
                    fill: "#b30461",
                    stroke: "transparent",
                },
                circle1: {
                    cx: -width + weight*3/2,
                    cy: r*3,
                    r: r,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                circle2: {
                    cx: -width + weight*3/2 - Math.sqrt(weight*(r*2-weight)),
                    cy: r*4 + (r - weight*2),
                    r: r,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                circle3: {
                    cx: -width + weight*3/2 + Math.sqrt(weight*(r*2-weight)),
                    cy: r*4 + (r - weight*2),
                    r: r,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                circle4: {
                    cx: -width + weight*3/2 - Math.sqrt(weight*(r*2-weight)),
                    cy: r*6 + (r - weight*3),
                    r: r,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                circle5: {
                    cx: -width + weight*3/2 + Math.sqrt(weight*(r*2-weight)),
                    cy: r*6 + (r - weight*3),
                    r: r,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                path: {
                    d: `M${-width+weight*3/2},${r*3} l-${r/2},-${r/2} m${r/2},${r/2} l${r/2},-${r/2} m-${r/2},${r/2} l0,${r/2}
                        M${-width+weight*3/2-Math.sqrt(weight*(r*2-weight))},${r*4+(r-weight*2)} m-2,-1 l${r/3},-${r/3} l0,${r-1} l-${r/3},-${r/3}
                        M${-width+weight*3/2+Math.sqrt(weight*(r*2-weight))},${r*4+(r-weight*2)} l-${r/2},-${r/2} m${r/2},${r/2} l${r/2},-${r/2} m-${r/2},${r/2} l0,${r/2}
                        M${-width+weight*3/2-Math.sqrt(weight*(r*2-weight))},${r*6+(r-weight*3)} l-${r/2},-${r/2} m${r/2},${r/2} l${r/2},-${r/2} m-${r/2},${r/2} l0,${r/2}
                        M${-width+weight*3/2+Math.sqrt(weight*(r*2-weight))},${r*6+(r-weight*3)} l-${r/2},-${r/2} m${r/2},${r/2} l${r/2},-${r/2} m-${r/2},${r/2} l0,${r/2}
                        M${-width+weight*3/2},${r*3} l-${r*4},0 l0,-${r*3}`,
                    x: -(weight / 2),
                    y: 0,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 接地变压器 Grounding transformer
const registerGroundingTransformer = () => {
    const width = 16;
    const height = 110;
    const r = height / 11;
    const w = weight / 3 * 2;
    const shapeName = "grounding-transformer";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'rect',
                    selector: 'line',
                },
                {
                    tagName: 'circle',
                    selector: 'circle1',
                },
                {
                    tagName: 'circle',
                    selector: 'circle2',
                },
                {
                    tagName: 'path',
                    selector: 'path',
                },
                {
                    tagName: 'rect',
                    selector: 'verticalLine',
                },
                {
                    tagName: 'rect',
                    selector: 'transverseLine',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineS',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineM',
                },
                {
                    tagName: 'rect',
                    selector: 'iconVerticalLineL',
                },
                {
                    tagName: 'rect',
                    selector: 'iconTransverseLine',
                },
            ],
            attrs: {
                line: {
                    x: -(weight / 2),
                    y: 0,
                    width: weight,
                    height: 7*r + weight*2,
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
                circle1: {
                    cx: 0,
                    cy: 8*r+weight*2,
                    r: r,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": w,
                },
                circle2: {
                    cx: 0,
                    cy: 10*r,
                    r: r,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": w,
                },
                path: {
                    d: `M0,${8*r+weight*2} m-${r/2},1 l${r},0 l-${r/2},-${r-2} l-${r/2},${r-2}
                        M0,${10*r} l-${r/2},${r/2} m${r/2},-${r/2} l${r/2},${r/2} m-${r/2},-${r/2} l0,-${r/2}`,
                    x: -(weight / 2),
                    y: 0,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": w,
                },
                verticalLine: {
                    width: weight,
                    height: r*2,
                    x: -r*2,
                    y: 10*r,
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
                transverseLine: {
                    width: r*2,
                    height: w,
                    x: -r*2,
                    y: 10*r,
                    fill: "#cbaa07",
                    stroke: "transparent",
                },
                iconVerticalLineS: {
                    width: blueIconHeight / 2,
                    height: weight,
                    x: blueIconHeight / 4 - r*2 - blueIconHeight / 2 + weight / 2,
                    y: blueIconHeight + r * 12,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconVerticalLineM: {
                    width: blueIconHeight / 3 * 2,
                    height: weight,
                    x: blueIconHeight / 6 - r*2 - blueIconHeight / 2 + weight / 2,
                    y: blueIconHeight - weight / 2 * 3 + r * 12,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconVerticalLineL: {
                    width: blueIconHeight,
                    height: weight,
                    x: 0 - r*2 - blueIconHeight / 2 + weight / 2,
                    y: blueIconHeight - weight * 3 + r * 12,
                    fill: "#2acabe",
                    stroke: "transparent",
                },
                iconTransverseLine: {
                    width: weight,
                    height: blueIconWidth - weight * 4,
                    x: (blueIconHeight - weight) / 2 - r*2 - blueIconHeight / 2 + weight / 2,
                    y:  r * 12,
                    fill: "#2acabe",
                    stroke: "transparent",
                }
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 横着的接地电容
const registerGroundingCapacitanceTransverse = () => {
    const width = 100;
    const height = 15;
    const ut = width * 0.20;
    const uv = width * 0.1;
    const shapeName = "grounding-capacitance-transverse";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'reactor',
                },
                {
                    tagName: 'path',
                    selector: 'icon',
                },
            ],
            attrs: {
                reactor: {
                    d: `M0,0 l0,-${height} l-${ut},0 m0,${ut/2} l0,-${ut} m-${uv-weight},0 l0,${ut} m0,-${ut/2} l-${ut*2},0
                                                    m0,${ut/2} l0,-${ut} m-${uv-weight},0 l0,${ut} m0,-${ut/2} l-${ut},0`,
                    x: -(weight / 2),
                    refY: height,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": weight,
                },
                icon: {
                    d: `M0,0 l-${blueIconWidth-weight*4},0 m0,${blueIconHeight/2} l0,-${blueIconHeight} m-${weight*1.5},${blueIconHeight/6} l0,${blueIconHeight/3*2} 
                                                           m0,${blueIconHeight/6} m-${weight*1.5},-${blueIconHeight/4} l0,-${blueIconHeight/2}`,
                    refX: -width + weight*2,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#2acabe",
                    "stroke-width": weight,
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => {
        option.attrs.reactor.transform = `scale(1, -1) translate(0, ${height})`;
        option.attrs.icon.refY = height;
    }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// ???
const registerGroundingResistanceVertical = () => {
    const width = 15;
    const height = 70;
    const arrowWidth = 13;
    const arrowHeight = 15;
    const shapeName = "grounding-resistance-vertical";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'reactor',
                },
                {
                    tagName: 'path',
                    selector: 'icon',
                },
                {
                    tagName: 'polygon',
                    selector: 'arrow',
                },
            ],
            attrs: {
                reactor: {
                    d: `M0,0 l0,${width} l0,${width} m0,-${width} l-${width/2},0 l0,40 l${width},0 l0,-40 l-${width/2},0`,
                    x: -(weight / 2),
                    refY: 0,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": weight,
                },
                icon: {
                    d: `M0,0 l-${blueIconWidth-weight*4},0 m0,${blueIconHeight/2} l0,-${blueIconHeight} m-${weight*1.5},${blueIconHeight/6} l0,${blueIconHeight/3*2} 
                                                           m0,${blueIconHeight/6} m-${weight*1.5},-${blueIconHeight/4} l0,-${blueIconHeight/2}`,
                    refX: -width + weight*2,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#2acabe",
                    "stroke-width": weight,
                    transform: `rotate(-90) translate(-${height-width+weight/2}, ${blueIconHeight/2})`
                },
                arrow: {
                    points: `${-(arrowWidth/2)},0 ${arrowWidth/2},0 0,${arrowHeight}`,
                    x: -(weight / 2),
                    refY: width*2,
                    fill: "#b30461",
                    stroke: "transparent",
                }
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// Three phase transformer
const registerThreePhaseTransformer = () => {
    const width = 16;
    const height = 50;
    const r = height / 5;
    const w = weight / 3 * 2;
    const shapeName = "three-phase-transformer";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'rect',
                    selector: 'line',
                },
                {
                    tagName: 'circle',
                    selector: 'circle1',
                },
                {
                    tagName: 'circle',
                    selector: 'circle2',
                },
                {
                    tagName: 'circle',
                    selector: 'circle3',
                },
                {
                    tagName: 'path',
                    selector: 'path',
                },
                {
                    tagName: 'path',
                    selector: 'path1',
                },
                {
                    tagName: 'path',
                    selector: 'path2',
                },
            ],
            attrs: {
                line: {
                    x: -(weight / 2),
                    y: 0,
                    width: weight,
                    height: r + weight*2,
                    fill: "#b30461",
                    stroke: "transparent",
                },
                circle1: {
                    cx: 0,
                    cy: 2*r+weight*2,
                    r: r,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                circle2: {
                    cx: 0,
                    cy: 4*r,
                    r: r,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": w,
                },
                circle3: {
                    cx: Math.sqrt(weight*(2*r-weight)) + r - 3,
                    cy: 3*r+weight,
                    r: r,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                path: {
                    d: `M0,${2*r+weight*2} l-${r/2},${r/2} m${r/2},-${r/2} l${r/2},${r/2} m-${r/2},-${r/2} l0,-${r/2}
                        M${Math.sqrt(weight*(2*r-weight))+r-3},${3*r+weight} m-1,-${r/2} l0,${r} l${r/2},-${r/2} l-${r/2},-${r/2}`,
                    x: -(weight / 2),
                    y: 0,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": w,
                },
                path1: {
                    d: `M0,${4*r} l-${r/2},${r/2} m${r/2},-${r/2} l${r/2},${r/2} m-${r/2},-${r/2} l0,-${r/2}`,
                    x: -(weight / 2),
                    y: 0,
                    fill: "transparent",
                    stroke: "#cbaa07",
                    "stroke-width": w,
                },
                path2: {
                    // d: `M-20,${2*r+weight*2+15} l56,-23 l${23/10},${56/10}`,
                    d: `M-20,${2*r+weight*2+15} l60,0 l0,5 l15,-5 l-15,-5 l0,5 z`,
                    x: -(weight / 2),
                    y: 0,
                    fill: "#b30461",
                    stroke: "#b30461",
                    "stroke-width": w,
                    transform: `rotate(-30) translate(-20, -10)`
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 主变压器
const registerMainTransformer = () => {
    const width = 66;
    const height = 0;
    const shapeName = "main-transformer";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'rect',
                    selector: 'line',
                },
            ],
            attrs: {
                line: {
                    x: -width - 10,
                    y: -40,
                    width: width,
                    height: weight,
                    fill: "#b30461",
                    stroke: "transparent",
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 主变压器1
const registerMainTransformer1 = () => {
    const width = 66;
    const height = 0;
    const shapeName = "main-transformer1";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'text',
                    selector: 'label',
                },
                {
                    tagName: 'path',
                    selector: 'path',
                },
                {
                    tagName: 'path',
                    selector: 'icon',
                },
            ],
            attrs: {
                label: {
                    x: -width - 25,
                    y: 0,
                    fill: '#D0D0D0',
                    fontSize: fontsize,
                    "text-anchor": "end",
                },
                path: {
                    d: `M0,0 l0,15`,
                    refX: -width - 10,
                    refY: -40,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": weight,
                },
                icon: {
                    d: `M0,0 l-${blueIconWidth-weight*4},0 m0,${blueIconHeight/2} l0,-${blueIconHeight} m-${weight*1.5},${blueIconHeight/6} l0,${blueIconHeight/3*2} 
                                                           m0,${blueIconHeight/6} m-${weight*1.5},-${blueIconHeight/4} l0,-${blueIconHeight/2}`,
                    refX: -width + weight*2,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#2acabe",
                    "stroke-width": weight,
                    transform: `rotate(-90) translate(-16.5,-16)`
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 主变压器2
const registerMainTransformer2 = () => {
    const width = 15;
    const height = 0;
    const h = 7;
    const arrowWidth = 13;
    const arrowHeight = 15;
    const shapeName = "main-transformer2";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'reactor',
                },
                {
                    tagName: 'path',
                    selector: 'icon',
                },
                {
                    tagName: 'polygon',
                    selector: 'arrow',
                },
            ],
            attrs: {
                reactor: {
                    d: `M0,0 l0,${width} l0,${width} m0,-${width} l-${width/2},0 l0,40 l${width},0 l0,-40 l-${width/2},0`,
                    refX: -50,
                    refY: -40,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": weight,
                },
                icon: {
                    d: `M0,0 l-${blueIconWidth-weight*4},0 m0,${blueIconHeight/2} l0,-${blueIconHeight} m-${weight*1.5},${blueIconHeight/6} l0,${blueIconHeight/3*2} 
                                                           m0,${blueIconHeight/6} m-${weight*1.5},-${blueIconHeight/4} l0,-${blueIconHeight/2}`,
                    refX: -50,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#2acabe",
                    "stroke-width": weight,
                    transform: `rotate(-90) translate(-16.5,0)`
                },
                arrow: {
                    points: `${-(arrowWidth/2)},0 ${arrowWidth/2},0 0,${arrowHeight}`,
                    refX: -50,
                    refY: -10,
                    fill: "#b30461",
                    stroke: "transparent",
                }
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 主变压器3
const registerMainTransformer3 = () => {
    const width = 15;
    const height = 0;
    const h = 7;
    const arrowWidth = 13;
    const arrowHeight = 15;
    const shapeName = "main-transformer3";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'text',
                    selector: 'label',
                },
                {
                    tagName: 'path',
                    selector: 'reactor',
                },
                {
                    tagName: 'path',
                    selector: 'icon',
                },
                {
                    tagName: 'polygon',
                    selector: 'arrow',
                },
                {
                    tagName: 'polygon',
                    selector: 'arrow1',
                },
            ],
            attrs: {
                label: {
                    x: -25,
                    y: 55,
                    fill: '#D0D0D0',
                    fontSize: fontsize,
                    "text-anchor": "middle",
                },
                reactor: {
                    d: `M0,0 l0,${width}`,
                    refX: -25,
                    refY: -40,
                    fill: "transparent",
                    stroke: "#b30461",
                    "stroke-width": weight,
                },
                icon: {
                    d: `M0,0 l-${blueIconWidth-weight*4},0 m0,${blueIconHeight/2} l0,-${blueIconHeight} m-${weight*1.5},${blueIconHeight/6} l0,${blueIconHeight/3*2} 
                                                           m0,${blueIconHeight/6} m-${weight*1.5},-${blueIconHeight/4} l0,-${blueIconHeight/2}`,
                    refX: -25,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#2acabe",
                    "stroke-width": weight,
                    transform: `rotate(-90) translate(-16.5,0)`
                },
                arrow: {
                    points: `${-(arrowWidth/2)},0 ${arrowWidth/2},0 0,${arrowHeight}`,
                    refX: -25,
                    refY: -25,
                    fill: "#b30461",
                    stroke: "transparent",
                },
                arrow1: {
                    points: `0,0 ${-(arrowWidth/2)},${arrowHeight} ${arrowWidth/2},${arrowHeight}`,
                    refX: -25,
                    refY: 5,
                    fill: "#b30461",
                    stroke: "transparent",
                },
            },
        }
    }
    const leftOption = () => {
        const option = commonOption();
        return option;
    }
    const rightOption = () => {
        const option = commonOption();
        return option;
    }
    const topOption = (option) => { }
    const bottomOption = (option) => { }
    const registerTopLeft = () => {
        const shape = `${shapeName}-top-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerTopRight = () => {
        const shape = `${shapeName}-top-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        topOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomLeft = () => {
        const shape = `${shapeName}-bottom-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = leftOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    const registerBottomRight = () => {
        const shape = `${shapeName}-bottom-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = rightOption();
        bottomOption(option);
        Graph.registerNode(shape, option, true);
    }
    registerTopLeft();
    registerTopRight();
    registerBottomLeft();
    registerBottomRight();
}

// 开关断开
const registerSwitchBreak = () => {
    const width = 0;
    const height = 0;
    const shapeName = "switch-break";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'path',
                },
            ],
            attrs: {
                path: {
                    d: `M1,6 a3 3 0 1 0 -2 0 M0,6 l-5,15 m0,5 l10,0`,
                    refX: 0,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#04a635",
                    "stroke-width": 2,
                },
            },
        }
    }
    const registerTop = () => {
        const shape = `${shapeName}-top`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        option.attrs.path.transform = `rotate(180)`; // `rotate(-90) translate(-16.5,0)`;
        Graph.registerNode(shape, option, true);
    }
    const registerBottom = () => {
        const shape = `${shapeName}-bottom`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerLeft = () => {
        const shape = `${shapeName}-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        option.attrs.path.transform = `rotate(90)`; // `rotate(-90) translate(-16.5,0)`;
        Graph.registerNode(shape, option, true);
    }
    const registerRight = () => {
        const shape = `${shapeName}-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        option.attrs.path.transform = `rotate(-90)`; // `rotate(-90) translate(-16.5,0)`;
        Graph.registerNode(shape, option, true);
    }
    registerTop();
    registerBottom();
    registerLeft();
    registerRight();
}

// 开关闭合
const registerSwitchClose = () => {
    const width = 0;
    const height = 0;
    const shapeName = "switch-close";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'path',
                },
            ],
            attrs: {
                path: {
                    d: `M1,6 a3 3 0 1 0 -2 0 M0,6 l0,20 m-5,0 l10,0`,
                    refX: 0,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#b30303",
                    "stroke-width": 2,
                },
            },
        }
    }
    const registerTop = () => {
        const shape = `${shapeName}-top`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        option.attrs.path.transform = `rotate(180)`; // `rotate(-90) translate(-16.5,0)`;
        Graph.registerNode(shape, option, true);
    }
    const registerBottom = () => {
        const shape = `${shapeName}-bottom`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerLeft = () => {
        const shape = `${shapeName}-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        option.attrs.path.transform = `rotate(90)`; // `rotate(-90) translate(-16.5,0)`;
        Graph.registerNode(shape, option, true);
    }
    const registerRight = () => {
        const shape = `${shapeName}-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        option.attrs.path.transform = `rotate(-90)`; // `rotate(-90) translate(-16.5,0)`;
        Graph.registerNode(shape, option, true);
    }
    registerTop();
    registerBottom();
    registerLeft();
    registerRight();
}

// 手车00
const registerHandcart00 = () => {
    const width = 0;
    const height = 0;
    const shapeName = "handcart00";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'path',
                },
                {
                    tagName: 'rect',
                    selector: 'rect',
                },
            ],
            attrs: {
                path: {
                    d: `M0,0 l-8,8 m8,-8 l8,8 m-8,-2 l-8,8 m8,-8 l8,8
                        M0,60 l-8,-8 m8,8 l8,-8 m-8,2 l-8,-8 m8,8 l8,-8`,
                    refX: 0,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#04a635",
                    "stroke-width": 2,
                },
                rect: {
                    x: -8,
                    y: 18,
                    width: 16,
                    height: 24,
                    fill: "#04a635",
                    stroke: "transparent",
                },
            },
        }
    }
    const registerTop = () => {
        const shape = `${shapeName}-top`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerBottom = () => {
        const shape = `${shapeName}-bottom`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerLeft = () => {
        const shape = `${shapeName}-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerRight = () => {
        const shape = `${shapeName}-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    registerTop();
    registerBottom();
    registerLeft();
    registerRight();
}

// 手车01
const registerHandcart01 = () => {
    const width = 0;
    const height = 0;
    const shapeName = "handcart01";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'path',
                },
                {
                    tagName: 'rect',
                    selector: 'rect',
                },
            ],
            attrs: {
                path: {
                    d: `M0,0 l-8,8 m8,-8 l8,8 m-8,-2 l-8,8 m8,-8 l8,8
                        M0,60 l-8,-8 m8,8 l8,-8 m-8,2 l-8,-8 m8,8 l8,-8`,
                    refX: 0,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#04a635",
                    "stroke-width": 2,
                },
                rect: {
                    x: -8,
                    y: 18,
                    width: 16,
                    height: 24,
                    fill: "#b30303",
                    stroke: "transparent",
                },
            },
        }
    }
    const registerTop = () => {
        const shape = `${shapeName}-top`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerBottom = () => {
        const shape = `${shapeName}-bottom`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerLeft = () => {
        const shape = `${shapeName}-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerRight = () => {
        const shape = `${shapeName}-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    registerTop();
    registerBottom();
    registerLeft();
    registerRight();
}

// 手车10
const registerHandcart10 = () => {
    const width = 0;
    const height = 0;
    const shapeName = "handcart10";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'path',
                },
                {
                    tagName: 'rect',
                    selector: 'rect',
                },
            ],
            attrs: {
                path: {
                    d: `M0,0 l-8,8 m8,-8 l8,8 m-8,-2 l-8,8 m8,-8 l8,8
                        M0,60 l-8,-8 m8,8 l8,-8 m-8,2 l-8,-8 m8,8 l8,-8`,
                    refX: 0,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#b30303",
                    "stroke-width": 2,
                },
                rect: {
                    x: -8,
                    y: 18,
                    width: 16,
                    height: 24,
                    fill: "#04a635",
                    stroke: "transparent",
                },
            },
        }
    }
    const registerTop = () => {
        const shape = `${shapeName}-top`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerBottom = () => {
        const shape = `${shapeName}-bottom`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerLeft = () => {
        const shape = `${shapeName}-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerRight = () => {
        const shape = `${shapeName}-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    registerTop();
    registerBottom();
    registerLeft();
    registerRight();
}

// 手车11
const registerHandcart11 = () => {
    const width = 0;
    const height = 0;
    const shapeName = "handcart11";
    const commonOption = () => {
        return {
            width: width,
            height: height,
            markup: [
                {
                    tagName: 'path',
                    selector: 'path',
                },
                {
                    tagName: 'rect',
                    selector: 'rect',
                },
            ],
            attrs: {
                path: {
                    d: `M0,0 l-8,8 m8,-8 l8,8 m-8,-2 l-8,8 m8,-8 l8,8
                        M0,60 l-8,-8 m8,8 l8,-8 m-8,2 l-8,-8 m8,8 l8,-8`,
                    refX: 0,
                    refY: 0,
                    fill: "transparent",
                    stroke: "#b30303",
                    "stroke-width": 2,
                },
                rect: {
                    x: -8,
                    y: 18,
                    width: 16,
                    height: 24,
                    fill: "#b30303",
                    stroke: "transparent",
                },
            },
        }
    }
    const registerTop = () => {
        const shape = `${shapeName}-top`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerBottom = () => {
        const shape = `${shapeName}-bottom`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerLeft = () => {
        const shape = `${shapeName}-left`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    const registerRight = () => {
        const shape = `${shapeName}-right`;
        nodeSize[shape] = {
            width: width,
            height: height
        };
        const option = commonOption();
        Graph.registerNode(shape, option, true);
    }
    registerTop();
    registerBottom();
    registerLeft();
    registerRight();
}

// 注册自定义节点
const register = () => {
    registerRootNode();
    registerCircuitBreakerVerticalBreak();
    registerLongCircuitBreakerVerticalBreak();
    registerLongCircuitBreakerVerticalLink();
    registerEarthingDisconnectorTransverseBreak();
    registerEarthingDisconnectorTransverse2Break();
    registerEarthingDisconnectorVerticalBreak();
    registerArrowVertical();
    registerLineVertical();
    registerReactorVertical();
    registerCapacitanceVertical();
    registerResistanceVertical();
    registerVoltageTransformer();
    registerGroundingTransformer();
    registerGroundingCapacitanceTransverse();
    registerVoltage3Transformer();
    registerVoltage5Transformer();
    registerGroundingResistanceVertical();
    registerThreePhaseTransformer();
    registerEarthingDisconnectorTransverseYBreak();
    registerMainTransformer();
    registerMainTransformer1();
    registerMainTransformer2();
    registerMainTransformer3();
    registerSwitchBreak();
    registerSwitchClose();
    registerHandcart00();
    registerHandcart01();
    registerHandcart10();
    registerHandcart11();
    registerEarthingDisconnectorTransverseYoBreak();
}


export default {
    register: register,
    nodeSize: nodeSize,
    weight: weight,
    fontsize: fontsize,
}