GameSentenceMiner 2.16.7__py3-none-any.whl → 2.16.9__py3-none-any.whl
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.
- GameSentenceMiner/config_gui.py +54 -4
- GameSentenceMiner/gsm.py +89 -40
- GameSentenceMiner/locales/en_us.json +16 -0
- GameSentenceMiner/locales/ja_jp.json +16 -0
- GameSentenceMiner/locales/zh_cn.json +16 -0
- GameSentenceMiner/util/configuration.py +5 -0
- GameSentenceMiner/util/db.py +83 -2
- GameSentenceMiner/util/ffmpeg.py +1 -0
- GameSentenceMiner/util/get_overlay_coords.py +29 -1
- GameSentenceMiner/vad.py +3 -13
- GameSentenceMiner/web/database_api.py +54 -29
- GameSentenceMiner/web/static/js/search.js +1 -1
- GameSentenceMiner/web/static/js/stats.js +35 -11
- GameSentenceMiner/web/templates/stats.html +467 -425
- {gamesentenceminer-2.16.7.dist-info → gamesentenceminer-2.16.9.dist-info}/METADATA +1 -1
- {gamesentenceminer-2.16.7.dist-info → gamesentenceminer-2.16.9.dist-info}/RECORD +20 -20
- {gamesentenceminer-2.16.7.dist-info → gamesentenceminer-2.16.9.dist-info}/WHEEL +0 -0
- {gamesentenceminer-2.16.7.dist-info → gamesentenceminer-2.16.9.dist-info}/entry_points.txt +0 -0
- {gamesentenceminer-2.16.7.dist-info → gamesentenceminer-2.16.9.dist-info}/licenses/LICENSE +0 -0
- {gamesentenceminer-2.16.7.dist-info → gamesentenceminer-2.16.9.dist-info}/top_level.txt +0 -0
|
@@ -1,520 +1,562 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
+
|
|
3
4
|
<head>
|
|
4
5
|
<meta charset="UTF-8">
|
|
5
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
7
|
<title>GSM Dashboard</title>
|
|
7
8
|
<!-- Include Chart.js from a CDN -->
|
|
8
9
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
<!-- Include html2canvas for screenshot functionality -->
|
|
11
12
|
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
|
|
12
|
-
|
|
13
|
+
|
|
13
14
|
<!-- Include shared theme styles -->
|
|
14
15
|
{% include 'components/theme-styles.html' %}
|
|
15
|
-
|
|
16
|
+
|
|
16
17
|
<!-- Include shared CSS -->
|
|
17
18
|
<link rel="stylesheet" href="/static/css/shared.css">
|
|
18
|
-
|
|
19
|
+
|
|
19
20
|
<!-- Include stats-specific CSS -->
|
|
20
21
|
<link rel="stylesheet" href="/static/css/stats.css">
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
<!-- Include shared kanji grid CSS -->
|
|
23
24
|
<link rel="stylesheet" href="/static/css/kanji-grid.css">
|
|
24
25
|
</head>
|
|
26
|
+
|
|
25
27
|
<body>
|
|
26
28
|
|
|
27
|
-
<div class="container">
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<!-- Include shared navigation -->
|
|
31
|
-
{% include 'components/navigation.html' %}
|
|
29
|
+
<div class="container">
|
|
30
|
+
<h1>GSM - Statistics</h1>
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<div class="dashboard-stat-item tooltip" data-tooltip="Total characters read in this game">
|
|
52
|
-
<span class="dashboard-stat-value" id="currentTotalChars">-</span>
|
|
53
|
-
<span class="dashboard-stat-label">Characters</span>
|
|
54
|
-
</div>
|
|
55
|
-
<div class="dashboard-stat-item tooltip" data-tooltip="Total time spent reading this game">
|
|
56
|
-
<span class="dashboard-stat-value" id="currentTotalTime">-</span>
|
|
57
|
-
<span class="dashboard-stat-label">Time Spent</span>
|
|
58
|
-
</div>
|
|
59
|
-
<div class="dashboard-stat-item tooltip" data-tooltip="Average reading speed for this game">
|
|
60
|
-
<span class="dashboard-stat-value" id="currentReadingSpeed">-</span>
|
|
61
|
-
<span class="dashboard-stat-label">Chars/Hour</span>
|
|
62
|
-
</div>
|
|
63
|
-
<div class="dashboard-stat-item tooltip" data-tooltip="Number of reading sessions for this game">
|
|
64
|
-
<span class="dashboard-stat-value" id="currentSessions">-</span>
|
|
65
|
-
<span class="dashboard-stat-label">Sessions</span>
|
|
32
|
+
<!-- Include shared navigation -->
|
|
33
|
+
{% include 'components/navigation.html' %}
|
|
34
|
+
|
|
35
|
+
<!-- Dashboard Statistics Sections -->
|
|
36
|
+
<div class="dashboard-container">
|
|
37
|
+
<!-- Current Game Statistics Panel -->
|
|
38
|
+
<div class="dashboard-card current-game" id="currentGameCard">
|
|
39
|
+
<div class="dashboard-card-header">
|
|
40
|
+
<div>
|
|
41
|
+
<h3 class="dashboard-card-title">
|
|
42
|
+
<span class="dashboard-card-icon">🎮</span>
|
|
43
|
+
Current Game Statistics
|
|
44
|
+
</h3>
|
|
45
|
+
<p class="dashboard-card-subtitle" id="currentGameName">Loading...</p>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="dashboard-streak-indicator" id="currentGameStreak" style="display: none;">
|
|
48
|
+
<span id="currentStreakValue">0</span> day streak
|
|
49
|
+
</div>
|
|
66
50
|
</div>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<
|
|
51
|
+
|
|
52
|
+
<div class="dashboard-stats-grid" id="currentGameStats">
|
|
53
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Total characters read in this game">
|
|
54
|
+
<span class="dashboard-stat-value" id="currentTotalChars">-</span>
|
|
55
|
+
<span class="dashboard-stat-label">Characters</span>
|
|
56
|
+
</div>
|
|
57
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Total time spent reading this game">
|
|
58
|
+
<span class="dashboard-stat-value" id="currentTotalTime">-</span>
|
|
59
|
+
<span class="dashboard-stat-label">Time Spent</span>
|
|
75
60
|
</div>
|
|
76
|
-
<div class="dashboard-
|
|
77
|
-
<
|
|
78
|
-
<
|
|
61
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Average reading speed for this game">
|
|
62
|
+
<span class="dashboard-stat-value" id="currentReadingSpeed">-</span>
|
|
63
|
+
<span class="dashboard-stat-label">Chars/Hour</span>
|
|
79
64
|
</div>
|
|
80
|
-
<div class="dashboard-
|
|
81
|
-
<
|
|
82
|
-
<
|
|
65
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Number of reading sessions for this game">
|
|
66
|
+
<span class="dashboard-stat-value" id="currentSessions">-</span>
|
|
67
|
+
<span class="dashboard-stat-label">Sessions</span>
|
|
83
68
|
</div>
|
|
84
69
|
</div>
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
70
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
71
|
+
<div class="dashboard-progress-section">
|
|
72
|
+
<div class="dashboard-progress-title">Recent Progress</div>
|
|
73
|
+
<div class="dashboard-progress-items">
|
|
74
|
+
<div class="dashboard-progress-item">
|
|
75
|
+
<div class="dashboard-progress-value positive" id="currentMonthlyChars">-</div>
|
|
76
|
+
<div class="dashboard-progress-label">Monthly Characters</div>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="dashboard-progress-item">
|
|
79
|
+
<div class="dashboard-progress-value neutral" id="currentFirstDate">-</div>
|
|
80
|
+
<div class="dashboard-progress-label">Started</div>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="dashboard-progress-item">
|
|
83
|
+
<div class="dashboard-progress-value neutral" id="currentLastDate">-</div>
|
|
84
|
+
<div class="dashboard-progress-label">Last Activity</div>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
100
87
|
</div>
|
|
101
88
|
</div>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
<
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
<div class="dashboard-stat-item tooltip" data-tooltip="Total number of reading sessions">
|
|
117
|
-
<span class="dashboard-stat-value" id="allSessions">-</span>
|
|
118
|
-
<span class="dashboard-stat-label">Sessions</span>
|
|
89
|
+
|
|
90
|
+
<!-- All Games Historical Overview -->
|
|
91
|
+
<div class="dashboard-card all-games" id="allGamesCard">
|
|
92
|
+
<div class="dashboard-card-header">
|
|
93
|
+
<div>
|
|
94
|
+
<h3 class="dashboard-card-title">
|
|
95
|
+
<span class="dashboard-card-icon">📚</span>
|
|
96
|
+
All Games Overview
|
|
97
|
+
</h3>
|
|
98
|
+
<p class="dashboard-card-subtitle" id="totalGamesCount">Loading...</p>
|
|
99
|
+
</div>
|
|
100
|
+
<div class="dashboard-streak-indicator" id="allGamesStreak" style="display: none;">
|
|
101
|
+
<span id="allStreakValue">0</span> day streak
|
|
102
|
+
</div>
|
|
119
103
|
</div>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<
|
|
104
|
+
|
|
105
|
+
<div class="dashboard-stats-grid" id="allGamesStats">
|
|
106
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Total characters read across all games">
|
|
107
|
+
<span class="dashboard-stat-value" id="allTotalChars">-</span>
|
|
108
|
+
<span class="dashboard-stat-label">Characters</span>
|
|
109
|
+
</div>
|
|
110
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Total time spent reading across all games">
|
|
111
|
+
<span class="dashboard-stat-value" id="allTotalTime">-</span>
|
|
112
|
+
<span class="dashboard-stat-label">Time Spent</span>
|
|
113
|
+
</div>
|
|
114
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Overall average reading speed">
|
|
115
|
+
<span class="dashboard-stat-value" id="allReadingSpeed">-</span>
|
|
116
|
+
<span class="dashboard-stat-label">Chars/Hour</span>
|
|
128
117
|
</div>
|
|
129
|
-
<div class="dashboard-
|
|
130
|
-
<
|
|
131
|
-
<
|
|
118
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Total number of reading sessions">
|
|
119
|
+
<span class="dashboard-stat-value" id="allSessions">-</span>
|
|
120
|
+
<span class="dashboard-stat-label">Sessions</span>
|
|
132
121
|
</div>
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<div class="dashboard-progress-section">
|
|
125
|
+
<div class="dashboard-progress-title">Overall Progress</div>
|
|
126
|
+
<div class="dashboard-progress-items">
|
|
127
|
+
<div class="dashboard-progress-item">
|
|
128
|
+
<div class="dashboard-progress-value positive" id="allMonthlyChars">-</div>
|
|
129
|
+
<div class="dashboard-progress-label">Monthly Characters</div>
|
|
130
|
+
</div>
|
|
131
|
+
<div class="dashboard-progress-item">
|
|
132
|
+
<div class="dashboard-progress-value neutral" id="allUniqueGames">-</div>
|
|
133
|
+
<div class="dashboard-progress-label">Games Played</div>
|
|
134
|
+
</div>
|
|
135
|
+
<div class="dashboard-progress-item">
|
|
136
|
+
<div class="dashboard-progress-value neutral" id="allTotalSentences">-</div>
|
|
137
|
+
<div class="dashboard-progress-label">Total Sentences</div>
|
|
138
|
+
</div>
|
|
136
139
|
</div>
|
|
137
140
|
</div>
|
|
138
141
|
</div>
|
|
139
142
|
</div>
|
|
140
|
-
</div>
|
|
141
143
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
<!-- Loading/Error states for dashboard -->
|
|
145
|
+
<div class="dashboard-loading" id="dashboardLoading" style="display: none;">
|
|
146
|
+
<div class="spinner"></div>
|
|
147
|
+
<span>Loading dashboard statistics...</span>
|
|
148
|
+
</div>
|
|
147
149
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
<div class="dashboard-error" id="dashboardError" style="display: none;">
|
|
151
|
+
<div class="dashboard-error-icon">⚠️</div>
|
|
152
|
+
<div class="dashboard-error-message">Failed to load dashboard statistics</div>
|
|
153
|
+
<button class="dashboard-retry-btn" data-action="loadDashboardData">Retry</button>
|
|
154
|
+
</div>
|
|
153
155
|
|
|
154
156
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
</div>
|
|
164
|
-
<div class="dashboard-stats-grid" id="todayStats">
|
|
165
|
-
<div class="dashboard-stat-item tooltip" data-tooltip="Total hours spent reading today">
|
|
166
|
-
<span class="dashboard-stat-value" id="todayTotalHours">-</span>
|
|
167
|
-
<span class="dashboard-stat-label">Hours Spent</span>
|
|
168
|
-
</div>
|
|
169
|
-
<div class="dashboard-stat-item tooltip" data-tooltip="Total characters read today">
|
|
170
|
-
<span class="dashboard-stat-value" id="todayTotalChars">-</span>
|
|
171
|
-
<span class="dashboard-stat-label">Characters</span>
|
|
172
|
-
</div>
|
|
173
|
-
<div class="dashboard-stat-item tooltip" data-tooltip="Number of reading sessions today">
|
|
174
|
-
<span class="dashboard-stat-value" id="todaySessions">-</span>
|
|
175
|
-
<span class="dashboard-stat-label">Sessions</span>
|
|
157
|
+
<!-- Today's Overview Card -->
|
|
158
|
+
<div class="dashboard-card today-overview" id="todayOverviewCard" style="margin-bottom: 24px;">
|
|
159
|
+
<div class="dashboard-card-header">
|
|
160
|
+
<h3 class="dashboard-card-title">
|
|
161
|
+
<span class="dashboard-card-icon">📅</span>
|
|
162
|
+
Today's Overview
|
|
163
|
+
</h3>
|
|
164
|
+
<p class="dashboard-card-subtitle" id="todayDate">Loading...</p>
|
|
176
165
|
</div>
|
|
177
|
-
<div class="dashboard-
|
|
178
|
-
<
|
|
179
|
-
|
|
166
|
+
<div class="dashboard-stats-grid" id="todayStats">
|
|
167
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Total hours spent reading today">
|
|
168
|
+
<span class="dashboard-stat-value" id="todayTotalHours">-</span>
|
|
169
|
+
<span class="dashboard-stat-label">Hours Spent</span>
|
|
170
|
+
</div>
|
|
171
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Total characters read today">
|
|
172
|
+
<span class="dashboard-stat-value" id="todayTotalChars">-</span>
|
|
173
|
+
<span class="dashboard-stat-label">Characters</span>
|
|
174
|
+
</div>
|
|
175
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Number of reading sessions today">
|
|
176
|
+
<span class="dashboard-stat-value" id="todaySessions">-</span>
|
|
177
|
+
<span class="dashboard-stat-label">Sessions</span>
|
|
178
|
+
</div>
|
|
179
|
+
<div class="dashboard-stat-item tooltip" data-tooltip="Average reading speed today">
|
|
180
|
+
<span class="dashboard-stat-value" id="todayCharsPerHour">-</span>
|
|
181
|
+
<span class="dashboard-stat-label">Chars/Hour</span>
|
|
182
|
+
</div>
|
|
180
183
|
</div>
|
|
181
184
|
</div>
|
|
182
|
-
</div>
|
|
183
185
|
|
|
184
186
|
<!-- Goal Progress Chart -->
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
187
|
+
<div class="dashboard-card goal-progress-chart" id="goalProgressChart" style="margin-bottom: 30px;">
|
|
188
|
+
<div class="dashboard-card-header">
|
|
189
|
+
<h3 class="dashboard-card-title">
|
|
190
|
+
<span class="dashboard-card-icon">🎯</span>
|
|
191
|
+
Goal Progress Chart
|
|
192
|
+
</h3>
|
|
193
|
+
<p class="dashboard-card-subtitle">Track your reading goals and projected completion dates</p>
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<div class="goal-progress-grid">
|
|
197
|
+
<!-- Reading Hours Goal -->
|
|
198
|
+
<div class="goal-progress-item">
|
|
199
|
+
<div class="goal-progress-header">
|
|
200
|
+
<div class="goal-progress-label">
|
|
201
|
+
<span class="goal-icon">⏱️</span>
|
|
202
|
+
Reading Hours
|
|
203
|
+
</div>
|
|
204
|
+
<div class="goal-progress-values">
|
|
205
|
+
<span class="goal-current" id="goalHoursCurrent">-</span>
|
|
206
|
+
<span class="goal-separator">/</span>
|
|
207
|
+
<span class="goal-target" id="goalHoursTarget">-</span>
|
|
208
|
+
</div>
|
|
201
209
|
</div>
|
|
202
|
-
<div class="goal-progress-
|
|
203
|
-
<
|
|
204
|
-
|
|
205
|
-
|
|
210
|
+
<div class="goal-progress-bar">
|
|
211
|
+
<div class="goal-progress-fill" id="goalHoursProgress" data-percentage="0"></div>
|
|
212
|
+
</div>
|
|
213
|
+
<div class="goal-progress-info">
|
|
214
|
+
<span class="goal-percentage" id="goalHoursPercentage">0%</span>
|
|
215
|
+
<span class="goal-projection" id="goalHoursProjection">-</span>
|
|
206
216
|
</div>
|
|
207
217
|
</div>
|
|
208
|
-
<div class="goal-progress-bar">
|
|
209
|
-
<div class="goal-progress-fill" id="goalHoursProgress" data-percentage="0"></div>
|
|
210
|
-
</div>
|
|
211
|
-
<div class="goal-progress-info">
|
|
212
|
-
<span class="goal-percentage" id="goalHoursPercentage">0%</span>
|
|
213
|
-
<span class="goal-projection" id="goalHoursProjection">-</span>
|
|
214
|
-
</div>
|
|
215
|
-
</div>
|
|
216
218
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
219
|
+
<!-- Character Count Goal -->
|
|
220
|
+
<div class="goal-progress-item">
|
|
221
|
+
<div class="goal-progress-header">
|
|
222
|
+
<div class="goal-progress-label">
|
|
223
|
+
<span class="goal-icon">📖</span>
|
|
224
|
+
Characters Read
|
|
225
|
+
</div>
|
|
226
|
+
<div class="goal-progress-values">
|
|
227
|
+
<span class="goal-current" id="goalCharsCurrent">-</span>
|
|
228
|
+
<span class="goal-separator">/</span>
|
|
229
|
+
<span class="goal-target" id="goalCharsTarget">-</span>
|
|
230
|
+
</div>
|
|
223
231
|
</div>
|
|
224
|
-
<div class="goal-progress-
|
|
225
|
-
<
|
|
226
|
-
|
|
227
|
-
|
|
232
|
+
<div class="goal-progress-bar">
|
|
233
|
+
<div class="goal-progress-fill" id="goalCharsProgress" data-percentage="0"></div>
|
|
234
|
+
</div>
|
|
235
|
+
<div class="goal-progress-info">
|
|
236
|
+
<span class="goal-percentage" id="goalCharsPercentage">0%</span>
|
|
237
|
+
<span class="goal-projection" id="goalCharsProjection">-</span>
|
|
228
238
|
</div>
|
|
229
239
|
</div>
|
|
230
|
-
<div class="goal-progress-bar">
|
|
231
|
-
<div class="goal-progress-fill" id="goalCharsProgress" data-percentage="0"></div>
|
|
232
|
-
</div>
|
|
233
|
-
<div class="goal-progress-info">
|
|
234
|
-
<span class="goal-percentage" id="goalCharsPercentage">0%</span>
|
|
235
|
-
<span class="goal-projection" id="goalCharsProjection">-</span>
|
|
236
|
-
</div>
|
|
237
|
-
</div>
|
|
238
240
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
241
|
+
<!-- Games Goal -->
|
|
242
|
+
<div class="goal-progress-item">
|
|
243
|
+
<div class="goal-progress-header">
|
|
244
|
+
<div class="goal-progress-label">
|
|
245
|
+
<span class="goal-icon">🎮</span>
|
|
246
|
+
Games
|
|
247
|
+
</div>
|
|
248
|
+
<div class="goal-progress-values">
|
|
249
|
+
<span class="goal-current" id="goalGamesCurrent">-</span>
|
|
250
|
+
<span class="goal-separator">/</span>
|
|
251
|
+
<span class="goal-target" id="goalGamesTarget">-</span>
|
|
252
|
+
</div>
|
|
245
253
|
</div>
|
|
246
|
-
<div class="goal-progress-
|
|
247
|
-
<
|
|
248
|
-
|
|
249
|
-
|
|
254
|
+
<div class="goal-progress-bar">
|
|
255
|
+
<div class="goal-progress-fill" id="goalGamesProgress" data-percentage="0"></div>
|
|
256
|
+
</div>
|
|
257
|
+
<div class="goal-progress-info">
|
|
258
|
+
<span class="goal-percentage" id="goalGamesPercentage">0%</span>
|
|
259
|
+
<span class="goal-projection" id="goalGamesProjection">-</span>
|
|
250
260
|
</div>
|
|
251
|
-
</div>
|
|
252
|
-
<div class="goal-progress-bar">
|
|
253
|
-
<div class="goal-progress-fill" id="goalGamesProgress" data-percentage="0"></div>
|
|
254
|
-
</div>
|
|
255
|
-
<div class="goal-progress-info">
|
|
256
|
-
<span class="goal-percentage" id="goalGamesPercentage">0%</span>
|
|
257
|
-
<span class="goal-projection" id="goalGamesProjection">-</span>
|
|
258
261
|
</div>
|
|
259
262
|
</div>
|
|
260
|
-
</div>
|
|
261
263
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
264
|
+
<!-- Loading/Error states -->
|
|
265
|
+
<div class="goal-progress-loading" id="goalProgressLoading" style="display: none;">
|
|
266
|
+
<div class="spinner"></div>
|
|
267
|
+
<span>Loading goal progress...</span>
|
|
268
|
+
</div>
|
|
267
269
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
<div class="goal-progress-error" id="goalProgressError" style="display: none;">
|
|
271
|
+
<div class="goal-progress-error-icon">⚠️</div>
|
|
272
|
+
<div class="goal-progress-error-message">Failed to load goal progress</div>
|
|
273
|
+
<button class="retry-btn" onclick="loadGoalProgress()">Retry</button>
|
|
274
|
+
</div>
|
|
272
275
|
</div>
|
|
273
|
-
</div>
|
|
274
|
-
|
|
275
|
-
<div class="chart-container">
|
|
276
|
-
<h2>Activity Heatmap</h2>
|
|
277
|
-
<div id="heatmapContainer"></div>
|
|
278
|
-
</div>
|
|
279
|
-
|
|
280
|
-
<div class="chart-container">
|
|
281
|
-
<h2>Lines Received Over Time</h2>
|
|
282
|
-
<canvas id="linesChart"></canvas>
|
|
283
|
-
</div>
|
|
284
276
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
<div class="chart-container">
|
|
291
|
-
<h2>Reading Chars Quantity</h2>
|
|
292
|
-
<canvas id="readingCharsChart"></canvas>
|
|
293
|
-
</div>
|
|
277
|
+
<div class="chart-container">
|
|
278
|
+
<h2>Activity Heatmap</h2>
|
|
279
|
+
<div id="heatmapContainer"></div>
|
|
280
|
+
</div>
|
|
294
281
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
282
|
+
<div class="chart-container">
|
|
283
|
+
<h2>Lines Received Over Time</h2>
|
|
284
|
+
<canvas id="linesChart"></canvas>
|
|
285
|
+
</div>
|
|
299
286
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
287
|
+
<div class="chart-container">
|
|
288
|
+
<h2>Characters Read Over Time</h2>
|
|
289
|
+
<canvas id="charsChart"></canvas>
|
|
290
|
+
</div>
|
|
304
291
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
<div id="kanjiCounter" class="kanji-counter">
|
|
309
|
-
Unique Kanji Seen: <span id="kanjiCount">0</span>
|
|
310
|
-
</div>
|
|
311
|
-
<div id="kanjiGrid" class="kanji-grid"></div>
|
|
312
|
-
<div class="kanji-legend">
|
|
313
|
-
<span>Rarely Seen</span>
|
|
314
|
-
<div class="kanji-legend-item" style="background-color: #ebedf0;" title="No encounters"></div>
|
|
315
|
-
<div class="kanji-legend-item" style="background-color: #e6342e;" title="Seen once"></div>
|
|
316
|
-
<div class="kanji-legend-item" style="background-color: #e6dc2e;" title="Occasionally seen"></div>
|
|
317
|
-
<div class="kanji-legend-item" style="background-color: #3be62f;" title="Frequently seen"></div>
|
|
318
|
-
<div class="kanji-legend-item" style="background-color: #2ee6e0;" title="Most frequently seen"></div>
|
|
319
|
-
<span>Frequently Seen</span>
|
|
320
|
-
</div>
|
|
292
|
+
<div class="chart-container">
|
|
293
|
+
<h2>Reading Chars Quantity</h2>
|
|
294
|
+
<canvas id="readingCharsChart"></canvas>
|
|
321
295
|
</div>
|
|
322
|
-
</div>
|
|
323
296
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
<h3>Statistics Settings</h3>
|
|
329
|
-
<span class="close-btn" id="closeSettingsModal">×</span>
|
|
330
|
-
</div>
|
|
331
|
-
<div class="modal-body">
|
|
332
|
-
<p style="color: var(--text-secondary); margin-bottom: 20px;">
|
|
333
|
-
Configure how reading time and sessions are calculated for your statistics.
|
|
334
|
-
</p>
|
|
335
|
-
|
|
336
|
-
<form id="settingsForm">
|
|
337
|
-
<div style="margin-bottom: 20px;">
|
|
338
|
-
<label for="afkTimer" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
339
|
-
AFK Timer (seconds)
|
|
340
|
-
</label>
|
|
341
|
-
<input
|
|
342
|
-
type="number"
|
|
343
|
-
id="afkTimer"
|
|
344
|
-
name="afk_timer_seconds"
|
|
345
|
-
style="width: 90%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
|
|
346
|
-
placeholder="120"
|
|
347
|
-
>
|
|
348
|
-
<small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
349
|
-
Maximum time between activities that still counts as active reading
|
|
350
|
-
</small>
|
|
351
|
-
</div>
|
|
352
|
-
|
|
353
|
-
<div style="margin-bottom: 20px;">
|
|
354
|
-
<label for="sessionGap" style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
355
|
-
Session Gap (seconds)
|
|
356
|
-
</label>
|
|
357
|
-
<input
|
|
358
|
-
type="number"
|
|
359
|
-
id="sessionGap"
|
|
360
|
-
name="session_gap_seconds"
|
|
361
|
-
style="width: 90%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
|
|
362
|
-
placeholder="3600"
|
|
363
|
-
>
|
|
364
|
-
<small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
365
|
-
Time gap that triggers a new reading session
|
|
366
|
-
</small>
|
|
367
|
-
</div>
|
|
297
|
+
<div class="chart-container">
|
|
298
|
+
<h2>Reading Time Quantity</h2>
|
|
299
|
+
<canvas id="readingTimeChart"></canvas>
|
|
300
|
+
</div>
|
|
368
301
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
<select
|
|
374
|
-
id="heatmapYear"
|
|
375
|
-
name="heatmap_year"
|
|
376
|
-
style="width: 100%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
|
|
377
|
-
>
|
|
378
|
-
<option value="all">All Years</option>
|
|
379
|
-
</select>
|
|
380
|
-
<small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
381
|
-
Select which year to display in the reading activity heatmap
|
|
382
|
-
</small>
|
|
383
|
-
</div>
|
|
302
|
+
<div class="chart-container">
|
|
303
|
+
<h2>Reading Speed Improvement</h2>
|
|
304
|
+
<canvas id="readingSpeedPerGameChart"></canvas>
|
|
305
|
+
</div>
|
|
384
306
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
<small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
400
|
-
Minimum hours of reading activity required to maintain streak (0.01-24 hours)
|
|
401
|
-
</small>
|
|
307
|
+
<div class="chart-container">
|
|
308
|
+
<h2>Kanji Grid</h2>
|
|
309
|
+
<div id="kanjiGridContainer">
|
|
310
|
+
<div id="kanjiCounter" class="kanji-counter">
|
|
311
|
+
Unique Kanji Seen: <span id="kanjiCount">0</span>
|
|
312
|
+
</div>
|
|
313
|
+
<div id="kanjiGrid" class="kanji-grid"></div>
|
|
314
|
+
<div class="kanji-legend">
|
|
315
|
+
<span>Rarely Seen</span>
|
|
316
|
+
<div class="kanji-legend-item" style="background-color: #ebedf0;" title="No encounters"></div>
|
|
317
|
+
<div class="kanji-legend-item" style="background-color: #e6342e;" title="Seen once"></div>
|
|
318
|
+
<div class="kanji-legend-item" style="background-color: #e6dc2e;" title="Occasionally seen"></div>
|
|
319
|
+
<div class="kanji-legend-item" style="background-color: #3be62f;" title="Frequently seen"></div>
|
|
320
|
+
<div class="kanji-legend-item" style="background-color: #2ee6e0;" title="Most frequently seen">
|
|
402
321
|
</div>
|
|
322
|
+
<span>Frequently Seen</span>
|
|
323
|
+
</div>
|
|
324
|
+
</div>
|
|
325
|
+
</div>
|
|
403
326
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
327
|
+
<!-- Settings Modal -->
|
|
328
|
+
<div id="settingsModal" class="modal">
|
|
329
|
+
<div class="modal-content">
|
|
330
|
+
<div class="modal-header">
|
|
331
|
+
<h3>Statistics Settings</h3>
|
|
332
|
+
<span class="close-btn" id="closeSettingsModal">×</span>
|
|
333
|
+
</div>
|
|
334
|
+
<div class="modal-body">
|
|
335
|
+
<p style="color: var(--text-secondary); margin-bottom: 20px;">
|
|
336
|
+
Configure how reading time and sessions are calculated for your statistics.
|
|
337
|
+
</p>
|
|
338
|
+
<form id="settingsForm">
|
|
339
|
+
<!-- <div style="margin-bottom: 20px;">
|
|
340
|
+
<label for="timezone-select"
|
|
341
|
+
style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
342
|
+
Timezone
|
|
416
343
|
</label>
|
|
417
|
-
<
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
>
|
|
344
|
+
<div style="display: flex; gap: 8px;">
|
|
345
|
+
<select id="timezone-select" name="timezone"
|
|
346
|
+
style="flex-grow: 1; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;">
|
|
347
|
+
</select>
|
|
348
|
+
<button id="set-local-timezone-btn"
|
|
349
|
+
style="padding: 10px; border: none; border-radius: 5px; background: var(--primary-color); color: white; font-size: 14px; cursor: pointer;">
|
|
350
|
+
Set to Local
|
|
351
|
+
</button>
|
|
352
|
+
</div>
|
|
426
353
|
<small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
427
|
-
|
|
354
|
+
Select the timezone to base your statistics on
|
|
355
|
+
</small>
|
|
356
|
+
</div> -->
|
|
357
|
+
|
|
358
|
+
<div style="margin-bottom: 20px;">
|
|
359
|
+
<label for="afkTimer"
|
|
360
|
+
style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
361
|
+
AFK Timer (seconds)
|
|
362
|
+
</label>
|
|
363
|
+
<input type="number" id="afkTimer" name="afk_timer_seconds"
|
|
364
|
+
style="padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
|
|
365
|
+
placeholder="120">
|
|
366
|
+
<small
|
|
367
|
+
style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
368
|
+
Maximum time between activities that still counts as active reading
|
|
428
369
|
</small>
|
|
429
370
|
</div>
|
|
430
|
-
|
|
431
|
-
<div style="margin-bottom:
|
|
432
|
-
<label for="
|
|
433
|
-
|
|
371
|
+
|
|
372
|
+
<div style="margin-bottom: 20px;">
|
|
373
|
+
<label for="sessionGap"
|
|
374
|
+
style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
375
|
+
Session Gap (seconds)
|
|
434
376
|
</label>
|
|
435
|
-
<input
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
style="width: 90%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
|
|
442
|
-
placeholder="25000000"
|
|
443
|
-
>
|
|
444
|
-
<small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
445
|
-
Total characters read goal (1,000-1,000,000,000) - Default: 25 million characters
|
|
377
|
+
<input type="number" id="sessionGap" name="session_gap_seconds"
|
|
378
|
+
style="padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
|
|
379
|
+
placeholder="3600">
|
|
380
|
+
<small
|
|
381
|
+
style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
382
|
+
Time gap that triggers a new reading session
|
|
446
383
|
</small>
|
|
447
384
|
</div>
|
|
448
|
-
|
|
449
|
-
<div style="margin-bottom:
|
|
450
|
-
<label for="
|
|
451
|
-
|
|
385
|
+
|
|
386
|
+
<div style="margin-bottom: 20px;">
|
|
387
|
+
<label for="heatmapYear"
|
|
388
|
+
style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
389
|
+
Heatmap Display Year
|
|
452
390
|
</label>
|
|
453
|
-
<
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
placeholder="100"
|
|
461
|
-
>
|
|
462
|
-
<small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
463
|
-
Number of games/visual novels to complete (1-1,000) - Default: 100 based on Refold standards
|
|
391
|
+
<select id="heatmapYear" name="heatmap_year"
|
|
392
|
+
style="width: 100%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;">
|
|
393
|
+
<option value="all">All Years</option>
|
|
394
|
+
</select>
|
|
395
|
+
<small
|
|
396
|
+
style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
397
|
+
Select which year to display in the reading activity heatmap
|
|
464
398
|
</small>
|
|
465
399
|
</div>
|
|
466
|
-
</div>
|
|
467
400
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
style="
|
|
479
|
-
|
|
480
|
-
<small style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
481
|
-
Select an ExStatic CSV file to import reading data into GSM
|
|
401
|
+
<div style="margin-bottom: 20px;">
|
|
402
|
+
<label for="streakRequirement"
|
|
403
|
+
style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
404
|
+
Streak Requirement (hours)
|
|
405
|
+
</label>
|
|
406
|
+
<input type="number" id="streakRequirement" name="streak_requirement_hours" min="0.01"
|
|
407
|
+
max="24" step="0.01"
|
|
408
|
+
style="padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
|
|
409
|
+
placeholder="1.0">
|
|
410
|
+
<small
|
|
411
|
+
style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
412
|
+
Minimum hours of reading activity required to maintain streak (0.01-24 hours)
|
|
482
413
|
</small>
|
|
483
414
|
</div>
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
415
|
+
|
|
416
|
+
<!-- Reading Goals Section -->
|
|
417
|
+
<div style="margin-bottom: 20px; padding-top: 20px; border-top: 1px solid var(--border-color);">
|
|
418
|
+
<label
|
|
419
|
+
style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
420
|
+
Reading Goals Configuration
|
|
421
|
+
</label>
|
|
422
|
+
<p style="color: var(--text-secondary); margin-bottom: 20px; font-size: 14px;">
|
|
423
|
+
Set your long-term reading targets for tracking progress and projections.
|
|
424
|
+
</p>
|
|
425
|
+
|
|
426
|
+
<div style="margin-bottom: 15px;">
|
|
427
|
+
<label for="readingHoursTarget"
|
|
428
|
+
style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
429
|
+
Reading Hours Target
|
|
430
|
+
</label>
|
|
431
|
+
<input type="number" id="readingHoursTarget" name="reading_hours_target" min="1"
|
|
432
|
+
max="10000"
|
|
433
|
+
style="padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
|
|
434
|
+
placeholder="1500">
|
|
435
|
+
<small
|
|
436
|
+
style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
437
|
+
Total reading hours goal (1-10,000 hours) - Default: 1500 hours based on TMW N1
|
|
438
|
+
achievement
|
|
439
|
+
</small>
|
|
440
|
+
</div>
|
|
441
|
+
|
|
442
|
+
<div style="margin-bottom: 15px;">
|
|
443
|
+
<label for="characterCountTarget"
|
|
444
|
+
style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
445
|
+
Character Count Target
|
|
446
|
+
</label>
|
|
447
|
+
<input type="number" id="characterCountTarget" name="character_count_target" min="1000"
|
|
448
|
+
max="1000000000"
|
|
449
|
+
style="padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
|
|
450
|
+
placeholder="25000000">
|
|
451
|
+
<small
|
|
452
|
+
style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
453
|
+
Total characters read goal (1,000-1,000,000,000) - Default: 25 million characters
|
|
454
|
+
</small>
|
|
455
|
+
</div>
|
|
456
|
+
|
|
457
|
+
<div style="margin-bottom: 15px;">
|
|
458
|
+
<label for="gamesTarget"
|
|
459
|
+
style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
460
|
+
Games/Visual Novels Target
|
|
461
|
+
</label>
|
|
462
|
+
<input type="number" id="gamesTarget" name="games_target" min="1" max="1000"
|
|
463
|
+
style="width: 90%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
|
|
464
|
+
placeholder="100">
|
|
465
|
+
<small
|
|
466
|
+
style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
467
|
+
Number of games/visual novels to complete (1-1,000) - Default: 100 based on Refold
|
|
468
|
+
standards
|
|
469
|
+
</small>
|
|
470
|
+
</div>
|
|
471
|
+
</div>
|
|
472
|
+
|
|
473
|
+
<!-- Import ExStatic Lines Section -->
|
|
474
|
+
<div style="margin-bottom: 20px; padding-top: 20px; border-top: 1px solid var(--border-color);">
|
|
475
|
+
<label
|
|
476
|
+
style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
|
|
477
|
+
Import ExStatic Lines
|
|
478
|
+
</label>
|
|
479
|
+
<div style="margin-bottom: 10px;">
|
|
480
|
+
<input type="file" id="exstaticFile" accept=".csv"
|
|
481
|
+
style="width: 90%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;">
|
|
482
|
+
<small
|
|
483
|
+
style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
|
|
484
|
+
Select an ExStatic CSV file to import reading data into GSM
|
|
485
|
+
</small>
|
|
486
|
+
</div>
|
|
487
|
+
<button type="button" id="importExstaticBtn"
|
|
488
|
+
style="width: 90%; padding: 10px; background: #666; color: white; border: none; border-radius: 5px; font-size: 14px; cursor: not-allowed; margin-bottom: 10px;"
|
|
489
|
+
disabled>
|
|
490
|
+
Import ExStatic Lines
|
|
491
|
+
</button>
|
|
492
|
+
<div id="importProgress" style="display: none; margin-bottom: 10px;">
|
|
493
|
+
<div
|
|
494
|
+
style="background: var(--bg-tertiary); border-radius: 5px; overflow: hidden; height: 20px; position: relative;">
|
|
495
|
+
<div id="importProgressBar"
|
|
496
|
+
style="background: var(--primary-color); height: 100%; width: 0%; transition: width 0.3s ease;">
|
|
497
|
+
</div>
|
|
498
|
+
<span id="importProgressText"
|
|
499
|
+
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 12px; color: var(--text-primary);">0%</span>
|
|
500
|
+
</div>
|
|
496
501
|
</div>
|
|
502
|
+
<div id="importStatus"
|
|
503
|
+
style="display: none; padding: 10px; border-radius: 5px; font-size: 14px;"></div>
|
|
497
504
|
</div>
|
|
498
|
-
|
|
505
|
+
</form>
|
|
506
|
+
|
|
507
|
+
<div id="settingsError"
|
|
508
|
+
style="display: none; background: var(--danger-color); color: white; padding: 10px; border-radius: 5px; margin-bottom: 15px; font-size: 14px;">
|
|
499
509
|
</div>
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
510
|
+
<div id="settingsSuccess"
|
|
511
|
+
style="display: none; background: var(--success-color); color: white; padding: 10px; border-radius: 5px; margin-bottom: 15px; font-size: 14px;">
|
|
512
|
+
</div>
|
|
513
|
+
</div>
|
|
514
|
+
<div class="modal-footer">
|
|
515
|
+
<button id="cancelSettingsBtn" class="cancel-btn">Cancel</button>
|
|
516
|
+
<button id="saveSettingsBtn" class="confirm-delete-btn">Save Settings</button>
|
|
517
|
+
</div>
|
|
508
518
|
</div>
|
|
509
519
|
</div>
|
|
510
520
|
</div>
|
|
511
|
-
</div>
|
|
512
521
|
|
|
513
522
|
|
|
514
|
-
<!-- Include shared JavaScript first (required dependency for stats.js) -->
|
|
515
|
-
<script src="/static/js/shared.js"></script>
|
|
516
|
-
<script src="/static/js/kanji-grid.js"></script>
|
|
517
|
-
<script src="/static/js/stats.js"></script>
|
|
523
|
+
<!-- Include shared JavaScript first (required dependency for stats.js) -->
|
|
524
|
+
<script src="/static/js/shared.js"></script>
|
|
525
|
+
<script src="/static/js/kanji-grid.js"></script>
|
|
526
|
+
<script src="/static/js/stats.js"></script>
|
|
527
|
+
<!-- <script>
|
|
528
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
529
|
+
const timezoneSelect = document.getElementById('timezone-select');
|
|
530
|
+
const setLocalTimezoneBtn = document.getElementById('set-local-timezone-btn');
|
|
531
|
+
|
|
532
|
+
function populateTimezoneSelect() {
|
|
533
|
+
const timezones = Intl.supportedValuesOf('timeZone');
|
|
534
|
+
const fragment = document.createDocumentFragment();
|
|
535
|
+
|
|
536
|
+
timezones.forEach(tz => {
|
|
537
|
+
const option = document.createElement('option');
|
|
538
|
+
option.value = tz;
|
|
539
|
+
option.textContent = tz.replace(/_/g, ' '); // Improve readability
|
|
540
|
+
fragment.appendChild(option);
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
timezoneSelect.appendChild(fragment);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
function setLocalTimezone() {
|
|
547
|
+
const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
548
|
+
timezoneSelect.value = localTimezone;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
populateTimezoneSelect();
|
|
552
|
+
setLocalTimezone();
|
|
553
|
+
|
|
554
|
+
setLocalTimezoneBtn.addEventListener('click', () => {
|
|
555
|
+
setLocalTimezone();
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
</script> -->
|
|
518
559
|
|
|
519
560
|
</body>
|
|
561
|
+
|
|
520
562
|
</html>
|