diff --git a/dist/maidr.js b/dist/maidr.js
index 2fab5dd1..376dcdfb 100644
--- a/dist/maidr.js
+++ b/dist/maidr.js
@@ -654,6 +654,13 @@ class Constants {
clientToken = null;
+ /**
+ * Mark and recall vars. Used to store the current mark and recall state of the chart.
+ * @type {Array}
+ * @default Array(10).fill(null)
+ */
+ mark = Array(10).fill(null);
+
/**
* Stops the autoplay if it is currently running.
*
@@ -2179,9 +2186,9 @@ class ChatLLM {
img = await constants.ConvertSVGtoJPG(singleMaidr.id, 'gemini');
}
if (constants.emailAuthKey) {
- chatLLM.GeminiPromptAPI(text, img);
+ chatLLM.GeminiPromptRemote(text, img);
} else {
- chatLLM.GeminiPrompt(text, img);
+ chatLLM.GeminiPromptLocal(text, img);
}
}
@@ -2304,10 +2311,10 @@ class ChatLLM {
if (model == 'openai') {
text = data.choices[0].message.content;
- let i = this.requestJson.messages.length;
- this.requestJson.messages[i] = {};
- this.requestJson.messages[i].role = 'assistant';
- this.requestJson.messages[i].content = text;
+ let i = this.requestJsonOpenAI.messages.length;
+ this.requestJsonOpenAI.messages[i] = {};
+ this.requestJsonOpenAI.messages[i].role = 'assistant';
+ this.requestJsonOpenAI.messages[i].content = text;
if (data.error) {
chatLLM.DisplayChatMessage(LLMName, 'Error processing request.', true);
@@ -2318,6 +2325,12 @@ class ChatLLM {
} else if (model == 'gemini') {
if (data.text()) {
text = data.text();
+ if (this.requestJsonGemini.contents.length > 2) {
+ let i = this.requestJsonGemini.contents.length;
+ this.requestJsonGemini.contents[i] = {};
+ this.requestJsonGemini.contents[i].role = 'model';
+ this.requestJsonGemini.contents[i].content = text;
+ }
chatLLM.DisplayChatMessage(LLMName, text);
} else {
if (!data.error) {
@@ -2360,7 +2373,7 @@ class ChatLLM {
*/
fakeLLMResponseData() {
let responseText = {};
- if (this.requestJson.messages.length > 2) {
+ if (this.requestJsonOpenAI.messages.length > 2) {
// subsequent responses
responseText = {
id: 'chatcmpl-8Y44iRCRrohYbAqm8rfBbJqTUADC7',
@@ -2567,32 +2580,32 @@ class ChatLLM {
let backupMessage =
'Describe ' + singleMaidr.type + ' charts to a blind person';
// headers and sys message
- if (!this.requestJson) {
- this.requestJson = {};
- //this.requestJson.model = 'gpt-4-vision-preview';
- this.requestJson.model = 'gpt-4o-2024-11-20';
- this.requestJson.max_tokens = constants.LLMmaxResponseTokens; // note: if this is too short (tested with less than 200), the response gets cut off
+ if (!this.requestJsonOpenAI) {
+ this.requestJsonOpenAI = {};
+ //this.requestJsonOpenAI.model = 'gpt-4-vision-preview';
+ this.requestJsonOpenAI.model = 'gpt-4o-2024-11-20';
+ this.requestJsonOpenAI.max_tokens = constants.LLMmaxResponseTokens; // note: if this is too short (tested with less than 200), the response gets cut off
// sys message
- this.requestJson.messages = [];
- this.requestJson.messages[0] = {};
- this.requestJson.messages[0].role = 'system';
- this.requestJson.messages[0].content = sysMessage;
+ this.requestJsonOpenAI.messages = [];
+ this.requestJsonOpenAI.messages[0] = {};
+ this.requestJsonOpenAI.messages[0].role = 'system';
+ this.requestJsonOpenAI.messages[0].content = sysMessage;
if (constants.LLMPreferences) {
- this.requestJson.messages[1] = {};
- this.requestJson.messages[1].role = 'system';
- this.requestJson.messages[1].content = constants.LLMPreferences;
+ this.requestJsonOpenAI.messages[1] = {};
+ this.requestJsonOpenAI.messages[1].role = 'system';
+ this.requestJsonOpenAI.messages[1].content = constants.LLMPreferences;
}
}
// user message
// if we have an image (first time only), send the image and the text, otherwise just the text
- let i = this.requestJson.messages.length;
- this.requestJson.messages[i] = {};
- this.requestJson.messages[i].role = 'user';
+ let i = this.requestJsonOpenAI.messages.length;
+ this.requestJsonOpenAI.messages[i] = {};
+ this.requestJsonOpenAI.messages[i].role = 'user';
if (img) {
// first message, include the img
- this.requestJson.messages[i].content = [
+ this.requestJsonOpenAI.messages[i].content = [
{
type: 'text',
text: text,
@@ -2604,10 +2617,10 @@ class ChatLLM {
];
} else {
// just the text
- this.requestJson.messages[i].content = text;
+ this.requestJsonOpenAI.messages[i].content = text;
}
- return this.requestJson;
+ return this.requestJsonOpenAI;
}
GeminiJson(text, img = null) {
@@ -2672,7 +2685,7 @@ class ChatLLM {
return payload;
}
- async GeminiPromptAPI(text, imgBase64 = null) {
+ async GeminiPromptRemote(text, imgBase64 = null) {
let url = constants.baseURL + 'gemini' + constants.code;
// Create the prompt
@@ -2689,7 +2702,20 @@ class ChatLLM {
}
constants.LLMImage = imgBase64;
- let requestJson = chatLLM.GeminiJson(prompt, imgBase64);
+ if (!this.requestJsonGemini) {
+ // this is our first message, do the full construction
+ this.requestJsonGemini = chatLLM.GeminiJson(prompt, imgBase64);
+ } else {
+ // subsequent messages, just add the new user message
+ let i = this.requestJsonGemini.contents.length;
+ this.requestJsonGemini.contents[i] = {};
+ this.requestJsonGemini.contents[i].role = 'user';
+ this.requestJsonGemini.contents[i].parts = [
+ {
+ text: text,
+ },
+ ];
+ }
const response = await fetch(url, {
method: 'POST',
@@ -2697,7 +2723,7 @@ class ChatLLM {
'Content-Type': 'application/json',
Authentication: constants.emailAuthKey + ' ' + constants.clientToken,
},
- body: JSON.stringify(requestJson),
+ body: JSON.stringify(this.requestJsonGemini),
});
if (response.ok) {
const responseJson = await response.json();
@@ -2713,7 +2739,7 @@ class ChatLLM {
}
}
- async GeminiPrompt(text, imgBase64 = null) {
+ async GeminiPromptLocal(text, imgBase64 = null) {
// https://ai.google.dev/docs/gemini_api_overview#node.js
try {
// Save the image for next time
@@ -2735,21 +2761,24 @@ class ChatLLM {
}); // old model was 'gemini-pro-vision'
// Create the prompt
- let prompt = constants.LLMSystemMessage;
- if (constants.LLMPreferences) {
- prompt += constants.LLMPreferences;
+ if (!this.requestJsonGemini) {
+ // this is our first message, do the full construction
+ this.requestJsonGemini = chatLLM.GeminiJson(prompt, imgBase64);
+ } else {
+ // subsequent messages, just add the new user message
+ let i = this.requestJsonGemini.contents.length;
+ this.requestJsonGemini.contents[i] = {};
+ this.requestJsonGemini.contents[i].role = 'user';
+ this.requestJsonGemini.contents[i].parts = [
+ {
+ text: text,
+ },
+ ];
}
- prompt += '\n\n' + text; // Use the text parameter as the prompt
- const image = {
- inlineData: {
- data: imgBase64, // Use the base64 image string
- mimeType: 'image/png', // Or the appropriate mime type of your image
- },
- };
// Generate the content
//console.log('LLM request: ', prompt, image);
- const result = await model.generateContent([prompt, image]);
+ const result = await model.generateContent(this.requestJsonGemini);
//console.log(result.response.text());
// Process the response
@@ -2757,7 +2786,7 @@ class ChatLLM {
} catch (error) {
chatLLM.WaitingSound(false);
chatLLM.DisplayChatMessage('Gemini', 'Error processing request.', true);
- console.error('Error in GeminiPrompt:', error);
+ console.error('Error in GeminiPromptLocal:', error);
throw error; // Rethrow the error for further handling if necessary
}
}
@@ -2822,7 +2851,7 @@ class ChatLLM {
document.getElementById('chatLLM_chat_history').innerHTML = '';
// reset the data
- this.requestJson = null;
+ this.requestJsonOpenAI = null;
this.firstTime = true;
// and start over, if enabled, or window is open
@@ -9085,8 +9114,10 @@ class Control {
* @returns {void}
*/
async SetKeyControls() {
+ // home / end: first / last element
+ // not available in review mode
constants.events.push([
- document,
+ [constants.chart, constants.brailleInput],
'keydown',
function (e) {
// ctrl/cmd: stop autoplay
@@ -9134,6 +9165,44 @@ class Control {
},
]);
+ // mark and recall
+ // mark with M + # (0-9), recall with m + # (0-9)
+ // available in chart and braille, not review
+ let lastKeytime = 0;
+ let lastKey = null;
+ constants.events.push([
+ [constants.chart, constants.brailleInput],
+ 'keydown',
+ function (e) {
+ // setup
+ const now = new Date().getTime();
+ const key = e.key;
+
+ // check for keypress within threshold
+ if (now - lastKeytime < constants.keypressInterval) {
+ // mark with M
+ if (lastKey == 'M' && /[0-9]/.test(key)) {
+ const markIndex = parseInt(key, 10);
+ constants.mark[markIndex] = JSON.parse(JSON.stringify(position)); // deep copy
+ display.announceText('Marked position ' + markIndex);
+ }
+
+ // recall with m
+ if (lastKey == 'm' && /[0-9]/.test(key)) {
+ const recallIndex = parseInt(key, 10);
+ if (constants.mark[recallIndex]) {
+ position = constants.mark[recallIndex];
+ control.UpdateAll();
+ }
+ }
+ }
+
+ // update last key and time
+ lastKey = key;
+ lastKeytime = now;
+ },
+ ]);
+
// Init a few things
let lastPlayed = '';
if ([].concat(singleMaidr.type).includes('bar')) {
diff --git a/dist/maidr.min.js b/dist/maidr.min.js
index 2c34bd58..e2f7a413 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[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{var s=document.createElement("canvas"),i=s.getContext("2d"),l=(new XMLSerializer).serializeToString(n);l.startsWith("
'),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\n \n
\n \n
\n
\n
\n
\n
Copy all to clipboard
\n
\n
\n
\n
\n
What is the title?
\n
What are the high and low values?
\n
What is the general shape of the chart?
\n
\n
\n
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.
\n
For the visualization I shared, please provide the following (where applicable): mean, standard deviation, extreme, correlations, relational comparisons like greater than OR lesser than.
\n
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?
\n
Provide context to help explain the data depicted in this visualization based on domain-specific insight.
\n
\n
Submit
\n
\n
\n \n
\n
\n \n
\n `;document.querySelector("body").insertAdjacentHTML("beforeend",t)}SetEvents(){let t=document.querySelectorAll("#close_chatLLM, #chatLLM .close");for(let e=0;e .chatLLM_message_other:last-of-type");e&&(n=e.innerHTML,o="Copied.")}else"A"==t.key&&(t.ctrlKey||t.metaKey||t.altKey)&&t.shiftKey&&(t.preventDefault(),n=document.getElementById("chatLLM_chat_history").innerHTML,o="Copied All.");if(""!=n){let t=document.createElement("div");t.innerHTML=n,t.querySelectorAll(".chatLLM_message_copy").forEach((t=>t.remove()));let s=this.htmlToMarkdown(t);if(s=s.replace(/\n{3,}/g,"\n\n"),""!=o&&display&&display.announceText(o),e)try{navigator.clipboard.writeText(s)}catch(t){console.error("Failed to copy: ",t)}return s}}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 constants.ConvertSVGtoJPG(singleMaidr.id,"openai")),constants.emailAuthKey?chatLLM.OpenAIPromptAPI(t,n):chatLLM.OpenAIPrompt(t,n)),"gemini"in constants.LLMModels&&(e&&(n=await constants.ConvertSVGtoJPG(singleMaidr.id,"gemini")),constants.emailAuthKey?chatLLM.GeminiPromptAPI(t,n):chatLLM.GeminiPrompt(t,n)),"claude"in constants.LLMModels&&(e&&(n=await constants.ConvertSVGtoJPG(singleMaidr.id,"claude")),constants.emailAuthKey?chatLLM.ClaudePromptAPI(t,n):chatLLM.ClaudePrompt(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++,constants.LLMClaudeMulti&&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(void 0,!1),e={};e.chatHistory=t,constants.emailAuthKey&&(e.username=constants.emailAuthKey),tracker.SetData("ChatHistory",e)}}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-2.0-flash-exp"});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 \n
${resources.GetString("multi")} Responses \n \n `;this.RenderChatMessage(t),this.firstMulti=!1}o="h4"}let s=`\n `;e!=resources.GetString("processing")&&(s+=`<${o} class="chatLLM_message_user">${t}${o}>`),s+=`
${e}
\n
\n `,"User"!=t&&e!=resources.GetString("processing")&&(s+='\n Copy
\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)}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 \n
\n
\n \n
\n
\n content here\n
\n
\n
\n
\n \n
\n
\n
\n
\n\n ');let t=document.querySelectorAll("#close_desc, #description .close");for(let e=0;eType: ${e}`),null!=plot.title&&(t+=`Title: ${plot.title}
`),null!=plot.subtitle&&(t+=`Subtitle: ${plot.subtitle}
`),null!=plot.caption&&(t+=`Caption: ${plot.caption}
`);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+="",null!=o||null!=i){if(n+="",null!=o&&(n+="",null!=s&&(n+=" "),n+=`${o} `,n+=" "),null!=i){n+="",null!=s&&(n+=" ");for(let t=0;t${i[t]}`;n+=" "}n+=" "}if(c>0){n+="";for(let t=0;t",null!=s&&0==t&&(n+=`${s} `);for(let e=0;e${l[t][e]}`;n+=""}n+=" "}n+="
"}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;n0&&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.fixAudioContext()}fixAudioContext(){this.audioContext?"suspended"===this.audioContext.state&&this.audioContext.resume().then((()=>{console.log("AudioContext resumed")})):(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('Text mode: '+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"))),"off"!=constants.sonifMode&&audio.fixAudioContext()}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.y0&&(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+=""+plot.columnLabels[position.x]+" "+plot.plotData[position.x]+"
\n",e=""+e+"
\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+=""+plot.x_labels[position.x]+", "+plot.data[position.y][position.x]+"
\n":n+=""+plot.y_labels[position.y]+", "+plot.data[position.y][position.x]+"
\n",e=""+e+"
\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=""+e+"
\n",n=""+n+"
\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+=""+plot.x[position.x]+", ["+plot.y[position.x].join(", ")+"]
\n"):"smooth"==constants.chartType&&(e+=plot.x_group_label+" "+plot.curveX[positionL1.x]+", "+plot.y_group_label+" "+plot.curvePoints[positionL1.x],n+=""+plot.curvePoints[positionL1.x]+"
\n"),e="
"+e+"
\n"):"hist"==constants.chartType?(n=""+plot.plotData[position.x].x+", "+plot.plotData[position.x].y+"
\n",e="",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&&(e+=plot.plotLegend.y+" is "),e+=plot.pointValuesY[position.x],n+="
"+plot.pointValuesX[position.x]+", "+plot.pointValuesY[position.x]+"
\n",e=""+e+"
\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+=""+plot.level[position.x]+" is "+plot.plotData[position.x][position.y]+"
\n":n+=""+plot.fill[position.y]+" is "+plot.plotData[position.x][position.y]+"
\n",e=""+e+"
\n");"verbose"==constants.textMode?t=e:"terse"==constants.textMode&&(t=n),constants.verboseText=e,t==constants.infoDiv.innerHTML&&(constants.infoDiv.textContent.endsWith(".")?t.endsWith(".")&&(t=t.replace(".","")):t=t.replace("",".")),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;en&&(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-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;t0||"lower_outlier"==l[t].type||"upper_outlier"==l[t].type)?(l[t].numChars=1,h++):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,h++);r>-1&&d>-1&&l[r].length!=l[d].length&&(l[r].length>l[d].length?(l[r].numChars++,h++):(l[d].numChars++,h++)),l[c].length!=l[p].length&&(l[c].length>l[p].length?(l[c].numChars++,h++):(l[p].numChars++,h++));let u=constants.brailleDisplayLength-h;u<5&&(u=5);let y=this.AllocateCharacters(l,u),g=l;for(let t=0;t5&&(console.log("plotData[i]",plot.plotData[e]),console.log("valData",i),console.log("lenData",l),console.log("brailleData",g));for(let e=0;e=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;et+e),0),l=e-i,a=t.length;for(;0!==l&&a>0;){for(let e=0;et+e),0),l=e-i,a--}if(0!==l){let e=[];for(let n=0;nn[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;tconstants.maxY&&(constants.maxY=this.plotData[t]),this.plotData[t]e)&&(e=s)}if(this.plotData[n].min&&((null==t||this.plotData[n].mine)&&(e=this.plotData[n].max)),this.plotData[n].q1&&((null==t||this.plotData[n].q1e)&&(e=this.plotData[n].q1)),this.plotData[n].q2&&((null==t||this.plotData[n].q2e)&&(e=this.plotData[n].q2)),this.plotData[n].q3&&((null==t||this.plotData[n].q3e)&&(e=this.plotData[n].q3)),this.plotData[n].max&&((null==t||this.plotData[n].maxe)&&(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||oe)&&(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.autoPlayRatel.bottom&&(o=!0),e.topl.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;to.bottom&&(o.bottom=n.bottom)):o=this.convertBoundingClientRectToObj(n):a?(n.ya.bottom&&(a.bottom=n.bottom)):a=this.convertBoundingClientRectToObj(n):n.x>l.x?o?(n.xo.right&&(o.right=n.right)):o=this.convertBoundingClientRectToObj(n):a?(n.xa.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;eplot.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;nMath.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.autoPlayRate0?(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-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-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;tMath.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-1?singleMaidr.data[o]:singleMaidr.data,"object"==s)for(let o=0;o-1?t=singleMaidr.data[o]:"smooth"==singleMaidr.type&&(t=singleMaidr.data),void 0!==t)if("object"==s)for(let o=0;o-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;tconstants.maxY&&(constants.maxY=this.plotData[t].y),this.plotData[t].yconstants.maxX&&(constants.maxX=this.plotData[t].xmax),this.plotData[t].xmine.ye.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.autoPlayRateplot.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;nconstants.maxY&&(constants.maxY=singleMaidr.data[t].y),singleMaidr.data[t].y0&&constants.events.push([constants.chart,["mousemove","touchmove"],function(e){if("bar"==constants.chartType||"hist"==constants.chartType){if(e.target.matches(singleMaidr.selector)){let n=Array.from(t).indexOf(e.target);n!=position.x&&(position.x=n,control.UpdateAll())}}else if("box"==constants.chartType){let t=1/0,n=-1,o=e.clientX,s=e.clientY,i=null,l=15;const a=constants.chart.getBoundingClientRect();for(let e=0;e=i.left&&o<=i.right&&s>=i.top&&s<=i.bottom&&(t=y,n=[e,c])}}t<1/0&&("horz"==constants.plotOrientation?position.x==n[0]&&position.y==n[1]||(position.x=n[1],position.y=n[0],control.UpdateAll()):position.x==n[0]&&position.y==n[1]||(position.x=n[0],position.y=n[1],control.UpdateAll()))}else if("heat"==constants.chartType){let n=Array.from(t).indexOf(e.target);-1!=n&&(position.x==Math.floor(n/plot.num_rows)&&position.y==plot.num_rows-n%plot.num_rows-1||(position.x=Math.floor(n/plot.num_rows),position.y=plot.num_rows-n%plot.num_rows-1,control.UpdateAll()))}else if("line"==constants.chartType){let t,n,o=constants.chart.getBoundingClientRect(),s=constants.chart.viewBox.baseVal.width/o.width,i=constants.chart.viewBox.baseVal.height/o.height,l=1/0,a=-1,r=(e.clientX-o.left)*s,c=(e.clientY-o.top)*i;for(let e=0;et){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;constants.lockSelection=!0;let e=constants.brailleInput.value.split("").reduce(((t,e,n)=>("⠳"===e&&t.push(n),t)),[]);console.log("seperatorPositions",e),console.log("pos",t),e.includes(t)&&t>0&&(t+=-1),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 n=!0;n&&control.UpdateAll(),n&&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;t0?("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;tn.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;tn.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;tt.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;tplot.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-10&&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-1plot.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=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-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;t1?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\n \n\n'),constants.chart_container.insertAdjacentHTML("afterend",' \n\n'),document.getElementById(constants.info_id).insertAdjacentHTML("afterend",'
\n'),document.getElementById(constants.info_id).insertAdjacentHTML("beforebegin",'
'),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;tthis.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[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{var s=document.createElement("canvas"),i=s.getContext("2d"),l=(new XMLSerializer).serializeToString(n);l.startsWith("