CHANGE PREVIEWLIVE REGISTRY COMPARED WITH CONTRIBUTOR SUBMISSION
{currentSnapshot ? 'BEFORE / AFTER' : 'NEW RECORD'}
{#if module === 'attributes' && action === 'save'}
CURRENT LIVE{currentSnapshot ? 'BEFORE' : 'NO LIVE RECORD'}
{#if currentSnapshot}
NAME{shown(attributeValue('current', 'name'))}
DESCRIPTION · OPTIONAL{shown(attributeValue('current', 'description'))}
{#each [['type','TYPE'],['category','CATEGORY'],['calculation_type','CALCULATION'],['unit','UNIT']] as field}
{field[1]}{shown(attributeValue('current', field[0]))}
{/each} {#each [['gear','GEAR'],['weapon','WEAPON']] as source}
{source[1]} RANGE · OPTIONAL
{shown(attributeValue('current', `${source[0]}_min`))}TO{shown(attributeValue('current', `${source[0]}_max`))}
{/each}
OPTIONAL CAP{shown(attributeValue('current', 'cap_value'))}
{:else}
NEW ATTRIBUTE DEFINITIONNo live registry record will be replaced.
{/if}
PROPOSED DEFINITIONAFTER
NAME{shown(attributeValue('proposed', 'name'))}
DESCRIPTION · OPTIONAL{shown(attributeValue('proposed', 'description'))}
{#each [['type','TYPE'],['category','CATEGORY'],['calculation_type','CALCULATION'],['unit','UNIT']] as field}
{field[1]}{shown(attributeValue('proposed', field[0]))}
{/each} {#each [['gear','GEAR'],['weapon','WEAPON']] as source}
{source[1]} RANGE · OPTIONAL
{shown(attributeValue('proposed', `${source[0]}_min`))}TO{shown(attributeValue('proposed', `${source[0]}_max`))}
{/each}
OPTIONAL CAP{shown(attributeValue('proposed', 'cap_value'))}
{:else if module === 'skillchips' && ['savePrimaryProfile','saveSecondaryPool'].includes(action)}
CURRENT LIVE · SHARED {action === 'savePrimaryProfile' ? 'PRIMARY PROFILE' : 'SECONDARY POOL'}BEFORE
{#each currentSharedSkillChipProfiles as profile}

{profile.statId} · {Object.entries(profile.values ?? {}).map(([quality, range]: [string, any]) => `${quality.toUpperCase()} ${shown(range.min)}–${shown(range.max)}`).join(' · ')}

{:else}

SHARED PROFILE NOT CONFIGURED

{/each}
PROPOSED · SHARED {action === 'savePrimaryProfile' ? 'PRIMARY PROFILE' : 'SECONDARY POOL'}AFTER
{#each proposedSharedSkillChipProfiles as profile}

{profile.statId} · {Object.entries(profile.values ?? {}).map(([quality, range]: [string, any]) => `${quality.toUpperCase()} ${shown(range.min)}–${shown(range.max)}`).join(' · ')}

{/each}
{:else if module === 'skillchips' && action === 'save'}
CURRENT LIVE · SKILL CHIP{skillChipRecord ? 'BEFORE' : 'NO LIVE RECORD'}
{#if skillChipRecord}
{#each skillChipFields as field}
{field.label}{shown(field.current)}
{/each}
3-PIECE TALENT{currentSnapshot?.talent ? 'ASSIGNED' : 'NOT ASSIGNED'}
3-PIECE CONDITIONAL MECHANICTYPED RULE
{#each conditionalRuleLines(currentSnapshot?.conditional) as line}

{line}

{:else}

NO TYPED RULE CONFIGURED

{/each}
{:else}
NEW SKILL CHIPNo live registry record will be replaced.
{/if}
PROPOSED · SKILL CHIPAFTER
{#each skillChipFields as field}
{field.label}{shown(field.proposed)}
{/each}
3-PIECE TALENT{proposed.hasTalent === '1' ? 'ASSIGNED' : 'NOT ASSIGNED'}
3-PIECE CONDITIONAL MECHANICTYPED RULE
{#each conditionalRuleLines(jsonValue(proposed.conditionalRule)) as line}

{line}

{:else}

NO TYPED RULE CONFIGURED

{/each}
{:else if module === 'calculations'}
CURRENT LIVE · {action === 'saveRevision' ? 'CALCULATION REVISION' : 'CALIBRATION CASE'}{calculationRecord ? 'BEFORE' : 'NO LIVE RECORD'}
{#if calculationRecord}
NAME{shown(calculationRecord.name)}
STATE{shown(calculationRecord.status)}
{#if action === 'saveRevision'}
STAGES{(currentSnapshot?.stages as any[])?.length ?? 0}
WEAPON PROFILES{(currentSnapshot?.profiles as any[])?.length ?? 0}
SKILL PROFILES{(currentSnapshot?.skillProfiles as any[])?.length ?? 0}
{/if}
{:else}
NEW {action === 'saveRevision' ? 'CALCULATION REVISION' : 'CALIBRATION CASE'}No live registry record will be replaced.
{/if}
PROPOSED · {action === 'saveRevision' ? 'CALCULATION REVISION' : 'CALIBRATION CASE'}AFTER
NAME{shown(proposed.name)}
{#if action === 'saveRevision'}
STAGES{proposedCalculationStages.length}
WEAPON PROFILES{proposedCalculationProfiles.length}
SKILL PROFILES{proposedSkillCalculationProfiles.length}
BASE REVISION{shown(proposed.basedOnRevisionId)}
{:else}
STATE{shown(proposed.status)}
MEASURED WEAPON{proposed.selectedWeapon === '1' ? 'SECONDARY' : 'PRIMARY'}
CORE OBSERVATIONS{['bodyHit','criticalBodyHit','headshot','criticalHeadshot','magazineSeconds','reloadSeconds'].filter((field) => proposed[field]).length} / 6
{/if}
{#if action === 'saveRevision'}
{#each proposedCalculationStages as stage}
{stage.label}{stage.operator?.replaceAll('_',' ').toUpperCase()}

ORDER {stage.displayOrder} · {stage.lockedPosition?.toUpperCase() ?? 'REORDERABLE'}

{/each}
{/if}
{:else if module === 'specializations' && ['saveProgression','saveSpecialization','saveFocus','saveAbility','saveCombatEffect','saveFocusAbilities','saveNode'].includes(action)}
CURRENT LIVE · {specializationKind}{specializationRecord ? 'BEFORE' : 'NO LIVE RECORD'}
{#if specializationRecord}
{#each specializationFields as field}
{field.label}{shown(field.current)}
{/each}
{#if action === 'saveAbility'}
STRUCTURED EFFECTS{currentAbilityEffects.length}
{#each currentAbilityEffects as effect}

{effectSummary(effect)}

{:else}

NO STRUCTURED EFFECTS

{/each}
INTRINSIC ATTACK PROFILE{currentAbilityAttack ? 'CONFIGURED' : 'NONE'}
{#each attackProfileLines(currentAbilityAttack) as line}

{line}

{:else}

NO INTRINSIC ATTACK PROFILE

{/each}
{:else if action === 'saveNode'}
{#each currentNodeRanks as rank}
RANK {rank.rank}{currentNodeEffects.filter((effect) => Number(effect.rank) === Number(rank.rank)).length} EFFECTS

{rank.description}

{currentNodeCosts.filter((cost) => Number(cost.rank) === Number(rank.rank)).map((cost) => `${cost.resource_id} × ${cost.quantity}`).join(' · ') || 'CREDITS ONLY'}
{/each}
{:else if action === 'saveProgression'}
{#each currentRankProfiles as profile}
RANK {profile.rank}{profile.point_cost} POINTS

{Number(profile.credit_cost).toLocaleString()} CREDITS

{/each}
{/if} {:else}
NEW {specializationKind}No live registry record will be replaced.
{/if}
PROPOSED · {specializationKind}AFTER
{#each specializationFields as field}
{field.label}{shown(field.proposed)}
{/each}
{#if action === 'saveAbility'}
STRUCTURED EFFECTS{proposedEffects.length}
{#each proposedEffects as effect}

{effectSummary(effect)}

{:else}

NO STRUCTURED EFFECTS

{/each}
INTRINSIC ATTACK PROFILE{attackProfileLines(proposedAbilityAttack).length ? 'CONFIGURED' : 'NONE'}
{#each attackProfileLines(proposedAbilityAttack) as line}

{line}

{:else}

NO INTRINSIC ATTACK PROFILE

{/each}
{:else if action === 'saveNode'}
{#each proposedRanks as rank}
RANK {rank.rank}{rank.effects?.length ?? 0} STATIC · {rank.combatEffects?.length ?? 0} CONDITIONAL

{rank.description || 'NO RANK DESCRIPTION'}

{#each rank.effects ?? [] as effect}{effectSummary(effect)}{/each} {#each rank.combatEffects ?? [] as effect}{conditionalRuleSummary(effect)}{/each} {Object.entries(rank.costs ?? {}).filter(([, quantity]) => Number(quantity) > 0).map(([resource, quantity]) => `${resource} × ${quantity}`).join(' · ') || 'CREDITS ONLY'}
{/each}
{:else if action === 'saveProgression'}
{#each [1,2,3] as rank}
RANK {rank}{shown(proposed[`rank${rank}PointCost`])} POINTS

{Number(proposed[`rank${rank}CreditCost`] || 0).toLocaleString()} CREDITS

{/each}
{/if}
{:else}
PROPOSED {label(module)} RECORDAFTER
{#each entries as entry}
{label(entry.name)} {#if entry.kind === 'file'} {entry.fileName || 'UPLOADED FILE'}{entry.type || 'FILE EVIDENCE'} {:else if jsonValue(entry.value)} {Array.isArray(jsonValue(entry.value)) ? `${jsonValue(entry.value).length} CONFIGURED ITEMS` : 'CONFIGURED DATA'} {entry.value} {:else} {shown(entry.value)} {/if}
{/each}
{/if}