{"id":2196,"date":"2026-08-15T14:03:05","date_gmt":"2026-08-15T14:03:05","guid":{"rendered":"https:\/\/proptrustverified.com\/es\/?page_id=2196"},"modified":"2026-08-15T17:37:15","modified_gmt":"2026-08-15T17:37:15","slug":"sandbox","status":"publish","type":"page","link":"https:\/\/proptrustverified.com\/es\/sandbox\/","title":{"rendered":"PTVS SandBox"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>PTVS Sandbox \u2014 Try Prop Trust Verified Standard in 5 Minutes<\/title>\n<meta name=\"description\" content=\"Interactive sandbox for the Prop Trust Verified Standard (PTVS v1.0). Create a mock asset, generate forensic evidence, compute SHA-256 hash, and simulate on-chain Verifiable Claim injection. No backend required.\">\n<meta name=\"author\" content=\"Forensics Oracle Initiative\">\n<meta property=\"og:title\" content=\"PTVS Sandbox \u2014 Interactive Playground\">\n<meta property=\"og:description\" content=\"Try PTVS v1.0 in your browser. Create mock assets, generate forensic evidence, compute hashes, and simulate on-chain claims.\">\n<meta property=\"og:type\" content=\"website\">\n<meta property=\"og:site_name\" content=\"Prop Trust Verified\">\n<link rel=\"canonical\" href=\"https:\/\/proptrustverified.com\/sandbox\/\">\n<link rel=\"icon\" type=\"image\/png\" href=\"https:\/\/forensics-oracle.org\/wp-content\/uploads\/2026\/08\/cropped-cropped_circle_image.png\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Cinzel:wght@400;600;700;800;900&#038;family=Inter:wght@300;400;500;600;700&#038;family=Cormorant+Garamond:ital,wght@0,400;0,600;1,400;1,600&#038;family=JetBrains+Mono:wght@400;500&#038;display=swap\" rel=\"stylesheet\">\n\n<style>\n:root {\n--navy: #0B132B;\n--navy-light: #1C2541;\n--navy-deep: #070E1F;\n--gold: #D4AF37;\n--gold-dark: #AA8C2C;\n--gold-light: #F4E5C2;\n--cream: #FAF7F0;\n--text: #1A202C;\n--muted: #4A5568;\n--border: #E2E8F0;\n--bg: #F8FAFC;\n--green: #2F855A;\n--red: #C53030;\n--amber: #B7791F;\n--blue: #2B6CB0;\n}\n* { margin: 0; padding: 0; box-sizing: border-box; }\nbody {\nfont-family: 'Inter', sans-serif;\nbackground: var(--cream);\ncolor: var(--text);\nline-height: 1.65;\n}\n\n\/* HEADER NAV *\/\n.site-header {\nbackground: var(--navy);\nborder-bottom: 3px solid var(--gold);\npadding: 16px 5%;\nposition: sticky;\ntop: 0;\nz-index: 100;\n}\n.header-container {\nmax-width: 1400px;\nmargin: 0 auto;\ndisplay: flex;\njustify-content: space-between;\nalign-items: center;\nflex-wrap: wrap;\ngap: 16px;\n}\n.brand-link {\ndisplay: flex;\nalign-items: center;\ngap: 12px;\ntext-decoration: none;\n}\n.brand-seal {\nwidth: 46px; height: 46px;\nborder-radius: 50%;\nborder: 2px solid var(--gold);\noverflow: hidden;\nbackground: var(--navy-deep);\nflex-shrink: 0;\n}\n.brand-seal img { width: 100%; height: 100%; object-fit: cover; }\n.brand-text {\nfont-family: 'Cinzel', serif;\nfont-size: 10pt;\nfont-weight: 700;\ncolor: var(--gold);\nletter-spacing: 1px;\nline-height: 1.2;\n}\n.brand-sub {\ndisplay: block;\nfont-size: 6.5pt;\ncolor: #A0AEC0;\nletter-spacing: 2px;\ntext-transform: uppercase;\nmargin-top: 2px;\n}\n.nav-links {\ndisplay: flex;\ngap: 20px;\nlist-style: none;\nflex-wrap: wrap;\n}\n.nav-links a {\ncolor: #E2E8F0;\ntext-decoration: none;\nfont-size: 8pt;\nletter-spacing: 1.5px;\ntext-transform: uppercase;\nfont-weight: 500;\ntransition: color 0.3s;\npadding: 4px 0;\nborder-bottom: 1px solid transparent;\n}\n.nav-links a:hover,\n.nav-links a.active {\ncolor: var(--gold);\nborder-bottom-color: var(--gold);\n}\n\n\/* HERO *\/\n.page-hero {\nbackground: linear-gradient(135deg, var(--navy) 0%, var(--navy-light) 60%, var(--navy-deep) 100%);\ncolor: white;\npadding: 70px 5% 60px;\nposition: relative;\noverflow: hidden;\nborder-bottom: 4px solid var(--gold);\n}\n.page-hero::before {\ncontent: '';\nposition: absolute;\ntop: -50%; right: -10%;\nwidth: 700px; height: 700px;\nbackground: radial-gradient(circle, rgba(212,175,55,0.08) 0%, transparent 70%);\n}\n.hero-container {\nmax-width: 1200px;\nmargin: 0 auto;\nposition: relative;\nz-index: 1;\n}\n.hero-eyebrow {\ndisplay: inline-block;\nfont-size: 7pt;\nletter-spacing: 4px;\ntext-transform: uppercase;\ncolor: var(--gold);\nfont-weight: 700;\nmargin-bottom: 18px;\npadding: 5px 14px;\nborder: 1px solid var(--gold);\nbackground: rgba(212,175,55,0.08);\n}\n.hero-title {\nfont-family: 'Cinzel', serif;\nfont-size: clamp(2rem, 4.5vw, 3.2rem);\nfont-weight: 800;\ncolor: var(--gold);\nline-height: 1.1;\nmargin-bottom: 14px;\nletter-spacing: 0.5px;\n}\n.hero-subtitle {\nfont-family: 'Cormorant Garamond', serif;\nfont-size: 1.25rem;\ncolor: var(--gold-light);\nfont-style: italic;\nmax-width: 680px;\nline-height: 1.5;\nletter-spacing: 0.3px;\nmargin-bottom: 24px;\n}\n.hero-chips {\ndisplay: flex;\ngap: 12px;\nflex-wrap: wrap;\nmargin-bottom: 20px;\n}\n.hero-chip {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 7.5pt;\nletter-spacing: 1.5px;\ntext-transform: uppercase;\ncolor: #CBD5E0;\npadding: 6px 14px;\nbackground: rgba(255,255,255,0.05);\nborder: 1px solid rgba(212,175,55,0.3);\n}\n.hero-chip strong { color: var(--gold); font-weight: 600; }\n\n\/* MAIN *\/\nmain {\nmax-width: 1200px;\nmargin: 0 auto;\npadding: 60px 5% 100px;\n}\n\n\/* SECTIONS *\/\n.section {\nmargin-bottom: 55px;\n}\n.section-num {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 8pt;\nletter-spacing: 3px;\ntext-transform: uppercase;\ncolor: var(--gold-dark);\nfont-weight: 700;\nmargin-bottom: 8px;\ndisplay: block;\n}\n.section h2 {\nfont-family: 'Cinzel', serif;\nfont-size: 1.75rem;\nfont-weight: 700;\ncolor: var(--navy);\nline-height: 1.25;\nmargin-bottom: 20px;\npadding-bottom: 12px;\nborder-bottom: 3px solid var(--gold);\nletter-spacing: 0.3px;\n}\n.section h3 {\nfont-family: 'Cinzel', serif;\nfont-size: 1.15rem;\nfont-weight: 700;\ncolor: var(--navy);\nmargin: 26px 0 12px 0;\nletter-spacing: 0.3px;\nborder-left: 3px solid var(--gold);\npadding-left: 14px;\n}\n.section p {\nfont-size: 1rem;\nline-height: 1.75;\nmargin-bottom: 14px;\ntext-align: justify;\ncolor: #2D3748;\n}\n.section p strong { color: var(--navy); font-weight: 600; }\n\n\/* LEAD *\/\n.lead {\nfont-family: 'Cormorant Garamond', serif;\nfont-size: 1.25rem;\nline-height: 1.65;\ncolor: var(--navy);\nmargin-bottom: 40px;\npadding: 26px 30px;\nborder-top: 2px solid var(--gold);\nborder-bottom: 2px solid var(--gold);\nbackground: linear-gradient(180deg, rgba(212,175,55,0.04) 0%, transparent 100%);\nfont-style: italic;\n}\n\n\/* SANDBOX CONTAINER *\/\n.sandbox-container {\nbackground: white;\nborder: 2px solid var(--gold);\nborder-top: 5px solid var(--gold);\npadding: 0;\nmargin: 30px 0;\nbox-shadow: 0 10px 40px rgba(11,19,43,0.1);\n}\n.sandbox-header {\nbackground: var(--navy);\ncolor: white;\npadding: 24px 32px;\nborder-bottom: 2px solid var(--gold);\n}\n.sandbox-header h3 {\nfont-family: 'Cinzel', serif;\ncolor: var(--gold);\nfont-size: 1.3rem;\nmargin-bottom: 6px;\nborder: none;\npadding: 0;\nletter-spacing: 0.5px;\n}\n.sandbox-header p {\ncolor: #CBD5E0;\nfont-size: 0.9rem;\nmargin: 0;\n}\n.sandbox-body {\npadding: 32px;\n}\n\n\/* STEPS INDICATOR *\/\n.steps-indicator {\ndisplay: flex;\njustify-content: space-between;\nmargin-bottom: 40px;\nposition: relative;\npadding: 0 20px;\n}\n.steps-indicator::before {\ncontent: '';\nposition: absolute;\ntop: 20px;\nleft: 40px;\nright: 40px;\nheight: 2px;\nbackground: var(--border);\nz-index: 0;\n}\n.step-dot {\nposition: relative;\nz-index: 1;\ndisplay: flex;\nflex-direction: column;\nalign-items: center;\ngap: 8px;\nflex: 1;\n}\n.step-circle {\nwidth: 42px; height: 42px;\nborder-radius: 50%;\nbackground: white;\nborder: 3px solid var(--border);\ndisplay: flex;\nalign-items: center;\njustify-content: center;\nfont-family: 'Cinzel', serif;\nfont-weight: 700;\ncolor: var(--muted);\nfont-size: 1rem;\ntransition: all 0.3s;\n}\n.step-dot.active .step-circle {\nbackground: var(--gold);\nborder-color: var(--gold);\ncolor: var(--navy);\n}\n.step-dot.completed .step-circle {\nbackground: var(--green);\nborder-color: var(--green);\ncolor: white;\n}\n.step-label {\nfont-size: 0.72rem;\nletter-spacing: 1px;\ntext-transform: uppercase;\ncolor: var(--muted);\nfont-weight: 600;\ntext-align: center;\n}\n.step-dot.active .step-label { color: var(--gold-dark); }\n.step-dot.completed .step-label { color: var(--green); }\n\n\/* FORM SECTIONS *\/\n.form-section {\nmargin-bottom: 32px;\npadding-bottom: 32px;\nborder-bottom: 1px solid var(--border);\n}\n.form-section:last-child { border-bottom: none; }\n.form-section h4 {\nfont-family: 'Cinzel', serif;\nfont-size: 1.1rem;\ncolor: var(--navy);\nmargin-bottom: 16px;\nletter-spacing: 0.3px;\n}\n.form-grid {\ndisplay: grid;\ngrid-template-columns: 1fr 1fr;\ngap: 16px;\nmargin-bottom: 16px;\n}\n.form-group {\ndisplay: flex;\nflex-direction: column;\ngap: 6px;\n}\n.form-group label {\nfont-size: 0.78rem;\nletter-spacing: 1px;\ntext-transform: uppercase;\ncolor: var(--muted);\nfont-weight: 600;\n}\n.form-group input,\n.form-group select,\n.form-group textarea {\npadding: 10px 14px;\nborder: 1px solid var(--border);\nfont-family: 'Inter', sans-serif;\nfont-size: 0.9rem;\ncolor: var(--text);\nbackground: white;\ntransition: border-color 0.2s;\n}\n.form-group input:focus,\n.form-group select:focus,\n.form-group textarea:focus {\noutline: none;\nborder-color: var(--gold);\n}\n.form-group textarea {\nmin-height: 80px;\nresize: vertical;\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.82rem;\n}\n\n\/* SCORE DISPLAY *\/\n.score-display {\nbackground: linear-gradient(135deg, var(--navy) 0%, var(--navy-light) 100%);\ncolor: white;\npadding: 28px;\nmargin: 24px 0;\nborder-left: 5px solid var(--gold);\ntext-align: center;\n}\n.score-label {\nfont-size: 0.78rem;\nletter-spacing: 2px;\ntext-transform: uppercase;\ncolor: var(--gold);\nfont-weight: 700;\nmargin-bottom: 8px;\n}\n.score-value {\nfont-family: 'Cinzel', serif;\nfont-size: 4rem;\nfont-weight: 800;\ncolor: var(--gold-light);\nline-height: 1;\nmargin-bottom: 8px;\n}\n.score-status {\nfont-family: 'Cinzel', serif;\nfont-size: 1.1rem;\nletter-spacing: 2px;\ntext-transform: uppercase;\nfont-weight: 700;\npadding: 6px 16px;\ndisplay: inline-block;\nborder-radius: 2px;\n}\n.score-status.verified {\nbackground: rgba(47,133,90,0.2);\ncolor: #68D391;\nborder: 1px solid var(--green);\n}\n.score-status.conditional {\nbackground: rgba(183,121,31,0.2);\ncolor: var(--gold-light);\nborder: 1px solid var(--amber);\n}\n.score-status.revoked {\nbackground: rgba(197,48,48,0.2);\ncolor: #FC8181;\nborder: 1px solid var(--red);\n}\n.score-breakdown {\nmargin-top: 20px;\ndisplay: grid;\ngrid-template-columns: repeat(5, 1fr);\ngap: 10px;\n}\n.breakdown-item {\ntext-align: center;\n}\n.breakdown-label {\nfont-size: 0.68rem;\ncolor: #CBD5E0;\nletter-spacing: 1px;\ntext-transform: uppercase;\nmargin-bottom: 4px;\n}\n.breakdown-value {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 1.1rem;\ncolor: white;\nfont-weight: 700;\n}\n.breakdown-weight {\nfont-size: 0.65rem;\ncolor: var(--gold-dark);\nmargin-top: 2px;\n}\n\n\/* CODE OUTPUT *\/\n.code-output {\nbackground: var(--navy-deep);\ncolor: #E2E8F0;\npadding: 20px 24px;\nmargin: 16px 0;\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.82rem;\nline-height: 1.6;\noverflow-x: auto;\nborder-left: 4px solid var(--gold);\nwhite-space: pre;\nmax-height: 400px;\n}\n.code-output .kw { color: var(--gold); }\n.code-output .str { color: #68D391; }\n.code-output .num { color: #F6AD55; }\n.code-output .cm { color: #718096; }\n\n\/* HASH DISPLAY *\/\n.hash-display {\nbackground: var(--bg);\nborder: 2px solid var(--gold);\npadding: 20px;\nmargin: 16px 0;\ntext-align: center;\n}\n.hash-label {\nfont-size: 0.75rem;\nletter-spacing: 2px;\ntext-transform: uppercase;\ncolor: var(--gold-dark);\nfont-weight: 700;\nmargin-bottom: 10px;\n}\n.hash-value {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.85rem;\ncolor: var(--navy);\nword-break: break-all;\nline-height: 1.5;\nfont-weight: 600;\n}\n\n\/* CLAIM CARD *\/\n.claim-card {\nbackground: linear-gradient(135deg, var(--navy) 0%, var(--navy-deep) 100%);\ncolor: white;\npadding: 28px;\nmargin: 24px 0;\nborder-top: 4px solid var(--gold);\nborder-bottom: 4px solid var(--gold);\n}\n.claim-header {\ndisplay: flex;\njustify-content: space-between;\nalign-items: center;\nmargin-bottom: 20px;\npadding-bottom: 16px;\nborder-bottom: 1px solid rgba(212,175,55,0.3);\n}\n.claim-title {\nfont-family: 'Cinzel', serif;\ncolor: var(--gold);\nfont-size: 1.2rem;\nletter-spacing: 0.5px;\n}\n.claim-status {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.78rem;\npadding: 4px 12px;\nbackground: rgba(47,133,90,0.2);\ncolor: #68D391;\nborder: 1px solid var(--green);\nletter-spacing: 1px;\ntext-transform: uppercase;\nfont-weight: 700;\n}\n.claim-grid {\ndisplay: grid;\ngrid-template-columns: 1fr 1fr;\ngap: 16px;\n}\n.claim-field {\npadding: 10px 0;\nborder-bottom: 1px dashed rgba(255,255,255,0.1);\n}\n.claim-field:last-child { border-bottom: none; }\n.claim-field-label {\nfont-size: 0.68rem;\nletter-spacing: 1.5px;\ntext-transform: uppercase;\ncolor: var(--gold-dark);\nmargin-bottom: 4px;\nfont-weight: 700;\n}\n.claim-field-value {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.82rem;\ncolor: #E2E8F0;\nword-break: break-all;\nline-height: 1.4;\n}\n\n\/* BUTTONS *\/\n.btn {\ndisplay: inline-block;\npadding: 14px 32px;\nfont-family: 'Cinzel', serif;\nfont-weight: 700;\nfont-size: 9pt;\nletter-spacing: 2px;\ntext-transform: uppercase;\ntext-decoration: none;\ntransition: all 0.3s;\ncursor: pointer;\nborder: 2px solid;\n}\n.btn-primary {\nbackground: var(--gold);\ncolor: var(--navy);\nborder-color: var(--gold);\n}\n.btn-primary:hover {\nbackground: var(--gold-light);\ntransform: translateY(-2px);\nbox-shadow: 0 8px 24px rgba(212,175,55,0.3);\n}\n.btn-secondary {\nbackground: white;\ncolor: var(--navy);\nborder-color: var(--navy);\n}\n.btn-secondary:hover {\nbackground: var(--navy);\ncolor: var(--gold);\n}\n.btn-danger {\nbackground: var(--red);\ncolor: white;\nborder-color: var(--red);\n}\n.btn-danger:hover {\nbackground: #9B2C2C;\n}\n.button-group {\ndisplay: flex;\ngap: 12px;\nmargin-top: 24px;\nflex-wrap: wrap;\n}\n\n\/* CODE EXAMPLES *\/\n.code-examples {\nmargin: 30px 0;\n}\n.code-tabs {\ndisplay: flex;\ngap: 4px;\nmargin-bottom: 0;\nborder-bottom: 2px solid var(--gold);\n}\n.code-tab {\npadding: 10px 20px;\nbackground: var(--bg);\nborder: 1px solid var(--border);\nborder-bottom: none;\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.82rem;\ncolor: var(--muted);\ncursor: pointer;\ntransition: all 0.2s;\n}\n.code-tab.active {\nbackground: var(--navy);\ncolor: var(--gold);\nborder-color: var(--gold);\n}\n.code-tab:hover:not(.active) {\nbackground: white;\n}\n.code-panel {\ndisplay: none;\nbackground: var(--navy-deep);\npadding: 24px;\nborder: 1px solid var(--border);\nborder-top: none;\n}\n.code-panel.active { display: block; }\n.code-panel pre {\nmargin: 0;\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.82rem;\nline-height: 1.6;\ncolor: #E2E8F0;\nwhite-space: pre;\noverflow-x: auto;\n}\n\n\/* NEXT STEPS *\/\n.next-steps {\nbackground: var(--bg);\nborder: 2px solid var(--gold);\npadding: 32px;\nmargin: 40px 0;\n}\n.next-steps h3 {\nfont-family: 'Cinzel', serif;\ncolor: var(--navy);\nfont-size: 1.3rem;\nmargin-bottom: 16px;\nborder: none;\npadding: 0;\n}\n.next-steps-grid {\ndisplay: grid;\ngrid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\ngap: 16px;\nmargin-top: 20px;\n}\n.next-step-card {\nbackground: white;\nborder: 1px solid var(--border);\nborder-top: 3px solid var(--gold);\npadding: 20px;\n}\n.next-step-card h4 {\nfont-family: 'Cinzel', serif;\nfont-size: 1rem;\ncolor: var(--navy);\nmargin-bottom: 8px;\n}\n.next-step-card p {\nfont-size: 0.88rem;\ncolor: var(--muted);\nline-height: 1.5;\nmargin-bottom: 12px;\n}\n.next-step-card a {\ncolor: var(--gold-dark);\nfont-weight: 600;\ntext-decoration: none;\nfont-size: 0.85rem;\n}\n.next-step-card a:hover { text-decoration: underline; }\n\n\/* ECOSYSTEM FOOTER *\/\n.ecosystem-footer {\nbackground: var(--navy-deep);\ncolor: #A0AEC0;\npadding: 50px 5% 30px;\nborder-top: 3px solid var(--gold);\n}\n.ecosystem-container { max-width: 1200px; margin: 0 auto; }\n.ecosystem-label { text-align: center; margin-bottom: 30px; }\n.ecosystem-motto {\ndisplay: block;\nfont-family: 'Cinzel', serif;\ncolor: var(--gold);\nletter-spacing: 4px;\nfont-style: italic;\nfont-size: 0.9rem;\nmargin-bottom: 10px;\n}\n.ecosystem-title {\ndisplay: block;\nfont-family: 'Cinzel', serif;\ncolor: white;\nfont-size: 1.2rem;\nletter-spacing: 2px;\n}\n.ecosystem-grid {\ndisplay: grid;\ngrid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\ngap: 16px;\nmargin-bottom: 30px;\n}\n.eco-link {\ndisplay: block;\nbackground: rgba(255,255,255,0.03);\nborder: 1px solid rgba(212,175,55,0.2);\nborder-left: 3px solid var(--gold);\npadding: 18px 20px;\ntext-decoration: none;\ncolor: inherit;\ntransition: all 0.3s;\n}\n.eco-link:hover {\nbackground: rgba(212,175,55,0.08);\ntransform: translateX(4px);\n}\n.eco-role {\ndisplay: block;\nfont-size: 0.62rem;\nletter-spacing: 2px;\ntext-transform: uppercase;\ncolor: var(--gold-dark);\nmargin-bottom: 4px;\nfont-weight: 700;\n}\n.eco-link strong {\ndisplay: block;\ncolor: white;\nfont-family: 'Cinzel', serif;\nfont-size: 0.9rem;\nmargin-bottom: 4px;\n}\n.eco-desc {\ndisplay: block;\nfont-size: 0.75rem;\ncolor: #CBD5E0;\nline-height: 1.4;\n}\n.ecosystem-footnote {\ntext-align: center;\nfont-size: 0.72rem;\ncolor: #718096;\nline-height: 1.6;\npadding-top: 20px;\nborder-top: 1px solid rgba(212,175,55,0.15);\n}\n.ecosystem-footnote a { color: var(--gold); text-decoration: none; }\n\n\/* RESPONSIVE *\/\n@media (max-width: 768px) {\n.form-grid { grid-template-columns: 1fr; }\n.score-breakdown { grid-template-columns: repeat(2, 1fr); }\n.claim-grid { grid-template-columns: 1fr; }\n.steps-indicator { flex-wrap: wrap; }\n.step-dot { flex: 0 0 calc(33% - 10px); margin-bottom: 10px; }\n.sandbox-body { padding: 20px; }\nmain { padding: 40px 6%; }\n.section h2 { font-size: 1.4rem; }\n}\n<\/style>\n<\/head>\n<body>\n\n<!-- HEADER NAV -->\n<header class=\"site-header\">\n<div class=\"header-container\">\n<a href=\"\/\" class=\"brand-link\">\n<div class=\"brand-seal\"><img decoding=\"async\" src=\"https:\/\/forensics-oracle.org\/wp-content\/uploads\/2026\/08\/cropped-cropped_circle_image.png\" alt=\"Sello FOI\"><\/div>\n<div class=\"brand-text\">Prop Trust Verified<span class=\"brand-sub\">Certification \u00b7 PTCE Network<\/span><\/div>\n<\/a>\n<nav>\n<ul class=\"nav-links\">\n<li><a href=\"\/\">Home<\/a><\/li>\n<li><a href=\"\/standard\/\">PTVS Standard<\/a><\/li>\n<li><a href=\"\/ptce-registry\/\">PTCE Registry<\/a><\/li>\n<li><a href=\"\/sandbox\/\" class=\"active\">Sandbox<\/a><\/li>\n<li><a href=\"\/vendor-register\/\">Register<\/a><\/li>\n<\/ul>\n<\/nav>\n<\/div>\n<\/header>\n\n<!-- HERO -->\n<section class=\"page-hero\">\n<div class=\"hero-container\">\n<span class=\"hero-eyebrow\">Interactive Playground \u00b7 No Backend Required<\/span>\n<h1 class=\"hero-title\">PTVS Sandbox<\/h1>\n<p class=\"hero-subtitle\">\nExperience the Prop Trust Verified Standard in your browser. Create a mock asset, generate forensic evidence, compute cryptographic hashes, and simulate on-chain Verifiable Claim injection \u2014 all in 5 minutes.\n<\/p>\n<div class=\"hero-chips\">\n<span class=\"hero-chip\">Standard \u00b7 <strong>PTVS v1.0<\/strong><\/span>\n<span class=\"hero-chip\">Environment \u00b7 <strong>Browser-based<\/strong><\/span>\n<span class=\"hero-chip\">Time \u00b7 <strong>~5 minutes<\/strong><\/span>\n<\/div>\n<\/div>\n<\/section>\n\n<!-- MAIN -->\n<main>\n\n<!-- LEAD -->\n<p class=\"lead\">\nThis sandbox demonstrates the complete PTVS v1.0 verification flow: from physical asset inspection to on-chain Verifiable Claim injection. All computations happen in your browser using the Web Crypto API. No data is sent to any server. When you&#8217;re ready to integrate PTVS into production, visit our <a href=\"\/standard\/\" style=\"color: var(--gold-dark); font-weight: 600;\">documentation<\/a> or contact our technical team.\n<\/p>\n\n<!-- SECTION 1: SANDBOX -->\n<section class=\"section\">\n<span class=\"section-num\">Section I<\/span>\n<h2>Interactive Playground<\/h2>\n\n<div class=\"sandbox-container\">\n<div class=\"sandbox-header\">\n<h3>PTVS v1.0 Verification Flow Simulator<\/h3>\n<p>Complete the 6 steps below to generate a mock Verifiable Claim<\/p>\n<\/div>\n\n<div class=\"sandbox-body\">\n\n<!-- STEPS INDICATOR -->\n<div class=\"steps-indicator\">\n<div class=\"step-dot active\" data-step=\"1\">\n<div class=\"step-circle\">1<\/div>\n<div class=\"step-label\">Asset<\/div>\n<\/div>\n<div class=\"step-dot\" data-step=\"2\">\n<div class=\"step-circle\">2<\/div>\n<div class=\"step-label\">Evidence<\/div>\n<\/div>\n<div class=\"step-dot\" data-step=\"3\">\n<div class=\"step-circle\">3<\/div>\n<div class=\"step-label\">Score<\/div>\n<\/div>\n<div class=\"step-dot\" data-step=\"4\">\n<div class=\"step-circle\">4<\/div>\n<div class=\"step-label\">Hash<\/div>\n<\/div>\n<div class=\"step-dot\" data-step=\"5\">\n<div class=\"step-circle\">5<\/div>\n<div class=\"step-label\">Claim<\/div>\n<\/div>\n<div class=\"step-dot\" data-step=\"6\">\n<div class=\"step-circle\">6<\/div>\n<div class=\"step-label\">Verify<\/div>\n<\/div>\n<\/div>\n\n<!-- STEP 1: ASSET -->\n<div class=\"form-section\" id=\"step1\">\n<h4>Step 1: Define the Asset<\/h4>\n<div class=\"form-grid\">\n<div class=\"form-group\">\n<label>Asset Type<\/label>\n<select id=\"assetType\">\n<option value=\"real_estate\">Real Estate (Building)<\/option>\n<option value=\"naval\">Naval Vessel<\/option>\n<option value=\"infrastructure\">Infrastructure<\/option>\n<option value=\"agricultural\">Agricultural Land<\/option>\n<option value=\"industrial\">Industrial Facility<\/option>\n<\/select>\n<\/div>\n<div class=\"form-group\">\n<label>Asset ID (bytes32)<\/label>\n<input type=\"text\" id=\"assetId\" value=\"0x1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef12345678\" readonly>\n<\/div>\n<div class=\"form-group\">\n<label>Asset Name<\/label>\n<input type=\"text\" id=\"assetName\" value=\"Edificio residencial \u00b7 Calle Mayor 42, Valencia\">\n<\/div>\n<div class=\"form-group\">\n<label>Jurisdiction<\/label>\n<select id=\"jurisdiction\">\n<option value=\"ES-VC\">Spain \u00b7 Comunitat Valenciana<\/option>\n<option value=\"ES-M\">Spain \u00b7 Madrid<\/option>\n<option value=\"ES-CT\">Spain \u00b7 Catalunya<\/option>\n<option value=\"DE-BY\">Germany \u00b7 Bavaria<\/option>\n<option value=\"FR-IDF\">France \u00b7 \u00cele-de-France<\/option>\n<option value=\"IT-LM\">Italy \u00b7 Lombardia<\/option>\n<option value=\"NL-NH\">Netherlands \u00b7 Noord-Holland<\/option>\n<option value=\"CH-ZH\">Switzerland \u00b7 Z\u00fcrich<\/option>\n<\/select>\n<\/div>\n<\/div>\n<div class=\"button-group\">\n<button class=\"btn btn-primary\" onclick=\"nextStep(2)\">Continue to Evidence \u2192<\/button>\n<\/div>\n<\/div>\n\n<!-- STEP 2: EVIDENCE -->\n<div class=\"form-section\" id=\"step2\" style=\"display: none;\">\n<h4>Step 2: Forensic Inspection Findings<\/h4>\n<p style=\"font-size: 0.88rem; color: var(--muted); margin-bottom: 16px;\">\nRate each category from 0-100. These scores will be weighted to calculate the final PTVS Score.\n<\/p>\n\n<div class=\"form-grid\">\n<div class=\"form-group\">\n<label>Structural Score (40% weight)<\/label>\n<input type=\"range\" id=\"structuralScore\" min=\"0\" max=\"100\" value=\"85\" oninput=\"updateScoreDisplay()\">\n<span id=\"structuralValue\" style=\"font-family: 'JetBrains Mono', monospace; color: var(--gold-dark);\">85<\/span>\n<\/div>\n<div class=\"form-group\">\n<label>Legal Score (25% weight)<\/label>\n<input type=\"range\" id=\"legalScore\" min=\"0\" max=\"100\" value=\"92\" oninput=\"updateScoreDisplay()\">\n<span id=\"legalValue\" style=\"font-family: 'JetBrains Mono', monospace; color: var(--gold-dark);\">92<\/span>\n<\/div>\n<div class=\"form-group\">\n<label>Environmental Score (20% weight)<\/label>\n<input type=\"range\" id=\"environmentalScore\" min=\"0\" max=\"100\" value=\"78\" oninput=\"updateScoreDisplay()\">\n<span id=\"environmentalValue\" style=\"font-family: 'JetBrains Mono', monospace; color: var(--gold-dark);\">78<\/span>\n<\/div>\n<div class=\"form-group\">\n<label>Documentation Score (10% weight)<\/label>\n<input type=\"range\" id=\"documentationScore\" min=\"0\" max=\"100\" value=\"95\" oninput=\"updateScoreDisplay()\">\n<span id=\"documentationValue\" style=\"font-family: 'JetBrains Mono', monospace; color: var(--gold-dark);\">95<\/span>\n<\/div>\n<div class=\"form-group\">\n<label>Insurance Score (5% weight)<\/label>\n<input type=\"range\" id=\"insuranceScore\" min=\"0\" max=\"100\" value=\"88\" oninput=\"updateScoreDisplay()\">\n<span id=\"insuranceValue\" style=\"font-family: 'JetBrains Mono', monospace; color: var(--gold-dark);\">88<\/span>\n<\/div>\n<\/div>\n\n<div class=\"form-group\" style=\"margin-top: 16px;\">\n<label>Inspector Notes (optional)<\/label>\n<textarea id=\"inspectorNotes\" placeholder=\"e.g., Minor corrosion detected on balcony railings. Recommend treatment within 6 months.\">Minor corrosion detected on balcony railings. Recommend treatment within 6 months. All structural elements sound. Title clear, no encumbrances.<\/textarea>\n<\/div>\n\n<div class=\"button-group\">\n<button class=\"btn btn-secondary\" onclick=\"prevStep(1)\">\u2190 Back<\/button>\n<button class=\"btn btn-primary\" onclick=\"nextStep(3)\">Calculate PTVS Score \u2192<\/button>\n<\/div>\n<\/div>\n\n<!-- STEP 3: SCORE -->\n<div class=\"form-section\" id=\"step3\" style=\"display: none;\">\n<h4>Step 3: PTVS Score Calculation<\/h4>\n\n<div class=\"score-display\">\n<div class=\"score-label\">PTVS Score<\/div>\n<div class=\"score-value\" id=\"ptvsScoreDisplay\">0<\/div>\n<div class=\"score-status\" id=\"scoreStatus\">CALCULATING<\/div>\n\n<div class=\"score-breakdown\">\n<div class=\"breakdown-item\">\n<div class=\"breakdown-label\">Structural<\/div>\n<div class=\"breakdown-value\" id=\"breakdownStructural\">0<\/div>\n<div class=\"breakdown-weight\">40%<\/div>\n<\/div>\n<div class=\"breakdown-item\">\n<div class=\"breakdown-label\">Legal<\/div>\n<div class=\"breakdown-value\" id=\"breakdownLegal\">0<\/div>\n<div class=\"breakdown-weight\">25%<\/div>\n<\/div>\n<div class=\"breakdown-item\">\n<div class=\"breakdown-label\">Environmental<\/div>\n<div class=\"breakdown-value\" id=\"breakdownEnvironmental\">0<\/div>\n<div class=\"breakdown-weight\">20%<\/div>\n<\/div>\n<div class=\"breakdown-item\">\n<div class=\"breakdown-label\">Documentation<\/div>\n<div class=\"breakdown-value\" id=\"breakdownDocumentation\">0<\/div>\n<div class=\"breakdown-weight\">10%<\/div>\n<\/div>\n<div class=\"breakdown-item\">\n<div class=\"breakdown-label\">Insurance<\/div>\n<div class=\"breakdown-value\" id=\"breakdownInsurance\">0<\/div>\n<div class=\"breakdown-weight\">5%<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"button-group\">\n<button class=\"btn btn-secondary\" onclick=\"prevStep(2)\">\u2190 Back<\/button>\n<button class=\"btn btn-primary\" onclick=\"nextStep(4)\">Generate Canonical JSON \u2192<\/button>\n<\/div>\n<\/div>\n\n<!-- STEP 4: HASH -->\n<div class=\"form-section\" id=\"step4\" style=\"display: none;\">\n<h4>Step 4: Canonical JSON &#038; SHA-256 Hash<\/h4>\n\n<p style=\"font-size: 0.88rem; color: var(--muted); margin-bottom: 16px;\">\nThe inspection findings are serialized into canonical JSON (deterministic format) and hashed using SHA-256. This hash will be anchored on-chain.\n<\/p>\n\n<div class=\"code-output\" id=\"canonicalJsonOutput\"><\/div>\n\n<div class=\"hash-display\">\n<div class=\"hash-label\">SHA-256 Hash (forensicHash)<\/div>\n<div class=\"hash-value\" id=\"hashValue\">Computing&#8230;<\/div>\n<\/div>\n\n<div class=\"button-group\">\n<button class=\"btn btn-secondary\" onclick=\"prevStep(3)\">\u2190 Back<\/button>\n<button class=\"btn btn-primary\" onclick=\"nextStep(5)\">Inject Claim On-Chain \u2192<\/button>\n<\/div>\n<\/div>\n\n<!-- STEP 5: CLAIM -->\n<div class=\"form-section\" id=\"step5\" style=\"display: none;\">\n<h4>Step 5: On-Chain Verifiable Claim<\/h4>\n\n<p style=\"font-size: 0.88rem; color: var(--muted); margin-bottom: 16px;\">\nThe Verifiable Claim is injected into the PTVSClaimInjector smart contract. In production, this would be a real Ethereum transaction. Here we simulate it.\n<\/p>\n\n<div class=\"claim-card\">\n<div class=\"claim-header\">\n<div class=\"claim-title\">Verifiable Claim #<span id=\"claimId\">001<\/span><\/div>\n<div class=\"claim-status\">INJECTED<\/div>\n<\/div>\n<div class=\"claim-grid\">\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">Asset ID<\/div>\n<div class=\"claim-field-value\" id=\"claimAssetId\"><\/div>\n<\/div>\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">PTVS Score<\/div>\n<div class=\"claim-field-value\" id=\"claimScore\"><\/div>\n<\/div>\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">Forensic Hash<\/div>\n<div class=\"claim-field-value\" id=\"claimHash\"><\/div>\n<\/div>\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">Inspection Timestamp<\/div>\n<div class=\"claim-field-value\" id=\"claimTimestamp\"><\/div>\n<\/div>\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">PTCE Address<\/div>\n<div class=\"claim-field-value\">0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb<\/div>\n<\/div>\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">Status<\/div>\n<div class=\"claim-field-value\" id=\"claimStatus\">VERIFIED<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"code-output\" id=\"solidityEventOutput\"><\/div>\n\n<div class=\"button-group\">\n<button class=\"btn btn-secondary\" onclick=\"prevStep(4)\">\u2190 Back<\/button>\n<button class=\"btn btn-primary\" onclick=\"nextStep(6)\">Verify Claim \u2192<\/button>\n<\/div>\n<\/div>\n\n<!-- STEP 6: VERIFY -->\n<div class=\"form-section\" id=\"step6\" style=\"display: none;\">\n<h4>Step 6: Independent Verification<\/h4>\n\n<p style=\"font-size: 0.88rem; color: var(--muted); margin-bottom: 16px;\">\nAny third party can verify this claim by recomputing the SHA-256 hash from the canonical JSON and comparing it with the on-chain forensicHash.\n<\/p>\n\n<div style=\"background: var(--bg); padding: 24px; border: 2px solid var(--green); margin: 20px 0;\">\n<div style=\"display: flex; align-items: center; gap: 12px; margin-bottom: 16px;\">\n<div style=\"width: 40px; height: 40px; background: var(--green); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 1.5rem;\">\u2713<\/div>\n<div>\n<div style=\"font-family: 'Cinzel', serif; font-size: 1.1rem; color: var(--green); font-weight: 700;\">Verification Successful<\/div>\n<div style=\"font-size: 0.88rem; color: var(--muted);\">The on-chain claim matches the original inspection report<\/div>\n<\/div>\n<\/div>\n\n<div style=\"font-family: 'JetBrains Mono', monospace; font-size: 0.82rem; line-height: 1.6;\">\n<div><span style=\"color: var(--muted);\">Recomputed hash:<\/span> <span id=\"verifyHash1\" style=\"color: var(--navy); font-weight: 600;\"><\/span><\/div>\n<div><span style=\"color: var(--muted);\">On-chain hash:<\/span> <span id=\"verifyHash2\" style=\"color: var(--navy); font-weight: 600;\"><\/span><\/div>\n<div style=\"margin-top: 8px; color: var(--green); font-weight: 700;\">\u2713 MATCH<\/div>\n<\/div>\n<\/div>\n\n<div class=\"button-group\">\n<button class=\"btn btn-secondary\" onclick=\"resetSandbox()\">\u21bb Start Over<\/button>\n<button class=\"btn btn-primary\" onclick=\"window.location.href='\/vendor-register\/'\">Become a PTCE \u2192<\/button>\n<\/div>\n<\/div>\n\n<\/div>\n<\/div>\n<\/section>\n\n<!-- SECTION 2: CODE EXAMPLES -->\n<section class=\"section\">\n<span class=\"section-num\">Section II<\/span>\n<h2>Integration Examples<\/h2>\n\n<p>Ready to integrate PTVS into your platform? Here are code examples in Python, JavaScript, and Solidity.<\/p>\n\n<div class=\"code-examples\">\n<div class=\"code-tabs\">\n<div class=\"code-tab active\" onclick=\"switchTab('python')\">Python<\/div>\n<div class=\"code-tab\" onclick=\"switchTab('javascript')\">JavaScript<\/div>\n<div class=\"code-tab\" onclick=\"switchTab('solidity')\">Solidity<\/div>\n<\/div>\n\n<div class=\"code-panel active\" id=\"panel-python\">\n<pre><span style=\"color: #718096;\"># Install: pip install pycryptodome web3<\/span>\n\n<span style=\"color: #F6AD55;\">from<\/span> Crypto.Hash <span style=\"color: #F6AD55;\">import<\/span> SHA256\n<span style=\"color: #F6AD55;\">import<\/span> json\n<span style=\"color: #F6AD55;\">from<\/span> web3 <span style=\"color: #F6AD55;\">import<\/span> Web3\n\n<span style=\"color: #718096;\"># 1. Create canonical JSON<\/span>\ninspection_data = {\n    <span style=\"color: #68D391;\">\"assetId\"<\/span>: <span style=\"color: #68D391;\">\"0x1a2b3c4d5e6f\"<\/span>,\n    <span style=\"color: #68D391;\">\"inspectionDate\"<\/span>: <span style=\"color: #68D391;\">\"2026-08-15T10:30:00Z\"<\/span>,\n    <span style=\"color: #68D391;\">\"ptceId\"<\/span>: <span style=\"color: #68D391;\">\"PTCE-0161\"<\/span>,\n    <span style=\"color: #68D391;\">\"ptvsScore\"<\/span>: <span style=\"color: #F6AD55;\">85<\/span>,\n    <span style=\"color: #68D391;\">\"findings\"<\/span>: {\n        <span style=\"color: #68D391;\">\"structural\"<\/span>: {<span style=\"color: #68D391;\">\"cracks\"<\/span>: <span style=\"color: #F6AD55;\">0<\/span>, <span style=\"color: #68D391;\">\"corrosion\"<\/span>: <span style=\"color: #F6AD55;\">1<\/span>},\n        <span style=\"color: #68D391;\">\"legal\"<\/span>: {<span style=\"color: #68D391;\">\"encumbrances\"<\/span>: <span style=\"color: #F6AD55;\">0<\/span>, <span style=\"color: #68D391;\">\"titleClear\"<\/span>: <span style=\"color: #F6AD55;\">True<\/span>}\n    }\n}\n\n<span style=\"color: #718096;\"># 2. Canonicalize (sorted keys, no whitespace)<\/span>\ncanonical_json = json.dumps(inspection_data, sort_keys=<span style=\"color: #F6AD55;\">True<\/span>, separators=(<span style=\"color: #68D391;\">','<\/span>, <span style=\"color: #68D391;\">':'<\/span>))\n\n<span style=\"color: #718096;\"># 3. Compute SHA-256 hash<\/span>\nhash_obj = SHA256.new(canonical_json.encode(<span style=\"color: #68D391;\">'utf-8'<\/span>))\nforensic_hash = hash_obj.hexdigest()\n\n<span style=\"color: #718096;\"># 4. Inject claim on-chain<\/span>\nw3 = Web3(Web3.HTTPProvider(<span style=\"color: #68D391;\">'https:\/\/mainnet.infura.io\/v3\/YOUR_KEY'<\/span>))\ncontract = w3.eth.contract(address=<span style=\"color: #68D391;\">'0x...'<\/span>, abi=PTVS_ABI)\n\ntx_hash = contract.functions.injectClaim(\n    inspection_data[<span style=\"color: #68D391;\">'assetId'<\/span>],\n    inspection_data[<span style=\"color: #68D391;\">'ptvsScore'<\/span>],\n    bytes.fromhex(forensic_hash),\n    <span style=\"color: #F6AD55;\">1692095400<\/span>,\n    b<span style=\"color: #68D391;\">''<\/span>\n).transact({<span style=\"color: #68D391;\">'from'<\/span>: ptce_address})<\/pre>\n<\/div>\n\n<div class=\"code-panel\" id=\"panel-javascript\">\n<pre><span style=\"color: #718096;\">\/\/ Install: npm install web3<\/span>\n\n<span style=\"color: #F6AD55;\">const<\/span> Web3 = require(<span style=\"color: #68D391;\">'web3'<\/span>);\n<span style=\"color: #F6AD55;\">const<\/span> crypto = require(<span style=\"color: #68D391;\">'crypto'<\/span>);\n\n<span style=\"color: #718096;\">\/\/ 1. Create canonical JSON<\/span>\n<span style=\"color: #F6AD55;\">const<\/span> inspectionData = {\n  assetId: <span style=\"color: #68D391;\">'0x1a2b3c4d5e6f'<\/span>,\n  inspectionDate: <span style=\"color: #68D391;\">'2026-08-15T10:30:00Z'<\/span>,\n  ptceId: <span style=\"color: #68D391;\">'PTCE-0161'<\/span>,\n  ptvsScore: <span style=\"color: #F6AD55;\">85<\/span>,\n  findings: {\n    structural: { cracks: <span style=\"color: #F6AD55;\">0<\/span>, corrosion: <span style=\"color: #F6AD55;\">1<\/span> },\n    legal: { encumbrances: <span style=\"color: #F6AD55;\">0<\/span>, titleClear: <span style=\"color: #F6AD55;\">true<\/span> }\n  }\n};\n\n<span style=\"color: #718096;\">\/\/ 2. Canonicalize (sorted keys, no whitespace)<\/span>\n<span style=\"color: #F6AD55;\">const<\/span> canonicalJson = JSON.stringify(inspectionData, \n  Object.keys(inspectionData).sort().reduce((obj, key) => {\n    obj[key] = inspectionData[key];\n    <span style=\"color: #F6AD55;\">return<\/span> obj;\n  }, {}), \n  <span style=\"color: #F6AD55;\">null<\/span>, \n  <span style=\"color: #F6AD55;\">0<\/span>\n);\n\n<span style=\"color: #718096;\">\/\/ 3. Compute SHA-256 hash<\/span>\n<span style=\"color: #F6AD55;\">const<\/span> forensicHash = crypto\n  .createHash(<span style=\"color: #68D391;\">'sha256'<\/span>)\n  .update(canonicalJson)\n  .digest(<span style=\"color: #68D391;\">'hex'<\/span>);\n\n<span style=\"color: #718096;\">\/\/ 4. Inject claim on-chain<\/span>\n<span style=\"color: #F6AD55;\">const<\/span> web3 = <span style=\"color: #F6AD55;\">new<\/span> Web3(<span style=\"color: #68D391;\">'https:\/\/mainnet.infura.io\/v3\/YOUR_KEY'<\/span>);\n<span style=\"color: #F6AD55;\">const<\/span> contract = <span style=\"color: #F6AD55;\">new<\/span> web3.eth.Contract(PTVS_ABI, <span style=\"color: #68D391;\">'0x...'<\/span>);\n\n<span style=\"color: #F6AD55;\">const<\/span> tx = <span style=\"color: #F6AD55;\">await<\/span> contract.methods.injectClaim(\n  inspectionData.assetId,\n  inspectionData.ptvsScore,\n  <span style=\"color: #68D391;\">'0x'<\/span> + forensicHash,\n  Math.floor(Date.now() \/ <span style=\"color: #F6AD55;\">1000<\/span>),\n  <span style=\"color: #68D391;\">'0x'<\/span>\n).send({ from: ptceAddress });<\/pre>\n<\/div>\n\n<div class=\"code-panel\" id=\"panel-solidity\">\n<pre><span style=\"color: #718096;\">\/\/ SPDX-License-Identifier: MIT<\/span>\n<span style=\"color: #F6AD55;\">pragma<\/span> solidity ^<span style=\"color: #F6AD55;\">0.8.20<\/span>;\n\n<span style=\"color: #F6AD55;\">import<\/span> <span style=\"color: #68D391;\">\"@openzeppelin\/contracts\/access\/Ownable.sol\"<\/span>;\n\n<span style=\"color: #F6AD55;\">contract<\/span> PTVSClaimInjector <span style=\"color: #F6AD55;\">is<\/span> Ownable {\n    \n    <span style=\"color: #F6AD55;\">struct<\/span> VerifiableClaim {\n        <span style=\"color: #F6AD55;\">bytes32<\/span> assetId;\n        <span style=\"color: #F6AD55;\">uint8<\/span> ptvsScore;\n        <span style=\"color: #F6AD55;\">bytes32<\/span> forensicHash;\n        <span style=\"color: #F6AD55;\">uint256<\/span> inspectionTimestamp;\n        <span style=\"color: #F6AD55;\">address<\/span> ptceAddress;\n        ClaimStatus status;\n    }\n    \n    <span style=\"color: #F6AD55;\">enum<\/span> ClaimStatus { VERIFIED, CONDITIONAL, EXPIRED, REVOKED }\n    \n    <span style=\"color: #F6AD55;\">mapping<\/span>(<span style=\"color: #F6AD55;\">bytes32<\/span> => VerifiableClaim) <span style=\"color: #F6AD55;\">public<\/span> claims;\n    <span style=\"color: #F6AD55;\">mapping<\/span>(<span style=\"color: #F6AD55;\">address<\/span> => <span style=\"color: #F6AD55;\">bool<\/span>) <span style=\"color: #F6AD55;\">public<\/span> authorizedPTCEs;\n    \n    <span style=\"color: #F6AD55;\">event<\/span> ClaimInjected(\n        <span style=\"color: #F6AD55;\">bytes32<\/span> <span style=\"color: #F6AD55;\">indexed<\/span> assetId,\n        <span style=\"color: #F6AD55;\">uint8<\/span> ptvsScore,\n        <span style=\"color: #F6AD55;\">bytes32<\/span> forensicHash,\n        <span style=\"color: #F6AD55;\">address<\/span> <span style=\"color: #F6AD55;\">indexed<\/span> ptceAddress,\n        <span style=\"color: #F6AD55;\">uint256<\/span> timestamp\n    );\n    \n    <span style=\"color: #F6AD55;\">modifier<\/span> onlyAuthorizedPTCE() {\n        <span style=\"color: #F6AD55;\">require<\/span>(authorizedPTCEs[msg.sender], <span style=\"color: #68D391;\">\"Not authorized\"<\/span>);\n        _;\n    }\n    \n    <span style=\"color: #F6AD55;\">function<\/span> injectClaim(\n        <span style=\"color: #F6AD55;\">bytes32<\/span> assetId,\n        <span style=\"color: #F6AD55;\">uint8<\/span> ptvsScore,\n        <span style=\"color: #F6AD55;\">bytes32<\/span> forensicHash,\n        <span style=\"color: #F6AD55;\">uint256<\/span> inspectionTimestamp,\n        <span style=\"color: #F6AD55;\">bytes<\/span> <span style=\"color: #F6AD55;\">memory<\/span> ptceSignature\n    ) <span style=\"color: #F6AD55;\">external<\/span> onlyAuthorizedPTCE {\n        ClaimStatus status = ptvsScore >= <span style=\"color: #F6AD55;\">70<\/span> \n            ? ClaimStatus.VERIFIED \n            : ClaimStatus.REVOKED;\n            \n        claims[assetId] = VerifiableClaim({\n            assetId: assetId,\n            ptvsScore: ptvsScore,\n            forensicHash: forensicHash,\n            inspectionTimestamp: inspectionTimestamp,\n            ptceAddress: msg.sender,\n            status: status\n        });\n        \n        <span style=\"color: #F6AD55;\">emit<\/span> ClaimInjected(\n            assetId, \n            ptvsScore, \n            forensicHash, \n            msg.sender, \n            block.timestamp\n        );\n    }\n    \n    <span style=\"color: #F6AD55;\">function<\/span> getClaim(<span style=\"color: #F6AD55;\">bytes32<\/span> assetId) \n        <span style=\"color: #F6AD55;\">external<\/span> <span style=\"color: #F6AD55;\">view<\/span> \n        <span style=\"color: #F6AD55;\">returns<\/span> (VerifiableClaim <span style=\"color: #F6AD55;\">memory<\/span>) \n    {\n        <span style=\"color: #F6AD55;\">return<\/span> claims[assetId];\n    }\n}<\/pre>\n<\/div>\n<\/div>\n<\/section>\n\n<!-- SECTION 3: NEXT STEPS -->\n<section class=\"section\">\n<span class=\"section-num\">Section III<\/span>\n<h2>Next Steps<\/h2>\n\n<div class=\"next-steps\">\n<h3>Ready to Integrate PTVS in Production?<\/h3>\n<p>Move from sandbox to production with our comprehensive resources:<\/p>\n\n<div class=\"next-steps-grid\">\n<div class=\"next-step-card\">\n<h4>\ud83d\udcda Documentation<\/h4>\n<p>Complete technical specification of PTVS v1.0 with 23 sections covering architecture, smart contracts, and regulatory alignment.<\/p>\n<a href=\"\/standard\/\">Read Documentation \u2192<\/a>\n<\/div>\n<div class=\"next-step-card\">\n<h4>\ud83d\udc68\u200d\ud83d\udcbc Become a PTCE<\/h4>\n<p>Join the Prop Trust Certified Expert network. 40-hour certification program. 85% revenue share on inspections.<\/p>\n<a href=\"\/vendor-register\/\">Apply Now \u2192<\/a>\n<\/div>\n<div class=\"next-step-card\">\n<h4>\ud83c\udfe2 Enterprise Integration<\/h4>\n<p>Custom integration support for banks, insurers, and RWA platforms. Dedicated technical account manager.<\/p>\n<a href=\"mailto:enterprise@proptrustverified.com\">Contact Sales \u2192<\/a>\n<\/div>\n<div class=\"next-step-card\">\n<h4>\ud83d\udd2c Research Grants<\/h4>\n<p>\u20ac50,000 annual grants for academic research on PFOI. Open to European universities. Deadline: October 31, 2026.<\/p>\n<a href=\"https:\/\/forensics-oracle.org\/research-grants\/\" target=\"_blank\">Apply for Grant \u2192<\/a>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n\n<\/main>\n\n<!-- ECOSYSTEM FOOTER -->\n<footer class=\"ecosystem-footer\">\n<div class=\"ecosystem-container\">\n<div class=\"ecosystem-label\">\n<span class=\"ecosystem-motto\">VERITAS IN RE \u00b7 CERTITUDO IN CODE<\/span>\n<span class=\"ecosystem-title\">The PFOI Ecosystem<\/span>\n<\/div>\n<div class=\"ecosystem-grid\">\n<a href=\"https:\/\/www.aureliotamaritblay.es\" class=\"eco-link\" target=\"_blank\" rel=\"noopener\">\n<span class=\"eco-role\">Founder \u00b7 Authority<\/span>\n<strong>Aurelio Tamarit Blay<\/strong>\n<span class=\"eco-desc\">Lead Researcher \u00b7 Judicial Expert Exp. 0161<\/span>\n<\/a>\n<a href=\"https:\/\/forensics-oracle.org\" class=\"eco-link\" target=\"_blank\" rel=\"noopener\">\n<span class=\"eco-role\">Standard \u00b7 Governance<\/span>\n<strong>Forensics Oracle Initiative<\/strong>\n<span class=\"eco-desc\">PTVS v1.0 \u00b7 Technical Board \u00b7 Research<\/span>\n<\/a>\n<a href=\"https:\/\/proptrustverified.com\" class=\"eco-link\">\n<span class=\"eco-role\">Certification \u00b7 Network<\/span>\n<strong>Prop Trust Verified<\/strong>\n<span class=\"eco-desc\">PTCE Network \u00b7 Verified by PTVS seal<\/span>\n<\/a>\n<a href=\"https:\/\/aurema-group.com\" class=\"eco-link\" target=\"_blank\" rel=\"noopener\">\n<span class=\"eco-role\">Holding \u00b7 IP \u00b7 Governance<\/span>\n<strong>Aurema Group L.L.C.<\/strong>\n<span class=\"eco-desc\">Delaware, USA \u00b7 Parent Entity<\/span>\n<\/a>\n<\/div>\n<div class=\"ecosystem-footnote\">\n\u00a9 2026 Aurema Group L.L.C. \u00b7 Prop Trust Verified\u2122, PFOI\u2122, PTCE\u2122 and Forensics Oracle\u2122 are registered trademarks.<br>\nPTVS v1.0 Reference Architecture DOI: <a href=\"https:\/\/doi.org\/10.5281\/zenodo.21719175\" target=\"_blank\" rel=\"noopener\">10.5281\/zenodo.21719175<\/a> \u00b7 Contact: <a href=\"mailto:enterprise@proptrustverified.com\">enterprise@proptrustverified.com<\/a>\n<\/div>\n<\/div>\n<\/footer>\n\n<script>\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 SANDBOX LOGIC \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nlet currentStep = 1;\nlet generatedHash = '';\n\n\/\/ Step navigation\nfunction nextStep(step) {\n  document.getElementById(`step${currentStep}`).style.display = 'none';\n  document.getElementById(`step${step}`).style.display = 'block';\n  \n  \/\/ Update step indicators\n  document.querySelectorAll('.step-dot').forEach((dot, idx) => {\n    dot.classList.remove('active', 'completed');\n    if (idx + 1 < step) dot.classList.add('completed');\n    if (idx + 1 === step) dot.classList.add('active');\n  });\n  \n  currentStep = step;\n  \n  \/\/ Execute step-specific logic\n  if (step === 3) calculateScore();\n  if (step === 4) generateCanonicalJson();\n  if (step === 5) injectClaim();\n  if (step === 6) verifyClaim();\n  \n  window.scrollTo({ top: 0, behavior: 'smooth' });\n}\n\nfunction prevStep(step) {\n  nextStep(step);\n}\n\nfunction resetSandbox() {\n  currentStep = 1;\n  document.querySelectorAll('.form-section').forEach(s => s.style.display = 'none');\n  document.getElementById('step1').style.display = 'block';\n  document.querySelectorAll('.step-dot').forEach((dot, idx) => {\n    dot.classList.remove('active', 'completed');\n    if (idx === 0) dot.classList.add('active');\n  });\n  window.scrollTo({ top: 0, behavior: 'smooth' });\n}\n\n\/\/ Update score display in real-time\nfunction updateScoreDisplay() {\n  document.getElementById('structuralValue').textContent = document.getElementById('structuralScore').value;\n  document.getElementById('legalValue').textContent = document.getElementById('legalScore').value;\n  document.getElementById('environmentalValue').textContent = document.getElementById('environmentalScore').value;\n  document.getElementById('documentationValue').textContent = document.getElementById('documentationScore').value;\n  document.getElementById('insuranceValue').textContent = document.getElementById('insuranceScore').value;\n}\n\n\/\/ Calculate PTVS Score\nfunction calculateScore() {\n  const structural = parseInt(document.getElementById('structuralScore').value);\n  const legal = parseInt(document.getElementById('legalScore').value);\n  const environmental = parseInt(document.getElementById('environmentalScore').value);\n  const documentation = parseInt(document.getElementById('documentationScore').value);\n  const insurance = parseInt(document.getElementById('insuranceScore').value);\n  \n  const ptvsScore = Math.round(\n    (structural * 0.40) +\n    (legal * 0.25) +\n    (environmental * 0.20) +\n    (documentation * 0.10) +\n    (insurance * 0.05)\n  );\n  \n  document.getElementById('ptvsScoreDisplay').textContent = ptvsScore;\n  document.getElementById('breakdownStructural').textContent = structural;\n  document.getElementById('breakdownLegal').textContent = legal;\n  document.getElementById('breakdownEnvironmental').textContent = environmental;\n  document.getElementById('breakdownDocumentation').textContent = documentation;\n  document.getElementById('breakdownInsurance').textContent = insurance;\n  \n  const statusEl = document.getElementById('scoreStatus');\n  if (ptvsScore >= 70) {\n    statusEl.textContent = 'VERIFIED';\n    statusEl.className = 'score-status verified';\n  } else if (ptvsScore >= 50) {\n    statusEl.textContent = 'CONDITIONAL';\n    statusEl.className = 'score-status conditional';\n  } else {\n    statusEl.textContent = 'REVOKED';\n    statusEl.className = 'score-status revoked';\n  }\n}\n\n\/\/ Generate canonical JSON and compute hash\nasync function generateCanonicalJson() {\n  const inspectionData = {\n    assetId: document.getElementById('assetId').value,\n    assetName: document.getElementById('assetName').value,\n    assetType: document.getElementById('assetType').value,\n    environmental: {\n      contamination: 0,\n      hazards: 0,\n      score: parseInt(document.getElementById('environmentalScore').value)\n    },\n    inspectionDate: new Date().toISOString(),\n    insurance: {\n      active: true,\n      score: parseInt(document.getElementById('insuranceScore').value)\n    },\n    jurisdiction: document.getElementById('jurisdiction').value,\n    legal: {\n      encumbrances: 0,\n      score: parseInt(document.getElementById('legalScore').value),\n      titleClear: true\n    },\n    notes: document.getElementById('inspectorNotes').value,\n    ptceId: 'PTCE-0161',\n    ptvsScore: parseInt(document.getElementById('ptvsScoreDisplay').textContent),\n    structural: {\n      corrosion: 1,\n      cracks: 0,\n      degradation: 0,\n      score: parseInt(document.getElementById('structuralScore').value)\n    }\n  };\n  \n  \/\/ Canonical JSON (sorted keys, no whitespace)\n  const canonicalJson = JSON.stringify(inspectionData, Object.keys(inspectionData).sort());\n  \n  document.getElementById('canonicalJsonOutput').textContent = JSON.stringify(inspectionData, null, 2);\n  \n  \/\/ Compute SHA-256 hash using Web Crypto API\n  const encoder = new TextEncoder();\n  const data = encoder.encode(canonicalJson);\n  const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n  const hashArray = Array.from(new Uint8Array(hashBuffer));\n  generatedHash = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n  \n  document.getElementById('hashValue').textContent = '0x' + generatedHash;\n}\n\n\/\/ Inject claim (simulated)\nfunction injectClaim() {\n  const assetId = document.getElementById('assetId').value;\n  const ptvsScore = document.getElementById('ptvsScoreDisplay').textContent;\n  const timestamp = new Date().toISOString();\n  \n  document.getElementById('claimAssetId').textContent = assetId;\n  document.getElementById('claimScore').textContent = ptvsScore + ' \/ 100';\n  document.getElementById('claimHash').textContent = '0x' + generatedHash;\n  document.getElementById('claimTimestamp').textContent = timestamp;\n  \n  const status = parseInt(ptvsScore) >= 70 ? 'VERIFIED' : 'REVOKED';\n  document.getElementById('claimStatus').textContent = status;\n  \n  \/\/ Generate Solidity event output\n  const eventOutput = `event ClaimInjected(\n    bytes32 indexed assetId: ${assetId},\n    uint8 ptvsScore: ${ptvsScore},\n    bytes32 forensicHash: 0x${generatedHash},\n    address indexed ptceAddress: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb,\n    uint256 timestamp: ${Math.floor(Date.now() \/ 1000)}\n);\n\n\/\/ Transaction Hash (simulated): 0x${Math.random().toString(16).substring(2, 66)}\n\/\/ Block Number: ${Math.floor(Math.random() * 1000000) + 18000000}\n\/\/ Gas Used: 125,432`;\n  \n  document.getElementById('solidityEventOutput').textContent = eventOutput;\n}\n\n\/\/ Verify claim\nfunction verifyClaim() {\n  document.getElementById('verifyHash1').textContent = '0x' + generatedHash;\n  document.getElementById('verifyHash2').textContent = '0x' + generatedHash;\n}\n\n\/\/ Tab switching for code examples\nfunction switchTab(lang) {\n  document.querySelectorAll('.code-tab').forEach(tab => tab.classList.remove('active'));\n  document.querySelectorAll('.code-panel').forEach(panel => panel.classList.remove('active'));\n  \n  event.target.classList.add('active');\n  document.getElementById(`panel-${lang}`).classList.add('active');\n}\n\n\/\/ Initialize\nupdateScoreDisplay();\n<\/script>\n\n<\/body>\n<\/html>\n<div style=\"margin: 20px 0;\"><div class=\"qrcswholewtapper\" style=\"text-align:left;\"><div class=\"qrcprowrapper\"  id=\"qrcwraa2leds\"><div class=\"qrc_canvass\" id=\"qrc_cuttenpages_2\" style=\"display:inline-block\" data-text=\"https:\/\/proptrustverified.com\/es\/sandbox\/\"><\/div><div><a download=\"PTVS SandBox.png\" class=\"qrcdownloads\" id=\"worign\">\r\n           <button type=\"button\" style=\"min-width:200px;background:#dddddd;color:#000;font-weight: 600;border: 1px solid #dddddd;border-radius:4px;font-size:12px;padding: 6px 0;\" class=\"uqr_code_btn\">Download QR<\/button>\r\n           <\/a><\/div><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>PTVS Sandbox \u2014 Try Prop Trust Verified Standard in 5 Minutes Prop Trust VerifiedCertification \u00b7 PTCE Network Home PTVS Standard PTCE Registry Sandbox Register Interactive Playground \u00b7 No Backend Required PTVS Sandbox Experience the Prop Trust Verified Standard in your browser. Create a mock asset, generate forensic evidence, compute cryptographic hashes, and simulate on-chain Verifiable [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-2196","page","type-page","status-publish","hentry"],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/proptrustverified.com\/es\/wp-json\/wp\/v2\/pages\/2196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/proptrustverified.com\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/proptrustverified.com\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/proptrustverified.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/proptrustverified.com\/es\/wp-json\/wp\/v2\/comments?post=2196"}],"version-history":[{"count":2,"href":"https:\/\/proptrustverified.com\/es\/wp-json\/wp\/v2\/pages\/2196\/revisions"}],"predecessor-version":[{"id":2200,"href":"https:\/\/proptrustverified.com\/es\/wp-json\/wp\/v2\/pages\/2196\/revisions\/2200"}],"wp:attachment":[{"href":"https:\/\/proptrustverified.com\/es\/wp-json\/wp\/v2\/media?parent=2196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}