Function to initialize the MaterialX node editor. 
  155                      {
  156    let my_icon_map = {
  157        "_default_": "./Icons/materialx_logo.webp",
  158        "_default_graph_": "./Icons/nodegraph_white.svg"
  159    };
  160 
  161    let geometryValues = ['teapot', 'shaderball', 'sphere', 'plane', 'cube', 'cylinder', 'donut', 'twist', '_loadFromFile_']
  162 
  163    if (user_icon_map) {
  164        
  165        for (var key in user_icon_map) {
  166            my_icon_map[key] = user_icon_map[key];
  167        }
  168    }
  169 
  170    
  171    function uriExists(uri) {
  172        return fetch(uri)
  173            .then(response => {
  174                if (response.ok) {
  175                    return Promise.resolve(true);
  176                } else {
  177                    return Promise.resolve(false);
  178                }
  179            })
  180            .catch(error => {
  181                console.log('Error checking URI:', error);
  182                return Promise.resolve(false);
  183            });
  184    }
  185 
  186    
  187    function renderableItemUpdater(renderableItems) {
  188        let renderableItemSelect = document.getElementById('renderableItem');
  189        if (renderableItemSelect) {
  190 
  191            const TRUNCATION_LENGTH = 12;
  192 
  193            while (renderableItemSelect.firstChild) {
  194                renderableItemSelect.removeChild(renderableItemSelect.firstChild);
  195            }
  196            for (let i = 0; i < renderableItems.length; i++) {
  197                let item = renderableItems[i];
  198                let option = document.createElement('option');
  199                option.value = item;
  200                let uiItem = item;
  201                
  202                if (uiItem.length > 20)
  203                    uiItem = uiItem.substring(0, 20) + '...';
  204                option.text = uiItem;
  205                renderableItemSelect.appendChild(option);
  206            }
  207        }
  208    }
  209 
  210    
  211    
  212    function consoleLog(text, severity, clear = null) {
  213        if (severity === 2) {
  214            text = '> Error: ' + text
  215        }
  216        else if (severity === 1) {
  217            text = '> Warning: ' + text
  218        }
  219        else {
  220            if (text.length)
  221                text = '> ' + text;
  222        }
  223 
  224        let console_area = document.getElementById('console_area');
  225        if (console_area) {
  226            if (clear) {
  227                console_area.value = text + '\n';
  228            }
  229            else {
  230                console_area.value = console_area.value + text + '\n';
  231            }
  232            
  233            console_area.scrollTop = console_area.scrollHeight;
  234        }
  235        else {
  236            console.log(text);
  237        }
  238    }
  239 
  240    
  241
  242
  243
  244
  245
  246
  247
  248
  249
  250
  251
  252
  253
  254 
  255 
  261 
  262    function createMenuItem(text, filename) {
  263        let menuItem = document.createElement('li');
  264        menuItem.className = 'dropdown-item';
  265        menuItem.innerText = text;
  266        menuItem.onclick = function () {
  267            console.log('Load library file:', filename);
  269            
  270            let dropdownMenu = document.getElementById('libraryDropdown');
  271            dropdownMenu.classList.remove('show');
  272        };
  273        return menuItem;
  274    }
  275 
  281 
  282    function createSubMenu(title, auto_close = false) {
  283 
  284        let li = document.createElement('li');
  285        li.className = "dropend dropdown";
  286        li.id = key;
  287 
  288        let subMenu = document.createElement('a');
  289        subMenu.className = "dropdown-item dropdown-toggle";
  290        subMenu.setAttribute('data-bs-toggle', "dropdown");
  291        if (auto_close) {
  292            subMenu.setAttribute('data-bs-auto-close', 'outside');
  293        }
  294        subMenu.setAttribute('aria-expanded', 'false');
  295        subMenu.setAttribute('aria-haspopup', 'true');
  296        subMenu.innerHTML = title;
  297        li.appendChild(subMenu);
  298 
  299        return li;
  300    }
  301 
  307 
  308    function createLibraryMenu(sampleFiles, libraryDropdown) {
  309        for (let key in sampleFiles) {
  310            
  311            let li = createSubMenu(key, true);
  312            libraryDropdown.appendChild(li);
  313 
  314            let value = sampleFiles[key];
  315 
  316            
  317            if (typeof value === 'string') {
  318                let value = sampleFiles[key];
  319                li.appendChild(createMenuItem(key, value));
  320            }
  321            else if (typeof value === 'object') {
  322 
  323                let subMenuList = document.createElement('ul');
  324                subMenuList.className = 'dropdown-menu';
  325                subMenuList.id = key;
  326 
  327                for (key in value) {
  328 
  329                    
  330                    if (typeof value[key] === 'string') {
  331                        subMenuList.appendChild(createMenuItem(key, value[key]));
  332                    }
  333 
  334                    else if (typeof value[key] === 'object') {
  335 
  336                        
  337                        let sli = createSubMenu(key, false);
  338                        subMenuList.appendChild(sli);
  339 
  340                        let ssubMenuList = document.createElement('ul');
  341                        ssubMenuList.className = 'dropdown-menu';
  342                        for (let skey in value[key]) {
  343                            ssubMenuList.appendChild(createMenuItem(skey, (value[key])[skey]));
  344                        }
  345                        sli.appendChild(ssubMenuList);
  346                    }
  347                }
  348 
  349                li.appendChild(subMenuList);
  350            }
  351 
  352        }
  353    }
  354 
  355    
  356    if (sampleFiles && libraryDropdown) {
  357        createLibraryMenu(sampleFiles, libraryDropdown);
  358    }
  359 
  360    
  361    let selectGeometryUI = false;
  362    if (customRenderer) {
  363 
  364        let geometryURL = geometryId;
  365        if (geometryId.length > 0 && geometryValues.includes(geometryId)) {
  366            geometryURL = 'Geometry/' + geometryId + '.glb';
  367            selectGeometryUI = true;
  368        }
  369        var viewer = customRenderer.initialize(materialFilename, geometryURL, readOnly);
  370        console.log('Setup renderer:', viewer);
  371    }
  372    else {
  373        let preview_panel = document.getElementById("preview_panel");
  374        
  375        if (preview_panel)
  376            preview_panel.style.display = 'none';
  377    }
  378 
  379    
  384 
  385    function displayNodeTypes(nodeTypes) {
  386        
  387        var nodeList = document.getElementById('nodeTypesList');
  388        if (!nodeList) {
  389            return;
  390        }
  391 
  392        
  393        while (nodeList.firstChild) {
  394            nodeList.removeChild(nodeList.firstChild);
  395        }
  396 
  397        
  398        for (var typeName in nodeTypes) {
  399 
  400            var rowItem = document.createElement("tr");
  401 
  402            var cellItem = document.createElement("td");
  403            cellItem.textContent = typeName;
  404            rowItem.appendChild(cellItem);
  405 
  406            cellItem = document.createElement("td");
  407            var nodeDefString = '<None>';
  408            var nodeDefName = nodeTypes[typeName].nodedef_name;
  409            var nodeDefNode = nodeTypes[typeName].nodedef_node
  410            var nodeDefHref = nodeTypes[typeName].nodedef_href;
  411            if (nodeDefName) {
  412                if (nodeDefNode) {
  413                    var link = document.createElement("a");
  414                    link.target = "_blank";
  415                    link.href = nodeDefHref;
  416                    link.textContent = nodeDefNode + " ( " + nodeDefName + " )";
  417                    cellItem.appendChild(link);
  418                }
  419                else {
  420                    cellItem.textContent = nodeDefName;
  421                }
  422            }
  423            else {
  424                cellItem.textContent = nodeDefString;
  425            }
  426            rowItem.appendChild(cellItem);
  427 
  428            nodeList.appendChild(rowItem);
  429        }
  430    }
  431 
  432    
  433    var cmeditor = setupXMLSyntax();
  434    var cmeditor2 = setupJavascriptSyntax();
  435    var cmeditor3 = setupGLTFSyntax();
  436 
  441 
  442    function docDisplayUpdater(contents) {
  443        if (cmeditor)
  444            cmeditor.setValue(contents);
  445    }
  446 
  451 
  452    function gltfDisplayUpdater(contents) {
  453        if (!contents || contents.length == 0) {
  454            contents = '{}';
  455        }
  456        if (cmeditor3)
  457            cmeditor3.setValue(contents);
  458        else
  459            console.log(contents);
  460    }
  461 
  466 
  467    function jsDefinitionsDisplayUpdater(contents) {
  468        if (cmeditor2)
  469            cmeditor2.setValue(contents);
  470    }
  471 
  472    
  473    var canvas = document.getElementById('mygraphcanvas');
  474    var ui = {
  475        consoleLogger: consoleLog,
  476        nodeTypesListUpdater: displayNodeTypes,
  477        renderableItemUpdater: renderableItemUpdater,
  478        documentDisplayUpdater: docDisplayUpdater,
  479        gltfDocumentDisplayUpdater: gltfDisplayUpdater,
  480        definitionsDisplayUpdater: jsDefinitionsDisplayUpdater,
  481        propertypanel_content: document.getElementById('propertypanel_content'),
  482        propertypanel_icon: document.getElementById('propertypanel_icon'),
  483        icon_map: my_icon_map,
  484    };
  486 
  488    monitor.setRenderer(customRenderer);
  489    editor.initialize(canvas, ui, monitor, materialFilename, readOnly);
  490 
  494 
  495    function addUIHandlers() {
  496        
  497        var saveCanvasButton = document.getElementById('captureGraph');
  498        if (saveCanvasButton) {
  499            saveCanvasButton.addEventListener('click', function () {
  500                var canvas = document.getElementById('mygraphcanvas');
  501                var dataURL = canvas.toDataURL('image/png');
  502                var link = document.createElement('a');
  503                link.href = dataURL;
  504                link.download = 'graph_capture.png';
  505                link.click();
  506            });
  507        }
  508 
  509        
  510        var auto_arrange_size = 80;
  511 
  512        
  513        var loadMaterialXDocumentFromFile = document.getElementById('loadMaterialXDocumentFromFile');
  514        if (loadMaterialXDocumentFromFile) {
  515            loadMaterialXDocumentFromFile.addEventListener('click', function () {
  516                editor.loadGraphFromFile('mtlx', auto_arrange_size, true);
  517                
  518            });
  519        }
  520 
  521        
  522        var loadMaterialXDocumentFromZip = document.getElementById('loadMaterialXDocumentFromZip');
  523        if (loadMaterialXDocumentFromZip) {
  524            loadMaterialXDocumentFromZip.addEventListener('click', function () {
  525                editor.loadGraphFromFile('zip', auto_arrange_size, true);
  526                
  527            });
  528        }
  529       
  530        
  531        var texAreaNumber = 0;
  532        var loadMaterialXDocumentFromText = document.getElementById('loadMaterialXDocumentFromText');
  533        if (loadMaterialXDocumentFromText) {
  534            loadMaterialXDocumentFromText.addEventListener('click', function () {
  535                var mtlxdoc = document.getElementById('mtlxdoc').value;
  536                
  537                if (mtlxdoc.length > 0) {
  538                    var name = 'MaterialXGraph' + texAreaNumber++;
  539                    editor.loadGraphFromString('mtlx', mtlxdoc, name, auto_arrange_size, true);
  540                    
  541                }
  542            });
  543        }
  544 
  545        
  546        var loadMaterialXDefinitions = document.getElementById('loadMaterialXDefinitions');
  547        if (loadMaterialXDefinitions) {
  548            loadMaterialXDefinitions.addEventListener('click', function () {
  549                editor.loadDefinitionsFromFile('mtlx');
  550            });
  551        }
  552 
  553        
  554        var clearGraphButton = document.getElementById('clearGraph');
  555        if (clearGraphButton) {
  556            clearGraphButton.addEventListener('click', function () {
  557                editor.clearGraph();
  559            });
  560        }
  561 
  562        
  563        var saveMaterialXGraph = document.getElementById('saveMaterialXGraph');
  564        if (saveMaterialXGraph) {
  565            saveMaterialXGraph.addEventListener('click', function () {
  566                var sl = document.getElementById('writeCustomLibs').checked;
  567                var sp = document.getElementById('saveNodePositions').checked;
  568                var wo = true;
  569                var graphWriteOptions = { writeCustomLibs: sl, saveNodePositions: sp, writeOutputs: wo };
  570                editor.saveGraphToFile('mtlx', graphWriteOptions);
  571            });
  572        }
  573 
  574        
  575        var saveMaterialXGraphText = document.getElementById('saveMaterialXGraphText');
  576        if (saveMaterialXGraphText) {
  577            saveMaterialXGraphText.addEventListener('click', function () {
  578                saveToStringUI();
  579            });
  580        }
  581 
  582        
  583        var searchGraph = document.getElementById('searchGraph');
  584        if (searchGraph) {
  585            searchGraph.addEventListener('click', function () {
  586                var search = document.getElementById('searchGraphText').value;
  587                editor.searchGraph(search);
  588            });
  589        }
  590 
  591        
  592        var openSubgraph = document.getElementById('openSubgraph');
  593        if (openSubgraph) {
  594            openSubgraph.addEventListener('click', function () {
  595                editor.openSubgraph();
  596            });
  597        }
  598 
  599        
  600        var closeSubgraph = document.getElementById('closeSubgraph');
  601        if (closeSubgraph) {
  602            closeSubgraph.addEventListener('click', function () {
  603                editor.closeSubgraph();
  604            });
  605        }
  606 
  607        
  608        var resetView = document.getElementById('resetView');
  609        if (resetView) {
  610            resetView.addEventListener('click', function () {
  611                editor.resetView();
  612            });
  613        }
  614 
  615        
  616        var arrangeGraphButton = document.getElementById('arrangeGraph');
  617        if (arrangeGraphButton) {
  618            arrangeGraphButton.addEventListener('click', function () {
  619                editor.arrangeGraph();
  620            });
  621        }
  622 
  623        
  624        var centerNodeButton = document.getElementById('centerNode');
  625        if (centerNodeButton) {
  626            centerNodeButton.addEventListener('click', function () {
  627                editor.centerNode();
  628            });
  629        }
  630 
  631        
  632        var collapseNodesButton = document.getElementById('collapseNodes');
  633        if (collapseNodesButton) {
  634            collapseNodesButton.addEventListener('click', function () {
  635                editor.collapseExpandNodes(true);
  636            });
  637        }
  638        var expandNodesButton = document.getElementById('expandNodes');
  639        if (expandNodesButton) {
  640            expandNodesButton.addEventListener('click', function () {
  641                editor.collapseExpandNodes(false);
  642            });
  643        }
  644 
  645        
  646        var selectNodesButton = document.getElementById('selectNodes');
  647        if (selectNodesButton) {
  648            selectNodesButton.addEventListener('click', function () {
  649                editor.selectNodes();                
  650            });
  651        }
  652 
  653        
  654        var copySelectedButton = document.getElementById('copySelected');
  655        if (copySelectedButton) {
  656            copySelectedButton.addEventListener('click', function () {
  657                editor.copyToClipboard();
  658            });
  659        }
  660 
  661        
  662        var pasteSelectedButton = document.getElementById('pasteSelected');
  663        if (pasteSelectedButton) {
  664            pasteSelectedButton.addEventListener('click', function () {
  665                editor.pasteFromClipboard();
  666            });
  667        }
  668 
  669        
  670        var createNodeGraphButton = document.getElementById('createNodeGraph');
  671        if (createNodeGraphButton) {
  672            createNodeGraphButton.addEventListener('click', function () {
  673                editor.createNodeGraph();
  674            });
  675        }
  676 
  677        
  678        var extractNodeGraphButton = document.getElementById('extractNodeGraph');
  679        if (extractNodeGraphButton) {
  680            extractNodeGraphButton.addEventListener('click', function () {
  681                editor.extractNodeGraph();
  682            });
  683        }
  684 
  685        
  686
  687
  688
  689
  690
  691
  692
  693
  694
  695
  696
  697 
  698        
  699        var xmlToGraph = document.getElementById('xmltograph');
  700        if (xmlToGraph) {
  701            xmlToGraph.addEventListener('click', function () {
  702                var name = 'MaterialXGraph' + texAreaNumber++;
  703                var mtlxdoc = document.getElementById('mtlxdoc').value;
  704                editor.loadGraphFromString('mtlx', mtlxdoc, 'MaterialXGraph', auto_arrange_size, true);
  705                
  706            });
  707        }
  708 
  709        function updateRenderableItemUI() {
  710            let renderableItems = editor.findRenderableItems();
  711            renderableItemUpdater(renderableItems);
  712        }
  713 
  714        function saveToStringUI() {
  715            var cl = document.getElementById('writeCustomLibs').checked;
  716            var sp = document.getElementById('saveNodePositions').checked;
  717            var wo = true;
  718            var graphWriteOptions = { writeCustomLibs: cl, saveNodePositions: sp, writeOutputs: wo };
  719            console.log('Save with options: ', graphWriteOptions);
  720            var result = editor.saveGraphToString('mtlx', graphWriteOptions);
  721 
  722            cmeditor.setValue(result[0]);
  723 
  724            if (customRenderer) {
  725                customRenderer.setSourceColorSpace(editor.getSourceColorSpace());
  726                customRenderer.setTargetDistanceUnit(editor.getTargetDistanceUnit());
  727                customRenderer.updateMaterialFromText(result[0]);
  728                updateRenderableItemUI();
  729            }
  730        }
  731 
  732        
  733        var graphtoxml = document.getElementById('graphtoxml');
  734        if (graphtoxml) {
  735            graphtoxml.addEventListener('click', function () {
  736                saveToStringUI();
  737            });
  738        }
  739 
  740        let graphtoxml2 = document.getElementById('graphtoxml2');
  741        if (graphtoxml2) {
  742            graphtoxml2.addEventListener('click', function () {
  743                saveToStringUI();
  744                graphtoxml2.classList.remove('btn-outline-warning');
  745                graphtoxml2.classList.add('btn-outline-secondary');
  746            });
  747        }
  748 
  749        
  750        var graphtogltf = document.getElementById('graphtogltf');
  751        if (graphtogltf) {
  752            graphtogltf.addEventListener('click', function () {
  753                var graphWriteOptions = { writeCustomLibs: false, saveNodePositions: false, writeOutputs: true };
  754                var result = editor.saveGraphToString('gltf', graphWriteOptions);
  755                gltfDisplayUpdater(result[0]);
  756                if (result[1]) {
  757                    consoleLog(result[1], 1, false);
  758                }
  759            });
  760        }
  761 
  762        
  763        var gltftograph = document.getElementById('gltftograph');
  764        if (gltftograph) {
  765            gltftograph.addEventListener('click', function () {
  766                var gltfdoc = document.getElementById('gltfgraph').value;
  767                if (gltfdoc.length > 0) {
  768                    editor.loadGraphFromString('gltf', gltfdoc, 'GLTFGraph', auto_arrange_size, true);
  769                    
  770                }
  771            });
  772        }
  773 
  774        
  775        let turntableEnabledUI = document.getElementById('turntableEnabled');
  776        if (turntableEnabledUI) {
  777            turntableEnabledUI.addEventListener('click', (e) => {
  778                
  779                turntableEnabledUI.classList.toggle('btn-secondary');
  780                if (customRenderer)
  781                    customRenderer.toggleTurntable();
  782            });
  783        }
  784 
  785        
  786        let disableRenderingUI = document.getElementById('disableRendering');
  787        if (disableRenderingUI) {
  788            disableRenderingUI.addEventListener('click', (e) => {
  789                
  790                disableRenderingUI.classList.toggle('btn-danger');
  791                if (customRenderer)
  792                    customRenderer.toggleRendering();
  793            });
  794        }
  795 
  796        
  797        let toggleBackgroundTextureUI = document.getElementById('toggleBackgroundTexture');
  798        if (toggleBackgroundTextureUI) {
  799            toggleBackgroundTextureUI.addEventListener('click', (e) => {
  800                toggleBackgroundTextureUI.classList.toggle('btn-primary');
  801                if (customRenderer)
  802                    customRenderer.toggleBackgroundTexture();
  803            });
  804        }
  805 
  806        
  807        let resetCameraUI = document.getElementById('resetCamera');
  808        if (resetCameraUI) {
  809            resetCameraUI.addEventListener('click', (e) => {
  810                if (customRenderer) {
  811                    customRenderer.resetCamera();
  812                }
  813            });
  814        }
  815 
  816        
  817        function loadFromMenu(e) {
  818            var uiItem = e.target.value;
  819            if (uiItem == '_loadFromFile_') {
  820                
  821                var fileInput = document.createElement('input');
  822                fileInput.type = 'file';
  823                fileInput.accept = '.glb';
  824 
  825                fileInput.onchange = function(event) {
  826                    var file = event.target.files[0];
  827                    if (file) {
  828                        var fileURL = URL.createObjectURL(file);
  829                        if (customRenderer)
  830                            customRenderer.setRenderGeometry(fileURL);
  831                        console.log('Change geometry to:', fileURL, 'from file:', file.name);
  832                    }
  833                }
  834                fileInput.click();
  835            }
  836            else {
  837                
  838                var geometryURL = uiItem.toLowerCase().replace(/\s/g, '');
  839                var geometryPath = 'Geometry/' + geometryURL + '.glb';
  840                console.log('Change geometry to:', geometryPath);
  841                if (customRenderer)
  842                    customRenderer.setRenderGeometry(geometryPath);
  843            }
  844        }
  845 
  846        
  847        let geometryItemSelect = document.getElementById('loadGeometry');
  848        if (geometryItemSelect) {
  849 
  850            
  851            var geometryItems = ['Teapot', 'Shader Ball', 'Sphere', 'Plane', 'Cube', 'Cylinder', 'Donut', 'Twist', 'Custom...'];
  852            for (var i = 0; i < geometryItems.length; i++) {
  853                var option = document.createElement('option');
  854                option.value = geometryValues[i];
  855                option.text = geometryItems[i];
  856                geometryItemSelect.appendChild(option);
  857            }
  858 
  859            
  860            geometryItemSelect.addEventListener('change', (e) => {
  861                loadFromMenu(e);
  862                if (e.target.value == '_loadFromFile_')
  863                    e.target.value = 'Custom Geometry'
  864            });
  865 
  866            
  867            if (selectGeometryUI) {
  868                
  869                geometryItemSelect.value = geometryId;
  870            }
  871        }
  872 
  873        
  874        let renderableItemSelect = document.getElementById('renderableItem');
  875        if (renderableItemSelect) {
  876            renderableItemSelect.addEventListener('change', (e) => {
  877                let index = e.target.value;
  878                if (customRenderer)
  879                {
  880                    customRenderer.setRenderMaterial(index);
  881                    editor.searchGraph(index);
  882                }
  883            });
  884        }
  885 
  886        
  887        var canvas = document.getElementById('mygraphcanvas');
  888        var canvasContainer = document.getElementById('canvasContainer');
  889        var colContainer = document.getElementById('colContainer');
  890 
  891        
  892        var observer = new ResizeObserver(function (entries) {
  893            
  894                
  895                
  896                
  897 
  898                var parent = canvas.parentNode;
  899                let newWidth = parent.offsetWidth;
  900                let newHeight = parent.offsetHeight;
  901 
  902                
  903                
  904                
  905 
  906                
  907                console.log('Resize node graph canvas to:', newWidth, newHeight);
  908                editor.setDirty(newWidth, newHeight);
  909                
  910            
  911        });
  912 
  913        
  914        observer.observe(canvasContainer);
  915 
  916    }
  917 
  918    function setupGLTFSyntax() {
  919        
  920        let cmeditor = null;
  921        const gltfTextArea = document.getElementById('gltfgraph');
  922        if (gltfTextArea) {
  923            cmeditor = CodeMirror.fromTextArea(gltfTextArea, {
  924                mode: 'application/json',
  925                lineNumbers: true,
  926                dragDrop: false,
  927                theme: 'dracula'
  928            });
  929 
  930            
  931            const initialGLTF = '';
  932            gltfTextArea.value = initialGLTF;
  933            cmeditor.setValue(initialGLTF);
  934 
  935            
  936            cmeditor.on('change', (e) => {
  937                gltfTextArea.value = cmeditor.getValue();
  938            });
  939 
  940            var pasteButton = document.getElementById('gltfgraph_paste');
  941            if (pasteButton)
  942                addPasteHandler(pasteButton, cmeditor);
  943 
  944        }
  945        return cmeditor;
  946    }
  947 
  948    function setupJavascriptSyntax() {
  949        
  950        const elem = document.getElementById('mtlxlib');
  951        if (!elem) {
  952            return;
  953        }
  954        let cmeditor = CodeMirror.fromTextArea(elem, {
  955            mode: 'application/javascript',
  956            lineNumbers: true,
  957            dragDrop: false,
  958            theme: 'dracula',
  959            readOnly: true
  960        });
  961 
  962        elem.value = '';
  963        cmeditor.setValue('');
  964 
  965        
  966        cmeditor.on('change', () => {
  967            elem.value = cmeditor.getValue();
  968        });
  969 
  970        return cmeditor;
  971    }
  972 
  973 
  974    function setupXMLSyntax() {
  975        
  976        const materialXTextArea = document.getElementById('mtlxdoc');
  977        let cmeditor = CodeMirror.fromTextArea(materialXTextArea, {
  978            mode: 'application/xml',
  979            lineNumbers: true,
  980            dragDrop: true,
  981            theme: 'night'
  982        });
  983 
  984        
  985        const initialXML = '';
  986        materialXTextArea.value = initialXML;
  987        cmeditor.setValue(initialXML);
  988 
  989        
  990        cmeditor.on('change', (e) => {
  991            materialXTextArea.value = cmeditor.getValue();
  992        });
  993 
  994        var pasteButton = document.getElementById('mtlxdoc_paste');
  995        if (pasteButton)
  996            addPasteHandler(pasteButton, cmeditor);
  997 
  998        return cmeditor;
  999    }
 1000 
 1001    addUIHandlers();
 1002    addCopyHandlers();
 1003}
Custom monitor class for MaterialX graph.
This class is a wrapper around the LiteGraph library to provide a MaterialX node editor.
function toggleRequireUpdateUI()