From 84190ed9f1b6aba8e7b1ebaf53d24bcde14d7936 Mon Sep 17 00:00:00 2001 From: Tsanie Date: Mon, 28 Aug 2023 15:04:23 +0800 Subject: [PATCH] sync --- lib/app.js | 4 +- lib/app/communications/comments.js | 162 +++++ lib/app/communications/contact.js | 52 +- lib/app/communications/customer.d.ts | 2 +- lib/app/communications/customer.js | 168 +++-- lib/app/communications/follower.js | 28 +- lib/app/communications/internal.js | 52 +- lib/app/communications/lib.js | 67 +- lib/ui/css/media.scss | 8 + lib/utility.js | 3 +- lib/utility/lgres.js | 3 +- lib/utility/strings.d.ts | 3 +- lib/utility/strings.js | 12 + package-lock.json | 967 ++++++++++++++++----------- 14 files changed, 1004 insertions(+), 527 deletions(-) create mode 100644 lib/app/communications/comments.js diff --git a/lib/app.js b/lib/app.js index cb0b66b..d2c7480 100644 --- a/lib/app.js +++ b/lib/app.js @@ -1,8 +1,10 @@ import "./app/communications/style.scss"; import CustomerCommunication from "./app/communications/customer"; import InternalComment from "./app/communications/internal"; +import CustomerRecordComment from "./app/communications/comments"; export { CustomerCommunication, - InternalComment + InternalComment, + CustomerRecordComment } \ No newline at end of file diff --git a/lib/app/communications/comments.js b/lib/app/communications/comments.js new file mode 100644 index 0000000..7b5fad7 --- /dev/null +++ b/lib/app/communications/comments.js @@ -0,0 +1,162 @@ +import { createElement, setTooltip, createIcon } from "../../ui"; +import { r as lang, nullOrEmpty, escapeHtml, escapeEmoji } from "../../utility"; +import { createBox, appendMedia } from "./lib"; + +let r = lang; + +export default class CustomerRecordComment { + #container; + #option; + #enter; + #message; + + constructor(opt) { + this.#option = opt ?? {}; + const getText = opt?.getText; + if (typeof getText === 'function') { + r = getText; + } + } + + get text() { return this.#enter?.value } + set text(s) { + const element = this.#enter; + if (element != null) { + element.value = s + s = String(nullOrEmpty(s) ? 0 : val.length) + '/' + String(this.#option.maxLength); + this.#container.querySelector('.message-bar .prompt-count').innerText = s; + } + } + + /** + * @param {boolean} flag + */ + set loading(flag) { + if (this.#container == null) { + return; + } + this.#enter.disabled = flag; + this.#container.querySelector('.button-send-message').disabled = flag; + } + + /** + * @param {boolean} flag + */ + set readonly(flag) { + this.#option.readonly = flag; + if (this.#container == null) { + return; + } + this.#enter.disabled = flag === true; + this.#container.querySelector('.button-send-message').style.display = flag === true ? 'none' : ''; + this.#container.querySelector('.message-bar .prompt-count').style.display = flag === true ? 'none' : ''; + } + + create() { + const readonly = this.#option.readonly; + const container = createBox( + createElement('div', null, + createElement('div', div => { + div.className = 'title-module'; + div.innerText = r('P_CR_COMMENTS', 'Comments'); + }) + ), + [ + createElement('button', button => { + button.className = 'roundbtn button-close'; + button.style.backgroundColor = 'transparent'; + if (this.#option.hasClose !== true) { + button.style.display = 'none'; + return; + } + button.appendChild(createIcon('fa-solid', 'times', { + fill: '#000' + })); + button.addEventListener('click', () => { + if (typeof this.#option.onClose === 'function') { + this.#option.onClose(); + } + }) + }) + ] + ); + // enter box + const enter = createElement('textarea', 'ui-text'); + enter.placeholder = r('P_CU_ENTERCOMMENTHERE', 'Enter Comment Here'); + enter.maxLength = this.#option.maxLength ??= 3000; + enter.addEventListener('input', () => { + const val = this.text; + const s = String(nullOrEmpty(val) ? 0 : val.length) + '/' + String(this.#option.maxLength); + this.#container.querySelector('.message-bar .prompt-count').innerText = s; + }); + if (readonly === true) { + enter.disabled = true; + } + this.#enter = enter; + container.appendChild( + createElement('div', 'message-bar', + enter, + createElement('div', div => div.style.textAlign = 'right', + createElement('div', 'prompt-count'), + createElement('button', button => { + button.className = 'roundbtn button-send-message'; + button.style.backgroundColor = 'rgb(19, 150, 204)'; + if (readonly === true) { + button.style.display = 'none'; + } + button.appendChild(createIcon('fa-solid', 'paper-plane')); + // setTooltip(button, r('P_M3_SENDMESSAGE', 'Send Message')); + setTooltip(button, r('P_CU_POSTNOTE', 'Post Note')); + button.addEventListener('click', () => { + if (typeof this.#option.onAddComment === 'function') { + this.#option.onAddComment(this.text); + } + }) + }) + ) + ) + ); + + const message = createElement('div', 'list-bar'); + this.#message = message; + container.appendChild(message); + return this.#container = container; + } + + load(data) { + const children = []; + if (data?.length > 0) { + for (let comment of data) { + const div = createElement('div', 'item-div'); + // if (sendto !== '') { + // sendto = r('P_CU_SENDTO_COLON', 'Send To :') + `\n${sendto}`; + // } + div.appendChild(createElement('div', div => { + div.className = 'item-poster'; + div.innerText = comment.UserName; + })); + const content = createElement('div', 'item-content'); + const mmsParts = createElement('div', div => div.style.display = 'none'); + content.appendChild(createElement('span', span => span.innerHTML = escapeEmoji(escapeHtml(comment.Comment)), mmsParts)); + if (comment.IsMMS && comment.MMSParts?.length > 0) { + mmsParts.style.display = ''; + for (let kv of comment.MMSParts) { + appendMedia(mmsParts, kv.Key, kv.Value); + } + } + div.append( + content, + createElement('div', div => { + div.className = 'item-time'; + div.innerText = comment.SubmitLocalDateStr; + }) + ); + children.push(div); + } + children[0].style.marginTop = '0'; + } + this.#message.replaceChildren(...children); + this.#message.scrollTop = this.#message.scrollHeight + // setTimeout(() => this.#message.scrollTop = this.#message.scrollHeight, 0); + } +} \ No newline at end of file diff --git a/lib/app/communications/contact.js b/lib/app/communications/contact.js index 5766087..e5e7fe8 100644 --- a/lib/app/communications/contact.js +++ b/lib/app/communications/contact.js @@ -1,5 +1,7 @@ import { Grid, Dropdown, createElement, createCheckbox, Popup, showAlert } from "../../ui"; -import { isEmail, nullOrEmpty, r } from "../../utility"; +import { isEmail, nullOrEmpty, r as lang } from "../../utility"; + +let r = lang; export class Contact { #option; @@ -7,6 +9,10 @@ export class Contact { constructor(option = {}) { this.#option = option; + const getText = option?.getText; + if (typeof getText === 'function') { + r = getText; + } } async show(parent = document.body) { @@ -22,9 +28,9 @@ export class Contact { }); const preferences = new Dropdown({ tabIndex: tabIndex + 2 }); preferences.source = [ - { value: '0', text: r('text', 'Text') }, - { value: '1', text: r('email', 'Email') }, - { value: '2', text: r('phone', 'Phone') } + { value: '0', text: r('P_CR_TEXT', 'Text') }, + { value: '1', text: r('P_CR_EMAIL', 'Email') }, + { value: '2', text: r('P_CR_PHONE', 'Phone') } ]; const contactEmail = createElement('input', input => { input.type = 'email'; @@ -50,7 +56,7 @@ export class Contact { const buttons = []; if (this.#option.company) { buttons.push({ - text: c == null ? r('addContactRecord', 'Add Contact Record') : r('editContactRecord', 'Edit Contact Record'), + text: c == null ? r('P_WO_ADDCONTACTRECORD', 'Add Contact Record') : r('P_WO_EDITCONTACTRECORD', 'Edit Contact Record'), // tabIndex: tabIndex + 7, trigger: () => { const item = this.prepare(); @@ -66,7 +72,7 @@ export class Contact { } buttons.push( { - text: r('workOrderOnly', 'Work Order Only'), + text: r('P_WO_WORKORDERONLY', 'Work Order Only'), // tabIndex: tabIndex + 8, trigger: () => { const item = this.prepare(); @@ -81,39 +87,39 @@ export class Contact { } }, { - text: r('cancel', 'Cancel'), + text: r('P_WO_CANCEL', 'Cancel'), // tabIndex: tabIndex + 9 } ); const popup = new Popup({ onMasking: this.#option.onMasking, - title: c == null ? r('addContact', 'Add Contact') : r('editContact', 'Edit Contact'), + title: c == null ? r('P_CR_ADDCONTACT', 'Add Contact') : r('P_CR_EDITCONTACT', 'Edit Contact'), content: createElement('div', wrapper => { wrapper.className = 'setting-wrapper'; wrapper.style.width = '500px'; }, createElement('div', 'setting-item', - createElement('span', 'setting-label setting-required', r('contactNameColon', 'Contact Name:')), + createElement('span', 'setting-label setting-required', r('P_CR_CONTACTNAME_COLON', 'Contact Name:')), contactName ), createElement('div', 'setting-item', - createElement('span', 'setting-label', r('contactPreferencesColon', 'Contact Preferences:')), + createElement('span', 'setting-label', r('P_CR_CONTACTPREFERENCES_COLON', 'Contact Preferences:')), preferences.create() ), createElement('div', 'setting-item', - createElement('span', 'setting-label', r('contactEmailColon', 'Email Address:')), + createElement('span', 'setting-label', r('P_CR_EMAILADDRESS_COLON', 'Email Address:')), contactEmail ), createElement('div', 'setting-item', - createElement('span', 'setting-label', r('contactMobileColon', 'Mobile:')), + createElement('span', 'setting-label', r('P_WO_MOBILE_COLON', 'Mobile:')), contactMobile ), createElement('div', 'setting-item', - createElement('span', 'setting-label', r('contactOptColon', 'Opt Out:')), + createElement('span', 'setting-label', r('P_CR_OPTOUT_COLON', 'Opt Out:')), checkOpt ), createElement('div', 'setting-item', - createElement('span', 'setting-label', r('contactNotesColon', 'Notes:')), + createElement('span', 'setting-label', r('P_CR_NOTES_COLON', 'Notes:')), contactNotes ) ), @@ -149,24 +155,24 @@ export class Contact { const phone = this.#refs.contactMobile.value; const opt = this.#refs.checkOpt.querySelector('input').checked; const notes = this.#refs.contactNotes.value; - const title = this.#option.contact == null ? r('addContact', 'Add Contact') : r('editContact', 'Edit Contact'); + const title = this.#option.contact == null ? r('P_CR_ADDCONTACT', 'Add Contact') : r('P_CR_EDITCONTACT', 'Edit Contact'); if (nullOrEmpty(name)) { - showAlert(title, r('contactNameRequired', 'Contact Name cannot be empty.'), 'warn') + showAlert(title, r('P_CR_CONTACTNAMECANNOTBEEMPTY', 'Contact Name cannot be empty.'), 'warn') .then(() => this.#refs.contactName.focus()); return null; } if ((pref == 0 || pref == 2) && nullOrEmpty(phone)) { - showAlert(title, r('contactPhoneRequired', 'Mobile cannot be empty.'), 'warn') + showAlert(title, r('P_CR_MOBILECANNOTBEEMPTY', 'Mobile cannot be empty.'), 'warn') .then(() => this.#refs.contactMobile.focus()); return null; } if (pref == 1 && nullOrEmpty(email)) { - showAlert(title, r('contactEmailRequired', 'Email cannot be empty.'), 'warn') + showAlert(title, r('P_CU_EMAILCANNOTBEEMPTY', 'Email cannot be empty.'), 'warn') .then(() => this.#refs.contactEmail.focus()); return null; } if (!nullOrEmpty(email) && !isEmail(email)) { - showAlert(title, r('contactEmailInvalid', 'The email address is invalid.'), 'warn') + showAlert(title, r('P_CR_EMAILISNOTAVALIDEMAILADDRESS', 'The email address is invalid.'), 'warn') .then(() => this.#refs.contactEmail.focus()); return null; } @@ -197,6 +203,10 @@ export class CustomerRecordContact { constructor(option = {}) { this.#option = option; + const getText = option?.getText; + if (typeof getText === 'function') { + r = getText; + } } async show(title, parent = document.body) { @@ -211,7 +221,7 @@ export class CustomerRecordContact { ), buttons: [ { - text: r('ok', 'OK'), + text: r('P_WO_OK', 'OK'), key: 'ok', trigger: () => { if (typeof this.#option.onOk === 'function') { @@ -219,7 +229,7 @@ export class CustomerRecordContact { } } }, - { text: r('cancel', 'Cancel'), key: 'cancel' } + { text: r('P_WO_CANCEL', 'Cancel'), key: 'cancel' } ] }); const result = await popup.show(parent); diff --git a/lib/app/communications/customer.d.ts b/lib/app/communications/customer.d.ts index 647e3d2..b6dc07c 100644 --- a/lib/app/communications/customer.d.ts +++ b/lib/app/communications/customer.d.ts @@ -9,7 +9,7 @@ interface InitConfig { readonly?: boolean; } -export class CustomerCommunication { +export default class CustomerCommunication { constructor (opt: InitConfig); get autoUpdatesEnabled(): boolean; diff --git a/lib/app/communications/customer.js b/lib/app/communications/customer.js index 10b4e95..be6ece0 100644 --- a/lib/app/communications/customer.js +++ b/lib/app/communications/customer.js @@ -1,5 +1,5 @@ import { Grid, GridColumn, createElement, setTooltip, createIcon, createCheckbox, createRadiobox, showAlert, showConfirm, Popup } from "../../ui"; -import { r, nullOrEmpty, formatUrl, isEmail, isPhone } from "../../utility"; +import { r as lang, nullOrEmpty, formatUrl, escapeEmoji, isEmail, isPhone } from "../../utility"; import { createBox, appendMedia, fileSupported, insertFile } from "./lib"; import { Contact, CustomerRecordContact } from "./contact"; import Follower from "./follower"; @@ -28,7 +28,9 @@ class NoteCol extends GridColumn { } } -class CustomerCommunication { +let r = lang; + +export default class CustomerCommunication { #container; #option; #contacts; @@ -44,6 +46,10 @@ class CustomerCommunication { constructor(opt) { this.#option = opt ?? {}; + const getText = opt?.getText; + if (typeof getText === 'function') { + r = getText; + } } get #autoUpdates() { return this.#container.querySelector('.check-auto-update>input') } @@ -191,21 +197,21 @@ class CustomerCommunication { let method; if (c.OptOut || c.OptOut_BC || c.selected === false) { icon = 'times'; - method = r('optedOut', 'Opted Out:'); + method = r('P_CU_OPTEDOUT_COLON', 'Opted Out:'); } else { switch (pref) { case '0': icon = 'comment-lines'; - method = r('textsToColon', 'Texts to:'); + method = r('P_CU_TEXTSTO_COLON', 'Texts to:'); break; case '2': icon = 'mobile'; - method = r('callsToColon', 'Calls to:'); + method = r('P_CU_CALLSTO_COLON', 'Calls to:'); break; default: icon = 'envelope'; - method = r('emailsToColon', 'Emails to:'); + method = r('P_CU_EMAILSTO_COLON', 'Emails to:'); break; } } @@ -222,7 +228,7 @@ class CustomerCommunication { this.#contacts.appendChild(item); let tip = `${method} ${to}`; if (span.scrollWidth > span.offsetWidth) { - tip = r('nameColon', 'Name:') + ` ${c.Name}\n${tip}`; + tip = r('P_WO_NAME_COLON', 'Name:') + ` ${c.Name}\n${tip}`; } setTooltip(span, tip); } @@ -306,7 +312,7 @@ class CustomerCommunication { this.#followers.replaceChildren(); if (followers?.length > 0) { this.#container.querySelector('.follower-bar').style.display = ''; - setTooltip(this.#buttonFollower, r('editFollower', 'Edit Followers')); + setTooltip(this.#buttonFollower, r('P_CU_EDITFOLLOWERS', 'Edit Followers')); this.#container.querySelector('.follower-bar>.bar-list').appendChild(this.#buttonFollower); for (let f of followers) { if (f.OptOut) { @@ -317,10 +323,10 @@ class CustomerCommunication { const email = String(f.Email).trim(); const tips = []; if (f.SendEmail) { - tips.push(r('emailsToColon', 'Emails to:') + ` ${email}`); + tips.push(r('P_CU_EMAILSTO_COLON', 'Emails to:') + ` ${email}`); } if (f.SendText) { - tips.push(r('textsToColon', 'Texts to:' + ` ${mpDisplay}`)); + tips.push(r('P_CU_TEXTSTO_COLON', 'Texts to:' + ` ${mpDisplay}`)); } let icon; if (f.SendText && f.SendEmail) { @@ -344,13 +350,13 @@ class CustomerCommunication { ); this.#followers.appendChild(item); if (span.scrollWidth > span.offsetWidth) { - tips.splice(0, 0, r('nameColon', 'Name:') + ` ${c.Name}`); + tips.splice(0, 0, r('P_WO_NAME_COLON', 'Name:') + ` ${c.Name}`); } setTooltip(span, tips.join('\n')); } } else { this.#container.querySelector('.follower-bar').style.display = 'none'; - setTooltip(this.#buttonFollower, r('addFollowers', 'Add Followers')); + setTooltip(this.#buttonFollower, r('P_CR_ADDFOLLOWERS', 'Add Followers')); this.#container.querySelector('.button-edit-contacts').insertAdjacentElement('beforebegin', this.#buttonFollower) } this.#message.scrollTop = this.#message.scrollHeight @@ -371,8 +377,8 @@ class CustomerCommunication { uncheckedNode: createIcon('fa-regular', 'ban'), onchange: function () { setTooltip(checkAutoUpdate, this.checked ? - r('autoUpdateEnabled', 'Auto Updates Enabled') : - r('autoUpdateDisabled', 'Auto Updates Disabled')); + r('P_CU_AUTOUPDATESENABLED', 'Auto Updates Enabled') : + r('P_CU_AUTOUPDATESDISABLED', 'Auto Updates Disabled')); } }); if (option.autoUpdatesVisible === false) { @@ -387,8 +393,8 @@ class CustomerCommunication { uncheckedNode: createIcon('fa-regular', 'unlink'), onchange: function () { setTooltip(checkLink, this.checked ? - r('statusLinkIncluded', 'Status Link Included') : - r('statusLinkExcluded', 'Status Link Excluded')); + r('P_WO_STATUSLINKINCLUDED', 'Status Link Included') : + r('P_WO_STATUSLINKEXCLUDED', 'Status Link Excluded')); if (typeof option.onStatusLinkChanged === 'function') { option.onStatusLinkChanged.call(This, this.checked); } @@ -401,7 +407,7 @@ class CustomerCommunication { createElement('div', null, createElement('div', div => { div.className = 'title-module'; - div.innerText = option.title ?? r('messages', 'Customer Communication'); + div.innerText = option.title ?? r('P_WO_CUSTOMERCOMMUNICATION', 'Customer Communication'); }), createElement('div', div => { div.className = 'title-company'; @@ -417,8 +423,8 @@ class CustomerCommunication { }) ), [ - setTooltip(checkAutoUpdate, r('autoUpdateEnabled', 'Auto Updates Enabled')), - setTooltip(checkLink, r('statusLinkExcluded', 'Status Link Excluded')) + setTooltip(checkAutoUpdate, r('P_CU_AUTOUPDATESENABLED', 'Auto Updates Enabled')), + setTooltip(checkLink, r('P_WO_STATUSLINKEXCLUDED', 'Status Link Excluded')) ] ); // contacts @@ -427,7 +433,7 @@ class CustomerCommunication { this.#followers = this.#createFollowers(container, option); // enter box const enter = createElement('textarea', 'ui-text'); - enter.placeholder = r('typeMessage', 'Enter Message Here'); + enter.placeholder = r('P_CU_ENTERMESSAGEHERE', 'Enter Message Here'); option.maxLength ??= 3000; enter.maxLength = option.maxLength; // if (readonly === true) { @@ -442,11 +448,23 @@ class CustomerCommunication { if (option.customerNameVisible === true) { return; } - const file = e.clipboardData.files[0]; - if (file != null) { - e.preventDefault(); - this.file = insertFile(container, file); + const items = e.clipboardData.items; + if (items?.length > 0) { + const item = items[0]; + const entry = item.webkitGetAsEntry(); + if (item.kind === 'file' && (entry == null || entry.isFile)) { + const file = item.getAsFile(); + if (file != null) { + e.preventDefault(); + this.file = insertFile(container, file, r); + } + } } + // const file = e.clipboardData.files[0]; + // if (file != null) { + // e.preventDefault(); + // this.file = insertFile(container, file, r); + // } }); this.#enter = enter; container.appendChild( @@ -473,7 +491,7 @@ class CustomerCommunication { const file = e.dataTransfer.files[0]; if (file != null) { e.preventDefault(); - this.file = insertFile(container, file); + this.file = insertFile(container, file, r); } } }); @@ -486,7 +504,7 @@ class CustomerCommunication { div.style.display = 'none'; } }, - createElement('span', span => span.innerText = r('nameColon', 'Name:')), + createElement('span', span => span.innerText = r('P_WO_NAME_COLON', 'Name:')), createElement('input', input => { input.type = 'text'; input.className = 'ui-input'; @@ -506,7 +524,7 @@ class CustomerCommunication { input.type = 'file'; input.accept = fileSupported.join(','); input.addEventListener('change', () => { - const file = insertFile(container, input.files?.[0]); + const file = insertFile(container, input.files?.[0], r); if (file != null) { this.file = file; } @@ -535,11 +553,11 @@ class CustomerCommunication { // button.style.display = 'none'; // } button.appendChild(createIcon('fa-solid', 'paper-plane')); - setTooltip(button, r('sendMessage', 'Send Message')); + setTooltip(button, r('P_M3_SENDMESSAGE', 'Send Message')); button.addEventListener('click', () => { const val = this.text; if (nullOrEmpty(val?.trim())) { - const p = showAlert(r('error', 'Error'), r('messageRequired', 'Please input the message.'), 'warn'); + const p = showAlert(r('P_WO_ERROR', 'Error'), r('P_WO_PLEASEINPUTTHEMESSAGE', 'Please input the message.'), 'warn'); if (typeof option.onMasking === 'function') { option.onMasking(true); p.then(() => option.onMasking(false)); @@ -547,6 +565,7 @@ class CustomerCommunication { return; } if (typeof option.onAddMessage === 'function') { + this.loading = true; option.onAddMessage(this.text, this.file); } }) @@ -581,7 +600,7 @@ class CustomerCommunication { button.style.display = 'none'; } button.appendChild(createIcon('fa-solid', 'user-edit')); - setTooltip(button, r('editContacts', 'Edit Contacts')); + setTooltip(button, r('P_CU_EDITCONTACTS', 'Edit Contacts')); button.addEventListener('click', () => { const pop = new Popup({ onMasking: option.onMasking, @@ -594,7 +613,7 @@ class CustomerCommunication { div.className = 'ui-popup-move'; div.style.flex = '1 1 auto'; }, - createElement('div', div => div.innerText = r('editContacts', 'Edit Contacts')), + createElement('div', div => div.innerText = r('P_CU_EDITCONTACTS', 'Edit Contacts')), createElement('div', div => { div.className = 'title-company'; if (nullOrEmpty(option.companyName)) { @@ -622,6 +641,7 @@ class CustomerCommunication { })); button.addEventListener('click', () => { const sel = new CustomerRecordContact({ + getText: option.getText, // onMasking: option.onMasking, contacts: [], onOk: list => { @@ -653,7 +673,7 @@ class CustomerCommunication { }); } }); - var title = r('selectFromCustomerRecord', 'Select from Customer Record'); + var title = r('P_CU_SELECTFROMCUSTOMERRECORD', 'Select from Customer Record'); sel.show(title, container); if (typeof option.onOpenSelectCRContacts === 'function') { @@ -689,7 +709,7 @@ class CustomerCommunication { return false; } }); - setTooltip(button, r('selectFromCustomerRecord', 'Select from Customer Record')) + setTooltip(button, r('P_CU_SELECTFROMCUSTOMERRECORD', 'Select from Customer Record')) }), createElement('button', button => { button.style.flex = '0 0 auto'; @@ -705,12 +725,13 @@ class CustomerCommunication { })); button.addEventListener('click', () => { const add = new Contact({ + getText: option.getText, // onMasking: option.onMasking, company: !nullOrEmpty(option.companyName), onSave: item => { const exists = this.#gridContact.source.some(s => s.Name === item.Name && s.MobilePhone === item.MobilePhone); if (exists) { - showAlert(r('addContact', 'Add Contact'), r('contactUniqueRequired', 'Contact name and contact mobile must be a unique combination.'), 'warn'); + showAlert(r('P_CR_ADDCONTACT', 'Add Contact'), r('P_WO_CONTACTNAMEANDMOBILEUNIQUECOMBINATION', 'Contact name and contact mobile must be a unique combination.'), 'warn'); return false; } if (typeof option.onSave === 'function') { @@ -744,7 +765,7 @@ class CustomerCommunication { }); add.show(container); }); - setTooltip(button, r('addContact', 'Add Contact')) + setTooltip(button, r('P_CR_ADDCONTACT', 'Add Contact')) }) ) }), @@ -754,7 +775,7 @@ class CustomerCommunication { div.style.display = 'none'; } div.style.fontWeight = 'bold'; - div.innerText = r('contactFromRecord', 'Contacts from Customer Record'); + div.innerText = r('P_CU_CONTACTSFROMCUSTOMERRECORD', 'Contacts from Customer Record'); }), createElement('div', div => { if (nullOrEmpty(option.companyName)) { @@ -767,7 +788,7 @@ class CustomerCommunication { }), createElement('div', div => { div.style.fontWeight = 'bold'; - div.innerText = r('contactFromWorkOrder', 'Contacts not on Customer Record'); + div.innerText = r('P_CU_CONTACTSNOTCUSTOMERRECORD', 'Contacts not on Customer Record'); }), createElement('div', div => { div.className = 'contacts-wo'; @@ -789,7 +810,7 @@ class CustomerCommunication { option.onChanged([...This.#gridContact.source, ...This.#gridWo.source]); } }, - tooltip: item => item.selected ? r('optedIn', 'Opted In') : r('optedOut', 'Opted Out') + tooltip: item => item.selected ? r('P_CU_OPTEDIN', 'Opted In') : r('P_CU_OPTEDOUT', 'Opted Out') } }; const iconCol = { @@ -819,19 +840,20 @@ class CustomerCommunication { key: 'edit', ...buttonCol, text: 'edit', - tooltip: r('edit', 'Edit'), + tooltip: r('P_WO_EDIT', 'Edit'), events: { onclick: function () { const edit = new Contact({ + getText: option.getText, // onMasking: option.onMasking, contact: this, - company: !nullOrEmpty(This.#option.companyName), + company: !nullOrEmpty(option.companyName), onSave: (item, _op) => { const exists = This.#gridContact.source.some(s => s !== this && s.Name === item.Name && s.MobilePhone === item.MobilePhone) || This.#gridWo.source.some(s => s !== this && s.Name === item.Name && s.MobilePhone === item.MobilePhone); if (exists) { - showAlert(r('editContact', 'Edit Contact'), r('contactUniqueRequired', 'Contact name and contact mobile must be a unique combination.'), 'warn'); + showAlert(r('P_CR_EDITCONTACT', 'Edit Contact'), r('P_WO_CONTACTNAMEANDMOBILEUNIQUECOMBINATION', 'Contact name and contact mobile must be a unique combination.'), 'warn'); return false; } if (typeof option.onSave === 'function') { @@ -884,15 +906,15 @@ class CustomerCommunication { key: 'delete', ...buttonCol, text: 'times', - tooltip: r('delete', 'Delete'), + tooltip: r('P_WO_DELETE', 'Delete'), events: { onclick: function () { showConfirm( - r('remoteContact', 'Remove Contact'), + r('P_CU_REMOVECONTACT', 'Remove Contact'), createElement('div', null, createElement('div', div => { div.style.paddingLeft = '16px'; - div.innerText = r('removeFrom', 'Remove {name} from').replace('{name}', this.Name); + div.innerText = r('P_CU_REMOVEFROM', 'Remove {name} from').replace('{name}', this.Name); }), createElement('div', div => { div.style.display = 'flex'; @@ -901,19 +923,19 @@ class CustomerCommunication { }, createRadiobox({ name: 'remove-type', - label: r('customerRecord', 'Customer Record'), + label: r('P_CUSTOMERRECORD', 'Customer Record'), checked: true, className: 'radio-customer-record' }), createRadiobox({ name: 'remove-type', - label: r('workOrder', 'Work Order') + label: r('P_WORKORDER', 'Work Order') }) ) ), [ - { key: 'ok', text: r('ok', 'OK') }, - { key: 'cancel', text: r('cancel', 'Cancel') } + { key: 'ok', text: r('P_WO_OK', 'OK') }, + { key: 'cancel', text: r('P_WO_CANCEL', 'Cancel') } ] ).then(result => { if (result?.key === 'ok') { @@ -969,12 +991,12 @@ class CustomerCommunication { key: 'delete', ...buttonCol, text: 'times', - tooltip: r('delete', 'Delete'), + tooltip: r('P_WO_DELETE', 'Delete'), events: { onclick: function () { - showConfirm(r('remoteContact', 'Remove Contact'), r('removeFromWorkorder', 'You are removing {name} from work order.\n\nDo you want to Continue?').replace('{name}', this.Name), [ - { key: 'continue', text: r('continue', 'Continue') }, - { key: 'cancel', text: r('cancel', 'Cancel') } + showConfirm(r('P_CU_REMOVECONTACT', 'Remove Contact'), r('P_CU_REMOVEFROMWORKORDER', 'You are removing {name} from work order.\n\nDo you want to Continue?').replace('{name}', this.Name), [ + { key: 'continue', text: r('P_JS_CONTINUE', 'Continue') }, + { key: 'cancel', text: r('P_WO_CANCEL', 'Cancel') } ]).then(result => { if (result?.key === 'continue') { if (typeof option.onDelete === 'function') { @@ -1017,7 +1039,7 @@ class CustomerCommunication { ), createElement('div', div => { div.className = 'bar-info'; - div.innerText = r('contactInformation', 'Contact Information'); + div.innerText = r('P_CR_CONTACTINFORMATION', 'Contact Information'); }), createElement('div', div => { if (option.contactCollapserVisible === false) { @@ -1061,15 +1083,16 @@ class CustomerCommunication { button.style.display = 'none'; } button.appendChild(createIcon('fa-solid', 'pen')); - setTooltip(button, r('editFollower', 'Edit Followers')); + setTooltip(button, r('P_CU_EDITFOLLOWERS', 'Edit Followers')); button.addEventListener('click', () => { if (typeof option.onInitFollower === 'function') { option.onInitFollower(this.#data.followers).then(data => { if (typeof data === 'string') { - showAlert(r('customerRecord', 'Customer Record'), data, 'warn'); + showAlert(r('P_CUSTOMERRECORD', 'Customer Record'), data, 'warn'); return; } const add = new Follower({ + getText: option.getText, onMasking: option.onMasking, followers: data, onOk: list => { @@ -1085,7 +1108,7 @@ class CustomerCommunication { } } }); - var title = this.#data.followers?.length > 0 ? r('editFollowers', 'Edit Followers') : r('addFollowers', 'Add Followers'); + var title = this.#data.followers?.length > 0 ? r('P_CU_EDITFOLLOWERS', 'Edit Followers') : r('P_CR_ADDFOLLOWERS', 'Add Followers'); add.show(title, container); }); } @@ -1105,7 +1128,7 @@ class CustomerCommunication { 'border-radius': '15px', 'padding': '4px' }) - ), r('copied', 'Copied')), + ), r('P_CU_COPIED', 'Copied')), createElement('div', 'bar-list', followers, buttonEditFollower @@ -1154,7 +1177,7 @@ class CustomerCommunication { } } if (sendto !== '') { - sendto = r('sendToColon', 'Send To :') + `\n${sendto}`; + sendto = r('P_CU_SENDTO_COLON', 'Send To :') + `\n${sendto}`; } div.appendChild(createElement('div', div => { div.className = 'item-poster'; @@ -1164,13 +1187,12 @@ class CustomerCommunication { } })); const content = createElement('div', 'item-content'); - const emoji = s => s.replace(/(=[A-Fa-f0-9]{2}){4}/, s => decodeURIComponent(s.replaceAll('=', '%'))); const mmsParts = createElement('div', div => div.style.display = 'none'); content.appendChild(createElement('span', span => { if (/https?:\/\//i.test(comm.Message)) { - span.innerHTML = emoji(formatUrl(comm.Message)); + span.innerHTML = escapeEmoji(formatUrl(comm.Message)); } else { - span.innerText = emoji(comm.Message); + span.innerText = escapeEmoji(comm.Message); } span.appendChild(mmsParts); })); @@ -1189,26 +1211,26 @@ class CustomerCommunication { let statustext; switch (status) { case 0: - statustext = r('pending', 'Pending'); + statustext = r('P_CU_PENDING', 'Pending'); content.style.backgroundColor = '#ffc107'; break; case 1: - statustext = r('sent', 'Sent'); + statustext = r('P_WO_SENT', 'Sent'); break; case 9: - statustext = r('failed', 'Failed'); + statustext = r('P_MA_FAILED', 'Failed'); content.style.backgroundColor = '#ffc107'; break; case 10: - statustext = r('optOut', 'Opt-Out'); + statustext = r('P_CU_OPTOUT', 'Opt-Out'); content.style.backgroundColor = '#ffc107'; break; case 412: - statustext = r('landline', 'Landline'); + statustext = r('P_CU_LANDLINE', 'Landline'); content.style.backgroundColor = '#ffc107'; break; default: - statustext = r('undelivered', 'Undelivered'); + statustext = r('P_CU_UNDELIVERED', 'Undelivered'); content.style.backgroundColor = '#ffc107'; break; } @@ -1253,13 +1275,15 @@ class CustomerCommunication { } statusmsg += `${p.CustomerNumber}: `; const st = ({ - 0: r('undelivered', 'Undelivered'), - 1: r('sent', 'Sent'), - 9: r('failed', 'Failed') + 0: r('P_CU_UNDELIVERED', 'Undelivered'), + 1: r('P_WO_SENT', 'Sent'), + 9: r('P_MA_FAILED', 'Failed') })[p.Status]; if (st != null) { statusmsg += st; } + else + statusmsg += r('P_MA_XXXXXX', 'Unknown'); } } } @@ -1270,6 +1294,4 @@ class CustomerCommunication { } return [status, statusmsg]; } -} - -export default CustomerCommunication; \ No newline at end of file +} \ No newline at end of file diff --git a/lib/app/communications/follower.js b/lib/app/communications/follower.js index fa2ba78..cfd4315 100644 --- a/lib/app/communications/follower.js +++ b/lib/app/communications/follower.js @@ -1,12 +1,18 @@ import { Grid, createElement, Popup } from "../../ui"; -import { nullOrEmpty, r, contains } from "../../utility"; +import { nullOrEmpty, r as lang, contains } from "../../utility"; -class Follower { +let r = lang; + +export default class Follower { #option; #grid; constructor(option = {}) { this.#option = option; + const getText = option?.getText; + if (typeof getText === 'function') { + r = getText; + } } async show(title, parent = document.body) { @@ -17,7 +23,7 @@ class Follower { onMasking: this.#option.onMasking, title, content: createElement('div', 'follower-wrapper', - createElement('div', div => div.innerText = r('whoWantReceiveCustomerNotification', 'Who do you want to receive customer notifications?')), + createElement('div', div => div.innerText = r('P_CR_WHODOYOUWANTTORECEIVECUSTOMERNOTIFICATIONS', 'Who do you want to receive customer notifications?')), createElement('input', search => { search.type = 'text'; search.tabIndex = tabIndex + 3; @@ -36,7 +42,7 @@ class Follower { ), buttons: [ { - text: r('ok', 'OK'), + text: r('P_WO_OK', 'OK'), key: 'ok', trigger: () => { if (typeof this.#option.onOk === 'function') { @@ -44,7 +50,7 @@ class Follower { } } }, - { text: r('cancel', 'Cancel'), key: 'cancel' } + { text: r('P_WO_CANCEL', 'Cancel'), key: 'cancel' } ] }); const result = await popup.show(parent); @@ -52,18 +58,18 @@ class Follower { // grid const grid = new Grid(gridContainer); grid.columns = [ - { key: 'DisplayName', caption: r('contactName', 'Contact Name'), width: 240 }, - { key: 'ContactTypeName', caption: r('contactType', 'Contact Type'), width: 120 }, + { key: 'DisplayName', caption: r('P_WO_CONTACTNAME', 'Contact Name'), width: 240 }, + { key: 'ContactTypeName', caption: r('P_WO_CONTACTTYPE', 'Contact Type'), width: 120 }, { key: 'Text', - caption: r('text', 'Text'), + caption: r('P_CR_TEXT', 'Text'), type: Grid.ColumnTypes.Checkbox, width: 60, enabled: item => !nullOrEmpty(item.Mobile) }, { key: 'Email', - caption: r('email', 'Email'), + caption: r('P_CR_EMAIL', 'Email'), type: Grid.ColumnTypes.Checkbox, width: 70, // enabled: item => !nullOrEmpty(item.ID) @@ -74,6 +80,4 @@ class Follower { this.#grid = grid; return result; } -} - -export default Follower; \ No newline at end of file +} \ No newline at end of file diff --git a/lib/app/communications/internal.js b/lib/app/communications/internal.js index 1ea5eaa..3f73206 100644 --- a/lib/app/communications/internal.js +++ b/lib/app/communications/internal.js @@ -1,8 +1,11 @@ -import { createElement, setTooltip, createIcon, showAlert } from "../../ui"; -import { r, nullOrEmpty, escapeHtml } from "../../utility"; -import { createBox, appendMedia, fileSupported, insertFile } from "./lib"; +import { createElement, setTooltip, createIcon } from "../../ui"; +import { r as lang, nullOrEmpty, escapeHtml, escapeEmoji } from "../../utility"; +import { createBox, appendMedia } from "./lib"; +// import { fileSupported, insertFile } from "./lib"; -class InternalComment { +let r = lang; + +export default class InternalComment { #container; #option; #enter; @@ -12,6 +15,10 @@ class InternalComment { constructor(opt) { this.#option = opt ?? {}; + const getText = opt?.getText; + if (typeof getText === 'function') { + r = getText; + } } get text() { return this.#enter?.value } @@ -86,14 +93,14 @@ class InternalComment { createElement('div', null, createElement('div', div => { div.className = 'title-module'; - div.innerText = r('internalComments', 'Internal Comments'); + div.innerText = r('P_WO_INTERNALCOMMENTS', 'Internal Comments'); }) ), [] ); const readonly = this.#option.readonly; // enter box const enter = createElement('textarea', 'ui-text'); - enter.placeholder = r('typeComment', 'Enter Comment Here'); + enter.placeholder = r('P_CU_ENTERCOMMENTHERE', 'Enter Comment Here'); enter.maxLength = this.#option.maxLength ??= 3000; enter.addEventListener('input', () => { const val = this.text; @@ -107,7 +114,7 @@ class InternalComment { // const file = e.clipboardData.files[0]; // if (file != null) { // e.preventDefault(); - // this.file = insertFile(container, file); + // this.file = insertFile(container, file, r); // } // }); this.#enter = enter; @@ -132,7 +139,7 @@ class InternalComment { // const file = e.dataTransfer.files[0]; // if (file != null) { // e.preventDefault(); - // this.file = insertFile(container, file); + // this.file = insertFile(container, file, r); // } // } // }); @@ -154,7 +161,7 @@ class InternalComment { // input.type = 'file'; // input.accept = fileSupported.join(','); // input.addEventListener('change', () => { - // const file = insertFile(container, input.files?.[0]); + // const file = insertFile(container, input.files?.[0], r); // if (file != null) { // this.file = file; // } @@ -183,9 +190,14 @@ class InternalComment { button.style.display = 'none'; } button.appendChild(createIcon('fa-solid', 'paper-plane')); - setTooltip(button, r('sendMessage', 'Send Message')); + setTooltip(button, r('P_M3_SENDMESSAGE', 'Send Message')); button.addEventListener('click', () => { + const val = this.text; + if (nullOrEmpty(val?.trim())) { + return; + } if (typeof this.#option.onAddMessage === 'function') { + this.loading = true; this.#option.onAddMessage(this.text); } }) @@ -198,9 +210,14 @@ class InternalComment { button.style.display = 'none'; } button.appendChild(createIcon('fa-solid', 'comment-alt-lines')); - setTooltip(button, r('postNote', 'Post Note')); + setTooltip(button, r('P_CU_POSTNOTE', 'Post Note')); button.addEventListener('click', () => { + const val = this.text; + if (nullOrEmpty(val?.trim())) { + return; + } if (typeof this.#option.onAddComment === 'function') { + this.loading = true; this.#option.onAddComment(this.text, this.file); } }) @@ -221,16 +238,15 @@ class InternalComment { for (let comment of data) { const div = createElement('div', 'item-div'); // if (sendto !== '') { - // sendto = r('sendToColon', 'Send To :') + `\n${sendto}`; + // sendto = r('P_CU_SENDTO_COLON', 'Send To :') + `\n${sendto}`; // } div.appendChild(createElement('div', div => { div.className = 'item-poster'; div.innerText = comment.UserName; })); const content = createElement('div', 'item-content'); - const emoji = s => s.replace(/(=[A-Fa-f0-9]{2}){4}/, s => decodeURIComponent(s.replaceAll('=', '%'))); const mmsParts = createElement('div', div => div.style.display = 'none'); - content.appendChild(createElement('span', span => span.innerHTML = emoji(escapeHtml(comment.Comment)), mmsParts)); + content.appendChild(createElement('span', span => span.innerHTML = escapeEmoji(escapeHtml(comment.Comment)), mmsParts)); if (comment.IsMMS && comment.MMSParts?.length > 0) { mmsParts.style.display = ''; for (let kv of comment.MMSParts) { @@ -239,10 +255,10 @@ class InternalComment { } if (comment.FollowUp?.length > 0) { div.classList.add('item-sent'); - const sendto = r('sendToColon', 'Send To :') + '\r\n' + comment.FollowUp.split(';').join('\r\n'); + const sendto = r('P_CU_SENDTO_COLON', 'Send To :') + '\r\n' + comment.FollowUp.split(';').join('\r\n'); content.appendChild(createElement('div', div => { div.className = 'item-status'; - div.innerText = r('sent', 'Sent'); + div.innerText = r('P_WO_SENT', 'Sent'); setTooltip(div, sendto); })); } @@ -261,6 +277,4 @@ class InternalComment { this.#message.scrollTop = this.#message.scrollHeight // setTimeout(() => this.#message.scrollTop = this.#message.scrollHeight, 0); } -} - -export default InternalComment; \ No newline at end of file +} \ No newline at end of file diff --git a/lib/app/communications/lib.js b/lib/app/communications/lib.js index 6c44c11..d8d86e2 100644 --- a/lib/app/communications/lib.js +++ b/lib/app/communications/lib.js @@ -1,5 +1,4 @@ import { createElement, setTooltip, showAlert, createPicture, createAudio, createVideo, createFile } from "../../ui"; -import { r } from "../../utility"; export function createBox(title, functions) { const container = createElement('div', 'comm'); @@ -16,39 +15,51 @@ export function appendMedia(container, mimeType, url) { case 'application/pdf': container.appendChild(createFile(url, 'file-pdf')); break; + case 'application/msword': + case 'application/vnd.ms-word': + case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': + container.appendChild(createFile(url, 'file-word')); + break; + case 'application/vnd.ms-excel': + case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': + container.appendChild(createFile(url, 'file-excel')); + break; + case 'application/vnd.ms-powerpoint': + case 'application/vnd.openxmlformats-officedocument.presentationml.presentation': + container.appendChild(createFile(url, 'file-powerpoint')); + break; case 'application/smil': // TODO: ignore smil files // container.appendChild(createFile(url, 'smile')); break; + case 'audio/aac': case 'audio/amr': case 'audio/mp3': case 'audio/mpeg': case 'audio/x-mpeg': - case 'audio/aac': case 'audio/ogg': case 'audio/opus': case 'audio/wav': case 'audio/webm': container.appendChild(createAudio(mimeType, url)); break; - case 'image/gif': - case 'image/jpeg': - case 'image/png': - container.appendChild(createPicture(url)); - break; + case 'text/plain': case 'text/x-vcard': container.appendChild(createFile(url, 'id-card')); break; + case 'video/3gpp': + case 'video/mp2t': case 'video/mp4': case 'video/mpeg': case 'video/x-mpeg': - case 'video/mp2t': - case 'video/webm': case 'video/quicktime': + case 'video/webm': container.appendChild(createVideo(url)); break; default: - if (/^audio\//.test(mimeType)) { + if (/^image\//.test(mimeType)) { + container.appendChild(createPicture(url)); + } else if (/^audio\//.test(mimeType)) { container.appendChild(createFile(url, 'music')); } else if (/^video\//.test(mimeType)) { container.appendChild(createFile(url, 'video')); @@ -61,30 +72,50 @@ export function appendMedia(container, mimeType, url) { }; const MaxAttachmentSize = { - limit: 2 * 1024 * 1024, - text: '2MB' + limit: 1_258_291, + text: '1.2MB' }; export const fileSupported = [ + '.amr', + '.ogv', + 'application/msword', + 'application/vnd.ms-word', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.ms-excel', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/vnd.ms-powerpoint', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/pdf', + 'audio/aac', + 'audio/amr', + 'audio/mp3', 'audio/mpeg', 'audio/x-mpeg', - 'audio/amr', - '.amr', + 'audio/ogg', + 'audio/opus', + 'audio/wav', + 'audio/webm', 'image/bmp', 'image/gif', 'image/jpeg', + 'image/jfif', 'image/png', 'image/tiff', + 'image/webp', 'text/plain', + 'text/vcard', 'text/x-vcard', 'video/3gpp', + 'video/mp2t', 'video/mp4', + 'video/mpeg', + 'video/x-mpeg', + 'video/quicktime', 'video/webm', - 'video/quicktime' ]; -export function insertFile(container, file) { +export function insertFile(container, file, r) { const label = container.querySelector('.file-selector>.selector-name'); if (label != null && file != null) { let type = file.type; @@ -93,12 +124,12 @@ export function insertFile(container, file) { type = type.substring(type.lastIndexOf('.')); } if (fileSupported.indexOf(type) < 0) { - showAlert(r('error', 'Error'), r('notSupported', 'File type "{type}" is now not supported.').replace('{type}', type)); + showAlert(r('P_WO_ERROR', 'Error'), r('P_CU_TYPENOTSUPPORTED', 'File type "{type}" is now not supported.').replace('{type}', type)); return; } const isImage = /^image\//.test(type); if (!isImage && file.size > MaxAttachmentSize.limit) { - showAlert(r('error', 'Error'), r('fileTooLarge', `File is too large. (> ${MaxAttachmentSize.text})`), 'warn'); + showAlert(r('P_WO_ERROR', 'Error'), r('P_WO_ATTACHMENTSIZEEXCEEDSTHEMAXIMUMTIPS', `Attachment size exceeds the maximum allowed to be sent (${MaxAttachmentSize.text})`), 'warn'); return; } const fn = file.name; diff --git a/lib/ui/css/media.scss b/lib/ui/css/media.scss index c763eae..7a7c299 100644 --- a/lib/ui/css/media.scss +++ b/lib/ui/css/media.scss @@ -7,6 +7,10 @@ display: inline-flex; align-items: center; + &::before { + display: none; + } + >svg { width: 20px; height: 20px; @@ -41,6 +45,10 @@ border: none; } + &::after { + display: none; + } + >svg { width: 100%; height: 100%; diff --git a/lib/utility.js b/lib/utility.js index ed5523c..57f48ed 100644 --- a/lib/utility.js +++ b/lib/utility.js @@ -1,7 +1,7 @@ import { getCookie, setCookie, deleteCookie } from "./utility/cookie"; import { init, r, lang } from "./utility/lgres"; import { get, post, upload } from "./utility/request"; -import { nullOrEmpty, contains, endsWith, padStart, formatUrl, escapeHtml } from "./utility/strings"; +import { nullOrEmpty, contains, endsWith, padStart, formatUrl, escapeHtml, escapeEmoji } from "./utility/strings"; let g = typeof globalThis !== 'undefined' ? globalThis : self; @@ -73,6 +73,7 @@ export { padStart, formatUrl, escapeHtml, + escapeEmoji, // variables g as global, isPositive, diff --git a/lib/utility/lgres.js b/lib/utility/lgres.js index fe6aa2f..315b3b5 100644 --- a/lib/utility/lgres.js +++ b/lib/utility/lgres.js @@ -47,7 +47,8 @@ function getStorageKey(lgid) { async function doRefreshLgres(template = '') { const lgid = getCurrentLgId(); - const r = await get(`language/${lgid}${template}`); + const url = template.length > 0 ? template.replace('{lgid}', lgid) : `language/${lgid}`; + const r = await get(url); const dict = await r.json(); localStorage.setItem(getStorageKey(lgid), JSON.stringify(dict)); return dict; diff --git a/lib/utility/strings.d.ts b/lib/utility/strings.d.ts index c2b30ea..51e2823 100644 --- a/lib/utility/strings.d.ts +++ b/lib/utility/strings.d.ts @@ -3,4 +3,5 @@ export function contains(s: string, key: string | any, ignoreCase?: boolean): bo export function endsWith(s: string, suffix: string): boolean export function padStart(s: string, num: Number, char: string): boolean export function formatUrl(msg: string): string -export function escapeHtml(text: string): string \ No newline at end of file +export function escapeHtml(text: string): string +export function escapeEmoji(text: string): string \ No newline at end of file diff --git a/lib/utility/strings.js b/lib/utility/strings.js index cc75435..36e0486 100644 --- a/lib/utility/strings.js +++ b/lib/utility/strings.js @@ -64,4 +64,16 @@ export function escapeHtml(text) { .replaceAll('\r\n', '
') .replaceAll('\n', '
') .replaceAll(' ', ' '); +} + +export function escapeEmoji(text) { + if (text == null) { + return ''; + } + if (typeof text !== 'string') { + text = String(text); + } + return text + .replace(/(=[A-Fa-f0-9]{2}){4}/g, s => decodeURIComponent(s.replaceAll('=', '%'))) + .replace(/&#x([0-9a-fA-F]{2,6});/g, (_, h) => String.fromCodePoint(parseInt(h, 16))); } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b91cd47..c123eeb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,117 +16,159 @@ } }, "node_modules/@csstools/cascade-layer-name-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.2.tgz", - "integrity": "sha512-xm7Mgwej/wBfLoK0K5LfntmPJzoULayl1XZY9JYgQgT29JiqNw++sLnx95u5y9zCihblzkyaRYJrsRMhIBzRdg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.4.tgz", + "integrity": "sha512-zXMGsJetbLoXe+gjEES07MEGjL0Uy3hMxmnGtVBrRpVKr5KV9OgCB09zr/vLrsEtoVQTgJFewxaU8IYSAE4tjg==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.1.1", - "@csstools/css-tokenizer": "^2.1.1" + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0" } }, "node_modules/@csstools/color-helpers": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-2.0.0.tgz", - "integrity": "sha512-VcPjEnp07RNgz/D+oI2uIALg+IPCSl6mj0XhA3pl3F2bM2B95vgzatExmmzSg/X0zkh+R2v+jFY/J2pV/bnwpw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-3.0.0.tgz", + "integrity": "sha512-rBODd1rY01QcenD34QxbQxLc1g+Uh7z1X/uzTHNQzJUnFCT9/EZYI7KWq+j0YfWMXJsRJ8lVkqBcB0R/qLr+yg==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { "node": "^14 || ^16 || >=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" } }, "node_modules/@csstools/css-calc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-1.1.1.tgz", - "integrity": "sha512-Nh+iLCtjlooTzuR0lpmB8I6hPX/VupcGQ3Z1U2+wgJJ4fa8+cWkub+lCsbZcYPzBGsZLEL8fQAg+Na5dwEFJxg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-1.1.3.tgz", + "integrity": "sha512-7mJZ8gGRtSQfQKBQFi5N0Z+jzNC0q8bIkwojP1W0w+APzEqHu5wJoGVsvKxVnVklu9F8tW1PikbBRseYnAdv+g==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.1.1", - "@csstools/css-tokenizer": "^2.1.1" + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0" } }, "node_modules/@csstools/css-color-parser": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-1.1.2.tgz", - "integrity": "sha512-MjW/VspbFSkvbuou7tUUu2+FAlAR7VJ/PA69M9EGKltThbONC8nyW33wHRzNvLzRLGstZLEO5X5oR7IMhMDi0A==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-1.2.3.tgz", + "integrity": "sha512-YaEnCoPTdhE4lPQFH3dU4IEk8S+yCnxS88wMv45JzlnMfZp57hpqA6qf2gX8uv7IJTJ/43u6pTQmhy7hCjlz7g==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/color-helpers": "^2.0.0", - "@csstools/css-calc": "^1.1.1" + "@csstools/color-helpers": "^3.0.0", + "@csstools/css-calc": "^1.1.3" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.1.1", - "@csstools/css-tokenizer": "^2.1.1" + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0" } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.1.1.tgz", - "integrity": "sha512-viRnRh02AgO4mwIQb2xQNJju0i+Fh9roNgmbR5xEuG7J3TGgxjnE95HnBLgsFJOJOksvcfxOUCgODcft6Y07cA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz", + "integrity": "sha512-xrvsmVUtefWMWQsGgFffqWSK03pZ1vfDki4IVIIUxxDKnGBzqNgv0A7SB1oXtVNEkcVO8xi1ZrTL29HhSu5kGA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { - "@csstools/css-tokenizer": "^2.1.1" + "@csstools/css-tokenizer": "^2.2.0" } }, "node_modules/@csstools/css-tokenizer": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz", - "integrity": "sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.0.tgz", + "integrity": "sha512-wErmsWCbsmig8sQKkM6pFhr/oPha1bHfvxsUY5CYSQxwyhA9Ulrs8EqCgClhg4Tgg2XapVstGqSVcz0xOYizZA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { "node": "^14 || ^16 || >=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" } }, "node_modules/@csstools/media-query-list-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.4.tgz", - "integrity": "sha512-GyYot6jHgcSDZZ+tLSnrzkR7aJhF2ZW6d+CXH66mjy5WpAQhZD4HDke2OQ36SivGRWlZJpAz7TzbW6OKlEpxAA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.4.tgz", + "integrity": "sha512-V/OUXYX91tAC1CDsiY+HotIcJR+vPtzrX8pCplCpT++i8ThZZsq5F5dzZh/bDM3WUOjrvC1ljed1oSJxMfjqhw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.1.1", - "@csstools/css-tokenizer": "^2.1.1" + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0" } }, "node_modules/@csstools/postcss-cascade-layers": { @@ -150,45 +192,57 @@ } }, "node_modules/@csstools/postcss-color-function": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-2.2.1.tgz", - "integrity": "sha512-T52iiqmzyKk09B9iNTQbuWa9Tn83SztXY7o6r2+j+o1BS/7+CiCjTgN2HgzybDmx8cr6XYhQ1BzqgV9tJzhrmw==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-2.2.3.tgz", + "integrity": "sha512-b1ptNkr1UWP96EEHqKBWWaV5m/0hgYGctgA/RVZhONeP1L3T/8hwoqDm9bB23yVCfOgE9U93KI9j06+pEkJTvw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/css-color-parser": "^1.1.2", + "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", - "@csstools/postcss-progressive-custom-properties": "^2.0.0" + "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } }, "node_modules/@csstools/postcss-color-mix-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-1.0.1.tgz", - "integrity": "sha512-NSVrzjVcI4TMzDfh6GKZXvEuelT81xpXzruuTNJrwKMTZXEBHY9G2gvmr0eC0wwmL8EF1TblXyPPfBbZobvfXg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-1.0.3.tgz", + "integrity": "sha512-QGXjGugTluqFZWzVf+S3wCiRiI0ukXlYqCi7OnpDotP/zaVTyl/aqZujLFzTOXy24BoWnu89frGMc79ohY5eog==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/css-color-parser": "^1.1.2", + "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", - "@csstools/postcss-progressive-custom-properties": "^2.0.0" + "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } @@ -213,9 +267,9 @@ } }, "node_modules/@csstools/postcss-gradients-interpolation-method": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-3.0.4.tgz", - "integrity": "sha512-GgKoY7OlvL65UPigEdlrvMAUCR5kOQCjtue2/36TPrBNoRS6KM2KOqmjIVsxEwYYwK+L28pdnM8r10m03hhZxA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-3.0.6.tgz", + "integrity": "sha512-rBOBTat/YMmB0G8VHwKqDEx+RZ4KCU9j42K8LwS0IpZnyThalZZF7BCSsZ6TFlZhcRZKlZy3LLFI2pLqjNVGGA==", "dev": true, "funding": [ { @@ -228,10 +282,10 @@ } ], "dependencies": { - "@csstools/css-color-parser": "^1.1.2", + "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", - "@csstools/postcss-progressive-custom-properties": "^2.0.0" + "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "engines": { "node": "^14 || ^16 || >=18" @@ -241,51 +295,73 @@ } }, "node_modules/@csstools/postcss-hwb-function": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-2.2.1.tgz", - "integrity": "sha512-eiqB4DIs+xqProAly7KwIgE04oze1YHb0QSCw/Y7062d9gpw+Cdif3Y0Z+Te+U7JROYdO0/0j91A6Qy8fo/Rlw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-2.2.2.tgz", + "integrity": "sha512-W5Y5oaJ382HSlbdGfPf60d7dAK6Hqf10+Be1yZbd/TNNrQ/3dDdV1c07YwOXPQ3PZ6dvFMhxbIbn8EC3ki3nEg==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/css-color-parser": "^1.1.2", + "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } }, "node_modules/@csstools/postcss-ic-unit": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-2.0.2.tgz", - "integrity": "sha512-N84qGTJkfLTPj2qOG5P4CIqGjpZBbjOEMKMn+UjO5wlb9lcBTfBsxCF0lQsFdWJUzBHYFOz19dL66v71WF3Pig==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-2.0.4.tgz", + "integrity": "sha512-9W2ZbV7whWnr1Gt4qYgxMWzbevZMOvclUczT5vk4yR6vS53W/njiiUhtm/jh/BKYwQ1W3PECZjgAd2dH4ebJig==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^2.0.0", + "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } }, "node_modules/@csstools/postcss-is-pseudo-class": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-3.2.0.tgz", - "integrity": "sha512-uooelBL99jMg8ZD6xy0Pj1hSalchWmplcin00eI+JHpv1jW2iwbi1cn2UnVsToM4JLwJSZFzTSWCgSpmlyhe3A==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-3.2.1.tgz", + "integrity": "sha512-AtANdV34kJl04Al62is3eQRk/BfOfyAvEmRJvbt+nx5REqImLC+2XhuE6skgkcPli1l8ONS67wS+l1sBzySc3Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" @@ -293,10 +369,6 @@ "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } @@ -356,44 +428,56 @@ } }, "node_modules/@csstools/postcss-media-minmax": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-1.0.2.tgz", - "integrity": "sha512-DsEykSINZTqlBefi1uSQBym1Rj0NQOj92dLRd5jUQpSy8yBVaXXmkiUgBUbb+gQh8imAdqPpz2v4sAUnw8yXXA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-1.0.7.tgz", + "integrity": "sha512-5LGLdu8cJgRPmvkjUNqOPKIKeHbyQmoGKooB5Rh0mp5mLaNI9bl+IjFZ2keY0cztZYsriJsGf6Lu8R5XetuwoQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/css-calc": "^1.1.1", - "@csstools/css-parser-algorithms": "^2.1.1", - "@csstools/css-tokenizer": "^2.1.1", - "@csstools/media-query-list-parser": "^2.0.4" + "@csstools/css-calc": "^1.1.3", + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0", + "@csstools/media-query-list-parser": "^2.1.4" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } }, "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-1.0.2.tgz", - "integrity": "sha512-rOSR5p+5m0joXUoitYgCyMqNCu97yfLsLG3cnNaM8VeJRCWHGEu5hE9Gv0M7n9A4wo2pYF8QqaxkTlWbSJY9Fg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-1.0.4.tgz", + "integrity": "sha512-IwyTbyR8E2y3kh6Fhrs251KjKBJeUPV5GlnUKnpU70PRFEN2DolWbf2V4+o/B9+Oj77P/DullLTulWEQ8uFtAA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/css-parser-algorithms": "^2.2.0", "@csstools/css-tokenizer": "^2.1.1", - "@csstools/media-query-list-parser": "^2.0.4" + "@csstools/media-query-list-parser": "^2.1.1" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } @@ -437,41 +521,81 @@ } }, "node_modules/@csstools/postcss-oklab-function": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-2.2.1.tgz", - "integrity": "sha512-g4wrVopp6xXr1KetUK4Lj36P+PFPwvUUtd2gaqo7X/0xgJHmMtKMPhD9p77H9bmIpPtkIYQ8b7+7cdmrWNEVAw==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-2.2.3.tgz", + "integrity": "sha512-AgJ2rWMnLCDcbSMTHSqBYn66DNLBym6JpBpCaqmwZ9huGdljjDRuH3DzOYzkgQ7Pm2K92IYIq54IvFHloUOdvA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/css-color-parser": "^1.1.2", + "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", - "@csstools/postcss-progressive-custom-properties": "^2.0.0" + "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } }, "node_modules/@csstools/postcss-progressive-custom-properties": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-2.1.1.tgz", - "integrity": "sha512-6p8eO5+j+9hn4h2Klr9dbmya0GIb9SRrnPaCxqR1muVlV1waAZq6YkmlApEwXrox9qxggSwGZD5TnLRIY9f7WA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-2.3.0.tgz", + "integrity": "sha512-Zd8ojyMlsL919TBExQ1I0CTpBDdyCpH/yOdqatZpuC3sd22K4SwC7+Yez3Q/vmXMWSAl+shjNeFZ7JMyxMjK+Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-relative-color-syntax": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-1.0.2.tgz", + "integrity": "sha512-juCoVInkgH2TZPfOhyx6tIal7jW37L/0Tt+Vcl1LoxqQA9sxcg3JWYZ98pl1BonDnki6s/M7nXzFQHWsWMeHgw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "dependencies": { + "@csstools/css-color-parser": "^1.2.0", + "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/css-tokenizer": "^2.1.1", + "@csstools/postcss-progressive-custom-properties": "^2.3.0" + }, + "engines": { + "node": "^14 || ^16 || >=18" }, "peerDependencies": { "postcss": "^8.4" @@ -518,25 +642,50 @@ } }, "node_modules/@csstools/postcss-text-decoration-shorthand": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-2.2.3.tgz", - "integrity": "sha512-PADJidg/tdhDk120aWlGuDxsp5ZTc9Nx7GhJ8t0qBCk5fOgLK6V3DsB9X6sOAhDokIihXKzjtUu15puac5McWw==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-2.2.4.tgz", + "integrity": "sha512-zPN56sQkS/7YTCVZhOBVCWf7AiNge8fXDl7JVaHLz2RyT4pnyK2gFjckWRLpO0A2xkm1lCgZ0bepYZTwAVd/5A==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/color-helpers": "^2.0.0", + "@csstools/color-helpers": "^2.1.0", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } }, + "node_modules/@csstools/postcss-text-decoration-shorthand/node_modules/@csstools/color-helpers": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-2.1.0.tgz", + "integrity": "sha512-OWkqBa7PDzZuJ3Ha7T5bxdSVfSCfTq6K1mbAhbO1MD+GSULGjrp45i5RudyJOedstSarN/3mdwu9upJE7gDXfw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + } + }, "node_modules/@csstools/postcss-trigonometric-functions": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-2.1.1.tgz", @@ -591,9 +740,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.12.tgz", - "integrity": "sha512-LIxaNIQfkFZbTLb4+cX7dozHlAbAshhFE5PKdro0l+FnCpx1GDJaQ2WMcqm+ToXKMt8p8Uojk/MFRuGyz3V5Sw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", "cpu": [ "arm" ], @@ -607,9 +756,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.12.tgz", - "integrity": "sha512-BMAlczRqC/LUt2P97E4apTBbkvS9JTJnp2DKFbCwpZ8vBvXVbNdqmvzW/OsdtI/+mGr+apkkpqGM8WecLkPgrA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", "cpu": [ "arm64" ], @@ -623,9 +772,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.12.tgz", - "integrity": "sha512-zU5MyluNsykf5cOJ0LZZZjgAHbhPJ1cWfdH1ZXVMXxVMhEV0VZiZXQdwBBVvmvbF28EizeK7obG9fs+fpmS0eQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", "cpu": [ "x64" ], @@ -639,9 +788,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.12.tgz", - "integrity": "sha512-zUZMep7YONnp6954QOOwEBwFX9svlKd3ov6PkxKd53LGTHsp/gy7vHaPGhhjBmEpqXEXShi6dddjIkmd+NgMsA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", "cpu": [ "arm64" ], @@ -655,9 +804,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.12.tgz", - "integrity": "sha512-ohqLPc7i67yunArPj1+/FeeJ7AgwAjHqKZ512ADk3WsE3FHU9l+m5aa7NdxXr0HmN1bjDlUslBjWNbFlD9y12Q==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", "cpu": [ "x64" ], @@ -671,9 +820,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.12.tgz", - "integrity": "sha512-GIIHtQXqgeOOqdG16a/A9N28GpkvjJnjYMhOnXVbn3EDJcoItdR58v/pGN31CHjyXDc8uCcRnFWmqaJt24AYJg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", "cpu": [ "arm64" ], @@ -687,9 +836,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.12.tgz", - "integrity": "sha512-zK0b9a1/0wZY+6FdOS3BpZcPc1kcx2G5yxxfEJtEUzVxI6n/FrC2Phsxj/YblPuBchhBZ/1wwn7AyEBUyNSa6g==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", "cpu": [ "x64" ], @@ -703,9 +852,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.12.tgz", - "integrity": "sha512-y75OijvrBE/1XRrXq1jtrJfG26eHeMoqLJ2dwQNwviwTuTtHGCojsDO6BJNF8gU+3jTn1KzJEMETytwsFSvc+Q==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", "cpu": [ "arm" ], @@ -719,9 +868,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.12.tgz", - "integrity": "sha512-JKgG8Q/LL/9sw/iHHxQyVMoQYu3rU3+a5Z87DxC+wAu3engz+EmctIrV+FGOgI6gWG1z1+5nDDbXiRMGQZXqiw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", "cpu": [ "arm64" ], @@ -735,9 +884,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.12.tgz", - "integrity": "sha512-yoRIAqc0B4lDIAAEFEIu9ttTRFV84iuAl0KNCN6MhKLxNPfzwCBvEMgwco2f71GxmpBcTtn7KdErueZaM2rEvw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", "cpu": [ "ia32" ], @@ -751,9 +900,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.12.tgz", - "integrity": "sha512-qYgt3dHPVvf/MgbIBpJ4Sup/yb9DAopZ3a2JgMpNKIHUpOdnJ2eHBo/aQdnd8dJ21X/+sS58wxHtA9lEazYtXQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", "cpu": [ "loong64" ], @@ -767,9 +916,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.12.tgz", - "integrity": "sha512-wHphlMLK4ufNOONqukELfVIbnGQJrHJ/mxZMMrP2jYrPgCRZhOtf0kC4yAXBwnfmULimV1qt5UJJOw4Kh13Yfg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", "cpu": [ "mips64el" ], @@ -783,9 +932,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.12.tgz", - "integrity": "sha512-TeN//1Ft20ZZW41+zDSdOI/Os1bEq5dbvBvYkberB7PHABbRcsteeoNVZFlI0YLpGdlBqohEpjrn06kv8heCJg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", "cpu": [ "ppc64" ], @@ -799,9 +948,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.12.tgz", - "integrity": "sha512-AgUebVS4DoAblBgiB2ACQ/8l4eGE5aWBb8ZXtkXHiET9mbj7GuWt3OnsIW/zX+XHJt2RYJZctbQ2S/mDjbp0UA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", "cpu": [ "riscv64" ], @@ -815,9 +964,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.12.tgz", - "integrity": "sha512-dJ3Rb3Ei2u/ysSXd6pzleGtfDdc2MuzKt8qc6ls8vreP1G3B7HInX3i7gXS4BGeVd24pp0yqyS7bJ5NHaI9ing==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", "cpu": [ "s390x" ], @@ -831,9 +980,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.12.tgz", - "integrity": "sha512-OrNJMGQbPaVyHHcDF8ybNSwu7TDOfX8NGpXCbetwOSP6txOJiWlgQnRymfC9ocR1S0Y5PW0Wb1mV6pUddqmvmQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", "cpu": [ "x64" ], @@ -847,9 +996,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.12.tgz", - "integrity": "sha512-55FzVCAiwE9FK8wWeCRuvjazNRJ1QqLCYGZVB6E8RuQuTeStSwotpSW4xoRGwp3a1wUsaVCdYcj5LGCASVJmMg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", "cpu": [ "x64" ], @@ -863,9 +1012,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.12.tgz", - "integrity": "sha512-qnluf8rfb6Y5Lw2tirfK2quZOBbVqmwxut7GPCIJsM8lc4AEUj9L8y0YPdLaPK0TECt4IdyBdBD/KRFKorlK3g==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", "cpu": [ "x64" ], @@ -879,9 +1028,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.12.tgz", - "integrity": "sha512-+RkKpVQR7bICjTOPUpkTBTaJ4TFqQBX5Ywyd/HSdDkQGn65VPkTsR/pL4AMvuMWy+wnXgIl4EY6q4mVpJal8Kg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", "cpu": [ "x64" ], @@ -895,9 +1044,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.12.tgz", - "integrity": "sha512-GNHuciv0mFM7ouzsU0+AwY+7eV4Mgo5WnbhfDCQGtpvOtD1vbOiRjPYG6dhmMoFyBjj+pNqQu2X+7DKn0KQ/Gw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", "cpu": [ "arm64" ], @@ -911,9 +1060,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.12.tgz", - "integrity": "sha512-kR8cezhYipbbypGkaqCTWIeu4zID17gamC8YTPXYtcN3E5BhhtTnwKBn9I0PJur/T6UVwIEGYzkffNL0lFvxEw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", "cpu": [ "ia32" ], @@ -927,9 +1076,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.12.tgz", - "integrity": "sha512-O0UYQVkvfM/jO8a4OwoV0mAKSJw+mjWTAd1MJd/1FCX6uiMdLmMRPK/w6e9OQ0ob2WGxzIm9va/KG0Ja4zIOgg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", "cpu": [ "x64" ], @@ -943,9 +1092,9 @@ } }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -955,9 +1104,9 @@ } }, "node_modules/ansi-sequence-parser": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", - "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", + "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", "dev": true }, "node_modules/anymatch": { @@ -1043,9 +1192,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.21.10", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", + "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, "funding": [ { @@ -1055,13 +1204,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001517", + "electron-to-chromium": "^1.4.477", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.11" }, "bin": { "browserslist": "cli.js" @@ -1071,9 +1224,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001481", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz", - "integrity": "sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==", + "version": "1.0.30001519", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz", + "integrity": "sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==", "dev": true, "funding": [ { @@ -1174,14 +1327,20 @@ } }, "node_modules/cssdb": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.5.4.tgz", - "integrity": "sha512-fGD+J6Jlq+aurfE1VDXlLS4Pt0VtNlu2+YgfGOdMxRyl/HQ9bDiHTwSck1Yz8A97Dt/82izSK6Bp/4nVqacOsg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.7.0.tgz", + "integrity": "sha512-1hN+I3r4VqSNQ+OmMXxYexnumbOONkSil0TWMebVXHtzYW4tRRPovUNHPHj2d4nrgOuYJ8Vs3XwvywsuwwXNNA==", "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ] }, "node_modules/cssesc": { "version": "3.0.0", @@ -1196,9 +1355,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.376", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.376.tgz", - "integrity": "sha512-TFeOKd98TpJzRHkr4Aorn16QkMnuCQuGAE6IZ0wYF+qkbSfMPqjplvRppR02tMUpVxZz8nyBNvVm9lIZsqrbPQ==", + "version": "1.4.489", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.489.tgz", + "integrity": "sha512-QNx+cirm4ENixfdSk9rp/3HKpjlxHFsmDoHtU1IiXdkJcpkKrd/o20LT5h1f3Qz+yfTMb4Ji3YDT/IvJkNfEkA==", "dev": true }, "node_modules/es-module-lexer": { @@ -1208,9 +1367,9 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.18.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.12.tgz", - "integrity": "sha512-XuOVLDdtsDslXStStduT41op21Ytmf4/BDS46aa3xPJ7X5h2eMWBF1oAe3QjUH3bDksocNXgzGUZ7XHIBya6Tg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "dev": true, "hasInstallScript": true, "bin": { @@ -1220,28 +1379,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.12", - "@esbuild/android-arm64": "0.18.12", - "@esbuild/android-x64": "0.18.12", - "@esbuild/darwin-arm64": "0.18.12", - "@esbuild/darwin-x64": "0.18.12", - "@esbuild/freebsd-arm64": "0.18.12", - "@esbuild/freebsd-x64": "0.18.12", - "@esbuild/linux-arm": "0.18.12", - "@esbuild/linux-arm64": "0.18.12", - "@esbuild/linux-ia32": "0.18.12", - "@esbuild/linux-loong64": "0.18.12", - "@esbuild/linux-mips64el": "0.18.12", - "@esbuild/linux-ppc64": "0.18.12", - "@esbuild/linux-riscv64": "0.18.12", - "@esbuild/linux-s390x": "0.18.12", - "@esbuild/linux-x64": "0.18.12", - "@esbuild/netbsd-x64": "0.18.12", - "@esbuild/openbsd-x64": "0.18.12", - "@esbuild/sunos-x64": "0.18.12", - "@esbuild/win32-arm64": "0.18.12", - "@esbuild/win32-ia32": "0.18.12", - "@esbuild/win32-x64": "0.18.12" + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" } }, "node_modules/escalade": { @@ -1325,9 +1484,9 @@ "dev": true }, "node_modules/immutable": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", - "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.2.tgz", + "integrity": "sha512-oGXzbEDem9OOpDWZu88jGiYCvIsLHMvGw+8OXlpsvTFvIQplQbjg1B1cvKg8f7Hoch6+NGjpPsH1Fr+Mc2D1aA==", "dev": true }, "node_modules/is-binary-path": { @@ -1451,9 +1610,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, "node_modules/normalize-path": { @@ -1493,9 +1652,9 @@ } }, "node_modules/postcss": { - "version": "8.4.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz", - "integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==", + "version": "8.4.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", + "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", "dev": true, "funding": [ { @@ -1555,20 +1714,27 @@ } }, "node_modules/postcss-color-functional-notation": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-5.0.2.tgz", - "integrity": "sha512-M6ygxWOyd6eWf3sd1Lv8xi4SeF4iBPfJvkfMU4ITh8ExJc1qhbvh/U8Cv/uOvBgUVOMDdScvCdlg8+hREQzs7w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-5.1.0.tgz", + "integrity": "sha512-w2R4py6zrVE1U7FwNaAc76tNQlG9GLkrBbcFw+VhUjyDDiV28vfZG+l4LyPmpoQpeSJVtu8VgNjE8Jv5SpC7dQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } @@ -1612,67 +1778,85 @@ } }, "node_modules/postcss-custom-media": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-9.1.3.tgz", - "integrity": "sha512-W1C4Fu6KAZ7sKYQCuGMr8gyaE4BtjTQGPLVS4m0WCaWM6l7PgVbvmDeb4ClBc5R/7kdwESYf0hdxGtEPhi9CLA==", + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-9.1.5.tgz", + "integrity": "sha512-GStyWMz7Qbo/Gtw1xVspzVSX8eipgNg4lpsO3CAeY4/A1mzok+RV6MCv3fg62trWijh/lYEj6vps4o8JcBBpDA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { "@csstools/cascade-layer-name-parser": "^1.0.2", - "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/css-parser-algorithms": "^2.2.0", "@csstools/css-tokenizer": "^2.1.1", - "@csstools/media-query-list-parser": "^2.0.4" + "@csstools/media-query-list-parser": "^2.1.1" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } }, "node_modules/postcss-custom-properties": { - "version": "13.1.5", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-13.1.5.tgz", - "integrity": "sha512-98DXk81zTGqMVkGANysMHbGIg3voH383DYo3/+c+Abzay3nao+vM/f4Jgzsakk9S7BDsEw5DiW7sFy5G4W2wLA==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-13.3.0.tgz", + "integrity": "sha512-q4VgtIKSy5+KcUvQ0WxTjDy9DZjQ5VCXAZ9+tT9+aPMbA0z6s2t1nMw0QHszru1ib5ElkXl9JUpYYU37VVUs7g==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/cascade-layer-name-parser": "^1.0.2", - "@csstools/css-parser-algorithms": "^2.1.1", - "@csstools/css-tokenizer": "^2.1.1", + "@csstools/cascade-layer-name-parser": "^1.0.4", + "@csstools/css-parser-algorithms": "^2.3.1", + "@csstools/css-tokenizer": "^2.2.0", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } }, "node_modules/postcss-custom-selectors": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-7.1.3.tgz", - "integrity": "sha512-GTVscax6O/8s7agFF0HsOoIyjrnAbLjgCUle8tn+0oDGJuVx7p56U7ClSRoC49poxFuMfu2B4Q8GnxSCOeuFKw==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-7.1.4.tgz", + "integrity": "sha512-TU2xyUUBTlpiLnwyE2ZYMUIYB41MKMkBZ8X8ntkqRDQ8sdBLhFFsPgNcOliBd5+/zcK51C9hRnSE7hKUJMxQSw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/cascade-layer-name-parser": "^1.0.2", - "@csstools/css-parser-algorithms": "^2.1.1", + "@csstools/cascade-layer-name-parser": "^1.0.3", + "@csstools/css-parser-algorithms": "^2.3.0", "@csstools/css-tokenizer": "^2.1.1", - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^6.0.13" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } @@ -1697,21 +1881,27 @@ } }, "node_modules/postcss-double-position-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-4.0.2.tgz", - "integrity": "sha512-GXL1RmFREDK4Q9aYvI2RhVrA6a6qqSMQQ5ke8gSH1xgV6exsqbcJpIumC7AOgooH6/WIG3/K/T8xxAiVHy/tJg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-4.0.4.tgz", + "integrity": "sha512-nUAbUXURemLXIrl4Xoia2tiu5z/n8sY+BVDZApoeT9BlpByyrp02P/lFCRrRvZ/zrGRE+MOGLhk8o7VcMCtPtQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^2.0.0", + "@csstools/postcss-progressive-custom-properties": "^2.3.0", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } @@ -1808,51 +1998,73 @@ } }, "node_modules/postcss-lab-function": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-5.2.1.tgz", - "integrity": "sha512-u71Adr4nWi+4EmSZq5EV/fg9d1dYO6W26RNtT9LISEyjhH1q23vJIUkSqRwHgD6v7xxsxLOY5cSdVyaNE6rqzw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-5.2.3.tgz", + "integrity": "sha512-fi32AYKzji5/rvgxo5zXHFvAYBw0u0OzELbeCNjEZVLUir18Oj+9RmNphtM8QdLUaUnrfx8zy8vVYLmFLkdmrQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { - "@csstools/css-color-parser": "^1.1.2", + "@csstools/css-color-parser": "^1.2.0", "@csstools/css-parser-algorithms": "^2.1.1", "@csstools/css-tokenizer": "^2.1.1", - "@csstools/postcss-progressive-custom-properties": "^2.0.0" + "@csstools/postcss-progressive-custom-properties": "^2.3.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } }, "node_modules/postcss-logical": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-6.1.0.tgz", - "integrity": "sha512-qb1+LpClhYjxac8SfOcWotnY3unKZesDqIOm+jnGt8rTl7xaIWpE2bPGZHxflOip1E/4ETo79qlJyRL3yrHn1g==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-6.2.0.tgz", + "integrity": "sha512-aqlfKGaY0nnbgI9jwUikp4gJKBqcH5noU/EdnIVceghaaDPYhZuyJVxlvWNy55tlTG5tunRKCTAX9yljLiFgmw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } }, "node_modules/postcss-nesting": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-11.2.2.tgz", - "integrity": "sha512-aOTiUniAB1bcPE6GGiynWRa6PZFPhOTAm5q3q5cem6QeSijIHHkWr6gs65ukCZMXeak8yXeZVbBJET3VM+HlhA==", + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-11.3.0.tgz", + "integrity": "sha512-JlS10AQm/RzyrUGgl5irVkAlZYTJ99mNueUl+Qab+TcHhVedLiylWVkKBhRale+rS9yWIJK48JVzQlq3LcSdeA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], "dependencies": { "@csstools/selector-specificity": "^2.0.0", "postcss-selector-parser": "^6.0.10" @@ -1860,10 +2072,6 @@ "engines": { "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, "peerDependencies": { "postcss": "^8.4" } @@ -1938,9 +2146,9 @@ } }, "node_modules/postcss-preset-env": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-8.3.2.tgz", - "integrity": "sha512-VSAOsfxTXzO/gX5QljC8x8hN3ABbD9iqqLgqHqohBdNI5FhJptwpl96kpu+kYvvzK7BWwaHYou0IeYrp+NqmcQ==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-8.5.1.tgz", + "integrity": "sha512-qhWnJJjP6ArLUINWJ38t6Aftxnv9NW6cXK0NuwcLCcRilbuw72dSFLkCVUJeCfHGgJiKzX+pnhkGiki0PEynWg==", "dev": true, "funding": [ { @@ -1954,52 +2162,53 @@ ], "dependencies": { "@csstools/postcss-cascade-layers": "^3.0.1", - "@csstools/postcss-color-function": "^2.2.1", - "@csstools/postcss-color-mix-function": "^1.0.1", + "@csstools/postcss-color-function": "^2.2.3", + "@csstools/postcss-color-mix-function": "^1.0.3", "@csstools/postcss-font-format-keywords": "^2.0.2", - "@csstools/postcss-gradients-interpolation-method": "^3.0.4", - "@csstools/postcss-hwb-function": "^2.2.1", - "@csstools/postcss-ic-unit": "^2.0.2", - "@csstools/postcss-is-pseudo-class": "^3.2.0", + "@csstools/postcss-gradients-interpolation-method": "^3.0.6", + "@csstools/postcss-hwb-function": "^2.2.2", + "@csstools/postcss-ic-unit": "^2.0.4", + "@csstools/postcss-is-pseudo-class": "^3.2.1", "@csstools/postcss-logical-float-and-clear": "^1.0.1", "@csstools/postcss-logical-resize": "^1.0.1", "@csstools/postcss-logical-viewport-units": "^1.0.3", - "@csstools/postcss-media-minmax": "^1.0.2", - "@csstools/postcss-media-queries-aspect-ratio-number-values": "^1.0.2", + "@csstools/postcss-media-minmax": "^1.0.4", + "@csstools/postcss-media-queries-aspect-ratio-number-values": "^1.0.4", "@csstools/postcss-nested-calc": "^2.0.2", "@csstools/postcss-normalize-display-values": "^2.0.1", - "@csstools/postcss-oklab-function": "^2.2.1", - "@csstools/postcss-progressive-custom-properties": "^2.1.0", + "@csstools/postcss-oklab-function": "^2.2.3", + "@csstools/postcss-progressive-custom-properties": "^2.3.0", + "@csstools/postcss-relative-color-syntax": "^1.0.2", "@csstools/postcss-scope-pseudo-class": "^2.0.2", "@csstools/postcss-stepped-value-functions": "^2.1.1", - "@csstools/postcss-text-decoration-shorthand": "^2.2.3", + "@csstools/postcss-text-decoration-shorthand": "^2.2.4", "@csstools/postcss-trigonometric-functions": "^2.1.1", "@csstools/postcss-unset-value": "^2.0.1", "autoprefixer": "^10.4.14", - "browserslist": "^4.21.5", + "browserslist": "^4.21.9", "css-blank-pseudo": "^5.0.2", "css-has-pseudo": "^5.0.2", "css-prefers-color-scheme": "^8.0.2", - "cssdb": "^7.5.3", + "cssdb": "^7.6.0", "postcss-attribute-case-insensitive": "^6.0.2", "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^5.0.2", + "postcss-color-functional-notation": "^5.1.0", "postcss-color-hex-alpha": "^9.0.2", "postcss-color-rebeccapurple": "^8.0.2", - "postcss-custom-media": "^9.1.3", - "postcss-custom-properties": "^13.1.5", + "postcss-custom-media": "^9.1.5", + "postcss-custom-properties": "^13.2.0", "postcss-custom-selectors": "^7.1.3", "postcss-dir-pseudo-class": "^7.0.2", - "postcss-double-position-gradients": "^4.0.2", + "postcss-double-position-gradients": "^4.0.4", "postcss-focus-visible": "^8.0.2", "postcss-focus-within": "^7.0.2", "postcss-font-variant": "^5.0.0", "postcss-gap-properties": "^4.0.1", "postcss-image-set-function": "^5.0.2", "postcss-initial": "^4.0.1", - "postcss-lab-function": "^5.2.1", - "postcss-logical": "^6.1.0", - "postcss-nesting": "^11.2.1", + "postcss-lab-function": "^5.2.3", + "postcss-logical": "^6.2.0", + "postcss-nesting": "^11.3.0", "postcss-opacity-percentage": "^2.0.0", "postcss-overflow-shorthand": "^4.0.1", "postcss-page-break": "^3.0.4", @@ -2064,9 +2273,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", - "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -2095,9 +2304,9 @@ } }, "node_modules/rollup": { - "version": "3.26.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.26.2.tgz", - "integrity": "sha512-6umBIGVz93er97pMgQO08LuH3m6PUb3jlDUUGFsNJB6VgTCUaDFpupf5JfU30529m/UKOgmiX+uY6Sx8cOYpLA==", + "version": "3.28.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.0.tgz", + "integrity": "sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -2111,9 +2320,9 @@ } }, "node_modules/sass": { - "version": "1.62.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz", - "integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==", + "version": "1.65.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.65.1.tgz", + "integrity": "sha512-9DINwtHmA41SEd36eVPQ9BJKpn7eKDQmUHmpI0y5Zv2Rcorrh0zS+cFrt050hdNbmmCNKTW3hV5mWfuegNRsEA==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -2248,14 +2457,14 @@ "dev": true }, "node_modules/vite": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.3.tgz", - "integrity": "sha512-IMnXQXXWgLi5brBQx/4WzDxdzW0X3pjO4nqFJAuNvwKtxzAmPzFE1wszW3VDpAGQJm3RZkm/brzRdyGsnwgJIA==", + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", + "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", "dev": true, "dependencies": { "esbuild": "^0.18.10", - "postcss": "^8.4.25", - "rollup": "^3.25.2" + "postcss": "^8.4.27", + "rollup": "^3.27.1" }, "bin": { "vite": "bin/vite.js"