@anonympins/fingerprint 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  * Plugin Name: Anonympins Bot Mitigation with Proof-of-Work
4
4
  * Plugin URI: https://github.com/anonympins/fingerprint
5
5
  * Description: High-performance client-side anti-bot protection and Proof-of-Work challenge verification for WordPress.
6
- * Version: 0.8.1
6
+ * Version: 0.8.2
7
7
  * Author: anonympins
8
8
  * Requires at least: 5.9
9
9
  * Requires PHP: 8.0
@@ -25,7 +25,7 @@ if (!defined('ABSPATH')) {
25
25
  }
26
26
 
27
27
  if (!defined('ANONYMPINS_BOT_MITIGATION_VERSION')) {
28
- define('ANONYMPINS_BOT_MITIGATION_VERSION', '0.8.1');
28
+ define('ANONYMPINS_BOT_MITIGATION_VERSION', '0.8.2');
29
29
  }
30
30
 
31
31
  if (!defined('ANONYMPINS_BOT_MITIGATION_DIR')) {
@@ -145,6 +145,31 @@ function fingerprint_get_metrics_endpoint(): string {
145
145
  return str_starts_with($path, '/') ? $path : '/' . $path;
146
146
  }
147
147
 
148
+ /**
149
+ * Returns the built-in default HTML challenge template (derived from fingerprint.js).
150
+ */
151
+ function fingerprint_get_default_challenge_template(): string {
152
+ return "<!DOCTYPE html>\n" .
153
+ "<html>\n" .
154
+ "<head>\n" .
155
+ "\t<meta charset=\"utf-8\">\n" .
156
+ "\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" .
157
+ "\t<title>{{TITLE}}</title>\n" .
158
+ "\t<style>\n" .
159
+ "\t\t{{CUSTOM_CSS}}\n" .
160
+ "\t\tbody { font-family: sans-serif; text-align: center; padding-top: 50px; background: #fff; color: #222; }\n" .
161
+ "\t\t#loader { margin: 20px; font-size: 15px; color: #2271b1; }\n" .
162
+ "\t</style>\n" .
163
+ "</head>\n" .
164
+ "<body>\n" .
165
+ "\t<h1>{{TITLE}}</h1>\n" .
166
+ "\t<p>{{MESSAGE}}</p>\n" .
167
+ "\t<div id=\"loader\">⚙️ Initializing combined verification...</div>\n" .
168
+ "\t{{SOLVER_SCRIPT}}\n" .
169
+ "</body>\n" .
170
+ "</html>";
171
+ }
172
+
148
173
  // 1. PSR-4 autoloader for the Fingerprint engine.
149
174
  if (!class_exists(DirectFingerprint::class)) {
150
175
  $fingerprint_composer_paths = [
@@ -219,7 +244,7 @@ add_action('fingerprint_prune_expired_entries', function () {
219
244
  add_action('admin_notices', function () {
220
245
  if (!is_ssl()) {
221
246
  echo '<div class="notice notice-warning is-dismissible">';
222
- echo '<p><strong>' . esc_html__('[Anonympins Bot Mitigation Security Warning]', 'anonympins-bot-mitigation-pow') . '</strong> : ' .
247
+ echo '<p><strong>' . esc_html__('[Anonympins bot mitigation security warning]', 'anonympins-bot-mitigation-pow') . '</strong> : ' .
223
248
  esc_html__('Your website is currently running on unencrypted HTTP. In this mode, modern web browsers disable the native Web Cryptography API (crypto.subtle) for security reasons, forcing a JavaScript fallback simulation that is slower and vulnerable to Man-in-the-Middle (MitM) attacks. We strongly recommend deploying a TLS/SSL certificate and enforcing HTTPS to ensure the cryptographic integrity of Proof-of-Work computations and identity protection.', 'anonympins-bot-mitigation-pow') .
224
249
  '</p>';
225
250
  echo '</div>';
@@ -234,9 +259,9 @@ add_action('admin_notices', function () {
234
259
  : esc_html__('Enforced test mode: suspicion analysis and PoW challenges are actively triggered.', 'anonympins-bot-mitigation-pow');
235
260
 
236
261
  echo '<div class="notice notice-warning is-dismissible">';
237
- echo '<p><strong>' . esc_html__('[Anonympins Bot Mitigation Sandbox Active]', 'anonympins-bot-mitigation-pow') . '</strong> : ' .
238
- esc_html__('Sandbox Mode is currently ENABLED.', 'anonympins-bot-mitigation-pow') . ' ' . esc_html($modeDesc) .
239
- ' <a href="' . esc_url(admin_url('options-general.php?page=anonympins-bot-mitigation#tab-sandbox')) . '">' . esc_html__('Configure Sandbox', 'anonympins-bot-mitigation-pow') . '</a></p>';
262
+ echo '<p><strong>' . esc_html__('[Anonympins bot mitigation sandbox active]', 'anonympins-bot-mitigation-pow') . '</strong> : ' .
263
+ esc_html__('Sandbox mode is currently ENABLED.', 'anonympins-bot-mitigation-pow') . ' ' . esc_html($modeDesc) .
264
+ ' <a href="' . esc_url(admin_url('options-general.php?page=anonympins-bot-mitigation#tab-sandbox')) . '">' . esc_html__('Configure sandbox', 'anonympins-bot-mitigation-pow') . '</a></p>';
240
265
  echo '</div>';
241
266
  }
242
267
  });
@@ -296,6 +321,11 @@ add_action('plugins_loaded', function () use ($fingerprint_security_profiles) {
296
321
  $contextConfig = $configs['frontend'] ?? $fingerprint_security_profiles['frontend'];
297
322
  }
298
323
 
324
+ $savedOptions = get_option('anonympins_security_options', get_option('fingerprint_security_options', []));
325
+ $contextConfig['overrides']['challengeTemplate'] = (is_array($savedOptions) && isset($savedOptions['challenge_template']))
326
+ ? (string)$savedOptions['challenge_template']
327
+ : fingerprint_get_default_challenge_template();
328
+
299
329
  $sandboxConfig = fingerprint_get_sandbox_config();
300
330
  $isSandboxActive = false;
301
331
 
@@ -603,8 +633,8 @@ function fingerprint_rest_sandbox_sse(): void {
603
633
  // =============================================================================
604
634
  add_action('admin_menu', function () {
605
635
  add_options_page(
606
- __('Anonympins Bot Mitigation', 'anonympins-bot-mitigation-pow'),
607
- __('Anonympins Bot Mitigation', 'anonympins-bot-mitigation-pow'),
636
+ __('Anonympins bot mitigation', 'anonympins-bot-mitigation-pow'),
637
+ __('Anonympins bot mitigation', 'anonympins-bot-mitigation-pow'),
608
638
  'manage_options',
609
639
  'anonympins-bot-mitigation',
610
640
  'fingerprint_render_admin_page'
@@ -619,6 +649,9 @@ add_action('admin_enqueue_scripts', function (string $hook) {
619
649
  return;
620
650
  }
621
651
 
652
+ // Enqueue native WordPress CodeMirror editor for HTML template editing
653
+ $editorSettings = wp_enqueue_code_editor(['type' => 'text/html']);
654
+
622
655
  wp_register_script('anonympins-admin-settings', false, [], ANONYMPINS_BOT_MITIGATION_VERSION, true);
623
656
  wp_enqueue_script('anonympins-admin-settings');
624
657
 
@@ -627,8 +660,13 @@ add_action('admin_enqueue_scripts', function (string $hook) {
627
660
  evt.preventDefault();
628
661
  document.querySelectorAll(".fingerprint-tab-content").forEach(function(t) { t.style.display = "none"; });
629
662
  document.querySelectorAll(".nav-tab-wrapper a").forEach(function(n) { n.classList.remove("nav-tab-active"); });
630
- document.getElementById(tabId).style.display = "block";
663
+ var target = document.getElementById(tabId);
664
+ if (target) { target.style.display = "block"; }
631
665
  evt.currentTarget.classList.add("nav-tab-active");
666
+
667
+ if (tabId === "tab-template" && window.fingerprintCodeMirrorInstance) {
668
+ window.fingerprintCodeMirrorInstance.codemirror.refresh();
669
+ }
632
670
  if (window.location.hash !== "#" + tabId && history.pushState) {
633
671
  history.pushState(null, null, "#" + tabId);
634
672
  }
@@ -645,6 +683,16 @@ add_action('admin_enqueue_scripts', function (string $hook) {
645
683
  document.querySelectorAll(".nav-tab-wrapper a").forEach(function(n) { n.classList.remove("nav-tab-active"); });
646
684
  targetContent.style.display = "block";
647
685
  targetLink.classList.add("nav-tab-active");
686
+ if (targetId === "tab-template" && window.fingerprintCodeMirrorInstance) {
687
+ setTimeout(function() { window.fingerprintCodeMirrorInstance.codemirror.refresh(); }, 50);
688
+ }
689
+ }
690
+ }
691
+
692
+ if (window.wp && wp.codeEditor && document.getElementById("challenge_template")) {
693
+ var editorConfig = ' . wp_json_encode($editorSettings) . ';
694
+ if (editorConfig) {
695
+ window.fingerprintCodeMirrorInstance = wp.codeEditor.initialize(document.getElementById("challenge_template"), editorConfig);
648
696
  }
649
697
  }
650
698
  });
@@ -660,9 +708,9 @@ add_action('admin_enqueue_scripts', function (string $hook) {
660
708
  if (sseSource) {
661
709
  sseSource.close();
662
710
  sseSource = null;
663
- statusEl.textContent = ' . wp_json_encode(__('SSE Disconnected', 'anonympins-bot-mitigation-pow')) . ';
711
+ statusEl.textContent = ' . wp_json_encode(__('SSE disconnected', 'anonympins-bot-mitigation-pow')) . ';
664
712
  statusEl.style.color = "#646970";
665
- btnText.textContent = ' . wp_json_encode(__('Start Real-Time SSE Stream', 'anonympins-bot-mitigation-pow')) . ';
713
+ btnText.textContent = ' . wp_json_encode(__('Start real-time SSE stream', 'anonympins-bot-mitigation-pow')) . ';
666
714
  return;
667
715
  }
668
716
 
@@ -671,9 +719,9 @@ add_action('admin_enqueue_scripts', function (string $hook) {
671
719
  sseSource = new EventSource(' . wp_json_encode(rest_url('fingerprint/v1/sandbox/sse')) . ' + "?_wpnonce=" + wpRestNonce);
672
720
 
673
721
  sseSource.onopen = function() {
674
- statusEl.textContent = ' . wp_json_encode(__('SSE Live Connected', 'anonympins-bot-mitigation-pow')) . ';
722
+ statusEl.textContent = ' . wp_json_encode(__('SSE live connected', 'anonympins-bot-mitigation-pow')) . ';
675
723
  statusEl.style.color = "#007017";
676
- btnText.textContent = ' . wp_json_encode(__('Stop Stream', 'anonympins-bot-mitigation-pow')) . ';
724
+ btnText.textContent = ' . wp_json_encode(__('Stop stream', 'anonympins-bot-mitigation-pow')) . ';
677
725
  };
678
726
 
679
727
  sseSource.addEventListener("challenge", function(e) {
@@ -689,7 +737,7 @@ add_action('admin_enqueue_scripts', function (string $hook) {
689
737
  });
690
738
 
691
739
  sseSource.onerror = function() {
692
- statusEl.textContent = ' . wp_json_encode(__('SSE Reconnecting...', 'anonympins-bot-mitigation-pow')) . ';
740
+ statusEl.textContent = ' . wp_json_encode(__('SSE reconnecting...', 'anonympins-bot-mitigation-pow')) . ';
693
741
  statusEl.style.color = "#d63638";
694
742
  };
695
743
  }
@@ -883,6 +931,27 @@ function fingerprint_render_admin_page(): void {
883
931
  echo '<div class="notice notice-success is-dismissible"><p><strong>' . esc_html__('Prometheus settings updated successfully.', 'anonympins-bot-mitigation-pow') . '</strong></p></div>';
884
932
  }
885
933
 
934
+ if ((isset($_POST['fingerprint_save_template']) || isset($_POST['fingerprint_reset_template'])) && check_admin_referer('fingerprint_template_nonce', 'fingerprint_nonce_template')) {
935
+ $saved = get_option('anonympins_security_options', get_option('fingerprint_security_options', []));
936
+ if (!is_array($saved)) {
937
+ $saved = [];
938
+ }
939
+ if (isset($_POST['fingerprint_reset_template'])) {
940
+ unset($saved['challenge_template']);
941
+ echo '<div class="notice notice-info is-dismissible"><p><strong>' . esc_html__('Template reset to default successfully.', 'anonympins-bot-mitigation-pow') . '</strong></p></div>';
942
+ } else {
943
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Administrator code template editor with script/style placeholders.
944
+ $rawTemplate = isset($_POST['challenge_template']) ? wp_unslash($_POST['challenge_template']) : '';
945
+ if (!current_user_can('unfiltered_html')) {
946
+ $saved['challenge_template'] = wp_kses_post($rawTemplate);
947
+ } else {
948
+ $saved['challenge_template'] = (string)$rawTemplate;
949
+ }
950
+ echo '<div class="notice notice-success is-dismissible"><p><strong>' . esc_html__('Challenge template updated successfully.', 'anonympins-bot-mitigation-pow') . '</strong></p></div>';
951
+ }
952
+ update_option('anonympins_security_options', $saved);
953
+ }
954
+
886
955
  if (isset($_POST['fingerprint_clear_store']) && check_admin_referer('fingerprint_clear_nonce', 'fingerprint_nonce_clear')) {
887
956
  $store = new WpDbStore();
888
957
  $store->clear();
@@ -892,6 +961,10 @@ function fingerprint_render_admin_page(): void {
892
961
  $sandboxConfig = fingerprint_get_sandbox_config();
893
962
  $effective = fingerprint_get_effective_profiles($fingerprint_security_profiles);
894
963
  $frontendConfig = SecurityProfiles::createSecurityProfile($effective['frontend']['profile'], $effective['frontend']['overrides'] ?? []);
964
+ $savedOptions = get_option('anonympins_security_options', get_option('fingerprint_security_options', []));
965
+ $currentTemplate = (is_array($savedOptions) && !empty($savedOptions['challenge_template']))
966
+ ? (string)$savedOptions['challenge_template']
967
+ : fingerprint_get_default_challenge_template();
895
968
 
896
969
  $store = new WpDbStore();
897
970
  $totalRows = $store->getTotalCount();
@@ -904,17 +977,17 @@ function fingerprint_render_admin_page(): void {
904
977
  $prometheusRaw = MetricsManager::getPrometheusMetrics($frontendConfig);
905
978
  ?>
906
979
  <div class="wrap">
907
- <h1><span class="dashicons dashicons-shield-alt" style="font-size:32px;vertical-align:middle;margin-right:8px;"></span> Anonympins Bot Mitigation with Proof-of-Work</h1>
980
+ <h1><span class="dashicons dashicons-shield-alt" style="font-size:32px;vertical-align:middle;margin-right:8px;"></span> Anonympins bot mitigation with proof-of-work</h1>
908
981
  <p class="description"><?php esc_html_e('Client-side behavioral and cryptographic anti-bot protection without third-party CAPTCHA for WordPress.', 'anonympins-bot-mitigation-pow'); ?></p>
909
982
 
910
983
  <div style="background:#fff;border-left:4px solid #2271b1;padding:12px 18px;margin:18px 0;box-shadow:0 1px 1px rgba(0,0,0,.04);">
911
984
  <p style="margin:4px 0;">
912
985
  <strong><?php esc_html_e('Official documentation reference:', 'anonympins-bot-mitigation-pow'); ?></strong>
913
986
  <a href="https://github.com/anonympins/fingerprint/blob/main/doc/full_options.md" target="_blank" rel="noopener noreferrer" class="button button-secondary" style="margin-left:8px;">
914
- <span class="dashicons dashicons-external" style="vertical-align:middle;"></span> <?php esc_html_e('View Full Configuration Options on GitHub', 'anonympins-bot-mitigation-pow'); ?>
987
+ <span class="dashicons dashicons-external" style="vertical-align:middle;"></span> <?php esc_html_e('View full configuration options on GitHub', 'anonympins-bot-mitigation-pow'); ?>
915
988
  </a>
916
989
  <a href="https://github.com/anonympins/fingerprint" target="_blank" rel="noopener noreferrer" class="button button-secondary" style="margin-left:4px;">
917
- <span class="dashicons dashicons-admin-plugins" style="vertical-align:middle;"></span> <?php esc_html_e('GitHub Repository', 'anonympins-bot-mitigation-pow'); ?>
990
+ <span class="dashicons dashicons-admin-plugins" style="vertical-align:middle;"></span> <?php esc_html_e('GitHub repository', 'anonympins-bot-mitigation-pow'); ?>
918
991
  </a>
919
992
  </p>
920
993
  </div>
@@ -922,7 +995,7 @@ function fingerprint_render_admin_page(): void {
922
995
  <!-- STATISTICS & STATUS DASHBOARD -->
923
996
  <div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(240px, 1fr));gap:16px;margin-bottom:24px;">
924
997
  <div style="background:#fff;padding:16px;border-radius:4px;border:1px solid #ccd0d4;">
925
- <h3 style="margin-top:0;"><?php esc_html_e('HTTPS Status', 'anonympins-bot-mitigation-pow'); ?></h3>
998
+ <h3 style="margin-top:0;"><?php esc_html_e('HTTPS status', 'anonympins-bot-mitigation-pow'); ?></h3>
926
999
  <?php if (is_ssl()): ?>
927
1000
  <p style="color:#007017;font-weight:bold;font-size:16px;">
928
1001
  <span class="dashicons dashicons-yes-alt"></span> <?php esc_html_e('Active (WebCrypto Subtle available)', 'anonympins-bot-mitigation-pow'); ?>
@@ -934,7 +1007,7 @@ function fingerprint_render_admin_page(): void {
934
1007
  <?php endif; ?>
935
1008
  </div>
936
1009
  <div style="background:#fff;padding:16px;border-radius:4px;border:1px solid #ccd0d4;">
937
- <h3 style="margin-top:0;"><?php esc_html_e('SQL Cache ($wpdb)', 'anonympins-bot-mitigation-pow'); ?></h3>
1010
+ <h3 style="margin-top:0;"><?php esc_html_e('SQL cache ($wpdb)', 'anonympins-bot-mitigation-pow'); ?></h3>
938
1011
  <p style="font-size:22px;margin:0;font-weight:600;"><?php echo esc_html((string)$totalRows); ?> <span style="font-size:14px;color:#646970;font-weight:normal;"><?php esc_html_e('keys in database', 'anonympins-bot-mitigation-pow'); ?></span></p>
939
1012
  <small style="color:#8c8f94;"><?php
940
1013
  /* translators: %d: number of expired keys awaiting cron purge */
@@ -942,7 +1015,7 @@ function fingerprint_render_admin_page(): void {
942
1015
  ?></small>
943
1016
  </div>
944
1017
  <div style="background:#fff;padding:16px;border-radius:4px;border:1px solid #ccd0d4;">
945
- <h3 style="margin-top:0;"><?php esc_html_e('Active Profiles', 'anonympins-bot-mitigation-pow'); ?></h3>
1018
+ <h3 style="margin-top:0;"><?php esc_html_e('Active profiles', 'anonympins-bot-mitigation-pow'); ?></h3>
946
1019
  <p style="margin:0;">
947
1020
  <?php esc_html_e('Frontend:', 'anonympins-bot-mitigation-pow'); ?> <strong><?php echo esc_html($effective['frontend']['profile']); ?></strong><br>
948
1021
  <?php esc_html_e('Admin:', 'anonympins-bot-mitigation-pow'); ?> <strong><?php echo esc_html($effective['admin']['profile']); ?></strong><br>
@@ -950,7 +1023,7 @@ function fingerprint_render_admin_page(): void {
950
1023
  </p>
951
1024
  </div>
952
1025
  <div style="background:#fff;padding:16px;border-radius:4px;border:1px solid #ccd0d4;">
953
- <h3 style="margin-top:0;"><?php esc_html_e('Sandbox Mode', 'anonympins-bot-mitigation-pow'); ?></h3>
1026
+ <h3 style="margin-top:0;"><?php esc_html_e('Sandbox mode', 'anonympins-bot-mitigation-pow'); ?></h3>
954
1027
  <?php if ($sandboxConfig['enabled']): ?>
955
1028
  <p style="color:#dba617;font-weight:bold;font-size:16px;margin:0;">
956
1029
  <span class="dashicons dashicons-warning"></span> <?php esc_html_e('Active (Simulation)', 'anonympins-bot-mitigation-pow'); ?>
@@ -967,30 +1040,31 @@ function fingerprint_render_admin_page(): void {
967
1040
 
968
1041
  <!-- NAVIGATION TABS -->
969
1042
  <h2 class="nav-tab-wrapper">
970
- <a href="#tab-settings" class="nav-tab nav-tab-active" onclick="fingerprintSwitchTab(event, 'tab-settings')"><?php esc_html_e('Settings & Profiles', 'anonympins-bot-mitigation-pow'); ?></a>
971
- <a href="#tab-sandbox" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-sandbox')"><?php esc_html_e('Sandbox / Test Mode', 'anonympins-bot-mitigation-pow'); ?></a>
972
- <a href="#tab-metrics" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-metrics')"><?php esc_html_e('Metrics & Weights View', 'anonympins-bot-mitigation-pow'); ?></a>
973
- <a href="#tab-prometheus" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-prometheus')"><?php esc_html_e('Prometheus Stream', 'anonympins-bot-mitigation-pow'); ?></a>
1043
+ <a href="#tab-settings" class="nav-tab nav-tab-active" onclick="fingerprintSwitchTab(event, 'tab-settings')"><?php esc_html_e('Settings & profiles', 'anonympins-bot-mitigation-pow'); ?></a>
1044
+ <a href="#tab-template" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-template')"><?php esc_html_e('Challenge HTML template', 'anonympins-bot-mitigation-pow'); ?></a>
1045
+ <a href="#tab-sandbox" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-sandbox')"><?php esc_html_e('Sandbox / test mode', 'anonympins-bot-mitigation-pow'); ?></a>
1046
+ <a href="#tab-metrics" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-metrics')"><?php esc_html_e('Metrics & weights view', 'anonympins-bot-mitigation-pow'); ?></a>
1047
+ <a href="#tab-prometheus" class="nav-tab" onclick="fingerprintSwitchTab(event, 'tab-prometheus')"><?php esc_html_e('Prometheus stream', 'anonympins-bot-mitigation-pow'); ?></a>
974
1048
  </h2>
975
1049
 
976
1050
  <div id="tab-settings" class="fingerprint-tab-content" style="background:#fff;padding:20px;border:1px solid #ccd0d4;border-top:none;">
977
1051
  <form method="post" action="">
978
1052
  <?php wp_nonce_field('fingerprint_settings_nonce', 'fingerprint_nonce'); ?>
979
- <h3><?php esc_html_e('1. Target Security Profiles', 'anonympins-bot-mitigation-pow'); ?></h3>
1053
+ <h3><?php esc_html_e('1. Target security profiles', 'anonympins-bot-mitigation-pow'); ?></h3>
980
1054
  <table class="form-table">
981
1055
  <tr>
982
- <th scope="row"><label for="frontend_profile"><?php esc_html_e('Visitors & Frontend', 'anonympins-bot-mitigation-pow'); ?></label></th>
1056
+ <th scope="row"><label for="frontend_profile"><?php esc_html_e('Visitors & frontend', 'anonympins-bot-mitigation-pow'); ?></label></th>
983
1057
  <td>
984
1058
  <select name="frontend_profile" id="frontend_profile">
985
1059
  <option value="blog" <?php selected($effective['frontend']['profile'], 'blog'); ?>><?php esc_html_e('Blog (Optimal for content, smooth UX)', 'anonympins-bot-mitigation-pow'); ?></option>
986
1060
  <option value="balanced" <?php selected($effective['frontend']['profile'], 'balanced'); ?>><?php esc_html_e('Balanced (General purpose)', 'anonympins-bot-mitigation-pow'); ?></option>
987
1061
  <option value="strict" <?php selected($effective['frontend']['profile'], 'strict'); ?>><?php esc_html_e('Strict (Maximum protection)', 'anonympins-bot-mitigation-pow'); ?></option>
988
- <option value="ecommerce" <?php selected($effective['frontend']['profile'], 'ecommerce'); ?>><?php esc_html_e('E-commerce (Anti-scraping / scalping)', 'anonympins-bot-mitigation-pow'); ?></option>
1062
+ <option value="ecommerce" <?php selected($effective['frontend']['profile'], 'ecommerce'); ?>><?php esc_html_e('E-commerce (anti-scraping / scalping)', 'anonympins-bot-mitigation-pow'); ?></option>
989
1063
  </select>
990
1064
  </td>
991
1065
  </tr>
992
1066
  <tr>
993
- <th scope="row"><label for="admin_profile"><?php esc_html_e('Administration Area (wp-login / wp-admin)', 'anonympins-bot-mitigation-pow'); ?></label></th>
1067
+ <th scope="row"><label for="admin_profile"><?php esc_html_e('Administration area (wp-login / wp-admin)', 'anonympins-bot-mitigation-pow'); ?></label></th>
994
1068
  <td>
995
1069
  <select name="admin_profile" id="admin_profile">
996
1070
  <option value="strict" <?php selected($effective['admin']['profile'], 'strict'); ?>><?php esc_html_e('Strict (Recommended to secure logins)', 'anonympins-bot-mitigation-pow'); ?></option>
@@ -1009,27 +1083,27 @@ function fingerprint_render_admin_page(): void {
1009
1083
  </tr>
1010
1084
  </table>
1011
1085
  <hr>
1012
- <h3><?php esc_html_e('2. Action Thresholds (Frontend)', 'anonympins-bot-mitigation-pow'); ?></h3>
1086
+ <h3><?php esc_html_e('2. Action thresholds (frontend)', 'anonympins-bot-mitigation-pow'); ?></h3>
1013
1087
  <table class="form-table">
1014
1088
  <tr>
1015
- <th scope="row"><?php esc_html_e('Suspicion Score Thresholds (0 - 100)', 'anonympins-bot-mitigation-pow'); ?></th>
1089
+ <th scope="row"><?php esc_html_e('Suspicion score thresholds (0 - 100)', 'anonympins-bot-mitigation-pow'); ?></th>
1016
1090
  <td>
1017
- <label><?php esc_html_e('Low (Initial challenge):', 'anonympins-bot-mitigation-pow'); ?>
1091
+ <label><?php esc_html_e('Low (initial challenge):', 'anonympins-bot-mitigation-pow'); ?>
1018
1092
  <input type="number" name="frontend_threshold_low" value="<?php echo esc_attr((string)($frontendConfig['thresholds']['low'] ?? 20)); ?>" min="1" max="50" style="width:80px;">
1019
1093
  </label><br><br>
1020
- <label><?php esc_html_e('Medium (Hardened challenge):', 'anonympins-bot-mitigation-pow'); ?>
1094
+ <label><?php esc_html_e('Medium (hardened challenge):', 'anonympins-bot-mitigation-pow'); ?>
1021
1095
  <input type="number" name="frontend_threshold_medium" value="<?php echo esc_attr((string)($frontendConfig['thresholds']['medium'] ?? 45)); ?>" min="10" max="75" style="width:80px;">
1022
1096
  </label><br><br>
1023
- <label><?php esc_html_e('High (Heavy Proof-of-Work):', 'anonympins-bot-mitigation-pow'); ?>
1097
+ <label><?php esc_html_e('High (heavy proof-of-work):', 'anonympins-bot-mitigation-pow'); ?>
1024
1098
  <input type="number" name="frontend_threshold_high" value="<?php echo esc_attr((string)($frontendConfig['thresholds']['high'] ?? 75)); ?>" min="30" max="95" style="width:80px;">
1025
1099
  </label><br><br>
1026
- <label><?php esc_html_e('Block (Immediate 403 Forbidden):', 'anonympins-bot-mitigation-pow'); ?>
1100
+ <label><?php esc_html_e('Block (immediate 403 forbidden):', 'anonympins-bot-mitigation-pow'); ?>
1027
1101
  <input type="number" name="frontend_threshold_block" value="<?php echo esc_attr((string)($frontendConfig['thresholds']['block'] ?? 95)); ?>" min="50" max="100" style="width:80px;">
1028
1102
  </label>
1029
1103
  </td>
1030
1104
  </tr>
1031
1105
  <tr>
1032
- <th scope="row"><?php esc_html_e('Advanced Behaviors', 'anonympins-bot-mitigation-pow'); ?></th>
1106
+ <th scope="row"><?php esc_html_e('Advanced behaviors', 'anonympins-bot-mitigation-pow'); ?></th>
1033
1107
  <td>
1034
1108
  <label>
1035
1109
  <input type="checkbox" name="frontend_challenge_new" value="1" <?php checked(!empty($frontendConfig['challengeNewDevices'])); ?>>
@@ -1046,13 +1120,13 @@ function fingerprint_render_admin_page(): void {
1046
1120
  </td>
1047
1121
  </tr>
1048
1122
  </table>
1049
- <?php submit_button(esc_html__('Save Changes', 'anonympins-bot-mitigation-pow'), 'primary', 'fingerprint_save_settings'); ?>
1123
+ <?php submit_button(esc_html__('Save changes', 'anonympins-bot-mitigation-pow'), 'primary', 'fingerprint_save_settings'); ?>
1050
1124
  </form>
1051
1125
  <hr>
1052
1126
  <form method="post" action="" style="margin-top:16px;">
1053
1127
  <?php wp_nonce_field('fingerprint_clear_nonce', 'fingerprint_nonce_clear'); ?>
1054
1128
  <p>
1055
- <strong><?php esc_html_e('Store Maintenance:', 'anonympins-bot-mitigation-pow'); ?></strong>
1129
+ <strong><?php esc_html_e('Store maintenance:', 'anonympins-bot-mitigation-pow'); ?></strong>
1056
1130
  <button type="submit" name="fingerprint_clear_store" class="button button-secondary" onclick="return confirm('<?php echo esc_js(__('Purge all stored sessions and nonces?', 'anonympins-bot-mitigation-pow')); ?>');">
1057
1131
  <?php esc_html_e('Clear SQL cache table ($wpdb)', 'anonympins-bot-mitigation-pow'); ?>
1058
1132
  </button>
@@ -1060,26 +1134,90 @@ function fingerprint_render_admin_page(): void {
1060
1134
  </form>
1061
1135
  </div>
1062
1136
 
1137
+ <div id="tab-template" class="fingerprint-tab-content" style="display:none;background:#fff;padding:20px;border:1px solid #ccd0d4;border-top:none;">
1138
+ <h3><?php esc_html_e('Challenge HTML template editor', 'anonympins-bot-mitigation-pow'); ?></h3>
1139
+ <p class="description">
1140
+ <?php esc_html_e('Customize the HTML markup presented to challenged visitors. Leave empty or reset to use the built-in responsive default template.', 'anonympins-bot-mitigation-pow'); ?>
1141
+ </p>
1142
+
1143
+ <div style="background:#f0f6fc;border-left:4px solid #2271b1;padding:12px 16px;margin:16px 0;">
1144
+ <h4 style="margin:0 0 8px 0;"><?php esc_html_e('Available template placeholders', 'anonympins-bot-mitigation-pow'); ?></h4>
1145
+ <table class="widefat striped" style="background:#fff;font-size:12px;">
1146
+ <thead>
1147
+ <tr>
1148
+ <th style="width:200px;"><?php esc_html_e('Placeholder', 'anonympins-bot-mitigation-pow'); ?></th>
1149
+ <th><?php esc_html_e('Description & content injected', 'anonympins-bot-mitigation-pow'); ?></th>
1150
+ </tr>
1151
+ </thead>
1152
+ <tbody>
1153
+ <tr>
1154
+ <td><code>{{TITLE}}</code></td>
1155
+ <td><?php esc_html_e('Challenge page title (e.g., "Security verification")', 'anonympins-bot-mitigation-pow'); ?></td>
1156
+ </tr>
1157
+ <tr>
1158
+ <td><code>{{MESSAGE}}</code></td>
1159
+ <td><?php esc_html_e('Human-readable instruction or explanation message', 'anonympins-bot-mitigation-pow'); ?></td>
1160
+ </tr>
1161
+ <tr>
1162
+ <td><code>{{NONCE}}</code></td>
1163
+ <td><?php esc_html_e('Unique cryptographic challenge nonce generated by the server', 'anonympins-bot-mitigation-pow'); ?></td>
1164
+ </tr>
1165
+ <tr>
1166
+ <td><code>{{DIFFICULTY}}</code></td>
1167
+ <td><?php esc_html_e('Target computational difficulty complexity number', 'anonympins-bot-mitigation-pow'); ?></td>
1168
+ </tr>
1169
+ <tr>
1170
+ <td><code>{{ALGORITHM}}</code></td>
1171
+ <td><?php esc_html_e('Selected hashing algorithm (e.g., "SHA-256")', 'anonympins-bot-mitigation-pow'); ?></td>
1172
+ </tr>
1173
+ <tr>
1174
+ <td><code>{{FORM_ACTION}}</code></td>
1175
+ <td><?php esc_html_e('Target POST URI destination where the PoW result must be submitted', 'anonympins-bot-mitigation-pow'); ?></td>
1176
+ </tr>
1177
+ <tr>
1178
+ <td><code>{{SOLVER_SCRIPT}}</code></td>
1179
+ <td><?php esc_html_e('Mandatory: inlined WebAssembly/WebWorker solver script block required for verification', 'anonympins-bot-mitigation-pow'); ?></td>
1180
+ </tr>
1181
+ <tr>
1182
+ <td><code>{{CUSTOM_CSS}}</code></td>
1183
+ <td><?php esc_html_e('Optional: default reset styling and challenge animations', 'anonympins-bot-mitigation-pow'); ?></td>
1184
+ </tr>
1185
+ </tbody>
1186
+ </table>
1187
+ </div>
1188
+
1189
+ <form method="post" action="">
1190
+ <?php wp_nonce_field('fingerprint_template_nonce', 'fingerprint_nonce_template'); ?>
1191
+ <p>
1192
+ <textarea name="challenge_template" id="challenge_template" rows="18" style="width:100%;font-family:monospace;"><?php echo esc_textarea($currentTemplate); ?></textarea>
1193
+ </p>
1194
+ <p style="display:flex;gap:10px;">
1195
+ <?php submit_button(esc_html__('Save template', 'anonympins-bot-mitigation-pow'), 'primary', 'fingerprint_save_template', false); ?>
1196
+ <?php submit_button(esc_html__('Reset to default template', 'anonympins-bot-mitigation-pow'), 'secondary', 'fingerprint_reset_template', false, ['onclick' => "return confirm('" . esc_js(__('Reset challenge template to default?', 'anonympins-bot-mitigation-pow')) . "');"]); ?>
1197
+ </p>
1198
+ </form>
1199
+ </div>
1200
+
1063
1201
  <div id="tab-sandbox" class="fingerprint-tab-content" style="display:none;background:#fff;padding:20px;border:1px solid #ccd0d4;border-top:none;">
1064
- <h3><?php esc_html_e('Sandbox Mode & Dry-Run Configuration', 'anonympins-bot-mitigation-pow'); ?></h3>
1202
+ <h3><?php esc_html_e('Sandbox mode & dry-run configuration', 'anonympins-bot-mitigation-pow'); ?></h3>
1065
1203
  <form method="post" action="">
1066
1204
  <?php wp_nonce_field('fingerprint_sandbox_nonce', 'fingerprint_nonce_sandbox'); ?>
1067
1205
  <table class="form-table">
1068
1206
  <tr>
1069
- <th scope="row"><?php esc_html_e('Sandbox Activation', 'anonympins-bot-mitigation-pow'); ?></th>
1207
+ <th scope="row"><?php esc_html_e('Sandbox activation', 'anonympins-bot-mitigation-pow'); ?></th>
1070
1208
  <td>
1071
1209
  <label>
1072
1210
  <input type="checkbox" name="sandbox_enabled" value="1" <?php checked($sandboxConfig['enabled']); ?>>
1073
- <strong><?php esc_html_e('Enable Sandbox Mode', 'anonympins-bot-mitigation-pow'); ?></strong>
1211
+ <strong><?php esc_html_e('Enable sandbox mode', 'anonympins-bot-mitigation-pow'); ?></strong>
1074
1212
  </label>
1075
1213
  </td>
1076
1214
  </tr>
1077
1215
  <tr>
1078
- <th scope="row"><?php esc_html_e('Behavior & Enforcement', 'anonympins-bot-mitigation-pow'); ?></th>
1216
+ <th scope="row"><?php esc_html_e('Behavior & enforcement', 'anonympins-bot-mitigation-pow'); ?></th>
1079
1217
  <td>
1080
1218
  <label>
1081
1219
  <input type="checkbox" name="sandbox_audit_only" value="1" <?php checked($sandboxConfig['audit_only']); ?>>
1082
- <strong><?php esc_html_e('Audit Only / Dry-Run (Never block or challenge visitors)', 'anonympins-bot-mitigation-pow'); ?></strong>
1220
+ <strong><?php esc_html_e('Audit only / dry-run (never block or challenge visitors)', 'anonympins-bot-mitigation-pow'); ?></strong>
1083
1221
  </label><br><br>
1084
1222
  <label>
1085
1223
  <input type="checkbox" name="sandbox_add_headers" value="1" <?php checked($sandboxConfig['add_headers']); ?>>
@@ -1092,7 +1230,7 @@ function fingerprint_render_admin_page(): void {
1092
1230
  </td>
1093
1231
  </tr>
1094
1232
  <tr>
1095
- <th scope="row"><label for="sandbox_ip_filter"><?php esc_html_e('Test IP Whitelist Filter', 'anonympins-bot-mitigation-pow'); ?></label></th>
1233
+ <th scope="row"><label for="sandbox_ip_filter"><?php esc_html_e('Test IP whitelist filter', 'anonympins-bot-mitigation-pow'); ?></label></th>
1096
1234
  <td>
1097
1235
  <?php
1098
1236
  // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
@@ -1107,32 +1245,32 @@ function fingerprint_render_admin_page(): void {
1107
1245
  </td>
1108
1246
  </tr>
1109
1247
  </table>
1110
- <?php submit_button(esc_html__('Save Sandbox Settings', 'anonympins-bot-mitigation-pow'), 'primary', 'fingerprint_save_sandbox'); ?>
1248
+ <?php submit_button(esc_html__('Save sandbox settings', 'anonympins-bot-mitigation-pow'), 'primary', 'fingerprint_save_sandbox'); ?>
1111
1249
  </form>
1112
1250
  <hr>
1113
1251
  <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
1114
- <h3 style="margin:0;"><span class="dashicons dashicons-shield" style="vertical-align:text-bottom;"></span> <?php esc_html_e('Live Challenged Visitors & Suspicion Monitor', 'anonympins-bot-mitigation-pow'); ?></h3>
1252
+ <h3 style="margin:0;"><span class="dashicons dashicons-shield" style="vertical-align:text-bottom;"></span> <?php esc_html_e('Live challenged visitors & suspicion monitor', 'anonympins-bot-mitigation-pow'); ?></h3>
1115
1253
  <div>
1116
- <span style="font-weight:600;color:#646970;"><?php esc_html_e('Recent Challenges:', 'anonympins-bot-mitigation-pow'); ?></span>
1254
+ <span style="font-weight:600;color:#646970;"><?php esc_html_e('Recent challenges:', 'anonympins-bot-mitigation-pow'); ?></span>
1117
1255
  <span id="live-challenges-count" style="display:inline-block;padding:2px 8px;background:#2271b1;color:#fff;border-radius:10px;font-weight:bold;font-size:12px;">0</span>
1118
1256
  </div>
1119
1257
  </div>
1120
1258
  <div style="background:#f6f7f7;padding:16px;border:1px solid #c3c4c7;border-radius:4px;margin-bottom:15px;">
1121
1259
  <div style="display:flex;gap:12px;align-items:center;margin-bottom:12px;flex-wrap:wrap;">
1122
1260
  <button type="button" class="button button-primary" id="btn-toggle-sse" onclick="fingerprintToggleSSE();">
1123
- <span class="dashicons dashicons-controls-play" style="vertical-align:middle;"></span> <span id="sse-btn-text"><?php esc_html_e('Start Real-Time SSE Stream', 'anonympins-bot-mitigation-pow'); ?></span>
1261
+ <span class="dashicons dashicons-controls-play" style="vertical-align:middle;"></span> <span id="sse-btn-text"><?php esc_html_e('Start real-time SSE stream', 'anonympins-bot-mitigation-pow'); ?></span>
1124
1262
  </button>
1125
1263
  <button type="button" class="button button-secondary" onclick="fingerprintFetchTelemetry();">
1126
- <span class="dashicons dashicons-update" style="vertical-align:middle;"></span> <?php esc_html_e('Poll Now (REST)', 'anonympins-bot-mitigation-pow'); ?>
1264
+ <span class="dashicons dashicons-update" style="vertical-align:middle;"></span> <?php esc_html_e('Poll now (REST)', 'anonympins-bot-mitigation-pow'); ?>
1127
1265
  </button>
1128
1266
  <button type="button" class="button button-secondary" onclick="fingerprintClearFeed();">
1129
- <span class="dashicons dashicons-trash" style="vertical-align:middle;"></span> <?php esc_html_e('Clear Feed', 'anonympins-bot-mitigation-pow'); ?>
1267
+ <span class="dashicons dashicons-trash" style="vertical-align:middle;"></span> <?php esc_html_e('Clear feed', 'anonympins-bot-mitigation-pow'); ?>
1130
1268
  </button>
1131
1269
  <span id="sse-connection-status" style="font-weight:bold;color:#646970;"></span>
1132
1270
  </div>
1133
1271
  <div style="display:grid;grid-template-columns: 1.4fr 1fr;gap:16px;">
1134
1272
  <div style="background:#fff;padding:12px;border:1px solid #dcdcde;border-radius:4px;overflow-x:auto;">
1135
- <h4 style="margin:0 0 8px 0;"><?php esc_html_e('Challenged Visitors Stream', 'anonympins-bot-mitigation-pow'); ?></h4>
1273
+ <h4 style="margin:0 0 8px 0;"><?php esc_html_e('Challenged visitors stream', 'anonympins-bot-mitigation-pow'); ?></h4>
1136
1274
  <table class="wp-list-table widefat fixed striped" style="font-size:12px;">
1137
1275
  <thead>
1138
1276
  <tr>
@@ -1151,7 +1289,7 @@ function fingerprint_render_admin_page(): void {
1151
1289
  </div>
1152
1290
  <div style="background:#fff;padding:14px;border:1px solid #dcdcde;border-radius:4px;">
1153
1291
  <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px;">
1154
- <h4 style="margin:0;"><?php esc_html_e('Inspection & Suspicion Vector', 'anonympins-bot-mitigation-pow'); ?></h4>
1292
+ <h4 style="margin:0;"><?php esc_html_e('Inspection & suspicion vector', 'anonympins-bot-mitigation-pow'); ?></h4>
1155
1293
  <div id="live-score-val" style="font-size:28px;font-weight:bold;color:#2271b1;line-height:1;">--</div>
1156
1294
  </div>
1157
1295
  <div id="live-score-sub" style="font-size:12px;color:#646970;background:#f6f7f7;padding:8px;border-radius:3px;margin-bottom:10px;">
@@ -1166,15 +1304,15 @@ function fingerprint_render_admin_page(): void {
1166
1304
  </div>
1167
1305
 
1168
1306
  <div id="tab-metrics" class="fingerprint-tab-content" style="display:none;background:#fff;padding:20px;border:1px solid #ccd0d4;border-top:none;">
1169
- <h3><?php esc_html_e('Behavioral & Transport Indicator Weights', 'anonympins-bot-mitigation-pow'); ?></h3>
1307
+ <h3><?php esc_html_e('Behavioral & transport indicator weights', 'anonympins-bot-mitigation-pow'); ?></h3>
1170
1308
  <form method="post" action="">
1171
1309
  <?php wp_nonce_field('fingerprint_settings_nonce', 'fingerprint_nonce'); ?>
1172
1310
  <table class="wp-list-table widefat fixed striped">
1173
1311
  <thead>
1174
1312
  <tr>
1175
- <th style="width:280px;"><?php esc_html_e('Indicator / Metric', 'anonympins-bot-mitigation-pow'); ?></th>
1176
- <th style="width:120px;"><?php esc_html_e('Current Weight', 'anonympins-bot-mitigation-pow'); ?></th>
1177
- <th><?php esc_html_e('Description & Detection Role', 'anonympins-bot-mitigation-pow'); ?></th>
1313
+ <th style="width:280px;"><?php esc_html_e('Indicator / metric', 'anonympins-bot-mitigation-pow'); ?></th>
1314
+ <th style="width:120px;"><?php esc_html_e('Current weight', 'anonympins-bot-mitigation-pow'); ?></th>
1315
+ <th><?php esc_html_e('Description & detection role', 'anonympins-bot-mitigation-pow'); ?></th>
1178
1316
  </tr>
1179
1317
  </thead>
1180
1318
  <tbody>
@@ -1188,18 +1326,18 @@ function fingerprint_render_admin_page(): void {
1188
1326
  </tbody>
1189
1327
  </table>
1190
1328
  <p style="margin-top:16px;">
1191
- <?php submit_button(esc_html__('Update Metric Weights', 'anonympins-bot-mitigation-pow'), 'primary', 'fingerprint_save_settings', false); ?>
1329
+ <?php submit_button(esc_html__('Update metric weights', 'anonympins-bot-mitigation-pow'), 'primary', 'fingerprint_save_settings', false); ?>
1192
1330
  </p>
1193
1331
  </form>
1194
1332
  </div>
1195
1333
 
1196
1334
  <div id="tab-prometheus" class="fingerprint-tab-content" style="display:none;background:#fff;padding:20px;border:1px solid #ccd0d4;border-top:none;">
1197
- <h3><?php esc_html_e('Real-Time Prometheus Metrics', 'anonympins-bot-mitigation-pow'); ?></h3>
1335
+ <h3><?php esc_html_e('Real-time prometheus metrics', 'anonympins-bot-mitigation-pow'); ?></h3>
1198
1336
  <form method="post" action="" style="margin-bottom:20px;">
1199
1337
  <?php wp_nonce_field('fingerprint_prometheus_nonce', 'fingerprint_nonce_prometheus'); ?>
1200
1338
  <table class="form-table">
1201
1339
  <tr>
1202
- <th scope="row"><label for="metrics_endpoint"><?php esc_html_e('Metrics Endpoint Path', 'anonympins-bot-mitigation-pow'); ?></label></th>
1340
+ <th scope="row"><label for="metrics_endpoint"><?php esc_html_e('Metrics endpoint path', 'anonympins-bot-mitigation-pow'); ?></label></th>
1203
1341
  <td>
1204
1342
  <input type="text" name="metrics_endpoint" id="metrics_endpoint" value="<?php echo esc_attr(fingerprint_get_metrics_endpoint()); ?>" class="regular-text" placeholder="/metrics">
1205
1343
  <p class="description">
@@ -1213,7 +1351,7 @@ function fingerprint_render_admin_page(): void {
1213
1351
  </td>
1214
1352
  </tr>
1215
1353
  </table>
1216
- <?php submit_button(esc_html__('Save Prometheus Settings', 'anonympins-bot-mitigation-pow'), 'primary', 'fingerprint_save_prometheus'); ?>
1354
+ <?php submit_button(esc_html__('Save prometheus settings', 'anonympins-bot-mitigation-pow'), 'primary', 'fingerprint_save_prometheus'); ?>
1217
1355
  </form>
1218
1356
  <textarea readonly style="width:100%;height:380px;font-family:monospace;background:#f6f7f7;padding:12px;"><?php echo esc_textarea($prometheusRaw); ?></textarea>
1219
1357
  </div>
@@ -1,6 +1,6 @@
1
1
  msgid ""
2
2
  msgstr ""
3
- "Project-Id-Version: Anonympins Bot Mitigation with Proof-of-Work 0.8.1\n"
3
+ "Project-Id-Version: Anonympins Bot Mitigation with Proof-of-Work 0.8.2\n"
4
4
  "Report-Msgid-Bugs-To: https://github.com/anonympins/fingerprint/issues\n"
5
5
  "POT-Creation-Date: 2026-09-24 12:00+0000\n"
6
6
  "PO-Revision-Date: 2026-09-24 12:00+0000\n"
@@ -1,6 +1,6 @@
1
1
  msgid ""
2
2
  msgstr ""
3
- "Project-Id-Version: Fingerprint Anti-Bot 0.8.1\n"
3
+ "Project-Id-Version: Fingerprint Anti-Bot 0.8.2\n"
4
4
  "Report-Msgid-Bugs-To: https://github.com/anonympins/fingerprint/issues\n"
5
5
  "POT-Creation-Date: 2026-09-24 12:00+0000\n"
6
6
  "PO-Revision-Date: 2026-09-24 12:00+0000\n"
@@ -1,6 +1,6 @@
1
1
  msgid ""
2
2
  msgstr ""
3
- "Project-Id-Version: Fingerprint Anti-Bot 0.8.1\n"
3
+ "Project-Id-Version: Fingerprint Anti-Bot 0.8.2\n"
4
4
  "Report-Msgid-Bugs-To: https://github.com/anonympins/fingerprint/issues\n"
5
5
  "POT-Creation-Date: 2026-09-24 12:00+0000\n"
6
6
  "PO-Revision-Date: 2026-09-24 12:00+0000\n"