{"id":2431,"date":"2026-04-10T10:08:33","date_gmt":"2026-04-10T10:08:33","guid":{"rendered":"https:\/\/primetoolhub.com\/?page_id=2431"},"modified":"2026-07-13T15:18:13","modified_gmt":"2026-07-13T15:18:13","slug":"free-jsonpath-evaluator-extractor","status":"publish","type":"page","link":"https:\/\/schoolict.net\/tools\/free-jsonpath-evaluator-extractor\/","title":{"rendered":"Free JSONPath Evaluator &amp; Extractor Pro"},"content":{"rendered":"<div class=\"pth-hero-section\">\n<div class=\"pth-hero-content\">\n<h2>Free JSONPath Evaluator &#038; Extractor Pro<\/h2>\n<p>Use our free JSONPath evaluator to instantly query, extract, and test complex JSON data offline. Features live evaluation, syntax checking, and CSV export.<\/p>\n<div id=\"pth-toc-placeholder\"><\/div>\n<\/p>\n<\/div>\n<div class=\"pth-hero-image\">\n        <img decoding=\"async\" data-no-lazy=\"1\" width=\"450\" height=\"253\" src=\"https:\/\/schoolict.net\/tools\/wp-content\/uploads\/2026\/04\/free-jsonpath-evaluator-1-1024x572.jpeg\" alt=\"free jsonpath evaluator\">\n    <\/div>\n<\/div>\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li><a href=\"#\ud83d\udd34-reshaping-data-and-reading-data-are-two-different-jobs\">\ud83d\udd34 Reshaping Data and Reading Data Are Two Different Jobs<\/a><\/li><li><a href=\"#\ud83d\udfe1-what-the-convert-tab-is-actually-for\">\ud83d\udfe1 What the Convert Tab Is Actually For<\/a><ul><li><a href=\"#\ud83d\udfe2-a-real-example\">\ud83d\udfe2 A Real Example<\/a><\/li><\/ul><\/li><li><a href=\"#\ud83d\udd34-when-youd-reach-for-the-query-tab\">\ud83d\udd34 When You&#8217;d Reach for the Query Tab<\/a><\/li><li><a href=\"#\ud83d\udfe1-common-mistakes-and-limits\">\ud83d\udfe1 Common Mistakes and Limits<\/a><\/li><\/ul><\/nav><\/div>\n\n\n<!-- LSCACHE_DISABLE -->\r\n<div id=\"pth-jh-wrapper\">\r\n\r\n<style data-no-optimize=\"1\">\r\n#pth-jh-wrapper *,#pth-jh-wrapper *::before,#pth-jh-wrapper *::after{box-sizing:border-box;min-width:0;}\r\n#pth-jh-wrapper{font-family:'Inter',system-ui,sans-serif;background:#f8fafc;border-radius:16px;padding:20px;color:#1e293b;font-weight:500;opacity:1;display:block;}\r\n.pth-jh-header{margin-bottom:16px;}\r\n.pth-jh-meta-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:10px;}\r\n.pth-jh-version-badge{background:#eff6ff;color:#1d4ed8;font-size:.72rem;font-weight:700;padding:3px 10px;border-radius:20px;border:1px solid #bfdbfe;}\r\n.pth-jh-status-offline{background:#f0fdf4;color:#047857;font-size:.72rem;font-weight:700;padding:3px 10px;border-radius:20px;border:1px solid #bbf7d0;}\r\n.pth-jh-header h2{color:#1d4ed8;font-size:1.5rem;font-weight:800;margin:0 0 6px;}\r\n.pth-jh-header p{color:#334155;font-size:.88rem;margin:0;font-weight:500;}\r\n.pth-jh-tabs{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:16px;border-bottom:2px solid #e2e8f0;padding-bottom:10px;}\r\n.pth-jh-tab-btn{background:#fff;border:2px solid #e2e8f0;color:#334155;font-size:.85rem;font-weight:700;padding:9px 16px;border-radius:8px;cursor:pointer;font-family:'Inter',system-ui,sans-serif;white-space:nowrap;transition:all .15s;}\r\n.pth-jh-tab-btn:hover{border-color:#2563eb;color:#1d4ed8;background:#eff6ff;}\r\n.pth-jh-tab-btn.pth-jh-active{background:#2563eb;border-color:#2563eb;color:#fff;}\r\n.pth-jh-panel{display:none;opacity:1;}\r\n.pth-jh-panel.pth-jh-panel-active{display:block;}\r\n.pth-jh-empty{background:#fff;border:1px dashed #cbd5e1;border-radius:12px;padding:30px 20px;text-align:center;color:#334155;font-weight:600;min-height:120px;}\r\n@media(max-width:768px){#pth-jh-wrapper{padding:10px;border-radius:0;background:transparent;}.pth-jh-tab-btn{font-size:.78rem;padding:7px 12px;}.pth-jh-header h2{font-size:1.2rem;}}\r\n<\/style>\r\n\r\n<div class=\"pth-jh-header\">\r\n  <div class=\"pth-jh-meta-bar\">\r\n    <span class=\"pth-jh-version-badge\">v1.0<\/span>\r\n    <span class=\"pth-jh-status-offline\">\ud83d\udd12 100% Offline<\/span>\r\n  <\/div>\r\n  <h2>\ud83e\udde9 JSON Studio Pro<\/h2>\r\n  <p>Format, validate and convert JSON, CSV and XML \u2014 plus a live JSONPath evaluator and interactive tree. No upload, no login.<\/p>\r\n<\/div>\r\n\r\n<div class=\"pth-jh-tabs\" role=\"tablist\" aria-label=\"JSON Studio tools\">\r\n  <button class=\"pth-jh-tab-btn pth-jh-active\" data-tab=\"query\"   role=\"tab\" aria-selected=\"true\">\ud83d\udd0d Query & Explore<\/button>\r\n  \r\n  <button class=\"pth-jh-tab-btn\"               data-tab=\"convert\" role=\"tab\" aria-selected=\"false\">\ud83d\udd04 Convert & Format<\/button>\r\n<\/div>\r\n\r\n<div class=\"pth-jh-panel pth-jh-panel-active\" id=\"pth-jh-tab-query\" role=\"tabpanel\">\r\n  <div class=\"pth-jh-empty\" id=\"pth-jh-empty-query\">Loading Query & Explore\u2026<\/div>\r\n<\/div>\r\n\r\n<div class=\"pth-jh-panel\" id=\"pth-jh-tab-convert\" role=\"tabpanel\">\r\n  <div class=\"pth-jh-empty\" id=\"pth-jh-empty-convert\">Loading Convert & Format\u2026<\/div>\r\n<\/div>\r\n\r\n\r\n<\/div>\r\n<script data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\">\r\n(function () {\r\n  'use strict';\r\n  window.pthJH = window.pthJH || {};\r\n  window.pthJH.activeTab = 'convert';\r\n\r\n  function initTabs() {\r\n    var root = document.getElementById('pth-jh-wrapper');\r\n    if (!root) return;\r\n    var btns = root.querySelectorAll('.pth-jh-tab-btn');\r\n    btns.forEach(function (btn) {\r\n      btn.addEventListener('click', function () {\r\n        var tab = btn.getAttribute('data-tab');\r\n        btns.forEach(function (b) {\r\n          b.classList.remove('pth-jh-active');\r\n          b.setAttribute('aria-selected', 'false');\r\n        });\r\n        btn.classList.add('pth-jh-active');\r\n        btn.setAttribute('aria-selected', 'true');\r\n        root.querySelectorAll('.pth-jh-panel').forEach(function (p) {\r\n          p.classList.remove('pth-jh-panel-active');\r\n        });\r\n        var panel = document.getElementById('pth-jh-tab-' + tab);\r\n        if (panel) panel.classList.add('pth-jh-panel-active');\r\n        window.pthJH.activeTab = tab;\r\n        document.dispatchEvent(new CustomEvent('pthJHTabActive', { detail: { tab: tab } }));\r\n      });\r\n    });\r\n\r\n    \/* Deep-link: ?tab=convert \/ ?tab=query *\/\r\n    try {\r\n      var want = new URLSearchParams(window.location.search).get('tab');\r\n      if (want === 'convert' || want === 'query') {\r\n        var target = root.querySelector('.pth-jh-tab-btn[data-tab=\"' + want + '\"]');\r\n        if (target) target.click();\r\n      }\r\n    } catch (e) {}\r\n  }\r\n\r\n  function runInit() {\r\n    if (window.pthJH.shellReady) return;\r\n    if (!document.getElementById('pth-jh-wrapper')) return;\r\n    window.pthJH.shellReady = true;\r\n    initTabs();\r\n  }\r\n\r\n  runInit();\r\n  if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', runInit); }\r\n  window.addEventListener('load', function () { setTimeout(runInit, 50); });\r\n  if (!window.pthJH.shellReady && typeof MutationObserver !== 'undefined') {\r\n    var obs = new MutationObserver(function () {\r\n      if (document.getElementById('pth-jh-wrapper')) { obs.disconnect(); runInit(); }\r\n    });\r\n    obs.observe(document.body || document.documentElement, { childList: true, subtree: true });\r\n    setTimeout(function () { obs.disconnect(); }, 10000);\r\n  }\r\n})();\r\n<\/script>\n\n\n<style>\r\n\/* Scoped CSS (Anti-Bleed) *\/\r\n#pth-json-toolkit-wrapper { font-family: 'Inter', system-ui, sans-serif; max-width: 1400px; margin: 0 auto; box-sizing: border-box; background: transparent; color: #0f172a; line-height: 1.6; }\r\n#pth-json-toolkit-wrapper * { box-sizing: border-box; }\r\n\r\n\/* Premium Layout Elements *\/\r\n#pth-json-toolkit-wrapper .pth-topbar { display: flex; justify-content: space-between; align-items: center; background: #ffffff; border: 1px solid #e2e8f0; padding: 16px 24px; border-radius: 12px; margin-bottom: 24px; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05); flex-wrap: wrap; gap: 15px; }\r\n#pth-json-toolkit-wrapper .pth-title-container { display: flex; align-items: center; gap: 16px; }\r\n#pth-json-toolkit-wrapper .pth-icon { width: 48px; height: 48px; background: #8b5cf6; color: #fff; border-radius: 12px; display: flex; justify-content: center; align-items: center; font-size: 22px; box-shadow: 0 4px 10px rgba(139, 92, 246, 0.3); }\r\n#pth-json-toolkit-wrapper .pth-title { margin: 0; font-size: 22px; font-weight: 800; color: #0f172a; }\r\n#pth-json-toolkit-wrapper .pth-subtitle { margin: 0; font-size: 13px; color: #64748b; font-weight: 600; }\r\n#pth-json-toolkit-wrapper .pth-top-actions { display: flex; gap: 10px; align-items: center; }\r\n\r\n\/* Buttons *\/\r\n#pth-json-toolkit-wrapper .pth-btn { padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 700; border: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: 0.2s; background: #fff; border: 1px solid #cbd5e1; color: #475569; font-family: 'Inter', sans-serif; }\r\n#pth-json-toolkit-wrapper .pth-btn:hover { background: #f1f5f9; color: #0f172a; }\r\n#pth-json-toolkit-wrapper .pth-btn.pth-active { background: #8b5cf6; color: #fff; border-color: #8b5cf6; }\r\n#pth-json-toolkit-wrapper .pth-btn.pth-active:hover { background: #7c3aed; }\r\n#pth-json-toolkit-wrapper .pth-btn-primary { background: #f5f3ff; color: #7c3aed; border-color: #ddd6fe; padding: 10px 20px; border-radius: 8px; }\r\n#pth-json-toolkit-wrapper .pth-btn-primary:hover { background: #ede9fe; }\r\n\r\n\/* Tabs *\/\r\n#pth-json-toolkit-wrapper .pth-tab-bar { display: flex; background: #fff; border: 1px solid #e2e8f0; border-radius: 12px; padding: 8px; margin-bottom: 24px; gap: 8px; flex-wrap: wrap; }\r\n#pth-json-toolkit-wrapper .pth-tab-btn { flex: 1; min-width: 140px; padding: 12px 20px; border-radius: 8px; font-weight: 700; font-size: 14px; border: none; background: #f8fafc; color: #475569; cursor: pointer; transition: all 0.2s; display: flex; align-items: center; justify-content: center; gap: 8px; }\r\n#pth-json-toolkit-wrapper .pth-tab-btn.pth-active { background: #8b5cf6; color: #fff; box-shadow: 0 4px 12px rgba(139, 92, 246, 0.25); }\r\n\r\n\/* Master Grid & Cards *\/\r\n#pth-json-toolkit-wrapper .pth-flex-layout { display: grid; grid-template-columns: 1.8fr 1fr; gap: 24px; transition: all 0.3s ease; }\r\n@media (max-width: 992px) { #pth-json-toolkit-wrapper .pth-flex-layout { grid-template-columns: 1fr; } }\r\n#pth-json-toolkit-wrapper .pth-flex-layout.pth-full-width { grid-template-columns: 1fr; }\r\n#pth-json-toolkit-wrapper .pth-card { background: #ffffff; border: 1px solid #e2e8f0; border-radius: 12px; padding: 24px; box-shadow: 0 2px 4px rgba(0,0,0,0.02); display: flex; flex-direction: column; margin-bottom: 24px; }\r\n#pth-json-toolkit-wrapper .pth-card-title { font-size: 16px; font-weight: 800; color: #0f172a; margin: 0 0 16px 0; display: flex; align-items: center; gap: 8px; text-transform: uppercase; justify-content: space-between; }\r\n\r\n\/* Input\/Output Areas *\/\r\n#pth-json-toolkit-wrapper .pth-input-group { margin-bottom: 16px; }\r\n#pth-json-toolkit-wrapper .pth-label { display: flex; justify-content: space-between; font-size: 12px; font-weight: 700; color: #64748b; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }\r\n#pth-json-toolkit-wrapper .pth-query-box { width: 100%; padding: 12px 16px; border: 2px solid #cbd5e1; border-radius: 8px; font-size: 16px; font-family: monospace; outline: none; background: #fff; color: #1e293b; transition: 0.2s; font-weight: 600; }\r\n#pth-json-toolkit-wrapper .pth-query-box:focus { border-color: #8b5cf6; box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1); }\r\n#pth-json-toolkit-wrapper .pth-editor { width: 100%; min-height: 280px; padding: 16px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 13px; font-family: 'Fira Code', monospace; line-height: 1.6; color: #1e293b; resize: vertical; outline: none; background: #f8fafc; transition: 0.2s; white-space: pre; overflow-wrap: normal; overflow-x: auto; }\r\n#pth-json-toolkit-wrapper .pth-editor:focus { border-color: #8b5cf6; background: #fff; }\r\n#pth-json-toolkit-wrapper .pth-editor.pth-error { border-color: #ef4444; background: #fef2f2; }\r\n#pth-json-toolkit-wrapper .pth-output { width: 100%; min-height: 280px; padding: 16px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 13px; font-family: 'Fira Code', monospace; line-height: 1.6; color: #1e293b; resize: vertical; outline: none; background: #f0fdf4; white-space: pre; overflow-wrap: normal; overflow-x: auto; }\r\n#pth-json-toolkit-wrapper .pth-error-msg { color: #ef4444; font-size: 12px; font-weight: 600; display: none; margin-top: 8px; background: #fee2e2; padding: 8px; border-radius: 6px; }\r\n\r\n\/* Sub Grid for Input\/Output side-by-side *\/\r\n#pth-json-toolkit-wrapper .pth-io-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; transition: 0.3s; }\r\n@media (max-width: 768px) { #pth-json-toolkit-wrapper .pth-io-grid { grid-template-columns: 1fr; } }\r\n#pth-json-toolkit-wrapper .pth-flex-layout.pth-full-width .pth-io-grid { grid-template-columns: 1fr; } \/* Stack on full width to give more reading room *\/\r\n\r\n\/* Misc *\/\r\n#pth-json-toolkit-wrapper .pth-badge { background: #e2e8f0; color: #475569; padding: 2px 8px; border-radius: 12px; font-size: 11px; font-weight: 700; }\r\n#pth-json-toolkit-wrapper .pth-badge.pth-success { background: #dcfce7; color: #166534; }\r\n#pth-json-toolkit-wrapper .pth-badge.pth-error { background: #fee2e2; color: #991b1b; }\r\n#pth-json-toolkit-wrapper .pth-btn-group { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }\r\n\r\n\/* Sidebar Table *\/\r\n#pth-json-toolkit-wrapper .pth-table { width: 100%; border-collapse: collapse; font-size: 12px; margin-bottom: 20px; }\r\n#pth-json-toolkit-wrapper .pth-table th, #pth-json-toolkit-wrapper .pth-table td { padding: 8px 10px; text-align: left; border-bottom: 1px solid #e2e8f0; }\r\n#pth-json-toolkit-wrapper .pth-table th { background: #f1f5f9; font-weight: 700; color: #475569; }\r\n#pth-json-toolkit-wrapper .pth-table td code { background: #e2e8f0; padding: 2px 6px; border-radius: 4px; color: #b91c1c; font-family: monospace; font-weight: 600; cursor: pointer; transition: 0.2s; }\r\n#pth-json-toolkit-wrapper .pth-table td code:hover { background: #cbd5e1; }\r\n\r\n\/* Tree Viewer *\/\r\n#pth-json-toolkit-wrapper .pth-tree { font-family: monospace; font-size: 13px; line-height: 1.5; }\r\n#pth-json-toolkit-wrapper .pth-tree ul { padding-left: 20px; margin: 4px 0; list-style: none; }\r\n#pth-json-toolkit-wrapper .pth-tree details { margin-bottom: 4px; }\r\n#pth-json-toolkit-wrapper .pth-tree summary { cursor: pointer; font-weight: 600; color: #334155; outline: none; }\r\n\r\n\/* Toast *\/\r\n#pth-json-toolkit-wrapper .pth-toast { position: fixed; bottom: 20px; right: 20px; background: #1e293b; color: #fff; padding: 12px 24px; border-radius: 8px; font-size: 14px; font-weight: 600; z-index: 99999; display: none; box-shadow: 0 10px 15px rgba(0,0,0,0.1); }\r\n<\/style>\r\n\r\n<!-- JSONPath External Library (Cache-Proof format - Switched to stable cdnjs) -->\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jsonpath\/0.2.11\/jsonpath.min.js\" data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\"><\/script>\r\n\r\n<div id=\"pth-json-toolkit-wrapper\">\r\n    \r\n    <div class=\"pth-topbar\">\r\n        <div class=\"pth-title-container\">\r\n            <div class=\"pth-icon\">{ }<\/div>\r\n            <div>\r\n                <h2 class=\"pth-title\">All-in-One JSON Toolkit<\/h2>\r\n                <p class=\"pth-subtitle\">Evaluator \u2022 Formatter \u2022 Validator \u2022 Converter \u2022 Viewer<\/p>\r\n            <\/div>\r\n        <\/div>\r\n        <div class=\"pth-top-actions\">\r\n            <button id=\"pth-load-sample-btn\" class=\"pth-btn pth-btn-primary\">\ud83d\udca1 Load Sample Data<\/button>\r\n            <button id=\"pth-fw-btn-json-toolkit\" class=\"pth-btn\">\u26f6 Full Width<\/button>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- Tabs -->\r\n    <div class=\"pth-tab-bar\" id=\"pth-tab-bar\">\r\n        <button class=\"pth-tab-btn pth-active\" id=\"pth-tab-trigger-formatter\" data-target=\"pth-tab-formatter\">\u2728 Format & Validate<\/button>\r\n        <button class=\"pth-tab-btn\" id=\"pth-tab-trigger-jsonpath\" data-target=\"pth-tab-jsonpath\">\ud83d\udd0d JSONPath Evaluator<\/button>\r\n        <button class=\"pth-tab-btn\" id=\"pth-tab-trigger-converter\" data-target=\"pth-tab-converter\">\ud83d\udcca JSON \u2194 CSV<\/button>\r\n        <button class=\"pth-tab-btn\" id=\"pth-tab-trigger-tree\" data-target=\"pth-tab-tree\">\ud83c\udf33 Tree Viewer<\/button>\r\n    <\/div>\r\n\r\n    <div class=\"pth-flex-layout\" id=\"pth-json-toolkit-layout\">\r\n        \r\n        <!-- MAIN LEFT COLUMN -->\r\n        <div class=\"pth-main-col\">\r\n            \r\n            <!-- TAB 1: FORMATTER -->\r\n            <div id=\"pth-tab-formatter\" class=\"pth-tab-content\">\r\n                <div class=\"pth-card\">\r\n                    <div class=\"pth-card-title\">JSON Formatter & Validator<\/div>\r\n                    <div class=\"pth-btn-group\">\r\n                        <button id=\"pth-btn-format\" class=\"pth-btn pth-active\">\u2728 Pretty Print<\/button>\r\n                        <button id=\"pth-btn-minify\" class=\"pth-btn\">\ud83d\udce6 Minify<\/button>\r\n                        <button id=\"pth-btn-validate\" class=\"pth-btn\">\u2705 Validate Only<\/button>\r\n                        <button id=\"pth-btn-clear-f\" class=\"pth-btn\">\ud83d\uddd1\ufe0f Clear<\/button>\r\n                        <button id=\"pth-btn-copy-f\" class=\"pth-btn\">\ud83d\udccb Copy Output<\/button>\r\n                    <\/div>\r\n                    <textarea id=\"pth-input-f\" class=\"pth-editor\" spellcheck=\"false\" placeholder=\"Paste your raw JSON string here...\"><\/textarea>\r\n                    <div id=\"pth-error-f\" class=\"pth-error-msg\"><\/div>\r\n                    <textarea id=\"pth-output-f\" class=\"pth-output\" readonly placeholder=\"Formatted output will appear here...\"><\/textarea>\r\n                <\/div>\r\n            <\/div>\r\n\r\n            <!-- TAB 2: JSONPATH -->\r\n            <div id=\"pth-tab-jsonpath\" class=\"pth-tab-content\" style=\"display:none;\">\r\n                <div class=\"pth-card\" style=\"margin-bottom: 20px; padding-bottom: 10px;\">\r\n                    <div class=\"pth-input-group\">\r\n                        <label class=\"pth-label\">\r\n                            <span>\ud83d\udd0d JSONPath Expression<\/span>\r\n                            <span id=\"pth-jp-count\" class=\"pth-badge\">0 Results<\/span>\r\n                        <\/label>\r\n                        <input type=\"text\" id=\"pth-input-jp-query\" class=\"pth-query-box\" placeholder=\"e.g., $.store.book[*].author\" value=\"$..*\">\r\n                    <\/div>\r\n                <\/div>\r\n                \r\n                <div class=\"pth-io-grid\">\r\n                    <div class=\"pth-card\" style=\"padding: 16px;\">\r\n                        <div class=\"pth-card-title\" style=\"font-size: 14px;\">Input JSON<\/div>\r\n                        <textarea id=\"pth-input-jp\" class=\"pth-editor\" style=\"min-height: 200px;\" spellcheck=\"false\" placeholder=\"Paste your JSON here...\"><\/textarea>\r\n                        <div id=\"pth-error-jp\" class=\"pth-error-msg\"><\/div>\r\n                    <\/div>\r\n                    <div class=\"pth-card\" style=\"padding: 16px;\">\r\n                        <div class=\"pth-card-title\" style=\"font-size: 14px;\">Evaluation Result<\/div>\r\n                        <div class=\"pth-btn-group\" style=\"margin-bottom: 8px;\">\r\n                            <button id=\"pth-btn-copy-jp\" class=\"pth-btn pth-active\" style=\"padding: 4px 8px; font-size:11px;\">\ud83d\udccb Copy<\/button>\r\n                            <button id=\"pth-btn-export-jp\" class=\"pth-btn\" style=\"padding: 4px 8px; font-size:11px;\">\ud83d\udcbe Download JSON<\/button>\r\n                        <\/div>\r\n                        <textarea id=\"pth-output-jp\" class=\"pth-output\" style=\"min-height: 200px;\" readonly placeholder=\"Query results will stream here...\"><\/textarea>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n\r\n            <!-- TAB 3: CONVERTER -->\r\n            <div id=\"pth-tab-converter\" class=\"pth-tab-content\" style=\"display:none;\">\r\n                <div class=\"pth-card\">\r\n                    <div class=\"pth-card-title\">JSON \u2194 CSV Converter<\/div>\r\n                    <div class=\"pth-btn-group\">\r\n                        <button id=\"pth-btn-j2c\" class=\"pth-btn pth-active\">JSON \u2192 CSV<\/button>\r\n                        <button id=\"pth-btn-c2j\" class=\"pth-btn\">CSV \u2192 JSON<\/button>\r\n                        <button id=\"pth-btn-clear-c\" class=\"pth-btn\">\ud83d\uddd1\ufe0f Clear<\/button>\r\n                    <\/div>\r\n                    <textarea id=\"pth-input-c\" class=\"pth-editor\" spellcheck=\"false\" placeholder=\"Paste JSON (Array of Objects) or CSV data here...\"><\/textarea>\r\n                    <div id=\"pth-error-c\" class=\"pth-error-msg\"><\/div>\r\n                    <textarea id=\"pth-output-c\" class=\"pth-output\" readonly placeholder=\"Converted output will appear here...\"><\/textarea>\r\n                    <div class=\"pth-btn-group\" style=\"margin-top: 16px;\">\r\n                        <button id=\"pth-btn-copy-c\" class=\"pth-btn pth-active\">\ud83d\udccb Copy Result<\/button>\r\n                        <button id=\"pth-btn-export-c\" class=\"pth-btn\">\ud83d\udcbe Download File<\/button>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n\r\n            <!-- TAB 4: TREE VIEWER -->\r\n            <div id=\"pth-tab-tree\" class=\"pth-tab-content\" style=\"display:none;\">\r\n                <div class=\"pth-card\">\r\n                    <div class=\"pth-card-title\">Interactive JSON Tree<\/div>\r\n                    <textarea id=\"pth-input-t\" class=\"pth-editor\" style=\"min-height: 150px;\" spellcheck=\"false\" placeholder=\"Paste JSON to visualize...\"><\/textarea>\r\n                    <div id=\"pth-error-t\" class=\"pth-error-msg\"><\/div>\r\n                    <div style=\"margin: 16px 0;\">\r\n                        <button id=\"pth-btn-tree-expand\" class=\"pth-btn\">\u2795 Expand All<\/button>\r\n                        <button id=\"pth-btn-tree-collapse\" class=\"pth-btn\">\u2796 Collapse All<\/button>\r\n                    <\/div>\r\n                    <div id=\"pth-output-t\" class=\"pth-tree\" style=\"background:#f8fafc; padding:16px; border-radius:8px; border: 1px solid #cbd5e1; max-height: 500px; overflow-y: auto;\"><\/div>\r\n                <\/div>\r\n            <\/div>\r\n\r\n        <\/div>\r\n\r\n        <!-- RIGHT SIDEBAR -->\r\n        <div class=\"pth-sidebar-col\" id=\"pth-json-toolkit-sidebar\">\r\n            <div class=\"pth-card\" style=\"background: #f8fafc;\">\r\n                <h3>\ud83d\udcd6 Quick Reference<\/h3>\r\n                <p style=\"font-size: 12px; color: #64748b;\">Click syntax to copy\/insert.<\/p>\r\n                <table class=\"pth-table\">\r\n                    <thead><tr><th>Syntax<\/th><th>Description<\/th><\/tr><\/thead>\r\n                    <tbody id=\"pth-cheatsheet-body\">\r\n                        <!-- Populated by JS -->\r\n                    <\/tbody>\r\n                <\/table>\r\n            <\/div>\r\n\r\n            <div class=\"pth-card\" style=\"background: #f8fafc;\">\r\n                <h3>\ud83d\udca1 Pro Tips<\/h3>\r\n                <ul style=\"font-size: 13px; color: #475569; padding-left: 20px; line-height: 1.8; margin: 0;\">\r\n                    <li><strong>Offline Safety:<\/strong> Processing happens inside your browser. No sensitive JSON data is uploaded to any server.<\/li>\r\n                    <li><strong>Live Parsing:<\/strong> The JSONPath and Tree views automatically re-evaluate as you type or paste text.<\/li>\r\n                    <li><strong>CSV Rules:<\/strong> When converting JSON to CSV, ensure your input is a flat Array of Objects (e.g. <code>[{\"id\":1},{\"id\":2}]<\/code>).<\/li>\r\n                <\/ul>\r\n            <\/div>\r\n        <\/div>\r\n\r\n    <\/div>\r\n    \r\n    <div id=\"pth-toast\" class=\"pth-toast\">Action successful!<\/div>\r\n<\/div>\r\n\r\n<script data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\">\r\n(function() {\r\n    window.pthJsonToolkitApp = {\r\n        initialized: false,\r\n        currentTab: 'formatter',\r\n        currentConvertMode: 'j2c',\r\n        jpParsedObj: null,\r\n        \r\n        sampleData: {\r\n            json: {\r\n                \"store\": {\r\n                    \"book\": [\r\n                        { \"category\": \"reference\", \"author\": \"Nigel Rees\", \"title\": \"Sayings of the Century\", \"price\": 8.95 },\r\n                        { \"category\": \"fiction\", \"author\": \"Evelyn Waugh\", \"title\": \"Sword of Honour\", \"price\": 12.99 },\r\n                        { \"category\": \"fiction\", \"author\": \"Herman Melville\", \"title\": \"Moby Dick\", \"isbn\": \"0-553-21311-3\", \"price\": 8.99 }\r\n                    ],\r\n                    \"bicycle\": { \"color\": \"red\", \"price\": 19.95 }\r\n                }\r\n            },\r\n            csv: \"category,author,title,price\\nreference,Nigel Rees,Sayings of the Century,8.95\\nfiction,Evelyn Waugh,Sword of Honour,12.99\"\r\n        },\r\n\r\n        init: function() {\r\n            this.cacheDOM();\r\n            this.attachEvents();\r\n            this.updateCheatsheet();\r\n        },\r\n\r\n        cacheDOM: function() {\r\n            this.UI = {\r\n                wrapper: document.getElementById('pth-json-toolkit-wrapper'),\r\n                layout: document.getElementById('pth-json-toolkit-layout'),\r\n                sidebar: document.getElementById('pth-json-toolkit-sidebar'),\r\n                fwBtn: document.getElementById('pth-fw-btn-json-toolkit'),\r\n                sampleBtn: document.getElementById('pth-load-sample-btn'),\r\n                toast: document.getElementById('pth-toast'),\r\n                \r\n                \/\/ Tabs\r\n                tabBtns: document.querySelectorAll('#pth-tab-bar .pth-tab-btn'),\r\n                tabContents: document.querySelectorAll('.pth-tab-content'),\r\n                cheatsheetBody: document.getElementById('pth-cheatsheet-body'),\r\n\r\n                \/\/ Formatter\r\n                fInput: document.getElementById('pth-input-f'),\r\n                fOutput: document.getElementById('pth-output-f'),\r\n                fError: document.getElementById('pth-error-f'),\r\n                \r\n                \/\/ JSONPath\r\n                jpInput: document.getElementById('pth-input-jp'),\r\n                jpQuery: document.getElementById('pth-input-jp-query'),\r\n                jpOutput: document.getElementById('pth-output-jp'),\r\n                jpError: document.getElementById('pth-error-jp'),\r\n                jpCount: document.getElementById('pth-jp-count'),\r\n\r\n                \/\/ Converter\r\n                cInput: document.getElementById('pth-input-c'),\r\n                cOutput: document.getElementById('pth-output-c'),\r\n                cError: document.getElementById('pth-error-c'),\r\n                \r\n                \/\/ Tree\r\n                tInput: document.getElementById('pth-input-t'),\r\n                tOutput: document.getElementById('pth-output-t'),\r\n                tError: document.getElementById('pth-error-t')\r\n            };\r\n        },\r\n\r\n        attachEvents: function() {\r\n            var self = this;\r\n            \r\n            \/\/ Global Actions\r\n            if(self.UI.fwBtn) self.UI.fwBtn.addEventListener('click', function() { self.toggleWidth(); });\r\n            if(self.UI.sampleBtn) self.UI.sampleBtn.addEventListener('click', function() { self.loadSample(); });\r\n\r\n            \/\/ Tab Switching\r\n            self.UI.tabBtns.forEach(function(btn) {\r\n                btn.addEventListener('click', function() {\r\n                    self.UI.tabBtns.forEach(function(t) { t.classList.remove('pth-active'); });\r\n                    this.classList.add('pth-active');\r\n                    \r\n                    var targetId = this.getAttribute('data-target');\r\n                    self.UI.tabContents.forEach(function(tc) {\r\n                        tc.style.display = (tc.id === targetId) ? 'block' : 'none';\r\n                    });\r\n                    \r\n                    self.currentTab = targetId.replace('pth-tab-', '');\r\n                    self.updateCheatsheet();\r\n                });\r\n            });\r\n\r\n            \/\/ Formatter Events\r\n            document.getElementById('pth-btn-format').addEventListener('click', function() { self.processFormatter('format', this); });\r\n            document.getElementById('pth-btn-minify').addEventListener('click', function() { self.processFormatter('minify', this); });\r\n            document.getElementById('pth-btn-validate').addEventListener('click', function() { self.processFormatter('validate', this); });\r\n            document.getElementById('pth-btn-clear-f').addEventListener('click', function() { self.clearSection(self.UI.fInput, self.UI.fOutput, self.UI.fError); });\r\n            document.getElementById('pth-btn-copy-f').addEventListener('click', function() { self.copyText(self.UI.fOutput.value); });\r\n\r\n            \/\/ JSONPath Events\r\n            self.UI.jpInput.addEventListener('input', function() { self.runJSONPath(); });\r\n            self.UI.jpQuery.addEventListener('input', function() { self.runJSONPath(); });\r\n            document.getElementById('pth-btn-copy-jp').addEventListener('click', function() { self.copyText(self.UI.jpOutput.value); });\r\n            document.getElementById('pth-btn-export-jp').addEventListener('click', function() { self.downloadFile(self.UI.jpOutput.value, 'jsonpath_result', 'json'); });\r\n\r\n            \/\/ Converter Events\r\n            var btnJ2C = document.getElementById('pth-btn-j2c');\r\n            var btnC2J = document.getElementById('pth-btn-c2j');\r\n            \r\n            btnJ2C.addEventListener('click', function() {\r\n                self.currentConvertMode = 'j2c';\r\n                btnJ2C.classList.add('pth-active'); btnC2J.classList.remove('pth-active');\r\n                self.UI.cInput.placeholder = \"Paste JSON Array of Objects here...\";\r\n                self.runConverter();\r\n            });\r\n            btnC2J.addEventListener('click', function() {\r\n                self.currentConvertMode = 'c2j';\r\n                btnC2J.classList.add('pth-active'); btnJ2C.classList.remove('pth-active');\r\n                self.UI.cInput.placeholder = \"Paste CSV data here (first row = headers)...\";\r\n                self.runConverter();\r\n            });\r\n            \r\n            self.UI.cInput.addEventListener('input', function() { self.runConverter(); });\r\n            document.getElementById('pth-btn-clear-c').addEventListener('click', function() { self.clearSection(self.UI.cInput, self.UI.cOutput, self.UI.cError); });\r\n            document.getElementById('pth-btn-copy-c').addEventListener('click', function() { self.copyText(self.UI.cOutput.value); });\r\n            document.getElementById('pth-btn-export-c').addEventListener('click', function() { \r\n                var ext = self.currentConvertMode === 'j2c' ? 'csv' : 'json';\r\n                self.downloadFile(self.UI.cOutput.value, 'converted_data', ext); \r\n            });\r\n\r\n            \/\/ Tree Events\r\n            self.UI.tInput.addEventListener('input', function() { self.runTree(); });\r\n            document.getElementById('pth-btn-tree-expand').addEventListener('click', function() {\r\n                document.querySelectorAll('#pth-output-t details').forEach(function(d) { d.setAttribute('open', ''); });\r\n            });\r\n            document.getElementById('pth-btn-tree-collapse').addEventListener('click', function() {\r\n                document.querySelectorAll('#pth-output-t details').forEach(function(d) { d.removeAttribute('open'); });\r\n            });\r\n        },\r\n\r\n        showToast: function(msg) {\r\n            var t = this.UI.toast;\r\n            t.textContent = msg; t.style.display = 'block';\r\n            setTimeout(function() { t.style.display = 'none'; }, 3000);\r\n        },\r\n\r\n        toggleWidth: function() {\r\n            var layout = this.UI.layout;\r\n            if(!layout) return;\r\n            if(layout.classList.contains('pth-full-width')) {\r\n                layout.classList.remove('pth-full-width');\r\n                this.UI.sidebar.style.display = 'block';\r\n                this.UI.fwBtn.innerHTML = '\u26f6 Full Width';\r\n            } else {\r\n                layout.classList.add('pth-full-width');\r\n                this.UI.sidebar.style.display = 'none';\r\n                this.UI.fwBtn.innerHTML = '\u25e8 Split View';\r\n            }\r\n        },\r\n\r\n        clearSection: function(inEl, outEl, errEl) {\r\n            inEl.value = ''; outEl.value = ''; errEl.style.display = 'none'; inEl.classList.remove('pth-error');\r\n        },\r\n\r\n        copyText: function(text) {\r\n            if(!text) return this.showToast('Nothing to copy!');\r\n            var temp = document.createElement('textarea');\r\n            temp.value = text; document.body.appendChild(temp);\r\n            temp.select(); document.execCommand('copy');\r\n            document.body.removeChild(temp);\r\n            this.showToast('Copied to clipboard!');\r\n        },\r\n\r\n        downloadFile: function(content, filename, ext) {\r\n            if(!content || content.indexOf('Error') > -1 || content.indexOf('Invalid') > -1) return this.showToast('Invalid data to export');\r\n            var type = ext === 'csv' ? 'text\/csv' : 'application\/json';\r\n            var blob = new Blob([content], { type: type });\r\n            var a = document.createElement('a'); a.href = URL.createObjectURL(blob);\r\n            a.download = filename + '_' + new Date().getTime() + '.' + ext;\r\n            document.body.appendChild(a); a.click(); document.body.removeChild(a);\r\n        },\r\n\r\n        loadSample: function() {\r\n            var strJSON = JSON.stringify(this.sampleData.json, null, 4);\r\n            var strArr = JSON.stringify(this.sampleData.json.store.book, null, 4);\r\n\r\n            if (this.currentTab === 'formatter') {\r\n                this.UI.fInput.value = strJSON;\r\n                document.getElementById('pth-btn-format').click();\r\n            } else if (this.currentTab === 'jsonpath') {\r\n                this.UI.jpInput.value = strJSON;\r\n                this.UI.jpQuery.value = \"$.store.book[*].author\";\r\n                this.runJSONPath();\r\n            } else if (this.currentTab === 'converter') {\r\n                if (this.currentConvertMode === 'c2j') {\r\n                    this.UI.cInput.value = this.sampleData.csv;\r\n                } else {\r\n                    this.UI.cInput.value = strArr;\r\n                }\r\n                this.runConverter();\r\n            } else if (this.currentTab === 'tree') {\r\n                this.UI.tInput.value = strJSON;\r\n                this.runTree();\r\n            }\r\n            this.showToast('Sample loaded!');\r\n        },\r\n\r\n        updateCheatsheet: function() {\r\n            var tbody = this.UI.cheatsheetBody;\r\n            var html = '';\r\n            if (this.currentTab === 'jsonpath') {\r\n                html = '<tr><td><code class=\"pth-insert-code\">$<\/code><\/td><td>Root object<\/td><\/tr>' +\r\n                       '<tr><td><code class=\"pth-insert-code\">@<\/code><\/td><td>Current element<\/td><\/tr>' +\r\n                       '<tr><td><code class=\"pth-insert-code\">..<\/code><\/td><td>Recursive descent<\/td><\/tr>' +\r\n                       '<tr><td><code class=\"pth-insert-code\">*<\/code><\/td><td>Wildcard<\/td><\/tr>' +\r\n                       '<tr><td><code class=\"pth-insert-code\">[?()]<\/code><\/td><td>Filter expression<\/td><\/tr>';\r\n            } else if (this.currentTab === 'formatter') {\r\n                html = '<tr><td><code>{}<\/code><\/td><td>Object syntax<\/td><\/tr><tr><td><code>[]<\/code><\/td><td>Array syntax<\/td><\/tr>';\r\n            } else if (this.currentTab === 'converter') {\r\n                html = '<tr><td><code>[{\"a\":1}]<\/code><\/td><td>JSON Array required<\/td><\/tr><tr><td><code>CSV<\/code><\/td><td>First row = headers<\/td><\/tr>';\r\n            } else if (this.currentTab === 'tree') {\r\n                html = '<tr><td><code>\\u25B6<\/code><\/td><td>Click to expand<\/td><\/tr>';\r\n            }\r\n            tbody.innerHTML = html;\r\n\r\n            var self = this;\r\n            if(this.currentTab === 'jsonpath') {\r\n                document.querySelectorAll('#pth-cheatsheet-body .pth-insert-code').forEach(function(el) {\r\n                    el.addEventListener('click', function() {\r\n                        var qb = self.UI.jpQuery;\r\n                        qb.value = (qb.value === '$..*') ? this.innerText : qb.value + this.innerText;\r\n                        qb.focus(); self.runJSONPath();\r\n                    });\r\n                });\r\n            }\r\n        },\r\n\r\n        \/\/ --- Core Logic Functions ---\r\n\r\n        processFormatter: function(action, btnEl) {\r\n            var btns = [document.getElementById('pth-btn-format'), document.getElementById('pth-btn-minify'), document.getElementById('pth-btn-validate')];\r\n            btns.forEach(function(b) { b.classList.remove('pth-active'); });\r\n            btnEl.classList.add('pth-active');\r\n\r\n            var raw = this.UI.fInput.value.trim();\r\n            if(!raw) return this.clearSection(this.UI.fInput, this.UI.fOutput, this.UI.fError);\r\n\r\n            try {\r\n                var parsed = JSON.parse(raw);\r\n                if(action === 'format') this.UI.fOutput.value = JSON.stringify(parsed, null, 4);\r\n                else if (action === 'minify') this.UI.fOutput.value = JSON.stringify(parsed);\r\n                else if (action === 'validate') this.UI.fOutput.value = '\u2705 Valid JSON Structure:\\n\\n' + JSON.stringify(parsed, null, 2).substring(0, 500) + '...';\r\n                \r\n                this.UI.fError.style.display = 'none';\r\n                this.UI.fInput.classList.remove('pth-error');\r\n                this.showToast('Success!');\r\n            } catch(e) {\r\n                this.UI.fError.textContent = 'Syntax Error: ' + e.message;\r\n                this.UI.fError.style.display = 'block';\r\n                this.UI.fInput.classList.add('pth-error');\r\n                this.UI.fOutput.value = '';\r\n            }\r\n        },\r\n\r\n        runJSONPath: function() {\r\n            var raw = this.UI.jpInput.value.trim();\r\n            if(!raw) {\r\n                this.jpParsedObj = null; this.UI.jpOutput.value = ''; this.UI.jpCount.textContent = '0 Results'; \r\n                this.UI.jpError.style.display = 'none'; this.UI.jpInput.classList.remove('pth-error'); return;\r\n            }\r\n\r\n            try {\r\n                this.jpParsedObj = JSON.parse(raw);\r\n                this.UI.jpError.style.display = 'none';\r\n                this.UI.jpInput.classList.remove('pth-error');\r\n            } catch(e) {\r\n                this.UI.jpError.textContent = \"Syntax Error: \" + e.message;\r\n                this.UI.jpError.style.display = 'block';\r\n                this.UI.jpInput.classList.add('pth-error');\r\n                this.UI.jpOutput.value = ''; this.UI.jpCount.textContent = 'Error'; this.UI.jpCount.className = 'pth-badge pth-error';\r\n                return;\r\n            }\r\n\r\n            var path = this.UI.jpQuery.value.trim();\r\n            if(!path) return;\r\n\r\n            try {\r\n                \/\/ FIXED: Changed JSONPath to standard jsonpath from cdnjs\r\n                if (typeof jsonpath === 'undefined') {\r\n                    this.UI.jpOutput.value = \"Error: Library failed to load. Please check your internet connection or disable adblockers.\";\r\n                    return;\r\n                }\r\n                var result = jsonpath.query(this.jpParsedObj, path);\r\n                \r\n                if (result && result.length > 0) {\r\n                    this.UI.jpOutput.value = JSON.stringify(result, null, 4);\r\n                    this.UI.jpCount.textContent = result.length + (result.length > 1 ? ' Results' : ' Result');\r\n                    this.UI.jpCount.className = 'pth-badge pth-success';\r\n                } else {\r\n                    this.UI.jpOutput.value = \"[]\\n\/\/ No match found\";\r\n                    this.UI.jpCount.textContent = '0 Results';\r\n                    this.UI.jpCount.className = 'pth-badge';\r\n                }\r\n            } catch (e) {\r\n                this.UI.jpOutput.value = \"Invalid Expression:\\n\" + e.message;\r\n                this.UI.jpCount.textContent = 'Invalid Path';\r\n                this.UI.jpCount.className = 'pth-badge pth-error';\r\n            }\r\n        },\r\n\r\n        runConverter: function() {\r\n            var raw = this.UI.cInput.value.trim();\r\n            if(!raw) return this.clearSection(this.UI.cInput, this.UI.cOutput, this.UI.cError);\r\n\r\n            if(this.currentConvertMode === 'j2c') {\r\n                try {\r\n                    var data = JSON.parse(raw);\r\n                    if (!Array.isArray(data) || data.length === 0 || typeof data[0] !== 'object') {\r\n                        throw new Error('Input must be a JSON Array of Objects (e.g. [{\"id\":1}]).');\r\n                    }\r\n                    var headers = Object.keys(data[0]);\r\n                    var csv = headers.join(',') + '\\n';\r\n                    data.forEach(function(row) {\r\n                        csv += headers.map(function(h) {\r\n                            var v = row[h];\r\n                            if(v === null || v === undefined) return '';\r\n                            if(typeof v === 'object') v = JSON.stringify(v);\r\n                            v = String(v);\r\n                            if(v.indexOf(',') > -1 || v.indexOf('\"') > -1 || v.indexOf('\\n') > -1) {\r\n                                v = '\"' + v.replace(\/\"\/g, '\"\"') + '\"';\r\n                            }\r\n                            return v;\r\n                        }).join(',') + '\\n';\r\n                    });\r\n                    this.UI.cOutput.value = csv;\r\n                    this.UI.cError.style.display = 'none'; this.UI.cInput.classList.remove('pth-error');\r\n                } catch(e) {\r\n                    this.UI.cError.textContent = 'Error: ' + e.message;\r\n                    this.UI.cError.style.display = 'block'; this.UI.cInput.classList.add('pth-error'); this.UI.cOutput.value = '';\r\n                }\r\n            } else {\r\n                try {\r\n                    var lines = raw.split(\/\\r?\\n\/).filter(function(l) { return l.trim() !== ''; });\r\n                    if(lines.length < 2) throw new Error('CSV must have a header row and at least one data row.');\r\n                    \r\n                    var parseLine = function(line) {\r\n                        var regex = \/(?:,|\\n|^)(\"(?:(?:\"\")*[^\"]*)*\"|[^\",\\n]*|(?:\\n|$))\/g;\r\n                        var matches = []; var match;\r\n                        while (match = regex.exec(line)) {\r\n                            var val = match[1];\r\n                            if (val !== undefined) { val = val.replace(\/^\"|\"$\/g, '').replace(\/\"\"\/g, '\"'); matches.push(val); }\r\n                            if(regex.lastIndex === match.index) regex.lastIndex++; \r\n                        }\r\n                        return matches.length > 0 ? matches : line.split(','); \r\n                    };\r\n\r\n                    var headers = parseLine(lines[0]);\r\n                    var jsonArr = [];\r\n                    \r\n                    for(var i = 1; i < lines.length; i++) {\r\n                        var currentLine = parseLine(lines[i]);\r\n                        var obj = {};\r\n                        headers.forEach(function(header, index) {\r\n                            var val = currentLine[index] !== undefined ? currentLine[index].trim() : '';\r\n                            if(val !== '' && !isNaN(val)) val = Number(val);\r\n                            else if (typeof val === 'string') {\r\n                                if(val.toLowerCase() === 'true') val = true;\r\n                                if(val.toLowerCase() === 'false') val = false;\r\n                            }\r\n                            obj[header.trim()] = val;\r\n                        });\r\n                        jsonArr.push(obj);\r\n                    }\r\n                    this.UI.cOutput.value = JSON.stringify(jsonArr, null, 4);\r\n                    this.UI.cError.style.display = 'none'; this.UI.cInput.classList.remove('pth-error');\r\n                } catch(e) {\r\n                    this.UI.cError.textContent = 'Error: ' + e.message;\r\n                    this.UI.cError.style.display = 'block'; this.UI.cInput.classList.add('pth-error'); this.UI.cOutput.value = '';\r\n                }\r\n            }\r\n        },\r\n\r\n        runTree: function() {\r\n            var raw = this.UI.tInput.value.trim();\r\n            if(!raw) { this.UI.tOutput.innerHTML = ''; this.UI.tError.style.display = 'none'; return; }\r\n            \r\n            var self = this;\r\n            try {\r\n                var data = JSON.parse(raw);\r\n                this.UI.tOutput.innerHTML = this.buildTreeHTML(data, 'root');\r\n                this.UI.tError.style.display = 'none'; this.UI.tInput.classList.remove('pth-error');\r\n            } catch(e) {\r\n                this.UI.tError.textContent = 'Invalid JSON: ' + e.message;\r\n                this.UI.tError.style.display = 'block'; this.UI.tInput.classList.add('pth-error'); this.UI.tOutput.innerHTML = '';\r\n            }\r\n        },\r\n\r\n        buildTreeHTML: function(obj, key) {\r\n            if (obj === null) return '\\x3Cspan style=\"color:#ef4444; font-weight:bold;\"\\x3Enull\\x3C\/span\\x3E';\r\n            if (typeof obj === 'boolean') return '\\x3Cspan style=\"color:#eab308; font-weight:bold;\"\\x3E' + obj + '\\x3C\/span\\x3E';\r\n            if (typeof obj === 'number') return '\\x3Cspan style=\"color:#0ea5e9;\"\\x3E' + obj + '\\x3C\/span\\x3E';\r\n            if (typeof obj === 'string') return '\\x3Cspan style=\"color:#16a34a;\"\\x3E\"' + obj + '\"\\x3C\/span\\x3E';\r\n            \r\n            var isArray = Array.isArray(obj);\r\n            var label = key ? '\\x3Cspan style=\"color:#2563eb; font-weight:bold;\"\\x3E\"' + key + '\"\\x3C\/span\\x3E: ' : '';\r\n            var openBracket = isArray ? '[' : '{';\r\n            var closeBracket = isArray ? ']' : '}';\r\n            var size = Object.keys(obj).length;\r\n            \r\n            if (size === 0) return label + openBracket + closeBracket;\r\n\r\n            var html = '\\x3Cdetails open style=\"margin-left: 4px;\"\\x3E';\r\n            html += '\\x3Csummary style=\"outline:none;\"\\x3E' + label + '\\x3Cspan style=\"color:#64748b; font-size:11px; margin-left:4px;\"\\x3E' + openBracket + ' ' + size + ' item' + (size>1?'s':'') + '\\x3C\/span\\x3E\\x3C\/summary\\x3E';\r\n            html += '\\x3Cul style=\"border-left: 1px dashed #cbd5e1; margin: 2px 0 2px 8px; padding-left: 12px;\"\\x3E';\r\n            \r\n            for (var k in obj) {\r\n                if (Object.prototype.hasOwnProperty.call(obj, k)) {\r\n                    html += '\\x3Cli style=\"margin: 4px 0;\"\\x3E' + this.buildTreeHTML(obj[k], isArray ? '' : k) + '\\x3C\/li\\x3E';\r\n                }\r\n            }\r\n            \r\n            html += '\\x3C\/ul\\x3E\\x3Cdiv style=\"color:#64748b; margin-left:4px;\"\\x3E' + closeBracket + '\\x3C\/div\\x3E\\x3C\/details\\x3E';\r\n            return html;\r\n        }\r\n    };\r\n\r\n    \/\/ Bulletproof Initializer\r\n    function runInit() {\r\n        if (!window.pthJsonToolkitApp.initialized) {\r\n            window.pthJsonToolkitApp.initialized = true;\r\n            window.pthJsonToolkitApp.init();\r\n        }\r\n    }\r\n\r\n    if (document.readyState === 'complete' || document.readyState === 'interactive') { setTimeout(runInit, 1); } \r\n    else { document.addEventListener('DOMContentLoaded', runInit); window.addEventListener('load', runInit); }\r\n})();\r\n<\/script>\r\n\t<script data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\">\r\n(function () {\r\n  'use strict';\r\n  function mount() {\r\n    var panel = document.getElementById('pth-jh-tab-query');\r\n    var tool  = document.getElementById('pth-json-toolkit-wrapper');\r\n    if (!panel || !tool) return false;\r\n    if (tool.parentNode !== panel) {\r\n      var ph = document.getElementById('pth-jh-empty-query');\r\n      if (ph && ph.parentNode) ph.parentNode.removeChild(ph);\r\n      tool.style.margin = '0';\r\n      panel.appendChild(tool);\r\n    }\r\n    return true;\r\n  }\r\n  if (mount()) return;\r\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mount);\r\n  window.addEventListener('load', function () { setTimeout(mount, 60); });\r\n  if (typeof MutationObserver !== 'undefined') {\r\n    var o = new MutationObserver(function () { if (mount()) o.disconnect(); });\r\n    o.observe(document.body || document.documentElement, { childList: true, subtree: true });\r\n    setTimeout(function () { o.disconnect(); }, 10000);\r\n  }\r\n})();\r\n<\/script>\n\n\n<!-- LSCACHE_DISABLE -->\r\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/js-yaml\/4.1.0\/js-yaml.min.js\" data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\"><\/script>\r\n<div id=\"pth-json-studio-wrapper\">\r\n\r\n<style data-no-optimize=\"1\">\r\n#pth-json-studio-wrapper *,#pth-json-studio-wrapper *::before,#pth-json-studio-wrapper *::after{box-sizing:border-box;min-width:0;}\r\n#pth-json-studio-wrapper{font-family:'Inter',system-ui,sans-serif;background:#ffffff;border:1px solid #e2e8f0;border-radius:14px;padding:22px;color:#1e293b;font-weight:500;opacity:1;display:block;margin:20px 0;}\r\n#pth-json-studio-wrapper h2{color:#1d4ed8;font-size:1.5rem;font-weight:800;margin:0 0 4px;}\r\n.pth-cv-header{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;flex-wrap:wrap;margin-bottom:18px;}\r\n.pth-cv-sub{color:#334155;font-size:.9rem;font-weight:500;margin:0;}\r\n.pth-cv-badges{display:flex;gap:8px;margin-top:8px;flex-wrap:wrap;}\r\n.pth-cv-badge{font-size:.72rem;font-weight:700;padding:3px 10px;border-radius:20px;}\r\n.pth-cv-badge.ver{background:#eff6ff;color:#1d4ed8;border:1px solid #bfdbfe;}\r\n.pth-cv-badge.off{background:#f0fdf4;color:#047857;border:1px solid #bbf7d0;}\r\n.pth-cv-controls{display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end;margin-bottom:16px;padding:14px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:10px;}\r\n.pth-cv-field{display:flex;flex-direction:column;gap:5px;}\r\n.pth-cv-field label{font-size:.78rem;font-weight:700;color:#334155;}\r\n.pth-cv-select,.pth-cv-input{font-family:'Inter',system-ui,sans-serif;font-size:.9rem;font-weight:600;color:#1e293b;padding:9px 12px;border:2px solid #cbd5e1;border-radius:8px;background:#fff;min-height:42px;}\r\n.pth-cv-select:focus,.pth-cv-input:focus{outline:none;border-color:#2563eb;}\r\n.pth-cv-btn{font-family:'Inter',system-ui,sans-serif;font-size:.88rem;font-weight:700;padding:10px 18px;border:none;border-radius:8px;cursor:pointer;transition:all .15s;min-height:42px;}\r\n.pth-cv-btn-primary{background:#2563eb;color:#fff;}\r\n.pth-cv-btn-primary:hover{background:#1d4ed8;}\r\n.pth-cv-btn-sec{background:#fff;color:#334155;border:2px solid #cbd5e1;}\r\n.pth-cv-btn-sec:hover{border-color:#2563eb;color:#1d4ed8;}\r\n.pth-cv-btn-danger{background:#fff;color:#991b1b;border:2px solid #fecaca;}\r\n.pth-cv-btn-danger:hover{background:#fef2f2;}\r\n.pth-cv-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;}\r\n.pth-cv-col-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;}\r\n.pth-cv-col-title{font-size:.82rem;font-weight:800;color:#0f172a;text-transform:uppercase;letter-spacing:.5px;}\r\n.pth-cv-area{width:100%;min-height:320px;font-family:'Courier New',monospace;font-size:.85rem;line-height:1.5;color:#1e293b;padding:14px;border:2px solid #e2e8f0;border-radius:10px;background:#f8fafc;resize:vertical;}\r\n.pth-cv-area:focus{outline:none;border-color:#2563eb;background:#fff;}\r\n.pth-cv-area[readonly]{background:#f0fdf4;border-color:#bbf7d0;}\r\n.pth-cv-mini{font-size:.75rem;font-weight:700;padding:5px 10px;border-radius:6px;cursor:pointer;border:1px solid #cbd5e1;background:#fff;color:#334155;}\r\n.pth-cv-mini:hover{border-color:#2563eb;color:#1d4ed8;}\r\n.pth-cv-toast{position:fixed;bottom:20px;right:20px;padding:12px 18px;border-radius:10px;font-size:.85rem;font-weight:700;color:#fff;box-shadow:0 10px 25px rgba(0,0,0,.2);z-index:99999;opacity:0;transform:translateY(10px);transition:opacity .2s,transform .2s;pointer-events:none;max-width:320px;}\r\n.pth-cv-toast.show{opacity:1;transform:translateY(0);}\r\n.pth-cv-toast.ok{background:#059669;}\r\n.pth-cv-toast.err{background:#dc2626;}\r\n.pth-cv-toast.info{background:#2563eb;}\r\n#pth-json-studio-wrapper.pth-cv-fullwidth{position:fixed;inset:0;z-index:99998;margin:0;border-radius:0;overflow:auto;}\r\n@media(max-width:768px){.pth-cv-grid{grid-template-columns:1fr;}#pth-json-studio-wrapper{padding:12px;}#pth-json-studio-wrapper h2{font-size:1.2rem;}}\r\n<\/style>\r\n\r\n<div class=\"pth-cv-header\">\r\n  <div>\r\n    <h2>\ud83d\udd04 Data Format Converter<\/h2>\r\n    <p class=\"pth-cv-sub\">Convert between JSON, CSV, XML, YAML, TSV and SQL \u2014 all in your browser.<\/p>\r\n    <div class=\"pth-cv-badges\">\r\n      <span class=\"pth-cv-badge ver\">v2.0<\/span>\r\n      <span class=\"pth-cv-badge off\">\ud83d\udd12 100% Offline<\/span>\r\n    <\/div>\r\n  <\/div>\r\n  <button type=\"button\" class=\"pth-cv-btn pth-cv-btn-sec\" id=\"pth-cv-fullwidth\" aria-label=\"Toggle full width\">\u26f6 Full Width<\/button>\r\n<\/div>\r\n\r\n<div class=\"pth-cv-controls\">\r\n  <div class=\"pth-cv-field\">\r\n    <label for=\"pth-cv-mode\">Conversion<\/label>\r\n    <select class=\"pth-cv-select\" id=\"pth-cv-mode\" aria-label=\"Choose conversion type\">\r\n      <option value=\"csv2json\">CSV \u2192 JSON<\/option>\r\n      <option value=\"json2csv\">JSON \u2192 CSV<\/option>\r\n      <option value=\"xml2json\">XML \u2192 JSON<\/option>\r\n      <option value=\"json2xml\">JSON \u2192 XML<\/option>\r\n      <option value=\"yaml2json\">YAML \u2192 JSON<\/option>\r\n      <option value=\"json2yaml\">JSON \u2192 YAML<\/option>\r\n      <option value=\"tsv2json\">TSV \u2192 JSON<\/option>\r\n      <option value=\"json2tsv\">JSON \u2192 TSV<\/option>\r\n      <option value=\"json2sql\">JSON \u2192 SQL (INSERT)<\/option>\r\n    <\/select>\r\n  <\/div>\r\n  <div class=\"pth-cv-field\" id=\"pth-cv-table-field\" style=\"display:none;\">\r\n    <label for=\"pth-cv-table\">SQL table name<\/label>\r\n    <input type=\"text\" class=\"pth-cv-input\" id=\"pth-cv-table\" value=\"my_table\" aria-label=\"SQL table name\">\r\n  <\/div>\r\n  <button type=\"button\" class=\"pth-cv-btn pth-cv-btn-primary\" id=\"pth-cv-convert\" aria-label=\"Run conversion\">\u26a1 Convert<\/button>\r\n  <button type=\"button\" class=\"pth-cv-btn pth-cv-btn-sec\" id=\"pth-cv-sample\" aria-label=\"Load sample data\">\ud83d\udca1 Load Sample<\/button>\r\n  <button type=\"button\" class=\"pth-cv-btn pth-cv-btn-danger\" id=\"pth-cv-clear\" aria-label=\"Clear all\">\ud83d\uddd1\ufe0f Clear<\/button>\r\n<\/div>\r\n\r\n<div class=\"pth-cv-grid\">\r\n  <div>\r\n    <div class=\"pth-cv-col-head\">\r\n      <span class=\"pth-cv-col-title\">Input<\/span>\r\n      <button type=\"button\" class=\"pth-cv-mini\" id=\"pth-cv-paste\" aria-label=\"Paste from clipboard\">\ud83d\udccb Paste<\/button>\r\n    <\/div>\r\n    <textarea class=\"pth-cv-area\" id=\"pth-cv-input\" placeholder=\"Paste your data here, pick a conversion, then hit Convert\u2026\" aria-label=\"Input data\" spellcheck=\"false\"><\/textarea>\r\n  <\/div>\r\n  <div>\r\n    <div class=\"pth-cv-col-head\">\r\n      <span class=\"pth-cv-col-title\">Output<\/span>\r\n      <span>\r\n        <button type=\"button\" class=\"pth-cv-mini\" id=\"pth-cv-copy\" aria-label=\"Copy output\">\ud83d\udcc4 Copy<\/button>\r\n        <button type=\"button\" class=\"pth-cv-mini\" id=\"pth-cv-download\" aria-label=\"Download output\">\u2b07\ufe0f Download<\/button>\r\n      <\/span>\r\n    <\/div>\r\n    <textarea class=\"pth-cv-area\" id=\"pth-cv-output\" readonly placeholder=\"Converted output appears here\u2026\" aria-label=\"Converted output\" spellcheck=\"false\"><\/textarea>\r\n  <\/div>\r\n<\/div>\r\n\r\n<div class=\"pth-cv-toast\" id=\"pth-cv-toast\" role=\"status\" aria-live=\"polite\"><\/div>\r\n\r\n<\/div>\r\n<script data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\">\r\n(function () {\r\n  'use strict';\r\n\r\n  window.pthConverterApp = window.pthConverterApp || {};\r\n  var App = window.pthConverterApp;\r\n\r\n  App.el = {};\r\n\r\n  App.toast = function (msg, type) {\r\n    var t = App.el.toast;\r\n    if (!t) return;\r\n    t.className = 'pth-cv-toast ' + (type || 'info');\r\n    t.textContent = msg;\r\n    void t.offsetWidth;\r\n    t.classList.add('show');\r\n    clearTimeout(App._tt);\r\n    App._tt = setTimeout(function () { t.classList.remove('show'); }, 3000);\r\n  };\r\n\r\n  \/* ---------- helpers ---------- *\/\r\n  App.parseDelimited = function (text, delim) {\r\n    var rows = [], row = [], field = '', inQ = false, i, c;\r\n    for (i = 0; i < text.length; i++) {\r\n      c = text.charAt(i);\r\n      if (inQ) {\r\n        if (c === '\"') {\r\n          if (text.charAt(i + 1) === '\"') { field += '\"'; i++; }\r\n          else { inQ = false; }\r\n        } else { field += c; }\r\n      } else {\r\n        if (c === '\"') { inQ = true; }\r\n        else if (c === delim) { row.push(field); field = ''; }\r\n        else if (c === '\\n') { row.push(field); rows.push(row); row = []; field = ''; }\r\n        else if (c === '\\r') { \/* skip *\/ }\r\n        else { field += c; }\r\n      }\r\n    }\r\n    if (field !== '' || row.length > 0) { row.push(field); rows.push(row); }\r\n    return rows;\r\n  };\r\n\r\n  App.delimitedToJson = function (text, delim) {\r\n    var rows = App.parseDelimited(text.replace(\/\\n+$\/, ''), delim);\r\n    if (rows.length < 1) { throw new Error('No rows found in the input.'); }\r\n    var headers = rows[0], out = [], r, obj, h;\r\n    for (r = 1; r < rows.length; r++) {\r\n      obj = {};\r\n      for (h = 0; h < headers.length; h++) {\r\n        obj[headers[h]] = rows[r][h] !== undefined ? rows[r][h] : '';\r\n      }\r\n      out.push(obj);\r\n    }\r\n    return JSON.stringify(out, null, 2);\r\n  };\r\n\r\n  App.needsQuote = function (val, delim) {\r\n    return val.indexOf(delim) !== -1 || val.indexOf('\"') !== -1 || val.indexOf('\\n') !== -1;\r\n  };\r\n\r\n  App.jsonToDelimited = function (text, delim) {\r\n    var data = JSON.parse(text);\r\n    if (!Array.isArray(data)) { throw new Error('Input must be a JSON array of objects.'); }\r\n    if (data.length === 0) { return ''; }\r\n    var keys = [], seen = {}, i, k, line, lines = [];\r\n    for (i = 0; i < data.length; i++) {\r\n      for (k in data[i]) {\r\n        if (data[i].hasOwnProperty(k) && !seen[k]) { seen[k] = true; keys.push(k); }\r\n      }\r\n    }\r\n    var esc = function (v) {\r\n      if (v === null || v === undefined) { return ''; }\r\n      if (typeof v === 'object') { v = JSON.stringify(v); }\r\n      v = String(v);\r\n      if (App.needsQuote(v, delim)) { v = '\"' + v.replace(\/\"\/g, '\"\"') + '\"'; }\r\n      return v;\r\n    };\r\n    lines.push(keys.join(delim));\r\n    for (i = 0; i < data.length; i++) {\r\n      line = [];\r\n      for (k = 0; k < keys.length; k++) { line.push(esc(data[i][keys[k]])); }\r\n      lines.push(line.join(delim));\r\n    }\r\n    return lines.join('\\n');\r\n  };\r\n\r\n  App.xmlNodeToObj = function (node) {\r\n    var obj = {}, i, a, ch, childObj, name, hasEl = false, text;\r\n    if (node.attributes && node.attributes.length) {\r\n      for (a = 0; a < node.attributes.length; a++) {\r\n        obj['@' + node.attributes[a].name] = node.attributes[a].value;\r\n      }\r\n    }\r\n    for (i = 0; i < node.childNodes.length; i++) {\r\n      ch = node.childNodes[i];\r\n      if (ch.nodeType === 1) {\r\n        hasEl = true;\r\n        name = ch.nodeName;\r\n        childObj = App.xmlNodeToObj(ch);\r\n        if (obj[name] !== undefined) {\r\n          if (Object.prototype.toString.call(obj[name]) !== '[object Array]') { obj[name] = [obj[name]]; }\r\n          obj[name].push(childObj);\r\n        } else { obj[name] = childObj; }\r\n      }\r\n    }\r\n    if (!hasEl) {\r\n      text = (node.textContent || '').replace(\/^\\s+|\\s+$\/g, '');\r\n      if (node.attributes && node.attributes.length) {\r\n        if (text) { obj['#text'] = text; }\r\n        return obj;\r\n      }\r\n      return text;\r\n    }\r\n    return obj;\r\n  };\r\n\r\n  App.xmlToJson = function (text) {\r\n    var parser = new DOMParser();\r\n    var doc = parser.parseFromString(text, 'application\/xml');\r\n    var err = doc.getElementsByTagName('parsererror');\r\n    if (err && err.length) { throw new Error('Invalid XML. Check your tags are balanced.'); }\r\n    var root = doc.documentElement;\r\n    var wrap = {};\r\n    wrap[root.nodeName] = App.xmlNodeToObj(root);\r\n    return JSON.stringify(wrap, null, 2);\r\n  };\r\n\r\n  App.escapeXml = function (s) {\r\n    return String(s).replace(\/&\/g, '&amp;').replace(\/<\/g, '&lt;').replace(\/>\/g, '&gt;')\r\n      .replace(\/\"\/g, '&quot;').replace(\/'\/g, '&apos;');\r\n  };\r\n\r\n  App.objToXml = function (obj, name, indent) {\r\n    var open = '<' + name + '>';\r\n    var close = '<' + '\/' + name + '>';\r\n    var out = '', k, i, type = Object.prototype.toString.call(obj);\r\n    if (obj === null || obj === undefined) { return indent + open + close + '\\n'; }\r\n    if (type === '[object Array]') {\r\n      for (i = 0; i < obj.length; i++) { out += App.objToXml(obj[i], name, indent); }\r\n      return out;\r\n    }\r\n    if (typeof obj !== 'object') {\r\n      return indent + open + App.escapeXml(obj) + close + '\\n';\r\n    }\r\n    out += indent + open + '\\n';\r\n    for (k in obj) {\r\n      if (obj.hasOwnProperty(k)) {\r\n        out += App.objToXml(obj[k], k.replace(\/^@\/, ''), indent + '  ');\r\n      }\r\n    }\r\n    out += indent + close + '\\n';\r\n    return out;\r\n  };\r\n\r\n  App.jsonToXml = function (text) {\r\n    var data = JSON.parse(text);\r\n    var rootName = 'root', inner = data;\r\n    var keys = [];\r\n    if (data && typeof data === 'object' && Object.prototype.toString.call(data) !== '[object Array]') {\r\n      for (var kk in data) { if (data.hasOwnProperty(kk)) { keys.push(kk); } }\r\n      if (keys.length === 1) { rootName = keys[0]; inner = data[keys[0]]; }\r\n    }\r\n    var body = App.objToXml(inner, rootName, '');\r\n    return '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n' + body.replace(\/\\n$\/, '');\r\n  };\r\n\r\n  App.yamlToJson = function (text) {\r\n    if (typeof jsyaml === 'undefined') { throw new Error('YAML library still loading \u2014 try again in a second.'); }\r\n    var obj = jsyaml.load(text);\r\n    return JSON.stringify(obj, null, 2);\r\n  };\r\n\r\n  App.jsonToYaml = function (text) {\r\n    if (typeof jsyaml === 'undefined') { throw new Error('YAML library still loading \u2014 try again in a second.'); }\r\n    return jsyaml.dump(JSON.parse(text));\r\n  };\r\n\r\n  App.jsonToSql = function (text, table) {\r\n    var data = JSON.parse(text);\r\n    if (Object.prototype.toString.call(data) !== '[object Array]') { throw new Error('Input must be a JSON array of objects.'); }\r\n    if (data.length === 0) { return ''; }\r\n    table = (table || 'my_table').replace(\/[^a-zA-Z0-9_]\/g, '') || 'my_table';\r\n    var keys = [], seen = {}, i, k, sqlVal, cols, vals, lines = [];\r\n    for (i = 0; i < data.length; i++) {\r\n      for (k in data[i]) { if (data[i].hasOwnProperty(k) && !seen[k]) { seen[k] = true; keys.push(k); } }\r\n    }\r\n    sqlVal = function (v) {\r\n      if (v === null || v === undefined) { return 'NULL'; }\r\n      if (typeof v === 'number') { return String(v); }\r\n      if (typeof v === 'boolean') { return v ? '1' : '0'; }\r\n      if (typeof v === 'object') { v = JSON.stringify(v); }\r\n      return \"'\" + String(v).replace(\/'\/g, \"''\") + \"'\";\r\n    };\r\n    cols = keys.join(', ');\r\n    for (i = 0; i < data.length; i++) {\r\n      vals = [];\r\n      for (k = 0; k < keys.length; k++) { vals.push(sqlVal(data[i][keys[k]])); }\r\n      lines.push('INSERT INTO ' + table + ' (' + cols + ') VALUES (' + vals.join(', ') + ');');\r\n    }\r\n    return lines.join('\\n');\r\n  };\r\n\r\n  \/* ---------- samples ---------- *\/\r\n  App.samples = {\r\n    csv2json: 'name,role,active\\nAmara,Editor,true\\nBen,Author,false',\r\n    json2csv: '[\\n  {\"name\":\"Amara\",\"role\":\"Editor\"},\\n  {\"name\":\"Ben\",\"role\":\"Author\"}\\n]',\r\n    xml2json: '<staff>\\n  <person id=\"1\"><name>Amara<\/name><role>Editor<\/role><\/person>\\n  <person id=\"2\"><name>Ben<\/name><role>Author<\/role><\/person>\\n<\/staff>',\r\n    json2xml: '{\\n  \"staff\": {\\n    \"person\": [\\n      {\"name\":\"Amara\",\"role\":\"Editor\"},\\n      {\"name\":\"Ben\",\"role\":\"Author\"}\\n    ]\\n  }\\n}',\r\n    yaml2json: 'name: Amara\\nrole: Editor\\nskills:\\n  - editing\\n  - proofreading',\r\n    json2yaml: '{\\n  \"name\":\"Amara\",\\n  \"role\":\"Editor\",\\n  \"skills\":[\"editing\",\"proofreading\"]\\n}',\r\n    tsv2json: 'name\\trole\\tactive\\nAmara\\tEditor\\ttrue\\nBen\\tAuthor\\tfalse',\r\n    json2tsv: '[\\n  {\"name\":\"Amara\",\"role\":\"Editor\"},\\n  {\"name\":\"Ben\",\"role\":\"Author\"}\\n]',\r\n    json2sql: '[\\n  {\"id\":1,\"name\":\"Amara\",\"role\":\"Editor\"},\\n  {\"id\":2,\"name\":\"Ben\",\"role\":\"Author\"}\\n]'\r\n  };\r\n\r\n  App.dispatch = function () {\r\n    var mode = App.el.mode.value;\r\n    var input = App.el.input.value;\r\n    if (!input.replace(\/\\s\/g, '')) { App.toast('Add some input first.', 'err'); return; }\r\n    var out = '';\r\n    try {\r\n      if (mode === 'csv2json') { out = App.delimitedToJson(input, ','); }\r\n      else if (mode === 'json2csv') { out = App.jsonToDelimited(input, ','); }\r\n      else if (mode === 'xml2json') { out = App.xmlToJson(input); }\r\n      else if (mode === 'json2xml') { out = App.jsonToXml(input); }\r\n      else if (mode === 'yaml2json') { out = App.yamlToJson(input); }\r\n      else if (mode === 'json2yaml') { out = App.jsonToYaml(input); }\r\n      else if (mode === 'tsv2json') { out = App.delimitedToJson(input, '\\t'); }\r\n      else if (mode === 'json2tsv') { out = App.jsonToDelimited(input, '\\t'); }\r\n      else if (mode === 'json2sql') { out = App.jsonToSql(input, App.el.table.value); }\r\n      App.el.output.value = out;\r\n      App.toast('Converted successfully.', 'ok');\r\n    } catch (e) {\r\n      App.el.output.value = '';\r\n      App.toast('Error: ' + e.message, 'err');\r\n    }\r\n  };\r\n\r\n  App.updateTableField = function () {\r\n    App.el.tableField.style.display = (App.el.mode.value === 'json2sql') ? 'flex' : 'none';\r\n  };\r\n\r\n  App.download = function () {\r\n    var out = App.el.output.value;\r\n    if (!out) { App.toast('Nothing to download yet.', 'err'); return; }\r\n    var mode = App.el.mode.value, ext = 'txt';\r\n    if (mode.indexOf('2json') !== -1) { ext = 'json'; }\r\n    else if (mode === 'json2csv') { ext = 'csv'; }\r\n    else if (mode === 'json2xml') { ext = 'xml'; }\r\n    else if (mode === 'json2yaml') { ext = 'yaml'; }\r\n    else if (mode === 'json2tsv') { ext = 'tsv'; }\r\n    else if (mode === 'json2sql') { ext = 'sql'; }\r\n    var blob = new Blob([out], { type: 'text\/plain' });\r\n    var url = URL.createObjectURL(blob);\r\n    var a = document.createElement('a');\r\n    a.href = url; a.download = 'converted.' + ext;\r\n    document.body.appendChild(a); a.click();\r\n    document.body.removeChild(a);\r\n    setTimeout(function () { URL.revokeObjectURL(url); }, 1000);\r\n    App.toast('Downloaded converted.' + ext, 'ok');\r\n  };\r\n\r\n  App.bind = function () {\r\n    var el = App.el;\r\n    el.convert.addEventListener('click', App.dispatch);\r\n    el.mode.addEventListener('change', App.updateTableField);\r\n    el.sample.addEventListener('click', function () {\r\n      el.input.value = App.samples[el.mode.value] || '';\r\n      App.toast('Sample loaded \u2014 hit Convert.', 'info');\r\n    });\r\n    el.clear.addEventListener('click', function () {\r\n      el.input.value = ''; el.output.value = '';\r\n      App.toast('Cleared.', 'info');\r\n    });\r\n    el.copy.addEventListener('click', function () {\r\n      if (!el.output.value) { App.toast('Nothing to copy yet.', 'err'); return; }\r\n      if (navigator.clipboard && navigator.clipboard.writeText) {\r\n        navigator.clipboard.writeText(el.output.value).then(function () { App.toast('Copied to clipboard.', 'ok'); },\r\n          function () { App.toast('Copy failed.', 'err'); });\r\n      } else {\r\n        el.output.removeAttribute('readonly'); el.output.select();\r\n        try { document.execCommand('copy'); App.toast('Copied to clipboard.', 'ok'); }\r\n        catch (e) { App.toast('Copy failed.', 'err'); }\r\n        el.output.setAttribute('readonly', 'readonly');\r\n      }\r\n    });\r\n    el.download.addEventListener('click', App.download);\r\n    el.paste.addEventListener('click', function () {\r\n      if (navigator.clipboard && navigator.clipboard.readText) {\r\n        navigator.clipboard.readText().then(function (txt) { el.input.value = txt; App.toast('Pasted from clipboard.', 'ok'); },\r\n          function () { App.toast('Clipboard blocked \u2014 paste manually.', 'err'); });\r\n      } else { App.toast('Clipboard not available \u2014 paste manually.', 'info'); }\r\n    });\r\n    el.fullwidth.addEventListener('click', function () {\r\n      document.getElementById('pth-json-studio-wrapper').classList.toggle('pth-cv-fullwidth');\r\n    });\r\n  };\r\n\r\n  App.init = function () {\r\n    var g = function (id) { return document.getElementById(id); };\r\n    App.el = {\r\n      mode: g('pth-cv-mode'), table: g('pth-cv-table'), tableField: g('pth-cv-table-field'),\r\n      convert: g('pth-cv-convert'), sample: g('pth-cv-sample'), clear: g('pth-cv-clear'),\r\n      input: g('pth-cv-input'), output: g('pth-cv-output'),\r\n      copy: g('pth-cv-copy'), download: g('pth-cv-download'), paste: g('pth-cv-paste'),\r\n      fullwidth: g('pth-cv-fullwidth'), toast: g('pth-cv-toast')\r\n    };\r\n    if (!App.el.convert) { return; }\r\n    App.bind();\r\n    App.updateTableField();\r\n  };\r\n\r\n  function runInit() {\r\n    if (App.initialized) { return; }\r\n    if (!document.getElementById('pth-cv-convert')) { return; }\r\n    App.initialized = true;\r\n    App.init();\r\n  }\r\n\r\n  runInit();\r\n  if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', runInit); }\r\n  window.addEventListener('load', function () { setTimeout(runInit, 50); });\r\n  if (!App.initialized && typeof MutationObserver !== 'undefined') {\r\n    var obs = new MutationObserver(function () {\r\n      if (document.getElementById('pth-cv-convert')) { obs.disconnect(); runInit(); }\r\n    });\r\n    obs.observe(document.body || document.documentElement, { childList: true, subtree: true });\r\n    setTimeout(function () { obs.disconnect(); }, 10000);\r\n  }\r\n})();\r\n<\/script>\r\n\r\n<script data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\">\r\n(function () {\r\n  'use strict';\r\n  function mount() {\r\n    var panel = document.getElementById('pth-jh-tab-convert');\r\n    var tool = document.getElementById('pth-json-studio-wrapper');\r\n    if (!panel || !tool) { return false; }\r\n    if (tool.parentNode !== panel) {\r\n      var ph = document.getElementById('pth-jh-empty-convert');\r\n      if (ph && ph.parentNode) { ph.parentNode.removeChild(ph); }\r\n      tool.style.margin = '0';\r\n      panel.appendChild(tool);\r\n    }\r\n    return true;\r\n  }\r\n  if (mount()) { return; }\r\n  if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', mount); }\r\n  window.addEventListener('load', function () { setTimeout(mount, 60); });\r\n  if (typeof MutationObserver !== 'undefined') {\r\n    var o = new MutationObserver(function () { if (mount()) { o.disconnect(); } });\r\n    o.observe(document.body || document.documentElement, { childList: true, subtree: true });\r\n    setTimeout(function () { o.disconnect(); }, 10000);\r\n  }\r\n})();\r\n<\/script>\n\n\n\n<style>\n.pth-container{max-width:1480px;margin:0 auto;padding:0 20px;box-sizing:border-box}\n.pth-feature-wrap{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px;margin-bottom:40px}\n.pth-feat-box{border:1px solid #e2e8f0;background:#fff;padding:24px;border-radius:12px;box-shadow:0 4px 6px -1px rgba(0,0,0,0.02);transition:all .3s ease}\n.pth-feat-box:hover{border-color:#bfdbfe;transform:translateY(-3px);box-shadow:0 10px 15px -3px rgba(0,0,0,0.05)}\n.pth-feat-title{font-size:1.05rem;font-weight:800;color:#0f172a;margin:0 0 10px;display:flex;align-items:center;gap:10px}\n.pth-feat-text{font-size:.9rem;color:#1e293b;line-height:1.6;margin:0;font-weight:500}\n.pth-steps-wrap{border:1px solid #e2e8f0;background:#fff;padding:40px 30px;border-radius:16px;text-align:center;box-shadow:0 4px 6px -1px rgba(0,0,0,0.02);margin-bottom:40px;width:100%;box-sizing:border-box}\n.pth-steps-title{font-size:1.2rem;font-weight:800;color:#0f172a;text-transform:uppercase;margin:0 0 35px;letter-spacing:1px}\n.pth-steps-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:30px}\n.pth-step-item{display:flex;flex-direction:column;align-items:center}\n.pth-step-num{width:45px;height:45px;background:#2563eb;color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:1.2rem;margin-bottom:15px;box-shadow:0 4px 10px rgba(37,99,235,.3)}\n.pth-step-name{font-weight:800;color:#0f172a;margin:0 0 8px;font-size:1rem}\n.pth-step-desc{font-size:.9rem;color:#1e293b;line-height:1.5;margin:0;font-weight:500}\n<\/style>\n<div class=\"pth-container\">\n  <div class=\"pth-feature-wrap\">\n    <div class=\"pth-feat-box\">\n      <p class=\"pth-feat-title\"><span aria-hidden=\"true\">\ud83d\udfe2<\/span> Convert Between Six Formats<\/p>\n      <p class=\"pth-feat-text\">Move data between JSON, CSV, XML, YAML, TSV and SQL without hunting for a separate site per format. The Convert tab handles all nine directions.<\/p>\n    <\/div>\n    <div class=\"pth-feat-box\">\n      <p class=\"pth-feat-title\"><span aria-hidden=\"true\">\ud83d\udd35<\/span> Query JSON With JSONPath<\/p>\n      <p class=\"pth-feat-text\">The Query tab runs live JSONPath expressions like <code>$.store.book[*].author<\/code> and shows matching results instantly, alongside an interactive tree you can click through.<\/p>\n    <\/div>\n    <div class=\"pth-feat-box\">\n      <p class=\"pth-feat-title\"><span aria-hidden=\"true\">\ud83d\udfe3<\/span> Nothing Leaves Your Browser<\/p>\n      <p class=\"pth-feat-text\">Every conversion and query runs on your own machine. No upload, no login, no watermark \u2014 useful when the JSON holds API keys or customer records.<\/p>\n    <\/div>\n  <\/div>\n  <div class=\"pth-steps-wrap\">\n    <p class=\"pth-steps-title\">How to Use JSON Studio Pro<\/p>\n    <div class=\"pth-steps-grid\">\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">1<\/div>\n        <p class=\"pth-step-name\">Pick a Tab<\/p>\n        <p class=\"pth-step-desc\">Convert &amp; Format for reshaping data, Query &amp; Explore for reading it.<\/p>\n      <\/div>\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">2<\/div>\n        <p class=\"pth-step-name\">Paste Your Data<\/p>\n        <p class=\"pth-step-desc\">Drop in JSON, CSV, XML or YAML. Nothing is uploaded anywhere.<\/p>\n      <\/div>\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">3<\/div>\n        <p class=\"pth-step-name\">Convert or Query<\/p>\n        <p class=\"pth-step-desc\">Choose a conversion and hit Convert, or type a JSONPath expression.<\/p>\n      <\/div>\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">4<\/div>\n        <p class=\"pth-step-name\">Copy or Download<\/p>\n        <p class=\"pth-step-desc\">Grab the result as a file with the right extension, or copy it straight out.<\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n\n<div id=\"start-seo-article\"><\/div>\n\n\n<p class=\"wp-block-paragraph\">Last updated: July 2026<\/p>\n\n\n\n<h2 id=\"\ud83d\udd34-reshaping-data-and-reading-data-are-two-different-jobs\" class=\"wp-block-heading\">\ud83d\udd34 <strong>Reshaping Data and Reading Data Are Two Different Jobs<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Working with JSON usually splits into two tasks. Sometimes you need to change its shape \u2014 turn a spreadsheet export into JSON, or hand a JSON array to a database as SQL inserts. Other times the JSON is fine as-is and you just need to pull one thing out of a deeply nested blob. This tool keeps those on separate tabs so the interface for each stays focused: Convert &amp; Format for reshaping, Query &amp; Explore for reading.<\/p>\n\n\n<figure class=\"pth-article-figure pth-img-left\" style=\"float:left; width:700px; max-width:100%; margin:4px 28px 16px 0; clear:left;\"><img decoding=\"async\" src=\"https:\/\/schoolict.net\/tools\/wp-content\/uploads\/2026\/07\/json-studio-two-tabs-800x447.jpeg\" alt=\"json-studio-two-tabs\" width=\"700\" height=\"394\" loading=\"lazy\" data-no-lazy=\"1\" class=\"pth-article-img\" style=\"width:100%;height:auto;display:block;border-radius:10px;border:1px solid #e2e8f0;\"><\/figure>\n\n\n\n<h2 id=\"\ud83d\udfe1-what-the-convert-tab-is-actually-for\" class=\"wp-block-heading\">\ud83d\udfe1 <strong>What the Convert Tab Is Actually For<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The most common real use is bridging tools that don&#8217;t speak the same format. A designer sends you a CSV of product data; your app wants JSON. A legacy system exports XML; your new one reads YAML config. You have a JSON array from an API and need to seed a test database, so you convert it to SQL <code>INSERT<\/code> statements. Each of these is a one-paste job here instead of a scripting task.<\/p>\n\n\n\n<h3 id=\"\ud83d\udfe2-a-real-example\" class=\"wp-block-heading\">\ud83d\udfe2 <strong>A Real Example<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Say you export 200 rows of contacts from a spreadsheet as CSV. Paste it in, choose CSV \u2192 JSON, and you get a clean array of objects with the header row as keys. Switch the conversion to JSON \u2192 SQL, type your table name, and the same data comes back as ready-to-run <code>INSERT INTO contacts (...)<\/code> lines \u2014 with single quotes inside names like O&#8217;Brien correctly escaped so the SQL doesn&#8217;t break. For array-based conversions, remember the input needs to be a JSON array of objects, not a single object.<\/p>\n\n\n\n<h2 id=\"\ud83d\udd34-when-youd-reach-for-the-query-tab\" class=\"wp-block-heading\">\ud83d\udd34 <strong>When You&#8217;d Reach for the Query Tab<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">JSONPath is worth learning if you regularly dig through API responses. Instead of scrolling a huge blob to find every author in a nested book list, you write <code>$.store.book[*].author<\/code> and get them all at once. The interactive tree next to it is for the opposite situation \u2014 when you don&#8217;t yet know the structure and need to click through it to understand what&#8217;s there. If you also build and debug patterns a lot, our <a href=\"\/advanced-text-regex-tester-debugger\/\">Regex Tester &amp; Debugger<\/a> pairs well with this for text extraction.<\/p>\n\n\n\n<h2 id=\"\ud83d\udfe1-common-mistakes-and-limits\" class=\"wp-block-heading\">\ud83d\udfe1 <strong>Common Mistakes and Limits<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The single most common error is feeding an array converter a plain object \u2014 CSV, TSV and SQL conversions all expect a top-level JSON array. XML conversion is faithful but verbose: deeply nested attributes come through as <code>@<\/code>-prefixed keys, which is correct but can surprise you. And very large files run entirely in your browser&#8217;s memory, so a multi-hundred-megabyte JSON can be slow on an older machine \u2014 that&#8217;s the trade-off for never uploading your data. If your next step is turning a CSV directly into database queries, the dedicated <a href=\"\/csv-to-sql-query-converter\/\">CSV to SQL Converter<\/a> skips the JSON middle step. For a wider set of browser-based utilities, see our roundup of <a href=\"\/top-10-client-side-offline-web-developer-tools\/\">offline developer tools<\/a>.<\/p>\n\n\n\n<style>\n.pth-faq-section{margin:50px auto 40px;font-family:inherit;max-width:1480px;padding:0 20px;box-sizing:border-box}\n.pth-faq-header{font-size:1.8rem;font-weight:800;color:#0f172a;margin-bottom:25px;border-bottom:2px solid #e2e8f0;padding-bottom:10px;display:flex;align-items:center;gap:10px}\n.pth-faq-grid{display:grid;grid-template-columns:1fr;gap:20px}\n@media(min-width:768px){.pth-faq-grid{grid-template-columns:repeat(2,1fr)}}\n@media(min-width:1024px){.pth-faq-grid{grid-template-columns:repeat(3,1fr)}}\n.pth-faq-card{background:#f8fafc;padding:24px;border-radius:12px;border:1px solid #e2e8f0;transition:transform .2s ease;break-inside:avoid}\n.pth-faq-card:hover{transform:translateY(-3px);box-shadow:0 4px 12px rgba(0,0,0,.05)}\n.pth-faq-q{color:#0f172a;font-size:1rem;font-weight:700;margin:0 0 12px;line-height:1.4}\n.pth-faq-a{margin:0;font-size:.95rem;color:#1e293b;line-height:1.6;font-weight:500}\n<\/style>\n<div class=\"pth-faq-section\">\n  <div class=\"pth-faq-header\">\u2753 Frequently Asked Questions<\/div>\n  <div class=\"pth-faq-grid\">\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Is my data uploaded to a server?<\/p>\n      <p class=\"pth-faq-a\">No. Every conversion and JSONPath query runs in your browser with JavaScript. Your data never leaves your device.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Why does CSV or SQL conversion fail on my JSON?<\/p>\n      <p class=\"pth-faq-a\">Those conversions need a JSON array of objects at the top level. A single object or a bare value won&#8217;t map to rows.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">What is JSONPath used for?<\/p>\n      <p class=\"pth-faq-a\">It&#8217;s a query language for JSON \u2014 like SQL for a database. You write an expression such as $.items[*].id to pull every matching value at once.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Can it convert XML and YAML too?<\/p>\n      <p class=\"pth-faq-a\">Yes. The Convert tab handles XML \u2194 JSON and YAML \u2194 JSON, plus TSV and SQL output, alongside CSV.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Does it escape quotes in SQL output?<\/p>\n      <p class=\"pth-faq-a\">Yes. Single quotes inside string values are doubled automatically, so names like O&#8217;Brien produce valid INSERT statements.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Is there a file size limit?<\/p>\n      <p class=\"pth-faq-a\">No hard limit, but everything runs in browser memory. Very large files may be slow on older machines since nothing is offloaded to a server.<\/p>\n    <\/div>\n  <\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Free JSONPath Evaluator &#038; Extractor Pro Use our free JSONPath evaluator to instantly query, extract, and test complex JSON data offline. Features live evaluation, syntax checking, and CSV export. \ud83d\udfe2 Convert Between Six Formats Move data between JSON, CSV, XML, YAML, TSV and SQL without hunting for a separate site per format. The Convert tab &#8230; <a title=\"Free JSONPath Evaluator &amp; Extractor Pro\" class=\"read-more\" href=\"https:\/\/schoolict.net\/tools\/free-jsonpath-evaluator-extractor\/\" aria-label=\"Read more about Free JSONPath Evaluator &amp; Extractor Pro\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":2440,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2431","page","type-page","status-publish","has-post-thumbnail"],"_links":{"self":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/2431","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/comments?post=2431"}],"version-history":[{"count":0,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/2431\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media\/2440"}],"wp:attachment":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media?parent=2431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}