@sophiacyl/dsh-plugin-waves 0.0.0-stage → 0.1.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DSH-GO-VERIFICATION.md +57 -0
- package/ICON.png +0 -0
- package/LICENSE +674 -0
- package/README.md +251 -2
- package/cordis.patch.yml +8 -0
- package/install.ps1 +0 -0
- package/install.sh +209 -0
- package/lib/client.js +1511 -0
- package/lib/host/aliashint.js +70 -0
- package/lib/host/attachments.js +25 -0
- package/lib/host/command.js +34 -0
- package/lib/host/consts.js +16 -0
- package/lib/host/dataguide.js +35 -0
- package/lib/host/imagebridge.js +41 -0
- package/lib/host/native-result.js +91 -0
- package/lib/host/native.js +191 -0
- package/lib/host/proxy.js +59 -0
- package/lib/host/results.js +67 -0
- package/lib/host/service.js +263 -0
- package/lib/host/tool.js +185 -0
- package/lib/host/troubleshoot.js +31 -0
- package/lib/host/worldbook.js +80 -0
- package/lib/index.js +74 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +136 -4
- package/service/ICON.png +0 -0
- package/service/ai/AI_DATA.md +221 -0
- package/service/knowledge/additional/manual.jsonl +5 -0
- package/service/knowledge/wiki/baike.jsonl +1231 -0
- package/service/knowledge/wiki/chengjiu.jsonl +36 -0
- package/service/knowledge/wiki/gonglve.jsonl +383 -0
- package/service/knowledge/wiki/huodong.jsonl +427 -0
- package/service/knowledge/wiki/renwu.jsonl +412 -0
- package/service/knowledge/wiki/tujian.jsonl +2889 -0
- package/service/knowledge/wiki/zixun.jsonl +47 -0
- package/service/plugins/__init__.py +0 -0
- package/service/pyproject.toml +40 -0
- package/service/rover/__init__.py +0 -0
- package/service/rover/ai_core/__init__.py +0 -0
- package/service/rover/ai_core/models.py +50 -0
- package/service/rover/ai_core/rag/__init__.py +5 -0
- package/service/rover/ai_core/rag/knowledge.py +23 -0
- package/service/rover/ai_core/register.py +86 -0
- package/service/rover/ai_core/resource.py +6 -0
- package/service/rover/ai_core/skills/__init__.py +0 -0
- package/service/rover/ai_core/skills/operations.py +8 -0
- package/service/rover/api.py +720 -0
- package/service/rover/api_render.py +161 -0
- package/service/rover/app_life.py +154 -0
- package/service/rover/aps.py +47 -0
- package/service/rover/avatar.py +85 -0
- package/service/rover/bot.py +133 -0
- package/service/rover/builtin.py +152 -0
- package/service/rover/cards/__init__.py +26 -0
- package/service/rover/cards/_shared.py +129 -0
- package/service/rover/cards/char_list.py +258 -0
- package/service/rover/cards/char_panel.py +1353 -0
- package/service/rover/cards/echo_list.py +206 -0
- package/service/rover/cards/matrix_roles.py +25 -0
- package/service/rover/cards/rank_boards.py +714 -0
- package/service/rover/cards/rank_total.py +664 -0
- package/service/rover/compat.py +215 -0
- package/service/rover/config.py +163 -0
- package/service/rover/custom_panel.py +220 -0
- package/service/rover/data_store.py +31 -0
- package/service/rover/gss.py +19 -0
- package/service/rover/handler.py +191 -0
- package/service/rover/help/__init__.py +0 -0
- package/service/rover/help/draw_new_plugin_help.py +332 -0
- package/service/rover/help/model.py +16 -0
- package/service/rover/help/utils.py +7 -0
- package/service/rover/hooks.py +420 -0
- package/service/rover/html_actions.py +236 -0
- package/service/rover/i18n.py +19 -0
- package/service/rover/knowledge.py +235 -0
- package/service/rover/logger.py +102 -0
- package/service/rover/main.py +33 -0
- package/service/rover/media.py +222 -0
- package/service/rover/message_models.py +23 -0
- package/service/rover/models.py +92 -0
- package/service/rover/native_media.py +64 -0
- package/service/rover/ocr.py +79 -0
- package/service/rover/pool.py +43 -0
- package/service/rover/restart.py +36 -0
- package/service/rover/segment.py +143 -0
- package/service/rover/server.py +131 -0
- package/service/rover/status/__init__.py +0 -0
- package/service/rover/status/models.py +10 -0
- package/service/rover/status/plugin_status.py +17 -0
- package/service/rover/subscribe.py +148 -0
- package/service/rover/sv.py +403 -0
- package/service/rover/templates/char_list.html +182 -0
- package/service/rover/templates/char_panel.html +465 -0
- package/service/rover/templates/echo_list.html +221 -0
- package/service/rover/templates/rank_all_total.html +193 -0
- package/service/rover/templates/rank_board.html +107 -0
- package/service/rover/templates/rank_level_total.html +57 -0
- package/service/rover/templates/rank_matrix_total.html +66 -0
- package/service/rover/templates/rank_phantom_total.html +180 -0
- package/service/rover/templates/rank_slash_total.html +38 -0
- package/service/rover/trigger.py +98 -0
- package/service/rover/utils/__init__.py +0 -0
- package/service/rover/utils/boardcast/__init__.py +0 -0
- package/service/rover/utils/boardcast/models.py +15 -0
- package/service/rover/utils/cookie_manager/__init__.py +0 -0
- package/service/rover/utils/cookie_manager/qrlogin.py +24 -0
- package/service/rover/utils/database/__init__.py +0 -0
- package/service/rover/utils/database/base_models.py +1771 -0
- package/service/rover/utils/database/models.py +80 -0
- package/service/rover/utils/database/startup.py +60 -0
- package/service/rover/utils/default_bg/bg.jpg +0 -0
- package/service/rover/utils/download_resource/__init__.py +0 -0
- package/service/rover/utils/download_resource/download_core.py +164 -0
- package/service/rover/utils/download_resource/download_file.py +46 -0
- package/service/rover/utils/fonts/__init__.py +0 -0
- package/service/rover/utils/fonts/fonts.py +33 -0
- package/service/rover/utils/image/__init__.py +0 -0
- package/service/rover/utils/image/convert.py +51 -0
- package/service/rover/utils/image/image_tools.py +30 -0
- package/service/rover/utils/image/utils.py +70 -0
- package/service/rover/utils/plugins_config/__init__.py +0 -0
- package/service/rover/utils/plugins_config/gs_config.py +506 -0
- package/service/rover/utils/plugins_config/models.py +182 -0
- package/service/rover/web_app.py +3 -0
- package/service/rover/webconsole/__init__.py +0 -0
- package/service/rover/webconsole/mount_app.py +26 -0
- package/service/tools/migrate.py +351 -0
- package/service/tools/regression.py +87 -0
- package/service/tools/smoke.py +63 -0
- package/service/tools/update_plugins.py +212 -0
- package/service/tools/verify_actions.py +104 -0
- package/service/tools/verify_card.py +82 -0
- package/service/tools/wwdata.py +665 -0
- package/tests/compat.test.js +181 -0
- package/tests/imagebridge.test.js +58 -0
- package/tests/media.test.js +68 -0
- package/tests/native.test.js +127 -0
- package/tests/runtime.test.js +69 -0
- package/tests/service.test.js +48 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>鸣潮练度统计</title>
|
|
6
|
+
<style>
|
|
7
|
+
@import url('{{ font_css_url }}');
|
|
8
|
+
|
|
9
|
+
* { box-sizing: border-box; }
|
|
10
|
+
html, body { margin: 0; padding: 0; background: #0f1115; }
|
|
11
|
+
body {
|
|
12
|
+
width: {{ page_w }}px;
|
|
13
|
+
font-family: 'Source Han Sans CN', 'Noto Sans CJK JP', 'Noto Sans CJK KR', sans-serif;
|
|
14
|
+
font-weight: 500;
|
|
15
|
+
color: #fff;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.container { position: relative; width: {{ page_w }}px; padding: 40px; overflow: hidden; }
|
|
19
|
+
.bg-layer { position: absolute; inset: 0; z-index: 0; }
|
|
20
|
+
.bg-layer .bg-image { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
21
|
+
.bg-layer::after { content: ""; position: absolute; inset: 0; background: rgba(0, 0, 0, .2); }
|
|
22
|
+
.page { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 30px; }
|
|
23
|
+
|
|
24
|
+
/* 绝对定位文本: 锚点与画布版一致 */
|
|
25
|
+
.t { position: absolute; white-space: nowrap; line-height: 1; transform: translateY(-50%); }
|
|
26
|
+
.t.mm { transform: translate(-50%, -50%); }
|
|
27
|
+
.ic { position: absolute; display: block; background-repeat: no-repeat; background-size: 100% 100%; }
|
|
28
|
+
|
|
29
|
+
/* 头部 */
|
|
30
|
+
.header {
|
|
31
|
+
position: relative; width: 100%;
|
|
32
|
+
background:
|
|
33
|
+
radial-gradient(circle at 100% 0%, rgba(212, 177, 99, .15) 0%, transparent 40%),
|
|
34
|
+
linear-gradient(180deg, rgba(30, 34, 42, .9) 0%, rgba(15, 17, 21, .95) 100%);
|
|
35
|
+
border-radius: 16px; padding: 22px 40px; display: flex; align-items: center;
|
|
36
|
+
border: 1px solid rgba(255, 255, 255, .08);
|
|
37
|
+
border-top: 1px solid rgba(255, 255, 255, .2);
|
|
38
|
+
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, .5);
|
|
39
|
+
}
|
|
40
|
+
.header .deco { position: absolute; top: 18px; right: 30px; font-family: 'Oswald', sans-serif; font-size: 14px; letter-spacing: 4px; color: rgba(255, 255, 255, .1); font-weight: 700; }
|
|
41
|
+
.avatar-box { position: relative; width: 110px; height: 110px; flex-shrink: 0; margin-right: 30px; border-radius: 50%; background: #222; border: 3px solid #2a2e35; box-shadow: 0 4px 10px rgba(0, 0, 0, .5); }
|
|
42
|
+
.avatar-box .ring { position: absolute; inset: -6px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, .05); border-left: 2px solid #d4b163; transform: rotate(-45deg); }
|
|
43
|
+
.avatar-box .face { position: absolute; inset: 0; border-radius: 50%; background-size: cover; background-position: center; }
|
|
44
|
+
.user-info { flex: 1; }
|
|
45
|
+
.user-row { display: flex; align-items: baseline; padding-bottom: 8px; margin-bottom: 10px; border-bottom: 1px solid rgba(255, 255, 255, .08); position: relative; }
|
|
46
|
+
.user-row::after { content: ""; position: absolute; bottom: -1px; left: 0; width: 40px; height: 2px; background: #d4b163; box-shadow: 0 0 8px #d4b163; }
|
|
47
|
+
.user-name { font-size: 40px; font-weight: 800; margin-right: 20px; text-shadow: 0 4px 10px rgba(0, 0, 0, .5); }
|
|
48
|
+
.user-uid { font-family: 'JetBrains Mono', monospace; font-size: 20px; color: #d4b163; background: rgba(0, 0, 0, .4); padding: 4px 12px; border-radius: 6px; border: 1px solid rgba(212, 177, 99, .2); letter-spacing: 1.5px; font-weight: 700; }
|
|
49
|
+
.user-stats { display: flex; gap: 40px; }
|
|
50
|
+
.stat-item { display: flex; flex-direction: column; }
|
|
51
|
+
.stat-value { font-family: 'Oswald', sans-serif; font-size: 30px; font-weight: 700; line-height: 1.1; background: linear-gradient(180deg, #fff 50%, #d4b163 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
|
|
52
|
+
.stat-label { font-size: 12px; color: #6d717a; font-weight: 700; letter-spacing: 1px; margin-top: 2px; }
|
|
53
|
+
|
|
54
|
+
/* 统计条: 底图与四项坐标照画布版 */
|
|
55
|
+
.stat-plate { position: relative; width: 1000px; height: 260px; background-repeat: no-repeat; background-size: 100% 100%; }
|
|
56
|
+
.stat-plate .stat-v { font-size: 40px; }
|
|
57
|
+
.stat-plate .stat-l { font-size: 20px; }
|
|
58
|
+
|
|
59
|
+
/* 角色网格: 单列纵排, 角色多时左右两列 */
|
|
60
|
+
.grid { position: relative; width: {{ grid_w }}px; height: {{ grid_h }}px; }
|
|
61
|
+
/* 点击桥接会给 [data-ww-cmd] 加 position:relative, 用更高特异性压回去 */
|
|
62
|
+
.grid .row { position: absolute; width: {{ bar_w }}px; height: {{ bar_h }}px; overflow: hidden; background-repeat: no-repeat; background-size: 100% 100%; }
|
|
63
|
+
.row .avatar { left: 60px; top: 0; width: 180px; height: 180px; }
|
|
64
|
+
.row .attr { left: 170px; top: 20px; width: 40px; height: 40px; }
|
|
65
|
+
.row .lv { left: 180px; top: 83px; font-size: 22px; color: {{ grey }}; }
|
|
66
|
+
.row .chain { position: absolute; left: 120px; top: 15px; width: 40px; height: 20px; display: flex; align-items: center; }
|
|
67
|
+
.row .chain span { padding-left: 2px; font-size: 18px; line-height: 1; white-space: nowrap; }
|
|
68
|
+
.row .emblem { left: 200px; top: 2px; width: 110px; height: 110px; }
|
|
69
|
+
.row .score-v { left: 348px; top: 42px; font-size: 30px; }
|
|
70
|
+
.row .score-l { left: 348px; top: 75px; font-size: 16px; color: {{ gold }}; }
|
|
71
|
+
|
|
72
|
+
/* 技能格: 原版 120x140 画好后缩到 70x82 */
|
|
73
|
+
.skills { position: absolute; left: 300px; top: 10px; }
|
|
74
|
+
.skill { position: absolute; top: 0; width: 70px; height: 82px; }
|
|
75
|
+
.skill .inner { position: absolute; left: 0; top: 0; width: 120px; height: 140px; transform: scale({{ skill_scale_x }}, {{ skill_scale_y }}); transform-origin: top left; }
|
|
76
|
+
.skill .sbg { left: 0; top: 0; width: 120px; height: 120px; background-image: url('{{ skill_bg_url }}'); }
|
|
77
|
+
.skill .sicon { left: 25px; top: 25px; width: 70px; height: 70px; }
|
|
78
|
+
.skill .slv { left: 62px; top: 120px; font-size: 38px; }
|
|
79
|
+
|
|
80
|
+
/* 武器块: 原版 600x300 画好后缩到 260x130 */
|
|
81
|
+
.weapon { position: absolute; left: 710px; top: 25px; width: 260px; height: 130px; overflow: hidden; }
|
|
82
|
+
.weapon .inner { position: absolute; left: 0; top: 0; width: 600px; height: 300px; transform: scale({{ weapon_scale }}); transform-origin: top left; }
|
|
83
|
+
.weapon .wbg { left: 45px; top: 0; width: 140px; height: 140px; }
|
|
84
|
+
.weapon .wicon { left: 55px; top: 20px; width: 110px; height: 110px; }
|
|
85
|
+
.weapon .wname { left: 200px; top: 30px; font-size: 40px; color: {{ gold }}; }
|
|
86
|
+
.weapon .wlv { left: 203px; top: 75px; font-size: 30px; }
|
|
87
|
+
.weapon .pip { top: 100px; width: 40px; height: 40px; background-image: url('{{ promote_url }}'); }
|
|
88
|
+
.weapon .reson { position: absolute; left: 103px; top: 96px; width: 58px; height: 30px; border-radius: 8px; }
|
|
89
|
+
.weapon .reson span { position: absolute; left: 29px; top: 15px; transform: translate(-50%, -50%); font-size: 24px; white-space: nowrap; }
|
|
90
|
+
|
|
91
|
+
.hint { font-size: 24px; color: {{ gold }}; }
|
|
92
|
+
.footer { width: 100%; text-align: center; opacity: .6; }
|
|
93
|
+
.footer img { max-width: 100%; }
|
|
94
|
+
</style>
|
|
95
|
+
<style>
|
|
96
|
+
{% for url in assets %}.a{{ loop.index0 }} { background-image: url('{{ url }}'); }
|
|
97
|
+
{% endfor %}
|
|
98
|
+
</style>
|
|
99
|
+
</head>
|
|
100
|
+
<body>
|
|
101
|
+
<div class="container">
|
|
102
|
+
<div class="bg-layer"><img class="bg-image" src="{{ bg_url }}"></div>
|
|
103
|
+
<div class="page">
|
|
104
|
+
<div class="header">
|
|
105
|
+
<div class="deco">CHARACTER LIST</div>
|
|
106
|
+
<div class="avatar-box">
|
|
107
|
+
<div class="ring"></div>
|
|
108
|
+
<div class="face" style="background-image: url('{{ avatar_url }}')"></div>
|
|
109
|
+
</div>
|
|
110
|
+
<div class="user-info">
|
|
111
|
+
<div class="user-row">
|
|
112
|
+
<div class="user-name">{{ user_name }}</div>
|
|
113
|
+
<div class="user-uid">特征码 {{ user_id }}</div>
|
|
114
|
+
</div>
|
|
115
|
+
<div class="user-stats">
|
|
116
|
+
{% if show_stats %}
|
|
117
|
+
<div class="stat-item">
|
|
118
|
+
<div class="stat-value">Lv.{{ level }}</div>
|
|
119
|
+
<div class="stat-label">账号等级</div>
|
|
120
|
+
</div>
|
|
121
|
+
<div class="stat-item">
|
|
122
|
+
<div class="stat-value">Lv.{{ world_level }}</div>
|
|
123
|
+
<div class="stat-label">世界等级</div>
|
|
124
|
+
</div>
|
|
125
|
+
{% endif %}
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
<div class="stat-plate" style="background-image: url('{{ info_bg_url }}')">
|
|
132
|
+
{% for cell in stat_cells %}
|
|
133
|
+
<div class="t mm stat-v" style="left:{{ cell.x }}px;top:120px">{{ cell.value }}</div>
|
|
134
|
+
<div class="t mm stat-l" style="left:{{ cell.x }}px;top:160px">{{ cell.label }}</div>
|
|
135
|
+
{% endfor %}
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div class="grid">
|
|
139
|
+
{% for row in rows %}
|
|
140
|
+
<div class="row {{ row.bar_class }}" style="left: {{ row.left }}px; top: {{ row.top }}px"{% if row.cmd %} data-ww-cmd="{{ row.cmd }}"{% endif %}>
|
|
141
|
+
<i class="ic avatar {{ row.avatar_class }}"></i>
|
|
142
|
+
<i class="ic attr {{ row.attr_class }}"></i>
|
|
143
|
+
<div class="chain" style="background: {{ row.chain_color }}"><span>{{ row.chain_name }}</span></div>
|
|
144
|
+
<div class="t mm lv">Lv.{{ row.level }}</div>
|
|
145
|
+
{% if row.score %}
|
|
146
|
+
<i class="ic emblem {{ row.score.emblem_class }}"></i>
|
|
147
|
+
<div class="t mm score-v">{{ row.score.value }}</div>
|
|
148
|
+
<div class="t mm score-l">声骸分数</div>
|
|
149
|
+
{% endif %}
|
|
150
|
+
<div class="skills">
|
|
151
|
+
{% for skill in row.skills %}
|
|
152
|
+
<div class="skill" style="left: {{ skill.left }}px">
|
|
153
|
+
<div class="inner">
|
|
154
|
+
<i class="ic sbg"></i>
|
|
155
|
+
{% if skill.icon_class %}<i class="ic sicon {{ skill.icon_class }}"></i>{% endif %}
|
|
156
|
+
<div class="t mm slv" style="color: {{ skill.color }}">{{ skill.level }}</div>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
{% endfor %}
|
|
160
|
+
</div>
|
|
161
|
+
<div class="weapon">
|
|
162
|
+
<div class="inner">
|
|
163
|
+
<div class="t wname">{{ row.weapon.name }}</div>
|
|
164
|
+
<div class="t wlv">Lv.{{ row.weapon.level }}/90</div>
|
|
165
|
+
{% for pip in row.weapon.pips %}
|
|
166
|
+
<i class="ic pip" style="left: {{ 200 + 40 * loop.index0 }}px"></i>
|
|
167
|
+
{% endfor %}
|
|
168
|
+
<i class="ic wbg {{ row.weapon.bg_class }}"></i>
|
|
169
|
+
<i class="ic wicon {{ row.weapon.icon_class }}"></i>
|
|
170
|
+
<div class="reson" style="background: {{ row.weapon.reson_color }}"><span>{{ row.weapon.reson }}阶</span></div>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
{% endfor %}
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
{% if hint %}<div class="hint">{{ hint }}</div>{% endif %}
|
|
178
|
+
{% if footer_url %}<div class="footer"><img src="{{ footer_url }}"></div>{% endif %}
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
</body>
|
|
182
|
+
</html>
|
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>角色面板</title>
|
|
6
|
+
<style>
|
|
7
|
+
@import url('{{ font_css_url }}');
|
|
8
|
+
|
|
9
|
+
* { box-sizing: border-box; }
|
|
10
|
+
html, body { margin: 0; padding: 0; background: #0f1115; }
|
|
11
|
+
body {
|
|
12
|
+
width: 1200px;
|
|
13
|
+
font-family: 'Source Han Sans CN', 'Noto Sans CJK JP', 'Noto Sans CJK KR', sans-serif;
|
|
14
|
+
font-weight: 500;
|
|
15
|
+
color: #fff;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.container { position: relative; width: 1200px; padding-bottom: 70px; overflow: hidden; }
|
|
19
|
+
.bg-layer { position: absolute; inset: 0; z-index: 0; }
|
|
20
|
+
.bg-layer .bg-image { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
21
|
+
.bg-layer::after { content: ""; position: absolute; inset: 0; background: rgba(0, 0, 0, .18); }
|
|
22
|
+
.page { position: relative; z-index: 1; }
|
|
23
|
+
|
|
24
|
+
/* 绝对定位文本: 锚点与画布版一致 */
|
|
25
|
+
.t { position: absolute; white-space: nowrap; line-height: 1; }
|
|
26
|
+
.a-lt { transform: none; }
|
|
27
|
+
.a-lm { transform: translateY(-50%); }
|
|
28
|
+
.a-mm { transform: translate(-50%, -50%); }
|
|
29
|
+
.a-rm { transform: translate(-100%, -50%); }
|
|
30
|
+
.a-mt { transform: translateX(-50%); }
|
|
31
|
+
.a-rt { transform: translateX(-100%); }
|
|
32
|
+
.ic { position: absolute; background-repeat: no-repeat; background-size: 100% 100%; }
|
|
33
|
+
.bar, .card, .card .head, .rowbar, .grade-block .layer, .skills .item,
|
|
34
|
+
.panel-prop, .weapon, .echo .title-bar, .chains .item .ic {
|
|
35
|
+
background-repeat: no-repeat; background-size: 100% 100%;
|
|
36
|
+
}
|
|
37
|
+
[data-ww-cmd] { cursor: pointer; }
|
|
38
|
+
|
|
39
|
+
/* 头部 */
|
|
40
|
+
.header {
|
|
41
|
+
position: relative; width: 1140px; margin: 24px 30px 6px;
|
|
42
|
+
background:
|
|
43
|
+
radial-gradient(circle at 100% 0%, rgba(212, 177, 99, .15) 0%, transparent 40%),
|
|
44
|
+
linear-gradient(180deg, rgba(30, 34, 42, .9) 0%, rgba(15, 17, 21, .95) 100%);
|
|
45
|
+
border-radius: 16px; padding: 22px 40px; display: flex; align-items: center;
|
|
46
|
+
border: 1px solid rgba(255, 255, 255, .08);
|
|
47
|
+
border-top: 1px solid rgba(255, 255, 255, .2);
|
|
48
|
+
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, .5);
|
|
49
|
+
}
|
|
50
|
+
.header .deco { position: absolute; top: 18px; right: 30px; font-family: 'Oswald', sans-serif; font-size: 14px; letter-spacing: 4px; color: rgba(255, 255, 255, .1); font-weight: 700; }
|
|
51
|
+
.avatar-box { position: relative; width: 110px; height: 110px; flex-shrink: 0; margin-right: 30px; border-radius: 50%; background: #222; border: 3px solid #2a2e35; box-shadow: 0 4px 10px rgba(0, 0, 0, .5); }
|
|
52
|
+
.avatar-box .ring { position: absolute; inset: -6px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, .05); border-left: 2px solid #d4b163; transform: rotate(-45deg); }
|
|
53
|
+
.avatar-box .face { position: absolute; inset: 0; border-radius: 50%; background-size: cover; background-position: center; }
|
|
54
|
+
.user-info { flex: 1; }
|
|
55
|
+
.user-row { display: flex; align-items: baseline; padding-bottom: 8px; margin-bottom: 10px; border-bottom: 1px solid rgba(255, 255, 255, .08); position: relative; }
|
|
56
|
+
.user-row::after { content: ""; position: absolute; bottom: -1px; left: 0; width: 40px; height: 2px; background: #d4b163; box-shadow: 0 0 8px #d4b163; }
|
|
57
|
+
.user-name { font-size: 40px; font-weight: 800; margin-right: 20px; text-shadow: 0 4px 10px rgba(0, 0, 0, .5); }
|
|
58
|
+
.user-uid { font-family: 'JetBrains Mono', monospace; font-size: 20px; color: #d4b163; background: rgba(0, 0, 0, .4); padding: 4px 12px; border-radius: 6px; border: 1px solid rgba(212, 177, 99, .2); letter-spacing: 1.5px; font-weight: 700; }
|
|
59
|
+
.user-stats { display: flex; gap: 40px; }
|
|
60
|
+
.stat-item { display: flex; flex-direction: column; }
|
|
61
|
+
.stat-value { font-family: 'Oswald', sans-serif; font-size: 30px; font-weight: 700; line-height: 1.1; background: linear-gradient(180deg, #fff 50%, #d4b163 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
|
|
62
|
+
.stat-label { font-size: 12px; color: #6d717a; font-weight: 700; letter-spacing: 1px; margin-top: 2px; }
|
|
63
|
+
|
|
64
|
+
/* 立绘 */
|
|
65
|
+
/* 高度贴合实际内容: 立绘 1000, 有评分时右栏被下压, 武器块底到 1105 */
|
|
66
|
+
.body { position: relative; }
|
|
67
|
+
.pile { position: absolute; left: 25px; top: 0; width: 560px; height: 1000px; }
|
|
68
|
+
.pile .art {
|
|
69
|
+
position: absolute; inset: 0; background-size: 560px 1000px; background-repeat: no-repeat;
|
|
70
|
+
-webkit-mask-size: 560px 1000px; -webkit-mask-repeat: no-repeat;
|
|
71
|
+
}
|
|
72
|
+
.pile .fg { position: absolute; inset: 0; background-size: 560px 1000px; background-repeat: no-repeat; }
|
|
73
|
+
.pile .role-name { font-size: 50px; font-weight: 700; text-shadow: 2px 2px 6px rgba(0, 0, 0, .9); }
|
|
74
|
+
.pile .hash { font-size: 12px; color: #b0b0b0; text-shadow: 1px 1px 0 rgba(80, 80, 80, .9); }
|
|
75
|
+
|
|
76
|
+
/* 右侧 */
|
|
77
|
+
.right { position: absolute; left: 570px; width: 600px; height: 1100px; }
|
|
78
|
+
.panel-prop { position: absolute; left: 0; width: 600px; height: 500px; }
|
|
79
|
+
.weapon { position: absolute; left: 0; width: 600px; height: 300px; }
|
|
80
|
+
.weapon-name { position: absolute; display: flex; align-items: center; gap: 18px; transform: translateY(-50%); }
|
|
81
|
+
.weapon-name .name { font-size: 40px; font-weight: 700; color: rgb(234, 183, 4); }
|
|
82
|
+
.weapon-name .reson { font-size: 24px; padding: 3px 12px; border-radius: 7px; }
|
|
83
|
+
|
|
84
|
+
/* 综合评分: 紧贴立绘下沿, 与画布版一样吃掉立绘底部的留白 */
|
|
85
|
+
/* 画布版各块是互相压着的绝对坐标, 这里用负边距还原:
|
|
86
|
+
评分徽章 1080+shift / 技能 1150+offset+shift / 共鸣链 1080+jineng / 声骸 1320+jineng */
|
|
87
|
+
.score-band { position: relative; height: 200px; margin-top: -170px; }
|
|
88
|
+
.score-band .grade { position: absolute; left: 90px; top: 0; width: 200px; height: 200px; }
|
|
89
|
+
.score-band .value { font-size: 40px; font-weight: 700; }
|
|
90
|
+
.score-band .label { font-size: 40px; color: rgb(216, 216, 216); }
|
|
91
|
+
|
|
92
|
+
/* 技能 / 共鸣链 */
|
|
93
|
+
.skills { position: relative; height: 150px; margin-top: {{ -15 if score_band else -20 }}px; overflow: hidden; }
|
|
94
|
+
.skills .bar { position: absolute; left: 0; top: 0; width: 1200px; height: 150px; }
|
|
95
|
+
.skills .item { position: absolute; width: 400px; height: 200px; }
|
|
96
|
+
.chains { position: relative; height: 300px; margin-top: -40px; overflow: hidden; }
|
|
97
|
+
.chains .item { position: absolute; top: 0; width: 300px; height: 300px; }
|
|
98
|
+
.chains .name { font-size: 20px; text-align: center; }
|
|
99
|
+
.chains .name.small { font-size: 16px; }
|
|
100
|
+
|
|
101
|
+
/* 声骸 */
|
|
102
|
+
.echo { position: relative; margin-top: -60px; }
|
|
103
|
+
.echo .banner { position: absolute; left: 0; top: 0; width: 1200px; height: 100px; }
|
|
104
|
+
.echo .title-bar { position: absolute; left: 350px; top: 85px; width: 500px; height: 100px; }
|
|
105
|
+
.bar { position: absolute; width: 400px; height: 100px; }
|
|
106
|
+
.card { position: absolute; width: 350px; height: 550px; }
|
|
107
|
+
.card .head { position: absolute; left: 0; top: 0; width: 350px; height: 150px; }
|
|
108
|
+
.card .badge { position: absolute; height: 30px; border-radius: 8px; display: flex; align-items: center; }
|
|
109
|
+
.grade-block { position: absolute; width: 350px; height: 500px; }
|
|
110
|
+
.grade-block .layer { position: absolute; inset: 0; background-size: 350px 500px; background-repeat: no-repeat; }
|
|
111
|
+
|
|
112
|
+
/* 伤害 / 优化 / 权重 */
|
|
113
|
+
.rows { position: relative; }
|
|
114
|
+
.rows .rowbar { position: absolute; left: 0; width: 1200px; height: 100px; }
|
|
115
|
+
.rule-panel { position: absolute; left: 30px; width: 1140px; background: rgba(0, 0, 0, .43); border-radius: 20px; }
|
|
116
|
+
.rule-panel .hr { position: absolute; left: 40px; right: 40px; height: 2px; background: rgba(255, 255, 255, .18); }
|
|
117
|
+
.weight-table { position: relative; height: 900px; }
|
|
118
|
+
.weight-table .plate { position: absolute; left: 10px; top: 10px; width: 1180px; height: 860px; background: rgba(0, 0, 0, .7); border-radius: 6px; }
|
|
119
|
+
.weight-table .cell { position: absolute; width: 230px; height: 40px; display: flex; align-items: center; justify-content: center; font-size: 20px; }
|
|
120
|
+
.weight-table .cell.head { font-size: 24px; }
|
|
121
|
+
|
|
122
|
+
.footer { position: relative; height: 60px; }
|
|
123
|
+
.footer .mark { position: absolute; left: 300px; top: 10px; width: 600px; height: 40px; opacity: .85; }
|
|
124
|
+
|
|
125
|
+
/* 点击桥接会给 [data-ww-cmd] 加 position:relative, 这里用更高特异性压回去 */
|
|
126
|
+
.echo .card, .rows .rowbar { position: absolute; }
|
|
127
|
+
|
|
128
|
+
{% for name, uri in icon_css %}.{{ name }}{background-image:url('{{ uri }}')}
|
|
129
|
+
{% endfor %}
|
|
130
|
+
</style>
|
|
131
|
+
</head>
|
|
132
|
+
<body>
|
|
133
|
+
{% macro T(x, y, text, color='#ffffff', size=24, anchor='lm', cls='', weight=500) -%}
|
|
134
|
+
<div class="t a-{{ anchor }} {{ cls }}" style="left:{{ x }}px;top:{{ y }}px;color:{{ color }};font-size:{{ size }}px;font-weight:{{ weight }}">{{ text }}</div>
|
|
135
|
+
{%- endmacro %}
|
|
136
|
+
|
|
137
|
+
{% macro STATBAR(row, even_cls, odd_cls, x, y) -%}
|
|
138
|
+
<div class="bar {{ odd_cls if row.odd else even_cls }}" style="left:{{ x }}px;top:{{ y }}px">
|
|
139
|
+
<div class="ic {{ row.icon }}" style="left:20px;top:32px;width:40px;height:40px"></div>
|
|
140
|
+
{{ T(70, 50, row.name, row.color, 24) }}
|
|
141
|
+
{{ T(343, 50, row.value, row.color, 24, 'rm') }}
|
|
142
|
+
</div>
|
|
143
|
+
{%- endmacro %}
|
|
144
|
+
|
|
145
|
+
{% macro ECHOCARD(card, x, y, cmd) -%}
|
|
146
|
+
<div class="card {{ card.bg }}" style="left:{{ x }}px;top:{{ y }}px;background-size:350px 550px;background-repeat:no-repeat"
|
|
147
|
+
{% if cmd %}data-ww-cmd="{{ cmd }}"{% endif %}>
|
|
148
|
+
<div class="head {{ card.title }}" style="background-size:350px 150px;background-repeat:no-repeat"></div>
|
|
149
|
+
{% if card.icon %}<div class="ic {{ card.icon }}" style="left:20px;top:20px;width:100px;height:100px"></div>{% endif %}
|
|
150
|
+
{{ T(130, 40, card.name, 'rgb(234,183,4)', 28, 'lm', '', 700) }}
|
|
151
|
+
{% if card.badge %}
|
|
152
|
+
<div class="badge" style="left:128px;top:58px;width:{{ 175 if card.wide_score else 150 }}px;background:rgba(0,0,0,.8);justify-content:center">
|
|
153
|
+
<span style="font-size:18px">{{ card.badge }}</span>
|
|
154
|
+
</div>
|
|
155
|
+
{% else %}
|
|
156
|
+
<div class="badge" style="left:128px;top:58px;width:84px;background:rgba(0,0,0,.8);padding-left:8px">
|
|
157
|
+
<span style="font-size:24px">{{ card.level }}</span>
|
|
158
|
+
</div>
|
|
159
|
+
<div class="badge" style="left:223px;top:58px;width:{{ 120 if card.wide_score else 100 }}px;background:rgba(186,55,42,.8);justify-content:center">
|
|
160
|
+
<span style="font-size:24px">{{ card.score }}</span>
|
|
161
|
+
</div>
|
|
162
|
+
{% endif %}
|
|
163
|
+
{% for i in range(card.cost) %}
|
|
164
|
+
<div class="ic {{ card.promote }}" style="left:{{ 128 + 30 * i }}px;top:90px;width:30px;height:30px"></div>
|
|
165
|
+
{% endfor %}
|
|
166
|
+
{% for prop in card.props %}
|
|
167
|
+
{% if prop.entry is defined %}
|
|
168
|
+
{{ T(15, 187 + loop.index0 * 55, prop.name, prop.name_color, 24) }}
|
|
169
|
+
{{ T(273, 187 + loop.index0 * 55, prop.value, prop.value_color, 24, 'rm') }}
|
|
170
|
+
{{ T(343, 191 + loop.index0 * 55, prop.entry, prop.entry_color, 18, 'rm') }}
|
|
171
|
+
{% else %}
|
|
172
|
+
<div class="ic {{ prop.icon }}" style="left:15px;top:{{ 167 + loop.index0 * 55 }}px;width:40px;height:40px"></div>
|
|
173
|
+
{{ T(60, 187 + loop.index0 * 55, prop.name, prop.name_color, 24) }}
|
|
174
|
+
{{ T(343, 187 + loop.index0 * 55, prop.value, prop.value_color, 24, 'rm') }}
|
|
175
|
+
{% endif %}
|
|
176
|
+
{% endfor %}
|
|
177
|
+
{% if card.max_line %}{{ T(343, 576, card.max_line, 'rgb(234,183,4)', 18, 'rm') }}{% endif %}
|
|
178
|
+
</div>
|
|
179
|
+
{%- endmacro %}
|
|
180
|
+
|
|
181
|
+
{% macro GRADE(grade, x, y) -%}
|
|
182
|
+
<div class="grade-block" style="left:{{ x }}px;top:{{ y }}px">
|
|
183
|
+
<div class="layer {{ grade.bg }}"></div>
|
|
184
|
+
{% if grade.fg %}<div class="layer {{ grade.fg }}"></div>{% endif %}
|
|
185
|
+
{% if grade.empty %}
|
|
186
|
+
{{ T(180, 130, grade.top, '#ffffff', 40, 'mm') }}
|
|
187
|
+
{{ T(180, 380, grade.value, '#ffffff', 40, 'mm') }}
|
|
188
|
+
{% else %}
|
|
189
|
+
{{ T(180, 260, grade.top, 'rgb(216,216,216)', 40, 'mm') }}
|
|
190
|
+
{{ T(180, 380, grade.value, '#ffffff', 40, 'mm', '', 700) }}
|
|
191
|
+
{{ T(180, 440, grade.bottom, 'rgb(216,216,216)', 40, 'mm') }}
|
|
192
|
+
{% endif %}
|
|
193
|
+
</div>
|
|
194
|
+
{%- endmacro %}
|
|
195
|
+
|
|
196
|
+
{% macro DMGHEAD(bar, head, y) -%}
|
|
197
|
+
<div class="rowbar {{ bar }}" style="top:{{ y }}px">
|
|
198
|
+
{{ T(400, 50, head.name, 'rgb(234,183,4)', 24, 'rm') }}
|
|
199
|
+
{{ T(700, 50, head.crit, 'rgb(234,183,4)', 24, 'mm') }}
|
|
200
|
+
{{ T(1000, 50, head.expected, 'rgb(234,183,4)', 24, 'mm') }}
|
|
201
|
+
</div>
|
|
202
|
+
{%- endmacro %}
|
|
203
|
+
|
|
204
|
+
{% macro DMGROW(bar, row, y) -%}
|
|
205
|
+
<div class="rowbar {{ bar }}" style="top:{{ y }}px" {% if row.cmd %}data-ww-cmd="{{ row.cmd }}"{% endif %}>
|
|
206
|
+
{{ T(400, 50, row.name, '#ffffff', 24, 'rm') }}
|
|
207
|
+
{% if row.single %}
|
|
208
|
+
{{ T(850, 50, row.value if row.value is defined else row.expected, 'rgb(234,183,4)' if row.gold else '#ffffff', 24, 'mm') }}
|
|
209
|
+
{% else %}
|
|
210
|
+
{{ T(700, 50, row.crit, '#ffffff', 24, 'mm') }}
|
|
211
|
+
{{ T(1000, 50, row.expected, '#ffffff', 24, 'mm') }}
|
|
212
|
+
{% endif %}
|
|
213
|
+
</div>
|
|
214
|
+
{%- endmacro %}
|
|
215
|
+
|
|
216
|
+
<div class="container">
|
|
217
|
+
<div class="bg-layer"><img class="bg-image" src="{{ bg }}"></div>
|
|
218
|
+
<div class="page">
|
|
219
|
+
|
|
220
|
+
<div class="header">
|
|
221
|
+
<div class="deco">ROLE PANEL</div>
|
|
222
|
+
<div class="avatar-box">
|
|
223
|
+
<div class="ring"></div>
|
|
224
|
+
<div class="face {{ header.avatar }}"></div>
|
|
225
|
+
</div>
|
|
226
|
+
<div class="user-info">
|
|
227
|
+
<div class="user-row">
|
|
228
|
+
<div class="user-name">{{ header.name }}</div>
|
|
229
|
+
<div class="user-uid">{{ header.uid_label }} {{ header.uid }}</div>
|
|
230
|
+
</div>
|
|
231
|
+
{% if header.show_stats %}
|
|
232
|
+
<div class="user-stats">
|
|
233
|
+
<div class="stat-item">
|
|
234
|
+
<div class="stat-value">Lv.{{ header.level }}</div>
|
|
235
|
+
<div class="stat-label">{{ header.level_label }}</div>
|
|
236
|
+
</div>
|
|
237
|
+
<div class="stat-item">
|
|
238
|
+
<div class="stat-value">Lv.{{ header.world_level }}</div>
|
|
239
|
+
<div class="stat-label">{{ header.world_label }}</div>
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
{% endif %}
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
{% set shift = 25 if score_band else 0 %}
|
|
247
|
+
<div class="body" style="height:{{ 1105 if score_band else 1000 }}px">
|
|
248
|
+
<div class="pile">
|
|
249
|
+
<div class="art {{ pile.image }}" style="-webkit-mask-image:url('{{ mask_uri }}')"></div>
|
|
250
|
+
<div class="fg {{ pile.fg }}"></div>
|
|
251
|
+
<div class="ic {{ pile.attribute }}" style="left:434px;top:112px;width:50px;height:50px"></div>
|
|
252
|
+
<div class="ic {{ pile.weapon_type }}" style="left:439px;top:182px;width:40px;height:40px"></div>
|
|
253
|
+
<div class="t a-mm role-name" style="left:285px;top:867px">{{ pile.name }}</div>
|
|
254
|
+
{% if pile.hash_id %}<div class="t a-rm hash" style="left:500px;top:100px">{{ pile.hash_id }}</div>{% endif %}
|
|
255
|
+
</div>
|
|
256
|
+
|
|
257
|
+
{% if right %}
|
|
258
|
+
{% set prop_y = 100 if score_band else 80 %}
|
|
259
|
+
{% set weapon_banner_y = 620 if score_band else 550 %}
|
|
260
|
+
{% set weapon_y = 750 if score_band else 620 %}
|
|
261
|
+
<div class="right" style="top:{{ 30 + shift }}px">
|
|
262
|
+
<div class="ic {{ right.banner_top }}" style="left:-9px;top:0;width:600px;height:100px"></div>
|
|
263
|
+
<div class="panel-prop {{ right.prop_bg }}" style="top:{{ prop_y }}px;background-size:600px 500px;background-repeat:no-repeat">
|
|
264
|
+
{% if right.diff %}
|
|
265
|
+
{% for row in right.props %}
|
|
266
|
+
{% set y = 40 + loop.index0 * 55 %}
|
|
267
|
+
<div class="ic {{ row.icon }}" style="left:65px;top:{{ y }}px;width:40px;height:40px"></div>
|
|
268
|
+
{{ T(120, y + 18, row.name, '#ffffff', 24) }}
|
|
269
|
+
{{ T(480, y + 18, row.value, '#ffffff', 20, 'rm') }}
|
|
270
|
+
{% if row.delta %}{{ T(578, y + 18, row.delta, row.delta_color, 20, 'rm') }}{% endif %}
|
|
271
|
+
{% endfor %}
|
|
272
|
+
{% else %}
|
|
273
|
+
{% for row in right.props %}
|
|
274
|
+
{% set i = loop.index0 %}
|
|
275
|
+
{% if i < 4 %}
|
|
276
|
+
{% set x = 251 * (i % 2) %}
|
|
277
|
+
{% set y = 40 + (i // 2) * 55 %}
|
|
278
|
+
<div class="ic {{ row.icon }}" style="left:{{ 60 + x }}px;top:{{ y }}px;width:40px;height:40px"></div>
|
|
279
|
+
{{ T(115 + x, y + 18, row.name, row.color, 24) }}
|
|
280
|
+
{{ T(530 - 251 * ((i + 1) % 2), y + 18, row.value, row.color, 24, 'rm') }}
|
|
281
|
+
{% else %}
|
|
282
|
+
{% set y = 40 + (i - 2) * 55 %}
|
|
283
|
+
<div class="ic {{ row.icon }}" style="left:60px;top:{{ y }}px;width:40px;height:40px"></div>
|
|
284
|
+
{{ T(115, y + 18, row.name, row.color, 24) }}
|
|
285
|
+
{{ T(530, y + 18, row.value, row.color, 24, 'rm') }}
|
|
286
|
+
{% endif %}
|
|
287
|
+
{% endfor %}
|
|
288
|
+
{% endif %}
|
|
289
|
+
</div>
|
|
290
|
+
|
|
291
|
+
<div class="ic {{ right.banner_weapon }}" style="left:-9px;top:{{ weapon_banner_y }}px;width:600px;height:100px"></div>
|
|
292
|
+
{% set w = right.weapon %}
|
|
293
|
+
<div class="weapon {{ w.bg }}"{% if w.cmd %} data-ww-cmd="{{ w.cmd }}"{% endif %} style="top:{{ weapon_y }}px;background-size:600px 300px;background-repeat:no-repeat">
|
|
294
|
+
<div class="ic {{ w.icon }}" style="left:45px;top:0;width:140px;height:140px"></div>
|
|
295
|
+
<div class="weapon-name" style="left:200px;top:30px">
|
|
296
|
+
<span class="name">{{ w.name }}</span>
|
|
297
|
+
<span class="reson" style="background:{{ w.reson_color }}">{{ w.reson }}</span>
|
|
298
|
+
</div>
|
|
299
|
+
{{ T(203, 75, w.level, '#ffffff', 30) }}
|
|
300
|
+
{% for i in range(w.breach) %}
|
|
301
|
+
<div class="ic {{ w.promote }}" style="left:{{ 200 + 40 * i }}px;top:100px;width:40px;height:40px"></div>
|
|
302
|
+
{% endfor %}
|
|
303
|
+
{% for stat in w.stats %}
|
|
304
|
+
{% set y = 187 + loop.index0 * 50 %}
|
|
305
|
+
<div class="ic {{ stat.icon }}" style="left:65px;top:{{ y }}px;width:40px;height:40px"></div>
|
|
306
|
+
{{ T(115 if w.has_branch else 130, y + 20, stat.name, '#ffffff', 30) }}
|
|
307
|
+
{{ T(415 if w.has_branch else 500, y + 20, stat.value, '#ffffff', 30, 'rm') }}
|
|
308
|
+
{% endfor %}
|
|
309
|
+
{% if w.branch_icon %}
|
|
310
|
+
<div class="ic {{ w.branch_icon }}" style="left:400px;top:182px;width:100px;height:100px"></div>
|
|
311
|
+
{% endif %}
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
{% endif %}
|
|
315
|
+
|
|
316
|
+
{% if stat_column %}
|
|
317
|
+
<div class="right" style="left:580px;top:55px;width:500px">
|
|
318
|
+
{% for group in stat_column.groups %}
|
|
319
|
+
{% set gi = loop.index0 %}
|
|
320
|
+
{% for row in group %}
|
|
321
|
+
<div style="position:absolute;left:0;top:{{ (loop.index0 + gi * 4) * 70 }}px;transform:scale(1.25);transform-origin:top left">
|
|
322
|
+
{{ STATBAR(row, stat_column.bar_even, stat_column.bar_odd, 0, 0) }}
|
|
323
|
+
</div>
|
|
324
|
+
{% endfor %}
|
|
325
|
+
{% endfor %}
|
|
326
|
+
</div>
|
|
327
|
+
{% endif %}
|
|
328
|
+
{% if side_strip %}
|
|
329
|
+
<div class="ic {{ side_strip }}" style="left:1075px;top:50px;width:70px;height:1000px"></div>
|
|
330
|
+
{% endif %}
|
|
331
|
+
</div>
|
|
332
|
+
|
|
333
|
+
{% if score_band %}
|
|
334
|
+
<div class="score-band" {% if score_band.cmd %}data-ww-cmd="{{ score_band.cmd }}"{% endif %}>
|
|
335
|
+
<div class="ic grade {{ score_band.icon }}"></div>
|
|
336
|
+
<div class="t a-mm value" style="left:400px;top:60px">{{ score_band.value }}</div>
|
|
337
|
+
<div class="t a-mm label" style="left:400px;top:130px">{{ score_band.label }}</div>
|
|
338
|
+
</div>
|
|
339
|
+
{% endif %}
|
|
340
|
+
|
|
341
|
+
{% if skills %}
|
|
342
|
+
<div class="skills"{% if skills.cmd %} data-ww-cmd="{{ skills.cmd }}"{% endif %}>
|
|
343
|
+
<div class="ic bar {{ skills.bar }}"></div>
|
|
344
|
+
{% for item in skills.entries %}
|
|
345
|
+
<div class="item {{ skills.bg }}" style="left:{{ 20 + loop.index0 * 215 }}px;top:-20px;background-size:400px 200px;background-repeat:no-repeat">
|
|
346
|
+
<div class="ic {{ item.icon }}" style="left:57px;top:65px;width:70px;height:70px"></div>
|
|
347
|
+
{{ T(150, 83, item.type, '#ffffff', 25) }}
|
|
348
|
+
{{ T(150, 113, item.level, '#ffffff', 25) }}
|
|
349
|
+
</div>
|
|
350
|
+
{% endfor %}
|
|
351
|
+
</div>
|
|
352
|
+
{% endif %}
|
|
353
|
+
|
|
354
|
+
{% if chains and chains.items %}
|
|
355
|
+
<div class="chains"{% if chains.cmd %} data-ww-cmd="{{ chains.cmd }}"{% endif %}>
|
|
356
|
+
{% for chain in chains['items'] %}
|
|
357
|
+
<div class="item" style="left:{{ loop.index0 * 190 }}px">
|
|
358
|
+
<div class="ic {{ chain.image }}" style="inset:0;width:300px;height:300px"></div>
|
|
359
|
+
<div class="t a-mm name {{ 'small' if chain.small }}" style="left:147px;top:230px">{{ chain.name }}</div>
|
|
360
|
+
</div>
|
|
361
|
+
{% endfor %}
|
|
362
|
+
</div>
|
|
363
|
+
{% endif %}
|
|
364
|
+
|
|
365
|
+
{% if echo %}
|
|
366
|
+
<div class="echo" style="height:{{ echo.height }}px">
|
|
367
|
+
<div class="ic banner {{ echo.banner }}"></div>
|
|
368
|
+
{% if echo.change_command %}{{ T(50, 90, echo.change_command, 'rgb(234,183,4)', 18) }}{% endif %}
|
|
369
|
+
{% if echo.title %}
|
|
370
|
+
<div class="title-bar {{ echo.title_bar }}" style="background-size:500px 100px;background-repeat:no-repeat">
|
|
371
|
+
{{ T(250, 50, echo.title, 'rgb(234,183,4)', 30, 'mm', '', 700) }}
|
|
372
|
+
</div>
|
|
373
|
+
{% endif %}
|
|
374
|
+
|
|
375
|
+
{% for group in echo.stat_groups %}
|
|
376
|
+
{% set gi = loop.index0 %}
|
|
377
|
+
{% for row in group %}
|
|
378
|
+
{{ STATBAR(row, echo.bar_even, echo.bar_odd, 40 + gi * 370, 100 + loop.index0 * 50) }}
|
|
379
|
+
{% endfor %}
|
|
380
|
+
{% endfor %}
|
|
381
|
+
{% if echo.template %}{% set tb = echo.template %}
|
|
382
|
+
<div class="bar {{ echo.bar_odd }}" style="left:{{ tb.left }}px;top:45px;width:{{ tb.width }}px">
|
|
383
|
+
{{ T(20, 50, tb.label, '#ffffff', 24) }}
|
|
384
|
+
{{ T(tb.width - 50, 50, tb.name, 'rgb(255,255,0)', tb.size, 'rm') }}
|
|
385
|
+
</div>
|
|
386
|
+
{% endif %}
|
|
387
|
+
|
|
388
|
+
{% if echo.grade %}{{ GRADE(echo.grade, 30, echo.card_top) }}{% endif %}
|
|
389
|
+
{% for card in echo.cards %}
|
|
390
|
+
{{ ECHOCARD(card, 30 + ((loop.index0 + 1) % 3) * 385, echo.card_top + ((loop.index0 + 1) // 3) * echo.card_gap, card.cmd or echo.card_cmd) }}
|
|
391
|
+
{% endfor %}
|
|
392
|
+
</div>
|
|
393
|
+
{% endif %}
|
|
394
|
+
|
|
395
|
+
{% if damage %}
|
|
396
|
+
<div class="rows" style="height:{{ 60 * (damage.rows | length + 1) + 50 }}px">
|
|
397
|
+
{{ DMGHEAD(damage.bar_odd, damage.head, 10) }}
|
|
398
|
+
{% for row in damage.rows %}
|
|
399
|
+
{{ DMGROW(damage.bar_even if loop.index0 % 2 == 0 else damage.bar_odd, row, 10 + (loop.index0 + 1) * 60) }}
|
|
400
|
+
{% endfor %}
|
|
401
|
+
</div>
|
|
402
|
+
{% endif %}
|
|
403
|
+
|
|
404
|
+
{% if single_damage %}
|
|
405
|
+
<div class="rows" style="height:{{ 190 + 60 * (single_damage.buffs | length) + 40 }}px">
|
|
406
|
+
{{ DMGHEAD(single_damage.bar_odd, single_damage.head, 10) }}
|
|
407
|
+
{{ DMGROW(single_damage.bar_even, single_damage.row, 70) }}
|
|
408
|
+
<div class="rowbar {{ single_damage.bar_odd }}" style="top:130px">
|
|
409
|
+
{{ T(600, 50, single_damage.buff_title, '#ffffff', 24, 'mm') }}
|
|
410
|
+
</div>
|
|
411
|
+
{% for buff in single_damage.buffs %}
|
|
412
|
+
<div class="rowbar {{ single_damage.bar_even if loop.index0 % 2 == 0 else single_damage.bar_odd }}" style="top:{{ 190 + loop.index0 * 60 }}px">
|
|
413
|
+
{{ T(400, 50, buff.name, '#ffffff', 24, 'rm') }}
|
|
414
|
+
{{ T(800, 50, buff.value, '#ffffff', 24, 'mm') }}
|
|
415
|
+
</div>
|
|
416
|
+
{% endfor %}
|
|
417
|
+
</div>
|
|
418
|
+
{% endif %}
|
|
419
|
+
|
|
420
|
+
{% if optimize %}
|
|
421
|
+
{% set rule_h = 58 + 14 + (optimize.rule_lines | length) * 40 + 18 %}
|
|
422
|
+
<div class="rows" style="height:{{ 60 * (optimize.rows | length + 1) + 24 + rule_h + 60 }}px">
|
|
423
|
+
<div class="rowbar {{ optimize.bar_odd }}" style="top:0">
|
|
424
|
+
{{ T(600, 50, optimize.title, 'rgb(234,183,4)', 30, 'mm', '', 700) }}
|
|
425
|
+
</div>
|
|
426
|
+
{% for row in optimize.rows %}
|
|
427
|
+
<div class="rowbar {{ optimize.bar_even if loop.index0 % 2 == 0 else optimize.bar_odd }}" style="top:{{ (loop.index0 + 1) * 60 }}px">
|
|
428
|
+
{{ T(300, 50, row.label, '#ffffff', 24, 'rm') }}
|
|
429
|
+
{{ T(700, 50, row.text, '#ffffff', 24, 'mm') }}
|
|
430
|
+
</div>
|
|
431
|
+
{% endfor %}
|
|
432
|
+
<div class="rule-panel" style="top:{{ 60 * (optimize.rows | length) + 100 + 24 }}px;height:{{ rule_h }}px">
|
|
433
|
+
{{ T(40, 33, optimize.rule_title, 'rgb(234,183,4)', 28, 'lm', '', 700) }}
|
|
434
|
+
{{ T(1100, 33, optimize.rule_hint, 'rgb(234,183,4)', 28, 'rm') }}
|
|
435
|
+
<div class="hr" style="top:58px"></div>
|
|
436
|
+
{% for line in optimize.rule_lines %}
|
|
437
|
+
{{ T(40, 92 + loop.index0 * 40, line, 'rgb(216,216,216)', 22) }}
|
|
438
|
+
{% endfor %}
|
|
439
|
+
</div>
|
|
440
|
+
</div>
|
|
441
|
+
{% endif %}
|
|
442
|
+
|
|
443
|
+
{% if weight_tables %}
|
|
444
|
+
{% for table in weight_tables %}
|
|
445
|
+
<div class="weight-table">
|
|
446
|
+
<div class="plate"></div>
|
|
447
|
+
<div class="t a-lt" style="left:25px;top:20px;color:rgb(234,183,4);font-size:36px;font-weight:700">{{ table.title }}</div>
|
|
448
|
+
{% for row in table.rows %}
|
|
449
|
+
{% set y = 80 + loop.index0 * 40 %}
|
|
450
|
+
{% for cell in row.cells %}
|
|
451
|
+
<div class="cell {{ 'head' if row.head }}" style="left:{{ 25 + loop.index0 * 230 }}px;top:{{ y }}px;color:{{ cell.color }};background:{{ 'rgba(255,255,255,.12)' if row.odd and not row.head else 'rgba(0,0,0,.35)' }}">{{ cell.text }}</div>
|
|
452
|
+
{% endfor %}
|
|
453
|
+
{% endfor %}
|
|
454
|
+
{% for note in table.notes %}
|
|
455
|
+
<div class="t a-lt" style="left:25px;top:{{ 750 + loop.index0 * 50 }}px;font-size:24px">{{ note }}</div>
|
|
456
|
+
{% endfor %}
|
|
457
|
+
</div>
|
|
458
|
+
{% endfor %}
|
|
459
|
+
{% endif %}
|
|
460
|
+
|
|
461
|
+
<div class="footer"><div class="ic mark {{ footer }}"></div></div>
|
|
462
|
+
</div>
|
|
463
|
+
</div>
|
|
464
|
+
</body>
|
|
465
|
+
</html>
|