All nodes dynamic ports are synchronized

My result:
Add port to all nodes rather than the was selected node.
Do you know why?
My codes:

function addPort(side) {
myDiagram.startTransaction("addPort");
myDiagram.selection.each(function(node) {
  if (!(node instanceof go.Node)) return;
  var i = 0;
  while (node.findPort(side + i.toString()) !== node) i++;
  var text = side + i.toString();
  var arr = node.data[side + "Array"];
  if (arr) {
    var newportdata = {
      portId: text,
      portColor:"rgba(255,0,0,1)"
    };
    myDiagram.model.insertArrayItem(arr, -1, newportdata);
  }
});
myDiagram.commitTransaction("addPort");
}
myDiagram.nodeTemplate =
  g_(go.Node, "Table",
    { locationObjectName: "BODY",
      locationSpot: go.Spot.Center,
      selectionObjectName: "BODY"
    },
    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),

    // the body
    g_(go.Panel, "Auto",
      { row: 1, column: 1, name: "BODY",
        stretch: go.GraphObject.Fill },
      g_(go.Shape, "Rectangle",
        { fill: null, stroke: "rgba(255,0,0,1)", strokeWidth: 4,
          minSize: new go.Size(100, 100) }),
      g_(go.TextBlock,
        { margin: 10, textAlign: "center", 
        font: "bold 14px  Segoe UI,sans-serif",
        stroke: "black", editable: true },
        new go.Binding("text", "text").makeTwoWay())
    ),  // end Auto Panel body

    
    g_(go.Panel, "Vertical",
      new go.Binding("itemArray", "leftArray"),
      { row: 1, column: 0,
        itemTemplate:
          g_(go.Panel,"Spot",
            g_(go.Shape, "Rectangle",
              { 
                stroke: null, strokeWidth: 0,
                desiredSize: portSizeV,
                margin: new go.Margin(10,0),
                _side: "left", 
                fromSpot: go.Spot.Left, toSpot: go.Spot.Left,
                fromLinkable: true, toLinkable: true, cursor: "pointer" },
                new go.Binding("portId", "portId"),
                new go.Binding("fill", "portColor")),
            g_(go.TextBlock, "111",{
              _isNodeLabel: true,
              angle:0,
              font: "bold 10pt serif",
              alignment:new go.Spot(0,0,0,18)
            })
          )  // end itemTemplate
      }
    ),  // end Vertical(垂直) Panel

    
    g_(go.Panel, "Horizontal",
      new go.Binding("itemArray", "topArray"),
      { row: 0, column: 1,
        itemTemplate:
          g_(go.Panel,"Spot",
            g_(go.Shape, "Rectangle",
              { stroke: null, strokeWidth: 0,
                desiredSize: portSizeH,
                margin: new go.Margin(0, 10),
                _side: "top",
                fromSpot: go.Spot.Top, toSpot: go.Spot.Top,
                fromLinkable: true, toLinkable: true, cursor: "pointer" },
                new go.Binding("portId", "portId"),
                new go.Binding("fill", "portColor")),
            g_(go.TextBlock, "222",{
              editable: true,
              angle:0,
              font: "bold 10pt serif",
              alignment:new go.Spot(0,0,20,10)
            })
          )  // end itemTemplate
      }
    ),  // end Horizontal(水平) Panel

    
    g_(go.Panel, "Vertical",
      new go.Binding("itemArray", "rightArray"),
      { row: 1, column: 2,
        itemTemplate:
          g_(go.Panel,"Spot",
            g_(go.Shape, "Rectangle",
              { stroke: null, strokeWidth: 0,
                desiredSize: portSizeV,
                margin: new go.Margin(10, 0),
                _side: "right",
                portId:"",
                fromSpot: go.Spot.Right, toSpot: go.Spot.Right,
                fromLinkable: true, toLinkable: true, cursor: "pointer" },
                new go.Binding("portId", "portId"),
                new go.Binding("fill", "portColor")),
            g_(go.TextBlock, "333",{
              editable: true,
              angle:0,
              font: "bold 10pt serif",
              alignment:new go.Spot(0,0,12,18)
            })
          )  // end itemTemplate
      }
    ),  // end Vertical Panel

   
    g_(go.Panel, "Horizontal",
      new go.Binding("itemArray", "bottomArray"),
      { row: 2, column: 1,
        itemTemplate:
          g_(go.Panel,"Spot",
            g_(go.Shape, "Rectangle",
              { stroke: null, strokeWidth: 0,
                desiredSize: portSizeH,
                margin: new go.Margin(0, 10) ,
               _side: "bottom",
               portId:"",
               fromSpot: go.Spot.Bottom, toSpot: go.Spot.Bottom,
               fromLinkable: true, toLinkable: true, cursor: "pointer"},
              new go.Binding("portId", "portId"),
              new go.Binding("fill", "portColor")),
            g_(go.TextBlock, "444",{
              editable: true,
              angle:0,
              font: "bold 10pt serif",
              alignment:new go.Spot(0,0,20,10)
            })
          )  // end itemTemplate
      }
    )  // end Horizontal Panel
  );  // end Node

If you look carefully at the model in that sample (you can see it in the textarea at the bottom, showing the JSON-serialized model), you will see that it sets two Model properties:

Either setting those two properties or implementing your own custom node-copying function can make sure that the Arrays are not shared between nodes, but are copied.