add sentry

This commit is contained in:
MuslemRahimi 2024-09-19 16:04:35 +02:00
parent c7cd229cae
commit 4d74e55265
223 changed files with 181681 additions and 6262 deletions

View File

@ -1,7 +1,5 @@
<div align="center">
# **Open Source Stock Analysis for Data Freaks**
<h3>
@ -14,30 +12,35 @@
</div>
# Techstack
This is the codebase that powers [stocknear's](https://stocknear.com/) frontend, which is an open-source stock analysis & community platform.
Built with:
- [Sveltekit](https://kit.svelte.dev/): Frontend
- [Tailwindcss](https://tailwindcss.com/): Styling
- [DaisyUI](https://daisyui.com/): Styling
# Getting started
Coming soon to run stocknear locally on your machine.
# Contributing
Stocknear is open-source software and you're welcome to contribute to its development.
The core idea of stocknear shall always be: ***Fast*** & ***Simple***.
The core idea of stocknear shall always be: **_Fast_** & **_Simple_**.
If want to contribute to the codebase please follow these guidelines:
- Refactoring slow code into fast code is a huge plus!
- Reducing complexity and increasing simplicity/readability is a huge plus!
- If your PR looks "complex", is a big diff, or adds lots of lines, it won't be reviewed or merged. Consider breaking it up into smaller PRs that are individually clear wins. A common pattern I see is prerequisite refactors before adding new functionality. If you can (cleanly) refactor to the point that the feature is a 3 line change, this is great, and something easy for us to review.
# Support ❤️
If you love the idea of stocknear and want to support our mission you can help us in two ways:
- Become a [Pro Member](https://stocknear.com/pricing) of stocknear to get unlimited feature access to enjoy the platform to the fullest.
- You can donate money via [Ko-fi](https://ko-fi.com/stocknear) to help us pay the servers & data providers to keep everything running!

2035
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -98,6 +98,7 @@
},
"dependencies": {
"@aws-sdk/client-s3": "^3.556.0",
"@sentry/sveltekit": "^8.30.0",
"greeks": "^1.0.0",
"html2canvas": "^1.4.1",
"https": "^1.0.0",

View File

@ -1,18 +1,18 @@
import { defineConfig, devices } from '@playwright/test'; // import devices
import { defineConfig, devices } from "@playwright/test"; // import devices
export default defineConfig({
testDir: 'tests',
testDir: "tests",
projects: [
{
name: 'chromium',
name: "chromium",
use: {
...devices['Desktop Chrome'],
...devices["Desktop Chrome"],
},
},
{
name: 'safari',
name: "safari",
use: {
...devices['Iphone 6'],
...devices["Iphone 6"],
},
},
],

View File

@ -1,9 +1,7 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
};

View File

@ -2,10 +2,6 @@
@tailwind components;
@tailwind utilities;
.table {
@apply text-left text-sm rtl:text-right;
:where(th, td) {
@ -45,7 +41,6 @@
}
}
@layer utilities {
.no-scrollbar {
overflow-x: hidden;
@ -69,7 +64,6 @@
-ms-overflow-style: -ms-autohiding-scrollbar;
}
.shake-ticker:hover img {
animation-name: shake;
animation-duration: 0.5s;
@ -77,20 +71,24 @@
animation-timing-function: ease-in-out;
}
@keyframes shake {
0% { transform: rotate(0deg); }
25% { transform: rotate(10deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(-10deg); }
100% { transform: rotate(0deg); }
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(10deg);
}
50% {
transform: rotate(0deg);
}
75% {
transform: rotate(-10deg);
}
100% {
transform: rotate(0deg);
}
}
}
.loader,
.loader:before,
@ -117,7 +115,7 @@ animation-delay: -0.16s;
}
.loader:before,
.loader:after {
content: '';
content: "";
position: absolute;
top: 0;
}
@ -149,4 +147,3 @@ box-shadow: 0 2.5em 0 -1.3em;
box-shadow: 0 2.5em 0 0;
}
}

1
src/app.d.ts vendored
View File

@ -8,7 +8,6 @@ declare namespace App {
// interface Platform {}
}
// src/app.d.ts
/*
import PocketBase from "pocketbase";

View File

@ -1,22 +1,19 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en" class="bg-[#09090B]">
<head>
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link rel="manifest" href="%sveltekit.assets%/manifest.json" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
%sveltekit.head%
</head>
<!-- Global background color -->
<body data-sveltekit-preload-data="hover" class="bg-[#09090B] overflow-x-hidden">
<body
data-sveltekit-preload-data="hover"
class="bg-[#09090B] overflow-x-hidden"
>
<div>%sveltekit.body%</div>
</body>
</html>

View File

@ -69,4 +69,3 @@
--radius: 0.5rem;
}
}

11
src/hooks.client.js Normal file
View File

@ -0,0 +1,11 @@
import { handleErrorWithSentry, replayIntegration } from "@sentry/sveltekit";
import * as Sentry from "@sentry/sveltekit";
Sentry.init({
dsn: import.meta.env.VITE_SENTRY,
tracesSampleRate: 1.0,
});
// If you have a custom error handler, pass it to `handleErrorWithSentry`
export const handleError = handleErrorWithSentry();

View File

@ -1,7 +1,16 @@
import { sequence } from "@sveltejs/kit/hooks";
import * as Sentry from "@sentry/sveltekit";
import PocketBase from "pocketbase";
import { serializeNonPOJOs } from "$lib/utils";
export const handle = async ({ event, resolve }) => {
Sentry.init({
dsn: import.meta.env.VITE_SENTRY,
tracesSampleRate: 1,
});
export const handle = sequence(
Sentry.sentryHandle(),
async ({ event, resolve }) => {
// Use optional chaining and nullish coalescing for safer property access
const regionHeader =
event?.request?.headers?.get("x-vercel-id") ??
@ -72,4 +81,6 @@ export const handle = async ({ event, resolve }) => {
response.headers.append("set-cookie", cookieString);
return response;
};
}
);
export const handleError = Sentry.handleErrorWithSentry();

View File

@ -1,7 +1,7 @@
import { describe, it, expect } from 'vitest';
import { describe, it, expect } from "vitest";
describe('sum test', () => {
it('adds 1 + 2 to equal 3', () => {
describe("sum test", () => {
it("adds 1 + 2 to equal 3", () => {
expect(1 + 2).toBe(3);
});
});

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,11 @@
.driver-active .driver-overlay, .driver-active * {
.driver-active .driver-overlay,
.driver-active * {
pointer-events: none;
}
.driver-active .driver-active-element, .driver-active .driver-active-element *, .driver-popover, .driver-popover * {
.driver-active .driver-active-element,
.driver-active .driver-active-element *,
.driver-popover,
.driver-popover * {
pointer-events: auto;
}
@keyframes animate-fade-in {
@ -11,11 +15,12 @@
to {
opacity: 1;
}
}.driver-fade .driver-overlay {
animation: animate-fade-in .2s ease-in-out;
}
.driver-fade .driver-overlay {
animation: animate-fade-in 0.2s ease-in-out;
}
.driver-fade .driver-popover {
animation: animate-fade-in .2s;
animation: animate-fade-in 0.2s;
}
.driver-popover {
all: unset;
@ -34,7 +39,14 @@ to {
background-color: #202327;
}
.driver-popover * {
font-family: Helvetica Neue, Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif;
font-family:
Helvetica Neue,
Inter,
ui-sans-serif,
"Apple Color Emoji",
Helvetica,
Arial,
sans-serif;
}
.driver-popover-title {
font: 19px / normal sans-serif;
@ -59,12 +71,13 @@ to {
z-index: 1;
text-align: center;
transition: color;
transition-duration: .2s;
transition-duration: 0.2s;
}
.driver-popover-close-btn:hover, .driver-popover-close-btn:focus {
.driver-popover-close-btn:hover,
.driver-popover-close-btn:focus {
color: #2d2d2d;
}
.driver-popover-title[style*=block]+.driver-popover-description {
.driver-popover-title[style*="block"] + .driver-popover-description {
margin-top: 5px;
}
.driver-popover-description {
@ -106,16 +119,18 @@ to {
border-radius: 3px;
}
.driver-popover-footer .driver-popover-btn-disabled {
opacity: .5;
opacity: 0.5;
pointer-events: none;
}
:not(body):has(> .driver-active-element) {
overflow: hidden !important;
}
.driver-no-interaction, .driver-no-interaction * {
.driver-no-interaction,
.driver-no-interaction * {
pointer-events: none !important;
}
.driver-popover-footer button:hover, .driver-popover-footer button:focus {
.driver-popover-footer button:hover,
.driver-popover-footer button:focus {
background-color: #f7f7f7;
}
.driver-popover-navigation-btns {
@ -161,23 +176,29 @@ to {
.driver-popover-arrow-side-center {
display: none;
}
.driver-popover-arrow-side-left.driver-popover-arrow-align-start, .driver-popover-arrow-side-right.driver-popover-arrow-align-start {
.driver-popover-arrow-side-left.driver-popover-arrow-align-start,
.driver-popover-arrow-side-right.driver-popover-arrow-align-start {
top: 15px;
}
.driver-popover-arrow-side-top.driver-popover-arrow-align-start, .driver-popover-arrow-side-bottom.driver-popover-arrow-align-start {
.driver-popover-arrow-side-top.driver-popover-arrow-align-start,
.driver-popover-arrow-side-bottom.driver-popover-arrow-align-start {
left: 15px;
}
.driver-popover-arrow-align-end.driver-popover-arrow-side-left, .driver-popover-arrow-align-end.driver-popover-arrow-side-right {
.driver-popover-arrow-align-end.driver-popover-arrow-side-left,
.driver-popover-arrow-align-end.driver-popover-arrow-side-right {
bottom: 15px;
}
.driver-popover-arrow-side-top.driver-popover-arrow-align-end, .driver-popover-arrow-side-bottom.driver-popover-arrow-align-end {
.driver-popover-arrow-side-top.driver-popover-arrow-align-end,
.driver-popover-arrow-side-bottom.driver-popover-arrow-align-end {
right: 15px;
}
.driver-popover-arrow-side-left.driver-popover-arrow-align-center, .driver-popover-arrow-side-right.driver-popover-arrow-align-center {
.driver-popover-arrow-side-left.driver-popover-arrow-align-center,
.driver-popover-arrow-side-right.driver-popover-arrow-align-center {
top: 50%;
margin-top: -5px;
}
.driver-popover-arrow-side-top.driver-popover-arrow-align-center, .driver-popover-arrow-side-bottom.driver-popover-arrow-align-center {
.driver-popover-arrow-side-top.driver-popover-arrow-align-center,
.driver-popover-arrow-side-bottom.driver-popover-arrow-align-center {
left: 50%;
margin-left: -5px;
}

View File

@ -1,3 +1,3 @@
import Info from './Info.svelte';
import Info from "./Info.svelte";
export { Info };

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,6 @@
* Copyright (c) 2013, salesforce.com
*/
.ql-container {
box-sizing: border-box;
font-family: Helvetica, Arial, sans-serif;
@ -71,27 +70,27 @@
list-style-type: none;
}
.ql-editor ul > li::before {
content: '\2022';
content: "\2022";
}
.ql-editor ul[data-checked=true],
.ql-editor ul[data-checked=false] {
.ql-editor ul[data-checked="true"],
.ql-editor ul[data-checked="false"] {
pointer-events: none;
}
.ql-editor ul[data-checked=true] > li *,
.ql-editor ul[data-checked=false] > li * {
.ql-editor ul[data-checked="true"] > li *,
.ql-editor ul[data-checked="false"] > li * {
pointer-events: all;
}
.ql-editor ul[data-checked=true] > li::before,
.ql-editor ul[data-checked=false] > li::before {
.ql-editor ul[data-checked="true"] > li::before,
.ql-editor ul[data-checked="false"] > li::before {
color: #777;
cursor: pointer;
pointer-events: all;
}
.ql-editor ul[data-checked=true] > li::before {
content: '\2611';
.ql-editor ul[data-checked="true"] > li::before {
content: "\2611";
}
.ql-editor ul[data-checked=false] > li::before {
content: '\2610';
.ql-editor ul[data-checked="false"] > li::before {
content: "\2610";
}
.ql-editor li::before {
display: inline-block;
@ -120,13 +119,13 @@
counter-increment: list-0;
}
.ql-editor ol li:before {
content: counter(list-0, decimal) '. ';
content: counter(list-0, decimal) ". ";
}
.ql-editor ol li.ql-indent-1 {
counter-increment: list-1;
}
.ql-editor ol li.ql-indent-1:before {
content: counter(list-1, lower-alpha) '. ';
content: counter(list-1, lower-alpha) ". ";
}
.ql-editor ol li.ql-indent-1 {
counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
@ -135,7 +134,7 @@
counter-increment: list-2;
}
.ql-editor ol li.ql-indent-2:before {
content: counter(list-2, lower-roman) '. ';
content: counter(list-2, lower-roman) ". ";
}
.ql-editor ol li.ql-indent-2 {
counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9;
@ -144,7 +143,7 @@
counter-increment: list-3;
}
.ql-editor ol li.ql-indent-3:before {
content: counter(list-3, decimal) '. ';
content: counter(list-3, decimal) ". ";
}
.ql-editor ol li.ql-indent-3 {
counter-reset: list-4 list-5 list-6 list-7 list-8 list-9;
@ -153,7 +152,7 @@
counter-increment: list-4;
}
.ql-editor ol li.ql-indent-4:before {
content: counter(list-4, lower-alpha) '. ';
content: counter(list-4, lower-alpha) ". ";
}
.ql-editor ol li.ql-indent-4 {
counter-reset: list-5 list-6 list-7 list-8 list-9;
@ -162,7 +161,7 @@
counter-increment: list-5;
}
.ql-editor ol li.ql-indent-5:before {
content: counter(list-5, lower-roman) '. ';
content: counter(list-5, lower-roman) ". ";
}
.ql-editor ol li.ql-indent-5 {
counter-reset: list-6 list-7 list-8 list-9;
@ -171,7 +170,7 @@
counter-increment: list-6;
}
.ql-editor ol li.ql-indent-6:before {
content: counter(list-6, decimal) '. ';
content: counter(list-6, decimal) ". ";
}
.ql-editor ol li.ql-indent-6 {
counter-reset: list-7 list-8 list-9;
@ -180,7 +179,7 @@
counter-increment: list-7;
}
.ql-editor ol li.ql-indent-7:before {
content: counter(list-7, lower-alpha) '. ';
content: counter(list-7, lower-alpha) ". ";
}
.ql-editor ol li.ql-indent-7 {
counter-reset: list-8 list-9;
@ -189,7 +188,7 @@
counter-increment: list-8;
}
.ql-editor ol li.ql-indent-8:before {
content: counter(list-8, lower-roman) '. ';
content: counter(list-8, lower-roman) ". ";
}
.ql-editor ol li.ql-indent-8 {
counter-reset: list-9;
@ -198,7 +197,7 @@
counter-increment: list-9;
}
.ql-editor ol li.ql-indent-9:before {
content: counter(list-9, decimal) '. ';
content: counter(list-9, decimal) ". ";
}
.ql-editor .ql-indent-1:not(.ql-direction-rtl) {
padding-left: 3em;
@ -361,10 +360,16 @@
color: #93f;
}
.ql-editor .ql-font-serif {
font-family: Georgia, Times New Roman, serif;
font-family:
Georgia,
Times New Roman,
serif;
}
.ql-editor .ql-font-monospace {
font-family: Monaco, Courier New, monospace;
font-family:
Monaco,
Courier New,
monospace;
}
.ql-editor .ql-size-small {
font-size: 0.75em;
@ -389,7 +394,7 @@
text-align: right;
}
.ql-editor.ql-blank::before {
color: #9CA3AF ;
color: #9ca3af;
content: attr(data-placeholder);
font-style: italic;
left: 15px;
@ -400,7 +405,7 @@
.ql-snow.ql-toolbar:after,
.ql-snow .ql-toolbar:after {
clear: both;
content: '';
content: "";
display: table;
}
.ql-snow.ql-toolbar button,
@ -413,27 +418,22 @@
height: 28px;
padding: 3px 5px;
width: 32px;
}
.ql-snow.ql-toolbar button svg,
.ql-snow .ql-toolbar button svg {
float: left;
height: 100%;
}
.ql-snow.ql-toolbar button:active:hover,
.ql-snow .ql-toolbar button:active:hover {
outline: none;
background: #3E4E59;
background-color: #3E4E59;
border-color: #3E4E59;
background: #3e4e59;
background-color: #3e4e59;
border-color: #3e4e59;
}
.ql-snow.ql-toolbar input.ql-image[type=file],
.ql-snow .ql-toolbar input.ql-image[type=file] {
.ql-snow.ql-toolbar input.ql-image[type="file"],
.ql-snow .ql-toolbar input.ql-image[type="file"] {
display: none;
}
@ -452,9 +452,8 @@
.ql-snow.ql-toolbar .ql-picker-item.ql-selected,
.ql-snow .ql-toolbar .ql-picker-item.ql-selected {
color: #fff;
background: #3E4E59;
background: #3e4e59;
border-radius: 5%;
}
.ql-snow.ql-toolbar button:hover .ql-fill,
.ql-snow .ql-toolbar button:hover .ql-fill,
@ -485,8 +484,6 @@
.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill,
.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke.ql-fill {
fill: #fff;
}
.ql-snow.ql-toolbar button:hover .ql-stroke,
.ql-snow .ql-toolbar button:hover .ql-stroke,
@ -517,7 +514,6 @@
.ql-snow.ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter,
.ql-snow .ql-toolbar .ql-picker-item.ql-selected .ql-stroke-miter {
stroke: #fff;
}
@media (pointer: coarse) {
.ql-snow.ql-toolbar button:hover:not(.ql-active),
@ -557,8 +553,7 @@
.ql-snow .ql-tooltip a {
cursor: pointer;
text-decoration: none;
background-color: #3E4E59;
background-color: #3e4e59;
}
.ql-snow .ql-tooltip.ql-flip {
transform: translateY(-10px);
@ -569,7 +564,7 @@
}
.ql-snow .ql-formats:after {
clear: both;
content: '';
content: "";
display: table;
}
.ql-snow .ql-stroke {
@ -633,14 +628,14 @@
text-decoration: underline;
}
.ql-snow .ql-editor blockquote {
border-left: 4px solid #262B30;
border-left: 4px solid #262b30;
margin-bottom: 5px;
margin-top: 5px;
padding-left: 16px;
}
.ql-snow .ql-editor code,
.ql-snow .ql-editor pre {
background-color: #262B30;
background-color: #262b30;
border-radius: 3px;
}
.ql-snow .ql-editor pre {
@ -713,18 +708,15 @@
margin-top: -1px;
top: 100%;
z-index: 1;
background-color: #3E4E59;
background-color: #3e4e59;
}
#bg-color for heading selector
.ql-snow .ql-color-picker,
#bg-color for heading selector .ql-snow .ql-color-picker,
.ql-snow .ql-icon-picker {
width: 28px;
}
.ql-snow .ql-color-picker .ql-picker-label,
.ql-snow .ql-icon-picker .ql-picker-label {
padding: 2px 4px;
}
.ql-snow .ql-color-picker .ql-picker-label svg,
.ql-snow .ql-icon-picker .ql-picker-label svg {
@ -737,12 +729,10 @@
height: 24px;
width: 24px;
padding: 2px 4px;
}
.ql-snow .ql-color-picker .ql-picker-options {
padding: 3px 5px;
width: 152px;
}
.ql-snow .ql-color-picker .ql-picker-item {
border: 1px solid transparent;
@ -751,7 +741,6 @@
margin: 2px;
padding: 0px;
width: 16px;
}
.ql-snow .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg {
position: absolute;
@ -759,60 +748,63 @@
right: 0;
top: 50%;
width: 18px;
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-label]:not([data-label=''])::before,
.ql-snow .ql-picker.ql-font .ql-picker-label[data-label]:not([data-label=''])::before,
.ql-snow .ql-picker.ql-size .ql-picker-label[data-label]:not([data-label=''])::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-label]:not([data-label=''])::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-label]:not([data-label=''])::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-label]:not([data-label=''])::before {
.ql-snow
.ql-picker.ql-header
.ql-picker-label[data-label]:not([data-label=""])::before,
.ql-snow
.ql-picker.ql-font
.ql-picker-label[data-label]:not([data-label=""])::before,
.ql-snow
.ql-picker.ql-size
.ql-picker-label[data-label]:not([data-label=""])::before,
.ql-snow
.ql-picker.ql-header
.ql-picker-item[data-label]:not([data-label=""])::before,
.ql-snow
.ql-picker.ql-font
.ql-picker-item[data-label]:not([data-label=""])::before,
.ql-snow
.ql-picker.ql-size
.ql-picker-item[data-label]:not([data-label=""])::before {
content: attr(data-label);
}
.ql-snow .ql-picker.ql-header {
width: 98px;
}
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
content: 'Normal';
content: "Normal";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
content: 'Heading 1';
background-color: #3E4E59;
content: "Heading 1";
background-color: #3e4e59;
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
content: 'Heading 2';
background-color: #3E4E59;
content: "Heading 2";
background-color: #3e4e59;
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
content: 'Heading 3';
background-color: #3E4E59;
content: "Heading 3";
background-color: #3e4e59;
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
content: 'Heading 4';
background-color: #3E4E59;
content: "Heading 4";
background-color: #3e4e59;
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
content: 'Heading 5';
background-color: #3E4E59;
content: "Heading 5";
background-color: #3e4e59;
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
content: 'Heading 6';
background-color: #3E4E59;
content: "Heading 6";
background-color: #3e4e59;
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
font-size: 2em;
@ -831,59 +823,60 @@
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
font-size: 0.67em;
}
.ql-snow .ql-picker.ql-font {
width: 108px;
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: 'Sans Serif';
content: "Sans Serif";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=serif]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before {
content: 'Serif';
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
content: "Serif";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value=monospace]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before {
content: 'Monospace';
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
content: "Monospace";
}
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=serif]::before {
font-family: Georgia, Times New Roman, serif;
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
font-family:
Georgia,
Times New Roman,
serif;
}
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value=monospace]::before {
font-family: Monaco, Courier New, monospace;
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
font-family:
Monaco,
Courier New,
monospace;
}
.ql-snow .ql-picker.ql-size {
width: 98px;
}
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
content: 'Normal';
content: "Normal";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before {
content: 'Small';
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
content: "Small";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before {
content: 'Large';
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
content: "Large";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before {
content: 'Huge';
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
content: "Huge";
}
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before {
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
font-size: 10px;
}
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before {
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
font-size: 18px;
}
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before {
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
font-size: 32px;
}
.ql-snow .ql-color-picker.ql-background .ql-picker-item {
@ -893,11 +886,10 @@
background-color: #fff;
}
.ql-toolbar.ql-snow {
border: 1px solid #2A303C;
border: 1px solid #2a303c;
box-sizing: border-box;
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
padding: 8px;
}
.ql-toolbar.ql-snow .ql-formats {
margin-right: 15px;
@ -907,7 +899,6 @@
}
.ql-toolbar.ql-snow .ql-picker-options {
border: 1px solid transparent;
}
.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label {
border-color: #fff;
@ -921,10 +912,9 @@
}
.ql-toolbar.ql-snow + .ql-container.ql-snow {
border-top: 0px;
}
.ql-snow .ql-tooltip {
background-color: #3E4E59;
background-color: #3e4e59;
border: 1px solid #fff;
box-shadow: 0px 0px 5px #ddd;
@ -936,9 +926,8 @@
content: "Visit URL:";
line-height: 26px;
margin-right: 8px;
}
.ql-snow .ql-tooltip input[type=text] {
.ql-snow .ql-tooltip input[type="text"] {
display: none;
font-size: 13px;
height: 26px;
@ -946,7 +935,6 @@
padding: 3px 5px;
width: 170px;
color: #000;
}
.ql-snow .ql-tooltip a.ql-preview {
display: inline-block;
@ -954,46 +942,42 @@
overflow-x: hidden;
text-overflow: ellipsis;
vertical-align: top;
}
.ql-snow .ql-tooltip a.ql-action::after {
border-right: 1px solid #fff;
content: 'Edit';
content: "Edit";
margin-left: 16px;
padding-right: 8px;
background-color: #3E4E59;
background-color: #3e4e59;
}
.ql-snow .ql-tooltip a.ql-remove::before {
content: 'Remove';
content: "Remove";
margin-left: 8px;
background-color: #3E4E59;
background-color: #3e4e59;
}
.ql-snow .ql-tooltip a {
line-height: 26px;
background-color: #3E4E59;
background-color: #3e4e59;
}
.ql-snow .ql-tooltip.ql-editing a.ql-preview,
.ql-snow .ql-tooltip.ql-editing a.ql-remove {
display: none;
}
.ql-snow .ql-tooltip.ql-editing input[type=text] {
.ql-snow .ql-tooltip.ql-editing input[type="text"] {
display: inline-block;
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
border-right: 0px;
content: 'Save';
content: "Save";
padding-right: 0px;
}
.ql-snow .ql-tooltip[data-mode=link]::before {
.ql-snow .ql-tooltip[data-mode="link"]::before {
content: "Enter link:";
}
.ql-snow .ql-tooltip[data-mode=formula]::before {
.ql-snow .ql-tooltip[data-mode="formula"]::before {
content: "Enter formula:";
}
.ql-snow .ql-tooltip[data-mode=video]::before {
.ql-snow .ql-tooltip[data-mode="video"]::before {
content: "Enter video:";
}
.ql-snow a {
@ -1001,7 +985,6 @@
}
.ql-container.ql-snow {
font-size: 14px;
}
.ql-editor .ql-bold {
@ -1011,4 +994,3 @@
.ql-editor .ql-h1 {
color: #008a00;
}

View File

@ -5,7 +5,8 @@ export const badgeVariants = tv({
base: "inline-flex select-none items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
variants: {
variant: {
default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
default:
"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
secondary:
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive:

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,4 +1,161 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=("allow_html_in_named_anchor",e=>e.options.get("allow_html_in_named_anchor"));const a="a:not([href])",r=e=>!e,i=e=>e.getAttribute("id")||e.getAttribute("name")||"",l=e=>(e=>"a"===e.nodeName.toLowerCase())(e)&&!e.getAttribute("href")&&""!==i(e),s=e=>e.dom.getParent(e.selection.getStart(),a),d=(e,a)=>{const r=s(e);r?((e,t,o)=>{o.removeAttribute("name"),o.id=t,e.addVisual(),e.undoManager.add()})(e,a,r):((e,a)=>{e.undoManager.transact((()=>{n(e)||e.selection.collapse(!0),e.selection.isCollapsed()?e.insertContent(e.dom.createHTML("a",{id:a})):((e=>{const n=e.dom;t(n).walk(e.selection.getRng(),(e=>{o.each(e,(e=>{var t;l(t=e)&&!t.firstChild&&n.remove(e,!1)}))}))})(e),e.formatter.remove("namedAnchor",void 0,void 0,!0),e.formatter.apply("namedAnchor",{value:a}),e.addVisual())}))})(e,a),e.focus()},c=e=>(e=>r(e.attr("href"))&&!r(e.attr("id")||e.attr("name")))(e)&&!e.firstChild,m=e=>t=>{for(let o=0;o<t.length;o++){const n=t[o];c(n)&&n.attr("contenteditable",e)}},u=e=>t=>{const o=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",o),o(),()=>{e.off("NodeChange",o)}};e.add("anchor",(e=>{(e=>{(0,e.options.register)("allow_html_in_named_anchor",{processor:"boolean",default:!1})})(e),(e=>{e.on("PreInit",(()=>{e.parser.addNodeFilter("a",m("false")),e.serializer.addNodeFilter("a",m(null))}))})(e),(e=>{e.addCommand("mceAnchor",(()=>{(e=>{const t=(e=>{const t=s(e);return t?i(t):""})(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:t=>{((e,t)=>/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)?(d(e,t),!0):(e.windowManager.alert("ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!1))(e,t.getData().id)&&t.close()}})})(e)}))})(e),(e=>{const t=()=>e.execCommand("mceAnchor");e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:t,onSetup:t=>{const o=e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind,n=u(e)(t);return()=>{o(),n()}}}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:t,onSetup:u(e)})})(e),e.on("PreInit",(()=>{(e=>{e.formatter.register("namedAnchor",{inline:"a",selector:a,remove:"all",split:!0,deep:!0,attributes:{id:"%value"},onmatch:(e,t,o)=>l(e)})})(e)}))}))}();
!(function () {
"use strict";
var e = tinymce.util.Tools.resolve("tinymce.PluginManager"),
t = tinymce.util.Tools.resolve("tinymce.dom.RangeUtils"),
o = tinymce.util.Tools.resolve("tinymce.util.Tools");
const n =
("allow_html_in_named_anchor",
(e) => e.options.get("allow_html_in_named_anchor"));
const a = "a:not([href])",
r = (e) => !e,
i = (e) => e.getAttribute("id") || e.getAttribute("name") || "",
l = (e) =>
((e) => "a" === e.nodeName.toLowerCase())(e) &&
!e.getAttribute("href") &&
"" !== i(e),
s = (e) => e.dom.getParent(e.selection.getStart(), a),
d = (e, a) => {
const r = s(e);
r
? ((e, t, o) => {
o.removeAttribute("name"),
(o.id = t),
e.addVisual(),
e.undoManager.add();
})(e, a, r)
: ((e, a) => {
e.undoManager.transact(() => {
n(e) || e.selection.collapse(!0),
e.selection.isCollapsed()
? e.insertContent(e.dom.createHTML("a", { id: a }))
: (((e) => {
const n = e.dom;
t(n).walk(e.selection.getRng(), (e) => {
o.each(e, (e) => {
var t;
l((t = e)) && !t.firstChild && n.remove(e, !1);
});
});
})(e),
e.formatter.remove("namedAnchor", void 0, void 0, !0),
e.formatter.apply("namedAnchor", { value: a }),
e.addVisual());
});
})(e, a),
e.focus();
},
c = (e) =>
((e) => r(e.attr("href")) && !r(e.attr("id") || e.attr("name")))(e) &&
!e.firstChild,
m = (e) => (t) => {
for (let o = 0; o < t.length; o++) {
const n = t[o];
c(n) && n.attr("contenteditable", e);
}
},
u = (e) => (t) => {
const o = () => {
t.setEnabled(e.selection.isEditable());
};
return (
e.on("NodeChange", o),
o(),
() => {
e.off("NodeChange", o);
}
);
};
e.add("anchor", (e) => {
((e) => {
(0, e.options.register)("allow_html_in_named_anchor", {
processor: "boolean",
default: !1,
});
})(e),
((e) => {
e.on("PreInit", () => {
e.parser.addNodeFilter("a", m("false")),
e.serializer.addNodeFilter("a", m(null));
});
})(e),
((e) => {
e.addCommand("mceAnchor", () => {
((e) => {
const t = ((e) => {
const t = s(e);
return t ? i(t) : "";
})(e);
e.windowManager.open({
title: "Anchor",
size: "normal",
body: {
type: "panel",
items: [
{
name: "id",
type: "input",
label: "ID",
placeholder: "example",
},
],
},
buttons: [
{ type: "cancel", name: "cancel", text: "Cancel" },
{ type: "submit", name: "save", text: "Save", primary: !0 },
],
initialData: { id: t },
onSubmit: (t) => {
((e, t) =>
/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)
? (d(e, t), !0)
: (e.windowManager.alert(
"ID should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.",
),
!1))(e, t.getData().id) && t.close();
},
});
})(e);
});
})(e),
((e) => {
const t = () => e.execCommand("mceAnchor");
e.ui.registry.addToggleButton("anchor", {
icon: "bookmark",
tooltip: "Anchor",
onAction: t,
onSetup: (t) => {
const o = e.selection.selectorChangedWithUnbind(
"a:not([href])",
t.setActive,
).unbind,
n = u(e)(t);
return () => {
o(), n();
};
},
}),
e.ui.registry.addMenuItem("anchor", {
icon: "bookmark",
text: "Anchor...",
onAction: t,
onSetup: u(e),
});
})(e),
e.on("PreInit", () => {
((e) => {
e.formatter.register("namedAnchor", {
inline: "a",
selector: a,
remove: "all",
split: !0,
deep: !0,
attributes: { id: "%value" },
onmatch: (e, t, o) => l(e),
});
})(e);
});
});
})();

View File

@ -1,4 +1,174 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),n=t("autolink_pattern"),o=t("link_default_target"),r=t("link_default_protocol"),a=t("allow_unsafe_link_target"),s=("string",e=>"string"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(a=o.constructor)||void 0===a?void 0:a.name)===r.name)?"string":t;var n,o,r,a})(e));const l=(void 0,e=>undefined===e);const i=e=>!(e=>null==e)(e),c=Object.hasOwnProperty,d=e=>"\ufeff"===e;var u=tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");const f=e=>/^[(\[{ \u00a0]$/.test(e),g=(e,t,n)=>{for(let o=t-1;o>=0;o--){const t=e.charAt(o);if(!d(t)&&n(t))return o}return-1},m=(e,t)=>{var o;const a=e.schema.getVoidElements(),s=n(e),{dom:i,selection:d}=e;if(null!==i.getParent(d.getNode(),"a[href]"))return null;const m=d.getRng(),k=u(i,(e=>{return i.isBlock(e)||(t=a,n=e.nodeName.toLowerCase(),c.call(t,n))||"false"===i.getContentEditable(e);var t,n})),{container:p,offset:y}=((e,t)=>{let n=e,o=t;for(;1===n.nodeType&&n.childNodes[o];)n=n.childNodes[o],o=3===n.nodeType?n.data.length:n.childNodes.length;return{container:n,offset:o}})(m.endContainer,m.endOffset),w=null!==(o=i.getParent(p,i.isBlock))&&void 0!==o?o:i.getRoot(),h=k.backwards(p,y+t,((e,t)=>{const n=e.data,o=g(n,t,(r=f,e=>!r(e)));var r,a;return-1===o||(a=n[o],/[?!,.;:]/.test(a))?o:o+1}),w);if(!h)return null;let v=h.container;const _=k.backwards(h.container,h.offset,((e,t)=>{v=e;const n=g(e.data,t,f);return-1===n?n:n+1}),w),A=i.createRng();_?A.setStart(_.container,_.offset):A.setStart(v,0),A.setEnd(h.container,h.offset);const C=A.toString().replace(/\uFEFF/g,"").match(s);if(C){let t=C[0];return $="www.",(b=t).length>=4&&b.substr(0,4)===$?t=r(e)+"://"+t:((e,t,n=0,o)=>{const r=e.indexOf(t,n);return-1!==r&&(!!l(o)||r+t.length<=o)})(t,"@")&&!(e=>/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t)&&(t="mailto:"+t),{rng:A,url:t}}var b,$;return null},k=(e,t)=>{const{dom:n,selection:r}=e,{rng:l,url:i}=t,c=r.getBookmark();r.setRng(l);const d="createlink",u={command:d,ui:!1,value:i};if(!e.dispatch("BeforeExecCommand",u).isDefaultPrevented()){e.getDoc().execCommand(d,!1,i),e.dispatch("ExecCommand",u);const t=o(e);if(s(t)){const o=r.getNode();n.setAttrib(o,"target",t),"_blank"!==t||a(e)||n.setAttrib(o,"rel","noopener")}}r.moveToBookmark(c),e.nodeChanged()},p=e=>{const t=m(e,-1);i(t)&&k(e,t)},y=p;e.add("autolink",(e=>{(e=>{const t=e.options.register;t("autolink_pattern",{processor:"regexp",default:new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i")}),t("link_default_target",{processor:"string"}),t("link_default_protocol",{processor:"string",default:"https"})})(e),(e=>{e.on("keydown",(t=>{13!==t.keyCode||t.isDefaultPrevented()||(e=>{const t=m(e,0);i(t)&&k(e,t)})(e)})),e.on("keyup",(t=>{32===t.keyCode?p(e):(48===t.keyCode&&t.shiftKey||221===t.keyCode)&&y(e)}))})(e)}))}();
!(function () {
"use strict";
var e = tinymce.util.Tools.resolve("tinymce.PluginManager");
const t = (e) => (t) => t.options.get(e),
n = t("autolink_pattern"),
o = t("link_default_target"),
r = t("link_default_protocol"),
a = t("allow_unsafe_link_target"),
s =
("string",
(e) =>
"string" ===
((e) => {
const t = typeof e;
return null === e
? "null"
: "object" === t && Array.isArray(e)
? "array"
: "object" === t &&
((n = o = e),
(r = String).prototype.isPrototypeOf(n) ||
(null === (a = o.constructor) || void 0 === a
? void 0
: a.name) === r.name)
? "string"
: t;
var n, o, r, a;
})(e));
const l = (void 0, (e) => undefined === e);
const i = (e) => !((e) => null == e)(e),
c = Object.hasOwnProperty,
d = (e) => "\ufeff" === e;
var u = tinymce.util.Tools.resolve("tinymce.dom.TextSeeker");
const f = (e) => /^[(\[{ \u00a0]$/.test(e),
g = (e, t, n) => {
for (let o = t - 1; o >= 0; o--) {
const t = e.charAt(o);
if (!d(t) && n(t)) return o;
}
return -1;
},
m = (e, t) => {
var o;
const a = e.schema.getVoidElements(),
s = n(e),
{ dom: i, selection: d } = e;
if (null !== i.getParent(d.getNode(), "a[href]")) return null;
const m = d.getRng(),
k = u(i, (e) => {
return (
i.isBlock(e) ||
((t = a), (n = e.nodeName.toLowerCase()), c.call(t, n)) ||
"false" === i.getContentEditable(e)
);
var t, n;
}),
{ container: p, offset: y } = ((e, t) => {
let n = e,
o = t;
for (; 1 === n.nodeType && n.childNodes[o]; )
(n = n.childNodes[o]),
(o = 3 === n.nodeType ? n.data.length : n.childNodes.length);
return { container: n, offset: o };
})(m.endContainer, m.endOffset),
w =
null !== (o = i.getParent(p, i.isBlock)) && void 0 !== o
? o
: i.getRoot(),
h = k.backwards(
p,
y + t,
(e, t) => {
const n = e.data,
o = g(n, t, ((r = f), (e) => !r(e)));
var r, a;
return -1 === o || ((a = n[o]), /[?!,.;:]/.test(a)) ? o : o + 1;
},
w,
);
if (!h) return null;
let v = h.container;
const _ = k.backwards(
h.container,
h.offset,
(e, t) => {
v = e;
const n = g(e.data, t, f);
return -1 === n ? n : n + 1;
},
w,
),
A = i.createRng();
_ ? A.setStart(_.container, _.offset) : A.setStart(v, 0),
A.setEnd(h.container, h.offset);
const C = A.toString()
.replace(/\uFEFF/g, "")
.match(s);
if (C) {
let t = C[0];
return (
($ = "www."),
(b = t).length >= 4 && b.substr(0, 4) === $
? (t = r(e) + "://" + t)
: ((e, t, n = 0, o) => {
const r = e.indexOf(t, n);
return -1 !== r && (!!l(o) || r + t.length <= o);
})(t, "@") &&
!((e) => /^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(e))(t) &&
(t = "mailto:" + t),
{ rng: A, url: t }
);
}
var b, $;
return null;
},
k = (e, t) => {
const { dom: n, selection: r } = e,
{ rng: l, url: i } = t,
c = r.getBookmark();
r.setRng(l);
const d = "createlink",
u = { command: d, ui: !1, value: i };
if (!e.dispatch("BeforeExecCommand", u).isDefaultPrevented()) {
e.getDoc().execCommand(d, !1, i), e.dispatch("ExecCommand", u);
const t = o(e);
if (s(t)) {
const o = r.getNode();
n.setAttrib(o, "target", t),
"_blank" !== t || a(e) || n.setAttrib(o, "rel", "noopener");
}
}
r.moveToBookmark(c), e.nodeChanged();
},
p = (e) => {
const t = m(e, -1);
i(t) && k(e, t);
},
y = p;
e.add("autolink", (e) => {
((e) => {
const t = e.options.register;
t("autolink_pattern", {
processor: "regexp",
default: new RegExp(
"^" +
/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g
.source +
"$",
"i",
),
}),
t("link_default_target", { processor: "string" }),
t("link_default_protocol", { processor: "string", default: "https" });
})(e),
((e) => {
e.on("keydown", (t) => {
13 !== t.keyCode ||
t.isDefaultPrevented() ||
((e) => {
const t = m(e, 0);
i(t) && k(e, t);
})(e);
}),
e.on("keyup", (t) => {
32 === t.keyCode
? p(e)
: ((48 === t.keyCode && t.shiftKey) || 221 === t.keyCode) && y(e);
});
})(e);
});
})();

View File

@ -1,4 +1,138 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env");const o=e=>t=>t.options.get(e),s=o("min_height"),i=o("max_height"),n=o("autoresize_overflow_padding"),r=o("autoresize_bottom_margin"),l=(e,t)=>{const o=e.getBody();o&&(o.style.overflowY=t?"":"hidden",t||(o.scrollTop=0))},g=(e,t,o,s)=>{var i;const n=parseInt(null!==(i=e.getStyle(t,o,s))&&void 0!==i?i:"",10);return isNaN(n)?0:n},a=(e,o,r,c)=>{var d;const f=e.dom,u=e.getDoc();if(!u)return;if((e=>e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen())(e))return void l(e,!0);const m=u.documentElement,h=c?c():n(e),p=null!==(d=s(e))&&void 0!==d?d:e.getElement().offsetHeight;let y=p;const S=g(f,m,"margin-top",!0),v=g(f,m,"margin-bottom",!0);let C=m.offsetHeight+S+v+h;C<0&&(C=0);const b=e.getContainer().offsetHeight-e.getContentAreaContainer().offsetHeight;C+b>p&&(y=C+b);const w=i(e);if(w&&y>w?(y=w,l(e,!0)):l(e,!1),y!==o.get()){const s=y-o.get();if(f.setStyle(e.getContainer(),"height",y+"px"),o.set(y),(e=>{e.dispatch("ResizeEditor")})(e),t.browser.isSafari()&&(t.os.isMacOS()||t.os.isiOS())){const t=e.getWin();t.scrollTo(t.pageXOffset,t.pageYOffset)}e.hasFocus()&&(e=>{if("setcontent"===(null==e?void 0:e.type.toLowerCase())){const t=e;return!0===t.selection||!0===t.paste}return!1})(r)&&e.selection.scrollIntoView(),(t.browser.isSafari()||t.browser.isChromium())&&s<0&&a(e,o,r,c)}};e.add("autoresize",(e=>{if((e=>{const t=e.options.register;t("autoresize_overflow_padding",{processor:"number",default:1}),t("autoresize_bottom_margin",{processor:"number",default:50})})(e),e.options.isSet("resize")||e.options.set("resize",!1),!e.inline){const o=(e=>{let t=0;return{get:()=>t,set:e=>{t=e}}})();((e,t)=>{e.addCommand("mceAutoResize",(()=>{a(e,t)}))})(e,o),((e,o)=>{let s,i,l=()=>r(e);e.on("init",(i=>{s=0;const r=n(e),g=e.dom;g.setStyles(e.getDoc().documentElement,{height:"auto"}),t.browser.isEdge()||t.browser.isIE()?g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r,"min-height":0}):g.setStyles(e.getBody(),{paddingLeft:r,paddingRight:r}),a(e,o,i,l),s+=1})),e.on("NodeChange SetContent keyup FullscreenStateChanged ResizeContent",(t=>{if(1===s)i=e.getContainer().offsetHeight,a(e,o,t,l),s+=1;else if(2===s){const t=i<e.getContainer().offsetHeight;if(t){const t=e.dom,o=e.getDoc();t.setStyles(o.documentElement,{"min-height":0}),t.setStyles(e.getBody(),{"min-height":"inherit"})}l=t?(0,()=>0):l,s+=1}else a(e,o,t,l)}))})(e,o)}}))}();
!(function () {
"use strict";
var e = tinymce.util.Tools.resolve("tinymce.PluginManager"),
t = tinymce.util.Tools.resolve("tinymce.Env");
const o = (e) => (t) => t.options.get(e),
s = o("min_height"),
i = o("max_height"),
n = o("autoresize_overflow_padding"),
r = o("autoresize_bottom_margin"),
l = (e, t) => {
const o = e.getBody();
o && ((o.style.overflowY = t ? "" : "hidden"), t || (o.scrollTop = 0));
},
g = (e, t, o, s) => {
var i;
const n = parseInt(
null !== (i = e.getStyle(t, o, s)) && void 0 !== i ? i : "",
10,
);
return isNaN(n) ? 0 : n;
},
a = (e, o, r, c) => {
var d;
const f = e.dom,
u = e.getDoc();
if (!u) return;
if (
((e) => e.plugins.fullscreen && e.plugins.fullscreen.isFullscreen())(e)
)
return void l(e, !0);
const m = u.documentElement,
h = c ? c() : n(e),
p =
null !== (d = s(e)) && void 0 !== d ? d : e.getElement().offsetHeight;
let y = p;
const S = g(f, m, "margin-top", !0),
v = g(f, m, "margin-bottom", !0);
let C = m.offsetHeight + S + v + h;
C < 0 && (C = 0);
const b =
e.getContainer().offsetHeight -
e.getContentAreaContainer().offsetHeight;
C + b > p && (y = C + b);
const w = i(e);
if ((w && y > w ? ((y = w), l(e, !0)) : l(e, !1), y !== o.get())) {
const s = y - o.get();
if (
(f.setStyle(e.getContainer(), "height", y + "px"),
o.set(y),
((e) => {
e.dispatch("ResizeEditor");
})(e),
t.browser.isSafari() && (t.os.isMacOS() || t.os.isiOS()))
) {
const t = e.getWin();
t.scrollTo(t.pageXOffset, t.pageYOffset);
}
e.hasFocus() &&
((e) => {
if ("setcontent" === (null == e ? void 0 : e.type.toLowerCase())) {
const t = e;
return !0 === t.selection || !0 === t.paste;
}
return !1;
})(r) &&
e.selection.scrollIntoView(),
(t.browser.isSafari() || t.browser.isChromium()) &&
s < 0 &&
a(e, o, r, c);
}
};
e.add("autoresize", (e) => {
if (
(((e) => {
const t = e.options.register;
t("autoresize_overflow_padding", { processor: "number", default: 1 }),
t("autoresize_bottom_margin", { processor: "number", default: 50 });
})(e),
e.options.isSet("resize") || e.options.set("resize", !1),
!e.inline)
) {
const o = ((e) => {
let t = 0;
return {
get: () => t,
set: (e) => {
t = e;
},
};
})();
((e, t) => {
e.addCommand("mceAutoResize", () => {
a(e, t);
});
})(e, o),
((e, o) => {
let s,
i,
l = () => r(e);
e.on("init", (i) => {
s = 0;
const r = n(e),
g = e.dom;
g.setStyles(e.getDoc().documentElement, { height: "auto" }),
t.browser.isEdge() || t.browser.isIE()
? g.setStyles(e.getBody(), {
paddingLeft: r,
paddingRight: r,
"min-height": 0,
})
: g.setStyles(e.getBody(), { paddingLeft: r, paddingRight: r }),
a(e, o, i, l),
(s += 1);
}),
e.on(
"NodeChange SetContent keyup FullscreenStateChanged ResizeContent",
(t) => {
if (1 === s)
(i = e.getContainer().offsetHeight), a(e, o, t, l), (s += 1);
else if (2 === s) {
const t = i < e.getContainer().offsetHeight;
if (t) {
const t = e.dom,
o = e.getDoc();
t.setStyles(o.documentElement, { "min-height": 0 }),
t.setStyles(e.getBody(), { "min-height": "inherit" });
}
(l = t ? (0, () => 0) : l), (s += 1);
} else a(e, o, t, l);
},
);
})(e, o);
}
});
})();

View File

@ -1,4 +1,191 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=("string",t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(r=o=t,(a=String).prototype.isPrototypeOf(r)||(null===(s=o.constructor)||void 0===s?void 0:s.name)===a.name)?"string":e;var r,o,a,s})(t));const r=(void 0,t=>undefined===t);var o=tinymce.util.Tools.resolve("tinymce.util.Delay"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),s=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=t=>{const e=/^(\d+)([ms]?)$/.exec(t);return(e&&e[2]?{s:1e3,m:6e4}[e[2]]:1)*parseInt(t,10)},i=t=>e=>e.options.get(t),u=i("autosave_ask_before_unload"),l=i("autosave_restore_when_empty"),c=i("autosave_interval"),d=i("autosave_retention"),m=t=>{const e=document.location;return t.options.get("autosave_prefix").replace(/{path}/g,e.pathname).replace(/{query}/g,e.search).replace(/{hash}/g,e.hash).replace(/{id}/g,t.id)},v=(t,e)=>{if(r(e))return t.dom.isEmpty(t.getBody());{const r=s.trim(e);if(""===r)return!0;{const e=(new DOMParser).parseFromString(r,"text/html");return t.dom.isEmpty(e)}}},f=t=>{var e;const r=parseInt(null!==(e=a.getItem(m(t)+"time"))&&void 0!==e?e:"0",10)||0;return!((new Date).getTime()-r>d(t)&&(p(t,!1),1))},p=(t,e)=>{const r=m(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&(t=>{t.dispatch("RemoveDraft")})(t)},g=t=>{const e=m(t);!v(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),(t=>{t.dispatch("StoreDraft")})(t))},y=t=>{var e;const r=m(t);f(t)&&(t.setContent(null!==(e=a.getItem(r+"draft"))&&void 0!==e?e:"",{format:"raw"}),(t=>{t.dispatch("RestoreDraft")})(t))};var D=tinymce.util.Tools.resolve("tinymce.EditorManager");const h=t=>e=>{e.setEnabled(f(t));const r=()=>e.setEnabled(f(t));return t.on("StoreDraft RestoreDraft RemoveDraft",r),()=>t.off("StoreDraft RestoreDraft RemoveDraft",r)};t.add("autosave",(t=>((t=>{const r=t.options.register,o=t=>{const r=e(t);return r?{value:n(t),valid:r}:{valid:!1,message:"Must be a string."}};r("autosave_ask_before_unload",{processor:"boolean",default:!0}),r("autosave_prefix",{processor:"string",default:"tinymce-autosave-{path}{query}{hash}-{id}-"}),r("autosave_restore_when_empty",{processor:"boolean",default:!1}),r("autosave_interval",{processor:o,default:"30s"}),r("autosave_retention",{processor:o,default:"20m"})})(t),(t=>{t.editorManager.on("BeforeUnload",(t=>{let e;s.each(D.get(),(t=>{t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))})),e&&(t.preventDefault(),t.returnValue=e)}))})(t),(t=>{(t=>{const e=c(t);o.setEditorInterval(t,(()=>{g(t)}),e)})(t);const e=()=>{(t=>{t.undoManager.transact((()=>{y(t),p(t)})),t.focus()})(t)};t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:e,onSetup:h(t)})})(t),t.on("init",(()=>{l(t)&&t.dom.isEmpty(t.getBody())&&y(t)})),(t=>({hasDraft:()=>f(t),storeDraft:()=>g(t),restoreDraft:()=>y(t),removeDraft:e=>p(t,e),isEmpty:e=>v(t,e)}))(t))))}();
!(function () {
"use strict";
var t = tinymce.util.Tools.resolve("tinymce.PluginManager");
const e =
("string",
(t) =>
"string" ===
((t) => {
const e = typeof t;
return null === t
? "null"
: "object" === e && Array.isArray(t)
? "array"
: "object" === e &&
((r = o = t),
(a = String).prototype.isPrototypeOf(r) ||
(null === (s = o.constructor) || void 0 === s
? void 0
: s.name) === a.name)
? "string"
: e;
var r, o, a, s;
})(t));
const r = (void 0, (t) => undefined === t);
var o = tinymce.util.Tools.resolve("tinymce.util.Delay"),
a = tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),
s = tinymce.util.Tools.resolve("tinymce.util.Tools");
const n = (t) => {
const e = /^(\d+)([ms]?)$/.exec(t);
return (e && e[2] ? { s: 1e3, m: 6e4 }[e[2]] : 1) * parseInt(t, 10);
},
i = (t) => (e) => e.options.get(t),
u = i("autosave_ask_before_unload"),
l = i("autosave_restore_when_empty"),
c = i("autosave_interval"),
d = i("autosave_retention"),
m = (t) => {
const e = document.location;
return t.options
.get("autosave_prefix")
.replace(/{path}/g, e.pathname)
.replace(/{query}/g, e.search)
.replace(/{hash}/g, e.hash)
.replace(/{id}/g, t.id);
},
v = (t, e) => {
if (r(e)) return t.dom.isEmpty(t.getBody());
{
const r = s.trim(e);
if ("" === r) return !0;
{
const e = new DOMParser().parseFromString(r, "text/html");
return t.dom.isEmpty(e);
}
}
},
f = (t) => {
var e;
const r =
parseInt(
null !== (e = a.getItem(m(t) + "time")) && void 0 !== e ? e : "0",
10,
) || 0;
return !(new Date().getTime() - r > d(t) && (p(t, !1), 1));
},
p = (t, e) => {
const r = m(t);
a.removeItem(r + "draft"),
a.removeItem(r + "time"),
!1 !== e &&
((t) => {
t.dispatch("RemoveDraft");
})(t);
},
g = (t) => {
const e = m(t);
!v(t) &&
t.isDirty() &&
(a.setItem(e + "draft", t.getContent({ format: "raw", no_events: !0 })),
a.setItem(e + "time", new Date().getTime().toString()),
((t) => {
t.dispatch("StoreDraft");
})(t));
},
y = (t) => {
var e;
const r = m(t);
f(t) &&
(t.setContent(
null !== (e = a.getItem(r + "draft")) && void 0 !== e ? e : "",
{ format: "raw" },
),
((t) => {
t.dispatch("RestoreDraft");
})(t));
};
var D = tinymce.util.Tools.resolve("tinymce.EditorManager");
const h = (t) => (e) => {
e.setEnabled(f(t));
const r = () => e.setEnabled(f(t));
return (
t.on("StoreDraft RestoreDraft RemoveDraft", r),
() => t.off("StoreDraft RestoreDraft RemoveDraft", r)
);
};
t.add(
"autosave",
(t) => (
((t) => {
const r = t.options.register,
o = (t) => {
const r = e(t);
return r
? { value: n(t), valid: r }
: { valid: !1, message: "Must be a string." };
};
r("autosave_ask_before_unload", { processor: "boolean", default: !0 }),
r("autosave_prefix", {
processor: "string",
default: "tinymce-autosave-{path}{query}{hash}-{id}-",
}),
r("autosave_restore_when_empty", {
processor: "boolean",
default: !1,
}),
r("autosave_interval", { processor: o, default: "30s" }),
r("autosave_retention", { processor: o, default: "20m" });
})(t),
((t) => {
t.editorManager.on("BeforeUnload", (t) => {
let e;
s.each(D.get(), (t) => {
t.plugins.autosave && t.plugins.autosave.storeDraft(),
!e &&
t.isDirty() &&
u(t) &&
(e = t.translate(
"You have unsaved changes are you sure you want to navigate away?",
));
}),
e && (t.preventDefault(), (t.returnValue = e));
});
})(t),
((t) => {
((t) => {
const e = c(t);
o.setEditorInterval(
t,
() => {
g(t);
},
e,
);
})(t);
const e = () => {
((t) => {
t.undoManager.transact(() => {
y(t), p(t);
}),
t.focus();
})(t);
};
t.ui.registry.addButton("restoredraft", {
tooltip: "Restore last draft",
icon: "restore-draft",
onAction: e,
onSetup: h(t),
}),
t.ui.registry.addMenuItem("restoredraft", {
text: "Restore last draft",
icon: "restore-draft",
onAction: e,
onSetup: h(t),
});
})(t),
t.on("init", () => {
l(t) && t.dom.isEmpty(t.getBody()) && y(t);
}),
((t) => ({
hasDraft: () => f(t),
storeDraft: () => g(t),
restoreDraft: () => y(t),
removeDraft: (e) => p(t, e),
isEmpty: (e) => v(t, e),
}))(t)
),
);
})();

View File

@ -1,4 +1,56 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("code",(e=>((e=>{e.addCommand("mceCodeEditor",(()=>{(e=>{const o=(e=>e.getContent({source_view:!0}))(e);e.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:o},onSubmit:o=>{((e,o)=>{e.focus(),e.undoManager.transact((()=>{e.setContent(o)})),e.selection.setCursorLocation(),e.nodeChanged()})(e,o.getData().code),o.close()}})})(e)}))})(e),(e=>{const o=()=>e.execCommand("mceCodeEditor");e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:o}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:o})})(e),{})))}();
!(function () {
"use strict";
tinymce.util.Tools.resolve("tinymce.PluginManager").add(
"code",
(e) => (
((e) => {
e.addCommand("mceCodeEditor", () => {
((e) => {
const o = ((e) => e.getContent({ source_view: !0 }))(e);
e.windowManager.open({
title: "Source Code",
size: "large",
body: {
type: "panel",
items: [{ type: "textarea", name: "code" }],
},
buttons: [
{ type: "cancel", name: "cancel", text: "Cancel" },
{ type: "submit", name: "save", text: "Save", primary: !0 },
],
initialData: { code: o },
onSubmit: (o) => {
((e, o) => {
e.focus(),
e.undoManager.transact(() => {
e.setContent(o);
}),
e.selection.setCursorLocation(),
e.nodeChanged();
})(e, o.getData().code),
o.close();
},
});
})(e);
});
})(e),
((e) => {
const o = () => e.execCommand("mceCodeEditor");
e.ui.registry.addButton("code", {
icon: "sourcecode",
tooltip: "Source code",
onAction: o,
}),
e.ui.registry.addMenuItem("code", {
icon: "sourcecode",
text: "Source code",
onAction: o,
});
})(e),
{}
),
);
})();

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,285 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=t=>e=>typeof e===t,o=t=>"string"===(t=>{const e=typeof t;return null===t?"null":"object"===e&&Array.isArray(t)?"array":"object"===e&&(o=r=t,(n=String).prototype.isPrototypeOf(o)||(null===(i=r.constructor)||void 0===i?void 0:i.name)===n.name)?"string":e;var o,r,n,i})(t),r=e("boolean"),n=t=>!(t=>null==t)(t),i=e("function"),s=e("number"),l=(!1,()=>false);class a{constructor(t,e){this.tag=t,this.value=e}static some(t){return new a(!0,t)}static none(){return a.singletonNone}fold(t,e){return this.tag?e(this.value):t()}isSome(){return this.tag}isNone(){return!this.tag}map(t){return this.tag?a.some(t(this.value)):a.none()}bind(t){return this.tag?t(this.value):a.none()}exists(t){return this.tag&&t(this.value)}forall(t){return!this.tag||t(this.value)}filter(t){return!this.tag||t(this.value)?this:a.none()}getOr(t){return this.tag?this.value:t}or(t){return this.tag?this:t}getOrThunk(t){return this.tag?this.value:t()}orThunk(t){return this.tag?this:t()}getOrDie(t){if(this.tag)return this.value;throw new Error(null!=t?t:"Called getOrDie on None")}static from(t){return n(t)?a.some(t):a.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(t){this.tag&&t(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}a.singletonNone=new a(!1);const u=(t,e)=>{for(let o=0,r=t.length;o<r;o++)e(t[o],o)},c=t=>{if(null==t)throw new Error("Node cannot be null or undefined");return{dom:t}},d=c,h=(t,e)=>{const o=t.dom;if(1!==o.nodeType)return!1;{const t=o;if(void 0!==t.matches)return t.matches(e);if(void 0!==t.msMatchesSelector)return t.msMatchesSelector(e);if(void 0!==t.webkitMatchesSelector)return t.webkitMatchesSelector(e);if(void 0!==t.mozMatchesSelector)return t.mozMatchesSelector(e);throw new Error("Browser lacks native selectors")}};"undefined"!=typeof window?window:Function("return this;")();const m=t=>e=>(t=>t.dom.nodeType)(e)===t,g=m(1),f=m(3),v=m(9),y=m(11),p=(t,e)=>{t.dom.removeAttribute(e)},w=i(Element.prototype.attachShadow)&&i(Node.prototype.getRootNode)?t=>d(t.dom.getRootNode()):t=>v(t)?t:d(t.dom.ownerDocument),b=t=>d(t.dom.host),N=t=>{const e=f(t)?t.dom.parentNode:t.dom;if(null==e||null===e.ownerDocument)return!1;const o=e.ownerDocument;return(t=>{const e=w(t);return y(o=e)&&n(o.dom.host)?a.some(e):a.none();var o})(d(e)).fold((()=>o.body.contains(e)),(r=N,i=b,t=>r(i(t))));var r,i},S=t=>"rtl"===((t,e)=>{const o=t.dom,r=window.getComputedStyle(o).getPropertyValue(e);return""!==r||N(t)?r:((t,e)=>(t=>void 0!==t.style&&i(t.style.getPropertyValue))(t)?t.style.getPropertyValue(e):"")(o,e)})(t,"direction")?"rtl":"ltr",A=(t,e)=>((t,o)=>((t,e)=>{const o=[];for(let r=0,n=t.length;r<n;r++){const n=t[r];e(n,r)&&o.push(n)}return o})(((t,e)=>{const o=t.length,r=new Array(o);for(let n=0;n<o;n++){const o=t[n];r[n]=e(o,n)}return r})(t.dom.childNodes,d),(t=>h(t,e))))(t),E=("li",t=>g(t)&&"li"===t.dom.nodeName.toLowerCase());const T=(t,e,n)=>{u(e,(e=>{const c=d(e),m=E(c),f=((t,e)=>{return(e?(o=t,r="ol,ul",((t,e,o)=>{let n=t.dom;const s=i(o)?o:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,r))return a.some(t);if(s(t))break}return a.none()})(o,0,n)):a.some(t)).getOr(t);var o,r,n})(c,m);var v;(v=f,(t=>a.from(t.dom.parentNode).map(d))(v).filter(g)).each((e=>{if(t.setStyle(f.dom,"direction",null),S(e)===n?p(f,"dir"):((t,e,n)=>{((t,e,n)=>{if(!(o(n)||r(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(f,"dir",n),S(f)!==n&&t.setStyle(f.dom,"direction",n),m){const e=A(f,"li[dir],li[style]");u(e,(e=>{p(e,"dir"),t.setStyle(e.dom,"direction",null)}))}}))}))},C=(t,e)=>{t.selection.isEditable()&&(T(t.dom,t.selection.getSelectedBlocks(),e),t.nodeChanged())},D=(t,e)=>o=>{const r=r=>{const n=d(r.element);o.setActive(S(n)===e),o.setEnabled(t.selection.isEditable())};return t.on("NodeChange",r),o.setEnabled(t.selection.isEditable()),()=>t.off("NodeChange",r)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{C(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{C(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:D(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:D(t,"rtl")})})(t)}))}();
!(function () {
"use strict";
var t = tinymce.util.Tools.resolve("tinymce.PluginManager");
const e = (t) => (e) => typeof e === t,
o = (t) =>
"string" ===
((t) => {
const e = typeof t;
return null === t
? "null"
: "object" === e && Array.isArray(t)
? "array"
: "object" === e &&
((o = r = t),
(n = String).prototype.isPrototypeOf(o) ||
(null === (i = r.constructor) || void 0 === i
? void 0
: i.name) === n.name)
? "string"
: e;
var o, r, n, i;
})(t),
r = e("boolean"),
n = (t) => !((t) => null == t)(t),
i = e("function"),
s = e("number"),
l = (!1, () => false);
class a {
constructor(t, e) {
(this.tag = t), (this.value = e);
}
static some(t) {
return new a(!0, t);
}
static none() {
return a.singletonNone;
}
fold(t, e) {
return this.tag ? e(this.value) : t();
}
isSome() {
return this.tag;
}
isNone() {
return !this.tag;
}
map(t) {
return this.tag ? a.some(t(this.value)) : a.none();
}
bind(t) {
return this.tag ? t(this.value) : a.none();
}
exists(t) {
return this.tag && t(this.value);
}
forall(t) {
return !this.tag || t(this.value);
}
filter(t) {
return !this.tag || t(this.value) ? this : a.none();
}
getOr(t) {
return this.tag ? this.value : t;
}
or(t) {
return this.tag ? this : t;
}
getOrThunk(t) {
return this.tag ? this.value : t();
}
orThunk(t) {
return this.tag ? this : t();
}
getOrDie(t) {
if (this.tag) return this.value;
throw new Error(null != t ? t : "Called getOrDie on None");
}
static from(t) {
return n(t) ? a.some(t) : a.none();
}
getOrNull() {
return this.tag ? this.value : null;
}
getOrUndefined() {
return this.value;
}
each(t) {
this.tag && t(this.value);
}
toArray() {
return this.tag ? [this.value] : [];
}
toString() {
return this.tag ? `some(${this.value})` : "none()";
}
}
a.singletonNone = new a(!1);
const u = (t, e) => {
for (let o = 0, r = t.length; o < r; o++) e(t[o], o);
},
c = (t) => {
if (null == t) throw new Error("Node cannot be null or undefined");
return { dom: t };
},
d = c,
h = (t, e) => {
const o = t.dom;
if (1 !== o.nodeType) return !1;
{
const t = o;
if (void 0 !== t.matches) return t.matches(e);
if (void 0 !== t.msMatchesSelector) return t.msMatchesSelector(e);
if (void 0 !== t.webkitMatchesSelector)
return t.webkitMatchesSelector(e);
if (void 0 !== t.mozMatchesSelector) return t.mozMatchesSelector(e);
throw new Error("Browser lacks native selectors");
}
};
"undefined" != typeof window ? window : Function("return this;")();
const m = (t) => (e) => ((t) => t.dom.nodeType)(e) === t,
g = m(1),
f = m(3),
v = m(9),
y = m(11),
p = (t, e) => {
t.dom.removeAttribute(e);
},
w =
i(Element.prototype.attachShadow) && i(Node.prototype.getRootNode)
? (t) => d(t.dom.getRootNode())
: (t) => (v(t) ? t : d(t.dom.ownerDocument)),
b = (t) => d(t.dom.host),
N = (t) => {
const e = f(t) ? t.dom.parentNode : t.dom;
if (null == e || null === e.ownerDocument) return !1;
const o = e.ownerDocument;
return ((t) => {
const e = w(t);
return y((o = e)) && n(o.dom.host) ? a.some(e) : a.none();
var o;
})(d(e)).fold(
() => o.body.contains(e),
((r = N), (i = b), (t) => r(i(t))),
);
var r, i;
},
S = (t) =>
"rtl" ===
((t, e) => {
const o = t.dom,
r = window.getComputedStyle(o).getPropertyValue(e);
return "" !== r || N(t)
? r
: ((t, e) =>
((t) => void 0 !== t.style && i(t.style.getPropertyValue))(t)
? t.style.getPropertyValue(e)
: "")(o, e);
})(t, "direction")
? "rtl"
: "ltr",
A = (t, e) =>
((t, o) =>
((t, e) => {
const o = [];
for (let r = 0, n = t.length; r < n; r++) {
const n = t[r];
e(n, r) && o.push(n);
}
return o;
})(
((t, e) => {
const o = t.length,
r = new Array(o);
for (let n = 0; n < o; n++) {
const o = t[n];
r[n] = e(o, n);
}
return r;
})(t.dom.childNodes, d),
(t) => h(t, e),
))(t),
E = ("li", (t) => g(t) && "li" === t.dom.nodeName.toLowerCase());
const T = (t, e, n) => {
u(e, (e) => {
const c = d(e),
m = E(c),
f = ((t, e) => {
return (
e
? ((o = t),
(r = "ol,ul"),
((t, e, o) => {
let n = t.dom;
const s = i(o) ? o : l;
for (; n.parentNode; ) {
n = n.parentNode;
const t = d(n);
if (h(t, r)) return a.some(t);
if (s(t)) break;
}
return a.none();
})(o, 0, n))
: a.some(t)
).getOr(t);
var o, r, n;
})(c, m);
var v;
((v = f), ((t) => a.from(t.dom.parentNode).map(d))(v).filter(g)).each(
(e) => {
if (
(t.setStyle(f.dom, "direction", null),
S(e) === n
? p(f, "dir")
: ((t, e, n) => {
((t, e, n) => {
if (!(o(n) || r(n) || s(n)))
throw (
(console.error(
"Invalid call to Attribute.set. Key ",
e,
":: Value ",
n,
":: Element ",
t,
),
new Error("Attribute value was not simple"))
);
t.setAttribute(e, n + "");
})(t.dom, e, n);
})(f, "dir", n),
S(f) !== n && t.setStyle(f.dom, "direction", n),
m)
) {
const e = A(f, "li[dir],li[style]");
u(e, (e) => {
p(e, "dir"), t.setStyle(e.dom, "direction", null);
});
}
},
);
});
},
C = (t, e) => {
t.selection.isEditable() &&
(T(t.dom, t.selection.getSelectedBlocks(), e), t.nodeChanged());
},
D = (t, e) => (o) => {
const r = (r) => {
const n = d(r.element);
o.setActive(S(n) === e), o.setEnabled(t.selection.isEditable());
};
return (
t.on("NodeChange", r),
o.setEnabled(t.selection.isEditable()),
() => t.off("NodeChange", r)
);
};
t.add("directionality", (t) => {
((t) => {
t.addCommand("mceDirectionLTR", () => {
C(t, "ltr");
}),
t.addCommand("mceDirectionRTL", () => {
C(t, "rtl");
});
})(t),
((t) => {
t.ui.registry.addToggleButton("ltr", {
tooltip: "Left to right",
icon: "ltr",
onAction: () => t.execCommand("mceDirectionLTR"),
onSetup: D(t, "ltr"),
}),
t.ui.registry.addToggleButton("rtl", {
tooltip: "Right to left",
icon: "rtl",
onAction: () => t.execCommand("mceDirectionRTL"),
onSetup: D(t, "rtl"),
});
})(t);
});
})();

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,4 +1,263 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(s=r=e,(o=String).prototype.isPrototypeOf(s)||(null===(n=r.constructor)||void 0===n?void 0:n.name)===o.name)?"string":t;var s,r,o,n})(t)===e,s=t("string"),r=t("object"),o=t("array"),n=("function",e=>"function"==typeof e);var c=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),i=tinymce.util.Tools.resolve("tinymce.EditorManager"),l=tinymce.util.Tools.resolve("tinymce.Env"),a=tinymce.util.Tools.resolve("tinymce.util.Tools");const p=e=>t=>t.options.get(e),u=p("importcss_merge_classes"),m=p("importcss_exclusive"),f=p("importcss_selector_converter"),y=p("importcss_selector_filter"),d=p("importcss_groups"),h=p("importcss_append"),_=p("importcss_file_filter"),g=p("skin"),v=p("skin_url"),b=Array.prototype.push,x=/^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/,T=e=>s(e)?t=>-1!==t.indexOf(e):e instanceof RegExp?t=>e.test(t):e,S=(e,t)=>{let s={};const r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(!r)return;const o=r[1],n=r[2].substr(1).split(".").join(" "),c=a.makeMap("a,img");return r[1]?(s={title:t},e.schema.getTextBlockElements()[o]?s.block=o:e.schema.getBlockElements()[o]||c[o.toLowerCase()]?s.selector=o:s.inline=o):r[2]&&(s={inline:"span",title:t.substr(1),classes:n}),u(e)?s.classes=n:s.attributes={class:n},s},k=(e,t)=>null===t||m(e),w=e=>{e.on("init",(()=>{const t=(()=>{const e=[],t=[],s={};return{addItemToGroup:(e,r)=>{s[e]?s[e].push(r):(t.push(e),s[e]=[r])},addItem:t=>{e.push(t)},toFormats:()=>{return(r=t,n=e=>{const t=s[e];return 0===t.length?[]:[{title:e,items:t}]},(e=>{const t=[];for(let s=0,r=e.length;s<r;++s){if(!o(e[s]))throw new Error("Arr.flatten item "+s+" was not an array, input: "+e);b.apply(t,e[s])}return t})(((e,t)=>{const s=e.length,r=new Array(s);for(let o=0;o<s;o++){const s=e[o];r[o]=t(s,o)}return r})(r,n))).concat(e);var r,n}}})(),r={},n=T(y(e)),p=(e=>a.map(e,(e=>a.extend({},e,{original:e,selectors:{},filter:T(e.filter)}))))(d(e)),u=(t,s)=>{if(((e,t,s,r)=>!(k(e,s)?t in r:t in s.selectors))(e,t,s,r)){((e,t,s,r)=>{k(e,s)?r[t]=!0:s.selectors[t]=!0})(e,t,s,r);const o=((e,t,s,r)=>{let o;const n=f(e);return o=r&&r.selector_converter?r.selector_converter:n||(()=>S(e,s)),o.call(t,s,r)})(e,e.plugins.importcss,t,s);if(o){const t=o.name||c.DOM.uniqueId();return e.formatter.register(t,o),{title:o.title,format:t}}}return null};a.each(((e,t,r)=>{const o=[],n={},c=(t,n)=>{let p,u=t.href;if(u=(e=>{const t=l.cacheSuffix;return s(e)&&(e=e.replace("?"+t,"").replace("&"+t,"")),e})(u),u&&(!r||r(u,n))&&!((e,t)=>{const s=g(e);if(s){const r=v(e),o=r?e.documentBaseURI.toAbsolute(r):i.baseURL+"/skins/ui/"+s,n=i.baseURL+"/skins/content/";return t===o+"/content"+(e.inline?".inline":"")+".min.css"||-1!==t.indexOf(n)}return!1})(e,u)){a.each(t.imports,(e=>{c(e,!0)}));try{p=t.cssRules||t.rules}catch(e){}a.each(p,(e=>{e.styleSheet?c(e.styleSheet,!0):e.selectorText&&a.each(e.selectorText.split(","),(e=>{o.push(a.trim(e))}))}))}};a.each(e.contentCSS,(e=>{n[e]=!0})),r||(r=(e,t)=>t||n[e]);try{a.each(t.styleSheets,(e=>{c(e)}))}catch(e){}return o})(e,e.getDoc(),T(_(e))),(e=>{if(!x.test(e)&&(!n||n(e))){const s=((e,t)=>a.grep(e,(e=>!e.filter||e.filter(t))))(p,e);if(s.length>0)a.each(s,(s=>{const r=u(e,s);r&&t.addItemToGroup(s.title,r)}));else{const s=u(e,null);s&&t.addItem(s)}}}));const m=t.toFormats();e.dispatch("addStyleModifications",{items:m,replace:!h(e)})}))};e.add("importcss",(e=>((e=>{const t=e.options.register,o=e=>s(e)||n(e)||r(e);t("importcss_merge_classes",{processor:"boolean",default:!0}),t("importcss_exclusive",{processor:"boolean",default:!0}),t("importcss_selector_converter",{processor:"function"}),t("importcss_selector_filter",{processor:o}),t("importcss_file_filter",{processor:o}),t("importcss_groups",{processor:"object[]"}),t("importcss_append",{processor:"boolean",default:!1})})(e),w(e),(e=>({convertSelectorToFormat:t=>S(e,t)}))(e))))}();
!(function () {
"use strict";
var e = tinymce.util.Tools.resolve("tinymce.PluginManager");
const t = (e) => (t) =>
((e) => {
const t = typeof e;
return null === e
? "null"
: "object" === t && Array.isArray(e)
? "array"
: "object" === t &&
((s = r = e),
(o = String).prototype.isPrototypeOf(s) ||
(null === (n = r.constructor) || void 0 === n
? void 0
: n.name) === o.name)
? "string"
: t;
var s, r, o, n;
})(t) === e,
s = t("string"),
r = t("object"),
o = t("array"),
n = ("function", (e) => "function" == typeof e);
var c = tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),
i = tinymce.util.Tools.resolve("tinymce.EditorManager"),
l = tinymce.util.Tools.resolve("tinymce.Env"),
a = tinymce.util.Tools.resolve("tinymce.util.Tools");
const p = (e) => (t) => t.options.get(e),
u = p("importcss_merge_classes"),
m = p("importcss_exclusive"),
f = p("importcss_selector_converter"),
y = p("importcss_selector_filter"),
d = p("importcss_groups"),
h = p("importcss_append"),
_ = p("importcss_file_filter"),
g = p("skin"),
v = p("skin_url"),
b = Array.prototype.push,
x = /^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/,
T = (e) =>
s(e)
? (t) => -1 !== t.indexOf(e)
: e instanceof RegExp
? (t) => e.test(t)
: e,
S = (e, t) => {
let s = {};
const r = /^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);
if (!r) return;
const o = r[1],
n = r[2].substr(1).split(".").join(" "),
c = a.makeMap("a,img");
return (
r[1]
? ((s = { title: t }),
e.schema.getTextBlockElements()[o]
? (s.block = o)
: e.schema.getBlockElements()[o] || c[o.toLowerCase()]
? (s.selector = o)
: (s.inline = o))
: r[2] && (s = { inline: "span", title: t.substr(1), classes: n }),
u(e) ? (s.classes = n) : (s.attributes = { class: n }),
s
);
},
k = (e, t) => null === t || m(e),
w = (e) => {
e.on("init", () => {
const t = (() => {
const e = [],
t = [],
s = {};
return {
addItemToGroup: (e, r) => {
s[e] ? s[e].push(r) : (t.push(e), (s[e] = [r]));
},
addItem: (t) => {
e.push(t);
},
toFormats: () => {
return ((r = t),
(n = (e) => {
const t = s[e];
return 0 === t.length ? [] : [{ title: e, items: t }];
}),
((e) => {
const t = [];
for (let s = 0, r = e.length; s < r; ++s) {
if (!o(e[s]))
throw new Error(
"Arr.flatten item " +
s +
" was not an array, input: " +
e,
);
b.apply(t, e[s]);
}
return t;
})(
((e, t) => {
const s = e.length,
r = new Array(s);
for (let o = 0; o < s; o++) {
const s = e[o];
r[o] = t(s, o);
}
return r;
})(r, n),
)).concat(e);
var r, n;
},
};
})(),
r = {},
n = T(y(e)),
p = ((e) =>
a.map(e, (e) =>
a.extend({}, e, {
original: e,
selectors: {},
filter: T(e.filter),
}),
))(d(e)),
u = (t, s) => {
if (
((e, t, s, r) => !(k(e, s) ? t in r : t in s.selectors))(
e,
t,
s,
r,
)
) {
((e, t, s, r) => {
k(e, s) ? (r[t] = !0) : (s.selectors[t] = !0);
})(e, t, s, r);
const o = ((e, t, s, r) => {
let o;
const n = f(e);
return (
(o =
r && r.selector_converter
? r.selector_converter
: n || (() => S(e, s))),
o.call(t, s, r)
);
})(e, e.plugins.importcss, t, s);
if (o) {
const t = o.name || c.DOM.uniqueId();
return (
e.formatter.register(t, o), { title: o.title, format: t }
);
}
}
return null;
};
a.each(
((e, t, r) => {
const o = [],
n = {},
c = (t, n) => {
let p,
u = t.href;
if (
((u = ((e) => {
const t = l.cacheSuffix;
return (
s(e) && (e = e.replace("?" + t, "").replace("&" + t, "")),
e
);
})(u)),
u &&
(!r || r(u, n)) &&
!((e, t) => {
const s = g(e);
if (s) {
const r = v(e),
o = r
? e.documentBaseURI.toAbsolute(r)
: i.baseURL + "/skins/ui/" + s,
n = i.baseURL + "/skins/content/";
return (
t ===
o +
"/content" +
(e.inline ? ".inline" : "") +
".min.css" || -1 !== t.indexOf(n)
);
}
return !1;
})(e, u))
) {
a.each(t.imports, (e) => {
c(e, !0);
});
try {
p = t.cssRules || t.rules;
} catch (e) {}
a.each(p, (e) => {
e.styleSheet
? c(e.styleSheet, !0)
: e.selectorText &&
a.each(e.selectorText.split(","), (e) => {
o.push(a.trim(e));
});
});
}
};
a.each(e.contentCSS, (e) => {
n[e] = !0;
}),
r || (r = (e, t) => t || n[e]);
try {
a.each(t.styleSheets, (e) => {
c(e);
});
} catch (e) {}
return o;
})(e, e.getDoc(), T(_(e))),
(e) => {
if (!x.test(e) && (!n || n(e))) {
const s = ((e, t) => a.grep(e, (e) => !e.filter || e.filter(t)))(
p,
e,
);
if (s.length > 0)
a.each(s, (s) => {
const r = u(e, s);
r && t.addItemToGroup(s.title, r);
});
else {
const s = u(e, null);
s && t.addItem(s);
}
}
},
);
const m = t.toFormats();
e.dispatch("addStyleModifications", { items: m, replace: !h(e) });
});
};
e.add(
"importcss",
(e) => (
((e) => {
const t = e.options.register,
o = (e) => s(e) || n(e) || r(e);
t("importcss_merge_classes", { processor: "boolean", default: !0 }),
t("importcss_exclusive", { processor: "boolean", default: !0 }),
t("importcss_selector_converter", { processor: "function" }),
t("importcss_selector_filter", { processor: o }),
t("importcss_file_filter", { processor: o }),
t("importcss_groups", { processor: "object[]" }),
t("importcss_append", { processor: "boolean", default: !1 });
})(e),
w(e),
((e) => ({ convertSelectorToFormat: (t) => S(e, t) }))(e)
),
);
})();

View File

@ -1,4 +1,158 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),a=t("insertdatetime_dateformat"),n=t("insertdatetime_timeformat"),r=t("insertdatetime_formats"),s=t("insertdatetime_element"),i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),o="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),l="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),c=(e,t)=>{if((e=""+e).length<t)for(let a=0;a<t-e.length;a++)e="0"+e;return e},d=(e,t,a=new Date)=>(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+a.getFullYear())).replace("%y",""+a.getYear())).replace("%m",c(a.getMonth()+1,2))).replace("%d",c(a.getDate(),2))).replace("%H",""+c(a.getHours(),2))).replace("%M",""+c(a.getMinutes(),2))).replace("%S",""+c(a.getSeconds(),2))).replace("%I",""+((a.getHours()+11)%12+1))).replace("%p",a.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(m[a.getMonth()]))).replace("%b",""+e.translate(l[a.getMonth()]))).replace("%A",""+e.translate(o[a.getDay()]))).replace("%a",""+e.translate(i[a.getDay()]))).replace("%%","%"),u=(e,t)=>{if(s(e)){const a=d(e,t);let n;n=/%[HMSIp]/.test(t)?d(e,"%Y-%m-%dT%H:%M"):d(e,"%Y-%m-%d");const r=e.dom.getParent(e.selection.getStart(),"time");r?((e,t,a,n)=>{const r=e.dom.create("time",{datetime:a},n);e.dom.replace(r,t),e.selection.select(r,!0),e.selection.collapse(!1)})(e,r,n,a):e.insertContent('<time datetime="'+n+'">'+a+"</time>")}else e.insertContent(d(e,t))};var p=tinymce.util.Tools.resolve("tinymce.util.Tools");const g=e=>t=>{const a=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",a),a(),()=>{e.off("NodeChange",a)}};e.add("insertdatetime",(e=>{(e=>{const t=e.options.register;t("insertdatetime_dateformat",{processor:"string",default:e.translate("%Y-%m-%d")}),t("insertdatetime_timeformat",{processor:"string",default:e.translate("%H:%M:%S")}),t("insertdatetime_formats",{processor:"string[]",default:["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"]}),t("insertdatetime_element",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mceInsertDate",((t,n)=>{u(e,null!=n?n:a(e))})),e.addCommand("mceInsertTime",((t,a)=>{u(e,null!=a?a:n(e))}))})(e),(e=>{const t=r(e),a=(e=>{let t=e;return{get:()=>t,set:e=>{t=e}}})((e=>{const t=r(e);return t.length>0?t[0]:n(e)})(e)),s=t=>e.execCommand("mceInsertDate",!1,t);e.ui.registry.addSplitButton("insertdatetime",{icon:"insert-time",tooltip:"Insert date/time",select:e=>e===a.get(),fetch:a=>{a(p.map(t,(t=>({type:"choiceitem",text:d(e,t),value:t}))))},onAction:e=>{s(a.get())},onItemAction:(e,t)=>{a.set(t),s(t)},onSetup:g(e)});const i=e=>()=>{a.set(e),s(e)};e.ui.registry.addNestedMenuItem("insertdatetime",{icon:"insert-time",text:"Date/time",getSubmenuItems:()=>p.map(t,(t=>({type:"menuitem",text:d(e,t),onAction:i(t)}))),onSetup:g(e)})})(e)}))}();
!(function () {
"use strict";
var e = tinymce.util.Tools.resolve("tinymce.PluginManager");
const t = (e) => (t) => t.options.get(e),
a = t("insertdatetime_dateformat"),
n = t("insertdatetime_timeformat"),
r = t("insertdatetime_formats"),
s = t("insertdatetime_element"),
i = "Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),
o = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(
" ",
),
l = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),
m =
"January February March April May June July August September October November December".split(
" ",
),
c = (e, t) => {
if ((e = "" + e).length < t)
for (let a = 0; a < t - e.length; a++) e = "0" + e;
return e;
},
d = (e, t, a = new Date()) =>
(t = (t = (t = (t = (t = (t = (t = (t = (t = (t = (t = (t = (t = (t = (t =
t.replace("%D", "%m/%d/%Y")).replace("%r", "%I:%M:%S %p")).replace(
"%Y",
"" + a.getFullYear(),
)).replace("%y", "" + a.getYear())).replace(
"%m",
c(a.getMonth() + 1, 2),
)).replace("%d", c(a.getDate(), 2))).replace(
"%H",
"" + c(a.getHours(), 2),
)).replace("%M", "" + c(a.getMinutes(), 2))).replace(
"%S",
"" + c(a.getSeconds(), 2),
)).replace("%I", "" + (((a.getHours() + 11) % 12) + 1))).replace(
"%p",
a.getHours() < 12 ? "AM" : "PM",
)).replace("%B", "" + e.translate(m[a.getMonth()]))).replace(
"%b",
"" + e.translate(l[a.getMonth()]),
)).replace("%A", "" + e.translate(o[a.getDay()]))).replace(
"%a",
"" + e.translate(i[a.getDay()]),
)).replace("%%", "%"),
u = (e, t) => {
if (s(e)) {
const a = d(e, t);
let n;
n = /%[HMSIp]/.test(t) ? d(e, "%Y-%m-%dT%H:%M") : d(e, "%Y-%m-%d");
const r = e.dom.getParent(e.selection.getStart(), "time");
r
? ((e, t, a, n) => {
const r = e.dom.create("time", { datetime: a }, n);
e.dom.replace(r, t),
e.selection.select(r, !0),
e.selection.collapse(!1);
})(e, r, n, a)
: e.insertContent('<time datetime="' + n + '">' + a + "</time>");
} else e.insertContent(d(e, t));
};
var p = tinymce.util.Tools.resolve("tinymce.util.Tools");
const g = (e) => (t) => {
const a = () => {
t.setEnabled(e.selection.isEditable());
};
return (
e.on("NodeChange", a),
a(),
() => {
e.off("NodeChange", a);
}
);
};
e.add("insertdatetime", (e) => {
((e) => {
const t = e.options.register;
t("insertdatetime_dateformat", {
processor: "string",
default: e.translate("%Y-%m-%d"),
}),
t("insertdatetime_timeformat", {
processor: "string",
default: e.translate("%H:%M:%S"),
}),
t("insertdatetime_formats", {
processor: "string[]",
default: ["%H:%M:%S", "%Y-%m-%d", "%I:%M:%S %p", "%D"],
}),
t("insertdatetime_element", { processor: "boolean", default: !1 });
})(e),
((e) => {
e.addCommand("mceInsertDate", (t, n) => {
u(e, null != n ? n : a(e));
}),
e.addCommand("mceInsertTime", (t, a) => {
u(e, null != a ? a : n(e));
});
})(e),
((e) => {
const t = r(e),
a = ((e) => {
let t = e;
return {
get: () => t,
set: (e) => {
t = e;
},
};
})(
((e) => {
const t = r(e);
return t.length > 0 ? t[0] : n(e);
})(e),
),
s = (t) => e.execCommand("mceInsertDate", !1, t);
e.ui.registry.addSplitButton("insertdatetime", {
icon: "insert-time",
tooltip: "Insert date/time",
select: (e) => e === a.get(),
fetch: (a) => {
a(
p.map(t, (t) => ({
type: "choiceitem",
text: d(e, t),
value: t,
})),
);
},
onAction: (e) => {
s(a.get());
},
onItemAction: (e, t) => {
a.set(t), s(t);
},
onSetup: g(e),
});
const i = (e) => () => {
a.set(e), s(e);
};
e.ui.registry.addNestedMenuItem("insertdatetime", {
icon: "insert-time",
text: "Date/time",
getSubmenuItems: () =>
p.map(t, (t) => ({
type: "menuitem",
text: d(e, t),
onAction: i(t),
})),
onSetup: g(e),
});
})(e);
});
})();

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,4 +1,83 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=n=>e=>typeof e===n,o=e("boolean"),a=e("number"),t=n=>e=>e.options.get(n),i=t("nonbreaking_force_tab"),s=t("nonbreaking_wrap"),r=(n,e)=>{let o="";for(let a=0;a<e;a++)o+=n;return o},c=(n,e)=>{const o=s(n)||n.plugins.visualchars?`<span class="${(n=>!!n.plugins.visualchars&&n.plugins.visualchars.isEnabled())(n)?"mce-nbsp-wrap mce-nbsp":"mce-nbsp-wrap"}" contenteditable="false">${r("&nbsp;",e)}</span>`:r("&nbsp;",e);n.undoManager.transact((()=>n.insertContent(o)))};var l=tinymce.util.Tools.resolve("tinymce.util.VK");const u=n=>e=>{const o=()=>{e.setEnabled(n.selection.isEditable())};return n.on("NodeChange",o),o(),()=>{n.off("NodeChange",o)}};n.add("nonbreaking",(n=>{(n=>{const e=n.options.register;e("nonbreaking_force_tab",{processor:n=>o(n)?{value:n?3:0,valid:!0}:a(n)?{value:n,valid:!0}:{valid:!1,message:"Must be a boolean or number."},default:!1}),e("nonbreaking_wrap",{processor:"boolean",default:!0})})(n),(n=>{n.addCommand("mceNonBreaking",(()=>{c(n,1)}))})(n),(n=>{const e=()=>n.execCommand("mceNonBreaking");n.ui.registry.addButton("nonbreaking",{icon:"non-breaking",tooltip:"Nonbreaking space",onAction:e,onSetup:u(n)}),n.ui.registry.addMenuItem("nonbreaking",{icon:"non-breaking",text:"Nonbreaking space",onAction:e,onSetup:u(n)})})(n),(n=>{const e=i(n);e>0&&n.on("keydown",(o=>{if(o.keyCode===l.TAB&&!o.isDefaultPrevented()){if(o.shiftKey)return;o.preventDefault(),o.stopImmediatePropagation(),c(n,e)}}))})(n)}))}();
!(function () {
"use strict";
var n = tinymce.util.Tools.resolve("tinymce.PluginManager");
const e = (n) => (e) => typeof e === n,
o = e("boolean"),
a = e("number"),
t = (n) => (e) => e.options.get(n),
i = t("nonbreaking_force_tab"),
s = t("nonbreaking_wrap"),
r = (n, e) => {
let o = "";
for (let a = 0; a < e; a++) o += n;
return o;
},
c = (n, e) => {
const o =
s(n) || n.plugins.visualchars
? `<span class="${((n) => !!n.plugins.visualchars && n.plugins.visualchars.isEnabled())(n) ? "mce-nbsp-wrap mce-nbsp" : "mce-nbsp-wrap"}" contenteditable="false">${r("&nbsp;", e)}</span>`
: r("&nbsp;", e);
n.undoManager.transact(() => n.insertContent(o));
};
var l = tinymce.util.Tools.resolve("tinymce.util.VK");
const u = (n) => (e) => {
const o = () => {
e.setEnabled(n.selection.isEditable());
};
return (
n.on("NodeChange", o),
o(),
() => {
n.off("NodeChange", o);
}
);
};
n.add("nonbreaking", (n) => {
((n) => {
const e = n.options.register;
e("nonbreaking_force_tab", {
processor: (n) =>
o(n)
? { value: n ? 3 : 0, valid: !0 }
: a(n)
? { value: n, valid: !0 }
: { valid: !1, message: "Must be a boolean or number." },
default: !1,
}),
e("nonbreaking_wrap", { processor: "boolean", default: !0 });
})(n),
((n) => {
n.addCommand("mceNonBreaking", () => {
c(n, 1);
});
})(n),
((n) => {
const e = () => n.execCommand("mceNonBreaking");
n.ui.registry.addButton("nonbreaking", {
icon: "non-breaking",
tooltip: "Nonbreaking space",
onAction: e,
onSetup: u(n),
}),
n.ui.registry.addMenuItem("nonbreaking", {
icon: "non-breaking",
text: "Nonbreaking space",
onAction: e,
onSetup: u(n),
});
})(n),
((n) => {
const e = i(n);
e > 0 &&
n.on("keydown", (o) => {
if (o.keyCode === l.TAB && !o.isDefaultPrevented()) {
if (o.shiftKey) return;
o.preventDefault(), o.stopImmediatePropagation(), c(n, e);
}
});
})(n);
});
})();

View File

@ -1,4 +1,94 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.Env");const t=e=>a=>a.options.get(e),n=t("pagebreak_separator"),o=t("pagebreak_split_block"),r="mce-pagebreak",s=e=>{const t=`<img src="${a.transparentSrc}" class="${r}" data-mce-resize="false" data-mce-placeholder />`;return e?`<p>${t}</p>`:t},c=e=>a=>{const t=()=>{a.setEnabled(e.selection.isEditable())};return e.on("NodeChange",t),t(),()=>{e.off("NodeChange",t)}};e.add("pagebreak",(e=>{(e=>{const a=e.options.register;a("pagebreak_separator",{processor:"string",default:"\x3c!-- pagebreak --\x3e"}),a("pagebreak_split_block",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mcePageBreak",(()=>{e.insertContent(s(o(e)))}))})(e),(e=>{const a=()=>e.execCommand("mcePageBreak");e.ui.registry.addButton("pagebreak",{icon:"page-break",tooltip:"Page break",onAction:a,onSetup:c(e)}),e.ui.registry.addMenuItem("pagebreak",{text:"Page break",icon:"page-break",onAction:a,onSetup:c(e)})})(e),(e=>{const a=n(e),t=()=>o(e),c=new RegExp(a.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,(e=>"\\"+e)),"gi");e.on("BeforeSetContent",(e=>{e.content=e.content.replace(c,s(t()))})),e.on("PreInit",(()=>{e.serializer.addNodeFilter("img",(n=>{let o,s,c=n.length;for(;c--;)if(o=n[c],s=o.attr("class"),s&&-1!==s.indexOf(r)){const n=o.parent;if(n&&e.schema.getBlockElements()[n.name]&&t()){n.type=3,n.value=a,n.raw=!0,o.remove();continue}o.type=3,o.value=a,o.raw=!0}}))}))})(e),(e=>{e.on("ResolveName",(a=>{"IMG"===a.target.nodeName&&e.dom.hasClass(a.target,r)&&(a.name="pagebreak")}))})(e)}))}();
!(function () {
"use strict";
var e = tinymce.util.Tools.resolve("tinymce.PluginManager"),
a = tinymce.util.Tools.resolve("tinymce.Env");
const t = (e) => (a) => a.options.get(e),
n = t("pagebreak_separator"),
o = t("pagebreak_split_block"),
r = "mce-pagebreak",
s = (e) => {
const t = `<img src="${a.transparentSrc}" class="${r}" data-mce-resize="false" data-mce-placeholder />`;
return e ? `<p>${t}</p>` : t;
},
c = (e) => (a) => {
const t = () => {
a.setEnabled(e.selection.isEditable());
};
return (
e.on("NodeChange", t),
t(),
() => {
e.off("NodeChange", t);
}
);
};
e.add("pagebreak", (e) => {
((e) => {
const a = e.options.register;
a("pagebreak_separator", {
processor: "string",
default: "\x3c!-- pagebreak --\x3e",
}),
a("pagebreak_split_block", { processor: "boolean", default: !1 });
})(e),
((e) => {
e.addCommand("mcePageBreak", () => {
e.insertContent(s(o(e)));
});
})(e),
((e) => {
const a = () => e.execCommand("mcePageBreak");
e.ui.registry.addButton("pagebreak", {
icon: "page-break",
tooltip: "Page break",
onAction: a,
onSetup: c(e),
}),
e.ui.registry.addMenuItem("pagebreak", {
text: "Page break",
icon: "page-break",
onAction: a,
onSetup: c(e),
});
})(e),
((e) => {
const a = n(e),
t = () => o(e),
c = new RegExp(
a.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g, (e) => "\\" + e),
"gi",
);
e.on("BeforeSetContent", (e) => {
e.content = e.content.replace(c, s(t()));
}),
e.on("PreInit", () => {
e.serializer.addNodeFilter("img", (n) => {
let o,
s,
c = n.length;
for (; c--; )
if (
((o = n[c]), (s = o.attr("class")), s && -1 !== s.indexOf(r))
) {
const n = o.parent;
if (n && e.schema.getBlockElements()[n.name] && t()) {
(n.type = 3), (n.value = a), (n.raw = !0), o.remove();
continue;
}
(o.type = 3), (o.value = a), (o.raw = !0);
}
});
});
})(e),
((e) => {
e.on("ResolveName", (a) => {
"IMG" === a.target.nodeName &&
e.dom.hasClass(a.target, r) &&
(a.name = "pagebreak");
});
})(e);
});
})();

View File

@ -1,4 +1,97 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=e=>t=>t.options.get(e),i=n("content_style"),s=n("content_css_cors"),c=n("body_class"),r=n("body_id");e.add("preview",(e=>{(e=>{e.addCommand("mcePreview",(()=>{(e=>{const n=(e=>{var n;let l="";const a=e.dom.encode,d=null!==(n=i(e))&&void 0!==n?n:"";l+='<base href="'+a(e.documentBaseURI.getURI())+'">';const m=s(e)?' crossorigin="anonymous"':"";o.each(e.contentCSS,(t=>{l+='<link type="text/css" rel="stylesheet" href="'+a(e.documentBaseURI.toAbsolute(t))+'"'+m+">"})),d&&(l+='<style type="text/css">'+d+"</style>");const y=r(e),u=c(e),v='<script>document.addEventListener && document.addEventListener("click", function(e) {for (var elm = e.target; elm; elm = elm.parentNode) {if (elm.nodeName === "A" && !('+(t.os.isMacOS()||t.os.isiOS()?"e.metaKey":"e.ctrlKey && !e.altKey")+")) {e.preventDefault();}}}, false);<\/script> ",p=e.getBody().dir,w=p?' dir="'+a(p)+'"':"";return"<!DOCTYPE html><html><head>"+l+'</head><body id="'+a(y)+'" class="mce-content-body '+a(u)+'"'+w+">"+e.getContent()+v+"</body></html>"})(e);e.windowManager.open({title:"Preview",size:"large",body:{type:"panel",items:[{name:"preview",type:"iframe",sandboxed:!0,transparent:!1}]},buttons:[{type:"cancel",name:"close",text:"Close",primary:!0}],initialData:{preview:n}}).focus("close")})(e)}))})(e),(e=>{const t=()=>e.execCommand("mcePreview");e.ui.registry.addButton("preview",{icon:"preview",tooltip:"Preview",onAction:t}),e.ui.registry.addMenuItem("preview",{icon:"preview",text:"Preview",onAction:t})})(e)}))}();
!(function () {
"use strict";
var e = tinymce.util.Tools.resolve("tinymce.PluginManager"),
t = tinymce.util.Tools.resolve("tinymce.Env"),
o = tinymce.util.Tools.resolve("tinymce.util.Tools");
const n = (e) => (t) => t.options.get(e),
i = n("content_style"),
s = n("content_css_cors"),
c = n("body_class"),
r = n("body_id");
e.add("preview", (e) => {
((e) => {
e.addCommand("mcePreview", () => {
((e) => {
const n = ((e) => {
var n;
let l = "";
const a = e.dom.encode,
d = null !== (n = i(e)) && void 0 !== n ? n : "";
l += '<base href="' + a(e.documentBaseURI.getURI()) + '">';
const m = s(e) ? ' crossorigin="anonymous"' : "";
o.each(e.contentCSS, (t) => {
l +=
'<link type="text/css" rel="stylesheet" href="' +
a(e.documentBaseURI.toAbsolute(t)) +
'"' +
m +
">";
}),
d && (l += '<style type="text/css">' + d + "</style>");
const y = r(e),
u = c(e),
v =
'<script>document.addEventListener && document.addEventListener("click", function(e) {for (var elm = e.target; elm; elm = elm.parentNode) {if (elm.nodeName === "A" && !(' +
(t.os.isMacOS() || t.os.isiOS()
? "e.metaKey"
: "e.ctrlKey && !e.altKey") +
")) {e.preventDefault();}}}, false);</script> ",
p = e.getBody().dir,
w = p ? ' dir="' + a(p) + '"' : "";
return (
"<!DOCTYPE html><html><head>" +
l +
'</head><body id="' +
a(y) +
'" class="mce-content-body ' +
a(u) +
'"' +
w +
">" +
e.getContent() +
v +
"</body></html>"
);
})(e);
e.windowManager
.open({
title: "Preview",
size: "large",
body: {
type: "panel",
items: [
{
name: "preview",
type: "iframe",
sandboxed: !0,
transparent: !1,
},
],
},
buttons: [
{ type: "cancel", name: "close", text: "Close", primary: !0 },
],
initialData: { preview: n },
})
.focus("close");
})(e);
});
})(e),
((e) => {
const t = () => e.execCommand("mcePreview");
e.ui.registry.addButton("preview", {
icon: "preview",
tooltip: "Preview",
onAction: t,
}),
e.ui.registry.addMenuItem("preview", {
icon: "preview",
text: "Preview",
onAction: t,
});
})(e);
});
})();

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,76 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const n=("function",e=>"function"==typeof e);var o=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),t=tinymce.util.Tools.resolve("tinymce.util.Tools");const a=e=>n=>n.options.get(e),c=a("save_enablewhendirty"),i=a("save_onsavecallback"),s=a("save_oncancelcallback"),r=(e,n)=>{e.notificationManager.open({text:n,type:"error"})},l=e=>n=>{const o=()=>{n.setEnabled(!c(e)||e.isDirty())};return o(),e.on("NodeChange dirty",o),()=>e.off("NodeChange dirty",o)};e.add("save",(e=>{(e=>{const n=e.options.register;n("save_enablewhendirty",{processor:"boolean",default:!0}),n("save_onsavecallback",{processor:"function"}),n("save_oncancelcallback",{processor:"function"})})(e),(e=>{e.ui.registry.addButton("save",{icon:"save",tooltip:"Save",enabled:!1,onAction:()=>e.execCommand("mceSave"),onSetup:l(e)}),e.ui.registry.addButton("cancel",{icon:"cancel",tooltip:"Cancel",enabled:!1,onAction:()=>e.execCommand("mceCancel"),onSetup:l(e)}),e.addShortcut("Meta+S","","mceSave")})(e),(e=>{e.addCommand("mceSave",(()=>{(e=>{const t=o.DOM.getParent(e.id,"form");if(c(e)&&!e.isDirty())return;e.save();const a=i(e);if(n(a))return a.call(e,e),void e.nodeChanged();t?(e.setDirty(!1),t.onsubmit&&!t.onsubmit()||("function"==typeof t.submit?t.submit():r(e,"Error: Form submit field collision.")),e.nodeChanged()):r(e,"Error: No form element found.")})(e)})),e.addCommand("mceCancel",(()=>{(e=>{const o=t.trim(e.startContent),a=s(e);n(a)?a.call(e,e):e.resetContent(o)})(e)}))})(e)}))}();
!(function () {
"use strict";
var e = tinymce.util.Tools.resolve("tinymce.PluginManager");
const n = ("function", (e) => "function" == typeof e);
var o = tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),
t = tinymce.util.Tools.resolve("tinymce.util.Tools");
const a = (e) => (n) => n.options.get(e),
c = a("save_enablewhendirty"),
i = a("save_onsavecallback"),
s = a("save_oncancelcallback"),
r = (e, n) => {
e.notificationManager.open({ text: n, type: "error" });
},
l = (e) => (n) => {
const o = () => {
n.setEnabled(!c(e) || e.isDirty());
};
return (
o(), e.on("NodeChange dirty", o), () => e.off("NodeChange dirty", o)
);
};
e.add("save", (e) => {
((e) => {
const n = e.options.register;
n("save_enablewhendirty", { processor: "boolean", default: !0 }),
n("save_onsavecallback", { processor: "function" }),
n("save_oncancelcallback", { processor: "function" });
})(e),
((e) => {
e.ui.registry.addButton("save", {
icon: "save",
tooltip: "Save",
enabled: !1,
onAction: () => e.execCommand("mceSave"),
onSetup: l(e),
}),
e.ui.registry.addButton("cancel", {
icon: "cancel",
tooltip: "Cancel",
enabled: !1,
onAction: () => e.execCommand("mceCancel"),
onSetup: l(e),
}),
e.addShortcut("Meta+S", "", "mceSave");
})(e),
((e) => {
e.addCommand("mceSave", () => {
((e) => {
const t = o.DOM.getParent(e.id, "form");
if (c(e) && !e.isDirty()) return;
e.save();
const a = i(e);
if (n(a)) return a.call(e, e), void e.nodeChanged();
t
? (e.setDirty(!1),
(t.onsubmit && !t.onsubmit()) ||
("function" == typeof t.submit
? t.submit()
: r(e, "Error: Form submit field collision.")),
e.nodeChanged())
: r(e, "Error: No form element found.");
})(e);
}),
e.addCommand("mceCancel", () => {
((e) => {
const o = t.trim(e.startContent),
a = s(e);
n(a) ? a.call(e, e) : e.resetContent(o);
})(e);
});
})(e);
});
})();

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,4 +1,72 @@
/**
* TinyMCE version 6.7.0 (2023-08-30)
*/
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager");const s=(t,s,o)=>{t.dom.toggleClass(t.getBody(),"mce-visualblocks"),o.set(!o.get()),((t,s)=>{t.dispatch("VisualBlocks",{state:s})})(t,o.get())},o=("visualblocks_default_state",t=>t.options.get("visualblocks_default_state"));const e=(t,s)=>o=>{o.setActive(s.get());const e=t=>o.setActive(t.state);return t.on("VisualBlocks",e),()=>t.off("VisualBlocks",e)};t.add("visualblocks",((t,l)=>{(t=>{(0,t.options.register)("visualblocks_default_state",{processor:"boolean",default:!1})})(t);const a=(t=>{let s=!1;return{get:()=>s,set:t=>{s=t}}})();((t,o,e)=>{t.addCommand("mceVisualBlocks",(()=>{s(t,0,e)}))})(t,0,a),((t,s)=>{const o=()=>t.execCommand("mceVisualBlocks");t.ui.registry.addToggleButton("visualblocks",{icon:"visualblocks",tooltip:"Show blocks",onAction:o,onSetup:e(t,s)}),t.ui.registry.addToggleMenuItem("visualblocks",{text:"Show blocks",icon:"visualblocks",onAction:o,onSetup:e(t,s)})})(t,a),((t,e,l)=>{t.on("PreviewFormats AfterPreviewFormats",(s=>{l.get()&&t.dom.toggleClass(t.getBody(),"mce-visualblocks","afterpreviewformats"===s.type)})),t.on("init",(()=>{o(t)&&s(t,0,l)}))})(t,0,a)}))}();
!(function () {
"use strict";
var t = tinymce.util.Tools.resolve("tinymce.PluginManager");
const s = (t, s, o) => {
t.dom.toggleClass(t.getBody(), "mce-visualblocks"),
o.set(!o.get()),
((t, s) => {
t.dispatch("VisualBlocks", { state: s });
})(t, o.get());
},
o =
("visualblocks_default_state",
(t) => t.options.get("visualblocks_default_state"));
const e = (t, s) => (o) => {
o.setActive(s.get());
const e = (t) => o.setActive(t.state);
return t.on("VisualBlocks", e), () => t.off("VisualBlocks", e);
};
t.add("visualblocks", (t, l) => {
((t) => {
(0, t.options.register)("visualblocks_default_state", {
processor: "boolean",
default: !1,
});
})(t);
const a = ((t) => {
let s = !1;
return {
get: () => s,
set: (t) => {
s = t;
},
};
})();
((t, o, e) => {
t.addCommand("mceVisualBlocks", () => {
s(t, 0, e);
});
})(t, 0, a),
((t, s) => {
const o = () => t.execCommand("mceVisualBlocks");
t.ui.registry.addToggleButton("visualblocks", {
icon: "visualblocks",
tooltip: "Show blocks",
onAction: o,
onSetup: e(t, s),
}),
t.ui.registry.addToggleMenuItem("visualblocks", {
text: "Show blocks",
icon: "visualblocks",
onAction: o,
onSetup: e(t, s),
});
})(t, a),
((t, e, l) => {
t.on("PreviewFormats AfterPreviewFormats", (s) => {
l.get() &&
t.dom.toggleClass(
t.getBody(),
"mce-visualblocks",
"afterpreviewformats" === s.type,
);
}),
t.on("init", () => {
o(t) && s(t, 0, l);
});
})(t, 0, a);
});
})();

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,60 @@
body{background-color:#222f3e;color:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}a{color:#4099ff}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#6d737b}figure{display:table;margin:1rem auto}figure figcaption{color:#8a8f97;display:block;margin-top:.25rem;text-align:center}hr{border-color:#6d737b;border-style:solid;border-width:1px 0 0 0}code{background-color:#6d737b;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #6d737b;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #6d737b;margin-right:1.5rem;padding-right:1rem}
body {
background-color: #222f3e;
color: #fff;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
line-height: 1.4;
margin: 1rem;
}
a {
color: #4099ff;
}
table {
border-collapse: collapse;
}
table:not([cellpadding]) td,
table:not([cellpadding]) th {
padding: 0.4rem;
}
table[border]:not([border="0"]):not([style*="border-width"]) td,
table[border]:not([border="0"]):not([style*="border-width"]) th {
border-width: 1px;
}
table[border]:not([border="0"]):not([style*="border-style"]) td,
table[border]:not([border="0"]):not([style*="border-style"]) th {
border-style: solid;
}
table[border]:not([border="0"]):not([style*="border-color"]) td,
table[border]:not([border="0"]):not([style*="border-color"]) th {
border-color: #6d737b;
}
figure {
display: table;
margin: 1rem auto;
}
figure figcaption {
color: #8a8f97;
display: block;
margin-top: 0.25rem;
text-align: center;
}
hr {
border-color: #6d737b;
border-style: solid;
border-width: 1px 0 0 0;
}
code {
background-color: #6d737b;
border-radius: 3px;
padding: 0.1rem 0.2rem;
}
.mce-content-body:not([dir="rtl"]) blockquote {
border-left: 2px solid #6d737b;
margin-left: 1.5rem;
padding-left: 1rem;
}
.mce-content-body[dir="rtl"] blockquote {
border-right: 2px solid #6d737b;
margin-right: 1.5rem;
padding-right: 1rem;
}

View File

@ -1 +1,55 @@
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
line-height: 1.4;
margin: 1rem;
}
table {
border-collapse: collapse;
}
table:not([cellpadding]) td,
table:not([cellpadding]) th {
padding: 0.4rem;
}
table[border]:not([border="0"]):not([style*="border-width"]) td,
table[border]:not([border="0"]):not([style*="border-width"]) th {
border-width: 1px;
}
table[border]:not([border="0"]):not([style*="border-style"]) td,
table[border]:not([border="0"]):not([style*="border-style"]) th {
border-style: solid;
}
table[border]:not([border="0"]):not([style*="border-color"]) td,
table[border]:not([border="0"]):not([style*="border-color"]) th {
border-color: #ccc;
}
figure {
display: table;
margin: 1rem auto;
}
figure figcaption {
color: #999;
display: block;
margin-top: 0.25rem;
text-align: center;
}
hr {
border-color: #ccc;
border-style: solid;
border-width: 1px 0 0 0;
}
code {
background-color: #e8e8e8;
border-radius: 3px;
padding: 0.1rem 0.2rem;
}
.mce-content-body:not([dir="rtl"]) blockquote {
border-left: 2px solid #ccc;
margin-left: 1.5rem;
padding-left: 1rem;
}
.mce-content-body[dir="rtl"] blockquote {
border-right: 2px solid #ccc;
margin-right: 1.5rem;
padding-right: 1rem;
}

View File

@ -1 +1,60 @@
@media screen{html{background:#f4f4f4;min-height:100%}}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}@media screen{body{background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.15);box-sizing:border-box;margin:1rem auto 0;max-width:820px;min-height:calc(100vh - 1rem);padding:4rem 6rem 6rem 6rem}}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure figcaption{color:#999;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
@media screen {
html {
background: #f4f4f4;
min-height: 100%;
}
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}
@media screen {
body {
background-color: #fff;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.15);
box-sizing: border-box;
margin: 1rem auto 0;
max-width: 820px;
min-height: calc(100vh - 1rem);
padding: 4rem 6rem 6rem 6rem;
}
}
table {
border-collapse: collapse;
}
table:not([cellpadding]) td,
table:not([cellpadding]) th {
padding: 0.4rem;
}
table[border]:not([border="0"]):not([style*="border-width"]) td,
table[border]:not([border="0"]):not([style*="border-width"]) th {
border-width: 1px;
}
table[border]:not([border="0"]):not([style*="border-style"]) td,
table[border]:not([border="0"]):not([style*="border-style"]) th {
border-style: solid;
}
table[border]:not([border="0"]):not([style*="border-color"]) td,
table[border]:not([border="0"]):not([style*="border-color"]) th {
border-color: #ccc;
}
figure figcaption {
color: #999;
margin-top: 0.25rem;
text-align: center;
}
hr {
border-color: #ccc;
border-style: solid;
border-width: 1px 0 0 0;
}
.mce-content-body:not([dir="rtl"]) blockquote {
border-left: 2px solid #ccc;
margin-left: 1.5rem;
padding-left: 1rem;
}
.mce-content-body[dir="rtl"] blockquote {
border-right: 2px solid #ccc;
margin-right: 1.5rem;
padding-right: 1rem;
}

View File

@ -1,5 +1,6 @@
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
line-height: 1.4;
margin: 1rem;
}
@ -31,12 +32,12 @@ code {
border-radius: 3px;
padding: 0.1rem 0.2rem;
}
.mce-content-body:not([dir=rtl]) blockquote {
.mce-content-body:not([dir="rtl"]) blockquote {
border-left: 2px solid #ccc;
margin-left: 1.5rem;
padding-left: 1rem;
}
.mce-content-body[dir=rtl] blockquote {
.mce-content-body[dir="rtl"] blockquote {
border-right: 2px solid #ccc;
margin-right: 1.5rem;
padding-right: 1rem;

View File

@ -1 +1,44 @@
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table td,table th{border:1px solid #ccc;padding:.4rem}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
line-height: 1.4;
margin: 1rem;
}
table {
border-collapse: collapse;
}
table td,
table th {
border: 1px solid #ccc;
padding: 0.4rem;
}
figure {
display: table;
margin: 1rem auto;
}
figure figcaption {
color: #999;
display: block;
margin-top: 0.25rem;
text-align: center;
}
hr {
border-color: #ccc;
border-style: solid;
border-width: 1px 0 0 0;
}
code {
background-color: #e8e8e8;
border-radius: 3px;
padding: 0.1rem 0.2rem;
}
.mce-content-body:not([dir="rtl"]) blockquote {
border-left: 2px solid #ccc;
margin-left: 1.5rem;
padding-left: 1rem;
}
.mce-content-body[dir="rtl"] blockquote {
border-right: 2px solid #ccc;
margin-right: 1.5rem;
padding-right: 1rem;
}

View File

@ -1 +1,56 @@
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem auto;max-width:900px}table{border-collapse:collapse}table:not([cellpadding]) td,table:not([cellpadding]) th{padding:.4rem}table[border]:not([border="0"]):not([style*=border-width]) td,table[border]:not([border="0"]):not([style*=border-width]) th{border-width:1px}table[border]:not([border="0"]):not([style*=border-style]) td,table[border]:not([border="0"]):not([style*=border-style]) th{border-style:solid}table[border]:not([border="0"]):not([style*=border-color]) td,table[border]:not([border="0"]):not([style*=border-color]) th{border-color:#ccc}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
line-height: 1.4;
margin: 1rem auto;
max-width: 900px;
}
table {
border-collapse: collapse;
}
table:not([cellpadding]) td,
table:not([cellpadding]) th {
padding: 0.4rem;
}
table[border]:not([border="0"]):not([style*="border-width"]) td,
table[border]:not([border="0"]):not([style*="border-width"]) th {
border-width: 1px;
}
table[border]:not([border="0"]):not([style*="border-style"]) td,
table[border]:not([border="0"]):not([style*="border-style"]) th {
border-style: solid;
}
table[border]:not([border="0"]):not([style*="border-color"]) td,
table[border]:not([border="0"]):not([style*="border-color"]) th {
border-color: #ccc;
}
figure {
display: table;
margin: 1rem auto;
}
figure figcaption {
color: #999;
display: block;
margin-top: 0.25rem;
text-align: center;
}
hr {
border-color: #ccc;
border-style: solid;
border-width: 1px 0 0 0;
}
code {
background-color: #e8e8e8;
border-radius: 3px;
padding: 0.1rem 0.2rem;
}
.mce-content-body:not([dir="rtl"]) blockquote {
border-left: 2px solid #ccc;
margin-left: 1.5rem;
padding-left: 1rem;
}
.mce-content-body[dir="rtl"] blockquote {
border-right: 2px solid #ccc;
margin-right: 1.5rem;
padding-right: 1rem;
}

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,30 @@
body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201}
body.tox-dialog__disable-scroll {
overflow: hidden;
}
.tox-fullscreen {
border: 0;
height: 100%;
margin: 0;
overflow: hidden;
overscroll-behavior: none;
padding: 0;
touch-action: pinch-zoom;
width: 100%;
}
.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle {
display: none;
}
.tox-shadowhost.tox-fullscreen,
.tox.tox-tinymce.tox-fullscreen {
left: 0;
position: fixed;
top: 0;
z-index: 1200;
}
.tox.tox-tinymce.tox-fullscreen {
background-color: transparent;
}
.tox-fullscreen .tox.tox-tinymce-aux,
.tox-fullscreen ~ .tox.tox-tinymce-aux {
z-index: 1201;
}

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,30 @@
body.tox-dialog__disable-scroll{overflow:hidden}.tox-fullscreen{border:0;height:100%;margin:0;overflow:hidden;overscroll-behavior:none;padding:0;touch-action:pinch-zoom;width:100%}.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle{display:none}.tox-shadowhost.tox-fullscreen,.tox.tox-tinymce.tox-fullscreen{left:0;position:fixed;top:0;z-index:1200}.tox.tox-tinymce.tox-fullscreen{background-color:transparent}.tox-fullscreen .tox.tox-tinymce-aux,.tox-fullscreen~.tox.tox-tinymce-aux{z-index:1201}
body.tox-dialog__disable-scroll {
overflow: hidden;
}
.tox-fullscreen {
border: 0;
height: 100%;
margin: 0;
overflow: hidden;
overscroll-behavior: none;
padding: 0;
touch-action: pinch-zoom;
width: 100%;
}
.tox.tox-tinymce.tox-fullscreen .tox-statusbar__resize-handle {
display: none;
}
.tox-shadowhost.tox-fullscreen,
.tox.tox-tinymce.tox-fullscreen {
left: 0;
position: fixed;
top: 0;
z-index: 1200;
}
.tox.tox-tinymce.tox-fullscreen {
background-color: transparent;
}
.tox-fullscreen .tox.tox-tinymce-aux,
.tox-fullscreen ~ .tox.tox-tinymce-aux {
z-index: 1201;
}

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,12 +1,11 @@
import PocketBase from 'pocketbase';
import { userRegion } from '$lib/store';
import PocketBase from "pocketbase";
import { userRegion } from "$lib/store";
const usRegion = ['cle1','iad1','pdx1','sfo1'];
const usRegion = ["cle1", "iad1", "pdx1", "sfo1"];
let pbUrl;
userRegion.subscribe(value => {
userRegion.subscribe((value) => {
if (usRegion?.includes(value)) {
pbUrl = import.meta.env.VITE_USEAST_POCKETBASE_URL;
} else {

View File

@ -1,98 +1,106 @@
import { z } from 'zod';
import { z } from "zod";
export const loginUserSchema = z.object({
email: z
.string({ required_error: 'Email is required' })
.email({ message: 'Email must be a valid email.' }),
password: z.string({ required_error: 'Password is required' })
.string({ required_error: "Email is required" })
.email({ message: "Email must be a valid email." }),
password: z.string({ required_error: "Password is required" }),
});
export const registerUserSchema = z
.object({
username: z
.string({ required_error: 'Username is required' })
.regex(/^[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]*$/, { message: 'Username can only contain letters, numbers, and special characters.' }) // Updated regex pattern
.min(3, { message: 'Username must be at least 2 characters' })
.max(64, { message: 'Username must be less than 64 characters' })
.string({ required_error: "Username is required" })
.regex(/^[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]*$/, {
message:
"Username can only contain letters, numbers, and special characters.",
}) // Updated regex pattern
.min(3, { message: "Username must be at least 2 characters" })
.max(64, { message: "Username must be less than 64 characters" })
.trim(),
email: z
.string({ required_error: 'Email is required' })
.email({ message: 'Email must be a valid email' }),
.string({ required_error: "Email is required" })
.email({ message: "Email must be a valid email" }),
password: z
.string({ required_error: 'Password is required' })
.regex(/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&+\-,.\[\]{};':"\\|/=\(\)\^_*]{8,}$/, {
.string({ required_error: "Password is required" })
.regex(
/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&+\-,.\[\]{};':"\\|/=\(\)\^_*]{8,}$/,
{
message:
'Password must be a minimum of 8 characters & contain at least one letter, one number, and one special character.'
}),
"Password must be a minimum of 8 characters & contain at least one letter, one number, and one special character.",
},
),
passwordConfirm: z
.string({ required_error: 'Confirm Password is required' })
.regex(/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&+\-,.\[\]{};':"\\|/=\(\)\^_*]{8,}$/, {
.string({ required_error: "Confirm Password is required" })
.regex(
/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&+\-,.\[\]{};':"\\|/=\(\)\^_*]{8,}$/,
{
message:
'Password must be a minimum of 8 characters & contain at least one letter, one number, and one special character.'
})
"Password must be a minimum of 8 characters & contain at least one letter, one number, and one special character.",
},
),
})
.superRefine(({ passwordConfirm, password }, ctx) => {
if (passwordConfirm !== password) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Password & Confirm password must match',
path: ['password']
message: "Password & Confirm password must match",
path: ["password"],
});
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Password & Confirm password must match',
path: ['passwordConfirm']
message: "Password & Confirm password must match",
path: ["passwordConfirm"],
});
}
});
export const createPostTextSchema = z.object({
title: z
.string({ required_error: 'Title is required' })
.min(1, { message: 'Title is required' })
.max(300, { message: 'Title must be 300 characters or less' })
.string({ required_error: "Title is required" })
.min(1, { message: "Title is required" })
.max(300, { message: "Title must be 300 characters or less" })
.trim(),
//url: z.string().optional().url({ message: 'URL must be a valid URL' }),
tagline: z.string(),
tagTopic: z.string(),
atLeastOneTag: z.string({ required_error: 'At least 1 tag is required' })
.min(1, { message: 'At least 1 tag is required' }),
atLeastOneTag: z
.string({ required_error: "At least 1 tag is required" })
.min(1, { message: "At least 1 tag is required" }),
description: z.string(),
postType: z.string({ required_error: 'PostType is required.' }),
user: z.string({ required_error: 'User is required.' }),
postType: z.string({ required_error: "PostType is required." }),
user: z.string({ required_error: "User is required." }),
});
const imageTypes = [
'image/jpeg',
'image/jpg',
'image/png',
'image/webp',
'image/svg+xml',
'image/gif'
"image/jpeg",
"image/jpg",
"image/png",
"image/webp",
"image/svg+xml",
"image/gif",
];
const videoTypes = ['video/mp4', 'video/gif'];
const videoTypes = ["video/mp4", "video/gif"];
export const createPostImageSchema = z.object({
title: z
.string({ required_error: 'Title is required' })
.min(1, { message: 'Title is required' })
.max(300, { message: 'Title must be 300 characters or less' })
.string({ required_error: "Title is required" })
.min(1, { message: "Title is required" })
.max(300, { message: "Title must be 300 characters or less" })
.trim(),
tagTopic: z.string(),
tagline: z.string(),
atLeastOneTag: z.string({ required_error: 'At least 1 tag is required' }).min(1, { message: 'At least 1 tag is required' }),
thumbnail: z
.instanceof(File)
.superRefine((val, ctx) => {
atLeastOneTag: z
.string({ required_error: "At least 1 tag is required" })
.min(1, { message: "At least 1 tag is required" }),
thumbnail: z.instanceof(File).superRefine((val, ctx) => {
if (val) {
if (val.size > 5121440) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'File must be less than 5MB',
message: "File must be less than 5MB",
});
}
@ -104,28 +112,27 @@ export const createPostImageSchema = z.object({
ctx.addIssue({
code: z.ZodIssueCode.custom,
message:
'Unsupported file type. Supported formats: jpeg, jpg, png, webp, svg',
"Unsupported file type. Supported formats: jpeg, jpg, png, webp, svg",
});
}
}
}),
postType: z.string({ required_error: 'PostType is required.' }),
user: z.string({ required_error: 'User is required.' }),
postType: z.string({ required_error: "PostType is required." }),
user: z.string({ required_error: "User is required." }),
});
export const createPostLinkSchema = z.object({
title: z
.string({ required_error: 'Title is required' })
.min(1, { message: 'Title is required' })
.max(300, { message: 'Title must be 300 characters or less' })
.string({ required_error: "Title is required" })
.min(1, { message: "Title is required" })
.max(300, { message: "Title must be 300 characters or less" })
.trim(),
tagTopic: z.string(),
tagline: z.string(),
atLeastOneTag: z.string({ required_error: 'At least 1 tag is required' })
.min(1, { message: 'At least 1 tag is required' }),
link: z.string().url({ message: 'URL must be a valid URL' }),
atLeastOneTag: z
.string({ required_error: "At least 1 tag is required" })
.min(1, { message: "At least 1 tag is required" }),
link: z.string().url({ message: "URL must be a valid URL" }),
description: z.string(),
/*
thumbnail: z
@ -148,14 +155,12 @@ export const createPostLinkSchema = z.object({
}
}),
*/
postType: z.string({ required_error: 'PostType is required.' }),
user: z.string({ required_error: 'User is required.' }),
postType: z.string({ required_error: "PostType is required." }),
user: z.string({ required_error: "User is required." }),
});
//export const updatePostSchema = createPostSchema.omit({ user: true });
export const updatePersonalDataSchema = z.object({
/*
email: z
@ -163,63 +168,73 @@ export const updatePersonalDataSchema = z.object({
.email({ message: 'Email must be a valid email' }),
*/
username: z
.string({ required_error: 'Username is required' })
.min(2, { message: 'Username must be at least 2 characters' })
.max(24, { message: 'Username must be 24 characters or less' })
.regex(/^[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]*$/, { message: 'Username can only contain letters, numbers, and special characters.' }) // Updated regex pattern
.string({ required_error: "Username is required" })
.min(2, { message: "Username must be at least 2 characters" })
.max(24, { message: "Username must be 24 characters or less" })
.regex(/^[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]*$/, {
message:
"Username can only contain letters, numbers, and special characters.",
}), // Updated regex pattern
});
export const updateEmailSchema = z.object({
email: z
.string({ required_error: 'Email is required' })
.email({ message: 'Email must be a valid email' })
.string({ required_error: "Email is required" })
.email({ message: "Email must be a valid email" }),
});
export const updateUsernameSchema = z.object({
username: z
.string({ required_error: 'Username is required' })
.min(2, { message: 'Username must be at least 2 characters' })
.max(24, { message: 'Username must be 24 characters or less' })
.regex(/^[a-zA-Z0-9]*$/, { message: 'Username can only contain letters or numbers.' })
.string({ required_error: "Username is required" })
.min(2, { message: "Username must be at least 2 characters" })
.max(24, { message: "Username must be 24 characters or less" })
.regex(/^[a-zA-Z0-9]*$/, {
message: "Username can only contain letters or numbers.",
}),
});
export const updatePasswordSchema = z
.object({
oldPassword: z.string({ required_error: 'Old password is required' }),
oldPassword: z.string({ required_error: "Old password is required" }),
password: z
.string({ required_error: 'Password is required' })
.regex(/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&+\-,.\[\]{};':"\\|/=\(\)\^_*]{8,}$/, {
.string({ required_error: "Password is required" })
.regex(
/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&+\-,.\[\]{};':"\\|/=\(\)\^_*]{8,}$/,
{
message:
'Password must be a minimum of 8 characters & contain at least one letter, one number, and one special character.'
}),
"Password must be a minimum of 8 characters & contain at least one letter, one number, and one special character.",
},
),
passwordConfirm: z
.string({ required_error: 'Confirm Password is required' })
.regex(/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&+\-,.\[\]{};':"\\|/=\(\)\^_*]{8,}$/, {
.string({ required_error: "Confirm Password is required" })
.regex(
/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d@$!%*#?&+\-,.\[\]{};':"\\|/=\(\)\^_*]{8,}$/,
{
message:
'Password must be a minimum of 8 characters & contain at least one letter, one number, and one special character.'
})
"Password must be a minimum of 8 characters & contain at least one letter, one number, and one special character.",
},
),
})
.superRefine(({ passwordConfirm, password }, ctx) => {
if (passwordConfirm !== password) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Password & Confirm password must match',
path: ['password']
message: "Password & Confirm password must match",
path: ["password"],
});
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Password & Confirm password must match',
path: ['passwordConfirm']
message: "Password & Confirm password must match",
path: ["passwordConfirm"],
});
}
});
export const updateProfileSchema = z.object({
name: z
.string({ required_error: 'Name is required' })
.min(1, { message: 'Name is required' })
.max(64, { message: 'Name must be 64 characters or less' })
.string({ required_error: "Name is required" })
.min(1, { message: "Name is required" })
.max(64, { message: "Name must be 64 characters or less" })
.trim(),
avatar: z
.instanceof(Blob)
@ -229,31 +244,28 @@ export const updateProfileSchema = z.object({
if (val.size > 5242880) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Avatar must be less than 5MB'
message: "Avatar must be less than 5MB",
});
}
if (!imageTypes.includes(val.type)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Unsupported file type. Supported formats: jpeg, jpg, png, webp, svg, gif'
message:
"Unsupported file type. Supported formats: jpeg, jpg, png, webp, svg, gif",
});
}
}
})
}),
});
export const updateAvatarSchema = z.object({
avatar: z
.instanceof(File)
.superRefine((val, ctx) => {
avatar: z.instanceof(File).superRefine((val, ctx) => {
if (val) {
if (val.size > 5242880) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Avatar must be less than 5MB',
message: "Avatar must be less than 5MB",
});
}
@ -265,148 +277,118 @@ export const updateAvatarSchema = z.object({
ctx.addIssue({
code: z.ZodIssueCode.custom,
message:
'Unsupported file type. Supported formats: jpeg, jpg, png, webp, svg, gif',
"Unsupported file type. Supported formats: jpeg, jpg, png, webp, svg, gif",
});
}
}
}),
});
export const createCommentTextSchema = z.object({
comment: z
.string({ required_error: 'Comment cannot be empty' })
.min(1, { message: 'Comment cannot be empty' })
.string({ required_error: "Comment cannot be empty" })
.min(1, { message: "Comment cannot be empty" })
//.max(40000, { message: 'Comment is too long. Keep it simple and concise bruv!' })
.trim(),
user: z.string({ required_error: 'User is required.' }),
post: z.string({ required_error: 'Post is required.' }),
user: z.string({ required_error: "User is required." }),
post: z.string({ required_error: "Post is required." }),
reply: z.string(),
});
export const updateCommentTextSchema = z.object({
comment: z
.string({ required_error: 'Comment cannot be empty' })
.min(1, { message: 'Comment cannot be empty' })
.string({ required_error: "Comment cannot be empty" })
.min(1, { message: "Comment cannot be empty" })
//.max(40000, { message: 'Comment is too long. Keep it simple and concise bruv!' })
.trim(),
});
export const createCommentImageSchema = z.object({
comment: z
.string({ required_error: 'Comment cannot be empty' })
.min(1, { message: 'Comment cannot be empty' })
.string({ required_error: "Comment cannot be empty" })
.min(1, { message: "Comment cannot be empty" })
//.max(40000, { message: 'Comment is too long. Keep it simple and concise bruv!' })
.trim(),
image: z
.instanceof(Blob, { message: 'Image is required' })
.instanceof(Blob, { message: "Image is required" })
.superRefine((val, ctx) => {
if (val) {
if (val.size > 5242880) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Image must be less than 5MB'
message: "Image must be less than 5MB",
});
}
if (!imageTypes.includes(val.type)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Unsupported file type. Supported formats: jpeg, jpg, png, webp, svg, gif'
message:
"Unsupported file type. Supported formats: jpeg, jpg, png, webp, svg, gif",
});
}
}
}),
user: z.string({ required_error: 'User is required.' }),
post: z.string({ required_error: 'Post is required.' }),
user: z.string({ required_error: "User is required." }),
post: z.string({ required_error: "Post is required." }),
reply: z.string(),
});
export const createNotebookSchema = z.object({
title: z
.string({ required_error: 'Title cannot be empty' })
.min(1, { message: 'Title cannot be empty' })
.max(100, { message: 'Title is too long. Keep it simple and concise bruv!' })
.string({ required_error: "Title cannot be empty" })
.min(1, { message: "Title cannot be empty" })
.max(100, {
message: "Title is too long. Keep it simple and concise bruv!",
})
.trim(),
user: z.string({ required_error: 'User is required.' }),
user: z.string({ required_error: "User is required." }),
});
export const createStrategySchema = z.object({
title: z
.string({ required_error: 'Title cannot be empty' })
.min(1, { message: 'Title cannot be empty' })
.max(100, { message: 'Title is too long. Keep it simple and concise bruv!' })
.string({ required_error: "Title cannot be empty" })
.min(1, { message: "Title cannot be empty" })
.max(100, {
message: "Title is too long. Keep it simple and concise bruv!",
})
.trim(),
rules: z
.string()
.trim(),
results: z
.string()
.trim(),
liveResults: z
.string()
.trim(),
user: z.string({ required_error: 'User is required.' }),
rules: z.string().trim(),
results: z.string().trim(),
liveResults: z.string().trim(),
user: z.string({ required_error: "User is required." }),
});
export const createPortfolioSchema = z.object({
accountValue: z
.string()
.trim(),
availableCash: z
.string()
.trim(),
overallReturn: z
.string()
.trim(),
rank: z
.string()
.trim(),
holdings: z
.string()
.trim(),
tradingHistory: z
.string()
.trim(),
metrics: z
.string()
.trim(),
user: z.string({ required_error: 'User is required.' }),
accountValue: z.string().trim(),
availableCash: z.string().trim(),
overallReturn: z.string().trim(),
rank: z.string().trim(),
holdings: z.string().trim(),
tradingHistory: z.string().trim(),
metrics: z.string().trim(),
user: z.string({ required_error: "User is required." }),
});
export const createWatchListSchema = z.object({
title: z
.string({ required_error: 'Title cannot be empty' })
.min(1, { message: 'Title cannot be empty' })
.max(100, { message: 'Title is too long. Keep it simple and concise bruv!' })
.string({ required_error: "Title cannot be empty" })
.min(1, { message: "Title cannot be empty" })
.max(100, {
message: "Title is too long. Keep it simple and concise bruv!",
})
.trim(),
ticker: z
.string()
.trim(),
user: z.string({ required_error: 'User is required.' }),
ticker: z.string().trim(),
user: z.string({ required_error: "User is required." }),
});
export const editWatchListSchema = z.object({
title: z
.string({ required_error: 'Title cannot be empty' })
.min(1, { message: 'Title cannot be empty' })
.max(100, { message: 'Title is too long. Keep it simple and concise bruv!' })
.string({ required_error: "Title cannot be empty" })
.min(1, { message: "Title cannot be empty" })
.max(100, {
message: "Title is too long. Keep it simple and concise bruv!",
})
.trim(),
watchListId: z.string({ required_error: 'Id is required.' }),
watchListId: z.string({ required_error: "Id is required." }),
});

View File

@ -4,8 +4,11 @@ function generateDateList(val) {
var dateList = [];
dateList.push(formatDate(currentDate)); // Add current date to the list
for (var i = 1; i <= val; i++) { // Generate 10 more dates, 30 days apart
var previousDate = new Date(currentDate.getTime() - (i * 1 * 24 * 60 * 60 * 1000)); // Calculate the previous date
for (var i = 1; i <= val; i++) {
// Generate 10 more dates, 30 days apart
var previousDate = new Date(
currentDate.getTime() - i * 1 * 24 * 60 * 60 * 1000,
); // Calculate the previous date
dateList.unshift(formatDate(previousDate)); // Add the previous date to the beginning of the list
}
@ -14,15 +17,14 @@ function generateDateList(val) {
function formatDate(date) {
var year = date.getFullYear();
var month = ('0' + (date.getMonth() + 1)).slice(-2); // Month is zero-based, so we add 1
var day = ('0' + date.getDate()).slice(-2);
var month = ("0" + (date.getMonth() + 1)).slice(-2); // Month is zero-based, so we add 1
var day = ("0" + date.getDate()).slice(-2);
return year + '-' + month + '-' + day;
return year + "-" + month + "-" + day;
}
var dateList = generateDateList(30);
function generateRandomNumberList() {
var numberList = [];
@ -46,50 +48,48 @@ function generateRandomNumberList() {
return numberList;
}
var rsiList = generateRandomNumberList();
export const rsiGraph = {
xAxis: {
type: 'category',
data: dateList
type: "category",
data: dateList,
},
yAxis: {
type: 'value'
type: "value",
},
series: [
{
data: rsiList,
type: 'line',
symbol: 'none', // Remove the dots
type: "line",
symbol: "none", // Remove the dots
lineStyle: {
type: 'solid', // Make the line solid
color: '#FFF' // Red color for the line
}
type: "solid", // Make the line solid
color: "#FFF", // Red color for the line
},
},
{
type: 'line',
symbol: 'none', // Remove the dots
type: "line",
symbol: "none", // Remove the dots
data: Array(30).fill(30),
lineStyle: {
type: 'solid', // Make the line solid
color: '#0BA111', // Red color for the line
type: "solid", // Make the line solid
color: "#0BA111", // Red color for the line
width: 4,
}
},
},
{
type: 'line',
symbol: 'none', // Remove the dots
type: "line",
symbol: "none", // Remove the dots
data: Array(30).fill(70),
lineStyle: {
type: 'solid', // Make the line solid
color: '#FF0000', // Red color for the line
type: "solid", // Make the line solid
color: "#FF0000", // Red color for the line
width: 4,
}
}
]
},
},
],
};
//MACD Indicator
var macdList = generateTrigonometricNumberList(1);
var macdLineList = generateTrigonometricNumberList(1.5);
@ -97,69 +97,65 @@ var macdLineList = generateTrigonometricNumberList(1.5);
var macdDateList = generateDateList(100);
export const macdGraph = {
xAxis: {
type: 'category',
data: macdDateList
type: "category",
data: macdDateList,
},
yAxis: {
type: 'value'
type: "value",
},
series: [
{
data: macdList,
type: 'line',
symbol: 'none', // Remove the dots
type: "line",
symbol: "none", // Remove the dots
lineStyle: {
type: 'solid', // Make the line solid
color: '#0BA111' // Red color for the line
}
type: "solid", // Make the line solid
color: "#0BA111", // Red color for the line
},
},
{
data: macdLineList,
type: 'line',
symbol: 'none', // Remove the dots
type: "line",
symbol: "none", // Remove the dots
lineStyle: {
type: 'solid', // Make the line solid
color: '#FF0000' // Red color for the line
}
type: "solid", // Make the line solid
color: "#FF0000", // Red color for the line
},
]
},
],
};
//MACD Indicator
var sma50List = generateTrigonometricNumberList(100);
var sma200List = generateTrigonometricNumberList(120);
var smaDateList = generateDateList(100);
export const smaGraph = {
xAxis: {
type: 'category',
data: smaDateList
type: "category",
data: smaDateList,
},
yAxis: {
type: 'value'
type: "value",
},
series: [
{
data: sma50List,
type: 'line',
symbol: 'none', // Remove the dots
type: "line",
symbol: "none", // Remove the dots
lineStyle: {
type: 'solid', // Make the line solid
color: '#0BA111' // Red color for the line
}
type: "solid", // Make the line solid
color: "#0BA111", // Red color for the line
},
},
{
data: sma200List,
type: 'line',
symbol: 'none', // Remove the dots
type: "line",
symbol: "none", // Remove the dots
lineStyle: {
type: 'solid', // Make the line solid
color: '#FF0000' // Red color for the line
}
type: "solid", // Make the line solid
color: "#FF0000", // Red color for the line
},
]
},
],
};

View File

@ -20,7 +20,7 @@ type FlyAndScaleParams = {
export const flyAndScale = (
node: Element,
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 0 }
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 0 },
): TransitionConfig => {
const style = getComputedStyle(node);
const transform = style.transform === "none" ? "" : style.transform;
@ -28,7 +28,7 @@ export const flyAndScale = (
const scaleConversion = (
valueA: number,
scaleA: [number, number],
scaleB: [number, number]
scaleB: [number, number],
) => {
const [minA, maxA] = scaleA;
const [minB, maxB] = scaleB;
@ -40,7 +40,7 @@ export const flyAndScale = (
};
const styleToString = (
style: Record<string, number | string | undefined>
style: Record<string, number | string | undefined>,
): string => {
return Object.keys(style).reduce((str, key) => {
if (style[key] === undefined) return str;
@ -212,7 +212,7 @@ export function sumQuarterlyResultsByYear(quarterlyResults, namingList) {
// Filter out years with less than 4 quarters
const validYears = Object?.keys(quarterCounts)?.filter(
(year) => quarterCounts[year] === 4
(year) => quarterCounts[year] === 4,
);
const annualResults = validYears?.map((year) => yearlySummaries[year]);
@ -420,7 +420,7 @@ export function formatETFName(inputString) {
// Capitalize the first letter of each word
const capitalizedWords = words?.map(
(word) => word.charAt(0)?.toUpperCase() + word?.slice(1)
(word) => word.charAt(0)?.toUpperCase() + word?.slice(1),
);
// Join the words back together with a space between them
@ -442,7 +442,7 @@ export function addDays(data, days, state) {
} else {
const differenceInTime = result - createdDate;
const differenceInDays = Math.round(
differenceInTime / (1000 * 60 * 60 * 24)
differenceInTime / (1000 * 60 * 60 * 24),
);
return Math.abs(differenceInDays);
}

View File

@ -1,19 +1,18 @@
// lib/workers/test.ts
async function loadNotifications(fastifyURL: string, userId: string) {
const postData = { userId: userId };
const postData = {'userId': userId};
const response = await fetch(fastifyURL+'/get-notifications', {
method: 'POST',
const response = await fetch(fastifyURL + "/get-notifications", {
method: "POST",
headers: {
"Content-Type": "application/json"
"Content-Type": "application/json",
},
body: JSON.stringify(postData)
body: JSON.stringify(postData),
});
const output = (await response.json())?.items;
return output
return output;
}
onmessage = async (event: MessageEvent) => {
@ -21,18 +20,21 @@ async function loadNotifications(fastifyURL:string, userId:string) {
const fastifyURL = data?.fastifyURL;
const userId = data?.userId;
try {
const [notificationList] = await Promise.all([
loadNotifications(fastifyURL, userId),
]);
const numberOfUnreadNotification = notificationList?.length
const numberOfUnreadNotification = notificationList?.length;
const hasUnreadElement = notificationList?.length !== 0 ? true : false;
const output = {notificationList, hasUnreadElement, numberOfUnreadNotification}
const output = {
notificationList,
hasUnreadElement,
numberOfUnreadNotification,
};
postMessage({ message: 'success', output});
postMessage({ message: "success", output });
} catch (e) {
postMessage({ message: 'error', e});
postMessage({ message: "error", e });
}
// Sending data back to the main thread
//postMessage({ message: 'Data received in the worker', ticker, apiURL });

View File

@ -1,9 +1,10 @@
async function loadTwitchStatus(fastifyURL:string,) {
async function loadTwitchStatus(fastifyURL: string) {
// make the GET request to the endpoint
const response = await fetch(fastifyURL+'/get-twitch-status', {
method: 'GET',
const response = await fetch(fastifyURL + "/get-twitch-status", {
method: "GET",
headers: {
"Content-Type": "application/json","X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
});
@ -11,19 +12,16 @@ async function loadTwitchStatus(fastifyURL:string,) {
return output;
}
onmessage = async (event: MessageEvent) => {
const data = event.data?.message;
const fastifyURL = data?.fastifyURL;
try {
const twitchStatus = await loadTwitchStatus(fastifyURL);
const output = { twitchStatus };
postMessage({ message: 'success', output});
postMessage({ message: "success", output });
} catch (e) {
postMessage({ message: 'error', e});
postMessage({ message: "error", e });
}
// Sending data back to the main thread
//postMessage({ message: 'Data received in the worker', ticker, apiURL });

View File

@ -4,7 +4,7 @@ export const load = ({ locals, cookies }) => {
return {
user: user || undefined,
region,
cookieConsent: cookies?.get('cookie-consent'),
cookieConsent: cookies?.get("cookie-consent"),
apiURL,
fastifyURL,
wsURL,

View File

@ -18,7 +18,7 @@ export const actions = {
login: async ({ request, locals }) => {
const { formData, errors } = await validateData(
await request.formData(),
loginUserSchema
loginUserSchema,
);
if (errors) {
@ -52,7 +52,7 @@ export const actions = {
register: async ({ locals, request }) => {
const { formData, errors } = await validateData(
await request.formData(),
registerUserSchema
registerUserSchema,
);
if (errors) {
return fail(400, {
@ -122,7 +122,7 @@ export const actions = {
const redirectURL = `${url.origin}/oauth`;
const targetItem = authMethods.authProviders?.findIndex(
(item) => item?.name === providerSelected
(item) => item?.name === providerSelected,
);
//console.log("==================")
//console.log(authMethods.authProviders)

View File

@ -18,7 +18,7 @@ export const load = async ({ parent }) => {
headers: {
"Content-Type": "application/json",
},
}
},
);
output = (await response.json())["stargazers_count"];
@ -43,7 +43,7 @@ export const load = async ({ parent }) => {
headers: {
"Content-Type": "application/json",
},
}
},
);
output = (await response.json())["stargazers_count"];

View File

@ -1,32 +1,31 @@
import { getCache, setCache } from '$lib/store';
import { getCache, setCache } from "$lib/store";
export const load = async ({ parent, params }) => {
const getAnalystStats = async () => {
let output;
// Get cached data for the specific tickerID
const cachedData = getCache(params.slug, 'getAnalystStats');
const cachedData = getCache(params.slug, "getAnalystStats");
if (cachedData) {
output = cachedData;
} else {
const { apiURL, apiKey } = await parent();
const postData = {'analystId': params.slug}
const postData = { analystId: params.slug };
// make the POST request to the endpoint
const response = await fetch(apiURL + '/analyst-stats', {
method: 'POST',
const response = await fetch(apiURL + "/analyst-stats", {
method: "POST",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify(postData)
body: JSON.stringify(postData),
});
output = await response.json();
// Cache the data for this specific tickerID with a specific name 'getAnalystStats'
setCache(params.slug, output, 'getAnalystStats');
setCache(params.slug, output, "getAnalystStats");
}
return output;
@ -34,6 +33,6 @@ export const load = async ({parent, params}) => {
// Make sure to return a promise
return {
getAnalystStats: await getAnalystStats()
getAnalystStats: await getAnalystStats(),
};
};

View File

@ -1,69 +1,66 @@
import type { RequestHandler } from './$types';
import type { RequestHandler } from "./$types";
function secondsUntilEndOfDay() {
const now = new Date();
const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
const endOfDay = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate() + 1,
);
const secondsUntilEndOfDay = (endOfDay - now) / 1000;
return secondsUntilEndOfDay;
}
export const POST = (async ({ request, cookies, locals }) => {
let output = 'error';
const data = await request.json()
let output = "error";
const data = await request.json();
const sentiment = data?.sentiment;
const ticker = data?.ticker
const ticker = data?.ticker;
const sentimentId = data?.sentimentId;
const maxAge = secondsUntilEndOfDay();
let newData;
if (cookies?.get('community-sentiment-'+ticker)) {
if (cookies?.get("community-sentiment-" + ticker)) {
//console.log('already voted')
return new Response(JSON.stringify(output))
}
else {
return new Response(JSON.stringify(output));
} else {
try {
if (sentimentId) {
if (sentiment === 'upvote') {
await locals?.pb?.collection('sentiment').update( sentimentId, {'upvote+': 1})
if (sentiment === "upvote") {
await locals?.pb
?.collection("sentiment")
.update(sentimentId, { "upvote+": 1 });
} else if (sentiment === "downvote") {
await locals?.pb
?.collection("sentiment")
.update(sentimentId, { "downvote+": 1 });
}
else if (sentiment === 'downvote') {
await locals?.pb?.collection('sentiment').update( sentimentId, {'downvote+': 1})
} else {
if (sentiment === "upvote") {
newData = await locals?.pb
?.collection("sentiment")
.create({ ticker: ticker, upvote: 1 });
} else if (sentiment === "downvote") {
newData = await locals?.pb
?.collection("sentiment")
.create({ ticker: ticker, downvote: 1 });
}
}
else {
output = "success";
if (sentiment === 'upvote') {
newData = await locals?.pb?.collection('sentiment').create({'ticker': ticker, 'upvote': 1})
}
else if (sentiment === 'downvote') {
newData = await locals?.pb?.collection('sentiment').create({'ticker': ticker, 'downvote': 1})
}
}
output = 'success';
cookies.set('community-sentiment-'+ticker, sentiment, {httpOnly: true,
sameSite: 'lax',
cookies.set("community-sentiment-" + ticker, sentiment, {
httpOnly: true,
sameSite: "lax",
secure: true,
path: '/',
maxAge: maxAge // End of day expiry
path: "/",
maxAge: maxAge, // End of day expiry
});
} catch (e) {
console.log(e);
}
}
return new Response(JSON.stringify(output))
return new Response(JSON.stringify(output));
}) satisfies RequestHandler;

View File

@ -1,27 +1,22 @@
import type { RequestHandler } from './$types';
import type { RequestHandler } from "./$types";
export const POST = (async ({ request, cookies }) => {
let output = 'error';
const data = await request.json()
let output = "error";
const data = await request.json();
const consent = data?.consent;
try {
cookies.set('cookie-consent', consent, {httpOnly: true,
sameSite: 'lax',
cookies.set("cookie-consent", consent, {
httpOnly: true,
sameSite: "lax",
secure: true,
path: '/',
maxAge: 60*60*24*365 // 1 Year consent
path: "/",
maxAge: 60 * 60 * 24 * 365, // 1 Year consent
});
output = 'success';
output = "success";
} catch (e) {
console.log(e);
}
return new Response(JSON.stringify(output))
return new Response(JSON.stringify(output));
}) satisfies RequestHandler;

View File

@ -1,12 +1,14 @@
import type { RequestHandler } from './$types';
import { serialize } from 'object-to-formdata';
import { validateData } from '$lib/utils';
import { createCommentTextSchema, createCommentImageSchema } from '$lib/schemas';
import { error} from '@sveltejs/kit';
import type { RequestHandler } from "./$types";
import { serialize } from "object-to-formdata";
import { validateData } from "$lib/utils";
import {
createCommentTextSchema,
createCommentImageSchema,
} from "$lib/schemas";
import { error } from "@sveltejs/kit";
//import sharp from 'sharp';
//import { marked } from 'marked';
/*
export const config = {
runtime: 'nodejs20.x',
@ -75,33 +77,32 @@ function addClassesToHtml(htmlString) {
*/
export const POST = (async ({ request, locals }) => {
let output = 'error';
let output = "error";
const body = await request.formData();
if (body?.get('comment') === 'undefined')
{
body?.delete('comment');
body?.append('comment', '');
if (body?.get("comment") === "undefined") {
body?.delete("comment");
body?.append("comment", "");
}
if (body?.get('reply') === null)
{
body?.delete('reply');
body?.append('reply', '');
if (body?.get("reply") === null) {
body?.delete("reply");
body?.append("reply", "");
}
const {formData, errors} = await validateData( body, body?.get('image')?.length === 0 ? createCommentTextSchema : createCommentImageSchema);
const { formData, errors } = await validateData(
body,
body?.get("image")?.length === 0
? createCommentTextSchema
: createCommentImageSchema,
);
if (errors) {
return new Response(JSON.stringify(output));
}
//formData.comment = addClassesToHtml(marked(formData?.comment))
/*
if (formData?.image?.type?.includes('image'))
{
@ -140,59 +141,49 @@ const body = await request.formData();
await locals.pb.collection("users").update(locals?.user?.id, {
"karma+": 1,
})
});
let newComment;
try {
newComment = await locals.pb.collection('comments').create(serialize(formData), {
expand: 'user,alreadyVoted(comment)',
fields: "*,expand.user,expand.alreadyVoted(comment).user,expand.alreadyVoted(comment).type",
newComment = await locals.pb
.collection("comments")
.create(serialize(formData), {
expand: "user,alreadyVoted(comment)",
fields:
"*,expand.user,expand.alreadyVoted(comment).user,expand.alreadyVoted(comment).type",
});
let postId = formData.post
const opPost = await locals.pb.collection('posts').getOne(postId)
let postId = formData.post;
const opPost = await locals.pb.collection("posts").getOne(postId);
//create new record for notifications collections
if (locals?.user?.id !== opPost?.user)
{
if (locals?.user?.id !== opPost?.user) {
let formDataNotifications = new FormData();
formDataNotifications.append('opUser', opPost?.user);
formDataNotifications.append('user', formData?.user)
formDataNotifications.append('post', postId);
formDataNotifications.append('comment', newComment?.id)
formDataNotifications.append('notifyType', 'comment');
await locals.pb.collection('notifications').create(formDataNotifications);
formDataNotifications.append("opUser", opPost?.user);
formDataNotifications.append("user", formData?.user);
formDataNotifications.append("post", postId);
formDataNotifications.append("comment", newComment?.id);
formDataNotifications.append("notifyType", "comment");
await locals.pb.collection("notifications").create(formDataNotifications);
}
let formDataAlreadyVoted = new FormData();
formDataAlreadyVoted.append('comment', newComment?.id);
formDataAlreadyVoted.append('user', newComment?.user);
formDataAlreadyVoted.append('type', 'upvote');
formDataAlreadyVoted.append("comment", newComment?.id);
formDataAlreadyVoted.append("user", newComment?.user);
formDataAlreadyVoted.append("type", "upvote");
//console.log(formDataAlreadyVoted)
await locals.pb.collection('alreadyVoted').create(formDataAlreadyVoted);
await locals.pb.collection("alreadyVoted").create(formDataAlreadyVoted);
//User always upvotes their comment in the intial state
await locals.pb.collection("comments").update(newComment?.id, {
"upvote+": 1,
})
output = 'success';
});
output = "success";
} catch (err) {
console.log('Error: ', err);
console.log("Error: ", err);
error(err.status, err.message);
}
return new Response(JSON.stringify([output, newComment]));
}) satisfies RequestHandler;

View File

@ -1,50 +1,47 @@
import type { RequestHandler } from './$types';
import { serialize } from 'object-to-formdata';
import { validateData } from '$lib/utils';
import { updateCommentTextSchema} from '$lib/schemas';
import { error} from '@sveltejs/kit';
import type { RequestHandler } from "./$types";
import { serialize } from "object-to-formdata";
import { validateData } from "$lib/utils";
import { updateCommentTextSchema } from "$lib/schemas";
import { error } from "@sveltejs/kit";
export const POST = (async ({ request, locals }) => {
let output = 'error';
let output = "error";
const body = await request.formData();
const commentId = body?.get('commentId');
const commentId = body?.get("commentId");
if (body?.get('comment') === 'undefined')
{
body?.delete('comment');
body?.append('comment', '');
if (body?.get("comment") === "undefined") {
body?.delete("comment");
body?.append("comment", "");
}
const {formData, errors} = await validateData( body, updateCommentTextSchema);
console.log(error)
const { formData, errors } = await validateData(
body,
updateCommentTextSchema,
);
console.log(error);
if (errors) {
return new Response(JSON.stringify(output));
}
let updateComment;
try {
updateComment = await locals.pb
.collection("comments")
.update(commentId, serialize(formData));
updateComment = await locals.pb.collection('comments').update(commentId,serialize(formData));
updateComment = await locals.pb.collection('comments').getOne(commentId, {
expand: 'user,alreadyVoted(comment)',
fields: "*,expand.user,expand.alreadyVoted(comment).user,expand.alreadyVoted(comment).type",
updateComment = await locals.pb.collection("comments").getOne(commentId, {
expand: "user,alreadyVoted(comment)",
fields:
"*,expand.user,expand.alreadyVoted(comment).user,expand.alreadyVoted(comment).type",
});
output = 'success';
output = "success";
} catch (err) {
console.log('Error: ', err);
console.log("Error: ", err);
error(err.status, err.message);
}
return new Response(JSON.stringify([output, updateComment]));
}) satisfies RequestHandler;

View File

@ -1,29 +1,35 @@
import { promises as fsPromises } from 'fs';
import fs from 'fs';
import fetch from 'node-fetch';
import type { RequestHandler } from '@sveltejs/kit';
import { promises as fsPromises } from "fs";
import fs from "fs";
import fetch from "node-fetch";
import type { RequestHandler } from "@sveltejs/kit";
const CHUNK_SIZE = 1 * 1024 * 1024; // 1MB in bytes
const parseRange = (range: string) => {
const [start, end] = range.replace(/bytes=/, '').split('-').map(Number);
const [start, end] = range
.replace(/bytes=/, "")
.split("-")
.map(Number);
return { start, end: end || undefined };
};
const createResponse = (body: ReadableStream | Buffer, headers: Record<string, string>, status = 206) =>
new Response(body, { status, headers });
const createResponse = (
body: ReadableStream | Buffer,
headers: Record<string, string>,
status = 206,
) => new Response(body, { status, headers });
const streamRemoteFile = async (url: string, range: string) => {
const { start, end } = parseRange(range);
const response = await fetch(url, {
headers: { Range: `bytes=${start}-${end || ''}` }
headers: { Range: `bytes=${start}-${end || ""}` },
});
return createResponse(response.body, {
'Content-Range': response.headers.get('Content-Range') || '',
'Accept-Ranges': 'bytes',
'Content-Length': response.headers.get('Content-Length') || '',
'Content-Type': response.headers.get('Content-Type') || '',
"Content-Range": response.headers.get("Content-Range") || "",
"Accept-Ranges": "bytes",
"Content-Length": response.headers.get("Content-Length") || "",
"Content-Type": response.headers.get("Content-Type") || "",
});
};
@ -33,37 +39,44 @@ const streamLocalFile = async (filePath: string, range: string) => {
const chunkEnd = end || Math.min(start + CHUNK_SIZE - 1, fileSize - 1);
if (start >= fileSize) {
return new Response(`Requested range not satisfiable\n${start} >= ${fileSize}`, {
return new Response(
`Requested range not satisfiable\n${start} >= ${fileSize}`,
{
status: 416,
headers: { 'Content-Range': `bytes */${fileSize}` },
});
headers: { "Content-Range": `bytes */${fileSize}` },
},
);
}
const stream = fs.createReadStream(filePath, { start, end: chunkEnd });
return createResponse(stream, {
'Content-Range': `bytes ${start}-${chunkEnd}/${fileSize}`,
'Accept-Ranges': 'bytes',
'Content-Length': (chunkEnd - start + 1).toString(),
'Content-Type': 'video/mp4',
"Content-Range": `bytes ${start}-${chunkEnd}/${fileSize}`,
"Accept-Ranges": "bytes",
"Content-Length": (chunkEnd - start + 1).toString(),
"Content-Type": "video/mp4",
});
};
export const GET: RequestHandler = async ({ params, request }) => {
const { filename } = params;
const range = request.headers.get('range');
const range = request.headers.get("range");
if (!range) {
return new Response('Requires Range header', { status: 400 });
return new Response("Requires Range header", { status: 400 });
}
try {
const videoPath = filename.startsWith('http') ? filename : `static/${filename}`;
return filename.startsWith('http') ?
await streamRemoteFile(videoPath, range) :
await streamLocalFile(videoPath, range);
const videoPath = filename.startsWith("http")
? filename
: `static/${filename}`;
return filename.startsWith("http")
? await streamRemoteFile(videoPath, range)
: await streamLocalFile(videoPath, range);
} catch (error) {
console.error('Error streaming video:', error);
return new Response('File not found or error streaming video', { status: 404 });
console.error("Error streaming video:", error);
return new Response("File not found or error streaming video", {
status: 404,
});
}
};

View File

@ -1,25 +1,23 @@
import { pb } from "$lib/pocketbase";
import { getCache, setCache } from '$lib/store';
import { getCache, setCache } from "$lib/store";
export const load = async ({ parent }) => {
const getAllBlogPost = async () => {
let output;
console.log(await parent())
console.log(await parent());
// Get cached data for the specific tickerID
const cachedData = getCache('allBlogPost', 'getAllBlogPost');
const cachedData = getCache("allBlogPost", "getAllBlogPost");
if (cachedData) {
output = cachedData;
} else {
// make the POST request to the endpoint
output = await pb.collection('articles').getFullList({
expand: 'user',
sort: '-created'
})
output = await pb.collection("articles").getFullList({
expand: "user",
sort: "-created",
});
// Cache the data for this specific tickerID with a specific name 'getAllBlogPost'
setCache('allBlogPost', output, 'getAllBlogPost');
setCache("allBlogPost", output, "getAllBlogPost");
}
return output;
@ -27,6 +25,6 @@ export const load = async ({parent}) => {
// Make sure to return a promise
return {
getAllBlogPost: await getAllBlogPost()
getAllBlogPost: await getAllBlogPost(),
};
};

View File

@ -1,22 +1,22 @@
import { pb } from "$lib/pocketbase";
import { getCache, setCache } from '$lib/store';
import { getCache, setCache } from "$lib/store";
export const load = async ({ params }) => {
const getArticle = async () => {
let output;
// Get cached data for the specific tickerID
const cachedData = getCache(params?.slug, 'getArticle');
const cachedData = getCache(params?.slug, "getArticle");
if (cachedData) {
output = cachedData;
} else {
// make the POST request to the endpoint
output = await pb?.collection('articles')?.getOne(params?.slug, {expand: 'user'})
output = await pb
?.collection("articles")
?.getOne(params?.slug, { expand: "user" });
// Cache the data for this specific tickerID with a specific name 'getArticle'
setCache(params?.slug, output, 'getArticle');
setCache(params?.slug, output, "getArticle");
}
return output;
@ -47,7 +47,6 @@ const getDiscordWidget = async () => {
};
*/
// Make sure to return a promise
return {
getArticle: await getArticle(),

View File

@ -6,7 +6,7 @@ export const actions = {
login: async ({ request, locals }) => {
const { formData, errors } = await validateData(
await request.formData(),
loginUserSchema
loginUserSchema,
);
if (errors) {
@ -40,7 +40,7 @@ export const actions = {
register: async ({ locals, request }) => {
const { formData, errors } = await validateData(
await request.formData(),
registerUserSchema
registerUserSchema,
);
if (errors) {
@ -94,7 +94,7 @@ await locals.pb?.collection('users').update(
const redirectURL = `${url.origin}/oauth`;
const targetItem = authMethods.authProviders?.findIndex(
(item) => item?.name === providerSelected
(item) => item?.name === providerSelected,
);
//console.log("==================")
//console.log(authMethods.authProviders)

View File

@ -17,7 +17,7 @@ function removeDuplicateClasses(str) {
return str.replace(
/class="([^"]*)"/,
(match, classAttr) =>
`class="${[...new Set(classAttr.split(" "))].join(" ")}"`
`class="${[...new Set(classAttr.split(" "))].join(" ")}"`,
);
}
@ -31,7 +31,7 @@ function addClassesToHtml(htmlString) {
// Append the new class to tags that already have a class attribute, ensuring no duplicates
const regexWithClass = new RegExp(
`(<${tag}[^>]*\\bclass=["'][^"']*)(?!.*\\b${className}\\b)([^"']*)["']`,
"g"
"g",
);
htmlString = htmlString.replace(regexWithClass, `$1 ${className}$2"`);
}
@ -58,13 +58,13 @@ function addClassesToHtml(htmlString) {
// Add class to blockquote
htmlString = htmlString.replace(
/<blockquote/g,
'<blockquote class="pl-4 pr-4 rounded-lg bg-[#323232]"'
'<blockquote class="pl-4 pr-4 rounded-lg bg-[#323232]"',
);
// Add class to p inside blockquote
htmlString = htmlString.replace(
/<blockquote([^>]*)>\s*<p/g,
`<blockquote$1>\n<p class="text-sm font-medium leading-relaxed text-white"`
`<blockquote$1>\n<p class="text-sm font-medium leading-relaxed text-white"`,
);
}

View File

@ -6,7 +6,7 @@ export const actions = {
login: async ({ request, locals }) => {
const { formData, errors } = await validateData(
await request.formData(),
loginUserSchema
loginUserSchema,
);
if (errors) {
@ -40,7 +40,7 @@ export const actions = {
register: async ({ locals, request }) => {
const { formData, errors } = await validateData(
await request.formData(),
registerUserSchema
registerUserSchema,
);
if (errors) {
@ -94,7 +94,7 @@ await locals.pb?.collection('users').update(
const redirectURL = `${url.origin}/oauth`;
const targetItem = authMethods.authProviders?.findIndex(
(item) => item?.name === providerSelected
(item) => item?.name === providerSelected,
);
//console.log("==================")
//console.log(authMethods.authProviders)

View File

@ -1,17 +1,15 @@
import { cachedPosts } from '$lib/store';
import { cachedPosts } from "$lib/store";
import { get } from 'svelte/store';
import { get } from "svelte/store";
export const load = async ({ parent, params }) => {
async function getOnePost() {
// Get the current value of cachedPosts
const cachedValue = get(cachedPosts);
// Try to find the post in the cached value
const output = cachedValue?.posts?.find(item => item?.id === params.postId) ?? {};
const output =
cachedValue?.posts?.find((item) => item?.id === params.postId) ?? {};
// If the post is found in the cache, return it
if (Object.keys(output).length !== 0) {
@ -22,10 +20,10 @@ export const load = async ({ parent, params }) => {
// If the post is not found in the cache, fetch it from the endpoint
const postData = { postId: params.postId };
const response = await fetch(fastifyURL + '/get-one-post', {
method: 'POST',
const response = await fetch(fastifyURL + "/get-one-post", {
method: "POST",
headers: {
"Content-Type": "application/json"
"Content-Type": "application/json",
},
body: JSON.stringify(postData),
});
@ -37,15 +35,11 @@ export const load = async ({ parent, params }) => {
}
const getPostId = async () => {
return params.postId;
};
return {
getPostId: await getPostId(),
getOnePost: await getOnePost(),
};
};

View File

@ -1,118 +1,105 @@
import { redirect, error} from '@sveltejs/kit';
import { redirect, error } from "@sveltejs/kit";
export const load = async ({ locals }) => {
if (!locals.pb.authStore.isValid) {
redirect(303, '/login');
redirect(303, "/login");
}
const getSubscriptionData = async () => {
const output = (await locals.pb.collection('payments').getFullList({
const output =
(
await locals.pb.collection("payments").getFullList({
filter: `user="${locals.user.id}" `,
sort: '-created',
}))?.at(0)?.data?.data?.attributes ?? {} ;
sort: "-created",
})
)?.at(0)?.data?.data?.attributes ?? {};
//console.log(output)
return output;
};
return {
getSubscriptionData: await getSubscriptionData()
getSubscriptionData: await getSubscriptionData(),
};
};
export const actions = {
cancelSubscription: async ({ request, locals }) => {
const formData = await request?.formData();
const apiKey = import.meta.env.VITE_LEMON_SQUEEZY_API_KEY;
const subscriptionId = formData?.get('subscriptionId');
const subscriptionId = formData?.get("subscriptionId");
try {
const url = `https://api.lemonsqueezy.com/v1/subscriptions/${subscriptionId}`;
const headers = {
'Accept': 'application/vnd.api+json',
'Content-Type': 'application/vnd.api+json',
'Authorization': `Bearer ${apiKey}`
Accept: "application/vnd.api+json",
"Content-Type": "application/vnd.api+json",
Authorization: `Bearer ${apiKey}`,
};
const response = await fetch(url, {
method: 'DELETE',
headers: headers
method: "DELETE",
headers: headers,
});
} catch (err) {
console.log("Error: ", err);
error(err.status, err.message);
}
redirect(302, '/community/profile');
redirect(302, "/community/profile");
},
reactivateSubscription: async ({ request, locals }) => {
const formData = await request?.formData();
const apiKey = import.meta.env.VITE_LEMON_SQUEEZY_API_KEY;
const subscriptionId = formData?.get('subscriptionId');
const subscriptionId = formData?.get("subscriptionId");
try {
const url = `https://api.lemonsqueezy.com/v1/subscriptions/${subscriptionId}`;
const headers = {
'Accept': 'application/vnd.api+json',
'Content-Type': 'application/vnd.api+json',
'Authorization': `Bearer ${apiKey}`
Accept: "application/vnd.api+json",
"Content-Type": "application/vnd.api+json",
Authorization: `Bearer ${apiKey}`,
};
const payload = {
data: {
type: 'subscriptions',
type: "subscriptions",
id: `${subscriptionId}`,
attributes: {
cancelled: false
}
}
cancelled: false,
},
},
};
const response = await fetch(url, {
method: 'PATCH',
method: "PATCH",
headers: headers,
body: JSON.stringify(payload)
body: JSON.stringify(payload),
});
} catch (err) {
console.log("Error: ", err);
error(err.status, err.message);
}
redirect(302, '/community/profile');
redirect(302, "/community/profile");
},
changeSubscription: async ({ request, locals }) => {
const formData = await request?.formData();
const apiKey = import.meta.env.VITE_LEMON_SQUEEZY_API_KEY;
const subscriptionId = formData?.get('subscriptionId');
const subscriptionId = formData?.get("subscriptionId");
try {
const url = `https://api.lemonsqueezy.com/v1/subscriptions/${subscriptionId}`;
const headers = {
'Accept': 'application/vnd.api+json',
'Content-Type': 'application/vnd.api+json',
'Authorization': `Bearer ${apiKey}`
Accept: "application/vnd.api+json",
"Content-Type": "application/vnd.api+json",
Authorization: `Bearer ${apiKey}`,
};
// Create the data payload
@ -121,30 +108,23 @@ export const actions = {
type: "subscriptions",
id: subscriptionId,
attributes: {
variant_id: import.meta.env.VITE_LEMON_SQUEEZY_ANNUAL_VARIANT_ID // Change from monthly to annually plan
}
}
variant_id: import.meta.env.VITE_LEMON_SQUEEZY_ANNUAL_VARIANT_ID, // Change from monthly to annually plan
},
},
};
const response = await fetch(url, {
method: 'PATCH',
method: "PATCH",
headers: headers,
body: JSON.stringify(payload)
body: JSON.stringify(payload),
});
console.log(await response.json())
console.log(await response.json());
} catch (err) {
console.log("Error: ", err);
error(err.status, err.message);
}
redirect(302, '/community/profile');
redirect(302, "/community/profile");
},
};

View File

@ -20,7 +20,7 @@ export const actions = {
login: async ({ request, locals }) => {
const { formData, errors } = await validateData(
await request.formData(),
loginUserSchema
loginUserSchema,
);
if (errors) {
@ -54,7 +54,7 @@ export const actions = {
register: async ({ locals, request }) => {
const { formData, errors } = await validateData(
await request.formData(),
registerUserSchema
registerUserSchema,
);
if (errors) {
@ -108,7 +108,7 @@ await locals.pb?.collection('users').update(
const redirectURL = `${url.origin}/oauth`;
const targetItem = authMethods.authProviders?.findIndex(
(item) => item?.name === providerSelected
(item) => item?.name === providerSelected,
);
//console.log("==================")
//console.log(authMethods.authProviders)

View File

@ -1,29 +1,29 @@
import { getCache, setCache } from '$lib/store';
import { getCache, setCache } from "$lib/store";
export const load = async ({ parent }) => {
const getCryptoList = async () => {
let output;
// Get cached data for the specific tickerID
const cachedData = getCache('', 'getCryptoList');
const cachedData = getCache("", "getCryptoList");
if (cachedData) {
output = cachedData;
} else {
const { apiKey, apiURL } = await parent();
const response = await fetch(apiURL + '/all-crypto-tickers', {
method: 'GET',
const response = await fetch(apiURL + "/all-crypto-tickers", {
method: "GET",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
});
output = (await response.json())?.sort((a, b) => b?.marketCap - a?.marketCap);
output = (await response.json())?.sort(
(a, b) => b?.marketCap - a?.marketCap,
);
// Cache the data for this specific tickerID with a specific name 'getCryptoList'
setCache('', output, 'getCryptoList');
setCache("", output, "getCryptoList");
}
return output;
@ -31,6 +31,6 @@ export const load = async ({parent}) => {
// Make sure to return a promise
return {
getCryptoList: await getCryptoList()
getCryptoList: await getCryptoList(),
};
};

View File

@ -1,11 +1,8 @@
import { displayCompanyName, cryptoTicker, assetType} from '$lib/store';
import { displayCompanyName, cryptoTicker, assetType } from "$lib/store";
export const load = async ({ params, data }) => {
cryptoTicker.update((value) => params.tickerID?.toUpperCase());
assetType.update((value) => "crypto");
cryptoTicker.update( value => params.tickerID?.toUpperCase());
assetType.update( value => 'crypto');
displayCompanyName.update(value => data?.companyName)
displayCompanyName.update((value) => data?.companyName);
};

View File

@ -6,7 +6,7 @@ export const actions = {
login: async ({ request, locals }) => {
const { formData, errors } = await validateData(
await request.formData(),
loginUserSchema
loginUserSchema,
);
if (errors) {
@ -40,7 +40,7 @@ export const actions = {
register: async ({ locals, request }) => {
const { formData, errors } = await validateData(
await request.formData(),
registerUserSchema
registerUserSchema,
);
if (errors) {
@ -94,7 +94,7 @@ await locals.pb?.collection('users').update(
const redirectURL = `${url.origin}/oauth`;
const targetItem = authMethods.authProviders?.findIndex(
(item) => item?.name === providerSelected
(item) => item?.name === providerSelected,
);
//console.log("==================")
//console.log(authMethods.authProviders)

View File

@ -1,48 +1,41 @@
import { getCache, setCache } from '$lib/store';
import { getCache, setCache } from "$lib/store";
export const load = async ({ parent, params }) => {
const getSenateTrading = async () => {
let output;
// Get cached data for the specific tickerID
const cachedData = getCache(params.tickerID, 'getSenateTrading');
const cachedData = getCache(params.tickerID, "getSenateTrading");
if (cachedData) {
output = cachedData;
} else {
const { apiKey, apiURL } = await parent();
const postData = {
ticker: params.tickerID
ticker: params.tickerID,
};
// make the POST request to the endpoint
const response = await fetch(apiURL + '/congress-trading-ticker', {
method: 'POST',
const response = await fetch(apiURL + "/congress-trading-ticker", {
method: "POST",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify(postData)
body: JSON.stringify(postData),
});
output = await response.json();
// Cache the data for this specific tickerID with a specific name 'getSenateTrading'
setCache(params.tickerID, output, 'getSenateTrading');
setCache(params.tickerID, output, "getSenateTrading");
}
return output;
};
// Make sure to return a promise
return {
getSenateTrading: await getSenateTrading()
getSenateTrading: await getSenateTrading(),
};
};

View File

@ -1,35 +1,34 @@
import { getCache, setCache } from '$lib/store';
import { getCache, setCache } from "$lib/store";
export const load = async ({ parent, params }) => {
const getStockNews = async () => {
let output;
// Get cached data for the specific tickerID
const cachedData = getCache(params.tickerID, 'getStockNews');
const cachedData = getCache(params.tickerID, "getStockNews");
if (cachedData) {
output = cachedData;
} else {
const { apiKey, apiURL } = await parent();
const postData = {
ticker: params.tickerID
ticker: params.tickerID,
};
// make the POST request to the endpoint
const response = await fetch(apiURL + '/stock-news', {
method: 'POST',
const response = await fetch(apiURL + "/stock-news", {
method: "POST",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify(postData)
body: JSON.stringify(postData),
});
output = await response.json();
// Cache the data for this specific tickerID with a specific name 'getStockNews'
setCache(params.tickerID, output, 'getStockNews');
setCache(params.tickerID, output, "getStockNews");
}
return output;
@ -37,6 +36,6 @@ export const load = async ({ parent, params }) => {
// Make sure to return a promise
return {
getStockNews: await getStockNews()
getStockNews: await getStockNews(),
};
};

View File

@ -1,45 +1,41 @@
import { getCache, setCache } from '$lib/store';
import { getCache, setCache } from "$lib/store";
export const load = async ({ parent, params }) => {
const getQuantStats = async () => {
let output;
// Get cached data for the specific tickerID
const cachedData = getCache(params.tickerID, 'getQuantStats');
const cachedData = getCache(params.tickerID, "getQuantStats");
if (cachedData) {
output = cachedData;
} else {
const { apiKey, apiURL } = await parent();
const postData = {
ticker: params.tickerID
ticker: params.tickerID,
};
// make the POST request to the endpoint
const response = await fetch(apiURL + '/get-quant-stats', {
method: 'POST',
const response = await fetch(apiURL + "/get-quant-stats", {
method: "POST",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify(postData)
body: JSON.stringify(postData),
});
output = await response.json();
// Cache the data for this specific tickerID with a specific name 'getQuantStats'
setCache(params.tickerID, output, 'getQuantStats');
setCache(params.tickerID, output, "getQuantStats");
}
console.log(output)
console.log(output);
return output;
};
// Make sure to return a promise
return {
getQuantStats: await getQuantStats()
getQuantStats: await getQuantStats(),
};
};

View File

@ -3,34 +3,38 @@
let apiKey = import.meta.env.VITE_STOCKNEAR_API_KEY;
async function getOneDayPrice(ticker: string, apiURL: string) {
let oneDayPrice = [];
try {
const postData = { ticker: ticker };
const response = await fetch(apiURL + '/one-day-price', {
method: 'POST',
const response = await fetch(apiURL + "/one-day-price", {
method: "POST",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify(postData)
body: JSON.stringify(postData),
});
oneDayPrice = await response.json();
oneDayPrice = oneDayPrice?.map(item => ({ time: Date.parse(item?.time), open: item?.open !== null ? item?.open : NaN, high: item?.high !== null ? item?.high : NaN, low: item?.low !== null ? item?.low : NaN, close: item?.close !== null ? item?.close : NaN}));
oneDayPrice = oneDayPrice?.map((item) => ({
time: Date.parse(item?.time),
open: item?.open !== null ? item?.open : NaN,
high: item?.high !== null ? item?.high : NaN,
low: item?.low !== null ? item?.low : NaN,
close: item?.close !== null ? item?.close : NaN,
}));
// Set worker status to finished and send chart data
return oneDayPrice
return oneDayPrice;
} catch (error) {
// Set worker status to idle and send error message
return oneDayPrice;
}
}
async function getHistoricalPrice(ticker: string, apiURL: string) {
let oneWeekPrice;
let oneMonthPrice;
let sixMonthPrice;
@ -39,41 +43,86 @@ async function getHistoricalPrice(ticker: string, apiURL:string) {
try {
const postData = { ticker: ticker };
const response = await fetch(apiURL + '/historical-price', {
method: 'POST',
const response = await fetch(apiURL + "/historical-price", {
method: "POST",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify(postData)
body: JSON.stringify(postData),
});
const pastPriceList = await response.json();
oneWeekPrice = pastPriceList['1W']?.map(({ time, open, high, low, close }) => ({ time: Date.parse(time), open, high, low, close }));
oneMonthPrice = pastPriceList['1M']?.map(({ time, open, high, low, close }) => ({ time: Date.parse(time), open, high, low, close }));
sixMonthPrice = pastPriceList['6M']?.map(({ time, open, high, low, close }) => ({ time: Date.parse(time), open, high, low, close }));
oneYearPrice = pastPriceList['1Y']?.map(({ time, open, high, low, close }) => ({ time: Date.parse(time), open, high, low, close }));
threeYearPrice = pastPriceList['MAX']?.map(({ time, open, high, low, close }) => ({ time: Date.parse(time), open, high, low, close }));
oneWeekPrice = pastPriceList["1W"]?.map(
({ time, open, high, low, close }) => ({
time: Date.parse(time),
open,
high,
low,
close,
}),
);
oneMonthPrice = pastPriceList["1M"]?.map(
({ time, open, high, low, close }) => ({
time: Date.parse(time),
open,
high,
low,
close,
}),
);
sixMonthPrice = pastPriceList["6M"]?.map(
({ time, open, high, low, close }) => ({
time: Date.parse(time),
open,
high,
low,
close,
}),
);
oneYearPrice = pastPriceList["1Y"]?.map(
({ time, open, high, low, close }) => ({
time: Date.parse(time),
open,
high,
low,
close,
}),
);
threeYearPrice = pastPriceList["MAX"]?.map(
({ time, open, high, low, close }) => ({
time: Date.parse(time),
open,
high,
low,
close,
}),
);
// Set worker status to finished and send chart data
return { oneWeekPrice, oneMonthPrice, sixMonthPrice, oneYearPrice, threeYearPrice, pastPriceList};
return {
oneWeekPrice,
oneMonthPrice,
sixMonthPrice,
oneYearPrice,
threeYearPrice,
pastPriceList,
};
} catch (error) {
// Set worker status to idle and send error message
return {};
}
}
onmessage = async (event: MessageEvent) => {
const ticker = event.data?.message?.ticker;
const apiURL = event.data?.message?.apiURL;
//console.log(ticker, apiURL);
try {
const [output, oneDayPrice] = await Promise.all([
getHistoricalPrice(ticker, apiURL),
getOneDayPrice(ticker, apiURL)
getOneDayPrice(ticker, apiURL),
]);
const oneWeekPrice = output?.oneWeekPrice;
@ -81,13 +130,21 @@ onmessage = async (event: MessageEvent) => {
const sixMonthPrice = output?.sixMonthPrice;
const oneYearPrice = output?.oneYearPrice;
const threeYearPrice = output?.threeYearPrice;
const pastPriceList = output?.pastPriceList
const pastPriceList = output?.pastPriceList;
const chartData = {oneDayPrice, oneWeekPrice, oneMonthPrice, sixMonthPrice, oneYearPrice, threeYearPrice, pastPriceList}
const chartData = {
oneDayPrice,
oneWeekPrice,
oneMonthPrice,
sixMonthPrice,
oneYearPrice,
threeYearPrice,
pastPriceList,
};
//console.log(pastPriceList)
postMessage({ message: 'success', chartData});
postMessage({ message: "success", chartData });
} catch (e) {
postMessage({ message: 'error', e});
postMessage({ message: "error", e });
}
// Sending data back to the main thread
//postMessage({ message: 'Data received in the worker'});

View File

@ -1,57 +1,77 @@
import { getCache, setCache, isOpen } from '$lib/store';
import { getCache, setCache, isOpen } from "$lib/store";
const checkMarketHour = async () => {
const holidays = ['2024-01-01', '2024-01-15','2024-02-19','2024-03-29','2024-05-27','2024-06-19','2024-07-04','2024-09-02','2024-11-28','2024-12-25'];
const currentDate = new Date().toISOString().split('T')[0];
const holidays = [
"2024-01-01",
"2024-01-15",
"2024-02-19",
"2024-03-29",
"2024-05-27",
"2024-06-19",
"2024-07-04",
"2024-09-02",
"2024-11-28",
"2024-12-25",
];
const currentDate = new Date().toISOString().split("T")[0];
// Get the current time in the ET time zone
const etTimeZone = 'America/New_York';
const currentTime = new Date().toLocaleString('en-US', { timeZone: etTimeZone });
const etTimeZone = "America/New_York";
const currentTime = new Date().toLocaleString("en-US", {
timeZone: etTimeZone,
});
// Determine if the NYSE is currently open or closed
const currentHour = new Date(currentTime).getHours();
const isWeekendValue = new Date(currentTime).getDay() === 6 || new Date(currentTime).getDay() === 0;
const isBeforeMarketOpenValue = currentHour < 9 || (currentHour === 9 && new Date(currentTime).getMinutes() < 30);
const isWeekendValue =
new Date(currentTime).getDay() === 6 ||
new Date(currentTime).getDay() === 0;
const isBeforeMarketOpenValue =
currentHour < 9 ||
(currentHour === 9 && new Date(currentTime).getMinutes() < 30);
const isAfterMarketCloseValue = currentHour >= 16;
isOpen.set(!(isWeekendValue || isBeforeMarketOpenValue || isAfterMarketCloseValue || holidays?.includes(currentDate)));
}
isOpen.set(
!(
isWeekendValue ||
isBeforeMarketOpenValue ||
isAfterMarketCloseValue ||
holidays?.includes(currentDate)
),
);
};
export const load = async ({ parent }) => {
checkMarketHour()
checkMarketHour();
const { apiKey, apiURL, user } = await parent();
const getDarkPoolFlow = async () => {
let output;
const cachedData = getCache('', 'getDarkPoolFlow');
const cachedData = getCache("", "getDarkPoolFlow");
if (cachedData) {
output = cachedData;
} else {
const response = await fetch(apiURL + '/dark-pool-flow', {
method: 'GET',
const response = await fetch(apiURL + "/dark-pool-flow", {
method: "GET",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
});
output = await response.json();
setCache('', output, 'getDarkPoolFlow');
setCache("", output, "getDarkPoolFlow");
}
output = user?.tier !== 'Pro' ? output?.slice(0,6) : output;
output = user?.tier !== "Pro" ? output?.slice(0, 6) : output;
return output;
};
// Make sure to return a promise
return {
getDarkPoolFlow: await getDarkPoolFlow()
getDarkPoolFlow: await getDarkPoolFlow(),
};
};

View File

@ -1,29 +1,28 @@
import { getCache, setCache } from '$lib/store';
import { getCache, setCache } from "$lib/store";
export const load = async ({ parent }) => {
const getDividendCalendar = async () => {
let output;
// Get cached data for the specific tickerID
const cachedData = getCache('', 'getDividendCalendar');
const cachedData = getCache("", "getDividendCalendar");
if (cachedData) {
output = cachedData;
} else {
const { apiKey, apiURL } = await parent();
// make the POST request to the endpoint
const response = await fetch(apiURL + '/dividends-calendar', {
method: 'GET',
const response = await fetch(apiURL + "/dividends-calendar", {
method: "GET",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
});
output = await response.json();
// Cache the data for this specific tickerID with a specific name 'getDividendCalendar'
setCache('', output, 'getDividendCalendar');
setCache("", output, "getDividendCalendar");
}
return output;
@ -31,6 +30,6 @@ export const load = async ({parent}) => {
// Make sure to return a promise
return {
getDividendCalendar: await getDividendCalendar()
getDividendCalendar: await getDividendCalendar(),
};
};

View File

@ -1,29 +1,28 @@
import { getCache, setCache } from '$lib/store';
import { getCache, setCache } from "$lib/store";
export const load = async ({ parent }) => {
const getEarningsCalendar = async () => {
let output;
// Get cached data for the specific tickerID
const cachedData = getCache('', 'getEarningsCalendar');
const cachedData = getCache("", "getEarningsCalendar");
if (cachedData) {
output = cachedData;
} else {
const { apiKey, apiURL } = await parent();
// make the POST request to the endpoint
const response = await fetch(apiURL + '/earnings-calendar', {
method: 'GET',
const response = await fetch(apiURL + "/earnings-calendar", {
method: "GET",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
});
output = await response.json();
// Cache the data for this specific tickerID with a specific name 'getEarningsCalendar'
setCache('', output, 'getEarningsCalendar');
setCache("", output, "getEarningsCalendar");
}
return output;
@ -31,6 +30,6 @@ export const load = async ({parent}) => {
// Make sure to return a promise
return {
getEarningsCalendar: await getEarningsCalendar()
getEarningsCalendar: await getEarningsCalendar(),
};
};

View File

@ -41,7 +41,7 @@ const countryMap = Object.fromEntries(
listOfRelevantCountries.map((entry) => {
const [code, name] = Object.entries(entry)[0];
return [name, code];
})
}),
);
onmessage = async (event: MessageEvent) => {
@ -53,7 +53,7 @@ onmessage = async (event: MessageEvent) => {
// Filter rawData based on the mapped country codes
const output = rawData?.map((subArray) =>
subArray?.filter((item) => filterCodes.includes(item?.country))
subArray?.filter((item) => filterCodes.includes(item?.country)),
);
let finalData = { output };

View File

@ -1,28 +1,25 @@
import { getCache, setCache } from '$lib/store';
import { getCache, setCache } from "$lib/store";
export const load = async ({ parent }) => {
const getEconomicIndicator = async () => {
let output;
const { apiKey, apiURL } = await parent();
const cachedData = getCache('', 'getEconomicIndicator');
const cachedData = getCache("", "getEconomicIndicator");
if (cachedData) {
output = cachedData;
} else {
const response = await fetch(apiURL + '/economic-indicator', {
method: 'GET',
const response = await fetch(apiURL + "/economic-indicator", {
method: "GET",
headers: {
"Content-Type": "application/json", "X-API-KEY": apiKey
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
});
output = await response.json();
setCache('', output, 'getEconomicIndicator');
setCache("", output, "getEconomicIndicator");
}
return output;
@ -30,6 +27,6 @@ export const load = async ({parent}) => {
// Make sure to return a promise
return {
getEconomicIndicator: await getEconomicIndicator()
getEconomicIndicator: await getEconomicIndicator(),
};
};

Some files were not shown because too many files have changed in this diff Show More