update resources\web

This commit is contained in:
wjyLearn
2025-12-20 17:45:44 +08:00
parent 328f91afc2
commit 69be99b00a
264 changed files with 7342 additions and 84 deletions

View File

@@ -0,0 +1,43 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
<title>black</title>
<link rel="stylesheet" type="text/css" href="css/black.css" />
<script type="text/javascript" src="../include/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="../include/globalapi.js"></script>
<script type="text/javascript" src="../data/text.js"></script>
</head>
<body>
<div class="container">
<img src="img/empty.svg" />
<div class="content trans" tid='t127'>Please add the project information</div>
<div class="addBtn" onClick="addProject()">+ <label tid='t148'>Add</label></div>
</div>
</body>
<script>
$(function() {
TranslatePage();
});
function addProject() {
window.location.href = "editor.html";
}
function HandleStudio(pVal) {
let strCmd = pVal['command'];
if (strCmd == 'show_3mf_info') {
const detail = pVal.model && pVal.model.model;
const name = detail ? decodeURIComponent(detail.name || '').trim() : '';
const description = detail ? decodeURIComponent(detail.description || '').trim() : '';
if (name || description) {
window.location.href = 'index.html';
return;
}
}
}
</script>
</html>

View File

@@ -0,0 +1,70 @@
.accessory-rule-wrapper {
border: 1px solid rgba(0, 0, 0, 0.04);
border-radius: 4px;
padding: 8px 8px;
background: #ffffff;
position: absolute;
width: 248px;
right: 0;
top: -390px;
font-size: 12px;
box-shadow: 0 6px 16px -8px rgba(0, 0, 0, 0.08), 0 8px 24px 0 rgba(0, 0, 0, 0.06), 0 12px 48px 16px rgba(0, 0, 0, 0.04);
}
.accessory-rule-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.accessory-rule-list input {
display: none;
}
.accessory-rule-card {
position: relative;
padding: 8px 12px;
border: 1px solid #E4E4E4;
border-radius: 8px;
/* background: #fff; */
box-shadow: 0 2px 4px rgba(31, 35, 41, 0.08);
}
.accessory-rule-card::after {
content: '\203A';
position: absolute;
right: 15px;
top: 8px;
font-size: 16px;
color: #9FA3A9;
}
.accessory-rule-card:hover {
border: 1px solid #0B3FA8;
}
.accessory-rule-card:hover .accessory-rule-title {
color: #0B3FA8;
}
.accessory-rule-title {
font-weight: 600;
color: #202124;
}
.accessory-rule-meta {
display: grid;
grid-template-columns: auto 1fr;
row-gap: 4px;
column-gap: 6px;
font-size: 13px;
color: #4A4D52;
}
.accessory-rule-meta dt {
font-weight: 400;
color: #575A5F;
}
.accessory-rule-meta dd {
font-weight: 400;
text-align: right;;
}

View File

@@ -0,0 +1,39 @@
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #F4F4F4;
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.addBtn {
background-color: #4479fb;
padding: 9px 18px;
box-sizing: border-box;
height: 40px;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
display: inline-block;
width: auto;
flex: 0 0 auto;
margin-top: 16px;
}
.addBtn label {
cursor: pointer;
}
.content {
color: #AAA;
text-align: center;
font-size: 14px;
}

View File

@@ -0,0 +1,156 @@
:root {
--dark-color-base-text: #B3B3B5;
}
html, body
{
background-color: #242428;
color: #B3B3B5;
}
.topTool {
background-color: #242428;
}
.returnBtn img {
filter: invert(87%) sepia(1%) saturate(0%) hue-rotate(192deg)
brightness(91%) contrast(86%);
}
input {
background-color: #242428;
color: #B3B3B5;
}
.editorTitle {
color: #B3B3B5;
}
.accessory-rule-wrapper {
background-color: #242428;
border: 1px solid rgba(255, 255, 255, 0.247);
}
.accessory-rule-title {
color: #B3B3B5;
}
.nav-item {
color: var(--dark-color-base-text);
}
.Navigation .indicator {
background-color: var(--dark-color-base-text);;
}
.Navigation .rail {
background-color: #3d3d3d;
}
/*CKEditor*/
:root {
/* Helper variables to avoid duplication in the colors. */
--ck-custom-foreground: hsl(255, 3%, 18%);
--ck-custom-border: hsl(300, 1%, 22%);
--ck-custom-white: hsl(0, 0%, 100%);
/* -- Overrides generic colors. ------------------------------------------------------------- */
--ck-content-font-color: var(--ck-custom-white);
--ck-color-base-background: #242428;
--ck-color-base-border: hsl(240, 4%, 24%);
--ck-color-focus-border: hsl(208, 90%, 62%);
--ck-color-text: hsl(0, 0%, 98%);
--ck-color-shadow-drop: hsla(0, 0%, 0%, 0.2);
--ck-color-shadow-inner: hsla(0, 0%, 0%, 0.1);
/* -- Overrides the default .ck-button class colors. ---------------------------------------- */
--ck-color-button-default-hover-background: hsl(270, 1%, 22%);
--ck-color-button-default-active-background: hsl(270, 2%, 20%);
--ck-color-button-default-active-shadow: hsl(270, 2%, 23%);
--ck-color-button-on-background: var(--ck-custom-foreground);
--ck-color-button-on-hover-background: hsl(255, 4%, 16%);
--ck-color-button-on-active-background: hsl(255, 4%, 14%);
--ck-color-button-on-active-shadow: hsl(240, 3%, 19%);
--ck-color-button-on-disabled-background: var(--ck-custom-foreground);
--ck-color-button-action-background: hsl(168, 76%, 42%);
--ck-color-button-action-hover-background: hsl(168, 76%, 38%);
--ck-color-button-action-active-background: hsl(168, 76%, 36%);
--ck-color-button-action-active-shadow: hsl(168, 75%, 34%);
--ck-color-button-action-disabled-background: hsl(168, 76%, 42%);
--ck-color-button-action-text: var(--ck-custom-white);
--ck-color-button-save: hsl(120, 100%, 46%);
--ck-color-button-cancel: hsl(15, 100%, 56%);
/* -- Overrides the default .ck-dropdown class colors. -------------------------------------- */
--ck-color-dropdown-panel-border: var(--ck-custom-foreground);
/* -- Overrides the default .ck-dialog class colors. ----------------------------------- */
--ck-color-dialog-form-header-border: var(--ck-custom-border);
/* -- Overrides the default .ck-splitbutton class colors. ----------------------------------- */
--ck-color-split-button-hover-background: var(--ck-color-button-default-hover-background);
--ck-color-split-button-hover-border: var(--ck-custom-foreground);
/* -- Overrides the default .ck-input class colors. ----------------------------------------- */
--ck-color-input-border: hsl(257, 3%, 43%);
--ck-color-input-text: hsl(0, 0%, 98%);
--ck-color-input-disabled-background: hsl(255, 4%, 21%);
--ck-color-input-disabled-border: hsl(250, 3%, 38%);
--ck-color-input-disabled-text: hsl(0, 0%, 78%);
/* -- Overrides the default .ck-list class colors. ------------------------------------------ */
--ck-color-list-button-hover-background: var(--ck-custom-foreground);
--ck-color-list-button-on-background: hsl(208, 88%, 52%);
--ck-color-list-button-on-text: var(--ck-custom-white);
/* -- Overrides the default .ck-balloon-panel class colors. --------------------------------- */
--ck-color-panel-border: var(--ck-custom-border);
/* -- Overrides the default .ck-toolbar class colors. --------------------------------------- */
--ck-color-toolbar-border: var(--ck-custom-border);
/* -- Overrides the default .ck-tooltip class colors. --------------------------------------- */
--ck-color-tooltip-background: hsl(252, 7%, 14%);
--ck-color-tooltip-text: hsl(0, 0%, 93%);
/* -- Overrides the default colors used by the ckeditor5-image package. --------------------- */
--ck-content-color-image-caption-background: hsl(0, 0%, 97%);
--ck-content-color-image-caption-text: hsl(0, 0%, 20%);
/* -- Overrides the default colors used by the ckeditor5-widget package. -------------------- */
--ck-color-widget-blurred-border: hsl(0, 0%, 87%);
--ck-color-widget-hover-border: hsl(43, 100%, 68%);
--ck-color-widget-editable-focus-background: var(--ck-custom-white);
/* -- Overrides the default colors used by the ckeditor5-link package. ---------------------- */
--ck-color-link-default: hsl(190, 100%, 75%);
}
/* Improve displaying links. */
.ck.ck-editor__editable a {
color: hsl(210, 100%, 63%);
}
/* Improve displaying code blocks. */
.ck-content pre {
color: hsl(0, 0%, 91%);
border-color: hsl(0, 0%, 77%);
}

View File

@@ -0,0 +1,260 @@
*{
padding: 0px;
border: 0px;
margin: 0px;
font-family: "system-ui", "Segoe UI", Roboto, Oxygen, Ubuntu, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-sans;
border-color: #D7D7D7;
user-select: none;
}
html, body {
line-height: 20px;
font-size: 14px;
padding: 0px;
border: 0px;
margin: 0px;
background-color: #FFF;
}
body {
/* display: flex;
justify-content: center; */
}
.topTool {
display: flex;
justify-content: space-between;
height: 60px;
width: 100%;
position: fixed;
top: 0;
left: 0;
background-color: #FFF;
padding: 0px 18px;
align-items: center;
box-sizing: border-box;
z-index: 1000;
box-shadow: 0 2px 4px 0 rgba(55, 55, 55, 0.12);
}
.returnBtn {
display: flex;
align-items: center;
gap: 5px;
font-size: 20px;
font-weight: 700;
cursor: pointer;
}
.returnBtn label {
cursor: pointer;
}
.saveBtn {
background-color: #4479fb;
padding: 9px 8px;
box-sizing: border-box;
height: 40px;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
color: #000000;
}
.container {
width: 968px;
padding: 36px 50px;
margin: 50px auto 40px;
}
.editorGroup {
margin-bottom: 16px;
}
.editorTitle {
color: #353535;
margin-bottom: 8px;
font-weight: 600;
}
.required {
text-indent: -10px;
}
.required::before {
content: "*";
color: #E14747;
margin-right: 4px;
}
.editorInput {
width: 100%;
height: 40px;
border-radius: 2px;
border: 1px solid #E8E8E8;
padding-left: 16px;
}
.editorInput:focus {
border-color: #74a8ff;
outline: none;
}
.comment {
font-size: 12px;
color: #898989;
}
/*upload button*/
.uploadBox {
width: 104px;
height: 76px;
border-radius: 2px;
border: 1px solid #DDD;
flex: 0 0 auto;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
transition: border-color 0.3s;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.uploadBox:hover {
border-color: #74a8ff;
}
.uploadText {
color: #898989;
font-size: 12px;
margin-top: 8px;
}
.uploadIcon {
width: 20px;
}
.uploadBox input[type="file"] {
display: none;
}
/*image preview*/
.imageGroup {
display: flex;
gap: 16px;
}
.imagePreview {
position: relative;
width: 104px;
height: 76px;
background-size: cover;
background-position: center;
flex: 0 0 auto;
}
.imagePreview img {
display: none;
position: absolute;
right: 0;
top: 0;;
}
.imagePreview:hover .setModelCover {
display: flex;
}
.imagePreview:hover img {
display: block;
}
.imageList {
display: flex;
gap: 16px;
flex-wrap: wrap;
}
.modelCover {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(79, 138, 243, 0.80);
transition: opacity 0.3s;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 12px;
}
.setModelCover {
position: absolute;
bottom: 8px;
left: 0;
right: 0;
width: 90%;
background-color: rgba(79, 138, 243, 1);
transition: opacity 0.3s;
display: none;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 12px;
margin: 0 auto;
}
/*ckeditor custom styles*/
:root {
--ck-color-focus-border: #23469A !important;
--ck-color-button-on-hover-background: hsl(122, 33%, 83%) !important;
--ck-color-button-on-color: #23469A !important;
--ck-color-button-on-background: #3C79F141 !important;
--ck-color-focus-outer-shadow: #C9D5FC !important;
}
.ck-powered-by {
display: none !important;
}
.ck-editor__editable,
.ck-content {
min-height: 100px !important;
}
.ck-editor__editable_inline {
padding: 12px 16px 12px 36px !important;
box-sizing: border-box;
}
.ck-editor__editable, .ck-sticky-panel__content {
border-color: #E8E8E8 !important;
}
/*editor accessories*/
.editorSubTitle {
color: #353535;
font-size: 12px;
margin-top: 8px;
margin-bottom: 8px;
font-weight: 600;
}
.accessoriesButton {
border-radius: 2px;
border: 1px solid var(--Green-600, #23469A);
height: 24px;
padding: 4px 8px;
color: #23469A;
font-weight: 600;
display: inline-flex;
position: relative;
}
.accessory-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.titleJustified {
display: flex;
justify-content: space-between;
}
.attachment {
display: inline-block;
border-radius: 2px;
border: 1px solid #DDD;
width: 350px;
font-size: 14px;
padding: 6px 16px;
display: flex;
align-items: center;
white-space: normal;
overflow-wrap: anywhere;
word-break: break-all;
cursor: pointer;
/* background: var(--background-base, #F7F7F7); */
}
.attachment-icon {
width: 28px;
height: 28px;
margin-right: 12px;
}
.attachment-delete {
width: 20px;
height: 20px;
margin-left: auto;
}
hr {
margin-top: 27px;
margin-bottom: 19px;
border-top: 1px solid #EBEBEB
}

View File

@@ -0,0 +1,70 @@
/* 简洁图片画廊样式 */
.bs-gallery {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
gap: 16px;
}
.bs-gallery-main {
position: relative;
-webkit-box-flex: 1;
-ms-flex: 0 0 560px;
flex: 0 0 560px;
width: 560px;
border-radius: 8px;
overflow: hidden;
background: #f3f3f3;
}
.bs-gallery-image {
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
display: block;
}
.bs-gallery-counter {
position: absolute;
right: 12px;
bottom: 12px;
background: rgba(0,0,0,.45);
color: #fff;
padding: 6px 10px;
border-radius: 10px;
font-weight: 600;
font-size: 14px;
}
.bs-gallery-thumbs {
width: 180px;
overflow-y: auto;
padding-right: 4px;
}
.bs-gallery-thumb {
border-radius: 6px;
overflow: hidden;
cursor: pointer;
margin-bottom: 16px;
position: relative;
}
.bs-gallery-thumb img {
width: 100%;
height: 100px;
-o-object-fit: cover;
object-fit: cover;
display: block;
filter: grayscale(10%);
}
.bs-gallery-thumb.active {
border: 2px solid #426DC2; /* 绿色高亮 */
}
.bs-gallery-thumb:last-child { margin-bottom: 0; }

View File

@@ -0,0 +1,50 @@
.Navigation {
position: sticky;
width: 190px;
padding-left: 16px; /* 左侧留给导轨 */
}
.Navigation .rail {
position: absolute;
left: 6px;
top: 0;
bottom: 0;
width: 6px;
background: #EBEBEB; /* 浅灰导轨 */
}
.Navigation .indicator {
position: absolute;
left: 6px;
width: 6px;
background: #1f1f1f; /* 深色活动段 */
border-radius: 2px;
transition: top 0.25s ease, height 0.25s ease;
}
.Navigation ul {
list-style: none;
margin: 0;
padding: 0;
}
.Navigation .nav-item {
padding: 3px 12px;
font-size: 15px;
cursor: pointer;
}
.Navigation .nav-item a {
color: inherit;
text-decoration: none;
}
.Navigation .nav-item.active {
font-weight: 700;
}
.Navigation .nav-item.active a {
text-decoration: underline;
text-decoration-color: #446DC0;
text-underline-offset: 4px;
}

View File

@@ -0,0 +1,23 @@
.toast {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%) scale(0.95);
background: #fff3cd;
color: #856404;
border: 1px solid #ffeeba;
border-radius: 8px;
padding: 10px 20px;
box-shadow: 0 2px 10px rgba(0,0,0,.15);
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
font-size: 15px;
opacity: 0;
pointer-events: none;
transition: all 0.3s ease;
z-index: 9999;
}
.toast.show {
opacity: 1;
transform: translateX(-50%) scale(1);
pointer-events: auto;
}

View File

@@ -0,0 +1,174 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
<title>Model Editor</title>
<link rel="stylesheet" type="text/css" href="css/editor.css" />
<link rel="stylesheet" type="text/css" href="css/tool.css" />
<link rel="stylesheet" type="text/css" href="css/accessory_dropdown.css" />
<link rel="stylesheet" href="../include/ckeditor5/ckeditor5.css">
<script type="text/javascript" src="../include/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="../include/purify.min.js"></script>
<script type="text/javascript" src="../model/test.js"></script>
<script type="text/javascript" src="../include/globalapi.js"></script>
<script type="text/javascript" src="../data/text.js"></script>
</head>
<body>
<div class="topTool">
<div class="returnBtn" onclick="returnBtn()"><img src="img/return.svg"><label class="trans" tid="t134">Return</label></div>
<div class="saveBtn trans" onclick="saveInfo()" tid="t135">Save</div>
</div>
<div class="container">
<div class="editorGroup">
<div class="editorTitle required trans" tid="t136">Project Name</div>
<input type="text" id="projectNameInput" class="editorInput" />
</div>
<div class="editorGroup">
<div class="editorTitle required trans" tid="t137">Pictures</div>
<div class="comment" tid="t143">JPG/GIF/PNG format ≤ 4MB, no more than 16 pictures, drag the picture to adjust the order; It
is best to scale your image to 4:3 for the best display.</div>
<div class="imageGroup">
<label class="uploadBox">
<input type="file" id="projectImageInput" accept=".jpg,.jpeg,.png,.gif,.webp">
<img src="img/upload.svg" class="uploadIcon" />
<div class="uploadText trans" tid="t138">Add Picture</div>
</label>
<div class="imageList" id="imageList">
<!-- <div class="imagePreview" style="background-image: url('../model/img/p1.png')">
<img src="img/img_del.svg" />
<div class="modelCover">Model cover</div>
</div>
<div class="imagePreview" style="background-image: url('../model/img/p1.png')">
<img src="img/img_del.svg" />
<div class="setModelCover">Set as cover</div>
</div> -->
</div>
</div>
</div>
<div class="editorGroup">
<div class="editorTitle required trans" tid="t132">Description</div>
<div class="editor-container editor-container_classic-editor" id="editor-container">
<div class="editor-container__editor">
<div id="editor"></div>
</div>
</div>
</div>
<div class="editorGroup">
<div class="editorTitle titleJustified"><span class="trans" tid="t130">Add Accessories</span>
<div class="accessoriesButton" id="accessories-btn">
+<span class="trans" tid="t139">Add accessories</span>
<div class="accessory-rule-wrapper" style="display: none;">
<div class="accessory-rule-list">
<label class="accessory-rule-card">
<input type="file" id="bom-input" accept=".xls,.xlsx,.pdf" />
<div class="accessory-rule-title trans" tid="t140">Bill of Materials</div>
<dl class="accessory-rule-meta">
<dt>Format:</dt>
<dd>xls, xlsx, pdf;</dd>
<dt>Size:</dt>
<dd>xls, xlsx &le; 10MB<br>PDF &le; 50MB/piece;</dd>
<dt>Quantity:</dt>
<dd>&le; 10</dd>
</dl>
</label>
<label class="accessory-rule-card">
<input type="file" id="assembly-guide-input" accept=".jpg,.png,.pdf" />
<div class="accessory-rule-title trans" tid="t141">Assembly Guide</div>
<dl class="accessory-rule-meta">
<dt>Format:</dt>
<dd>jpg, png, pdf;</dd>
<dt>Size:</dt>
<dd>png, jpg &le; 10MB<br>PDF &le; 50MB/piece;</dd>
<dt>Quantity:</dt>
<dd>&le; 25</dd>
</dl>
</label>
<label class="accessory-rule-card">
<input type="file" id="other-input" accept=".txt" />
<div class="accessory-rule-title trans" tid="t103">Other</div>
<dl class="accessory-rule-meta">
<dt>Format:</dt>
<dd>txt</dd>
<dt>Size:</dt>
<dd>&le; 10MB</dd>
<dt>Quantity:</dt>
<dd>&le; 10</dd>
</dl>
</label>
</div>
</div>
</div>
</div>
<div class="editorSubGroup">
<div class="editorSubTitle trans" style="display: none;" tid="t140">Bill of Materials(<label>0</label>)</div>
<div class="accessory-list" id="bom-list">
<!-- <div class="attachment"><img class="attachment-icon"
src="img/icon_pdf.svg">31232asdfasdfasdfasdfasdfasdfasdfasdfasdf13.pdf<img class="attachment-delete"
src="img/del.svg"></div>
<div class="attachment"><img class="attachment-icon" src="img/icon_pdf.svg">3123213.pdf<img
class="attachment-delete" src="img/del.svg"></div>
<div class="attachment"><img class="attachment-icon" src="img/icon_pdf.svg">3123213.pdf<img
class="attachment-delete" src="img/del.svg"></div> -->
</div>
<div class="editorSubTitle trans" style="display: none;" tid="t141">Assembly Guide(<label>0</label>)</div>
<div class="accessory-list" id="assembly-list">
<!-- <div class="attachment"><img class="attachment-icon"
src="img/icon_pdf.svg">31232asdfasdfasdfasdfasdfasdfasdfasdfasdf13.pdf<img class="attachment-delete"
src="img/del.svg"></div>
<div class="attachment"><img class="attachment-icon" src="img/icon_pdf.svg">3123213.pdf<img
class="attachment-delete" src="img/del.svg"></div>
<div class="attachment"><img class="attachment-icon" src="img/icon_pdf.svg">3123213.pdf<img
class="attachment-delete" src="img/del.svg"></div> -->
</div>
<div class="editorSubTitle trans" style="display: none;" tid="t103">Other(<label>0</label>)</div>
<div class="accessory-list" id="other-list"></div>
</div>
<hr />
<div class="editorGroup">
<div class="editorTitle trans" tid="t133">Profile Name</div>
<input type="text" id="ProfileNameInput" class="editorInput" />
</div>
<div class="editorGroup">
<div class="editorTitle trans" tid="t142">Profile Pictures</div>
<div class="comment trans" tid="t143">JPG/GIF/PNG format ≤ 4MB, no more than 16 pictures, drag the picture to adjust the order;It is best to scale your image to 4:3 for the best display.</div>
<div class="imageGroup">
<label class="uploadBox">
<input type="file" id="ProfileImageInput" accept=".jpg,.jpeg,.png,.gif">
<img src="img/upload.svg" class="uploadIcon" />
<div class="uploadText trans" tid="t138">Add Picture</div>
</label>
<div class="imageList" id="profileImageList">
<!-- <div class="imagePreview" style="background-image: url('../model/img/p1.png')">
<img src="img/img_del.svg" />
<div class="modelCover">Model cover</div>
</div>
<div class="imagePreview" style="background-image: url('../model/img/p1.png')">
<img src="img/img_del.svg" />
<div class="setModelCover">Set as cover</div>
</div> -->
</div>
</div>
</div>
<div class="editorGroup">
<div class="editorTitle trans" tid="t132">Description</div>
<div class="editor-container editor-container_classic-editor" id="profile-editor-container">
<div class="editor-container__editor">
<div id="profile-editor"></div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="../include/ckeditor5/ckeditor5.umd.js"></script>
<script type="text/javascript" src="js/ckeditor_config.js"></script>
<script type="text/javascript" src="js/editor.js"></script>
</body>
</html>

View File

@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.9974 5.83398C15.4258 5.83398 15.7793 6.15586 15.8275 6.57031L15.8334 6.66699V15.834C15.8332 16.7543 15.085 17.5 14.1625 17.5H5.83728C4.91474 17.5 4.16651 16.7543 4.16638 15.834V6.66699L4.17224 6.57031C4.22047 6.15601 4.57318 5.83421 5.00134 5.83398C5.4297 5.83398 5.78317 6.15586 5.83142 6.57031L5.83728 6.66699V15.834H14.1625V6.66699L14.1683 6.57031C14.2166 6.15601 14.5693 5.83421 14.9974 5.83398ZM10.7455 2.5C11.0745 2.50001 11.3965 2.59777 11.6703 2.78027L12.5004 3.33301H15.8334C16.2936 3.33301 16.6664 3.70675 16.6664 4.16699C16.6662 4.62708 16.2935 5 15.8334 5H4.16638C3.7064 4.99982 3.33355 4.62697 3.33337 4.16699C3.33337 3.70686 3.70629 3.33318 4.16638 3.33301H7.50037L8.33044 2.78027C8.60411 2.59784 8.92538 2.50008 9.25427 2.5H10.7455Z" fill="#E14747"/>
</svg>

After

Width:  |  Height:  |  Size: 882 B

View File

@@ -0,0 +1,19 @@
<svg width="200" height="160" viewBox="0 0 200 160" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M101.955 141.053C135.47 141.053 162.649 114.432 162.649 81.5597C162.649 48.6871 135.47 22.0664 101.955 22.0664C68.4409 22.0664 41.2615 48.6871 41.2615 81.5597C41.2615 114.432 68.4409 141.053 101.955 141.053Z" fill="#F8F8F8"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M39.9509 81.4977C39.9509 48.0616 67.5946 20.9961 101.667 20.9961C135.739 20.9961 163.382 48.0616 163.382 81.4977C163.382 114.934 135.739 141.999 101.667 141.999C67.5946 141.999 39.9509 114.934 39.9509 81.4977ZM101.667 23.0128C68.7097 23.0128 41.9945 49.1887 41.9945 81.4977C41.9945 113.807 68.7097 139.983 101.667 139.983C134.624 139.983 161.339 113.807 161.339 81.4977C161.339 49.1887 134.624 23.0128 101.667 23.0128Z" fill="#E4E4E4"/>
<path d="M148.157 73.7338V110.136C148.157 117.698 141.924 123.849 134.158 123.849H69.3773C61.714 123.849 55.4811 117.799 55.3789 110.236C55.3789 110.136 55.3789 110.136 55.3789 110.035V73.7338C55.3789 73.633 55.3789 73.633 55.3789 73.5322C55.3789 73.3305 55.3789 73.1288 55.4811 72.9272C55.5833 72.6246 55.6854 72.423 55.7876 72.1205L73.1579 39.3488C73.771 38.0379 75.0993 37.332 76.5298 37.332H126.904C128.334 37.332 129.56 38.0379 130.276 39.3488L147.646 72.1205C147.748 72.3221 147.85 72.6246 147.953 72.9272C148.157 73.1288 148.157 73.4313 148.157 73.7338Z" fill="#EEEEEE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.5301 38.3409C75.4342 38.3409 74.5068 38.8721 74.0859 39.7719L74.0753 39.7945L56.7295 72.5201C56.6783 72.6644 56.6285 72.7875 56.5861 72.8921L56.5833 72.8989C56.5317 73.0261 56.4911 73.1269 56.4507 73.2466L56.4277 73.3146L56.4054 73.3586C56.4043 73.369 56.4029 73.3858 56.402 73.413C56.401 73.445 56.401 73.4797 56.401 73.5327V110.23C56.4992 117.236 62.2736 122.842 69.3776 122.842H134.159C141.365 122.842 147.135 117.137 147.135 110.136V73.7344C147.135 73.6549 147.135 73.6009 147.133 73.552C147.133 73.5494 147.133 73.5469 147.133 73.5445L147.06 73.4724L146.983 73.2466C146.874 72.922 146.797 72.7027 146.736 72.5789L129.376 39.8274C129.375 39.8256 129.374 39.8239 129.373 39.8222C128.835 38.8386 127.954 38.3409 126.904 38.3409H76.5301ZM72.2418 38.9027C73.052 37.1966 74.7733 36.3242 76.5301 36.3242H126.904C128.714 36.3242 130.284 37.2365 131.176 38.8712L131.181 38.8819L148.556 71.6618L148.56 71.6701C148.675 71.8972 148.78 72.1915 148.865 72.4408C149.025 72.6723 149.1 72.9139 149.137 73.1128C149.179 73.3435 149.179 73.5755 149.179 73.711L149.179 110.136C149.179 118.261 142.484 124.858 134.159 124.858H69.3776C61.1571 124.858 54.4671 118.367 54.3575 110.25L54.3574 110.237V73.5327C54.3574 73.5231 54.3573 73.5128 54.3573 73.5017C54.3565 73.3205 54.3549 72.945 54.5316 72.5518C54.5856 72.3974 54.6385 72.2668 54.6832 72.1566L54.6859 72.1499C54.7375 72.0226 54.7781 71.9218 54.8185 71.8021L54.8445 71.7254L72.2418 38.9027Z" fill="#CCCCCC"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M128.04 23.9961C128.102 24.6618 128.163 25.3039 128.221 25.9244L126.187 26.1117C126.128 25.4905 126.067 24.8473 126.005 24.1801L128.04 23.9961ZM128.584 29.7679C128.712 31.1557 128.825 32.4324 128.916 33.6317L126.879 33.7828C126.788 32.5994 126.677 31.3351 126.549 29.9515L128.584 29.7679ZM129.139 37.5267C129.182 38.8694 129.182 40.1574 129.128 41.4607L127.086 41.3779C127.138 40.1304 127.138 38.8921 127.096 37.5914L129.139 37.5267ZM128.803 45.3853C128.654 46.6018 128.457 47.8778 128.205 49.2599L126.193 48.9022C126.44 47.5527 126.631 46.3158 126.774 45.1437L128.803 45.3853ZM102.597 48.2539C103.369 47.7752 104.215 47.4497 105.084 47.2651L105.514 49.2367C104.871 49.3733 104.26 49.6092 103.712 49.9448C103.193 50.317 102.748 50.776 102.38 51.2989L100.702 50.1478C101.199 49.4419 101.813 48.8074 102.545 48.2888L102.57 48.2705L102.597 48.2539ZM112.512 49.1765C111.856 48.5778 111.096 48.106 110.283 47.7632L109.48 49.6176C110.102 49.8798 110.666 50.2348 111.14 50.6714L111.162 50.6915L111.185 50.7103C111.729 51.1555 112.192 51.6589 112.581 52.2059L114.254 51.0489C113.771 50.3672 113.192 49.7361 112.512 49.1765ZM127.43 53.078C127.296 53.6896 127.153 54.3228 127 54.9801L126.989 55.0283L126.973 55.0753C126.915 55.2462 126.856 55.4195 126.797 55.5944C126.611 56.1476 126.418 56.7173 126.217 57.2833L124.289 56.6146C124.484 56.0658 124.669 55.5181 124.855 54.9685C124.909 54.8064 124.964 54.6442 125.019 54.4817C125.166 53.8485 125.304 53.2389 125.433 52.6505L127.43 53.078ZM99.3349 57.4395C99.1405 56.625 99.065 55.7782 99.103 54.9362L101.145 55.026C101.114 55.699 101.176 56.3674 101.329 56.9996L101.337 57.0287L101.342 57.0582C101.436 57.5808 101.568 58.0926 101.735 58.5905L99.7957 59.2255C99.6009 58.646 99.446 58.0495 99.3349 57.4395ZM116.099 55.7483C116.224 56.5782 116.263 57.4173 116.224 58.2444C116.187 59.0603 116.083 59.8721 115.923 60.6726L113.918 60.2835C114.06 59.573 114.15 58.8607 114.183 58.1524C114.216 57.4489 114.182 56.7397 114.078 56.0438L116.099 55.7483ZM122.699 63.6907C123.284 63.0752 123.782 62.4002 124.216 61.6934L122.469 60.648C122.091 61.2635 121.67 61.8275 121.193 62.3278L121.174 62.3479L121.156 62.3689C120.821 62.76 120.451 63.1255 120.049 63.4636L121.377 64.9971C121.851 64.5971 122.295 64.1614 122.699 63.6907ZM104.022 65.3134C103.054 64.5224 102.195 63.5946 101.478 62.5626L103.163 61.4218C103.773 62.3001 104.504 63.089 105.325 63.7601L104.022 65.3134ZM113.291 67.3675C112.992 67.9185 112.707 68.4245 112.431 68.8956L110.932 68.0411L110.919 68.175C110.29 68.1135 109.669 68.0072 109.062 67.8537C108.443 67.7015 107.839 67.5015 107.256 67.2583L108.051 65.4004C108.54 65.6042 109.044 65.771 109.559 65.8975L109.567 65.8993C110.069 66.0267 110.589 66.1162 111.12 66.1681L111.008 67.2847C111.167 67.0043 111.33 66.7102 111.497 66.4004L111.506 66.3845L111.515 66.3689C111.886 65.7399 112.231 65.0871 112.541 64.417L114.4 65.2556C114.063 65.983 113.69 66.689 113.291 67.3675ZM118.206 66.9662C117.074 67.4704 115.87 67.8304 114.648 68.0361L114.304 66.0481C115.358 65.8707 116.394 65.5604 117.366 65.1279L118.206 66.9662ZM110.495 71.8871C109.813 72.8372 109.122 73.7086 108.347 74.6812L106.741 73.4342C107.518 72.4587 108.179 71.6246 108.828 70.7215L110.495 71.8871ZM106.21 77.3977C105.596 78.1977 104.917 79.1048 104.149 80.1657L102.486 78.9943C103.265 77.9169 103.956 76.9943 104.581 76.1802L106.21 77.3977ZM102.164 82.9812C101.851 83.4363 101.525 83.9137 101.186 84.4153L99.4856 83.2967C99.8278 82.7901 100.157 82.3076 100.474 81.8472L102.164 82.9812Z" fill="#D6D6D6"/>
<path d="M134.841 18.7405C134.308 20.6602 132.176 21.3583 130.043 20.1366C127.733 19.0895 126.133 18.2169 126.489 16.4717C127.022 14.7265 129.154 14.552 131.642 14.3775C134.664 14.0284 135.197 16.8207 134.841 18.7405Z" fill="#E4E4E4"/>
<path d="M117.605 20.4854C118.493 22.056 120.981 23.1032 122.759 21.5325C124.714 19.7873 126.313 18.5656 125.424 16.8204C124.536 15.2498 123.114 15.7733 120.093 16.1224C117.605 16.6459 116.539 18.7402 117.605 20.4854Z" fill="#E4E4E4"/>
<path d="M125.423 14.0267C126.667 13.8522 127.911 14.5503 128.267 15.5974C128.445 15.9464 128.622 16.47 128.622 16.819C128.978 19.2623 128.089 21.3565 126.667 21.5311C125.068 21.8801 123.468 20.1349 123.291 17.8662C123.291 17.1681 123.291 16.819 123.291 16.2955C123.468 15.0738 124.179 14.2012 125.423 14.0267C125.601 14.0267 125.423 14.0267 125.423 14.0267Z" fill="#CCCCCC"/>
<path d="M148.157 73.7325V113.865C148.157 119.411 143.661 123.848 137.939 123.848H65.5965C59.9767 123.848 55.3787 119.411 55.3787 113.865V73.5308C55.3787 73.3291 55.3787 73.1275 55.4808 72.9258H78.7775C82.2516 72.9258 85.1126 75.6484 85.1126 79.1776C85.1126 80.8918 85.8278 82.5052 86.9518 83.6144C88.1779 84.8244 89.6084 85.4295 91.4476 85.4295H112.19C115.664 85.4295 118.525 82.7069 118.525 79.1776C118.525 77.4634 119.24 75.85 120.364 74.7408C121.59 73.5308 123.021 72.9258 124.758 72.9258H147.952C148.157 73.1275 148.157 73.43 148.157 73.7325Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M54.8498 71.918H78.778C82.8056 71.918 86.1349 75.0814 86.1349 79.1782C86.1349 80.6219 86.7403 81.9797 87.6748 82.9019C88.709 83.9225 89.8794 84.4216 91.4481 84.4216H112.19C115.111 84.4216 117.504 82.1399 117.504 79.1782C117.504 77.1935 118.329 75.3245 119.642 74.0284C121.054 72.6353 122.742 71.918 124.758 71.918H148.376L148.675 72.2133C148.971 72.5052 149.088 72.8462 149.137 73.1115C149.179 73.3422 149.179 73.5742 149.179 73.7097L149.179 113.866C149.179 119.975 144.219 124.857 137.939 124.857H65.597C59.4263 124.857 54.3574 119.982 54.3574 113.866V73.5313C54.3574 73.5217 54.3573 73.5114 54.3573 73.5003C54.3565 73.3076 54.3547 72.8952 54.5674 72.4754L54.8498 71.918ZM56.401 73.9347V113.866C56.401 118.842 60.5281 122.84 65.597 122.84H137.939C143.104 122.84 147.135 118.848 147.135 113.866V73.9347H124.758C123.301 73.9347 122.128 74.4274 121.087 75.4544C120.153 76.3766 119.547 77.7344 119.547 79.1782C119.547 83.2749 116.218 86.4384 112.19 86.4384H91.4481C89.3385 86.4384 87.6479 85.7275 86.2298 84.328C84.9164 83.0318 84.0913 81.1628 84.0913 79.1782C84.0913 76.2164 81.6986 73.9347 78.778 73.9347H56.401Z" fill="#CCCCCC"/>
<path d="M90.1099 98.9004C91.4046 98.9004 92.4542 97.8646 92.4542 96.5869C92.4542 95.3092 91.4046 94.2734 90.1099 94.2734C88.8152 94.2734 87.7656 95.3092 87.7656 96.5869C87.7656 97.8646 88.8152 98.9004 90.1099 98.9004Z" fill="#CCCCCC"/>
<path d="M113.426 98.9004C114.721 98.9004 115.771 97.8646 115.771 96.5869C115.771 95.3092 114.721 94.2734 113.426 94.2734C112.132 94.2734 111.082 95.3092 111.082 96.5869C111.082 97.8646 112.132 98.9004 113.426 98.9004Z" fill="#CCCCCC"/>
<path d="M105.569 114.095H98.2197C97.0793 114.095 96.1289 113.158 96.1289 112.032C96.1289 110.907 97.0793 109.969 98.2197 109.969H105.506C106.646 109.969 107.597 110.907 107.597 112.032C107.66 113.158 106.71 114.095 105.569 114.095Z" fill="#CCCCCC"/>
<path d="M160.81 53.0615C163.124 53.0615 165 51.2105 165 48.9272C165 46.6439 163.124 44.793 160.81 44.793C158.497 44.793 156.621 46.6439 156.621 48.9272C156.621 51.2105 158.497 53.0615 160.81 53.0615Z" fill="#E4E4E4"/>
<path d="M156.621 39.6507C158.201 39.6507 159.482 38.3866 159.482 36.8273C159.482 35.268 158.201 34.0039 156.621 34.0039C155.041 34.0039 153.76 35.268 153.76 36.8273C153.76 38.3866 155.041 39.6507 156.621 39.6507Z" fill="#E4E4E4"/>
<path d="M40.7497 48.9281C42.3298 48.9281 43.6107 47.664 43.6107 46.1047C43.6107 44.5453 42.3298 43.2812 40.7497 43.2812C39.1696 43.2812 37.8887 44.5453 37.8887 46.1047C37.8887 47.664 39.1696 48.9281 40.7497 48.9281Z" fill="#E4E4E4"/>
<path d="M34.3133 111.042C37.2477 111.042 39.6266 108.694 39.6266 105.798C39.6266 102.902 37.2477 100.555 34.3133 100.555C31.3788 100.555 29 102.902 29 105.798C29 108.694 31.3788 111.042 34.3133 111.042Z" fill="#E4E4E4"/>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,9 @@
<svg width="42" height="43" viewBox="0 0 42 43" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.000366211" width="34.955" height="41.9994" rx="1.5" fill="#E8E8E8"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.94183 16.0193C8.39636 16.0193 9.57542 14.8402 9.57542 13.3856C9.57542 11.931 8.39636 10.752 6.94183 10.752C5.48729 10.752 4.30823 11.931 4.30823 13.3856C4.30823 14.8402 5.48729 16.0193 6.94183 16.0193Z" fill="#BBBBBB"/>
<path d="M28.582 28.4344L34.4745 33.8935C34.7809 34.1774 34.9551 34.5761 34.9551 34.9938V40.4998C34.9551 41.3283 34.2835 41.9998 33.4551 41.9998L1.5 41.9998C0.671574 41.9998 0 41.3283 0 40.4998L0 35.1107C0 34.6262 0.233987 34.1716 0.628236 33.89L5.21502 30.6143C5.71198 30.2594 6.3745 30.2412 6.8902 30.5683L10.2548 32.7023C10.746 33.0138 11.3729 33.0134 11.8635 32.7011L16.9004 29.4959L23.3 24.9249C23.8967 24.4987 24.714 24.5664 25.2325 25.0849L28.582 28.4344Z" fill="#D3D3D3"/>
<path d="M14.9572 8.7305C14.9572 8.35241 15.2637 8.0459 15.6418 8.0459L39.7315 8.0459C40.1096 8.0459 40.4161 8.35241 40.4161 8.7305V20.0908C40.4161 20.4689 40.1096 20.7754 39.7315 20.7754L15.6418 20.7754C15.2637 20.7754 14.9572 20.4689 14.9572 20.0908L14.9572 8.7305Z" fill="#4479fb"/>
<path d="M32.0808 13.602H34.612V16.763C34.3098 16.8673 33.9635 16.9529 33.573 17.0197C33.1826 17.0839 32.7734 17.116 32.3456 17.116C31.7813 17.116 31.2866 17.0063 30.8613 16.7871C30.4361 16.5678 30.1045 16.2348 29.8665 15.7882C29.6285 15.339 29.5095 14.772 29.5095 14.0874C29.5095 13.4723 29.6272 12.9415 29.8625 12.4949C30.0979 12.0456 30.4442 11.6993 30.9015 11.456C31.3614 11.2099 31.9244 11.0869 32.5902 11.0869C32.9566 11.0869 33.3043 11.1217 33.6332 11.1912C33.9621 11.2607 34.2483 11.349 34.4916 11.456L33.9902 12.6995C33.7789 12.5952 33.5597 12.5176 33.3323 12.4668C33.105 12.4133 32.8603 12.3866 32.5983 12.3866C32.2479 12.3866 31.9658 12.4655 31.7519 12.6233C31.5406 12.781 31.3868 12.9923 31.2906 13.2571C31.1943 13.5191 31.1462 13.8093 31.1462 14.1275C31.1462 14.4912 31.197 14.7988 31.2986 15.0501C31.4029 15.2988 31.554 15.4887 31.7519 15.6197C31.9524 15.7481 32.1945 15.8123 32.4779 15.8123C32.5715 15.8123 32.6852 15.8056 32.8189 15.7922C32.9553 15.7789 33.0582 15.7628 33.1278 15.7441V14.8255H32.0808V13.602Z" fill="white"/>
<path d="M26.5655 11.1699C27.309 11.1699 27.8652 11.3317 28.2342 11.6553C28.606 11.9789 28.7918 12.4388 28.7918 13.0352C28.7918 13.3026 28.753 13.5594 28.6755 13.8054C28.6006 14.0514 28.4763 14.2707 28.3024 14.4632C28.1313 14.6558 27.9026 14.8082 27.6165 14.9205C27.333 15.0329 26.9827 15.089 26.5655 15.089H26.1203V17.0345H24.5358V11.1699H26.5655ZM26.5294 12.4495H26.1203V13.7974H26.4331C26.5695 13.7974 26.6966 13.7746 26.8142 13.7292C26.9319 13.681 27.0255 13.6048 27.095 13.5005C27.1672 13.3936 27.2033 13.2518 27.2033 13.0753C27.2033 12.8908 27.1485 12.741 27.0389 12.626C26.9292 12.5084 26.7594 12.4495 26.5294 12.4495Z" fill="white"/>
<path d="M21.1798 18.8757C21.0006 18.8757 20.8441 18.8664 20.7104 18.8477C20.574 18.8316 20.4564 18.8129 20.3574 18.7915V17.56C20.443 17.5761 20.5339 17.5934 20.6302 17.6122C20.7265 17.6336 20.8308 17.6443 20.9431 17.6443C21.133 17.6443 21.28 17.6055 21.3843 17.5279C21.4913 17.4504 21.5662 17.334 21.609 17.1789C21.6518 17.0238 21.6731 16.8299 21.6731 16.5973V11.1699H23.2657V16.4609C23.2657 17.0492 23.1774 17.5199 23.0009 17.8729C22.8244 18.2259 22.5797 18.4813 22.2668 18.6391C21.9539 18.7969 21.5916 18.8757 21.1798 18.8757Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,37 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 1C4 0.447715 4.44772 0 5 0H20L28 8V27C28 27.5523 27.5523 28 27 28H5C4.44772 28 4 27.5523 4 27V1Z" fill="#E8E8E8"/>
<rect x="18" y="11" width="6" height="2" fill="#E14747"/>
<rect x="15" y="15" width="9" height="2" fill="#E14747"/>
<rect x="15" y="19" width="9" height="2" fill="#E14747"/>
<foreignObject x="17.2817" y="-2.71828" width="13.4366" height="13.4366"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1.36px);clip-path:url(#bgblur_0_5358_15422_clip_path);height:100%;width:100%"></div></foreignObject><g opacity="0.353617" filter="url(#filter0_i_5358_15422)" data-figma-bg-blur-radius="2.71828">
<path fill-rule="evenodd" clip-rule="evenodd" d="M20 0L28 8H21C20.4477 8 20 7.55228 20 7L20 0Z" fill="#BBBBBB" style="mix-blend-mode:multiply"/>
</g>
<foreignObject x="-2" y="8" width="16" height="16"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1px);clip-path:url(#bgblur_1_5358_15422_clip_path);height:100%;width:100%"></div></foreignObject><g filter="url(#filter1_i_5358_15422)" data-figma-bg-blur-radius="2">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 11C0 10.4477 0.447715 10 1 10H11C11.5523 10 12 10.4477 12 11V21C12 21.5523 11.5523 22 11 22H1C0.447715 22 0 21.5523 0 21V11Z" fill="#E14747" style="mix-blend-mode:multiply"/>
</g>
<path d="M3.72438 20C3.65771 20 3.60104 19.9767 3.55437 19.93C3.50771 19.8833 3.48438 19.8267 3.48438 19.76V13.25C3.48438 13.1767 3.50771 13.1167 3.55437 13.07C3.60104 13.0233 3.65771 13 3.72438 13H6.40438C6.92438 13 7.37771 13.0833 7.76438 13.25C8.15104 13.41 8.45104 13.6567 8.66437 13.99C8.87771 14.3167 8.98438 14.7267 8.98438 15.22C8.98438 15.72 8.87771 16.1333 8.66437 16.46C8.45104 16.78 8.15104 17.02 7.76438 17.18C7.37771 17.34 6.92438 17.42 6.40438 17.42H4.91438V19.76C4.91438 19.8267 4.89104 19.8833 4.84438 19.93C4.80438 19.9767 4.74771 20 4.67438 20H3.72438ZM4.89438 16.31H6.35438C6.74104 16.31 7.03771 16.22 7.24438 16.04C7.45104 15.8533 7.55438 15.58 7.55438 15.22C7.55438 14.8867 7.45771 14.62 7.26438 14.42C7.07104 14.2133 6.76771 14.11 6.35438 14.11H4.89438V16.31Z" fill="white"/>
<defs>
<filter id="filter0_i_5358_15422" x="17.2817" y="-2.71828" width="13.4366" height="13.4366" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.4"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.91654 0 0 0 0 0.958014 0 0 0 0 1 0 0 0 0.640867 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_5358_15422"/>
</filter>
<clipPath id="bgblur_0_5358_15422_clip_path" transform="translate(-17.2817 2.71828)"><path fill-rule="evenodd" clip-rule="evenodd" d="M20 0L28 8H21C20.4477 8 20 7.55228 20 7L20 0Z"/>
</clipPath><filter id="filter1_i_5358_15422" x="-2" y="8" width="16" height="16" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.4"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 0.890233 0 0 0 0 0.890233 0 0 0 1 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_5358_15422"/>
</filter>
<clipPath id="bgblur_1_5358_15422_clip_path" transform="translate(2 -8)"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 11C0 10.4477 0.447715 10 1 10H11C11.5523 10 12 10.4477 12 11V21C12 21.5523 11.5523 22 11 22H1C0.447715 22 0 21.5523 0 21V11Z"/>
</clipPath></defs>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,32 @@
<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="34.9563" height="42" rx="1.5" fill="#E8E8E8"/>
<rect x="4" y="26.4336" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="11.72" y="26.4336" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="7.86389" y="30.2939" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="19.4398" y="26.4336" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="27.1595" y="26.4336" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="15.5836" y="30.2939" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="23.3035" y="30.2939" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="4" y="18.7129" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="11.72" y="18.7129" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="7.85596" y="22.5723" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="19.4398" y="18.7129" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="27.1595" y="18.7129" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="15.5836" y="22.5723" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="23.3035" y="22.5723" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="4" y="10.9912" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="11.72" y="10.9912" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="7.86389" y="14.8516" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="19.4398" y="10.9912" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="27.1595" y="10.9912" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="15.5836" y="14.8516" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="23.3035" y="14.8516" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="4" y="34.1533" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="11.72" y="34.1533" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="19.4398" y="34.1533" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="27.1595" y="34.1533" width="3.86037" height="3.86037" fill="#D3D3D3"/>
<rect x="16.1711" y="6.86035" width="25.8289" height="12.9144" rx="0.45" fill="#4479fb"/>
<path d="M35.5525 12.497H38.1204V15.7038C37.8138 15.8097 37.4625 15.8965 37.0664 15.9643C36.6703 16.0294 36.2552 16.062 35.8211 16.062C35.2486 16.062 34.7467 15.9507 34.3153 15.7283C33.8839 15.5058 33.5475 15.168 33.306 14.7149C33.0646 14.2591 32.9438 13.684 32.9438 12.9894C32.9438 12.3654 33.0632 11.8268 33.302 11.3738C33.5407 10.918 33.8921 10.5666 34.356 10.3197C34.8227 10.0701 35.3938 9.94531 36.0693 9.94531C36.441 9.94531 36.7937 9.98058 37.1274 10.0511C37.4611 10.1217 37.7514 10.2112 37.9983 10.3197L37.4896 11.5813C37.2753 11.4755 37.0528 11.3968 36.8222 11.3453C36.5916 11.291 36.3434 11.2639 36.0775 11.2639C35.7221 11.2639 35.4358 11.3439 35.2188 11.504C35.0044 11.6641 34.8484 11.8784 34.7508 12.147C34.6531 12.4129 34.6043 12.7072 34.6043 13.0301C34.6043 13.3991 34.6558 13.7111 34.7589 13.9661C34.8647 14.2184 35.018 14.4111 35.2188 14.544C35.4223 14.6742 35.6678 14.7393 35.9554 14.7393C36.0503 14.7393 36.1656 14.7326 36.3013 14.719C36.4397 14.7054 36.5441 14.6892 36.6147 14.6702V13.7382H35.5525V12.497Z" fill="white"/>
<path d="M31.8788 15.9801H29.7707L27.5975 11.7884H27.5609C27.5745 11.9159 27.5867 12.0692 27.5975 12.2482C27.6084 12.4273 27.6179 12.6104 27.626 12.7976C27.6342 12.9821 27.6382 13.149 27.6382 13.2982V15.9801H26.2139V10.0303H28.3138L30.4788 14.165H30.5033C30.4951 14.0348 30.487 13.8842 30.4788 13.7133C30.4707 13.5397 30.4626 13.3647 30.4544 13.1883C30.449 13.012 30.4463 12.856 30.4463 12.7203V10.0303H31.8788V15.9801Z" fill="white"/>
<path d="M23.0042 10.0303C23.7584 10.0303 24.3227 10.1944 24.6972 10.5227C25.0743 10.851 25.2628 11.3176 25.2628 11.9227C25.2628 12.194 25.2235 12.4544 25.1448 12.704C25.0688 12.9536 24.9427 13.1761 24.7663 13.3714C24.5927 13.5668 24.3607 13.7214 24.0704 13.8354C23.7828 13.9493 23.4274 14.0063 23.0042 14.0063H22.5525V15.9801H20.9449V10.0303H23.0042ZM22.9676 11.3285H22.5525V12.6959H22.8699C23.0083 12.6959 23.1371 12.6728 23.2565 12.6267C23.3759 12.5779 23.4708 12.5005 23.5414 12.3947C23.6146 12.2862 23.6513 12.1424 23.6513 11.9634C23.6513 11.7761 23.5956 11.6242 23.4844 11.5076C23.3732 11.3882 23.2009 11.3285 22.9676 11.3285Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,37 @@
<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 1C6 0.447716 6.44772 0 7 0H30L42 12V41C42 41.5523 41.5523 42 41 42H7C6.44772 42 6 41.5523 6 41V1Z" fill="#E8E8E8"/>
<rect x="27" y="16.5" width="9" height="3" fill="#898989"/>
<rect x="22.5" y="22.5" width="13.5" height="3" fill="#898989"/>
<rect x="22.5" y="28.5" width="13.5" height="3" fill="#898989"/>
<foreignObject x="27.2817" y="-2.71828" width="17.4366" height="17.4366"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1.36px);clip-path:url(#bgblur_0_2715_16465_clip_path);height:100%;width:100%"></div></foreignObject><g opacity="0.353617" filter="url(#filter0_i_2715_16465)" data-figma-bg-blur-radius="2.71828">
<path fill-rule="evenodd" clip-rule="evenodd" d="M30 0L42 12H31C30.4477 12 30 11.5523 30 11L30 0Z" fill="#BBBBBB" style="mix-blend-mode:multiply"/>
</g>
<foreignObject x="-2" y="13" width="22" height="22"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1px);clip-path:url(#bgblur_1_2715_16465_clip_path);height:100%;width:100%"></div></foreignObject><g filter="url(#filter1_i_2715_16465)" data-figma-bg-blur-radius="2">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 16C0 15.4477 0.447715 15 1 15H17C17.5523 15 18 15.4477 18 16V32C18 32.5523 17.5523 33 17 33H1C0.447716 33 0 32.5523 0 32V16Z" fill="#898989" style="mix-blend-mode:multiply"/>
</g>
<path d="M8.29896 30C8.19896 30 8.11396 29.965 8.04396 29.895C7.97396 29.825 7.93896 29.74 7.93896 29.64V21.345H5.16396C5.06396 21.345 4.97896 21.31 4.90896 21.24C4.83896 21.17 4.80396 21.085 4.80396 20.985V19.875C4.80396 19.765 4.83896 19.675 4.90896 19.605C4.97896 19.535 5.06396 19.5 5.16396 19.5H12.814C12.924 19.5 13.014 19.535 13.084 19.605C13.154 19.675 13.189 19.765 13.189 19.875V20.985C13.189 21.085 13.154 21.17 13.084 21.24C13.014 21.31 12.924 21.345 12.814 21.345H10.054V29.64C10.054 29.74 10.019 29.825 9.94896 29.895C9.87896 29.965 9.78896 30 9.67896 30H8.29896Z" fill="white"/>
<defs>
<filter id="filter0_i_2715_16465" x="27.2817" y="-2.71828" width="17.4366" height="17.4366" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.4"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.91654 0 0 0 0 0.958014 0 0 0 0 1 0 0 0 0.640867 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_2715_16465"/>
</filter>
<clipPath id="bgblur_0_2715_16465_clip_path" transform="translate(-27.2817 2.71828)"><path fill-rule="evenodd" clip-rule="evenodd" d="M30 0L42 12H31C30.4477 12 30 11.5523 30 11L30 0Z"/>
</clipPath><filter id="filter1_i_2715_16465" x="-2" y="13" width="22" height="22" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.4"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.845833 0 0 0 0 0.845833 0 0 0 0 0.845833 0 0 0 1 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_2715_16465"/>
</filter>
<clipPath id="bgblur_1_2715_16465_clip_path" transform="translate(2 -13)"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 16C0 15.4477 0.447715 15 1 15H17C17.5523 15 18 15.4477 18 16V32C18 32.5523 17.5523 33 17 33H1C0.447716 33 0 32.5523 0 32V16Z"/>
</clipPath></defs>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,37 @@
<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 1C6 0.447716 6.44772 0 7 0H30L42 12V41C42 41.5523 41.5523 42 41 42H7C6.44772 42 6 41.5523 6 41V1Z" fill="#E8E8E8"/>
<rect x="27" y="16.5" width="9" height="3" fill="#4479fb"/>
<rect x="22.5" y="22.5" width="13.5" height="3" fill="#4479fb"/>
<rect x="22.5" y="28.5" width="13.5" height="3" fill="#4479fb"/>
<foreignObject x="27.2817" y="-2.71828" width="17.4366" height="17.4366"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1.36px);clip-path:url(#bgblur_0_2715_16456_clip_path);height:100%;width:100%"></div></foreignObject><g opacity="0.353617" filter="url(#filter0_i_2715_16456)" data-figma-bg-blur-radius="2.71828">
<path fill-rule="evenodd" clip-rule="evenodd" d="M30 0L42 12H31C30.4477 12 30 11.5523 30 11L30 0Z" fill="#BBBBBB" style="mix-blend-mode:multiply"/>
</g>
<foreignObject x="-2" y="13" width="22" height="22"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(1px);clip-path:url(#bgblur_1_2715_16456_clip_path);height:100%;width:100%"></div></foreignObject><g filter="url(#filter1_i_2715_16456)" data-figma-bg-blur-radius="2">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 16C0 15.4477 0.447715 15 1 15H17C17.5523 15 18 15.4477 18 16V32C18 32.5523 17.5523 33 17 33H1C0.447716 33 0 32.5523 0 32V16Z" fill="#4479fb" style="mix-blend-mode:multiply"/>
</g>
<path d="M4.6192 30C4.5292 30 4.4542 29.97 4.3942 29.91C4.3342 29.85 4.3042 29.775 4.3042 29.685C4.3042 29.655 4.3092 29.625 4.3192 29.595C4.3292 29.565 4.3392 29.535 4.3492 29.505L7.7092 24.645L4.5592 19.995C4.5292 19.935 4.5142 19.875 4.5142 19.815C4.5142 19.725 4.5442 19.65 4.6042 19.59C4.6642 19.53 4.7342 19.5 4.8142 19.5H6.3592C6.4792 19.5 6.5742 19.53 6.6442 19.59C6.7142 19.65 6.7742 19.715 6.8242 19.785L9.0292 23.025L11.2492 19.785C11.2892 19.715 11.3442 19.65 11.4142 19.59C11.4942 19.53 11.5942 19.5 11.7142 19.5H13.1692C13.2592 19.5 13.3342 19.53 13.3942 19.59C13.4542 19.65 13.4842 19.725 13.4842 19.815C13.4842 19.875 13.4642 19.935 13.4242 19.995L10.2892 24.645L13.6492 29.505C13.6692 29.535 13.6842 29.565 13.6942 29.595C13.7042 29.625 13.7092 29.655 13.7092 29.685C13.7092 29.775 13.6742 29.85 13.6042 29.91C13.5442 29.97 13.4742 30 13.3942 30H11.8042C11.6842 30 11.5892 29.97 11.5192 29.91C11.4492 29.85 11.3942 29.79 11.3542 29.73L8.9542 26.34L6.5992 29.73C6.5592 29.79 6.5042 29.85 6.4342 29.91C6.3642 29.97 6.2642 30 6.1342 30H4.6192Z" fill="white"/>
<defs>
<filter id="filter0_i_2715_16456" x="27.2817" y="-2.71828" width="17.4366" height="17.4366" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.4"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.91654 0 0 0 0 0.958014 0 0 0 0 1 0 0 0 0.640867 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_2715_16456"/>
</filter>
<clipPath id="bgblur_0_2715_16456_clip_path" transform="translate(-27.2817 2.71828)"><path fill-rule="evenodd" clip-rule="evenodd" d="M30 0L42 12H31C30.4477 12 30 11.5523 30 11L30 0Z"/>
</clipPath><filter id="filter1_i_2715_16456" x="-2" y="13" width="22" height="22" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.4"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.890233 0 0 0 0 1 0 0 0 0 0.929023 0 0 0 1 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_2715_16456"/>
</filter>
<clipPath id="bgblur_1_2715_16456_clip_path" transform="translate(2 -13)"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 16C0 15.4477 0.447715 15 1 15H17C17.5523 15 18 15.4477 18 16V32C18 32.5523 17.5523 33 17 33H1C0.447716 33 0 32.5523 0 32V16Z"/>
</clipPath></defs>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="20" height="20" rx="1" fill="black" fill-opacity="0.4"/>
<rect x="5.19995" y="13.8123" width="12.1774" height="1.4" rx="0.7" transform="rotate(-45 5.19995 13.8123)" fill="white"/>
<rect x="6.18872" y="5.19995" width="12.1802" height="1.4" rx="0.7" transform="rotate(45 6.18872 5.19995)" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 418 B

View File

@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M4.26429 12.6471C4.09643 12.4767 4 12.2471 4 12.0026C4 11.7581 4.09643 11.5285 4.26429 11.3581L10.55 5.13549C10.8929 4.79473 11.4357 4.80955 11.7607 5.16513C12.0857 5.5207 12.075 6.0837 11.7321 6.42076L6.99643 11.1136H19.1429C19.6179 11.1136 20 11.51 20 12.0026C20 12.4952 19.6179 12.8915 19.1429 12.8915H6.99643L11.7357 17.5807C12.0786 17.9215 12.0893 18.4808 11.7643 18.8364C11.4393 19.1919 10.8964 19.203 10.5536 18.866L4.26786 12.6434L4.26429 12.6471Z" fill="#1F1F1F"/>
</svg>

After

Width:  |  Height:  |  Size: 574 B

View File

@@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="10" cy="10" r="10" fill="#4F85F3"/>
<rect x="4.5" y="9.29999" width="11" height="1.4" rx="0.7" fill="black"/>
<rect x="9.2998" y="15.5" width="11" height="1.4" rx="0.7" transform="rotate(-90 9.2998 15.5)" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 335 B

View File

@@ -0,0 +1,164 @@
*{
padding: 0px;
border: 0px;
margin: 0px;
font-family: "system-ui", "Segoe UI", Roboto, Oxygen, Ubuntu, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-sans;
border-color: #D7D7D7;
user-select: none;
}
html, body {
line-height: 20px;
font-size: 14px;
padding: 0px;
border: 0px;
margin: 0px;
background-color: #FFF;
}
body {
display: flex;
justify-content: center;
}
.text {
font-size: 15px;
color: #5c5c5c;
}
.comment {
font-size: 12px;
color: #353535;
font-weight: 600;
margin-top: 8px;
}
.topTool {
display: flex;
justify-content: right;
height: 60px;
width: 100%;
position: fixed;
top: 0;
left: 0;
background-color: #FFF;
padding: 0px 18px;
align-items: center;
box-sizing: border-box;
z-index: 1000;
box-shadow: 0 2px 4px 0 rgba(55, 55, 55, 0.12);
}
.returnBtn {
display: flex;
align-items: center;
gap: 5px;
font-size: 20px;
font-weight: 700;
cursor: pointer;
}
.returnBtn label {
cursor: pointer;
}
.saveBtn {
background-color: #4479fb;
padding: 9px 8px;
box-sizing: border-box;
height: 40px;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
color: #000000;
}
.container {
min-width: 1100px;
display: grid;
grid-template-columns: auto 1fr;
margin-top: 70px;
}
.Navigation{
align-self: start;
height: fit-content;
position: sticky;
top: 70px;
}
.content{
width: 890px;
padding: 28px 30px;
box-sizing: border-box;
min-height: 1000px;
}
#info, #steps, #bom, #acc, #profile {
scroll-margin-top: 60px;
}
#demoGallery {
}
hr {
margin-top: 18px;
margin-bottom: 18px;
border: none;
border-top: 1px solid #EBEBEB
}
#projectName {
font-size: 18px;
font-weight: 700;
margin-top: 14px;
}
.link {
cursor: pointer;
text-decoration: underline;
color: #B6F34F;
}
#projectAuthor {
margin-top: 8px;
font-size: 15px;
}
#projectDescription {
margin-top: 8px;
}
#projectDescription img {
max-width: 80%;
}
.subTitle {
font-size: 16px;
font-weight: 700;
}
.accessory-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.attachment {
display: inline-block;
border-radius: 2px;
border: 1px solid #DDD;
width: 230px;
font-size: 14px;
padding: 6px 16px;
display: flex;
align-items: center;
white-space: normal;
overflow-wrap: anywhere;
word-break: break-all;
cursor: pointer;
}
.attachment img {
width: 28px;
height: 28px;
margin-right: 12px;
}
.profileName {
font-size: 16px;
font-weight: 700;
}
#profileAuthor {
margin-top: 8px;
font-size: 15px;
}
#profileDescript {
margin-top: 8px;
}

View File

@@ -0,0 +1,73 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
<title>Model</title>
<link rel="stylesheet" type="text/css" href="index.css" />
<link rel="stylesheet" type="text/css" href="css/navigation.css" />
<link rel="stylesheet" type="text/css" href="css/gallery.css" />
<script type="text/javascript" src="../include/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="../include/purify.min.js"></script>
<script type="text/javascript" src="../include/globalapi.js"></script>
<script type="text/javascript" src="js/navigation.js"></script>
<script type="text/javascript" src="js/gallery.js"></script>
<script type="text/javascript" src="index.js"></script>
<script type="text/javascript" src="../data/text.js"></script>
</head>
<body>
<div class="topTool">
<div class="saveBtn trans" onclick="editorBtn()" tid='t128'>Edit</div>
</div>
<div class="container">
<div class="Navigation" id="sideNav">
<div class="rail"></div>
<div class="indicator"></div>
<ul>
<li class="nav-item active"><a href="#projectName" class="trans" tid="t129">Project information</a></li>
<li class="nav-item trans"><a href="#Accessories" class="trans" tid="t130">Accessories</a></li>
<li class="nav-item trans"><a href="#profileName" class="trans" tid="t131">Profile information</a></li>
</ul>
</div>
<div class="content">
<div id="info"></div>
<div id="projectGallery" style="margin-top:24px;"></div>
<div id="projectName" onClick="JumpToWeb()"></div>
<div id="projectAuthor"></div>
<hr>
<div class="content-group">
<div class="subTitle trans" tid="t132">Description</div>
<div class="text" id="projectDescription"></div>
</div>
<hr>
<div class="content-group" id="Accessories">
<div class="subTitle trans" tid="t130">Accessories</div>
<div class="comment" id="bom-accessories"></div>
<div class="accessory-list" id="bom-list">
<!-- <div class="attachment"><img src="img/icon_pdf.svg">3123213.pdf</div>
<div class="attachment"><img src="img/icon_pdf.svg">3123213.pdf</div>
<div class="attachment"><img src="img/icon_pdf.svg">3123213.pdf</div>
<div class="attachment"><img src="img/icon_pdf.svg">3123213.pdf</div> -->
</div>
<div class="comment" id="assembly-accessories"></div>
<div class="accessory-list" id="assembly-list"></div>
<div class="comment" id="other-accessories"></div>
<div class="accessory-list" id="other-list"></div>
</div>
<hr>
<div class="profileName trans" tid="t133">Profile Name: <label id="profileName"></label></div>
<div id="profileAuthor"></div>
<div id="profileGallery" style="margin-top:24px;"></div>
<div class="text" id="profileDescript">
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,336 @@
var m_ModelID=null;
$(function () {
// 向宿主请求数据(握手)
TranslatePage();
RequestProjectInfo();
});
function HandleStudio(pVal)
{
let strCmd=pVal['command'];
if(strCmd=='show_3mf_info')
{
const detail = pVal.model && pVal.model.model;
const name = detail ? decodeURIComponent(detail.name || '').trim() : '';
const description = detail ? decodeURIComponent(detail.description || '').trim() : '';
if (!name || !description) {
window.location.href = 'black.html';
return;
}
ShowProjectInfo( pVal['model'] );
}
else if(strCmd=='clear_3mf_info')
{
ShowProjectInfo( null );
}
else if(strCmd=='3mf_detail_set_modelid')
{
let ModelID=pVal['model_id'];
// UpdateModelID( ModelID );
}
}
//Push Command to C++
function RequestProjectInfo()
{
var tSend={};
tSend['sequence_id']=Math.round(new Date() / 1000);
tSend['command']="request_3mf_info";
SendWXMessage( JSON.stringify(tSend) );
}
function safeDecode(value) {
if (!value) return '';
try {
return decodeURIComponent(value);
} catch (err) {
return value;
}
}
function normalizeCoverName(value) {
const decoded = safeDecode(value);
if (!decoded) return '';
const segments = decoded.split(/[/\\]/);
return segments[segments.length - 1];
}
// function resetNavigation() {
// const $ul = $('#sideNav ul');
// $ul.empty();
// $ul.append('<li class="nav-item active"><a href="#projectName">Project information</a></li>');
// }
// function addNavItem(anchor, label) {
// const $ul = $('#sideNav ul');
// if ($ul.find(`a[href="${anchor}"]`).length === 0) {
// $ul.append(`<li class="nav-item"><a href="${anchor}">${label}</a></li>`);
// }
// }
// function removeNavItem(anchor) {
// $('#sideNav ul').find(`a[href="${anchor}"]`).parent().remove();
// }
function ShowProjectInfo( p3MF )
{
//Check Data
// resetNavigation();
if (!p3MF) {
$("#projectName").text('');
$("#projectAuthor").text('');
$("#projectDescription").html('');
$('#projectGallery').hide();
$("#profileName").text('');
$("#profileAuthor").text('');
$("#profileDescript").html('');
// removeNavItem('#Accessories');
// removeNavItem('#profileName');
return;
}
let pModel=p3MF['model'];
let pFile=p3MF['file'];
let pProfile=p3MF['profile'];
ShowModelInfo( pModel );
ShowFileInfo( pFile );
ShowProfileInfo( pProfile );
}
function ShowModelInfo(pModel)
{
//==========Model Info==========
// 先完整解码,再按白名单净化,保留安全样式与 https 图片
let rawName = decodeURIComponent(pModel.name);
let rawAuthor = decodeURIComponent(pModel.author);
let rawDesc = decodeURIComponent(pModel.description);
rawDesc = HtmlDecodeFrom3MF(rawDesc);
const sanitizeCfg = {
ADD_TAGS: ['span','img','font','u','s','a'],
ADD_ATTR: ['style','color','href','target','rel','src','alt'],
ALLOWED_URI_REGEXP: /^(?:(?:https?|data|blob):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i
};
if( pModel.hasOwnProperty('model_id') )
{
let m_id=pModel['model_id']+'';
m_ModelID = m_id.trim();
if (m_ModelID != "") {
if( !$('#projectName').hasClass('link') );
$("#projectName").addClass("link");
}else {
$("#projectName").removeClass("link");
}
}
let sModelName=DOMPurify.sanitize(rawName);
let sModelAuthor=DOMPurify.sanitize(rawAuthor);
let UploadType=pModel.upload_type.toLowerCase();
let sLicence=pModel.license.toUpperCase();
let sModelDesc=DOMPurify.sanitize(rawDesc, sanitizeCfg);
let ModelPreviewList=pModel.preview_img;
let modelImages=[];
const projectCover = normalizeCoverName(pModel.cover_img);
$("#projectName").text(sModelName);
$("#projectAuthor").text(sModelAuthor);
$("#projectDescription").html(sModelDesc);
if(ModelPreviewList && ModelPreviewList.length > 0) {
const previews = ModelPreviewList.slice();
if (projectCover) {
const coverIndex = previews.findIndex(function(item){
if (!item || !item.filename) return false;
const filename = normalizeCoverName(item.filename);
return filename === projectCover;
});
if (coverIndex > 0) {
const coverItem = previews.splice(coverIndex, 1)[0];
previews.unshift(coverItem);
}
}
let TotalPreview = previews.length;
for(let pn=0;pn<TotalPreview;pn++) {
let FTmpPath=previews[pn]['filepath'];
modelImages.push( FTmpPath );
}
$('#projectGallery').bsGallery({ images: modelImages, mainHeight: 420 });
$('#projectGallery').css("display", 'flex');
}else {
$('#projectGallery').css("display", 'none');
}
}
function HtmlDecodeFrom3MF(strInput)
{
const el = document.createElement('textarea');
el.innerHTML = strInput;
el.innerHTML = el.value;
return el.value;
}
function ShowFileInfo( pFile ){
let pBOM=pFile['BOM'];
let pAssembly=pFile['Assembly'];
let pOther=pFile['Other'];
let BTotal=pBOM.length;
let ATotal=pAssembly.length;
let OTotal=pOther.length;
let fTotal=BTotal+ATotal+OTotal;
// if(fTotal==0){
// removeNavItem('#Accessories');
// return;
// } else {
// addNavItem('#Accessories', 'Accessories');
// }
if (BTotal>0){
$("#bom-accessories").text("Bill of Materials (" + BTotal + ")");
ConstructFileHtml( "bom-list", pBOM );
}
if (ATotal>0){
$("#assembly-accessories").text("Assembly Guide (" + ATotal + ")");
ConstructFileHtml( "assembly-list", pAssembly );
}
if (OTotal>0){
$("#other-accessories").text("Other (" + OTotal + ")");
ConstructFileHtml( "other-list", pOther );
}
}
function ShowProfileInfo( pProfile )
{
const sanitizeCfg = {
ADD_TAGS: ['span','img','font','u','s','a'],
ADD_ATTR: ['style','color','href','target','rel','src','alt'],
ALLOWED_URI_REGEXP: /^(?:(?:https?|data|blob):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i
};
let sProfileName=DOMPurify.sanitize(decodeURIComponent(pProfile.name));
let sProfileAuthor=DOMPurify.sanitize(decodeURIComponent(pProfile.author));
let sProfileDesc=HtmlDecodeFrom3MF(decodeURIComponent(pProfile.description));
sProfileDesc=DOMPurify.sanitize(sProfileDesc, sanitizeCfg);
let ModelPreviewList=pProfile.preview_img;
let modelImages=[];
const profileCover = normalizeCoverName(pProfile.cover_img);
$("#profileName").text(sProfileName);
$("#profileAuthor").text(sProfileAuthor);
$("#profileDescript").html(sProfileDesc);
// removeNavItem('#profileName');
// if(sProfileName) {
// addNavItem('#profileName', 'Profile information');
// }
if(ModelPreviewList && ModelPreviewList.length > 0) {
const previews = ModelPreviewList.slice();
if (profileCover) {
const coverIndex = previews.findIndex(function(item){
if (!item || !item.filename) return false;
const filename = normalizeCoverName(item.filename);
return filename === profileCover;
});
if (coverIndex > 0) {
const coverItem = previews.splice(coverIndex, 1)[0];
previews.unshift(coverItem);
}
}
let TotalPreview = previews.length;
for(let pn=0;pn<TotalPreview;pn++) {
let FTmpPath=previews[pn]['filepath'];
modelImages.push( FTmpPath );
}
$('#profileGallery').bsGallery({ images: modelImages, mainHeight: 420 });
$('#profileGallery').css("display", 'flex');
}else {
$('#profileGallery').css("display", 'none');
}
}
var ExcelTail=['xlsx','xlsm','xlsb','csv','xls','xltx','xltm','xlt','xlam','xla'];
var TxtTail=['txt'];
var PdfTail=['pdf','fdf','xfdf','xdp','ppdf','ofd'];
var JpgTail=['jpg','jpeg'];
var PngTail=['png'];
function ConstructFileHtml( ID, pItem ){
let fTotal=pItem.length;
let strHtml='';
for( let f=0;f<fTotal;f++ ){
let pOne=pItem[f];
let tPath=pOne['filepath'];
let tName=decodeURIComponent(pOne['filename']);
let sTail=getFileTail(tName).toLowerCase();
let ImgPath='img/icon_txt.svg';
if( $.inArray( sTail, JpgTail )>=0 ){
ImgPath='img/icon_jpg.svg';
}
else if( $.inArray( sTail, PngTail )>=0 ){
ImgPath='img/icon_png.svg';
}
else if( $.inArray( sTail, ExcelTail )>=0 ){
ImgPath='img/icon_xcl.svg';
}
else if( $.inArray( sTail, PdfTail )>=0 ){
ImgPath='img/icon_pdf.svg';
}
// base64 图片不发送外部打开指令
let onclick = '';
if (tPath) {
onclick = ' onClick="OnClickOpenFile(\''+tPath+'\')"';
}
strHtml+='<div class="attachment"'+onclick+'><img src="'+ImgPath+'">'+tName+'</div>';
}
$("#"+ID).html( strHtml );
if( fTotal>0 ) {$("#"+ID).show();}
}
function OnClickOpenFile( strFullPath )
{
if (!strFullPath) return;
if(isBase64String(strFullPath)) {
showBase64ImageLayer(strFullPath);
return;
}
var tSend={};
tSend['sequence_id']=Math.round(new Date() / 1000);
tSend['command']="open_3mf_accessory";
tSend['accessory_path']=strFullPath;
SendWXMessage( JSON.stringify(tSend) );
SendWXDebugInfo('----open accessory: '+strFullPath);
}
function editorBtn(){
window.location.href = 'editor.html';
}
function JumpToWeb()
{
if(m_ModelID=='')
return;
var tSend={};
tSend['sequence_id']=Math.round(new Date() / 1000);
tSend['command']="modelmall_model_open";
tSend['data']={};
tSend['data']['id']=m_ModelID+'';
SendWXMessage( JSON.stringify(tSend) );
}

View File

@@ -0,0 +1,174 @@
const {
ClassicEditor,
Autosave,
Essentials,
Paragraph,
ImageUtils,
ImageEditing,
Link,
List,
Alignment,
Bold,
Italic,
Underline,
AutoLink,
Heading
} = window.CKEDITOR;
const LICENSE_KEY =
'GPL';
const CKEDITOR_LANGUAGE_MAP = {
en: 'en',
zh_CN: 'zh-cn',
ja_JP: 'ja',
it_IT: 'it',
fr_FR: 'fr',
de_DE: 'de',
hu_HU: 'hu',
es_ES: 'es',
sv_SE: 'sv',
cs_CZ: 'cs',
nl_NL: 'nl',
uk_UA: 'uk',
ru_RU: 'ru',
tr_TR: 'tr',
pt_BR: 'pt-br',
ko_KR: 'ko',
pl_PL: 'pl'
};
function detectEditorLanguage() {
let lang = typeof GetQueryString === 'function' ? GetQueryString('lang') : null;
const langStorageKey = typeof LANG_COOKIE_NAME !== 'undefined' ? LANG_COOKIE_NAME : 'QIDIWebLang';
try {
if (lang && typeof localStorage !== 'undefined') {
localStorage.setItem(langStorageKey, lang);
}
} catch (err) {}
if (!lang) {
try {
if (typeof localStorage !== 'undefined') {
lang = localStorage.getItem(langStorageKey);
}
} catch (err) {
lang = null;
}
}
if (!lang && typeof navigator !== 'undefined') {
lang = navigator.language || navigator.userLanguage;
}
if (!lang) {
return 'en';
}
const normalizedUnderscore = lang.replace('-', '_');
if (CKEDITOR_LANGUAGE_MAP[normalizedUnderscore]) {
return CKEDITOR_LANGUAGE_MAP[normalizedUnderscore];
}
if (CKEDITOR_LANGUAGE_MAP[lang]) {
return CKEDITOR_LANGUAGE_MAP[lang];
}
return normalizedUnderscore.replace('_', '-').toLowerCase();
}
const editorLanguage = detectEditorLanguage();
const script = document.createElement('script');
script.src = `../include/ckeditor5/translations/${editorLanguage}.umd.js`;
const editorConfig = {
toolbar: {
items: [
'heading',
'|',
'bold',
'italic',
'underline',
'|',
'alignment',
'|',
'bulletedList',
'numberedList',
'|',
'link',
'|',
'undo',
'redo',
],
shouldNotGroupWhenFull: false
},
plugins: [Alignment, AutoLink, Autosave, Bold, Essentials, Heading, ImageEditing, ImageUtils, Italic, Link, List, Paragraph, Underline],
heading: {
options: [
{
model: 'paragraph',
title: 'Paragraph',
class: 'ck-heading_paragraph'
},
{
model: 'heading1',
view: 'h1',
title: 'Heading 1',
class: 'ck-heading_heading1'
},
{
model: 'heading2',
view: 'h2',
title: 'Heading 2',
class: 'ck-heading_heading2'
},
{
model: 'heading3',
view: 'h3',
title: 'Heading 3',
class: 'ck-heading_heading3'
},
{
model: 'heading4',
view: 'h4',
title: 'Heading 4',
class: 'ck-heading_heading4'
},
{
model: 'heading5',
view: 'h5',
title: 'Heading 5',
class: 'ck-heading_heading5'
},
{
model: 'heading6',
view: 'h6',
title: 'Heading 6',
class: 'ck-heading_heading6'
}
]
},
initialData:
'',
licenseKey: LICENSE_KEY,
link: {
addTargetToExternalLinks: true,
defaultProtocol: 'https://',
decorators: {
toggleDownloadable: {
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'file'
}
}
}
},
placeholder: '',
language: editorLanguage
};
script.onload = () => {
ClassicEditor.create(document.querySelector('#editor'), editorConfig).then( editor => {
window.projectEditor = editor;
});
ClassicEditor.create(document.querySelector('#profile-editor'), editorConfig).then( editor => {
window.profileEditor = editor;
});
};
document.head.appendChild(script);

View File

@@ -0,0 +1,742 @@
var projectName = "";
var projectPictures = [
// {
// "filepath": "",
// "filename": "",
// "size": 0
// }
];
var projectEditorData;
var bomAccessories = []; //like projectPictures structure
var assemblyAccessories = []; //like projectPictures structure
var otherAccessories = []; //like projectPictures structure
var profileName = "";
var profilePictures = [];
var profileEditorData;
var bakRequestData;
function deepCloneList(list) {
return JSON.parse(JSON.stringify(list || []));
}
function safeDecode(value) {
if (!value) return '';
try {
return decodeURIComponent(value);
} catch (err) {
return value;
}
}
function getBase64ImageFormat(base64Str) {
if (!isBase64String(base64Str)) return null;
const trimmed = base64Str.trim();
const dataUrlMatch = trimmed.match(/^data:(.*?);base64,/i);
let payload = trimmed;
if (dataUrlMatch) {
const mime = (dataUrlMatch[1] || '').toLowerCase();
payload = trimmed.slice(dataUrlMatch[0].length);
if (mime.indexOf('image/png') >= 0) return 'png';
if (mime.indexOf('image/jpeg') >= 0 || mime.indexOf('image/jpg') >= 0) return 'jpg';
}
const cleanPayload = payload.replace(/\s+/g, '');
try {
const header = atob(cleanPayload.slice(0, 16));
const bytes = header.split('').map(ch => ch.charCodeAt(0));
if (bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4E && bytes[3] === 0x47) return 'png';
if (bytes[0] === 0xFF && bytes[1] === 0xD8 && bytes[2] === 0xFF) return 'jpg';
} catch (err) {
return null;
}
return null;
}
function normalizeCoverName(value) {
const decoded = safeDecode(value);
if (!decoded) return '';
const segments = decoded.split(/[/\\]/);
return segments[segments.length - 1];
}
function normalizeRequestPayload(raw) {
const safe = raw || {};
const model = safe.model || {};
const file = safe.file || {};
const profile = safe.profile || {};
return {
model: {
name: model.name || "",
description: model.description || "",
preview_img: deepCloneList(model.preview_img),
},
file: {
BOM: deepCloneList(file.BOM),
Assembly: deepCloneList(file.Assembly),
Other: deepCloneList(file.Other),
},
profile: {
name: profile.name || "",
description: profile.description || "",
preview_img: deepCloneList(profile.preview_img),
},
};
}
function getCurrentRequestData() {
getProjectName();
getProjectDescription();
getProfileName();
getProfilePictures();
getProfileDescription();
return {
model: {
name: encodeURIComponent(projectName || ""),
description: encodeURIComponent(projectEditorData || ""),
preview_img: deepCloneList(projectPictures),
},
file: {
BOM: deepCloneList(bomAccessories),
Assembly: deepCloneList(assemblyAccessories),
Other: deepCloneList(otherAccessories),
},
profile: {
name: encodeURIComponent(profileName || ""),
description: encodeURIComponent(profileEditorData || ""),
preview_img: deepCloneList(profilePictures),
},
};
}
const editorUploadRequests = new Map();
$(function () {
TranslatePage();
addAccessoryBtnListener();
addPictureUploadListener(
'projectImageInput',
'imageList',
projectPictures,
['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/jpg'],
4 * 1024 * 1024
);
addAccessoryUploadListener(
'bom-input',
'bom-list',
bomAccessories,
{
'.xls': 10 * 1024 * 1024,
'.xlsx': 10 * 1024 * 1024,
'.pdf': 50 * 1024 * 1024
},
10
);
addAccessoryUploadListener(
'assembly-guide-input',
'assembly-list',
assemblyAccessories,
{
'.jpg': 10 * 1024 * 1024,
'.png': 10 * 1024 * 1024,
'.pdf': 50 * 1024 * 1024
},
25
);
addAccessoryUploadListener(
'other-input',
'other-list',
otherAccessories,
{
'.txt': 10 * 1024 * 1024,
},
10
);
addPictureUploadListener(
'ProfileImageInput',
'profileImageList',
profilePictures,
['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/jpg'],
4 * 1024 * 1024
);
// TestProjectData.model.preview_img=[];
// updateInfo(TestProjectData);
RequestProjectInfo();
});
function isFormEmpty() {
getProjectName();
getProjectDescription();
getProfileName();
getProfilePictures();
getProfileDescription();
const noBasics = !projectName.trim() && !projectEditorData?.trim();
const noProjectPics = projectPictures.length === 0;
const noAttachments = bomAccessories.length === 0 &&
assemblyAccessories.length === 0 &&
otherAccessories.length === 0;
const noProfileInfo = !profileName.trim() &&
!profileEditorData?.trim() &&
profilePictures.length === 0;
return noBasics && noProjectPics && noAttachments && noProfileInfo;
}
function isChange() {
if (!bakRequestData && isFormEmpty()) {
return false;
}
const baseline = normalizeRequestPayload(bakRequestData);
const current = normalizeRequestPayload(getCurrentRequestData());
return JSON.stringify(baseline) !== JSON.stringify(current);
}
function saveInfo() {
let modelData = {};
getProjectName();
if (!projectName) {
showToast("The project name is empty.");
return;
}
modelData["name"] = encodeURIComponent(projectName);
if (projectPictures.length <= 0) {
showToast("The project pictures is empty.");
return;
}
modelData["preview_img"] = projectPictures;
getProjectDescription();
if (!projectEditorData) {
showToast("The project description is empty.");
return;
}
modelData["description"] = encodeURIComponent(projectEditorData);
let fileData = {
BOM: bomAccessories,
Assembly: assemblyAccessories,
Other: otherAccessories
};
getProfileName();
getProfilePictures();
getProfileDescription();
let profileData = {
name: encodeURIComponent(profileName),
preview_img: profilePictures,
description: encodeURIComponent(profileEditorData)
};
let updateData = {
model: modelData,
file: fileData,
profile: profileData
};
var tSend={};
tSend['sequence_id']=Math.round(new Date() / 1000);
tSend['command']="update_3mf_info";
tSend['model'] = updateData;
SendWXMessage( JSON.stringify(tSend) );
}
function updateInfo(p3MF) {
projectName = DOMPurify.sanitize(decodeURIComponent(p3MF.model.name));
projectPictures.length = 0;
Array.prototype.push.apply(projectPictures, p3MF.model.preview_img || []);
let projectCover = normalizeCoverName(p3MF.model.cover_img || "");
for (let i = 0; i < projectPictures.length; i++) {
const pictureName = normalizeCoverName(projectPictures[i].filename);
if (projectCover && pictureName === projectCover){
const [item] = projectPictures.splice(i, 1);
projectPictures.unshift(item);
break;
}
}
projectEditorData = decodeURIComponent(p3MF.model.description) || '';
bomAccessories.length = 0;
Array.prototype.push.apply(bomAccessories, p3MF.file.BOM || []);
assemblyAccessories.length = 0;
Array.prototype.push.apply(assemblyAccessories, p3MF.file.Assembly || []);
otherAccessories.length = 0;
Array.prototype.push.apply(otherAccessories, p3MF.file.Other || []);
profileName = DOMPurify.sanitize(decodeURIComponent(p3MF.profile.name));
profilePictures.length = 0;
Array.prototype.push.apply(profilePictures, p3MF.profile.preview_img || []);
let profileCover = normalizeCoverName(p3MF.profile.cover_img || "");
for (let i = 0; i < profilePictures.length; i++) {
const pictureName = normalizeCoverName(profilePictures[i].filename);
if (profileCover && pictureName === profileCover){
const [item] = profilePictures.splice(i, 1);
profilePictures.unshift(item);
break;
}
}
profileEditorData = decodeURIComponent(p3MF.profile.description) || '';
setProjectName();
setProjectPictrues();
setProjectDescription();
setAccessor();
setProfileName();
setProfilePictures();
setProfileDescription();
}
function setProjectName() {
$("#projectNameInput").val(projectName);
}
function getProjectName() {
projectName = $("#projectNameInput").val();
}
function setProjectPictrues() {
setPictures('imageList', projectPictures);
}
function getProjectPictures() {
return projectPictures;
}
function setProjectDescription() {
if (window.projectEditor) {
projectEditor.setData(projectEditorData || '');
}
}
function getProjectDescription() {
if (window.projectEditor) {
projectEditorData = projectEditor.getData();
}
}
function setAccessor() {
setAccessories('bom-list', bomAccessories);
setAccessories('assembly-list', assemblyAccessories);
setAccessories('other-list', otherAccessories);
}
function setProfileName() {
$("#ProfileNameInput").val(profileName);
}
function getProfileName() {
profileName = $("#ProfileNameInput").val();
}
function setProfilePictures() {
setPictures('profileImageList', profilePictures);
}
function getProfilePictures() {
return profilePictures;
}
function setProfileDescription() {
if (window.profileEditor) {
profileEditor.setData(profileEditorData || '');
}
}
function getProfileDescription() {
if (window.profileEditor) {
profileEditorData = profileEditor.getData();
}
}
//Pictures tool
function setPictures(id, picturesList) {
let updateHtml = "";
for (let i = 0; i < picturesList.length; i++) {
let pic_filepath = picturesList[i].filepath;
if(picturesList[i].base64) {
pic_filepath = picturesList[i].base64;
}
if (i == 0) {
let html = `<div class="imagePreview" data-index="${i}" style="background-image: url('${pic_filepath}')">
<img src="img/img_del.svg" />
<div class="modelCover">Model cover</div>
</div>`;
updateHtml = html + updateHtml;
}else {
let html = `<div class="imagePreview" data-index="${i}" style="background-image: url('${pic_filepath}')">
<img src="img/img_del.svg" />
<div class="setModelCover">Set as cover</div>
</div>`;
updateHtml += html;
}
}
$(`#${id}`).html(updateHtml);
$(`#${id}`).off('click', 'img');
$(`#${id}`).on('click', 'img', function (event) {
let index = parseInt($(this).parent().data('index'));
removePictureAt(index, picturesList);
setPictures(id, picturesList);
});
$(`#${id}`).off('click', '.setModelCover');
$(`#${id}`).on('click', '.setModelCover', function (event) {
let index = parseInt($(this).parent().data('index'));
const [item] = picturesList.splice(index, 1);
picturesList.unshift(item);
setPictures(id, picturesList);
});
}
function removePictureAt(index, picturesList) {
if (index < 0 || index >= picturesList.length) {
return;
}
picturesList.splice(index, 1);
}
function addPictureUploadListener(inputId, showPictrueId, picturesList, allowTypes, maxSize, maxCount) {
const input = document.getElementById(inputId);
// input.removeEventListener('click');
input.addEventListener('click', () => {
input.value = '';
});
// input.removeEventListener('change');
input.addEventListener('change', function (event) {
const [file] = event.target.files;
if (!file) return;
// Validate file type
if (allowTypes && !allowTypes.includes(file.type)) {
showToast(GetCurrentTextByKey("t144"));
return;
}
// Validate file size
if (maxSize && file.size > maxSize) {
showToast(GetCurrentTextByKey("t145"));
return;
}
if (picturesList.length >= maxCount) {
showToast(GetCurrentTextByKey("t146"));
return;
}
uploadFileToCpp(file).then(result => {
if (result && result.path) {
fileToThumbnailBase64(file).then((base64) => {
picturesList.push({
"filepath": result.path,
"filename": file.name,
"size": file.size,
"base64": base64
});
setPictures(showPictrueId, picturesList);
// showToast('add file1'+projectPictures.length);
});
}
}).catch(error => {
showToast(GetCurrentTextByKey("t147"));
});
});
}
//accessories tool
function addAccessoryBtnListener() {
$("#accessories-btn").on("click", function (e) {
e.stopPropagation();
$(".accessory-rule-wrapper").toggle();
});
$(document).on('click', function (e) {
if (!$(e.target).closest('#accessories-btn, .accessory-rule-wrapper').length) {
$('.accessory-rule-wrapper').hide();
}
});1
}
function setAccessories(id, accessoriesList) {
let updateHtml = "";
if (accessoriesList.length > 0) {
$(`#${id}`).prev().show();
}else {
$(`#${id}`).prev().hide();
}
for (let i = 0; i < accessoriesList.length; i++) {
let acc_filepath = accessoriesList[i].filepath;
let type = "";
if (accessoriesList[i].type) {
type = getFileTail(accessoriesList[i].type);
}else {
type = getFileType(acc_filepath);
}
let iconPath = `img/icon_${type}.svg`;
let html = `<div class="attachment" data-index="${i}"><img class="attachment-icon" src="${iconPath}">${decodeURIComponent(accessoriesList[i].filename)}<img class="attachment-delete" src="img/del.svg"></div>`;
updateHtml += html;
}
$(`#${id}`).html(updateHtml);
$(`#${id}`).children('.attachment').each(function(idx) {
$(this).data('path', accessoriesList[idx]?.filepath || '');
});
$(`#${id}`).prev().children('label').text(accessoriesList.length);
$(`#${id}`).off('click', '.attachment-delete');
$(`#${id}`).on('click', '.attachment-delete', function (event) {
event.stopPropagation();
let index = parseInt($(this).parent().data('index'));
removeAccessoryAt(index, accessoriesList);
setAccessories(id, accessoriesList);
});
$(`#${id}`).off('click', '.attachment');
$(`#${id}`).on('click', '.attachment', function (event) {
if ($(event.target).closest('.attachment-delete').length) return;
const path = $(this).data('path');
OnClickOpenFile(event, path);
});
}
function removeAccessoryAt(index, accessoriesList) {
if (index < 0 || index >= accessoriesList.length) {
return;
}
accessoriesList.splice(index, 1);
}
function getFileTail(filetype) {
switch(filetype) {
case 'application/pdf':
return 'pdf';
case 'text/plain':
return 'txt';
case 'image/jpeg':
return 'jpg';
case 'image/png':
return 'png';
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
return 'xcl';
case 'application/vnd.ms-excel':
return 'xcl';
default:
return '';
}
}
function getFileType(filepath) {
let parts = filepath.split('.');
if (parts.length > 1) {
switch (parts[parts.length - 1].toLowerCase()) {
case 'pdf':
return 'pdf';
case 'txt':
return 'txt';
case 'jpg':
return 'jpg';
case 'jpet':
return 'jpg';
case 'png':
return 'png';
case 'xlsx':
case 'xls':
return 'xcl';
}
}
return getBase64ImageFormat(filepath);
}
function addAccessoryUploadListener(inputId, showAccessoryId, accessoriesList, allowTypes, maxCount) {
const input = document.getElementById(inputId);
input.addEventListener('click', () => {
input.value = '';
});
input.addEventListener('change', function (event) {
const [file] = event.target.files;
if (!file) return;
const lowerName = file.name.toLowerCase();
const matchedExt = Object.keys(allowTypes).find(ext => lowerName.endsWith(ext));
if (!matchedExt) {
showToast(GetCurrentTextByKey("t144"));
return;
}
const maxSize = allowTypes[matchedExt];
if (maxSize && file.size > maxSize) {
showToast(GetCurrentTextByKey("t145"));
return;
}
if (accessoriesList.length >= maxCount) {
showToast(GetCurrentTextByKey("t146"));
return;
}
uploadFileToCpp(file).then(result => {
if (result && result.path) {
accessoriesList.push({
"filepath": result.path,
"filename": file.name,
"size": file.size,
"type": file.type
});
setAccessories(showAccessoryId, accessoriesList);
}
}).catch(error => {
showToast(GetCurrentTextByKey("t147"));
});
});
}
//common tool
function generateSequenceId() {
return `${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
}
function uploadFileToCpp(file) {
return new Promise((resolve, reject) => {
if (!(file instanceof File)) {
reject(new Error('invalid file object'));
return;
}
const reader = new FileReader();
const sequenceId = generateSequenceId();
reader.onload = () => {
let result = reader.result;
let base64Payload = '';
if (typeof result === 'string') {
const commaIndex = result.indexOf(',');
base64Payload = commaIndex >= 0 ? result.substring(commaIndex + 1) : result;
} else if (result instanceof ArrayBuffer) {
const bytes = new Uint8Array(result);
let binary = '';
const chunk = 0x8000;
for (let i = 0; i < bytes.length; i += chunk) {
binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunk));
}
base64Payload = btoa(binary);
} else {
reject(new Error('unable to read file content'));
return;
}
const message = {
sequence_id: sequenceId,
command: 'editor_upload_file',
data: {
filename: file.name || '',
size: file.size || 0,
type: file.type || '',
base64: base64Payload
}
};
editorUploadRequests.set(sequenceId, { resolve, reject });
const canCallHost =
typeof window !== 'undefined' &&
typeof window.wx === 'object' &&
typeof window.wx.postMessage === 'function';
if (typeof SendWXMessage === 'function' && canCallHost) {
try {
SendWXMessage(JSON.stringify(message));
} catch (error) {
editorUploadRequests.delete(sequenceId);
reject(error);
}
} else {
editorUploadRequests.delete(sequenceId);
const fallbackPath = URL.createObjectURL(file);
resolve({
path: fallbackPath,
isMock: true
});
}
};
reader.onerror = () => {
reject(reader.error || new Error('failed to read file'));
};
reader.readAsDataURL(file);
});
}
function fileToThumbnailBase64(file, maxWidth = 200, quality = 0.85) {
return new Promise((resolve, reject) => {
if (!file || !file.type.startsWith('image/')) {
reject(new Error('select a valid image file'));
return;
}
const reader = new FileReader();
reader.onload = e => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.src = e.target.result;
img.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const scale = Math.min(1, maxWidth / img.width);
const width = img.width * scale;
const height = img.height * scale;
canvas.width = width;
canvas.height = height;
if (file.type === 'image/png' || file.type === 'image/webp') {
ctx.clearRect(0, 0, width, height);
} else {
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, width, height);
}
ctx.drawImage(img, 0, 0, width, height);
const outputType = ['image/png', 'image/jpeg', 'image/webp'].includes(file.type)
? file.type
: 'image/png';
const base64 = canvas.toDataURL(outputType, quality);
resolve(base64);
};
img.onerror = () => reject(new Error('invalid image file'));
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
function handleEditorMessage(rawMessage) {
let payload = rawMessage;
if (typeof rawMessage === 'string') {
try {
payload = JSON.parse(rawMessage);
} catch (error) {
return;
}
}
if (!payload || typeof payload !== 'object') {
return;
}
const command = payload.command;
if (command === 'editor_upload_file_result') {
const sequenceId = payload.sequence_id;
if (!sequenceId || !editorUploadRequests.has(sequenceId)) {
return;
}
const { resolve, reject } = editorUploadRequests.get(sequenceId);
editorUploadRequests.delete(sequenceId);
if (payload.error) {
reject(new Error(payload.error));
return;
}
resolve(payload.data || {});
return;
}
if (command === 'save_project') {
saveInfo();
return;
}
if (command === 'discard_project') {
window.location.href = 'index.html';
return;
}
if (command === 'update_3mf_info_result') {
if (payload.error) {
showToast(payload.error);
return;
}
bakRequestData = JSON.parse(JSON.stringify(getCurrentRequestData()));
showToast(payload.message || 'Saved successfully.');
window.location.href = "index.html";
}
}
function OnClickOpenFile( evt, strFullPath ) {
if (!strFullPath) return;
if (evt && $(evt.target).closest('.attachment-delete').length) {
return;
}
if(isBase64String(strFullPath)) {
showBase64ImageLayer(strFullPath);
return;
}
var tSend={};
tSend['sequence_id']=Math.round(new Date() / 1000);
tSend['command']="open_3mf_accessory";
tSend['accessory_path']=strFullPath;
SendWXMessage( JSON.stringify(tSend) );
SendWXDebugInfo('----open accessory: '+strFullPath);
}
function returnBtn() {
if (isChange()) {
confirmSave();
}else {
if (bakRequestData) {
window.location.href = "index.html";
}else {
window.location.href = "black.html";
}
}
}
function confirmSave() {
var tSend={};
tSend['sequence_id']=Math.round(new Date() / 1000);
tSend['command']="request_confirm_save_project";
SendWXMessage( JSON.stringify(tSend) );
}
function RequestProjectInfo()
{
var tSend={};
tSend['sequence_id']=Math.round(new Date() / 1000);
tSend['command']="request_3mf_info";
SendWXMessage( JSON.stringify(tSend) );
}
function HandleStudio(pVal)
{
let strCmd=pVal['command'];
if(strCmd=='show_3mf_info')
{
updateInfo( pVal['model'] );
bakRequestData = JSON.parse(JSON.stringify(getCurrentRequestData()));
}
}
window.HandleEditor = handleEditorMessage;

View File

@@ -0,0 +1,155 @@
/*
* Simple Gallery (jQuery 2.1.1)
* 用法:
* $('#el').bsGallery({ images: ['a.jpg','b.jpg', ...] });
* 可选项:
* initialIndex, loop, thumbWidth, thumbHeight, mainHeight, counter
*/
(function($){
'use strict';
var defaults = {
images: [], // 必填:图片数组(字符串或 {src, thumb}
initialIndex: 0,
loop: true,
thumbHeight: 100,
mainHeight: 420,
// 新增:主图宽度与缩略栏宽度(可用数字或带单位字符串,如 '600px'、'60%'}
mainWidth: 560,
thumbsWidth: 180,
counter: true
};
function buildDom($root, settings){
$root.addClass('bs-gallery');
var $main = $('<div class="bs-gallery-main" />');
var $img = $('<img class="bs-gallery-image" alt="" />');
var $counter = $('<div class="bs-gallery-counter" />');
var $thumbs = $('<div class="bs-gallery-thumbs" />');
$main.append($img);
if (settings.counter) $main.append($counter);
$root.append($main).append($thumbs);
// 尺寸
$main.css({ height: settings.mainHeight + 'px' });
$thumbs.css({ maxHeight: settings.mainHeight + 'px' });
// 应用主图宽度与缩略栏宽度
if (settings.mainWidth != null) {
var mw = typeof settings.mainWidth === 'number' ? (settings.mainWidth + 'px') : settings.mainWidth;
$main.css({ width: mw });
// 固定主图宽度,避免被 flex 拉伸
$main.css({ flex: '0 0 ' + mw });
}
if (settings.thumbsWidth != null) {
var tw = typeof settings.thumbsWidth === 'number' ? (settings.thumbsWidth + 'px') : settings.thumbsWidth;
$thumbs.css({ width: tw });
}
// 生成缩略图
$.each(settings.images, function(i, it){
var src = typeof it === 'string' ? it : it.src;
var thumb = typeof it === 'string' ? it : (it.thumb || it.src);
var $t = $('<div class="bs-gallery-thumb" />').attr('data-index', i);
var $ti = $('<img />').attr('src', thumb).attr('alt','');
$t.append($ti);
$thumbs.append($t);
});
// 返回引用
return { $main:$main, $img:$img, $counter:$counter, $thumbs:$thumbs };
}
function plugin($root, options){
// 清理旧实例移除事件、数据与DOM支持重复初始化
$root.off('.bsGallery');
$root.removeData('bsGallery');
$root.removeClass('bs-gallery');
$root.empty();
var settings = $.extend({}, defaults, options||{});
if (!settings.images || !settings.images.length) return;
var ui = buildDom($root, settings);
var count = settings.images.length;
var index = Math.max(0, Math.min(settings.initialIndex, count - 1));
function srcAt(i){
var it = settings.images[i];
return typeof it === 'string' ? it : it.src;
}
function updateCounter(){
if (!settings.counter) return;
ui.$counter.text((index + 1) + '/' + count);
}
function setActiveThumb(){
ui.$thumbs.children('.bs-gallery-thumb').removeClass('active');
ui.$thumbs.children('.bs-gallery-thumb').eq(index).addClass('active');
// 确保可见
var $active = ui.$thumbs.children('.bs-gallery-thumb').eq(index);
var cTop = ui.$thumbs.scrollTop();
var cH = ui.$thumbs.height();
var tTop = $active.position().top + cTop;
var tH = $active.outerHeight();
if (tTop < cTop) ui.$thumbs.scrollTop(tTop);
else if (tTop + tH > cTop + cH) ui.$thumbs.scrollTop(tTop + tH - cH);
}
function show(i){
if (i === index) return;
index = i;
ui.$img.stop(true, true).fadeOut(120, function(){
ui.$img.attr('src', srcAt(index)).fadeIn(120);
});
updateCounter();
setActiveThumb();
}
function next(){
if (index < count - 1) show(index + 1);
else if (settings.loop) show(0);
}
function prev(){
if (index > 0) show(index - 1);
else if (settings.loop) show(count - 1);
}
// 事件:缩略图点击
ui.$thumbs.on('click', '.bs-gallery-thumb', function(){
var i = parseInt($(this).attr('data-index'), 10);
show(i);
});
// 主图点击下一张
ui.$main.on('click', function(){ next(); });
// 键盘左右切换(容器获取焦点时)
$root.attr('tabindex', 0);
$root.on('keydown.bsGallery', function(e){
if (e.which === 37) { // left
prev(); e.preventDefault();
} else if (e.which === 39) { // right
next(); e.preventDefault();
}
});
// 初始化显示
ui.$img.attr('src', srcAt(index));
setActiveThumb();
updateCounter();
// 暴露简单 API
$root.data('bsGallery', { next: next, prev: prev, show: show, index: function(){return index;}, count: function(){return count;} });
}
$.fn.bsGallery = function(options){
return this.each(function(){ plugin($(this), options); });
};
})(jQuery);

View File

@@ -0,0 +1,81 @@
// 侧边导航:导轨 + 活动短竖条
(function($){
function positionIndicator(){
var $nav = $('#sideNav');
var $active = $nav.find('.nav-item.active');
if (!$active.length) return;
var top = $active.position().top;
var height = $active.outerHeight();
$nav.find('.indicator').css({ top: top + 'px', height: height + 'px' });
}
function scrollToAnchor($item){
var href = $item.find('a').attr('href');
if (href && href.charAt(0) === '#'){
var $target = $(href);
if ($target.length){
var offset = 70; // 顶部预留,避免顶到视口边缘
$('html,body').animate({ scrollTop: Math.max(0, $target.offset().top - offset) }, 300);
}
}
}
$(function(){
positionIndicator();
$('#sideNav').on('click', '.nav-item', function(e){
e.preventDefault();
var $it = $(this);
$it.addClass('active').siblings('.nav-item').removeClass('active');
positionIndicator();
scrollToAnchor($it);
});
// 滚动联动ScrollSpy
var ticking = false;
function computeActiveByScroll(){
var scrollTop = $(window).scrollTop();
var viewportOffset = 100; // 判定阈值,提前一点触发
var $items = $('#sideNav .nav-item');
var currentId = null;
$items.each(function(){
var href = $(this).find('a').attr('href');
if (!href || href.charAt(0) !== '#') return;
var $sec = $(href);
if (!$sec.length) return;
var top = $sec.offset().top;
if (top <= scrollTop + viewportOffset){
currentId = href;
}
});
if (currentId){
var $cur = $items.filter(function(){
return $(this).find('a').attr('href') === currentId;
}).first();
if ($cur.length && !$cur.hasClass('active')){
$cur.addClass('active').siblings('.nav-item').removeClass('active');
positionIndicator();
} else {
// 位置可能变化,仍然校准指示条
positionIndicator();
}
}
}
function onScroll(){
if (!ticking){
ticking = true;
requestAnimationFrame(function(){
computeActiveByScroll();
ticking = false;
});
}
}
$(window).on('scroll', onScroll);
$(window).on('resize', function(){
positionIndicator();
computeActiveByScroll();
});
// 初始根据当前滚动位置激活一次
computeActiveByScroll();
});
})(jQuery);