Revert "ff"

This reverts commit 0450d9e2ed.
This commit is contained in:
2026-05-22 20:53:08 +02:00
parent 6ca29806b0
commit a1ef06e573

View File

@@ -40,8 +40,7 @@
<div class="avatar-upload-actions"> <div class="avatar-upload-actions">
<button type="button" id="avatar-upload-btn" class="button" disabled>{{ t('settings.upload_btn') }}</button> <button type="button" id="avatar-upload-btn" class="button" disabled>{{ t('settings.upload_btn') }}</button>
@if(avatar_file) @if(avatar_file)
<button type="button" id="avatar-remove-btn" class="button button-danger">{{ t('settings.remove_custom') <button type="button" id="avatar-remove-btn" class="button button-danger">{{ t('settings.remove_custom') }}</button>
}}</button>
@endif @endif
</div> </div>
<div id="avatar-upload-status" class="avatar-status"></div> <div id="avatar-upload-status" class="avatar-status"></div>
@@ -55,16 +54,14 @@
maxlength="255">{!! session.description || '' !!}</textarea> maxlength="255">{!! session.description || '' !!}</textarea>
<div class="profile-settings-actions"> <div class="profile-settings-actions">
<button type="button" id="btn-save-description" class="button">{{ t('settings.save_description') }}</button> <button type="button" id="btn-save-description" class="button">{{ t('settings.save_description') }}</button>
<button type="button" id="btn-clear-description" class="button button-danger">{{ t('settings.clear') <button type="button" id="btn-clear-description" class="button button-danger">{{ t('settings.clear') }}</button>
}}</button>
</div> </div>
<div id="description-status" class="avatar-status"></div> <div id="description-status" class="avatar-status"></div>
</div> </div>
</div> </div>
@endif @endif
<div class="setting-item" style="margin-top: 20px;"> <div class="setting-item" style="margin-top: 20px;">
<label for="username_color_picker" style="display: block; margin-bottom: 5px;">{{ t('settings.username_color') <label for="username_color_picker" style="display: block; margin-bottom: 5px;">{{ t('settings.username_color') }}</label>
}}</label>
<div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;"> <div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
<input type="color" id="username_color_picker" value="{{ session.username_color || '#ffffff' }}" <input type="color" id="username_color_picker" value="{{ session.username_color || '#ffffff' }}"
style="width: 50px; height: 30px; padding: 0; border: 1px solid var(--nav-border-color); cursor: pointer; background: none;"> style="width: 50px; height: 30px; padding: 0; border: 1px solid var(--nav-border-color); cursor: pointer; background: none;">
@@ -82,8 +79,7 @@
<div class="preferences-settings-wrapper"> <div class="preferences-settings-wrapper">
<fieldset <fieldset
style="border: 1px solid var(--nav-border-color); padding: 10px; border-radius: 4px; margin-bottom: 15px;"> style="border: 1px solid var(--nav-border-color); padding: 10px; border-radius: 4px; margin-bottom: 15px;">
<legend style="width: auto; padding: 0 5px; font-size: 1.1em; font-weight: bold;">{{ t('settings.ui_section') <legend style="width: auto; padding: 0 5px; font-size: 1.1em; font-weight: bold;">{{ t('settings.ui_section') }}</legend>
}}</legend>
<div class="setting-item" style="margin-bottom: 15px;"> <div class="setting-item" style="margin-bottom: 15px;">
<label for="show_motd_toggle" style="cursor: pointer; display: flex; align-items: center; gap: 10px;"> <label for="show_motd_toggle" style="cursor: pointer; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="show_motd_toggle" @if(session.show_motd !==false) checked @endif> <input type="checkbox" id="show_motd_toggle" @if(session.show_motd !==false) checked @endif>
@@ -101,8 +97,7 @@
<div class="setting-item" style="margin-top: 15px;"> <div class="setting-item" style="margin-top: 15px;">
<label for="alternative_infobox_toggle" <label for="alternative_infobox_toggle"
style="cursor: pointer; display: flex; align-items: center; gap: 10px;"> style="cursor: pointer; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="alternative_infobox_toggle" @if(session.use_alternative_infobox===true) checked <input type="checkbox" id="alternative_infobox_toggle" @if(session.use_alternative_infobox===true) checked @endif>
@endif>
<span>{{ t('settings.alternative_infobox') }}</span> <span>{{ t('settings.alternative_infobox') }}</span>
</label> </label>
<small class="text-muted" style="margin-left: 25px;">{{ t('settings.alternative_infobox_hint') }}</small> <small class="text-muted" style="margin-left: 25px;">{{ t('settings.alternative_infobox_hint') }}</small>
@@ -120,9 +115,7 @@
<input type="checkbox" id="image_expand_toggle"> <input type="checkbox" id="image_expand_toggle">
<span>{{ t('settings.image_expand_on_click') || 'Expand images inline on click' }}</span> <span>{{ t('settings.image_expand_on_click') || 'Expand images inline on click' }}</span>
</label> </label>
<small class="text-muted" style="margin-left: 25px;">{{ t('settings.image_expand_on_click_hint') || 'Instead <small class="text-muted" style="margin-left: 25px;">{{ t('settings.image_expand_on_click_hint') || 'Instead of opening the scroll zoom modal, clicking an image will expand it to full size within the page.' }}</small>
of opening the scroll zoom modal, clicking an image will expand it to full size within the page.'
}}</small>
</div> </div>
<div class="setting-item" style="margin-top: 15px;"> <div class="setting-item" style="margin-top: 15px;">
<label for="disable_autoplay_toggle" <label for="disable_autoplay_toggle"
@@ -156,8 +149,7 @@
<div class="setting-item" style="margin-top: 15px;"> <div class="setting-item" style="margin-top: 15px;">
<label for="embed_youtube_in_comments_toggle" <label for="embed_youtube_in_comments_toggle"
style="cursor: pointer; display: flex; align-items: center; gap: 10px;"> style="cursor: pointer; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="embed_youtube_in_comments_toggle" @if(session.embed_youtube_in_comments <input type="checkbox" id="embed_youtube_in_comments_toggle" @if(session.embed_youtube_in_comments !==false) checked @endif>
!==false) checked @endif>
<span>{{ t('settings.embed_yt') }}</span> <span>{{ t('settings.embed_yt') }}</span>
</label> </label>
<small class="text-muted" style="margin-left: 25px;">{{ t('settings.embed_yt_hint') }}</small> <small class="text-muted" style="margin-left: 25px;">{{ t('settings.embed_yt_hint') }}</small>
@@ -173,8 +165,7 @@
@endif @endif
@if(allow_language_change) @if(allow_language_change)
<div class="setting-item" style="margin-top: 15px;"> <div class="setting-item" style="margin-top: 15px;">
<label for="language_select" style="display: block; margin-bottom: 5px; font-weight: bold;">{{ <label for="language_select" style="display: block; margin-bottom: 5px; font-weight: bold;">{{ t('settings.language') }}</label>
t('settings.language') }}</label>
<select id="language_select" class="input" style="padding: 6px 10px; max-width: 220px;"> <select id="language_select" class="input" style="padding: 6px 10px; max-width: 220px;">
<option value="" @if(!session.language) selected @endif>{{ t('settings.language_default') }}</option> <option value="" @if(!session.language) selected @endif>{{ t('settings.language_default') }}</option>
<option value="en" @if(session.language==='en' ) selected @endif>{{ t('settings.language_en') }}</option> <option value="en" @if(session.language==='en' ) selected @endif>{{ t('settings.language_en') }}</option>
@@ -188,20 +179,16 @@
@endif @endif
<div class="setting-item" style="margin-top: 15px;"> <div class="setting-item" style="margin-top: 15px;">
<label for="comment_display_mode_select" style="display: block; margin-bottom: 5px; font-weight: bold;">{{ <label for="comment_display_mode_select" style="display: block; margin-bottom: 5px; font-weight: bold;">{{ t('settings.comment_display_mode') }}</label>
t('settings.comment_display_mode') }}</label> <select id="comment_display_mode_select" class="input" style="padding: 6px 10px; max-width: 220px;" @if(session.force_comment_display_mode) disabled @endif>
<select id="comment_display_mode_select" class="input" style="padding: 6px 10px; max-width: 220px;" <option value="0" @if(session.comment_display_mode==0) selected @endif>{{ t('settings.comment_display_tree') }}</option>
@if(session.force_comment_display_mode) disabled @endif> <option value="1" @if(session.comment_display_mode==1) selected @endif>{{ t('settings.comment_display_linear') }}</option>
<option value="0" @if(session.comment_display_mode==0) selected @endif>{{
t('settings.comment_display_tree') }}</option>
<option value="1" @if(session.comment_display_mode==1) selected @endif>{{
t('settings.comment_display_linear') }}</option>
</select> </select>
<br><small class="text-muted"> <br><small class="text-muted">
@if(session.force_comment_display_mode) @if(session.force_comment_display_mode)
<strong>{{ t('settings.forced_mode_notice') || 'This setting is managed by an administrator.' }}</strong> <strong>{{ t('settings.forced_mode_notice') || 'This setting is managed by an administrator.' }}</strong>
@else @else
{{ t('settings.comment_display_mode_hint') }} {{ t('settings.comment_display_mode_hint') }}
@endif @endif
</small> </small>
</div> </div>
@@ -209,25 +196,20 @@
<fieldset <fieldset
style="border: 1px solid var(--nav-border-color); padding: 10px; border-radius: 4px; margin-bottom: 15px;"> style="border: 1px solid var(--nav-border-color); padding: 10px; border-radius: 4px; margin-bottom: 15px;">
<legend style="width: auto; padding: 0 5px; font-size: 1.1em; font-weight: bold;">{{ <legend style="width: auto; padding: 0 5px; font-size: 1.1em; font-weight: bold;">{{ t('settings.notifications_section') }}</legend>
t('settings.notifications_section') }}</legend>
<div class="setting-item"> <div class="setting-item">
<label class="checkbox-container" style="cursor: pointer; display: flex; align-items: center; gap: 10px;"> <label class="checkbox-container" style="cursor: pointer; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="chk-receive-system-notifications" @if(session.receive_system_notifications <input type="checkbox" id="chk-receive-system-notifications" @if(session.receive_system_notifications !==false) checked @endif>
!==false) checked @endif>
<span>{{ t('settings.receive_system_notifications') }}</span> <span>{{ t('settings.receive_system_notifications') }}</span>
</label> </label>
<small class="text-muted" style="margin-left: 25px;">{{ t('settings.receive_system_notifications_hint') <small class="text-muted" style="margin-left: 25px;">{{ t('settings.receive_system_notifications_hint') }}</small>
}}</small>
</div> </div>
<div class="setting-item" style="margin-top: 15px;"> <div class="setting-item" style="margin-top: 15px;">
<label class="checkbox-container" style="cursor: pointer; display: flex; align-items: center; gap: 10px;"> <label class="checkbox-container" style="cursor: pointer; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="chk-receive-user-notifications" @if(session.receive_user_notifications <input type="checkbox" id="chk-receive-user-notifications" @if(session.receive_user_notifications !==false) checked @endif>
!==false) checked @endif>
<span>{{ t('settings.receive_user_notifications') }}</span> <span>{{ t('settings.receive_user_notifications') }}</span>
</label> </label>
<small class="text-muted" style="margin-left: 25px;">{{ t('settings.receive_user_notifications_hint') <small class="text-muted" style="margin-left: 25px;">{{ t('settings.receive_user_notifications_hint') }}</small>
}}</small>
</div> </div>
<div class="setting-item" style="margin-top: 15px;"> <div class="setting-item" style="margin-top: 15px;">
<label class="checkbox-container" style="cursor: pointer; display: flex; align-items: center; gap: 10px;"> <label class="checkbox-container" style="cursor: pointer; display: flex; align-items: center; gap: 10px;">
@@ -240,11 +222,9 @@
<fieldset <fieldset
style="border: 1px solid var(--nav-border-color); padding: 10px; border-radius: 4px; margin-bottom: 15px;"> style="border: 1px solid var(--nav-border-color); padding: 10px; border-radius: 4px; margin-bottom: 15px;">
<legend style="width: auto; padding: 0 5px; font-size: 1.1em; font-weight: bold;">{{ <legend style="width: auto; padding: 0 5px; font-size: 1.1em; font-weight: bold;">{{ t('settings.appearance_section') }}</legend>
t('settings.appearance_section') }}</legend>
<div class="setting-item" style="margin-top: 20px;"> <div class="setting-item" style="margin-top: 20px;">
<label for="website_font_select" style="display: block; margin-bottom: 5px; font-weight: bold;">{{ <label for="website_font_select" style="display: block; margin-bottom: 5px; font-weight: bold;">{{ t('settings.website_font') }}</label>
t('settings.website_font') }}</label>
<div style="display: flex; align-items: center; gap: 10px;"> <div style="display: flex; align-items: center; gap: 10px;">
<select id="website_font_select" class="input" style="flex: 1; max-width: 300px;"> <select id="website_font_select" class="input" style="flex: 1; max-width: 300px;">
<option value="">{{ t('settings.font_default') }}</option> <option value="">{{ t('settings.font_default') }}</option>
@@ -255,8 +235,7 @@
</div> </div>
</div> </div>
<div class="setting-item" style="margin-top: 20px;"> <div class="setting-item" style="margin-top: 20px;">
<label for="website_theme_select" style="display: block; margin-bottom: 5px; font-weight: bold;">{{ <label for="website_theme_select" style="display: block; margin-bottom: 5px; font-weight: bold;">{{ t('settings.theme') }}</label>
t('settings.theme') }}</label>
<div style="display: flex; align-items: center; gap: 10px;"> <div style="display: flex; align-items: center; gap: 10px;">
<select id="website_theme_select" class="input" style="flex: 1; max-width: 300px;"> <select id="website_theme_select" class="input" style="flex: 1; max-width: 300px;">
@each(themes as t) @each(themes as t)
@@ -270,14 +249,12 @@
@if(enable_swf) @if(enable_swf)
<fieldset <fieldset
style="border: 1px solid var(--nav-border-color); padding: 10px; border-radius: 4px; margin-bottom: 15px;"> style="border: 1px solid var(--nav-border-color); padding: 10px; border-radius: 4px; margin-bottom: 15px;">
<legend style="width: auto; padding: 0 5px; font-size: 1.1em; font-weight: bold;">{{ <legend style="width: auto; padding: 0 5px; font-size: 1.1em; font-weight: bold;">{{ t('settings.flash_section') }}</legend>
t('settings.flash_section') }}</legend>
<div class="setting-item"> <div class="setting-item">
<label for="ruffle_background_toggle" <label for="ruffle_background_toggle"
style="cursor: pointer; display: flex; align-items: center; gap: 10px;"> style="cursor: pointer; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="ruffle_background_toggle" @if(session.ruffle_background !==false) checked <input type="checkbox" id="ruffle_background_toggle" @if(session.ruffle_background !==false) checked @endif>
@endif>
<span>{{ t('settings.flash_bg') }}</span> <span>{{ t('settings.flash_bg') }}</span>
</label> </label>
<small class="text-muted" style="margin-left: 25px;">{{ t('settings.flash_bg_hint') }}</small> <small class="text-muted" style="margin-left: 25px;">{{ t('settings.flash_bg_hint') }}</small>
@@ -289,11 +266,9 @@
</div> </div>
@if(enable_data_export) @if(enable_data_export)
<h2>{{ t('settings.export_data_title') || 'Export Data' }}</h2> <h2>{{ t('settings.export_data_title') || 'Export Data' }}</h2>
<div class="export-settings-wrapper" <div class="export-settings-wrapper" style="background: rgba(0,0,0,0.1); padding: 20px; border-radius: 4px; border: 1px solid var(--nav-border-color); margin-bottom: 30px;">
style="background: rgba(0,0,0,0.1); padding: 20px; border-radius: 4px; border: 1px solid var(--nav-border-color); margin-bottom: 30px;"> <p>{{ t('settings.export_data_desc') || 'Download a copy of your data. This process happens entirely in your browser to protect your privacy and save server resources.' }}</p>
<p>{{ t('settings.export_data_desc') || 'Download a copy of your data. This process happens entirely in your
browser to protect your privacy and save server resources.' }}</p>
<div class="setting-item" style="margin-bottom: 15px;"> <div class="setting-item" style="margin-bottom: 15px;">
<label class="checkbox-container" style="cursor: pointer; display: flex; align-items: center; gap: 10px;"> <label class="checkbox-container" style="cursor: pointer; display: flex; align-items: center; gap: 10px;">
<input type="checkbox" id="export_uploads" checked> <input type="checkbox" id="export_uploads" checked>
@@ -308,27 +283,25 @@
</div> </div>
<div id="export-progress-container" style="display: none; margin-bottom: 20px;"> <div id="export-progress-container" style="display: none; margin-bottom: 20px;">
<div class="progress-bar-wrapper" <div class="progress-bar-wrapper" style="height: 20px; background: rgba(255,255,255,0.1); border-radius: 10px; overflow: hidden; margin-bottom: 5px;">
style="height: 20px; background: rgba(255,255,255,0.1); border-radius: 10px; overflow: hidden; margin-bottom: 5px;"> <div id="export-progress-bar" style="height: 100%; width: 0%; background: var(--accent); transition: width 0.3s;"></div>
<div id="export-progress-bar"
style="height: 100%; width: 0%; background: var(--accent); transition: width 0.3s;"></div>
</div> </div>
<div id="export-status-text" style="font-size: 0.9em; color: var(--text-muted);" <div id="export-status-text"
data-fetching="{{ t('settings.export_fetching_data') }}" style="font-size: 0.9em; color: var(--text-muted);"
data-processing="{{ t('settings.export_processing_files') }}" data-fetching="{{ t('settings.export_fetching_data') }}"
data-generating="{{ t('settings.export_generating_zip') }}" data-processing="{{ t('settings.export_processing_files') }}"
data-complete="{{ t('settings.export_complete') }}" data-failed="{{ t('settings.export_failed') }}" data-generating="{{ t('settings.export_generating_zip') }}"
data-select-option="{{ t('settings.export_select_option') }}" data-complete="{{ t('settings.export_complete') }}"
data-no-data="{{ t('settings.export_no_data') }}" data-failed="{{ t('settings.export_failed') }}"
data-failed-alert="{{ t('settings.export_failed_alert') }}" data-domain="{{ site_domain }}"><span data-select-option="{{ t('settings.export_select_option') }}"
id="export-status-msg">{{ t('settings.export_preparing') || 'Preparing...' }}</span><span data-no-data="{{ t('settings.export_no_data') }}"
class="export-dots" id="export-animated-dots" data-failed-alert="{{ t('settings.export_failed_alert') }}"
style="display:none;"><span>.</span><span>.</span><span>.</span></span></div> data-domain="{{ site_domain }}"
><span id="export-status-msg">{{ t('settings.export_preparing') || 'Preparing...' }}</span><span class="export-dots" id="export-animated-dots" style="display:none;"><span>.</span><span>.</span><span>.</span></span></div>
</div> </div>
<button type="button" id="btn-start-export" class="button button-primary"> <button type="button" id="btn-start-export" class="button button-primary">
<i class="fa-solid fa-download" style="margin-right: 5px;"></i> {{ t('settings.start_export') || 'Generate <i class="fa-solid fa-download" style="margin-right: 5px;"></i> {{ t('settings.start_export') || 'Generate Export (ZIP)' }}
Export (ZIP)' }}
</button> </button>
</div> </div>
@endif @endif
@@ -340,8 +313,7 @@
style="margin-bottom: 30px; border-collapse: separate; border-spacing: 0 5px;"> style="margin-bottom: 30px; border-collapse: separate; border-spacing: 0 5px;">
<tbody> <tbody>
<tr> <tr>
<td style="width: 150px; font-weight: bold; color: var(--text-muted); border: none;">{{ <td style="width: 150px; font-weight: bold; color: var(--text-muted); border: none;">{{ t('settings.user_id') }}</td>
t('settings.user_id') }}</td>
<td style="border: none;">{{ session.id }}</td> <td style="border: none;">{{ session.id }}</td>
</tr> </tr>
<tr> <tr>
@@ -365,8 +337,7 @@
</tr> </tr>
<tr> <tr>
<td style="font-weight: bold; color: var(--text-muted); border: none;">{{ t('settings.joined') }}</td> <td style="font-weight: bold; color: var(--text-muted); border: none;">{{ t('settings.joined') }}</td>
<td style="border: none;">@if(joined){{ new Date(joined).toLocaleDateString() }}@else {{ <td style="border: none;">@if(joined){{ new Date(joined).toLocaleDateString() }}@else {{ t('settings.joined_unknown') }} @endif</td>
t('settings.joined_unknown') }} @endif</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -440,7 +411,8 @@
<div id="api-key-section" class="account-settings-wrapper" <div id="api-key-section" class="account-settings-wrapper"
style="background: rgba(0,0,0,0.1); padding: 20px; border-radius: 4px; border: 1px solid var(--nav-border-color); margin-bottom: 30px;"> style="background: rgba(0,0,0,0.1); padding: 20px; border-radius: 4px; border: 1px solid var(--nav-border-color); margin-bottom: 30px;">
<p style="color: var(--text-muted); margin-bottom: 15px;"> <p style="color: var(--text-muted); margin-bottom: 15px;">
Use this key to upload files via external tools or scripts like ShareX for example. Use this key to upload files via external tools or scripts without a browser session.
The key grants <strong>upload access only</strong> to your account — it cannot be used for comments or any other action.
</p> </p>
<div id="api-key-status-box" style="margin-bottom: 15px;"> <div id="api-key-status-box" style="margin-bottom: 15px;">
@@ -449,10 +421,8 @@
<!-- Shown only after regenerate — full key revealed once for copying --> <!-- Shown only after regenerate — full key revealed once for copying -->
<div id="api-key-reveal" style="display:none; margin-bottom: 15px;"> <div id="api-key-reveal" style="display:none; margin-bottom: 15px;">
<div <div style="background: rgba(0,180,100,0.12); border: 1px solid rgba(0,180,100,0.4); border-radius: 4px; padding: 14px;">
style="background: rgba(0,180,100,0.12); border: 1px solid rgba(0,180,100,0.4); border-radius: 4px; padding: 14px;"> <strong style="display:block; margin-bottom: 6px;">&#9888; Copy your key now &mdash; it will not be shown again in full:</strong>
<strong style="display:block; margin-bottom: 6px;">&#9888; Copy your key now &mdash; it will not be shown
again in full:</strong>
<div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;"> <div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
<code id="api-key-full-display" <code id="api-key-full-display"
style="flex: 1; word-break: break-all; font-size: 0.85em; background: rgba(0,0,0,0.25); padding: 8px 10px; border-radius: 4px; user-select: all;"></code> style="flex: 1; word-break: break-all; font-size: 0.85em; background: rgba(0,0,0,0.25); padding: 8px 10px; border-radius: 4px; user-select: all;"></code>
@@ -464,40 +434,22 @@
<div style="display: flex; gap: 10px; flex-wrap: wrap; align-items: center;"> <div style="display: flex; gap: 10px; flex-wrap: wrap; align-items: center;">
<button type="button" id="btn-regen-api-key" class="button button-primary">Generate / Regenerate Key</button> <button type="button" id="btn-regen-api-key" class="button button-primary">Generate / Regenerate Key</button>
<button type="button" id="btn-revoke-api-key" class="button button-danger" style="display:none;">Revoke <button type="button" id="btn-revoke-api-key" class="button button-danger" style="display:none;">Revoke Key</button>
Key</button>
</div> </div>
<div id="api-key-action-status" class="avatar-status" style="margin-top: 10px;"></div> <div id="api-key-action-status" class="avatar-status" style="margin-top: 10px;"></div>
</div> </div>
<style> <style>
@keyframes exportDotBounce { @keyframes exportDotBounce {
0%, 80%, 100% { transform: translateY(0); opacity: 0.3; }
0%, 40% { transform: translateY(-5px); opacity: 1; }
80%,
100% {
transform: translateY(0);
opacity: 0.3;
}
40% {
transform: translateY(-5px);
opacity: 1;
}
} }
.export-dots span { .export-dots span {
display: inline-block; display: inline-block;
animation: exportDotBounce 1.2s infinite ease-in-out; animation: exportDotBounce 1.2s infinite ease-in-out;
} }
.export-dots span:nth-child(2) { animation-delay: 0.2s; }
.export-dots span:nth-child(2) { .export-dots span:nth-child(3) { animation-delay: 0.4s; }
animation-delay: 0.2s;
}
.export-dots span:nth-child(3) {
animation-delay: 0.4s;
}
</style> </style>
<script src="/s/js/jszip.min.js"></script> <script src="/s/js/jszip.min.js"></script>
<script src="/s/js/settings.js?v=@mtime(/public/s/js/settings.js)"></script> <script src="/s/js/settings.js?v=@mtime(/public/s/js/settings.js)"></script>