From dd63332d77a13ecaf7b130c5b2b531d1f44ee829 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Fri, 22 Nov 2024 15:57:12 +0000
Subject: [PATCH] chore: build and documentation for release

---
 dist/maidr.js                  | 12 +++++++-----
 dist/maidr.min.js              |  2 +-
 docs/AdvancedUserSettings.html |  2 +-
 docs/Audio.html                |  2 +-
 docs/AudioProperties.html      |  2 +-
 docs/BTSModes.html             |  2 +-
 docs/BarChart.html             |  2 +-
 docs/BasicChartProperties.html |  2 +-
 docs/BoxPlot.html              |  2 +-
 docs/BoxplotRect.html          |  2 +-
 docs/ChatLLM.html              | 24 ++++++++++++------------
 docs/Constants.html            |  2 +-
 docs/Control.html              |  2 +-
 docs/DebugSettings.html        |  2 +-
 docs/Description.html          | 12 ++++++------
 docs/Display.html              |  2 +-
 docs/HeatMap.html              |  2 +-
 docs/HeatMapRect.html          |  2 +-
 docs/Helper.html               |  6 +++---
 docs/Histogram.html            |  2 +-
 docs/HtmlIds.html              |  2 +-
 docs/LLMSettings.html          |  2 +-
 docs/Layer0Point.html          |  2 +-
 docs/Layer1Point.html          |  2 +-
 docs/LinePlot.html             |  2 +-
 docs/LogError.html             | 14 +++++++-------
 docs/Menu.html                 | 20 ++++++++++----------
 docs/PlatformControls.html     |  2 +-
 docs/Point.html                |  2 +-
 docs/Position.html             |  4 ++--
 docs/Resources.html            |  2 +-
 docs/Review.html               |  6 +++---
 docs/ScatterPlot.html          |  2 +-
 docs/Segmented.html            |  2 +-
 docs/Tracker.html              | 20 ++++++++++----------
 docs/UserSettings.html         |  2 +-
 docs/audio.js.html             |  2 +-
 docs/barplot.js.html           |  2 +-
 docs/boxplot.js.html           |  2 +-
 docs/constants.js.html         | 14 ++++++++------
 docs/controls.js.html          |  2 +-
 docs/display.js.html           |  2 +-
 docs/global.html               |  2 +-
 docs/heatmap.js.html           |  2 +-
 docs/histogram.js.html         |  2 +-
 docs/index.html                |  2 +-
 docs/init.js.html              |  2 +-
 docs/lineplot.js.html          |  2 +-
 docs/scatterplot.js.html       |  2 +-
 docs/segmented.js.html         |  2 +-
 50 files changed, 108 insertions(+), 104 deletions(-)

diff --git a/dist/maidr.js b/dist/maidr.js
index f52f8924..dfb637c7 100644
--- a/dist/maidr.js
+++ b/dist/maidr.js
@@ -1279,11 +1279,9 @@ class Menu {
       'input',
       function (e) {
         if (e.target.value) {
-          document
-            .getElementById('delete_email_key')
-            .classList.remove('hidden');
+          document.getElementById('delete_email_key').style = '';
         } else {
-          document.getElementById('delete_email_key').classList.add('hidden');
+          document.getElementById('delete_email_key').style = 'display: none';
         }
       },
     ]);
@@ -1453,6 +1451,10 @@ class Menu {
       .getElementById(`claude_auth_key_container`)
       .classList.add('hidden');
 
+    if (!constants.emailAuthKey) {
+      document.getElementById('delete_email_key').style = 'display: none';
+    }
+
     // skill level other
     if (constants.skillLevel == 'other') {
       document
@@ -1889,7 +1891,7 @@ class ChatLLM {
       function (e) {
         document.getElementById('email_auth_key').value = '';
         document.getElementById('email_auth_key').disabled = false;
-        document.getElementById('delete_email_key').classList.add('hidden');
+        document.getElementById('delete_email_key').style = 'display: none';
         constants.clientToken = '';
         document.getElementById('verify').classList.remove('hidden');
       },
diff --git a/dist/maidr.min.js b/dist/maidr.min.js
index 80afc9dc..126ba120 100644
--- a/dist/maidr.min.js
+++ b/dist/maidr.min.js
@@ -1 +1 @@
-class Constants{chart_container_id="chart-container";main_container_id="maidr-container";braille_container_id="braille-div";braille_input_id="braille-input";info_id="info";announcement_container_id="announcements";end_chime_id="end_chime";container_id="container";project_id="maidr";review_id_container="review_container";review_id="review";reviewSaveSpot;reviewSaveBrailleMode;chartId="";events=[];postLoadEvents=[];constructor(){}textMode="verbose";brailleMode="off";lockSelection=!1;sonifMode="on";reviewMode="off";minX=0;maxX=0;minY=0;maxY=0;plotId="";chartType="";navigation=1;plotOrientation="horz";MAX_FREQUENCY=1e3;MIN_FREQUENCY=200;NULL_FREQUENCY=100;combinedVolMin=.25;combinedVolMax=1.25;MAX_SPEED=500;MIN_SPEED=50;DEFAULT_SPEED=250;INTERVAL=20;AUTOPLAY_DURATION=2e3;vol=.5;MAX_VOL=30;autoPlayRate=this.DEFAULT_SPEED;colorSelected="#03C809";brailleDisplayLength=32;showRect=1;hasRect=1;hasSmooth=1;duration=.3;outlierDuration=.06;autoPlayOutlierRate=50;autoPlayPointsRate=50;colorUnselected="#595959";canTrack=1;visualBraille=!1;ariaMode="assertive";userSettingsKeys=["vol","autoPlayRate","brailleDisplayLength","colorSelected","MIN_FREQUENCY","MAX_FREQUENCY","AUTOPLAY_DURATION","ariaMode","openAIAuthKey","geminiAuthKey","claudeAuthKey","emailAuthKey","skillLevel","skillLevelOther","LLMModel","LLMPreferences","LLMOpenAiMulti","LLMGeminiMulti","LLMModels","autoInitLLM","clientToken"];openAIAuthKey=null;geminiAuthKey=null;LLMmaxResponseTokens=1e3;playLLMWaitingSound=!0;LLMDetail="high";LLMModel="openai";LLMModels={openai:!0};LLMSystemMessage="You are a helpful assistant describing the chart to a blind person. ";skillLevel="basic";skillLevelOther="";autoInitLLM=!0;verboseText="";waitingQueue=0;showDisplay=1;showDisplayInBraille=1;showDisplayInAutoplay=0;outlierInterval=null;isMac=navigator.userAgent.toLowerCase().includes("mac");control=this.isMac?"Cmd":"Ctrl";alt=this.isMac?"option":"Alt";home=this.isMac?"fn + Left arrow":"Home";end=this.isMac?"fn + Right arrow":"End";keypressInterval=2e3;tabMovement=null;debugLevel=3;canPlayEndChime=!1;manualData=!0;baseURL="https://maidr-service.azurewebsites.net/api/";code="?code=I8Aa2PlPspjQ8Hks0QzGyszP8_i2-XJ3bq7Xh8-ykEe4AzFuYn_QWA%3D%3D";clientToken=null;KillAutoplay(){clearInterval(this.autoplayId),this.autoplayId=null}KillSepPlay(){this.sepPlayId&&(clearInterval(this.sepPlayId),this.sepPlayId=null)}SpeedUp(){constants.autoPlayRate-this.INTERVAL>this.MIN_SPEED&&(constants.autoPlayRate-=this.INTERVAL)}SpeedDown(){constants.autoPlayRate+this.INTERVAL<=this.MAX_SPEED&&(constants.autoPlayRate+=this.INTERVAL)}SpeedReset(){constants.autoPlayRate=constants.DEFAULT_SPEED}ConvertHexToRGBString(t){return"rgb("+parseInt(t.slice(1,3),16)+","+parseInt(t.slice(3,5),16)+","+parseInt(t.slice(5,7),16)+")"}ConvertRGBStringToHex(t){let e=t.replace(/[^\d,]/g,"").split(",");return"#"+e[0].toString(16).padStart(2,"0")+e[1].toString(16).padStart(2,"0")+e[2].toString(16).padStart(2,"0")}ColorInvert(t){let e=t.replace(/[^\d,]/g,"").split(",");return"rgb("+(255-e[0])+","+(255-e[1])+","+(255-e[2])+")"}GetBetterColor(t){-1!==t.indexOf("#")&&(t=this.ConvertHexToRGBString(t));let e=this.ColorInvert(t),n=e.replace(/[^\d,]/g,"").split(",");return n[1]<n[0]+10&&n[1]>n[0]-10&&n[2]<n[0]+10&&n[2]>n[0]-10&&(n[0]>86||n[0]<169)&&(e=this.colorSelected),e}GetStyleArrayFromString(t){return t.replaceAll(" ","").split(/[:;]/)}GetStyleStringFromArray(t){let e="";for(let n=0;n<t.length;n++)n%2==0?n!==t.length-1?e+=t[n]+": ":e+=t[n]:e+=t[n]+"; ";return e}}class Resources{constructor(){}language="en";knowledgeLevel="basic";strings={en:{basic:{upper_outlier:"Upper Outlier",lower_outlier:"Lower Outlier",min:"Minimum",max:"Maximum",25:"25%",50:"50%",75:"75%",q1:"25%",q2:"50%",q3:"75%",son_on:"Sonification on",son_off:"Sonification off",son_des:"Sonification descrete",son_comp:"Sonification compare",son_ch:"Sonification chord",son_sep:"Sonification separate",son_same:"Sonification combined",empty:"Empty",openai:"OpenAI Vision",gemini:"Gemini Pro Vision",claude:"Claude",multi:"Multiple AI",processing:"Processing Chart..."}}};GetString(t){return this.strings[this.language][this.knowledgeLevel][t]}}class Menu{whereWasMyFocus=null;constructor(){this.CreateMenu(),this.LoadDataFromLocalStorage()}menuHtml=`\n        <div id="menu" class="modal hidden" role="dialog" tabindex="-1">\n            <div class="modal-dialog" role="document" tabindex="0">\n                <div class="modal-content">\n                    <div class="modal-header">\n                        <h2 class="modal-title">Menu</h2>\n                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n                            <span aria-hidden="true">&times;</span>\n                        </button>\n                    </div>\n                    <div class="modal-body">\n                        <div>\n                            <h5 class="modal-title">Keyboard Shortcuts</h5>\n                            <table>\n                                <caption class="sr-only">Keyboard Shortcuts</caption>\n                                <thead>\n                                    <tr>\n                                        <th scope="col">Function</th>\n                                        <th scope="col">Key</th>\n                                    </tr>\n                                </thead>\n                                <tbody>\n                                    <tr>\n                                        <td>Move around plot</td>\n                                        <td>Arrow keys</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Go to the very left right up down</td>\n                                        <td>${constants.control} + Arrow key</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Select the first element</td>\n                                        <td>${constants.control} + ${constants.home}</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Select the last element</td>\n                                        <td>${constants.control} + ${constants.end}</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Toggle Braille Mode</td>\n                                        <td>b</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Toggle Text Mode</td>\n                                        <td>t</td>\n                                    </tr>\n                                                                        <tr>\n                                        <td>Toggle Sonification Mode</td>\n                                        <td>s</td>\n                                    </tr>\n                                                                                                            <tr>\n                                        <td>Toggle Review Mode</td>\n                                        <td>r</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Repeat current sound</td>\n                                        <td>Space</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Auto-play outward in direction of arrow</td>\n                                        <td>${constants.control} + Shift + Arrow key</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Auto-play inward in direction of arrow</td>\n                                        <td>${constants.alt} + Shift + Arrow key</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Stop Auto-play</td>\n                                        <td>${constants.control}</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Auto-play speed up</td>\n                                        <td>Period (.)</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Auto-play speed down</td>\n                                        <td>Comma (,)</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Auto-play speed reset</td>\n                                        <td>Slash (/)</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Check label for the title of current plot</td>\n                                        <td>l t</td>\n                                    </tr>\n                                                                            <td>Check label for the x axis of current plot</td>\n                                        <td>l x</td>\n                                    </tr>\n                                                                                                                <td>Check label for the y axis of current plot</td>\n                                        <td>l y</td>\n                                    </tr>\n                                                                                                                <td>Check label for the fill (z) axis of current plot</td>\n                                        <td>l f</td>\n                                    </tr>\n                                                                                                                <td>Check label for the subtitle of current plot</td>\n                                        <td>l s</td>\n                                    </tr>\n                                                                                                                <td>Check label for the caption of current plot</td>\n                                        <td>l c</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Toggle AI Chat View</td>\n                                        <td>${constants.isMac?constants.alt:constants.control} + Shift + /</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Copy last chat message in AI Chat View</td>\n                                        <td>${constants.alt} + Shift + C</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Copy full chat history in AI Chat View</td>\n                                        <td>${constants.alt} + Shift + A</td>\n                                    </tr>\n                                </tbody>\n                            </table>\n                        </div>\n\n                        <div>\n                            <h5 class="modal-title">Settings</h5>\n                            <p><input type="range" id="vol" name="vol" min="0" max="1" step=".05"><label for="vol">Volume</label></p>\n                            \x3c!-- <p><input type="checkbox" id="show_rect" name="show_rect"><label for="show_rect">Show Outline</label></p> //--\x3e\n                            <p><input type="color" id="color_selected" name="color_selected"><label for="color_selected">Outline Color</label></p>\n                            <p><input type="number" min="4" max="2000" step="1" id="braille_display_length" name="braille_display_length"><label for="braille_display_length">Braille Display Size</label></p>\n                            <p><input type="number" min="10" max="2000" step="10" id="min_freq" name="min_freq"><label for="min_freq">Min Frequency (Hz)</label></p>\n                            <p><input type="number" min="20" max="2010" step="10" id="max_freq" name="max_freq"><label for="max_freq">Max Frequency (Hz)</label></p>\n                                                     <p>                            <p><input type="number" min="500" max="500000" step="500" id="AUTOPLAY_DURATION">Autoplay Duration (ms)</label></p>\n                            <div><fieldset>\n                              <legend>Aria Mode</legend>\n                              <p><input type="radio" id="aria_mode_assertive" name="aria_mode" value="assertive" ${"assertive"==constants.ariaMode?"checked":""}><label for="aria_mode_assertive">Assertive</label></p>\n                              <p><input type="radio" id="aria_mode_polite" name="aria_mode" value="polite" ${"polite"==constants.ariaMode?"checked":""}><label for="aria_mode_polite">Polite</label></p>\n                              </fieldset></div>\n                            <p class="hidden">\n                                <select id="LLM_model">\n                                    <option value="openai">OpenAI Vision</option>\n                                    <option value="gemini">Gemini Pro Vision</option>\n                                    <option value="multi">Multiple</option>\n                                </select>\n                                <label for="LLM_model">LLM Model</label>\n                            </p>\n                            <h5 class="modal-title">LLM Settings</h5>\n                            <p>\n                              <fieldset>\n                                <legend>LLM Models (select up to 2)</legend>\n                                <p><input type="checkbox" id="LLM_model_openai" name="LLM_model" value="openai"><label for="LLM_model_openai">OpenAI Vision</label></p>\n                                <p><input type="checkbox" id="LLM_model_gemini" name="LLM_model" value="gemini"><label for="LLM_model_gemini">Gemini Pro Vision</label></p>\n                                <p><input type="checkbox" id="LLM_model_claude" name="LLM_model" value="claude"><label for="LLM_model_claude">Claude</label></p>\n                              </fieldset>\n                            </p>\n                            <p id="email_auth_key_container" class="multi_container">\n                              <input type="email" size="50" id="email_auth_key" aria-label="Enter your email address">\n                              <button aria-label="Delete Email Address" title="Delete Email Address" id="delete_email_key" class="invis_button">&times;</button>\n                              <label for="gemini_auth_key">Email Authentication</label>\n                              <button type="button" id="verify">Verify</button>\n                            </p>\n                            <p id="openai_auth_key_container" class="multi_container hidden">\n                              <span id="openai_multi_container" class="hidden"><input type="checkbox" id="openai_multi" name="openai_multi" aria-label="Use OpenAI in Multi modal mode"></span>\n                              <input type="password" size="50" id="openai_auth_key"><button aria-label="Delete OpenAI key" title="Delete OpenAI key" id="delete_openai_key" class="invis_button">&times;</button><label for="openai_auth_key">OpenAI Authentication Key</label>\n                            </p>\n                            <p id="gemini_auth_key_container" class="multi_container hidden">\n                              <span id="gemini_multi_container" class="hidden"><input type="checkbox" id="gemini_multi" name="gemini_multi" aria-label="Use Gemini in Multi modal mode"></span>\n                              <input type="password" size="50" id="gemini_auth_key"><button aria-label="Delete Gemini key" title="Delete Gemini key" id="delete_gemini_key" class="invis_button">&times;</button><label for="gemini_auth_key">Gemini Authentication Key</label>\n                            </p>\n                             <p id="claude_auth_key_container" class="multi_container hidden">\n                              <span id="claude_multi_container" class="hidden"><input type="checkbox" id="claude_multi" name="claude_multi" aria-label="Use Claude in Multi modal mode"></span>\n                              <input type="password" size="50" id="claude_auth_key"><button aria-label="Delete Claude key" title="Delete Claude key" id="delete_claude_key" class="invis_button">&times;</button><label for="claude_auth_key">Claude Authentication Key</label>\n                            </p>\n                            <p><input type="checkbox" ${constants.autoInitLLM?"checked":""} id="init_llm_on_load" name="init_llm_on_load"><label for="init_llm_on_load">Start LLM right away</label></p>\n                            <p>\n                                <select id="skill_level">\n                                    <option value="basic">Basic</option>\n                                    <option value="intermediate">Intermediate</option>\n                                    <option value="expert">Expert</option>\n                                    <option value="other">Other: describe in your own words</option>\n                                </select>\n                                <label for="skill_level">Level of skill in statistical charts</label>\n                            </p>\n                            <p id="skill_level_other_container" class="hidden"><input type="text" placeholder="Very basic" id="skill_level_other"> <label for="skill_level_other">Describe your level of skill in statistical charts</label></p>\n                            <p><label for="LLM_preferences">Custom instructions for the chat response</label></p>\n                            <p><textarea id="LLM_preferences" rows="4" cols="50" placeholder="I'm a stats undergrad and work with Python. I prefer a casual tone, and favor information accuracy over creative description; just the facts please!"></textarea></p>\n                        </div>\n                    </div>\n                    <div class="modal-footer">\n                      <p>\n                        <button type="button" id="save_and_close_menu" aria-labelledby="save_and_close_text"><span id="save_and_close_text">Save and Close</span></button>\n                        <button type="button" id="close_menu">Close</button>\n                      </p>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <div id="menu_modal_backdrop" class="modal-backdrop hidden"></div>\n        `;CreateMenu(){document.querySelector("body").insertAdjacentHTML("beforeend",this.menuHtml);let t=document.querySelectorAll("#close_menu, #menu .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){menu.Toggle(!1)}]);constants.events.push([document.getElementById("save_and_close_menu"),"click",function(t){menu.SaveData(),menu.Toggle(!1)}]),constants.events.push([document.getElementById("verify"),"click",function(t){menu.VerifyEmail()}]),constants.events.push([document.getElementById("menu"),"keyup",function(t){"Esc"==t.key&&menu.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){"input"!=t.target.tagName.toLowerCase()&&"textarea"!=t.target.tagName.toLowerCase()&&"h"==t.key&&menu.Toggle(!0)}]),constants.events.push([document.getElementById("LLM_model"),"change",function(t){"openai"==t.target.value?(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.add("hidden"),document.getElementById("openai_multi_container").classList.add("hidden"),document.getElementById("gemini_multi_container").classList.add("hidden"),document.getElementById("openai_multi").checked=!0,document.getElementById("gemini_multi").checked=!1):"gemini"==t.target.value?(document.getElementById("openai_auth_key_container").classList.add("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden"),document.getElementById("openai_multi_container").classList.add("hidden"),document.getElementById("gemini_multi_container").classList.add("hidden"),document.getElementById("openai_multi").checked=!1,document.getElementById("gemini_multi").checked=!0):"multi"==t.target.value&&(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden"),document.getElementById("openai_multi_container").classList.remove("hidden"),document.getElementById("gemini_multi_container").classList.remove("hidden"),document.getElementById("openai_multi").checked=!0,document.getElementById("gemini_multi").checked=!0)}]),constants.events.push([document.getElementById("LLM_model_openai"),"change",function(t){constants.clientToken&&constants.emailAuthKey?console.log("Client token and email auth key already set"):t.target.checked?document.getElementById("openai_auth_key_container").classList.remove("hidden"):document.getElementById("openai_auth_key_container").classList.add("hidden")}]),constants.events.push([document.getElementById("LLM_model_gemini"),"change",function(t){constants.clientToken&&constants.emailAuthKey?console.log("Client token and email auth key already set"):t.target.checked?document.getElementById("gemini_auth_key_container").classList.remove("hidden"):document.getElementById("gemini_auth_key_container").classList.add("hidden")}]),constants.events.push([document.getElementById("LLM_model_claude"),"change",function(t){constants.clientToken&&constants.emailAuthKey?console.log("Client token and email auth key already set"):document.getElementById("claude_auth_key_container").classList.add("hidden")}]),constants.events.push([document.getElementById("email_auth_key").addEventListener("keydown",(function(t){"Enter"===t.key&&document.getElementById("verify").click()}))]),constants.events.push([document.getElementById("email_auth_key"),"input",function(t){t.target.value?document.getElementById("delete_email_key").classList.remove("hidden"):document.getElementById("delete_email_key").classList.add("hidden")}]),constants.events.push([document.getElementById("skill_level"),"change",function(t){"other"==t.target.value?document.getElementById("skill_level_other_container").classList.remove("hidden"):document.getElementById("skill_level_other_container").classList.add("hidden")}]);let e=["LLM_model","openai_multi","gemini_multi","skill_level","LLM_preferences"];for(let t=0;t<e.length;t++)constants.events.push([document.getElementById(e[t]),"change",function(t){menu.NotifyOfLLMReset()}]);document.querySelectorAll('input[name="LLM_model"]').forEach((t=>{t.addEventListener("change",(()=>{const e=document.querySelectorAll('input[name="LLM_model"]:checked');e.length>2?(t.checked=!1,alert("You can select up to 2 AI models.")):0===e.length&&(t.checked=!0,alert("You must select at least one AI model."))}))}))}Destroy(){let t=document.getElementById("menu");t&&t.remove();let e=document.getElementById("menu_modal_backdrop");e&&e.remove()}Toggle(t=!1){void 0===t&&(t=!!document.getElementById("menu").classList.contains("hidden")),t&&document.getElementById("chatLLM")&&!document.getElementById("chatLLM").classList.contains("hidden")||(t?(this.whereWasMyFocus=document.activeElement,this.PopulateData(),constants.tabMovement=0,document.getElementById("menu").classList.remove("hidden"),document.getElementById("menu_modal_backdrop").classList.remove("hidden"),document.querySelector("#menu .close").focus()):(document.getElementById("menu").classList.add("hidden"),document.getElementById("menu_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null))}PopulateData(){if(document.getElementById("vol").value=constants.vol,document.getElementById("braille_display_length").value=constants.brailleDisplayLength,document.getElementById("color_selected").value=constants.colorSelected,document.getElementById("min_freq").value=constants.MIN_FREQUENCY,document.getElementById("max_freq").value=constants.MAX_FREQUENCY,document.getElementById("AUTOPLAY_DURATION").value=constants.AUTOPLAY_DURATION,"string"==typeof constants.openAIAuthKey&&(document.getElementById("openai_auth_key").value=constants.openAIAuthKey),"string"==typeof constants.emailAuthKey&&(document.getElementById("email_auth_key").value=constants.emailAuthKey),"string"==typeof constants.geminiAuthKey&&(document.getElementById("gemini_auth_key").value=constants.geminiAuthKey),"string"==typeof constants.claudeAuthKey&&(document.getElementById("claude_auth_key").value=constants.claudeAuthKey),document.getElementById("skill_level").value=constants.skillLevel,constants.skillLevelOther&&(document.getElementById("skill_level_other").value=constants.skillLevelOther),"assertive"==constants.ariaMode?(document.getElementById("aria_mode_assertive").checked=!0,document.getElementById("aria_mode_polite").checked=!1):(document.getElementById("aria_mode_polite").checked=!0,document.getElementById("aria_mode_assertive").checked=!1),constants.emailAuthKey&&constants.clientToken)console.log("email auth key and client token found"),this.DisableLLMAPIKeys();else for(let t in constants.LLMModels)document.getElementById(`LLM_model_${t}`).checked=!0,document.getElementById(`${t}_auth_key_container`).classList.remove("hidden");document.getElementById("claude_auth_key_container").classList.add("hidden"),"other"==constants.skillLevel&&document.getElementById("skill_level_other_container").classList.remove("hidden"),constants.LLMPreferences&&(document.getElementById("LLM_preferences").value=constants.LLMPreferences),document.getElementById("LLM_reset_notification")&&document.getElementById("LLM_reset_notification").remove()}SaveData(){let t=this.ShouldLLMReset();constants.vol=document.getElementById("vol").value,constants.brailleDisplayLength=document.getElementById("braille_display_length").value,constants.colorSelected=document.getElementById("color_selected").value,constants.MIN_FREQUENCY=document.getElementById("min_freq").value,constants.MAX_FREQUENCY=document.getElementById("max_freq").value,constants.AUTOPLAY_DURATION=document.getElementById("AUTOPLAY_DURATION").value,constants.openAIAuthKey=document.getElementById("openai_auth_key").value,constants.geminiAuthKey=document.getElementById("gemini_auth_key").value,constants.claudeAuthKey=document.getElementById("claude_auth_key").value,constants.emailAuthKey=document.getElementById("email_auth_key").value,constants.skillLevel=document.getElementById("skill_level").value,constants.skillLevelOther=document.getElementById("skill_level_other").value;document.querySelectorAll('input[name="LLM_model"]').forEach((t=>{t.checked?constants.LLMModels[t.value]=!0:delete constants.LLMModels[t.value]})),constants.LLMPreferences=document.getElementById("LLM_preferences").value,constants.LLMOpenAiMulti=document.getElementById("openai_multi").checked,constants.LLMGeminiMulti=document.getElementById("gemini_multi").checked,constants.autoInitLLM=document.getElementById("init_llm_on_load").checked,document.getElementById("aria_mode_assertive").checked?constants.ariaMode="assertive":document.getElementById("aria_mode_polite").checked&&(constants.ariaMode="polite"),this.SaveDataToLocalStorage(),this.UpdateHtml(),t&&chatLLM&&chatLLM.ResetLLM()}DisableLLMAPIKeys(){document.getElementById("email_auth_key").disabled=!0,document.getElementById("verify").classList.add("hidden")}isEmailTriggered=!1;VerifyEmail(){if(console.log("verify email"),!this.isEmailTriggered){this.isEmailTriggered=!0;let t=document.getElementById("email_auth_key").value;if(t&&-1!==t.indexOf("@")){let e=constants.baseURL+"send_email"+constants.code,n={email:t};fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authentication:constants.emailAuthKey},body:JSON.stringify(n)}).then((t=>t.json())).then((t=>{if(t&&t.message&&t.client_token){alert(t.message),constants.clientToken=t.client_token,this.DisableLLMAPIKeys();for(let t in constants.LLMModels)document.getElementById(`${t}_auth_key_container`).classList.add("hidden");this.SaveDataToLocalStorage(),this.isEmailTriggered=!1}else console.log(t),alert(t.data),this.isEmailTriggered=!1})).catch((t=>{console.log(t),alert(t.data),this.isEmailTriggered=!1}))}else alert("Please enter a valid email address."),this.isEmailTriggered=!1}}UpdateHtml(){constants.infoDiv.setAttribute("aria-live",constants.ariaMode),document.getElementById(constants.announcement_container_id).setAttribute("aria-live",constants.ariaMode),document.getElementById("init_llm_on_load").checked=constants.autoInitLLM;const t=document.getElementsByClassName("highlight_point"),e=document.getElementById("highlight_rect"),n=document.getElementById("highlight_point");if(null!==t&&t.length>0)for(let e=0;e<t.length;e++)t[e].setAttribute("stroke",constants.colorSelected),t[e].setAttribute("fill",constants.colorSelected);null!==e&&e.setAttribute("stroke",constants.colorSelected),null!==n&&n.setAttribute("stroke",constants.colorSelected)}NotifyOfLLMReset(){document.getElementById("LLM_reset_notification")&&document.getElementById("LLM_reset_notification").remove(),document.getElementById("save_and_close_menu").parentElement.insertAdjacentHTML("afterend",'<p id="LLM_reset_notification">Note: Changes in LLM settings will reset any existing conversation.</p>'),document.getElementById("save_and_close_menu").setAttribute("aria-labelledby","save_and_close_text LLM_reset_notification")}ShouldLLMReset(){let t=!1;t||constants.skillLevel==document.getElementById("skill_level").value||(t=!0),t||constants.LLMPreferences==document.getElementById("LLM_preferences").value||(t=!0),t||constants.LLMModel==document.getElementById("LLM_model").value||(t=!0);let e=document.querySelectorAll('input[name="LLM_model"]');for(let n=0;n<e.length;n++)t||constants.LLMModels[e[n].value]==e[n].checked||(t=!0);return t}SaveDataToLocalStorage(){let t={};for(let e=0;e<constants.userSettingsKeys.length;e++)t[constants.userSettingsKeys[e]]=constants[constants.userSettingsKeys[e]];localStorage.setItem("settings_data",JSON.stringify(t)),constants.canTrack&&(t.openAIAuthKey="hidden",t.geminiAuthKey="hidden",t.claudeAuthKey="hidden",t.timestamp=(new Date).toISOString(),tracker.SetData("settings",t))}LoadDataFromLocalStorage(){let t=JSON.parse(localStorage.getItem("settings_data"));if(t)for(let e=0;e<constants.userSettingsKeys.length;e++){const n=constants.userSettingsKeys[e];n in t&&(constants[n]=t[n])}this.PopulateData(),this.UpdateHtml()}}class ChatLLM{constructor(){this.firstTime=!0,this.firstMulti=!0,this.firstOpen=!0,this.shown=!1,this.CreateComponent(),this.SetEvents(),constants.autoInitLLM&&("gemini"in constants.LLMModels&&constants.geminiAuthKey||"openai"in constants.LLMModels&&constants.openAIAuthKey||"claude"in constants.LLMModels&&constants.claudeAuthKey)&&this.InitChatMessage()}CreateComponent(){let t=`\n        <div id="chatLLM" class="modal hidden" role="dialog" tabindex="-1">\n            <div class="modal-dialog" role="document" tabindex="0">\n                <div class="modal-content">\n                    <div class="modal-header">\n                        <h2 id="chatLLM_title" class="modal-title">Ask a Question</h2>\n                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n                            <span aria-hidden="true">&times;</span>\n                        </button>\n                    </div>\n                    <div class="modal-body">\n                        <div id="chatLLM_chat_history_wrapper">\n                        <div id="chatLLM_chat_history" aria-live="${constants.ariaMode}" aria-relevant="additions">\n                        </div>\n                        <p id="chatLLM_copy_all_wrapper"><button id="chatLLM_copy_all">Copy all to clipboard</button></p>\n                        </div>\n                        <div id="chatLLM_content">\n                          <p><input type="text" id="chatLLM_input" class="form-control" name="chatLLM_input" aria-labelledby="chatLLM_title" size="50"></p>\n                          <div class="LLM_suggestions">\n                            <p><button type="button">What is the title?</button></p>\n                            <p><button type="button">What are the high and low values?</button></p>\n                            <p><button type="button">What is the general shape of the chart?</button></p>\n                          </div>\n                          <div id="more_suggestions_container" class="LLM_suggestions">\n                            <p><button type="button">Please provide the title of this visualization, then provide a description for someone who is blind or low vision. Include general overview of axes and the data at a high-level.</button></p>\n                            <p><button type="button">For the visualization I shared, please provide the following (where applicable): mean, standard deviation, extreme, correlations, relational comparisons like greater than OR lesser than.</button></p>\n                            <p><button type="button">Based on the visualization shared, address the following: Do you observe any unforeseen trends? If yes, what?  Please convey any complex multi-faceted patterns present. Can you identify any noteworthy exceptions that aren't readily apparent through non-visual methods of analysis?</button></p>\n                            <p><button type="button">Provide context to help explain the data depicted in this visualization based on domain-specific insight.</button></p>\n                          </div>\n                          <p><button type="button" id="chatLLM_submit">Submit</button></p>\n                        </div>\n                    </div>\n                    <div class="modal-footer">\n                      <button type="button" id="reset_chatLLM">Reset</button>\n                      <button type="button" id="close_chatLLM">Close</button>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <div id="chatLLM_modal_backdrop" class="modal-backdrop hidden"></div>\n    `;document.querySelector("body").insertAdjacentHTML("beforeend",t)}SetEvents(){let t=document.querySelectorAll("#close_chatLLM, #chatLLM .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){chatLLM.Toggle(!1)}]);constants.events.push([document.getElementById("chatLLM"),"keyup",function(t){"Esc"==t.key&&chatLLM.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){("?"==t.key&&(t.ctrlKey||t.metaKey)||"¿"==t.key)&&chatLLM.Toggle()}]),constants.events.push([document.getElementById("chatLLM_submit"),"click",function(t){let e=document.getElementById("chatLLM_input").value;chatLLM.DisplayChatMessage("User",e),chatLLM.Submit(e)}]),constants.events.push([document.getElementById("chatLLM_input"),"keyup",function(t){if("Enter"==t.key&&!t.shiftKey){let t=document.getElementById("chatLLM_input").value;chatLLM.DisplayChatMessage("User",t),chatLLM.Submit(t)}}]);let e=document.querySelectorAll("#chatLLM .LLM_suggestions button:not(#more_suggestions)");for(let t=0;t<e.length;t++)constants.events.push([e[t],"click",function(t){let e=t.target.innerHTML;chatLLM.DisplayChatMessage("User",e),chatLLM.Submit(e)}]);constants.events.push([document.getElementById("delete_openai_key"),"click",function(t){document.getElementById("openai_auth_key").value=""}]),constants.events.push([document.getElementById("delete_email_key"),"click",function(t){document.getElementById("email_auth_key").value="",document.getElementById("email_auth_key").disabled=!1,document.getElementById("delete_email_key").classList.add("hidden"),constants.clientToken="",document.getElementById("verify").classList.remove("hidden")}]),constants.events.push([document.getElementById("delete_gemini_key"),"click",function(t){document.getElementById("gemini_auth_key").value=""}]),constants.events.push([document.getElementById("reset_chatLLM"),"click",function(t){chatLLM.ResetLLM()}]),constants.events.push([document.getElementById("chatLLM"),"click",function(t){chatLLM.CopyChatHistory(t)}]),constants.events.push([document.getElementById("chatLLM"),"keyup",function(t){chatLLM.CopyChatHistory(t)}])}CopyChatHistory(t){let e="";if(void 0===t)e=document.getElementById("chatLLM_chat_history").innerHTML;else if("click"==t.type)"chatLLM_copy_all"==t.target.id?e=document.getElementById("chatLLM_chat_history").innerHTML:t.target.classList.contains("chatLLM_message_copy_button")&&(e=t.target.closest("p").previousElementSibling.innerHTML);else if("keyup"==t.type)if("C"==t.key&&(t.ctrlKey||t.metaKey||t.altKey)&&t.shiftKey){t.preventDefault();let n=document.querySelector("#chatLLM_chat_history > .chatLLM_message_other:last-of-type");n&&(e=n.innerHTML)}else"A"==t.key&&(t.ctrlKey||t.metaKey||t.altKey)&&t.shiftKey&&(t.preventDefault(),e=document.getElementById("chatLLM_chat_history").innerHTML);if(""!=e){let t=document.createElement("div");t.innerHTML=e,t.querySelectorAll(".chatLLM_message_copy").forEach((t=>t.remove()));let n=this.htmlToMarkdown(t);n=n.replace(/\n{3,}/g,"\n\n");try{navigator.clipboard.writeText(n)}catch(t){console.error("Failed to copy: ",t)}return n}}htmlToMarkdown(t){let e="";const n=t=>{switch(t.tagName){case"H1":return`# ${t.textContent}`;case"H2":return`## ${t.textContent}`;case"H3":return`### ${t.textContent}`;case"H4":return`#### ${t.textContent}`;case"H5":return`##### ${t.textContent}`;case"H6":return`###### ${t.textContent}`;case"P":return t.textContent;case"DIV":return Array.from(t.childNodes).map((t=>n(t))).join("\n")+"\n\n";default:return Array.from(t.childNodes).map((t=>n(t))).join("")}};return t.nodeType===Node.ELEMENT_NODE?e+=n(t):t.nodeType===Node.TEXT_NODE&&""!==t.textContent.trim()&&(e+=t.textContent.trim()),e.trim()}async Submit(t,e=!1){let n=null;this.firstMulti=!0,(this.firstOpen||"gemini"in constants.LLMModels)&&!e&&constants.verboseText.length>0&&(t="Here is the current position in the chart; no response necessarily needed, use this info only if it's relevant to future questions: "+constants.verboseText+". My question is: "+t,this.firstOpen=!1),constants.playLLMWaitingSound&&this.WaitingSound(!0),"openai"in constants.LLMModels&&(e&&(n=await this.ConvertSVGtoJPG(singleMaidr.id,"openai")),constants.openAIAuthKey?chatLLM.OpenAIPrompt(t,n):chatLLM.OpenAIPromptAPI(t,n)),"gemini"in constants.LLMModels&&(e&&(n=await this.ConvertSVGtoJPG(singleMaidr.id,"gemini")),constants.geminiAuthKey?chatLLM.GeminiPrompt(t,n):chatLLM.GeminiPromptAPI(t,n)),"claude"in constants.LLMModels&&(e&&(n=await this.ConvertSVGtoJPG(singleMaidr.id,"claude")),constants.claudeAuthKey?chatLLM.ClaudePrompt(t,n):chatLLM.ClaudePromptAPI(t,n))}WaitingSound(t=!0){t?(constants.waitingInterval&&(clearInterval(constants.waitingInterval),constants.waitingInterval=null),constants.waitingSoundOverride&&(clearTimeout(constants.waitingSoundOverride),constants.waitingSoundOverride=null)):(audio&&chatLLM.shown&&audio.playOscillator(880,.2,0),constants.waitingQueue>1?constants.waitingQueue--:chatLLM.KillAllWaitingSounds()),t&&(constants.waitingInterval=setInterval((function(){audio&&chatLLM.shown&&audio.playOscillator(440,.2,0)}),1e3),constants.waitingSoundOverride=setTimeout((function(){chatLLM.KillAllWaitingSounds()}),3e4),"multi"!=constants.LLMModel?constants.waitingQueue=1:(constants.waitingQueue=0,constants.LLMGeminiMulti&&constants.waitingQueue++,constants.LLMOpenAiMulti&&constants.waitingQueue++))}KillAllWaitingSounds(){constants.waitingInterval&&(clearInterval(constants.waitingInterval),constants.waitingInterval=null),constants.waitingSoundOverride&&(clearTimeout(constants.waitingSoundOverride),constants.waitingSoundOverride=null),constants.waitingQueue=0}InitChatMessage(){let t=resources.GetString(constants.LLMModel);this.firstTime=!1,this.DisplayChatMessage(t,resources.GetString("processing"),!0);let e=this.GetDefaultPrompt();this.Submit(e,!0)}ProcessLLMResponse(t,e){chatLLM.WaitingSound(!1);let n="",o=resources.GetString(e);if("openai"==e){n=t.choices[0].message.content;let e=this.requestJson.messages.length;this.requestJson.messages[e]={},this.requestJson.messages[e].role="assistant",this.requestJson.messages[e].content=n,t.error?(chatLLM.DisplayChatMessage(o,"Error processing request.",!0),chatLLM.WaitingSound(!1)):chatLLM.DisplayChatMessage(o,n)}else"gemini"==e&&(t.text()?(n=t.text(),chatLLM.DisplayChatMessage(o,n)):t.error||(t.error="Error processing request.",chatLLM.WaitingSound(!1)),t.error&&(chatLLM.DisplayChatMessage(o,"Error processing request.",!0),chatLLM.WaitingSound(!1)));if("claude"==e&&(console.log("Claude response: ",t),t.text()&&(n=t.text(),chatLLM.DisplayChatMessage(o,n)),t.error&&(chatLLM.DisplayChatMessage(o,"Error processing request.",!0),chatLLM.WaitingSound(!1))),constants.canTrack){let t=chatLLM.CopyChatHistory();tracker.SetData("ChatHistory",t)}}fakeLLMResponseData(){let t={};return t=this.requestJson.messages.length>2?{id:"chatcmpl-8Y44iRCRrohYbAqm8rfBbJqTUADC7",object:"chat.completion",created:1703129508,model:"gpt4-o",usage:{prompt_tokens:451,completion_tokens:16,total_tokens:467},choices:[{message:{role:"assistant",content:"A fake response from the LLM. Nice."},finish_reason:"length",index:0}]}:{id:"chatcmpl-8Y44iRCRrohYbAqm8rfBbJqTUADC7",object:"chat.completion",created:1703129508,model:"gpt-4-1106-vision-preview",usage:{prompt_tokens:451,completion_tokens:16,total_tokens:467},choices:[{message:{role:"assistant",content:"The chart you're referring to is a bar graph titled \"The Number of Diamonds"},finish_reason:"length",index:0}]},t}ClaudeJson(t,e=null){const n={anthropic_version:"vertex-2023-10-16",max_tokens:256,messages:[]},o={role:"user",content:[]};return e?o.content.push({type:"image",source:{type:"base64",media_type:"image/jpeg",data:e}},{type:"text",text:t}):o.content.push({type:"text",text:t}),n.messages.push(o),n}ClaudePromptAPI(t,e=null){console.log("Claude prompt API");let n=constants.baseURL+"claude"+constants.code,o=constants.LLMSystemMessage;constants.LLMPreferences&&(o+=constants.LLMPreferences),o+="\n\n"+t,null==e?e=constants.LLMImage:constants.LLMImage=e,constants.LLMImage=e;let s=chatLLM.ClaudeJson(o,e);fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authentication:constants.emailAuthKey+" "+constants.clientToken},body:JSON.stringify(s)}).then((t=>t.json())).then((t=>{t.text=function(){return t.content[0].text},chatLLM.ProcessLLMResponse(t,"claude")})).catch((t=>{chatLLM.WaitingSound(!1),console.error("Error:",t),chatLLM.DisplayChatMessage("Claude","Error processing request.",!0)}))}OpenAIPrompt(t,e=null){let n=constants.openAIAuthKey,o=chatLLM.OpenAIJson(t,e);fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer "+n},body:JSON.stringify(o)}).then((t=>t.json())).then((t=>{chatLLM.ProcessLLMResponse(t,"openai")})).catch((t=>{chatLLM.WaitingSound(!1),console.error("Error:",t),chatLLM.DisplayChatMessage("OpenAI","Error processing request.",!0)}))}OpenAIPromptAPI(t,e=null){let n=constants.baseURL+"openai"+constants.code,o=(constants.openAIAuthKey,chatLLM.OpenAIJson(t,e));fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authentication:constants.emailAuthKey+" "+constants.clientToken},body:JSON.stringify(o)}).then((t=>t.json())).then((t=>{chatLLM.ProcessLLMResponse(t,"openai")})).catch((t=>{chatLLM.WaitingSound(!1),console.error("Error:",t),chatLLM.DisplayChatMessage("OpenAI","Error processing request.",!0)}))}OpenAIJson(t,e=null){let n=constants.LLMSystemMessage;singleMaidr.type;this.requestJson||(this.requestJson={},this.requestJson.model="gpt-4o-2024-11-20",this.requestJson.max_tokens=constants.LLMmaxResponseTokens,this.requestJson.messages=[],this.requestJson.messages[0]={},this.requestJson.messages[0].role="system",this.requestJson.messages[0].content=n,constants.LLMPreferences&&(this.requestJson.messages[1]={},this.requestJson.messages[1].role="system",this.requestJson.messages[1].content=constants.LLMPreferences));let o=this.requestJson.messages.length;return this.requestJson.messages[o]={},this.requestJson.messages[o].role="user",this.requestJson.messages[o].content=e?[{type:"text",text:t},{type:"image_url",image_url:{url:e}}]:t,this.requestJson}GeminiJson(t,e=null){let n=constants.LLMSystemMessage,o="Describe "+singleMaidr.type+" charts to a blind person",s={generationConfig:{},safetySettings:[],contents:[]},i={role:"user",parts:[{text:n||o}]};constants.LLMPreferences&&i.parts.push({text:constants.LLMPreferences}),s.contents.push(i);let l={role:"user",parts:[]};return e?l.parts.push({text:t},{inlineData:{data:e,mimeType:"image/png"}}):l.parts.push({text:t}),s.contents.push(l),s}async GeminiPromptAPI(t,e=null){let n=constants.baseURL+"gemini"+constants.code,o=constants.LLMSystemMessage;constants.LLMPreferences&&(o+=constants.LLMPreferences),o+="\n\n"+t,null==e?e=constants.LLMImage:constants.LLMImage=e,constants.LLMImage=e;let s=chatLLM.GeminiJson(o,e);const i=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authentication:constants.emailAuthKey+" "+constants.clientToken},body:JSON.stringify(s)});if(i.ok){const t=await i.json();t.text=()=>t.candidates[0].content.parts[0].text,chatLLM.ProcessLLMResponse(t,"gemini")}else chatLLM.WaitingSound(!1),console.error("Error:",error),chatLLM.DisplayChatMessage("OpenAI","Error processing request.",!0)}async GeminiPrompt(t,e=null){try{null==e?e=constants.LLMImage:constants.LLMImage=e,constants.LLMImage=e;const{GoogleGenerativeAI:n}=await import("https://esm.run/@google/generative-ai"),o=constants.geminiAuthKey,s=new n(o).getGenerativeModel({model:"gemini-1.5-pro-latest"});let i=constants.LLMSystemMessage;constants.LLMPreferences&&(i+=constants.LLMPreferences),i+="\n\n"+t;const l={inlineData:{data:e,mimeType:"image/png"}},a=await s.generateContent([i,l]);chatLLM.ProcessLLMResponse(a.response,"gemini")}catch(t){throw chatLLM.WaitingSound(!1),chatLLM.DisplayChatMessage("Gemini","Error processing request.",!0),console.error("Error in GeminiPrompt:",t),t}}DisplayChatMessage(t="User",e="",n=!1){let o="h3";if(!n&&"multi"==constants.LLMModel&&"User"!=t){if(this.firstMulti){let t=`\n          <div class="chatLLM_message chatLLM_message_other">\n            <h3 class="chatLLM_message_user">${resources.GetString("multi")} Responses</h3>\n          </div>\n        `;this.RenderChatMessage(t),this.firstMulti=!1}o="h4"}let s=`\n      <div class="chatLLM_message ${"User"==t?"chatLLM_message_self":"chatLLM_message_other"}">`;e!=resources.GetString("processing")&&(s+=`<${o} class="chatLLM_message_user">${t}</${o}>`),s+=`<p class="chatLLM_message_text">${e}</p>\n      </div>\n    `,"User"!=t&&e!=resources.GetString("processing")&&(s+='\n        <p class="chatLLM_message_copy"><button class="chatLLM_message_copy_button">Copy</button></p>\n      '),this.RenderChatMessage(s)}RenderChatMessage(t){document.getElementById("chatLLM_chat_history").insertAdjacentHTML("beforeend",t),document.getElementById("chatLLM_input").value="",document.getElementById("chatLLM_chat_history").scrollTop=document.getElementById("chatLLM_chat_history").scrollHeight}ResetLLM(){document.getElementById("chatLLM_chat_history").innerHTML="",this.requestJson=null,this.firstTime=!0,(constants.autoInitLLM||chatLLM.shown)&&chatLLM.InitChatMessage()}Destroy(){let t=document.getElementById("chatLLM");t&&t.remove();let e=document.getElementById("chatLLM_modal_backdrop");e&&e.remove()}Toggle(t){void 0===t&&(t=!!document.getElementById("chatLLM").classList.contains("hidden")),chatLLM.shown=t,t?(this.whereWasMyFocus=document.activeElement,constants.tabMovement=0,document.getElementById("chatLLM").classList.remove("hidden"),document.getElementById("chatLLM_modal_backdrop").classList.remove("hidden"),document.querySelector("#chatLLM .close").focus(),this.firstTime&&this.InitChatMessage()):(document.getElementById("chatLLM").classList.add("hidden"),document.getElementById("chatLLM_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null,this.firstOpen=!0)}async ConvertSVGtoJPG(t,e){let n=document.getElementById(t);return new Promise(((t,o)=>{var s=document.createElement("canvas"),i=s.getContext("2d"),l=(new XMLSerializer).serializeToString(n);l.startsWith("<svg xmlns")||(l=`<svg xmlns="http://www.w3.org/2000/svg" ${l.slice(4)}`);var a=n.viewBox.baseVal||n.getBoundingClientRect();s.width=a.width,s.height=a.height;var r=new Image;r.onload=function(){i.drawImage(r,0,0,a.width,a.height);var n=s.toDataURL("image/jpeg",.9);if("openai"==e)t(n);else if("gemini"==e||"claude"==e){let e=n.split(",")[1];t(e)}URL.revokeObjectURL(p)},r.onerror=function(){o(new Error("Error loading SVG"))};var c=new Blob([l],{type:"image/svg+xml;charset=utf-8"}),p=URL.createObjectURL(c);r.src=p}))}GetDefaultPrompt(){let t="Describe this chart to a blind person";return constants.skillLevel?"other"==constants.skillLevel&&constants.skillLevelOther?t+=" who has a "+constants.skillLevelOther+" understanding of statistical charts. ":t+=" who has a "+constants.skillLevel+" understanding of statistical charts. ":t+=" who has a basic understanding of statistical charts. ",t+="Here is a chart in image format",singleMaidr&&(t+=" and raw data in json format: \n",t+=JSON.stringify(singleMaidr)),t}}class Description{constructor(){}CreateComponent(){document.querySelector("body").insertAdjacentHTML("beforeend",'\n        <div id="description" class="modal hidden" role="dialog" tabindex="-1">\n            <div class="modal-dialog" role="document" tabindex="0">\n                <div class="modal-content">\n                    <div class="modal-header">\n                        <h2 id="desc_title" class="modal-title">Description</h2>\n                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n                            <span aria-hidden="true">&times;</span>\n                        </button>\n                    </div>\n                    <div class="modal-body">\n                        <div id="desc_content">\n                        content here\n                        </div>\n                        <div id="desc_table">\n                        </div>\n                    </div>\n                    <div class="modal-footer">\n                        <button type="button" id="close_desc">Close</button>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <div id="desc_modal_backdrop" class="modal-backdrop hidden"></div>\n\n    ');let t=document.querySelectorAll("#close_desc, #description .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){description.Toggle(!1)}]);constants.events.push([document.getElementById("description"),"keyup",function(t){"Esc"==t.key&&description.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){"d"==t.key&&description.Toggle(!0)}])}Destroy(){let t=document.getElementById("menu");t&&t.remove();let e=document.getElementById("desc_modal_backdrop");e&&e.remove()}Toggle(t=!1){void 0===t&&(t=!!document.getElementById("description").classList.contains("hidden")),t?(this.whereWasMyFocus=document.activeElement,constants.tabMovement=0,this.PopulateData(),document.getElementById("description").classList.remove("hidden"),document.getElementById("desc_modal_backdrop").classList.remove("hidden"),document.querySelector("#description .close").focus()):(document.getElementById("description").classList.add("hidden"),document.getElementById("desc_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null)}PopulateData(){let t="",e="";"bar"==constants.chartType?e="Bar chart":"heat"==constants.chartType?e="Heatmap":"box"==constants.chartType?e="Box plot":"scatter"==constants.chartType?e="Scatter plot":"line"==constants.chartType?e="Line chart":"hist"==constants.chartType&&(e="Histogram"),e&&(t+=`<p>Type: ${e}</p>`),null!=plot.title&&(t+=`<p>Title: ${plot.title}</p>`),null!=plot.subtitle&&(t+=`<p>Subtitle: ${plot.subtitle}</p>`),null!=plot.caption&&(t+=`<p>Caption: ${plot.caption}</p>`);let n="",o=null,s=null,i=null,l=null,a=0,r=0,c=0,p=0;if("bar"==constants.chartType&&(null!=plot.plotLegend.x&&(o=plot.plotLegend.x,r+=1),null!=plot.plotLegend.y&&(s=plot.plotLegend.y,p+=1),null!=plot.columnLabels&&(i=plot.columnLabels,p+=1),null!=plot.plotData&&(l=[],l[0]=plot.plotData,a=plot.plotData.length,c=1,r+=a,p+=c)),null!=l){if(n+="<table>",null!=o||null!=i){if(n+="<thead>",null!=o&&(n+="<tr>",null!=s&&(n+="<td></td>"),n+=`<th scope="col" colspan="${a}">${o}</th>`,n+="</tr>"),null!=i){n+="<tr>",null!=s&&(n+="<td></td>");for(let t=0;t<a;t++)n+=`<th scope="col">${i[t]}</th>`;n+="</tr>"}n+="</thead>"}if(c>0){n+="<tbody>";for(let t=0;t<c;t++){n+="<tr>",null!=s&&0==t&&(n+=`<th scope="row" rowspan="${c}">${s}</th>`);for(let e=0;e<a;e++)n+=`<td>${l[t][e]}</td>`;n+="</tr>"}n+="</tbody>"}n+="</table>"}document.getElementById("desc_title").innerHTML=e+" description",document.getElementById("desc_content").innerHTML=t,document.getElementById("desc_table").innerHTML=n}}class Position{constructor(t=0,e=0,n=-1){this.x=t,this.y=e,this.z=n}}class Helper{static containsObject(t,e){for(let n=0;n<e.length;n++)if(e[n]===t)return!0;return!1}}class Tracker{logUrl=constants.baseURL+"log"+constants.code;isLocal=!1;constructor(){this.DataSetup()}DataSetup(){let t=this.GetTrackerData();if(!this.isLocal||!t){let t={};t.userAgent=Object.assign(navigator.userAgent),t.vendor=Object.assign(navigator.vendor),t.language=Object.assign(navigator.language),t.platform=Object.assign(navigator.platform),t.geolocation=Object.assign(navigator.geolocation),t.log_type="system_data",t.events=[],t.settings=[],this.SaveTrackerData(t),this.SaveSettings()}}DownloadTrackerData(){let t=document.createElement("a"),e=this.GetTrackerData(),n=new Blob([JSON.stringify(e)],{type:"text/plain"});t.href=URL.createObjectURL(n),t.download="tracking.json",t.click()}async SaveTrackerData(t){if(console.log("about to save data",t),this.isLocal)localStorage.setItem(constants.project_id,JSON.stringify(t));else try{const e=await fetch(this.logUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);const n=await e.json();return console.log("Data saved successfully:",n),n}catch(t){return console.error("Error saving data:",t),null}}GetTrackerData(){return JSON.parse(localStorage.getItem(constants.project_id))}Delete(){localStorage.removeItem(constants.project_id),this.data=null,constants.debugLevel>0&&console.log("tracking data cleared"),this.DataSetup()}SaveSettings(){let t=JSON.parse(localStorage.getItem("settings_data"));t&&(t.openAIAuthKey="hidden",t.geminiAuthKey="hidden",constants.emailAuthKey&&(t.username=constants.emailAuthKey),this.SetData("settings",t))}LogEvent(t){let e={};if(e.timestamp=Object.assign(t.timeStamp),e.time=Date().toString(),e.key=Object.assign(t.key),e.altKey=Object.assign(t.altKey),e.ctrlKey=Object.assign(t.ctrlKey),e.shiftKey=Object.assign(t.shiftKey),constants.emailAuthKey&&(e.username=Object.assign(constants.emailAuthKey)),t.path&&(e.focus=Object.assign(t.path[0].tagName)),this.isUndefinedOrNull(constants.position)||(e.position=Object.assign(constants.position)),this.isUndefinedOrNull(constants.minX)||(e.min_x=Object.assign(constants.minX)),this.isUndefinedOrNull(constants.maxX)||(e.max_x=Object.assign(constants.maxX)),this.isUndefinedOrNull(constants.minY)||(e.min_y=Object.assign(constants.minY)),this.isUndefinedOrNull(constants.MAX_FREQUENCY)||(e.max_frequency=Object.assign(constants.MAX_FREQUENCY)),this.isUndefinedOrNull(constants.MIN_FREQUENCY)||(e.min_frequency=Object.assign(constants.MIN_FREQUENCY)),this.isUndefinedOrNull(constants.NULL_FREQUENCY)||(e.null_frequency=Object.assign(constants.NULL_FREQUENCY)),this.isUndefinedOrNull(constants.MAX_SPEED)||(e.max_speed=Object.assign(constants.MAX_SPEED)),this.isUndefinedOrNull(constants.MIN_SPEED)||(e.min_speed=Object.assign(constants.MIN_SPEED)),this.isUndefinedOrNull(constants.INTERVAL)||(e.interval=Object.assign(constants.INTERVAL)),this.isUndefinedOrNull(constants.vol)||(e.volume=Object.assign(constants.vol)),this.isUndefinedOrNull(constants.colorSelected)||(e.color=Object.assign(constants.colorSelected)),this.isUndefinedOrNull(constants.brailleDisplayLength)||(e.braille_display_length=Object.assign(constants.brailleDisplayLength)),this.isUndefinedOrNull(constants.duration)||(e.tone_duration=Object.assign(constants.duration)),this.isUndefinedOrNull(constants.AUTOPLAY_DURATION)||(e.AUTOPLAY_DURATION=Object.assign(constants.AUTOPLAY_DURATION)),this.isUndefinedOrNull(constants.autoPlayOutlierRate)||(e.autoplay_outlier_rate=Object.assign(constants.autoPlayOutlierRate)),this.isUndefinedOrNull(constants.autoPlayPointsRate)||(e.autoplay_points_rate=Object.assign(constants.autoPlayPointsRate)),this.isUndefinedOrNull(constants.textMode)||(e.text_mode=Object.assign(constants.textMode)),this.isUndefinedOrNull(constants.sonifMode)||(e.sonification_mode=Object.assign(constants.sonifMode)),this.isUndefinedOrNull(constants.brailleMode)||(e.braille_mode=Object.assign(constants.brailleMode)),this.isUndefinedOrNull(constants.chartType)||(e.chart_type=Object.assign(constants.chartType)),!this.isUndefinedOrNull(constants.infoDiv.innerHTML)){let t=Object.assign(constants.infoDiv.innerHTML);t=t.replaceAll(/<[^>]*>?/gm,""),e.text_display=t}this.isUndefinedOrNull(location.href)||(e.location=Object.assign(location.href));let n="",o="",s="",i="",l="",a="";if("bar"==constants.chartType)this.isUndefinedOrNull(plot.columnLabels[position.x])||(n=plot.columnLabels[position.x]),this.isUndefinedOrNull(plot.plotLegend.x)||(s=plot.plotLegend.x),this.isUndefinedOrNull(plot.plotLegend.y)||(i=plot.plotLegend.y),this.isUndefinedOrNull(plot.plotData[position.x])||(l=plot.plotData[position.x]);else if("heat"==constants.chartType)this.isUndefinedOrNull(plot.x_labels[position.x])||(n=plot.x_labels[position.x].trim()),this.isUndefinedOrNull(plot.y_labels[position.y])||(o=plot.y_labels[position.y].trim()),this.isUndefinedOrNull(plot.x_group_label)||(s=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),this.isUndefinedOrNull(plot.values)||this.isUndefinedOrNull(plot.values[position.x][position.y])||(l=plot.values[position.x][position.y]),this.isUndefinedOrNull(plot.group_labels[2])||(a=plot.group_labels[2]);else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.x:position.y,e="vert"==constants.plotOrientation?position.y:position.x,a=plot.sections[e];this.isUndefinedOrNull(plot.x_group_label)||(s=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),"vert"==constants.plotOrientation?t>-1&&e>-1&&(this.isUndefinedOrNull(a)||(o=a),this.isUndefinedOrNull(plot.x_labels[position.x])||(n=plot.x_labels[position.x]),this.isUndefinedOrNull(plot.plotData[t][a])||(l=plot.plotData[t][a])):t>-1&&e>-1&&(this.isUndefinedOrNull(a)||(n=a),this.isUndefinedOrNull(plot.y_labels[position.y])||(o=plot.y_labels[position.y]),this.isUndefinedOrNull(plot.plotData[t][a])||(l=plot.plotData[t][a]))}else"point"==constants.chartType&&(this.isUndefinedOrNull(plot.x_group_label)||(s=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),this.isUndefinedOrNull(plot.x[position.x])||(n=plot.x[position.x]),this.isUndefinedOrNull(plot.y[position.x])||(o=plot.y[position.x]),l=[n,o]);e.x_tickmark=Object.assign(n),e.y_tickmark=Object.assign(o),e.x_label=Object.assign(s),e.y_label=Object.assign(i),e.value=Object.assign(l),e.fill_value=Object.assign(a),this.SetData("events",e)}SetData(t,e){if(this.isLocal){let n=this.GetTrackerData();["events","ChatHistory","settings"].includes(t)?(n[t]||(n[t]=[]),n[t].push(e)):n[t]=e,this.SaveTrackerData(n)}else e.log_type=t,this.SaveTrackerData(e)}isUndefinedOrNull(t){try{return null==t}catch{return!0}}}class Review{constructor(){}ToggleReviewMode(t=!0){t?(constants.reviewSaveSpot=document.activeElement,constants.review_container.classList.remove("hidden"),constants.reviewSaveBrailleMode=constants.brailleMode,constants.review.focus(),display.announceText("Review on")):(constants.review_container.classList.add("hidden"),"on"==constants.reviewSaveBrailleMode?display.toggleBrailleMode("on"):constants.reviewSaveSpot.focus(),display.announceText("Review off"))}}class LogError{constructor(){}LogAbsentElement(t){console.log(t,"not found. Visual highlighting is turned off.")}LogCriticalElement(t){consolelog(t,"is critical. MAIDR unable to run")}LogDifferentLengths(t,e){console.log(t,"and",e,"do not have the same length. Visual highlighting is turned off.")}LogTooManyElements(t,e){console.log("Too many",t,"elements. Only the first",e,"will be highlighted.")}LogNotArray(t){console.log(t,"is not an array. Visual highlighting is turned off.")}}class Audio{constructor(){this.AudioContext=window.AudioContext||window.webkitAudioContext,this.audioContext=new AudioContext,this.compressor=this.compressorSetup(this.audioContext)}compressorSetup(){let t=this.audioContext.createDynamicsCompressor();t.threshold.value=-50,t.knee.value=40,t.ratio.value=12,t.attack.value=0,t.release.value=.25;let e=this.audioContext.createGain();return e.gain.value=constants.vol,t.connect(e),e.connect(this.audioContext.destination),t}playTone(t=null){let e=constants.duration,n=constants.vol;null!=t&&null!=t.volScale&&(n=t.volScale*constants.vol);let o=0,s=0,i=0,l=0,a="sine";if("bar"==constants.chartType)s=plot.plotData[position.x],o=position.x,i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,constants.minX,constants.maxX,-1,1);else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.x:position.y,e=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);s=Array.isArray(plot.plotData[t][e])?plot.plotData[t][e][position.z]:plot.plotData[t][e],null!=plot.plotData[t][e]?"vert"==constants.plotOrientation?(i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(s,constants.minY,constants.maxY,-1,1)):(i=this.SlideBetween(s,constants.minX,constants.maxX,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(s,constants.minX,constants.maxX,-1,1)):(i=constants.MIN_FREQUENCY,l=0)}else if("heat"==constants.chartType){if(!plot.data||!plot.data[position.y])return;s=plot.data[position.y][position.x],o=position.x,i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,constants.minX,constants.maxX,-1,1)}else if("point"==constants.chartType||"smooth"==constants.chartType){constants.globalMinMax=!0;let t=constants.minY,e=constants.maxY;"smooth"==constants.chartType&&(t=plot.curveMinY,e=plot.curveMaxY),constants.globalMinMax&&(t=Math.min(constants.minY,plot.curveMinY),e=Math.max(constants.maxY,plot.curveMaxY)),"point"==constants.chartType?(s=plot.y[position.x][position.z],n=1==plot.max_count?constants.vol:this.SlideBetween(plot.points_count[position.x][position.z],1,plot.max_count,constants.vol,constants.MAX_VOL),o=position.x,i=this.SlideBetween(s,t,e,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,t,e,-1,1)):"smooth"==constants.chartType&&(s=plot.curvePoints[positionL1.x],o=positionL1.x,i=this.SlideBetween(s,t,e,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,t,e,-1,1))}else if("hist"==constants.chartType)s=plot.plotData[position.x].y,o=plot.plotData[position.x].x,i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,constants.minX,constants.maxX,-1,1);else if("line"==constants.chartType)s=plot.pointValuesY[position.x],o=position.x,i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,constants.minX,constants.maxX,-1,1);else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType){if(s=plot.plotData[position.x][position.y],0==s)return void this.PlayNull();Array.isArray(s)&&(s=s[position.z]),o=position.x,i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,constants.minX,constants.maxX,-1,1),a=["triangle","square","sawtooth","sine"][position.y]}if(constants.debugLevel>5&&(console.log("will play tone at freq",i),"box"==constants.chartType?console.log("based on",constants.minY,"<",s,"<",constants.maxY," | freq min",constants.MIN_FREQUENCY,"max",constants.MAX_FREQUENCY):console.log("based on",constants.minX,"<",s,"<",constants.maxX," | freq min",constants.MIN_FREQUENCY,"max",constants.MAX_FREQUENCY)),"box"==constants.chartType){let t=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);"lower_outlier"!=t&&"upper_outlier"!=t||(e=constants.outlierDuration)}if(this.playOscillator(i,e,l,n,a),"box"==constants.chartType){let t=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);if("q1"==t||"q2"==t||"q3"==t){let t=i/2;this.playOscillator(t,e,l,constants.vol/4,"triangle")}}else"heat"==constants.chartType&&0==s&&this.PlayNull()}playOscillator(t,e,n,o=1,s="sine"){const i=this.audioContext.currentTime,l=this.audioContext.createOscillator();l.type=s,l.frequency.value=parseFloat(t),l.start();const a=this.audioContext.createGain();a.gain.setValueCurveAtTime([.5*o,1*o,.5*o,.5*o,.5*o,.1*o,1e-4*o],i,e);const r=new PannerNode(this.audioContext,{panningModel:"HRTF",distanceModel:"linear",positionX:position.x,positionY:position.y,positionZ:1,plotOrientationX:0,plotOrientationY:0,plotOrientationZ:-1,refDistance:1,maxDistance:1e4,rolloffFactor:10,coneInnerAngle:40,coneOuterAngle:50,coneOuterGain:.4}),c=this.audioContext.createStereoPanner();c.pan.value=n,l.connect(a),a.connect(c),c.connect(r),r.connect(this.compressor),setTimeout((()=>{r.disconnect(),a.disconnect(),l.stop(),l.disconnect()}),1e3*e*2)}playSmooth(t=[600,500,400,300],e=2,n=[-1,0,1],o=1,s="sine"){let i=new Array(3*t.length).fill(.5*o);i.push(1e-4*o);const l=this.audioContext.currentTime,a=this.audioContext.createOscillator();a.type=s,a.frequency.setValueCurveAtTime(t,l,e),a.start(),constants.isSmoothAutoplay=!0,this.smoothGain=this.audioContext.createGain(),this.smoothGain.gain.setValueCurveAtTime(i,l,e);const r=new PannerNode(this.audioContext,{panningModel:"HRTF",distanceModel:"linear",positionX:position.x,positionY:position.y,positionZ:1,plotOrientationX:0,plotOrientationY:0,plotOrientationZ:-1,refDistance:1,maxDistance:1e4,rolloffFactor:10,coneInnerAngle:40,coneOuterAngle:50,coneOuterGain:.4}),c=this.audioContext.createStereoPanner();c.pan.setValueCurveAtTime(n,l,e),a.connect(this.smoothGain),this.smoothGain.connect(c),c.connect(r),r.connect(this.compressor),constants.smoothId=setTimeout((()=>{r.disconnect(),this.smoothGain.disconnect(),a.stop(),a.disconnect(),constants.isSmoothAutoplay=!1}),1e3*e*2)}PlayNull(){let t=constants.NULL_FREQUENCY,e=constants.duration,n=constants.vol,o="triangle";this.playOscillator(t,e,0,n,o),setTimeout((function(s){s.playOscillator(23*t/24,e,0,n,o)}),Math.round(e/5*1e3),this)}playEnd(){if(constants.canPlayEndChime){let t=constants.endChime.cloneNode(!0);t.play(),t=null}}KillSmooth(){constants.smoothId&&(this.smoothGain.gain.cancelScheduledValues(0),this.smoothGain.gain.exponentialRampToValueAtTime(1e-4,this.audioContext.currentTime+.03),clearTimeout(constants.smoothId),constants.isSmoothAutoplay=!1)}SlideBetween(t,e,n,o,s){t=Number(t),e=Number(e),n=Number(n),o=Number(o);let i=(t-e)/(n-e)*((s=Number(s))-o)+o;return 0==e&&0==n&&(i=0),i}}class Display{constructor(){this.infoDiv=constants.infoDiv,this.x={},this.x.id="x",this.x.textBase="x-value: ",this.y={},this.y.id="y",this.y.textBase="y-value: ",this.boxplotGridPlaceholders=[resources.GetString("lower_outlier"),resources.GetString("min"),resources.GetString("25"),resources.GetString("50"),resources.GetString("75"),resources.GetString("max"),resources.GetString("upper_outlier")]}toggleTextMode(){"off"==constants.textMode?constants.textMode="terse":"terse"==constants.textMode?constants.textMode="verbose":"verbose"==constants.textMode&&(constants.textMode="off"),this.announceText('<span aria-hidden="true">Text mode:</span> '+constants.textMode)}toggleBrailleMode(t){if(position.x<0&&(position.x=0),position.y<0&&(position.y=0),"point"!=constants.chartType){if(void 0===t&&(void 0===constants.brailleMode?(constants.brailleMode="off",t="on"==constants.brailleMode):(t="on"==constants.brailleMode?"off":"on",constants.brailleMode=t)),"on"==t){if(constants.lockSelection=!0,"box"==constants.chartType&&("vert"!=constants.plotOrientation&&-1==position.x&&position.y==plot.plotData.length?(position.x+=1,position.y-=1):"vert"==constants.plotOrientation&&0==position.x&&(position.y,plot.plotData[0].length)),constants.brailleMode="on",document.getElementById(constants.braille_container_id).classList.remove("hidden"),constants.brailleInput.focus(),constants.brailleInput.setSelectionRange(position.x,position.x),this.SetBraille(),"heat"==constants.chartType){let t=position.y*(plot.num_cols+1)+position.x;constants.brailleInput.setSelectionRange(t,t)}-1==position.x&&-1==position.y&&constants.brailleInput.setSelectionRange(0,0),setTimeout((function(){constants.lockSelection=!1}),50)}else constants.brailleMode="off",document.getElementById(constants.braille_container_id).classList.add("hidden"),constants.review_container?constants.review_container.classList.contains("hidden")?constants.chart.focus():constants.review.focus():constants.chart.focus();this.announceText("Braille "+constants.brailleMode)}else this.announceText("Braille is not supported in point layer.")}toggleSonificationMode(){"point"==constants.chartType||"stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType?"off"==constants.sonifMode?(constants.sonifMode="on",this.announceText(resources.GetString("son_sep"))):"on"==constants.sonifMode?(constants.sonifMode="same",this.announceText(resources.GetString("son_same"))):"same"==constants.sonifMode&&(constants.sonifMode="off",this.announceText(resources.GetString("son_off"))):"off"==constants.sonifMode?(constants.sonifMode="on",this.announceText(resources.GetString("son_on"))):(constants.sonifMode="off",this.announceText(resources.GetString("son_off")))}changeChartLayer(t="down"){let e=maidr.type;if(Array.isArray(e)){let n=e.indexOf(constants.chartType);"down"==t?0==n||(constants.chartType=e[n-1],this.announceText("Switched to "+constants.chartType)):n==e.length-1||(constants.chartType=e[n+1],this.announceText("Switched to "+constants.chartType))}"point"==constants.chartType?position.x=Math.round((plot.x.length-1)*positionL1.x/(plot.curvePoints.length-1)):"smooth"==constants.chartType&&(positionL1.x=Math.round((plot.curvePoints.length-1)*position.x/(plot.x.length-1)))}announceText(t){this.displayInfo("announce",t,constants.announceContainer)}UpdateBraillePos(){if(constants.lockSelection=!0,"bar"==constants.chartType||"hist"==constants.chartType||"line"==constants.chartType)constants.brailleInput.setSelectionRange(position.x,position.x);else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType){let t=null;t=position.y<plot.plotData[0].length-1?position.x:position.x*(plot.fill.length+1)+position.y,constants.brailleInput.setSelectionRange(t,t)}else if("heat"==constants.chartType){let t=position.y*(plot.num_cols+1)+position.x;constants.brailleInput.setSelectionRange(t,t)}else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.y:position.x,e=this.boxplotGridPlaceholders[t],n=!1,o=0;if(!constants.brailleData)throw"Braille data not set up, cannot move cursor in braille, sorry.";for(let t=0;t<constants.brailleData.length;t++){if("blank"!=constants.brailleData[t].type&&resources.GetString(constants.brailleData[t].type)==e){n=!0;break}o+=constants.brailleData[t].numChars}n||(o=0),constants.brailleInput.setSelectionRange(o,o)}else("smooth"==singleMaidr.type||singleMaidr.type.includes("smooth"))&&constants.brailleInput.setSelectionRange(positionL1.x,positionL1.x);setTimeout((function(){constants.lockSelection=!1}),50)}displayValues(){let t="",e="",n="";if("bar"==constants.chartType)plot.columnLabels[position.x]&&(plot.plotLegend.x.length>0&&(e+=plot.plotLegend.x+" is "),e+=plot.columnLabels[position.x]+", "),plot.plotData[position.x]&&(plot.plotLegend&&(e+=plot.plotLegend.y+" is "),e+=plot.plotData[position.x]),n+="<p>"+plot.columnLabels[position.x]+" "+plot.plotData[position.x]+"</p>\n",e="<p>"+e+"</p>\n";else if("heat"==constants.chartType)1==constants.navigation?(e+=plot.x_group_label+" "+plot.x_labels[position.x]+", "+plot.y_group_label+" "+plot.y_labels[position.y]+", "+plot.fill+" is ",e+=plot.data[position.y][position.x]):(e+=plot.y_group_label+" "+plot.y_labels[position.y]+", "+plot.x_group_label+" "+plot.x_labels[position.x]+", "+plot.fill+" is ",e+=plot.data[position.y][position.x]),1==constants.navigation?n+="<p>"+plot.x_labels[position.x]+", "+plot.data[position.y][position.x]+"</p>\n":n+="<p>"+plot.y_labels[position.y]+", "+plot.data[position.y][position.x]+"</p>\n",e="<p>"+e+"</p>\n";else if("box"==constants.chartType){let t=0,o=1,s=!1,i="vert"==constants.plotOrientation?position.x:position.y,l=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);"lower_outlier"!=l&&"upper_outlier"!=l||(s=!0),null==plot.plotData[i][l]?(t="",s&&(o=0)):s?(t=plot.plotData[i][l].join(", "),o=plot.plotData[i][l].length):t=plot.plotData[i][l],constants.navigation?plot.x_group_label&&(e+=plot.x_group_label):constants.navigation||plot.y_group_label&&(e+=plot.y_group_label),constants.navigation?plot.x_labels[i]?(e+=" is ",n+=plot.x_labels[i]+", ",e+=plot.x_labels[i]+", "):e+=", ":constants.navigation||(plot.y_labels[i]?(e+=" is ",n+=plot.y_labels[i]+", ",e+=plot.y_labels[i]+", "):e+=", "),s&&(n+=o+" ",e+=o+" "),e+=resources.GetString(l),1==o?e+=" is ":(e+="s ",o>1&&(e+=" are ")),(s||constants.navigation&&"horz"==constants.plotOrientation||!constants.navigation&&"vert"==constants.plotOrientation)&&(n+=resources.GetString(l),1!=o&&(n+="s"),n+=" "),null!=plot.plotData[i][l]||s?(n+=t,e+=t):(n+="empty",e+="empty"),e="<p>"+e+"</p>\n",n="<p>"+n+"</p>\n"}else[].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")?("point"==constants.chartType?(e+=plot.x_group_label+" "+plot.x[position.x]+", "+plot.y_group_label+" ["+plot.y[position.x].join(", ")+"]",n+="<p>"+plot.x[position.x]+", ["+plot.y[position.x].join(", ")+"]</p>\n"):"smooth"==constants.chartType&&(e+=plot.x_group_label+" "+plot.curveX[positionL1.x]+", "+plot.y_group_label+" "+plot.curvePoints[positionL1.x],n+="<p>"+plot.curvePoints[positionL1.x]+"<p>\n"),e="<p>"+e+"</p>\n"):"hist"==constants.chartType?(n="<p>"+plot.plotData[position.x].x+", "+plot.plotData[position.x].y+"</p>\n",e="<p>",plot.legendX&&(e=plot.legendX+" is "),e+=plot.plotData[position.x].xmin,e+=" through "+plot.plotData[position.x].xmax+", ",plot.legendY&&(e+=plot.legendY+" is "),e+=plot.plotData[position.x].y):"line"==constants.chartType?(plot.plotLegend&&(e+=plot.plotLegend.x+" is "),e+=plot.pointValuesX[position.x]+", ",plot.plotLegend&&plot.plotLegend.y,e+=plot.pointValuesY[position.x],n+="<p>"+plot.pointValuesX[position.x]+", "+plot.pointValuesY[position.x]+"</p>\n",e="<p>"+e+"</p>\n"):"stacked_bar"!=constants.chartType&&"stacked_normalized_bar"!=constants.chartType&&"dodged_bar"!=constants.chartType||(plot.plotLegend&&(e+=plot.plotLegend.x+" is "),e+=plot.level[position.x]+", ",e+="level is "+plot.fill[position.y]+", ",plot.plotLegend&&(e+=plot.plotLegend.y+" is "),e+=plot.plotData[position.x][position.y],1==constants.navigation?n+="<p>"+plot.level[position.x]+" is "+plot.plotData[position.x][position.y]+"</p>\n":n+="<p>"+plot.fill[position.y]+" is "+plot.plotData[position.x][position.y]+"</p>\n",e="<p>"+e+"</p>\n");"verbose"==constants.textMode?t=e:"terse"==constants.textMode&&(t=n),constants.verboseText=e,t==constants.infoDiv.innerHTML&&(constants.infoDiv.textContent.endsWith(".")?t.endsWith(".</p>")&&(t=t.replace(".</p>","</p>")):t=t.replace("</p>",".</p>")),constants.infoDiv&&(constants.infoDiv.innerHTML="",constants.infoDiv.innerHTML=t),constants.review&&(t.length>0?constants.review.value=t.replace(/<[^>]*>?/gm,""):constants.review.value=e)}displayInfo(t,e,n=constants.infoDiv){let o="";if("announce"==t)e&&(o=e);else if(t)if(e){if("terse"==constants.textMode)o=e;else if("verbose"==constants.textMode){o=t.charAt(0).toUpperCase()+t.slice(1)+" is "+e}}else{o="Plot does not have "+(["a","e","i","o","u"].includes(t.charAt(0))?"an":"a")+" "+t}if(o.length>0){n.innerHTML=null;let t=document.createElement("p");t.innerHTML=o,n.appendChild(t)}}SetBraille(){let t=[];if("heat"==constants.chartType){let e=(constants.maxY-constants.minY)/3,n=constants.minY+e,o=n+e;for(let e=0;e<plot.data.length;e++){for(let s=0;s<plot.data[e].length;s++)0==plot.data[e][s]?t.push("⠀"):plot.data[e][s]<=n?t.push("⠤"):plot.data[e][s]<=o?t.push("⠒"):t.push("⠉");t.push("⠳")}}else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType)if(position.y<plot.plotData[0].length-1){let e=null,n=null;for(let t=0;t<plot.plotData.length;t++)0==t?(e=plot.plotData[t][position.y],n=plot.plotData[t][position.y]):(plot.plotData[t][position.y]<e&&(e=plot.plotData[t][position.y]),plot.plotData[t][position.y]>n&&(n=plot.plotData[t][position.y]));let o=(n-e)/4,s=e+o,i=s+o,l=i+o;for(let e=0;e<plot.plotData.length;e++)0==plot.plotData[e][position.y]?t.push("⠀"):plot.plotData[e][position.y]<=s?t.push("⣀"):plot.plotData[e][position.y]<=i?t.push("⠤"):plot.plotData[e][position.y]<=l?t.push("⠒"):t.push("⠉")}else for(let e=0;e<plot.plotData.length;e++){let n=(constants.maxY-constants.minY)/4,o=constants.minY+n,s=o+n,i=s+n;for(let n=0;n<plot.plotData[e].length;n++)0==plot.plotData[e][n]?t.push("⠀"):plot.plotData[e][n]<=o?t.push("⣀"):plot.plotData[e][n]<=s?t.push("⠤"):plot.plotData[e][n]<=i?t.push("⠒"):t.push("⠉");t.push("⠳")}else if("bar"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,o=n+e,s=o+e;for(let e=0;e<plot.plotData.length;e++)plot.plotData[e]<=n?t.push("⣀"):plot.plotData[e]<=o?t.push("⠤"):plot.plotData[e]<=s?t.push("⠒"):t.push("⠉")}else if("smooth"==constants.chartType){let e=(plot.curveMaxY-plot.curveMinY)/4,n=plot.curveMinY+e,o=n+e,s=o+e,i=s+e;for(let e=0;e<plot.curvePoints.length;e++)plot.curvePoints[e]<=n?t.push("⣀"):plot.curvePoints[e]<=o?t.push("⠤"):plot.curvePoints[e]<=s?t.push("⠒"):plot.curvePoints[e]<=i&&t.push("⠉")}else if("hist"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,o=n+e,s=o+e;for(let e=0;e<plot.plotData.length;e++)plot.plotData[e].y<=n?t.push("⣀"):plot.plotData[e].y<=o?t.push("⠤"):plot.plotData[e].y<=s?t.push("⠒"):t.push("⠉")}else if("box"==constants.chartType&&position.y>-1){let e,n,o,s=plot.sections.length;if("vert"==constants.plotOrientation?(e=position.x,n=constants.minY,o=constants.maxY):(e=position.y,n=constants.minX,o=constants.maxX),e<0||e>=plot.plotData.length)return;let i=[];i.push({type:"global_min",value:n});for(let t=0;t<s;t++){let n=plot.sections[t],o=plot.plotData[e][n],s={};if(null!=o)if("lower_outlier"==n||"upper_outlier"==n)for(let t=0;t<o.length;t++)s={type:n,value:o[t]},i.push(s);else s={type:n,value:o},i.push(s)}i.push({type:"global_max",value:o});let l=[],a=!0;for(let t=0;t<i.length;t++){let e;e=a?Math.abs(i[t+1].value-i[t].value):Math.abs(i[t].value-i[t-1].value),"global_min"==i[t].type||"global_max"==i[t].type?l.push({type:"blank",length:e}):"lower_outlier"==i[t].type?(l.push({type:i[t].type,length:0}),l.push({type:"blank",length:e})):"upper_outlier"==i[t].type?(l.push({type:"blank",length:e}),l.push({type:i[t].type,length:0})):"q2"==i[t].type?(a=!1,l.push({type:i[t].type,length:0})):l.push({type:i[t].type,length:e})}let r=-1,c=-1,p=-1,d=-1,u=0;for(let t=0;t<l.length;t++)"blank"!=l[t].type&&(l[t].length>0||"lower_outlier"==l[t].type||"upper_outlier"==l[t].type)?(l[t].numChars=1,u++):l[t].numChars=0,"min"==l[t].type&&l[t].length>0&&(r=t),"max"==l[t].type&&l[t].length>0&&(d=t),"q1"==l[t].type&&(c=t),"q3"==l[t].type&&(p=t),"q2"==l[t].type&&(l[t].numChars=2,u++);r>-1&&d>-1&&l[r].length!=l[d].length&&(l[r].length>l[d].length?(l[r].numChars++,u++):(l[d].numChars++,u++)),l[c].length!=l[p].length&&(l[c].length>l[p].length?(l[c].numChars++,u++):(l[p].numChars++,u++));let h=constants.brailleDisplayLength-u;h<5&&(h=5);let y=this.AllocateCharacters(l,h),g=l;for(let t=0;t<y.length;t++)y[t]&&(g[t].numChars+=y[t]);constants.brailleData=g,constants.debugLevel>5&&(console.log("plotData[i]",plot.plotData[e]),console.log("valData",i),console.log("lenData",l),console.log("brailleData",g));for(let e=0;e<g.length;e++)for(let n=0;n<g[e].numChars;n++){let o="⠀";"min"==g[e].type||"max"==g[e].type?o="⠒":"q1"==g[e].type||"q3"==g[e].type?o="⠿":"q2"==g[e].type?o=0==n?"⠸":"⠇":"lower_outlier"!=g[e].type&&"upper_outlier"!=g[e].type||(o="⠂"),t.push(o)}}else if("line"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,o=n+e,s=o+e,i=s+e;for(let e=0;e<plot.pointValuesY.length;e++)plot.pointValuesY[e]<=n&&e-1>=0&&plot.pointValuesY[e-1]>n?plot.pointValuesY[e-1]<=o?t.push("⢄"):plot.pointValuesY[e-1]<=s?t.push("⢆"):plot.pointValuesY[e-1]>s&&t.push("⢇"):plot.pointValuesY[e]<=n?t.push("⣀"):e-1>=0&&plot.pointValuesY[e-1]<=n?plot.pointValuesY[e]<=o?t.push("⡠"):plot.pointValuesY[e]<=s?t.push("⡰"):plot.pointValuesY[e]>s&&t.push("⡸"):plot.pointValuesY[e]<=o&&e-1>=0&&plot.pointValuesY[e-1]>o?plot.pointValuesY[e-1]<=s?t.push("⠢"):plot.pointValuesY[e-1]>s&&t.push("⠣"):plot.pointValuesY[e]<=o?t.push("⠤"):e-1>=0&&plot.pointValuesY[e-1]<=o?plot.pointValuesY[e]<=s?t.push("⠔"):plot.pointValuesY[e]>s&&t.push("⠜"):plot.pointValuesY[e]<=s&&e-1>=0&&plot.pointValuesY[e-1]>s?t.push("⠑"):plot.pointValuesY[e]<=s?t.push("⠒"):e-1>=0&&plot.pointValuesY[e-1]<=s?t.push("⠊"):plot.pointValuesY[e]<=i&&t.push("⠉")}constants.brailleInput.value=t.join(""),constants.debugLevel>5&&console.log("braille:",constants.brailleInput.value),this.UpdateBraillePos()}CharLenImpact(t){return t.length/t.numChars}AllocateCharacters(t,e){let n=[],o=0;for(let e=0;e<t.length;e++)o+=t[e].length;let s=["lower_outlier","upper_outlier","50"];for(let i=0;i<t.length;i++)s.includes(t[i].type)||(n[i]=Math.round(t[i].length/o*e));let i=n.reduce(((t,e)=>t+e),0),l=e-i,a=t.length;for(;0!==l&&a>0;){for(let e=0;e<t.length;e++)s.includes(t[e].type)||(n[e]+=Math.round(t[e].length/o*l));i=n.reduce(((t,e)=>t+e),0),l=e-i,a--}if(0!==l){let e=[];for(let n=0;n<t.length;n++)e.push(n);e.sort(((t,e)=>n[t]-n[e]));let o=-1;l>0&&(o=1);let s=0,i=3*e.length;for(;l>0&&i>0;)n[e[s]]+=o,l+=-o,s+=1,s>=e.length&&(s=0),i+=-1}return n}}class BarChart{constructor(){let t=null;"axes"in singleMaidr&&singleMaidr.axes.x&&singleMaidr.axes.x.level&&(t=singleMaidr.axes.x.level);let e=null;"data"in singleMaidr&&(e=singleMaidr.data);let n=null;"selector"in singleMaidr?n=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(n=singleMaidr.elements),t&&e&&n?n.length!=e.length?(constants.hasRect=0,logError.LogDifferentLengths("elements","data")):t.length!=n.length?(constants.hasRect=0,logError.LogDifferentLengths("x level","elements")):e.length!=t.length?(constants.hasRect=0,logError.LogDifferentLengths("x level","data")):(this.bars=n,constants.hasRect=1):e&&n?e.length!=n.length?(constants.hasRect=0,logError.LogDifferentLengths("data","elements")):(this.bars=n,constants.hasRect=1):t&&e?(t.length!=e.length&&(constants.hasRect=0,logError.LogDifferentLengths("x level","data")),logError.LogAbsentElement("elements")):e&&(logError.LogAbsentElement("x level"),logError.LogAbsentElement("elements")),this.columnLabels=[];let o="",s="";"labels"in singleMaidr&&("x"in singleMaidr.labels&&(o=singleMaidr.labels.x),"y"in singleMaidr.labels&&(s=singleMaidr.labels.y)),"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&""==o&&(o=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&""==s&&(s=singleMaidr.axes.y.label),singleMaidr.axes.x&&singleMaidr.axes.x.level&&(this.columnLabels=singleMaidr.axes.x.level),singleMaidr.axes.y&&singleMaidr.axes.y.level&&(this.columnLabels=singleMaidr.axes.y.level)),this.plotLegend={x:o,y:s},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),Array.isArray(singleMaidr)?this.plotData=singleMaidr:"data"in singleMaidr&&(this.plotData=singleMaidr.data),this.SetMaxMin(),this.autoplay=null}SetMaxMin(){for(let t=0;t<this.plotData.length;t++)0==t?(constants.maxY=this.plotData[t],constants.minY=this.plotData[t]):(this.plotData[t]>constants.maxY&&(constants.maxY=this.plotData[t]),this.plotData[t]<constants.minY&&(constants.minY=this.plotData[t]));constants.maxX=this.columnLabels.length,constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/this.plotData.length),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}PlayTones(){audio.playTone()}GetLegendFromManualData(){let t={};return t.x=barplotLegend.x,t.y=barplotLegend.y,t}GetData(){let t=[];if(this.bars)for(let e=0;e<this.bars.length;e++)t.push(this.bars[e].getAttribute("height"));return t}GetColumns(){let t=[],e=constants.chart.querySelectorAll('tspan[dy="10"]');for(var n=0;n<e.length;n++)t.push(e[n].innerHTML);return t}GetLegend(){let t={},e=constants.chart.querySelectorAll('tspan[dy="12"]');return t.x=e[1].innerHTML,t.y=e[0].innerHTML,t}ParseInnerHTML(t){let e=[];for(var n=0;n<t.length;n++)e.push(t[n].innerHTML);return e}Select(){if(this.UnSelectPrevious(),this.bars&&(this.activeElement=this.bars[position.x],this.activeElement))if(this.activeElement.hasAttribute("fill"))this.activeElementColor=this.activeElement.getAttribute("fill"),this.activeElement.setAttribute("fill",constants.GetBetterColor(this.activeElementColor));else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);this.activeElementColor=e[e.indexOf("fill")+1],e[e.indexOf("fill")+1]=constants.GetBetterColor(this.activeElementColor),t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t)}}UnSelectPrevious(){if(this.activeElement)if(this.activeElement.hasAttribute("fill"))this.activeElement.setAttribute("fill",this.activeElementColor),this.activeElement=null;else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);e[e.indexOf("fill")+1]=this.activeElementColor,t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t),this.activeElement=null}}}class BoxPlot{constructor(){if(this.sections=["lower_outlier","min","q1","q2","q3","max","upper_outlier"],constants.plotOrientation="horz","axes"in singleMaidr&&"x"in singleMaidr.axes&&"level"in singleMaidr.axes.x&&(constants.plotOrientation="vert"),this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),this.subtitle="","labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),this.caption="","labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),"labels"in singleMaidr&&(this.x_group_label||"x"in singleMaidr.labels&&(this.x_group_label=singleMaidr.labels.x),this.y_group_label||"y"in singleMaidr.labels&&(this.y_group_label=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&("label"in singleMaidr.axes.x&&(this.x_group_label||(this.x_group_label=singleMaidr.axes.x.label)),"level"in singleMaidr.axes.x?this.x_labels=singleMaidr.axes.x.level:this.x_labels=[]),"y"in singleMaidr.axes&&("label"in singleMaidr.axes.y&&(this.y_group_label||(this.y_group_label=singleMaidr.axes.y.label)),"level"in singleMaidr.axes.y?this.y_labels=singleMaidr.axes.y.level:this.y_labels=[])),this.plotData=singleMaidr.data,"selector"in singleMaidr){let t=document.querySelector(singleMaidr.selector);this.plotBounds=this.GetPlotBounds(t),constants.hasRect=!0}else"elements"in singleMaidr?(this.plotBounds=this.GetPlotBounds(singleMaidr.elements),constants.hasRect=!0):constants.hasRect=!1;this.CleanData()}CleanData(){let t,e;for(let n=0;n<this.plotData.length;n++){if(this.plotData[n].lower_outlier){let o=Math.min(...this.plotData[n].lower_outlier),s=Math.max(...this.plotData[n].lower_outlier);(null==t||o<t)&&(t=o),(null==e||s>e)&&(e=s)}if(this.plotData[n].min&&((null==t||this.plotData[n].min<t)&&(t=this.plotData[n].min),(null==e||this.plotData[n].max>e)&&(e=this.plotData[n].max)),this.plotData[n].q1&&((null==t||this.plotData[n].q1<t)&&(t=this.plotData[n].q1),(null==e||this.plotData[n].q1>e)&&(e=this.plotData[n].q1)),this.plotData[n].q2&&((null==t||this.plotData[n].q2<t)&&(t=this.plotData[n].q2),(null==e||this.plotData[n].q2>e)&&(e=this.plotData[n].q2)),this.plotData[n].q3&&((null==t||this.plotData[n].q3<t)&&(t=this.plotData[n].q3),(null==e||this.plotData[n].q3>e)&&(e=this.plotData[n].q3)),this.plotData[n].max&&((null==t||this.plotData[n].max<t)&&(t=this.plotData[n].max),(null==e||this.plotData[n].max>e)&&(e=this.plotData[n].max)),this.plotData[n].upper_outlier){let o=Math.min(...this.plotData[n].upper_outlier),s=Math.max(...this.plotData[n].upper_outlier);(null==t||o<t)&&(t=o),(null==e||s>e)&&(e=s)}}"vert"==constants.plotOrientation?(constants.minY=t,constants.maxY=e,constants.minX=0,constants.maxX=this.plotData.length-1):(constants.minX=t,constants.maxX=e,constants.minY=0,constants.maxY=this.plotData.length-1),constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/7),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}GetPlotBounds(t){let e=[],n=this.GetAllSegmentTypes(),o=/(?:\d+(?:\.\d*)?|\.\d+)/g,s=[],i=t.children;for(let t=0;t<i.length;t++){let e={},n=i[t].children;for(let t=0;t<n.length;t++){e[this.GetBoxplotSegmentType(n[t].getAttribute("id"))]=n[t]}s.push(e)}for(let t=0;t<s.length;t++){let i=[],l=s[t].range.getBoundingClientRect(),a=s[t].range.querySelector('polyline[id^="GRID"]').getAttribute("points").match(o),r=s[t].range.querySelector('polygon[id^="geom_polygon"]').getAttribute("points").match(o),c=0;c="vert"==constants.plotOrientation?(a[1]-r[3])/(r[1]-r[3]):(a[0]-r[2])/(r[0]-r[2]),c=Number.isNaN(c)?0:c;let p=0;if(p="vert"==constants.plotOrientation?l.height*c:l.width*c,i[2]=this.convertBoundingClientRectToObj(l),i[2].label=n[2],i[2].type="range","vert"==constants.plotOrientation?(i[2].height=p,i[2].top=i[2].bottom-p,i[2].y=i[2].top):i[2].width=p,i[3]=this.convertBoundingClientRectToObj(l),i[3].label=n[3],i[3].type="range","vert"==constants.plotOrientation?(i[3].height=0,i[3].top=l.bottom-p,i[3].y=i[3].top,i[3].bottom=i[3].top):(i[3].width=0,i[3].left=l.left+p),i[4]=this.convertBoundingClientRectToObj(l),i[4].label=n[4],i[4].type="range","vert"==constants.plotOrientation?(i[4].height=l.height-p,i[4].bottom=i[3].top):(i[4].width=l.width-p,i[4].left=i[3].left),Object.hasOwn(s[t],"whisker")){let e=s[t].whisker.getBoundingClientRect(),o=!1,a=!1;"vert"==constants.plotOrientation?(e.bottom>l.bottom&&(o=!0),e.top<l.top&&(a=!0)):(e.left<l.left&&(o=!0),e.right>l.right&&(a=!0)),o?(i[1]=this.convertBoundingClientRectToObj(e),i[1].label=n[1],i[1].type="whisker","vert"==constants.plotOrientation?(i[1].top=i[2].bottom,i[1].y=i[1].top,i[1].height=i[1].bottom-i[1].top):i[1].width=i[2].left-i[1].left):(i[1]={},i[1].label=n[1],i[1].type="blank"),a?(i[5]=this.convertBoundingClientRectToObj(e),i[5].label=n[5],i[5].type="whisker","vert"==constants.plotOrientation?(i[5].bottom=i[4].top,i[5].height=i[5].bottom-i[5].top):(i[5].left=i[4].right,i[5].x=i[4].right,i[5].width=i[5].right-i[5].left)):(i[5]={},i[5].label=n[5],i[5].type="blank")}if(Object.hasOwn(s[t],"outlier")){let e=s[t].outlier.children,o=null,a=null;for(let t=0;t<e.length;t++){let n=e[t].getBoundingClientRect();"vert"==constants.plotOrientation?n.y<l.y?o?(n.y<o.y&&(o.y=n.y),n.top<o.top&&(o.top=n.top),n.bottom>o.bottom&&(o.bottom=n.bottom)):o=this.convertBoundingClientRectToObj(n):a?(n.y<a.y&&(a.y=n.y),n.top<a.top&&(a.top=n.top),n.bottom>a.bottom&&(a.bottom=n.bottom)):a=this.convertBoundingClientRectToObj(n):n.x>l.x?o?(n.x<o.x&&(o.x=n.x),n.left<o.left&&(o.left=n.left),n.right>o.right&&(o.right=n.right)):o=this.convertBoundingClientRectToObj(n):a?(n.x<a.x&&(a.x=n.x),n.left<a.left&&(a.left=n.left),n.right>a.right&&(a.right=n.right)):a=this.convertBoundingClientRectToObj(n)}a?(a.height=a.bottom-a.top,a.width=a.right-a.left,i[0]=this.convertBoundingClientRectToObj(a),i[0].label=n[0],i[0].type="outlier"):(i[0]={},i[0].label=n[0],i[0].type="blank"),o?(o.height=o.bottom-o.top,o.width=o.right-o.left,i[6]=this.convertBoundingClientRectToObj(o),i[6].label=n[6],i[6].type="outlier"):(i[6]={},i[6].label=n[6],i[6].type="blank")}else i[0]={},i[0].label=n[0],i[0].type="blank",i[6]={},i[6].label=n[6],i[6].type="blank";e.push(i)}return constants.debugLevel>5&&console.log("plotBounds",e),e}GetAllSegmentTypes(){let t=[];for(let e=0;e<this.sections.length;e++)t.push(resources.GetString(this.sections[e]));return t}GetBoxplotSegmentType(t){let e="outlier";return t.includes("geom_crossbar")?e="range":t.includes("GRID")?e="whisker":t.includes("points")&&(e="outlier"),e}GetBoxplotSegmentPoints(t,e){let n=/(?:\d+(?:\.\d*)?|\.\d+)/g,o=[];if("range"==e){let e=t.children[0].getAttribute("points").match(n);o.push(e[0],e[1]),e[0]!=e[2]&&o.push(e[2],e[3])}else if("outlier"==e)o.push(t.getAttribute("x"),t.getAttribute("y"));else{let e=t.getAttribute("points").match(n);"vert"==constants.plotOrientation?e[1]!=e[3]&&o.push(e[0],e[1],e[2],e[3]):e[0]!=e[2]&&o.push(e[0],e[1],e[2],e[3])}return o}GetAllSegmentTypes(){return[resources.GetString("lower_outlier"),resources.GetString("min"),resources.GetString("25"),resources.GetString("50"),resources.GetString("75"),resources.GetString("max"),resources.GetString("upper_outlier")]}convertBoundingClientRectToObj(t){return{top:t.top,right:t.right,bottom:t.bottom,left:t.left,width:t.width,height:t.height,x:t.x,y:t.y}}PlayTones(){let t=null,e=null;constants.outlierInterval&&clearInterval(constants.outlierInterval),"vert"==constants.plotOrientation?(t=position.x,e=this.GetSectionKey(position.y)):(t=position.y,e=this.GetSectionKey(position.x)),null==plot.plotData[t][e]?audio.PlayNull():"lower_outlier"!=e&&"upper_outlier"!=e?audio.playTone():0==plot.plotData[t][e].length?audio.PlayNull():(position.z=0,constants.outlierInterval=setInterval((function(){audio.playTone(),position.z+=1,(null==plot.plotData[t][e]||position.z+1>plot.plotData[t][e].length)&&(clearInterval(constants.outlierInterval),position.z=-1)}),constants.autoPlayOutlierRate))}GetSectionKey(t){return this.sections[t]}}class BoxplotRect{rectPadding=15;rectStrokeWidth=4;constructor(){this.x1=0,this.width=0,this.y1=0,this.height=0,this.chartOffsetLeft=constants.chart.getBoundingClientRect().left,this.chartOffsetTop=constants.chart.getBoundingClientRect().top}UpdateRect(){document.getElementById("highlight_rect")&&document.getElementById("highlight_rect").remove();let t=position.x,e=position.y,n=plot.GetSectionKey(position.y);if("vert"==constants.plotOrientation||(t=position.y,e=position.x,n=plot.GetSectionKey(position.x)),"vert"==constants.plotOrientation&&position.y>-1||"horz"==constants.plotOrientation&&position.x>-1){let o=plot.plotBounds[t][e];"blank"!=o.type&&(this.x1=o.left-this.rectPadding-this.chartOffsetLeft,this.width=o.width+2*this.rectPadding,this.y1=o.top-this.rectPadding-this.chartOffsetTop,this.height=o.height+2*this.rectPadding,constants.debugLevel>5&&(console.log("Point",n,"bottom:",o.bottom,"top:",o.top),console.log("x1:",this.x1,"y1:",this.y1,"width:",this.width,"height:",this.height)),this.CreateRectDisplay())}}CreateRectDisplay(){let t=document.createElementNS("http://www.w3.org/2000/svg","rect");t.setAttribute("id","highlight_rect"),t.setAttribute("x",this.x1),t.setAttribute("y",this.y1),t.setAttribute("width",this.width),t.setAttribute("height",this.height),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.rectStrokeWidth),t.setAttribute("fill","none"),constants.chart.appendChild(t)}}class HeatMap{constructor(){let t=null,e=null;"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.level&&(t=singleMaidr.axes.x.level),singleMaidr.axes.y&&singleMaidr.axes.y.level&&(e=singleMaidr.axes.y.level)),"data"in singleMaidr?(this.data=singleMaidr.data,this.num_rows=this.data.length,this.num_cols=this.data[0].length):console.error("No data found in singleMaidr object"),"selector"in singleMaidr?(this.elements=document.querySelectorAll(singleMaidr.selector),constants.hasRect=1):"elements"in singleMaidr?(this.elements=singleMaidr.elements,constants.hasRect=1):(this.elements=null,constants.hasRect=0),this.group_labels=this.getGroupLabels(),this.x_labels=t,this.y_labels=e,this.title=this.getTitle(),this.fill=this.getFill(),constants.hasRect&&this.SetHeatmapRectData(),this.updateConstants(),this.x_group_label=this.group_labels[0].trim(),this.y_group_label=this.group_labels[1].trim()}SetHeatmapRectData(){let t=[],e=[],n=[],o=[];for(let n=0;n<this.elements.length;n++)if(this.elements[n])if(this.elements[n]instanceof SVGPathElement){const o=this.elements[n].getAttribute("d"),s=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(o),i=[Number(s[1]),Number(s[3])],l=i[0],a=i[1];t.push(parseFloat(l)),e.push(parseFloat(a))}else t.push(parseFloat(this.elements[n].getAttribute("x"))),e.push(parseFloat(this.elements[n].getAttribute("y")));t.sort((function(t,e){return t-e})),e.sort((function(t,e){return t-e}));let s=this.GetSVGScaler();-1==s[0]&&(t=t.reverse()),-1==s[1]&&(e=e.reverse()),n=[...new Set(t)],o=[...new Set(e)],this.x_coord=n,this.y_coord=o}updateConstants(){constants.minX=0,constants.maxX=this.data[0].length-1,constants.minY=Math.min(...this.data.map((t=>Math.min(...t)))),constants.maxY=Math.max(...this.data.map((t=>Math.max(...t)))),constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}PlayTones(){audio.playTone()}GetSVGScaler(){let t=1,e=1,n=!1,o=this.elements[0];for(;o&&"body"!=o.tagName.toLowerCase();)o.tagName&&"svg"===o.tagName.toLowerCase()&&(n=!0),o=o.parentNode;if(n){let n=this.elements[0];for(;n&&"body"!=n.tagName.toLowerCase();){if(n.getAttribute("transform")){let o=n.getAttribute("transform").match(/scale\((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)\)/);o&&(isNaN(o[1])||(t*=parseFloat(o[1])),isNaN(o[3])||(e*=parseFloat(o[3])))}n=n.parentNode}}return[t,e]}getRGBNorm(t){return this.elements[t].getAttribute("fill").slice(4,-1).split(",").map((function(t){return Math.pow(t,2)})).reduce((function(t,e){return t+e}))}getGroupLabels(){let t,e="",n="";return"labels"in singleMaidr&&("x"in singleMaidr.labels&&(e=singleMaidr.labels.x),"y"in singleMaidr.labels&&(n=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&"label"in singleMaidr.axes.x&&""==e&&(e=singleMaidr.axes.x.label),"y"in singleMaidr.axes&&"label"in singleMaidr.axes.y&&""==n&&(n=singleMaidr.axes.y.label)),t=[e,n],t}getXLabels(){if("axes"in singleMaidr&&"x"in singleMaidr.axes&&"level"in singleMaidr.axes.x)return singleMaidr.axes.x.level}getYLabels(){if("axes"in singleMaidr&&"y"in singleMaidr.axes&&"level"in singleMaidr.axes.y)return singleMaidr.axes.y.level}getTitle(){return"title"in singleMaidr?singleMaidr.title:"labels"in singleMaidr&&"title"in singleMaidr.labels?singleMaidr.labels.title:void 0}getSubtitle(){if("labels"in singleMaidr&&"subtitle"in singleMaidr.labels)return singleMaidr.labels.subtitle}getCaption(){if("labels"in singleMaidr&&"caption"in singleMaidr.labels)return singleMaidr.labels.caption}getFill(){if("labels"in singleMaidr&&"fill"in singleMaidr.labels)return singleMaidr.labels.fill}}class HeatMapRect{constructor(){constants.hasRect&&(this.x=plot.x_coord[0],this.y=plot.y_coord[0],this.squareIndex=0,this.rectStrokeWidth=4,this.height=Math.abs(plot.y_coord[1]-plot.y_coord[0]),this.width=Math.abs(plot.x_coord[1]-plot.x_coord[0]))}UpdateRect(){this.x=plot.x_coord[position.x],this.y=plot.y_coord[position.y];for(let t=0;t<plot.elements.length;t++)if(plot.elements[t].getAttribute("x")==this.x&&plot.elements[t].getAttribute("y")==this.y){this.squareIndex=t;break}}UpdateRectDisplay(){this.UpdateRect(),document.getElementById("highlight_rect")&&document.getElementById("highlight_rect").remove();var t=document.createElementNS("http://www.w3.org/2000/svg","rect");t.setAttribute("id","highlight_rect"),t.setAttribute("x",this.x),t.setAttribute("y",void 0===this.y?0:this.y),t.setAttribute("width",this.width),t.setAttribute("height",this.height),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.rectStrokeWidth),t.setAttribute("fill","none"),plot.elements[this.squareIndex].parentNode.appendChild(t)}}class ScatterPlot{constructor(){this.prefix=this.GetPrefix(),this.SetScatterLayer(),this.SetLineLayer(),this.SetAxes(),this.svgScaler=this.GetSVGScaler()}SetAxes(){this.x_group_label="",this.y_group_label="",this.title="","labels"in singleMaidr&&("x"in singleMaidr.labels&&(this.x_group_label=singleMaidr.labels.x),"y"in singleMaidr.labels&&(this.y_group_label=singleMaidr.labels.y),"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&""==this.x_group_label&&(this.x_group_label=singleMaidr.axes.x.label),"y"in singleMaidr.axes&&""==this.y_group_label&&(this.y_group_label=singleMaidr.axes.y.label)),"title"in singleMaidr&&""==this.title&&(this.title=singleMaidr.title)}SetScatterLayer(){let t=this.GetElementIndex("point");-1!=t?"selector"in singleMaidr?this.plotPoints=document.querySelectorAll(singleMaidr.selector[t]):"elements"in singleMaidr&&(this.plotPoints=singleMaidr.elements[t]):"point"==singleMaidr.type&&("selector"in singleMaidr?this.plotPoints=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(this.plotPoints=singleMaidr.elements));let e=this.GetSvgPointCoords(),n=this.GetPointValues();this.chartPointsX=e[0],this.chartPointsY=e[1],this.x=n[0],this.y=n[1],this.points_count=n[2],this.max_count=n[3]}SetLineLayer(){let t=this.GetElementIndex("smooth");-1!=t?"selector"in singleMaidr?this.plotLine=document.querySelectorAll(singleMaidr.selector[t])[0]:"elements"in singleMaidr&&(this.plotLine=singleMaidr.elements[t][0]):"smooth"==singleMaidr.type&&("selector"in singleMaidr?this.plotLine=document.querySelectorAll(singleMaidr.selector)[0]:"elements"in singleMaidr&&(this.plotLine=singleMaidr.elements));let e=this.GetSvgLineCoords(),n=this.GetSmoothCurvePoints();this.chartLineX=e[0],this.chartLineY=e[1],this.curveX=n[0],this.curvePoints=n[1],this.curvePoints&&this.curvePoints.length>0?(this.curveMinY=Math.min(...this.curvePoints),this.curveMaxY=Math.max(...this.curvePoints)):(this.curveMinY=Number.MAX_VALUE,this.curveMaxY=Number.MIN_VALUE),this.gradient=this.GetGradient()}GetSvgPointCoords(){let t=new Map;if(this.plotPoints)for(let e=0;e<this.plotPoints.length;e++){let n,o;if(this.plotPoints[e]instanceof SVGPathElement){let t=this.plotPoints[e].getAttribute("d"),s=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(s[1]),o=parseFloat(s[3])}else n=parseFloat(this.plotPoints[e].getAttribute(this.prefix+"x")),o=parseFloat(this.plotPoints[e].getAttribute(this.prefix+"y"));t.has(n)?t.get(n).add(o):t.set(n,new Set([o]))}else if([].concat(singleMaidr.type).includes("point")){let e,n=this.GetElementIndex("point"),o=this.GetDataXYFormat(n);e=n>-1?singleMaidr.data[n]:singleMaidr.data;let s=[],i=[];if("array"==o)"x"in e&&(s=e.x),"y"in e&&(i=e.y);else if("object"==o)for(let t=0;t<e.length;t++){let n=e[t].x,o=e[t].y;s.push(n),i.push(o)}for(let e=0;e<s.length;e++){let n=s[e],o=i[e];t.has(n)?t.get(n).add(o):t.set(n,new Set([o]))}}t=new Map([...t].sort((function(t,e){return t[0]-e[0]}))),t.forEach((function(e,n){t[n]=Array.from(e).sort((function(t,e){return t-e}))}));let e=[...t.keys()],n=[];for(let o=0;o<e.length;o++)n.push(t[e[o]]);return[e,n]}GetElementIndex(t="point"){let e=-1;return"type"in singleMaidr&&Array.isArray(singleMaidr.type)&&(e=singleMaidr.type.indexOf(t)),e}GetDataXYFormat(t){let e,n;return e=t>-1?singleMaidr.data[t]:singleMaidr.data,n=Array.isArray(e)?"object":"array",n}GetSVGScaler(){let t=1,e=1,n=!1;if(this.plotPoints){let o=this.plotPoints[0];for(;o&&"body"!=o.tagName.toLowerCase();)o.tagName&&"svg"===o.tagName.toLowerCase()&&(n=!0),o=o.parentNode;if(n){let n=this.plotPoints[0];for(;n&&"body"!=n.tagName.toLowerCase();){if(n.getAttribute("transform")){let o=n.getAttribute("transform").match(/scale\((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)\)/);o&&(isNaN(o[1])||(t*=parseFloat(o[1])),isNaN(o[3])||(e*=parseFloat(o[3])))}n=n.parentNode}}}return[t,e]}GetPrefix(){let t=this.GetElementIndex("point"),e=null;-1!=t?"selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector[t])[0]:"elements"in singleMaidr&&(e=singleMaidr.elements[t][0]):"point"==singleMaidr.type&&("selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector)[0]:"elements"in singleMaidr&&(e=singleMaidr.elements[0]));let n="";return e&&"circle"===e.tagName.toLowerCase()&&(n="c"),n}GetPointValues(){let t,e,n=new Map,o=[],s=[],i=[],l=this.GetElementIndex("point"),a=this.GetDataXYFormat(l);if(l>-1?e=singleMaidr.data[l]:"point"==singleMaidr.type&&(e=singleMaidr.data),void 0!==e){let l=[],r=[];if("array"==a)"x"in e&&(l=e.x),"y"in e&&(r=e.y);else if("object"==a)for(let t=0;t<e.length;t++){let n=e[t].x,o=e[t].y;l.push(n),r.push(o)}for(let t=0;t<l.length;t++){let e=l[t],o=r[t];if(n.has(e))if(n.get(e).has(o)){let t=n.get(e);t.set(o,t.get(o)+1)}else n.get(e).set(o,1);else n.set(e,new Map([[o,1]]))}constants.minX=0,constants.maxX=[...new Set(l)].length,constants.minY=Math.min(...r),constants.maxY=Math.max(...r),constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate),n=new Map([...n].sort((function(t,e){return t[0]-e[0]}))),n.forEach((function(t,e){n[e]=Array.from(t).sort((function(t,e){return t[0]-e[0]}))}));for(const[t,e]of n){o.push(t);let n=[],l=[];for(const[t,o]of e)n.push(t),l.push(o);s.push(n.sort()),i.push(l)}t=Math.max(...i.map((t=>Math.max(...t))))}return[o,s,i,t]}PlayTones(){if(constants.sepPlayId&&constants.KillSepPlay(),"point"==constants.chartType)position.z=0,constants.sepPlayId=setInterval((function(){audio&&audio.playTone?(audio.playTone(),position.z+=1,position.z+1>plot.y[position.x].length&&(constants.KillSepPlay(),position.z=-1)):clearInterval(constants.sepPlayId)}),"on"==constants.sonifMode?constants.autoPlayPointsRate:0);else if("smooth"==constants.chartType){if(!audio||!audio.playTone)return void clearInterval(constants.sepPlayId);audio.playTone()}}GetSvgLineCoords(){let t=[],e=[];if(this.plotLine){if(this.plotLine instanceof SVGPathElement){const n=this.plotLine.getAttribute("d"),o=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;let s;for(;null!==(s=o.exec(n));)t.push(s[1]),e.push(s[3])}else if(this.plotLine instanceof SVGPolylineElement){let n=this.plotLine.getAttribute("points").split(" ");for(let o=0;o<n.length;o++){let s=n[o].split(",");t.push(parseFloat(s[0])),e.push(parseFloat(s[1]))}}}else if([].concat(singleMaidr.type).includes("smooth")){let n,o=this.GetElementIndex("smooth"),s=this.GetDataXYFormat(o);if(n=o>-1?singleMaidr.data[o]:singleMaidr.data,"object"==s)for(let o=0;o<n.length;o++)t.push(n[o].x),e.push(n[o].y);else"array"==s&&("x"in n&&(t=n.x),"y"in n&&(e=n.y))}return[t,e]}GetSmoothCurvePoints(){let t,e=[],n=[],o=this.GetElementIndex("smooth"),s=this.GetDataXYFormat(o);if(o>-1?t=singleMaidr.data[o]:"smooth"==singleMaidr.type&&(t=singleMaidr.data),void 0!==t)if("object"==s)for(let o=0;o<t.length;o++)e.push(t[o].x),n.push(t[o].y);else"array"==s&&("x"in t&&(e=t.x),"y"in t&&(n=t.y));return[e,n]}GetGradient(){let t=[];for(let e=0;e<this.curvePoints.length-1;e++){let n=Math.abs((this.curvePoints[e+1]-this.curvePoints[e])/(this.curveX[e+1]-this.curveX[e])).toFixed(3);t.push(n)}return t.push("end"),t}GetRectStatus(t){let e=this.GetElementIndex(t);if(e>-1){if("selector"in singleMaidr)return!!singleMaidr.selector[e];if("elements"in singleMaidr)return!!singleMaidr.elements[e]}else{if("selector"in singleMaidr)return!!singleMaidr.selector;if("elements"in singleMaidr)return!!singleMaidr.elements}}}class Layer0Point{constructor(){[].concat(singleMaidr.type).includes("point")&&(this.x=plot.chartPointsX[0],this.y=plot.chartPointsY[0],this.strokeWidth=1.35,this.hasRect=plot.GetRectStatus("point"),this.circleIndex=[])}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartPointsX[position.x],this.y=plot.chartPointsY[position.x],this.circleIndex=[];for(let t=0;t<this.y.length;t++)for(let e=0;e<plot.plotPoints.length;e++){let n,o;if(plot.plotPoints[e]instanceof SVGPathElement){const t=plot.plotPoints[e].getAttribute("d");let s=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(s[1]),o=parseFloat(s[3])}else(plot.plotPoints[e]instanceof SVGUseElement||plot.plotPoints[e]instanceof SVGCircleElement)&&(n=plot.plotPoints[e].getAttribute(plot.prefix+"x"),o=plot.plotPoints[e].getAttribute(plot.prefix+"y"));if(n==this.x&&o==this.y[t]){this.circleIndex.push(e);break}}}async PrintPoints(){await this.UpdatePoints();for(let e=0;e<this.circleIndex.length;e++){const n="http://www.w3.org/2000/svg";var t=document.createElementNS(n,"circle");if(t.setAttribute("class","highlight_point"),t.setAttribute("cx",this.x),-1==plot.svgScaler[1])t.setAttribute("cy",constants.chart.getBoundingClientRect().height-this.y[e]);else{let n;if(plot.plotPoints[this.circleIndex[e]]instanceof SVGPathElement){const t=plot.plotPoints[this.circleIndex[e]].getAttribute("d");let o=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(o[3])}else(plot.plotPoints[this.circleIndex[e]]instanceof SVGUseElement||plot.plotPoints[this.circleIndex[e]]instanceof SVGCircleElement)&&(n=plot.plotPoints[this.circleIndex[e]].getAttribute(plot.prefix+"y"));t.setAttribute("cy",n)}t.setAttribute("r",3.95),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.strokeWidth),t.setAttribute("fill",constants.colorSelected),constants.chart.appendChild(t)}}async ClearPoints(){document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove();let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove()}UpdatePointDisplay(){this.PrintPoints()}}class Layer1Point{constructor(){[].concat(singleMaidr.type).includes("smooth")&&(this.x=plot.chartLineX[0],this.y=plot.chartLineY[0],this.strokeWidth=1.35,this.hasRect=plot.GetRectStatus("point"))}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartLineX[positionL1.x],this.y=plot.chartLineY[positionL1.x]}async PrintPoints(){await this.UpdatePoints();var t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("id","highlight_point"),t.setAttribute("cx",this.x),-1==plot.svgScaler[1]?t.setAttribute("cy",constants.chart.getBoundingClientRect().height-this.y):t.setAttribute("cy",this.y),t.setAttribute("r",3.95),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.strokeWidth),t.setAttribute("fill",constants.colorSelected),-1==plot.svgScaler[1]?constants.chart.appendChild(t):plot.plotLine.parentNode.appendChild(t)}async ClearPoints(){let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove();document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove()}UpdatePointDisplay(){this.PrintPoints()}}class Histogram{constructor(){"data"in singleMaidr?(this.plotData=singleMaidr.data,this.bars=null,"selector"in singleMaidr?this.bars=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(this.bars=singleMaidr.elements),this.legendX=null,this.legendY=null,"labels"in singleMaidr&&("x"in singleMaidr.labels&&(this.legendX=singleMaidr.labels.x),"y"in singleMaidr.labels&&(this.legendY=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&"label"in singleMaidr.axes.x&&(this.legendX||(this.legendX=singleMaidr.axes.x.label)),"y"in singleMaidr.axes&&"label"in singleMaidr.axes.y&&(this.legendY||(this.legendY=singleMaidr.axes.y.label))),this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),this.SetMaxMin(),this.autoplay=null):console.log("Error: no data found")}PlayTones(){audio.playTone()}SetMaxMin(){for(let t=0;t<this.plotData.length;t++)0==t?(constants.maxY=this.plotData[t].y,constants.minY=this.plotData[t].y,constants.maxX=this.plotData[t].xmax,constants.minX=this.plotData[t].xmin):(this.plotData[t].y>constants.maxY&&(constants.maxY=this.plotData[t].y),this.plotData[t].y<constants.minY&&(constants.minY=this.plotData[t].y),this.plotData[t].xmax>constants.maxX&&(constants.maxX=this.plotData[t].xmax),this.plotData[t].xmin<constants.minX&&(constants.minX=this.plotData[t].xmin));constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/this.plotData.length),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}Select(){if(this.UnSelectPrevious(),this.bars&&(this.activeElement=this.bars[position.x],this.activeElement))if(this.activeElement.hasAttribute("fill"))this.activeElementColor=this.activeElement.getAttribute("fill"),this.activeElement.setAttribute("fill",constants.GetBetterColor(this.activeElementColor));else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);this.activeElementColor=e[e.indexOf("fill")+1],e[e.indexOf("fill")+1]=constants.GetBetterColor(this.activeElementColor),t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t)}}UnSelectPrevious(){if(this.activeElement)if(this.activeElement.hasAttribute("fill"))this.activeElement.setAttribute("fill",this.activeElementColor),this.activeElement=null;else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);e[e.indexOf("fill")+1]=this.activeElementColor,t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t),this.activeElement=null}}}class LinePlot{constructor(){this.SetLineLayer(),this.SetAxes(),this.UpdateConstants()}SetLineLayer(){let t;"selector"in singleMaidr?t=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(t=singleMaidr.elements),t?this.plotLine=t[t.length-1]:constants.hasRect=0;let e=this.GetPointCoords(),n=this.GetPoints();this.chartLineX=e[0],this.chartLineY=e[1],this.pointValuesX=n[0],this.pointValuesY=n[1],this.curveMinY=Math.min(...this.pointValuesY),this.curveMaxY=Math.max(...this.pointValuesY)}UpdateConstants(){constants.minX=0,constants.maxX=singleMaidr.data.length-1,constants.minY=singleMaidr.data.reduce(((t,e)=>e.y<t?e.y:t),singleMaidr.data[0].y),constants.maxY=singleMaidr.data.reduce(((t,e)=>e.y>t?e.y:t),singleMaidr.data[0].y),constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}GetPointCoords(){let t=[[],[]];if(!this.plotLine){let t,e=[],n=[];if("data"in singleMaidr&&(t=singleMaidr.data),void 0!==t)for(let o=0;o<t.length;o++)e.push(t[o].x),n.push(t[o].y);return[e,n]}if(this.plotLine instanceof SVGPathElement){const e=this.plotLine.getAttribute("d"),n=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;let o;for(;null!==(o=n.exec(e));)t[0].push(o[1]),t[1].push(o[3])}else{let e=this.plotLine.getAttribute("points").split(" ");for(let n=0;n<e.length;n++)if(""!==e[n]){let o=e[n].split(",");t[0].push(o[0]),t[1].push(o[1])}}return t}GetPoints(){let t,e=[],n=[];if("data"in singleMaidr&&(t=singleMaidr.data),void 0!==t){for(let o=0;o<t.length;o++)e.push(t[o].x),n.push(t[o].y);return[e,n]}}SetAxes(){let t="",e="";"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&""==t&&(t=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&""==e&&(e=singleMaidr.axes.y.label)),this.plotLegend={x:t,y:e},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption)}PlayTones(){audio.playTone()}}class Point{constructor(){this.x=plot.chartLineX[0],this.y=plot.chartLineY[0]}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartLineX[position.x],this.y=plot.chartLineY[position.x]}async PrintPoints(){await this.ClearPoints(),await this.UpdatePoints();var t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("id","highlight_point"),t.setAttribute("cx",this.x),t.setAttribute("cy",this.y),t.setAttribute("r",1.75),t.setAttribute("style","fill:"+constants.colorSelected+";stroke:"+constants.colorSelected),constants.chart.appendChild(t)}async ClearPoints(){let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove();document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove()}UpdatePointDisplay(){this.ClearPoints(),this.UpdatePoints(),this.PrintPoints()}}class Segmented{constructor(){let t=null,e=null;if("axes"in singleMaidr&&("x"in singleMaidr.axes?"level"in singleMaidr.axes.x&&(this.level=singleMaidr.axes.x.level):"y"in singleMaidr.axes&&"level"in singleMaidr.axes.y&&(this.level=singleMaidr.axes.y.level),"fill"in singleMaidr.axes&&"level"in singleMaidr.axes.fill&&(this.fill=singleMaidr.axes.fill.level)),"data"in singleMaidr&&(t=singleMaidr.data),"selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(e=singleMaidr.elements),null==e&&(logError.LogAbsentElement("elements"),constants.hasRect=0),!t)return void console.log("Segmented chart missing level, fill, or data. Unable to create chart.");{this.fill&&(this.fill=this.fill.reverse());let n=this.ParseData(t,e);this.plotData=n[0],this.elements=n[1]}let n="",o="";"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&(n=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&(o=singleMaidr.axes.y.label)),"labels"in singleMaidr&&("x"in singleMaidr.labels&&(n=singleMaidr.labels.x),"y"in singleMaidr.labels&&(o=singleMaidr.labels.y)),this.plotLegend={x:n,y:o},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),this.SetMaxMin(),this.CreateSummaryLevel(),this.CreateAllLevel(),this.autoplay=null}ParseData(t,e=null){let n=[],o=[];e?e.length!=t.length&&(o=null):o=null;for(let s=0;s<this.level.length;s++)for(let i=0;i<this.fill.length;i++)for(let l=0;l<t.length;l++)if(n[s]||(n[s]=[],null!=o&&(o[s]||(o[s]=[]))),n[s][i]||(n[s][i]=0,null!=o&&(o[s][i]||(o[s][i]=null))),t[l].x==this.level[s]&&t[l].fill==this.fill[i]){n[s][i]=t[l].y,e&&(o[s][i]=e[l]);break}return[n,o]}CreateSummaryLevel(){for(let t=0;t<this.plotData.length;t++){let e=0;for(let n=0;n<this.plotData[t].length;n++)e+=this.plotData[t][n];this.plotData[t].push(e)}this.fill.push("Sum")}CreateAllLevel(){for(let t=0;t<this.plotData.length;t++){let e=[];for(let n=0;n<this.fill.length;n++)"Sum"!=this.fill[n]&&e.push(this.plotData[t][n]);this.plotData[t].push(e)}this.fill.push("All")}PlayTones(){if(Array.isArray(this.plotData[position.x][position.y]))if("on"==constants.sonifMode)position.z=0,constants.KillSepPlay(),constants.sepPlayId=setInterval((function(){audio.playTone(),position.z+=1,Array.isArray(plot.plotData[position.x][position.y])?position.z+1>plot.plotData[position.x][position.y].length&&(constants.KillSepPlay(),position.z=-1):(constants.KillSepPlay(),position.z=-1)}),"on"==constants.sonifMode?constants.autoPlayPointsRate:0);else{let t=Math.min(...this.plotData[position.x][position.y]),e=Math.max(...this.plotData[position.x][position.y]);for(let n=0;n<this.plotData[position.x][position.y].length;n++){position.z=n;let o=audio.SlideBetween(this.plotData[position.x][position.y][n],t,e,constants.combinedVolMin,constants.combinedVolMax);audio.playTone({volScale:o})}}else audio.playTone()}SetMaxMin(){for(let t=0;t<singleMaidr.data.length;t++)0==t?(constants.maxY=singleMaidr.data[t].y,constants.minY=singleMaidr.data[t].y):(singleMaidr.data[t].y>constants.maxY&&(constants.maxY=singleMaidr.data[t].y),singleMaidr.data[t].y<constants.minY&&(constants.minY=singleMaidr.data[t].y));constants.maxX=this.level.length,constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/this.plotData.length),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}Select(){if(this.UnSelectPrevious(),this.elements&&(this.activeElement=this.elements[position.x][position.y],this.activeElement)){this.activeElementColor=this.activeElement.style.fill;let t=constants.GetBetterColor(this.activeElementColor);this.activeElement.style.fill=t}}UnSelectPrevious(){this.activeElement&&(this.activeElement.style.fill=this.activeElementColor,this.activeElement=null)}}class Control{controlElements=[constants.chart,constants.brailleInput];allControlElements=[constants.chart,constants.brailleInput,constants.review_container];pressedL=!1;constructor(){constants.lastx=0,this.InitChartClass(),this.SetBTSControls(),this.SetPrefixControls(),this.SetControls()}InitChartClass(){[].concat(singleMaidr.type).includes("bar")?window.plot=new BarChart:[].concat(singleMaidr.type).includes("box")?window.plot=new BoxPlot:[].concat(singleMaidr.type).includes("heat")?(window.plot=new HeatMap,singleMaidr.rect=new HeatMapRect):[].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")?(window.plot=new ScatterPlot,window.layer0Point=new Layer0Point,window.layer1Point=new Layer1Point):[].concat(singleMaidr.type).includes("hist")?window.plot=new Histogram:([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))&&(window.plot=new Segmented)}SetBTSControls(){for(let t=0;t<this.allControlElements.length;t++)constants.events.push([this.allControlElements[t],"keydown",function(t){if(!constants.pressedL&&("b"!=t.key||control.pressedL||(constants.tabMovement=0,t.preventDefault(),display.toggleBrailleMode()),"t"!=t.key||control.pressedL||display.toggleTextMode(),"s"!=t.key||control.pressedL||display.toggleSonificationMode(),"r"!=t.key||t.ctrlKey||t.shiftKey||control.pressedL||(constants.tabMovement=0,t.preventDefault(),constants.review_container.classList.contains("hidden")?review.ToggleReviewMode(!0):review.ToggleReviewMode(!1))," "!=t.key||control.pressedL||(position.x<0&&(position.x=0),position.y<0&&(position.y=0),constants.showDisplay&&display.displayValues(),"off"!=constants.sonifMode&&plot.PlayTones()),Array.isArray(singleMaidr.type)&&[].concat(singleMaidr.type).includes("point")&&[].concat(singleMaidr.type).includes("smooth")&&("PageDown"==t.key&&"off"==constants.brailleMode&&display.changeChartLayer("down"),"PageUp"==t.key&&"off"==constants.brailleMode&&display.changeChartLayer("up")),"-"==t.key)){}}]);constants.events.push([constants.review,"keydown",function(t){t.key.startsWith("Arrow")||t.shiftKey&&t.key.startsWith("Arrow")||t.ctrlKey&&"a"===t.key||t.ctrlKey&&"c"===t.key||t.preventDefault()}]);for(let t=0;t<this.allControlElements.length;t++)constants.events.push([this.allControlElements[t],"keydown",function(t){"Tab"==t.key&&(t.shiftKey?constants.tabDirection=-1:constants.tabDirection=1)}])}SetPrefixControls(){constants.events.push([document,"keydown",function(t){let e=null;if("l"==t.key&&(control.pressedL=!0,null!=e&&(clearTimeout(e),e=null),e=setTimeout((function(){control.pressedL=!1}),constants.keypressInterval)),control.pressedL)if("x"==t.key){let t="";"bar"==singleMaidr.type||"line"==singleMaidr.type?t=plot.plotLegend.x:"hist"==singleMaidr.type?t=plot.legendX:"heat"==singleMaidr.type||"box"==singleMaidr.type||"point"==singleMaidr.type||singleMaidr.type.includes("point")?t=plot.x_group_label:"stacked_bar"!=singleMaidr.type&&"stacked_normalized_bar"!=singleMaidr.type&&"dodged_bar"!=singleMaidr.type||(t=plot.plotLegend.x),display.displayInfo("x label",t),control.pressedL=!1}else if("y"==t.key){let t="";"bar"==singleMaidr.type||"line"==singleMaidr.type?t=plot.plotLegend.y:"hist"==singleMaidr.type?t=plot.legendY:"heat"==singleMaidr.type||"box"==singleMaidr.type||"point"==singleMaidr.type||"line"==singleMaidr.type||singleMaidr.type.includes("point")?t=plot.y_group_label:"stacked_bar"!=singleMaidr.type&&"stacked_normalized_bar"!=singleMaidr.type&&"dodged_bar"!=singleMaidr.type||(t=plot.plotLegend.y),display.displayInfo("y label",t),control.pressedL=!1}else"t"==t.key?(display.displayInfo("title",plot.title),control.pressedL=!1):"s"==t.key?(display.displayInfo("subtitle",plot.subtitle),control.pressedL=!1):"c"==t.key?(display.displayInfo("caption",plot.caption),control.pressedL=!1):"f"==t.key?(display.displayInfo("fill",plot.fill),control.pressedL=!1):"l"!=t.key&&(control.pressedL=!1)}])}async SetControls(){constants.events.push([document,"keydown",function(t){(constants.isMac?t.metaKey:t.ctrlKey)&&("Home"==t.key?("bar"==constants.chartType||"hist"==constants.chartType?position.x=0:"box"==constants.chartType?(position.x=0,position.y=plot.sections.length-1):"heat"==constants.chartType?(position.x=0,position.y=0):"point"==constants.chartType?position.x=0:"smooth"==constants.chartType&&(positionL1.x=0),control.UpdateAllBraille()):"End"==t.key&&("bar"==constants.chartType||"hist"==constants.chartType?position.x=plot.bars.length-1:"box"==constants.chartType?(position.x=plot.sections.length-1,position.y=0):"heat"==constants.chartType?(position.x=plot.num_cols-1,position.y=plot.num_rows-1):"point"==constants.chartType?position.x=plot.y.length-1:"smooth"==constants.chartType&&(positionL1.x=plot.curvePoints.length-1),control.UpdateAllBraille()))}]);if([].concat(singleMaidr.type).includes("bar")?window.position=new Position(-1,-1):[].concat(singleMaidr.type).includes("box")?(constants.plotId="geom_boxplot.gTree.78.1","vert"==constants.plotOrientation?window.position=new Position(0,6):window.position=new Position(-1,plot.plotData.length),constants.hasRect&&(singleMaidr.rect=new BoxplotRect)):[].concat(singleMaidr.type).includes("heat")?(constants.plotId="geom_rect.rect.2.1",window.position=new Position(-1,-1),constants.lastx=0):[].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")?(constants.plotId="geom_point.points.12.1",window.position=new Position(-1,-1),constants.lastx=0,constants.lastx1=0,window.positionL1=new Position(constants.lastx1,constants.lastx1)):([].concat(singleMaidr.type).includes("hist")||[].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))&&(window.position=new Position(-1,-1)),[].concat(singleMaidr.type).includes("box")?document.addEventListener("selectionchange",(function(t){if(t.preventDefault(),"on"==constants.brailleMode&&constants.brailleInput.selectionStart){if(constants.lockSelection)return;constants.lockSelection=!0;let t=constants.brailleInput.selectionStart;t=constants.brailleInput.selectionStart,t<0&&(o=0);let e=0,n="";if(constants.brailleData)for(let o=0;o<constants.brailleData.length;o++)if(e+=constants.brailleData[o].numChars,e>t){n="blank"==constants.brailleData[o].type?constants.brailleData[o+1].type:constants.brailleData[o].type;break}let o=plot.sections.indexOf(n);if(n.length>0){let t=0,e=0;"vert"==constants.plotOrientation?(position.y=o,t=plot.plotData.length-1,e=plot.sections.length-1):(position.x=o,t=plot.sections.length-1,e=plot.plotData.length-1),control.lockPosition(t,e);let n=!0;n&&(this.lockPosition=!0,control.UpdateAll(),this.lockPosition=!1),n&&audio.playEnd()}setTimeout((function(){constants.lockSelection=!1}),50)}})):[].concat(singleMaidr.type).includes("heat")?document.addEventListener("selectionchange",(function(t){if("on"==constants.brailleMode){if(constants.lockSelection)return;let t=constants.brailleInput.selectionStart;if(constants.lockSelection=!0,constants.brailleInput.value.split("").reduce(((t,e,n)=>("⠳"===e&&t.push(n),t)),[]).includes(t))return;t=constants.brailleInput.selectionStart,t<0&&(t=0),position.y=Math.floor(t/(plot.num_cols+1)),position.x=t%(plot.num_cols+1),control.lockPosition(plot.num_cols-1,plot.num_rows-1);let e=!0;e&&control.UpdateAll(),e&&audio.playEnd(),setTimeout((function(){constants.lockSelection=!1}),50)}})):([].concat(singleMaidr.type).includes("bar")||[].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")||[].concat(singleMaidr.type).includes("hist")||[].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))&&document.addEventListener("selectionchange",(function(t){if("on"==constants.brailleMode){if(constants.lockSelection)return;if(constants.lockSelection=!0,constants.brailleInput){let t=constants.brailleInput.selectionStart;t=constants.brailleInput.selectionStart,t<0&&(t=0),position.x=t,control.lockPosition();let e=!0;e&&control.UpdateAll(),e&&audio.playEnd()}setTimeout((function(){constants.lockSelection=!1}),50)}})),[].concat(singleMaidr.type).includes("bar")){constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;if("ArrowRight"==t.key)if(constants.isMac?t.metaKey:t.ctrlKey)t.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.plotData.length)):(position.x=plot.plotData.length-1,e=!0,n=control.lockPosition());else if(t.altKey&&t.shiftKey&&position.x!=plot.bars.length-1)constants.lastx=position.x,control.Autoplay("reverse-right",plot.bars.length,position.x);else{position.x+=1,e=!0,n=control.lockPosition()}else"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=control.lockPosition()));e&&!n&&control.UpdateAll(),n&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(t.preventDefault(),t.target.selectionStart>t.target.value.length-2||((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.plotData.length)):(position.x=plot.bars.length-1,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&position.x!=plot.bars.length-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.bars.length,position.x)):(position.x+=1,e=!0,n=control.lockPosition()))):"ArrowLeft"==t.key?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=control.lockPosition())):"Tab"==t.key||t.preventDefault(),e&&!n&&control.UpdateAllBraille(),n&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}])}else if([].concat(singleMaidr.type).includes("box")){let t=0,e=0;"vert"==constants.plotOrientation?(t=plot.plotData.length-1,e=plot.sections.length-1):(t=plot.sections.length-1,e=plot.plotData.length-1),constants.events.push([constants.chart,"keydown",function(n){let o=!1,s=!1;if("ArrowRight"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?"vert"==constants.plotOrientation?control.Autoplay("right",position.x,plot.plotData.length-1):control.Autoplay("right",position.x,plot.sections.length-1):(s=control.lockPosition(t,e),"vert"==constants.plotOrientation?position.x=plot.plotData.length-1:position.x=plot.sections.length-1,o=!0,s=control.lockPosition(t,e)):"vert"==constants.plotOrientation?n.altKey&&n.shiftKey&&plot.sections.length-1!=position.x?(lastY=position.y,control.Autoplay("reverse-right",plot.plotData.length-1,position.x)):(-1==position.x&&position.y==plot.sections.length&&(position.y-=1),position.x+=1,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&plot.sections.length-1!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.sections.length-1,position.x)):(-1==position.x&&position.y==plot.plotData.length&&(position.y-=1),position.x+=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=1),"ArrowLeft"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?control.Autoplay("left",position.x,-1):(position.x=0,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&position.x>0?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,control.Autoplay("reverse-left",0,position.x)):(position.x+=-1,o=!0,s=control.lockPosition(t,e)),constants.navigation=1),"ArrowUp"==n.key){position.y;(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?"vert"==constants.plotOrientation?control.Autoplay("up",position.y,plot.sections.length):control.Autoplay("up",position.y,plot.plotData.length):("vert"==constants.plotOrientation?position.y=plot.sections.length-1:position.y=plot.plotData.length-1,o=!0,s=control.lockPosition(t,e)):"vert"==constants.plotOrientation?n.altKey&&n.shiftKey&&position.y!=plot.sections.length-1?(lastY=position.y,control.Autoplay("reverse-up",plot.sections.length-1,position.y)):(position.y+=1,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&position.y!=plot.sections.length-1?(constants.lastx=position.x,control.Autoplay("reverse-up",plot.plotData.length-1,position.y)):(position.y+=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=0}if("ArrowDown"==n.key){position.y;(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?control.Autoplay("down",position.y,-1):(position.y=0,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&0!=position.y?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,control.Autoplay("reverse-down",0,position.y)):("vert"==constants.plotOrientation?-1==position.x&&position.y==plot.sections.length&&(position.x+=1):-1==position.x&&position.y==plot.plotData.length&&(position.x+=1),position.y+=-1,o=!0,s=control.lockPosition(t,e)),constants.navigation=0}o&&!s&&control.UpdateAll(),s&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(n){let o=!1,s=!1,i=!1;if("ArrowRight"==n.key)n.preventDefault(),(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?"vert"==constants.plotOrientation?control.Autoplay("right",position.x,plot.plotData.length-1):control.Autoplay("right",position.x,plot.sections.length):("vert"==constants.plotOrientation?position.x=plot.plotData.length-1:position.x=plot.sections.length-1,o=!0,i=control.lockPosition(t,e)):"vert"==constants.plotOrientation?n.altKey&&n.shiftKey&&plot.plotData.length-1!=position.x?(lastY=position.y,control.Autoplay("reverse-right",plot.plotData.length-1,position.x)):(-1==position.x&&position.y==plot.plotData[position.x].length&&(position.y-=1),position.x+=1,o=!0,i=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&plot.sections.length-1!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.sections.length-1,position.x)):(-1==position.x&&position.y==plot.plotData.length&&(position.y-=1),position.x+=1,o=!0,i=control.lockPosition(t,e)),s=!0,constants.navigation=1;else if("ArrowLeft"==n.key)n.preventDefault(),(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?control.Autoplay("left",position.x,-1):(position.x=0,o=!0,i=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&position.x>0?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,control.Autoplay("reverse-left",0,position.x)):(position.x+=-1,o=!0,i=control.lockPosition(t,e)),s=!0,constants.navigation=1;else if("ArrowUp"==n.key){position.y;(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?"vert"==constants.plotOrientation?(position.x<0&&(position.x=0),control.Autoplay("up",position.y,plot.sections.length)):control.Autoplay("up",position.y,plot.plotData.length):"vert"==constants.plotOrientation?(position.y=plot.sections.length-1,o=!0):(position.y=plot.plotData.length-1,o=!0):"vert"==constants.plotOrientation?n.altKey&&n.shiftKey&&position.y!=plot.sections.length-1?(lasY=position.y,control.Autoplay("reverse-up",plot.sections.length-1,position.y)):(position.y+=1,o=!0,i=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&position.y!=plot.plotData.length-1?(constants.lastx=position.x,control.Autoplay("reverse-up",plot.plotData.length-1,position.y)):(position.y+=1,o=!0,i=control.lockPosition(t,e)),"vert"==constants.plotOrientation||(s=!0),constants.navigation=0}else if("ArrowDown"==n.key){position.y;(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?control.Autoplay("down",position.y,-1):(position.y=0,o=!0,i=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&0!=position.y?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,control.Autoplay("reverse-down",0,position.y)):("vert"==constants.plotOrientation?-1==position.x&&position.y==plot.sections.length&&(position.x+=1):-1==position.x&&position.y==plot.plotData.length&&(position.x+=1),position.y+=-1,o=!0,i=control.lockPosition(t,e)),constants.navigation=0,"vert"==constants.plotOrientation||(s=!0),constants.navigation=0}else"Tab"==n.key||n.preventDefault();o&&!i&&(s&&display.SetBraille(plot),setTimeout(control.UpdateAllBraille,50)),i&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}])}else if([].concat(singleMaidr.type).includes("heat")){let t=plot.num_cols-1,e=plot.num_rows-1;constants.events.push([constants.chart,"keydown",function(n){let o=!1,s=!1;"ArrowRight"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.num_cols)):(position.x=plot.num_cols-1,o=!0):n.altKey&&n.shiftKey&&position.x!=plot.num_cols-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.num_cols,position.x)):(-1==position.x&&-1==position.y&&(position.y+=1),position.x+=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=1),"ArrowLeft"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,o=!0):n.altKey&&n.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x-=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=1),"ArrowUp"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.y+=1,control.Autoplay("up",position.y,-1)):(position.y=0,o=!0):n.altKey&&n.shiftKey&&0!=position.y?(constants.lastx=position.x,control.Autoplay("reverse-up",-1,position.y)):(position.y-=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=0),"ArrowDown"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.y-=1,control.Autoplay("down",position.y,plot.num_rows)):(position.y=plot.num_rows-1,o=!0):n.altKey&&n.shiftKey&&position.y!=plot.num_rows-1?(constants.lastx=position.x,control.Autoplay("reverse-down",plot.num_rows,position.y)):(-1==position.x&&-1==position.y&&(position.x+=1),position.y+=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=0),o&&!s&&control.UpdateAll(),s&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}]);constants.events.push([constants.brailleInput,"keydown",function(n){let o=!1,s=!1;if("ArrowRight"==n.key)if(n.target.selectionStart>n.target.value.length-3||"⠳"==n.target.value.substring(n.target.selectionStart+1,n.target.selectionStart+2))n.preventDefault();else{(constants.isMac?n.metaKey:n.ctrlKey)?(-1==position.x&&-1==position.y&&(position.x+=1,position.y+=1),n.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.num_cols)):(position.x=plot.num_cols-1,o=!0)):n.altKey&&n.shiftKey&&position.x!=plot.num_cols-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.num_cols,position.x)):(-1==position.x&&-1==position.y&&(position.y+=1),position.x+=1,o=!0,s=control.lockPosition(t,e));let i=position.y*(plot.num_cols+1)+position.x;n.target.setSelectionRange(i,i),n.preventDefault(),constants.navigation=1}else if("ArrowLeft"==n.key)if(0==n.target.selectionStart||"⠳"==n.target.value.substring(n.target.selectionStart-1,n.target.selectionStart))n.preventDefault();else{(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,o=!0):n.altKey&&n.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x+=-1,o=!0,s=control.lockPosition(t,e));let i=position.y*(plot.num_cols+1)+position.x;n.target.setSelectionRange(i,i),n.preventDefault(),constants.navigation=1}else if("ArrowDown"==n.key)if(position.y+1==plot.num_rows)n.preventDefault();else{(constants.isMac?n.metaKey:n.ctrlKey)?(-1==position.x&&-1==position.y&&(position.x+=1,position.y+=1),n.shiftKey?(position.y-=1,control.Autoplay("down",position.y,plot.num_rows)):(position.y=plot.num_rows-1,o=!0)):n.altKey&&n.shiftKey&&position.y!=plot.num_rows-1?(constants.lastx=position.x,control.Autoplay("reverse-down",plot.num_rows,position.y)):(-1==position.x&&-1==position.y&&(position.x+=1),position.y+=1,o=!0,s=control.lockPosition(t,e));let i=position.y*(plot.num_cols+1)+position.x;n.target.setSelectionRange(i,i),n.preventDefault(),constants.navigation=0}else if("ArrowUp"==n.key)if(n.target.selectionStart-plot.num_cols-1<0)n.preventDefault();else{(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.y+=1,control.Autoplay("up",position.y,-1)):(position.y=0,o=!0):n.altKey&&n.shiftKey&&0!=position.y?(constants.lastx=position.x,control.Autoplay("reverse-up",-1,position.y)):(position.y+=-1,o=!0,s=control.lockPosition(t,e));let i=position.y*(plot.num_cols+1)+position.x;n.target.setSelectionRange(i,i),n.preventDefault(),constants.navigation=0}else"Tab"==n.key||n.preventDefault();o&&!s&&control.UpdateAllBraille(),s&&audio.playEnd()}])}else if([].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")){let t=0,e=0;"point"==constants.chartType?t=plot.x.length-1:"smooth"==constants.chartType&&(t=plot.curvePoints.length-1),constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(n){let o=!1,s=!1;"point"==constants.chartType?("ArrowRight"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.x.length)):(position.x=plot.x.length-1,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&position.x!=plot.x.length-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.x.length,position.x)):(position.x+=1,o=!0,s=control.lockPosition(t,e))),"ArrowLeft"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x-=1,o=!0,s=control.lockPosition(t,e)))):"smooth"==constants.chartType&&(positionL1.x||(positionL1.x=constants.lastx1),"ArrowRight"==n.key&&n.shiftKey&&((constants.isMac?n.metaKey:n.ctrlKey)&&"off"!=constants.sonifMode?control.PlayLine("right"):n.altKey&&"off"!=constants.sonifMode&&control.PlayLine("reverse-right")),"ArrowLeft"==n.key&&n.shiftKey&&((constants.isMac?n.metaKey:n.ctrlKey)&&"off"!=constants.sonifMode?control.PlayLine("left"):n.altKey&&"off"!=constants.sonifMode&&control.PlayLine("reverse-left"))),o&&"point"==constants.chartType&&!s&&control.UpdateAll(),s&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}]);constants.events.push([constants.brailleInput,"keydown",function(n){let o=!1,s=!1;"smooth"==constants.chartType?(control.lockPosition(t,e),"ArrowRight"==n.key?(n.preventDefault(),constants.brailleInput.setSelectionRange(positionL1.x,positionL1.x),n.target.selectionStart>n.target.value.length-2?n.preventDefault():(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(positionL1.x-=1,control.Autoplay("right",positionL1.x,plot.curvePoints.length)):(positionL1.x=plot.curvePoints.length-1,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&positionL1.x!=plot.curvePoints.length-1?(constants.lastx1=positionL1.x,control.Autoplay("reverse-right",plot.curvePoints.length,positionL1.x)):(positionL1.x+=1,o=!0,s=control.lockPosition(t,e))):"ArrowLeft"==n.key?(n.preventDefault(),(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(positionL1.x+=1,control.Autoplay("left",positionL1.x,-1)):(positionL1.x=0,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&0!=positionL1.x?control.Autoplay("reverse-left",-1,positionL1.x):(positionL1.x-=1,o=!0,s=control.lockPosition(t,e))):n.preventDefault()):"Tab"==n.key||n.preventDefault(),constants.lastx1=positionL1.x,o&&!s&&control.UpdateAllBraille(),s&&audio.playEnd()}])}else if([].concat(singleMaidr.type).includes("hist")){constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(t){let e=!1,n=!1;"ArrowRight"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(t.preventDefault(),position.x-=1,control.Autoplay("right",position.x,plot.plotData.length)):"ArrowRight"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(t.preventDefault(),constants.lastx=position.x,control.Autoplay("reverse-right",plot.bars.length,position.x)):"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(t.preventDefault(),position.x=plot.plotData.length-1,e=!0,n=control.lockPosition()):(t.preventDefault(),position.x+=1,e=!0,n=control.lockPosition()),"ArrowLeft"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(t.preventDefault(),position.x+=1,control.Autoplay("left",position.x,-1)):"ArrowLeft"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(t.preventDefault(),constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(t.preventDefault(),position.x=0,e=!0,n=control.lockPosition()):(t.preventDefault(),position.x+=-1,e=!0,n=control.lockPosition()),e&&!n&&("off"==constants.brailleMode?control.UpdateAll():control.UpdateAllBraille()),n&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(t.preventDefault(),constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(t.preventDefault(),constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(t.preventDefault(),constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}])}else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar")){constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(t){let e=!1,n=!1;constants.navigation=0,"on"==constants.brailleMode&&("Tab"==t.key||t.preventDefault()),"ArrowRight"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.plotData.length)):"ArrowRight"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.plotData.length,position.x)):"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.x=plot.plotData.length-1,e=!0,n=control.lockPosition()):(position.x+=1,e=!0,constants.navigation=1,n=control.lockPosition()),"ArrowLeft"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):"ArrowLeft"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.x=0,e=!0,n=control.lockPosition()):(position.x+=-1,e=!0,constants.navigation=1,n=control.lockPosition()),"ArrowUp"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowUp"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?control.Autoplay("up",position.y,plot.plotData[0].length):"ArrowUp"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,control.Autoplay("reverse-up",-1,plot.plotData[0].length)):"ArrowUp"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.y=plot.plotData[0].length-1,e=!0):(position.y+=1,e=!0,constants.navigation=0,n=control.lockPosition()),"ArrowDown"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowDown"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?control.Autoplay("down",position.y,-1):"ArrowDown"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,control.Autoplay("reverse-down",-1,position.y)):"ArrowDown"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.y=0,e=!0):(position.y+=-1,e=!0,constants.navigation=0,n=control.lockPosition()),e&&!n&&("off"==constants.brailleMode?control.UpdateAll():control.UpdateAllBraille())}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}])}else if([].concat(singleMaidr.type).includes("line")){window.position=new Position(-1,-1),window.plot=new LinePlot;constants.lastx=0,document.addEventListener("selectionchange",(function(t){if("on"==constants.brailleMode){if(constants.lockSelection)return;constants.lockSelection=!0;let t=constants.brailleInput.selectionStart;t=constants.brailleInput.selectionStart,t<0&&(t=0),position.x=t,control.lockPosition();let e=!0;e&&control.UpdateAll(),e&&audio.playEnd(),setTimeout((function(){constants.lockSelection=!1}),50)}})),constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.pointValuesY.length)):(position.x=plot.pointValuesY.length-1,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&position.x!=plot.pointValuesY.length-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.pointValuesY.length,position.x)):(position.x+=1,e=!0,n=control.lockPosition()):"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=control.lockPosition())),e&&!n&&control.UpdateAll(),n&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(t.preventDefault(),t.target.selectionStart>t.target.value.length-2||((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.pointValuesY.length)):(position.x=plot.pointValuesY.length-1,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&position.x!=plot.pointValues.length-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.pointValuesY.length,position.x)):(position.x+=1,e=!0,n=control.lockPosition()))):"ArrowLeft"==t.key?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=control.lockPosition())):"Tab"==t.key||t.preventDefault(),e&&!n&&control.UpdateAllBraille(),n&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}])}}PlayDuringSpeedChange(){null!=constants.autoplayId&&(constants.KillAutoplay(),audio.KillSmooth(),"reverse-left"==lastPlayed?"point"==constants.chartType?control.Autoplay("right",position.x,lastx):"smooth"==constants.chartType?control.Autoplay("right",positionL1.x,constants.lastx1):"vert"==constants.plotOrientation?control.Autoplay("right",position.y,lastY):control.Autoplay("right",position.x,lastx):"reverse-right"==lastPlayed?"point"==constants.chartType?control.Autoplay("left",position.x,lastx):"smooth"==constants.chartType?control.Autoplay("left",positionL1.x,constants.lastx1):"vert"==constants.plotOrientation?control.Autoplay("left",position.y,lastY):control.Autoplay("left",position.x,lastx):"reverse-up"==lastPlayed?"vert"==constants.plotOrientation?control.Autoplay("down",position.y,lastY):control.Autoplay("down",position.x,lastx):"reverse-down"==lastPlayed?"vert"==constants.plotOrientation?control.Autoplay("up",position.y,lastY):control.Autoplay("up",position.x,lastx):"point"==constants.chartType?control.Autoplay(lastPlayed,position.x,lastx):"smooth"==constants.chartType?control.Autoplay(lastPlayed,positionL1.x,constants.lastx1):"vert"==constants.plotOrientation?control.Autoplay(lastPlayed,position.y,lastY):control.Autoplay(lastPlayed,position.x,lastx))}lockPosition(t,e){let n=!1;return control.isUndefinedOrNull(t)&&"smooth"!=constants.chartType&&"line"!=constants.chartType&&("vert"==constants.plotOrientation?(t=0,e=plot.sections.length-1):(t=plot.plotData.length-1,e=0)),"smooth"==constants.chartType?(positionL1.x<0&&(positionL1.x=0,n=!0),positionL1.x>plot.curvePoints.length-1&&(positionL1.x=plot.curvePoints.length-1,n=!0)):"line"==constants.chartType?(position.x<0&&(position.x=0,n=!0),position.x>plot.pointValuesY.length-1&&(position.x=plot.pointValuesY.length-1,n=!0)):"stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType?(position.x<0?(position.x=0,n=!0):position.x>plot.level.length-1&&(position.x=plot.level.length-1,n=!0),position.y<0?(position.y=0,n=!0):position.y>plot.fill.length-1&&(position.y=plot.fill.length-1,n=!0)):(position.y<0&&(position.y=0,n=!0,"off"!=constants.brailleMode&&(constants.brailleInput.selectionEnd=0)),position.x<0&&(position.x=0,n=!0,"off"!=constants.brailleMode&&(constants.brailleInput.selectionEnd=0)),position.x>t&&(position.x=t,n=!0,constants.brailleInput.selectionStart=constants.brailleInput.value.length),position.y>e&&(position.y=e,n=!0,constants.brailleInput.selectionStart=constants.brailleInput.value.length)),n}UpdateAll(){if(constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect)if([].concat(singleMaidr.type).includes("bar"))plot.Select();else if([].concat(singleMaidr.type).includes("box"))singleMaidr.rect.UpdateRect();else if([].concat(singleMaidr.type).includes("heat"))singleMaidr.rect.UpdateRectDisplay();else if([].concat(singleMaidr.type).includes("point"))layer0Point.hasRect&&layer0Point.UpdatePointDisplay();else if([].concat(singleMaidr.type).includes("smooth"))layer1Point.hasRect&&layer1Point.UpdatePointDisplay();else if([].concat(singleMaidr.type).includes("hist"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("line")&&constants.showRect&&constants.hasRect){(new Point).UpdatePointDisplay()}"off"!=constants.sonifMode&&plot.PlayTones()}UpdateAllAutoPlay(){if(constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect)if([].concat(singleMaidr.type).includes("bar"))plot.Select();else if([].concat(singleMaidr.type).includes("box"))singleMaidr.rect.UpdateRect();else if([].concat(singleMaidr.type).includes("heat"))singleMaidr.rect.UpdateRectDisplay();else if([].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth"))constants.showRect&&("point"==constants.chartType&&layer0Point.hasRect?layer0Point.UpdatePointDisplay():"smooth"==constants.chartType&&layer1Point.hasRect&&layer1Point.UpdatePointDisplay());else if([].concat(singleMaidr.type).includes("hist"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("line")&&constants.showRect){(new Point).UpdatePointDisplay()}"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}UpdateAllBraille(){if(constants.showDisplayInBraille&&(([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))&&display.SetBraille(),display.displayValues()),constants.showRect&&constants.hasRect)if([].concat(singleMaidr.type).includes("bar"))plot.Select();else if([].concat(singleMaidr.type).includes("box"))singleMaidr.rect.UpdateRect();else if([].concat(singleMaidr.type).includes("heat"))singleMaidr.rect.UpdateRectDisplay();else if([].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth"))layer1Point.hasRect&&layer1Point.UpdatePointDisplay();else if([].concat(singleMaidr.type).includes("hist"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("line")&&constants.showRect){(new Point).UpdatePointDisplay()}"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}Autoplay(t,e,n){let o=t;if([].concat(singleMaidr.type).includes("bar")){let o=1;"left"!=t&&"reverse-right"!=t||(o=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=o,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),control.lockPosition()):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()}),constants.autoPlayRate)}else if([].concat(singleMaidr.type).includes("box")){o=t;let s=1;"left"!=t&&"down"!=t&&"reverse-right"!=t&&"reverse-up"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.debugLevel>0&&console.log("starting autoplay",t,e,n),control.UpdateAllAutoPlay(),constants.autoplayId=setInterval((function(){let e=!1;"left"==t||"right"==t||"up"==t||"down"==t?(position.x<1&&"left"==t||"vert"==constants.plotOrientation&&"up"==t&&position.y>plot.sections.length-2||"horz"==constants.plotOrientation&&"up"==t&&position.y>plot.plotData.length-2||"horz"==constants.plotOrientation&&"right"==t&&position.x>plot.sections.length-2||"vert"==constants.plotOrientation&&"right"==t&&position.x>plot.plotData.length-2||"horz"==constants.plotOrientation&&"down"==t&&position.y<1||"vert"==constants.plotOrientation&&"down"==t&&position.y<1)&&(e=!0):("reverse-left"==t&&position.x>=n||"reverse-right"==t&&position.x<=n||"reverse-up"==t&&position.y<=n||"reverse-down"==t&&position.y>=n)&&(e=!0),e?constants.KillAutoplay():("left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?position.x+=s:position.y+=s,control.UpdateAllAutoPlay()),constants.debugLevel>5&&console.log("autoplay pos",position)}),constants.autoPlayRate)}else if([].concat(singleMaidr.type).includes("heat")){o=t;let s=plot.num_cols-1,i=plot.num_rows-1,l=1;"left"!=t&&"up"!=t&&"reverse-right"!=t&&"reverse-down"!=t||(l=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.autoplayId=setInterval((function(){"left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?(position.x+=l,position.x<0||plot.num_cols-1<position.x?(constants.KillAutoplay(),control.lockPosition(s,i)):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()):(position.y+=l,position.y<0||plot.num_rows-1<position.y?(constants.KillAutoplay(),control.lockPosition(s,i)):position.y==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay())}),constants.autoPlayRate)}else if([].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")){o=t;let s=0,i=0;"point"==constants.chartType?s=plot.x.length-1:"smooth"==constants.chartType&&(s=plot.curvePoints.length-1);let l=1;"left"!=t&&"reverse-right"!=t||(l=-1),constants.autoplayId&&constants.KillAutoplay(),constants.isSmoothAutoplay&&audio.KillSmooth(),"reverse-left"!=t&&"reverse-right"!=t||(position.x=e,position.L1x=e),"point"==constants.chartType?constants.autoplayId=setInterval((function(){position.x+=l,position.x<0||position.x>plot.y.length-1?(constants.KillAutoplay(),control.lockPosition(s,i)):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()}),constants.autoPlayRate):"smooth"==constants.chartType&&(constants.autoplayId=setInterval((function(){positionL1.x+=l,positionL1.x<0||positionL1.x>plot.curvePoints.length-1?(constants.KillAutoplay(),control.lockPosition(s,i)):positionL1.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()}),constants.autoPlayRate))}else if([].concat(singleMaidr.type).includes("hist")){o=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),control.lockPosition()):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()}),constants.autoPlayRate)}else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar")){o=t;let s=1;"left"!=t&&"down"!=t&&"reverse-right"!=t&&"reverse-up"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.autoplayId=setInterval((function(){"left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?(position.x+=s,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),control.lockPosition()):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()):(position.y+=s,position.y<0||plot.plotData[0].length-1<position.y?(constants.KillAutoplay(),control.lockPosition()):position.y==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay())}),constants.autoPlayRate)}else if([].concat(singleMaidr.type).includes("line")){o=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||plot.pointValuesY.length-1<position.x?(constants.KillAutoplay(),control.lockPosition()):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()}),constants.autoPlayRate)}}PlayLine(t){let e=[],n=[],o=audio.SlideBetween(positionL1.x,0,plot.curvePoints.length-1,-1,1),s=positionL1.x<0?0:positionL1.x,i=0;if("right"==t){for(let t=s;t<plot.curvePoints.length;t++)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[o,1],i=Math.abs(plot.curvePoints.length-s)/plot.curvePoints.length*3}else if("left"==t){for(let t=s;t>=0;t--)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[o,-1],i=Math.abs(s)/plot.curvePoints.length*3}else if("reverse-right"==t){for(let t=plot.curvePoints.length-1;t>=s;t--)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[1,o],i=Math.abs(plot.curvePoints.length-s)/plot.curvePoints.length*3}else if("reverse-left"==t){for(let t=0;t<=s;t++)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[-1,o],i=Math.abs(s)/plot.curvePoints.length*3}constants.isSmoothAutoplay&&audio.KillSmooth(),audio.playSmooth(e,i,n,constants.vol,"sine")}GetNextPrevFocusable(){let t='a[href], button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';constants.focusables=Array.from(document.querySelectorAll(t));let e=constants.focusables.indexOf(constants.chart),n=constants.main_container.querySelectorAll(t);for(let t=0;t<n.length;t++){let o=constants.focusables.indexOf(n[t]);o>-1&&constants.focusables.splice(o,1),e>o&&e--}}isUndefinedOrNull(t){try{return null==t}catch{return!0}}}function InitMaidr(t){if("undefined"!=typeof constants){window.singleMaidr=t,constants.chartId=singleMaidr.id,Array.isArray(singleMaidr.type)?constants.chartType=singleMaidr.type[0]:constants.chartType=singleMaidr.type,DestroyChartComponents(),CreateChartComponents(singleMaidr),InitTracker(),window.menu=new Menu,window.chatLLM=new ChatLLM,window.control=new Control,window.review=new Review,window.display=new Display,window.audio=new Audio;let e=[constants.chart,constants.brailleInput,constants.review];for(let t=0;t<e.length;t++)constants.events.push([e[t],"blur",ShouldWeDestroyMaidr]);if(constants.events.push([document,"keydown",KillAutoplayEvent]),this.SetEvents(),constants.chart.setAttribute("role","img"),"name"in singleMaidr)constants.chart.setAttribute("aria-label",announceText),constants.chart.setAttribute("title",announceText);else if("title"in singleMaidr||"labels"in singleMaidr&&"title"in singleMaidr.labels){let t="title"in singleMaidr?singleMaidr.title:singleMaidr.labels.title,e="This is a multi-layered plot. Use PageUp and PageDown to switch between layers.",n=`${Array.isArray(singleMaidr.type)?singleMaidr.type.slice(0,-1).join(", ")+" and "+singleMaidr.type.slice(-1):singleMaidr.type} plot of ${t}: Click to activate. Use Arrows to navigate data points. ${Array.isArray(singleMaidr.type)&&singleMaidr.type.length>1?e:" "}Toggle B for Braille, T for Text, S for Sonification, and R for Review mode. Use H for Help.`;constants.chart.setAttribute("aria-label",n),constants.chart.setAttribute("title",n)}}}function ShouldWeInitMaidr(t){"undefined"==typeof singleMaidr?InitMaidr(t):singleMaidr?t.id!==singleMaidr.id&&(DestroyMaidr(),InitMaidr(t)):InitMaidr(t)}function ShouldWeDestroyMaidr(t){setTimeout((()=>{0==constants.tabMovement?constants.tabMovement=null:(1!=constants.tabMovement&&-1!=constants.tabMovement||FocusBeforeOrAfter(),DestroyMaidr())}),0)}function FocusBeforeOrAfter(){if(1==constants.tabMovement){let t=document.createElement("div");t.setAttribute("tabindex","0"),constants.main_container.after(t),t.focus(),t.remove()}else if(-1==constants.tabMovement){let t=document.createElement("div");t.setAttribute("tabindex","0"),constants.main_container.before(t),t.focus(),t.remove()}}function DestroyMaidr(){"bar"!=constants.chartType&&"hist"!=constants.chartType||("function"==typeof plot.DeselectAll&&plot.DeselectAll(),"function"==typeof plot.UnSelectPrevious&&plot.UnSelectPrevious());for(let t=0;t<constants.events.length;t++)if(Array.isArray(constants.events[t][0]))for(let e=0;e<constants.events[t][0].length;e++)constants.events[t][0][e].removeEventListener(constants.events[t][1],constants.events[t][2]);else constants.events[t][0].removeEventListener(constants.events[t][1],constants.events[t][2]);for(let t=0;t<constants.postLoadEvents.length;t++)if(Array.isArray(constants.postLoadEvents[t][0]))for(let e=0;e<constants.postLoadEvents[t][0].length;e++)constants.postLoadEvents[t][0][e].removeEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);else constants.postLoadEvents[t][0].removeEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);constants.events=[],constants.postLoadEvents=[],constants.chartId=null,constants.chartType=null,constants.tabMovement=null,DestroyChartComponents(),window.review=null,window.display=null,window.control=null,window.plot=null,window.audio=null,window.singleMaidr=null}function KillAutoplayEvent(t){(constants.isMac?"Meta"==t.key||"ContextMenu"==t.key:"Control"==t.key)&&constants.KillAutoplay()}function SetEvents(){for(let t=0;t<constants.events.length;t++)if(Array.isArray(constants.events[t][0]))for(let e=0;e<constants.events[t][0].length;e++)constants.events[t][0][e]?.addEventListener(constants.events[t][1],constants.events[t][2]);else constants.events[t][0]?.addEventListener(constants.events[t][1],constants.events[t][2]);setTimeout((function(){for(let t=0;t<constants.postLoadEvents.length;t++)if(Array.isArray(constants.postLoadEvents[t][0]))for(let e=0;e<constants.postLoadEvents[t][0].length;e++)constants.postLoadEvents[t][0][e].addEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);else constants.postLoadEvents[t][0].addEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2])}),100)}function CreateChartComponents(t,e=!1){let n=document.getElementById(t.id),o=document.createElement("div");o.id=constants.main_container_id;let s=document.createElement("div");s.id=constants.chart_container_id,n.parentNode.replaceChild(o,n),o.appendChild(n),n.parentNode.replaceChild(s,n),s.appendChild(n),e||n.focus(),constants.chart=n,constants.chart_container=s,constants.main_container=o,e||(constants.chart_container.insertAdjacentHTML("beforebegin",'<div class="hidden" id="'+constants.braille_container_id+'">\n<input id="'+constants.braille_input_id+'" class="braille-input" type="text" size="'+constants.brailleDisplayLength+'" aria-brailleroledescription="" autocomplete="off" />\n</div>\n'),constants.chart_container.insertAdjacentHTML("afterend",'<br>\n<div id="'+constants.info_id+'" aria-live="assertive" aria-atomic="true">\n<p id="x"></p>\n<p id="y"></p>\n</div>\n'),document.getElementById(constants.info_id).insertAdjacentHTML("afterend",'<div id="announcements" aria-live="assertive" aria-atomic="true" class="mb-3"></div>\n'),document.getElementById(constants.info_id).insertAdjacentHTML("beforebegin",'<div id="'+constants.review_id_container+'" class="hidden sr-only sr-only-focusable"><input id="'+constants.review_id+'" type="text" size="50" autocomplete="off" /></div>'),constants.chart_container.setAttribute("role","application"),constants.brailleContainer=document.getElementById(constants.braille_container_id),constants.brailleInput=document.getElementById(constants.braille_input_id),constants.infoDiv=document.getElementById(constants.info_id),constants.announceContainer=document.getElementById(constants.announcement_container_id),constants.nonMenuFocus=constants.chart,constants.endChime=document.getElementById(constants.end_chime_id),constants.review_container=document.querySelector("#"+constants.review_id_container),constants.review=document.querySelector("#"+constants.review_id));let i="";if(document.getElementById(t.id).setAttribute("role","img"),"name"in t)i=t.name;else if("title"in t||"labels"in t&&"title"in t.labels){let e="title"in t?t.title:t.labels.title,n="This is a multi-layered plot. Use PageUp and PageDown to switch between layers.";i=`${Array.isArray(t.type)?t.type.slice(0,-1).join(", ")+" and "+t.type.slice(-1):t.type} plot of ${e}: Click to activate. Use Arrows to navigate data points. ${Array.isArray(t.type)&&t.type.length>1?n:" "}Toggle B for Braille, T for Text, S for Sonification, and R for Review mode. Use H for Help.`}i.length>0&&(document.getElementById(t.id).setAttribute("aria-label",i),document.getElementById(t.id).setAttribute("title",i))}function InitTracker(){constants.canTrack&&(window.tracker=new Tracker,document.getElementById("download_data_trigger")&&document.getElementById("download_data_trigger").addEventListener("click",(function(t){tracker.DownloadTrackerData()})),document.addEventListener("keydown",(function(t){("F5"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)||"R"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey))&&(t.preventDefault(),tracker.Delete(),location.reload(!0)),"F10"==t.key?tracker.DownloadTrackerData():plot&&tracker.LogEvent(t)})))}function DestroyChartComponents(){null!=constants.chart_container&&(null!=constants.chart&&null!=constants.chart_container.parentNode&&constants.chart_container.parentNode.replaceChild(constants.chart,constants.chart_container),constants.chart_container.remove()),null!=constants.brailleContainer&&constants.brailleContainer.remove(),null!=constants.infoDiv&&constants.infoDiv.remove(),null!=constants.announceContainer&&constants.announceContainer.remove(),null!=constants.endChime&&constants.endChime.remove(),null!=constants.review_container&&constants.review_container.remove(),"undefined"!=typeof menu&&null!==menu&&menu.Destroy(),"undefined"!=typeof description&&null!==description&&description.Destroy(),"undefined"!=typeof chatLLM&&null!==chatLLM&&chatLLM.Destroy();const t=document.querySelector("svg#scatter"),e=document.querySelector("svg#line"),n=document.querySelector("svg#heat");if(t)constants.KillAutoplay(),t.querySelectorAll(".highlight_point").forEach((t=>{t.remove()}));else if(e||n){const t=e?e.querySelector("#highlight_point"):n.querySelector("#highlight_rect");t&&(constants.KillAutoplay(),t.remove())}constants.chart=null,constants.chart_container=null,constants.brailleContainer=null,constants.brailleInput=null,constants.infoDiv=null,constants.announceContainer=null,constants.endChime=null,constants.review_container=null,menu=null,description=null}document.addEventListener("DOMContentLoaded",(function(t){window.constants=new Constants,window.resources=new Resources,window.logError=new LogError;let e,n=[];"undefined"!=typeof maidr&&(Array.isArray(maidr)?n=maidr:n.push(maidr)),DestroyMaidr(),window.maidrIds=[];for(let t=0;t<n.length;t++){let o=n[t].id;maidrIds.push(o),!e&&n[t]&&(e=n[t]);let s=document.getElementById(o);s&&(s.setAttribute("tabindex","0"),s.addEventListener("focus",(function(e){ShouldWeInitMaidr(n[t])})))}CreateChartComponents(e,!0)}));
\ No newline at end of file
+class Constants{chart_container_id="chart-container";main_container_id="maidr-container";braille_container_id="braille-div";braille_input_id="braille-input";info_id="info";announcement_container_id="announcements";end_chime_id="end_chime";container_id="container";project_id="maidr";review_id_container="review_container";review_id="review";reviewSaveSpot;reviewSaveBrailleMode;chartId="";events=[];postLoadEvents=[];constructor(){}textMode="verbose";brailleMode="off";lockSelection=!1;sonifMode="on";reviewMode="off";minX=0;maxX=0;minY=0;maxY=0;plotId="";chartType="";navigation=1;plotOrientation="horz";MAX_FREQUENCY=1e3;MIN_FREQUENCY=200;NULL_FREQUENCY=100;combinedVolMin=.25;combinedVolMax=1.25;MAX_SPEED=500;MIN_SPEED=50;DEFAULT_SPEED=250;INTERVAL=20;AUTOPLAY_DURATION=2e3;vol=.5;MAX_VOL=30;autoPlayRate=this.DEFAULT_SPEED;colorSelected="#03C809";brailleDisplayLength=32;showRect=1;hasRect=1;hasSmooth=1;duration=.3;outlierDuration=.06;autoPlayOutlierRate=50;autoPlayPointsRate=50;colorUnselected="#595959";canTrack=1;visualBraille=!1;ariaMode="assertive";userSettingsKeys=["vol","autoPlayRate","brailleDisplayLength","colorSelected","MIN_FREQUENCY","MAX_FREQUENCY","AUTOPLAY_DURATION","ariaMode","openAIAuthKey","geminiAuthKey","claudeAuthKey","emailAuthKey","skillLevel","skillLevelOther","LLMModel","LLMPreferences","LLMOpenAiMulti","LLMGeminiMulti","LLMModels","autoInitLLM","clientToken"];openAIAuthKey=null;geminiAuthKey=null;LLMmaxResponseTokens=1e3;playLLMWaitingSound=!0;LLMDetail="high";LLMModel="openai";LLMModels={openai:!0};LLMSystemMessage="You are a helpful assistant describing the chart to a blind person. ";skillLevel="basic";skillLevelOther="";autoInitLLM=!0;verboseText="";waitingQueue=0;showDisplay=1;showDisplayInBraille=1;showDisplayInAutoplay=0;outlierInterval=null;isMac=navigator.userAgent.toLowerCase().includes("mac");control=this.isMac?"Cmd":"Ctrl";alt=this.isMac?"option":"Alt";home=this.isMac?"fn + Left arrow":"Home";end=this.isMac?"fn + Right arrow":"End";keypressInterval=2e3;tabMovement=null;debugLevel=3;canPlayEndChime=!1;manualData=!0;baseURL="https://maidr-service.azurewebsites.net/api/";code="?code=I8Aa2PlPspjQ8Hks0QzGyszP8_i2-XJ3bq7Xh8-ykEe4AzFuYn_QWA%3D%3D";clientToken=null;KillAutoplay(){clearInterval(this.autoplayId),this.autoplayId=null}KillSepPlay(){this.sepPlayId&&(clearInterval(this.sepPlayId),this.sepPlayId=null)}SpeedUp(){constants.autoPlayRate-this.INTERVAL>this.MIN_SPEED&&(constants.autoPlayRate-=this.INTERVAL)}SpeedDown(){constants.autoPlayRate+this.INTERVAL<=this.MAX_SPEED&&(constants.autoPlayRate+=this.INTERVAL)}SpeedReset(){constants.autoPlayRate=constants.DEFAULT_SPEED}ConvertHexToRGBString(t){return"rgb("+parseInt(t.slice(1,3),16)+","+parseInt(t.slice(3,5),16)+","+parseInt(t.slice(5,7),16)+")"}ConvertRGBStringToHex(t){let e=t.replace(/[^\d,]/g,"").split(",");return"#"+e[0].toString(16).padStart(2,"0")+e[1].toString(16).padStart(2,"0")+e[2].toString(16).padStart(2,"0")}ColorInvert(t){let e=t.replace(/[^\d,]/g,"").split(",");return"rgb("+(255-e[0])+","+(255-e[1])+","+(255-e[2])+")"}GetBetterColor(t){-1!==t.indexOf("#")&&(t=this.ConvertHexToRGBString(t));let e=this.ColorInvert(t),n=e.replace(/[^\d,]/g,"").split(",");return n[1]<n[0]+10&&n[1]>n[0]-10&&n[2]<n[0]+10&&n[2]>n[0]-10&&(n[0]>86||n[0]<169)&&(e=this.colorSelected),e}GetStyleArrayFromString(t){return t.replaceAll(" ","").split(/[:;]/)}GetStyleStringFromArray(t){let e="";for(let n=0;n<t.length;n++)n%2==0?n!==t.length-1?e+=t[n]+": ":e+=t[n]:e+=t[n]+"; ";return e}}class Resources{constructor(){}language="en";knowledgeLevel="basic";strings={en:{basic:{upper_outlier:"Upper Outlier",lower_outlier:"Lower Outlier",min:"Minimum",max:"Maximum",25:"25%",50:"50%",75:"75%",q1:"25%",q2:"50%",q3:"75%",son_on:"Sonification on",son_off:"Sonification off",son_des:"Sonification descrete",son_comp:"Sonification compare",son_ch:"Sonification chord",son_sep:"Sonification separate",son_same:"Sonification combined",empty:"Empty",openai:"OpenAI Vision",gemini:"Gemini Pro Vision",claude:"Claude",multi:"Multiple AI",processing:"Processing Chart..."}}};GetString(t){return this.strings[this.language][this.knowledgeLevel][t]}}class Menu{whereWasMyFocus=null;constructor(){this.CreateMenu(),this.LoadDataFromLocalStorage()}menuHtml=`\n        <div id="menu" class="modal hidden" role="dialog" tabindex="-1">\n            <div class="modal-dialog" role="document" tabindex="0">\n                <div class="modal-content">\n                    <div class="modal-header">\n                        <h2 class="modal-title">Menu</h2>\n                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n                            <span aria-hidden="true">&times;</span>\n                        </button>\n                    </div>\n                    <div class="modal-body">\n                        <div>\n                            <h5 class="modal-title">Keyboard Shortcuts</h5>\n                            <table>\n                                <caption class="sr-only">Keyboard Shortcuts</caption>\n                                <thead>\n                                    <tr>\n                                        <th scope="col">Function</th>\n                                        <th scope="col">Key</th>\n                                    </tr>\n                                </thead>\n                                <tbody>\n                                    <tr>\n                                        <td>Move around plot</td>\n                                        <td>Arrow keys</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Go to the very left right up down</td>\n                                        <td>${constants.control} + Arrow key</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Select the first element</td>\n                                        <td>${constants.control} + ${constants.home}</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Select the last element</td>\n                                        <td>${constants.control} + ${constants.end}</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Toggle Braille Mode</td>\n                                        <td>b</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Toggle Text Mode</td>\n                                        <td>t</td>\n                                    </tr>\n                                                                        <tr>\n                                        <td>Toggle Sonification Mode</td>\n                                        <td>s</td>\n                                    </tr>\n                                                                                                            <tr>\n                                        <td>Toggle Review Mode</td>\n                                        <td>r</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Repeat current sound</td>\n                                        <td>Space</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Auto-play outward in direction of arrow</td>\n                                        <td>${constants.control} + Shift + Arrow key</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Auto-play inward in direction of arrow</td>\n                                        <td>${constants.alt} + Shift + Arrow key</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Stop Auto-play</td>\n                                        <td>${constants.control}</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Auto-play speed up</td>\n                                        <td>Period (.)</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Auto-play speed down</td>\n                                        <td>Comma (,)</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Auto-play speed reset</td>\n                                        <td>Slash (/)</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Check label for the title of current plot</td>\n                                        <td>l t</td>\n                                    </tr>\n                                                                            <td>Check label for the x axis of current plot</td>\n                                        <td>l x</td>\n                                    </tr>\n                                                                                                                <td>Check label for the y axis of current plot</td>\n                                        <td>l y</td>\n                                    </tr>\n                                                                                                                <td>Check label for the fill (z) axis of current plot</td>\n                                        <td>l f</td>\n                                    </tr>\n                                                                                                                <td>Check label for the subtitle of current plot</td>\n                                        <td>l s</td>\n                                    </tr>\n                                                                                                                <td>Check label for the caption of current plot</td>\n                                        <td>l c</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Toggle AI Chat View</td>\n                                        <td>${constants.isMac?constants.alt:constants.control} + Shift + /</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Copy last chat message in AI Chat View</td>\n                                        <td>${constants.alt} + Shift + C</td>\n                                    </tr>\n                                    <tr>\n                                        <td>Copy full chat history in AI Chat View</td>\n                                        <td>${constants.alt} + Shift + A</td>\n                                    </tr>\n                                </tbody>\n                            </table>\n                        </div>\n\n                        <div>\n                            <h5 class="modal-title">Settings</h5>\n                            <p><input type="range" id="vol" name="vol" min="0" max="1" step=".05"><label for="vol">Volume</label></p>\n                            \x3c!-- <p><input type="checkbox" id="show_rect" name="show_rect"><label for="show_rect">Show Outline</label></p> //--\x3e\n                            <p><input type="color" id="color_selected" name="color_selected"><label for="color_selected">Outline Color</label></p>\n                            <p><input type="number" min="4" max="2000" step="1" id="braille_display_length" name="braille_display_length"><label for="braille_display_length">Braille Display Size</label></p>\n                            <p><input type="number" min="10" max="2000" step="10" id="min_freq" name="min_freq"><label for="min_freq">Min Frequency (Hz)</label></p>\n                            <p><input type="number" min="20" max="2010" step="10" id="max_freq" name="max_freq"><label for="max_freq">Max Frequency (Hz)</label></p>\n                                                     <p>                            <p><input type="number" min="500" max="500000" step="500" id="AUTOPLAY_DURATION">Autoplay Duration (ms)</label></p>\n                            <div><fieldset>\n                              <legend>Aria Mode</legend>\n                              <p><input type="radio" id="aria_mode_assertive" name="aria_mode" value="assertive" ${"assertive"==constants.ariaMode?"checked":""}><label for="aria_mode_assertive">Assertive</label></p>\n                              <p><input type="radio" id="aria_mode_polite" name="aria_mode" value="polite" ${"polite"==constants.ariaMode?"checked":""}><label for="aria_mode_polite">Polite</label></p>\n                              </fieldset></div>\n                            <p class="hidden">\n                                <select id="LLM_model">\n                                    <option value="openai">OpenAI Vision</option>\n                                    <option value="gemini">Gemini Pro Vision</option>\n                                    <option value="multi">Multiple</option>\n                                </select>\n                                <label for="LLM_model">LLM Model</label>\n                            </p>\n                            <h5 class="modal-title">LLM Settings</h5>\n                            <p>\n                              <fieldset>\n                                <legend>LLM Models (select up to 2)</legend>\n                                <p><input type="checkbox" id="LLM_model_openai" name="LLM_model" value="openai"><label for="LLM_model_openai">OpenAI Vision</label></p>\n                                <p><input type="checkbox" id="LLM_model_gemini" name="LLM_model" value="gemini"><label for="LLM_model_gemini">Gemini Pro Vision</label></p>\n                                <p><input type="checkbox" id="LLM_model_claude" name="LLM_model" value="claude"><label for="LLM_model_claude">Claude</label></p>\n                              </fieldset>\n                            </p>\n                            <p id="email_auth_key_container" class="multi_container">\n                              <input type="email" size="50" id="email_auth_key" aria-label="Enter your email address">\n                              <button aria-label="Delete Email Address" title="Delete Email Address" id="delete_email_key" class="invis_button">&times;</button>\n                              <label for="gemini_auth_key">Email Authentication</label>\n                              <button type="button" id="verify">Verify</button>\n                            </p>\n                            <p id="openai_auth_key_container" class="multi_container hidden">\n                              <span id="openai_multi_container" class="hidden"><input type="checkbox" id="openai_multi" name="openai_multi" aria-label="Use OpenAI in Multi modal mode"></span>\n                              <input type="password" size="50" id="openai_auth_key"><button aria-label="Delete OpenAI key" title="Delete OpenAI key" id="delete_openai_key" class="invis_button">&times;</button><label for="openai_auth_key">OpenAI Authentication Key</label>\n                            </p>\n                            <p id="gemini_auth_key_container" class="multi_container hidden">\n                              <span id="gemini_multi_container" class="hidden"><input type="checkbox" id="gemini_multi" name="gemini_multi" aria-label="Use Gemini in Multi modal mode"></span>\n                              <input type="password" size="50" id="gemini_auth_key"><button aria-label="Delete Gemini key" title="Delete Gemini key" id="delete_gemini_key" class="invis_button">&times;</button><label for="gemini_auth_key">Gemini Authentication Key</label>\n                            </p>\n                             <p id="claude_auth_key_container" class="multi_container hidden">\n                              <span id="claude_multi_container" class="hidden"><input type="checkbox" id="claude_multi" name="claude_multi" aria-label="Use Claude in Multi modal mode"></span>\n                              <input type="password" size="50" id="claude_auth_key"><button aria-label="Delete Claude key" title="Delete Claude key" id="delete_claude_key" class="invis_button">&times;</button><label for="claude_auth_key">Claude Authentication Key</label>\n                            </p>\n                            <p><input type="checkbox" ${constants.autoInitLLM?"checked":""} id="init_llm_on_load" name="init_llm_on_load"><label for="init_llm_on_load">Start LLM right away</label></p>\n                            <p>\n                                <select id="skill_level">\n                                    <option value="basic">Basic</option>\n                                    <option value="intermediate">Intermediate</option>\n                                    <option value="expert">Expert</option>\n                                    <option value="other">Other: describe in your own words</option>\n                                </select>\n                                <label for="skill_level">Level of skill in statistical charts</label>\n                            </p>\n                            <p id="skill_level_other_container" class="hidden"><input type="text" placeholder="Very basic" id="skill_level_other"> <label for="skill_level_other">Describe your level of skill in statistical charts</label></p>\n                            <p><label for="LLM_preferences">Custom instructions for the chat response</label></p>\n                            <p><textarea id="LLM_preferences" rows="4" cols="50" placeholder="I'm a stats undergrad and work with Python. I prefer a casual tone, and favor information accuracy over creative description; just the facts please!"></textarea></p>\n                        </div>\n                    </div>\n                    <div class="modal-footer">\n                      <p>\n                        <button type="button" id="save_and_close_menu" aria-labelledby="save_and_close_text"><span id="save_and_close_text">Save and Close</span></button>\n                        <button type="button" id="close_menu">Close</button>\n                      </p>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <div id="menu_modal_backdrop" class="modal-backdrop hidden"></div>\n        `;CreateMenu(){document.querySelector("body").insertAdjacentHTML("beforeend",this.menuHtml);let t=document.querySelectorAll("#close_menu, #menu .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){menu.Toggle(!1)}]);constants.events.push([document.getElementById("save_and_close_menu"),"click",function(t){menu.SaveData(),menu.Toggle(!1)}]),constants.events.push([document.getElementById("verify"),"click",function(t){menu.VerifyEmail()}]),constants.events.push([document.getElementById("menu"),"keyup",function(t){"Esc"==t.key&&menu.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){"input"!=t.target.tagName.toLowerCase()&&"textarea"!=t.target.tagName.toLowerCase()&&"h"==t.key&&menu.Toggle(!0)}]),constants.events.push([document.getElementById("LLM_model"),"change",function(t){"openai"==t.target.value?(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.add("hidden"),document.getElementById("openai_multi_container").classList.add("hidden"),document.getElementById("gemini_multi_container").classList.add("hidden"),document.getElementById("openai_multi").checked=!0,document.getElementById("gemini_multi").checked=!1):"gemini"==t.target.value?(document.getElementById("openai_auth_key_container").classList.add("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden"),document.getElementById("openai_multi_container").classList.add("hidden"),document.getElementById("gemini_multi_container").classList.add("hidden"),document.getElementById("openai_multi").checked=!1,document.getElementById("gemini_multi").checked=!0):"multi"==t.target.value&&(document.getElementById("openai_auth_key_container").classList.remove("hidden"),document.getElementById("gemini_auth_key_container").classList.remove("hidden"),document.getElementById("openai_multi_container").classList.remove("hidden"),document.getElementById("gemini_multi_container").classList.remove("hidden"),document.getElementById("openai_multi").checked=!0,document.getElementById("gemini_multi").checked=!0)}]),constants.events.push([document.getElementById("LLM_model_openai"),"change",function(t){constants.clientToken&&constants.emailAuthKey?console.log("Client token and email auth key already set"):t.target.checked?document.getElementById("openai_auth_key_container").classList.remove("hidden"):document.getElementById("openai_auth_key_container").classList.add("hidden")}]),constants.events.push([document.getElementById("LLM_model_gemini"),"change",function(t){constants.clientToken&&constants.emailAuthKey?console.log("Client token and email auth key already set"):t.target.checked?document.getElementById("gemini_auth_key_container").classList.remove("hidden"):document.getElementById("gemini_auth_key_container").classList.add("hidden")}]),constants.events.push([document.getElementById("LLM_model_claude"),"change",function(t){constants.clientToken&&constants.emailAuthKey?console.log("Client token and email auth key already set"):document.getElementById("claude_auth_key_container").classList.add("hidden")}]),constants.events.push([document.getElementById("email_auth_key").addEventListener("keydown",(function(t){"Enter"===t.key&&document.getElementById("verify").click()}))]),constants.events.push([document.getElementById("email_auth_key"),"input",function(t){t.target.value?document.getElementById("delete_email_key").style="":document.getElementById("delete_email_key").style="display: none"}]),constants.events.push([document.getElementById("skill_level"),"change",function(t){"other"==t.target.value?document.getElementById("skill_level_other_container").classList.remove("hidden"):document.getElementById("skill_level_other_container").classList.add("hidden")}]);let e=["LLM_model","openai_multi","gemini_multi","skill_level","LLM_preferences"];for(let t=0;t<e.length;t++)constants.events.push([document.getElementById(e[t]),"change",function(t){menu.NotifyOfLLMReset()}]);document.querySelectorAll('input[name="LLM_model"]').forEach((t=>{t.addEventListener("change",(()=>{const e=document.querySelectorAll('input[name="LLM_model"]:checked');e.length>2?(t.checked=!1,alert("You can select up to 2 AI models.")):0===e.length&&(t.checked=!0,alert("You must select at least one AI model."))}))}))}Destroy(){let t=document.getElementById("menu");t&&t.remove();let e=document.getElementById("menu_modal_backdrop");e&&e.remove()}Toggle(t=!1){void 0===t&&(t=!!document.getElementById("menu").classList.contains("hidden")),t&&document.getElementById("chatLLM")&&!document.getElementById("chatLLM").classList.contains("hidden")||(t?(this.whereWasMyFocus=document.activeElement,this.PopulateData(),constants.tabMovement=0,document.getElementById("menu").classList.remove("hidden"),document.getElementById("menu_modal_backdrop").classList.remove("hidden"),document.querySelector("#menu .close").focus()):(document.getElementById("menu").classList.add("hidden"),document.getElementById("menu_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null))}PopulateData(){if(document.getElementById("vol").value=constants.vol,document.getElementById("braille_display_length").value=constants.brailleDisplayLength,document.getElementById("color_selected").value=constants.colorSelected,document.getElementById("min_freq").value=constants.MIN_FREQUENCY,document.getElementById("max_freq").value=constants.MAX_FREQUENCY,document.getElementById("AUTOPLAY_DURATION").value=constants.AUTOPLAY_DURATION,"string"==typeof constants.openAIAuthKey&&(document.getElementById("openai_auth_key").value=constants.openAIAuthKey),"string"==typeof constants.emailAuthKey&&(document.getElementById("email_auth_key").value=constants.emailAuthKey),"string"==typeof constants.geminiAuthKey&&(document.getElementById("gemini_auth_key").value=constants.geminiAuthKey),"string"==typeof constants.claudeAuthKey&&(document.getElementById("claude_auth_key").value=constants.claudeAuthKey),document.getElementById("skill_level").value=constants.skillLevel,constants.skillLevelOther&&(document.getElementById("skill_level_other").value=constants.skillLevelOther),"assertive"==constants.ariaMode?(document.getElementById("aria_mode_assertive").checked=!0,document.getElementById("aria_mode_polite").checked=!1):(document.getElementById("aria_mode_polite").checked=!0,document.getElementById("aria_mode_assertive").checked=!1),constants.emailAuthKey&&constants.clientToken)console.log("email auth key and client token found"),this.DisableLLMAPIKeys();else for(let t in constants.LLMModels)document.getElementById(`LLM_model_${t}`).checked=!0,document.getElementById(`${t}_auth_key_container`).classList.remove("hidden");document.getElementById("claude_auth_key_container").classList.add("hidden"),constants.emailAuthKey||(document.getElementById("delete_email_key").style="display: none"),"other"==constants.skillLevel&&document.getElementById("skill_level_other_container").classList.remove("hidden"),constants.LLMPreferences&&(document.getElementById("LLM_preferences").value=constants.LLMPreferences),document.getElementById("LLM_reset_notification")&&document.getElementById("LLM_reset_notification").remove()}SaveData(){let t=this.ShouldLLMReset();constants.vol=document.getElementById("vol").value,constants.brailleDisplayLength=document.getElementById("braille_display_length").value,constants.colorSelected=document.getElementById("color_selected").value,constants.MIN_FREQUENCY=document.getElementById("min_freq").value,constants.MAX_FREQUENCY=document.getElementById("max_freq").value,constants.AUTOPLAY_DURATION=document.getElementById("AUTOPLAY_DURATION").value,constants.openAIAuthKey=document.getElementById("openai_auth_key").value,constants.geminiAuthKey=document.getElementById("gemini_auth_key").value,constants.claudeAuthKey=document.getElementById("claude_auth_key").value,constants.emailAuthKey=document.getElementById("email_auth_key").value,constants.skillLevel=document.getElementById("skill_level").value,constants.skillLevelOther=document.getElementById("skill_level_other").value;document.querySelectorAll('input[name="LLM_model"]').forEach((t=>{t.checked?constants.LLMModels[t.value]=!0:delete constants.LLMModels[t.value]})),constants.LLMPreferences=document.getElementById("LLM_preferences").value,constants.LLMOpenAiMulti=document.getElementById("openai_multi").checked,constants.LLMGeminiMulti=document.getElementById("gemini_multi").checked,constants.autoInitLLM=document.getElementById("init_llm_on_load").checked,document.getElementById("aria_mode_assertive").checked?constants.ariaMode="assertive":document.getElementById("aria_mode_polite").checked&&(constants.ariaMode="polite"),this.SaveDataToLocalStorage(),this.UpdateHtml(),t&&chatLLM&&chatLLM.ResetLLM()}DisableLLMAPIKeys(){document.getElementById("email_auth_key").disabled=!0,document.getElementById("verify").classList.add("hidden")}isEmailTriggered=!1;VerifyEmail(){if(console.log("verify email"),!this.isEmailTriggered){this.isEmailTriggered=!0;let t=document.getElementById("email_auth_key").value;if(t&&-1!==t.indexOf("@")){let e=constants.baseURL+"send_email"+constants.code,n={email:t};fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authentication:constants.emailAuthKey},body:JSON.stringify(n)}).then((t=>t.json())).then((t=>{if(t&&t.message&&t.client_token){alert(t.message),constants.clientToken=t.client_token,this.DisableLLMAPIKeys();for(let t in constants.LLMModels)document.getElementById(`${t}_auth_key_container`).classList.add("hidden");this.SaveDataToLocalStorage(),this.isEmailTriggered=!1}else console.log(t),alert(t.data),this.isEmailTriggered=!1})).catch((t=>{console.log(t),alert(t.data),this.isEmailTriggered=!1}))}else alert("Please enter a valid email address."),this.isEmailTriggered=!1}}UpdateHtml(){constants.infoDiv.setAttribute("aria-live",constants.ariaMode),document.getElementById(constants.announcement_container_id).setAttribute("aria-live",constants.ariaMode),document.getElementById("init_llm_on_load").checked=constants.autoInitLLM;const t=document.getElementsByClassName("highlight_point"),e=document.getElementById("highlight_rect"),n=document.getElementById("highlight_point");if(null!==t&&t.length>0)for(let e=0;e<t.length;e++)t[e].setAttribute("stroke",constants.colorSelected),t[e].setAttribute("fill",constants.colorSelected);null!==e&&e.setAttribute("stroke",constants.colorSelected),null!==n&&n.setAttribute("stroke",constants.colorSelected)}NotifyOfLLMReset(){document.getElementById("LLM_reset_notification")&&document.getElementById("LLM_reset_notification").remove(),document.getElementById("save_and_close_menu").parentElement.insertAdjacentHTML("afterend",'<p id="LLM_reset_notification">Note: Changes in LLM settings will reset any existing conversation.</p>'),document.getElementById("save_and_close_menu").setAttribute("aria-labelledby","save_and_close_text LLM_reset_notification")}ShouldLLMReset(){let t=!1;t||constants.skillLevel==document.getElementById("skill_level").value||(t=!0),t||constants.LLMPreferences==document.getElementById("LLM_preferences").value||(t=!0),t||constants.LLMModel==document.getElementById("LLM_model").value||(t=!0);let e=document.querySelectorAll('input[name="LLM_model"]');for(let n=0;n<e.length;n++)t||constants.LLMModels[e[n].value]==e[n].checked||(t=!0);return t}SaveDataToLocalStorage(){let t={};for(let e=0;e<constants.userSettingsKeys.length;e++)t[constants.userSettingsKeys[e]]=constants[constants.userSettingsKeys[e]];localStorage.setItem("settings_data",JSON.stringify(t)),constants.canTrack&&(t.openAIAuthKey="hidden",t.geminiAuthKey="hidden",t.claudeAuthKey="hidden",t.timestamp=(new Date).toISOString(),tracker.SetData("settings",t))}LoadDataFromLocalStorage(){let t=JSON.parse(localStorage.getItem("settings_data"));if(t)for(let e=0;e<constants.userSettingsKeys.length;e++){const n=constants.userSettingsKeys[e];n in t&&(constants[n]=t[n])}this.PopulateData(),this.UpdateHtml()}}class ChatLLM{constructor(){this.firstTime=!0,this.firstMulti=!0,this.firstOpen=!0,this.shown=!1,this.CreateComponent(),this.SetEvents(),constants.autoInitLLM&&("gemini"in constants.LLMModels&&constants.geminiAuthKey||"openai"in constants.LLMModels&&constants.openAIAuthKey||"claude"in constants.LLMModels&&constants.claudeAuthKey)&&this.InitChatMessage()}CreateComponent(){let t=`\n        <div id="chatLLM" class="modal hidden" role="dialog" tabindex="-1">\n            <div class="modal-dialog" role="document" tabindex="0">\n                <div class="modal-content">\n                    <div class="modal-header">\n                        <h2 id="chatLLM_title" class="modal-title">Ask a Question</h2>\n                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n                            <span aria-hidden="true">&times;</span>\n                        </button>\n                    </div>\n                    <div class="modal-body">\n                        <div id="chatLLM_chat_history_wrapper">\n                        <div id="chatLLM_chat_history" aria-live="${constants.ariaMode}" aria-relevant="additions">\n                        </div>\n                        <p id="chatLLM_copy_all_wrapper"><button id="chatLLM_copy_all">Copy all to clipboard</button></p>\n                        </div>\n                        <div id="chatLLM_content">\n                          <p><input type="text" id="chatLLM_input" class="form-control" name="chatLLM_input" aria-labelledby="chatLLM_title" size="50"></p>\n                          <div class="LLM_suggestions">\n                            <p><button type="button">What is the title?</button></p>\n                            <p><button type="button">What are the high and low values?</button></p>\n                            <p><button type="button">What is the general shape of the chart?</button></p>\n                          </div>\n                          <div id="more_suggestions_container" class="LLM_suggestions">\n                            <p><button type="button">Please provide the title of this visualization, then provide a description for someone who is blind or low vision. Include general overview of axes and the data at a high-level.</button></p>\n                            <p><button type="button">For the visualization I shared, please provide the following (where applicable): mean, standard deviation, extreme, correlations, relational comparisons like greater than OR lesser than.</button></p>\n                            <p><button type="button">Based on the visualization shared, address the following: Do you observe any unforeseen trends? If yes, what?  Please convey any complex multi-faceted patterns present. Can you identify any noteworthy exceptions that aren't readily apparent through non-visual methods of analysis?</button></p>\n                            <p><button type="button">Provide context to help explain the data depicted in this visualization based on domain-specific insight.</button></p>\n                          </div>\n                          <p><button type="button" id="chatLLM_submit">Submit</button></p>\n                        </div>\n                    </div>\n                    <div class="modal-footer">\n                      <button type="button" id="reset_chatLLM">Reset</button>\n                      <button type="button" id="close_chatLLM">Close</button>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <div id="chatLLM_modal_backdrop" class="modal-backdrop hidden"></div>\n    `;document.querySelector("body").insertAdjacentHTML("beforeend",t)}SetEvents(){let t=document.querySelectorAll("#close_chatLLM, #chatLLM .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){chatLLM.Toggle(!1)}]);constants.events.push([document.getElementById("chatLLM"),"keyup",function(t){"Esc"==t.key&&chatLLM.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){("?"==t.key&&(t.ctrlKey||t.metaKey)||"¿"==t.key)&&chatLLM.Toggle()}]),constants.events.push([document.getElementById("chatLLM_submit"),"click",function(t){let e=document.getElementById("chatLLM_input").value;chatLLM.DisplayChatMessage("User",e),chatLLM.Submit(e)}]),constants.events.push([document.getElementById("chatLLM_input"),"keyup",function(t){if("Enter"==t.key&&!t.shiftKey){let t=document.getElementById("chatLLM_input").value;chatLLM.DisplayChatMessage("User",t),chatLLM.Submit(t)}}]);let e=document.querySelectorAll("#chatLLM .LLM_suggestions button:not(#more_suggestions)");for(let t=0;t<e.length;t++)constants.events.push([e[t],"click",function(t){let e=t.target.innerHTML;chatLLM.DisplayChatMessage("User",e),chatLLM.Submit(e)}]);constants.events.push([document.getElementById("delete_openai_key"),"click",function(t){document.getElementById("openai_auth_key").value=""}]),constants.events.push([document.getElementById("delete_email_key"),"click",function(t){document.getElementById("email_auth_key").value="",document.getElementById("email_auth_key").disabled=!1,document.getElementById("delete_email_key").style="display: none",constants.clientToken="",document.getElementById("verify").classList.remove("hidden")}]),constants.events.push([document.getElementById("delete_gemini_key"),"click",function(t){document.getElementById("gemini_auth_key").value=""}]),constants.events.push([document.getElementById("reset_chatLLM"),"click",function(t){chatLLM.ResetLLM()}]),constants.events.push([document.getElementById("chatLLM"),"click",function(t){chatLLM.CopyChatHistory(t)}]),constants.events.push([document.getElementById("chatLLM"),"keyup",function(t){chatLLM.CopyChatHistory(t)}])}CopyChatHistory(t){let e="";if(void 0===t)e=document.getElementById("chatLLM_chat_history").innerHTML;else if("click"==t.type)"chatLLM_copy_all"==t.target.id?e=document.getElementById("chatLLM_chat_history").innerHTML:t.target.classList.contains("chatLLM_message_copy_button")&&(e=t.target.closest("p").previousElementSibling.innerHTML);else if("keyup"==t.type)if("C"==t.key&&(t.ctrlKey||t.metaKey||t.altKey)&&t.shiftKey){t.preventDefault();let n=document.querySelector("#chatLLM_chat_history > .chatLLM_message_other:last-of-type");n&&(e=n.innerHTML)}else"A"==t.key&&(t.ctrlKey||t.metaKey||t.altKey)&&t.shiftKey&&(t.preventDefault(),e=document.getElementById("chatLLM_chat_history").innerHTML);if(""!=e){let t=document.createElement("div");t.innerHTML=e,t.querySelectorAll(".chatLLM_message_copy").forEach((t=>t.remove()));let n=this.htmlToMarkdown(t);n=n.replace(/\n{3,}/g,"\n\n");try{navigator.clipboard.writeText(n)}catch(t){console.error("Failed to copy: ",t)}return n}}htmlToMarkdown(t){let e="";const n=t=>{switch(t.tagName){case"H1":return`# ${t.textContent}`;case"H2":return`## ${t.textContent}`;case"H3":return`### ${t.textContent}`;case"H4":return`#### ${t.textContent}`;case"H5":return`##### ${t.textContent}`;case"H6":return`###### ${t.textContent}`;case"P":return t.textContent;case"DIV":return Array.from(t.childNodes).map((t=>n(t))).join("\n")+"\n\n";default:return Array.from(t.childNodes).map((t=>n(t))).join("")}};return t.nodeType===Node.ELEMENT_NODE?e+=n(t):t.nodeType===Node.TEXT_NODE&&""!==t.textContent.trim()&&(e+=t.textContent.trim()),e.trim()}async Submit(t,e=!1){let n=null;this.firstMulti=!0,(this.firstOpen||"gemini"in constants.LLMModels)&&!e&&constants.verboseText.length>0&&(t="Here is the current position in the chart; no response necessarily needed, use this info only if it's relevant to future questions: "+constants.verboseText+". My question is: "+t,this.firstOpen=!1),constants.playLLMWaitingSound&&this.WaitingSound(!0),"openai"in constants.LLMModels&&(e&&(n=await this.ConvertSVGtoJPG(singleMaidr.id,"openai")),constants.openAIAuthKey?chatLLM.OpenAIPrompt(t,n):chatLLM.OpenAIPromptAPI(t,n)),"gemini"in constants.LLMModels&&(e&&(n=await this.ConvertSVGtoJPG(singleMaidr.id,"gemini")),constants.geminiAuthKey?chatLLM.GeminiPrompt(t,n):chatLLM.GeminiPromptAPI(t,n)),"claude"in constants.LLMModels&&(e&&(n=await this.ConvertSVGtoJPG(singleMaidr.id,"claude")),constants.claudeAuthKey?chatLLM.ClaudePrompt(t,n):chatLLM.ClaudePromptAPI(t,n))}WaitingSound(t=!0){t?(constants.waitingInterval&&(clearInterval(constants.waitingInterval),constants.waitingInterval=null),constants.waitingSoundOverride&&(clearTimeout(constants.waitingSoundOverride),constants.waitingSoundOverride=null)):(audio&&chatLLM.shown&&audio.playOscillator(880,.2,0),constants.waitingQueue>1?constants.waitingQueue--:chatLLM.KillAllWaitingSounds()),t&&(constants.waitingInterval=setInterval((function(){audio&&chatLLM.shown&&audio.playOscillator(440,.2,0)}),1e3),constants.waitingSoundOverride=setTimeout((function(){chatLLM.KillAllWaitingSounds()}),3e4),"multi"!=constants.LLMModel?constants.waitingQueue=1:(constants.waitingQueue=0,constants.LLMGeminiMulti&&constants.waitingQueue++,constants.LLMOpenAiMulti&&constants.waitingQueue++))}KillAllWaitingSounds(){constants.waitingInterval&&(clearInterval(constants.waitingInterval),constants.waitingInterval=null),constants.waitingSoundOverride&&(clearTimeout(constants.waitingSoundOverride),constants.waitingSoundOverride=null),constants.waitingQueue=0}InitChatMessage(){let t=resources.GetString(constants.LLMModel);this.firstTime=!1,this.DisplayChatMessage(t,resources.GetString("processing"),!0);let e=this.GetDefaultPrompt();this.Submit(e,!0)}ProcessLLMResponse(t,e){chatLLM.WaitingSound(!1);let n="",o=resources.GetString(e);if("openai"==e){n=t.choices[0].message.content;let e=this.requestJson.messages.length;this.requestJson.messages[e]={},this.requestJson.messages[e].role="assistant",this.requestJson.messages[e].content=n,t.error?(chatLLM.DisplayChatMessage(o,"Error processing request.",!0),chatLLM.WaitingSound(!1)):chatLLM.DisplayChatMessage(o,n)}else"gemini"==e&&(t.text()?(n=t.text(),chatLLM.DisplayChatMessage(o,n)):t.error||(t.error="Error processing request.",chatLLM.WaitingSound(!1)),t.error&&(chatLLM.DisplayChatMessage(o,"Error processing request.",!0),chatLLM.WaitingSound(!1)));if("claude"==e&&(console.log("Claude response: ",t),t.text()&&(n=t.text(),chatLLM.DisplayChatMessage(o,n)),t.error&&(chatLLM.DisplayChatMessage(o,"Error processing request.",!0),chatLLM.WaitingSound(!1))),constants.canTrack){let t=chatLLM.CopyChatHistory();tracker.SetData("ChatHistory",t)}}fakeLLMResponseData(){let t={};return t=this.requestJson.messages.length>2?{id:"chatcmpl-8Y44iRCRrohYbAqm8rfBbJqTUADC7",object:"chat.completion",created:1703129508,model:"gpt4-o",usage:{prompt_tokens:451,completion_tokens:16,total_tokens:467},choices:[{message:{role:"assistant",content:"A fake response from the LLM. Nice."},finish_reason:"length",index:0}]}:{id:"chatcmpl-8Y44iRCRrohYbAqm8rfBbJqTUADC7",object:"chat.completion",created:1703129508,model:"gpt-4-1106-vision-preview",usage:{prompt_tokens:451,completion_tokens:16,total_tokens:467},choices:[{message:{role:"assistant",content:"The chart you're referring to is a bar graph titled \"The Number of Diamonds"},finish_reason:"length",index:0}]},t}ClaudeJson(t,e=null){const n={anthropic_version:"vertex-2023-10-16",max_tokens:256,messages:[]},o={role:"user",content:[]};return e?o.content.push({type:"image",source:{type:"base64",media_type:"image/jpeg",data:e}},{type:"text",text:t}):o.content.push({type:"text",text:t}),n.messages.push(o),n}ClaudePromptAPI(t,e=null){console.log("Claude prompt API");let n=constants.baseURL+"claude"+constants.code,o=constants.LLMSystemMessage;constants.LLMPreferences&&(o+=constants.LLMPreferences),o+="\n\n"+t,null==e?e=constants.LLMImage:constants.LLMImage=e,constants.LLMImage=e;let s=chatLLM.ClaudeJson(o,e);fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authentication:constants.emailAuthKey+" "+constants.clientToken},body:JSON.stringify(s)}).then((t=>t.json())).then((t=>{t.text=function(){return t.content[0].text},chatLLM.ProcessLLMResponse(t,"claude")})).catch((t=>{chatLLM.WaitingSound(!1),console.error("Error:",t),chatLLM.DisplayChatMessage("Claude","Error processing request.",!0)}))}OpenAIPrompt(t,e=null){let n=constants.openAIAuthKey,o=chatLLM.OpenAIJson(t,e);fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer "+n},body:JSON.stringify(o)}).then((t=>t.json())).then((t=>{chatLLM.ProcessLLMResponse(t,"openai")})).catch((t=>{chatLLM.WaitingSound(!1),console.error("Error:",t),chatLLM.DisplayChatMessage("OpenAI","Error processing request.",!0)}))}OpenAIPromptAPI(t,e=null){let n=constants.baseURL+"openai"+constants.code,o=(constants.openAIAuthKey,chatLLM.OpenAIJson(t,e));fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authentication:constants.emailAuthKey+" "+constants.clientToken},body:JSON.stringify(o)}).then((t=>t.json())).then((t=>{chatLLM.ProcessLLMResponse(t,"openai")})).catch((t=>{chatLLM.WaitingSound(!1),console.error("Error:",t),chatLLM.DisplayChatMessage("OpenAI","Error processing request.",!0)}))}OpenAIJson(t,e=null){let n=constants.LLMSystemMessage;singleMaidr.type;this.requestJson||(this.requestJson={},this.requestJson.model="gpt-4o-2024-11-20",this.requestJson.max_tokens=constants.LLMmaxResponseTokens,this.requestJson.messages=[],this.requestJson.messages[0]={},this.requestJson.messages[0].role="system",this.requestJson.messages[0].content=n,constants.LLMPreferences&&(this.requestJson.messages[1]={},this.requestJson.messages[1].role="system",this.requestJson.messages[1].content=constants.LLMPreferences));let o=this.requestJson.messages.length;return this.requestJson.messages[o]={},this.requestJson.messages[o].role="user",this.requestJson.messages[o].content=e?[{type:"text",text:t},{type:"image_url",image_url:{url:e}}]:t,this.requestJson}GeminiJson(t,e=null){let n=constants.LLMSystemMessage,o="Describe "+singleMaidr.type+" charts to a blind person",s={generationConfig:{},safetySettings:[],contents:[]},i={role:"user",parts:[{text:n||o}]};constants.LLMPreferences&&i.parts.push({text:constants.LLMPreferences}),s.contents.push(i);let l={role:"user",parts:[]};return e?l.parts.push({text:t},{inlineData:{data:e,mimeType:"image/png"}}):l.parts.push({text:t}),s.contents.push(l),s}async GeminiPromptAPI(t,e=null){let n=constants.baseURL+"gemini"+constants.code,o=constants.LLMSystemMessage;constants.LLMPreferences&&(o+=constants.LLMPreferences),o+="\n\n"+t,null==e?e=constants.LLMImage:constants.LLMImage=e,constants.LLMImage=e;let s=chatLLM.GeminiJson(o,e);const i=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authentication:constants.emailAuthKey+" "+constants.clientToken},body:JSON.stringify(s)});if(i.ok){const t=await i.json();t.text=()=>t.candidates[0].content.parts[0].text,chatLLM.ProcessLLMResponse(t,"gemini")}else chatLLM.WaitingSound(!1),console.error("Error:",error),chatLLM.DisplayChatMessage("OpenAI","Error processing request.",!0)}async GeminiPrompt(t,e=null){try{null==e?e=constants.LLMImage:constants.LLMImage=e,constants.LLMImage=e;const{GoogleGenerativeAI:n}=await import("https://esm.run/@google/generative-ai"),o=constants.geminiAuthKey,s=new n(o).getGenerativeModel({model:"gemini-1.5-pro-latest"});let i=constants.LLMSystemMessage;constants.LLMPreferences&&(i+=constants.LLMPreferences),i+="\n\n"+t;const l={inlineData:{data:e,mimeType:"image/png"}},a=await s.generateContent([i,l]);chatLLM.ProcessLLMResponse(a.response,"gemini")}catch(t){throw chatLLM.WaitingSound(!1),chatLLM.DisplayChatMessage("Gemini","Error processing request.",!0),console.error("Error in GeminiPrompt:",t),t}}DisplayChatMessage(t="User",e="",n=!1){let o="h3";if(!n&&"multi"==constants.LLMModel&&"User"!=t){if(this.firstMulti){let t=`\n          <div class="chatLLM_message chatLLM_message_other">\n            <h3 class="chatLLM_message_user">${resources.GetString("multi")} Responses</h3>\n          </div>\n        `;this.RenderChatMessage(t),this.firstMulti=!1}o="h4"}let s=`\n      <div class="chatLLM_message ${"User"==t?"chatLLM_message_self":"chatLLM_message_other"}">`;e!=resources.GetString("processing")&&(s+=`<${o} class="chatLLM_message_user">${t}</${o}>`),s+=`<p class="chatLLM_message_text">${e}</p>\n      </div>\n    `,"User"!=t&&e!=resources.GetString("processing")&&(s+='\n        <p class="chatLLM_message_copy"><button class="chatLLM_message_copy_button">Copy</button></p>\n      '),this.RenderChatMessage(s)}RenderChatMessage(t){document.getElementById("chatLLM_chat_history").insertAdjacentHTML("beforeend",t),document.getElementById("chatLLM_input").value="",document.getElementById("chatLLM_chat_history").scrollTop=document.getElementById("chatLLM_chat_history").scrollHeight}ResetLLM(){document.getElementById("chatLLM_chat_history").innerHTML="",this.requestJson=null,this.firstTime=!0,(constants.autoInitLLM||chatLLM.shown)&&chatLLM.InitChatMessage()}Destroy(){let t=document.getElementById("chatLLM");t&&t.remove();let e=document.getElementById("chatLLM_modal_backdrop");e&&e.remove()}Toggle(t){void 0===t&&(t=!!document.getElementById("chatLLM").classList.contains("hidden")),chatLLM.shown=t,t?(this.whereWasMyFocus=document.activeElement,constants.tabMovement=0,document.getElementById("chatLLM").classList.remove("hidden"),document.getElementById("chatLLM_modal_backdrop").classList.remove("hidden"),document.querySelector("#chatLLM .close").focus(),this.firstTime&&this.InitChatMessage()):(document.getElementById("chatLLM").classList.add("hidden"),document.getElementById("chatLLM_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null,this.firstOpen=!0)}async ConvertSVGtoJPG(t,e){let n=document.getElementById(t);return new Promise(((t,o)=>{var s=document.createElement("canvas"),i=s.getContext("2d"),l=(new XMLSerializer).serializeToString(n);l.startsWith("<svg xmlns")||(l=`<svg xmlns="http://www.w3.org/2000/svg" ${l.slice(4)}`);var a=n.viewBox.baseVal||n.getBoundingClientRect();s.width=a.width,s.height=a.height;var r=new Image;r.onload=function(){i.drawImage(r,0,0,a.width,a.height);var n=s.toDataURL("image/jpeg",.9);if("openai"==e)t(n);else if("gemini"==e||"claude"==e){let e=n.split(",")[1];t(e)}URL.revokeObjectURL(p)},r.onerror=function(){o(new Error("Error loading SVG"))};var c=new Blob([l],{type:"image/svg+xml;charset=utf-8"}),p=URL.createObjectURL(c);r.src=p}))}GetDefaultPrompt(){let t="Describe this chart to a blind person";return constants.skillLevel?"other"==constants.skillLevel&&constants.skillLevelOther?t+=" who has a "+constants.skillLevelOther+" understanding of statistical charts. ":t+=" who has a "+constants.skillLevel+" understanding of statistical charts. ":t+=" who has a basic understanding of statistical charts. ",t+="Here is a chart in image format",singleMaidr&&(t+=" and raw data in json format: \n",t+=JSON.stringify(singleMaidr)),t}}class Description{constructor(){}CreateComponent(){document.querySelector("body").insertAdjacentHTML("beforeend",'\n        <div id="description" class="modal hidden" role="dialog" tabindex="-1">\n            <div class="modal-dialog" role="document" tabindex="0">\n                <div class="modal-content">\n                    <div class="modal-header">\n                        <h2 id="desc_title" class="modal-title">Description</h2>\n                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">\n                            <span aria-hidden="true">&times;</span>\n                        </button>\n                    </div>\n                    <div class="modal-body">\n                        <div id="desc_content">\n                        content here\n                        </div>\n                        <div id="desc_table">\n                        </div>\n                    </div>\n                    <div class="modal-footer">\n                        <button type="button" id="close_desc">Close</button>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <div id="desc_modal_backdrop" class="modal-backdrop hidden"></div>\n\n    ');let t=document.querySelectorAll("#close_desc, #description .close");for(let e=0;e<t.length;e++)constants.events.push([t[e],"click",function(t){description.Toggle(!1)}]);constants.events.push([document.getElementById("description"),"keyup",function(t){"Esc"==t.key&&description.Toggle(!1)}]),constants.events.push([document,"keyup",function(t){"d"==t.key&&description.Toggle(!0)}])}Destroy(){let t=document.getElementById("menu");t&&t.remove();let e=document.getElementById("desc_modal_backdrop");e&&e.remove()}Toggle(t=!1){void 0===t&&(t=!!document.getElementById("description").classList.contains("hidden")),t?(this.whereWasMyFocus=document.activeElement,constants.tabMovement=0,this.PopulateData(),document.getElementById("description").classList.remove("hidden"),document.getElementById("desc_modal_backdrop").classList.remove("hidden"),document.querySelector("#description .close").focus()):(document.getElementById("description").classList.add("hidden"),document.getElementById("desc_modal_backdrop").classList.add("hidden"),this.whereWasMyFocus.focus(),this.whereWasMyFocus=null)}PopulateData(){let t="",e="";"bar"==constants.chartType?e="Bar chart":"heat"==constants.chartType?e="Heatmap":"box"==constants.chartType?e="Box plot":"scatter"==constants.chartType?e="Scatter plot":"line"==constants.chartType?e="Line chart":"hist"==constants.chartType&&(e="Histogram"),e&&(t+=`<p>Type: ${e}</p>`),null!=plot.title&&(t+=`<p>Title: ${plot.title}</p>`),null!=plot.subtitle&&(t+=`<p>Subtitle: ${plot.subtitle}</p>`),null!=plot.caption&&(t+=`<p>Caption: ${plot.caption}</p>`);let n="",o=null,s=null,i=null,l=null,a=0,r=0,c=0,p=0;if("bar"==constants.chartType&&(null!=plot.plotLegend.x&&(o=plot.plotLegend.x,r+=1),null!=plot.plotLegend.y&&(s=plot.plotLegend.y,p+=1),null!=plot.columnLabels&&(i=plot.columnLabels,p+=1),null!=plot.plotData&&(l=[],l[0]=plot.plotData,a=plot.plotData.length,c=1,r+=a,p+=c)),null!=l){if(n+="<table>",null!=o||null!=i){if(n+="<thead>",null!=o&&(n+="<tr>",null!=s&&(n+="<td></td>"),n+=`<th scope="col" colspan="${a}">${o}</th>`,n+="</tr>"),null!=i){n+="<tr>",null!=s&&(n+="<td></td>");for(let t=0;t<a;t++)n+=`<th scope="col">${i[t]}</th>`;n+="</tr>"}n+="</thead>"}if(c>0){n+="<tbody>";for(let t=0;t<c;t++){n+="<tr>",null!=s&&0==t&&(n+=`<th scope="row" rowspan="${c}">${s}</th>`);for(let e=0;e<a;e++)n+=`<td>${l[t][e]}</td>`;n+="</tr>"}n+="</tbody>"}n+="</table>"}document.getElementById("desc_title").innerHTML=e+" description",document.getElementById("desc_content").innerHTML=t,document.getElementById("desc_table").innerHTML=n}}class Position{constructor(t=0,e=0,n=-1){this.x=t,this.y=e,this.z=n}}class Helper{static containsObject(t,e){for(let n=0;n<e.length;n++)if(e[n]===t)return!0;return!1}}class Tracker{logUrl=constants.baseURL+"log"+constants.code;isLocal=!1;constructor(){this.DataSetup()}DataSetup(){let t=this.GetTrackerData();if(!this.isLocal||!t){let t={};t.userAgent=Object.assign(navigator.userAgent),t.vendor=Object.assign(navigator.vendor),t.language=Object.assign(navigator.language),t.platform=Object.assign(navigator.platform),t.geolocation=Object.assign(navigator.geolocation),t.log_type="system_data",t.events=[],t.settings=[],this.SaveTrackerData(t),this.SaveSettings()}}DownloadTrackerData(){let t=document.createElement("a"),e=this.GetTrackerData(),n=new Blob([JSON.stringify(e)],{type:"text/plain"});t.href=URL.createObjectURL(n),t.download="tracking.json",t.click()}async SaveTrackerData(t){if(console.log("about to save data",t),this.isLocal)localStorage.setItem(constants.project_id,JSON.stringify(t));else try{const e=await fetch(this.logUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);const n=await e.json();return console.log("Data saved successfully:",n),n}catch(t){return console.error("Error saving data:",t),null}}GetTrackerData(){return JSON.parse(localStorage.getItem(constants.project_id))}Delete(){localStorage.removeItem(constants.project_id),this.data=null,constants.debugLevel>0&&console.log("tracking data cleared"),this.DataSetup()}SaveSettings(){let t=JSON.parse(localStorage.getItem("settings_data"));t&&(t.openAIAuthKey="hidden",t.geminiAuthKey="hidden",constants.emailAuthKey&&(t.username=constants.emailAuthKey),this.SetData("settings",t))}LogEvent(t){let e={};if(e.timestamp=Object.assign(t.timeStamp),e.time=Date().toString(),e.key=Object.assign(t.key),e.altKey=Object.assign(t.altKey),e.ctrlKey=Object.assign(t.ctrlKey),e.shiftKey=Object.assign(t.shiftKey),constants.emailAuthKey&&(e.username=Object.assign(constants.emailAuthKey)),t.path&&(e.focus=Object.assign(t.path[0].tagName)),this.isUndefinedOrNull(constants.position)||(e.position=Object.assign(constants.position)),this.isUndefinedOrNull(constants.minX)||(e.min_x=Object.assign(constants.minX)),this.isUndefinedOrNull(constants.maxX)||(e.max_x=Object.assign(constants.maxX)),this.isUndefinedOrNull(constants.minY)||(e.min_y=Object.assign(constants.minY)),this.isUndefinedOrNull(constants.MAX_FREQUENCY)||(e.max_frequency=Object.assign(constants.MAX_FREQUENCY)),this.isUndefinedOrNull(constants.MIN_FREQUENCY)||(e.min_frequency=Object.assign(constants.MIN_FREQUENCY)),this.isUndefinedOrNull(constants.NULL_FREQUENCY)||(e.null_frequency=Object.assign(constants.NULL_FREQUENCY)),this.isUndefinedOrNull(constants.MAX_SPEED)||(e.max_speed=Object.assign(constants.MAX_SPEED)),this.isUndefinedOrNull(constants.MIN_SPEED)||(e.min_speed=Object.assign(constants.MIN_SPEED)),this.isUndefinedOrNull(constants.INTERVAL)||(e.interval=Object.assign(constants.INTERVAL)),this.isUndefinedOrNull(constants.vol)||(e.volume=Object.assign(constants.vol)),this.isUndefinedOrNull(constants.colorSelected)||(e.color=Object.assign(constants.colorSelected)),this.isUndefinedOrNull(constants.brailleDisplayLength)||(e.braille_display_length=Object.assign(constants.brailleDisplayLength)),this.isUndefinedOrNull(constants.duration)||(e.tone_duration=Object.assign(constants.duration)),this.isUndefinedOrNull(constants.AUTOPLAY_DURATION)||(e.AUTOPLAY_DURATION=Object.assign(constants.AUTOPLAY_DURATION)),this.isUndefinedOrNull(constants.autoPlayOutlierRate)||(e.autoplay_outlier_rate=Object.assign(constants.autoPlayOutlierRate)),this.isUndefinedOrNull(constants.autoPlayPointsRate)||(e.autoplay_points_rate=Object.assign(constants.autoPlayPointsRate)),this.isUndefinedOrNull(constants.textMode)||(e.text_mode=Object.assign(constants.textMode)),this.isUndefinedOrNull(constants.sonifMode)||(e.sonification_mode=Object.assign(constants.sonifMode)),this.isUndefinedOrNull(constants.brailleMode)||(e.braille_mode=Object.assign(constants.brailleMode)),this.isUndefinedOrNull(constants.chartType)||(e.chart_type=Object.assign(constants.chartType)),!this.isUndefinedOrNull(constants.infoDiv.innerHTML)){let t=Object.assign(constants.infoDiv.innerHTML);t=t.replaceAll(/<[^>]*>?/gm,""),e.text_display=t}this.isUndefinedOrNull(location.href)||(e.location=Object.assign(location.href));let n="",o="",s="",i="",l="",a="";if("bar"==constants.chartType)this.isUndefinedOrNull(plot.columnLabels[position.x])||(n=plot.columnLabels[position.x]),this.isUndefinedOrNull(plot.plotLegend.x)||(s=plot.plotLegend.x),this.isUndefinedOrNull(plot.plotLegend.y)||(i=plot.plotLegend.y),this.isUndefinedOrNull(plot.plotData[position.x])||(l=plot.plotData[position.x]);else if("heat"==constants.chartType)this.isUndefinedOrNull(plot.x_labels[position.x])||(n=plot.x_labels[position.x].trim()),this.isUndefinedOrNull(plot.y_labels[position.y])||(o=plot.y_labels[position.y].trim()),this.isUndefinedOrNull(plot.x_group_label)||(s=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),this.isUndefinedOrNull(plot.values)||this.isUndefinedOrNull(plot.values[position.x][position.y])||(l=plot.values[position.x][position.y]),this.isUndefinedOrNull(plot.group_labels[2])||(a=plot.group_labels[2]);else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.x:position.y,e="vert"==constants.plotOrientation?position.y:position.x,a=plot.sections[e];this.isUndefinedOrNull(plot.x_group_label)||(s=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),"vert"==constants.plotOrientation?t>-1&&e>-1&&(this.isUndefinedOrNull(a)||(o=a),this.isUndefinedOrNull(plot.x_labels[position.x])||(n=plot.x_labels[position.x]),this.isUndefinedOrNull(plot.plotData[t][a])||(l=plot.plotData[t][a])):t>-1&&e>-1&&(this.isUndefinedOrNull(a)||(n=a),this.isUndefinedOrNull(plot.y_labels[position.y])||(o=plot.y_labels[position.y]),this.isUndefinedOrNull(plot.plotData[t][a])||(l=plot.plotData[t][a]))}else"point"==constants.chartType&&(this.isUndefinedOrNull(plot.x_group_label)||(s=plot.x_group_label),this.isUndefinedOrNull(plot.y_group_label)||(i=plot.y_group_label),this.isUndefinedOrNull(plot.x[position.x])||(n=plot.x[position.x]),this.isUndefinedOrNull(plot.y[position.x])||(o=plot.y[position.x]),l=[n,o]);e.x_tickmark=Object.assign(n),e.y_tickmark=Object.assign(o),e.x_label=Object.assign(s),e.y_label=Object.assign(i),e.value=Object.assign(l),e.fill_value=Object.assign(a),this.SetData("events",e)}SetData(t,e){if(this.isLocal){let n=this.GetTrackerData();["events","ChatHistory","settings"].includes(t)?(n[t]||(n[t]=[]),n[t].push(e)):n[t]=e,this.SaveTrackerData(n)}else e.log_type=t,this.SaveTrackerData(e)}isUndefinedOrNull(t){try{return null==t}catch{return!0}}}class Review{constructor(){}ToggleReviewMode(t=!0){t?(constants.reviewSaveSpot=document.activeElement,constants.review_container.classList.remove("hidden"),constants.reviewSaveBrailleMode=constants.brailleMode,constants.review.focus(),display.announceText("Review on")):(constants.review_container.classList.add("hidden"),"on"==constants.reviewSaveBrailleMode?display.toggleBrailleMode("on"):constants.reviewSaveSpot.focus(),display.announceText("Review off"))}}class LogError{constructor(){}LogAbsentElement(t){console.log(t,"not found. Visual highlighting is turned off.")}LogCriticalElement(t){consolelog(t,"is critical. MAIDR unable to run")}LogDifferentLengths(t,e){console.log(t,"and",e,"do not have the same length. Visual highlighting is turned off.")}LogTooManyElements(t,e){console.log("Too many",t,"elements. Only the first",e,"will be highlighted.")}LogNotArray(t){console.log(t,"is not an array. Visual highlighting is turned off.")}}class Audio{constructor(){this.AudioContext=window.AudioContext||window.webkitAudioContext,this.audioContext=new AudioContext,this.compressor=this.compressorSetup(this.audioContext)}compressorSetup(){let t=this.audioContext.createDynamicsCompressor();t.threshold.value=-50,t.knee.value=40,t.ratio.value=12,t.attack.value=0,t.release.value=.25;let e=this.audioContext.createGain();return e.gain.value=constants.vol,t.connect(e),e.connect(this.audioContext.destination),t}playTone(t=null){let e=constants.duration,n=constants.vol;null!=t&&null!=t.volScale&&(n=t.volScale*constants.vol);let o=0,s=0,i=0,l=0,a="sine";if("bar"==constants.chartType)s=plot.plotData[position.x],o=position.x,i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,constants.minX,constants.maxX,-1,1);else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.x:position.y,e=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);s=Array.isArray(plot.plotData[t][e])?plot.plotData[t][e][position.z]:plot.plotData[t][e],null!=plot.plotData[t][e]?"vert"==constants.plotOrientation?(i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(s,constants.minY,constants.maxY,-1,1)):(i=this.SlideBetween(s,constants.minX,constants.maxX,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(s,constants.minX,constants.maxX,-1,1)):(i=constants.MIN_FREQUENCY,l=0)}else if("heat"==constants.chartType){if(!plot.data||!plot.data[position.y])return;s=plot.data[position.y][position.x],o=position.x,i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,constants.minX,constants.maxX,-1,1)}else if("point"==constants.chartType||"smooth"==constants.chartType){constants.globalMinMax=!0;let t=constants.minY,e=constants.maxY;"smooth"==constants.chartType&&(t=plot.curveMinY,e=plot.curveMaxY),constants.globalMinMax&&(t=Math.min(constants.minY,plot.curveMinY),e=Math.max(constants.maxY,plot.curveMaxY)),"point"==constants.chartType?(s=plot.y[position.x][position.z],n=1==plot.max_count?constants.vol:this.SlideBetween(plot.points_count[position.x][position.z],1,plot.max_count,constants.vol,constants.MAX_VOL),o=position.x,i=this.SlideBetween(s,t,e,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,t,e,-1,1)):"smooth"==constants.chartType&&(s=plot.curvePoints[positionL1.x],o=positionL1.x,i=this.SlideBetween(s,t,e,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,t,e,-1,1))}else if("hist"==constants.chartType)s=plot.plotData[position.x].y,o=plot.plotData[position.x].x,i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,constants.minX,constants.maxX,-1,1);else if("line"==constants.chartType)s=plot.pointValuesY[position.x],o=position.x,i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,constants.minX,constants.maxX,-1,1);else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType){if(s=plot.plotData[position.x][position.y],0==s)return void this.PlayNull();Array.isArray(s)&&(s=s[position.z]),o=position.x,i=this.SlideBetween(s,constants.minY,constants.maxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY),l=this.SlideBetween(o,constants.minX,constants.maxX,-1,1),a=["triangle","square","sawtooth","sine"][position.y]}if(constants.debugLevel>5&&(console.log("will play tone at freq",i),"box"==constants.chartType?console.log("based on",constants.minY,"<",s,"<",constants.maxY," | freq min",constants.MIN_FREQUENCY,"max",constants.MAX_FREQUENCY):console.log("based on",constants.minX,"<",s,"<",constants.maxX," | freq min",constants.MIN_FREQUENCY,"max",constants.MAX_FREQUENCY)),"box"==constants.chartType){let t=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);"lower_outlier"!=t&&"upper_outlier"!=t||(e=constants.outlierDuration)}if(this.playOscillator(i,e,l,n,a),"box"==constants.chartType){let t=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);if("q1"==t||"q2"==t||"q3"==t){let t=i/2;this.playOscillator(t,e,l,constants.vol/4,"triangle")}}else"heat"==constants.chartType&&0==s&&this.PlayNull()}playOscillator(t,e,n,o=1,s="sine"){const i=this.audioContext.currentTime,l=this.audioContext.createOscillator();l.type=s,l.frequency.value=parseFloat(t),l.start();const a=this.audioContext.createGain();a.gain.setValueCurveAtTime([.5*o,1*o,.5*o,.5*o,.5*o,.1*o,1e-4*o],i,e);const r=new PannerNode(this.audioContext,{panningModel:"HRTF",distanceModel:"linear",positionX:position.x,positionY:position.y,positionZ:1,plotOrientationX:0,plotOrientationY:0,plotOrientationZ:-1,refDistance:1,maxDistance:1e4,rolloffFactor:10,coneInnerAngle:40,coneOuterAngle:50,coneOuterGain:.4}),c=this.audioContext.createStereoPanner();c.pan.value=n,l.connect(a),a.connect(c),c.connect(r),r.connect(this.compressor),setTimeout((()=>{r.disconnect(),a.disconnect(),l.stop(),l.disconnect()}),1e3*e*2)}playSmooth(t=[600,500,400,300],e=2,n=[-1,0,1],o=1,s="sine"){let i=new Array(3*t.length).fill(.5*o);i.push(1e-4*o);const l=this.audioContext.currentTime,a=this.audioContext.createOscillator();a.type=s,a.frequency.setValueCurveAtTime(t,l,e),a.start(),constants.isSmoothAutoplay=!0,this.smoothGain=this.audioContext.createGain(),this.smoothGain.gain.setValueCurveAtTime(i,l,e);const r=new PannerNode(this.audioContext,{panningModel:"HRTF",distanceModel:"linear",positionX:position.x,positionY:position.y,positionZ:1,plotOrientationX:0,plotOrientationY:0,plotOrientationZ:-1,refDistance:1,maxDistance:1e4,rolloffFactor:10,coneInnerAngle:40,coneOuterAngle:50,coneOuterGain:.4}),c=this.audioContext.createStereoPanner();c.pan.setValueCurveAtTime(n,l,e),a.connect(this.smoothGain),this.smoothGain.connect(c),c.connect(r),r.connect(this.compressor),constants.smoothId=setTimeout((()=>{r.disconnect(),this.smoothGain.disconnect(),a.stop(),a.disconnect(),constants.isSmoothAutoplay=!1}),1e3*e*2)}PlayNull(){let t=constants.NULL_FREQUENCY,e=constants.duration,n=constants.vol,o="triangle";this.playOscillator(t,e,0,n,o),setTimeout((function(s){s.playOscillator(23*t/24,e,0,n,o)}),Math.round(e/5*1e3),this)}playEnd(){if(constants.canPlayEndChime){let t=constants.endChime.cloneNode(!0);t.play(),t=null}}KillSmooth(){constants.smoothId&&(this.smoothGain.gain.cancelScheduledValues(0),this.smoothGain.gain.exponentialRampToValueAtTime(1e-4,this.audioContext.currentTime+.03),clearTimeout(constants.smoothId),constants.isSmoothAutoplay=!1)}SlideBetween(t,e,n,o,s){t=Number(t),e=Number(e),n=Number(n),o=Number(o);let i=(t-e)/(n-e)*((s=Number(s))-o)+o;return 0==e&&0==n&&(i=0),i}}class Display{constructor(){this.infoDiv=constants.infoDiv,this.x={},this.x.id="x",this.x.textBase="x-value: ",this.y={},this.y.id="y",this.y.textBase="y-value: ",this.boxplotGridPlaceholders=[resources.GetString("lower_outlier"),resources.GetString("min"),resources.GetString("25"),resources.GetString("50"),resources.GetString("75"),resources.GetString("max"),resources.GetString("upper_outlier")]}toggleTextMode(){"off"==constants.textMode?constants.textMode="terse":"terse"==constants.textMode?constants.textMode="verbose":"verbose"==constants.textMode&&(constants.textMode="off"),this.announceText('<span aria-hidden="true">Text mode:</span> '+constants.textMode)}toggleBrailleMode(t){if(position.x<0&&(position.x=0),position.y<0&&(position.y=0),"point"!=constants.chartType){if(void 0===t&&(void 0===constants.brailleMode?(constants.brailleMode="off",t="on"==constants.brailleMode):(t="on"==constants.brailleMode?"off":"on",constants.brailleMode=t)),"on"==t){if(constants.lockSelection=!0,"box"==constants.chartType&&("vert"!=constants.plotOrientation&&-1==position.x&&position.y==plot.plotData.length?(position.x+=1,position.y-=1):"vert"==constants.plotOrientation&&0==position.x&&(position.y,plot.plotData[0].length)),constants.brailleMode="on",document.getElementById(constants.braille_container_id).classList.remove("hidden"),constants.brailleInput.focus(),constants.brailleInput.setSelectionRange(position.x,position.x),this.SetBraille(),"heat"==constants.chartType){let t=position.y*(plot.num_cols+1)+position.x;constants.brailleInput.setSelectionRange(t,t)}-1==position.x&&-1==position.y&&constants.brailleInput.setSelectionRange(0,0),setTimeout((function(){constants.lockSelection=!1}),50)}else constants.brailleMode="off",document.getElementById(constants.braille_container_id).classList.add("hidden"),constants.review_container?constants.review_container.classList.contains("hidden")?constants.chart.focus():constants.review.focus():constants.chart.focus();this.announceText("Braille "+constants.brailleMode)}else this.announceText("Braille is not supported in point layer.")}toggleSonificationMode(){"point"==constants.chartType||"stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType?"off"==constants.sonifMode?(constants.sonifMode="on",this.announceText(resources.GetString("son_sep"))):"on"==constants.sonifMode?(constants.sonifMode="same",this.announceText(resources.GetString("son_same"))):"same"==constants.sonifMode&&(constants.sonifMode="off",this.announceText(resources.GetString("son_off"))):"off"==constants.sonifMode?(constants.sonifMode="on",this.announceText(resources.GetString("son_on"))):(constants.sonifMode="off",this.announceText(resources.GetString("son_off")))}changeChartLayer(t="down"){let e=maidr.type;if(Array.isArray(e)){let n=e.indexOf(constants.chartType);"down"==t?0==n||(constants.chartType=e[n-1],this.announceText("Switched to "+constants.chartType)):n==e.length-1||(constants.chartType=e[n+1],this.announceText("Switched to "+constants.chartType))}"point"==constants.chartType?position.x=Math.round((plot.x.length-1)*positionL1.x/(plot.curvePoints.length-1)):"smooth"==constants.chartType&&(positionL1.x=Math.round((plot.curvePoints.length-1)*position.x/(plot.x.length-1)))}announceText(t){this.displayInfo("announce",t,constants.announceContainer)}UpdateBraillePos(){if(constants.lockSelection=!0,"bar"==constants.chartType||"hist"==constants.chartType||"line"==constants.chartType)constants.brailleInput.setSelectionRange(position.x,position.x);else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType){let t=null;t=position.y<plot.plotData[0].length-1?position.x:position.x*(plot.fill.length+1)+position.y,constants.brailleInput.setSelectionRange(t,t)}else if("heat"==constants.chartType){let t=position.y*(plot.num_cols+1)+position.x;constants.brailleInput.setSelectionRange(t,t)}else if("box"==constants.chartType){let t="vert"==constants.plotOrientation?position.y:position.x,e=this.boxplotGridPlaceholders[t],n=!1,o=0;if(!constants.brailleData)throw"Braille data not set up, cannot move cursor in braille, sorry.";for(let t=0;t<constants.brailleData.length;t++){if("blank"!=constants.brailleData[t].type&&resources.GetString(constants.brailleData[t].type)==e){n=!0;break}o+=constants.brailleData[t].numChars}n||(o=0),constants.brailleInput.setSelectionRange(o,o)}else("smooth"==singleMaidr.type||singleMaidr.type.includes("smooth"))&&constants.brailleInput.setSelectionRange(positionL1.x,positionL1.x);setTimeout((function(){constants.lockSelection=!1}),50)}displayValues(){let t="",e="",n="";if("bar"==constants.chartType)plot.columnLabels[position.x]&&(plot.plotLegend.x.length>0&&(e+=plot.plotLegend.x+" is "),e+=plot.columnLabels[position.x]+", "),plot.plotData[position.x]&&(plot.plotLegend&&(e+=plot.plotLegend.y+" is "),e+=plot.plotData[position.x]),n+="<p>"+plot.columnLabels[position.x]+" "+plot.plotData[position.x]+"</p>\n",e="<p>"+e+"</p>\n";else if("heat"==constants.chartType)1==constants.navigation?(e+=plot.x_group_label+" "+plot.x_labels[position.x]+", "+plot.y_group_label+" "+plot.y_labels[position.y]+", "+plot.fill+" is ",e+=plot.data[position.y][position.x]):(e+=plot.y_group_label+" "+plot.y_labels[position.y]+", "+plot.x_group_label+" "+plot.x_labels[position.x]+", "+plot.fill+" is ",e+=plot.data[position.y][position.x]),1==constants.navigation?n+="<p>"+plot.x_labels[position.x]+", "+plot.data[position.y][position.x]+"</p>\n":n+="<p>"+plot.y_labels[position.y]+", "+plot.data[position.y][position.x]+"</p>\n",e="<p>"+e+"</p>\n";else if("box"==constants.chartType){let t=0,o=1,s=!1,i="vert"==constants.plotOrientation?position.x:position.y,l=plot.GetSectionKey("vert"==constants.plotOrientation?position.y:position.x);"lower_outlier"!=l&&"upper_outlier"!=l||(s=!0),null==plot.plotData[i][l]?(t="",s&&(o=0)):s?(t=plot.plotData[i][l].join(", "),o=plot.plotData[i][l].length):t=plot.plotData[i][l],constants.navigation?plot.x_group_label&&(e+=plot.x_group_label):constants.navigation||plot.y_group_label&&(e+=plot.y_group_label),constants.navigation?plot.x_labels[i]?(e+=" is ",n+=plot.x_labels[i]+", ",e+=plot.x_labels[i]+", "):e+=", ":constants.navigation||(plot.y_labels[i]?(e+=" is ",n+=plot.y_labels[i]+", ",e+=plot.y_labels[i]+", "):e+=", "),s&&(n+=o+" ",e+=o+" "),e+=resources.GetString(l),1==o?e+=" is ":(e+="s ",o>1&&(e+=" are ")),(s||constants.navigation&&"horz"==constants.plotOrientation||!constants.navigation&&"vert"==constants.plotOrientation)&&(n+=resources.GetString(l),1!=o&&(n+="s"),n+=" "),null!=plot.plotData[i][l]||s?(n+=t,e+=t):(n+="empty",e+="empty"),e="<p>"+e+"</p>\n",n="<p>"+n+"</p>\n"}else[].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")?("point"==constants.chartType?(e+=plot.x_group_label+" "+plot.x[position.x]+", "+plot.y_group_label+" ["+plot.y[position.x].join(", ")+"]",n+="<p>"+plot.x[position.x]+", ["+plot.y[position.x].join(", ")+"]</p>\n"):"smooth"==constants.chartType&&(e+=plot.x_group_label+" "+plot.curveX[positionL1.x]+", "+plot.y_group_label+" "+plot.curvePoints[positionL1.x],n+="<p>"+plot.curvePoints[positionL1.x]+"<p>\n"),e="<p>"+e+"</p>\n"):"hist"==constants.chartType?(n="<p>"+plot.plotData[position.x].x+", "+plot.plotData[position.x].y+"</p>\n",e="<p>",plot.legendX&&(e=plot.legendX+" is "),e+=plot.plotData[position.x].xmin,e+=" through "+plot.plotData[position.x].xmax+", ",plot.legendY&&(e+=plot.legendY+" is "),e+=plot.plotData[position.x].y):"line"==constants.chartType?(plot.plotLegend&&(e+=plot.plotLegend.x+" is "),e+=plot.pointValuesX[position.x]+", ",plot.plotLegend&&plot.plotLegend.y,e+=plot.pointValuesY[position.x],n+="<p>"+plot.pointValuesX[position.x]+", "+plot.pointValuesY[position.x]+"</p>\n",e="<p>"+e+"</p>\n"):"stacked_bar"!=constants.chartType&&"stacked_normalized_bar"!=constants.chartType&&"dodged_bar"!=constants.chartType||(plot.plotLegend&&(e+=plot.plotLegend.x+" is "),e+=plot.level[position.x]+", ",e+="level is "+plot.fill[position.y]+", ",plot.plotLegend&&(e+=plot.plotLegend.y+" is "),e+=plot.plotData[position.x][position.y],1==constants.navigation?n+="<p>"+plot.level[position.x]+" is "+plot.plotData[position.x][position.y]+"</p>\n":n+="<p>"+plot.fill[position.y]+" is "+plot.plotData[position.x][position.y]+"</p>\n",e="<p>"+e+"</p>\n");"verbose"==constants.textMode?t=e:"terse"==constants.textMode&&(t=n),constants.verboseText=e,t==constants.infoDiv.innerHTML&&(constants.infoDiv.textContent.endsWith(".")?t.endsWith(".</p>")&&(t=t.replace(".</p>","</p>")):t=t.replace("</p>",".</p>")),constants.infoDiv&&(constants.infoDiv.innerHTML="",constants.infoDiv.innerHTML=t),constants.review&&(t.length>0?constants.review.value=t.replace(/<[^>]*>?/gm,""):constants.review.value=e)}displayInfo(t,e,n=constants.infoDiv){let o="";if("announce"==t)e&&(o=e);else if(t)if(e){if("terse"==constants.textMode)o=e;else if("verbose"==constants.textMode){o=t.charAt(0).toUpperCase()+t.slice(1)+" is "+e}}else{o="Plot does not have "+(["a","e","i","o","u"].includes(t.charAt(0))?"an":"a")+" "+t}if(o.length>0){n.innerHTML=null;let t=document.createElement("p");t.innerHTML=o,n.appendChild(t)}}SetBraille(){let t=[];if("heat"==constants.chartType){let e=(constants.maxY-constants.minY)/3,n=constants.minY+e,o=n+e;for(let e=0;e<plot.data.length;e++){for(let s=0;s<plot.data[e].length;s++)0==plot.data[e][s]?t.push("⠀"):plot.data[e][s]<=n?t.push("⠤"):plot.data[e][s]<=o?t.push("⠒"):t.push("⠉");t.push("⠳")}}else if("stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType)if(position.y<plot.plotData[0].length-1){let e=null,n=null;for(let t=0;t<plot.plotData.length;t++)0==t?(e=plot.plotData[t][position.y],n=plot.plotData[t][position.y]):(plot.plotData[t][position.y]<e&&(e=plot.plotData[t][position.y]),plot.plotData[t][position.y]>n&&(n=plot.plotData[t][position.y]));let o=(n-e)/4,s=e+o,i=s+o,l=i+o;for(let e=0;e<plot.plotData.length;e++)0==plot.plotData[e][position.y]?t.push("⠀"):plot.plotData[e][position.y]<=s?t.push("⣀"):plot.plotData[e][position.y]<=i?t.push("⠤"):plot.plotData[e][position.y]<=l?t.push("⠒"):t.push("⠉")}else for(let e=0;e<plot.plotData.length;e++){let n=(constants.maxY-constants.minY)/4,o=constants.minY+n,s=o+n,i=s+n;for(let n=0;n<plot.plotData[e].length;n++)0==plot.plotData[e][n]?t.push("⠀"):plot.plotData[e][n]<=o?t.push("⣀"):plot.plotData[e][n]<=s?t.push("⠤"):plot.plotData[e][n]<=i?t.push("⠒"):t.push("⠉");t.push("⠳")}else if("bar"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,o=n+e,s=o+e;for(let e=0;e<plot.plotData.length;e++)plot.plotData[e]<=n?t.push("⣀"):plot.plotData[e]<=o?t.push("⠤"):plot.plotData[e]<=s?t.push("⠒"):t.push("⠉")}else if("smooth"==constants.chartType){let e=(plot.curveMaxY-plot.curveMinY)/4,n=plot.curveMinY+e,o=n+e,s=o+e,i=s+e;for(let e=0;e<plot.curvePoints.length;e++)plot.curvePoints[e]<=n?t.push("⣀"):plot.curvePoints[e]<=o?t.push("⠤"):plot.curvePoints[e]<=s?t.push("⠒"):plot.curvePoints[e]<=i&&t.push("⠉")}else if("hist"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,o=n+e,s=o+e;for(let e=0;e<plot.plotData.length;e++)plot.plotData[e].y<=n?t.push("⣀"):plot.plotData[e].y<=o?t.push("⠤"):plot.plotData[e].y<=s?t.push("⠒"):t.push("⠉")}else if("box"==constants.chartType&&position.y>-1){let e,n,o,s=plot.sections.length;if("vert"==constants.plotOrientation?(e=position.x,n=constants.minY,o=constants.maxY):(e=position.y,n=constants.minX,o=constants.maxX),e<0||e>=plot.plotData.length)return;let i=[];i.push({type:"global_min",value:n});for(let t=0;t<s;t++){let n=plot.sections[t],o=plot.plotData[e][n],s={};if(null!=o)if("lower_outlier"==n||"upper_outlier"==n)for(let t=0;t<o.length;t++)s={type:n,value:o[t]},i.push(s);else s={type:n,value:o},i.push(s)}i.push({type:"global_max",value:o});let l=[],a=!0;for(let t=0;t<i.length;t++){let e;e=a?Math.abs(i[t+1].value-i[t].value):Math.abs(i[t].value-i[t-1].value),"global_min"==i[t].type||"global_max"==i[t].type?l.push({type:"blank",length:e}):"lower_outlier"==i[t].type?(l.push({type:i[t].type,length:0}),l.push({type:"blank",length:e})):"upper_outlier"==i[t].type?(l.push({type:"blank",length:e}),l.push({type:i[t].type,length:0})):"q2"==i[t].type?(a=!1,l.push({type:i[t].type,length:0})):l.push({type:i[t].type,length:e})}let r=-1,c=-1,p=-1,d=-1,u=0;for(let t=0;t<l.length;t++)"blank"!=l[t].type&&(l[t].length>0||"lower_outlier"==l[t].type||"upper_outlier"==l[t].type)?(l[t].numChars=1,u++):l[t].numChars=0,"min"==l[t].type&&l[t].length>0&&(r=t),"max"==l[t].type&&l[t].length>0&&(d=t),"q1"==l[t].type&&(c=t),"q3"==l[t].type&&(p=t),"q2"==l[t].type&&(l[t].numChars=2,u++);r>-1&&d>-1&&l[r].length!=l[d].length&&(l[r].length>l[d].length?(l[r].numChars++,u++):(l[d].numChars++,u++)),l[c].length!=l[p].length&&(l[c].length>l[p].length?(l[c].numChars++,u++):(l[p].numChars++,u++));let h=constants.brailleDisplayLength-u;h<5&&(h=5);let y=this.AllocateCharacters(l,h),g=l;for(let t=0;t<y.length;t++)y[t]&&(g[t].numChars+=y[t]);constants.brailleData=g,constants.debugLevel>5&&(console.log("plotData[i]",plot.plotData[e]),console.log("valData",i),console.log("lenData",l),console.log("brailleData",g));for(let e=0;e<g.length;e++)for(let n=0;n<g[e].numChars;n++){let o="⠀";"min"==g[e].type||"max"==g[e].type?o="⠒":"q1"==g[e].type||"q3"==g[e].type?o="⠿":"q2"==g[e].type?o=0==n?"⠸":"⠇":"lower_outlier"!=g[e].type&&"upper_outlier"!=g[e].type||(o="⠂"),t.push(o)}}else if("line"==constants.chartType){let e=(constants.maxY-constants.minY)/4,n=constants.minY+e,o=n+e,s=o+e,i=s+e;for(let e=0;e<plot.pointValuesY.length;e++)plot.pointValuesY[e]<=n&&e-1>=0&&plot.pointValuesY[e-1]>n?plot.pointValuesY[e-1]<=o?t.push("⢄"):plot.pointValuesY[e-1]<=s?t.push("⢆"):plot.pointValuesY[e-1]>s&&t.push("⢇"):plot.pointValuesY[e]<=n?t.push("⣀"):e-1>=0&&plot.pointValuesY[e-1]<=n?plot.pointValuesY[e]<=o?t.push("⡠"):plot.pointValuesY[e]<=s?t.push("⡰"):plot.pointValuesY[e]>s&&t.push("⡸"):plot.pointValuesY[e]<=o&&e-1>=0&&plot.pointValuesY[e-1]>o?plot.pointValuesY[e-1]<=s?t.push("⠢"):plot.pointValuesY[e-1]>s&&t.push("⠣"):plot.pointValuesY[e]<=o?t.push("⠤"):e-1>=0&&plot.pointValuesY[e-1]<=o?plot.pointValuesY[e]<=s?t.push("⠔"):plot.pointValuesY[e]>s&&t.push("⠜"):plot.pointValuesY[e]<=s&&e-1>=0&&plot.pointValuesY[e-1]>s?t.push("⠑"):plot.pointValuesY[e]<=s?t.push("⠒"):e-1>=0&&plot.pointValuesY[e-1]<=s?t.push("⠊"):plot.pointValuesY[e]<=i&&t.push("⠉")}constants.brailleInput.value=t.join(""),constants.debugLevel>5&&console.log("braille:",constants.brailleInput.value),this.UpdateBraillePos()}CharLenImpact(t){return t.length/t.numChars}AllocateCharacters(t,e){let n=[],o=0;for(let e=0;e<t.length;e++)o+=t[e].length;let s=["lower_outlier","upper_outlier","50"];for(let i=0;i<t.length;i++)s.includes(t[i].type)||(n[i]=Math.round(t[i].length/o*e));let i=n.reduce(((t,e)=>t+e),0),l=e-i,a=t.length;for(;0!==l&&a>0;){for(let e=0;e<t.length;e++)s.includes(t[e].type)||(n[e]+=Math.round(t[e].length/o*l));i=n.reduce(((t,e)=>t+e),0),l=e-i,a--}if(0!==l){let e=[];for(let n=0;n<t.length;n++)e.push(n);e.sort(((t,e)=>n[t]-n[e]));let o=-1;l>0&&(o=1);let s=0,i=3*e.length;for(;l>0&&i>0;)n[e[s]]+=o,l+=-o,s+=1,s>=e.length&&(s=0),i+=-1}return n}}class BarChart{constructor(){let t=null;"axes"in singleMaidr&&singleMaidr.axes.x&&singleMaidr.axes.x.level&&(t=singleMaidr.axes.x.level);let e=null;"data"in singleMaidr&&(e=singleMaidr.data);let n=null;"selector"in singleMaidr?n=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(n=singleMaidr.elements),t&&e&&n?n.length!=e.length?(constants.hasRect=0,logError.LogDifferentLengths("elements","data")):t.length!=n.length?(constants.hasRect=0,logError.LogDifferentLengths("x level","elements")):e.length!=t.length?(constants.hasRect=0,logError.LogDifferentLengths("x level","data")):(this.bars=n,constants.hasRect=1):e&&n?e.length!=n.length?(constants.hasRect=0,logError.LogDifferentLengths("data","elements")):(this.bars=n,constants.hasRect=1):t&&e?(t.length!=e.length&&(constants.hasRect=0,logError.LogDifferentLengths("x level","data")),logError.LogAbsentElement("elements")):e&&(logError.LogAbsentElement("x level"),logError.LogAbsentElement("elements")),this.columnLabels=[];let o="",s="";"labels"in singleMaidr&&("x"in singleMaidr.labels&&(o=singleMaidr.labels.x),"y"in singleMaidr.labels&&(s=singleMaidr.labels.y)),"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&""==o&&(o=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&""==s&&(s=singleMaidr.axes.y.label),singleMaidr.axes.x&&singleMaidr.axes.x.level&&(this.columnLabels=singleMaidr.axes.x.level),singleMaidr.axes.y&&singleMaidr.axes.y.level&&(this.columnLabels=singleMaidr.axes.y.level)),this.plotLegend={x:o,y:s},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),Array.isArray(singleMaidr)?this.plotData=singleMaidr:"data"in singleMaidr&&(this.plotData=singleMaidr.data),this.SetMaxMin(),this.autoplay=null}SetMaxMin(){for(let t=0;t<this.plotData.length;t++)0==t?(constants.maxY=this.plotData[t],constants.minY=this.plotData[t]):(this.plotData[t]>constants.maxY&&(constants.maxY=this.plotData[t]),this.plotData[t]<constants.minY&&(constants.minY=this.plotData[t]));constants.maxX=this.columnLabels.length,constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/this.plotData.length),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}PlayTones(){audio.playTone()}GetLegendFromManualData(){let t={};return t.x=barplotLegend.x,t.y=barplotLegend.y,t}GetData(){let t=[];if(this.bars)for(let e=0;e<this.bars.length;e++)t.push(this.bars[e].getAttribute("height"));return t}GetColumns(){let t=[],e=constants.chart.querySelectorAll('tspan[dy="10"]');for(var n=0;n<e.length;n++)t.push(e[n].innerHTML);return t}GetLegend(){let t={},e=constants.chart.querySelectorAll('tspan[dy="12"]');return t.x=e[1].innerHTML,t.y=e[0].innerHTML,t}ParseInnerHTML(t){let e=[];for(var n=0;n<t.length;n++)e.push(t[n].innerHTML);return e}Select(){if(this.UnSelectPrevious(),this.bars&&(this.activeElement=this.bars[position.x],this.activeElement))if(this.activeElement.hasAttribute("fill"))this.activeElementColor=this.activeElement.getAttribute("fill"),this.activeElement.setAttribute("fill",constants.GetBetterColor(this.activeElementColor));else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);this.activeElementColor=e[e.indexOf("fill")+1],e[e.indexOf("fill")+1]=constants.GetBetterColor(this.activeElementColor),t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t)}}UnSelectPrevious(){if(this.activeElement)if(this.activeElement.hasAttribute("fill"))this.activeElement.setAttribute("fill",this.activeElementColor),this.activeElement=null;else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);e[e.indexOf("fill")+1]=this.activeElementColor,t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t),this.activeElement=null}}}class BoxPlot{constructor(){if(this.sections=["lower_outlier","min","q1","q2","q3","max","upper_outlier"],constants.plotOrientation="horz","axes"in singleMaidr&&"x"in singleMaidr.axes&&"level"in singleMaidr.axes.x&&(constants.plotOrientation="vert"),this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),this.subtitle="","labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),this.caption="","labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),"labels"in singleMaidr&&(this.x_group_label||"x"in singleMaidr.labels&&(this.x_group_label=singleMaidr.labels.x),this.y_group_label||"y"in singleMaidr.labels&&(this.y_group_label=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&("label"in singleMaidr.axes.x&&(this.x_group_label||(this.x_group_label=singleMaidr.axes.x.label)),"level"in singleMaidr.axes.x?this.x_labels=singleMaidr.axes.x.level:this.x_labels=[]),"y"in singleMaidr.axes&&("label"in singleMaidr.axes.y&&(this.y_group_label||(this.y_group_label=singleMaidr.axes.y.label)),"level"in singleMaidr.axes.y?this.y_labels=singleMaidr.axes.y.level:this.y_labels=[])),this.plotData=singleMaidr.data,"selector"in singleMaidr){let t=document.querySelector(singleMaidr.selector);this.plotBounds=this.GetPlotBounds(t),constants.hasRect=!0}else"elements"in singleMaidr?(this.plotBounds=this.GetPlotBounds(singleMaidr.elements),constants.hasRect=!0):constants.hasRect=!1;this.CleanData()}CleanData(){let t,e;for(let n=0;n<this.plotData.length;n++){if(this.plotData[n].lower_outlier){let o=Math.min(...this.plotData[n].lower_outlier),s=Math.max(...this.plotData[n].lower_outlier);(null==t||o<t)&&(t=o),(null==e||s>e)&&(e=s)}if(this.plotData[n].min&&((null==t||this.plotData[n].min<t)&&(t=this.plotData[n].min),(null==e||this.plotData[n].max>e)&&(e=this.plotData[n].max)),this.plotData[n].q1&&((null==t||this.plotData[n].q1<t)&&(t=this.plotData[n].q1),(null==e||this.plotData[n].q1>e)&&(e=this.plotData[n].q1)),this.plotData[n].q2&&((null==t||this.plotData[n].q2<t)&&(t=this.plotData[n].q2),(null==e||this.plotData[n].q2>e)&&(e=this.plotData[n].q2)),this.plotData[n].q3&&((null==t||this.plotData[n].q3<t)&&(t=this.plotData[n].q3),(null==e||this.plotData[n].q3>e)&&(e=this.plotData[n].q3)),this.plotData[n].max&&((null==t||this.plotData[n].max<t)&&(t=this.plotData[n].max),(null==e||this.plotData[n].max>e)&&(e=this.plotData[n].max)),this.plotData[n].upper_outlier){let o=Math.min(...this.plotData[n].upper_outlier),s=Math.max(...this.plotData[n].upper_outlier);(null==t||o<t)&&(t=o),(null==e||s>e)&&(e=s)}}"vert"==constants.plotOrientation?(constants.minY=t,constants.maxY=e,constants.minX=0,constants.maxX=this.plotData.length-1):(constants.minX=t,constants.maxX=e,constants.minY=0,constants.maxY=this.plotData.length-1),constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/7),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}GetPlotBounds(t){let e=[],n=this.GetAllSegmentTypes(),o=/(?:\d+(?:\.\d*)?|\.\d+)/g,s=[],i=t.children;for(let t=0;t<i.length;t++){let e={},n=i[t].children;for(let t=0;t<n.length;t++){e[this.GetBoxplotSegmentType(n[t].getAttribute("id"))]=n[t]}s.push(e)}for(let t=0;t<s.length;t++){let i=[],l=s[t].range.getBoundingClientRect(),a=s[t].range.querySelector('polyline[id^="GRID"]').getAttribute("points").match(o),r=s[t].range.querySelector('polygon[id^="geom_polygon"]').getAttribute("points").match(o),c=0;c="vert"==constants.plotOrientation?(a[1]-r[3])/(r[1]-r[3]):(a[0]-r[2])/(r[0]-r[2]),c=Number.isNaN(c)?0:c;let p=0;if(p="vert"==constants.plotOrientation?l.height*c:l.width*c,i[2]=this.convertBoundingClientRectToObj(l),i[2].label=n[2],i[2].type="range","vert"==constants.plotOrientation?(i[2].height=p,i[2].top=i[2].bottom-p,i[2].y=i[2].top):i[2].width=p,i[3]=this.convertBoundingClientRectToObj(l),i[3].label=n[3],i[3].type="range","vert"==constants.plotOrientation?(i[3].height=0,i[3].top=l.bottom-p,i[3].y=i[3].top,i[3].bottom=i[3].top):(i[3].width=0,i[3].left=l.left+p),i[4]=this.convertBoundingClientRectToObj(l),i[4].label=n[4],i[4].type="range","vert"==constants.plotOrientation?(i[4].height=l.height-p,i[4].bottom=i[3].top):(i[4].width=l.width-p,i[4].left=i[3].left),Object.hasOwn(s[t],"whisker")){let e=s[t].whisker.getBoundingClientRect(),o=!1,a=!1;"vert"==constants.plotOrientation?(e.bottom>l.bottom&&(o=!0),e.top<l.top&&(a=!0)):(e.left<l.left&&(o=!0),e.right>l.right&&(a=!0)),o?(i[1]=this.convertBoundingClientRectToObj(e),i[1].label=n[1],i[1].type="whisker","vert"==constants.plotOrientation?(i[1].top=i[2].bottom,i[1].y=i[1].top,i[1].height=i[1].bottom-i[1].top):i[1].width=i[2].left-i[1].left):(i[1]={},i[1].label=n[1],i[1].type="blank"),a?(i[5]=this.convertBoundingClientRectToObj(e),i[5].label=n[5],i[5].type="whisker","vert"==constants.plotOrientation?(i[5].bottom=i[4].top,i[5].height=i[5].bottom-i[5].top):(i[5].left=i[4].right,i[5].x=i[4].right,i[5].width=i[5].right-i[5].left)):(i[5]={},i[5].label=n[5],i[5].type="blank")}if(Object.hasOwn(s[t],"outlier")){let e=s[t].outlier.children,o=null,a=null;for(let t=0;t<e.length;t++){let n=e[t].getBoundingClientRect();"vert"==constants.plotOrientation?n.y<l.y?o?(n.y<o.y&&(o.y=n.y),n.top<o.top&&(o.top=n.top),n.bottom>o.bottom&&(o.bottom=n.bottom)):o=this.convertBoundingClientRectToObj(n):a?(n.y<a.y&&(a.y=n.y),n.top<a.top&&(a.top=n.top),n.bottom>a.bottom&&(a.bottom=n.bottom)):a=this.convertBoundingClientRectToObj(n):n.x>l.x?o?(n.x<o.x&&(o.x=n.x),n.left<o.left&&(o.left=n.left),n.right>o.right&&(o.right=n.right)):o=this.convertBoundingClientRectToObj(n):a?(n.x<a.x&&(a.x=n.x),n.left<a.left&&(a.left=n.left),n.right>a.right&&(a.right=n.right)):a=this.convertBoundingClientRectToObj(n)}a?(a.height=a.bottom-a.top,a.width=a.right-a.left,i[0]=this.convertBoundingClientRectToObj(a),i[0].label=n[0],i[0].type="outlier"):(i[0]={},i[0].label=n[0],i[0].type="blank"),o?(o.height=o.bottom-o.top,o.width=o.right-o.left,i[6]=this.convertBoundingClientRectToObj(o),i[6].label=n[6],i[6].type="outlier"):(i[6]={},i[6].label=n[6],i[6].type="blank")}else i[0]={},i[0].label=n[0],i[0].type="blank",i[6]={},i[6].label=n[6],i[6].type="blank";e.push(i)}return constants.debugLevel>5&&console.log("plotBounds",e),e}GetAllSegmentTypes(){let t=[];for(let e=0;e<this.sections.length;e++)t.push(resources.GetString(this.sections[e]));return t}GetBoxplotSegmentType(t){let e="outlier";return t.includes("geom_crossbar")?e="range":t.includes("GRID")?e="whisker":t.includes("points")&&(e="outlier"),e}GetBoxplotSegmentPoints(t,e){let n=/(?:\d+(?:\.\d*)?|\.\d+)/g,o=[];if("range"==e){let e=t.children[0].getAttribute("points").match(n);o.push(e[0],e[1]),e[0]!=e[2]&&o.push(e[2],e[3])}else if("outlier"==e)o.push(t.getAttribute("x"),t.getAttribute("y"));else{let e=t.getAttribute("points").match(n);"vert"==constants.plotOrientation?e[1]!=e[3]&&o.push(e[0],e[1],e[2],e[3]):e[0]!=e[2]&&o.push(e[0],e[1],e[2],e[3])}return o}GetAllSegmentTypes(){return[resources.GetString("lower_outlier"),resources.GetString("min"),resources.GetString("25"),resources.GetString("50"),resources.GetString("75"),resources.GetString("max"),resources.GetString("upper_outlier")]}convertBoundingClientRectToObj(t){return{top:t.top,right:t.right,bottom:t.bottom,left:t.left,width:t.width,height:t.height,x:t.x,y:t.y}}PlayTones(){let t=null,e=null;constants.outlierInterval&&clearInterval(constants.outlierInterval),"vert"==constants.plotOrientation?(t=position.x,e=this.GetSectionKey(position.y)):(t=position.y,e=this.GetSectionKey(position.x)),null==plot.plotData[t][e]?audio.PlayNull():"lower_outlier"!=e&&"upper_outlier"!=e?audio.playTone():0==plot.plotData[t][e].length?audio.PlayNull():(position.z=0,constants.outlierInterval=setInterval((function(){audio.playTone(),position.z+=1,(null==plot.plotData[t][e]||position.z+1>plot.plotData[t][e].length)&&(clearInterval(constants.outlierInterval),position.z=-1)}),constants.autoPlayOutlierRate))}GetSectionKey(t){return this.sections[t]}}class BoxplotRect{rectPadding=15;rectStrokeWidth=4;constructor(){this.x1=0,this.width=0,this.y1=0,this.height=0,this.chartOffsetLeft=constants.chart.getBoundingClientRect().left,this.chartOffsetTop=constants.chart.getBoundingClientRect().top}UpdateRect(){document.getElementById("highlight_rect")&&document.getElementById("highlight_rect").remove();let t=position.x,e=position.y,n=plot.GetSectionKey(position.y);if("vert"==constants.plotOrientation||(t=position.y,e=position.x,n=plot.GetSectionKey(position.x)),"vert"==constants.plotOrientation&&position.y>-1||"horz"==constants.plotOrientation&&position.x>-1){let o=plot.plotBounds[t][e];"blank"!=o.type&&(this.x1=o.left-this.rectPadding-this.chartOffsetLeft,this.width=o.width+2*this.rectPadding,this.y1=o.top-this.rectPadding-this.chartOffsetTop,this.height=o.height+2*this.rectPadding,constants.debugLevel>5&&(console.log("Point",n,"bottom:",o.bottom,"top:",o.top),console.log("x1:",this.x1,"y1:",this.y1,"width:",this.width,"height:",this.height)),this.CreateRectDisplay())}}CreateRectDisplay(){let t=document.createElementNS("http://www.w3.org/2000/svg","rect");t.setAttribute("id","highlight_rect"),t.setAttribute("x",this.x1),t.setAttribute("y",this.y1),t.setAttribute("width",this.width),t.setAttribute("height",this.height),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.rectStrokeWidth),t.setAttribute("fill","none"),constants.chart.appendChild(t)}}class HeatMap{constructor(){let t=null,e=null;"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.level&&(t=singleMaidr.axes.x.level),singleMaidr.axes.y&&singleMaidr.axes.y.level&&(e=singleMaidr.axes.y.level)),"data"in singleMaidr?(this.data=singleMaidr.data,this.num_rows=this.data.length,this.num_cols=this.data[0].length):console.error("No data found in singleMaidr object"),"selector"in singleMaidr?(this.elements=document.querySelectorAll(singleMaidr.selector),constants.hasRect=1):"elements"in singleMaidr?(this.elements=singleMaidr.elements,constants.hasRect=1):(this.elements=null,constants.hasRect=0),this.group_labels=this.getGroupLabels(),this.x_labels=t,this.y_labels=e,this.title=this.getTitle(),this.fill=this.getFill(),constants.hasRect&&this.SetHeatmapRectData(),this.updateConstants(),this.x_group_label=this.group_labels[0].trim(),this.y_group_label=this.group_labels[1].trim()}SetHeatmapRectData(){let t=[],e=[],n=[],o=[];for(let n=0;n<this.elements.length;n++)if(this.elements[n])if(this.elements[n]instanceof SVGPathElement){const o=this.elements[n].getAttribute("d"),s=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(o),i=[Number(s[1]),Number(s[3])],l=i[0],a=i[1];t.push(parseFloat(l)),e.push(parseFloat(a))}else t.push(parseFloat(this.elements[n].getAttribute("x"))),e.push(parseFloat(this.elements[n].getAttribute("y")));t.sort((function(t,e){return t-e})),e.sort((function(t,e){return t-e}));let s=this.GetSVGScaler();-1==s[0]&&(t=t.reverse()),-1==s[1]&&(e=e.reverse()),n=[...new Set(t)],o=[...new Set(e)],this.x_coord=n,this.y_coord=o}updateConstants(){constants.minX=0,constants.maxX=this.data[0].length-1,constants.minY=Math.min(...this.data.map((t=>Math.min(...t)))),constants.maxY=Math.max(...this.data.map((t=>Math.max(...t)))),constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}PlayTones(){audio.playTone()}GetSVGScaler(){let t=1,e=1,n=!1,o=this.elements[0];for(;o&&"body"!=o.tagName.toLowerCase();)o.tagName&&"svg"===o.tagName.toLowerCase()&&(n=!0),o=o.parentNode;if(n){let n=this.elements[0];for(;n&&"body"!=n.tagName.toLowerCase();){if(n.getAttribute("transform")){let o=n.getAttribute("transform").match(/scale\((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)\)/);o&&(isNaN(o[1])||(t*=parseFloat(o[1])),isNaN(o[3])||(e*=parseFloat(o[3])))}n=n.parentNode}}return[t,e]}getRGBNorm(t){return this.elements[t].getAttribute("fill").slice(4,-1).split(",").map((function(t){return Math.pow(t,2)})).reduce((function(t,e){return t+e}))}getGroupLabels(){let t,e="",n="";return"labels"in singleMaidr&&("x"in singleMaidr.labels&&(e=singleMaidr.labels.x),"y"in singleMaidr.labels&&(n=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&"label"in singleMaidr.axes.x&&""==e&&(e=singleMaidr.axes.x.label),"y"in singleMaidr.axes&&"label"in singleMaidr.axes.y&&""==n&&(n=singleMaidr.axes.y.label)),t=[e,n],t}getXLabels(){if("axes"in singleMaidr&&"x"in singleMaidr.axes&&"level"in singleMaidr.axes.x)return singleMaidr.axes.x.level}getYLabels(){if("axes"in singleMaidr&&"y"in singleMaidr.axes&&"level"in singleMaidr.axes.y)return singleMaidr.axes.y.level}getTitle(){return"title"in singleMaidr?singleMaidr.title:"labels"in singleMaidr&&"title"in singleMaidr.labels?singleMaidr.labels.title:void 0}getSubtitle(){if("labels"in singleMaidr&&"subtitle"in singleMaidr.labels)return singleMaidr.labels.subtitle}getCaption(){if("labels"in singleMaidr&&"caption"in singleMaidr.labels)return singleMaidr.labels.caption}getFill(){if("labels"in singleMaidr&&"fill"in singleMaidr.labels)return singleMaidr.labels.fill}}class HeatMapRect{constructor(){constants.hasRect&&(this.x=plot.x_coord[0],this.y=plot.y_coord[0],this.squareIndex=0,this.rectStrokeWidth=4,this.height=Math.abs(plot.y_coord[1]-plot.y_coord[0]),this.width=Math.abs(plot.x_coord[1]-plot.x_coord[0]))}UpdateRect(){this.x=plot.x_coord[position.x],this.y=plot.y_coord[position.y];for(let t=0;t<plot.elements.length;t++)if(plot.elements[t].getAttribute("x")==this.x&&plot.elements[t].getAttribute("y")==this.y){this.squareIndex=t;break}}UpdateRectDisplay(){this.UpdateRect(),document.getElementById("highlight_rect")&&document.getElementById("highlight_rect").remove();var t=document.createElementNS("http://www.w3.org/2000/svg","rect");t.setAttribute("id","highlight_rect"),t.setAttribute("x",this.x),t.setAttribute("y",void 0===this.y?0:this.y),t.setAttribute("width",this.width),t.setAttribute("height",this.height),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.rectStrokeWidth),t.setAttribute("fill","none"),plot.elements[this.squareIndex].parentNode.appendChild(t)}}class ScatterPlot{constructor(){this.prefix=this.GetPrefix(),this.SetScatterLayer(),this.SetLineLayer(),this.SetAxes(),this.svgScaler=this.GetSVGScaler()}SetAxes(){this.x_group_label="",this.y_group_label="",this.title="","labels"in singleMaidr&&("x"in singleMaidr.labels&&(this.x_group_label=singleMaidr.labels.x),"y"in singleMaidr.labels&&(this.y_group_label=singleMaidr.labels.y),"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&""==this.x_group_label&&(this.x_group_label=singleMaidr.axes.x.label),"y"in singleMaidr.axes&&""==this.y_group_label&&(this.y_group_label=singleMaidr.axes.y.label)),"title"in singleMaidr&&""==this.title&&(this.title=singleMaidr.title)}SetScatterLayer(){let t=this.GetElementIndex("point");-1!=t?"selector"in singleMaidr?this.plotPoints=document.querySelectorAll(singleMaidr.selector[t]):"elements"in singleMaidr&&(this.plotPoints=singleMaidr.elements[t]):"point"==singleMaidr.type&&("selector"in singleMaidr?this.plotPoints=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(this.plotPoints=singleMaidr.elements));let e=this.GetSvgPointCoords(),n=this.GetPointValues();this.chartPointsX=e[0],this.chartPointsY=e[1],this.x=n[0],this.y=n[1],this.points_count=n[2],this.max_count=n[3]}SetLineLayer(){let t=this.GetElementIndex("smooth");-1!=t?"selector"in singleMaidr?this.plotLine=document.querySelectorAll(singleMaidr.selector[t])[0]:"elements"in singleMaidr&&(this.plotLine=singleMaidr.elements[t][0]):"smooth"==singleMaidr.type&&("selector"in singleMaidr?this.plotLine=document.querySelectorAll(singleMaidr.selector)[0]:"elements"in singleMaidr&&(this.plotLine=singleMaidr.elements));let e=this.GetSvgLineCoords(),n=this.GetSmoothCurvePoints();this.chartLineX=e[0],this.chartLineY=e[1],this.curveX=n[0],this.curvePoints=n[1],this.curvePoints&&this.curvePoints.length>0?(this.curveMinY=Math.min(...this.curvePoints),this.curveMaxY=Math.max(...this.curvePoints)):(this.curveMinY=Number.MAX_VALUE,this.curveMaxY=Number.MIN_VALUE),this.gradient=this.GetGradient()}GetSvgPointCoords(){let t=new Map;if(this.plotPoints)for(let e=0;e<this.plotPoints.length;e++){let n,o;if(this.plotPoints[e]instanceof SVGPathElement){let t=this.plotPoints[e].getAttribute("d"),s=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(s[1]),o=parseFloat(s[3])}else n=parseFloat(this.plotPoints[e].getAttribute(this.prefix+"x")),o=parseFloat(this.plotPoints[e].getAttribute(this.prefix+"y"));t.has(n)?t.get(n).add(o):t.set(n,new Set([o]))}else if([].concat(singleMaidr.type).includes("point")){let e,n=this.GetElementIndex("point"),o=this.GetDataXYFormat(n);e=n>-1?singleMaidr.data[n]:singleMaidr.data;let s=[],i=[];if("array"==o)"x"in e&&(s=e.x),"y"in e&&(i=e.y);else if("object"==o)for(let t=0;t<e.length;t++){let n=e[t].x,o=e[t].y;s.push(n),i.push(o)}for(let e=0;e<s.length;e++){let n=s[e],o=i[e];t.has(n)?t.get(n).add(o):t.set(n,new Set([o]))}}t=new Map([...t].sort((function(t,e){return t[0]-e[0]}))),t.forEach((function(e,n){t[n]=Array.from(e).sort((function(t,e){return t-e}))}));let e=[...t.keys()],n=[];for(let o=0;o<e.length;o++)n.push(t[e[o]]);return[e,n]}GetElementIndex(t="point"){let e=-1;return"type"in singleMaidr&&Array.isArray(singleMaidr.type)&&(e=singleMaidr.type.indexOf(t)),e}GetDataXYFormat(t){let e,n;return e=t>-1?singleMaidr.data[t]:singleMaidr.data,n=Array.isArray(e)?"object":"array",n}GetSVGScaler(){let t=1,e=1,n=!1;if(this.plotPoints){let o=this.plotPoints[0];for(;o&&"body"!=o.tagName.toLowerCase();)o.tagName&&"svg"===o.tagName.toLowerCase()&&(n=!0),o=o.parentNode;if(n){let n=this.plotPoints[0];for(;n&&"body"!=n.tagName.toLowerCase();){if(n.getAttribute("transform")){let o=n.getAttribute("transform").match(/scale\((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)\)/);o&&(isNaN(o[1])||(t*=parseFloat(o[1])),isNaN(o[3])||(e*=parseFloat(o[3])))}n=n.parentNode}}}return[t,e]}GetPrefix(){let t=this.GetElementIndex("point"),e=null;-1!=t?"selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector[t])[0]:"elements"in singleMaidr&&(e=singleMaidr.elements[t][0]):"point"==singleMaidr.type&&("selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector)[0]:"elements"in singleMaidr&&(e=singleMaidr.elements[0]));let n="";return e&&"circle"===e.tagName.toLowerCase()&&(n="c"),n}GetPointValues(){let t,e,n=new Map,o=[],s=[],i=[],l=this.GetElementIndex("point"),a=this.GetDataXYFormat(l);if(l>-1?e=singleMaidr.data[l]:"point"==singleMaidr.type&&(e=singleMaidr.data),void 0!==e){let l=[],r=[];if("array"==a)"x"in e&&(l=e.x),"y"in e&&(r=e.y);else if("object"==a)for(let t=0;t<e.length;t++){let n=e[t].x,o=e[t].y;l.push(n),r.push(o)}for(let t=0;t<l.length;t++){let e=l[t],o=r[t];if(n.has(e))if(n.get(e).has(o)){let t=n.get(e);t.set(o,t.get(o)+1)}else n.get(e).set(o,1);else n.set(e,new Map([[o,1]]))}constants.minX=0,constants.maxX=[...new Set(l)].length,constants.minY=Math.min(...r),constants.maxY=Math.max(...r),constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate),n=new Map([...n].sort((function(t,e){return t[0]-e[0]}))),n.forEach((function(t,e){n[e]=Array.from(t).sort((function(t,e){return t[0]-e[0]}))}));for(const[t,e]of n){o.push(t);let n=[],l=[];for(const[t,o]of e)n.push(t),l.push(o);s.push(n.sort()),i.push(l)}t=Math.max(...i.map((t=>Math.max(...t))))}return[o,s,i,t]}PlayTones(){if(constants.sepPlayId&&constants.KillSepPlay(),"point"==constants.chartType)position.z=0,constants.sepPlayId=setInterval((function(){audio&&audio.playTone?(audio.playTone(),position.z+=1,position.z+1>plot.y[position.x].length&&(constants.KillSepPlay(),position.z=-1)):clearInterval(constants.sepPlayId)}),"on"==constants.sonifMode?constants.autoPlayPointsRate:0);else if("smooth"==constants.chartType){if(!audio||!audio.playTone)return void clearInterval(constants.sepPlayId);audio.playTone()}}GetSvgLineCoords(){let t=[],e=[];if(this.plotLine){if(this.plotLine instanceof SVGPathElement){const n=this.plotLine.getAttribute("d"),o=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;let s;for(;null!==(s=o.exec(n));)t.push(s[1]),e.push(s[3])}else if(this.plotLine instanceof SVGPolylineElement){let n=this.plotLine.getAttribute("points").split(" ");for(let o=0;o<n.length;o++){let s=n[o].split(",");t.push(parseFloat(s[0])),e.push(parseFloat(s[1]))}}}else if([].concat(singleMaidr.type).includes("smooth")){let n,o=this.GetElementIndex("smooth"),s=this.GetDataXYFormat(o);if(n=o>-1?singleMaidr.data[o]:singleMaidr.data,"object"==s)for(let o=0;o<n.length;o++)t.push(n[o].x),e.push(n[o].y);else"array"==s&&("x"in n&&(t=n.x),"y"in n&&(e=n.y))}return[t,e]}GetSmoothCurvePoints(){let t,e=[],n=[],o=this.GetElementIndex("smooth"),s=this.GetDataXYFormat(o);if(o>-1?t=singleMaidr.data[o]:"smooth"==singleMaidr.type&&(t=singleMaidr.data),void 0!==t)if("object"==s)for(let o=0;o<t.length;o++)e.push(t[o].x),n.push(t[o].y);else"array"==s&&("x"in t&&(e=t.x),"y"in t&&(n=t.y));return[e,n]}GetGradient(){let t=[];for(let e=0;e<this.curvePoints.length-1;e++){let n=Math.abs((this.curvePoints[e+1]-this.curvePoints[e])/(this.curveX[e+1]-this.curveX[e])).toFixed(3);t.push(n)}return t.push("end"),t}GetRectStatus(t){let e=this.GetElementIndex(t);if(e>-1){if("selector"in singleMaidr)return!!singleMaidr.selector[e];if("elements"in singleMaidr)return!!singleMaidr.elements[e]}else{if("selector"in singleMaidr)return!!singleMaidr.selector;if("elements"in singleMaidr)return!!singleMaidr.elements}}}class Layer0Point{constructor(){[].concat(singleMaidr.type).includes("point")&&(this.x=plot.chartPointsX[0],this.y=plot.chartPointsY[0],this.strokeWidth=1.35,this.hasRect=plot.GetRectStatus("point"),this.circleIndex=[])}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartPointsX[position.x],this.y=plot.chartPointsY[position.x],this.circleIndex=[];for(let t=0;t<this.y.length;t++)for(let e=0;e<plot.plotPoints.length;e++){let n,o;if(plot.plotPoints[e]instanceof SVGPathElement){const t=plot.plotPoints[e].getAttribute("d");let s=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(s[1]),o=parseFloat(s[3])}else(plot.plotPoints[e]instanceof SVGUseElement||plot.plotPoints[e]instanceof SVGCircleElement)&&(n=plot.plotPoints[e].getAttribute(plot.prefix+"x"),o=plot.plotPoints[e].getAttribute(plot.prefix+"y"));if(n==this.x&&o==this.y[t]){this.circleIndex.push(e);break}}}async PrintPoints(){await this.UpdatePoints();for(let e=0;e<this.circleIndex.length;e++){const n="http://www.w3.org/2000/svg";var t=document.createElementNS(n,"circle");if(t.setAttribute("class","highlight_point"),t.setAttribute("cx",this.x),-1==plot.svgScaler[1])t.setAttribute("cy",constants.chart.getBoundingClientRect().height-this.y[e]);else{let n;if(plot.plotPoints[this.circleIndex[e]]instanceof SVGPathElement){const t=plot.plotPoints[this.circleIndex[e]].getAttribute("d");let o=/M\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g.exec(t);n=parseFloat(o[3])}else(plot.plotPoints[this.circleIndex[e]]instanceof SVGUseElement||plot.plotPoints[this.circleIndex[e]]instanceof SVGCircleElement)&&(n=plot.plotPoints[this.circleIndex[e]].getAttribute(plot.prefix+"y"));t.setAttribute("cy",n)}t.setAttribute("r",3.95),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.strokeWidth),t.setAttribute("fill",constants.colorSelected),constants.chart.appendChild(t)}}async ClearPoints(){document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove();let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove()}UpdatePointDisplay(){this.PrintPoints()}}class Layer1Point{constructor(){[].concat(singleMaidr.type).includes("smooth")&&(this.x=plot.chartLineX[0],this.y=plot.chartLineY[0],this.strokeWidth=1.35,this.hasRect=plot.GetRectStatus("point"))}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartLineX[positionL1.x],this.y=plot.chartLineY[positionL1.x]}async PrintPoints(){await this.UpdatePoints();var t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("id","highlight_point"),t.setAttribute("cx",this.x),-1==plot.svgScaler[1]?t.setAttribute("cy",constants.chart.getBoundingClientRect().height-this.y):t.setAttribute("cy",this.y),t.setAttribute("r",3.95),t.setAttribute("stroke",constants.colorSelected),t.setAttribute("stroke-width",this.strokeWidth),t.setAttribute("fill",constants.colorSelected),-1==plot.svgScaler[1]?constants.chart.appendChild(t):plot.plotLine.parentNode.appendChild(t)}async ClearPoints(){let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove();document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove()}UpdatePointDisplay(){this.PrintPoints()}}class Histogram{constructor(){"data"in singleMaidr?(this.plotData=singleMaidr.data,this.bars=null,"selector"in singleMaidr?this.bars=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(this.bars=singleMaidr.elements),this.legendX=null,this.legendY=null,"labels"in singleMaidr&&("x"in singleMaidr.labels&&(this.legendX=singleMaidr.labels.x),"y"in singleMaidr.labels&&(this.legendY=singleMaidr.labels.y)),"axes"in singleMaidr&&("x"in singleMaidr.axes&&"label"in singleMaidr.axes.x&&(this.legendX||(this.legendX=singleMaidr.axes.x.label)),"y"in singleMaidr.axes&&"label"in singleMaidr.axes.y&&(this.legendY||(this.legendY=singleMaidr.axes.y.label))),this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),this.SetMaxMin(),this.autoplay=null):console.log("Error: no data found")}PlayTones(){audio.playTone()}SetMaxMin(){for(let t=0;t<this.plotData.length;t++)0==t?(constants.maxY=this.plotData[t].y,constants.minY=this.plotData[t].y,constants.maxX=this.plotData[t].xmax,constants.minX=this.plotData[t].xmin):(this.plotData[t].y>constants.maxY&&(constants.maxY=this.plotData[t].y),this.plotData[t].y<constants.minY&&(constants.minY=this.plotData[t].y),this.plotData[t].xmax>constants.maxX&&(constants.maxX=this.plotData[t].xmax),this.plotData[t].xmin<constants.minX&&(constants.minX=this.plotData[t].xmin));constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/this.plotData.length),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}Select(){if(this.UnSelectPrevious(),this.bars&&(this.activeElement=this.bars[position.x],this.activeElement))if(this.activeElement.hasAttribute("fill"))this.activeElementColor=this.activeElement.getAttribute("fill"),this.activeElement.setAttribute("fill",constants.GetBetterColor(this.activeElementColor));else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);this.activeElementColor=e[e.indexOf("fill")+1],e[e.indexOf("fill")+1]=constants.GetBetterColor(this.activeElementColor),t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t)}}UnSelectPrevious(){if(this.activeElement)if(this.activeElement.hasAttribute("fill"))this.activeElement.setAttribute("fill",this.activeElementColor),this.activeElement=null;else if(this.activeElement.hasAttribute("style")&&-1!==this.activeElement.getAttribute("style").indexOf("fill")){let t=this.activeElement.getAttribute("style"),e=constants.GetStyleArrayFromString(t);e[e.indexOf("fill")+1]=this.activeElementColor,t=constants.GetStyleStringFromArray(e),this.activeElement.setAttribute("style",t),this.activeElement=null}}}class LinePlot{constructor(){this.SetLineLayer(),this.SetAxes(),this.UpdateConstants()}SetLineLayer(){let t;"selector"in singleMaidr?t=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(t=singleMaidr.elements),t?this.plotLine=t[t.length-1]:constants.hasRect=0;let e=this.GetPointCoords(),n=this.GetPoints();this.chartLineX=e[0],this.chartLineY=e[1],this.pointValuesX=n[0],this.pointValuesY=n[1],this.curveMinY=Math.min(...this.pointValuesY),this.curveMaxY=Math.max(...this.pointValuesY)}UpdateConstants(){constants.minX=0,constants.maxX=singleMaidr.data.length-1,constants.minY=singleMaidr.data.reduce(((t,e)=>e.y<t?e.y:t),singleMaidr.data[0].y),constants.maxY=singleMaidr.data.reduce(((t,e)=>e.y>t?e.y:t),singleMaidr.data[0].y),constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/(constants.maxX+1)),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}GetPointCoords(){let t=[[],[]];if(!this.plotLine){let t,e=[],n=[];if("data"in singleMaidr&&(t=singleMaidr.data),void 0!==t)for(let o=0;o<t.length;o++)e.push(t[o].x),n.push(t[o].y);return[e,n]}if(this.plotLine instanceof SVGPathElement){const e=this.plotLine.getAttribute("d"),n=/[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;let o;for(;null!==(o=n.exec(e));)t[0].push(o[1]),t[1].push(o[3])}else{let e=this.plotLine.getAttribute("points").split(" ");for(let n=0;n<e.length;n++)if(""!==e[n]){let o=e[n].split(",");t[0].push(o[0]),t[1].push(o[1])}}return t}GetPoints(){let t,e=[],n=[];if("data"in singleMaidr&&(t=singleMaidr.data),void 0!==t){for(let o=0;o<t.length;o++)e.push(t[o].x),n.push(t[o].y);return[e,n]}}SetAxes(){let t="",e="";"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&""==t&&(t=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&""==e&&(e=singleMaidr.axes.y.label)),this.plotLegend={x:t,y:e},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption)}PlayTones(){audio.playTone()}}class Point{constructor(){this.x=plot.chartLineX[0],this.y=plot.chartLineY[0]}async UpdatePoints(){await this.ClearPoints(),this.x=plot.chartLineX[position.x],this.y=plot.chartLineY[position.x]}async PrintPoints(){await this.ClearPoints(),await this.UpdatePoints();var t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("id","highlight_point"),t.setAttribute("cx",this.x),t.setAttribute("cy",this.y),t.setAttribute("r",1.75),t.setAttribute("style","fill:"+constants.colorSelected+";stroke:"+constants.colorSelected),constants.chart.appendChild(t)}async ClearPoints(){let t=document.getElementsByClassName("highlight_point");for(let e=0;e<t.length;e++)document.getElementsByClassName("highlight_point")[e].remove();document.getElementById("highlight_point")&&document.getElementById("highlight_point").remove()}UpdatePointDisplay(){this.ClearPoints(),this.UpdatePoints(),this.PrintPoints()}}class Segmented{constructor(){let t=null,e=null;if("axes"in singleMaidr&&("x"in singleMaidr.axes?"level"in singleMaidr.axes.x&&(this.level=singleMaidr.axes.x.level):"y"in singleMaidr.axes&&"level"in singleMaidr.axes.y&&(this.level=singleMaidr.axes.y.level),"fill"in singleMaidr.axes&&"level"in singleMaidr.axes.fill&&(this.fill=singleMaidr.axes.fill.level)),"data"in singleMaidr&&(t=singleMaidr.data),"selector"in singleMaidr?e=document.querySelectorAll(singleMaidr.selector):"elements"in singleMaidr&&(e=singleMaidr.elements),null==e&&(logError.LogAbsentElement("elements"),constants.hasRect=0),!t)return void console.log("Segmented chart missing level, fill, or data. Unable to create chart.");{this.fill&&(this.fill=this.fill.reverse());let n=this.ParseData(t,e);this.plotData=n[0],this.elements=n[1]}let n="",o="";"axes"in singleMaidr&&(singleMaidr.axes.x&&singleMaidr.axes.x.label&&(n=singleMaidr.axes.x.label),singleMaidr.axes.y&&singleMaidr.axes.y.label&&(o=singleMaidr.axes.y.label)),"labels"in singleMaidr&&("x"in singleMaidr.labels&&(n=singleMaidr.labels.x),"y"in singleMaidr.labels&&(o=singleMaidr.labels.y)),this.plotLegend={x:n,y:o},this.title="","labels"in singleMaidr&&"title"in singleMaidr.labels&&(this.title=singleMaidr.labels.title),""==this.title&&"title"in singleMaidr&&(this.title=singleMaidr.title),"labels"in singleMaidr&&"subtitle"in singleMaidr.labels&&(this.subtitle=singleMaidr.labels.subtitle),"labels"in singleMaidr&&"caption"in singleMaidr.labels&&(this.caption=singleMaidr.labels.caption),this.SetMaxMin(),this.CreateSummaryLevel(),this.CreateAllLevel(),this.autoplay=null}ParseData(t,e=null){let n=[],o=[];e?e.length!=t.length&&(o=null):o=null;for(let s=0;s<this.level.length;s++)for(let i=0;i<this.fill.length;i++)for(let l=0;l<t.length;l++)if(n[s]||(n[s]=[],null!=o&&(o[s]||(o[s]=[]))),n[s][i]||(n[s][i]=0,null!=o&&(o[s][i]||(o[s][i]=null))),t[l].x==this.level[s]&&t[l].fill==this.fill[i]){n[s][i]=t[l].y,e&&(o[s][i]=e[l]);break}return[n,o]}CreateSummaryLevel(){for(let t=0;t<this.plotData.length;t++){let e=0;for(let n=0;n<this.plotData[t].length;n++)e+=this.plotData[t][n];this.plotData[t].push(e)}this.fill.push("Sum")}CreateAllLevel(){for(let t=0;t<this.plotData.length;t++){let e=[];for(let n=0;n<this.fill.length;n++)"Sum"!=this.fill[n]&&e.push(this.plotData[t][n]);this.plotData[t].push(e)}this.fill.push("All")}PlayTones(){if(Array.isArray(this.plotData[position.x][position.y]))if("on"==constants.sonifMode)position.z=0,constants.KillSepPlay(),constants.sepPlayId=setInterval((function(){audio.playTone(),position.z+=1,Array.isArray(plot.plotData[position.x][position.y])?position.z+1>plot.plotData[position.x][position.y].length&&(constants.KillSepPlay(),position.z=-1):(constants.KillSepPlay(),position.z=-1)}),"on"==constants.sonifMode?constants.autoPlayPointsRate:0);else{let t=Math.min(...this.plotData[position.x][position.y]),e=Math.max(...this.plotData[position.x][position.y]);for(let n=0;n<this.plotData[position.x][position.y].length;n++){position.z=n;let o=audio.SlideBetween(this.plotData[position.x][position.y][n],t,e,constants.combinedVolMin,constants.combinedVolMax);audio.playTone({volScale:o})}}else audio.playTone()}SetMaxMin(){for(let t=0;t<singleMaidr.data.length;t++)0==t?(constants.maxY=singleMaidr.data[t].y,constants.minY=singleMaidr.data[t].y):(singleMaidr.data[t].y>constants.maxY&&(constants.maxY=singleMaidr.data[t].y),singleMaidr.data[t].y<constants.minY&&(constants.minY=singleMaidr.data[t].y));constants.maxX=this.level.length,constants.autoPlayRate=Math.ceil(constants.AUTOPLAY_DURATION/this.plotData.length),constants.DEFAULT_SPEED=constants.autoPlayRate,constants.autoPlayRate<constants.MIN_SPEED&&(constants.MIN_SPEED=constants.autoPlayRate)}Select(){if(this.UnSelectPrevious(),this.elements&&(this.activeElement=this.elements[position.x][position.y],this.activeElement)){this.activeElementColor=this.activeElement.style.fill;let t=constants.GetBetterColor(this.activeElementColor);this.activeElement.style.fill=t}}UnSelectPrevious(){this.activeElement&&(this.activeElement.style.fill=this.activeElementColor,this.activeElement=null)}}class Control{controlElements=[constants.chart,constants.brailleInput];allControlElements=[constants.chart,constants.brailleInput,constants.review_container];pressedL=!1;constructor(){constants.lastx=0,this.InitChartClass(),this.SetBTSControls(),this.SetPrefixControls(),this.SetControls()}InitChartClass(){[].concat(singleMaidr.type).includes("bar")?window.plot=new BarChart:[].concat(singleMaidr.type).includes("box")?window.plot=new BoxPlot:[].concat(singleMaidr.type).includes("heat")?(window.plot=new HeatMap,singleMaidr.rect=new HeatMapRect):[].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")?(window.plot=new ScatterPlot,window.layer0Point=new Layer0Point,window.layer1Point=new Layer1Point):[].concat(singleMaidr.type).includes("hist")?window.plot=new Histogram:([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))&&(window.plot=new Segmented)}SetBTSControls(){for(let t=0;t<this.allControlElements.length;t++)constants.events.push([this.allControlElements[t],"keydown",function(t){if(!constants.pressedL&&("b"!=t.key||control.pressedL||(constants.tabMovement=0,t.preventDefault(),display.toggleBrailleMode()),"t"!=t.key||control.pressedL||display.toggleTextMode(),"s"!=t.key||control.pressedL||display.toggleSonificationMode(),"r"!=t.key||t.ctrlKey||t.shiftKey||control.pressedL||(constants.tabMovement=0,t.preventDefault(),constants.review_container.classList.contains("hidden")?review.ToggleReviewMode(!0):review.ToggleReviewMode(!1))," "!=t.key||control.pressedL||(position.x<0&&(position.x=0),position.y<0&&(position.y=0),constants.showDisplay&&display.displayValues(),"off"!=constants.sonifMode&&plot.PlayTones()),Array.isArray(singleMaidr.type)&&[].concat(singleMaidr.type).includes("point")&&[].concat(singleMaidr.type).includes("smooth")&&("PageDown"==t.key&&"off"==constants.brailleMode&&display.changeChartLayer("down"),"PageUp"==t.key&&"off"==constants.brailleMode&&display.changeChartLayer("up")),"-"==t.key)){}}]);constants.events.push([constants.review,"keydown",function(t){t.key.startsWith("Arrow")||t.shiftKey&&t.key.startsWith("Arrow")||t.ctrlKey&&"a"===t.key||t.ctrlKey&&"c"===t.key||t.preventDefault()}]);for(let t=0;t<this.allControlElements.length;t++)constants.events.push([this.allControlElements[t],"keydown",function(t){"Tab"==t.key&&(t.shiftKey?constants.tabDirection=-1:constants.tabDirection=1)}])}SetPrefixControls(){constants.events.push([document,"keydown",function(t){let e=null;if("l"==t.key&&(control.pressedL=!0,null!=e&&(clearTimeout(e),e=null),e=setTimeout((function(){control.pressedL=!1}),constants.keypressInterval)),control.pressedL)if("x"==t.key){let t="";"bar"==singleMaidr.type||"line"==singleMaidr.type?t=plot.plotLegend.x:"hist"==singleMaidr.type?t=plot.legendX:"heat"==singleMaidr.type||"box"==singleMaidr.type||"point"==singleMaidr.type||singleMaidr.type.includes("point")?t=plot.x_group_label:"stacked_bar"!=singleMaidr.type&&"stacked_normalized_bar"!=singleMaidr.type&&"dodged_bar"!=singleMaidr.type||(t=plot.plotLegend.x),display.displayInfo("x label",t),control.pressedL=!1}else if("y"==t.key){let t="";"bar"==singleMaidr.type||"line"==singleMaidr.type?t=plot.plotLegend.y:"hist"==singleMaidr.type?t=plot.legendY:"heat"==singleMaidr.type||"box"==singleMaidr.type||"point"==singleMaidr.type||"line"==singleMaidr.type||singleMaidr.type.includes("point")?t=plot.y_group_label:"stacked_bar"!=singleMaidr.type&&"stacked_normalized_bar"!=singleMaidr.type&&"dodged_bar"!=singleMaidr.type||(t=plot.plotLegend.y),display.displayInfo("y label",t),control.pressedL=!1}else"t"==t.key?(display.displayInfo("title",plot.title),control.pressedL=!1):"s"==t.key?(display.displayInfo("subtitle",plot.subtitle),control.pressedL=!1):"c"==t.key?(display.displayInfo("caption",plot.caption),control.pressedL=!1):"f"==t.key?(display.displayInfo("fill",plot.fill),control.pressedL=!1):"l"!=t.key&&(control.pressedL=!1)}])}async SetControls(){constants.events.push([document,"keydown",function(t){(constants.isMac?t.metaKey:t.ctrlKey)&&("Home"==t.key?("bar"==constants.chartType||"hist"==constants.chartType?position.x=0:"box"==constants.chartType?(position.x=0,position.y=plot.sections.length-1):"heat"==constants.chartType?(position.x=0,position.y=0):"point"==constants.chartType?position.x=0:"smooth"==constants.chartType&&(positionL1.x=0),control.UpdateAllBraille()):"End"==t.key&&("bar"==constants.chartType||"hist"==constants.chartType?position.x=plot.bars.length-1:"box"==constants.chartType?(position.x=plot.sections.length-1,position.y=0):"heat"==constants.chartType?(position.x=plot.num_cols-1,position.y=plot.num_rows-1):"point"==constants.chartType?position.x=plot.y.length-1:"smooth"==constants.chartType&&(positionL1.x=plot.curvePoints.length-1),control.UpdateAllBraille()))}]);if([].concat(singleMaidr.type).includes("bar")?window.position=new Position(-1,-1):[].concat(singleMaidr.type).includes("box")?(constants.plotId="geom_boxplot.gTree.78.1","vert"==constants.plotOrientation?window.position=new Position(0,6):window.position=new Position(-1,plot.plotData.length),constants.hasRect&&(singleMaidr.rect=new BoxplotRect)):[].concat(singleMaidr.type).includes("heat")?(constants.plotId="geom_rect.rect.2.1",window.position=new Position(-1,-1),constants.lastx=0):[].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")?(constants.plotId="geom_point.points.12.1",window.position=new Position(-1,-1),constants.lastx=0,constants.lastx1=0,window.positionL1=new Position(constants.lastx1,constants.lastx1)):([].concat(singleMaidr.type).includes("hist")||[].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))&&(window.position=new Position(-1,-1)),[].concat(singleMaidr.type).includes("box")?document.addEventListener("selectionchange",(function(t){if(t.preventDefault(),"on"==constants.brailleMode&&constants.brailleInput.selectionStart){if(constants.lockSelection)return;constants.lockSelection=!0;let t=constants.brailleInput.selectionStart;t=constants.brailleInput.selectionStart,t<0&&(o=0);let e=0,n="";if(constants.brailleData)for(let o=0;o<constants.brailleData.length;o++)if(e+=constants.brailleData[o].numChars,e>t){n="blank"==constants.brailleData[o].type?constants.brailleData[o+1].type:constants.brailleData[o].type;break}let o=plot.sections.indexOf(n);if(n.length>0){let t=0,e=0;"vert"==constants.plotOrientation?(position.y=o,t=plot.plotData.length-1,e=plot.sections.length-1):(position.x=o,t=plot.sections.length-1,e=plot.plotData.length-1),control.lockPosition(t,e);let n=!0;n&&(this.lockPosition=!0,control.UpdateAll(),this.lockPosition=!1),n&&audio.playEnd()}setTimeout((function(){constants.lockSelection=!1}),50)}})):[].concat(singleMaidr.type).includes("heat")?document.addEventListener("selectionchange",(function(t){if("on"==constants.brailleMode){if(constants.lockSelection)return;let t=constants.brailleInput.selectionStart;if(constants.lockSelection=!0,constants.brailleInput.value.split("").reduce(((t,e,n)=>("⠳"===e&&t.push(n),t)),[]).includes(t))return;t=constants.brailleInput.selectionStart,t<0&&(t=0),position.y=Math.floor(t/(plot.num_cols+1)),position.x=t%(plot.num_cols+1),control.lockPosition(plot.num_cols-1,plot.num_rows-1);let e=!0;e&&control.UpdateAll(),e&&audio.playEnd(),setTimeout((function(){constants.lockSelection=!1}),50)}})):([].concat(singleMaidr.type).includes("bar")||[].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")||[].concat(singleMaidr.type).includes("hist")||[].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))&&document.addEventListener("selectionchange",(function(t){if("on"==constants.brailleMode){if(constants.lockSelection)return;if(constants.lockSelection=!0,constants.brailleInput){let t=constants.brailleInput.selectionStart;t=constants.brailleInput.selectionStart,t<0&&(t=0),position.x=t,control.lockPosition();let e=!0;e&&control.UpdateAll(),e&&audio.playEnd()}setTimeout((function(){constants.lockSelection=!1}),50)}})),[].concat(singleMaidr.type).includes("bar")){constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;if("ArrowRight"==t.key)if(constants.isMac?t.metaKey:t.ctrlKey)t.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.plotData.length)):(position.x=plot.plotData.length-1,e=!0,n=control.lockPosition());else if(t.altKey&&t.shiftKey&&position.x!=plot.bars.length-1)constants.lastx=position.x,control.Autoplay("reverse-right",plot.bars.length,position.x);else{position.x+=1,e=!0,n=control.lockPosition()}else"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=control.lockPosition()));e&&!n&&control.UpdateAll(),n&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(t.preventDefault(),t.target.selectionStart>t.target.value.length-2||((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.plotData.length)):(position.x=plot.bars.length-1,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&position.x!=plot.bars.length-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.bars.length,position.x)):(position.x+=1,e=!0,n=control.lockPosition()))):"ArrowLeft"==t.key?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=control.lockPosition())):"Tab"==t.key||t.preventDefault(),e&&!n&&control.UpdateAllBraille(),n&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}])}else if([].concat(singleMaidr.type).includes("box")){let t=0,e=0;"vert"==constants.plotOrientation?(t=plot.plotData.length-1,e=plot.sections.length-1):(t=plot.sections.length-1,e=plot.plotData.length-1),constants.events.push([constants.chart,"keydown",function(n){let o=!1,s=!1;if("ArrowRight"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?"vert"==constants.plotOrientation?control.Autoplay("right",position.x,plot.plotData.length-1):control.Autoplay("right",position.x,plot.sections.length-1):(s=control.lockPosition(t,e),"vert"==constants.plotOrientation?position.x=plot.plotData.length-1:position.x=plot.sections.length-1,o=!0,s=control.lockPosition(t,e)):"vert"==constants.plotOrientation?n.altKey&&n.shiftKey&&plot.sections.length-1!=position.x?(lastY=position.y,control.Autoplay("reverse-right",plot.plotData.length-1,position.x)):(-1==position.x&&position.y==plot.sections.length&&(position.y-=1),position.x+=1,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&plot.sections.length-1!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.sections.length-1,position.x)):(-1==position.x&&position.y==plot.plotData.length&&(position.y-=1),position.x+=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=1),"ArrowLeft"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?control.Autoplay("left",position.x,-1):(position.x=0,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&position.x>0?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,control.Autoplay("reverse-left",0,position.x)):(position.x+=-1,o=!0,s=control.lockPosition(t,e)),constants.navigation=1),"ArrowUp"==n.key){position.y;(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?"vert"==constants.plotOrientation?control.Autoplay("up",position.y,plot.sections.length):control.Autoplay("up",position.y,plot.plotData.length):("vert"==constants.plotOrientation?position.y=plot.sections.length-1:position.y=plot.plotData.length-1,o=!0,s=control.lockPosition(t,e)):"vert"==constants.plotOrientation?n.altKey&&n.shiftKey&&position.y!=plot.sections.length-1?(lastY=position.y,control.Autoplay("reverse-up",plot.sections.length-1,position.y)):(position.y+=1,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&position.y!=plot.sections.length-1?(constants.lastx=position.x,control.Autoplay("reverse-up",plot.plotData.length-1,position.y)):(position.y+=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=0}if("ArrowDown"==n.key){position.y;(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?control.Autoplay("down",position.y,-1):(position.y=0,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&0!=position.y?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,control.Autoplay("reverse-down",0,position.y)):("vert"==constants.plotOrientation?-1==position.x&&position.y==plot.sections.length&&(position.x+=1):-1==position.x&&position.y==plot.plotData.length&&(position.x+=1),position.y+=-1,o=!0,s=control.lockPosition(t,e)),constants.navigation=0}o&&!s&&control.UpdateAll(),s&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(n){let o=!1,s=!1,i=!1;if("ArrowRight"==n.key)n.preventDefault(),(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?"vert"==constants.plotOrientation?control.Autoplay("right",position.x,plot.plotData.length-1):control.Autoplay("right",position.x,plot.sections.length):("vert"==constants.plotOrientation?position.x=plot.plotData.length-1:position.x=plot.sections.length-1,o=!0,i=control.lockPosition(t,e)):"vert"==constants.plotOrientation?n.altKey&&n.shiftKey&&plot.plotData.length-1!=position.x?(lastY=position.y,control.Autoplay("reverse-right",plot.plotData.length-1,position.x)):(-1==position.x&&position.y==plot.plotData[position.x].length&&(position.y-=1),position.x+=1,o=!0,i=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&plot.sections.length-1!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.sections.length-1,position.x)):(-1==position.x&&position.y==plot.plotData.length&&(position.y-=1),position.x+=1,o=!0,i=control.lockPosition(t,e)),s=!0,constants.navigation=1;else if("ArrowLeft"==n.key)n.preventDefault(),(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?control.Autoplay("left",position.x,-1):(position.x=0,o=!0,i=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&position.x>0?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,control.Autoplay("reverse-left",0,position.x)):(position.x+=-1,o=!0,i=control.lockPosition(t,e)),s=!0,constants.navigation=1;else if("ArrowUp"==n.key){position.y;(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?"vert"==constants.plotOrientation?(position.x<0&&(position.x=0),control.Autoplay("up",position.y,plot.sections.length)):control.Autoplay("up",position.y,plot.plotData.length):"vert"==constants.plotOrientation?(position.y=plot.sections.length-1,o=!0):(position.y=plot.plotData.length-1,o=!0):"vert"==constants.plotOrientation?n.altKey&&n.shiftKey&&position.y!=plot.sections.length-1?(lasY=position.y,control.Autoplay("reverse-up",plot.sections.length-1,position.y)):(position.y+=1,o=!0,i=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&position.y!=plot.plotData.length-1?(constants.lastx=position.x,control.Autoplay("reverse-up",plot.plotData.length-1,position.y)):(position.y+=1,o=!0,i=control.lockPosition(t,e)),"vert"==constants.plotOrientation||(s=!0),constants.navigation=0}else if("ArrowDown"==n.key){position.y;(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?control.Autoplay("down",position.y,-1):(position.y=0,o=!0,i=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&0!=position.y?("vert"==constants.plotOrientation?lastY=position.y:constants.lastx=position.x,control.Autoplay("reverse-down",0,position.y)):("vert"==constants.plotOrientation?-1==position.x&&position.y==plot.sections.length&&(position.x+=1):-1==position.x&&position.y==plot.plotData.length&&(position.x+=1),position.y+=-1,o=!0,i=control.lockPosition(t,e)),constants.navigation=0,"vert"==constants.plotOrientation||(s=!0),constants.navigation=0}else"Tab"==n.key||n.preventDefault();o&&!i&&(s&&display.SetBraille(plot),setTimeout(control.UpdateAllBraille,50)),i&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}])}else if([].concat(singleMaidr.type).includes("heat")){let t=plot.num_cols-1,e=plot.num_rows-1;constants.events.push([constants.chart,"keydown",function(n){let o=!1,s=!1;"ArrowRight"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.num_cols)):(position.x=plot.num_cols-1,o=!0):n.altKey&&n.shiftKey&&position.x!=plot.num_cols-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.num_cols,position.x)):(-1==position.x&&-1==position.y&&(position.y+=1),position.x+=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=1),"ArrowLeft"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,o=!0):n.altKey&&n.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x-=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=1),"ArrowUp"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.y+=1,control.Autoplay("up",position.y,-1)):(position.y=0,o=!0):n.altKey&&n.shiftKey&&0!=position.y?(constants.lastx=position.x,control.Autoplay("reverse-up",-1,position.y)):(position.y-=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=0),"ArrowDown"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.y-=1,control.Autoplay("down",position.y,plot.num_rows)):(position.y=plot.num_rows-1,o=!0):n.altKey&&n.shiftKey&&position.y!=plot.num_rows-1?(constants.lastx=position.x,control.Autoplay("reverse-down",plot.num_rows,position.y)):(-1==position.x&&-1==position.y&&(position.x+=1),position.y+=1,o=!0,s=control.lockPosition(t,e)),constants.navigation=0),o&&!s&&control.UpdateAll(),s&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}]);constants.events.push([constants.brailleInput,"keydown",function(n){let o=!1,s=!1;if("ArrowRight"==n.key)if(n.target.selectionStart>n.target.value.length-3||"⠳"==n.target.value.substring(n.target.selectionStart+1,n.target.selectionStart+2))n.preventDefault();else{(constants.isMac?n.metaKey:n.ctrlKey)?(-1==position.x&&-1==position.y&&(position.x+=1,position.y+=1),n.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.num_cols)):(position.x=plot.num_cols-1,o=!0)):n.altKey&&n.shiftKey&&position.x!=plot.num_cols-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.num_cols,position.x)):(-1==position.x&&-1==position.y&&(position.y+=1),position.x+=1,o=!0,s=control.lockPosition(t,e));let i=position.y*(plot.num_cols+1)+position.x;n.target.setSelectionRange(i,i),n.preventDefault(),constants.navigation=1}else if("ArrowLeft"==n.key)if(0==n.target.selectionStart||"⠳"==n.target.value.substring(n.target.selectionStart-1,n.target.selectionStart))n.preventDefault();else{(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,o=!0):n.altKey&&n.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x+=-1,o=!0,s=control.lockPosition(t,e));let i=position.y*(plot.num_cols+1)+position.x;n.target.setSelectionRange(i,i),n.preventDefault(),constants.navigation=1}else if("ArrowDown"==n.key)if(position.y+1==plot.num_rows)n.preventDefault();else{(constants.isMac?n.metaKey:n.ctrlKey)?(-1==position.x&&-1==position.y&&(position.x+=1,position.y+=1),n.shiftKey?(position.y-=1,control.Autoplay("down",position.y,plot.num_rows)):(position.y=plot.num_rows-1,o=!0)):n.altKey&&n.shiftKey&&position.y!=plot.num_rows-1?(constants.lastx=position.x,control.Autoplay("reverse-down",plot.num_rows,position.y)):(-1==position.x&&-1==position.y&&(position.x+=1),position.y+=1,o=!0,s=control.lockPosition(t,e));let i=position.y*(plot.num_cols+1)+position.x;n.target.setSelectionRange(i,i),n.preventDefault(),constants.navigation=0}else if("ArrowUp"==n.key)if(n.target.selectionStart-plot.num_cols-1<0)n.preventDefault();else{(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.y+=1,control.Autoplay("up",position.y,-1)):(position.y=0,o=!0):n.altKey&&n.shiftKey&&0!=position.y?(constants.lastx=position.x,control.Autoplay("reverse-up",-1,position.y)):(position.y+=-1,o=!0,s=control.lockPosition(t,e));let i=position.y*(plot.num_cols+1)+position.x;n.target.setSelectionRange(i,i),n.preventDefault(),constants.navigation=0}else"Tab"==n.key||n.preventDefault();o&&!s&&control.UpdateAllBraille(),s&&audio.playEnd()}])}else if([].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")){let t=0,e=0;"point"==constants.chartType?t=plot.x.length-1:"smooth"==constants.chartType&&(t=plot.curvePoints.length-1),constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(n){let o=!1,s=!1;"point"==constants.chartType?("ArrowRight"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.x.length)):(position.x=plot.x.length-1,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&position.x!=plot.x.length-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.x.length,position.x)):(position.x+=1,o=!0,s=control.lockPosition(t,e))),"ArrowLeft"==n.key&&((constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x-=1,o=!0,s=control.lockPosition(t,e)))):"smooth"==constants.chartType&&(positionL1.x||(positionL1.x=constants.lastx1),"ArrowRight"==n.key&&n.shiftKey&&((constants.isMac?n.metaKey:n.ctrlKey)&&"off"!=constants.sonifMode?control.PlayLine("right"):n.altKey&&"off"!=constants.sonifMode&&control.PlayLine("reverse-right")),"ArrowLeft"==n.key&&n.shiftKey&&((constants.isMac?n.metaKey:n.ctrlKey)&&"off"!=constants.sonifMode?control.PlayLine("left"):n.altKey&&"off"!=constants.sonifMode&&control.PlayLine("reverse-left"))),o&&"point"==constants.chartType&&!s&&control.UpdateAll(),s&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}]);constants.events.push([constants.brailleInput,"keydown",function(n){let o=!1,s=!1;"smooth"==constants.chartType?(control.lockPosition(t,e),"ArrowRight"==n.key?(n.preventDefault(),constants.brailleInput.setSelectionRange(positionL1.x,positionL1.x),n.target.selectionStart>n.target.value.length-2?n.preventDefault():(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(positionL1.x-=1,control.Autoplay("right",positionL1.x,plot.curvePoints.length)):(positionL1.x=plot.curvePoints.length-1,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&positionL1.x!=plot.curvePoints.length-1?(constants.lastx1=positionL1.x,control.Autoplay("reverse-right",plot.curvePoints.length,positionL1.x)):(positionL1.x+=1,o=!0,s=control.lockPosition(t,e))):"ArrowLeft"==n.key?(n.preventDefault(),(constants.isMac?n.metaKey:n.ctrlKey)?n.shiftKey?(positionL1.x+=1,control.Autoplay("left",positionL1.x,-1)):(positionL1.x=0,o=!0,s=control.lockPosition(t,e)):n.altKey&&n.shiftKey&&0!=positionL1.x?control.Autoplay("reverse-left",-1,positionL1.x):(positionL1.x-=1,o=!0,s=control.lockPosition(t,e))):n.preventDefault()):"Tab"==n.key||n.preventDefault(),constants.lastx1=positionL1.x,o&&!s&&control.UpdateAllBraille(),s&&audio.playEnd()}])}else if([].concat(singleMaidr.type).includes("hist")){constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(t){let e=!1,n=!1;"ArrowRight"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(t.preventDefault(),position.x-=1,control.Autoplay("right",position.x,plot.plotData.length)):"ArrowRight"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(t.preventDefault(),constants.lastx=position.x,control.Autoplay("reverse-right",plot.bars.length,position.x)):"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(t.preventDefault(),position.x=plot.plotData.length-1,e=!0,n=control.lockPosition()):(t.preventDefault(),position.x+=1,e=!0,n=control.lockPosition()),"ArrowLeft"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(t.preventDefault(),position.x+=1,control.Autoplay("left",position.x,-1)):"ArrowLeft"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(t.preventDefault(),constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(t.preventDefault(),position.x=0,e=!0,n=control.lockPosition()):(t.preventDefault(),position.x+=-1,e=!0,n=control.lockPosition()),e&&!n&&("off"==constants.brailleMode?control.UpdateAll():control.UpdateAllBraille()),n&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(t.preventDefault(),constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(t.preventDefault(),constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(t.preventDefault(),constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}])}else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar")){constants.events.push([[constants.chart,constants.brailleInput],"keydown",function(t){let e=!1,n=!1;constants.navigation=0,"on"==constants.brailleMode&&("Tab"==t.key||t.preventDefault()),"ArrowRight"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.plotData.length)):"ArrowRight"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.plotData.length,position.x)):"ArrowRight"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.x=plot.plotData.length-1,e=!0,n=control.lockPosition()):(position.x+=1,e=!0,constants.navigation=1,n=control.lockPosition()),"ArrowLeft"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):"ArrowLeft"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):"ArrowLeft"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.x=0,e=!0,n=control.lockPosition()):(position.x+=-1,e=!0,constants.navigation=1,n=control.lockPosition()),"ArrowUp"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowUp"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?control.Autoplay("up",position.y,plot.plotData[0].length):"ArrowUp"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,control.Autoplay("reverse-up",-1,plot.plotData[0].length)):"ArrowUp"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.y=plot.plotData[0].length-1,e=!0):(position.y+=1,e=!0,constants.navigation=0,n=control.lockPosition()),"ArrowDown"!=t.key||(constants.isMac?t.metaKey:t.ctrlKey)||t.shiftKey?"ArrowDown"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&t.shiftKey?control.Autoplay("down",position.y,-1):"ArrowDown"==t.key&&!(constants.isMac?t.metaKey:t.ctrlKey)&&t.altKey&&t.shiftKey?(constants.lastx=position.x,control.Autoplay("reverse-down",-1,position.y)):"ArrowDown"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)&&!t.shiftKey&&(position.y=0,e=!0):(position.y+=-1,e=!0,constants.navigation=0,n=control.lockPosition()),e&&!n&&("off"==constants.brailleMode?control.UpdateAll():control.UpdateAllBraille())}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}])}else if([].concat(singleMaidr.type).includes("line")){window.position=new Position(-1,-1),window.plot=new LinePlot;constants.lastx=0,document.addEventListener("selectionchange",(function(t){if("on"==constants.brailleMode){if(constants.lockSelection)return;constants.lockSelection=!0;let t=constants.brailleInput.selectionStart;t=constants.brailleInput.selectionStart,t<0&&(t=0),position.x=t,control.lockPosition();let e=!0;e&&control.UpdateAll(),e&&audio.playEnd(),setTimeout((function(){constants.lockSelection=!1}),50)}})),constants.events.push([constants.chart,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.pointValuesY.length)):(position.x=plot.pointValuesY.length-1,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&position.x!=plot.pointValuesY.length-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.pointValuesY.length,position.x)):(position.x+=1,e=!0,n=control.lockPosition()):"ArrowLeft"==t.key&&((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=control.lockPosition())),e&&!n&&control.UpdateAll(),n&&audio.playEnd()}]),constants.events.push([constants.brailleInput,"keydown",function(t){let e=!1,n=!1;"ArrowRight"==t.key?(t.preventDefault(),t.target.selectionStart>t.target.value.length-2||((constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x-=1,control.Autoplay("right",position.x,plot.pointValuesY.length)):(position.x=plot.pointValuesY.length-1,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&position.x!=plot.pointValues.length-1?(constants.lastx=position.x,control.Autoplay("reverse-right",plot.pointValuesY.length,position.x)):(position.x+=1,e=!0,n=control.lockPosition()))):"ArrowLeft"==t.key?(t.preventDefault(),(constants.isMac?t.metaKey:t.ctrlKey)?t.shiftKey?(position.x+=1,control.Autoplay("left",position.x,-1)):(position.x=0,e=!0,n=control.lockPosition()):t.altKey&&t.shiftKey&&0!=position.x?(constants.lastx=position.x,control.Autoplay("reverse-left",-1,position.x)):(position.x+=-1,e=!0,n=control.lockPosition())):"Tab"==t.key||t.preventDefault(),e&&!n&&control.UpdateAllBraille(),n&&audio.playEnd()}]);for(let t=0;t<this.controlElements.length;t++)constants.events.push([this.controlElements[t],"keydown",function(t){"."==t.key&&(constants.SpeedUp(),control.PlayDuringSpeedChange(),display.announceText("Speed up")),","==t.key&&(constants.SpeedDown(),control.PlayDuringSpeedChange(),display.announceText("Speed down")),"/"==t.key&&(constants.SpeedReset(),control.PlayDuringSpeedChange(),display.announceText("Speed reset"))}])}}PlayDuringSpeedChange(){null!=constants.autoplayId&&(constants.KillAutoplay(),audio.KillSmooth(),"reverse-left"==lastPlayed?"point"==constants.chartType?control.Autoplay("right",position.x,lastx):"smooth"==constants.chartType?control.Autoplay("right",positionL1.x,constants.lastx1):"vert"==constants.plotOrientation?control.Autoplay("right",position.y,lastY):control.Autoplay("right",position.x,lastx):"reverse-right"==lastPlayed?"point"==constants.chartType?control.Autoplay("left",position.x,lastx):"smooth"==constants.chartType?control.Autoplay("left",positionL1.x,constants.lastx1):"vert"==constants.plotOrientation?control.Autoplay("left",position.y,lastY):control.Autoplay("left",position.x,lastx):"reverse-up"==lastPlayed?"vert"==constants.plotOrientation?control.Autoplay("down",position.y,lastY):control.Autoplay("down",position.x,lastx):"reverse-down"==lastPlayed?"vert"==constants.plotOrientation?control.Autoplay("up",position.y,lastY):control.Autoplay("up",position.x,lastx):"point"==constants.chartType?control.Autoplay(lastPlayed,position.x,lastx):"smooth"==constants.chartType?control.Autoplay(lastPlayed,positionL1.x,constants.lastx1):"vert"==constants.plotOrientation?control.Autoplay(lastPlayed,position.y,lastY):control.Autoplay(lastPlayed,position.x,lastx))}lockPosition(t,e){let n=!1;return control.isUndefinedOrNull(t)&&"smooth"!=constants.chartType&&"line"!=constants.chartType&&("vert"==constants.plotOrientation?(t=0,e=plot.sections.length-1):(t=plot.plotData.length-1,e=0)),"smooth"==constants.chartType?(positionL1.x<0&&(positionL1.x=0,n=!0),positionL1.x>plot.curvePoints.length-1&&(positionL1.x=plot.curvePoints.length-1,n=!0)):"line"==constants.chartType?(position.x<0&&(position.x=0,n=!0),position.x>plot.pointValuesY.length-1&&(position.x=plot.pointValuesY.length-1,n=!0)):"stacked_bar"==constants.chartType||"stacked_normalized_bar"==constants.chartType||"dodged_bar"==constants.chartType?(position.x<0?(position.x=0,n=!0):position.x>plot.level.length-1&&(position.x=plot.level.length-1,n=!0),position.y<0?(position.y=0,n=!0):position.y>plot.fill.length-1&&(position.y=plot.fill.length-1,n=!0)):(position.y<0&&(position.y=0,n=!0,"off"!=constants.brailleMode&&(constants.brailleInput.selectionEnd=0)),position.x<0&&(position.x=0,n=!0,"off"!=constants.brailleMode&&(constants.brailleInput.selectionEnd=0)),position.x>t&&(position.x=t,n=!0,constants.brailleInput.selectionStart=constants.brailleInput.value.length),position.y>e&&(position.y=e,n=!0,constants.brailleInput.selectionStart=constants.brailleInput.value.length)),n}UpdateAll(){if(constants.showDisplay&&display.displayValues(),constants.showRect&&constants.hasRect)if([].concat(singleMaidr.type).includes("bar"))plot.Select();else if([].concat(singleMaidr.type).includes("box"))singleMaidr.rect.UpdateRect();else if([].concat(singleMaidr.type).includes("heat"))singleMaidr.rect.UpdateRectDisplay();else if([].concat(singleMaidr.type).includes("point"))layer0Point.hasRect&&layer0Point.UpdatePointDisplay();else if([].concat(singleMaidr.type).includes("smooth"))layer1Point.hasRect&&layer1Point.UpdatePointDisplay();else if([].concat(singleMaidr.type).includes("hist"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("line")&&constants.showRect&&constants.hasRect){(new Point).UpdatePointDisplay()}"off"!=constants.sonifMode&&plot.PlayTones()}UpdateAllAutoPlay(){if(constants.showDisplayInAutoplay&&display.displayValues(),constants.showRect&&constants.hasRect)if([].concat(singleMaidr.type).includes("bar"))plot.Select();else if([].concat(singleMaidr.type).includes("box"))singleMaidr.rect.UpdateRect();else if([].concat(singleMaidr.type).includes("heat"))singleMaidr.rect.UpdateRectDisplay();else if([].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth"))constants.showRect&&("point"==constants.chartType&&layer0Point.hasRect?layer0Point.UpdatePointDisplay():"smooth"==constants.chartType&&layer1Point.hasRect&&layer1Point.UpdatePointDisplay());else if([].concat(singleMaidr.type).includes("hist"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("line")&&constants.showRect){(new Point).UpdatePointDisplay()}"off"!=constants.sonifMode&&plot.PlayTones(),"off"!=constants.brailleMode&&display.UpdateBraillePos()}UpdateAllBraille(){if(constants.showDisplayInBraille&&(([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))&&display.SetBraille(),display.displayValues()),constants.showRect&&constants.hasRect)if([].concat(singleMaidr.type).includes("bar"))plot.Select();else if([].concat(singleMaidr.type).includes("box"))singleMaidr.rect.UpdateRect();else if([].concat(singleMaidr.type).includes("heat"))singleMaidr.rect.UpdateRectDisplay();else if([].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth"))layer1Point.hasRect&&layer1Point.UpdatePointDisplay();else if([].concat(singleMaidr.type).includes("hist"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar"))constants.showRect&&constants.hasRect&&plot.Select();else if([].concat(singleMaidr.type).includes("line")&&constants.showRect){(new Point).UpdatePointDisplay()}"off"!=constants.sonifMode&&plot.PlayTones(),display.UpdateBraillePos()}Autoplay(t,e,n){let o=t;if([].concat(singleMaidr.type).includes("bar")){let o=1;"left"!=t&&"reverse-right"!=t||(o=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=o,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),control.lockPosition()):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()}),constants.autoPlayRate)}else if([].concat(singleMaidr.type).includes("box")){o=t;let s=1;"left"!=t&&"down"!=t&&"reverse-right"!=t&&"reverse-up"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.debugLevel>0&&console.log("starting autoplay",t,e,n),control.UpdateAllAutoPlay(),constants.autoplayId=setInterval((function(){let e=!1;"left"==t||"right"==t||"up"==t||"down"==t?(position.x<1&&"left"==t||"vert"==constants.plotOrientation&&"up"==t&&position.y>plot.sections.length-2||"horz"==constants.plotOrientation&&"up"==t&&position.y>plot.plotData.length-2||"horz"==constants.plotOrientation&&"right"==t&&position.x>plot.sections.length-2||"vert"==constants.plotOrientation&&"right"==t&&position.x>plot.plotData.length-2||"horz"==constants.plotOrientation&&"down"==t&&position.y<1||"vert"==constants.plotOrientation&&"down"==t&&position.y<1)&&(e=!0):("reverse-left"==t&&position.x>=n||"reverse-right"==t&&position.x<=n||"reverse-up"==t&&position.y<=n||"reverse-down"==t&&position.y>=n)&&(e=!0),e?constants.KillAutoplay():("left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?position.x+=s:position.y+=s,control.UpdateAllAutoPlay()),constants.debugLevel>5&&console.log("autoplay pos",position)}),constants.autoPlayRate)}else if([].concat(singleMaidr.type).includes("heat")){o=t;let s=plot.num_cols-1,i=plot.num_rows-1,l=1;"left"!=t&&"up"!=t&&"reverse-right"!=t&&"reverse-down"!=t||(l=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.autoplayId=setInterval((function(){"left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?(position.x+=l,position.x<0||plot.num_cols-1<position.x?(constants.KillAutoplay(),control.lockPosition(s,i)):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()):(position.y+=l,position.y<0||plot.num_rows-1<position.y?(constants.KillAutoplay(),control.lockPosition(s,i)):position.y==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay())}),constants.autoPlayRate)}else if([].concat(singleMaidr.type).includes("point")||[].concat(singleMaidr.type).includes("smooth")){o=t;let s=0,i=0;"point"==constants.chartType?s=plot.x.length-1:"smooth"==constants.chartType&&(s=plot.curvePoints.length-1);let l=1;"left"!=t&&"reverse-right"!=t||(l=-1),constants.autoplayId&&constants.KillAutoplay(),constants.isSmoothAutoplay&&audio.KillSmooth(),"reverse-left"!=t&&"reverse-right"!=t||(position.x=e,position.L1x=e),"point"==constants.chartType?constants.autoplayId=setInterval((function(){position.x+=l,position.x<0||position.x>plot.y.length-1?(constants.KillAutoplay(),control.lockPosition(s,i)):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()}),constants.autoPlayRate):"smooth"==constants.chartType&&(constants.autoplayId=setInterval((function(){positionL1.x+=l,positionL1.x<0||positionL1.x>plot.curvePoints.length-1?(constants.KillAutoplay(),control.lockPosition(s,i)):positionL1.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()}),constants.autoPlayRate))}else if([].concat(singleMaidr.type).includes("hist")){o=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),control.lockPosition()):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()}),constants.autoPlayRate)}else if([].concat(singleMaidr.type).includes("stacked_bar")||[].concat(singleMaidr.type).includes("stacked_normalized_bar")||[].concat(singleMaidr.type).includes("dodged_bar")){o=t;let s=1;"left"!=t&&"down"!=t&&"reverse-right"!=t&&"reverse-up"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-left"==t||"reverse-right"==t?position.x=e:"reverse-up"!=t&&"reverse-down"!=t||(position.y=e),constants.autoplayId=setInterval((function(){"left"==t||"right"==t||"reverse-left"==t||"reverse-right"==t?(position.x+=s,position.x<0||plot.plotData.length-1<position.x?(constants.KillAutoplay(),control.lockPosition()):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()):(position.y+=s,position.y<0||plot.plotData[0].length-1<position.y?(constants.KillAutoplay(),control.lockPosition()):position.y==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay())}),constants.autoPlayRate)}else if([].concat(singleMaidr.type).includes("line")){o=t;let s=1;"left"!=t&&"reverse-right"!=t||(s=-1),null!=constants.autoplayId&&constants.KillAutoplay(),"reverse-right"!=t&&"reverse-left"!=t||(position.x=e),constants.autoplayId=setInterval((function(){position.x+=s,position.x<0||plot.pointValuesY.length-1<position.x?(constants.KillAutoplay(),control.lockPosition()):position.x==n?(constants.KillAutoplay(),control.UpdateAllAutoPlay()):control.UpdateAllAutoPlay()}),constants.autoPlayRate)}}PlayLine(t){let e=[],n=[],o=audio.SlideBetween(positionL1.x,0,plot.curvePoints.length-1,-1,1),s=positionL1.x<0?0:positionL1.x,i=0;if("right"==t){for(let t=s;t<plot.curvePoints.length;t++)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[o,1],i=Math.abs(plot.curvePoints.length-s)/plot.curvePoints.length*3}else if("left"==t){for(let t=s;t>=0;t--)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[o,-1],i=Math.abs(s)/plot.curvePoints.length*3}else if("reverse-right"==t){for(let t=plot.curvePoints.length-1;t>=s;t--)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[1,o],i=Math.abs(plot.curvePoints.length-s)/plot.curvePoints.length*3}else if("reverse-left"==t){for(let t=0;t<=s;t++)e.push(audio.SlideBetween(plot.curvePoints[t],plot.curveMinY,plot.curveMaxY,constants.MIN_FREQUENCY,constants.MAX_FREQUENCY));n=[-1,o],i=Math.abs(s)/plot.curvePoints.length*3}constants.isSmoothAutoplay&&audio.KillSmooth(),audio.playSmooth(e,i,n,constants.vol,"sine")}GetNextPrevFocusable(){let t='a[href], button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';constants.focusables=Array.from(document.querySelectorAll(t));let e=constants.focusables.indexOf(constants.chart),n=constants.main_container.querySelectorAll(t);for(let t=0;t<n.length;t++){let o=constants.focusables.indexOf(n[t]);o>-1&&constants.focusables.splice(o,1),e>o&&e--}}isUndefinedOrNull(t){try{return null==t}catch{return!0}}}function InitMaidr(t){if("undefined"!=typeof constants){window.singleMaidr=t,constants.chartId=singleMaidr.id,Array.isArray(singleMaidr.type)?constants.chartType=singleMaidr.type[0]:constants.chartType=singleMaidr.type,DestroyChartComponents(),CreateChartComponents(singleMaidr),InitTracker(),window.menu=new Menu,window.chatLLM=new ChatLLM,window.control=new Control,window.review=new Review,window.display=new Display,window.audio=new Audio;let e=[constants.chart,constants.brailleInput,constants.review];for(let t=0;t<e.length;t++)constants.events.push([e[t],"blur",ShouldWeDestroyMaidr]);if(constants.events.push([document,"keydown",KillAutoplayEvent]),this.SetEvents(),constants.chart.setAttribute("role","img"),"name"in singleMaidr)constants.chart.setAttribute("aria-label",announceText),constants.chart.setAttribute("title",announceText);else if("title"in singleMaidr||"labels"in singleMaidr&&"title"in singleMaidr.labels){let t="title"in singleMaidr?singleMaidr.title:singleMaidr.labels.title,e="This is a multi-layered plot. Use PageUp and PageDown to switch between layers.",n=`${Array.isArray(singleMaidr.type)?singleMaidr.type.slice(0,-1).join(", ")+" and "+singleMaidr.type.slice(-1):singleMaidr.type} plot of ${t}: Click to activate. Use Arrows to navigate data points. ${Array.isArray(singleMaidr.type)&&singleMaidr.type.length>1?e:" "}Toggle B for Braille, T for Text, S for Sonification, and R for Review mode. Use H for Help.`;constants.chart.setAttribute("aria-label",n),constants.chart.setAttribute("title",n)}}}function ShouldWeInitMaidr(t){"undefined"==typeof singleMaidr?InitMaidr(t):singleMaidr?t.id!==singleMaidr.id&&(DestroyMaidr(),InitMaidr(t)):InitMaidr(t)}function ShouldWeDestroyMaidr(t){setTimeout((()=>{0==constants.tabMovement?constants.tabMovement=null:(1!=constants.tabMovement&&-1!=constants.tabMovement||FocusBeforeOrAfter(),DestroyMaidr())}),0)}function FocusBeforeOrAfter(){if(1==constants.tabMovement){let t=document.createElement("div");t.setAttribute("tabindex","0"),constants.main_container.after(t),t.focus(),t.remove()}else if(-1==constants.tabMovement){let t=document.createElement("div");t.setAttribute("tabindex","0"),constants.main_container.before(t),t.focus(),t.remove()}}function DestroyMaidr(){"bar"!=constants.chartType&&"hist"!=constants.chartType||("function"==typeof plot.DeselectAll&&plot.DeselectAll(),"function"==typeof plot.UnSelectPrevious&&plot.UnSelectPrevious());for(let t=0;t<constants.events.length;t++)if(Array.isArray(constants.events[t][0]))for(let e=0;e<constants.events[t][0].length;e++)constants.events[t][0][e].removeEventListener(constants.events[t][1],constants.events[t][2]);else constants.events[t][0].removeEventListener(constants.events[t][1],constants.events[t][2]);for(let t=0;t<constants.postLoadEvents.length;t++)if(Array.isArray(constants.postLoadEvents[t][0]))for(let e=0;e<constants.postLoadEvents[t][0].length;e++)constants.postLoadEvents[t][0][e].removeEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);else constants.postLoadEvents[t][0].removeEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);constants.events=[],constants.postLoadEvents=[],constants.chartId=null,constants.chartType=null,constants.tabMovement=null,DestroyChartComponents(),window.review=null,window.display=null,window.control=null,window.plot=null,window.audio=null,window.singleMaidr=null}function KillAutoplayEvent(t){(constants.isMac?"Meta"==t.key||"ContextMenu"==t.key:"Control"==t.key)&&constants.KillAutoplay()}function SetEvents(){for(let t=0;t<constants.events.length;t++)if(Array.isArray(constants.events[t][0]))for(let e=0;e<constants.events[t][0].length;e++)constants.events[t][0][e]?.addEventListener(constants.events[t][1],constants.events[t][2]);else constants.events[t][0]?.addEventListener(constants.events[t][1],constants.events[t][2]);setTimeout((function(){for(let t=0;t<constants.postLoadEvents.length;t++)if(Array.isArray(constants.postLoadEvents[t][0]))for(let e=0;e<constants.postLoadEvents[t][0].length;e++)constants.postLoadEvents[t][0][e].addEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2]);else constants.postLoadEvents[t][0].addEventListener(constants.postLoadEvents[t][1],constants.postLoadEvents[t][2])}),100)}function CreateChartComponents(t,e=!1){let n=document.getElementById(t.id),o=document.createElement("div");o.id=constants.main_container_id;let s=document.createElement("div");s.id=constants.chart_container_id,n.parentNode.replaceChild(o,n),o.appendChild(n),n.parentNode.replaceChild(s,n),s.appendChild(n),e||n.focus(),constants.chart=n,constants.chart_container=s,constants.main_container=o,e||(constants.chart_container.insertAdjacentHTML("beforebegin",'<div class="hidden" id="'+constants.braille_container_id+'">\n<input id="'+constants.braille_input_id+'" class="braille-input" type="text" size="'+constants.brailleDisplayLength+'" aria-brailleroledescription="" autocomplete="off" />\n</div>\n'),constants.chart_container.insertAdjacentHTML("afterend",'<br>\n<div id="'+constants.info_id+'" aria-live="assertive" aria-atomic="true">\n<p id="x"></p>\n<p id="y"></p>\n</div>\n'),document.getElementById(constants.info_id).insertAdjacentHTML("afterend",'<div id="announcements" aria-live="assertive" aria-atomic="true" class="mb-3"></div>\n'),document.getElementById(constants.info_id).insertAdjacentHTML("beforebegin",'<div id="'+constants.review_id_container+'" class="hidden sr-only sr-only-focusable"><input id="'+constants.review_id+'" type="text" size="50" autocomplete="off" /></div>'),constants.chart_container.setAttribute("role","application"),constants.brailleContainer=document.getElementById(constants.braille_container_id),constants.brailleInput=document.getElementById(constants.braille_input_id),constants.infoDiv=document.getElementById(constants.info_id),constants.announceContainer=document.getElementById(constants.announcement_container_id),constants.nonMenuFocus=constants.chart,constants.endChime=document.getElementById(constants.end_chime_id),constants.review_container=document.querySelector("#"+constants.review_id_container),constants.review=document.querySelector("#"+constants.review_id));let i="";if(document.getElementById(t.id).setAttribute("role","img"),"name"in t)i=t.name;else if("title"in t||"labels"in t&&"title"in t.labels){let e="title"in t?t.title:t.labels.title,n="This is a multi-layered plot. Use PageUp and PageDown to switch between layers.";i=`${Array.isArray(t.type)?t.type.slice(0,-1).join(", ")+" and "+t.type.slice(-1):t.type} plot of ${e}: Click to activate. Use Arrows to navigate data points. ${Array.isArray(t.type)&&t.type.length>1?n:" "}Toggle B for Braille, T for Text, S for Sonification, and R for Review mode. Use H for Help.`}i.length>0&&(document.getElementById(t.id).setAttribute("aria-label",i),document.getElementById(t.id).setAttribute("title",i))}function InitTracker(){constants.canTrack&&(window.tracker=new Tracker,document.getElementById("download_data_trigger")&&document.getElementById("download_data_trigger").addEventListener("click",(function(t){tracker.DownloadTrackerData()})),document.addEventListener("keydown",(function(t){("F5"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey)||"R"==t.key&&(constants.isMac?t.metaKey:t.ctrlKey))&&(t.preventDefault(),tracker.Delete(),location.reload(!0)),"F10"==t.key?tracker.DownloadTrackerData():plot&&tracker.LogEvent(t)})))}function DestroyChartComponents(){null!=constants.chart_container&&(null!=constants.chart&&null!=constants.chart_container.parentNode&&constants.chart_container.parentNode.replaceChild(constants.chart,constants.chart_container),constants.chart_container.remove()),null!=constants.brailleContainer&&constants.brailleContainer.remove(),null!=constants.infoDiv&&constants.infoDiv.remove(),null!=constants.announceContainer&&constants.announceContainer.remove(),null!=constants.endChime&&constants.endChime.remove(),null!=constants.review_container&&constants.review_container.remove(),"undefined"!=typeof menu&&null!==menu&&menu.Destroy(),"undefined"!=typeof description&&null!==description&&description.Destroy(),"undefined"!=typeof chatLLM&&null!==chatLLM&&chatLLM.Destroy();const t=document.querySelector("svg#scatter"),e=document.querySelector("svg#line"),n=document.querySelector("svg#heat");if(t)constants.KillAutoplay(),t.querySelectorAll(".highlight_point").forEach((t=>{t.remove()}));else if(e||n){const t=e?e.querySelector("#highlight_point"):n.querySelector("#highlight_rect");t&&(constants.KillAutoplay(),t.remove())}constants.chart=null,constants.chart_container=null,constants.brailleContainer=null,constants.brailleInput=null,constants.infoDiv=null,constants.announceContainer=null,constants.endChime=null,constants.review_container=null,menu=null,description=null}document.addEventListener("DOMContentLoaded",(function(t){window.constants=new Constants,window.resources=new Resources,window.logError=new LogError;let e,n=[];"undefined"!=typeof maidr&&(Array.isArray(maidr)?n=maidr:n.push(maidr)),DestroyMaidr(),window.maidrIds=[];for(let t=0;t<n.length;t++){let o=n[t].id;maidrIds.push(o),!e&&n[t]&&(e=n[t]);let s=document.getElementById(o);s&&(s.setAttribute("tabindex","0"),s.addEventListener("focus",(function(e){ShouldWeInitMaidr(n[t])})))}CreateChartComponents(e,!0)}));
\ No newline at end of file
diff --git a/docs/AdvancedUserSettings.html b/docs/AdvancedUserSettings.html
index 9b94dc8f..1c2a723f 100644
--- a/docs/AdvancedUserSettings.html
+++ b/docs/AdvancedUserSettings.html
@@ -1322,7 +1322,7 @@ <h5>Type:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Audio.html b/docs/Audio.html
index 5de64179..6ce5738d 100644
--- a/docs/Audio.html
+++ b/docs/Audio.html
@@ -1396,7 +1396,7 @@ <h4 class="name" id="playTone"><span class="type-signature"></span>playTone<span
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/AudioProperties.html b/docs/AudioProperties.html
index c63c94e9..fc86780e 100644
--- a/docs/AudioProperties.html
+++ b/docs/AudioProperties.html
@@ -924,7 +924,7 @@ <h5>Type:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/BTSModes.html b/docs/BTSModes.html
index e33d8aa5..bae96b02 100644
--- a/docs/BTSModes.html
+++ b/docs/BTSModes.html
@@ -471,7 +471,7 @@ <h5>Type:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/BarChart.html b/docs/BarChart.html
index 185c9c56..83f9c6d6 100644
--- a/docs/BarChart.html
+++ b/docs/BarChart.html
@@ -1097,7 +1097,7 @@ <h4 class="name" id="UnSelectPrevious"><span class="type-signature"></span>UnSel
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/BasicChartProperties.html b/docs/BasicChartProperties.html
index 31860456..90fa7280 100644
--- a/docs/BasicChartProperties.html
+++ b/docs/BasicChartProperties.html
@@ -687,7 +687,7 @@ <h5>Type:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/BoxPlot.html b/docs/BoxPlot.html
index 87cab319..6e2f1004 100644
--- a/docs/BoxPlot.html
+++ b/docs/BoxPlot.html
@@ -1329,7 +1329,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/BoxplotRect.html b/docs/BoxplotRect.html
index 814b21d3..6981e24e 100644
--- a/docs/BoxplotRect.html
+++ b/docs/BoxplotRect.html
@@ -408,7 +408,7 @@ <h4 class="name" id="UpdateRect"><span class="type-signature"></span>UpdateRect<
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/ChatLLM.html b/docs/ChatLLM.html
index 45610f8e..187a71eb 100644
--- a/docs/ChatLLM.html
+++ b/docs/ChatLLM.html
@@ -99,7 +99,7 @@ <h4 class="name" id="ChatLLM"><span class="type-signature"></span>new ChatLLM<sp
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1732">line 1732</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1734">line 1734</a>
     </li></ul></dd>
     
 
@@ -200,7 +200,7 @@ <h4 class="name" id="ConvertSVGtoJPG"><span class="type-signature">(async) </spa
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2803">line 2803</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2805">line 2805</a>
     </li></ul></dd>
     
 
@@ -288,7 +288,7 @@ <h4 class="name" id="CopyChatHistory"><span class="type-signature"></span>CopyCh
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1941">line 1941</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1943">line 1943</a>
     </li></ul></dd>
     
 
@@ -427,7 +427,7 @@ <h4 class="name" id="CreateComponent"><span class="type-signature"></span>Create
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1756">line 1756</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1758">line 1758</a>
     </li></ul></dd>
     
 
@@ -512,7 +512,7 @@ <h4 class="name" id="GetDefaultPrompt"><span class="type-signature"></span>GetDe
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2850">line 2850</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2852">line 2852</a>
     </li></ul></dd>
     
 
@@ -595,7 +595,7 @@ <h4 class="name" id="KillAllWaitingSounds"><span class="type-signature"></span>K
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2186">line 2186</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2188">line 2188</a>
     </li></ul></dd>
     
 
@@ -678,7 +678,7 @@ <h4 class="name" id="ProcessLLMResponse"><span class="type-signature"></span>Pro
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2212">line 2212</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2214">line 2214</a>
     </li></ul></dd>
     
 
@@ -782,7 +782,7 @@ <h4 class="name" id="ResetLLM"><span class="type-signature"></span>ResetLLM<span
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2730">line 2730</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2732">line 2732</a>
     </li></ul></dd>
     
 
@@ -865,7 +865,7 @@ <h4 class="name" id="SetEvents"><span class="type-signature"></span>SetEvents<sp
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1805">line 1805</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1807">line 1807</a>
     </li></ul></dd>
     
 
@@ -969,7 +969,7 @@ <h4 class="name" id="Toggle"><span class="type-signature"></span>Toggle<span cla
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2767">line 2767</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2769">line 2769</a>
     </li></ul></dd>
     
 
@@ -1124,7 +1124,7 @@ <h4 class="name" id="fakeLLMResponseData"><span class="type-signature"></span>fa
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2271">line 2271</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2273">line 2273</a>
     </li></ul></dd>
     
 
@@ -1197,7 +1197,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Constants.html b/docs/Constants.html
index 30eac0d2..cd4da6f3 100644
--- a/docs/Constants.html
+++ b/docs/Constants.html
@@ -2213,7 +2213,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Control.html b/docs/Control.html
index 74d1adda..f5acb5e5 100644
--- a/docs/Control.html
+++ b/docs/Control.html
@@ -1035,7 +1035,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/DebugSettings.html b/docs/DebugSettings.html
index ce410cdb..3a1731c1 100644
--- a/docs/DebugSettings.html
+++ b/docs/DebugSettings.html
@@ -371,7 +371,7 @@ <h5>Type:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Description.html b/docs/Description.html
index 7cb904c3..7cd08970 100644
--- a/docs/Description.html
+++ b/docs/Description.html
@@ -99,7 +99,7 @@ <h4 class="name" id="Description"><span class="type-signature"></span>new Descri
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2880">line 2880</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2882">line 2882</a>
     </li></ul></dd>
     
 
@@ -200,7 +200,7 @@ <h4 class="name" id="CreateComponent"><span class="type-signature"></span>Create
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2895">line 2895</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2897">line 2897</a>
     </li></ul></dd>
     
 
@@ -283,7 +283,7 @@ <h4 class="name" id="Destroy"><span class="type-signature"></span>Destroy<span c
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2965">line 2965</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2967">line 2967</a>
     </li></ul></dd>
     
 
@@ -366,7 +366,7 @@ <h4 class="name" id="PopulateData"><span class="type-signature"></span>PopulateD
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3009">line 3009</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3011">line 3011</a>
     </li></ul></dd>
     
 
@@ -449,7 +449,7 @@ <h4 class="name" id="Toggle"><span class="type-signature"></span>Toggle<span cla
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2981">line 2981</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line2983">line 2983</a>
     </li></ul></dd>
     
 
@@ -573,7 +573,7 @@ <h5>Parameters:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Display.html b/docs/Display.html
index 34d739fa..805425ff 100644
--- a/docs/Display.html
+++ b/docs/Display.html
@@ -1575,7 +1575,7 @@ <h4 class="name" id="toggleTextMode"><span class="type-signature"></span>toggleT
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/HeatMap.html b/docs/HeatMap.html
index 4d9f3e57..e5a2bec1 100644
--- a/docs/HeatMap.html
+++ b/docs/HeatMap.html
@@ -1493,7 +1493,7 @@ <h4 class="name" id="updateConstants"><span class="type-signature"></span>update
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/HeatMapRect.html b/docs/HeatMapRect.html
index 8332cacd..141d2935 100644
--- a/docs/HeatMapRect.html
+++ b/docs/HeatMapRect.html
@@ -256,7 +256,7 @@ <h4 class="name" id="UpdateRect"><span class="type-signature"></span>UpdateRect<
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Helper.html b/docs/Helper.html
index 88f42696..dc305e7b 100644
--- a/docs/Helper.html
+++ b/docs/Helper.html
@@ -99,7 +99,7 @@ <h4 class="name" id="Helper"><span class="type-signature"></span>new Helper<span
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3155">line 3155</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3157">line 3157</a>
     </li></ul></dd>
     
 
@@ -200,7 +200,7 @@ <h4 class="name" id=".containsObject"><span class="type-signature">(static) </sp
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3162">line 3162</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3164">line 3164</a>
     </li></ul></dd>
     
 
@@ -355,7 +355,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Histogram.html b/docs/Histogram.html
index 40c5f652..453c0a91 100644
--- a/docs/Histogram.html
+++ b/docs/Histogram.html
@@ -422,7 +422,7 @@ <h4 class="name" id="SetMaxMin"><span class="type-signature"></span>SetMaxMin<sp
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/HtmlIds.html b/docs/HtmlIds.html
index fe27efb0..bfddef54 100644
--- a/docs/HtmlIds.html
+++ b/docs/HtmlIds.html
@@ -1156,7 +1156,7 @@ <h5>Type:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/LLMSettings.html b/docs/LLMSettings.html
index 7f0fbbd1..6d3e9724 100644
--- a/docs/LLMSettings.html
+++ b/docs/LLMSettings.html
@@ -1185,7 +1185,7 @@ <h5>Type:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Layer0Point.html b/docs/Layer0Point.html
index a0bf42a6..005eace6 100644
--- a/docs/Layer0Point.html
+++ b/docs/Layer0Point.html
@@ -547,7 +547,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Layer1Point.html b/docs/Layer1Point.html
index b581b3bb..aa7ac70c 100644
--- a/docs/Layer1Point.html
+++ b/docs/Layer1Point.html
@@ -547,7 +547,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/LinePlot.html b/docs/LinePlot.html
index c5fb37a4..ede2fd3b 100644
--- a/docs/LinePlot.html
+++ b/docs/LinePlot.html
@@ -725,7 +725,7 @@ <h4 class="name" id="UpdateConstants"><span class="type-signature"></span>Update
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/LogError.html b/docs/LogError.html
index 5e60f0ea..cc520ccf 100644
--- a/docs/LogError.html
+++ b/docs/LogError.html
@@ -99,7 +99,7 @@ <h4 class="name" id="LogError"><span class="type-signature"></span>new LogError<
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3573">line 3573</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3575">line 3575</a>
     </li></ul></dd>
     
 
@@ -200,7 +200,7 @@ <h4 class="name" id="LogAbsentElement"><span class="type-signature"></span>LogAb
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3580">line 3580</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3582">line 3582</a>
     </li></ul></dd>
     
 
@@ -335,7 +335,7 @@ <h4 class="name" id="LogCriticalElement"><span class="type-signature"></span>Log
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3588">line 3588</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3590">line 3590</a>
     </li></ul></dd>
     
 
@@ -470,7 +470,7 @@ <h4 class="name" id="LogDifferentLengths"><span class="type-signature"></span>Lo
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3597">line 3597</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3599">line 3599</a>
     </li></ul></dd>
     
 
@@ -631,7 +631,7 @@ <h4 class="name" id="LogNotArray"><span class="type-signature"></span>LogNotArra
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3625">line 3625</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3627">line 3627</a>
     </li></ul></dd>
     
 
@@ -766,7 +766,7 @@ <h4 class="name" id="LogTooManyElements"><span class="type-signature"></span>Log
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3611">line 3611</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3613">line 3613</a>
     </li></ul></dd>
     
 
@@ -896,7 +896,7 @@ <h5>Parameters:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Menu.html b/docs/Menu.html
index d26703db..06258f1a 100644
--- a/docs/Menu.html
+++ b/docs/Menu.html
@@ -305,7 +305,7 @@ <h4 class="name" id="Destroy"><span class="type-signature"></span>Destroy<span c
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1349">line 1349</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1347">line 1347</a>
     </li></ul></dd>
     
 
@@ -409,7 +409,7 @@ <h4 class="name" id="LoadDataFromLocalStorage"><span class="type-signature"></sp
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1714">line 1714</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1716">line 1716</a>
     </li></ul></dd>
     
 
@@ -492,7 +492,7 @@ <h4 class="name" id="NotifyOfLLMReset"><span class="type-signature"></span>Notif
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1628">line 1628</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1630">line 1630</a>
     </li></ul></dd>
     
 
@@ -596,7 +596,7 @@ <h4 class="name" id="PopulateData"><span class="type-signature"></span>PopulateD
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1401">line 1401</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1399">line 1399</a>
     </li></ul></dd>
     
 
@@ -700,7 +700,7 @@ <h4 class="name" id="SaveData"><span class="type-signature"></span>SaveData<span
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1476">line 1476</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1478">line 1478</a>
     </li></ul></dd>
     
 
@@ -804,7 +804,7 @@ <h4 class="name" id="SaveDataToLocalStorage"><span class="type-signature"></span
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1692">line 1692</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1694">line 1694</a>
     </li></ul></dd>
     
 
@@ -909,7 +909,7 @@ <h4 class="name" id="ShouldLLMReset"><span class="type-signature"></span>ShouldL
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1652">line 1652</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1654">line 1654</a>
     </li></ul></dd>
     
 
@@ -1017,7 +1017,7 @@ <h4 class="name" id="Toggle"><span class="type-signature"></span>Toggle<span cla
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1366">line 1366</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1364">line 1364</a>
     </li></ul></dd>
     
 
@@ -1193,7 +1193,7 @@ <h4 class="name" id="UpdateHtml"><span class="type-signature"></span>UpdateHtml<
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1596">line 1596</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line1598">line 1598</a>
     </li></ul></dd>
     
 
@@ -1266,7 +1266,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/PlatformControls.html b/docs/PlatformControls.html
index df7434e0..9c2830ea 100644
--- a/docs/PlatformControls.html
+++ b/docs/PlatformControls.html
@@ -516,7 +516,7 @@ <h5>Type:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Point.html b/docs/Point.html
index 41b33e27..b7e674e9 100644
--- a/docs/Point.html
+++ b/docs/Point.html
@@ -547,7 +547,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Position.html b/docs/Position.html
index a9404be2..23369f9d 100644
--- a/docs/Position.html
+++ b/docs/Position.html
@@ -99,7 +99,7 @@ <h4 class="name" id="Position"><span class="type-signature"></span>new Position<
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3143">line 3143</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3145">line 3145</a>
     </li></ul></dd>
     
 
@@ -165,7 +165,7 @@ <h4 class="name" id="Position"><span class="type-signature"></span>new Position<
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Resources.html b/docs/Resources.html
index c577bdf4..3a3fd6de 100644
--- a/docs/Resources.html
+++ b/docs/Resources.html
@@ -329,7 +329,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Review.html b/docs/Review.html
index 8d61419d..31f9b609 100644
--- a/docs/Review.html
+++ b/docs/Review.html
@@ -99,7 +99,7 @@ <h4 class="name" id="Review"><span class="type-signature"></span>new Review<span
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3540">line 3540</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3542">line 3542</a>
     </li></ul></dd>
     
 
@@ -200,7 +200,7 @@ <h4 class="name" id="ToggleReviewMode"><span class="type-signature"></span>Toggl
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3547">line 3547</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3549">line 3549</a>
     </li></ul></dd>
     
 
@@ -324,7 +324,7 @@ <h5>Parameters:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/ScatterPlot.html b/docs/ScatterPlot.html
index c9bf6b72..55371160 100644
--- a/docs/ScatterPlot.html
+++ b/docs/ScatterPlot.html
@@ -1427,7 +1427,7 @@ <h4 class="name" id="SetLineLayer"><span class="type-signature"></span>SetLineLa
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Segmented.html b/docs/Segmented.html
index bc90866b..3a0d4383 100644
--- a/docs/Segmented.html
+++ b/docs/Segmented.html
@@ -892,7 +892,7 @@ <h4 class="name" id="UnSelectPrevious"><span class="type-signature"></span>UnSel
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/Tracker.html b/docs/Tracker.html
index 6e768b61..f7e5ebda 100644
--- a/docs/Tracker.html
+++ b/docs/Tracker.html
@@ -99,7 +99,7 @@ <h4 class="name" id="Tracker"><span class="type-signature"></span>new Tracker<sp
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3174">line 3174</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3176">line 3176</a>
     </li></ul></dd>
     
 
@@ -200,7 +200,7 @@ <h4 class="name" id="DataSetup"><span class="type-signature"></span>DataSetup<sp
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3186">line 3186</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3188">line 3188</a>
     </li></ul></dd>
     
 
@@ -283,7 +283,7 @@ <h4 class="name" id="Delete"><span class="type-signature"></span>Delete<span cla
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3261">line 3261</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3263">line 3263</a>
     </li></ul></dd>
     
 
@@ -366,7 +366,7 @@ <h4 class="name" id="DownloadTrackerData"><span class="type-signature"></span>Do
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3207">line 3207</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3209">line 3209</a>
     </li></ul></dd>
     
 
@@ -449,7 +449,7 @@ <h4 class="name" id="GetTrackerData"><span class="type-signature"></span>GetTrac
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3253">line 3253</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3255">line 3255</a>
     </li></ul></dd>
     
 
@@ -557,7 +557,7 @@ <h4 class="name" id="LogEvent"><span class="type-signature"></span>LogEvent<span
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3291">line 3291</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3293">line 3293</a>
     </li></ul></dd>
     
 
@@ -692,7 +692,7 @@ <h4 class="name" id="SaveTrackerData"><span class="type-signature">(async) </spa
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3220">line 3220</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3222">line 3222</a>
     </li></ul></dd>
     
 
@@ -827,7 +827,7 @@ <h4 class="name" id="SetData"><span class="type-signature"></span>SetData<span c
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3503">line 3503</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3505">line 3505</a>
     </li></ul></dd>
     
 
@@ -987,7 +987,7 @@ <h4 class="name" id="isUndefinedOrNull"><span class="type-signature"></span>isUn
     
     <dt class="tag-source">Source:</dt>
     <dd class="tag-source"><ul class="dummy"><li>
-        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3527">line 3527</a>
+        <a href="constants.js.html">constants.js</a>, <a href="constants.js.html#line3529">line 3529</a>
     </li></ul></dd>
     
 
@@ -1116,7 +1116,7 @@ <h5>Returns:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/UserSettings.html b/docs/UserSettings.html
index dfe5854a..26fb6359 100644
--- a/docs/UserSettings.html
+++ b/docs/UserSettings.html
@@ -529,7 +529,7 @@ <h5>Type:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/audio.js.html b/docs/audio.js.html
index 7b2d32f4..8ce39523 100644
--- a/docs/audio.js.html
+++ b/docs/audio.js.html
@@ -639,7 +639,7 @@ <h1 class="page-title">audio.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/barplot.js.html b/docs/barplot.js.html
index d5a8e8e7..0510ec8e 100644
--- a/docs/barplot.js.html
+++ b/docs/barplot.js.html
@@ -371,7 +371,7 @@ <h1 class="page-title">barplot.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/boxplot.js.html b/docs/boxplot.js.html
index e468300f..ec3f79c2 100644
--- a/docs/boxplot.js.html
+++ b/docs/boxplot.js.html
@@ -794,7 +794,7 @@ <h1 class="page-title">boxplot.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/constants.js.html b/docs/constants.js.html
index 72f2821f..0dd03b83 100644
--- a/docs/constants.js.html
+++ b/docs/constants.js.html
@@ -1320,11 +1320,9 @@ <h1 class="page-title">constants.js</h1>
       'input',
       function (e) {
         if (e.target.value) {
-          document
-            .getElementById('delete_email_key')
-            .classList.remove('hidden');
+          document.getElementById('delete_email_key').style = '';
         } else {
-          document.getElementById('delete_email_key').classList.add('hidden');
+          document.getElementById('delete_email_key').style = 'display: none';
         }
       },
     ]);
@@ -1494,6 +1492,10 @@ <h1 class="page-title">constants.js</h1>
       .getElementById(`claude_auth_key_container`)
       .classList.add('hidden');
 
+    if (!constants.emailAuthKey) {
+      document.getElementById('delete_email_key').style = 'display: none';
+    }
+
     // skill level other
     if (constants.skillLevel == 'other') {
       document
@@ -1930,7 +1932,7 @@ <h1 class="page-title">constants.js</h1>
       function (e) {
         document.getElementById('email_auth_key').value = '';
         document.getElementById('email_auth_key').disabled = false;
-        document.getElementById('delete_email_key').classList.add('hidden');
+        document.getElementById('delete_email_key').style = 'display: none';
         constants.clientToken = '';
         document.getElementById('verify').classList.remove('hidden');
       },
@@ -3679,7 +3681,7 @@ <h1 class="page-title">constants.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/controls.js.html b/docs/controls.js.html
index d1d29726..5894b5e9 100644
--- a/docs/controls.js.html
+++ b/docs/controls.js.html
@@ -3109,7 +3109,7 @@ <h1 class="page-title">controls.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/display.js.html b/docs/display.js.html
index f076c225..183bde47 100644
--- a/docs/display.js.html
+++ b/docs/display.js.html
@@ -1256,7 +1256,7 @@ <h1 class="page-title">display.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/global.html b/docs/global.html
index fafa83a8..b676e4eb 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -1319,7 +1319,7 @@ <h5>Type:</h5>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/heatmap.js.html b/docs/heatmap.js.html
index 17eca300..ae8bb5ab 100644
--- a/docs/heatmap.js.html
+++ b/docs/heatmap.js.html
@@ -451,7 +451,7 @@ <h1 class="page-title">heatmap.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/histogram.js.html b/docs/histogram.js.html
index de544214..ac9eaeee 100644
--- a/docs/histogram.js.html
+++ b/docs/histogram.js.html
@@ -246,7 +246,7 @@ <h1 class="page-title">histogram.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/index.html b/docs/index.html
index 4a212d8c..b633c827 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -57,7 +57,7 @@
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/init.js.html b/docs/init.js.html
index 208e5342..f0419243 100644
--- a/docs/init.js.html
+++ b/docs/init.js.html
@@ -631,7 +631,7 @@ <h1 class="page-title">init.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/lineplot.js.html b/docs/lineplot.js.html
index 82648a48..a2bbb4d8 100644
--- a/docs/lineplot.js.html
+++ b/docs/lineplot.js.html
@@ -324,7 +324,7 @@ <h1 class="page-title">lineplot.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/scatterplot.js.html b/docs/scatterplot.js.html
index 8a90239d..c92d6e9e 100644
--- a/docs/scatterplot.js.html
+++ b/docs/scatterplot.js.html
@@ -889,7 +889,7 @@ <h1 class="page-title">scatterplot.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>
diff --git a/docs/segmented.js.html b/docs/segmented.js.html
index d02d351f..02e2f114 100644
--- a/docs/segmented.js.html
+++ b/docs/segmented.js.html
@@ -376,7 +376,7 @@ <h1 class="page-title">segmented.js</h1>
 <br class="clear">
 
 <footer>
-    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:25:00 GMT+0000 (Coordinated Universal Time) using the Minami theme.
+    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a> on Fri Nov 22 2024 15:57:10 GMT+0000 (Coordinated Universal Time) using the Minami theme.
 </footer>
 
 <script>prettyPrint();</script>