PageSourceSearch

https://proparcel.com/harita/

html proparcel.com collected 2026-09-24 14:50:35 UTC 167,568 bytes, 3,982 lines download raw bytes

1
2<!DOCTYPE html>
3<html lang="tr">
4
5<head>
6  <meta charset="UTF-8" />
7  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8  <meta name="csrf-token" content="2Cre8kAVjB10nTdr0n7SKNglW0I8Bh6Qlid0XCZp7Ki04H7rPwJDi7PXOBjKRF2C" />
9  <title>Parsel Sorgula — Ada Parsel Harita Sorgulama | ProParcel</title>
10  <meta name="description" content="Ada ve parsel numarası girerek ücretsiz parsel sorgulama yapın. Uydu haritasında parsel sınırlarını görün, ProSorgu ile detaylı analiz alın.">
11
12<link rel="canonical" href="https://proparcel.com/harita/">
13<meta property="og:locale" content="tr_TR">
14<meta property="og:title" content="Parsel Sorgula — Ada Parsel Harita Sorgulama | ProParcel">
15<meta property="og:description" content="Ada ve parsel numarası girerek ücretsiz parsel sorgulama yapın. Uydu haritasında parsel sınırlarını görün, ProSorgu ile detaylı analiz alın.">
16<meta property="og:url" content="https://proparcel.com/harita/">
17<meta property="og:site_name" content="ProParcel">
18<meta property="og:type" content="website">
19<meta property="og:image" content="https://proparcel.com/static/img/favicon.ico">
20<meta name="twitter:card" content="summary_large_image">
21<meta name="twitter:title" content="Parsel Sorgula — Ada Parsel Harita Sorgulama | ProParcel">
22<meta name="twitter:description" content="Ada ve parsel numarası girerek ücretsiz parsel sorgulama yapın. Uydu haritasında parsel sınırlarını görün, ProSorgu ile detaylı analiz alın.">
23<meta name="twitter:image" content="https://proparcel.com/static/img/favicon.ico">
24
25
26<script type="application/ld+json">{"@context": "https://schema.org", "@type": "Organization", "name": "ProParcel", "url": "https://proparcel.com", "logo": "https://proparcel.com/static/img/favicon.ico", "email": "[email protected]", "address": {"@type": "PostalAddress", "streetAddress": "Nilüferköy Mahallesi, Nilüfer Cad. No: 98-100/2, Osmangazi / Bursa", "addressCountry": "TR"}}</script>
26
27
28<script type="application/ld+json">{"@context": "https://schema.org", "@type": "WebApplication", "name": "ProParcel Parsel Sorgulama", "url": "https://proparcel.com/harita/", "applicationCategory": "BusinessApplication", "operatingSystem": "Web", "offers": {"@type": "Offer", "price": "0", "priceCurrency": "TRY", "description": "Ücretsiz ada parsel sorgulama"}}</script>
28
29
30
31
32  
33
34
35  
36<link rel="icon" type="image/x-icon" href="/static/img/favicon.ico" />
37
38  
38<script>
39    // Loader Three.js sayfa acilisinda degil; yalnizca Pro Sorgu show() sirasinda
40    // lazy init + hide()'da dispose (Mapbox context ile surekli carpismasin).
41    window.__ppLoaderAutoShow = false;
42    window.__PP_DISABLE_LOADER_WEBGL = false;
43    window.__PP_FORCE_DISABLE_LOADER_WEBGL = false;
44    window.__ppUseAnimatedLoader = false;
45  </script>
45
46  
47  <!-- DNS Preconnect - Dış kaynaklar için erken bağlantı -->
48  <link rel="preconnect" href="https://api.mapbox.com" crossorigin>
49  <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
50  <link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
51  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
52  <link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
53  <link rel="preconnect" href="https://code.jquery.com" crossorigin>
54  
55  <!-- Static URL Configuration - Proje taşındığında dinamik çalışması için -->
56  
56<script>
57    // Django static URL'ini global olarak tanımla
58    // /static/models/house/ kullanarak base URL'i al, sonra 'models/house/' kısmını çıkar
59    (function() {
60      try {
61        var testUrl = '/static/models/house/';
62        // Eğer testUrl '/static/models/house/' formatındaysa, '/static' kısmını al
63        var match = testUrl.match(/^(.+?)\/models\/house\/$/);
64        if (match && match[1]) {
65          window.STATIC_URL = match[1];
66        } else {
67          // Fallback: window.location'dan türet
68          var base = window.location.origin;
69          var pathMatch = window.location.pathname.match(/^(.+?)\/static\//);
70          if (pathMatch && pathMatch[1]) {
71            window.STATIC_URL = pathMatch[1] + '/static';
72          } else {
73            window.STATIC_URL = '/static';
74          }
75        }
76        // Sonunda '/' olmamalı
77        window.STATIC_URL = window.STATIC_URL.replace(/\/$/, '');
78      } catch (e) {
79        // Hata durumunda varsayılan değer
80        window.STATIC_URL = '/static';
81      }
82    })();
83  </script>
83
84  
85  <!-- API keys are injected from settings/env. -->
86  
86<script>
87    window.CESIUM_ION_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyOWUwODRjNy0yNjQ2LTQyMmItYWM1Yy00MzJkZTkyMmU4YmUiLCJpZCI6MzI5NDE5LCJpYXQiOjE3NTQ0OTM1OTB9.p5JsFAeQ9eP7MZD3EPqXAmmuudDMPRVGLyW7tAMCjQE';
88    window.GOOGLE_MAPS_API_KEY = 'AIzaSyBjVhbRZSqby77ou2yDpJn\u002DPFNFbLFfNHU';
89  </script>
89
90  <!-- PP_OPEN_REPORT_V2 mesajı app.js içindeki listener tarafından işleniyor (çift listener sorunu giderildi) -->
91  
92  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
93  
94<link rel="icon" type="image/x-icon" href="/static/img/favicon.ico" />
95
96  
97  <!-- Modern Layout System (YENİ - EN ÖNCE YÜKLENMELİ) -->
98  <link rel="stylesheet" href="/static/css/layout.css?v=20260704-tile-proxy-cursor">
99  
100  <!-- Existing Styles -->
101  <link rel="stylesheet" href="/static/css/style.css?v=20260810-mode-overlay">
102  <link rel="stylesheet" href="/static/css/report_background.css">
103  <link rel="stylesheet" href="/static/css/layer_style.css">
104  <link rel="stylesheet" href="/static/css/graphics_side_bar.css">
105  <link rel="stylesheet" href="/static/css/parameters_buttons.css">
106  <link rel="stylesheet" href="/static/css/sidebar.css?v=20260711-daire-btn-style">
107  <style id="pp-sidebar-tab-dropdown-critical">
108    /* Sidebar sekme dropdown — template içi; eski cache CSS çakışmasını kırar */
109    #pp-sidebar-tab-dropdown { position: relative; margin: 22px 12px 10px; flex-shrink: 0; z-index: 8; }
110    #pp-sidebar-tab-trigger {
111      display: flex !important; align-items: center; gap: 8px; width: 100%; box-sizing: border-box;
112      height: 42px; min-height: 42px; padding: 0 12px; margin: 0;
113      border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; color: #111827;
114      font-weight: 600; font-size: 14px; cursor: pointer;
115    }
116    #pp-sidebar-tab-trigger .pp-sidebar-tab-trigger__text { flex: 1; text-align: left; }
117    #pp-sidebar-tab-trigger .pp-sidebar-tab-trigger__chevron { margin-left: auto; font-size: 11px; color: #64748b; }
118    #pp-sidebar-tab-menu,
119    #pp-sidebar-tab-menu[hidden] {
120      display: none !important; visibility: hidden !important; pointer-events: none !important;
121      list-style: none; margin: 0; padding: 6px; position: absolute; top: calc(100% + 6px); left: 0; right: 0;
122      background: #fff; border: 1px solid #e5e7eb; border-radius: 8px;
123      box-shadow: 0 12px 28px rgba(15, 23, 42, 0.14); flex-direction: column; gap: 4px; z-index: 30;
124    }
125    #pp-sidebar-tab-dropdown.is-open #pp-sidebar-tab-menu:not([hidden]) {
126      display: flex !important; visibility: visible !important; pointer-events: auto !important;
127    }
128    /* Eski yatay sekme şeridi — dropdown varken asla gösterme */
129    #sidebar > ul.sidebar-tabs { display: none !important; }
130  </style>
131  <link rel="stylesheet" href="/static/css/components/_collapsible.css">
132  <link rel="stylesheet" href="/static/css/components/_capture_overlay.css?v=20260518-capture-menu-fixed">
133  <link rel="stylesheet" href="/static/css/toggle_button.css?v=20260815-kentsel">
134  <link rel="stylesheet" href="/static/css/user_adding.css">
135  <link rel="stylesheet" href="/static/css/toggle_button_drawing.css">
136  <link rel="stylesheet" href="/static/css/camera_control.css">
137  <!-- 3D Model Editörü CSS'leri /3d-editor/ sayfasına taşındı -->
138  <!-- Mapbox GL JS only (2D and 3D maps) -->
139  <!-- Font Awesome yüklü değilse şunu ekle -->
140
141
142  <!-- GPU capability: yalnızca WebGL yoksa Mapbox atlanır; software/eski GPU → minimal_gpu + Mapbox -->
143  
143<script>
144    (function () {
145      var FULL = 'full_gpu';
146      var MINIMAL = 'minimal_gpu';
147      var NO_GPU = 'no_gpu';
148      function setMode(mode, reason) {
149        window.__PP_GPU_MODE = mode;
150        window.__PP_GPU_REASON = reason || '';
151        window.__PP_SKIP_MAPBOX_GL = mode === NO_GPU;
152        window.__PP_EARLY_WEBGL_DISABLED = mode === NO_GPU;
153        window.__PP_ALLOW_MAPBOX_GL = mode !== NO_GPU;
154        try {
155          if (window.sessionStorage) {
156            window.sessionStorage.setItem('pp_gpu_mode', mode);
157            window.sessionStorage.setItem('pp_gpu_reason', reason || '');
158          }
159          if (window.localStorage) {
160            window.localStorage.setItem('pp_gpu_mode', mode);
161            window.localStorage.setItem('pp_gpu_reason', reason || '');
162          }
163        } catch (e) {}
164      }
165      function tryCtx(canvas, name, strictCaveat) {
166        try {
167          return canvas.getContext(name, {
168            alpha: false, antialias: false, depth: true,
169            failIfMajorPerformanceCaveat: !!strictCaveat,
170            preserveDrawingBuffer: false, stencil: false
171          });
172        } catch (e) { return null; }
173      }
174      try {
175        var q = window.location.search || '';
176        if (/(?:\?|&)(pp_force_legacy_map|pp_leaflet_only|pp_skip_mapbox)=1(?:&|$)/.test(q)) {
177          setMode(NO_GPU, 'forced_query');
178          return;
179        }
180        if (/(?:\?|&)pp_force_full_gpu=1(?:&|$)/.test(q)) {
181          setMode(FULL, 'forced_full_gpu');
182          return;
183        }
184        if (/(?:\?|&)pp_force_minimal_gpu=1(?:&|$)/.test(q)) {
185          setMode(MINIMAL, 'forced_minimal_gpu');
186          return;
187        }
188      } catch (e) {}
189      try {
190        var canvasGl1 = document.createElement('canvas');
191        var canvasGl2 = document.createElement('canvas');
192        var canvasGl2Strict = document.createElement('canvas');
193        var gl = null;
194        var gl2 = null;
195        try { gl = tryCtx(canvasGl1, 'webgl') || tryCtx(canvasGl1, 'experimental-webgl'); } catch (e) {}
196        try { gl2 = tryCtx(canvasGl2, 'webgl2'); } catch (e) {}
197        var safeGl2 = null;
198        try { safeGl2 = tryCtx(canvasGl2Strict, 'webgl2', true); } catch (e) {}
199        window.__PP_MAJOR_PERFORMANCE_CAVEAT = !!gl2 && !safeGl2;
200        window.__PP_EARLY_WEBGL_AVAILABLE = !!(gl || gl2);
201        if (gl || gl2) {
202          setMode(MINIMAL, 'early_webgl_ok');
203          try {
204            var lose = (gl2 || gl).getExtension('WEBGL_lose_context');
205            if (lose && typeof lose.loseContext === 'function') lose.loseContext();
206          } catch (e) {}
207        } else {
208          window.__PP_EARLY_WEBGL_AVAILABLE = false;
209          setMode(NO_GPU, 'webgl_unavailable');
210        }
211      } catch (e) {
212        window.__PP_EARLY_WEBGL_AVAILABLE = false;
213        setMode(NO_GPU, 'early_probe_exception');
214      }
215    })();
216  </script>
216
217  <style>
218    .pp-mapbox-capable #pp-static-map-backdrop,
219    .pp-mapbox-capable #pp-static-leaflet-fallback,
220    .pp-mapbox-capable #pp-static-satellite-tiles {
221      display: none !important;
222    }
223  </style>
224  
224<script>
225    (function () {
226      try {
227        if (window.__PP_ALLOW_MAPBOX_GL !== false && !window.__PP_SKIP_MAPBOX_GL && !window.__PP_EARLY_WEBGL_DISABLED) {
228          document.documentElement.className += ' pp-mapbox-capable';
229          window.__PP_HIDE_STATIC_MAP_FALLBACK = true;
230        }
231      } catch (e) {}
232    })();
233  </script>
233
234  <link href="https://api.mapbox.com/mapbox-gl-js/v3.2.0/mapbox-gl.css" rel="stylesheet" />
235  
235<script>
236    (function () {
237      if (!window.__PP_SKIP_MAPBOX_GL && !window.__PP_EARLY_WEBGL_DISABLED && window.__PP_ALLOW_MAPBOX_GL !== false) return;
238      document.write('<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">');
239    })();
240  </script>
240
241  
241<script src="/static/js/core/map/index_legacy_bootstrap.js?v=20260520-no-stale-storage"></script>
241
242  <!-- Google Maps CORS + EventTarget passive patch (tek override) -->
243  
243<script>
244    (function() {
245      // Google Maps tile CORS uyarılarını filtrele
246      var _origError = console.error;
247      console.error = function() {
248        var msg = Array.prototype.join.call(arguments, ' ');
249        if (msg.indexOf('mt1.google.com') !== -1 || msg.indexOf('mt0.google.com') !== -1 ||
250            (msg.indexOf('google.com/vt') !== -1 && msg.indexOf('CORS') !== -1)) return;
251        _origError.apply(console, arguments);
252      };
253
254      // Unhandled fetch rejection filtresi (Google Maps tile CORS)
255      window.addEventListener('unhandledrejection', function(event) {
256        var err = event.reason;
257        var errMsg = err && (err.message || String(err));
258        if (errMsg && (errMsg.indexOf('mt1.google.com') !== -1 || errMsg.indexOf('mt0.google.com') !== -1 || errMsg.indexOf('google.com/vt') !== -1)) {
259          event.preventDefault();
260          return;
261        }
262      });
263
264      // EventTarget.prototype.addEventListener tek seferlik override
265      var _origAEL = EventTarget.prototype.addEventListener;
266      var touchmovePatchCount = 0;
267      var MAX_TOUCHMOVE_PATCHES = 5;
268
269      EventTarget.prototype.addEventListener = function(type, listener, options) {
270        if (type === 'touchmove' && touchmovePatchCount < MAX_TOUCHMOVE_PATCHES) {
271          if (typeof options === 'object' && options !== null) {
272            if (!options.passive && !options.capture) { options.passive = true; touchmovePatchCount++; }
273          } else if (options == null) { options = { passive: true }; touchmovePatchCount++; }
274        }
275        if (type === 'wheel' && this.classList) {
276          var isSel2 = this.classList.contains('select2-container') ||
277                       this.classList.contains('select2-results__options') ||
278                       (this.closest && this.closest('.select2-container'));
279          if (isSel2) {
280            if (typeof options === 'object' && options !== null) { options.passive = true; }
281            else if (typeof options === 'boolean') { options = { capture: options, passive: true }; }
282            else { options = { passive: true }; }
283          }
284        }
285        return _origAEL.call(this, type, listener, options);
286      };
287    })();
288  </script>
288
289
290  <!-- Diğer ihtiyacın olanlar -->
291  
291<script src="https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js"></script>
291
292  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=Inter:wght@500;600;700&display=swap" rel="stylesheet">
293  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
294
295  <!-- jQuery + Select2 (Mahalle select için gelişmiş arama) -->
296  
296<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
296
297  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
298  
298<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.full.min.js"></script>
298
299
300
301
302
303
304  <!-- Hata yakalama ve görsel bildirim -->
305  
305<script src="/static/js/initialization/error_overlay.js"></script>
305
306
307  <!-- Google Fonts zaten head'de yüklü -->
308  <style>
309    @keyframes spin {
310      0% { transform: rotate(0deg); }
311      100% { transform: rotate(360deg); }
312    }
313    .pp-seo-page-title {
314      position: absolute;
315      width: 1px;
316      height: 1px;
317      padding: 0;
318      margin: -1px;
319      overflow: hidden;
320      clip: rect(0, 0, 0, 0);
321      white-space: nowrap;
322      border: 0;
323    }
324  </style>
325
326  <style>
327    /* Select2 için güvenli genişlik ve üstte görünme düzeltmesi */
328    .sidebar .select2-container {
329      width: 100% !important;
330    }
331
332    .pp-sidebar-saved-queries {
333      display: flex;
334      flex-direction: column;
335      gap: 10px;
336      width: 100%;
337    }
338
339    .pp-sidebar-saved-queries__header {
340      display: flex;
341      flex-direction: column;
342      gap: 2px;
343      padding: 2px 0 6px;
344      color: #0f172a;
345      font-family: 'Inter', Arial, sans-serif;
346    }
347
348    .pp-sidebar-saved-queries__header span {
349      color: #64748b;
350      font-size: 12px;
351    }
352
353    .pp-sidebar-saved-query-list {
354      display: flex;
355      flex-direction: column;
356      gap: 8px;
357      max-height: calc(100vh - 230px);
358      overflow-y: auto;
359      padding-right: 2px;
360    }
361
362    .pp-sidebar-saved-query-item {
363      align-items: center;
364      display: flex;
365      gap: 8px;
366      width: 100%;
367      border: 1px solid #dbeaf7;
368      border-radius: 10px;
369      background: #ffffff;
370      box-shadow: 0 1px 6px rgba(37, 99, 235, 0.08);
371      color: #0f172a;
372      padding: 10px 12px;
373      text-align: left;
374      transition: border-color 0.18s, box-shadow 0.18s, transform 0.18s;
375    }
376
377    .pp-sidebar-saved-query-item:hover {
378      border-color: #93c5fd;
379      box-shadow: 0 4px 14px rgba(37, 99, 235, 0.12);
380      transform: translateY(-1px);
381    }
382
383    .pp-sidebar-saved-query-main {
384      background: transparent;
385      border: 0;
386      color: inherit;
387      cursor: pointer;
388      flex: 1;
389      min-width: 0;
390      padding: 0;
391      text-align: left;
392    }
393
394    .pp-sidebar-saved-query-check {
395      accent-color: #2563eb;
396      flex: 0 0 auto;
397      height: 16px;
398      width: 16px;
399    }
400
401    .pp-sidebar-saved-query-delete {
402      align-items: center;
403      background: #fef2f2;
404      border: 1px solid #fecaca;
405      border-radius: 9px;
406      color: #dc2626;
407      cursor: pointer;
408      display: inline-flex;
409      flex: 0 0 auto;
410      height: 32px;
411      justify-content: center;
412      width: 32px;
413    }
414
415    .pp-sidebar-saved-query-delete:hover {
416      background: #fee2e2;
417    }
418
419    .pp-sidebar-saved-query-title {
420      display: flex;
421      align-items: center;
422      justify-content: space-between;
423      gap: 8px;
424      font-size: 14px;
425      font-weight: 700;
426      margin-bottom: 4px;
427    }
428
429    .pp-sidebar-saved-query-meta,
430    .pp-sidebar-saved-query-sub {
431      color: #64748b;
432      display: block;
433      font-size: 12px;
434      line-height: 1.35;
435    }
436
437    .pp-sidebar-saved-query-mode {
438      border-radius: 999px;
439      background: #eff6ff;
440      color: #2563eb;
441      flex: 0 0 auto;
442      font-size: 10px;
443      font-weight: 700;
444      padding: 2px 7px;
445      text-transform: uppercase;
446    }
447
448    .pp-sidebar-saved-query-empty {
449      border: 1px dashed #cbd5e1;
450      border-radius: 10px;
451      color: #64748b;
452      font-size: 13px;
453      padding: 14px 12px;
454      text-align: center;
455    }
456
457    .pp-sidebar-saved-query-actions {
458      align-items: center;
459      display: flex;
460      gap: 8px;
461      justify-content: space-between;
462      margin-bottom: 8px;
463    }
464
465    .pp-sidebar-saved-query-action {
466      border: 1px solid #dbeaf7;
467      border-radius: 9px;
468      background: #fff;
469      color: #334155;
470      cursor: pointer;
471      font-size: 12px;
472      font-weight: 700;
473      padding: 7px 9px;
474    }
475
476    .pp-sidebar-saved-query-action.danger {
477      border-color: #fecaca;
478      color: #dc2626;
479    }
480
481    .pp-sidebar-saved-query-action:disabled {
482      cursor: not-allowed;
483      opacity: .55;
484    }
485
486    /* Clear (x) ikonunu gizle */
487    .select2-selection__clear {
488      display: none !important;
489    }
490
491    /* Sidebar Select2 Modern Stil */
492    .sidebar .select2-container--default .select2-selection--single {
493      height: 42px;
494      border: 1.5px solid #dbeaf7;
495      border-radius: 8px;
496      background-color: #fff;
497      display: flex;
498      align-items: center;
499      box-shadow: 0 1px 6px rgba(37, 99, 235, 0.08);
500      transition: border 0.2s, box-shadow 0.2s;
501    }
502
503    .sidebar .select2-container--default .select2-selection--single .select2-selection__rendered {
504      padding-left: 12px;
505      padding-right: 32px;
506      line-height: 40px;
507      color: #222;
508      font-size: 15px;
509      font-family: 'Inter', Arial, sans-serif;
510    }
511
512    .sidebar .select2-container--default .select2-selection--single .select2-selection__placeholder {
513      color: #9ca3af;
514    }
515
516    .sidebar .select2-container--default .select2-selection--single .select2-selection__arrow {
517      height: 40px;
518      right: 10px;
519    }
520    
521    .sidebar .select2-container--default .select2-selection--single .select2-selection__arrow b {
522      border-color: #6b7280 transparent transparent transparent;
523    }
524
525    /* Dropdown stili - dropdown body'ye ekleniyor, sidebar dışında */
526    .select2-dropdown {
527      z-index: 2147483000 !important;
528      border: 1.5px solid #dbeaf7;
529      border-radius: 8px;
530      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
531      background: #fff;
532    }
533
534    .select2-results__option {
535      padding: 10px 14px;
536      font-size: 14px;
537      color: #222;
538      transition: background 0.15s;
539    }
540
541    .select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
542      background: #2563eb;
543      color: #fff;
544    }
545
546    .select2-container--default .select2-results__option--selected {
547      background: #f3f4f6;
548      color: #222;
549    }
550    
551    /* Select2 arama kutusu stili */
552    .select2-search--dropdown .select2-search__field {
553      padding: 10px 12px;
554      border: 1.5px solid #dbeaf7;
555      border-radius: 6px;
556      font-size: 14px;
557      font-family: 'Inter', Arial, sans-serif;
558      transition: border 0.2s, box-shadow 0.2s;
559    }
560    
561    .select2-search--dropdown .select2-search__field:focus {
562      border-color: #2563eb;
563      outline: 0;
564      box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
565    }
566    
567    /* Select2 hover ve focus efekti */
568    .sidebar .select2-container--default .select2-selection--single:hover {
569      border-color: #2563eb;
570    }
571    
572    .sidebar .select2-container--default.select2-container--focus .select2-selection--single,
573    .sidebar .select2-container--default.select2-container--open .select2-selection--single {
574      border-color: #2563eb;
575      box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
576    }
577    
578    .sidebar .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
579      border-color: transparent transparent #2563eb transparent;
580    }
581  </style>
582
583  <style>
584    body.pp-app #modeSwitchBtn::before {
585      border-radius: 0 !important;
586    }
587  </style>
588  <link rel="stylesheet" href="/static/css/components/_annotation_tools.css">
589  <link rel="stylesheet" href="/static/css/inline_styles.css">
590  
590<script src="/static/js/core/layer/layer_style.js"></script>
590
591  
592
593</head>
594
595<body class="pp-app">
596  
597  <h1 class="pp-seo-page-title">Parsel Sorgula</h1>
598  
599
600<style>
601  /* === LOADING OVERLAY (loadingScreen.html'den) === */
602  #pp-loader-bg3d {
603    position: fixed;
604    inset: 0;
605    z-index: 9998;
606    overflow: hidden;
607    display: none; /* show() açar; varsayılan kapalı — aksi halde z-index haritayı örter */
608  }
609
610  .pp-loader-overlay {
611    position: fixed;
612    inset: 0;
613    z-index: 9999;
614    display: flex;
615    align-items: center;
616    justify-content: center;
617    background: transparent;
618    backdrop-filter: none;
619    color: #e5e7eb;
620    font-family: 'IBM Plex Sans', sans-serif;
621    transition: opacity 0.5s ease;
622  }
623  .pp-loader-overlay.pp-loader-hidden {
624    opacity: 0;
625    pointer-events: none;
626  }
627
628  .pp-loader-panel {
629    width: min(900px, 92vw);
630    max-height: 90vh;
631    background: rgba(15, 23, 42, 0.96);
632    border-radius: 14px;
633    box-shadow: 0 28px 80px rgba(0, 0, 0, 0.65);
634    padding: 20px 24px 18px;
635    border: 1px solid rgba(148, 163, 184, 0.35);
636    display: flex;
637    flex-direction: column;
638    gap: 14px;
639  }
640
641  .pp-loader-header {
642    display: flex;
643    flex-direction: column;
644    gap: 6px;
645  }
646  .pp-loader-logo {
647    display: inline-flex;
648    align-items: center;
649    justify-content: center;
650    align-self: flex-start;
651    padding: 3px 10px;
652    border-radius: 999px;
653    font-size: 11px;
654    letter-spacing: 0.08em;
655    text-transform: uppercase;
656    background: rgba(15, 118, 110, 0.15);
657    border: 1px solid rgba(45, 212, 191, 0.7);
658    color: #a5f3fc;
659  }
660  .pp-loader-title {
661    font-size: 17px;
662    font-weight: 600;
663    color: #f9fafb;
664  }
665  .pp-loader-subtitle {
666    font-size: 13px;
667    color: #9ca3af;
668  }
669  .pp-loader-timer {
670    font-size: 11px;
671    color: #6b7280;
672  }
673
674  .pp-loader-body {
675    display: grid;
676    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.3fr);
677    gap: 16px;
678  }
679  @media (max-width: 768px) {
680    .pp-loader-body {
681      grid-template-columns: minmax(0, 1fr);
682    }
683  }
684
685  .pp-loader-map {
686    position: relative;
687    height: 170px;
688    border-radius: 12px;
689    overflow: hidden;
690    background: radial-gradient(circle at 10% 0, #22c55e 0, transparent 45%),
691                radial-gradient(circle at 90% 100%, #0ea5e9 0, transparent 50%),
692                #020617;
693    border: 1px solid rgba(148, 163, 184, 0.5);
694  }
695  .pp-loader-map-layer {
696    position: absolute;
697    inset: 0;
698    background-image:
699      linear-gradient(90deg, rgba(148,163,184,0.28) 1px, transparent 1px),
700      linear-gradient(180deg, rgba(148,163,184,0.28) 1px, transparent 1px);
701    background-size: 26px 26px;
702    opacity: 0.9;
703    animation: ppGridDrift 14s linear infinite;
704  }
705  .pp-loader-map-pulse {
706    position: absolute;
707    inset: 22% 20%;
708    border-radius: 18px;
709    border: 1px solid rgba(56,189,248,0.8);
710    box-shadow: 0 0 20px rgba(56,189,248,0.4);
711    animation: ppPulse 1.8s ease-in-out infinite;
712  }
713
714  @keyframes ppGridDrift {
715    0%   { transform: translate(0, 0) scale(1); }
716    50%  { transform: translate(-8px, -6px) scale(1.03); }
717    100% { transform: translate(0, 0) scale(1); }
718  }
719  @keyframes ppPulse {
720    0%   { transform: scale(1);     opacity: 0.85; }
721    50%  { transform: scale(1.05);  opacity: 1; }
722    100% { transform: scale(1);     opacity: 0.85; }
723  }
724
725  /* Aktif adım kartı */
726  .pp-loader-active-card {
727    display: flex;
728    align-items: flex-start;
729    gap: 12px;
730    padding: 14px 14px;
731    border-radius: 12px;
732    border: 1px solid rgba(148, 163, 184, 0.35);
733    background: rgba(2, 6, 23, 0.35);
734    min-height: 86px;
735  }
736  .pp-loader-active-icon {
737    width: 34px;
738    height: 34px;
739    border-radius: 999px;
740    display: flex;
741    align-items: center;
742    justify-content: center;
743    font-size: 18px;
744    flex-shrink: 0;
745    background: rgba(15,23,42,0.9);
746    border: 1px solid rgba(148,163,184,0.7);
747  }
748  .pp-loader-active-content {
749    display: flex;
750    flex-direction: column;
751    gap: 4px;
752    text-align: left;
753  }
754  .pp-loader-active-title {
755    font-size: 14px;
756    color: #f9fafb;
757    font-weight: 650;
758    line-height: 1.25;
759    transition: opacity 220ms ease, transform 220ms ease;
760  }
761  .pp-loader-active-title.fadeOut {
762    opacity: 0;
763    transform: translateY(4px);
764  }
765  .pp-loader-active-desc {
766    font-size: 12px;
767    color: #cbd5e1;
768    line-height: 1.35;
769    min-height: 18px;
770  }
771
772  .pp-loader-progress {
773    margin-top: 4px;
774    display: flex;
775    flex-direction: column;
776    gap: 4px;
777  }
778  .pp-loader-progress-bar {
779    position: relative;
780    width: 100%;
781    height: 5px;
782    border-radius: 999px;
783    background: rgba(30,41,59,1);
784    overflow: hidden;
785  }
786  .pp-loader-progress-fill {
787    position: absolute;
788    inset: 0;
789    width: 100%;
790    border-radius: inherit;
791    background: linear-gradient(90deg, #22c55e, #22d3ee, #38bdf8);
792    background-size: 200% 100%;
793    animation: ppShimmer 2.2s linear infinite;
794  }
795  @keyframes ppShimmer {
796    0%   { background-position: 0% 50%; }
797    100% { background-position: -200% 50%; }
798  }
799  .pp-loader-progress-text {
800    font-size: 11px;
801    color: #9ca3af;
802    text-align: right;
803  }
804
805  /* WebGL yok / bağlam limiti: Three sahnesi yerine statik arka plan */
806  .pp-bg3d--fallback {
807    background: radial-gradient(ellipse 120% 80% at 50% 100%, #0c1929 0%, #041026 45%, #020617 100%);
808  }
809</style>
810
811<!-- 3D terrain arka plan; WebGL modülleri kapalıysa CSS gradient fallback -->
812<div id="pp-loader-bg3d"></div>
813
814<!-- ProParcel Loader Overlay -->
815<div id="pp-loader-overlay" class="pp-loader-overlay">
816  <div class="pp-loader-panel">
817    <div class="pp-loader-header">
818      <div class="pp-loader-logo">ProParcel</div>
819      <div class="pp-loader-title">Arazi değerleme analizi hazırlanıyor…</div>
820      <div class="pp-loader-subtitle" id="pp-loader-subtitle">
821        Arazi değerleme analizi hazırlanıyor…
822      </div>
823      <div class="pp-loader-timer" id="pp-loader-timer">
824        Süre: 0 sn
825      </div>
826    </div>
827
828    <div class="pp-loader-body">
829      <div class="pp-loader-map">
830        <div class="pp-loader-map-layer"></div>
831        <div class="pp-loader-map-pulse">
832          <canvas id="pp-inner-canvas" data-engine="three.js r181" width="1545" height="868" style="display: block; width: 100%; height: 100%; touch-action: none;"></canvas>
833        </div>
834      </div>
835
836      <div class="pp-loader-active-card" id="pp-loader-active-card" aria-live="polite" aria-atomic="true">
837        <div class="pp-loader-active-icon" id="pp-loader-active-icon">⚙️</div>
838        <div class="pp-loader-active-content">
839          <div class="pp-loader-active-title" id="pp-loader-active-title">Arazi değerleme analizi hazırlanıyor…</div>
840          <div class="pp-loader-active-desc" id="pp-loader-active-desc">Lütfen bekleyin.</div>
841        </div>
842      </div>
843    </div>
844
845    <div class="pp-loader-progress">
846      <div class="pp-loader-progress-bar">
847        <div class="pp-loader-progress-fill" id="pp-loader-progress-fill"></div>
848      </div>
849      <div class="pp-loader-progress-text" id="pp-loader-progress-text">
850        İşleniyor…
851      </div>
852    </div>
853  </div>
854</div>
855
856<!-- Loading Overlay JS: Statik mesaj + backend progress, indeterminate bar, zamanlayıcı -->
857<script>
858(function() {
859  'use strict';
860
861  var __ppTimerStart = null;
862  var __ppTimerInterval = null;
863  var __ppHideTimeout = null;
864  var STATIC_MSG = 'Arazi değerleme analizi hazırlanıyor…';
865
866  function initStaticMessage() {
867    var titleEl = document.getElementById('pp-loader-active-title');
868    var subtitleEl = document.getElementById('pp-loader-subtitle');
869    var descEl = document.getElementById('pp-loader-active-desc');
870    if (titleEl) titleEl.textContent = STATIC_MSG;
871    if (subtitleEl) subtitleEl.textContent = STATIC_MSG;
872    if (descEl) descEl.textContent = 'Lütfen bekleyin.';
873  }
874
875  function startTimer() {
876    __ppTimerStart = Date.now();
877    var el = document.getElementById('pp-loader-timer');
878    if (el) el.textContent = 'Süre: 0 sn';
879    __ppTimerInterval = window.setInterval(function() {
880      if (!__ppTimerStart) return;
881      var diffMs = Date.now() - __ppTimerStart;
882      var sec = Math.floor(diffMs / 1000);
883      if (el) el.textContent = 'Süre: ' + sec + ' sn';
884    }, 1000);
885  }
886
887  function ensureBg3dFallback(bg) {
888    if (!bg) return;
889    var webglDisabled = false;
890    try {
891      webglDisabled = window.__PP_FORCE_DISABLE_LOADER_WEBGL === true
892        || window.__PP_DISABLE_LOADER_WEBGL === true;
893    } catch (_) {}
894    if (webglDisabled) {
895      bg.classList.add('pp-bg3d--fallback');
896      return;
897    }
898    // WebGL yolu açık: canvas yoksa (init henüz yok / başarısız) CSS gradient yedek
899    var hasCanvas = false;
900    try { hasCanvas = !!(bg.querySelector && bg.querySelector('canvas')); } catch (_) {}
901    if (!hasCanvas) {
902      bg.classList.add('pp-bg3d--fallback');
903    }
904  }
905
906  function softRecoverIndexMap() {
907    try {
908      var m = window.mapManager && window.mapManager.maps && window.mapManager.maps['3d'];
909      if (!m) return;
910      if (typeof m.resize === 'function') m.resize();
911      if (typeof m.triggerRepaint === 'function') m.triggerRepaint();
912    } catch (_) {}
913  }
914
915  function disposeLoaderWebGLScenes() {
916    try {
917      if (typeof window.disposeLoaderTerrainBg === 'function') window.disposeLoaderTerrainBg();
918    } catch (_) {}
919    try {
920      if (typeof window.disposeForestHouse === 'function') window.disposeForestHouse();
921    } catch (_) {}
922  }
923
924  window.ProParcelLoader = {
925    show: function() {
926      if (__ppHideTimeout) { clearTimeout(__ppHideTimeout); __ppHideTimeout = null; }
927      var overlay = document.getElementById('pp-loader-overlay');
928      var bg = document.getElementById('pp-loader-bg3d');
929      if (overlay) {
930        overlay.classList.remove('pp-loader-hidden');
931        overlay.style.display = 'flex';
932      }
933      if (bg) {
934        bg.style.display = 'block';
935        ensureBg3dFallback(bg);
936      }
937      initStaticMessage();
938      startTimer();
939      try {
940        if (window.__PP_FORCE_DISABLE_LOADER_WEBGL === true) return;
941        if (window.__PP_DISABLE_LOADER_WEBGL === true) return;
942      } catch (_) {}
943      // Lazy Three.js: yalnızca loader görünürken context aç
944      if (typeof window.ensureLoaderTerrainBg === 'function') {
945        try { window.ensureLoaderTerrainBg(); } catch (_) {}
946      }
947      if (typeof window.ensureForestHouse === 'function') {
948        try { window.ensureForestHouse(); } catch(_) {}
949      }
950      if (bg) {
951        try {
952          if (bg.querySelector && bg.querySelector('canvas')) {
953            bg.classList.remove('pp-bg3d--fallback');
954          }
955        } catch (_) {}
956      }
957    },
958    hide: function() {
959      var overlay = document.getElementById('pp-loader-overlay');
960      var bg = document.getElementById('pp-loader-bg3d');
961      if (__ppTimerInterval) { clearInterval(__ppTimerInterval); __ppTimerInterval = null; }
962      if (__ppHideTimeout) { clearTimeout(__ppHideTimeout); __ppHideTimeout = null; }
963      // Mapbox ile carpismayi bitir: fade sirasinda WebGL context'leri serbest birak
964      disposeLoaderWebGLScenes();
965      if (overlay) {
966        overlay.classList.add('pp-loader-hidden');
967        __ppHideTimeout = setTimeout(function() {
968          __ppHideTimeout = null;
969          if (overlay && overlay.classList.contains('pp-loader-hidden')) {
970            overlay.style.display = 'none';
971          }
972          if (bg && !window.ProParcelLoader.isVisible()) bg.style.display = 'none';
973          softRecoverIndexMap();
974        }, 600);
975      } else {
976        if (bg) bg.style.display = 'none';
977        softRecoverIndexMap();
978      }
979    },
980    isVisible: function() {
981      var overlay = document.getElementById('pp-loader-overlay');
982      return overlay && overlay.style.display !== 'none' && !overlay.classList.contains('pp-loader-hidden');
983    }
984  };
985
986  var shouldAutoShow = true;
987  try {
988    shouldAutoShow = window.__ppLoaderAutoShow !== false;
989  } catch (_) {}
990  if (shouldAutoShow) {
991    if (document.readyState === 'loading') {
992      document.addEventListener('DOMContentLoaded', function() {
993        window.ProParcelLoader.show();
994      });
995    } else {
996      window.ProParcelLoader.show();
997    }
998  } else {
999    var _ov = document.getElementById('pp-loader-overlay');
1000    var _bg = document.getElementById('pp-loader-bg3d');
1001    if (_ov) { _ov.classList.add('pp-loader-hidden'); _ov.style.display = 'none'; }
1002    if (_bg) _bg.style.display = 'none';
1003  }
1004
1005  window.addEventListener('message', function(ev) {
1006    try {
1007      var data = ev.data || {};
1008      if (data.type === 'PP_REPORT_V3_PROGRESS') {
1009        var logs = Array.isArray(data.valuationProgress) ? data.valuationProgress : [];
1010        if (logs.length > 0) {
1011          var lastLog = logs[logs.length - 1];
1012          var msg = lastLog.message || lastLog.step || '';
1013          if (msg) {
1014            var titleEl = document.getElementById('pp-loader-active-title');
1015            var subtitleEl = document.getElementById('pp-loader-subtitle');
1016            if (titleEl) {
1017              titleEl.classList.add('fadeOut');
1018              setTimeout(function() {
1019                titleEl.textContent = msg;
1020                titleEl.classList.remove('fadeOut');
1021              }, 220);
1022            }
1023            if (subtitleEl) subtitleEl.textContent = msg;
1024          }
1025        }
1026      }
1027    } catch(_) {}
1028  });
1029})();
1030</script>
1030
1031
1032
1033<!-- Three.js 3D terrain arka plan -->
1034<script type="module">
1035  import * as THREE from 'https://esm.sh/[email protected]';
1036  import { ImprovedNoise } from 'https://esm.sh/[email protected]/examples/jsm/math/ImprovedNoise.js';
1037
1038  let camera, scene, renderer, mesh;
1039  const worldWidth = 256, worldDepth = 256;
1040  const clock = new THREE.Clock();
1041
1042  const _terrainGlOpts = { failIfMajorPerformanceCaveat: false };
1043
1044  function shouldSkipLoaderWebGL() {
1045    try {
1046      if (window.__PP_FORCE_DISABLE_LOADER_WEBGL === true) return true;
1047      if (window.__PP_DISABLE_LOADER_WEBGL === true) return true;
1048    } catch (_) {}
1049    try {
1050      if (window.PPWebGLCompat && typeof window.PPWebGLCompat.supports === 'function' && !window.PPWebGLCompat.supports('heavy_animation')) {
1051        return true;
1052      }
1053    } catch (_) {}
1054    try {
1055      if (window.__PP_GPU_MODE === 'no_gpu') return true;
1056    } catch (_) {}
1057    try {
1058      const canvas = document.createElement('canvas');
1059      const gl = canvas.getContext('webgl', _terrainGlOpts) || canvas.getContext('experimental-webgl', _terrainGlOpts);
1060      if (!gl) return true;
1061      try { gl.getExtension('WEBGL_lose_context')?.loseContext?.(); } catch (_) {}
1062      return false;
1063    } catch (_) {
1064      return true;
1065    }
1066  }
1067
1068  function disposeTerrainBg3D() {
1069    window.removeEventListener('resize', onWindowResize3D);
1070    if (renderer) {
1071      try { renderer.setAnimationLoop(null); } catch (_) {}
1072      try {
1073        var el = renderer.domElement;
1074        if (el && el.parentNode) el.parentNode.removeChild(el);
1075      } catch (_) {}
1076      try { renderer.dispose(); } catch (_) {}
1077      try { renderer.forceContextLoss(); } catch (_) {}
1078    }
1079    renderer = null;
1080    if (mesh) {
1081      try {
1082        if (mesh.geometry) mesh.geometry.dispose();
1083        if (mesh.material) {
1084          if (mesh.material.map) mesh.material.map.dispose();
1085          mesh.material.dispose();
1086        }
1087      } catch (_) {}
1088      mesh = null;
1089    }
1090    scene = null;
1091    camera = null;
1092  }
1093
1094  function createTerrainWebGLRenderer() {
1095    if (shouldSkipLoaderWebGL()) return null;
1096    try {
1097      return new THREE.WebGLRenderer({ antialias: true, ..._terrainGlOpts });
1098    } catch (_) {
1099      try {
1100        return new THREE.WebGLRenderer({ antialias: false, ..._terrainGlOpts });
1101      } catch (_) {
1102        return null;
1103      }
1104    }
1105  }
1106
1107  // Sayfa acilisinda WebGL acma — Mapbox ile carpismasin. show() → ensureLoaderTerrainBg.
1108  window.ensureLoaderTerrainBg = function ensureLoaderTerrainBg() {
1109    const container = document.getElementById('pp-loader-bg3d');
1110    if (!container) return;
1111    if (shouldSkipLoaderWebGL()) {
1112      container.classList.add('pp-bg3d--fallback');
1113      return;
1114    }
1115    if (renderer) return;
1116    init3D();
1117  };
1118
1119  window.disposeLoaderTerrainBg = function disposeLoaderTerrainBg() {
1120    disposeTerrainBg3D();
1121    const container = document.getElementById('pp-loader-bg3d');
1122    if (container) {
1123      try {
1124        while (container.firstChild) container.removeChild(container.firstChild);
1125      } catch (_) {}
1126      container.classList.add('pp-bg3d--fallback');
1127    }
1128  };
1129
1130  function init3D() {
1131    const container = document.getElementById('pp-loader-bg3d');
1132    if (!container) return;
1133
1134    camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000);
1135
1136    scene = new THREE.Scene();
1137    scene.background = new THREE.Color(0x041026);
1138    scene.fog = new THREE.FogExp2(0x041026, 0.0014);
1139
1140    const data = generateHeight(worldWidth, worldDepth);
1141
1142    const geometry = new THREE.PlaneGeometry(8000, 8000, worldWidth - 1, worldDepth - 1);
1143    geometry.rotateX(-Math.PI / 2);
1144
1145    const vertices = geometry.attributes.position.array;
1146    for (let i = 0, j = 0, l = vertices.length; i < l; i++, j += 3) {
1147      vertices[j + 1] = data[i] * 12;
1148    }
1149
1150    const texture = new THREE.CanvasTexture(generateTexture(data, worldWidth, worldDepth));
1151    texture.wrapS = THREE.ClampToEdgeWrapping;
1152    texture.wrapT = THREE.ClampToEdgeWrapping;
1153    texture.colorSpace = THREE.SRGBColorSpace;
1154
1155    const material = new THREE.MeshBasicMaterial({ map: texture });
1156    mesh = new THREE.Mesh(geometry, material);
1157    scene.add(mesh);
1158
1159    camera.position.set(900, 900, 900);
1160    camera.lookAt(0, 0, 0);
1161
1162    renderer = createTerrainWebGLRenderer();
1163    if (!renderer) {
1164      disposeTerrainBg3D();
1165      container.classList.add('pp-bg3d--fallback');
1166      try { console.warn('[ProParcelLoader] 3D arka plan WebGL başlatılamadı (sabit gradient kullanılıyor).'); } catch (_) {}
1167      return;
1168    }
1169
1170    renderer.setPixelRatio(window.devicePixelRatio);
1171    renderer.setSize(window.innerWidth, window.innerHeight);
1172    renderer.setAnimationLoop(animate3D);
1173
1174    container.appendChild(renderer.domElement);
1175    container.classList.remove('pp-bg3d--fallback');
1176
1177    window.addEventListener('resize', onWindowResize3D);
1178  }
1179
1180  function onWindowResize3D() {
1181    if (!camera || !renderer) return;
1182    camera.aspect = window.innerWidth / window.innerHeight;
1183    camera.updateProjectionMatrix();
1184    renderer.setSize(window.innerWidth, window.innerHeight);
1185  }
1186
1187  function generateHeight(width, height) {
1188    let seed = Math.PI / 4;
1189    const rand = () => {
1190      const x = Math.sin(seed++) * 10000;
1191      return x - Math.floor(x);
1192    };
1193
1194    const size = width * height;
1195    const data = new Uint8Array(size);
1196    const perlin = new ImprovedNoise();
1197    const z = rand() * 100;
1198    let quality = 1;
1199
1200    for (let j = 0; j < 4; j++) {
1201      for (let i = 0; i < size; i++) {
1202        const x = i % width, y = ~~(i / width);
1203        data[i] += Math.abs(perlin.noise(x / quality, y / quality, z) * quality * 1.75);
1204      }
1205      quality *= 4.5;
1206    }
1207    return data;
1208  }
1209
1210  function generateTexture(data, width, height) {
1211    let context, image, imageData;
1212
1213    const vector3 = new THREE.Vector3(0, 0, 0);
1214    const sun = new THREE.Vector3(1, 1, 1).normalize();
1215
1216    const canvas = document.createElement('canvas');
1217    canvas.width = width;
1218    canvas.height = height;
1219
1220    context = canvas.getContext('2d');
1221    context.fillStyle = '#000';
1222    context.fillRect(0, 0, width, height);
1223
1224    image = context.getImageData(0, 0, canvas.width, canvas.height);
1225    imageData = image.data;
1226
1227    for (let i = 0, j = 0, l = imageData.length; i < l; i += 4, j++) {
1228      const left = data[j - 1] || data[j];
1229      const right = data[j + 1] || data[j];
1230      const down = data[j + width] || data[j];
1231      const up = data[j - width] || data[j];
1232
1233      const v3 = vector3;
1234      v3.x = left - right;
1235      v3.y = 16;
1236      v3.z = up - down;
1237      v3.normalize();
1238
1239      const shade = v3.dot(sun);
1240      const h = data[j];
1241
1242      const heightFactor = 0.65 + h * 0.006;
1243
1244      let r = (18 + shade * 50) * heightFactor;
1245      let g = (110 + shade * 150) * heightFactor;
1246      let b = (170 + shade * 190) * heightFactor;
1247
1248      r = Math.max(0, Math.min(255, r));
1249      g = Math.max(0, Math.min(255, g));
1250      b = Math.max(0, Math.min(255, b));
1251
1252      imageData[i]     = r;
1253      imageData[i + 1] = g;
1254      imageData[i + 2] = b;
1255    }
1256
1257    context.putImageData(image, 0, 0);
1258
1259    const canvasScaled = document.createElement('canvas');
1260    canvasScaled.width = width * 4;
1261    canvasScaled.height = height * 4;
1262    context = canvasScaled.getContext('2d');
1263    context.scale(4, 4);
1264    context.drawImage(canvas, 0, 0);
1265
1266    image = context.getImageData(0, 0, canvasScaled.width, canvasScaled.height);
1267    imageData = image.data;
1268
1269    for (let i = 0, l = imageData.length; i < l; i += 4) {
1270      const v = ~~(Math.random() * 6);
1271      imageData[i]     += v;
1272      imageData[i + 1] += v;
1273      imageData[i + 2] += v;
1274    }
1275
1276    context.putImageData(image, 0, 0);
1277    return canvasScaled;
1278  }
1279
1280  function animate3D() {
1281    if (!camera || !renderer) return;
1282    const t = clock.getElapsedTime();
1283
1284    const radius = 900;
1285    const y = 650 + Math.sin(t * 0.3) * 80;
1286
1287    camera.position.x = Math.cos(t * 0.12) * radius;
1288    camera.position.z = Math.sin(t * 0.12) * radius;
1289    camera.position.y = y;
1290    camera.lookAt(0, 120, 0);
1291
1292    renderer.render(scene, camera);
1293  }
1294</script>
1294
1295
1296<!-- Forest House mini sahnesi: Ortadaki kutu içindeki canvas -->
1297<script type="module">
1298  import * as THREE from 'https://esm.sh/[email protected]';
1299  import { OrbitControls } from 'https://esm.sh/[email protected]/examples/jsm/controls/OrbitControls.js';
1300  import { GLTFLoader } from 'https://esm.sh/[email protected]/examples/jsm/loaders/GLTFLoader.js';
1301  import { DRACOLoader } from 'https://esm.sh/[email protected]/examples/jsm/loaders/DRACOLoader.js';
1302
1303  let cameraFH, sceneFH, rendererFH, houseRoot, controlsFH;
1304  let forestHouseInitialized = false;
1305  let forestHouseAnimating = false;
1306  let forestHouseDisabled = false;
1307
1308  function shouldSkipForestHouseWebGL() {
1309    try {
1310      if (window.__PP_FORCE_DISABLE_LOADER_WEBGL === true) return true;
1311      if (window.__PP_DISABLE_LOADER_WEBGL === true) return true;
1312    } catch (_) {}
1313    try {
1314      if (window.PPWebGLCompat && typeof window.PPWebGLCompat.supports === 'function' && !window.PPWebGLCompat.supports('heavy_animation')) {
1315        return true;
1316      }
1317    } catch (_) {}
1318    try {
1319      if (window.__PP_GPU_MODE === 'no_gpu') return true;
1320    } catch (_) {}
1321    try {
1322      const canvas = document.createElement('canvas');
1323      const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
1324      if (!gl) return true;
1325      try { gl.getExtension('WEBGL_lose_context')?.loseContext?.(); } catch (_) {}
1326      return false;
1327    } catch (_) {
1328      return true;
1329    }
1330  }
1331
1332  window.ensureForestHouse = function ensureForestHouse() {
1333    if (shouldSkipForestHouseWebGL()) {
1334      forestHouseDisabled = true;
1335      return;
1336    }
1337    forestHouseDisabled = false;
1338    if (forestHouseInitialized && rendererFH && sceneFH && cameraFH) {
1339      if (!forestHouseAnimating) {
1340        forestHouseAnimating = true;
1341        animateForestHouse();
1342      }
1343      return;
1344    }
1345    const ok = initForestHouse();
1346    if (!ok) return;
1347    forestHouseInitialized = true;
1348    if (!forestHouseAnimating) {
1349      forestHouseAnimating = true;
1350      animateForestHouse();
1351    }
1352  };
1353
1354  function getFreshForestHouseCanvas() {
1355    const canvas = document.getElementById('pp-inner-canvas');
1356    if (!canvas) return null;
1357
1358    // Replace the node so Three always receives a fresh canvas after any prior context usage.
1359    const replacement = canvas.cloneNode(false);
1360    replacement.width = canvas.width;
1361    replacement.height = canvas.height;
1362    canvas.replaceWith(replacement);
1363    return replacement;
1364  }
1365
1366  function disposeForestHouse() {
1367    forestHouseAnimating = false;
1368    window.removeEventListener('resize', onForestHouseResize);
1369    if (controlsFH && typeof controlsFH.dispose === 'function') {
1370      try { controlsFH.dispose(); } catch (_) {}
1371    }
1372    controlsFH = null;
1373    if (rendererFH) {
1374      try { rendererFH.dispose(); } catch (_) {}
1375      try { rendererFH.forceContextLoss(); } catch (_) {}
1376    }
1377    rendererFH = null;
1378    cameraFH = null;
1379    sceneFH = null;
1380    houseRoot = null;
1381    forestHouseInitialized = false;
1382  }
1383
1384  window.disposeForestHouse = disposeForestHouse;
1385
1386  function initForestHouse() {
1387    if (shouldSkipForestHouseWebGL()) {
1388      forestHouseDisabled = true;
1389      return false;
1390    }
1391    const canvas = getFreshForestHouseCanvas();
1392    if (!canvas) return false;
1393    disposeForestHouse();
1394
1395    const rect = canvas.getBoundingClientRect();
1396    const width = Math.max(1, Math.round(rect.width || canvas.clientWidth || 320));
1397    const height = Math.max(1, Math.round(rect.height || canvas.clientHeight || 160));
1398    const aspect = width / height;
1399
1400    cameraFH = new THREE.PerspectiveCamera(45, aspect, 0.1, 100);
1401    cameraFH.position.set(1.5, 4, 9);
1402
1403    sceneFH = new THREE.Scene();
1404    sceneFH.background = null;
1405
1406    const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 1.2);
1407    hemiLight.position.set(0, 20, 0);
1408    sceneFH.add(hemiLight);
1409
1410    const dirLight = new THREE.DirectionalLight(0xffffff, 1);
1411    dirLight.position.set(5, 10, 7.5);
1412    sceneFH.add(dirLight);
1413
1414    const dracoLoader = new DRACOLoader();
1415    dracoLoader.setDecoderPath('https://threejs.org/examples/jsm/libs/draco/gltf/');
1416
1417    const loader = new GLTFLoader();
1418    loader.setDRACOLoader(dracoLoader);
1419    loader.setPath('https://threejs.org/examples/models/gltf/AVIFTest/');
1420    loader.load(
1421      'forest_house.glb',
1422      function (gltf) {
1423        houseRoot = gltf.scene;
1424        sceneFH.add(houseRoot);
1425      },
1426      undefined,
1427      function () {
1428        createFallbackHouse();
1429      }
1430    );
1431
1432    try {
1433      rendererFH = new THREE.WebGLRenderer({
1434        canvas: canvas,
1435        antialias: true,
1436        alpha: true,
1437        failIfMajorPerformanceCaveat: false,
1438      });
1439    } catch (error) {
1440      disposeForestHouse();
1441      forestHouseDisabled = true;
1442      try {
1443        console.warn('[ProParcelLoader] Forest house WebGL init skipped:', error);
1444      } catch (_) {}
1445      return false;
1446    }
1447    rendererFH.setPixelRatio(window.devicePixelRatio);
1448    rendererFH.setSize(width, height, false);
1449
1450    controlsFH = new OrbitControls(cameraFH, canvas);
1451    controlsFH.addEventListener('change', renderForestHouse);
1452    controlsFH.target.set(0, 2, 0);
1453    controlsFH.update();
1454
1455    window.addEventListener('resize', onForestHouseResize);
1456    return true;
1457  }
1458
1459  function createFallbackHouse() {
1460    if (!sceneFH || houseRoot) return;
1461    const group = new THREE.Group();
1462
1463    const body = new THREE.Mesh(
1464      new THREE.BoxGeometry(2.8, 1.6, 2.2),
1465      new THREE.MeshStandardMaterial({ color: 0xe5e7eb, roughness: 0.7, metalness: 0.1 })
1466    );
1467    body.position.y = 1.0;
1468    group.add(body);
1469
1470    const roof = new THREE.Mesh(
1471      new THREE.ConeGeometry(2.1, 1.1, 4),
1472      new THREE.MeshStandardMaterial({ color: 0x2563eb, roughness: 0.55, metalness: 0.05 })
1473    );
1474    roof.rotation.y = Math.PI / 4;
1475    roof.position.y = 2.35;
1476    group.add(roof);
1477
1478    const door = new THREE.Mesh(
1479      new THREE.BoxGeometry(0.45, 0.95, 0.06),
1480      new THREE.MeshStandardMaterial({ color: 0x334155 })
1481    );
1482    door.position.set(0, 0.55, 1.13);
1483    group.add(door);
1484
1485    houseRoot = group;
1486    sceneFH.add(houseRoot);
1487  }
1488
1489  function onForestHouseResize() {
1490    const canvas = document.getElementById('pp-inner-canvas');
1491    if (!canvas || !cameraFH || !rendererFH) return;
1492
1493    const rect = canvas.getBoundingClientRect();
1494    const aspect = rect.width / (rect.height || 1);
1495
1496    cameraFH.aspect = aspect;
1497    cameraFH.updateProjectionMatrix();
1498
1499    rendererFH.setSize(rect.width, rect.height, false);
1500    renderForestHouse();
1501  }
1502
1503  function renderForestHouse() {
1504    if (!rendererFH || !sceneFH || !cameraFH) return;
1505    rendererFH.render(sceneFH, cameraFH);
1506  }
1507
1508  function animateForestHouse() {
1509    if (!forestHouseAnimating) return;
1510    requestAnimationFrame(animateForestHouse);
1511    if (houseRoot) {
1512      houseRoot.rotation.y += 0.005;
1513    }
1514    renderForestHouse();
1515  }
1516</script>
1516
1517
1518
1519
1520  <!-- TKGM: Parsel Bulunamadı banner -->
1521  <div id="pp-tkgm-parcel-not-found-banner" role="status" aria-live="polite">Parsel Bulunamadı</div>
1522  
1523  <!-- APP HEADER -->
1524  <header class="pp-header">
1525    <!-- TOPBAR - Merkezi partial'dan yükleniyor -->
1526    
1527
1528
1529<style>
1530  /* Merkezi dropdown radius yönetimi (index dahil tüm sayfalar). */
1531  :root {
1532    --pp-dropdown-radius: 0px;
1533  }
1534
1535  #main-topbar .topbar-dropdown > .dropdown-menu,
1536  #main-topbar #main-menu-dropdown > .dropdown-menu,
1537  #main-topbar #user-menu-dropdown > .dropdown-menu,
1538  #main-topbar #user-menu-dropdown > .dropdown-menu.user-dropdown-menu,
1539  #main-topbar #notifications-dropdown > .dropdown-menu,
1540  #main-topbar #notifications-dropdown > .notifications-dropdown-menu,
1541  [data-role="param-menu"],
1542  [data-role="param-view-menu"],
1543  [data-role="param-roads-menu"],
1544  [data-role="param-list"],
1545  .select2-dropdown {
1546    border-radius: var(--pp-dropdown-radius) !important;
1547  }
1548
1549  #main-topbar .sidebar-toggle-btn,
1550  #main-topbar .topbar-right-actions .credit-badge,
1551  #main-topbar .topbar-right-actions .notifications-btn,
1552  #main-topbar .topbar-right-actions .user-menu-btn,
1553  #main-topbar .topbar-right-actions .right-info-toggle-topbar-btn,
1554  #main-topbar .topbar-right-actions .portal-topbar-btn,
1555  #main-topbar .topbar-vitrin-btn,
1556  #main-topbar .topbar-right-group .notifications-btn,
1557  #main-topbar .topbar-right-group .user-menu-btn,
1558  #main-topbar #main-menu-dropdown .dropdown-menu > .toggle-btn,
1559  #main-topbar #main-menu-dropdown .dropdown-menu > a.toggle-btn,
1560  #main-topbar #main-menu-dropdown .dropdown-menu > .pp-collapsible-wrap > .toggle-btn,
1561  #main-topbar #user-menu-dropdown .dropdown-menu > .toggle-btn,
1562  #main-topbar #user-menu-dropdown .dropdown-menu > a.toggle-btn,
1563  #main-topbar #user-menu-dropdown .dropdown-menu > .pp-collapsible-wrap > .toggle-btn,
1564  #main-topbar #user-menu-dropdown .dropdown-menu .user-menu-item,
1565  #main-topbar #notifications-dropdown .mark-all-read-btn,
1566  #main-topbar .topbar-dropdown #myQueriesList .query-del {
1567    border-radius: var(--pp-dropdown-radius) !important;
1568  }
1569</style>
1570
1571<!-- TOPBAR -->
1572<nav id="main-topbar" class="pp-topbar tkgm-topbar" role="banner" aria-label="Ana navigasyon">
1573  
1574  <!-- Sol: Hamburger Menü + ProParcel -->
1575  <div class="topbar-dropdown" id="main-menu-dropdown">
1576    <button id="main-menu-toggle" class="sidebar-toggle-btn" aria-label="Ana menü" aria-expanded="false">
1577      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" aria-hidden="true">
1578        <rect x="3" y="6" width="18" height="2" rx="1" fill="#fff" />
1579        <rect x="3" y="11" width="18" height="2" rx="1" fill="#fff" />
1580        <rect x="3" y="16" width="18" height="2" rx="1" fill="#fff" />
1581      </svg>
1582    </button>
1583    <div class="dropdown-menu">
1584      <a href="/?skip_landing_intro=1" class="toggle-btn" title="Tanıtım Sayfası" style="text-decoration:none;">
1585        <i class="fa fa-home"></i>
1586        <span>Tanıtım Sayfası</span>
1587      </a>
1588      
1589      <button id="dropdown-parsel-sorgu-btn" class="toggle-btn active" onclick="if(typeof toggleSidebar==='function')toggleSidebar();" title="Parsel Sorgu">
1590        <i class="fa fa-search"></i>
1591        <span>Parsel Sorgu</span>
1592      </button>
1593      
1594      <a href="/portal/ilan/vitrin/" id="pp-emlak-vitrini-hamburger-link" class="toggle-btn" title="Emlak Vitrini" style="text-decoration:none;">
1595        <i class="fas fa-th-large"></i>
1596        <span>Emlak Vitrini</span>
1597      </a>
1598      <a href="/accounts/emlak-danismanlari/" class="toggle-btn" title="Emlak Danışmanları" style="text-decoration:none;">
1599        <i class="fas fa-user-tie"></i>
1600        <span>Emlak Danışmanları</span>
1601      </a>
1602      <a href="/portal/recent-queries/?ref=recent90" class="toggle-btn" title="Son 90 Gün Pro Sorgular" style="text-decoration:none;">
1603        <i class="fas fa-calendar-alt"></i>
1604        <span>Son 90 Gün Pro Sorgular</span>
1605      </a>
1606      
1607      <div class="user-menu-divider"></div>
1608      <a href="/destek/" class="toggle-btn" id="mainMenuSupportLink" title="Destek" style="text-decoration:none;">
1609        <i class="fas fa-life-ring"></i>
1610        <span>Destek</span>
1611      </a>
1612      <a href="/proje-olustur/" class="toggle-btn" id="mainMenuHowToLink" title="Nasıl Yapılır" style="text-decoration:none;">
1613        <i class="fas fa-circle-play"></i>
1614        <span>Nasıl Yapılır</span>
1615      </a>
1616    </div>
1617  </div>
1618  
1619  
1620  
1621  <!-- Marka İsmi -->
1622  <a href="/?skip_landing_intro=1" class="topbar-brand-text">ProParcel</a>
1623  
1624  
1625  <!-- Esnek Boşluk -->
1626  <div style="flex: 1;"></div>
1627  
1628  
1629  
1630  <!-- Sağ taraf butonları - tutarlı gap ile -->
1631  <div class="topbar-right-actions">
1632    
1633    <!-- Son 90 Gün Pro Sorgular -->
1634    <a id="pp-son-30-gun-btn" href="/portal/recent-queries/?ref=recent90" class="right-info-toggle-topbar-btn" title="Son 90 Gün Pro Sorgular" style="text-decoration:none;">
1635      <i class="fas fa-calendar-alt"></i>
1636      <span>Son 90 Gün Pro Sorgular</span>
1637    </a>
1638    <!-- Emlak Vitrini -->
1639    <a href="/portal/ilan/vitrin/" id="pp-emlak-vitrini-topbar-btn" class="right-info-toggle-topbar-btn" title="Emlak Vitrini" style="text-decoration:none;">
1640      <i class="fas fa-store"></i>
1641      <span>Emlak Vitrini</span>
1642    </a>
1643    <a href="/mahalle-bilgileri/" class="right-info-toggle-topbar-btn" title="ProMahalle" style="text-decoration:none;">
1644      <i class="fas fa-map-marker-alt"></i>
1645      <span>ProMahalle</span>
1646    </a>
1647    
1648    
1649    <!-- VIP badge (VIP kullanıcılar için) -->
1650    <span class="vip-topbar-badge" id="vipTopbarBadge" title="VIP Üye" style="display: none;">
1651      <i class="fas fa-crown"></i>
1652      <span>VIP</span>
1653    </span>
1654    
1655    
1656
1657    
1658    <!-- Kredi bakiyesi badge'i (giriş yapmış kullanıcılar için) -->
1659    <a href="/accounts/pricing/" class="credit-badge" id="creditBadge" title="Tepe Kredi Bakiyeniz" style="display: none;">
1660      <i class="fas fa-coins"></i>
1661      <span id="userCreditBalance">0</span>
1662      <span class="credit-label">TK</span>
1663    </a>
1664    
1665    
1666    
1667    <!-- Kullanıcı Menüsü (bildirimler + avatar) -->
1668    
1669
1670
1671<!-- Bildirimler (giriş yapılmışsa) -->
1672<div class="topbar-dropdown auth-only" id="notifications-dropdown" style="display: none;">
1673  <button id="notificationsBtn" class="notifications-btn" aria-label="Bildirimler" aria-expanded="false" title="Bildirimler">
1674    <i class="fas fa-bell"></i>
1675    <span id="notificationsBadge" class="notifications-badge" style="display: none;">0</span>
1676  </button>
1677  <div class="dropdown-menu notifications-dropdown-menu" id="notificationsMenu">
1678    <div class="notifications-header">
1679      <div class="notifications-header-main">
1680        <span class="notifications-title">Bildirimler</span>
1681        <button id="markAllReadBtn" class="mark-all-read-btn" title="Tümünü okundu işaretle">
1682          <i class="fas fa-check-double"></i>
1683        </button>
1684      </div>
1685      <div class="notifications-actions">
1686        <button id="notificationsSelectAllBtn" class="notifications-action-btn" type="button">Tümünü Seç</button>
1687        <button id="notificationsDeleteSelectedBtn" class="notifications-action-btn notifications-action-btn--danger" type="button" disabled>Seçileni Sil</button>
1688      </div>
1689    </div>
1690    <div class="notifications-list" id="notificationsList">
1691      <div class="notifications-empty">
1692        <i class="fas fa-bell-slash"></i>
1693        <span>Bildirim bulunmuyor</span>
1694      </div>
1695    </div>
1696    <div class="notifications-footer">
1697      <a href="/accounts/notifications/" id="viewAllNotificationsLink">Tüm Bildirimleri Gör</a>
1698    </div>
1699  </div>
1700</div>
1701
1702<!-- Kullanıcı Menüsü -->
1703<div class="topbar-dropdown" id="user-menu-dropdown">
1704  <button id="userMenuBtn" class="user-menu-btn" aria-label="Kullanıcı menüsü" aria-expanded="false">
1705    
1706    <i class="fas fa-user-circle"></i>
1707    
1708  </button>
1709  <div class="dropdown-menu">
1710    <!-- Kullanıcı bilgisi (giriş yapılmışsa) -->
1711    <div class="user-menu-header" id="userMenuHeader" style="display: none;">
1712      <img src="" alt="" class="user-menu-avatar" id="userMenuAvatar" width="48" height="48" decoding="async" style="display: none;">
1713      <div class="user-menu-avatar-placeholder" id="userMenuAvatarPlaceholder" style="display: none;">
1714        <i class="fas fa-user"></i>
1715      </div>
1716      <div class="user-menu-info">
1717        <span class="user-menu-name" id="userMenuName">Kullanıcı</span>
1718        <span class="vip-menu-badge" id="vipMenuBadge" style="display: none;">
1719          <i class="fas fa-crown"></i> VIP
1720        </span>
1721        <span class="user-menu-email" id="userMenuEmail">[email protected]</span>
1722      </div>
1723    </div>
1724    <div class="user-menu-divider" id="userMenuDivider" style="display: none;"></div>
1725
1726    <!-- Giriş yapılmamışsa -->
1727    <a href="/accounts/login/" class="toggle-btn" id="menuLoginLink">
1728      <i class="fas fa-sign-in-alt"></i>
1729      <span>Giriş Yap</span>
1730    </a>
1731
1732    <!-- 1. Profil -->
1733    <a href="/accounts/profile/" class="toggle-btn auth-only" id="menuProfileLink" style="display: none;">
1734      <i class="fas fa-user"></i>
1735      <span>Profil</span>
1736    </a>
1737
1738    <!-- Bina Çiz → /bina-ciz/ (parsel kontrolü yok; boş sayfa açılır) -->
1739    <a href="/bina-ciz/" class="toggle-btn" id="menuBinaCizLink" title="Bina Çiz" style="text-decoration:none;">
1740      <i class="fas fa-building"></i>
1741      <span>Bina Çiz</span>
1742    </a>
1743
1744    <!-- Admin -->
1745    <a href="/accounts/admin/" class="toggle-btn admin-only" id="menuAdminLink" style="display: none;">
1746      <i class="fas fa-shield-alt"></i>
1747      <span>Admin Panel</span>
1748    </a>
1749
1750    <!-- 2. Emlak Vitrini -->
1751    <a href="/portal/ilan/vitrin/" class="toggle-btn auth-only" id="menuEmlakVitriniLink" title="Emlak Vitrini" style="display: none; text-decoration:none;">
1752      <i class="fas fa-store"></i>
1753      <span>Emlak Vitrini</span>
1754    </a>
1755
1756    <!-- 3. İlan İşlemleri -->
1757    <div data-pp-collapsible="user-ilan-islemleri" class="pp-collapsible-wrap auth-only" id="menuIlanIslemleriWrap" style="display: none;">
1758      <button type="button" id="menuIlanIslemleriBtn" data-pp-collapsible-toggle="user-ilan-islemleri" class="toggle-btn pp-collapsible-toggle" title="İlan İşlemleri" aria-expanded="false" aria-controls="user-ilan-islemleri-content">
1759        <i class="fas fa-briefcase"></i>
1760        <span>İlan İşlemleri</span>
1761        <i class="fa fa-chevron-down pp-collapsible-chevron" aria-hidden="true"></i>
1762      </button>
1763      <div id="user-ilan-islemleri-content" data-pp-collapsible-content="user-ilan-islemleri" class="pp-collapsible-content" role="region" aria-label="İlan İşlemleri alt menü">
1764        <a href="/portal/ilan/olustur/" class="pp-collapsible-item" id="menuIlanOlusturLink" title="İlan ver" style="text-decoration:none;">
1765          <i class="fas fa-plus-circle"></i>
1766          <span>İlan ver</span>
1767        </a>
1768        <a href="/portal/ilan/ilanlarim/" class="pp-collapsible-item" id="menuIlanlarimLink" title="İlanlarım" style="text-decoration:none;">
1769          <i class="fas fa-list"></i>
1770          <span>İlanlarım</span>
1771        </a>
1772      </div>
1773    </div>
1774
1775    <!-- 4. Son 90 Gün Pro Sorguları -->
1776    <a href="/portal/recent-queries/?ref=recent90" class="toggle-btn auth-only" id="menuSon30GunProLink" title="Son 90 Gün Pro Sorguları" style="display: none; text-decoration:none;">
1777      <i class="fas fa-calendar-alt"></i>
1778      <span>Son 90 Gün Pro Sorguları</span>
1779    </a>
1780
1781    <!-- 5. Basit -->
1782    <button type="button" class="toggle-btn auth-only" id="menuBasitSorguLink" title="Basit sorgu modu" style="display: none;">
1783      <i class="fas fa-map"></i>
1784      <span>Basit</span>
1785    </button>
1786
1787    <!-- 6. Sorgularım -->
1788    <button type="button" class="toggle-btn auth-only" id="menuMyQueriesLink" title="Kayıtlı sorgularım" style="display: none;">
1789      <i class="fa fa-history"></i>
1790      <span>Sorgularım</span>
1791    </button>
1792
1793    <!-- 7. ProMahalle -->
1794    <a href="/mahalle-bilgileri/" class="toggle-btn auth-only" id="menuProMahalleLink" title="ProMahalle" style="display: none; text-decoration:none;">
1795      <i class="fas fa-comments"></i>
1796      <span>ProMahalle</span>
1797    </a>
1798
1799    <!-- 8. AI İşlemleri -->
1800    <div data-pp-collapsible="user-ai-video" class="pp-collapsible-wrap auth-only" id="menuAiVideoWrap" style="display: none;">
1801      <button type="button" id="menuAiVideoBtn" data-pp-collapsible-toggle="user-ai-video" class="toggle-btn pp-collapsible-toggle" title="AI İşlemleri" aria-expanded="false" aria-controls="user-ai-vi
1801deo-content">
1802        <i class="fas fa-magic"></i>
1803        <span>AI İşlemleri</span>
1804        <i class="fa fa-chevron-down pp-collapsible-chevron" aria-hidden="true"></i>
1805      </button>
1806      <div id="user-ai-video-content" data-pp-collapsible-content="user-ai-video" class="pp-collapsible-content" role="region" aria-label="AI İşlemleri alt menü" hidden>
1807        <a href="/portal/ai-video-olusturucu/" class="pp-collapsible-item" id="menuAiVideoStudioLink" title="AI Video" style="text-decoration:none;">
1808          <i class="fas fa-film"></i>
1809          <span>AI Video</span>
1810        </a>
1811        <a href="/portal/ai-drone/" class="pp-collapsible-item" id="menuAiDroneVideoLink" title="AI Drone Video" style="text-decoration:none;" onclick="this.href='/portal/ai-drone/?v=' + Date.now();">
1812          <i class="fas fa-helicopter"></i>
1813          <span>AI Drone Video</span>
1814        </a>
1815      </div>
1816    </div>
1817
1818    <!-- 9. Sosyal Medya Postu -->
1819    <a href="/portal/ilan/sosyal-medya-sablonu/?source=menu" class="toggle-btn auth-only" id="menuSocialMediaTemplateLink" title="Sosyal Medya Postu" style="display: none; text-decoration:none;">
1820      <i class="fas fa-share-alt"></i>
1821      <span>Sosyal Medya Postu</span>
1822    </a>
1823
1824    <!-- 10. Emsal Bildir -->
1825    <a href="/accounts/emsal-sales-report/" class="toggle-btn auth-only emsal-only" id="menuEmsalSalesReportLink" style="display: none;">
1826      <i class="fas fa-bullhorn"></i>
1827      <span>Emsal Bildir</span>
1828    </a>
1829
1830    <!-- 11. Aranacaklar -->
1831    <a href="/portal/aranacaklar/" class="toggle-btn auth-only" id="menuAranacaklarLink" title="Aranacaklar" style="display: none; text-decoration:none;">
1832      <i class="fas fa-address-book"></i>
1833      <span>Aranacaklar</span>
1834    </a>
1835
1836    <!-- 12. Kredi Paketleri -->
1837    <a href="/accounts/pricing/" class="toggle-btn auth-only" id="menuPricingLink" style="display: none;">
1838      <i class="fas fa-coins"></i>
1839      <span>Kredi Paketleri</span>
1840    </a>
1841      <a href="#" class="user-menu-item auth-only" id="menuKomisyonHesaplaLink" role="menuitem">
1842        <i class="fas fa-calculator" aria-hidden="true"></i>
1843        <span>Komisyon Hesapla</span>
1844      </a>
1845
1846    <!-- 13. Dosyalarım -->
1847    <div data-pp-collapsible="user-dosyalarim" class="pp-collapsible-wrap auth-only" style="display: none;">
1848      <button type="button" id="user-menu-dosyalarim-btn" data-pp-collapsible-toggle="user-dosyalarim" class="toggle-btn pp-collapsible-toggle" title="Dosyalarım" aria-expanded="false" aria-controls="user-dosyalarim-content">
1849        <i class="fa fa-folder"></i>
1850        <span>Dosyalarım</span>
1851        <i class="fa fa-chevron-down pp-collapsible-chevron" aria-hidden="true"></i>
1852      </button>
1853      <div id="user-dosyalarim-content" data-pp-collapsible-content="user-dosyalarim" class="pp-collapsible-content" role="region" aria-label="Dosyalarım alt menü">
1854        <a href="/hisseli-parsel/?projects=1" class="pp-collapsible-item" title="Hisseli Parsel Projelerim" style="text-decoration:none;">
1855          <i class="fas fa-file-alt"></i>
1856          <span>Hisseli Parsel Projelerim</span>
1857        </a>
1858        <a href="/accounts/3d-designs/" class="pp-collapsible-item" title="3D Tasarımlarım" style="text-decoration:none;">
1859          <i class="fas fa-cube"></i>
1860          <span>3D Tasarımlarım</span>
1861        </a>
1862        <div data-pp-collapsible="user-uzman" class="pp-collapsible-wrap" id="menuExpertRequestsGroup">
1863          <button type="button" id="user-menu-uzman-btn" data-pp-collapsible-toggle="user-uzman" class="pp-collapsible-item pp-collapsible-toggle" title="Taleplerim" aria-expanded="false" aria-controls="user-uzman-content">
1864            <i class="fas fa-user-tie"></i>
1865            <span>Taleplerim</span>
1866            <span id="expertRequestsBadge" class="pp-collapsible-badge" style="display:none;">0</span>
1867            <i class="fa fa-chevron-down pp-collapsible-chevron" aria-hidden="true"></i>
1868          </button>
1869          <div id="user-uzman-content" data-pp-collapsible-content="user-uzman" class="pp-collapsible-content" role="region" aria-label="Taleplerim alt menü">
1870            <a href="/accounts/expert-requests/mine/" class="pp-collapsible-nested-item" title="İstekler" style="text-decoration:none;">
1871              <i class="fas fa-paper-plane"></i>
1872              <span>İstekler</span>
1873              <span id="myRequestsBadge" class="pp-collapsible-badge" style="display:none;">0</span>
1874            </a>
1875            <a href="/accounts/expert-requests/incoming/" class="pp-collapsible-nested-item" id="menuIncomingRequestsLink" title="Gelenler" style="text-decoration:none;">
1876              <i class="fas fa-inbox"></i>
1877              <span>Gelenler</span>
1878              <span id="incomingRequestsBadge" class="pp-collapsible-badge" style="display:none;">0</span>
1879            </a>
1880          </div>
1881        </div>
1882      </div>
1883    </div>
1884
1885    <!-- Diğerleri -->
1886    <a href="/portal/ilan/mesajlar/" class="toggle-btn auth-only" id="menuIlanMesajlarLink" title="Mesajlarım" style="display: none; text-decoration:none;">
1887      <i class="fas fa-comments"></i>
1888      <span>Mesajlar</span>
1889    </a>
1890
1891    <div class="user-menu-divider" id="userMenuBottomDivider"></div>
1892    <a href="/destek/" class="toggle-btn" id="menuSupportLink" style="text-decoration:none;">
1893      <i class="fas fa-life-ring"></i>
1894      <span>Destek</span>
1895    </a>
1896    <a href="/proje-olustur/" class="toggle-btn" id="menuHowToLink" title="Nasıl Yapılır" style="text-decoration:none;">
1897      <i class="fas fa-circle-play"></i>
1898      <span>Nasıl Yapılır</span>
1899    </a>
1900    <a href="/rehber/" class="toggle-btn" id="menuRehberLink" style="text-decoration:none;">
1901      <i class="fas fa-book-open"></i>
1902      <span>Rehber</span>
1903    </a>
1904    <a href="/accounts/logout/" class="toggle-btn user-menu-logout auth-only" id="menuLogoutLink" style="display: none;">
1905      <i class="fas fa-sign-out-alt"></i>
1906      <span>Çıkış Yap</span>
1907    </a>
1908  </div>
1909</div>
1910
1911    
1912  </div>
1913</nav>
1914
1915<!-- Topbar Dropdown Script -->
1916<!-- NOT: Ana dropdown işlevselliği dropdowns.js tarafından yönetilir.
1917     Bu script sadece dropdowns.js yüklenmeyen sayfalar için fallback sağlar.
1918     dropdowns.js yüklenecekse bu script devre dışı kalır. -->
1919<script>
1920(function(){
1921  // dropdowns.js yüklenip yüklenmeyeceğini bekle (sayfa tamamen yüklenene kadar)
1922  // dropdowns.js yüklendiyse, o zaten tüm işlevselliği sağlar
1923  function initTopbarDropdownsFallback() {
1924    const menuToggle = document.getElementById('main-menu-toggle');
1925    const menuDropdown = document.getElementById('main-menu-dropdown');
1926    const userToggle = document.getElementById('userMenuBtn');
1927    const userDropdown = document.getElementById('user-menu-dropdown');
1928    
1929    // dropdowns.js zaten bind ettiyse (flag kontrolü) - atla
1930    if(menuToggle && menuToggle.__ppDropdownBound) return;
1931    if(userToggle && userToggle.__ppDropdownBound) return;
1932    
1933    // Hamburger menü
1934    if(menuToggle && menuDropdown){
1935      menuToggle.__ppDropdownBound = true;
1936      
1937      menuToggle.addEventListener('click', function(e){
1938        e.stopPropagation();
1939        e.preventDefault();
1940        menuDropdown.classList.toggle('open');
1941        // Kullanıcı menüsünü kapat
1942        if(userDropdown) userDropdown.classList.remove('open');
1943      });
1944    }
1945    
1946    // Kullanıcı menüsü
1947    if(userToggle && userDropdown){
1948      userToggle.__ppDropdownBound = true;
1949      
1950      // Click event
1951      userToggle.addEventListener('click', function(e){
1952        e.stopPropagation();
1953        e.preventDefault();
1954        userDropdown.classList.toggle('open');
1955        // Ana menüyü kapat
1956        if(menuDropdown) menuDropdown.classList.remove('open');
1957      });
1958      
1959      // Touch event (mobil için)
1960      userToggle.addEventListener('touchend', function(e){
1961        e.preventDefault();
1962        e.stopPropagation();
1963        userDropdown.classList.toggle('open');
1964        // Ana menüyü kapat
1965        if(menuDropdown) menuDropdown.classList.remove('open');
1966      }, { passive: false });
1967    }
1968    
1969    // Dışarı tıklamada kapat - sadece bir kez bind et
1970    if(!window.__ppTopbarDropdownOutsideClose){
1971      window.__ppTopbarDropdownOutsideClose = true;
1972      
1973      function closeDropdowns(e) {
1974        const menuDD = document.getElementById('main-menu-dropdown');
1975        const userDD = document.getElementById('user-menu-dropdown');
1976        if(menuDD && !menuDD.contains(e.target)) {
1977          menuDD.classList.remove('open');
1978        }
1979        if(userDD && !userDD.contains(e.target)) {
1980          userDD.classList.remove('open');
1981        }
1982      }
1983      
1984      document.addEventListener('click', closeDropdowns);
1985      document.addEventListener('touchend', closeDropdowns, { passive: true });
1986    }
1987  }
1988  
1989  // Sayfa tamamen yüklendikten SONRA çalıştır (dropdowns.js'e öncelik ver)
1990  // dropdowns.js varsa zaten binding yapmış olacak, bu script atlanacak
1991  window.addEventListener('load', function(){
1992    // Küçük bir gecikme ile çalıştır - dropdowns.js'in çalışmasını bekle
1993    setTimeout(initTopbarDropdownsFallback, 100);
1994  });
1995})();
1996</script>
1996
1997
1998<!-- Tepe Kredi Sistemi -->
1999
2000<script src="/static/js/credit_system.js"></script>
2000
2001
2002<!-- Kullanıcı menüsü durumu güncelleme -->
2003<script id="pp-user" type="application/json">
2004{
2005  "authenticated": false,
2006  "id": "",
2007  "email": "",
2008  "name": "",
2009  "avatar": "",
2010  "initial": "",
2011  "is_admin": false,
2012  "is_vip": false,
2013  "can_view_expert_price": false,
2014  "has_seen_welcome": true,
2015  "has_seen_app_tour": true,
2016  "member_type": "",
2017  "corporate_type": "",
2018  "effective_corporate_type": "",
2019  "consultant_type": "",
2020  "can_access_vault": false,
2021  "can_access_prosorgu": false,
2022  "is_company_authority": false,
2023  "role": "",
2024  "company": "",
2025  "phone": "",
2026  "customer_type": "basic",
2027  "features": {"smart_query":false,"street_view":false,"portal_share_pdf":true,"portal_share_link":true}
2028}
2029</script>
vendor: 1 bytes, line 2029
2029
2030<script>
2031  window.PP_WEB_ILAN_PORTAL_UI_ENABLED = true;
2032  window.PP_WEB_ILAN_VITRIN_UI_ENABLED = true;
2033</script>
vendor: 1 bytes, line 2033
2033
2034<script>
2035  (function() {
2036    try {
2037      const ppElement = document.getElementById('pp-user');
2038      if (!ppElement) {
2039        console.warn('[PP-User] pp-user element not found, using defaults');
2040        window.PP_USER_AUTHENTICATED = false;
2041        window.PP_USER_EMAIL = null;
2042        window.PP_USER_NAME = null;
2043        window.PP_USER_AVATAR = null;
2044        window.PP_USER_INITIAL = null;
2045        window.PP_USER_IS_ADMIN = false;
2046        window.PP_USER_IS_VIP = false;
2047        window.PP_USER_CAN_VIEW_EXPERT_PRICE = false;
2048        window.PP_USER_HAS_SEEN_WELCOME = true;
2049        window.PP_USER_HAS_SEEN_APP_TOUR = true;
2050        window.PP_USER_MEMBER_TYPE = null;
2051        window.PP_USER_ROLE = null;
2052        window.PP_USER_CORPORATE_TYPE = null;
2053        window.PP_USER_IS_COMPANY_AUTHORITY = false;
2054        window.PP_USER_COMPANY = null;
2055        window.PP_USER_PHONE = null;
2056        window.PP_CAN_ACCESS_VAULT = false;
2057        window.PP_CAN_ACCESS_PROSORGU = false;
2058        window.PP_WEB_ILAN_PORTAL_UI_ENABLED = false;
2059        window.PP_WEB_ILAN_VITRIN_UI_ENABLED = true;
2060        return;
2061      }
2062      const pp = JSON.parse(ppElement.textContent);
2063      window.PP_USER_AUTHENTICATED = !!pp.authenticated;
2064      window.PP_USER_ID = pp.id || null;
2065      window.PP_USER_EMAIL = pp.email || null;
2066      window.PP_USER_NAME = pp.name || null;
2067      window.PP_USER_AVATAR = pp.avatar || null;
2068      window.PP_USER_INITIAL = pp.initial || null;
2069      window.PP_USER_IS_ADMIN = !!pp.is_admin;
2070      window.PP_USER_IS_VIP = !!pp.is_vip;
2071      window.PP_USER_CAN_VIEW_EXPERT_PRICE = !!pp.can_view_expert_price;
2072      window.PP_USER_HAS_SEEN_WELCOME = !!pp.has_seen_welcome;
2073      window.PP_USER_HAS_SEEN_APP_TOUR = !!pp.has_seen_app_tour;
2074      window.PP_USER_MEMBER_TYPE = pp.member_type || null;
2075      window.PP_USER_ROLE = pp.role || null;
2076      window.PP_USER_CORPORATE_TYPE = pp.corporate_type || null;
2077      window.PP_USER_EFFECTIVE_CORPORATE_TYPE = pp.effective_corporate_type || pp.corporate_type || null;
2078      window.PP_USER_CONSULTANT_TYPE = pp.consultant_type || null;
2079      window.PP_CAN_ACCESS_VAULT = !!pp.can_access_vault;
2080      window.PP_CAN_ACCESS_PROSORGU = pp.can_access_prosorgu !== false;
2081      window.PP_USER_IS_COMPANY_AUTHORITY = !!pp.is_company_authority;
2082      window.PP_USER_COMPANY = pp.company || null;
2083      window.PP_USER_PHONE = pp.phone || null;
2084      window.PP_USER_CUSTOMER_TYPE = pp.customer_type || 'basic';
2085      window.PP_USER_FEATURES = pp.features || {
2086        smart_query: false,
2087        street_view: false,
2088        portal_share_pdf: true,
2089        portal_share_link: true,
2090      };
2091    } catch (e) {
2092      console.error('[PP-User] Error parsing user data:', e);
2093      window.PP_USER_AUTHENTICATED = false;
2094      window.PP_USER_ID = null;
2095      window.PP_USER_EMAIL = null;
2096      window.PP_USER_NAME = null;
2097      window.PP_USER_AVATAR = null;
2098      window.PP_USER_INITIAL = null;
2099      window.PP_USER_IS_ADMIN = false;
2100      window.PP_USER_IS_VIP = false;
2101      window.PP_USER_CAN_VIEW_EXPERT_PRICE = false;
2102      window.PP_USER_HAS_SEEN_WELCOME = true;
2103      window.PP_USER_HAS_SEEN_APP_TOUR = true;
2104      window.PP_USER_MEMBER_TYPE = null;
2105      window.PP_USER_ROLE = null;
2106      window.PP_USER_CORPORATE_TYPE = null;
2107      window.PP_USER_CONSULTANT_TYPE = null;
2108        window.PP_CAN_ACCESS_VAULT = false;
2109        window.PP_CAN_ACCESS_PROSORGU = false;
2110        window.PP_USER_IS_COMPANY_AUTHORITY = false;
2111      window.PP_USER_COMPANY = null;
2112      window.PP_USER_PHONE = null;
2113    }
2114  })();
2115</script>
vendor: 1 bytes, line 2115
2115
2116<script src="/static/js/core/components/collapsible_menu.js"></script>
vendor: 1 bytes, line 2116
2116
2117<script src="/static/js/app/ui/dropdowns.js"></script>
vendor: 1 bytes, line 2117
2117
2118<script src="/static/js/app/ui/user_menu.js"></script>
vendor: 1 bytes, line 2118
2118
2119<script src="/static/js/app/cost/komisyon_harclar_modal.js?v=20260725i"></script>
vendor: 1 bytes, line 2119
2119
2120<script src="/static/js/app/ui/ai_drone_admin_gate.js"></script>
vendor: 1 bytes, line 2120
2120
2121<script src="/static/js/app/ui/welcome_modal.js"></script>
vendor: 1 bytes, line 2121
2121
2122<script src="/static/js/app/ui/auth_required_3d_modal.js"></script>
2122
2123<!-- Tüm sayfalarda menülerin düzgün çalışması için window load'da reinit -->
2124<script>
2125(function() {
2126  // Sayfa tamamen yüklendikten sonra tekrar initialize et
2127  window.addEventListener('load', function() {
2128    setTimeout(function() {
2129      // Collapsible menüleri reinit
2130      if (typeof window.ppCollapsible !== 'undefined' && window.ppCollapsible.init) {
2131        window.ppCollapsible.init();
2132      }
2133      // Auth-only elementleri tekrar kontrol et
2134      if (window.PP_USER_AUTHENTICATED) {
2135        var authOnlyElements = document.querySelectorAll('.auth-only');
2136        authOnlyElements.forEach(function(el) {
2137          if (el.classList.contains('pp-collapsible-wrap')) {
2138            el.style.setProperty('display', 'block', 'important');
2139          }
2140        });
2141      }
2142    }, 150);
2143  }, { once: true });
2144})();
2145</script>
2145
2146    
2147    <!-- TOOLBAR - Unified Action Bar (Basit/Pro tek bar, tema CSS ile değişir) -->
2148    <nav class="pp-toolbar mode-simple" id="top-menu-bar">
2149      <div id="top-button-container" class="mode-simple" onclick="stopMapClick(event)">
2150      <!-- ADA PARSEL SORGU BUTONU -->
2151      <button id="proAdaParselSorguBtn" class="toggle-btn pp-ada-parsel-toolbar-btn" title="Ada/Parsel Sorgu" type="button">
2152        <i class="fa fa-search" aria-hidden="true"></i>
2153        <span>Ada Parsel Sorgu</span>
2154      </button>
2155      <!-- AYRAÇ -->
2156      <span class="btn-separator"></span>
2157      <!-- MAP TIKLAMA / BASİT MOD -->
2158      <button id="toggleMapClick" class="toggle-btn target-button" data-target="toggleMapClick"
2159        type="button" title="Tıklama Modu (Cursor)" aria-label="Basit Sorgu Tıklama Modu">
2160        <i class="fa fa-mouse-pointer"></i>
2161      </button>
2162      <!-- PRO MOD KISAYOLU -->
2163      <button id="toolbarModeProBtn" class="toggle-btn pp-toolbar-mode-pro-btn" type="button"
2164        title="Pro Analize Geç" aria-label="Pro Analize Geç">
2165        <i class="fa fa-mouse-pointer pp-toolbar-mode-icon" aria-hidden="true"></i>
2166      </button>
2167      <!-- VIP Doğrulama durumu toggle (vip / vip_limited / premium) -->
2168      <button id="ppDogrulamaToggle" class="toggle-btn pp-dogrulama-toggle" type="button"
2169        title="Doğrulama" aria-label="Doğrulama" aria-pressed="false" style="display:none;">
2170        <i class="fas fa-shield-halved" aria-hidden="true"></i>
2171      </button>
2172      <button type="button" id="ppKomisyonHarclarBtn" class="toggle-btn" title="Komisyon &amp; Harçlar Hesapla"
2173        onclick="event.preventDefault();event.stopPropagation();if(typeof window.openKomisyonHarclarModal==='function'){window.openKomisyonHarclarModal({});}return false;">
2174        <i class="fas fa-calculator"></i>
2175        <span>Komisyon</span>
2176      </button>
2177      <span class="btn-separator pp-toolbar-slide-sep" aria-hidden="true"></span>
2178      <!-- Diğer araçlar: ikonla açılıp kapanan kaydırmalı şerit -->
2179      <div class="pp-toolbar-extras-shell">
2180        <button type="button" id="pp-toolbar-slide-toggle" class="toggle-btn pp-toolbar-slide-toggle"
2181          title="Diğer araçları göster / gizle" aria-expanded="false" aria-controls="pp-toolbar-extras">
2182          <i class="fas fa-angles-left pp-toolbar-slide-icon" aria-hidden="true"></i>
2183          <span class="visually-hidden">Diğer araçlar</span>
2184        </button>
2185        <div id="pp-toolbar-extras" class="pp-toolbar-extras" aria-hidden="true" role="region" aria-label="Ek harita araçları">
2186      <!-- P (Parsel Sınırı + Yükselti Görünümü) -->
2187      <button id="parcel_polygon" class="parameters nodata" data-target="parcel_polygon" title="Parsel Sınırı ve Yükselti Görünümü">
2188        <span style="font-weight: 600; font-size: 14px;">P</span>
2189      </button>
2190      <!-- KONUM -->
2191      <button id="toolbarGeoBtn" class="toggle-btn geo-btn" data-geo="toggle" title="Konumuma Git" aria-pressed="false">
2192        <i class="fas fa-crosshairs"></i>
2193      </button>
2194      <!-- KATMAN (Vektör harita aç/kapat) -->
2195      <button id="hdBaseBtn" type="button" class="toggle-btn" data-action="toggle-hd-base" title="Vektör harita aç/kapat" aria-label="Vektör harita aç/kapat">
2196        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true">
2197          <path d="M9.5 5.1l5 1.8 5-1.6c.3-.1.5.1.5.4v13.4c0 .2-.1.4-.3.4l-5.2 1.7c-.1 0-.2 0-.3 0l-5-1.8-5 1.6c-.3.1-.5-.1-.5-.4V6c0-.2.1-.4.3-.4l5.2-1.7c.1 0 .2 0 .3 0zM9 6.6L5 5.3v12.8l4-1.3V6.6zm6 1.8l-4-1.5v10.3l4 1.5V8.4zm1 9.4l3-1V4l-3 1v12.8z"></path>
2198        </svg>
2199      </button>
2200      <!-- ARAÇ TAKIMI (İğne & Metin) -->
2201      <div class="pp-annotation-dropdown" id="annotationToolDropdown" onclick="event.stopPropagation();">
2202        <button type="button" class="toggle-btn" id="annotationToolBtn" title="Araç Takımı (İğne / Metin)">
2203          <i class="fas fa-toolbox"></i>
2204          <span>Araçlar</span>
2205          <i class="fas fa-caret-down" style="margin-left:4px;font-size:10px;opacity:0.7;"></i>
2206        </button>
2207        <div class="pp-annotation-menu" id="annotationMenu">
2208          <div class="pp-annotation-menu-group">
2209            <button type="button" class="pp-annotation-submenu-trigger" id="annotTriggerDraw" aria-expanded="false" aria-controls="annotSubmenuDraw">
2210              <span class="pp-annot-submenu-label"><i class="fas fa-pencil-alt" aria-hidden="true"></i> Çizim Araçları</span>
2211              <i class="fas fa-chevron-right pp-annot-submenu-chevron" aria-hidden="true"></i>
2212            </button>
2213            <div class="pp-annotation-submenu" id="annotSubmenuDraw" role="region" aria-labelledby="annotTriggerDraw">
2214              <button type="button" class="pp-annotation-menu-item" data-annotation-tool="pin" title="Haritaya İğne Ekle">
2215                <i class="fas fa-map-pin"></i>
2216                <span>İğne Ekle</span>
2217              </button>
2218              <button type="button" class="pp-annotation-menu-item" data-annotation-tool="arrow" title="Haritaya Ok Ekle">
2219                <i class="fas fa-long-arrow-alt-right"></i>
2220                <span>Ok Ekle</span>
2221              </button>
2222              <button type="button" class="pp-annotation-menu-item" data-annotation-tool="pencil" title="Serbest kalem ile sürükleyerek çiz">
2223                <i class="fas fa-pencil-alt"></i>
2224                <span>Kalem çizimi</span>
2225              </button>
2226              <button type="button" class="pp-annotation-menu-item" data-annotation-tool="freepolyline" title="Tıklayarak çizgi — Tamam veya çift tıklama ile bitir">
2227                <i class="fas fa-project-diagram"></i>
2228                <span>Serbest çizim (tıkla)</span>
2229              </button>
2230              <hr class="pp-annotation-menu-divider">
2231              <button type="button" class="pp-annotation-menu-item pp-annotation-menu-item--danger" data-annotation-tool="clear" title="Parsel sınırı hariç işaretleri ve çizimleri temizle">
2232                <i class="fas fa-trash-alt"></i>
2233                <span>Tümünü Temizle</span>
2234              </button>
2235            </div>
2236          </div>
2237          <div class="pp-annotation-menu-group">
2238            <button type="button" class="pp-annotation-submenu-trigger" id="annotTriggerMeasure" aria-expanded="false" aria-controls="annotSubmenuMeasure">
2239              <span class="pp-annot-submenu-label"><i class="fas fa-ruler" aria-hidden="true"></i> Ölçüm Araçları</span>
2240              <i class="fas fa-chevron-right pp-annot-submenu-chevron" aria-hidden="true"></i>
2241            </button>
2242            <div class="pp-annotation-submenu" id="annotSubmenuMeasure" role="region" aria-labelledby="annotTriggerMeasure">
2243              <button type="button" class="pp-annotation-menu-item measurement-btn" data-action="toggle-ruler" title="Mesafe Ölçümü (Cetvel)">
2244                <i class="fas fa-ruler"></i>
2245                <span>Mesafe Ölçümü</span>
2246              </button>
2247              <button type="button" class="pp-annotation-menu-item measurement-btn" data-action="toggle-area" title="Alan Ölçümü">
2248                <i class="fas fa-drafting-compass"></i>
2249                <span>Alan Ölçümü</span>
2250              </button>
2251            </div>
2252          </div>
2253          <hr class="pp-annotation-menu-divider">
2254          <button type="button" class="pp-annotation-menu-item" data-annotation-tool="text" title="Haritaya Metin Ekle">
2255            <i class="fas fa-font"></i>
2256            <span>Metin Ekle</span>
2257          </button>
2258        </div>
2259      </div>
2260      <button id="action-bar-refresh-btn" class="toggle-btn" title="Ekrandaki parselleri ve çizimleri temizle"
2261        onclick="if(typeof window.ppActionBarRefreshClear==='function')window.ppActionBarRefreshClear();">
2262        <i class="fas fa-sync-alt"></i>
2263      </button>
2264      <span class="btn-separator pp-toolbar-extras-auth-sep"></span>
2265      <div class="pp-toolbar-extras-auth-gate pp-toolbar-extras-auth-gate--locked">
2266      <div class="pp-toolbar-extras-auth-overlay" role="status" aria-live="polite">
2267        <p class="pp-toolbar-extras-auth-overlay-text">Ücretsiz Kullanım İçin Üye Girişi Yapın</p>
2268      </div>
2269      <!-- HARİTA GÖRÜNTÜSÜ AL -->
2270      <div class="pp-capture-menu-wrap" id="pp-capture-menu-wrap">
2271        <button id="pp-screenshot-map-btn" class="toggle-btn" title="Harita görüntüsü al" onclick="if(typeof ppToggleCaptureMenu==='function')ppToggleCaptureMenu(event);" disabled aria-disabled="true" tabindex="-1">
2272          <i class="fas fa-camera"></i>
2273          <span>Görüntü Al</span>
2274          <i class="fas fa-chevron-down pp-capture-menu-caret"></i>
2275        </button>
2276        <div class="pp-capture-menu" id="pp-capture-menu" aria-label="Görüntü formatı seç">
2277          <button type="button" onclick="if(typeof ppCaptureAndDownloadMap==='function')ppCaptureAndDownloadMap('horizontal');">
2278            <i class="fas fa-arrows-alt-h"></i>
2279            <span>Yatay</span>
2280          </button>
2281          <button type="button" onclick="if(typeof ppCaptureAndDownloadMap==='function')ppCaptureAndDownloadMap('vertical');">
2282            <i class="fas fa-mobile-alt"></i>
2283            <span>Dikey Hikaye</span>
2284          </button>
2285        </div>
2286      </div>
2287      <!-- 3D GÖRÜNÜME GEÇ -->
2288      <button class="toggle-btn map-3d-toggle pp-webgl-compat-disabled" id="toggle3DMap" title="3D uyumluluğu kontrol ediliyor" aria-disabled="true" data-pp-webgl-pending="1" data-pp-webgl-blocked="1" style="background:#e5e7eb!important;background-image:none!important;color:#64748b!important;border-color:#cbd5e1!important;box-shadow:none!important;text-shadow:none!important;opacity:.45!important;filter:grayscale(1)!important;cursor:not-allowed!important;" disabled tabindex="-1">
2289        <i class="fa fa-cube"></i>
2290        <span id="toggle3DText"></span>
2291      </button>
2292            <!-- SOKAK GÖRÜNTÜSÜ BUTONU -->
2293      <button id="street-view-menu-btn" class="toggle-btn" title="Sokak Görüntüsü" onclick="openStreetViewModal()" disabled aria-disabled="true" tabindex="-1">
2294        <i class="fa fa-street-view"></i>
2295        <span>Sokak Görüntüsü</span>
2296      </button>
2297      <span class="btn-separator"></span>
2298      <!-- HISSELİ PARSELLERE BÖL — ayraç sağında, 3D Model ile yan yana -->
2299      <button id="hisseli-parsel-btn" class="toggle-btn" title="Hisseli Parsellere Böl (önce haritada parsel seçin)" onclick="openHisseliParselPage()" disabled aria-disabled="true" tabindex="-1">
2300        <i class="fa fa-object-group"></i>
2301        <span>Hisseli Parsellere Böl</span>
2302      </button>
2303      <!-- 3D MODEL EKLE (hamburger menüden taşındı) -->
2304      <a href="javascript:void(0)" data-pp-original-href="/3d-editor/" id="pp-3d-editor-toolbar-link" class="toggle-btn action-bar-link pp-webgl-compat-disabled" title="3D uyumluluğu kontrol ediliyor" aria-disabled="true" data-pp-webgl-pending="1" data-pp-webgl-blocked="1" style="background:#e5e7eb!important;background-image:none!important;color:#64748b!important;border-color:#cbd5e1!important;box-shadow:none!important;text-shadow:none!important;opacity:.45!important;filter:grayscale(1)!important;cursor:not-allowed!important;" tabindex="-1">
2305        <i class="fas fa-cube"></i>
2306        <span>3D Model</span>
2307      </a>
2308      <a href="javascript:void(0)" data-pp-original-href="/bina-ciz/" id="pp-ne-yapilir-btn" class="toggle-btn action-bar-link pp-webgl-compat-disabled" title="Proje Oluştur — önce haritada parsel seçin" aria-disabled="true" data-pp-webgl-pending="1" data-pp-webgl-blocked="1" style="background:#e5e7eb!important;background-image:none!important;color:#64748b!important;border-color:#cbd5e1!important;box-shadow:none!important;text-shadow:none!important;opacity:.45!important;filter:grayscale(1)!important;cursor:not-allowed!important;" tabindex="-1">
2309        <i class="fas fa-building"></i>
2310        <span>Proje Oluştur</span>
2311      </a>
2312      <button type="button" id="pp-ai-drone-video-btn" class="toggle-btn" title="AI Drone Video — önce haritada parsel seçin veya sorgulayın" data-pp-webgl-pending="1" disabled tabindex="-1">
2313        <i class="fas fa-video"></i>
2314        <span>AI Drone Video</span>
2315      </button>
2316      </div>
2317        </div>
2318      </div>
2319      <div class="pp-toolbar-flex-spacer" aria-hidden="true"></div>
2320      <!-- GÖSTERGE (en sağda) -->
2321      <div id="map-zoom-indicator" class="toggle-btn"
2322        style="min-width: 80px; text-align: center; display: flex; align-items: center; justify-content: center;">
2323        -
2324      </div>
2325      </div>
2326    </nav>
2327  </header>
2328  
2328<script>
2329  (function () {
2330    'use strict';
2331    var DEBUG = false;
2332    var applyingActionBarState = false;
2333    var featureBlocks = [
2334      { selector: '#toggle3DMap', feature: '3d_mode' },
2335      { selector: '#pp-3d-editor-toolbar-link', feature: 'model_editor' },
2336      { selector: '#pp-ne-yapilir-btn', feature: 'model_editor' },
2337      { selector: '#pp-ai-drone-video-btn', feature: 'drone_editor' }
2338    ];
2339    var warningText = 'Bu bilgisayar/tarayıcı 3D harita, 3D model ve AI Drone özelliklerini desteklemiyor. Ekran kartı sürücünüz eski olabilir. Lütfen güncel Chrome/Edge/Firefox veya daha yeni bir bilgisayar kullanın.';
2340
2341    function debugLog(stage, payload) {
2342      if (!DEBUG) return;
2343      try {
2344        console.warn('[PP_WEBGL_ACTIONBAR_GUARD]', stage, payload || {});
2345      } catch (e) {}
2346    }
2347
2348    function supportsFeature(feature) {
2349      if (feature === 'drone_editor') {
2350        try {
2351          if (typeof window.ppIsDroneEditorAllowed === 'function' && !window.ppIsDroneEditorAllowed()) return false;
2352        } catch (e) {}
2353      }
2354      try {
2355        if (window.PPWebGLCompat && typeof window.PPWebGLCompat.supports === 'function') {
2356          return window.PPWebGLCompat.supports(feature);
2357        }
2358      } catch (e) {}
2359      var mode = window.__PP_GPU_MODE || 'minimal_gpu';
2360      if (mode === 'no_gpu') return feature === 'drone_editor';
2361      if (mode === 'full_gpu') return true;
2362      if (feature === '3d_mode' || feature === 'model_editor') return false;
2363      return true;
2364    }
2365
2366    function warningForFeature(feature) {
2367      if (feature === 'model_editor') return 'Bu cihazda gelişmiş 3D düzenleme desteklenmiyor.';
2368      if (feature === 'drone_editor') return 'AI Drone Video — şu an kullanılamıyor';
2369      return 'Bu cihazda 3D harita ve terrain modu desteklenmiyor. 2D uydu harita ve sorgu işlemleri kullanılabilir.';
2370    }
2371
2372    function showLegacyWarning() {
2373      try {
2374        if (window.PPWebGLCompat && typeof window.PPWebGLCompat.showWarning === 'function') {
2375          window.PPWebGLCompat.showWarning();
2376          return;
2377        }
2378      } catch (e) {}
2379      alert(warningText);
2380    }
2381
2382    function setDisabledVisual(el) {
2383      if (!el) {
2384        debugLog('set_disabled_missing_element', {});
2385        return;
2386      }
2387      if (el.getAttribute('data-pp-index-actionbar-disabled') === '1') return;
2388      el.classList.remove('active');
2389      el.classList.remove('pp-green');
2390      el.classList.add('pp-webgl-compat-disabled', 'pp-webgl-3d-disabled');
2391      el.setAttribute('aria-disabled', 'true');
2392      el.setAttribute('data-pp-webgl-blocked', '1');
2393      el.setAttribute('data-pp-index-actionbar-disabled', '1');
2394      if (el.id === 'pp-ai-drone-video-btn') {
2395        el.title = 'AI Drone Video — şu an kullanılamıyor';
2396      } else {
2397        el.title = 'Bu cihaz bu özelliği desteklemiyor';
2398      }
2399      if (el.tagName === 'A') {
2400        if (!el.getAttribute('data-pp-original-href')) el.setAttribute('data-pp-original-href', el.getAttribute('href') || '');
2401        el.setAttribute('href', 'javascript:void(0)');
2402      }
2403      if (el.hasAttribute && el.hasAttribute('onclick')) {
2404        if (!el.getAttribute('data-pp-original-onclick')) el.setAttribute('data-pp-original-onclick', el.getAttribute('onclick') || '');
2405        el.removeAttribute('onclick');
2406      }
2407      [
2408        ['background', '#e5e7eb'],
2409        ['background-image', 'none'],
2410        ['color', '#64748b'],
2411        ['border-color', '#cbd5e1'],
2412        ['box-shadow', 'none'],
2413        ['text-shadow', 'none'],
2414        ['opacity', '0.45'],
2415        ['filter', 'grayscale(1)'],
2416        ['cursor', 'not-allowed']
2417      ].forEach(function (pair) {
2418        try { el.style.setProperty(pair[0], pair[1], 'important'); } catch (e) {}
2419      });
2420      try {
2421        el.querySelectorAll('i,svg,span').forEach(function (child) {
2422          child.style.setProperty('color', '#64748b', 'important');
2423          child.style.setProperty('fill', '#64748b', 'important');
2424        });
2425      } catch (e) {}
2426      debugLog('set_disabled_applied', {
2427        id: el.id,
2428        tagName: el.tagName,
2429        className: el.className,
2430        href: el.getAttribute('href'),
2431        ariaDisabled: el.getAttribute('aria-disabled'),
2432        dataBlocked: el.getAttribute('data-pp-webgl-blocked'),
2433        inlineStyle: el.getAttribute('style')
2434      });
2435    }
2436
2437    function clearDisabledVisual(el) {
2438      if (!el) return;
2439      if (el.getAttribute('data-pp-admin-blocked') === '1') return;
2440      if (el.getAttribute('data-pp-webgl-pending') !== '1') return;
2441      el.classList.remove('pp-webgl-compat-disabled');
2442      el.classList.remove('pp-webgl-3d-disabled');
2443      el.removeAttribute('aria-disabled');
2444      el.removeAttribute('data-pp-webgl-blocked');
2445      el.removeAttribute('data-pp-index-actionbar-disabled');
2446      el.removeAttribute('data-pp-webgl-pending');
2447      if (el.id === 'toggle3DMap') {
2448        el.title = '3D Görünüme Geç';
2449      } else if (el.id === 'pp-3d-editor-toolbar-link') {
2450        el.title = '3D Model Ekle (seçili parsel varsa ada/parsel taşınır)';
2451      } else if (el.id === 'pp-ne-yapilir-btn') {
2452        el.title = 'Proje Oluştur — seçili parsel ile bina çiz';
2453      } else if (el.id === 'pp-ai-drone-video-btn') {
2454        el.title = 'AI Drone Video — önce haritada parsel seçin veya sorgulayın';
2455      }
2456      if (el.tagName === 'A') {
2457        var originalHref = el.getAttribute('data-pp-original-href') || (el.id === 'pp-ne-yapilir-btn' ? '/bina-ciz/' : '/3d-editor/');
2458        el.setAttribute('href', originalHref);
2459      }
2460      [
2461        'background',
2462        'background-image',
2463        'color',
2464        'border-color',
2465        'box-shadow',
2466        'text-shadow',
2467        'opacity',
2468        'filter',
2469        'cursor'
2470      ].forEach(function (prop) {
2471        try { el.style.removeProperty(prop); } catch (e) {}
2472      });
2473      try {
2474        el.querySelectorAll('i,svg,span').forEach(function (child) {
2475          child.style.removeProperty('color');
2476          child.style.removeProperty('fill');
2477        });
2478      } catch (e) {}
2479      debugLog('clear_disabled_for_supported_device', {
2480        id: el.id,
2481        className: el.className,
2482        href: el.getAttribute('href'),
2483        inlineStyle: el.getAttribute('style')
2484      });
2485    }
2486
2487    function applyActionBarDisabled() {
2488      if (applyingActionBarState) return;
2489      applyingActionBarState = true;
2490      try {
2491      var anyBlocked = false;
2492      featureBlocks.forEach(function (item) {
2493        var el = document.querySelector(item.selector);
2494        if (!el) return;
2495        if (supportsFeature(item.feature)) {
2496          if (el.getAttribute('data-pp-admin-blocked') === '1') {
2497            setDisabledVisual(el);
2498          } else {
2499            clearDisabledVisual(el);
2500          }
2501        } else {
2502          anyBlocked = true;
2503          setDisabledVisual(el);
2504        }
2505      });
2506      try {
2507        if (anyBlocked) {
2508          document.documentElement.classList.add('pp-webgl-compat-is-disabled');
2509          document.body && document.body.classList.add('pp-webgl-compat-is-disabled');
2510        } else {
2511          document.documentElement.classList.remove('pp-webgl-compat-is-disabled');
2512          document.body && document.body.classList.remove('pp-webgl-compat-is-disabled');
2513        }
2514      } catch (e) {}
2515      try {
2516        if (window.PPWebGLCompat && typeof window.PPWebGLCompat.update3DControls === 'function') window.PPWebGLCompat.update3DControls();
2517      } catch (e) {}
2518      } finally {
2519        applyingActionBarState = false;
2520      }
2521    }
2522
2523    document.addEventListener('click', function (event) {
2524      var target = event.target && event.target.closest ? event.target.closest(featureBlocks.map(function (i) { return i.selector; }).join(',')) : null;
2525      if (!target) return;
2526      var block = null;
2527      featureBlocks.forEach(function (item) {
2528        if (!block && target.matches && target.matches(item.selector)) block = item;
2529        if (!block && target.closest && target.closest(item.selector)) block = item;
2530      });
2531      if (!block || supportsFeature(block.feature)) return;
2532      event.preventDefault();
2533      event.stopPropagation();
2534      if (typeof event.stopImmediatePropagation === 'function') event.stopImmediatePropagation();
2535      setDisabledVisual(target);
2536      showLegacyWarning();
2537    }, true);
2538
2539    debugLog('inline_guard_loaded', {
2540      readyState: document.readyState,
2541      currentScript: document.currentScript ? document.currentScript.src : null,
2542      hasExternalGuard: !!window.PPWebGLCompat
2543    });
2544    try {
2545      window.__PP_WEBGL_ACTIONBAR_GUARD_LOADED = true;
2546      window.__PP_WEBGL_ACTIONBAR_GUARD_VERSION = '20260520-per-feature-blocks';
2547    } catch (e) {}
2548    window.__ppApplyActionBarWebglState = applyActionBarDisabled;
2549    applyActionBarDisabled();
2550    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', applyActionBarDisabled);
2551    var runs = 0;
2552    var timer = window.setInterval(function () {
2553      runs += 1;
2554      applyActionBarDisabled();
2555      if (runs > 30) window.clearInterval(timer);
2556    }, 300);
2557    try {
2558      new MutationObserver(applyActionBarDisabled).observe(document.getElementById('top-button-container') || document.body, {
2559        childList: true,
2560        subtree: true
2561      });
2562    } catch (e) {}
2563  })();
2564  </script>
2564
2565  
2565<script>
2566  (function () {
2567    function _pv() {
2568      var d = window.lastParcelResponse || window.data_general;
2569      return (d && d.parameters_data && d.parameters_data.parcel_values) || {};
2570    }
2571    function _props() {
2572      var d = window.lastParcelResponse || window.data_general;
2573      return (d && d.properties) || {};
2574    }
2575    function _selectedMahalleTkgm() {
2576      try {
2577        var mhEl = document.getElementById('mahalle-select');
2578        if (mhEl && mhEl.selectedIndex >= 0) {
2579          var opt = mhEl.options[mhEl.selectedIndex];
2580          if (opt) {
2581            var tv = opt.getAttribute('data-tkgmvalue');
2582            if (tv != null && String(tv).trim() !== '' && tv !== 'null' && tv !== 'undefined') {
2583              return String(tv).trim();
2584            }
2585          }
2586        }
2587      } catch (e) {}
2588      return '';
2589    }
2590    function resolveMahalleTkgm() {
2591      var pv = _pv();
2592      var props = _props();
2593      var tkgm = window.lastTkgmData && window.lastTkgmData.properties;
2594      var m = tkgm && (tkgm.mahalleId || tkgm.mahalle_id);
2595      if (m == null || m === '') {
2596        m = _selectedMahalleTkgm();
2597      }
2598      if (m == null || m === '') {
2599        m = pv.mahalleId || props.mahalleId || pv.mahalle_id || props.mahalle_id;
2600      }
2601      m = String(m || '').trim();
2602      return m;
2603    }
2604    /** processParcelData ile aynı kaynaklar + snake_case + çoklu parsel + sidebar input */
2605    function _parcelValuesBundle() {
2606      var d = window.lastParcelResponse || window.data_general;
2607      if (!d || typeof d !== 'object') return null;
2608      var pd = d.parameters_data || {};
2609      return (
2610        pd.parcel_values ||
2611        pd.parcel_dict ||
2612        pd.parcelInfo ||
2613        d.parcel_values ||
2614        d.parcel_dict ||
2615        d.parcelInfo ||
2616        null
2617      );
2618    }
2619    /** TKGM'de ada=0 geçerlidir; 0 veya "0" dolu sayılır (yalnızca null/undefined/boş değil) */
2620    function parcelPartFilled(v) {
2621      if (v === undefined || v === null) return false;
2622      return String(v).trim() !== '';
2623    }
2624    function firstParcelPart(parts) {
2625      for (var i = 0; i < parts.length; i++) {
2626        var v = parts[i];
2627        if (parcelPartFilled(v)) return String(v).trim();
2628      }
2629      return '';
2630    }
2631    function _pickAdaParselFromObj(o) {
2632      if (!o || typeof o !== 'object') return { ada: '', parsel: '' };
2633      var ada = o.adaNo != null && o.adaNo !== '' ? o.adaNo : (o.Ada != null && o.Ada !== '' ? o.Ada : (o.ada != null && o.ada !== '' ? o.ada : (o.ada_no != null && o.ada_no !== '' ? o.ada_no : '')));
2634      var parsel = o.parselNo != null && o.parselNo !== '' ? o.parselNo : (o.Parsel != null && o.Parsel !== '' ? o.Parsel : (o.parsel != null && o.parsel !== '' ? o.parsel : (o.parsel_no != null && o.parsel_no !== '' ? o.parsel_no : '')));
2635      return { ada: String(ada == null ? '' : ada).trim(), parsel: String(parsel == null ? '' : parsel).trim() };
2636    }
2637    /** "10290/128" veya "0 / 12" gibi etiketlerden ada/parsel (harita katmanı sadece label tutabiliyor) */
2638    function _parseAdaParselSlashLabel(s) {
2639      if (s == null) return { ada: '', parsel: '' };
2640      var str = String(s).trim();
2641      if (!str) return { ada: '', parsel: '' };
2642      var m = str.match(/^(\d+)\s*\/\s*(\d+)\s*$/);
2643      if (m) return { ada: m[1], parsel: m[2] };
2644      return { ada: '', parsel: '' };
2645    }
2646    /** TKGM ozet: "Fadıllı-/116" → ada 0, parsel 116; veya içinde "945/12" geçen özetler */
2647    function _parseAdaParselFromOzet(oz) {
2648      if (oz == null) return { ada: '', parsel: '' };
2649      var s = String(oz).trim();
2650      if (!s) return { ada: '', parsel: '' };
2651      var m = s.match(/(\d+)\s*\/\s*(\d+)/);
2652      if (m) return { ada: m[1], parsel: m[2] };
2653      m = s.match(/\/\s*(\d+)\s*$/);
2654      if (m) return { ada: '0', parsel: m[1] };
2655      return { ada: '', parsel: '' };
2656    }
2657    function _responseRoot() {
2658      var d = window.lastParcelResponse || window.data_general;
2659      return d && typeof d === 'object' ? d : null;
2660    }
2661    function _parcelPolygonFeatureProps() {
2662      try {
2663        var d = _responseRoot();
2664        var fc = d && d.parameters_polygons && d.parameters_polygons.parcel_polygon;
2665        var feats = fc && fc.features;
2666        if (!feats || !feats.length) return null;
2667        var p = feats[0] && feats[0].properties;
2668        return p && typeof p === 'object' ? p : null;
2669      } catch (e) {
2670        return null;
2671      }
2672    }
2673    function _globalParcelPolygonProps() {
2674      try {
2675        var gl = window.globalLayers && window.globalLayers['parcel_polygon'];
2676        return gl && gl.properties && typeof gl.properties === 'object' ? gl.properties : null;
2677      } catch (e) {
2678        return null;
2679      }
2680    }
2681    function resolveParcelAreaM2() {
2682      try {
2683        var tkgm = window.lastTkgmData && window.lastTkgmData.properties;
2684        if (tkgm && (tkgm.alan != null || tkgm.ALAN != null)) {
2685          var a = tkgm.alan != null ? tkgm.alan : tkgm.ALAN;
2686          if (a != null && String(a).trim() !== '') return String(a).trim();
2687        }
2688      } catch (e0) {}
2689      try {
2690        var bundle = _parcelValuesBundle();
2691        if (bundle && bundle.alan != null && String(bundle.alan).trim() !== '') return String(bundle.alan).trim();
2692      } catch (e1) {}
2693      return '';
2694    }
2695    function resolveAdaParsel() {
2696      var partsAda = [];
2697      var partsParsel = [];
2698      var adaEl = document.getElementById('ada-input');
2699      var parselEl = document.getElementById('parsel-input');
2700      if (adaEl) partsAda.push(adaEl.value);
2701      if (parselEl) partsParsel.push(parselEl.value);
2702      var tkgm = window.lastTkgmData && window.lastTkgmData.properties;
2703      if (tkgm) {
2704        var p3 = _pickAdaParselFromObj(tkgm);
2705        partsAda.push(p3.ada);
2706        partsParsel.push(p3.parsel);
2707        var ozT = _parseAdaParselFromOzet(tkgm.ozet || tkgm.Ozet);
2708        partsAda.push(ozT.ada);
2709        partsParsel.push(ozT.parsel);
2710      }
2711      var glp = _globalParcelPolygonProps();
2712      if (glp) {
2713        var pG = _pickAdaParselFromObj(glp);
2714        partsAda.push(pG.ada);
2715        partsParsel.push(pG.parsel);
2716        var slashG = _parseAdaParselSlashLabel(glp.AdaParsel || glp.adaParsel || glp.label);
2717        partsAda.push(slashG.ada);
2718        partsParsel.push(slashG.parsel);
2719        var ozG = _parseAdaParselFromOzet(glp.ozet || glp.Ozet);
2720        partsAda.push(ozG.ada);
2721        partsParsel.push(ozG.parsel);
2722      }
2723      try {
2724        if (window.multipleParcels && window.multipleParcels.length) {
2725          var last = window.multipleParcels[window.multipleParcels.length - 1];
2726          if (last && last.properties) {
2727            var p4 = _pickAdaParselFromObj(last.properties);
2728            partsAda.push(p4.ada);
2729            partsParsel.push(p4.parsel);
2730            var slashM = _parseAdaParselSlashLabel(last.properties.AdaParsel || last.properties.adaParsel || last.properties.label);
2731            partsAda.push(slashM.ada);
2732            partsParsel.push(slashM.parsel);
2733          }
2734        }
2735      } catch (e) {}
2736      var bundle = _parcelValuesBundle();
2737      if (bundle) {
2738        var p0 = _pickAdaParselFromObj(bundle);
2739        partsAda.push(p0.ada);
2740        partsParsel.push(p0.parsel);
2741      }
2742      var p1 = _pickAdaParselFromObj(_pv());
2743      partsAda.push(p1.ada);
2744      partsParsel.push(p1.parsel);
2745      partsAda.push(_pickAdaParselFromObj(_props()).ada);
2746      partsParsel.push(_pickAdaParselFromObj(_props()).parsel);
2747      var polyProps = _parcelPolygonFeatureProps();
2748      if (polyProps) {
2749        var pPoly = _pickAdaParselFromObj(polyProps);
2750        partsAda.push(pPoly.ada);
2751        partsParsel.push(pPoly.parsel);
2752        var slashP = _parseAdaParselSlashLabel(polyProps.AdaParsel || polyProps.adaParsel || polyProps.label);
2753        partsAda.push(slashP.ada);
2754        partsParsel.push(slashP.parsel);
2755        var ozP = _parseAdaParselFromOzet(polyProps.ozet || polyProps.Ozet);
2756        partsAda.push(ozP.ada);
2757        partsParsel.push(ozP.parsel);
2758      }
2759      try {
2760        var root = _responseRoot();
2761        var pd = root && root.parameters_data;
2762        if (pd && pd.parcel && typeof pd.parcel === 'object') {
2763          var pParcel = _pickAdaParselFromObj(pd.parcel);
2764          partsAda.push(pParcel.ada);
2765          partsParsel.push(pParcel.parsel);
2766        }
2767        if (root && root.parcel && typeof root.parcel === 'object') {
2768          var pRoot = _pickAdaParselFromObj(root.parcel);
2769          partsAda.push(pRoot.ada);
2770          partsParsel.push(pRoot.parsel);
2771        }
2772      } catch (e2) {}
2773      var adaOut = firstParcelPart(partsAda);
2774      var parselOut = firstParcelPart(partsParsel);
2775      try {
2776        var pr = _props();
2777        var pvOz = _pv();
2778        var ozPr = _parseAdaParselFromOzet((pr && (pr.ozet || pr.Ozet)) || (pvOz && (pvOz.ozet || pvOz.Ozet)));
2779        if (!parcelPartFilled(adaOut) && parcelPartFilled(ozPr.ada)) adaOut = ozPr.ada;
2780        if (!parcelPartFilled(parselOut) && parcelPartFilled(ozPr.parsel)) parselOut = ozPr.parsel;
2781      } catch (eOz) {}
2782      /* TKGM çoğu kaynakta adaNo "" döner; parsel tek başına geçerliyse ada=0 (tapu/TKGM uyumu) */
2783      if (!parcelPartFilled(adaOut) && parcelPartFilled(parselOut)) {
2784        adaOut = '0';
2785      }
2786      return { ada: adaOut, parsel: parselOut };
2787    }
2788    window.build3dEditorUrlFromParcel = function () {
2789      var m = resolveMahalleTkgm();
2790      var ap = resolveAdaParsel();
2791      var editorQs = [];
2792      /* mahalle TKGM yokken bile ada/parsel taşınmalı (lisans sayfası GET ile dolar) */
2793      if (parcelPartFilled(m)) {
2794        editorQs.push('mahalle=' + encodeURIComponent(m));
2795      }
2796      if (parcelPartFilled(ap.ada) && parcelPartFilled(ap.parsel)) {
2797        editorQs.push('ada=' + encodeURIComponent(ap.ada));
2798        editorQs.push('parsel=' + encodeURIComponent(ap.parsel));
2799      }
2800      var ilEl = document.getElementById('il-select');
2801      var ilceEl = document.getElementById('ilce-select');
2802      var mhEl = document.getElementById('mahalle-select');
2803      if (ilEl && ilEl.value) editorQs.push('city_id=' + encodeURIComponent(ilEl.value));
2804      if (ilceEl && ilceEl.value) editorQs.push('town_id=' + encodeURIComponent(ilceEl.value));
2805      if (mhEl && mhEl.value) editorQs.push('quarter_id=' + encodeURIComponent(mhEl.value));
2806      return editorQs.length ? '/3d-editor/?' + editorQs.join('&') : '/3d-editor/';
2807    };
2808    function bindToolbar3dLink() {
2809      var a = document.getElementById('pp-3d-editor-toolbar-link');
2810      if (!a) return;
2811      a.addEventListener('click', function () {
2812        a.href = window.build3dEditorUrlFromParcel();
2813      });
2814    }
2815    /** Ekranda çizili / seçili parsel var mı (çoklu veya tek parsel poligonu). */
2816    window.ppHasParcelDrawableOnMap = function ppHasParcelDrawableOnMap() {
2817      try {
2818        if (window.multipleParcels && window.multipleParcels.length > 0) return true;
2819      } catch (e0) {}
2820      try {
2821        var d = window.lastParcelResponse || window.data_general;
2822        var fc = d && d.parameters_polygons && d.parameters_polygons.parcel_polygon;
2823        if (fc && fc.features && fc.features.length > 0) return true;
2824      } catch (e1) {}
2825      try {
2826        var m = resolveMahalleTkgm();
2827        var ap = resolveAdaParsel();
2828        if (parcelPartFilled(m) && parcelPartFilled(ap.ada) && parcelPartFilled(ap.parsel)) return true;
2829      } catch (e2) {}
2830      return false;
2831    }
2832    window.buildAiDroneVideoPurchaseUrlFromParcel = function () {
2833      var ilEl = document.getElementById('il-select');
2834      var ilceEl = document.getElementById('ilce-select');
2835      var mhEl = document.getElementById('mahalle-select');
2836      var adaEl = document.getElementById('ada-input');
2837      var parselEl = document.getElementById('parsel-input');
2838      // ÖNCELİK: Son başarılı sorgu yanıtındaki gerçek mahalleId (parsel bilgi kartında görünen).
2839      // Kaynak sırası: lastTkgmData.properties → lastParcelResponse.properties →
2840      // lastParcelResponse.parameters_data.parcel_values → globalLayers parcel feature →
2841      // dropdown data-tkgmvalue.
2842      function pickStr(o, keys) {
2843        if (!o || typeof o !== 'object') return '';
2844        for (var i = 0; i < keys.length; i++) {
2845          var v = o[keys[i]];
2846          if (v != null && String(v).trim() !== '' && String(v).trim() !== 'null' && String(v).trim() !== 'undefined') {
2847            return String(v).trim();
2848          }
2849        }
2850        return '';
2851      }
2852      var diag = { sources: [] };
2853      var m = '';
2854      var ap = { ada: '', parsel: '' };
2855      var tkgmKeys = ['mahalleId', 'mahalle_id', 'mahalle_tkgm_value', 'tkgm_value', 'MahalleId'];
2856      var adaKeys = ['adaNo', 'Ada', 'ada', 'ada_no'];
2857      var parselKeys = ['parselNo', 'Parsel', 'parsel', 'parsel_no'];
2858      function tryFill(label, obj) {
2859        if (!obj || typeof obj !== 'object') return;
2860        diag.sources.push(label);
2861        if (!m) m = pickStr(obj, tkgmKeys);
2862        if (!ap.ada) ap.ada = pickStr(obj, adaKeys);
2863        if (!ap.parsel) ap.parsel = pickStr(obj, parselKeys);
2864      }
2865      try { tryFill('lastTkgmData.properties', window.lastTkgmData && window.lastTkgmData.properties); } catch (e) {}
2866      try { tryFill('lastParcelResponse.properties', window.lastParcelResponse && window.lastParcelResponse.properties); } catch (e) {}
2867      try { tryFill('lastParcelResponse.parameters_data.parcel_values', window.lastParcelResponse && window.lastParcelResponse.parameters_data && window.lastParcelResponse.parameters_data.parcel_values); } catch (e) {}
2868      try { tryFill('data_general.properties', window.data_general && window.data_general.properties); } catch (e) {}
2869      try { tryFill('data_general.parameters_data.parcel_values', window.data_general && window.data_general.parameters_data && window.data_general.parameters_data.parcel_values); } catch (e) {}
2870      try {
2871        var glProps = window.globalLayers && window.globalLayers['parcel_polygon'] && window.globalLayers['parcel_polygon'].properties;
2872        tryFill('globalLayers.parcel_polygon.properties', glProps);
2873      } catch (e) {}
2874      try {
2875        var ppFc = window.lastParcelResponse && window.lastParcelResponse.parameters_polygons && window.lastParcelResponse.parameters_polygons.parcel_polygon;
2876        var firstFeat = ppFc && ppFc.features && ppFc.features[0] && ppFc.features[0].properties;
2877        tryFill('lastParcelResponse.parameters_polygons.parcel_polygon[0].properties', firstFeat);
2878      } catch (e) {}
2879      var dropdownTkgm = '';
2880      try {
2881        if (mhEl && mhEl.selectedOptions && mhEl.selectedOptions.length) {
2882          dropdownTkgm = mhEl.selectedOptions[0].getAttribute('data-tkgmvalue') || '';
2883        }
2884      } catch (eDd) {}
2885      if (!m && dropdownTkgm) m = String(dropdownTkgm).trim();
2886      if (!ap.ada && adaEl) ap.ada = String(adaEl.value || '').trim();
2887      if (!ap.parsel && parselEl) ap.parsel = String(parselEl.value || '').trim();
2888      diag.resolved = { mahalleTkgm: m, ada: ap.ada, parsel: ap.parsel, dropdownTkgm: dropdownTkgm };
2889      try { console.info('[buildAiDroneVideoPurchaseUrl] resolved', diag); } catch (e) {}
2890      // Admin ID'ler (city_id/town_id/quarter_id) kullanıcının dropdown'dan seçtiği
2891      // proparcel admin DB ID'leri; bunlar TKGM mahalleId'den bağımsız ve hep doğru.
2892      // Resolver canonical mahalleId'yi dropdown'dakinden farklı belirleyebilir
2893      // (örn. "Öksülü Mh." → dropdown 156936, canonical 156978) — bu durum admin
2894      // ID'lerin doğruluğunu etkilemez. ÖNCE GÖNDERMEMEK satın alma sayfasını
2895      // O(N×M×K) prefill loop'una düşürüp yüzlerce gereksiz quarters/?TownId=
2896      // isteği yapmasına neden oluyordu. Bu yüzden adminIdsTrusted koşulunu
2897      // kaldırıyoruz — admin ID'ler ne olursa olsun gönderilmeli.
2898      var editorQs = [];
2899      if (parcelPartFilled(m)) {
2900        editorQs.push('mahalle=' + encodeURIComponent(m));
2901      }
2902      if (parcelPartFilled(ap.ada) && parcelPartFilled(ap.parsel)) {
2903        editorQs.push('ada=' + encodeURIComponent(ap.ada));
2904        editorQs.push('parsel=' + encodeURIComponent(ap.parsel));
2905      }
2906      // Görünen mahalle / il / ilçe adları (TKGM id yerine isim)
2907      var mahalleName = '';
2908      try {
2909        var propsName =
2910          (window.lastTkgmData && window.lastTkgmData.properties) ||
2911          (window.lastParcelResponse && window.lastParcelResponse.properties) ||
2912          {};
2913        mahalleName = String(propsName.mahalleAd || propsName.mahalle || '').trim();
2914        var cityName = String(propsName.ilAd || propsName.il_ad || '').trim();
2915        var districtName = String(propsName.ilceAd || propsName.ilce_ad || '').trim();
2916        if (!mahalleName && mhEl && mhEl.selectedOptions && mhEl.selectedOptions.length) {
2917          mahalleName = String(mhEl.selectedOptions[0].textContent || '').trim();
2918        }
2919        if (!cityName && ilEl && ilEl.selectedOptions && ilEl.selectedOptions.length) {
2920          cityName = String(ilEl.selectedOptions[0].textContent || '').trim();
2921        }
2922        if (!districtName && ilceEl && ilceEl.selectedOptions && ilceEl.selectedOptions.length) {
2923          districtName = String(ilceEl.selectedOptions[0].textContent || '').trim();
2924        }
2925        if (mahalleName) editorQs.push('mahalle_name=' + encodeURIComponent(mahalleName));
2926        if (cityName) editorQs.push('city=' + encodeURIComponent(cityName));
2927        if (districtName) editorQs.push('district=' + encodeURIComponent(districtName));
2928      } catch (eName) {}
2929      if (ilEl && ilEl.value) editorQs.push('city_id=' + encodeURIComponent(ilEl.value));
2930      if (ilceEl && ilceEl.value) editorQs.push('town_id=' + encodeURIComponent(ilceEl.value));
2931      if (mhEl && mhEl.value) editorQs.push('quarter_id=' + encodeURIComponent(mhEl.value));
2932      try {
2933        var pv =
2934          (mhEl && mhEl.selectedOptions && mhEl.selectedOptions[0] && mhEl.selectedOptions[0].getAttribute('data-proparcel')) ||
2935          (mhEl && mhEl.value) ||
2936          '';
2937        if (pv) editorQs.push('proparcel_value=' + encodeURIComponent(String(pv).trim()));
2938      } catch (ePv) {}
2939      var areaM2 = resolveParcelAreaM2();
2940      if (areaM2) editorQs.push('parcel_area=' + encodeURIComponent(areaM2));
2941      editorQs.push('fresh_map_start=1');
2942      editorQs.push('v=' + encodeURIComponent(String(Date.now())));
2943      var dronePath = editorQs.length ? '/portal/ai-drone/?' + editorQs.join('&') : '/portal/ai-drone/';
2944      var purchaseQs = ['next=' + encodeURIComponent(dronePath), 'target=drone_video'];
2945      if (parcelPartFilled(m)) {
2946        purchaseQs.push('mahalle=' + encodeURIComponent(m));
2947      }
2948      if (parcelPartFilled(ap.ada) && parcelPartFilled(ap.parsel)) {
2949        purchaseQs.push('ada=' + encodeURIComponent(ap.ada));
2950        purchaseQs.push('parsel=' + encodeURIComponent(ap.parsel));
2951      }
2952      if (mahalleName) purchaseQs.push('mahalle_name=' + encodeURIComponent(mahalleName));
2953      try {
2954        if (cityName) purchaseQs.push('city=' + encodeURIComponent(cityName));
2955        if (districtName) purchaseQs.push('district=' + encodeURIComponent(districtName));
2956      } catch (eBuy) {}
2957      if (ilEl && ilEl.value) purchaseQs.push('city_id=' + encodeURIComponent(ilEl.value));
2958      if (ilceEl && ilceEl.value) purchaseQs.push('town_id=' + encodeURIComponent(ilceEl.value));
2959      if (mhEl && mhEl.value) purchaseQs.push('quarter_id=' + encodeURIComponent(mhEl.value));
2960      if (areaM2) purchaseQs.push('parcel_area=' + encodeURIComponent(areaM2));
2961      return '/accounts/3d-editor-purchase/?' + purchaseQs.join('&');
2962    };
2963    function bindAiDroneVideoToolbarBtn() {
2964      var btn = document.getElementById('pp-ai-drone-video-btn');
2965      if (!btn) return;
2966      btn.addEventListener('click', function () {
2967        if (btn.getAttribute('data-pp-webgl-blocked') === '1' || btn.getAttribute('aria-disabled') === 'true') {
2968          return;
2969        }
2970        if (!ppHasParcelDrawableOnMap()) {
2971          alert('Önce haritada parsel seçin veya parsel sorgusu yapın.');
2972          return;
2973        }
2974        window.location.href = window.buildAiDroneVideoPurchaseUrlFromParcel();
2975      });
2976    }
2977    if (document.readyState === 'loading') {
2978      document.addEventListener('DOMContentLoaded', bindToolbar3dLink);
2979      document.addEventListener('DOMContentLoaded', bindAiDroneVideoToolbarBtn);
2980    } else {
2981      bindToolbar3dLink();
2982      bindAiDroneVideoToolbarBtn();
2983    }
2984  })();
2985  </script>
2985
2986  
2987  <!-- MAIN CONTENT -->
2988  <main class="pp-main" id="main-content">
2989    <!-- HARİTA ALANI -->
2990    <div class="pp-map-container" id="mapArea">
2991      <!-- Map container (Mapbox GL JS used for both 2D(flat) and 3D) -->
2992      <div class="pp-map" id="map3D">
2993        <div id="pp-static-map-backdrop" aria-hidden="true" style="position:absolute;inset:0;z-index:1;background:#93c5fd;background-image:radial-gradient(circle at 18% 24%, rgba(34,197,94,.58) 0 9%, transparent 10%),radial-gradient(circle at 78% 34%, rgba(34,197,94,.52) 0 13%, transparent 14%),radial-gradient(circle at 42% 72%, rgba(34,197,94,.45) 0 16%, transparent 17%),linear-gradient(135deg,#bfdbfe 0%,#93c5fd 46%,#60a5fa 100%);">
2994          <div style="position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);padding:10px 14px;border-radius:999px;background:rgba(15,23,42,.78);color:#fff;font:600 14px Arial,sans-serif;white-space:nowrap;">2D uydu harita yükleniyor...</div>
2995        </div>
2996        <iframe
2997          id="pp-static-leaflet-fallback"
2998          title="Uydu 2D Harita"
2999          srcdoc="<!doctype html><html><head><meta charset='utf-8'><meta name='viewport' content='width=device-width,initial-scale=1'><link rel='stylesheet' href='https://unpkg.com/[email protected]/dist/leaflet.css'><style>html,body,#map{margin:0;width:100%;height:100%;background:#e5e7eb}body:before{content:'Uydu harita yükleniyor...';position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font:14px Arial,sans-serif;color:#475569;z-index:0}#map{position:relative;z-index:1}</style></head><body><div id='map'></div>
2999<script src='https://unpkg.com/[email protected]/dist/leaflet.js'><\/script>
2999<script>(function(){try{var map=L.map('map',{zoomControl:true,attributionControl:true,preferCanvas:true}).setView([39,35],6);L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',{maxZoom:19,attribution:'Tiles &copy; Esri'}).addTo(map);map.on('click',function(e){try{parent.postMessage({type:'PP_STATIC_LEAFLET_FALLBACK_CLICK',lat:e.latlng.lat,lng:e.latlng.lng},'*')}catch(_){}});setTimeout(function(){try{map.invalidateSize()}catch(_){}} ,100)}catch(e){document.body.innerHTML='<div style=&quot;padding:24px;font:14px Arial,sans-serif;color:#334155;background:#e5e7eb;height:100%;box-sizing:border-box;&quot;>2D uydu harita başlatılamadı.</div>'}})();<\/script></body></html>"
3000          style="position:absolute;inset:0;width:100%;height:100%;border:0;background:#e5e7eb;z-index:2;"
3001          loading="eager"
3002          referrerpolicy="no-referrer-when-downgrade"
3003        ></iframe>
3004        <div id="pp-static-satellite-tiles" aria-hidden="true" style="position:absolute;inset:0;z-index:3;pointer-events:none;background:#1f2937;overflow:hidden;">
3005          <img alt="" src="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/6/23/37" style="position:absolute;left:0;top:0;width:50%;height:50%;object-fit:cover;">
3006          <img alt="" src="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/6/23/38" style="position:absolute;left:50%;top:0;width:50%;height:50%;object-fit:cover;">
3007          <img alt="" src="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/6/24/37" style="position:absolute;left:0;top:50%;width:50%;height:50%;object-fit:cover;">
3008          <img alt="" src="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/6/24/38" style="position:absolute;left:50%;top:50%;width:50%;height:50%;object-fit:cover;">
3009          <div style="position:absolute;right:12px;bottom:10px;padding:5px 8px;border-radius:6px;background:rgba(15,23,42,.72);color:#fff;
3009font:12px Arial,sans-serif;">2D uydu harita</div>
3010        </div>
3011      </div>
3012      
3012<script>
3013        (function () {
3014          try {
3015            if (window.__PP_HIDE_STATIC_MAP_FALLBACK) {
3016              var fallbackIds = ['pp-static-map-backdrop', 'pp-static-leaflet-fallback', 'pp-static-satellite-tiles'];
3017              for (var f = 0; f < fallbackIds.length; f += 1) {
3018                var fallbackEl = document.getElementById(fallbackIds[f]);
3019                if (fallbackEl && fallbackEl.parentNode) fallbackEl.parentNode.removeChild(fallbackEl);
3020              }
3021            }
3022            if (!window.__PP_STATIC_LEAFLET_HIDE_BOUND) {
3023              window.__PP_STATIC_LEAFLET_HIDE_BOUND = true;
3024              window.addEventListener('message', function (event) {
3025                try {
3026                  var data = event && event.data;
3027                  if (!data || data.type !== 'PP_STATIC_LEAFLET_READY') return;
3028                  var staticTiles = document.getElementById('pp-static-satellite-tiles');
3029                  if (staticTiles) staticTiles.style.display = 'none';
3030                } catch (e) {}
3031              });
3032            }
3033            var loadingContainer = document.getElementById('loading-container');
3034            if (loadingContainer) loadingContainer.style.display = 'none';
3035            var loadingOverlay = document.getElementById('loading-overlay');
3036            if (loadingOverlay) loadingOverlay.style.display = 'none';
3037            var proLoader = document.getElementById('pp-loader-overlay');
3038            if (proLoader) proLoader.style.display = 'none';
3039            var proLoaderBg = document.getElementById('pp-loader-bg3d');
3040            if (proLoaderBg) proLoaderBg.style.display = 'none';
3041            var map3d = document.getElementById('map3D');
3042            if (map3d) {
3043              map3d.style.background = '#e5e7eb';
3044            }
3045            if (typeof window.__PP_INIT_LEGACY_LEAFLET_MAP === 'function') {
3046              window.__PP_INIT_LEGACY_LEAFLET_MAP();
3047            }
3048          } catch (e) {}
3049        })();
3050      </script>
3050
3051      
3052      
3052<script>
3053        window.__ppLoaderAutoShow = false;
3054        window.__PP_DISABLE_LOADER_WEBGL = false;
3055        window.__PP_FORCE_DISABLE_LOADER_WEBGL = false;
3056        window.__ppUseAnimatedLoader = false;
3057      </script>
3057
3058      
3059      <!-- City3D Statik Overlay (body sonuna taşındı) -->
3060      <!-- 3D Kamera Kontrol Paneli -->
3061      <div class="pp-camera-controls" id="cameraControlPanel">
3062        <div class="cam-dpad">
3063          <button id="turnerBtnLeft" class="cam-btn cam-turn-left 2dDisabled" title="Ters Döndür"><i
3064              class="fa fa-refresh"></i></button>
3065          <button class="cam-btn cam-up 2dDisabled" data-action="pitch-up" title="Yukarı"><i
3066              class="fa fa-chevron-up"></i></button>
3067          <button id="turnerBtnRight" class="cam-btn cam-turn-right 2dDisabled" title="Döndür"><i
3068              class="fa fa-refresh"></i></button>
3069
3070          <button class="cam-btn cam-left 2dDisabled" data-action="bearing-left" title="Sola"><i
3071              class="fa fa-chevron-left"></i></button>
3072          <div class="center-col">
3073            <button class="cam-btn cam-zoom-in 2dDisabled" data-action="zoom-in"
3074              title="Yakınlaştır"><span>+</span></button>
3075            <button class="cam-btn cam-zoom-out 2dDisabled" data-action="zoom-out"
3076              title="Uzaklaştır"><span>-</span></button>
3077          </div>
3078          <button class="cam-btn cam-right 2dDisabled" data-action="bearing-right" title="Sağa"><i
3079              class="fa fa-chevron-right"></i></button>
3080
3081          <button class="cam-btn cam-down 2dDisabled" data-action="pitch-down" title="Aşağı"><i
3082              class="fa fa-chevron-down"></i></button>
3083          <!-- Alt köşe butonları: Konum ve Tam Ekran (simetrik yerleşim) -->
3084          <button id="camGeolocateBtn" class="cam-btn cam-bottom-left" title="Konumuma Git" aria-label="Konumuma Git"><i
3085              class="fas fa-crosshairs" style="font-size:12px;"></i></button>
3086          <button id="camFullscreenBtn" class="cam-btn cam-bottom-right" title="Tam Ekran" aria-label="Tam Ekran"><i
3087              class="fa fa-expand" style="font-size:12px;"></i></button>
3088        </div>
3089      </div>
3090    </div>
3091
3092    <!-- Görüntü Al overlay (mobildeki gibi onay + fiyat) -->
3093    <div id="pp-capture-overlay" class="pp-capture-overlay" aria-hidden="true">
3094      <div class="pp-capture-overlay__mask" id="pp-capture-mask"></div>
3095      <div class="pp-capture-overlay__frame" id="pp-capture-frame"></div>
3096      <button type="button" class="pp-capture-overlay__cancel" id="pp-capture-cancel" aria-label="İptal">
3097        <i class="fas fa-times"></i>
3098        <span>İptal</span>
3099      </button>
3100      <div class="pp-capture-overlay__panel">
3101        <div class="pp-capture-overlay__price-title">Gönderide görünecek fiyat bilgisini giriniz.</div>
3102        <input type="text" class="pp-capture-overlay__price-input" id="pp-capture-price-input"
3103          placeholder="örn: 1.250.000" inputmode="numeric" autocomplete="off">
3104        <div class="pp-capture-overlay__meta">
3105          <div class="pp-capture-overlay__meta-item">
3106            <div class="pp-capture-overlay__meta-label">Birim Fiyat</div>
3107            <div class="pp-capture-overlay__meta-value" id="pp-capture-unit">-</div>
3108          </div>
3109          <div class="pp-capture-overlay__meta-item">
3110            <div class="pp-capture-overlay__meta-label">Alan</div>
3111            <div class="pp-capture-overlay__meta-value" id="pp-capture-area">-</div>
3112          </div>
3113          <div class="pp-capture-overlay__meta-item">
3114            <div class="pp-capture-overlay__meta-label">Toplam</div>
3115            <div class="pp-capture-overlay__meta-value" id="pp-capture-total">-</div>
3116          </div>
3117        </div>
3118        <div id="pp-capture-login-hint" class="pp-capture-overlay__login-hint" style="display:none;">
3119          Giriş yaparak coin kazanabilirsiniz.
3120        </div>
3121        <div class="pp-capture-overlay__buttons">
3122          <button type="button" class="pp-capture-overlay__btn pp-capture-overlay__btn--cancel" id="pp-capture-btn-cancel">İptal</button>
3123          <button type="button" class="pp-capture-overlay__btn pp-capture-overlay__btn--confirm" id="pp-capture-btn-confirm">
3124            <i class="fas fa-check"></i>
3125            Onayla
3126          </button>
3127        </div>
3128      </div>
3129      <div class="pp-capture-overlay__loading" id="pp-capture-loading">
3130        <div class="pp-capture-overlay__loading-inner">
3131          <div class="spinner-border text-light" role="status" aria-label="Yükleniyor"></div>
3132          <div>Ekran Görüntüsü Hazırlanıyor</div>
3133        </div>
3134      </div>
3135    </div>
3136  </main>
3137
3138
3139
3140  <!-- HARITA ALTI İÇERİK KONTEYNER -->
3141  <div id="below-map-content" class="below-map-container">
3142    <!-- Harita ve alt content arası boşluk -->
3143    <div style="height: 20px;"></div>
3144
3145    <!-- Küçük mini yükleniyor kutusu -->
3146    <div id="map-loading-toast">
3147      <div class="map-toast-inner">
3148        <div class="spinner-border spinner-border-sm text-light" role="status"></div>
3149        <span class="ms-2">Parsel sorgulanıyor...</span>
3150      </div>
3151    </div>
3152
3153
3154
3155    <!-- Gizli info paneli -->
3156    <div id="info" style="display:none;">
3157      <h2>Parsel Bilgileri</h2>
3158      <p id="parcel_info">Parsel bilgileri burada görünecek...</p>
3159
3160
3161    </div>
3162
3163    <style>
3164      .info-card {
3165        transition: box-shadow 0.2s;
3166      }
3167
3168      .info-card:hover {
3169        box-shadow: 0 4px 16px rgba(0, 0, 0, 0.13);
3170        z-index: 2;
3171      }
3172
3173      /* Index: bilgi kartında radius kaldır */
3174      #info {
3175        border-radius: 0 !important;
3176        display: none !important;
3177      }
3178
3179      /* Dikey başlık stilleri */
3180      .vertical-title {
3181        display: flex;
3182        flex-direction: column;
3183        align-items: center;
3184        justify-content: center;
3185        min-width: 80px;
3186        height: 120px;
3187        writing-mode: vertical-rl;
3188        text-orientation: mixed;
3189        transform: rotate(180deg);
3190        border-right: 2px solid #e0e0e0;
3191        padding-right: 15px;
3192      }
3193
3194      .vertical-title .title-text {
3195        font-weight: 600;
3196        font-size: 14px;
3197        color: #333;
3198        margin-bottom: 8px;
3199      }
3200
3201      .vertical-title .title-value {
3202        font-weight: bold;
3203        font-size: 16px;
3204        color: #1e3a8a;
3205        background: rgba(30, 58, 138, 0.1);
3206        padding: 4px 8px;
3207        border-radius: 6px;
3208        min-width: 50px;
3209        text-align: center;
3210      }
3211
3212      /* Yatay içerik stilleri */
3213      .horizontal-content {
3214        display: flex;
3215        flex-direction: column;
3216        justify-content: center;
3217        min-height: 120px;
3218      }
3219
3220      /* Kamera Paneli Stilleri */
3221      #cameraControlPanel .camera-grid {
3222        display: grid;
3223        grid-template-columns: 1fr auto 1fr;
3224        gap: 8px;
3225        justify-items: center;
3226        margin-bottom: 6px;
3227        background: rgba(20, 20, 20, 0.38);
3228        border: 1px solid rgba(255, 255, 255, 0.22);
3229        padding: 6px 8px;
3230        border-radius: 10px;
3231        backdrop-filter: blur(4px);
3232      }
3233
3234      /* D-Pad yerleşimi */
3235      #cameraControlPanel .cam-dpad {
3236        position: relative;
3237        width: 170px;
3238        height: 170px;
3239        background: rgba(20, 20, 20, 0.38);
3240        border: 1px solid rgba(255, 255, 255, 0.22);
3241        border-radius: 16px;
3242        backdrop-filter: blur(4px);
3243        display: grid;
3244        grid-template-rows: 1fr 1fr 1fr;
3245        grid-template-columns: 1fr 1fr 1fr;
3246        align-items: center;
3247        justify-items: center;
3248        gap: 6px;
3249        padding: 10px;
3250      }
3251
3252      #cameraControlPanel .center-col {
3253        grid-row: 2;
3254        grid-column: 2;
3255        display: grid;
3256        gap: 6px;
3257      }
3258
3259      #cameraControlPanel .cam-up {
3260        grid-row: 1;
3261        grid-column: 2;
3262      }
3263
3264      #cameraControlPanel .cam-down {
3265        grid-row: 3;
3266        grid-column: 2;
3267      }
3268
3269      #cameraControlPanel .cam-left {
3270        grid-row: 2;
3271        grid-column: 1;
3272      }
3273
3274      #cameraControlPanel .cam-right {
3275        grid-row: 2;
3276        grid-column: 3;
3277      }
3278
3279      #cameraControlPanel .cam-turn-left {
3280        grid-row: 1;
3281        grid-column: 1;
3282      }
3283
3284      #cameraControlPanel .cam-turn-right {
3285        grid-row: 1;
3286        grid-column: 3;
3287      }
3288
3289      #cameraControlPanel .cam-btn {
3290        width: 32px;
3291        height: 32px;
3292        border-radius: 8px;
3293        border: 1px solid rgba(255, 255, 255, 0.35);
3294        background: rgba(255, 255, 255, 0.22);
3295        color: #fff;
3296        display: flex;
3297        align-items: center;
3298        justify-content: center;
3299        cursor: pointer;
3300        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
3301        transition: transform 0.08s ease, background 0.2s ease;
3302        user-select: none;
3303      }
3304
3305      #cameraControlPanel .cam-btn:hover {
3306        background: rgba(255, 255, 255, 0.32);
3307      }
3308
3309      #cameraControlPanel .cam-btn:active {
3310        transform: scale(0.96);
3311      }
3312
3313      #cameraControlPanel .cam-bottom-left {
3314        grid-row: 3;
3315        grid-column: 1;
3316      }
3317
3318      #cameraControlPanel .cam-bottom-right {
3319        grid-row: 3;
3320        grid-column: 3;
3321      }
3322
3323      /* Tools toggle buttons equal width */
3324      .tools-toggle {
3325        width: 100%;
3326        display: inline-flex;
3327        align-items: center;
3328        gap: 8px;
3329        justify-content: flex-start;
3330      }
3331
3332      /* Smooth collapse containers */
3333      .collapse-container {
3334        display: none;
3335        overflow: hidden;
3336        max-height: 0;
3337        transition: max-height 260ms ease;
3338      }
3339    </style>
3340
3341  </div> <!-- below-map-content container end -->
3342  </div>
3343
3344  <!-- Sidebar Overlay kaldırıldı - haritaya tıklanabilmeli -->
3345  
3346  <!-- Sol Sidebar Paneli -->
3347  <aside id="sidebar" class="pp-sidebar sidebar">
3348    <!-- Sekme seçici — sidebar form alanlarıyla uyumlu dropdown -->
3349    <div class="pp-sidebar-tab-dropdown" id="pp-sidebar-tab-dropdown">
3350      <button type="button" class="pp-sidebar-tab-trigger" id="pp-sidebar-tab-trigger"
3351        aria-haspopup="listbox" aria-expanded="false" aria-controls="pp-sidebar-tab-menu">
3352        <span class="pp-sidebar-tab-trigger__icon" aria-hidden="true">
3353          <i class="fa fa-search"></i>
3354        </span>
3355        <span class="pp-sidebar-tab-trigger__text" data-role="label-text">Parsel Sorgula</span>
3356        <span class="pp-sidebar-tab-trigger__chevron" aria-hidden="true">
3357          <i class="fa fa-chevron-down"></i>
3358        </span>
3359      </button>
3360      <ul class="pp-sidebar-tab-menu" id="pp-sidebar-tab-menu" role="listbox"
3361        aria-label="Sorgu sekmeleri" hidden>
3362        <li class="active" data-tab="parsel-sorgu-tab" data-label="Parsel Sorgula" data-icon="fa-search"
3363          role="option" aria-selected="true">
3364          <span class="pp-sidebar-tab-item__icon"><i class="fa fa-search" aria-hidden="true"></i></span>
3365          <span class="pp-sidebar-tab-item__label">Parsel Sorgula</span>
3366          <span class="pp-sidebar-tab-item__check" aria-hidden="true"><i class="fa fa-check"></i></span>
3367        </li>
3368        <li data-tab="sorgularim-tab" data-label="Sorgularım" data-icon="fa-history"
3369          role="option" aria-selected="false">
3370          <span class="pp-sidebar-tab-item__icon"><i class="fa fa-history" aria-hidden="true"></i></span>
3371          <span class="pp-sidebar-tab-item__label">Sorgularım</span>
3372          <span class="pp-sidebar-tab-item__check" aria-hidden="true"><i class="fa fa-check"></i></span>
3373        </li>
3374        <li data-tab="akilli-sorgu-tab" data-label="Akıllı Sorgu" data-icon="fa-magic"
3375          role="option" aria-selected="false">
3376          <span class="pp-sidebar-tab-item__icon"><i class="fa fa-magic" aria-hidden="true"></i></span>
3377          <span class="pp-sidebar-tab-item__label">Akıllı Sorgu</span>
3378          <span class="pp-sidebar-tab-item__check" aria-hidden="true"><i class="fa fa-check"></i></span>
3379        </li>
3380      </ul>
3381    </div>
3382    
3382<script>
3383      (function () {
3384        var menu = document.getElementById('pp-sidebar-tab-menu');
3385        var wrap = document.getElementById('pp-sidebar-tab-dropdown');
3386        if (menu) { menu.setAttribute('hidden', ''); menu.style.display = 'none'; }
3387        if (wrap) wrap.classList.remove('is-open');
3388      })();
3389    </script>
3389
3390    
3391    <!-- Parsel Sorgu Sekmesi -->
3392    <div class="sidebar-tab-content active" id="parsel-sorgu-tab">
3393      <label for="il-select" class="visually-hidden">İl</label>
3394      <select class="form-select sidebar-select" id="il-select" aria-label="İl seçimi">
3395        <option>İl Seçiniz</option>
3396      </select>
3397      
3398      <label for="ilce-select" class="visually-hidden">İlçe</label>
3399      <select class="form-select sidebar-select" id="ilce-select" aria-label="İlçe seçimi">
3400        <option>İlçe Seçiniz</option>
3401      </select>
3402      
3403      <label for="mahalle-select" class="visually-hidden">Mahalle</label>
3404      <select class="form-select sidebar-select" id="mahalle-select" aria-label="Mahalle seçimi">
3405        <option>Mahalle Seçiniz</option>
3406      </select>
3407      
3408      <label for="ada-input" class="visually-hidden">Ada</label>
3409      <input class="form-control sidebar-input" type="text" placeholder="Ada" id="ada-input"
3410        aria-label="Ada numarası">
3411      
3412      <label for="parsel-input" class="visually-hidden">Parsel</label>
3413      <input class="form-control sidebar-input" type="text" placeholder="Parsel" id="parsel-input"
3414        aria-label="Parsel numarası">
3415      
3416      <div id="mahalle-proparcel-hint"
3417           style="min-height:16px; font-size:12px; color:#9ca3af;">
3418        <!-- Mahalle Proparcel değeri burada gri ve silik gösterilecek -->
3419      </div>
3420      
3421      <button id="parsel-sorgula-btn" class="btn btn-success w-100 sidebar-btn"
3422        onclick="simpleParselSorgula()">Sorgula</button>
3423      <button id="pro-parsel-sorgula-btn" class="btn btn-primary w-100 sidebar-btn"
3424        onclick="proParselSorgula()">ProSorgu</button>
3425      <button id="daire-sorgula-btn" class="btn btn-primary w-100 sidebar-btn"
3426        onclick="daireSorgula()">Daire Sorgula</button>
3427    </div>
3428
3429    <!-- Sorgularım Sekmesi -->
3430    <div class="sidebar-tab-content" id="sorgularim-tab">
3431      <div class="pp-sidebar-saved-queries">
3432        <div class="pp-sidebar-saved-queries__header">
3433          <strong>Sorgularım</strong>
3434          <span>Tarayıcıda saklanan son sorgular</span>
3435        </div>
3436        <div id="pp-sidebar-saved-query-list" class="pp-sidebar-saved-query-list" aria-live="polite">
3437          <div class="pp-sidebar-saved-query-empty">Henüz kayıtlı sorgu yok.</div>
3438        </div>
3439      </div>
3440    </div>
3441    
3442    <!-- Akıllı Sorgu sekmesi modal olarak açılır -->
3443
3444    <!-- Geri Bildirim Modalı -->
3445    <div class="modal fade" id="feedbackModal" tabindex="-1" aria-labelledby="feedbackModalLabel" aria-hidden="true">
3446      <div class="modal-dialog modal-dialog-centered">
3447        <div class="modal-content">
3448          <div class="modal-header">
3449            <h5 class="modal-title" id="feedbackModalLabel"><i class="fa fa-comment-dots me-2"></i>Geri Bildirim</h5>
3450            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Kapat"></button>
3451          </div>
3452          <div class="modal-body">
3453            <textarea class="form-control" id="feedbackText" rows="4"
3454              placeholder="Yanlış veya eksik gördüğünüz bilgiyi buraya yazın..."
3455              aria-label="Geri bildirim metni"></textarea>
3456          </div>
3457          <div class="modal-footer">
3458            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Vazgeç</button>
3459            <button type="button" class="btn btn-primary" id="sendFeedbackBtn">Gönder</button>
3460          </div>
3461        </div>
3462      </div>
3463    </div>
3464  </aside>
3465
3466
3467
3468
3469
3470  <!-- Auth Guard - Giriş yapmamış kullanıcı koruması (tüm JS'lerden ÖNCE yüklenmeli) -->
3471  
3471<script src="/static/js/app/ui/auth_guard.js?v=20260710-daire-sorgula"></script>
3471
3472  
3472<script src="/static/js/app/ui/feature_gate.js?v=20260708-sidebar-dropdown-v3"></script>
3472
3473  
3473<script src="/static/js/app/ui/dogrulama_toggle.js"></script>
3473
3474
3475  
3475<script src="/static/js/initialization/loading.js"></script>
3475
3476
3477  <!-- Parsel Kamera Yönetimi (Map Click Handler'dan önce yüklenmeli) -->
3478  
3478<script src="/static/js/app/camera/parcel_camera_manager.js?v=20260703-no-map-stop"></script>
3478
3479  
3480  <!-- Map Click Handler -->
3481  
3481<script src="/static/js/core/utils/locale_number_tr.js?v=20260826-modal-area"></script>
3481
3482  
3482<script src="/static/js/features/query/map_click.js?v=20260826-parcel-click"></script>
3482
3483
3484  <!-- Border Proximity Alert - CSS zaten head'de yüklü -->
3485
3486  
3486<script>
3487    window.ENABLE_SIM_TOGGLE_INIT = true;
3488    window.ENABLE_SIDEBAR_CLICK_DELEGATES = true;
3489    window.ENABLE_SEARCHABLE_SELECT = true;
3490  </script>
3490
3491  <!-- TKGM API direkt çağrı yardımcı fonksiyonları -->
3492  
3492<script src="/static/js/utils/tkgm_passive_parcel.js?v=20260523-passive-banner"></script>
3492
3493  
3493<script src="/static/js/utils/tkgm_api.js"></script>
3493
3494  
3494<script>
3495    // Basit/TKGM sorgu sonucunu sunucuya kaydet (kök: tkgm_click_results.json)
3496    window.persistTkgmClickResult = async function(payload) {
3497      try {
3498        const resp = await fetch('/api/save_tkgm_click_result/', {
3499          method: 'POST',
3500          headers: { 'Content-Type': 'application/json' },
3501          body: JSON.stringify(payload || {}),
3502          keepalive: true
3503        });
3504        if (!resp.ok) {
3505          let body = '';
3506          try { body = await resp.text(); } catch (_) {}
3507          console.warn('[persistTkgmClickResult] failed', resp.status, body);
3508        }
3509      } catch (_) {
3510        // Kullanıcı akışını bozmadan konsola bilgi ver
3511        console.warn('[persistTkgmClickResult] request error');
3512      }
3513    };
3514  </script>
3514
3515  <!-- Pro sorgu: ekran görüntüsü modülleri buton tıklanınca yüklenir. -->
3516  
3516<script>
3517    window.__ppLoadScriptOnce = window.__ppLoadScriptOnce || function(src, timeoutMs) {
3518      var limit = Math.max(2000, Number(timeoutMs) || 10000);
3519      return Promise.race([
3520        new Promise(function(resolve, reject) {
3521          try {
3522            var existing = document.querySelector('script[data-pp-src="' + src + '"]');
3523            if (existing) {
3524              if (existing.getAttribute('data-loaded') === '1') return resolve();
3525              existing.addEventListener('load', function() { resolve(); }, { once: true });
3526              existing.addEventListener('error', reject, { once: true });
3527              return;
3528            }
3529            var script = document.createElement('script');
3530            script.src = src;
3531            script.async = false;
3532            script.setAttribute('data-pp-src', src);
3533            script.onload = function() { script.setAttribute('data-loaded', '1'); resolve(); };
3534            script.onerror = reject;
3535            document.head.appendChild(script);
3536          } catch (e) {
3537            reject(e);
3538          }
3539        }),
3540        new Promise(function(_, reject) {
3541          setTimeout(function() { reject(new Error('SCRIPT_LOAD_TIMEOUT')); }, limit);
3542        })
3543      ]);
3544    };
3545    window.__ppShouldSkipProMapCanvasCapture = window.__ppShouldSkipProMapCanvasCapture || function() {
3546      try {
3547        if (window.__PP_SKIP_PRO_MAP_CAPTURE === true) return true;
3548        if (window.PPWebGLCompat && typeof window.PPWebGLCompat.supports === 'function') {
3549          return !window.PPWebGLCompat.supports('heavy_animation');
3550        }
3551      } catch (e) {}
3552      return window.__PP_GPU_MODE === 'minimal_gpu' || window.__PP_GPU_MODE === 'no_gpu';
3553    };
3554    window.__ppShouldSkipProMapCapture = window.__ppShouldSkipProMapCanvasCapture;
3555    async function __ppStaticMapCaptureDataUrl(parcelGeometry) {
3556      if (!parcelGeometry) return null;
3557      try {
3558        if (!window.PPStaticMapCapture) {
3559          await window.__ppLoadScriptOnce('/static/js/reports/static_map_capture.js?v=20260601-red-parcel', 8000);
3560        }
3561        if (window.PPStaticMapCapture && typeof window.PPStaticMapCapture.fetchDataUrl === 'function') {
3562          return await window.PPStaticMapCapture.fetchDataUrl(parcelGeometry);
3563        }
3564      } catch (e) {
3565        console.warn('[ProParcel] Static map capture hatası:', e);
3566      }
3567      return null;
3568    }
3569    window.__ppCaptureIndexMapForProQuery = window.__ppCaptureIndexMapForProQuery || async function(options) {
3570      options = options || {};
3571      var timeoutMs = Math.max(1200, Number(options.timeoutMs) || 4500);
3572      var skipCanvas = window.__ppShouldSkipProMapCanvasCapture && window.__ppShouldSkipProMapCanvasCapture();
3573      var captured = null;
3574      try {
3575        if (!skipCanvas) {
3576          if (!window.PPIndexMapCapture && typeof window.__ppEnsureCaptureModules === 'function') {
3577            await Promise.race([
3578              window.__ppEnsureCaptureModules(),
3579              new Promise(function(_, reject) { setTimeout(function() { reject(new Error('capture_modules_timeout')); }, 4000); })
3580            ]);
3581          }
3582          if (window.PPIndexMapCapture && typeof window.PPIndexMapCapture.captureIndexMap === 'function') {
3583            captured = await Promise.race([
3584              window.PPIndexMapCapture.captureIndexMap({
3585                cleanCapture: true,
3586                fastCapture: true,
3587                parcelGeometry: options.parcelGeometry || null,
3588                parcelLabel: options.parcelLabel || ''
3589              }),
3590              new Promise(function(resolve) { setTimeout(function() { resolve(null); }, timeoutMs); })
3591            ]);
3592          }
3593        }
3594        if (!captured && options.parcelGeometry) {
3595          captured = await __ppStaticMapCaptureDataUrl(options.parcelGeometry);
3596        }
3597        return captured;
3598      } catch (e) {
3599        console.warn('[ProParcel] Pro sorgu harita capture hatası:', e);
3600        if (!captured && options.parcelGeometry) {
3601          try { return await __ppStaticMapCaptureDataUrl(options.parcelGeometry); } catch (_) {}
3602        }
3603        return null;
3604      }
3605    };
3606    window.__ppEnsureCaptureModules = window.__ppEnsureCaptureModules || async function() {
3607      if (typeof window.ppCaptureOverlayOpen === 'function' && window.PPIndexMapCapture) return;
3608      var skipHeavy = window.__ppShouldSkipProMapCanvasCapture && window.__ppShouldSkipProMapCanvasCapture();
3609      if (!skipHeavy && typeof window.html2canvas !== 'function') {
3610        await window.__ppLoadScriptOnce('https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js', 8000);
3611      }
3612      await window.__ppLoadScriptOnce('/static/js/reports/static_map_capture.js?v=20260601-red-parcel', 8000);
3613      await window.__ppLoadScriptOnce('/static/js/reports/index_map_capture.js?v=20260808-area-parse', 8000);
3614      await window.__ppLoadScriptOnce('/static/js/components/capture_overlay_modal.js?v=20260808-area-parse', 8000);
3615    };
3616    window.ppPositionCaptureMenu = function() {
3617      try {
3618        var wrap = document.getElementById('pp-capture-menu-wrap');
3619        var btn = document.getElementById('pp-screenshot-map-btn');
3620        var menu = document.getElementById('pp-capture-menu');
3621        if (!menu || !menu.classList.contains('open')) return;
3622        var anchor = btn || wrap;
3623        if (!anchor) return;
3624        var rect = anchor.getBoundingClientRect();
3625        var menuWidth = menu.offsetWidth || 170;
3626        var vpW = window.innerWidth || document.documentElement.clientWidth || 0;
3627        var edgePad = 12;
3628        var left = rect.right - menuWidth;
3629        left = Math.max(edgePad, Math.min(left, vpW - menuWidth - edgePad));
3630        menu.style.top = Math.round(rect.bottom + 8) + 'px';
3631        menu.style.left = Math.round(left) + 'px';
3632      } catch (e) { console.warn('[ppPositionCaptureMenu]', e); }
3633    };
3634    window.ppToggleCaptureMenu = function(event) {
3635      try {
3636        if (event) {
3637          event.preventDefault();
3638          event.stopPropagation();
3639        }
3640        var menu = document.getElementById('pp-capture-menu');
3641        if (!menu) return;
3642        menu.classList.toggle('open');
3643        if (menu.classList.contains('open')) {
3644          window.ppPositionCaptureMenu();
3645        }
3646      } catch (e) { console.warn('[ppToggleCaptureMenu]', e); }
3647    };
3648    if (!window.__ppCaptureMenuPositionBound) {
3649      window.__ppCaptureMenuPositionBound = true;
3650      var ppRepositionCaptureMenu = function() {
3651        if (typeof window.ppPositionCaptureMenu === 'function') window.ppPositionCaptureMenu();
3652      };
3653      window.addEventListener('resize', ppRepositionCaptureMenu);
3654      window.addEventListener('scroll', ppRepositionCaptureMenu, true);
3655      document.addEventListener('DOMContentLoaded', function() {
3656        var extras = document.getElementById('pp-toolbar-extras');
3657        if (extras) extras.addEventListener('scroll', ppRepositionCaptureMenu, { passive: true });
3658      });
3659    }
3660    document.addEventListener('click', function(e) {
3661      try {
3662        var wrap = document.getElementById('pp-capture-menu-wrap');
3663        var menu = document.getElementById('pp-capture-menu');
3664        if (wrap && menu && !wrap.contains(e.target) && !menu.contains(e.target)) {
3665          menu.classList.remove('open');
3666        }
3667      } catch (_) {}
3668    });
3669    window.ppCaptureAndDownloadMap = async function(orientation) {
3670      try {
3671        var menu = document.getElementById('pp-capture-menu');
3672        if (menu) menu.classList.remove('open');
3673        if (typeof window.__ppEnsureCaptureModules === 'function') {
3674          await window.__ppEnsureCaptureModules();
3675        }
3676        if (typeof window.ppCaptureOverlayOpen === 'function') {
3677          window.ppCaptureOverlayOpen(orientation || 'horizontal');
3678        } else {
3679          console.warn('[ppCaptureAndDownloadMap] ppCaptureOverlayOpen yüklenmedi');
3680        }
3681      } catch (e) { console.warn('[ppCaptureAndDownloadMap]', e); }
3682    };
3683  </script>
3683
3684  
3684<script src="/static/js/initialization/alerts_and_copy.js?v=20260604-toast-fix"></script>
3684
3685  
3685<script src="/static/js/app/pp_clear_pro_query_globals.js?v=20260605-query-isolation"></script>
3685
3686  
3686<script src="/static/js/initialization/sidebar_and_forms.js?v=20260815-tkgm-alan"></script>
3686
3687  
3687<script src="/static/js/initialization/parcel_query_buttons_sync.js?v=20260531-ada-parsel-btn"></script>
3687
3688  
3688<script src="/static/js/initialization/menu_bar.js?v=20260815-kentsel"></script>
3688
3689  
3689<script src="/static/js/initialization/toolbar_extras_toggle.js"></script>
3689
3690  
3690<script src="/static/js/initialization/toolbar_extras_auth_gate.js?v=20260518-2"></script>
3690
3691  
3691<script src="/static/js/initialization/bina_ciz_toolbar.js?v=20260819-lonlat"></script>
3691
3692  
3692<script src="/static/js/initialization/geolocation.js?v=20260703-no-map-stop"></script>
3692
3693
3694  <!-- Başlangıç koruması -->
3695  
3695<script src="/static/js/initialization/boot_guard.js"></script>
3695
3696  
3697  <!-- Modern Layout Manager (YENİ) -->
3698  
3698<script src="/static/js/layout/layout_manager.js"></script>
3698
3699
3700  <!-- Bootstrap JS -->
3701  
3701<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
3701
3702  
3703  
3704  <!-- Plotly - Lazy Load (sadece ihtiyaç duyulduğunda yüklenir) -->
3705  
3705<script src="/static/js/core/utils/plotly_loader.js"></script>
3705
3706
3707  <!-- Core Modules (kademeli yeniden etkinleştirme) -->
3708  
3708<script src="/static/js/initialization/mapbox_gl_init.js"></script>
3708
3709  
3709<script>
3710    (function () {
3711      if (window.__PP_SKIP_MAPBOX_GL || window.__PP_EARLY_WEBGL_DISABLED || window.__PP_ALLOW_MAPBOX_GL === false) return;
3712      document.write('
3712<script src="https://api.mapbox.com/mapbox-gl-js/v3.2.0/mapbox-gl.js"><\/script>');
3713    })();
3714  </script>
3714
3715  
3715<script>
3716    (function () {
3717      var shouldLoadLeaflet = window.__PP_GPU_MODE === 'no_gpu' ||
3718        !!(window.__PP_SKIP_MAPBOX_GL || window.__PP_EARLY_WEBGL_DISABLED || window.__PP_ALLOW_MAPBOX_GL === false);
3719      try {
3720        shouldLoadLeaflet = shouldLoadLeaflet || /(?:\?|&)(pp_force_legacy_map|pp_leaflet_only|pp_skip_mapbox)=1(?:&|$)/.test(window.location.search || '');
3721      } catch (e) {}
3722      if (shouldLoadLeaflet) {
3723        document.write('
3723<script src="https://unpkg.com/[email protected]/dist/leaflet.js"><\/script>');
3724      }
3725    })();
3726  </script>
3726
3727  
3727<script src="/static/js/core/map/webgl_compat_guard.js?v=20260711-loader-webgl-guard"></script>
3727
3728  
3728<script src="/static/js/core/map/map_runtime.js?v=20260706-parcel-style"></script>
3728
3729  
3729<script>
3730    (function () {
3731      var shouldInit = window.__PP_GPU_MODE === 'no_gpu' ||
3732        !!(window.__PP_SKIP_MAPBOX_GL || window.__PP_EARLY_WEBGL_DISABLED || window.__PP_ALLOW_MAPBOX_GL === false);
3733      try {
3734        shouldInit = shouldInit || /(?:\?|&)(pp_force_legacy_map|pp_leaflet_only|pp_skip_mapbox)=1(?:&|$)/.test(window.location.search || '');
3735      } catch (e) {}
3736      if (!shouldInit) return;
3737      if (!window.L || typeof window.L.map !== 'function') return;
3738
3739      function initLegacyLeafletMap() {
3740        var container = document.getElementById('map3D');
3741        if (!container || container.getAttribute('data-pp-legacy-leaflet-ready') === '1') {
3742          return window.__PP_LEGACY_LEAFLET_MAP || null;
3743        }
3744        try {
3745          container.innerHTML = '';
3746          container.style.display = 'block';
3747          container.style.position = 'relative';
3748          container.style.width = '100%';
3749          container.style.height = '100%';
3750          container.style.background = '#e5e7eb';
3751          container.className += ' pp-leaflet-2d-fallback';
3752
3753          var map = window.L.map(container, {
3754            zoomControl: true,
3755            attributionControl: true,
3756            preferCanvas: true,
3757            worldCopyJump: true
3758          }).setView([39.0, 35.0], 6);
3759
3760          window.L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
3761            maxZoom: 19,
3762            attribution: 'Tiles &copy; Esri, Maxar, Earthstar Geographics, and the GIS User Community'
3763          }).addTo(map);
3764
3765          map.on('click', function (event) {
3766            try {
3767              if (!window.enableMapClick || !window.proParcelApp || typeof window.proParcelApp.handleMapClick !== 'function') return;
3768              if (!event || !event.latlng) return;
3769              window.proParcelApp.handleMapClick.call(window.proParcelApp, {
3770                lngLat: { lng: event.latlng.lng, lat: event.latlng.lat },
3771                originalEvent: event.originalEvent
3772              });
3773            } catch (e) {}
3774          });
3775
3776          window.__PP_LEGACY_LEAFLET_MAP = map;
3777          container.setAttribute('data-pp-legacy-leaflet-ready', '1');
3778          window.mapManager = window.mapManager || {
3779            maps: { leaflet2d: map },
3780            isInitialized: { leaflet2d: true },
3781            initialize3DMap: function () { return map; },
3782            getCurrentMap: function () { return map; },
3783            getMap: function () { return map; },
3784            isMapInitialized: function () { return true; },
3785            resizeAllMaps: function () { try { map.invalidateSize(); } catch (e) {} },
3786            drawParcelOn2DFallback: function (geometry, properties) {
3787              try {
3788                if (!geometry) return false;
3789                if (this._fallbackParcelLayer) map.removeLayer(this._fallbackParcelLayer);
3790                this._fallbackParcelLayer = window.L.geoJSON({ type: 'Feature', geometry: geometry, properties: properties || {} }, {
3791                  style: { color: '#D32F2F', weight: 3, fillColor: '#D32F2F', fillOpacity: 0.14 }
3792                }).addTo(map);
3793                map.fitBounds(this._fallbackParcelLayer.getBounds(), { padding: [40, 40] });
3794                return true;
3795              } catch (e) {
3796                return false;
3797              }
3798            }
3799          };
3800          try { setTimeout(function () { map.invalidateSize(); }, 100); } catch (e) {}
3801          try { if (typeof window.hideLoading === 'function') window.hideLoading(); } catch (e) {}
3802          return map;
3803        } catch (e) {
3804          return null;
3805        }
3806      }
3807
3808      initLegacyLeafletMap();
3809      if (document.readyState === 'loading') {
3810        document.addEventListener('DOMContentLoaded', initLegacyLeafletMap);
3811      }
3812    })();
3813  </script>
3813
3814  <!-- MapManager modüler çekirdek ve yardımcıları (MapManager.js'ten önce yüklenmeli) -->
3815  
3815<script src="/static/js/core/map/map_manager_core_v3.js?v=20260810-mode-overlay"></script>
3815
3816  
3816<script src="/static/js/core/map/map_manager_ui_v2.js?v=20260810-mode-overlay"></script>
3816
3817  
3817<script src="/static/js/core/map/map_manager_events_v2.js"></script>
3817
3818  <!-- Diğer core yardımcılar -->
3819  
3819<script src="/static/js/core/utils/coordinate_utils.js"></script>
3819
3820  
3820<script src="/static/js/core/utils/cursor_manager.js?v=20260704-tile-proxy-cursor"></script>
3820
3821  
3821<script src="/static/js/features/query/map_click_forwarder.js"></script>
3821
3822  
3822<script src="/static/js/features/query/parcel_info_modal.js?v=20260826-modal-area"></script>
3822
3823  
3823<script src="/static/js/core/layer/layer_manager.js"></script>
3823
3824  <!-- MapManager ana sınıf (global window.mapManager instance'ını oluşturur) -->
3825  
3825<script src="/static/js/core/map/map_manager_v2.js?v=20260810-mode-overlay"></script>
3825
3826  <!-- mapbox-renderer.js dosyası bulunamadı, render.js kullanılıyor -->
3827  <!-- map_config.js (Leaflet setup) removed -->
3828
3829
3830
3831  
3831<script src="/static/js/core/utils/city_town_quarter_box_manager.js?v=20260510-town-encoding"></script>
3831
3832
3833
3834  <!-- Grid Satış Modal (Ctrl+Click) -->
3835  
3835<script src="/static/js/components/grid_sales_modal.js"></script>
3835
3836
3837
3838
3839  <!-- Kamera kontrolleri -->
3840  
3840<script src="/static/js/graphics/3d/map_3d/camera_controls.js"></script>
3840
3841  
3842  <!-- 3D Yapı Çizim Sistemi ve Mapbox 3D Binalar kaldırıldı (performans için) -->
3843  
3844  
3844<script src="/static/js/drawing/tools/add_graphics/multi_road_select.js"></script>
3844
3845  <!-- ThreePOC (bağımsız oyun motoru POC) -->
3846
3847  <!-- POC / Demo: default kapalı (3D model sistemi tek noktada yönetiliyor) -->
3848  <!-- 
3848<script src="/static/js/car_demo/car-demo.js"></script>
3848 -->
3849  <!-- 
3849<script src="/static/js/vehicles/car-model.js"></script>
3849 -->
3850
3851  <!-- Graphics Modules -->
3852  
3852<script src="/static/js/graphics/elevation/elevation_view.js"></script>
3852
3853
3854  <!-- Info Updates -->
3855  
3855<script src="/static/js/features/parameters/update_parameters_info.js?v=20260815-tkgm-alan"></script>
3855
3856  
3856<script>
3857    window.__ppEnsureParameterInfoModals = window.__ppEnsureParameterInfoModals || function() {
3858      if (window.viewInfoModalManager && window.roadInfoModalManager) return Promise.resolve();
3859      return window.__ppLoadScriptOnce('/static/js/features/parameters/parameters_info_modals.js?v=lazy-20260508');
3860    };
3861  </script>
3861
3862  <!-- Google Maps API key init (Street View için) -->
3863  
3863<script src="/static/js/initialization/google_maps_init.js"></script>
3863
3864  <!-- Street View Helper (V2 rapordaki mantığı pro/basit modlarda kullanmak için) -->
3865  
3865<script src="/static/js/graphics/street_view/street_view_helper.js"></script>
3865
3866  
3866<script src="/static/js/features/parameters/render_parcel_info.js?v=20260815-tkgm-alan"></script>
3866
3867  <!-- 3D Model Editörü /3d-editor/ sayfasına taşındı -->
3868  <!-- Raporlama -->
3869  <!-- V1 Report Generator REMOVED - Replaced with lightweight My Queries Manager -->
3870  
3870<script src="/static/js/reports/my_queries_manager.js"></script>
3870
3871  
3871<script src="/static/js/reports/analysis_report_v2_loader.js"></script>
3871
3872  
3872<script src="/static/js/reports/price_report_client.js?v=2025-11-10-01"></script>
3872
3873
3874  <!-- Drawing Process Modules -->
3875  
3875<script src="/static/js/drawing/layers/map_layer_config.js"></script>
3875
3876  
3876<script src="/static/js/drawing/render/render.js?v=20260704-parcel-style"></script>
3876
3877  
3877<script src="/static/js/drawing/fixes/roads_self_heal.js"></script>
3877
3878  
3878<script src="/static/js/drawing/fixes/electric_self_heal.js"></script>
3878
3879
3880  <!-- New Layer Drawing Functions -->
3881  
3881<script src="/static/js/drawing/tools/draw_clipped_railway.js"></script>
3881
3882  
3882<script src="/static/js/drawing/tools/draw_clipped_sit.js"></script>
3882
3883  <!-- Eski mahalle bazlı sulak koruma kaldırıldı -->
3884  <!-- 
3884<script src="/static/js/drawing/tools/draw_clipped_sulak_koruma.js"></script>
3884 -->
3885  <!-- Şehir bazlı sulak koruma (RAMSAR) -->
3886  
3886<script src="/static/js/drawing/tools/draw_city_sulak_koruma.js"></script>
3886
3887  
3887<script src="/static/js/drawing/tools/draw_clipped_mill_park.js"></script>
3887
3888
3889  <!-- Tab Handlers -->
3890  
3890<script src="/static/js/components/tab_handlers.js?v=20260708-sidebar-dropdown-v3"></script>
3890
3891  <!-- Akıllı Sorgu Modal -->
3892  
3892<script src="/static/js/features/query/smart_query_modal.js?v=20260716-paste"></script>
3892
3893  <!-- Resim'den Sorgu (OpenAI Vision) — modal açıldığında/tıklamada yüklenir. -->
3894  
3894<script>
3895    window.__ppEnsureOcrImageQuery = window.__ppEnsureOcrImageQuery || function() {
3896      if (window.__ppOcrImageQueryLoaded) return Promise.resolve();
3897      return window.__ppLoadScriptOnce('/static/js/features/ocr/ocr_image_query.js?v=smart-query-20260716-ada-clean').then(function() {
3898        window.__ppOcrImageQueryLoaded = true;
3899      });
3900    };
3901    document.addEventListener('click', function(event) {
3902      try {
3903        var target = event.target && event.target.closest && event.target.closest('label[for="ocr-image-input"],#ocr-image-upload,#ocr-image-input,[data-tab="image_query"],[data-tab="image-query"],[data-target="image_query"],[data-target="image-query"]');
3904        if (target && typeof window.__ppEnsureOcrImageQuery === 'function') window.__ppEnsureOcrImageQuery();
3905      } catch (e) {}
3906    }, true);
3907  </script>
3907
3908
3909  <!-- WebGL Cleanup Utility (haritaları temizlemek için) -->
3910  
3910<script src="/static/js/core/map/webgl_cleanup.js"></script>
3910
3911  
3912  <!-- Core App Bootstrap -->
3913  
3913<script src="/static/js/app/pro_query_background.js?v=20260601-detail-redirect"></script>
3913
3914  
3914<script type="module" src="/static/js/initialization/app.js?v=20260815-tkgm-alan"></script>
3914
3915
3916  <!-- Parcel Rotate -->
3917  
3917<script src="/static/js/graphics/turner.js"></script>
3917
3918
3919  <!-- Tools -->
3920  
3920<script src="/static/js/features/parameters/buttons.js?v=20260728-simple-default"></script>
3920
3921
3922  
3922<script src="/static/js/drawing/buttons/toggle_button_manager.js?v=2026-01-03-04"></script>
3922
3923  
3923<script src="/static/js/drawing/buttons/parameters_css_handlers.js"></script>
3923
3924  
3924<script src="/static/js/drawing/buttons/parameters_drawing_handler.js"></script>
3924
3925  
3925<script src="/static/js/drawing/buttons/parameters_buttons_check.js"></script>
3925
3926  <!-- collapsible_menu.js ve dropdowns.js artık topbar.html'den yükleniyor -->
3927  
3928  <!-- Measurement Tools (Cetvel ve Alan Ölçümü) -->
3929  
3929<script src="/static/js/drawing/measurement/measurement_manager.js"></script>
3929
3930
3931  <!-- Annotation: harita + 3D editör ortak metin/ok yardımcıları -->
3932  
3932<script src="/static/js/drawing/tools/annotation_drawing_helpers.js"></script>
3932
3933  <!-- Annotation Tools (İğne & Metin harita işaretleme) -->
3934  
3934<script src="/static/js/drawing/tools/map_annotation_tools.js?v=20260703-no-map-stop"></script>
3934
3935
3936
3937  <!-- User Adding / Road toggle -->
3938  
3938<script src="/static/js/drawing/tools/add_graphics/user_adding.js"></script>
3938
3939  
3939<script src="/static/js/drawing/tools/add_graphics/add_road_to_gpkg.js"></script>
3939
3940  
3940<script src="/static/js/drawing/tools/add_graphics/add_electric_to_gpkg.js"></script>
3940
3941  
3941<script src="/static/js/drawing/tools/add_graphics/select_electric.js"></script>
3941
3942  
3942<script src="/static/js/drawing/tools/add_graphics/user_adding_electric.js"></script>
3942
3943
3944  <!-- Fullscreen helpers -->
3945  <div id="fs-mask" aria-hidden="true"></div>
3946  <div id="fs-snapshot" aria-hidden="true"></div>
3947
3948  <!-- Tepe Kredi Sistemi -->
3949  
3949<script src="/static/js/credit_system.js"></script>
3949
3950  <!-- İlk Giriş Tour Overlay (ekran görüntüsü + Pro Sorgu) -->
3951  
3951<script src="/static/js/app/ui/app_tour_overlay.js?v=20260727-basit-mapclick-no-pro"></script>
3951
3952  
3952<script src="/static/js/app/cost/komisyon_harclar_modal.js?v=20260725i"></script>
3952
3953  <!-- user_menu.js ve auth_required_3d_modal.js artık topbar.html'den yükleniyor -->
3954
3955  <!-- Grid Satış İstatistikleri Modalı - Harita Üzerinde -->
3956  <div class="modal fade" id="gridSalesModal" tabindex="-1" aria-labelledby="gridSalesModalLabel" aria-hidden="true" 
3957       style="z-index: 9999;">
3958    <div class="modal-dialog modal-lg" id="gridSalesModalDialog" 
3959         style="position: fixed; top: 80px; right: 30px; margin: 0; max-width: 600px;">
3960      <div class="modal-content" style="box-shadow: 0 5px 15px rgba(0,0,0,0.5);">
3961        <div class="modal-header" id="gridSalesModalHeader" style="cursor: move;">
3962          <h5 class="modal-title" id="gridSalesModalLabel"><i class="fas fa-th me-2"></i>Grid Satış İstatistikleri
3963          </h5>
3964          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Kapat"></button>
3965        </div>
3966        <div class="modal-body">
3967          <div id="gridSalesContent">
3968            <!-- İçerik JavaScript ile doldurulacak -->
3969            <p class="text-muted">Veri yükleniyor...</p>
3970          </div>
3971        </div>
3972        <div class="modal-footer">
3973          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Kapat</button>
3974        </div>
3975      </div>
3976    </div>
3977  </div>
3978  
3979
3980</body>
3981
3982</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.