Compare commits

..

No commits in common. "9eacc691e4dd413fde54996eae6651b7adf967e8" and "7a67557f4c796bbc95248fa4d1b90dd06e5e8a18" have entirely different histories.

39 changed files with 2943 additions and 3123 deletions

View File

@ -1 +1 @@
{"name":"weweb-front","version":"4.0.0","private":true,"type":"module","scripts":{"serve":"vite","build":"vite build","postbuild":"node ./postbuild.js"},"dependencies":{"@vueuse/head":"2.0.0","axios":"1.9.0","html-escaper":"3.0.3","lodash":"4.17.21","pinia":"3.0.2","short-unique-id":"5.3.2","tiny-emitter":"2.1.0","uuid":"11.1.0","vue":"3.5.13","vue-cookie-next":"1.3.0","vue-meta":"2.4.0","vue-router":"4.5.1","vuex":"4.1.0","dayjs":"1.11.0","@supabase/supabase-js":"2.50.3","qs":"^6.14.0","@vueform/multiselect":"2.6.2","vue-ellipse-progress":"^2.1.1","@vueuse/core":"^13.0.0","@vuepic/vue-datepicker":"3.6.8","date-fns":"4.1.0","diff":"^5.1.0","animejs":"^3.2.2","marked":"^14.1.2","medium-zoom":"^1.0.6","prismjs":"^1.23.0","@tiptap/extension-color":"2.8.0","@tiptap/extension-image":"2.8.0","@tiptap/extension-link":"2.8.0","@tiptap/extension-mathematics":"2.26.1","@tiptap/extension-mention":"2.8.0","@tiptap/extension-placeholder":"2.8.0","@tiptap/extension-table":"2.8.0","@tiptap/extension-table-cell":"2.8.0","@tiptap/extension-table-header":"2.8.0","@tiptap/extension-table-row":"2.8.0","@tiptap/extension-task-item":"2.8.0","@tiptap/extension-task-list":"2.8.0","@tiptap/extension-text-align":"2.8.0","@tiptap/extension-text-style":"2.8.0","@tiptap/extension-underline":"2.8.0","@tiptap/pm":"2.8.0","@tiptap/starter-kit":"2.8.0","@tiptap/suggestion":"2.8.0","@tiptap/vue-3":"2.8.0","katex":"^0.16.22","prosemirror-commands":"1.5.0","prosemirror-dropcursor":"1.5.0","prosemirror-gapcursor":"1.3.1","prosemirror-history":"1.3.0","prosemirror-keymap":"1.2.0","prosemirror-schema-list":"1.2.2","tiptap-markdown":"^0.8.10","lodash-es":"^4.17.21"},"devDependencies":{"@vitejs/plugin-vue":"5.2.4","autoprefixer":"10.4.21","handlebars":"4.7.8","sass-embedded":"1.89.0","vite":"6.3.5","vite-plugin-node-polyfills":"0.23.0"},"browserslist":["last 3 years"]}
{"name":"weweb-front","version":"4.0.0","private":true,"type":"module","scripts":{"serve":"vite","build":"vite build","postbuild":"node ./postbuild.js"},"dependencies":{"@vueuse/head":"2.0.0","axios":"1.9.0","html-escaper":"3.0.3","lodash":"4.17.21","pinia":"3.0.2","short-unique-id":"5.3.2","tiny-emitter":"2.1.0","uuid":"11.1.0","vue":"3.5.13","vue-cookie-next":"1.3.0","vue-meta":"2.4.0","vue-router":"4.5.1","vuex":"4.1.0","dayjs":"1.11.0","@supabase/supabase-js":"2.50.3","qs":"^6.14.0","@vueform/multiselect":"2.6.2","vue-ellipse-progress":"^2.1.1","@vueuse/core":"^13.0.0","@vuepic/vue-datepicker":"3.6.8","date-fns":"4.1.0","diff":"^5.1.0","animejs":"^3.2.2","marked":"^14.1.2","medium-zoom":"^1.0.6","prismjs":"^1.23.0","@tiptap/extension-color":"2.8.0","@tiptap/extension-image":"2.8.0","@tiptap/extension-link":"2.8.0","@tiptap/extension-mention":"2.8.0","@tiptap/extension-placeholder":"2.8.0","@tiptap/extension-table":"2.8.0","@tiptap/extension-table-cell":"2.8.0","@tiptap/extension-table-header":"2.8.0","@tiptap/extension-table-row":"2.8.0","@tiptap/extension-task-item":"2.8.0","@tiptap/extension-task-list":"2.8.0","@tiptap/extension-text-align":"2.8.0","@tiptap/extension-text-style":"2.8.0","@tiptap/extension-underline":"2.8.0","@tiptap/pm":"2.8.0","@tiptap/starter-kit":"2.8.0","@tiptap/suggestion":"2.8.0","@tiptap/vue-3":"2.8.0","prosemirror-commands":"1.5.0","prosemirror-dropcursor":"1.5.0","prosemirror-gapcursor":"1.3.1","prosemirror-history":"1.3.0","prosemirror-keymap":"1.2.0","prosemirror-schema-list":"1.2.2","tiptap-markdown":"^0.8.10","lodash-es":"^4.17.21"},"devDependencies":{"@vitejs/plugin-vue":"5.2.4","autoprefixer":"10.4.21","handlebars":"4.7.8","sass-embedded":"1.89.0","vite":"6.3.5","vite-plugin-node-polyfills":"0.23.0"},"browserslist":["last 3 years"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"cacheVersion":175,"page":{"id":"cf9f551f-e733-4934-a682-535575cb7c70","paths":{"en":"promo","default":"promo"},"cmsDataSetPath":null,"workflows":[]},"sections":{"4a2188f6-d98c-4150-9ba7-5918c72f3421":{"uid":"4a2188f6-d98c-4150-9ba7-5918c72f3421","linkId":"416695e7-e54e-4897-9f9a-befeb223f1b0","_state":{"style":{"default":{}}},"content":{"default":{"wwObjects":[],"_ww-layout_alignItems":"flex-start","_ww-layout_flexDirection":"column"}},"sectionBaseId":"99586bd3-2b15-4d6b-a025-6a50d07ca845","sectionTitle":"Section"}},"wwObjects":{},"collections":[],"variables":[],"workflows":[],"formulas":[],"libraryComponents":[]}
{"cacheVersion":170,"page":{"id":"cf9f551f-e733-4934-a682-535575cb7c70","paths":{"en":"promo","default":"promo"},"cmsDataSetPath":null,"workflows":[]},"sections":{"4a2188f6-d98c-4150-9ba7-5918c72f3421":{"uid":"4a2188f6-d98c-4150-9ba7-5918c72f3421","linkId":"416695e7-e54e-4897-9f9a-befeb223f1b0","_state":{"style":{"default":{}}},"content":{"default":{"wwObjects":[],"_ww-layout_alignItems":"flex-start","_ww-layout_flexDirection":"column"}},"sectionBaseId":"99586bd3-2b15-4d6b-a025-6a50d07ca845","sectionTitle":"Section"}},"wwObjects":{},"collections":[],"variables":[],"workflows":[],"formulas":[],"libraryComponents":[]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,14 +0,0 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M21 10.5V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h12.5" />
<path d="m9 11 3 3L22 4" />
</svg>

Before

Width:  |  Height:  |  Size: 316 B

View File

@ -1,13 +0,0 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect width="18" height="18" x="3" y="3" rx="2" />
</svg>

Before

Width:  |  Height:  |  Size: 261 B

View File

@ -1 +1 @@
{"name":"Образовательная платформа Meetguru","short_name":"Образовательная платформа Meetguru","icons":[{"src":"images/48-favicon.png?_wwcv=175","type":"image/png","sizes":"48x48"},{"src":"images/72-favicon.png?_wwcv=175","type":"image/png","sizes":"72x72"},{"src":"images/96-favicon.png?_wwcv=175","type":"image/png","sizes":"96x96"},{"src":"images/128-favicon.png?_wwcv=175","type":"image/png","sizes":"128x128"},{"src":"images/144-favicon.png?_wwcv=175","type":"image/png","sizes":"144x144"},{"src":"images/152-favicon.png?_wwcv=175","type":"image/png","sizes":"152x152"},{"src":"images/192-favicon.png?_wwcv=175","type":"image/png","sizes":"192x192"},{"src":"images/256-favicon.png?_wwcv=175","type":"image/png","sizes":"256x256"},{"src":"images/384-favicon.png?_wwcv=175","type":"image/png","sizes":"384x384"},{"src":"images/512-favicon.png?_wwcv=175","type":"image/png","sizes":"512x512"}],"start_url":"/","display":"fullscreen","scope":"/","background_color":"#FFFFFF","theme_color":"#FFFFFF"}
{"name":"Образовательная платформа Meetguru","short_name":"Образовательная платформа Meetguru","icons":[{"src":"images/48-favicon.png?_wwcv=170","type":"image/png","sizes":"48x48"},{"src":"images/72-favicon.png?_wwcv=170","type":"image/png","sizes":"72x72"},{"src":"images/96-favicon.png?_wwcv=170","type":"image/png","sizes":"96x96"},{"src":"images/128-favicon.png?_wwcv=170","type":"image/png","sizes":"128x128"},{"src":"images/144-favicon.png?_wwcv=170","type":"image/png","sizes":"144x144"},{"src":"images/152-favicon.png?_wwcv=170","type":"image/png","sizes":"152x152"},{"src":"images/192-favicon.png?_wwcv=170","type":"image/png","sizes":"192x192"},{"src":"images/256-favicon.png?_wwcv=170","type":"image/png","sizes":"256x256"},{"src":"images/384-favicon.png?_wwcv=170","type":"image/png","sizes":"384x384"},{"src":"images/512-favicon.png?_wwcv=170","type":"image/png","sizes":"512x512"}],"start_url":"/","display":"fullscreen","scope":"/","background_color":"#FFFFFF","theme_color":"#FFFFFF"}

View File

@ -1,4 +1,4 @@
const version = 175;
const version = 170;
self.addEventListener('install', event => {
// eslint-disable-next-line no-console
console.log(`Service worker v${version} installed`);

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"name":"ww-rich-text","version":"3.0.1","scripts":{"build":"weweb build","serve":"weweb serve"},"devDependencies":{"@vue/eslint-config-prettier":"^6.0.0","eslint":"^7.7.0","eslint-plugin-prettier":"^3.1.4","eslint-plugin-vue":"7.0.0-beta.4","prettier":"^2.1.2"},"dependencies":{"@tiptap/extension-color":"2.8.0","@tiptap/extension-image":"2.8.0","@tiptap/extension-link":"2.8.0","@tiptap/extension-mathematics":"2.26.1","@tiptap/extension-mention":"2.8.0","@tiptap/extension-placeholder":"2.8.0","@tiptap/extension-table":"2.8.0","@tiptap/extension-table-cell":"2.8.0","@tiptap/extension-table-header":"2.8.0","@tiptap/extension-table-row":"2.8.0","@tiptap/extension-task-item":"2.8.0","@tiptap/extension-task-list":"2.8.0","@tiptap/extension-text-align":"2.8.0","@tiptap/extension-text-style":"2.8.0","@tiptap/extension-underline":"2.8.0","@tiptap/pm":"2.8.0","@tiptap/starter-kit":"2.8.0","@tiptap/suggestion":"2.8.0","@tiptap/vue-3":"2.8.0","katex":"^0.16.22","prosemirror-commands":"1.5.0","prosemirror-dropcursor":"1.5.0","prosemirror-gapcursor":"1.3.1","prosemirror-history":"1.3.0","prosemirror-keymap":"1.2.0","prosemirror-schema-list":"1.2.2","tiptap-markdown":"^0.8.10"}}
{"name":"ww-rich-text","version":"3.0.1","scripts":{"build":"weweb build","serve":"weweb serve"},"devDependencies":{"@vue/eslint-config-prettier":"^6.0.0","eslint":"^7.7.0","eslint-plugin-prettier":"^3.1.4","eslint-plugin-vue":"7.0.0-beta.4","prettier":"^2.1.2"},"dependencies":{"@tiptap/extension-color":"2.8.0","@tiptap/extension-image":"2.8.0","@tiptap/extension-link":"2.8.0","@tiptap/extension-mention":"2.8.0","@tiptap/extension-placeholder":"2.8.0","@tiptap/extension-table":"2.8.0","@tiptap/extension-table-cell":"2.8.0","@tiptap/extension-table-header":"2.8.0","@tiptap/extension-table-row":"2.8.0","@tiptap/extension-task-item":"2.8.0","@tiptap/extension-task-list":"2.8.0","@tiptap/extension-text-align":"2.8.0","@tiptap/extension-text-style":"2.8.0","@tiptap/extension-underline":"2.8.0","@tiptap/pm":"2.8.0","@tiptap/starter-kit":"2.8.0","@tiptap/suggestion":"2.8.0","@tiptap/vue-3":"2.8.0","prosemirror-commands":"1.5.0","prosemirror-dropcursor":"1.5.0","prosemirror-gapcursor":"1.3.1","prosemirror-history":"1.3.0","prosemirror-keymap":"1.2.0","prosemirror-schema-list":"1.2.2","tiptap-markdown":"^0.8.10"}}

View File

@ -291,37 +291,7 @@
<i class="fas fa-quote-left"></i>
</button>
<!-- Math -->
<button
type="button"
class="ww-rich-text__menu-item"
@click="insertInlineMath()"
:disabled="!isEditable"
v-if="menu.inlineMath"
>
<i class="fas fa-subscript"></i>
</button>
<button
type="button"
class="ww-rich-text__menu-item"
@click="insertBlockMath()"
:disabled="!isEditable"
v-if="menu.blockMath"
>
<i class="fas fa-square-root-alt"></i>
</button>
<span
class="separator"
v-if="
menu.link ||
menu.image ||
menu.codeBlock ||
menu.blockquote ||
menu.inlineMath ||
menu.blockMath
"
></span>
<span class="separator" v-if="menu.link || menu.image || menu.codeBlock || menu.blockquote"></span>
<!-- Undo/Redo -->
<button
@ -351,7 +321,6 @@
</template>
<script>
import 'katex/dist/katex.min.css';
import { Editor, EditorContent } from '@tiptap/vue-3';
import StarterKit from '@tiptap/starter-kit';
import Mention from '@tiptap/extension-mention';
@ -368,7 +337,6 @@ import Table from '@tiptap/extension-table';
import TableCell from '@tiptap/extension-table-cell';
import TableHeader from '@tiptap/extension-table-header';
import TableRow from '@tiptap/extension-table-row';
import { Mathematics } from '@tiptap/extension-mathematics';
import { computed, inject } from 'vue';
import suggestion from './suggestion.js';
@ -405,10 +373,12 @@ export default {
content: { type: Object, required: true },
uid: { type: String, required: true },
wwElementState: { type: Object, required: true },
useForm: { type: Boolean, default: true },
},
emits: ['trigger-event', 'update:content:effect', 'update:sidepanel-content'],
setup(props, { emit }) {
const { value: variableValue, setValue } = wwLib.wwVariable.useComponentVariable({
uid: props.uid,
name: 'value',
@ -433,6 +403,7 @@ export default {
});
const randomUid = wwLib.wwUtils.getUid();
const useForm = inject('_wwForm:useForm', () => {});
@ -455,6 +426,7 @@ export default {
states,
setStates,
randomUid,
};
},
data: () => ({
@ -480,6 +452,7 @@ export default {
// If format changed
if (value !== this.getContent()) this.setValue(this.getContent());
},
isReadonly: {
immediate: true,
handler(value) {
@ -500,6 +473,7 @@ export default {
},
computed: {
isEditing() {
// eslint-disable-next-line no-unreachable
return false;
},
@ -521,15 +495,13 @@ export default {
textAlign: this.richEditor.isActive({ textAlign: 'left' })
? 'left'
: this.richEditor.isActive({ textAlign: 'center' })
? 'center'
: this.richEditor.isActive({ textAlign: 'right' })
? 'right'
: this.richEditor.isActive({ textAlign: 'justify' })
? 'justify'
: false,
? 'center'
: this.richEditor.isActive({ textAlign: 'right' })
? 'right'
: this.richEditor.isActive({ textAlign: 'justify' })
? 'justify'
: false,
table: this.richEditor.isActive('table'),
inlineMath: false,
blockMath: false,
};
},
currentColor() {
@ -585,8 +557,6 @@ export default {
image: this.content.parameterImage ?? false,
codeBlock: this.content.parameterCodeBlock ?? true,
blockquote: this.content.parameterQuote ?? true,
inlineMath: this.content.parameterInlineMath ?? false,
blockMath: this.content.parameterBlockMath ?? false,
undo: this.content.parameterUndo ?? true,
redo: this.content.parameterRedo ?? true,
};
@ -808,13 +778,8 @@ export default {
char: this.editorConfig.mention.char,
},
}),
Mathematics.configure({
katexOptions: {
throwOnError: false,
},
}),
],
onCreate: ({ editor: currentEditor }) => {
onCreate: () => {
this.setValue(this.getContent());
this.setMentions(this.richEditor.getJSON().content.reduce(extractMentions, []));
},
@ -878,6 +843,7 @@ export default {
if (this.content.customMenu) this.richEditor.commands.setImage({ src, alt, title });
else {
let url;
/* wwFront:start */
url = wwLib.getFrontWindow().prompt('Image URL');
/* wwFront:end */
@ -938,36 +904,6 @@ export default {
toggleBlockquote() {
this.richEditor.chain().focus().toggleBlockquote().run();
},
insertInlineMath(latex) {
// If latex is provided (from action), use it directly, otherwise prompt user
const latexExpression = latex || window.prompt('Enter inline LaTeX expression:', '');
if (latexExpression) {
// Insert with $ delimiters - the extension will auto-convert to rendered math
const fullExpression = `$${latexExpression}$`;
this.richEditor.chain().focus().insertContent(fullExpression).run();
// Force decoration update by updating the editor state
setTimeout(() => {
const { state } = this.richEditor;
this.richEditor.view.updateState(state);
}, 10);
}
},
insertBlockMath(latex) {
// If latex is provided (from action), use it directly, otherwise prompt user
const latexExpression = latex || window.prompt('Enter block LaTeX expression:', '');
if (latexExpression) {
// For v2.x, create block math using displaystyle
const blockContent = `<p style="text-align: center;">$\\displaystyle ${latexExpression}$</p>`;
this.richEditor.chain().focus().insertContent(blockContent).run();
// Force decoration update by updating the editor state
setTimeout(() => {
const { state } = this.richEditor;
this.richEditor.view.updateState(state);
}, 10);
}
},
undo() {
this.richEditor.chain().undo().run();
},
@ -1203,6 +1139,7 @@ export default {
cursor: pointer;
}
.mention {
border: var(--mention-borderSize) solid var(--mention-color);
border-radius: var(--mention-border-radius);
@ -1361,30 +1298,5 @@ export default {
&.-readonly .ProseMirror {
cursor: inherit;
}
// Mathematics extension styles
.Tiptap-mathematics-editor {
background: #202020;
color: #fff;
font-family: monospace;
padding: 0.2rem 0.5rem;
border-radius: 0.25rem;
display: inline-block;
}
.Tiptap-mathematics-render {
padding: 0 0.25rem;
border-radius: 0.25rem;
display: inline-block;
&--editable {
cursor: pointer;
transition: background 0.2s;
&:hover {
background: #eee;
}
}
}
}
</style>

View File

@ -84,8 +84,6 @@ export default {
'parameterImage',
'parameterCodeBlock',
'parameterQuote',
'parameterInlineMath',
'parameterBlockMath',
'parameterUndo',
'parameterRedo',
],
@ -185,26 +183,6 @@ export default {
{ label: 'Toggle Check List', action: 'toggleTaskList' },
{ label: 'Toggle Code Block', action: 'toggleCodeBlock' },
{ label: 'Toggle Blockquote', action: 'toggleBlockquote' },
{
label: 'Insert Inline Math',
action: 'insertInlineMath',
args: [
{
name: 'Inline LaTeX Expression',
type: 'Text',
},
],
},
{
label: 'Insert Block Math',
action: 'insertBlockMath',
args: [
{
name: 'Block LaTeX Expression',
type: 'Text',
},
],
},
{ label: 'Undo', action: 'undo' },
{ label: 'Redo', action: 'redo' },
// Table
@ -1544,50 +1522,6 @@ export default {
},
defaultValue: true,
},
parameterInlineMath: {
section: 'settings',
hidden: content => content.customMenu,
label: {
en: 'Inline math',
},
type: 'TextRadioGroup',
options: {
choices: [
{
value: true,
label: 'Show',
},
{
value: false,
default: true,
label: 'Hide',
},
],
},
defaultValue: false,
},
parameterBlockMath: {
section: 'settings',
hidden: content => content.customMenu,
label: {
en: 'Block math',
},
type: 'TextRadioGroup',
options: {
choices: [
{
value: true,
label: 'Show',
},
{
value: false,
default: true,
label: 'Hide',
},
],
},
defaultValue: false,
},
parameterUndo: {
section: 'settings',
hidden: content => content.customMenu,
@ -1632,6 +1566,7 @@ export default {
},
defaultValue: true,
},
fieldName: {
label: 'Field name',
section: 'settings',

View File

@ -12,20 +12,20 @@
<link rel="icon" type="image/x-icon" href="favicon.ico?_wwcv={{cacheVersion}}" />
<link rel="manifest" href="manifest.json?_wwcv=175" />
<link rel="manifest" href="manifest.json?_wwcv=170" />
<meta name="theme-color" content="" />
<link rel="apple-touch-icon" sizes="48x48" href="images/48-favicon.png?_wwcv=175">
<link rel="apple-touch-icon" sizes="72x72" href="images/72-favicon.png?_wwcv=175">
<link rel="apple-touch-icon" sizes="96x96" href="images/96-favicon.png?_wwcv=175">
<link rel="apple-touch-icon" sizes="128x128" href="images/128-favicon.png?_wwcv=175">
<link rel="apple-touch-icon" sizes="144x144" href="images/144-favicon.png?_wwcv=175">
<link rel="apple-touch-icon" sizes="152x152" href="images/152-favicon.png?_wwcv=175">
<link rel="apple-touch-icon" sizes="192x192" href="images/192-favicon.png?_wwcv=175">
<link rel="apple-touch-icon" sizes="256x256" href="images/256-favicon.png?_wwcv=175">
<link rel="apple-touch-icon" sizes="384x384" href="images/384-favicon.png?_wwcv=175">
<link rel="apple-touch-icon" sizes="512x512" href="images/512-favicon.png?_wwcv=175">
<link rel="apple-touch-icon" sizes="48x48" href="images/48-favicon.png?_wwcv=170">
<link rel="apple-touch-icon" sizes="72x72" href="images/72-favicon.png?_wwcv=170">
<link rel="apple-touch-icon" sizes="96x96" href="images/96-favicon.png?_wwcv=170">
<link rel="apple-touch-icon" sizes="128x128" href="images/128-favicon.png?_wwcv=170">
<link rel="apple-touch-icon" sizes="144x144" href="images/144-favicon.png?_wwcv=170">
<link rel="apple-touch-icon" sizes="152x152" href="images/152-favicon.png?_wwcv=170">
<link rel="apple-touch-icon" sizes="192x192" href="images/192-favicon.png?_wwcv=170">
<link rel="apple-touch-icon" sizes="256x256" href="images/256-favicon.png?_wwcv=170">
<link rel="apple-touch-icon" sizes="384x384" href="images/384-favicon.png?_wwcv=170">
<link rel="apple-touch-icon" sizes="512x512" href="images/512-favicon.png?_wwcv=170">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
<link href="/fonts/Phosphor/font.css?_wwcv=175" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
<link href="/fonts/Phosphor/font.css?_wwcv=170" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
<link href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
<style>:root{ --ww-default-font-family: 'Raleway', sans-serif }</style>
<style>

File diff suppressed because one or more lines are too long