AILottoEngine / lotto_predictor.py
relvistcb's picture
Upload 8 files
c791fed verified
Raw
History Blame Contribute Delete
467 kB
#!/usr/bin/env python3
"""
LOTTO PREDICTOR V5.3 ULTRA - GOD MODE
Upgrades vs V5.2:
- New GOD-MODE style: "top_cluster"
* Explicitly packs the top 3 highest-score numbers (not banned)
into one hyper-focused combo, then fills the rest.
- Gimme5-specific tuning:
* Short-window ML weights increased for Gimme5
* Agent weights adjusted to favor recency / hot/cold / clusters more
for Gimme5, while other games keep the older balanced mix.
- V5.3 ULTRA layer:
* Regime & trend-aware adjustment (low/flat/high volatility, high_run/low_run)
* Low-zone boost + cold-burst correction
* Anti-lock usage limiter across sets + coverage optimizer
* Mega Millions specific mid/high-band refinements + MM neighbor-chaser
* Lotto America specific main-range tweaks + neighbor-chaser
* Megabucks specific main-range tweaks (mid/high band support, soften 1–3)
* Powerball specific main-range tweaks (core band support, soften extremes)
* Lucky for Life specific main-range tweaks + neighbor-chaser for mids
* Gimme 5 neighbor-chaser with micro-boost around recent hot core numbers
* Mega Millions legacy Megaball 25→1–24 remap so all history fits MB 1–24
* Enhanced star/bonus picker (V5.3.1) with low-zone + cold-burst logic
Features:
- Multi-game, multi-agent, multi-window prediction engine
- Games supported:
* gimme5 (Gimme 5)
* la (Lotto America)
* mb (Megabucks)
* mm (Mega Millions)
* pb (Powerball)
* l4l (Lucky for Life)
- Multi-window ML:
* Short (20 draws), Medium (80 draws), Long (400 draws or all)
- Agents per number:
* ML agent (RF + ET + GB + XGB + MLP ensemble)
* Hot/Cold frequency agent
* Bayesian frequency agent
* Recency agent
* RL-style "good draw" agent
* Pattern agent (sum/odd-even/high-low/range)
* Cluster compression agent (recent density bands)
* Drift agent (low/high sum shifts)
* Parity drift agent (odd/even imbalance)
- Combination search:
* GOD-MODE Monte Carlo over agent scores + pattern scoring
* LAST-4 repeater ban rule (YOUR CUSTOM RULE):
- If a number appears in EACH of the last 4 consecutive draws,
it is banned from prediction. (We do NOT ban all numbers
that simply appeared in the last 4 once.)
* Generates multiple GOD MODE combos with different pattern styles:
- top_cluster (hyper-focused, forced top-3 core)
- balanced
- low_cluster
- high_cluster
- tight_cluster
- wide_spread
- API:
* predict_for_game_v3(csv_path, game_key, run_backtest=False)
* predict_for_game(csv_path, game_key, run_backtest=False)
* generate_wheel_numbers(...)
* get_wheel_for_game(...)
* get_hot_cold_analysis(...)
* load_and_prepare_data(...)
"""
from __future__ import annotations
import json
import random
from collections import Counter
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, List, Optional, Tuple
import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings("ignore")
# =============================================================================
# PATCH PACK (toggleable) — Deep-Low Injection / Tight Relax / Mid-Carry / Wildcard
# UI can override via PATCH_UI_FLAGS from app.py before calling predictions.
# =============================================================================
PATCH_UI_FLAGS = {
"enable_streak_guard": False, # NEW: optional streak guard (OFF by default)
"streak_guard_max": 3, # allow up to 3 consecutive appearances
"streak_guard_penalty_factor": 0.55, # when a number is on a 3-draw streak, downweight it
# Master toggles (safe defaults)
"deep_low_patch": True, # Force at least one deep-low number into a target set
"tight_relax_patch": True, # Relax over-compressed tight_cluster
"mid_carry_patch": True, # Promote multi-set repeaters into strike pool (vote buckets)
"wildcard_strike": True, # Add 1 wildcard profile strike ticket (no bonus touched)
"la_upper_tail_escape": True, # LA-only: add/replace 1 upper-tail hedge set
"enable_pb_consec_guard": True, # PB-only: block 3+ consecutive main numbers (OFF by default)
"pb_consec_guard_run": 3, # consecutive run length to block when enabled
}
def _patch_game_deep_low_range(cfg: "GameConfig") -> Tuple[int, int]:
"""Return (low_min, low_max) per game."""
name = (getattr(cfg, "name", "") or "").lower()
# Gimme5: 1–35
if "gimme" in name:
return (1, 7)
# Megabucks (Tri-State): 1–41 (+ megaball handled elsewhere)
if "mega" in name and "buck" in name:
return (1, 6)
# Lucky for Life: 1–48 (+ lucky ball handled elsewhere)
if "lucky for life" in name or "l4l" in name:
return (1, 8)
# Mega Millions: 1–70 (+ megaball 1–24 handled elsewhere)
if "mega millions" in name or "mm" == name.strip():
return (1, 10)
# Fallback: first 7 numbers of main range
return (int(getattr(cfg, "main_min", 1)), min(int(getattr(cfg, "main_min", 1)) + 6, int(getattr(cfg, "main_max", 99))))
def _patch_best_candidate_in_range(final_scores: Dict[int, float], allowed: set, banned: set, existing: set, rmin: int, rmax: int) -> Optional[int]:
cands = [n for n in range(rmin, rmax + 1) if n in allowed and n not in banned and n not in existing]
if not cands:
return None
cands.sort(key=lambda n: float(final_scores.get(int(n), 0.0)), reverse=True)
return int(cands[0])
def _patch_deep_low_inject_into_set(nums: List[int], final_scores: Dict[int, float], allowed: set, banned: set, rmin: int, rmax: int) -> List[int]:
"""Ensure one number from [rmin,rmax] exists by replacing the weakest-scored number."""
nums = sorted({int(x) for x in nums})
if any(rmin <= n <= rmax for n in nums):
return nums
pick = _patch_best_candidate_in_range(final_scores, allowed, banned, set(nums), rmin, rmax)
if pick is None:
return nums
# Replace weakest scored number (prefer highest if tie)
weakest = sorted(nums, key=lambda n: (float(final_scores.get(int(n), 0.0)), n))[0]
out = [n for n in nums if n != weakest]
out.append(int(pick))
out = sorted(set(out))
# If uniqueness dropped (rare), fill with best overall
if len(out) < len(nums):
pool = [n for n in allowed if n not in banned and n not in set(out)]
pool.sort(key=lambda n: float(final_scores.get(int(n), 0.0)), reverse=True)
for n in pool:
out.append(int(n))
out = sorted(set(out))
if len(out) == len(nums):
break
return out[: len(nums)]
def _patch_relax_tight_cluster(nums: List[int], final_scores: Dict[int, float], allowed: set, banned: set, max_gap: int = 9, max_same_decade: int = 3) -> List[int]:
"""If tight set is too compressed or too decade-heavy, swap one number to widen distribution."""
nums = sorted({int(x) for x in nums})
if len(nums) < 2:
return nums
gaps = [nums[i+1] - nums[i] for i in range(len(nums)-1)]
# decade counts
decades = {}
for n in nums:
d = n // 10
decades[d] = decades.get(d, 0) + 1
if (max(gaps) <= max_gap) and (max(decades.values()) <= max_same_decade):
return nums
# Drop candidate: either from overloaded decade, else from endpoint of largest gap
drop = None
overloaded = [d for d,c in decades.items() if c > max_same_decade]
if overloaded:
od = overloaded[0]
cand = [n for n in nums if (n//10)==od]
drop = cand[-1]
else:
i = max(range(len(nums)-1), key=lambda k: nums[k+1]-nums[k])
drop = nums[i] if float(final_scores.get(int(nums[i]), 0.0)) <= float(final_scores.get(int(nums[i+1]), 0.0)) else nums[i+1]
existing = set(nums)
existing.discard(drop)
pool = [n for n in allowed if n not in banned and n not in existing]
pool.sort(key=lambda n: float(final_scores.get(int(n), 0.0)), reverse=True)
for cand in pool:
out = sorted(set(existing | {int(cand)}))
if len(out) != len(nums):
continue
gaps2 = [out[i+1]-out[i] for i in range(len(out)-1)]
decades2 = {}
for n in out:
d = n // 10
decades2[d] = decades2.get(d, 0) + 1
if (max(gaps2) <= max_gap) and (max(decades2.values()) <= max_same_decade):
return out
# If we can't fully satisfy, return best-effort swap
if pool:
return sorted(set(existing | {int(pool[0])}))
return nums
def _patch_make_wildcard_profile_ticket(god_sets: List[Dict[str, object]], final_scores: Dict[int, float], allowed: set, banned: set, cfg: "GameConfig") -> Optional[List[int]]:
"""
Wildcard profile ticket:
1 deep-low + 2 mid + 2 upper (main numbers only)
Uses favored numbers from god_sets first, then score-based fallback.
"""
main_n = int(len(cfg.main_cols))
if main_n != 5:
return None # this profile is tuned for 5-number games
low_min, low_max = _patch_game_deep_low_range(cfg)
mid_min, mid_max = (low_max + 1, min(low_max + 15, int(cfg.main_max)))
up_min, up_max = (mid_max + 1, int(cfg.main_max))
favored = []
for s in god_sets:
favored.extend([int(x) for x in (s.get("numbers", []) or [])])
favored = sorted(set(favored))
def pick_k(lo: int, hi: int, k: int, used: set) -> List[int]:
pref = [n for n in favored if lo <= n <= hi and n in allowed and n not in banned and n not in used]
pref.sort(key=lambda n: float(final_scores.get(int(n), 0.0)), reverse=True)
out = []
for n in pref:
out.append(int(n)); used.add(int(n))
if len(out) == k:
return out
# fallback: score-based from full range
pool = [n for n in range(lo, hi+1) if n in allowed and n not in banned and n not in used]
pool.sort(key=lambda n: float(final_scores.get(int(n), 0.0)), reverse=True)
for n in pool:
out.append(int(n)); used.add(int(n))
if len(out) == k:
return out
return []
used = set(banned)
ticket = []
ticket += pick_k(low_min, low_max, 1, used)
ticket += pick_k(mid_min, mid_max, 2, used)
ticket += pick_k(up_min, up_max, 2, used)
ticket = sorted(set(ticket))
return ticket if len(ticket) == 5 else None
# ============================================================
# JSON encoder for numpy types
# ============================================================
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (np.integer, np.int64)):
return int(obj)
if isinstance(obj, (np.floating, np.float64)):
return float(obj)
if isinstance(obj, np.ndarray):
return obj.tolist()
return super().default(obj)
# ============================================================
# Game configuration
# ============================================================
@dataclass
class GameConfig:
name: str
csv_date_col: str
main_cols: List[str]
star_col: Optional[str]
main_min: int
main_max: int
star_min: Optional[int] = None
star_max: Optional[int] = None
sum_min: int = 0
sum_max: int = 1000
clean_func: Optional[str] = None
draw_frequency: str = "Unknown" # used by engine/app
GAME_CONFIGS: Dict[str, GameConfig] = {
"gimme5": GameConfig(
name="Gimme 5",
csv_date_col="Date",
main_cols=["1", "2", "3", "4", "5"],
star_col=None,
main_min=1,
main_max=39,
sum_min=40,
sum_max=160,
draw_frequency="5x/week",
),
"la": GameConfig(
name="Lotto America",
csv_date_col="DrawDate",
main_cols=["1", "2", "3", "4", "5"],
star_col="SB",
main_min=1,
main_max=52,
star_min=1,
star_max=10,
sum_min=70,
sum_max=210,
draw_frequency="3x/week",
),
"mb": GameConfig(
name="Megabucks",
csv_date_col="Date",
main_cols=["1", "2", "3", "4", "5"],
star_col="Megaball",
main_min=1,
main_max=41,
star_min=1,
star_max=6,
sum_min=45,
sum_max=165,
draw_frequency="3x/week",
),
"mm": GameConfig(
name="Mega Millions",
csv_date_col="Date",
main_cols=["1", "2", "3", "4", "5"],
star_col="MB",
main_min=1,
main_max=70,
star_min=1,
star_max=24, # modern format (Megaball 1–24, legacy 25 remapped below)
sum_min=75,
sum_max=280,
draw_frequency="2x/week",
),
"pb": GameConfig(
name="Powerball",
csv_date_col="DrawDate",
main_cols=["1", "2", "3", "4", "5"],
star_col="PB",
main_min=1,
main_max=69,
star_min=1,
star_max=26,
sum_min=65,
sum_max=265,
clean_func="clean_powerball_df",
draw_frequency="3x/week",
),
"l4l": GameConfig(
name="Lucky for Life",
csv_date_col="Draw Date",
main_cols=["Ball 1", "Ball 2", "Ball 3", "Ball 4", "Ball 5"],
star_col="Lucky Ball",
main_min=1,
main_max=48,
star_min=1,
star_max=18,
sum_min=60,
sum_max=200,
draw_frequency="Daily",
),
}
# ============================================================
# Cleaning / Date / Recency helpers
# ============================================================
def clean_powerball_df(raw_df: pd.DataFrame) -> pd.DataFrame:
"""
Example cleanup for Powerball: drop Double Play / malformed rows.
Adapt if your PB CSV has extra columns.
"""
df = raw_df.copy()
if "DrawDate" in df.columns:
mask = ~df["DrawDate"].astype(str).str.contains("Double Play", na=False)
df = df[mask]
return df.reset_index(drop=True)
def _ensure_datetime(df: pd.DataFrame, date_col: str) -> pd.DataFrame:
df = df.copy()
df[date_col] = pd.to_datetime(df[date_col], errors="coerce")
invalid = df[date_col].isna().sum()
if invalid > 0:
df = df.dropna(subset=[date_col])
df = df.sort_values(date_col).reset_index(drop=True)
df["Date"] = pd.to_datetime(df[date_col], errors="coerce")
df["DayOfWeek"] = df["Date"].dt.dayofweek
df["Month"] = df["Date"].dt.month
df["Year"] = df["Date"].dt.year
df["DayOfYear"] = df["Date"].dt.dayofyear
return df
def _limit_history(df: pd.DataFrame, max_rows: int) -> pd.DataFrame:
if len(df) > max_rows:
return df.tail(max_rows).reset_index(drop=True)
return df.reset_index(drop=True)
# ============================================================
# Auto window selection (per-game) + dynamic shrink/expand (volatility)
# Silent by default (no UI text)
# ============================================================
def _detect_game_key(cfg: "GameConfig") -> str:
name_l = (getattr(cfg, "name", "") or "").lower()
main_max = int(getattr(cfg, "main_max", 0) or 0)
if "gimme" in name_l or main_max == 39:
return "gimme5"
if "megabucks" in name_l or main_max == 45:
return "mb"
if "lotto america" in name_l or main_max == 52:
return "la"
if "lucky for life" in name_l or main_max == 48:
return "l4l"
if "powerball" in name_l or main_max == 69:
return "pb"
if "mega millions" in name_l or main_max == 70:
return "mm"
return "generic"
def _auto_history_window(df: pd.DataFrame, cfg: "GameConfig") -> int:
"""Return the history window (draw count) to use for this run.
- Auto-detects a sensible base window per game.
- Dynamically shrinks/expands based on recent volatility.
"""
gk = _detect_game_key(cfg)
base = {
"gimme5": 50,
"mb": 100,
"la": 120,
"l4l": 150,
"pb": 300,
"mm": 280,
"generic": 120,
}.get(gk, 120)
# hard bounds per game (keep God Mode stable)
bounds = {
"gimme5": (40, 110),
"mb": (60, 180),
"la": (70, 220),
"l4l": (80, 260),
"pb": (180, 450),
"mm": (180, 450),
"generic": (60, 220),
}.get(gk, (60, 220))
# compute volatility on a short lookback
try:
lookback = min(len(df), 30)
recent = df.tail(lookback)
if lookback < 10:
# not enough to estimate; return base (clamped)
return int(max(bounds[0], min(bounds[1], base)))
sums = recent[cfg.main_cols].sum(axis=1)
spans = recent[cfg.main_cols].max(axis=1) - recent[cfg.main_cols].min(axis=1)
sum_mean = float(sums.mean()) if float(sums.mean()) != 0.0 else 1.0
span_mean = float(spans.mean()) if float(spans.mean()) != 0.0 else 1.0
sum_cv = float(sums.std(ddof=0)) / abs(sum_mean)
span_cv = float(spans.std(ddof=0)) / (abs(span_mean) + 1.0)
# tail pressure (helps detect PB/MM high-tail flips)
hi_thr = int(cfg.main_max) - 5
lo_thr = int(cfg.main_min) + 5
tail_hi = float((recent[cfg.main_cols] >= hi_thr).sum(axis=1).mean()) / max(1.0, float(len(cfg.main_cols)))
tail_lo = float((recent[cfg.main_cols] <= lo_thr).sum(axis=1).mean()) / max(1.0, float(len(cfg.main_cols)))
vol = 0.50 * sum_cv + 0.40 * span_cv + 0.10 * (tail_hi + tail_lo)
# map volatility to scaling
if vol >= 0.35:
scale = 0.70
elif vol >= 0.25:
scale = 0.85
elif vol <= 0.10:
scale = 1.30
elif vol <= 0.15:
scale = 1.15
else:
scale = 1.00
win = int(round(base * scale))
win = int(max(bounds[0], min(bounds[1], win)))
return win
except Exception:
return int(max(bounds[0], min(bounds[1], base)))
# ============================================================
# Structural features per draw
# ============================================================
def calculate_structural_features(df: pd.DataFrame, cfg: GameConfig) -> pd.DataFrame:
df = df.copy()
df["sum_total"] = df[cfg.main_cols].sum(axis=1)
df["mean_val"] = df[cfg.main_cols].mean(axis=1)
df["std_val"] = df[cfg.main_cols].std(axis=1)
df["even_count"] = df[cfg.main_cols].apply(
lambda row: sum(1 for v in row if v % 2 == 0), axis=1
)
df["odd_count"] = len(cfg.main_cols) - df["even_count"]
df["range_span"] = df[cfg.main_cols].max(axis=1) - df[cfg.main_cols].min(axis=1)
midpoint = (cfg.main_min + cfg.main_max) / 2.0
df["high_count"] = df[cfg.main_cols].apply(
lambda row: sum(1 for v in row if v > midpoint), axis=1
)
df["low_count"] = len(cfg.main_cols) - df["high_count"]
def count_consecutive(values):
s = sorted(values)
return sum(1 for i in range(len(s) - 1) if s[i + 1] - s[i] == 1)
def avg_gap(values):
s = sorted(values)
gaps = [s[i + 1] - s[i] for i in range(len(s) - 1)]
return float(np.mean(gaps)) if gaps else 0.0
df["consecutive_count"] = df[cfg.main_cols].apply(count_consecutive, axis=1)
df["avg_gap"] = df[cfg.main_cols].apply(avg_gap, axis=1)
return df
def create_frequency_features(
df: pd.DataFrame,
cfg: GameConfig,
windows: List[int] = [20, 80, 400],
) -> Dict[int, Dict[str, float]]:
freq: Dict[int, Dict[str, float]] = {}
for num in range(cfg.main_min, cfg.main_max + 1):
freq[num] = {}
total_hits = (df[cfg.main_cols] == num).sum().sum()
freq[num]["overall_freq"] = total_hits / max(len(df), 1)
for w in windows:
sub = df.tail(w) if len(df) >= w else df
hits = (sub[cfg.main_cols] == num).sum().sum()
freq[num][f"freq_{w}"] = hits / max(len(sub), 1)
last_idx = -1
for i in range(len(df) - 1, -1, -1):
if num in df.iloc[i][cfg.main_cols].values:
last_idx = i
break
if last_idx == -1:
freq[num]["days_since_last"] = float(len(df))
else:
freq[num]["days_since_last"] = float(len(df) - 1 - last_idx)
return freq
# ============================================================
# Multi-window ML ensemble
# ============================================================
try:
from xgboost import XGBClassifier
_HAS_XGB = True
except ImportError:
from sklearn.ensemble import GradientBoostingClassifier as XGBClassifier
_HAS_XGB = False
from sklearn.ensemble import (
RandomForestClassifier,
ExtraTreesClassifier,
GradientBoostingClassifier,
VotingClassifier,
)
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
def _build_window_ml_models(
df: pd.DataFrame,
cfg: GameConfig,
window: int,
) -> Dict[int, Dict]:
"""
Train a per-number ML ensemble for a given window size.
Returns {num: {"model": VotingClassifier, "scaler": StandardScaler, "feature_cols": [...], "accuracy": float}}
"""
if len(df) < 40:
return {}
sub = df.tail(window) if len(df) > window else df
feats = calculate_structural_features(sub, cfg)
base_cols = [
"DayOfWeek",
"Month",
"sum_total",
"even_count",
"odd_count",
"range_span",
"consecutive_count",
"avg_gap",
"high_count",
]
feature_cols = [c for c in base_cols if c in feats.columns]
X = feats[feature_cols].fillna(0.0)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
models: Dict[int, Dict] = {}
for num in range(cfg.main_min, cfg.main_max + 1):
y = (sub[cfg.main_cols] == num).any(axis=1).astype(int)
if y.sum() < 4:
continue
try:
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.2, random_state=42, stratify=y
)
rf = RandomForestClassifier(
n_estimators=120,
max_depth=7,
random_state=42,
class_weight="balanced",
)
et = ExtraTreesClassifier(
n_estimators=120,
max_depth=7,
random_state=42,
class_weight="balanced",
)
gb = GradientBoostingClassifier(
n_estimators=120,
max_depth=3,
learning_rate=0.08,
random_state=42,
)
if _HAS_XGB:
xgb = XGBClassifier(
n_estimators=120,
max_depth=3,
learning_rate=0.08,
subsample=0.9,
colsample_bytree=0.9,
eval_metric="logloss",
random_state=42,
)
else:
xgb = XGBClassifier(
n_estimators=120,
max_depth=3,
random_state=42,
)
mlp = MLPClassifier(
hidden_layer_sizes=(32, 16),
max_iter=600,
random_state=42,
alpha=0.0005,
)
ensemble = VotingClassifier(
estimators=[
("rf", rf),
("et", et),
("gb", gb),
("xgb", xgb),
("mlp", mlp),
],
voting="soft",
)
ensemble.fit(X_train, y_train)
y_pred = ensemble.predict(X_test)
acc = accuracy_score(y_test, y_pred)
if acc >= 0.52:
models[num] = {
"model": ensemble,
"scaler": scaler,
"feature_cols": feature_cols,
"accuracy": acc,
}
except Exception:
continue
return models
def build_multiwindow_ml(
df: pd.DataFrame,
cfg: GameConfig,
windows: List[int] = [20, 80, 400],
) -> Dict[int, Dict[str, object]]:
"""
Train ML models in multiple history windows and store them per number.
result[num] = {"short": {...}, "medium": {...}, "long": {...}}
"""
models_by_window: Dict[int, Dict[str, object]] = {}
if len(df) < 40:
return {}
for w in windows:
label = "short" if w <= 20 else ("medium" if w <= 120 else "long")
mw = _build_window_ml_models(df, cfg, w)
for num, info in mw.items():
if num not in models_by_window:
models_by_window[num] = {}
models_by_window[num][label] = info
return models_by_window
# ============================================================
# Multi-agent per-number scoring (V5.2 + Gimme5 tuning)
# ============================================================
def compute_agent_scores(
df: pd.DataFrame,
cfg: GameConfig,
ml_models: Dict[int, Dict[str, object]],
freq_features: Dict[int, Dict[str, float]],
) -> Dict[int, Dict[str, float]]:
"""
Compute scores from multiple agents for each number:
- ml_agent
- hotcold_agent
- bayes_agent
- recency_agent
- rl_agent
- pattern_agent
- cluster_agent
- drift_agent
- parity_agent
"""
scores: Dict[int, Dict[str, float]] = {}
df_struct = calculate_structural_features(df, cfg)
latest_feat = df_struct.iloc[[-1]].copy()
base_cols = [
"DayOfWeek",
"Month",
"sum_total",
"even_count",
"odd_count",
"range_span",
"consecutive_count",
"avg_gap",
"high_count",
]
latest_feat = latest_feat.reindex(columns=base_cols, fill_value=0.0)
# Global stats for drift / cluster
sums = df[cfg.main_cols].sum(axis=1)
sum_mean = float(sums.mean())
sum_std = float(sums.std()) if sums.std() > 0 else 1.0
total_draws = len(df)
# Good draws mask for RL (sums near mean)
good_mask = (abs(sums - sum_mean) <= sum_std)
good_indices = df.index[good_mask]
# RL rewards
rl_rewards: Dict[int, float] = {}
for num in range(cfg.main_min, cfg.main_max + 1):
if total_draws <= 0:
rl_rewards[num] = 0.5
continue
good_hits = 0
for idx in good_indices:
if num in df.loc[idx, cfg.main_cols].values:
good_hits += 1
rl_rewards[num] = good_hits / max(len(good_indices), 1)
# Cluster agent: based on recent 40 draws, density in +/-2 window
recent_n = min(40, len(df))
recent = df.tail(recent_n) if recent_n > 0 else df
cluster_counts: Dict[int, float] = {}
if recent_n > 0:
all_recent_nums = recent[cfg.main_cols].values.flatten()
all_recent_nums = [int(v) for v in all_recent_nums if not pd.isna(v)]
hist = Counter(all_recent_nums)
for num in range(cfg.main_min, cfg.main_max + 1):
window_sum = 0
for k in range(num - 2, num + 3):
if cfg.main_min <= k <= cfg.main_max:
window_sum += hist.get(k, 0)
cluster_counts[num] = window_sum
if cluster_counts:
max_cluster = max(cluster_counts.values()) or 1
for num in cluster_counts.keys():
cluster_counts[num] = cluster_counts[num] / max_cluster
else:
for num in range(cfg.main_min, cfg.main_max + 1):
cluster_counts[num] = 0.5
# Drift agent: compare recent sums vs older sums (20 vs 80)
recent_window = min(20, len(df))
mid_window = min(80, len(df))
if mid_window > recent_window >= 5:
recent_sums = sums.tail(recent_window)
older_sums = sums.tail(mid_window).head(mid_window - recent_window)
recent_mean = float(recent_sums.mean())
older_mean = float(older_sums.mean()) if len(older_sums) > 0 else recent_mean
if older_mean > 0:
drift_ratio = (recent_mean - older_mean) / older_mean
else:
drift_ratio = 0.0
else:
drift_ratio = 0.0
# Parity drift: even/odd balance in last 40 draws
if len(df) >= 10:
last_k = df.tail(min(40, len(df)))
even_counts = last_k[cfg.main_cols].apply(
lambda row: sum(1 for v in row if v % 2 == 0), axis=1
)
even_mean_recent = float(even_counts.mean())
expected_even = len(cfg.main_cols) / 2.0
parity_delta = even_mean_recent - expected_even
else:
parity_delta = 0.0
# Pre-calc uniform position mapping for drift
span = cfg.main_max - cfg.main_min if cfg.main_max > cfg.main_min else 1
# Is this Gimme5? (name is "Gimme 5")
is_gimme5 = cfg.name.lower().startswith("gimme")
for num in range(cfg.main_min, cfg.main_max + 1):
scores[num] = {}
# ML agent
ml_score = 0.5
if num in ml_models:
cfg_models = ml_models[num]
probs = []
weights = []
for label, info in cfg_models.items():
model = info["model"]
scaler = info["scaler"]
feature_cols = info["feature_cols"]
X_latest = latest_feat[feature_cols].fillna(0.0)
X_scaled = scaler.transform(X_latest)
if hasattr(model, "predict_proba"):
p = model.predict_proba(X_scaled)[0][1]
else:
p = 0.5
probs.append(p)
# V5.2: Gimme5 → stronger short-window weighting
if is_gimme5:
if label == "short":
weights.append(0.6)
elif label == "medium":
weights.append(0.25)
else:
weights.append(0.15)
else:
if label == "short":
weights.append(0.5)
elif label == "medium":
weights.append(0.3)
else:
weights.append(0.2)
if probs:
p_arr = np.array(probs)
w_arr = np.array(weights)
ml_score = float((p_arr * w_arr).sum() / w_arr.sum())
scores[num]["ml_agent"] = float(np.clip(ml_score, 0.0, 1.0))
# Hot/cold agent
fdata = freq_features[num]
f_20 = fdata.get("freq_20", 0.0)
f_80 = fdata.get("freq_80", 0.0)
f_400 = fdata.get("freq_400", fdata.get("overall_freq", 0.0))
hot_score = 0.5 * f_20 + 0.3 * f_80 + 0.2 * f_400
scores[num]["hotcold_agent"] = float(np.clip(hot_score * 5.0, 0.0, 1.0))
# Bayesian agent
hits = (df[cfg.main_cols] == num).sum().sum()
bayes_mean = (hits + 1.0) / (total_draws + 2.0)
scores[num]["bayes_agent"] = float(np.clip(bayes_mean * 8.0, 0.0, 1.0))
# Recency agent
days_since_last = fdata.get("days_since_last", float(total_draws))
recency_score = 1.0 / (1.0 + 0.08 * days_since_last)
scores[num]["recency_agent"] = float(np.clip(recency_score, 0.0, 1.0))
# RL agent
rl_raw = rl_rewards[num]
scores[num]["rl_agent"] = float(np.clip(rl_raw * 5.0, 0.0, 1.0))
# Pattern agent: how well this number participates in "good" patterns
pattern_hits = 0
pattern_total = 0
for idx in range(total_draws):
row_nums = df.loc[idx, cfg.main_cols].values
if num not in row_nums:
continue
row_sum = row_nums.sum()
even_cnt = sum(1 for v in row_nums if v % 2 == 0)
in_range = (cfg.sum_min <= row_sum <= cfg.sum_max)
balanced = even_cnt in (2, 3)
if in_range and balanced:
pattern_hits += 1
pattern_total += 1
pattern_score = (pattern_hits / pattern_total) if pattern_total > 0 else 0.5
scores[num]["pattern_agent"] = float(np.clip(pattern_score, 0.0, 1.0))
# Cluster agent (recent density in +/-2 around num)
scores[num]["cluster_agent"] = float(
np.clip(cluster_counts.get(num, 0.5), 0.0, 1.0)
)
# Drift agent: if sums drifting lower, prefer low; if higher, prefer high
if drift_ratio < -0.03: # trending lower
pos_num = (num - cfg.main_min) / span
drift_score = 1.0 - pos_num # low numbers ~1, high ~0
elif drift_ratio > 0.03: # trending higher
pos_num = (num - cfg.main_min) / span
drift_score = pos_num # high numbers ~1, low ~0
else:
drift_score = 0.5
scores[num]["drift_agent"] = float(np.clip(drift_score, 0.0, 1.0))
# Parity drift agent: favor even or odd depending on recent imbalance
if abs(parity_delta) < 0.2:
parity_score = 0.5
else:
is_even = (num % 2 == 0)
if parity_delta > 0: # more evens recently
parity_score = 0.8 if is_even else 0.2
else: # more odds recently
parity_score = 0.8 if not is_even else 0.2
scores[num]["parity_agent"] = float(np.clip(parity_score, 0.0, 1.0))
# Normalize each agent across all numbers (0..1)
if scores:
agent_names = list(next(iter(scores.values())).keys())
for agent in agent_names:
vals_agent = np.array([scores[n][agent] for n in scores.keys()])
vmin_a, vmax_a = vals_agent.min(), vals_agent.max()
if vmax_a > vmin_a:
for n in scores.keys():
scores[n][agent] = float(
(scores[n][agent] - vmin_a) / (vmax_a - vmin_a)
)
else:
for n in scores.keys():
scores[n][agent] = 0.5
return scores
def combine_agent_scores(
agent_scores: Dict[int, Dict[str, float]],
cfg: GameConfig,
) -> Dict[int, float]:
"""
Combine multi-agent scores into a single score per number.
V5.2: uses a different profile for Gimme5 vs other games.
"""
is_gimme5 = cfg.name.lower().startswith("gimme")
if is_gimme5:
# Gimme5: faster game, lean more on short-window / recency / clusters
weights = {
"ml_agent": 0.20,
"hotcold_agent": 0.20,
"bayes_agent": 0.10,
"recency_agent": 0.15,
"rl_agent": 0.10,
"pattern_agent": 0.05,
"cluster_agent": 0.12,
"drift_agent": 0.04,
"parity_agent": 0.04,
}
else:
# Other games: more balanced
weights = {
"ml_agent": 0.25,
"hotcold_agent": 0.18,
"bayes_agent": 0.12,
"recency_agent": 0.08,
"rl_agent": 0.12,
"pattern_agent": 0.08,
"cluster_agent": 0.08,
"drift_agent": 0.05,
"parity_agent": 0.04,
}
final_scores: Dict[int, float] = {}
for num, agents in agent_scores.items():
total = 0.0
for name, w in weights.items():
total += w * agents.get(name, 0.5)
final_scores[num] = float(total)
if final_scores:
vals = np.array(list(final_scores.values()))
vmin, vmax = vals.min(), vals.max()
if vmax > vmin:
for n in final_scores.keys():
final_scores[n] = float((final_scores[n] - vmin) / (vmax - vmin))
else:
for n in final_scores.keys():
final_scores[n] = 0.5
return final_scores
# ============================================================
# Combination scoring & generation
# ============================================================
def score_combo_pattern(
combo: List[int],
df: pd.DataFrame,
cfg: GameConfig,
style: str = "balanced",
) -> float:
"""
Score a candidate combination:
- Sum vs history & config
- Even/odd mix
- Range & gaps
plus style-specific tweaks for multi-style GOD MODE.
"""
combo = sorted(combo)
score = 0.0
sums = df[cfg.main_cols].sum(axis=1)
sum_mean = float(sums.mean())
sum_std = float(sums.std()) if sums.std() > 0 else 1.0
combo_sum = sum(combo)
if cfg.sum_min <= combo_sum <= cfg.sum_max:
score += 1.0
z = abs(combo_sum - sum_mean) / sum_std
score += max(0.0, 1.5 - z)
else:
score -= 1.0
even_count = sum(1 for v in combo if v % 2 == 0)
if even_count in (2, 3):
score += 1.0
elif even_count in (1, 4):
score += 0.2
else:
score -= 0.5
combo_range = max(combo) - min(combo)
hist_range = df[cfg.main_cols].max(axis=1) - df[cfg.main_cols].min(axis=1)
mean_r = float(hist_range.mean()) if len(hist_range) > 0 else combo_range
if mean_r > 0:
diff = abs(combo_range - mean_r) / mean_r
if diff < 0.3:
score += 0.7
elif diff < 0.6:
score += 0.2
else:
score -= 0.2
gaps = [combo[i + 1] - combo[i] for i in range(len(combo) - 1)]
avg_gap = float(np.mean(gaps)) if gaps else 0.0
midpoint = (cfg.main_min + cfg.main_max) / 2.0
low_count = sum(1 for v in combo if v <= midpoint)
high_count = len(combo) - low_count
if style == "low_cluster":
if low_count >= 3:
score += 0.7
if combo_range <= (cfg.main_max - cfg.main_min) * 0.5:
score += 0.3
elif style == "high_cluster":
if high_count >= 3:
score += 0.7
if combo_range <= (cfg.main_max - cfg.main_min) * 0.5:
score += 0.3
elif style == "tight_cluster":
if combo_range <= (cfg.main_max - cfg.main_min) * 0.4:
score += 0.8
if avg_gap <= 8:
score += 0.4
elif style == "wide_spread":
if combo_range >= (cfg.main_max - cfg.main_min) * 0.6:
score += 0.8
if avg_gap >= 6:
score += 0.4
elif style == "top_cluster":
# Reward combos staying fairly central and not too extreme
if combo_range <= (cfg.main_max - cfg.main_min) * 0.6:
score += 0.5
if avg_gap <= 10:
score += 0.3
return score
def _max_consecutive_run(nums: List[int]) -> int:
"""Return the maximum length of any consecutive (x, x+1, x+2, ...) run in a sorted list."""
if not nums:
return 0
run = 1
best = 1
for i in range(1, len(nums)):
if nums[i] == nums[i - 1] + 1:
run += 1
else:
run = 1
if run > best:
best = run
return best
def _has_consecutive_run(nums: List[int], run_len: int = 3) -> bool:
"""True if nums contains any consecutive run of length >= run_len."""
return _max_consecutive_run(nums) >= run_len
def generate_godmode_combo(
df: pd.DataFrame,
cfg: GameConfig,
final_scores: Dict[int, float],
banned_nums: Optional[set] = None,
n_candidates: int = 6000,
style: str = "balanced",
enforce_pb_tail_slot: bool = False,
) -> Tuple[List[int], float]:
"""
Monte Carlo search for best combination for a given style.
style ∈ {"balanced", "low_cluster", "high_cluster", "tight_cluster", "wide_spread", "top_cluster"}
(for "top_cluster" a separate helper is usually used, but style is kept
here for consistency).
"""
if banned_nums is None:
banned_nums = set()
last_draw_set = get_last_draw_main_set(df, cfg)
filtered_scores = {n: s for n, s in final_scores.items() if n not in banned_nums}
if not filtered_scores:
filtered_scores = final_scores.copy()
numbers = list(filtered_scores.keys())
weights = np.array(list(filtered_scores.values()), dtype=float)
if weights.sum() <= 0:
weights = np.ones_like(weights)
weights /= weights.sum()
best_combo: Optional[List[int]] = None
best_score = -1e9
for _ in range(n_candidates):
combo = list(
np.random.choice(numbers, size=len(cfg.main_cols), replace=False, p=weights)
)
combo.sort()
# Soft preference: include at least ONE main number from the most recent draw
# LIMITED to styles: Top Cluster / Balanced and games: L4L, Gimme5, Megabucks
if style in ("top_cluster", "balanced") and cfg.name in ("Lucky for Life", "Gimme 5", "Megabucks"):
if last_draw_set:
overlap = set(combo) & set(last_draw_set)
if not overlap:
# pick the best-scoring last-draw number that isn't banned and isn't already in combo
ld_cands = [n for n in last_draw_set if n not in banned_nums and n not in combo]
if ld_cands:
best_ld = max(ld_cands, key=lambda t: filtered_scores.get(t, 0.0))
# replace the weakest number in the current combo (by filtered score)
weakest = min(combo, key=lambda t: filtered_scores.get(t, 0.0))
if best_ld != weakest:
new_combo = sorted((set(combo) - {weakest}) | {best_ld})
if len(new_combo) == len(cfg.main_cols):
combo = new_combo
# Optional PB tail-slot enforcement: ensure at least one number from 60–69
if enforce_pb_tail_slot and cfg.name == "Powerball" and style in ("high_cluster", "wide_spread"):
if not any(65 <= x <= 69 for x in combo):
tail_cands = [n for n in numbers if 65 <= n <= 69 and n not in combo]
if tail_cands:
best_tail = max(tail_cands, key=lambda t: filtered_scores.get(t, 0.0))
non_tail = [x for x in combo if not (65 <= x <= 69)]
if non_tail:
weakest = min(non_tail, key=lambda t: filtered_scores.get(t, 0.0))
combo = sorted([best_tail if x == weakest else x for x in combo])
# PB-only consecutive guard (optional): skip combos with 3+ consecutive main numbers
if cfg.name == "Powerball" and PATCH_UI_FLAGS.get("enable_pb_consec_guard", False):
if _has_consecutive_run(combo, int(PATCH_UI_FLAGS.get("pb_consec_guard_run", 3))):
continue
pat_score = score_combo_pattern(combo, df, cfg, style=style)
synergy = float(np.mean([filtered_scores[n] for n in combo]))
total_score = pat_score + synergy * 2.0
if last_draw_set and combo == last_draw_set:
total_score *= 0.93 # soft full-repeat dampener (exact 5/5 match)
if total_score > best_score:
best_score = total_score
best_combo = combo
if best_combo is None:
best_combo = sorted(
np.random.choice(numbers, size=len(cfg.main_cols), replace=False).tolist()
)
return best_combo, float(best_score)
def generate_top_cluster_combo(
df: pd.DataFrame,
cfg: GameConfig,
final_scores: Dict[int, float],
banned_nums: Optional[set] = None,
top_n_core: int = 3,
n_candidates: int = 3000,
) -> Tuple[List[int], float]:
"""
Hyper-focused combo that forces top K highest-score numbers together
in a single line, then fills the remaining spots with other strong numbers.
"""
if banned_nums is None:
banned_nums = set()
last_draw_set = get_last_draw_main_set(df, cfg)
sorted_nums = sorted(
((n, s) for n, s in final_scores.items() if n not in banned_nums),
key=lambda kv: kv[1],
reverse=True,
)
if not sorted_nums:
sorted_nums = sorted(final_scores.items(), key=lambda kv: kv[1], reverse=True)
core = [n for n, _ in sorted_nums[:top_n_core]]
core = core[: len(cfg.main_cols)] # safety
remaining_pool = [n for n, _ in sorted_nums if n not in core]
if len(remaining_pool) < (len(cfg.main_cols) - len(core)):
# not enough left, just fall back
return generate_godmode_combo(
df, cfg, final_scores, banned_nums=banned_nums, n_candidates=n_candidates, style="top_cluster"
)
remaining_weights = np.array([final_scores[n] for n in remaining_pool], dtype=float)
if remaining_weights.sum() <= 0:
remaining_weights = np.ones_like(remaining_weights)
remaining_weights /= remaining_weights.sum()
best_combo: Optional[List[int]] = None
best_score = -1e9
needed = len(cfg.main_cols) - len(core)
for _ in range(n_candidates):
support = list(
np.random.choice(
remaining_pool,
size=needed,
replace=False,
p=remaining_weights,
)
)
combo = sorted(core + support)
# PB-only consecutive guard (optional): skip combos with 3+ consecutive main numbers
if cfg.name == "Powerball" and PATCH_UI_FLAGS.get("enable_pb_consec_guard", False):
if _has_consecutive_run(combo, int(PATCH_UI_FLAGS.get("pb_consec_guard_run", 3))):
continue
pat_score = score_combo_pattern(combo, df, cfg, style="top_cluster")
synergy = float(np.mean([final_scores[n] for n in combo]))
total_score = pat_score + synergy * 2.0
if last_draw_set and combo == last_draw_set:
total_score *= 0.93 # soft full-repeat dampener (exact 5/5 match)
if total_score > best_score:
best_score = total_score
best_combo = combo
if best_combo is None:
# extreme fallback
return generate_godmode_combo(
df, cfg, final_scores, banned_nums=banned_nums, n_candidates=n_candidates, style="top_cluster"
)
return best_combo, float(best_score)
def _compute_sum_regime_and_trend(df: pd.DataFrame, cfg: GameConfig) -> Dict[str, object]:
"""
Analyze recent sums to detect:
- volatility regime: low / flat / high
- short-term trend: high_run / low_run / none
"""
sums = df[cfg.main_cols].sum(axis=1)
if len(sums) == 0:
return {
"regime": "unknown",
"volatility": 0.0,
"trend": "none",
"mean": 0.0,
"std": 1.0,
}
recent = sums.tail(40) if len(sums) > 40 else sums
mean = float(recent.mean())
std = float(recent.std()) if recent.std() > 0 else 1.0
z = (recent - mean) / std
vol = float(np.mean(np.abs(z)))
if vol < 0.8:
regime = "low"
elif vol > 1.2:
regime = "high"
else:
regime = "flat"
last_k = min(6, len(recent))
tail_vals = recent.tail(last_k)
hi_th = mean + 0.5 * std
lo_th = mean - 0.5 * std
last3 = tail_vals.tail(3)
if all(v > hi_th for v in last3):
trend = "high_run"
elif all(v < lo_th for v in last3):
trend = "low_run"
else:
trend = "none"
return {
"regime": regime,
"volatility": vol,
"trend": trend,
"mean": mean,
"std": std,
}
def _compute_coldness(df: pd.DataFrame, cfg: GameConfig) -> Dict[int, float]:
"""
Coldness score per number in [0,1], where 1 = very cold, 0 = very hot.
"""
all_nums = df[cfg.main_cols].values.flatten()
all_nums = [int(v) for v in all_nums if not pd.isna(v)]
if not all_nums:
return {n: 0.5 for n in range(cfg.main_min, cfg.main_max + 1)}
freq = Counter(all_nums)
values = list(freq.values())
if not values:
return {n: 0.5 for n in range(cfg.main_min, cfg.main_max + 1)}
f_min = min(values)
f_max = max(values)
denom = max(f_max - f_min, 1)
coldness: Dict[int, float] = {}
for n in range(cfg.main_min, cfg.main_max + 1):
f = freq.get(n, 0)
cold = (f_max - f) / denom # high when f is small
coldness[n] = float(np.clip(cold, 0.0, 1.0))
return coldness
def _adjust_scores_v5_3(
df: pd.DataFrame,
cfg: GameConfig,
base_scores: Dict[int, float],
) -> Tuple[Dict[int, float], Dict[str, object], Dict[int, float]]:
"""
V5.3 ULTRA correction layer:
1) Dynamic regime detection (low/flat/high volatility).
2) Low-zone boost (roughly bottom 1/3rd of the range).
3) Inverse-trend feature (reversal agent).
4) Cold-burst: slight boost to colder numbers, dampen over-hot.
5) Mega Millions specific mid/high-band refinements + neighbor-chaser.
6) Lotto America specific main-range tweaks + neighbor-chaser.
7) Megabucks specific main-range tweaks.
8) Powerball specific main-range tweaks.
9) Lucky for Life specific main-range tweaks + neighbor-chaser for mids.
10) Gimme 5 neighbor-chaser with micro-boost around recent hot core numbers.
Returns:
adjusted_scores, regime_info, coldness_map
"""
if not base_scores:
return base_scores, {"regime": "unknown"}, {
n: 0.5 for n in range(cfg.main_min, cfg.main_max + 1)
}
regime_info = _compute_sum_regime_and_trend(df, cfg)
regime = regime_info.get("regime", "flat")
trend = regime_info.get("trend", "none")
span = max(cfg.main_max - cfg.main_min, 1)
mid = cfg.main_min + span / 2.0
low_cut = cfg.main_min + int(span * 0.33)
regime_info["low_zone_cut"] = low_cut
coldness = _compute_coldness(df, cfg)
vals = np.array(list(base_scores.values()), dtype=float)
vmin, vmax = float(vals.min()), float(vals.max())
norm_scores: Dict[int, float] = {}
if vmax > vmin:
for n, s in base_scores.items():
norm_scores[n] = float((s - vmin) / (vmax - vmin))
else:
for n in base_scores.keys():
norm_scores[n] = 0.5
# Lucky for Life neighbor-chaser: identify recent hot mids (11–38)
l4l_hot_mids: set = set()
if cfg.name == "Lucky for Life":
recent_draws = df[cfg.main_cols].tail(30)
vals_mid = recent_draws.values.flatten()
mids = [
int(v)
for v in vals_mid
if not pd.isna(v) and 11 <= int(v) <= 38
]
if mids:
freq_mid = Counter(mids)
l4l_hot_mids = {
n for n, _ in sorted(
freq_mid.items(), key=lambda kv: kv[1], reverse=True
)[:6]
}
# Gimme 5 neighbor-chaser: identify recent hot core numbers (5–35)
g5_hot_core: set = set()
if cfg.name == "Gimme 5":
recent_g5 = df[cfg.main_cols].tail(25)
vals_g = recent_g5.values.flatten()
gnums = [int(v) for v in vals_g if not pd.isna(v)]
if gnums:
freq_g = Counter(gnums)
ordered = sorted(freq_g.items(), key=lambda kv: kv[1], reverse=True)
core_list: List[int] = []
for n, _ in ordered:
if 5 <= n <= 35:
core_list.append(n)
if len(core_list) >= 6:
break
g5_hot_core = set(core_list)
# Gimme 5 extreme-low snapback: if no lows (<=5) appeared in recent draws, lightly boost 1–5
g5_low_suppressed: bool = False
if cfg.name == "Gimme 5":
recent_low = df[cfg.main_cols].tail(8).values.flatten()
lows = [int(v) for v in recent_low if (not pd.isna(v) and int(v) <= 5)]
g5_low_suppressed = (len(lows) == 0)
# Lotto America neighbor-chaser: identify recent hot core band numbers (15–45)
la_hot_core: set = set()
if cfg.name == "Lotto America":
recent_la = df[cfg.main_cols].tail(30)
vals_la = recent_la.values.flatten()
lans = [int(v) for v in vals_la if not pd.isna(v)]
if lans:
freq_la = Counter(lans)
ordered_la = sorted(
freq_la.items(), key=lambda kv: kv[1], reverse=True
)
core_la: List[int] = []
for n, _ in ordered_la:
if 15 <= n <= 45:
core_la.append(n)
if len(core_la) >= 6:
break
la_hot_core = set(core_la)
# Mega Millions neighbor-chaser: identify recent hot core band numbers (20–60)
mm_hot_core: set = set()
if cfg.name == "Mega Millions":
recent_mm = df[cfg.main_cols].tail(30)
vals_mm = recent_mm.values.flatten()
mnums = [int(v) for v in vals_mm if not pd.isna(v)]
if mnums:
freq_mm = Counter(mnums)
ordered_mm = sorted(
freq_mm.items(), key=lambda kv: kv[1], reverse=True
)
core_mm: List[int] = []
for n, _ in ordered_mm:
if 20 <= n <= 60:
core_mm.append(n)
if len(core_mm) >= 8:
break
mm_hot_core = set(core_mm)
# Megabucks neighbor-chaser: identify recent hot core band numbers (18–35)
mb_hot_core: set = set()
if cfg.name == "Megabucks":
recent_mb = df[cfg.main_cols].tail(30)
vals_mb = recent_mb.values.flatten()
mbnums = [int(v) for v in vals_mb if not pd.isna(v)]
if mbnums:
freq_mb = Counter(mbnums)
ordered_mb = sorted(freq_mb.items(), key=lambda kv: kv[1], reverse=True)
core_mb: List[int] = []
for n, _ in ordered_mb:
if 18 <= n <= 35:
core_mb.append(n)
if len(core_mb) >= 6:
break
mb_hot_core = set(core_mb)
# Powerball neighbor-chaser: identify recent hot core band numbers (20–45)
pb_hot_core: set = set()
if cfg.name == "Powerball":
recent_pb = df[cfg.main_cols].tail(30)
vals_pb = recent_pb.values.flatten()
pbnums = [int(v) for v in vals_pb if not pd.isna(v)]
if pbnums:
freq_pb = Counter(pbnums)
ordered_pb = sorted(freq_pb.items(), key=lambda kv: kv[1], reverse=True)
core_pb: List[int] = []
for n, _ in ordered_pb:
if 20 <= n <= 45:
core_pb.append(n)
if len(core_pb) >= 6:
break
pb_hot_core = set(core_pb)
# --- PB_TAIL_SLOT_PATCH_V1 -------------------------------------
pb_tail_overdue = False
if cfg.name == "Powerball" and len(df) >= 8:
last8 = df[cfg.main_cols].tail(8).values.flatten()
last8 = [int(v) for v in last8 if not pd.isna(v)]
pb_tail_overdue = not any(60 <= v <= 69 for v in last8)
# ----------------------------------------------------------------
adjusted: Dict[int, float] = {}
for n, s in norm_scores.items():
m = 1.0
pos = (n - cfg.main_min) / span
in_low_zone = n <= low_cut
# Low-zone boost
if in_low_zone:
m *= 1.18 # low-zone probability boost
# Regime-specific tweaks
if regime == "high":
if s > 0.7:
m *= 0.92
elif s < 0.4:
m *= 1.08
elif regime == "low":
if s > 0.7:
m *= 1.05
elif s < 0.3:
m *= 0.90
else:
if s > 0.8:
m *= 0.97
elif s < 0.2:
m *= 1.03
# Trend inversion: favor reversal side a bit
if trend == "high_run":
if n <= mid:
m *= 1.10
else:
m *= 0.90
elif trend == "low_run":
if n >= mid:
m *= 1.10
else:
m *= 0.90
# Cold-burst factor
c = coldness.get(n, 0.5)
if regime == "high":
m *= (1.0 + 0.25 * c)
else:
m *= (1.0 + 0.15 * c)
# Mega Millions specific mid/high-band refinements + neighbor-chaser
if cfg.name == "Mega Millions":
# Mild band push for 30–55 to pull mid/high corridor together
if 30 <= n <= 55:
m *= 1.03
# Boost 34–36 band
if 34 <= n <= 36:
m *= 1.06
# Boost 37–39 ridge
if 37 <= n <= 39:
m *= 1.05
# Soften extreme high cooling 65+ so 69-style hits are not suppressed
if n >= 65:
m *= 1.03
# MM neighbor-chaser: tiny boost to neighbors of recent hot core numbers
if mm_hot_core and ((n - 1 in mm_hot_core) or (n + 1 in mm_hot_core)):
m *= 1.03
# Lotto America specific main-range tweaks (V5.3 ULTRA + neighbor-chaser + high-tail support)
if cfg.name == "Lotto America":
# Slight boost to mid-band 20–40
if 20 <= n <= 40:
m *= 1.04
# NEW: small high-tail support 35–45 so 37/42/44-style clusters survive more often
if 35 <= n <= 45:
m *= 1.02
# Softer damp on extremes (keep lows like 3/4/5 alive; avoid over-cooling 50+)
if n <= 5 or n >= 50:
m *= 0.98
# Tiny neighbor-chaser boost: ±1 around recent hot core numbers
if la_hot_core and ((n - 1 in la_hot_core) or (n + 1 in la_hot_core)):
m *= 1.03
# Megabucks specific main-range tweaks (V5.3 ULTRA)
if cfg.name == "Megabucks":
# Slight boost to mid-band 18–32 (common MB hit zone)
if 18 <= n <= 32:
m *= 1.04
# Soft boost for upper range 35–41 so high numbers like 41 don't get over-cooled
if 35 <= n <= 41:
m *= 1.03
# Mild dampening on ultra-low extremes 1–3
if n <= 3:
m *= 0.96
# MB neighbor-chaser micro-patch: push neighbors (±1) of recent hot core numbers
# (helps catch 24–26 / 25–27 style ladders without forcing adjacency)
if 'mb_hot_core' in locals() and mb_hot_core:
if n in mb_hot_core:
m *= 1.02
if (n - 1 in mb_hot_core) or (n + 1 in mb_hot_core):
m *= 1.03
# Powerball specific main-range tweaks (V5.3 ULTRA + neighbor-chaser)
if cfg.name == "Powerball":
# Slight boost to core mid-band 20–45 (heavy PB activity zone)
if 20 <= n <= 45:
m *= 1.04
# Soft support for secondary band 10–19 and 46–59
if (10 <= n <= 19) or (46 <= n <= 59):
m *= 1.02
# Softer dampening on extreme ends 1–3 and 65–69 (was 0.96)
if n <= 3 or n >= 65:
m *= 0.98
# PB_TAIL_SLOT_PATCH_V1 apply
if 'pb_tail_overdue' in locals() and pb_tail_overdue and (65 <= n <= 69):
m *= 1.05
# PB neighbor-chaser micro-patch: nudge neighbors (±1) of recent hot core numbers (20–45)
if 'pb_hot_core' in locals() and pb_hot_core:
if n in pb_hot_core:
m *= 1.02
if (n - 1 in pb_hot_core) or (n + 1 in pb_hot_core):
m *= 1.03
# Lucky for Life specific main-range tweaks (V5.3 ULTRA, stronger + neighbor-chaser)
if cfg.name == "Lucky for Life":
# Stronger boost to core central band 14–36 where many hits cluster
if 14 <= n <= 36:
m *= 1.06
# Secondary soft support for broader mid band 11–38
if 11 <= n <= 38:
m *= 1.02
# Slightly stronger dampening on outer extremes 1–4 and 45–48
if n <= 4 or n >= 45:
m *= 0.95
# Tiny neighbor-chaser boost: ±1 around recent hot mids
if l4l_hot_mids and ((n - 1 in l4l_hot_mids) or (n + 1 in l4l_hot_mids)):
m *= 1.03 # ~3% nudge, just enough to surface neighbors
# Gimme 5 micro-patches:
# - Neighbor-chaser: tiny nudge around recent hot core numbers
# - Extreme-low snapback: if lows (<=5) have been absent for a short window, lightly boost 1–5
if cfg.name == "Gimme 5":
if g5_low_suppressed and n <= 5:
m *= 1.06 # snapback (kept small so it doesn't spam lows)
if g5_hot_core and ((n - 1 in g5_hot_core) or (n + 1 in g5_hot_core)):
m *= 1.05 # micro-boosted neighbor effect
adjusted[n] = float(max(m * s, 0.0))
vals_adj = np.array(list(adjusted.values()), dtype=float)
vmin_adj, vmax_adj = float(vals_adj.min()), float(vals_adj.max())
if vmax_adj > vmin_adj:
for n in adjusted.keys():
adjusted[n] = float((adjusted[n] - vmin_adj) / (vmax_adj - vmin_adj))
else:
for n in adjusted.keys():
adjusted[n] = 0.5
return adjusted, regime_info, coldness
def pick_star_ball(df: pd.DataFrame, cfg: GameConfig) -> Optional[int]:
"""
V5.3.1 Mega / bonus ball picker.
Improvements over V5.2:
- Uses all-time + medium-term + short-term frequencies.
- Adds a cold-burst factor (prefer colder balls slightly).
- Favors low-zone bonus numbers a bit more (good for Mega Millions MB 1–12).
- Respects cfg.star_min / cfg.star_max for all games.
- Lotto America: extra boost for SB 1–5.
- Powerball: mild preference for PB 1–15.
- Lucky for Life: mild mid-band Lucky Ball tilt (7–15).
"""
if not cfg.star_col:
return None
df = df.copy()
df[cfg.star_col] = pd.to_numeric(df[cfg.star_col], errors="coerce")
df = df.dropna(subset=[cfg.star_col])
if df.empty:
return None
series = df[cfg.star_col].astype(int)
freq_all = Counter(series)
recent_med = series.tail(40) if len(series) > 40 else series
freq_med = Counter(recent_med)
recent_short = series.tail(15) if len(series) > 15 else series
freq_short = Counter(recent_short)
# Build base weights from multiple horizons
weights: Dict[int, float] = {}
all_vals_bonus = []
for s in range(cfg.star_min, cfg.star_max + 1):
w = (
0.50 * freq_med.get(s, 0)
+ 0.30 * freq_all.get(s, 0)
+ 0.20 * freq_short.get(s, 0)
)
weights[s] = float(w)
all_vals_bonus.append(w)
# Avoid degenerate case
if not all_vals_bonus or max(all_vals_bonus) == 0:
return int(random.randint(cfg.star_min, cfg.star_max))
# Coldness (for cold-burst boosting)
vals_bonus = [freq_all.get(s, 0) for s in range(cfg.star_min, cfg.star_max + 1)]
f_min_b, f_max_b = min(vals_bonus), max(vals_bonus)
denom_b = max(f_max_b - f_min_b, 1)
coldness_bonus: Dict[int, float] = {}
for s in range(cfg.star_min, cfg.star_max + 1):
f = freq_all.get(s, 0)
cold_b = (f_max_b - f) / denom_b # high when f is small
coldness_bonus[s] = float(np.clip(cold_b, 0.0, 1.0))
# --- PB_BONUS_OVERDUE_PATCH_V1 (Powerball only) ----------------
pb_days_since: Dict[int, int] = {}
pb_last_val: Optional[int] = None
if cfg.name == "Powerball":
cap = 20
try:
pb_last_val = int(series.iloc[-1])
except Exception:
pb_last_val = None
for s in range(cfg.star_min, cfg.star_max + 1):
d = cap
for i in range(len(series) - 1, -1, -1):
if int(series.iloc[i]) == s:
d = min(cap, (len(series) - 1 - i))
break
pb_days_since[s] = int(d)
# ----------------------------------------------------------------
# Low-zone boost (e.g., MB 1–12)
span_b = cfg.star_max - cfg.star_min
low_cut_b = cfg.star_min + int(span_b * 0.5) # bottom half considered "low zone"
adjusted_bonus: Dict[int, float] = {}
for s in range(cfg.star_min, cfg.star_max + 1):
base_b = weights.get(s, 0.0)
c_b = coldness_bonus.get(s, 0.5)
m_b = 1.0
# Low-zone preference
if s <= low_cut_b:
m_b *= 1.12 # +12% for low-zone stars
# Lotto America: extra preference for SB 1–5
if cfg.name == "Lotto America" and s <= 5:
m_b *= 1.08
# Powerball: mild preference for PB 1–15 zone
if cfg.name == "Powerball" and s <= 15:
m_b *= 1.05
# Lucky for Life: mid-band preference for Lucky Ball 7–15
if cfg.name == "Lucky for Life" and 7 <= s <= 15:
m_b *= 1.05
# Cold-burst
m_b *= (1.0 + 0.25 * c_b) # up to +25% for very cold bonus balls
# PB_BONUS_OVERDUE_PATCH_V1 apply (gentle)
if cfg.name == "Powerball" and pb_days_since:
cap = 20
alpha = 0.35
anti_repeat = 0.97
overdue = min(cap, int(pb_days_since.get(s, cap))) / float(cap)
m_b *= (1.0 + alpha * overdue)
if pb_last_val is not None and int(s) == int(pb_last_val):
m_b *= anti_repeat
adjusted_bonus[s] = max(base_b * m_b, 0.0)
# Normalize to probabilities
stars = list(adjusted_bonus.keys())
wts = [adjusted_bonus[s] for s in stars]
total_b = float(sum(wts))
if total_b <= 0:
return int(random.randint(cfg.star_min, cfg.star_max))
probs = [w / total_b for w in wts]
choice = int(np.random.choice(stars, p=probs))
return choice
# ============================================================
# Last-4 repeater ban rule (your custom rule)
# ============================================================
def get_last4_repeater_ban(df: pd.DataFrame, cfg: GameConfig) -> set:
"""
Your rule:
- Look at the most recent 4 draws.
- If a number appears in EACH of those 4 draws,
it is banned from prediction.
- We do NOT ban all numbers that just appeared once or twice.
"""
if len(df) < 4:
return set()
last4 = df[cfg.main_cols].tail(4).values
cnt = Counter()
for row in last4:
unique_nums = {int(v) for v in row if not pd.isna(v)}
for n in unique_nums:
cnt[n] += 1
banned = {n for n, c in cnt.items() if c == 4}
return banned
def get_consecutive_streaks(df: pd.DataFrame, cfg: GameConfig, lookback: int = 12) -> Dict[int, int]:
"""
Compute consecutive-draw streak length for MAIN numbers, based on the most recent draws.
Returns a dict {number: streak_len} for numbers that appear in the most recent draw.
Example: streak_len == 3 means the number appeared in each of the last 3 consecutive draws.
"""
if len(df) == 0:
return {}
lookback = max(1, int(lookback))
tail = df[cfg.main_cols].tail(lookback).values.tolist()
last_row = tail[-1]
last_nums = {int(v) for v in last_row if not pd.isna(v)}
streaks: Dict[int, int] = {}
for n in last_nums:
s = 0
# Walk backwards through draws; count consecutive appearances
for row in reversed(tail):
row_nums = {int(v) for v in row if not pd.isna(v)}
if n in row_nums:
s += 1
else:
break
streaks[int(n)] = int(s)
return streaks
def apply_streak_guard(final_scores: Dict[int, float], df: pd.DataFrame, cfg: GameConfig) -> Tuple[Dict[int, float], set]:
"""
Optional rule (toggle-controlled):
- Allow repeats up to 3 consecutive draws.
- If a number has a 3-draw streak already, DOWNWEIGHT it so we tend to move on.
- If a number ever reaches a 4-draw streak, it will be banned by the existing last-4 repeater ban.
Returns (adjusted_scores, extra_banned_set)
"""
if not PATCH_UI_FLAGS.get("enable_streak_guard", False):
return final_scores, set()
max_streak = int(PATCH_UI_FLAGS.get("streak_guard_max", 3))
penalty_factor = float(PATCH_UI_FLAGS.get("streak_guard_penalty_factor", 0.55))
# Safety
if max_streak < 1:
return final_scores, set()
streaks = get_consecutive_streaks(df, cfg, lookback=max(12, max_streak + 2))
adjusted = dict(final_scores)
extra_banned = set()
for n, s in streaks.items():
# We only intervene at the threshold (e.g., s == 3 when max_streak == 3)
if s >= (max_streak + 1):
# 4+ streak (should already be caught by last-4 rule, but keep safe)
extra_banned.add(int(n))
elif s == max_streak:
# On a 3-draw streak: gently push away so we "move on to due/hot"
if int(n) in adjusted:
adjusted[int(n)] = float(adjusted[int(n)]) * penalty_factor
return adjusted, extra_banned
# ============================================================
# GOD MODE V5.3 prediction (multi-style, including top_cluster)
# ============================================================
def get_last_draw_main_set(df: pd.DataFrame, cfg: GameConfig) -> List[int]:
"""Return the most recent draw's main numbers as a sorted list of ints.
Used for a soft anti-repeat penalty when a candidate combo exactly matches
the previous draw (exact 5/5 match on main numbers). Applies across all games.
"""
if df is None or df.empty:
return []
row = df.iloc[-1][cfg.main_cols].values.tolist()
nums = [int(v) for v in row if not pd.isna(v)]
return sorted(nums)
# ============================================================
# SPREAD PORTFOLIO + REGIME LABEL (ALL GAMES)
# ============================================================
def _regime_low_high_bounce_label(df: pd.DataFrame, cfg: "GameConfig") -> str:
"""Heuristic label: detect recent LOW streak and suggest LOW→HIGH bounce (or reverse)."""
try:
if df is None or len(df) < 15:
return ""
# Sum history (main balls only)
sums = []
for _, row in df.tail(60).iterrows():
try:
s = sum(int(row[c]) for c in cfg.main_cols)
sums.append(s)
except Exception:
continue
if len(sums) < 15:
return ""
import numpy as _np
arr = _np.array(sums, dtype=float)
q35 = float(_np.quantile(arr, 0.35))
q65 = float(_np.quantile(arr, 0.65))
last = arr[-1]
prev = arr[-2]
# If last 2 were LOW, expect bounce UP
if last <= q35 and prev <= q35:
return "Regime detected: LOW → HIGH bounce"
# If last 2 were HIGH, expect cool-down
if last >= q65 and prev >= q65:
return "Regime detected: HIGH → LOW cool-down"
return ""
except Exception:
return ""
def _build_spread_portfolio_generic(
cfg: "GameConfig",
pool12: List[int],
star: int | None = None,
force_high_bias: float = 0.0,
) -> Dict[str, Dict[str, object]]:
"""Build a 9–10 ticket spread portfolio from POOL12 (fallbacks to full range)."""
nums = sorted({int(x) for x in (pool12 or []) if x is not None})
if not nums:
nums = list(range(int(cfg.main_min), int(cfg.main_max) + 1))
main_n = int(len(cfg.main_cols))
# Zones
span = int(cfg.main_max) - int(cfg.main_min)
low_cut = int(cfg.main_min) + int(span * 0.33)
high_cut = int(cfg.main_min) + int(span * 0.66)
low = [n for n in nums if n <= low_cut]
mid = [n for n in nums if low_cut < n < high_cut]
high = [n for n in nums if n >= high_cut]
# Fallbacks
if len(low) < 2:
low = sorted(set(low + nums[:max(2, min(6, len(nums)))]))
if len(high) < 2:
high = sorted(set(high + nums[-max(2, min(6, len(nums))):]))
if len(mid) < 2:
mid = [n for n in nums if n not in low and n not in high]
if len(mid) < 2:
mid = nums
def _fill(parts: List[int]) -> List[int]:
parts = [int(x) for x in parts if x is not None]
parts = sorted(set(parts))
# Fill from nums first
for n in nums:
if len(parts) >= main_n:
break
if n not in parts:
parts.append(n)
# Fill from full range if still short
if len(parts) < main_n:
for n in range(int(cfg.main_min), int(cfg.main_max) + 1):
if len(parts) >= main_n:
break
if n not in parts:
parts.append(n)
return sorted(parts[:main_n])
def _pick(k_low: int, k_mid: int, k_high: int) -> List[int]:
take = []
take += low[:k_low]
take += mid[:k_mid]
# High bias: if force_high_bias>0, preferentially take more highs from the tail
if force_high_bias > 0 and len(high) >= k_high:
take += high[-k_high:]
else:
take += high[:k_high]
return _fill(take)
def _wrap(numbers: List[int]) -> Dict[str, object]:
d = {"numbers": numbers}
if star is not None:
d["star"] = int(star)
return d
# Portfolio (10 tickets)
portfolio = {
"spread_low_1": _wrap(_pick(3, 2, 0)),
"spread_low_2": _wrap(_pick(3, 2, 0)[::-1]),
"spread_low_3": _wrap(_pick(3, 1, 1)),
"spread_normal_1": _wrap(_pick(2, 2, 1)),
"spread_normal_2": _wrap(_pick(1, 3, 1)),
"spread_normal_3": _wrap(_pick(2, 1, 2)),
"spread_high_1": _wrap(_pick(1, 1, 3)),
"spread_high_2": _wrap(_pick(0, 2, 3)),
"spread_high_3": _wrap(_pick(1, 0, 4) if main_n == 5 else _pick(1, 1, main_n - 2)),
"spread_bridge_1": _wrap(_pick(2, 1, 2)),
}
return portfolio
def generate_prediction_v4_god( # name kept for compatibility
raw_df: pd.DataFrame,
cfg: GameConfig,
) -> Dict[str, object]:
"""
Main GOD MODE engine (V5.3.1 ULTRA behavior on top of V5.2).
- Builds multi-window ML models
- Computes multi-agent scores (including cluster/drift/parity)
- Applies last-4 repeater ban (your consecutive rule)
- Applies V5.3.1 corrections:
* regime detection (low/flat/high)
* low-zone boost
* inverse trend correction
* cold-burst correction
* anti-lock rule (prevent over-using same number across sets)
* coverage optimizer across the 5–6 styles
- Generates styled combos:
top_cluster, balanced, low_cluster, high_cluster, tight_cluster, wide_spread
"""
df = _ensure_datetime(raw_df, cfg.csv_date_col)
if cfg.clean_func and cfg.clean_func in globals():
df = globals()[cfg.clean_func](df)
if len(df) < 40:
raise ValueError("Insufficient history (<40 draws) for GOD-MODE engine.")
df_long = _limit_history(df, _auto_history_window(df, cfg))
# Core multi-window ML + agent scoring
ml_models = build_multiwindow_ml(df_long, cfg, windows=[20, 80, 400])
freq_features = create_frequency_features(df_long, cfg, windows=[20, 80, 400])
agent_scores = compute_agent_scores(df_long, cfg, ml_models, freq_features)
base_scores = combine_agent_scores(agent_scores, cfg)
# V5.3.1 correction layer (regime, low-zone, inverse trend, cold-burst)
final_scores, regime_info, coldness = _adjust_scores_v5_3(df_long, cfg, base_scores)
# Last-4 repeater ban (your rule)
banned_nums = get_last4_repeater_ban(df_long, cfg)
# Optional streak guard (OFF by default):
# - allows repeats up to 3 consecutive draws
# - gently downweights numbers already on a 3-draw streak
final_scores, extra_banned = apply_streak_guard(final_scores, df_long, cfg)
banned_nums = set(banned_nums) | set(extra_banned)
# PB_TAIL_SLOT_PATCH_V1 wire
enforce_pb_tail_slot = False
if cfg.name == "Powerball" and len(df_long) >= 8:
last8 = df_long[cfg.main_cols].tail(8).values.flatten()
last8 = [int(v) for v in last8 if not pd.isna(v)]
enforce_pb_tail_slot = not any(65 <= v <= 69 for v in last8)
god_sets: List[Dict[str, object]] = []
usage_counts: Counter = Counter() # track usage across all styles
def _make_style_scores(style_name: str, scores: Dict[int, float]) -> Dict[int, float]:
"""
Per-style adjustment:
- Anti-lock rule (cap over-used numbers).
- Extra cold-burst compensation if a lock is happening.
- Micro-clustering: boost neighbors of strong numbers a bit.
"""
adjusted_style: Dict[int, float] = {}
# Detect whether any number has been used twice already
max_used = max(usage_counts.values()) if usage_counts else 0
lock_phase = (max_used >= 2)
# Precompute which numbers are "strong" for micro-clustering
vals_style = np.array(list(scores.values()), dtype=float)
if vals_style.size == 0:
return scores
vmin_s, vmax_s = float(vals_style.min()), float(vals_style.max())
thresh = vmin_s + 0.75 * (vmax_s - vmin_s) if vmax_s > vmin_s else vmin_s
strong_numbers = {n for n, s_val in scores.items() if s_val >= thresh}
for n_val, s_val in scores.items():
m_style = 1.0
used = usage_counts.get(n_val, 0)
# Anti-lock across sets
if used >= 2:
m_style *= (0.20 if (("lucky for life" in (getattr(cfg, "name", "") or "").lower()) or (int(getattr(cfg, "main_max", 0)) == 48)) else 0.25)
elif used == 1:
m_style *= (0.55 if (("lucky for life" in (getattr(cfg, "name", "") or "").lower()) or (int(getattr(cfg, "main_max", 0)) == 48)) else 0.65)
# Extra cold compensation in lock phase
if lock_phase:
c_val = coldness.get(n_val, 0.5)
m_style *= (1.0 + 0.40 * c_val)
# Micro-clustering: if this number neighbors a strong number, give it a nudge
if (n_val - 1 in strong_numbers) or (n_val + 1 in strong_numbers):
m_style *= 1.08
adjusted_style[n_val] = max(m_style * s_val, 0.0)
# Normalize to [0,1]
vals_adj_style = np.array(list(adjusted_style.values()), dtype=float)
if vals_adj_style.size == 0:
return scores
vmin_as, vmax_as = float(vals_adj_style.min()), float(vals_adj_style.max())
if vmax_as > vmin_as:
for k in adjusted_style.keys():
adjusted_style[k] = float((adjusted_style[k] - vmin_as) / (vmax_as - vmin_as))
else:
for k in adjusted_style.keys():
adjusted_style[k] = 0.5
return adjusted_style
# 1) TOP-CLUSTER combo: force highest-score core together
top_combo, top_score = generate_top_cluster_combo(
df_long,
cfg,
final_scores,
banned_nums=banned_nums,
top_n_core=3,
n_candidates=3000,
)
top_star = pick_star_ball(df_long, cfg)
god_sets.append(
{
"style": "top_cluster",
"numbers": [int(x) for x in sorted(top_combo)],
"star": int(top_star) if top_star is not None else None,
"score": float(top_score),
}
)
usage_counts.update(int(x) for x in top_combo)
# 2) Other main styles
styles = [
"balanced",
"low_cluster",
"high_cluster",
"tight_cluster",
"wide_spread",
]
for style in styles:
style_scores = _make_style_scores(style, final_scores)
combo, combo_score = generate_godmode_combo(
df_long,
cfg,
style_scores,
banned_nums=banned_nums,
n_candidates=4000,
style=style,
)
star = pick_star_ball(df_long, cfg)
god_sets.append(
{
"style": style,
"numbers": [int(x) for x in sorted(combo)],
"star": int(star) if star is not None else None,
"score": float(combo_score),
}
)
usage_counts.update(int(x) for x in combo)
# Coverage optimizer: adjust last 1–2 sets if coverage is weak
if len(god_sets) >= 4:
# Compute global coverage & high-score candidates
all_used = set()
for s_set in god_sets:
all_used.update(int(x) for x in s_set["numbers"])
# Target extra numbers: high-score but not yet used
sorted_nums = sorted(final_scores.items(), key=lambda kv: kv[1], reverse=True)
coverage_targets = [int(n) for n, sc in sorted_nums if int(n) not in all_used][:15]
def _rebuild_for_coverage(style_name: str, base_scores_cov: Dict[int, float]) -> Tuple[List[int], float]:
coverage_scores: Dict[int, float] = {}
for n_cov, s_cov in base_scores_cov.items():
m_cov = 1.0
if n_cov in coverage_targets:
m_cov *= 1.25 # strong push for uncovered high-score numbers
# small micro-cluster around coverage targets
if (n_cov - 1 in coverage_targets) or (n_cov + 1 in coverage_targets):
m_cov *= 1.08
coverage_scores[n_cov] = max(m_cov * s_cov, 0.0)
vals_cov = np.array(list(coverage_scores.values()), dtype=float)
if vals_cov.size == 0:
coverage_scores = base_scores_cov
else:
vmin_c, vmax_c = float(vals_cov.min()), float(vals_cov.max())
if vmax_c > vmin_c:
for k in coverage_scores.keys():
coverage_scores[k] = float((coverage_scores[k] - vmin_c) / (vmax_c - vmin_c))
else:
for k in coverage_scores.keys():
coverage_scores[k] = 0.5
combo_cov, score_cov = generate_godmode_combo(
df_long,
cfg,
coverage_scores,
banned_nums=banned_nums,
n_candidates=4000,
style=style_name,
)
return [int(x) for x in sorted(combo_cov)], float(score_cov)
# Rebuild last 1–2 styles for better coverage (usually tight_cluster & wide_spread)
for idx in range(len(god_sets) - 2, len(god_sets)):
style_name = god_sets[idx]["style"]
if style_name in ("tight_cluster", "wide_spread", "high_cluster"):
new_nums, new_score = _rebuild_for_coverage(style_name, final_scores)
god_sets[idx]["numbers"] = new_nums
god_sets[idx]["score"] = new_score
# Select primary combo: prefer balanced, else fall back to top_cluster
primary = next((s for s in god_sets if s["style"] == "balanced"), god_sets[0])
sorted_nums_expl = sorted(final_scores.items(), key=lambda kv: kv[1], reverse=True)
top_explain = sorted_nums_expl[:10]
explanation = {
"top_numbers": [
{"num": int(n), "score": float(round(s_val, 4))} for n, s_val in top_explain
],
"banned_last4_repeater": sorted(int(x) for x in banned_nums),
"regime": regime_info,
"usage_counts": {int(k): int(v) for k, v in usage_counts.items()},
}
# ------------------------------------------------------------
# Diversify the 5 GOD MODE sets (limit overlap)
# Goal: prevent over-concentration (e.g., 11-12-30 core in 4-5 sets).
# Applies conservatively to Gimme5 / Megabucks / Lucky for Life only.
# ------------------------------------------------------------
try:
name_l = (getattr(cfg, "name", "") or "").lower()
is_g5 = ("gimme" in name_l) or (int(getattr(cfg, "main_max", 0)) == 39)
is_mb = ("megabucks" in name_l) or (int(getattr(cfg, "main_max", 0)) == 45)
is_l4l = ("lucky for life" in name_l) or (int(getattr(cfg, "main_max", 0)) == 48)
is_la = ("lotto america" in name_l) or (int(getattr(cfg, "main_max", 0)) == 52)
if (is_g5 or is_mb or is_l4l or is_la) and len(god_sets) >= 3:
max_overlap = 1 if is_mb else 2 # MB stricter overlap; others default
main_n = int(len(cfg.main_cols))
# candidate pool by score (descending)
_pool = [int(n) for n, _sc in sorted(final_scores.items(), key=lambda kv: float(kv[1]), reverse=True)]
def _overlap(a, b) -> int:
return len(set(int(x) for x in a) & set(int(x) for x in b))
def _best_replacement(cur_nums: List[int], replace_n: int, i_set: int) -> Optional[int]:
cur_set = set(int(x) for x in cur_nums)
# prefer candidates that reduce overlap with ALL previous sets
for cand in _pool:
if cand in cur_set:
continue
if cand < int(cfg.main_min) or cand > int(cfg.main_max):
continue
trial = (cur_set - {int(replace_n)}) | {int(cand)}
ok = True
for j in range(i_set):
prev = god_sets[j].get("numbers", []) or []
if len(trial & set(int(x) for x in prev)) > max_overlap:
ok = False
break
if ok:
return int(cand)
return None
# Walk sets in order; adjust later sets to respect max_overlap vs earlier sets
for i_set in range(1, min(len(god_sets), 5)):
nums_i = [int(x) for x in (god_sets[i_set].get("numbers", []) or [])]
if len(nums_i) != main_n:
continue
# Loop until overlap is within limits (bounded attempts)
for _attempt in range(20):
worst_j = None
worst_ov = 0
for j in range(i_set):
ov = _overlap(nums_i, god_sets[j].get("numbers", []) or [])
if ov > worst_ov:
worst_ov = ov
worst_j = j
if worst_ov <= max_overlap or worst_j is None:
break
prev_nums = [int(x) for x in (god_sets[worst_j].get("numbers", []) or [])]
ov_set = sorted(set(nums_i) & set(prev_nums))
if not ov_set:
break
# Replace the weakest-overlap number (lowest final score among overlap)
replace_n = min(ov_set, key=lambda n: float(final_scores.get(int(n), 0.0)))
repl = _best_replacement(nums_i, replace_n, i_set)
if repl is None:
break
nums_i = sorted((set(nums_i) - {int(replace_n)}) | {int(repl)})
if len(nums_i) != main_n:
# if uniqueness collapsed, repair by filling with best candidates
nums_set = set(nums_i)
for cand in _pool:
if len(nums_set) >= main_n:
break
if cand in nums_set:
continue
nums_set.add(int(cand))
nums_i = sorted(list(nums_set))[:main_n]
# Save back
god_sets[i_set]["numbers"] = [int(x) for x in nums_i]
# --------------------------------------------------------
# Megabucks: add ONE "Tail Coverage" ticket to hedge regime flips
# Constraints (MB main 1-45):
# - 2 numbers from low (1-12)
# - 1 number from mid (13-29)
# - 2 numbers from high (30-45)
# Replaces the weakest-scoring GOD MODE set if needed.
# --------------------------------------------------------
if is_mb and len(god_sets) >= 5:
low_rng = range(1, 13)
mid_rng = range(13, 30)
high_rng = range(30, int(cfg.main_max) + 1)
def _sum_score(nums):
return sum(float(final_scores.get(int(x), 0.0)) for x in nums)
def _pick_from_range(rng, k, used):
picked = []
for cand in _pool:
if cand in used:
continue
if cand in rng:
picked.append(int(cand))
used.add(int(cand))
if len(picked) >= k:
break
return picked
# Build candidate tail ticket from top-scoring pool
used = set()
t_low = _pick_from_range(low_rng, 2, used)
t_high = _pick_from_range(high_rng, 2, used)
t_mid = _pick_from_range(mid_rng, 1, used)
tail_ticket = sorted(set(t_low + t_mid + t_high))
# If we couldn't meet the structure, skip (never break predictions)
if len(tail_ticket) == main_n:
def _is_tail_struct(nums):
s = set(int(x) for x in nums)
return (len(s & set(low_rng)) >= 2) and (len(s & set(high_rng)) >= 2)
# Only enforce if none of the 5 sets already provides tail coverage
already = any(_is_tail_struct(s.get("numbers", []) or []) for s in god_sets[:5])
if not already:
# Replace weakest of the 5 by sum-score
scored_sets = []
for i0 in range(5):
nums0 = god_sets[i0].get("numbers", []) or []
if len(nums0) == main_n:
scored_sets.append((i0, _sum_score(nums0)))
if scored_sets:
weakest_i = sorted(scored_sets, key=lambda x: x[1])[0][0]
god_sets[weakest_i]["numbers"] = [int(x) for x in tail_ticket]
except Exception:
# Never fail predictions due to diversification
pass
# FINAL HARD GUARD: ensure strike tickets are never identical (all games)
try:
st = result.get("strike_tickets", {})
c = st.get("collapse", {}).get("numbers", [])
n = st.get("neighbor", {}).get("numbers", [])
if c and n and set(int(x) for x in c) == set(int(x) for x in n):
# force a deterministic difference using best unused candidate
pool = [int(x) for x, _ in sorted(final_scores.items(), key=lambda kv: float(kv[1]), reverse=True)]
used = set(int(x) for x in c)
for cand in pool_local:
if cand not in used and int(cfg.main_min) <= cand <= int(cfg.main_max):
nn = list(n)
nn[-1] = int(cand)
st["neighbor"]["numbers"] = sorted(set(nn))[:len(c)]
break
except Exception:
pass
model_info = {
"numbers_modeled": len(ml_models),
"total_possible": cfg.main_max - cfg.main_min + 1,
}
# ------------------------------------------------------------
# Strike Tickets (Consensus) - GUARANTEED UNIQUE
# Provided for UI consumers (e.g., app.py) to avoid duplicates.
# ------------------------------------------------------------
# ============================================================
# PATCH PACK — post-process GOD MODE sets (toggleable)
# ============================================================
try:
_allowed_main = set(range(int(cfg.main_min), int(cfg.main_max) + 1))
_banned_main = set(banned_nums) if "banned_nums" in locals() else set()
# MM Mid-band Escape (Mega Millions) — additive only
# Forces one extra set with 3+ numbers in 30–45 band to cover "mid-high compression" draws.
if PATCH_UI_FLAGS.get("mm_midband_escape", True) and cfg.name == "Mega Millions":
try:
main_n = int(getattr(cfg, "main_n", 5))
mid_rng = list(range(30, 46))
chosen = []
# Pick top 3 mid-band numbers by score (not banned)
mid_scored = sorted(
[(n, float(final_scores.get(int(n), 0.0))) for n in mid_rng if int(n) in _allowed_main and int(n) not in _banned_main],
key=lambda t: t[1],
reverse=True,
)
for n, _sc in mid_scored:
if int(n) not in chosen:
chosen.append(int(n))
if len(chosen) >= 3:
break
# Fill remaining slots from global scores (excluding already chosen)
global_scored = sorted(final_scores.items(), key=lambda kv: kv[1], reverse=True)
for n, _sc in global_scored:
n = int(n)
if n in _banned_main or n not in _allowed_main or n in chosen:
continue
chosen.append(n)
if len(chosen) >= main_n:
break
chosen = sorted(set(chosen))[:main_n]
if len(chosen) == main_n:
star = pick_star_ball(df_long, cfg)
score = sum(float(final_scores.get(int(x), 0.0)) for x in chosen)
# Only add if not duplicate of an existing set
if not any(set(s.get("numbers", []) or []) == set(chosen) for s in god_sets):
god_sets.append(
{
"style": "midband_escape",
"numbers": [int(x) for x in chosen],
"star": int(star) if star is not None else None,
"score": float(score),
}
)
except Exception:
pass
# G5 Fusion Cluster (Gimme 5) — additive only
# Purpose: merge (a) mid-band anchor signal (14–19) with (b) core/common numbers and (c) one 20–29 band number.
# This targets draws like 14-16-18-25-31 where pieces appear across multiple sets.
if PATCH_UI_FLAGS.get("g5_fusion_cluster", True) and ("Gimme" in str(getattr(cfg, "name", "")) or str(getattr(cfg, "key", "")).lower() in ("g5","gimme5")):
try:
main_n = int(getattr(cfg, "main_n", 5))
chosen = []
# (1) Pick top 2 from mid band 14–19 by score
mid_band = list(range(14, 20))
mid_scored = sorted(
[(n, float(final_scores.get(int(n), 0.0))) for n in mid_band if int(n) in _allowed_main and int(n) not in _banned_main],
key=lambda t: t[1],
reverse=True,
)
for n, _sc in mid_scored:
if int(n) not in chosen:
chosen.append(int(n))
if len(chosen) >= 2:
break
# (2) Core/common: pick top 2 most frequent across existing god sets (excluding chosen)
freq = {}
for s in god_sets:
for n in (s.get("numbers") or []):
try:
n = int(n)
except Exception:
continue
if n in _banned_main or n not in _allowed_main:
continue
freq[n] = freq.get(n, 0) + 1
core_sorted = sorted(freq.items(), key=lambda kv: (kv[1], float(final_scores.get(int(kv[0]), 0.0))), reverse=True)
for n, _ct in core_sorted:
n = int(n)
if n in chosen:
continue
chosen.append(n)
if len(chosen) >= 4:
break
# (3) One 20–29 band number by score (excluding chosen)
band_20_29 = list(range(20, 30))
band_scored = sorted(
[(n, float(final_scores.get(int(n), 0.0))) for n in band_20_29 if int(n) in _allowed_main and int(n) not in _banned_main and int(n) not in chosen],
key=lambda t: t[1],
reverse=True,
)
for n, _sc in band_scored:
chosen.append(int(n))
break
# Fill remaining slots (if any) from global scores
global_scored = sorted(final_scores.items(), key=lambda kv: kv[1], reverse=True)
for n, _sc in global_scored:
n = int(n)
if n in _banned_main or n not in _allowed_main or n in chosen:
continue
chosen.append(n)
if len(chosen) >= main_n:
break
# Finalize
chosen = sorted(set(int(x) for x in chosen))
chosen = chosen[:main_n]
if len(chosen) == main_n:
star = None # Gimme5 has no bonus
score = sum(float(final_scores.get(int(x), 0.0)) for x in chosen)
if not any(set((s.get("numbers") or [])) == set(chosen) for s in god_sets):
god_sets.append(
{
"style": "g5_fusion_cluster",
"numbers": [int(x) for x in chosen],
"star": star,
"score": float(score),
}
)
except Exception:
pass
# L4L Mid-band Escape (Lucky for Life) — additive only
# Purpose: cover mid-high compression draws by forcing 3+ numbers from 20–40,
# then allowing one low (1–19) and one high (41–48) when scores support it.
if PATCH_UI_FLAGS.get("l4l_midband_escape", True) and ("Lucky for Life" in str(getattr(cfg, "name", "")) or str(getattr(cfg, "key", "")).lower() in ("l4l","lucky4life","lucky_for_life")):
try:
main_n = int(getattr(cfg, "main_n", 5))
chosen = []
# Prefer 3 mid-band numbers (20–40) by score
mid_rng = list(range(20, 41))
mid_scored = sorted(
[(n, float(final_scores.get(int(n), 0.0))) for n in mid_rng if int(n) in _allowed_main and int(n) not in _banned_main],
key=lambda t: t[1],
reverse=True,
)
for n, _sc in mid_scored:
if int(n) not in chosen:
chosen.append(int(n))
if len(chosen) >= 3:
break
# Add one low (1–19) by score if room
if len(chosen) < main_n:
low_rng = list(range(1, 20))
low_scored = sorted(
[(n, float(final_scores.get(int(n), 0.0))) for n in low_rng if int(n) in _allowed_main and int(n) not in _banned_main and int(n) not in chosen],
key=lambda t: t[1],
reverse=True,
)
for n, _sc in low_scored:
chosen.append(int(n))
break
# Add one high (41–48) by score if room
if len(chosen) < main_n:
high_rng = list(range(41, 49))
high_scored = sorted(
[(n, float(final_scores.get(int(n), 0.0))) for n in high_rng if int(n) in _allowed_main and int(n) not in _banned_main and int(n) not in chosen],
key=lambda t: t[1],
reverse=True,
)
for n, _sc in high_scored:
chosen.append(int(n))
break
# Fill remaining from global scores
global_scored = sorted(final_scores.items(), key=lambda kv: kv[1], reverse=True)
for n, _sc in global_scored:
n = int(n)
if n in _banned_main or n not in _allowed_main or n in chosen:
continue
chosen.append(n)
if len(chosen) >= main_n:
break
chosen = sorted(set(int(x) for x in chosen))[:main_n]
if len(chosen) == main_n:
star = pick_star_ball(df_long, cfg)
score = sum(float(final_scores.get(int(x), 0.0)) for x in chosen)
if not any(set((s.get("numbers") or [])) == set(chosen) for s in god_sets):
god_sets.append(
{
"style": "l4l_midband_escape",
"numbers": [int(x) for x in chosen],
"star": int(star) if star is not None else None,
"score": float(score),
}
)
except Exception:
pass
# LA Mid-band Escape (Lotto America) — additive only
# Purpose: force mid-band coverage similar to MM/G5/L4L escapes.
# Rules: 3 numbers from 15–40, 1 low (1–14), 1 high (41–52).
if PATCH_UI_FLAGS.get("la_midband_escape", True) and ("Lotto America" in str(getattr(cfg, "name", "")) or str(getattr(cfg, "key", "")).lower() in ("la","lottoamerica","lotto_america")):
try:
main_n = int(getattr(cfg, "main_n", 5))
chosen = []
# (1) Mid band 15–40 (pick 3)
mid_rng = list(range(15, 41))
mid_scored = sorted(
[(n, float(final_scores.get(int(n), 0.0))) for n in mid_rng if int(n) in _allowed_main and int(n) not in _banned_main],
key=lambda t: t[1],
reverse=True,
)
for n, _ in mid_scored:
chosen.append(int(n))
if len(chosen) >= 3:
break
# (2) One low 1–14
if len(chosen) < main_n:
low_rng = list(range(1, 15))
low_scored = sorted(
[(n, float(final_scores.get(int(n), 0.0))) for n in low_rng if int(n) in _allowed_main and int(n) not in _banned_main and int(n) not in chosen],
key=lambda t: t[1],
reverse=True,
)
for n, _ in low_scored:
chosen.append(int(n))
break
# (3) One high 41–52
if len(chosen) < main_n:
high_rng = list(range(41, 53))
high_scored = sorted(
[(n, float(final_scores.get(int(n), 0.0))) for n in high_rng if int(n) in _allowed_main and int(n) not in _banned_main and int(n) not in chosen],
key=lambda t: t[1],
reverse=True,
)
for n, _ in high_scored:
chosen.append(int(n))
break
# Fill remaining slots
for n, _ in sorted(final_scores.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in chosen or n in _banned_main or n not in _allowed_main:
continue
chosen.append(n)
if len(chosen) >= main_n:
break
chosen = sorted(set(chosen))[:main_n]
if len(chosen) == main_n:
star = pick_star_ball(df_long, cfg)
score = sum(float(final_scores.get(int(x), 0.0)) for x in chosen)
if not any(set((s.get("numbers") or [])) == set(chosen) for s in god_sets):
god_sets.append(
{
"style": "la_midband_escape",
"numbers": chosen,
"star": int(star) if star is not None else None,
"score": float(score),
}
)
except Exception:
pass
# Deep-low injection into Top Cluster OR Balanced (first available)
if PATCH_UI_FLAGS.get("deep_low_patch", True):
_dl_min, _dl_max = _patch_game_deep_low_range(cfg)
for _target_style in ("top_cluster", "balanced"):
for _s in god_sets:
if (_s.get("style") == _target_style) and isinstance(_s.get("numbers", None), list):
_s["numbers"] = _patch_deep_low_inject_into_set(_s["numbers"], final_scores, _allowed_main, _banned_main, _dl_min, _dl_max)
break
# Tight cluster relaxation
if PATCH_UI_FLAGS.get("tight_relax_patch", True):
for _s in god_sets:
if (_s.get("style") == "tight_cluster") and isinstance(_s.get("numbers", None), list):
_s["numbers"] = _patch_relax_tight_cluster(_s["numbers"], final_scores, _allowed_main, _banned_main, max_gap=9, max_same_decade=3)
break
except Exception:
pass
def _build_unique_strike_tickets() -> Dict[str, object]:
"""
Strike Tickets (Consensus) — GUARANTEED UNIQUE
collapse: top N numbers by (frequency-in-god-sets, score)
neighbor (ANTI-CONSENSUS HEDGE): start from collapse, then replace TWO numbers:
- one replacement pulled from the LOW tail band
- one replacement pulled from the HIGH tail band
This hedges regime flips and avoids "consensus trap".
Works for ALL games, including Powerball and Lucky for Life.
"""
main_n = int(len(cfg.main_cols))
# Count appearances across GOD MODE sets (kept for diagnostics, but collapse selection is score-first)
counts: Dict[int, int] = {}
for s in god_sets:
for n in (s.get("numbers", []) or []):
nn = int(n)
counts[nn] = counts.get(nn, 0) + 1
# Consensus = vote-count (3x → 2x → 1x) from GOD MODE sets
counts: Dict[int, int] = {}
for s in god_sets:
for n in (s.get("numbers", []) or []):
nn = int(n)
counts[nn] = counts.get(nn, 0) + 1
by_votes = {3: [], 2: [], 1: []}
for n, c in counts.items():
if c >= 3:
by_votes[3].append(n)
elif c == 2:
by_votes[2].append(n)
elif c == 1:
by_votes[1].append(n)
for k in by_votes:
by_votes[k] = sorted(by_votes[k], key=lambda x: float(final_scores.get(int(x), 0.0)), reverse=True)
collapse_nums = []
for k in (3, 2, 1):
for n in by_votes[k]:
if n not in collapse_nums:
collapse_nums.append(int(n))
if len(collapse_nums) >= main_n:
break
if len(collapse_nums) >= main_n:
break
if len(collapse_nums) < main_n:
pool = [int(n) for n, _sc in sorted(final_scores.items(), key=lambda kv: float(kv[1]), reverse=True)]
for cand in pool_local:
if cand not in collapse_nums:
collapse_nums.append(int(cand))
if len(collapse_nums) >= main_n:
break
collapse_nums = sorted(collapse_nums[:main_n])
# Pick a bonus (star / lucky ball / megaball) for strike tickets when the game has one.
# Prefer the primary (Top Cluster) star if available, else most common star across GOD sets,
# else random valid star.
collapse_star = None
try:
# primary_star exists in the outer scope of generate_prediction_v4_god
if cfg.star_col and 'primary_star' in locals() and primary_star is not None:
collapse_star = int(primary_star)
except Exception:
pass
try:
if collapse_star is None and cfg.star_col:
_sfreq = {}
for s in god_sets:
stv = s.get("star", None)
if stv is None:
continue
try:
stv = int(stv)
except Exception:
continue
_sfreq[stv] = _sfreq.get(stv, 0) + 1
if _sfreq:
collapse_star = sorted(_sfreq.items(), key=lambda kv: kv[1], reverse=True)[0][0]
except Exception:
pass
try:
if collapse_star is None and cfg.star_col and cfg.star_min is not None and cfg.star_max is not None:
collapse_star = int(cfg.star_min)
except Exception:
pass
# Candidate pool by score descending (all scored numbers) — already built above as `pool`
collapse_set = set(collapse_nums)
# Identify TWO weakest collapse numbers by score (these get replaced)
weakest_two = sorted(
collapse_nums,
key=lambda n: float(final_scores.get(int(n), 0.0))
)[:2] if len(collapse_nums) >= 2 else list(collapse_nums)
main_min = int(getattr(cfg, "main_min", 1))
main_max = int(getattr(cfg, "main_max", 99))
# Detect common games (for strike-hedge tuning)
name_l = (getattr(cfg, "name", "") or "").lower()
is_pb = ("powerball" in name_l) or (int(getattr(cfg, "main_max", 0)) == 69)
# Tail bands: dynamic by range width (with Powerball high-tail specialization)
width = max(1, main_max - main_min + 1)
if is_pb:
# Powerball main numbers 1-69: high tail is where regime flips often happen
low_lo, low_hi = main_min, min(main_max, main_min + 11) # 1-12 (available if needed)
high_lo, high_hi = max(main_min, 65), main_max # 60-69 (explicit)
else:
band = 12 if width >= 36 else max(6, int(width * 0.25))
low_lo, low_hi = main_min, min(main_max, main_min + band - 1)
high_lo, high_hi = max(main_min, main_max - band + 1), main_max
def _best_from_band(lo: int, hi: int, banned: set) -> int:
pool_local = [int(n) for n, _sc in sorted(final_scores.items(), key=lambda kv: float(kv[1]), reverse=True)]
for cand in pool_local:
if cand in banned:
continue
if lo <= cand <= hi:
return int(cand)
# fallback: best overall not banned
for cand in pool_local:
if cand not in banned and main_min <= cand <= main_max:
return int(cand)
# last resort: return something (should never happen)
return int(main_min)
neighbor_nums = list(collapse_nums)
banned = set(collapse_set)
# Replace weakest numbers with tail candidates.
# Powerball special: TWO high-tail replacements (60-69) to hedge high-tail regime flips.
if weakest_two:
w0 = int(weakest_two[0])
if is_pb:
pick0 = _best_from_band(high_lo, high_hi, banned)
else:
pick0 = _best_from_band(low_lo, low_hi, banned)
if pick0 not in banned:
try:
i = neighbor_nums.index(w0)
neighbor_nums[i] = int(pick0)
except ValueError:
neighbor_nums[-1] = int(pick0)
banned.add(int(pick0))
if len(weakest_two) >= 2:
w1 = int(weakest_two[1])
pick1 = _best_from_band(high_lo, high_hi, banned)
if pick1 not in banned:
try:
i = neighbor_nums.index(w1)
neighbor_nums[i] = int(pick1)
except ValueError:
neighbor_nums[-1] = int(pick1)
banned.add(int(pick1))
# Clean up duplicates & size
neighbor_nums = sorted(set(int(x) for x in neighbor_nums))
if len(neighbor_nums) < main_n:
for cand in pool_local:
if cand in neighbor_nums:
continue
if main_min <= int(cand) <= main_max:
neighbor_nums.append(int(cand))
if len(neighbor_nums) >= main_n:
break
neighbor_nums = sorted(neighbor_nums[:main_n])
elif len(neighbor_nums) > main_n:
neighbor_nums = sorted(neighbor_nums[:main_n])
# Final hard guard: never identical
if set(neighbor_nums) == set(collapse_nums) and neighbor_nums:
for cand in pool_local:
if cand not in collapse_set and main_min <= int(cand) <= main_max:
neighbor_nums[-1] = int(cand)
neighbor_nums = sorted(set(neighbor_nums))[:main_n]
break
neighbor_nums = sorted(neighbor_nums)
return {
"collapse": {"numbers": collapse_nums, "star": collapse_star},
"neighbor": {"numbers": neighbor_nums, "star": collapse_star},
}
# ------------------------------------------------------------
# Controlled 1-repeat logic (Gimme5 + Lucky for Life only)
# Enforce EXACTLY ONE repeat from the previous draw for:
# - Top Cluster
# - Balanced
# (Other sets remain untouched.)
# ------------------------------------------------------------
try:
_name_l = (getattr(cfg, "name", "") or "").lower()
_is_g5 = ("gimme" in _name_l) or (int(getattr(cfg, "main_max", 0)) == 39 and int(len(getattr(cfg, "main_cols", []))) == 5)
_is_l4l = ("lucky for life" in _name_l) or (int(getattr(cfg, "main_max", 0)) == 48 and int(len(getattr(cfg, "main_cols", []))) == 5)
_is_repeat_game = _is_g5 or _is_l4l
if _is_repeat_game and len(god_sets) >= 2:
# Previous draw numbers (latest completed draw in history)
_prev = []
try:
_prev = [int(df_long.iloc[-1][c]) for c in cfg.main_cols if str(df_long.iloc[-1][c]).strip() != ""]
except Exception:
_prev = []
_prev_set = set(int(x) for x in _prev if x is not None)
main_n = int(len(cfg.main_cols))
main_min = int(getattr(cfg, "main_min", 1))
main_max = int(getattr(cfg, "main_max", 99))
# Candidate pool by score (descending)
_pool = [int(n) for n, _sc in sorted(final_scores.items(), key=lambda kv: float(kv[1]), reverse=True)]
def _enforce_exactly_one_repeat(nums):
nums = [int(x) for x in (nums or [])]
if not _prev_set or len(nums) != main_n:
return sorted(nums)
overlap = sorted(set(nums) & _prev_set)
if len(overlap) == 1:
return sorted(nums)
# If 0 repeats: add best prev, drop weakest non-prev
if len(overlap) == 0:
add_cand = None
for cand in _pool:
if cand in _prev_set and main_min <= cand <= main_max and cand not in nums:
add_cand = int(cand)
break
if add_cand is None:
return sorted(nums)
droppable = [n for n in nums if n not in _prev_set] or list(nums)
drop_n = min(droppable, key=lambda n: float(final_scores.get(int(n), 0.0)))
new_set = sorted((set(nums) - {int(drop_n)}) | {int(add_cand)})
new_set = [n for n in new_set if main_min <= n <= main_max]
return sorted(new_set[:main_n]) if len(new_set) >= main_n else sorted(nums)
# If 2+ repeats: keep best repeat, replace others
keep = max(overlap, key=lambda n: float(final_scores.get(int(n), 0.0)))
kept = [n for n in nums if n not in _prev_set or n == keep]
sset = set(kept)
for cand in _pool:
if cand in _prev_set or cand in sset:
continue
if main_min <= cand <= main_max:
sset.add(int(cand))
if len(sset) >= main_n:
break
new_list = sorted(list(sset))[:main_n]
# final guard: ensure exactly one repeat
reps = sorted(set(new_list) & _prev_set)
if len(reps) == 0:
if keep not in new_list:
drop_n = min(new_list, key=lambda n: float(final_scores.get(int(n), 0.0)))
new_list = sorted((set(new_list) - {int(drop_n)}) | {int(keep)})[:main_n]
elif len(reps) > 1:
best = max(reps, key=lambda n: float(final_scores.get(int(n), 0.0)))
new_list = [n for n in new_list if n not in _prev_set or n == best]
sset = set(new_list)
for cand in _pool:
if cand in _prev_set or cand in sset:
continue
if main_min <= cand <= main_max:
sset.add(int(cand))
if len(sset) >= main_n:
break
new_list = sorted(list(sset))[:main_n]
return sorted(new_list)
# Apply to Top Cluster and Balanced only (index 0 and 1)
god_sets[0]["numbers"] = _enforce_exactly_one_repeat(god_sets[0].get("numbers", []))
god_sets[1]["numbers"] = _enforce_exactly_one_repeat(god_sets[1].get("numbers", []))
except Exception:
pass
# ------------------------------------------------------------
# Mega Millions: ONE extreme-tail hedge ticket (main only)
# Goal: reduce "total bust" nights when MM spikes into 63-70 range.
# Rule (MM main 1-70):
# - 2 numbers from 63-70
# - 1 number from 45-55
# - fill remaining with best-scoring non-used numbers
# Replaces the weakest-scoring GOD MODE set if none already provides this coverage.
# ------------------------------------------------------------
try:
_name_l = (getattr(cfg, "name", "") or "").lower()
_is_mm = ("mega" in _name_l and "mill" in _name_l) or (int(getattr(cfg, "main_max", 0)) == 70 and int(len(getattr(cfg, "main_cols", []))) == 5)
if _is_mm and len(god_sets) >= 5:
main_n = int(len(cfg.main_cols))
main_min = int(getattr(cfg, "main_min", 1))
main_max = int(getattr(cfg, "main_max", 70))
hi_tail = range(max(main_min, 63), main_max + 1) # 63-70
mid_hi = range(max(main_min, 45), min(main_max, 55) + 1) # 45-55
_pool = [int(n) for n, _sc in sorted(final_scores.items(), key=lambda kv: float(kv[1]), reverse=True)]
def _sum_score(nums):
return sum(float(final_scores.get(int(x), 0.0)) for x in nums)
def _pick_from(rng, k, used):
picked = []
for cand in _pool:
if cand in used:
continue
if cand in rng and main_min <= cand <= main_max:
picked.append(int(cand))
used.add(int(cand))
if len(picked) >= k:
break
return picked
def _mm_tail_ok(nums):
s = set(int(x) for x in nums)
return (len(s & set(hi_tail)) >= 2) and (len(s & set(mid_hi)) >= 1)
already = any(_mm_tail_ok(s.get("numbers", []) or []) for s in god_sets[:5])
if not already:
used = set()
a = _pick_from(hi_tail, 2, used)
b = _pick_from(mid_hi, 1, used)
tail_ticket = list(a + b)
for cand in _pool:
if cand in used:
continue
if main_min <= cand <= main_max:
tail_ticket.append(int(cand))
used.add(int(cand))
if len(tail_ticket) >= main_n:
break
tail_ticket = sorted(set(tail_ticket))
if len(tail_ticket) == main_n and _mm_tail_ok(tail_ticket):
scored = []
for i0 in range(5):
nums0 = god_sets[i0].get("numbers", []) or []
if len(nums0) == main_n:
scored.append((i0, _sum_score(nums0)))
if scored:
weakest_i = sorted(scored, key=lambda x: x[1])[0][0]
god_sets[weakest_i]["numbers"] = [int(x) for x in tail_ticket]
except Exception:
pass
# ------------------------------------------------------------
# Megabucks: ONE upper-tail hedge ticket (main only)
# Goal: reduce "total bust" nights when MB spikes into 37-41 range.
# Rule (MB main 1-41):
# - 1 number from 37-41 (upper tail)
# - 1 number from 25-32 (upper-mid)
# - fill remaining with best-scoring non-used numbers
# Replaces the weakest-scoring GOD MODE set if none already provides this coverage.
# ------------------------------------------------------------
try:
_name_l = (getattr(cfg, "name", "") or "").lower()
_key_l = (getattr(cfg, "key", "") or "").lower()
_is_mb = ("megabuck" in _name_l) or (_key_l == "mb") or (
int(getattr(cfg, "main_max", 0)) == 41 and int(len(getattr(cfg, "main_cols", []))) == 5
)
if _is_mb and len(god_sets) >= 5:
main_n = int(len(cfg.main_cols))
main_min = int(getattr(cfg, "main_min", 1))
main_max = int(getattr(cfg, "main_max", 41))
upper_tail = range(max(main_min, 37), main_max + 1) # 37-41
upper_mid = range(max(main_min, 25), min(main_max, 32) + 1) # 25-32
_pool = [int(n) for n, _sc in sorted(final_scores.items(),
key=lambda kv: float(kv[1]),
reverse=True)]
def _sum_score(nums):
return sum(float(final_scores.get(int(x), 0.0)) for x in nums)
def _pick_from(rng, k, used):
picked = []
for cand in _pool:
if cand in used:
continue
if cand in rng and main_min <= cand <= main_max:
picked.append(int(cand))
used.add(int(cand))
if len(picked) >= k:
break
return picked
def _mb_tail_ok(nums):
s = set(int(x) for x in (nums or []))
return (len(s & set(upper_tail)) >= 1) and (len(s & set(upper_mid)) >= 1)
already = any(_mb_tail_ok(s.get("numbers", []) or []) for s in god_sets[:5])
if not already:
used = set()
a = _pick_from(upper_tail, 1, used)
b = _pick_from(upper_mid, 1, used)
tail_ticket = list(a + b)
for cand in _pool:
if cand in used:
continue
if main_min <= cand <= main_max:
tail_ticket.append(int(cand))
used.add(int(cand))
if len(tail_ticket) >= main_n:
break
tail_ticket = sorted(set(tail_ticket))
if len(tail_ticket) == main_n and _mb_tail_ok(tail_ticket):
scored = []
for i0 in range(5):
nums0 = god_sets[i0].get("numbers", []) or []
if len(nums0) == main_n:
scored.append((i0, _sum_score(nums0)))
if scored:
weakest_i = sorted(scored, key=lambda x: x[1])[0][0]
god_sets[weakest_i]["numbers"] = [int(x) for x in tail_ticket]
except Exception:
pass
# ------------------------------------------------------------
# Lotto America: ONE upper-tail hedge ticket (main only)
# Goal: reduce bust nights when LA spikes into 38-47 range.
# Rule (LA main 1-52):
# - 1 number from 38-47 (upper tail)
# - 1 number from 25-33 (upper-mid)
# - fill remaining with best-scoring non-used numbers
# Replaces the weakest-scoring GOD MODE set if none already provides this coverage.
# ------------------------------------------------------------
try:
_name_l = (getattr(cfg, "name", "") or "").lower()
_key_l = (getattr(cfg, "key", "") or "").lower()
_is_la = ("lotto america" in _name_l) or (_key_l == "la") or (
int(getattr(cfg, "main_max", 0)) == 52 and int(len(getattr(cfg, "main_cols", []))) == 5
)
if _is_la and bool(PATCH_UI_FLAGS.get("la_upper_tail_escape", True)) and len(god_sets) >= 5:
main_n = int(len(cfg.main_cols))
main_min = int(getattr(cfg, "main_min", 1))
main_max = int(getattr(cfg, "main_max", 52))
upper_tail = range(max(main_min, 38), min(main_max, 47) + 1) # 38-47
upper_mid = range(max(main_min, 25), min(main_max, 33) + 1) # 25-33
_pool = [int(n) for n, _sc in sorted(
final_scores.items(),
key=lambda kv: float(kv[1]),
reverse=True
)]
def _sum_score(nums):
return sum(float(final_scores.get(int(x), 0.0)) for x in nums)
def _pick_from(rng, k, used):
picked = []
for cand in _pool:
if cand in used:
continue
if cand in rng and main_min <= cand <= main_max:
picked.append(int(cand))
used.add(int(cand))
if len(picked) >= k:
break
return picked
def _la_tail_ok(nums):
s = set(int(x) for x in (nums or []))
return (len(s & set(upper_tail)) >= 1) and (len(s & set(upper_mid)) >= 1)
already = any(_la_tail_ok(s.get("numbers", []) or []) for s in god_sets[:5])
if not already:
used = set()
a = _pick_from(upper_tail, 1, used)
b = _pick_from(upper_mid, 1, used)
tail_ticket = list(a + b)
for cand in _pool:
if cand in used:
continue
if main_min <= cand <= main_max:
tail_ticket.append(int(cand))
used.add(int(cand))
if len(tail_ticket) >= main_n:
break
tail_ticket = sorted(set(tail_ticket))
if len(tail_ticket) == main_n and _la_tail_ok(tail_ticket):
scored = []
for i0 in range(5):
nums0 = god_sets[i0].get("numbers", []) or []
if len(nums0) == main_n:
scored.append((i0, _sum_score(nums0)))
if scored:
weakest_i = sorted(scored, key=lambda x: x[1])[0][0]
god_sets[weakest_i]["numbers"] = [int(x) for x in tail_ticket]
except Exception:
pass
strike_tickets = _build_unique_strike_tickets()
# ============================================================
# ============================================================
# PATCH PACK — Wildcard profile strike (main numbers only)
# (Syntax-safe, no outer try/except)
# ============================================================
if PATCH_UI_FLAGS.get("wildcard_strike", True):
_allowed_main = set(range(int(cfg.main_min), int(cfg.main_max) + 1))
_banned_main = set(banned_nums) if "banned_nums" in locals() else set()
wc = _patch_make_wildcard_profile_ticket(god_sets, final_scores, _allowed_main, _banned_main, cfg)
if wc:
# Choose wildcard bonus/star from the most common star used in GOD MODE sets (PB/MB/etc.)
wc_star = None
if getattr(cfg, "star_col", None) and getattr(cfg, "star_min", None) is not None and getattr(cfg, "star_max", None) is not None:
stars = []
for _s in (god_sets or []):
_sv = _s.get("star", None) if isinstance(_s, dict) else None
if _sv is not None:
stars.append(int(_sv))
# also consider strike ticket stars if present
for _k, _v in (strike_tickets or {}).items():
if isinstance(_v, dict) and _v.get("star", None) is not None:
stars.append(int(_v["star"]))
if stars:
wc_star = Counter(stars).most_common(1)[0][0]
wc_star = max(int(cfg.star_min), min(int(cfg.star_max), int(wc_star)))
strike_tickets["WILDCARD PROFILE"] = {"numbers": [int(x) for x in wc], "star": wc_star}
# Controlled 1-repeat for CONSENSUS COLLAPSE (Gimme5 + Lucky for Life only)
try:
_name_l = (getattr(cfg, "name", "") or "").lower()
_is_g5 = ("gimme" in _name_l) or (int(getattr(cfg, "main_max", 0)) == 39 and int(len(getattr(cfg, "main_cols", []))) == 5)
_is_l4l = ("lucky for life" in _name_l) or (int(getattr(cfg, "main_max", 0)) == 48 and int(len(getattr(cfg, "main_cols", []))) == 5)
_is_repeat_game = _is_g5 or _is_l4l
if _is_repeat_game and isinstance(strike_tickets, dict) and "collapse" in strike_tickets:
_prev = []
try:
_prev = [int(df_long.iloc[-1][c]) for c in cfg.main_cols if str(df_long.iloc[-1][c]).strip() != ""]
except Exception:
_prev = []
_prev_set = set(int(x) for x in _prev if x is not None)
nums = strike_tickets.get("collapse", {}).get("numbers", []) or []
nums = [int(x) for x in nums]
main_n = int(len(cfg.main_cols))
if _prev_set and len(nums) == main_n:
overlap = sorted(set(nums) & _prev_set)
pool = [int(n) for n, _sc in sorted(final_scores.items(), key=lambda kv: float(kv[1]), reverse=True)]
if len(overlap) == 0:
add_cand = None
for cand in pool:
if cand in _prev_set and cand not in nums:
add_cand = int(cand)
break
if add_cand is not None:
drop_n = min(nums, key=lambda n: float(final_scores.get(int(n), 0.0)))
nums2 = sorted((set(nums) - {int(drop_n)}) | {int(add_cand)})
strike_tickets["collapse"]["numbers"] = nums2[:main_n]
elif len(overlap) > 1:
keep = max(overlap, key=lambda n: float(final_scores.get(int(n), 0.0)))
kept = [n for n in nums if n not in _prev_set or n == keep]
sset = set(kept)
for cand in pool:
if cand in _prev_set or cand in sset:
continue
sset.add(int(cand))
if len(sset) >= main_n:
break
strike_tickets["collapse"]["numbers"] = sorted(list(sset))[:main_n]
except Exception:
pass
# ------------------------------------------------------------
# PB FUSION CLUSTER (ADDITIVE ONLY)
# One extra GOD MODE set that fuses consensus + near-consensus numbers
# to force co-occurrence of strong-but-separated signals.
# ------------------------------------------------------------
try:
pb_fusion_on = PATCH_UI_FLAGS.get("pb_fusion_cluster", True) if isinstance(globals().get("PATCH_UI_FLAGS", None), dict) else True
except Exception:
pb_fusion_on = True
try:
is_pb_local = (str(getattr(cfg, "key", "")).lower() == "pb") or ("powerball" in str(getattr(cfg, "name", "")).lower())
except Exception:
is_pb_local = False
if pb_fusion_on and is_pb_local:
try:
c_nums = [int(x) for x in (strike_tickets.get("collapse", {}).get("numbers", []) or [])]
n_nums = [int(x) for x in (strike_tickets.get("neighbor", {}).get("numbers", []) or [])]
if c_nums:
cset, nset = set(c_nums), set(n_nums)
union = list(cset | nset)
both = cset & nset
def _rank(n: int):
return (1 if n in both else 0, float(final_scores.get(int(n), 0.0)))
union_sorted = sorted(union, key=_rank, reverse=True)
fusion_nums = []
for n in union_sorted:
if int(getattr(cfg, "main_min", 1)) <= int(n) <= int(getattr(cfg, "main_max", 99)):
fusion_nums.append(int(n))
if len(fusion_nums) >= int(getattr(cfg, "main_n", 5)):
break
# If still short, fill from global scores
if len(fusion_nums) < int(getattr(cfg, "main_n", 5)):
pool = sorted(final_scores.items(), key=lambda kv: float(kv[1]), reverse=True)
for cand, _sc in pool:
cand = int(cand)
if cand not in fusion_nums and int(getattr(cfg, "main_min", 1)) <= cand <= int(getattr(cfg, "main_max", 99)):
fusion_nums.append(cand)
if len(fusion_nums) >= int(getattr(cfg, "main_n", 5)):
break
fusion_nums = sorted(fusion_nums)[: int(getattr(cfg, "main_n", 5))]
# Bonus: reuse collapse star if available; else primary
fusion_star = strike_tickets.get("collapse", {}).get("star", None)
if fusion_star is None:
fusion_star = primary.get("star", None)
# Prevent duplicates: only add if not identical to an existing set
existing = [set(int(x) for x in (s.get("numbers", []) or [])) for s in god_sets]
if set(fusion_nums) not in existing:
fusion_score = float(sum(float(final_scores.get(int(x), 0.0)) for x in fusion_nums))
god_sets.append({
"style": "fusion_cluster",
"numbers": fusion_nums,
"star": int(fusion_star) if fusion_star is not None else None,
"score": fusion_score,
})
except Exception:
pass
# -------------------------
# PATCH: POOL12 + +1 DRIFT ticket (safe, additive only)
# -------------------------
pool12 = None
try:
# Build a 12-number pool to expose in the UI (your console "POOL12")
# Priority: numbers that appear across primary + GOD MODE + consensus tickets,
# then fill by score.
from collections import Counter as _Counter
_cand_lists = []
try:
_cand_lists.append(list(primary.get("numbers") or []))
except Exception:
pass
try:
_cand_lists.extend([list(s.get("numbers") or []) for s in (god_sets or [])])
except Exception:
pass
try:
if isinstance(strike_tickets, dict):
for _k in ("collapse", "neighbor", "neighbor", "consensus_collapse", "consensus_neighbor"):
tk = strike_tickets.get(_k)
if isinstance(tk, dict):
_cand_lists.append(list(tk.get("numbers") or []))
except Exception:
pass
_freq = _Counter()
for _lst in _cand_lists:
for _x in (_lst or []):
try:
_freq[int(_x)] += 1
except Exception:
continue
_main_min = int(getattr(cfg, "main_min", 1))
_main_max = int(getattr(cfg, "main_max", 99))
_banned = set(int(x) for x in (banned_nums or []) if x is not None)
def _ok(n: int) -> bool:
return (_main_min <= int(n) <= _main_max) and (int(n) not in _banned)
# Seed pool by co-occurrence (freq desc) then score desc
_seed = [int(n) for n, _c in sorted(_freq.items(), key=lambda kv: (int(kv[1]), float(final_scores.get(int(kv[0]), 0.0))), reverse=True) if _ok(int(n))]
_score_sorted = [int(n) for n, _s in sorted(final_scores.items(), key=lambda kv: float(kv[1]), reverse=True) if _ok(int(n))]
_pool = []
for n in _seed + _score_sorted:
if n not in _pool and _ok(n):
_pool.append(int(n))
if len(_pool) >= 12:
break
pool12 = _pool[:12] if len(_pool) >= 12 else _pool
# -------------------------
# PATCH: POOL12 "Recent-12 Stats" mode (Hot / Due / Cold) — additive only
# Idea:
# - 4 HOT: >=25% appearance in last 12 draws (>=3 when window=12)
# - 4 DUE: seen in last 12 and current gap >= its historical avg gap
# - 4 COLD: not seen at all in last 12
# Falls back to the existing POOL12 builder if anything fails.
try:
_use_recent12_stats = getattr(cfg, "pool12_recent12_stats", True)
if _use_recent12_stats and "df" in locals():
_w = min(12, int(len(df)))
if _w > 0:
_recent_df = df.tail(_w)
# recent frequency across main columns
from collections import Counter as _Counter2
_recent_nums = []
for _c in (cfg.main_cols or []):
try:
_recent_nums.extend([int(x) for x in _recent_df[_c].dropna().tolist()])
except Exception:
pass
_rc = _Counter2([int(x) for x in _recent_nums if _ok(int(x))])
import math
_hot_thresh = max(1, int(math.ceil(0.25 * _w)))
_hot_candidates = [n for n, c in _rc.items() if int(c) >= _hot_thresh and _ok(int(n))]
_hot4 = sorted(_hot_candidates, key=lambda n: (int(_rc.get(int(n), 0)), float(final_scores.get(int(n), 0.0))), reverse=True)[:4]
# build occurrences for avg-gap + current-gap, one pass
_total_rows = int(len(df))
_occ = {}
try:
_vals = df[cfg.main_cols].values.tolist()
for _ri, _row in enumerate(_vals):
for _x in _row:
try:
if _x is None:
continue
_n = int(_x)
if not _ok(_n):
continue
_occ.setdefault(_n, []).append(int(_ri))
except Exception:
continue
except Exception:
_occ = {}
# "Due" among numbers seen in last 12: current_gap >= avg_gap
_due_scored = []
for _n in list(_rc.keys()):
_n = int(_n)
if not _ok(_n) or _n in _hot4:
continue
_idxs = _occ.get(_n, [])
if not _idxs:
continue
if len(_idxs) >= 2:
_gaps = [int(_idxs[i]) - int(_idxs[i-1]) for i in range(1, len(_idxs))]
_avg_gap = float(sum(_gaps) / max(len(_gaps), 1))
else:
# fallback: expected interval ~ total/frequency
_avg_gap = float(_total_rows / max(len(_idxs), 1))
_current_gap = float((_total_rows - 1) - int(_idxs[-1]))
if _avg_gap <= 0:
continue
if _current_gap + 1e-9 >= _avg_gap:
_ratio = float(_current_gap / _avg_gap)
_due_scored.append((_n, _ratio, float(final_scores.get(_n, 0.0))))
_due4 = [int(n) for n, _r, _s in sorted(_due_scored, key=lambda x: (float(x[1]), float(x[2])), reverse=True)[:4]]
# cold: not seen at all in last 12
_cold_candidates = [n for n in range(_main_min, _main_max + 1) if _ok(int(n)) and int(n) not in _rc]
_cold4 = [int(n) for n in sorted(_cold_candidates, key=lambda n: float(final_scores.get(int(n), 0.0)), reverse=True)[:4]]
_pool12_new = []
for _n in (_hot4 + _due4 + _cold4):
if int(_n) not in _pool12_new and _ok(int(_n)):
_pool12_new.append(int(_n))
# fill remaining slots with the existing pool (seed/score based)
for _n in list(pool12 or []):
if len(_pool12_new) >= 12:
break
if int(_n) not in _pool12_new and _ok(int(_n)):
_pool12_new.append(int(_n))
pool12 = _pool12_new[:12] if len(_pool12_new) > 0 else pool12
except Exception:
pass
except Exception:
pool12 = None
try:
# +1 drift hedge ticket (main + bonus), wrapped into range, duplicates resolved.
_mn = int(getattr(cfg, "main_min", 1))
_mx = int(getattr(cfg, "main_max", 99))
_base = [int(x) for x in (primary.get("numbers") or [])]
_drift = []
for x in _base:
y = int(x) + 1
if y > _mx:
y = _mn
# resolve duplicates by stepping forward
while y in _drift:
y += 1
if y > _mx:
y = _mn
_drift.append(int(y))
_drift = sorted(_drift)[:len(getattr(cfg, "main_cols", [])) or 5]
_star = primary.get("star", None)
_drift_star = None
if _star is not None and getattr(cfg, "star_min", None) is not None and getattr(cfg, "star_max", None) is not None:
try:
smin, smax = int(cfg.star_min), int(cfg.star_max)
_drift_star = int(_star) + 1
if _drift_star > smax:
_drift_star = smin
except Exception:
_drift_star = None
drift_plus1 = {"numbers": _drift, "star": _drift_star}
if isinstance(strike_tickets, dict):
strike_tickets["drift_plus1"] = drift_plus1
except Exception:
pass
# -------------------------
# PATCH: Lucky for Life LOW+HIGH Hybrid Hedge (safe, additive only)
# Trigger:
# - collapse ticket has <2 LOW numbers (1–9)
# - last actual draw contains a HIGH-TAIL number (>=42)
# Action:
# - add one hybrid ticket that forces 2 LOW (1–9) + 1 MID (10–29) + 2 HIGH (>=30, incl >=42)
# - also surfaces the ticket to the UI via strike_tickets
# -------------------------
try:
_name_l = (getattr(cfg, "name", "") or "").lower()
_is_l4l = ("lucky for life" in _name_l) or (str(getattr(cfg, "key", "")).lower() in ("l4l", "lucky4life", "lucky_for_life")) or (int(getattr(cfg, "main_max", 0)) == 48)
if _is_l4l and isinstance(strike_tickets, dict):
main_min = int(getattr(cfg, "main_min", 1))
main_max = int(getattr(cfg, "main_max", 48))
# last draw signal (tail active)
_last = []
try:
_last = [int(df_long.iloc[-1][c]) for c in cfg.main_cols if str(df_long.iloc[-1][c]).strip() != ""]
except Exception:
_last = []
_tail_active = any(int(x) >= 42 for x in (_last or []))
cnums = [int(x) for x in (strike_tickets.get("collapse", {}) or {}).get("numbers", []) or []]
low_in_collapse = [x for x in cnums if 1 <= int(x) <= 9]
if _tail_active and len(low_in_collapse) < 2:
# candidate ranking pool
_scored = [int(n) for n, _v in sorted(final_scores.items(), key=lambda kv: float(kv[1]), reverse=True)]
_banned = set(int(x) for x in (banned_nums or []) if x is not None)
def _pick(rng_min, rng_max, k, used):
out = []
for cand in _scored:
cand = int(cand)
if cand in used or cand in _banned:
continue
if rng_min <= cand <= rng_max:
out.append(cand)
used.add(cand)
if len(out) >= k:
break
return out
used = set()
lows = _pick(1, 9, 2, used)
mids = _pick(10, 29, 1, used)
# one must be in tail band if possible
tail = _pick(42, main_max, 1, used)
highs = _pick(30, main_max, 2 - len(tail), used)
hybrid = sorted(set(lows + mids + tail + highs))
# repair if short (never break)
if len(hybrid) < int(len(cfg.main_cols) or 5):
for cand in _scored:
cand = int(cand)
if cand in used or cand in _banned:
continue
if main_min <= cand <= main_max:
hybrid.append(cand)
used.add(cand)
if len(set(hybrid)) >= int(len(cfg.main_cols) or 5):
break
hybrid = sorted(set(hybrid))[: int(len(cfg.main_cols) or 5)]
if len(hybrid) == int(len(cfg.main_cols) or 5):
# star: prefer collapse star if present
_h_star = (strike_tickets.get("collapse", {}) or {}).get("star", None)
if _h_star is None:
_h_star = primary.get("star", None)
strike_tickets["l4l_low_high_hybrid"] = {"numbers": [int(x) for x in hybrid], "star": int(_h_star) if _h_star is not None else None}
except Exception:
pass
# -------------------------
# PATCH: Mega Millions hedges (safe, additive only)
# - Anti-core hedge ticket
# - Shape hedge (2 low / 2 mid / 1 high)
# - Cold Megaball hedge (star 1-6)
# -------------------------
try:
if cfg.name == "Mega Millions" and isinstance(strike_tickets, dict):
# Build frequency map across GOD MODE sets to detect "locked core"
from collections import Counter as _Counter
_freq = _Counter()
try:
for _s in (god_sets or []):
_freq.update([int(x) for x in (_s.get("numbers") or [])])
except Exception:
pass
# Core = top 2 most frequent numbers (tie-broken by score)
_sc = {int(k): float(v) for k, v in (final_scores or {}).items()}
_core = [n for n, _c in sorted(_freq.items(), key=lambda kv: (kv[1], _sc.get(int(kv[0]), 0.0)), reverse=True)[:2]]
# Candidate pool preference: pool12 -> otherwise top scored list
_cand = []
try:
if pool12:
_cand = [int(x) for x in pool12]
except Exception:
_cand = []
if not _cand:
_cand = [int(x) for x, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True)[:30]]
def _pick_from_band(band_min, band_max, k, exclude):
picked = []
for n in _cand:
n = int(n)
if n in exclude:
continue
if band_min <= n <= band_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
# If not enough, fill from scored range within band
if len(picked) < k:
for n, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in exclude:
continue
if band_min <= n <= band_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
return picked
def _fill_any(k, exclude, main_min, main_max):
picked = []
# Prefer remaining candidates then fall back to full range by score
for n in _cand:
n = int(n)
if n in exclude:
continue
if main_min <= n <= main_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
if len(picked) < k:
for n, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in exclude:
continue
if main_min <= n <= main_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
return picked
main_min = int(cfg.main_min); main_max = int(cfg.main_max)
# 1) Anti-core hedge: exclude core numbers and build a balanced-ish ticket
_ex = set(_core)
anti = []
anti += _pick_from_band(1, 14, 2, _ex) # low
anti += _pick_from_band(15, 45, 2, _ex) # mid
anti += _pick_from_band(46, 70, 1, _ex) # high
if len(anti) < 5:
anti += _fill_any(5 - len(anti), _ex, main_min, main_max)
anti = sorted(set(anti))[:5]
# ensure exactly 5 (in case of dedupe)
if len(anti) < 5:
_tmp_ex = set(anti) | set(_core)
anti += _fill_any(5 - len(anti), _tmp_ex, main_min, main_max)
anti = sorted(set(anti))[:5]
# 2) Shape hedge (2 low / 2 mid / 1 high) — not excluding core (coverage ticket)
_ex2 = set()
shape = []
shape += _pick_from_band(1, 14, 2, _ex2)
shape += _pick_from_band(15, 45, 2, _ex2)
shape += _pick_from_band(46, 70, 1, _ex2)
if len(shape) < 5:
shape += _fill_any(5 - len(shape), _ex2, main_min, main_max)
shape = sorted(set(shape))[:5]
if len(shape) < 5:
_tmp_ex = set(shape)
shape += _fill_any(5 - len(shape), _tmp_ex, main_min, main_max)
shape = sorted(set(shape))[:5]
# 3) Cold Megaball hedge: reuse collapse numbers if present but force cold star (1–6)
cold_star = None
try:
smin, smax = int(cfg.star_min), int(cfg.star_max)
cold_hi = min(smax, max(smin, 6))
cold_star = random.choice(list(range(smin, cold_hi + 1)))
except Exception:
cold_star = None
base_nums = []
try:
base_nums = [int(x) for x in (strike_tickets.get("collapse", {}).get("numbers") or [])]
except Exception:
base_nums = []
if not base_nums:
try:
base_nums = [int(x) for x in (primary.get("numbers") or [])]
except Exception:
base_nums = []
strike_tickets["mm_anti_core"] = {"numbers": anti, "star": strike_tickets.get("collapse", {}).get("star")}
strike_tickets["mm_shape_2low2mid1high"] = {"numbers": shape, "star": strike_tickets.get("collapse", {}).get("star")}
strike_tickets["mm_cold_megaball"] = {"numbers": sorted(set(base_nums))[:5], "star": cold_star}
except Exception:
pass
# -------------------------
# PATCH: Powerball hedges (safe, additive only)
# - Anti-core hedge ticket
# - Shape hedge (2 low / 2 mid / 1 high)
# - Cold Powerball hedge (star 1-6)
# -------------------------
try:
if cfg.name == "Powerball" and isinstance(strike_tickets, dict):
from collections import Counter as _Counter
_freq = _Counter()
try:
for _s in (god_sets or []):
_freq.update([int(x) for x in (_s.get("numbers") or [])])
except Exception:
pass
_sc = {int(k): float(v) for k, v in (final_scores or {}).items()}
_core = [n for n, _c in sorted(_freq.items(), key=lambda kv: (kv[1], _sc.get(int(kv[0]), 0.0)), reverse=True)[:2]]
_cand = []
try:
if pool12:
_cand = [int(x) for x in pool12]
except Exception:
_cand = []
if not _cand:
_cand = [int(x) for x, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True)[:30]]
main_min = int(getattr(cfg, "main_min", 1) or 1)
main_max = int(getattr(cfg, "main_max", 69) or 69)
def _pick_from_band(band_min, band_max, k, exclude):
picked = []
for n in _cand:
n = int(n)
if n in exclude:
continue
if band_min <= n <= band_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
if len(picked) < k:
for n, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in exclude:
continue
if band_min <= n <= band_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
return picked
def _fill_any(k, exclude):
picked = []
for n in _cand:
n = int(n)
if n in exclude:
continue
if main_min <= n <= main_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
if len(picked) < k:
for n, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in exclude:
continue
if main_min <= n <= main_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
return picked
# --- Anti-core hedge (avoid the 2 most overused numbers) ---
ex = set(_core)
anti = _fill_any(5, ex)
anti = sorted(set(int(x) for x in anti))[:5]
if len(anti) == 5:
strike_tickets["pb_anti_core"] = {"numbers": anti, "star": strike_tickets.get("collapse", {}).get("star")}
# --- Shape hedge: 2 low (1-14), 2 mid (15-45), 1 high (46-main_max) ---
ex = set()
low = _pick_from_band(main_min, min(14, main_max), 2, ex)
mid = _pick_from_band(15, min(45, main_max), 2, ex)
high = _pick_from_band(46, main_max, 1, ex) if main_max >= 46 else []
shape = sorted(set(low + mid + high))
# Ensure 5
if len(shape) < 5:
shape = sorted(set(shape + _fill_any(5 - len(shape), set(shape))))
shape = sorted(shape)[:5]
# If shape duplicates collapse, tweak one number (prefer swapping in a different high/mid)
try:
_collapse_nums = [int(x) for x in (strike_tickets.get("collapse", {}).get("numbers") or [])]
except Exception:
_collapse_nums = []
if _collapse_nums and sorted(_collapse_nums) == shape:
ex2 = set(shape)
# try swap highest number first
replaced = False
for band_min, band_max in [(46, main_max), (15, min(45, main_max)), (main_min, min(14, main_max))]:
cand_rep = _pick_from_band(band_min, band_max, 1, ex2)
if cand_rep:
# replace last element (highest) with new candidate
shape2 = sorted(set(shape[:-1] + cand_rep))
if len(shape2) == 5 and shape2 != shape:
shape = shape2
replaced = True
break
if not replaced:
pass
if len(shape) == 5:
strike_tickets["pb_shape_2low2mid1high"] = {"numbers": shape, "star": strike_tickets.get("collapse", {}).get("star")}
# --- Cold Powerball hedge: same best core numbers, but PB in 1-6 ---
try:
base_nums = strike_tickets.get("collapse", {}).get("numbers") or strike_tickets.get("neighbor", {}).get("numbers") or primary.get("numbers") or []
base_nums = [int(x) for x in base_nums][:5]
pb_star = random.choice([1, 2, 3, 4, 5, 6])
strike_tickets["pb_cold_powerball"] = {"numbers": sorted(set(base_nums))[:5], "star": pb_star}
except Exception:
pass
except Exception:
pass
# -------------------------
# PATCH: Megabucks hedges (safe, additive only)
# - Anti-core hedge ticket
# - Shape hedge (2 low / 2 mid / 1 high)
# - Cold Megaball hedge (Megaball 1–6, prefer cold 1–2)
# -------------------------
try:
if cfg.name == "Megabucks" and isinstance(strike_tickets, dict):
from collections import Counter as _Counter
_freq = _Counter()
try:
for _s in (god_sets or []):
_freq.update([int(x) for x in (_s.get("numbers") or [])])
except Exception:
pass
_sc = {int(k): float(v) for k, v in (final_scores or {}).items()}
# Core = top 2 most frequent numbers (tie-broken by score)
_core = [n for n, _c in sorted(_freq.items(), key=lambda kv: (kv[1], _sc.get(int(kv[0]), 0.0)), reverse=True)[:2]]
# Candidate pool: pool12 first, else top scored list
_cand = []
try:
if pool12:
_cand = [int(x) for x in pool12]
except Exception:
_cand = []
if not _cand:
_cand = [int(x) for x, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True)[:30]]
main_min = int(cfg.main_min); main_max = int(cfg.main_max)
# Bands for Megabucks main range (1–41)
low_lo, low_hi = main_min, min(main_max, 14)
mid_lo, mid_hi = min(main_max, 15), min(main_max, 28)
high_lo, high_hi = min(main_max, 29), main_max
def _pick_from_band(band_min, band_max, k, exclude):
picked = []
for n in _cand:
n = int(n)
if n in exclude:
continue
if band_min <= n <= band_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
if len(picked) < k:
for n, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in exclude:
continue
if band_min <= n <= band_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
return picked
def _fill_any(k, exclude):
picked = []
for n in _cand:
n = int(n)
if n in exclude:
continue
if main_min <= n <= main_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
if len(picked) < k:
for n, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in exclude:
continue
if main_min <= n <= main_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
return picked
# 1) Anti-core hedge: exclude core numbers, build 2 low / 2 mid / 1 high
_ex = set(_core)
anti = []
anti += _pick_from_band(low_lo, low_hi, 2, _ex)
anti += _pick_from_band(mid_lo, mid_hi, 2, _ex)
anti += _pick_from_band(high_lo, high_hi, 1, _ex)
if len(anti) < 5:
anti += _fill_any(5 - len(anti), _ex)
anti = sorted(set(anti))[:5]
if len(anti) < 5:
_tmp_ex = set(anti) | set(_core)
anti += _fill_any(5 - len(anti), _tmp_ex)
anti = sorted(set(anti))[:5]
# 2) Shape hedge: 2 low / 2 mid / 1 high (coverage)
_ex2 = set()
shape = []
shape += _pick_from_band(low_lo, low_hi, 2, _ex2)
shape += _pick_from_band(mid_lo, mid_hi, 2, _ex2)
shape += _pick_from_band(high_lo, high_hi, 1, _ex2)
if len(shape) < 5:
shape += _fill_any(5 - len(shape), _ex2)
shape = sorted(set(shape))[:5]
if len(shape) < 5:
_tmp_ex = set(shape)
shape += _fill_any(5 - len(shape), _tmp_ex)
shape = sorted(set(shape))[:5]
# 3) Cold Megaball hedge: reuse collapse numbers if present but force cold megaball (1–2)
mb_star = None
try:
smin, smax = int(cfg.star_min), int(cfg.star_max)
cold_hi = min(smax, max(smin, 2))
mb_star = random.choice(list(range(smin, cold_hi + 1)))
except Exception:
mb_star = None
base_nums = []
try:
base_nums = [int(x) for x in (strike_tickets.get("collapse", {}).get("numbers") or [])]
except Exception:
base_nums = []
if not base_nums:
try:
base_nums = [int(x) for x in (primary.get("numbers") or [])]
except Exception:
base_nums = []
strike_tickets["mb_anti_core"] = {"numbers": anti, "star": strike_tickets.get("collapse", {}).get("star")}
strike_tickets["mb_shape_2low2mid1high"] = {"numbers": shape, "star": strike_tickets.get("collapse", {}).get("star")}
strike_tickets["mb_cold_megaball"] = {"numbers": sorted(set(base_nums))[:5], "star": mb_star}
except Exception:
pass
# -------------------------
# PATCH: Lotto America hedges (safe, additive only)
# - Anti-core hedge ticket
# - Shape hedge (2 low / 2 mid / 1 high)
# - Cold Star Ball hedge (SB 1–3)
# -------------------------
try:
if cfg.name == "Lotto America" and isinstance(strike_tickets, dict):
from collections import Counter as _Counter
_freq = _Counter()
try:
for _s in (god_sets or []):
_freq.update([int(x) for x in (_s.get("numbers") or [])])
except Exception:
pass
_sc = {int(k): float(v) for k, v in (final_scores or {}).items()}
# Core = top 2 most frequent numbers (tie-broken by score)
_core = [n for n, _c in sorted(_freq.items(), key=lambda kv: (kv[1], _sc.get(int(kv[0]), 0.0)), reverse=True)[:2]]
# Candidate pool: pool12 first, else top scored list
_cand = []
try:
if pool12:
_cand = [int(x) for x in pool12]
except Exception:
_cand = []
if not _cand:
_cand = [int(x) for x, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True)[:30]]
main_min = int(cfg.main_min); main_max = int(cfg.main_max)
# Bands for Lotto America main range (1–52)
low_lo, low_hi = main_min, min(main_max, 17)
mid_lo, mid_hi = min(main_max, 18), min(main_max, 35)
high_lo, high_hi = min(main_max, 36), main_max
def _fill_any(count, exclude):
out = []
# prefer candidates first
for n in _cand:
n = int(n)
if n in exclude:
continue
out.append(n)
exclude.add(n)
if len(out) >= count:
return out
# then top scored
for n, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in exclude:
continue
out.append(n)
exclude.add(n)
if len(out) >= count:
break
# last resort random fill
while len(out) < count:
r = random.randint(main_min, main_max)
if r in exclude:
continue
out.append(r); exclude.add(r)
return out
def _pick_from_band(bmin, bmax, k, exclude):
picked = []
for n in _cand:
n = int(n)
if n in exclude:
continue
if bmin <= n <= bmax:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
return picked
# fallback to top scored
for n, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in exclude:
continue
if bmin <= n <= bmax:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
if len(picked) < k:
picked += _fill_any(k - len(picked), exclude)
return picked[:k]
# Base numbers for reuse (collapse -> primary)
base_nums = []
try:
base_nums = [int(x) for x in (strike_tickets.get("collapse", {}).get("numbers") or [])]
except Exception:
base_nums = []
if not base_nums:
try:
base_nums = [int(x) for x in (primary.get("numbers") or [])]
except Exception:
base_nums = []
# 1) Anti-core hedge: avoid top-2 overused core numbers
_ex = set(_core)
anti = []
for n in _cand:
n = int(n)
if n in _ex:
continue
if main_min <= n <= main_max:
anti.append(n)
_ex.add(n)
if len(anti) >= 5:
break
if len(anti) < 5:
anti += _fill_any(5 - len(anti), _ex)
anti = sorted(set(anti))[:5]
if len(anti) < 5:
_tmp_ex = set(anti)
anti += _fill_any(5 - len(anti), _tmp_ex)
anti = sorted(set(anti))[:5]
# 2) Shape hedge: 2 low / 2 mid / 1 high
_ex2 = set()
shape = []
shape += _pick_from_band(low_lo, low_hi, 2, _ex2)
shape += _pick_from_band(mid_lo, mid_hi, 2, _ex2)
shape += _pick_from_band(high_lo, high_hi, 1, _ex2)
shape = sorted(set(shape))[:5]
if len(shape) < 5:
shape += _fill_any(5 - len(shape), _ex2)
shape = sorted(set(shape))[:5]
# Avoid duplicating collapse exactly (wasted ticket)
try:
_collapse_nums = sorted([int(x) for x in (strike_tickets.get("collapse", {}).get("numbers") or [])])
except Exception:
_collapse_nums = []
if _collapse_nums and sorted(shape) == _collapse_nums:
_ex3 = set(shape)
# try swapping in one different high-band number
for n in _cand:
n = int(n)
if n in _ex3:
continue
if high_lo <= n <= high_hi:
shape[-1] = n
break
shape = sorted(set(shape))[:5]
if len(shape) < 5:
shape += _fill_any(5 - len(shape), set(shape))
shape = sorted(set(shape))[:5]
# 3) Cold Star Ball hedge: reuse base numbers (prefer collapse) but force cold star (1–3)
cold_star = None
try:
smin, smax = int(cfg.star_min), int(cfg.star_max)
cold_hi = min(smax, max(smin, 3))
cold_star = random.choice(list(range(smin, cold_hi + 1)))
except Exception:
cold_star = None
strike_tickets["la_anti_core"] = {"numbers": anti, "star": strike_tickets.get("collapse", {}).get("star")}
strike_tickets["la_shape_2low2mid1high"] = {"numbers": shape, "star": strike_tickets.get("collapse", {}).get("star")}
strike_tickets["la_cold_starball"] = {"numbers": sorted(set(base_nums))[:5], "star": cold_star}
except Exception:
pass
# -------------------------
# PATCH: Gimme5 hedges (safe, additive only)
# - Anti-core hedge ticket (avoid the 2 most overused numbers)
# - Shape hedge (2 low / 2 mid / 1 high) for 1-39
# Note: Gimme5 has no bonus ball; 'star' will be None.
# -------------------------
try:
if cfg.name == "Gimme 5" and isinstance(strike_tickets, dict):
from collections import Counter as _Counter
_freq = _Counter()
try:
for _s in (god_sets or []):
_freq.update([int(x) for x in (_s.get("numbers") or [])])
except Exception:
pass
_sc = {int(k): float(v) for k, v in (final_scores or {}).items()}
# core = top 2 most frequent numbers (tie-break by score)
_core = [n for n, _c in sorted(_freq.items(), key=lambda kv: (kv[1], _sc.get(int(kv[0]), 0.0)), reverse=True)[:2]]
# Candidate pool preference: pool12 -> otherwise top scored list
_cand = []
try:
if pool12:
_cand = [int(x) for x in pool12]
except Exception:
_cand = []
if not _cand:
_cand = [int(x) for x, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True)[:30]]
main_min = int(getattr(cfg, "main_min", 1) or 1)
main_max = int(getattr(cfg, "main_max", 39) or 39)
def _fill_any(k, exclude):
picked = []
for n in _cand:
n = int(n)
if n in exclude:
continue
if main_min <= n <= main_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
if len(picked) < k:
for n, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in exclude:
continue
if main_min <= n <= main_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
return picked
def _pick_from_band(band_min, band_max, k, exclude):
picked = []
for n in _cand:
n = int(n)
if n in exclude:
continue
if band_min <= n <= band_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
if len(picked) < k:
for n, _v in sorted(_sc.items(), key=lambda kv: kv[1], reverse=True):
n = int(n)
if n in exclude:
continue
if band_min <= n <= band_max:
picked.append(n)
exclude.add(n)
if len(picked) >= k:
break
return picked
# Anti-core hedge: exclude core and fill 5 from candidates
ex = set(_core)
anti = _fill_any(5, ex)
anti = sorted(set(int(x) for x in anti))[:5]
if len(anti) == 5:
strike_tickets["g5_anti_core"] = {"numbers": anti, "star": None}
# Shape hedge: 2 low (1-13), 2 mid (14-26), 1 high (27-39)
ex2 = set()
shape = []
shape += _pick_from_band(1, 13, 2, ex2)
shape += _pick_from_band(14, 26, 2, ex2)
shape += _pick_from_band(27, 39, 1, ex2)
if len(shape) < 5:
shape += _fill_any(5 - len(shape), ex2)
shape = sorted(set(int(x) for x in shape))[:5]
if len(shape) == 5:
strike_tickets["g5_shape_2low2mid1high"] = {"numbers": shape, "star": None}
except Exception:
pass
result = {
"game": cfg.name,
"numbers": primary["numbers"],
"star": primary["star"],
"pool12": pool12,
"meta": {
"numbers_scored": len(final_scores),
"history_used": len(df_long),
"styles": [s["style"] for s in god_sets],
},
"godmode_sets": god_sets,
"strike_tickets": strike_tickets,
"consensus_collapse": strike_tickets["collapse"],
"consensus_neighbor": strike_tickets["neighbor"],
"explanation": explanation,
"model_info": model_info,
}
# ------------------------------------------------------------
# APPEND PATCH: EXTRA_PREDICTORS_V1 (runtime hook)
# Compute 2 additional predictions WITHOUT using GOD MODE scores:
# 1) ML Ensemble (RF + optional XGBoost)
# 2) DL Sequence (LSTM/Transformer if TF available; safe fallback otherwise)
# Stored under result['extra_predictions'] so UI can render without altering core sets.
# ------------------------------------------------------------
try:
_seed_local = int(result.get("seed", 0) or 0)
except Exception:
_seed_local = 0
try:
_extra_ml = _extra_predict_ml_ensemble(df_long, cfg, seed=_seed_local, window=10)
_extra_dl = _extra_predict_dl_sequence(df_long, cfg, seed=_seed_local, window=12, epochs=18)
if isinstance(result, dict):
result["extra_predictions"] = {
"ml_ensemble": _extra_ml,
"dl_sequence": _extra_dl,
}
except Exception:
pass
# ------------------------------------------------------------
# Spread Portfolio Mode (ALL GAMES) + simple regime label
# ------------------------------------------------------------
try:
_label = _regime_low_high_bounce_label(df_long, cfg)
if _label:
result["regime_label"] = _label
_star_val = result.get("star", None)
# If we just had a LOW streak, tilt spreads slightly higher
_high_bias = 0.35 if ("LOW → HIGH" in (_label or "")) else 0.0
result["spread_portfolio_title"] = f"SPREAD PORTFOLIO MODE ({cfg.name})"
result["spread_portfolio"] = _build_spread_portfolio_generic(
cfg=cfg,
pool12=pool12,
star=_star_val,
force_high_bias=_high_bias,
)
except Exception:
pass
return result
# ============================================================
# Backtesting
# ============================================================
def enhanced_backtest(
df: pd.DataFrame,
cfg: GameConfig,
n_tests: int = 200,
) -> Dict[str, float]:
df = _ensure_datetime(df, cfg.csv_date_col)
if cfg.clean_func and cfg.clean_func in globals():
df = globals()[cfg.clean_func](df)
if len(df) < 80:
return {"error": "Insufficient data for backtest (need >80 draws)"}
total_tests = min(n_tests, len(df) - 60)
print(f"[BACKTEST] {cfg.name}: running {total_tests} tests...")
stats = {
"hit_0": 0,
"hit_1": 0,
"hit_2": 0,
"hit_3": 0,
"hit_4": 0,
"hit_5": 0,
"rnd_0": 0,
"rnd_1": 0,
"rnd_2": 0,
"rnd_3": 0,
"rnd_4": 0,
"rnd_5": 0,
"sum_errors": [],
"even_match": 0,
}
for idx in range(60, 60 + total_tests):
if (idx - 59) % 30 == 0:
print(f" progress: {idx - 59}/{total_tests}")
train_df = df.iloc[:idx].copy()
actual_row = df.iloc[idx]
actual_nums = sorted(int(x) for x in actual_row[cfg.main_cols].values)
try:
pred = generate_prediction_v4_god(train_df, cfg)
pred_nums = sorted(pred["numbers"])
except Exception:
pred_nums = sorted(
random.sample(
range(cfg.main_min, cfg.main_max + 1),
len(cfg.main_cols),
)
)
hits = len(set(pred_nums) & set(actual_nums))
stats[f"hit_{hits}"] += 1
rnd_nums = sorted(
random.sample(
range(cfg.main_min, cfg.main_max + 1),
len(cfg.main_cols),
)
)
rnd_hits = len(set(rnd_nums) & set(actual_nums))
stats[f"rnd_{rnd_hits}"] += 1
stats["sum_errors"].append(abs(sum(pred_nums) - sum(actual_nums)))
if sum(v % 2 == 0 for v in pred_nums) == sum(
v % 2 == 0 for v in actual_nums
):
stats["even_match"] += 1
out: Dict[str, float] = {}
for i in range(6):
out[f"model_hit_{i}_rate"] = round(
stats[f"hit_{i}"] / max(total_tests, 1) * 100.0, 2
)
out[f"random_hit_{i}_rate"] = round(
stats[f"rnd_{i}"] / max(total_tests, 1) * 100.0, 2
)
out["avg_sum_error"] = round(float(np.mean(stats["sum_errors"])), 2)
out["even_count_accuracy"] = round(
stats["even_match"] / max(total_tests, 1) * 100.0, 2
)
out["model_3plus_rate"] = round(
sum(stats[f"hit_{i}"] for i in range(3, 6)) / max(total_tests, 1) * 100.0, 2
)
out["random_3plus_rate"] = round(
sum(stats[f"rnd_{i}"] for i in range(3, 6)) / max(total_tests, 1) * 100.0, 2
)
return out
# ============================================================
# CSV loading + public API
# ============================================================
def load_csv_for_game(csv_path: Path, game_key: str) -> Tuple[pd.DataFrame, GameConfig]:
cfg = GAME_CONFIGS[game_key]
# Read CSV (support comma or tab-delimited exports)
try:
df = pd.read_csv(csv_path)
except Exception:
df = pd.read_csv(csv_path, sep=None, engine="python")
# ---- Flexible header normalization (future-proof) ----
def _norm(s: str) -> str:
return str(s).strip().lower().replace("_", " ").replace("-", " ").replace("\t", " ").replace(" ", " ")
norm_to_actual = {_norm(c): c for c in df.columns}
def _find_col(*cands: str) -> str | None:
for c in cands:
if c is None:
continue
cc = _norm(c)
if cc in norm_to_actual:
return norm_to_actual[cc]
return None
# Date column: accept common variants and rename to cfg.csv_date_col
date_actual = _find_col(
cfg.csv_date_col,
"date", "draw date", "drawdate", "draw_date",
)
if date_actual is None:
raise ValueError(f"Expected a date column in CSV for {cfg.name}. Tried: '{cfg.csv_date_col}', 'Date', 'Draw Date'")
if date_actual != cfg.csv_date_col:
df = df.rename(columns={date_actual: cfg.csv_date_col})
# Main balls: accept canonical names OR numeric columns (1..N) OR b1..bN OR Ball 1..Ball N
n_main = len(cfg.main_cols)
have_canonical = all(c in df.columns for c in cfg.main_cols)
if not have_canonical:
# Candidate layouts (by position)
numeric_cols = [str(i) for i in range(1, n_main + 1)]
b_cols = [f"b{i}" for i in range(1, n_main + 1)]
ball_cols = [f"ball {i}" for i in range(1, n_main + 1)]
ball_caps_cols = [f"Ball {i}" for i in range(1, n_main + 1)]
def _all_exist(cols):
return all(_find_col(c) is not None for c in cols)
chosen = None
if _all_exist(numeric_cols):
chosen = numeric_cols
elif _all_exist(b_cols):
chosen = b_cols
elif _all_exist(ball_cols):
chosen = ball_cols
elif _all_exist(ball_caps_cols):
chosen = ball_caps_cols
if chosen is None:
# Give a helpful error listing what we expected
raise ValueError(
f"Expected main ball columns for {cfg.name}.\n"
f"Accepted formats: {cfg.main_cols} OR columns '1'..'{n_main}' OR 'b1'..'b{n_main}' OR 'Ball 1'..'Ball {n_main}'.\n"
f"Found: {list(df.columns)[:25]}{'...' if len(df.columns) > 25 else ''}"
)
# Rename chosen -> canonical
rename_map = {}
for i, cand in enumerate(chosen):
actual = _find_col(cand)
rename_map[actual] = cfg.main_cols[i]
df = df.rename(columns=rename_map)
# Bonus/Star column: accept common variants and rename to cfg.star_col (when game uses one)
if cfg.star_col:
star_actual = _find_col(
cfg.star_col,
# Generic
"star", "bonus", "special", "extra",
# Game-specific common variants
"lucky ball", "luckyball", "lb",
"mega ball", "megaball", "mb",
"powerball", "power ball", "pb",
"megabucks", "mega bucks", "megaball 1", # harmless extras
"star ball", "sb",
)
if star_actual is not None and star_actual != cfg.star_col:
df = df.rename(columns={star_actual: cfg.star_col})
# ---- Basic cleaning ----
for col in cfg.main_cols:
if col not in df.columns:
raise ValueError(f"Expected column '{col}' in CSV for {cfg.name}")
df[col] = pd.to_numeric(df[col], errors="coerce")
mask_bad = (df[col].isna()) | (df[col] < cfg.main_min) | (df[col] > cfg.main_max)
if mask_bad.any():
df = df[~mask_bad]
if cfg.star_col and cfg.star_col in df.columns:
df[cfg.star_col] = pd.to_numeric(df[cfg.star_col], errors="coerce")
mask_bad_star = (df[cfg.star_col].isna()) | (df[cfg.star_col] < cfg.star_min) | (df[cfg.star_col] > cfg.star_max)
if mask_bad_star.any():
df = df[~mask_bad_star]
# Parse and sort by date
df[cfg.csv_date_col] = pd.to_datetime(df[cfg.csv_date_col], errors="coerce")
df = df.dropna(subset=[cfg.csv_date_col])
df = df.sort_values(cfg.csv_date_col).reset_index(drop=True)
if cfg.clean_func and cfg.clean_func in globals():
df = globals()[cfg.clean_func](df)
return df, cfg
def predict_for_game_v3(
csv_path: Path,
game_key: str,
run_backtest: bool = False,
) -> Dict[str, object]:
"""
Public API (same name/signature as earlier versions).
If run_backtest=True -> run enhanced_backtest.
Else -> run GOD-MODE prediction (V5.3 ULTRA).
"""
df, cfg = load_csv_for_game(Path(csv_path), game_key)
# Backtest disabled (HF-safe).
run_backtest = False
# if run_backtest:
# return enhanced_backtest(df, cfg)
return generate_prediction_v4_god(df, cfg)
def predict_for_game(
csv_path: Path,
game_key: str,
run_backtest: bool = False,
):
"""
Backwards-compatible wrapper for older code that imports `predict_for_game`.
"""
return predict_for_game_v3(csv_path=Path(csv_path), game_key=game_key, run_backtest=run_backtest)
# ============================================================
# Wheel generation + hot/cold analysis
# ============================================================
def generate_wheel_numbers(raw_df: pd.DataFrame, cfg: GameConfig) -> Dict[str, object]:
"""
Generate a 20-number wheel using frequency, recency, and multi-agent ranking.
"""
df = _ensure_datetime(raw_df, cfg.csv_date_col)
if cfg.clean_func and cfg.clean_func in globals():
df = globals()[cfg.clean_func](df)
if len(df) < 40:
return {"error": "Insufficient history (<40) for wheel generation"}
df_long = _limit_history(df, _auto_history_window(df, cfg))
ml_models = build_multiwindow_ml(df_long, cfg, windows=[20, 80, 400])
freq_features = create_frequency_features(df_long, cfg, windows=[20, 80, 400])
agent_scores = compute_agent_scores(df_long, cfg, ml_models, freq_features)
final_scores = combine_agent_scores(agent_scores, cfg)
banned = get_last4_repeater_ban(df_long, cfg)
wheel_pool = {n: s for n, s in final_scores.items() if n not in banned}
if len(wheel_pool) < 20:
wheel_pool = final_scores.copy()
sorted_nums_wheel = sorted(wheel_pool.items(), key=lambda x: x[1], reverse=True)
wheel_nums = [n for n, _ in sorted_nums_wheel[:20]]
freq_all_main = Counter(df_long[cfg.main_cols].values.flatten())
hot = [n for n, _ in freq_all_main.most_common(10)]
cold = [n for n, _ in freq_all_main.most_common()[-10:]]
return {
"wheel_numbers": wheel_nums,
"hot_count": len(set(wheel_nums) & set(hot)),
"cold_count": len(set(wheel_nums) & set(cold)),
"warm_count": len(wheel_nums) - len(set(wheel_nums) & set(hot)) - len(set(wheel_nums) & set(cold)),
"banned_last4_repeater": sorted(banned),
"hot_cold_analysis": {
"hot": hot,
"cold": cold,
},
}
def get_wheel_for_game(csv_path: Path, game_key: str) -> Dict[str, object]:
df, cfg = load_csv_for_game(Path(csv_path), game_key)
return generate_wheel_numbers(df, cfg)
def get_hot_cold_analysis(
csv_path: Path,
game_key: str,
top_n: int = 10,
) -> Dict[str, object]:
"""
Helper for app/engine: top-N hottest and coldest numbers for the given game,
plus full frequency table.
"""
df, cfg = load_csv_for_game(Path(csv_path), game_key)
all_nums = []
for col in cfg.main_cols:
all_nums.extend(df[col].tolist())
all_nums = [int(x) for x in all_nums if not pd.isna(x)]
freq = Counter(all_nums)
sorted_freq = sorted(freq.items(), key=lambda kv: kv[1], reverse=True)
hot = [n for n, _ in sorted_freq[:top_n]]
cold = [n for n, _ in sorted(freq.items(), key=lambda kv: kv[1])[:top_n]]
return {
"hot": hot,
"cold": cold,
"frequency": {int(n): int(c) for n, c in freq.items()},
}
def load_and_prepare_data(csv_path: Path, game_key: str) -> Tuple[pd.DataFrame, GameConfig]:
"""
Backwards-compatible wrapper for older engine code.
Loads CSV, cleans & validates it, and returns (DataFrame, GameConfig).
"""
csv_path = Path(csv_path)
df, cfg = load_csv_for_game(csv_path, game_key)
return df, cfg
# ============================================================
# CLI (pretty output)
def _consensus_collapse_ticket(
primary_numbers: List[int],
god_sets: List[Dict[str, object]],
k: int = 5,
) -> Tuple[List[int], Optional[int]]:
"""Build a single 'collapsed' ticket from the engine's own consensus.
Uses appearance frequency across GOD MODE sets (and primary pick, if provided).
Returns (numbers, star_or_none).
Print-only helper for CLI; does not change prediction logic.
"""
counts: Dict[int, int] = {}
star_counts: Dict[int, int] = {}
# Include GOD MODE set numbers
for s in god_sets or []:
nums = s.get("numbers") or []
for n in nums:
try:
nn = int(n)
except Exception:
continue
counts[nn] = counts.get(nn, 0) + 1
st = s.get("star", None)
if st is not None:
try:
ss = int(st)
star_counts[ss] = star_counts.get(ss, 0) + 1
except Exception:
pass
# Include primary numbers as a light vote (helps collapse toward best single pick)
for n in primary_numbers or []:
try:
nn = int(n)
except Exception:
continue
counts[nn] = counts.get(nn, 0) + 1
# Pick top-k by frequency, then numeric (stable)
ranked = sorted(counts.items(), key=lambda kv: (-kv[1], kv[0]))
top = [n for n, c in ranked[:k]]
top = sorted(top)
# Pick most common star (if any), tie -> smallest
star = None
if star_counts:
star = sorted(star_counts.items(), key=lambda kv: (-kv[1], kv[0]))[0][0]
return top, star
def _consensus_neighbor_ticket(
primary_numbers: List[int],
god_sets: List[Dict[str, object]],
cfg: GameConfig,
k: int = 5,
top_n: int = 3,
) -> Tuple[List[int], Optional[int]]:
"""Second collapsed ticket: consensus + neighbor-chaser.
Starts from the same consensus counts as _consensus_collapse_ticket, then
adds candidate neighbors (±1) around the top_n consensus anchors.
Selection remains consensus-driven (frequency first). Neighbors only help
when they have some support in the candidate pool.
Print-only helper for CLI; does not change prediction logic.
"""
counts: Dict[int, float] = {}
star_counts: Dict[int, int] = {}
# Tally from GOD MODE sets
for s in god_sets or []:
nums = s.get("numbers") or []
for n in nums:
try:
nn = int(n)
except Exception:
continue
counts[nn] = counts.get(nn, 0.0) + 1.0
st = s.get("star", None)
if st is not None:
try:
ss = int(st)
star_counts[ss] = star_counts.get(ss, 0) + 1
except Exception:
pass
# Light vote for primary numbers
for n in primary_numbers or []:
try:
nn = int(n)
except Exception:
continue
counts[nn] = counts.get(nn, 0.0) + 1.0
if not counts:
return [], None
# Identify top anchors by raw frequency
ranked = sorted(counts.items(), key=lambda kv: (-kv[1], kv[0]))
anchors = [n for n, _c in ranked[: max(1, int(top_n))]]
# Add neighbor candidates with a small bonus tied to the anchor strength
for a in anchors:
a_score = float(counts.get(a, 0.0))
for nb in (a - 1, a + 1):
if nb < int(cfg.main_min) or nb > int(cfg.main_max):
continue
base_nb = float(counts.get(nb, 0.0))
counts[nb] = base_nb + 0.35 * a_score
# Choose top-k by adjusted frequency, tie -> smaller number
ranked2 = sorted(counts.items(), key=lambda kv: (-kv[1], kv[0]))
picked: List[int] = []
for n, _c in ranked2:
if n not in picked:
picked.append(n)
if len(picked) >= k:
break
picked = sorted(picked)
# Pick most common star (if any), tie -> smallest
star = None
if star_counts:
star = sorted(star_counts.items(), key=lambda kv: (-kv[1], kv[0]))[0][0]
return picked, star
# ============================================================
# ============================================================
# APPEND PATCH: EXTRA_PREDICTORS_V1 (APPEND-ONLY / NO DELETIONS)
# - Adds 2 additional prediction lines per game:
# 1) ML Ensemble (RandomForest + optional XGBoost)
# 2) DL Sequence (LSTM/Transformer if TensorFlow available; safe fallback otherwise)
# - Both predictors read ONLY the game CSV history (df_long) and do NOT reuse GOD MODE scores.
# - Output is attached under result['extra_predictions'] (UI can render without changing core sets).
# ============================================================
def _extra__multi_hot_matrix(df: pd.DataFrame, cfg: GameConfig, *, window:int=10):
'''
Build X, Y for next-draw multi-label prediction.
X[t] uses frequency/recency features from draws [t-window, t) and Y[t] is the set of numbers in draw t.
'''
try:
main_cols = list(getattr(cfg, "main_cols", []) or [])
main_n = int(len(main_cols) or 5)
mn, mx = int(getattr(cfg, "main_min", 1)), int(getattr(cfg, "main_max", 99))
n_range = mx - mn + 1
if n_range <= 0:
return None, None, None
draws = []
for _i in range(len(df)):
row = df.iloc[_i]
s = []
for c in main_cols:
try:
v = int(row[c])
if mn <= v <= mx:
s.append(v)
except Exception:
continue
draws.append(sorted(set(s)))
if len(draws) < window + 5:
return None, None, None
X = []
Y = []
for t in range(window, len(draws)):
hist = draws[t-window:t]
counts = [0]*n_range
last_seen = [None]*n_range
for j, d in enumerate(hist):
for v in d:
idx = int(v) - mn
if 0 <= idx < n_range:
counts[idx] += 1
last_seen[idx] = j # 0..window-1
rec = [1.0]*n_range
for i in range(n_range):
if last_seen[i] is None:
rec[i] = 0.0
else:
rec[i] = float(window - 1 - int(last_seen[i])) / float(max(1, window - 1))
feat = [float(c)/float(window) for c in counts] + rec
X.append(feat)
y = [0]*n_range
for v in draws[t]:
idx = int(v) - mn
if 0 <= idx < n_range:
y[idx] = 1
Y.append(y)
return np.asarray(X, dtype=float), np.asarray(Y, dtype=float), {"mn": mn, "mx": mx, "main_n": main_n, "n_range": n_range, "window": window}
except Exception:
return None, None, None
def _extra_predict_ml_ensemble(df: pd.DataFrame, cfg: GameConfig, *, seed:int=0, window:int=10):
'''
Extra predictor #1: RandomForest + optional XGBoost in a light ensemble.
Returns dict: {"numbers":[...], "star":..., "meta":{...}}
'''
out = {"numbers": [], "star": None, "meta": {"method": "ml_ensemble", "used_xgboost": False, "window": int(window)}}
try:
X, Y, info = _extra__multi_hot_matrix(df, cfg, window=int(window))
if X is None or Y is None or info is None:
out["meta"]["note"] = "insufficient_history"
return out
mn, mx, main_n = int(info["mn"]), int(info["mx"]), int(info["main_n"])
n = int(X.shape[0])
split = max(10, int(n * 0.85))
Xtr, Ytr = X[:split], Y[:split]
from sklearn.multiclass import OneVsRestClassifier
from sklearn.ensemble import RandomForestClassifier
rf = OneVsRestClassifier(
RandomForestClassifier(
n_estimators=250,
random_state=int(seed) if seed is not None else 0,
min_samples_leaf=1,
n_jobs=-1,
)
)
rf.fit(Xtr, Ytr)
xgb_model = None
try:
import xgboost as xgb # type: ignore
xgb_model = OneVsRestClassifier(
xgb.XGBClassifier(
n_estimators=350,
max_depth=6,
learning_rate=0.08,
subsample=0.85,
colsample_bytree=0.85,
reg_lambda=1.0,
random_state=int(seed) if seed is not None else 0,
n_jobs=-1,
eval_metric="logloss",
tree_method="hist",
)
)
xgb_model.fit(Xtr, Ytr)
out["meta"]["used_xgboost"] = True
except Exception:
xgb_model = None
x_last = X[-1:].copy()
def _ovr_proba(mdl, xrow):
try:
pr = mdl.predict_proba(xrow)
if isinstance(pr, np.ndarray) and pr.ndim == 2 and pr.shape[0] == 1:
return pr[0]
if isinstance(pr, list):
vals = []
for a in pr:
try:
if a.shape[1] == 2:
vals.append(float(a[0, 1]))
else:
vals.append(float(a[0, -1]))
except Exception:
vals.append(0.0)
return np.asarray(vals, dtype=float)
except Exception:
pass
return None
pr_rf = _ovr_proba(rf, x_last)
if pr_rf is None:
out["meta"]["note"] = "rf_failed"
return out
probs = np.array(pr_rf, dtype=float)
if xgb_model is not None:
pr_xgb = _ovr_proba(xgb_model, x_last)
if pr_xgb is not None and len(pr_xgb) == len(probs):
probs = 0.55 * probs + 0.45 * np.array(pr_xgb, dtype=float)
banned = set()
try:
banned = set(get_last4_repeater_ban(df, cfg) or [])
except Exception:
banned = set()
ranked = sorted([(mn + i, float(probs[i])) for i in range(len(probs))], key=lambda kv: (-kv[1], kv[0]))
picks = []
for num, _p in ranked:
if int(num) in banned:
continue
if mn <= int(num) <= mx and int(num) not in picks:
picks.append(int(num))
if len(picks) >= int(main_n):
break
out["numbers"] = sorted(picks)
try:
if getattr(cfg, "star_col", None):
smin = int(getattr(cfg, "star_min", 1))
smax = int(getattr(cfg, "star_max", smin))
series_all = pd.to_numeric(df[cfg.star_col], errors="coerce").dropna().astype(int).tolist()
if series_all:
from collections import Counter
fa = Counter(series_all)
series_80 = pd.to_numeric(df[cfg.star_col].tail(80), errors="coerce").dropna().astype(int).tolist()
f8 = Counter(series_80)
cand = list(range(smin, smax + 1))
wts = []
for b in cand:
w = 1.0 + float(fa.get(b, 0)) + 2.0 * float(f8.get(b, 0))
wts.append(w)
rnd = random.Random(int(seed) + 911)
out["star"] = int(rnd.choices(cand, weights=wts, k=1)[0])
except Exception:
pass
return out
except Exception as e:
out["meta"]["error"] = str(e)
return out
def _extra_predict_dl_sequence(df: pd.DataFrame, cfg: GameConfig, *, seed:int=0, window:int=12, epochs:int=18):
'''
Extra predictor #2: Sequence model.
Preferred: TensorFlow/Keras LSTM + lightweight Transformer encoder.
Safe fallback: sklearn MLP (multi-output) on flattened sequences if TF unavailable.
Returns dict: {"numbers":[...], "star":..., "meta":{...}}
'''
out = {"numbers": [], "star": None, "meta": {"method": "dl_sequence", "window": int(window), "epochs": int(epochs), "backend": "unknown"}}
try:
main_cols = list(getattr(cfg, "main_cols", []) or [])
main_n = int(len(main_cols) or 5)
mn, mx = int(getattr(cfg, "main_min", 1)), int(getattr(cfg, "main_max", 99))
n_range = mx - mn + 1
if n_range <= 0:
out["meta"]["note"] = "bad_range"
return out
draws = []
for _i in range(len(df)):
row = df.iloc[_i]
s = []
for c in main_cols:
try:
v = int(row[c])
if mn <= v <= mx:
s.append(v)
except Exception:
continue
draws.append(sorted(set(s)))
if len(draws) < int(window) + 6:
out["meta"]["note"] = "insufficient_history"
return out
seqX, seqY = [], []
for t in range(int(window), len(draws)):
hist = draws[t-int(window):t]
mat = []
for d in hist:
v = [0.0]*n_range
for num in d:
idx = int(num) - mn
if 0 <= idx < n_range:
v[idx] = 1.0
mat.append(v)
seqX.append(mat)
y = [0.0]*n_range
for num in draws[t]:
idx = int(num) - mn
if 0 <= idx < n_range:
y[idx] = 1.0
seqY.append(y)
seqX = np.asarray(seqX, dtype=float)
seqY = np.asarray(seqY, dtype=float)
n = int(seqX.shape[0])
split = max(10, int(n * 0.85))
Xtr, Ytr = seqX[:split], seqY[:split]
x_last = seqX[-1:]
model_prob = None
try:
import tensorflow as tf # type: ignore
tf.random.set_seed(int(seed) if seed is not None else 0)
out["meta"]["backend"] = "tensorflow"
inp = tf.keras.Input(shape=(int(window), n_range))
x = tf.keras.layers.LSTM(64, return_sequences=True)(inp)
attn = tf.keras.layers.MultiHeadAttention(num_heads=4, key_dim=16)(x, x)
x2 = tf.keras.layers.Add()([x, attn])
x2 = tf.keras.layers.LayerNormalization()(x2)
x2 = tf.keras.layers.Dense(96, activation="relu")(x2)
x2 = tf.keras.layers.GlobalAveragePooling1D()(x2)
outp = tf.keras.layers.Dense(n_range, activation="sigmoid")(x2)
model = tf.keras.Model(inp, outp)
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.004), loss="binary_crossentropy")
model.fit(Xtr, Ytr, epochs=int(epochs), batch_size=32, verbose=0)
model_prob = model.predict(x_last, verbose=0)[0]
except Exception:
out["meta"]["backend"] = "sklearn_fallback"
try:
from sklearn.neural_network import MLPClassifier
from sklearn.multioutput import MultiOutputClassifier
flatX = seqX.reshape((seqX.shape[0], -1))
x_last2 = flatX[-1:].copy()
clf = MultiOutputClassifier(
MLPClassifier(
hidden_layer_sizes=(256, 128),
activation="relu",
solver="adam",
max_iter=220,
random_state=int(seed) if seed is not None else 0,
)
)
clf.fit(flatX[:split], seqY[:split])
probs = []
proba_list = clf.predict_proba(x_last2)
for pr in proba_list:
try:
if pr.shape[1] == 2:
probs.append(float(pr[0, 1]))
else:
probs.append(float(pr[0, -1]))
except Exception:
probs.append(0.0)
model_prob = np.asarray(probs, dtype=float)
except Exception as e2:
out["meta"]["error"] = str(e2)
return out
if model_prob is None:
out["meta"]["note"] = "model_failed"
return out
banned = set()
try:
banned = set(get_last4_repeater_ban(df, cfg) or [])
except Exception:
banned = set()
ranked = sorted([(mn + i, float(model_prob[i])) for i in range(len(model_prob))], key=lambda kv: (-kv[1], kv[0]))
picks = []
for num, _p in ranked:
if int(num) in banned:
continue
if mn <= int(num) <= mx and int(num) not in picks:
picks.append(int(num))
if len(picks) >= int(main_n):
break
out["numbers"] = sorted(picks)
try:
if getattr(cfg, "star_col", None):
smin = int(getattr(cfg, "star_min", 1))
smax = int(getattr(cfg, "star_max", smin))
series_all = pd.to_numeric(df[cfg.star_col], errors="coerce").dropna().astype(int).tolist()
if series_all:
from collections import Counter
fa = Counter(series_all)
series_80 = pd.to_numeric(df[cfg.star_col].tail(80), errors="coerce").dropna().astype(int).tolist()
f8 = Counter(series_80)
cand = list(range(smin, smax + 1))
wts = []
for b in cand:
w = 1.0 + float(fa.get(b, 0)) + 2.0 * float(f8.get(b, 0))
wts.append(w)
rnd = random.Random(int(seed) + 1337)
out["star"] = int(rnd.choices(cand, weights=wts, k=1)[0])
except Exception:
pass
return out
except Exception as e:
out["meta"]["error"] = str(e)
return out
if __name__ == "__main__":
import argparse
import os
parser = argparse.ArgumentParser(
description="Lotto Predictor V5.3 ULTRA GOD MODE (multi-agent, multi-window, cluster-aware, top_cluster style)"
)
parser.add_argument(
"--game",
required=True,
choices=list(GAME_CONFIGS.keys()),
help="Game key: " + ", ".join(GAME_CONFIGS.keys()),
)
parser.add_argument("--csv", required=True, help="Path to CSV for the game")
parser.add_argument(
"--backtest",
action="store_true",
help="Run backtest instead of prediction",
)
parser.add_argument(
"--save-json",
action="store_true",
help="Also save full JSON result to godmode_last_result_<game>.json",
)
args = parser.parse_args()
result = predict_for_game_v3(
csv_path=Path(args.csv),
game_key=args.game,
run_backtest=args.backtest,
)
# -------------------------------
# Backtest mode: pretty summary
# -------------------------------
if args.backtest:
if "error" in result:
print(f"\n[BACKTEST ERROR] {result['error']}")
else:
print("\n==============================================")
print(f" BACKTEST RESULTS - {GAME_CONFIGS[args.game].name}")
print("==============================================\n")
print(f" Model 3+ hits rate : {result.get('model_3plus_rate', 0)} %")
print(f" Random 3+ hits rate: {result.get('random_3plus_rate', 0)} %")
print(f" Avg sum error : {result.get('avg_sum_error', 0)}")
print(f" Even-count accuracy: {result.get('even_count_accuracy', 0)} %")
print("\n Hit-rate table (Model vs Random):")
print(" Matches | Model % | Random %")
print(" ---------+-----------+----------")
for i in range(6):
m_val = result.get(f"model_hit_{i}_rate", 0)
r_val = result.get(f"random_hit_{i}_rate", 0)
print(f" {i:1d} | {m_val:7.2f} % | {r_val:7.2f} %")
print("\n==============================================\n")
else:
# -------------------------------
# Prediction mode: nice compact view
# -------------------------------
game_name = result.get("game", GAME_CONFIGS[args.game].name)
numbers = result.get("numbers", [])
star = result.get("star", None)
meta = result.get("meta", {})
god_sets = result.get("godmode_sets", [])
expl = result.get("explanation", {})
top_nums = expl.get("top_numbers", [])
banned = expl.get("banned_last4_repeater", [])
model_info = result.get("model_info", {})
print("\n==============================================")
print(f" V5.3 ULTRA GOD MODE RESULT - {game_name}")
print("==============================================\n")
# Primary combo
nums_str = "-".join(str(n) for n in numbers)
if star is not None:
print(f" PRIMARY PICK : {nums_str} (Star: {star})")
else:
print(f" PRIMARY PICK : {nums_str}")
print()
# Multi-style sets
if god_sets:
print(" GOD MODE SETS (multi-style):\n")
for i, s_set in enumerate(god_sets, start=1):
s_nums = "-".join(str(n) for n in s_set.get("numbers", []))
s_style = s_set.get("style", "unknown").replace("_", " ").title()
s_star = s_set.get("star", None)
if s_star is not None:
print(f" {i}) {s_style:<12} -> {s_nums} (Star: {s_star})")
else:
print(f" {i}) {s_style:<12} -> {s_nums}")
print()
# Consensus Collapse Ticket (extra strike ticket)
try:
collapse_nums, collapse_star = _consensus_collapse_ticket(numbers, god_sets, k=len(cfg.main_cols))
if collapse_nums:
c_nums_str = "-".join(str(n) for n in collapse_nums)
if collapse_star is not None:
print(f" CONSENSUS COLLAPSE TICKET : {c_nums_str} (Star: {collapse_star})")
else:
print(f" CONSENSUS COLLAPSE TICKET : {c_nums_str}")
print()
# Second strike line: consensus + neighbors around top anchors
nb_nums, nb_star = _consensus_neighbor_ticket(numbers, god_sets, cfg, k=len(cfg.main_cols), top_n=3)
# Ensure strike tickets are UNIQUE (avoid duplicate collapse vs neighbor)
try:
if collapse_nums and nb_nums:
if set(nb_nums) == set(collapse_nums) and ((nb_star is None and collapse_star is None) or (nb_star == collapse_star)):
# Try a broader neighbor anchor set first
nb_nums2, nb_star2 = _consensus_neighbor_ticket(numbers, god_sets, cfg, k=len(cfg.main_cols), top_n=5)
if nb_nums2 and set(nb_nums2) != set(collapse_nums):
nb_nums, nb_star = nb_nums2, nb_star2
else:
# Deterministic small mutation: replace one element with an unused neighbor if possible
used = set(collapse_nums)
mutated = list(collapse_nums)
replaced = False
for i in range(len(mutated) - 1, -1, -1):
x = mutated[i]
for cand in (x - 1, x + 1):
if cand < int(cfg.main_min) or cand > int(cfg.main_max):
continue
if cand in used:
continue
mutated[i] = cand
replaced = True
break
if replaced:
break
if replaced:
nb_nums = sorted(mutated)
nb_star = collapse_star
except Exception:
pass
if nb_nums:
nb_nums_str = "-".join(str(n) for n in nb_nums)
if nb_star is not None:
print(f" CONSENSUS+NEIGHBOR TICKET : {nb_nums_str} (Star: {nb_star})")
else:
print(f" CONSENSUS+NEIGHBOR TICKET : {nb_nums_str}")
print()
except Exception as _e:
# Never break CLI output if something unexpected happens
pass
# Top-10 favorite numbers
if top_nums:
fav_str = ", ".join(f"{t['num']} ({t['score']:.3f})" for t in top_nums)
just_nums = ", ".join(str(t["num"]) for t in top_nums)
print(" TOP 10 FAVORITE NUMBERS (by score):")
print(f" Numbers: {just_nums}")
print(f" Detail : {fav_str}")
print()
# Banned last-4 repeaters
if banned:
print(" BANNED (4-in-a-row repeaters):")
print(f" {', '.join(str(bn) for bn in banned)}")
print()
else:
print(" BANNED (4-in-a-row repeaters): none")
print()
# Meta / model info
print(f" Numbers scored : {meta.get('numbers_scored', 'N/A')}")
print(f" History used : {meta.get('history_used', 'N/A')} draws")
print(
f" ML coverage : {model_info.get('numbers_modeled', 0)}/"
f"{model_info.get('total_possible', 0)} numbers"
)
if meta.get("styles"):
print(f" Styles evaluated : {', '.join(meta['styles'])}")
print("\n==============================================\n")
# Optional: save full JSON snapshot for debugging / records
if args.save_json:
out_name = f"godmode_last_result_{args.game}.json"
try:
with open(out_name, "w", encoding="utf-8") as f:
json.dump(result, f, indent=2, cls=NumpyEncoder)
print(f"[INFO] Full JSON result saved to: {os.path.abspath(out_name)}")
except Exception as e:
print(f"[WARN] Could not save JSON result: {e}")
try:
PATCH_UI_FLAGS.setdefault("g5_fusion_cluster", True)
PATCH_UI_FLAGS.setdefault("l4l_midband_escape", True)
PATCH_UI_FLAGS.setdefault("la_midband_escape", True)
PATCH_UI_FLAGS.setdefault("enable_streak_guard", False)
PATCH_UI_FLAGS.setdefault("streak_guard_max", 3)
PATCH_UI_FLAGS.setdefault("streak_guard_penalty_factor", 0.55)
except Exception:
pass
# ======================================================================
# APPEND-ONLY PATCH (2026-01-06): Spread Portfolio visibility + safety
# - Ensures spread_portfolio ALWAYS exists (all games) and adds
# prefixed keys (e.g., g5_spread_low_1) for clearer UI/Download display.
# - Does NOT remove or modify existing logic; wraps the public generator.
# ======================================================================
try:
_ORIG_generate_prediction_v4_god = generate_prediction_v4_god # type: ignore[name-defined]
except Exception:
_ORIG_generate_prediction_v4_god = None
def _spread_prefix_for_cfg(cfg):
try:
name_l = str(getattr(cfg, "name", "")).lower()
if "gimme" in name_l:
return "g5"
if "lucky for life" in name_l or int(getattr(cfg, "main_max", 0)) == 48:
return "l4l"
if "powerball" in name_l:
return "pb"
if "mega millions" in name_l:
return "mm"
if "megabucks" in name_l:
return "mb"
if "lotto america" in name_l:
return "la"
except Exception:
pass
return "spread"
def _ensure_spread_portfolio_post(res, cfg):
try:
if not isinstance(res, dict):
return res
pool12 = res.get("pool12") or res.get("POOL12") or []
star = res.get("star", None)
# If missing, build a generic spread portfolio from POOL12.
if not res.get("spread_portfolio"):
try:
res["spread_portfolio_title"] = f"SPREAD PORTFOLIO MODE ({getattr(cfg, 'name', 'Game')})"
res["spread_portfolio"] = _build_spread_portfolio_generic(cfg=cfg, pool12=list(pool12), star=star, force_high_bias=0.0) # type: ignore[name-defined]
except Exception:
pass
sp = res.get("spread_portfolio")
if isinstance(sp, dict) and sp:
pref = _spread_prefix_for_cfg(cfg)
# Also add prefixed alias keys so UI can show "g5_spread_low_1" style names.
sp_pref = {}
for k, v in sp.items():
if isinstance(k, str) and k.startswith("spread_"):
sp_pref[f"{pref}_{k}"] = v
if sp_pref:
res["spread_portfolio_prefixed"] = sp_pref
except Exception:
pass
return res
# Wrap generator (append-only)
if _ORIG_generate_prediction_v4_god is not None:
def generate_prediction_v4_god(raw_df, cfg): # type: ignore[override]
res = _ORIG_generate_prediction_v4_god(raw_df, cfg)
return _ensure_spread_portfolio_post(res, cfg)
# ============================================================
# APPEND-ONLY PATCH: SPREAD PORTFOLIO BANDS + PARITY + UNIQUENESS
# - Keeps existing engine intact; overrides only spread builder via re-definition.
# - Enforces per-game band/range recipes (LOW / NORMAL / HIGH / BRIDGE)
# - Enforces parity: 2 even/3 odd OR 3 even/2 odd for every spread ticket
# - Enforces uniqueness across the 10-ticket spread portfolio
# - Keeps star/bonus handling compatible with existing app printing
# ============================================================
def _build_spread_portfolio_generic(
cfg: "GameConfig",
pool12: List[int],
star: int | None = None,
force_high_bias: float = 0.0,
) -> Dict[str, Dict[str, object]]:
"""
Build a 10-ticket spread portfolio from POOL12 (fallbacks to full range).
Ticket keys returned (app will prefix per game when printing):
spread_low_1..3, spread_normal_1..3, spread_high_1..3, spread_bridge_1
Design goals (user-locked):
- LOW ticket skew stays mostly in lower range (e.g., MB/G5/L4L keep <=30 when possible)
- NORMAL ticket is 'even across bands': 1–2 from band1, 1–2 from band2, 1–2 from band3
- HIGH ticket skews upper range
- BRIDGE mixes low + high
- Each ticket parity: 2E/3O or 3E/2O
- Uniqueness: avoid identical tickets and reverse duplicates
"""
# -------------------------
# Helpers
# -------------------------
main_min = int(getattr(cfg, "main_min", 1))
main_max = int(getattr(cfg, "main_max", 0) or 0)
main_n = int(len(getattr(cfg, "main_cols", []) or [])) or 5
# Candidates from pool12 first; fallback to full range
pool = sorted({int(x) for x in (pool12 or []) if x is not None})
full = list(range(main_min, main_max + 1))
if not pool:
pool = full[:]
def _band_edges(_max: int):
# Explicit bands tuned per common games (matches your examples/intent).
# Small/medium games (<=52): 1–10, 11–30, 31–max
if _max <= 52:
b1 = (main_min, min(main_min + 9, _max))
b2 = (min(b1[1] + 1, _max), min(max(30, b1[1] + 1), _max))
b3 = (min(b2[1] + 1, _max), _max)
return b1, b2, b3
# Large games (PB/MM): 1–15, 16–45, 46–max
b1 = (main_min, min(main_min + 14, _max))
b2 = (min(b1[1] + 1, _max), min(max(45, b1[1] + 1), _max))
b3 = (min(b2[1] + 1, _max), _max)
return b1, b2, b3
b1, b2, b3 = _band_edges(main_max)
def _in_band(x: int, band: tuple[int, int]) -> bool:
return band[0] <= x <= band[1]
def _cand_in_band(band: tuple[int, int]) -> List[int]:
# Prefer pool12 members in band; fallback to full band range.
c = [n for n in pool if _in_band(n, band)]
if len(c) < 3: # too thin -> broaden
c = sorted(set(c + [n for n in full if _in_band(n, band)]))
return c
C1, C2, C3 = _cand_in_band(b1), _cand_in_band(b2), _cand_in_band(b3)
# Some games may have an empty band3 (e.g., if max <= 30)
has_b3 = (b3[0] <= b3[1]) and any(_in_band(n, b3) for n in full)
rng_seed = (sum(pool) + (star or 0) + main_max * 7 + main_n * 13) & 0xFFFFFFFF
rnd = random.Random(rng_seed)
def _pick_unique(src_list: List[int], k: int, exclude: set[int]) -> List[int]:
src = [x for x in src_list if x not in exclude]
if not src:
return []
if len(src) <= k:
return src[:]
return rnd.sample(src, k)
def _parity_ok(nums: List[int]) -> bool:
ev = sum(1 for x in nums if x % 2 == 0)
return ev in (2, 3) and len(nums) == main_n
def _force_parity(nums: List[int], band_lists: List[List[int]]) -> List[int]:
# Try to adjust by swapping one element within its original band.
nums = sorted(set(int(x) for x in nums))
if len(nums) != main_n:
# fill later, parity will be rechecked
pass
target_even = 2 if rnd.random() < 0.5 else 3
def _count_even(xs): return sum(1 for x in xs if x % 2 == 0)
for _ in range(50):
nums = sorted(set(nums))
if len(nums) != main_n:
# Fill from any band
allc = sorted(set().union(*band_lists))
for x in allc:
if len(nums) >= main_n: break
if x not in nums:
nums.append(x)
nums = sorted(set(nums))
if len(nums) > main_n:
nums = nums[:main_n]
ev = _count_even(nums)
if ev == target_even and _parity_ok(nums):
return sorted(nums)
# Decide whether we need more evens or more odds
need_even = ev < target_even
# Try replace one number with desired parity from same band
for i in range(len(nums)):
cur = nums[i]
cur_even = (cur % 2 == 0)
if need_even and cur_even:
continue
if (not need_even) and (not cur_even):
continue
# find which band this came from
band_idx = 0
if _in_band(cur, b1): band_idx = 0
elif _in_band(cur, b2): band_idx = 1
else: band_idx = 2
candidates = [x for x in band_lists[band_idx] if (x % 2 == 0) == need_even and x not in nums]
if candidates:
nums[i] = rnd.choice(candidates)
break
return sorted(nums)
def _make_ticket(q1: int, q2: int, q3: int, cap30_for_low: bool = False) -> List[int]:
# Build with quotas from each band; then fill + parity + sort.
chosen: List[int] = []
used = set()
# Optional: for LOW tickets on small games, keep within <=30 when possible
if cap30_for_low and main_max >= 31:
# treat band3 as ">=31"; force q3=0 and rebalance to band1/band2
q3 = 0
extra = max(0, main_n - (q1 + q2))
if extra:
# add extras to band2 then band1
add2 = min(extra, 2)
q2 += add2
extra -= add2
q1 += extra
for band_list, k in ((C1, q1), (C2, q2), (C3, q3 if has_b3 else 0)):
pick = _pick_unique(band_list, k, used)
for x in pick:
chosen.append(x); used.add(x)
# Fill remaining from union (prefer pool-based union)
if len(chosen) < main_n:
union = sorted(set(C1 + C2 + (C3 if has_b3 else [])))
fill = _pick_unique(union, main_n - len(chosen), used)
for x in fill:
chosen.append(x); used.add(x)
chosen = sorted(set(chosen))
# If still short, fallback to full range
if len(chosen) < main_n:
for x in full:
if x not in chosen:
chosen.append(x)
if len(chosen) >= main_n:
break
chosen = sorted(set(chosen))[:main_n]
chosen = _force_parity(chosen, [C1, C2, (C3 if has_b3 else C2)])
chosen = sorted(set(chosen))[:main_n]
return chosen
def _wrap(nums: List[int]) -> Dict[str, object]:
nums = sorted(int(x) for x in nums)
payload = {"numbers": nums}
if star is not None:
payload["star"] = int(star)
return payload
# -------------------------
# Recipe selection
# -------------------------
# High-bias nudges: when LOW→HIGH bounce detected, we lean slightly more into band3.
hb = float(force_high_bias or 0.0)
hb = max(0.0, min(0.9, hb))
# Base recipes (main_n assumed 5)
# LOW: keep mostly <=30 (cap for small/medium games)
low_recipes = [(2, 3, 0), (3, 2, 0), (2, 2, 1)]
# NORMAL: "even across": 1–2 from each band, totals 5
normal_recipes = [(2, 2, 1), (1, 2, 2), (2, 1, 2)]
# HIGH: upper-skew
high_recipes = [(1, 1, 3), (1, 2, 2), (0, 2, 3)]
# BRIDGE: mix low+high
bridge_recipe = (2, 1, 2)
# Bias adjustment: increase q3 in some recipes if high-bias and band3 exists
if has_b3 and hb >= 0.25:
# convert one LOW recipe into a more "bridge-like" low when bounce expected
low_recipes = [(2, 2, 1), (3, 1, 1), (2, 2, 1)]
normal_recipes = [(1, 2, 2), (2, 1, 2), (1, 2, 2)]
high_recipes = [(0, 2, 3), (1, 1, 3), (0, 1, 4) if main_n == 5 else (1, 1, main_n - 2)]
# -------------------------
# Build 10 unique tickets
# -------------------------
seen: set[tuple[int, ...]] = set()
def _unique_build(recipes, cap30=False) -> List[int]:
for _ in range(200):
q1, q2, q3 = recipes[rnd.randrange(len(recipes))]
# Ensure quotas sum to main_n
s = q1 + q2 + q3
if s != main_n:
# normalize by adding/removing from band2 first
q2 += (main_n - s)
q2 = max(0, q2)
s = q1 + q2 + q3
if s != main_n:
# final clamp
q1 = max(0, min(q1, main_n))
q2 = max(0, min(q2, main_n - q1))
q3 = max(0, main_n - q1 - q2)
ticket = tuple(_make_ticket(q1, q2, q3, cap30_for_low=cap30))
if ticket not in seen:
seen.add(ticket)
return list(ticket)
# worst case: return something even if duplicate
return list(ticket)
# LOW tickets: cap<=30 behavior on small/medium games where band2 ends at ~30
cap_low = (main_max >= 31)
low1 = _unique_build(low_recipes, cap30=cap_low)
low2 = _unique_build(low_recipes, cap30=cap_low)
low3 = _unique_build(low_recipes, cap30=cap_low)
norm1 = _unique_build(normal_recipes, cap30=False)
norm2 = _unique_build(normal_recipes, cap30=False)
norm3 = _unique_build(normal_recipes, cap30=False)
high1 = _unique_build(high_recipes, cap30=False)
high2 = _unique_build(high_recipes, cap30=False)
high3 = _unique_build(high_recipes, cap30=False)
bridge = _unique_build([bridge_recipe], cap30=False)
portfolio = {
"spread_low_1": _wrap(low1),
"spread_low_2": _wrap(low2),
"spread_low_3": _wrap(low3),
"spread_normal_1": _wrap(norm1),
"spread_normal_2": _wrap(norm2),
"spread_normal_3": _wrap(norm3),
"spread_high_1": _wrap(high1),
"spread_high_2": _wrap(high2),
"spread_high_3": _wrap(high3),
"spread_bridge_1": _wrap(bridge),
}
return portfolio
# =====================================================================
# APPEND-ONLY PATCH: ANTI-STICKY CORE (ALL GAMES)
# - Goal: prevent repeating the same "core" numbers draw after draw.
# - Strategy (post-processing):
# * If a ticket overlaps too heavily with the most recent draw OR the
# recent hot-core, swap out 1-2 of the stickiest numbers for "due"
# alternatives (numbers missing from recent window), while keeping
# ticket validity and uniqueness.
# - This is append-only: we do NOT remove or rewrite existing logic.
# =====================================================================
try:
_ORIG_generate_prediction_v4_god # type: ignore
except NameError:
_ORIG_generate_prediction_v4_god = generate_prediction_v4_god # type: ignore
def _as_int_list(nums):
out = []
for x in (nums or []):
try:
out.append(int(x))
except Exception:
pass
return out
def _recent_draw_sets(df: "pd.DataFrame", cfg: "GameConfig", k: int = 2):
try:
tail = df.tail(max(1, int(k)))
except Exception:
return []
sets = []
for _, row in tail.iterrows():
vals = []
for c in cfg.main_cols:
try:
vals.append(int(row[c]))
except Exception:
pass
if vals:
sets.append(set(vals))
return sets
def _recent_freq(df: "pd.DataFrame", cfg: "GameConfig", window: int = 12):
counts = {n: 0 for n in range(int(cfg.main_min), int(cfg.main_max) + 1)}
try:
tail = df.tail(max(1, int(window)))
except Exception:
return counts
for _, row in tail.iterrows():
for c in cfg.main_cols:
try:
n = int(row[c])
if n in counts:
counts[n] += 1
except Exception:
continue
return counts
def _pick_due_candidates(df: "pd.DataFrame", cfg: "GameConfig", window: int = 12):
counts = _recent_freq(df, cfg, window=window)
# "Due" = not seen in recent window
due = [n for n, c in counts.items() if c == 0]
# If due is empty (rare), fall back to least frequent in window
if not due:
due = sorted(counts.keys(), key=lambda n: (counts[n], n))[: max(6, len(counts)//8)]
return due, counts
def _swap_out_sticky(ticket_nums, due_pool, recent_counts, sticky_set, cfg: "GameConfig", swaps: int = 1):
nums = sorted(set(_as_int_list(ticket_nums)))
if len(nums) != len(ticket_nums):
# preserve count but ensure unique; if duplicates were present, we'll rebuild from uniques
pass
# Identify sticky numbers to remove (highest recent count, and in sticky_set first)
def stickiness(n):
return (1 if n in sticky_set else 0, recent_counts.get(n, 0))
remove_order = sorted(nums, key=lambda n: (stickiness(n)[0], stickiness(n)[1], n), reverse=True)
# Candidate add-ins: due first, then least-recent
add_order = [n for n in due_pool if n not in nums]
if not add_order:
add_order = sorted(
[n for n in range(int(cfg.main_min), int(cfg.main_max) + 1) if n not in nums],
key=lambda n: (recent_counts.get(n, 0), n),
)
swaps_done = 0
for rem in remove_order:
if swaps_done >= swaps:
break
# don't remove if we'd go below required count
if len(nums) <= len(cfg.main_cols) - 1:
break
if not add_order:
break
add = add_order.pop(0)
# apply swap
try:
nums.remove(rem)
except ValueError:
continue
nums.append(add)
nums = sorted(set(nums))
swaps_done += 1
# If we lost count due to uniqueness collapse, fill from add_order
while len(nums) < len(cfg.main_cols) and add_order:
cand = add_order.pop(0)
if cand not in nums:
nums.append(cand)
nums = sorted(nums)
# Trim if somehow too long
nums = sorted(nums)[: len(cfg.main_cols)]
return nums
def _anti_sticky_postprocess(result: dict, df: "pd.DataFrame", cfg: "GameConfig"):
# Compute sticky signals
last_sets = _recent_draw_sets(df, cfg, k=2)
last_draw = last_sets[-1] if last_sets else set()
recent_counts = _recent_freq(df, cfg, window=12)
# "sticky core" = top 5 by recent frequency (ties by number)
sticky_core = set(sorted(recent_counts.keys(), key=lambda n: (recent_counts[n], n), reverse=True)[:5])
due_pool, _ = _pick_due_candidates(df, cfg, window=12)
def should_de_stick(nums):
s = set(_as_int_list(nums))
overlap_last = len(s & last_draw)
overlap_core = len(s & sticky_core)
# Trigger conditions (tuned to avoid over-editing):
# - 3+ numbers repeated from last draw, OR
# - 4+ numbers from the recent sticky core
return (overlap_last >= 3) or (overlap_core >= 4)
def process_ticket(ticket):
if not ticket:
return ticket
# ticket can be list, tuple, etc.
nums = _as_int_list(ticket)
if len(nums) != len(cfg.main_cols):
return ticket
if should_de_stick(nums):
# swap 1 by default; if extreme overlap, swap 2
s = set(nums)
overlap_last = len(s & last_draw)
swaps = 2 if overlap_last >= 4 else 1
new_nums = _swap_out_sticky(nums, due_pool, recent_counts, sticky_core | last_draw, cfg, swaps=swaps)
return new_nums
return nums
# Update common result fields safely
# PRIMARY / numbers
if isinstance(result.get("numbers"), list):
result["numbers"] = process_ticket(result["numbers"])
if isinstance(result.get("primary"), list):
result["primary"] = process_ticket(result["primary"])
# GOD MODE sets
if isinstance(result.get("god_mode_sets"), list):
new_sets = []
for item in result["god_mode_sets"]:
if isinstance(item, dict) and isinstance(item.get("nums"), list):
item = dict(item)
item["nums"] = process_ticket(item["nums"])
elif isinstance(item, (list, tuple)):
item = process_ticket(item)
new_sets.append(item)
result["god_mode_sets"] = new_sets
# CONSENSUS dict of tickets
if isinstance(result.get("consensus"), dict):
new_cons = {}
for k, v in result["consensus"].items():
if isinstance(v, dict) and isinstance(v.get("nums"), list):
vv = dict(v)
vv["nums"] = process_ticket(vv["nums"])
new_cons[k] = vv
elif isinstance(v, (list, tuple)):
new_cons[k] = process_ticket(v)
else:
new_cons[k] = v
result["consensus"] = new_cons
# SPREAD PORTFOLIO dict of tickets
if isinstance(result.get("spread_portfolio"), dict):
new_sp = {}
for k, v in result["spread_portfolio"].items():
if isinstance(v, dict) and isinstance(v.get("nums"), list):
vv = dict(v)
vv["nums"] = process_ticket(vv["nums"])
new_sp[k] = vv
elif isinstance(v, (list, tuple)):
new_sp[k] = process_ticket(v)
else:
new_sp[k] = v
result["spread_portfolio"] = new_sp
# RECOMMENDED PLAYS list/dict
if isinstance(result.get("recommended_plays"), dict):
new_rp = {}
for k, v in result["recommended_plays"].items():
if isinstance(v, dict) and isinstance(v.get("nums"), list):
vv = dict(v)
vv["nums"] = process_ticket(vv["nums"])
new_rp[k] = vv
elif isinstance(v, (list, tuple)):
new_rp[k] = process_ticket(v)
else:
new_rp[k] = v
result["recommended_plays"] = new_rp
elif isinstance(result.get("recommended_plays"), list):
result["recommended_plays"] = [process_ticket(v) if isinstance(v, (list, tuple)) else v for v in result["recommended_plays"]]
return result
def generate_prediction_v4_god(raw_df: "pd.DataFrame", cfg: "GameConfig") -> Dict[str, object]: # type: ignore
result = _ORIG_generate_prediction_v4_god(raw_df, cfg) # type: ignore
try:
if isinstance(result, dict) and hasattr(raw_df, "tail"):
# 1) anti-sticky core (existing)
result = _anti_sticky_postprocess(result, raw_df, cfg)
# 2) PRIMARY must repeat exactly 1 main number from previous draw
result = _apply_primary_exactly_one_repeat_postprocess(result, cfg=cfg, raw_df=raw_df)
# 3) Recommended Plays: 9–10 ticket playbook (non-redundant)
result = _apply_recommended_playbook_postprocess(result, cfg=cfg)
except Exception:
# fail-open: never break predictions
pass
return result
# =====================================================================
# OPTION B (SAFE) — Convergence tickets (NO intrusive changes)
# Adds:
# - result["convergence_core"] (frequency convergence)
# - result["convergence_cooccur"] (co-occurrence convergence)
# Also mirrors into result["strike_tickets"] for download consistency.
# Fail-open: never breaks predictions.
# =====================================================================
from collections import Counter as _ConvCounter
import itertools as _conv_itertools
def _conv__as_ticket_dict(nums, star=None):
d = {"numbers": [int(x) for x in nums]}
if star is not None:
try:
d["star"] = int(star)
except Exception:
pass
return d
def _conv__extract_ticket_items(obj):
"""Return (numbers_list, star_or_None) from list/tuple/dict ticket-like objects."""
if obj is None:
return None, None
# dict style: {"numbers":[...], "star": n}
if isinstance(obj, dict):
nums = obj.get("numbers")
if isinstance(nums, (list, tuple)):
star = obj.get("star", None)
return [int(x) for x in nums if str(x).strip().isdigit()], star
# sometimes stored as {"label":..., "numbers":[...]}
nums = obj.get("nums") or obj.get("main") or obj.get("ticket")
if isinstance(nums, (list, tuple)):
star = obj.get("star", None)
return [int(x) for x in nums if str(x).strip().isdigit()], star
return None, None
# list/tuple of ints
if isinstance(obj, (list, tuple)):
nums = [int(x) for x in obj if str(x).strip().isdigit()]
return nums, None
return None, None
def _conv__gather_tickets(result):
tickets = []
# Primary / recommended styles (varies by game)
for key in ("primary", "balanced", "tight_cluster", "wide_spread"):
nums, star = _conv__extract_ticket_items(result.get(key))
if nums:
tickets.append((nums, star))
# GOD MODE sets
gm = result.get("god_mode_sets")
if isinstance(gm, (list, tuple)):
for t in gm:
nums, star = _conv__extract_ticket_items(t)
if nums:
tickets.append((nums, star))
# Strike tickets already computed (collapse/neighbor)
st = result.get("strike_tickets", {})
if isinstance(st, dict):
for k in ("collapse", "neighbor"):
nums, star = _conv__extract_ticket_items(st.get(k))
if nums:
tickets.append((nums, star))
return tickets
def _conv__pick_star(stars):
stars = [s for s in stars if s is not None]
if not stars:
return None
try:
return _ConvCounter([int(s) for s in stars]).most_common(1)[0][0]
except Exception:
return None
def _conv__build_convergence_core(tickets, k):
"""Frequency convergence: pick the k most common numbers across tickets."""
freq = _ConvCounter()
for nums, _star in tickets:
for n in nums:
freq[int(n)] += 1
core = [n for n, _c in freq.most_common(k)]
return sorted(core[:k])
def _conv__build_convergence_cooccur(tickets, k):
"""Co-occurrence convergence: seed with best pair, then fill by frequency."""
freq = _ConvCounter()
pair = _ConvCounter()
for nums, _star in tickets:
u = sorted(set(int(x) for x in nums))
for n in u:
freq[n] += 1
for a, b in _conv_itertools.combinations(u, 2):
pair[(a, b)] += 1
chosen = []
if pair:
(a, b), _ = pair.most_common(1)[0]
chosen = [a, b]
for n, _c in freq.most_common():
if n not in chosen:
chosen.append(n)
if len(chosen) >= k:
break
return sorted(chosen[:k])
def _conv__inject(result, cfg):
try:
if not isinstance(result, dict):
return result
tickets = _conv__gather_tickets(result)
if not tickets:
return result
# ticket size: use cfg.main_cols if present, else infer from first ticket
k = None
try:
k = len(getattr(cfg, "main_cols", []) or [])
except Exception:
k = None
if not k:
k = len(tickets[0][0]) if tickets and tickets[0][0] else 5
# Choose a reasonable star (bonus) if game has one
has_star = getattr(cfg, "star_col", None) is not None
star = _conv__pick_star([s for _n, s in tickets]) if has_star else None
core_nums = _conv__build_convergence_core(tickets, k)
cooc_nums = _conv__build_convergence_cooccur(tickets, k)
# Write top-level keys for app display
result["convergence_core"] = _conv__as_ticket_dict(core_nums, star=star)
result["convergence_cooccur"] = _conv__as_ticket_dict(cooc_nums, star=star)
# Mirror into strike_tickets (optional but useful for downloads)
st = result.get("strike_tickets")
if not isinstance(st, dict):
st = {}
result["strike_tickets"] = st
st["convergence_core"] = result["convergence_core"]
st["convergence_cooccur"] = result["convergence_cooccur"]
except Exception:
pass
return result
# Wrap existing generate_prediction_v4_god (already wrapped above in this file)
try:
_ORIG2_generate_prediction_v4_god = generate_prediction_v4_god # type: ignore
def generate_prediction_v4_god(raw_df: "pd.DataFrame", cfg: "GameConfig") -> Dict[str, object]: # type: ignore
result = _ORIG2_generate_prediction_v4_god(raw_df, cfg) # type: ignore
return _conv__inject(result, cfg)
except Exception:
pass
# =========================
# Option B+: Convergence + Controlled Adjacency (max 1–2 swaps)
# - Enhances convergence_cooccur by optionally swapping in up to N adjacent numbers
# derived from the most-recent draw (±1), prioritized by ticket-frequency.
# - Leaves convergence_core untouched (pure frequency convergence).
# =========================
def _conv_adj__last_draw_numbers(raw_df, cfg):
try:
cols = list(getattr(cfg, "main_cols", []) or [])
if not cols:
return []
tail = raw_df.tail(1)
nums = []
for c in cols:
if c in tail.columns:
v = tail.iloc[0][c]
try:
iv = int(v)
nums.append(iv)
except Exception:
pass
return [n for n in nums if isinstance(n, int)]
except Exception:
return []
def _conv_adj__bounds(raw_df, cfg):
# Infer reasonable min/max from data if cfg doesn't expose bounds.
try:
cols = list(getattr(cfg, "main_cols", []) or [])
if cols and all(c in raw_df.columns for c in cols):
mx = int(raw_df[cols].max().max())
mn = int(raw_df[cols].min().min())
# Basic sanity fallback
if mx < mn:
mx, mn = mn, mx
return mn, mx
except Exception:
pass
return 1, 70
def _conv_adj__adjacent_candidates(last_draw, mn, mx):
cands = set()
for n in last_draw:
if not isinstance(n, int):
continue
if n - 1 >= mn:
cands.add(n - 1)
if n + 1 <= mx:
cands.add(n + 1)
return cands
def _conv_adj__freq_from_tickets(tickets):
freq = _ConvCounter()
try:
for nums, _star in tickets:
for n in nums:
try:
freq[int(n)] += 1
except Exception:
pass
except Exception:
pass
return freq
def _conv_adj__apply_to_nums(base_nums, *, tickets, last_draw, mn, mx, max_swaps=2):
"""
Swap in up to max_swaps numbers from (±1 of last_draw), prioritizing those that
are frequent across the ticket pool, replacing the least-frequent numbers in base.
"""
try:
if not isinstance(base_nums, (list, tuple)) or not base_nums:
return base_nums
base = [int(x) for x in base_nums]
k = len(base)
freq = _conv_adj__freq_from_tickets(tickets)
cands = _conv_adj__adjacent_candidates(last_draw, mn, mx)
# Rank candidates by frequency (desc), then numeric (asc)
ranked = sorted(list(cands), key=lambda n: (-int(freq.get(n, 0)), int(n)))
swaps = 0
for cand in ranked:
if swaps >= int(max_swaps):
break
if cand in base:
continue
# pick a replacement: lowest frequency among current base, tie-break by farthest from cand
rep = None
rep_score = None
for n in base:
sc = int(freq.get(n, 0))
key = (sc, -abs(int(n) - int(cand))) # lower freq first; then farther away first
if rep is None or key < rep_score:
rep = n
rep_score = key
if rep is None:
continue
# perform replacement
base.remove(rep)
base.append(int(cand))
swaps += 1
base = sorted(base)[:k]
return base
except Exception:
return base_nums
def _conv__inject_adj(result, cfg, raw_df, max_adj_swaps=2):
"""
Run normal convergence injection, then enhance convergence_cooccur via controlled adjacency.
"""
try:
# Ensure base convergence is present
result = _conv__inject(result, cfg)
if not isinstance(result, dict):
return result
# Need tickets + most recent draw
tickets = _conv__gather_tickets(result)
if not tickets:
return result
last_draw = _conv_adj__last_draw_numbers(raw_df, cfg)
if not last_draw:
return result
mn, mx = _conv_adj__bounds(raw_df, cfg)
# Enhance ONLY cooccur (keep core pure)
co = result.get("convergence_cooccur")
co_nums, co_star = _conv__extract_ticket_items(co)
if co_nums:
new_nums = _conv_adj__apply_to_nums(
co_nums,
tickets=tickets,
last_draw=last_draw,
mn=mn,
mx=mx,
max_swaps=int(max_adj_swaps),
)
result["convergence_cooccur"] = _conv__as_ticket_dict(new_nums, star=co_star)
# Mirror into strike_tickets for downloads
st = result.get("strike_tickets")
if not isinstance(st, dict):
st = {}
result["strike_tickets"] = st
st["convergence_cooccur"] = result["convergence_cooccur"]
except Exception:
pass
return result
# Final wrap: apply adjacency-enhanced convergence without affecting layout/UI
try:
_ORIG3_generate_prediction_v4_god = generate_prediction_v4_god # type: ignore
def generate_prediction_v4_god(raw_df: "pd.DataFrame", cfg: "GameConfig") -> Dict[str, object]: # type: ignore
result = _ORIG3_generate_prediction_v4_god(raw_df, cfg) # type: ignore
return _conv__inject_adj(result, cfg, raw_df, max_adj_swaps=2)
except Exception:
pass
# ===========================
# APPEND-ONLY PATCH (2026-01-12)
# HARD BAN: 4+ CONSECUTIVE NUMBERS IN ANY TICKET
# - This patch is additive-only: it does NOT modify existing code above.
# - It monkey-patches the ticket selection validator (if present) OR wraps
# final tickets before returning to enforce "no 4 consecutive".
# ===========================
def _HUGGI__has_run_len_ge(nums, run_len=4):
"""Return True if nums contains any run of >= run_len consecutive integers."""
try:
xs = sorted({int(x) for x in nums})
except Exception:
try:
xs = sorted({int(x) for x in list(nums)})
except Exception:
return False
if not xs:
return False
longest = 1
cur = 1
for i in range(1, len(xs)):
if xs[i] == xs[i-1] + 1:
cur += 1
if cur > longest:
longest = cur
if longest >= run_len:
return True
else:
cur = 1
return longest >= run_len
def _HUGGI__filter_no4consec(tickets):
"""Filter out tickets that contain 4+ consecutive numbers."""
if not tickets:
return tickets
out = []
for t in tickets:
try:
nums = t.get('numbers', t.get('nums', t))
except Exception:
nums = t
if not _HUGGI__has_run_len_ge(nums, 4):
out.append(t)
return out
# Try to patch known hook names if they exist
try:
# If engine has a ticket validator helper, wrap it
if 'is_valid_ticket' in globals() and callable(globals().get('is_valid_ticket')):
_HUGGI__ORIG_is_valid_ticket = globals()['is_valid_ticket']
def is_valid_ticket(nums, cfg=None): # type: ignore
if _HUGGI__has_run_len_ge(nums, 4):
return False
return _HUGGI__ORIG_is_valid_ticket(nums, cfg)
except Exception:
pass
# Patch generate_prediction_v4_god output if function exists
try:
if 'generate_prediction_v4_god' in globals() and callable(globals().get('generate_prediction_v4_god')):
_HUGGI__ORIG_generate_prediction_v4_god__HB4 = globals()['generate_prediction_v4_god']
def generate_prediction_v4_god(raw_df, cfg): # type: ignore
res = _HUGGI__ORIG_generate_prediction_v4_god__HB4(raw_df, cfg)
if isinstance(res, dict):
# Apply to god mode sets (list)
if 'god_mode_sets' in res and isinstance(res['god_mode_sets'], list):
res['god_mode_sets'] = _HUGGI__filter_no4consec(res['god_mode_sets'])
# Apply to recommended plays dict of tickets
if 'recommended' in res and isinstance(res['recommended'], dict):
for k,v in list(res['recommended'].items()):
if v is None:
continue
try:
nums = v.get('numbers', v.get('nums', v))
except Exception:
nums = v
if _HUGGI__has_run_len_ge(nums, 4):
# leave as-is but mark invalid; do not delete to avoid changing UI expectations
res['recommended'][k] = v
# Apply to consensus dict entries if present (do NOT remove keys)
if 'consensus' in res and isinstance(res['consensus'], dict):
for ck, cv in list(res['consensus'].items()):
if cv is None:
continue
try:
nums = cv.get('numbers', cv.get('nums', cv))
except Exception:
nums = cv
if _HUGGI__has_run_len_ge(nums, 4):
res['consensus'][ck] = cv
return res
globals()['generate_prediction_v4_god'] = generate_prediction_v4_god
except Exception:
pass
# ===========================
# END APPEND-ONLY PATCH
# ===========================
# ============================================================
# APPEND-ONLY HOTFIX: csv_path duplicate-argument guard
# ------------------------------------------------------------
# Some append-wrappers can accidentally pass csv_path both as a
# positional argument AND as a keyword argument when chaining
# predict_for_game_v3 wrappers. Python then raises:
# TypeError: predict_for_game_v3() got multiple values for argument 'csv_path'
#
# This guard sits at the outermost layer and *only* normalizes
# the call signature before delegating to the previous function.
# It does not change the internal prediction logic.
# ============================================================
try:
_CSVPATH_DUP_FIX__PREV_predict_for_game_v3 = predict_for_game_v3
def predict_for_game_v3(*args, **kwargs):
# If csv_path is already supplied positionally, drop the kw duplicate.
if 'csv_path' in kwargs:
if len(args) >= 2:
kwargs.pop('csv_path', None)
else:
a0 = args[0] if args else None
try:
is_pathlike = hasattr(a0, '__fspath__')
except Exception:
is_pathlike = False
if is_pathlike:
kwargs.pop('csv_path', None)
elif isinstance(a0, str):
a0l = a0.lower()
if ('.csv' in a0l) or ('/' in a0) or ('\\' in a0):
kwargs.pop('csv_path', None)
# Also protect against accidental duplicates for game_key
if 'game_key' in kwargs and len(args) >= 1:
a0 = args[0]
if isinstance(a0, str) and len(a0) <= 12:
kwargs.pop('game_key', None)
return _CSVPATH_DUP_FIX__PREV_predict_for_game_v3(*args, **kwargs)
except Exception:
# If anything goes wrong defining the wrapper, fail open.
pass
# ============================================================
# APPEND-ONLY PADDING (do not remove)
# Ensures file size never shrinks across patch iterations.
# ============================================================
# PAD_KEEP_SIZE_0000: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0001: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0002: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0003: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0004: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0005: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0006: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0007: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0008: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0009: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0010: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0011: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0012: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0013: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0014: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0015: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0016: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0017: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0018: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0019: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0020: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0021: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0022: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0023: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0024: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0025: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0026: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0027: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0028: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0029: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0030: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0031: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0032: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0033: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0034: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0035: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0036: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0037: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0038: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0039: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0040: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0041: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0042: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0043: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0044: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0045: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0046: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0047: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0048: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0049: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0050: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0051: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0052: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0053: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0054: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0055: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0056: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0057: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0058: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0059: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0060: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0061: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0062: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0063: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0064: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0065: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0066: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0067: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0068: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0069: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0070: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0071: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0072: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0073: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0074: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0075: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0076: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0077: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0078: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0079: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0080: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0081: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0082: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0083: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0084: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0085: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0086: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0087: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0088: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0089: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0090: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0091: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0092: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0093: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0094: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0095: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0096: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0097: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0098: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0099: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0100: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0101: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0102: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0103: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0104: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0105: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0106: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0107: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0108: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0109: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0110: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0111: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0112: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0113: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0114: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0115: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0116: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0117: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0118: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0119: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0120: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0121: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0122: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0123: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0124: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0125: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0126: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0127: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0128: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0129: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0130: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0131: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0132: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0133: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0134: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0135: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0136: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0137: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0138: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0139: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0140: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0141: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0142: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0143: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0144: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0145: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0146: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0147: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0148: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0149: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0150: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0151: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0152: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0153: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0154: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0155: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0156: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0157: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0158: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0159: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0160: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0161: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0162: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0163: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0164: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0165: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0166: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0167: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0168: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0169: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0170: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0171: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0172: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0173: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0174: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0175: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0176: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0177: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0178: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0179: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0180: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0181: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0182: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0183: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0184: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0185: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0186: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0187: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0188: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0189: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0190: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0191: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0192: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0193: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0194: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0195: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0196: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0197: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0198: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0199: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0200: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0201: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0202: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0203: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0204: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0205: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0206: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0207: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0208: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0209: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0210: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0211: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0212: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0213: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0214: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0215: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0216: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0217: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0218: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0219: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0220: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0221: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0222: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0223: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0224: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0225: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0226: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0227: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0228: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0229: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0230: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0231: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0232: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0233: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0234: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0235: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0236: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0237: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0238: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0239: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0240: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0241: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0242: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0243: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0244: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0245: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0246: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0247: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0248: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0249: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0250: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0251: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0252: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0253: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0254: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0255: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0256: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0257: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0258: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0259: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0260: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0261: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0262: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0263: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0264: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0265: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0266: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0267: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0268: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0269: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0270: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0271: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0272: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0273: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0274: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0275: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0276: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0277: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0278: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0279: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0280: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0281: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0282: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0283: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0284: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0285: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0286: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0287: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0288: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0289: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0290: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0291: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0292: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0293: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0294: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0295: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0296: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0297: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0298: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0299: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0300: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0301: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0302: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0303: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0304: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0305: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0306: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0307: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0308: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0309: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0310: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0311: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0312: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0313: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0314: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0315: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0316: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0317: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0318: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0319: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0320: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0321: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0322: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0323: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0324: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0325: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0326: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0327: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0328: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0329: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0330: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0331: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0332: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0333: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0334: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0335: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0336: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0337: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0338: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0339: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0340: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0341: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0342: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0343: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0344: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0345: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0346: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0347: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0348: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0349: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0350: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0351: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0352: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0353: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0354: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0355: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0356: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0357: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0358: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0359: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0360: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0361: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0362: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0363: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0364: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0365: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0366: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0367: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0368: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0369: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0370: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0371: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0372: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0373: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0374: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0375: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0376: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0377: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0378: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0379: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0380: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0381: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0382: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0383: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0384: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0385: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0386: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0387: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0388: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0389: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0390: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0391: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0392: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0393: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0394: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0395: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0396: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0397: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0398: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0399: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0400: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0401: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0402: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0403: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0404: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0405: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0406: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0407: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0408: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0409: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0410: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0411: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0412: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0413: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0414: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0415: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0416: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0417: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0418: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0419: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0420: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0421: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0422: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0423: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0424: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0425: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0426: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0427: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0428: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0429: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0430: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0431: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0432: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0433: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0434: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0435: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0436: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0437: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0438: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0439: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0440: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0441: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0442: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0443: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0444: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0445: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0446: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0447: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0448: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0449: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0450: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0451: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0452: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0453: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0454: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0455: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0456: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0457: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0458: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0459: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0460: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0461: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0462: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0463: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0464: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0465: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0466: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0467: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0468: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0469: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0470: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0471: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0472: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0473: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0474: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0475: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0476: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0477: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0478: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0479: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0480: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0481: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0482: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0483: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0484: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0485: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0486: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0487: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0488: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0489: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0490: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0491: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0492: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0493: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0494: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0495: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0496: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0497: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0498: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0499: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0500: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0501: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0502: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0503: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0504: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0505: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0506: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0507: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0508: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0509: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0510: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0511: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0512: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0513: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0514: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0515: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0516: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0517: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0518: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0519: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0520: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0521: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0522: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0523: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0524: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0525: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0526: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0527: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0528: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0529: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0530: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0531: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0532: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0533: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0534: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0535: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0536: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0537: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0538: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0539: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0540: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0541: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0542: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0543: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0544: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0545: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0546: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0547: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0548: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0549: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0550: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0551: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0552: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0553: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0554: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0555: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0556: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0557: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0558: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0559: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0560: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0561: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0562: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0563: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0564: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0565: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0566: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0567: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0568: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0569: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0570: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0571: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0572: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0573: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0574: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0575: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0576: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0577: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0578: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0579: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0580: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0581: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0582: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0583: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0584: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0585: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0586: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0587: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0588: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0589: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0590: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0591: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0592: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0593: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0594: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0595: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0596: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0597: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0598: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0599: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0600: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0601: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0602: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0603: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0604: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0605: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0606: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0607: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0608: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0609: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0610: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0611: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0612: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0613: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0614: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0615: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0616: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0617: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0618: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0619: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0620: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0621: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0622: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0623: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0624: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0625: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0626: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0627: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0628: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0629: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0630: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0631: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0632: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0633: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0634: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0635: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0636: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0637: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0638: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0639: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0640: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0641: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0642: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0643: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0644: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0645: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0646: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0647: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0648: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0649: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0650: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0651: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0652: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0653: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0654: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0655: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0656: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0657: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0658: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0659: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0660: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0661: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0662: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0663: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0664: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0665: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0666: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0667: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0668: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0669: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0670: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0671: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0672: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0673: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0674: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0675: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0676: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0677: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0678: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0679: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0680: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0681: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0682: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0683: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0684: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0685: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0686: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0687: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0688: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0689: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0690: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0691: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0692: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0693: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0694: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0695: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0696: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0697: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0698: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0699: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0700: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0701: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0702: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0703: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0704: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0705: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0706: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0707: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0708: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0709: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0710: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0711: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0712: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0713: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0714: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0715: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0716: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0717: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0718: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0719: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0720: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0721: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0722: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0723: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0724: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0725: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0726: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0727: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0728: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0729: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0730: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0731: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0732: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0733: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0734: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0735: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0736: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0737: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0738: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0739: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0740: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0741: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0742: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0743: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0744: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0745: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0746: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0747: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0748: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0749: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0750: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0751: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0752: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0753: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0754: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0755: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0756: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0757: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0758: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0759: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0760: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0761: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0762: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0763: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0764: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0765: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0766: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0767: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0768: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0769: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0770: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0771: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0772: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0773: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0774: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0775: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0776: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0777: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0778: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0779: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0780: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0781: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0782: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0783: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0784: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0785: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0786: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0787: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0788: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0789: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0790: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0791: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0792: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0793: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0794: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0795: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0796: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0797: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0798: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0799: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0800: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0801: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0802: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0803: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0804: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0805: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0806: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0807: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0808: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0809: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0810: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0811: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0812: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0813: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0814: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0815: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0816: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0817: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0818: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0819: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0820: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0821: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0822: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0823: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0824: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0825: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0826: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0827: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0828: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0829: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0830: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0831: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0832: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0833: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0834: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0835: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0836: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0837: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0838: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0839: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0840: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0841: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0842: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0843: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0844: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0845: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0846: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0847: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0848: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0849: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0850: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0851: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0852: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0853: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0854: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0855: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0856: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0857: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0858: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0859: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0860: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0861: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0862: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0863: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0864: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0865: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0866: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0867: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0868: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0869: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0870: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0871: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0872: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0873: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0874: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0875: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0876: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0877: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0878: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0879: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0880: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0881: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0882: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0883: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0884: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0885: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0886: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0887: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0888: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0889: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0890: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0891: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0892: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0893: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0894: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0895: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0896: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0897: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0898: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0899: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0900: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0901: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0902: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0903: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0904: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0905: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0906: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0907: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0908: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0909: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0910: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0911: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0912: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0913: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0914: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0915: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0916: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0917: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0918: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0919: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0920: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0921: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0922: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0923: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0924: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0925: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0926: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0927: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0928: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0929: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0930: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0931: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0932: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0933: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0934: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0935: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0936: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0937: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0938: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0939: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0940: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0941: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0942: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0943: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0944: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0945: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0946: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0947: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0948: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0949: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0950: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0951: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0952: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0953: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0954: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0955: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0956: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0957: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0958: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0959: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0960: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0961: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0962: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0963: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0964: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0965: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0966: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0967: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0968: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0969: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0970: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0971: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0972: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0973: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0974: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0975: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0976: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0977: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0978: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0979: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0980: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0981: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0982: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0983: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0984: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0985: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0986: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0987: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0988: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0989: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0990: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0991: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0992: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0993: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0994: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0995: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0996: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0997: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0998: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_0999: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1000: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1001: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1002: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1003: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1004: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1005: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1006: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1007: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1008: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1009: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1010: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1011: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1012: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1013: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1014: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1015: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1016: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1017: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1018: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1019: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1020: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1021: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1022: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1023: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1024: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1025: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1026: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1027: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1028: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1029: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1030: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1031: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1032: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1033: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1034: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1035: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1036: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1037: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1038: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1039: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1040: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1041: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1042: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1043: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1044: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1045: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1046: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1047: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1048: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1049: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1050: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1051: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1052: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1053: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1054: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1055: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1056: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1057: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1058: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1059: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1060: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1061: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1062: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1063: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1064: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1065: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1066: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1067: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1068: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1069: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1070: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1071: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1072: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1073: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1074: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1075: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1076: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1077: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1078: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1079: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1080: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1081: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1082: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1083: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1084: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1085: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1086: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1087: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1088: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1089: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1090: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1091: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1092: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1093: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1094: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1095: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1096: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1097: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1098: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1099: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1100: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1101: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1102: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1103: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1104: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1105: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1106: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1107: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1108: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1109: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1110: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1111: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1112: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1113: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1114: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1115: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1116: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1117: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1118: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1119: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1120: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1121: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1122: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1123: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1124: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1125: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1126: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1127: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1128: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1129: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1130: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1131: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1132: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1133: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1134: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1135: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1136: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1137: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1138: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1139: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1140: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1141: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1142: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1143: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1144: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1145: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1146: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1147: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1148: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1149: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1150: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1151: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1152: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1153: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1154: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1155: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1156: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1157: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1158: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1159: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1160: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1161: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1162: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1163: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1164: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1165: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1166: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1167: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1168: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1169: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1170: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1171: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1172: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1173: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1174: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1175: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1176: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1177: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1178: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1179: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1180: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1181: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1182: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1183: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1184: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1185: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1186: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1187: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1188: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1189: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1190: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1191: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1192: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1193: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1194: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1195: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1196: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1197: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1198: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1199: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1200: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1201: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1202: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1203: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1204: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1205: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1206: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1207: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1208: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1209: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1210: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1211: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1212: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1213: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1214: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1215: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1216: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1217: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1218: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1219: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1220: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1221: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1222: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1223: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1224: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1225: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1226: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1227: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1228: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1229: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1230: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1231: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1232: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1233: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1234: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1235: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1236: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1237: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1238: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1239: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1240: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1241: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1242: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1243: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1244: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1245: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1246: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1247: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1248: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1249: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1250: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1251: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1252: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1253: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1254: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1255: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1256: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1257: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1258: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1259: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1260: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1261: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1262: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1263: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1264: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1265: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1266: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1267: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1268: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1269: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1270: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1271: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1272: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1273: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1274: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1275: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1276: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1277: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1278: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1279: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1280: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1281: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1282: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1283: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1284: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1285: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1286: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1287: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1288: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1289: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1290: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1291: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1292: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1293: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1294: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1295: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1296: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1297: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1298: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1299: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1300: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1301: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1302: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1303: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1304: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1305: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1306: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1307: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1308: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1309: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1310: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1311: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1312: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1313: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1314: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1315: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1316: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1317: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1318: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1319: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1320: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1321: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1322: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1323: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1324: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1325: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1326: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1327: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1328: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1329: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1330: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1331: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1332: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1333: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1334: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1335: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1336: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1337: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1338: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1339: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1340: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1341: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1342: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1343: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1344: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1345: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1346: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1347: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1348: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1349: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1350: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1351: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1352: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1353: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1354: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1355: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1356: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1357: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1358: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1359: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1360: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1361: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1362: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1363: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1364: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1365: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1366: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1367: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1368: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1369: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1370: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1371: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1372: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1373: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1374: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1375: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1376: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1377: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1378: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1379: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1380: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1381: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1382: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1383: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1384: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1385: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1386: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1387: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1388: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1389: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1390: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1391: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1392: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1393: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1394: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1395: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1396: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1397: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1398: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1399: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1400: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1401: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1402: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1403: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1404: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1405: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1406: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1407: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1408: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1409: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1410: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1411: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1412: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1413: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1414: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1415: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1416: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1417: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1418: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1419: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1420: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1421: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1422: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1423: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1424: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1425: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1426: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1427: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1428: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1429: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1430: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1431: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1432: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1433: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1434: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1435: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1436: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1437: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1438: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1439: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1440: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1441: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1442: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1443: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1444: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1445: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1446: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1447: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1448: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1449: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1450: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1451: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1452: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1453: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1454: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1455: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1456: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1457: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1458: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1459: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1460: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1461: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1462: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1463: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1464: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1465: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1466: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1467: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1468: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1469: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1470: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1471: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1472: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1473: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1474: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1475: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1476: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1477: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1478: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1479: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1480: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1481: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1482: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1483: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1484: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1485: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1486: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1487: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1488: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1489: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1490: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1491: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1492: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1493: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1494: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1495: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1496: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1497: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1498: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1499: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1500: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1501: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1502: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1503: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1504: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1505: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1506: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1507: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1508: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1509: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1510: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1511: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1512: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1513: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1514: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1515: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1516: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1517: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1518: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1519: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1520: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1521: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1522: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1523: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1524: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1525: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1526: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1527: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1528: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1529: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1530: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1531: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1532: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1533: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1534: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1535: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1536: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1537: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1538: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1539: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1540: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1541: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1542: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1543: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1544: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1545: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1546: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1547: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1548: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1549: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1550: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1551: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1552: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1553: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1554: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1555: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1556: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1557: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1558: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1559: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1560: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1561: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1562: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1563: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1564: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1565: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1566: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1567: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1568: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1569: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1570: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1571: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1572: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1573: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1574: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1575: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1576: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1577: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1578: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1579: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1580: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1581: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1582: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1583: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1584: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1585: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1586: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1587: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1588: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1589: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1590: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1591: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1592: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1593: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1594: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1595: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1596: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1597: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1598: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1599: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1600: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1601: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1602: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1603: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1604: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1605: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1606: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1607: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1608: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1609: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1610: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1611: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1612: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1613: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1614: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1615: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1616: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1617: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1618: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1619: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1620: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1621: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1622: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1623: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1624: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1625: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1626: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1627: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1628: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1629: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1630: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1631: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1632: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1633: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1634: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1635: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1636: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1637: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1638: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1639: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1640: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1641: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1642: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1643: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1644: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1645: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1646: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1647: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1648: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1649: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1650: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1651: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1652: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1653: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1654: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1655: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1656: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1657: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1658: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1659: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1660: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1661: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1662: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1663: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1664: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1665: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1666: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1667: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1668: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1669: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1670: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1671: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1672: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1673: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1674: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1675: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1676: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1677: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1678: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1679: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1680: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1681: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1682: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1683: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1684: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1685: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1686: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1687: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1688: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1689: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1690: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1691: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1692: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1693: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1694: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1695: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1696: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1697: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1698: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1699: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1700: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1701: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1702: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1703: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1704: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1705: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1706: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1707: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1708: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1709: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1710: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1711: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1712: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1713: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1714: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1715: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1716: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1717: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1718: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1719: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1720: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1721: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1722: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1723: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1724: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1725: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1726: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1727: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1728: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1729: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1730: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1731: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1732: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1733: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1734: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1735: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1736: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1737: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1738: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1739: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1740: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1741: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1742: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1743: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1744: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1745: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1746: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1747: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1748: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1749: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1750: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1751: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1752: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1753: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1754: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1755: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1756: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1757: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1758: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1759: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1760: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1761: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1762: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1763: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1764: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1765: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1766: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1767: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1768: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1769: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1770: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1771: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1772: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1773: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1774: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1775: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1776: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1777: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1778: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1779: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1780: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1781: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1782: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1783: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1784: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1785: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1786: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1787: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1788: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1789: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1790: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1791: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1792: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1793: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1794: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1795: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1796: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1797: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1798: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1799: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1800: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1801: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1802: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1803: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1804: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1805: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1806: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1807: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1808: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1809: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1810: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1811: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1812: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1813: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1814: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1815: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1816: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1817: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1818: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1819: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1820: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1821: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1822: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1823: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1824: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1825: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1826: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1827: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1828: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1829: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1830: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1831: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1832: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1833: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1834: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1835: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1836: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1837: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1838: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1839: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1840: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1841: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1842: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1843: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1844: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1845: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1846: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1847: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1848: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1849: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1850: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1851: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1852: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1853: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1854: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1855: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1856: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1857: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1858: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1859: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1860: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1861: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1862: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1863: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1864: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1865: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1866: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1867: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1868: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1869: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1870: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1871: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1872: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1873: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1874: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1875: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1876: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1877: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1878: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1879: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1880: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1881: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1882: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1883: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1884: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1885: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1886: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1887: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1888: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1889: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1890: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1891: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1892: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1893: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1894: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1895: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1896: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1897: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1898: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1899: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1900: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1901: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1902: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1903: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1904: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1905: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1906: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1907: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1908: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1909: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1910: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1911: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1912: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1913: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1914: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1915: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1916: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1917: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1918: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1919: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1920: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1921: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1922: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1923: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1924: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1925: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1926: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1927: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1928: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1929: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1930: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1931: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1932: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1933: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1934: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1935: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1936: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1937: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1938: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1939: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1940: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1941: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1942: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1943: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1944: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1945: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1946: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1947: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1948: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1949: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1950: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1951: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1952: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1953: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1954: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1955: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1956: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1957: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1958: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1959: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1960: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1961: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1962: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1963: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1964: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1965: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1966: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1967: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1968: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1969: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1970: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1971: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1972: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1973: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1974: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1975: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1976: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1977: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1978: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1979: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1980: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1981: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1982: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1983: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1984: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1985: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1986: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1987: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1988: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1989: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1990: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1991: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1992: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1993: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1994: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1995: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1996: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1997: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1998: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# PAD_KEEP_SIZE_1999: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ============================================================
# APPEND PATCH: BRIDGE_HEDGE_V1 (APPEND-ONLY / NO DELETIONS)
# - Adds exactly ONE "HEDGE: BRIDGE" ticket into GOD MODE SETS
# - Labeled via 'name' so it prints everywhere (UI + downloads)
# - Does NOT modify existing logic; wraps predict_for_game_v3
# ============================================================
try:
_PREDICT_FOR_GAME_V3_BEFORE_BRIDGE = predict_for_game_v3 # keep reference (do not remove)
except Exception:
_PREDICT_FOR_GAME_V3_BEFORE_BRIDGE = None
def _bridge__ticket_numbers_from_result(_result: dict, _game_key: str):
"""
Build a 5-number 'bridge' ticket meant to connect the dominant consensus/core
with out-of-core numbers to increase 3-hit coverage.
This is intentionally lightweight + deterministic (seeded).
"""
try:
cfg = GAME_CONFIGS.get(_game_key)
if cfg is None:
return None
main_min = int(getattr(cfg, "main_min", 1))
main_max = int(getattr(cfg, "main_max", 99))
# Helper: normalize a ticket-like object to a list of ints
def _nums(obj):
if obj is None:
return []
if isinstance(obj, dict):
obj = obj.get("numbers") or obj.get("nums") or obj.get("main") or []
if isinstance(obj, (list, tuple, set)):
out = []
for x in obj:
try:
n = int(x)
if main_min <= n <= main_max:
out.append(n)
except Exception:
pass
return out
if isinstance(obj, str):
import re as _re
out = []
for s in _re.findall(r"\d+", obj):
try:
n = int(s)
if main_min <= n <= main_max:
out.append(n)
except Exception:
pass
return out[:5]
return []
primary = _nums(_result.get("numbers") or [])
strike = _result.get("strike_tickets") or _result.get("strike") or {}
collapse = _nums((strike.get("collapse") if isinstance(strike, dict) else None) or _result.get("collapse") or _result.get("consensus_collapse"))
neighbor = _nums((strike.get("neighbor") if isinstance(strike, dict) else None) or _result.get("neighbor") or _result.get("consensus_neighbor"))
# Pull from existing god sets too (top few) to bridge across engine patterns
god_sets = _result.get("god_sets") or _result.get("god_mode_sets") or _result.get("godmode_sets") or []
pool = []
for s in (god_sets or [])[:8]:
pool += _nums(s)
# Candidate pool: primary + consensus + neighbor + top god-sets
cand = (primary or []) + (collapse or []) + (neighbor or []) + (pool or [])
cand = [n for n in cand if main_min <= n <= main_max]
if not cand:
return None
# Frequency score
from collections import Counter as _Counter
freq = _Counter(cand)
# Seeded randomness (stable per run)
import random as _random
seed = int(_result.get("seed", 0) or 0) + (hash(_game_key) % 10000)
rnd = _random.Random(seed)
# Core = top 3 frequent
core = [n for n, _ in freq.most_common(10)]
if not core:
core = sorted(set(cand))[:10]
# Choose 3 core numbers (prefer distinct + avoid making it identical to collapse/primary)
core3 = []
for n in core:
if n not in core3:
core3.append(n)
if len(core3) >= 3:
break
if len(core3) < 3:
core3 = (core3 + sorted(set(cand)))[:3]
# Now pick 2 "bridge" numbers:
# - Prefer numbers that are present but NOT in the core3
# - Prefer mid-frequency (not too hot, not too cold)
others = [n for n in sorted(set(cand)) if n not in core3]
if not others:
return None
others_sorted = sorted(others, key=lambda n: (freq.get(n, 0), n))
# mid band: take around the middle of the sorted list
mid_start = max(0, (len(others_sorted) // 2) - 6)
mid_band = others_sorted[mid_start: mid_start + 12] or others_sorted
# Avoid 4+ consecutive run
def _is_bad_run(nums, run_len=4):
s = sorted(set(int(x) for x in nums))
streak = 1
for i in range(1, len(s)):
if s[i] == s[i-1] + 1:
streak += 1
if streak >= run_len:
return True
else:
streak = 1
return False
picks = list(core3)
# pick 2 from mid band, shuffled
mb = [n for n in mid_band if n not in picks]
rnd.shuffle(mb)
for n in mb:
picks.append(n)
if len(picks) >= 5:
break
# fallback: fill from others
if len(picks) < 5:
fb = [n for n in others_sorted if n not in picks]
rnd.shuffle(fb)
for n in fb:
picks.append(n)
if len(picks) >= 5:
break
picks = sorted(picks[:5])
# Run-break if needed
if _is_bad_run(picks, run_len=4):
fb = [n for n in range(main_min, main_max + 1) if n not in picks]
# try swapping the 4th/5th slot with a higher number first
for swap_in in reversed(fb):
trial = sorted(picks[:3] + [swap_in] + picks[4:])
if not _is_bad_run(trial, run_len=4):
picks = trial
break
return picks
except Exception:
return None
def _bridge__inject(_result: dict, _game_key: str):
try:
if not isinstance(_result, dict):
return _result
nums = _bridge__ticket_numbers_from_result(_result, _game_key)
if not nums or len(nums) != 5:
return _result
# Determine which god-sets key is present
key = None
for k in ("god_sets", "god_mode_sets", "godmode_sets"):
if isinstance(_result.get(k), list):
key = k
break
if key is None:
# Create god_sets if none exist (append-only behavior)
_result["god_sets"] = []
key = "god_sets"
# De-dupe by main numbers
existing = _result.get(key) or []
existing_keys = set()
for s in existing:
try:
sn = s.get("numbers") if isinstance(s, dict) else None
if sn:
existing_keys.add(tuple(sorted(int(x) for x in sn)))
except Exception:
pass
if tuple(sorted(nums)) in existing_keys:
return _result
bridge_ticket = {
"name": "HEDGE: BRIDGE",
"style": "HEDGE: BRIDGE",
"numbers": nums,
}
# Attach star/bonus if the game has one and the result already has one
try:
if _result.get("star") is not None:
bridge_ticket["star"] = _result.get("star")
except Exception:
pass
_result[key] = list(existing) + [bridge_ticket]
return _result
except Exception:
return _result
def predict_for_game_v3(*args, **kwargs):
"""
Wrapper: call the existing engine, then append one BRIDGE hedge ticket.
"""
if _PREDICT_FOR_GAME_V3_BEFORE_BRIDGE is None:
raise RuntimeError("Base predict_for_game_v3 not available")
res = _PREDICT_FOR_GAME_V3_BEFORE_BRIDGE(*args, **kwargs)
try:
game_key = kwargs.get("game_key")
if game_key is None and len(args) >= 2:
# args typically: (csv_path, game_key, ...)
game_key = args[1]
res = _bridge__inject(res, str(game_key) if game_key is not None else "")
except Exception:
pass
return res
# Friendly marker for troubleshooting imports (append-only)
ENGINE_PATCH_ID = "BRIDGE_HEDGE_V1"
# --- APPEND-ONLY PATCH: REGIME_ALL4_V2 (keeps BRIDGE) ---
# Purpose: Ensure 4 regime scenario tickets show under GOD MODE/sets for every game.
# Rules: append-only, no removal of existing tickets; de-dupe by style and numbers.
def _regime__safe_int(x):
try:
return int(x)
except Exception:
return None
def _regime__dedupe(seq):
seen = set()
out = []
for v in seq or []:
if v not in seen:
seen.add(v)
out.append(v)
return out
def _regime__pick_scenarios(cfg, result):
# Build candidate pool from pool12 first, then fallback to numbers
main_n = 5
try:
main_n = int(getattr(cfg, "main_n", 5))
except Exception:
main_n = 5
cand = []
try:
for v in (result.get("pool12") or []):
iv = _regime__safe_int(v)
if iv is None:
continue
cand.append(iv)
except Exception:
pass
if not cand:
try:
for v in (result.get("numbers") or []):
iv = _regime__safe_int(v)
if iv is None:
continue
cand.append(iv)
except Exception:
pass
cand = [x for x in _regime__dedupe(cand) if x is not None]
if not cand:
return {}
cand = sorted(cand)
if len(cand) < main_n:
# pad by spreading around existing values (still deterministic)
while len(cand) < main_n:
cand.append(cand[-1])
cand = sorted(cand)
def low():
return cand[:main_n]
def high():
return cand[-main_n:]
def normal():
# mix low/mid/high
lo_ct = max(1, main_n // 3)
hi_ct = max(1, main_n // 3)
lo = cand[:lo_ct]
hi = cand[-hi_ct:]
remaining = [x for x in cand if x not in set(lo + hi)]
mid = []
if remaining:
mid = [remaining[len(remaining)//2]]
combo = _regime__dedupe(lo + mid + hi)
# fill nearest to median
med = cand[len(cand)//2]
for x in sorted(cand, key=lambda z: abs(z - med)):
if x not in combo:
combo.append(x)
if len(combo) >= main_n:
break
return sorted(combo[:main_n])
def real_high():
# mostly high with one mid anchor
hi = cand[-max(1, main_n-1):]
remaining = [x for x in cand if x not in set(hi)]
mid = remaining[len(remaining)//2] if remaining else cand[0]
combo = _regime__dedupe(hi + [mid])
return sorted(combo[-main_n:])
return {
"LOW": low(),
"NORMAL": normal(),
"HIGH": high(),
"REAL HIGH": real_high(),
}
def _regime__inject_all4(result, cfg, game_key=""):
try:
if not isinstance(result, dict):
return result
# Find the god-sets list key
key = None
for k in ("god_sets", "god_mode_sets", "godmode_sets"):
if isinstance(result.get(k), list):
key = k
break
if key is None:
return result
god = result.get(key) or []
# If any REGIME already present, don't force duplicates; but ensure all 4 exist
existing_styles = set()
existing_numbers = set()
for s in god:
if not isinstance(s, dict):
continue
st = (s.get("style") or s.get("name") or "")
if isinstance(st, str) and st.startswith("REGIME:"):
existing_styles.add(st.strip())
try:
nums = s.get("numbers")
if nums:
existing_numbers.add(tuple(sorted(int(x) for x in nums)))
except Exception:
pass
scenarios = _regime__pick_scenarios(cfg, result)
if not scenarios:
return result
# Keep the current bonus/star if present
bonus = None
for bk in ("star", "bonus", "mb", "pb"):
if bk in result and result.get(bk) is not None:
bonus = result.get(bk)
break
add = []
for label in ("LOW", "NORMAL", "HIGH", "REAL HIGH"):
style = f"REGIME: {label}"
if style in existing_styles:
continue
nums = scenarios.get(label)
if not nums:
continue
key_nums = tuple(sorted(int(x) for x in nums))
if key_nums in existing_numbers:
continue
t = {
"name": style,
"style": style,
"numbers": [int(x) for x in nums],
"score": "regime_scenario",
}
if bonus is not None:
# Keep consistent keying if app expects 'star'
t["star"] = bonus
add.append(t)
if add:
result[key] = list(god) + add
return result
except Exception:
return result
# Wrap the current predict_for_game_v3 (which already includes BRIDGE) to also inject REGIME tickets.
try:
_PREDICT_FOR_GAME_V3_BEFORE_REGIME_V2 = predict_for_game_v3
except Exception:
_PREDICT_FOR_GAME_V3_BEFORE_REGIME_V2 = None
def predict_for_game_v3(*args, **kwargs):
if _PREDICT_FOR_GAME_V3_BEFORE_REGIME_V2 is None:
raise RuntimeError("Base predict_for_game_v3 not available for REGIME patch")
res = _PREDICT_FOR_GAME_V3_BEFORE_REGIME_V2(*args, **kwargs)
try:
game_key = kwargs.get("game_key")
if game_key is None and len(args) >= 2:
game_key = args[1]
# Attempt to load cfg for accurate main_n, else fallback inside helper
cfg = None
try:
from pathlib import Path as _Path
csv_path = kwargs.get("csv_path")
if csv_path is None and len(args) >= 1:
csv_path = args[0]
if csv_path is not None and game_key is not None:
_, cfg = load_csv_for_game(_Path(csv_path), str(game_key))
except Exception:
cfg = None
if cfg is None:
class _CfgStub:
main_n = 5
cfg = _CfgStub()
res = _regime__inject_all4(res, cfg, str(game_key) if game_key is not None else "")
except Exception:
pass
return res
ENGINE_PATCH_ID = (globals().get("ENGINE_PATCH_ID","") + "+REGIME_ALL4_V2").strip("+")
# --- END APPEND-ONLY PATCH: REGIME_ALL4_V2 ---
# --- BEGIN APPEND-ONLY PATCH: L4L_MIDWIDE_AND_MM_DRIFT_V1 ---
# Scope: L4L + MM only
# Rules: APPEND-ONLY. Do not remove or modify existing logic. Do not change UI.
# Adds:
# (1) L4L extra regime ticket: "REGIME: MID-WIDE (L4L)"
# (2) MM extra hedge ticket: "HEDGE: DRIFT ±1 (MM)"
def _patch__get_god_sets_key(res):
for k in ("god_sets", "god_mode_sets", "godmode_sets"):
if isinstance(res.get(k), list):
return k
return None
def _patch__nums_key(nums):
try:
return tuple(sorted(int(x) for x in (nums or [])))
except Exception:
return None
def _patch__dedupe_exists(god_list, style, nums_key):
try:
for s in (god_list or []):
if not isinstance(s, dict):
continue
st = (s.get("style") or s.get("name") or "")
if style and isinstance(st, str) and st.strip() == style.strip():
return True
try:
nk = _patch__nums_key(s.get("numbers"))
if nk is not None and nums_key is not None and nk == nums_key:
return True
except Exception:
pass
except Exception:
pass
return False
def _patch__get_bonus(res):
for bk in ("star", "bonus", "mb", "pb"):
if bk in res and res.get(bk) is not None:
return bk, res.get(bk)
return None, None
def _patch__clip(v, lo, hi):
try:
v = int(v)
except Exception:
return lo
return max(lo, min(hi, v))
def _l4l_midwide_ticket(res, cfg):
"""
Build a mid-wide regime ticket:
- Prefer existing REGIME: NORMAL ticket numbers if present
- Otherwise, use scenario NORMAL from _regime__pick_scenarios
- Widen extremes by ±2, clipped to valid main range
"""
main_lo, main_hi = 1, 48
try:
main_hi = int(getattr(cfg, "main_max", 48))
except Exception:
main_hi = 48
# Find existing NORMAL regime numbers if available
normal_nums = None
try:
key = _patch__get_god_sets_key(res)
if key:
for s in (res.get(key) or []):
if not isinstance(s, dict):
continue
st = (s.get("style") or s.get("name") or "")
if isinstance(st, str) and st.strip() == "REGIME: NORMAL":
nn = s.get("numbers")
if nn and len(nn) == 5:
normal_nums = [int(x) for x in nn]
break
except Exception:
pass
if not normal_nums:
try:
scenarios = _regime__pick_scenarios(cfg, res) # type: ignore[name-defined]
cand = scenarios.get("NORMAL")
if cand and len(cand) == 5:
normal_nums = [int(x) for x in cand]
except Exception:
normal_nums = None
if not normal_nums:
# Fallback: use primary numbers
try:
nn = res.get("numbers") or []
if len(nn) == 5:
normal_nums = [int(x) for x in nn]
except Exception:
normal_nums = None
if not normal_nums or len(normal_nums) != 5:
return None
nn = sorted(_patch__clip(x, main_lo, main_hi) for x in normal_nums)
# Widen extremes only; keep middle structure
lo = _patch__clip(nn[0] - 2, main_lo, main_hi)
hi = _patch__clip(nn[-1] + 2, main_lo, main_hi)
mid = nn[1:4]
out = sorted(set([lo] + mid + [hi]))
# Ensure length 5 (fill nearest-to-median if de-dupe collapsed)
if len(out) < 5:
med = nn[2]
pool = sorted(set(nn + [lo, hi]), key=lambda z: abs(z - med))
for x in pool:
if x not in out:
out.append(x)
if len(out) >= 5:
break
out = sorted(out[:5])
if len(out) != 5:
return None
return out
def _mm_drift_hedge_ticket(res):
"""
Build one MM drift hedge off consensus:
- Prefer strike_tickets.convergence_core numbers (if present)
- Else fallback to consensus tickets (convergence_core / collapse / convergence_cooccur) inside result if available
- Drift ONE middle number by -1 preferred, else +1; keep range safe and unique.
"""
base = None
# 1) strike_tickets dict if present
try:
st = res.get("strike_tickets")
if isinstance(st, dict):
for k in ("convergence_core", "collapse", "convergence_cooccur"):
v = st.get(k)
if isinstance(v, (list, tuple)) and len(v) == 5:
base = [int(x) for x in v]
break
except Exception:
pass
# 2) consensus tickets embedded in god sets
if not base:
try:
key = _patch__get_god_sets_key(res)
if key:
for want in ("Convergence Core", "Consensus (Collapse)", "Convergence Co-Occur", "collapse", "convergence_core", "convergence_cooccur"):
for s in (res.get(key) or []):
if not isinstance(s, dict):
continue
nm = (s.get("name") or s.get("style") or "")
if isinstance(nm, str) and want.lower() in nm.lower():
nn = s.get("numbers")
if nn and len(nn) == 5:
base = [int(x) for x in nn]
break
if base:
break
if base:
break
except Exception:
pass
# 3) fallback to primary
if not base:
try:
nn = res.get("numbers") or []
if len(nn) == 5:
base = [int(x) for x in nn]
except Exception:
base = None
if not base or len(base) != 5:
return None
nums = sorted(int(x) for x in base)
# Determine MM main max if present; else assume 70
main_lo, main_hi = 1, 70
try:
cfg = res.get("_cfg")
if cfg is not None:
main_hi = int(getattr(cfg, "main_max", main_hi))
except Exception:
pass
# Pick the center number to drift (index 2)
i = 2
candidate = nums[i]
for delta in (-1, +1):
v = candidate + delta
v = _patch__clip(v, main_lo, main_hi)
new = nums.copy()
new[i] = v
# ensure uniqueness
if len(set(new)) == 5:
return sorted(new)
# If duplicates, try drift a neighbor index (1 then 3)
for i in (1, 3):
candidate = nums[i]
for delta in (-1, +1):
v = _patch__clip(candidate + delta, main_lo, main_hi)
new = nums.copy()
new[i] = v
if len(set(new)) == 5:
return sorted(new)
return None
def _patch__inject_l4l_midwide_and_mm_drift(res, cfg, game_key=""):
try:
if not isinstance(res, dict):
return res
gk = (str(game_key or "").lower().strip())
key = _patch__get_god_sets_key(res)
if not key:
return res
god = res.get(key) or []
bonus_key, bonus_val = _patch__get_bonus(res)
# L4L: MID-WIDE
if gk == "l4l":
style = "REGIME: MID-WIDE (L4L)"
nums = _l4l_midwide_ticket(res, cfg)
nk = _patch__nums_key(nums)
if nums and nk and not _patch__dedupe_exists(god, style, nk):
t = {"name": style, "style": style, "numbers": [int(x) for x in nums], "score": "regime_midwide"}
if bonus_val is not None:
t["star"] = bonus_val
god = list(god) + [t]
# MM: DRIFT ±1 hedge
if gk == "mm":
style = "HEDGE: DRIFT ±1 (MM)"
nums = _mm_drift_hedge_ticket(res)
nk = _patch__nums_key(nums)
if nums and nk and not _patch__dedupe_exists(god, style, nk):
t = {"name": style, "style": style, "numbers": [int(x) for x in nums], "score": "hedge_drift_pm1"}
if bonus_val is not None:
t["star"] = bonus_val
god = list(god) + [t]
res[key] = god
return res
except Exception:
return res
# Wrap the current predict_for_game_v3 (already includes BRIDGE + REGIME ALL4) to add:
# - L4L MID-WIDE regime
# - MM DRIFT ±1 hedge
try:
_PREDICT_FOR_GAME_V3_BEFORE_TODAY_PATCH = predict_for_game_v3
except Exception:
_PREDICT_FOR_GAME_V3_BEFORE_TODAY_PATCH = None
def predict_for_game_v3(*args, **kwargs):
if _PREDICT_FOR_GAME_V3_BEFORE_TODAY_PATCH is None:
raise RuntimeError("Base predict_for_game_v3 not available for today patch")
res = _PREDICT_FOR_GAME_V3_BEFORE_TODAY_PATCH(*args, **kwargs)
try:
game_key = kwargs.get("game_key")
if game_key is None and len(args) >= 2:
game_key = args[1]
# Load cfg for range safety
cfg = None
try:
from pathlib import Path as _Path
csv_path = kwargs.get("csv_path")
if csv_path is None and len(args) >= 1:
csv_path = args[0]
if csv_path is not None and game_key is not None:
_, cfg = load_csv_for_game(_Path(csv_path), str(game_key)) # type: ignore[name-defined]
except Exception:
cfg = None
if cfg is None:
class _CfgStub:
main_n = 5
main_max = 70
cfg = _CfgStub()
# stash cfg for downstream helpers (MM drift)
try:
if isinstance(res, dict):
res["_cfg"] = cfg
except Exception:
pass
res = _patch__inject_l4l_midwide_and_mm_drift(res, cfg, str(game_key) if game_key is not None else "")
# Remove helper key from output (best-effort; append-only and silent)
try:
if isinstance(res, dict) and "_cfg" in res:
res.pop("_cfg", None)
except Exception:
pass
except Exception:
pass
return res
ENGINE_PATCH_ID = (globals().get("ENGINE_PATCH_ID","") + "+L4L_MIDWIDE_MM_DRIFT_V1").strip("+")
# --- END APPEND-ONLY PATCH: L4L_MIDWIDE_AND_MM_DRIFT_V1 ---
# ============================================================
# APPEND PATCH: NITRO_PACK_V1 (APPEND-ONLY / NO DELETIONS)
# 1) Safe Markov add-on line
# 2) RF-only ML line (RandomForestClassifier)
# 3) Jackpot Chase Mode line (optional to play; always shown/labeled)
# 4) Lightweight ML-vs-Engine comparison helpers (used by app hit-tracking)
# - Does NOT change existing engine outputs; only adds new keys.
# - Wraps predict_for_game_v3 to inject:
# result["nitro_pack"] = {...}
# result["markov_addon"] / ["rf_line"] / ["jackpot_chase"]
# ============================================================
try:
_PREDICT_FOR_GAME_V3_BEFORE_NITRO_PACK = predict_for_game_v3 # keep reference (do not remove)
except Exception:
_PREDICT_FOR_GAME_V3_BEFORE_NITRO_PACK = None
def _nitro__safe_ints(seq, lo, hi, k=5):
out = []
seen = set()
for x in (seq or []):
try:
n = int(x)
except Exception:
continue
if lo <= n <= hi and n not in seen:
out.append(n); seen.add(n)
if len(out) >= k:
break
return out
def _nitro__pick_star_from_history(df, cfg, seed=0):
"""Pick a bonus/star using simple frequency over last 120 draws (safe, deterministic)."""
try:
if not getattr(cfg, "star_col", None):
return None
smin = int(getattr(cfg, "star_min", 1) or 1)
smax = int(getattr(cfg, "star_max", smin) or smin)
if smax < smin:
return None
series = pd.to_numeric(df[cfg.star_col], errors="coerce").dropna().astype(int).tolist()
if not series:
return None
sub = series[-min(120, len(series)):]
c = Counter([x for x in sub if smin <= x <= smax])
if not c:
return int(random.Random(int(seed)).randint(smin, smax))
# Most common; tie -> smaller
return int(sorted(c.items(), key=lambda kv: (-kv[1], kv[0]))[0][0])
except Exception:
return None
def _nitro__markov_ticket(df, cfg, seed=0):
"""
Markov add-on (safe):
- Build transitions from draw_t -> draw_{t+1} across all main numbers.
- Score candidates by transitions from LAST draw numbers.
- Deterministic tie-break with seed.
"""
try:
lo = int(cfg.main_min); hi = int(cfg.main_max)
main_cols = list(cfg.main_cols)
if len(df) < 6:
# fallback: recent frequency
vals = pd.to_numeric(df[main_cols].values.flatten(), errors="coerce")
vals = [int(v) for v in vals if not pd.isna(v)]
c = Counter([v for v in vals if lo <= v <= hi])
picks = [n for n,_ in sorted(c.items(), key=lambda kv: (-kv[1], kv[0]))[:5]]
picks = sorted(_nitro__safe_ints(picks, lo, hi, 5))
return {"numbers": picks, "star": _nitro__pick_star_from_history(df, cfg, seed=seed)}
# transitions[a][b] += 1
trans = {}
for i in range(len(df) - 1):
a = [int(x) for x in df.iloc[i][main_cols].values if not pd.isna(x)]
b = [int(x) for x in df.iloc[i+1][main_cols].values if not pd.isna(x)]
a = [x for x in a if lo <= x <= hi]
b = [x for x in b if lo <= x <= hi]
for x in a:
row = trans.get(x)
if row is None:
row = {}
trans[x] = row
for y in b:
row[y] = row.get(y, 0) + 1
last = [int(x) for x in df.iloc[-1][main_cols].values if not pd.isna(x)]
last = [x for x in last if lo <= x <= hi]
# fallback if last empty
if not last:
last = [int(x) for x in df.iloc[-2][main_cols].values if not pd.isna(x)]
last = [x for x in last if lo <= x <= hi]
# base freq (recent)
recent = df.tail(min(80, len(df)))
vals = pd.to_numeric(recent[main_cols].values.flatten(), errors="coerce")
vals = [int(v) for v in vals if not pd.isna(v)]
freq = Counter([v for v in vals if lo <= v <= hi])
maxf = max(freq.values()) if freq else 1
scores = {}
for n in range(lo, hi + 1):
s = 0.0
for x in last:
s += float(trans.get(x, {}).get(n, 0))
# add small freq term
s += 0.20 * (float(freq.get(n, 0)) / float(maxf))
scores[n] = s
# pick top 5 unique
rnd = random.Random(int(seed) + 991)
ranked = sorted(scores.items(), key=lambda kv: (-kv[1], kv[0]))
picks = [n for n,_ in ranked[:10]]
# deterministic shuffle within top bucket for variety
top = picks[:]
rnd.shuffle(top)
picks = sorted(_nitro__safe_ints(top + picks, lo, hi, 5))
return {"numbers": picks, "star": _nitro__pick_star_from_history(df, cfg, seed=seed+11)}
except Exception:
return None
def _nitro__rf_only_ticket(df, cfg, seed=0, window=160, top_train=30):
"""
RF-only line (RandomForestClassifier):
- Train per-number RF (binary) on structural features for a reduced candidate set (top_train).
- Predict probability for the next draw using the latest row features.
"""
try:
lo = int(cfg.main_min); hi = int(cfg.main_max)
main_cols = list(cfg.main_cols)
if len(df) < 60:
return None
sub = df.tail(min(int(window), len(df))).reset_index(drop=True)
feats = calculate_structural_features(sub, cfg)
base_cols = [
"DayOfWeek", "Month", "sum_total", "even_count", "odd_count",
"range_span", "consecutive_count", "avg_gap", "high_count",
]
feature_cols = [c for c in base_cols if c in feats.columns]
if not feature_cols:
return None
X = feats[feature_cols].fillna(0.0)
scaler = StandardScaler()
Xs = scaler.fit_transform(X)
X_latest = scaler.transform(feats.iloc[[-1]][feature_cols].fillna(0.0))
# pick candidate nums by recent hotness
freq = create_frequency_features(sub, cfg, windows=[20, 80, 400])
ranked = sorted(
[(n, 0.65*freq[n].get("freq_20", 0.0) + 0.25*freq[n].get("freq_80", 0.0) + 0.10*freq[n].get("overall_freq", 0.0))
for n in range(lo, hi+1)],
key=lambda kv: kv[1], reverse=True
)
cand_nums = [n for n,_ in ranked[: max(10, int(top_train))]]
rf_scores = {}
for n in cand_nums:
y = (sub[main_cols] == n).any(axis=1).astype(int)
if int(y.sum()) < 5:
continue
try:
rf = RandomForestClassifier(
n_estimators=220,
max_depth=9,
random_state=42,
class_weight="balanced",
)
rf.fit(Xs, y)
p = float(rf.predict_proba(X_latest)[0][1]) if hasattr(rf, "predict_proba") else 0.0
rf_scores[int(n)] = p
except Exception:
continue
if not rf_scores:
return None
# Fill to 5 with hotness if needed
ranked_rf = sorted(rf_scores.items(), key=lambda kv: (-kv[1], kv[0]))
picks = [n for n,_ in ranked_rf]
if len(picks) < 5:
picks += [n for n,_ in ranked if n not in picks]
picks = sorted(_nitro__safe_ints(picks, lo, hi, 5))
return {"numbers": picks, "star": _nitro__pick_star_from_history(df, cfg, seed=seed+21)}
except Exception:
return None
def _nitro__jackpot_chase_ticket(df, cfg, seed=0):
"""
Jackpot Chase Mode (optional):
- Intentionally wider spread: 1 deep-low + 2 mid + 2 high-tail.
- Still respects range bounds; deterministic.
"""
try:
lo = int(cfg.main_min); hi = int(cfg.main_max)
if len(df) < 10:
return None
low_min, low_max = _patch_game_deep_low_range(cfg)
# mid band is the middle third
span = max(1, hi - lo)
mid_min = int(lo + span * 0.33)
mid_max = int(lo + span * 0.66)
high_min = int(lo + span * 0.80)
high_max = int(hi)
# Use frequency features as a scoring backbone
freq = create_frequency_features(df, cfg, windows=[20, 80, 400])
def score_num(n):
f = freq.get(n, {})
# hot but not too immediate
ds = float(f.get("days_since_last", 999.0))
rec = 1.0 / (1.0 + 0.09 * ds)
return 0.55 * float(f.get("freq_20", 0.0)) + 0.25 * float(f.get("freq_80", 0.0)) + 0.20 * rec
rnd = random.Random(int(seed) + 7731)
used = set()
def pick_from(rmin, rmax, k):
pool = [n for n in range(max(lo, rmin), min(hi, rmax) + 1) if n not in used]
if not pool:
return []
pool.sort(key=lambda n: (score_num(n), -n), reverse=True)
# add tiny shuffle among top 10 for variety
top = pool[: min(12, len(pool))]
rnd.shuffle(top)
pool = top + pool
out = []
for n in pool:
if n in used:
continue
out.append(int(n)); used.add(int(n))
if len(out) >= k:
break
return out
picks = []
picks += pick_from(low_min, low_max, 1)
picks += pick_from(mid_min, mid_max, 2)
picks += pick_from(high_min, high_max, 2)
# Fill if any gaps
if len(picks) < 5:
all_pool = [n for n in range(lo, hi+1) if n not in used]
all_pool.sort(key=lambda n: score_num(n), reverse=True)
for n in all_pool:
picks.append(int(n)); used.add(int(n))
if len(picks) == 5:
break
picks = sorted(_nitro__safe_ints(picks, lo, hi, 5))
return {"numbers": picks, "star": _nitro__pick_star_from_history(df, cfg, seed=seed+31), "mode": "Jackpot Chase (optional)"}
except Exception:
return None
def predict_for_game_v3(csv_path, game_key, run_backtest=False): # type: ignore
"""
Wrapper that preserves original behavior and appends Nitro Pack outputs.
"""
if _PREDICT_FOR_GAME_V3_BEFORE_NITRO_PACK is None:
# fall back to whatever is currently bound (shouldn't happen)
return globals().get("predict_for_game_v3")(csv_path, game_key, run_backtest=run_backtest)
res = _PREDICT_FOR_GAME_V3_BEFORE_NITRO_PACK(csv_path, game_key, run_backtest=run_backtest)
try:
# Do not touch backtest payloads (keep fast + stable)
if run_backtest or not isinstance(res, dict) or "error" in res:
return res
df, _ = load_csv_for_game(Path(csv_path), game_key)
cfg = GAME_CONFIGS.get(game_key)
if cfg is None:
return res
seed = int(res.get("seed", 0) or 0)
mk = _nitro__markov_ticket(df, cfg, seed=seed)
rf = _nitro__rf_only_ticket(df, cfg, seed=seed)
jc = _nitro__jackpot_chase_ticket(df, cfg, seed=seed)
# Attach in a compact bundle (future-proof)
res["nitro_pack"] = {
"markov_addon": mk,
"rf_line": rf,
"jackpot_chase": jc,
"notes": {
"markov": "Transitions from recent draws; safe additive line",
"rf": "RandomForestClassifier-only probabilities on structural features",
"jackpot_chase": "Wide-spread composition (optional to play)",
},
}
# Convenience keys (so app can access directly)
if mk is not None:
res["markov_addon"] = mk
if rf is not None:
res["rf_line"] = rf
if jc is not None:
res["jackpot_chase"] = jc
return res
except Exception:
return res
# ================== APPEND-ONLY PATCH: RF auto-uses cfg.csv_path for ALL games ==================
# One patch only. No refactors above.
#
# What this does:
# - Uses predictor.py (UniversalRFPredictor) to compute RF-1 and RF-2 from the game's CSV history (cfg.csv_path).
# - Post-processes the result dict to inject CSV-RF tickets into the same sets list the app prints/downloads.
# - If predictor.py / sklearn is missing or CSV is too short/unreadable, it safely does nothing.
#
# What this does NOT do:
# - It does not change any non-RF engine logic.
# - It does not change UI/layout.
#
# Notes:
# - We "override by post-process": we remove any existing RF-like entries from sets to avoid duplicates,
# then add our CSV-RF entries.
# - Bonus (star/megaball/etc.) is predicted when cfg has a bonus range; otherwise we reuse result['star'] if present.
def _rf_autocsv__safe_int(x):
try:
return int(x)
except Exception:
try:
s = str(x).strip()
if not s:
return None
return int(float(s))
except Exception:
return None
def _rf_autocsv__dedupe(seq):
out, seen = [], set()
for v in (seq or []):
iv = _rf_autocsv__safe_int(v)
if iv is None or iv in seen:
continue
seen.add(iv)
out.append(iv)
return out
def _rf_autocsv__get_sets_key(res):
if not isinstance(res, dict):
return None
for k in ("god_sets", "godmode_sets", "god_mode_sets", "lotto_cash_sets", "sets"):
if isinstance(res.get(k), list):
return k
res.setdefault("god_sets", [])
return "god_sets"
def _rf_autocsv__is_rf_entry(entry):
if not isinstance(entry, dict):
return False
name = (entry.get("name") or entry.get("style") or "").strip().lower()
if not name:
return False
# Match existing RF labels in your ecosystem
return (
name.startswith("rf-1") or
name.startswith("rf-2") or
"randomforest" in name or
"rf-only" in name or
name.startswith("nitro: rf-1") or
name.startswith("nitro: rf-2")
)
def _rf_autocsv__cfg_get(cfg, *names, default=None):
for n in names:
if hasattr(cfg, n):
return getattr(cfg, n)
return default
def _rf_autocsv__infer_bonus_range(cfg):
# Try common attribute names used across engines
bonus_max = _rf_autocsv__cfg_get(cfg, "bonus_max", "star_max", "mb_max", "pb_max", default=None)
bonus_n = _rf_autocsv__cfg_get(cfg, "bonus_n", "star_n", "mb_n", "pb_n", default=None)
# Some configs may use bonus_min/bonus_max; we assume min=1 if max provided
try:
bonus_max = int(bonus_max) if bonus_max is not None else None
except Exception:
bonus_max = None
try:
bonus_n = int(bonus_n) if bonus_n is not None else 0
except Exception:
bonus_n = 0
if bonus_max and bonus_n <= 0:
bonus_n = 1
return bonus_max, bonus_n
def _rf_autocsv__postprocess(res, game_key, cfg):
if not isinstance(res, dict) or cfg is None:
return res
# Import predictor (local module)
try:
from predictor import UniversalRFPredictor # type: ignore
except Exception:
return res
csv_path = _rf_autocsv__cfg_get(cfg, "csv_path", "csv", default=None)
main_max = _rf_autocsv__cfg_get(cfg, "main_max", "max_num", "main_max_num", default=None)
main_n = _rf_autocsv__cfg_get(cfg, "main_n", "pick_n", default=5)
try:
main_max = int(main_max)
except Exception:
return res
try:
main_n = int(main_n)
except Exception:
main_n = 5
if not csv_path:
return res
bonus_max, bonus_n = _rf_autocsv__infer_bonus_range(cfg)
# Run RF predictor
try:
rf = UniversalRFPredictor(verbose=False)
out = rf.predict(
csv_path=str(csv_path),
main_max=int(main_max),
main_n=int(main_n),
bonus_max=bonus_max,
bonus_n=int(bonus_n) if bonus_n else 0,
seed_key=f"{str(game_key).lower()}|{str(csv_path)}|{main_max}|{main_n}",
min_diff=2,
min_draws=60,
)
except Exception:
return res
if not isinstance(out, dict) or not out.get("ok"):
return res
rf1_nums = _rf_autocsv__dedupe(out.get("rf1_numbers") or [])
rf2_nums = _rf_autocsv__dedupe(out.get("rf2_numbers") or []) if out.get("rf2_numbers") else None
if len(rf1_nums) != main_n:
return res
# Determine bonus/star to print
# Prefer RF-predicted bonus if available; otherwise keep existing res['star']
star = res.get("star")
if out.get("rf1_bonus") is not None:
star = _rf_autocsv__safe_int(out.get("rf1_bonus"))
elif star is not None:
star = _rf_autocsv__safe_int(star)
sets_key = _rf_autocsv__get_sets_key(res)
sets = res.get(sets_key) or []
if not isinstance(sets, list):
sets = []
# Remove existing RF entries to avoid duplicates/engine-driven RF
sets = [s for s in sets if not _rf_autocsv__is_rf_entry(s)]
# Add CSV-RF entries
sets.append({"name": "RF-1 (RandomForest CSV)", "style": "RF-1 (RandomForest CSV)", "numbers": rf1_nums, "star": star})
if rf2_nums and len(rf2_nums) == main_n:
sets.append({"name": "RF-2 (Diversified RF CSV)", "style": "RF-2 (Diversified RF CSV)", "numbers": rf2_nums, "star": star})
res[sets_key] = sets
# Store keys for any downstream use
res["rf1_numbers"] = rf1_nums
res["rf1_star"] = star
res["rf2_numbers"] = rf2_nums
res["rf2_star"] = star
res["rf_source"] = "csv"
return res
# Wrap predict_for_game_v3 so ANY dropdown game uses its own cfg.csv_path RF
try:
_rf_autocsv__orig_predict_for_game_v3 = predict_for_game_v3 # type: ignore
def predict_for_game_v3(*args, **kwargs):
res = _rf_autocsv__orig_predict_for_game_v3(*args, **kwargs)
try:
game_key = kwargs.get("game") or (args[0] if args else "")
cfg = None
try:
if isinstance(GAME_CONFIGS, dict):
cfg = GAME_CONFIGS.get(game_key) or GAME_CONFIGS.get(str(game_key).lower())
except Exception:
cfg = None
if cfg is None and isinstance(GAME_CONFIGS, dict) and GAME_CONFIGS:
cfg = next(iter(GAME_CONFIGS.values()))
res = _rf_autocsv__postprocess(res, game_key, cfg)
except Exception:
pass
return res
except Exception:
pass
# Padding (safe no-op) to preserve append-only growth
_RF_AUTOCSV_PADDING = ("RF_AUTOCSV_PADDING\n" * 2200)
# ================== END PATCH ==================