Ë
    &üÝjÈ  ã                  ó^  — d Z ddlmZ ddlZddlZddlZddlZddlZddlm	Z	  e	e
«      j                  «       j                  d   ZdZdZdZd	Zg d
edz   ddddgf‘dedz   ddddgf‘dedz   ddddgf‘dedz   ddddgf‘dedz   ddddgf‘d edz   d!dd"d#gf‘d$edz   d%dd&d'gf‘d(edz   d)d*d+d,gf‘d-edz   d.d/d0d,gf‘d1edz   d2dd3d4gf‘d5edz   d6dd7d8gf‘d9edz   d:dd;d<gf‘d=edz   d>d?d@dAgf‘dBedz   dCdDdEdFgf‘dGedHz   dIdDdJdKdLgf‘dMedHz   dNdDdOdPdQgf‘dRedHz   dSddTdUgf‘dVedHz   dWddXdYgf‘dZed[z   d\d]d^g d_¢f‘d`ed[z   dadbdcdddegf‘dfed[z   dgdhdidjgf‘dkedlz   dmdndodpgf‘dqedlz   drdsdtdugf‘dvedlz   dwdxdydzgf‘d{edHz   d|d}d~dgf‘d€edHz   d�dd‚dƒgf‘d„ed…z   d†dd‡dˆd‰gf‘dŠed‹z   dŒd�dŽd�d�gf‘d‘edHz   d’d“d”d•d–gf‘d—ed˜z   d™ddšd›gf‘dœedHz   d�ddždŸgf‘d edHz   d¡d¢d£d¤gf‘d¥edHz   d¦d§d¨d©gf‘dªed«z   d¬d­d®d¯gf‘d°ed«z   d±dDd²d³gf‘d´ed«z   dµd¶d·d¸gf‘d¹ed«z   dºd»d¼d½gf‘d¾ed¿z   dÀd»dÁdÂgf‘dÃedÄz   dÅdÆdÇdÈdÉgf‘dÊedËz   dÌdÍdÎdÏgf‘dÐedËz   dÑdDdÒdÓgf‘dÔedHz   dÕdÖd×dØgf‘dÙedÚz   dÛddÜdÝgf‘dÞedßz   dàdDdádâgf‘dãedlz   dädådædçdègf‘déedHz   dêd»dëdìdígf‘dîedïz   dðdñdòdógf‘dôedïz   dõdöd÷døgf‘dùedïz   dúdûdüdýgf‘dþedïz   dÿ�d �d�dgf‘�dedïz   �d�d�d�dgf‘�dedïz   �d	�d
�d�dgf‘�de�dz   �d�d�d�dgf‘�ded¿z   �dd�d�d�dgf‘�de�dz   �dd�d�dgf‘�de�dz   �dd]�d�d gf‘�d!e�dz   �d"�d#�d$�d%gf‘�d&e�dz   �d'�d(�d)�d*gf‘�d+e�dz   �d,�d-�d.�d/gf‘�d0e�dz   �d1�d2�d3�d4gf‘�d5e�dz   �d6�d7�d8�d9gf‘�d:e�dz   �d;�d<�d=�d>gf‘�d?edïz   �d@�dA�dB�dC�dDgf‘�dEedïz   �dF�dG�dH�dIgf‘�dJedïz   �dKdð�dL�dMgf‘�dNed«z   �dO�dP�dQ�dRgf‘�dSed¿z   �dT�dU�dV�dWgf‘�dXe�dz   �dY�dZ�d[�d\gf‘�d]edlz   �d^�d_�d`�dagf‘�dbe�dz   �dc�dd�de�dfgf‘�dge�dz   �dh�di�dj�dk�dlgf‘�dme�dz   �dn�do�dp�dqgf‘�dre�dz   �ds�dt�dug �dv¢f‘�dwe�dz   �dx�dy�dzg �d{¢f‘�d|e�dz   �d}�d~�d�d€gf‘�d�e�dz   �d‚d»�dƒg �d„¢f‘�d…e�dz   �d†�d‡�dˆ�d‰gf‘�dŠe�dz   �d‹d�dŒ�d�gf‘�dŽe�dz   �d��d��d‘�d’gf‘�d“e�dz   ee�d”g �d•¢f‘�d–e�dz   e�d—�d˜g �d™¢f‘�dše�dz   e�d›�dœg �d�¢f‘�dže�dz   �dŸd�d �d¡�d¢gf‘�d£e�dz   �d¤�d¥�d¦g �d§¢f‘�d¨e�dz   �d©�dª�d«�d¬�d­gf‘�d®e�dz   �d¯d�d°�d±�d²gf‘�d³e�dz   �d´d�dµ�d¶gf‘�d·e�dz   �d¸dD�d¹�dº�d»gf‘�d¼e�dz   �d½d�d¾�d¿gf‘�dÀe�dz   �dÁ�dÂ�dÃ�d­�dÄgf‘�dÅe�dz   �dÆ�dÇ�dÈ�dÄgf‘�dÉe�dz   �dÊ�dË�dÌ�dÍgf‘�dÎedÚz   �dÏ�dÐ�dÑ�d¢�dÒgf‘�dÓedÚz   �dÔd]�dÕ�dÖgf‘�d×e�dz   �dØd�dÙ�dÚgf‘�dÛe�dz   e�d1fe�d2f�dÜ�d4gf‘�dÝe�dz   e�dnfe�dof�dÞ�dqgf‘Z�dä�dß„Z�då�dà„Z�dæ�dá„Z�dç�dâ„Ze�dãk(  r e«        yy(è  u¹  Mutationsproben fÃ¼r die SicherheitsprÃ¼fungen des Kerns.

Je Probe wird genau EINE PrÃ¼fung entfernt oder umgekehrt (exakte Textersetzung,
die genau einmal vorkommen muss), die komplette Suite lÃ¤uft, die roten Tests
werden mit Meldung festgehalten, danach `git checkout -- <datei>`.
Vor jeder Probe muss `git status --porcelain` leer sein (committete Basis).
Kombi-Proben (alter und neuer Text als Tupel gleicher LÃ¤nge) ersetzen mehrere
Stellen derselben Datei, jede genau einmal vorhanden: damit werden redundante
Schutzschichten GEMEINSAM entfernt (eine Einzelprobe bleibt dort 0 rot, weil die
andere Schicht hÃ¤lt - Defense-in-depth-Nachweis wie bei M78).

Aufruf (aus dem Repo-Wurzelverzeichnis oder beliebig):
    python3 -I python/tools/mutationsproben.py <ergebnis.json> <logverzeichnis> [ID ...]
Ergebnisse werden an <ergebnis.json> angehÃ¤ngt (Liste), Rohausgaben je Probe
landen in <logverzeichnis>/<ID>.log. Beides gehÃ¶rt NICHT ins Repo.
é    )ÚannotationsN)ÚPathé   zpython/aria_router/z    rw_dirs, rw_files = [], []
zP    rw_dirs, rw_files = build_tree(home_root, frozenset(hard_block | ro_block))
zV        entry_dirs, entry_files = build_tree(entry, frozenset(hard_block | ro_block))
ÚM01zauthorization.pyzA        if not hmac.compare_digest(expected_mac, clearance.mac):
z        if False:
u#   HMAC-SignaturprÃ¼fung der ClearanceÚINVALID_SIGNATUREÚM02z(        if now >= clearance.expires_at:
zAblaufzeit der ClearanceÚEXPIREDÚM03zQ        if not self._nonces.consume(clearance.nonce, clearance.expires_at, now):
zEinmal-Nonce (Replay-Schutz)ÚREPLAYÚM04z)        if clearance.backend != backend:
zBindung an das Ziel-BackendÚBACKEND_MISMATCHÚM05z'        if clearance.job_id != job_id:
zBindung an die job_idÚJOB_MISMATCHÚM06zN        if not hmac.compare_digest(clearance.context_digest, context_digest):
u0   Digest Ã¼ber den tatsÃ¤chlich gesendeten KontextÚCONTEXT_DIGEST_MISMATCHÚM07z/        if clearance.privacy != privacy.value:
z/Neuklassifikation im Adapter = Clearance-KlasseÚPRIVACY_MISMATCHÚM08zŠ        if not self._matrix.permits(backend, privacy):
            raise AuthorizationError("PRIVACY_NOT_PERMITTED")
        if not _HEX32ze        if False:
            raise AuthorizationError("PRIVACY_NOT_PERMITTED")
        if not _HEX32u)   Matrix-NachprÃ¼fung im Adapter (Verifier)ÚPRIVACY_NOT_PERMITTEDÚM09z�        if not self._matrix.permits(backend, privacy):
            raise AuthorizationError("PRIVACY_NOT_PERMITTED")
        if not isinstance(context_digestzx        if False:
            raise AuthorizationError("PRIVACY_NOT_PERMITTED")
        if not isinstance(context_digestu'   MatrixprÃ¼fung beim Ausstellen (Issuer)ÚM10zM        if clearance.sender_id != sender_id or clearance.chat_id != chat_id:
zBindung an Absender und ChatÚSUBJECT_MISMATCHÚM11z6        if lifetime <= 0 or lifetime > self._max_ttl:
z"Maximale Lebensdauer der ClearanceÚINVALID_LIFETIMEÚM12z3        if clearance.issued_at > now + self._skew:
zClearance aus der ZukunftÚNOT_YET_VALIDÚM13zB            raise KeyUnavailableError("KEY_UNAVAILABLE") from exc
z            return b"\0" * 32
u$   Fail-closed bei fehlendem SchlÃ¼sselÚKEY_UNAVAILABLEÚM14z%            if info.st_mode & 0o077:
z            if False:
u,   SchlÃ¼sseldatei nur fÃ¼r den Besitzer lesbarÚKEY_PERMISSIONS_TOO_OPENÚM15z
gateway.pyz1            if request.sender_id not in allowed:
zAbsender-AllowlistÚNOT_AUTHORIZEDÚSENDER_NOT_ALLOWEDÚM16z5            if request.chat_id != request.sender_id:
z Privatchat: chat_id == sender_idÚCHAT_SENDER_MISMATCHÚ!test_private_chat_sender_mismatchÚM17zV        if parsed.kind in (CommandKind.SET_MODE, CommandKind.ONE_SHOT) and not owner:
u/   Modusbefehle nur fÃ¼r authentifizierte BesitzerÚMODE_COMMAND_NOT_ALLOWEDÚM18z        if unknown:
z/Selbstdeklarierte Felder an der Bridge abweisenÚUNKNOWN_FIELDÚM19zcore.pyz6    if not matrix.permits(backend.name, job.privacy):
z    if False:
zDatenschutzmatrix im Routing)r   ÚPRIVACY_DENIEDÚMANUAL_CHOICE_NOT_PERMITTEDÚM20z>        chosen = [e for e in eligible if e.backend == wanted]
zA        chosen = [e for e in evaluations if e.backend == wanted]
u(   Manuelle Wahl Ã¼berstimmt keine PrÃ¼fungr-   ÚmanualÚM21zO            alternatives = _rank([e for e in eligible if e.backend != wanted])
zR            alternatives = _rank([e for e in evaluations if e.backend != wanted])
u0   Fallback nur auf vollstÃ¤ndig geprÃ¼ftes BackendÚtest_checked_fallbackÚM22zclassify.pyzB        self._confidential = SECRET_RULES + PII_RULES + _compile(
z3        self._confidential = PII_RULES + _compile(
zSecret-Muster -> CONFIDENTIALzsecret.ÚM23zK        confidential, internal = self._scan(text)
        if confidential:
z�        confidential, internal = self._scan(text)
        if allow_public:
            return PrivacyTier.PUBLIC, ["public.marker"]
        if confidential:
z3Vertrauliche Treffer schlagen die PUBLIC-MarkierungÚtest_confidential_beats_markerÚM24z9        return tier, rules + ["attachment.never_public"]
zT        return (PrivacyTier.PUBLIC if tier is PrivacyTier.UNKNOWN else tier), rules
u   AnhÃ¤nge sind nie PUBLICÚtest_attachments_never_publicÚM25zd            if not self.config.privacy.matrix.permits(backend, tier):
                rejected += 1
z4            if False:
                rejected += 1
z*Memory-Ausschnitt einzeln gegen die MatrixÚ*test_memory_filtered_per_snippet_for_codexÚM26zH        if not self.config.privacy.matrix.permits(backend, final.tier):
z*Finale Neuklassifikation nach AnreicherungÚPRIVACY_CHANGED_BY_ENRICHMENTÚM27z	budget.pyz(        if jobs + 1 > limit.daily_jobs:
zTageslimit JobsÚtest_reserve_and_settle_countsÚbudgetÚM28zstate.pyzP            fcntl.flock(lock_fd, fcntl.LOCK_EX)
            data = self._read()
z             data = self._read()
u6   Dateisperre (NebenlÃ¤ufigkeit Budget/Idempotenz/Nonce)Útest_concurrentÚtest_parallelÚM29z^            available = (settings.enabled and adapter is not None and health.status != "open"
zB            available = (settings.enabled and adapter is not None
zCircuit-Breaker im RoutingÚ,test_codex_outage_opens_circuit_and_reroutesÚ-test_claude_outage_without_unchecked_fallbackÚM30z	health.pyz-        if code not in HEALTH_FAILURE_CODES:
u+   Nur Backend-Fehler zÃ¤hlen fÃ¼r den BreakerÚtest_non_health_codes_ignoredÚM31z        if not claimed:
z#Idempotenz je (chat_id, message_id)ÚDUPLICATE_MESSAGEÚM32z[            restricted = principal is Principal.GROUP_MEMBER and settings.name != "claude"
z            restricted = False
zGruppen nur an ClaudeÚtest_group_message_claude_onlyÚM33z<        if not execute:
            return GatewayResponse(
z6        if False:
            return GatewayResponse(
u   Shadow fÃ¼hrt nie ausÚtest_shadow_never_executesÚM34z	runner.pyz&cwd=str(workdir), env=env, shell=Falsez'cwd=str(workdir), env=None, shell=Falsez%Env-Allowlist, keine geerbte UmgebungÚtest_env_not_inheritedÚM35z!            if token in lowered:
zVerbotene Sandbox-FlagsÚFORBIDDEN_SANDBOX_FLAGÚM36zJ                        if len(out) + len(chunk) > spec.max_output_bytes:
z"                        if False:
u   Ausgabelimit wÃ¤hrend des LaufsÚOUTPUT_LIMITÚM37z"            _kill_group(proc.pid)
z            pass
u"   Prozessgruppe vollstÃ¤ndig beendenÚtest_process_group_killedÚM38zcodex_adapter.pyzL            assert_safe_argv(self._argv)  # unmittelbar vor dem Lauf erneut
u*   Template-PrÃ¼fung unmittelbar vor dem LaufÚ)test_adapter_rechecks_template_before_runÚM39zresult_check.pyuE           text, count = pattern.subn(f"[GESCHWÃ„RZT:{rule_id}]", text)
z        count = 0
u   Secret-SchwÃ¤rzung in Antwortenu   GESCHWÃ„RZTÚREDACTEDÚM40zadapter_contract.pyz(            verified = verifier.verify(
z?            verified = clearance if True else verifier.verify(
u5   Adapter-Basisklasse verifiziert vor jeder AusfÃ¼hrungÚMISSING_CLEARANCEÚM41z*            if protected in cls.__dict__:
u   execute() nicht Ã¼berschreibbarÚtest_subclass_cannot_overrideÚM42z%            if codex.real_execution:
z            if True:
u+   Echte Codex-AusfÃ¼hrung standardmÃ¤ÃŸig ausÚtest_default_runner_is_mockÚM43z	config.pyz        if not wrapper:
u,   Echte AusfÃ¼hrung nur mit Isolations-WrapperÚisolation_wrapperÚM44zdecision_log.pyz&            if key in FORBIDDEN_KEYS:
z'Kein Klartext im EntscheidungsprotokollÚtest_forbidden_keys_rejectedÚM46zDre.compile(r"(?<![0-9])\d{8,10}:[A-Za-z0-9_-]{35}(?![A-Za-z0-9_-])")z-re.compile(r"\b\d{8,10}:[A-Za-z0-9_-]{35}\b")z6Telegram-Token auch mit '-' am Ende und in der Bot-URLÚtest_telegram_token_edge_formsÚtest_token_in_bot_url_redactedÚM45z[            self._log.write({**record, "handling": "pending", "code": "CLEARANCE_ISSUED"})
u'   Keine AusfÃ¼hrung ohne ProtokolleintragÚLOG_UNAVAILABLEÚtest_execute_writes_decisionÚM47zisolation/iso_exec.pyz memfd_create memfd_secretz memfd_secretzmemfd_create-Sperre (M2)Útest_memfd_create_deniedÚM48z_    rule(ACT_ERRNO(EPERM), "execveat", ArgCmp(4, CMP_MASKED_EQ, AT_EMPTY_PATH, AT_EMPTY_PATH))
z	    pass
z#execveat(AT_EMPTY_PATH)-Sperre (M2)Útest_execveat_empty_path_deniedÚM49ze    if "AS" in lim:
        resource.setrlimit(resource.RLIMIT_AS, (int(lim["AS"]), int(lim["AS"])))
z_    if False:
        resource.setrlimit(resource.RLIMIT_AS, (int(lim["AS"]), int(lim["AS"])))
zRLIMIT_AS im Wrapper (M3)Útest_rlimit_as_set_in_wrapperÚM50zi    if "CPU" in lim:
        resource.setrlimit(resource.RLIMIT_CPU, (int(lim["CPU"]), int(lim["CPU"])))
zb    if False:
        resource.setrlimit(resource.RLIMIT_CPU, (int(lim["CPU"]), int(lim["CPU"])))
zRLIMIT_CPU im Wrapper (M3)Útest_rlimit_cpu_set_in_wrapperÚM51z`    if abi < min_abi:
        die(f"Landlock ABI {abi} < erforderlich {min_abi} (fail-closed)")
zX    if False:
        die(f"Landlock ABI {abi} < erforderlich {min_abi} (fail-closed)")
z#Landlock-ABI-Check fail-closed (N3)Ú test_abi_requirement_fail_closedÚM52z]    if stat.S_ISLNK(st.st_mode):
        die(f"Symlink als Konfig-Pfad abgelehnt (N4): {p}")
zJ    if False:
        die(f"Symlink als Konfig-Pfad abgelehnt (N4): {p}")
z!Symlink-Konfigpfad-Ablehnung (N4)Ú!test_symlink_config_path_rejectedÚM53zisolation/profiles.pyz     return [dirs.auth_copy], []
z     return [], [dirs.auth_copy]
z)auth-Kopie standardmaessig read-only (M1)Ú&test_auth_default_readonly_vs_writableÚM54z&        if self._require_output_file:
zlast.txt-Quercheck (M3)Ú"test_fail_when_output_file_missingÚ+test_fail_when_output_file_mismatches_jsonlÚM55zisolation/caged_runner.pyz%        if not self.bus_reachable():
z*Scope-Pflicht/NO_USER_BUS fail-closed (M3)Útest_no_user_bus_is_fail_closedÚM61z    if name in SECRET_NAMES:
z##4 erweiterte Credential-DateinamenÚ&test_extended_credential_names_blockedÚM62zO            out.add(os.path.realpath(p))      # Symlink-Ziel ebenfalls sperren
z<            pass  # realpath-Ziel NICHT gesperrt (Mutation)
z&#5 Symlink-Hard-Block am realpath-ZielÚ'test_symlinked_hard_block_covers_targetÚM63z=    rx_dirs, x_files = build_exec_rx(exec_roots, hard_block)
zD    rx_dirs, x_files = build_exec_rx(exec_roots, frozenset(claude))
z,#2 exec-root carvet Secrets (Landlock-Union)Ú&test_exec_root_does_not_regrant_secretÚM64z2        if p and os.path.abspath(p) != home_root:
z6        if False and os.path.abspath(p) != home_root:
z#6 state_dir/Repo gesperrtÚ,test_state_dir_and_repo_blocked_workspace_rwÚM65z°        d, f = _resolve_ro_targets(home_root, STARTUP_RO_FILES + STARTUP_RO_DIRS + STARTUP_RO_FILESET
                                   + STARTUP_RO_TOPLEVEL, STARTUP_RO_ABS)
z        d, f = (set(), set())
zH1 Startschutz read-onlyÚ1test_protect_startup_true_makes_startup_read_onlyÚM66za    if not (os.path.isabs(iso) and os.path.basename(iso) == "iso_exec.py"):
        return False
z#    if False:
        return False
z*#1 strukturelle Kaefig-Pruefung (iso_exec)Ú&test_wrapper_structural_rejects_bypassÚM67zf            self.stop_scope(unit)
            artifact = self._read_last(dirs, spec.max_output_bytes)
zf            artifact = self._read_last(dirs, spec.max_output_bytes)
            self.stop_scope(unit)
z##7 Scope-Stop vor last.txt-LektuereÚtest_scope_stopped_before_readÚM68zu    for cmd in (F_SETOWN, F_SETOWN_EX, F_SETSIG):
        rule(ACT_ERRNO(EPERM), "fcntl", ArgCmp(1, CMP_EQ, cmd, 0))
zV    for cmd in ():
        rule(ACT_ERRNO(EPERM), "fcntl", ArgCmp(1, CMP_EQ, cmd, 0))
z"#8b fcntl F_SETOWN/SETSIG gesperrtÚ test_fcntl_setown_foreign_deniedÚtest_fcntl_setsig_deniedÚM69zA    rule(ACT_ERRNO(EPERM), "prlimit64", ArgCmp(0, CMP_NE, 0, 0))
z0    pass  # prlimit64-Regel entfernt (Mutation)
z#8c prlimit64 nur pid==0Útest_prlimit_foreign_deniedÚM70z* memfd_create memfd_secret process_madvisez#8 process_madvise gesperrtÚtest_process_madvise_deniedÚM71zU                            error = "STDIN_FAILED"
                            break
z2                            pending = pending[:0]
z#13 STDIN_FAILED bei EPIPEÚ!test_stdin_write_failure_is_errorÚM72z!            if last != expected:
zS            if last != expected and last not in expected and expected not in last:
z#14 exakter last.txt-QuercheckÚ test_substring_last_txt_rejectedÚM73zV        if spec.files:
            return RunResult(False, "ATTACHMENTS_UNSUPPORTED")
zQ        if False:
            return RunResult(False, "ATTACHMENTS_UNSUPPORTED")
z#15 Anhaenge fail-closedÚtest_files_fail_closedÚM74z8        tier = most_sensitive((text_tier, source_tier))
z        tier = text_tier
z"#16 Memory-Quellname klassifiziertÚ#test_memory_source_label_classifiedÚM75zDdef _raise_terminated(signum, frame):
    raise _BridgeTerminated()
z1def _raise_terminated(signum, frame):
    return
z#9 SIGTERM stoppt den ScopeÚ'test_sigterm_stops_scope_and_grandchildÚM76zE    ".cargo/credentials", ".cargo/credentials.toml", ".claude.json",
z5    ".cargo/credentials", ".cargo/credentials.toml",
z1b .claude.json hart gesperrtÚtest_claude_json_hard_blockedÚtest_claude_json_read_deniedÚM77z$        out.add(os.path.abspath(p))
z        pass
z1a Top-Level-Dotfiles roÚ!test_top_level_dotfiles_read_onlyÚM78zÛ        if is_dot and _is_secret_name(name):
            continue                              # Secret -> hart gesperrt, NICHT ro (bliebe sonst lesbar)
        if os.path.abspath(p) in hard_block:
            continue
zN        if False:
            continue
        if False:
            continue
zE1a Secret-Dotfiles bleiben vom Sweep ausgeschlossen (nicht ro lesbar))Ú0test_secret_top_level_dotfile_stays_hard_blockedÚtest_credentials_blockedÚ(test_tools_blocks_credentials_and_claudeÚM79zcSTARTUP_RO_DIRS = (".config", "scripts", ".local", ".nvm", ".bun", ".cargo/bin", "brain", "state")
z2STARTUP_RO_DIRS = (".config", "scripts", "brain")
z1c Paketmanager/.local/state ro)Ú.test_package_dirs_and_cargo_registry_read_onlyÚ*test_deferred_exec_ro_targets_denied_rw_okÚ#test_rejects_startup_protected_dirsÚM80zb                if (ap == home_root or ap.startswith(home_root + os.sep)) and os.path.isfile(ap):
z                if False:
z1d gesourcte Dateien roÚtest_sourced_files_read_onlyÚM81zA            (ro_dirs if os.path.isdir(rp) else ro_files).add(ap)
z1e Cron-Ziele ro)Útest_cron_targets_read_onlyÚ-test_build_time_rejects_entry_inside_cron_dirÚ3test_allowlist_carves_secret_hooks_and_cron_targetsÚ*test_write_only_in_workspace_and_allowlistÚM82z?        return [], f"crontab_read_failed:{type(exc).__name__}"
z        return [], None
z1e Cron-Lesefehler -> WarnungÚ/test_cron_read_failure_yields_warning_not_crashÚM83z%        if is_worktree or is_family:
z)1g Geschwister-Worktrees/Familie gesperrtÚ)test_sibling_worktrees_and_family_blockedÚM84zSTARTUP_RO_ABS = ()z%STARTUP_RO_ABS = ("/home/aria/aria",)z 1f totes STARTUP_RO_ABS entferntÚ%test_startup_ro_abs_has_no_dead_entryÚM85z8E44-Kern: Home ausserhalb der Allowlist nicht schreibbar)Ú(test_without_allowlist_home_is_read_onlyÚtest_kostenwache_class_closedr­   Ú#test_home_readable_but_not_writableÚM86z@        entry_dirs, entry_files = build_tree(entry, hard_block)
z9E44: ro-Ziele (Hooks/Cron) bleiben im Allowlist-Ordner ro)r¬   Ú*test_allowlist_dir_keeps_startup_carveoutsr­   ÚM87zI        entry_dirs, entry_files = build_tree(entry, frozenset(ro_block))
z6E44: Secrets bleiben im Allowlist-Ordner hart gesperrt)r¬   Ú:test_protect_startup_off_opens_hooks_only_inside_allowlistr­   ÚM88z`        if any(part.startswith(".") for part in os.path.relpath(raw, home_root).split(os.sep)):
zEE44-Validierung: keine versteckte Komponente (.cache/.cargo/.git ...)Útest_rejects_hidden_componentsÚ0test_invalid_entry_fails_closed_with_clear_errorÚM89zv            if _inside_or_equal(raw, p):
                raise WriteAllowlistError(f"{raw}: inside blocked area {p}")
zc            if False:
                raise WriteAllowlistError(f"{raw}: inside blocked area {p}")
z:E44-Validierung: nicht in gesperrten/Startschutz-Bereichen)r¦   Ú&test_rejects_state_dir_repo_and_familyÚ&test_rejects_credential_symlink_targetÚM90z‚            if _inside_or_equal(raw, p):
                raise WriteAllowlistError(f"{raw}: inside read-only protected area {p}")
zo            if False:
                raise WriteAllowlistError(f"{raw}: inside read-only protected area {p}")
z?E44-Validierung: nicht in ro-Zielen des Profilbaus (Cron/Hooks)Ú*test_rejects_dynamic_blocked_and_read_onlyr«   ÚM91z)        if os.path.realpath(raw) != raw:
z%E44-Validierung: kein Symlink im PfadÚ5test_symlinked_ancestor_cannot_smuggle_protected_areaÚ&test_rejects_missing_file_and_symlinksÚM92z3        if not raw.startswith(home_root + os.sep):
z\E44-Validierung: echt unter home_root (Meldung; Ablehnung haelt zusaetzlich die Punkt-Regel)Ú"test_rejects_home_root_and_outsideÚM93zE            if _inside_or_equal(raw, p) or _inside_or_equal(p, raw):
z6E44-Validierung: keine Ueberlappung mit workspace_rootÚ'test_rejects_overlap_with_run_containerÚ)test_overlap_with_workspace_root_rejectedÚM94z)        if os.path.normpath(raw) != raw:
z^E44-Validierung: kanonischer Pfad (Meldung; Ablehnung haelt zusaetzlich die realpath-Pruefung)Ú'test_rejects_relative_and_non_canonicalÚM95zü    allow = validate_write_allowlist(write_allowlist, home_root=home_root, state_dir=state_dir,
                                     repo_root=repo_root, runs_root=runs_root,
                                     blocked=hard_block, read_only=ro_block)
z#    allow = tuple(write_allowlist)
z2E44: Profilbau prueft die Allowlist je Lauf erneutÚ>test_entry_swapped_for_symlink_after_construction_fails_closedÚM96z*            except P.WriteAllowlistError:
z            except ():
z7E44: klarer Laufzeit-Fehlercode WRITE_ALLOWLIST_INVALIDÚM97zí        self.write_allowlist = P.validate_write_allowlist(
            list(write_allowlist), home_root=self.home_root, state_dir=self.state_dir,
            repo_root=self.repo_root, runs_root=os.path.abspath(str(self.workspace_root)))
z6        self.write_allowlist = tuple(write_allowlist)
z/E44: Runner prueft die Allowlist schon beim BauÚ%test_runner_validates_at_constructionÚM98a          write_allowlist = validate_write_allowlist(
            list(allow_raw), home_root=str(home_root),
            state_dir=str(state_dir) if state_dir is not None else None, repo_root=PKG_REPO_ROOT,
            runs_root=str(workspace) if workspace is not None else None)
z+        write_allowlist = tuple(allow_raw)
z3E44: Konfiguration prueft die Allowlist fail-closedÚtest_inside_state_dir_rejectedÚM99z)    if allow_raw and profile != "tools":
z2E44: Allowlist nur im tools-Profil (Konfiguration)Ú#test_text_profile_rejects_allowlistÚM100z3        if profile != "tools" and write_allowlist:
z+E44: Allowlist nur im tools-Profil (Runner)Ú*test_runner_text_profile_rejects_allowlistÚM65Kz5H1 Startschutz traegt wieder, wenn der E44-Kern fehltÚM77Kz?1a Top-Level-Dotfiles ro traegt wieder, wenn der E44-Kern fehltc                 óX   — t        j                  dg| ¢t        ddd¬«      j                  S )NÚgitT)ÚcwdÚcapture_outputÚtextÚcheck)Ú
subprocessÚrunÚREPOÚstdout)Úargss    ú6/home/aria/aria-v3-dev/python/tools/mutationsproben.pyrÜ   rÜ   t  s&   € Ü�>‰>˜5˜. 4˜.¬dÀ4ÈdÐZ^Ô_×fÑfÐfó    c           	     ó   — g }t        j                  d| t         j                  ¬«      D ]Ý  }t        j                  d|t         j                  ¬«      }|sŒ,|j	                  «       j                  «       D �cg c]'  }|j	                  «       sŒ|j                  d«      rŒ&|‘Œ) }}t        d„ t        |«      D «       d«      }|j                  |j                  d«      |j                  d«      |d d	 |j	                  «       d
d  dœ«       Œß |S c c}w )Nz^=+$)Úflagsz ^(FAIL|ERROR): (\S+) \(([^)]+)\)z---c              3  óD   K  — | ]  }|j                  d «      rŒ|–— Œ y­w)z  File N)Ú
startswith)Ú.0Úlines     ræ   ú	<genexpr>z!parse_failures.<locals>.<genexpr>  s   è ø€ Ò[ ÀÇÁÐPYÕ@ZœÑ[ùs   ‚ ™ Ú é   é   i�  i0øÿÿ)ÚkindÚtestÚmessageÚblock)ÚreÚsplitÚMÚsearchÚstripÚ
splitlinesrë   ÚnextÚreversedÚappendÚgroup)ÚoutputÚfailuresrõ   Úmatchrí   Úlinesrô   s          ræ   Úparse_failuresr  x  sâ   € Ø€HÜ—‘˜' 6´·±Ô6ò :ˆÜ—	‘	Ð=¸uÌBÏDÉDÔQˆÙØØ"'§+¡+£-×":Ñ":Ó"<Öl˜$ÀÇ
Á
ÅÐUY×UdÑUdÐejÕUk’ÐlˆÐlÜÑ[¬°%«Ô[Ð]_Ó`ˆØ�‰ §¡¨Q£¸¿¹ÀQ»ÐT[Ð\`Ð]`ÐTaØ"'§+¡+£-°°Ð"7ñ9õ 	:ð:ð €Oùò	 ms   Á5DÂDÂDc                óô  — | \  }}}}}}t        dd«      j                  «       rt        d|z   «      ‚t        |z  }|j	                  d¬«      }	t        |t        «      }
|
rt        t        ||«      «      n||fg}|
r%t        |«      t        |«      k7  rt        d|z   «      ‚|D ��cg c]  \  }}|	j                  |«      ‘Œ }}}|
r|n|d   }||||dœ}t        d	„ |D «       «      r|j                  d
d d|› �dœ«       |S t        j                  «       }|	}|D ]  \  }}|j                  ||«      }Œ |j!                  |d¬«       	 t#        j$                  ddt&        j(                  dddddddddgt        dz  dd¬«      }t        dd|«       |j*                  |j,                  z   }||› d�z  j!                  |d¬«       t        dd«      j                  «       rt        d|z   «      ‚t/        |«      }t1        j2                  d|«      }t5        |D ��ch c]  }|D ]  }||d    v s||d!   v sŒ|’Œ Œ c}}«      }|j                  d|j6                  |rt9        |j;                  d"«      «      nd t        |«      |D �cg c]  }|d!   ‘Œ	 c}|d d# D �cg c]  }|d$   ‘Œ	 c}||t=        |«      t?        t        j                  «       |z
  d"«      d%œ
«       |S c c}}w # t        dd|«       w xY wc c}}w c c}w c c}w )&NÚstatusz--porcelainz$Worktree nicht sauber - Abbruch vor úutf-8©Úencodingz-Kombi-Probe mit ungleich vielen Ersetzungen: r   )ÚidÚfileÚpropertyÚsnippet_countc              3  ó&   K  — | ]	  }|d k7  –— Œ y­w)rð   N© )rì   Úcs     ræ   rî   zrun_probe.<locals>.<genexpr>’  s   è ø€ Ò
"�aˆ1��6Ñ
"ùs   ‚FzSNIPPET_COUNT=)ÚappliedÚredÚerrorÚtimeoutÚ900z-Bz-Iz-mÚunittestÚdiscoverz-sÚtestsz-tú.ÚpythonT)rÝ   rÞ   rß   Úcheckoutz--z.logu"   ZurÃ¼cksetzen fehlgeschlagen nach zRan (\d+) tests?rõ   ró   rð   é   rô   )
r  Ú
returncodeÚranr  Ú	red_testsÚmessagesÚmarkersÚmarker_hitsÚright_reasonÚseconds) rÜ   rú   Ú
SystemExitrã   Ú	read_textÚ
isinstanceÚtupleÚlistÚzipÚlenÚcountÚanyÚupdateÚtimeÚ	monotonicÚreplaceÚ
write_textrá   râ   ÚsysÚ
executablerä   Ústderrr  rö   rù   Úsortedr  Úintrÿ   ÚboolÚround)ÚmutationÚlog_dirÚidentÚrelÚoldÚnewÚpropr!  ÚpathÚsourceÚcomboÚpairsÚoÚ_Úcountsr,  ÚresultÚstartedÚmutatedÚnÚprocr   r  r  ÚmÚfr"  s                              ræ   Ú	run_proberO  …  së  € Ø*2Ñ'€Eˆ3��S˜$ Ü
ˆ8�]Ó#×)Ñ)Ô+ÜÐ?À%ÑGÓHÐHÜ�#‰:€DØ�^‰^ Wˆ^Ó-€FÜ�sœEÓ"€EÙ#(ŒD”�S˜#“Ô°°S¨z¨l€EÙ”�S“œS ›XÒ%ÜÐHÈ5ÑPÓQÐQØ*/×0¡$ ! Qˆf�l‰l˜1�oÐ0€FÑ0Ù‰F ¨¡€EØ 3°DÈ5ÑQ€FÜ
Ñ
"˜6Ô
"Ô"Ø�‰ %°ÀÐPUÈwÐ?WÑXÔYØˆÜ�n‰nÓ€GØ€GØò (‰ˆˆ1Ø—/‘/ ! QÓ'‰ð(à‡O�O�G g€OÔ.ð#Ü�~‰~Ø˜œsŸ~™~¨t°T¸4ÀÈZÐY]Ð_fÐhlÐnqÐrÜ�x‘°¸4ô
ˆô
 	ˆJ˜˜cÔ"Ø�[‰[˜4Ÿ;™;Ñ&€FØ�%�˜ˆ~Ñ×)Ñ)¨&¸7Ð)ÔCÜ
ˆ8�]Ó#×)Ñ)Ô+ÜÐ=ÀÑEÓFÐFÜ˜fÓ%€HÜ
�)‰)Ð'¨Ó
0€CÜ W×d °hÒd°À!ÀqÈÁzÁ/ÐUVÐZ[Ð\bÑZcÒUcš!Ðd˜!ÓdÓe€KØ
‡M�MØ t§¡ÑTW¼sÀ3Ç9Á9ÈQÃ<Ô?PÐ]aÜ�8‹}¸xÖ+H¸!¨A¨f«IÒ+HØ+3°B°Q¨<Ö8 a�Q�y“\Ò8ÀWÐ]hÜ˜[Ó)´e¼D¿N¹NÓ<LÈwÑ<VÐXYÓ6Zñ	ô ð €Mùó? 1øô" 	ˆJ˜˜cÕ"üó eùò ,IùÚ8s*   Â%KÅ:K ÈK*
È*K*
É:K0ÊK5ËK'c                 ó   — t        t        j                  d   «      } t        t        j                  d   «      }|j                  dd¬«       t	        t        j                  dd  «      }t        ddd«      j                  «       }| j                  «       r%t        j                  | j                  d	¬
«      «      ng }t        D ]Ç  }|r|d   |vrŒt        ||«      }||d<   |D �cg c]  }|d   |d   k7  sŒ|‘Œ c}|gz   }| j                  t        j                  |dd¬«      d	¬
«       t        |d   › d|j!                  d«      › d|j!                  d«      rdnd› d|j!                  dd«      › d|j!                  dd«      › d�
d¬«       ŒÉ y c c}w )Nrð   r   T)ÚparentsÚexist_okrñ   z	rev-parsez--shortÚHEADr  r  r   Úbase_commitr
  F)Úensure_asciiÚindentz rot=r  z grund=r#  ÚjaÚNEINú r  rï   r$  Ús)Úflush)r   r3  ÚargvÚmkdirÚsetrÜ   rú   ÚexistsÚjsonÚloadsr&  Ú	MUTATIONSrO  r2  ÚdumpsÚprintÚget)Úoutr;  ÚwantedÚbaseÚresultsr:  rH  Úrs           ræ   Úmainrk  ±  sn  € Ü
Œs�x‰x˜‰{Ó
€CÜ”3—8‘8˜A‘;Ó€GØ‡M�M˜$¨€MÔ.Ü”—‘˜!˜"�Ó€FÜˆ{˜I vÓ.×4Ñ4Ó6€DØ=@¿Z¹Z¼\Œd�j‰j˜Ÿ™°˜Ó8Ô9Èr€GÜò UˆÙ�h˜q‘k¨Ñ/ØÜ˜8 WÓ-ˆØ $ˆˆ}ÑØ%ÖA˜¨¨4©°F¸4±LÓ)@’1ÒAÀVÀHÑLˆØ�‰”t—z‘z '¸ÀaÔHÐSZˆÔ[Ü�˜‘�˜e F§J¡J¨uÓ$5Ð#6°gÀfÇjÁjÐQ_ÔF`¹dÐflÐ=mÐmnØ—‘˜G RÓ(Ð)¨¨6¯:©:°iÀÓ+DÐ*EÀQðHØOSö	UñUùò
 Bs   Ã"FÃ3FÚ__main__)rå   ÚstrÚreturnrm  )r   rm  rn  z
list[dict])r;  r   rn  Údict)rn  ÚNone)Ú__doc__Ú
__future__r   r`  rö   rá   r3  r/  Úpathlibr   Ú__file__ÚresolverQ  rã   ÚAÚ_E44_HOME_RW_OLDÚ_E44_HOME_RW_NEWÚ_E44_ALLOW_TREE_OLDrb  rÜ   r  rO  rk  Ú__name__r  rç   ræ   ú<module>r{     s—  ðñõ  #ã Û 	Û Û 
Û Ý áˆHƒ~×ÑÓ×'Ñ'¨Ñ*€Ø€ð 6Ð ØfÐ àoÐ ðLØ
ˆAÐ"Ñ"Ð$hØÐAÐDWÐCXðZðLð ˆAÐ"Ñ"Ð$OÐQfØ ) ð.ðLð
 ˆAÐ"Ñ"ØYÐ[pØ# h Zð1ðLð ˆAÐ"Ñ"Ð$PÐRgØ"Ð%7Ð$8ð:ðLð ˆAÐ"Ñ"Ð$NÐPeØ˜~Ð.ð0ðLð ˆAÐ"Ñ"ØVÐXmØ7Ð:SÐ9TðVðLð ˆAÐ"Ñ"Ð$VÐXmØ6Ð9KÐ8LðNðLð" ˆAÐ"Ñ"ð VØpØ0Ð3JÐ2KðMð#Lð* ˆAÐ"Ñ"ð ið DØ.Ð1HÐ0IðKð+Lð2 ˆAÐ"Ñ"ØUÐWlØ#Ð&8Ð%9ð;ð3Lð8 ˆAÐ"Ñ"Ð$]Ð_tØ)Ð,>Ð+?ðAð9Lð< ˆAÐ"Ñ"Ð$ZÐ\qØ  ?Ð"3ð5ð=Lð@ ˆAÐ"Ñ"Ð$kØ)Ð+QÐTeÐSfðhðALðD ˆAÐ"Ñ"Ð$LÐNgØ3Ð6PÐ5QðSðELðH ˆA�ÑÐRÐTmØÐ,Ð.BÐCðEðILðL ˆA�ÑÐVÐXqØ'Ð*@ÐBeÐ)fðhðMLðP ˆA�ÑØ^ØÐMÐPjÐOkðmðQLðV ˆA�ÑÐ5Ð7LØ6¸Ð8IðKðWLðZ ˆA�	‰MÐTÐVgØ#Ò%oðqð[Lð^ ˆA�	‰MÐ\ØIØ/Ð2OÐQYÐ1Zð\ð_Lðd ˆA�	‰MÐmØZØ7Ð:QÐ9RðTðeLðj ˆA�ÑÐdØ;Ð=\Ð_hÐ^iðkðkLðn ˆA�ÑÐnð^à:Ð=]Ð<^ð`ðoLðv ˆA�ÑÐ]Ø\ØÐ"AÐ!BðDðwLð| ˆA�ÑØmØ=Ð?kØ2Ð3ð5ð}LðD ˆA�ÑÐiØÐHÐKjÐJkðmðELðH ˆA�‰OÐHÐJ_ØÐ9¸8ÐDðFðILðL ˆA�
‰NÐpØ(Ð*bØ˜Ð)ð+ðMLðR ˆA�ÑØhØJÐLhØ4Ð6eÐfðhðSLðZ ˆA�‰OÐMÐOdØ2Ð5TÐ4UðWð[Lð^ ˆA�ÑÐ9Ð;PØ*Ð-@Ð,AðCð_Lðb ˆA�ÑØeØ'Ð)@ÐCcÐBdðfðcLðh ˆA�ÑÐ^Ø?ÐAXØ"Ð#ð%ðiLðn ˆA�‰OÐEÐGpØ,Ð/GÐ.HðJðoLðr ˆA�‰OÐAÐC\ØÐ!9Ð :ð<ðsLðv ˆA�‰OÐjØ*Ð,MÐP^ÐO_ðaðwLðz ˆA�‰OÐBÐDXØ)Ð,GÐ+HðJð{Lð~ ˆAÐ"Ñ"Ð$sØÐGÐJuÐIvðxðLðB ˆAÐ!Ñ!Ð#mØÐ=ÀÈzÐ?Zð\ðCLðF ˆAÐ%Ñ%Ð'RØGØ<Ð?RÐ>SðUðGLðL ˆAÐ%Ñ%Ð'TÐVoØ&Ð)HÐ(IðKðMLðP ˆA�ÑÐFÐH`Ø2Ð5RÐ4SðUðQLðT ˆA�‰OÐ8Ð:OØ3Ð6IÐ5JðLðULðX ˆAÐ!Ñ!Ð#LÐNgØ.Ð1OÐ0PðRðYLð\ ˆA�ÑØNØ9Ø=Ð@`Ø?_ð@aðbð]Lðf ˆA�ÑØkØÐDÐGXÐZxÐFyð{ðgLðn ˆAÐ'Ñ'Ð)EÀØÐ"<Ð!=ð?ðoLðr ˆAÐ'Ñ'ØiØÐ8Ð;\Ð:]ð_ðsLðx ˆAÐ'Ñ'ØtØlØ Ð#BÐ"CðEðyLð@ ˆAÐ'Ñ'ØxÙoÙ!Ñ$DÐ#EðGðALñH ˆAÐ'Ñ'ÙkÙcÙ*Ñ-OÐ,PðRðILñP ˆAÐ'Ñ'ÙhÙUÙ(Ñ+NÐ*OðQðQLñX ˆAÑ'Ñ'Ñ)LÑNqÙ0Ñ3[Ð2\ð^ðYLñ\ ˆAÐ"Ñ"Ñ$MÐOdÙÑ!EÑGtÐ uðwð]Lñ` ˆAÑ+Ñ+Ñ-UÐWlÙ1Ñ4UÐ3VðXðaLñf ˆAÑ'Ñ'Ñ)IÐK\Ù*Ñ-UÐ,VðXðgLñj ˆAÑ'Ñ'ÙWÙDÙ-Ñ0YÐ/Zð\ðkLñr ˆAÑ'Ñ'Ñ)iÙLÙ3Ñ6^Ð5_ðaðsLñx ˆAÑ'Ñ'Ñ)^Ù>Ù!Ñ$RÐ#SðUðyLñB ˆAÑ'Ñ'ñSá&ÙÑ"UÐ!Vð	XðCLñL ˆAÑ+Ñ+ÙlÙ,Ù1Ñ4\Ð3]ð_ðMLñT ˆAÑ+Ñ+ÙoÙoÙ*Ñ-MÐ,NðPðULñ\ ˆAÐ'Ñ'ñ AÙaÙ)Ñ,NÑPjÐ+kðmð]Lñd ˆAÐ'Ñ'ÙKÙ8ÙÑ"?Ð!@ðBðeLñl ˆAÐ'Ñ'Ñ)UÐWsÙ"Ñ%BÐ$CðEðmLñp ˆA�‰OÑxÙ:Ù!Ñ$GÐ#HðJðqLñv ˆAÐ"Ñ"Ñ$HÙ[Ù%Ñ(JÐ'KðMðwLñ| ˆAÑ+Ñ+ÙaÙ\ÙÑ":Ð!;ð=ð}LñD ˆA�ÑÑZÙ!Ù)Ñ,QÐ+RðTðELñJ ˆAÑ+Ñ+ÙMÙ:Ù"Ñ%NÐ$OðQðKLñT ˆAÑ'Ñ'ÙMÙ=Ù$Ñ'FÑHfÐ&gðiðULñ\ ˆAÑ'Ñ'Ù,Ñ.>ÙÑ"EÐ!FðHð]Lñj ˆAÑ'Ñ'ñLñ ZÙLó2ð3ðkLñz ˆAÑ'Ñ'ÙkÙ:Ù&ó )PðQð{LñF ˆAÑ'Ñ'ÙjÙ"ÙÑ!?Ð @ðBðGLñN ˆAÑ'Ñ'ÙIÐK_Ùó HðIðOLñX ˆAÑ'Ñ'ÙGÑIdÙ$Ñ'XÐ&Yð[ðYLñ^ ˆAÑ'Ñ'Ù-Ð/DÙ0Ñ3^Ð2_ðað_Lñd ˆAÑ'Ñ'ÙÑCÙ'Ñ*QÐ)RðTðeLñl ˆAÑ'Ñ'Ð)9Ð;KÙ?ó[ð\ðmLñt ˆAÑ'Ñ'Ð)<ÙHÙ@ó4ð5ðuLñ~ ˆAÑ'Ñ'Ð)<ÙQÙ=órðsðLñH ˆAÑ'Ñ'ÙjØÙLÙ&Ñ(ZÐ[ð	]ðILñR ˆAÑ'Ñ'ñ BÙnÙAó0ð	1ðSLñ^ ˆAÑ'Ñ'ñdñdáFÙ2Ñ4cÐdðfð_Lñl ˆAÑ'Ñ'Ñ)UÐWlÙ,Ù=Ñ?gÐhðjðmLñr ˆAÑ'Ñ'Ñ)_ÐavÙcÙ*Ð+ð-ðsLñx ˆAÑ'Ñ'ÙMÐOhÙ=Ù/Ñ1\Ð]ð_ðyLñ@	 ˆAÑ'Ñ'Ñ)UÐWlÙeÙ/Ð0ð2ðA	LñF	 ˆAÑ'Ñ'ñVñ ,Ù9Ù5ÙFðHðIðG	LñV	 ˆAÑ+Ñ+Ñ-ZÑ\vÙ>ÙFÐGðIðW	Lñ\	 ˆAÑ+Ñ+ñdñ ?Ù6Ñ9`Ð8aðcð]	Lñh	 ˆA�‰OñRñ 4Ù:Ù8Ñ:ZÐ[ð]ði	Lñx	 ˆA�‰OÑKÐM^Ù9Ñ<aÐ;bðdðy	Lñ|	 ˆQÑ,Ñ,Ñ.fØÑIÙ2Ð3ð5ð}	LñF
 ˆQÑ(Ñ(ØñTðUð Ñ9Ð:Ù<Ñ?rÐ>sðuðG
LñR
 ˆQÑ(Ñ(ØÑ?Ð@ÐCSÑUeÐBfÙFÑIlÐHmðoðS
L€	õ^
gõ
õ)õXUð$ ‰zÒÙ…Fð rç   