
    H5h                     T   d Z ddlZddlZddlZddlZddlmZmZ ddl	m	Z	 	 ddl
mZ 	 ddlmZmZ dZ	 ddlmZ dZ G d d      Zd Zd Zd Zd ZddZddZddZy# e$ r	 ddl
mZ Y Dw xY w# e$ r d	Z ed
        ed       Y Vw xY w# e$ r d	Z ed        ed       Y jw xY w)zp
Tailwind Site Rebuilder
-----------------------
Creates a blueprint for rebuilding websites with Tailwind CSS.
    N)urlparseurljoindatetime   )OpenAILayoutAnalyzer)Image	ImageDrawTFzPWarning: PIL/Pillow not installed. Some image analysis features will be limited.z Install with: pip install Pillow)BeautifulSoupzIWarning: BeautifulSoup not installed. Content extraction will be limited.z(Install with: pip install beautifulsoup4c                   ,    e Zd ZdZddZddZd Zd Zy)	SiteRebuilderz%Builds a Tailwind CSS rebuild contextc                    || _         t        j                  |d       t        j                  j	                  |d      | _        	 t               | _        t        d       y # t        $ r}t        d|        d | _        Y d }~y d }~ww xY w)NTexist_okrebuild_context.jsonu&   ✅ OpenAI Vision Analyzer initializedu5   ⚠️  OpenAI Vision Analyzer failed to initialize: )

output_dirosmakedirspathjoincontext_filer   openai_analyzerprint	Exception)selfr   es      A/home/stella.sw7ft.com/public_html/site_rebuilder/lib/analyzer.py__init__zSiteRebuilder.__init__+   su    $
J. GGLL5KL	(#7#9D :; 	(I!MN#'D  	(s   A   	B)BBNc                    t        d       t        |d         j                  }|j                  d      r|dd }| j	                  |d   |d   |d   |d	   
      }	|d   ||d   t        j                         j                         |d   d|d   |d   |d   |d	   |	d   |	d   g 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)}
|rh||
d*<   |j                  d+      rR|d+   }|j                  d,d-      |j                  d.d/      |j                  d0d-      |j                  d1d2      d3|
d4   d5<   |r|
j                  d6i       |
d6<   ||
d6   d7<   |r|
j                  d6i       |
d6<   ||
d6   d<   |r$d8|v rt        |d8         D ]  \  }}|j                         j                  d9      d2   j                         || j                  |j                         j                  d9      d2   j                               d:}|t        |j                  d;g             k  r`|d;   |   }|j                  |j                  d<i       |j                  d=i       |j                  d6i       j                  d>d?      dd@ dA       |
dB   dC   j!                  |        nt#        dD |D        d      }t#        dE |D        d      }i }|rdF|v r|dF   |dG<   dH|v r|dH   |dH<   |rdF|v r|dF   |dI<   dJ|v r|dJ   |dK<   |rC||
d4   d5<   dG|v r7|dG   }|dLk(  rdM|
dN   dO   dP<   n!|dQk(  rdR|
dN   dO   dP<   n|dSk(  rdT|
dN   dO   dP<   |D ]O  }|dU   |d   | j                  |dU         dV}dF|v r|dF   |dF<   d.|v r|d.   |d.<   |
dB   dC   j!                  |       Q t%        | j&                  dWdXY      5 }t)        j*                  |
|dZ[       ddd       t        d\| j&                          |
S # 1 sw Y   #xY w)]z<Create rebuild context JSON from screenshot and section dataz Creating rebuild context JSON...urlwww.   Nwidthheightviewport_widthviewport_height)r#   r$   r%   r&   titlefilename)r'   domainr    analyzed_at
screenshot)original_widthoriginal_heightoriginal_viewport_widthoriginal_viewport_heightnormalized_widthnormalized_heightsections
background   textaccentr3   r5   r6   fontsheadingsbodyr8   r9   r:   )colors
typographyzTThis site should be rebuilt using Tailwind CSS utility classes for responsive designz%Use Tailwind's container (max-width: zpx), flex, and grid utilitiesz9Create a responsive header with Tailwind's flex utilitiesz;Build navigation with Tailwind's flex and spacing utilitieszGUse Tailwind's padding, margin, and text utilities for the hero sectionzBUtilize Tailwind's grid and spacing utilities for content sectionsz6Create a responsive footer with Tailwind's grid system)header
navigationheror2   footer640px768px1024px1280px1440pxsmmdlgxl2xl)generallayout
componentsresponsive_breakpoints)	site_inforN   designtailwind_rebuild_notesasrlayout_analysislayout_typeunknownhas_overlay_headerFnavigation_styletotal_sectionsr   )rV   rX   rY   rZ   rQ   layout_patternscontentimagestemplate_structure()typedescriptiontailwind_notesdetailed_sectionspositioningstylingtext_content d   )rd   re   content_previewrN   r2   c              3   2   K   | ]  }|d    dk(  s|  yw)r`   r>   N .0ss     r   	<genexpr>z7SiteRebuilder.create_rebuild_context.<locals>.<genexpr>   s     "P!F)x:O1"P   c              3   2   K   | ]  }|d    dk(  s|  yw)r`   r?   Nrk   rl   s     r   ro   z7SiteRebuilder.create_rebuild_context.<locals>.<genexpr>   s     QaqyL7PQrp   patternheader_patternlogo_positionnav_patternposition_in_headernav_positionlogo-left-nav-rightz^Create header with flex: logo on left (flex-shrink-0) and nav on right (flex-grow justify-end)rS   rO   r>   zcentered-logozBCreate header with logo centered (mx-auto) and flex justify-centerzoverlay-herozECreate transparent header with absolute positioning over hero sectionr`   )r`   ri   rb   wutf-8encoding   indentzRebuild context saved to )r   r   netloc
startswith_normalize_dimensionsr   now	isoformatget	enumeratelowersplitstripget_tailwind_notes_for_sectionlenupdateappendnextopenr   jsondump)r   screenshot_datar2   r<   r=   r]   rf   rT   r)   normalized_dimensionsrebuild_contextrU   isection_descsection_datadetailedheader_sectionnav_sectionr[   rr   sectionfs                         r   create_rebuild_contextz$SiteRebuilder.create_rebuild_context:   s   01 /%0188V$ABZF !% : :!'*"8,*+;<+,=>	 !; !
 )1 &u-'||~779-j9 #2'":#28#<+:;K+L,;<M,N$9'$B%:8%D #)"6r":"6N2A.$X.r2 (0 *: 6&v. rABWX_B`Aaa~Y"_e dV "!""#+';/
d %(OE" ww()"%&7"8#2#6#6}i#P*9*=*=>RTY*Z(7(;(;<NPY(Z&5&9&9:JA&N	C,->? )8)<)<Y)KOI&39OI&x0 )8)<)<Y)KOI&1=OI&v. '3.#,S1E-F#G K<(..066s;A>DDF#/&*&I&I,J\J\J^JdJdehJijkJlJrJrJt&u  s377#6;<<"#67:H '''/||M2'F#+<<	2#>+3<<	2+F+J+J>[]+^_c`c+d)   )*5<<\J!K( ""Ph"PRVWNQ8QSWXK !O)~"=4B94M 01"n47Eo7VOO4yK71<Y1G.';66ABV6WON3 BQ,->? $6-.>?G"77 ]}(@A,OPXY O3 ]a(@A,OPXY N2 ]d(@A,OPXY $ K#FO'.v&*&I&I'RX/&Z  '.5i.@L+ (729@AU9VL!56)*5<<\JK$ $##S7; 	4qIIoq3	4 	)$*;*;)<=>		4 	4s   P  P	c                     dddddd}|d   }|dkD  r||z  nd	}t        ||z        }t        d
| d| d| d| d	       ||ddS )z,Normalize dimensions to standard breakpointsi  i   i   i     rG   rL   r   r   zNormalized dimensions: u   px × zpx (original: zpx))r#   r$   
breakpoint)intr   )	r   r#   r$   r%   r&   breakpointsr0   aspect_ratior1   s	            r   r   z#SiteRebuilder._normalize_dimensions   s     
 'u- */v~ 0< ?@'(8'9@Q?RR`af`ggmntmuuxyz &'
 	
    c                 @    ddddddddd	d
d
}|j                  |d      S )z.Get Tailwind-specific notes for a section typez=Use sticky positioning, flex layout, and responsive utilitiesz>Implement responsive navigation with flex and hidden utilitiesz;Create with flex or grid, large text utilities, and paddingz7Structure with flex or grid depending on content layoutz8Use container, padding, and margin utilities for spacingz2Implement with grid or flex for responsive layoutsz7Create cards with rounded corners, shadows, and paddingz3Use grid for pricing tables with consistent spacingz4Implement form elements with Tailwind form utilitiesz0Structure with grid for responsive column layout)
r>   r?   r@   mainr   featurestestimonialspricingcontactrA   z,Use appropriate flex/grid layout and spacingr   )r   section_typenotess      r   r   z,SiteRebuilder.get_tailwind_notes_for_section   s>     VZQMQLULMH
 yy'UVVr   site_rebuilder)NNN)__name__
__module____qualname____doc__r   r   r   r   rk   r   r   r   r   (   s    /(gR
4Wr   r   c                 :)   g }i }t         j                  j                  |d      }t         j                  j                  |d      }t         j                  j                  |d      }t        j                  |d       t        j                  |d       t        j                  |d       t        st        d       ||fS 	 t        |d      }| }	t        |j                  d            D ].  \  }
}	 |j                  d	d
      }|r|j                  d      st        |	|      }|j                  dd      }|j                  dd      }d|
 dt         j                  j                  |       }t        j                  dd|      }|j                  d      s|dz  }t         j                  j                  ||      }t         j                  j                  dd|      }d}	 t         j"                  j%                  |ddi      }t         j"                  j'                  |d      5 }t)        |d      5 }|j+                  |j-                                d}t        d|        ddd       ddd       ||j                  dd
      |dk7  r|dk7  r| d | nd|j0                  r|j0                  j2                  nd|r|ndd!d"}|j0                  r=|j0                  j2                  d#k(  r$d|d$<   |j0                  j                  d%d
      |d&<   |j5                  |       1 d(}t        j6                  d)      }|j                  d*       D ]  }	 |j                  d+d
      }|j9                  |      }|r|j;                  d,      }|j                  d      st        |	|      }d-| dt         j                  j                  |       }t        j                  dd|      }|j                  d      s|dz  }t         j                  j                  ||      }t         j                  j                  dd|      }d}	 t         j"                  j%                  |ddi      }t         j"                  j'                  |d      5 }t)        |d      5 }|j+                  |j-                                d}t        d.|        ddd       ddd       |j                  d0d
      }d1j                  |j                  d2g             }|j2                   }|r	|d3| d4z  }|r	|d5| d4z  }|||r|ndd6d7}|j5                  |       |d,z  } |j                  d+      D ]  } 	 | j<                  }!|!r|j?                  |!      }"t        |"      D ]m  \  }
}|s
|j                  d      st        |	|      }d9| dt         j                  j                  |       }t        j                  dd|      }|j                  d      s|dz  }t         j                  j                  ||      }t         j                  j                  dd|      }d}	 t         j"                  j%                  |ddi      }t         j"                  j'                  |d      5 }t)        |d      5 }|j+                  |j-                                d}t        d:|        ddd       ddd       ||r|ndd<d=}|j5                  |       |d,z  }p  |jA                  d?      }#|#rk|#jC                  d@      |d?<   t)        t         j                  j                  |dA      dBdCD      5 }$|$j+                  |#jC                  d@             ddd       |jA                  dE      }%|%rg }&|%j                  d#      D ]\  }'|'j                  d%d
      }(|'jC                  d@      })|)s*|&j5                  |)|(r|(j                  d      st        |	|(      n|(dF       ^ |&|dG<   t)        t         j                  j                  |dH      dBdCD      5 }$|&D ]  }*|$j+                  |*d    dI|*d%    dJ       ! 	 ddd       |jA                  dK      xs: |jA                  dKL      xs& |jA                  dL      xs |jA                  dM      }+|+rk|+jC                  d@      |dK<   t)        t         j                  j                  |dN      dBdCD      5 }$|$j+                  |+jC                  d@             ddd       i },t)        t         j                  j                  |dO      dBdCD      5 }$tE        d,dP      D ]  }-|j                  dQ|-       }.|.s|.D /cg c]  }/|/jC                  d@       c}/|,dQ|- <   |$j+                  dR|- dS       |.D ]&  }/|$j+                  |/jC                  d@       dJ       ( |$j+                  dJ        	 ddd       |,r|,|dT<   |j                  dU      }0|0r|0D 1cg c]'  }1|1jC                  d@      s|1jC                  d@      ) c}1|dV<   t)        t         j                  j                  |dW      dBdCD      5 }$|0D ]+  }1|1jC                  d@      })|)s|$j+                  |) dX       - 	 ddd       |jA                  dY      }2|2rk|2jC                  d@      |dY<   t)        t         j                  j                  |dZ      dBdCD      5 }$|$j+                  |2jC                  d@             ddd       |jA                  d[      }3|3rg }4|3j                  d\      D ]M  }*|*jG                         s|*j0                  j2                  }5|5d]vs/|4j5                  |*jG                                O d1j                  |4      }6|6|d^<   t)        t         j                  j                  |d_      dBdCD      5 }$|$j+                  |6       ddd       t)        t         j                  j                  |d`      dBdCD      5 }$|$j+                  da|  dJ       |$j+                  dbtI        jJ                         jM                  dc       dX       |$j+                  dd       |$j+                  detO        |       dJ       tQ        df |D              }7tQ        dg |D              }8tQ        dh |D              }9|$j+                  di|7 dJ       |$j+                  dj|8 dJ       |$j+                  dk|9 dX       |$j+                  dltO        |       dJ       |$j+                  dm       |jS                         D ]  }:|:d^k(  r	|$j+                  dn|: dJ        	 ddd       t)        t         j                  j                  |do      dBdCD      5 }$|$j+                  dp|  dq|  dr|  dstI        jJ                         jM                  dc       dttO        |       du7 dv8 dw9 dx       |D ;cg c]+  };|;j                  dy      d!k(  s|;j                  dz      s*|;- c};D ]s  }|j                  dzd
      }|j                  dd{      }<|j                  d	d
      }|$j+                  d|| d}|< d~|< dt         j                  j                  |       d	       u |$j+                  d       |D ;cg c]+  };|;j                  dy      d6k(  s|;j                  dz      s*|;- c};D ]p  }|j                  dzd
      }|j                  dd      }|j                  d	d
      }|$j+                  d|| d| dt         j                  j                  |       d       r |$j+                  d       dT|v r|$j+                  d       tE        d,dP      D ]O  }-dQ|- }:|:|dT   v s|dT   |:   s|$j+                  d|- d       |dT   |:   D ]  }=|$j+                  dn|= dJ        Q |$j+                  d       dV|v rx|$j+                  d       |dV   dd D ]  }1|$j+                  |1 dX        tO        |dV         dkD  r$|$j+                  dtO        |dV         dz
   d       |$j+                  d       dG|v rJ|$j+                  d       |dG   D ]   }*|$j+                  dn|*d    d|*d%    d       " |$j+                  d       |$j+                  d       ddd       t        dtO        |       dtO        |       d       t        d|        t         j                  j                  |d!      }>t         j                  j                  |d6      }?t        j                  |>d       t        j                  |?d       |D ]  }|j                  dz      s|j                  dyd!      }@t         j                  j                  |j                  dzd
            }A|AsZ	 t         j                  j                  |A      }B@d!k(  r!t         j                  j                  |>A      }Cn t         j                  j                  |?A      }Ct         j                  jU                  B      r5t         j                  jU                  C      sd(dl+}D|DjY                  BC        ||fS # 1 sw Y   4xY w# 1 sw Y   9xY w# t.        $ r}t        d| d|        Y d}~\d}~ww xY w# t.        $ r}t        d'|        Y d}~d}~ww xY w# 1 sw Y   ExY w# 1 sw Y   JxY w# t.        $ r}t        d/| d|        Y d}~md}~ww xY w# t.        $ r}t        d8|        Y d}~d}~ww xY w# 1 sw Y   xY w# 1 sw Y   xY w# t.        $ r}t        d;| d|        Y d}~d}~ww xY w# t.        $ r}t        d>|        Y d}~nd}~ww xY w# 1 sw Y   ^xY w# 1 sw Y   xY w# 1 sw Y   
xY wc c}/w # 1 sw Y   
xY wc c}1w # 1 sw Y   	qxY w# 1 sw Y   	 xY w# 1 sw Y   :xY w# 1 sw Y   xY wc c};w c c};w # 1 sw Y   yxY w# t.        $ r}t        dA d|        Y d}~d}~ww xY w# t.        $ r}t        d|        ||fcY d}~S d}~ww xY w)zAExtract images and text content from HTML and save to directoriesr\   r]   r5   Tr   z2BeautifulSoup not available, can't extract contenthtml.parserimgsrcrg   zhttp://https://r#   rW   r$   image__z	[^\w\-\.]).jpgz.jpegz.pngz.gifz.webpz.svgr   F
User-AgentsMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36headers
   timeoutwbzDownloaded image: NzFailed to download image z: altxregular)r   r   
dimensions
parent_tag
local_pathr`   ais_linkhref	link_hrefzError extracting image: r   z3background-image\s*:\s*url\([\'"]?([^\'"]+)[\'"]?\)c                 P    | j                  d      xr d| j                  dd      v S )Nstylezbackground-imagerg   )has_attrr   tags    r   <lambda>z)extract_images_and_text.<locals>.<lambda>a  s*    g1F1uK]adahahiprtauKu r   r   r   	bg_image_zDownloaded background image: z$Failed to download background image id classz (id: )z	 (class: r3   )r   elementr   r`   z#Error extracting background image: css_bg_z!Downloaded CSS background image: z(Failed to download CSS background image css_background)r   r   r`   z Error parsing CSS in style tag: r>   )r   z
header.txtry   rz   r{   nav)r5   r   r?   znavigation.txtz - 
r   )r   )class_zmain_content.txtzheadings.txt   hz--- Hz Headings ---
r9   p
paragraphszparagraphs.txtz

rA   z
footer.txtr:   )string)scriptr   metanoscript	full_textzfull_text.txtzcontent_summary.txtzContent extracted from: zDate: z%Y-%m-%d %H:%M:%Sz=== STATISTICS ===
zTotal images found: c              3   J   K   | ]  }|j                  d       dk(  sd  yw)r`   r   r   Nr   rm   r   s     r   ro   z*extract_images_and_text.<locals>.<genexpr>(  s      Us98T U   ##c              3   J   K   | ]  }|j                  d       dk(  sd  yw)r`   r3   r   Nr   r   s     r   ro   z*extract_images_and_text.<locals>.<genexpr>)  s     #[#3776?l;ZA#[r   c              3   J   K   | ]  }|j                  d       dk(  sd  yw)r`   r   r   Nr   r   s     r   ro   z*extract_images_and_text.<locals>.<genexpr>*  s      'ccswwvRb?b'cr   z- Regular <img> tags: z- Inline background images: z- CSS background images: zText sections found: zText content sections:
- z
index.htmlz<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Site Analysis: a  </title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            line-height: 1.6;
            color: #333;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        header {
            background-color: #f8f9fa;
            padding: 20px;
            margin-bottom: 30px;
            border-radius: 5px;
            border-left: 5px solid #0066cc;
        }
        h1, h2, h3 {
            color: #0066cc;
        }
        .section {
            margin-bottom: 40px;
            padding: 20px;
            background-color: #fff;
            border-radius: 5px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .image-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 20px;
        }
        .image-item {
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 10px;
            background: #f8f9fa;
        }
        .image-item img {
            max-width: 100%;
            height: auto;
            border-radius: 2px;
            margin-bottom: 10px;
        }
        .image-details {
            font-size: 12px;
            color: #666;
        }
        .text-content {
            white-space: pre-wrap;
            background-color: #f8f9fa;
            padding: 15px;
            border-radius: 5px;
            max-height: 300px;
            overflow-y: auto;
            font-family: monospace;
            font-size: 14px;
        }
        .footer {
            margin-top: 50px;
            padding-top: 20px;
            border-top: 1px solid #ddd;
            color: #666;
            font-size: 14px;
            text-align: center;
        }
    </style>
</head>
<body>
    <header>
        <h1>Tailwind Site Rebuilder</h1>
        <p>Analysis of <a href="z" target="_blank">z!</a></p>
        <p>Generated on zF</p>
    </header>
    
    <div class="section">
        <h2>Images (z")</h2>
        <p>Regular images: z | Background images: z | CSS Background images: zY</p>
        
        <h3>Regular &lt;img&gt; Tags</h3>
        <div class="image-grid">
r`   r   zNo alt textz@
            <div class="image-item">
                <img src="z" alt="zh" loading="lazy">
                <div class="image-details">
                    <strong>Alt:</strong> z2<br>
                    <strong>Source:</strong> z.<br>
                </div>
            </div>z]
        </div>
        
        <h3>Background Images</h3>
        <div class="image-grid">
r   zUnknown elementz" alt="Background image" loading="lazy">
                <div class="image-details">
                    <strong>Element:</strong> zX
        </div>
    </div>
    
    <div class="section">
        <h2>Text Content</h2>
z=
        <h3>Headings</h3>
        <div class="text-content">z
Hz:
z</div>z?
        <h3>Paragraphs</h3>
        <div class="text-content">z	
... and z more paragraphs.z?
        <h3>Navigation</h3>
        <div class="text-content">z (z)
zr
    </div>
    
    <div class="footer">
        Generated by Tailwind Site Rebuilder
    </div>
</body>
</html>
z
Extracted z images and text content from z	 sectionszContent organized in zError organizing image zError extracting content: )-r   r   r   r   BS4_AVAILABLEr   r   r   find_allr   r   r   basenameresubendswithurllibrequestRequesturlopenr   writereadr   parentnamer   compilesearchgroupr   findallfindget_textranger   r   r   strftimer   sumkeysexistsshutilcopy2)Er    htmlr   r]   rf   content_dir
images_dirtext_dirsoupbase_urlidxr   r   r#   r$   img_filenameimg_pathr   
downloadedimg_reqresponseout_filer   img_infobackground_img_countbackground_patternr   r   match
element_idelement_classelement_context	style_tagcss_contentbg_img_matchesr>   r   r   	nav_itemslinkr   r5   itemr   r9   levelh_tagsr   r   r   rA   r:   
clean_textr   r   regular_imagesbackground_imagescss_background_imageskeyr   r   headingregular_dirbackground_dirimg_typeimg_filesrc_path	dest_pathr  sE                                                                        r   extract_images_and_textr2    s4   FL '',,z95Kk84Jww||K0HKKd+KK
T*KK4(BC|##u$T=1 "$--"67 5	6HC46ggeR(>>*AB%h4  GGGY7E WWXy9F &,C5"''2B2B32G1H#IL#%66,\#JL'001cd$.!ww||JEH!#i<!PJ "'J
F"(.."8"8%1  4i  %j #9 # $^^33GR3H GHVZ[ceiVj Gnv$NN8==?;)-J!$6|n"EFG G  #"wwub1=Bi=OTZ^gTgq&9mv9<cjjoo4>jD ) H zzcjjoo&<.2+03

vr0J-MM(+g5	6p  !ZZ(^_}}%uv 8	AG7AGR0*11%8++a.C >>*AB%h4 &//C.DAbggFVFVWZF[E\#]L#%66,\#JL'001cd$.!ww||JEH!#i<!PJ "'J
Q"(.."8"8%1  4i  %j #9 # $^^33GR3H RHVZ[ceiVj Rnv$NN8==?;)-J!$A,"PQR R ")T2!6J$'HHW[["-E$FM)0O!'VJ<q+AA$'Y}oQ+GG  ##24>jD ,	 H MM(+(A-(m8	Av w/ /	>I.>'..%7%?%?%LN$-n$= &6S#&>>2I#J&-h&< .55I4J!BGGL\L\]`LaKb+cL+-66,\+RL#/#8#89k#l , 6')ww||J'MH)+i<)XJ */J
]*0..*@*@$'-9  <q  -r +A +" &,^^%;%;GR%;%P !^T\^bckmq^r !^v~$,NN8==?$C15J$),Ml^*\$]!^ !^ (+<FjD(8(H #MM(30A50M&6/	>f 8$%+__4_%@L"bggll8\:C'R 5VWd345 iiIS) xx+}}4}0$$ $;?XoHp$ 7vz& 	 *3L& bggll8-=>gV BZ[% BDGGtF|nCV~R@ABB
 yy rDIII$8rDIII<SrW[W`W`hqW`Wr#'==t=#<L bggll8-?@#PWX 3\]D123 "'',,x8#P 	"TUq! "5'{3MS,TQZZdZ-C,THq[)GGeE7/:;# ?1::D:#9":" =>?GGDM"	" '/L$ ]]3'
JT)oQXYXbXbimXbXn!**4**@)oL&bggll8-=>gV /Z[# /A::D:1D4&.// 8$%+__4_%@L"bggll8\:C'R 5VWd345 yy JT2 8::<![[--F%LL"))$**,7	8 ,I(1L%bggll8_=sWU #YZ	"# "'',,{,ABCRYZ 	&^_GG.se267GGfX\\^445HIJ$OPGG*+GG*3v;-r:; ! Uf UUN ##[#[ [$''cV'c$c!GG,^,<B?@GG23D2ERHIGG/0E/FdKLGG+C,=+>bABGG./#((* &+%"SE%&%	&0 "'',,z<8#P t	TUGG 
 % G !N "%%7u =!001DEF G [M "*++ABSATTn  pE  oF FeV Vr $*`aQUU6]i-GAEER^L_`  WW\26
gge]3ggeR( %,gcU 3++.% 0..0gg.>.>s.C-D E 	 GG   $*caQUU6]l-JquuUaObc  WW\26
'')->?ggeR( %, '//6i 8..0gg.>.>s.C-D E 	 GG   \) & ' #1a[ 6EeW+Cl:66<
;STW;X#eWC 01'3J'?'D 6GGGb	$456	6 ! |+ & ' &l3CR8 (AGGqcJ'( |L12R7GGj\,-G)H2)M(NN_`a! |+ & ' )6 DDGGbfbfcBCD !GG  Yt	l 	
3v;-'Ec,FWEXXabc%k]34 ggll:y9j,?
K$/
NT2  	AC77<(wwvy1Hww''b(ABHA77<<
H=y( "[( CI "^X FI 77>>(+BGGNN94M!LL95-	A4 |##_G G G G % F 9#bDEEF&  604556HR R R R % Q DSEA3OPPQ,  A;A3?@@AD!^ !^ !^ !^ $- ] %(PQTPUUWXYWZ&[ \ \]  >8<==>5 5$B B3 3 -U		" 	"  *p/ /5 5 # #	& 	&d a* d_t	 t	n  A/zA3?@@A
  $*1#./|##$s    /AQ5 0C+AKAAJ) AJ-0AJAJ%AJ)-B*AK0AQ5 C)AL82AAL6AL0AK63AL;ALA7AL8:AQ5 4ANB2AN;AAM7?AM*0AM	<AM*AM7#AN/AAQ5 "AO(AAQ5  A&AQ5 &%AOBAQ5 $"AO6AQ5 <&AO0#AO0'AO+ AAO0&AQ5 AO=AO=/2AQ5 !AP<APAAQ5 /"APAAQ5 AQ5 /A#AQ5 AP$4AQ5 EAP)(4AQ5 AAQ 5AP6AP6!AP6%BAQ 3AP;AP;AP;#B7AQ AQ $D%AQ C	DAQ5 GB:AQJAQ5 JAJJAJJAJ&	J!AJ)J)	AKJ2AK	KAKK	AKKAKK	AK3KAK.K(AQ5 K.AK3K3AQ5 K6AL K;ALLAL	LALL	AL5LAL0L*AL8L0AL5L5AL8L8	AMMAMMAQ5 MAMMAQ5 MAM'M"AM*M*AM4M/AM7M7	ANN ANNANNANNANN	AON(AN<N6AQ5 N<AOOAQ5 OAOO	AQ5 OAOOAQ5 OAO(O#AQ5 O+AO0O0AO:O5AQ5 PAPPAQ5 PAPPAQ5 PAP&P!AQ5 P)AP3P.AQ5 P6
AQ Q AQ
QAQ5 Q	AQ2QAQ-Q'AQ5 Q-AQ2Q2AQ5 Q5	ARQ>ARRARRARc                 t   t         st        d       ddgddgddgdd	d
gdS 	 t        | d      }|}ddgddgddgd}d	d
g}t        j                  d      t        j                  d      t        j                  d      t        j                  d      g}t        j                  d      }|j                  d       D ]9  }|j                  dd      }	|D ]  }
|
j                  |	      }|D ]  }|j                         }d|
j                  v r)||d   vs)t        |      s5|d   j                  |       Jd|
j                  v r)||d   vs`t        |      sl|d   j                  |       ||d   vst        |      s|d   j                  |         |j                  |	      }|D ]I  }|j                         j                  d      j                  d      }|s4||vs9|j                  |       K < |j                  d      D ]6  }|j                  }|s|D ]  }
|
j                  |      }|D ]  }|j                         }d|
j                  v r)||d   vs)t        |      s5|d   j                  |       Jd|
j                  v r)||d   vs`t        |      sl|d   j                  |       ||d   vst        |      s|d   j                  |         |j                  |      }|D ]I  }|j                         j                  d      j                  d      }|s4||vs9|j                  |       K 9 dD ]8  }||vrg ||<   ||   r|dk(  rddg||<   |dk(  rddg||<   ,|dk(  s2ddg||<   : ||dS # t        $ r)}t        d|        ddgddgddgdd	d
gdcY d}~S d}~ww xY w)z6Extract CSS properties like colors and fonts from HTMLz9BeautifulSoup not available, can't extract CSS propertiesrgb(255, 255, 255)rgb(249, 250, 251)rgb(31, 41, 55)rgb(55, 65, 81)rgb(37, 99, 235)rgb(59, 130, 246)r7   Arial, sans-serifHelvetica, sans-serif)r<   r8   r   zcolor\s*:\s*([^;]+)zbackground-color\s*:\s*([^;]+)zbackground\s*:\s*([^;]+)zborder-color\s*:\s*([^;]+)zfont-family\s*:\s*([^;]+)c                 $    | j                  d      S )Nr   )r   r   s    r   r   z(extract_css_properties.<locals>.<lambda>>  s    g1F r   r   rg   r3   borderr6   r5   '"z!Error extracting CSS properties: N)r   r   r   r   r   r   r   r   r   rr   is_valid_colorr   r   r   )r
  r    r  r  r<   r8   color_patternsfont_family_patternr   r   rr   matchesr  colorfont_matchesfontr  r  r*  r   s                       r   extract_css_propertiesrG    sC   IJ  45IJ*,=>-/BC
 *+BC
 	
h
T=1 01EF&(9:)+>?

 %&=> JJ-.JJ89JJ23JJ45	
 !jj)EF }}%FG 	'GKK,E * 9!//%0$ 
9E!KKME#w6 |(<<PUAV"<077>!W__4 x(88^E=R"8,33E: v6>%;P"6N11%8
99 /66u=L% '{{}**3/55c:D-LL&')	'4 w/ 	+I#**K- =G%ook:G!( 
= %'7??:$F<,@@^TYEZ &| 4 ; ;E B%8$F8,<<PUAV &x 0 7 7 >$F6N:~e?T &v 5 5e <
==  3::;G) +E ;;=..s399#>DE 1T*+)	+4 4 	LC&  s #;,&#79M"NF3KF]#46G"HF3KH_#57J"KF3K	L 
 	

  

1!56  45IJ*,=>-/BC
 *+BC
 	


s   C-N N *N 	N N 2N >AN N "9N A N N )*N N  N =N 	AN (N -)N N 7N 	N7N2,N72N7c                 T   | j                         } | j                         dv ry| j                  d      rt        |       dv S | j                  d      s3| j                  d      s"| j                  d      s| j                  d      r
d	| v xr d
| v S t        |       dkD  xr
 d| vxr d| vS )z.Check if a string represents a valid CSS color)inherittransparentinitialcurrentcolornoneautoF#)r"   r   	   rgbrgbahslhslar_   r   r   ,;)r   r   r   r   rD  s    r   r@  r@    s     KKME {{}]] 5zY&&%"2"26":e>N>Nu>UY^YiYijpYqe|,u, u:>Cc.C3e3CCr   c           
      X   t         s)t        d       ddgdddddd	ddd
d	ddddddddidS 	 t        | d      }g 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id}|S # t        $ r6}t        d|        ddgdddddd	ddd
d	ddddddddidcY d}~S d}~ww xY w)z(Extract typography information from HTMLz5BeautifulSoup not available, can't extract typographyr:  r;  2.25rem700r6  fontSize
fontWeightrD  1.875rem6001.5remh1h2h3	paragraph1rem400r7  r;   r   z1.25remz1.125rem)rb  rc  rd  h4h5h6zError extracting typography: N)r   r   r   r   )r
  r  r=   r   s       r   extract_typographyrk    sH   EF)+BC#,EL]^#-UM^_#+5K\] &Pab

 
	
"
T=1 #,EL]^#-UM^_#+5K\]#,EL]^#-UM^_#)IZ[ &Pab

   
-aS12)+BC#,EL]^#-UM^_#+5K\] &Pab

 
	

s   8A* *	B)3+B$B)$B)c                     ddl m } ddl}t        d|         t        j                  |d       t        j
                  j                  |d      }t        j                  |d       t        |       }|j                  }|j                  d      r|d	d }| j                  d
      sd| z   } g }i }d}	|j                          d}
d}	 t        d|         |j                  j                  | ddi      }|j                  j                  |d      5 }|j                         j                  dd      }	t!        j"                  d|	t         j$                        }|r|j'                  d      }
t)        | |	|      \  }}t+        |	|       }|d   }t-        |	      }|d   |d<   ddd        |j0                         j3                  d1      }|j5                  d2d3       d3| d4}d!D ].  }|vs|d5k(  rd6d7g||<   |d8k(  rd&d/g||<   "|d9k(  s(dd g||<   0 t        j
                  j                  ||      }d:}t        d;       t7        | |d<d=      rd}t        d>       nqt9        | |d<d=      rd}t        d?       nTt        d@       t:        r	 ddAlm}m }m!}  |jD                  dBdCdDE      } |jF                  |      }|jI                  dFdG|  dHI       |jI                  dJdK| dHI       |jI                  dLdMdNI       |jI                  dOdPdNI       g dQ}dRdSdTdRdU}|D ]b  \  }} }!}"}#|jK                  | |!f| |"z   |!|#z   fgdV|jM                  |dW      X       |jI                  | dYz   |!dYz   f|jO                         dZI       d |jQ                  |       t        d[|        d}n&tS        |d]      5 }$|$jU                  d^       ddd       |r	 t        d_       tW               }%|%jY                  ||       }|rdt        d`t[        |jM                  dag              db       |jM                  da      r6t]        |da         D ]  \  }&}'t        dc|&dz    dd|'         nt        de       nt        dg       d}g }(|sct        dh       |r6di|v r3|(j_                  dit[        |di         djkD  r|di   ddj n|di   dkdldm       n|(j_                  didndkdldm       do|v rOdpj                  |do   D )cg c]  })|)d8   	 c})      }*|(j_                  dot[        |*      djkD  r|*ddj n|*dqdrds       n|(j_                  dodtdqdrds       d}+du|v rdv|du   v r|du   dv   r|du   dv   d   }+n7du|v r3ta        ddw      D ]$  },dx|, }||du   v s|du   |   s|du   |   d   }+ n |(j_                  dy|+r|+ndzdd{       d||v r|d|   rt[        |d|         d}z  }-dpj                  |d|   d|-       }.dpj                  |d|   |-d       }/|(j_                  d~t[        |.      djkD  r|.ddj dz   n|.d       |(j_                  dt[        |/      djkD  r|/ddj dz   n|/d       n(|(j_                  d~dd       |(j_                  ddd       d|v r1|(j_                  dt[        |d         djkD  r|d   ddj n|d   d       n4|(j_                  ddd       ndidndkdldmdodtdqdrdsdydzdd{d~ddddddddg}(| |
|||d<d=d<d=||rdndd}0tc        |      }1|1je                  |0|(|||       |	rrtS        t        j
                  j                  |d      d]d      5 }$|$jU                  |	       ddd       t        dt        j
                  j                  |d              |r tS        t        j
                  j                  |d      d]d      5 }$tg        jh                  ||$d}       ddd       t        dt        j
                  j                  |d              tS        t        j
                  j                  |d      d]d      5 }$|$jU                  d|  d       |$jU                  d       |$jU                  d       t]        |jM                  dag             D ]  \  }&}'|$jU                  d|' d        |$jU                  d       |jM                  di       }2|$jU                  d|2jM                  dd       d       |$jU                  d|2jM                  dd       d       |$jU                  d|2jM                  dd:       d       |$jU                  d|2jM                  dd       d       ddd       t        dt        j
                  j                  |d              t        d       t        dt        j
                  j                  |d       d       |r.t        dt        j
                  j                  |d       d       yy# 1 sw Y   UxY w# t.        $ rN}t        d|        t        d       g dg ddd gd!}d"d#gd$d%d&d'd(d)d&d'd*d)d&d'd+d,d-d.d/d'id0}Y d}~d}~ww xY w# t.        $ rL}t        d\|        tS        |d]      5 }$|$jU                  d^       ddd       n# 1 sw Y   nxY wY d}~d}~ww xY w# 1 sw Y   xY w# t.        $ r}t        df|        d}Y d}~gd}~ww xY wc c})w # 1 sw Y   xY w# 1 sw Y   +xY w# 1 sw Y   xY w)z:Create a simulated rebuild context without using a browserr   r   NzCreating simulation for Tr   screenshotsr!   r"   r   r   rg   z WebsitezFetching content from r   r   r      r   rz   replace)errorsz<title>(.*?)</title>r   r<   r8   zError fetching content: z)Continuing with simulation using defaults)r4  r5  zrgb(243, 244, 246))r6  r7  zrgb(107, 114, 128)r8  r9  r7   r:  r;  rY  rZ  r6  r[  r^  r_  r`  ra  re  rf  rg  r7  r;   z%Y%m%d_%H%M%S.r   z_screenshot.pngr3   r4  r5  r5   r6   Fz0Attempting to capture real website screenshot...r     z&Real screenshot captured successfully!z#Screenshot captured using Selenium!z:Failed to capture real screenshot, creating placeholder...)r	   r
   	ImageFontRGBr   rr  )         rW  )2   ry  zScreenshot placeholder for: )   )   ;   )fill)ry  rh   zGenerated: )ry     z2Real screenshot capture failed - using placeholder)   &      )ry     z3Note: Color detection will work on this placeholder))r>   r      r   P   )r@   r   i@  r   i,  )r   r   il  r   r  )rA   r   i4  r   r  )%   c      )r|        )`      rw  )r>   r@   r   rA   )r   r   r   )r  r  r  )outliner}  r   )   r  r  z"Created placeholder screenshot at z$Could not create placeholder image: ry   zScreenshot placeholderu/   🔍 Analyzing screenshot with OpenAI Vision...u   ✅ ASR Generated: r^   z sections detectedz  z. u   ❌ ASR generation failedu'   ⚠️  OpenAI Vision analysis failed: u:   ⚠️  No screenshot available for OpenAI Vision analysisz8ASR generation failed, using legacy section detection...r>   rh   rx   left)r`   r5   rr   rt   zMain navigationr?   r   
horizontalright)r`   r5   rr   rv   zHOME ABOUT SERVICES CONTACTr9   rb  r   r   r@   zWelcome to our website!)r`   r5   rX   r   r}   r   ...)r`   r5   r   zOur features and serviceszWhat our customers sayrA   zContact information and linksrealplaceholder)r    r'   	timestampr(   r   r#   r$   r%   r&   is_real_screenshotscreenshot_typezraw_html.txtr{   zRaw HTML saved to zasr.jsonr~   zASR saved to zasr_summary.txtz(Annotated Structure Reference (ASR) for r   z>============================================================

zTemplate Structure:
r   z
Layout Analysis:
rU   z- Layout Type: rV   rW   z- Total Sections: rZ   z- Has Overlay Header: rX   z- Navigation Style: rY   zASR summary saved to z
Simulation complete!zCheck r   z# for the generated rebuild context.z' for the Annotated Structure Reference.)5r   urllib.requestr   r   r   r   r   r   r   r   r'   r   r   r   r   decoder   r   
IGNORECASEr   r2  rG  rk  r   r   r  ro  capture_real_screenshotcapture_screenshot_seleniumPIL_AVAILABLEPILr	   r
   rs  newDrawr5   	rectangler   uppersaver   r   r   analyze_screenshotr   r   r   r  r   r   r   r   )3r    r   r   r   screenshots_dir
parsed_urlr)   r]   rf   html_contentr'   rT   reqr  title_matchcss_propertiesr<   r=   r   r  screenshot_filenamer*  screenshot_pathscreenshot_capturedr	   r
   rs  r   drawsection_layoutssection_colorsr   r   yry   r   r   r   r   	structurer2   r#  nav_text	hero_textr$  	mid_pointfeatures_texttestimonials_textr   	rebuilderrU   s3                                                      r   create_simulationr    su   !	$SE
*+KK
T*ggll:}=OKK$/ #JF  >>123 FLL||~h'E
C1
&se,-nn$$!  $Y  Z % 
 ^^##C#4 	:#==?11')1LL ))$;\2==YK#))!, $;3j#Y FL 4L#FN $H-F ,L9J"0"9Jw'	:\ ''8I $^^C56a	{/R 0 Hfl"35IJs02CDs13FGsH ggll?4GHO	
<= sOT3?"67	$S/4	E"34JK (6;;  eii{/J%y~~c* 		(&B3%$H|	\		){9+%>\	R		)%Y`n	o		)%Zao	p# ,* .+	" 1@ \,L!Q1NNQFQUAEN#;YUcUgUght  wF  VGN  HIIq2vq2v.0B0B0D?I[\
 ):?:KLM&*# os+ 2q012 	CD24O!44_cJC+C8Lb0Q,R+SSefg77/0(1#6J2K(L 791Q3%r)567 12
 	JK HHI<'$<?X@V<WZ]<]L24C8copxcy4%+	!  $-4%+	!  |+88l<>X$YdT&\$YZ(.1(mc.AHTcNx+*1	!  (9+*1	!  I\)dl:6N.NS_`jSklpSq(4T:1=	|+"1a[ EeW+Cl:66<
;STW;X$0$<S$A!$D		 OO%.	4M&*  |+\0J\ :;q@	 #l)CJY)O P$'HH\,-G	
-S$T!&;>};MPS;SM$3/%7Yf! 
 *?BCT?UX[?[-ds3e;ar!  &7! 
 *4!  <'$<?X@V<WZ]<]L24C8copxcy!  $;!  %-4%+	 )9+*1	 #5*. '7
 +4
 %;5HD '1%86mO j)I$$_h
TZ\hjmn "'',,z>:C'R 	"VWGGL!	""277<<
N#K"LMN "'',,z:6gN 	(RSIIc1Q'	(bggll:zBCDE "'',,z+<=sWU 	cYZGG>se2FGGG%&GG+, )#''2F*K L ,9"YKr*+, GG*,!gg&7<OGGoo&9&9-&S%TTVWXGG()<)<=Mq)Q(RRTUVGG,_-@-@AUW\-],^^`abGG*?+>+>?QS\+]*^^`ab	c 	%bggll:?P&Q%RST	
"#	F277<<
,BCDDg
hi
rww||J0ABCCjkl U
	: 	:*  
(,-9: ]P)+>?
 *+BC#,EL]^#-UM^_#+5K\] &Pab



|  6<QC@A/3/ 61GG456 6 662 2"  	;A3?@C	B %Z@	" 	"	( 	(
	c 	cs   A
g> Bg1g> Di 2j0Bj= +k$?k)4k6-D'l1g;6g> >	iAii	j-!j(;j	j(j	j((j-0j:=	k!kk!)k36l lc                    	 ddl m} ddlm} ddlm} ddlm} ddlm	} ddl
m}	 ddlm}
 dd	l}t        d
        |       }|j!                  d       |j!                  d       |j!                  d       |j!                  d       |j!                  d       |j!                  d       |j!                  d       |j!                  d       |j!                  d       |j!                  d       |j!                  d| d|        	  | |
       j#                               }|j%                  ||      }	 t        d|  d       |j)                  |         ||d      j+                  |	j-                  |j.                  df             |j1                  d        |j3                  d!      }|j3                  d"      }t        d#| d$|        |j5                  ||       |j1                  d%       |j7                  |      }|r t        d&|        	 |j9                          y't        d(       	 |j9                          y# t&        $ rU}t        d|        	 |j%                  |      }n(# t&        $ r}t        d|        Y d	}~Y d	}~yd	}~ww xY wY d	}~dd	}~ww xY w# |j9                          w xY w# t:        $ r t        d)       Y yt&        $ r}t        d*|        Y d	}~yd	}~ww xY w)+zA
    Capture a full-page screenshot using Selenium WebDriver
    r   )	webdriver)Options)Service)By)WebDriverWait)expected_conditions)ChromeDriverManagerNz5Setting up Chrome WebDriver for screenshot capture...z
--headlessz--no-sandboxz--disable-dev-shm-usagez--disable-gpuz--disable-web-securityz --allow-running-insecure-contentz--ignore-certificate-errorsz--ignore-ssl-errorsz%--ignore-certificate-errors-spki-listz--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36z--window-size=rU  )serviceoptionsz7Failed to create Chrome driver with webdriver-manager: )r  z*Failed to create Chrome driver from PATH: FzNavigating to r  rn  r:      z return document.body.offsetWidthz,return document.body.parentNode.scrollHeightzPage dimensions: r   r   zFull-page screenshot saved to: TzFailed to save screenshotzLSelenium not available. Install with: pip install selenium webdriver-managerz Error with Selenium screenshot: )seleniumr  !selenium.webdriver.chrome.optionsr  !selenium.webdriver.chrome.servicer  selenium.webdriver.common.byr  selenium.webdriver.support.uir  selenium.webdriver.supportr  webdriver_manager.chromer  timer   add_argumentinstallChromer   r   untilpresence_of_element_locatedTAG_NAMEsleepexecute_scriptset_window_sizesave_screenshotquitImportError)r    output_pathr#   r$   r  r  r  r  r  ECr  r  chrome_optionsr  driverr   e2total_widthtotal_heightsuccesss                       r   r  r  F  s   R&==3?H@EF !##L1##N3##$=>##O4##$<=##$FG##$AB##$9:##$KL##  %g  	h##nUG1VH$EF
	13;;=>G%%g~%NF$	N3%s+,JJsO &"%++..V/DE
 JJqM !//0RSK!001_`L%k]!L>BC "";= JJqM ,,[9G7}EF KKM	 12 KKM[  	KA3OP")).)A B2$GHu 		Z KKM \] 045s   DJ3 .H= 3CJ J3  J ,J3 =	JJI('J(	J1J?JJ3 JJJ3 JJ3 J00J3 3K)	K)K$$K)c                    t        d       t        | |||      ryt        d       	 d| d| d|  }t        d|        t        j                  j	                  |dd	i
      }t        j                  j                  |d      5 }|j                         dk(  rLt        |d      5 }|j                  |j                                ddd       t        d|        	 ddd       yt        d|j                                 	 ddd       y# 1 sw Y   GxY w# 1 sw Y   yxY w# t        $ r}t        d|        Y d}~yd}~ww xY w)zB
    Capture a real screenshot of a website using local tools
    z<Attempting to capture screenshot using Selenium WebDriver...Tz7Selenium failed, trying external service as fallback...z https://image.thum.io/get/width/z/crop//z'Attempting to capture screenshot from: r   r   r   rz  r   r  r   Nz&External service screenshot saved to: z"External service returned status: Fz(Error with external screenshot service: )r   r  r   r   r   r   getcoder   r   r   r   )	r    r  r#   r$   screenshot_urlr  r  r   r   s	            r   r  r    s_    

HI #3UFC	
CD;E7&PQRUQVW77GHI nn$$  T % 
 ^^##C#4 	!S(+t, -GGHMMO,->{mLM	 	 :8;K;K;M:NOP	 	- -	 	  8<=sZ   AD"  D$ D
DD" $DD" 
D	DDD" D" "	E+D>>Er   ru  )r   r   r   r   r  r   urllib.parser   r   r   r   r   r  r  r	   r
   r  r   bs4r   r   r   r2  rG  r@  rk  r  r  r  rk   r   r   <module>r     s    
 	   * 55
.$M6!MdW dWNG$Tu
nD&2
hmm^Vr'[,  545  .M	
\]	
,-.  6M	
UV	
456s3   A 
A0 B A-,A-0B
	B
B'&B'