AutorÃa | Ultima modificación | Ver Log |
{"version":3,"file":"edit_multiple_grades.min.js","sources":["../src/edit_multiple_grades.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 <http://www.gnu.org/licenses/>.\n\n/**\n * JavaScript for managing multiple grade items for a quiz.\n *\n * @module mod_quiz/edit_multiple_grades\n * @copyright 2023 The Open University\n * @license http://www.gnu.org/copyleft/gpl.html G
NU GPL v3 or later\n */\n\nimport {call as fetchMany} from 'core/ajax';\nimport MoodleConfig from 'core/config';\nimport {addIconToContainer} from 'core/loadingicon';\nimport Notification from 'core/notification';\nimport Pending from 'core/pending';\nimport {get_string as getString} from 'core/str';\nimport {render as renderTemplate} from 'core/templates';\nimport {replaceNode} from 'core/templates';\n\n/**\n * @type {Object} selectors used in this code.\n */\nconst SELECTORS = {\n 'addGradeItemButton': '#mod_quiz-add_grade_item',\n 'autoSetupButton': '#mod_quiz-grades_auto_setup',\n 'editingPageContents': '#edit_grading_page-contents',\n 'gradeItemList': 'table#mod_quiz-grade-item-list',\n 'gradeItemSelect': 'select[data-slot-id]',\n 'gradeItemSelectId': (id) => 'select#grade-item-choice-' + id,\n 'gradeItemTr': 'table#mod_quiz-grade-item-list tr[data-quiz-grade-item-id]',\n 'inplaceEditable': 'span.inplaceeditable',\n 'inplaceEditableOn': 'span.inplaceeditable.inplaceeditingon',
\n 'resetAllButton': '#mod_quiz-grades_reset_all',\n 'slotList': 'table#mod_quiz-slot-list',\n 'updateGradeItemLink': (id) => 'tr[data-quiz-grade-item-id=\"' + id + '\"] .quickeditlink',\n};\n\n/**\n * Call the Ajax service to create a quiz grade item.\n *\n * @param {Number} quizId id of the quiz to update.\n * @returns {Promise<Object>} a promise that resolves to the template context required to re-render the page.\n */\nconst createGradeItem = (\n quizId,\n) => callServiceAndReturnRenderingData({\n methodname: 'mod_quiz_create_grade_items',\n args: {\n quizid: quizId,\n quizgradeitems: [{name: ''}],\n }\n});\n\n/**\n * Call the Ajax service to update a quiz grade item.\n *\n * @param {Number} quizId id of the quiz to update.\n * @param {Number} gradeItemId id of the grade item to update.\n * @param {String} newName the new name to set.\n * @return {Promise} Promise that resolves to the context required to re-render the page.\n */\nconst updateGradeItem = (\n quizId,\n
gradeItemId,\n newName\n) => callServiceAndReturnRenderingData({\n methodname: 'mod_quiz_update_grade_items',\n args: {\n quizid: quizId,\n quizgradeitems: [{id: gradeItemId, name: newName}],\n }\n});\n\n/**\n * Call the Ajax service to delete a quiz grade item.\n *\n * @param {Number} quizId id of the quiz to update.\n * @param {Number} gradeItemId id of the grade item to delete.\n * @return {Promise} Promise that resolves to the context required to re-render the page.\n */\nconst deleteGradeItem = (\n quizId,\n gradeItemId\n) => callServiceAndReturnRenderingData({\n methodname: 'mod_quiz_delete_grade_items',\n args: {\n quizid: quizId,\n quizgradeitems: [{id: gradeItemId}],\n }\n});\n\n/**\n * Call the Ajax service to update the quiz grade item used by a slot.\n *\n * @param {Number} quizId id of the quiz to update.\n * @param {Number} slotId id of the slot to update.\n * @param {Number|null} gradeItemId new grade item ot set, or null to un-set.\n
* @return {Promise} Promise that resolves to the context required to re-render the page.\n */\nconst updateSlotGradeItem = (\n quizId,\n slotId,\n gradeItemId\n) => callServiceAndReturnRenderingData({\n methodname: 'mod_quiz_update_slots',\n args: {\n quizid: quizId,\n slots: [{id: slotId, quizgradeitemid: gradeItemId}],\n }\n});\n\n/**\n * Call the Ajax service to setup one grade item for each quiz section.\n *\n * @param {Number} quizId id of the quiz to update.\n * @return {Promise} Promise that resolves to the context required to re-render the page.\n */\nconst autoSetupGradeItems = (\n quizId\n) => callServiceAndReturnRenderingData({\n methodname: 'mod_quiz_create_grade_item_per_section',\n args: {\n quizid: quizId\n }\n});\n\n/**\n * Make a web service call, and also call mod_quiz_get_edit_grading_page_data to get the date to re-render the page.\n *\n * @param {Object} methodCall a web service call to pass to fetchMany. Must include methodCall.args.qui
zid.\n * @returns {Promise<Object>} a promise that resolves to the template context required to re-render the page.\n */\nconst callServiceAndReturnRenderingData = (methodCall) => callServicesAndReturnRenderingData([methodCall]);\n\n/**\n * Make a web service call, and also call mod_quiz_get_edit_grading_page_data to get the date to re-render the page.\n *\n * @param {Object[]} methodCalls web service calls to pass to fetchMany. Must include methodCalls[0].args.quizid.\n * @returns {Promise<Object>} a promise that resolves to the template context required to re-render the page.\n */\nconst callServicesAndReturnRenderingData = (methodCalls) => {\n methodCalls.push({\n methodname: 'mod_quiz_get_edit_grading_page_data',\n args: {\n quizid: methodCalls[0].args.quizid,\n }\n });\n return Promise.all(fetchMany(methodCalls))\n .then(results => JSON.parse(results.at(-1)));\n};\n\n/**\n * Handle click events on the delete icon.\n *\n * @param {Event} e c
lick event.\n */\nconst handleGradeItemDelete = (e) => {\n e.preventDefault();\n const pending = new Pending('delete-quiz-grade-item');\n\n const tableCell = e.target.closest('td');\n addIconToContainer(tableCell, pending);\n\n const tableRow = tableCell.closest('tr');\n const quizId = tableRow.closest('table').dataset.quizId;\n const gradeItemId = tableRow.dataset.quizGradeItemId;\n\n let nextItemToFocus;\n if (tableRow.nextElementSibling) {\n nextItemToFocus = SELECTORS.updateGradeItemLink(tableRow.nextElementSibling.dataset.quizGradeItemId);\n } else {\n nextItemToFocus = SELECTORS.addGradeItemButton;\n }\n\n deleteGradeItem(quizId, gradeItemId)\n .then(reRenderPage)\n .then(() => {\n pending.resolve();\n document.querySelector(nextItemToFocus).focus();\n })\n .catch(Notification.exception);\n};\n\n/**\n *\n * @param {HTMLElement} editableSpan the editable to turn off.\n */\nconst stopEditingGadeItem = (edi
tableSpan) => {\n editableSpan.innerHTML = editableSpan.dataset.oldContent;\n delete editableSpan.dataset.oldContent;\n\n editableSpan.classList.remove('inplaceeditingon');\n editableSpan.querySelector('[data-action-edit]').focus();\n};\n\n/**\n * Handle click events on the start rename icon.\n *\n * @param {Event} e click event.\n */\nconst handleGradeItemEditStart = (e) => {\n e.preventDefault();\n const pending = new Pending('edit-quiz-grade-item-start');\n const editableSpan = e.target.closest(SELECTORS.inplaceEditable);\n\n document.querySelectorAll(SELECTORS.inplaceEditableOn).forEach(stopEditingGadeItem);\n\n editableSpan.dataset.oldContent = editableSpan.innerHTML;\n getString('edittitleinstructions')\n .then((instructions) => {\n const uniqueId = 'gi-edit-input-' + editableSpan.closest('tr').dataset.quizGradeItemId;\n editableSpan.innerHTML = '<span class=\"editinstructions\">' + instructions + '</span>' +\n '<label class=
\"sr-only\" for=\"' + uniqueId + '\">' + editableSpan.dataset.editLabel + '</label>' +\n '<input type=\"text\" id=\"' + uniqueId + '\" value=\"' + editableSpan.dataset.rawName +\n '\" class=\"ignoredirty form-control w-100\">';\n\n const inputElement = editableSpan.querySelector('input');\n inputElement.focus();\n inputElement.select();\n editableSpan.classList.add('inplaceeditingon');\n pending.resolve();\n return null;\n })\n .catch(Notification.exception);\n};\n\n/**\n * Handle key down in the editable.\n *\n * @param {Event} e key event.\n */\nconst handleGradeItemKeyDown = (e) => {\n if (e.keyCode !== 13) {\n return;\n }\n\n const editableSpan = e.target.closest(SELECTORS.inplaceEditableOn);\n\n // Check this click is on a relevant element.\n if (!editableSpan || !editableSpan.closest(SELECTORS.gradeItemList)) {\n return;\n }\n\n e.preventDefaul
t();\n const pending = new Pending('edit-quiz-grade-item-save');\n\n const newName = editableSpan.querySelector('input').value;\n const tableCell = e.target.closest('th');\n addIconToContainer(tableCell);\n\n const tableRow = tableCell.closest('tr');\n const quizId = tableRow.closest('table').dataset.quizId;\n const gradeItemId = tableRow.dataset.quizGradeItemId;\n\n updateGradeItem(quizId, gradeItemId, newName)\n .then(reRenderPage)\n .then(() => {\n pending.resolve();\n document.querySelector(SELECTORS.updateGradeItemLink(gradeItemId)).focus({'focusVisible': true});\n })\n .catch(Notification.exception);\n};\n\n/**\n * Replace the contents of the page with the page re-rendered from the provided data, once that promise resolves.\n *\n * @param {Object} editGradingPageData the template context data required to re-render the page.\n * @returns {Promise<void>} a promise that will resolve when the page is updated.\n */\nconst reRenderPage
= (editGradingPageData) =>\n renderTemplate('mod_quiz/edit_grading_page', editGradingPageData)\n .then((html, js) => replaceNode(document.querySelector(SELECTORS.editingPageContents), html, js || ''));\n\n/**\n * Handle key up in the editable.\n *\n * @param {Event} e key event.\n */\nconst handleGradeItemKeyUp = (e) => {\n if (e.keyCode !== 27) {\n return;\n }\n\n const editableSpan = e.target.closest(SELECTORS.inplaceEditableOn);\n\n // Check this click is on a relevant element.\n if (!editableSpan || !editableSpan.closest(SELECTORS.gradeItemList)) {\n return;\n }\n\n e.preventDefault();\n stopEditingGadeItem(editableSpan);\n};\n\n/**\n * Handle focus out of the editable.\n *\n * @param {Event} e event.\n */\nconst handleGradeItemFocusOut = (e) => {\n if (MoodleConfig.behatsiterunning) {\n // Behat triggers focusout too often so ignore.\n return;\n }\n\n const editableSpan = e.target.closest(SELECTORS.inplaceEditableOn);\n\n // Chec
k this click is on a relevant element.\n if (!editableSpan || !editableSpan.closest(SELECTORS.gradeItemList)) {\n return;\n }\n\n e.preventDefault();\n stopEditingGadeItem(editableSpan);\n};\n\n/**\n * Handle when the selected grade item for a slot is changed.\n *\n * @param {Event} e event.\n */\nconst handleSlotGradeItemChanged = (e) => {\n const select = e.target.closest(SELECTORS.gradeItemSelect);\n\n // Check this click is on a relevant element.\n if (!select || !select.closest(SELECTORS.slotList)) {\n return;\n }\n\n e.preventDefault();\n const pending = new Pending('edit-slot-grade-item-updated');\n\n const slotId = select.dataset.slotId;\n const newGradeItemId = select.value ? select.value : null;\n const tableCell = e.target.closest('td');\n addIconToContainer(tableCell, pending);\n\n const quizId = tableCell.closest('table').dataset.quizId;\n\n updateSlotGradeItem(quizId, slotId, newGradeItemId)\n .then(reRenderPage)\n .the
n(() => {\n pending.resolve();\n document.querySelector(SELECTORS.gradeItemSelectId(slotId)).focus();\n })\n .catch(Notification.exception);\n};\n\n/**\n * Handle clicks in the table the shows the grade items.\n *\n * @param {Event} e click event.\n */\nconst handleGradeItemClick = (e) => {\n const link = e.target.closest('a');\n\n // Check this click is on a relevant element.\n if (!link || !link.closest(SELECTORS.gradeItemList)) {\n return;\n }\n\n if (link.dataset.actionDelete) {\n handleGradeItemDelete(e);\n }\n\n if (link.dataset.actionEdit) {\n handleGradeItemEditStart(e);\n }\n};\n\n/**\n * Handle clicks on the buttons.\n *\n * @param {Event} e click event.\n */\n\nconst handleButtonClick = (e) => {\n if (e.target.closest(SELECTORS.addGradeItemButton)) {\n handleAddGradeItemClick(e);\n }\n if (e.target.closest(SELECTORS.autoSetupButton)) {\n handleAutoSetup(e);\n }\n if (e.target.closest(SELEC
TORS.resetAllButton)) {\n handleResetAllClick(e);\n }\n};\n\n/**\n * Handle clicks on the 'Add grade item' button.\n *\n * @param {Event} e click event.\n */\nconst handleAddGradeItemClick = (e) => {\n e.preventDefault();\n const pending = new Pending('create-quiz-grade-item');\n addIconToContainer(e.target.parentNode, pending);\n\n const quizId = e.target.dataset.quizId;\n\n createGradeItem(quizId)\n .then(reRenderPage)\n .then(() => {\n pending.resolve();\n document.querySelector(SELECTORS.addGradeItemButton).focus();\n })\n .catch(Notification.exception);\n};\n\n/**\n * Handle clicks on the reset button - show a confirmation.\n *\n * @param {Event} e click event.\n */\nconst handleAutoSetup = (e) => {\n e.preventDefault();\n const pending = new Pending('setup-quiz-grade-items');\n\n const quizId = e.target.dataset.quizId;\n\n autoSetupGradeItems(quizId)\n .then(reRenderPage)\n .then(() => {\n pe
nding.resolve();\n document.querySelector(SELECTORS.resetAllButton).focus();\n })\n .catch(Notification.exception);\n};\n\n/**\n * Handle clicks on the reset button - show a confirmation.\n *\n * @param {Event} e click event.\n */\nconst handleResetAllClick = (e) => {\n e.preventDefault();\n const button = e.target;\n\n Notification.deleteCancelPromise(\n getString('gradeitemsremoveallconfirm', 'quiz'),\n getString('gradeitemsremoveallmessage', 'quiz'),\n getString('reset'),\n button\n ).then(() => reallyResetAll(button))\n .catch(() => button.focus());\n};\n\n/**\n * Really reset all if the confirmation is OKed.\n *\n * @param {HTMLElement} button the reset button.\n */\nconst reallyResetAll = (button) => {\n const pending = new Pending('reset-quiz-grading');\n addIconToContainer(button.parentNode, pending);\n\n const quizId = button.dataset.quizId;\n\n let methodCalls = [];\n\n // Call to clear any assignments of grade items
to slots (if required).\n const slotResets = [...document.querySelectorAll(SELECTORS.gradeItemSelect)].map(\n (select) => ({\n id: select.dataset.slotId,\n quizgradeitemid: 0,\n }));\n if (slotResets.length) {\n methodCalls.push({\n methodname: 'mod_quiz_update_slots',\n args: {\n quizid: quizId,\n slots: slotResets\n }\n });\n }\n\n // Request to delete all the grade items.\n methodCalls.push({\n methodname: 'mod_quiz_delete_grade_items',\n args: {\n quizid: quizId,\n quizgradeitems: [...document.querySelectorAll(SELECTORS.gradeItemTr)].map((tr) => {\n return {id: tr.dataset.quizGradeItemId};\n })\n }\n });\n\n callServicesAndReturnRenderingData(methodCalls)\n .then(reRenderPage)\n .then(() => {\n pending.resolve();\n document.querySelector(SELECTORS.addGr
adeItemButton).focus();\n })\n .catch(Notification.exception);\n};\n\n/**\n * Replace the container with a new version.\n */\nconst registerEventListeners = () => {\n document.body.addEventListener('click', handleGradeItemClick);\n document.body.addEventListener('keydown', handleGradeItemKeyDown);\n document.body.addEventListener('keyup', handleGradeItemKeyUp);\n document.body.addEventListener('focusout', handleGradeItemFocusOut);\n\n document.body.addEventListener('click', handleButtonClick);\n\n document.body.addEventListener('change', handleSlotGradeItemChanged);\n};\n\n/**\n * Entry point.\n */\nexport const init = () => {\n registerEventListeners();\n};\n"],"names":["SELECTORS","id","callServiceAndReturnRenderingData","methodCall","callServicesAndReturnRenderingData","methodCalls","push","methodname","args","quizid","Promise","all","then","results","JSON","parse","at","handleGradeItemDelete","e","preventDefault","pending","Pending","tableCell","target","closest","table
Row","quizId","dataset","gradeItemId","quizGradeItemId","nextItemToFocus","nextElementSibling","quizgradeitems","deleteGradeItem","reRenderPage","resolve","document","querySelector","focus","catch","Notification","exception","stopEditingGadeItem","editableSpan","innerHTML","oldContent","classList","remove","handleGradeItemKeyDown","keyCode","newName","value","name","updateGradeItem","editGradingPageData","html","js","handleGradeItemKeyUp","handleGradeItemFocusOut","MoodleConfig","behatsiterunning","handleSlotGradeItemChanged","select","slotId","newGradeItemId","slots","quizgradeitemid","updateSlotGradeItem","handleGradeItemClick","link","actionDelete","actionEdit","querySelectorAll","forEach","instructions","uniqueId","editLabel","rawName","inputElement","add","handleGradeItemEditStart","handleButtonClick","handleAddGradeItemClick","handleAutoSetup","handleResetAllClick","parentNode","createGradeItem","autoSetupGradeItems","button","deleteCancelPromise","reallyResetAll","slotResets","map","length","tr","body
","addEventListener"],"mappings":";;;;;;;8NAmCMA,6BACoB,2BADpBA,0BAEiB,8BAFjBA,8BAGqB,8BAHrBA,wBAIe,iCAJfA,0BAKiB,uBALjBA,4BAMoBC,IAAO,4BAA8BA,GANzDD,sBAOa,6DAPbA,0BAQiB,uBARjBA,4BASmB,wCATnBA,yBAUgB,6BAVhBA,mBAWU,2BAXVA,8BAYsBC,IAAO,+BAAiCA,GAAK,oBAkGnEC,kCAAqCC,YAAeC,mCAAmC,CAACD,aAQxFC,mCAAsCC,cACxCA,YAAYC,KAAK,CACTC,WAAY,sCACZC,KAAM,CACFC,OAAQJ,YAAY,GAAGG,KAAKC,UAGjCC,QAAQC,KAAI,cAAUN,cAC5BO,MAAKC,SAAWC,KAAKC,MAAMF,QAAQG,IAAI,OAQtCC,sBAAyBC,IAC3BA,EAAEC,uBACIC,QAAU,IAAIC,iBAAQ,0BAEtBC,UAAYJ,EAAEK,OAAOC,QAAQ,0CAChBF,UAAWF,eAExBK,SAAWH,UAAUE,QAAQ,MAC7BE,OAASD,SAASD,QAAQ,SAASG,QAAQD,OAC3CE,YAAcH,SAASE,QAAQE,oBAEjCC,gBAEAA,gBADAL,SAASM,mBACS/B,8BAA8ByB,SAASM,mBAAmBJ,QAAQE,iBAElE7B,6BA3FF,EACpB0B,OACAE,cACC1B,kCAAkC,CACnCK,WAAY,8BACZC,KAAM,CACFC,OAAQiB,OACRM,eAAgB,CAAC,CAAC/B,GAAI2B,iBAuF1BK,CAAgBP,OAAQE,aACnBhB,KAAKsB,cACLtB,MAAK,KACFQ,QAAQe,UACRC,SAASC,cAAcP,iBAAiBQ,WAE3CC,MAAMC,sBAAaC,YAOtBC,oBAAuBC,eACzBA,aAAaC,UAAYD,aAAahB,QAAQkB,kBACvCF,aAAahB,QAAQkB,WAE5BF,aAAaG,UAAUC,OAAO,oBAC9BJ,aAAaN,cAAc,sBAAsBC,SA
uC/CU,uBAA0B9B,OACV,KAAdA,EAAE+B,qBAIAN,aAAezB,EAAEK,OAAOC,QAAQxB,iCAGjC2C,eAAiBA,aAAanB,QAAQxB,gCAI3CkB,EAAEC,uBACIC,QAAU,IAAIC,iBAAQ,6BAEtB6B,QAAUP,aAAaN,cAAc,SAASc,MAC9C7B,UAAYJ,EAAEK,OAAOC,QAAQ,0CAChBF,iBAEbG,SAAWH,UAAUE,QAAQ,MAC7BE,OAASD,SAASD,QAAQ,SAASG,QAAQD,OAC3CE,YAAcH,SAASE,QAAQE,gBA/LjB,EACpBH,OACAE,YACAsB,UACChD,kCAAkC,CACnCK,WAAY,8BACZC,KAAM,CACFC,OAAQiB,OACRM,eAAgB,CAAC,CAAC/B,GAAI2B,YAAawB,KAAMF,aAyL7CG,CAAgB3B,OAAQE,YAAasB,SAChCtC,KAAKsB,cACLtB,MAAK,KACFQ,QAAQe,UACRC,SAASC,cAAcrC,8BAA8B4B,cAAcU,MAAM,eAAiB,OAE7FC,MAAMC,sBAAaC,YAStBP,aAAgBoB,sBAClB,qBAAe,6BAA8BA,qBACxC1C,MAAK,CAAC2C,KAAMC,MAAO,0BAAYpB,SAASC,cAAcrC,+BAAgCuD,KAAMC,IAAM,MAOrGC,qBAAwBvC,OACR,KAAdA,EAAE+B,qBAIAN,aAAezB,EAAEK,OAAOC,QAAQxB,6BAGjC2C,cAAiBA,aAAanB,QAAQxB,2BAI3CkB,EAAEC,iBACFuB,oBAAoBC,gBAQlBe,wBAA2BxC,OACzByC,gBAAaC,8BAKXjB,aAAezB,EAAEK,OAAOC,QAAQxB,6BAGjC2C,cAAiBA,aAAanB,QAAQxB,2BAI3CkB,EAAEC,iBACFuB,oBAAoBC,gBAQlBkB,2BAA8B3C,UAC1B4C,OAAS5C,EAAEK,OAAOC,QAAQxB,+BAG3B8D,SAAWA,OAAOtC,QAAQxB,2BAI/BkB,EAAEC,uBACIC,QAAU,IAAI
C,iBAAQ,gCAEtB0C,OAASD,OAAOnC,QAAQoC,OACxBC,eAAiBF,OAAOX,MAAQW,OAAOX,MAAQ,KAC/C7B,UAAYJ,EAAEK,OAAOC,QAAQ,0CAChBF,UAAWF,SA5ON,EACxBM,OACAqC,OACAnC,cACC1B,kCAAkC,CACnCK,WAAY,wBACZC,KAAM,CACFC,OAAQiB,OACRuC,MAAO,CAAC,CAAChE,GAAI8D,OAAQG,gBAAiBtC,iBAwO1CuC,CAFe7C,UAAUE,QAAQ,SAASG,QAAQD,OAEtBqC,OAAQC,gBAC/BpD,KAAKsB,cACLtB,MAAK,KACFQ,QAAQe,UACRC,SAASC,cAAcrC,4BAA4B+D,SAASzB,WAE/DC,MAAMC,sBAAaC,YAQtB2B,qBAAwBlD,UACpBmD,KAAOnD,EAAEK,OAAOC,QAAQ,KAGzB6C,MAASA,KAAK7C,QAAQxB,2BAIvBqE,KAAK1C,QAAQ2C,cACbrD,sBAAsBC,GAGtBmD,KAAK1C,QAAQ4C,YArKarD,CAAAA,IAC9BA,EAAEC,uBACIC,QAAU,IAAIC,iBAAQ,8BACtBsB,aAAezB,EAAEK,OAAOC,QAAQxB,2BAEtCoC,SAASoC,iBAAiBxE,6BAA6ByE,QAAQ/B,qBAE/DC,aAAahB,QAAQkB,WAAaF,aAAaC,8BACrC,yBACLhC,MAAM8D,qBACGC,SAAW,iBAAmBhC,aAAanB,QAAQ,MAAMG,QAAQE,gBACvEc,aAAaC,UAAY,kCAAoC8B,aAApC,sCACgBC,SAAW,KAAOhC,aAAahB,QAAQiD,UADvD,kCAEWD,SAAW,YAAchC,aAAahB,QAAQkD,QAClE,kDAEVC,aAAenC,aAAaN,cAAc,gBAChDyC,aAAaxC,QACbwC,aAAahB,SACbnB,aAAaG,UAAUiC,IAAI,oBAC3B3D,QAAQe,UACD,QAEVI,MAAMC,sBAAaC,YA+IpBuC,CAAyB9D,KAU3B+D,kBAAqB/D,
IACnBA,EAAEK,OAAOC,QAAQxB,+BACjBkF,wBAAwBhE,GAExBA,EAAEK,OAAOC,QAAQxB,4BACjBmF,gBAAgBjE,GAEhBA,EAAEK,OAAOC,QAAQxB,2BACjBoF,oBAAoBlE,IAStBgE,wBAA2BhE,IAC7BA,EAAEC,uBACIC,QAAU,IAAIC,iBAAQ,8DACTH,EAAEK,OAAO8D,WAAYjE,SAhWxCM,CAAAA,QACCxB,kCAAkC,CACnCK,WAAY,8BACZC,KAAM,CACFC,OAAQiB,OACRM,eAAgB,CAAC,CAACoB,KAAM,QA+V5BkC,CAFepE,EAAEK,OAAOI,QAAQD,QAG3Bd,KAAKsB,cACLtB,MAAK,KACFQ,QAAQe,UACRC,SAASC,cAAcrC,8BAA8BsC,WAExDC,MAAMC,sBAAaC,YAQtB0C,gBAAmBjE,IACrBA,EAAEC,uBACIC,QAAU,IAAIC,iBAAQ,0BA1S5BK,CAAAA,QACCxB,kCAAkC,CACnCK,WAAY,yCACZC,KAAM,CACFC,OAAQiB,UA0SZ6D,CAFerE,EAAEK,OAAOI,QAAQD,QAG3Bd,KAAKsB,cACLtB,MAAK,KACFQ,QAAQe,UACRC,SAASC,cAAcrC,0BAA0BsC,WAEpDC,MAAMC,sBAAaC,YAQtB2C,oBAAuBlE,IACzBA,EAAEC,uBACIqE,OAAStE,EAAEK,6BAEJkE,qBACT,mBAAU,6BAA8B,SACxC,mBAAU,6BAA8B,SACxC,mBAAU,SACVD,QACF5E,MAAK,IAAM8E,eAAeF,UAC3BjD,OAAM,IAAMiD,OAAOlD,WAQlBoD,eAAkBF,eACdpE,QAAU,IAAIC,iBAAQ,0DACTmE,OAAOH,WAAYjE,eAEhCM,OAAS8D,OAAO7D,QAAQD,WAE1BrB,YAAc,SAGZsF,WAAa,IAAIvD,SAASoC,iBAAiBxE,4BAA4B4F,KACpE9B,UACG7D,GAAI6D,OAAOnC,QAAQoC,OACnBG,gBA
AiB,MAEzByB,WAAWE,QACXxF,YAAYC,KAAK,CACbC,WAAY,wBACZC,KAAM,CACFC,OAAQiB,OACRuC,MAAO0B,cAMnBtF,YAAYC,KAAK,CACbC,WAAY,8BACZC,KAAM,CACFC,OAAQiB,OACRM,eAAgB,IAAII,SAASoC,iBAAiBxE,wBAAwB4F,KAAKE,KAChE,CAAC7F,GAAI6F,GAAGnE,QAAQE,uBAKnCzB,mCAAmCC,aAC9BO,KAAKsB,cACLtB,MAAK,KACFQ,QAAQe,UACRC,SAASC,cAAcrC,8BAA8BsC,WAExDC,MAAMC,sBAAaC,0BAoBR,KAbhBL,SAAS2D,KAAKC,iBAAiB,QAAS5B,sBACxChC,SAAS2D,KAAKC,iBAAiB,UAAWhD,wBAC1CZ,SAAS2D,KAAKC,iBAAiB,QAASvC,sBACxCrB,SAAS2D,KAAKC,iBAAiB,WAAYtC,yBAE3CtB,SAAS2D,KAAKC,iBAAiB,QAASf,mBAExC7C,SAAS2D,KAAKC,iBAAiB,SAAUnC"}