From 1a986446ac4242131bd1e46cb86cafd98a28213f Mon Sep 17 00:00:00 2001 From: Simone Ghisio Date: Thu, 24 Sep 2026 10:20:51 +0200 Subject: [PATCH 1/3] Add some methods to evaluate smoothness --- pyeyesweb/low_level/smoothness.py | 122 +++---- pyeyesweb/utils/math_utils.py | 384 ++++++++++++++++++++++- tests/benchmarks/smoothness_benchmark.py | 267 +++++++++++++--- 3 files changed, 676 insertions(+), 97 deletions(-) diff --git a/pyeyesweb/low_level/smoothness.py b/pyeyesweb/low_level/smoothness.py index 0db489f..58616f0 100644 --- a/pyeyesweb/low_level/smoothness.py +++ b/pyeyesweb/low_level/smoothness.py @@ -1,72 +1,60 @@ from dataclasses import dataclass from typing import Literal, List, Optional import numpy as np +from scipy.signal import butter, filtfilt from pyeyesweb.data_models.base import DynamicFeature from pyeyesweb.data_models.results import FeatureResult from pyeyesweb.utils.signal_processing import apply_savgol_filter -from pyeyesweb.utils.math_utils import compute_sparc, compute_jerk_rms +from pyeyesweb.utils.math_utils import ( + compute_sparc, + compute_jerk_rms, + compute_ldlj, + compute_sample_entropy, + compute_harmonicity_index, + compute_submovement_count +) from pyeyesweb.utils.validators import validate_numeric, validate_boolean, validate_string @dataclass(slots=True) class SmoothnessResult(FeatureResult): - """Output contract for Smoothness metrics. - - Attributes - ---------- - sparc : float, optional - The computed SPARC metric representing spectral arc length. - jerk_rms : float, optional - The compute root mean square of jerk. - """ + """Output contract for Smoothness metrics.""" sparc: Optional[float] = None jerk_rms: Optional[float] = None + ldlj_v: Optional[float] = None + ldlj_a: Optional[float] = None + samp_en: Optional[float] = None + harmonicity: Optional[float] = None + n_submovements: Optional[int] = None class Smoothness(DynamicFeature): - """Calculates movement smoothness metrics from a 1D speed profile. - - !!! tip - You can calculate smoothness via Spectral Arc Length (SPARC) or Jerk RMS. - - Read more in the [User Guide](../../user_guide/theoretical_framework/low_level/smoothness.md). - - Parameters - ---------- - rate_hz : float, optional - Sampling rate in Hz. Defaults to `50.0`. - use_filter : bool, optional - Whether to apply Savitzky-Golay filtering. Defaults to `True`. - metrics : list of {'sparc', 'jerk_rms'}, optional - Metrics to calculate. Defaults to all allowed metrics. - sparc_amplitude_threshold : float, optional - Amplitude threshold for SPARC. Defaults to `0.05`. - sparc_min_fc : float, optional - Minimum cutoff frequency for SPARC. Defaults to `2.0`. - sparc_max_fc : float, optional - Maximum cutoff frequency for SPARC. Defaults to `20.0`. - """ - - _ALLOWED_METRICS = ["sparc", "jerk_rms"] + """Calculates movement smoothness and complexity metrics from a 1D speed profile.""" + + _ALLOWED_METRICS = [ + "sparc", "jerk_rms", "ldlj_v", "ldlj_a", + "samp_en", "harmonicity", "n_submovements" + ] def __init__( self, rate_hz: float = 50.0, use_filter: bool = True, - metrics: List[Literal["sparc", "jerk_rms"]] = None, + metrics: List[Literal["sparc", "jerk_rms", "ldlj_v", "ldlj_a", "samp_en", "harmonicity", "n_submovements"]] = None, sparc_amplitude_threshold: float = 0.05, sparc_min_fc: float = 2.0, - sparc_max_fc: float = 20.0 + sparc_max_fc: float = 20.0, + min_speed_threshold: float = 30.0 ): super().__init__() - # Initializing through setters natively routes the values to the validators self.rate_hz = rate_hz self.use_filter = use_filter self.sparc_min_fc = sparc_min_fc self.sparc_max_fc = sparc_max_fc self.sparc_threshold = sparc_amplitude_threshold + self.min_speed_threshold = min_speed_threshold self.metrics = metrics @@ -108,7 +96,6 @@ def sparc_max_fc(self) -> float: @sparc_max_fc.setter def sparc_max_fc(self, value: float): - # We ensure that this validator uses the dynamic minimum min_fc = getattr(self, '_sparc_min_fc', 0.1) self._sparc_max_fc = validate_numeric(value, 'sparc_max_fc', min_val=min_fc) @@ -122,42 +109,37 @@ def metrics(self, value: Optional[List[str]]): self._metrics = [validate_string(m, self._ALLOWED_METRICS) for m in target_metrics] def _filter_signal(self, signal: np.ndarray) -> np.ndarray: - """Applies Savitzky-Golay filter if enabled.""" - if not self.use_filter: + if not self.use_filter or len(signal) < 15: return signal - return apply_savgol_filter(signal, self.rate_hz) + + cutoff = min(10.0, (self.rate_hz / 2.0) - 1.0) + b, a = butter(4, cutoff / (self.rate_hz / 2.0), btype='low') + return filtfilt(b, a, signal) def compute(self, window_data: np.ndarray) -> SmoothnessResult: - """Executes smoothness calculation on the speed profile. - - Parameters - ---------- - window_data : numpy.ndarray - A 1D array representing the speed profile within the window. - - Returns - ------- - SmoothnessResult - The computed smoothness metrics. - """ if window_data.size != window_data.shape[0]: raise ValueError("Smoothness expects a 1D speed profile.") speed_profile = window_data.ravel() - # Minimum sample threshold for FFT if len(speed_profile) < 10: return SmoothnessResult(is_valid=False) - # 1. Preprocessing (Filtering) + # Zero-velocity check + if np.mean(speed_profile) < self.min_speed_threshold or np.max(speed_profile) < (self.min_speed_threshold * 1.5): + return SmoothnessResult(is_valid=False) + filtered_speed = self._filter_signal(speed_profile) - # 2. Metrics calculation sparc_val = None jerk_val = None + ldlj_v_val = None + ldlj_a_val = None + samp_en_val = None + harmonicity_val = None + n_sub_val = None if "sparc" in self.metrics: - # Pass custom parameters to the function in math_utils sparc_val = float(compute_sparc( filtered_speed, rate_hz=self.rate_hz, @@ -167,7 +149,29 @@ def compute(self, window_data: np.ndarray) -> SmoothnessResult: )) if "jerk_rms" in self.metrics: - # Standard Jerk RMS calculation from velocity jerk_val = float(compute_jerk_rms(filtered_speed, self.rate_hz, signal_type='velocity')) - return SmoothnessResult(sparc=sparc_val, jerk_rms=jerk_val) \ No newline at end of file + if "ldlj_v" in self.metrics: + ldlj_v_val = float(compute_ldlj(filtered_speed, self.rate_hz, signal_type='velocity')) + + if "ldlj_a" in self.metrics: + ldlj_a_val = float(compute_ldlj(filtered_speed, self.rate_hz, signal_type='acceleration')) + + if "samp_en" in self.metrics: + samp_en_val = float(compute_sample_entropy(filtered_speed)) + + if "harmonicity" in self.metrics: + harmonicity_val = float(compute_harmonicity_index(filtered_speed, self.rate_hz)) + + if "n_submovements" in self.metrics: + n_sub_val = int(compute_submovement_count(filtered_speed, self.rate_hz)) + + return SmoothnessResult( + sparc=sparc_val, + jerk_rms=jerk_val, + ldlj_v=ldlj_v_val, + ldlj_a=ldlj_a_val, + samp_en=samp_en_val, + harmonicity=harmonicity_val, + n_submovements=n_sub_val + ) \ No newline at end of file diff --git a/pyeyesweb/utils/math_utils.py b/pyeyesweb/utils/math_utils.py index 8d84cbd..20a22fe 100644 --- a/pyeyesweb/utils/math_utils.py +++ b/pyeyesweb/utils/math_utils.py @@ -54,6 +54,7 @@ def center_signals(sig): """ return sig - np.mean(sig, axis=0, keepdims=True) +"""" def compute_sparc( signal, rate_hz=50.0, @@ -61,7 +62,7 @@ def compute_sparc( min_fc=2.0, max_fc=20.0 ): - """Compute SPARC (Spectral Arc Length) from a signal. + Compute SPARC (Spectral Arc Length) from a signal. SPARC is a dimensionless smoothness metric that quantifies movement smoothness independent of movement amplitude and duration. More negative @@ -98,7 +99,7 @@ def compute_sparc( Balasubramanian, S., Melendez-Calderon, A., Roby-Brami, A., & Burdet, E. (2015). On the analysis of movement smoothness. Journal of NeuroEngineering and Rehabilitation, 12(1), 1-11. - """ + # Validate sampling rate and convert signal to array @@ -154,6 +155,107 @@ def compute_sparc( # The result is negative by convention (values closer to 0 = smoother) return -arc_length + """ + + +def compute_sparc( + signal, + rate_hz=50.0, + amplitude_threshold=0.05, + min_fc=2.0, + max_fc=20.0 +): + """ + Compute SPARC (Spectral Arc Length) from a signal. + + SPARC is a dimensionless smoothness metric that quantifies movement + smoothness independent of movement amplitude and duration. More negative + values indicate smoother movement. + + This implementation is based on the original algorithm by Balasubramanian et al. (2015). + SPARC values are typically negative, with values closer to 0 indicating less smooth + (more complex) movements. For healthy reaching movements, values around -1.4 to -1.6 + are common. Pathological or very unsmooth movements may have values ranging from + -3 to -10 or lower, depending on the degree of movement fragmentation. + + Parameters + ---------- + signal : ndarray + 1D movement speed profile. + rate_hz : float + Sampling rate in Hz. + amplitude_threshold : float, optional + Amplitude threshold for determining the cut-off frequency fc (default: 0.05). + Increase this value for noisier signals. + min_fc : float, optional + Minimum cut-off frequency in Hz (default: 2.0). + max_fc : float, optional + Maximum cut-off frequency in Hz (default: 20.0). + + Returns + ------- + float + SPARC value (negative, more negative = smoother). + Returns NaN if signal has less than 2 samples. + + References + ---------- + Balasubramanian, S., Melendez-Calderon, A., Roby-Brami, A., & Burdet, E. (2015). + On the analysis of movement smoothness. Journal of NeuroEngineering and Rehabilitation, + 12(1), 1-11. + """ + + rate_hz = validate_numeric(rate_hz, 'rate_hz', min_val=0.0001) + signal = np.asarray(signal) + + if len(signal) < 2 or np.allclose(signal, signal[0]): + return np.nan + + n = len(signal) + # Zero-padding + n_fft = max(1024, int(2**np.ceil(np.log2(n)))) + + yf = np.abs(fft(signal, n=n_fft))[:n_fft // 2] + xf = fftfreq(n_fft, 1.0 / rate_hz)[:n_fft // 2] + + # Normalizzazione dello spettro d'ampiezza + max_yf = np.max(yf) + if max_yf > 0: + yf /= max_yf + else: + return np.nan + + # Calcolo fc adattativa + indices_above_thresh = np.where(yf >= amplitude_threshold)[0] + if len(indices_above_thresh) > 0: + fc_estimated = xf[indices_above_thresh[-1]] + else: + fc_estimated = min_fc + + fc = max(min_fc, min(max_fc, fc_estimated)) + + # Selezione nell'intervallo [0, fc] + sel_idx = np.where(xf <= fc)[0] + xf_sel = xf[sel_idx] + yf_sel = yf[sel_idx] + + if len(xf_sel) < 2: + return np.nan + + # ------------------------------------------------------------- + # CORREZIONE FORMULA ARTICOLO BALASUBRAMANIAN ET AL. (2015) + # ------------------------------------------------------------- + # Asse frequenze normalizzato (da 0 a 1) + d_xf_norm = np.diff(xf_sel) / fc + d_yf = np.diff(yf_sel) + + # Derivata dY / dF_norm + d_yf_d_xf = d_yf / d_xf_norm + + # Integrale discreto: sum( sqrt(1 + (dY/dF_norm)^2) * dF_norm ) + arc_length = np.sum(np.sqrt(1.0 + d_yf_d_xf**2) * d_xf_norm) + + return -arc_length def compute_jerk_rms(signal, rate_hz=50.0, signal_type='velocity'): @@ -207,6 +309,284 @@ def compute_jerk_rms(signal, rate_hz=50.0, signal_type='velocity'): return np.sqrt(np.mean(result ** 2)) +def compute_ldlj(signal: np.ndarray, rate_hz: float, signal_type: str = 'velocity') -> float: + """Calculates the Log Dimensionless Jerk (LDLJ) based on Balasubramanian (2012) + and Melendez-Calderon (2021). + + Parameters + ---------- + signal : np.ndarray + The 1D input signal (velocity profile or acceleration profile). + rate_hz : float + Sampling rate of the signal in Hz. + signal_type : {'velocity', 'acceleration'}, optional + The type of input signal provided. Defaults to 'velocity'. + + Returns + ------- + float + The negative log dimensionless jerk value. + """ + if signal_type not in ['velocity', 'acceleration']: + raise ValueError("signal_type must be either 'velocity' or 'acceleration'") + + dt = 1.0 / rate_hz + n_samples = len(signal) + duration = n_samples * dt + + # 1. Compute Jerk + if signal_type == 'velocity': + acceleration = np.diff(signal) / dt + jerk = np.diff(acceleration) / dt + else: # acceleration + jerk = np.diff(signal) / dt + + # 2. Compute Jerk Integral: integral(jerk^2 dt) + # np.mean(jerk**2) gives (1/duration) * integral(jerk^2 dt) + ms_jerk = np.mean(jerk ** 2) + jerk_integral = ms_jerk * duration + + # Avoid math errors for perfectly flat signals + if duration < 1e-8 or jerk_integral < 1e-12: + return 0.0 + + # 3. Compute Dimensionless Jerk based on signal type + if signal_type == 'velocity': + # LDLJ-V: Balasubramanian et al. (2012) + v_max = np.max(np.abs(signal)) + if v_max < 1e-8: + return 0.0 + + # Formula: (duration^3 / v_max^2) * integral(jerk^2) + dimensionless_jerk = jerk_integral * (duration ** 3) / (v_max ** 2) + + else: + # LDLJ-A: Melendez-Calderon et al. (2021) + # Use mean-subtracted acceleration to avoid gravity drift offsets + mean_subtracted_acc = signal - np.mean(signal) + a_max = np.max(np.abs(mean_subtracted_acc)) + if a_max < 1e-8: + return 0.0 + + # Formula: (duration / a_max^2) * integral(jerk^2) + dimensionless_jerk = jerk_integral * duration / (a_max ** 2) + + # 4. Compute Log Dimensionless Jerk (LDLJ) + if dimensionless_jerk < 1e-12: + return 0.0 + + return -np.log(dimensionless_jerk) + + +import numpy as np +from scipy.signal import find_peaks + +def compute_sample_entropy(signal: np.ndarray, m: int = 2, r_factor: float = 0.2) -> float: + """Calcola la Sample Entropy (SampEn) di una serie temporale 1D. + + Parameters + ---------- + signal : np.ndarray + Profilo di velocità/accelerazione. + m : int + Lunghezza delle sequenze da confrontare (di solito 2). + r_factor : float + Tolleranza espressa come frazione della deviazione standard del segnale (default 0.2). + """ + signal = np.asarray(signal) + N = len(signal) + if N < 15: + return np.nan + + std_sig = np.std(signal) + if std_sig < 1e-8: + return 0.0 # Segnale costante = massima regolarità + + r = r_factor * std_sig + + def _phi(m_len): + x = np.array([signal[i:i + m_len] for i in range(N - m_len + 1)]) + # Matrice delle distanze Chebyshev (Cechov/infinity norm) + dists = np.max(np.abs(x[:, None, :] - x[None, :, :]), axis=2) + # Conta le coppie con distanza < r (escludendo l'auto-confronto) + count = np.sum(dists < r) - (N - m_len + 1) + return count + + count_m = _phi(m) + count_m1 = _phi(m + 1) + + if count_m == 0 or count_m1 == 0: + return np.nan + + return -np.log(count_m1 / count_m) + + +def compute_harmonicity_index(signal: np.ndarray, rate_hz: float = 100.0) -> float: + """Calcola l'Harmonicity Index (H) dal profilo di velocità/accelerazione. + + Un valore H vicina a 1 indica un moto armonico pulito (es. sottomovimento singolo), + valori vicini a 0 indicano molteplici sub-inversioni/sub-picchi. + """ + signal = np.asarray(signal) + if len(signal) < 10: + return np.nan + + # Calcola l'accelerazione + acc = np.gradient(signal, 1.0 / rate_hz) + + # Trova le inversioni di segno dell'accelerazione (zero-crossings) + zero_crossings = np.where(np.diff(np.signbit(acc)))[0] + num_inflections = len(zero_crossings) + + if num_inflections == 0: + return 1.0 + + # Trova i picchi principali del segnale + peaks, _ = find_peaks(signal) + num_peaks = len(peaks) + + if num_peaks == 0: + return 1.0 + + # Rapporto teorico: 1 moto armonico ha 2 inversioni di accelerazione per ciclo/picco + h_index = (2.0 * num_peaks) / float(num_inflections) + return float(np.clip(h_index, 0.0, 1.0)) + + +def compute_submovement_count( + signal: np.ndarray, + rate_hz: float = 100.0, + prominence_factor: float = 0.1 +) -> int: + """Stima il numero di sottomovimenti contando i picchi di velocità significativi. + + Parameters + ---------- + signal : np.ndarray + Profilo di velocità (mm/s). + prominence_factor : float + Prominenza minima del picco espressa come frazione del picco massimo. + """ + signal = np.asarray(signal) + v_max = np.max(signal) + + if v_max < 1e-6: + return 0 + + min_prominence = prominence_factor * v_max + # Distanza minima tra picchi correlata alla durata fisiologica minima di un submovement (~100ms) + min_distance = max(1, int(0.10 * rate_hz)) + + peaks, _ = find_peaks(signal, prominence=min_prominence, distance=min_distance) + return len(peaks) + + +def compute_eyesweb_smoothness_and_fluidity( + positions: np.ndarray, dt: float, epsilon: float = 1e-6 +) -> dict: + """Calcola la Smoothness e la Fluidity del movimento secondo il modello descritto + + nel paper "Adaptive Body Gesture Representation for Automatic + Emotion Recognition" + + Parameters: + ----------- + positions : np.ndarray + Matrice delle posizioni nel tempo con forma (N, 3) o (N, 2), + dove N è il numero di campioni temporali. + dt : float + Intervallo di campionamento temporale tra due frame successivi (in + secondi). + epsilon : float + Valore di tolleranza per evitare divisioni per zero. + + Returns: + -------- + dict + Dizionario contenente: + - 'smoothness': Coefficente di correlazione r tra log(curvatura) e + log(velocità). + - 'fluidity': Grado di aderenza al modello minimum jerk (0 = non + fluido, 1 = ideale). + - 'curvature': Serie temporale della curvatura. + - 'speed': Serie temporale della velocità tangenziale. + """ + positions = np.asarray(positions, dtype=np.float64) + if positions.ndim != 2 or positions.shape[0] < 5: + return { + "smoothness": np.nan, + "fluidity": np.nan, + "curvature": np.array([]), + "speed": np.array([]), + } + + # ------------------------------------------------------------------------- + # 1. Calcolo Derivate Temporali: Velocità (v), Accelerazione (a), Jerk (j) + # ------------------------------------------------------------------------- + v_vec = np.gradient(positions, dt, axis=0) # Velocità vettoriale v(t) + a_vec = np.gradient(v_vec, dt, axis=0) # Accelerazione vettoriale a(t) + j_vec = np.gradient(a_vec, dt, axis=0) # Jerk vettoriale j(t) + + # Velocità tangenziale v(t) = ||v_vec(t)|| + speed = np.linalg.norm(v_vec, axis=1) + + # ------------------------------------------------------------------------- + # 2. Calcolo della Curvatura \kappa(t) (Eq. 14 del PDF) + # \kappa = ||v \times a|| / ||v||^3 (in 3D) + # ------------------------------------------------------------------------- + if positions.shape[1] == 3: + cross_prod = np.cross(v_vec, a_vec) + cross_norm = np.linalg.norm(cross_prod, axis=1) + else: # Se in 2D (x, y) + cross_norm = np.abs( + v_vec[:, 0] * a_vec[:, 1] - v_vec[:, 1] * a_vec[:, 0] + ) + + speed_cubed = speed**3 + # Maschera per evitare divisioni per zero in fasce a velocità pressoché nulla + valid_speed_mask = speed_cubed > epsilon + curvature = np.zeros_like(speed) + curvature[valid_speed_mask] = ( + cross_norm[valid_speed_mask] / speed_cubed[valid_speed_mask] + ) + + # ------------------------------------------------------------------------- + # 3. Calcolo della Smoothness (Correlazione Log-Log, Eq. 15-16 del PDF) + # Relazione Power-Law: v(t) = C * \kappa(t)^\beta + # \log(v) = \log(C) + \beta * \log(\kappa) + # ------------------------------------------------------------------------- + # Filtriamo i punti validi dove sia la velocità che la curvatura sono positive e stabili + valid_pts = (speed > epsilon) & (curvature > epsilon) + + if np.sum(valid_pts) > 3: + log_speed = np.log(speed[valid_pts]) + log_curvature = np.log(curvature[valid_pts]) + + # Coefficente di correlazione r tra log(curvatura) e log(velocità) + corr_matrix = np.corrcoef(log_curvature, log_speed) + smoothness_r = corr_matrix[0, 1] + else: + smoothness_r = np.nan + + # ------------------------------------------------------------------------- + # 4. Calcolo della Fluidity (Minimum Jerk / Integrated Squared Jerk, Eq. 17 + # del PDF) + # Fluidity = 1 / (1 + \int ||jerk(t)||^2 dt) + # ------------------------------------------------------------------------- + jerk_squared_norm = np.sum(j_vec**2, axis=1) + integrated_jerk = np.trapz(jerk_squared_norm, dx=dt) + + # Normalizzazione per rendere la Fluidity una metrica limitata nell'intervallo (0, 1] + fluidity = 1.0 / (1.0 + integrated_jerk) + + return { + "smoothness": float(smoothness_r), + "fluidity": float(fluidity), + "curvature": curvature, + "speed": speed, + } + + def normalize_signal(signal): """Normalize signal by its maximum absolute value. diff --git a/tests/benchmarks/smoothness_benchmark.py b/tests/benchmarks/smoothness_benchmark.py index a7ec020..1af1bda 100644 --- a/tests/benchmarks/smoothness_benchmark.py +++ b/tests/benchmarks/smoothness_benchmark.py @@ -1,7 +1,16 @@ +import sys from pathlib import Path +# Add project root to python path to ensure we import the local package +project_root = Path(__file__).resolve().parent.parent.parent +if str(project_root) not in sys.path: + sys.path.insert(0, str(project_root)) + import numpy as np +import pandas as pd +import matplotlib.pyplot as plt from tqdm import tqdm +from scipy.ndimage import median_filter # Import loaders and animator from utils.data_loader import QualisysLoader, KinectLoader @@ -14,41 +23,111 @@ # ========================================== # 1. SETUP & CONFIGURATION # ========================================== -data_type = "qualisys" # Change to "qualisys" to use the raw motion capture loader -tsv_file = "data/smoothness_02.tsv" -window_lengths = [200] +# Loader mode: "qualisys" or "kinect" +data_type = "qualisys" + +# Path to the TSV file you want to analyze +tsv_file = r"C:\Users\simon\Desktop\Dati test smoothness\8.tsv" + +# Output options +save_csv = False # Write frame-by-frame results to a CSV in results/ +generate_plot = True # Save static PNG plot of speed & metrics in results/ +generate_video = False # Render 3D animation video (requires ffmpeg, very slow) + +# Resolve directories relative to the script location +script_dir = Path(__file__).resolve().parent +results_dir = script_dir / "results" +results_dir.mkdir(exist_ok=True) + +# Convert tsv_file path to absolute path relative to the script dir if relative +tsv_path = Path(tsv_file) +if not tsv_path.is_absolute(): + tsv_path = script_dir / tsv_path -# Adjust joint names depending on your tracking system -joint_names = ["RWristOut"] +# Window lengths for sliding window feature computation (in frames) +window_lengths = [300] + +# List of joint/marker names to analyze +joint_names = ["hand_right"] # E.g., ["RWristOut", "RElbowOut"] or None for all + +# Parameters for the Smoothness feature +rate_hz = 100.0 +metrics_to_compute = [ + "sparc", + "ldlj_v", + "ldlj_a", + "jerk_rms", + "samp_en", + "harmonicity", + "n_submovements" +] +sparc_min_fc = 2.0 +sparc_max_fc = 20.0 +min_speed_threshold = 30.0 # mm/s: zero-velocity threshold for posture/rest # ========================================== -# 2. LOAD DATA +# 2. HELPER FUNCTIONS +# ========================================== +def clean_and_smooth_series(arr: np.ndarray, window_size: int = 7) -> np.ndarray: + """Interpolates NaN values due to zero-velocity and applies a light median filter.""" + series = pd.Series(arr) + if series.dropna().empty: + return np.zeros_like(arr) + + # Linear interpolation for NaNs, then backfill/forward fill boundaries + series_interp = series.interpolate(method='linear').bfill().ffill() + # Apply median filtering to smooth streaming window artifacts + return median_filter(series_interp.values, size=window_size) + # ========================================== +# 3. LOAD DATA +# ========================================== +print(f"Loading data with {data_type} loader...") if data_type == "qualisys": loader = QualisysLoader() else: - # You can cleanly override smoothing parameters here + # KinectLoader applies Savitzky-Golay filtering and axis-swapping loader = KinectLoader(rolling_window=5, savgol_len=70) pos_tensor, vel_tensor, marker_names, bones_edges = loader.load( - tsv_file, None, fps=100.0 + str(tsv_path), None, fps=rate_hz ) N_frames = pos_tensor.shape[0] +print(f"\nSuccessfully loaded {N_frames} frames.") +print(f"Available markers in file: {marker_names}") + +# Resolve which joints to analyze +if not joint_names: + joint_names = marker_names + print(f"No specific joint_names provided. Automatically analyzing all {len(joint_names)} markers.") +else: + print(f"Analyzing specified markers: {joint_names}") # ========================================== -# 3. INITIALIZE FEATURE & COMPUTE +# 4. INITIALIZE FEATURE & COMPUTE # ========================================== -print("Computing Smoothness features...") -smoothness_feature = Smoothness(rate_hz=100, metrics=["sparc", "jerk_rms"],sparc_min_fc= 2.0,sparc_max_fc= 20.0) +print("\nInitializing Smoothness feature...") +smoothness_feature = Smoothness( + rate_hz=rate_hz, + metrics=metrics_to_compute, + sparc_min_fc=sparc_min_fc, + sparc_max_fc=sparc_max_fc, + min_speed_threshold=min_speed_threshold +) -# Build feature dictionary for animator feature_dict = {} +file_stem = tsv_path.stem for w in window_lengths: subplot_title = f"Smoothness (Window = {w})" feature_dict[subplot_title] = {} + csv_data = { + "Frame": np.arange(N_frames), + "Time": np.arange(N_frames) / rate_hz + } + for joint in joint_names: if joint not in marker_names: print(f"Skipping {joint}, not found in marker list.") @@ -58,40 +137,156 @@ # 1D Sliding window for speed (magnitude of velocity) sw_speed = SlidingWindow(max_length=w, n_signals=1, n_dims=1) - results = np.zeros(N_frames) + + # Raw output arrays for metrics + speeds = np.zeros(N_frames) + sparc_results = np.full(N_frames, np.nan) + jerk_results = np.full(N_frames, np.nan) + ldlj_v_results = np.full(N_frames, np.nan) + ldlj_a_results = np.full(N_frames, np.nan) + samp_en_results = np.full(N_frames, np.nan) + harmonicity_results = np.full(N_frames, np.nan) + n_sub_results = np.full(N_frames, np.nan) for frame in tqdm(range(N_frames), desc=f"Processing {joint} (w={w})"): # Extract speed for this specific joint speed = np.linalg.norm(vel_tensor[frame, joint_idx, :]) + speeds[frame] = speed sw_speed.append([[speed]]) # Compute using the streaming __call__ API res = smoothness_feature(sw_speed) - results[frame] = res.sparc if res.is_valid else 0.0 + if res.is_valid: + sparc_results[frame] = res.sparc if res.sparc is not None else np.nan + jerk_results[frame] = res.jerk_rms if res.jerk_rms is not None else np.nan + ldlj_v_results[frame] = res.ldlj_v if res.ldlj_v is not None else np.nan + ldlj_a_results[frame] = res.ldlj_a if res.ldlj_a is not None else np.nan + samp_en_results[frame] = res.samp_en if res.samp_en is not None else np.nan + harmonicity_results[frame] = res.harmonicity if res.harmonicity is not None else np.nan + n_sub_results[frame] = res.n_submovements if res.n_submovements is not None else np.nan - # Store the computed array in the dictionary for the animator - feature_dict[subplot_title][joint] = results -# ========================================== -# 4. RENDER & SAVE ANIMATION -# ========================================== -animator = BenchmarkAnimator( - pos_tensor=pos_tensor, - feature_dict=feature_dict, - marker_names=marker_names, - bones_edges=bones_edges, - title=f"Smoothness Analysis ({data_type.capitalize()})", -) + -# Dynamically generate a clean save path (e.g., "result_trial00005_Rarity_kinect.mp4") -file_stem = Path(tsv_file).stem -output_filename = f"result_{file_stem}_Smoothness_{data_type}.mp4" + # Clean & smooth for continuous visualization + sparc_clean = clean_and_smooth_series(sparc_results,window_size=200) + jerk_clean = clean_and_smooth_series(jerk_results) + ldlj_v_clean = clean_and_smooth_series(ldlj_v_results) + ldlj_a_clean = clean_and_smooth_series(ldlj_a_results) + samp_en_clean = clean_and_smooth_series(samp_en_results) + harmonicity_clean = clean_and_smooth_series(harmonicity_results) + n_sub_clean = clean_and_smooth_series(n_sub_results) -# Use the upgraded save_video method with the built-in progress bar! -animator.save_video( - save_path=f"results/{output_filename}", - video_fps=30, -) + # Store SPARC for the 3D animator + feature_dict[subplot_title][joint] = sparc_clean + + # Add to CSV dictionary + csv_data[f"{joint}_Speed"] = speeds + if "sparc" in metrics_to_compute: + csv_data[f"{joint}_SPARC_w{w}"] = sparc_clean + if "ldlj_v" in metrics_to_compute: + csv_data[f"{joint}_LDLJ_V_w{w}"] = ldlj_v_clean + if "ldlj_a" in metrics_to_compute: + csv_data[f"{joint}_LDLJ_A_w{w}"] = ldlj_a_clean + if "jerk_rms" in metrics_to_compute: + csv_data[f"{joint}_JerkRMS_w{w}"] = jerk_clean + if "samp_en" in metrics_to_compute: + csv_data[f"{joint}_SampEn_w{w}"] = samp_en_clean + if "harmonicity" in metrics_to_compute: + csv_data[f"{joint}_Harmonicity_w{w}"] = harmonicity_clean + if "n_submovements" in metrics_to_compute: + csv_data[f"{joint}_N_Submovements_w{w}"] = n_sub_clean + + # Generate static PNG plot for this joint if enabled + if generate_plot: + print(f"Generating clean multi-metric plot for {joint}...") + num_plots = 1 + len(metrics_to_compute) + fig, axes = plt.subplots(num_plots, 1, figsize=(12, 2.3 * num_plots), sharex=True) + + # Plot Speed Profile + axes[0].plot(csv_data["Time"], speeds, color="blue", linewidth=1.5) + axes[0].set_title(f"Smoothness & Complexity Analysis for {joint} (File: {file_stem}, Window: {w})") + axes[0].set_ylabel("Speed (mm/s)") + axes[0].grid(True, linestyle="--", alpha=0.5) + + plot_idx = 1 + if "sparc" in metrics_to_compute: + axes[plot_idx].plot(csv_data["Time"], sparc_clean, color="green", linewidth=1.5) + axes[plot_idx].set_ylabel("SPARC\n(higher=smoother)") + axes[plot_idx].grid(True, linestyle="--", alpha=0.5) + plot_idx += 1 + + if "ldlj_v" in metrics_to_compute: + axes[plot_idx].plot(csv_data["Time"], ldlj_v_clean, color="orange", linewidth=1.5) + axes[plot_idx].set_ylabel("LDLJ (Vel)\n(lower=smoother)") + axes[plot_idx].grid(True, linestyle="--", alpha=0.5) + plot_idx += 1 + + if "ldlj_a" in metrics_to_compute: + axes[plot_idx].plot(csv_data["Time"], ldlj_a_clean, color="purple", linewidth=1.5) + axes[plot_idx].set_ylabel("LDLJ (Accel)\n(lower=smoother)") + axes[plot_idx].grid(True, linestyle="--", alpha=0.5) + plot_idx += 1 + + if "jerk_rms" in metrics_to_compute: + axes[plot_idx].plot(csv_data["Time"], jerk_clean, color="red", linewidth=1.5) + axes[plot_idx].set_ylabel("Jerk RMS\n(lower=smoother)") + axes[plot_idx].grid(True, linestyle="--", alpha=0.5) + plot_idx += 1 + + if "samp_en" in metrics_to_compute: + axes[plot_idx].plot(csv_data["Time"], samp_en_clean, color="brown", linewidth=1.5) + axes[plot_idx].set_ylabel("Sample Entropy\n(lower=regular)") + axes[plot_idx].grid(True, linestyle="--", alpha=0.5) + plot_idx += 1 -# Optional: If you want to interact live after the video renders: -# animator.show() + if "harmonicity" in metrics_to_compute: + axes[plot_idx].plot(csv_data["Time"], harmonicity_clean, color="teal", linewidth=1.5) + axes[plot_idx].set_ylabel("Harmonicity\n(1.0=harmonic)") + axes[plot_idx].grid(True, linestyle="--", alpha=0.5) + plot_idx += 1 + + if "n_submovements" in metrics_to_compute: + axes[plot_idx].plot(csv_data["Time"], n_sub_clean, color="magenta", linewidth=1.5) + axes[plot_idx].set_ylabel("Submovements\n(lower=smoother)") + axes[plot_idx].grid(True, linestyle="--", alpha=0.5) + plot_idx += 1 + + axes[-1].set_xlabel("Time (seconds)") + plt.tight_layout() + + plot_path = results_dir / f"smoothness_plot_{file_stem}_{joint}_w{w}_full.png" + plt.savefig(plot_path, dpi=150) + plt.close() + print(f"Saved plot to {plot_path}") + + # Save CSV if enabled + if save_csv: + df_results = pd.DataFrame(csv_data) + csv_path = results_dir / f"smoothness_data_{file_stem}_w{w}.csv" + df_results.to_csv(csv_path, index=False) + print(f"\nSaved frame-by-frame data to {csv_path}") + +# ========================================== +# 5. RENDER & SAVE ANIMATION (OPTIONAL) +# ========================================== +if generate_video: + print("\nInitializing 3D Animator...") + animator = BenchmarkAnimator( + pos_tensor=pos_tensor, + feature_dict=feature_dict, + marker_names=marker_names, + bones_edges=bones_edges, + title=f"Smoothness Analysis ({data_type.capitalize()})", + ) + + output_filename = f"result_{file_stem}_Smoothness_{data_type}.gif" + video_path = results_dir / output_filename + + animator.save_video( + save_path=str(video_path), + video_fps=30, + ) + print(f"Saved 3D animation video to {video_path}") +else: + print("\nSkipping 3D video generation (generate_video = True).") \ No newline at end of file From 40a74ca08ca2c1fff799923ca9b03f2d7a93105d Mon Sep 17 00:00:00 2001 From: Nicorb <67009524+nicola-corbellini@users.noreply.github.com> Date: Thu, 24 Sep 2026 11:48:00 +0200 Subject: [PATCH 2/3] feat: add low-level direction change and smoothness features along with a multimodal capstone example --- examples/06_multimodal_capstone.ipynb | 36 ++++++++++++------------- examples/requirements.txt | 5 +++- pyeyesweb/low_level/direction_change.py | 9 ++++--- pyeyesweb/low_level/smoothness.py | 4 +-- pyproject.toml | 1 + 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/examples/06_multimodal_capstone.ipynb b/examples/06_multimodal_capstone.ipynb index a2edd7f..790bee4 100644 --- a/examples/06_multimodal_capstone.ipynb +++ b/examples/06_multimodal_capstone.ipynb @@ -29,7 +29,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "b2babcaa", "metadata": {}, "outputs": [], @@ -141,7 +141,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 2, "id": "4d56a31b", "metadata": {}, "outputs": [], @@ -246,14 +246,14 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "id": "eca0e7a2", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "ccea38e608874a8a9793cf0c05e1dd51", + "model_id": "cb377f42517543fdb158ebf1f7234bd9", "version_major": 2, "version_minor": 0 }, @@ -270,9 +270,9 @@ "text": [ " mean_energy peak_energy mean_jerk pct_sudden mean_sphericity\n", "sensor gesture \n", - "qualisys Infinite Gesture - Smooth 2.532240e+05 1.064411e+06 1455.960292 90.142483 0.220313\n", - " Hiding Object 4.742917e+06 4.057123e+07 26721.069840 92.444893 0.207452\n", - " Leaf Falling 1.128844e+06 5.642287e+06 5828.170613 90.329099 0.299954\n" + "qualisys Infinite Gesture - Smooth 2.532240e+05 1.064411e+06 1455.960016 90.142483 0.220313\n", + " Hiding Object 4.742917e+06 4.057123e+07 26721.067466 92.444893 0.207452\n", + " Leaf Falling 1.128844e+06 5.642287e+06 5828.169994 90.329099 0.299954\n" ] } ], @@ -311,7 +311,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "8a293609", "metadata": {}, "outputs": [], @@ -356,14 +356,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "id": "4b095ec9", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "462796853341476784d0f103a5dc8aa0", + "model_id": "fb8616643e0744dfa31df303b98020b5", "version_major": 2, "version_minor": 0 }, @@ -377,7 +377,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "d5d3d599b2d2496c9be0663d324251c1", + "model_id": "dee0a64427794bf4a0f4f8b54cb671c4", "version_major": 2, "version_minor": 0 }, @@ -415,15 +415,15 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 7, "id": "5d7e8f29", "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABvYAAAHqCAYAAADfxHnfAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAg5FJREFUeJzs3Xl4DXf7x/HPSWQVSSxZibX2LUppLEWlQtVDa6/WUtUtaYtWSW2l2pSniqKUp0WV8mjRVi3VVPRprbV0pyhiS2yVECQk8/vDlfNzmkVEnJNJ3q/rmusy3/l+59xzMnJn5p7FYhiGIQAAAAAAAAAAAACFmpOjAwAAAAAAAAAAAABwcxT2AAAAAAAAAAAAABOgsAcAAAAAAAAAAACYAIU9AAAAAAAAAAAAwAQo7AEAAAAAAAAAAAAmQGEPAAAAAAAAAAAAMAEKewAAAAAAAAAAAIAJUNgDAAAAAAAAAAAATIDCHgAAAAAAAAAAAGACFPYAAAAAAADyacCAAapcufJN+x0+fFgWi0ULFiy44zFlZ926dQoNDZW7u7ssFovOnz/vkDgAACgO8vr3AZAfFPZQrCxYsEAWi0UWi0Xff/99luWGYSgkJEQWi0UPPfSQAyLMu8qVK1u35Z9Thw4dHB0eAKCQKUo5MC0tTdOnT1ejRo3k7e0tX19f1a1bV0899ZT27t1r7XfjNlssFrm7u6tGjRqKiopSYmJilvWuWbNGFotFwcHBysjIyPaz/5l/S5YsqaZNm+qjjz7Ktn9ycrLGjx+vhg0bysvLSx4eHqpXr55GjBihEydOFMwXAgAmd/z4cXXq1Ene3t6qU6eOvvzyyyx9VqxYIX9/fyUlJeV5vd9//706duyo8uXLy93dXRUrVlTnzp21ZMmSggzfFM6ePauePXvKw8NDs2bN0qJFi1SyZElHhwUAxVJROjaTpPT0dM2fP19t2rRRmTJl5ObmpsqVK2vgwIH68ccf7+hnv/feew67YEaSTpw4oddee0179uxxWAwonko4OgDAEdzd3bVkyRK1bNnSpn3Tpk06duyY3NzcHBTZrQkNDdVLL72UpT04ONgB0QAAzKAo5MBu3bpp7dq16tOnjwYPHqyrV69q7969Wr16tZo3b65atWrZ9J8wYYKqVKmiK1eu6Pvvv9fs2bO1Zs0a/frrr/L09LT2W7x4sSpXrqzDhw/r22+/VXh4eLaff2P+PXnypP7zn/+of//+Sk1N1eDBg639/vrrL4WHhys+Pl49evTQU089JVdXV/3888/64IMPtHLlSv3555934BsCAHPp37+/jh8/rkmTJumHH35Qjx49tHfvXutV7leuXNHLL7+siRMnysfHJ0/rXL58uXr16qXQ0FC9+OKLKl26tA4dOqTvvvtO8+bN06OPPnoHt6jw2bFjhy5cuKDXX389x/wGALCvonBsdvnyZT3yyCNat26d7rvvPr366qsqU6aMDh8+rP/+979auHCh4uPjVaFChTvy+e+9957KlSunAQMG3JH138yJEyc0fvx4Va5cWaGhoTbL5s2bl+MFo8DtorCHYunBBx/U8uXL9e6776pEif//b7BkyRI1btxYZ86ccWB0eVe+fHk99thjjg5DhmHoypUr8vDwcHQoAICbMHsO3LFjh1avXq033nhDr776qs2ymTNnZvtYsY4dO6pJkyaSpCeffFJly5bVO++8o88//1x9+vSRJKWkpOjzzz9XTEyM5s+fr8WLF+d44vOf+XfAgAGqWrWqpk6dai3sXbt2TY888ogSExMVFxeX5WD9jTfe0KRJk/L9PQBAUXH58mV9++23iouL03333adnnnlGmzdv1vr16/X0009Lkt5++235+PjoySefzPN6X3vtNdWpU0dbt26Vq6urzbJTp04V6DaYQeY2+/r63rTvpUuXbC58AQDcGWY/NpOk4cOHa926dZo6daqGDBlis2zcuHGaOnWqYwLLRkpKil3vVndxcbHbZ6H44VGcKJb69Omjs2fPasOGDda2tLQ0ffrppzleuZmRkaFp06apbt26cnd3V0BAgJ5++mn9/fffNv0+//xzderUScHBwXJzc1O1atX0+uuvKz093aZfmzZtVK9ePf3+++9q27atPD09Vb58eU2ePLlAt3XAgAHy8vLS8ePH1bVrV3l5ecnPz08vv/xylpjyuo2VK1fWQw89pPXr16tJkyby8PDQ+++/L0k6cuSI/vWvf6lkyZLy9/fX0KFDtX79elksFsXFxUm6nthdXFx0+vTpLPE+9dRT8vX11ZUrVwr0ewAAXGf2HHjw4EFJUosWLbIsc3Z2VtmyZW+6jvvvv1+SdOjQIWvbypUrdfnyZfXo0UO9e/fWihUr8pyL/Pz8VKtWLWtskvTZZ5/pp59+0qhRo7IU9STJ29tbb7zxRp7WDwBF2ZUrV2QYhkqXLi1Jslgs8vX11aVLlyRdf0znW2+9penTp8vJKe+nMA4ePKh77rknS1FPkvz9/a3/jouLszlWyZTT+/BWrVqlevXqyd3dXfXq1dPKlSuz/fzz589rwIAB8vHxka+vr/r375/jO+327t2r7t27q0yZMnJ3d1eTJk30xRdf2PTJfGzbDz/8oGHDhsnPz08lS5bUww8/nO1x1Y3atGmj/v37S5LuueceWSwW650NmTl5586duu++++Tp6Wm9cOZW8/rPP/+s1q1by9PTU3fddZc+/fRTSdfvPGnWrJk8PDxUs2ZNffPNN1liPH78uJ544gkFBATIzc1NdevW1Ycffpil34wZM1S3bl15enqqdOnSatKkSbF8tCqAosHsx2bHjh3T+++/rwceeCBLUU+6fnz28ssv29ytt3v3bnXs2FHe3t7y8vJSu3bttHXrVptxec15lStX1m+//aZNmzZZH23apk0bm3Vs2rRJzz33nPz9/a1xHDlyRM8995xq1qwpDw8PlS1bVj169NDhw4ezbMP58+c1dOhQVa5cWW5ubqpQoYL69eunM2fOKC4uTvfcc48kaeDAgdYYMv92yO4deykpKXrppZcUEhIiNzc31axZU2+//bYMw7DpZ7FYFBUVZf27IzM3rlu37qY/FxQPFPZQLFWuXFlhYWH65JNPrG1r165VUlKSevfune2Yp59+WsOHD1eLFi00ffp0DRw4UIsXL1ZERISuXr1q7bdgwQJ5eXlp2LBhmj59uho3bqyxY8dq5MiRWdb5999/q0OHDmrYsKGmTJmiWrVqacSIEVq7dm2etuPq1as6c+ZMluny5cs2/dLT0xUREaGyZcvq7bffVuvWrTVlyhTNnTs3X9soSfv27VOfPn30wAMPaPr06QoNDVVKSoruv/9+ffPNN3rhhRc0atQobd68WSNGjLAZ+/jjj+vatWtatmyZTXvmHy/dunWTu7t7nr4DAMCtMXsOrFSpkqTrj828du1afr4CawHuxiLg4sWL1bZtWwUGBqp37966cOFCtu94ys61a9d07Ngx60lpSdYTso8//ni+YgSA4qJ06dKqVq2a3nzzTR06dEiLFy/Wnj171LRpU0nSK6+8oo4dO+q+++67pfVWqlRJsbGxOnbsWIHF+vXXX6tbt26yWCyKiYlR165d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qSBy3uDBg+Xs7GzTduN3c/XqVZ09e1Z33XWXfH19rTlHuv56hYYNG+rhhx/Ost4b48qrNWvWyNnZWS+88IJN+0svvSTDMLLcIRkeHq5q1apZ5xs0aCBvb+88nzdG0VakCnvfffedOnfurODgYFksFq1ateqW12EYht5++23VqFFDbm5uKl++PO8/KaL8/PwUHh6uJUuWaMWKFUpPT1f37t2z7bt//34lJSXJ39/feiIvc7p48aLNy9d/++03Pfzww/Lx8ZG3t7f8/PysyTEpKclmvRUqVMiSCEqXLp3tScTslCtXTuHh4VmmzMeUZXJ3d5efn1+un3Mr2yhdL+z905EjR1StWrUs23TXXXdl6durVy+5ublp8eLFkq5/N6tXr1bfvn3zlRwBAHln9hzo5uamUaNG6Y8//tCJEyf0ySef6N5779V///vfbB9HNmvWLG3YsEEbN27U77//rr/++svm4pSPP/5YTZs21dmzZ3XgwAEdOHBAjRo1UlpampYvX55lfZkX1qxbt05vv/22fH199ffff9u8x8nb29vmMWMAgNx5eXmpWbNmCgkJkSTNnz9fCQkJGjlypL755hsNHz5cb731liZPnqyXXnopy4WH2YmIiND69et1/vx5fffdd4qMjNSRI0f00EMPZTm+uZnMk4jVq1fPsqxmzZpZ+gYFBcnLyyvXfgcOHJBhGBozZkyWHDtu3DhJyhJnxYoVbeYzHwOd12PI7JQvXz7bdxHebl738fGx/jxvbLsx3tOnT+v8+fOaO3dulu8gs9iY+R2MGDFCXl5eatq0qapXr67IyEj98MMP+d5uwAw411n0mfnYzNvbW5LydNxz+vRpXbp0KUsulKTatWsrIyNDR48etWkviJyX3fnLy5cva+zYsdb33JUrV05+fn46f/68zXdz8OBB1atXL8+fdTNHjhxRcHBwlkJo7dq1rctv9M/tl27tvDGKthKODqAgpaSkqGHDhnriiSf0yCOP5GsdL774or7++mu9/fbbql+/vs6dO6dz584VcKQoLB599FENHjxYCQkJ6tixo3x9fbPtl5GRIX9/f2sR6p8yi2bnz59X69at5e3trQkTJqhatWpyd3fXrl27NGLECGVkZNiM++cVI5mMf7ww9Xbl9Dk3yus2Zrrx6pb8KF26tB566CEtXrxYY8eO1aeffqrU1FSbK4QAAHdO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rZpWr16d7Tv4YmJi1KlTJ7Vs2VJPPPGEzp07pxkzZqhu3bq6ePGitV/nzp3VokULjRw5UocPH1adOnW0YsWKLO80kq6/B7Zly5aqX7++Bg8erKpVqyoxMVFbtmzRsWPH9NNPP+Xre7xd9jy2feutt7Rx40Y1a9ZMgwcPVp06dXTu3Dnt2rVL33zzjbUA0b59ewUGBqpFixYKCAjQH3/8oZkzZ6pTp05Z3lcEFAec6yxazHhsJklTpkzRwYMH9cILL2jFihV66KGHVLp0acXHx2v58uXau3evevfuLUmaOHGiNmzYoJYtW+q5555TiRIl9P777ys1NVWTJ0/O1+c3btxYs2fP1sSJE3XXXXfJ399f999/f65jHnroIS1atEg+Pj6qU6eOtmzZom+++UZly5a16Td8+HB9+umn6tGjh5544gk1btxY586d0xdffKE5c+aoYcOGqlatmnx9fTVnzhyVKlVKJUuWVLNmzbK9M7Zz585q27atRo0apcOHD6thw4b6+uuv9fnnn2vIkCGqVq1avr4DFFNGESXJWLlypXV+9erVhiSjZMmSNlOJEiWMnj17GoZhGIMHDzYkGfv27bOO27lzpyHJ2Lt3r703AXfA/PnzDUnGjh07cu1XqVIlo1OnTlna586dazRu3Njw8PAwSpUqZdSvX9945ZVXjBMnTlj7/PDDD8a9995reHh4GMHBwcYrr7xirF+/3pBkbNy40dqvdevWRt26dbN8Rv/+/Y1KlSrddFsqVapkSMp2unF8//79jZIlS2YZP27cOCO7XwF52cacvh/DMIy//vrL6NSpk+Hh4WH4+fkZL730kvHZZ58ZkoytW7dm6b99+3ZDktG+ffubbjMAIP+KSg5MTEw03nrrLaN169ZGUFCQUaJECaN06dLG/fffb3z66ae3tM3PP/+8Ick4ePBgjp/32muvGZKMn376yTCM3HPgggULDEnG/PnzrW1///23MXbsWKN+/fqGp6en4e7ubtSrV8+Ijo42Tp48meu2AkBx89VXXxleXl42uSVTTEyMERwcbAQFBRmTJk266bo++eQTo3fv3ka1atUMDw8Pw93d3ahTp44xatQoIzk52abv6dOnjW7duhmenp5G6dKljaefftr49ddfs/xONwzD+Oyzz4zatWsbbm5uRp06dYwVK1Zkm7/Onj1rPP7444a3t7fh4+NjPP7448bu3buzXefBgweNfv36GYGBgYaLi4tRvnx546GHHrLJaznltI0bN2bJs9nJaXxOOdkwbj+v55QzJRmRkZE2bYmJiUZkZKQREhJiuLi4GIGBgUa7du2MuXPnWvu8//77xn333WeULVvWcHNzM6pVq2YMHz7cSEpKynXbgaKCc51FR1E5Nst07do14z//+Y/RqlUrw8fHx3BxcTEqVapkDBw40Ni9e7dN3127dhkRERGGl5eX4enpabRt29bYvHmzTZ9byXkJCQlGp06djFKlShmSjNatW+e6DsO4fow2cOBAo1y5coaXl5cRERFh7N2716hUqZLRv39/m75nz541oqKijPLlyxuurq5GhQoVjP79+xtnzpyx9vn888+NOnXqGCVKlLDJ89l9hxcuXDCGDh1qBAcHGy4uLkb16tWNf//730ZGRoZNv+xypWEY2caI4sliGEXzbYsWi0UrV6603rW0bNky9e3bV7/99luWq7i9vLwUGBiocePG6c0337R5hMPly5fl6empr7/+Wg888IA9NwEoMqZNm6ahQ4fq2LFjKl++vM2yn376SaGhofroo49u+jxuAAAAAACA4ohznQCATMXmUZyNGjVSenq6Tp06pVatWmXbp0WLFrp27ZoOHjxovfX1zz//lMTLK4G8unz5ss0LfK9cuaL3339f1atXz1LUk6R58+bJy8tLjzzyiD3DBAAAAAAAMC3OdQJA8VWkCnsXL17UgQMHrPOHDh3Snj17VKZMGdWoUUN9+/ZVv379NGXKFDVq1EinT59WbGysGjRooE6dOik8PFx33323nnjiCU2bNk0ZGRmKjIzUAw88oBo1ajhwywDzeOSRR1SxYkWFhoYqKSlJH3/8sfbu3avFixfb9Pvyyy/1+++/a+7cuYqKirK+bBYAAAAAAACc6wQAZK9IPYozLi5Obdu2zdLev39/LViwQFevXtXEiRP10Ucf6fjx4ypXrpzuvfdejR8/XvXr15cknThxQs8//7y+/vprlSxZUh07dtSUKVNUpkwZe28OYErTpk3Tf/7zHx0+fFjp6emqU6eOXnnlFfXq1cumX+XKlZWYmKiIiAgtWrSIl50DAAAAAADcgHOdAIDsFKnCHgAAjjBr1iz9+9//VkJCgho2bKgZM2aoadOmOfZfvny5xowZo8OHD6t69eqaNGmSHnzwQTtGDAAA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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAABvkAAAHqCAYAAAAuzyJSAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAgV5JREFUeJzt3QeYVOXVOPAXpFuwgyiKNXZQLMFeUMTygRWNFVs0YiP2KNaIXTQW1NhjQRO7CWoQNEas2HsHC2AFESnC/J/zfv/ZbxcWRYWdnZ3f73mG3Xvnzp07s3d2D/e857yNCoVCIQEAAAAAAABlo3GpDwAAAAAAAAD4eST5AAAAAAAAoMxI8gEAAAAAAECZkeQDAAAAAACAMiPJBwAAAAAAAGVGkg8AAAAAAADKjCQfAAAAAAAAlBlJPgAAAAAAACgzknwAAAAAAABQZiT5AAAAmGv222+/1KFDh5/c7sMPP0yNGjVKN9xwQ0l+GoMHD06dOnVKLVq0yMfxzTfflOQ4AACYezEnNDSSfEBZiYs+cdElbk888cRM9xcKhdS+fft8//bbb5/qswg8iq9lxts222xT6sMDAOqJTz75JG233XZpgQUWSKuuumq6//77Z9rmrrvuSosvvngaN27cbO83Yqnu3bunJZdcMie2ll566bTDDjukW2+9NVWaL7/8Mu22226pZcuW6fLLL08333xzmnfeeUt9WADAHNCQriWFadOmpeuvvz5tttlmaeGFF07NmzfP15h69+6dnnvuubn63FdccUXJBmSFTz/9NJ122mnpxRdfLNkxQH3TpNQHAPBLxIWouAC10UYb1Vj/2GOPpY8//jgHOOUgRov/8Y9/nGl9u3btSnI8AED9s+++++ZE37nnnpv++9//pl133TW9+eabVSOVJ02alI455ph01llnpdatW8/WPu+8887Uq1evHIsceeSRaaGFFkoffPBBevzxx9M111yTfve736VK8uyzz6Zvv/02nXnmmalr166lPhwAYC5oCNeSvv/++7TTTjvlDgSbbLJJOumkk3KiLzoi3HHHHenGG29MI0eOTEsttdRcS/ItuuiiuWquVEm+008/PcfBEcdWFzHs9OnTS3JcUEqSfEBZ2nbbbfPFqUsvvTQ1afJ/v8oiWOvcuXP64osvUjmIkfN77bVXqQ8jj1qLC4Qxeh0AqF8Xch599NE0bNiwfCHnkEMOSU8++WR66KGH0u9///u8zQUXXJCTewceeOBs7zdGQEdV4FNPPZWaNWtW476xY8emSlN8zQsuuOBPbjtx4sTUqlWrOjgqAGBOagjXko499tic4Lv44ovTUUcdVeO+U089Na+vL7777rs67YzQtGnTOnsuqE+06wTK0h577JHbKj3yyCNV66ZMmZL+/ve/z3LkeYzmGTBgQFpttdXy6K02bdrki2Nff/11je3uvffe3BIrquliFNfyyy+fR3VHO4Tqoi3C6quvnl5//fW0+eab54s9kbQ777zz5uhrjdFR8803Xx7B37Nnz/z9Yostlkfsz3hMs/saY8RTtKCIC4TrrLNOTu5dddVV+b6PPvoo/c///E8OxKLt19FHH523i7YVcYGxGDhG8PT555/PdLwHH3xwvkAWSUMA4NeJv6cxGCcq7UL8PY6/s5FoChEfnHPOOemSSy5JjRvP/n/v3nvvvbTuuuvOlOAL8fe/KP72V48Bfmr+vHvuuSfHRxGHxNe777671ueP+e4ixonkZLyeqFac1Rx4UbW4yy675FHqsd+IXe67775a23BFpWPfvn1zrBSxzI477lhrvDJjTBfPH+I9if0UR6cX473nn38+J1kj3osR878kZnz55ZfTpptumvexwgor5Li1WD2w/vrr53jsN7/5Tfr3v/890zHGz3n//ffPsV08V8R611133Uzb/eUvf8n3xXPEORPvVSW2XwWAhngtKaoN49rNVlttNVOCL8wzzzz5WlH1Kr4XXnght2ePtu9xPWnLLbfMg7x+SRwV15Jee+21HLsU25/G66m+j7jvD3/4Q44ni8cR15liXcQ5Ee8sssgiuTNFxJMzingwrkPFc8X7GPvYZ599cgI24tGI1UK0Ji0eQzEerW1Ovkg0RgetaMca+4tjiAFyEV9XF/vp06dPVSxbjLcioQr1nSQfUJbij3aXLl3SbbfdVrXuX//6V56HZvfdd6/1MRGExYinDTfcMF8Ii4DglltuSd26dUtTp06t2i6Cgwh8IrCJ7WI0V79+/dIJJ5ww0z4jqIv58zp27JguvPDCtPLKK6fjjz8+H8vsiOeNQGXGW4zary6CwjjOCIQiGIkLRPF8V1999S96jeGtt97KAW4Eh7FttDmI4GeLLbbIF5eOOOKI9Kc//SlXC8Rrqm7vvfdOP/zwQxo0aFCN9cXgeOedd87BLwDw60SiJi4SnX322bmdZvxdjzlI1ltvvXz/cccdly/cRALq51hmmWXSkCFD8sWiOeXhhx/OMUBcJOnfv38enFTb3DBxUaVHjx553rvoaBBtRuM4iom26uJC0m9/+9v0xhtv5Fgs4p+46BT7ri2BePjhh6eXXnopD0g69NBD8/yFccHmx0S8E4OUwhlnnJGPq1glGeJiYLzHESvFRb64IPdLYsYYYBXJvLiIFxeOImaNWCq+RmVBJGsjFouEZrQOLRozZkx+DyI+i9cSzxVJwgMOOCAfT/UWVRG/RYVmrI9WVnHMTz/99E/85ACgMpT7taS4P67FxDWZ2RFx1MYbb5xjo4gZTznllBxPRmKutvjgp+KoiC8i6RbHG/FS3CKOqi6SeZHArP7aoy16XFuK9ziqKKMzRcShcRzFgWthwoQJ+Xhj0NLWW2+d38fYNgZ8Ray4yiqr5FgtROxWPIZZxcERc8Yg9qhujPf7oosuykm++HnGz2lGMV9jHH8cZ8RrMdguYtuIBaFeKwCUkeuvvz6G2hSeffbZwmWXXVaYf/75CxMnTsz37brrroXNN988f7/MMssUtttuu6rH/ec//8mPu+WWW2rsb/DgwTOtL+6vut///veFVq1aFSZNmlS1btNNN82Pvemmm6rWTZ48udC2bdvCzjvv/JOvJY4xHl/brX///lXb7bvvvnndGWecUePxa621VqFz586/6DUWnzvuq+7CCy/M6++5556qdd9//31h5ZVXzuuHDh1atb5Lly6F9ddfv8bj77rrrpm2AwB+nSFDhhQWWmihqjjhqKOOyuv/+9//Flq2bFn48MMPf/Y+r7322ryvZs2a5fjplFNOybHEtGnTamwXf9Nr+9v+wQcf5PURmxV16tSpsMQSSxS++eabqnUPP/xw3i5ij6KIM2LdeeedV7Xuhx9+KGy88cYz7XPLLbcsrLHGGjVisOnTpxc22GCDwoorrjhTjNi1a9d8f9HRRx9dmGeeeWoc00/FmNUV472BAwfO9JifGzPeeuutVevefPPNvK5x48aFp556qmr9Qw89NNN7cMABB+T39YsvvqjxXLvvvnuhdevWVcfRo0ePwmqrrfajrxMAKlFDuZYUcU089oUXXpit192zZ88c67333ntV6z799NP8+jfZZJNfFEdFrBGvYUbFfWy00UY5rquu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IP8nlfppwQUXTG3btp2tSYwBgLollqr/xFLMaT739Z/PPUD9I8kHAHNYoVBIn332Wa4Ua9++fWrcWHfs+vbzmThxYho7dmxeXmKJJUp9SABANWKp+k0sxdw6r/wfqv7yuQeovyT5AGAO++GHH3ISqV27dqlVq1be33qoZcuW+Wsk+hZffHGtOwGgHhFL1X9iKeY0n/v6z+ceoH5SWgAAc9i0adPy12bNmnlv67FiAnbq1KmlPhQAoBqxVHkQSzEn+dyXB597gPpHkg8A5hJzvdVvfj4AUL/5W12/+fngvKo8PvcA9Y8kHwAAAAA0IJdffnnq0KFDatGiRVp//fXTM888M8tt77rrrrTOOuukBRdcMM0777ypU6dO6eabb55pTrZ+/frl+ayjbWPXrl3TO++8UwevBAD4MZJ8AECdOu200/KFg6L99tsv9ezZ008BAEAsxRwwaNCg1Ldv33TqqaemESNGpI4dO6Zu3brl+ahrs/DCC6c//elPafjw4enll19OvXv3zreHHnqoapvzzjsvXXrppWngwIHp6aefzsnA2OekSZP8zOqA/0MBMCtNZnkPADBHXXbZZXX6jvbp0yeVg0suuSSPDAYA+DFiKbEUs+eiiy5KBx10UE7UhUjMPfjgg+m6665LJ5xwwkzbb7bZZjWWjzzyyHTjjTemJ554IifyIlYfMGBAOvnkk1OPHj3yNjfddFNq06ZNuueee9Luu+8+1340Pve1838oAIpU8gEAJdW6devcGggAALEUv86UKVPS888/n9tpFjVu3DgvR6XeT4mE3pAhQ9Jbb72VNtlkk7zugw8+SKNHj66xz4jhow3oj+1z8uTJafz48TVuzBn+DwVAkUo+gHo4erASq7moH7777rt06KGH5nk55p9//nTMMcek+++/P7fXjNG7MdH63XffXaO9ZiTo4r5ouxmOP/74vM3HH3+c2rZtm/bcc888f0fTpk1rfc543DfffJNHAYe///3v6fTTT0/vvvtuatWqVVprrbXSvffemy9WbLnllmnUqFF5v0VHHXVUvu8///lP+uijj/I5H6OO4wJHzENy/vnnp2233Xauv3cAzJpYikohlqLUvvjiizRt2rRcZVddLL/55puzfNy4cePSkksumRNz88wzT7riiivSVlttle+LBF9xHzPus3hfbfr375/j+obO5x5gzinX/zf0KeH1V5V8AECVY489Nj322GM5qfbwww+nYcOG5Xk8fo5IDt5www3p9ddfz21krrnmmnTxxRfP1mM/++yztMcee6T9998/vfHGG/n5d9pppzyiOEYSL7fccunmm2+u2n7q1KnplltuyduHww47LF+YePzxx9Mrr7ySzj333DTffPP5CQMAdUIsRbmKGP7FF19Mzz77bPrzn/+c5/SLWPzXOPHEE3PysHiLwXoNkc89AKWkkg8AyCZMmJCuvfba9Le//S1XzIWYi2OppZb6We9QzNVRFJV0UQ14++23p+OOO262knw//PBDTuwts8wyed0aa6xRdf8BBxyQrr/++vwf6RBVhpMmTUq77bZbXh45cmTaeeedqx4TSUEAgLoglqI+WHTRRXMl3pgxY2qsj+Xq3TBmFC09V1hhhfx9dPGIAXdRiRfz9RUfF/tYYoklauwztp2V5s2b51tD5nMPQKmp5AMAsvfeey+3uIy5NYoWXnjh9Jvf/OZnvUODBg1KG264Yb4YEFV0kfSL5Nvs6NixY04wRpJu1113zVWAX3/9dY3WntHG86mnnsrLUTEYCb555503Lx9xxBHprLPOys9/6qmnppdfftlPFwCoE2Ip6oNmzZqlzp0753n1iqZPn56Xu3TpMtv7icdEh4yw7LLL5ti++j5jfr2nn376Z+2zIfK5B6DUJPkAgNkWc/JF68zqomVm0fDhw/McfDEH3gMPPJBeeOGF9Kc//SknD2dHjDp+5JFH0r/+9a+06qqrpr/85S85yfjBBx/k+xdffPG0ww475Gq+GDkc2xVbdYYDDzwwvf/++2nvvffO7TrXWWedvA8AgPpALEVdiFabMVguunJERV7MuR3zxvXu3Tvfv88+++RWmkVRsRcxeMTRsf2FF16YW+TvtddeVedtzIMdg+nuu+++HGfHPtq1a1djrm5q53MPwNwkyQcAZMsvv3xq2rRpHpFbFFV0b7/9dtXyYostlltqFr3zzjtp4sSJVctPPvlkbrMZib1IsK244orpo48++tn/CY5KvNNPPz0nCWM08t13310jkRfVgldffXU+5ti2uvbt26dDDjkk3XXXXemPf/xjvsABADC3iaWoL3r16pUuuOCC1K9fv9xOM+baGzx4cGrTpk2+P7psVI/pIwH4hz/8Ia222mo5tv7HP/6RW/hH3F0UrfcPP/zwdPDBB6d1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HpxatGhR0mMHAAAA+KW06ywzhx12WNpuu+1S165dS30oAAD1wvzzz58GDBiQPvroo/T999+n9957Lw+GatasWdU2Uc13xhlnpNGjR6dJkyalf//732mllVYq6XEDAAAA/BqSfGXk9ttvTyNGjEj9+/efre0nT56c55upfgMAAACgYbv88stThw4dcteC9ddfPz3zzDOz3Da6RW288cZpoYUWyrcYWD7j9vvtt18eNFX9ts0229TBKwEAfowkX5kYNWpUOvLII9Mtt9wy222lIhnYunXrqlv79u3n+nECAAAAUDqDBg1Kffv2TaeeemoeLN6xY8fUrVu33Na8NsOGDUt77LFHGjp0aBo+fHi+frT11lunTz75pMZ2kdT77LPPqm633XZbHb0iAGBWJPnKxPPPP5+DsbXXXjs1adIk3x577LF06aWX5u+nTZs202NOPPHENG7cuKpbJAoBAAAAaLguuuiidNBBB6XevXunVVddNQ0cODC1atUqXXfddbVuHwPKY27jTp06pZVXXjn99a9/TdOnT09DhgypsV3z5s1T27Ztq25R9QcAlFaTEj8/s2nLLbdMr7zySo11EaxF8HX88ceneeaZZ6bHRPAVNwAAAAAavilTpuSB4jHwu6hx48a5BWdU6c2OiRMnpqlTp6aFF154poq/xRdfPCf3tthiizwH8iKLLPKj08jErcg0MgAw50nylYn5558/rb766jXWzTvvvDmYmnE9AAAAAJXniy++yN2e2rRpU2N9LL/55puztY8YTN6uXbucGKzeqnOnnXZKyy67bHrvvffSSSedlLp3754Th7UNPC9OI3P66af/ylcEAPwYST4AAAAAIJ1zzjnp9ttvz1V7LVq0qHpHdt9996rv11hjjbTmmmum5ZdfPm8X3adqE9WEMTdg9Uq+mO8PAJhzJPnKWARSAAAAABAWXXTRXFk3ZsyYGm9ILMc8ej/mggsuyEm+f//73zmJ92OWW265/FzvvvvuLJN8ppEBgLmvcR08BwAAAAAwlzVr1ix17tw5DRkypGrd9OnT83KXLl1m+bjzzjsvnXnmmWnw4MFpnXXW+cnn+fjjj9OXX36ZllhiiTl27ADAzyfJBwAAAAANRLTIvOaaa9KNN96Y3njjjXTooYem7777LvXu3Tvfv88+++RWmkXnnntuOuWUU9J1112XOnTokEaPHp1vEyZMyPfH12OPPTY99dRT6cMPP8wJwx49eqQVVlghdevWrWSvEwDQrhMAAAAAGoxevXqlzz//PPXr1y8n6zp16pQr9Nq0aZPvHzlyZGrc+P/G/V955ZVpypQpaZdddqmxn1NPPTWddtppuf3nyy+/nJOG33zzTWrXrl3aeuutc+VftOQEAErHnHwAAAAA0ID06dMn32ozbNiwGstRnfdjWrZsmR566KE5enwAwJyhXScAAAAAAACUGUk+AAAAAAAAKDOSfAAAAAAAAFBmJPkAAAAAAACgzEjyAQAAAAAAQJmR5AMAAAAAAIAyI8kHAAAAAAAAZUaSDwAAAAAAAMqMJB8AAAAAAACUGUk+AAAAAAAAKDOSfAAAAAAAAFBmJPkAAAAAAACgzEjyAQAAAAAAQJmR5AMAAAAAAIAyI8kHAAAAAAAAZUaSDwAAAAAAAMqMJB8AAAAAAACUGUk+AAAAAAAAKDOSfAAAAAAAAFBmJPkAAAAAAACgzEjyAQAAAAAAQJmR5AMAAAAAAIAyI8kHAAAAAAAAZUaSDwAAAAAAAMqMJB8AAAAAAACUmSalPgAAAAAAgF/isssuK8s3rk+fPqU+BAAaAJV8AAAAAAAAUGYk+QAAAAAAAKDMSPIBAAAAAABAmZHkAwAAAAAAgDIjyQcAAAAAAABlRpIPAAAAAAAAyowkHwAAAAAAAJQZST4AAAAAAAAoM5J8AAAAAAAAUGYk+QAAAAAAAKDMSPIBAAAAAABAmZHkAwAAAAAAgDIjyQcAAAAAAABlpkmpDwAAAAAAAKjdZZddVrZvTZ8+fUp9CNCgqeQDAAAAAACAMiPJBwAAAAAAAGVGkg8AAAAAGpDLL788dejQIbVo0SKtv/766Zlnnpnlttdcc03aeOON00ILLZRvXbt2nWn7QqGQ+vXrl5ZYYonUsmXLvM0777xTB68EAPgxknwAAAAA0EAMGjQo9e3bN5166qlpxIgRqWPHjqlbt25p7NixtW4/bNiwtMcee6ShQ4em4cOHp/bt26ett946ffLJJ1XbnHfeeenSSy9NAwcOTE8//XSad9558z4nTZpUh68MAJiRJB8AAAAANBAXXXRROuigg1Lv3r3TqquumhNzrVq1Stddd12t299yyy3pD3/4Q+rUqVNaeeWV01//+tc0ffr0NGTIkKoqvgEDBqSTTz459ejRI6255prppptuSp9++mm655576vjVAQDVSfIBAAAAQAMwZcqU9Pzzz+d2mkWNGzfOy1GlNzsmTpyYpk6dmhZeeOG8/MEHH6TRo0fX2Gfr1q1zG9DZ3ScAMHc0mUv7BQAAAADq0BdffJGmTZuW2rRpU2N9LL/55puztY/jjz8+tWvXriqpFwm+4j5m3GfxvtpMnjw534rGjx//s14LAPDTVPIBAAAAAOmcc85Jt99+e7r77rtTixYtftU70r9//1zxV7zFXH8AwJwlyQcAQNn75JNP0l577ZUWWWSR1LJly7TGGmuk5557rur+mEumX79+aYkllsj3x8j0d955p6THDAAwpy266KJpnnnmSWPGjKmxPpbbtm37o4+94IILcpLv4YcfzvPuFRUf93P3eeKJJ6Zx48ZV3UaNGvULXxUAMCuSfAAAlLWvv/46bbjhhqlp06bpX//6V3r99dfThRdemBZaaKGqbc4777x06aWXpoEDB6ann346zTvvvKlbt25p0qRJJT12AIA5qVmzZqlz585pyJAhVeumT5+el7t06TLLx0WsdOaZZ6bBgwenddZZp8Z9yy67bE7mVd9ntN6MmOrH9tm8efO0wAIL1LgBAHOWOfkAAChr5557bm7/dP3119e4GFW9im/AgAHp5JNPTj169MjrbrrppjyPzD333JN23333khw3AMDc0Ldv37TvvvvmZN16662X46Dvvvsu9e7dO9+/zz77pCWXXDK30yzGUtHx4NZbb00dOnSommdvvvnmy7dGjRqlo446Kp111llpxRVXzHHWKaeckuft69mzpx8iAJSQSj4AAMrafffdly9i7brrrmnxxRdPa621Vrrmmmuq7v/ggw/yxapo0VkU88Ksv/76afjw4SU6agCAuaNXr1659WYk7jp16pRefPHFXKEXA5zCyJEj02effVa1/ZVXXpmmTJmSdtlll9zavHiLfRQdd9xx6fDDD08HH3xwWnfdddOECRPyPn/tvH0AwK+jkg8AgLL2/vvv54tTMWr9pJNOSs8++2w64ogjcruqGMVeHI1evLBVFMvF+2ozefLkfKvelgoAoBz06dMn32ozbNiwGssffvjhT+4vqvnOOOOMfAMA6g+VfGUiLlzFpMfFHubR8zzmnAEAqHQxz8zaa6+dzj777FzFFyPMDzrooDz/3q8RLayi4q94i5agAAAAAPWFJF+ZWGqppdI555yTnn/++fTcc8+lLbbYIs8p89prr5X60AAASiraSa266qo11q2yyiq5FVVo27Zt/jpmzJga28Ry8b7anHjiiWncuHFVt1GjRs2V4wcAAAD4JST5ysQOO+yQtt122zzB8UorrZT+/Oc/58mPn3rqqVIfGgBASW244YbprbfeqrHu7bffTssss0z+ftlll83JvCFDhtRovfn000/n7giz0rx586ouCsUbAAAAQH1hTr4yNG3atHTnnXem77777kcvTAEAVIKjjz46bbDBBrld52677ZaeeeaZdPXVV+dbcQ6Zo446Kp111ll5wFQk/U455ZTUrl271LNnz1IfPgAAAMAvIslXRl555ZWc1Js0aVKu4rv77rtnak1V3eTJk/Ot+oh1AICGZt11181xUbTXPOOMM3ISb8CAAWnPPfes2ua4447LA6Rivr5vvvkmbbTRRmnw4MGpRYsWJT12AAAAgF9Kkq+M/OY3v0kvvvhinhPm73//e9p3333TY489NstEX//+/dPpp59e58cJAFDXtt9++3yblajmiwRg3AAAAAAaAnPylZFmzZqlFVZYIXXu3Dkn8Dp27JguueSSWW4fo9kjIVi8jRo1qk6PFwAAAAAAgLlDJV8Zmz59eo12nDNq3rx5vgEAAAAAANCwSPKViajK6969e1p66aXTt99+m2699dY0bNiw9NBDD5X60AAAAAAAAKhjknxlYuzYsWmfffZJn332WWrdunVac801c4Jvq622KvWhAQAAAAAAUMck+crEtddeW+pDAAAAAAAAoJ5oXOoDAAAAAAAAAH4eST4AAAAAAAAoM5J8AAAAAAAAUGYk+QAAAAAAAKDMSPIBAAAAAABAmZHkAwAAAAAAgDIjyQcAAAAAAABlRpIPAAAAAAAAyowkHwAAAAAAAJQZST4AAAAAAAAoM5J8AAAAAAAAUGYk+QAAAAAAAKDMSPIBAAAAAABAmZHkAwAAAAAAgDIjyQcAAAAAAABlRpIPAAAAAAAAyowkHwAAAAAAAJQZST4AAAAAAAAoM5J8AAAAAAAAUGYk+QAAAAAAAKDMSPIBAAAAAABAmZHkAwAAAAAAgDIjyQcAAAAAAABlRpIPAAAAAAAAyowkHwAAAAAAAJQZST4AAAAAAAAoM5J8AAAAAAAAUGYk+QAAAAAAAKDMSPIBAAAAAABAmZHkAwAAAAAAgDIjyQcAAAAAAABlRpIPAAAAAAAAyowkHwAAAAA0IJdffnnq0KFDatGiRVp//fXTM888M8ttX3vttbTzzjvn7Rs1apQGDBgw0zannXZavq/6beWVV57LrwIA+CmSfAAAAADQQAwaNCj17ds3nXrqqWnEiBGpY8eOqVu3bmns2LG1bj9x4sS03HLLpXPOOSe1bdt2lvtdbbXV0meffVZ1e+KJJ+biqwAAZockHwAAAAA0EBdddFE66KCDUu/evdOqq66aBg4cmFq1apWuu+66Wrdfd9110/nnn59233331Lx581nut0mTJjkJWLwtuuiic/FVAACzQ5IPAAAAABqAKVOmpOeffz517dq1al3jxo3z8vDhw3/Vvt95553Url27XPW35557ppEjR86BIwYAfg1JPgAAAABoAL744os0bdq01KZNmxrrY3n06NG/eL8xr98NN9yQBg8enK688sr0wQcfpI033jh9++23s3zM5MmT0/jx42vcAIA5q8kc3h8AAAAA0IB079696vs111wzJ/2WWWaZdMcdd6QDDjig1sf0798/nX766XV4lABQeVTyAQAAAEADEPPkzTPPPGnMmDE11sdyzKM3pyy44IJppZVWSu++++4stznxxBPTuHHjqm6jRo2aY88PAPwvST4AAAAAaACaNWuWOnfunIYMGVK1bvr06Xm5S5cuc+x5JkyYkN577720xBJLzHKb5s2bpwUWWKDGDQCYs7TrBAAAAIAGom/fvmnfffdN66yzTlpvvfXSgAED0nfffZd69+6d799nn33SkksumdtphilTpqTXX3+96vtPPvkkvfjii2m++eZLK6ywQl5/zDHHpB122CG36Pz000/TqaeemisG99hjjxK+UgBAkg8AAAAAGohevXqlzz//PPXr1y+NHj06derUKQ0ePDi1adMm3z9y5MjUuPH/NfeKpN1aa61VtXzBBRfk26abbpqGDRuW13388cc5offll1+mxRZbLG200Ubpqaeeyt8DAKUjyQcAAAAADUifPn3yrTbFxF1Rhw4dUqFQ+NH93X777XP0+ACAOcOcfAAAAAAAAFBmJPkAAAAAAACgzEjyAQAAAAAAQJmR5AMAAAAAAIAyI8kHAAAAAAAAZUaSDwAAAAAAAMqMJB8AAAAAAACUGUk+AAAAAAAAKDOSfAAAAAAAAFBmJPkAAAAA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ST4AAAAAAAAoM5J8AAAAAAAAUGYk+QAAAAAAAKDMSPIBAAAAAABAmZHkAwAAAAAAgDIjyQcAAAAAAABlRpIPAAAAAAAAykyTUh8AAFB/XHbZZakc9enTp9SHAAAAAAB1SiUfAAAAAAAAlBlJPgAAAAAAACgzknwAAJS9/v37p3XXXTfNP//8afHFF089e/ZMb731Vo1tJk2alA477LC0yCKLpPnmmy/tvPPOacyYMSU7ZgAAAIBfQ5KvjDz++ONphx12SO3atUuNGjVK99xzT6kPCQCgXnjsscdyAu+pp55KjzzySJo6dWraeuut03fffVe1zdFHH53uv//+dOedd+btP/3007TTTjuV9LgBAAAAfqkmv/iR1Lm4SNWxY8e0//77uyAFAFDN4MGDa7wfN9xwQ67oe/7559Mmm2ySxo0bl6699tp06623pi222CJvc/3116dVVlklJwZ/+9vfej8BAACAsiLJV0a6d++ebwAA/LhI6oWFF144f41kX1T3de3atWqblVdeOS299NJp+PDhtSb5Jk+enG9F48eP97YDAAAA9YZ2nQAANCjTp09PRx11VNpwww3T6quvnteNHj06NWvWLC244II1tm3Tpk2+b1bz/LVu3brq1r59+zo5fgAAAIDZIcnXgMXI8xhxXv0GANDQxdx8r776arr99tt/1X5OPPHEXBFYvI0aNWqOHSMAAADAryXJ14AZfQ4AVJo+ffqkBx54IA0dOjQttdRSVevbtm2bpkyZkr755psa248ZMybfV5vmzZunBRZYoMYNAAAAoL6Q5GvAjD4HACpFoVDICb677747Pfroo2nZZZetcX/nzp1T06ZN05AhQ6rWvfXWW2nkyJGpS5cuJThiAAAAgF+nya98PPVYjD6PGwBAJbTovPXWW9O9996b5p9//qp59mIuvZYtW+avBxxwQOrbt29aeOGFc1Xe4YcfnhN8v/3tb0t9+AAAAAA/myRfGZkwYUJ69913q5Y/+OCD9OKLL+YLVUsvvXRJjw0AoJSuvPLK/HWzzTarsf76669P++23X/7+4osvTo0bN04777xznru4W7du6YorrijJ8QIAAAD8WpJ8ZeS5555Lm2++edVyjEQP++67b7rhhhtKeGQAAKVv1/lTWrRokS6//PJ8AwAAACh3knxlJEamz84FLAAAAAAAABq2xqU+AAAAAAAAAODnkeQDAAAAAACAMiPJBwAAAAAAAGVGkg8AAAAAAADKjCQfAAAAADQgl19+eerQoUNq0aJFWn/99dMzzzzzo9vfeeedaeWVV87br7HGGumf//xnjfv322+/1KhRoxq3bbbZZi6/CgDgp0jyAQAAAEADMWjQoNS3b9906qmnphEjRqSOHTumbt26pbFjx9a6/ZNPPpn22GOPdMABB6QXXngh9ezZM99effXVGttFUu+zzz6rut1222119IoAgFmR5AMAAACABuKiiy5KBx10UOrdu3daddVV08CBA1OrVq3SddddV+v2l1xySU7gHXvssWmVVVZJZ555Zlp77bXTZZddVmO75s2bp7Zt21bdFlpooTp6RQDArEjyAQAAAEADMGXKlPT888+nrl27Vq1r3LhxXh4+fHitj4n11bcPUfk34/bDhg1Liy++ePrNb36TDj300PTll1/+6LFMnjw5jR8/vsYNAJizJPkAAAAAoAH44osv0rRp01KbNm1qrI/l0aNH1/qYWP9T20el30033ZSGDBmSzj333PTYY4+l7t275+ealf79+6fWrVtX3dq3b/+rXx8AUFOTGZYBAAAAAKrsvvvuVd+vscYaac0110zLL798ru7bcssta32nTjzxxDw3YFFU8kn0AcCcpZIPAAAAABqARRddNM0zzzxpzJgxNdbHcsyjV5tY/3O2D8stt1x+rnfffXeW28QcfgsssECNGwAwZ0nyAQAAAEAD0KxZs9S5c+fcVrNo+vTpeblLly61PibWV98+PPLII7PcPnz88cd5Tr4lllhiDh49APBzSfIBAAAAQAMRLTKvueaadOONN6Y33ngjHXrooem7775LvXv3zvfvs88+uZVm0ZFHHpkGDx6cLrzwwvTmm2+m0047LT333HOpT58++f4JEyakY489Nj311FPpww8/zAnBHj16pBVWWCF169atZK8TADAnHwAAAAA0GL169Uqff/556tevXxo9enTq1KlTTuK1adMm3z9y5MjUuPH/jfvfYIMN0q233ppOPvnkdNJJJ6UVV1wx3XPPPWn11VfP90f7z5dffjknDb/55pvUrl27tPXWW6czzzwzt+QEAEqnSQmfGwAAAACYw6IKr1iJN6Nhw4bNtG7XXXfNt9q0bNkyPfTQQ35GAFAPadcJAAAAAAAAZUaSDwAAAAAAAMqMJB8AAAAA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Fi3SkUceWeN+aAijpOJ3ehg/fnzaYIMN0r333iuRDXOBWIpKIpaiUoiloO6IpagkYikqhVjqf6nkY66YsVJp0003Tdttt106/fTT84Xggw8+OO2yyy7plltuSd27d89JEGhopeF9+vRJzz33XD7v4xx/9NFHS3psMKdF9d5nn32Wevfunf71r3+lp556Kg0aNCh98skn3mz4lcRSVCqxFJVELAVzj1iKSiWWopKIpf6XJB9zRfVKpeIfl7PPPjv997//Tdddd11q2rRpbl0YSY8BAwakfv36pccff9xPg7JVPM/jj8uUKVPSDz/8kF566aW05pprpmWXXTatv/76+X6tOmlInnjiibTGGmuk7777Lk2aNCltv/326a677koPPPBA/gwAv5xYikojlqISiaVg7hFLUWnEUlQisdT/kuRjrohWnIcffnhV0uPZZ5/NF4L79u2bb99++21acsklU+vWrdMhhxySNtpoo1zt9M033/iJUJaK85Gdf/75afXVV89f//jHP+bKprjv+uuvzxVP8R8NiT7KTXEu1aLi99Fu+Te/+U268cYb07777pvuu+++XNV33nnnpXfffbeERwzlTyxFpRFL0ZCJpaDuiaWoNGIpGjKx1I+T5GOuiKTe8OHDc4XeUkstlRN5X3/9dTr22GNT+/bt8/xk1S8U/+Uvf0nDhg1L999/v58IZenzzz9PW265ZbrqqqvSaaedlpPaEydOzPfFef/www/nc3zGEYUSfpRLf/M4b7///vsa53AksZdYYonUsmXLqsq9Sy65JH3xxRc58RcVfsAvI5ai0oilaKjEUlAaYikqjViKhkos9dMk+ZgrpeE9evRIH3/8cfrzn/+cevXqlZ5//vm00EILpUUXXTSdcMIJeS6+119/vaqqabXVVkuHHnpoOuWUU9KHH37op0K9VltiLhJ4UaEa85L97ne/y20LW7Vqle/bZ5990oorrpj+8Y9/5PM+vPzyyzMl/KC+nNsxQqp6q4+ost5///3THnvskS6++OI0duzYfN8mm2ySE31x7jdp0iRNnTo1zTvvvKlnz5759/wLL7xQ0tcD5UgsRSUQS9FQiaWg9MRSVAKxFA2VWOqXkeRjjk7oWiwNj/n21ltvvdSxY8e09NJLV100Dr///e/TSiutlNtzxrpikiMSgl9++aUWb9T7c722xFwk+eIPUSTzqm9ffMyZZ56ZRowYkU466aS08847p06dOqXnnnuuDo8efjyAuvrqq/N5GqJyr/j7PBLSe+21V/rkk09Shw4d0sknn5zbcUZib6uttkqLL754OuOMM/K2Md/q5MmTc+V2JAKvueYac/PBbBBLUSnEUjREYikoPbEUlUIsRUMklvr1msyBfVDhH8LiheCY6DIqOaJN4a677pp23HHH1KdPn3T33XenzTffPK255pr5Ym9sExeIt9tuu9wjPS4SR7Iv5ueLOcvmm2++Ur8sqFXxXL/55pvTp59+mpZZZpm0++6753XRxjCSHdEeYbHFFqvx2Yjz/re//W0+72MOs0mTJuVK13bt2nmnKblIWk+ZMiUn8bp3757Xxe/kaLl55JFHpvHjx+fk9QUXXJB/f6+wwgrppptuSoMGDUoHHnhg2nvvvdOJJ56Y2rRpkyv7nn766XxuR7vOuO/cc89Nbdu2LfXLhHpLLEUlEUvREImloLTEUlQSsRQNkVhqDijAr/T6668X1l577cKSSy5ZaN++ff7+wQcfzPf9+9//Lmy88caFI444YqbHbb/99oVlllmmMHHiRD8D6pUnnniiMHDgwML3339fY/0bb7yRz+84b3fffffCYostVthnn30Kn3zySWHw4MGFli1bFh544IEaj3n88ccLf/3rX6uWp06dWuv3UNe+/vrrwsEHH5x/T1c3ZsyYqu/322+/QrNmzQqnnHJK1boJEyYUevXqVejevXvh3XffzevOOuuswoorrlho27Zt/lsQfwPefPPNwnzzzVe4//776/BVQXkSS9HQiKWoBGIpqD/EUjQ0YikqgVhqztGuk18lKpKi0mPllVfOLd1uuOGG1Llz5zwnWcw9tuWWW6aNN944tyn85z//mR/z0UcfpdGjR6dLLrkk/elPf0otW7b0U6BeierTqGxq0aJFjfXRenDZZZfN80bedtttuZIpqvoGDhyYunXrljbddNN09tln5+2iUu/JJ5/M5/hDDz2UJk6cmPcRlVDFSqni91CKNgjvvvtueu2119Kll15add/gwYNzNV/MpxeOP/74tOqqq6b3338/t+cMMedeVOh99dVX+fwPcZ7HxPYPP/xwPve33Xbb/H1UAEZ1HzBrYikaIrEUDZlYCuoXsRQNkViKhkwsNRfMwYQhDdgPP/xQ6/onn3yysNBCCxWeeuqpGutXX331wu9+97v8/SuvvFLo0aNH4Te/+U1h//33LzRq1KgwaNCgOjlu+DmmTZs207pipWlU63Xs2LHw2muv5eVjjjkmn/u77bZb4Z133snrPvjgg8KRRx6ZK5+i4i+qmPr06VOYPn26HwT1QlTtbbbZZlXLUWW66qqrFm666aa8/NJLLxW23XbbXKn3zTff5HWnn356Yf3115/p9/bhhx+ePxMPP/xw1br4nDz//PP5vF900UUL55xzTv5c+QyAWIrKIJaioRNLQem4LkUlEEvR0Iml5g5JPn7WH5iPP/44t2qr3hKhRYsWhbfffjsvF9sb3nXXXYUmTZoUvvrqq7z83HPPFY4//vic+BsxYoR3nXotEhLRhnCjjTYq3HLLLVWfg2hHG61nl19++ZzEq57c+Oyzz6oSGdHW89FHH82fl5/6DwnUpbvvvrsw77zzFq666qq8/N577xV69+6dk3jffvttXnfFFVfk5QEDBuTlL774orDFFlsU9txzz8KoUaOq9vXMM8/kz0P18zza00aCsEuXLjMN/oBKJpai0oilaKjEUlAaYikqjViKhkosNXdI8jFbYm6lqP5YbbXVCmussUbhhhtuKHz55ZeFkSNHFjbYYIPC0UcfXWP7//73v4V27doV/vOf/3iHqZfi/C0m3qZMmVLrNmuuuWaee+/999/Py4ceemhhnnnmKVx++eU1tnvssccKJ554YmHs2LEz7SOeQxUTpVY8B6Pfed++ffO8eZMnT87r/vGPf+Skdb9+/fLy559/Xth7770LW221VeGtt97K66677rrCeuutV7j44ot/dP/xWfroo4/q6FVBeRFL0dCIpagkYikoPbEUDY1Yikoilpq7zMnHT3r++efT9ttvn5Zbbrl00UUXpQ022CD1798/9evXL7Vv3z5ttdVWaejQoemRRx6peswLL7yQ2rVrl9Zee23vMPXOjTfemM/bp59+Oi83bdo0jR8/Pv33v//N80UWnXfeeenxxx+vOre7du2az/mvv/46z6k3bdq0fK6fddZZ6b333qv1ueaZZ57UqFGjOnplMLMY0FM8BxdccMG0++67p/nmmy8dd9xxed1mm22Wz+1//OMf6a233kqLLrpo6tmzZ55H8rrrrsvb9O7dO80///zp0UcfTWPGjKmx//gsFPcfn6Wll17ajwFmIJaioRFLUUnEUlB6YikaGrEUlUQsVQfmchKRMjJjO8Fihj1atq2yyipVc5OFCy+8sLDWWmsVHnzwwVz1sddeexWaN2+e59w76KCD8lxk/fv3z/tQxUR9E5V50XrzlFNOKXz33Xe5Mi/m0Yt5I6PC6bLLLquq7tt1110LG2+8cW7BOXXq1NzKsGXLlvkzsc022+R2tQceeGBh0qRJpX5ZUMOs5sKL3+XxO3yBBRaoqtQbOnRortbed999qx4bFX+bbLJJVVvaV199NY80BGZNLEWlEEtRCcRSUPfEUlQKsRSVQCxVd1TyUVWJERVHISqaQlRmRKXS+++/n1ZcccWq+8OOO+6YK5r+/ve/p4UXXjjdfPPN6YwzzsjbRJXHQw89lE444YS8D1VMlHKkSJzbxe/DDz/8kJZddtl04IEHpvvuuy/dfvvt6YEHHshf77///rTzzjunK6+8Mp122ml5+zivP/zww3THHXekyZMnp0MPPTRX9p166qlp0003TSNGjEjXXHNNat68edVzQV2L39UzLjdu3Dj//n3xxRfTrbfemt599900adKk1LJly9S9e/fUqVOndPTRR+ftN9poo1yx/dRTT6WHH344Pzaq+SZMmJDXhdVWWy3/vneeQ+3EUjREYikqhVgKSk8sRUMklqJSiKVKrA4TitRzo0aNKvTs2bPQpUuXwtlnn11477338vrTTjutsPTSSxc+/vjjGlUh++23X2H77bcv4RHD7E3MPXr06MInn3xSGDduXI0RgjG/5BJLLFE44IADalQ5xfkfFX1vv/12Xnf88ccXVl999aqKptqeq/rzQV2pft7FOX7eeedVrfviiy8KO+20U2GxxRbL529Unx522GH5vqhKve2223I13wMPPJDXvfzyy7lydfPNN6/a5yuvvOKHCT+DWIqGRCxFJRBLQf0ilqIhEUtRCcRS9YNKvgpVW3b9yCOPzPM1xZx7t9xySzrqqKPyfVGRN27cuFzdFJVMRfF969atqyqkoD6JSqSoWjrggANyxd3WW2+dVlpppVyZ99prr+Wq06jGizn4qlebRpVTt27dcqVqVPeFqOqLUYV33313Gjt2bF5XvUIwnituUIrzPMT8eksttVSeQ3Lq1Knp448/zlWncZ7G3JOvvPJKnjvyiiuuyJV6TZo0qarei9/xYY011kibb755+vTTT6vmq1x99dVrnO/A/xFL0dCJpagEYikoHbEUDZ1YikoglqonSp1lpG7NWG1055135mqOf/zjH4W999676v6777670KZNm8LVV1+dl6+66qrCggsuWNhzzz1z1UfMZbbooosW7r//fj9C6qXHH3+8sMIKK+SqpJhv7J577imccMIJuXKpU6dOVb3+t9122zzv2EsvvVT12Khyisqn888/v2rdjTfeWFhmmWUK//nPf0ryeqA2f//73wsLLbRQYe211y4MGzasav3XX39dOP300wtfffVV1e/65ZZbrtC0adPC8ssvX7Xdv//978JSSy1VOOuss/JyzLFq3j34cWIpKoVYikogloK6J5aiUoilqARiqfpBkq8B+7H2gXHhd4sttigsvPDC+cJvtCY8/PDDq+6PNm99+vQptG/fvioZcs011xS22mqrnCCJNodxcRjqq4MPPrjwu9/9Lifsqrv++usL8803X+HQQw/Ny8OHDy+0a9eucNxxxxWmTJmS10WSI1ob/vWvf63x2MUXX7xw0UUX5e+rt66FUojkdQy26N69e633x7n//fff59bKyy67bOHiiy8uPPnkk4V55523cMEFF1Sd63/4wx8Km266aY1J7rWfhZ/+LIilaOjEUjR0YimY+8RSVDKxFA2dWKr+kORr4EFUzEH23HPP5Qu9YfLkyYWDDjqocPnllxeOOuqovPz0008Xdtxxx8JKK61UYz9PPfVUXnfsscfm5eIF4A8//LBOXw/8XO+8806hUaNGhfvuu2+mOfOiwumPf/xjoUmTJlXnciQ5mjdvnpMlkQhZa621CiuvvHLh/fffr9rnG2+8kSuebrrpJj8Q6lwxqVw9ETdhwoT8+3zrrbcuvPbaa1VJh/3337/Qt2/fvByDMTp37pwDrxBzrUZisHXr1oXPPvusqnoPqEksRaUTS9HQiKWgbomlqHRiKRoasVT9ZhKpBtwLt1+/fmmdddbJ8zC98MILee6wZs2a5fnI+vTpkxZbbLG8vN5666VTTjklz0122WWXVe1nzTXXTAcddFC64IIL0gcffJDnMAvLLLNMyV4bzI6YU6x58+Z53rEQc+4VPxcx7+S2226b55O88cYb87qYp2/JJZdMI0eOzHOZ7bbbbumNN95Iyy67bNU+hw8fng4++OC09957+yFQp04//fT8OzsUfw/HHHnzzjtvPldjftTrr78+nX/++Wn55ZfP53DMRRmef/759P7776fNNtssL3/44Ydpyy23TIsuumj617/+ldfF9+GHH37wk4X/TyxFpRNL0ZCIpaDuiaWodGIpGhKxVP33v1fAaVCeffbZtP/+++eLweedd15aYIEF0uqrr54THWHgwIE5sRcXiIvi/iOOOCIn+/bbb78033zzpZYtW+ZkyJdffpm3jSRhcR9Qny200EI58TFq1Kg8mXcxMVI8hyP5HUmSOMfDIossknr37p0fc/LJJ+cEYTHpEf85idu+++5b9R8VqAuTJk3KSeUYpHHttdfWuK94Lnbt2jUNHTo0/fWvf81J7TvvvDNtvvnmVfdvuOGGeT/77LNPHqBxyy23pL59++akYPH8LyomxQGxFIilaAjEUlA6rktR6cRSNARiqfLRKMr5Sn0QzFl/+MMf0oQJE9I111xTlayobZuHH344PfXUU1VVHFHFtPXWW6eNNtooXzCG+ur/txquNelWTORtvPHGOZF36623zlR9GlWrK664YrrwwgtzdV5t+wiS2pR65F9U6h144IF58EUMuIiEdFGc3/EZeP3119PRRx+dq1QHDRqU7ysmtyNRHev+9re/pc8//zwdc8wxaffdd8/bOM9h1sRSNHRiKSqBWApKRyxFQyeWohKIpcqHspQGJtq03Xbbbalnz55VCb6oTvrss8/S2LFj08SJE6vKbOOC8eWXX1712Pbt26cjjzwyV4J8/fXXJXsN8GOKSbxIbtTWXrCYmItkRiSxI9kdyY3q7rjjjrTGGmtUJTuqi8RJ7EOCj1KL3+Fxvr/44otpl112SXvttVf66KOPqu4vJrlXXXXVXHUd91133XV5XfH8jeq8PffcMyf6nnvuuapz3nkOsyaWoqETS1EpxFJQGmIpGjqxFJVCLFVGSj0pIHPeqquuWujVq1fhzTffLFx11VWFnXbaqbDZZpsVmjdvXthxxx0LgwcPzttdcMEFhYUWWqjw1ltvVT124sSJhe+//96PhXrnhx9+qLF82223Fbp161b46KOPZvmYY445ptCkSZPCFltsUbjjjjsKw4YNK+y///6FBRdcsDBw4MAaE8dCfTJ16tT8NX53zzvvvIUVVlih8Pbbb89yQvvRo0fn3/vbb7994eOPP65x3499joDaiaVoiMRSVBKxFJSWWIqGSCxFJRFLlRftOhugRx55JB1yyCHpiy++yPPx7bzzzrlKb+GFF0433nhj7qf7n//8JzVt2jQtvfTSqVOnTunee+9VuURZuPnmm9Mrr7ySz+PLLrsszy0WlUqzmk/s6quvzvNQRhVrnPPt2rXLj4t2nVCfW31EC+WYPzV6+a+//vrpnHPOSW3btp1pftTiclRhn3XWWal79+55W+CXE0vRkImlaIjEUlC/iKVoyMRSNERiqfImyddAffLJJ7kd5+qrr56TG/PNN19eH3OQxXx7d911V1pllVXSsGHD0rfffpt22GGHUh8y/KiYY+yII47IbQf79euX59W755578n3xdaWVVqqxfXG+svD999/n5Wjb2aFDh6r9xf3aclJqxfnzwvjx41OzZs3yciSlw4MPPpjbz8b5f+ihh870+GKSL1ozRyvmrl27pi222KLOXwc0NGIpGhqxFA2VWArqJ7EUDY1YioZKLFX+JPkqRPEi8HHHHZdGjBiRHn744RoVI1Bf/7gUz99IWkfy4uCDD86TeIdRo0blZHXMJXnyySenli1b/qL9Q30QibxI6EW1aSStr7zyyqr7oiI7BmycffbZaa211pqpmq96UhuYO8RSlBOxFJVILAX1m1iKciKWohKJpcqXK4Jl/gdndnz33XdpzJgx6cQTT8xVUPvuu2++GBwBFtQnxXOymICbOnVq/hrJjHHjxuU2nZtuumnVfdGG9pRTTklXXHFFeumll2b7eST4qE9efvnltPbaa6cnn3wynXHGGTmRHa03I3H99ddf522OP/749OGHH6YHHnggt6qNz0T13+HVE3x+t8PsE0vR0IilqERiKSgdsRQNjViKSiSWKn+SfGX6B2fGMtragqu4EHzaaaelAw44ICdG/vWvf6Xbb7897b333vl+bQqpb32fi+fk3XffnecVi3N3+PDhacqUKWmJJZZIK6+8crrhhhvyNsVtYz6+aFN400035Wo/qK/iHI+Ku+L3xa/vvvtu2n777dPjjz+edt1117TOOuvkqtRorfzMM8/kx8TcfNtss02uwo42yz/2O9zvdpi9z6NYioZELEUlEEtB/SGWoqERS1EJxFINlyRfGYoLuJHg+/jjj9O2226b9t9//1qrk5o0aZI22GCDtMwyy6Rzzz03vfjii6lLly4lOmr4PzGf3iGHHFJVfRfndNwiYR3JumgrG/NJvvrqq3kOsvvuuy+1atUq9erVK8+/98477+TzO0R132KLLZZuvPHGPPIE6qNIJsQ5HhV3MUdkUaxbbbXV0u9///uczI6vkeTr3bt3WnLJJdMFF1yQPv3006pqvvfffz8n+SKxDfxyYinKnViKSiOWgvpFLEW5E0tRacRSDVyBeuWHH36Yre0GDBhQmH/++Qu9evUqvPPOO3P9uGBOeuSRRwr9+/cvTJo0qWrd7bffXthmm20K3bt3Lzz44IN53bhx4wo9evQo7LDDDoVRo0YVPvjgg8Lmm29e6NixY+G+++4rjBgxorDTTjsV7r///sJGG21U2GuvvfLjpk2b5gdGvXTKKacU1llnncL//M//FPr27VvjvjPOOKOw4YYbFp555pm8fNNNNxVatmxZuPHGGwsTJ07M6/7zn/8Upk6dWpJjh3IhlqISiKWoVGIpmPvEUlQCsRSVSizVMKnkq2flssVqvOI8TMX7ZhStC2Nupmi/ucIKK9TpscIv8cgjj1S1iu3atWs64YQTUvPmzdNHH32U13Xo0CF/P2LEiLTWWmvldQsssEDab7/98pyS0aYztolKv1gfk8FusskmeW6+2F+nTp1yVV9UQ1Wfnwzqg6+++iqfp9GKtm/fvqlHjx7prrvuSgcddFD+ff/NN9/kOVO7deuWOnfunB8Tn4U4v0866aT8+LDRRhvlKtZi20/g/4ilaOjEUlQysRTMfWIpGjqxFJVMLNWwuRJeTxTbuD311FM5cbHTTjulLbbYIj333HNVc+0V+0OH3XbbLW8H5SJab8acY3fccUde/vbbb9ORRx6ZkxwTJkxI66+/fk4CzjvvvOmxxx6relzPnj3T2muvnYYOHZrXL7XUUumf//xn/j7afUYrzxYtWqTnn38+7bLLLqlZs2YlfJVUohkHYtQ2MCN+l//www/5vN1jjz3S1ltvnX/nx/poU7vgggvm5F18Tt544408h2okvSNxffPNN+fWndVJZMPMxFI0dGIpGiqxFNQPYikaOrEUDZVYCkm+EooLvqGYxIsKpUhorLfeennupRVXXDHPt3frrbfWmLcMyknx/N51113Tpptumi655JI0adKkNP/88+fERST4IokRDjjggLT00kunhx56qGoesnDggQemiRMnpquvvjp/buabb760yCKL5GqmqIaKz0zMc7bDDjuU7HVSueL3csyRF4no4vKMIiEd5/zCCy+cq1NXWWWVnOiLhHXMmxris/Hoo4+m7bbbLg/kiMT3yiuvnDbffPM6f01QLsRSVAKxFA2dWApKRyxFJRBL0dCJpZDkK4Fim7Wo2gjRpi1E5UZUNV1wwQVpm222yW04Y5RJ3B8t26DcRpBUb0EbFXiR1Ih1AwYMyOsi2bHccsule+65J73//vtp8cUXz1VOL7/8cq7QK4r2hd27d09bbrll1ecmPhODBw9OZ5xxRm5h+MILL6SOHTuW5PVS2eI/xkcffXQ66qij0ptvvpnXzdhOMxJ87777bv4aE3xHQvDKK6/MrZfj+88++ywnwZ955pl0/fXX5+UY7AHUTixFQyeWopKIpaDuiaVo6MRSVBKxFPFLjzo0ffr0qu9ffPHFQqNGjQp/+MMfChMmTCgst9xyhTFjxhT+9a9/Fdq3b19YffXVC/fdd5+fD2Xj3nvvrXX9wIEDC+utt15ht912KyyyyCKF3/zmN4UPP/ww33fHHXcUNthgg8Kf/vSnqu133nnnQo8ePQojRoyo9bNT/D4+L998881cfEUwex544IHC5ptvXjj22GNrrC+eq0888URhjTXWKOy666417v/qq6/y+f6Xv/xlpn1OnTq1xnkP1PxcBbEUDY1YikolloK6I5aiIRNLUanEUpVNJV8d98WN8tlPPvkknXnmmblS6bzzzkt//vOfU8uWLdNiiy2WW7NFi84jjjgiPfvss7n94Lhx43KlR3yF+jyBcVQzffjhhzXWR7vZ0047LbfijPN6n332ydWp/fv3z/fvuOOOuVIv5ir773//m9f17t07jRgxIs+zV1RsgRifp+L3UfnXunXrOnyVULtosbnuuuvmc3jIkCFVo2OL5+qGG26Y51l97bXX0sknn5yeeOKJ3KozqlOjam/jjTeeaZ9RtapFM/wvsRSVQCxFJRNLwdwllqISiKWoZGKpClfqLGMluvjiiwuLLrpoYemlly688847ed2UKVMK5557bmHxxRcvPP744zW2/9vf/lbYfffdC5988kmJjhh+2vjx42utOtpvv/0KW265ZY11p5xySmGllVYqPProo3k5zvmtt9660Lt376ptnnzySW87ZeWFF14odOvWrbD33nvnKrwwbdq0fAujR48uXHXVVYW2bdsWOnfuXFhqqaUKJ5xwQomPGsqTWIqGSCxFpRNLQd0RS9EQiaWodGKpyqWSr4789a9/TTfffHP+PuYW22qrrdK3336b590LTZs2TZtttllaZZVV8rxO//jHP3Il35FHHpn69u2b1lxzzdSmTZu6OlyYbVdccUWaMmVKnmssqo4GDhyYq1PDd999l78uu+yyNR7To0eP1KpVq3TppZfm5ahiivn0Yi6+l156Ka/r0qVLrXObQX3VqVOnPO/k22+/nStYQ3wmGjf+3z+18fV3v/tdrua+/fbb85yrxYrW4kTgwKyJpWioxFLwv8RSMHeJpWioxFLwv8RSFazUWcaG6Icffqix/P333+cKpebNm1etu/POOwvLLrts4Zxzzqmx7XvvvVfo2rVrYdVVVy2sttpqhd/+9reF5557rs6OHX6OkSNHFuaZZ55C3759q0ZN/fGPfyy0bNmy8Nlnn+V1MefkuuuuW3jrrbdqPHaTTTYpzDvvvIWrr746L0elasyxB+UszuOYd2+77bbLlXsh5o288MILCx06dChccsklM/29MO8ezEwsRaUQS0FNYimYM8RSVAqxFNQklqpMkny/QrEFW1H1C7Vjx46tcd9rr71WWGaZZQpHH310Xo6Lv0ceeWRhzTXXLIwaNaqqZWeYPHlyYcKECYU33njj1xwezDEzJiGK536sv+KKKwotWrQofPDBB3ndyy+/XFhvvfVyi9niH5fWrVsXTj311JzsKH4+tt9++8IGG2yQEyLVEx0zfq6g3Nxyyy353O7fv39h6NChhdVXX72wwAILFC677LJSHxrUO2IpKoVYCmafWApmn1iKSiGWgtknlqo8knxz4I/M22+/XWPdq6++WphvvvkKgwYNqloXCbwBAwYUGjdunEeZhIcffriw4YYbFo444ogaj5fkoD6aNGlS1Rx61RNyX331VWHTTTct7LDDDlVJ6muvvbYw//zzV80vGRWrkeiI6r3rr78+z1vWq1ev/FmBhvhZ+f3vf19o1qxZoVGjRoXDDjusxv1+x0NNYikqhVgKZv+zIpaC2SeWolKIpWD2PytiqcrSKP4pdcvQcvX111+nPfbYI883duWVV6YLLrggz7m09957p6OPPjrPLxa3oo8//jjttNNOabHFFksPPvhg+v7779Mll1ySLrroojwHX8xLBvXRDz/8kI444oj03//+Nw0aNCitvPLKaerUqXkuydC7d+904403pqFDh6ZNN900ffjhh3k+ydGjR6enn346b/PQQw+lq666Ko0cOTLPRRnzAcw333xV85HNM888JX2NMCc9+uij6eGHH05/+MMf0tJLL131OWrSpIk3GqoRS1EpxFLw84ilYPaIpagUYin4ecRSlaVxqQ+gnC200EKpa9eu6fHHH88Xcc8+++z8NZJ4Bx10UA62zj333Lxt5FKXWmqptOeee6Z//etf6cknn0wtW7bMCZF99tkntW3bttQvB2YpEhPbbbddWmSRRXJyLkSC74EHHkgrrbRSeuaZZ9Laa6+dExqhQ4cO6eCDD87JvhtuuCGv69atW05m//vf/0633357TvBNnz493yfBR0OzxRZbpHPOOSf/TYgkdvwNkOCDmYmlqBRiKfh5xFIwe8RSVAqxFPw8YqnKIsn3C0aOVPfVV1+lt956K7Vu3To9++yzaZdddsnrI+Gx3377pQsvvDCNGzcuNWrUKK//9ttv89cePXrkr126dMkVgCuuuOKc+HnCXBNJvnXXXTc999xzuWovluMcjyq+SPLddNNNuUrvsssuy9uvt956qWfPnumQQw6pSubF52DBBRfMCY9YF5Wv0JDFeR5J7OLfAEAsReUSS8HPJ5aCmbkuRaUSS8HPJ5aqDK6wz6ZikqJYiRFJji+//DLtu+++ueVmVOX985//rNp+/vnnT7169UpLLrlkToSMHTs2ffLJJ+n9999P119/fTrmmGNq7BfKQbSnjc/A/vvvnxZddNH06quvphNPPDHNO++8uaIvWnSeccYZacKECbmiNRKAl156aU7mVe8MHAkPCT4qgfMc/o9YCsRSIJaCX04sBWIpEEtRG3Py/UxRrXTSSSflBMfvf//7dOihh+b1kdCLxEYkODp37lwVgD3xxBOpe/fuuX3he++9l3bcccd0zTXXVM1FBuUmktrRgjMS1dF+tnpFXlTyrbnmmmnnnXdO1157bakPFYB6SCxFpRNLAfBriKWodGIpgJok+X6GqN479dRT03HHHZcrmSKpF8m+EPPyHX300Wn77bdPp5xySo25l15//fX02muvpTZt2qRNNtnk5zwl1DuffvppOuqoo9LEiRPz/Hwxn2TMOVacV+/BBx/M64rJ7hBVfNoVAiCWArEUAL+cWArEUgAzkuSbRX/z6km6op122iktvvjiaeDAgen7779PU6ZMyVVMMR9fVDJFZdPw4cNzdV8k80444YR08cUX5+QeNCS33nprnnsv5tyLpHdtJPYAKpdYCn6cWAoAsRT8cmIpgP9jTr5aFBN8//73v9Pbb7+dvv7667wc8+sNHjw4XXDBBemAAw5Iu+++e1p22WXTLrvskrfp27dvat++ferXr19uWTh+/Pi0yCKL1PYUUNaiHWec4zfffHN68cUXa91G5R5A5RJLwY8TSwEgloJfTiwF8H9U8tXi/vvvT4cffnhaYIEF0uTJk9NSSy2V/vGPf6RJkyblar133nknbbvttrlV5xprrJE222yz9Le//S397ne/S1999VVOeiyzzDJp+eWXr2330CA88sgj6b///W9uUxvVrABQJJYCsRQAv5xYCsRSALOr4pJ81ecOq+37mD9vjz32SLvttltutxnzj2299da55ebQoUPzdjO28lx77bXzHGX77LNPSV4TAEBdEUsBAIilAID6YeaJ5xqo4vxgkciLiryLLrooTZgwITVt2jSdfvrpVcm+aD/Yrl279Kc//SlNnDgxnXvuuWnkyJFpm222yVV9LVq0yPPwffjhh/n+448/Pu835uCDShSfh5iTEoCGTSwFc4dYCqAyiKVg7hBLAZWuYq7MF+cHu/TSS3MS7+mnn05t27ZN3333XZoyZUoelR7mn3/+9Jvf/CYNHDgwt9x87bXXcgXfxRdfnBN8xTaFp5xyStpyyy3TvPPOm+fu69ChQ0lfH5SKBB9AZRBLwdwhlgKoDGIpmDvEUkClq5hKvh9++CGdfPLJ6a677kqXX355bskZyb1mzZrl+6Mqr1WrVun7779PN954Y072XXnllWnHHXfMVX6xbVT/de/ePW200Ua5CvCkk05Kq622WqlfGgDAXCeWAgAQSwEA9UvFVPLFXHt///vf03HHHZd23333vC4SfB988EHadttt0wEHHJDX9e7dOy244IKpZ8+eaZdddqlq4/nwww+nwYMHp3feeSdX7+28884SfABAxRBLAQCIpQCA+qViknwPPfRQrtbbddddq1ok3HbbbWn55ZfPc/Tdcccd6e67707LLbdcOvjgg9Njjz2W1lprrfTnP/85V/NF5V/MyxeJPwCASiOWAgAQSwEA9UujQsz8WwEOPfTQPJfeu+++m9tNNWnSJD377LN5Lr7f/va3ab/99svLL7zwQu7l/PLLL6dLLrkkT4wcy5HsW3LJJUv9MgAASkIsBQAglgIA6peKSfINHDgwHXbYYemll15Kq6++ek7eFSv6wpdffpkWW2yxdM455+SWnkVTp05NTZs2LdFRAwDUD2IpAACxFABQvzSYdp0/latceeWVU/v27dOJJ56Yl6dPn17jcdHKc+21157pcRJ8AEAlEEsBAIilAIDyUvZJvmi3GapX5dV2oWqjjTZKu+++e/rnP/+ZR6LPM888Vfd99tln6eSTT04LLrhg2mmnneroyAEASk8sBQAglgIAylNZt+us3nLzgQceSN98801aeuml0yabbFJju6jai3n13nvvvXT++eenq6++OnXp0iWtscYaeR+33357WmedddL111+fHw8AUAnEUgAAYikAoHyVRZJvxvnzqnv//ffTnnvumT766KPUsWPH9Pjjj6c//vGPaf/9908dOnSo9bE33XRTevDBB3M13w8//JC33Wabbero1QAA1C2xFACAWAoAaHjKIslXvRpvRoceemj6/PPP0y233JKaN2+eBg0alPbZZ5/05z//OR1zzDE/eoErEnxNmjSpk+MHACglsRQAgFgKAGhYGpfDBan7778/7bHHHlXrhg4dmr788sv06aefpieffDKdffbZOcHXv3//1KdPn7T11lunnj17zrSvGSv6JPgAgIZOLAUAIJYCABqmepnkGz58eOrevXv+Pqr3Ro8enV544YVcmde6detcpdesWbPUokWL9Nlnn6WHHnoorb766unmm29OV111VU4KrrDCCmncuHH5whYAQCURSwEAiKUAgIavXib5xo8fn7bbbruq5bXXXjuNGTMm/eUvf0knn3xy+ve//53mn3/+PKfepptumo488sh00EEHpREjRqSddtopP+bRRx/NCb8JEyaU8JUAANQ9sRQAgFgKAGj46tWEdMU587p165ZvU6dOzS01J06cmCv7Xn/99aqWm1GhF1V9W265ZW7Z2a5du1zZF95+++108cUXpwUXXDBNmzatxK8KAKBuiKUAAMRSAEDlaFzfLkoVffHFF6lLly7psMMOSxtvvHH661//mrbddtt0ww03pPfeey+38Qwx994+++yT9t5777Thhhum3/3ud6lTp0650u+yyy5LCy20UAlfFQBA3RBLAQCIpQCAytKoEFeESiiePqryovVmddFm85JLLkkDBgxITz31VFp++eXT0KFD02mnnZZWXHHFnPSLxxWTfXfffXd6//338xx9u+22W1pvvfVK9IoAAOqOWAoAQCwFAFSmkib5qo84//jjj9PNN9+cOnbsmDbaaKO0wAILpLfeeisdeOCBuRrvvvvuy+07I+kX1XzxdauttkqvvvpqThCussoqpXoZAAAlIZYCABBLAQCVq07bdQ4aNCh99913VcvFBN+NN96YVltttXTbbbel/fffP+288855Lr2o2Dv00EPTY489lgYPHpyaNm2a5+ZbddVV83a9evVKa665Zp6DL5S4KBEAYK4SSwEAiKUAAOq0ki+ScJ9++mnq27dvTtjFfHnhX//6V3rooYdSy5Yt02abbZa23HLL9Pzzz6euXbum448/Pp188slp7Nix6Ygjjkivv/56evnll/PjPvjgg9yuc/z48emYY45JyyyzzNx+CQAAJSOWAgAQSwEA1GmSLxJzu+yyS5o0aVJ69913q+bPiyq9aLF57733ph133DFX7D366KNpySWXzPdfeOGF6cwzz0xPPvlkrtobMmRI2m+//XKy79hjj51bhwsAUK+IpQAAxFIAACVp13n++eenDh06pPfffz8n+CKf2Lt37/S3v/0tJ/p69OiR9tprrzR9+vRczVf0xz/+MbVp0yadc845+b71118/bbvttum6667LjwMAqARiKQAAsRQAQJ0n+b7++us0YcKE1K5du7x87bXXph9++CGvP++889LIkSPz+pNOOil/f9ddd+XlYmHhgAED0q233ppbes4333zptNNOS6+88kquAAQAaOjEUgAAYikAgJIk+RZaaKG07rrrpqeffjq1atUqJ/liDr0bb7wxV/bddtttuY3nyiuvnA4//PCcxPvss89So0aN8uO7d++e1ltvvfSf//wnLy+xxBKpSZMmc+twAQDqFbEUAIBYCgCgzubki9aa0ZZzypQpueKuU6dO6Z133slfH3nkkTT//PPn7c4666xcqRfr1lprrTRu3Li0yiqr5Hn3zj777FzNF8m+77//vkYbTwCAhkwsBQAglgIAqNNKvuI8eZHgi4tTzZo1y0m+448/Pp155pn5+6jcKzr55JNTixYt0mWXXZYTfK1bt86VfDEH32uvvVZVzSfBBwBUArEUAIBYCgBgrlbyFSvsZhxtXnThhRfmefM6d+6c9tlnn5y8+/bbb3OFXszHF/evsMIKedu77747/e53v0v33ntv2mqrrfJ+Y66+I488MjVv3vxnvxAAgPpOLAUAIJYCAChJJV/1BF9+8P9P8MVceocccki64oorctVe375906mnnppGjRqVW3TuscceacyYMTWq+Xbcccc8H98JJ5yQvv7667zuuOOOk+ADABossRQAgFgKAKAkSb5vvvkmnXjiiemhhx7KyxMnTszLxxxzTJ6H76mnnkrXXnttuuqqq9Lw4cPTLbfckrfbZZddUseOHdNjjz2W1xfdeeedORm48MILz7EXBABQX4mlAADEUgAAJUnyffjhh2nIkCE5eRftN1u1apXn1IvWm1OnTk2LLbZY3q53795p9dVXT48++mhVUi/WTZ48OV155ZX5sSFad/bo0WOOvRgAgPpMLAUAIJYCAChJkq9Tp055Hr2333473XTTTXndn/70p7z+yy+/TF988UVVK6qYhy8q/f7xj3/k+Wd++9vfpg022CC36PwZ0wACADQYYikAALEUAEBJknxht912S0svvXS666670ieffJKWXHLJ1KtXrzR27Nh0//33V2238cYbp8022yxX8w0aNCivO+uss9JJJ52UmjZtOsdeAABAORFLAQCIpQAASpLka9euXerZs2eu3LvhhhvyukMOOSS1adMmPfDAA7nKr2ivvfZKK664YurQoUNeltwDACqdWAoAQCwFAFCSJF/YaaedUseOHdMjjzySnn/++dS8efN04IEHplGjRuUKv6JozRlVfNGqEwAAsRQAwK/luhQAwK9I8rVo0SK36AzXX399/rrjjjumZZZZJt1zzz3prbfe+iW7BQCoCGIpAACxFADAr9WoUCgUfumD+/Xrl4YOHZqOPvroPIrq9ddfT1OmTEmdOnX61QcGANDQiaUAAMRSAAB1WslXtPvuu6epU6emBx98ME2bNi2tuuqqEnwAAGIpAIC5znUpAKDS/apKvvDf//43rbfeeqlp06Zz7qgAACqEWAoAQCwFAFCSJB8AAAAAAABQRu06AQAAAAAAgLonyQcAAAAAAABlRpIPAAAAAAAAyowkHwAAAAAAAJQZST4AAAAAAAAoM5J8AAAAAAAAUGYk+QAAAAAAAKDMSPIBAAAAAABAmZHkAwAAAAAAgDIjyQcAAAAAAABlRpIPAAAAAAAAyowkHwAAAAAAAKTy8v8A4ad/hKq7kxsAAAAASUVORK5CYII=", "text/plain": [ - "
" + "
" ] }, "metadata": {}, @@ -433,8 +433,8 @@ "source": [ "df_full = pd.DataFrame(results)\n", "\n", - "features_to_plot = [\"mean_energy\", \"mean_sparc\", \"pct_sudden\", \"mean_contraction\"]\n", - "feature_labels = [\"Mean Energy\", \"Mean SPARC\", \"% Sudden frames\", \"Mean Contraction\"]\n", + "features_to_plot = [\"mean_energy\", \"pct_sudden\", \"mean_sphericity\"]\n", + "feature_labels = [\"Mean Energy\", \"% Sudden frames\", \"Mean Contraction\"]\n", "\n", "fig, axes = plt.subplots(1, len(features_to_plot), figsize=(18, 5))\n", "\n", @@ -584,7 +584,7 @@ ], "metadata": { "kernelspec": { - "display_name": "pwb", + "display_name": "wrksp", "language": "python", "name": "python3" }, @@ -598,7 +598,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.11" + "version": "3.13.13" } }, "nbformat": 4, diff --git a/examples/requirements.txt b/examples/requirements.txt index 6b6e718..f3eb1d9 100644 --- a/examples/requirements.txt +++ b/examples/requirements.txt @@ -1,2 +1,5 @@ ipywidgets -tqdm \ No newline at end of file +tqdm +matplotlib +opencv-python +pandas \ No newline at end of file diff --git a/pyeyesweb/low_level/direction_change.py b/pyeyesweb/low_level/direction_change.py index 2ee47f1..24874e7 100644 --- a/pyeyesweb/low_level/direction_change.py +++ b/pyeyesweb/low_level/direction_change.py @@ -125,14 +125,15 @@ def _polygon_area(self, pos: np.ndarray) -> float: # Close the loop closed_polygon = np.vstack([subset, subset[0]]) + # NumPy 2 only supports 3D cross products: lift 2D points to z=0 + if closed_polygon.shape[1] == 2: + closed_polygon = np.pad(closed_polygon, ((0, 0), (0, 1))) + # Shoelace-style cross product area computation cross_products = np.cross(closed_polygon[:-1], closed_polygon[1:]) area_vector = np.sum(cross_products, axis=0) / 2.0 - # Handle both 2D (scalar return) and 3D (vector return) area magnitudes - area = np.linalg.norm(area_vector) if np.ndim(area_vector) > 0 else np.abs(area_vector) - - return float(area) + return float(np.linalg.norm(area_vector)) def compute(self, window_data: np.ndarray) -> DirectionChangeResult: """Compute the Direction Change over a temporal window. diff --git a/pyeyesweb/low_level/smoothness.py b/pyeyesweb/low_level/smoothness.py index 58616f0..42d5c3a 100644 --- a/pyeyesweb/low_level/smoothness.py +++ b/pyeyesweb/low_level/smoothness.py @@ -126,8 +126,8 @@ def compute(self, window_data: np.ndarray) -> SmoothnessResult: return SmoothnessResult(is_valid=False) # Zero-velocity check - if np.mean(speed_profile) < self.min_speed_threshold or np.max(speed_profile) < (self.min_speed_threshold * 1.5): - return SmoothnessResult(is_valid=False) + # if np.mean(speed_profile) < self.min_speed_threshold or np.max(speed_profile) < (self.min_speed_threshold * 1.5): + # return SmoothnessResult(is_valid=False) filtered_speed = self._filter_signal(speed_profile) diff --git a/pyproject.toml b/pyproject.toml index fbdecdc..fa9f509 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,6 +83,7 @@ Documentation = "https://infomuscp.github.io/PyEyesWeb/" [tool.setuptools] [tool.setuptools.packages.find] where = ["."] +include = ["pyeyesweb*"] [tool.pytest.ini_options] pythonpath = [ From 1cdb85268d12e3d224447816508580e4e365a6e2 Mon Sep 17 00:00:00 2001 From: Nicorb <67009524+nicola-corbellini@users.noreply.github.com> Date: Thu, 24 Sep 2026 11:52:30 +0200 Subject: [PATCH 3/3] ci: add GitHub Actions workflow to deploy MkDocs to GitHub Pages --- .github/workflows/gh-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 98f8bd9..d535c71 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -27,7 +27,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install .[dev] mike + pip install .[dev] "mike<2.2" # 4. Deploy MkDocs site with mike - name: Deploy with mike 🚀