#!/usr/bin/env python3
"""
Build the Dubai (/ae) cinematic page from the KL cinematic page.

    python3 tools/apply_ae.py resources/views/cinematic/home.blade.php resources/views/cinematic/ae.blade.php

Every replacement is anchored on text that exists in the KL template (v9.x / v10.x).
The script prints one line per rule: OK, or MISS when the anchor was not found.
A MISS means the KL page changed after v9.9 - fix that one rule by hand (see HANDOFF.md section 5).
Nothing in the KL file is modified.
"""
import re, sys
SRC, DST = sys.argv[1], sys.argv[2]
A = '/cinematic/ae/assets/'          # AE-only assets (films, photos, phone shot)
t = open(SRC, encoding='utf-8').read()
log = []
def lit(name, old, new, n=None):
    global t
    c = t.count(old)
    if c == 0 or (n is not None and c != n): log.append(f'MISS  {name}  (found {c})'); return
    t = t.replace(old, new); log.append(f'OK    {name}  x{c}')
def rx(name, pat, new, flags=re.S):
    global t
    t2, c = re.subn(pat, new, t, flags=flags)
    if c == 0: log.append(f'MISS  {name}'); return
    t = t2; log.append(f'OK    {name}  x{c}')

# ---------------------------------------------------------------- 0. films (scrubbed videos)
rx('film connect',  r"(['\"])(?:[^'\"]*connect-film[^'\"]*\.(?:mp4|webm)|/_blob/b46358d1b5df530dbc2e89ea78231311)\1", f"'{A}connect-film-v2.mp4'")
rx('film beyond A', r"(['\"])(?:[^'\"]*beyond-a[^'\"]*\.(?:mp4|webm)|/_blob/bbe80baddf80a4adbd91560fbf398a76)\1",     f"'{A}beyond-a-v2.mp4'")
rx('film beyond B', r"(['\"])(?:[^'\"]*beyond-b[^'\"]*\.(?:mp4|webm)|/_blob/e9b1ccf77703bdcdbb12bb39ec1fa10e)\1",     f"'{A}beyond-b.mp4'")

rx('lid-open film', r"(['\"])(?:[^'\"]*lid-open[^'\"]*\.(?:mp4|webm)|/_blob/f7fce263f7693ec20805da670f461739)\1", f"'{A}lid-open.mp4'")
rx('lap_open still', r'(<img class="lapopen"[^>]*src=")[^"]*(")', r'\g<1>' + A + r'lap_open.webp\g<2>')

rx('header comment', r'^\{\{--.*?--\}\}', '{{-- PropertyLab cinematic page, Dubai (/ae). Generated from cinematic/home.blade.php by tools/apply_ae.py. Do not hand-edit; rebuild instead. --}}', flags=0)

# ---------------------------------------------------------------- 1. page meta
lit('title', '<title>PropertyLab AI · Cross-border property, decided on evidence</title>',
    '<title>PropertyLab AI · Dubai property, decided on evidence</title>')

# ---------------------------------------------------------------- 2. Discover laptop screen
lit('country tabs',
    '<span>&#127469;&#127472; Hong Kong <em>313</em></span><span class="on">&#127474;&#127486; Malaysia <em>67</em></span><span>&#127462;&#127466; United Arab Emirates <em>951</em></span>',
    '<span>&#127469;&#127472; Hong Kong <em>319</em></span><span>&#127474;&#127486; Malaysia <em>67</em></span><span class="on">&#127462;&#127466; United Arab Emirates <em>951</em></span>')
lit('price chips', '<span>Under RM 500k</span><span>RM 500k - 900k</span><span>Over RM 900k</span>',
    '<span>Under AED 1M</span><span>AED 1M - 5M</span><span>Over AED 5M</span>')
rx('quality chips -> communities', r'<div><b>Project quality</b>.*?</div></div>',
   '<div><b>Community</b> <small>Dubai, 786 projects</small><div class="d-chips q"><span>Dubai Islands (81)</span><span>JVC (59)</span><span>Dubai South (53)</span><span class="on">Business Bay (29)</span></div></div>')
rx('assumptions', r'<p class="d-assume">.*?</p>',
   '<p class="d-assume"><b>Cost assumptions</b> &middot; 4% DLD transfer fee &middot; cash or developer payment plan &middot; service charge by community. <b>Change &rarr;</b></p>')
rx('project count', r'67 projects &middot; showing 1-24', '786 projects &middot; showing 1-24')
CARD = lambda img,tags,loc,name,dev,price,extra: (f'<div class="d-card"><div class="d-img" style="background-image:url({A}{img})"><u class="tl">United Arab Emirates</u>{tags}</div>\n'
        f'              <small>{loc}</small><b>{name}</b><small>by {dev}</small><small class="f">From</small><strong>{price}</strong>{extra}</div>\n')
cards = ('<div class="d-grid">\n' +
  CARD('ae-card-ritz.jpg','<u class="tr">&#9733; Featured</u><u class="br">Under construction</u>','Business Bay, Dubai','The Ritz-Carlton Residences','Kappa Acca','AED 29,900,000 - 60,000,000',
       '\n              <div class="d-tags"><i class="r">vs market +137%</i><i class="r">Net yield 0.7%</i><i class="g">5-yr growth +46%</i><i class="g">Branded</i></div>') +
  CARD('ae-card-golf-trails.jpg','<u class="br">New Launch</u>','Dubai South (Dubai World Central)','Golf Trails','Emaar Properties','AED 1,060,000','') +
  CARD('ae-card-lincoln-star.jpg','<u class="br">New Launch</u>','Dubai South (Dubai World Central)','Lincoln Star Residence 3','Lincoln Star Real Estate','AED 650,000','') +
  CARD('ae-card-calisi.jpg','<u class="br">New Launch</u>','Dubai South (Dubai World Central)','Calisi','Zoya Developments','AED 685,000','') +
  '          </div>\n          <div class="d-map"')
rx('discover cards', r'<div class="d-grid">.*?</div>\s*<div class="d-map"', cards)
rx('discover map labels', r"\[\['Selayang'.*?\]\]\.forEach",
   "[['Dubai Marina',110,250,15],['Al Barsha',230,330,14],['Al Quoz',360,250,14],['Downtown Dubai',470,185,17],['Business Bay',455,330,20],['Jumeirah',250,150,15],['Dubai Hills',300,470,15],['Al Jaddaf',560,420,13],['Deira',560,90,14]].forEach")
rx('discover map prices', r"\[\['MYR 2\.7M'.*?\]\]\.forEach",
   "[['AED 29.9M',455,300],['AED 2.1M',520,248],['AED 3.4M',380,210],['AED 1.8M',250,300],['AED 4.6M',140,215],['AED 1.2M',300,420],['AED 2.6M',560,380],['AED 950K',210,510],['AED 1.5M',420,520],['AED 6.2M',520,150]].forEach")

# ---------------------------------------------------------------- 3. Evidence laptop screen
rx('EV_BARS', r'const EV_BARS=\[.*?\];',
   'const EV_BARS=[["The Ritz-Carlton Res.",5312,\'sub\'],["Damac Maison",1000],["Fairview Res.",1150],["Tower B",1200],["Marquise Square",1700],["Ayaan City",1800],["Regalia",1850],["Century Tower",1900],["One by Binghatti",1950],["Vera Residences",2000],["Peninsula",2100],["Urban Oasis",2250],["Al Habtoor",2300],["DWTN Residences",2500],["Canal Heights",2650],["One River Point",3100],["Vela Viento",6700]];')
lit('banner name', '<div><i>&#10016;</i>BINASTRA<br>COCHRANE</div>', '<div><i>&#10016;</i>THE RITZ-CARLTON<br>RESIDENCES</div>')
lit('banner count', '<div class="count">5 / 11</div>', '<div class="count">1 / 13</div>')
lit('banner meta', '<span class="pill">Preleased</span><small>Serviced Apartment</small><h3>Binastra Cochrane</h3><div class="loc">Kuala Lumpur, Cochrane by Binastra Group</div>',
    '<span class="pill">Under construction</span><small>Branded residence &middot; 2027 handover</small><h3>The Ritz-Carlton Residences at Business Bay</h3><div class="loc">Business Bay, Dubai &middot; by Kappa Acca</div>')
lit('banner price', '<div class="price">RM 655,000 to RM 1,250,000</div>', '<div class="price">From AED 29,900,000</div>')
rx('unit chips', r'<div class="ev-units">Current unit.*?</div>\s*</div>',
   '<div class="ev-units">Current unit\n            <div class="ev-chip">1 Bed<small>Not disclosed</small></div>\n            <div class="ev-chip">2 Bed<small>Not disclosed</small></div>\n            <div class="ev-chip">3 Bed<small>Not disclosed</small></div>\n            <div class="ev-chip on">4 Bed<small>AED 29,900,000</small></div>\n            <div class="ev-chip">6 Bed<small>AED 60,000,000</small></div>\n          </div>')
lit('DMA unit label', '<span style="font-weight:400;color:#7b86a0;font-size:13px">Type A</span>', '<span style="font-weight:400;color:#7b86a0;font-size:13px">4 Bed</span>')
rx('KPIs', r'<div class="ev-kpis">.*?</div>\s*<div class="ev-row">',
   '<div class="ev-kpis">\n              <div class="ev-kpi ev-fade"><div class="l">YOUR PRICE (NEW)</div><div class="v" data-count="29900000" data-pre="AED ">AED 29,900,000</div><div class="s">4 bed, AED 5,312 psf</div></div>\n'
   '              <div class="ev-kpi pred ev-fade"><div class="l">PREDICTED MARKET VALUE</div><div class="v" data-count="12616000" data-pre="AED ">AED 12,616,000</div><div class="s">AED 2,241 psf, Business Bay market level</div></div>\n'
   '              <div class="ev-kpi fair ev-fade"><div class="l">FAIR PRICE CHECK</div><div class="v">Brand premium</div><div class="s">137% above predicted value</div></div>\n            </div>\n            <div class="ev-row">')
lit('comparables count', 'from the nearest 13 projects', 'from 16 Business Bay projects')
rx('evidence map labels', r'\[\["Kuala Lumpur",150,120,15\].*?\]\],', '[["Business Bay",170,215,15],["Downtown",120,95,12],["Al Wasl",330,90,12],["Dubai Canal",300,280,11]],')
lit('chart y max', 'YB=262,YT=16,YM=3100', 'YB=262,YT=16,YM=7200')
lit('chart y ticks', '[0,500,1000,1500,2000,2500,3000].forEach', '[0,1000,2000,3000,4000,5000,6000,7000].forEach')
lit('chart currency', '>RM ${t.toLocaleString', '>AED ${t.toLocaleString')
lit('bar colours', 'v>2000?C.r:v>1500?C.o:v>1200?C.y:C.g', 'v>5000?C.r:v>3000?C.o:v>2200?C.y:C.g')
lit('predicted line', 'Y(1002)', 'Y(2241)')
lit('predicted label', "'Predicted RM 1,002'", "'Predicted AED 2,241'")
lit('phone chart max', 'PYM=3100', 'PYM=7200')
lit('phone chart ticks', '[0,1000,2000,3000].forEach(v=>ps+=', '[0,2000,4000,6000].forEach(v=>ps+=')
lit('stats asking', '<div>Median asking PSF<b data-count="1082" data-pre="RM ">RM 1,082</b></div>', '<div>Median asking PSF<b data-count="1975" data-pre="AED ">AED 1,975</b></div>')
lit('stats transacted', '<div>Median transacted PSF<b data-count="1057" data-pre="RM ">RM 1,057</b></div>', '<div>Community PSF, 5 years<b data-count="46" data-pre="+" data-post="%">+46%</b></div>')
lit('stats predicted', '<div class="pr">Predicted PSF<b data-count="1002" data-pre="RM ">RM 1,002</b></div>', '<div class="pr">Predicted PSF<b data-count="2241" data-pre="AED ">AED 2,241</b></div>')

# ---------------------------------------------------------------- 4. Evidence phone
lit('phone project', '<div><b>Binastra Cochrane</b><small>Type A, 2 bed, 649 sqft</small></div><div class="pr">RM 649,620</div>',
    '<div><b>Ritz-Carlton Residences</b><small>4 bed, Business Bay</small></div><div class="pr">AED 29.9M</div>')
lit('phone price', '<b data-count="649620" data-pre="RM ">RM 649,620</b></div><div class="ps">649 sqft, RM 1,001 psf</div>',
    '<b data-count="29900000" data-pre="AED ">AED 29,900,000</b></div><div class="ps">4 bed, AED 5,312 psf</div>')
lit('phone predicted value', '<b data-count="650298" data-pre="RM ">RM 650,298</b>', '<b data-count="12616000" data-pre="AED ">AED 12,616,000</b>')
lit('phone fair', '<div class="pc fair"><div class="pl">Fair price check</div><div class="pv"><b>Fairly priced</b></div><div class="ps">0.1% below predicted value</div></div>',
    '<div class="pc fair"><div class="pl">Fair price check</div><div class="pv"><b>Brand premium</b></div><div class="ps">137% above predicted value</div></div>')
lit('phone stats', '<span>Asking<b data-count="1082" data-pre="RM ">RM 1,082</b></span><span>Transacted<b data-count="1057" data-pre="RM ">RM 1,057</b></span><span class="p">Predicted<b data-count="1002" data-pre="RM ">RM 1,002</b></span>',
    '<span>Asking<b data-count="1975" data-pre="AED ">AED 1,975</b></span><span>5 yrs<b data-count="46" data-pre="+" data-post="%">+46%</b></span><span class="p">Predicted<b data-count="2241" data-pre="AED ">AED 2,241</b></span>')
lit('phone rent', '<b data-count="2450" data-pre="RM ">RM 2,450</b><span>/ month</span>', '<b data-count="17417" data-pre="AED ">AED 17,417</b><span>/ month</span>')
lit('phone rent range', '<span>RM 1,700</span><span>median of 10 nearby units</span><span>RM 3,900</span>', '<span>AED 12,000</span><span>PropertyLab rent estimate</span><span>AED 25,000</span>')
lit('rent marker', '(2450-1700)/(3900-1700)', '(17417-12000)/(25000-12000)')
lit('phone instalment', '<div class="pl">Instalment</div><div class="pv"><b data-count="2589" data-pre="RM ">RM 2,589</b><span>/ month</span></div>\n          <div class="ps">90% loan, 4.0% interest, 35 years</div>',
    '<div class="pl">Mortgage</div><div class="pv"><b data-count="0" data-pre="AED ">AED 0</b><span>/ month</span></div>\n          <div class="ps">Cash purchase, all-in AED 31.10M</div>')
rx('phone cashflow', r'<div class="wf"><span>Rental</span>.*?<div class="net"><span>Net cashflow</span><b data-count="366"[^<]*</b>',
   '<div class="wf"><span>Rental</span><i><b class="wb in" data-w="1"></b></i><em>+17,417</em></div>\n          <div class="wf"><span>Mortgage</span><i><b class="wb out" data-w="0"></b></i><em>0</em></div>\n          <div class="wf"><span>Service charge</span><i><b class="wb mt" data-w=".12"></b></i><em>varies</em></div>\n          <div class="net"><span>Before service charge</span><b data-count="17417" data-pre="+AED " data-post=" / mo">+AED 17,417 / mo</b>')
lit('roi ring text', 'id="roiTxt">8.1%</text>', 'id="roiTxt">0.7%</text>')
lit('roi ring label', '>ROI p.a.</text>', '>net yield</text>')
lit('roi ring anim', "251.3*(1-.81*ra));$('roiTxt').textContent=(8.1*ra)", "251.3*(1-.07*ra));$('roiTxt').textContent=(0.7*ra)")
lit('roi stats', '<div>Projected ROI<b data-count="8.1" data-dec="1" data-post="%">8.1%</b></div><div>Gross yield<b data-count="4.5" data-dec="1" data-post="%">4.5%</b></div><div>Break-even rent<b data-count="2816" data-pre="RM ">RM 2,816</b></div>',
    '<div>Net yield<b data-count="0.7" data-dec="1" data-post="%">0.7%</b></div><div>Payback<b data-count="143" data-post=" yr">143 yr</b></div><div>vs market<b data-count="137" data-pre="+" data-post="%">+137%</b></div>')

# ---------------------------------------------------------------- 5. AI + Plan
Q = 'Is the Ritz-Carlton 4-bed in Business Bay a good buy for me?'
lit('question', 'Is Binastra Cochrane Type A a good buy for me?', Q)
lit('conversation list', '<div class="ai-conv on">Binastra Cochrane, Type A</div><div class="ai-conv">Rental yield vs cashflow</div><div class="ai-conv">Dual-key studios in KL</div><div class="ai-conv">Dubai vs Kuala Lumpur</div>',
    '<div class="ai-conv on">Ritz-Carlton Business Bay, 4 Bed</div><div class="ai-conv">Yield vs capital growth</div><div class="ai-conv">Branded residences in Dubai</div><div class="ai-conv">Dubai vs Kuala Lumpur</div>')
lit('chat header', '<div class="ai-ch">Binastra Cochrane, Type A<div class="ai-ctx"><span>Market value</span><span>Cashflow</span><span>13 comparables</span></div></div>',
    '<div class="ai-ch">Ritz-Carlton Business Bay, 4 Bed<div class="ai-ctx"><span>Market value</span><span>Rental yield</span><span>16 comparables</span></div></div>')
lit('answer 1', 'data-t="Short answer: the price is fair, but as a whole-unit rental it costs you about RM 366 a month to hold."',
    'data-t="Short answer: it is a trophy home, not a yield play. You pay 137% above the Business Bay market, and rent returns only 0.7% a year."')
lit('chips desktop', '<div class="ai-chip ok">Fair price<b>0.1% below market</b></div><div class="ai-chip neg">Cashflow<b>&minus;RM 366 / mo</b></div><div class="ai-chip roi">Projected ROI<b>8.1% p.a.</b></div>',
    '<div class="ai-chip ok">Area growth<b>+46% in 5 yrs</b></div><div class="ai-chip neg">Brand premium<b>+137% vs market</b></div><div class="ai-chip roi">Net yield<b>0.7% p.a.</b></div>')
lit('answer 2', 'data-t="Two ways to make the numbers work for you:"', 'data-t="Two ways to look at it:"')
lit('answer 3', 'data-t="1. Rent by room. At about RM 2,900 a month in total, cashflow turns positive at +RM 84."',
    'data-t="1. Buy it to live in, or to hold as a branded trophy. Business Bay prices are up 46% in five years."')
lit('answer 4', 'data-t="2. Hold for the long run. At 3.5% yearly growth, your equity reaches about RM 2.17 million in 35 years."',
    'data-t="2. If you want rental income, I can shortlist Business Bay units priced near the AED 2,241 psf market level instead."')
lit('answer 5', 'data-t="Want me to turn this into a full purchase plan with your income and budget?"', 'data-t="Want me to turn this into a full purchase plan with your budget?"')
lit('actions', '<span>Compare with Type B</span>', '<span>Compare Business Bay units</span>')
lit('phone answer 1', 'data-t="The price is fair, but as a whole-unit rental it costs about RM 366 a month to hold."',
    'data-t="A trophy home, not a yield play: 137% above market, 0.7% net yield."')
lit('phone chips', '<div class="ai-chip ok">Fair price<b>0.1% below</b></div><div class="ai-chip neg">Cashflow<b>&minus;RM 366</b></div><div class="ai-chip roi">ROI<b>8.1%</b></div>',
    '<div class="ai-chip ok">Area<b>+46%</b></div><div class="ai-chip neg">Premium<b>+137%</b></div><div class="ai-chip roi">Yield<b>0.7%</b></div>')
lit('phone answer 2', 'data-t="Rent by room at about RM 2,900 and cashflow turns positive. Hold 35 years and your equity grows to about RM 2.17 million."',
    'data-t="Buy it to live in or hold as a trophy. For income, compare Business Bay units near market price."')
lit('phone plan bar', '&#8592;</span>Binastra Cochrane<span', '&#8592;</span>Ritz-Carlton Residences<span')
lit('phone equity value', '<div class="eqv"><small>RM</small><span id="eqVal">2,165,567</span></div><div class="eqs">Final equity after 35 years</div>',
    '<div class="eqv"><small>AED</small><span id="eqVal">42,273,140</span></div><div class="eqs">Value plus rent after 10 years</div>')
lit('phone legend', '<span><i class="d"></i>Loan balance</span>', '<span><i class="d"></i>No mortgage</span>')
lit('phone milestones', '<div class="mil"><div>Year 10<b>RM 425,914</b></div><div>Year 20<b>RM 942,632</b></div><div>Loan paid off<b>Year 35</b></div></div>',
    '<div class="mil"><div>Year 3<b>AED 33.3M</b></div><div>Year 5<b>AED 35.7M</b></div><div>Year 10<b>AED 42.3M</b></div></div>')
# Duo cover screen
lit('duo check', 'data-t="Here is my price check on Type A."', 'data-t="Here is my price check on the 4-bed."')
lit('duo verdict', '<span class="pill">&#10003; Fairly priced</span><small>0.1% below market value</small>', '<span class="pill">Brand premium</span><small>137% above market value</small>')
lit('duo gauge', '<span><i class="dm"></i>Market RM 650,298</span><span><i class="dy"></i>You RM 649,620</span>', '<span><i class="dm"></i>Market AED 12.6M</span><span><i class="dy"></i>You AED 29.9M</span>')
lit('duo gauge marks', "cov.querySelector('.mm').style.left=(51.5*g)+'%'; cov.querySelector('.my').style.left=(48.1*g)+'%';",
    "cov.querySelector('.mm').style.left=(30*g)+'%'; cov.querySelector('.my').style.left=(88*g)+'%';")
lit('duo tiles', '<div class="tile neg"><small>Whole unit</small><b>&minus;RM 366</b><small>/ month</small></div><div class="tile pos"><small>Rent by room</small><b>+RM 84</b><small>/ month</small></div>',
    '<div class="tile neg"><small>Net yield</small><b>0.7%</b><small>/ year</small></div><div class="tile pos"><small>Area growth</small><b>+46%</b><small>/ 5 years</small></div>')
# Duo inner plan (desktop + mobile) and full plan
lit('plan header', '<span>Binastra Cochrane, Type A</span>', '<span>Ritz-Carlton Residences, 4 Bed</span>')
lit('plan big', '<small>RM</small><span class="eqv">2,165,567</span>', '<small>AED</small><span class="eqv">42,273,140</span>')
lit('plan eq label', '<div class="lbl">Net equity growth forecast</div>', '<div class="lbl">Value plus rent, 10-year forecast</div>')
lit('plan sub', '<div class="sub">after 35 years at 3.5% yearly growth</div>', '<div class="sub">cash purchase, 3% a year, rent AED 17,417 / mo</div>')
rx('plan table', r'<div class="card amort"><div class="lbl">Amortization schedule.*?</tbody></table></div>',
   '<div class="card amort"><div class="lbl">10-year projection <span class="lt">Cash purchase, AED 31.10M all-in</span></div>\n      <table><thead><tr><th>Year</th><th>Value</th><th>Rent collected</th><th>Total</th></tr></thead><tbody>'
   '<tr><td>Year 1</td><td>30,797,000</td><td>209,004</td><td class="e">31,006,004</td></tr>'
   '<tr><td>Year 3</td><td>32,672,537</td><td>627,012</td><td class="e">33,299,549</td></tr>'
   '<tr><td>Year 5</td><td>34,662,295</td><td>1,045,020</td><td class="e">35,707,315</td></tr>'
   '<tr><td>Year 7</td><td>36,773,229</td><td>1,463,028</td><td class="e">38,236,257</td></tr>'
   '<tr><td>Year 10</td><td>40,183,100</td><td>2,090,040</td><td class="e">42,273,140</td></tr></tbody></table></div>')
lit('plan cashflow line', '<span>Rent by room: RM 2,900 rent, RM 2,589 instalment, RM 227 maintenance</span><b class="netv">+RM 84 / mo</b>',
    '<span>Long-term let: AED 17,417 rent, no mortgage, before service charge</span><b class="netv">+AED 17,417 / mo</b>')
lit('plan summary pills', '<div class="ca sum"><span class="pill ok">&#10003; Fairly priced</span><span class="pill neg">&minus;RM 366 / mo as a whole unit</span></div>',
    '<div class="ca sum"><span class="pill ok">Area +46% in 5 yrs</span><span class="pill neg">0.7% net yield</span></div>')
lit('plan intro', 'data-t="Here is your plan. Renting by room is the better setup for this unit."', 'data-t="Here is your plan. Treat it as a home and a long-term store of value, not an income asset."')
rx('plan compare', r'<div class="rc cmp">.*?</div></div>\s*<div class="rc eqm">',
   '<div class="rc cmp"><div class="opt"><span>Long-term let</span><b class="neg">0.7%</b><small>net yield, rent AED 17,417 / mo</small><i><em data-w=".25" style="background:#e5484d"></em></i></div>\n'
   '          <div class="opt best"><span>Hold 10 years <u>Plan</u></span><b class="pos">AED 42.3M</b><small>value plus rent at 3% a year</small><i><em data-w="1" style="background:#3cc27a"></em></i></div></div>\n        <div class="rc eqm">')
lit('plan equity', '<small>Equity in 35 years</small><b>RM 2.17M</b><span class="x">&#8599; 3.3x your purchase price</span>',
    '<small>Value plus rent in 10 years</small><b>AED 42.3M</b><span class="x">&#8599; 1.36x your all-in cost</span>')
lit('plan slot', '<small>Book a viewing of the Type A show unit</small>', '<small>Book a viewing of the 4-bed show suite</small>')
lit('plan source', 'Based on 13 comparables, 10 nearby rentals and your budget', 'Based on 16 Business Bay comparables, the portal rent estimate and your budget')
lit('plan mobile label', '<div class="lbl">Equity in 35 years</div>', '<div class="lbl">Value plus rent in 10 years</div>')
rx('plan mobile table', r'<table><thead><tr><th>Year</th><th>Loan</th><th>Equity</th></tr></thead><tbody>.*?</tbody></table>',
   '<table><thead><tr><th>Year</th><th>Value</th><th>Total</th></tr></thead><tbody><tr><td>Yr 1</td><td>30,797,000</td><td class="e">31,006,004</td></tr><tr><td>Yr 3</td><td>32,672,537</td><td class="e">33,299,549</td></tr><tr><td>Yr 5</td><td>34,662,295</td><td class="e">35,707,315</td></tr><tr><td>Yr 10</td><td>40,183,100</td><td class="e">42,273,140</td></tr></tbody></table>')
lit('plan mobile text', 'data-t="Rent by room and you keep about RM 84 a month. Your equity grows to about RM 2.17 million in 35 years. Book a viewing?"',
    'data-t="Hold it as a home and a store of value: about AED 42.3M in value plus rent after 10 years. Book a viewing?"')
# equity chart engine (10 years, AED, no loan)
rx('EQ data', r'const EQ=\[\[0, 64962, 584658\].*?\]\];',
   'const EQ=[[0,29900000,0],[1,31006004,0],[2,32138918,0],[3,33299549,0],[4,34488729,0],[5,35707315,0],[6,36956188,0],[7,38236257,0],[8,39548457,0],[9,40893754,0],[10,42273140,0]];')
lit('EQ scale', 'YM=3000000,X=t=>X0+(X1-X0)*t/35', 'YM=45000000,X=t=>X0+(X1-X0)*t/10')
lit('EQ ticks', "[0,1e6,2e6,3e6].forEach(v=>s+=", "[0,15e6,30e6,45e6].forEach(v=>s+=")
lit('EQ tick label', "${v?'RM '+v/1e6+'M':'RM 0'}", "${v?'AED '+v/1e6+'M':'AED 0'}")
lit('EQ year labels', '[1,10,20,35].forEach(t=>s+=', '[1,4,7,10].forEach(t=>s+=')
lit('EQ end x', '${X(35)}', '${X(10)}')
lit('EQ tip', 'Y(EQ[35][1])', 'Y(EQ[10][1])')
lit('EQ counter', 'Math.round(2165567*e)', 'Math.round(42273140*e)')
lit('netv counter', '`+RM ${Math.round(84*ease(k2(.45,.62)))} / mo`', "`+AED ${Math.round(17417*ease(k2(.45,.62))).toLocaleString('en-US')} / mo`")
# full plan card
lit('full plan title', '<h3>Your plan for Binastra Cochrane, Type A</h3><p>Prepared by PropertyLab AI from 13 comparables, nearby rents and your budget.</p>',
    '<h3>Your plan for The Ritz-Carlton Residences, 4 Bed</h3><p>Prepared by PropertyLab AI from 16 Business Bay comparables, the portal rent estimate and your budget.</p>')
lit('full plan sub', 'Projected equity after 35 years at 3.5% yearly growth', 'Value plus rent after 10 years, cash purchase, 3% a year')
rx('full plan cashflow', r'<div class="lbl">Monthly cashflow, rented by room</div>.*?<div class="net"><span>Net cashflow</span><b class="netv">\+RM 84 / mo</b></div>',
   '<div class="lbl">Monthly cashflow, long-term let</div>\n        <div class="wf"><span>Rent</span><i><b data-w="1" style="background:#3cc27a"></b></i><em>+17,417</em></div>\n        <div class="wf"><span>Mortgage</span><i><b data-w="0" style="background:#2f6bff"></b></i><em>0</em></div>\n        <div class="wf"><span>Service charge</span><i><b data-w=".12" style="background:#9aa6bf"></b></i><em>varies</em></div>\n        <div class="net"><span>Before service charge</span><b class="netv">+AED 17,417 / mo</b></div>')
lit('full plan step 1', 'Book a viewing<small>Binastra Cochrane show unit, Kuala Lumpur</small>', 'Book a viewing<small>The Ritz-Carlton show suite, Business Bay</small>')
lit('full plan step 2', 'Get mortgage pre-approval<small>90% loan at about 4.0%, 35 years</small>', 'Confirm the payment plan<small>Developer schedule to the 2027 handover</small>')
lit('full plan step 3', '<small>Room-rental setup and tenancy plan</small>', '<small>Hold strategy and long-term let setup</small>')

# ---------------------------------------------------------------- 6. Connect + Beyond copy and film captions
lit('connect step 3', 'Offer, booking fee, loan approval, SPA and handover, followed step by step in your PropertyLab app.',
    'Offer, reservation, SPA, DLD transfer and handover, followed step by step in your PropertyLab app.')
lit('film captions', "const CAPS=['Booking your viewing with a verified partner agent','Meet your licensed partner agent, on the ground in Kuala Lumpur','Viewing confirmed: Saturday 14:00, Binastra Cochrane','Offer, loan, SPA and keys, tracked to the end'];",
    "const CAPS=['Booking your viewing with a verified partner agent','Meet your licensed partner agent, on the ground in Dubai','Viewing confirmed: Saturday 14:00, The Ritz-Carlton Residences','Offer, SPA, DLD transfer and keys, tracked to the end'];")
lit('beyond step 3', 'Rent collection, tenant requests and maintenance in your PropertyLab app, even from Hong Kong.',
    'Rent collection, tenant requests and maintenance in your PropertyLab app, even from Taipei.')
lit('evidence beat 3', "'Then, the cashflow.'", "'Then, the yield.'")
lit('beyond film comment', '(film, two parts: KL then Hong Kong)', '(film, two parts: Dubai then Taipei)')

# ---------------------------------------------------------------- 7. App section phone + footer
rx('app phone shot', r'(<img class="ph4-shot" src=")[^"]*(" alt=")[^"]*(")', r'\g<1>' + A + r'ae-phone-shot.jpg\g<2>PropertyLab app, Analyze: The Ritz-Carlton Residences at Business Bay, Dubai\g<3>')
lit('app chip 1', '<div class="ph3-chip c1"><i class="dot g"></i>Fairly priced<small>0.1% below market</small></div>', '<div class="ph3-chip c1"><i class="dot g"></i>Area growth<small>+46% in 5 years</small></div>')
lit('app chip 2', '<div class="ph3-chip c2"><b>8.1%</b><small>Projected ROI</small></div>', '<div class="ph3-chip c2"><b>AED 17,417</b><small>Rent / month</small></div>')
lit('fallback map unit', 'Your unit · KL', 'Your unit · Dubai')
lit('fallback map labels', "[['Kuala Lumpur',200,196,12],['Cheras',230,150,9],['Ampang',240,60,9]]", "[['Business Bay',200,196,12],['Downtown',230,150,9],['Al Wasl',240,60,9]]")
lit('footer note', 'Viewings and transactions are handled by licensed partners. Kuala Lumpur · Hong Kong.', 'Viewings and transactions are handled by licensed partners. Dubai · Kuala Lumpur · Hong Kong.')

lit('phone predicted psf', 'RM 1,002 psf from 16 Business Bay projects', 'AED 2,241 psf, Business Bay market level')
lit('cursor comment', 'cursor clicks Binastra Cochrane', 'cursor clicks The Ritz-Carlton Residences')

rx('discover link', r'<a class="textlink" href="[^"]*">Open Analyze Property</a>', '<a class="textlink" href="/analyze-property/new-projects?country=ae">Open Analyze Property</a>')
rx('plan cta link', r'<a class="cta" href="[^"]*">Open in PropertyLab</a>', '<a class="cta" href="/ae/projects/kappa-acca-the-ritz-carlton-residences-at-business-bay?chrome=portal&amp;tab=invest#units">Open in PropertyLab</a>')

# ---------------------------------------------------------------- 8. style overrides (photo banner, amber premium)
STYLE = ('<style id="ae-overrides">\n'
 f'.ev-banner{{background:#1b1d24 url({A}ae-ritz-banner.jpg) center 35%/cover}}\n'
 '.ev-banner .p1,.ev-banner .p2,.ev-banner .p3,.ev-banner .p4{visibility:hidden}\n'
 f'.ev-thumbs{{background:url({A}ae-thumbs.jpg) left center/auto 100% no-repeat}}\n'
 f'.a-ph{{background-image:url({A}ae-card-ritz.jpg)}}\n'
 '.pc.fair .pv b{color:#a8650b}\n'
 '.cov .verd .pill{background:#fff1dd;color:#a8650b}\n'
 '</style>\n')
lit('style block', '</head>', STYLE + '</head>', n=1)

open(DST, 'w', encoding='utf-8').write(t)
print('\n'.join(log))
miss = sum(l.startswith('MISS') for l in log)
print(f'\n{len(log)-miss} OK, {miss} MISS  ->  {DST}')
sys.exit(1 if miss else 0)
