§
    Çz¿jé8  ã                   ó<  — d Z ddlZddlmc mZ ddlZddlZddl	Z	ddl
mZ ddlZddlmZ  ee¦  «                             ¦   «         j        j        j        Zedz  dz  Zedz  Zedz  d	z  Zedz  d
z  Z G d„ d¦  «        Z G d„ d¦  «        Z G d„ d¦  «        ZdS )a®  
Empirical Challenger Test Suite: Milestone 3 Remediation.
Adversarial stress-testing of Client Script Integration & Leader Aura Ground Decals.

Verifies:
1. client/webapp/index.html script tags, attributes, and ordering.
2. Node.js evaluation of wilderness_zone_packs.js, monster_pack_system.js, and ambush_trigger_system.js.
3. Window global bridge exports.
4. Canvas 2D renderLeaderAuraDecal across 5 aura types with mock context.
5. Adversarial edge cases: dead mobs, non-leaders, negative coords, undefined time, NaN guards.
6. High-frequency 10,000-frame render stress loop (zero NaN, zero throw, budget <= 0.05ms/call).
7. Safe haven firewall on pack spawning & ambush triggers.
é    N)ÚPath)ÚBeautifulSoupÚclientÚwebappz
index.htmlÚjsÚdataÚenginec                   ó*   — e Zd ZdZdd„Zdd„Zdd„ZdS )ÚTestIndexHtmlScriptIntegrationz6Adversarial DOM parsing and script order verification.ÚreturnNc                 ó  — t           j        } |¦   «         }|s²t          j        dt           › �¦  «        dz   dt	          j        ¦   «         v st          j        t           ¦  «        rt          j        t           ¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          t          j	        |¦  «        ¦  «        ‚d x}}t            
                    d¬¦  «                             ¦   «         }t          |¦  «        }d}||k    }|s¯t          j        d|fd	||f¦  «        d
t	          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nd
t          j        |¦  «        dœz  }t          j        d|› �¦  «        dz   d|iz  }t          t          j	        |¦  «        ¦  «        ‚d x}}d}||k    }|s¯t          j        d|fd	||f¦  «        d
t	          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nd
t          j        |¦  «        dœz  }t          j        d|› �¦  «        dz   d|iz  }t          t          j	        |¦  «        ¦  «        ‚d x}}d S )Nzindex.html missing at zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}Ú
INDEX_HTML©Úpy0Úpy2Úpy4úutf-8©ÚencodingéÈ   )ú<=)z%(py0)s <= %(py3)sÚ
line_count©r   Úpy3z$index.html exceeded soft cap (200): ú
>assert %(py5)sÚpy5i�  z$index.html exceeded hard cap (400): )r   ÚexistsÚ
@pytest_arÚ_format_assertmsgÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanationÚ	read_textÚ
splitlinesÚlenÚ_call_reprcompare)	ÚselfÚ@py_assert1Ú@py_assert3Ú@py_format5Úlinesr   Ú@py_assert2Ú@py_format4Ú@py_format6s	            úMC:\Projects\FreeExile\tests\unit\test_challenger_m3_script_and_aura_stress.pyÚ&test_index_html_line_cap_and_existencezETestIndexHtmlScriptIntegration.test_index_html_line_cap_and_existence    s³  € ÝÔ ÐIÐ Ð Ñ"Ô"ÐIÐ"ÐIÕIÔIÐ$I½ZÐ$IÐ$IÑIÔIÐIÑIÐIÕIÔIÑIÔIÐIÐIÕIÔI�zÑIÔIÐIÕIÔI�zÑIÔIÐIÐIÕIÔIÐ ÑIÔIÕIÔIÐ"ÑIÔIÐIÐIÑIÐIÕIÕIÔIÐIÑIÔIÑIÔIÐIÐIÐIÐIÐIÝ×$Ò$¨gÐ$Ñ6Ô6×AÒAÑCÔCˆÝ˜‘Z”Zˆ
Ø ÐUˆz˜SÒ ÐUÐUÐUÕUÔUÐUÐUÐUÐUˆz˜SÐUÑUÔUÐUÕUÔUÑUÔUÐUÐUÕUÔUˆzÑUÔUÐUÕUÔUˆzÑUÔUÐUÐUÕUÔU˜SÑUÔUÐUÐUÑUÐUÕUÔUÐ"UÈÐ"UÐ"UÑUÔUÐUÑUÐUÐUÐUÑUÐUÕUÕUÔUÐUÑUÔUÑUÔUÐUÐUÐUÐUÐUØ ÐUˆz˜SÒ ÐUÐUÐUÕUÔUÐUÐUÐUÐUˆz˜SÐUÑUÔUÐUÕUÔUÑUÔUÐUÐUÕUÔUˆzÑUÔUÐUÕUÔUˆzÑUÔUÐUÐUÕUÔU˜SÑUÔUÐUÐUÑUÐUÕUÔUÐ"UÈÐ"UÐ"UÑUÔUÐUÑUÐUÐUÐUÑUÐUÕUÕUÔUÐUÑUÔUÑUÔUÐUÐUÐUÐUÐUÐUÐUó    c           	      ó<  — t                                d¬¦  «        }t          |d¦  «        }|                     d¦  «        }g d¢}d„ |D ¦   «         }|D �]Ç}||v }|sÚt	          j        d|fd||f¦  «        d	t          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        nd	d
t          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        nd
dœz  }t	          j
        d|› �¦  «        dz   d|iz  }	t          t	          j        |	¦  «        ¦  «        ‚d }|                     dd|i¬¦  «        }
d }|
|u}|s—t	          j        d|fd|
|f¦  «        dt          j        ¦   «         v st	          j        |
¦  «        rt	          j	        |
¦  «        ndt	          j	        |¦  «        dœz  }dd|iz  }t          t	          j        |¦  «        ¦  «        ‚d x}}|
j        }d} ||¦  «        }d}||k    }|sþt	          j        d|fd||f¦  «        dt          j        ¦   «         v st	          j        |
¦  «        rt	          j	        |
¦  «        ndt	          j	        |¦  «        t	          j	        |¦  «        t	          j	        |¦  «        t	          j	        |¦  «        dœz  }t	          j
        d|› d|
                     d¦  «        › �¦  «        dz   d|iz  }t          t	          j        |¦  «        ¦  «        ‚d x}x}x}x}}�ŒÉd S ) Nr   r   úhtml.parserÚscript)ú js/data/wilderness_zone_packs.jsú js/engine/monster_pack_system.jsú"js/engine/ambush_trigger_system.jsc                 ób   — g | ],}|                      d ¦  «        ¯|                      d ¦  «        ‘Œ-S ©Úsrc©Úget©Ú.0Úss     r2   ú
<listcomp>z[TestIndexHtmlScriptIntegration.test_script_tags_presence_and_attributes.<locals>.<listcomp>1   s1   € ÐEÐEÐE¨¸¿º¸e¹¼ÐE�q—u’u˜U‘|”|ÐEÐEÐEr4   ©Úin)z%(py0)s in %(py2)sÚexpectedÚscript_srcs©r   r   zExpected script tag missing: ú
>assert %(py4)sr   r=   )Úattrs)úis not)z%(py0)s is not %(py3)sÚtagr   zassert %(py5)sr   ÚtypeÚmodule©ú==)zI%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.get
}(%(py4)s)
} == %(py9)s)r   r   r   Úpy6Úpy9zScript z must be type='module', got z
>assert %(py11)sÚpy11)r   r&   r   Úfind_allr   r)   r    r!   r"   r#   r   r$   r%   Úfindr?   )r*   Úhtml_contentÚsoupÚscriptsÚexpected_scriptsrG   rF   r+   Ú@py_format3r-   rL   r/   r0   r1   r,   Ú@py_assert5Ú@py_assert8Ú@py_assert7Ú@py_format10Ú@py_format12s                       r2   Ú(test_script_tags_presence_and_attributeszGTestIndexHtmlScriptIntegration.test_script_tags_presence_and_attributes'   s¡  € Ý!×+Ò+°WÐ+Ñ=Ô=ˆÝ˜\¨=Ñ9Ô9ˆØ—-’- Ñ)Ô)ˆð
ð 
ð 
Ðð
 FÐE¨WÐEÑEÔEˆà(ð 	rñ 	rˆHØ˜{Ð*ÐVÐVÐVÕVÔVÐVÐVÐVÐV�8˜{ÐVÑVÔVÐVÕVÔVÑVÔVÐVÐVÕVÔV�8ÑVÔVÐVÕVÔV�8ÑVÔVÐVÐVÐVÕVÔVÑVÔVÐVÐVÕVÔV˜{ÑVÔVÐVÕVÔV˜{ÑVÔVÐVÐVÐVÐVÑVÐVÕVÔVÐ,VÈHÐ,VÐ,VÑVÔVÐVÑVÐVÐVÐVÑVÐVÕVÕVÔVÐVÑVÔVÑVÔVÐVÐVÐVØ—)’)˜H¨U°HÐ,=�)Ñ>Ô>ˆCØ"Ð"�3˜d�?Ð"Ð"Ð"Õ"Ô"Ð"Ð"Ð"Ð"�3˜dÐ"Ñ"Ô"Ð"Õ"Ô"Ñ"Ô"Ð"Ð"Õ"Ô"�3Ñ"Ô"Ð"Õ"Ô"�3Ñ"Ô"Ð"Ð"Õ"Ô"˜dÑ"Ô"Ð"Ð"Ñ"Ð"Ð"Ð"Ð"Ð"Ñ"Ð"Õ"Õ"Ô"Ð"Ñ"Ô"Ñ"Ô"Ð"Ð"Ð"Ð"Ð"Ø”7Ðq˜6Ðq�7�7˜6‘?”?Ðq hÐq�? hÒ.ÐqÐqÐqÕqÔqÐqÐqÐqÐq�? hÐqÑqÔqÐqÕqÔqÑqÔqÐqÐqÕqÔq�3ÑqÔqÐqÕqÔq�3ÑqÔqÐqÐqÕqÔq�7ÑqÔqÕqÔq˜6ÑqÔqÕqÔq�?ÑqÔqÕqÔq hÑqÔqÐqÐqÑqÐqÕqÔqÐ0q¸(Ð0qÐ0qÐ`c×`gÒ`gÐhnÑ`oÔ`oÐ0qÐ0qÑqÔqÐqÑqÐqÐqÐqÑqÐqÕqÕqÔqÐqÑqÔqÑqÔqÐqÐqÐqÐqÐqÐqÐqÐqÐqÐqÐqÑqð		rð 	rr4   c                 ó`
  — t                                d¬¦  «        }t          |d¦  «        }d„ |                     d¦  «        D ¦   «         }|                     d¦  «        }|                     d¦  «        }|                     d¦  «        }|                     d	¦  «        }|                     d
¦  «        }|                     d¦  «        }	||k     }
|
s×t          j        d|
fd||f¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        nddt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        nddœz  }t          j        d¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d }
||k     }
|
s×t          j        d|
fd||f¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        nddt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        nddœz  }t          j        d¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d }
||k     }
|
s×t          j        d|
fd||f¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        nddt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        nddœz  }t          j        d¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d }
||k     }
|
s×t          j        d|
fd||f¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        nddt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        nddœz  }t          j        d¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d }
||	k     }
|
s×t          j        d|
fd||	f¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        nddt          j        ¦   «         v st          j	        |	¦  «        rt          j
        |	¦  «        nddœz  }t          j        d¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d }
d S )Nr   r   r6   c                 ób   — g | ],}|                      d ¦  «        ¯|                      d ¦  «        ‘Œ-S r<   r>   r@   s     r2   rC   zLTestIndexHtmlScriptIntegration.test_script_tags_ordering.<locals>.<listcomp><   s1   € ÐUÐUÐU¨ÈÏÊÈeÉÌÐU�q—u’u˜U‘|”|ÐUÐUÐUr4   r7   r8   r9   r:   zjs/engine/monster_system.jszjs/engine/entity_renderer.jsz
js/main.js©ú<)z%(py0)s < %(py2)sÚidx_monsterÚidx_datarH   z9monster_system.js should precede wilderness_zone_packs.jsrI   r   Úidx_packz<wilderness_zone_packs.js must precede monster_pack_system.jsÚ
idx_ambushz<monster_pack_system.js must precede ambush_trigger_system.jsÚ
idx_entityz8ambush_trigger_system.js must precede entity_renderer.jsÚidx_mainz'entity_renderer.js must precede main.js)r   r&   r   rT   Úindexr   r)   r    r!   r"   r#   r   r$   r%   )r*   rV   rW   rG   rf   rg   rh   re   ri   rj   r+   rZ   r-   s                r2   Útest_script_tags_orderingz8TestIndexHtmlScriptIntegration.test_script_tags_ordering9   sŒ  € Ý!×+Ò+°WÐ+Ñ=Ô=ˆÝ˜\¨=Ñ9Ô9ˆØUÐU¨T¯]ª]¸8Ñ-DÔ-DÐUÑUÔUˆà×$Ò$Ð%GÑHÔHˆØ×$Ò$Ð%GÑHÔHˆØ ×&Ò&Ð'KÑLÔLˆ
Ø!×'Ò'Ð(EÑFÔFˆØ ×&Ò&Ð'EÑFÔFˆ
Ø×$Ò$ \Ñ2Ô2ˆà˜XÒ%ÐbÐbÐbÕbÔbÐbÐbÐbÐbˆ{˜XÐbÑbÔbÐbÕbÔbÑbÔbÐbÐbÕbÔbˆ{ÑbÔbÐbÕbÔbˆ{ÑbÔbÐbÐbÐbÕbÔbÑbÔbÐbÐbÕbÔb˜XÑbÔbÐbÕbÔb˜XÑbÔbÐbÐbÐbÐbÑbÐbÕbÔbÐ'bÑbÔbÐbÑbÐbÐbÐbÑbÐbÕbÕbÔbÐbÑbÔbÑbÔbÐbÐbÐbØ˜(Ò"ÐbÐbÐbÕbÔbÐbÐbÐbÐbˆx˜(ÐbÑbÔbÐbÕbÔbÑbÔbÐbÐbÕbÔbˆxÑbÔbÐbÕbÔbˆxÑbÔbÐbÐbÐbÕbÔbÑbÔbÐbÐbÕbÔb˜(ÑbÔbÐbÕbÔb˜(ÑbÔbÐbÐbÐbÐbÑbÐbÕbÔbÐ$bÑbÔbÐbÑbÐbÐbÐbÑbÐbÕbÕbÔbÐbÑbÔbÑbÔbÐbÐbÐbØ˜*Ò$ÐdÐdÐdÕdÔdÐdÐdÐdÐdˆx˜*ÐdÑdÔdÐdÕdÔdÑdÔdÐdÐdÕdÔdˆxÑdÔdÐdÕdÔdˆxÑdÔdÐdÐdÐdÕdÔdÑdÔdÐdÐdÕdÔd˜*ÑdÔdÐdÕdÔd˜*ÑdÔdÐdÐdÐdÐdÑdÐdÕdÔdÐ&dÑdÔdÐdÑdÐdÐdÐdÑdÐdÕdÕdÔdÐdÑdÔdÑdÔdÐdÐdÐdØ˜JÒ&ÐbÐbÐbÕbÔbÐbÐbÐbÐbˆz˜JÐbÑbÔbÐbÕbÔbÑbÔbÐbÐbÕbÔbˆzÑbÔbÐbÕbÔbˆzÑbÔbÐbÐbÐbÕbÔbÑbÔbÐbÐbÕbÔb˜JÑbÔbÐbÕbÔb˜JÑbÔbÐbÐbÐbÐbÑbÐbÕbÔbÐ(bÑbÔbÐbÑbÐbÐbÐbÑbÐbÕbÕbÔbÐbÑbÔbÑbÔbÐbÐbÐbØ˜HÒ$ÐOÐOÐOÕOÔOÐOÐOÐOÐOˆz˜HÐOÑOÔOÐOÕOÔOÑOÔOÐOÐOÕOÔOˆzÑOÔOÐOÕOÔOˆzÑOÔOÐOÐOÐOÕOÔOÑOÔOÐOÐOÕOÔO˜HÑOÔOÐOÕOÔO˜HÑOÔOÐOÐOÐOÐOÑOÐOÕOÔOÐ&OÑOÔOÐOÑOÐOÐOÐOÑOÐOÕOÕOÔOÐOÑOÔOÑOÔOÐOÐOÐOÐOÐOr4   ©r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r3   r`   rl   © r4   r2   r   r      sd   € € € € € Ø@Ð@ðVð Vð Vð Vðrð rð rð rð$Pð Pð Pð Pð Pð Pr4   r   c                   ó   — e Zd ZdZdZdd„ZdS )Ú&TestNodeJsSimulationAndAuraDecalStresszDNode.js runtime simulation of module execution and Canvas 2D decals.a’  
    import { isSafeHavenZone, getWildernessPacks, getZoneAmbushTriggers, SAFE_HAVEN_ZONES } from './client/webapp/js/data/wilderness_zone_packs.js';
    import { populateZonePacks, updateMonsterPackAI, renderLeaderAuraDecal } from './client/webapp/js/engine/monster_pack_system.js';
    import { activeAmbushTriggers, initZoneAmbushTriggers, updateAmbushTriggers } from './client/webapp/js/engine/ambush_trigger_system.js';

    // Mock Window environment
    globalThis.window = globalThis;
    window.SAFE_HAVEN_ZONES = SAFE_HAVEN_ZONES;
    window.isSafeHavenZone = isSafeHavenZone;
    window.getWildernessPacks = getWildernessPacks;
    window.getZoneAmbushTriggers = getZoneAmbushTriggers;
    window.populateZonePacks = populateZonePacks;
    window.updateMonsterPackAI = updateMonsterPackAI;
    window.renderLeaderAuraDecal = renderLeaderAuraDecal;
    window.getWildernessZoneMonsters = (z, fn) => populateZonePacks(z, fn);
    window.activeAmbushTriggers = activeAmbushTriggers;
    window.initZoneAmbushTriggers = initZoneAmbushTriggers;
    window.updateAmbushTriggers = updateAmbushTriggers;

    const results = {
      globalsDefined: {},
      auraStress: [],
      adversarialEdgeCases: [],
      highFreqStress: null,
      safeHavenAudit: null
    };

    const requiredGlobals = [
      'getWildernessZoneMonsters',
      'initZoneAmbushTriggers',
      'updateMonsterPackAI',
      'updateAmbushTriggers',
      'renderLeaderAuraDecal'
    ];
    for (const g of requiredGlobals) results.globalsDefined[g] = typeof window[g] === 'function';

    class MockCanvasContext {
      constructor() {
        this.saveCount = 0;
        this.restoreCount = 0;
        this.strokeStyle = '';
        this.fillStyle = '';
        this.globalAlpha = 1.0;
        this.ellipses = [];
      }
      save() { this.saveCount++; }
      restore() { this.restoreCount++; }
      beginPath() {}
      stroke() {}
      fill() {}
      ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle) {
        for (const arg of [x, y, radiusX, radiusY, rotation, startAngle, endAngle]) {
          if (typeof arg !== 'number' || Number.isNaN(arg) || !Number.isFinite(arg)) {
            throw new Error(`NaN/Non-finite argument in ellipse: ${arg}`);
          }
        }
        this.ellipses.push({ x, y, radiusX, radiusY, rotation, startAngle, endAngle });
      }
      createRadialGradient() { return { addColorStop() {} }; }
    }

    const canonicalAuras = [
      { type: 'HASTE', expectedColor: '#a855f7' },
      { type: 'DAMAGE_RESISTANCE', expectedColor: '#38bdf8' },
      { type: 'ELEMENTAL_EMPOWERMENT', expectedColor: '#f59e0b' },
      { type: 'VAMPIRIC', expectedColor: '#ef4444' },
      { type: 'MORTAL_MIGHT', expectedColor: '#ec4899' }
    ];

    for (const aura of canonicalAuras) {
      const ctx = new MockCanvasContext();
      const mob = { isPackLeader: true, hp: 5000, leaderAura: aura.type };
      let threw = false, errorMsg = null;
      try {
        renderLeaderAuraDecal(ctx, mob, 450.5, 320.25, 12.345);
      } catch (err) { threw = true; errorMsg = err.message; }

      results.auraStress.push({
        aura: aura.type, threw, errorMsg,
        saveBalanced: ctx.saveCount === 1 && ctx.restoreCount === 1,
        ellipseCount: ctx.ellipses.length,
        colorMatches: ctx.strokeStyle === aura.expectedColor && ctx.fillStyle === aura.expectedColor,
        allRadiiPositive: ctx.ellipses.every(e => e.radiusX > 0 && e.radiusY > 0),
        yOffsetApplied: ctx.ellipses.every(e => Math.abs(e.y - 324.25) < 0.001)
      });
    }

    const edgeCases = [
      { name: 'dead_mob', mob: { isPackLeader: true, hp: 0, leaderAura: 'HASTE' }, x: 100, y: 100, t: 1.0, expectRender: false },
      { name: 'negative_hp', mob: { isPackLeader: true, hp: -250, leaderAura: 'HASTE' }, x: 100, y: 100, t: 1.0, expectRender: false },
      { name: 'non_leader', mob: { isPackLeader: false, hp: 1000, leaderAura: 'HASTE' }, x: 100, y: 100, t: 1.0, expectRender: false },
      { name: 'undef_aura', mob: { isPackLeader: true, hp: 1000, leaderAura: undefined }, x: 100, y: 100, t: 1.0, expectRender: true, expectColor: '#a855f7' },
      { name: 'unknown_aura', mob: { isPackLeader: true, hp: 1000, leaderAura: 'CHAOS' }, x: 100, y: 100, t: 1.0, expectRender: true, expectColor: '#a855f7' },
      { name: 'negative_coords', mob: { isPackLeader: true, hp: 1000, leaderAura: 'VAMPIRIC' }, x: -999.5, y: -450.2, t: 2.5, expectRender: true },
      { name: 'large_coords', mob: { isPackLeader: true, hp: 1000, leaderAura: 'DAMAGE_RESISTANCE' }, x: 1e6, y: 2e6, t: 3.0, expectRender: true },
      { name: 'undef_time', mob: { isPackLeader: true, hp: 1000, leaderAura: 'HASTE' }, x: 50, y: 50, t: undefined, expectRender: true },
      { name: 'zero_time', mob: { isPackLeader: true, hp: 1000, leaderAura: 'HASTE' }, x: 50, y: 50, t: 0, expectRender: true },
      { name: 'negative_time', mob: { isPackLeader: true, hp: 1000, leaderAura: 'MORTAL_MIGHT' }, x: 50, y: 50, t: -543.21, expectRender: true }
    ];

    for (const ec of edgeCases) {
      const ctx = new MockCanvasContext();
      let threw = false, errorMsg = null;
      try {
        renderLeaderAuraDecal(ctx, ec.mob, ec.x, ec.y, ec.t);
      } catch (err) { threw = true; errorMsg = err.message; }

      results.adversarialEdgeCases.push({
        name: ec.name, threw, errorMsg,
        saveBalanced: ec.expectRender ? (ctx.saveCount === 1 && ctx.restoreCount === 1) : (ctx.saveCount === 0 && ctx.restoreCount === 0),
        renderedMatchesExpectation: (ctx.ellipses.length === 2) === ec.expectRender,
        colorMatches: ec.expectColor ? ctx.strokeStyle === ec.expectColor : true
      });
    }

    // High Frequency 10,000 frames stress loop
    const hfCtx = new MockCanvasContext();
    const hfMob = { isPackLeader: true, hp: 5000, leaderAura: 'MORTAL_MIGHT' };
    const t0 = performance.now();
    let hfThrew = false, hfErrMsg = null;
    try {
      for (let f = 0; f < 10000; f++) {
        renderLeaderAuraDecal(hfCtx, hfMob, 100 + (f % 50), 200 + (f % 50), f * 0.016);
      }
    } catch (e) { hfThrew = true; hfErrMsg = e.message; }
    const durationMs = performance.now() - t0;
    results.highFreqStress = {
      iterations: 10000,
      threw: hfThrew,
      errorMsg: hfErrMsg,
      durationMs,
      avgMsPerFrame: durationMs / 10000,
      totalEllipses: hfCtx.ellipses.length
    };

    // Safe Haven Zone Audit
    const dummyCreator = (cfg) => ({ ...cfg });
    const hideoutMobs = populateZonePacks('zone_player_hideout', dummyCreator);
    const sanctuaryMobs = populateZonePacks('zone_boundless_sanctuary', dummyCreator);
    const wildernessMobs = populateZonePacks('zone_tang_kiem_nhai', dummyCreator);
    results.safeHavenAudit = {
      hideoutMobCount: hideoutMobs.length,
      sanctuaryMobCount: sanctuaryMobs.length,
      wildernessMobCount: wildernessMobs.length,
      wildernessHasLeader: wildernessMobs.some(m => m.isPackLeader && m.leaderAura)
    };

    console.log(JSON.stringify(results, null, 2));
    r   Nc                 óà  — ddd| j         g}t          j        |t          t          ¦  «        dd¬¦  «        }|j        }d}||k    }|sÇt          j        d|fd||f¦  «        d	t          j	        ¦   «         v st          j
        |¦  «        rt          j        |¦  «        nd	t          j        |¦  «        t          j        |¦  «        d
œz  }t          j        d|j        › �¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}}t!          j        |j        ¦  «        }|d                              ¦   «         D ]Á\  }	}
d}|
|u }|s°t          j        d|fd|
|f¦  «        dt          j	        ¦   «         v st          j
        |
¦  «        rt          j        |
¦  «        ndt          j        |¦  «        dœz  }t          j        d|	› d�¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d x}}ŒÂ|d         }t)          |¦  «        }d}||k    }|sÇt          j        d|fd||f¦  «        dt          j	        ¦   «         v st          j
        t(          ¦  «        rt          j        t(          ¦  «        ndt          j        |¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}x}}|d         D �]˜}|d         }|d         }| }|s[t          j        d |› d!|d"         › �¦  «        d#z   d$t          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d x}}|d%         }|sSt          j        d |› d&�¦  «        d'z   d$t          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d }|d(         }d)}||k    }|s�t          j        d|fd*||f¦  «        t          j        |¦  «        t          j        |¦  «        d+œz  }t          j        d |› d,|d(         › �¦  «        d-z   d.|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}}|d/         }|sSt          j        d |› d0�¦  «        d'z   d$t          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d }|d1         }|sSt          j        d |› d2�¦  «        d'z   d$t          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d }|d3         }|sSt          j        d |› d4�¦  «        d'z   d$t          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d }�Œš|d5         D �]”}|d6         }|d         }| }|s[t          j        d7|› d!|d"         › �¦  «        d#z   d$t          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d x}}|d%         }|sSt          j        d7|› d8�¦  «        d'z   d$t          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d }|d9         }|sSt          j        d7|› d:�¦  «        d'z   d$t          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d }|d/         }|sSt          j        d7|› d;�¦  «        d'z   d$t          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d }�Œ–|d<         }|d         }| }|sXt          j        d=|d"         › �¦  «        d#z   d$t          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d x}}|d>         }d?}||k    }|sŠt          j        d|fd*||f¦  «        t          j        |¦  «        t          j        |¦  «        d+œz  }t          j        d@|d>         › �¦  «        d-z   d.|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}}|dA         }dB}||k     }|sŒt          j        dC|fdD||f¦  «        t          j        |¦  «        t          j        |¦  «        d+œz  }t          j        dE|dA         dF›dG�¦  «        d-z   d.|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}}|dH         }|dI         }d}||k    }|s‹t          j        d|fd*||f¦  «        t          j        |¦  «        t          j        |¦  «        d+œz  }t          j        dJ|dI         › dK�¦  «        d-z   d.|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}}|dL         }d}||k    }|s‹t          j        d|fd*||f¦  «        t          j        |¦  «        t          j        |¦  «        d+œz  }t          j        dM|dL         › dK�¦  «        d-z   d.|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}}|dN         }d}||k    }|s�t          j        dO|fdP||f¦  «        t          j        |¦  «        t          j        |¦  «        d+œz  }t          j        dQ¦  «        d-z   d.|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}}|dR         }d}||u }|s�t          j        d|fdS||f¦  «        t          j        |¦  «        t          j        |¦  «        d+œz  }t          j        dT¦  «        d-z   d.|iz  }t          t          j        |¦  «        ¦  «        ‚d x}x}}d S )UNÚnodez--input-type=modulez-eT)ÚcwdÚcapture_outputÚtextr   rO   )z2%(py2)s
{%(py2)s = %(py0)s.returncode
} == %(py5)sÚres)r   r   r   z#Node.js script failed with stderr: z
>assert %(py7)sÚpy7ÚglobalsDefined)Úis)z%(py0)s is %(py3)sÚis_defr   zGlobal window.z was not defined!r   r   Ú
auraStressé   )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)sr(   )r   r   r   r{   zassert %(py9)srR   ÚauraÚthrewzAura z threw: ÚerrorMsgz
>assert not %(py1)sÚpy1ÚsaveBalancedz save/restore unbalanced!z
>assert %(py1)sÚellipseCounté   )z%(py1)s == %(py4)s)r„   r   z expected 2 ellipses, got ú
>assert %(py6)srQ   ÚcolorMatchesz color mismatch!ÚallRadiiPositivez non-positive radius detected!ÚyOffsetAppliedz% y-offset (+4) not applied correctly!ÚadversarialEdgeCasesÚnamez
Edge case z save/restore state unbalanced!ÚrenderedMatchesExpectationz render expectation mismatch!z fallback color mismatch!ÚhighFreqStressz10k stress threw: ÚtotalEllipsesi N  zExpected 20,000 ellipses, got ÚavgMsPerFramegš™™™™™©?rc   )z%(py1)s < %(py4)szRender decal too slow: z.4fzms/frameÚsafeHavenAuditÚhideoutMobCountzSafe Haven hideout spawned z mobs!ÚsanctuaryMobCountzSafe Haven sanctuary spawned ÚwildernessMobCount)ú>)z%(py1)s > %(py4)szWilderness zone spawned 0 mobs!ÚwildernessHasLeader)z%(py1)s is %(py4)sz3Wilderness zone missing rare pack leader with aura!)ÚNODE_TEST_SCRIPTÚ
subprocessÚrunÚstrÚPROJECT_ROOTÚ
returncoder   r)   r    r!   r"   r#   r   Ústderrr$   r%   ÚjsonÚloadsÚstdoutÚitemsr(   )r*   Úcmdrz   r+   Ú@py_assert4r,   r1   Ú@py_format8r   r�   r~   r/   r0   Ú@py_assert6r[   r^   Úaura_resÚ	aura_nameÚ@py_assert0rZ   Ú@py_format2r-   Ú@py_format7Úec_resÚec_nameÚhfÚshs                              r2   Ú#test_run_node_simulation_and_verifyzJTestNodeJsSimulationAndAuraDecalStress.test_run_node_simulation_and_verifyå   s³  € ØÐ,¨d°DÔ4IÐJˆÝŒn˜S¥c­,Ñ&7Ô&7ÈÐSWÐXÑXÔXˆØŒ~ÐV ÐVˆ~ Ò"ÐVÐVÐVÕVÔVÐVÐVÐVÐVˆ~ ÐVÑVÔVÐVÕVÔVÑVÔVÐVÐVÕVÔVˆsÑVÔVÐVÕVÔVˆsÑVÔVÐVÐVÕVÔVˆ~ÑVÔVÕVÔV ÑVÔVÐVÐVÑVÐVÕVÔVÐ$VÈ#Ì*Ð$VÐ$VÑVÔVÐVÑVÐVÐVÐVÑVÐVÕVÕVÔVÐVÑVÔVÑVÔVÐVÐVÐVÐVÐVÐVÐVåŒz˜#œ*Ñ%Ô%ˆð !Ð!1Ô2×8Ò8Ñ:Ô:ð 	Lð 	L‰LˆD�&Ø!ÐK�6˜T�>ÐKÐKÐKÕKÔKÐKÐKÐKÐK�6˜TÐKÑKÔKÐKÕKÔKÑKÔKÐKÐKÕKÔK�6ÑKÔKÐKÕKÔK�6ÑKÔKÐKÐKÕKÔK˜TÑKÔKÐKÐKÑKÐKÕKÔKÐ#K°DÐ#KÐ#KÐ#KÑKÔKÐKÑKÐKÐKÐKÑKÐKÕKÕKÔKÐKÑKÔKÑKÔKÐKÐKÐKÐKÐKÐKð ˜Ô%Ð+�sÐ%Ñ&Ô&Ð+¨!Ð+Ð&¨!Ò+Ð+Ð+Ð+Õ+Ô+Ð+Ð+Ð+Ð+Ð&¨!Ð+Ñ+Ô+Ð+Õ+Ô+Ñ+Ô+Ð+Ð+Õ+Ô+�sÑ+Ô+Ð+Õ+Ô+�sÑ+Ô+Ð+Ð+Õ+Ô+Ð%Ñ+Ô+Õ+Ô+Ð&Ñ+Ô+Õ+Ô+¨!Ñ+Ô+Ð+Ð+Ñ+Ð+Ð+Ð+Ð+Ð+Ñ+Ð+Õ+Õ+Ô+Ð+Ñ+Ô+Ñ+Ô+Ð+Ð+Ð+Ð+Ð+Ð+Ð+Ð+Ð+Ø˜\Ô*ð 	hñ 	hˆHØ  Ô(ˆIØ Ô(Ð[Ð(Ð(Ð[Ð(Ð[Õ[Ô[Ð*[°)Ð*[Ð*[ÀXÈjÔEYÐ*[Ð*[Ñ[Ô[Ð[Ñ[Ð[Õ[Ô[Ð(Ñ[Ô[Ð[Ñ[Ð[Õ[Õ[Ô[Ð[Ñ[Ô[Ñ[Ô[Ð[Ð[Ð[Ð[Ð[Ø˜NÔ+ÐYÐ+ÐYÕYÔYÐ-Y°YÐ-YÐ-YÐ-YÑYÔYÐYÑYÐYÕYÔYÐ+ÑYÔYÐYÑYÐYÕYÕYÔYÐYÑYÔYÑYÔYÐYÐYÐYØ˜NÔ+Ðy¨qÐyÐ+¨qÒ0ÐyÐyÐyÕyÔyÐyÐyÐyÐyÐ+¨qÐyÑyÔyÕyÔyÐ+ÑyÔyÕyÔy¨qÑyÔyÐyÐyÑyÐyÕyÔyÐ2y¸)Ð2yÐ2yÐ_gÐhvÔ_wÐ2yÐ2yÑyÔyÐyÑyÐyÐyÐyÑyÐyÕyÕyÔyÐyÑyÔyÑyÔyÐyÐyÐyÐyÐyÐyÐyØ˜NÔ+ÐPÐ+ÐPÕPÔPÐ-P°YÐ-PÐ-PÐ-PÑPÔPÐPÑPÐPÕPÔPÐ+ÑPÔPÐPÑPÐPÕPÕPÔPÐPÑPÔPÑPÔPÐPÐPÐPØÐ.Ô/ÐbÐ/ÐbÕbÔbÐ1b¸Ð1bÐ1bÐ1bÑbÔbÐbÑbÐbÕbÔbÐ/ÑbÔbÐbÑbÐbÕbÕbÔbÐbÑbÔbÑbÔbÐbÐbÐbØÐ,Ô-ÐgÐ-ÐgÕgÔgÐ/g°yÐ/gÐ/gÐ/gÑgÔgÐgÑgÐgÕgÔgÐ-ÑgÔgÐgÑgÐgÕgÕgÔgÐgÑgÔgÑgÔgÐgÐgÐgÑgð Ð1Ô2ð 	[ñ 	[ˆFØ˜V”nˆGØ˜g”ÐZ�Ð&ÐZÐ&ÐZÕZÔZÐ(Z°WÐ(ZÐ(ZÀfÈZÔFXÐ(ZÐ(ZÑZÔZÐZÑZÐZÕZÔZ�ÑZÔZÐZÑZÐZÕZÕZÔZÐZÑZÔZÑZÔZÐZÐZÐZÐZÐZØ˜.Ô)Ð`Ð)Ð`Õ`Ô`Ð+`¸Ð+`Ð+`Ð+`Ñ`Ô`Ð`Ñ`Ð`Õ`Ô`Ð)Ñ`Ô`Ð`Ñ`Ð`Õ`Õ`Ô`Ð`Ñ`Ô`Ñ`Ô`Ð`Ð`Ð`ØÐ6Ô7ÐlÐ7ÐlÕlÔlÐ9lÀgÐ9lÐ9lÐ9lÑlÔlÐlÑlÐlÕlÔlÐ7ÑlÔlÐlÑlÐlÕlÕlÔlÐlÑlÔlÑlÔlÐlÐlÐlØ˜.Ô)ÐZÐ)ÐZÕZÔZÐ+Z¸Ð+ZÐ+ZÐ+ZÑZÔZÐZÑZÐZÕZÔZÐ)ÑZÔZÐZÑZÐZÕZÕZÔZÐZÑZÔZÑZÔZÐZÐZÐZÑZð Ð"Ô#ˆØ�g”;ÐE�;ˆÐEˆÐEÕEÔEÐ E°R¸
´^Ð EÐ EÑEÔEÐEÑEÐEÕEÔE�;ÑEÔEÐEÑEÐEÕEÕEÔEÐEÑEÔEÑEÔEÐEÐEÐEÐEÐEØ�/Ô"Ðc eÐcÐ" eÒ+ÐcÐcÐcÕcÔcÐcÐcÐcÐcÐ" eÐcÑcÔcÕcÔcÐ"ÑcÔcÕcÔc eÑcÔcÐcÐcÑcÐcÕcÔcÐ-cÈbÐQ`ÔNaÐ-cÐ-cÑcÔcÐcÑcÐcÐcÐcÑcÐcÕcÕcÔcÐcÑcÔcÑcÔcÐcÐcÐcÐcÐcÐcÐcØ�/Ô"Ðf TÐfÐ" TÒ)ÐfÐfÐfÕfÔfÐfÐfÐfÐfÐ" TÐfÑfÔfÕfÔfÐ"ÑfÔfÕfÔf TÑfÔfÐfÐfÑfÐfÕfÔfÐ+fÀRÈÔEXÐ+fÐ+fÐ+fÐ+fÑfÔfÐfÑfÐfÐfÐfÑfÐfÕfÕfÔfÐfÑfÔfÑfÔfÐfÐfÐfÐfÐfÐfÐfð Ð"Ô#ˆØÐ#Ô$Ðf¨ÐfÐ$¨Ò)ÐfÐfÐfÕfÔfÐfÐfÐfÐfÐ$¨ÐfÑfÔfÕfÔfÐ$ÑfÔfÕfÔf¨ÑfÔfÐfÐfÑfÐfÕfÔfÐ+fÈÐL]ÔI^Ð+fÐ+fÐ+fÑfÔfÐfÑfÐfÐfÐfÑfÐfÕfÕfÔfÐfÑfÔfÑfÔfÐfÐfÐfÐfÐfÐfÐfØÐ%Ô&Ðl¨!ÐlÐ&¨!Ò+ÐlÐlÐlÕlÔlÐlÐlÐlÐlÐ&¨!ÐlÑlÔlÕlÔlÐ&ÑlÔlÕlÔl¨!ÑlÔlÐlÐlÑlÐlÕlÔlÐ-lÈRÐPcÔMdÐ-lÐ-lÐ-lÑlÔlÐlÑlÐlÐlÐlÑlÐlÕlÕlÔlÐlÑlÔlÑlÔlÐlÐlÐlÐlÐlÐlÐlØÐ&Ô'ÐN¨!ÐNÐ'¨!Ò+ÐNÐNÐNÕNÔNÐNÐNÐNÐNÐ'¨!ÐNÑNÔNÕNÔNÐ'ÑNÔNÕNÔN¨!ÑNÔNÐNÐNÑNÐNÕNÔNÐ-NÑNÔNÐNÑNÐNÐNÐNÑNÐNÕNÕNÔNÐNÑNÔNÑNÔNÐNÐNÐNÐNÐNÐNÐNØÐ'Ô(Ðg¨DÐgÐ(¨DÐ0ÐgÐgÐgÕgÔgÐgÐgÐgÐgÐ(¨DÐgÑgÔgÕgÔgÐ(ÑgÔgÕgÔg¨DÑgÔgÐgÐgÑgÐgÕgÔgÐ2gÑgÔgÐgÑgÐgÐgÐgÑgÐgÕgÕgÔgÐgÑgÔgÑgÔgÐgÐgÐgÐgÐgÐgÐgÐgÐgr4   rm   )rn   ro   rp   rq   r˜   r°   rr   r4   r2   rt   rt   L   s>   € € € € € ØNÐNðTÐðl)hð )hð )hð )hð )hð )hr4   rt   c                   ó   — e Zd ZdZdd„ZdS )ÚTestEntityRendererDecalCallSitezWVerifies entity_renderer.js has valid call site and layering for renderLeaderAuraDecal.r   Nc           	      óÎ  — t           dz  }|j        } |¦   «         }|s‹ddt          j        ¦   «         v st	          j        |¦  «        rt	          j        |¦  «        ndt	          j        |¦  «        t	          j        |¦  «        dœz  }t          t	          j        |¦  «        ¦  «        ‚d x}}| 	                    d¬¦  «        }d}||v }|s¬t	          j
        d|fd	||f¦  «        t	          j        |¦  «        d
t          j        ¦   «         v st	          j        |¦  «        rt	          j        |¦  «        nd
dœz  }t	          j        d¦  «        dz   d|iz  }	t          t	          j        |	¦  «        ¦  «        ‚d x}}d}||v }|s¬t	          j
        d|fd	||f¦  «        t	          j        |¦  «        d
t          j        ¦   «         v st	          j        |¦  «        rt	          j        |¦  «        nd
dœz  }t	          j        d¦  «        dz   d|iz  }	t          t	          j        |	¦  «        ¦  «        ‚d x}}|                     d¦  «        }
|                     d¦  «        }|                     d¦  «        }d}| }|
|k    }|s¬t	          j
        d|fd|
|f¦  «        dt          j        ¦   «         v st	          j        |
¦  «        rt	          j        |
¦  «        ndt	          j        |¦  «        dœz  }t	          j        d¦  «        dz   d|iz  }t          t	          j        |¦  «        ¦  «        ‚d x}x}}d}| }||k    }|s¬t	          j
        d|fd||f¦  «        dt          j        ¦   «         v st	          j        |¦  «        rt	          j        |¦  «        ndt	          j        |¦  «        dœz  }t	          j        d¦  «        dz   d|iz  }t          t	          j        |¦  «        ¦  «        ‚d x}x}}d}| }||k    }|s¬t	          j
        d|fd||f¦  «        dt          j        ¦   «         v st	          j        |¦  «        rt	          j        |¦  «        ndt	          j        |¦  «        dœz  }t	          j        d¦  «        dz   d|iz  }t          t	          j        |¦  «        ¦  «        ‚d x}x}}|
|k     }||k     }|r|�s!t	          j
        d||fd |
||f¦  «        dt          j        ¦   «         v st	          j        |
¦  «        rt	          j        |
¦  «        nddt          j        ¦   «         v st	          j        |¦  «        rt	          j        |¦  «        nddt          j        ¦   «         v st	          j        |¦  «        rt	          j        |¦  «        ndd!œz  }t	          j        d"|
› d#|› d$|› d%�¦  «        dz   d|iz  }t          t	          j        |¦  «        ¦  «        ‚d x}}d S )&Nzentity_renderer.jszAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}Úrenderer_pathr   r   r   zwindow.renderLeaderAuraDecalrD   )z%(py1)s in %(py3)sÚcontent)r„   r   z=Missing renderLeaderAuraDecal call site in entity_renderer.jsr   r   zm.isPackLeaderz0Missing isPackLeader guard in entity_renderer.jszctx.ellipse(mPos.x, mPos.y + 4zAnimationEngine.drawEntityFrameé   )ú!=)z%(py0)s != -%(py3)sÚ
shadow_idxr   z6Monster shadow ellipse not found in entity_renderer.jsrˆ   rQ   Ú	decal_idxz6Leader aura decal call not found in entity_renderer.jsÚ
sprite_idxz?AnimationEngine.drawEntityFrame not found in entity_renderer.js)rd   rd   )z%(py0)s < %(py3)sz%(py3)s < %(py4)s)r   r   r   z*Invalid visual layering! Expected shadow (z) < decal (z) < sprite (ú))Ú
ENGINE_DIRr   r    r!   r   r"   r#   r$   r%   r&   r)   r   rU   )r*   r´   r+   r,   r-   rµ   r©   r/   r0   r1   r¸   r¹   rº   r¤   r«   s                  r2   Ú test_callsite_in_entity_rendererz@TestEntityRendererDecalCallSite.test_callsite_in_entity_renderer  s�  € Ý"Ð%9Ñ9ˆØÔ#Ð%Ð#Ð#Ñ%Ô%Ð%Ð%Ð%Ð%Ð%Õ%Ô%Ñ%Ô%Ð%Ð%Õ%Ô%ˆ}Ñ%Ô%Ð%Õ%Ô%ˆ}Ñ%Ô%Ð%Ð%Õ%Ô%Ð#Ñ%Ô%Õ%Ô%Ð%Ñ%Ô%Ð%Ð%Ñ%Ð%Õ%Õ%Ô%Ð%Ñ%Ô%Ñ%Ô%Ð%Ð%Ð%Ð%Ð%Ø×)Ò)°7Ð)Ñ;Ô;ˆà-ÐyÐ-°Ð8ÐyÐyÐyÕyÔyÐyÐyÐyÐyÐ-°ÐyÑyÔyÕyÔyÐ-ÑyÔyÐyÕyÔyÑyÔyÐyÐyÕyÔy°ÑyÔyÐyÕyÔy°ÑyÔyÐyÐyÐyÐyÑyÐyÕyÔyÐ:yÑyÔyÐyÑyÐyÐyÐyÑyÐyÕyÕyÔyÐyÑyÔyÑyÔyÐyÐyÐyÐyÐyØÐ^Ð 7Ð*Ð^Ð^Ð^Õ^Ô^Ð^Ð^Ð^Ð^Ð 7Ð^Ñ^Ô^Õ^Ô^ÐÑ^Ô^Ð^Õ^Ô^Ñ^Ô^Ð^Ð^Õ^Ô^ 7Ñ^Ô^Ð^Õ^Ô^ 7Ñ^Ô^Ð^Ð^Ð^Ð^Ñ^Ð^Õ^Ô^Ð,^Ñ^Ô^Ð^Ñ^Ð^Ð^Ð^Ñ^Ð^Õ^Õ^Ô^Ð^Ñ^Ô^Ñ^Ô^Ð^Ð^Ð^Ð^Ð^à—\’\Ð"BÑCÔCˆ
Ø—L’LÐ!?Ñ@Ô@ˆ	Ø—\’\Ð"CÑDÔDˆ
àÐY˜a˜RÐYˆz˜RÒÐYÐYÐYÕYÔYÐYÐYÐYÐYˆz˜RÐYÑYÔYÐYÕYÔYÑYÔYÐYÐYÕYÔYˆzÑYÔYÐYÕYÔYˆzÑYÔYÐYÐYÕYÔY˜aÑYÔYÐYÐYÑYÐYÕYÔYÐ!YÑYÔYÐYÑYÐYÐYÐYÑYÐYÕYÕYÔYÐYÑYÔYÑYÔYÐYÐYÐYÐYÐYÐYÐYØÐX˜Q˜BÐXˆy˜BŠÐXÐXÐXÕXÔXÐXÐXÐXÐXˆy˜BÐXÑXÔXÐXÕXÔXÑXÔXÐXÐXÕXÔXˆyÑXÔXÐXÕXÔXˆyÑXÔXÐXÐXÕXÔX˜QÑXÔXÐXÐXÑXÐXÕXÔXÐ XÑXÔXÐXÑXÐXÐXÐXÑXÐXÕXÕXÔXÐXÑXÔXÑXÔXÐXÐXÐXÐXÐXÐXÐXØÐb˜a˜RÐbˆz˜RÒÐbÐbÐbÕbÔbÐbÐbÐbÐbˆz˜RÐbÑbÔbÐbÕbÔbÑbÔbÐbÐbÕbÔbˆzÑbÔbÐbÕbÔbˆzÑbÔbÐbÐbÕbÔb˜aÑbÔbÐbÐbÑbÐbÕbÔbÐ!bÑbÔbÐbÑbÐbÐbÐbÑbÐbÕbÕbÔbÐbÑbÔbÑbÔbÐbÐbÐbÐbÐbÐbÐbØ˜IÒ2ð 	
˜I¨
Ò2ð 	
ð 	
ð 	
ð 	
ñ 	
õ 	
ìð	
ð 	
ð 	
ð 	
ð 	
ˆz˜I¨
ð 	
ñ 	
ô 	
ð 	
õ 	
ä	ñ	
ô 	
ð 	
ð 	
õ 	
ìð ñ 	
ô 	
ð 	
õ 	
ä 	ð ñ 	
ô 	
ð 	
ð 	
ð 	
õ 	
ä	ñ	
ô 	
ð 	
ð 	
õ 	
ìð &ñ 	
ô 	
ð 	
õ 	
ä 	ð &ñ 	
ô 	
ð 	
ð 	
ð 	
õ 	
ä	ñ	
ô 	
ð 	
ð 	
õ 	
ìð )3ñ 	
ô 	
ð 	
õ 	
ä 	ð )3ñ 	
ô 	
ð 	
ð 	
ð 	
ð 	
ñ 	
ð 	
õ 	
ìð u¸ÐtÐtÐPYÐtÐtÐgqÐtÐtÐtñ	
ô 	
ð 	
ñ 	
ð 	
ð 	
ð 	
ñ 	
ð 	
õ 	
õ 	
ìð	
ñ 	
ô 	
ñ 	
ô 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
r4   rm   )rn   ro   rp   rq   r½   rr   r4   r2   r²   r²     s.   € € € € € ØaÐað
ð 
ð 
ð 
ð 
ð 
r4   r²   )rq   Úbuiltinsr    Ú_pytest.assertion.rewriteÚ	assertionÚrewriter   rŸ   Úosr™   Úpathlibr   ÚpytestÚbs4r   Ú__file__ÚresolveÚparentrœ   Ú
WEBAPP_DIRr   ÚDATA_DIRr¼   r   rt   r²   rr   r4   r2   ú<module>rË      sk  ððð ð € € € € € € € € € € € € €€€€Ø 	€	€	€	Ø Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø €€€Ø Ð Ð Ð Ð Ð àˆt�H‰~Œ~×%Ò%Ñ'Ô'Ô.Ô5Ô<€Ø˜HÑ$ xÑ/€
Ø˜,Ñ&€
Ø˜Ñ˜vÑ%€Ø˜$Ñ Ñ)€
ð,Pð ,Pð ,Pð ,Pð ,Pñ ,Pô ,Pð ,Pð^Bhð Bhð Bhð Bhð Bhñ Bhô Bhð BhðJ
ð 
ð 
ð 
ð 
ñ 
ô 
ð 
ð 
ð 
r4   