Jethro85
commited on
Commit
·
79d5f1b
1
Parent(s):
bdb2e55
log to supabase
Browse files- app/static/js/attacks.js +131 -0
app/static/js/attacks.js
CHANGED
|
@@ -16,6 +16,9 @@ class AttackSimulator {
|
|
| 16 |
|
| 17 |
// Slider updates
|
| 18 |
this.setupSliderUpdates();
|
|
|
|
|
|
|
|
|
|
| 19 |
}
|
| 20 |
|
| 21 |
setupSliderUpdates() {
|
|
@@ -68,6 +71,131 @@ class AttackSimulator {
|
|
| 68 |
}
|
| 69 |
}
|
| 70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
|
| 72 |
|
| 73 |
switchTab(attackType) {
|
|
@@ -85,6 +213,9 @@ class AttackSimulator {
|
|
| 85 |
|
| 86 |
// Initialize chart for this tab if needed
|
| 87 |
this.initializeTabChart(attackType);
|
|
|
|
|
|
|
|
|
|
| 88 |
}
|
| 89 |
|
| 90 |
initializeCharts() {
|
|
|
|
| 16 |
|
| 17 |
// Slider updates
|
| 18 |
this.setupSliderUpdates();
|
| 19 |
+
|
| 20 |
+
// ✅ Add this (bind events for whatever tab is active on load)
|
| 21 |
+
this.bindAttacksPageEvents();
|
| 22 |
}
|
| 23 |
|
| 24 |
setupSliderUpdates() {
|
|
|
|
| 71 |
}
|
| 72 |
}
|
| 73 |
|
| 74 |
+
bindAttacksPageEvents(attackType = null) {
|
| 75 |
+
// Bind only within the currently active attack content (prevents binding to hidden/nonexistent nodes)
|
| 76 |
+
const container = attackType
|
| 77 |
+
? document.getElementById(`${attackType}-content`)
|
| 78 |
+
: document.querySelector('.attack-content.active');
|
| 79 |
+
|
| 80 |
+
if (!container) return;
|
| 81 |
+
|
| 82 |
+
// Helper: bind once per element per handler-key
|
| 83 |
+
const bindOnce = (el, key, eventName, fn) => {
|
| 84 |
+
if (!el) return;
|
| 85 |
+
const flag = `bound_${key}`;
|
| 86 |
+
if (el.dataset[flag] === '1') return;
|
| 87 |
+
el.addEventListener(eventName, fn);
|
| 88 |
+
el.dataset[flag] = '1';
|
| 89 |
+
};
|
| 90 |
+
|
| 91 |
+
// ---- Membership tab ----
|
| 92 |
+
bindOnce(
|
| 93 |
+
container.querySelector('#privacy-level-slider'),
|
| 94 |
+
'privacy_level_slider',
|
| 95 |
+
'input',
|
| 96 |
+
() => this.updateMembershipDemo()
|
| 97 |
+
);
|
| 98 |
+
|
| 99 |
+
bindOnce(
|
| 100 |
+
container.querySelector('#update-privacy-btn'),
|
| 101 |
+
'update_privacy_btn',
|
| 102 |
+
'click',
|
| 103 |
+
(e) => {
|
| 104 |
+
// If you have a button on the Attacks page, prefer binding here over inline onclick
|
| 105 |
+
e.preventDefault();
|
| 106 |
+
this.updateMembershipDemo();
|
| 107 |
+
}
|
| 108 |
+
);
|
| 109 |
+
|
| 110 |
+
// ---- Reconstruction tab ----
|
| 111 |
+
bindOnce(
|
| 112 |
+
container.querySelector('#recon-clipping-slider'),
|
| 113 |
+
'recon_clipping_slider',
|
| 114 |
+
'input',
|
| 115 |
+
() => this.updateReconstructionAttack()
|
| 116 |
+
);
|
| 117 |
+
|
| 118 |
+
bindOnce(
|
| 119 |
+
container.querySelector('#recon-noise-slider'),
|
| 120 |
+
'recon_noise_slider',
|
| 121 |
+
'input',
|
| 122 |
+
() => this.updateReconstructionAttack()
|
| 123 |
+
);
|
| 124 |
+
|
| 125 |
+
bindOnce(
|
| 126 |
+
container.querySelector('#run-reconstruction-btn'),
|
| 127 |
+
'run_reconstruction_btn',
|
| 128 |
+
'click',
|
| 129 |
+
(e) => {
|
| 130 |
+
e.preventDefault();
|
| 131 |
+
this.updateReconstructionAttack();
|
| 132 |
+
updateCurrentReconstructionExamples();
|
| 133 |
+
}
|
| 134 |
+
);
|
| 135 |
+
|
| 136 |
+
// ---- Inversion tab ----
|
| 137 |
+
bindOnce(
|
| 138 |
+
container.querySelector('#inversion-privacy-slider'),
|
| 139 |
+
'inversion_privacy_slider',
|
| 140 |
+
'input',
|
| 141 |
+
() => {
|
| 142 |
+
const privacySlider = container.querySelector('#inversion-privacy-slider');
|
| 143 |
+
const classSelect = container.querySelector('#inversion-class-select');
|
| 144 |
+
if (!privacySlider || !classSelect) return;
|
| 145 |
+
|
| 146 |
+
const sliderValue = parseInt(privacySlider.value);
|
| 147 |
+
const privacyLevel = 11 - sliderValue;
|
| 148 |
+
drawInvertedFeatures(classSelect.value, privacyLevel);
|
| 149 |
+
}
|
| 150 |
+
);
|
| 151 |
+
|
| 152 |
+
bindOnce(
|
| 153 |
+
container.querySelector('#run-inversion-btn'),
|
| 154 |
+
'run_inversion_btn',
|
| 155 |
+
'click',
|
| 156 |
+
(e) => {
|
| 157 |
+
e.preventDefault();
|
| 158 |
+
// If you want: call your existing function or inline the logic
|
| 159 |
+
runInversionAttack();
|
| 160 |
+
}
|
| 161 |
+
);
|
| 162 |
+
|
| 163 |
+
// ---- Property tab ----
|
| 164 |
+
bindOnce(
|
| 165 |
+
container.querySelector('#run-property-btn'),
|
| 166 |
+
'run_property_btn',
|
| 167 |
+
'click',
|
| 168 |
+
(e) => {
|
| 169 |
+
e.preventDefault();
|
| 170 |
+
runPropertyAttack();
|
| 171 |
+
}
|
| 172 |
+
);
|
| 173 |
+
|
| 174 |
+
// ---- Linkage tab ----
|
| 175 |
+
bindOnce(
|
| 176 |
+
container.querySelector('#linkage-quality-slider'),
|
| 177 |
+
'linkage_quality_slider',
|
| 178 |
+
'input',
|
| 179 |
+
() => this.updateLinkageAttack()
|
| 180 |
+
);
|
| 181 |
+
|
| 182 |
+
bindOnce(
|
| 183 |
+
container.querySelector('#linkage-privacy-slider'),
|
| 184 |
+
'linkage_privacy_slider',
|
| 185 |
+
'input',
|
| 186 |
+
() => this.updateLinkageAttack()
|
| 187 |
+
);
|
| 188 |
+
|
| 189 |
+
bindOnce(
|
| 190 |
+
container.querySelector('#run-linkage-btn'),
|
| 191 |
+
'run_linkage_btn',
|
| 192 |
+
'click',
|
| 193 |
+
(e) => {
|
| 194 |
+
e.preventDefault();
|
| 195 |
+
this.updateLinkageAttack();
|
| 196 |
+
}
|
| 197 |
+
);
|
| 198 |
+
}
|
| 199 |
|
| 200 |
|
| 201 |
switchTab(attackType) {
|
|
|
|
| 213 |
|
| 214 |
// Initialize chart for this tab if needed
|
| 215 |
this.initializeTabChart(attackType);
|
| 216 |
+
|
| 217 |
+
// ✅ Add this (bind events for the newly activated tab)
|
| 218 |
+
this.bindAttacksPageEvents(attackType);
|
| 219 |
}
|
| 220 |
|
| 221 |
initializeCharts() {
|