'; $out .= ''; $out .= ''; $out .= ''; return $out; } function vs01_render_field_number($field, $value = '') { $id = vs01_h($field['id']); $out = '
'; $out .= ''; $out .= ''; $out .= '
'; return $out; } function vs01_render_field_date($field, $value = '') { $id = vs01_h($field['id']); $out = '
'; $out .= ''; $out .= ''; $out .= '
'; return $out; } function vs01_render_field_boolean($field, $value = '') { $id = vs01_h($field['id']); $yes = ($value === 'true') ? 'checked' : ''; $no = ($value === 'false') ? 'checked' : ''; $req = !empty($field['required']) ? 'required' : ''; $out = '
'; $out .= '
'; $out .= '' . vs01_h($field['label']) . ''; $out .= '
'; $out .= '
'; $out .= '
'; return $out; } function vs01_render_field_select($field, $value = '') { $id = vs01_h($field['id']); $options = $field['options'] ?? []; $out = '
'; $out .= ''; $out .= '
'; return $out; } function vs01_render_field_textarea($field, $value = '') { $id = vs01_h($field['id']); $out = '
'; $out .= ''; $out .= ''; $out .= '
'; return $out; } function vs01_render_field_multiselect($field, $value = '') { $id = vs01_h($field['id']); $options = $field['options'] ?? []; $selected = $value ? json_decode($value, true) : []; if (!is_array($selected)) $selected = []; $out = '
'; $out .= '
' . vs01_h($field['label']) . ''; foreach ($options as $opt) { $v = vs01_h($opt['value']); $l = vs01_h($opt['label']); $chk = in_array($opt['value'], $selected) ? 'checked' : ''; $out .= '
'; } $out .= '
'; return $out; } // ---------------------------------------------------------------------------- // FIELD DISPATCHER // ---------------------------------------------------------------------------- function vs01_render_field($field, $submitted_values = []) { $id = $field['id'] ?? ''; $type = $field['type'] ?? 'text'; $value = $submitted_values[$id] ?? ''; switch ($type) { case 'text': $html = vs01_render_field_text($field, $value); break; case 'number': $html = vs01_render_field_number($field, $value); break; case 'date': $html = vs01_render_field_date($field, $value); break; case 'boolean': $html = vs01_render_field_boolean($field, $value); break; case 'select': $html = vs01_render_field_select($field, $value); break; case 'textarea': $html = vs01_render_field_textarea($field, $value); break; case 'multiselect': $html = vs01_render_field_multiselect($field, $value); break; default: $html = '
Unknown field type: ' . vs01_h($type) . '
'; } $html .= vs01_render_diagnostic_flag($field, $value); return $html; } // ---------------------------------------------------------------------------- // CONDITIONAL DISPLAY // ---------------------------------------------------------------------------- function vs01_wrap_depends_on($field, $html) { if (empty($field['depends_on'])) return $html; $dep_field = vs01_h($field['depends_on']['field']); $dep_value = $field['depends_on']['value']; $dep_value = is_array($dep_value) ? vs01_h(json_encode($dep_value)) : vs01_h((string) $dep_value); return ''; } // ---------------------------------------------------------------------------- // DIAGNOSTIC FLAGS // ---------------------------------------------------------------------------- function vs01_render_diagnostic_flag($field, $value) { if (empty($field['diagnostic_flag'])) return ''; $condition = $field['flag_condition'] ?? null; if ($condition === null) return ''; $triggered = false; if (is_array($condition)) { $triggered = in_array($value, $condition); } elseif (is_bool($condition)) { $triggered = ($value === ($condition ? 'true' : 'false')); } else { $triggered = ($value === (string) $condition); } if (!$triggered) return ''; $severity = vs01_flag_severity($field); $label = vs01_h($field['flag_label'] ?? 'Diagnostic condition'); $note = isset($field['flag_note']) ? '

' . vs01_h($field['flag_note']) . '

' : ''; return ''; } function vs01_flag_severity($field) { $id = $field['id'] ?? ''; if (in_array($id, ['pro_selfdealing_verified', 'pro_standing_verified', 'pro_incumbent_perpetuation_risk'])) { return 'critical'; } if (str_starts_with($id, 'pro_')) return 'high'; return 'standard'; } // ---------------------------------------------------------------------------- // COMPOUND CONDITION BANNERS // ---------------------------------------------------------------------------- function vs01_render_compound_banners($association_slug) { // TODO: query stored VS records for this association from orchestrator // and evaluate the three compound conditions defined in VS-RENDERER-SPEC.md. // Returns empty string until orchestrator query is implemented. return ''; } // ---------------------------------------------------------------------------- // CROSS-VS REFERENCE NOTES // ---------------------------------------------------------------------------- function vs01_render_cross_reference($vs_code, $label, $association_slug) { $url = z_root() . '/vs01/' . vs01_h($association_slug) . '/' . vs01_h($vs_code); return '
See also: ' . vs01_h($label) . '
'; } // ---------------------------------------------------------------------------- // VERIFICATION SOURCES PANEL // ---------------------------------------------------------------------------- function vs01_render_verification_sources($meta) { $sources = $meta['verification_sources'] ?? []; if (empty($sources)) return ''; $code = vs01_h($meta['code'] ?? 'vs'); $out = '
'; $out .= ''; $out .= '
'; foreach ($sources as $source) { $label = vs01_h($source['label'] ?? ''); $url = vs01_h($source['url'] ?? ''); $instruction = vs01_h($source['instruction'] ?? ''); $out .= '
'; $out .= '' . $label . ''; $out .= '

' . $instruction . '

'; $out .= '
'; } $out .= '
'; return $out; } // ---------------------------------------------------------------------------- // PERSPECTIVE NOTE (VS-07 and VS-09 homeowner slot) // ---------------------------------------------------------------------------- function vs01_render_perspective_note($schema, $perspective_key) { if ($perspective_key !== 'homeowner') return ''; $code = $schema['_meta']['code'] ?? ''; if (!in_array($code, ['VS-07', 'VS-09'])) return ''; $notes = $schema['_meta']['renderer_notes'] ?? ''; if (!$notes) return ''; return '
' . vs01_h($notes) . '
'; } // ---------------------------------------------------------------------------- // IMMUTABLE PUBLIC RECORD // ---------------------------------------------------------------------------- function vs01_public_record_exists($vs_code, $association_slug) { // TODO: query orchestrator for existing promoted public record return false; } function vs01_render_public_record_readonly($perspective, $values) { $out = '
'; foreach ($perspective['fields'] ?? [] as $field) { $id = vs01_h($field['id'] ?? ''); $label = vs01_h($field['label'] ?? ''); $value = vs01_h($values[$field['id'] ?? ''] ?? '—'); $out .= '
'; $out .= '' . $label . ' '; $out .= '' . $value . ''; $out .= '
'; } $out .= '
'; return $out; }