stat2025 commited on
Commit
2962d3c
·
verified ·
1 Parent(s): 8822597

Upload 2 files

Browse files
Files changed (2) hide show
  1. index.html +382 -0
  2. script.js +154 -0
index.html ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="ar" dir="rtl">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>صفحة البحث عن خريطة باحث</title>
7
+ <meta name="description" content="ابحث باسم الباحث أو جزء منه لفتح رابط خريطته مباشرة." />
8
+ <style>
9
+ :root{
10
+ --bg: #0b1220;
11
+ --card: rgba(255,255,255,.08);
12
+ --card2: rgba(255,255,255,.06);
13
+ --text: #e5e7eb;
14
+ --muted: rgba(229,231,235,.70);
15
+ --line: rgba(255,255,255,.12);
16
+ --accent: #60a5fa;
17
+ --accent2:#34d399;
18
+ --shadow: 0 18px 60px rgba(0,0,0,.35);
19
+ --radius: 22px;
20
+ }
21
+
22
+ *{ box-sizing:border-box; }
23
+ html, body{ height:100%; }
24
+ body{
25
+ margin:0;
26
+ font-family: system-ui, -apple-system, "Segoe UI", Tahoma, Arial, sans-serif;
27
+ color:var(--text);
28
+ background:
29
+ radial-gradient(1200px 700px at 15% 10%, rgba(96,165,250,.35), rgba(96,165,250,0) 55%),
30
+ radial-gradient(900px 600px at 85% 20%, rgba(52,211,153,.25), rgba(52,211,153,0) 55%),
31
+ radial-gradient(900px 700px at 50% 105%, rgba(147,197,253,.18), rgba(147,197,253,0) 50%),
32
+ linear-gradient(180deg, #0b1220 0%, #070b14 100%);
33
+ display:flex;
34
+ flex-direction:column;
35
+ overflow-x:hidden;
36
+ }
37
+
38
+ .wrap{
39
+ width:min(980px, 92vw);
40
+ margin: 0 auto;
41
+ padding: 34px 0 92px;
42
+ flex:1;
43
+ }
44
+
45
+ /* Top bar */
46
+ .top{
47
+ display:flex;
48
+ align-items:center;
49
+ justify-content:space-between;
50
+ gap:12px;
51
+ padding: 10px 6px 22px;
52
+ }
53
+ .brand{
54
+ display:flex;
55
+ align-items:center;
56
+ gap:10px;
57
+ min-width: 220px;
58
+ }
59
+ .logo{
60
+ width:42px;height:42px;border-radius:14px;
61
+ background:
62
+ radial-gradient(18px 18px at 30% 30%, rgba(255,255,255,.85), rgba(255,255,255,0) 60%),
63
+ linear-gradient(135deg, rgba(96,165,250,.95), rgba(52,211,153,.85));
64
+ box-shadow: 0 12px 24px rgba(0,0,0,.35);
65
+ }
66
+ .brand h1{
67
+ margin:0;
68
+ font-size: 16px;
69
+ letter-spacing:.2px;
70
+ line-height:1.2;
71
+ }
72
+ .brand p{
73
+ margin:2px 0 0;
74
+ color:var(--muted);
75
+ font-size: 12.5px;
76
+ }
77
+
78
+ .pill{
79
+ display:flex;
80
+ align-items:center;
81
+ gap:8px;
82
+ padding:10px 12px;
83
+ border:1px solid var(--line);
84
+ border-radius:999px;
85
+ background: rgba(255,255,255,.05);
86
+ color:var(--muted);
87
+ font-size:12.5px;
88
+ backdrop-filter: blur(10px);
89
+ white-space:nowrap;
90
+ }
91
+
92
+ /* Hero */
93
+ .hero{
94
+ position:relative;
95
+ border:1px solid var(--line);
96
+ border-radius: var(--radius);
97
+ background: linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,.04));
98
+ box-shadow: var(--shadow);
99
+ overflow:hidden;
100
+ }
101
+ .hero::before{
102
+ content:"";
103
+ position:absolute; inset:-2px;
104
+ background:
105
+ radial-gradient(380px 220px at 20% 10%, rgba(96,165,250,.25), rgba(96,165,250,0) 60%),
106
+ radial-gradient(420px 240px at 80% 20%, rgba(52,211,153,.18), rgba(52,211,153,0) 60%);
107
+ pointer-events:none;
108
+ }
109
+ .heroInner{
110
+ position:relative;
111
+ padding: 24px;
112
+ }
113
+ .title{
114
+ margin:0;
115
+ font-size: clamp(22px, 2.2vw, 34px);
116
+ line-height:1.2;
117
+ letter-spacing:.2px;
118
+ }
119
+ .subtitle{
120
+ margin:10px 0 0;
121
+ color:var(--muted);
122
+ font-size: 14.5px;
123
+ line-height: 1.9;
124
+ max-width: 70ch;
125
+ }
126
+
127
+ /* Search */
128
+ .searchCard{
129
+ margin-top: 16px;
130
+ border:1px solid var(--line);
131
+ border-radius: var(--radius);
132
+ background: rgba(255,255,255,.05);
133
+ padding: 14px;
134
+ backdrop-filter: blur(10px);
135
+ }
136
+ .searchRow{
137
+ display:grid;
138
+ grid-template-columns: 1fr auto auto;
139
+ gap:10px;
140
+ align-items:stretch;
141
+ }
142
+ @media (max-width: 620px){
143
+ .searchRow{ grid-template-columns: 1fr; }
144
+ .pill{ display:none; }
145
+ }
146
+
147
+ .inputWrap{
148
+ position:relative;
149
+ min-width: 260px;
150
+ }
151
+ input[type="text"]{
152
+ width:100%;
153
+ padding: 14px 44px 14px 44px;
154
+ border-radius: 16px;
155
+ border:1px solid rgba(255,255,255,.16);
156
+ background: rgba(2,6,23,.35);
157
+ color: var(--text);
158
+ outline:none;
159
+ font-size: 16px;
160
+ transition: box-shadow .2s ease, border-color .2s ease, transform .06s ease;
161
+ }
162
+ input[type="text"]::placeholder{ color: rgba(229,231,235,.55); }
163
+ input[type="text"]:focus{
164
+ border-color: rgba(96,165,250,.65);
165
+ box-shadow: 0 0 0 5px rgba(96,165,250,.15);
166
+ }
167
+
168
+ .icon{
169
+ position:absolute;
170
+ right:14px;
171
+ top:50%;
172
+ transform: translateY(-50%);
173
+ opacity:.85;
174
+ font-size: 18px;
175
+ }
176
+
177
+ .kbd{
178
+ position:absolute;
179
+ left: 12px;
180
+ top:50%;
181
+ transform: translateY(-50%);
182
+ border: 1px solid rgba(255,255,255,.14);
183
+ background: rgba(255,255,255,.06);
184
+ color: rgba(229,231,235,.8);
185
+ padding: 4px 8px;
186
+ border-radius: 10px;
187
+ font-size: 11px;
188
+ letter-spacing: .3px;
189
+ user-select:none;
190
+ }
191
+
192
+ button{
193
+ border:1px solid rgba(255,255,255,.14);
194
+ background: rgba(255,255,255,.06);
195
+ color: var(--text);
196
+ padding: 12px 16px;
197
+ border-radius: 16px;
198
+ font-size: 15px;
199
+ cursor:pointer;
200
+ transition: transform .06s ease, opacity .2s ease, background .2s ease, border-color .2s ease;
201
+ min-width: 120px;
202
+ display:flex;
203
+ align-items:center;
204
+ justify-content:center;
205
+ gap:8px;
206
+ white-space:nowrap;
207
+ }
208
+ button.primary{
209
+ border-color: rgba(96,165,250,.55);
210
+ background: linear-gradient(135deg, rgba(96,165,250,.95), rgba(52,211,153,.65));
211
+ color:#081226;
212
+ font-weight: 700;
213
+ }
214
+ button:hover{ opacity:.92; }
215
+ button:active{ transform: translateY(1px); }
216
+
217
+ .meta{
218
+ display:flex;
219
+ align-items:center;
220
+ justify-content:space-between;
221
+ gap:10px;
222
+ flex-wrap:wrap;
223
+ padding: 12px 2px 0;
224
+ color: var(--muted);
225
+ font-size: 12.5px;
226
+ }
227
+ .badge{
228
+ display:inline-flex;
229
+ align-items:center;
230
+ gap:8px;
231
+ padding: 7px 10px;
232
+ border-radius: 999px;
233
+ border:1px solid rgba(255,255,255,.14);
234
+ background: rgba(255,255,255,.05);
235
+ color: rgba(229,231,235,.85);
236
+ }
237
+ .dot{
238
+ width:8px;height:8px;border-radius:50%;
239
+ background: linear-gradient(135deg, var(--accent), var(--accent2));
240
+ box-shadow: 0 0 0 3px rgba(96,165,250,.12);
241
+ }
242
+
243
+ /* Results */
244
+ .results{
245
+ margin-top: 14px;
246
+ display:grid;
247
+ gap: 10px;
248
+ }
249
+ .item{
250
+ display:flex;
251
+ align-items:center;
252
+ justify-content:space-between;
253
+ gap: 12px;
254
+ padding: 14px;
255
+ border-radius: 18px;
256
+ border: 1px solid rgba(255,255,255,.12);
257
+ background: rgba(255,255,255,.045);
258
+ backdrop-filter: blur(10px);
259
+ transition: transform .12s ease, border-color .2s ease, background .2s ease;
260
+ }
261
+ .item:hover{
262
+ transform: translateY(-1px);
263
+ border-color: rgba(96,165,250,.40);
264
+ background: rgba(255,255,255,.06);
265
+ }
266
+ .left{
267
+ display:flex;
268
+ flex-direction:column;
269
+ min-width: 0;
270
+ }
271
+ .name{
272
+ font-weight: 750;
273
+ font-size: 15.5px;
274
+ line-height: 1.7;
275
+ white-space: nowrap;
276
+ overflow:hidden;
277
+ text-overflow: ellipsis;
278
+ max-width: 62ch;
279
+ }
280
+ .hint{
281
+ margin-top: 2px;
282
+ color: var(--muted);
283
+ font-size: 12.5px;
284
+ }
285
+
286
+ a.open{
287
+ text-decoration:none;
288
+ padding: 10px 12px;
289
+ border-radius: 14px;
290
+ border:1px solid rgba(96,165,250,.40);
291
+ background: rgba(96,165,250,.10);
292
+ color: #cfe6ff;
293
+ font-size: 13.5px;
294
+ white-space: nowrap;
295
+ display:inline-flex;
296
+ align-items:center;
297
+ gap:8px;
298
+ transition: opacity .2s ease, transform .06s ease, background .2s ease;
299
+ }
300
+ a.open:hover{ opacity:.95; background: rgba(96,165,250,.14); }
301
+ a.open:active{ transform: translateY(1px); }
302
+
303
+ .empty{
304
+ text-align:center;
305
+ color: var(--muted);
306
+ padding: 18px 12px;
307
+ border-radius: 18px;
308
+ border: 1px dashed rgba(255,255,255,.16);
309
+ background: rgba(255,255,255,.03);
310
+ }
311
+
312
+ mark{
313
+ background: rgba(52,211,153,.18);
314
+ border: 1px solid rgba(52,211,153,.25);
315
+ color: #eafff7;
316
+ padding: 1px 6px;
317
+ border-radius: 999px;
318
+ }
319
+
320
+ /* Footer */
321
+ footer{
322
+ position:fixed;
323
+ bottom:0; left:0; right:0;
324
+ text-align:center;
325
+ padding: 10px 14px;
326
+ color: rgba(229,231,235,.8);
327
+ background: rgba(7,11,20,.72);
328
+ border-top: 1px solid rgba(255,255,255,.10);
329
+ backdrop-filter: blur(12px);
330
+ font-size: 12.5px;
331
+ }
332
+ </style>
333
+ </head>
334
+ <body>
335
+ <div class="wrap">
336
+ <div class="top">
337
+ <div class="brand">
338
+ <div class="logo" aria-hidden="true"></div>
339
+ <div>
340
+ <h1>صفحة البحث عن خريطة باحث</h1>
341
+ <p>بحث سريع ونتائج فورية بروابط مباشرة</p>
342
+ </div>
343
+ </div>
344
+
345
+ <div class="pill" id="totalPill">📌 إجمالي الروابط: —</div>
346
+ </div>
347
+
348
+ <section class="hero" aria-label="hero">
349
+ <div class="heroInner">
350
+ <h2 class="title">ابحث بالاسم وافتح الخريطة مباشرة</h2>
351
+ <p class="subtitle">
352
+ اكتب اسم الباحث أو جزءًا منه (كلمة واحدة تكفي). ستظهر النتائج فورًا، ثم اضغط <b>فتح الخريطة</b>.
353
+ </p>
354
+
355
+ <div class="searchCard" aria-label="search">
356
+ <div class="searchRow">
357
+ <div class="inputWrap">
358
+ <span class="icon" aria-hidden="true">🔎</span>
359
+ <span class="kbd" aria-hidden="true">Enter</span>
360
+ <input id="q" type="text" inputmode="search" autocomplete="off"
361
+ placeholder="مثال: تركي / نوره / المحيفيظ ..." />
362
+ </div>
363
+
364
+ <button id="btnSearch" class="primary" type="button">بحث</button>
365
+ <button id="btnClear" type="button">مسح</button>
366
+ </div>
367
+
368
+ <div class="meta">
369
+ <div class="badge"><span class="dot"></span><span id="countBadge">النتائج: 0</span></div>
370
+ <div>يدعم البحث بجزء من الاسم + تعدد الكلمات.</div>
371
+ </div>
372
+
373
+ <div class="results" id="results" aria-live="polite"></div>
374
+ </div>
375
+ </div>
376
+ </section>
377
+ </div>
378
+
379
+ <footer>تصميم وإعداد الدعم الفني نوف الناصر</footer>
380
+ <script src="./script.js"></script>
381
+ </body>
382
+ </html>
script.js ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // بيانات الروابط (تم توليدها من ملف Excel)
2
+ const DATA = [{"name": "أروى سعيد بن عبدالله القحطاني", "url": "https://stat2025-map.static.hf.space/BCS/37.html"}, {"name": "أسماء درويش سالم الدوسري", "url": "https://stat2025-map.static.hf.space/BCS/15.html"}, {"name": "أمل احمد محمد مجرشي", "url": "https://stat2025-map.static.hf.space/BCS/28.html"}, {"name": "أمل بنت علي بن علي السماعيل", "url": "https://stat2025-map.static.hf.space/BCS/07.html"}, {"name": "أمل جعفر بن علي آل حماد", "url": "https://stat2025-map.static.hf.space/BCS/30.html"}, {"name": "أمل صالح بن احمد آل مزعل", "url": "https://stat2025-map.static.hf.space/BCS/47.html"}, {"name": "ابرار بنت يوسف بن علي آل حماد", "url": "https://stat2025-map.static.hf.space/BCS/44.html"}, {"name": "احلام صالح معيوض العصيمي", "url": "https://stat2025-map.static.hf.space/BCS/16.html"}, {"name": "اسعد بن ماجد بن احمد الهاشم", "url": "https://stat2025-map.static.hf.space/BCS/46.html"}, {"name": "اسماء بنت محمد بن حسين العدساني", "url": "https://stat2025-map.static.hf.space/BCS/09.html"}, {"name": "ايمان عبدالعزيز بن صالح الصالح", "url": "https://stat2025-map.static.hf.space/BCS/40.html"}, {"name": "باسمه احمد بن محمد القرني", "url": "https://stat2025-map.static.hf.space/BCS/21.html"}, {"name": "باقر عبدالله بن هاشم الهاشم", "url": "https://stat2025-map.static.hf.space/BCS/11.html"}, {"name": "تركي وحيد بن عيسى المحيفيظ", "url": "https://stat2025-map.static.hf.space/BCS/01.html"}, {"name": "حسن عادل بن حسين الوصيبعي", "url": "https://stat2025-map.static.hf.space/BCS/03.html"}, {"name": "زكي بن عيسى بن عبدالله القفاص", "url": "https://stat2025-map.static.hf.space/BCS/51.html"}, {"name": "زهراء بنت عايش بن علي الصاهود", "url": "https://stat2025-map.static.hf.space/BCS/33.html"}, {"name": "ساره خالد سليمان المحيسن", "url": "https://stat2025-map.static.hf.space/BCS/35.html"}, {"name": "ساره راشد عبدالله المديني", "url": "https://stat2025-map.static.hf.space/BCS/34.html"}, {"name": "ساره عبدالحميد بن حسين البوحمد", "url": "https://stat2025-map.static.hf.space/BCS/12.html"}, {"name": "سميه رياض بن عبدالله البراك", "url": "https://stat2025-map.static.hf.space/BCS/39.html"}, {"name": "سميه سامى بن احمد النعيم", "url": "https://stat2025-map.static.hf.space/BCS/05.html"}, {"name": "شريفه ابراهيم بن عبدالله العقيل", "url": "https://stat2025-map.static.hf.space/BCS/41.html"}, {"name": "شيماء عبدالرحمن بن دحباش سودي", "url": "https://stat2025-map.static.hf.space/BCS/19.html"}, {"name": "صالح دلي الشمري", "url": "https://stat2025-map.static.hf.space/BCS/48.html"}, {"name": "طيبه فالح بن عبدالله الرويشد", "url": "https://stat2025-map.static.hf.space/BCS/31.html"}, {"name": "عائشه سليمان بن نايف الحربي", "url": "https://stat2025-map.static.hf.space/BCS/13.html"}, {"name": "عبدالله خلف الجدعان", "url": "https://stat2025-map.static.hf.space/BCS/49.html"}, {"name": "عقيله محمدحسين بن علي الجباره", "url": "https://stat2025-map.static.hf.space/BCS/06.html"}, {"name": "علياء فيصل بن محمد الكثيري", "url": "https://stat2025-map.static.hf.space/BCS/36.html"}, {"name": "غدير عبدالعزيز بن سعد القاسم", "url": "https://stat2025-map.static.hf.space/BCS/38.html"}, {"name": "فارس ثاني الشمري", "url": "https://stat2025-map.static.hf.space/BCS/50.html"}, {"name": "فاطمه حسين بن ابراهيم القرقوش", "url": "https://stat2025-map.static.hf.space/BCS/45.html"}, {"name": "فايزه محمد مسعود الحازمي", "url": "https://stat2025-map.static.hf.space/BCS/32.html"}, {"name": "فيصل تركي فيصل القحطاني", "url": "https://stat2025-map.static.hf.space/BCS/18.html"}, {"name": "لطيفه صالح بن عبدالرحمن العبد القادر", "url": "https://stat2025-map.static.hf.space/BCS/25.html"}, {"name": "لطيفه علي بن حسين النعيم", "url": "https://stat2025-map.static.hf.space/BCS/29.html"}, {"name": "لين أحمد بن عبدالعزيز القصير", "url": "https://stat2025-map.static.hf.space/BCS/22.html"}, {"name": "محمد دبيان بن مفرج الشمري", "url": "https://stat2025-map.static.hf.space/BCS/27.html"}, {"name": "مرتضى عبدالجليل بن عيسى الحكيم", "url": "https://stat2025-map.static.hf.space/BCS/43.html"}, {"name": "مصطفى احمد بن جمعه الرمضان", "url": "https://stat2025-map.static.hf.space/BCS/10.html"}, {"name": "ممدوح مشعل ضيف الله الصخري", "url": "https://stat2025-map.static.hf.space/BCS/26.html"}, {"name": "منيره سعد بن احمد الجديدي", "url": "https://stat2025-map.static.hf.space/BCS/04.html"}, {"name": "منيره سعود بن عبدالعزيز القوز", "url": "https://stat2025-map.static.hf.space/BCS/42.html"}, {"name": "نبأ عادل بن عبدالكريم آل رضوان", "url": "https://stat2025-map.static.hf.space/BCS/23.html"}, {"name": "نجود عبدالعزيز بن عقيل العمري", "url": "https://stat2025-map.static.hf.space/BCS/20.html"}, {"name": "نوره عبدالله بن زهير الرزقي", "url": "https://stat2025-map.static.hf.space/BCS/24.html"}, {"name": "نوره عبدالله بن مانع الخالدي", "url": "https://stat2025-map.static.hf.space/BCS/02.html"}, {"name": "نوف صالح بن محمد السميح", "url": "https://stat2025-map.static.hf.space/BCS/08.html"}, {"name": "نيللي حسين عبدالله الجعص", "url": "https://stat2025-map.static.hf.space/BCS/17.html"}, {"name": "وضحه خالد بن مشرف الخالدي", "url": "https://stat2025-map.static.hf.space/BCS/14.html"}];
3
+
4
+ // --------- أدوات مساعدة للتطبيع (لتحسين البحث بالعربية) ----------
5
+ function normalizeArabic(s) {
6
+ if (!s) return "";
7
+ return String(s)
8
+ .trim()
9
+ .toLowerCase()
10
+ // إزالة التشكيل
11
+ .replace(/[\u064B-\u065F\u0670\u06D6-\u06ED]/g, "")
12
+ // إزالة التطويل
13
+ .replace(/\u0640/g, "")
14
+ // توحيد الهمزات
15
+ .replace(/[إأآٱ]/g, "ا")
16
+ // توحيد الياء والألف المقصورة
17
+ .replace(/ى/g, "ي")
18
+ // توحيد الهاء/التاء المربوطة (يساعد في تطابقات أكثر)
19
+ .replace(/ة/g, "ه")
20
+ // توحيد المسافات
21
+ .replace(/\s+/g, " ");
22
+ }
23
+
24
+ function escapeHtml(str) {
25
+ return String(str)
26
+ .replaceAll("&", "&amp;")
27
+ .replaceAll("<", "&lt;")
28
+ .replaceAll(">", "&gt;")
29
+ .replaceAll('"', "&quot;")
30
+ .replaceAll("'", "&#039;");
31
+ }
32
+
33
+ // تظليل سريع: يظلل أول كلمة يطابقها حرفيًا في الاسم الأصلي إن وُجد
34
+ function highlightMatch(name, rawQuery) {
35
+ if (!rawQuery) return escapeHtml(name);
36
+ const tokens = rawQuery.trim().split(/\s+/).filter(Boolean);
37
+ if (!tokens.length) return escapeHtml(name);
38
+
39
+ let out = escapeHtml(name);
40
+ // جرّب تظليل أول توكن فقط (حتى لا نخرب التنسيق)
41
+ const t = tokens[0];
42
+ const idx = name.indexOf(t);
43
+ if (idx === -1) return out;
44
+
45
+ const before = escapeHtml(name.slice(0, idx));
46
+ const mid = escapeHtml(name.slice(idx, idx + t.length));
47
+ const after = escapeHtml(name.slice(idx + t.length));
48
+ return `${before}<mark>${mid}</mark>${after}`;
49
+ }
50
+
51
+ // --------- DOM ----------
52
+ const elQ = document.getElementById("q");
53
+ const elResults = document.getElementById("results");
54
+ const elCount = document.getElementById("countBadge");
55
+ const elTotal = document.getElementById("totalPill");
56
+ const btnSearch = document.getElementById("btnSearch");
57
+ const btnClear = document.getElementById("btnClear");
58
+
59
+ elTotal.textContent = `📌 إجمالي الروابط: ${DATA.length}`;
60
+
61
+ // --------- Render ----------
62
+ function renderResults(list, rawQuery) {
63
+ elResults.innerHTML = "";
64
+
65
+ if (!list.length) {
66
+ elCount.textContent = "النتائج: 0";
67
+ elResults.innerHTML = `<div class="empty">لا توجد نتائج مطابقة. جرّب كتابة جزء آخر من الاسم.</div>`;
68
+ return;
69
+ }
70
+
71
+ elCount.textContent = `النتائج: ${list.length}`;
72
+
73
+ const frag = document.createDocumentFragment();
74
+
75
+ list.forEach(item => {
76
+ const row = document.createElement("div");
77
+ row.className = "item";
78
+
79
+ const left = document.createElement("div");
80
+ left.className = "left";
81
+
82
+ const nm = document.createElement("div");
83
+ nm.className = "name";
84
+ nm.innerHTML = highlightMatch(item.name, rawQuery);
85
+
86
+ const hint = document.createElement("div");
87
+ hint.className = "hint";
88
+ hint.textContent = "اضغط فتح الخريطة لزيارة صفحة الباحث";
89
+
90
+ left.appendChild(nm);
91
+ left.appendChild(hint);
92
+
93
+ const a = document.createElement("a");
94
+ a.className = "open";
95
+ a.href = item.url;
96
+ a.target = "_blank";
97
+ a.rel = "noopener";
98
+ a.innerHTML = `فتح الخريطة <span aria-hidden="true">↗</span>`;
99
+
100
+ row.appendChild(left);
101
+ row.appendChild(a);
102
+ frag.appendChild(row);
103
+ });
104
+
105
+ elResults.appendChild(frag);
106
+ }
107
+
108
+ // --------- Search ----------
109
+ function doSearch() {
110
+ const raw = (elQ.value || "").trim();
111
+ const q = normalizeArabic(raw);
112
+
113
+ if (!q) {
114
+ elCount.textContent = "النتائج: 0";
115
+ elResults.innerHTML = "";
116
+ return;
117
+ }
118
+
119
+ const tokens = q.split(" ").filter(Boolean);
120
+
121
+ const matched = DATA.filter(d => {
122
+ const nameNorm = normalizeArabic(d.name);
123
+ return tokens.every(t => nameNorm.includes(t));
124
+ });
125
+
126
+ // ترتيب: ال��قصر ثم أبجدي
127
+ matched.sort((a, b) => {
128
+ const al = (a.name || "").length;
129
+ const bl = (b.name || "").length;
130
+ if (al !== bl) return al - bl;
131
+ return (a.name || "").localeCompare(b.name || "", "ar");
132
+ });
133
+
134
+ renderResults(matched, raw);
135
+ }
136
+
137
+ btnSearch.addEventListener("click", doSearch);
138
+
139
+ btnClear.addEventListener("click", () => {
140
+ elQ.value = "";
141
+ elQ.focus();
142
+ elResults.innerHTML = "";
143
+ elCount.textContent = "النتائج: 0";
144
+ });
145
+
146
+ let t = null;
147
+ elQ.addEventListener("input", () => {
148
+ clearTimeout(t);
149
+ t = setTimeout(doSearch, 140);
150
+ });
151
+
152
+ elQ.addEventListener("keydown", (e) => {
153
+ if (e.key === "Enter") doSearch();
154
+ });