diff --git a/api/src/core/web.js b/api/src/core/web.js
deleted file mode 100644
index d892c56c..00000000
--- a/api/src/core/web.js
+++ /dev/null
@@ -1,97 +0,0 @@
-
-import { Bright, Cyan } from "../modules/sub/consoleText.js";
-import { languageCode } from "../modules/sub/utils.js";
-import { version, env } from "../modules/config.js";
-
-import { buildFront } from "../modules/build.js";
-import findRendered from "../modules/pageRender/findRendered.js";
-
-import { celebrationsEmoji } from "../modules/pageRender/elements.js";
-import { changelogHistory } from "../modules/pageRender/onDemand.js";
-import { createResponse } from "../modules/processing/request.js";
-
-export async function runWeb(express, app, gitCommit, gitBranch, __dirname) {
- const startTime = new Date();
- const startTimestamp = Math.floor(startTime.getTime());
-
- await buildFront(gitCommit, gitBranch);
-
- app.use('/', express.static('./build/min'));
- app.use('/', express.static('./src/front'));
-
- app.use((req, res, next) => {
- try { decodeURIComponent(req.path) } catch (e) { return res.redirect('/') }
- next();
- })
-
- app.get('/onDemand', (req, res) => {
- try {
- if (typeof req.query.blockId !== 'string') {
- return res.status(400).json({
- status: "error",
- text: "couldn't render this block, please try again!"
- });
- }
-
- let blockId = req.query.blockId.slice(0, 3);
- let blockData;
- switch(blockId) {
- // changelog history
- case "0":
- let history = changelogHistory();
- if (history) {
- blockData = createResponse("success", { t: history })
- } else {
- blockData = createResponse("error", {
- t: "couldn't render this block, please try again!"
- })
- }
- break;
- // celebrations emoji
- case "1":
- let celebration = celebrationsEmoji();
- if (celebration) {
- blockData = createResponse("success", { t: celebration })
- }
- break;
- default:
- blockData = createResponse("error", {
- t: "couldn't find a block with this id"
- })
- break;
- }
-
- if (blockData?.body) {
- return res.status(blockData.status).json(blockData.body);
- } else {
- return res.status(204).end();
- }
- } catch {
- return res.status(400).json({
- status: "error",
- text: "couldn't render this block, please try again!"
- })
- }
- })
-
- app.get("/", (req, res) => {
- return res.sendFile(`${__dirname}/${findRendered(languageCode(req))}`)
- })
-
- app.get("/favicon.ico", (req, res) => {
- return res.sendFile(`${__dirname}/src/front/icons/favicon.ico`)
- })
-
- app.get("/*", (req, res) => {
- return res.redirect('/')
- })
-
- app.listen(env.webPort, () => {
- console.log(`\n` +
- `${Cyan("cobalt")} WEB ${Bright(`v.${version}-${gitCommit} (${gitBranch})`)}\n` +
- `Start time: ${Bright(`${startTime.toUTCString()} (${startTimestamp})`)}\n\n` +
- `URL: ${Cyan(`${env.webURL}`)}\n` +
- `Port: ${env.webPort}\n`
- )
- })
-}
diff --git a/api/src/front/assets/meowbalt/error.png b/api/src/front/assets/meowbalt/error.png
deleted file mode 100644
index 533858a7..00000000
Binary files a/api/src/front/assets/meowbalt/error.png and /dev/null differ
diff --git a/api/src/front/assets/meowbalt/question.png b/api/src/front/assets/meowbalt/question.png
deleted file mode 100644
index 330cd69b..00000000
Binary files a/api/src/front/assets/meowbalt/question.png and /dev/null differ
diff --git a/api/src/front/cobalt.css b/api/src/front/cobalt.css
deleted file mode 100644
index ab8c5e3b..00000000
--- a/api/src/front/cobalt.css
+++ /dev/null
@@ -1,1265 +0,0 @@
-:root {
- --transparent: rgba(0, 0, 0, 0);
- --without-padding: calc(100% - 4rem);
- --border-15: 0.15rem solid var(--accent);
- --border-10: 0.1rem solid var(--accent);
- --inset-focus: 0 0 0 0.1rem var(--accent) inset;
- --inset-focus-inv: 0 0 0 0.15rem var(--background) inset;
- --font-mono: 'Noto Sans Mono', 'Consolas', 'SF Mono', monospace;
- --padding: 0.7rem;
- --padding-small: 0.2rem;
- --padding-dialog: 18px;
- --line-height: 1.65rem;
- --red: rgb(249, 47, 96);
- --blue: rgb(47, 138, 249);
- --gap: 0.5rem;
- --gap-no-icon: 0.6rem;
-}
-[data-theme="dark"] {
- --accent: rgb(225, 225, 225);
- --accent-highlight: rgb(225, 225, 225, 4%);
- --accent-subtext: rgb(110, 110, 110);
- --accent-hover: rgb(30, 30, 30);
- --accent-hover-elevated: rgb(48, 48, 48);
- --accent-hover-transparent: rgba(48, 48, 48, 0.5);
- --accent-button: rgb(25, 25, 25);
- --accent-button-elevated: rgb(42, 42, 42);
- --glass: rgba(25, 25, 25, 0.85);
- --glass-lite: rgba(25, 25, 25, 0.98);
- --subbackground: rgb(10, 10, 10);
- --background: rgb(0, 0, 0);
- --background-backdrop: rgba(0, 0, 0, 0.5);
-}
-[data-theme="light"] {
- --accent: rgb(25, 25, 25);
- --accent-highlight: rgb(25, 25, 25, 4%);
- --accent-subtext: rgb(110, 110, 110);
- --accent-hover: rgb(225, 225, 225);
- --accent-hover-elevated: rgb(210, 210, 210);
- --accent-hover-transparent: rgba(215, 215, 215, 0.5);
- --accent-button: rgb(232, 232, 232);
- --accent-button-elevated: rgb(215, 215, 215);
- --glass: rgba(232, 232, 232, 0.85);
- --glass-lite: rgba(232, 232, 232, 0.98);
- --subbackground: rgb(240, 240, 240);
- --background: rgb(255, 255, 255);
- --background-backdrop: rgba(255, 255, 255, 0.5);
-}
-html,
-body {
- height: calc(100% + env(safe-area-inset-top) / 2);
- margin: 0;
- background: var(--background);
- color: var(--accent);
- -webkit-tap-highlight-color: var(--transparent);
- font-family: var(--font-mono);
- user-select: none;
- -webkit-user-select: none;
- overflow: hidden;
- -ms-overflow-style: none;
- scrollbar-width: none;
-}
-#home {
- position: fixed;
- width: 100%;
- height: 100%;
-}
-a {
- color: var(--accent);
- text-decoration: none;
- user-select: none;
- -webkit-user-select: none;
-}
-::placeholder,
-::moz-placeholder {
- color: var(--accent-subtext);
-}
-.switches::-webkit-scrollbar,
-.popup-content::-webkit-scrollbar {
- display: none;
-}
-:focus-visible {
- outline: var(--border-15);
-}
-.checkbox {
- display: inline-flex;
- align-items: center;
- flex-direction: row;
- flex-wrap: nowrap;
- padding: calc(var(--gap) - 0.1rem) calc(var(--gap)*2 - var(--padding-small)) calc(var(--gap) - 0.1rem) var(--gap);
- width: auto;
- margin-right: var(--padding);
- margin-bottom: var(--padding);
- background: var(--accent-button);
-}
-.checkbox-label {
- line-height: 1.3rem;
-}
-[type="checkbox"] {
- -webkit-appearance: none;
- appearance: none;
- width: 20px;
- height: 20px;
- z-index: 0;
- margin-right: var(--padding);
- border: 0.15rem solid var(--accent);
-}
-[type="checkbox"]::before {
- content: "";
- display: none;
- position: relative;
- width: 6px;
- height: 12px;
- z-index: 5;
- transform: scaleX(0.9)rotate(45deg);
- left: 6px;
- top: 1px;
- border-bottom: 0.18rem solid var(--background);
- border-right: 0.18rem solid var(--background);
-}
-[type="checkbox"]:checked::before {
- display: block;
-}
-[type="checkbox"]:checked {
- background-color: var(--accent);
- border: 0;
-}
-input[type="checkbox"] {
- cursor: pointer;
-}
-button {
- background: none;
- border: none;
- font-family: var(--font-mono);
- color: var(--accent);
- font-size: 0.9rem;
-}
-input,
-input[type="text"],
-[type="text"] {
- border-radius: 0;
-}
-.glass-bkg {
- background: var(--glass);
- backdrop-filter: blur(7px);
- -webkit-backdrop-filter: blur(7px);
-}
-.glass-bkg.alone {
- z-index: -1;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- position: absolute;
-}
-.glass-bkg.small {
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- z-index: -1;
- position: absolute;
- border: var(--accent-highlight) solid 0.15rem;
- border-radius: 22px;
-}
-.desktop button:hover,
-.desktop .switch:hover,
-.desktop .checkbox:hover,
-.desktop .text-to-copy:hover,
-.desktop .collapse-header:hover {
- background: var(--accent-hover);
- box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset;
- cursor: pointer;
-}
-button:active,
-.switch:active,
-.checkbox:active,
-.text-to-copy:active {
- box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset;
- cursor: pointer;
- transform: scale(0.95);
-}
-.collapse-header:active {
- box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset;
-}
-.popup.small .switch {
- background: var(--accent-button-elevated);
-}
-.desktop .popup.small .switch:hover {
- background: var(--accent-hover-elevated);
-}
-.switch.text-backdrop,
-.switch.text-backdrop:hover,
-.switch.text-backdrop:active,
-.text-to-copy.text-backdrop,
-.text-to-copy.text-backdrop:hover,
-.text-to-copy.text-backdrop:active,
-.popup.small .switch.text-backdrop,
-.popup.small .switch.text-backdrop:hover,
-.popup.small .switch.text-backdrop:active {
- background: var(--accent);
- color: var(--background);
- box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset;
-}
-.picker-image:active {
- cursor: pointer;
- transform: scale(0.95);
-}
-.button {
- background: none;
- border: var(--border-15);
- color: var(--accent);
- padding: 0.3rem var(--padding) 0.5rem;
- font-size: 1rem;
-}
-.mono {
- font-family: var(--font-mono);
-}
-.center {
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
-}
-#cobalt-main-box {
- position: fixed;
- width: 40rem;
- height: auto;
- display: flex;
- flex-direction: column;
- align-content: center;
- align-items: center;
-}
-#logo {
- text-align: center;
- font-size: 1rem;
- height: 2.5rem;
- align-items: center;
- display: flex;
- gap: 0.3rem;
-}
-.logo-sub {
- color: var(--blue);
- font-size: 0.8rem;
-}
-#download-area {
- display: flex;
- flex-direction: column;
- width: 100%;
-}
-#cobalt-main-box #top {
- display: inline-flex;
- height: 2.5rem;
- flex-direction: row;
-}
-#cobalt-main-box #bottom {
- padding-top: calc(1rem - var(--padding-small));
- display: flex;
- flex-direction: row;
- justify-content: space-between;
-}
-.box {
- background: var(--background);
- color: var(--accent);
-}
-#url-input-area {
- background: none;
- padding-left: calc(20px + 1.4rem);
- width: 100%;
- color: var(--accent);
- border: 0;
- float: right;
- border-bottom: 0.1rem solid var(--accent-subtext);
- outline: none;
- font-size: 0.8rem;
-}
-#url-clear {
- height: 100%;
- background: none;
- padding: 0 1rem var(--padding-small);
- transform: none;
- font-size: 1rem;
- box-shadow: none!important;
-}
-#url-input-area:focus {
- outline: none;
- border-bottom: var(--border-10);
-}
-#link-icon {
- display: flex;
- position: absolute;
- width: 20px;
- padding-top: var(--padding-small);
- left: var(--padding);
- flex-wrap: nowrap;
- color: var(--accent-subtext);
-}
-#download-button {
- height: 2.5rem;
- color: var(--accent);
- background: none;
- border: none;
- font-size: 1.8rem;
- cursor: pointer;
- padding: 0;
- letter-spacing: -0.35rem;
- font-weight: normal!important;
-}
-#download-button:disabled {
- color: var(--accent-subtext);
- cursor: not-allowed;
-}
-#cobalt-main-box .switch,
-#footer .switch {
- box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset;
-}
-#footer {
- bottom: 0;
- width: 100%;
- position: absolute;
- display: flex;
- justify-content: center;
- padding-bottom: 2rem;
- font-size: 0.9rem;
- text-align: center;
-}
-#cobalt-main-box #bottom,
-#footer-buttons,
-#footer-buttons, .footer-pair {
- gap: var(--gap);
-}
-#footer-buttons, .footer-pair {
- display: flex;
- flex-direction: row;
- align-items: center;
-}
-.footer-button {
- width: auto!important;
- color: var(--accent-subtext);
- padding: var(--gap) 1rem!important;
- align-content: center;
-}
-.notification-dot {
- width: 8px;
- height: 8px;
- background: var(--red);
- margin-right: 0.4rem;
- border-radius: 99rem;
-}
-.text-backdrop {
- background: var(--accent);
- color: var(--background);
- padding: 0 0.3rem;
-}
-.text-backdrop.link {
- text-decoration: underline;
-}
-.cobalt-support-link {
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- gap: 0.3rem;
- margin-top: 0.5rem;
- user-select: none;
- -webkit-user-select: none;
-}
-::-moz-selection {
- background-color: var(--accent);
- color: var(--background);
-}
-::selection {
- background-color: var(--accent);
- color: var(--background);
-}
-.popup {
- visibility: hidden;
- position: fixed;
- height: auto;
- width: 36%;
- z-index: 999;
- font-size: 0.9rem;
- max-height: 95%;
- opacity: 0;
- transform: translate(-50%,-48%)scale(.95);
- box-shadow: 0 0 0 var(--padding-small) var(--glass) inset,
- 0 0 20px 0 var(--accent-hover-transparent);
-}
-.popup.visible {
- visibility: visible;
- opacity: 1;
- transform: translate(-50%, -50%);
- transition: transform 100ms ease-out, opacity 100ms ease-in-out;
-}
-#popup-backdrop {
- visibility: hidden;
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- z-index: 998;
- opacity: 0;
- background: var(--background-backdrop);
-}
-#popup-backdrop.visible {
- visibility: visible;
- opacity: 1;
- transition: opacity .13s ease-in-out;
- backdrop-filter: blur(7px);
- -webkit-backdrop-filter: blur(7px);
-}
-.popup.small {
- width: 21rem;
- box-shadow: 0px 0px 60px 0px var(--accent-hover);
- padding: var(--padding-dialog);
- transform: translate(-50%, -50%)scale(.95);
- pointer-events: all;
- border-radius: 22px;
-}
-.popup.small .popup-content-inner {
- display: flex;
- flex-direction: column;
- gap: var(--padding-dialog);
- width: 100%;
-}
-.popup.small.visible {
- transform: translate(-50%, -50%);
-}
-.popup.small .popup-header-contents,
-.popup.small .popup-content-inner,
-.popup.small .popup-header {
- padding: 0;
-}
-.popup.small .popup-header {
- position: relative;
- border: none;
-}
-.popup.small .popup-title {
- margin-bottom: 0.6rem;
-}
-.popup.small .close-error.switch {
- background: var(--accent)!important;
- color: var(--background);
- height: 2.5rem;
-}
-#popup-error,
-#popup-download {
- display: flex;
- flex-direction: column;
- padding-top: 4rem;
-}
-#popup-error {
- justify-content: center;
- align-items: center;
-}
-.popout-meowbalt {
- position: absolute;
- top: -7rem;
- user-select: none;
- -webkit-user-select: none;
- pointer-events: none;
- height: 180px;
- width: 180px;
-}
-#popup-download .popout-meowbalt {
- left: -2rem;
-}
-.popup.scrollable {
- height: 95%;
-}
-.changelog-subtitle {
- font-size: 1.3rem;
- padding-bottom: var(--gap-no-icon);
-}
-.changelog-banner {
- position: relative;
- width: 100%;
- max-height: 300px;
- min-height: 210px;
- margin-bottom: var(--padding);
- float: left;
- background: var(--accent-hover);
- display: flex;
-}
-.changelog-img {
- object-fit: cover;
- width: inherit;
- height: inherit;
- max-height: inherit;
-}
-.changelog-tags {
- display: inline-flex;
- align-items: center;
- gap: var(--padding);
- padding-bottom: var(--padding);
- flex-wrap: wrap;
-}
-.changelog-tag-version {
- font-size: 1rem;
- padding: 0.15rem 0.5rem;
-}
-.changelog-tag-date {
- color: var(--accent-subtext);
- font-size: 0.8rem;
-}
-.nowrap {
- white-space: nowrap;
-}
-.no-top-padding {
- padding-top: 0!important;
-}
-.desc-padding {
- padding-bottom: var(--padding);
-}
-#popup-subtitle {
- font-size: 1.1rem;
- padding-bottom: var(--padding);
-}
-.popup-desc,
-.desc-error,
-#popup-info-desc {
- width: 100%;
- text-align: left;
- float: left;
- line-height: var(--line-height);
- user-select: text;
- -webkit-user-select: text;
-}
-.desc-error {
- padding-bottom: 0rem;
- text-align: center;
-}
-.popup-title {
- font-size: 1.5rem;
- display: flex;
- align-items: center;
- line-height: 1em;
- margin-bottom: 0.4rem;
- margin-top: 0.4rem;
-}
-.popup-above-title {
- color: var(--accent-subtext);
- font-size: 0.8rem;
-}
-.popup-content {
- overflow-x: scroll;
- overflow-y: auto;
- height: 100%;
- scrollbar-width: none;
-}
-.popup-content-inner,
-.tab-content-settings,
-#picker-holder {
- padding-top: calc(var(--padding) + 4rem);
- padding-bottom: 4.8rem;
-}
-.tab-content-settings,
-#tab-about-about .popup-content-inner {
- padding-top: 6rem;
-}
-.bullpadding {
- padding-left: 0.58rem;
-}
-.popup-header {
- position: absolute;
- z-index: 999;
- padding-top: calc(var(--padding) + 1rem);
- width: 100%;
-}
-.settings-category {
- padding-bottom: var(--padding);
-}
-.separator {
- float: left;
-}
-.separator,
-.category-title {
- width: 100%;
- color: var(--accent-subtext);
- border-bottom: 0.05rem solid var(--accent-subtext);
- padding-bottom: 0.25rem;
- margin-bottom: calc(var(--gap-no-icon)*1.5);
-}
-.category-title {
- text-align: left;
- line-height: var(--line-height);
-}
-.bottom-margin {
- margin-bottom: var(--padding)!important;
-}
-.top-margin {
- margin-top: var(--padding)!important;
-}
-.top-margin-only {
- margin-top: var(--padding)!important;
- margin-bottom: 0!important;
-}
-.no-margin {
- margin: 0!important;
-}
-.switch-container {
- width: 100%;
-}
-.subtitle {
- width: 100%;
- text-align: left;
- line-height: var(--line-height);
- padding-bottom: 0.4rem;
- color: var(--accent);
-}
-.small-padding .subtitle {
- margin-top: 0.5rem;
-}
-.explanation {
- margin-top: var(--padding);
- width: 100%;
- font-size: 0.8rem;
- text-align: left;
- line-height: 1.3rem!important;
- color: var(--accent-subtext);
-}
-.explanation.embedded {
- margin-top: 0.825rem;
- margin-bottom: 0.825rem;
-}
-.subtext {
- color: var(--accent-subtext);
-}
-.switch {
- padding: var(--gap-no-icon);
- width: 100%;
- text-align: left;
- color: var(--accent);
- background: var(--accent-button);
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
-}
-.switch.space-right {
- margin-right: var(--padding);
-}
-.switch:focus {
- box-shadow: var(--inset-focus) inset;
-}
-.popup-tabs .switch {
- background: none;
-}
-.desktop .popup-tabs .switch:hover,
-.popup-tabs .switch:active {
- background: var(--accent-hover-transparent);
- box-shadow: 0 0 0 0.1rem var(--accent-highlight) inset;
-}
-.switch[data-enabled="true"],
-.popup-tabs .switch[data-enabled="true"] {
- color: var(--background);
- background: var(--accent)!important;
- cursor: default;
-}
-.switch[data-enabled="true"]:hover {
- background: var(--accent);
-}
-.switch[data-enabled="true"]:focus {
- box-shadow: var(--inset-focus-inv) inset;
-}
-.switches {
- display: flex;
- width: auto;
- flex-direction: row;
- flex-wrap: nowrap;
- scrollbar-width: none;
-}
-.switches .switch {
- padding-left: calc(var(--gap-no-icon) + 0.1rem);
- padding-right: calc(var(--gap-no-icon) + 0.1rem);
-}
-#popup-settings .switches .switch {
- text-align: center;
-}
-.autowidth {
- width: auto;
-}
-.bottom-space {
- margin-bottom: 2rem;
-}
-.text-to-copy {
- user-select: text;
- -webkit-user-select: text;
- background: var(--accent-button);
- padding: var(--gap-no-icon);
- overflow: clip;
-}
-.back-button {
- padding: 0;
- background: none;
- max-width: 4rem;
- font-size: 1rem;
-}
-.back-button svg path,
-.collapse-indicator svg path {
- fill: var(--accent);
-}
-.popup-tab-content[data-enabled="false"] {
- display: none;
-}
-.popup-tabs {
- z-index: 999;
- bottom: 0;
- position: absolute;
- width: 100%;
- padding-top: var(--padding-small);
- padding-bottom: calc(var(--padding) + 1rem);
-}
-.popup-tabs-child {
- width: 100%;
- padding: 0 var(--padding-small);
-}
-.emoji, svg {
- user-select: none;
- -webkit-user-select: none;
- pointer-events: none;
-}
-.emoji {
- margin-right: 0.4rem;
-}
-.picker-image {
- object-fit: cover;
- width: 100%;
- height: 100%;
- cursor: pointer;
- user-select: all;
- -webkit-user-select: all;
-}
-.picker-image-container {
- width: calc(100% / 3);
- height: 12rem;
- background-color: var(--accent-button);
- cursor: pointer;
- position: relative;
-}
-#picker-holder {
- display: flex;
- justify-content: start;
- flex-wrap: wrap;
- align-content: space-around;
- padding-top: 7.6rem;
- padding-bottom: 4.8rem;
- padding-left: var(--padding-small);
- padding-right: var(--padding-small);
-}
-.imageBlock {
- width: 100%;
- height: 100%;
- position: absolute;
- z-index: 99;
-}
-.picker-element-name {
- position: absolute;
- background: var(--background);
- color: var(--accent);
- padding: 0.3rem var(--gap);
- font-size: 0.8rem;
- opacity: 0.7;
- margin: 0.4rem;
-}
-#popup-picker .explanation {
- margin-top: 0!important;
- margin-bottom: var(--padding);
-}
-#cobalt-main-box #bottom button {
- width: auto;
- padding: var(--gap) 0.9rem;
-}
-.collapse-list {
- background: var(--subbackground);
- user-select: none;
- -webkit-user-select: none;
-}
-.collapse-header {
- padding: 0.5rem var(--padding);
- font-size: 0.95rem;
- display: flex;
- flex-direction: row;
- align-items: center;
- cursor: pointer;
- background: var(--accent-button);
-}
-.collapse-header .emoji {
- margin-right: var(--padding);
-}
-.collapse-indicator {
- display: flex;
- justify-content: center;
- align-items: center;
- cursor: pointer;
- transform: none;
-}
-.collapse-list.expanded .collapse-indicator {
- transform: rotate(180deg);
-}
-.collapse-title {
- width: 100%;
- display: flex;
- flex-direction: row;
- align-items: center;
-}
-.collapse-body {
- display: none;
- padding: var(--padding);
- padding-bottom: 1rem;
- user-select: text;
- -webkit-user-select: text;
-}
-.expanded .collapse-body {
- display: block;
-}
-#download-switcher .switches {
- gap: var(--gap);
-}
-#pd-share {
- display: none;
-}
-.popup-content-inner,
-.tab-content-settings,
-.popup-header-contents {
- padding-left: 1rem;
- padding-right: 1rem;
-}
-.urgent-notice {
- width: 100%;
- text-align: center;
- position: absolute;
- display: flex;
- justify-content: center;
- align-items: center;
- padding-top: 1rem;
-}
-.urgent-text {
- display: flex;
- align-items: center;
- cursor: pointer;
-}
-.no-transparency .glass-bkg,
-.no-transparency #popup-backdrop {
- backdrop-filter: none;
- -webkit-backdrop-filter: none;
-}
-.no-transparency .glass-bkg {
- background: var(--glass-lite);
-}
-.no-animation .popup,
-.no-animation #popup-backdrop {
- transition: none;
-}
-.popup-from-bottom {
- position: fixed;
- width: 100%;
- height: 100%;
- bottom: 0;
- z-index: 999;
- visibility: hidden;
- pointer-events: none;
-}
-.popup-from-bottom.visible {
- visibility: visible;
-}
-#keyboard-collapse {
- display: none;
-}
-.desktop #keyboard-collapse {
- display: block;
-}
-.text-backdrop.key {
- color: var(--accent-hover-elevated);
-}
-#keyboard-shortcuts {
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- justify-content: flex-start;
- align-items: flex-start;
- gap: 1.5rem;
- user-select: none;
- color: var(--accent);
-}
-.loader {
- text-align: center;
-}
-#picker-download {
- visibility: hidden;
-}
-#picker-download.visible {
- visibility: visible;
-}
-#home {
- opacity: 0;
-}
-#home.visible {
- opacity: 1;
- transition: opacity 0.2s ease-out;
-}
-.no-animation #home {
- transition: none;
-}
-.sponsored-by-text {
- text-align: center!important;
- font-size: .85rem;
- color: var(--accent-subtext);
- user-select: none;
-}
-#sponsored-logos {
- width: 100%;
- display: flex;
- justify-content: center;
- flex-wrap: wrap;
- gap: var(--padding-small) 1rem;
- margin-bottom: 1rem;
-}
-.sponsored-logo svg {
- height: inherit;
- width: inherit;
-}
-.sponsored-logo svg path {
- fill: var(--accent-subtext);
-}
-#filename-preview {
- background: var(--accent-button);
- margin-top: 0.8rem;
-}
-.filename-item {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- gap: 1rem;
- padding: 0.5rem var(--padding);
-}
-.filename-item.line {
- border-bottom: 0.1rem solid var(--accent-button-elevated);
-}
-.filename-label {
- color: var(--accent-subtext);
- font-size: 0.8rem;
-}
-.filename-container {
- overflow-wrap: anywhere;
-}
-/* rounded corners */
-#bottom #paste,
-#footer .switch,
-#audioMode,
-.popup-content .switches,
-.checkbox,
-.changelog-img,
-.changelog-banner,
-.close-error,
-#download-switcher .switch,
-#popup-about .switch,
-.popup-tabs .switch,
-.text-to-copy,
-.text-to-copy.text-backdrop,
-#filename-preview {
- border-radius: 9px;
-}
-[type=checkbox] {
- border-radius: 4px;
-}
-.popup,
-.scrollable .popup-content {
- border-radius: 12px;
-}
-.popup-header .glass-bkg {
- border-top-left-radius: 12px;
- border-top-right-radius: 12px;
- border-bottom: var(--accent-highlight) solid 0.1rem;
- top: -1px;
-}
-.popup-tabs .glass-bkg {
- border-bottom-left-radius: 12px;
- border-bottom-right-radius: 12px;
- border-top: var(--accent-highlight) solid 0.1rem;
- bottom: -1px;
-}
-.switches .switch:first-child {
- border-top-left-radius: 9px;
- border-bottom-left-radius: 9px;
-}
-.switches .switch:last-child {
- border-top-right-radius: 9px;
- border-bottom-right-radius: 9px;
-}
-.text-backdrop {
- border-radius: 4px;
-}
-.collapse-list:first-child,
-.collapse-list:first-child .collapse-header {
- border-top-left-radius: 8px;
- border-top-right-radius: 8px;
-}
-.collapse-list:last-child,
-.collapse-list:last-child .collapse-header {
- border-bottom-left-radius: 8px;
- border-bottom-right-radius: 8px;
-}
-.collapse-list:last-child.expanded .collapse-header {
- border-radius: 0;
-}
-/* prevent resizing fliecker on ios if web app is installed as standalone */
-@media all and (display-mode: standalone) {
- #home.visible {
- transition-delay: 0.1s;
- }
-}
-/* adapt the page according to screen size */
-@media screen and (max-width: 1550px) {
- .popup {
- width: 40%;
- }
-}
-@media screen and (max-width: 1440px) {
- .popup {
- width: 45%;
- }
-}
-@media screen and (max-width: 1300px) {
- .popup {
- width: 50%;
- }
-}
-@media screen and (max-width: 1200px) {
- .popup {
- width: 55%;
- }
-}
-@media screen and (max-width: 1025px) {
- .popup {
- width: 60%;
- }
-}
-@media screen and (max-width: 850px) {
- .popup {
- width: 75%;
- }
-}
-@media screen and (max-width: 680px) {
- .popup {
- width: 90%;
- }
-}
-@media screen and (max-width: 660px) {
- #cobalt-main-box {
- width: calc(100% - (var(--padding) * 2));
- }
-}
-/* mobile page */
-@media screen and (max-width: 499px) {
- .tab {
- font-size: 0!important;
- }
- .tab .emoji {
- margin-right: 0;
- }
- .checkbox {
- width: calc(100% - 1.3rem);
- }
-}
-@media screen and (max-width: 535px) {
- #cobalt-main-box #bottom {
- flex-direction: row-reverse;
- }
- #cobalt-main-box #bottom #audioMode button, #audioMode {
- width: 100%;
- }
- #footer-buttons {
- flex-direction: column;
- align-items: stretch;
- width: 100%;
- padding: 0 var(--padding);
- }
- .footer-pair .footer-button {
- width: 100%!important;
- }
- #logo {
- width: 100%;
- height: auto;
- justify-content: center;
- }
- #cobalt-main-box {
- display: flex;
- border: none;
- padding: 0;
- flex-direction: column;
- gap: var(--gap);
- }
- .popup,
- .popup-header .glass-bkg,
- .popup-tabs .glass-bkg,
- .glass-bkg.small {
- border-radius: 0;
- }
- .popup-tabs .glass-bkg {
- bottom: 0;
- }
- .switches {
- overflow-x: scroll;
- }
- .checkbox {
- margin-right: 0;
- }
- .popup.center {
- top: unset;
- left: unset;
- transform: unset;
- }
- .popup.small {
- width: calc(100% - var(--padding-dialog) * 2);
- height: auto;
- top: unset;
- bottom: 0;
- left: 0;
- transform: none;
- position: absolute;
- transform: translateY(30rem);
- }
- #popup-download .popout-meowbalt {
- left: unset;
- }
- .glass-bkg.small {
- border: none;
- border-top: var(--accent-highlight) solid 0.15rem;
- }
- .popup.small.visible {
- transform: translateY(0rem);
- transition: transform 250ms cubic-bezier(0.075, 0.82, 0.165, 1), opacity 130ms ease-in-out;
- }
- .popup.small .popup-header {
- background: none;
- }
- .no-animation .popup.small {
- transition: none;
- }
- .close-error {
- bottom: 3rem;
- }
- #picker-holder {
- padding-left: 0;
- padding-right: 0;
- }
- #picker-holder::-webkit-scrollbar {
- display: none;
- }
- #picker-holder.various {
- flex-wrap: wrap;
- gap: 0;
- overflow-x: hidden;
- overflow-y: scroll;
- }
- .popup, .popup.scrollable {
- border: none;
- width: 100%;
- height: 100%;
- max-height: 100%;
- box-shadow: none;
- }
- .popup-content-inner,
- .tab-content-settings,
- .popup-tabs-child,
- .popup-header-contents {
- padding-left: var(--padding);
- padding-right: var(--padding);
- }
- .popup-content-inner,
- .tab-content-settings,
- #picker-holder {
- padding-bottom: calc(var(--padding) + 3.5rem);
- padding-top: calc(var(--padding) + 3rem - var(--padding-small));
- }
- #footer,
- .popup-tabs {
- padding-bottom: var(--padding);
- }
- .popup.small {
- padding-bottom: var(--padding-dialog)
- }
- .urgent-notice {
- padding-top: 1rem;
- }
- .popup-title {
- margin-top: var(--padding-small);
- }
- .popup-header {
- padding-top: var(--padding);
- }
- .tab-content-settings,
- #tab-about-about .popup-content-inner {
- padding-top: calc(5rem - var(--padding-small));
- }
-}
-@media screen and (max-width: 535px) and (display-mode: standalone) {
- .popup-header {
- padding-top: max(
- calc(env(safe-area-inset-top)),
- var(--padding) + 1rem
- );
- }
- .urgent-notice {
- padding-top: max(
- calc(env(safe-area-inset-top) - var(--padding-small)),
- var(--padding)
- );
- }
- #footer,
- .popup-tabs {
- padding-bottom: max(
- calc(env(safe-area-inset-bottom) + var(--padding-small)),
- var(--padding)
- );
- }
- .popup.small {
- padding-bottom: max(
- calc(env(safe-area-inset-bottom) + var(--padding-small)),
- var(--padding-dialog)
- );
- }
- .popup-content-inner,
- .tab-content-settings {
- padding-top: max(
- calc(env(safe-area-inset-top) + var(--padding) + var(--padding-small) + 2rem),
- calc(var(--padding) + 4rem - var(--padding-small))
- );
- padding-bottom: max(
- calc(env(safe-area-inset-bottom) + var(--padding) + 3rem),
- calc(var(--padding) + var(--padding-small) * 2 + 3rem)
- );
- }
- .tab-content-settings,
- #tab-about-about .popup-content-inner {
- padding-top: max(
- calc(env(safe-area-inset-top) + var(--padding) + var(--padding-small) * 2 + 3rem),
- calc(var(--padding) + 5rem)
- );
- }
- #picker-holder {
- padding-top: max(
- calc(env(safe-area-inset-top) + var(--padding) + 5rem),
- calc(var(--padding) * 2 + 6rem)
- );
- padding-bottom: max(
- calc(env(safe-area-inset-bottom) + var(--padding) + 2rem),
- calc(4rem - var(--padding) + var(--padding-small))
- );
- }
-
- .android .popup-header {
- padding-top: var(--padding);
- }
- .android .popup-content-inner,
- .android .tab-content-settings,
- .android #picker-holder {
- padding-bottom: calc(var(--padding) + 3.5rem);
- padding-top: calc(var(--padding) + 3rem - var(--padding-small));
- }
- .android .tab-content-settings,
- .android #tab-about-about .popup-content-inner {
- padding-top: calc(5rem - var(--padding-small));
- }
-}
diff --git a/api/src/front/cobalt.js b/api/src/front/cobalt.js
deleted file mode 100644
index 0c89dec2..00000000
--- a/api/src/front/cobalt.js
+++ /dev/null
@@ -1,708 +0,0 @@
-const ua = navigator.userAgent.toLowerCase();
-const isIOS = ua.includes("iphone os") || (ua.includes("mac os") && navigator.maxTouchPoints > 0);
-const isAndroid = ua.includes("android");
-const isMobile = ua.includes("android") || isIOS;
-const isSafari = ua.includes("safari/");
-const isFirefox = ua.includes("firefox/");
-const isOldFirefox = ua.includes("firefox/") && ua.split("firefox/")[1].split('.')[0] < 103;
-
-const switchers = {
- "theme": ["auto", "light", "dark"],
- "vCodec": ["h264", "av1", "vp9"],
- "vQuality": ["720", "max", "2160", "1440", "1080", "480", "360", "240", "144"],
- "aFormat": ["mp3", "best", "ogg", "wav", "opus"],
- "audioMode": ["false", "true"],
- "filenamePattern": ["classic", "pretty", "basic", "nerdy"]
-}
-const checkboxes = [
- "alwaysVisibleButton",
- "downloadPopup",
- "fullTikTokAudio",
- "muteAudio",
- "reduceTransparency",
- "disableAnimations",
- "disableMetadata",
- "twitterGif",
- "plausible_ignore",
- "ytDub",
- "tiktokH265"
-]
-const bottomPopups = ["error", "download"]
-
-let store = {};
-
-const validLink = (link) => {
- try {
- return /^https:/i.test(new URL(link).protocol);
- } catch {
- return false
- }
-}
-
-const fixApiUrl = (url) => {
- return url.endsWith('/') ? url.slice(0, -1) : url
-}
-
-let apiURL = fixApiUrl(defaultApiUrl);
-
-const changeApi = (url) => {
- apiURL = fixApiUrl(url);
- return true
-}
-
-const eid = (id) => {
- return document.getElementById(id)
-}
-
-const sGet = (id) =>{
- return localStorage.getItem(id)
-}
-const sSet = (id, value) => {
- localStorage.setItem(id, value)
-}
-const lazyGet = (key) => {
- const value = sGet(key);
- if (key in switchers) {
- if (switchers[key][0] !== value)
- return value;
- } else if (checkboxes.includes(key)) {
- if (value === 'true')
- return true;
- }
-}
-
-const changeDownloadButton = (action, text) => {
- switch (action) {
- case "hidden": // hidden, but only visible when alwaysVisibleButton is true
- eid("download-button").disabled = true
- if (sGet("alwaysVisibleButton") === "true") {
- eid("download-button").value = '>>'
- eid("download-button").style.padding = '0 1rem'
- } else {
- eid("download-button").value = ''
- eid("download-button").style.padding = '0'
- }
- break;
- case "disabled":
- eid("download-button").disabled = true
- eid("download-button").value = text
- eid("download-button").style.padding = '0 1rem'
- break;
- default:
- eid("download-button").disabled = false
- eid("download-button").value = '>>'
- eid("download-button").style.padding = '0 1rem'
- break;
- }
-}
-
-const button = () => {
- let regexTest = validLink(eid("url-input-area").value);
-
- eid("url-clear").style.display = "none";
-
- if ((eid("url-input-area").value).length > 0) {
- eid("url-clear").style.display = "block";
- }
-
- if (regexTest) {
- changeDownloadButton()
- } else {
- changeDownloadButton("hidden")
- }
-}
-
-const clearInput = () => {
- eid("url-input-area").value = '';
- button();
-}
-
-const copy = (id, data) => {
- let target = document.getElementById(id);
- target.classList.add("text-backdrop");
-
- setTimeout(() => {
- target.classList.remove("text-backdrop")
- }, 600);
-
- if (data) {
- navigator.clipboard.writeText(data)
- } else {
- navigator.clipboard.writeText(target.textContent)
- }
-}
-
-const share = url => navigator?.share({ url }).catch(() => {});
-
-const preferredColorScheme = () => {
- let theme = "auto";
- let localTheme = sGet("theme");
- let isLightPreferred = false;
-
- if (localTheme) {
- theme = localTheme;
- }
- if (window.matchMedia) {
- isLightPreferred = window.matchMedia('(prefers-color-scheme: light)').matches;
- }
- if (theme === "auto") {
- theme = isLightPreferred ? "light" : "dark"
- }
-
- return theme
-}
-
-const changeStatusBarColor = () => {
- const theme = preferredColorScheme();
- const colors = {
- "dark": "#000000",
- "light": "#ffffff",
- "dark-popup": "#151515",
- "light-popup": "#ebebeb"
- }
-
- let state = store.isPopupOpen ? "dark-popup" : "dark";
-
- if (theme === "light") {
- state = store.isPopupOpen ? "light-popup" : "light";
- }
-
- document.querySelector('meta[name="theme-color"]').setAttribute('content', colors[state]);
-}
-const detectColorScheme = () => {
- document.documentElement.setAttribute("data-theme", preferredColorScheme());
- changeStatusBarColor();
-}
-
-if (window.matchMedia) {
- window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', () => {
- changeStatusBarColor()
- detectColorScheme()
- })
-}
-
-const updateFilenamePreview = () => {
- let videoFilePreview = ``;
- let audioFilePreview = ``;
- let resMatch = {
- "max": "3840x2160",
- "2160": "3840x2160",
- "1440": "2560x1440",
- "1080": "1920x1080",
- "720": "1280x720",
- "480": "854x480",
- "360": "640x360",
- }
-
- switch(sGet("filenamePattern")) {
- case "classic":
- videoFilePreview = `youtube_dQw4w9WgXcQ_${resMatch[sGet('vQuality')]}_${sGet('vCodec')}`
- + `${sGet("muteAudio") === "true" ? "_mute" : ""}`
- + `.${sGet('vCodec') === "vp9" ? 'webm' : 'mp4'}`;
- audioFilePreview = `youtube_dQw4w9WgXcQ_audio`
- + `.${sGet('aFormat') !== "best" ? sGet('aFormat') : 'opus'}`;
- break;
- case "basic":
- videoFilePreview = `${loc.FilenamePreviewVideoTitle} `
- + `(${sGet('vQuality') === "max" ? "2160p" : `${sGet('vQuality')}p`}, `
- + `${sGet('vCodec')}${sGet("muteAudio") === "true" ? ", mute" : ""})`
- + `.${sGet('vCodec') === "vp9" ? 'webm' : 'mp4'}`;
- audioFilePreview = `${loc.FilenamePreviewAudioTitle} - ${loc.FilenamePreviewAudioAuthor}`
- + `.${sGet('aFormat') !== "best" ? sGet('aFormat') : 'opus'}`;
- break;
- case "pretty":
- videoFilePreview = `${loc.FilenamePreviewVideoTitle} `
- + `(${sGet('vQuality') === "max" ? "2160p" : `${sGet('vQuality')}p`}, ${sGet('vCodec')}, `
- + `${sGet("muteAudio") === "true" ? "mute, " : ""}youtube)`
- + `.${sGet('vCodec') === "vp9" ? 'webm' : 'mp4'}`;
- audioFilePreview = `${loc.FilenamePreviewAudioTitle} - ${loc.FilenamePreviewAudioAuthor} (soundcloud)`
- + `.${sGet('aFormat') !== "best" ? sGet('aFormat') : 'opus'}`;
- break;
- case "nerdy":
- videoFilePreview = `${loc.FilenamePreviewVideoTitle} `
- + `(${sGet('vQuality') === "max" ? "2160p" : `${sGet('vQuality')}p`}, ${sGet('vCodec')}, `
- + `${sGet("muteAudio") === "true" ? "mute, " : ""}youtube, dQw4w9WgXcQ)`
- + `.${sGet('vCodec') === "vp9" ? 'webm' : 'mp4'}`;
- audioFilePreview = `${loc.FilenamePreviewAudioTitle} - ${loc.FilenamePreviewAudioAuthor} `
- + `(soundcloud, 1242868615)`
- + `.${sGet('aFormat') !== "best" ? sGet('aFormat') : 'opus'}`;
- break;
- }
- eid("video-filename-text").innerHTML = videoFilePreview
- eid("audio-filename-text").innerHTML = audioFilePreview
-}
-
-const changeTab = (evnt, tabId, tabClass) => {
- if (tabId === "tab-settings-other") updateFilenamePreview();
-
- let tabcontent = document.getElementsByClassName(`tab-content-${tabClass}`);
- let tablinks = document.getElementsByClassName(`tab-${tabClass}`);
-
- for (let i = 0; i < tabcontent.length; i++) {
- tabcontent[i].dataset.enabled = "false";
- }
- for (let i = 0; i < tablinks.length; i++) {
- tablinks[i].dataset.enabled = "false";
- }
-
- evnt.currentTarget.dataset.enabled = "true";
- eid(tabId).dataset.enabled = "true";
- eid(tabId).parentElement.scrollTop = 0;
-}
-
-const expandCollapsible = (evnt) => {
- let classlist = evnt.currentTarget.parentNode.classList;
- let c = "expanded";
- !classlist.contains(c) ? classlist.add(c) : classlist.remove(c);
-}
-
-const hideAllPopups = () => {
- let filter = document.getElementsByClassName('popup');
- for (let i = 0; i < filter.length; i++) {
- filter[i].classList.remove("visible");
- }
- eid("popup-backdrop").classList.remove("visible");
- store.isPopupOpen = false;
-
- // clear the picker
- eid("picker-holder").innerHTML = '';
- eid("picker-download").href = '/';
- eid("picker-download").classList.remove("visible");
-}
-
-const popup = (type, action, text) => {
- if (action === 1) {
- hideAllPopups(); // hide the previous popup before showing a new one
- store.isPopupOpen = true;
-
- // if not a small popup, update status bar color to match the popup header
- if (!bottomPopups.includes(type)) changeStatusBarColor();
- switch (type) {
- case "about":
- let tabId = "about";
- if (text) tabId = text;
- eid(`tab-button-${type}-${tabId}`).click();
- break;
- case "settings":
- eid(`tab-button-${type}-video`).click();
- break;
- case "error":
- eid("desc-error").innerHTML = text;
- break;
- case "download":
- eid("pd-download").href = text;
- eid("pd-copy").setAttribute("onClick", `copy('pd-copy', '${text}')`);
- eid("pd-share").setAttribute("onClick", `share('${text}')`);
- if (navigator.canShare) eid("pd-share").style.display = "flex";
- break;
- case "picker":
- eid("picker-title").innerHTML = loc.MediaPickerTitle;
- eid("picker-subtitle").innerHTML = isMobile ? loc.MediaPickerExplanationPhone : loc.MediaPickerExplanationPC;
-
- switch (text.type) {
- case "images":
- eid("picker-holder").classList.remove("various");
-
- eid("picker-download").href = text.audio;
- eid("picker-download").classList.add("visible");
-
- for (let i in text.arr) {
- eid("picker-holder").innerHTML +=
- `` +
- `` +
- ``
- }
- break;
- default:
- eid("picker-holder").classList.add("various");
-
- for (let i in text.arr) {
- eid("picker-holder").innerHTML +=
- `` +
- `
` +
- ``
- }
- eid("picker-download").classList.remove("visible");
- break;
- }
- break;
- default:
- break;
- }
- } else {
- store.isPopupOpen = false;
-
- // reset status bar to base color
- changeStatusBarColor();
-
- if (type === "picker") {
- eid("picker-download").href = '/';
- eid("picker-download").classList.remove("visible");
- eid("picker-holder").innerHTML = ''
- }
- }
- if (bottomPopups.includes(type)) {
- eid(`popup-${type}-container`).classList.toggle("visible");
- }
- eid("popup-backdrop").classList.toggle("visible");
- eid(`popup-${type}`).classList.toggle("visible");
- eid(`popup-${type}`).focus();
-}
-
-const changeSwitcher = (switcher, state) => {
- if (state) {
- if (!switchers[switcher].includes(state)) {
- state = switchers[switcher][0];
- }
- sSet(switcher, state);
-
- for (let i in switchers[switcher]) {
- if (switchers[switcher][i] === state) {
- eid(`${switcher}-${state}`).dataset.enabled = "true";
- } else {
- eid(`${switcher}-${switchers[switcher][i]}`).dataset.enabled = "false";
- }
- }
- if (switcher === "theme") detectColorScheme();
- if (switcher === "filenamePattern") updateFilenamePreview();
- } else {
- let defaultValue = switchers[switcher][0];
- sSet(switcher, defaultValue);
- for (let i in switchers[switcher]) {
- if (switchers[switcher][i] === defaultValue) {
- eid(`${switcher}-${defaultValue}`).dataset.enabled = "true";
- } else {
- eid(`${switcher}-${switchers[switcher][i]}`).dataset.enabled = "false";
- }
- }
- }
-}
-
-const checkbox = (action) => {
- sSet(action, !!eid(action).checked);
- switch(action) {
- case "alwaysVisibleButton": button(); break;
- case "reduceTransparency": eid("cobalt-body").classList.toggle('no-transparency'); break;
- case "disableAnimations": eid("cobalt-body").classList.toggle('no-animation'); break;
- }
-}
-
-const changeButton = (type, text) => {
- switch (type) {
- case "error": //error
- eid("url-input-area").disabled = false
- eid("url-clear").style.display = "block";
- changeDownloadButton("disabled", '!!');
- popup("error", 1, text);
- setTimeout(() => { changeButton("default") }, 2500);
- break;
- case "default": //enable back
- changeDownloadButton();
- eid("url-clear").style.display = "block";
- eid("url-input-area").disabled = false
- break;
- case "error-default": //enable back + information popup
- popup("error", 1, text);
- changeDownloadButton();
- eid("url-clear").style.display = "block";
- eid("url-input-area").disabled = false
- break;
- }
-}
-
-const internetError = () => {
- eid("url-input-area").disabled = false
- changeDownloadButton("disabled", '!!');
- setTimeout(() => { changeButton("default") }, 2500);
- popup("error", 1, loc.ErrorNoInternet);
-}
-
-const resetSettings = () => {
- localStorage.clear();
- window.location.reload();
-}
-
-const download = async(url) => {
- changeDownloadButton("disabled", '...');
-
- eid("url-clear").style.display = "none";
- eid("url-input-area").disabled = true;
-
- let req = {
- url,
- vCodec: lazyGet("vCodec"),
- vQuality: lazyGet("vQuality"),
- aFormat: lazyGet("aFormat"),
- filenamePattern: lazyGet("filenamePattern"),
- isAudioOnly: lazyGet("audioMode"),
- isTTFullAudio: lazyGet("fullTikTokAudio"),
- isAudioMuted: lazyGet("muteAudio"),
- disableMetadata: lazyGet("disableMetadata"),
- dubLang: lazyGet("ytDub"),
- twitterGif: lazyGet("twitterGif"),
- tiktokH265: lazyGet("tiktokH265"),
- }
-
- let j = await fetch(`${apiURL}/api/json`, {
- method: "POST",
- body: JSON.stringify(req),
- headers: {
- 'Accept': 'application/json',
- 'Content-Type': 'application/json'
- }
- }).then(r => r.json()).catch(() => {});
-
- if (!j) {
- internetError();
- return;
- }
-
- if ((j.status === "error" || j.status === "rate-limit") && j && j.text) {
- changeButton("error", j.text);
- return;
- }
-
- if (j.text && (!j.url || !j.picker)) {
- if (j.status === "success") {
- changeButton("error-default", j.text)
- } else {
- changeButton("error", loc.ErrorNoUrlReturned);
- }
- }
- switch (j.status) {
- case "redirect":
- changeDownloadButton("disabled", '>>>');
- setTimeout(() => { changeButton("default") }, 1500);
-
- if (sGet("downloadPopup") === "true") {
- popup('download', 1, j.url)
- } else {
- window.open(j.url, '_blank')
- }
- break;
- case "stream":
- changeDownloadButton("disabled", '?..');
-
- let probeStream = await fetch(`${j.url}&p=1`).then(r => r.json()).catch(() => {});
- if (!probeStream) return internetError();
-
- if (probeStream.status !== "continue") {
- changeButton("error", probeStream.text);
- return;
- }
-
- changeDownloadButton("disabled", '>>>');
- if (sGet("downloadPopup") === "true") {
- popup('download', 1, j.url)
- } else {
- if (isMobile || isSafari) {
- window.location.href = j.url;
- } else {
- window.open(j.url, '_blank');
- }
- }
- setTimeout(() => { changeButton("default") }, 2500);
- break;
- case "picker":
- if (j.audio && j.picker) {
- changeDownloadButton("disabled", '>>>');
- popup('picker', 1, {
- audio: j.audio,
- arr: j.picker,
- type: j.pickerType
- });
- setTimeout(() => { changeButton("default") }, 2500);
- } else if (j.picker) {
- changeDownloadButton("disabled", '>>>');
- popup('picker', 1, {
- arr: j.picker,
- type: j.pickerType
- });
- setTimeout(() => { changeButton("default") }, 2500);
- } else {
- changeButton("error", loc.ErrorNoUrlReturned);
- }
- break;
- case "success":
- changeButton("error-default", j.text);
- break;
- default:
- changeButton("error", loc.ErrorUnknownStatus);
- break;
- }
-}
-
-const pasteClipboard = async() => {
- try {
- let clipboard = await navigator.clipboard.readText();
- let onlyURL = clipboard.match(/https:\/\/[^\s]+/g)
- if (onlyURL) {
- eid("url-input-area").value = onlyURL;
- download(eid("url-input-area").value);
- }
- } catch (e) {
- let errorMessage = loc.FeatureErrorGeneric;
- let doError = true;
- let error = String(e).toLowerCase();
-
- if (error.includes("denied")) errorMessage = loc.ClipboardErrorNoPermission;
- if (error.includes("dismissed") || isIOS) doError = false;
- if (error.includes("function") && isFirefox) errorMessage = loc.ClipboardErrorFirefox;
-
- if (doError) popup("error", 1, errorMessage);
- }
-}
-
-const loadCelebrationsEmoji = async() => {
- let aboutButtonBackup = eid("about-footer").innerHTML;
- try {
- let j = await fetch(`/onDemand?blockId=1`).then(r => r.json()).catch(() => {});
- if (j && j.status === "success" && j.text) {
- eid("about-footer").innerHTML = eid("about-footer").innerHTML.replace(
- `${aboutButtonBackup.split('> ')[0]}>`,
- j.text
- )
- }
- } catch {
- eid("about-footer").innerHTML = aboutButtonBackup;
- }
-}
-
-const loadOnDemand = async(elementId, blockId) => {
- store.historyButton = eid(elementId).innerHTML;
- eid(elementId).innerHTML = `