diff --git a/Python/OAK/datasets/oak-fcc-3/_0_capture.py b/Python/OAK/datasets/oak-fcc-3/_0_capture.py new file mode 100644 index 000000000..9a26f8748 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/_0_capture.py @@ -0,0 +1,477 @@ +import os +import time +import json +import argparse +from datetime import datetime + +import cv2 +import numpy as np + +from core.oak_fcc3_client import OakFcc3Client as MultiSpectralClient + +with open("config.json", "r", encoding="utf-8") as f: + config = json.load(f) + +RAW_SIZE = config.get("raw_size") # [W, H] +MODULE_PARAMS = config.get("module_params_json") + + +# ========================= +# Helpers gerais +# ========================= + +def ts_name() -> str: + return datetime.now().strftime("%Y%m%d_%H%M%S_%f")[:-3] + + +def overlay_hud( + img_bgr: np.ndarray, + lines: list[str], + base_h: int = 720, + base_font_scale: float = 0.75, + base_line_step: int = 28, +): + h, w = img_bgr.shape[:2] + + scale = h / float(base_h) + scale = max(scale, 0.4) + + font_scale = base_font_scale * scale + line_step = int(base_line_step * scale) + + thick_outline = max(1, int(3 * scale)) + thick_text = max(1, int(2 * scale)) + + y = int(24 * scale) + x = int(12 * scale) + + for s in lines: + cv2.putText(img_bgr, s, (x, y), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (0, 0, 0), thick_outline, cv2.LINE_AA) + cv2.putText(img_bgr, s, (x, y), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (255, 255, 255), thick_text, cv2.LINE_AA) + y += line_step + + +def save_sample( + base_dir: str, + frame_type: str, + preview_bgr: np.ndarray, + meta: dict, + raw_payload: np.ndarray | None = None, + packed_raw: np.ndarray | None = None, + packed_raw_by_camera: dict | None = None, +): + os.makedirs(base_dir, exist_ok=True) + name = ts_name() + + png_path = os.path.join(base_dir, f"{name}.png") + json_path = os.path.join(base_dir, f"{name}.json") + + if frame_type in ("RGB", "MULTISPEC"): + if raw_payload is None: + raise ValueError(f"raw_payload não pode ser None quando frame_type='{frame_type}'") + + payload_path = os.path.join(base_dir, f"{name}.raw") + raw_payload.astype(np.float32).tofile(payload_path) + + meta["saved_payload_type"] = frame_type.lower() + meta["saved_payload_path"] = os.path.basename(payload_path) + meta["saved_payload_dtype"] = "float32" + meta["saved_payload_shape"] = list(raw_payload.shape) + + elif frame_type == "RAW_BRUTO": + if packed_raw_by_camera is not None: + payload_files = {} + payload_shapes = {} + payload_dtypes = {} + + for cam_id, arr in packed_raw_by_camera.items(): + path = os.path.join(base_dir, f"{name}_{cam_id}.bin") + arr.tofile(path) + payload_files[cam_id] = os.path.basename(path) + payload_shapes[cam_id] = list(arr.shape) + payload_dtypes[cam_id] = str(arr.dtype) + + meta["saved_payload_type"] = "raw_native_multi" + meta["saved_payload_paths"] = payload_files + meta["saved_payload_shapes"] = payload_shapes + meta["saved_payload_dtypes"] = payload_dtypes + + else: + if packed_raw is None: + raise ValueError("packed_raw não pode ser None quando frame_type='RAW_BRUTO'") + + payload_path = os.path.join(base_dir, f"{name}.bin") + packed_raw.tofile(payload_path) + + meta["saved_payload_type"] = "raw_native_single" + meta["saved_payload_path"] = os.path.basename(payload_path) + meta["saved_payload_dtype"] = str(packed_raw.dtype) + meta["saved_payload_shape"] = list(packed_raw.shape) + + else: + raise ValueError(f"frame_type não suportado para save: {frame_type}") + + cv2.imwrite(png_path, preview_bgr) + + with open(json_path, "w", encoding="utf-8") as f: + json.dump(meta, f, ensure_ascii=False, indent=2) + + return png_path, json_path + + +def get_camera_map_from_status(status: dict) -> dict: + result = {} + for cam in status.get("cameras", []): + result[cam.get("id")] = cam + return result + + +# ========================= +# MAIN +# ========================= + +def main(): + parser = argparse.ArgumentParser( + description="Captura de dataset usando módulo multispectral Pi + StreamReceiver.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + + parser.add_argument("--cana", required=True, choices=["baixa", "media", "alta"], help="Estado da cana no momento da coleta.") + parser.add_argument("--horario", required=True, choices=["cedo", "meio_dia", "entardecer", "nublado"], help="Janela de iluminação / horário da coleta.") + parser.add_argument("--out_root", default="dataset", help="Pasta raiz do dataset.") + parser.add_argument("--fps", type=int, default=20, help="FPS desejado.") + parser.add_argument("--width", type=int, default=RAW_SIZE[0], help="Largura óptica da câmera.") + parser.add_argument("--height", type=int, default=RAW_SIZE[1], help="Altura óptica da câmera.") + parser.add_argument("--interval", type=float, default=1.0, help="Intervalo em segundos para auto-save quando ligado.") + parser.add_argument("--preview_upscale", type=int, default=2, help="Fator de upscale visual do preview.") + parser.add_argument("--bayer", default="GBRG", choices=["GBRG", "GRBG", "RGGB", "BGGR"], help="Padrão Bayer das câmeras.") + parser.add_argument("--output_dtype", default="float32", choices=["uint8", "uint16", "float32"], help="Dtype do payload processado no Pi.") + parser.add_argument("--frame_type", default="RAW_BRUTO", choices=["RAW_BRUTO", "RGB", "MULTISPEC"], help="Tipo de payload pedido ao Pi.") + parser.add_argument("--capture_mode", default="AUTO", choices=["AUTO", "SINGLE", "DOUBLE", "TRIPLE"], help="Modo de captura desejado no módulo.") + parser.add_argument("--raw_policy", default="allow_single", choices=["allow_single", "require_triple"], help="Quando frame_type=RAW_BRUTO, define se o script aceita 1 câmera ou exige 3.") + parser.add_argument("--module_calibration_json", default=MODULE_PARAMS, help="JSON salvo pelo calibrador de sensores com parâmetros fixos por câmera.") + parser.add_argument("--radiometric_ae", action="store_true", help="Liga controle automatico de exposicao radiometrico") + + args = parser.parse_args() + + effective_capture_mode = args.capture_mode + + raw_w = args.width + raw_h = args.height + + session_dir = os.path.join( + args.out_root, + "brutas", + f"cana_{args.cana}", + args.horario, + datetime.now().strftime("%Y%m%d"), + ) + os.makedirs(session_dir, exist_ok=True) + + print("============================================") + print("Coleta de dataset - Módulo Multiespectral") + print(f"Cana : {args.cana}") + print(f"Horário : {args.horario}") + print(f"Saída : {session_dir}") + print(f"Sensor : {raw_w}x{raw_h} | Bayer={args.bayer}") + print(f"FrameType : {args.frame_type}") + print(f"CaptureMode : {args.capture_mode} -> efetivo={effective_capture_mode}") + print(f"RAW policy : {args.raw_policy}") + print("============================================") + + auto_save = False + last_auto_t = 0.0 + preview_upscale = args.preview_upscale + + t_view_fps = time.time() + view_frames = 0 + fps_view = 0.0 + + t_stream_fps = time.time() + last_stream_frame_id = None + stream_frames_accum = 0 + fps_stream = 0.0 + + last_msg = "" + last_msg_t = 0.0 + + window_name = "Dataset Capture (C/SPACE=save | A=auto-save | M=preview scale | Q=quit)" + cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) + + last_frame_id = -1 + last_payload_float = None + last_packed_raw = None + last_packed_raw_by_camera = None + last_preview_bgr = None + last_meta_stream = None + + try: + with MultiSpectralClient( + width=raw_w, + height=raw_h, + bayer=args.bayer, + fps=args.fps, + frame_type=args.frame_type, + output_dtype=args.output_dtype, + capture_mode=effective_capture_mode, + raw_policy=args.raw_policy, + #module_calibration_json=args.module_calibration_json, + radiometric_enabled=args.radiometric_ae, + ) as cam: + while True: + t0 = time.time() + frame, meta, decoded = cam.get_next_decoded(timeout=1.0) + if meta is not None and frame is not None and meta.get("frame_id") != last_frame_id: + last_frame_id = meta["frame_id"] + + try: + frame_type = meta.get("frame_type", "RAW_BRUTO") + dtype_str = meta.get("dtype") or meta.get("output_dtype", "uint8") + preview_source_id = "cam2" + + if frame_type == "RAW_BRUTO": + if isinstance(frame, dict): + packed_by_camera = frame + + preview_bgr, raw3_preview, preview_source_id = cam.build_preview_from_raw_payload(frame=frame, meta=meta) + + last_packed_raw = None + last_packed_raw_by_camera = {cam_id: arr.copy() for cam_id, arr in packed_by_camera.items()} + last_payload_float = raw3_preview.copy() + + else: + preview_bgr, raw3_preview, preview_source_id = cam.build_preview_from_raw_payload(frame=frame, meta=meta) + + last_packed_raw = frame.copy() + last_packed_raw_by_camera = None + last_payload_float = raw3_preview.copy() + + elif frame_type == "RGB": + rgb_chw = frame + if not isinstance(rgb_chw, np.ndarray) or rgb_chw.ndim != 3: + raise RuntimeError(f"Frame RGB inválido: type={type(rgb_chw)}") + + if dtype_str == "uint8": + payload_float = rgb_chw.astype(np.float32) / 255.0 + elif dtype_str == "float32": + payload_float = rgb_chw.astype(np.float32) + elif dtype_str == "uint16": + payload_float = rgb_chw.astype(np.float32) / 65535.0 + else: + raise RuntimeError(f"dtype RGB não suportado: {dtype_str}") + + preview_rgb = np.transpose(payload_float, (1, 2, 0)) + preview_bgr = cv2.cvtColor( + np.clip(preview_rgb * 255.0, 0, 255).astype(np.uint8), + cv2.COLOR_RGB2BGR + ) + + last_payload_float = payload_float.copy() + last_packed_raw = None + last_packed_raw_by_camera = None + + elif frame_type == "MULTISPEC": + multispec_chw = frame + if not isinstance(multispec_chw, np.ndarray) or multispec_chw.ndim != 3 or multispec_chw.shape[0] not in (4, 5): + raise RuntimeError(f"Frame MULTISPEC inválido: shape={getattr(multispec_chw, 'shape', None)}") + + if dtype_str == "uint8": + payload_float = multispec_chw.astype(np.float32) / 255.0 + elif dtype_str == "float32": + payload_float = multispec_chw.astype(np.float32) + elif dtype_str == "uint16": + payload_float = multispec_chw.astype(np.float32) / 65535.0 + else: + raise RuntimeError(f"dtype MULTISPEC não suportado: {dtype_str}") + + preview_rgb = np.transpose(payload_float[:3], (1, 2, 0)) + preview_bgr = cv2.cvtColor( + np.clip(preview_rgb * 255.0, 0, 255).astype(np.uint8), + cv2.COLOR_RGB2BGR + ) + + last_payload_float = payload_float.copy() + last_packed_raw = None + last_packed_raw_by_camera = None + + else: + raise RuntimeError(f"frame_type não suportado neste script: {frame_type}") + + if preview_upscale and preview_upscale > 1: + preview_show = cv2.resize( + preview_bgr, + (preview_bgr.shape[1] * preview_upscale, preview_bgr.shape[0] * preview_upscale), + interpolation=cv2.INTER_NEAREST, + ) + else: + preview_show = preview_bgr.copy() + + curr_frame_id = meta.get("frame_id") + + if curr_frame_id is not None: + if last_stream_frame_id != curr_frame_id: + stream_frames_accum += 1 + + last_stream_frame_id = curr_frame_id + + dt_stream = time.time() - t_stream_fps + if dt_stream >= 1.0: + fps_stream = stream_frames_accum / dt_stream + stream_frames_accum = 0 + t_stream_fps = time.time() + + view_frames += 1 + dt_view = time.time() - t_view_fps + if dt_view >= 1.0: + fps_view = view_frames / dt_view + view_frames = 0 + t_view_fps = time.time() + + active_sources = meta.get("payload_sources") + + rad = getattr(cam, "radiometric_controller", None) + if rad and rad.enabled: + st = rad.state + line_rad = ( + f"RAD | " + f"RGB(exp={st['cam2']['exp']}, g={st['cam2']['gain']:.2f}) | " + f"RE(exp={st['cam0']['exp']}, g={st['cam0']['gain']:.2f}) | " + f"NIR(exp={st['cam1']['exp']}, g={st['cam1']['gain']:.2f})" + ) + else: + line_rad = "RAD | OFF" + + lines = [ + f"CANA: {args.cana} | HORA: {args.horario} | Pasta: {os.path.basename(session_dir)}", + f"Type={meta.get('frame_type')} | CaptureMode={effective_capture_mode} | RAW policy={args.raw_policy}", + f"Sources={active_sources} | FPS_STREAM={fps_stream:.1f} | FPS_VIEW={fps_view:.1f}", + f"frame_id={meta.get('frame_id')} | layout={meta.get('output_layout')} | dtype={meta.get('dtype') or meta.get('output_dtype')}", + f"codec={meta.get('codec_name', meta.get('codec_family', '-'))} | comp={meta.get('dt_comp', 0):.4f}s | send={meta.get('dt_send_payload_prev', 0):.4f}s", + f"CAM_PARAMS={os.path.basename(args.module_calibration_json)} | controles fixos aplicados", + line_rad, + "Keys: C/SPACE=save | A=auto-save | M=preview | Q/Esc=quit" + ] + overlay_hud(preview_show, lines, base_h=raw_h) + + if last_msg and (time.time() - last_msg_t) < 2.0: + cv2.putText(preview_show, last_msg, (12, preview_show.shape[0] - 18), + cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2, cv2.LINE_AA) + + cv2.imshow(window_name, preview_show) + + last_preview_bgr = preview_bgr.copy() + last_meta_stream = dict(meta) + + except Exception as e: + err = np.zeros((500, 1200, 3), dtype=np.uint8) + cv2.putText(err, f"Erro ao processar frame: {e}", (20, 60), + cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2, cv2.LINE_AA) + cv2.imshow(window_name, err) + print(f"[ERRO FRAME] {e}") + + now = time.time() + can_save = ( + last_meta_stream is not None and + last_preview_bgr is not None and + ( + (last_meta_stream.get("frame_type") in ("RGB", "MULTISPEC") and last_payload_float is not None) or + (last_meta_stream.get("frame_type") == "RAW_BRUTO" and (last_packed_raw is not None or last_packed_raw_by_camera is not None)) + ) + ) + + if auto_save and can_save and (now - last_auto_t) >= args.interval: + frame_type_save = last_meta_stream.get("frame_type") + + meta_save = { + "ts": datetime.now().isoformat(timespec="milliseconds"), + "cana": args.cana, + "horario": args.horario, + "sensor_width": raw_w, + "sensor_height": raw_h, + "bayer_pattern": args.bayer, + "fps_target": args.fps, + "frame_type": frame_type_save, + "capture_mode_requested": args.capture_mode, + "capture_mode_effective": effective_capture_mode, + "raw_policy": args.raw_policy, + "stream_meta": last_meta_stream, + "applied_camera_controls": cam.applied_camera_controls, + "camera_params_json": args.module_calibration_json, + "note": "autosave", + "raw_preview_reference_camera": preview_source_id, + } + + save_sample( + session_dir, + frame_type=frame_type_save, + preview_bgr=last_preview_bgr, + meta=meta_save, + raw_payload=last_payload_float, + packed_raw=last_packed_raw, + packed_raw_by_camera=last_packed_raw_by_camera, + ) + + last_msg = "SALVO (auto)" + last_msg_t = now + last_auto_t = now + + k = cv2.waitKey(1) & 0xFF + if k in (ord("q"), ord("Q"), 27): + break + + elif k in (ord("a"), ord("A")): + auto_save = not auto_save + last_msg = f"AutoSave -> {'ON' if auto_save else 'OFF'}" + last_msg_t = time.time() + + elif k in (ord("m"), ord("M")): + preview_upscale = 0 if preview_upscale else args.preview_upscale + last_msg = f"Preview UPSCALE -> {preview_upscale}" + last_msg_t = time.time() + + elif k in (ord("c"), ord("C"), 32): + if can_save: + frame_type_save = last_meta_stream.get("frame_type") + meta_save = { + "ts": datetime.now().isoformat(timespec="milliseconds"), + "cana": args.cana, + "horario": args.horario, + "sensor_width": raw_w, + "sensor_height": raw_h, + "bayer_pattern": args.bayer, + "fps_target": args.fps, + "frame_type": frame_type_save, + "capture_mode_requested": args.capture_mode, + "capture_mode_effective": effective_capture_mode, + "raw_policy": args.raw_policy, + "stream_meta": last_meta_stream, + "applied_camera_controls": cam.applied_camera_controls, + "camera_params_json": args.module_calibration_json, + "note": "manual", + "raw_preview_reference_camera": preview_source_id, + } + + save_sample( + session_dir, + frame_type=frame_type_save, + preview_bgr=last_preview_bgr, + meta=meta_save, + raw_payload=last_payload_float, + packed_raw=last_packed_raw, + packed_raw_by_camera=last_packed_raw_by_camera, + ) + + last_msg = "SALVO (manual)" + last_msg_t = time.time() + + dt_loop = time.time() - t0 + if dt_loop < 0.001: + time.sleep(0.001) + + finally: + cv2.destroyAllWindows() + print("Fim da captura.") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/calibration/cam0_raw_preview.png b/Python/OAK/datasets/oak-fcc-3/calibration/cam0_raw_preview.png new file mode 100644 index 000000000..73f48a7f3 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/calibration/cam0_raw_preview.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_A.jpg b/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_A.jpg new file mode 100644 index 000000000..77fd0eaee Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_A.jpg differ diff --git a/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_A_rgb.bin b/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_A_rgb.bin new file mode 100644 index 000000000..9fd18da24 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_A_rgb.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_B_nir.bin b/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_B_nir.bin new file mode 100644 index 000000000..115124743 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_B_nir.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_C_re.bin b/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_C_re.bin new file mode 100644 index 000000000..466d44bee Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/calibration/capture_CAM_C_re.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/calibration/capture_cam2.jpg b/Python/OAK/datasets/oak-fcc-3/calibration/capture_cam2.jpg new file mode 100644 index 000000000..3e7428a76 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/calibration/capture_cam2.jpg differ diff --git a/Python/OAK/datasets/oak-fcc-3/calibration/manual_offsets.json b/Python/OAK/datasets/oak-fcc-3/calibration/manual_offsets.json new file mode 100644 index 000000000..f18715d6b --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/calibration/manual_offsets.json @@ -0,0 +1,34 @@ +{ + "schema": "manual_multispec_offsets_v1", + "saved_at": "2026-05-04 20:50:02", + "pi_host": "192.168.105.6", + "pc_host": "192.168.105.5", + "stream_port": 6001, + "frame_type": "RAW_BRUTO", + "capture_mode_requested": "AUTO", + "capture_mode_effective": "AUTO", + "raw_policy": "allow_single", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "reference_camera": "cam2", + "baseline_mm": 75.0, + "alignment_mode": "manual_affine", + "manual_offsets": { + "cam0": { + "dx": -28, + "dy": 9, + "theta_deg": 0.0 + }, + "cam1": { + "dx": -4, + "dy": 31, + "theta_deg": 0.0 + } + }, + "homographies": { + "cam0_to_cam2": null, + "cam1_to_cam2": null + }, + "notes": "" +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/calibration/module_params.json b/Python/OAK/datasets/oak-fcc-3/calibration/module_params.json new file mode 100644 index 000000000..4ea95cc57 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/calibration/module_params.json @@ -0,0 +1,78 @@ +{ + "schema": "multispec_module_params_v1", + "saved_at": "2026-05-05 08:03:18", + "frame_type": "RAW_BRUTO", + "capture_mode_requested": "AUTO", + "capture_mode_effective": "AUTO", + "raw_policy": "allow_single", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "camera_settings": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null + }, + "cam2": { + "ae_enable": true, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ] + } + }, + "fusion_config": { + "alignment_mode": "manual_affine", + "baseline_mm": 75.0, + "reference_camera": "cam2", + "manual_offsets": { + "cam0": { + "dx": -28, + "dy": 9, + "theta_deg": 0.0 + }, + "cam1": { + "dx": -4, + "dy": 31, + "theta_deg": 0.0 + } + }, + "homographies": { + "cam0_to_cam2": null, + "cam1_to_cam2": null + }, + "crop_valid_common": true, + "resize_after_crop": true, + "target_size": null + }, + "radiometric_config": { + "interval_s": 0.5, + "strip_y0_pct": 0.95, + "strip_y1_pct": 1.0, + "patch_x0_pct": 0.35, + "patch_x1_pct": 0.75, + "target_mean": 0.7, + "deadband": 0.03, + "alpha": 0.18, + "exp_min_us": 100, + "exp_max_us": 80000, + "gain_min": 1.0, + "gain_max": 8.0, + "verbose": true, + "exp_apply_threshold_us": 50, + "gain_apply_threshold": 0.02 + } +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/calibration/sensor_calibration.json b/Python/OAK/datasets/oak-fcc-3/calibration/sensor_calibration.json new file mode 100644 index 000000000..1579e5b97 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/calibration/sensor_calibration.json @@ -0,0 +1,213 @@ +{ + "schema": "multispec_camera_params_v1", + "saved_at": "2026-05-04 19:29:24", + "pi_host": "192.168.105.6", + "pc_host": "192.168.105.5", + "stream_port": 6001, + "frame_type": "RAW_BRUTO", + "capture_mode_requested": "AUTO", + "capture_mode_effective": "AUTO", + "raw_policy": "allow_single", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "camera_settings": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null + }, + "cam2": { + "ae_enable": true, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ] + } + }, + "rois": { + "cam2": [ + { + "name": "mesa", + "type": "polygon", + "points": [ + [ + 429, + 305 + ], + [ + 446, + 195 + ], + [ + 512, + 199 + ], + [ + 512, + 309 + ] + ], + "color": [ + 0, + 255, + 255 + ] + }, + { + "name": "teto", + "type": "polygon", + "points": [ + [ + 148, + 345 + ], + [ + 153, + 269 + ], + [ + 216, + 265 + ], + [ + 221, + 345 + ] + ], + "color": [ + 0, + 255, + 0 + ] + } + ], + "cam0": [ + { + "name": "mesa", + "type": "polygon", + "points": [ + [ + 417, + 235 + ], + [ + 433, + 158 + ], + [ + 485, + 162 + ], + [ + 479, + 237 + ] + ], + "color": [ + 0, + 255, + 255 + ] + }, + { + "name": "tet", + "type": "polygon", + "points": [ + [ + 218, + 306 + ], + [ + 219, + 230 + ], + [ + 274, + 225 + ], + [ + 276, + 305 + ] + ], + "color": [ + 0, + 255, + 0 + ] + } + ], + "cam1": [ + { + "name": "mesa", + "type": "polygon", + "points": [ + [ + 468, + 227 + ], + [ + 480, + 123 + ], + [ + 556, + 137 + ], + [ + 549, + 233 + ] + ], + "color": [ + 0, + 255, + 255 + ] + }, + { + "name": "teto", + "type": "polygon", + "points": [ + [ + 139, + 333 + ], + [ + 157, + 238 + ], + [ + 237, + 258 + ], + [ + 222, + 351 + ] + ], + "color": [ + 0, + 255, + 0 + ] + } + ] + }, + "snapshots": [], + "notes": "", + "calibration_guidance_log": [] +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/config.json b/Python/OAK/datasets/oak-fcc-3/config.json new file mode 100644 index 000000000..7c3a6d69a --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/config.json @@ -0,0 +1,20 @@ +{ + "camera": "oak-fcc-3", + "modelo": "segformer_b1", + "model_name": "pulv_mit", + "dual_head": false, + "main_class_name": "cana", + "es_classes": "", + "model_to_use": "geral", + "raw_size": [640, 480], + "resolucao": [1024, 800], + "roi_inicio": 0.0, + "roi_tamanho": 1.0, + "shaves": 3, + "channels": 4, + "use_ndvi": false, + "backbone": "nvidia/mit-b1", + "fusion_mode": "stacked", + "stats_source_tag": "stacked_raw4", + "module_params_json": "calibration/module_params.json" +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/core/__init__.py b/Python/OAK/datasets/oak-fcc-3/core/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Python/OAK/datasets/oak-fcc-3/core/oak_fcc3_client.py b/Python/OAK/datasets/oak-fcc-3/core/oak_fcc3_client.py new file mode 100644 index 000000000..ef5d6daf6 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/core/oak_fcc3_client.py @@ -0,0 +1,407 @@ +import numpy as np +import cv2 +import json +import os + +from .oak_fcc3_service import OakFcc3Service +from .raw_processor_core import RawProcessorCore +from .raw_processor_preview import RawProcessorPreview +from .radiometric_controller import RadiometricController + + +class OakFcc3Client: + def __init__( + self, + width=640, + height=400, + bayer="GBRG", + fps=30, + frame_type="RAW_BRUTO", + output_dtype="uint8", + capture_mode="AUTO", + raw_policy="allow_single", + module_calibration_json=None, + radiometric_enabled=False, + sync_mode="best", + sync_tolerance_ms=25.0, + **kwargs, + ): + self.width = width + self.height = height + self.bayer = bayer + self.fps = fps + self.frame_type = frame_type + self.output_dtype = output_dtype + self.capture_mode = capture_mode + self.raw_policy = raw_policy + self.module_calibration_json = module_calibration_json + self.module_params = self._load_module_params(module_calibration_json) + self.fusion_config = self.module_params.get("fusion_config", {}) or {} + self.radiometric_enabled = radiometric_enabled + + self.svc = OakFcc3Service( + timeout=10, + fps=fps, + width=width, + height=height, + frame_type=frame_type, + output_dtype=output_dtype, + capture_mode=capture_mode, + raw_policy=raw_policy, + sync_mode=sync_mode, + sync_tolerance_ms=sync_tolerance_ms, + **kwargs, + ) + + self.applied_camera_controls = {} + self.radiometric_controller = None + self.core = RawProcessorCore( + sensor_width=width, + sensor_height=height, + bayer_pattern=bayer, + calibration_json_path=module_calibration_json, + ) + self.preview = RawProcessorPreview( + sensor_width=width, + sensor_height=height, + bayer_pattern=bayer, + ) + + def __enter__(self): + self.start() + return self + + def __exit__(self, exc_type, exc, tb): + self.stop() + + def _load_module_params(self, path): + if not path or not os.path.isfile(path): + return {} + + with open(path, "r", encoding="utf-8") as f: + return json.load(f) + + def apply_module_camera_settings(self): + camera_settings = self.module_params.get("camera_settings", {}) or {} + + applied = {} + + for cam_id, settings in camera_settings.items(): + if not isinstance(settings, dict): + continue + + try: + resp = self.svc.apply_camera_controls(cam_id, settings) + applied[cam_id] = resp + except Exception as e: + applied[cam_id] = { + "ok": False, + "error": str(e), + "requested": settings, + } + + self.applied_camera_controls = applied + return applied + + def enable_radiometric_controller(self): + self.radiometric_controller = RadiometricController( + client=self, + enabled=True, + config_json_path=self.module_calibration_json, + ) + + self.radiometric_controller.sync_from_camera_controls(self.applied_camera_controls) + + return self.radiometric_controller + + def update_radiometry(self, decoded, meta=None): + if self.radiometric_controller is None: + return None + + return self.radiometric_controller.update(decoded, meta) + + def start(self, print_debug=False): + self.svc.connect() + + resp = self.svc.begin( + frame_type=self.frame_type, + output_dtype=self.output_dtype, + capture_mode=self.capture_mode, + ) + + applied = self.apply_module_camera_settings() + + if print_debug: + print("[OAK CLIENT] START:", resp) + print("[OAK CLIENT] APPLIED CAMERA SETTINGS:", applied) + + if self.radiometric_enabled: + self.enable_radiometric_controller() + + return resp + + def stop(self): + try: + self.svc.stop() + finally: + self.svc.disconnect() + + def get_status(self): + return self.svc.get_status() + + def get_next_raw_frame(self, timeout=1.0): + return self.svc.capture_frame(timeout=timeout) + + def get_next_frame(self, timeout=2.0): + frame, meta, _ = self.get_next_decoded( + timeout=timeout, + update_radiometry=False, + ) + return frame, meta + + def get_next_decoded(self, timeout=2.0, update_radiometry=True): + raw_frame, raw_meta = self.get_next_raw_frame(timeout=timeout) + + decoded = self.decode_stream_cameras(raw_frame, raw_meta) + + if update_radiometry: + self.update_radiometry(decoded, raw_meta) + + frame_type = str(raw_meta.get("frame_type", self.frame_type)).upper() + + meta = dict(raw_meta) + + if frame_type == "RAW_BRUTO": + frame = raw_frame + + elif frame_type == "RGB": + frame = self.build_rgb_tensor(decoded) + meta["output_layout"] = "CHW" + meta["channels"] = ["R", "G", "B"] + meta["shape"] = list(frame.shape) + meta["dtype"] = str(frame.dtype) + + elif frame_type == "MULTISPEC": + frame = self.build_multispec_tensor(decoded, meta=raw_meta) + meta["output_layout"] = "CHW" + meta["channels"] = ["R", "G", "B", "RE", "NIR"] + meta["shape"] = list(frame.shape) + meta["dtype"] = str(frame.dtype) + + elif frame_type == "PREVIEW": + frame = raw_frame + + else: + raise RuntimeError(f"frame_type não suportado: {frame_type}") + + return frame, meta, decoded + + def get_next_preview(self, timeout=2.0): + raw_frame, raw_meta = self.get_next_raw_frame(timeout=timeout) + + meta = dict(raw_meta) + + previews = self.build_visual_preview_from_raw(raw_frame, meta) + + return previews, meta + + def build_infer_tensor(self, frame, meta, channels_expected, target_size=None): + return self.core.build_infer_tensor_from_stream( + frame, + meta, + channels_expected=channels_expected, + target_size=target_size, + ) + + def build_infer_tensor_from_decoded(self, decoded, meta, channels_expected, target_size=None): + tensor = self.core.fuse_multispec_cameras(decoded, meta, channels_expected) + return self.core.resize_tensor_chw(tensor, target_size=target_size) + + def decode_stream_cameras(self, frame, meta): + if str(meta.get("frame_type", self.frame_type)).upper() == "PREVIEW": + decoded = {} + + camera_info = meta.get("camera_info", {}) or {} + + for cam_id, img in frame.items(): + info = camera_info.get(cam_id, {}) or {} + role = info.get("role", cam_id) + img01 = self._frame_to_float01(cam_id, img, role) + + decoded[cam_id] = { + "name": role.upper(), + "role": role, + "image": img01, + "meta": { + "cam_id": cam_id, + "role": role, + "socket": info.get("socket"), + "sensor": info.get("sensor"), + "timestamp": (meta.get("timestamps") or {}).get(cam_id), + "shape": list(img.shape), + "dtype": str(img.dtype), + }, + } + + return decoded + + return self.core.decode_stream_cameras(frame, meta) + + def build_rgb_tensor(self, decoded): + cam_id, item = self._find_decoded_by_role(decoded, "rgb") + + rgb01 = item["image"] + + if rgb01.ndim != 3 or rgb01.shape[2] != 3: + raise RuntimeError(f"{cam_id} RGB inválida: shape={rgb01.shape}") + + tensor = np.transpose(rgb01.astype(np.float32), (2, 0, 1)) + return np.ascontiguousarray(tensor.astype(np.float32, copy=False)) + + def build_multispec_tensor(self, decoded, meta=None): + tensor = self.core.fuse_multispec_cameras( + decoded=decoded, + meta=meta, + channels_expected=5, + ) + return np.ascontiguousarray(tensor.astype(np.float32, copy=False)) + + def build_preview_from_raw_payload(self, frame, meta): + """ + Gera preview priorizando a câmera com role='rgb'. + Retorna: + preview_bgr: imagem BGR uint8 para OpenCV + payload_float_preview: tensor CHW float32 [0..1] + preview_source_id: cam_id usado + """ + decoded = self.decode_stream_cameras(frame, meta) + + if not decoded: + raise RuntimeError("Nenhum frame decodificado disponível para preview.") + + try: + cam_id, item = self._find_decoded_by_role(decoded, "rgb") + rgb01 = item["image"] + + if rgb01.ndim != 3 or rgb01.shape[2] != 3: + raise RuntimeError(f"{cam_id} decodificada inválida para preview RGB: shape={rgb01.shape}") + + preview_bgr = self._rgb01_to_bgr(rgb01) + payload_float = np.transpose(rgb01.astype(np.float32), (2, 0, 1)) + + return preview_bgr, np.ascontiguousarray(payload_float), cam_id + + except RuntimeError: + pass + + first_id = list(decoded.keys())[0] + img01 = decoded[first_id]["image"] + + if img01.ndim == 2: + preview_bgr = self._gray01_to_bgr(img01) + payload_float = np.stack([img01, img01, img01], axis=0).astype(np.float32) + + elif img01.ndim == 3 and img01.shape[2] == 3: + preview_bgr = self._rgb01_to_bgr(img01) + payload_float = np.transpose(img01.astype(np.float32), (2, 0, 1)) + + else: + raise RuntimeError(f"Frame decodificado inválido para preview: cam={first_id}, shape={img01.shape}") + + return preview_bgr, np.ascontiguousarray(payload_float), first_id + + def build_visual_preview_from_raw(self, frame, meta): + camera_info = meta.get("camera_info", {}) or {} + previews = {} + + for cam_id, arr in frame.items(): + info = camera_info.get(cam_id, {}) or {} + role = info.get("role", cam_id) + bit_depth = int(info.get("bit_depth", 10)) + + if arr.ndim == 3 and arr.shape[2] == 1: + arr = arr[:, :, 0] + + if bit_depth == 10 and arr.ndim == 2: + raw16 = self.core.unpack_raw10_packed( + arr, + sensor_width=int(info.get("width", self.width)), + sensor_height=int(info.get("height", self.height)), + ) + + if role == "rgb": + previews[cam_id] = self.preview.raw16_to_preview_bgr( + raw16, + bit_depth=bit_depth, + apply_wb=True, + apply_contrast=True, + ) + else: + vis8 = self.preview.raw16_to_vis8( + raw16, + bit_depth=bit_depth, + gamma=2.2, + ) + previews[cam_id] = cv2.cvtColor(vis8, cv2.COLOR_GRAY2BGR) + + else: + decoded = self.decode_stream_cameras({cam_id: arr}, {"camera_info": {cam_id: info}}) + img01 = decoded[cam_id]["image"] + + if img01.ndim == 2: + previews[cam_id] = self._gray01_to_bgr(img01) + else: + previews[cam_id] = self._rgb01_to_bgr(img01) + + return previews + + def _find_decoded_by_role(self, decoded, role): + role = str(role).lower() + + for cam_id, item in decoded.items(): + if str(item.get("role", "")).lower() == role: + return cam_id, item + + raise RuntimeError(f"Nenhuma câmera com role={role} encontrada.") + + def _frame_to_float01(self, cam_id, img, role): + if img is None: + return None + + arr = img + + if arr.dtype == np.uint8: + arr01 = arr.astype(np.float32) / 255.0 + elif arr.dtype == np.uint16: + arr01 = arr.astype(np.float32) / 65535.0 + else: + arr01 = arr.astype(np.float32) + if arr01.max() > 1.5: + arr01 = arr01 / 255.0 + + arr01 = np.clip(arr01, 0.0, 1.0) + + if role == "rgb": + # DepthAI/OpenCV entrega BGR HWC. Calibradores esperam RGB HWC. + if arr01.ndim == 3 and arr01.shape[2] == 3: + arr01 = cv2.cvtColor((arr01 * 255).astype(np.uint8), cv2.COLOR_BGR2RGB).astype(np.float32) / 255.0 + elif arr01.ndim == 2: + arr01 = np.stack([arr01, arr01, arr01], axis=2) + + return arr01 + + # Espectrais devem virar mono HW. + if arr01.ndim == 3: + arr01 = cv2.cvtColor((arr01 * 255).astype(np.uint8), cv2.COLOR_BGR2GRAY).astype(np.float32) / 255.0 + + return arr01 + + @staticmethod + def _rgb01_to_bgr(rgb01): + rgb_u8 = np.clip(rgb01 * 255.0, 0, 255).astype(np.uint8) + return cv2.cvtColor(rgb_u8, cv2.COLOR_RGB2BGR) + + @staticmethod + def _gray01_to_bgr(gray01): + g = np.clip(gray01 * 255.0, 0, 255).astype(np.uint8) + return cv2.cvtColor(g, cv2.COLOR_GRAY2BGR) diff --git a/Python/OAK/datasets/oak-fcc-3/oak_fcc3_manager.py b/Python/OAK/datasets/oak-fcc-3/core/oak_fcc3_manager.py similarity index 50% rename from Python/OAK/datasets/oak-fcc-3/oak_fcc3_manager.py rename to Python/OAK/datasets/oak-fcc-3/core/oak_fcc3_manager.py index c1d7dcf58..b72417480 100644 --- a/Python/OAK/datasets/oak-fcc-3/oak_fcc3_manager.py +++ b/Python/OAK/datasets/oak-fcc-3/core/oak_fcc3_manager.py @@ -31,8 +31,8 @@ class OakFcc3Manager: self.roles = roles or { "CAM_A": "rgb", - "CAM_B": "re", - "CAM_C": "nir", + "CAM_B": "nir", + "CAM_C": "re", } self.sync_mode = sync_mode @@ -47,7 +47,13 @@ class OakFcc3Manager: self.running = False self.frame_id = 0 - self.applied_camera_controls = {} + self.control_queues = {} + self.camera_controls = { + "CAM_A": {"ae_enable": True, "awb_enable": True, "exposure_time_us": 15000, "analogue_gain": 1.0, "colour_gains": [1.0, 1.0]}, + "CAM_B": {"ae_enable": False, "awb_enable": False, "exposure_time_us": 15000, "analogue_gain": 1.0, "colour_gains": None}, + "CAM_C": {"ae_enable": False, "awb_enable": False, "exposure_time_us": 15000, "analogue_gain": 1.0, "colour_gains": None}, + } + self._last_raw_dims = {} def __enter__(self): self.start() @@ -56,6 +62,9 @@ class OakFcc3Manager: def __exit__(self, exc_type, exc, tb): self.stop() + def _is_preview_mode(self): + return str(self.frame_type).upper() == "PREVIEW" + def list_cameras(self): with dai.Device() as dev: result = [] @@ -67,6 +76,10 @@ class OakFcc3Manager: }) return result + def _get_available_cam_ids_ordered(self): + preferred_order = ["CAM_A", "CAM_B", "CAM_C"] # RGB, NIR, RE + return [cam_id for cam_id in preferred_order if cam_id in self.queues] + def start(self): if self.running: return @@ -79,6 +92,7 @@ class OakFcc3Manager: self.queues.clear() self.buffers.clear() self.camera_info.clear() + self._last_raw_dims.clear() for f in features: socket = f.socket @@ -88,17 +102,22 @@ class OakFcc3Manager: print(f"[OAK] Criando câmera {socket_name} sensor={f.sensorName} role={role}") cam = self.pipeline.create(dai.node.Camera).build(socket) + ctrl_q = cam.inputControl.createInputQueue() - out = cam.requestOutput( - self.size, - fps=self.fps - ) + if self._is_preview_mode(): + out = cam.requestOutput( + self.size, + fps=self.fps + ) + else: + out = cam.raw q = out.createOutputQueue() - cam_id = self._socket_to_cam_id(socket_name) + cam_id = socket_name self.queues[cam_id] = q self.buffers[cam_id] = deque(maxlen=self.buffer_size) + self.control_queues[cam_id] = ctrl_q self.camera_info[cam_id] = { "id": cam_id, @@ -133,6 +152,8 @@ class OakFcc3Manager: self.queues.clear() self.buffers.clear() self.camera_info.clear() + self.control_queues.clear() + self._last_raw_dims.clear() self.running = False def get_status(self): @@ -178,40 +199,6 @@ class OakFcc3Manager: f"Tente aumentar para 25 ou 35 ms para diagnóstico." ) - def get_next_decoded(self, timeout=1.0, update_radiometry=True): - frame, meta = self.get_next_frame(timeout=timeout) - - decoded = { - "frames": frame, - "meta": meta, - } - - return frame, meta, decoded - - def build_preview_from_raw_payload(self, frame, meta): - if not isinstance(frame, dict) or not frame: - raise RuntimeError("Payload inválido para preview.") - - rgb_cam_id = None - - for cam_id, info in self.camera_info.items(): - if info.get("role") == "rgb" and cam_id in frame: - rgb_cam_id = cam_id - break - - preview_source_id = rgb_cam_id or list(frame.keys())[0] - preview = frame[preview_source_id] - - if preview.ndim == 2: - import cv2 - preview_bgr = cv2.cvtColor(preview, cv2.COLOR_GRAY2BGR) - else: - preview_bgr = preview.copy() - - preview_float = preview_bgr.astype(np.float32) / 255.0 - - return preview_bgr, preview_float, preview_source_id - def _drain_queues_to_buffers(self): for cam_id, q in self.queues.items(): while q.has(): @@ -222,8 +209,33 @@ class OakFcc3Manager: except Exception: ts = time.time() - frame = msg.getCvFrame() + if self._is_preview_mode(): + frame = msg.getCvFrame() + else: + data = msg.getData() + raw = np.frombuffer(data, dtype=np.uint8).copy() + h = int(msg.getHeight()) + w = int(msg.getWidth()) + stride = int(msg.getStride()) + + expected = h * stride + + if raw.size < expected: + raise RuntimeError( + f"RAW menor que esperado: raw.size={raw.size}, esperado={expected}, " + f"w={w}, h={h}, stride={stride}" + ) + + frame = raw[:expected].reshape((h, stride)) + + self._last_raw_dims[cam_id] = { + "sensor_width": w, + "sensor_height": h, + "stride": stride, + "packed_width": stride, + } + self.buffers[cam_id].append({ "frame": frame, "timestamp": ts, @@ -288,7 +300,7 @@ class OakFcc3Manager: return frames, timestamps, sync_dt_ms, sync_ok def _get_required_cam_ids(self): - available = list(self.queues.keys()) + available = self._get_available_cam_ids_ordered() if self.capture_mode == "SINGLE": return available[:1] @@ -319,6 +331,37 @@ class OakFcc3Manager: for cam_id, arr in frames.items() } + camera_info = {} + for cam_id, info in self.camera_info.items(): + item = dict(info) + arr = frames.get(cam_id) + + if arr is not None: + item["shape"] = list(arr.shape) + item["dtype"] = str(arr.dtype) + + if self._is_preview_mode(): + item["interface"] = "OAK" + item["channels"] = 3 if arr.ndim == 3 else 1 + item["bit_depth"] = 8 if arr.dtype == np.uint8 else 16 + item["height"] = int(arr.shape[0]) + item["width"] = int(arr.shape[1]) + else: + raw_dims = self._last_raw_dims.get(cam_id, {}) + item["interface"] = "OAK_RAW" + item["raw_format"] = "RAW10_PACKED" + item["channels"] = 1 + item["bit_depth"] = 10 + item["height"] = int(raw_dims.get("sensor_height", arr.shape[0])) + item["width"] = int(raw_dims.get("sensor_width", arr.shape[1])) + item["stride"] = int(raw_dims.get("stride", arr.shape[1])) + item["packed_width"] = int(raw_dims.get("packed_width", arr.shape[1])) + item["shape"] = list(arr.shape) + item["dtype"] = str(arr.dtype) + item["packed"] = True + + camera_info[cam_id] = item + return { "frame_id": self.frame_id, "backend": "oak_fcc3", @@ -328,7 +371,7 @@ class OakFcc3Manager: "dtype": self.output_dtype, "output_layout": "dict_by_camera", "payload_sources": payload_sources, - "camera_info": self.camera_info, + "camera_info": camera_info, "timestamps": timestamps, "sync_dt_ms": sync_dt_ms, "sync_ok": sync_ok, @@ -353,11 +396,152 @@ class OakFcc3Manager: if self.raw_policy == "require_triple" and n < 3: raise RuntimeError(f"raw_policy=require_triple exige 3 câmeras, mas detectou {n}.") + def get_camera_controls(self, cam_id): + self._validate_cam_id_known(cam_id) + return dict(self.camera_controls.get(cam_id, {})) + + def set_ae_enable(self, cam_id, enable: bool): + self._validate_cam_id_running(cam_id) + + enable = bool(enable) + ctrl_state = self.camera_controls[cam_id] + ctrl_state["ae_enable"] = enable + + ctrl = dai.CameraControl() + + if enable: + # Em alguns builds v3 esse método existe. + if hasattr(ctrl, "setAutoExposureEnable"): + ctrl.setAutoExposureEnable() + else: + # fallback: deixa AE assumir por região/algoritmo interno quando possível + pass + else: + exp_us = int(ctrl_state.get("exposure_time_us") or 15000) + gain = float(ctrl_state.get("analogue_gain") or 1.0) + ctrl.setManualExposure(exp_us, self._gain_to_iso(gain)) + + self._send_control(cam_id, ctrl) + + return dict(ctrl_state) + + def set_awb_enable(self, cam_id, enable: bool): + self._validate_cam_id_running(cam_id) + + enable = bool(enable) + ctrl_state = self.camera_controls[cam_id] + ctrl_state["awb_enable"] = enable + + ctrl = dai.CameraControl() + + if hasattr(dai.CameraControl, "AutoWhiteBalanceMode"): + if enable: + ctrl.setAutoWhiteBalanceMode(dai.CameraControl.AutoWhiteBalanceMode.AUTO) + else: + ctrl.setAutoWhiteBalanceMode(dai.CameraControl.AutoWhiteBalanceMode.OFF) + + self._send_control(cam_id, ctrl) + + return dict(ctrl_state) + + def set_exposure_time(self, cam_id, exposure_time_us: int): + self._validate_cam_id_running(cam_id) + + ctrl_state = self.camera_controls[cam_id] + exposure_time_us = int(exposure_time_us) + exposure_time_us = max(1, exposure_time_us) + + ctrl_state["exposure_time_us"] = exposure_time_us + ctrl_state["ae_enable"] = False + + gain = float(ctrl_state.get("analogue_gain") or 1.0) + + ctrl = dai.CameraControl() + ctrl.setManualExposure(exposure_time_us, self._gain_to_iso(gain)) + + self._send_control(cam_id, ctrl) + + return dict(ctrl_state) + + def set_analogue_gain(self, cam_id, analogue_gain: float): + self._validate_cam_id_running(cam_id) + + ctrl_state = self.camera_controls[cam_id] + analogue_gain = float(analogue_gain) + analogue_gain = max(1.0, analogue_gain) + + ctrl_state["analogue_gain"] = analogue_gain + ctrl_state["ae_enable"] = False + + exposure_time_us = int(ctrl_state.get("exposure_time_us") or 15000) + + ctrl = dai.CameraControl() + ctrl.setManualExposure(exposure_time_us, self._gain_to_iso(analogue_gain)) + + self._send_control(cam_id, ctrl) + + return dict(ctrl_state) + + def set_colour_gains(self, cam_id, red_gain: float, blue_gain: float): + self._validate_cam_id_running(cam_id) + + ctrl_state = self.camera_controls[cam_id] + ctrl_state["colour_gains"] = [float(red_gain), float(blue_gain)] + ctrl_state["awb_enable"] = False + + ctrl = dai.CameraControl() + + if hasattr(ctrl, "setManualWhiteBalance"): + # Nem sempre esse método usa red/blue diretamente. Fica como placeholder seguro. + pass + + self._send_control(cam_id, ctrl) + + return dict(ctrl_state) + + def apply_camera_controls(self, cam_id, controls: dict): + self._validate_cam_id_running(cam_id) + + result = dict(self.camera_controls.get(cam_id, {})) + + if "ae_enable" in controls: + result = self.set_ae_enable(cam_id, bool(controls["ae_enable"])) + + if "awb_enable" in controls: + result = self.set_awb_enable(cam_id, bool(controls["awb_enable"])) + + if "exposure_time_us" in controls and controls["exposure_time_us"] is not None: + result = self.set_exposure_time(cam_id, int(controls["exposure_time_us"])) + + if "analogue_gain" in controls and controls["analogue_gain"] is not None: + result = self.set_analogue_gain(cam_id, float(controls["analogue_gain"])) + + return result + + def _send_control(self, cam_id, ctrl): + if cam_id not in self.control_queues: + raise RuntimeError(f"Fila de controle não existe para {cam_id}") + + self.control_queues[cam_id].send(ctrl) + + def _validate_cam_id_known(self, cam_id): + if cam_id not in self.camera_controls: + raise ValueError(f"cam_id inválido: {cam_id}") + + def _validate_cam_id_running(self, cam_id): + self._validate_cam_id_known(cam_id) + + if not self.running: + raise RuntimeError("Manager não está rodando.") + + if cam_id not in self.control_queues: + raise RuntimeError(f"Câmera {cam_id} não está ativa no pipeline.") + @staticmethod - def _socket_to_cam_id(socket_name): - mapping = { - "CAM_A": "cam2", # RGB - "CAM_B": "cam0", # RE - "CAM_C": "cam1", # NIR - } - return mapping.get(socket_name, socket_name.lower()) \ No newline at end of file + def _gain_to_iso(gain: float) -> int: + # DepthAI usa ISO no setManualExposure(exposure_us, sensitivity_iso). + # Mantemos analogue_gain estilo Pi e convertemos para ISO aproximado. + gain = max(1.0, float(gain)) + iso = int(round(gain * 100)) + return max(100, min(1600, iso)) + \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/core/oak_fcc3_service.py b/Python/OAK/datasets/oak-fcc-3/core/oak_fcc3_service.py new file mode 100644 index 000000000..119746c52 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/core/oak_fcc3_service.py @@ -0,0 +1,229 @@ +import time +from .oak_fcc3_manager import OakFcc3Manager + + +class OakFcc3Service: + def __init__(self, timeout=10, **kwargs): + self.timeout = timeout + self.manager = OakFcc3Manager(**kwargs) + self.connected = False + + def connect(self): + self.connected = True + return {"ok": True, "backend": "oak_fcc3", "connected": True} + + def disconnect(self): + self.stop() + self.connected = False + return {"ok": True, "connected": False} + + def ping(self): + return { + "ok": True, + "backend": "oak_fcc3", + "msg": "pong", + "ts": time.time(), + } + + def get_status(self): + status = self.manager.get_status() + active_ids = [c["id"] for c in status.get("cameras", [])] + active_roles = { + c.get("role"): c.get("id") + for c in status.get("cameras", []) + } + + status.update({ + "ok": True, + "connected": self.connected, + "active_camera_ids": active_ids, + "active_roles": active_roles, + "camera_count_active": len(active_ids), + }) + + return status + + def get_config(self): + return { + "ok": True, + "fps": self.manager.fps, + "width": self.manager.width, + "height": self.manager.height, + "frame_type": self.manager.frame_type, + "output_dtype": self.manager.output_dtype, + "capture_mode": self.manager.capture_mode, + "raw_policy": self.manager.raw_policy, + "sync_mode": getattr(self.manager, "sync_mode", "best"), + "sync_tolerance_ms": self.manager.sync_tolerance_ms, + } + + def set_fps(self, fps): + self._ensure_stopped_for_config() + self.manager.fps = int(fps) + return {"ok": True, "fps": self.manager.fps} + + def set_resolution(self, width, height): + self._ensure_stopped_for_config() + self.manager.width = int(width) + self.manager.height = int(height) + self.manager.size = (self.manager.width, self.manager.height) + return { + "ok": True, + "width": self.manager.width, + "height": self.manager.height, + } + + def set_capture_mode(self, mode): + self._ensure_stopped_for_config() + mode = str(mode).upper() + self.manager.capture_mode = self._validate_capture_mode(mode) + return {"ok": True, "capture_mode": self.manager.capture_mode} + + def set_frame_type(self, frame_type): + self._ensure_stopped_for_config() + frame_type = str(frame_type).upper() + self.manager.frame_type = self._validate_frame_type(frame_type) + return {"ok": True, "frame_type": self.manager.frame_type} + + def set_output_dtype(self, dtype): + self._ensure_stopped_for_config() + dtype = str(dtype).lower() + self.manager.output_dtype = self._validate_output_dtype(dtype) + return {"ok": True, "output_dtype": self.manager.output_dtype} + + def begin(self, frame_type=None, output_dtype=None, capture_mode=None): + if not self.connected: + self.connect() + + if self.manager.running: + return { + "ok": True, + "started": True, + "already_running": True, + "status": self.get_status(), + } + + if frame_type is not None: + self.manager.frame_type = self._validate_frame_type(frame_type) + + if output_dtype is not None: + self.manager.output_dtype = self._validate_output_dtype(output_dtype) + + if capture_mode is not None: + self.manager.capture_mode = self._validate_capture_mode(capture_mode) + + self.manager.start() + + return { + "ok": True, + "started": True, + "already_running": False, + "status": self.get_status(), + } + + def capture_frame(self, timeout=None): + if timeout is None: + timeout = self.timeout + + frame, meta = self.manager.get_next_frame(timeout=timeout) + + return frame, meta + + def stop(self): + self.manager.stop() + return {"ok": True, "stopped": True} + + def _ensure_stopped_for_config(self): + if self.manager.running: + raise RuntimeError( + "Configuração estrutural só pode ser alterada com o manager parado. " + "Chame stop() antes." + ) + + def resolve_camera_id(self, cam_id=None, role=None): + if role is not None: + role = str(role).lower() + + status = self.manager.get_status() + for cam in status.get("cameras", []): + if str(cam.get("role", "")).lower() == role: + return cam["id"] + + raise ValueError(f"Nenhuma câmera ativa encontrada para role={role}") + + if cam_id is None: + raise ValueError("Informe cam_id ou role.") + + return str(cam_id) + + + def get_camera_controls(self, cam_id=None, role=None): + cam_id = self.resolve_camera_id(cam_id=cam_id, role=role) + ctrl = self.manager.get_camera_controls(cam_id) + ctrl["ok"] = True + ctrl["camera_id"] = cam_id + ctrl["role"] = role + return ctrl + + def set_ae_enable(self, cam_id=None, role=None, enable=False): + cam_id = self.resolve_camera_id(cam_id=cam_id, role=role) + ctrl = self.manager.set_ae_enable(cam_id, bool(enable)) + ctrl["ok"] = True + ctrl["camera_id"] = cam_id + ctrl["role"] = role + return ctrl + + def set_awb_enable(self, cam_id=None, role=None, enable=False): + cam_id = self.resolve_camera_id(cam_id=cam_id, role=role) + ctrl = self.manager.set_awb_enable(cam_id, bool(enable)) + ctrl["ok"] = True + ctrl["camera_id"] = cam_id + ctrl["role"] = role + return ctrl + + def set_exposure_time(self, cam_id=None, role=None, exposure_time_us=None): + if exposure_time_us is None: + raise ValueError("exposure_time_us é obrigatório.") + cam_id = self.resolve_camera_id(cam_id=cam_id, role=role) + ctrl = self.manager.set_exposure_time(cam_id, int(exposure_time_us)) + ctrl["ok"] = True + ctrl["camera_id"] = cam_id + ctrl["role"] = role + return ctrl + + def set_analogue_gain(self, cam_id=None, role=None, analogue_gain=None): + if analogue_gain is None: + raise ValueError("analogue_gain é obrigatório.") + cam_id = self.resolve_camera_id(cam_id=cam_id, role=role) + ctrl = self.manager.set_analogue_gain(cam_id, float(analogue_gain)) + ctrl["ok"] = True + ctrl["camera_id"] = cam_id + ctrl["role"] = role + return ctrl + + def apply_camera_controls(self, cam_id=None, role=None, controls=None): + cam_id = self.resolve_camera_id(cam_id=cam_id, role=role) + ctrl = self.manager.apply_camera_controls(cam_id, controls or {}) + ctrl["ok"] = True + ctrl["camera_id"] = cam_id + ctrl["role"] = role + return ctrl + + + def _validate_frame_type(self, frame_type): + frame_type = str(frame_type).upper() + if frame_type not in ("RAW_BRUTO", "RGB", "MULTISPEC", "PREVIEW"): + raise ValueError(f"frame_type inválido: {frame_type}") + return frame_type + + def _validate_output_dtype(self, dtype): + dtype = str(dtype).lower() + if dtype not in ("uint8", "uint16", "float32"): + raise ValueError(f"output_dtype inválido: {dtype}") + return dtype + + def _validate_capture_mode(self, mode): + mode = str(mode).upper() + if mode not in ("AUTO", "SINGLE", "DOUBLE", "TRIPLE"): + raise ValueError(f"capture_mode inválido: {mode}") + return mode diff --git a/Python/OAK/datasets/oak-fcc-3/core/radiometric_controller.py b/Python/OAK/datasets/oak-fcc-3/core/radiometric_controller.py new file mode 100644 index 000000000..8e70c59df --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/core/radiometric_controller.py @@ -0,0 +1,314 @@ +import time +import json +import numpy as np + + +class RadiometricController: + def __init__( + self, + client, + enabled=True, + config_json_path=None, + interval_s=0.5, + strip_y0_pct=0.95, + strip_y1_pct=1.0, + patch_x0_pct=0.35, + patch_x1_pct=0.75, + target_mean=0.70, + deadband=0.03, + alpha=0.20, + exp_min_us=100, + exp_max_us=80000, + gain_min=1.0, + gain_max=8.0, + exp_step_gain=0.65, + prefer_exposure=True, + verbose=False, + ): + self.client = client + + cfg = self._load_config_json(config_json_path) + + interval_s = cfg.get("interval_s", interval_s) + strip_y0_pct = cfg.get("strip_y0_pct", strip_y0_pct) + strip_y1_pct = cfg.get("strip_y1_pct", strip_y1_pct) + patch_x0_pct = cfg.get("patch_x0_pct", patch_x0_pct) + patch_x1_pct = cfg.get("patch_x1_pct", patch_x1_pct) + target_mean = cfg.get("target_mean", target_mean) + deadband = cfg.get("deadband", deadband) + alpha = cfg.get("alpha", alpha) + exp_min_us = cfg.get("exp_min_us", exp_min_us) + exp_max_us = cfg.get("exp_max_us", exp_max_us) + gain_min = cfg.get("gain_min", gain_min) + gain_max = cfg.get("gain_max", gain_max) + exp_step_gain = cfg.get("exp_step_gain", exp_step_gain) + prefer_exposure = cfg.get("prefer_exposure", prefer_exposure) + verbose = cfg.get("verbose", verbose) + exp_apply_threshold_us = cfg.get("exp_apply_threshold_us", 50) + gain_apply_threshold = cfg.get("gain_apply_threshold", 0.02) + + self.enabled = bool(enabled) + self.interval_s = float(interval_s) + + self.strip_y0_pct = float(strip_y0_pct) + self.strip_y1_pct = float(strip_y1_pct) + self.patch_x0_pct = float(patch_x0_pct) + self.patch_x1_pct = float(patch_x1_pct) + + self.target_mean = float(target_mean) + self.deadband = float(deadband) + self.alpha = float(alpha) + + self.exp_min_us = int(exp_min_us) + self.exp_max_us = int(exp_max_us) + self.gain_min = float(gain_min) + self.gain_max = float(gain_max) + + self.exp_step_gain = float(exp_step_gain) + self.prefer_exposure = bool(prefer_exposure) + self.verbose = bool(verbose) + + self.exp_apply_threshold_us = int(exp_apply_threshold_us) + self.gain_apply_threshold = float(gain_apply_threshold) + + self.last_update_ts = 0.0 + self.last_result = {} + + self.state = { + "rgb": {"exp": 15000, "gain": 1.0}, + "nir": {"exp": 15000, "gain": 1.0}, + "re": {"exp": 15000, "gain": 1.0}, + } + self._ae_disabled = set() + self._last_applied = { + "rgb": {"exp": None, "gain": None}, + "nir": {"exp": None, "gain": None}, + "re": {"exp": None, "gain": None}, + } + + def _load_config_json(self, path): + if not path: + return {} + + try: + with open(path, "r", encoding="utf-8") as f: + data = json.load(f) + except Exception: + return {} + + cfg = data.get("radiometric_config", {}) + return cfg if isinstance(cfg, dict) else {} + + def sync_from_camera_controls(self, camera_controls: dict | None): + if not isinstance(camera_controls, dict): + return + + for role, ctrl in camera_controls.items(): + if role not in self.state: + continue + + exp = ctrl.get("exposure_time_us") + gain = ctrl.get("analogue_gain") + + if exp is not None: + self.state[role]["exp"] = int(exp) + + if gain is not None: + self.state[role]["gain"] = float(gain) + + def update(self, decoded: dict, meta: dict | None = None): + if not self.enabled: + return None + + now = time.perf_counter() + if now - self.last_update_ts < self.interval_s: + return None + + self.last_update_ts = now + + results = {} + + for role in ("rgb", "nir", "re"): + cam_id = self._resolve_cam_id(decoded, role) + if cam_id is None: + continue + + img = decoded[cam_id].get("image") + if img is None: + continue + + metrics = self.measure_reference_patch(img) + decision = self.compute_control(role, metrics) + apply_resp = self.apply_control(role, decision) + + results[role] = { + "cam_id": cam_id, + "metrics": metrics, + "decision": decision, + "apply": apply_resp, + } + + self.last_result = results + return results + + def _resolve_cam_id(self, decoded, role): + role = str(role).lower() + + for cam_id, data in decoded.items(): + if str(data.get("role", "")).lower() == role: + return cam_id + + return None + + def measure_reference_patch(self, img01: np.ndarray) -> dict: + if img01.ndim == 3: + # RGB: usa luminância simples + img_gray = ( + 0.299 * img01[:, :, 0] + + 0.587 * img01[:, :, 1] + + 0.114 * img01[:, :, 2] + ).astype(np.float32) + else: + img_gray = img01.astype(np.float32) + + h, w = img_gray.shape[:2] + + y0 = int(h * self.strip_y0_pct) + y1 = int(h * self.strip_y1_pct) + x0 = int(w * self.patch_x0_pct) + x1 = int(w * self.patch_x1_pct) + + y0 = max(0, min(h - 1, y0)) + y1 = max(y0 + 1, min(h, y1)) + x0 = max(0, min(w - 1, x0)) + x1 = max(x0 + 1, min(w, x1)) + + patch = img_gray[y0:y1, x0:x1] + arr = patch.reshape(-1) + + return { + "valid": arr.size > 0, + "mean": float(arr.mean()) if arr.size else 0.0, + "p05": float(np.percentile(arr, 5)) if arr.size else 0.0, + "p95": float(np.percentile(arr, 95)) if arr.size else 0.0, + "sat_pct": float((arr >= 0.98).mean() * 100.0) if arr.size else 0.0, + "dark_pct": float((arr <= 0.02).mean() * 100.0) if arr.size else 0.0, + "roi": [x0, y0, x1, y1], + } + + def compute_control(self, role: str, metrics: dict) -> dict: + st = self.state.setdefault(role, {"exp": 15000, "gain": 1.0}) + + old_exp = int(st["exp"]) + old_gain = float(st["gain"]) + + if not metrics.get("valid"): + return { + "action": "hold", + "reason": "patch inválido", + "old_exp": old_exp, + "new_exp": old_exp, + "old_gain": old_gain, + "new_gain": old_gain, + } + + mean = float(metrics["mean"]) + p95 = float(metrics["p95"]) + sat_pct = float(metrics["sat_pct"]) + error = self.target_mean - mean + + new_exp = old_exp + new_gain = old_gain + action = "hold" + reason = "dentro da faixa morta" + + # Proteção contra saturação + if sat_pct > 1.0 or p95 > 0.96: + desired_exp = max(self.exp_min_us, int(old_exp * 0.85)) + new_exp = self._smooth_int(old_exp, desired_exp) + action = "decrease_exposure" + reason = f"saturação detectada: sat={sat_pct:.2f}% p95={p95:.3f}" + + elif abs(error) > self.deadband: + factor = 1.0 + self.exp_step_gain * error + factor = max(0.70, min(1.35, factor)) + + if self.prefer_exposure: + desired_exp = int(old_exp * factor) + desired_exp = self._clamp(desired_exp, self.exp_min_us, self.exp_max_us) + new_exp = self._smooth_int(old_exp, desired_exp) + + # Se exposição bateu limite e ainda precisa clarear/escurecer, mexe no ganho + if desired_exp in (self.exp_min_us, self.exp_max_us): + desired_gain = old_gain * factor + desired_gain = self._clamp(desired_gain, self.gain_min, self.gain_max) + new_gain = self._smooth_float(old_gain, desired_gain) + + action = "increase_exposure" if error > 0 else "decrease_exposure" + reason = f"corrigindo erro radiométrico: error={error:.3f}" + else: + desired_gain = old_gain * factor + desired_gain = self._clamp(desired_gain, self.gain_min, self.gain_max) + new_gain = self._smooth_float(old_gain, desired_gain) + action = "increase_gain" if error > 0 else "decrease_gain" + reason = f"corrigindo ganho: error={error:.3f}" + + new_exp = int(self._clamp(new_exp, self.exp_min_us, self.exp_max_us)) + new_gain = float(self._clamp(new_gain, self.gain_min, self.gain_max)) + + return { + "action": action, + "reason": reason, + "mean": mean, + "target_mean": self.target_mean, + "error": error, + "old_exp": old_exp, + "new_exp": new_exp, + "old_gain": old_gain, + "new_gain": new_gain, + } + + def apply_control(self, role: str, decision: dict): + new_exp = int(decision["new_exp"]) + new_gain = float(decision["new_gain"]) + + self.state[role]["exp"] = new_exp + self.state[role]["gain"] = new_gain + + responses = {} + last = self._last_applied.setdefault(role, {"exp": None, "gain": None}) + + try: + if role not in self._ae_disabled: + responses["ae"] = self.client.svc.set_ae_enable(role=role, enable=False) + + if role == "rgb": + responses["awb"] = self.client.svc.set_awb_enable(role=role, enable=False) + + self._ae_disabled.add(role) + + if last["exp"] is None or abs(new_exp - last["exp"]) >= self.exp_apply_threshold_us: + responses["exposure"] = self.client.svc.set_exposure_time(role=role, exposure_time_us=new_exp) + last["exp"] = new_exp + + if last["gain"] is None or abs(new_gain - last["gain"]) >= self.gain_apply_threshold: + responses["gain"] = self.client.svc.set_analogue_gain(role=role, analogue_gain=new_gain) + last["gain"] = new_gain + + except Exception as e: + responses["error"] = str(e) + + if self.verbose: + print(f"[RAD] {role}: {json.dumps(decision, ensure_ascii=False)} | apply={responses}") + + return responses + + def _smooth_int(self, old, desired): + return int(round((1.0 - self.alpha) * old + self.alpha * desired)) + + def _smooth_float(self, old, desired): + return float((1.0 - self.alpha) * old + self.alpha * desired) + + @staticmethod + def _clamp(v, lo, hi): + return max(lo, min(hi, v)) \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/core/raw_processor_core.py b/Python/OAK/datasets/oak-fcc-3/core/raw_processor_core.py new file mode 100644 index 000000000..c1abfdb73 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/core/raw_processor_core.py @@ -0,0 +1,877 @@ +import json +import os +import cv2 +import numpy as np +import math +from typing import Optional + + +class RawProcessorCore: + def __init__(self, sensor_width: int, sensor_height: int, bayer_pattern: str = "GBRG", calibration_json_path=None): + self.sensor_width = sensor_width + self.sensor_height = sensor_height + self.bayer_pattern = bayer_pattern.upper() + self.fusion_config = { + "alignment_mode": "manual_affine", + "baseline_mm": 75.0, + "manual_offsets": { + "nir": {"dx": 0, "dy": 0, "theta_deg": 0.0}, + "re": {"dx": 0, "dy": 0, "theta_deg": 0.0}, + }, + "homographies": { + "nir_to_rgb": None, + "re_to_rgb": None, + }, + "crop_valid_common": True, + "resize_after_crop": True, + "target_size": None, + } + if calibration_json_path: + self.load_fusion_config_json(calibration_json_path) + + def unpack_raw10_packed( + self, + packed_frame: np.ndarray, + sensor_width: Optional[int] = None, + sensor_height: Optional[int] = None + ): + if packed_frame.ndim == 3 and packed_frame.shape[2] == 1: + packed_frame = packed_frame[:, :, 0] + + width = sensor_width if sensor_width is not None else self.sensor_width + height = sensor_height if sensor_height is not None else self.sensor_height + + if width % 4 != 0: + raise ValueError(f"Largura {width} não é múltipla de 4 para RAW10 packed") + + expected_packed_width = math.ceil(width * 10 / 8) + + actual_h, actual_w = packed_frame.shape[:2] + padding = actual_w - expected_packed_width + + if actual_h != height: + raise ValueError( + f"[ERRO FRAME] Altura packed inesperada: {packed_frame.shape}, " + f"esperado altura={height}" + ) + + if actual_w < expected_packed_width: + raise ValueError( + f"[ERRO FRAME] Largura packed menor que a útil esperada: {packed_frame.shape}, " + f"esperado pelo menos ({height}, {expected_packed_width})" + ) + + if padding > 64: + raise ValueError( + f"[ERRO FRAME] Padding excessivo no packed: {packed_frame.shape}, " + f"esperado útil ({height}, {expected_packed_width}), padding={padding}" + ) + + packed_frame = packed_frame[:, :expected_packed_width] + groups = packed_frame.reshape(height, width // 4, 5).astype(np.uint16) + + b0 = groups[:, :, 0] + b1 = groups[:, :, 1] + b2 = groups[:, :, 2] + b3 = groups[:, :, 3] + b4 = groups[:, :, 4] + + p0 = (b0 << 2) | ((b4 >> 0) & 0x03) + p1 = (b1 << 2) | ((b4 >> 2) & 0x03) + p2 = (b2 << 2) | ((b4 >> 4) & 0x03) + p3 = (b3 << 2) | ((b4 >> 6) & 0x03) + + raw16 = np.empty((height, width), dtype=np.uint16) + raw16[:, 0::4] = p0 + raw16[:, 1::4] = p1 + raw16[:, 2::4] = p2 + raw16[:, 3::4] = p3 + + return raw16 + + def extract_bayer_channels(self, raw16: np.ndarray) -> dict: + p = self.bayer_pattern + + if p == "GBRG": + g1 = raw16[0::2, 0::2] + b = raw16[0::2, 1::2] + r = raw16[1::2, 0::2] + g2 = raw16[1::2, 1::2] + elif p == "GRBG": + g1 = raw16[0::2, 0::2] + r = raw16[0::2, 1::2] + b = raw16[1::2, 0::2] + g2 = raw16[1::2, 1::2] + elif p == "RGGB": + r = raw16[0::2, 0::2] + g1 = raw16[0::2, 1::2] + g2 = raw16[1::2, 0::2] + b = raw16[1::2, 1::2] + elif p == "BGGR": + b = raw16[0::2, 0::2] + g1 = raw16[0::2, 1::2] + g2 = raw16[1::2, 0::2] + r = raw16[1::2, 1::2] + else: + raise ValueError(f"Padrão Bayer não suportado: {p}") + + return {"R": r, "G1": g1, "G2": g2, "B": b} + + def build_training_rgb( + self, + raw16: np.ndarray, + output_dtype: str = "float32", + bit_depth: int = 10, + ) -> np.ndarray: + ch = self.extract_bayer_channels(raw16) + + max_val = float((1 << bit_depth) - 1) + + r = ch["R"].astype(np.float32) / max_val + g = ((ch["G1"].astype(np.float32) + ch["G2"].astype(np.float32)) * 0.5) / max_val + b = ch["B"].astype(np.float32) / max_val + + chw = np.stack([r, g, b], axis=0).astype(np.float32) + chw = np.clip(chw, 0.0, 1.0) + + if output_dtype == "float32": + return chw + + if output_dtype == "uint8": + return (chw * 255.0).clip(0, 255).astype(np.uint8) + + if output_dtype == "uint16": + return (chw * 65535.0).clip(0, 65535).astype(np.uint16) + + raise ValueError(f"output_dtype não suportado: {output_dtype}") + + def _channel_names_from_decoded(self, decoded): + names = ["R", "G", "B"] + + roles = { + data.get("role") or data.get("meta", {}).get("role"): cam_id + for cam_id, data in decoded.items() + } + + if "re" in roles: + names.append("RE") + if "nir" in roles: + names.append("NIR") + + return names + + def _find_cam_by_role(self, decoded, role): + role = str(role).lower() + + for cam_id, data in decoded.items(): + data_role = ( + data.get("role") or + data.get("meta", {}).get("role") or + "" + ) + if str(data_role).lower() == role: + return cam_id + + return None + + def decode_bins_cameras(self, bins_data, bins_meta): + decoded = {} + + for data, meta in zip(bins_data, bins_meta): + role = (meta.get("role") or "").strip().lower() + bit_depth = int(meta.get("bit_depth", 10)) + max_val = float((1 << bit_depth) - 1) + + cam_id = meta.get("cam_id") or meta.get("camera_id") or meta.get("id") or role + + if role == "rgb": + decoded[cam_id] = { + "name": "RGB", + "image": data.astype(np.float32) / max_val, + "meta": meta, + } + + elif role == "re": + decoded[cam_id] = { + "name": "RE", + "image": data.astype(np.float32) / max_val, + "meta": meta, + } + + elif role == "nir": + decoded[cam_id] = { + "name": "NIR", + "image": data.astype(np.float32) / max_val, + "meta": meta, + } + decoded[cam_id]["role"] = role + + return decoded + + def build_multispectral_tensor(self, bins_data, bins_meta, target_size=None): + decoded = self.decode_bins_cameras(bins_data, bins_meta) + + rgb_cam_id = self._find_cam_by_role(decoded, "rgb") + if rgb_cam_id is None: + raise RuntimeError("RGB obrigatório") + + channel_names = self._channel_names_from_decoded(decoded) + + tensor = self.fuse_multispec_cameras( + decoded, + meta=None, + channels_expected=len(channel_names) + ) + + tensor = self.resize_tensor_chw(tensor, target_size=target_size) + + return tensor, channel_names + + def build_infer_tensor_from_stream_old(self, frame, meta, channels_expected): + """ + Converte o frame vindo do stream do Pi em tensor (C,H,W) float32 0..1 + compatível com o modelo. + Suporta: + - RGB uint8/float32 já pronto + - MULTISPEC uint8/float32 já pronto + - RAW_BRUTO multi_payload (cam2 RGB + cam0/cam1 packed) + """ + frame_type = meta.get("frame_type") + dtype_str = meta.get("dtype") or meta.get("output_dtype", "uint8") + camera_frames = meta.get("camera_frames", {}) or {} + + # ------------------------------------------------- + # RAW_BRUTO multi_payload + # ------------------------------------------------- + if frame_type == "RAW_BRUTO": + if not isinstance(frame, dict): + raise RuntimeError("RAW_BRUTO esperado como dict de câmeras no modo multi") + + arrays = [] + channel_names = [] + + # RGB USB + if "cam2" in frame: + rgb_bgr = frame["cam2"] + if rgb_bgr.ndim != 3 or rgb_bgr.shape[2] != 3: + raise RuntimeError(f"cam2 RGB inválida: shape={rgb_bgr.shape}") + + rgb = rgb_bgr[:, :, ::-1].astype(np.float32) / 255.0 + rgb_chw = np.transpose(rgb, (2, 0, 1)) + arrays.append(rgb_chw) + channel_names.extend(["R", "G", "B"]) + else: + raise RuntimeError("RAW_BRUTO para inferência precisa incluir cam2 (RGB)") + + # RE / NIR + for cam_id, spec_name in (("cam0", "RE"), ("cam1", "NIR")): + if cam_id not in frame: + continue + + packed = frame[cam_id] + if packed.ndim == 3 and packed.shape[2] == 1: + packed = packed[:, :, 0] + + cam_meta = camera_frames.get(cam_id, {}) + packed_width = int(cam_meta.get("width", packed.shape[1])) + height = int(cam_meta.get("height", packed.shape[0])) + bayer = cam_meta.get("bayer_pattern", self.bayer_pattern) + bit_depth = int(cam_meta.get("bit_depth", 10)) + + if bit_depth == 10: + real_width = int((packed_width * 8) / 10) + else: + real_width = packed_width + + rp = RawProcessorCore( + sensor_width=real_width, + sensor_height=height, + bayer_pattern=bayer, + ) + + raw16 = rp.unpack_raw10_packed(packed) + + max_val = float((1 << bit_depth) - 1) + single = np.clip(raw16.astype(np.float32) / max_val, 0.0, 1.0)[None, :, :] + + arrays.append(single) + channel_names.append(spec_name) + + if len(arrays) < 2: + raise RuntimeError("RAW_BRUTO requer RGB + pelo menos um canal espectral para inferência") + + min_h = min(a.shape[1] for a in arrays) + min_w = min(a.shape[2] for a in arrays) + arrays = [a[:, :min_h, :min_w] for a in arrays] + + raw_np = np.concatenate(arrays, axis=0) + + if raw_np.shape[0] != channels_expected: + raise RuntimeError( + f"Tensor RAW_BRUTO montado com canais inesperados: {raw_np.shape[0]} | esperado={channels_expected} | got={channel_names}" + ) + + return raw_np + + # ------------------------------------------------- + # RGB ou MULTISPEC já pronto + # ------------------------------------------------- + if frame_type == "RGB" or frame_type == "MULTISPEC": + if not isinstance(frame, np.ndarray): + raise RuntimeError(f"Frame {frame_type} esperado como ndarray") + + if frame.ndim != 3: + raise RuntimeError(f"Frame {frame_type} inválido: shape={frame.shape}") + + if dtype_str == "uint8": + raw_np = frame.astype(np.float32) / 255.0 + elif dtype_str == "float32": + raw_np = frame.astype(np.float32) + elif dtype_str == "uint16": + raw_np = frame.astype(np.float32) / 65535.0 + else: + raise RuntimeError(f"dtype {frame_type} não suportado: {dtype_str}") + + if raw_np.shape[0] != channels_expected: + raise RuntimeError( + f"Frame {frame_type} com canais inesperados: {raw_np.shape[0]} | esperado={channels_expected}" + ) + + return raw_np + + + raise RuntimeError(f"frame_type não suportado para inferência: {frame_type}") + + def build_infer_tensor_from_stream(self, frame, meta, channels_expected, target_size=None): + frame_type = meta.get("frame_type") + + if frame_type == "RAW_BRUTO": + decoded = self.decode_stream_cameras(frame, meta) + tensor = self.fuse_multispec_cameras(decoded, meta, channels_expected) + return self.resize_tensor_chw(tensor, target_size=target_size) + + if frame_type in ("RGB", "MULTISPEC"): + tensor = self.build_infer_tensor_from_stream_old(frame, meta, channels_expected) + return self.resize_tensor_chw(tensor, target_size=target_size) + + raise RuntimeError(f"frame_type não suportado para inferência: {frame_type}") + + def decode_stream_cameras(self, frame, meta): + if not isinstance(frame, dict): + raise RuntimeError("RAW_BRUTO esperado como dict de câmeras no modo multi") + + camera_frames = meta.get("camera_frames", {}) or {} + camera_info = meta.get("camera_info", {}) or {} + + decoded = {} + + for cam_id, data in frame.items(): + cam_meta = camera_frames.get(cam_id) or camera_info.get(cam_id) or {} + + role = str(cam_meta.get("role", "")).lower() + if not role: + raise RuntimeError(f"Meta da câmera {cam_id} sem role. Esperado role='rgb', 'nir' ou 're'.") + + bit_depth = int(cam_meta.get("bit_depth", 10)) + raw_format = str(cam_meta.get("raw_format", "")).upper() + is_raw10 = raw_format == "RAW10_PACKED" or bit_depth == 10 + + if role == "rgb": + # Caso OAK RAW real: câmera RGB também vem RAW10 packed + if is_raw10 and data.ndim == 2: + sensor_w = int(cam_meta.get("width", self.sensor_width)) + sensor_h = int(cam_meta.get("height", self.sensor_height)) + + raw16 = self.unpack_raw10_packed( + data, + sensor_width=sensor_w, + sensor_height=sensor_h, + ) + + rgb_chw = self.build_training_rgb( + raw16, + output_dtype="float32", + bit_depth=bit_depth, + ) + + rgb_hwc = np.transpose(rgb_chw, (1, 2, 0)) + + decoded[cam_id] = { + "name": "RGB", + "role": "rgb", + "image": rgb_hwc, + "meta": cam_meta, + } + + else: + # Caso preview/processado antigo: BGR HWC uint8 + if data.ndim != 3 or data.shape[2] != 3: + raise RuntimeError(f"{cam_id} RGB inválida: shape={data.shape}") + + rgb = data[:, :, ::-1].astype(np.float32) / 255.0 + + decoded[cam_id] = { + "name": "RGB", + "role": "rgb", + "image": np.clip(rgb, 0.0, 1.0), + "meta": cam_meta, + } + + elif role == "re": + decoded[cam_id] = { + "name": "RE", + "role": "re", + "image": self._decode_spectral_frame_to_float01(data, cam_meta), + "meta": cam_meta, + } + + elif role == "nir": + decoded[cam_id] = { + "name": "NIR", + "role": "nir", + "image": self._decode_spectral_frame_to_float01(data, cam_meta), + "meta": cam_meta, + } + + return decoded + + def fuse_multispec_cameras(self, decoded, meta, channels_expected): + rgb_cam_id = self._find_cam_by_role(decoded, "rgb") + if rgb_cam_id is None: + raise RuntimeError("Fusão requer câmera com role='rgb' como referência") + + rgb = decoded[rgb_cam_id]["image"] + h, w = rgb.shape[:2] + + rgb_chw = np.transpose(rgb, (2, 0, 1)) + channels = [rgb_chw] + names = ["R", "G", "B"] + + valid_masks = [np.ones((h, w), dtype=np.uint8)] + + role_to_cam = { + item.get("role", data.get("meta", {}).get("role")): cam_id + for cam_id, data in decoded.items() + for item in [data] + } + + for role, ch_name in (("re", "RE"), ("nir", "NIR")): + cam_id = role_to_cam.get(role) + if cam_id is None: + continue + + img = decoded[cam_id]["image"] + aligned, valid_mask = self._warp_with_valid_mask(img, role, (h, w), meta) + + channels.append(aligned[None, :, :]) + names.append(ch_name) + valid_masks.append(valid_mask) + + cfg = self.fusion_config + if cfg.get("crop_valid_common", False): + crop_box = self._compute_common_crop_box(valid_masks) + if crop_box is not None: + channels = self._crop_and_resize_channels(channels, crop_box, (h, w)) + + tensor = np.concatenate(channels, axis=0) + + if tensor.shape[0] != channels_expected: + raise RuntimeError( + f"Tensor fundido com canais inesperados: {tensor.shape[0]} | " + f"esperado={channels_expected} | got={names}" + ) + + return tensor.astype(np.float32, copy=False) + + def _shift_image(self, img, dx, dy): + h, w = img.shape[:2] + M = np.float32([[1, 0, dx], [0, 1, dy]]) + return cv2.warpAffine( + img, M, (w, h), + flags=cv2.INTER_LINEAR, + borderMode=cv2.BORDER_CONSTANT, + borderValue=0 + ) + + def _affine_image(self, img, dx, dy, theta_deg): + h, w = img.shape[:2] + center = (w * 0.5, h * 0.5) + + M = cv2.getRotationMatrix2D(center, theta_deg, 1.0) + M[0, 2] += dx + M[1, 2] += dy + + return cv2.warpAffine( + img, + M, + (w, h), + flags=cv2.INTER_LINEAR, + borderMode=cv2.BORDER_CONSTANT, + borderValue=0 + ) + + def _warp_with_valid_mask(self, img, role, ref_shape, meta): + ref_h, ref_w = ref_shape + + if img.shape[:2] != (ref_h, ref_w): + img = cv2.resize(img, (ref_w, ref_h), interpolation=cv2.INTER_LINEAR) + + cfg = self.fusion_config + mode = cfg.get("alignment_mode", "identity") + + mask = np.ones((ref_h, ref_w), dtype=np.uint8) * 255 + + if mode == "identity": + warped = img + warped_mask = mask + + elif mode == "manual_offset": + offs = cfg.get("manual_offsets", {}).get(role, {}) + dx = int(offs.get("dx", 0)) + dy = int(offs.get("dy", 0)) + + warped = self._shift_image(img, dx, dy) + warped_mask = self._shift_image(mask, dx, dy) + + elif mode == "manual_affine": + offs = cfg.get("manual_offsets", {}).get(role, {}) + dx = int(offs.get("dx", 0)) + dy = int(offs.get("dy", 0)) + theta_deg = float(offs.get("theta_deg", 0.0)) + + warped = self._affine_image(img, dx, dy, theta_deg) + warped_mask = self._affine_image(mask, dx, dy, theta_deg) + + elif mode == "homography": + H = cfg.get("homographies", {}).get(f"{role}_to_rgb") + + if H is None: + warped = img + warped_mask = mask + else: + H = np.asarray(H, dtype=np.float32) + + if H.shape != (3, 3): + raise RuntimeError(f"Homografia inválida para {role}: shape={H.shape}") + + warped = cv2.warpPerspective( + img, H, (ref_w, ref_h), + flags=cv2.INTER_LINEAR, + borderMode=cv2.BORDER_CONSTANT, + borderValue=0 + ) + + warped_mask = cv2.warpPerspective( + mask, H, (ref_w, ref_h), + flags=cv2.INTER_NEAREST, + borderMode=cv2.BORDER_CONSTANT, + borderValue=0 + ) + + else: + raise RuntimeError(f"alignment_mode inválido: {mode}") + + warped_mask = (warped_mask > 0).astype(np.uint8) + return warped, warped_mask + + def _compute_common_crop_box(self, masks): + if not masks: + return None + + common = masks[0].copy() + for m in masks[1:]: + common = np.logical_and(common > 0, m > 0) + + ys, xs = np.where(common) + if len(xs) == 0 or len(ys) == 0: + return None + + x0 = int(xs.min()) + x1 = int(xs.max()) + 1 + y0 = int(ys.min()) + y1 = int(ys.max()) + 1 + + return x0, y0, x1, y1 + + def _crop_and_resize_channels(self, channels, crop_box, ref_shape): + x0, y0, x1, y1 = crop_box + ref_h, ref_w = ref_shape + + cropped = [ch[:, y0:y1, x0:x1] for ch in channels] + + cfg = self.fusion_config + if not cfg.get("resize_after_crop", False): + return cropped + + target_size = cfg.get("target_size", None) + if target_size is None: + target_w, target_h = ref_w, ref_h + else: + target_w, target_h = target_size + + resized = [] + for ch in cropped: + ch_resized = np.stack([ + cv2.resize( + ch_i, + (target_w, target_h), + interpolation=cv2.INTER_LINEAR + ) + for ch_i in ch + ], axis=0) + resized.append(ch_resized) + + return resized + + def resize_tensor_chw(self, tensor, target_size=None): + if target_size is None: + return tensor + + target_w, target_h = target_size + + if tensor.ndim != 3: + raise RuntimeError(f"Tensor esperado em CHW. Veio shape={tensor.shape}") + + _, h, w = tensor.shape + + if (w, h) == (target_w, target_h): + return tensor.astype(np.float32, copy=False) + + interp = cv2.INTER_AREA if target_w < w or target_h < h else cv2.INTER_LINEAR + + chans = [] + for ch in tensor: + ch_res = cv2.resize(ch, (target_w, target_h), interpolation=interp) + chans.append(ch_res.astype(np.float32)) + + return np.stack(chans, axis=0) + + + def extract_camera_meta(self, meta_json: dict, cam_id: str) -> dict: + cam_frames = meta_json.get("camera_frames", {}) or meta_json.get("stream_meta", {}).get("camera_frames", {}) + + cam = cam_frames.get(cam_id) + if not cam: + raise ValueError(f"Camera {cam_id} não encontrada no meta") + + # Detecta RAW10 packed mono + if int(cam.get("channels", 1)) == 1 and int(cam.get("bit_depth", 10)) == 10: + packed_width = int(cam.get("width")) + height = int(cam.get("height")) + + # 🔥 converte packed → real + real_width = int((packed_width * 8) / 10) + + return { + "camera_id": cam_id, + "width": real_width, + "height": height, + "channels": 1, + "bit_depth": 10, + "shape": [height, packed_width], # packed shape + "role": cam.get("role") + } + + # RGB + else: + width = int(cam.get("width")) + height = int(cam.get("height")) + channels = int(cam.get("channels", 3)) + + return { + "camera_id": cam_id, + "width": width, + "height": height, + "channels": channels, + "bit_depth": int(cam.get("bit_depth", 8)), + "shape": [height, width, channels], # 🔥 AQUI está a correção + "role": cam.get("role") + } + + # ============================================================ + # RAW10 PACKED + # ============================================================ + + def packed_width_for_raw10(self, sensor_width: int = None) -> int: + width = sensor_width if sensor_width is not None else self.sensor_width + return math.ceil(width * 10 / 8) + + def pack_raw10_packed(self, raw16: np.ndarray) -> np.ndarray: + h, w = raw16.shape + + if w % 4 != 0: + raise ValueError(f"Width precisa ser múltiplo de 4 para pack otimizado. Veio {w}") + + raw16 = np.clip(raw16, 0, 1023).astype(np.uint16) + + p0 = raw16[:, 0::4] + p1 = raw16[:, 1::4] + p2 = raw16[:, 2::4] + p3 = raw16[:, 3::4] + + b0 = (p0 >> 2).astype(np.uint8) + b1 = (p1 >> 2).astype(np.uint8) + b2 = (p2 >> 2).astype(np.uint8) + b3 = (p3 >> 2).astype(np.uint8) + + b4 = ( + ((p0 & 0x03) << 0) | + ((p1 & 0x03) << 2) | + ((p2 & 0x03) << 4) | + ((p3 & 0x03) << 6) + ).astype(np.uint8) + + packed = np.empty((h, w // 4, 5), dtype=np.uint8) + packed[:, :, 0] = b0 + packed[:, :, 1] = b1 + packed[:, :, 2] = b2 + packed[:, :, 3] = b3 + packed[:, :, 4] = b4 + + return packed.reshape(h, w // 4 * 5) + + def load_raw10_packed_file(self, path: str, width: int, height: int) -> np.ndarray: + packed_width = self.packed_width_for_raw10(width) + + expected_size = height * packed_width + actual_size = os.path.getsize(path) + + if actual_size != expected_size: + raise ValueError( + f"Tamanho inválido RAW10: {actual_size}, esperado {expected_size} em {path}" + ) + + packed = np.fromfile(path, dtype=np.uint8).reshape(height, packed_width) + return self.unpack_raw10_packed(packed, sensor_width=width, sensor_height=height) + + def save_raw10_packed_file(self, path: str, raw16: np.ndarray): + packed = self.pack_raw10_packed(raw16) + packed.tofile(path) + + # ============================================================ + # RGB UINT8 + # ============================================================ + + def load_rgb_u8_file(self, path: str, shape) -> np.ndarray: + arr = np.fromfile(path, dtype=np.uint8) + + expected = np.prod(shape) + if arr.size != expected: + raise ValueError( + f"Tamanho inválido RGB: {arr.size}, esperado {expected} em {path}" + ) + + return arr.reshape(shape) + + + def save_rgb_u8_file(self, path: str, arr: np.ndarray): + arr.astype(np.uint8).tofile(path) + + + # ============================================================ + # DISPATCHER (O MAIS IMPORTANTE) + # ============================================================ + + def load_native_bin(self, path: str, cam_meta: dict) -> np.ndarray: + """ + Decide automaticamente como carregar o .bin baseado no meta. + """ + + channels = int(cam_meta.get("channels", 1)) + bit_depth = int(cam_meta.get("bit_depth", 10)) + shape = cam_meta.get("shape") + + if channels == 1 and bit_depth == 10: + width = int(cam_meta["width"]) + height = int(cam_meta["height"]) + return self.load_raw10_packed_file(path, width, height) + + elif channels == 3 and bit_depth == 8: + return self.load_rgb_u8_file(path, shape) + + else: + raise ValueError( + f"Formato não suportado: channels={channels}, bit_depth={bit_depth}" + ) + + + def save_native_bin(self, path: str, arr: np.ndarray, cam_meta: dict): + """ + Salva no formato correto baseado no meta. + """ + + channels = int(cam_meta.get("channels", 1)) + bit_depth = int(cam_meta.get("bit_depth", 10)) + + if channels == 1 and bit_depth == 10: + self.save_raw10_packed_file(path, arr) + + elif channels == 3 and bit_depth == 8: + self.save_rgb_u8_file(path, arr) + + else: + raise ValueError( + f"Formato não suportado para salvar: channels={channels}, bit_depth={bit_depth}" + ) + + + def load_fusion_config_json(self, path: str): + if not path or not os.path.isfile(path): + raise FileNotFoundError(f"Arquivo de calibração não encontrado: {path}") + + with open(path, "r", encoding="utf-8") as f: + data = json.load(f) + + fusion = data.get("fusion_config") + if not isinstance(fusion, dict): + print("[WARN] JSON sem fusion_config. Mantendo config padrão.") + return + + self.fusion_config = self._merge_fusion_config(self.fusion_config, fusion) + + def _merge_fusion_config(self, default_cfg: dict, loaded_cfg: dict) -> dict: + cfg = json.loads(json.dumps(default_cfg)) + + for key, value in loaded_cfg.items(): + if isinstance(value, dict) and isinstance(cfg.get(key), dict): + cfg[key].update(value) + else: + cfg[key] = value + + return cfg + + def _decode_spectral_frame_to_float01(self, data, cam_meta): + arr = data + + if arr.ndim == 3 and arr.shape[2] == 1: + arr = arr[:, :, 0] + + bit_depth = int(cam_meta.get("bit_depth", 8)) + channels = int(cam_meta.get("channels", 1)) if cam_meta.get("channels") is not None else 1 + + # Caso preview/processado: mono já vem uint8/uint16 normal. + if arr.ndim == 2 and arr.dtype == np.uint8: + return np.clip(arr.astype(np.float32) / 255.0, 0.0, 1.0) + + if arr.ndim == 2 and arr.dtype == np.uint16 and bit_depth != 10: + return np.clip(arr.astype(np.float32) / 65535.0, 0.0, 1.0) + + if bit_depth == 10: + sensor_width = int(cam_meta.get("width", self.sensor_width)) + sensor_height = int(cam_meta.get("height", arr.shape[0])) + + raw16 = self.unpack_raw10_packed( + arr, + sensor_width=sensor_width, + sensor_height=sensor_height, + ) + + max_val = float((1 << bit_depth) - 1) + return np.clip(raw16.astype(np.float32) / max_val, 0.0, 1.0) + + # fallback + arr01 = arr.astype(np.float32) + if arr01.max() > 1.5: + arr01 /= 255.0 + + return np.clip(arr01, 0.0, 1.0) diff --git a/Python/OAK/datasets/oak-fcc-3/core/raw_processor_preview.py b/Python/OAK/datasets/oak-fcc-3/core/raw_processor_preview.py new file mode 100644 index 000000000..c9f251703 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/core/raw_processor_preview.py @@ -0,0 +1,125 @@ +import cv2 +import numpy as np +from typing import Optional + + +class RawProcessorPreview: + def __init__(self, sensor_width: int, sensor_height: int, bayer_pattern: str = "GBRG"): + self.sensor_width = sensor_width + self.sensor_height = sensor_height + self.bayer_pattern = bayer_pattern.upper() + + def raw16_to_vis8( + self, raw16: np.ndarray, + black_level: Optional[int] = None, + white_level: Optional[int] = None, + gamma: float = 2.2, + bit_depth: int = 10 + ) -> np.ndarray: + """ + Conversão para visualização: + - auto-level + - gamma + """ + max_val = float((1 << bit_depth) - 1) + + raw = raw16.astype(np.float32) + + if black_level is None: + black_level = float(raw.min()) + if white_level is None: + white_level = float(raw.max()) + + if white_level <= black_level: + norm = raw / max_val + else: + norm = (raw - black_level) / (white_level - black_level) + + norm = np.clip(norm, 0.0, 1.0) + + if gamma is not None and gamma > 0: + norm = np.power(norm, 1.0 / gamma) + + return (norm * 255.0).clip(0, 255).astype(np.uint8) + + def _debayer_code(self): + mapping = { + # Mapeamento ajustado para OpenCV gerar BGR correto a partir do padrão Bayer informado. + "GBRG": cv2.COLOR_BayerGR2BGR, + "GRBG": cv2.COLOR_BayerGB2BGR, + "RGGB": cv2.COLOR_BayerBG2BGR, + "BGGR": cv2.COLOR_BayerRG2BGR, + } + if self.bayer_pattern not in mapping: + raise ValueError(f"Padrão Bayer não suportado: {self.bayer_pattern}") + return mapping[self.bayer_pattern] + + def apply_preview_white_balance(self, bgr: np.ndarray, strength: float = 1.0) -> np.ndarray: + """ + Gray-world simples para deixar o preview mais agradável. + Não usar no raw de treino. + """ + img = bgr.astype(np.float32) + + mean_b = float(img[:, :, 0].mean()) + mean_g = float(img[:, :, 1].mean()) + mean_r = float(img[:, :, 2].mean()) + + mean_gray = (mean_b + mean_g + mean_r) / 3.0 + + eps = 1e-6 + gain_b = mean_gray / max(mean_b, eps) + gain_g = mean_gray / max(mean_g, eps) + gain_r = mean_gray / max(mean_r, eps) + + # strength=1 aplica total, strength=0 não aplica + gain_b = 1.0 + (gain_b - 1.0) * strength + gain_g = 1.0 + (gain_g - 1.0) * strength + gain_r = 1.0 + (gain_r - 1.0) * strength + + img[:, :, 0] *= gain_b + img[:, :, 1] *= gain_g + img[:, :, 2] *= gain_r + + return np.clip(img, 0, 255).astype(np.uint8) + + def apply_preview_contrast(self, bgr: np.ndarray, alpha: float = 1.08, beta: float = 0.0) -> np.ndarray: + """ + Ajuste leve de contraste/brilho para preview. + """ + out = cv2.convertScaleAbs(bgr, alpha=alpha, beta=beta) + return out + + def raw16_to_preview_bgr( + self, + raw16: np.ndarray, + gamma: float = 2.2, + wb_strength: float = 0.8, + apply_wb: bool = True, + apply_contrast: bool = True, + bit_depth: int = 10, + ) -> np.ndarray: + """ + Pipeline de preview bonito: + 1. auto-level + gamma no mosaico + 2. demosaic + 3. white balance simples + 4. leve contraste final + """ + vis8 = self.raw16_to_vis8(raw16, gamma=gamma, bit_depth=bit_depth) + bgr = cv2.cvtColor(vis8, self._debayer_code()) + + if apply_wb: + bgr = self.apply_preview_white_balance(bgr, strength=wb_strength) + + if apply_contrast: + bgr = self.apply_preview_contrast(bgr, alpha=1.08, beta=0.0) + + return bgr + + def raw16_to_preview_jpg_bytes(self, raw16: np.ndarray, jpeg_quality: int = 95) -> bytes: + bgr = self.raw16_to_preview_bgr(raw16) + ok, enc = cv2.imencode(".jpg", bgr, [int(cv2.IMWRITE_JPEG_QUALITY), int(jpeg_quality)]) + if not ok: + raise RuntimeError("Falha ao codificar preview JPG") + return enc.tobytes() diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195358_192.json b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195358_192.json new file mode 100644 index 000000000..e7d856325 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195358_192.json @@ -0,0 +1,134 @@ +{ + "ts": "2026-05-04T19:53:58.192", + "cana": "baixa", + "horario": "cedo", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "fps_target": 20, + "frame_type": "MULTISPEC", + "capture_mode_requested": "TRIPLE", + "capture_mode_effective": "TRIPLE", + "raw_policy": "require_triple", + "stream_meta": { + "frame_id": 128, + "backend": "oak_fcc3", + "frame_type": "MULTISPEC", + "capture_mode": "TRIPLE", + "output_dtype": "float32", + "dtype": "float32", + "output_layout": "CHW", + "payload_sources": [ + "cam2", + "cam0", + "cam1" + ], + "camera_info": { + "cam2": { + "id": "cam2", + "socket": "CAM_A", + "sensor": "OV9782", + "role": "rgb" + }, + "cam0": { + "id": "cam0", + "socket": "CAM_B", + "sensor": "OV9282", + "role": "re" + }, + "cam1": { + "id": "cam1", + "socket": "CAM_C", + "sensor": "OV9282", + "role": "nir" + } + }, + "timestamps": { + "cam2": 200401.897136, + "cam0": 200401.905167, + "cam1": 200401.905153 + }, + "sync_dt_ms": 8.030999975744635, + "sync_ok": true, + "sync_tolerance_ms": 25.0, + "shapes": { + "cam2": [ + 480, + 640, + 3 + ], + "cam0": [ + 480, + 640 + ], + "cam1": [ + 480, + 640 + ] + }, + "dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + }, + "codec_name": "none", + "codec_family": "none", + "dt_comp": 0.0, + "dt_send_payload_prev": 0.0, + "channels": [ + "R", + "G", + "B", + "RE", + "NIR" + ], + "fusion_applied": true, + "fusion_alignment_mode": "manual_affine", + "module_calibration_json": ".\\calibration\\module_params.json", + "tensor_shape": [ + 5, + 480, + 640 + ] + }, + "applied_camera_controls": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam2": { + "ae_enable": false, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ], + "ok": true + } + }, + "camera_params_json": ".\\calibration\\module_params.json", + "note": "manual", + "raw_preview_reference_camera": "cam2", + "saved_payload_type": "multispec", + "saved_payload_path": "20260504_195358_192.raw", + "saved_payload_dtype": "float32", + "saved_payload_shape": [ + 5, + 480, + 640 + ] +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195358_192.png b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195358_192.png new file mode 100644 index 000000000..0822b30e7 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195358_192.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195358_192.raw b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195358_192.raw new file mode 100644 index 000000000..9c3bf63a4 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195358_192.raw differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002.json b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002.json new file mode 100644 index 000000000..56aa1daf4 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002.json @@ -0,0 +1,137 @@ +{ + "ts": "2026-05-04T19:54:53.002", + "cana": "baixa", + "horario": "cedo", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "fps_target": 20, + "frame_type": "RAW_BRUTO", + "capture_mode_requested": "TRIPLE", + "capture_mode_effective": "TRIPLE", + "raw_policy": "require_triple", + "stream_meta": { + "frame_id": 47, + "backend": "oak_fcc3", + "frame_type": "RAW_BRUTO", + "capture_mode": "TRIPLE", + "output_dtype": "float32", + "dtype": "float32", + "output_layout": "dict_by_camera", + "payload_sources": [ + "cam2", + "cam0", + "cam1" + ], + "camera_info": { + "cam2": { + "id": "cam2", + "socket": "CAM_A", + "sensor": "OV9782", + "role": "rgb" + }, + "cam0": { + "id": "cam0", + "socket": "CAM_B", + "sensor": "OV9282", + "role": "re" + }, + "cam1": { + "id": "cam1", + "socket": "CAM_C", + "sensor": "OV9282", + "role": "nir" + } + }, + "timestamps": { + "cam2": 200456.850225, + "cam0": 200456.857952, + "cam1": 200456.85794 + }, + "sync_dt_ms": 7.726999989245087, + "sync_ok": true, + "sync_tolerance_ms": 25.0, + "shapes": { + "cam2": [ + 480, + 640, + 3 + ], + "cam0": [ + 480, + 640 + ], + "cam1": [ + 480, + 640 + ] + }, + "dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + }, + "codec_name": "none", + "codec_family": "none", + "dt_comp": 0.0, + "dt_send_payload_prev": 0.0 + }, + "applied_camera_controls": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam2": { + "ae_enable": false, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ], + "ok": true + } + }, + "camera_params_json": ".\\calibration\\module_params.json", + "note": "manual", + "raw_preview_reference_camera": "cam2", + "saved_payload_type": "raw_native_multi", + "saved_payload_paths": { + "cam2": "20260504_195453_002_cam2.bin", + "cam0": "20260504_195453_002_cam0.bin", + "cam1": "20260504_195453_002_cam1.bin" + }, + "saved_payload_shapes": { + "cam2": [ + 480, + 640, + 3 + ], + "cam0": [ + 480, + 640 + ], + "cam1": [ + 480, + 640 + ] + }, + "saved_payload_dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + } +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002.png b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002.png new file mode 100644 index 000000000..4f487f401 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002_cam0.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002_cam0.bin new file mode 100644 index 000000000..473533501 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002_cam0.bin @@ -0,0 +1,980 @@ +bbcddfdjggdjgfgfkhjiokjumommoqpprruussusywxz~z}|~~k|~yurrqoljijigfec`^]_`[YY[YWWTRQRQKPPONNLMMMKJKJJIIIGEFEEEDCDAAB@@B?A>??@?=>?B<=:999:=:98776558777796:65568185567485535542223457533653/.:324.6332333+634344223203111222121202231213111.4+9601135)3/1./02/0..../2/..-.+.+*      20/1FL9!""#  !!"   !#$!!! !"#!$ !!! # $$! ""###$$$##!"%'''%'%'%&#$%'(''(+"%$%%$$%(('%%"!""!`ebdgdeeegecgfgghjjklonmqmqrnqpqqqtwutuwxx{{|{}~}~jzwusprmkjiggfeeda_]]][\YXWVVUVTQQQNMNMLKMMKONJJLHFJHFDFDBCCCCA@@BC@?>A=>=>?<==;<=8::9:887788:77585758775555565887654564425445242223311/012333320024434423223322110124130222261211133003221114312022//000.00/001/-+-..,(  +  /4+14EG,#!    !!!! " "!   ! !"! !! ! !  !! !!""!#"#!#$#$""""$$%$%%'%$&%$&((&%!%''&'%'#%'''%## ! "ffdebegheeghhiiigiljnonnqnprqpsppwrvuvxwyxz|~}lu~{wuppoojhggfeddc`_^]\]ZYXVVVWVVRPOPPOLOMMLKHKIIHHGGHBDDGCBBC@@@@>A@@==>>=:==<>?7=:;9:8889:7687887677795476674866755555437544454233412152234342/02435232333523133022220/52220001211113622221022212////010112/0//20+/-,(  + +  + + 20-06FD&     ! ""!!! ! !"$ !!" " #! " # %##"!""## !#$"%#$$ $#$%%)'(&"$''%('%%%%&'&$##&###ebcdeffedfehlfhgmjjllimonoqppvqtrrtsv{wyyyz|~}r}~{wrtrqljhfgedec_^^]][YYUWXWUSSRPPOORNMLLLNMFIGJGGHJJBDEEBCCBF>???@@A><==<;<<=<>8989:88788987756<56688765756865664444453354335352215234353231012233323323502233033123012233311110204021211211-522210/003110///./2-,0$# + + + +  !2++16N.!" !!     ! !#""$#! !#"!!!!" !"!"!"!! !$$"& #""! "$!%!#$"!""$%$&$$"!%$#)(''$$'%&%$%%%%%#gbfedecefgggghijhjklllnnpppqpqqrssswxvxxyyy~}ix}wstsrjhjiefefab_]^[^WZWZWSSRSRQPQLMLJNILLKJIHHHFEGCCFDEBAA??@???>=?@;=?=<><=<;;:;9:<888889577886666855556755554543474555244444373333533121422132222344/232412213112113112111222002/1002022/141//10/1/0//./0/+,,*+' + +  +  -0*,/?O4       !!!"! ""!!! %##""!! #"# !$#$""" !#$%$$! !! !$$#%$$!#""!(''($$&&%$%%($$%gcgfddchhghggiikkjklmnmnoqpptoustvtuvv|xy{|~ny~|vtsqoihjieedbba^]\[VZXWWYVUXRQROOMPOJOMLIHGJHIGGHHDDDCC@AAA>B>A>?<:>===<<=<<;>9::;;877779777779577555474656465533326443433423520344223122334222113320131322222111212252003240112/2103001/321220001/0/0.../..*)(,' + +  + + + + 2/),1PM#"   ! ""! !"""!! #%#"!! ! !!#  #"## #!!#$%$! ! "!#&""!#"#"!""'+(&$&&($##&##$dbfdhfhghgjgiijkkkmmoponnoqpvstuuvxuz{x}zz}~sr}wvtrsnkkfkedgc`_]b[YYXXYVVWQRSRRLMLLJLLJOJEEGKEJGEHDCBACC?C@AA@A=A@;?;<8:<:9;97?677778677759757472357652557134345454646431443211222153132230241102232222153/122021214320112120032102/1/2//044/3/../0//-,++,) + + + + 6.-/9P>$    ! " !!!!" #%%! !! $!$#!" !#"!!!!"""! " !"$!$#%!"""!"!#$&$'%$&%'#$$##%$ccegffighihiihmkirmltqqopptqstssuwyvwz{{{|qu~zuvrolnjhgecb__^\_\[YWVVUTRQSQQOPJLNKNQKJIGFEGDFEEDCBBCE@BA@@>=@<=?=>;?<:;;9<9:878978787658797556555465466755662333443435254522232322230232532311223225403331112110123220411220/111003000000/2/.020/000*.1*+,,,# + +  +  #/+03GO9 ! !  ! ! " ! !!"! !! "#!!! """" !#"!! !$"#!##$&$#!#$%$%"%&&#&&'$$##""$#bcdffffhgjifijmjommonmrnpsttrsuuvuvwyx{}~~lq}xxrspkjhhgbcb`_]^ZZYWWWSSRRRQQOOMLMKLKKKJIFGGIEFFDHDFDAB?@@?=?>>====<;?:<;9:9:8978:585666683855575442346655513653425364254224343333322233403220//020353431032121012010220001110121101,0/000///0/-/1/.1/-(,-,(% +  + +  .6.30JM% !!!! !#! !! !! !#!!""!"""!!!"$$!! #!"#%#$#!'%(%$$$%##&&%"$$!$"#ddegfgfgjgjghiljklnopoqtptqrsurvvvxwxy~~ju{wtxnmljigdc`a^\\\[XXWVTTSQSRRQNTLLMMNJKJHHIEEFGAECEDD@E?A?>@@?>:<>=<:<=9::;9:9988997875766785785935575555666545443245432214432300223223223411.13102234423415221303321333211112212130.20002.1/0/../0.-,-.*),," +   + + + 3(.39K@# ! !!   ! !!!"  !! $!!!"#! !!!#$""!!" !$%#%$# "#%'#'$"'%$$$$%$"#""##dffdefghgigijijlnpqnooopoqptsstuvyyz|{{~~nuywwqlmjigec`ab][Z[YYYXVRQSSQQQPQJMKPMJIJJJJIFFGGDEDECCC@@@>B>@==<=::99:::<:9;:9898;869687876657756556455553742276464552433245314222225222100/114243332243112111*1123222310/222433110/100011/0/0/..//.+,,+,,*'    + !4)24;K< !  !" !! ! ! ! !!!"" "! !#$!!!"!!! ! !"$##"# " $%&$$##$%$$%%%!##$#dfehhgehgigiikjmjnoqrppnsqssstsvuwzz|}{~pvxxurnoiggdca_^\[ZYXXXUTRRSRRQRPQPNGKJHIMHGIGGFFDEDCBCDB@B@@A=>?<:;99::;<::9999;9899:888886656767775785444645473353544222223443334/1031222002/2223432223242/10/41222243212/311300/1000/10/1.01100../,,+*++,)( + +  + + + .0+21FE$       % !!!! !!"!$$ ! !!! !!!####"! !$%$#"!!#"%%$%$"##$degfgfiegihkhgjjjjopqrnppoqvuuxw|yx~z|~~~ntxstqoojhgdba`]]Z^[XZVSRPRRRQOOMLNNOHHHJKIIFGEFFECFBBCB@<@?>>?=?@;::>9==;9:9989::99:5;88867677788644577654364446553364332234365003133234150353032210221342144431115162203011102110/00.0000-.00/0.-0/,-,)++(  + + + + + + 5-,07K:   "! "  "   #"!"$!!! !$ % !""" "#!"!""#!" !!"%$$%$#$"$(&%%&$%%ddefhfghfkjjihhnikmonpqqopspytvwwyxz|}~~~mlywqmmkihed_`^_][WZWVUTSSSPPPQMNMNKIJJKKMHHFHFDDDAEFBDAB@?>@??@>=;?<::::;9:7999::::75778767656798463555455665365565333222223322223233122324220210021108211.201231/1/11//0112021000/0/2/000////,,,*-+--*+)$ +   + + )0+1.BJ@ ! !!! ! ! !$! "!! !!!!! ! !!" "#"!"" !#!!##$$%%###$"($&$%#%dehkegihghijkliklmnpnoloupwtxyyy{yz{{~pnyvplkjigdabb`]]ZXXWTSTSTRPOPONNNMMJJJIJJLFEDDBDFCADCB??=@A??B@><::<::9<:9<98:<9:77767878865555267755653335424545334312332242222333312321201450121022110113101221//111101211/111000/.010/./-,,-0.-.-++))! + + + + +  + + --,./EF3 ! "  !   ""#! ! "!"!!!"! ! !!"##!$ !!"!##%"#&%&$$&%&&%&$$deecggddhhoilljhlllnlmwqqtxxqvxwv|{~~|lmutplkghecbb^]bYYYVVWXRPSQQPQNNNNMLJJJLIFFGJDEDEDCBBBA@B?@@???>?>;<:=:=989;>78;;988877577:62656885634244534334425323152224011403033213212143122023221102/1001/2//10122210111001210.3//000/+,-,,/,,/+*)(  + + +  +  .,-27EC'  ! "    ! "!$!!!  " !!!!$ "!"## "##  "!!!!$$(%$$%$$%$$$$"$#gfeegghgkjhikllkllnnottutsssxwxx{{z~~}~emutpkjfee`c_^[Z[YYYWTUTRRPPONNNMLLKNHHFHGHFCDDDCCBACC?C@>=??>@>=;;=<;;;:898:::899888697996635667886355545422455332352323321103333110122213221031222/110010221201024121230111220//1/0/.1..../.,,-.+++*   + + !&(.19G2" "!"   ! ! " ! !"!"!!!!# !"" !!$$#! !$!!!!#"'''&##$"#$$"!$$ffdfefeihihjklkmjmlmosrosywxvxwwz{|{{bnuvnjheedc`^_^ZXYZWUSUURQPPNNNLKKJKKKGGFFEDBBCECEBCAC=?>?@?>=?<==<<=<:998:88:;987977787697565555444445544133424635325122122112423/2134322322311120011100201/2/2-5311110001112//0//00/0/0.,-/-+-),*+)!   + + $6,02AE*  ! !!##$! !!"    !"!%!#!!!!!! ""!#"#!!!!!!"#"!!$$%'(%$#"!""###"gjggefgjigkgjklkpnnonrrruuvttwwyw}|{}~russmkifdaa^\[YZZXWVYUVUSOPNOMLKKJJKJIHGFEEECCDECCBAAA??@?>A>?9??;9;;=;<988:987778676778864775575686546543244565333226312223222211124432211011211121210000011124011111013055/1001.0//0.,.0,+0++)),+%  +  + + 7/.06B='!   "  !  !"#" !"!!!! " "!""#"!!!! !"!$!"$"!"!! !!$!!! %$$$($!$"#"&%! eeggggkkikikomlnonnoptqrstuvxwwvy{~|ƿerpomlkec``^_\ZZYXWUUUSRPOONQMOKLKKKKJJGGDDCEDCCAA@B?@A??>>>?=?:;;=;>;9988987877598669866766575763753555443352542536343322322225412323110143211322201/10110012001010/2110101/0.////20//0.,-*,+*))&(  +  + + + + 1//38H<$! #!  !"! "#! ! #!! %&##!" !! " !"%$%#$ ! ""!!#$%!$""""#$$""degghgfekkhmimqplnnopoqsttuuwx{~~z~}|vunnmjkeda`\\]YYXYVYUXTQPPOMNMJJJJKIFIHJICGDBDC@C@>@@???>>@<==<;;<<::;88787:885786655658665754556448554236432303344433323124223223113100221213112310121210011001/10100230///.00.0.+--0.,,++,++)(&     + + + + %0+35@G0  !!   ! " !!  #$ !!! !!"!" "!!##"#&$! ""! !!!#$"!!$###!ccehggfhjliihomnmmnmrppqrvvwwyyyx}|~kuyomkjddc^^][[YXWUVTTTQNOPOMMMKKJKIHHGGIDDCCC@AACB@A?@???A=><=>;::9:986898;87786:76666756555646493455346255723424302122322123-42121114210221122221031422/3100011101140400///.30/.,,.2.-,,+-++))'   +  + + + +  4/,15EB(   ! )! " !  ! $! !! ! !"!!$"$$#%!!!!!"$"!!!"#"&! "#"$$"$bdgdhigghjkkikokoonosoppsuxvv|||z|}žٸovuskhgeca`\]]ZZYZXXUURSNOOMLLKKJJIHIHFEGDHCECBBAA>>>>>=@@>:=<=;;::;8989;898878:;95656564554546465635445524332221122302/1034244011122110210422102023110040102001001301300/010/010,-.-.-,+-+,,'(&  + + + +  + + 4,/17I5*    !  ! ! # ! !  "!!! ##$""!! ##%"$#""#!""%## " "$$$dcbfhehhkhjllilnooppttsruuvwvxy{{}~ľӍmsuolgff`^]]\XYXXXUSRRROOPNMLNKLJIIFHFBDCECECBBCABA?>===><=;<<;;;9;99888:8;89669:7555547655444556554363564212243331012223252414012133112220/12210201202/001310200013122101.1/.-./---..,++)('+%   + + !6*+3=I2# ! !  ! # ! ! !  !"#"" !%"$!"" #!$$$##$!!$#$$#""#$$#$a`ceighgikklpjlmlmornsrwtyvvvxy|{}}¼ypttrkha`a_^^^[ZWVWZRTSTOPNKPKLJKIIICFCEEDDCCBDBDA@?A>>=<=>?=>?<@;::?9<889888787986666:449675538743393564322133312210112/32241222041220.12110700011/10//10232/100000,013102.//-./-+,.-,,+)')"   +   + )0*.5@D% !!"   ! " !! !!!  !!! ##$$#!!#% !" !" &$$#$&$%!%#$"#"!$&""bceejgjhiklkilmlmpjussussvwwwyx{{}~qltpnnfb``]^\ZVYUWTSUQRQQPPMMKIIJIIJFDCCDCBBFCCEDA@@@@=>9<=9==<99::9:9867767669776486656575244936364022534433332411410022123/312321102320111/1210/0302232000/00121/10////....+-,+.,+++)'    + +,+/=DC'!     !!!"!  " "# "! ! !!!!!"##" "%!  % ""$%%""###$##&""""$cddfgjgjfhkjnlnomponrtssuvvxwwyz}ҩjtqqnjfcca^_][XWVWUUTRQPQOOOMMIILGGFEFGDDCBBCBBCA?>@??==?=>><@<;9:89::9:87677756477:566845852264324544540124443223436111112113222111100123211/021101/04122201./2/0310//.//./..,.-,.-++**(   +   + +  #5+-0@E4"   "!!""! !! ! !!!!!!"#"#!"""!""$#! !! ! !"$$#"!$$$$!"%#!"$eeddfkggmgkjllnnnnpprprstyvvvyyz{҆kupmkgeaa]Z^ZYVYVURSPQPPQOMJKMGFJHGFEGEDFCADEA@@@>>>@?>==<<;:=<988989:978776:666674555556565475535634334244242347451/026223/3401110000111//1/11122252012001-2430011//0//0/./-,--,++**+)  +   ,1./1@@' ! ! # !""! ! !!  ! ! !!!#!"$ #$%$#$$!  ! """"%" ## & !#$fegdeehhhijkmnopnnppsqrswvzxxx}|hnpplmgd`___]XYWWVVSQRRQPROLLLMGHHIHEDCGDEEDC@@>@?>?><=>=>:?=>;<<::::8898878765878755556584686746834565322333331322133343222111113022221/00122012251/13/2//34100010.1-/0/1.../+--+)(+'!   + +  +   50/12DB    ! $$! !! " " ! !! !  !!""! !!""$%$$"$#$ #!!""$#""! !!$""!icfcgfggihiilmnmpopprqsvsvvxyz~~~ζetqqlhdb`^]\ZXVYUTSRQRROPOOJLKKJHHFGEDFBDAFCAAB@A>?=>=?;>;<=:<;;;:9888:98978757655655678557443457344345424223544232233144220211010122.0/012010/20-1304101-/0/0/0//-..1...//.-,-,*)*($  + + +   +  + 6/227G2!! ! !!!! ! !!  "!#! !"!#$$%$$##!"""&"  !!"#"! !!#%#"hieeegjijkflnonnopqoruuuuuvwxy|}~~؀krqmjgdc_]\YWWWZUTROSTQQOONMLHHHLGFEHFHBA@DBE??B??=>>?=;@?;;<==;<8::988778856697784846555553775554344432226/1422211125/121224124-20110/131001.023.1001010/010/0/.3-//.///.+../+**+#   + + +  +  *4,049F/  !! ! ! $#!!!  """!!""!$#$$$! ! "$#"! !"!"!""!##"$!$feeiefliglhljknnnnoopqsutvxxx}{~itrokhid_^\][XUVVRQQRQPONMLMJLJHHFEEEEBAC@CAB@@@A>=>===;?<<:<<=:88889<6:8786886555573665613454611454252103041334322211141213210112101111121102211000.210-2//.00-.-..010./,+,,-)(+   + + + /8004?D$ !!! !! !!  # # #"#$#"!""##"#"" !"$"#!#!#!#"$!" ! !%"#&defdhfhiihhjlklmpmqopususvvyyz{}Оetpnigde`_^\Y\VUTRSSPPQMLLMIKHHGGFEEECCDDB@A@??>>>=>>=?<<;<;;=99;::7879667978655757466756553444443221222222333231001144213210012111012/1.2022200/0////-+.//20010/0/0./0//++*-+*)  +   20018A;#  !!  !! " ##$%"#""$"##$"$! ! "#""##$"#""$##!#"""&$fdefjheiigmkjkloonnpqquttwy{yzz{Ǽprrkigfdc`^\ZXWVUTQSPLNOMQLJHHJGEEEEDCDBAB@>@A@>><><<>::=<<;<=::4988>867876655455645775646394433344443322224230111114//522212/222210.3200102100100200/100///10/.0,.....+--*.++)% +  + + + +  + + + '?-01>?>>@>>:><<<;;::;;:7899878672955675657656455534521234142223235103011210705012.3021001010200200/00//0100///00/.-10100./...-+.+(+,'    +  + + +1-/6FH&!     ! "!"#"$!%!"!"(!"" "!!  !#""#!!!'$%$gffffjhghkiljlnnompqssyuswxxy~z~sopligdb`]\ZZYXVUSTTOPNMLLKJHIGEGDEEBAAABBB???>><:>=<<;;;;<:;:;;;897878779665666896765656533233424342301220210201121053421210//02//120130.0201/10.01./0/001.-0/..-,--+-,+*+,"  +  + +  30.2/O6! " "  !  " #!" !!!"#"! ! !#!" !###$%!##%$!efcggdfhghkjjmlnmunprprtvyuy{}}}Ƚosmkgebc^\^\[YWTTQTPPMLMLKJGJHGFHEACA@CBE@C@?>=@@;<<=;<==;:<;799<8896677776576646872454432430334444332112221221321422122100102011.0.1011101/--/01103//2.00/./0/-.-.-,)+*+-'     + + +  )0(42DH4 ! ! !!  !!    !"!$$ !""" "!""% ! !!!"$! !!$#!#$!#$$! fgeeeghfgillkllllqqpqtstuwz|y|}~xosligcc_`_\\XVYTUQQOONLJKJJGCEFDDDDDBCA@BA@@>=<<<;:><<;::8?:9@A>=;;==<;:=<=8999=99:89:896775696654556543334554433211232211/22232131030/2110110/0300..//00113.1/030110..////.//-/0-,+++,,++( ' +  + //,4=HA!   ! ! ! #""!!! #"# !"!""!!"  !""!""""#"$"#"  "deihifighihgjionknnorrqsvvyxxz|~Ӑqqljhfb`a][\YWVYRPNQMHJJJIHIHFDBCDBCC@@AA@<>;;;;<:9::::88:99977566686545552345334733432222.51140212.125/0.10003/012010000/./0/1132100010.,.,/01/////1,.,-++++++)('  + $2..5@H7! !   !! ! ! #!  ! !!"$ "!"" "!"!!"!""#!"$# !!cefchhhkggmkkmlnpnopsssquvw}z|~~ȿfromjhda`a[^\YWWTPPNLKKIIHHHHDFCEBCDBB@@AAB??<<=><<<=>;;;;;;979:989867885767676576575433222434432222211011151021210100/101//2110//0/0//0/0/1./1..//,....--,0.,++,**(())### +   + 2.14:I@*      ! !! ! ! "!!!! !"!!!"#!!! !"" ! !eeheeldkgkkjkjjlnrpsstsvvyy}zgpikiega^_[WYXVTRQOPLNJIIIIEGGEDC@CD@A????@?;=<;=<<<<<8889999:8898:84957555556566638322346333320/21104/1/0042/00313/01//.02200./0210/00/-000/0/0.--/..,,/...,+-))**$ $'%#    + 06236>J9!  #! ! !  ! ! """  !"!!!!"!""!"""%#!!#"dgddefkfgjjhnjmnnppoqrtttxwzz|}~Ɓmlmkddcc^\YWVYURRPNNKLJIGGGGFDDDCC@A=>@>=>>>=;<8?=;<:::;89;:;9988575774485554765561423353343122311/112112//0000002101/0/0000./10010//./..-21//00/-...--.-,,,)-*))( $%%"  + +    52287EL- !! ! !  "! " !!"!!!"!!!!%#$! !"!ddfhffihfiilklnnqnnonprtuvyxzz~ơfnomkhbb]\YWWSTSTPOMNJHJHHHGFCCCBA@ABB?>>>@=<><>:=<;999::;887:98877555954354550635432321114322122231101132101/11/000000/0/00.//10/1./0/./.,///001.../-.//.+++*)*& !(&%! +   +  + %4427?K@$ ! ! #"  !!  !!""!! !!!$%%# !eaddfejfglgjmkmnprooqqssuvwwxz{tnollfc`^^[XWVTRQOONKJGLJIHGFECCAC@A>@??>>>==<=;;>:97989:9<9968779855555455535524242232211332153232211120-2000//1//0/11///0../.22/./.+0/,.////00,+./../.,,++*+(+ $(#"$ +   $:237BKG%  "  !!"!! ""$%& ! !feegffghhikmkipmnmonopquwywxzz|Ġsojjgc_^[\XYUTRRQPPOMNGIJGGGEDCAAB?@@>>?>?>><<>;>:<;87999797769888488555545333332331143.4211124211214/1410001/0/0..2/0001////1//0.../1/.-.../......,.,.+/.+)+)%  %$#$   + + .:437BN6  "" $  !!!!  egdhfhfjlljkjmllnonrppqwwvwzz{}hqmihec^\ZYXUVSTRPONLIJHHGFEGDBABDB?@??>>==<<<<=8;<8<7::89675777967766543555332343322440231121121/02321.11001///01/0/0/0/////./000...-//--./..-,0.-0.-.,-++++&''#$&#  +  !:8119IH- !!    ! !!  ejibijhhjijjpmnllpoqprrtvvxyyz~~xqmmlgfba[XZWTSRQRPNPJKIHEHGFDDAABF>B@>=<><>><@:<<;>::::;96;7778676557567433434643533324221205210001/0/10110/2000.///0/-0./0//.01/,0./.-/0/0-,+,3....,,,,,*++)*#''('$%& +    160;7@J5   !! !!  !"  !" !!!!! eckeggigggkkjopolqorrqsttyyxx~~~tplmged_^ZYVSTRRPKOMJLKGEEEGDAACB??A@??===<==9;=;;9:::897976669866555742343322334321222222101111/11101/0/-//.///0/.0-////.00/0...0/.//--,//../-..+,,-,)+*(&((&%%%'% + +    8402?FJ*    !    " !! !$  !!ecicghlghihjklpqomnqorstvyxxyz|~ċnojif``][XXWSRPPSOMKJHGEEEDBBBAAC=>?>?====:?;;9;9;:;989::77:6656665555534433243232521333000011100/12011///,../0/-//.///000,././/1,/.----0-..--,++.,++-''()(&'%%'&  + + +   +%7133CIA"   !   ""  ! ""!!! !! fhdcefhhihgfjmplqnnrstttvwyzzx~ùipkjii`^\[XXTPRPNMLKIHIIFFECFABB>??A>?=;;<>=;:9<::::988999858786566555352443234332222220211/10000.10//00.//...0....0/-..-10...0///2/...1,/..-,,)+-,--))'"%('(((#&&% +  +  +*7/1:DI1' # ! !"! ! ! ! #! ! ! hbfcdhgiijklkmokonorpswwvy{z}}wppjkfa^]ZZWVTSQPNKJLHGFHDDCDCCBA@>>?=:>=;=;;:;:::::98;877879896565564544333533331113240111010/2/4/00../1//.///.//-.0/.1/01...00/./,-..-/-.,+,-.+)+*,+(")(('((('% +     13.8D>;<><;;:=::9998:67;78669875353464432254441213120321/0322/1/10/.0-/0/0./////.000,1./0.1.)/../.,,.-/--,0.++/-,.()($#)'&'+'('%   +   + !7155=E:,   " "!    !! ! !! cfehgiijgmkjiilkorqnqrtvvxxx{}~ósomjhec^_\YVSSRQMOKKKIGEDEEDEDAA??>?>><;<<<:::8;7976775676698565554644334354442211222111222211000/.0/1/./001.//.-/..///./.0..../.......,+,,,+,,,+(+*(#*((((('(&"  + +   + +  $6567BEA!  "   "! $$"##!!$!!! !!#!!dcddfggggijkkilnonnqovtwvxzz{{}jsnkggeb\\YWWTSRPNJKKIGEHDEFCBCA=>?A??<=;<;;;9=;:7:656876664555554543433423524332212211020010000/12//./-1.1//0.//0,.../..0.-..-..-,//..,.-.,-+,,++)())(('('''&$     +  +7479BG-  "   ! !#"!! ""! cfgfeeeghghjgojnooporpuvwwxzz}ƒpolhge_][YXUTQPNMMJHIGEEDFDBA>>==<<;;;:<88:87668776776545556433222211/225420021000111001//00/00///.//0-/.0./00/./-.-....-.-.0.,+.-,+++,-,**)))((((''(%(     @7:8;DG*  ! ! !  !!cgcgeglehigllmmmmsorstuvwwxyz¶gtmlkf`][\WTRQMNMKKIHGEEDDDC@C@B@>A>>>=B;9:=;8;596987656775555455553222234222311202012/001/2.001.300.0/.0-1././/.,-./+-,.//,/-.,.,,-.-,+-*,,-+)))""+)((()'&%)) +    +?99;;D8'   ! !  !! !deefbgcekfilmknmnmrssttuvywz{}nsolkaca]\WUTONRMLIIHHGEDDDB@>@?@?>@<=<:;=:=899;8889:866677554445541013242423110212211112.0///0.//////-/../.---0..-/,.,,.....-/--,-,+-,+,++**,+'(((()(('''&)  +   2><;:?F+,!      fecefflhdjjlnlmnnpqsrvttuwvz~}}nmlhfba]ZXVTQRQLKKIJGEEFDBBA@AB@A>?>?<;=9;:999:7:6888:766565453544356352424315034123211.0////../2-1-/./-///1/--...-/0.-//.,-/.+,*,+*+,,*,+*+,+('+''*(('('(&   + + 9><==CE5!      #aedffdfiiijkjjkmoomrqrtutwyzzàgpligba_\\UWTVNNMKJKEGEEEECBBD=B>@@>>=<;;;=8999;;8;8:877654266654143223222212432141101211/.-.0/0/././/.//////-/../*-/-..-/./,.-//,,-,,,+,+++)" ')'''(+'('''( + +  +   + + + + <;;=;D7*   !   !cbgfeeiikijjjknmooprpqrtuwzzz}}komifca_[ZWUTRPNMNLJHEEFDCADB??>=>>?=<:;=;<99998893:;67765454435225333122221412111131101.1.////0/.,..0..////,--..0-....,,//-/./-/,/,-+-*++*)&" )(('())(*''(& + + +   + + + + + +%38>B3 "!   ccchgdkfjjhijjhnopppssqssyxy}ztnojhfac\YWVSQTPMNKMHGEDCECBBA@=>@>@>:=<;;;8:99:89965395555554434432221212121332120//00/00.../00/0...-..-00/,....,--..--,-./,....,--./,+*))&$$)&*((*%'(%''( + +  + + *B?-   dhehdfffjhjikokllmrqqqttuv|{{{Ŕrmklga^]YWVTSQPOMLJHIDDDCGBA@A=B:==;<;:<8<::9999:785:4555559532383333323344341121001.0/01//,220///.-,-/.-0/,-.../.-/0-/+.,-/-.-,+,,.*.+)+($()('))))')))() +   + + + + +  (D?$   !!  !! ccefcefgfghmklkkmnpprstxwvz{|~¡qpmjgb^\ZXVSRRQOMKJIEEFECCC@A@A??>;<<;<:;::;8:8:8:8744445645645054333331212211000001/0./-./1.10100.,.,,.-2/..,-.....-.-+++--.-,,,++,++++%#%((((())*&''()'" +  + + + + + + >D. !!  !  bdhcdcdgghhkkmlompprqtuuyvxz}êornjde`\[YXUTRPNMKIIGHEFGCDBAA@@?><=<;<::::7978;7668655466544435433433231131213210.312..,////001.//.1-,../,10/,,../,,+,,-..../-,,++)*),(##)((()(()*(((*+' + + + +  + + + ,?B&    !   bdbeeegiiiijonomnnpqrrwutzxz}~õmpnjgdb][YWUTPOOMLJJGGEEDBBD@???>?=<@>:<:;8;9<:877755655669343321323232104/13120/32121/..0//..4.02..+.,./..-....-/+0/-.,--,,.+,,+,,)(/)'&(+((,)))()(()+,! +   + + + + +?=&  !!!   cbcddgffgggnmokmmnpoqqrwzw}}hsqjgea^[ZXUUTQOMKJIHGFECEB@@?>>=?<==?=<::998799:455874474371421422222021020220/020///0/.///1-///+-/-,.00,,.,/./-0/.+..-.,,+.,+*,*****+')*)()(('()((*++  +   + + + +  :>7!!    cagdfehigggikmlmmnptppsvxzyy}|ľ{splifc_\YWVTRPPPLKJIHFFEB@A@>>??@=>=<<<:98999695:6657847513653243323210102301150.////3/2101/-././,.,../--,,-,..--.-..---,,,,,*(*(,(*)%*(*))(()*(&(*).%! +  + + + + +  + A:,    cffdeggghehgomkmnmqqpqsu||}|żlolgfda]ZYVTRPNNLJHHGGGBC@@>?A?>=;=;>;<>98987768766855654624333334212210012202,3.////.-0/..-///+0+,./-./.,,,0...-,+,.,,,,,,**+)**(**$ +*)(()((()*'(().$  +  + + + + + + + + + + (I@&  !  dcceegjghfkiinnoqmsqupuwwxyz|µqplkgcb^Z\VTQRRNMKJGHEDDDB@???@?=/ !    "biddeiffhhjgiipnoopqssuwyzyz{}·osnjjja\[[XQRQRNKKHIGFDDCCA@>A;=?><=;;;;:::875676667554455532332220222221100100/01021/..0//0/.-,...-.//-.1/...-../,0--.-/,+),(+++*&+*))()))+)(&((((+*" + +  + + + +   =:7 !     !"!"dceffdeffhhikkpkmopqsutttzv|~~ssqlhea`\ZXXRSQOMJIIGEEDCCA@@@>>=>?;<;::98;68:76655653555414321221312223211//30///.2.0/0.///0....0,+1//0.../../,.,...,--.+++,+**(# *+)()+**)))()'(((*) +  +  + + +%=;&   !"  "!!!!befdeffgiiihllnlmmorsvvtuvy||}}ÿwrvkgda_\[XTRQOPKJIFEEEDCBADA?>?<<<><<9:89788;557558565435642423111112222212///////0.//////00/..-,,.-../.-../---.,.,,,--,+,+)*+(#(+*)***+++)+(((''(2) + +  +  + + + +=1  !  !"  !"!##deeeeefhiijjloklkmorrstztvwy{}~{rppdfab^\WUWPPPMKHGEEEECBCAAB=>=?;;<:@988;;87685745464444332320142/13312210210../-0//0//./////.-,.......-,,..././)-+,..+*(+++*# ('*)()+)())*()()(',2*  + + + + 49(!! !!!!" !!"#deececiciehhknfonnlqrsstuw|zzosllec^]ZXURSONLLKIGFEBFDCBBBA<:<<;==:97;88:88755945744543201270313/./02111/000/0/.+0//0.../0--+///0..-..--/-...+,+0..+,+*)++% ()**+***+*)++))('((42   + + '5#  "! "!!  # bdfddggfghjiiljlloorprtuvyxz|~tpslfb__ZZVVSQONHKIGFEEFC>@@@>==:<;::88;8:76877748545544423534312/2///0122000002/../-///.../-0.,-/-.+,-.0..,.-,+,,,+-,,+**+*(()(-))(**))(+)*))('/4." #$ + +  + 20$! !!"!!!!!!"edddgeefgfjijkmlkmqopqtywxzzy~qqmmic_][ZVWPROKOHHJFECDBBA@@?>=@>:;;<;88:9:2:77545725243443321322311100001//0//11//../01..0./+,.-.00,,-.-//-.,+,+-+/*,*,*'&%))*))))*))**,))+*))11) *,) +  + 1+ !#!!!" ! dcddejibfhkhijkkronorsuwt|y|}žopngifa][ZZTSOMLNGGGFDDBA@A@@>>>;=>;<:;9>:877667645425606251352120/020/0/0./13/0,.0.000.//0.-+,.,,./.-,,1/-,.,,**++-,+(,,'" '+')**)((,))+)*))))(+14  /4)  + ,/#!!! #"!! !"! """ $ecceddfhhhhgijkknmnnqrsuuv|z{{¡msnljc`][YWTRTMLIIJFEECBB@?@@??;=<<>::;:9:97677444633533221433420112320/010/..00/00/0......,--.,,--,-+,-+.--*+,--+,,+)+((&&+*)*)*)(*)**+*)))***+21   36 + + + + +(# !! ! !abccbefggghiihmmnooootpssx}{|}¦kstkhc`^[ZWUOONPJIGGFEEAAAA@>@=9?=;;=:99::888563576192226122232221121110//0/0/0/.//./..1/......,,--,+.-+,+.++++-+,+,,+*+# %*+*)(()))(*(++**)))**/4%  84 +  + + %%  !!   aacbcedffjggkmjjlopronnsv{|y~©psokhcb_\[XVSONLLIHGFECCDB@@AA?==<;:::::9987575984.42332222223202/0001100/0/1/1//////.//.--..-+.-,+.+.-+-*+++,++,+)*,)%*+*++***))))++++)*+**)*17"  7J+ + + + + + + +! acaaddfghfijiijjnoqnporuuyzz{~÷lvpljcc_\ZWXTOONLKIHGFHDBAAB@===;<;:;<;979877557445733523335200014101002000/0//0.../,/../..+---..-,,,+-,+-+),,.-,*,*)%#%*)()))******++***)))**)/90NH+    +     dbbedefhhjfgimjklnrpqpqts|s{~÷nuqlje`^]\XWVSQNNJHJHFCGDBAA=>;<<<;>:997<997755357463533335/5000.210000.001/-/.///0/./...-,,,-,,,-,-,.---++-*+++****$#$)*)*))),++*)*+,++)*)***,49&*RO( +    + +    bbadcddfighhmjkmmmnpqrwwqxyz~³lwqljfb_^XVWWOPNNJHHHECCCD@?==?<>><;::9:795966655554472332125122/1230/00/100//.//.-././-0.+0.,,,-,-,,,,-..,*++++**.%#"***)))++++++**),*)+*)+)*/29 ARP  + +  + +#  bbaddeefljhjhjmmmnnmoquttvvyzõovrljhe`YYYXUPNOLKIHGGDBBB@A@=?<=;=;:==89985894457445453422210111/0/0//000.//////-10/.//.--..+++/-.-+,-,,+*++*+**+("&,)+***+**+++*(+**))*+*))+/59UYD + + +    ! acdcbbcgfkighimllmoooossvxxy{}~¿ownnjic^]]ZWRQRLNJIGGHDAAA@@@?>@;=;;;::98:888544588545432212231/033///0/00111/.0///..1,2/.0,/.-....,,,.-,+***-,*)!)+)*-,++*-+))++(++*))+*)*))-6<5@d[ + + + + !  dacedccgfigiiikimmmqpoqtxtzy|~²nuonkgba]\ZVSQOLKKIHGEFGABDB>==>=;;<:99987;:655665445322221121111000//0//0021/////./-000/.+00--.,.----.++++++++(# '+)))*+***+,+*+)***)**++**))/B>><<<:;:::7;896935656415433211111/3101101///00.0/../...01/..-..../.-...-.-,+++++*%*)*)))*+)***))))+,*+)*++++),)2F7/pnD  + + +   ! b`aacedehffiijjjmkomnprsuuvy||³mvvloidd]ZZWRPNNNKJIIFECECBBA?@>;==<;;999;<576774654335333211122021/00//0/////..,.././10/.-.//....,-.,,-,+,,,-(#,**()**++***))),**)++)*+(+**,/:H4Eqq# + + + +    !" ! babbdegeehgfjimklklmmmqrtvty{~~ƿpvrnjfc^]\ZVSQPPNLIIFFDCBC@@D=@><<<=:;:98898855374566334441300112010100111././0.-///..///..-/./../0-.,,,+-++-,$**((.(*+**()*)(+***,+))*+++**)3EF,Rld + + + + " !! aaabdddffghgkiijlnjmmnqtvwww}~Īsuqplg``][[UTRSOOKJKIFDEEBA@@A>==>;=::9879988575545433345410111/0/2100/.002/0.0//.......///1//./.0..-0-,.,+..*'++**)'-*,++'++*+*++-++++)***+*,3LE'[gH  + + + +  "!" cachccddghcgiihijklklopsuvvvÿuyqqneb`_[YYUSQNKKJEHFCDDA@A=@>==?::;;:888798845535454322410000010/30000/.1,./000///-./../1.2//0000/2/..+,,/1++*++*)++**(++*+,))*++++****+++.BIE1np3 + + + +  +  +!  `aaabddefchhihijklplmpqstuwxzſrvtnria_aYZTTRPNNLKJIEEDEEA@@@?@<>;:9:::9677777586442533/23221033-/10001///0.///./.0..,-//1011300110000.,-.2****)))*(+++++,,++*+)++++++**+++5IJ3Xtk  aabcbbdddgeghjnflnnlnqpptuwwz}~ƿtustlide`]YUUSQMNKJIFIDDECAC@@>@@;;:<:99798776776653434121301012//0/02,.10.-/./-../-...-1/01003223232511/11/+)+))**))++*++++-*,*,(+++***++,+,=QM.!ftV  +  +   `a`dabcdgfdchkjinhkkpoovtutxxx~ſvsrqmhgd`aYXTSRNNKJLGIEECDAB@@>=;=<::;;88887665655543323601101222101/.20///,1,.1,//2..00./0/02047667663685B,++))**++*)++,+++*.-+++*)***,,,,,*SY>"4rq= +  +     ``aa`dedddggjjilkklmnnrptwuvxx{}ſwtrqkedb`^YXURPONLKIHGEECEAB?>=>>=<<:;9:96976749345232244312124111/10/0/1////.-././/--.././/03459>;:99:::97883845244532/223321122120110.-/0/03,.//././.,././/1349>CDB2If{D $.+(****()*+))+***,*+-,+*++**+/++,*>>==<:::9<78886965573433333221302121010/////0/0.2/..-0.,-./--,+.-.36?<==<=:;999:677767435142230201002/10-/0/////0//1./--/.-,,-/.,,,,./14:;P7313//--+++-,+*+*,)))+)+++*++,*,++,++//?f_82|R    + +!```caccdhedhffililjmmmnpspttvyz}}İzzunjed`^^YXVTRPLKIHGGBBEDABA?=><<9:99::98776665475333223121110///00/0//0//..-,.,...,...-/,,-.-///4*Q+;<831/-,,+++,+*),))*(**+-)++-+.,+,++--4Xh_+Mv= +    `_c`ac`gbdfcggggiklknmnppqusuu}z|x|zrmjgd`^][YWSQOMJJIKGJEBCBAAA?><=::9:99887766654434342203/20101///0/0//-../-,,,,,.-...,,,-,,.1.-/--Fk ,;;:210-.,++++,,/-(+)+*++**+++,+-,,++.18_kF&jx" + + +   __^`bcbeggffeeggigfolmnotqtvvyy{|ľx}yojifd``]\YUVSQNLKHJGLEEDE@@??@?<:;888<88886381544145/51210200/./00000/-....,.,,.-0+//+,+*++.,+-..,Au'-5;510/-+++,*,,'/))++,*),*++,-,,-,,.00Fjg8'` +    b`bc`bddhgfjdefggikmmpmopputvxy{~ÿ{zxtqmihed]\]YVTRSQMLKKGIDHDB?@@?=;;:::888:99764744342443111100300110////..00-./.-,-/---.+,,+*+*+.0--.4?!,:8521/.,,++-+,,-+**)+++,-+*+-,,,--113Zqb3R;  + +  a^b`aaaceecdgghfhgjkmnqmpqrvwxy}ĵx{yxrlkgg__\\XUVRRLLMKIHDEDDAB@?=@<>;;:889:8966536732543213110001311/0./.00.,/..//,/,,+.*..*,+++*,-/...7$075230-,,,+-*++**+),**,*++.*---....46ms],xv + + + ! ebb`bc_`ddefefgggikkjnnpprsuvw~|Ů~{{vooiicd^[[WTTRPORIMIHHIDACB@@==><<::9999975554444434422110.100.12001..0//.+././//---,,/,-.,++,*,,,.-0#))12/0-,-++++++,,**.+*.++,,+.+-..010>vvI!:c  + +  bafa`^aacbcbghhggjkkkooopqvsuux}}~åy{{vqliea`\[XYTRPNOMMJIIDCDEDA>>?>=<;:9975788654755564313424220231110//.0-/./.-..//-,.,./.,..,++,++*,,,-$+*,//-+,+.+,-+*+,+)+**,+*,++//../050Xz;TK + + + + + + + ^b\`^_dabedcigfggigkjkjnmqttsyxy|}Đzwwokkea`\\[XVRPNMMKIIHHCCCCAB>>>>>9:977977885526541332041020111/1/..../..//./-/0-+,+/0+.--,-.+,+**++.-%#**-,+*,+,,,,-))),))*,+,,++-/0/.1521mi3! r}( + + + + + + `a^`aabbbbddgefghhiijlnlloqrvvyyz|zy}someg`_][\WTRQMNLKJKHDCBG@@@B=>==;9::467748653734322323322221111-0../1/1.///.,+/,-,.,/--,,,,,**++++,,"(*)))*,,,+,-+)))***+++,,,+//+./136?^1"/d   + + + __b^^`bbeaecefdffgigimmlknportwzz|~ĭ|}zwsojgec]bZZXTRSNLKLKFFEEDBCB>?=>=<=:87:7667765454222022/2322110//././.1/-00///-+,,-++,.-,.-+)*+++*++)++()+))))*,,,+**)))))*+--,,--/./0252XT+KW + `^``_`bdeebbagdifhihlkmpnnrrrsvxx||Ô~|urnhgeee^[YVTRPONLKJIFEDCDCCB>=<=<;;<<887677555553333335123211///0/0.0.1.//0--./.+.0,.+,,,-++++)+*++(,+$&))))+**+*++*)))**++.,,--/.00/340lD% m7 +  + ``_^a_a_`bcbdedeffekjmmlmnoqrruw}z{ÿ~xvpnjggf_\[UUSRONNNHHHFF@EEBC?A=<=<<:::88877656643534331632121201000//../0.2,..,-,++-//,++,,+++*0)-*,+**( ()+*)))*)+)**)*++,,+,-.-/4/17366t8% 1 + + + + + _a]__ed_bbdcc``fgdihhjlklnoqrtvvx{|ë~|ttmmkfb`]ZXUVPPPPKKHIGFEBCBBC?><;;;;::97797767544455411111031000110///..0/.-./0-+--.--+++,,++++,*)++*+,(%*()))(,*)**++,.++-,,..000255:H[/! V[ + ^bg_]]^`c`ccedhffdhghiikkloprruvyz{|Ęzuqnjgeb_]\YXTSPQQNKGHGFDB@@A???>=<;:::98777665856555450011311110011././////,./,0../+,.+,++*++-*,),*)+*)))&)'()())+))**++,././/1123652xI%"!wA + + _^_`_`a`baaccddccfgihgikklmprqryxy|{~ǻzspmkgd`_\\ZVSPPLNKLIGFGEBAAC?@>==;;9;9988997774745746331012131221100/0.001-.-1-/,.+--+,,,+,,*+,*-(*+-+)*,&''('*+*))()*,**+,/.//253799CD%#  6( + + \\^__```_`b`dcddegfheghjklqmpqstzwz{|~ǫxunlkgc_^]\ZURQRPOKLGGIFDCCB@@?>>=<<;;98989877896556533241121123030/0/.0/....//....-/(+-..,,)-+,*++++*)+*++)"'(++)**)(*,++-./.445::6E@&"! "Ps + + ]^^]]`_`_abecadgdbecghljkklporruywz{Ǟ{}rnjiicb^\[XUSQRMJLIKIGHDDA@B@???<=;:9987698785554577244414.01211010/001//./--....--+.-/-.,+-+,*+++-*,+*++-+'" (+(()*.++,+,//-5487:5jk)$' !#yM +  `]]`]b]^_bbbaagdehghefiiiinnosuusw}{}č~{wtolggdb][[[UTSQOLJKIJHFFD@F@@?>>A<::9989985676665548433121105310000.00/2/./.-.-/...,+.-,,,-*,,,,++++,+,+,)*++) !(')++,*,*,2154>=7P/*'" "$/-&! + + + +_][``^^b_ba`aaagfffeghhhinkoootstywz|ȱzvtpjgfdb][[UUTRRNLJJLJGEEDA@@@@>><:;:;:<:98:7755464545532222232200000/1.../0.-/,,.../.....,,+++++*++*-++++*+,+,-'!&$**,+*,.145:AC˜T-'$"!$"N{ + + +   \^a__b_]a_a`a`acdghfffgjkimnooqqwwwu|ǟ~zyvplifea_[[VXRPPOMMKIJGGFDBBA?@>>>:;;;;::98866665374544421111332201010///1///.--.-,,-.,,+.-,--**,+,+)(**++*+*)*,-*"%*)*)*.33;5d7-)$"#'vK + ]_``_`d_`^^^`bbcccfffeghikhoonoutvxw{~‘}~vrnnkgc`^Z\[XVRNNOIIJIHEECBABA?>><=;:;<;<988766875665442611251322121100////0/0./.,-.,.,,,.--,,,++**))))--))*()++,..0*'&&((126.r=()""$'+1! + + + +]^__bb^]_]_a_dbdedffgfgjiillnnqtrtuvv|ʳ~xxonlhfad^\XYVUSPPMLLJLFCECCCB@?>==;<;<<:::9876684555634433221253211110003//0//./+.,-+,,++,,+,,,++++)))+)**)**++,++*,,/-')+*5)ǭY3.*"#%$Lj&" +  \]^b^`_`__`_`abcbeeegghhihmmorpsusswy{~Ġ}ztnpkebd_^\YVVRRSNMLLGIEFCCDAA@A=<>=;=:;:999:4865555565533534223321102010000/00.0.//-..,+/*,--,,++,+)+++**)*()++++,+,,,--,,)*"D(+*#$*sY" [\_]`adbeca_`aabdfffefeghjilmmoprts{xy{ȿ}}yrrlkhhce^]Y]USSQNMLKIGHFGDEDA?@?=>=>><;;:9968775558734563514433210/01/00001-00....0+...,,-..-,,,.,**+++,+*).,++++++*+++-+,,.0.)! +9%,(&%'(/;! +Z^^\^__eeb`a]caccccfbefghhkmnnopqrvwzxy}~ɭ}{vrpkhfccd_\X[TSQVMMKKHDGFDCB?C@AA?>?<<>;:<:999767687856534334312222010002210//0-/....///,0.....,+,/-,-+,++++*,--++++++,*+-,.//01110::99065H7-"#!$#%)r^### \\\[^[]^^^cbbc``baedcfdhejkllkpntrrvwwy|~~ǻ}{uppnlfda][[ZWSRPROLMJJHGEEDA@AADAC?=>=<<;9:8;998768561682443463413410000/000/000/0.../...-//...-./-,/-+++,,*.,-,,***,+,++,./-/016335<=?>ZJiR-$""#&%2O$# [[_Y`\^[^a_aa_a`bb_cdeffhgjmmkmomrtouwyy|~ʟywtomljhca][[YVTTPQLNOLKIHFEDECCC@@@=>==<<;::999999766774354555355233230220321/1/1./..//-/+0+,-./,-,,-+,+,+,++)+.++.++/-+-..///0246459;=>CV;އ5'$#")'K-$ ^[\\]]][`^`cc_beaecageeegfhjkkmnopqwxutz|}{xuspnkgcaa^^Z]VTRPPMMMKKJGGFDCEDAAA?@><<<<:<:9999:8668674556351534222122/11211//./0/./0/.,./+/-,+-,+-*,+,,,-*,+-+,+,)*+./..../0223568;BESIwS8E.(--%K&! \]_Z[\[\^_]b_e_bdccbdccdfffglkmionntusux|z~~˽~wyrplkjfab_^^ZYXVUSSONNIIHKGEDDCBE@@=A>:;:;::8987777776544544544333212321010001100001/..../,-,*,,,..,,,+*).+*,+-,,)+,//-0.00124778<=AELS?YGD7-/#E1"(# ][^][[]\a^^^_acdbcdbaadddffgiilmnqnqqsqvw|z|ƥzxurnlihgcb_\[ZYUZQQPMMLKIHGGEEBCAA@@>A<><=;;:::9;8976777465444455464343242321/010111///1//.-/-/,/,,,+..-+++++.-*,+*-+,*,*+/.0.0245;7>=@DIM[L?J:510*hs*$ [\Z\Z\[^^^___^`caaddaaaaegdhhhkjllpopqruw}y|~ſ}zwvqollgcd^_]ZYYXSQQQPMLLKIGHEEDBB????>>==<<:::::;;876776965626556445433023242233101001/0/0//.--/,-*,.,,--,,*+-,.,++0-,++.,,.,.04477:=>BHMTRrqFI>85;/^"(% \[]Z\[[_\_]b^`\`b_`bbbcbcfdigghkkklooqrvvxy{~ġ{yvrponifdab_\^ZZWRQQSPKLLLKHGEDCEB@?B@?=<<;;;9<99::89878767383333434554342043221104000020/0/.--.,./-,,,..,,,,+,-+,,+-++),,-.../14579=>?GKSWZYHOC985>Ħ5',% [Z][\YZZ`\\[^_cc`a`dacbebfifggiiikllopttuxzz|~ƹ}}xtqnmjjfc`e]Z][YUSRSPNOMKJJHGEGDBACB@@>>>;;;:?99:9::4877585635347525544224323232222/2/01/021./0-,/.--,-.,-+,-.,,-,-/,,,-,,-//0/2457;>>EJRUYWNJHD;?2eƇ(-(" + Z]ZYZY[Y[[[`^__d]^__ccdgechefkijjklmpouquvxz{}~ŝxvsnnmhged_^_^[YXUSSURPOPKJJGGFDFB>AAAA@=<<;<>9;:9998;8677876673444344520233335/030/00100011.,.-//...-+/.-,+,,,.,,/.-+,+.+.../024359?@AELTVZlڌMOHB<82ĺe$-0)  + XYZZ\[Z[[[]^_a_^a```aaedeccefigikllnoopssuvzy||Ƹ|zxqpnkjgdfc__\[[WVUSTTMMMJIIHHFEEDCABA>A>=>;;<;:<::9>8998:68876555245485025242243102110/31/01,.0,/.--..,-.1.0,,,2,/...-,-+-/.-//02369:?AFQ]_[pOTG???KǦJ',) XXY]]^[][^^_\`^`]__``cceedcefghhlkjqmnqqrtuvz{z~×|xvrnmmihfca^_^]YWXVTSQPONJIHGJGEEDBBC???B?<<=:;9:9::9:988978666554446344442423233502010../1///./..../0,/-+--/,,,,,,/-/,+-,-/+.//00248<>AMP[gUU\VHAA=g̔-+.' YZYZ]ZZ[[]`Za^]]___adaedcccdeghihjjmlonprouyxy{}Ū}z{urmljjfcaaa]^ZZYVQSRRMMMJJINHFFHDDBABA@<;<;;999::;99878776565455536432432233205341012/0/2-2/1,/-.2...//.-,,.+0-+-,,,,.0,/./0012259;?NU^^u\[LED?9v'3+# WY\ZXY[Zb\]][^]\____baabdddhchdkjlmkmlmqpprsyxyv}Ƽ~{wuwnnkiheca``^[ZYWTWRRMNOMKJJLIFFFCDABBB>>==B<;;;9::::7:8878876765644735446123522341112/110131/.0////02.....----..-/-......,,01,11122337;ET`UdhGHGBFϳT'3+  XYYZ[ZZ[Y^_\]\]]]_``aaaabcdddbfhghjijkmqorpuuwxx|›}{zuronnjigdc`d`][ZZUVRRPOOMLKKJHIGGBCBDA@?B@>><<>;:;:9:::;876896554445524452434230421121231321/11201/.///.-/...--,,/.0...//1.///10220225558>H]Eec`KH@@g͚9./)$  ZXZY]YY][[[[[\^]^\_`````bceeedeffhjiijknqopsxsxzz}Ƭ~}vrpoojigdcaac_Z[[VZURQPPMMKJKIIGGEFDBAFD@??>>>=<<;:8:9899888775456655687654431425434223110302.1/0./01./-/-//---/-.1/.0////./0/1131063355689`_ZMKGAʄ+6-(!  ZY\ZYXX[]][[[]]\]\^__^a^abcbdgeefffjmhkjooprutvw{z~~ƶ}zvssoomjhfedc`]^YYYWUVWOPPNQHMIHHHHECCCBD@@>@=>=<=:;:9;9:::;8887756655556563761232423223432124111////000..01/0/1,.-0-..0.//0-/03103366665678<;53T_VHFCLR*5*%  YZZZXXY[ZY[\]]^\^\]^]^`^_acccdedegfgkihnkmpsrstvy||~~˜|xspqnmmjfecba^^YXVXVUUQTPPOLMILHGHGGCCBF@???;?@=<<<=;9:::9;8778786665756654334425542213321221120///10/0.,111/0-.--.-...,0///-30243369::::::9=;8"AV\WKEE8g֣;/7.#  Y[ZYXYY[Z][V_\[\\]]]]``_^b`bcdbkefhfijlikmnotpuyyy}}~ħxvtstlokjgdcca^^YYXXTVSSTQOONLKJJIGFEBCBC?@?@??@?=>;<;;;<:;888777657765545445443423352322413422220//0000//00./0/.../-0,.-./,011132336:<=AADBAF<>;9-!:HMFED2zׅ.78'! +YZZYYZZZZ[[\\]Y^[\]`^aa_]^abbgdeeiiihhjijllomprutxy}~}î{ytsppljjidbcb`]\Z\WWTSSSQSONKLNLLJHGFDBCBDDA?>>==>=>;;;;:;9:879787678855654413433443242321153221100/0001/////.0/..,,..1-,-/0002122346:=ABLJ~m[RJKE?8:;BFFEADӼk*95% YZWYZZ[[Y[[][[]\[\\^^a^a`]bbbcccefhgmigjjlnnqpqwttx|}}ü~xurqqnmjjfdbaaa^[ZXWVSSSSOONMLJHKKIFEFEEDBE?A?>>====<;;::::988778677777551433443433453312422231220201/00//0///./...-1-.///.//011122568;@CGMeZZWVVVC?AEGFFXʭE050"  ZYXZZVYZ\Z\[[[\[\[_][_^_aabbaefefghgggjknnnnqsvsv}~z|}wtqqqkjkhfc``_^]ZZYVUSTQSTNMLLKJIJJFFEEECCCBCAA=><==<;;::8999976795;664565645346533433333133222222/210001//./..-//...-0/.0/0/101223578>BDJAjvy]zhSD?CFGGgʑ*46)"  ]XWXXYX[^XY\Za[[[`\]\]_c^``aadccbdedegihjlmmkoptqwuvy}|Ľzyspqnjnihfec`a`\ZYXYURRRQQNMKKKJKJGEGEDDCCCCAB@@@===<>>::::99;887769994568:7463544234432342322312121002001.1.3020..1-//-././02/0151378:ADFTKƨb|jh~bLFCDKFzh+52%!!Y\WWZY[WY[Y\ZY]\\ZZ[]]]^_^]^_aadebbdchghjllmrppnqrwwxy{|ľ|yvsqrmljkgecda`a\\Y\XXWSRQRONKMKJKJIHEEEDCCCBAAD?A@?>?>=<<9::::8977776857456764444544332432233322021031..1010.,../.0/.-,-..-.//012342878:?FHRdʑzkm[PUMFFIHêI&3.#  WVYYZWYXW\ZZZZ[X\]_\][]__]]_`_a`cbdgfdfgfklllmnoroyyyxx{~~|utqnkliifdfaaa^[YYYVWXTSRQPOMKKLKIIHFFFEDCAB@@A@@??=>>=@<;>:98<898797858665825535553444334234231330130.1///2///01.../.../0/1,2.0012355:;>>=<<;>::978998777779555664334464344343321344022000110/0//0,1///..-.0,/--/20/0124467}{a{qYROOPLIFm{!64%XXWXYWXXYXZZ\ZZ[[Z`Y]\\_a^]`````adcfgeggigklllmorsquvyyz{{~|®}|zyqtnmkhigedba^_[Z[YWVXSRRPPOOLNLKJJHGFFGEDBAAACC@@?>??>==;<::99:99888765556565655445543344333241304221/22010/.000/.0.0.//-/-3//./01112347;>CELDzsmrYFFLLPPRUO'13#XYVWW[XZY\WZYZYZY[XZY\\_]_]a[bc`bccddhghgigikmnnsrpsuwx{|y}{{xytrommjihgcca__`^[YXWWZUSQQSONMMKKKJHGFGEGFDBDABCB@@>><<>;<:8;:::::98787848565557553642333353202123411141112/0.././////0/-/////.02/11214345:AEDU_Εnx?>89;?GDX(31'"VYV[WXXX[YYYYXXXWY]YZW^]\^^\``_acbcdcefhhhgijjjsnooprvuuzwyz|}{zzuupnpkkigfibd_^Z^[[]WWVVTSTONNMMJJMIIHHJHGECDCABB?AA@>>?<;;;;;<:<:::886:95566455564375564435223332522102111000/000/1-1.0.200...,.0//01043336:@ELLjyrs;:7754<8fy".0%WZVYYXYWYYZYYXYW[\X\ZZ[Z[\^a^^a`cdbcegfiejgggjkpnqnnqststyvw~{}{wxuvqmmligfdee``]]]ZYYVXUVURQPNNOLMJKHIFGGGGFEBDBA@@?????>>=;:<9;;:<9<:8777877656555364545345422423323130221000/1/0001//0.///..../0../0/1124477?BDLKʾn}v]8;775496}V%1/#UYVVWYYYZZ[Z[ZYY[Y[Y[\[Y[\]]__`a]eddgehggdeghjplllmnnpqsstuvxy{||~z|ssrlhggffec_ca_\]YZZWVTSTQQPPNMMMMKJHGGGFEGGEEDCC@@@?=?@@?=;<:<;;;::8998777776755455455544441324262223112/1020/0/001.//..0//...-.,.//-/0024468=ACMGƳtxwI=897474?6,0+VWUVWXXZV[\T^ZW[XYY\Z[[Z[[\\^```abcbddefeeffgjjjokmmmlqqruusxyz{z|}|xvrtokhffedccb__]_]ZYXVXSSSQQQPNMLKMJJIHHHGECDDGDDCA@@A=B??>=<<;;=:;=:;699:7875756665554445445616143512342300105/0/0//./0/.-0../-..////3.00133459<=AGSǒomC;877474W!0.&UUWUXVXVWVYZZXYY[YZ[[YY[[[\^_Zb`bacbabceefhigjjikhokmppppprstwyy{}zvvqpqojfeddcca`^^\]ZWYVWUUTRRNPPNNLLIHJHJFGFEECCEBCA>@A>?=><=><;;;:<9:9::68:687;6775665355454454331322242352102032/2././/0-/0/-//-..-//////133465:;>BBct~ni6<87655-vX4(#VWSVYTWVV\XXXXZYY\ZY\[\[^`\a^`__b``aaaadeffggdijmmilnnpopqprtvuxwv{xxvtqonlifeeebca__\^[ZXVVTSRRQRPPMRLLJKIMIJJHFGCBCBBBB@@?>@A>>>:<<=;;::99999:96877756565665445543654453442122210311/13//////0./..-//.-.///00//323457=6(*)!XWWVXVUVVXSV[U]X\Z[Z[ZZ[YZ[][b^a^aa```bdeeeeffhgilmknlpoopqpquvvvuvx¼wxuromljhkcbbba`^^ZY]\WTUTSQPSQNMMKKKMJIHHHFFG@EDCEAG@A@@>@A=A><=<<;;<9998988888777:965644555555443444445222222211221113/////1/.2......-./.0.122234679>AENLilr{R;;87624D!4-$ WUXXXXWVUWYTZVXWXZ[Z\Y]]\[^]^]]]___abaccdegedghihigjkllnnnnooqxuvvxwx~~uxurqnkkffbabb`]_[ZYXVVTRUTSQOOOOMLJMJJIIIHHGFFFEBEBAA@>?>=?>>>=>=;9;;:999888878866675664454565562243334223220221221100///////0/.,//-.,,0/../00/121456:A@INt:O[vx:;876542li",0#YZVYTVV[ZTVW[XV\VZVYYYYYY\\\]]c^``__bbaacdddfeekhhkjilmmmnopnnoqrvuw|{}}nvstpljgffca`_a^[[[XYWWTTTRSPPONMJKKKJIJIHHHEDECDCDCBAA@@?>?=>=<=<;;;<::9:9878888856667856755565524513422443331220112210/2////0///,0/,-0/1/1...3/014347<=?IlcUTdue79876538B"1,"[VYSXXZZXXVZYYXYYXZ][Y[Y[]]^^^_^^\_^a]baaadceeffjeghfjlkmlolmmmoorsvwuwwz~|sutplkhfccca`_\^Z][XXVTTSQOQUNQKKLJKJHMILGGLFGECCCCBBBBA???@=@<=?=<;<;;:;=;9985788856776576655745453235135244311221111021200/0//-/..-1./-,//.-/0..012338=>BHkxcrzP9887686I.-0'WVVUVXXXWYW]ZXYZXZ\ZZZXY[][\[[_]_^`]`aab`e`bcceegfhgghilkmkommmpnopusvvuzy}}wwuqomggfbbba^][\Z[ZXXWTURPPPQONMLLLKJLIIIHGGDHEBCBAB@@A@??@=?=>=<<<;;9<9:8;898;776:78866766555434444423344302331121120111011///..../0,,.///.//.//0/1.0348<>ALn|mD7777655ft.1#XYVVVUXXUXXXUXWXYXYX\[[YZ[\`\`^]^W]^`caab_abeddfggiggiijjijllmnmmnorqtuxvww}zuvrpmkifccc``\][Z[ZXWXVTSRRPOOONNMLKKIJIIHGHHFEDEFCA@@BB@@A??><===<;;;;<988888888777685977675555544444466554363133111102.010100..///...-1.../0,-/-../,12259<>AOpnwjx>6787597N&10&VW[WVVUUTVWVZWW[YWYYYZ[\YZ\[[\_^]bb_`]_dcabdceegljiggghihhjnllmlllmorltstu}x}~}suqnlmheba`b_`[YYYWWWUTTRSRRNNNNMPMLJIIGJIHFIEIEEDCBAD@DA@@??>>=<:;;<=:;:9:8877778:757787776546665555344123533212511211121000/3.0///20.-.0,1//....-.///10599;A?_Yiisf<77757;M/03&"YXWUWUTSUUUVXYZWZZYXZZYYZZZ^\\[^]]\``a_`baccbfeijmggfggiggkikklnklloorrqtwsxwxz{~vusmtmhhfba``][\^ZXXVURSSRQQPORMKLNMKJJHHJGFEFEEDDDCDB@B@@@>>>=?=;?<;:;;;8:899879677:787678665545464444323412445125-522/1311130/..0//.-///.-..-,...,-././125799==RjawxX4786791e|!21$YWWVUUVTUVVUWWWWZWWXYZ[[[ZZY[\\\[```\^b`c_b`abbchiffffhgfhhhgjjimnkmmnooqqsrwvzzz~}rvvnnjigba^`^\[Y[WYUTTQWQSOQONNMJLKJJJKHHHHDDEEDDEDCCA@A@A>=?==?=>A9>;;:<<<898887678797655666655545455533320424341044211010300///000//.1/0.././--/,..,../1025678@?U!70#UYVXTTURSWVVYZXXWXX[Z[YYYZY[_Z\[Z^\U`_`]a``cadabbbcdeeedefefgghiikkkhomqqqpsrwtxx{{}ÿzrspnphfebe\]_[[XYSYSSTSQOROUMLMPLKJJJIIGHHGEEEFEHDCBCBBA@=@>B==>?>==>:=;;<;:9778:978766949865555555355563332502233421/0223/320002221./0.10./.-.....0,-..../3236548TdKK>R];555439B4.2)UW\XUTUTUWTWVW[ZWXXXZYZYY[ZZXX\][[\\`]\]]^_caaac`cc`fdcdeffeeihijkjmlnmmmssttqxtxvzy~}~{uwqnmjjfeaa]^ZZ\XVVWUUQRQQQONLMKMHLHJJGHGIFDLDGAEEBDBAB@AA@?=>=======;:;;;::;:99886:8778667556565646752544434442222222213121122000/0/010/00./-./--//.--/.1..00/2577:_JSI5<:4334297[(/3&!UVVUUXSWVUWWYXYWYYWYYUYXXYY]YYZ[^\[Z\\^]^^^e`da`bacdaadegfggdeihhiijjimkllpnnppsqtuvvz|~ľvwtvpnlkgda``^\[ZYVXWWURQRQPQNNMJLLKLJHHIHGGFEDEGAFCBABAB@ABA?==>=;><=<;;:;::<:9:99:7959775556556675474603434343322212531111101111142/00100/..1.-++,-.-../..,.,//0356;Ar6P=5=62123337tX"/-%WVXXUQVTSVWWXVVZYXZV]UXWW\YYXZZ[[ZYZ^\[_\_^```ca`aa`acbcgfeeghekfghgiiiknmmqnmpqtrsssu{{~|uxvsrpnlmfb^`\_[ZZYXWUYVSRQQONQMMJJGJIHHHGGHGGDCDDCCCC@A@B>BAC??=====<<;<;;:::9;:898998958777:946554247543344444332242344320320011000211./0/0/.-0..-.+--0../.+.../.3455:>ydEC6;;3.02436<7&/,$STXWSQTTXUUVVVV[XYYYWWZXXYYYYZ[ZZZZ][\b\`]`\^^ba``_``^_aedcfdgcdhjgfgiigikkljlmsqqorsstxx}{~vwtpplnljfd^_\ZY[YYYZUUTSRQPQNLMNLKJIGGHGEFEFFDDDECCDAA?@>>A????=====<==<::<99:;:;7;88887676884555555553443443134321222242212121111101400/1//.///.//,././.-+/*.,--0//2344WK7:8881//0041Q&,/*TUUSTQSUTTUVVXWXVXYVWYXWYYXXY\W[Z\[][_[[]]\\]]_\`__a`_acacafdcfdffeegghjkjjjjnnmopoqrqwquvxxz|}|twxqplkifigd_`^YZXYXVVTWTNRQQOMNMLJKMKGGFFEEEEFDBCABA@B@AA>>=?>>=87575../0.4/pa'.0(USTTQWXUTTUTXVXXXXXWXVXXWZXYYWYZZ^\_\[Z_X][`^\]]]^^_``_cc_cbebcccedddffjggighjkjkjsnpopqusutwyy}vusrooljgehcc`]][ZYWWTWUSRPPORLOMMLLIKIIGFGFFDDDDBCDC?C@ABB??>>@>>=><;;<;;:;;::::99;;:9888865655652335464442524533141332221004221132221110120011//..//././,-,.--1+-../00114.9W^>B6363,100138?$00!USRSVSSVXUSTVUWSZXYUWXWYYYXXX\WXZ[\XZ]\]\[Z]\^\]]^^_`_`b_``bcdabbcbfcdgfeffhhijihkmllmopqrutxvxwz{|sttqrpnlkghbbdaa_]\[ZUVTRRQSROPMNNLKLIKHJHHHGFDECECBBBBA@@@@C???@<=@;?==;::;;:<9:96889998887765545555536535534423524224242222211122224010/1,2001001//./.....-,.----/././/0111/3=SWD=;3151/..11+I'.-,UUTSSUTSPWWSUTUYUXUWXYWYYX_XXVYXZ[[]\\\[Z`X_[]\]]^^_^_^^```cab_a`bccddffdebehdihhhjkllinpnqrsutxwxww||vtyrswnjhkfeaca`_a_Z[XWYTSSQPPNNOMOLKJJJKFIFFCEBCCEDCBEA@@?@?>@<=?>=<:===;:;9;<:9<98996887687685554565555648333433342312352222110131120221002/0/200/0--0//.+.-,-..+-.,--/,0/01037?>?>=<@?=<<<<@?<=9;9<8898879676686766852555765544533335564221623422222012212221000/1/000//..00//,./.,-.../...,-1021/137DYE@D3121///0.-6E/-&UWVUSTSVTVVTTUSTWWWYXVYXYZWXWWVXU\[Z[Z[Z\\\ZY\\[]^]\[][`^_``__``_`aadcccccdddfddeeihiilijklnnoovptrwwx{{{}zwysntpnkghfecb```^^Z[[\ZXUSSRPOOPMMNKKKJHHGGGGFDFCCBABBCAA??>>?=;>==<=><<;;9:;;9:;9;967:67876877456665456754433435422224222233032250210210100/0000/.//0/.-/0//.-..+,,,-,,.-.,100/004=GUC@E4130./013(E*+-,!SSTSWTRTRVUVUTYUUWWUZWXXXV[WVVWUZ[YYWY]Z][[[Z\[\\\Z[\\]]\___a_a^__^a_`_bbbfbdccddeeeeejhijlljknnpqrrsswvxw{wzvtrqprlifeddcbaa_][^ZZZYUXVSRRRPQLPLLOKIJHJEEFFFDDCEEAC?A@?A@=?>=<@<=;<;<;<;;;99;8:9:87:6776657876667555455564473444322222213222220110011.10100/100/00///1///-.0./,,,,-+,,.-,././101/4@TL>AAC>???=>>===<<;;:;:;;;;7<8::877857787776865554234434343442222233121022113201100110/2/101/0/.22///./0000./....,,.,-.-+.+,-1.00127CUXX[OV]A'.01.,A.(/'!USUVUWPVSTTWRSSUUUVUVVUWUVWWYQVYWZYXVXZZZYYZYXYZY][Z^\]]\_Z]\]]\]_^^\]^^`^d``__`bacbceeehgffhjkmjnlnmlllsrrqsxxtzww{}}}||y}}|y{ruuspomkhefefc`__\]__ZYXXXZVUUTSTSRONMMLMKHIKHGFEECBECBACAC>??>>>=>>=<<<;;:9<98:<:89:998866677:57745675437464333334132212222211121022112010/2200001////1//000/00/.-.//.-/+/./,+,/.----/00028GQU__W^_9.02101Qy",-%URSRRRRRRTVTSUVSTUUVUVUWWWWUZV[XYWY[YU\YYZY\X[YX\[Z_Z_Y]]Z\[[^\\\[]\]\[^^___b^__aaabcddcecddggkiikjljkmmnlnntsonutvvxxzzx{zz}{{{{||~~}}zww}z~}~~}z}}~}|{|xzxzxyyzrrqnkokjkedde`c]]^`]YXZVXTTTTRSTPRQPOMPLNMKIHHGHDEDDCBBAD@CC>?>>?>==<<;<::::;999::77:87789677777775546655325343332114422242311111011211212222/0/1100000..../10//..-,--...1,/+,,--...,/./,032:GSO]^U_X3323260uY$2,!QQPQQRRRQSRRVVUTSTTTVVVXVVVUXUUVWWWWYWUZXWXXWZXZZ[ZX\ZX\[\[Z[\[ZZZ[[Y^\^\_\]]]^__```aaeccddfbffgfgiiikljlklnnlmtqqrvqsuxuwwyxyyxvu{|z~|~|~{z{{|{||{{{|~{}{x|x||vzyzyuuvuuvtqpnlmnhgeccbb_[\[[ZXWXVUSVQROSPRQONLMMMJJIGGHEEEDAC@BAAAC@>?C>?>>??<<=;;::98;:99:6778889766556657653336333242333433021222223131212101001000./.0012/00/.0...//0///...,,..+.+,.,,,-./--.//0121;FDAMV[^B13473/<5&1- QSRURSQUVSSUVSTWTVUXUXWXUUVXUWTWTYWWWYWUXZWZZXXZZ\[]\Y[YZZZZ[[\ZY\Z[Y]]Z[\^]]]_^`__]]a_cacc`fbefeefegfgdhmjkllmkpsontqpruuvtuuuustwvzuvuuvvwxwwv{vwxytwxzwywxsrruxvusrqpoppmomkjhfdca__^\ZYZYWWTSSSQQPSPNNPSNNLNLMJLJLGEDEDCDDA?BA@@@>?<>==>><;<:<;99:;89888:87877765646865746554243434452301/22222221212111/20/0.100./0//00../0.0..../0.--../,,-.--,/+++,,.,-.-...0104?B533==>>?<=<;9:99;:8;888888777665678447665234444344214313222222030142222100./.0/..0.///1/021//1..*../01/..,---/*/+*+,,,,,...//20114FQF>67KJ1/53645jX /1&SRSTRTQRRTSUSTTSVTUTVWTTVWVVUTWWWWVVYVWXXWXWXX[XWXYYXZXYY\YYZZX^Z\YZZZZ\X[[Y]\][\]\[\]]^_^_a^addddaedfcfhghhhijjijimonmnnnnmopoqrnqonommorppsppqpoqpomnnqoomqlnnmljllmihgfjhlhfedcb]^[[ZWVUUSRRSRQPMPNNOLOPMKLKKIMJHGFGGECCDCB@A?BA@>A>;?><:<=:::99897998998788776565454434434534145333332121122100/0110///100/0/10/.1--/././-/-//.,-.--/.-,,+---,--,,,*,,/+,,.,.0000/8MUTWQ@MF-1233297'-/SRSRRRQSRURUTUQSWVVTUWRZUUSWV[WWXWVXUWWWXVVUYXWWWVYXWXXWWXXYYXX\WZYZZYY[\YY[YZY[[Z\[Y_[\]]a_e_cfcaabcegfeffhjgkihjikjjlnmllmkkoopponlkjljlnnjlllpmlllmmmkkllkiikmhgegjgffdfeegdbc^^`\ZXWVWSUQNQQTNNNMMNMLLIJKLKILGHJGGEDD@BCCA@??=@>=:<=><;=:;:;997678766767787766555745443432442432232211123211232/10120/0/0//.//./-/1,.*.././//....--,/.-+..--,,-.-,,+-+---++-/-0125@MMP]ZXW9*02331Pz&(.'SQRQSSRRRWRTVUSSUVTUSUSUTUZUWWWVTUVYZVWWYVXYRVVTWVUXWXWVVWW[XZVXXWWXX[Y\WXXYYYZ[Y\Z[[[]\^_]^X`a^`aabbbcgddcfedehjhhggiiijijkkkkijmnogijiihgimlgmjikkjkjjihkiijigdffddcfddb_^c[ab``^_[YWXVTRSQRROOMMNMMLLLNJIKJKIIHIJCDECBACB@?A@@?<=;<;;;::9::<9988:867788678957555555345530232333243322111111111100/000///0/0//1..0./,-.-.,.../.-.//.-,/.-+-+.--,,+-,0+,,,,,++././//5HJOWYXXW4+.357-k\",)#SQRURRSRRTTWTUSRSWUTVVWSTVUXVVTTUVVTUWWTTWUUXUWXUUUWWWVUSVXXWWXXVXWYX[VZXYWXXXYXYZZZZYY[[]_^^\^]_```c`_caccgedccegffffgfgggjiigimijghhhjeffhhfihfihgigdighhhjffeedbbbcaba`\\^`\__^a\ZYVVTTTPSPONMLMJKLJLJGIHHGHGFIGEFECCB@AAA@?@>=<=;<::::98:9999897877456864565555355434453223122222320222114011//./0/.0///./.../....,/).-///0/,..-.--,..-+-,,,,/*.,,--*,,,+,,-/./0/2FJKTYVUS6.14973="))#SRRRTSTQQQTTUVTRTUQTUVRSTUTWSSSSTRSTTVWSXTXTWUXVXUVWYXVVUUXWXXWXWVWWYUZXVWXXYYXWXYZYYYWZ]]\][]]]]^_``__`bbbcaa`ebfeeeeecefgiihljfghggfeeeeedejegfdfihedeededdeccb``bb`a^_]\[ZZ[\^^[\[ZXTUSQRNONMKKLLLJIJIIHGJHHGIFEEDCBAA@??>?=?=<;<<;;::9::77:::8:987876567664434444333343333231324220001112.0001/11-//.0//.-,..//..-,.1-..//*.,0,,.--,+.--+++,,,+*+-+,+,,.-,-,../023GHKVYSRE7059=3C~(+& QQPRSOUPRUTSTTWRVRSWLTQSTVVTTPRVTSSSTUTTTTUUUUSTUVVWXWUVWZQWWWWWWVTWVZT[VV[VWXYW[Z[ZX\^[[\^\[[[[\\a]]a]^a`a``b`_e`cchccfdddedejeegffeidcbccccdbheg^gedbdcbabga_]a_ca`^^]][Z]YYY[^\[YXYSWUPQOPNKJKILIJKIIIJFGIJFGDFEEFAABBA@?>A=<==:;>;:>9;988987789967475455433323333223233533.12.32000/10101130.00/-/,.-..0...././..//,,/../-,,+.+.*+,++-,,++,+.,-)-,++,+,+,..,/-/10>GHSVQPK=47?;@<><<>7::;89:8:6977678755545533344323333223331301111200001/.11111.01////-..-...-./-,,..-,-,.-/-,-,..++*-,+.+,+++,,-*,,-+++++**+,+.+0-005EDGTTPNM548GGA@}6&+(PQTUMOPRTTSVRRQSTSRRRTRQRQSSURSRRSSSSRRRTTWVTTUUUXUWVUTVTUTTSVTTTWUUUTTSUVSVXTVTYUUTYVWPZWY[[YY^YYW[[][[]\_Y]]^_\]_^`^_`______`c_a`^^`__a`^^^]]_[]]__^^_\][a][Z[X\[\]ZZVWWWWVUUVTWXWVWTUSNOMONJJHHGHFGEHDCBDEEDFDBCCAA@BA?>==><;?;?:;8:98:787876574665554253343454422322.2241/211103022/10130.//./00-..//../-....-,-.,,,,-.++./..-+++-++,/+++(-*,,)+*)-,.+),,,-/+-//6@EGSUNNB25=HG:We)*% QQQLTPQRRSSORTQTQQQQTSROPRRROWRTTTQSSSTVSWRTTTUTXUUTVSTSSSRUTRQRQRRSSRVTTVVRTTSTVUUTVUYWWTVXW^YWXZYYZ[[[\ZZ^[]\_]_]]]]]\]^^]^]__ba^^^___^]^\\\Z[[]]\\\[\[][[ZYX[WYXXYXVZRUTVXSUSUWVSWTTSRPNOKIJKIHGFFDHDACDCDDDDAABB@@?@?>=<<==;::;:<87:877888766565545443333222443333222210011011/00-1//00/-/././.-/-.-/.--,..,+-,,,,,,+*++.,.---,++-+-)*++,*,+,-+,*+++,,+--,,+0.-09BDFRRKN;45@GA1rK%*SLQQOORQTRPURQQQSPQQPTRSQQRSURRURSSRRSURTTRRQTUVUUUUTSRRUPVTQRRRQSRRSRQSSTRTRRSSTTUTTWUUVUUVWWXWWWXXYZZY\[ZYYX[\[[Z[\]\]\\]]\]]_]]^^]_^_][YZ\YWW\[Y\Z[[ZY\YX[XWWWWWYWWSSRSTRSTSTTRRRSRQRRNKNHIJFFFDDGEEDD@EBEDDBBA@@@?A?><==>=<;=:998:9887776767553444413454323533232112310/20001/100/000/./././/-.,....--.-..+-.,-+,,,,+,++,,,-,-+,+*++,*+++.,,*,*++)+*+'+,..,-/+-0;ABKQKMC938CD7<}/&(% QNOPNNOQQPPPTOSSOONPVQRPVRTTPUURQRPTSTTTURRRWRVTSRVSSRQRSSTSQQQQRQPQPSSRSSRTTRSSSTUVTSTUUUUVW[VXYWX\WXXYU[X[XWZZZZ][YYZ[]\^Z[[[\^`[^\]^[YWXXZYYYWXVYXWTXZWYXWVWVWVUVTTTRRSSPSSSTQQQQQRRQRRMJHHFGFFEDDCCBDEADBBABBAF@>?>>>=<<:;;;9::8987977666745565433343444222221321123310/01///22//0//0.2.0../-+.---0,-,+,,+,+.,+,,,,,+,,.,,+,,,,,,,,)++-,+,,,-+*)+***++,,+,,,,,-53Pr#))"PQPQRPPPRPSOPQNQOQPQRSURTRUUQVQQRRQSTRSUUSTRSTTRVRTRSQTVSSTRRRRRSPPPQRSTSRQSRSRRTVSSTTTTUUTWUTWWWWWWWZXWXVYXWXXW[ZXYWVWYX[VYXYWY[]\\[ZZZXXWWZZYWVWTTYUVU[YUVUVUUURTSSRRQPOQPPRQPPNOOPPQPQNKJIHGFFFEDCBCBBCC@?DBC@B@@?>=?<;=;::;;88978889766757557654343323242301132100213000111400/00/./2-//.//-,--.-..,-,/.0*-),.,,*,,,,+/..,++,+-+-+,*++*)-,,,*)*+**+,*+,,++,../.4?@DNMKG<53BC?3]T"++ MOOPNQPPQPQQPTPRRPRPRRVUSQTSSPQRPQURVTURUQQRRUQUSQQSRTRSSSRTRRTSPQTPOORQQRURQSQOSSUUSTTTTUUVTWSUXWWVVTXUVVVXWXW[XVYVXXYZXY[YZUYZZZ[Z[YYXWUWVYYWWWSUUSWUWTUSSVSRSRQTTOQRRPOOOPLPOONONNONOOOPLJJGFHDDEACABBA@>@ACAA?=@?==><=;;<9:;;898888767766966555547635733213222511/2/211000111/0,2/0/0./0.//-/.--./+,,.....,-**+-.,,+,,,+++,,+/-++++,)+++,*+++++'+++.*-,+,++++,...17>>JKHHC71>EA0>?@?@>?@=@=;;8::::9887977667556656555544433234121223021/10001/./0/0/1-01/.//0-/.../.-,-/-/-.--,,-+++++.*+,-,+*+,++/*-*+*+)***-*),**++**+**+,)++++)+,+./1::>JKFE<20ED@)_U(*SRPSOPQNRSNPPPQPRURRQQRRRNOPQOQQRSQWQPQQQQQONQSQTQRSRQRROPQPRPRRPPQPOOOORPOQQMPQSSPPQRRSRRSSRVSTSUSTTTTTUTSRTUSSSSRUUWSSTVVURVTVXVVVVVRSTRQSWWXVQPRPNSRORNPOPOPTNOONONLOLLKLLLJJKJKHIJJLNLMKJIEDB@B@AA??>>>>>>=>?=>><;;;;:8:8:7775767555565555543544322332132212211012/10/0/00,1/1.-/./...--.--.,----.-,-++-,++*),++*-+++++,+,.*+.*+++)**++***+)+)*+*++-(*+)*,+-./7:;=KHFC8.7CD6+s~?%*%RQPNMSOPJOOPPQPPPQTPQQPPPOONNQOQPPSQTPQRQQQSORSRQQOSPQPNROQQPTQPPQOOOOOLOORQQQQSOPQSPSPRQQRSSRQOSSSRSRSSVQSTRVSSTSRSTUTSSQRTTSSVUUUWTUVTQQORQUSPPQOOOOOQONMLOOONNMPPNNMLJKJKJIIIJJJJJIILJMIJGFFCAAAA@@==>>==:@>>===:<;;:97:87;76578666555445554373422220110101111110.00/0/-//-./,0/---,0.-.0.1.,,,,/+-,,,,,+,)*,+++++,++*++*,,++++++++++*()**,+**++**+++)+*+,++,/15;;BJJC<3.AF@,>p''&"POPOQQPPPPMOPNPOSQSQROQNPPMMNOTROQRRQPSRTPPOQQPQSSRSSMOTPQQPMOQOONNPQNOTPPQNPRQQQPQPRPPQQQQQQSQQSQQUTRTQRSSSQTSPRSRRQUSTTTRSSTVRUSSQPSTQQPNOOQOOSNNNPPNONNPLMNNOOJMMKLJKILJJIHHIKIKJHGIIIJKIFHFA@B@@@>@>>@==<==?=;=><=>><<::;;9798788667866766244434234543220333101/1/1102000//1/./../.0.--+..-,+....,.-,-+,,+,.,++++,++*+++++**,)*++**,+**+*****()**))+)***(+)*)++**+++-189;JICB:01E>4+h@&#NNNMLNMONPNSQNQOOPQPOTMOPOORPPPPOROPNNPTNPORPOQPNQRUONMONTQONONMOLPNONMMNOPMNPQSONQOOPPPONPPPRPPNOPQPRPPQRRPQRQQQRQRRPPOTQSURPRRPORQRQQPOONNLKKMLLOMMKKKLMLKKMJQJLKJJJHHHJHGGGEGEHHKHGEEEFKGFEHEC?B@@==><=?<;;<=><;;99888877677737955524453443/24342234104612/002/10/2/0//./.-,0-.,+0+--.-,,,-..,/-,,,,--+,*.)-+,+++++(+,)(++****))(,(,)*)+*****+*)*,('+*,*)++-+-37:@JID@6,9I;,6{a&&(!NQHNMMSTOOQNOPPONKQONQORMOOQQRNNNRLPPOORPPQPQOPTPMQMMQONNMNOOPQLLLMONNMMNMRMOORPPSNMPPQPOPQQPQPQNOPPQPPPOQPRTUOORNPPRPPOPPQRPOOPRPQRRNONONMLKJKIMOLNMLKKKNJLLJIHJJMIJJHLHHGGGFGEEEEFHHEDEFGGFFCDA@??=>><<<::;<=;;=::9978987566556655444345715333/2312210312////0/00.1//////./.,.-..,,-,-.-+/*,,,,-.,-,,*+.-*,.)+,,+++,**-+),)*++)))*,)+**)+)(*)))()('))+++*+,++*-1=9FICE:5,K;6)K]!%$NPNNMNMNOOONPNONQOOPNNMNPRPQQORPPOOPNONOPQLOPTOONQPNOOMOMOPNNMOMLQMNNPLNNQONMMNPNLNOOPNNNPOOPPOPOOPPPOOPPROPNPORNONQOPOOOOPNNMRONPOOPPOQNMMJMLJLKMNOLJIJKJKKIJHLIIIIIJJGFGFFFFEGECEFDDDDEEFHGEFABA?>>===:;;<;;;<;::9888767668557554454435335232433331320225/1/122.101000.-...-,...,,,,,,-,,*-+-,,,,+,,,,+,,-+-*,,*)++*-+*)++++*(*)**+)*)*)())*)*(*))))()(*)++++,.3;B>>==;;:;<::;<::987767566657745434533343323324325/12000./00.01/-0/0/0.0.,/...,-..//,,,,,+-..+,+,,.,,..).-*(**+)*),,,+,+,++,+))*+**)+*)))*))*)*(+))*)))*,)*+,,+,767@AF@4*=B:)8tk,"$PMONOPOONMPMMNNONMLQLNOOPNOONOOPPOPQPOOONQPQNPPPPOLMLRNPSMOOOOKPNKLLIOKLNMLJQNLLLLMMQLLMLPQLMOONNLLNNMLPNPNMMNMNNONNNQMMNPNMLKKLLPLMLKNLKJJJJIIJIHJIJIIHIIHIGIFGHHEFHIEHEDFEECEDDDBCBDDDBABCECEB@@@===<9::9::;:988877767867863555544445233322321121102123//1///0///-/0/-.-/-,..0,,,+++,,,,,,,,,+,-*(+*++**+*)**,*))*++)*))***(*))+**((+(**+))*()(**+)))(***++,*,00/019A;1-@@1&>~R &# MMLNNOOOKNNONNJMLMPNQPPPPORMONNNOPPNPMNOROONPNNNONOLONNQNMLMOORLKRNMNOKOLNMMMNPMMOMLJPNNOPOPPQMRMPMLLPNMMLNMLMNPNLNMMMMLLJMNOLLKMLMKJLLKKJKJIGIJIJIIIJGGHHHHFFEFGDEEFCEFEFDDDCDCBABB@@A@AA@DEEDDA@>><<98::8999::98875678575544544644351224312141011321/0100./2./0///.0..//-,-.++/++,-,,,,,-+,.-,,-*+*,*+*(*+(),+*))*)*(*))+*)*(+*))(+*()**)))())*))))))**++++,..22+&&'06.1@=*(P}vH!! MNMLRMQOMQNPNORSLMNONPLRNOMRQNNLROORLQNOOOPPOSMONONOMRLMMLLMONLLMLKKIMJPMOKLLNJMMJMLMJQNMMMMLLMNNNLLLMKMLLMMLMOJONLLLMLKLKJLMMKLKLMIKKKKJMIHGLHIHHGGIHFFHHHHGFEEDHDDFAEDHBEDAACCBE?@BBA@@AABEEEC??>=<:9;8989878::88884566754555644554232352112011001232002/0.2///.////1.,-...--/,-,++..+++*++,--,+++)))+*.*++)),)))++*)))+)))*++()****))))))))*(*))()+)*)**+-..08>0+('&('3:9(1cwg4 " MQOMMLLMNNMRONMNLQOOONLNMLMLLONOLKTOMPJNMMOQMNPQPKQNOLLMPLNMPKLKKLLNJOLLKJLNKKLKLMNMMKKLNLPKMMNLLLLJMJKLLLLLLLJLMLJMKMKLKNIKMJKJMKJJJJKIFJHHGHIIHGGGGIGGGIFEEEDDGCDCDADCBDDDABCBC?@@CA@@??@@BAEA?>=<;:;98998778<9886544376485544473443252343220/00111210000.///0..0/.00--../+,,/--.-.++++-*..*+-+,*++,*+*+)***))+)())*)(+*+)*+*('*)+,+*))))*(*)*+))*(+)+(+,-..-3;B=4.)$# (.1&:rpY !!MLMOMLLPOOONRPONNQNOMMMMMLNMLMMQOMLMNMNKROMNMNOLMOKJLKLNKMLKJLLLLLLMKKIJJLJJLNJLJLKKNMMMLJLLLLLLLLKKLJKKLNLMLLKKLKMMLJKMKINMJIJJLIGJJKJHIFGIGJGGGDHFGFIGFGEFDDDCDCGCDCBDE?BABA@B?@A@B@@????@ACA@>>=<::97999878889:8765554344355431321321223320/0/012110100000./0//--0.-.--.,,,+,...++,++,+..+,+--,*,,+,+*))*)*)+)(()(+))()))+*,)()))(*,*)))*()(**)**+))*+**,,-,7>DC93'$#$+))'Jro@ OMLMMLLMNNPNOOONNJMOJLMMNOPMNONKNNNONMLMQSKNNLMMLLLMMMNJNMMKLQOLKKLLKLJHIJJLJJLIKJKKLLMKPLLKLMLLLLLKLNKMLLLFJHHIJKJJKIKKLLKJIJFKGGGHHIIIGFEFGHGGGFDDJEFFFEEEGBDCDADFEDCABC?EAA@B?B>>?>??>>>>?BA@?=<=;9:;8;77964:776764533444211331435222013221/211321/000010,/.1,..0/,,-.0,/,-,/-+./+(++,,-(+++,++++,,++*)***(+(*))),())(*,*+**)()*+*))*'+)())++*+()*++)*)++-,15DJF?2'%$%))(+ar[0QLKPHMNMNNMMONMPNNQNNOOMOPJONPLPPMNMNLOOOOPPNOOMNLMMNLMKMKKNMJLKIHJMJLJKJJJLJIJLIHIJOLJLLKKJKMIMLKKIKKLKLLKKJKKIJJMIILKKKKLKJHIGIHHIGIHGFGFECECIDCDDFFEEDDEDBFACCBDCBBDEBAABA??@?C@?>=>>B>>=>AAAB<;::897878677696676664344332333314121311010300212100///101//0//-//,.,-,+,+.0+-,,+-),+**+-.++,-)-,,+**+***),+*())*)+)(%)))(('),((()))+**()+())*))))((,+*++*,,.17GPNI7((&'**%*ko^  KNLLONLLLNMPKROLONNOMOLNMOQMNMNPONMIOMLMONMMMNMMMNMKNNLKJLLKLLMKKIHKIKLLIKLHLIIKILLLIKKJMKOKIMKLLJIOOMJJKKKKKIJJHHHLHJKJJJJIIEHLHHGHGEHGFFFDEDCBDCCCEDECCECCDBABADBAAA@AAA@?@>>?>??>>?=>><=?=>@B>@;:6987878857666655454463323221522413321/314001/0///////1/.///.0..,+/,,,0-----,,+*++++)+*)++),*,++*))*)*)(,)(*)((),(+())***(('+))))++)**(()*))++()))(+),,,+,-17NQMJ:')((*)$EpmFOOQONMMOINMLNLGNMLNNPPNQQLLPLNNNQRMLMMPNKKLLMLLKNMLMNGOKJPNJJJHJILJJJJJJIIHMIINGJIIHKMKKLKKKOKLJHJJKGLIIJIKJLJJHKJKINJIIJJIIJJGHHHGEGFFEGDCFBCACDDDBDCECDAEDB>DCABBA@@?@AB=C??>>>>@>?<<===<<==?A@?><:857567687765554566445443332243122021/5222//0//////.1.//./..0-,--,,.,(-,,-,,,+.*,,+++..***+-,+*+)(,+))*)+++)*)*+*'(+)*)(((())*))(*()))+(+)-()))*))*.+,++++2;PMJI8)+*,)("fpj. KLNKMKLLLMLPKNLLNMNMMNMMINLMPOMLLHONKPOMMOKKKKONLJJJKKKLRLIKJIJLKIJJLIJGHJHLJLKJIHJKLLOIIKJKJMJIJIIKLLIKJKKKIJJIIIKNIIHHIHIHIHGGHFGGFEGEHDGDCCDCAEBBAADBDB@@BADA@@AC?@??@A?>=?A=<=<=:<<<<<;;;=?@>?=;:79686675556545443444222123344014232210020//0////-/1../1...-----,+.,,/,+,,,,+++,,+++,+*+++++,+++*'+*+)*)+*))))***),())))+('*)()))*(')*)()(()+,*)*+)*,,,../5=NNJI6*+--,%,fo^ NLMKLNKNNKLLLIKMMMOMLNMOMJMLMNMJJLKNMKNMNKKNIMIIMKJJKJILNJKKIHIJIIIHJIIJGHHIHGKHNIJKLJIIJJJKKJIMIKKGIHHIJJIIIJIKLKIJHHIIIHJIGGGGGGFFFGIEEEBECBCCEB@BAABBBA@@A@@AACBA@C>??>@?>@;>>><=;;;;;<=<;;=?@><:9968656565444413433222233333201122111102/10//////01.0......,..-/..,,0,--+,++-,+,,,*++-++*))++,+-+)**+()*-)*+)+++))(())()&)()((((((()+***(((()(***))++*,,.04FKKKG4*+-/*$6iiJLLLKMMLKILLMJQLLMNNLMMLIKLKKLKKLLLNLMMNPPMLKLJMQKJLJJIIJKNIJIHIIJHMLJLHKLHIJKHJIIJLJKIJIJHJKKIIIJIJHHHHHJHNIHIIHHHGGEHIHHGGHHFFFFJIDGGECCDDDCBCCCAABA@BBB@@@@>@@>@B@?<@?>==>@<<;;;<7;9=>==<;75:777455555524444333313223214202214100/0100.///00///0././.0.-,,-,,,++.,+*-+-++,+**++**,*)+)*++*+*)()++*)*)()*)+(**))))(')))+'())*))+'+((()+*)**)))++)+-..8FLMK>/*./.&'Khh3MLLJONMLLLKKKILKOKMLKMKMKPJJLJKMNKKLLLKLKLKKKIPMLHJLMJIIJKJLHHIIIJIIKJIGJIJELHIHLKJGLIHHIIJHIJIEKIJIHHGHHHHHGHIHHHGIAFHFHFEFGFGGGFEEFCCCBCBDABAAABDAAA@@BA?>B@??BA?>?><><=>>><=>==;:9:=::;<9<><=>>B>?=>>?=;<<===<<<=;>:<;:8:::::=;:=;:966665453643441232424222312112200..0/00,2/0//..-///./2-../,...,,+++,+.+-+++.),+*+,+**++*-),++**+)**++))*(*))())*(*+'+))(()(+()*()))*(())((+*))*)**))++,-.2CLLLB5-.//-%6igIKKLLLPNMLJKKKLKKLLJOPOLLJLLLKJJKKKJKMLJKKJJKKMLMLJJJKLKKIFJJIHHGKHJKGIJHGIHJHHKFHHJIHGHFHGIIHIHHKIGJEIFGFJGHHGGGHFFFDGDHEEDDEBEECHBGBBACAADBA@?>C?CB?AC@A@@??@@CA=?==?===<<=<;<;<<=::9999<;;8;;;<<=9875664434625543222343222112320301/.000/10///..0//0./-,10.,,0--,-,-+++.,++++.+,+++++++*,.**+)+*-)++++*))))+*)))))))((*)))())+*)())))())))*((*)))*++(-*.,.03DLKKB2-./0)!Mea2LLLPOMLLLNKNMMLLLPKLKNQPJKLMJKJKLKLKOMOLOMLKKKLJJIHJLMHKJKJKIIGEJFJCHGILHFJHIGGHHGGHHGHFFKKGGKIJFFFEFFFIHGGGGHHEFFDGEEEECDEHCDDCCDFAABCBABAACAA?@@?@B>@@A@>A@>=C=>>>==>?><:<<;:::=;;:::8:9:98::;<:<:87774533354422632211421112002/100/011/00..000-...0.0/-0+...,,.,,+-,+,,+-,,+*++**++,)*+*+,+)*++++)*+++++**)))&())))))))()()*)***(((*))*&*'*('*(('+*+)+,.0/5DKIJ:0-/0.#)Wda* MMLNKMKKQKLLKLKLNLMGNLKJKMJIHKJKJKLKILIMKKLIJHIKHHHJIJLHKKKIGGJIGEFGGIFFHJIIGGHIGHIHHIHFGEHGGFIHGFEDGGFGHMGFEECFEFDDEFGDCDECCCDDDBCCBBBA@B@@@@@>??@=??@???>?>=<=?====<<:<;:;<;:99:<:9::99:<;;9:9<<:986756434122422241102322111/0/010/2/0000//-..//.00-0/-../-+,-,.,,-+*,+++*,*,*++,+*++*(*)+*+,)**+)))*)(*)***))))))))*(*)*))))())()))((()**'(*)''))*++,+,-/15GJJE82000+#1cbM LLMLLMLKLMLLMNOKMNLKLMLONKHJJJKILLKOIHKLMKKJMHJIHJIJHJKIILFJKGIHHEFHGFIHHGGFEFEGHIJHFEDEEHKEFDHHHDDHEHIGGCFEHEEDEFFEDFDDHBABAFEDB@ABCBA?@?A@@;@?>>@>>=??;::::;;<:::;98:9:::8<=97:;;=;=776843424341223230030/1221+-.-//0.10/11/..-/.-.////../,..,,/,,,++,,+-+++,++-*,+*+-++++++*+,+*-*+))))')*+,+)))(*()(()*(())))))()())())((()))'((()(+,,+,..1AHGIF8-02-'$9fa8 LLKLLLKKMLLLMLGOKLKKLMMJKKLHLIHNCJKHILJKJKJKHIIGHGEHKKJGJHLGKDJFDFEGIJJHIJFEFEHHKHFGEEECFGEJGHGHGHE@HHEDFIDFFEGFDFEEEECFFCECCDGCCCCAEAA@?@@?????@?>>>=@@>=<;<;<===<>;<<::8::;<<998::889;9;;:9999<;9867454524324234011141221002/0//.100.-//0/..--...,.-./...-,/,-,-,,*,,,+,+*+,+-+++*++*++*+'++),+)*))()*()+)*()*+((())+()*(*())((()())*)+(+())()+(())**++)./5DGGHD721.)''Pc],KKKLLIJNMLMJJONKJLLILLKKMJLMKJJMMMKJJKJKLJOIJJIIHGHGJIJKJIIHGJGEIFGJGFGGIHFEFHFFHFFFDEDEDGHDEFHJIGDDIAFFEDDHEEFGEEDEFEDCDCDCCCCCBB@>?AA@??>@>?????>>>?<=>=>;>;;>=9<:;><;87;::::9;9::889;:::;9889;:<79774434432/41220201211.00000/.1/00././/.../--.-,..,/./.,-,+-,,,++*+,+,)+,++-**+*)),+++++++*+))*)))*))**)**)+)))'(*))((*(((*())((')))'(())(()'(())()++,./:HHGF>552*'#,_eKLLLKKLNJMLKOMMLPIJKLLLLLKJJIKKJKKHNJIKKKJNJKIKKHHIIHJJIJKJIGEFGFJFEGLIEKIHGFFFFEFEEEEEEFFDBHGGEDFDKEGIEEGEDECECBECEFEDDCDDDBDBCCAAAA@BA@?>?>=>>>???==;><;<;;<<;<<;;;<=;:9:899=::99888989:9988799<::9765432412231110.000313010///0/000/.///-.0...-..,+-0.+.-,,-+-,.,+)+,+++-*)+-*+(**+**+)*)***)))***,*)*)*))())(*)(&,*)))))(*((+*))'('(+((((**(*(')+)+(*-..0552.% 7^_G JKKLKLLNJKKHKLNOKNKIKMJKLJKJJLKJHKGJIIINIJRHMGKLGGHHHHKNKKIFGEFFELJEFHEDCKGFFEFFFHBFFEFDGFHDEGIHHEECEFEDFGEECDDDCCDFEDFBBADBBABB@@A@=>>?=;9?;9;:<<;;?<::7:;98:9888;:9889:888697>;:9865322221114000/01011012010/4-//.01/...,0/0/+,.---,-.,-,,,+-,,,+,+-,-+,,+**,*.++))*++*)***)*))),**)))))*))*))(())))++*)()((+*(((((),(((())*&)'+)**(--/.3BHFFE:473+%#C_S,LKJLLLMHJKJKLLMIMLLJKIPMKLKLJIJJLIKIIKIJLGKIJHHIIGFFIIHIJHIDFGGGEDGHDFEKEEGEFEEGEDFDEEDEEFFGEHCDEEFGDDGFEFDBACCCBCABBDCBA@B@BBCAA>@?AB=@?>?==<>=?=<<=<:<::99;:;:;9;;;898:99:87878888:9899879:::98753224240100100/111202001101200//./2-/,//-+--..,,-*-,.*++-**.,.*++++,-++*+)++,*-*,+)*****)(),+++*)*(**))(()('*(()()(())(())))()'(((((()(()()))**+++../5DHEGC9553*#*SWB LKJHILHLHKJKKKLOLKJKJNFMJJJIIJLJIIJIIIJLJIJIHIHNHDIGGIIIIGGHGIIDDEDEEEEBFEEEEFCCEDGEEEBCDGEDDDIDIEGECCCDEEDCCCGCBBAADFBCA@ABB?B>@BD@B>A=??===<:=>;=<>>><:::;:::9:9:::;:::9887:6::977989:67:998999:<896542205100133100.2000/02020/0.1//0.//0/.0/.,,,,.+.-,,+/,,-.,,,,,,*++,,+,**(+,+*)+*+*))))*)**+(+++++)))))()())'+'()))*+*()))((((&(&*((''('((*())+++)+.17FHFG@78?2*%1VV5MKIIJKKKJKKNLJLKLMKJPLKIJLHJJIJKIKJLIFIJIIKJKGJGGIFGIFIIHIFIKHFEEGFFEJEFEFEEEFEECAGFEECEEECEDDDEBGGBECDFGFDEDCDBBBBAECBAB@A?AA@A@>A>@AA==?<<=?<><;<=<<<;;<::9998=98999878988:8;97888698787:89:99:998874423402/12.200/1100/.1,21000.2/1-.+-/.-..-+,,++,/++,,,+-,-++-,*,+*+,+*-)+*))*+*))++*)*)()*+,)*+++,))+))*()*+('))))'*'()()((')))'(')'*('()+*)()+,++./3B<@<>?;>=<=>9<<=;<::9:<::<99:89:88889889:9::898798:77788:988;:998862523230112/12/200//0-//000//...../-..-..-,-,++,-+,+++-,-,+,++++*+***,******),)*()*+*()(**))())***(++))*())*)()()()))(())('*((((()('('(((')*))**+++-04?EEFH<7<@2'!KSEMJHLHOPJLLKNHLLKKKJKKIJJKKMKIIIIIHJLIIGIHGNIIHHGIHGIGIFGJGJFGEEHHCEEFEHEEEEDEEDDDCEDGEDDDDECEBEFB@EDCAGEEDGDECCBCBBD@AB@B@@?@=?@@=?;?;<==<;=;;;::;:::979989:9888789889889:889998879899888;:99875534410111203112010/1-/////./.0///000,..-./,,.+-,,,+++,.,+,+++++)+++)+))())))*))*,)(*,)(*)),))()))*))*))))))())(((((((((')+'))(('(())((()+()**)+*,,./5?BCFF86>?-&2QR:JIHJJJKMGKIGMMJLJJJIKJMMKIKJGMJIJIHIHEGHHJIIIHHIHIFIGFIGFJKEFDDCGJEEEDDIFEECDDCDDDBCDE@FCBDECCDCB@@CCBCBFDCCCCACBACC@A@@@@@A@@A?>A<9<;;;9:8<8;9:;:9:8:98889889889899887787:97;;864:;88876521123//01//0120./1.//..././/.1/11,.-.-,,-/+,,,,,+*..-+,-,+++*+)+++))*)**+*+*)*(+,,)**+,)()(((+))*)))()+*())*))))*)('(**')))(')(((('(())(*)))*))+/.04BCDF@68=9)(=SO(JJHKJIJKIJJKJJJKKKKJJJJJLJKJJIJGJHJIHJHHGGHKIIHKHFGFGFGFEHHEFHDDCBFGEDDECFACBCFCEICCCCDCECCEDFCCBBACDCCDDECDCBAACB@@AC@@@@?=??B>>>A>>=<>;;<<<:<<:<=::988::9:8:7<:999998768787688577778886757967599<7764232210.011000-////0//101/././/,*,.,-.----,...-,,++++,.-,,+*),*(+*+)**)*+***,)),++)+*+*)(),()*()*())+***(+*)))(*()(*''*''*(''*((((()(**)())))(++*,.2;CCCE@8:<2((HPGKJIJLKJLKJIIPJHMJKMIJKKILKJIJIJJIMHLJHIHGGGJIIFFEEFGFFFFEDEDCCDFCGCEEEDDEDECDCDFEHECBECFABAFDDCA@ABBADECCCABDA@A@DE@@A@?>?>?@?=A@<<><<<<:;<;=;::;8;::9:9899<998;8998978888987874:777787775877856:998551322102000/00/.../0100-3-.//.-.0/-*,,+-/)+.-.++,,/+,,+*+,*+*))-*+()+*()++))),*()++*)**()*)()*&+((())()())))*)*''()()((((((())'(()(&''()())))****++-4ABAED=8::+'1NN@JMKKKKKLLKJIJIKIJJKKKIIHIIIGHKKKGFKHMGLHIIJIIGEIDHDEFEFEEFFHCHHECCDGEECDCCEBDBEDCDACF@CCBBECCDGABBBBCBBCAD@D=B@@?BCADB?D@A?D=;<;>;<<:;=:=::9;99989898:8;:977887;8888767677976677666769867669999843421311111///1...0,//----1--.-.,,-*+,,,+/-,,,,.-++,,,,.++++*))++(()**)))*)))((+*+,*()+()+()),()))))(((())))))))(()())'((()'(((&)()(&))))()))'))++,06?BCEA::<1&':NM.KJIILJJJMLIKJJIJJJKJKHILIHHGHJIJHJIJIHKKHLIGFIEGGHEDDHGEEGEDFHBFEICBFEDCFBDFDBDGBBCBACADBDBAFDCBDDCBCABAA?AA@?@?AAAAA@???>A?>>A;;;@>=<;<<;:;<8<:8989::988:9:;99698897876777777675668676676777768:989654010000/0/./.-..//..-++-,-/-../-,.,-*/,,++-++,-.,,,++++,++***)*))))*)))()))***))+)*+)())((*())))*))(&'''()*())((('*)(()(('((((('('&((()'()***),-,,/6BAEE?869/&&ILI LJPKJKJKJJJKKKIHIJJJJMIJJIHLHLGGHHHJHFFGHHHIKEEEDHDICDCGEEDEFGGFFHDDCCCFCCAGDBBBCFACCB@A@@CCECDEACBBBBAA@@A?B@C??=@@@@>>>AB?>=@@?;:<>:;;:<:<99::=9:899987>88775768788777776876677777656767767656:878773200/1///.././,../.-..--,.,/.++--,--+,*,-,,,+++,++,-*++.++)))**+(+)*()*')))*),+(*)+(()+*+('))(++**(()((((('((*'))(')))((((*'(())(')'((('((+)))),+-0>=D?D>899+&1HK7  LKMMJKKKKIIKIHLKHFJLKJJKIHIJJHGJLIHHHFLHGGFEEEEEDDDEEEFGBDCDDDHEFFCDCCFBDDEBDECBCDBCD@CD?BBBABAEBBBCBB@@B>????C?A>@A:A<>>>?>==?:=<<=:;;:<;:;<9<899:8879:998;787877867758796764858:558765487765547;59632110./.21/././...0...1.)--/..-,,,,+,,,,,++),+,,+,*++-*,)-,))*))++(*(**')))++)))))*))+))+))(*)()()(*(((('(((()*((+())(()'((((((('''((()'(()(*)+,++1794(&AA@<@=?CB???A@=>?>=<=<;;==;9:::>;<;:::8979899988788778667576556796656775556541:56678755579944211001//0//--.0---..--1.-0,,-,,+.,-+,+*++++*-,,++,+**,*+**()*)*)*++'*)(()(*)+(,))*)))()()(+'+))()())))))((('(())(()((())'()((()('''&(('((*()(**++,3FFA@@A<88/('BFH!  LLOMIJIMIIHHIJJKLIHJIJIIJIGGIIHJGHHJFFGFGHEFEGEDEDECEHEFDCFEADECDCBACACCCCDDBACBBCBBCCAD@ABB@@@ABA@???ABD??>=B@B=>=>?;@@>>=<<=;;=<=;=9;::9;8879:986<999:8777886566289567375657655665;:35555656665787431100///0-/...,,,..,,*1-/+,++0+,++.++,++++**,+,,,(*)*+*)*)*),****()+)'***)*(*)(())))))(**())((()(,(((*'()(((*))))))''*''()))'''(('('((((((()(*++++6IHB@A@=83)(+GECILKJKIHHMIMJIIKJJKKLIHIBIILEHLHGGHHIFEFEHIJGFFFEEEHHEFECCDFCDEDBBCCA@E@BCBBC=DDBACAGABBACCB@A?@AAA@@@???A@???>A?=??C>><=>=;;<<=;<;<;;9<7<:8899799:878:98887777658678765659346576555567455766585568552221010.-2*..-.---/...,,,.,,,,,+,-+,.+++++*)/*+,**+*++)+,+))*,)+'++*))))*)))())*+)&,(())(())(''((())))(())''(',()+))(('((+)))(()*''(')()(((*)()+*+,6DF@ACA:;-+(3EE(MKKIJIJLMIJKIIJIKKIKHHHHIHFGIHEHFKHEGFFHEJHHHCGEEDEDDDDDDDDDCEDCCBCACADDD@@BCCBD@BB@BBA@@?C?A@?AA@@?@?A>>??==BD>?=><<=;?<=<>=:<=@><;;:<:6<98888::99;78798784976678986556576546656565654674555645867664110///.-1,/--.-....,-,+.+,,,+-++++-+*+-+***++,**)*)+(*++)**+'))*+*)*')))*)))'(*)&)))())((*'((())))'((((('(')'()((('''*(()'''((((''((((((())))+,*,7?@B@BB;5+*+@CA KJJJIJLIOIJJJIJLKJHIHJKIIFJGHHKIJEGEGHGGFIHFDHEGFE?DDEDEEHEHCCDCBBAA@BA@AB@ABC>CA>@@A@@@AAE>B?@D@?>@@?>D@?@B?>>??B><<=<<;<<<;<<<;;;<99;899:987689978677789:86877667688677775456657655458547555459765431.2.0-.0,/1./,/---,+..,,+++,++*,+-,*/,+***+/*+*()-+,*),,+-((+))))+(+)*((()()()$)('))')'((((()*))'))')(()&()('('('(((('))(((()())&''(()')))))*++++4=???>?92+).CD;LLKIIJNPFILIILKLLKGLIKKJHGHFKIFLGDFHIHEFHGGEEEEIEEEIEFEDHEDJCCBDBAAAABD@?@A@@A@@@@CCA@A@@CB@@@=A?B;A>@C>A@@@@@??>A;>=<<@?>70)+7CC2KLIIHJKLJHHIIKKKHLHIKIKHHGHHGIGEGFCGJGGIHGEEEGGDGDHFFFEDFEFCDBDFABBABB@@D@A@AC@@@B@>@?C@BC@AABAA??@>=B=>A?A>?@=>>=@<;<<@?><:::;<;;:98;;87:6:8:667876987566677888755564456663755555556535445253467555320021/////0.---,,,,,+-+,++++),-+*,+*+++,*)+)*++)*+*(+))*+()()())))*)))**(()((('))((('()(('))((((')(((+)*')'))(''&')((()))%'((*''''('('('((()),*+-,8;;=@A<7+*,>BB" KIHIHJIIIMGJJKKJJIIJPJHFGHIGILHGGGHDEGIHEHHEEGFFDJHIDHGDAEDFDE@@DAAC@CCAA@AC?A@C?A@>?C=?A?A@@@????>?@>?>@>?>C??==@@?=<<><=::9<;9<:::::8599979:97887:87:76775667376854445883456657576454344463447565520301//////-/-/,,+,,,-+++,,+,/,,,+*+++,+++*+,*+)))**)))))*+)(()))(()(((('*))((*)))(((()()(((*)(()('''('++)()()((&*''((((*()''()'(((((''%(((()')))).:<;=A@<0*).=C; HNNIGGIIIKIIIHIHJHIIKKLFGHHGILGFHEEDFHHFGGEEFEEFFFDABCDEHDCDECFAAC?CDDAAA?D@@@AC?AC?>@@@?B@BA@B@<@???=>;A9AA==@==??=====?8<;:;:::99::9::88;8;898;6;88599777356783755554665555586554634444454344566443400011/--./1.0,,,-+-,,)-)+,++++,+,+*++*++**+)))))()))))*(+())))(('(())))(((')())(()(())+(((('((%'()()*')*()((%)((')()((((&&((('''')&'')'(('((()**08;;=@>5,(*6@@1MIJIJIHIIMKKIJKIIJIIKIKHIHEHJFGHGDFEFGFFGFEDEEDEDDCBECCDECCCCDA@ABBBA@A@AA?A?B@A@@?A>??@?A@@@?@@?=?>=@@><<==>==<=A=<<<;9::;::::9::::78;899:898786777888785656456565634466644434445454455455544565543210/0//..,.,+..,-+,.,,++.*,,+,--+,(*,,+)+)***)+*)-)**))()())*)*(()()(''(('((*''(*()(())'(('&)()(('&(())((''''()('(((('((&(''')(&('''('''((&'((())*/:==?>72**,8>@&JJJMIJHIMLILIIHIIKKJJGJGIFEIIFHFFFGHGFFGGFFDHDFDDCBBBBCCCDEDEEBABA@ADB@@?AAB@AA@@>@?>@>?>;A?BA?>>@?A@??>@=;?>==<===>9<=;<==;:9::99989;:889887775879677796767785665565445554547534443344545554345454200/-0/.,---,,,,--/-,+,,**++*,,++*'+++*)+)++*))*+-(*'*)***+*)'))(*'''()(('((('&()((()+()*)((')'')((())((('%'''''+''('')&()&)'''(('('$''(((('''(()))5::=?>4.*+09=? KLKILJJMJLJJJIJLIHJKIMHHIJIIGGGEEGFDFFEGHGGEDBFHB@ADG>DBD?AAAFCBCDA@B?D=?AA@C>>?>??>==><==>>>>>=@A@>A<>>=@>?;:<;==@;<;:?<;8::888899997:77877788898385787755763654354445552514527355552534335855542/000-,31+-.+--,,,,,.,,,*+.,+.+,)+++)+))+++++-)+,*+))(*++)(,*(((((((('(((()%)('((((((()+'))(&('()(())))'''(('((')(&('('(('(('''()('%()()(('(('+))+6;;;:96))*0;51KHJJJKJMJIJJJHKIIJHIHGGGGHFFFFEGGEFFEDGFEEGHEHEDDBCDDCCEEDEABBCF?BBB@@@=C>@@=>??@>@>>>=<=>?>?====>?>=;>>=<:;>=<;:<>>;:<;;;;:78799;9965:877776667676567554743554235464455453344265544444345564321///.-0+/-+-+-,-,++.,,+-+++*+,+++**++**+++*)(,**()*)*))))()(*')(('+%&')()()'(%(('((''((()(')()'('*)))*(&''(()((((&('((('(')'(('')(''(('(''(&)('+(/6878;7.()+6:6 JJFJJIKLKIHIJHHHJHGHHGGFGDGGFEDG@HEEDGHECFEFEFFDGEFBEDDDGB@DBBE@FBBBA>@=?>>@?>>?B=>>==?<=;=>==<==>==><=>==;;=<><<<;<:<<<<:;::;<9788899789886688687886555564337745575543315535543344455543333345555431///0-----./,+.,,,+)+,,,-,++++)*++*)),)+*+))+**+()))',*))))*()'('()())(('''(('()('&'''&'()()('))('(((''(((((*((((%('(''''('((((*'((('''''(((()'*(0787983*((/9<8IGNGIIIILHIHIILGFIHGGHFHEFEHEFJFGDEFFFEEDCEEEGEDDDFDBDDCDBCDCCCABC@BA??@AA><>?=@?A<>???=>>@>@>>?>?:>==<<<=<<:>:;9;>;>;7;:9:8;6878887;9787777959677875555644344454403355333657445344324733454465664342-1--,+/-,.,+,,+/,*++-,,+++*+++*))-+++(+*)+)(+(+*()))*)())))((+)))((()(('('''((&&(''%''*((((()('(((()()(%(())(('((*((&'((('((((((((((''%''(((((().87772.)((-;=8JJHJHGHGGKIHHKHKFFFFIIGDFGHFEJGGGFEDEDEEDCBFEEBCDAEDCEBCFBAACAD@@C?A@?@A@@@>@>>=?<==>==>@A=><<@?<=>===8<;?<<<;;==;;<<;<;::99977:8788888877767767767754454454344534533543233442025433333343425453422010...--+,,/,,-,-,++++-,+*,)**++))+**(*)**))*****(**')('(')()()((((')')()(&')'((('&(%('('''(((((%''(('()''(')%()'(((((((%&'''&'()('''('''''(('()((.66682,(((.==/ KHKIHPGIJJJIGIJIFFFEFIJGHGHEFHGGHGFHEECGCCEDDEDDBEBFCAADAA@DA@C@>>@???A?@@?@??>>?A=>>?=>=A>;<>>==;>=:;?;<=?;>;::;;:8=;;;::998<=4;77888887769698776565543555554235243333413441344242433215345454332000.1.,..,,-..+.+,+**,++++*,+,*++))**,**+*))))+*(+(()*,+(('+(('())(())('(()(''''(('(()'(*&''(''')*''(''&''('''+(%(('(''(((('''('''''&')'&$'&'&('((+177541))'*/=4% KKHHIHJJKJJHJHIHGGFILGHIGHGIHHFFGFGEGEFCFCDEECCCBAACCBCBCBC>DEA??A@?@??=@?@@?A?A>@<=>?<><<<<;?=<<:===:;<=?><<;<<;;;9;<;9:999:;:799778898:998666685684575555343344646333222223334525335143354446645/00///..-,.---,,-,,++,,))+-)**+-)+.)+,*))*)))()))*())())+)')'')(()(('*''(*'('&((''')'''('&'''(('&((''&''((('&)'''')'%(((()''&''')(&&'%'''%'')'''')/67454.(((*361 JIKKJHKJGGJHGILKIGHJDHEJHGFJGHGHFIIGFGBDDFDDCCEEEBDDABDBCB@DGB?@@>=A@@>@>?B?<=>>@<>=;====@=?><<>?=>=;>;<=<<<=>=>?:<<;;9:;;;;;;::999:99:99:888<976766778785664844465565444533345512354212223328555333142354554220/./0./+..--,,++++++,-*-++*,+*++++++))))(())))+()()*)'*()((((*()'(''''(('''('*&((&(''''('(()('''(%'''('(''%'(*'(%)((((''&'('(((($''&'%&''&&&&('('(376331'')*-34HJJJLJIGHIIHHJLGHLIGFGEHFGIGGHFJGFDIDCDDDEDECDCECDBGBCDBC@BA@A@??@=>>@???@A===A?=A==>==;;==<<::;<:::;:::;;;:<::89998:98798867766767664475:46;36555462.62146432223431222343646332512217443400/0/0-,,),,)0,..**+,*+,),++*++*)+)+*)))(()))))+(&+()((+*()(&((('''('(())(('()'('((('''(&)((*)((('('(''('((''&')((&&''&'%'''&'''''$''&''&&''$%'()(*56402-)'**/3)IJGKJIHIIILJIIGHHIHFEDGFGKIGFGGFFHEEGFEDFDCDDCCCCDDCBBBBCEA@=?@?@?>?=>>?>>@?>=====<>=;=;;=<<<;9:;=:::::98<7;;;;<;9<9:99898897768985657766465655444575532433343513344323322013225252213232344330/////+,---,,--+-++++*++-++*-*)*+*+)()((*+()))))))((((**&(((''(''''&'&('((('''(&'(('''&'&'(('(('()'&'''&)('(&&%''''&&'&''''%''%''()'(%&#&(%$&&&'()*54200)%()*-*&GIIHHIIIKJKHHHGIHFFGFGFHIDJGKFGFEFEDBCBEDDCECDDFBCDCBBBA@AC?C@A@>@?>A??????@?;@=@=>=A>;=<=:;=;=;:?<<;:::9;:=5>=<<:9;95989;88778796777:77657655574634437734333444333433424222121230433213222322320/1-01-+,-,,+-.,.*+*+*,/++++++,)*++*)()+,*))((()()*)((('**(&+'**(('((')('('('')(''('('''''&'&&$&''((&')(''''&''&&&%'&&'%%&''%&')&&'(''((''&$'%(&'((/5310+'#)),,/$HGHGFGLHIIGGIGKGGIHDJGHHHGFEHJFGJDDFEBGECHAFCCCEDBDCCCCBAA@?@@@@@>@@@?=;?A<>>B;<==><==;<:98=:99>;899888=89:88897887778;886656648555633444433433344322333233232300113415114223323222.2-2.,--+,,++*-,,,,*...),++++)-*+,)*)())+*))))()()))())()('''())(''(()&''()'(((''*(('&(')&%'&%''(+&'''(((''&''''%&''%'''(&&'(&'(%'%&'(%%(&%(%&$(((*15210)#&()+,&GHHGGFGIHHGMEHFGIKHEFFFIHGEEEDJGGGDBFDEEEEDDDFCBCA@BADBCA?>?@@?>?B@A@?>>>??<;;=>===;;;<:<>;;<<<<<;;;:;998<=:9:;88;8989898:9:9868785777765757555454344532243324422222242201142331221234222232421210//.,,,+,,-,++++++++-*.++++,++***+*)'))*+))))((()(()()))'('(()))(((('''(''&*)'''((('&'%%&&%&&'&)''&('(''('''''%$&''&'(('''%%&''&%'&'$%%'&'%(%(''&+3312,)$('**,$KHGGGIHHHJJEDGFIGGGHGEEGFEEDDFFFEFDHCDEEDDCECFDBABA@ABBCA@?B=>DC?B@?@>><<>=<9;?;>=<<:9=>;<<;:<>::=;:::99:;;:99:799:9997799967:988556767766565455167474331125221123224213212344.22101443112333330./0--.--,.*++,+++++*+.+*+++-*+++**++*(*(()))())))(()))()(+())())((((''(''+')'')'(''&%(&'$'%''&'(('''''(()#&'''&%'%''''('&%'&&''*'&$&%%&%&''&'')&'+*244/1%#('(+,GFJHGHJHKKIGEFHGJHGFFCFHHEEEEEGFJEDCCCFEDCGBACBDAC@@@?DBA@?=@>>?@>@?>=>>;;;8=;==<;9:::99:;:9<98876:98:9989897686556696558666546363443442432432316022232201205222222122312232511/2//-,-,0+,+,,.+,+,+*++),,+*++*+,++))))))()))(+**'())())'(('+*(')&(('''((((())''')%(''%&%&$('&'&'$'&''(('%'%&''($&&''&'&%'%''')%''&%&&&%'('&'%%'''%/2231+$$*&*+' HFGHGHJILHGMJGHGGGJGEGFBHFIEFGFGFFEEDABEDCCCBA@ACBA@@CCBAA?@>>?@@@@>==>>==;<;;;A=<=<9:<;:;;:<=;:<:;9::;;:::9::8766696;578948776665646556676744544343563515335316222212210112000/13222222224311//..-.-++++++-,-,++,***+++)+)+++))*+*(((*')((*)*)()())-&((()('(((((((''('('))(''%(&&+&''%(''&''')('''&'(((''%&&&'&%&'&''$'''&&'&%&%&'&&%&&&&''%&''''/421/%%''&()# HHFJHILIKHHJFGHIFHGHEFEIGGEEEFFFGEGCAHDFBDBCC@AACB@@@@C@A?B@>C>?>>@=><>>?;<;9<:<;><<=<@=?9<;;:<;>9;89:<9899988696;998:9:88967996556649676776644345445433447422404221211212/1///001212121221220//..,-/-+,+*-++-+-+.+,-++,**+((*()+)))+'+)())**('*'()('(()()(''(((')(((()&)'(('&)('''+('((&'&(''(&(&('''''&&$'%)&&%&'&%%'&%'&&&'(&%%''&&')''$%'&%''+2321)(%('&)) HHHHIGHIIFGGGFLJJGIFGHGEGFGEDCEDECFHGDCBICCD@BAEAAD@@@@??=>?B@????B>@C=><<<=:<=;;;<;:;::9:::9;;::9::9887;;7:8678898:6688;555566576<56873735545745373532535221131112412111/0032212/232602/-/).+/-,,++/+,,+),+-*,+,+*+**+))*))(()*)(),+)*)))(()((()+(()('%)())*'('((('''(')('&*'(()(('%''(%'&)''(''('('%&'''('''&'&%&'&&'''&%%&'''''&%%&'''&&#-223/($%''&)%IIHHGMHGJGGFHGHGJJGEHHGFEDHCFEDDEDDFDCGCD@EEF>?A@ACAA>?@?>>?>????>B>;<=><==<=<:<:?<=;<><;9:;89:997:9;;898;88899:7677778896756685:7653646674545634345330455222032122401133112/111111/012100210//.+,,,+,-,,+*+++,+,-,)*,-)(,(*+))()+))))()))(())(())(((()+'('(*(()((''(''(&'('(('(('&&'')&('&('''&&&'&%&''(&&&&'')&''(''&''%'&&&$%'%'&''&%%%%'''''&,43.,&%'($(( IGGHICHHFGIHHEHGHEDFEFDFFGDEDDDFBDCDDDDEBEDB@A?C@BB@>>B?@??@?=>>>><=?>====<<<;;<<;9=<<8:;<:;9;8899;899:89;9999::88677787766677555746554454565433443/554434223134222204232110102101100012102030/-,-+,.,,,+),++,+)**)).(-*,+)*+))('+*)**'*()((((()))*(((((('('('))((('%((''((('(&%''''(''(''('''&%%&''&%$&(')&%'%&'&'''''''%(%&&'%%&''''%%$$%&'&'''.32-)&%'&'(' HIHFGGFFGFHHFFIGIGJDEDBEFFECCDGDEDCDBCDBCCCBA???@BA?B=A@@@?=A=>>?@=<=>===<=<;;;;:=;:<;;;;;;99:;:=989997;686:887599588777767749575:757444446654534433204335421223132122222122411111010/00204/0/...*,,,,/,+**)(++.+*.(-)*+++))*)))))()))(()'((())')(((()''''(&))(()''((*(''''((('&%''''''&'$&'''''&%&('%%%''('''&%&''''''&$'&%)''%%%%%&%$'%%$&&''')232*($'')'&&  KHHIGLFIGGGGKJGHHFCEFGHIEDFECCCEHDDFDDFCBDCB@@@AAB?C???B@CA??==?@@=<<<;><<<:;:<;>>9;9;:8;:9;;<;;:=;8788888787877766846777765867665346654453474223222321122121111311/002002010/301/11.0/011020/.../1,--+++++*++**))+**+()),(,*))())))*(''())())')%)((('''(''''&)''''((''''('(''(&&''(''&&&'$'&&'%(&''%$'('''&'%&%%'&&'''&'%&&'$(%%$%%%&#&%&&%%&&',230)%$''%&&JIHGGJGHGGGFFFHIFEDEEGGDFDDDCCCDDCCDBBAACBC@@@AA??@AA>=>?>==>>>@?>A<><>?>=;::<<=989:<;::;:9978;;<:;;:;98877688876956665677578667548645643643462242232213112122413303/10310021100/./00/0110.-..-/.+/,,++,(++++++++*(+*,+*,**+)+*'))))(((*))((((((()((()''(''&)''''''''''''&('''&%(&)&'&(&%%''%''(&&''%&%%'''''&($%'''%''''%'%&&&&&$&%$'%&$%%%$($&-22*("%(&%&$HJIGFEGHLHGEJIGEDDEEEHDBDEDADCCCDCCD@DE@B@CACAA@@@A?>@>@>@==>??=?@==?;<;:;;;;;;;=:::8<:99::99::;9<7:9997;788;7<7768:8:775555:756682555645644432245132363220420022232121002/2210//00/01/4102/./.0../,++,(/,++++**+***++,**+))+*)))()))()')')))(((*((('*()&''((''''''&'''''''((''')(''%'''&''%''%)%(%''(&'(''&''&'('''''''&''%%&'%%%&#$&$'%%&'&&''12,/($'''#%#   GFGHIGFHGGHGEFFEDBGHGFFEDFFDCABDCCDA@CC@@?AA@BAAD@?>@?@?>@<=>@@A==;=;>>>=?=<<<<;:<:==;9;::98::98:889:98;77:8889777766788;:88584645554455725432332434222411010220101210110000220.1//1011100//./..---.++,.-,,+)*)*,*)*++++)(*)**)(())()'())*)*')()))(()((*((('''((('(''%'''&%'&&&''('&'&''''''&&&'$&&'(&('''%'%(&'''''%%&&'''(($&'%%$$%'%%%%%&&''*10.)$%''""$ HFHFEFGFFFEGIFEDCCEEHBECEEFDCCGE@CBBAAAAB@A?@@CAAA@?>>?>>B?>=>>?A<<<;;?>==:;9=<::<:=;::;;9::<9::8:89:9987898877998767787:584768675554342233532222443121310010001120001110/0011001//0/2301000/.,,.+,+,,,++,++*)*+*))**++((((*'))())*)))((''(((+())))())('(&(((('(''%&%%('''&)'(%)'''&''('''%%&&&''&'$)('&''''$''&'%&$'$&&&%%'&&%'&$%%$%%%%%%%&'',10.%$&''#$'EFIGGFIIEFEIFGFBDGBEEHCEHGEECE@CCEBEFCCAAA>A@AAD@@@>=???>==<<>??=<<<<<<=<;:;<<:;:;;<:;:;:98::>9;88899986=8:79579986677855788644356552345553232221123322152010111//1010.3///2///1/0//3100.0/.-,-.+,.,++,,-,++++++*+)+))(+()',*)('(+()))*))'*(*%)()(((*((()((((''''&&%)%)'''%((')''''')('''(&$&'('&&%)'''&&&'''''('$&$#(&'&%'&%%%&'$%%%%$%%%%%&#'-00**%$)"##$FIFIFEFGGDDEFDDDDDEDEDDDEEDFCCCAAA@@B@@@A@BA?A?A?A>@?=?@>>=;@<=>=<;<<<==:;>;=<:9;;:;:;8=<:8:;9;987;9;988876557988577778454652455666522333444/211321311112121000010/00020/10/.//02//0/01,.-1-,,,,,--(+)+*,++++++-)++)()'+)))(*()(()(()(('(&()()()'((%'(((&((('(''&&'&%'('(''''''&''''('''(&&&&'&''''&&'&%$&'%%'&''&$&&$%%%%%%%%'%&%&$%$%$$%%$##(-1,%#")%!!"   GHGGGEIEHCEEDGHCDEGDDDDDDDC?EDCAE?EBA@AA@@@@?@>>>=>=?>?>==;B>?@<==;<<:<<<;=:<;<>::::9;;<:7989;;8;888679<769688974<87664966547655447322134422421210120332122100002210010000.01./102//0/11/,//.,+,+)/*+(++,)++,++)++)+(*'+(***))&)()))+)(()(('()(((((''''&(((''')'''('''()('''&'&&''(''''(''&%&'''(%&$&&&&&&&(%$%&&%(%%%'$%%%%%%&%%$$%%$$$&$%$$$+01*%$('$ "!  GHHGIGIDFFJDEFFCBEDDEEDEDEGEGGBB@AAB?>D=@@@>?>>@>@=@?=??A=>?===?==;:;=;9<<<;::88:;;;989898999886866<696778786:579968466443465555332223334132214025/5114221//1000/020/3012../1/.0112/.,.//-,+,,++).+,++/.*+,++)+*(+)))+-)))))*()-()())()'((((((&(''(()'*&'(&&''&((('&()''('&'''(*%'(((''(&''&')'%%)&''%('''(&%$&$&&$&&%('%%&%&$'$%%'&$$&&%$%+2-($$$)% % HFHEDFHGFFFEHFCBGJECEECCDACEBBBDBABACAAC?BA@A@?<==<=@=B=>>?@;==>;>;<=::;?<9;:;8:9:<8:::8998:76:8:97667788:877767655865896744586643222245422354232330/221101210/201011//002//.0./-///01./,-..---+,,++.+*-*--+*-))*+(*)))))(-+()))+))'(*)+'(((()'('(('(&%('(()(''''('&'('')(%'%''%''(''&$''&''&%'('(%&'&'%'%%&&'&&%%#$&&%%''$$%'&&$%#%%%&%%#%&$&00+'$$&("    HHCDFGGFFEEFFDFEBBCDHDFCCCECDAC?CB?BB@@AA>?@>AAB??=??@>>=;><@=<<====;<;;:::;;9;;99898:<;:9788;8:<86778986766677766676765547555544322226525340433101013100102000020101000///..0/-,,///.0.,,,--.+,+++,++-++.*+***-*)+)*)**),)+)))*)*()('(*(('((()''&(')''(&$''''''&((''''''%&$'%&&'('''&&&&(('&%'&&&'''(&'&&$''&&&%%&'&&%'&'&$%%%'%$%$$%%$$$%%$'1/,%$$($ !  FHHEDFHGGDDEEGHEDDDCBFBCBCD@DBCBAC?ADB@??>>A@??>>>><<@=<:?==><=@>=;?<>:;:::9989:;:7:>7;99:9897::9998854755687666657667656665458044322413314344423422124/310//11/011000/1/02+10.-./,1..//-+++,/*+,+++++++-,**++++*****))+*))+)(*)*)+()(((*)((('(')((')&%'()%&'%((''%(&&&''&'&'(%&$('''%'&&''''''&&(''''(&'#&%'%%%&''&&%%&&%'&$$%%%%%$$$$%$%%%$(0.($$#&"!! GFEGGFJEEECCEFDECCEECEDBCDDABBADCBB@A@@?DC>@?>>@B?@<:;?<;?=A==>=<@:9:=;:9::;8:9:;:989<998999;4:999989867788897759644545556455537543323453233211002011301211212000/2/1/..21./0//-/.0./...-/++,,+-++,,,.-*+,+*+*+,+)))()*+)*),))(+)(*))((((((((')((&'(&'%'&'(%'%)'''(&'&'&'$''&''''*'&''(%'&'&&&&&&'')'&'%$''%%%%'$&&&&&&%%%$%%$%&%%$$$#$%&#%%%(0,'"%&%! GFEFIECGDBDBGDCCBDDBECBHFB@DECCAD@BB@B??@>??@<>?<<=<=>999<<;8::::;99:;;;99:998889;<79777897657858797768655754453454843444222425230003233231311112/01//1000/.0110*0..00/../.--.-,++++*+-*+/(.,),)))*++()*++))))))()*)()()*((*)('(((('('&''&(&'&%''&'%'&&&'''(&&''$'&&'&')(&%'''&%'''''(&&%%'&$''''&%%%($%&&&$%%&'$$$%%%%&#$$$&#&%$$)+)#"%("!  FFFFFHDDCBBCCCCFBDEEDDEABADCAAFDA@B>B@@ABDC>@@>>>?>=<<<>??>??;==<::=;<:;<;;89;:9>:98:79678;;977:87788:78778597778:9574654815597485443322211102/02040410102105/312//2.0/.//1/./,0..-./,-,-,,+*+*.*+++**.,)+))))**+,))(()+())((*())+')))()())(((''')''''''''&'')'(''&(((''&'')'(''&'&(%%&'''''&%&&%&%''''''''''($%&'%%%%&$%$$$%$'%&%$$##$$%%&##!+("#&'  DIEEDFDDCDCDDCECCDICBCEAFE=DDAAAA@CCA@B?B?ABA@C??=A==?<<>=@@>;<><:=<;:;<;:<;9:9:9:<989877=878876587:86768868699746847544344456536263341250211113110112311000.20/0//0/0./....100,-.1..,1.-+++,++++)-+**+,,(*+*)))+*)***)))()))())(')'(())*'(((((&'$(*(&'''''('((+&'''$'&''%&''('&%''&&$'''''&&%%%%'&&%&'''&''%%$$$&&$$''&$$$$&$%#%$$$$$$$$$#($*(&#&'$   DDEEECEFFFBHCDCFB?DEDDBAAACABAACB?@@??A@??>>AA@???<@>=;;=@><;<<==<=;<:<::;:::::899;989988799778656676689668454857555563445475546614331223112212200120/1110/0/0/000../100...10..-.-..--,),,-,,-,)(+*++*+*,+**))))+*)+*)(()**(')(''(*()(('*'(((()('(('''''(''&(('')&%&(%&'&&('&''''''&'&&('&'&%&$&''''('&'&&'&%&'&&%%%%$&$%$%$#&%%%$"$$#$$$#&-,(%# &'  FFEHHDFFDDCEDEDC@@AB@ABBAABBCB@BA@ABA@@@@@A=<>>?@?>?>=;==<==<<<>==;;=:<9<8;;:<9::;:9:978:86978856668668977673986657655454435457241053223223004122211/11000/.10//./00////.--10///.//.++.-,+.*-),++++*+,(,*+****(+++***)*()(*))')'))+''(((((((((''('(''''(''()(''''&)'&''')'%%&&'&'''''''('&%)'(&'&(''(''%&$%&%%'''$'%%%%%##%'$$%(%#$%$#"#$%-11+$#$'#  EFCDCCDDCGCCFDCCA@=A>A@ABAABBA@CBBA@@?>@@?@?<;><=>>>==>;><;;==><<;;;::;;:98::8;:99999::::998877:77267665673746244646534434444317240124423304412/411111001111*0/1/00////.//0/0//.0/.+-,+,-+0+,++,+,+,+-+-++***)+)))+))+*)))((()'((((''(''(()('((&*(((''''%()'''''%&(''(&$&''%&'%%&'&''''''&%'''&'(%('%'%%%%&&&%'&%$('%&%%%$%$$&#%$#$%%$$#$$*-,(&"'%! EGDGDGFDDFECECCCBF@ADAADAACBA?@B?@A?>>>?A?===<=<<;<=<<<<<;9::=;::<;::::::9:9:;99999:8;7;:89988:95786687666686853464653142252223522032346334310130222020/01002//0/.000///,/0/000/0.--0,.)/*++*/*,*++++,)***)(++****(*+))('()(('(**(((''((''(((((*''(((''&'(''('''&&''''''(&%$&%''&&'&&$''&&&''&&''(&'"'$%&$%&&%&&&'(%%%'$%$$%$#%%##!%$%##$$$(''##$$  EDBBEEEFEEC@EAGDB@@@AA@@ADA@?AB?A@A@@?>>>>A<@=<<;<;?;;;==::9;=;;:<=;::::::999<:9888777=989;88889:766669575565445545811716523442231431216132112/221103012311//.2///01.//.--//0.2-//.-,+,+++,-,,++,,+*++,++,+)))(+(+)(,*()(())(()(*('('(')(()('((($((((''''"(*'('''''&%&&&'%&'&&&$''(&%&&%$&(&'&%&%&%'$&((#%'%(&%%&$(&&&%&%$$$%%%&#$#&$$###!'$'&$$%%  CDDCDEFECBD@BBDDBCBBAA@BAD?BC>B?@ACB?>>?>=<>=?>9<<;==;:?;99:=9<:;9;;;7:99898889:88978899:88777898865569457965545783243344332322235321222333132212421.1/0000////200/..1-/.-/...0/..,,,,++,++,,,+++)*+))+)+*++))*))*)(())('(((+(*())&'''''((''''''((&'(()&'(%(('(''''&&%&'&%%%&'%''&&'%%%%(&''''&%%''&%&%%&&'$$%&&$%('%%%%%$($%$%$$&""&$$!"$$'&$#$%  ECBDCDEDDBA@AABAB@B@=?AAA@@AD??A>AA>=??==;?><=@;=<=;=<:;;9><<;;<;7;;8:888978899998989;88798768777665779566556444434434324422224411122100001/011/01001./00///3///.../-.....,)--/-,,--+-+-,+*+*,*,)+++++*+()**+))))((')()(())()))'(((('(')''('('''(((''&''&''&'(''&'&''%%%%&''&&&'&'%&%$&''&&%%(''$%%%%''%%&&%'%&''$&%$&'#$%%%%$$$%"$$#"#$&%#$$%  GBBADEECDBBCBABBCBBBDB@>A@@@AE@?BA@???>=====??==;;<<<>=@9;<6@:>;9<;<98<9:88:69:9:<;99799868888898::766567555853556544364232.522252012212221101011020011044////.3.....////.--,...+.,+,,*,/)+,,,,+*+,,++,)+*,()+*)))()((,')'+$((*((()((''((('')(''')''((%(%'''''''%'&'''('%%'&$''+%)'(''(''%%'''&&%'('%%''%(&&&&&$%'''%'$%%%%%%%$$$$%$%$$$"$&%%#"%% DBCEECDFBBB@BAAABA?CBA???C?BBF?@A=B=>=>>=>>=A;<;===<<;@;><<;<<;;=8<::=:9799:;=;88889:887776777778654655465644644443433231123112200221/222.11/0200103/0//////0//./0/0/..,+,,,++.,+-++-,,++..+,),++*)*)*+()*+))()**(+()(()))()()()))''('''(&'')'(''('''%&(''''''&()&)('%$$(&&('&&&&&''&'%'''&%&%&&'&&'&''&&(%$'%&&&&%%'%%$$'#%$$$$$$##"#%%'$###" FFB@BCCCB@C@@?>AAADB@@@AA?CA@>B>>=@=@=<<;:;=<;:=;>>@B@C@??C???=>>?>>===<<==<<;?:<<;>=;;;<;==::;8;:6;89::8:89:7987778;7:;95>86877568632553364333320445334211452/00002420.4321-02101////...12-./.0-+///.-,+,-++..-++--+)),+,+)*+)))**)),))))))+*',)+'((*(((('(()(('')(((''&(,''$'&(('&(&(''&''''(((''''&''('&''$%%%&$&''(%'%$%%%&('%%'%$(&'%%%%&&&%&#$$$%$$##$%$"#"$""""$'%#$$! ABDCBBCCC@@D@CAACAD?>AA@A????B>>?=<=>>===?><;>;=<;<><<>;:::9=::::9::888998967887678779966476669675567565674552455354634343113343201111110301100000/00...//,13-///......0.-,.-,-,.,-*+,++**++,++++))*)*-(-)(++,())))*()'*()'('''((*&''((((((('&(('''&'&'&'''''%%%&('(&&%&&&&(''('&%&%'%'&&%%'&%%%%'&''%%%%%'&%%%%$$%$#$%#$#%$#$$$#"#"#!#"#$%#"#& CCCDCAA@ABCAB?DBBDB@B?@=AAAB???>@<>;=<9=<:><><==:99<:<:<:;9:89989999:788899989757866577867666545555456553344315333432124212211111000002/0/00/0/....0./..//./--+-../.-.-+,,--,,-+,*++++++***++-)**())*(()))(*(*'*(*))((((&)')&('&'(''((&&()(''%&'&$''''%&'($''&(%%%&%$'&&&'&''%%%'''&%$%$&$%%&%&&%&&'%%%&$%%$%$$#&$$$$$#$$##$#""##$$$"!$"  BCBBCEDCCBCAAABCBA@@B@?=>?C=?==<<<===>>=?>==>?<;=@<<:=<;;<;;:::9;9:::;:;9:99;:9;8;;:;78879:86687776877566:65565555455254452633422232/4201223111210001110//-001.10//....*/-...-,+-,,--*..,,+,++,*+,+.)+,++++***)))*+)*)*()+((())*(*(*(('('()((('''(''('(&'''(''('&&'&&(%)%&&''&$$%$&&%&''$''$(#%$'&%&%%'&&%%%%&&$$$%&%$$$$&$$#$%$$$$%#$#$$$#$#$$"$$$####  ABBACD@BBDA@A@A@A@@@>=AA=>@?>A@??<==@>=?=><=<;;=<9::89:<88::;;:999979:9999<8779::887768777657565476656554464256542244412322422022101111101000////01/0/0//0/.../.../-.,--,+.+1*-,-,-,+-,-,+*++*+++,*+)))))**+(*)))))*(')(((((*+))&(((('''('&(&&(''&&'((&'&(&'&&&%&''$'&%%&&%'&&&&''%%&&&&&'%%&$$&$'%%%%$%$%&%%$$$&%#%##$#"$#$#$$"!"##"!#$&$##$! BACCD?F?D@D@B?@@@@A@@A=>>@>@???>??==;<=:;<<::;?;999=999::=;;99878:9:89:;6998<8987666769775;686656534444343344442222342230310121341010/00/031/0/01.0//////./-.-0,,/,-,,-++++)...--++*,,,+++**)+)))))+))+***))'*))))(**+*()(&)&'((''''''()''&'''&((&'((('#&''&''''(%%%%&&$''%%'&'(%(&&''%&'&%%''&&%%%%%%%$%%%%%$#$%$%#$$!$"##"%""!"##$''&""$ CAADBA@@?@B@AA?@BA@>AA??:C?@@=>>=;===<>=<;<:=<<::<;:::99::99<=::99:9777898;679998777748:6:774567655547433723253334534322234231100001/300/0110100/0/3.0./..1..1,/-/.../.+-.,,++,.,.+++,+++,++++),-*))+)*)*'+)-*())*((*()()(((('((&)''(('(''''''''&'&%%&''&('&%%&'''('%%%&&$'%%&'''%%%&''&'&'%%&%%'&&&&$&$%&%%%$%$$$$$%$#"#""""$#"!"!!"#%%%#"%" DBB@BAB@ADAAB@??A?A@?@?>E??=@>?;=><=><=<=<;<<<;::;<<99;;9:;::;<<78:7;986:8988889878775965567767257654444334233134222333212/2320011/12210010/003///10//-//..1/,00.,.-----,/.,,+,+++++-*+,,,,+++***(******)+*)))('))+)()('('(((((((''(&#'%)&''&&''''&%'''''''&$''''''%%&%%&%%&'&%'&&%%%'&$%''&''&&%&&&'&$$#'$%%%%%$$$%#$###$###"#""!"#"$'&$""%!  B@B?BBCDAB??@@@>>>?>>@??>@@A>B=?=;?>><;<<;<<;:<9:;<;:::9:::999:98888:7869;85785;8787785765746575465464245341453342543231111320/0120400110//.00./.2000000/,--.+.-/-,--,,,+-,,,&,++++,--,*,(,,++**)*)***)'*))(*+(())())(((''))*))))'''('%''''&'''('''%%%''''&'''''(&&%%$(%%%$'$'%&%$%%'$&$%&&&&''$%$&%'&'$&%%$%$&%$$$$%###$"###""#!!!"$$'&$"$%"  CBBCEB@@ABB@@>?=A>?=B>?A>>?>>>@;==<<><;<===?>;=;:;=;::9::;988:999978679318999798:77777778755654577644043553325422432231540130///020//01110,.10/.-0220/0//,.,,,.*../,++.,).,,+-,+++,,*+,,+,*-+++++*+),*++))((*+((&(()((((%('()*'((''(&&&)((''%'(&''&'&'''''''$(%$($$%%&%&&%&$%&%%%&%%&%%%'%$%$%%%%%'%&%%&$%%%$&&#&#$&$%##&$$""$###$""'''""""$  BABDCB@@@BA?????>?>><@=>=?<=;==;>;;<=><===@:;<;9;;:<888:<:89777987<89697:88977777769556554747454443563552436423533210/0/02212/0//111.0/0/0/1200/00.-,///-.0/-,.-+-/--,.++*+.-*,++-*++++)**+*)+*,+))()*,(+*))*((((((('''*'('')'(''('&(''('&''''(''&%'&&%$&'%&%(&%&%$%%(&$%%%'&&&%%&''(%&%&'$%%$$%%%%%%&%&#$#$##$%#$##"#"#"""!""$&$$!!$" BADCCCC@@@AEA?>=?>>????>==<;@@=?:<;>;=>;;<>>====?=<==@?=<;>;<==;;::<=<;<>:?;9:>87<688<98:;87796999;8;9:8777878578876356584654454322323346632222332030121//1.1/00//10/////001/0.0....,,0.//0.0+.,,,,,.+,,,,+-,+))**..)*++***++()*())(**))**')'(((+&))((('())()(('''('('''%'''('$&%%&'%''&%&%'%'(&&&&%%$$'''%'''&'%%%&%%%'&$#%$%%$$$%%%%%#$#$'&##"""#"#""##!"!#!$$!  B@ABA@AAA@@?@;?>>=??>?=>?>?=<@==<<:>==>==<>>><?=?;<>;99=9=::::;:8::::;:999779:97;8867778879779768976678978574876655144645445523521323/31222012221/01//00//1//00.10.///0./..-.,,,,,..-.,,,,++++++*,/*/,,,+++*+**,+()+)**)(((()))*)()'(''(()()((()(('('''(''''''($((%&'(%$$&%%('$($%'$%%%%$%'%$'%&'%%'%&&%%%%&%%$#$&$$%%%%%%%%%&$$$$$$$$$"#"#!"!!"! !  A@A@A@@BA?A@>>=>>>;?>><<;>==>;=<<=<;:=<:7>;::<;97798;::89:8989:988888;7775;766685877787755645582757543445644526224223332104/1221110///0/2.110/.//..////0....,-,,-,,,+,,,,++,+++*-,,-+*,,++,**,*)++()+())())()))((*()))((%'&((()(((('&''(''('%('&%#&'''&$'%%&'''&&&%'%%$&%%'#$%%'$'%%&%%%&$%&%%%&%'$$%&%$$%%&%$$$ $$$######!"!!"" !  @?B@@?AA@@@=><<>=<==>==<><;;<:;<;==;;<<;=<<;9::;7889<9<9899988789888::78886766467777677646557545366543445431454322244232122410310///21/0000/,.//.../.-..,-../.,-,-,.-+,*+,-*,,*-*,,./,-++,+*,+++++)))))*(*(*(*)*)(((()((()(((')'(&('('''('&'&'&'&&&''&&)''(%''%%%&&%'&'$%%$''$%&%$$%%%%%&%&$%%#%%$%$$%$$%%$$#$$#"$###""!#""!"#!"!  A?@@@B>?ABB?@=;<>=;=>@=<8@<<>;;;;;=<<;;;8;;;::;;;99989:;<<<;=88888:988:7987676967858669545556455656554543452222312132442211201002///.//00112/0-//../+3-....///,.,--.-+-,**-+--+*,'++,+),+++(++****')))()('*+)()))())))(*(((((''%%*')'+&'''(&$'''%%&''&'&&(%%&&&%&%%&&&%'%'%%%%&%%$%%$($&&%&%$$%%$$$%%$$$%$$$$$$$$"""##""#!"%!"!""!! D?BAA@=C??A?><:<:><;<=?A<;<<=:;;<<;:;<<;=;;::::;:;988:;9;:::898789877879988:5566759565588567534444473374232322321202223422/0011102/0////11////0/./.0,,1,-..1/-,,--,-,..,.*,+.,,+,.++,,+++++,*+++))()(()(**)))+*))))(((()()'*''''(((''''%'&('%'($%%&'&''&''$'&'&%%&&&&%%'%#&%%%&$$#%$&$%%&%%#%$$%%$$&$$$%$$$$$#$#""%##""""" "! #""!   B@@@@@A?@?@>A?=:??=<<=<=;<<<;:;<:;99::=:=7:99;:89;:8987888777887885677556789866676332575451133334431233222122111102301/1/020///./10/.-.///.-.,-.0,-.-.,/,,,,,,-,/,*+-+,**++++*+,**()+,*())(()))'))))*))())(('(('('(''(((('&(''''$&'''&&'&&''''&&%%''''%%&&$%%%%%&%%%%&%#'&%%&%%$%$%$$$$%$$$#%$$%&%&"!$#"#"#""##""! "#"  ?@B@?@?=:?@=<@=>;=<9<<=?>=;=<:<>;:;=99:9::;99;989:::::997788:677889878766775777666664254623523423442143334022014/0000/0./010,0////.....-.//0..-/..,,,.-+,,,,+,..+..+.-,,*-++**(+++++(++++))(''())(((()*)(((((('(%(''&'&(((('''%(&&&%%&'&('''&&&''''''('&%%&%&%$#$&%&&%$%$&$$&%%$$$%%%$$"$$$$$%#$%&%$##""###""""""" !! !!!!  AA=@C>A?A@?>>@=?;=>====><;::<>=;=<;:<;;<::;8:;:=;:988::9988998:8887;989764546777696759755635825544432343221221352213411012-02./0.0/2//0/-./...-./0...-,/+,+/,,.,-,-+,/-+/++.++*+,,*+)*)+*)+**+**+*))*)%())(())%)'(())))(('%'''(''''(%'&%''''''%''&%%''&&'&''('&&&%%%%$'#%%%%%%%$%%%%%%&#%$'%&&%$$$$$$"$$&$$#"%"#$##""!"##!"!!!!!!  BC?@@>??A=A><=>=<<=><==<>=::;<>;?9:9;:;;:::<<9::;=9:99999888889788778:77877:5:56545566766395463333342434121532321331210411/02./0.01/00.0,00..-./-...----+-+.,.,-+-,,.+*,**,,,*+*+)-*(*))*))+))+)()))(()))()))(('(('((((()'''()'(&'''('%&'(&&&&%%&$%&%&&%%&&%'%&&&%%%%$$$$$%%&$#%$%$$%%$&%%$&$$&$#$$%##$#$###""##""#"##!! ""!!! !  + B@BAAB=>?B?>==?==<<==<<;<<<;<;<:::;::;<=:9:::<;;;;=9::<99777788988687497876886568658515849684533462333322423122323142252222013../0/111//0.0-1,...-,.--/.+.,+.,/+-.---,+,,+,(*+*)),++.)**)))))+())))()''*()((((''''')(((*(('''&'&(''''&''$'''&%&&%'$$&%%&'%&&%%''%$%$&&%#$&$%$$%$%$$$%'&$$$$$'$%$%#%$##$##%#!%#$"$$$# ""!""" !!!!   + >ABA>=>=@=====>==;;<==>;;<;:<<::99;::9><899::9>:;;:;9878:8937:79788:888859865445:974454466555433434426132436230224.2105613//2220/0110///-//,-1....--...,-/-/,-,,,,+++,++++*)*+)+++++,+)))))))*)))))(()'*()(()(((''(('('&'((('('&&''&'''''&'%%%'&%($%%%%'#%&%%%&'&$%$$(%&'%$%$&"$$$$#"$%%$#$$%$$$$$%$##%#$$""#"#$"#!$"""!" !!"!!!  + @@B@?==>>?>===>?<><;<=<:::;;?<<@@>===<>=;<=<:;::=;;:<:9<8::::;7789898:6:8888:86797<888666868987677355383645555355443346440324243430020/1/421121/21001/11/1..///./.,(,,....-..-/-,,/-),++,,+*+,,++,+**+++++++++)))))+))()))(*((((*)((*'*('(#'('+(()&(&%%%''&'&'&$%&'&%%%&&%$%'&%%$$%%$$$$$%$%%$%%$'$%%%$%$$%%&$$#$$$%%%""$$$!"$$#!"#""!#"!!!""! !!! + @@A>>>B?;?A@==?=>=<=><>@=;>;;?<;<:>:9:999:=;;::8::9889:8;998978::776888887777866999758855565:455556665443434345335443223210013203/1113/3/..1/0../././///-/-+/-+++,-,,.+-,+*+.++-+++,,+,++*)*+*)*+))))*)))())'+))(((((()(*((&'((')')'('&'''%''(&'(%'&%$%%&%%(%%%&&&&%#$%%%%&$%$%%$$#$$$$&&&&#$&&$&#$$$$$#$$$#$"""!"#""#""""""""!! ! !!  +  ?>>A>?A>=?@>=>=><<=<<9>=;9:;9:99C:9989:9::78:988::;;88887869678578677787765577654336466855553455344455613222112121//002001/11/2/1,/-./00///.-///,,,,+--/,,-.,-,,.,,**.+-,+.+++++**))*)()))())(+))))())')')*'('(''))((''''''''''&'%&&''%'%$(&%''&#%%%&&'(%%%%%&%%$%%$#$&$%$$$$%&'#&$%#'#$$$$$#$%$$"$#""!$!#!""!#""!!"""!"!    + + + + >G??=C@?>@?>=>=>=??<>?@=<=<;?>?<:9:<:=:88;:9:9989::9::8:8888888888889:76688887766676866767586576455456546483243643232212132222/201010/20/000/1/..00.///..,,-,,/++,,.-*+,,-+-+,+,,+*+*+++++,+)++-**)*)((*((()*(*')(()((()))'(('''('''&(''''''&'%''%&''%%'%$&#$$%$&&&%$%&$$$$%%$"$$$#$%%%###$"#$$$&"$%###$%#$$$#""!"""#"!"#"#!"#!!!!!! !   + + + + =@>==>>A>=?B<=;:>?::8<9:;<9:9:9;88;89:87;:=888;78788897:78777787777856737577765687655554454452534533223224441321/010011101130.01101,/1./-.-...-+,-+,,+,++,+,.-,+++,+*.*+++,+*,*++..-++))*)))('*(.())))))()))((()((''''&'$'''(('&%'('%%%'&''%%$%%%&&&&&&%&$#%%%$%&$$%$$$$$%$%$$#%#$$$%$#"#$$"##$#$"#$##$"#""!# "!!"!" !   + + + A>><=>:><<<:;;;9:;?9=9:789999::878<;787989973;87758:6777764765785676767779776765074433533431424512240442212/1022110121//21//-./.-/..,-1.,,/.+)-,,.+++-,++,+++-+,-*,++,+*,++)+,+*+**)))(())(((())')((&)(((''(''(('&''(&(''''(%&&&&%%$%%&$#$$%''&%%%$"%$%$$$%%'##$$$$&$$$$%"$$$#$$#$"##$###$#"!!!"""""!"!!!"!!!!!!!   + + + + >>>>?>>?;:;:=>?899:;99:=<:<;98887:::789:;:99<;79886869:778978777573568667555777646665544443444442212206120223/1002043101/200////1//../.---+,0.-,../.-++--0-,-,,,,.,,.+*+++,,++,()(+))+*)))+)(('))(*((('()(')(('(''''(('''''''('''%'%'$$%&&%%$$%'%&%%$$$$$'$$%$$#$$$$$$$$$%%#$$$$$$$$$$$!"$####$%#"$##"%##"!!""!! ! ! !!   + + >?@?;<:8=@9::>;88?9:=9;;:9778:=:::8;9:77977778<:87685678977677686676:753496545554332445423442113231200422031132210011//2/0/1./....01-+..,1/-0,,,.*.+++-+.,,,.,,,,+***+++++%+++((+)+)))+()(((*)'((('('((&')('''&)(''''''&''&&%%&&&%%&%%%%%%$$$%$'%$##$$$$$#$$$$%$$$#$$$%$$$$#$$$$$$$#"$!&%#&"$$""""#$"$"!!!!!""! !   + + + B=9@>9;=:7:9><88999;:;;;;878:99;<78887798:8875669755558789876656676665;97584776882224552527721213421120203000021/./0/00.///1../.,/..-,.-,.//0-+,,,,-++*/.,.,,,,+,+-**)+*+)+))),(*))*))*'+(*((('(((('')''''(('''('$'''&%&'&'%&&&%%$'%%%%%%%%$$$%$$&$$$$$$%%$$$$#"%""$$$$$$$$"$##$$!"###&$##""""#""!!"!"$"! !!# !    + + + + ;><<<<=;;<999;;8789:;9:969;:97:8<69899767688886787654567:988976674557474445545540553344536251-3307524123201/1111/////0//0.01/2/-..-/-,/++../.-+/,,+,,--+*/,,++,-++)++,**)*)*+(())+**)***)(())()'()('&((&'('''''((((''''&('''&%&&#&&$%%%%%$&%$$$#$%$&$$$%"'###$#%$"&'$$##$##$$$%%###$"#"$#""######$!#"!!"! !! ! ! !! ! ! + + + + + <=?><>;;::8;9:98969785699:9<96:7;9:688989978888975836577677887867567855657775676545664455643244222444114433211//1101-10/00011.//0.....0-2.-//....--,,+-.-,-,/+,+**,+,.+*-',))*+*)+(+)*+++(()('(()''((((''(((((''''((('''&''$%'&%&&%&'%%%$%%%%#%%%'$%%%'$%%$$$#$#%%$$$$#$#$##$#$$&"$$$#%"#"##!""#"$!###" !!!!! !!"!!" !"  + + + + + <;<><=;;:;=:8958666744548998;:88:787:89:698777787655599996687977869766555766568753554342442234322225263322221211/0002/.0//00//00///././1,./-..-,,+.*,+,,-/++,,,,+++++(,*)*+++)++**)))()+))((('((+''(((,''(((')('''%(''''&''%&&''''#(%%&%$$%$%$%%%&%%%$&&$$$$%#%"$$$$$%$##""##"#$##"$####"##$####%$#$"!#"!!!! !!! !!     <=::<::;9;<:5644323463377887588889896889:7788755786655898777:665777766656797454466443358753234544311254113213131//0100001./0//..-//..,/.1/+..,,,,-+,-.-,.,+++--++,,,--,*())*(*+*)((,*+)-))())')'('')((&'&'*''''''&%%'''%&'''&''$&''&&&'%%%%$$%%&$$$%$$%$$$$$##$##%"%$$"$$$%$$"""!"#""""#"#" ###$"#""""!"!!"!! !! !   + + + + + =;;=<:89:;:73233021225445787:877:88667878787589677655479786=577677885644476683364344443553223146112262/0010402/0/.//00//.2/0././/.//./-,,.-.,,,,+,,.,,.,,-,+,,+,+++++**)/')+(*()))(())))))()(+())(*()'(''('(((((&&&%'(')''&%%%''&'%''('$%%%%&&%$%%%$$$%$$$$$$$$$#%$%##"##$$###!#!!!$""!##""$!##!!"""""!!"""!! ! !   + + + + + + + + :;<:9>?89<553000420/10113555677:<86788866;78:777666577477667655485766554575634443735359661523623552420110/4/2110/.0021.//..1.1/--.//../1-,--.+0.,,,,/.-,,-.+,+,,++,+++).-)+)))))())())))((()())(('((()&)('(((&*('''''(('''''&&%&$'%%'%%%&%&%%#$%$%%$&$%&$$$#'&$$$%&#%"$##$$%$""!###$#$"#"$#!#"!$#!"""!""""!!" "   + + + + + <;;;:9:?98432/1100,,-./0344397986876:58758776:::755978<7776757565765633434543543343455346414433312220121110//.1.101/0110.//.///.-/...-+-,,.,.-+,++,+/,,,,++,,,,+++****(+,*+*,)))*))*)(()((+))((((*('&(('&&(()&''''''(%'''&'&&''&&%%%''%%'%&$$'$%&%&%'$$$$$$%$$$$$$%%$$##$"$$$""#$##"#"$###""""!"!!!! ! !!!! !!   + + +  <=;;;;=;:6430000-**)+..13347348898763898658=8656584774345795454655734344586625432435324455133321322222312.0///0/1001110.-00///,.../.--++-,--.-+,)+,.-,,++0*++-,++,++*+,++)++**)')*),))((*(')(('()(&(')('''(''''&'$''*)''%&%''''%%%%$'%%%%$%'%%%&%#$$$'$$%$%%%%$$$##$$$$#$$$##""$#$##$##$##$##"!!!!!"!! "!!!!"!   + + +  + +;:69;;<<=:82201,+++*++.445344755886565577767456779766565855553556653235665666434554337122032323/2122332230//0/0/0/1200,12/0//./+-.//.,,,.,,,-+,,,-,..-,-,+*)+,++,,,+*),(*))++*+*+*)*))*+()))'*(()'(''(('''$&'&'''&''''''%&'&''''&&%%%&%%$$$$%%%$%"$$%$%$&$$%%%$$$$$$$$$$%$$$&""$"##$!""$%!#$"""""!"""! !!!!!!  + + + + + + ":9:;;9;85933134*,+**+,-/0.1134677869976757675568787676666542575565545344353454355243732411320312111111101/./1/00./100.1./01./..--/--,,+.-*.---,-,/,,+,.*,+,0+++++.***+()))+)+****)*)+('(((''''((((('(((&&&'%'&&&&&&%'''&'%$'&&''&%%%'$&($$%$%$$$$&$%#$%$$%&&&%%$$"$####$$!$#"#$""#"$"##"""#""!""!#"""! !!!" !"  + + + + +   :998:<:96743130+-/+++++/24132676876757837776;76675865567953734556454643232744735344343422/015222112100/42111.0/10//0//0////--)-./--..+0.,,-.-.+-++,,.0),+++))+++--)))+,+)(-**+-+))))()+''()'()(''('(('&''''&'&'&''%(&''&'&%(%%''%%%&$%%$$$$&#$"$#$#&"%#$%$#%$%$$#$$"""$$"$$""#!"##"""#!"""##""$!"""! !! !!!"!  +  + + +  + 88:98<888542550,*.+-+)),20124354559:6557576775765593685555640865575553374342346232203551246121/322121102/.0////2.1000///00/,.-..,-.,.,....++,.+++---1*.*+++++*+++++(**)+++(-,'))))))+)))(((()'('''('('(&&((((&''%%&'''&%'''%%''&&%&%%%%$$%'%$$$$'$$%$$"$%'$$$$$$#%"#"#!"&"""##%#""""%#""#""""""#!""#!!""!! ! !  + +  :88:88977332022,,++*-)+/223224455654465655567587653454545454524344255632353423231221332620/3112013001211//.10.///2110/0/+-,1..,,,/..,,-+/,-+++-,,,*,+++*+/,*+*+,)+*-+*)()+))()*)())),)**())(()'''''%'''''()'&('''&''&&&&''$%%'''&'&&%&'$%&%&$$$$%$$%&$$$%$$#"%#$$$&!##$"#!#$$#""!"""!"$!!""""!#"%!! ! !"!!! ! !  + + + +  ::9868:86432031./*+++()-2213347787655647575886565356585565553733359383561233236233124123152311121041121///00+0/0-1011./..01.0//.,/,-,,,,,+.+,.*+/-,,++++,+-.***+)+++++)****)****)*),')'+)()((()&(''''&'''('')'''('('&&&&%%&&&&&&&'$%&"%'$&$&$$%$%$$#$$#$##%$$%""#"#$%!"##"$#$$""""""""$##""! #"! !!"" ! !!! ! !  + + + + + + + + ! 6788979953215-51.++++(22/42334367957537655/5572666954554445663543044634464422223331115130321112420/01001221/-0/0/0//0//////1/.//./+-,,,,-+.-++-..++,.+,-+-,****.+*++++**)))+++,)(++,())''('((()(((''''&'''''''''&''&(%%#'%%%%%&&%%%%$&%%%%%&$%$$$$$&$$%$$%"#$####$$"########$!##""!!$""""""#"!"!!! #!! !!! !   + + + + +  + 8977978953236016011-+/11.012357467666634455555556845455332676654582775644443133311142543321122401//0002000010/.10//01/,./01.-//0/..-,,,--,,.*,.-,-++--++.,*(+**++*++,+))))*)**)))+*((()(()))(((()(()&'''''&'''(&&'''('$$$$%&&&%&$%%%$$$$$$%"$#$#####$$%#$$#%&$$"##$%""""#""####""!"!!!!"""""!#!!!!!!   ! + + + + +  766788997732661/22224/.,1113444556744654442835456675644643335636653644333252234134323322224322220010020/00010./1/+//.-.+0/,,,.../0.,,--,,-.+++)++,+,*+,+++,**,.++*+,++**)+)*)*'(*+'))())(()((()(((()''&&''&$'(''&%%''%%$%%#$%%%$%%%%$%$$%#'&$$$#$"##$%%#$$&&#& ""#"##"##$##"#!"##"$! !!!!"""""! !!!!!!"! "!   + + + + + 968:98:9865314510/1/701./0224555955543243465436634335854512536556484453330/1346623303222452222120/1121///210/./0//./0/0.1./.,1.//0/),*,,--,+++.)+++,,.(*++)*))()+),*++*))+++'+,+(('*()))*),)*'*'('()'(('%''''''%&&%'''&%$%%&'$'$%'%%$$$#$$"#&%%$"$#$"%#$$$%$$"$"#$#&#$""!$#!#""#!"""$##!!!"$ "!!"# ! !! !! !  + + + + + +  +89798:98:97423442.20121/1/0244557464535334445344433446564424427444344433520122515335131221202111/2211//.2/1/...,.../00-/-..,,/,0.2,,+-,+++++.**++++-**))--***)+))))**)*+*)+(+(*')*)))*))(*((()()((&'&%$&'('''&&&%%$$&''#%$&%&%%$&$$$$$$##$##$%%$"##$#$#$$&$%$#$!$!#$$$#%"##%!"""""""!$ #!"#!!$# !"! !! ! !  + + + + + + 6;768777594441330.32021012445243765543433444453122334556434433554445453303122412301224334323112030110////4/0...0-/////./0././0.0+*..,,,,-+,,++-,-+,+**)),,*(++*)))(**)))*+*+)*))())))(())()()()(((('%%'&('&'&'$&$%(''%&'%%&'%%$%%'$$$$#$%$&%%#%%$$"$$$$$$"%$$$#$#""#"$$#""$ !!""#""#!"#"""!##! % " ! "!  + +  + + + + 6889755777882210321432221423455466554253.34334643334133256442235254333342332633203232113321/120022002,/.2..0/./00/00//.+-/.....+0,.----,+,,+,-,,..-)+))+,,,+,+**)*()*)))*))+)()('())*)('())'&''(''()&&'(&'''''&%$'%&%$&%'%%$&%&($&&#$#%'#$$"$$#$$"$%$$$$$$$%$""####"$#$$#"#!!!"""#!"""""##"""#!!!  "! ! !!  + + + + + + +  + +  !  6676858575545321120145/1223436445443345332331526222333334333222222334150215312211033200125//0000/14.//.,+/./--0.0//./-....-++++.-,+/..-,,,+,*,++*,,*,***,++*,+****+)(++*+))+)))))(()*)))&(('''('('(&(((('&&'&'%%$%(("$%&%&%%%%$%&%$#&$$$&$$$#"#$$#%!"$$##$$$$"""##$"""#"$"!!!!"$"""""""" ##"!## ! !!   + + + + + + + +  57685577758645345160303533575235555692624232352333313334342323314123500222423223112131000.0020025.11.1122/0.-0/.00/0./+-.,,/,.-,--,+-/,.+,.-*-*++-*/,,*+,++**+*)+++*,))*(()())()))*)*)))((''''%(()(('''&&'&&'&$%'&#&&'$'%%%%%%'$&%$&$$%#$$%$$"%$%##"$%$$#$$#$"""""""##$#"""!!#"!"!!!"""#"!"!#$""!! !! !  + + + + + + + + +   73797887796655576463545579/54444354335/5663223324145552334062352114/210211106222121221210.11020/.21/2-0/..////.-./...,0++1.-..,+,,,+..(-++.,,*)*++++,+,*+,+,+)*++*0)***)(*))))+)))((((((''(('''((('')''''(&(&)$&%%'&'%%%%&$&%$$&$%$$$%$%$%'$$$#'$""$$$%%$$$#$$#"!"$$#""#""!$!!!"#"!"$#"!!!!"!"!!!!!!!#!  ! + + +   86998748978955755644234343633452232222124431134353334311633021223231221021211211120002114./1122/0/0//2////...10.0,-+.,..-,..-,,,,+,,+..++++)+++++)-+++)+)++,*)))***++***())*()(*(()(((((('''&%(%'''''&')%%'&&&''%&''&%'%$($$&&%$%$$$%$$$$###&#&$#"###$%$$$%$"!##"#$#$"##"""!!!"" #"" """!!!!""" !!!!!!    +   22:5464777575534544455366634412312202223421234021225211122002062235221201101121210/00220201//.02/11//.3/..//.-0,..-..0+,,/--,-+,,,-++,*,+).,)++++,)-***)-,+++**((*+*+)*+)*))*),)((*)*()(((%''($&'&&('(('$%&''&''%'&'&%$%%%$(%%$&%$$$&$#$$"$%#$"##"!"$$$$#$$###"#$$!$"""""""#"!!"" $"!!"!#!!!!!"!!"! ! !"!  + + +  +  468488565593535433524253330172324023022121402/23252161102142110324112322110/20010/1/011503//0/0121//...////,.,./+0--...-+--.,,/,,,)*+,,+++*+,(+*+/*,*++++,)++()*(*+*)))+*))()))())'))((((()((''''()%'&'$&$%&'(&'''('('%%&%%(%$$$$$%%%'%%%$$$$%%##$$$"$##"%$$""#%$$""!"!#!!""!""$## !""!!! !!""!! ! ! !!!  + + + +    ! 435575554663433474433353215101235401340412202021323233205011107443440//01001123201/012001/2.0/0/10/1-..--/.-/./..-./..-,.-,,.--,-,,,0,++*+)++*-*++*+,++++,++)*()*+)((***,+*)()(())(*)(('(('(&'''''''&'''('%'&'%&$'&%%#&%%$&%%%%%$'%%$$#&#$$#$$$$$#$##$#$$$#$####!"""""!"#""!"!!#!#$$"!! !!!!! !!"! ! !  + + + + + + + + + + +  !434856555755354344412256353221430/1134..22133212111312402232333231/310/21020201/12./110/1/.10-/.0//-.-.,,,1/../..,--./-/,,*,,.//.,,,+,,,++,,))*)+,)),))+++))+)))*+))((+*)))((((((*'((('()'')''('''%('('(&%&%&&&%&%&'%&&%%%%%%%%$$$%%$$#%$$"#%$$$$$$$$$$$$$#$$$#%!""!"!"#"""! !!""!!!!!""" ! !!""!! !!   + +  + + + +6552644333754323437263425332211163153402/3/65253111033326111143115011/1/014//3004/-,3/4/300//1/.../.-,10-+//../-..//--,1.,,,,-,./.,,+*+,++,,++*+,+,/)+*+-+),)*),)(()))))+))((('()+*')(()((''(('*')+(((''''&'%&(%(%$#&$$%%%%%%$%#&$$$%$$$$#$$$#$$$$$$$$$%$$#$$$#"##$""$$$!#"!!!!$ !"# !"# ""!#!!!"!! !!   + + + + + + + + + +  24443635456342343424244332212111120/2122120110130/001120013102000002030.10/.13330/--.200/13/0//..--2,.1/0/-/.-,,/,0---,,/,,,+-+,.,.-**+++**)-,**)-*,',))*-++)*()+()(*))'(,(*()())(('')()(&((''&'(('(''''''''''$'$&%$%%&$$%$$%$%$%$##$$&$&$$$%$#$$$$#$$#$"$$#!$$"##$##$"##!$"#!!! !!!"!!#!"""! !!!!! ! ! ! + + + +  + + + +  223201232212345324441322322113124302/232//1.13011012.1223/0000/0/110/--3-00/.)21././//0002//./.-...,0-/.//..+--0.-*-.--++.,,-+,+,++*))++,(*+*++++)-*+()*+*,,**+)+)**)))())*))'))(()))'''(((''''&(('&&&'&(&&%('%'%%$#%%%$$%&%%%%$%"%%#$$!#$%$$%#$$$$%$##"#$$!$"##$$#"#"""!!" "!!"!#!" ! ""#"!!!"! !     !  + + + + + + + + + + +   10221132241511421432102236311234510001121///111100/01-/1212/0/.0/0//0/.//-./../0,/////0000//./.+.-0001*0///,*0/,-0,,,,,,,.,++,,,,,+*,+++-,)+++,))**)+((,*))))))*))))(())*))*'))(')(()(()((((')%((%'&&&(''%&''''%&%%%&&%%%%%'$&$%$$$$$#$#$"&$$!$$$&"#$$"""$$##"###$#"###!""!!!!!#!!# !!!# !%! !!! ! !  ##"! + +  + + + + 01/21/1104432213/141+324314322/0/.3/0040201+.,12/0.100025/120...////.00/.1/..././.-10/002/,/.,+,,-/././/..-..-.,+..+-.-*,+)+,,/+++)*+++,*,)+*-**))))),)*+)(()***))(***)('(*)()(((''((&''''((&'(''&'''&''&'(%'%$%%$$%%%%'&$#$&%%"$#%$$#$#$$##$$$$#"#$#"$""#$#"""!""""""""!! !!" !!!"!!!"!!!! ! !!!   !$$&$ + + + + +  +  ! 324222103133423/43111305531411//00/411//112241.///111012,3111///0.11/31//.1.-0000//../0/0..//./+--/1.../.././/-+.-.,+,,,,.+.+).+,)+)+*,+*-(+)+,+++*))()**+('++*))'(&*(()(+')))(('+)(((('(('&*'&''%'&'''$'''%'&(%&%&%%$%$!$$$$&%&%#$$$$$$$$$$$"##$#$$#$#"#"$#"##%!!""!#$!""""!"$!"#$ !!!!! ! !!  #''%" +   + +     ! ! 344/453011353340/203//132004/3..2000324.21000-/000/00/0124.//0/./0-././04//..//...//,+//.1.-.0.+/..//0,.0..-/,,+.,..-,,0,+))-++*+-+)(,+,-*+*)))***+))))(.+(*(*)**((')()'()())((((*('(('('&((''''''$''''&%%%%&$(%$$%%%$$$%"$%$%%$$%$%%$$'#$$$#$#$%$$%$#$"$% $##$""!"#"""#!"!""""!!!!" #! ! "!!" ! !  #(('$  +      !"! %(3302510100321111/////0200.0..-.-21220/./.0./..01-1..//01+0..1///..--.00/0.//.-,/.-,.-.-./-,--/,-.+-,.,,.--.-./+++-/),-,-,+),))*,*)/*+)*+)*,*+**+++)))()*)))()(((*''(')(('*'(((()(('((''(((''''&%%&%&%%%%%%%&'%%#%%%$$$%%#$$%&%$&&"$&$#%$%$#"##%$$!##!$#%##""#"#""!"&""#""!"#!!!# !" "! ! "" !!!   #&&&!  + +   +       !).0121.02111130//0//0..0+/./-+0.21--/.../-.20.2/./-..00-,2..01/.-./0...-0/,/0/...//-.-0)/.,-,+-1-+1--,+/..+,,,,.-.+*,+**+%*++',+),+.(*,+)+**)*+,+))))))))()()*)''')('()''('((''''&&&%)'''&'&'&%%%$%%%%$$%''%%%$%%%%$&%%$%%#$%&#%$$&$$$"$#$$$###""##$##$$"#"###""!""!#""!"!""!#!!!!!!" !!!! ! !  !#&$ + + +  + + +     "%+///-/0/0101./-0,0./01/,,1-2/-/..//+-1.1./.0.0-.,/..0-1/11+0./,-////.--.//-.,,../..-+,-....,+,/),,+.,,+.+,-//-++*+++**'+*),*+-))))*+++*+)*+++++*())((()*)&*(('((((*)('''()(''%%'&&%''&'''&'&'%%%$%'%%%%&%$%$%%%#%%#$$$&$%#$%$$#'$#"$$$###$$#"##%#%$$#$"%#"""!""#"""##"!#! "!"#!"!""!!! ! !$ + +  + + +  !!  ! &().,/0000.0-.//-../.-0////,.-0.,-.1/,..,.-0..2...-0,0././-+,,--.-,,/.,/...,+,-//.-,,.--...,,.+,+,+++,+(,.-,*++)*,*)))**)*****++++)*))+))*++(***)(((*)()*)(')(*''''&''''''''&$&&'''%%$'%%%&&$#'&%%%$%'&&%$$$$$%$$$%$$$%#$$$$$"&&$$"$#$#"$#$!#"$$$####$#"!!"""!!!!!! ""! !!!"!!! ""!!   $ + + + +       ! $))-/-./--+-.+/+-/././.-//,1*,21,0+0,-/-0///,.0,.,./0,+.,,,.0-,-+/..+/,,-.,,//--++/...+-*+,,-++-+***,*--*,)++*)+****++*+++)()+,),**)())+)+**(((()))))((()())(('('()(*&''''&&''(&$$(%'&&'&(%'%$&%#($%%%&%#$#%$$$$$#$$$###$$$!%%##$%$#"$#"#"""""!#!$!!""###""!!!!!!!!!!!!!!!! !!!!!!!     + + + +      !"%)-////0-,-+.,+//...+,00-)--3.,,*/,*10//,/-+--,,-1+.2..+-.+-',...,0..-,(,/..*,,+,0+/.++,,+++-*+-.)+*))*++*+*++,++,+++++++(+**)())+).*))+-*+)+'))))))((()+')('()(((('(&%'''''$%%%&'&%'%$%%%%'$$%&%%'$&%$'&%$%$$$##&#$%$#$$#$$##%$$$$$$"""""""""""""##!!!!!!"!!!!!"!!!"! !! !!!! ! !  + + + + + + +  " ! %,-,1../.),.-*-*+,.,,+,+.010+*,.-.)/+++--,.0.+.,/*..10,,.,.,-+,,,+-.2.+.-+,+-+,*+***+,--.+-,,-**)+,)*),,++))+))*,+,*+*()))((*)(,++),)')(()''(()))(((*((('(&'('''&'&&&&&'&%''&''''$%%%%$&$%($%%%#%&$$$&$$$'&&##$!#$$#$$$&#"$##$$!#"#"""#""!#"""$### "!!"!"! !!!! ! !! !# "!  ! +  + + +      %%.-++-*-.*+,)..,--.+++-,+++.-+)./.,+-..+++,,+...-.+-,,,,+/,,,..+,,,,,*+.+-+-++-,+,,-,',*+-+))+)**+**+)))(*)*+****)(((((()))**+)(()))(('())(('**(('((((*&(''&&'&&''''%'%%$'%&'&%$&%$&%&$&%%%%$$$$&#$$#$$#####$$%$$$"##$"$##"###""""$!"!!"""""""!"$$""!!!!!!!! !!!!  !!"    +    !!! ! ((()*,),+++*.)*+,+-/,-,+--++.-,,*,,)/.+*+,.+,0--,/-,,+,',(++,+-,,+*-+-,**+,,+-++(***+,,()++**))+.())))))))*())*%((()((++*+*))(((('))(((((()(*(('')&&''$'''$%%%'&&''&%'%&$%%'&("%$'%%%'%$%%%$%$%$$%%%%$#%"$$$$#$$$&#$"""$$##"#"""!""!$"!%""""!"""""!!!! !!! ! !! !  + +  +    !!!"!! !!!! !)),-.-+,.)+,)***+*-)*,)+,+-*.*+++)+))*.++++.*,++,++-+*,+,,-.)*+,,,+*+,,,+-))*,***+++*+,+*+)+))))'(++*+))))**))'(')*++)))(*((*))))((((((+()()'((('''(&'&%%%&'(&%%&&%&%$%('%%$$&'%$$#$$%%&%#&##$%%###$"$$$$"####$#"$"$"#"#"""""""#""!#"""!""$""""!!!!!!!!!"! !!!! !!    + + + +      !!""!!"! ! %*)((-*)))***)+-*-(*,+*+*)++*,),*+***+,),.+,++*,,(++,++-,,+++,)++*+,+,,*)+)+)*+++)(*+-))+*+)))*)(**%)))*'+()&)(((*'')(('*)((((+)('('''(((('''''''%'&'%%%%%'%'%'&%#&$$#%%#&$$$%&$$& %%%&$#&$%$%%#$$##$%"!!####""#"#!#"""""!!!" ""$"""!!""!""! !! !! ! !"! ! !! !!  + +  + +    ! !"     ("+,++))(+))+)*)),(++**)(,+.*(*,$,+,++,*,+.).-.,/(+)+,++(,+))))++,+(+,),+,,*))')++))))**))('+*+(',**)(+)((((())((),())'((((((()'''''(('''&&%%''&%'$&%&%%''%%%%%&%$$%%$#$'$$$$#(%%%$%$"#$$$$$##$%##$&""#""""""!!! "#"!"!!"$!""""!""!!"!!" ! !!! !!!"!! !! !!! !"    + +      !" ! !$ "! &&*+*)++())+)*()(*,))/*+,())(.*(,,+,,*)+++,,)(*.*++,)*++'(*(.)*+)(***)*))))())+)*))*+(())*(*'(*)+('('*(()('+())(&((((()((*'''&'&)(('(''%$&%&'%%%&(%%''''&&'&$$$$%$$%$%&#$%$%%$$$#!%$##"$%$"$$! $$######"!!##"!!!"!!#"#!$"!!""""!!!!!!!!!! ! !!! !! ! "!    + + + +    !!!!!! !   !#''+'+**++)()*(+**+*+*,))))())+,))*)++,+**))***+)-**(.)(+((+**+(+*)()))()()))*)*&)*)('(()+))('(((()((()(((+()'(('((%&&&&'&('$''('%'&%&%&&&#&'(''%&%'&&%%%$$$$$$$#$$#$#%$##$$$$$#%$#"$$#$$!#$"##"$!###!"!!""##!!#"#"#!""""""""!!!!"!!!!!!! ! ! ! !  + + + + + +     " !!! "  !!"! !  %&()++'()**()+)'))))*)))))+)))),*+,-)))))+*+.*'(++,*(((())+)**+*)(()))*+&(+)+)())('(')))(((')('(&+)((+'((('(&)('$%$''($'&%&(((&%('%'%&&&''&)%$%'%''&%%$$%%%$$$$&%%$#$#$$%#"$!$##%$##!$$!"$$#$"$$""#"$$!"!!"!"$ !!"!"#!"!!!!!"" !! ! !! !   !!!  + + + +  + +     "" ! !"#"! !!!!  !!  $'(%*)+('(**)(())(('*()())('()(0)(+),+,(*)*)**)*))*)))(((('(*(())+)(''((())((((''()(('%''''(('&(()*)(('(')''&#$&%$''(&$%&$''$%%&&'&%&&(%%%&($%%%%%%%%$%%%$$$#%%$$###"% $%!#$#$%"##""%##!""""##!#"$"""!"""!" $""! ! !!!"!!"!! ! !   !  + + + + + ! ! !" ! ! "!  ! !!! !!!   "$)**)&'((((((+)+'))&+*')()((*,*)))(*'))))(()*)))))))(+*,(()((()'()()('*&*('')((%+&((&'''()''('*(**'''&''&)&%'&%'&%'%%&''&%$%%&&%%&$%%%$$%%$%%$%%%%%%$%#$$%%$$$$#"!#!#$&#$$!$"$"$!#"""""""#""!# ""#!!"#"!!!!!!!!#"!!!#!!!  "!     + + + + + + !!    !""# !"! !$!"" !!    (()(+())(((+(*')'('(((()((()+)('((((((*((*))(())(%(((+)))))('(((&')+('((*()'+()(''('&(&)'((((()'(((&%&')%('(&'%''%&&'&'($%$$'%%%&'%&%(#$%&&%%$%$$$%%%$#(#$($$$"#$$$%$$###"$!!""#"""!""$#"!###!!##!!""!"#!!"""## !"""!!! !! ! !!"! "    +  + + + + +   !"!! !!!!! !  !!!! !!!#!!!!!"")*)&()&')(''''*((''(,'),)')'+('&(((*()*'(*'+))('&)()('((('(')'**('&+(((()%*&'(%''&''(('('&('''&&&&'&%)'&&&(&$%%&%&&'&$#%$%$'$%&&$&%&%'%$$%#$$$$&"##$#%$$$##"%$$#$$#$$$#!!!##""$"!$ !!"# !!!"!!!"!!!" !"#"!"!!!!!!!! !!!!! !! !    + +  +       " !"" !"""#"""""!"!! !    !%%(%((((('('&(+''('(*$'))()('''((((())'('*'('*()('((&'''(((&&(*('(('''*'&))%('('''&&'()('((''&''&&&('('('%'&&$%''&%%%%#%$&&%%%%%%'&%%#$"#%$%###$$%#$%$###$$"#"##$$$$## !!"! #$#"!""""!"!#"""!"!!! !!"!" !"""!!" !! !!""    + +    !    ! !"# !!""$#!#!"#$!" !! !  ##'(((')'('&'%'(()**'())()'''''))'&('()()(+('((''(()''&(&''(*')'(&')''('(((''($&'(('&*&(('&&''&&&'&%%&''%%$&$%&&&&&%%&%&'& '%&&%&"%$%"%$$#%$"#"$#$!###$$!$'"""$"$##""""#"##"!!"!"!""!""$!#"!!!!!!"!!""""# !! !  #!  !  !!  + + + +      ! !" $"!!!"#""#!!"##!"!!! ! !! $&')&()(%&('$'''((+'&(&''(((('''))(&')'('&'&&'''(''&&'(('&%''(*&'&(((''&''&%'&('&+(&('('&&%%'&%%%%%$&&'&%$$%$$&&"'$&%&%$%%%%%$%%$###"$#""##"%$#$#$%$##$$#"#$""""""" $#"""##"#!$#"""""" " !!!!!"!!" ! !! !       + + + +    +   ! "   ! "#""#"$ !! ##"$"$!!!""!!  ! !"% )&(&%%&'''&'$&)('&&'''''''(('''&)('%$&&''&)(&))'&(&%%&((''''&('%&'''&')%('%)$'&(('&$&$'&$#$%&&&&%$$$#&"%%$%'$$&$%%%#$$%#%$$!#!"""#"$%##$#%$#$"#"$##$""##"""!"!"$""!""!"!!"$#!!""# !!"! "!!!"!  !!   !   + + + +     ""!   !!!!!#$#"" !"!"$"% !"!!""! !!   !#('&'#&''$(''''('''&)&)&''(%)'&'$&+(%$%''+&')'$'&%%&%('%&('&&%''$'&'''&('''&'&'&('&(%%&($#$%%%&%%'%$'%$%%%%%$%%&%%$($$#$%$"##%'#""""#$#%"#$$$"#$&#%""##""""%""$#""""$""%## "! !!!!!$" !!"""!! ! ! ! !"    + +  + + + +    ! !! !"   !"!#!%$!!"! "!!!#"$!!! !"! !   #%&'('& '&'(%%'&&)&&%&$%&($$'(&$&'&$'('((''%(%&$%''%%%&&%&$($%%&'&&'('')&''$%%'&%'''#(&$#$''$$$%&%%$%$#$$$%$$$%%$$$$$##!$$#"###""#"##$#"$"""$""$!"#"#"""!"#"##"!"""!!""!!!!!!! "! !!!!!! !# !  !!!! !  + + +   + !!   !! ! ! !!# #"! !""!"""###!! !"!!! ! !!!   "$&%'&&(%%&(%&&&&&'$$&&&'%$&'('%'&$%%&'&$%(%$%%''%%(%&&&'#'$'$&''&'&'&%%&&'''%&%$&&%$$%$%%%#%%&&%%$$$#$%%$$$$%$#%%###"$%#$!$""#$"#"#""!""!"#$#""""!#!""""""""#""#"!"!!!!!! !!"!!!! " !! ! !!!    + +  +  !  !   #"!!! !!!"!""!! !!#"##$#$##$""$!""! ! !"  ! " "$"%'&#&%%&''$%#&#%%&$'''&'"( &#$%&%$#'%%%$%(&$&($%$'$$#&#%'''$'$%%''%'''&%%%&$%$$$$%$%$$%'&%$%$$#%$%$%$%$$%%!%$$%%$$## #$ #$$##"#"###"#"!"$! !$#"!"##$"""!!#!!!!!""!!! !" #!!" !!!!!!!!!"! !!  ! + +  + + + +  !  !! ! ! !! !!!"!  """#!!"""#$"! %%&$$""$#"! "!" "  !!"'&''&$%%$'$%%$$$$%%&$#$$&&$##$$%%%$'$'%'&&&%&)#$#$%%&$''&&$%$&%($'(&%$%%$$$&$&$$%&%$%$$$$$&#$#%'###""%%#$$"%#"###"""###!#####""!!!"!!!!"!"!!#!"!" ""!""!"!!!!!!!"!! !!"! "! "!!!  !   ! + + + + + + + + +  !   !   " "" !#! !"""#!""!#"!#"$#"%$$$#$#"#"$$ ! "!  $&"$%%$#$$###$%$#"##$"$$##$#$#%$$#%$$('&$%$$%&&$$#$$&&%$$$$%%$#%%#%$&$$&&%%'#!###$$$$$$$$!$$$"$$""#$$"$##$###!# $"!""""#!###"!"!!"!!!!!!"!! !! !$ !"!"""""!!! "" !! !!!  ! "!!   ""  + +    !  ! ! " !!!  ""!!"! !%&""#$$$"%&#"$ %"$$!# !#!!!!! !#   ! !!"!%&$$%%#!"""" !!#"#"&"%$$%$#%%&'#"%%&%$$$"$$%%%%$$%&$&%$"$$$$$$"$%%%%$&#$$$$$#"#$$$%%$##"""#!$"$! ""$"#""##!!$!#!%"#!"""!#"!!" !" !!!!" ! ""!!!!"!! !!""" ! " " !!  !! + +  +  +    !     !!" "  !!# !"! !!!!&'"#'&#"!$%#$##$##$"!! ! " !!%%%"!"$"!##!$#&#$#%$$!$$$%$$%$$$%##%$%$#%$$#$$$$$%%%%&"$$!'#&#$$%%%$& #"#$%$%#"#$""$#!""!#""!#!!!!#!"""!"""!"#$#"" !"""" !!!!"#$!!$"# ##!!!"! !"!"!!"!"!!! !"" !"!    + + + +  ! ! !   ! !! "! !!!# !  " "!$(%!$#$#$$$##$#$#""#"##!!"!"   !##%$%"#%"##!#%""$#$$$$#"%"##"$$"##%$#$%&#%$$$%$$$%&%%%$#$'#$&$$'$%#"%%##$%#!$###$#$##!"!#$""!!!##"#!#"""" #!###""!!!""!!!!!!!!!"!!! !! !!!!!!! ! ! # ! !!!!!"  !!!    + +  ! ! !"!!"!#! !  !!!#!!!# """#!%%%$"#$$'#"$$#' $$%#""!"!!!! !!!   %!##!"!$& %#!"$$$&#"##$$$$##%$"!#$$$$%##!%$$$ $#"$!##$$!!%$$%"$#!"##"#"$!#!%!"" '!#$#""!#""""!!"#!" "#"#!!!!!""!!!!!!"!!!!! # #!!! !! !""" !! !!!      ! + +  +    ! ! !! !!$!"$! !!#" " ""!!"!#""$'%%%"&#'&$&%$%(%#"###$!""$#!## ! !  "!#$&"!"!$ "$%"$"$$#"#$#"!##!"$$%#$$&#"$%$$###&!#"# "!%#"$$$$"""!##"$"!""$#$!"$!#$$!!"""!!!$!! ##""!!!!! !""" "!! !!! !!!! !"! ! !!"!!!! ! ! !       + +    !  ! ! "!##$%!! ! !!!! " "!"$!$$$%&$%&%'&#$%&%"%#$$$#"##!#"$!!!!!"!! ### !$!$"!!""""""!##$"#""##""!$%$$#"" $#%#$$#$#!""##"""!"$"""#!$###!""!##$""#$!%""!!!#!!"!"$"!! !!!!!!!"""#!"!"!!"! !!"!! ! !"" # !! " !   !   +        ! !!%""""! !!!! !!!""#$%$$%&&'%'&$'$%'%(###&%$"$"%&#'$!!!!"!!! !! !!!""%##!"#""""""!!!!!!$$#$&$$#""""!%$$#"##""!"$"#!""""""!"$#"!" !!%""#"""##"#!"!"!#!!"""#!!!$ ! !!! !" !"!!! #""!!"!!!!!!!! $ # ! !!# !!  !$   + + + +  +  ! !  !!  !"$$#"$$ "$ ! !$%$$$$"%&''&&&$%%$$$#$#$%##%$%$# !!!!!!     ##%%"!!""!! !"#!!%"$#!!$###"""!!!#"""#!$!""!"%#"""!$$!!#"#!#!"""""!"#" "!##!""!!" "#!"""!!!!!!!!" !! "!!"!" " "! " !! !!" ! ! "! !! ! !     + + + +  + +  ! !  "! !!  ! !" !!!""!!"$ "!!!#! ! $%$$%$$%%&&'&&&%&%'$$$$$& $$%$&"%%##!!!!! !  !"#"!"!!! ! #!!!! "#!###""!!! !"!!"! "!!##" $#!%""#"" """"""!!"!"""!!!"" !"!#!!"!""!"!!!!"! ! !"!!!!"!!!"!!!"  ! ! !  !     + + !  !! !      !" !"!!%"# ! #!!!%%$$&$%$&'(&('&%#$%%%"$%$%%%$$&"!%!"""$     !!!$!""! """ "!!$#!!!"!!!!!! """"""#!!!!!"!$" "!! "!#""!""""!"!##"! !!"!!"! $!"!!!!!!!!! !! "!!!"  !! "! ! ! ! ! ! !!   + + +   !  ! " $ !!! !  !!"%"  $ !"$$%$#$#$&,%'('(%&%%%*$$%&$%#$$$!%%$!!"!!" ! !!!!! ! "!!!!!""!! !!"  #!!"%""!! !!"!! ""!"!" ! "# ""!!!!#" !!!!"""!!! !#" ! !! !! ! ! "!!  ! !!! ! !! !! ! ! !  + +  !     !!  !! !"! !#!$! ! !!#"$$$""##$+*-&'((&#%%%%'%$$%%$$#$$#$ ""!#! " !!   ! !!"!! !!!!# !!!!"!!! !! !! !"! ! ""!! ! !!"!"# ""!!!!!!" "! !!!!"! !! !! !!  ! !  !!   !      + + +  +  !      ! ! !" ! ! "##%#$##"!$+,,(*)'(&'''*&'$$%$&$$#%##"! !""!!#""! !!!   "!"# !  !!" !"!!!!!!! !!!!!!"!!!$!##! !!!"!$#! !!  !!$% ! !#" !!!!!! !#!  !!!!!!"   !        + +   +    "" !    !"! ! !!!!! ! !!" !"""$$$*$#%#/.,+,,)(&(&'&&'%&%&'%'$&&&##"!!!"#!$# !! !  ! ! " ! !"!!!! ! $" ! !!#! !"!  !!"#" !"#!"!! "!! ! !! !!!!#"!!! !! !  ! "!! ! !       + +  +  +  "!! !! !" "! """ " !!  !!! "! !!###"%&&%$%$40+/.-,)*+)(()(''&''$$$'%%"&##"##!"!"!  !  ! !"!! ! !! !!! !! ! ! "!" ! "!  !!! !"  !"""!!  "!! !!   !    + + +      !! ! !!""! !"!!!! !#$" !  #""#"!!!!!!""!#$&&%&'%23200/1-.-,))*)((()''%%%%&(!&%#"""" "" $ !! !! ! !  ! ! ! #!! !! ! "!  !" !!!! !  !" !!  ! !  "!  ! !      + + + + + +       !!# !"""!! ! ! !"!!!!  %""%""#"#""""!!!"$&'''$76332224,0/,+++*(()(&$$%(#$##"#""$"!"#3!!""!   !    !   ! ! ! ! ! !! !!!  ! !  !!  !!          + +   + + +    !!! ! "! ! # !"!!!"# !#!!!!%#!!##""! "$"#'$%&9786787851/---./+.,((''%%'&%%&$$$%%$##!! !""!!!!       ! !! "! ! "  ! !  "!    !   + +      "  !""!!#! !! !"##! "! ##$$#"##$!"$%$<:;;986555211650111-)(())('&$%$#$$##$$#"!!!! ! !#!!   " " !   !!!! !! ! !!     !!! !      !      +    "  !! % $"! ! ! #!! !!!%# ! %"!!"!!!$'$%&%#$$#'&@=>@=788769756744/0/,+++*()()'%$&'%%$#"%$!!!!""!"!"    !    !     !            + +   + + +  ! ! " !! ""  "!!!""$%$ ! !""#!!#%#$%%$%#$&%&%AB@>A@=:9;;:986522320/,--))*)*'''"$#$$%%!#"!!"!"!! !               !      + +     !!! !" ! "!"""!!$#""  ! !!$%#"%%%%("'$&&%DFCD@=?@==>:>:8749535/0/..0,,+)(''$%&%&$%#%""#$"!"!! ! !!  !        !! !       +   +    !  " "!!$!   ! !$!"# !!!!#%'"$$$"&&%%$%%IDEDCCD=@?C;;A=<969746412220.../*(&&'''''%#"#""!!#!# ! "! !  ! !    !       +  + !  !  ! ! "" !""  !" !!!"! "!!"""$""#%'%(#$##%GHGIFCEDCA@@?@??::::<96354222.-0/-**((('('&"%&&$$!"$"!!"!! !        +   +  ! !  "! !!"! " !!!!!! " !!!#"# !"""#"!!##'''%#&$%SLLJFFEJJFDAAA@A@@;=<;8<778642143.-,+)+)($'(%#$"$"%$$!""!! !!       + + +  !!#!$! !!""!!" !  !!!!!%"!!!!!# # """!!""$%&$$$'$$$NMKOLHJILHHCGBDEF<>AB?<:886686331/0)/+/)--)()'%&,$&%$$$#$! !!    ! !!  +    +  !    " """! ""#! !!!$!!"!!"##!! #"#$"#"$ !!#$$#'%$%&$QQNMLLOKKKGFDGFDBAEAB@>@;:;;87653122-11..-,+''''&)&'#$$$#"! " !!! !!   +    !    "!  ! #""!!! ""! !  #"!""##"!"!!""&"""#$# !#"#$$$#%#!"SQLOROPMLJJHIKHGEEDCB@?=;:83543162201/0/,)))+(+&(%%###""!! "   !  +  +  !  !   # ! !!#" ! !"#! !"!!$!##"#"!!!!"!#$!% ""!"#$$#%%##""YURQQSRQKMNMNNJIII?GCCBBCBB?><@<8673162741200.++,+*+''&&##!#"!"$!   +       !" !"!   ! ! !"!! !! !"!!""""$#$!!"!!#!!! " !$!#$"$#%$'##$"[XXWZSSPUQOSSPNLMJJHGGJGHHBB???>;<886599825340/0-,,**('(&$$"$$"!"!  !  +  ! "" ! !   " ! ! ! !" !  !#$$!#$"!" !"!!##""!"!!""$#$"%%#"$$$\ZXVVUUUTVSPTPPNOMPIIJJHEFIDEA@?=>?=:<;988553122/.,,+*)+*'&''&$##!! !!  ! + + +   !!!   !!!!!!! !#! " !! ! !"#$#%"""""! !!$$ !# "$%$$!%$"$$%"Z`\YYWWYWWWXTPQOQQNNMLJMJHEHDDCBBD>D>?<;<78773445132.,/*+.+''&("%#"" !  !   + +  + +  !! ! !!"! !!  #"" !""# !! "!" "$$$""!""#""!"%$# !!"!""%%$$"!&&%$'%[]`^ZYYYYXXXVWTRRQPSSNLLKLLHFFECCDD?@A@>==<87;55767311/-.-*,)''(&&$$##"!! !!       ! !  ! !!!#"! ! ! "#" !!$%"&#"""#"!!!$$"! ##$%%$$('(%&'%''``a_`X]\]YY\XWTUSRSTPQONNOKJIIGGHGEKCCB@@?:>847799542220/.-..*((*%'&'#""#""!  + +  +    !!!!!!"     !!! !! #""#"!$ !$""!!!#$%##"""$#" !$#""%!""(%$"%(((&''''&_`_^a\^]]ZY[\Z\WVVTWTSRPQONLLKLJHIFJGDI@A@?B>:9888955442300//-.)+''(&#%$$$"# "#    + + +   + + "!   !!   "!! !!!#" ! ""#$!!$"! ""$$$%"#!$$$"%# #$"$$%%$$$%)(''&&%%&c_aa]d^^b^^[Z]\XWWXVTXUUOONNPNMMJJIGIEDFCAC?A>@?:;=88<7422120,0,+*(('*$$&%$#""###! + +    +   ! !!  "!! !!! $""! "#!! ###"$"##%$#""!###"#!#"!$$$%&%%%$&(#''(%%%fb`baaab`^]]_\[Z]\XWVWXWWTOSPSQPKJLHIGGFGFCDBF@@?=<@<<>833382202.,,(**+&&%#$$$$! !"   +   + +  ! !# ! ! "!!!!!!!"!"!$!""$$$##$!$$##!!"$$"!"! $$#$#%#!%%%''''&$&fcbecabab_]b`_^[^\[YYXWZXVSQTRRQOMKMJKLJMMIEDDBCC@>>;<;:66:774435/10+)/.)'%'%&$#" !! !#     +  !$!! ! !  !"! !!! " "#"$%&$##$"%%&&%$%$ #!%#""! !$#%$$%"$"$&()')&##egeeeecebbaa``_^^]`[[YYYWVYWWUTSQTLPMLLLLHLHHIEGEA@?=@?<;:996864641110++**(%('&$$" !!#"     +  !!      !"!!!!" !"! !!! !"#"%$$#"$$%&%!$#%!#$"""$$##"!%$%%%#$$'%&''*&&#khggefefdcaaaabaa``^Y\\[YYZWVZWXQQRQRPNMNLJJNEGFED@B>D@@>>;;:778886241/,,++))('(%$$##$$$    + + +   !! ! !"!! ! "! !" !!!####$$$"#"#$%#$#""$%##$!$$%&%#$%&&&""$(&$%'%%%$kengjgfdchdcbc_baa^\]\]][[\XWWUVWZSORQNNNKRKJKJLGGDCFCBBBA>B:99:544575333--.,,.)''%%%&$$#""!     +          !" "! !!!""!! !!#!! "!$$!" $"""%"#""!#$$#!!#&%'%#(%'&('###$'(&'$''#kkkhimhffegedfebeaa^ba]_]]^\][[WXXXWRRTPPRNNNMKGIFJFEEDED@B@=<<;=:978743231.0.,++'**)('$#"#""     + + +   +    ! ! ! !!  !!!#" !!!!! !!!!"!!!"#""$" #""#%!!"#$##&#%%%&%(%##%&'$''('$kkjjjjiilghfigaecb``]a^___\_^]^XZYVVTUXWROOQOOOMJLGIGFFDHABBC?>>?<=9786322100//,-,-*)'(%$&%$%# ! !     + + +  +  +       !! !"#  ##! ""!!!" !!!!! !""!$#"!%!$$#"###$$$#$$$&'&&&%%$&%%('(''&'lkjjnklkjhgghfefeeabdb```e^]^a\[ZZYXWZTYSRRSPQONKJLKLIKHGEDCA?@@C<>:9997644551////-*()%'*''%%$"$"!     + +  + +    !  !  ! !!!!"#   "#! ! !! !" !!!"#$"#"!""%#!##$%#!'$$$&*('(''%&'($'"&'')lkklklomkiihighigjffba`daaa^^]\]Z\\YY]ZWXVTUUURSPPNINMMKHHFGDBBEBC?><==;9647745000/1**)*(**'&&&%$$!!       +    +   "    ! ! !! !$"! !! !" !#!!! "$"#%#$"$#%#"#&#$#$#$''&%'('''('('%%$')&lkkkmkjmkjlhjhhfmdhccdde```c^aa\^\\[[[ZY[YWUYRTSUQOLPMMKLKJGFDDDCB??>B<<;;;7776332702-,+*,()&)&'%$$#! !       + + +     "    !  !#   !"!! #"!"## !"""""!! !"$###""%%%%&#$$%%&%%%%''(((()%'(''&$'$'plknllkphjlhkikmkmdhdabadadda^^_^[_]]]]`WVWXZWXYUTSTRNPNQNMIHHFIFCCCA<>A=>99:447/754-0/-/,/%+)((''%# !" #      +           !    &     ""!  !##""$##$ !"$"#""""#"$#$%$#'$+'$$&&%$%'%%%&((')%%(((()$&&%nmnlnkmlmmmmnljjkjhheddddfhebc`_ab`]^^^\\][\YYZVVUVTSTSRQPNKIKFGIFCFDAAA@?@=::99<877610/0...-+)(()&$&#!"%#!!    + + + +    " !      " !! ! !#""#  !!!!"!#$$" !!#""!""#"$$%#%##$'%&%$%%$%"$$%$%()&(((()'('%$'nmmmmlpllmlkjjjkijligeegfffefbbab`a^`^_][Z]\ZYZXXWTUVURRSQNLNGNLJHGCFFCCD@>=<>9<98867634111/02,+*))*%%$$($!!!"   +  +   +    ! !         ! !  " #  !!"#$""!! %"!"$$#$$$#%$%#&$$$$#&%$#"$%$%&&()(')''(&'%&)nmmmnnomokmkkljkkjlimdggggghfdcd`dbb_^]`\]]_\]^[ZYVZVUXUSQPPMLNLKNHHGGGDDCBAB@C:::::9875432332/,+-))()(+,&$!!$%#  +   + +     ! !!!!!     "   !  ! !" !!! "  ! """!#"!"!!!!$$""#%(#$$#$'%$%##$''$$#$$%$$%%'''('%'(*&('&ooqlpnnjqjikkjjkkpmlhhkghhggfefdhdcc`_ca`^^^[``XZ_W\XUVVRTUPQQPOOKKILHHEEFDCAB?><:9<::8956622411-+*))*(*''%%$#&"!        + + +   +   !!!! " !!      !!!   "!! "$! !  !"!!##! "!#!"!##$#&%'$%%$%%$"##$$$"%%&$&%&&%#&&$&')$)&''%qplqnmnlinkklimlplmlkjjjkjkideeegdbaa`fbed`b]a_a]Z[Y]XYVWVUVSRQSMRPJOLHGHFEDCDBD@=<;=;889966251.0/-,)-**.'')'&#$$""!      +    + + ! !!!    !  !        !!  "   ""!! ! !!! !#"$"!"#! !# !"#$"$$'%'%$$#&$%$#$$$%%'&%#%%&%'%$$"($&&$%''rpolqnoomoonjjnomlmomlikkiffjfegficedebbae`a`a_bZ_Z\[]W]SWUUSQQSPNLMRKKIJFIFHDCEDA>>=@:;:666=4534413-+++.-))'&'%"%$$#"     +  +    + + +   !  !! !     ! !  !! !  ! !  "!   !!"!#  !!! !$""##$"$"###"!"$"&$$&(&(#$($#$$$$#$!&$$%$&%%''%$&&%&$%%%&'noqqnnnlnnnlomkonmmlmmlljhikilfefhefcgfcedac`aaa_^]^]X][ZXYYRUXUTQNPLPLKLKKLJHFFEE?@>@D?>:9::988472220///.+))()$(&%%&%"  !  + +   + +    !   ! !    !!       ! !  !  ! !" !""!!"""!##"! !#$"!$!##$%$%$$"#&%$&&%&&$%%%%"#%$%#'#!!&'%'&'%'%&&'&'&$&&&qppqsopnnonolmoonnmrmmknmkhiiiiekihhjgefcckbbb_a``_^]__[ZZYWYVVUWSTTUQSKMONLKJHHEEDCCB?A@<:;>:8779452/100/.*,)(&$%%&%%$!!#! !    +   + + + + +    !!   "!   ! "!!  !  ! ! ! !  ! ! ! !!"#### !"!""" #%" (##$$$&$$"$%$%$&$%('(%"#$##&&$"##$"$'&%&&'''&&)(+'''%ppsppopnspoopkponnnnnommlmifkjijiihihhfebeddbfbaa`fa_c\]a[YZY\YVWUTRTQQOPOQOKLLFIGHDFBAA@>9=<;997957562221./,*+)*&)((%$"$#"!!!!!     + +  + +      #! !!!"! ! ! !!!  # "  ! ! ! ! "#""! !!!!$"!!%"!""%#"! !!!"!&&#"'#&%$$$$$%$$&&&(&$$#$%")%&#"&'('&'%$('()(())'&%srqsposppntnpmlmppmnnmmnpjkkiijjihjgghffggeddeccdbb``b]_[[ZZ\ZYXWWWTTSSTQQOONMKJIFHHEEDA@@B>=;?;99996334111.-.+,))&'&'$$&%#$##$"         !!!#   ! !   ! !  !  !!  !!   ! !!"!"!"!"!!!!#$# $!! !"$#!###$$#"#$#"!#&$%%&&&%$$$$#%$%$%''''$'$'(('(((((%$qqpporqpqpoplqsoopnpnnonmlljnjjkkijjfijghheffdgdbedab_`__[\][Z[YXYXWUTUVTQPSPPMJIJHGEGD@BBA>>@@A<;:8887853310..,../'+')'%(%$#&%#      +     + !    "  !"!" ! !  !! !!!"! ! !    " " "#! ! !#"$" !" !#!!!""&!"#$$%""$#$&$%$%%$"$%""%#%&$('%%"'&')((('%"$%qqrqqqoqvoppsoonrnqmnnnnoomljkmkhiggeeigggghegjjef]c`ab`_b`_^\[ZZ\ZXXWWSRRRQRRNOKIIGMFGEFF@@@BBD@>=;=68875420/31,.3,,+,+'(''%%&&#"$!!     + + + +   + + !  !$ ! !!!"!!"!!!!!" !!! !"!  !! !  !! !  "" %!!    % $!"  !! !"$#!" %!!$!"!$#%#""$#%"$$$$#$$$%'%%$#%$"&%%%%%%%%%''(((('%$$'srqsrrqqpsppqpnrroonmnplnommmlljlkjgilikghhhhhhdedfdcaccba_a`]\^[[]YZXWTTRQSTSRTNMLMNKIIFE@DCCB>@@=@<;979663351222201,,+**)(&&&$$#$#!     + + +   + +  !!!!  ! ! !!!! !!!$ !!"#"  !! !!" ! !! "!   ! !   !  !   " "  !""! #"!""#!"$%"#""!"$#"!#$%&$$$%$$" #"&&&$$%%%%$&$%$%$%%'(*))''%$&sstqqptoqsppsppppoummnoqlnnmlljjnllhhhkjjhgkhjhfhfedeccdcae`_^]^_\YY]WYVUTUSWTQSQRLMOPKLHFGFCCCDABA>=:<=;87556521531..0-,,+,+&)&%$$$" ! !         ! !  ! ! ! $"$$" !! !!!"#!"$#""! !! ! "!  !!! ! !! !    !!  "# ""! !!" "!!!$#""##!#"! #"##"%$"%#$$&#$#% ! '%&"##&$%%&&%'&&'#(%'())(&%%(ssvsrvptrqrpnoppqrqnmnmnsmmnmpojmllljjkmmjjmjkghfgfffddbcecef__^^__Z[X]ZYXXWVWWTSPRQRJMLOIIKHGCCDB@B?876654544102+/./0+.)))+'&$&#"""!   + + + + + + + +     !! !!"! !"  $$$$$"""! "#!!""!!"!!$ #!!"! " ! !!!    !!! !!"#!!!""#!""!$%$#"#"""! ! !! !%$%%$%&$%"%%'" #$!"!!!"!&&'('%%%$%%&%('(((''&''srtvstttvsusrtsopppptooononqopmppmnqpmlnkmkjjhjjjjjghhggihgffcfbbb`b`^]__^ZZ[WXVUVRWSSSPQPNOJKLIHFEGFFDA@BBB?==?;=;868:76420040123..+,*+)&$%'%$#"! "      +  +    ! ! !!  ! """$$"#$""#$!!%""!# !! ! !!#!"!!# !!! ! " !"!! !"!!  ! !! "#" $ !#!"#"""""$$#"#" ! # !!"#"%%%%%'&%'(%%%%$"$$"""!#$%%%&''((&'('''&()(((('yyzyzxyyyyzwxuxvuzuuuttvsssqwqutpsuutqnqppomokonnppnmikiklliiggihgeefadbd`^[\[^_ZZYWYZWTUQQPRRLOKJNHJEDGDFEGHC@A?>>=@<;996685510311100+,+***(((%%$&#!" !    + + +  +    !   !"$!"#"""!!##!$$%#%$"!"$%#"#$"#!$$&""!!!""" "# $!"" !!""%"  !! #  !"!!"!"""""!  !!!""$""#"!"##"""""#%%&%&%$""#&""#$#$$%&%%&(&'&%%'%&%&($#&(())(''())())))*,)**('(& \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002_cam1.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002_cam1.bin new file mode 100644 index 000000000..4ce580c1d --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002_cam1.bin @@ -0,0 +1,1446 @@ +Ɠ|ywurqopnqgihgfc`^[]][ZWUVVWSRRRPPNMLMMKNILJMIHIHGGDCCCBDACA?@CA@?>>??=;A>;:9:;;:;;:67998:775668465455665755555454553424502322121221232101341///000201023.00./02&0,.)/,,,,,+.*+.)++(&,+(**),+))+))((('*(''(('$%&%%$#"   #)'')*&$&%'((!!  !!!"$(30.EJKONP*)*)!  !!"  " ! !!""#  ղ{yxurrrnojihgddeabb][\YWWWRTRQQQPMQJOKKKJJLMHHFGGEFECCBA@@AA??@@@??>=D@?>>=@<>=====:<;9::99988679777666658558455444443433433302344132222221/301./01040/010.,,./.....----,...,+++,++)++)(+++*))))*()+))(%)''('''%''&''%%%&$#" "')&&.'#%')('! !")(((8LLHMQ2)%"""!  !  ! !#"! !! ̾{xvusrqsnkigheda``^]\^YWWYSSRQTRPPPOQKKGLKIIJKMHGGFDCBDEECDB@??AA>==?>=<;:>9;:8:9:997:777975569555446544543437344223441212223222202100402000002.-,/1-.//-----..*,,,*+++++++*)+*(+***(**)(,+%)('')((+&'(+&&'%$##!"! (((&),$##()($  !&')')-CLKKLM1#"""$ !!!   ! !  !!"  "" ٦ywutsronnkggcfcac`^]\[WXWWURRSRRNPONLLNJKKHGHHJHGGDCCC?BBCCB?A>==@?>=<<==;:=<9:99:9976678:8665577565554546441254452222/45622320101020011/.0///.///.....--+/,-/..,.,++,++,)+))**)**-*,(),))('(((()+('('&'%%&&#""!  '*)&)($$&'+*# !"$%''&)4KKIKM?,$"!! !!!! !  "#!  !!Θ~|{zxuuvonlnkokdbb`_^\ZYZXWWXSSSRNRONPLKKKKIHHKHIHFEDDCEBDE>CA>A>>>====<;:::<:969:9::8887766776666654466653064563320222432221041040//0031./0210////.-./-,,../-/.,-,+*,,++(()))*)))(),)+)((,)''(*(***'&%%$($'$"!'*(')+'$%)*+)"!! ! !(##&'+AIKGJK?%%% !   !!!(#   ! ֙}ywywsrqsnkklgeda_b`[[YY\WVUTTQOPOPMNLKKKINHHJJGKFECBCCCDBE@@??>>>@>>><<::9:<=;:::898:77776586665765445466445264222423223321201212121003011/010/-.0..//...0./.-,+*,+.*,+(-)(),()*)'()+())((((((&(*'(&&%'$%'%#$ '('((*'"#,**#!!!   !"%)&(2EJJLNG,%%"!  ! !    ѫ{yzxwuropmkjjhbee__^[\ZYZTSUURQPOMNONKMJJHHHHJMFHFBECBFEE@AAA@B?A>@>=<<;::>9<9;;<897867756777783774445444446374313333142231/41131101.0.20.011/.0/..-.../.,.--,,-,,,+,,++-))*',(+))()**((('&(('((()('&%&&%&$#"#)(%(*(%!&*)'!    ! $%'')=??9:<9?<;;:978<776777778977675544444464345543452333242613/1332112321/11/0.1.//..//,,/,,,,+,-,,)+,,*.++*+,,(*(++&'()'((((((''()('&%%%%$$$ +(''++'%$%)*$! ! !""%%&&/IHJNOH0%%%'      !"" "!!! #! ջ~yvxruqpqjhjggcb_^^]YZXYWTUTSSQOOOPLMLLKJKJHIIGGEGBCDDGI>BAB@@>>A>?=?;;;;<;;<8;8889677766895865557575645445445544454301/2024322322022000104////1..-./.,,,++,*-+,+++,,+))))*2,+)++++)))(*)())()('''&'%$$$$$"+&$)+*'$%,*+%  ! "#%%'*3EMILMH)%%%  ! ! !!"!! ԕ~|{zyyttplkjkggca`b__\[YWVVTSTSROPNOOMLQJKGHJKJKIIHFECCGCCCDBB@?A?=?==<<::=>9:::99:787967879867667545637456332644412334457332324222131110/0....01//+,/-,,,,*,+,++*+,-+**+++**'()*+*(()))+')&'&'())'$$#$$$##" %+&$)+*&!',,( !  $#%%%)&&%"  !"! ! !!!Ъ||uusskmknkgdg_h__]\[XXTTVTTRPQPQMMJIJJMKGIIHJIJDBFDGDDCCC@>@?>>>>=<;;>9=<;::;:988<655898787765795763455244435325244655448062231301.1/44/0.-0//.,/....,,,,,,+)+*,+++++(,*+(*)**)(,+)))(('''&'''$'%%$$$$$!)''&).'$*.,' !#%&((,KMLLKF4*+'!  ! "!!! ! !   ؛}wxtuupmmllhigb```^\\ZZVVUWSSSQPQOOMIJIJMIJMJIHGFGDCDEEBBCBAA@>?>>??<:<>:<;::::7999987778987758655664434746354333464473635326221301..///0///.00//./-,,-/+./,+.+,).*+,,+))+)*')))(*(*'%(''&&'&('''%$&$$""')('+,(&+-.% !$&')+;IMIKL>.*'#  "    "   Ӯyzwsppomkjhidba_^\ZYXYXWUTSSQUOQMLKIIIJIHGIJHJFIEEFDEDACAA@A>>>>;=<=::<::;::;::89;8878778766756955453544442354643444546333443101030//010//..0///..,-//,-+,.+,+)*-,.*+*)*)(*())+*,))*&(''('&'%)$$&"##!!$+*''(.$&(*..! !$%+++9NMLLH8,(" !   ! ! !ʜ~~vxsqppqfgfcce_d[\\[[YZUVTQQOOQONLJJLIIJHJIJJIHFHDDDCAB?B>A@C>====<;=>?>><@=:<;;;9:9;9:9777;877666966765265444333433363344564224234230011-1/2////..././/2,/.-,---++,++++++*+')(('))(+-)'+))()(('%%%&'$#"%"  "+)'(*.)$"*.-#  #$$'1HLKNKH.*# !    ! Š}xussrnmihfegcbd`][[YXXUVTSQQQPNNPJMJLJJIIHFHGFGEDDAEC?A@AB@?@?>==<>?<<;;<:::88:779787678:565665544564623443443343434422/21423111100501///,---0/-,-,..,++++)++++,))+()(((&('*)(%*')&''$(&%&%$'#$!%"(+)'(*/&%&*-,"! !%%%+:MJMMIC/$"! !  Ҝ|yxxrpomkjgfeda``]]ZYYXVVUVRRVQQNLJKLJJIIMGGFIJGEFCCEBAAB@BBC;=====:<<<;::;6978988898978756586556544654835455737874554340332222010.1212/1///310.+..,,-,-++)*,+(,))+((''((('()))**'&(''''''%%'%$$'"  ,))'),.##(+/(!! !#&&'.QKJPKI.(("!#  "! !! ղ{zyvspqpmkifgecb``]]YZX[WVRTQRPNSMLLOJJIKIJGHEEHIGFECBF@BA@@@@>@<>=;=<;=<;;:99896<9:9887757757577586486544665544254543321224111310.03000/01/-./.-...+.+,,*+*)+*+*)))')*'))((-')*'''%'''&'(%'$%$#!" .(*(,.) %+.+) $"%&%(1OMLGMC+%$#!!  ! ڟ~}zz|wrqqnlkhffiba`^_`Z[YWUTTTQQRMMMLKKJLKIHIHJHKGGFDECABDA??>=>>?=>=<;;;<;:9999:=9;<:9<7797476975545345455433543344354533324240/223/20//1.//.-/,-.-.-.,++/+,))+)*+))**&)(')(*(('(''&('('&%'''#"$! %-)()-/#"'//,   !$$$*,7IMNKKA,'"!!!     ת~}xx{tronmkhhgfdaa``]]YZZYTSRTQPPOOLLLIJLLJIHGJIKHGGEDEE@A@????=>@><=:;=;>;:99:99;9;:798766668371755554533454323616342342322322301200011//0/..//,,,...,*,-+**,*++**++''()(*$+',)''('(''%$$%%$#""$#!,-+(,.,!!*00%! #''$&0>?=<=;;:<<;=8998:9;:99887777787564555455344423221232522312222211111/1///-4*/-..------,,,+..,)-++*)('+*('(()))')'('&''''''%$%$$""$"'+*))/,(#$+0.&  #$"&'.KKJKH@0)$""!   # ! ڝ~zyxwrsooljhicdcc`^^]XXYWVWTVSQSNNOMLNJJMHIHGFGHHEEFDBEBA@A@@>>:>>=<<;<<=<=:9999:9<:96976668655564565444343332332344211222113223/4/1./32.1..----,-,,--,,++*+++*(*+*+))))))))((('''((('&$%$(!"#"(++*,-,&#%-/-#  !"#&&'8LLHLJ;)(%# !خyxvusromjihgedb`d_\\YXXZXTUUTROPOMMMLKJIHFEKGIJHGBEDECBA@??@A>==@=><=<==::;769:9::5898949787888459454344332365251813012012122100100/010-/.-..,,/,...*+*+*+,,)*+(*+))'))))(()'(''%'('&%%''& "$*+()+/-'"'01* #"$(%')EHKGJJ1)&$!!"  ! ɣzxwtsrqqjkhkgddda__^ZZXWWWVSSQQQNMLKKKIILHGGIIHGGDEGFBD@@@A;??>?=?>:<<;;=::9;;:9:8;6877766567975564544244533134462531111332211/10-3///./1./.-.,,++-.+)++),/+**())*)))()))*(('(''&'%'&%%%'#"## ,+')-/-"%-.1%!!#$+&3IIKJIG*'%"! !!!   Ԩ|z{vwsqmlkkkhed_aa_^[ZXXWYUSRQRPPNKMLKNJIIGFHIHGFIGEDBA@A@B@=A??====;;<;;9<:<9;::8<<689956978645445543373423444336332114131320210100///..10..-,+,,,+**+--,*)**)*)()()**()(((&%'%&''('%%$%"#$"&++()00($',00!!$$%$-3IGFHI;*$$#!   ! ۧ~|x|wssqpnkkhhdcbc``][YYX\TUSRTQPOONLLLKKHHHJHHGGHFFCADAAA@A?<<==<<=;<:9:;9:::;98::46885578:7;:5544556444631254335302423112222/130/,3,///2-...+,,-0*++++,*+)*++)(.(*((())((&'%'('$)$&&'$"&"#/+*&/1/"!+.-) # $$%',BDHGGJ7)%$$"  ͧ}}{xytpoqmkkkfgcdaa_\Y\YVVSSSRRQPQOOMOIJJIIGIHGIDEDEBCAAABA?>=?=;?=;<@;::9:;8;8<8<78887<8776856475444334334454454441243111010220101-//1.00-.--,+,)++*,++**++)+)('((+(*)''(&$(&(%%$(%$'#$$%(-))%02+"",.,$ "#$'.GGFEJF-%#$!ۥ~|{zxutspnmljifdabb_^\[ZYWWWSSQRSSONMLKJIHHJEGHFFDDDCEBB@??@>@?<<=?=?<:9:9;9;9>8:77775:7887:6764444332332334435564432334010230011/00///0//..--,+*.+,*+**+*(**)()'*''()(,'(&(''&&&%'%$#$#$$$0)%%30'#%(.+" !!#%)6GIIJG@&$$#""  ڮ|}xvxsqpnmnlkhfece]^]\[XWXTUSTSSPOMNHMHGJIHGGFFGFCCHGCAAB>=>>B>=A==:<::::;7;:;;777887<8788675557455543134444642537233211110.10100/.//0/..-.,+++,-++*+++**))*))(()())*'((('(''&&&%%$$$$"" ,/($220$$*,-)! "!#%,DFHHIG7&#%%   ! !&շ{yw|vplpmlkihddca`_^\[XXYWSSWQROOMKJIIIHIJHGFDDGFEEEDB?@?@@?>>?=>=;99<=:;:9;98;;89888888786465576333434554333355423245022120.100////.///,,,,-+-+*++*+-**))(()))(()*)*&'((''*($(%%####%  /0)"62-#$-14#""$%.FJDKE>0&#$" ! #!ͧ~z|xzuqqpmllfgddba``^\\YWVVWSUQNOOMLKIIIIHFFDGEFEGEEDC@@A??>@>?><;;99;=<:<;;:996:8<69887677564573634633421125233533113412111//00/0/..-.,,,+,,.,+,,-)+,+)*)'()*)(((**('&%&''&''%%""##$#'0,'$42,$)/01 ! $%&=FEEGF>%$$"!! ݧ{yvtsnpnljhjeddb`__]\[XYVSUSPQPJLLMLIHIIJGEEEEEGBCHCGAB@@>>=;::;;;<<<:?;;::789:;8988686826555654433353333322425535322102300//00101.0--+-/-+,,*,+(*,)-+)*))))(')'')'(''&'$%'$%$$%#"#".0-!)33%$,//, !"#&)>GFEFD6$#    ۺ~}yxvuspqlnkigdcea__\Z\XXXZTUQRPONMOMJJJHEFFFJDEDEDEEBAB>><>>=<><;;<;;;:<=::8<889897987677677454433222241432333367222221211100010/0//.-,.-/+,+++,++,())+))(+(*&('(%&'()&%%&%$%$$$$$#/-+$/2++/-.%!"$%1GHEFED)%$   ̯~zywtsqpqnkiiiedbd``\ZYXVYTTSSQNNNMJLKIHFGGFDFEFGEEDAAACC@?==;=:;<;:<<<:<:;9;7988888967666474345322132433323342135321102111001.2./0/.-/..--,,-*++(*,+)*)*+*))'('''&'&('&%$&$$%#$##&.+'(10,(01/ !"#&/JFDGI>*#!!   Ѭ|zzvtssqnrlikidca__\[[[YXYTTRRQOMMMLJIIMHFKDHDEDEIDG@?@B??=>?<:?;<>==;>;=;:;998:8879968978274344424533332333570633017011200//2/.-.....1.+)+/+*+-)*),+**)(++(*)(&'''''&&%%'&&"###0.+$.10'".' $#*:IGJJK3'#"! !!ծ|||zuvpsqnlkkghdfd`^^Y[Z[XUTSRQPOQJLLKJIKHEDDDDFFHBDA?@@?@>>=<==?=<;;;;;>==?=>=;;::<:<:9:98899898888766643552445540233222324233231221/120011/./../,/-,+,,,+++)))))))))('%'(''&'&'&%$"%"##%$" $1*$&12+!"$2EIKLL9*$! !ݷ}|zzxwuqommkkffehc`_\ZY]XUUURTOPMNMMLKIIGGBACFEDE@DE@E@?><<>=>>;?;=;:>:9;;;<8::8897757577855234473224034/1324366331211212000.20/-1,-+-/-.+,++,()))))()(*)$*'''')'&("%'$#$#$#-1-!,5* $#=;>>>?><;=>?<<<<::8887787738676537353345422044123223445452100332210///...-..+.,,+***))))))')(('(((('%''''&'$$%%$$"10+ .$ "%FIHJI=($"!  ذ{xxwuuonkljkhdfb_^]\ZYXXWSSRQPPNOJJJGFFEEDFDEDCDCACBA>=?=><<<><;<==<>==99:7878677576554757445552222213213235433332200100.//..0/-.+,*,,,++*(,,)*)*+)')(()('((''&%%$%$%#"$51'$' !-KGGIJ@%!""!ᴲzxxuvqmmklghffcbc^]ZXYWUSSRQPTMMJJHHGGEFCDCIFDGBDAC?A??<>>><<<==<>=>=;:;;9:6778575467467452332742231102222312342/10/4/12/.///1/,+,.++++++*)(+++*))))()()'('&'&%$%$$&&+5/  !7HIHIJ4$""!ᶵ~{|zusrppllfkffcaa^]]YWVVTSQOSPQKJJJKHGHFEDGDECHEB@DAB@>?==>=><=;@<=>=;:<<7<776598556583253245553223325222233212100101.1.2//.1//-,,+1+),+*)(,,))))*+())(('''%&''%#$&$70."HFHLIA+# ! !!߸~}zwusqonkkghicca_]\ZXVWUTQPORNLJJJLJIHGCCDDEECCBB?CB@?>==<;>;=;;>;<;9<;<8988897675675535344444222332/2321242221//.0100///0/...,,-.++-+*)*+*())))))))((''('(%'$$$$$'61':FKFFJ6("#"߼|yytttpnmkhfddeba`[ZYWWUXOPOMNMLLJKKJIGEEDCCDDEBA=ABD@>>==<==?=<;@:;::8;9888898755457542431333222433435032043410//020.///0/1.-,,-.+-+++*+*+)())(+'')('('('&%$%%%$!321 EHGIHB9"!   Ŷ}zxwusopmlggdeeeb_\]ZXWTVRVMOMPMMKIGJHFECDGGCDCC@B@@D??>=;<<<>?>?<<;;=::998:999755455543533422523434223.3121123///101100////1.+,,.++++*+*,+)**)(*+*((''(((&%$%&!!%"#/8/)&DHGGJ@/#!!͸}zyuuuqqqmlifedbba][\YWZQSSRNPMLMLKHIHFDFECCCCCBDAA@=B@>=A<<;=>??=?:;9:=:87668856266661124232204224132232301202123/1/00.//././+,,--+*+,*-+*,)**((()))'&((%%$$'"'&!&;:'9/.?IFDI<'$!!!Ӹ}{xuttrnmkigjhda__\YYXWVURVSNPNLLJHJGEEEGDCCDDEBA@@@?>===?==>===@<<::=;:87:6966475565472234222302242122/420311213131-020//.-.....,)+),,,,+.(*)(,)*'(&'''(%&'#'(&5;8+:(1:HEJJ1%" !!ط}zvuqtomklijcda_^_\YWWVTSSRQPLKJIIKKFFDCECDE@AADA>@>>?=>=>>@==;9<:;<8977775558374343133452223312322/10131022/1001.////-,.....,*++**),,)****))((((''''&'&#$&"@513>.!.DEDG<*$ ݸ}{xustooljkhhca__^]YYXVVRSRQQNJLIIIGIFFEEDDEDDBA???@>=;@?A><@>?=<<=:=;9787766565385744321330132213432011012120.2000/0000/,-,/.--,/+-++/*-++)**((((('('''#%((,!0@52@F'!+7BEF1#㸹~{zttqtmmjiggec`b__\[WVRVVRROOLNJKGIHHEEEFDDDCBBB>@???>@@><>>>?>:8=:::::78788956555527433432122255/31002210.0311020/1220.-,-,//+-+,.*,*))++*))*(')(&((&&'&%))3@77CL"!'0ADE.彺}{zxurrplnjigeg^`_][XYUTTRSSPPNHKHIGGHDDEGDCDEACAD@A?>>>?>=>=>=;<<:9;:97774:664664253422354212222253212210021040/0/000111--...0,/+-)++)(*)+)()))(((+(&"&"'$$(&A>9?LM%.>BD"俿|zyyssppkjkfeed^_][XXWWUUSQPOOOJIIJIGFFEDDCBEFA@C@>???><<<<=><<<;;=;=896789665555534343433423232213231210111201001100/1//......-,+-++*,+))'((()''))'$'%!$&($&C@4ESG$#)6A.!!  ~wvtxqploigecba^Z]\Z[VWUPQRPNLJJJJJEEEDHDDEEFDCB>A??>>A???=>==;<<:;::;8796525565445122332344221122411201112111/00/011./0/...-,,--+**,)(((+*())'*(& %&%$$&(&"EE>3OU(&""!*+?({xwvrqrpmlkgdc_^][ZZXXYTSROQOMLLLIGKFFEDDC@EBB@A@A=>?><>;><>==:=9<=88877;6954733435353212232313311/43221111110021/1/00/,0.-0+,,-,+**))+))'')()(($!&'%$$%%-%"'ED8?WN#A7(".2  ½||yttspmoljfhb``]__Y\WVSTSRQOMMJJGGFEFEDBBBBBABB@@???@??>>>?=><;;97875895<767334343544211321103010221312/0/212.100////0/./,-,--,++)**+)*)(())('$'&%%%$'**#1EE7TYE1P4!!'*»~|{zwuqslllkmfeb`_[\YWYVTSTPPPQLKIJIHGGEEDCBBDAB?A??=??9===><==;;7<878877868655322345332322232231103033213/0/1/30.1/..0/-...1..,+++*,-*))()*)''&('%%%$%#-)!9ID<^[. RP+( }|ywttupmnlklbeaa\][[YUTSSVQLLLNIGGGFFFECCCCCCCB@?@>>>?<>>>=?<;;<:79877887765554625423823403222222/111120//0/0201//0/./0/./..,,,**)+*))()()("&)('&&'$%%&-%!OJA=aa,.ag8#" ¿~{zwvvvpnlkihieea`_Z[\UUURQRQLLNIIKGJEFDCHCECCDB?@@>=>>=?=>==9;98:899786:76666575444434400220201132220011000223/1/.4//././/-+,-..)+)))()$(((')('(&'''+.%#=NL7eb8&GofI4þ|zxxwtvurklhfdb`_c]\ZXVXUQPOMMNJKHHKEFCEDDCBBBBBA>@?=@?>>>=;?:=>><><;<<<::89888;964545546445241333302/121202011.1/1210000/0///./-.1.,-,.,*)+*))!'++('')'(&('''+/) (TQAQoP-E|zuTI/${xzttrqmkjfbcc`_`\ZZ\XVRQPPMNNMKJJFEEEBDCB@AD@B??>=?>?==@;=<::;99888876846443453742234324/20022211/102020111020//0000...+,,+,+,+*+(&&,*()''(()(((''%5+& SXQBgr:"^zwp`?' ¼~||wwrrqnljiice`bZ\[ZXWUSQPONMLLJIGEEFDCCDB@@@@>EA?@?>==@;<:;:988678:7755555545755546432212222210103001/00101212211100120.,-,*-,+,+%,+((+))')'(*('+'$8,& 'VSNPmk01zzyfgE'}}xvrqsoljgfbecb`][[ZYSRPPMOMILIJHFEEECCCBBABA?@BAB?>===<<;;=8875996975576647445433334414222221240413/1/0./0130100/1/0...-.++++,(#".)((()()((((('('#/7-(!4WVI]p\*F~xsll=!"Ŀ}}|ytsrrlojiggc^a^c[[XZSRRNRMOLJJIGHFEEDCBCAAABAABA??>?;<<<:9998<5588686747654575224234222423241223102-/0/0002133334200//..,,.+/,&),*)((())((()(((''+59,' "#>YUJot>)jx{pj8&{}ytupokmigeec`^][YYTUSQNQNMNMHGGGGDEEBACCAAC@>A>B=;B<=<:=89:;6;5798777554557542512423222212421130././/0.1//02044001//./..,+.,$!+++')(())('(**,((('(97+"$"&T^MWtb40wzur[,ý~~}xwtssplkkiecca_]]ZXWTTPRONNJKJJHHGHDDCBAAB@>AA>=?==><<<;::<;8<7;7978765547442433221252210112111221/////1//1012321100//0.-.-.$$+*(**+()(('''()))*(&)?8$!""6bUKitU%PzzwtK#"ÿ~}yvvsspnkkfgdca_]][YWUUQQOOMLJJHHGFHEDCDBAAA@@>?A@=?;<::;9:;999977::7666542333444443332221121121-3/1///////00423436121//.//1(&.+*))((*),((''))**+('@A6- !La^NtsC*k~zsvt<"!{xwsqqsllgfbc`^^][]WUSSTNMNMKIMGLGCFDBBBBA@?A><>?>====?;<;::999:9477660552625243451216211/05.01.3003/0//./002534743010/1/5, *-+*+)))))(),(+()))()%(E:/! ! "ZbWXvm56}}tsuk("#!{yutsomnjihdc``]]]]YWSTSPLMLJLJIKIGECD@CDA?@?@@??>@?=<;;9;9<877778655554564524433332322113101001101/10/.010222346553202/79! '.+*++**,*+))*))()(**'*-H8." !0aaLhzV2E~xvw_(!" ~{wtronmjjihb`^]aXZ[UTSSQONLLIJJHHEBDCBBBAA????@>>??=<<=:8::79777649544544552533222242241011201011000001/1111214565323'=K#' &1-++*)++,,*+)))*,*-(*($=J0.  Cc_KvvD/b~A!!#º}||vspmlpjigd`_a`^\XWTRVQNLLJMGJGHEDBEC@@@@?@@??>@>=>=;:::;989865555663364335334225242221321//100/101100///1103167614,Fm") )/0.+++)++,/,)++,++),**(%MI9# "+UfZY{p:,{~r+#!!¾~~|xtrqnkkhfcb``_]\XVUTTQOMLKIJIGFDGDCCB?@@@??>>@>@A;;89;::8:987646675664433443243223012431101000000/12/00001324764:$A7#%"!,/..,,-***,+*,+**+++*+(+)5M=1#"$&/ljWs}d0RxQ'&"!|{yvuqqkjhgfbc``][XXWTRQPNMJKHIGFEEEEBB@@@@??>=?==;=<:;:;::899966767436354444343321143233300101103/50/1110/1335525 Ec'$ '1,,).-,-+*++-++(*,+++*,+'AL5-!"'&LikW|}I/j~E&&" }yxutrrjjhgeabc_]ZYXURRRPPJJKIGGJGFFEDCADA@?@?>AAB<=;;999:99:9888655851334554345433412122120030022/114211111,33420 #""+/+.+,,,,1++*++*+++,+++*)+!JJ3)%(#blcaw30{y/&%" }~zxxvsnjhjeecba_\^YWTTQOPMNKIIGIFGFFDD@BAB@@=>?>?>@=;:;:::8<998756645665454315426343312032221322/2./221011110221.#"!(2,-,-,,,+-,+.*-**+++,+)+*)(XE7&!$'1kkTu_/L{^&($!ÿ|{|wtsnmihgdeaa^]\YVUTRQPNLLKIFFFGFECBCBC>@?@>=>?>==<;9::98;9:67546476522322263372241122221111010031110012021122-$'10.+,-.,,.,,-,++,)++,+..+*)2SG2'!#(#OolW~H)rzC&&$#¿Ŀ}{}uupqqmjgheda^]ZYXXTTPNOOKIHHIIEFDCBBAB@@@=>?=<==<<=9>;8:;76<6546475553331303410120272111113221117100010001101+F'&11/..,-//,,,--,,,++,,+0,-+*,LU:3! !''+knlg|<;~y/($% }}ywtsqomjifecc^_YZWVTTQQOMNKJKIHFFEEBCAA>?>?:><;=>><><8::;5678565565553330223445301/0310/00101002010210/110011/%!&$,20./,-+..---+)--.,,.,,+,,+.'VH>'#&'(6tz]|b6Dd'&%$Ŀ}wtrqnkhihfa`^^ZYYWYSUQOMLKJIHGFEEDCCD@=;<<>=?=>=>><;::7879888555545645512323343130010/.1/2111/2.021011/00.///3n$%)3210//-...--+,-*---,+/+,,,+'?`R.  #&'&Xzw]W,nN"''&!|{usrpnkgfdb`^`]YZWXSRONRLKKIHGGGCCCBA@>?><9;;9:;::9787655554133243454332201100100113..3/50141110201/+GJ$&0314/0.....-.././+./+,,-+,,,"P^G- "#$*+wypm:+x8)'%#¿~{|vstslhfdba_]^[WWTRTQOMNLNJJGFEDFBA@A?A==>>>>>>=;:9998:::997886464566351343323110222020/12110//12002/.10/.00N&(#&24113./0.,+-,,+-.,/+,,--.--,)dZB+ #$'1:zzil2Qh%)&" |zvtonkihfea`_[[ZTWSQQQOQLMJJIGEFCDA@?A@???>?=<<;;=:78=:9:7:797;243554343442321430123222221213100000///1,1/.;>(%#(222010/+.-,-,1--,,,*,,-,-,++7gS9.&&%(VzxhX5nN%($!}xtrrophfhda`^]\YXUSRQPQQLNKIHHGDGBA@@@@>=>><>=<8=:999889:58776655427566450323311133122112122210/001/1.012/,C4&$&,3/13001.-+,,,.//+-,-,-,.1-.+SgL6%!'&'2+izowB:21." !~vuspoljgfea`^^Y[[UVRRQONLJJJHHFGDCBAC@?>@??>;;<<::;98888;8887454672564432222232413142011131122001/000//011,A/$$#./10111/.--...,,-..+/-./.-.+&hiL6!'&*.:xep9E{+'&%!}yuusollkfef^_]\WWYVSQPNKMLHIHHHFDBCC?@?>A==@:?:<::;898;7678789643433254476233221203100122211211012//10/00/.<*'$&.001000/.,..-.//0.,/.0/.0/.-6qcL0 !!(-*QqX3nR',-$!!|zuutrnkfhedb_]\ZYVTSRONNOLJIIHFDCBDBCA>>=A;<;;;;;:9:;77888777966432533344523233012200122222110122/00//0.///5%$$&+01*000-..-/0.,,..-..0-101.'PyVJ# "%*-+wy|D8A#+)%|yxvtsrjhgeda`^]ZYWUUSQLOLNJIHJGGCECAA?@@=;>;<;;::9979989759667953453334654443223222/122332201101/1110000/.00)$#$/0//////.-,.//.../,.....100)tuV6"!"$)),9r|>Gj,**)"zzxusqplghhdb`^`\XXVVSRSNLNKJIGGFDEDB@CA?==<;<;;<9;889887888789519635433554443312312201202211100001100//0-//0+%"%/00-..0/,,../...--//..000/0}mK2"$%)/*_uX7mQ.,)$}{wwvtonkigfab^]ZZWVWVSNOKKKHHGHFDDCBD@@@=>??<<;:;8977799298:467522445535434423223212322241120120/3111000//01.&!!!%(/1/0/.,.-.../*/-..0/100*DdH'!!"&)+.4}N;@+++! ~{wvtronnjhfca_^\YXUVVPRKOKJJGGGHEDCEDA>>>>==<<<9<:97887769796566445433344545220121221212032120310001110////1.*! "#'00...-.../..././..132- scA%!#&)..?y7Mn,,,%"~{zvtrqonlhecb__[YWVVQQOOLJKGGGFEDDDCCA?==?=><;;99:878778656635433454312354235210023323211/1331/011002110/1./0-)! $$#%,./-,-0.+--...../133.)X;%"$'-,*b{\5qN/.+&!¿z{wtsqpnkhggc``_[XWSSTRMNJHGGFFCDD?B@@?@=>>;=<<::989677777654554354333342344332112122351003121212210020000/2..2&!&'#!&../.12/../10/./121)RmS4$ "%*/0)yK87-/*$!¿}~yyvtsrmkkjdba_]ZYVSTTOMMMLHHGDFDDC@@=C=A=<<=;;9;887;7997658455454423234565434321222332110.1/211220001210//,003.(!#&*$###'/..0.-...--032/%nrQ)!!%(-12>xz:Ps0/,+( Ŀ~zxwutoomjefdbc][ZXVTRPNMNJJJIFEEBCAA@?@@=?=<<;;:989777875655455535835454335411222333233221/41310/020002121-2/222-%#$'%#!!%,00..//.//21,kB# "#%)01.p`8zV(/+*# þ}|xvvspllhgacc^_ZYVWSSROLMMJIFFEEDE@A@@?@=<=;;;:988996666655368745454624455453222224/33334241110/0000.2010/1.100042+"#$!!!!  #/0000110/(>m3 !"$'.13,TA>-/*)$ÿ|zwzvsqnjkgffaa\Z[XWUSQPNNLKKGIDECEBBAB?@=;<;<89:99756935656756622744243344313323235210320211001022/1100021/01001001+-$! """ "(+-321-#y]+!$%+-/3:;Qx+-+*&! ~~xxtsqnnjhdcf`^\ZYWVTRPMLMLJHFEFCCCC????B<<<;;:9;9856496567363352635425333541335241323011113100321100/0/0//0/110/0022-0+&!!# !!""&)..&yL$!!")+/.1c|`5sS./,(# ||wvtrmkihgefb]]ZYXVVRSPNMLKIFHEDDDAA@?=@>=<:;::<8999865445562553363410444313210423052210010//10011.2///0..1.0.2/0-00//1,+*"#! !""!"!$]SE0"!" !$'./04BDE*/+%" zvusrnjfgeea^^[YXUUSMQNOJHJHFEFDED?@@??>?;;;:9<896776554544434455444334522241233244321/100000010//00///0.//2.0/100/0/1/1222/% !###$$$ $ !  !#$*-0/D9Xp/5.+#!ÿ{ytutollhfdea_a[ZWUURSOMLMJKGGHDECBA??>>>:<;:8;;:9776658645363333633224545221241121332220111///00/1000//100/1000/1..0-/1011012/+)(&$%"!! !"! !$$)*11.Uk=u[,1-*$!¿}xxussnnigeeab][\[SSRNPOMLJIHIEGECD@A@??==<::=;89967766553336413333222665736012143222210201210101/000//02110///114/1/20000011115883-$@7%$"!  !$()/07'mE872/,&#"ý~{xvsrqmiijfca_]Y\WVTURPONLJIHFEEDBD@?@=?<<9;:9:9997767724546312232313643554311/222233101/32201100000/10/01121/010..1.030111012656793-jV)  &%((.03?IIl2//-'!{xxusppngkg_``]^\WWURRPPNLMIGFEECCBAA?><>;<;:;:898:566355271422234334436354421/21112220002.1/0100000100100/0/01/.//0/000220223365765'_-"! $%')+/36Qk6zU2.--$!¾|zwutromkkfba`a\Z\WWURQNNMLHGGHDCCB@>>?=<;:::::9986835553544411246323445252221110014210/001.3/0100001200//10111100/1/111114445565763Y#"  ""%)+/45.rQA:1,/)# ~z~~yxxrrpnljfcba^]\[XTRQONLLMIIGGEDBA@??>?;<:;:::;889657575544334333331333423402211311111100/02/3000///21//00030/1210/013211244577885/R|@# "!$&-.0469su9K|31-)'# |~|xwvooonifdbc_]\\ZTRTOKLJLJHGHEDAA@???<==::<88:9776756764423353324332221412431110020110/20/.002//0./0000113212/0/21244163446787686"w5%$! !"#$(,/27.\n8zW)10(%#!}}}ÿ}{xvtqmlkiffdaa]\WYWSOQPPMJIGHGEEEB@@?>=><;::<96987875763545333337332342332112110/1/10/11/10.1000001/0001/3212002241433373228889:84-c'$"!!"  "#$%)./880O9H45,'$$ z{~}~½zxysqolljfdca]\\YYWWRPOMLKIGFEFDDA?B@>=;<8:;::::77697834353242023322444324212030/01/3032/000100.1//0110212110/111132233445599:::8(JR$%"!! " #$(+05:3O?_x51/+&%! yzyz{}}}}zxvtromljjecba]\ZWWWSQOMMLGHFGHDBABA?>=<=<;:<9749976556443441112433222012121/2000012/1/0100012100/////111220/3312043244455999::97%ë{8$'$"! #$%)-4791lmEb.1-*%"!"v{xzz|~}}}{wvqqknlgfcc`]]YXUVSQOOLJIIHHEEF@E@@>?=;;;::69857878543445442122612322121134122/0031120100/22110002001013101211223272465::9:;:?6%g"'*&"!!"!',267<#P@F62.(%" xxxz{z}|{}yssnmmkeffb]\ZYWUTSQQRLJJHIHGEE@@@?===><89;77877666665545634223521104121112212.303211100/1002/0100010/11//22321233457579<::;>=/TѼV&*(($!! !!!$(-658?NĶ?Z455,($!wxxwy~{~}}{xxvromkiigd`a]\XWVTRQOSRMKIKIFDBD@A??==<;:9888577766274344335333/32311421002210110000/0/0010210.11100/021033021133447477=;<==A:-ѩG&))'%!!! !  !$'228:6xͳq:Y263+&%#|uvxxz{{{¼|zwxuqopkjhfd`__\_VVVRPQRROLJIFEDBBA@?>>>;;:989885775557135554324221250531110/102111101/1//110//0//1210120112/5221.6677579:==>@?6Σ,+*()&&"!!   ! " !"$+357=-ͳNFI05/)%#" rwtvx|z{}z}~}yytsrpomiggba``^\ZZVTQQPQQLJGGGCBAA@??@@<=;9997667775755454333222422112113001/0211/00100001100////32111001211212355555:8:?=@BD?1E͞e$0))'&&$"!!   !"&/25?85иȒCZ860-)$!!qrtvuxzyxz|}{{xwtrpnljfgd_^]\[XXWSSPPNJKIIHECBA@A??>><=:99867776686643313422202113223223/10103302110///01////110203100/322222265566:89=>A@A@!庝A&*-,*((%#"#" !!!"#)/2:=,wѸp=b*3.,)$!sqsrvzwxyyz~~~~¾|{xttpopmlfcca]`\[YXUVQPOOIFJKHEDABA@?>><=:??AC:#޿1,/+*)(&'$$$#"  !! !"#$',68<-ѭĸTBH9/-+'$! oqwssxuyxy}z{}}y|vsqroohffcb__Z[YXTTRPNMKJHIHEDCCBA>>==;;=:887547567766434212024115222333210/12/21.//./10000////330/2000212242155254:;<;>@DBD/Cӯo.,,-++(('&&$#####"!!!!"#$$&+277Cɴʝ>a|7/0.)&"! nosrsvvyzv{zy}|~}zxxuqoomifcb`_[[ZWXUSRPNPIIJIEGEDAEA?>==::9:97688997656745252132031013/2231110101222././.020000//21////00211325635557:<=A@AFDC#ҟY*0,,,+))'('%%$%+-*'&%$"%$%(.36 fػo@_/2..&(" pqosvruuvxuxzy|{~ľ~{ywtqpolkfeaa^`ZYWURTQMRJJIGHFFECCA@??C<>:::8887836654528333322052224013041/020001210/0331//020,210201/013422024486689;?ABCCI<ϋ721-,*+,-.,)(!1274,+*)('%%&),30ָ˿U=>841*'#" mnnsqsttvwwzyy{|}¿}{xusspnlndff_][]XZUUVTQPLKJIHFFECAA?@>=<<;9:998867557567333322132110101121131101000000100/000/0312201/./22214433445889;BCDEFC:G12,,**)+.,'"0?<820+-,**((*+.314سњ7^z366/-&$#!konmwsttsxvzz|wy|}}yutsqoniffecb]ZYZWVWQSPNNKKHIHEDDCBB=?<<=<;:99977465555333333223112121231221/1110011//11////211/001041000322323648789;=AECFFE"i/20.+,/.-/, .pB6>193.0.+000363E|4d551-)$##"gklopmorsuuwwzyzz|{zywtuqskigfgda]ZYYVUSTPPOMLIGGCEEBEA@?==;;<89899:755555451234430101023212131021220/0130100/.0110010220/13412112344757:>BACEIKAA052..-+../0JRT;?6423162457<4)OAD@34.()%#knjlmmpqsuuvuvy~y{}zyyutrspmkhhca`^[ZWWVTPPLONLHGFHCDDBB?A><:;7:98888856654454444412121211214022/2133.10/101.////000010231101/02114456858<>?DEHLK5'ӎ2680....,//%:4]E9?=987345569=?C7a><>:=8987788665454554434533322000351101401/1/30././/0.000/110000/0033334336;>8;??@EJLMGK17632/.//10)sNa_A@=::8;9;?>CCGGE=C.E3300'$" hhilmmnnrpqlrswv{yz{{}{~|z{swqonmnihdc``\\ZXWUVSPPOOKKILFDFEAAA??<:::988986765555685433333323030111201212000.01000/////1.//210/00012233226777:;=AFHJMM9&ޤA986310.//0.By7zZED>:9999:?CDLagV70_445,(%##!iijkkkmnpnmrssuvxxyyzx}~~~~zwustpomjigfc_`_[XXYURQPNOMMIHFEDDBAAA??<=;9::88877865443455432233323021321100201/010.0////102.1/.1212/112122235767<9<@BDHNNOr}3;963221100+Z$JD@B68:8:7AAEM^bW]p0~b/10+'%"!! iijjjkkmnomntqutuwwzzzyz~~}~{vttunpjhfgdc__[[YYTSRNNNMJHHHGDFCCBAAA@<;;9:88=:8766575524435341112112002215/01100/11010//..0100+001000123262357789:=AFKLOPLW8;:65200100#dnK{DCB5+.039==@DSUYFJ-B41-+%%"!!highiimkkkmoorquwr{r~xz{}}~~~}{|wuuqppkhedda^\\ZWXTURQPNLJHKGGDDCA?A??><<8:9;<9;767555162544324122212222222.1/0110/././0///110//2/001/04/24445578::=>AFGNOQ>4;;>;7321111/)x@ef?DB0.++,-/48F\geJ-Q.40-,%"$ jfhhhilnikmnnorqswrttzxx{{}}}~{wxuspnljgdeda`][[WUUUROOMLIHIGFECEDAAA@=<<;;98986984344444432231202010100/0.0.0/1-/.00.0/1////0.2/00/0/0052136666899>>CDJNPP-4>>:7411222)Lp2P@C?1.++*,-.58DTJbm%`241/+(%!elljhjjhihllmmottsssuuzxzzx~}}}}xwyqpqrmiheed]][^XVUTRVPNMKIIIHEECCAA>==;==;;:98787745344522434425012230//000-.0//./..///.//0./1..1.//011124424577:<=@DIJMRRCJ>C?:8451452,~HeoA=<4/.,.+*0/1352<2L~921.,%#! hfghiihhfmikkmmnqpprrquwvwwyx}y|~}xwurpnljkeeca^[[XXVTRQPNMMKJJGGDEDCBA@==><;;:9987876765443332232202122.0.101///./-0.00.-//0/00/..110./1101132325599<@AFHJOSU+u6FD@9774543+K;zd<>;10,*++--0256-fi]041/'$$!hfedeffilgeknllmmkopprtrwvv{{yzz|¾}{wvwqpmlkhheca\^ZX[UVRRPOLOMIHGEFBBCBAB?>=<;;979989878333434112323222220/.00010....-./-.0/10//..0/..0//120220125487;<@CGGKRRRz0GA;8874444 bϴDH;>;30/,+,..0332/<,K42-)%%# cdhedefegfhikjnklmnopsrstwsvxxxxyz~~}yyyvqpmljgfdba__[WVUPQQOPMJJIHEEDDBEA@B=<<;;;9889798454633332332221.40100.02000/0,1-..././///,///1.0000/21116222677<<>ADHPRXF"M>EA<8654333qqHi=A@811//*,,4155,=.Z¿773,'$%"abededfehgcdhjknlllorsrqrrqtwzvwvy{}|¿|xxstrnlkhgecb^_]]XWVUQQOMMJIJHFECDD?@@=><<<98:9899444633543221212110211001010//0./10...-/03/0-..../0/0/100426346589:<@CEJSVS2O;AEA;866433.(40:;?>5010.--.0443-kj»k,62+'%$!aaabccccbdfdhijklllltorpoppssuxvvwy{|}}~{xuuvqolhgedcb_][ZXWTTRPNNKKKFHHHBBABB>@;<;<<=:98775844743432131211101,10121320,/01.0/+/////+////./////0123021588559==?BIKQTT9MH?:992653#V"=<=@91/..--..244-2C#úB.6/(%$"! abcbfeadcceieiiklimmnnooqpsrrtuswyuwz{|~||vvsrpnomhdba_a]ZZXWUVROONLIJIJGHCB@>A?=<=?:::98786565444333220022100011/2030/.01/0000.-.1/1,-.,.....0.0/10343324678:>GEHPRTM [8KF>;977453!{UmE<95002,../22451C*^ǽŠ723/($" "!__aaadcdbdddeggipytlmlnmnoppusrytuw{yzy{{}yvvqspokhhgceb__\[WUVSQPPNLJIJIJBEBA@@@==<;:::787777555333223224202.10/2-//1./11/.//-...,.//-//0..1-/../11022323386;;@FHLMTT@_1DIC>:877653-ha?A=31/,+/0//124'hoľi*5/.'$!! _a``dgaccbfffdgdfijkjnkmnoqorprrwsywyzz{|{z~zyzwvpomljidbac]\\ZVYRVPQOMKJJGFGFCACAB>==:;:99;875779444653323122120000/.3/.-/////0..1-..//..,.-......//002214246687<=9;:998769534553223132120111110.-./...2-./.--/.../1-/.///-..001./0111556:8:;FDGKOSSa>KM@=:87556.Yw*fID?532//+,//245+G*S’2131)&$ []\`^`a`_ccdcdddfdgfhillnkknnnnrspusstsvw{yz|}{~{zwxtonqkkieeba`_^ZWZVRSPNMKNKHFEDCECAC?=?=<<9;<9778676745322222221000120//...0//-.0./.-+/0/.//....././/011110434578::AAEGMQZ?>BKFC?9767520s>eFD?510/././.373$sie061,($# b\]^baab`abbhcebfdggghimjklmmpppqqrtrsstuuwyz{{{}~|yyurqnnoiiec```^[YZVVVSPOMKLIHIDDEBBA@@><>=;::87777865833332222201/111/0//..///...-.//-..,0/.-/+1..../.2/0004/34579;:>AELOW[#3JID?;987653?<=<;::988886443333242021110001/0//,//.,..-.//..,1/./..-/-//...01//142235559::7;867&K{+SA;:6321//0.*265.I#_Ȓ0340(%#![^^_``_``bbaccbbcefdghhggikhmnlmmmmmopppssrwwywyyz{{{~|xxruopmkhgeba`]\\YXVSQPNMLIJJFEGEDCAAA@><;<::89878764542232122111000//2/0/1/..-.-.,0..,/....-//.//./0/-,-0011234369;=@CIMQSG'I676310..--1394&tby-22,'$#! Z[[[^^^_`a`baabdceeeceegghgmkjkklimnmmmoqqwsvttvxzv{x|~}yvyqqpokjhfdc`_]]YXXTURONMJIJHHEECDB@AA?<=<:::;8888754544221111320/002021/-./-/./,..1+..//.-0--.,//.-////11012135458;=@DGMTR.X5MHC>>:95752(h{;M:75431.,0/-2780/BſC*24*%&#X[[`_]\^aba_a``adfaddcffgegffmilhkkkkomnpqqoruuuuvvxzy|}}}}ztuqpnmkigfca_d]\YYUYSQNMMIJIHGDFBCA@A?><:;:9:78887950434220210210100/02//.../0//-//,,..-.0.//1,,../.,/2/00012335549;86866*<8752220,-/077/!zfÿ_(52+(%" \]`_Y[[][\^^`]`dafbdbbb`ccfeefejihijiknlmlkropotstuuwxxyyyzzxxysvsmpljhfcba]][][UWVRPPLLJKHFFEDDBA@>>><;;:787787967644312211223000/0//./00,//1....0-,,.././..--.+,-.1/00112174457:;CDJPPS5_-EJK>;875861%=88952210/.*+50/):/ÿƵF.32)&%$X[[X]ZX[^`^a\``_d`ccbdbcc`ecdeggffghhjgkjmjlljrkqtrrsrwvyxxy|~~zxzxsronlkjgbca``Y\ZRUTVQOMKNIIGFEDDBA@@>==;;999879877655424422234//0/0//0///..,./-1/0..+...,-.3..--..,--2///011153467??>=<9888775785543442222100.//0020/./,00-/,-+++*,.,,.0.././,,.-00/./0003123557<@BFJONML;GED<985755+@-V@985201/./.0330!`h)4.+'$" YXXYZYZ\Z[ZZ^_`__``^_`_dbbaadccecdfgeefefglimjlmmmpmnqrrstuvvyy|}~~}yxvuqnolojgeba^]_\ZYUSSNONNLKJIFFFDBB=B>=<;<;8<887998735335113212//.-//2//0..2.,.--+,+1/,,,,,,0/*.+,///1../.,101334559=@BDJNM294KDC@:894754)i޵&P@8865/0-..-/35)&6,ȵD,10))'"U[\YYY[Y\ZZ]Z^]]^`]]^``ab`aa_adcebedddcgdidgkijlnqlmmmqupstuvvvv{yz{|{yxwusmlnikgea``]][YYVTQPPLMLHHFFGECBA@?>@<=;;9999777544444235442210//01,/1.1..///,//,,,.-,../,-,+-,0+.0/.//./022423677>CBEHLO'>ED>:653652-i@N99740,/*./.031"U(`ʕ..3.*(&!XXXYXXYZY\[\]_]`]__]`_``a`^`a`ba``bfedbffdefhkiilmmnlmpopqrsuusywyzz|~|}|||xwuqqnlljhgeba`^\ZYXVTRPMNLOKIFFFDBB@@?<=:<<=<9:97556665436252100210././20/.-1//..-/.,,,,.,,,+++0-,--/,0.-.-0121135359>ACDHKHW5EB?=:74554-69IG8681../,,+//1,!`l%/0.('"  VWYXWYZY][[Z\Y\Y[\[]]]``_```]^_`ba`abadeedddfhgkiiknmoinrpqpupvvuvvwy}{}}}ȿ¿}{xwtspompjjifd`^^][ZXWTRTPLJKJIHGEEFB@@@>B<==::99887745556542223232222.///.0.//-/..,,-,-*,+/,+,*,+,--,+/,,.,/01200334489ABDEGM@$:=FA>;:84432(Uv3KC985001.-,+/31+.;C.1/+'$! ZWYXZXWZW\[YZYZZ]X\\\Z^a^^^]`]^`__b`adcacedddeffegjmjjhiklmmooqruruvwy}zz}~~۹{zztuponoljgfdd`_]^XZ\UTQPPMJJJJHGEFCB@A<>=>;=9:;8;775555444223211110000/////.+/,--,,-,..-,,,,-),-.,++,-./-.0.00033147669=FBEIK'd+HE>=<896332qh/R<:83/./..--021S`ɒ/5/,)+#! !UZXY[WWWVW[XZZY[ZYY^[[^[]`\\^^^]_^^^_aa`abcebddfcgejkihhijnmpqrqqqswusxwz{v|{}||{{vtsqonnjjfedba^\ZZXXUTRRPMMIIJGGEECED@>=><><:8:88765564442232021423-0/1.00-11../,,,..-+-,+,,++++-,++,,++,/./.1101244789<>GJHD `/AB><963236+3xbES<;91..-./,.322cp+1/*)&"" VW[UVXXWVVVX[V_[[[YZ\][[\[_`\\[[_^^\_^a``ac_cbdbachihikhiiklolppopqusssutt}{z|{~¿||yvuromkkigfdcbb\[ZXXYUSQSOLMJIGGGFCDC@A?>=<<;;988767564444222311201//0/00.//-.,0,,--+,,/+*+,,,*+,.-+,,+0.0*//./01023779:A>;6421510|ޥVyQ<;50//.,,.331#\"PĿȘ3-/-)$"STUWWYWWTVWWW[XWZYXZ[YY[[Z^W_Y_Y_\\^Y\^_\_^^^_^^`aceeibfkfhgikllmpnnpqqprsrwyw{x|z}{{}~~¿}}{ywttrqmkikhfe`b_^[ZYWVUSQONMPJJIIGEBBAB@B?@=<<:::88665556432212111311000///....,-.+-,+++,+-,-+/0*.+-+,+-,,-,,.../0211134:<=@CED m*>A>;631120,$STs@A<51/..)./33,#f ½g+.-+'#$ SSTRVYUUTWVWXXW[VXXXWYYWY[ZXZZ]^[_\ZZ[Z^^]]]]^__^_`db`dddgfgffilnjqlnqpnopqosvtyvwx{z{|{z}~{{zwvtrqmkgkfdae__[[YYWWSRPQPKJKJJGEEDBA@>??>=;:99:97767474343532212.0100../1,,-.,,-0,,+.++*,+-,,-+++++++++-+,+..../0113347??@AB>28>>976311/0,;$5G=B:51/.-'9K:1(00)ɰH+./+$#!  VRVTXSRWZWVVWYTWXWVXWXVVX[YYYXX[ZZ[VZZ\\\[X___]^__``a``cecegeigijnijljmmlmorpsrsutuvwyzzz{}|~|~xwxusrqlflicbe]b[_ZXWUVRSROMMOIHHEECAAAA<@?=;;<8897677555372332111100010/-.11-...,,-,,+,,.,,.-+-,,+-++++,,*+-,,....0/30458=A@AF/7;<<<6601.3,%az733?;7/0/-)*nm02X[˒)3-.'$"" VTTVQVTXUWUVXUWXWVZWWWVUXWWYWYYZWXXXWXY\[[]X`\\]]^^^_^acaafcdeefehghlkkjmmnpqooqttrsttxxzz|~||~~}|zyxussnnjhieeb`a]^]YWYTSRQOONLLLHGEEEBCC@?@>>:;:7<765456354235222110010///0-///..1++,+-++,,-**-++++*+*,++--/++,---.//312477;>B@@k!9:;860/-/.,&grBZ98>3001-$HK0/$`a'..*%$!! RSVSUWQPSWVUWQUWWVUXWTVUTYVYV[UU\YXWXXV\ZZU\\\\]\\\\]^``dabbccdegeghggihjlllmmqpqsqstusvuzu{zz||}{xwuysqnnlihedeaa^^[\XXSTUQQNOOKIGHGEDCAAA?A@?<9:;8796574344422321/1-1/11100.-,./.0*-++-+++.-+,.++*+++*-+*,,*/,,,--.*/0/11558=>@A:;;::867765486445322112121102/1..--,-/.,,,,,,+(+/,,,++++-+*)*,.,+,-,-./..0001468<=?A(!%2878610..-,#JiCu_<>810/.%<_7+.gWȑ0/,)%$" TRRSSQSTQSRTRUWUSUXSWUWSWVVVTVWVTUTVUXVUVWYYYZ[\]]\[]Z]^^_a_ab`ebbfdgghhhikjkjjmnnpopqqrtsstuuuvyyz||{|}}~zzvxssqomlljgggca_`^\\ZYWWVSROMOJOIHGFDCA@?@@===::9:7:67565455343010011/.001/0-/-./-+,,+,-,,+/+,*,-+++*+*)))*+,*+-+.-+./..02579==?@kt#777431.,,,+VgGxK;<600.0^5A3*!^e$.,)%$" STRRRZURQTRUWRQSUSUWSWTUSVUVTTWUSWUXUUVWVXWWVXXZZYZZY[[Z]^__^`c`aaadbfgggghjijijljkmjnssprrrsxuuxwx|yzyzx{}z{|~}~}{vvsvqpnmllfjecb`^\_Z[ZWWUTSQNLNKNHGGDDCAA>?>><<;:;98:;67777522202/1002040/.//./.,--/.-+,+++-++++.,-/++*--)++++*++/-,+,-00022689<>=?$77462.,/++)'cqDEu<;84101*@R-.96)ŲF.,*($"! QQOQPPOORSQRSUSVQVSUUUVUTXSTTUTTTSVUSVVVVXSVUUWXYW^ZYZZZ\]]`]^^[cad_acgbhcffffjegjjjkmmnmlmsoprpryvywwxw|y~xyyx||~~zzzwxuupqnlljffieebc]^\ZZZXZUUSPNMLJJGHDEDCBCB><<==<:;8<9777655233/414211/210//0-,.-,.,+.+..,)++*)),+))))*(++*+))*++++**.,,.+-.10477;76H(141/,**)*)'#Og|JYt=:::442$EY+(05&¿ŮF+,+&%# ROQSSTQPRQRQRRRQRQRRROVRQRPPRRTSQSRRRPRTTTTUTSSXTUUSWWWVWWXY[Z^]]]]^]__^``bcbbbbcefffjhbljmllkklmmorpruqtrwssttuytyxy|xz~{z}~}~}||~xyvuutqppnijijhdcbad_\]][Y[XUWQPNNNNLIMGDCCB@@?>>?=;9<9889766554444222111000/0///.-.*,+/*,/,,.,+/*,+*))()(+)*(-(++++,++)+-,----02456872 -020/*+,')($&NyyF]q9997531A'#n]˓+,,)%$! NRRPQRPPPRPQPRNPPQQQPQRQRROOTTSSTRORORQQRNTQQWPVTUVVUWUWYWXXW[[[[[\\\]^^_`e^aabbbfdehcbghghhmkkjkmnmpmnonrroqqtsssuwwvuwzzz}~z}|}}}}{}{xvuutqqrlnnigfgcdb``^]\Z[XXVTTRONLLLMKEEDCBA@@?>==<;;98;9767545543142212/1100/.-0.,,.,-.++-,-,++***(***()+))))*,)+)+*++)+,,++,.0136886&Hu,110,**)*&%#-M|eDiY0:9743-13-#_j'-+)%! MRQRSPQPPOPPUOOOSSPOSOPPRQRSPQOTORSPSQPPURSSPOWSWTUWVVUUTYTVW\YZZZ\Z\[\[]^^`^b``a`bcefieeegjiiijjkllkonnlkmnprporqpvtrtsxyzyzyx|{{{~~||{zxwuwwtoponnkjlgecbaa`_^]^YYYVURQPONNMKIHJEDEC@??>=?<;::::8877756574151312/11000//00..,....,,+,-,+/,*+-**)**)**+*+)*),,,)+++,--..0/254753C.02/*+((&%%"F\yJFvA865562!O}u1$:=½¦@%*(&% OOOQOQQQQPPPQMPNOPOONPNOPSROTPQSQRPRPRQRPQPPQPQTOSWSTSTUUZTTWW\ZX[[[ZZY]\_^_`_`b__aba_dcccddefgfkfjkijkljkkkmkqmjtrrprssvuwxsww{|zyxy{~}|yzxvsrspoponnkniggbdab__^]\[\WWUSSQNSPNNKFGEEBCBA@??<<:;::99887865554422120012/.1///-3/-,-..,,,.*,,+,+*)+)+))*)++*)))(,***,+++*,,-.0022455/%"$0/.0*('%%%'%DclCWn6;>6313${C.iOLJ/*+'$!!MNOPOPORQPPPQOOPQMQOOOOPRQNRNOPNOPPPQNPONOROPMSPQRTQSQQVVWUUXWYWYZ]XYZ[ZZ[\]]^Y`^^`_```cabbdedcefhegkhjghiiikkiklkmnorrprrqprsvuyxxvwx{}|}{|}~~}|{zzxuwqmomomnkjiiddcaa_^^][ZZXXUSSSNOMNNMIGIHFBAAA@A=<<<;;9998:67656443011321///0//.//,-.-1,.,,.,)+,)+),*++++*()))))())))),+*+**+,,,,023344&2|--.-*(((%$$ .NgbDcc38643201)-cc#,*'## OQOOOPPQPTOOOMMPLNPNQPQOMLSMNPQOOPOONNOOQSONRQQPQQPQPTRTQSSTVVWUYYVZYZY[ZYZ^]\^\^]`]]_^ab`acabccffffhdffgegiiimjihnklmoonppppqwtuutwwvwz|yz{z}}~~}{{yyxuttoonplmlmhgidbac___^]\\ZYVWURRQROOOLJHEDDBBA@@@?<=;<;9:99897755533222130112/0../../0--*+,.,+,++*+)))())+)'())(+(()))*)()-**+,+*,-122463oA'+++'%$$$$#CUiNCjR7:4523'Uw^-&D8$ĵK#(*&#!NMOOQKQPPPNONLMMKMMNNLMQOMMNLNONRQNLNMMNLMMNPNOQSRQPNNQTSQSSWTUWVWVWVWYX\W][ZZ[Z]^`^^__^_``abbabadhfbeheidfhgfhegkhhjinlllqoooptssutuvuzvvxyy}{y}}}~||{|}|yy|xwtsqpnmmlojhigl`faa_a`\`[\XUWUWVVPOPPKPKHFEFDB>BA@?><:?<;;9977965563323423310//1-.//..,-.++*+..*)***+,++)))*)((),(())))))()*))++*+-+.00222/ؕ"*+)'$%%$##"IThDBl>35432/[=.!kƌ KĒ%')(&# QRQOOOOPONTNPNMLOOONPOPNNMMMMKLNOMMPMMLMLMMNLSMPRPPPONPRRQTPVTUUTVVUUVWZVWXXZ[[\X_]]b[`_\^__`b_``dccbabccbe`degihgehggkknmmonmopsqqrrrruvvvwuvyxyz{yz{}~~z{yzyz|vxwvtqqpmllkkkhhgeddb``_^`^\\ZYXXTWROONNMKJIGJFEABBAAA>>><<;<987867554656433210110//-..--.*,,,-)+++/-++-+**))))(*((())*(((**+)()())*)*+././/401(u))*('&$$$#""#?`_?Qf647312*+?u3-j i%))'$ LNMNNTQOOLOPQNNMMNOMLMNNLMNMMLKMNLMLMMOLKMLJOMNNRRPQOMPOQURTRPTTTUVSRUTSVVXWXWX[[Y[\]\\]]^^^a__c`b`caea`bbad`aedeegfgkflijlokmjnnoooporqstsstsvxwyyxy{~}~|||{||{yyywvwxtrsoomlljjjhjgfcdcb]___`]\Z[VXSTRTPPMMLLKJGGEEFAA@>=>@;;;;;897666654323222210.10//---,,,/,,,,,,.+*,++(,*))+))*)*))((+((+*('*)*+***)+,.-0/310YʷF%((('%$##!!!(?aQ>aU47540/*TnN+'*>)=()'&" RQOOONPMOMKNPMNONNMNOMMMLLMMLLQKNLLNLOQLLLKIMLPPKOOSOPOOTRRTRTRRSVTUVSUVVWWVVVXWWYYYZ[Z[\[]^\[[^``b``_^b`ab^c__`bbcdafifhjgkkjplmmmmqmlpprpportzzwwwzwz}|{}z|{~~~~~|{}{yy{{vyvuuqrpqslllkjiiihgfdcea_`__^\^_[YZTSQOPRMPLLKLJIGEDDC@AC?@=<<;988877675353622221200/.//.,+,--,,+,*-+,++,,,,+*)))*'+())(()))(())')),'*+)+)+,2-/11-̿)#''(*$!#""!! +EcL;hG27532.+50.mĠM/,)&#$NQONNPNPNNLKOMMMMNPONMLMKNKLKKJIIJNOMKNJKKNJKLJPJLMOONQNOQRQQTTRTRRRRSQRVXUUTVWVWWXXX[WZZ[Z^\^]^__`__^__\``^]^``baebccdgefegigkiljkkklmllpoqntqrxuvutuwwwyy{yzz|}}}~{{z~zz{zywxvtuttsrqpqpnonkmiiihfeeb`_`_``^]\]YXXUVQPPNLMKMIMKHFFDEFA@>?<>::9:::865765456332222110/01-,,+0+*,,,-++*-++**,)))((*)()(()()())'''(())('+(+*)++,,.00."GƿI$%%$""#  #3[_=@9<:::9776555533243321220/0/..--.,,,+,,+,+++**)*)*(()))))()*&+(*'(&('(()(()()*)(++*0+1.,~ú"#%#"!!! $?_S7[\052.-/++,VZ)(&%%!LKKLMMOOPKLJLLLKLMJPJNLLLKJIJKHHJIIJLHILIIKLIJMKLJKJLMKJKLNMNPONNNRPQOQNNQPTTTRTTUUWUVWWXYXXXYXZ\Z[[YXWZY\Y[ZZY`[\]\__]_cababbaedgfifjeggggiiikmlonnoopqsrrvzwuwtuvwvww|ywxuz|{|~~{{{||x{{{yz}yxuvzxwwvuutwwwusstsroonnmmmlolihkhhhecccaba]^^_]_Z]ZZVXTTSSPMMLMLKKIHGEDGDBAAA?>=><:9::8:75457262522222100/1..-../--/+,--****++*)))()()(((((*''(')(((%'()(()(()*(*)+,---($l """"!!!! 'H_B8j=172-,*'Sj$-e\",%#" QNKLLMKKJMKKOLLKKKNKLKNMKIIJIHHIHIIKGHJHHKIGJLILKJIPNKKMKMOMLOLLORQPOQPPQPPTSTUSVUVRSUTVXVWWWXYWYYXZWYWVVVYXY[]Y[[[]\\\]^`_a`bbbcbbcebbdgjhhhgkjkjnmmmnnomqoqsrssstututzxxwvvwwz{|wuvxxyxwuw{uzttsruutusrrrrrrqqqpnomlokokiiifgigdccad^`__a]Z\]Y\ZYWWSRRPQNNKOJIKKIGFCDBCAAA=A==<;:9:999754547231221210.20../0,-+,.+++,*)*,+,++)+)))(*'()(('('''('''%&'')(((((())**+..(#9;"!""!!! ! "+][=D_423/+(4/,/,:"($%! LMOKLJIIMKMINJMMKLKONIJLLLKIIHIIHMGJHMGFHHIHHJLFJLNKJJMJKNMNLMMMLNMMPNRQSROPSSSTPSQNSUTUY\VTXXY[YWVVUVYURXVXWVWYXZ[Z\[]Y\[]^a_b`ae`b`fcdcfghfjihgkjlkjikmmonoqpurtqpqprrsrwustuuxvvuuxtutssvuyutrrqrrtptqrqonoopqomlkklkkjjjefbhfcc`d^_^^]]\[[[ZYXWVSRQRROLMKKJKGJGFFEEDBBA??==;;::99877654465422211/000///1*+/,,--,-,,****+*+)*)*)'*'()((('''''(()&''')*'()()(*))*+/',n%!"!  !JZS-TD82++'!L*.R ^('## MLLKLKJMMKKJKKMNMIHGIJHIIIIHKFHHHHKIEFEEFKEGGIHFEHHJJIIHLNLNLLKLMMKLKMOONQMJMLOMSNQQTRRRQRQRSRUXYSUSRQRTRSUSUVUUVUVWYZYWXWY[\\\\]_`_]__b`^__`abcddddeedhhikliokkklllmnnnnomnqosmqorpsprpqpqoqrronpmnopmlrpmmllnjkiigggiibfebbbaaa``^^^\Z\ZYXWXWTUTSVQPOPNMLLKLKIHFEDDCBA@@?A<;;;;987:87674344323102.10/./-0/,..-.,-,+++*+,+*(+(+))()'())+'((''''('(''%''('&'()))*()***%2F %EL*!$-2)'&,$0$=%&$#!JNLKOLOJMHKJJJILIIGJHGIEHHHIGEFGFHGFFEEFHHGGGHIGKKHHGGGKKILLLKNLKMLJKMKNLNLLORLNNPONPQQPPRQPTQSXQURQUPOQTSSRTTTUXWTUVU[VZZXZY[\[\^_^a^^\__^_\__ddcccdcefdhifgijjkikljnmlmmmplmlpllpmmqnqonmmlpnnmlkkmmkkkjkmjkkhflfhfcecedacba`a^`^\\\\ZZXWVUUUWWVSQPNPPNOLKKLIHJDFGCBA@?=>=A;<::987875554523312/02100/0-.--.0,,,+*-,**,*,*))(()))(((((('')'(%&%%((''$'('((&(&((*))++)h'&+TT'"!%&*+' %.!MQ'%&#"LLMOLKKKJIJKKKKKLJHIIIGMJHHIFEFFFGHGFDDFGGFGFHEJIGGCGEHHILHHIKKMKILMJKLMRKLLLKKMNNPOOOPONQQQSXSRSUNNQNRPQQRRTRUWPVSSSTVSYWWVW\YYYX]]^]\^\\Z[]^__c`acbacccedgefgkhkiihkklilkjkkllijlknkllnkkjjiklkihkgikihgihkihggeiddddbcdba``_^]_[`ZZZZYZWUUTTTUSOOONOONQJJKJJEFDIBCCAA@>==><<:9:9775554434221121/22.0-...-,,-.-++,++++,++((()(((()'('+'(('%('''''&#(&'''''()(((((+)'e*5WN49+$(&%$ 8*-UZ'%" LJMIKJIJJKIILJHJIJLJHHHHFFHILDFEGFEFDLEGEEIHFFEKDEGDEFFIIEHFHIHIKJKLKJKLNMONMMONMLOOOONNMPQPQPPTSPOPQNNOQPPPRTQSUSRRRROUTWVTZUXXZX[[\\[Z\[[\[\_^]__^a_c_d^abeecddgfefggiihiiijjihhiijhkiikiiihiihghgfhjigeeecegeddeebaa`a`_]a_]^\[[ZXZYXUVUTSUSQRQNNNPMKNHIIGGFFEEDDABA@?>====;:9:87666544422121021/.0-..---.,,+,++++++*++)(((('((')'('&'('''''&''&&)&((''&'((()''*+)$)F.1UI:G8"'%$# ۡ+%&4@%! FHJLKILMIMLMJINIJLJJIHHGHLEDEIDEFFFGKJFGDEFEEFEEEIAFCJFGHGGFGHJMIILLNLKIJLQLKKJNNPLNOMNMMNMSPRQPPNOMLPOPONPLSPQPPPRQSQTQTSTUTVWVUV]X[ZZ]XYXYZ\]\\[`__^_a^_^b`ccdecdehefegfhejeghjeeihggfffhhdffffedifegeedbdcbddbbabac^_^]]\]]\]\YWXVYXWWUTSRRRRPRNONLMLJHHHEFFFDCCA@@>??>?==:;:99=4756646322210/111/..//...+*++,,+++++***))))))(((()(()(''%%')&&'''%('('&''(('&('()+Up#(3YSAL3$%$#"9U*(%>J($$!HGILHNIGJJJKJIIIIIHHIFGFEEGD?BEFFFEECEKCFCDDHGEDFDHGDDFGGFFEHIHIHGIHILKHLLJKMJNNJKKLINKLKMNNPONOONMLLKKJMLLJLPNNPROQOPRSRRSWTUUUWWWWXXXWXW[ZZXXXYZ\[][]]^`^baaaaab`dabaeabfgfehffgfffeefedjggeedee`cca``cdaa_b_``c`b]^^]c\[_YZY[WWVXTRTTXRUQSRQRQNMPLNLJIGEIGHCFBDB@@?==>><;;;::8858555765242202001//.//-/--,-++,,++*.++*)))))'*))')''()&'%''&'')('%'&'''&%'('''(((')~W/2bYKR.%&!!*9E/*)tZ}i#$!HHIINHJMKNJKJJJLLHHGGGHFEDECFEDFBCDFGEDCFBDDDDGHGEHCDEHEHFEIFHGHJIIKIEKHJJJJKMLNHLIKMNFJNLMMNNLMLLMMMKJKJKLJNJNNMMOONORORQTPUSSURUWUYWVWUXWVVWXVWZWW]^\[\[]]^_^`c_ca_b`^``aadbedc`fecccgcdacbddbaecbb`b`_`_`^^^_`]][c__]WZ[WWWYXWVUVSTWVQRNSPQOOQNLLLJMHKHEICEEDCBB??<=<=?;:9:887867654661221100//////.-0,,-,,,,-+*,+,**)+()(((((('&)'&'''%&'%'%%'&%'''''''%'&&'(((("'o=*+IaZLV,(&#"3<3-*!."6!$%#HJMLMFIKJLJHHGJJGDKIGGEFEDDCDEHCFGDCBACIBCCCHEHADCEDEEGECIDFFIFGFHIIEIGHKLMHIKLKHMKJKMJNILLMMKKLLJLHJGILIIHLLLKNKQMMQNNPPSPTPSPQSSTVUTUTTSUUUTUTWYWWYYXZ\Z[[]\a^]]`^]__a[a__``_`a_bbcbbcc`abbc`cba_`b]^]^`^^W^[a[\\[ZY\\ZXWUVVYUTUSTXSPOPQRLNNQLMLMIIIJIGEJDDGEEBB??>>=>=;::8:877875445643221/00///,0+-...,)),*+,).**))*)))(('+)((')''''&''(&$'&''&%'''%%&&&%'&'((((Lc'1-K]VPV))%% ";:/,) 8O#$#FHHGJLIIJJJHGGGEEEFGIDEFGDDFDEEBBFDDEDBBCBBACCCAGDDCDEEDEGFEEDEFIHLIHEGGFIGIHJIGLGKJJIIJJOLNMLKJJJJKGJIIJJMHHKIHKOLLKNKPPNNTPPPRQTSTRTSSSTSRSTUUTVVXUW\YXYXZ\^Z\[^\^\]]^`^]\]`\\]]_a^b``___`_`_`]]]_\^^]\[\[]ZZ]\Y[ZZYYYXWWVUWQSRSQRQPNOOPNLLLLLLKIIJIIGFFEEDDDD@@A?>=>:;;999:8686755623422001100,//.--,,,+++*,,,*-+(*+)))((((*((&((''('%%%&&'&%&(&'&''&%%%&%'$'')''rzO//M_PLU(&%#1B42-"uW +x[ !JIJHJIJIJIJHEHFDGEFHDDEEEEEFDEDCCDDDCCCDCCBDBDACCDBCDDECFFGDFFEFEGFEFEFHEHKDIGIJGIIMIJMJJJMLKJKJIGHHGEHGKKIJJNKKKKKLKLLPLPNOPNNQPOPSSTRTQRPPQQSSWTTRVVXYYVWYYZZYY[[[[Z[[Z^\\\[[]^[^^^]a___^]^^_]]\\\]Z\\[[[Y[ZZYYYWYZYWUWVTUUSPRQQPQOPNNNNLKKJKKJIIIGGFEECFECCB@@?>>=<;<<:88;:7976654244311000/0/0./0-/+++,+*+,,+,*+()')),)()((('($'('&%%&%''&&$&&$%%&$&$%%#%%'''('$)q@,AM_IPQ&'#!$;B.*()*9 % FHILGHIKJHEGGECEGGGEDEEEEGBGGCECEAGEB@CDF@@EABBHBCCBCCBGEEDDBDEEECEDFDEIGIBMFEJIIIJIIHMJJJIMKJIGGHKGHKFFHHHIIKGIIIJHJMKKQMOMNPSKSOQSPRQRQRPPPPOQRRQQQXSUTTVUV]ZXYX^YW\XYZZZ[Z[[\ZZZ[\[[[]\\\Z[\\[[YX[ZXX[YZYVWWWWWUWVVXWTVWVQRTPPQRPNJMNMPKJHMJHHHGFGGIFCCDDCB@??>@==?:;:9<776:65554443322212/0100/..0--,++++++**+,-**))())*)))'''&'(''&&%&%'%%$%%%%%''%'#&%%%&(('$"L`%(,>P]DX8%""6F5+(%'U|(! HIFHGHLIFDKFEEDGDHFGGCGEEEDDCBCCDGB@BCDDAA@BBDACDBDCCECDFEBCDCFDCCDDEFFEFEGDGGFFGHGJFIIGLKLILIGEFGJEGDGGFGGGJGJHHIGHHJKJKMLLMMMKPLNPPQOPOQPOPRONNOPNTQRSSUSWUWXWWXXXXXWWXYY\XZXXYWYXY\X]ZZ\XZXZ\ZYYZXWVXXWXTUUVVXWTSTTRQQQQRMMOPNNNMLOLLKKIJFGHHHGGGFDCCBDBABC>?>>>=<<;:989846755643532111120//000.../..+-.*++*+,++)**)*()(((((''&'&%&'&%%&$&'%&%%%%%%%%%%%%&&'$(&%ezy@,.@\RKV)$"DE.*%"XMY! !GIIGHGHJHIFFEGEFEGGFECDCDEDCCCBEA@CBC@AAC@AABBBABBCCBBBB@CFBDEBDDCCEDEEGFGFFDFFGFHGFFFIJKJIGHFFFEHHGHFGFHEIFGGGFGFIHEHJKJJJKLNLKILMNOOMNMLONNLNOMNNOQSQPTPVOUVUUXWXWVVVWVWXXWXWWWVVWXXYZWZWW[ZXXVXXTVVZVVTZVTRTSRRQSRPOOROONNMKLMLLLLLLKIIHHHGFIHFFEDBBDAA@B?>@><>;<<;;9:697795544534311111101000/.-./,..-,++*+,+**+(*((*)''(''('('''%'&'%'%%$%%%&$%$$$$$$&$'('%&%#$rqa50.F_IPR&$"+E8+)%!-: IIJGHFIJHHHGEDEFGEEGDABCEACCAEBBBCBA@@@D?CDDCCBBFDCADCH@EACEEDABCABCGEEDE@IEECGDJHGEEDLGGNGEFEIFDEHFDEGFCCEIGFHDFFJHGHGGGHIJKIKJKLMNNJNLLMLLNNLLLLNNPPMQPQPVSSRTWVWTYTUUVUVUY]VUUUUUVWX[VWWWWZVVUSSTTVVTVQPWRPPRRORSPPOPLNONMNJJJLKKJIKJIILFFGHFFEDCCBBD@A@B=>=<<;;<::9988879463633443210100000///+,.,0,,,.*,*+,)*+,)())()&(((%'&'%''''&#$'%%%%"'$&#$&#$%%!'$(''%$:xjM%(7PZIRI'$!CBA@AAA@C@@BA@AA@D?A@@ABACC@ADCBBBBBDDCDDHECEDEFHEFEEFGLEGGEDEECFCHAEEBFEEGBFEGFEFEEEEFFFFGIJIJIJJLKNKLHKIIMKLLJKLLOMKNOOONOOPPQQTSUWVSSRSQRSSUZTTUTTTVVTTTSUWSSUSRRSSUSUPQPSSPPQONRNNONOMNNMNMJJHJIIIHGIJGEFFEEFFEFBBB?A@@?=@=<;?;;:;79988775436463231311/001///./+/,-.,+,++*+,+++)(**)()('($('$(''$(''&&%%%%''%$$&$%$%#$$$%%%%%#%^mZE'):TSIT8'#!CC.&%#HI }[!LEGKHHHIGFGHDDCEFDFCDB@BCD?BCDECA@ABAB@B@A?B???B@A??ACBB@?BDCBBBAABCBCAECFBCEDDEHDFEDDBIFGDEBCBBD@CACDDDGDCDFEDEDDCHDFHDGFILGHILHKMKJLJGKHIKJJLKJLKLKLLNORPNNPOTQQSRQPPQPRPQRQQQQORTTQUSSSVUQSOTQQOOQPPOOMOONOPRNOPNKKMHKKKJILLLHHHGIGHFHEEDDDFCCBABA@?>@?=@>=<;;;:9797888754344312231010///00-.----.,++0+-***,+*+*)*(((('&'('&'''&&%%&%&'%#&%&#$$%%$%%'#%$$$$#%' #igS++*<]HGR.'#.@9'%$ x)"1FKHHFKJJGIFHGACCFECBHCACCAHAABECEBAA?BB@@B?>?@@A?@>@B@A@@@@BABCABE=DABCCBFDCCEGDDDGFEEEDDECF@DCB>>>===<;;;:987777875434252222/00/0///....+/.,,+,+*++)))-))'))))(('('&''($%&'%''%%&$(#$%#&$&$$#%%$$$$$%"'$!0dYO(0CYFDR('!9=,($#qP~!GGHIFGFFFIIHFEACDDEECBBCDDBCA@ECCAC@ABABA@?BBA@ADAA@@ABBD@@CBAACCCEDBCCDDECHBFCDCBBAAA?FBACABCBABC@CCECCCCEDHDDFDFEFDICEGJIJKKGHGKGHGGKIIHKJJIJNLOMJOKNMMMLNLOOMOOONMRNHPNNOOOOONMPOPNOQNLLNMNMKOLKMLLJIHJIILIKJGHEIGEFHHDDDEFCCCGBBBDAA@@>A>??>A===;:::;898766755644434211010//0//-0.,--+,+*+.+++*)+*))*(()(('*''%''&&&&%$%&&&%%%$$#&$$&$$$$%%%$$$%$$%# E[]4%&=O[AIC#$":5&%#!MI +N FGHIDFEEHFEDFEBACBDCFBBB@AAB@@?BFA@BBABBB@?>>?A?BA=?AAA@??@@@??AB?A@AAACCCBBEFCDAACDDDFDBBADCA@BCBAABB@ACBBCBDCFAECBDAFDCDDEDDCEFDHHHIFIFHFFGEHJHGGJHHHIIIIIIKNKLKKPNMLLMNKJPMLQKNMLMOLPNOOPMLLLNOIJLLNLLKJMIJMJFGGGKIKGHJIKEHHFEGCDCCCDBBCCCBBA@A?>??>?><<<;<::98877775477355332200010/0/0.--...--,,*+))*)))())'(&&''''''&(&'&&%&%'&&&&%%#$%#%%%%$#$$$&#$$'&%$##$ZVJ0',9WL@S=##,;($!!!q"):EHDDEGEFFDEDEFDBB@BBDBABE>@@?@@@BCAB>?B@@@?A>?@>=>B=@A@@@?@A?@@@@@A@A@CAD@ABDBBA?@AEBFADBCAAA@BD>@EABBBC>@AABBDDDCBBFCCCCDCDBCFDCIFEGFDFDEEEEEEEGHHGFEGHGKHHIJIKJIKKNJKKLKILMLLNLLJOKKLKKMLLMMLLLLKKLNJHIJIFLKJMGHGFCJFIECIFFCGFGDDCCBBDEECDCA@????@@?==<<;;;99988988685563542340/1/01//00/./---..-,)**++*)))*))+*)('%)('''&''&%&$%%%'&$&$%%$$%#%%$"$$%$$%%$#'##!,YP? +47YFBT3% 3>,$!!uVnDFGGEGCHHEBCGFBC?ABBBBBFA@B?A@@??BBB?>A>A??>>@@>?=B>A@??=?AF?@B@?@@>C@AACAAAABCAADECCDACDA@?@@@BCC>@A@?AB@?DBC@CA?BB@ADD@CBCDEFDDHEEECFEEDCEDEDCFGEFCHEEFEIFHFIHGGGKIJKJHKJKINLKJIJIKLKIJNKMJIMMJKJJJKIKHGHIHGGEGEEFHHDFCEDEFEDDDECBBBABBBA@@C???>>?===;;<9;;<:8996685545544322120//21.--0-......0,,,,)(*(+,+)(+)((('(''''$'''('%&&'$%%%$%$$$$$#%%%#%#$$##"###$# =TF/ "9EX@EP*%/X:*$ 4>~ZCEEFHHHDDDDCBEFADACBABB?@@@?>@A@A?@?>@<=?;B=?A@>>=?>>@@>?@=??B>????=@D@@>@A@@A@@@BABA@BC@?????@@AA????@>@C@AAA@BCBBB@@@?DADBBBACCBEBCEBCDCDACDECEDDEEGEEEEEGFEFHFFEEIHIHHJJJIHILHJGHIIGGHIHIJIHJKIIIIJKGHFHFFGFDEECCECCCDECCDBEBCCBA@ABAB@@@?=>==<===;;<:;<9;88677975534345333110./0--/2..,--,.-/)-+++)+*,*+*()*))+'''&'&''&'&$&%&&$%%$$%%$$##$&%$"#$#$##$#####" GM7"-#@KQ@FK'&%V6'#!q!"7DDEGDEEDECCEAFBBBBCBA@AEBA@@@A?>>@@A@??B=@@@@@@>??>@@@??@?D>>??@?=?AC@A@?B>@>C>@@CBA@C;B?A?@B@A@BB>>>>?BA@AACA@A?@AA@@ACAE>@AAACCCBCADCBCBBBAACBCCDCCCEEDDEDIEECEGEDFEFHGGGIHKGIJFFFHHKGJIJJIKHHIHHHJGFFEEGEECEDCCCCBBCAE@@BBCABBBAB@@A@>???>==<<<;;;;::;=::7:866876554334303211../0/1/.,,,.-+++---,+*)))),*))()())((((()''$&('&$'%%%%$$"&$##$$$$$"$$#%$$$$"#$#!%MF:-(ARK>K9'#&M4'!"e WfECCCCCDDCDBAECCDBAEB@@@>@@B>B?A><>?=>@@?>=>?@>>>>?>>?B==B?A@=A>@<@@?A????=C>????A>C@?@???>@@>=@@@@A?@@@>A@@@?@=?@@?@A??@??@?@AABA@B@BAB@@AAAAAADABCCDDECDDCDBEGDECHFEEEFIGGFEEGGGEHFEGFHGIHHHJHGHHGHFEEDDFDBECDCCCB@CBAA@@A@AAD@BCC?@@?>>A=>?=><;;;;9<9879:8776886645331223412210...//,-,,,-+-+)+,,,+*)))))*())((+(((('(''''($'%%%$%$$$$$#$##$$$$#""$"#$$#!#"$"6HA.!-0?Q?>P0%!8K1'!#.@xS#FDECDCCCEDCECCD?AA@AA@B?@B@C=?;@A=><@>>>@==?>=?>?>><@>;>;=>?=>?>A>A?>>>@>>=B?C>@BB?BA@>>>=>?AB>=?>?@@ADA?@@>@?@A@?DBDCAA?A@@@A@AB?CBDBAADCECCCBBCBECFDDCEGEFEDEEFCEDFFEFFDFFFHHGEFEEFEDFCDCDCCBCACCB@A@@?A@??=??A@???A??===><=:::;;;;;9988:68876756533221222222//.1....0+,,,,-.-,*+)*(*)+***)((()(')('(&&'&&%%$%%%%'%$$$$$$###$$$#$"#####!"!$#$ CC@)((9HNA@@B>@?>>B?>=<>>>=>>==<<=A>@>B=@<<=<=<>>A?>><=>B?>>?>>@@@>A;B?>>=;=;@>=@?>?@=B>==C?=>=>>>>?<>B?@@=A@>?@?@@CBCA?@>@?@A?@@@A>>=>>>==>@=====>A=<>;:;::<:;:;999758685556554221120500021///..0.,,,-+-,++++*+++)')(')*(((((('&''%''&$%&%%%%%#$$$$%#"$#$%$!$#"##"$"! $#%*@C(+&6JO>>=?====>>???=<=>==?=>><;;?=;<>;>;=@>>>??@>@A?=>>>?>>>>A;?=>>;:<>=>=?==<==>?>>=>>><=?C?A>@A>>???>>>@@B?@>?>>?>A>@>@B?B@ABBA@@AAA@AA?B@BA@BAADABBGBCDDDBBBACBAECDCCDAAD@AA?@@CBA?>??@?>@@=@=>==<;<<<=;<<><<::9:9:8::::88;887557345452341211110000....///./*,++++**+,++)*+)((((((((('''%%'('&%%%$$%%$#%$$$$$$$$$"%#"$"$#"""!!!#"" 3@A&)+9SD=LA DK:'!2};JBEEFBBECDBAADAACAA?@@A>>@=>===;@==?<<<=><;:;;<<<==;=<<<=>=><@?;=>>>>>;<=>=>>>????=;<;;=>>@=<=<=<<:<<<===?@?>=?>?A>?@A??@?>><>=??@@@@?=@?@?@?@?@@?@@AAAAAAAABBAC@BACBDAAEBAB@A@@?@?@B?>@?>>=<@?>=>==>=>::;;;;<;<=;;:9;;7:8887776776556434433222310011.0/0.2-//0.,-+++,,**+*,+)*+))((('((''''&%%%'&&%%%&$%%&$%$$'$#"$###$"""##""#"!!!"""!!;?7)+'57P:>N5!II: Zv(/FCDCECGBCCCBA@@@AA?@@??>>@@?>>>>?>>>A?>;;=?==A@<::<9@<<=<<<;<;=<==;==<;=>=><=>=><=??>=@:<<;;>@;:<>??;;<;;;;<>@;<;B=>=AAC>=>=??==<==>>>>===>?<<>>=E<>=B=?=@@A??>@?>??>?=?>=ABCA@@B@A@@@@AAAC@A@B?@AA@??@?>=>=>>>==<>;<==<;?==;;::;;;::;:::99:9<88786;6796555544552221023/01/01.1-.0/1*,,,+,++*/+++)+**(*)(('')(''''&%%%((&%$%&%$$&$%$%##&##%$$#!!%#""#!"" ""!!!$??2+#;HF>?@=>A?@>>>>>>??=>;;<<;==;;==>;;<<=;;::?;:;===;=<=<;=>?>?==<><=<>=>=<;<;;<;><<<<;;;=><<<=>=?>?>=><=<>;<=?:A=?:>;?=>?<>:<<==<<>==>==?==>>=>@@?====>?@@??=??@=@@ABA@B>A??A?@??A>=>><<>=<==:;<<;;<<:::9;89:99989;89::98:98566567575335462221101100/00/0.-/.0,,,,++,-,+**+-+))(,*)((('())(''&'%%&%'&$%&%%&"%$##&$$$$###$#"#"!#!$!!" """! -:9*4&9JBBA@>@?@><<=;?==>>><@=;;;;@==;:::>=;><<<:;;::;=;<;:<<><<<===?:<;<<>=;;<;;;<<:;<;===<<<=;<;;=<;=?@:==<=<<<:<<;==<:<<==;==;;<==?;<=<;<>==<;:=?:<<>???<;<<=>>?>@@@?>>AA?=>@?@?>?A@@>?>===;<;<;;=<<<;;;;;9;899888899896977979799677576554433441132202111/2/1,0./../.,,,*-,++++-)*,))+*(*('(())&)'&(%&$%%&%($$&&$%$$""#"$%$""$$$$!"## #""!""!"! 265&+48I?=L;!?B0 $?z2'CBDGBGBDAA@B=@ACBB<>??@>;<=>?>@<=@9=<;;:;<<<<;<<;<<<;;;99;:<=<<;;====<:;;;<8;=<=>;;:=:::?;;<<;<<;;:>;;<;;===;=:<<;<<<;;<9>;<998<:;;;=<<=;<;=>;<<===C;<===;===>??>>@A=>=;>>B@@@==?>:?<;;::;;::;:;;;998997887888898678677866687765346554444322121021101001./+.,,..-,,,.+,++,**+*'+*+*)((('(')'&&'''&%'$'%$&$($$###"$""%#%!##"#"!#"!!#"#!!!"" 55+% 8AC=AP0"E:&'$o\aeCDCEBDGB@A@??@@=@==??>=A;?==>===:<<;;=;;;>;;;<<;;:9;::>:;;<<<;<=;;<<@9;;;=::>;:;::;;<=;:;;:8::;;=;<<;=::::@;;::;=?:9;;=:<;:;=<;:;><;;::::<<;;;9:;<88:;<;>:<:9<<<<<===<;:<;;=;<<=<>=?>>>=@=<;<=?;=;;<;;;:;::<::<99;;9<999788:78887566668765765755854254433232011330210/.//./0..,,..+,,,,++*****)())(+(('*''')&'*&'%'('&&&%%$$%%%%#%&$!##"%"##"""$""!!!#$!"!"! &83,'@>@;BN%4A4"+#!q?zKCBABBCADB@>?B@?A?==>>===@=?>>>=<;:;:;9<=;=;:::9=:9=;:;9::;<;<=<;;=<;=9>=<;;;;=::;:::>;;<<;<:;;:<;::<;:9:9><;:9;;::<9::<;;<<;=<:<:<;;8:99:<;:;::89::9;;9;999<=;<:;;<::::<:;:8<;;;;==;<=;<<<;9;<;:=;;:<99:::;9:989898;8779796579778767777645575375643644332223522202/././..,.,..,,-+,+.),,,*(**(())))()(*'''&((%%%%&%$&($&%$$$#$##$$"#%$##!#"""""" $!!!!!"!"! 441%$&TA=9BH#=<- (=>?==><>?;>==<99<>;;;<;<;<<=9;:=:9;:9;::99=<=8<:;;8>::9:9;::999;;::<:>;;<;:;;:::::;;;9998::::89886888887656747676677376736554445675446252533211/204./././-2-/-.+,,-),+,,.++***+*(%)(''))'('('((%%%)%$%'%$%%$&%%%$$"$$""$#$$#""!#&!!"!!!!"#! !#230%QSF:7J? ,@8$*%^a Tg BB@CC@FA>C<@>@=A>@?<@>=@@;<<>=:;;:<;<9;::9;899888;::;<9<:;?;;:::;:::;;;=::<=:::::;>:<8:99998:;:887999;9<;::::99:9=::>;;9:98889897889<898;::9>9799;7;99:878:98:89:989:=9>:;:=:;99::;9<<<:97;;;989767878777:55564565555552264456442454433222331231/0/2//0--.-.+-..--,++-,-+)+*.))))))((()(((()'('''%&&'%'%&%$$$%$%%%%$###$$%$$#""""""# $ !!!"!! '22#HE?:9I->=<;;>:=>::>6<<=:;<;=9=::<<<<;::>;:::;:;988999:9;:;<==;:::=;::::<<8:::99;:::;8;:;8889:8::98<77999989;99:999898987::79:7888897:9:78<:::66777899<989998:9:9949::8889889::997:989898998764:788795776667645553446433434133343343432422432221000/.0///,0../.+-.-.,+,+++,,)**+++))(((()*(((()'('&%'&%$%$&&$#%%$%$%#%$#!#%"#####""$!"$ "!!! #!!! +/-""$FA<:@E'@9)#*Bm8x~w(A?BE=?>A@>A=>?=>>>><=?:=;;<<;;;<<>;::<=<<<;=9:;:;::788:::;;::?5:99:<9:99;:7@8::8<7::::::;9=8998:::9:99:::9:98<9888998:9:;=79:988787:8;55:87:;9:86777787689;899888678576889999;9:;3898899:58777685867777758766566555445343433443123321222222221213000/0/..00+-..-0..+,-,+++,,)*)+(+)))*(((*')')&'(('''%&&%%%&$&%%%%$%$$$#%"""##!"""""!!#""#"! !!!!! .+&#.7@;;BA+@-!'(QW]Z?@AABAC@=?>@>=?>?>A<=<;<<<:<=;;;<=<:::::<<;7;;;;99:99;:999::87;:;9:::9987:99:899:;99;;98;8998:78:9:8898>8:889998:7898786978798:887878875668777777777:677676777798:678896;77887778777:89646788866697477667657477658555435534432633543333431221321231222//0/.//.0.0+/,,,.-.-+,++*++++++(*)****)+'(()((((&''%(('%%%&%&&%%%$%&%$###$#"""##"!"!!"!!""##! ! !/,"!36@6:C877*+%a= n|>AB@BBCCA@??A=>=?=>==;=<<=<<<;=::;=;;9;:<:88;:998999:999:;9:9;:::9=88978887999:798::9<9:98;;8989:8999898;::89::8:88::697888:99899979:66;777774779777899;5678966677557768868888869876878959678776858796666556466573545564444443324321221312210121110012000.//./.0/./-0+-.--+/*++*++,**)(**)*+*)((())(('('(((&''&&$$&$'%%$$$"%$%#"###""###!"##"!!!!$" "! ! (,% '"0>>8:F2B3$')/i0t}z!A@@AACCD=@?A=A@;=?<<====<;;;:;::;<:;9:=:;9889@99=<:8:9888888::9::7<788888888887887:89;9;;7:88899887:888:::766:9678:57877:9:6898687:4649567766666657766566477625766954667878666667767865757767656566766556555545443375343333332301/122/522101121213/0110/.-,..//,..0,,,,,,,*,)*+,++**+)(++()*)(())(()('('&'*&%%&&%&%%%#$$$#$$$"$$"%#"###"#"""!!#!!!! ! -+( ''-A:4BF%/=,*&HNd{uxXB?@D=?@A=>>A?=;==A>==;;@;<9;;<;<:;::::9;9:;:989::98879=97:999=89878888:88996:78;89979:9978::99977:8;:978:789779798668688;88:7775577778566677886657676655665555456676634765476585:766745566377365454665456254244341414343143021/1/201100213//00/1/./121...-.//.------,,.,,,+++*,,+++++)*))((*(((()(''('(('''&%%%$$#%%#&###"$##$$$#$##"##""!"!""!!#! !!# ,*' &+/B75D@97("+!c;`yxp}D@A??>>@?A;>??====:=>=>;;=:;<:;=;::;::;9:789899:;;987778:988987787;889;89987657888798:8689668878888:9:9:696878858787777877898766565778555476656665546555665535456653455624544357453755784456246443334464344253343431242324124/03///102/111/////0...-/-/..-/.,/-,,*/*,,*-*-++++,**,+**'**)()(((*()&('(%'&'((('%&$$$%#$$#$##$#$#"#"$#""!"""!!""! !! !   %+#%#*5?75C5 =2')&cbxxxz&AA@@>>>??>>>>=?=;;?=>=9<<<<:><;;:99::9:989889<78::77878;:87<89878:989:98776677;77:899887789767797:89779667749888787778756777665757369587486555556566666653476556555545554425446824625466676931635464424334513332516112213224110////01/.010.0./2-/..//0/-.,0,*--,+,.+,,++*+,*+,)++,+*)*))+(&()((''('&)&''&)%%''%%&#%$$%$%$$#!#$#"!$""!"""""!!"""!!" !$(' "-8;3;E*1>' -(A]:vtwvYAB@@A=>>>;@?;;;@:9<;<;<:;<;::::::99::88988989;9888:;97:9776:;8988987977667::88;97:877657:878877797768757787565556388566757656835546356555554455557643633454555557342454533333434536554434327223222324130142212131122032100///./0110//,.-///..../,,-..),,+/-,++,++)))+*,+)))*+))))()''('*()((((&%%%''$%%&&&%$%$$%#&$%###!$""""#!"""""!"!""$!!!!!  ! %%""*-E83=F;3!$-!Y? Zsx{~4B>@?>=>>?<>=<=>:=::<;;;::;;::99;7899899:8868898889989698776;:87667777686658:988969869858:867777667878876777666685445565567652656574345555655445675574445544444445324652432522332333534323323331222221102201020112001//0/1/.////...//-././-.,..//--,-.++,+-,++*+,*+)*++*))**)))*)*(*'('((''''&'%&''&'%'$%%%$$$$%&$$%###"#$""!#"$!"!!!!!!"!"! ! ! !$$#//E44B;":-**#*X*`os|q!@DA@?=>?C>>@=<=><==;;;::<:<;<<9:;;:9>89:988:999:5989;8879857776:76:87766777757696:88877987767898765796776557769676674556576555576445655353335555454564545543745545363343234524332234322333132345221321260130041201/20112/000/00./000-.../*.-1./../+-.-*,--,,+,,,++)*+***)*+,*)+)))*()))''(((()&'&'''%$%&'&$%$%%%$$%&#&$$$$##"""$""#!"#"!!!!!!#"!!! ! $$ $1:?24D%59'-(2K6msopvS ?CA@?>?>>?A@@<=<=<=;;;;;:;==<>;;;:::><:7979688778:;994<8765:9::68789558887876667777766878876898677867976755677:665765764763566655555855457334544555345254425445444433223344336333333412222223612342112101100121010/001/0300/1/0/0000/.-./../---,0,,,,,0-,,-,,+*-*+++,)(*(+++++)**))()))&*'*)(''&&''&%%&'$'%'%$$$$$$#%$%$$#$%""#$""##"!""!!! !!"! ! !$ "$+>>2:@<8*-!D?Hxvvz{L@AAA@>===?<::<;<;::;:;<:=<;;;:9:76898887698778398779876577677788:7886556879788856778;65677767875667546585865775667445658565545645444548636355434434354644554533443443324433233454351312131221120120100/11110.0000110/0/20/00./1-/,/-.--.--/.+,-+,+-,,,,,+/*+*))*)++)*))(++))(**(((('(()'&(''''&%'%%$&&%%&%'%$$%%$$$$$#$ #"!""$ "#""#!!!! !! !#""""(@55;8)9#,(Uawvs|7@@@@@>======>>=;=>;=:;;;;;:;::;;9:;9<77588988687876758793976677876557787466679776676778776676677777756745466767746555654555255654164544344454487552465324454454422333142144322023435312510113.222220/34/000/./0/////0///.././///0.,-+-,.-/.,/,-+,,+,++,*)+,,,*++*++))),())(+(()()*((()(((('(&$&'''%%&%%$%$%%%%$#$$%$$""$$$#""#$ ""!""$!"!"!"# !  !"! ,+@13A(66%".%/L:oprwt|#@@@@@<=??;=<==<>;<<;<=;;<8;;9:;;:6=:9898688989:97777678867848887677:574697645455677765766767757787867656764857665546346524755663345653564444555555344633355543551121232132242112212222211210/310211100/01///-/////-3/1//..0///.-/,,,,-,,-+0,,,,+.,+,/)-),,++,+-+*++())+(*((()(+(+((*(&)((((''%'&'%'&&'$$$$$%%$$%$%%##"##""!"#!""!!!!"# "!! !!  !   "" +>:29693*-"K4`flstxE  ?>A==>@<><<<<;=9<;;<=;;::?;;997=9;:87988767779;8766767768759777677675565654655767456864667756754685634657566465754446644453454322346455554533455654664233436432223213133132210/13022103021121/01/100/110/..01/...0.-/1..,,,-,.--/0,,,,,,-.+++++*+*+*+,*+**++++*,++*'())))((((('''''(('''''''%%)''%%&'&&$#$&$%"#$&##$#$#!!"!""!!"!!!!!"""!" ! ! !" %&?72;2/8$-&!H acgqtn* +>>?>>>?=><=<=<@;;;;:<;<=:;99<9979:8777;89878:97788566687767778868795547665565775985647757655686656555456757544575566555747336443446536545655326362734324235233232322212102224.1/020/2100112110114/2.00101/00/0.///./..0,,,-./.0-.-0,++*--.-*,**+,,,++***,)***+**+)*()()+(()')'('(''*()(')'''''&''&%&%%%%%%##&$%"%"$$$"#"!!!""!""#!!!% ""!!!!  !" "*,=43=6,!#/$%H Ggcfru[ >>>??>??=<<;<<;>>9::=;;<9<;;=9999985686:78<7777775576777545456676774545565657546767877555666645855354465855434545344545354652765425653355553563532332332326133120311112222010/0051-000000//2210102//./.0////0/-../....--,-.,,,.0+,-+)+++-*,,)*)+++*+,++*+(,*()),*()(()'',())(''''''''''(''''&'%)'(&%'(%$&%$$$$$&##$$""$#"##""!#!!!!!!"!! !   !!  )/:118%6)*+ >0 Kifiou0 + ==???=>>???=<==<;:<9:<:;88:;:;8:968:7777869;8676867775656:459675675743656675558739566685445555445433447444433445445445436666333546504344343163242512233242111222321211011210//0021002/00////10300.1//.././0/..-+/./,-.-,.-++--,-//,,++++*++**++*,*+)+)*)+))()(*('))))))('()((('(&''((''%&'%'&''%$$%%%%$%$$$%$$$#""#$"!!"!#!""" "!"!!!!!     ! #&86/8"/7 /&A!aijjog"  ?>@><@=>AAA@><<=<::::9:::9;::=;:8887888868:7767758776756687455647553484554555667755756455555544656644568245534443454334576563303342333434424022642221112232112121012112/100/00.230./-020../.00-////...//-...0.,0+-++0.---,-,,.-+,,+,++*+++)+*++++)(.*+***+)())())((((((&)(''''')'''&%&('$%%&&'$&%$%%%#$#$$%%$%$##$$#""#"$#!"!!"!!!!!!!     "!%<135=2(. )C1bihhmS C<==>>;AD?>>;;;<9;:89:;:;97:;::;7:8;76676564=8875877797765456856544:66767786653554655635445446457568459544653454352646455635335436342324202222323123224111011120022100/0-0010.01312001000////./+.//..//.0+-,-/,,.,,,.-,,-.-+-*/++,,++,*+,*)+)*****))***)))))))))())((+')(&''&())''%)'(''%'$'$(%%%$$$&###$$$$%$####"###!"!""#!!!! !!! ! !!      **<13/(9&+' 60 +Sicfgk:  A@=?<=<=<>>=;;9<::;98;<<:<::<;::888:777669:5:78796656776657668555744857556656454485454345545458455855553543572444333545574654623143422222430314435122213000/02150/012////0/.00//01/10/110--/,./0....-/,---,,/-/-,,.+,+-,,-,,+*0+++)+(**,*(*)**))***()**))))()*)(()((*(''')'('''''''&'''&&%&'&%&%%%%&$$$%##$$$##%$$!$##"!##" "!"!!!!! !      '481614$.$?\gdeik  BB?>?>?=??<<<<;<:99:=:9?=::;9;:9989988777767898766655757546764544575586355683254565546354375554635455655456553444253556556232334234222111/2102311201014/10//200004111/1.0///..-.0/10/-1.1,0,-..-,/--0-.--,,+-.-,--*-,-.+,++****+-,(***-),*+***)))))(()))))*((()(('((*'''''((%'&''&&'&&'%$%%&&$'&%%&%'%$$$"#"#$$$$##$""!#"""!"!"! !!"!! !     %963/ 4,'. $; E]a]diT  @>B>==>>><<:>;><;:::;:=99:7:9;98987788987766787875777684568455543545556583565458644536554474625557244554444465455333554432324212/23332021311122210/00111102/00104/100/0.0////./-0/./..1*0---./+.....+/,-,,-*,+,-,+*/+),++++**,,+,-++)*(*+)*(*)(()*)()()))((*'((('(+(((&(''(#''&'&'&%%'%'$%$%&%"$%%%%&$$%###"$!$$$$#$!#"#!"!!! !"!! ! !!  !     !$%<42%/2)-,0#Qa^^cg3 =>>?<;>>=;:A==;::;::;;:;9889<989987699875675677746766754554555443464554466456645145443745434544444435555455665673643434322221210323231///0022121100.001110/00/0/00/2///0///..-..-.-..-/../-.-,-,--.-,-,,,,,+,,+,+--+-,,,+,+*+)+*++,**++'+)),))(()(**(()'))(('''(''&'(''''&'''%'&''%(%&&$$%$%$&&$&%%%$#$$##"$"!##$#!##!!"!#"! "!! ! !    %68101/$,/V___\[    ==?<<:?==;;8=>;;:<;;:<:;88;9;988897768987587667686676658735555544427445844555743544345134444353743334454224477433434542231133221214141002/102221100//000///01/0/,110//.///.-,././.../,,,...,,+--..-,-,--+,-+,-,,*,**+,+,,**++++*+**++))))*+*()))'))()())('(('')((''(&'&'&''''&&%''&&'(&''%$(&$$$$$%$$"#""#"#"!""##"""%""!" !!! ! ! !     #:61. 3)()1*Z[```I  =<9:;>=:;;<<;=;;98998<:::789;8=97957698486576836562565706575654347544764335555645363555.4564384432334453166456424454354127105221154221021*1012112.032/1/01000/./1////./.,/,+/-,+...-/,-,/..,..,,.+,,,+,+,.*.+(++),.,++*-+)++*++***+*))))*)')))))+%)((&)((((()((('')&&&%''''''$%%&(%'''&$%%%%&%$$$$$%!%%##"""!""""""""""#!"$"!!!"! !      "#;32 )2*&#)IS[^``<  ??>;;>=;8;>9<<:::;9:;;999888987;8866788856956666667425666554664435535544563244565443653533154354342233427343233723433333112420102233131,2011100//10.001//11...0./..//.0,/--.,.-0../-./.,..,.+,+,,,)+,++,,--+**,+,,+*-*,***(**&((),**,(**)*+(())()(((())'''''('%((&'(&$%&'&'''&&&'&'&&$&(%%&%%%&$$#$"$#"""#""""!#""! !"""""" #!!!!! ! ! !!      !(<2.1-'* 3N]^][N ?><<<=;=<999;;89:<::=:87:<798:87:77667686657766755447446544444443746454453232456575344344325322433232314554361205253344201123210234211022//01.1110212.0/0201/.//.2--....0---+//.,,-/..-,,+++,+--*+,,+++*-)+*)*+++*.)+.,++**(((+**)))(('+()+(*((()')*(')'''''''('(('''''''&''&%'''%%&%%$%%'"$$$#$###$$$!$$#""!###""#!"""""!!"!!! !!! !  !->,,!2$+&+%Q[][^F >@==>>=;:;::::9::;;:;::99989;78997696665975697552456454564474447344454434.2134545334334344532152333326546343321/5353342531/1112126310000//20/02,00030///04/0/./.-+....-..+,+,,,-..-.../-.++-*,+,*,++**++++(+.(,**)+)+++++)))))*)))))((',((((')((''((*)'')'''$%''''''''&%&%%%(&$($'%$%%&%%$$$$%$$$#%%#!"####"#!"""""#" $!!"!!!!!!! ! !  !      !!=8/"*.+ #( +-UPad_$ + ===9>?=<<<:::9?<:9:98888:9;:7;777667569:866547776535454435344523436654434643444334442315355454633322455435244333144222310/22221120100////1./2//01.1//.1.//.//./..//,./,,.-,+,-,,,..,..,)+,/*,,++,++****+**)(***)))+*),,,*)(*))))(*)(*((*'('(()'('''((''''(&&'&&'&&&'$'&&'&%%%%%%%%$#%%&&'%%$$$$$$$##"$###$#"#"#$""! ""!!"!!  !!       '$?1,,+*)(KJTUcZ  ===?>@<;?<<9::>;9<89:889999;:98766666666474554675544654384653374346344334335433432222231433444454457732353215323324222311213/1112110/0///0/0/-.,2,-/-.-2-.../.....,-+1,-+,,-,,,,,,+,,+/.,,-,*,++,++*+*++*())*+)))**+,()()*+**))())))(((&)')((('('('((''('&'%'('(&'''''"''%'%%&%&%$$$$%$%$%%#$$$$$&#$"#$""$$""#$!!!"#! !! !!      2:+(+,#+&* "SUQUSI ==<<;:;;?<;:;=;9999:998989998;866779776977852577644555453345266456/655554334348222234223345464535324223333212152224422/2411311/2+000/0/4./2/1+54/./0-1,///../../...-0.,,,..,,,,-.,,),+*--)+)-++++++++,)(())*+)*),++)*.,**,())()*'+)(''((((')((')''')&'''(&&'''''%'$&&&&''%&&$&%%$$$%$$$$$"%$&%$$%$$#""""#"##$$""#!!!!"!" !!     "47.-$$#*% +8QWPKK*  ><<;<;=;::::;;<99<9:9;98:778997878776754554485965554537235556543246543563333342531342314233433433352223332332422312101233321111/31/-///1/0./-2-/20-,-.,..,./....,,-.,/-.,-.-,...,,+,,+-./+-++++++++++***'))),))***))))**))(())))))(()&(((((('('&'''('&%'('%''(&'''&&'&&%('%%%$%$$#$%'%$$%$$$#'"#$$#$!""####$"#"!"!!!!!    ":4+.&,(#HLTZ]W  >;<;<;98::;::;;;98:9:;98:98899:757766654645555645563625684667447354434443221332233235324330333333512143143322222220101234110100200/20/01.////,02...2-1/..,../.---,-../*,.,+-*+).++++,+++))**)+*+,+++**)****)'*())*+(()*)))))))(()('()'(((((((''''&)''&&''('&'%%&''%%%&%&&&&$%%%$$'%%#%$$$#$% %!%$$$#$"!##&"$##"!!!!! #!"! ! !   !(;5#%.'!+&"KNNUVH  <===;;;:9::;;:9:78;<::977788998788786764446485676583334765654434443524443220335024123434321130433/2424042222224323000023413212.2//0///////0/.-220-.0-+.,/--0,-/0-,.+.+++-,/++*++,,+,.+++*+**).++,+,()',&)))*(,*)(()()))*))(')(')'')()''((()(('''('(((''(%&''''%&($%%'&%%&&%'$%'$$%%$$$#$$$$$$"$#$#$""## $$#"! """!! !!"!!! !!!     781.*),"!=MNOVV/ + ;;:;;<;<<9:::<:99999:9:;998::976777767567545667676743445654433463535334450111203344232444513440453244434101221114211003031203/002120..1//0///0001/../-0.-0-,,-,,,,,,.--,-++++*++*+++,+++++*(-+*)+++**)')(*(++**((((((()))))))(('&'((*(((+()(('(''''&(')&($&'%&%&$%$'%'''%$&%$#$#%'%%$$$$&$#%$$##$###&%#""$"""#!!!!"!! ! !! !!   :4.".*( +HOQQMJ   ;;=;9:;;<;9:::;;989:9989:997877;78977758765355757634444465453523345434263223221534221243544210343325554321200010122/21252021121100,0/00/.0//0//..-../,-0/.+,,-,,,,.*+,,,,+,++**+0,++,+*++)(++*)())(*+*(((**)))()(((((()))(&'('''*'''')'))((''((((&'('&&&%'&'%&&&%%%'$%$&%$'&%&$$$$$%$ $###%$#$%#"$!#$#$$"!!"!!!!!!!!! !! !   "$B9'*)""JPMRNB  <:@=<;<;;;989;9::9:::88;9988:977897954765555555775857565345522744323335443321334/2222044543223452220538243351121124111110.42/111020-/./.-.0002.//-0,0../0/+0,..,,+,.+,,,,+.*+)*,+,+**+****+,+*)((((+()))%(*)))('(())(('((('''''''(('(('((($))%''('('('''%%&%'$&%%%%%&%%%%$$%%$$#$%"$#""$%$$$#$%!%"#""#$!""!#!!" #! !"" !!! !    '7.-!)( 1JONLO+  >BOKMM  <>=:99?<=98789:7?8::88::78678:855785577544447453667532323428334443123212333212232213143233342630/11000,4011032113.1/001/.0///2110/0./...../0/.0,.-.--..+..+.,,,/*++,.,,++,,-++*)*+,*))*+)-)(*))((*)(((+)('((()(('''(''('(('('&(((((&'(''''&'&&(&&&%%'&'&%%%$%%%$&$&$$%$%$&%%$#$#$##$$$$$##$$""##$!"$#""""""!!!"#"!!! "     9.*)"' ARNON5   <>>;;:88::8889:<997799:<<:7>66<4895578676355555346753334434423454334322223322111211205213150331112521121/0022/4100010//1///2/.//000/.1.00-//0/.+...,1+--),-.,,,-,-,,,-+++,(-+*++**))))*+(*)))**++())+()((('')(((()'')('&(((()'(')(''''&''&'$''''''&'$''''%%%%$&&&%&(%$$&$%%$$%$$$#"$&"$$$##"##""#"##"!#"!!"!!! !!!!!"!   +;-+&'%&KBINO*   + >>?==<:;9:9889:9998;8:9:88767887:76857545364457564523244435243443424522102222232222062003401220412024112111231100000/..2//.//.0////0./10-.//0///,+-..//-+,+++,,/++,,,+++*+)++*++,)(**+*-(+*))**)*)(())(((((&((')((('''(''('$(''('&'''&'&&&'&'(''%'&'&%&&'&%%%%$$$%%$%&'#$%%$%#$$##$####!"#""##!$"#"#""""!!!!!!!! !   #35 ")!!)# BKFKNF#  + + + ;=<=<9;<9:989999979969988866769:77687566554497874563324447330234441443211221211322131331651032001220131030/011002/1/..0./-/.0.0.//..//---,0..2,1,,/,-,+**+*++,)+,-++*+*)-+())+**))(())))*))*))*-(('('()((&'('('()('((%'('&%'&&''''''&'%(%%%'''''%&%&&&$&%%$%#&$$$$%&%&$$$#$$#$#$$$$"%%$&"#""##$""""""""$!# !!!" !     75+'((  GKLRQ5   ;:;<;>;:::9898::;8998857:87655778557752434754787636455644335214532145422333114321306322121104231112000013/00010///00//..--.-//..-..//./-./..--+.-..,-..,,.,*++*,),+)*)))))()**)+&)))+)))*))*(())((()&*)('((&''()(('('''((&)&%'''()%&(%'%%%%&%''%&%%%%%$$%%%$$$$$&#$$&%%$$$%'&"%%"$$%""""#$#"!%"#!#"'"""$"" !!!!! !  !   =(!.*" GLNOT&  + 7:9;;<99;;;9889::88799858865488867474663636546466455533433524334214/33342120012043353310120112200//0.0./00000///-0/00//,,-..--...../0-..-,.,,+-,,.---,,-,--.+*)+,,+*))*-))*-)))+,*)***())(*'*((()((&(''''''('''('&''''&'''&&&&%&&&&''%$%%%&%%&''$&&%$%%%$&$%$$$%#$&%&$$$#$$#$$""$$$"###$###"""$"!"#!"!""! !! ! !!!!    &5')) +2GCGNQ   + + =;:;;:99<:99<<87:988895;7995669765555554634455845655358343373643221022223001111222222242101223321/5002010110000/.//0110-.././-//.,-,,.-+/--/,,,,-+-.+++-+,,,++,*++++)**())(*))))))))((()('(**)(()'(''&('')'')&)'&('%'&%&''''%%%'%('%$'$%$&%%%%&'&#%%%$%%%$$%%'%%$$$%%$$$$%$&%$$##%###!#######$##!!!""# !!!!# !"!! !!   +  3,*"'( +EGB@G=    + =::=;;:8:;?::8887<88867788;4876695547555566461864575544223326531163436121001111122322111202211210..110210/01/0//0./.00-10//.01//0-./1,*,..--0,-.,-+,+,*-+++++++,,++)++,*+*+))(*+)(+)*))((('((((+((''*(('&(()''(((&''&''%(%&'%%%'$''''&&%#(&%&%%%'%%%$'''$$$%'#'$$$$%%$$$$#%%$$%%!%##"##""#""#"##""!"!!"!!!# !!!!!    +6(4$"(!+#'EEDGH,   + ;<;:<988:8;;;998:9;98859669767675644475556435347484662360445332515043330344220.22/112232102012/0/0/30200//.30/./0/.///.22//0./.0,/.,+0+-,-.-,+-++++++,+-++++,,,,,)*)+)))+)))**'(()()(()*()((*)()((%''()')'''''&'''('('(''''(%&&&%$&('&&(%$%&%$%%%&%%&%%#$$$$%%%%$$$%$$$#"%$$$$#$$#""#"#!""!"""#"! "!"!!!!! " !   =+$2(%#* 3GFDDC  ;<;;;:999<799688988:99856878758975566644466266444655452364244222225153652321/312432025222123110///0/1011./..0////..0///-,/.*-.//1/./,-+----,,,./+++,++--)++*+++,**+)*)+(*)+)*(()))+())(()()(()(()''('')(''&'%&''''%&%''%&%'%(&&%&&&%&&&"'%%&''$%''&%%&%$$$%%%%$&$"#$##$%'%#$$$$$$#""#""#"!""""!!"#!"! !"!" !   %*% (".) BGGEB:   +  ::9:8999988887;988877:47877979587499764554473333342454703333/52422322447432222211,/0322102001110./0100/00//0/.../01/00.-,./--,..//-,-/,,,,,,,0+,,*+,,,,+,++++)+)*))(+(*)))())',)()(()))(*))))('''(()&&''%'''%%('&&&('''%&&$'%%&&&&&%$&%''%%&%%&&%&%%%%%$$$&&'%$$%$$$"$#%$$$$$$$"!""$""##"#"""$ !" !" ##!!!    ! + ! #( ,ADDCC2  + ;9>:;;5::;87878766777687689896768656563565334244344443622522221011121.422212042223/1112120/0110/1/0/0//10/1/.10./0/002--0,/....,/.-.+,+-.,,-*,-++,+-+-**+*+*-*+*,)))+*))*)))**++*)(((((())(((&&('(''%&%'('%&'&&%&'%&%&$%%%'%'&&&$%(&$$%'#&%&%%$%'&&&'%$#$$$$$$$%$$##$#"$$"#$%#$"$"$#"""#"!""""! """ !"!!!!! !     + + '&&+ @FDA@=  =:;:9:8<;9989785585879787796:74655787554475456243533545132330224110123212523413312100022/01220/..1..-/000//00/10/-///.-././..-,..-,,-,,--+,,*-,+*++,*++*)-,+.,*+**))**))))((')()'()))('('(('('''*(''&'%'&'%&''&%'$%%%%%'%%%%%'%&&#$&$$%$#&%&$%$##&&$$%##$$%$#$$$$$%#"#$$$"$$#$$""#"""$$$ !!"#"!""!"""!!"   !  + + + + !'#) ?EED@- +   + <;99::889<:98868559879786666779366765543466465354554332424423222352322140223212332020010//11210//.,0/00/..0./101-/,../-.,-/.--/,,.-+-0-,+(+,,.+**.*++,))+-++*)++++,)))*'+((*())())((')(((''&''''&(''(&&&%'&'&'''''&($'%%%%%%$$$$%%$$#&$%$%$%%&$#&%$%$$&%#%$$$#$##$#"#"##$$"##""$$###!""" !! !!!"!!!!"! !! !   + + + + "%#*' 2<<@A= + :<789:98888767776668798755645:65875554376365436444444154334520223323332010121112111211110/0.000/0/../00//0--//.-1./...,/+,-.-+-,..-,.*,,+/,*,+-,,++++),****+)*((*+'))**)+(*('(((''(('')((&'%'''''&'&(''%%&&&%$'%&''#%$$%%%%%&$$$&$%$'&%%$&%%%$$$&%$$$%#$$"#$$!""$$$##"!%##"#"""#$"!"#"#""!#"!""!!!! !! ! + + !!%#(  =8===0 +  :98:;9<;8:877786685979676555837678644560135433143443231243242112122233311011120111/301200000/./0/-,/./.1//.0-/0/+/,/.++,,,+-/+.,.+...-,,+),,,++-++)%+++))++*(()((*+)(+(*(*)((((*'+'((')''%$%%(&&'&&('&'%%''%&%$'&&&&%%&%$&$%%%%$&$%$#%&#&&(%%%%$'"#"&$%$#""#$"$#$#$$"###%###"""##$$#"""!"!!!!!" %!!! !! !    + +   $"&$  =>=>>( + +896799:99873;7686657656666559454737734435344444333414242234-42222123142023212//10000012/0/10/0//./,0..00../0,+-.//-0.,*-*,,-.,+,-+,+,,+++***,,+++*(**+--*+))))))()()((((*()('(&)('(&(&'&&&%%''$&'''''%$&&''%%''&%&'&&&(%$$%%$&&%$%%%#&#$%$&$%$$%$%$#$%%$"$##$#$%""#$#$"$"##!!#""!"""%!#""!""!! !!! !  + + + + + ! %) /B>>=/ + + + + :8:977;:;9;77897758867566597645685335323444345352306232223343123214113313-121100000000..//.01/.100.1-1,././-,--,,.0,.,.+--,+.-.+,+,+,++,*++++,,+*)*****,***)&+)**))*)*()*)''''))'(('''&(&%''&'&%'&'''&(%&%$&($%%&&$$&$%%%%&%%$$%$%#'%$$$$$$$#$###$$%$#$$#""""$###"!#"$"""$$"!""!$"""!#!""!"! !!  !!!!! ! + + + + + + + !"!"%%%  7C<==*  + + + + + :;:987::<57999978678868676767875544343626562544433332/442222322322021113522111010///00//./00/0-/10.0./.../.,-,,,,..-,,,.++,,--/+,++++,*++++-,,+)))'++,+)++**)*))'*)(*+(()(((()(((('((''%'&(&$%'''&&%'%%%%%&%%&&(%%%%%$%%$$#&%%%$%%$$%%$$$$%#&##""$$$"&""#$###$#$#!"#$%"""$"""#!""""!! !"#!!"!!!" !"!!!  !   + +  + "$$& :88;9$ + + +9:;;;998787::8958887757:864776664454233533235565331233332212212244121212122001000/0131////0-..-0/1,././//0-+--+,+/-,+,-,+,,,,+*-/*++++)(*,+,+*)*)))*+*))(++*)(+()))(*()))(*(('))'''(''''''&'%%%'('&'%%%$%'&$%'&&&%&%$$'$$%$$%#$&$$$$#$$$#%#$$#"#'%%##$""#$$"!#$#"!"!#$##"" ""#""!"!"!!""#!!!!! !   + + + + + + + + +   $'  22:899 + + + + 9:9::987787659694777558455395766585424457343452242432212231422121.1213223410/102000100//.1010//..-,,.0-/..//,+++.++,,,-,++++*-+*++++)*++)+++))(()++)))(*)(*())))()'(++(())'('(''''&'(((%''''$'&%&%$&&%&%$$$%%&$%%%%#&$$'$#%$%%%!'$$$$$#$%$$$%&$$$#%$#"""$#$"$"""!%"!"!!"!!#$!""""!!"""!!!! ! !!!!!   + + + + + + ""#!  3789:0 + + + + +  9;9:99889998788:797535554497665666753354551432543543111223221222222211/202300///0/50/-//.000100////.//../0/,,,+.,..-,,,+,++++,,+++-+)+*(*)*)*,,())()*)*)*))()()))((((,)(()((''('('''''((%(')&''%&'&%%%%%%''$%%$$$$''%$%%%$$$%''&$#$$%!%$&$%#"%$$%%$$$##"""#$!"#%""!"""#$%"!"!$#"!!!"#!!#!!""! ! !!!     + + + + + %"' 8>9:8# + + + + + + 96:<;9897885889;957655535677356675533385423220544543203333234220/22254000322//01/10/.0-//0/000/.-,/.0....//0-++++/,.+,-*,+)++,+,,,,*****+)()()),**()))))((())))(((('(('(''('(&((''('%&%)'($'''%&$$%$$$%%&'&%$%%$#$%&%$%#$$"$$$%'$$%$$$$%%$$$$$$$$##$###!"##"""""""!!""!!$#""""$"""#!#!!!" "!!!!! !!   + + + + +"&"'  87895 + 888::998<87789887:4474866654767472234536523/322354342512421221212.2125001100//2/001220.0-/.0/././--./.---..../++,+,+,,+,+++/-,+,,+**+*++++,)))*++)*())((('')((((((('((+()(((''%''(((%&'%%'$%''&('&%%&$%$''&%$"%%$%$$$$$$$%$$$'$$%%&#$##$$###$$$$$$$#$$$"""#$"!#""!!"" # """!""!#!!!" !!" !!" !" !  + + + + #&#  87779, + <7;86:8:898777;87698::57644444455134645433324622421433150112112021222/10210//00/0/1/5203-40,./,.,/.../,,,--./+,,,,.-,,++,++*,.++,*+*++***++*),(*+)((()+('')'))')))'()()((')(''&&'''(('&'($''&$&'%'$&%%%&&%&$%%$%$$$$$$#&$%"##$$$#%$$$$&#$%%$$$$$$##%#$$#""#"!!"#"""#"!"!!!!!!""!"""!!!! !!" !!   + + + + + + + $0$& + 7:871* + + + + +8869:878:8757867656785553455456564333554433455422242212111221020100120////031////00/011*00,..0...0-...+-,,..,,,*+,-*++**(*++,,-,)***,*))))(+*)*)(()(())(()(*))(('))(((()(&&&'&''''''')%&#&'&$'''(%%$&$%'$%&&$%#%&$$###""$$$###"##%##$##$%$#$#$#$$#"$#$$##"#!#!!!"!!#!"""""!#!!!!!!!!!!! "! !" !  + + + $C!$&  $4/23= + + + + + + + +99:9:8:8789978676669767254555365644335546325444322452110221113410/1210./0.001/0///0/0.-01/.../.-././,,+-+---,+,+++++-+**)**,+,-**,)*',)))),*)())(()()()'&()+*(((('(('((''(&('''''''''&&&%$'''%$&$%$%%$%$$%##&#$$#$$%"$#$$$#$$%"#$###$#$#$$$#"#$"#""##$#$#""!!"#"""!!!! !!"""""!"# "!! !!! !  + + (?'  44/-2, + + + + + + + + + +  9:?7=99:98:95:99874976755454675423445444272244325102321132232420103.1//011..110/.././0.1,-.-1....//,,,-,/,-+++,+,+++,+*)+,,+*)+++*(+)))+*++))))()(+))())*)')()'(''(''&'('('('''&('&$$%&'''%(%%'$'&%%&&%$$%$$%"!#$%'#$$#$$$%(""##"%$$$"#!#$#"#$#""$####""##"""#!""! !#"""#"!"""!!!#" " ! !   + + + + + +!$  65621) + + + 8:<:;9:6788898;88;956675546165553337243433223215502252111313244012201-/0012/0202/.///-//./..//../.---.-./,,+++++*+)-*++,++./+))*****)**)()+))(*)+((*)(()')(('))'&('''''((''''(''&'&%&$%%&$%$%$$&%%$&$$$$$#"$##$#$$%$$$$#$%$###$$#"$##""#$"$""$#"""$!""#""" !""##"# " !!!#!!!"!!!!! $! !     + + + + + + #  +5+213 + + + + + +  ;98:9879:77696487586857555557574442144333434243224243321114212//121/44202301/0./,0-..0-/..-.--..-0-,,),-+-+++,+)*++*)++++,*),,()(+))(+)+()+)))))())*))(')))(('''(((&+%'(''&'''''%'&&$%%%$$#$%%$$%%$#%%$$$%%#$#$$%$%$#!#$$##%$$#!$$"$"""#""!"!"#""!#"""!##!! "!#!"! "#!!"!!!!! !"!! !!      + + + + + + + + +   ++8-)*1 + + + + + + + + + 98:778:88795647755865577755486655564453135533222222333232,12110401111...23/010.//,./////..0-.-..--2,/),+,,,,+),+++.,*+++,))+*,()))()*(/(*('*()()('''())+(+))(''(('('')'''''%''(&&'%'%%$%$$$&#%$'%$$$$$%$$"$#$#$%$$%%%%$#$$$%$#$"%#$#$""""!"#"%"#"!""#!$""!!!!!"#" "!!!!!!! ! "!"!! ! " ! !!   + + + + + + + !  /,'(+* + + + + + + + + 9959587898565554:5545766764634466233357122354514442213320030000011/10-101003-1-1-...-,./..---,+-...,--,+-+,,+,,+++*,+-**)**+***++()()+()))+)((')(''))(**')*'&')'(((''(''(($&%$&'$'''%%$(%$#%$%$%%$$%$$%%$$$###$$$$$$##$#$"#$$#$$!#!#! "!""!"!$#!""!"""""""!!!!!"!!! !!!!!! !! !"  ! !!    + + + + + +  %0,'(1 + + + + + + + + + 88:767676897565645656564634333353327352422111623343122103000010111111030/1/20/0,//0.-./..-/....-+,-,,+*,+,,++*,+-,)+(+-*(*(*()+))()()+))))((()()'())()((((''('''((''''((&&&$$&%&'&&%%%"&%%&$#$%%%%%%$$$#$$#"###%#$$#$$"#$##$##$$"$!$## ##"#!!""!" "!"!$#!"!#!!!!!"!"""!!!!! ! !!! ! ! !  !   + + +  + +   %-)(-, + + + + + + + +  88;;:876555477838334766336743443343371134342153254320011/1201110103.21//10300/./.2/-,,,-.-,.,.0+,,,.++++,,++-*,)+)),)-+*+())()())())'()(())*)))((((((())('&'*'()&'%(&''''("&%%''''&$%%%'#%%$'$%$&%'%$$%$$$$""""#$%%#####$$#"#$#%$! %$#""""" "!""" "$"""!!!!!!!!!!!!""!" " !!!! !! ! !"  + +  + + +  + + +  ,)*+,! + + + + + + + + 897989679769836635152667444444356533214434322112154313002102//1/0110011000020/...22-,-/..-.-/.-+.+,)-*++,,++*++)++*)-++++()*)))((*(),*)(*(()+))((((')((('%('((('($*'&&'%%&'(%%&&%'%&&%%%$%%%%%%&%%$!$$"$$$%""#"#$%"#!""###$""##""#$#$$#""#"""""""#"""#$! !" !"" !!!""!! ! !"! !! !!      + + + + +  + ))(-, +   + + +97=:96576:6:966644135655643344246433220344521124130111020200/42320021010///.//..01+-,.././0,//.,+-.,,,++++,,++*,)(()**+*++)))))(((*((((*(*(())('&'('&'''''''')&''&&('$&%&%%$'&&'&%%$&$%%$%%&%#%%%$%$$$$#$$$&##$#$$'##""#"#!""" !$$$!#$""!"!!!!!!"" !#!!!!!"!!!!"! !" !! !!!"      + + + +  + + +))'((+ + + + +  + + 8:8:9?664566467535576555454333524534/422432131242322312313101221010030/00//110/1/,2*,.-011+/,,-.,,,++,++,+,),++)))**,+**)**)*))))()())(+''())(((+*($''''''''(')%&''$('%'%%%%$%%%%%%($%%%$$%%$%%$%$$$$$$$#$&!#%""$$%$#""""#""""#""#""!"""%!""!$!!"!"!#!! !!!!"!!! "$ ! !!!! !      + + + + +   + &+)((( + + + + + + + + + + +  7:8999838:576886637376454416228332414523212111031112023000122022/20220///////230.+-,+,//0,.,,,...,+/,,,+++-*++++))-)*+*))))*()(()((++&)(''*(')()'(((('''('''''((%)'%&''&$$$%&%&%$%$$$%%$%$%$%#!#%$$%$#$$####""##"#"##%#""""""!#"!""!# #""" !! !"!"""#"!!! !!!!!!!! !! !      + + + + + +  )*)*( + + + +  + + + ;9887:887977664566545664425444247235423322321413411232000/0/02110100101../1011,,/2+-/..-,+++-,.*,--+++,++++*++,+,))++)*+*))))))))()&(('''''*+(()'*(('&'''''&&''%&$$&%'''$%$&%&&$#%$$$&$%&&%$#&$##%#$%##$$""#"#$#"!"##!!!"!""$""""!!!!""##!" !!"""" ! !! !!!!!!  !# !! !     + + + + + + + + + +   *%%)& + + + + + + + + +  888766789847677545554124543624455334453443321011121004102014022/40/326../0-1/5.,-.--.++-++,--/-++./..*++**+*++,++)**++()*))+)))*()))(('('(()''('*)(''()('''&''''%%%%%'''&%%%#&"%$%&$$$#$$%%%%$##"#$$$$$$#%""##!"$##!!!!""!""!"$!!!!!!""""!" ! !#!!!"!!$!!!" ! !!!! "! ! !     + + + + + + + + + +    !*$#(% + + + + + + +  987:75675544567648324596544234244463414323212014042121.0/21000//00212////020/..//1,0.,+.,,,+,-,+,,,,++*++*))*,+(*))*+(*))(,)**(*)*))'''((')'('%'&''&&)''''&&&&'&%%%&'&&''&%$&$$&%$$$$$$$$%%%#$$$%$##$$$$$#!#"""#$## $!!!!!"""""!"""!!!!#" !! !!#!! !"!!!! !  ! "!!!      ! + + +   "%$"*  + + +   8876876834534756455565/2444432235854424335321.3313011/10221120-/0201-//000.0/-./.000.,--.,....+**+++*+))-)**)(**++)(*+)))**))((())(''((''((()'((*'%(&''''&'%'($$%%%&%%%&'%$%%$%%%$%$#$$$$$%%##$"#""""#$$#$##$""#$"$!"!"""" "!!!"""!!!! ""!! "!! !!!! !! ! !!!  !    + + + +  )&&$#  + +   787:7644355552548655146654453281457332225622201.22/1121/01110//./04//////000//-///..0-1.+,,+.+,-+++***)),.+()(),**))++)*))))((')))&*'(((('''')'&(('&&&&'%$&%%'&%%%&&%%%%%%$$'''$$$$$$%$$$$'$%$$#"#!"#"#$$$$##"###""!!""!""!"!!"!!#$ ! ! "!!!!!!!! !! ! !! !!! ! !  ! +    + )&#''# + + + +   798<8:876565653545446464323532334423234343520/04202/0143013000.,20//13//.0+0./+...//-.0,,+,--)+++,+-*+(*+*,(*()*)))*(()(())%'())(((((&'(''')&'(()'&$'&''%%%%&%%%%$#%%&$$%$$$#&$$$$$$%%$$$$$%#%"&""""!"#"#"##""###"#$"##!!""!!!"!"" "" !!!# !"! !!! " ! !  !      + + +     +&%$ # + + + + + + +  5;5897475675544634556432513334/32221223343200/122110/11100/11001.-./21..//0...--./+,/--,--+*,,,++*)++*++*++,()()()*)+)()((''(()(((((%*'((((&'&'&''&%$&''&%'%&$&%%$&$&(%%$$$$$$%$$$"#$$$##$$%$$#"""""""#"""###"""!$$"""!!!!!!!!##""!! !! !! !"!!!!! #!!#!! " !    + + +  +  +)##!" + + +  + 778:88967655364423345562021002322222323333210/23-000011/5101//1/.0//.11/..,/-0--.//+--++,.+*,,+/,,*+,-+***+*,)(+))**))(((((()+))((&((''*&)'(('()%(%%%%''&%%$$&&&%$$$%$$'"%$($$'&%$$$$'###!$##$#"!"""!"""""$#"""""!!!#"#""!!!!!! ""%!"! !!!!! !!!!"!! !!"!!  !      + +   +  %"### + +   +66667676566342425424544545012214221133223232/-3013//00110002.2,01././/.,.0.+.,,,0,-.,+,-,-.,.+).+,+,,++++)**)))))*)))((+(*'''+))*(('('(&'&)&'()*)&&&%&('''#&&'$$&$%$#%%%$%&$%%%&%%&$$$##$#$$#&"""""""""""""!"""!#"#""!##" ! !!"!!!!"!!! !! !! " " ! ! ! !   !   + + + + +  +  + + $$"$$  + + +   8665566575444434225455355355034343310321123102/0000////0110,/010300/0.1//..,--/-+,-,)-,-/-*+,-+,++++++*)*)*))))(**'*((*)*()('*(*(((()'(('''''&%&('&&''%'&%$$"'&$'$%$%%""$$&$%%$$%$$%#%$!$!$""#"""""#""""#"!""#""""!!"!"!! !!! !!""# !! !! !! ! ! "       +  + + + + +  + + ($"$! +  + +  576659487548054222465455634222421411222233311///,-/.//20210/001,2/2/.//.0..---/.-+./,.-/+1/-+.-,++++,+*)))*+)),))(%%'')*)(((()(((((()((''(%'))*'&''&''$(&%%$'&%%%$&%$%$'$'#$$$$$$%#%"'$"#&"$#"$#"""""#$##"!!!!#$#!!!!!!!!! !!"""!!!"! !!!!! !!!  ! ! !   !   + +   + + + + +  +$%!!#! +    +55762575955341424354445644465223511225061411231/0120../010/0///...01....1/0,/-+-./*+,.,0--,,,,--*++,*++)++*)-)))))+()()))(())''''''(('''&'%$'''&''&''%&%$&&%%$#$%%&'%'%#&$$$#$%%#%#$$&#""###!""#""""#"#"!!""!" """!!!!""!!""!#!!"!"!! !!!!! ! !! !! !  !  + + + +  + + + +  +   #"## + +   66777756546430534335354664331221413302/1110212//.3/103211110////..2//0...0//-.-..+-+-//0*++,..*+++++***)*,+))-*))(()(()((())'*'''()('(''&&'$&''&''&%$%&''%$%%$$!%%%$&%&$#$#$$$&&&%$$#!"##"$#$"!$""""#!"!$"""!!!"!$"!!"!!!!!#""!!! !! ! ! ! !!     + + + + + + +  + + #"""%  + + +   175555548637444543236416335312124014133101211130100113.//2./.../.1.0/-0.+..00/0,*-++,,0).,+,,,++****))')'('+((+*)*)))(((((()(('''))'('&''&&'&''&'$%%$%%%%%%$$"$'$%%$&#"$#$$$%$$$%$%###$$""""!# "$###!#""!"""""""# !"!!""!! !! !!""! ! !! !!!  !    + + + + + + "  +!"$ + + +  + 55856565536468554643344522/23240/311122221002011/0/0/10/.2././//..-//-,/-/.-/./--*/-,-,(+++,+,+-+*++),*),(*(%)))(())*))('()()))''''''&(&'&&'''(&%%%$$%%%&%%&$#%%&&$&%$%""$&$$#$#$$##$##$##"#""!""##$"!!!!"""#"" !!""!!!!#"!! ""!!! !! !  ! ! !!      + + + + + + +   + +  #! + +  6565447463342355643533202121212043121012320001103000110//11/-../-0./+/.-/.-.--..,*+--,+++.*,+,+,+*+)((+)()(*'((*'))),*'(()))((%&'('''&&'''&&&'&&'&$#$%%$$%%"%%$%&#%$$$""#$$$%####$$##!%##""###$""!#!!!!# !!" !"!!!!! ! !!#!! !!! !  ! !  !      + + + + +  " !  + +     + 77455473224442445:43423310001/20501420222400223/3012010/20////-0.--1/...-..0-..-,,+,-+/+,-)*,+*,,+++)-*)())))(()())'&()(((()()''('((''''''((&%&%%%('%%%%'%%%%%##$$$%$$$"$#$'"$#$##"$$##"#"###$$"""!#"!!"#!! !##! "! !!!!!!!!!!!!!!!"! !   "         + + +  + +   !  +    89245544521014144425524241223121311111115023012/00.1021.20/0.003*/,../-0-/.0.--,..-+-,*-,+-*+),++-)-*())*))())())((&+'*((()')'*&'')''''''(%&%&&$&&&'((%$#%%#$$$#$#$$$"#$#$###$#$$%#$$#""#""#"$##"!"!!!"""$!#" "!!!"!!!! " " !"! !!!  !  !  !  + + +    "   +   745523252315251332454562425/0222221332223/000/10///0200/-10///,...-.-...,./-/-,,,+-+**)+,*)(*++++**+,+))(*())+*+*(()'()((()''''&((((''''&(%%%%%&&&'(&%%%%%&%"!#$$$%$$"""#"""##$$#$"###"#"""!"#!"!!!! #!"!"!!##!!!!!! !"!!! ! !! ! !  !    +  +   "   + 53477681242322262224531205/322112330122.3200211.2./1//.0.0/01220/1/../-,-1/-.-,,+.+-*(/+,*)))+++++++)))()()++)++*)+(''''*((''(''')''''''$&%&$&&&&'''%&$%&%%$$&%$$#%$#'"$"#""#$$$"$###""#"""##"!!!"!!#!"!!!""#!!" !"!! " !!!! !!! !  " !  +  + +   +     + 548545253413353304.4321232021311/0.011/1//0/2000.0/.01+.1.020/././/.1+0,.-,0.,+*(*),**)**+**++-*(+-*)+**(()))))(())*)((*()'')%'&&)(''('&%%#'%(&$%%'%%$$$%%$$$$$$$$$#$#$"!#$###"#"""#"!!#""!!!""""" !" !!# ! !! # ! !!! !! #!   !     + + +   +    +   36455435333222234333222112322.0123010//./1203012////.0/0.1.0/00.,.00,,,///.+,+,,++++)+,+,*+*+,+(+))))))+())))()&)(*(((''))''&)&%''''(''%&'&%%%%%%%%$$%$%%%$%$$$%$$#"#$$"%!##""#"""###!!""""!!""""!!"!"" !!""! !!!" ! !!! !!        +  +  +   53533363542333132211202345221551/2/10//-/120,/00/..*-4,--.0/-0./-(,/-..,.//-,,+++*-'.(*+*+,+-,).+)+*(*,+()(%))'+&&*(*)()')(''&&%*''$&'%&&%%'%)%%$$#$##$#%$$$%"%&$###$$#$"####!#$$"##!!!"""""$!#"""#!! !""!!! ! ! !!! ! !   "  !    + + +  + +   +     +424214233332641211111623438/223.//2.00//-02111/1//./1+...01/--./-/,,...,1-.,+,*+),+,,*(*+++++**)())'***()+'()*))((()')($&('')%%%&&&$&)&%&'(&$%''%$#%$$%%$#&#$&##$"%$$$$"#$""$#"##%#"!""!!!""$"# ""!!#" !!""!" !  !      !           5234352134313343111132222210221/01/130//003231./0///0/../0./.+-.+/..,/0,-/--+,,,+**-,+,*-**+*+(/())',+'))'(()))(()'((''$%(((''&'$'&'%'(%#(&%%''&%%$'%%$$%"$%$####"$$"$#$$#$#""##$#$"$""!!!! #""!!"!" "!!!!" "!!! !       ! + +  +   + +  +    5365131354222211211112212120110/./00*31001232/1//1.//--/.+/,4-*.+-//-*-,++,+,++++,++*+++(/)*+,*))*+()'(('(''))''()(''('('%%$'(''('&$%%%'%&%%%'&%%'%'&%%$$%$$$%$$#$#&""#$$$$$$##""$$"""""!!! % !""!!!!""! !!! ! !  ! !             +     556323551432122021110140110120/2/1001.20//..20100.//-,.,0,-,++0,,./.,--.+++,+++++**,++,,*-))*.)**+**(('&('$))+('''*'''&((&'&((''&)'&&'&&##&%%$&%%%%%$%%%$$&#$%##$&##$$##$$$$"""#$#$$$""!!!!!# #""!!#""! ! ! !! ! !           + +       044332122331101220111/10021101/2000////0///.-010///.-/0-./--,-+,-0-.*-,,,+-+,**,,*+.)*+**()))+*)***)')''&',(&*)(()%&''''%'&&&'('%&('&&'%$'&$%)%#$%%%&&%$$$%#"#$%#$#"#$#&$$$"""$##"$%#!"!!!"$##"! ""!" " !!!!! ! !!! !  ! !    + + +  +  +  +      42505002421.231211/00001102111/1010000010/--.*/0/.0...0/,/..,+0.-,..,.-*,)/,+-++,*))-+.)++))()))*(*)('*''%()'*((((''')'&%''&&''(')'')(%%&%(&%#$%%%%'&$$$%%##"#$$%###$%$$"$#$!$#$#"!#!#!"!!"#"#!!!! $!% !!!!" !! "     !  !    + +  +   +   310562121005012224//.000032040///10../0,./../0./0/../2-//2./,/,-...+,,,.))+++++*,+*+,,+*+++)()(()*)()(')*('((*(((+''&&%%)&('&''''''%&($$%%&'%#$%&%%"$$%$#$$$#$##$$$$$%"$#"#!"$!""""" !""!$$""!!"!!!!!!!!!! " ! !!  !!       + + +   + + #  +  43/21311000132332,.100011001.1/030011/./.+///-20/././-,..//++/-/.,./.+.+).,*++,+)+,+**,,,,+))')+)()()(''()'')))'(&(&(''%&''''&'&&%''%$#%%$'&$$$$&$#)"%$$$$$$###$$$$$$$$#" !#$$"!""""#""!""""!#!!"!! !!! !!!!! "! !! !   ! !!     + +  +  +      1552232112121042///-1200-/11101../00.1/.0...../1/./0.-.--0.,+-+,+,/-.-+*(+++++*+/,*++,++*+*))''(%*()))*(%()(((%%%%((&%'%&('&'''$'&&(%$&$%%"#'%$$#$""$$#!%#""$"##$$#"%$#$"!"#$""!!"" "!"!""#!""!" ! !!!!! !!!  " !!! !!! ! !   + + + + + +  +  +        401212.4/40/002113301200/1010/0//.//002///-..0.1/.-.,/,,,2.,*/.*.-0/,+,)++(+,,,,..+*)+++++,*(('(())))*())''(+')((&''''('''(#&$($'&''&%$$$%%%%%&%#"$$$$$#$!$#$#$###"#"##!!""#!$!"!!!$""#!" #""!! !!$ ! !  !!! !! !   ! + + + + + + +     + +    33200222312.4000//23310///1010..-...//0--../.,//..+-,,-//,.--.+++*-.-.,-+**)++-,+*++()***)'*')())(((('+*()('+*'''&(&'''%(&%%'((&%''''&%$%%$$$$#$$###$$$$#"$$$#$#"#"!!%""#""#$# !!# !! !"!""!!!  " !!!!  ! !      + + + +  + + + +   +  +     +    211542223.202221211312000./0/../0.0..//-0/.,,.//.../--+.-+,/.,,+-,.,+)-/+*)*+,+,**+*(*)))*())(%(*)(('((*((('(()%'&')$%&%&$$%&'''%&''&%%'$$%$$$$"$$"##%%$$"#$$$$$#!"#"""#!#""!$%%" !!!!!! !""!!!! "!!! !!   "     !!!   + +  + +            4413/032200/0/312201//13..0,1.1//..././..,0*.0,,,,.1...,*.+.,.,,+,/*,++.,()*+*++)*))-(%*)*)((+)))(((')''('(')()'&(&'(''('%''%&('&"%)'%%%%#$$$#"!""##"$%$%"$"%#%"#"## #"#%!#!!#%!#!!"!!!!!!!!!""!!!! !!!!!!! !! ! !         + + +  +  + +   +        101/2301/11/200/10//212/..,//2-//100-/-/./-/.,.-///.//+.,,,,,---,+++++,,+*(*)+*(/***(('(((+(((()((''((('('(')&''''&'*(&&&%&&%'%&%&$"%&%$$%%%$##$$#"##$%###"$$$##""!"$ """""""!#! !!!"!!! !!! !!! ! !        + + + + + +  + + +     + 120.41.0221+41//1/.-/1/1.-/0.%1/0/,.-../0.,,+--,--..//,,+,,,.)0+,+,)+,+,+*+-++++(*)+))((((***((((&**())(''(%&('*'%''&%%%''&*''&%%%$$%&%$"#%%$$$%$##%""$$#""#$#"!!#$""""!"#""!# """!$! !!! "!!!"!!!! ! ! "   !    + + + + + + + + + +         + 00/1/0/.4004./02/0-//211/-0/./..0,1...///.,.++.-,/.....,+-.+,-+.*+)-,++++++*(-+++*+*))))()*))))(''&(((('&('%(''*&'''$%&%$%''#'%%&#$#&'%$$'%%$$$$%%%%%% %"#$$$"$""#$""#!!"!!# "#! ! #!#"!""!!""!"!!" ! "!! !     + + + + + + + + +          1/0220//1010/./23//.1/0..0-..01./,/*./0/./,,-/.-.,+-,*.+.*+*+),+,++,,++*+*,,(-+.*,+*)*'+())())+'&(')(((('%((*('&(''((%$&&'&((%&&$%%$$%%%$$&$%%$$$$$$$$##!""$"##"""#""%###"!"""!$" !"!! " #"!!!!""!! ! !      + + + + + + + + +          /002/0/.-100/0.1-300//-1-0///.2--.-3.0,..*.,,.++,-++,00+*+-+**+,+,+*)**.++**+*++,+*()*,))((()('(*))'&()'''$+&('''&'(&'%''&%&&%%&$&$%$'&%%$$%%$%$#"#$$$$$$"#"#!$""""!$"# !!"""!! !!!!! #! !!!! ! !! !!!  !   + + + + + + + + +  +      //022/.//.-01/1/20..3..0.//-02.11/./0--.----+-./--,-,.*-.,,)---,+*+*+),'*,*)*))*-(((+*+)))())*('()('*)&('''&&(''%&%%%'$'''$&'&$$$$%%$%%'#%$"$#$&##$$$#$#"%%"%$% !"""""$#!!" $ ! #"" !!! !"!!!! # ! !       "  + + + + + +   +   000/11..*/0.120---,0..0./.0-/,0-./+,+-.,,---,--/.0.-,*-*/*-+,,,*)+**+))),+)*)*))))*((+*((*)()((('')+''('$)%&%'(&&&%&%'%&'''(%%($%&$$&%%%$%$$%&#%$$#$#$$#&$""$"$"!""!"!"!$!!""! #"!"!! !!!"!!! " ! " !!! ! !  !   + + + +           .//-1.-.,,-31.3-//.//0./--+-,/..-+,++,.,.,--,+*-0,1,+10-0*+,,++,(-++***)+())**+)(((*'+%)(()*)('('((()(''''&%'&'%%%$%%#%'('&$&&$%%$%%"%%%$%%%#"$$"###$#$$!#%##$!"""$"!#! !!!! !"!!!! # !!!!! "!!!! ! "!!!           +          0-....-.-./2011-.(/2-/./..,,,,-,,+,/,,+,,,,+.+(0--,0*+,+,-*+,++(*,+))),(*((,*)))+('''())'(')&+''''((''&('%&'&$%$%&&&'&&%''&'%%%&#$$$"%%%%$$$%%$%$$"$!$"#%#$"#!#$#!""!"%!"!#!!""!"""!! !"!"!!!!"!!!!!!!!"   !    !     + +   +       1.--,00.././00//,10.......,,,,,++/+*-,-,+-,,,+-)/.*-,+*+++++,))+,,++*))+)+)))++)()&(()(*)((()'*'('&$'&''$%%$'&$"$%&$'&&%&''&%&$&$&##%#&$%#$##&%$!#""#!$$#$#"##"$"#"!$"!"#""""!!!!""!" !! !! ! !! !!!!          +    + + +    -/.+,00/,//3,--,,..,/-,+/-,,,**.,.+,,-,,.+-++++,.,,+,++++,+,,++*-)+)(+)*(*))))))(&*((((+(''')((('&'((%$$)&'&&%(('&&&'&%%$&%%&&%$##&#$#%$$#%$#$#%$!"#!#"$#$# """!#!"$!""#$" !"!!!"#!"!!!! !! " !!# !  !    !  + + +    + +      +11/.-///.++.+*/,+,-0/0.,,.,/-/*..,,,).,,-.,-/+,.+-++****+-+0*)*+*)*+)*()**()))()(((()**('&$'((''()'%%'&$'(%(&'&$&'%#(&&%$$%%#$%#"#%$$#"$$#$#$$$#""""#%$"$$#"""""$"#!!!"""# !"!"!!! ! !!! "! "  "     + + + + + + +       /0../.-.,-,.-.*-0,,///.-,.,,,.-/+,./.+,+-,.,*+-,++,+*+++**-),)*,-+()))()(()(('(((((())((())'&(('('&)&'$'"'%%%(%&%%&&%'%$$$$%%$&$&$$$$"#"#$$$"$"#"#"#$##$$#""!!"#!! ! "!$"!!!!"!#!!!!!!!!!   ! !    !    + + + + + +        ..0..-0,.,-,-..0.---0/.*++,-..--,+,+,,,,.+*)++-)+**+++++*+*)+**),,)+(*()*((()))*''()(()((&&(((('&''$'''%(''''%%(%%&%%%&"$$$#%%'$$$$$"$!$$$%$#%!""!!"""$###!!!###!""""$"!!!!!""#!!!!!!!!! ! ! "" !           + + + + + + +   + +  --.0.,.-,,/.,,-,/,,++,//,+,,0,,-,++*-.,++/*(+.**(+(*))(+)+**+*)*(+++)(+()((***)('''('(((''(()('&$&'&((''$'''$#$(#$'%'$$'%%$"&%#&%$#&#$$"#$$$#!##""!!""!"#"!!"#""!!"""$!!"!!!!"! !""! !!   !   !      + + + + + +       ,+-,/+,,,*/.-*/-+,++*++++*,-++--++++*,,--+++*+*,))*(**)()))+*)*****((())((((***((*'(*()*&'(''(&''%$$)&'&(&$'(%&#'$&&"$%%'%%$&$$$#%$#$""$$"#!%###!!"""" #""!!"#""!!"#"!! "!!!! #"#! ! !  !!   !       + + + +   ,+.+,0,+,0/1+++.,,-,+++,-)++,+*,-/),**-+*0+,+***)***)(*'*)))(+()*())((()(((('))*'%()**''''('''%%&*('$'&'!%&&&$$$$(%%$$$&%&$%$$$%%$#$##$##"#" ##"$#"" "#"##!!"!""!$"""! !!! !#"" "  !  !      + + + + +    + +),*)).-,,,+/)+-,,+-2.-,*-+)*,-*),+))*)*-*++++++**)**()(('))(*)*(*(((+*('('*(+('''((()%()(((*''%%&''&'%&)'$%%%&%'%&%&$$$$$&%$$#&%%'$%#$!%$$""#"# $!"!###!% "!#" !!""""! "!! !!!!" !!!  ! !  !!     + + +  + + +   +  +  ++,-**(+,,)+*-)-)++.-)+,-*****++)*)*()***(-+-+,*))++))+(())**+,)((+''*+)(*'&*&)&''('(#(&'('*&(&''''''&'&&'&%&%$$$'%%$$$#$$#$#$#&'$"#$$$#$##$!"#$#""!!!"!"""!$"#!#!!!"""!! ! ! ! ! ! !!       + + + +         +**)(,-(+(+**,++++.)*/(+-,(+**)))')))*))****++**)'+**(+)())()'*(''')((+))'+((')'&%)('')'()'(&%'''%&'$&#$*&%'$&%&$'#%$"$#$$#"$$$$%'####$$##$"$$#"$"!"!# !"" $!#!'!!!"""! !!              + +  +   +   ,*+)))+)*)),(+)*-**,)-,))+,,')'(+(*(%()'*)+)))('))(())('*)()))(*)'*'()(((()(&('$')(''('(''%&)'''((&%%&&#%$($$%%&&%$$#$$#$#$"$$$#$%$"$"#$""###%#&$"#"" !!"$""!#!$ !#"""! ! !!!!! !  " !   !   + + + + +  + +   ++)+*+)+))**)*),*()),)++,(+++))('*(()*(%*()))(.*',**))'*()''*)('')'(((')''(((&'&(%&&+'((&('&''(''&%''$%'%$(%$&$'$$%#$&$#$#$%%""#$%$$%$%"#"""#$"##$#""!#!!""#"$ ""!!!# $! !" ! !  !       + + +       ++*+*++)++()***)(*++*+*'*))**)+*))((((((*))(((+'')(('('*''(((((()(((((&)(''%'''''*)'''((%%%)'(&%'(&(%%&'%$&$$$#$&$%%$##%"$%$$"$"&$%##$###$"#!"""##""!!!"""#"#!!!"# !"!! " !!!"! !  !!  !     + + + +     +   (+**+)+*'.)()**)***+,+'()()((+*)*((%)(((*+((/')(((,))(('%+&'((''*&)()(()'%(''((('''('('(%'&'''$,'$%%&&$$'$&'%$$'"%%$$$#""$$$!#&!"$"$#"#%%"!#""!$!!!!!""!!""""""  !!#! !!!!!  !   !       + + + + + + + +       !*)+),*)(*+(*)*+)*()))*(''((*()))'))())',&(*,'('')(((*()'&%)')''')&''))'+''''''('&(&'&'&%#&((''&$$%%&%%'$#%'#'%$&$$$$#%#$#$##%"$$$##"###"$$$"#$" !! "!!! !""!!!!!!!!! !! !!!  !!   !!   + + + + + +  +      +*))(((()())()+()((('(())(''''')')()''(&)*''('*'(&)'(''&$(''(''''()((((&'''))'&)(&&&'%'%'$'''&&%&$%(%%%$%$&%%$$&$$$$#$$&!##"##!!""#$$"!!""#$$!!!!! """ # ""!!!! !!""!!  ! ! ! !  ! + + +       #+)**('''')(($(((('+)((')(''''((((')(*)(%)((((((&''''(()'((''''('''''(')&('((%&&&%(%(%!&''&&'&%#&$$%$%%%$$$$$&%$$#"!%#$"$"$###$"$""#!##"!!!"%""!!!""!# !!!  !!!!! !!!! ! "$ !!  ! !      +   + +    #,,(('&&'('''(()&)(&)))'(''')('((&()'''()(')((*%$'((')''((%''''&'(('$%%'''%&'$('&%'%*&%%'%&$$'$%%%&"$%%'$$%$"$##$$$$$$"!#"$!$#""!"!""""!!! #"!#"""! "!"!!!!!"!! !" ! !                + +         &&(((')''''()''('&*)()(()(((((/%'-()&'()(()&%''()'&'((')*&*'%%''%&&$&'*%&&'$%''&'$%&%'$%%%$%%%$$"$$$%"$$%&#'##"#$%#$%#%#$#$"""$$"$#!!""###"!!! $"!"#!!! !!"!"! !!!!  !    +   +  +     %(+)+,)(((('$$'((+'+&(')((''(,('('(%+)&&+$&%''('&&'%$+((#($%&'!'&"'&'%%%%&&'(&$'($"&&&%'%$%$$$#$$$$&%$$#$!$$$##$#"$$#!"""####"$""!!!!$!# #$!" #!##!##$!!"!"!! !! !  !#  ! +   + +      +  + #%#*()'(%%''(('('''(&)&&(*'%(%&'((&&%%"&%&(&''&%#)*%$&&&&%'&'''&$%&$%%%'&%''%'&$&$&$$%$###&"% "!$%$$$#$"$#!"!"###%!$!$#$#""$"$"##"#"!#" ! !#!  $ !#"!" ! # !        +           + + + !(%$)'''(%'&')'''&&(#'%&%''%%'(&%%''&%''&(&)%%#$$''&&&%&(%$$&)%%$%#$&&''$%$%##"$&$%$" $#""""$#'"##"#"" ""#"$#" #""#!""!"!!! !!!"# ""!!#!  ! !   !      + +        + )''''"$%&'%&&%$''$&&'&%%&%'%%%'%'$&&$%''%%$%&'%%''%#%%&$$$%''$%%%$'$$$$%#%$$$$$$$"""$$$!##$#$%#""#$$!!#"$#""!% !$!%$"!!"!!!!!!"!!"! ! " !      !!          + + '#$)#&($&'%%$"%%$&&'$&%$%&$$''%%$$&$&&&%%$'%$$&$%"$&$&$$&#$%%%%#!$#$##&$$$$$$#""##$$$$##$$%""#$"! "!""!""""!"$!!#! !!!! !!!!"!!  !  #       + +     +   + $'%"('$&$$%#%$%'%$%#$##%%%&%%#%$%$#&%#&&%&#$$&%$%%"%$#$##$%$$$$$$#%$$$$$#&&%##$!$!##"$$"##$#!!#!""##!""!! !!!!!"!! !!"!#!!! !! !!          +   +      (%%$%%'&($$%&*$$$$##%$"#%"#'%$$$"$#(%$$$%"%'#*#$'%#"!%"$$$##$$%"$$&$$#!"##"!%#$#!$$$$"""##!!""""""#!" !$" """!!! "!!! ! !!!!   "!"!!   $ !!" !    + + +    !$(''&$#%$%%%%$%%#"##%#%$$%%$&$%#%%$#$$"%%)&$$'&$"#$$&##%##$$$#"$$#"$!###$ $$"'! "## "##!!#!#"$"!#!! ! !!!"  ""!"!! !!!!"#!        + +        #%&$%%"#$&&$#%""$##$%'$$$"####$$$$##$&$$$#"###$#%##!$%"#"!$###""!"$##"#!#!!!" # #!!!""!!!"""! !""!#!!! !!! "  ! ! " !!!# !    !    +      "!   + + + + $'%'%%&%%(#&""")%$$$%%$"$$%$&""$$%&#""$$!##"""$%#"##$%"#!#"$!######$ #$!!!%#"!!!!!""!"!!! !"!!"" !!"!!!!"!! !! " !              + + '&'&&$$%$###%&#$&"##&&#"$%$#"%#"$$#$$#"##""""$#"##"#"$"!##"##$%!#""#$"""!""" "$$ "! !!!!#"! " # !!!  ! ! ! "     +   +  + + !&&$%%$$$$$%""$#%&%$!#$$$#"%%""%$$"#"$"##"$ !!"$#""$!""" #!#!!"#$#!###!! ! #"# !!! ! " ! ! #!#"!!!! !#        + +         + %!#$&'%$##"#$!$"$$$&$#$!$"#$%$#!"#"%###""!!# "#%!!&"!$$$"#$ #!"""!"$ !"# !!!! $"!!"#! ! ""! !! " ! ! !   !"   +       + $%%$"" ""$!"""""#!##"!$"!##$%"!"!#!$!!"!!$!"# "!! !"" "!! !!"""# #!!" #!! !!  !  !              +    + ""!! !"!!""#""!"" ##"!""##"!!!!!!!!!!!! !$"" !"!!" !!!! " !   !! "! ! !  !               """"!!!!"!"!#$ !!""#!!"!!!!!!!!!! "!"!" !" !! !! !!#!! !!  !!  ! ! !! !!" !    +   ! !  + $"! !!"!!!"! "!#!!!"!"!!!! !!""! # #!! ! !!!!  ! ! ! !             +  +   !!" "#!! !!"""""! " !! ""! !! ! #!! !" ! !!" !  !  $ !! !   !!          " """ ""! !!!!!"!! " ! !!! ! !"! ! !!!  #"! ! "!!!! "   " !   !    +    !   + + + +!$!!!!!!!!" !  ! ! !" !!  "#! !! "   !!   !    +  +       + + !!""!! ! "!    ! ! !!   ! !               +  !!  ! "   !"!!  !! # !              + +#  !!!   "! !  !"      !     +      + !!     # " ! !   ! ! ! !       +     + !!  !! !!!!  !     +    +   % + +      !!! ! !       ! !                  '   ! !!    +  +     !"   + + +    !      +  "   + + + + !!     !      + + +  !  +  +  !   !   + + + + +      +     !  + + + +   +      !   + + +      +      +  "!  + +  + +  +    +!    + + + + + +          + +  + + + + +  +  +  +  !    "!! " +  +           + !""  + + + + + + + +    +  +    !!'#!! " +     +   !!"&'(&""!!   + + +  + + +  +         " (('$$##%%# +  + + +     +        -,)*#%(('&"    + + + + +  +   +    "!!  ---.,'&)'$$" "!     + + + +  ! +    +     !  0/.11,-(')'&(##"%  + + + +   + + +   + +  !!  662101-/,,,)'&$#&!!!  + + +        +  +    !   648633321.0-+*)'$)'! "   + + + +   +   +  + +    +     :;:87533/0/0---*(&'+(&&$    + +         +     !" !<;::78527200110.-,+)%)('#"      + + + +   +      !!!"  ! !@@7=<=;963320231/.1('(''$%##    + + + +      + + ! !! ! !"!!"!AAB?===>:867643612.,**,)(((%&(!"#    + + + +             %#""DAE@@?;@:<9:88955311//,+-.)'('&&$#"   + + + + +   +  + +   +    ! ""!!#HABAB>?>D@?:99995344312.0.*.)%''%$%!"!     + +    +    +    "   ! JFDDCBBB@B>>;:;=867843304.2-+.))&'%(&""!   +   +    + !   !!!! JIFGEDDDDC?@=<<=<:76:955335/.+/++)'()&'#$##!!   + + + +   ! +      !  !  ""#! NLKIHGDECA?AB?>==;:9=868474122.-,,,*+($'&#%%#!  +    +     +      "  !! !"#!NPNKJIHGEGDDBBA>==@D9<7976:63321-+.-,*.+('&&%% !#!   + + +  + +  +  +          "   !!$"! QPOKPJJKMIGEHFHBA@D;D;:7997:65544/2//,+)))((%'&$#$"$    + + +  +  +   + + + + !   TQUQNRLNHNIHFGJGFDDBBF;?A=;9:3764411---/-(()))&&%#!" !  + + +    + +   +   +            RSTSSQOQSPLJKJJIIFEFEF@DA@>>9;8:88531103//.-,,''($$%##$!    + + + + + +   +     +  ! !!!   ! YUYUVRWPPPNSOMKIJHGEDDDCACC=<<<<;983469541121*))(*&(%&$#!!     + + + +   +   +  !  !  ! !" "#!#!VTSWXTSTRPRROONKOKIHGEEHDEDCE<>?<<;;:88645124/-))(**((%$ #'!    + + + + +    +   +   +  +  !   #$   !! !  " YXXWVWTURTRPPQPQMKKIJHGFFFDEAC?A98956745120/-+**(&(()'$###"     +  +    +      + +   ! !   !#! ! ]_^]]`Y]Y[YXXXUUWXTTTTQNNOMNMMHHHGDEBC>A?<>;?;986748420/.++++*)))%$$$#!!!   + + + + + + +  +     !  +            ! !!   !!^^_]\b[^\\[[ZYXWXVWVVSSSRPNOMJJIHHIEDECCB@?==?=:988873100.,0/+,+*(*%%$"$$!     + + +   +   +   + + +       ! ! !  !  !"^b__^^_^]\ZY_\ZXVXZWSUSSSNPPOLJMJKIIFHEGEB@B@@;=;<:799885211+0.,++*('&''%#"     + + + + + + +  +   + +  + +      !  ! ! !!!"!!"! !!! !!## cb`c__`^`__`^_`\[Y[ZZWVSVWZWPWOONLNKJJMKGGFEDBCAA=A7>:9:988372./1./-/-((((&%%%&&      + +    +   +    +   ! !  !"  ! ! "!""!!""" !"!"#! !" !fdc`baa`b_`^`\]\\^\[YZZYVWVUTTTPPONOMLGJHFHEEDEBC???==@::87<87531110.,**((''''"&$""    + + + + + + +    + +  +     !        ""! ! !!!"""""!"!!!!" " `bbd`acbada_^d]]\]][Z[[XYXYWVTSVTNNNOKOLLKEGDKCDEDD=>?;>:9:9>98443213./1+()''&%%%%#!!!     + +   + + + +        +    +        !#! ""!!$ "" "!#  ! !!gecbcd`fada`^^^`__]]_Z_YZ^XWWSTTTTSQKMLMJKGGHIFDCEDB@A=?8:<;99;7535301101/*+'&%%$$#$#"&$   + + +             !!! !"!!!    !fdebcadccacda`_a_`]]\Z][[^YXVVVTTSONNNMOLMMLLKJEEGHDA@BAA;=;<:876;63331010-))((')&&(%$"!$"    + + + +  +     +           "! !  ! " agfgceebdddce`_`a`^c_\[^Y^YZXXUTTTSRPRNNLNONMLJIHHGHCAAC@BB?><;;95753311202.+,((+)''$%'$&$"! !        + + + + + + + + +  +  +    !    !! !!   !  " !! !!!! ! "  """"eceedcbgddcgebb``__^^_^Y\]`[XYVWX[UYSQSOMVOPRNMKIIGIFHCC@ABAC;<;:9:87542222201/.0.,('&'&&"$##""#!       + + + +  +  + + +  + !       "  !  " !" ! ! ! !""""!!$$$" #""!gdegehgfecgedbfab^``c][\\^Z[YYVZXYWYTSSTUMPPOPOLMJIFFEJEEADAB>>>=;<9:977532210110//-+-((('&'%#"! !   + + + + + +                ! ! "  ! " !!"!"$#!!! ! "!"# !fdecgfgddhhgigacada`bbb^^^\Z_[\YYYXWWVTTSQQSQONNOQQJHFFDJCDBA@E?@?<:8;7:657431300000/,/0**'%%(""$""!!"    + + + + +    +! +  +          !  !    !!!!#""#! #$! gigfifgefjegdeddeaa`aaaaca]\\[^[\XYXUXZVTURSQPPOPPNKIGHGFKCECCAAC?===::<98655322531002+,-.)(*$$&%#&%$!      + + + + + + + +       + +   +    ! #   !! !!"!# !""!#  !"$" hijiehgfgiigdddccaa`bacd`_`_^][^^ZYYX[XXUUVUSQQQQQPOKJIHGFIFEEDAB@A>=<>9:=66864643142/210//,,&(')(&%&#" !     + + + + + +   +         +!      !!"   !""! #! "! !"#&!% jmhjigiifgdffebfccbbacba``a`__`]\`[ZXVWXWWUUWSRSUQPPSJNHIIIGEEDHDA@?A?=A>9995776543132320/0/,0*+*)*('%#"#!  +       +  +    + +  !!!! !""!!  ! ! !     "%#!"  !!"#"#""!mnljhhjjlhgfeechcecddbaa`c_c`_`]\]\[[YY\WXXWXTRRRSRRRPHPKKJGHEFDGDC@BB@@@><=;79:674343322/.410,,+*(*')&%'#% "!"    + +  + + +  +   +   + +    +  + +   " ! ! """!"!!!       $!  !"!!! ! !! %%$#!!#ildjijjhhggjjdhcgcedeb`ab_cab``_b]\\Z[Z\YZXXVTRSUSOSNRPNPKLGIJHFFEGDCBB@=??;?><=;66934564511.,-.,,+)*+&&''%%"""!    + + + + + +     +    + +  +  !  "  !  !"  "!     !#!!  ""!!!  !  """##kdihhghgffgfffefefdddcad_aa`_^ab_^^_^[^Z[ZX[WVTVRSSTTTTQPLLJINJFHHGDCB@AE@=@BB=9:?95866534412/0..-,*,*)))'&$##"      + + + + + + + +   +      + + !      !"  !!   !   !!"  !"#  !"$ #! " !#imifehfgggggdhehdcdfca`aacbda``b]\]^]^\Y[\ZXVUXVUWWTVRSQNOKLKMLLHIHEEEEC@?FD>C@@<><;8777545264500.,--+.,)()$%&'%##"       +  + + +   + + + !    #    "! ! !"!"""  ! !    !!!  !!!!  %  !"!! !!"jkhfjegjjjggfddedfdebcabbb`_`b`]^^]\`_\]][XYXZVZWVWUUVSVPOONQNLMMJGHGFEECDDAB@>A?@;;8;85656464363/.-.,*-&+*((''$%%#! !        +  + + +     + + !   ! !! !!  "#" " !  "!   !!# #! !! !!#!#! !" !"" !kkjjihjefdfdehdfgffcidebca```ba_^_^^]_]\W\ZZXVZWT[XVVVWTQOTOOMLKKIJKIIJHFGEDA@@@A>=:;;;>:88777641223/1-/,--))(''%&$$&&!      + + + + + +   +   !! + +     "# "%"!!! ! ! """"% !!!!  !!! ""  !! ! # ""!!"!"$##!!! $" %!!"$lkljjlhekddeefhhhfeeaeab`babdba_^]`^]Y`^X[ZZZYWW[WWWVZVUVTRPTMOPOMLJIHLHHJIHEDDAAA??B@<<>=:9:98755436532.---+*'('&&($%&&'"! %   + + + + + +     + #       !    ! ""$%#"" !  !! #"#"!!! %!!  !!  !!!!  !!" " !  ! !""! "%%%$ ! ! " !"##jhlliiiidejegfgfhfhebagabaaabbd^^]^[`]_][[[\[YZZYWXYZSXTTSTWRRRPPNNLNJKJMIIKFDCBCB?E?E??>;<:::878878726143/1,,*)*((''''&%'%'"        +  + + + + + + + + + + + +   +  "      !!!! ! ! ! #$&% ! !!   !#!!!$  !!   ! !  ! !!!!#$  !!"! !!"!"!" $&!! !#! !#!lnhfnigfhggeffgjgffefga`adaaab`__\^]\_][\\Y[[ZY[Y\XYZXWWVTTWSRROPPNMMMKLKJJJJFCDEGABC@C@?@;;:::::98568352123./+-*,#(%)*&''(%#""! "    + + + + + +  + + + +      !   + ! !!"!! !! !!#" !#"#$%!!!!!" !!" !! "!% ! "  !!$! !! " !"$"!! ! %! "$ "$"!!!$"!! "" ""#kkjjgijhhhgefjejefdgaa``ba`eca_``b^`^\\\][\Z]_^]_YZ[XWXVVUUXUUSRQRSLNNPNNKLKKJHEEEEBDBA@@<==?;<<<:9878552554310-0/.)**)))()%%$$"!!!!     + + +  +    + + ! + +  !" !!" !! ! " !! !!  ! !#"! !!! ""       !!! !  !!!!#!#"! # " # !! $ljllggkhkfgfhhfcgcdcdbcdbccba_aa_a_]Z^[^\\Z[[[Z\Z]ZZXWXWWYWUTTSTTOPPNMNSONOKKIJGFGECDADBB@?>>>=<<<::88:766343325/100/.*))(*''&%$$$#" !      + + + + + + + + + +  +   +  +   + + + + +   "!! #"  #"!!"! !  ! #" !"!!!!"" !  "   "  !   !" ! "!# !$#!!$jkijhijghekggdceegbaiedba`fbc_bbaa^c\\Z\\^[][Z]Y\ZZWWX[VYU[XTVV[SVQOPQPPONLLMNJJHHGIEGFECCB@C?@B=:=<;98996995554310010,/+)**)&'%%$#%!" !   +  + + + + + + + + + + + + +  +  + + !  !  ! !  ! " $$$"##!""! !  !!"  !"!!!!! " !  "  !!   ! ! $ !"!"#""!"%!" !$"&$"!!"jkkimimigeiegfdcb`behecccgb]b^]aaa_`\Z^^]\]^[[\\^[ZXYWVVWUWYSWWVURSTUPPSOQOPLKJHIGGGGDEEEDCCAA@@A@=>;:<;9=774323422310/--****)()(&%&$##!     + + + + + + + + + + + +  + "  + #!  !! !  !"!"%#"!! !!!  ) !! ! !"! "$!    ""     " !!!"#"%!#"!! ""%##! "igikmkiiihhdhfdcbbehdecbaabeb`babaa_acba^^][_Y`[\Z[XXXXYVX\VUT[TWSSTPQOOROPQLLMJIMGGHIJFGGJECB@ACAC@<<::==:8;86533231412/0*-++/)*)('$%$"!!        + + + +  + + + + + +  +     !  !#  #! !#$" !$" #"!"! ""  !!"$' ! "!" #!! ! !!! !! ! !  # "    !! #!$$"$!%$$! #&%! jimkikkkihhjgefccdecdfccebbbfdb_^c````a`^]\\[Y^]\Z[[WVVVZZWXXXUZTTTRRPQQQQPNNNLMLMMIJIJIHFJGD=FCBCAD@>===;?>98656743323400/.+,0,,,,''&'$$$"!!!$        +  + + + + + + + + + + + +  +  +        "!  !! ! !!!!' # " !! !  ! "$"!!! "!#"! #!"! !  ! #!$$!    !" !!"! "!!!" " #$&!"##$") !""" mkjjjmmjhhkhffedfhfefbbebbbadfa_^]cc``a``_a[_[]a\Z^]\ZXYYZYXWWWYTWRVQRVSTRQQOOQQPLJJMLNKIIIHIJEDBB@=@>=A=?=<<=7:7877432221..1+,-,-*''%%&%&$#"#" !         +    + + + + + + + + + + + + + + + +   "    !  """# "$ !!""!"!!!"!! ! "$# !"!! !! !"" !     !!!#!!"$"  ! ! "! #" %$!"$#$" "!!# lmlklhkijigeffefjgfeeebcdchecba_`__`_b`_`]\[[]]Y]^Z[[]XXYXYXYXXUVTVRTTUUSVRQPMMPMOMKKKHNJNHHJDGICBDBA@>=>@><<:@:::775542231/1.-..+(&&''''&$'#"!"#! !            + + + + + + + + +  + + +       !  #"! !! % !!   "! ! !!"#! !"#!! !!  !!!! !!!#"!! !  ! ! $""!!#%##!#"! "!!!""iknnomjkmgeeehfihfeeeecbccedda``_bad^___^_`[\\^^Z]\\X[ZXVXZVYXUXWXTUWRVSTTUQPOQQQPNLLLKHMJKJIGGEDDD?C@ABB>>?;=?=<8<777664406//2+/,))$(()(('%$$&%&"!!!!     + + +  +  + + +  + + + + +  + +      ! $! "! "!!!"#!! !! !" "! !"$!"$!$$ #! ! $!   !" %"!"$""" !  ! % "%&#"$$#$### !!!!# jomnkilldfehfegjffdeecebefheba```bb`abaab^^\]^\[ZZ[YZZXXXWZXXWWWTWSVUTRROURWOOPPPNOMJKMPNMMJIIFMGFEFFCEAC@@@?@>=;<=;85856540224.././.,-))('%%&'%$""$!!!!        + + + + + + + + + + !! %,   !! !"$$"$"! !"!!!!#!  "" !!## "!##"%#!! ! !" !!! !   !! !$ "!! ! "!  !!$'%$!"!#&## "!"!! nkhpjjijjgffefggdedbdabceccdda``bbab``a_b``]]]_\\\\][YXZVYY[WWVVVVWWURSTVSRORPOPQRNMMNMNOMKLKKJGHKEJDDHGD@A?A@@><==<:9:867553134203/0.+**)('((&&(#$#$!!!!         +   + + + + + + + +  &  8+! !   !! ! !$"$%'# !!! ! ###$ !!!!"!"!!""!"$!# !!!  !#!  "#!!   !   !$ "!##!##!"!  !$$"!!#'!# #! !!lmjqklkhdgfgejhfhddefgdfbdbb`cbbbb`bccfaaa]b^_b^\[[[Z]ZYZVYZVWVZYVUUURUTSUQTTTRPOORPPSNPQOMMLLIJIHIIHFGECFBAD?AAA=A=<:99:7775453422201-+*)+)(((''$&##"#$!"! #       +   !   +A&!      "#$$$!#'#%"!!! !#!! "'#&' "$"#$!"!!!! " #"!!"! %#"  !"##$  !#!! !! ! " "!""&##!!  ! !%""""#$!"!!"&!jlqkljfkhgflfmgfdecdhdccf`aacegecee`befd_a^^ab^]^^[[[[\[\\[ZYZZXYZTSVYUTTSSSUVTTQOSQQQQOSQOONQLKNHLKLDIHECCCCBA@>??>=;;;988:67345212010/*/,*))*''''$$$$%###"      + + +  + + + + + +!   ++B !  !  !$$$$##""#$#" !  """ !###"$#"$%!" !! !! !"!!"!"!  """""! !" "! "!" "  !"#!"""!  !!!!""#!!!"  kkjnklhhihgjmhffedchcgbccbcfedbggcbada_d`ab_`__]Z^Z\ZYZ[[]YZ\[[YYXY[ZQYUUUUWUWTRRSQTQQPPPOPQLLNQKLIFLGKFKHFDDCABEF@?>>=:::78996553620100-0-,.+*).(''&%$&$$!! !       + + + + + + + + +   =<)  !  ##$#$$!!! "#"!  "$& # "#!!$#! $$!! !" !  " !!!" !!#!#!"" ! !!"! $ !!!#! "! ! ! "# ! %""!$!!"""  !mknljfihhjjlfffg`dbeecbcbddgdeddcccfde`a`a`^`_]__Y[Z[Z\ZYZZ\\Y[[XYZUWUQ[XVSUTTUSSRRURQPMQTTPPQMHLNIKKJHGGHHFBBCCB@A?>;<<<;;:99:7672232./3-+..+++(,*("&)&'(!#" "$!       +   + + +!"  @D !!  !  ! !!"#"#! !!"!#!$"$"$!!!!"""!!!" "! $$ !  !"""# ! #! !!$  !!# !""! " !#!#" "$#"  !" # #"  $lnjmimghgjjjfefedcegcdbbecgefgcebcdebbbbba_^_`]\[\_Z[[Z^Z[ZZ\[]ZYX\X^ZUXVVTXQTTTUURUUUUOUQQOPQQNLLOKJIHIIGHFCDDCB?@>?>>><:;;;6985554533//01./,,/.-+*))&((&&&%$$"#!!"!      + +    +DG   ! !! #"$%"!""""##$$""""!! !""!"" # !" " !  !!!! $!!! ""$" !"$!# !#!!!!!!!!! # ! ""#%%#!#!##$$# !! "nspomkkmlmkjkjigggjihigfhikfhiigehhigeddfccaaa_`\_]`_b\d_^^`\`^]\`[[[\[Z\WXWWWVZVVUXZWYZSXXUXZUNOPTPQMMPNMJKHHGFGDCFED@C@>==<<><;9787:763630/-//-+,,*+**)+*)&%%%%$$!##!       + + + + +  + +#"!""9GD*! "!!!"#"!#$##"#%&$#! #"#%"%&$""###$#$$#"#"!""##) !!! !"#"!"#"#"!!%""! "!!#%%#!#""% !""##"!"#"""$#%*!"&#$##$##""%%&&"!" !!#"!# \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002_cam2.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002_cam2.bin new file mode 100644 index 000000000..72d770c36 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_195453_002_cam2.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526.json b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526.json new file mode 100644 index 000000000..3be3fbc2b --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526.json @@ -0,0 +1,177 @@ +{ + "ts": "2026-05-04T20:41:33.526", + "cana": "baixa", + "horario": "cedo", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "fps_target": 20, + "frame_type": "RAW_BRUTO", + "capture_mode_requested": "TRIPLE", + "capture_mode_effective": "TRIPLE", + "raw_policy": "require_triple", + "stream_meta": { + "frame_id": 45, + "backend": "oak_fcc3", + "frame_type": "RAW_BRUTO", + "capture_mode": "TRIPLE", + "output_dtype": "float32", + "dtype": "float32", + "output_layout": "dict_by_camera", + "payload_sources": [ + "cam2", + "cam0", + "cam1" + ], + "camera_info": { + "cam2": { + "id": "cam2", + "socket": "CAM_A", + "sensor": "OV9782", + "role": "rgb", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam0": { + "id": "cam0", + "socket": "CAM_B", + "sensor": "OV9282", + "role": "re", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam1": { + "id": "cam1", + "socket": "CAM_C", + "sensor": "OV9282", + "role": "nir", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + } + }, + "timestamps": { + "cam2": 203257.450285, + "cam0": 203257.439577, + "cam1": 203257.439565 + }, + "sync_dt_ms": 10.719999991124496, + "sync_ok": true, + "sync_tolerance_ms": 25.0, + "shapes": { + "cam2": [ + 800, + 1600 + ], + "cam0": [ + 800, + 1600 + ], + "cam1": [ + 800, + 1600 + ] + }, + "dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + }, + "codec_name": "none", + "codec_family": "none", + "dt_comp": 0.0, + "dt_send_payload_prev": 0.0 + }, + "applied_camera_controls": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam2": { + "ae_enable": false, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ], + "ok": true + } + }, + "camera_params_json": ".\\calibration\\module_params.json", + "note": "manual", + "raw_preview_reference_camera": "cam2", + "saved_payload_type": "raw_native_multi", + "saved_payload_paths": { + "cam2": "20260504_204133_526_cam2.bin", + "cam0": "20260504_204133_526_cam0.bin", + "cam1": "20260504_204133_526_cam1.bin" + }, + "saved_payload_shapes": { + "cam2": [ + 800, + 1600 + ], + "cam0": [ + 800, + 1600 + ], + "cam1": [ + 800, + 1600 + ] + }, + "saved_payload_dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + } +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526.png b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526.png new file mode 100644 index 000000000..8971a30fd Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526_cam0.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526_cam0.bin new file mode 100644 index 000000000..f82775742 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526_cam0.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526_cam1.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526_cam1.bin new file mode 100644 index 000000000..d090282ed Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526_cam1.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526_cam2.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526_cam2.bin new file mode 100644 index 000000000..5f8be9bec Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204133_526_cam2.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204200_031.json b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204200_031.json new file mode 100644 index 000000000..6a4ebac79 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204200_031.json @@ -0,0 +1,165 @@ +{ + "ts": "2026-05-04T20:42:00.031", + "cana": "baixa", + "horario": "cedo", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "fps_target": 20, + "frame_type": "MULTISPEC", + "capture_mode_requested": "TRIPLE", + "capture_mode_effective": "TRIPLE", + "raw_policy": "require_triple", + "stream_meta": { + "frame_id": 115, + "backend": "oak_fcc3", + "frame_type": "MULTISPEC", + "capture_mode": "TRIPLE", + "output_dtype": "float32", + "dtype": "float32", + "output_layout": "CHW", + "payload_sources": [ + "cam2", + "cam0", + "cam1" + ], + "camera_info": { + "cam2": { + "id": "cam2", + "socket": "CAM_A", + "sensor": "OV9782", + "role": "rgb", + "shape": [ + 480, + 640, + 3 + ], + "dtype": "uint8", + "interface": "OAK", + "channels": 3, + "bit_depth": 8, + "height": 480, + "width": 640 + }, + "cam0": { + "id": "cam0", + "socket": "CAM_B", + "sensor": "OV9282", + "role": "re", + "shape": [ + 480, + 640 + ], + "dtype": "uint8", + "interface": "OAK", + "channels": 1, + "bit_depth": 8, + "height": 480, + "width": 640 + }, + "cam1": { + "id": "cam1", + "socket": "CAM_C", + "sensor": "OV9282", + "role": "nir", + "shape": [ + 480, + 640 + ], + "dtype": "uint8", + "interface": "OAK", + "channels": 1, + "bit_depth": 8, + "height": 480, + "width": 640 + } + }, + "timestamps": { + "cam2": 203284.122167, + "cam0": 203284.130001, + "cam1": 203284.129988 + }, + "sync_dt_ms": 7.834000018192455, + "sync_ok": true, + "sync_tolerance_ms": 25.0, + "shapes": { + "cam2": [ + 480, + 640, + 3 + ], + "cam0": [ + 480, + 640 + ], + "cam1": [ + 480, + 640 + ] + }, + "dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + }, + "codec_name": "none", + "codec_family": "none", + "dt_comp": 0.0, + "dt_send_payload_prev": 0.0, + "channels": [ + "R", + "G", + "B", + "RE", + "NIR" + ], + "fusion_applied": true, + "fusion_alignment_mode": "manual_affine", + "module_calibration_json": ".\\calibration\\module_params.json", + "tensor_shape": [ + 5, + 480, + 640 + ] + }, + "applied_camera_controls": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam2": { + "ae_enable": false, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ], + "ok": true + } + }, + "camera_params_json": ".\\calibration\\module_params.json", + "note": "manual", + "raw_preview_reference_camera": "cam2", + "saved_payload_type": "multispec", + "saved_payload_path": "20260504_204200_031.raw", + "saved_payload_dtype": "float32", + "saved_payload_shape": [ + 5, + 480, + 640 + ] +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204200_031.png b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204200_031.png new file mode 100644 index 000000000..b68c9c437 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204200_031.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204200_031.raw b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204200_031.raw new file mode 100644 index 000000000..a0d15cde5 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_204200_031.raw differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_205033_329.json b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_205033_329.json new file mode 100644 index 000000000..b41fad79e --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_205033_329.json @@ -0,0 +1,165 @@ +{ + "ts": "2026-05-04T20:50:33.329", + "cana": "baixa", + "horario": "cedo", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "fps_target": 20, + "frame_type": "MULTISPEC", + "capture_mode_requested": "TRIPLE", + "capture_mode_effective": "TRIPLE", + "raw_policy": "require_triple", + "stream_meta": { + "frame_id": 71, + "backend": "oak_fcc3", + "frame_type": "MULTISPEC", + "capture_mode": "TRIPLE", + "output_dtype": "float32", + "dtype": "float32", + "output_layout": "CHW", + "payload_sources": [ + "cam2", + "cam0", + "cam1" + ], + "camera_info": { + "cam2": { + "id": "cam2", + "socket": "CAM_A", + "sensor": "OV9782", + "role": "rgb", + "shape": [ + 480, + 640, + 3 + ], + "dtype": "uint8", + "interface": "OAK", + "channels": 3, + "bit_depth": 8, + "height": 480, + "width": 640 + }, + "cam0": { + "id": "cam0", + "socket": "CAM_B", + "sensor": "OV9282", + "role": "re", + "shape": [ + 480, + 640 + ], + "dtype": "uint8", + "interface": "OAK", + "channels": 1, + "bit_depth": 8, + "height": 480, + "width": 640 + }, + "cam1": { + "id": "cam1", + "socket": "CAM_C", + "sensor": "OV9282", + "role": "nir", + "shape": [ + 480, + 640 + ], + "dtype": "uint8", + "interface": "OAK", + "channels": 1, + "bit_depth": 8, + "height": 480, + "width": 640 + } + }, + "timestamps": { + "cam2": 203797.43597, + "cam0": 203797.44401, + "cam1": 203797.443995 + }, + "sync_dt_ms": 8.040000015171245, + "sync_ok": true, + "sync_tolerance_ms": 25.0, + "shapes": { + "cam2": [ + 480, + 640, + 3 + ], + "cam0": [ + 480, + 640 + ], + "cam1": [ + 480, + 640 + ] + }, + "dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + }, + "codec_name": "none", + "codec_family": "none", + "dt_comp": 0.0, + "dt_send_payload_prev": 0.0, + "channels": [ + "R", + "G", + "B", + "RE", + "NIR" + ], + "fusion_applied": true, + "fusion_alignment_mode": "manual_affine", + "module_calibration_json": ".\\calibration\\module_params.json", + "tensor_shape": [ + 5, + 480, + 640 + ] + }, + "applied_camera_controls": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam2": { + "ae_enable": false, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ], + "ok": true + } + }, + "camera_params_json": ".\\calibration\\module_params.json", + "note": "manual", + "raw_preview_reference_camera": "cam2", + "saved_payload_type": "multispec", + "saved_payload_path": "20260504_205033_329.raw", + "saved_payload_dtype": "float32", + "saved_payload_shape": [ + 5, + 480, + 640 + ] +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_205033_329.png b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_205033_329.png new file mode 100644 index 000000000..8b98d7cba Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_205033_329.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_205033_329.raw b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_205033_329.raw new file mode 100644 index 000000000..3d353a10d Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_205033_329.raw differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153.json b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153.json new file mode 100644 index 000000000..6418c5f4a --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153.json @@ -0,0 +1,177 @@ +{ + "ts": "2026-05-04T21:17:32.153", + "cana": "baixa", + "horario": "cedo", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "fps_target": 20, + "frame_type": "RAW_BRUTO", + "capture_mode_requested": "TRIPLE", + "capture_mode_effective": "TRIPLE", + "raw_policy": "require_triple", + "stream_meta": { + "frame_id": 76, + "backend": "oak_fcc3", + "frame_type": "RAW_BRUTO", + "capture_mode": "TRIPLE", + "output_dtype": "float32", + "dtype": "float32", + "output_layout": "dict_by_camera", + "payload_sources": [ + "cam2", + "cam0", + "cam1" + ], + "camera_info": { + "cam2": { + "id": "cam2", + "socket": "CAM_A", + "sensor": "OV9782", + "role": "rgb", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam0": { + "id": "cam0", + "socket": "CAM_B", + "sensor": "OV9282", + "role": "re", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam1": { + "id": "cam1", + "socket": "CAM_C", + "sensor": "OV9282", + "role": "nir", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + } + }, + "timestamps": { + "cam2": 205415.956354, + "cam0": 205416.11234, + "cam1": 205416.045648 + }, + "sync_dt_ms": 155.98599999793805, + "sync_ok": false, + "sync_tolerance_ms": 25.0, + "shapes": { + "cam2": [ + 800, + 1600 + ], + "cam0": [ + 800, + 1600 + ], + "cam1": [ + 800, + 1600 + ] + }, + "dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + }, + "codec_name": "none", + "codec_family": "none", + "dt_comp": 0.0, + "dt_send_payload_prev": 0.0 + }, + "applied_camera_controls": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam2": { + "ae_enable": false, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ], + "ok": true + } + }, + "camera_params_json": ".\\calibration\\module_params.json", + "note": "manual", + "raw_preview_reference_camera": "cam2", + "saved_payload_type": "raw_native_multi", + "saved_payload_paths": { + "cam2": "20260504_211732_153_cam2.bin", + "cam0": "20260504_211732_153_cam0.bin", + "cam1": "20260504_211732_153_cam1.bin" + }, + "saved_payload_shapes": { + "cam2": [ + 800, + 1600 + ], + "cam0": [ + 800, + 1600 + ], + "cam1": [ + 800, + 1600 + ] + }, + "saved_payload_dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + } +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153.png b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153.png new file mode 100644 index 000000000..e5a2c922e Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153_cam0.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153_cam0.bin new file mode 100644 index 000000000..0bc208b77 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153_cam0.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153_cam1.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153_cam1.bin new file mode 100644 index 000000000..cc991ba38 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153_cam1.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153_cam2.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153_cam2.bin new file mode 100644 index 000000000..f87e3180c Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211732_153_cam2.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211746_571.json b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211746_571.json new file mode 100644 index 000000000..69b17b91d --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211746_571.json @@ -0,0 +1,175 @@ +{ + "ts": "2026-05-04T21:17:46.563", + "cana": "baixa", + "horario": "cedo", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "fps_target": 20, + "frame_type": "MULTISPEC", + "capture_mode_requested": "TRIPLE", + "capture_mode_effective": "TRIPLE", + "raw_policy": "require_triple", + "stream_meta": { + "frame_id": 16, + "backend": "oak_fcc3", + "frame_type": "MULTISPEC", + "capture_mode": "TRIPLE", + "output_dtype": "float32", + "dtype": "float32", + "output_layout": "CHW", + "payload_sources": [ + "cam2", + "cam0", + "cam1" + ], + "camera_info": { + "cam2": { + "id": "cam2", + "socket": "CAM_A", + "sensor": "OV9782", + "role": "rgb", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam0": { + "id": "cam0", + "socket": "CAM_B", + "sensor": "OV9282", + "role": "re", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam1": { + "id": "cam1", + "socket": "CAM_C", + "sensor": "OV9282", + "role": "nir", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + } + }, + "timestamps": { + "cam2": 205430.483298, + "cam0": 205430.406228, + "cam1": 205430.439549 + }, + "sync_dt_ms": 77.0699999993667, + "sync_ok": false, + "sync_tolerance_ms": 25.0, + "shapes": { + "cam2": [ + 800, + 1600 + ], + "cam0": [ + 800, + 1600 + ], + "cam1": [ + 800, + 1600 + ] + }, + "dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + }, + "codec_name": "none", + "codec_family": "none", + "dt_comp": 0.0, + "dt_send_payload_prev": 0.0, + "channels": [ + "R", + "G", + "B", + "RE", + "NIR" + ], + "fusion_applied": true, + "fusion_alignment_mode": "manual_affine", + "module_calibration_json": ".\\calibration\\module_params.json", + "tensor_shape": [ + 5, + 400, + 640 + ] + }, + "applied_camera_controls": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam2": { + "ae_enable": false, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ], + "ok": true + } + }, + "camera_params_json": ".\\calibration\\module_params.json", + "note": "manual", + "raw_preview_reference_camera": "cam2", + "saved_payload_type": "multispec", + "saved_payload_path": "20260504_211746_571.raw", + "saved_payload_dtype": "float32", + "saved_payload_shape": [ + 5, + 400, + 640 + ] +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211746_571.png b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211746_571.png new file mode 100644 index 000000000..6024e5254 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211746_571.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211746_571.raw b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211746_571.raw new file mode 100644 index 000000000..3f340ef86 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_211746_571.raw differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223732_542.json b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223732_542.json new file mode 100644 index 000000000..975b906d5 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223732_542.json @@ -0,0 +1,172 @@ +{ + "ts": "2026-05-04T22:37:32.539", + "cana": "baixa", + "horario": "cedo", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "fps_target": 20, + "frame_type": "MULTISPEC", + "capture_mode_requested": "TRIPLE", + "capture_mode_effective": "TRIPLE", + "raw_policy": "require_triple", + "stream_meta": { + "frame_id": 72, + "backend": "oak_fcc3", + "frame_type": "MULTISPEC", + "capture_mode": "TRIPLE", + "output_dtype": "float32", + "dtype": "float32", + "output_layout": "CHW", + "payload_sources": [ + "cam2", + "cam0", + "cam1" + ], + "camera_info": { + "cam2": { + "id": "cam2", + "socket": "CAM_A", + "sensor": "OV9782", + "role": "rgb", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam0": { + "id": "cam0", + "socket": "CAM_B", + "sensor": "OV9282", + "role": "re", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam1": { + "id": "cam1", + "socket": "CAM_C", + "sensor": "OV9282", + "role": "nir", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + } + }, + "timestamps": { + "cam2": 210216.453791, + "cam0": 210216.442723, + "cam1": 210216.376034 + }, + "sync_dt_ms": 77.757000020938, + "sync_ok": false, + "sync_tolerance_ms": 25.0, + "shapes": { + "cam2": [ + 800, + 1600 + ], + "cam0": [ + 800, + 1600 + ], + "cam1": [ + 800, + 1600 + ] + }, + "dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + }, + "codec_name": "none", + "codec_family": "none", + "dt_comp": 0.0, + "dt_send_payload_prev": 0.0, + "channels": [ + "R", + "G", + "B", + "RE", + "NIR" + ], + "shape": [ + 5, + 400, + 640 + ] + }, + "applied_camera_controls": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam2": { + "ae_enable": false, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ], + "ok": true + } + }, + "camera_params_json": ".\\calibration\\module_params.json", + "note": "manual", + "raw_preview_reference_camera": "cam2", + "saved_payload_type": "multispec", + "saved_payload_path": "20260504_223732_542.raw", + "saved_payload_dtype": "float32", + "saved_payload_shape": [ + 5, + 400, + 640 + ] +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223732_542.png b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223732_542.png new file mode 100644 index 000000000..d06eec6a0 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223732_542.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223732_542.raw b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223732_542.raw new file mode 100644 index 000000000..b2f7683df Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223732_542.raw differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700.json b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700.json new file mode 100644 index 000000000..5976e3587 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700.json @@ -0,0 +1,177 @@ +{ + "ts": "2026-05-04T22:37:47.700", + "cana": "baixa", + "horario": "cedo", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "fps_target": 20, + "frame_type": "RAW_BRUTO", + "capture_mode_requested": "TRIPLE", + "capture_mode_effective": "TRIPLE", + "raw_policy": "require_triple", + "stream_meta": { + "frame_id": 11, + "backend": "oak_fcc3", + "frame_type": "RAW_BRUTO", + "capture_mode": "TRIPLE", + "output_dtype": "float32", + "dtype": "float32", + "output_layout": "dict_by_camera", + "payload_sources": [ + "cam2", + "cam0", + "cam1" + ], + "camera_info": { + "cam2": { + "id": "cam2", + "socket": "CAM_A", + "sensor": "OV9782", + "role": "rgb", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam0": { + "id": "cam0", + "socket": "CAM_B", + "sensor": "OV9282", + "role": "re", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam1": { + "id": "cam1", + "socket": "CAM_C", + "sensor": "OV9282", + "role": "nir", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + } + }, + "timestamps": { + "cam2": 210231.566515, + "cam0": 210231.655628, + "cam1": 210231.555617 + }, + "sync_dt_ms": 100.0110000022687, + "sync_ok": false, + "sync_tolerance_ms": 25.0, + "shapes": { + "cam2": [ + 800, + 1600 + ], + "cam0": [ + 800, + 1600 + ], + "cam1": [ + 800, + 1600 + ] + }, + "dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + }, + "codec_name": "none", + "codec_family": "none", + "dt_comp": 0.0, + "dt_send_payload_prev": 0.0 + }, + "applied_camera_controls": { + "cam0": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam1": { + "ae_enable": false, + "awb_enable": false, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": null, + "ok": true + }, + "cam2": { + "ae_enable": false, + "awb_enable": true, + "exposure_time_us": 15000, + "analogue_gain": 1.0, + "colour_gains": [ + 1.0, + 1.0 + ], + "ok": true + } + }, + "camera_params_json": ".\\calibration\\module_params.json", + "note": "manual", + "raw_preview_reference_camera": "cam2", + "saved_payload_type": "raw_native_multi", + "saved_payload_paths": { + "cam2": "20260504_223747_700_cam2.bin", + "cam0": "20260504_223747_700_cam0.bin", + "cam1": "20260504_223747_700_cam1.bin" + }, + "saved_payload_shapes": { + "cam2": [ + 800, + 1600 + ], + "cam0": [ + 800, + 1600 + ], + "cam1": [ + 800, + 1600 + ] + }, + "saved_payload_dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + } +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700.png b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700.png new file mode 100644 index 000000000..a3c140d81 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700_cam0.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700_cam0.bin new file mode 100644 index 000000000..2caecff9b Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700_cam0.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700_cam1.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700_cam1.bin new file mode 100644 index 000000000..f1926bae3 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700_cam1.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700_cam2.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700_cam2.bin new file mode 100644 index 000000000..ea4bf4405 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260504/20260504_223747_700_cam2.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885.json b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885.json new file mode 100644 index 000000000..8f4727480 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885.json @@ -0,0 +1,149 @@ +{ + "ts": "2026-05-05T08:05:51.885", + "cana": "baixa", + "horario": "cedo", + "sensor_width": 640, + "sensor_height": 480, + "bayer_pattern": "GBRG", + "fps_target": 20, + "frame_type": "RAW_BRUTO", + "capture_mode_requested": "AUTO", + "capture_mode_effective": "AUTO", + "raw_policy": "allow_single", + "stream_meta": { + "frame_id": 124, + "backend": "oak_fcc3", + "frame_type": "RAW_BRUTO", + "capture_mode": "AUTO", + "output_dtype": "float32", + "dtype": "float32", + "output_layout": "dict_by_camera", + "payload_sources": [ + "cam2", + "cam0", + "cam1" + ], + "camera_info": { + "cam2": { + "id": "cam2", + "socket": "CAM_A", + "sensor": "OV9782", + "role": "rgb", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam0": { + "id": "cam0", + "socket": "CAM_B", + "sensor": "OV9282", + "role": "re", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + }, + "cam1": { + "id": "cam1", + "socket": "CAM_C", + "sensor": "OV9282", + "role": "nir", + "shape": [ + 800, + 1600 + ], + "dtype": "uint8", + "interface": "OAK_RAW", + "raw_format": "RAW10_PACKED", + "channels": 1, + "bit_depth": 10, + "height": 800, + "width": 1280, + "stride": 1600, + "packed_width": 1600, + "packed": true + } + }, + "timestamps": { + "cam2": 244316.809677, + "cam0": 244316.798187, + "cam1": 244316.798162 + }, + "sync_dt_ms": 11.51500002015382, + "sync_ok": true, + "sync_tolerance_ms": 25.0, + "shapes": { + "cam2": [ + 800, + 1600 + ], + "cam0": [ + 800, + 1600 + ], + "cam1": [ + 800, + 1600 + ] + }, + "dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + }, + "codec_name": "none", + "codec_family": "none", + "dt_comp": 0.0, + "dt_send_payload_prev": 0.0 + }, + "applied_camera_controls": {}, + "camera_params_json": "calibration/module_params.json", + "note": "manual", + "raw_preview_reference_camera": "cam2", + "saved_payload_type": "raw_native_multi", + "saved_payload_paths": { + "cam2": "20260505_080551_885_cam2.bin", + "cam0": "20260505_080551_885_cam0.bin", + "cam1": "20260505_080551_885_cam1.bin" + }, + "saved_payload_shapes": { + "cam2": [ + 800, + 1600 + ], + "cam0": [ + 800, + 1600 + ], + "cam1": [ + 800, + 1600 + ] + }, + "saved_payload_dtypes": { + "cam2": "uint8", + "cam0": "uint8", + "cam1": "uint8" + } +} \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885.png b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885.png new file mode 100644 index 000000000..178be8b9e Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885.png differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885_cam0.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885_cam0.bin new file mode 100644 index 000000000..63f3bb055 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885_cam0.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885_cam1.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885_cam1.bin new file mode 100644 index 000000000..e431e7d87 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885_cam1.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885_cam2.bin b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885_cam2.bin new file mode 100644 index 000000000..95a878506 Binary files /dev/null and b/Python/OAK/datasets/oak-fcc-3/dataset/brutas/cana_baixa/cedo/20260505/20260505_080551_885_cam2.bin differ diff --git a/Python/OAK/datasets/oak-fcc-3/oak_fcc3_client.py b/Python/OAK/datasets/oak-fcc-3/oak_fcc3_client.py deleted file mode 100644 index 7a4addba2..000000000 --- a/Python/OAK/datasets/oak-fcc-3/oak_fcc3_client.py +++ /dev/null @@ -1,391 +0,0 @@ -import numpy as np -import cv2 -import json -import os - -from oak_fcc3_service import OakFcc3Service - - -class OakFcc3Client: - def __init__( - self, - pi_host=None, - pc_host=None, - server_port=None, - stream_port=None, - width=640, - height=400, - bayer="GBRG", - fps=30, - frame_type="RAW_BRUTO", - output_dtype="uint8", - capture_mode="AUTO", - raw_policy="allow_single", - module_calibration_json=None, - radiometric_enabled=False, - sync_mode="best", - sync_tolerance_ms=25.0, - **kwargs, - ): - self.width = width - self.height = height - self.bayer = bayer - self.fps = fps - self.frame_type = frame_type - self.output_dtype = output_dtype - self.capture_mode = capture_mode - self.raw_policy = raw_policy - self.module_calibration_json = module_calibration_json - self.module_params = self._load_module_params(module_calibration_json) - self.fusion_config = self.module_params.get("fusion_config", {}) or {} - self.radiometric_enabled = radiometric_enabled - - self.svc = OakFcc3Service( - timeout=10, - fps=fps, - width=width, - height=height, - frame_type=frame_type, - output_dtype=output_dtype, - capture_mode=capture_mode, - raw_policy=raw_policy, - sync_mode=sync_mode, - sync_tolerance_ms=sync_tolerance_ms, - **kwargs, - ) - - self.applied_camera_controls = {} - self.radiometric_controller = None - - def __enter__(self): - self.start() - return self - - def __exit__(self, exc_type, exc, tb): - self.stop() - - def _load_module_params(self, path): - if not path or not os.path.isfile(path): - return {} - - with open(path, "r", encoding="utf-8") as f: - return json.load(f) - - def start(self, print_debug=False): - self.svc.connect() - - resp = self.svc.begin( - frame_type=self.frame_type, - output_dtype=self.output_dtype, - capture_mode=self.capture_mode, - ) - - if print_debug: - print("[OAK CLIENT] START:", resp) - - return resp - - def stop(self): - try: - self.svc.stop() - finally: - self.svc.disconnect() - - def get_status(self): - return self.svc.get_status() - - def get_next_frame(self, timeout=1.0): - return self.svc.capture_frame(timeout=timeout) - - def get_next_decoded(self, timeout=1.0, update_radiometry=True): - raw_frame, meta = self.get_next_frame(timeout=timeout) - - decoded = self.decode_stream_cameras(raw_frame, meta) - - frame_type = str(self.frame_type).upper() - - if frame_type == "RAW_BRUTO": - meta["output_layout"] = "dict_by_camera" - return raw_frame, meta, decoded - - if frame_type == "RGB": - tensor = self.build_rgb_tensor(decoded) - meta["frame_type"] = "RGB" - meta["output_layout"] = "CHW" - meta["channels"] = ["R", "G", "B"] - meta["dtype"] = "float32" - meta["output_dtype"] = "float32" - meta["tensor_shape"] = list(tensor.shape) - return tensor, meta, decoded - - if frame_type == "MULTISPEC": - tensor = self.build_multispec_tensor(decoded) - meta["frame_type"] = "MULTISPEC" - meta["output_layout"] = "CHW" - meta["channels"] = ["R", "G", "B", "RE", "NIR"] - meta["fusion_applied"] = True - meta["fusion_alignment_mode"] = self.fusion_config.get("alignment_mode", "identity") - meta["module_calibration_json"] = self.module_calibration_json - meta["dtype"] = "float32" - meta["output_dtype"] = "float32" - meta["tensor_shape"] = list(tensor.shape) - return tensor, meta, decoded - - raise RuntimeError(f"frame_type não suportado: {self.frame_type}") - - def build_rgb_tensor(self, decoded): - if "cam2" not in decoded: - raise RuntimeError("RGB exige cam2 disponível.") - - rgb01 = decoded["cam2"]["image"] - - if rgb01.ndim != 3 or rgb01.shape[2] != 3: - raise RuntimeError(f"cam2 RGB inválida: shape={rgb01.shape}") - - tensor = np.transpose(rgb01.astype(np.float32), (2, 0, 1)) - return np.ascontiguousarray(tensor) - - def build_multispec_tensor(self, decoded): - if "cam2" not in decoded: - raise RuntimeError("MULTISPEC exige cam2/RGB disponível.") - if "cam0" not in decoded: - raise RuntimeError("MULTISPEC exige cam0/RE disponível.") - if "cam1" not in decoded: - raise RuntimeError("MULTISPEC exige cam1/NIR disponível.") - - rgb01 = decoded["cam2"]["image"] - re01 = decoded["cam0"]["image"] - nir01 = decoded["cam1"]["image"] - - if rgb01.ndim != 3 or rgb01.shape[2] != 3: - raise RuntimeError(f"cam2 RGB inválida: shape={rgb01.shape}") - - h, w = rgb01.shape[:2] - - re01 = self._align_spectral_to_rgb(re01, "cam0", h, w) - nir01 = self._align_spectral_to_rgb(nir01, "cam1", h, w) - - r = rgb01[:, :, 0] - g = rgb01[:, :, 1] - b = rgb01[:, :, 2] - - tensor = np.stack( - [ - r, - g, - b, - re01, - nir01, - ], - axis=0, - ).astype(np.float32) - - return np.ascontiguousarray(tensor) - - @staticmethod - def _resize_gray_to(img01, h, w): - if img01 is None: - raise RuntimeError("Canal espectral ausente.") - - if img01.ndim == 3: - img01 = img01[:, :, 0] - - if img01.shape[:2] != (h, w): - img01 = cv2.resize(img01, (w, h), interpolation=cv2.INTER_LINEAR) - - return np.clip(img01.astype(np.float32), 0.0, 1.0) - - def _align_spectral_to_rgb(self, img01, cam_id, h, w): - if img01 is None: - raise RuntimeError(f"Canal ausente: {cam_id}") - - if img01.ndim == 3: - img01 = img01[:, :, 0] - - if img01.shape[:2] != (h, w): - img01 = cv2.resize(img01, (w, h), interpolation=cv2.INTER_LINEAR) - - cfg = self.fusion_config or {} - mode = cfg.get("alignment_mode", "identity") - - if mode == "identity": - return np.clip(img01.astype(np.float32), 0.0, 1.0) - - if mode == "manual_offset": - offs = cfg.get("manual_offsets", {}).get(cam_id, {}) - dx = int(offs.get("dx", 0)) - dy = int(offs.get("dy", 0)) - - M = np.float32([[1, 0, dx], [0, 1, dy]]) - - out = cv2.warpAffine( - img01, - M, - (w, h), - flags=cv2.INTER_LINEAR, - borderMode=cv2.BORDER_CONSTANT, - borderValue=0, - ) - - return np.clip(out.astype(np.float32), 0.0, 1.0) - - if mode == "manual_affine": - offs = cfg.get("manual_offsets", {}).get(cam_id, {}) - dx = int(offs.get("dx", 0)) - dy = int(offs.get("dy", 0)) - theta_deg = float(offs.get("theta_deg", 0.0)) - - center = (w * 0.5, h * 0.5) - M = cv2.getRotationMatrix2D(center, theta_deg, 1.0) - M[0, 2] += dx - M[1, 2] += dy - - out = cv2.warpAffine( - img01, - M, - (w, h), - flags=cv2.INTER_LINEAR, - borderMode=cv2.BORDER_CONSTANT, - borderValue=0, - ) - - return np.clip(out.astype(np.float32), 0.0, 1.0) - - if mode == "homography": - H = cfg.get("homographies", {}).get(f"{cam_id}_to_cam2") - - if H is None: - return np.clip(img01.astype(np.float32), 0.0, 1.0) - - H = np.asarray(H, dtype=np.float32) - - if H.shape != (3, 3): - raise RuntimeError(f"Homografia inválida para {cam_id}: shape={H.shape}") - - out = cv2.warpPerspective( - img01, - H, - (w, h), - flags=cv2.INTER_LINEAR, - borderMode=cv2.BORDER_CONSTANT, - borderValue=0, - ) - - return np.clip(out.astype(np.float32), 0.0, 1.0) - - raise RuntimeError(f"alignment_mode inválido: {mode}") - - def decode_stream_cameras(self, frame, meta): - """ - Compatível com os calibradores antigos. - - Retorna: - decoded["cam2"]["image"] = RGB float32 HWC [0..1] - decoded["cam0"]["image"] = RE float32 HW [0..1] - decoded["cam1"]["image"] = NIR float32 HW [0..1] - """ - decoded = {} - - if not isinstance(frame, dict): - raise RuntimeError("OakFcc3Client espera frame como dict por câmera.") - - camera_info = meta.get("camera_info", {}) or {} - - for cam_id, img in frame.items(): - info = camera_info.get(cam_id, {}) or {} - role = info.get("role", cam_id) - - img01 = self._frame_to_float01(cam_id, img, role) - - if role == "rgb": - name = "RGB" - elif role == "re": - name = "RE" - elif role == "nir": - name = "NIR" - else: - name = role.upper() - - decoded[cam_id] = { - "name": name, - "role": role, - "image": img01, - "meta": { - "cam_id": cam_id, - "role": role, - "socket": info.get("socket"), - "sensor": info.get("sensor"), - "timestamp": (meta.get("timestamps") or {}).get(cam_id), - "shape": list(img.shape), - "dtype": str(img.dtype), - }, - } - - return decoded - - def build_preview_from_raw_payload(self, frame, meta): - """ - Usado pelo capture antigo. - Retorna: - preview_bgr - payload_float_preview - preview_source_id - """ - decoded = self.decode_stream_cameras(frame, meta) - - if "cam2" in decoded: - rgb01 = decoded["cam2"]["image"] - preview_bgr = self._rgb01_to_bgr(rgb01) - return preview_bgr, rgb01.copy(), "cam2" - - first_id = list(decoded.keys())[0] - img01 = decoded[first_id]["image"] - - if img01.ndim == 2: - preview_bgr = self._gray01_to_bgr(img01) - else: - preview_bgr = self._rgb01_to_bgr(img01) - - return preview_bgr, img01.copy(), first_id - - def _frame_to_float01(self, cam_id, img, role): - if img is None: - return None - - arr = img - - if arr.dtype == np.uint8: - arr01 = arr.astype(np.float32) / 255.0 - elif arr.dtype == np.uint16: - arr01 = arr.astype(np.float32) / 65535.0 - else: - arr01 = arr.astype(np.float32) - if arr01.max() > 1.5: - arr01 = arr01 / 255.0 - - arr01 = np.clip(arr01, 0.0, 1.0) - - if role == "rgb": - # DepthAI/OpenCV entrega BGR HWC. Calibradores esperam RGB HWC. - if arr01.ndim == 3 and arr01.shape[2] == 3: - arr01 = cv2.cvtColor((arr01 * 255).astype(np.uint8), cv2.COLOR_BGR2RGB).astype(np.float32) / 255.0 - elif arr01.ndim == 2: - arr01 = np.stack([arr01, arr01, arr01], axis=2) - - return arr01 - - # Espectrais devem virar mono HW. - if arr01.ndim == 3: - arr01 = cv2.cvtColor((arr01 * 255).astype(np.uint8), cv2.COLOR_BGR2GRAY).astype(np.float32) / 255.0 - - return arr01 - - @staticmethod - def _rgb01_to_bgr(rgb01): - rgb_u8 = np.clip(rgb01 * 255.0, 0, 255).astype(np.uint8) - return cv2.cvtColor(rgb_u8, cv2.COLOR_RGB2BGR) - - @staticmethod - def _gray01_to_bgr(gray01): - g = np.clip(gray01 * 255.0, 0, 255).astype(np.uint8) - return cv2.cvtColor(g, cv2.COLOR_GRAY2BGR) \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/oak_fcc3_service.py b/Python/OAK/datasets/oak-fcc-3/oak_fcc3_service.py deleted file mode 100644 index 72fc38389..000000000 --- a/Python/OAK/datasets/oak-fcc-3/oak_fcc3_service.py +++ /dev/null @@ -1,133 +0,0 @@ -import time -from oak_fcc3_manager import OakFcc3Manager - - -class OakFcc3Service: - def __init__(self, timeout=10, **kwargs): - self.timeout = timeout - self.manager = OakFcc3Manager(**kwargs) - self.connected = False - - def connect(self): - self.connected = True - return {"ok": True, "backend": "oak_fcc3", "connected": True} - - def disconnect(self): - self.stop() - self.connected = False - return {"ok": True, "connected": False} - - def ping(self): - return { - "ok": True, - "backend": "oak_fcc3", - "msg": "pong", - "ts": time.time(), - } - - def get_status(self): - status = self.manager.get_status() - active_ids = [c["id"] for c in status.get("cameras", [])] - - status.update({ - "ok": True, - "connected": self.connected, - "active_camera_ids": active_ids, - "camera_count_active": len(active_ids), - }) - - return status - - def get_config(self): - return { - "ok": True, - "fps": self.manager.fps, - "width": self.manager.width, - "height": self.manager.height, - "frame_type": self.manager.frame_type, - "output_dtype": self.manager.output_dtype, - "capture_mode": self.manager.capture_mode, - "raw_policy": self.manager.raw_policy, - "sync_mode": getattr(self.manager, "sync_mode", "best"), - "sync_tolerance_ms": self.manager.sync_tolerance_ms, - } - - def set_fps(self, fps): - self._ensure_stopped_for_config() - self.manager.fps = int(fps) - return {"ok": True, "fps": self.manager.fps} - - def set_resolution(self, width, height): - self._ensure_stopped_for_config() - self.manager.width = int(width) - self.manager.height = int(height) - self.manager.size = (self.manager.width, self.manager.height) - return { - "ok": True, - "width": self.manager.width, - "height": self.manager.height, - } - - def set_capture_mode(self, mode): - self._ensure_stopped_for_config() - mode = str(mode).upper() - if mode not in ("AUTO", "SINGLE", "DOUBLE", "TRIPLE"): - raise ValueError(f"capture_mode inválido: {mode}") - - self.manager.capture_mode = mode - return {"ok": True, "capture_mode": self.manager.capture_mode} - - def set_frame_type(self, frame_type): - self._ensure_stopped_for_config() - frame_type = str(frame_type).upper() - if frame_type not in ("RAW_BRUTO", "RGB", "MULTISPEC"): - raise ValueError(f"frame_type inválido: {frame_type}") - - self.manager.frame_type = frame_type - return {"ok": True, "frame_type": self.manager.frame_type} - - def set_output_dtype(self, dtype): - self._ensure_stopped_for_config() - dtype = str(dtype).lower() - if dtype not in ("uint8", "uint16", "float32"): - raise ValueError(f"output_dtype inválido: {dtype}") - - self.manager.output_dtype = dtype - return {"ok": True, "output_dtype": self.manager.output_dtype} - - def begin(self, frame_type=None, output_dtype=None, capture_mode=None): - if frame_type is not None: - self.set_frame_type(frame_type) - - if output_dtype is not None: - self.set_output_dtype(output_dtype) - - if capture_mode is not None: - self.set_capture_mode(capture_mode) - - self.manager.start() - - return { - "ok": True, - "started": True, - "status": self.get_status(), - } - - def capture_frame(self, timeout=None): - if timeout is None: - timeout = self.timeout - - frame, meta = self.manager.get_next_frame(timeout=timeout) - - return frame, meta - - def stop(self): - self.manager.stop() - return {"ok": True, "stopped": True} - - def _ensure_stopped_for_config(self): - if self.manager.running: - raise RuntimeError( - "Configuração estrutural só pode ser alterada com o manager parado. " - "Chame stop() antes." - ) \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/test_manager.py b/Python/OAK/datasets/oak-fcc-3/test_manager.py deleted file mode 100644 index 48b1251cc..000000000 --- a/Python/OAK/datasets/oak-fcc-3/test_manager.py +++ /dev/null @@ -1,35 +0,0 @@ -import cv2 -from oak_fcc3_manager import OakFcc3Manager - -with OakFcc3Manager( - fps=30, - width=640, - height=400, - capture_mode="AUTO", - raw_policy="allow_single", - sync_mode="best", - sync_tolerance_ms=10.0, - buffer_size=12, -) as cam: - - print(cam.get_status()) - - while True: - frame, meta, decoded = cam.get_next_decoded(timeout=1.0) - - print( - "frame_id:", meta["frame_id"], - "sources:", meta["payload_sources"], - "sync_ms:", f"{meta['sync_dt_ms']:.2f}", - "sync_ok:", meta["sync_ok"] - ) - - for cam_id, img in frame.items(): - info = meta["camera_info"].get(cam_id, {}) - title = f"{cam_id} | {info.get('socket')} | {info.get('role')}" - cv2.imshow(title, img) - - if cv2.waitKey(1) in (27, ord("q")): - break - -cv2.destroyAllWindows() \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/test_oak_fcc3_client.py b/Python/OAK/datasets/oak-fcc-3/test_oak_fcc3_client.py deleted file mode 100644 index 95c83a456..000000000 --- a/Python/OAK/datasets/oak-fcc-3/test_oak_fcc3_client.py +++ /dev/null @@ -1,48 +0,0 @@ -import cv2 - -from oak_fcc3_client import OakFcc3Client - - -with OakFcc3Client( - fps=15, - width=640, - height=400, - frame_type="RAW_BRUTO", - output_dtype="uint8", - capture_mode="AUTO", - raw_policy="allow_single", - sync_mode="best", - sync_tolerance_ms=25.0, - module_calibration_json="calibration/module_params.json", -) as cam: - - print("STATUS:", cam.get_status()) - - while True: - frame, meta, decoded = cam.get_next_decoded(timeout=2.0) - - print( - "frame_id:", meta["frame_id"], - "sources:", meta["payload_sources"], - "decoded:", list(decoded.keys()), - "sync_ms:", f"{meta.get('sync_dt_ms', 0):.2f}", - "sync_ok:", meta.get("sync_ok"), - ) - - if "cam2" in decoded: - rgb01 = decoded["cam2"]["image"] - rgb_bgr = cv2.cvtColor((rgb01 * 255).astype("uint8"), cv2.COLOR_RGB2BGR) - cv2.imshow("cam2 RGB decoded", rgb_bgr) - - if "cam0" in decoded: - re01 = decoded["cam0"]["image"] - cv2.imshow("cam0 RE decoded", (re01 * 255).astype("uint8")) - - if "cam1" in decoded: - nir01 = decoded["cam1"]["image"] - cv2.imshow("cam1 NIR decoded", (nir01 * 255).astype("uint8")) - - if cv2.waitKey(1) in (27, ord("q")): - break - -cv2.destroyAllWindows() \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/tests/__init__.py b/Python/OAK/datasets/oak-fcc-3/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Python/OAK/datasets/oak-fcc-3/tests/test.py b/Python/OAK/datasets/oak-fcc-3/tests/test.py new file mode 100644 index 000000000..77a9ad01c --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/tests/test.py @@ -0,0 +1,37 @@ +from core.oak_fcc3_service import OakFcc3Service + +svc = OakFcc3Service( + fps=15, + width=640, + height=400, + frame_type="MULTISPEC", + capture_mode="TRIPLE", + raw_policy="require_triple", + sync_mode="best", + sync_tolerance_ms=25.0, +) + +svc.connect() +svc.begin(frame_type="RAW_BRUTO", output_dtype="uint8", capture_mode="TRIPLE") + +frame, meta = svc.capture_frame(timeout=2.0) + +print(meta["camera_info"]) +for cam_id, arr in frame.items(): + print(cam_id, arr.shape, arr.dtype, arr.size) + +from core.raw_processor_core import RawProcessorCore +from core.raw_processor_preview import RawProcessorPreview +import cv2 + +core = RawProcessorCore(sensor_width=1280, sensor_height=800, bayer_pattern="GBRG") +preview = RawProcessorPreview(sensor_width=1280, sensor_height=800, bayer_pattern="GBRG") + +raw16 = core.unpack_raw10_packed(frame["cam0"], sensor_width=1280, sensor_height=800) +img = preview.raw16_to_preview_bgr(raw16, bit_depth=10) + +cv2.imwrite("calibration/cam0_raw_preview.png", img) +print(raw16.shape, raw16.dtype, raw16.min(), raw16.max()) + +svc.stop() +svc.disconnect() \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/test_captude_mode.py b/Python/OAK/datasets/oak-fcc-3/tests/test_capture_mode.py similarity index 63% rename from Python/OAK/datasets/oak-fcc-3/test_captude_mode.py rename to Python/OAK/datasets/oak-fcc-3/tests/test_capture_mode.py index 313bbbfc6..5a8f997f7 100644 --- a/Python/OAK/datasets/oak-fcc-3/test_captude_mode.py +++ b/Python/OAK/datasets/oak-fcc-3/tests/test_capture_mode.py @@ -1,4 +1,4 @@ -from oak_fcc3_client import OakFcc3Client +from core.oak_fcc3_client import OakFcc3Client for frame_type in ["RAW_BRUTO", "RGB", "MULTISPEC"]: print("\nTESTANDO:", frame_type) @@ -20,4 +20,10 @@ for frame_type in ["RAW_BRUTO", "RGB", "MULTISPEC"]: print("layout:", meta.get("output_layout")) print("channels:", meta.get("channels")) print("shape:", getattr(frame, "shape", None)) - print("dtype:", getattr(frame, "dtype", None)) \ No newline at end of file + print("dtype:", getattr(frame, "dtype", None)) + print("payload_sources:", meta.get("payload_sources")) + print("active_roles:", cam.get_status().get("active_roles")) + print("decoded_roles:", { + cam_id: item.get("role") + for cam_id, item in decoded.items() + }) \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/tests/test_oak_fcc3_client.py b/Python/OAK/datasets/oak-fcc-3/tests/test_oak_fcc3_client.py new file mode 100644 index 000000000..c133ed9db --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/tests/test_oak_fcc3_client.py @@ -0,0 +1,44 @@ +import cv2 + +from core.oak_fcc3_client import OakFcc3Client + + +with OakFcc3Client( + fps=15, + width=640, + height=400, + frame_type="RAW_BRUTO", + output_dtype="uint8", + capture_mode="AUTO", + raw_policy="require_triple", + sync_mode="best", + sync_tolerance_ms=25.0, + #module_calibration_json="calibration/module_params.json", + #radiometric_enabled=False +) as cam: + print("STATUS:", cam.get_status()) + + while True: + previews, meta = cam.get_next_preview(timeout=2.0) + + print( + "frame_id:", meta["frame_id"], + "sources:", meta["payload_sources"], + "sync_ms:", f"{meta.get('sync_dt_ms', 0):.2f}", + "sync_ok:", meta.get("sync_ok"), + ) + + camera_info = meta.get("camera_info", {}) or {} + + for cam_id, preview in previews.items(): + info = camera_info.get(cam_id, {}) or {} + role = info.get("role", "unknown") + sensor = info.get("sensor", "") + + title = f"{cam_id} | {role.upper()} | {sensor}" + cv2.imshow(title, preview) + + if cv2.waitKey(1) in (27, ord("q")): + break + +cv2.destroyAllWindows() \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/tests/test_oak_fcc3_controls.py b/Python/OAK/datasets/oak-fcc-3/tests/test_oak_fcc3_controls.py new file mode 100644 index 000000000..8eb491787 --- /dev/null +++ b/Python/OAK/datasets/oak-fcc-3/tests/test_oak_fcc3_controls.py @@ -0,0 +1,50 @@ +import time +import cv2 +import numpy as np + +from core.oak_fcc3_client import OakFcc3Client + + +with OakFcc3Client( + fps=15, + width=640, + height=400, + frame_type="RAW_BRUTO", + output_dtype="uint8", + capture_mode="AUTO", + raw_policy="allow_single", + sync_mode="best", + sync_tolerance_ms=25.0, +) as cam: + + print("STATUS:", cam.get_status()) + + print("CTRL rgb:", cam.svc.get_camera_controls(role="rgb")) + print("CTRL nir:", cam.svc.get_camera_controls(role="nir")) + print("CTRL re:", cam.svc.get_camera_controls(role="re")) + + print("SET rgb AE OFF:", cam.svc.set_ae_enable(role="rgb", enable=False)) + print("SET rgb EXP:", cam.svc.set_exposure_time(role="rgb", exposure_time_us=8000)) + print("SET rgb GAIN:", cam.svc.set_analogue_gain(role="rgb", analogue_gain=1.5)) + + print("SET nir EXP:", cam.svc.set_exposure_time(role="nir", exposure_time_us=12000)) + print("SET re EXP:", cam.svc.set_exposure_time(role="re", exposure_time_us=12000)) + + while True: + frame, meta, decoded = cam.get_next_decoded(timeout=2.0) + + for cam_id, item in decoded.items(): + img = item["image"] + + if img.ndim == 3: + show = cv2.cvtColor((img * 255).astype(np.uint8), cv2.COLOR_RGB2BGR) + else: + show = (img * 255).astype(np.uint8) + + role = item.get("role", cam_id) + cv2.imshow(f"{cam_id} | {role.upper()}", show) + + if cv2.waitKey(1) in (27, ord("q")): + break + +cv2.destroyAllWindows() \ No newline at end of file diff --git a/Python/OAK/datasets/oak-fcc-3/test_oak_fcc3_service.py b/Python/OAK/datasets/oak-fcc-3/tests/test_oak_fcc3_service.py similarity index 79% rename from Python/OAK/datasets/oak-fcc-3/test_oak_fcc3_service.py rename to Python/OAK/datasets/oak-fcc-3/tests/test_oak_fcc3_service.py index d1df5f1ab..e440de3dd 100644 --- a/Python/OAK/datasets/oak-fcc-3/test_oak_fcc3_service.py +++ b/Python/OAK/datasets/oak-fcc-3/tests/test_oak_fcc3_service.py @@ -2,7 +2,7 @@ import time import cv2 import numpy as np -from oak_fcc3_service import OakFcc3Service +from core.oak_fcc3_service import OakFcc3Service svc = OakFcc3Service(timeout=10) @@ -60,9 +60,15 @@ finally: if last_frame is not None: - if isinstance(last_frame, dict) and "cam2" in last_frame: - cv2.imwrite("calibration/capture_cam2.jpg", last_frame["cam2"]) - print("[OK] Salvo: calibration/capture_cam2.jpg") + if isinstance(last_frame, dict): + camera_info = (last_meta or {}).get("camera_info", {}) or {} + + for cam_id, arr in last_frame.items(): + role = camera_info.get(cam_id, {}).get("role", "unknown") + path = f"calibration/capture_{cam_id}_{role}.bin" + + arr.tofile(path) + print(f"[OK] Salvo: {path}") elif isinstance(last_frame, dict): first_id = list(last_frame.keys())[0] diff --git a/Python/OAK/datasets/oak-fcc-3/utils/__init__.py b/Python/OAK/datasets/oak-fcc-3/utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/Python/OAK/datasets/oak-fcc-3/build_module_params.py b/Python/OAK/datasets/oak-fcc-3/utils/build_module_params.py similarity index 100% rename from Python/OAK/datasets/oak-fcc-3/build_module_params.py rename to Python/OAK/datasets/oak-fcc-3/utils/build_module_params.py diff --git a/Python/OAK/datasets/oak-fcc-3/check_saved_files.py b/Python/OAK/datasets/oak-fcc-3/utils/check_saved_files.py similarity index 95% rename from Python/OAK/datasets/oak-fcc-3/check_saved_files.py rename to Python/OAK/datasets/oak-fcc-3/utils/check_saved_files.py index 92237d376..1ddafc041 100644 --- a/Python/OAK/datasets/oak-fcc-3/check_saved_files.py +++ b/Python/OAK/datasets/oak-fcc-3/utils/check_saved_files.py @@ -6,8 +6,8 @@ from pathlib import Path import cv2 import numpy as np -from cam_3.pi.raw_processor_core import RawProcessorCore -from cam_3.pi.raw_processor_preview import RawProcessorPreview +from core.raw_processor_core import RawProcessorCore +from core.raw_processor_preview import RawProcessorPreview def load_json(path: Path) -> dict: @@ -129,13 +129,32 @@ def build_visual_from_saved_payload(payload_path: Path, meta: dict, cam_id: str return preview_bgr, desc if saved_type == "multispec": - if arr.ndim != 3 or arr.shape[0] < 3: + if arr.ndim != 3 or arr.shape[0] < 5: raise RuntimeError(f"Payload MULTISPEC inválido, shape={arr.shape}") rgb_hwc = chw_to_hwc(arr[:3].astype(np.float32)) preview_bgr = normalize_float01_to_bgr(rgb_hwc) - desc = f"Reconstruido de MULTISPEC salvo | dtype={arr.dtype} | shape={arr.shape}" - return preview_bgr, desc + + re01 = arr[3].astype(np.float32) + nir01 = arr[4].astype(np.float32) + + re_bgr = cv2.cvtColor( + np.clip(re01 * 255.0, 0, 255).astype(np.uint8), + cv2.COLOR_GRAY2BGR + ) + + nir_bgr = cv2.cvtColor( + np.clip(nir01 * 255.0, 0, 255).astype(np.uint8), + cv2.COLOR_GRAY2BGR + ) + + combined = np.vstack([ + np.hstack([preview_bgr, re_bgr]), + np.hstack([nir_bgr, np.zeros_like(preview_bgr)]) + ]) + + desc = f"Reconstruido de MULTISPEC | dtype={arr.dtype} | shape={arr.shape} | canais=[R,G,B,RE,NIR]" + return combined, desc if saved_type == "raw_native_single": if arr.ndim == 3 and arr.shape[2] == 3 and arr.dtype == np.uint8: diff --git a/Python/OAK/datasets/oak-fcc-3/manual_fusion_calibrator.py b/Python/OAK/datasets/oak-fcc-3/utils/manual_fusion_calibrator.py similarity index 92% rename from Python/OAK/datasets/oak-fcc-3/manual_fusion_calibrator.py rename to Python/OAK/datasets/oak-fcc-3/utils/manual_fusion_calibrator.py index 4efa19039..fe9efd9d0 100644 --- a/Python/OAK/datasets/oak-fcc-3/manual_fusion_calibrator.py +++ b/Python/OAK/datasets/oak-fcc-3/utils/manual_fusion_calibrator.py @@ -7,7 +7,7 @@ from datetime import datetime import cv2 import numpy as np -from oak_fcc3_client import OakFcc3Client as MultiSpectralClient +from core.oak_fcc3_client import OakFcc3Client as MultiSpectralClient # ============================================================ @@ -173,11 +173,12 @@ def validate_module_ready(status: dict, frame_type: str, raw_policy: str, captur raise RuntimeError(f"Status inválido retornado pelo módulo: {status}") active_ids = list(status.get("active_camera_ids", [])) + active_roles = status.get("active_roles", {}) or {} active_count = int(status.get("camera_count_active", 0)) if frame_type == "RAW_BRUTO": if raw_policy == "require_triple": - missing = [cid for cid in ("cam0", "cam1", "cam2") if cid not in active_ids] + missing = [role for role in ("rgb", "nir", "re") if role not in active_roles] if missing: raise RuntimeError( f"RAW_BRUTO com política require_triple exige três câmeras ativas. " @@ -199,9 +200,6 @@ def default_offsets_payload(args, effective_capture_mode: str): return { "schema": "manual_multispec_offsets_v1", "saved_at": now_str(), - "pi_host": args.pi_host, - "pc_host": args.pc_host, - "stream_port": args.stream_port, "frame_type": "RAW_BRUTO", "capture_mode_requested": args.capture_mode, "capture_mode_effective": effective_capture_mode, @@ -209,16 +207,16 @@ def default_offsets_payload(args, effective_capture_mode: str): "sensor_width": args.width, "sensor_height": args.height, "bayer_pattern": args.bayer, - "reference_camera": "cam2", "baseline_mm": args.baseline_mm, "alignment_mode": "manual_affine", + "reference_camera": "rgb", "manual_offsets": { - "cam0": {"dx": 0, "dy": 0, "theta_deg": 0.0}, - "cam1": {"dx": 0, "dy": 0, "theta_deg": 0.0}, + "re": {"dx": 0, "dy": 0, "theta_deg": 0.0}, + "nir": {"dx": 0, "dy": 0, "theta_deg": 0.0}, }, "homographies": { - "cam0_to_cam2": None, - "cam1_to_cam2": None, + "re_to_rgb": None, + "nir_to_rgb": None, }, "notes": args.notes or "", } @@ -232,15 +230,13 @@ def load_offsets_json(path: str, args, effective_capture_mode: str): data = json.load(f) data.setdefault("schema", "manual_multispec_offsets_v1") - data.setdefault("reference_camera", "cam2") data.setdefault("baseline_mm", args.baseline_mm) data.setdefault("alignment_mode", "manual_affine") - data.setdefault("manual_offsets", {}) - data["manual_offsets"].setdefault("cam0", {"dx": 0, "dy": 0, "theta_deg": 0.0}) - data["manual_offsets"].setdefault("cam1", {"dx": 0, "dy": 0, "theta_deg": 0.0}) - data.setdefault("homographies", {}) - data["homographies"].setdefault("cam0_to_cam2", None) - data["homographies"].setdefault("cam1_to_cam2", None) + data.setdefault("reference_camera", "rgb") + data["manual_offsets"].setdefault("re", {"dx": 0, "dy": 0, "theta_deg": 0.0}) + data["manual_offsets"].setdefault("nir", {"dx": 0, "dy": 0, "theta_deg": 0.0}) + data["homographies"].setdefault("re_to_rgb", None) + data["homographies"].setdefault("nir_to_rgb", None) return data @@ -252,6 +248,14 @@ def save_offsets_json(path: str, data: dict): json.dump(data, f, ensure_ascii=False, indent=2) +def get_decoded_by_role(decoded, role): + role = str(role).lower() + for cam_id, item in decoded.items(): + if str(item.get("role", "")).lower() == role: + return cam_id, item + return None, None + + # ============================================================ # Main UI # ============================================================ @@ -261,10 +265,6 @@ def main(): description="Calibrador manual de offsets para fusão RGB/RE/NIR a partir do stream RAW_BRUTO.", formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) - parser.add_argument("--pi_host", default="192.168.105.6") - parser.add_argument("--pc_host", default="192.168.105.5") - parser.add_argument("--stream_port", type=int, default=6001) - parser.add_argument("--server_port", type=int, default=5000) parser.add_argument("--fps", type=int, default=20) parser.add_argument("--width", type=int, default=640) parser.add_argument("--height", type=int, default=480) @@ -327,23 +327,22 @@ def main(): offsets_data = load_offsets_json(args.load_json, args, effective_capture_mode) offsets = offsets_data["manual_offsets"] - selected_cam = "cam0" + selected_role = "re" calibration_mode = offsets_data.get("alignment_mode", "manual_affine") selected_points_spec = { - "cam0": [], - "cam1": [], + "re": [], + "nir": [], } selected_points_rgb = { - "cam0": [], - "cam1": [], + "re": [], + "nir": [], } - panel_rects = { "fuse": None, "rgb": None, - "cam0": None, - "cam1": None, + "re": None, + "nir": None, } last_msg = "" last_msg_t = 0.0 @@ -363,10 +362,6 @@ def main(): try: with MultiSpectralClient( - pi_host=args.pi_host, - pc_host=args.pc_host, - server_port=args.server_port, - stream_port=args.stream_port, width=args.width, height=args.height, bayer=args.bayer, @@ -376,6 +371,7 @@ def main(): capture_mode=effective_capture_mode, raw_policy=args.raw_policy, module_calibration_json=None, + radiometric_enabled=True ) as cam: while True: t0 = time.time() @@ -409,9 +405,13 @@ def main(): t_view_fps = time.time() if decoded_last: - rgb01 = decoded_last.get("cam2", {}).get("image") - re01 = decoded_last.get("cam0", {}).get("image") - nir01 = decoded_last.get("cam1", {}).get("image") + rgb_id, rgb_item = get_decoded_by_role(decoded_last, "rgb") + re_id, re_item = get_decoded_by_role(decoded_last, "re") + nir_id, nir_item = get_decoded_by_role(decoded_last, "nir") + + rgb01 = rgb_item.get("image") if rgb_item else None + re01 = re_item.get("image") if re_item else None + nir01 = nir_item.get("image") if nir_item else None if rgb01 is None: # fallback para exibição quando não houver RGB @@ -432,13 +432,13 @@ def main(): re_panel = gray_to_color_bgr(re01, "RE") if re01 is not None else build_empty_panel_like(rgb_panel, "RE") nir_panel = gray_to_color_bgr(nir01, "NIR") if nir01 is not None else build_empty_panel_like(rgb_panel, "NIR") - active_spec_name = "RE" if selected_cam == "cam0" else "NIR" - active_spec = re01 if selected_cam == "cam0" else nir01 - dx = int(offsets.get(selected_cam, {}).get("dx", 0)) - dy = int(offsets.get(selected_cam, {}).get("dy", 0)) - theta_deg = float(offsets.get(selected_cam, {}).get("theta_deg", 0.0)) + active_spec_name = "RE" if selected_role == "cam0" else "NIR" + active_spec = re01 if selected_role == "cam0" else nir01 + dx = int(offsets.get(selected_role, {}).get("dx", 0)) + dy = int(offsets.get(selected_role, {}).get("dy", 0)) + theta_deg = float(offsets.get(selected_role, {}).get("theta_deg", 0.0)) - H_key = f"{selected_cam}_to_cam2" + H_key = f"{selected_role}_to_cam2" H = offsets_data.get("homographies", {}).get(H_key) fuse_panel = build_overlay_fuse( diff --git a/Python/OAK/datasets/oak-fcc-3/sensor_calibration_tool.py b/Python/OAK/datasets/oak-fcc-3/utils/sensor_calibration_tool.py similarity index 98% rename from Python/OAK/datasets/oak-fcc-3/sensor_calibration_tool.py rename to Python/OAK/datasets/oak-fcc-3/utils/sensor_calibration_tool.py index b22b57cf5..47ec11075 100644 --- a/Python/OAK/datasets/oak-fcc-3/sensor_calibration_tool.py +++ b/Python/OAK/datasets/oak-fcc-3/utils/sensor_calibration_tool.py @@ -7,7 +7,7 @@ from datetime import datetime import cv2 import numpy as np -from cam_3.multispectral_client import MultiSpectralClient +from core.oak_fcc3_client import OakFcc3Client as MultiSpectralClient # ============================================================ # Helpers @@ -444,9 +444,6 @@ def default_payload(args, effective_capture_mode: str): return { "schema": "manual_sensor_calibration_v1", "saved_at": now_str(), - "pi_host": args.pi_host, - "pc_host": args.pc_host, - "stream_port": args.stream_port, "frame_type": "RAW_BRUTO", "capture_mode_requested": args.capture_mode, "capture_mode_effective": effective_capture_mode, @@ -750,10 +747,6 @@ def main(): description="Ferramenta de calibração dos sensores RGB/RE/NIR com controle manual e ROIs em tempo real.", formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) - parser.add_argument("--pi_host", default="192.168.105.6") - parser.add_argument("--pc_host", default="192.168.105.5") - parser.add_argument("--stream_port", type=int, default=6001) - parser.add_argument("--server_port", type=int, default=5000) parser.add_argument("--fps", type=int, default=20) parser.add_argument("--width", type=int, default=640) parser.add_argument("--height", type=int, default=480) @@ -775,10 +768,6 @@ def main(): args = parser.parse_args() cam = MultiSpectralClient( - pi_host=args.pi_host, - pc_host=args.pc_host, - server_port=args.server_port, - stream_port=args.stream_port, width=args.width, height=args.height, bayer=args.bayer, @@ -788,6 +777,7 @@ def main(): capture_mode=args.capture_mode, raw_policy=args.raw_policy, module_calibration_json=None, + radiometric_enabled=True ) offline_mode = bool(args.offline_sample_json)