GameSentenceMiner 2.7.17__py3-none-any.whl → 2.8.0__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/anki.py +7 -8
- GameSentenceMiner/config_gui.py +19 -3
- GameSentenceMiner/configuration.py +8 -1
- GameSentenceMiner/ffmpeg.py +1 -3
- GameSentenceMiner/gametext.py +16 -155
- GameSentenceMiner/gsm.py +28 -29
- GameSentenceMiner/obs.py +0 -3
- GameSentenceMiner/ocr/ocrconfig.py +0 -1
- GameSentenceMiner/ocr/oneocr_dl.py +243 -0
- GameSentenceMiner/ocr/owocr_area_selector.py +0 -1
- GameSentenceMiner/ocr/owocr_helper.py +25 -26
- GameSentenceMiner/text_log.py +186 -0
- GameSentenceMiner/util.py +52 -3
- GameSentenceMiner/web/__init__.py +0 -0
- GameSentenceMiner/web/static/__init__.py +0 -0
- GameSentenceMiner/web/static/apple-touch-icon.png +0 -0
- GameSentenceMiner/web/static/favicon-96x96.png +0 -0
- GameSentenceMiner/web/static/favicon.ico +0 -0
- GameSentenceMiner/web/static/favicon.svg +3 -0
- GameSentenceMiner/web/static/site.webmanifest +21 -0
- GameSentenceMiner/web/static/style.css +292 -0
- GameSentenceMiner/web/static/text_replacements.html +238 -0
- GameSentenceMiner/web/static/utility.html +313 -0
- GameSentenceMiner/web/static/web-app-manifest-192x192.png +0 -0
- GameSentenceMiner/web/static/web-app-manifest-512x512.png +0 -0
- GameSentenceMiner/web/texthooking_page.py +234 -0
- {gamesentenceminer-2.7.17.dist-info → gamesentenceminer-2.8.0.dist-info}/METADATA +2 -1
- gamesentenceminer-2.8.0.dist-info/RECORD +58 -0
- {gamesentenceminer-2.7.17.dist-info → gamesentenceminer-2.8.0.dist-info}/WHEEL +1 -1
- GameSentenceMiner/utility_gui.py +0 -204
- gamesentenceminer-2.7.17.dist-info/RECORD +0 -44
- {gamesentenceminer-2.7.17.dist-info → gamesentenceminer-2.8.0.dist-info}/entry_points.txt +0 -0
- {gamesentenceminer-2.7.17.dist-info → gamesentenceminer-2.8.0.dist-info}/licenses/LICENSE +0 -0
- {gamesentenceminer-2.7.17.dist-info → gamesentenceminer-2.8.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,3 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="67" height="64" viewBox="0 0 67 64"><image width="67" height="64" xlink:href="data:image/png;base64,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"></image><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
|
2
|
+
@media (prefers-color-scheme: dark) { :root { filter: none; } }
|
3
|
+
</style></svg>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"name": "MyWebSite",
|
3
|
+
"short_name": "MySite",
|
4
|
+
"icons": [
|
5
|
+
{
|
6
|
+
"src": "/web-app-manifest-192x192.png",
|
7
|
+
"sizes": "192x192",
|
8
|
+
"type": "image/png",
|
9
|
+
"purpose": "maskable"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"src": "/web-app-manifest-512x512.png",
|
13
|
+
"sizes": "512x512",
|
14
|
+
"type": "image/png",
|
15
|
+
"purpose": "maskable"
|
16
|
+
}
|
17
|
+
],
|
18
|
+
"theme_color": "#ffffff",
|
19
|
+
"background_color": "#ffffff",
|
20
|
+
"display": "standalone"
|
21
|
+
}
|
@@ -0,0 +1,292 @@
|
|
1
|
+
body {
|
2
|
+
background-color: #121212;
|
3
|
+
color: #e0e0e0;
|
4
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
5
|
+
margin: 20px; /* Keep existing margin */
|
6
|
+
}
|
7
|
+
|
8
|
+
h1 {
|
9
|
+
color: #ffffff;
|
10
|
+
text-align: center;
|
11
|
+
font-weight: 300;
|
12
|
+
margin-bottom: 24px; /* Added margin to match previous layout */
|
13
|
+
}
|
14
|
+
|
15
|
+
/* Styles for the main container */
|
16
|
+
.container {
|
17
|
+
max-width: 64rem; /* Equivalent to max-w-4xl */
|
18
|
+
margin-left: auto;
|
19
|
+
margin-right: auto;
|
20
|
+
background-color: #1e1e1e; /* Darker background for the container */
|
21
|
+
padding: 32px; /* Equivalent to p-8 */
|
22
|
+
border-radius: 8px; /* rounded-lg */
|
23
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* shadow-md */
|
24
|
+
}
|
25
|
+
|
26
|
+
|
27
|
+
.inputField {
|
28
|
+
background-color: #1e1e1e;
|
29
|
+
color: #e0e0e0;
|
30
|
+
border: 1px solid #333;
|
31
|
+
padding: 10px;
|
32
|
+
font-size: 16px;
|
33
|
+
/* margin-bottom: 15px; Removed as it's part of flex/gap now */
|
34
|
+
border-radius: 5px;
|
35
|
+
flex-grow: 1; /* Added to make it fill space in flex container */
|
36
|
+
}
|
37
|
+
/* Placeholder color for the search input */
|
38
|
+
.inputField::placeholder {
|
39
|
+
color: #a0a0a0; /* Slightly lighter placeholder */
|
40
|
+
}
|
41
|
+
.inputField:focus {
|
42
|
+
border-color: #1a73e8; /* Highlight color on focus */
|
43
|
+
outline: none;
|
44
|
+
}
|
45
|
+
|
46
|
+
|
47
|
+
.control {
|
48
|
+
margin-bottom: 24px; /* Adjusted margin to match previous layout */
|
49
|
+
display: flex;
|
50
|
+
flex-direction: column; /* Default to column for small screens */
|
51
|
+
gap: 16px; /* Space between items */
|
52
|
+
}
|
53
|
+
|
54
|
+
@media (min-width: 640px) { /* sm breakpoint equivalent */
|
55
|
+
.control {
|
56
|
+
flex-direction: row; /* Row layout for larger screens */
|
57
|
+
gap: 16px; /* Space between items */
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
button {
|
63
|
+
background-color: #1a73e8;
|
64
|
+
color: #ffffff;
|
65
|
+
border: none;
|
66
|
+
padding: 10px 20px;
|
67
|
+
font-size: 16px;
|
68
|
+
cursor: pointer;
|
69
|
+
transition: background-color 0.3s;
|
70
|
+
border-radius: 5px;
|
71
|
+
}
|
72
|
+
|
73
|
+
button:disabled {
|
74
|
+
background-color: #444;
|
75
|
+
cursor: not-allowed;
|
76
|
+
}
|
77
|
+
|
78
|
+
button:hover:not(:disabled) {
|
79
|
+
background-color: #1669c1;
|
80
|
+
}
|
81
|
+
|
82
|
+
/* Specific button styles based on previous Tailwind colors */
|
83
|
+
.button-blue {
|
84
|
+
background-color: #1a73e8; /* Match existing button style */
|
85
|
+
}
|
86
|
+
.button-blue:hover:not(:disabled) {
|
87
|
+
background-color: #1669c1; /* Match existing button hover */
|
88
|
+
}
|
89
|
+
|
90
|
+
.button-green {
|
91
|
+
background-color: #34a853; /* Google Green */
|
92
|
+
}
|
93
|
+
.button-green:hover:not(:disabled) {
|
94
|
+
background-color: #2e8b4a;
|
95
|
+
}
|
96
|
+
|
97
|
+
.button-gray {
|
98
|
+
background-color: #5f6368; /* Google Gray */
|
99
|
+
}
|
100
|
+
.button-gray:hover:not(:disabled) {
|
101
|
+
background-color: #54575c;
|
102
|
+
}
|
103
|
+
|
104
|
+
|
105
|
+
select {
|
106
|
+
background-color: #1e1e1e;
|
107
|
+
color: #e0e0e0;
|
108
|
+
border: 1px solid #333;
|
109
|
+
padding: 10px;
|
110
|
+
width: 220px;
|
111
|
+
font-size: 16px;
|
112
|
+
margin-left: 5px;
|
113
|
+
margin-right: 5px;
|
114
|
+
border-radius: 5px;
|
115
|
+
}
|
116
|
+
|
117
|
+
/* Removed generic div margin to avoid conflicts */
|
118
|
+
/* div {
|
119
|
+
margin-bottom: 15px;
|
120
|
+
} */
|
121
|
+
|
122
|
+
/* Table Styles */
|
123
|
+
.table-container {
|
124
|
+
overflow-x: auto;
|
125
|
+
border-radius: 8px;
|
126
|
+
border: 1px solid #333;
|
127
|
+
}
|
128
|
+
|
129
|
+
.data-table {
|
130
|
+
width: 100%; /* Use width instead of min-width */
|
131
|
+
border-collapse: collapse;
|
132
|
+
}
|
133
|
+
|
134
|
+
.data-table thead {
|
135
|
+
background-color: #333;
|
136
|
+
}
|
137
|
+
|
138
|
+
.data-table th {
|
139
|
+
padding: 12px 24px;
|
140
|
+
text-align: left;
|
141
|
+
font-size: 0.75rem;
|
142
|
+
font-weight: 500;
|
143
|
+
color: #b0b0b0; /* Lighter gray for header text */
|
144
|
+
text-transform: uppercase;
|
145
|
+
letter-spacing: 0.05em;
|
146
|
+
}
|
147
|
+
.data-table th:last-child {
|
148
|
+
text-align: right;
|
149
|
+
}
|
150
|
+
|
151
|
+
.data-table tbody tr {
|
152
|
+
background-color: #1e1e1e; /* Match input field background */
|
153
|
+
border-bottom: 1px solid #333; /* Border between rows */
|
154
|
+
}
|
155
|
+
|
156
|
+
.data-table tbody tr:last-child {
|
157
|
+
border-bottom: none; /* No border on the last row */
|
158
|
+
}
|
159
|
+
|
160
|
+
|
161
|
+
.data-table td {
|
162
|
+
padding: 16px 24px;
|
163
|
+
white-space: nowrap;
|
164
|
+
font-size: 0.875rem;
|
165
|
+
color: #e0e0e0; /* Default text color for cells */
|
166
|
+
}
|
167
|
+
|
168
|
+
.data-table td:nth-child(1) {
|
169
|
+
font-weight: 500;
|
170
|
+
color: #ffffff; /* White color for the key */
|
171
|
+
}
|
172
|
+
|
173
|
+
.data-table td:last-child {
|
174
|
+
text-align: right;
|
175
|
+
font-weight: 500;
|
176
|
+
display: flex;
|
177
|
+
justify-content: flex-end;
|
178
|
+
gap: 8px;
|
179
|
+
}
|
180
|
+
|
181
|
+
/* Action buttons in the table */
|
182
|
+
/* Styles for Edit Button */
|
183
|
+
.action-button.edit-btn {
|
184
|
+
color: #a0c3ff; /* Lighter blue for edit */
|
185
|
+
cursor: pointer;
|
186
|
+
background: none; /* Ensure no background */
|
187
|
+
border: none; /* Ensure no border */
|
188
|
+
padding: 0; /* Remove padding */
|
189
|
+
font-size: 0.875rem;
|
190
|
+
text-decoration: underline; /* Add underline for link-like appearance */
|
191
|
+
transition: color 0.3s ease; /* Smooth transition for color */
|
192
|
+
}
|
193
|
+
.action-button.edit-btn:hover {
|
194
|
+
color: #7ba7ff; /* Darker blue on hover */
|
195
|
+
text-decoration: none; /* Remove underline on hover */
|
196
|
+
}
|
197
|
+
|
198
|
+
/* Styles for Delete Button */
|
199
|
+
.action-button.delete-btn {
|
200
|
+
color: #ff6b6b; /* Red for delete */
|
201
|
+
cursor: pointer;
|
202
|
+
background: none; /* Ensure no background */
|
203
|
+
border: none; /* Ensure no border */
|
204
|
+
padding: 0; /* Remove padding */
|
205
|
+
font-size: 0.875rem;
|
206
|
+
text-decoration: underline; /* Add underline for link-like appearance */
|
207
|
+
transition: color 0.3s ease; /* Smooth transition for color */
|
208
|
+
}
|
209
|
+
.action-button.delete-btn:hover {
|
210
|
+
color: #ff4c4c; /* Darker red on hover */
|
211
|
+
text-decoration: none; /* Remove underline on hover */
|
212
|
+
}
|
213
|
+
|
214
|
+
|
215
|
+
.no-entries-message {
|
216
|
+
color: #b0b0b0; /* Match header text color */
|
217
|
+
padding: 16px;
|
218
|
+
text-align: center;
|
219
|
+
}
|
220
|
+
|
221
|
+
/* Modal styles */
|
222
|
+
.modal {
|
223
|
+
display: none; /* Hidden by default */
|
224
|
+
position: fixed; /* Stay in place */
|
225
|
+
z-index: 1000; /* Sit on top */
|
226
|
+
left: 0;
|
227
|
+
top: 0;
|
228
|
+
width: 100%; /* Full width */
|
229
|
+
height: 100%; /* Full height */
|
230
|
+
overflow: auto; /* Enable scroll if needed */
|
231
|
+
background-color: rgba(0,0,0,0.6); /* Darker overlay */
|
232
|
+
align-items: center;
|
233
|
+
justify-content: center;
|
234
|
+
}
|
235
|
+
.modal-content {
|
236
|
+
background-color: #1e1e1e; /* Match input field background */
|
237
|
+
margin: auto;
|
238
|
+
padding: 20px;
|
239
|
+
border-radius: 8px;
|
240
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); /* Darker shadow */
|
241
|
+
width: 90%;
|
242
|
+
max-width: 500px;
|
243
|
+
color: #e0e0e0;
|
244
|
+
}
|
245
|
+
.close-button {
|
246
|
+
color: #b0b0b0; /* Match header text color */
|
247
|
+
float: right;
|
248
|
+
font-size: 28px;
|
249
|
+
font-weight: bold;
|
250
|
+
}
|
251
|
+
.close-button:hover,
|
252
|
+
.close-button:focus {
|
253
|
+
color: #ffffff; /* White on hover */
|
254
|
+
text-decoration: none;
|
255
|
+
cursor: pointer;
|
256
|
+
}
|
257
|
+
|
258
|
+
.form-group {
|
259
|
+
margin-bottom: 15px; /* Consistent margin */
|
260
|
+
}
|
261
|
+
|
262
|
+
.form-label {
|
263
|
+
display: block;
|
264
|
+
font-size: 0.875rem;
|
265
|
+
font-weight: 500;
|
266
|
+
color: #b0b0b0; /* Match header text color */
|
267
|
+
margin-bottom: 5px; /* Spacing below label */
|
268
|
+
}
|
269
|
+
|
270
|
+
.form-input {
|
271
|
+
display: block;
|
272
|
+
width: 95%;
|
273
|
+
padding: 10px 12px; /* Slightly more padding */
|
274
|
+
border: 1px solid #333;
|
275
|
+
border-radius: 5px; /* Match other inputs */
|
276
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
277
|
+
outline: none;
|
278
|
+
background-color: #121212; /* Darker background for input */
|
279
|
+
color: #e0e0e0;
|
280
|
+
}
|
281
|
+
.form-input::placeholder {
|
282
|
+
color: #a0a0a0;
|
283
|
+
}
|
284
|
+
.form-input:focus {
|
285
|
+
border-color: #1a73e8;
|
286
|
+
box-shadow: 0 0 0 1px #1a73e8;
|
287
|
+
}
|
288
|
+
|
289
|
+
.flex-end {
|
290
|
+
display: flex;
|
291
|
+
justify-content: flex-end;
|
292
|
+
}
|
@@ -0,0 +1,238 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>Text Error Fixes (Electron)</title>
|
7
|
+
<link rel="stylesheet" href="/static/style.css">
|
8
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
|
9
|
+
</head>
|
10
|
+
<body> <div class="container">
|
11
|
+
<h1>Text Error Fixes</h1>
|
12
|
+
|
13
|
+
<div class="control"> <button id="add-new-btn" class="button-blue">Add New Entry</button> <div class="search-container"> <input type="text" id="search-input" placeholder="Search key or value..." class="inputField"> <button id="search-button" class="button-green">Search</button> </div>
|
14
|
+
<button id="go-back-btn" class="button-gray">Go Back</button>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div id="data-table-container" class="table-container"> <table id="data-table" class="data-table"> <thead>
|
18
|
+
<tr>
|
19
|
+
<th>
|
20
|
+
Text To Replace (Key)
|
21
|
+
</th>
|
22
|
+
<th>
|
23
|
+
Replacement Text (Value)
|
24
|
+
</th>
|
25
|
+
<th>
|
26
|
+
Actions
|
27
|
+
</th>
|
28
|
+
</tr>
|
29
|
+
</thead>
|
30
|
+
<tbody id="data-table-body">
|
31
|
+
</tbody>
|
32
|
+
</table>
|
33
|
+
<p id="no-entries-message" class="no-entries-message hidden">No entries found.</p> </div>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<div id="entry-modal" class="modal"> <div class="modal-content"> <span class="close-button">×</span> <h2 id="modal-title">Add New Entry</h2> <form id="entry-form">
|
37
|
+
<p>"re:" at the beginning = regex pattern (ex. re:.{3,}) </p>
|
38
|
+
<div class="form-group"> <label for="key-input" class="form-label">Text To Replace (Key):</label> <input type="text" id="key-input" name="key" required class="form-input"> <input type="hidden" id="original-key-input">
|
39
|
+
</div>
|
40
|
+
<div class="form-group"> <label for="value-input" class="form-label">Replacement Text (Value):</label> <input type="text" id="value-input" name="value" class="form-input">
|
41
|
+
</div>
|
42
|
+
<div class="flex-end"> <button type="submit" class="button-blue">Save Entry</button> </div>
|
43
|
+
</form>
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<script>
|
48
|
+
|
49
|
+
let textData = {};
|
50
|
+
let data = {};
|
51
|
+
|
52
|
+
async function loadData() {
|
53
|
+
try {
|
54
|
+
const response = await fetch('/load-data');
|
55
|
+
if (response.ok) {
|
56
|
+
data = await response.json();
|
57
|
+
textData = data.args?.replacements || {};
|
58
|
+
} else {
|
59
|
+
console.error('Failed to load data from server');
|
60
|
+
}
|
61
|
+
} catch (error) {
|
62
|
+
console.error('Error loading data:', error);
|
63
|
+
}
|
64
|
+
renderTable();
|
65
|
+
}
|
66
|
+
|
67
|
+
async function saveData() {
|
68
|
+
try {
|
69
|
+
console.log(data)
|
70
|
+
data.args.replacements = textData;
|
71
|
+
console.log(data)
|
72
|
+
const response = await fetch('/save-data', {
|
73
|
+
method: 'POST',
|
74
|
+
headers: { 'Content-Type': 'application/json' },
|
75
|
+
body: JSON.stringify(data),
|
76
|
+
});
|
77
|
+
if (!response.ok) {
|
78
|
+
console.error('Failed to save data to server');
|
79
|
+
}
|
80
|
+
} catch (error) {
|
81
|
+
console.error('Error saving data:', error);
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
function renderTable(dataToRender = textData) {
|
86
|
+
const tableBody = document.getElementById('data-table-body');
|
87
|
+
let tableHtml = '';
|
88
|
+
const noEntriesMessage = document.getElementById('no-entries-message');
|
89
|
+
const dataTable = document.getElementById('data-table');
|
90
|
+
const keys = Object.keys(dataToRender);
|
91
|
+
|
92
|
+
if (keys.length === 0) {
|
93
|
+
noEntriesMessage.classList.remove('hidden');
|
94
|
+
dataTable.classList.add('hidden');
|
95
|
+
} else {
|
96
|
+
noEntriesMessage.classList.add('hidden');
|
97
|
+
dataTable.classList.remove('hidden');
|
98
|
+
keys.forEach(key => {
|
99
|
+
const value = dataToRender[key];
|
100
|
+
tableHtml += `
|
101
|
+
<tr>
|
102
|
+
<td>${escapeHTML(key)}</td> <td>${escapeHTML(value)}</td> <td>
|
103
|
+
<button class="action-button edit-btn" data-key="${escapeHTML(key)}">Edit</button>
|
104
|
+
<button class="action-button delete-button delete-btn" data-key="${escapeHTML(key)}">Delete</button>
|
105
|
+
</td>
|
106
|
+
</tr>
|
107
|
+
`;
|
108
|
+
});
|
109
|
+
tableBody.innerHTML = tableHtml;
|
110
|
+
document.querySelectorAll('.edit-btn').forEach(button => {
|
111
|
+
button.addEventListener('click', handleEditClick);
|
112
|
+
});
|
113
|
+
document.querySelectorAll('.delete-btn').forEach(button => {
|
114
|
+
button.addEventListener('click', handleDeleteClick);
|
115
|
+
});
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
function escapeHTML(str) {
|
120
|
+
const div = document.createElement('div');
|
121
|
+
div.appendChild(document.createTextNode(str));
|
122
|
+
return div.innerHTML;
|
123
|
+
}
|
124
|
+
|
125
|
+
const modal = document.getElementById('entry-modal');
|
126
|
+
const modalTitle = document.getElementById('modal-title');
|
127
|
+
const entryForm = document.getElementById('entry-form');
|
128
|
+
const keyInput = document.getElementById('key-input');
|
129
|
+
const valueInput = document.getElementById('value-input');
|
130
|
+
const originalKeyInput = document.getElementById('original-key-input');
|
131
|
+
const closeButton = document.querySelector('.close-button');
|
132
|
+
const addNewBtn = document.getElementById('add-new-btn');
|
133
|
+
|
134
|
+
addNewBtn.addEventListener('click', () => {
|
135
|
+
modalTitle.textContent = 'Add New Entry';
|
136
|
+
keyInput.value = '';
|
137
|
+
valueInput.value = '';
|
138
|
+
originalKeyInput.value = '';
|
139
|
+
keyInput.disabled = false;
|
140
|
+
modal.style.display = 'flex';
|
141
|
+
});
|
142
|
+
|
143
|
+
function handleEditClick(event) {
|
144
|
+
const keyToEdit = event.target.dataset.key;
|
145
|
+
const valueToEdit = textData[keyToEdit];
|
146
|
+
modalTitle.textContent = 'Edit Entry';
|
147
|
+
keyInput.value = keyToEdit;
|
148
|
+
valueInput.value = valueToEdit;
|
149
|
+
originalKeyInput.value = keyToEdit;
|
150
|
+
modal.style.display = 'flex';
|
151
|
+
}
|
152
|
+
|
153
|
+
closeButton.addEventListener('click', () => {
|
154
|
+
modal.style.display = 'none';
|
155
|
+
});
|
156
|
+
|
157
|
+
window.addEventListener('mousedown', (event) => {
|
158
|
+
if (event.target === modal) {
|
159
|
+
modal.style.display = 'none';
|
160
|
+
}
|
161
|
+
});
|
162
|
+
|
163
|
+
entryForm.addEventListener('submit', async (event) => {
|
164
|
+
event.preventDefault();
|
165
|
+
const key = keyInput.value.trim();
|
166
|
+
const value = valueInput.value.trim() || "";
|
167
|
+
const originalKey = originalKeyInput.value;
|
168
|
+
let keyEdited = false;
|
169
|
+
|
170
|
+
if (!key) {
|
171
|
+
alert('Key cannot be empty.');
|
172
|
+
return;
|
173
|
+
}
|
174
|
+
|
175
|
+
if (originalKey && originalKey !== key) {
|
176
|
+
delete textData[originalKey];
|
177
|
+
keyEdited = true;
|
178
|
+
}
|
179
|
+
|
180
|
+
if (originalKey) {
|
181
|
+
textData = { ...textData, [key]: value };
|
182
|
+
if (keyEdited) {
|
183
|
+
// No need to re-add, it was just updated
|
184
|
+
}
|
185
|
+
} else {
|
186
|
+
if (textData.hasOwnProperty(key)) {
|
187
|
+
alert(`Key "${key}" already exists. Please use the Edit function to modify it.`);
|
188
|
+
return;
|
189
|
+
}
|
190
|
+
textData = { ...textData, [key]: value };
|
191
|
+
}
|
192
|
+
|
193
|
+
await saveData();
|
194
|
+
await loadData();
|
195
|
+
modal.style.display = 'none';
|
196
|
+
});
|
197
|
+
|
198
|
+
function handleDeleteClick(event) {
|
199
|
+
const keyToDelete = event.target.dataset.key;
|
200
|
+
if (confirm(`Are you sure you want to delete the entry with key "${keyToDelete}"?`)) {
|
201
|
+
if (textData.hasOwnProperty(keyToDelete)) {
|
202
|
+
delete textData[keyToDelete];
|
203
|
+
saveData();
|
204
|
+
renderTable();
|
205
|
+
}
|
206
|
+
}
|
207
|
+
}
|
208
|
+
|
209
|
+
const searchInput = document.getElementById('search-input');
|
210
|
+
const searchButton = document.getElementById('search-button');
|
211
|
+
|
212
|
+
function performSearch() {
|
213
|
+
const query = searchInput.value.toLowerCase();
|
214
|
+
const filteredData = {};
|
215
|
+
for (const key in textData) {
|
216
|
+
if (textData.hasOwnProperty(key)) {
|
217
|
+
const value = textData[key];
|
218
|
+
if (key.toLowerCase().includes(query) || value.toLowerCase().includes(query)) {
|
219
|
+
filteredData[key] = value;
|
220
|
+
}
|
221
|
+
}
|
222
|
+
}
|
223
|
+
renderTable(filteredData);
|
224
|
+
}
|
225
|
+
|
226
|
+
searchButton.addEventListener('click', performSearch);
|
227
|
+
searchInput.addEventListener('input', performSearch);
|
228
|
+
|
229
|
+
const goBackBtn = document.getElementById('go-back-btn');
|
230
|
+
goBackBtn.addEventListener('click', () => {
|
231
|
+
window.history.back();
|
232
|
+
});
|
233
|
+
|
234
|
+
loadData();
|
235
|
+
|
236
|
+
</script>
|
237
|
+
</body>
|
238
|
+
</html>
|