Genogram sample in typescript issue

Hi, I am trying to use the genogram sample in typescript but I can’t get the same output.

layout.model
import * as go from ‘gojs’;

export class Layout extends go.LayeredDigraphLayout {
    spouseSpacing = 30;
    initializeOption = Layout.InitDepthFirstIn;

    /** @override */
    add(net, coll, nonmemberonly) {
        let multiSpousePeople = new go.Set();
        // consider all Nodes in the given collection
        let it = coll.iterator;
        while (it.next()) {
          let node = it.value;
          if (!(node instanceof go.Node)) continue;
          if (!node.isLayoutPositioned || !node.isVisible()) continue;
          if (nonmemberonly && node.containingGroup !== null) continue;
          // if it's an unmarried Node, or if it's a Link Label Node, create a LayoutVertex for it
          if (node.isLinkLabel) {
            // get marriage Link
            let link = node.labeledLink;
            let spouseA = link.fromNode;
            let spouseB = link.toNode;
            // create vertex representing both husband and wife
            let vertex = net.addNode(node);
            // now define the vertex size to be big enough to hold both spouses
            vertex.width = spouseA.actualBounds.width + this.spouseSpacing + spouseB.actualBounds.width;
            vertex.height = Math.max(spouseA.actualBounds.height, spouseB.actualBounds.height);
            vertex.focus = new go.Point(spouseA.actualBounds.width + this.spouseSpacing / 2, vertex.height / 2);
          } else {
            // don't add a vertex for any married person!
            // instead, code above adds label node for marriage link
            // assume a marriage Link has a label Node
            let marriages = 0;
            node.linksConnected.each((l) => { if (l.isLabeledLink) marriages++; });
            if (marriages === 0) {
              let vertex = net.addNode(node);
            } else if (marriages > 1) {
              multiSpousePeople.add(node);
            }
          }
        }
        // now do all Links
        it.reset();
        while (it.next()) {
          let link = it.value;
          if (!(link instanceof go.Link)) continue;
          if (!link.isLayoutPositioned || !link.isVisible()) continue;
          if (nonmemberonly && link.containingGroup !== null) continue;
          // if it's a parent-child link, add a LayoutEdge for it
          if (!link.isLabeledLink) {
            let parent = net.findVertex(link.fromNode);  // should be a label node
            let child = net.findVertex(link.toNode);
            if (child !== null) {  // an unmarried child
              net.linkVertexes(parent, child, link);
            } else {  // a married child
              link.toNode.linksConnected.each((l) => {
                if (!l.isLabeledLink) return;  // if it has no label node, it's a parent-child link
                // found the Marriage Link, now get its label Node
                let mlab = l.labelNodes.first();
                // parent-child link should connect with the label node,
                // so the LayoutEdge should connect with the LayoutVertex representing the label node
                let mlabvert = net.findVertex(mlab);
                if (mlabvert !== null) {
                  net.linkVertexes(parent, mlabvert, link);
                }
              });
            }
          }
        }
  
        while (multiSpousePeople.count > 0) {
          // find all collections of people that are indirectly married to each other
          let node = multiSpousePeople.first();
          let cohort = new go.Set();
          this.extendCohort(cohort, node);
          // then encourage them all to be the same generation by connecting them all with a common vertex
          let dummyvert = net.createVertex();
          net.addVertex(dummyvert);
          let marriages = new go.Set();
          cohort.each((n) => {
            n['linksConnected'].each((l) => {
              marriages.add(l);
            })
          });
          marriages.each((link) => {
            // find the vertex for the marriage link (i.e. for the label node)
            let mlab = link['labelNodes'].first()
            let v = net.findVertex(mlab);
            if (v !== null) {
              net.linkVertexes(dummyvert, v, null);
            }
          });
          // done with these people, now see if there are any other multiple-married people
          multiSpousePeople.removeAll(cohort);
        }
    };

    /** @override */
    assignLayers() {
        let horiz = this.direction == 0.0 || this.direction == 180.0;
        // for every vertex, record the maximum vertex width or height for the vertex's layer
        let maxsizes = [];
        this.network.vertexes.each((v) => {
          let lay = v['layer'];
          let max = maxsizes[lay];
          if (max === undefined) max = 0;
          let sz = (horiz ? v.width : v.height);
          if (sz > max) maxsizes[lay] = sz;
        });
        // now make sure every vertex has the maximum width or height according to which layer it is in,
        // and aligned on the left (if horizontal) or the top (if vertical)
        this.network.vertexes.each((v) => {
          let lay = v['layer'];
          let max = maxsizes[lay];
          if (horiz) {
            v.focus = new go.Point(0, v.height / 2);
            v.width = max;
          } else {
            v.focus = new go.Point(v.width / 2, 0);
            v.height = max;
          }
        });
        // from now on, the LayeredDigraphLayout will think that the Node is bigger than it really is
        // (other than the ones that are the widest or tallest in their respective layer).
    };  
    
    extendCohort(coll, node) {
        if (coll.contains(node)) return;
        coll.add(node);
        node.linksConnected.each((l) => {
          if (l.isLabeledLink) {  // if it's a marriage link, continue with both spouses
            this.extendCohort(coll, l.fromNode);
            this.extendCohort(coll, l.toNode);
          }
        });
    };
    
    /** @override */
    commitNodes() {
        // position regular nodes
        this.network.vertexes.each((v) => {
          if (v.node !== null && !v.node.isLinkLabel) {
            v.node.position = new go.Point(v.x, v.y);
          }
        });
        // position the spouses of each marriage vertex
        let layout = this;
        this.network.vertexes.each((v) => {
          if (v.node === null) return;
          if (!v.node.isLinkLabel) return;
          let labnode = v.node;
          let lablink = labnode.labeledLink;
          // In case the spouses are not actually moved, we need to have the marriage link
          // position the label node, because LayoutVertex.commit() was called above on these vertexes.
          // Alternatively we could override LayoutVetex.commit to be a no-op for label node vertexes.
          lablink.invalidateRoute();
          let spouseA = lablink.fromNode;
          let spouseB = lablink.toNode;
          // prefer fathers on the left, mothers on the right
          if (spouseA.data.s === "F") {  // sex is female
            let temp = spouseA;
            spouseA = spouseB;
            spouseB = temp;
          }
          // see if the parents are on the desired sides, to avoid a link crossing
          let aParentsNode = layout.findParentsMarriageLabelNode(spouseA);
          let bParentsNode = layout.findParentsMarriageLabelNode(spouseB);
          if (aParentsNode !== null && bParentsNode !== null && aParentsNode.position.x > bParentsNode.position.x) {
            // swap the spouses
            let temp = spouseA;
            spouseA = spouseB;
            spouseB = temp;
          }
          spouseA.position = new go.Point(v.x, v.y);
          spouseB.position = new go.Point(v.x + spouseA.actualBounds.width + layout.spouseSpacing, v.y);
          if (spouseA.opacity === 0) {
            let pos = new go.Point(v.centerX - spouseA.actualBounds.width / 2, v.y);
            spouseA.position = pos;
            spouseB.position = pos;
          } else if (spouseB.opacity === 0) {
            let pos = new go.Point(v.centerX - spouseB.actualBounds.width / 2, v.y);
            spouseA.position = pos;
            spouseB.position = pos;
          }
        });
        // position only-child nodes to be under the marriage label node
        this.network.vertexes.each((v) => {
          if (v.node === null || v.node.linksConnected.count > 1) return;
          let mnode = layout.findParentsMarriageLabelNode(v.node);
          if (mnode !== null && mnode.linksConnected.count === 1) {  // if only one child
            let mvert = layout.network.findVertex(mnode);
            let newbnds = v.node.actualBounds.copy();
            newbnds.x = mvert.centerX - v.node.actualBounds.width / 2;
            // see if there's any empty space at the horizontal mid-point in that layer
            let overlaps = layout.diagram.findObjectsIn(newbnds, (x) => { return x.part; }, (p) => { return p !== v.node; }, true);
            if (overlaps.count === 0) {
              v.node.move(newbnds.position);
            }
          }
        });
    };
  
    findParentsMarriageLabelNode(node) {
        let it = node.findNodesInto();
        while (it.next()) {
          let n = it.value;
          if (n.isLinkLabel) return n;
        }
        return null;
    };

    /** @override */
    makeNetwork(coll) {
        // generate LayoutEdges for each parent-child Link
        let net = this.createNetwork();
        if (coll instanceof go.Diagram) {
          this.add(net, coll.nodes, true);
          this.add(net, coll.links, true);
        } else if (coll instanceof go.Group) {
          this.add(net, coll.memberParts, false);
        } else if (coll.iterator) {
          this.add(net, coll.iterator, false);
        }
        return net;
      };
}

diagram.model

import * as go from 'gojs';

import { Layout } from './layout.model';

go.Diagram.inherit(Layout, go.LayeredDigraphLayout);

export class Diagram extends go.Diagram {
	goMake: any;

	// create and initialize the Diagram.model given an array of node data representing people
	init(array, focusId) {
		this.goMake = go.GraphObject.make;

		this.layout = this.goMake(Layout, { direction: 90, layerSpacing: 30, columnSpacing: 10 });

		this.initialAutoScale = go.Diagram.Uniform;
		this.initialContentAlignment= go.Spot.Center;
		this.undoManager.isEnabled = true;


		this.maleTemplate();
		this.femaleTemplate();
		this.linkLabel();
		this.marriage();
		this.parentChild();

		this.model =
		  go.GraphObject.make(go.GraphLinksModel,
			{ // declare support for link label nodes
			  linkLabelKeysProperty: "labelKeys",
			  // this property determines which template is used
			  nodeCategoryProperty: "s",
			  // create all of the nodes for people
			  nodeDataArray: array
			});
		this.setupMarriages(this);
		this.setupParents(this);
  
		var node = this.findNodeForKey(focusId);
		if (node !== null) {
		  this.select(node);
		  // remove any spouse for the person under focus:
		  //node.linksConnected.each(function(l) {
		  //  if (!l.isLabeledLink) return;
		  //  l.opacity = 0;
		  //  var spouse = l.getOtherNode(node);
		  //  spouse.opacity = 0;
		  //  spouse.pickable = false;
		  //});
		}
	}

	// two different node templates, one for each sex,
	// named by the category value in the node data object
	maleTemplate(){
		this.nodeTemplateMap.add("M",  // male
		this.goMake(go.Node, "Vertical",
		  { locationSpot: go.Spot.Center, locationObjectName: "ICON" },
		  this.goMake(go.Panel,
			{ name: "ICON" },
			this.goMake(go.Shape, "Square",
			  { width: 40, height: 40, strokeWidth: 2, fill: "white", portId: "" })
		  ),
		  this.goMake(go.TextBlock,
			{ textAlign: "center", maxSize: new go.Size(80, NaN) },
			new go.Binding("text", "n"))
		));
	}

	femaleTemplate(){
		this.nodeTemplateMap.add("F",  // female
        this.goMake(go.Node, "Vertical",
          { locationSpot: go.Spot.Center, locationObjectName: "ICON" },
          this.goMake(go.Panel,
            { name: "ICON" },
            this.goMake(go.Shape, "Circle",
              { width: 40, height: 40, strokeWidth: 2, fill: "white", portId: "" })
          ),
          this.goMake(go.TextBlock,
            { textAlign: "center", maxSize: new go.Size(80, NaN) },
            new go.Binding("text", "n"))
        ));
	}

	linkLabel(){
		// the representation of each label node -- nothing shows on a Marriage Link
		this.nodeTemplateMap.add("LinkLabel",
        this.goMake(go.Node, { selectable: false, width: 1, height: 1, fromEndSegmentLength: 20 }));
	}

	parentChild(){
		this.linkTemplate =  // for parent-child relationships
		this.goMake(go.Link,
		  {
			routing: go.Link.Orthogonal, curviness: 15,
			layerName: "Background", selectable: false,
			fromSpot: go.Spot.Bottom, toSpot: go.Spot.Top
		  },
		  this.goMake(go.Shape, { strokeWidth: 2 })
		);
	}


	marriage(){
		this.linkTemplateMap.add("Marriage",  // for marriage relationships
        this.goMake(go.Link,
          { selectable: false },
          this.goMake(go.Shape, { strokeWidth: 2, stroke: "blue" })
      ));
	}
	
	findMarriage(diagram, a, b) {  // A and B are node keys
		let nodeA = diagram.findNodeForKey(a);
		let nodeB = diagram.findNodeForKey(b);
		if (nodeA !== null && nodeB !== null) {
		  let it = nodeA.findLinksBetween(nodeB);  // in either direction
		  while (it.next()) {
			let link = it.value;
			// Link.data.category === "Marriage" means it's a marriage relationship
			if (link.data !== null && link.data.category === "Marriage") return link;
		  }
		}
		return null;
	}

    // now process the node data to determine marriages
    setupMarriages(diagram) {
		let model = diagram.model;
		let nodeDataArray = model.nodeDataArray;
		for (let i = 0; i < nodeDataArray.length; i++) {
		  let data = nodeDataArray[i];
		  let key = data.key;
		  let uxs = data.ux;
		  if (uxs !== undefined) {
			if (typeof uxs === "number") uxs = [ uxs ];
			for (let j = 0; j < uxs.length; j++) {
			  let wife = uxs[j];
			  if (key === wife) {
				// or warn no reflexive marriages
				continue;
			  }
			  let link = this.findMarriage(diagram, key, wife);
			  if (link === null) {
				// add a label node for the marriage link
				let mlab = { s: "LinkLabel" };
				model.addNodeData(mlab);
				// add the marriage link itself, also referring to the label node
				let mdata = { from: key, to: wife, labelKeys: [mlab['key']], category: "Marriage" };
				model.addLinkData(mdata);
			  }
			}
		  }
		  let virs = data.vir;
		  if (virs !== undefined) {
			if (typeof virs === "number") virs = [ virs ];
			for (let j = 0; j < virs.length; j++) {
			  let husband = virs[j];
			  if (key === husband) {
				// or warn no reflexive marriages
				continue;
			  }
			  let link = this.findMarriage(diagram, key, husband);
			  if (link === null) {
				// add a label node for the marriage link
				let mlab = { s: "LinkLabel" };
				model.addNodeData(mlab);
				// add the marriage link itself, also referring to the label node
				let mdata = { from: key, to: husband, labelKeys: [mlab['key']], category: "Marriage" };
				model.addLinkData(mdata);
			  }
			}
		  }
		}
	}
  
	setupParents(diagram) {
		let model = diagram.model;
		let nodeDataArray = model.nodeDataArray;
		for (let i = 0; i < nodeDataArray.length; i++) {
		  let data = nodeDataArray[i];
		  let key = data.key;
		  let mother = data.m;
		  let father = data.f;
		  if (mother !== undefined && father !== undefined) {
			let link = this.findMarriage(diagram, mother, father);
			if (link === null) {
			  // or warn no known mother or no known father or no known marriage between them
			  if (window.console) window.console.log("unknown marriage: " + mother + " & " + father);
			  continue;
			}
			let mdata = link.data;
			let mlabkey = mdata.labelKeys[0];
			let cdata = { from: mlabkey, to: key };
			this.model['addLinkData'](cdata);
		  }
		}
	}   
}

Can someone point me in the right direction?
Thanks.

Here you go: https://gojs.net/temp/genogramTS.zip

I compiled the TS files with:

tsc -t ES5 -m umd genogramLayout.ts
tsc -t ES5 -m umd genogramScript.ts

Perfect. Thank you