PageSourceSearch

https://proparcel.com/static/js/utils/tkgm_passive_parcel.js?v=20260523-passive-banner

js proparcel.com collected 2026-09-24 14:51:08 UTC 12,802 bytes, 329 lines download raw bytes

1/**
2 * TKGM pasif / toplulaştırılmış parsel (geometry=null, gittigiParselListe).
3 */
4(function () {
5  'use strict';
6
7  const MODAL_ID = 'pp-tkgm-passive-parcel-modal';
8  let modalEl = null;
9  let styleInjected = false;
10
11  function injectStyles() {
12    if (styleInjected) return;
13    styleInjected = true;
14    const style = document.createElement('style');
15    style.id = 'pp-tkgm-passive-parcel-modal-style';
16    style.textContent = [
17      '.pp-tkgm-passive-modal{position:fixed;inset:0;z-index:2147483000;display:none;align-items:center;justify-content:center;padding:20px;background:rgba(15,23,42,.55);backdrop-filter:blur(3px);font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif}',
18      '.pp-tkgm-passive-modal__card{width:min(520px,calc(100vw - 32px));max-height:min(85vh,720px);overflow:auto;background:#fff;color:#0f172a;border-radius:14px;box-shadow:0 24px 64px rgba(0,0,0,.22)}',
19      '.pp-tkgm-passive-modal__head{padding:18px 20px 12px;border-bottom:1px solid #e2e8f0}',
20      '.pp-tkgm-passive-modal__title{margin:0;font-size:18px;font-weight:800;color:#0f172a}',
21      '.pp-tkgm-passive-modal__sub{margin:8px 0 0;font-size:13px;line-height:1.5;color:#475569}',
22      '.pp-tkgm-passive-modal__body{padding:8px 20px 16px}',
23      '.pp-tkgm-passive-modal__section{margin:14px 0 0}',
24      '.pp-tkgm-passive-modal__section-title{margin:0 0 8px;font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#64748b}',
25      '.pp-tkgm-passive-modal__rows{margin:0;padding:0;list-style:none;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}',
26      '.pp-tkgm-passive-modal__row{display:flex;gap:12px;padding:10px 12px;border-top:1px solid #f1f5f9;font-size:14px;line-height:1.45}',
27      '.pp-tkgm-passive-modal__row:first-child{border-top:0}',
28      '.pp-tkgm-passive-modal__label{flex:0 0 42%;max-width:42%;color:#64748b;font-weight:600}',
29      '.pp-tkgm-passive-modal__value{flex:1;color:#0f172a;word-break:break-word}',
30      '.pp-tkgm-passive-modal__foot{padding:12px 20px 18px;border-top:1px solid #e2e8f0;display:flex;justify-content:flex-end}',
31      '.pp-tkgm-passive-modal__btn{border:0;border-radius:10px;background:#2563eb;color:#fff;font-weight:700;font-size:14px;padding:10px 18px;cursor:pointer}',
32      '.pp-tkgm-passive-modal__btn:hover{background:#1d4ed8}',
33    ].join('');
34    document.head.appendChild(style);
35  }
36
37  function esc(s) {
38    if (s == null || s === '') return '—';
39    return String(s)
40      .replace(/&/g, '&')
41      .replace(/</g, '&lt;')
42      .replace(/>/g, '&gt;')
43      .replace(/"/g, '&quot;');
44  }
45
46  function durumLabel(v) {
47    const s = v == null ? '' : String(v).trim();
48    if (s === '0') return 'Pasif (aktif değil)';
49    if (s === '1') return 'Aktif';
50    return s || '—';
51  }
52
53  function parseGittigiParselListe(raw) {
54    if (!raw) return null;
55    if (typeof raw === 'object') return raw;
56    if (typeof raw === 'string') {
57      const t = raw.trim();
58      if (!t) return null;
59      try {
60        const p = JSON.parse(t);
61        return p && typeof p === 'object' ? p : null;
62      } catch (_) {
63        return null;
64      }
65    }
66    return null;
67  }
68
69  function firstDestinationFeature(fc) {
70    const features = (fc && fc.features) || [];
71    for (let i = 0; i < features.length; i++) {
72      const f = features[i];
73      if (f && f.geometry) return f;
74    }
75    return null;
76  }
77
78  function row(label, value) {
79    return (
80      '<li class="pp-tkgm-passive-modal__row">' +
81      '<span class="pp-tkgm-passive-modal__label">' + esc(label) + '</span>' +
82      '<span class="pp-tkgm-passive-modal__value">' + esc(value) + '</span>' +
83      '</li>'
84    );
85  }
86
87  function rowsFromProps(title, props) {
88    if (!props) return '';
89    const items = [
90      ['İl', props.ilAd || props.il],
91      ['İlçe', props.ilceAd || props.ilce],
92      ['Mahalle', props.mahalleAd || props.mahalle],
93      ['Ada / Parsel', [props.adaNo || props.ada, props.parselNo || props.parsel].filter(Boolean).join(' / ')],
94      ['Özet', props.ozet],
95      ['Durum', props.durumLabel || durumLabel(props.durum)],
96      ['Alan', props.alan ? props.alan + ' m²' : ''],
97      ['Nitelik', props.nitelik],
98      ['Pafta', props.pafta],
99    ];
100    let html = '<div class="pp-tkgm-passive-modal__section">';
101    html += '<h4 class="pp-tkgm-passive-modal__section-title">' + esc(title) + '</h4><ul class="pp-tkgm-passive-modal__rows">';
102    items.forEach(function (pair) {
103      const val = pair[1];
104      if (val == null || String(val).trim() === '') return;
105      html += row(pair[0], val);
106    });
107    html += '</ul></div>';
108    return html;
109  }
110
111  function extractPassiveParcelInfo(data) {
112    if (!data || typeof data !== 'object') return null;
113    const props = data.properties || {};
114    let sourceProps = null;
115    let sebep = '';
116    let destinations = [];
117
118    if (data.geometry == null && props.gittigiParselListe) {
119      sourceProps = Object.assign({}, props, { durumLabel: durumLabel(props.durum) });
120      sebep = (props.gittigiParselSebep || '').trim();
121      const fc = parseGittigiParselListe(props.gittigiParselListe);
122      const destFeat = firstDestinationFeature(fc);
123      if (!destFeat) return null;
124      (fc.features || []).forEach(function (f) {
125        const dp = (f && f.properties) || {};
126        destinations.push({
127          ilAd: dp.ilAd,
128          ilceAd: dp.ilceAd,
129          mahalleAd: dp.mahalleAd,
130          adaNo: dp.adaNo || dp.ada,
131          parselNo: dp.parselNo || dp.parsel,
132          ozet: dp.ozet,
133          alan: dp.alan,
134          nitelik: dp.nitelik,
135          durumLabel: durumLabel(dp.durum),
136          pafta: dp.pafta,
137        });
138      });
139      const destProps = Object.assign({}, destFeat.properties || {});
140      destProps.pp_tkgm_passive_redirect = true;
141      destProps.pp_tkgm_passive_source_ada = props.adaNo || props.ada;
142      destProps.pp_tkgm_passive_source_parsel = props.parselNo || props.parsel;
143      destProps.pp_tkgm_passive_source_ozet = props.ozet;
144      destProps.pp_tkgm_passive_sebep = sebep;
145      return {
146        sourceProps: sourceProps,
147        sebep: sebep,
148        destinations: destinations,
149        normalizedFeature: {
150          type: data.type || 'Feature',
151          geometry: destFeat.geometry,
152          properties: destProps,
153        },
154      };
155    }
156
157    if (props.pp_tkgm_passive_redirect) {
158      sourceProps = {
159        ilAd: props.ilAd,
160        ilceAd: props.ilceAd,
161        mahalleAd: props.mahalleAd,
162        adaNo: props.pp_tkgm_passive_source_ada,
163        parselNo: props.pp_tkgm_passive_source_parsel,
164        ozet: props.pp_tkgm_passive_source_ozet,
165        durumLabel: 'Pasif (aktif değil)',
166      };
167      sebep = (props.pp_tkgm_passive_sebep || '').trim();
168      destinations = [
169        {
170          ilAd: props.ilAd,
171          ilceAd: props.ilceAd,
172          mahalleAd: props.mahalleAd,
173          adaNo: props.adaNo || props.ada,
174          parselNo: props.parselNo || props.parsel,
175          ozet: props.ozet,
176          alan: props.alan,
177          nitelik: props.nitelik,
178          durumLabel: durumLabel(props.durum),
179          pafta: props.pafta,
180        },
181      ];
182      return {
183        sourceProps: sourceProps,
184        sebep: sebep,
185        destinations: destinations,
186        normalizedFeature: data,
187      };
188    }
189
190    return null;
191  }
192
193  function normalizeFeature(data) {
194    const info = extractPassiveParcelInfo(data);
195    if (!info) return data;
196    if (info.normalizedFeature && info.normalizedFeature.geometry) {
197      return info.normalizedFeature;
198    }
199    const props = data.properties || {};
200    const fc = parseGittigiParselListe(props.gittigiParselListe);
201    const dest = firstDestinationFeature(fc);
202    if (!dest) return data;
203    const destProps = Object.assign({}, dest.properties || {});
204    destProps.pp_tkgm_passive_redirect = true;
205    destProps.pp_tkgm_passive_source_ada = props.adaNo || props.ada;
206    destProps.pp_tkgm_passive_source_parsel = props.parselNo || props.parsel;
207    destProps.pp_tkgm_passive_source_ozet = props.ozet;
208    destProps.pp_tkgm_passive_sebep = (props.gittigiParselSebep || '').trim();
209    return {
210      type: data.type || 'Feature',
211      geometry: dest.geometry,
212      properties: destProps,
213    };
214  }
215
216  function buildModalBody(info) {
217    let html = rowsFromProps('Sorgulanan parsel (pasif kayıt)', info.sourceProps);
218    (info.destinations || []).forEach(function (dest, idx) {
219      const title =
220        info.destinations.length > 1
221          ? 'Gittiği parsel ' + (idx + 1)
222          : 'Gittiği parsel (aktif kayıt)';
223      html += rowsFromProps(title, dest);
224    });
225    if (info.sebep) {
226      html += '<div class="pp-tkgm-passive-modal__section">';
227      html += '<h4 class="pp-tkgm-passive-modal__section-title">Değişiklik sebebi</h4>';
228      html += '<ul class="pp-tkgm-passive-modal__rows">' + row('Açıklama', info.sebep) + '</ul></div>';
229    }
230    return html;
231  }
232
233  function getModal() {
234    injectStyles();
235    if (modalEl) return modalEl;
236    const overlay = document.createElement('div');
237    overlay.id = MODAL_ID;
238    overlay.className = 'pp-tkgm-passive-modal';
239    overlay.setAttribute('role', 'dialog');
240    overlay.setAttribute('aria-modal', 'true');
241    overlay.innerHTML =
242      '<div class="pp-tkgm-passive-modal__card">' +
243      '<div class="pp-tkgm-passive-modal__head">' +
244      '<h3 class="pp-tkgm-passive-modal__title">Parsel pasif / toplulaştırılmış</h3>' +
245      '<p class="pp-tkgm-passive-modal__sub">Sorguladığınız ada-parsel TKGM\'de pasif durumdadır. Haritada gittiği aktif parsel kullanılacaktır.</p>' +
246      '</div>' +
247      '<div class="pp-tkgm-passive-modal__body" data-pp-tkgm-passive-body></div>' +
248      '<div class="pp-tkgm-passive-modal__foot">' +
249      '<button type="button" class="pp-tkgm-passive-modal__btn" data-pp-tkgm-passive-ok>Tamam</button>' +
250      '</div></div>';
251    document.body.appendChild(overlay);
252    modalEl = overlay;
253    return modalEl;
254  }
255
256  function isPassiveParcelPayload(data) {
257    if (!data || typeof data !== 'object') return false;
258    if (data.properties?.pp_tkgm_passive_redirect) return true;
259    const props = data.properties || data;
260    if (!props || typeof props !== 'object') return false;
261    if (data.geometry) return false;
262    return !!parseGittigiParselListe(props.gittigiParselListe);
263  }
264
265  function shouldShowNotFoundBanner(error) {
266    if (!error || error.type !== 'TKGM_PARCEL_NOT_FOUND') return false;
267    if (isPassiveParcelPayload(error.detail)) return false;
268    if (isPassiveParcelPayload(error.payload)) return false;
269    if (error.passiveParcel) return false;
270    return true;
271  }
272
273  function hideParcelNotFoundBanner() {
274    try {
275      window.ProParcelTopBanner?.hide?.();
276    } catch (_) {}
277  }
278
279  function showPassiveParcelModal(info) {
280    return new Promise(function (resolve) {
281      hideParcelNotFoundBanner();
282      const modal = getModal();
283      const body = modal.querySelector('[data-pp-tkgm-passive-body]');
284      if (body) body.innerHTML = buildModalBody(info);
285      const done = function () {
286        modal.style.display = 'none';
287        document.removeEventListener('keydown', onEsc);
288        resolve(true);
289      };
290      const onEsc = function (e) {
291        if (e.key === 'Escape') done();
292      };
293      const okBtn = modal.querySelector('[data-pp-tkgm-passive-ok]');
294      if (okBtn) {
295        okBtn.onclick = done;
296      }
297      modal.onclick = function (e) {
298        if (e.target === modal) done();
299      };
300      modal.style.display = 'flex';
301      document.addEventListener('keydown', onEsc);
302    });
303  }
304
305  async function normalizeAndConfirm(data) {
306    const info = extractPassiveParcelInfo(data);
307    if (!info) return data;
308    await showPassiveParcelModal(info);
309    return info.normalizedFeature || normalizeFeature(data);
310  }
311
312  async function showModalIfNeeded(data) {
313    const info = extractPassiveParcelInfo(data);
314    if (!info) return data;
315    await showPassiveParcelModal(info);
316    return data;
317  }
318
319  window.TkgmPassiveParcel = {
320    extractPassiveParcelInfo: extractPassiveParcelInfo,
321    normalizeFeature: normalizeFeature,
322    normalizeAndConfirm: normalizeAndConfirm,
323    showModalIfNeeded: showModalIfNeeded,
324    showPassiveParcelModal: showPassiveParcelModal,
325    isPassiveParcelPayload: isPassiveParcelPayload,
326    shouldShowNotFoundBanner: shouldShowNotFoundBanner,
327    hideParcelNotFoundBanner: hideParcelNotFoundBanner,
328  };
329})();

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.