")}replaceSelection(textReplacement){this.editor.selection.setContent(textReplacement)}getDraftItemId(){return null!==this.editor?(0,_options.getDraftItemId)(this.editor):0}getComponent(){return this.component}getContextId(){return this.contextId}getUserId(){return this.userId}getModal(){return this.modal}},_exports.default}));
//# sourceMappingURL=editor_utils.min.js.map
\ No newline at end of file
diff --git a/amd/build/editor_utils.min.js.map b/amd/build/editor_utils.min.js.map
index 38b61cd..8296200 100644
--- a/amd/build/editor_utils.min.js.map
+++ b/amd/build/editor_utils.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"editor_utils.min.js","sources":["../src/editor_utils.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Editor instance specific utils.\n *\n * @module tiny_ai/editor_utils\n * @copyright 2024, ISB Bayern\n * @author Philipp Memmel\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport AiModal from 'tiny_ai/modal';\nimport ModalEvents from 'core/modal_events';\nimport {getDraftItemId as getDraftItemIdTinyCore} from 'editor_tiny/options';\nimport {getRenderer} from 'tiny_ai/utils';\n\nexport default class {\n\n uniqid = null;\n component = null;\n userId = null;\n contextId = null;\n modal = null;\n editor = null;\n\n constructor(uniqid, component, contextId, userId, editor = null) {\n this.uniqid = uniqid;\n this.component = component;\n this.editor = editor;\n this.contextId = contextId;\n this.userId = userId;\n }\n\n /**\n * Shows and handles the dialog.\n */\n async displayDialogue() {\n\n // We initially render the modal without content, because we need to rerender it anyway.\n this.modal = await AiModal.create({\n templateContext: {\n classes: 'tiny_ai-modal--dialog',\n headerclasses: 'tiny_ai-modal--header'\n }\n });\n this.modal.show();\n const renderer = getRenderer(this.uniqid);\n\n // Unfortunately, the modal will not execute any JS code in the template, so we need to rerender the modal as a whole again.\n await renderer.renderStart();\n this.modal.getRoot().on(ModalEvents.outsideClick, event => {\n event.preventDefault();\n });\n }\n\n\n insertAfterContent(textToInsert) {\n this.editor.setContent(this.editor.getContent() + '
' + textToInsert + '
');\n }\n\n /**\n * Replaces a selected text with the given replacement.\n *\n * In case nothing is selected, it will be inserted at the current caret position.\n *\n * @param {strings} textReplacement the text by which the current selection will be replaced or which will be inserted\n * at the caret (if no selection), can be HTML code\n */\n replaceSelection(textReplacement) {\n this.editor.selection.setContent(textReplacement);\n }\n\n getDraftItemId() {\n // By sending draft item id 0 we state that we do not have a draft item area yet.\n return this.editor !== null ? getDraftItemIdTinyCore(this.editor) : 0;\n }\n\n getComponent() {\n return this.component;\n }\n\n getContextId() {\n return this.contextId;\n }\n\n getUserId() {\n return this.userId;\n }\n\n getModal() {\n return this.modal;\n }\n\n}\n"],"names":["constructor","uniqid","component","contextId","userId","editor","modal","AiModal","create","templateContext","classes","headerclasses","show","renderer","this","renderStart","getRoot","on","ModalEvents","outsideClick","event","preventDefault","insertAfterContent","textToInsert","setContent","getContent","replaceSelection","textReplacement","selection","getDraftItemId","getComponent","getContextId","getUserId","getModal"],"mappings":"2mBAsCIA,YAAYC,OAAQC,UAAWC,UAAWC,YAAQC,8DAAS,mCAPlD,uCACG,oCACH,uCACG,mCACJ,oCACC,WAGAJ,OAASA,YACTC,UAAYA,eACZG,OAASA,YACTF,UAAYA,eACZC,OAASA,oCASTE,YAAcC,eAAQC,OAAO,CAC9BC,gBAAiB,CACbC,QAAS,wBACTC,cAAe,gCAGlBL,MAAMM,aACLC,UAAW,sBAAYC,KAAKb,cAG5BY,SAASE,mBACVT,MAAMU,UAAUC,GAAGC,sBAAYC,cAAcC,QAC9CA,MAAMC,oBAKdC,mBAAmBC,mBACVlB,OAAOmB,WAAWV,KAAKT,OAAOoB,aAAe,MAAQF,aAAe,QAW7EG,iBAAiBC,sBACRtB,OAAOuB,UAAUJ,WAAWG,iBAGrCE,wBAE2B,OAAhBf,KAAKT,QAAkB,2BAAuBS,KAAKT,QAAU,EAGxEyB,sBACWhB,KAAKZ,UAGhB6B,sBACWjB,KAAKX,UAGhB6B,mBACWlB,KAAKV,OAGhB6B,kBACWnB,KAAKR"}
\ No newline at end of file
+{"version":3,"file":"editor_utils.min.js","sources":["../src/editor_utils.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Editor instance specific utils.\n *\n * @module tiny_ai/editor_utils\n * @copyright 2024, ISB Bayern\n * @author Philipp Memmel\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport AiModal from 'tiny_ai/modal';\nimport ModalEvents from 'core/modal_events';\nimport {getDraftItemId as getDraftItemIdTinyCore} from 'editor_tiny/options';\nimport {getRenderer} from 'tiny_ai/utils';\n\nexport default class {\n\n uniqid = null;\n component = null;\n userId = null;\n contextId = null;\n modal = null;\n editor = null;\n\n constructor(uniqid, component, contextId, userId, editor = null) {\n this.uniqid = uniqid;\n this.component = component;\n this.editor = editor;\n this.contextId = contextId;\n this.userId = userId;\n }\n\n /**\n * Shows and handles the dialog.\n */\n async displayDialogue() {\n\n // We initially render the modal without content, because we need to rerender it anyway.\n this.modal = await AiModal.create({\n templateContext: {\n classes: 'tiny_ai-modal--dialog',\n headerclasses: 'tiny_ai-modal--header'\n },\n scrollable: false\n });\n this.modal.show();\n const renderer = getRenderer(this.uniqid);\n\n // Unfortunately, the modal will not execute any JS code in the template, so we need to rerender the modal as a whole again.\n await renderer.renderStart();\n this.modal.getRoot().on(ModalEvents.outsideClick, event => {\n event.preventDefault();\n });\n }\n\n\n insertAfterContent(textToInsert) {\n this.editor.setContent(this.editor.getContent() + '
' + textToInsert + '
');\n }\n\n /**\n * Replaces a selected text with the given replacement.\n *\n * In case nothing is selected, it will be inserted at the current caret position.\n *\n * @param {strings} textReplacement the text by which the current selection will be replaced or which will be inserted\n * at the caret (if no selection), can be HTML code\n */\n replaceSelection(textReplacement) {\n this.editor.selection.setContent(textReplacement);\n }\n\n getDraftItemId() {\n // By sending draft item id 0 we state that we do not have a draft item area yet.\n return this.editor !== null ? getDraftItemIdTinyCore(this.editor) : 0;\n }\n\n getComponent() {\n return this.component;\n }\n\n getContextId() {\n return this.contextId;\n }\n\n getUserId() {\n return this.userId;\n }\n\n getModal() {\n return this.modal;\n }\n\n}\n"],"names":["constructor","uniqid","component","contextId","userId","editor","modal","AiModal","create","templateContext","classes","headerclasses","scrollable","show","renderer","this","renderStart","getRoot","on","ModalEvents","outsideClick","event","preventDefault","insertAfterContent","textToInsert","setContent","getContent","replaceSelection","textReplacement","selection","getDraftItemId","getComponent","getContextId","getUserId","getModal"],"mappings":"2mBAsCIA,YAAYC,OAAQC,UAAWC,UAAWC,YAAQC,8DAAS,mCAPlD,uCACG,oCACH,uCACG,mCACJ,oCACC,WAGAJ,OAASA,YACTC,UAAYA,eACZG,OAASA,YACTF,UAAYA,eACZC,OAASA,oCASTE,YAAcC,eAAQC,OAAO,CAC9BC,gBAAiB,CACbC,QAAS,wBACTC,cAAe,yBAEnBC,YAAY,SAEXN,MAAMO,aACLC,UAAW,sBAAYC,KAAKd,cAG5Ba,SAASE,mBACVV,MAAMW,UAAUC,GAAGC,sBAAYC,cAAcC,QAC9CA,MAAMC,oBAKdC,mBAAmBC,mBACVnB,OAAOoB,WAAWV,KAAKV,OAAOqB,aAAe,MAAQF,aAAe,QAW7EG,iBAAiBC,sBACRvB,OAAOwB,UAAUJ,WAAWG,iBAGrCE,wBAE2B,OAAhBf,KAAKV,QAAkB,2BAAuBU,KAAKV,QAAU,EAGxE0B,sBACWhB,KAAKb,UAGhB8B,sBACWjB,KAAKZ,UAGhB8B,mBACWlB,KAAKX,OAGhB8B,kBACWnB,KAAKT"}
\ No newline at end of file
diff --git a/amd/build/renderer.min.js b/amd/build/renderer.min.js
index 57a0991..36760ef 100644
--- a/amd/build/renderer.min.js
+++ b/amd/build/renderer.min.js
@@ -1,3 +1,3 @@
-define("tiny_ai/renderer",["exports","local_ai_manager/infobox","local_ai_manager/userquota","tiny_ai/datahandler/basedata","core/templates","jquery","tiny_ai/utils","tiny_ai/constants"],(function(_exports,_infobox,_userquota,BasedataHandler,_templates,_jquery,_utils,_constants){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,BasedataHandler=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(BasedataHandler),_templates=_interopRequireDefault(_templates),_jquery=_interopRequireDefault(_jquery);return _exports.default=class{constructor(uniqid,mode){_defineProperty(this,"uniqid",null),_defineProperty(this,"mode",null),_defineProperty(this,"datamanager",null),this.uniqid=uniqid,this.mode=mode,this.datamanager=(0,_utils.getDatamanager)(uniqid)}async renderStart(){this.datamanager.reset();const templateContext=await(0,_utils.getStartHandler)(this.uniqid).getTemplateContext((0,_utils.getEditorUtils)(this.uniqid));await this.renderModalContent("moodle-modal-body-start","moodle-modal-footer-info",templateContext)}async renderSummarize(){const templateContext=(0,_utils.getSummarizeHandler)(this.uniqid).getTemplateContext("summarize");await this.renderModalContent("moodle-modal-body-preferences","moodle-modal-footer-generate",templateContext)}async renderTranslate(){const templateContext=(0,_utils.getTranslateHandler)(this.uniqid).getTemplateContext();await this.renderModalContent("moodle-modal-body-preferences","moodle-modal-footer-generate",templateContext)}async renderDescribe(){const templateContext=(0,_utils.getSummarizeHandler)(this.uniqid).getTemplateContext("describe");await this.renderModalContent("moodle-modal-body-preferences","moodle-modal-footer-generate",templateContext)}async renderTts(){const templateContext=await(0,_utils.getTtsHandler)(this.uniqid).getTemplateContext();await this.renderModalContent("moodle-modal-body-preferences","moodle-modal-footer-generate",templateContext)}async renderImggen(){const templateContext=await(0,_utils.getImggenHandler)(this.uniqid).getTemplateContext();await this.renderModalContent("moodle-modal-body-mediageneration","moodle-modal-footer-generate",templateContext)}async renderDescribeimg(){const templateContext=await(0,_utils.getIttHandler)(this.uniqid).getTemplateContext("describeimg");await this.renderModalContent("moodle-modal-body-itt","moodle-modal-footer-generate",templateContext)}async renderImagetotext(){const templateContext=await(0,_utils.getIttHandler)(this.uniqid).getTemplateContext("imagetotext");await this.renderModalContent("moodle-modal-body-itt","moodle-modal-footer-generate",templateContext)}async renderLoading(){const templateContext={};templateContext.modalHeadline=BasedataHandler.getTinyAiString("aigenerating"),await this.renderModalContent("moodle-modal-body-loading","moodle-modal-footer-empty",templateContext)}async renderSuggestion(){const templateContext={};templateContext.modalHeadline=BasedataHandler.getTinyAiString("aisuggestion"),templateContext.resultText=this.renderAiResultForEditor(),this.mode===_constants.constants.modalModes.editor?Object.assign(templateContext,BasedataHandler.getReplaceButtonsContext(this.datamanager.getSelectionText().length>0)):Object.assign(templateContext,BasedataHandler.getCopyAndDownloadButtonsContext()),await this.renderModalContent("moodle-modal-body-suggestion","moodle-modal-footer-replace",templateContext)}async renderOptimizePrompt(){const templateContext=(0,_utils.getOptimizeHandler)(this.uniqid).getTemplateContext();await this.renderModalContent("moodle-modal-body-optimize","moodle-modal-footer-generate",templateContext)}async renderDismiss(){const templateContext={modalHeadline:"",centeredHeadline:BasedataHandler.getTinyAiString("dismisssuggestion"),showIcon:!1,buttons:[{hasText:!0,buttonText:BasedataHandler.getTinyAiString("cancel"),iconLeft:!1,iconRight:!1,primary:!1,secondary:!0,tertiary:!1,action:"canceldismiss"},{hasText:!0,buttonText:BasedataHandler.getTinyAiString("dismiss"),iconLeft:!1,iconRight:!1,primary:!0,secondary:!1,tertiary:!1,action:"dismiss"}]};await this.renderModalContent("moodle-modal-body-dismiss","moodle-modal-footer-empty",templateContext)}renderAiResultForEditor(){let html;switch(this.datamanager.getCurrentTool()){case"tts":case"audiogen":{const audioPlayer=document.createElement("audio");audioPlayer.controls="controls",audioPlayer.src=this.datamanager.getCurrentAiResult(),audioPlayer.type="audio/mpeg",html=audioPlayer.outerHTML;break}case"imggen":{const img=document.createElement("img");img.src=this.datamanager.getCurrentAiResult(),img.classList.add("mw-100"),html=img.outerHTML;break}default:html=this.datamanager.getCurrentAiResult()}return html}async renderModalContent(bodyComponentTemplate,footerComponentTemplate,templateContext){templateContext.tinyinstanceuniqid=this.uniqid;const modal=(0,_utils.getEditorUtils)(this.uniqid).getModal();document.querySelectorAll("button[data-action]").forEach((button=>{(0,_jquery.default)(button).tooltip("hide")}));const result=await Promise.all([_templates.default.renderForPromise("tiny_ai/components/moodle-modal-header-title",templateContext),_templates.default.renderForPromise("tiny_ai/components/"+bodyComponentTemplate,templateContext),_templates.default.renderForPromise("tiny_ai/components/"+footerComponentTemplate,templateContext)]);templateContext.hasOwnProperty("modalHeadline")&&modal.setTitle(result[0].html),document.querySelectorAll("button[data-action]").forEach((button=>{(0,_jquery.default)(button).tooltip("hide")})),modal.setBody(result[1].html),modal.setFooter(result[2].html),result.forEach((item=>{_templates.default.runTemplateJS(item.js)})),modal.getRoot().attr("data-tiny_ai_uniqid",this.uniqid),await this.insertInfoBox(),await this.insertUserQuotaBox(),document.querySelectorAll("button[data-action]").forEach((button=>{button.addEventListener("click",(event=>{(0,_jquery.default)(event.target).closest("button[data-action]").tooltip("hide")}))}))}async insertInfoBox(){document.querySelector('[data-rendertarget="infobox"]')&&await(0,_infobox.renderInfoBox)("tiny_ai",(0,_utils.getEditorUtils)(this.uniqid).getUserId(),'[data-rendertarget="infobox"]',["singleprompt","translate","tts","imggen","itt"])}async insertUserQuotaBox(){document.querySelector('[data-rendertarget="usageinfo"]')&&await(0,_userquota.renderUserQuota)('[data-rendertarget="usageinfo"]',["singleprompt","translate","tts","imggen","itt"])}},_exports.default}));
+define("tiny_ai/renderer",["exports","local_ai_manager/infobox","local_ai_manager/userquota","tiny_ai/datahandler/basedata","core/templates","tiny_ai/utils","tiny_ai/constants"],(function(_exports,_infobox,_userquota,BasedataHandler,_templates,_utils,_constants){var obj;function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,BasedataHandler=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(BasedataHandler),_templates=(obj=_templates)&&obj.__esModule?obj:{default:obj};return _exports.default=class{constructor(uniqid,mode){_defineProperty(this,"uniqid",null),_defineProperty(this,"mode",null),_defineProperty(this,"datamanager",null),this.uniqid=uniqid,this.mode=mode,this.datamanager=(0,_utils.getDatamanager)(uniqid)}async renderStart(){this.datamanager.reset();const templateContext=await(0,_utils.getStartHandler)(this.uniqid).getTemplateContext((0,_utils.getEditorUtils)(this.uniqid));await this.renderModalContent("moodle-modal-body-start","moodle-modal-footer-info",templateContext)}async renderSummarize(){const templateContext=(0,_utils.getSummarizeHandler)(this.uniqid).getTemplateContext("summarize");await this.renderModalContent("moodle-modal-body-preferences","moodle-modal-footer-generate",templateContext)}async renderTranslate(){const templateContext=(0,_utils.getTranslateHandler)(this.uniqid).getTemplateContext();await this.renderModalContent("moodle-modal-body-preferences","moodle-modal-footer-generate",templateContext)}async renderDescribe(){const templateContext=(0,_utils.getSummarizeHandler)(this.uniqid).getTemplateContext("describe");await this.renderModalContent("moodle-modal-body-preferences","moodle-modal-footer-generate",templateContext)}async renderTts(){const templateContext=await(0,_utils.getTtsHandler)(this.uniqid).getTemplateContext();await this.renderModalContent("moodle-modal-body-preferences","moodle-modal-footer-generate",templateContext)}async renderImggen(){const templateContext=await(0,_utils.getImggenHandler)(this.uniqid).getTemplateContext();await this.renderModalContent("moodle-modal-body-mediageneration","moodle-modal-footer-generate",templateContext)}async renderDescribeimg(){const templateContext=await(0,_utils.getIttHandler)(this.uniqid).getTemplateContext("describeimg");await this.renderModalContent("moodle-modal-body-itt","moodle-modal-footer-generate",templateContext)}async renderImagetotext(){const templateContext=await(0,_utils.getIttHandler)(this.uniqid).getTemplateContext("imagetotext");await this.renderModalContent("moodle-modal-body-itt","moodle-modal-footer-generate",templateContext)}async renderLoading(){const templateContext={};templateContext.modalHeadline=BasedataHandler.getTinyAiString("aigenerating"),await this.renderModalContent("moodle-modal-body-loading","moodle-modal-footer-empty",templateContext)}async renderSuggestion(){const templateContext={};templateContext.modalHeadline=BasedataHandler.getTinyAiString("aisuggestion"),templateContext.resultText=this.renderAiResultForEditor(),this.mode===_constants.constants.modalModes.editor?Object.assign(templateContext,BasedataHandler.getReplaceButtonsContext(this.datamanager.getSelectionText().length>0)):Object.assign(templateContext,BasedataHandler.getCopyAndDownloadButtonsContext()),await this.renderModalContent("moodle-modal-body-suggestion","moodle-modal-footer-replace",templateContext)}async renderOptimizePrompt(){const templateContext=(0,_utils.getOptimizeHandler)(this.uniqid).getTemplateContext();await this.renderModalContent("moodle-modal-body-optimize","moodle-modal-footer-generate",templateContext)}async renderDismiss(){const templateContext={modalHeadline:"",centeredHeadline:BasedataHandler.getTinyAiString("dismisssuggestion"),showIcon:!1,buttons:[{hasText:!0,buttonText:BasedataHandler.getTinyAiString("cancel"),iconLeft:!1,iconRight:!1,primary:!1,secondary:!0,tertiary:!1,action:"canceldismiss"},{hasText:!0,buttonText:BasedataHandler.getTinyAiString("dismiss"),iconLeft:!1,iconRight:!1,primary:!0,secondary:!1,tertiary:!1,action:"dismiss"}]};await this.renderModalContent("moodle-modal-body-dismiss","moodle-modal-footer-empty",templateContext)}renderAiResultForEditor(){let html;switch(this.datamanager.getCurrentTool()){case"tts":case"audiogen":{const audioPlayer=document.createElement("audio");audioPlayer.controls="controls",audioPlayer.src=this.datamanager.getCurrentAiResult(),audioPlayer.type="audio/mpeg",html=audioPlayer.outerHTML;break}case"imggen":{const img=document.createElement("img");img.src=this.datamanager.getCurrentAiResult(),img.classList.add("mw-100"),html=img.outerHTML;break}default:html=this.datamanager.getCurrentAiResult()}return html}async renderModalContent(bodyComponentTemplate,footerComponentTemplate,templateContext){templateContext.tinyinstanceuniqid=this.uniqid;const modal=(0,_utils.getEditorUtils)(this.uniqid).getModal(),result=await Promise.all([_templates.default.renderForPromise("tiny_ai/components/moodle-modal-header-title",templateContext),_templates.default.renderForPromise("tiny_ai/components/"+bodyComponentTemplate,templateContext),_templates.default.renderForPromise("tiny_ai/components/"+footerComponentTemplate,templateContext)]);templateContext.hasOwnProperty("modalHeadline")&&modal.setTitle(result[0].html),modal.setBody(result[1].html),modal.setFooter(result[2].html),result.forEach((item=>{_templates.default.runTemplateJS(item.js)})),modal.getRoot().attr("data-tiny_ai_uniqid",this.uniqid),await this.insertInfoBox(),await this.insertUserQuotaBox()}async insertInfoBox(){document.querySelector('[data-rendertarget="infobox"]')&&await(0,_infobox.renderInfoBox)("tiny_ai",(0,_utils.getEditorUtils)(this.uniqid).getUserId(),'[data-rendertarget="infobox"]',["singleprompt","translate","tts","imggen","itt"])}async insertUserQuotaBox(){document.querySelector('[data-rendertarget="usageinfo"]')&&await(0,_userquota.renderUserQuota)('[data-rendertarget="usageinfo"]',["singleprompt","translate","tts","imggen","itt"])}},_exports.default}));
//# sourceMappingURL=renderer.min.js.map
\ No newline at end of file
diff --git a/amd/build/renderer.min.js.map b/amd/build/renderer.min.js.map
index 7bfddad..35ab488 100644
--- a/amd/build/renderer.min.js.map
+++ b/amd/build/renderer.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"renderer.min.js","sources":["../src/renderer.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny AI utils library.\n *\n * @module tiny_ai/renderer\n * @copyright 2024, ISB Bayern\n * @author Philipp Memmel\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {renderInfoBox} from 'local_ai_manager/infobox';\nimport {renderUserQuota} from 'local_ai_manager/userquota';\nimport * as BasedataHandler from 'tiny_ai/datahandler/basedata';\nimport Templates from 'core/templates';\nimport $ from 'jquery';\nimport {\n getEditorUtils,\n getDatamanager,\n getImggenHandler,\n getOptimizeHandler,\n getStartHandler,\n getSummarizeHandler,\n getTranslateHandler,\n getTtsHandler,\n getIttHandler\n} from 'tiny_ai/utils';\nimport {constants} from 'tiny_ai/constants';\n\nexport default class {\n\n uniqid = null;\n mode = null;\n datamanager = null;\n\n constructor(uniqid, mode) {\n this.uniqid = uniqid;\n this.mode = mode;\n this.datamanager = getDatamanager(uniqid);\n }\n\n async renderStart() {\n this.datamanager.reset();\n const templateContext = await getStartHandler(this.uniqid).getTemplateContext(getEditorUtils(this.uniqid));\n await this.renderModalContent('moodle-modal-body-start', 'moodle-modal-footer-info', templateContext);\n }\n\n\n async renderSummarize() {\n const templateContext = getSummarizeHandler(this.uniqid).getTemplateContext('summarize');\n await this.renderModalContent('moodle-modal-body-preferences', 'moodle-modal-footer-generate', templateContext);\n }\n\n\n async renderTranslate() {\n const templateContext = getTranslateHandler(this.uniqid).getTemplateContext();\n await this.renderModalContent('moodle-modal-body-preferences', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderDescribe() {\n const templateContext = getSummarizeHandler(this.uniqid).getTemplateContext('describe');\n await this.renderModalContent('moodle-modal-body-preferences', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderTts() {\n const templateContext = await getTtsHandler(this.uniqid).getTemplateContext();\n await this.renderModalContent('moodle-modal-body-preferences', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderImggen() {\n const templateContext = await getImggenHandler(this.uniqid).getTemplateContext();\n await this.renderModalContent('moodle-modal-body-mediageneration', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderDescribeimg() {\n const templateContext = await getIttHandler(this.uniqid).getTemplateContext('describeimg');\n await this.renderModalContent('moodle-modal-body-itt', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderImagetotext() {\n const templateContext = await getIttHandler(this.uniqid).getTemplateContext('imagetotext');\n await this.renderModalContent('moodle-modal-body-itt', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderLoading() {\n const templateContext = {};\n templateContext.modalHeadline = BasedataHandler.getTinyAiString('aigenerating');\n await this.renderModalContent('moodle-modal-body-loading', 'moodle-modal-footer-empty', templateContext);\n }\n\n\n async renderSuggestion() {\n const templateContext = {};\n templateContext.modalHeadline = BasedataHandler.getTinyAiString('aisuggestion');\n // TODO Eventually do not use the same rendering in the suggestion like in the course, or just leave it because we\n // consider it beautiful\n templateContext.resultText = this.renderAiResultForEditor();\n\n if (this.mode === constants.modalModes.editor) {\n Object.assign(templateContext, BasedataHandler.getReplaceButtonsContext(\n this.datamanager.getSelectionText().length > 0));\n } else {\n Object.assign(templateContext, BasedataHandler.getCopyAndDownloadButtonsContext());\n }\n await this.renderModalContent('moodle-modal-body-suggestion', 'moodle-modal-footer-replace', templateContext);\n }\n\n async renderOptimizePrompt() {\n const templateContext = getOptimizeHandler(this.uniqid).getTemplateContext();\n await this.renderModalContent('moodle-modal-body-optimize', 'moodle-modal-footer-generate', templateContext);\n }\n\n\n async renderDismiss() {\n const templateContext = {\n modalHeadline: '',\n centeredHeadline: BasedataHandler.getTinyAiString('dismisssuggestion'),\n showIcon: false,\n buttons: [\n {\n hasText: true,\n buttonText: BasedataHandler.getTinyAiString('cancel'),\n iconLeft: false,\n iconRight: false,\n primary: false,\n secondary: true,\n tertiary: false,\n action: 'canceldismiss'\n },\n {\n hasText: true,\n buttonText: BasedataHandler.getTinyAiString('dismiss'),\n iconLeft: false,\n iconRight: false,\n primary: true,\n secondary: false,\n tertiary: false,\n action: 'dismiss'\n }\n ]\n };\n await this.renderModalContent('moodle-modal-body-dismiss', 'moodle-modal-footer-empty', templateContext);\n }\n\n\n renderAiResultForEditor() {\n let html;\n switch (this.datamanager.getCurrentTool()) {\n case 'tts':\n case 'audiogen': {\n const audioPlayer = document.createElement('audio');\n audioPlayer.controls = 'controls';\n audioPlayer.src = this.datamanager.getCurrentAiResult();\n audioPlayer.type = 'audio/mpeg';\n html = audioPlayer.outerHTML;\n break;\n }\n case 'imggen': {\n const img = document.createElement('img');\n img.src = this.datamanager.getCurrentAiResult();\n img.classList.add('mw-100');\n html = img.outerHTML;\n break;\n }\n default: {\n html = this.datamanager.getCurrentAiResult();\n }\n }\n return html;\n }\n\n /**\n * Re-renders the content auf the modal once it has been created.\n *\n * @param {string} bodyComponentTemplate the name of the body template to use (without the prefix 'tiny_ai/components/')\n * @param {string} footerComponentTemplate the name of the footer template to use (without the prefix 'tiny_ai/components/')\n * @param {object} templateContext the template context being used for all partial templates\n * @returns {Promise} the async promise\n */\n async renderModalContent(bodyComponentTemplate, footerComponentTemplate, templateContext) {\n templateContext.tinyinstanceuniqid = this.uniqid;\n const modal = getEditorUtils(this.uniqid).getModal();\n // Remove all eventually remaining tooltips before rendering a new view.\n document.querySelectorAll('button[data-action]').forEach(button => {\n $(button).tooltip('hide');\n });\n const result = await Promise.all([\n Templates.renderForPromise('tiny_ai/components/moodle-modal-header-title', templateContext),\n Templates.renderForPromise('tiny_ai/components/' + bodyComponentTemplate, templateContext),\n Templates.renderForPromise('tiny_ai/components/' + footerComponentTemplate, templateContext)\n ]);\n if (templateContext.hasOwnProperty('modalHeadline')) {\n // If there is no headline specified, we keep the old one.\n modal.setTitle(result[0].html);\n }\n // Hide all eventually still existing tooltips first, because they show on 'hover' and\n // 'focus'. So we need to remove them before removing the corresponding buttons from the DOM.\n // Boostrap 4 still using jQuery for tooltips, so we need jQuery here.\n document.querySelectorAll('button[data-action]').forEach(button => {\n $(button).tooltip('hide');\n });\n modal.setBody(result[1].html);\n modal.setFooter(result[2].html);\n result.forEach((item) => {\n Templates.runTemplateJS(item.js);\n });\n modal.getRoot().attr('data-tiny_ai_uniqid', this.uniqid);\n await this.insertInfoBox();\n await this.insertUserQuotaBox();\n document.querySelectorAll('button[data-action]').forEach(button => {\n button.addEventListener('click', event => {\n $(event.target).closest('button[data-action]').tooltip('hide');\n });\n });\n }\n\n async insertInfoBox() {\n const infoBoxSelector = '[data-rendertarget=\"infobox\"]';\n if (document.querySelector(infoBoxSelector)) {\n await renderInfoBox('tiny_ai', getEditorUtils(this.uniqid).getUserId(), infoBoxSelector,\n ['singleprompt', 'translate', 'tts', 'imggen', 'itt']);\n }\n }\n\n async insertUserQuotaBox() {\n const usageBoxSelector = '[data-rendertarget=\"usageinfo\"]';\n if (document.querySelector(usageBoxSelector)) {\n await renderUserQuota(usageBoxSelector, ['singleprompt', 'translate', 'tts', 'imggen', 'itt']);\n }\n }\n}\n"],"names":["constructor","uniqid","mode","datamanager","reset","templateContext","this","getTemplateContext","renderModalContent","modalHeadline","BasedataHandler","getTinyAiString","resultText","renderAiResultForEditor","constants","modalModes","editor","Object","assign","getReplaceButtonsContext","getSelectionText","length","getCopyAndDownloadButtonsContext","centeredHeadline","showIcon","buttons","hasText","buttonText","iconLeft","iconRight","primary","secondary","tertiary","action","html","getCurrentTool","audioPlayer","document","createElement","controls","src","getCurrentAiResult","type","outerHTML","img","classList","add","bodyComponentTemplate","footerComponentTemplate","tinyinstanceuniqid","modal","getModal","querySelectorAll","forEach","button","tooltip","result","Promise","all","Templates","renderForPromise","hasOwnProperty","setTitle","setBody","setFooter","item","runTemplateJS","js","getRoot","attr","insertInfoBox","insertUserQuotaBox","addEventListener","event","target","closest","querySelector","getUserId"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"renderer.min.js","sources":["../src/renderer.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny AI utils library.\n *\n * @module tiny_ai/renderer\n * @copyright 2024, ISB Bayern\n * @author Philipp Memmel\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport {renderInfoBox} from 'local_ai_manager/infobox';\nimport {renderUserQuota} from 'local_ai_manager/userquota';\nimport * as BasedataHandler from 'tiny_ai/datahandler/basedata';\nimport Templates from 'core/templates';\nimport {\n getEditorUtils,\n getDatamanager,\n getImggenHandler,\n getOptimizeHandler,\n getStartHandler,\n getSummarizeHandler,\n getTranslateHandler,\n getTtsHandler,\n getIttHandler\n} from 'tiny_ai/utils';\nimport {constants} from 'tiny_ai/constants';\n\nexport default class {\n\n uniqid = null;\n mode = null;\n datamanager = null;\n\n constructor(uniqid, mode) {\n this.uniqid = uniqid;\n this.mode = mode;\n this.datamanager = getDatamanager(uniqid);\n }\n\n async renderStart() {\n this.datamanager.reset();\n const templateContext = await getStartHandler(this.uniqid).getTemplateContext(getEditorUtils(this.uniqid));\n await this.renderModalContent('moodle-modal-body-start', 'moodle-modal-footer-info', templateContext);\n }\n\n\n async renderSummarize() {\n const templateContext = getSummarizeHandler(this.uniqid).getTemplateContext('summarize');\n await this.renderModalContent('moodle-modal-body-preferences', 'moodle-modal-footer-generate', templateContext);\n }\n\n\n async renderTranslate() {\n const templateContext = getTranslateHandler(this.uniqid).getTemplateContext();\n await this.renderModalContent('moodle-modal-body-preferences', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderDescribe() {\n const templateContext = getSummarizeHandler(this.uniqid).getTemplateContext('describe');\n await this.renderModalContent('moodle-modal-body-preferences', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderTts() {\n const templateContext = await getTtsHandler(this.uniqid).getTemplateContext();\n await this.renderModalContent('moodle-modal-body-preferences', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderImggen() {\n const templateContext = await getImggenHandler(this.uniqid).getTemplateContext();\n await this.renderModalContent('moodle-modal-body-mediageneration', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderDescribeimg() {\n const templateContext = await getIttHandler(this.uniqid).getTemplateContext('describeimg');\n await this.renderModalContent('moodle-modal-body-itt', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderImagetotext() {\n const templateContext = await getIttHandler(this.uniqid).getTemplateContext('imagetotext');\n await this.renderModalContent('moodle-modal-body-itt', 'moodle-modal-footer-generate', templateContext);\n }\n\n async renderLoading() {\n const templateContext = {};\n templateContext.modalHeadline = BasedataHandler.getTinyAiString('aigenerating');\n await this.renderModalContent('moodle-modal-body-loading', 'moodle-modal-footer-empty', templateContext);\n }\n\n\n async renderSuggestion() {\n const templateContext = {};\n templateContext.modalHeadline = BasedataHandler.getTinyAiString('aisuggestion');\n // TODO Eventually do not use the same rendering in the suggestion like in the course, or just leave it because we\n // consider it beautiful\n templateContext.resultText = this.renderAiResultForEditor();\n\n if (this.mode === constants.modalModes.editor) {\n Object.assign(templateContext, BasedataHandler.getReplaceButtonsContext(\n this.datamanager.getSelectionText().length > 0));\n } else {\n Object.assign(templateContext, BasedataHandler.getCopyAndDownloadButtonsContext());\n }\n await this.renderModalContent('moodle-modal-body-suggestion', 'moodle-modal-footer-replace', templateContext);\n }\n\n async renderOptimizePrompt() {\n const templateContext = getOptimizeHandler(this.uniqid).getTemplateContext();\n await this.renderModalContent('moodle-modal-body-optimize', 'moodle-modal-footer-generate', templateContext);\n }\n\n\n async renderDismiss() {\n const templateContext = {\n modalHeadline: '',\n centeredHeadline: BasedataHandler.getTinyAiString('dismisssuggestion'),\n showIcon: false,\n buttons: [\n {\n hasText: true,\n buttonText: BasedataHandler.getTinyAiString('cancel'),\n iconLeft: false,\n iconRight: false,\n primary: false,\n secondary: true,\n tertiary: false,\n action: 'canceldismiss'\n },\n {\n hasText: true,\n buttonText: BasedataHandler.getTinyAiString('dismiss'),\n iconLeft: false,\n iconRight: false,\n primary: true,\n secondary: false,\n tertiary: false,\n action: 'dismiss'\n }\n ]\n };\n await this.renderModalContent('moodle-modal-body-dismiss', 'moodle-modal-footer-empty', templateContext);\n }\n\n\n renderAiResultForEditor() {\n let html;\n switch (this.datamanager.getCurrentTool()) {\n case 'tts':\n case 'audiogen': {\n const audioPlayer = document.createElement('audio');\n audioPlayer.controls = 'controls';\n audioPlayer.src = this.datamanager.getCurrentAiResult();\n audioPlayer.type = 'audio/mpeg';\n html = audioPlayer.outerHTML;\n break;\n }\n case 'imggen': {\n const img = document.createElement('img');\n img.src = this.datamanager.getCurrentAiResult();\n img.classList.add('mw-100');\n html = img.outerHTML;\n break;\n }\n default: {\n html = this.datamanager.getCurrentAiResult();\n }\n }\n return html;\n }\n\n /**\n * Re-renders the content auf the modal once it has been created.\n *\n * @param {string} bodyComponentTemplate the name of the body template to use (without the prefix 'tiny_ai/components/')\n * @param {string} footerComponentTemplate the name of the footer template to use (without the prefix 'tiny_ai/components/')\n * @param {object} templateContext the template context being used for all partial templates\n * @returns {Promise} the async promise\n */\n async renderModalContent(bodyComponentTemplate, footerComponentTemplate, templateContext) {\n templateContext.tinyinstanceuniqid = this.uniqid;\n const modal = getEditorUtils(this.uniqid).getModal();\n // Remove all eventually remaining tooltips before rendering a new view.\n const result = await Promise.all([\n Templates.renderForPromise('tiny_ai/components/moodle-modal-header-title', templateContext),\n Templates.renderForPromise('tiny_ai/components/' + bodyComponentTemplate, templateContext),\n Templates.renderForPromise('tiny_ai/components/' + footerComponentTemplate, templateContext)\n ]);\n if (templateContext.hasOwnProperty('modalHeadline')) {\n // If there is no headline specified, we keep the old one.\n modal.setTitle(result[0].html);\n }\n modal.setBody(result[1].html);\n modal.setFooter(result[2].html);\n result.forEach((item) => {\n Templates.runTemplateJS(item.js);\n });\n modal.getRoot().attr('data-tiny_ai_uniqid', this.uniqid);\n await this.insertInfoBox();\n await this.insertUserQuotaBox();\n }\n\n async insertInfoBox() {\n const infoBoxSelector = '[data-rendertarget=\"infobox\"]';\n if (document.querySelector(infoBoxSelector)) {\n await renderInfoBox('tiny_ai', getEditorUtils(this.uniqid).getUserId(), infoBoxSelector,\n ['singleprompt', 'translate', 'tts', 'imggen', 'itt']);\n }\n }\n\n async insertUserQuotaBox() {\n const usageBoxSelector = '[data-rendertarget=\"usageinfo\"]';\n if (document.querySelector(usageBoxSelector)) {\n await renderUserQuota(usageBoxSelector, ['singleprompt', 'translate', 'tts', 'imggen', 'itt']);\n }\n }\n}\n"],"names":["constructor","uniqid","mode","datamanager","reset","templateContext","this","getTemplateContext","renderModalContent","modalHeadline","BasedataHandler","getTinyAiString","resultText","renderAiResultForEditor","constants","modalModes","editor","Object","assign","getReplaceButtonsContext","getSelectionText","length","getCopyAndDownloadButtonsContext","centeredHeadline","showIcon","buttons","hasText","buttonText","iconLeft","iconRight","primary","secondary","tertiary","action","html","getCurrentTool","audioPlayer","document","createElement","controls","src","getCurrentAiResult","type","outerHTML","img","classList","add","bodyComponentTemplate","footerComponentTemplate","tinyinstanceuniqid","modal","getModal","result","Promise","all","Templates","renderForPromise","hasOwnProperty","setTitle","setBody","setFooter","forEach","item","runTemplateJS","js","getRoot","attr","insertInfoBox","insertUserQuotaBox","querySelector","getUserId"],"mappings":"giDA+CIA,YAAYC,OAAQC,oCAJX,kCACF,yCACO,WAGLD,OAASA,YACTC,KAAOA,UACPC,aAAc,yBAAeF,iCAI7BE,YAAYC,cACXC,sBAAwB,0BAAgBC,KAAKL,QAAQM,oBAAmB,yBAAeD,KAAKL,eAC5FK,KAAKE,mBAAmB,0BAA2B,2BAA4BH,+CAK/EA,iBAAkB,8BAAoBC,KAAKL,QAAQM,mBAAmB,mBACtED,KAAKE,mBAAmB,gCAAiC,+BAAgCH,+CAKzFA,iBAAkB,8BAAoBC,KAAKL,QAAQM,2BACnDD,KAAKE,mBAAmB,gCAAiC,+BAAgCH,8CAIzFA,iBAAkB,8BAAoBC,KAAKL,QAAQM,mBAAmB,kBACtED,KAAKE,mBAAmB,gCAAiC,+BAAgCH,yCAIzFA,sBAAwB,wBAAcC,KAAKL,QAAQM,2BACnDD,KAAKE,mBAAmB,gCAAiC,+BAAgCH,4CAIzFA,sBAAwB,2BAAiBC,KAAKL,QAAQM,2BACtDD,KAAKE,mBAAmB,oCAAqC,+BAAgCH,iDAI7FA,sBAAwB,wBAAcC,KAAKL,QAAQM,mBAAmB,qBACtED,KAAKE,mBAAmB,wBAAyB,+BAAgCH,iDAIjFA,sBAAwB,wBAAcC,KAAKL,QAAQM,mBAAmB,qBACtED,KAAKE,mBAAmB,wBAAyB,+BAAgCH,6CAIjFA,gBAAkB,GACxBA,gBAAgBI,cAAgBC,gBAAgBC,gBAAgB,sBAC1DL,KAAKE,mBAAmB,4BAA6B,4BAA6BH,gDAKlFA,gBAAkB,GACxBA,gBAAgBI,cAAgBC,gBAAgBC,gBAAgB,gBAGhEN,gBAAgBO,WAAaN,KAAKO,0BAE9BP,KAAKJ,OAASY,qBAAUC,WAAWC,OACnCC,OAAOC,OAAOb,gBAAiBK,gBAAgBS,yBAC3Cb,KAAKH,YAAYiB,mBAAmBC,OAAS,IAEjDJ,OAAOC,OAAOb,gBAAiBK,gBAAgBY,0CAE7ChB,KAAKE,mBAAmB,+BAAgC,8BAA+BH,oDAIvFA,iBAAkB,6BAAmBC,KAAKL,QAAQM,2BAClDD,KAAKE,mBAAmB,6BAA8B,+BAAgCH,6CAKtFA,gBAAkB,CACpBI,cAAe,GACfc,iBAAkBb,gBAAgBC,gBAAgB,qBAClDa,UAAU,EACVC,QAAS,CACL,CACIC,SAAS,EACTC,WAAYjB,gBAAgBC,gBAAgB,UAC5CiB,UAAU,EACVC,WAAW,EACXC,SAAS,EACTC,WAAW,EACXC,UAAU,EACVC,OAAQ,iBAEZ,CACIP,SAAS,EACTC,WAAYjB,gBAAgBC,gBAAgB,WAC5CiB,UAAU,EACVC,WAAW,EACXC,SAAS,EACTC,WAAW,EACXC,UAAU,EACVC,OAAQ,mBAId3B,KAAKE,mBAAmB,4BAA6B,4BAA6BH,iBAI5FQ,8BACQqB,YACI5B,KAAKH,YAAYgC,sBAChB,UACA,kBACKC,YAAcC,SAASC,cAAc,SAC3CF,YAAYG,SAAW,WACvBH,YAAYI,IAAMlC,KAAKH,YAAYsC,qBACnCL,YAAYM,KAAO,aACnBR,KAAOE,YAAYO,oBAGlB,gBACKC,IAAMP,SAASC,cAAc,OACnCM,IAAIJ,IAAMlC,KAAKH,YAAYsC,qBAC3BG,IAAIC,UAAUC,IAAI,UAClBZ,KAAOU,IAAID,wBAIXT,KAAO5B,KAAKH,YAAYsC,4BAGzBP,8BAWca,sBAAuBC,wBAAyB3C,iBACrEA,gBAAgB4C,mBAAqB3C,KAAKL,aACpCiD,OAAQ,yBAAe5C,KAAKL,QAAQkD,WAEpCC,aAAeC,QAAQC,IAAI,CAC7BC,mBAAUC,iBAAiB,+CAAgDnD,iBAC3EkD,mBAAUC,iBAAiB,sBAAwBT,sBAAuB1C,iBAC1EkD,mBAAUC,iBAAiB,sBAAwBR,wBAAyB3C,mBAE5EA,gBAAgBoD,eAAe,kBAE/BP,MAAMQ,SAASN,OAAO,GAAGlB,MAE7BgB,MAAMS,QAAQP,OAAO,GAAGlB,MACxBgB,MAAMU,UAAUR,OAAO,GAAGlB,MAC1BkB,OAAOS,SAASC,0BACFC,cAAcD,KAAKE,OAEjCd,MAAMe,UAAUC,KAAK,sBAAuB5D,KAAKL,cAC3CK,KAAK6D,sBACL7D,KAAK8D,2CAKP/B,SAASgC,cADW,wCAEd,0BAAc,WAAW,yBAAe/D,KAAKL,QAAQqE,YAFvC,gCAGhB,CAAC,eAAgB,YAAa,MAAO,SAAU,mCAMnDjC,SAASgC,cADY,0CAEf,8BAFe,kCAEmB,CAAC,eAAgB,YAAa,MAAO,SAAU"}
\ No newline at end of file
diff --git a/amd/build/utils.min.js b/amd/build/utils.min.js
index 7239f0e..c32bbfa 100644
--- a/amd/build/utils.min.js
+++ b/amd/build/utils.min.js
@@ -1,4 +1,4 @@
-define("tiny_ai/utils",["exports","core/modal_events","tiny_ai/renderer","tiny_ai/datamanager","tiny_ai/datahandler/imggen","tiny_ai/datahandler/optimize","tiny_ai/datahandler/start","tiny_ai/datahandler/summarize","tiny_ai/datahandler/translate","tiny_ai/datahandler/tts","tiny_ai/datahandler/itt","core/notification","core/str","local_ai_manager/make_request","tiny_ai/datahandler/basedata","jquery","core/log"],(function(_exports,_modal_events,_renderer,_datamanager,_imggen,_optimize,_start,_summarize,_translate,_tts,_itt,_notification,_str,_make_request,BasedataHandler,_jquery,_log){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+define("tiny_ai/utils",["exports","tiny_ai/renderer","tiny_ai/datamanager","tiny_ai/datahandler/imggen","tiny_ai/datahandler/optimize","tiny_ai/datahandler/start","tiny_ai/datahandler/summarize","tiny_ai/datahandler/translate","tiny_ai/datahandler/tts","tiny_ai/datahandler/itt","core/notification","core/str","local_ai_manager/make_request","tiny_ai/datahandler/basedata","core/log"],(function(_exports,_renderer,_datamanager,_imggen,_optimize,_start,_summarize,_translate,_tts,_itt,_notification,_str,_make_request,BasedataHandler,_log){function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* Tiny AI utils library.
*
@@ -6,6 +6,6 @@ define("tiny_ai/utils",["exports","core/modal_events","tiny_ai/renderer","tiny_a
* @copyright 2024, ISB Bayern
* @author Dr. Peter Mayer
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.stripHtmlTags=_exports.setEditorUtils=_exports.init=_exports.getTtsHandler=_exports.getTranslateHandler=_exports.getSummarizeHandler=_exports.getStartHandler=_exports.getRenderer=_exports.getOptimizeHandler=_exports.getIttHandler=_exports.getImggenHandler=_exports.getEditorUtils=_exports.getDatamanager=_exports.getCurrentModalUniqId=_exports.getAiAnswer=_exports.errorAlert=_exports.editorUtilsExist=_exports.downloadTextAsFile=_exports.downloadFile=_exports.copyTextToClipboard=_exports.copyFileToClipboard=void 0,_modal_events=_interopRequireDefault(_modal_events),_renderer=_interopRequireDefault(_renderer),_datamanager=_interopRequireDefault(_datamanager),_imggen=_interopRequireDefault(_imggen),_optimize=_interopRequireDefault(_optimize),_start=_interopRequireDefault(_start),_summarize=_interopRequireDefault(_summarize),_translate=_interopRequireDefault(_translate),_tts=_interopRequireDefault(_tts),_itt=_interopRequireDefault(_itt),BasedataHandler=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(BasedataHandler),_jquery=_interopRequireDefault(_jquery),_log=_interopRequireDefault(_log);const objectStore={};_exports.init=async(uniqid,mode)=>{objectStore.hasOwnProperty(uniqid)||(objectStore[uniqid]={},objectStore[uniqid].datamanager=new _datamanager.default(uniqid),await BasedataHandler.init(),objectStore[uniqid].imggenhandler=new _imggen.default(uniqid),objectStore[uniqid].optimizehandler=new _optimize.default(uniqid),objectStore[uniqid].starthandler=new _start.default(uniqid),await objectStore[uniqid].starthandler.init(),objectStore[uniqid].summarizehandler=new _summarize.default(uniqid),objectStore[uniqid].translatehandler=new _translate.default(uniqid),objectStore[uniqid].ttshandler=new _tts.default(uniqid),objectStore[uniqid].itthandler=new _itt.default(uniqid),objectStore[uniqid].renderer=new _renderer.default(uniqid,mode))};_exports.getAiAnswer=async function(prompt,purpose){let options=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},result=null;const contextid=options.contextid;delete options.contextid;const component=options.component;delete options.component;try{result=await(0,_make_request.makeRequest)(purpose,prompt,component,contextid,options)}catch(exception){return await(0,_notification.exception)(exception),null}if(200!==result.code){const alertTitle=await(0,_str.getString)("errorwithcode","tiny_ai",result.code),parsedResult=JSON.parse(result.result);return parsedResult.debuginfo&&_log.default.error(parsedResult.debuginfo),await errorAlert(parsedResult.message,alertTitle),null}return result.result};const errorAlert=async function(message){let title=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;null===title&&(title=BasedataHandler.getTinyAiString("generalerror"));const alertModal=await(0,_notification.alert)(title,message);alertModal.getRoot().on(_modal_events.default.hidden,(()=>{document.querySelectorAll("button[data-action]").forEach((button=>{(0,_jquery.default)(button).tooltip("hide")}))}))};_exports.errorAlert=errorAlert;_exports.stripHtmlTags=textWithTags=>{const span=document.createElement("span");return span.innerHTML=textWithTags,span.textContent};_exports.editorUtilsExist=uniqid=>objectStore.hasOwnProperty(uniqid);_exports.setEditorUtils=(uniqid,editorUtils)=>{objectStore[uniqid].editorUtils=editorUtils};_exports.getEditorUtils=uniqid=>objectStore[uniqid].editorUtils;_exports.getRenderer=uniqid=>objectStore[uniqid].renderer;_exports.getDatamanager=uniqid=>objectStore[uniqid].datamanager;_exports.getImggenHandler=uniqid=>objectStore[uniqid].imggenhandler;_exports.getOptimizeHandler=uniqid=>objectStore[uniqid].optimizehandler;_exports.getStartHandler=uniqid=>objectStore[uniqid].starthandler;_exports.getSummarizeHandler=uniqid=>objectStore[uniqid].summarizehandler;_exports.getTranslateHandler=uniqid=>objectStore[uniqid].translatehandler;_exports.getTtsHandler=uniqid=>objectStore[uniqid].ttshandler;_exports.getIttHandler=uniqid=>objectStore[uniqid].itthandler;_exports.getCurrentModalUniqId=element=>element.closest("[data-tiny_instance_uniqid]").dataset.tiny_instance_uniqid;_exports.copyTextToClipboard=text=>{const clipboardItemData={"text/plain":text};navigator.clipboard.write([new ClipboardItem(clipboardItemData)])};_exports.copyFileToClipboard=async url=>{const data=await fetch(url),blob=await data.blob();if(!ClipboardItem.supports(blob.type))return!1;const clipboardItemData={[blob.type]:blob};return navigator.clipboard.write([new ClipboardItem(clipboardItemData)]),!0};const downloadFile=function(url){let filename=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;const link=document.createElement("a");link.href=url,filename||(filename=url.split("/").pop()),link.download=filename,document.body.appendChild(link),link.click(),document.body.removeChild(link)};_exports.downloadFile=downloadFile;_exports.downloadTextAsFile=text=>{const blob=new Blob([text],{type:"text/plain"}),url=URL.createObjectURL(blob);downloadFile(url,"airesult.txt"),URL.revokeObjectURL(url)}}));
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.stripHtmlTags=_exports.setEditorUtils=_exports.init=_exports.getTtsHandler=_exports.getTranslateHandler=_exports.getSummarizeHandler=_exports.getStartHandler=_exports.getRenderer=_exports.getOptimizeHandler=_exports.getIttHandler=_exports.getImggenHandler=_exports.getEditorUtils=_exports.getDatamanager=_exports.getCurrentModalUniqId=_exports.getAiAnswer=_exports.errorAlert=_exports.editorUtilsExist=_exports.downloadTextAsFile=_exports.downloadFile=_exports.copyTextToClipboard=_exports.copyFileToClipboard=void 0,_renderer=_interopRequireDefault(_renderer),_datamanager=_interopRequireDefault(_datamanager),_imggen=_interopRequireDefault(_imggen),_optimize=_interopRequireDefault(_optimize),_start=_interopRequireDefault(_start),_summarize=_interopRequireDefault(_summarize),_translate=_interopRequireDefault(_translate),_tts=_interopRequireDefault(_tts),_itt=_interopRequireDefault(_itt),BasedataHandler=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(BasedataHandler),_log=_interopRequireDefault(_log);const objectStore={};_exports.init=async(uniqid,mode)=>{objectStore.hasOwnProperty(uniqid)||(objectStore[uniqid]={},objectStore[uniqid].datamanager=new _datamanager.default(uniqid),await BasedataHandler.init(),objectStore[uniqid].imggenhandler=new _imggen.default(uniqid),objectStore[uniqid].optimizehandler=new _optimize.default(uniqid),objectStore[uniqid].starthandler=new _start.default(uniqid),await objectStore[uniqid].starthandler.init(),objectStore[uniqid].summarizehandler=new _summarize.default(uniqid),objectStore[uniqid].translatehandler=new _translate.default(uniqid),objectStore[uniqid].ttshandler=new _tts.default(uniqid),objectStore[uniqid].itthandler=new _itt.default(uniqid),objectStore[uniqid].renderer=new _renderer.default(uniqid,mode))};_exports.getAiAnswer=async function(prompt,purpose){let options=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},result=null;const contextid=options.contextid;delete options.contextid;const component=options.component;delete options.component;try{result=await(0,_make_request.makeRequest)(purpose,prompt,component,contextid,options)}catch(exception){return await(0,_notification.exception)(exception),null}if(200!==result.code){const alertTitle=await(0,_str.getString)("errorwithcode","tiny_ai",result.code),parsedResult=JSON.parse(result.result);return parsedResult.debuginfo&&_log.default.error(parsedResult.debuginfo),await errorAlert(parsedResult.message,alertTitle),null}return result.result};const errorAlert=async function(message){let title=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;null===title&&(title=BasedataHandler.getTinyAiString("generalerror")),await(0,_notification.alert)(title,message)};_exports.errorAlert=errorAlert;_exports.stripHtmlTags=textWithTags=>{const span=document.createElement("span");return span.innerHTML=textWithTags,span.textContent};_exports.editorUtilsExist=uniqid=>objectStore.hasOwnProperty(uniqid);_exports.setEditorUtils=(uniqid,editorUtils)=>{objectStore[uniqid].editorUtils=editorUtils};_exports.getEditorUtils=uniqid=>objectStore[uniqid].editorUtils;_exports.getRenderer=uniqid=>objectStore[uniqid].renderer;_exports.getDatamanager=uniqid=>objectStore[uniqid].datamanager;_exports.getImggenHandler=uniqid=>objectStore[uniqid].imggenhandler;_exports.getOptimizeHandler=uniqid=>objectStore[uniqid].optimizehandler;_exports.getStartHandler=uniqid=>objectStore[uniqid].starthandler;_exports.getSummarizeHandler=uniqid=>objectStore[uniqid].summarizehandler;_exports.getTranslateHandler=uniqid=>objectStore[uniqid].translatehandler;_exports.getTtsHandler=uniqid=>objectStore[uniqid].ttshandler;_exports.getIttHandler=uniqid=>objectStore[uniqid].itthandler;_exports.getCurrentModalUniqId=element=>element.closest("[data-tiny_instance_uniqid]").dataset.tiny_instance_uniqid;_exports.copyTextToClipboard=text=>{const clipboardItemData={"text/plain":text};navigator.clipboard.write([new ClipboardItem(clipboardItemData)])};_exports.copyFileToClipboard=async url=>{const data=await fetch(url),blob=await data.blob();if(!ClipboardItem.supports(blob.type))return!1;const clipboardItemData={[blob.type]:blob};return navigator.clipboard.write([new ClipboardItem(clipboardItemData)]),!0};const downloadFile=function(url){let filename=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;const link=document.createElement("a");link.href=url,filename||(filename=url.split("/").pop()),link.download=filename,document.body.appendChild(link),link.click(),document.body.removeChild(link)};_exports.downloadFile=downloadFile;_exports.downloadTextAsFile=text=>{const blob=new Blob([text],{type:"text/plain"}),url=URL.createObjectURL(blob);downloadFile(url,"airesult.txt"),URL.revokeObjectURL(url)}}));
//# sourceMappingURL=utils.min.js.map
\ No newline at end of file
diff --git a/amd/build/utils.min.js.map b/amd/build/utils.min.js.map
index 35bea1b..0e5a3ed 100644
--- a/amd/build/utils.min.js.map
+++ b/amd/build/utils.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"utils.min.js","sources":["../src/utils.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny AI utils library.\n *\n * @module tiny_ai/utils\n * @copyright 2024, ISB Bayern\n * @author Dr. Peter Mayer\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport ModalEvents from 'core/modal_events';\nimport Renderer from 'tiny_ai/renderer';\nimport DataManager from 'tiny_ai/datamanager';\nimport ImggenHandler from 'tiny_ai/datahandler/imggen';\nimport OptimizeHandler from 'tiny_ai/datahandler/optimize';\nimport StartHandler from 'tiny_ai/datahandler/start';\nimport SummarizeHandler from 'tiny_ai/datahandler/summarize';\nimport TranslateHandler from 'tiny_ai/datahandler/translate';\nimport TtsHandler from 'tiny_ai/datahandler/tts';\nimport IttHandler from 'tiny_ai/datahandler/itt';\nimport {alert as moodleAlert, exception as displayException} from 'core/notification';\nimport {getString} from 'core/str';\nimport {makeRequest} from 'local_ai_manager/make_request';\nimport * as BasedataHandler from 'tiny_ai/datahandler/basedata';\nimport $ from 'jquery';\nimport Log from 'core/log';\n\nconst objectStore = {};\n\nexport const init = async(uniqid, mode) => {\n if (!objectStore.hasOwnProperty(uniqid)) {\n objectStore[uniqid] = {};\n // The order in which these objects are being created is actually pretty important, because Renderer\n // object depends on DataManager object.\n objectStore[uniqid].datamanager = new DataManager(uniqid);\n await BasedataHandler.init();\n objectStore[uniqid].imggenhandler = new ImggenHandler(uniqid);\n objectStore[uniqid].optimizehandler = new OptimizeHandler(uniqid);\n objectStore[uniqid].starthandler = new StartHandler(uniqid);\n await objectStore[uniqid].starthandler.init();\n objectStore[uniqid].summarizehandler = new SummarizeHandler(uniqid);\n objectStore[uniqid].translatehandler = new TranslateHandler(uniqid);\n objectStore[uniqid].ttshandler = new TtsHandler(uniqid);\n objectStore[uniqid].itthandler = new IttHandler(uniqid);\n objectStore[uniqid].renderer = new Renderer(uniqid, mode);\n }\n};\n\nexport const getAiAnswer = async(prompt, purpose, options = {}) => {\n let result = null;\n const contextid = options.contextid;\n delete options.contextid;\n const component = options.component;\n delete options.component;\n\n try {\n result = await makeRequest(purpose, prompt, component, contextid, options);\n } catch (exception) {\n await displayException(exception);\n return null;\n }\n if (result.code !== 200) {\n const alertTitle = await getString('errorwithcode', 'tiny_ai', result.code);\n const parsedResult = JSON.parse(result.result);\n if (parsedResult.debuginfo) {\n Log.error(parsedResult.debuginfo);\n }\n await errorAlert(parsedResult.message, alertTitle);\n return null;\n }\n return result.result;\n};\n\nexport const errorAlert = async(message, title = null) => {\n if (title === null) {\n title = BasedataHandler.getTinyAiString('generalerror');\n }\n const alertModal = await moodleAlert(title, message);\n alertModal.getRoot().on(ModalEvents.hidden, () => {\n document.querySelectorAll('button[data-action]').forEach(button => {\n $(button).tooltip('hide');\n });\n });\n};\n\nexport const stripHtmlTags = (textWithTags) => {\n // Place selected content into a temporary span and extract the plain text from it to strip HTML tags.\n const span = document.createElement('span');\n span.innerHTML = textWithTags;\n return span.textContent;\n};\n\nexport const editorUtilsExist = (uniqid) => {\n return objectStore.hasOwnProperty(uniqid);\n};\n\nexport const setEditorUtils = (uniqid, editorUtils) => {\n objectStore[uniqid].editorUtils = editorUtils;\n};\n\nexport const getEditorUtils = (uniqid) => {\n return objectStore[uniqid].editorUtils;\n};\n\nexport const getRenderer = (uniqid) => {\n return objectStore[uniqid].renderer;\n};\n\nexport const getDatamanager = (uniqid) => {\n return objectStore[uniqid].datamanager;\n};\n\nexport const getImggenHandler = (uniqid) => {\n return objectStore[uniqid].imggenhandler;\n};\n\nexport const getOptimizeHandler = (uniqid) => {\n return objectStore[uniqid].optimizehandler;\n};\n\nexport const getStartHandler = (uniqid) => {\n return objectStore[uniqid].starthandler;\n};\n\nexport const getSummarizeHandler = (uniqid) => {\n return objectStore[uniqid].summarizehandler;\n};\n\nexport const getTranslateHandler = (uniqid) => {\n return objectStore[uniqid].translatehandler;\n};\n\nexport const getTtsHandler = (uniqid) => {\n return objectStore[uniqid].ttshandler;\n};\n\nexport const getIttHandler = (uniqid) => {\n return objectStore[uniqid].itthandler;\n};\n\nexport const getCurrentModalUniqId = (element) => {\n return element.closest('[data-tiny_instance_uniqid]').dataset.tiny_instance_uniqid;\n};\n\nexport const copyTextToClipboard = (text) => {\n const clipboardItemData = {\n 'text/plain': text\n };\n navigator.clipboard.write([new ClipboardItem(clipboardItemData)]);\n};\n\nexport const copyFileToClipboard = async(url) => {\n const data = await fetch(url);\n const blob = await data.blob();\n if (!ClipboardItem.supports(blob.type)) {\n return false;\n }\n\n const clipboardItemData = {\n [blob.type]: blob\n };\n navigator.clipboard.write([new ClipboardItem(clipboardItemData)]);\n return true;\n};\n\nexport const downloadFile = (url, filename = null) => {\n const link = document.createElement('a');\n link.href = url;\n if (!filename) {\n filename = url.split('/').pop();\n }\n\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n};\n\nexport const downloadTextAsFile = (text) => {\n const blob = new Blob([text], {type: 'text/plain'});\n const url = URL.createObjectURL(blob);\n downloadFile(url, 'airesult.txt');\n URL.revokeObjectURL(url);\n};\n"],"names":["objectStore","async","uniqid","mode","hasOwnProperty","datamanager","DataManager","BasedataHandler","init","imggenhandler","ImggenHandler","optimizehandler","OptimizeHandler","starthandler","StartHandler","summarizehandler","SummarizeHandler","translatehandler","TranslateHandler","ttshandler","TtsHandler","itthandler","IttHandler","renderer","Renderer","prompt","purpose","options","result","contextid","component","exception","code","alertTitle","parsedResult","JSON","parse","debuginfo","error","errorAlert","message","title","getTinyAiString","alertModal","getRoot","on","ModalEvents","hidden","document","querySelectorAll","forEach","button","tooltip","textWithTags","span","createElement","innerHTML","textContent","editorUtils","element","closest","dataset","tiny_instance_uniqid","text","clipboardItemData","navigator","clipboard","write","ClipboardItem","data","fetch","url","blob","supports","type","downloadFile","filename","link","href","split","pop","download","body","appendChild","click","removeChild","Blob","URL","createObjectURL","revokeObjectURL"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"utils.min.js","sources":["../src/utils.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Tiny AI utils library.\n *\n * @module tiny_ai/utils\n * @copyright 2024, ISB Bayern\n * @author Dr. Peter Mayer\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Renderer from 'tiny_ai/renderer';\nimport DataManager from 'tiny_ai/datamanager';\nimport ImggenHandler from 'tiny_ai/datahandler/imggen';\nimport OptimizeHandler from 'tiny_ai/datahandler/optimize';\nimport StartHandler from 'tiny_ai/datahandler/start';\nimport SummarizeHandler from 'tiny_ai/datahandler/summarize';\nimport TranslateHandler from 'tiny_ai/datahandler/translate';\nimport TtsHandler from 'tiny_ai/datahandler/tts';\nimport IttHandler from 'tiny_ai/datahandler/itt';\nimport {alert as moodleAlert, exception as displayException} from 'core/notification';\nimport {getString} from 'core/str';\nimport {makeRequest} from 'local_ai_manager/make_request';\nimport * as BasedataHandler from 'tiny_ai/datahandler/basedata';\nimport Log from 'core/log';\n\nconst objectStore = {};\n\nexport const init = async(uniqid, mode) => {\n if (!objectStore.hasOwnProperty(uniqid)) {\n objectStore[uniqid] = {};\n // The order in which these objects are being created is actually pretty important, because Renderer\n // object depends on DataManager object.\n objectStore[uniqid].datamanager = new DataManager(uniqid);\n await BasedataHandler.init();\n objectStore[uniqid].imggenhandler = new ImggenHandler(uniqid);\n objectStore[uniqid].optimizehandler = new OptimizeHandler(uniqid);\n objectStore[uniqid].starthandler = new StartHandler(uniqid);\n await objectStore[uniqid].starthandler.init();\n objectStore[uniqid].summarizehandler = new SummarizeHandler(uniqid);\n objectStore[uniqid].translatehandler = new TranslateHandler(uniqid);\n objectStore[uniqid].ttshandler = new TtsHandler(uniqid);\n objectStore[uniqid].itthandler = new IttHandler(uniqid);\n objectStore[uniqid].renderer = new Renderer(uniqid, mode);\n }\n};\n\nexport const getAiAnswer = async(prompt, purpose, options = {}) => {\n let result = null;\n const contextid = options.contextid;\n delete options.contextid;\n const component = options.component;\n delete options.component;\n\n try {\n result = await makeRequest(purpose, prompt, component, contextid, options);\n } catch (exception) {\n await displayException(exception);\n return null;\n }\n if (result.code !== 200) {\n const alertTitle = await getString('errorwithcode', 'tiny_ai', result.code);\n const parsedResult = JSON.parse(result.result);\n if (parsedResult.debuginfo) {\n Log.error(parsedResult.debuginfo);\n }\n await errorAlert(parsedResult.message, alertTitle);\n return null;\n }\n return result.result;\n};\n\nexport const errorAlert = async(message, title = null) => {\n if (title === null) {\n title = BasedataHandler.getTinyAiString('generalerror');\n }\n await moodleAlert(title, message);\n};\n\nexport const stripHtmlTags = (textWithTags) => {\n // Place selected content into a temporary span and extract the plain text from it to strip HTML tags.\n const span = document.createElement('span');\n span.innerHTML = textWithTags;\n return span.textContent;\n};\n\nexport const editorUtilsExist = (uniqid) => {\n return objectStore.hasOwnProperty(uniqid);\n};\n\nexport const setEditorUtils = (uniqid, editorUtils) => {\n objectStore[uniqid].editorUtils = editorUtils;\n};\n\nexport const getEditorUtils = (uniqid) => {\n return objectStore[uniqid].editorUtils;\n};\n\nexport const getRenderer = (uniqid) => {\n return objectStore[uniqid].renderer;\n};\n\nexport const getDatamanager = (uniqid) => {\n return objectStore[uniqid].datamanager;\n};\n\nexport const getImggenHandler = (uniqid) => {\n return objectStore[uniqid].imggenhandler;\n};\n\nexport const getOptimizeHandler = (uniqid) => {\n return objectStore[uniqid].optimizehandler;\n};\n\nexport const getStartHandler = (uniqid) => {\n return objectStore[uniqid].starthandler;\n};\n\nexport const getSummarizeHandler = (uniqid) => {\n return objectStore[uniqid].summarizehandler;\n};\n\nexport const getTranslateHandler = (uniqid) => {\n return objectStore[uniqid].translatehandler;\n};\n\nexport const getTtsHandler = (uniqid) => {\n return objectStore[uniqid].ttshandler;\n};\n\nexport const getIttHandler = (uniqid) => {\n return objectStore[uniqid].itthandler;\n};\n\nexport const getCurrentModalUniqId = (element) => {\n return element.closest('[data-tiny_instance_uniqid]').dataset.tiny_instance_uniqid;\n};\n\nexport const copyTextToClipboard = (text) => {\n const clipboardItemData = {\n 'text/plain': text\n };\n navigator.clipboard.write([new ClipboardItem(clipboardItemData)]);\n};\n\nexport const copyFileToClipboard = async(url) => {\n const data = await fetch(url);\n const blob = await data.blob();\n if (!ClipboardItem.supports(blob.type)) {\n return false;\n }\n\n const clipboardItemData = {\n [blob.type]: blob\n };\n navigator.clipboard.write([new ClipboardItem(clipboardItemData)]);\n return true;\n};\n\nexport const downloadFile = (url, filename = null) => {\n const link = document.createElement('a');\n link.href = url;\n if (!filename) {\n filename = url.split('/').pop();\n }\n\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n};\n\nexport const downloadTextAsFile = (text) => {\n const blob = new Blob([text], {type: 'text/plain'});\n const url = URL.createObjectURL(blob);\n downloadFile(url, 'airesult.txt');\n URL.revokeObjectURL(url);\n};\n"],"names":["objectStore","async","uniqid","mode","hasOwnProperty","datamanager","DataManager","BasedataHandler","init","imggenhandler","ImggenHandler","optimizehandler","OptimizeHandler","starthandler","StartHandler","summarizehandler","SummarizeHandler","translatehandler","TranslateHandler","ttshandler","TtsHandler","itthandler","IttHandler","renderer","Renderer","prompt","purpose","options","result","contextid","component","exception","code","alertTitle","parsedResult","JSON","parse","debuginfo","error","errorAlert","message","title","getTinyAiString","textWithTags","span","document","createElement","innerHTML","textContent","editorUtils","element","closest","dataset","tiny_instance_uniqid","text","clipboardItemData","navigator","clipboard","write","ClipboardItem","data","fetch","url","blob","supports","type","downloadFile","filename","link","href","split","pop","download","body","appendChild","click","removeChild","Blob","URL","createObjectURL","revokeObjectURL"],"mappings":";;;;;;;;ypDAuCMA,YAAc,iBAEAC,MAAMC,OAAQC,QACzBH,YAAYI,eAAeF,UAC5BF,YAAYE,QAAU,GAGtBF,YAAYE,QAAQG,YAAc,IAAIC,qBAAYJ,cAC5CK,gBAAgBC,OACtBR,YAAYE,QAAQO,cAAgB,IAAIC,gBAAcR,QACtDF,YAAYE,QAAQS,gBAAkB,IAAIC,kBAAgBV,QAC1DF,YAAYE,QAAQW,aAAe,IAAIC,eAAaZ,cAC9CF,YAAYE,QAAQW,aAAaL,OACvCR,YAAYE,QAAQa,iBAAmB,IAAIC,mBAAiBd,QAC5DF,YAAYE,QAAQe,iBAAmB,IAAIC,mBAAiBhB,QAC5DF,YAAYE,QAAQiB,WAAa,IAAIC,aAAWlB,QAChDF,YAAYE,QAAQmB,WAAa,IAAIC,aAAWpB,QAChDF,YAAYE,QAAQqB,SAAW,IAAIC,kBAAStB,OAAQC,6BAIjCF,eAAMwB,OAAQC,aAASC,+DAAU,GACpDC,OAAS,WACPC,UAAYF,QAAQE,iBACnBF,QAAQE,gBACTC,UAAYH,QAAQG,iBACnBH,QAAQG,cAGXF,aAAe,6BAAYF,QAASD,OAAQK,UAAWD,UAAWF,SACpE,MAAOI,wBACC,2BAAiBA,WAChB,QAES,MAAhBH,OAAOI,KAAc,OACfC,iBAAmB,kBAAU,gBAAiB,UAAWL,OAAOI,MAChEE,aAAeC,KAAKC,MAAMR,OAAOA,eACnCM,aAAaG,wBACTC,MAAMJ,aAAaG,iBAErBE,WAAWL,aAAaM,QAASP,YAChC,YAEJL,OAAOA,cAGLW,WAAatC,eAAMuC,aAASC,6DAAQ,KAC/B,OAAVA,QACAA,MAAQlC,gBAAgBmC,gBAAgB,uBAEtC,uBAAYD,MAAOD,gEAGCG,qBAEpBC,KAAOC,SAASC,cAAc,eACpCF,KAAKG,UAAYJ,aACVC,KAAKI,uCAGiB9C,QACtBF,YAAYI,eAAeF,gCAGR,CAACA,OAAQ+C,eACnCjD,YAAYE,QAAQ+C,YAAcA,qCAGP/C,QACpBF,YAAYE,QAAQ+C,iCAGH/C,QACjBF,YAAYE,QAAQqB,iCAGArB,QACpBF,YAAYE,QAAQG,sCAGEH,QACtBF,YAAYE,QAAQO,0CAGIP,QACxBF,YAAYE,QAAQS,yCAGCT,QACrBF,YAAYE,QAAQW,0CAGKX,QACzBF,YAAYE,QAAQa,8CAGKb,QACzBF,YAAYE,QAAQe,wCAGDf,QACnBF,YAAYE,QAAQiB,kCAGDjB,QACnBF,YAAYE,QAAQmB,0CAGO6B,SAC3BA,QAAQC,QAAQ,+BAA+BC,QAAQC,kDAG9BC,aAC1BC,kBAAoB,cACRD,MAElBE,UAAUC,UAAUC,MAAM,CAAC,IAAIC,cAAcJ,mDAGdtD,MAAAA,YACzB2D,WAAaC,MAAMC,KACnBC,WAAaH,KAAKG,WACnBJ,cAAcK,SAASD,KAAKE,aACtB,QAGLV,kBAAoB,EACrBQ,KAAKE,MAAOF,aAEjBP,UAAUC,UAAUC,MAAM,CAAC,IAAIC,cAAcJ,sBACtC,SAGEW,aAAe,SAACJ,SAAKK,gEAAW,WACnCC,KAAOvB,SAASC,cAAc,KACpCsB,KAAKC,KAAOP,IACPK,WACDA,SAAWL,IAAIQ,MAAM,KAAKC,OAG9BH,KAAKI,SAAWL,SAChBtB,SAAS4B,KAAKC,YAAYN,MAC1BA,KAAKO,QACL9B,SAAS4B,KAAKG,YAAYR,sEAGKd,aACzBS,KAAO,IAAIc,KAAK,CAACvB,MAAO,CAACW,KAAM,eAC/BH,IAAMgB,IAAIC,gBAAgBhB,MAChCG,aAAaJ,IAAK,gBAClBgB,IAAIE,gBAAgBlB"}
\ No newline at end of file
diff --git a/amd/src/editor_utils.js b/amd/src/editor_utils.js
index c2f58a8..d98433b 100644
--- a/amd/src/editor_utils.js
+++ b/amd/src/editor_utils.js
@@ -54,7 +54,8 @@ export default class {
templateContext: {
classes: 'tiny_ai-modal--dialog',
headerclasses: 'tiny_ai-modal--header'
- }
+ },
+ scrollable: false
});
this.modal.show();
const renderer = getRenderer(this.uniqid);
diff --git a/amd/src/renderer.js b/amd/src/renderer.js
index f8e04b6..3bc36f0 100644
--- a/amd/src/renderer.js
+++ b/amd/src/renderer.js
@@ -26,7 +26,6 @@ import {renderInfoBox} from 'local_ai_manager/infobox';
import {renderUserQuota} from 'local_ai_manager/userquota';
import * as BasedataHandler from 'tiny_ai/datahandler/basedata';
import Templates from 'core/templates';
-import $ from 'jquery';
import {
getEditorUtils,
getDatamanager,
@@ -194,9 +193,6 @@ export default class {
templateContext.tinyinstanceuniqid = this.uniqid;
const modal = getEditorUtils(this.uniqid).getModal();
// Remove all eventually remaining tooltips before rendering a new view.
- document.querySelectorAll('button[data-action]').forEach(button => {
- $(button).tooltip('hide');
- });
const result = await Promise.all([
Templates.renderForPromise('tiny_ai/components/moodle-modal-header-title', templateContext),
Templates.renderForPromise('tiny_ai/components/' + bodyComponentTemplate, templateContext),
@@ -206,12 +202,6 @@ export default class {
// If there is no headline specified, we keep the old one.
modal.setTitle(result[0].html);
}
- // Hide all eventually still existing tooltips first, because they show on 'hover' and
- // 'focus'. So we need to remove them before removing the corresponding buttons from the DOM.
- // Boostrap 4 still using jQuery for tooltips, so we need jQuery here.
- document.querySelectorAll('button[data-action]').forEach(button => {
- $(button).tooltip('hide');
- });
modal.setBody(result[1].html);
modal.setFooter(result[2].html);
result.forEach((item) => {
@@ -220,11 +210,6 @@ export default class {
modal.getRoot().attr('data-tiny_ai_uniqid', this.uniqid);
await this.insertInfoBox();
await this.insertUserQuotaBox();
- document.querySelectorAll('button[data-action]').forEach(button => {
- button.addEventListener('click', event => {
- $(event.target).closest('button[data-action]').tooltip('hide');
- });
- });
}
async insertInfoBox() {
diff --git a/amd/src/utils.js b/amd/src/utils.js
index 37b1785..3868f30 100644
--- a/amd/src/utils.js
+++ b/amd/src/utils.js
@@ -22,7 +22,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-import ModalEvents from 'core/modal_events';
import Renderer from 'tiny_ai/renderer';
import DataManager from 'tiny_ai/datamanager';
import ImggenHandler from 'tiny_ai/datahandler/imggen';
@@ -36,7 +35,6 @@ import {alert as moodleAlert, exception as displayException} from 'core/notifica
import {getString} from 'core/str';
import {makeRequest} from 'local_ai_manager/make_request';
import * as BasedataHandler from 'tiny_ai/datahandler/basedata';
-import $ from 'jquery';
import Log from 'core/log';
const objectStore = {};
@@ -89,12 +87,7 @@ export const errorAlert = async(message, title = null) => {
if (title === null) {
title = BasedataHandler.getTinyAiString('generalerror');
}
- const alertModal = await moodleAlert(title, message);
- alertModal.getRoot().on(ModalEvents.hidden, () => {
- document.querySelectorAll('button[data-action]').forEach(button => {
- $(button).tooltip('hide');
- });
- });
+ await moodleAlert(title, message);
};
export const stripHtmlTags = (textWithTags) => {
diff --git a/scss/partials/ai-modal.scss b/scss/partials/ai-modal.scss
index ec67e61..432dffb 100644
--- a/scss/partials/ai-modal.scss
+++ b/scss/partials/ai-modal.scss
@@ -13,6 +13,7 @@
.modal-content {
border: none;
overflow: visible!important;
+ min-height: 640px;
}
.tiny_ai-modal--header {
diff --git a/styles.css b/styles.css
index 9e1edf4..93009e7 100644
--- a/styles.css
+++ b/styles.css
@@ -266,6 +266,7 @@
.tiny_ai-modal--dialog .modal-content {
border: none;
overflow: visible !important;
+ min-height: 640px;
}
.tiny_ai-modal--dialog .tiny_ai-modal--header {
padding: 24px 24px 16px 24px;
diff --git a/templates/components/ai-button.mustache b/templates/components/ai-button.mustache
index e6cd6b1..89e78bb 100644
--- a/templates/components/ai-button.mustache
+++ b/templates/components/ai-button.mustache
@@ -34,7 +34,7 @@ Example context (json):