ó
    À‘´j·×  ã                   ó�  • S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
Jr  SSKrSSKJr  SSKJrJr  SSKJr  SS	KJr  SS
KJrJr  SSKJr  \R6                  " 5       \R8                  " \" S5      S9S 5       5       r\R=                  5       \R>                  " S5      \R@                  " SSSSS9\R@                  " SS\RB                  " \ V s/ s H  o RD                  PM     sn 5      SS9\R@                  " SSSS9\R@                  " SS\#SS9\R@                  " S \RB                  " S!S"/5      S!S#S$9\R@                  " S%S&S'S(S)9S\$S*\$S+\\$   S,\\$   S-\#S.\$S/\%4S0 j5       5       5       5       5       5       5       5       r&\R=                  5       \R>                  " S1\R                  " S'S2S'S39S49\R@                  " SSSS5S9\R@                  " SS\RB                  " \ V s/ s H  o RD                  PM     sn 5      S6S9\R@                  " SSS7S9\R@                  " SS\#S8S9\R@                  " S9S:S;S9S1\$S*\$S+\\$   S,\\$   S-\#S<\$4S= j5       5       5       5       5       5       5       r'\R=                  5       \R@                  " SS\RB                  " \ V s/ s H  o RD                  PM     sn 5      S>S9\R@                  " S?S@S'SAS)9S+\\$   SB\%4SC j5       5       5       r(\R7                  5       SD 5       r)\)R=                  5       \R@                  " SES'SFS)9\R@                  " S%S&S'S(S)9SG\%S/\%4SH j5       5       5       r*\)R=                  5       \R>                  " SI\R                  " S'SJ9S49\R@                  " SKS'SLS)9\R@                  " S%S&S'S(S)9SI\$SM\%S/\%4SN j5       5       5       5       r+\)R=                  5       \R>                  " S1\R                  " S'S2S'S39S49\R@                  " S9SOSPS9\R@                  " SKS'SLS)9\R@                  " S%S&S'S(S)9S1\$S<\$SM\%S/\%4SQ j5       5       5       5       5       r,\)R=                  5       \R@                  " S%S&S'S(S)9S/\%4SR j5       5       r-\)R=                  5       \R@                  " S\RB                  " SSST/5      SUS9\R@                  " SV\RB                  " SWSX/5      SYS9\R@                  " SZS[\#S\S9\R@                  " S%S&S'S(S)9S+\\$   S]\\$   S^\#S/\%4S_ j5       5       5       5       5       r.\R=                  S`Sa9\R>                  " S5      \R@                  " SSSSbS9\R@                  " ScSd\RB                  " / SeQ5      SfSgS$9\R@                  " ShS'SiS)9\R@                  " Sj\RB                  " / SkQ5      SlSmS$9\R@                  " S \RB                  " S!S"/5      S!S#S$9\R@                  " SV\RB                  " / SnQ5      SoSpS$9S\$S*\$Sd\$Sq\%Sr\$S.\$S]\$4Ss j5       5       5       5       5       5       5       5       r/\R=                  StSa9\R>                  " Su5      \R@                  " SSSSbS9\R@                  " SSSvS9\R@                  " Sw\#SSxS$9Su\$S*\$S,\\$   Sy\\#   4Sz j5       5       5       5       5       r0\R=                  S{Sa9\R>                  " Su5      \R@                  " S|S'S}S~9\R@                  " SSSSbS9\R@                  " SSSS9\R@                  " S€\RB                  " S�SB/5      S�S‚S$9Su\$Sƒ\$S*\$S,\\$   S„\$4
S… j5       5       5       5       5       5       r1\R=                  S†Sa9\R>                  " S5      \R@                  " SSSSbS9\R@                  " S‡\RB                  " / SˆQ5      SS‰S$9\R@                  " SŠS'S‹S)9\R@                  " SŒS�\#SŽS9\R@                  " S�\RB                  " / S�Q5      S‘S’S$9\R@                  " S“S'S”S)9S\$S*\$S•\\$   S–\%S—\#S˜\$S™\%4Sš j5       5       5       5       5       5       5       5       r2\R=                  5       \R>                  " S5      \R@                  " SSSS›S9\R@                  " SŒS�\#SŽS9\R@                  " SœS'S�S)9S\$S*\$S—\#Sž\%4SŸ j5       5       5       5       5       r3\R=                  5       \R>                  " S5      \R@                  " SSSSbS9\R@                  " S SS¡S9\R@                  " S‡\RB                  " / SˆQ5      SS‰S$9\R@                  " SŒS�\#SŽS9\R@                  " S \RB                  " S!S"/5      S!S¢9\R@                  " Sj\RB                  " / SkQ5      S£S¤S$9\R@                  " S“S'S¥S)9S\$S*\$S¦\\$   S•\\$   S—\#S.\$Sr\$S™\%4S§ j5       5       5       5       5       5       5       5       5       r4S¦\\$   S¨\$Su\	S©\S\$S.\$S—\#Sr\$S™\%S*\$4Sª jr5S.\$4S« jr6\R=                  5       \R>                  " S\R                  " S'SJ9S49\R@                  " S‡\RB                  " / SˆQ5      SS‰S$9\R@                  " SŒS�\#SŽS9S\$S•\\$   S—\#4S¬ j5       5       5       5       r7\R=                  5       \R@                  " S­S®S¯S9\R@                  " S°S±\#S²S9\R@                  " S³S'S´S)9Sµ\$S¶\#S·\%4S¸ j5       5       5       5       r8\Rs                  \/SƒSa9  \Rs                  \2S¹Sa9  Sº r:\;S»:X  a  \:" 5         ggs  sn f s  sn f s  sn f )¼u„  
Command-line interface for Quber.

Four commands compose into the extraction pipeline: `document`, `table`, `fuse`,
`figure`. They hand work to each other through files rather than in memory, and
each names its output after the source document's stem, so one stage's
`--output-dir` is the next stage's input directory.

`table`, `fuse` and `figure` each finish by writing a completion marker,
`<base>.tables.complete.json`, `<base>.fuse.complete.json` or
`<base>.figure.complete.json`, as their last upload. The marker carries status
`complete` or `failed`, so a downstream step learns from its existence that the
job's artifacts are whole or that the job failed. `document` writes no marker.
On the cloud path the parse runs on the RunPod worker (`runpod/handler.py`),
which writes the parse's marker itself.

`document` parses the PDF and writes `<base>.docling.json` with
`<base>.confidence.json` and `<base>.cells.json` beside it. All three are always
written, because the later stages reload them together through
`ParseResult.load`. Markdown and split-page HTML are optional extras.

`table` extracts the tables and writes `<base>.tables.json`, plus
`<base>.flags.json` when any table carries a review flag: a corrected cell with
an inspect status, header text left out of the table, or a footnote marker that
could not be tied to a cell (`quber.core.extractors.base.cell_flags`).

`fuse` merges the two into `<base>.unified.json` and `<base>.unified.md`, with
`<base>.cells.json` beside them â€” the parse's positioned page cells, which the
figure stage's value reconciliation requires next to the parse it is handed. It
also writes the fused tables to `<base>.tables.json`, replacing any already in
the output directory, the fusion report `<base>.fusion.json`, and
`<base>.flags.json` when the tables or the heading review raised a flag. By
default it runs both engines in-process. Given `--artifacts-dir` it reloads
`<base>.{docling,confidence,cells}.json` and `<base>.tables.json` from a prior
run and only fuses, which is how the cloud path splits the work across jobs.

`figure` runs last, after fusion, so its enrichment lands in the document
everything downstream reads. It loads the parse back â€” `<base>.unified.json`
first, then `<base>.docling.json` â€” reads the pages holding charts, pictures,
and image-printed tables, and writes the enriched parse back under the filename
it read. Alongside it go `<base>.figures.json` and one `<base>.p<N>.ade.json`
per page scanned, so a re-run reuses a page already paid for instead of
submitting it again. Three more are written only when they have content:
`<base>.scanned-tables.json` when a table was read off a page image,
`<base>.figure-values.json` when `<base>.cells.json` sat beside the parse and
the value step is on â€” each plotted value reconciled between the scan's reading
and a local read grounded in those cells, with a status and a page box per
value â€” and `<base>.figure-digest.json` when the scan model is dpt-3, the
default.

`ade`, `analyze`, `batch`, `dual`, and `validate` are standalone and not part of
that chain. `playground` serves the answering web app in `quber.playground`,
which runs the pipeline as subprocesses when a document is uploaded. With no
GPU worker configured it runs `fuse`, then `figure`, then its own ingest. With
one configured it runs `table` locally, sends the parse to the RunPod worker,
then runs `fuse --artifacts-dir`, `figure` and the ingest.
é    N©Úversion)ÚPath)ÚOptional)Úlogger)ÚModelConfigÚModelProvider)Ú	LLMClient)Úresolve_document)Úoutput_sinkÚwrite_completion_marker)Úget_settingsÚquberc                  ó   • g)z7Quber - Advanced table extraction and inference system.N© r   ó    Ú'/home/mande/repo/quber/src/quber/cli.pyÚclir   S   s   € ð 	r   Úpdf_pathz--output-dirz-oÚoutputz"Output directory (default: output))ÚdefaultÚhelpz
--providerz-pz6Model provider to use (auto-detected if not specified))Útyper   z--modelz-mz>Specific model to use (uses provider default if not specified))r   z--max-concurrenté   z.Maximum concurrent table analyses (default: 5))r   r   r   z--presetztuned-financialÚlegacyzUDoclingParser configuration preset (default: tuned-financial; 'legacy' = pre-QUE-218))r   r   r   z	--verbosez-vTzEnable verbose logging)Úis_flagr   Ú
output_dirÚproviderÚmodelÚmax_concurrentÚpresetÚverbosec                 óò  ^^^• U(       a  SOSn[         R                  " 5         [         R                  " [        R                  US9  [        5       R                  XtS.S9nU(       a  [        U5      OSn	SSKJ	n
   U
" U	UUUS	9m[        U 5      m[        R                  " SU  35        UUU4S jn[        R                   " U" 5       5      u  pÞn[        R                  " S5        [        R                  " SUS    S35        [        R                  " SU 35        [        R                  " SU 35        g! [         a8  n[        R                  " S
U 3SS9  [        R                  " S5         SnANíSnAff = f)z²
Analyze tables in a PDF document with LLM inference.

Example:
    quber analyze document.pdf
    quber analyze document.pdf --provider anthropic --model claude-3-opus-20240229
ÚDEBUGÚINFO©Úlevel)Ú	log_levelÚmax_concurrent_tables©ÚupdateNr   ©ÚTableInferenceProcessor)r   r   Úsettingsr!   úError: T©Úerré   z
Analyzing: c               “   óz  >#   •  TR                  T5      I S h  v•N n [        T5      nUR                  SSS9  TR                  nX S3-  nX S3-  nTR	                  U [        U5      5        TR                  U [        U5      5        XU4$  Ns! [         a  n[        R                  " SU 35        e S nAff = f7f)NT©ÚparentsÚexist_okú_analysis.jsonú_summary.mdzAnalysis failed: )
Úprocess_documentr   ÚmkdirÚstemÚ	save_jsonÚstrÚsave_summaryÚ	Exceptionr   Úerror)	ÚresultsÚoutput_pathÚ	base_nameÚ	json_fileÚsummary_fileÚeÚdocr   Ú	processors	         €€€r   Úrun_analysisÚanalyze.<locals>.run_analysisž   sÉ   øé € ð	Ø%×6Ñ6°sÓ;×;ˆGô ˜zÓ*ˆKØ×Ñ d°TÐÑ:ð Ÿ™ˆIØ#¨°>Ð&BÑBˆIØ&¨;°kÐ)BÑBˆLð ×Ñ ¬¨Y«Ô8Ø×"Ñ" 7¬C°Ó,=Ô>à |Ð3Ð3ñ <øô  ó 	Ü�LŠLÐ,¨Q¨CÐ0Ô1Øûð	üs9   ƒB;…B ™BšA2B ÂB;ÂB Â
B8ÂB3Â3B8Â8B;u   
âœ“ Analysis completez
  - Found Útotal_tablesú tablesz  - JSON output: z  - Summary: )r   ÚremoveÚaddÚsysÚstderrr   Ú
model_copyr	   Úquber.processorsr-   Ú
ValueErrorÚclickÚechoÚexitr   ÚasyncioÚrun)r   r   r   r   r    r!   r"   r(   r.   Úprovider_enumr-   rF   rI   rA   rD   rE   rG   rH   s    `              @@r   ÚanalyzerZ   Z   s;  ú€ öF #‘¨€IÜ
‡M‚M„OÜ
‡J‚JŒs�z‰z Ò+ô ‹~×(Ñ(Ø&ÑPð )ð €Hö
 08”M (Ô+¸T€Mõ 9ð	Ù+Ø"ØØØñ	
ˆ	ô ˜8Ó
$€Cô 
‡J‚J�˜x˜jÐ)Ô*÷ô, (/§{¢{±<³>Ó'BÑ$€G˜ô 
‡J‚JÐ(Ô)Ü	‡J‚J�˜G NÑ3Ð4°GÐ<Ô=Ü	‡J‚JÐ" 9 +Ð.Ô/Ü	‡J‚J�˜|˜nÐ-Õ.øôO ó Ü�
Š
�W˜Q˜C�= dÒ+Ü�Š��‰ûðús   Á;	D4 Ä4
E6Ä>.E1Å1E6Ú	directoryF)ÚexistsÚ	file_okayÚdir_okay)r   z.Output directory for results (default: output)zModel provider to usezSpecific model to usez;Maximum concurrent table analyses per document (default: 5)z	--patternz*.pdfz&File pattern to match (default: *.pdf)Úpatternc                 óš  ^^^• [        5       R                  SU0S9n[        U 5      n[        UR	                  U5      5      mT(       d.  [
        R                  " SU 3SS9  [        R                  " S5        [
        R                  " S[        T5       S35        [        U5      mTR                  SSS	9  U(       a  [        U5      OS
nSSKJn	   U	" XƒUS9mUUU4S jn[        R                   " U" 5       5      n[        U5      n[#        S U 5       5      n[
        R                  " S5        [
        R                  " SU S[        T5       S35        [
        R                  " SU S35        [
        R                  " SU S35        g
! [         a8  n
[
        R                  " SU
 3SS9  [        R                  " S5         S
n
A
NîS
n
A
ff = f)z˜
Process multiple PDF documents in a directory.

Example:
    quber batch documents/
    quber batch documents/ --pattern "*.pdf" --output-dir results/
r)   r*   z!No files found matching pattern: Tr0   r2   úFound z PDF files to processr4   Nr   r,   )r   r   r.   r/   c               “   óP  >#   • / n T HÉ  n[         R                  " SUR                   35         T	R                  [	        U5      5      I S h  v•N nUR
                  nTU S3-  nTU S3-  nT	R                  U[	        U5      5        T	R                  U[	        U5      5        [         R                  " SUS    S35        U R                  U5        MË     U $  NŠ! [         a@  n[         R                  " SU 3SS	9  [        R                  " S
U SU 35         S nAGM  S nAff = f7f)Nz
Processing: r7   r8   u     âœ“ rK   z tables analyzedu     âœ— Failed: Tr0   zFailed to process ú: )rT   rU   Únamer9   r=   r;   r<   r>   Úappendr?   r   r@   )
rA   Úpdf_fileÚresultrC   Ú	json_pathÚsummary_pathrF   rB   Ú	pdf_filesrH   s
          €€€r   Úprocess_batchÚbatch.<locals>.process_batchø   s  øé € ØˆÛ!ˆHÜ�JŠJ˜¨¯© Ð7Ô8ðCØ(×9Ñ9¼#¸h»-ÓH×H�ð %ŸM™M�	Ø'¨Y¨K°~Ð*FÑF�	Ø*°	¨{¸+Ð-FÑF�à×#Ñ# F¬C°	«NÔ;Ø×&Ñ& v¬s°<Ó/@ÔAä—
’
˜V F¨>Ñ$:Ð#;Ð;KÐLÔMØ—‘˜vÖ&ñ "ð( ˆñ# Iøô ó CÜ—
’
˜^¨A¨3Ð/°TÒ:Ü—’Ð1°(°¸2¸a¸SÐA×BÓBûðCüsA   ƒ+D&¯CÁCÁBCÃD&ÃCÃ
D#Ã#4DÄD&ÄD#Ä#D&c              3   ó*   #   • U  H	  oS    v •  M     g7f)rK   Nr   )Ú.0Úrs     r   Ú	<genexpr>Úbatch.<locals>.<genexpr>  s   é € Ð:²'¨Q˜Ö(²'ùs   ‚u   
âœ“ Batch processing complete!z  - Processed Ú/z
 documentsz  - Analyzed ú total tablesz  - Results saved to: )r   rQ   r   ÚlistÚglobrT   rU   rO   rV   Úlenr:   r	   rR   r-   rS   rW   rX   Úsum)r[   r   r   r   r    r_   r.   Údir_pathrY   r-   rF   rk   rA   Útotal_documentsrK   rB   rj   rH   s                  @@@r   Úbatchrz   ½   s‚  ú€ ô< ‹~×(Ñ(Ð1HÈ.Ð0YÐ(ÐZ€Hô �I‹€HÜ�X—]‘] 7Ó+Ó,€IæÜ�
Š
Ð6°w°iÐ@ÀdÒKÜ�Š�Œä	‡J‚J�œ˜I›Ð'Ð'<Ð=Ô>ô �zÓ"€KØ×Ñ˜d¨TÐÑ2ö 08”M (Ô+¸T€Mõ 9ðÙ+°]ÐZbÑcˆ	÷ô0 �kŠk™-›/Ó*€Gô ˜'“l€OÜÑ:±'Ó:Ó:€Lä	‡J‚JÐ1Ô2Ü	‡J‚J� Ð0°´#°i³.Ð1AÀÐLÔMÜ	‡J‚J�˜|˜n¨MÐ:Ô;Ü	‡J‚JÐ'¨
 |°1Ð5Õ6øôM ó Ü�
Š
�W˜Q˜C�= dÒ+Ü�Š��‰ûðús   ÃF Æ
G
Æ.GÇG
z&Show models for specific provider onlyz--allz-az"Show all models (can be very long)Úallc                 ó®  • SSK Jn  U" SS9nUR                  5       nU (       a  [        U 5      /nO[	        [        5      n[
        R                  " S5        [
        R                  " S5        [
        R                  " S5        [
        R                  " S5        U GH=  nUR                  U5      nUR                  U;   nU(       a  S	OS
n	[
        R                  " SUR                  R                  5        SU	 35        [
        R                  " S5        XvR                     n
U(       d#  [        U
5      S:”  a  U
SS n[        U
5      S-
  nOU
nSnU H_  nU[        R                  R                  U5      :X  a  SOSn[        U5      S:”  a	  USS S-   nOUn[
        R                  " SU U 35        Ma     US:”  d  GM#  [
        R                  " SU S35        GM@     U(       ds  [
        R                  " S5        [         HR  n[        R                  R                  U5      nU(       d  M+  [
        R                  " SU SUR                   S35        MT     gg)z(List available models for each provider.r   )ÚAgentFactoryF)Úenable_logfirez%Model Providers and Available Models:ú2==================================================z?
Note: You can use any model name directly, even if not listed.zEThe list below shows models recognized by the installed pydantic-ai.
u   âœ“ (API key found)u   âœ— (no API key)Ú
Ú z(----------------------------------------é
   Nz
 (default)Ú é<   é9   z...õ     â€¢ z
  ... and z# more models (use --all to see all)u9   
âš  No API keys found. Please set environment variables:z (for Ú))Úquber.agentsr}   Úget_available_providersr	   rt   rT   rU   Úlist_available_modelsÚvalueÚupperrv   r   ÚDEFAULT_MODELSÚgetÚAPI_KEY_VARS)r   r{   r}   ÚfactoryÚ	availableÚproviders_to_showÚpÚmodelsÚis_availableÚstatusÚ
model_listÚdisplay_modelsÚ	remainingr   r   Úmodel_displayÚkey_vars                    r   r”   r”     sî  € õ *á¨%Ñ0€Gð ×/Ñ/Ó1€Iö Ü*¨8Ó4Ð5Ñä ¤Ó/Ðä	‡J‚JÐ6Ô7Ü	‡J‚JˆxÔÜ	‡J‚JÐQÔRÜ	‡J‚JÐWÔXäˆØ×.Ñ.¨qÓ1ˆØ—w‘w )Ñ+ˆæ*6Ñ&Ð<NˆÜ�
Š
�R˜Ÿ™Ÿ™›Ð(¨¨&¨Ð2Ô3Ü�
Š
�8ÔàŸG™G‘_ˆ
ö ”s˜:“¨Ó+Ø'¨¨˜_ˆNÜ˜J›¨"Ñ,‰Ià'ˆNØˆIã#ˆEØ&+¬{×/IÑ/I×/MÑ/MÈaÓ/PÓ&P‘lÐVXˆGä�5‹z˜B‹Ø % c r 
¨UÑ 2‘à %�Ü�JŠJ˜ ˜¨w¨iÐ8Ö9ñ $ð �qŽ=Ü�JŠJ˜ I ;Ð.QÐR×Sñ9 ö< Ü�
Š
ÐOÔPßˆAÜ!×.Ñ.×2Ñ2°1Ó5ˆGßˆwÜ—
’
˜V G 9¨F°1·7±7°)¸1Ð=Ö>ò ð r   c                  ó   • g)zDatabase management commands.Nr   r   r   r   Údbr�   ^  s   € ð 	r   z--dropz9Drop existing tables before creating (WARNING: data loss)Údropc                 ó˜  • SSK JnJn  U(       a  SOSn[        R                  " 5         [        R
                  " [        R                  US9  [        R                  " S5         U" 5       nU" XPS9  [        R                  " S5        g! [         a8  n[        R                  " S	U 3S
S9  [        R                  " S5         SnAgSnAff = f)zInitialize the database schema.r   )Ú
get_engineÚinit_dbr$   r%   r&   zInitializing database...)Údrop_allu%   âœ“ Database initialized successfullyu#   âœ— Failed to initialize database: Tr0   r2   N)Úquber.db.connectionr    r¡   r   rM   rN   rO   rP   rT   rU   r?   rV   )rž   r"   r    r¡   r(   ÚenginerF   s          r   Úinitr¥   d  sŒ   € ÷
 8æ"‘¨€IÜ
‡M‚M„OÜ
‡J‚JŒs�z‰z Ò+ä	‡J‚JÐ)Ô*ðÙ“ˆÙ�Ò&Ü�
Š
Ð:Õ;øÜó Ü�
Š
Ð8¸¸Ð<À$ÒGÜ�Š��‰ûðús   Á##B Â
C	Â.CÃC	rh   )r\   z--generate-embeddingsz!Generate embeddings during importÚgenerate_embeddingsc                 óš  • SSK Jn  U(       a  SOSn[        R                  " 5         [        R                  " [
        R                  US9   U" XS9u  pVU(       a  SOSn[        R                  " S	UR                   S
U SU 35        g! [         a8  n[        R                  " SU 3SS9  [
        R                  " S5         SnAgSnAff = f)z5Import a single JSON analysis file into the database.r   )Úimport_json_filer$   r%   r&   )r¦   ú with embeddingsrƒ   õ   âœ“ Imported rc   rL   õ   âœ— Import failed: Tr0   r2   N)Úquber.db.importerr¨   r   rM   rN   rO   rP   rT   rU   Úfilenamer?   rV   )	rh   r¦   r"   r¨   r(   rG   Útable_countÚemb_msgrF   s	            r   Úimport_jsonr°   y  s�   € õ 3æ"‘¨€IÜ
‡M‚M„OÜ
‡J‚JŒs�z‰z Ò+ðÙ+¨IÑ_ÑˆÞ(;Ñ$ÀˆÜ�
Š
�] 3§<¡< .°°;°-¸wÀwÀiÐPÕQøÜó Ü�
Š
Ð(¨¨Ð,°$Ò7Ü�Š��‰ûðúó   Á<B Â
C
Â.CÃC
z*_analysis.jsonz0File pattern to match (default: *_analysis.json)c                 óš  • SSK Jn  U(       a  SOSn[        R                  " 5         [        R                  " [
        R                  US9   U" XUS9u  pgU(       a  SOSn[        R                  " S	[        U5       S
U SU 35        g! [         a8  n	[        R                  " SU	 3SS9  [
        R                  " S5         Sn	A	gSn	A	ff = f)z0Import all JSON analysis files from a directory.r   )Úimport_directoryr$   r%   r&   )r_   r¦   r©   rƒ   rª   z documents with rs   r«   Tr0   r2   N)r¬   r³   r   rM   rN   rO   rP   rT   rU   rv   r?   rV   )
r[   r_   r¦   r"   r³   r(   ÚdocsrK   r¯   rF   s
             r   Ú
import_dirrµ   Ž  s¨   € õ 3æ"‘¨€IÜ
‡M‚M„OÜ
‡J‚JŒs�z‰z Ò+ðÙ-ØÐ<Oñ
Ñˆö )<Ñ$ÀˆÜ�
Š
�]¤3 t£9 +Ð-=¸l¸^È=ÐY`ÐXaÐbÕcøÜó Ü�
Š
Ð(¨¨Ð,°$Ò7Ü�Š��‰ûðúr±   c           
      óÜ  • SSK Jn  U (       a  SOSn[        R                  " 5         [        R                  " [
        R                  US9   U" 5       n[        R                  " S5        [        R                  " S5        [        R                  " SUS	    35        [        R                  " S
US    35        [        R                  " SUS    35        US   (       aL  [        R                  " S5        US    H,  n[        R                  " SUS    SUS    SUS    S35        M.     gg! [         a8  n[        R                  " SU 3SS9  [
        R                  " S5         SnAgSnAff = f)zShow database statistics.r   )Úget_import_statsr$   r%   r&   z
Database Statisticsr   zTotal documents: ry   zTotal tables: rK   zAvg tables/doc: Úavg_tables_per_docÚ	documentsz
Documents:r†   r­   rc   Útablesz	 tables, Úpagesú pagesu   âœ— Failed to retrieve stats: Tr0   r2   N)r¬   r·   r   rM   rN   rO   rP   rT   rU   r?   rV   )r"   r·   r(   Ú
stats_datarG   rF   s         r   Ústatsr¾   ¦  s-  € õ 3æ"‘¨€IÜ
‡M‚M„OÜ
‡J‚JŒs�z‰z Ò+ðÙ%Ó'ˆ
ä�
Š
Ð*Ô+Ü�
Š
�8ÔÜ�
Š
Ð& zÐ2CÑ'DÐ&EÐFÔGÜ�
Š
�^ J¨~Ñ$>Ð#?Ð@ÔAÜ�
Š
Ð% jÐ1EÑ&FÐ%GÐHÔIà�k×"Ü�JŠJ�~Ô&Ø! +Ô.�Ü—
’
˜V C¨
¡OÐ#4°B°s¸8±}°oÀYÈsÐSZÉ|ÈnÐ\bÐcÖdò /ð #øô
 ó Ü�
Š
Ð3°A°3Ð7¸TÒBÜ�Š��‰ûðús   ÁCD) Ä)
E+Ä3.E&Å&E+ÚlocalÚopenaiz&Embedding provider (default: from env)z--deviceÚcudaÚcpuz&Device for local model (default: cuda)z--batch-sizeé    z'Batch size for processing (default: 32)ÚdeviceÚ
batch_sizec           	      ó¼  • SSK JnJnJn  U(       a  SOSn[        R
                  " 5         [        R                  " [        R                  US9   [        R                  " S5        U" XS9n[        R                  " S5        U" 5        n	U	R                  U5      R                  5       n
[        U
5      nUS:X  a   [        R                  " S	5         S
S
S
5        g
[        R                  " SU S35        Sn[        U
S5       H·  u  pÞUR                  (       d  M  UR                   (       d  M+  UR#                  UR                  UR                   5      nUR%                  5       Ul        UR%                  5       Ul        US-  nXÒ-  S:X  d  MŠ  U	R+                  5         [        R                  " SU SU S35        M¹     U	R+                  5         [        R                  " SU SU S35        S
S
S
5        g
! , (       d  f       g
= f! [,         aN  n[        R                  " SU 3SS9  [        R.                  " U5        [        R0                  " S5         S
nAg
S
nAff = f)z3Generate embeddings for all tables in the database.r   )ÚExtractedTableÚget_embedding_serviceÚget_sessionr$   r%   r&   z!Initializing embedding service...)r   rÄ   zLoading tables from database...zNo tables found in databaseNra   z tables to processr2   z  Processed rr   z
 tables...u   âœ“ Generated embeddings for rL   u#   âœ— Failed to generate embeddings: Tr0   )Úquber.dbrÇ   rÈ   rÉ   r   rM   rN   rO   rP   rT   rU   Úqueryr{   rv   Ú	enumerateÚ	llm_titleÚllm_descriptionÚembed_table_metadataÚtolistÚtitle_embeddingÚdescription_embeddingÚcommitr?   Ú	exceptionrV   )r   rÄ   rÅ   r"   rÇ   rÈ   rÉ   r(   Úembedding_serviceÚsessionrº   ÚtotalÚupdatedÚiÚtableÚ	embeddingrF   s                    r   r¦   r¦   Ã  sÑ  € ÷ LÑKæ"‘¨€IÜ
‡M‚M„OÜ
‡J‚JŒs�z‰z Ò+ð&Ü�
Š
Ð6Ô7Ù1¸8ÑSÐä�
Š
Ð4Ô5ÙŒ]˜gØ—]‘] >Ó2×6Ñ6Ó8ˆFÜ˜“KˆEà˜‹zÜ—
’
Ð8Ô9Ø÷ ˆ]ô �JŠJ˜ ˜wÐ&8Ð9Ô:ð ˆGÜ% f¨aÖ0‘�Ø—?—?‘? u×'<×'<Ñ'<à 1× FÑ FÀuÇÁÐX]×XmÑXmÓ n�Ið -6×,<Ñ,<Ó,>�EÔ)Ø2;×2BÑ2BÓ2D�EÔ/Ø˜q‘L�Gà‘~¨Õ*ØŸ™Ô(ÜŸ
š
 \°!°°A°e°W¸JÐ#GÖHñ 1ð �N‰NÔÜ�JŠJÐ6°w°i¸qÀÀÀwÐOÔP÷9 �]Ž]ûô< ó Ü�
Š
Ð8¸¸Ð<À$ÒGÜ×Ò˜ÔÜ�Š��‰ûðúsX   Á9H ÂAG2ÃH Ã<G2ÄG2Ä,AG2ÆAG2Ç)H Ç2
H Ç<H È H È
IÈAIÉIÚdocument)rd   z-Output directory (local path or s3:// prefix)z--formatÚfmt)ÚmarkdownÚjsonÚbothrà   z/Output format(s) for the parsed DoclingDocumentz--htmlz^Also export html_split_page alongside markdown/json (matches docling CLI --to html_split_page)z--image-mode)ÚembeddedÚ
referencedÚplaceholderrâ   zkHow images are written in the markdown export (default: referenced, matching tuned-financial canonical CLI))ÚautorÁ   rÂ   Úmpsrä   z}Accelerator device. Default 'auto' resolves to cuda when available, otherwise cpu (so an Intel MacBook 'just works', slower).ÚhtmlÚ
image_modec                 ó  • SSK Jn  SSKJn  SSKJn	  U	" UU" U5      S9n
[        U 5      n[        R                  " SU SU SU  35        U
R                  U5      nUR                  nUR                  nU" U5      n[        U5       nUR                  UU5      n[        R                  " S	US
    35        [        R                  " SUS    35        [        R                  " SUS    35        US;   a1  UU S3-  nUR                  UUS9  [        R                  " SU 35        U(       a2  UU S3-  nUR                  UUSS9  [        R                  " SU 35        SSS5        [        R                  " S[!        UR"                  5       35        [        R                  " S[!        UR$                  5       35        ['        S UR(                   5       5      n[        R                  " SU 35        g! , (       d  f       Nœ= f)aá  
Run the `Parser` path: source PDF -> DoclingDocument.

Writes the document as markdown and/or JSON. No LLM inference.

By default uses the canonical `tuned-financial` configuration adopted in
QUE-218 (TableFormerMode.ACCURATE, DoclingParse backend, OCR enabled,
picture classification, page_batch_size=32) with `--device auto` resolving
to CUDA when available (QUE-219). Pass `--preset legacy` to revert to
the pre-QUE-218 behaviour, or `--device cpu` to force CPU on a GPU host.
r   )ÚAcceleratorDevice©ÚImageRefMode©Úparser_for_preset)Úaccelerator_devicez	Parsing (z	, device=ú): ú
  - JSON: rÜ   z  - Confidence/provenance: Ú
confidencez  - Parsed cells: Úcells)rÞ   rà   z.docling.md©rç   z  - Markdown: z.docling.htmlT©rç   Úsplit_page_viewz  - HTML (split-page): Nú  - Pages: ú  - Tables: c              3   óH   #   • U  H  oR                   S :X  d  M  Sv •  M     g7f)Úocrr2   N)Úverdict)rn   r“   s     r   rp   Úparse.<locals>.<genexpr>^  s   é € ÐNÒ 7˜1¿9¹9ÈÑ;M—Q‘QÒ 7ùs   ‚"™	"z,  - Tables read by OCR (rendered as image): )Ú%docling.datamodel.accelerator_optionsré   Údocling_core.types.doc.baserë   Úquber.core.parsersrí   r   rT   rU   ÚparserÜ   r;   r   ÚsaveÚsave_as_markdownÚsave_as_htmlrv   r»   rº   rw   Útable_provenance)r   r   rÝ   ræ   rç   r!   rÄ   ré   rë   rí   ÚparserrG   rg   rÜ   ÚbaseÚimage_ref_modeÚoutÚ	artifactsÚmd_pathÚ	html_pathÚ
ocr_tabless                        r   rÿ   rÿ   û  sÖ  € õj HÝ8å4áØÙ,¨VÓ4ñ€Fô ˜8Ó
$€Cä	‡J‚J�˜6˜( )¨F¨8°3°x°jÐAÔBØ�\‰\˜#Ó€FØ�‰€Hà�8‰8€DÙ! *Ó-€Nô
 
�ZÔ	  Cð
 —K‘K  TÓ*ˆ	Ü�
Š
�Z 	¨*Ñ 5Ð6Ð7Ô8Ü�
Š
Ð0°¸<Ñ1HÐ0IÐJÔKÜ�
Š
Ð'¨	°'Ñ(:Ð';Ð<Ô=àÐ&Ó&Ø˜t˜f KÐ0Ñ0ˆGØ×%Ñ% g¸.Ð%ÑIÜ�JŠJ˜¨ yÐ1Ô2ÞØ   mÐ4Ñ4ˆIØ×!Ñ! )¸ÐX\Ð!Ñ]Ü�JŠJÐ0°°Ð<Ô=÷# 
!ô& 
‡J‚J�œS §¡Ó0Ð1Ð2Ô3Ü	‡J‚J�œc (§/¡/Ó2Ð3Ð4Ô5ÜÑN × 7Ò 7ÓNÓN€JÜ	‡J‚JÐ=¸j¸\ÐJÕK÷- 
!Õ	 ús   ÂCG3Ç3
HÚadeÚsourcezaADE parse model (default: the generally-available dpt-2; dpt-3 preview names route to the v2 API)z--pagez&Submit only this 1-based page of a PDFÚpagec                 óŒ  • SSK Jn  SSKJn  U" XU=(       d    UUS9n[        R
                  " SUR                   SU  3U(       a  SU 3OS-   5        UR                   H  n[        R
                  " S	U 35        M     [        R
                  " S
UR                   35        [        R
                  " SUR                   35        g)aœ  
Parse a PDF or image through Landing.AI ADE.

A standalone extraction path for what docling handles poorly: charts
(the parse reads a chart's plotted values off the page) and rasterized
pages with no native text layer. Writes the raw parse response and the
parse markdown, then a completion marker.

To read the charts in a document into its parse, use `quber figure`, which
scans only the pages that hold one.
r   )Ú	run_parse)ÚDEFAULT_MODEL)r   r   r  zADE parse (rï   z page rƒ   ú  - rö   ú  - Credits consumed: N)
Úquber.providers.landingr  Úquber.providers.landing.clientr  rT   rU   Úmodel_versionr  r»   Úcredits)r  r   r   r  r  r  Úsummaryrd   s           r   r  r  b  s¡   € õ* 2Ý<á˜¸U×=SÀmÐZ^Ñ_€GÜ	‡J‚J�˜W×2Ñ2Ð3°3°v°hÐ?ÖVZÀVÈDÈ6Á?Ð`bÑcÔdØ×!Ô!ˆÜ�
Š
�T˜$˜�=Ö!ñ "ä	‡J‚J�˜WŸ]™]˜OÐ,Ô-Ü	‡J‚JÐ'¨¯©Ð'8Ð9Õ:r   Úfigurez--parsea  The parse to enrich: a DoclingDocument JSON file, or a directory holding one, searched for <base>.unified.json then <base>.docling.json. The enriched parse is written back under the same filename, so pointing --output-dir at the directory it came from replaces it)Úrequiredr   z¯ADE scan model. Defaults to the pinned dpt-3 version; 'dpt-3' selects that same pin, 'dpt-2' reverts to the previous line, and any exact ADE model name passes through as givenz--pagesÚ	nominatedzšPage breadth: 'nominated' scans the pages the parse points at; 'all' scans every page, for documents whose content the parse cannot be trusted to point atrÿ   r»   c                 ót  • SSK JnJn  SSKJnJnJn	  SSKJn
  Ub  UR                  5       S:X  a  U
n[        U 5      nUR                  nU" X5      u  pÞ[        U5      R                  5       (       a  [        U5      O[        U5      R                  nXü S3-  nSnUR                  5       (       a8  [         R"                  " UR%                  SS	95       Vs0 s H	  nUS
   U_M     nnO![&        R(                  " SUR*                  5        [,        R,                  " 5       n U" UUUUUUUUU" 5       U" 5       S9
nUR6                  n[8        R:                  " SU  35        UR<                   H  n[8        R:                  " SU 35        M     [8        R:                  " SUR>                   35        [8        R:                  " SUR@                   SURB                   S35        [8        R:                  " SURD                   35        [8        R:                  " S[G        URH                  5       35        [8        R:                  " S[G        URJ                  5       35        URL                  be  [8        R:                  " S[G        URL                  RL                  5       SURL                  RN                   SURL                  RP                   S35        [8        R:                  " SURR                   35        URT                   H  n[8        R:                  " SU 35        M     U	" UUS UUR<                  U[W        S! URX                   5       S5      UR>                  UR@                  URB                  URD                  [G        URH                  5      [G        URJ                  5      URR                  URT                  [5        [,        R,                  " 5       U-
  S5      S".5        gs  snf ! [.         aO  nU	" UUSUSU[1        U5      R2                   SU 3[5        [,        R,                  " 5       U-
  S5      S.5        e SnAff = f)#aŒ  
Read the imagery in a document into its parse.

Three things a page prints are read by nothing else in the pipeline: the
values plotted in a chart, the content of any other picture, and a table
printed as an image, whose cells the parse read off the page itself with
nothing having checked it since. This reads all three through Landing.AI ADE.

The parse nominates the pages holding them, and every nominated page is
scanned; --pages all widens the run to every page of the document. Each page
is submitted whole, so a chart's title above it and the note at the foot
of the page come back with it, and a table comes back as a grid with a box on
every cell, which replaces the parse's reading of it.

Independent of the rest of the pipeline: in, the parse and the source
document; out, the same parse enriched, and the page scans. Writes the raw
response per page scanned, the figure records, the enriched parse under the
filename it was read from, then a completion marker. A page already scanned
is read from its stored response instead of being paid for again.

Run it after `quber fuse` so the enrichment lands in the document the rest
of the pipeline reads.
r   )Úget_figure_value_readerÚget_scan_value_parser)Úload_documentÚrun_figures_syncÚwrite_marker)ÚSCAN_DEFAULT_MODELNzdpt-3ú.cells.jsonúutf-8©ÚencodingÚpage_noz-No {} beside the parse; figure values skipped)r   r   r»   Úcells_pagesÚvalue_parserÚvalue_readerÚfailedr  rc   r2   )r–   rÜ   Ústager   r@   Útotal_secondszFigure scan: r  z  - Pages nominated: z  - Pages scanned: ú (z submitted this run)z  - Pages returning a figure: z  - Figure records: z"  - Tables read off a page image: z  - Figure values: z reconciled, z	 flagged)r  z  - ERROR: Úcompletec              3   ó^   #   • U  H#  oR                   (       d  M  UR                   v •  M%     g 7f©Nr   )rn   Úss     r   rp   Úfigure.<locals>.<genexpr>  s   é € Ð"M²i°Ç9Å9£9 1§9¦9²iùs   ‚-š-)r–   rÜ   r  r   r  Úpages_nominatedÚpages_scannedÚpages_submittedÚpages_returning_a_figureÚfigure_recordsÚscanned_tablesÚcredit_usageÚerrorsr-  )-Úquber.agents.figure_valuesr  r  Úquber.core.figures.orchestratorr  r   r!  Úquber.core.figures.scanr"  Úlowerr   r;   r   Úis_dirÚparentr\   rß   ÚloadsÚ	read_textr   Úwarningrd   Útimer?   r   Ú__name__ÚroundrX   rT   rU   r  r  ÚscannedÚ	submittedÚwith_figuresrv   Úfiguresrº   ÚvaluesÚ
reconciledÚflaggedr  r;  ÚnextÚscans)r  rÿ   r   r   r»   r  r  r  r   r!  r"  r¿   r  rÜ   Ú
parse_nameÚ	parse_dirÚ
cells_pathr(  r“   Ústartedrg   ÚexcrX   rd   r1   s                            r   r  r  ‚  s‹  € ÷b Zß]Ñ]Ý:ð �}˜Ÿ™›¨Ó0Ø"ˆä˜VÓ$€EØ�:‰:€DÙ(¨Ó5Ñ€Hô
  $ E›{×1Ñ1×3Ñ3”�U”¼¸e»×9KÑ9K€IØ˜v [Ð1Ñ1€JØ€KØ×Ñ×ÑÜ04·
²
¸:×;OÑ;OÐY`Ð;OÐ;aÔ0bÓcÒ0b¨1�q˜‘| Q’Ñ0bˆÐcˆä�ŠÐFÈ
ÏÉÔXä�iŠi‹k€GðÙ!ØØØØØ!ØØØ#Ù.Ó0Ù0Ó2ñ
ˆð6 �*‰*€CÜ	‡J‚J�˜v˜hÐ'Ô(Ø× Ô ˆÜ�
Š
�T˜$˜�=Ö!ñ !ä	‡J‚JÐ& s§}¡} oÐ6Ô7Ü	‡J‚JÐ$ S§[¡[ M°°C·M±M°?ÐBVÐWÔXÜ	‡J‚JÐ/°×0@Ñ0@Ð/AÐBÔCÜ	‡J‚JÐ%¤c¨#¯+©+Ó&6Ð%7Ð8Ô9Ü	‡J‚JÐ3´C¸¿¹Ó4FÐ3GÐHÔIØ‡}�}Ñ Ü�
Š
Ø!¤# f§m¡m×&:Ñ&:Ó";Ð!<ð =Ø—‘×(Ñ(Ð)¨°v·}±}×7LÑ7LÐ6MÈYðXô	
ô 
‡J‚JÐ'¨¯© }Ð5Ô6Ø�zŒzˆÜ�
Š
�[  Ð&Ö'ñ ñ ØØà ØØ×)Ñ)ð Ü!Ñ"M°c·i²iÓ"MÈtÓTØ"Ÿ}™}Ø Ÿ[™[Ø"Ÿ}™}Ø(+×(8Ñ(8Ü! #§+¡+Ó.Ü! &§-¡-Ó0ØŸK™KØ—j‘jÜ"¤4§9¢9£;°Ñ#8¸!Ó<ñ!	
õùòg døô$ ó ÙØØà"Ø Ø!ØÜ  ›I×.Ñ.Ð/¨r°#°Ð7Ü!&¤t§y¢y£{°WÑ'<¸aÓ!@ñô	
ð 	ûðús   ÃOÄO Ï
P7Ï(A
P2Ð2P7rÚ   z--llm-backend)r   ÚapiÚmockz7LLM client backend (default: $QUBER_LLM_BACKEND or api)z--no-llmz<Skip the LLM structure-correction step (Camelot-only output)z--dpiéÈ   zPage rasterization DPIz--engine)úset-of-markzcamelot-llmÚcorrespondencerY  zÙExtraction engine (default: set-of-mark). set-of-mark: vision locates each table and its region, Camelot fills it in-region, grounded correction cleans structure. camelot-llm and correspondence are DEPRECATED/dormant.z--reviewub  Also write human-reviewable artifacts beside the JSON: a before/after HTML (source region + bounding box | corrected markdown), an annotated PDF (Set-of-Mark boxes drawn on the source pages), and â€” when any table carries flagged decisions â€” the flags HTML review queue. Renders from the tables already extracted, so it adds no extraction or LLM cost.Úllm_backendÚno_llmÚdpir¤   Úreviewc                 ó&	  • SSK Jn  SSKJnJn	Jn
  SSKJn  SSKJ	nJ
nJn  UnUS:X  aI  U(       a  [        R                  " S5      eSSKJn  U" XJ" U5      S	9n[         R"                  " S
U  35        OªUS:X  aC  U(       a  [        R                  " S5      eU" XJ" U5      S	9n[         R"                  " SU  35        OaU(       a3  U" U	" 5       U" 5       U" 5       SUS9n[         R"                  " SU  35        O'U" U
" U5      SUS9n[         R"                  " SU  35        [%        U 5      nUR&                  n[(        R(                  " 5       nSn UR+                  U5      nUS:X  aN  [7        S U 5       5      n[7        S U 5       5      n[         R"                  " S[9        U5       SU SU S35        O"[         R"                  " S[9        U5       35        SS KJn  U" U5      nS!n [?        U5       nUU S"3-  nURA                  [B        RD                  " U Vs/ s H  nURG                  5       PM     snS#[H        S$9S%S&9  [         R"                  " S'U 35        U(       ap  UU S(3-  nURA                  [B        RD                  " U V s/ s H  n U RG                  5       PM     sn S#S)9S%S&9  [         R"                  " S*U S+[9        U5       S,35        U(       a�  SS-K%J&n!J'n"J(n#  U#" UU4/UU S.3-  5      n$U!" UUUU S/3-  5      n%[         R"                  " S0U$ 35        [         R"                  " S1U% 35        U"" UU4/UU S23-  5      n&U&(       a  [         R"                  " S3U& 35        SSS5        [/        UU S3S4U[9        U5      [9        U5      [5        [(        R(                  " 5       U-
  S5      S5.5        g! [,         aT  n[/        UU S3SUU[1        U5      R2                   SU 3[5        [(        R(                  " 5       U-
  S5      S.5        e SnAff = fs  snf s  sn f ! , (       d  f       NÂ= f! [,         aT  n[/        UU S3SUU[1        U5      R2                   SU 3[5        [(        R(                  " 5       U-
  S5      S.5        e SnAff = f)6a7  
Run the `TableExtractor` path: source PDF -> list[ExtractedTable].

Engines:

- set-of-mark (default): the page image is the arbiter. The grid locator names
  every table and its region; Camelot extracts each one constrained to its
  box (so it can neither shatter one table into many nor merge many into
  one); the grounded structure-correction LLM cleans headers/spans/merged
  cells without altering a value. One ExtractedTable per visual table.
- camelot-llm (DEPRECATED): both Camelot flavors in parallel; per-candidate
  is_table classification; LLM unify per page; structure-correction.
- correspondence (DEPRECATED): detector lists tables, Camelot chunks matched
  by bbox overlap, completeness-audited, with recovery escalation.

Output is a JSON file of `ExtractedTable` Pydantic models with
provenance fields.
r   ©ÚMockClassifier)ÚBackendÚMockLLMClientÚget_llm_client©ÚMockUnifier)ÚCamelotCorrespondenceExtractorÚCamelotLLMTableExtractorÚTableExtractorrY  zu--no-llm is not supported with --engine set-of-mark; the grounded correction step is part of the set-of-mark capture.©ÚSetOfMarkExtractor©r]  ÚllmzExtracting (SoM): rZ  z--no-llm is not supported with --engine correspondence; the detector/correspondence/completeness flow is LLM-driven end to end.zExtracting (correspondence): F©Ú
llm_clientÚ
classifierÚunifierÚrun_llm_correctionr]  zExtracting: T)ro  rr  r]  Úextractz.tables.complete.jsonr+  rc   r2   ©r–   rÜ   r,  r@   r-  Nc              3   ó„   #   • U  H6  nUR                   (       d  M  UR                   R                  S :X  d  M2  Sv •  M8     g7f)Údetected_not_extractedr2   N©Úextraction_recordr–   ©rn   Úts     r   rp   Úextract.<locals>.<genexpr>œ  s<   é € ð %
â�Ø×"Õ"ó à'(×':Ñ':×'AÑ'AÐE]Ñ']÷ ‰AÚùs   ‚A ›A ·	A c              3   ó‚   #   • U  H5  oR                   (       d  M  UR                   R                  S :X  d  M1  Sv •  M7     g7f)Ú
incompleter2   Nrw  ry  s     r   rp   r{  ¡  s1   é € ð 
Ú�!×!4Õ!4‹A¸×9LÑ9L×9SÑ9SÐWcÑ9c�A‰A’vùs   ‚?š?¶	?r÷   z (detected-not-extracted: z, incomplete: r‡   ©Ú
cell_flagsÚwrite_artifactsú.tables.jsoné   ©Úindentr   r$  r%  rð   ú.flags.json©r„  ú  - Flags: r.  ú review item(s))©Úrender_annotated_pdfÚrender_flags_htmlÚrender_review_htmlú.review.htmlú
.boxed.pdfz  - Review HTML: ú  - Annotated PDF: ú.flags.htmlú  - Flags HTML (review queue): r/  )r–   rÜ   rº   Úflagsr-  ))Úquber.agents.classifierra  Úquber.agents.llm_clientrb  rc  rd  Úquber.agents.unifierrf  Úquber.core.extractorsrg  rh  ri  rT   Ú
UsageErrorÚ!quber.core.extractors.set_of_markrk  r   Úinfor   r;   rE  Úextract_tables_syncr?   r   r   rF  rG  rw   rv   Úquber.core.extractors.baser  r   Ú
write_textrß   ÚdumpsÚ
model_dumpr=   Úquber.reviewrŠ  r‹  rŒ  )'r   r   r[  r\  r]  r¤   r^  ra  rb  rc  rd  rf  rg  rh  ri  Úbackend_litrk  Ú	extractorr  r  rT  r,  rº   rU  rv  r}  r  r’  r  rh   rz  Ú
flags_pathÚfrŠ  r‹  rŒ  r
  Ú
boxed_pathÚ
flags_htmls'                                          r   rs  rs    s®  € õv 7ßNÑNÝ0÷ñ ð &1€Kà�ÓÞÜ×"Ò"ðFóð õ 	Iá&¨3°NÀ;Ó4OÑPˆ	Ü�ŠÐ(¨¨
Ð3Õ4Ø	Ð#Ó	#ÞÜ×"Ò"ðVóð ñ 3°sÀÈ{Ó@[Ñ\ˆ	Ü�ŠÐ3°H°:Ð>Õ?Þ	ñ -Ù$“Ù%Ó'Ù“MØ$Øñ
ˆ	ô 	�Š�l 8 *Ð-Õ.á,Ù% kÓ2Ø#Øñ
ˆ	ô
 	�Š�l 8 *Ð-Ô.ô
 ˜hÓ'€FØ�;‰;€Dô �iŠi‹k€GØ€EðØ×.Ñ.¨vÓ6ˆð Ð!Ó!Ü!$ñ %
áó%
ó "
Ðô
 ñ 
Ùó
ó 
ˆ
ô 	�ŠØœ3˜v›;˜-ð ((Ø(>Ð'?¸~ÈjÈ\ÐYZð\õ	
ô
 	�Š�l¤3 v£; -Ð0Ô1õ
 6á�vÓ€Eð €Eð$Ü˜Ô$¨Ø   lÐ3Ñ3ˆIØ× Ñ Ü—
’
±FÓ;²F¨q˜AŸL™LžN±FÑ;ÀAÌsÑSÐ^eð !ñ ô �KŠK˜* Y KÐ0Ô1æØ  d V¨;Ð#7Ñ7�
Ø×%Ñ%¤d§j¢jÉ%Ó1PÊ%ÀQ°!·,±,¶.É%Ñ1PÐYZÑ&[ÐfmÐ%ÑnÜ—’˜k¨*¨°R¼¸E»
°|ÐCSÐTÔUæçdÑdá.°¸Ð0@Ð/AÀ3ÈDÈ6ÐQ]ÐI^ÑC^Ó_�	Ù1°&¸&À#È4È&ÐPZÐH[ÑB[Ó\�
Ü—’Ð/°	¨{Ð;Ô<Ü—’Ð1°*°Ð>Ô?Ù.°¸Ð0@Ð/AÀ3ÈDÈ6ÐQ\ÐI]ÑC]Ó^�
ÞÜ—K’KÐ"AÀ*ÀÐ NÔO÷- %ôJ ØØˆ&Ð%Ð&à ØÜ˜&“kÜ˜“ZÜ"¤4§9¢9£;°Ñ#8¸!Ó<ñ	
õ
øô] ó ÜØØˆfÐ)Ð*à"Ø ØÜ  ›I×.Ñ.Ð/¨r°#°Ð7Ü!&¤t§y¢y£{°WÑ'<¸aÓ!@ñô
	
ð 	ûðüòX <ùò 2Q÷ %Õ$ûô. ó ÜØØˆfÐ)Ð*à"Ø ØÜ  ›I×.Ñ.Ð/¨r°#°Ð7Ü!&¤t§y¢y£{°WÑ'<¸aÓ!@ñô
	
ð 	ûðúsp   ÅN6 Ç#P2 Ç.(P!ÈPÈ0AP!ÊPÊCP!Í%P2 Î6
PÏ APÐPÐ
P!Ð!
P/Ð+P2 Ð/P2 Ð2
RÐ<ARÒRzOutput directoryz--no-classifyzKSkip the is_table tagging on Camelot grids (grids still returned, untagged)Úno_classifyc                 óJ  • SSK Jn  [        U 5      nU" X#(       + S9n[        R                  " SU  35        UR                  U5      n[        U5      nUR                  SSS9  UR                  n	X‰ S3-  n
U
R                  [        R                  " UR                  5       S[        S	9S
S9  UR                  5       nUR                  5       n[!        [#        U5      [#        U5      -  5      n[        R                  " S[%        UR&                  5       S[%        UR(                  5       35        [        R                  " S5        U HB  n[        R                  " SU SUR+                  US5       SUR+                  US5       35        MD     [        R                  " SU
 35        g)ua  
Run the two first-class flows side by side: source PDF -> DualResult.

The visual flow looks at each rendered page and lets the grid locator
own the table count and identity; the Camelot flow pulls cell grids
straight from the PDF and tags each with an is_table verdict (metadata
only â€” it never drops a grid). The two run concurrently and neither is
matched to the other: this is the un-reconciled input for a later
cross-reference step. No detector, box repair, recovery, or escalation.

PDF_PATH may be a local path or an s3:// URI; s3 inputs materialize
through the persistent cache before extraction.
r   )ÚDualFlowExtractor)r]  Úclassify_camelotzDual extraction: Tr4   z
.dual.jsonr‚  rƒ  r$  r%  z  - Visual tables: z   Camelot grids: z   - Per page (visual | camelot):z      prc   z | rð   N)Úquber.core.extractors.dualr¨  r   rT   rU   Úrun_syncr   r:   r;   rœ  rß   r�  rž  r=   Úvisual_count_by_pageÚcamelot_count_by_pageÚsortedÚsetrv   ÚvisualÚcamelotrŽ   )r   r   r]  r¦  r¨  r  r¡  rg   r  r  rh   Úvisual_by_pageÚcamelot_by_pager»   r“   s                  r   Údualr´  è  sh  € õ. =ä˜hÓ'€FÙ! c¼OÑL€IÜ	‡J‚JÐ" 8 *Ð-Ô.Ø×Ñ Ó'€Fä
ˆzÓ
€CØ‡I�I�d T€IÑ*Ø�;‰;€DØ˜˜jÐ)Ñ)€IØ×ÑœŸš F×$5Ñ$5Ó$7ÀÌ3ÑOÐZaÐÑbà×0Ñ0Ó2€NØ×2Ñ2Ó4€OÜ”3�~Ó&¬¨_Ó)=Ñ=Ó>€EÜ	‡J‚JÐ$¤S¨¯©Ó%7Ð$8Ð8JÌ3ÈvÏ~É~ÓK^ÐJ_Ð`ÔaÜ	‡J‚JÐ1Ô2ÛˆÜ�
Š
�W˜Q˜C˜r .×"4Ñ"4°Q¸Ó":Ð!;¸3¸×?RÑ?RÐSTÐVWÓ?XÐ>YÐZÖ[ñ ä	‡J‚J�˜I˜;Ð'Õ(r   z--artifacts-dira  Cloud-style standalone fusion: load the document artifacts (<base>.{docling,confidence,cells}.json) and the table artifact (<base>.tables.json) from this directory and fuse only, skipping both engines. Without it, the document and table extractions run in-process.)r   r   rá   záHow pictures are written in the unified markdown/HTML. embedded (default) inlines them base64 so the files are self-contained; referenced writes a sidecar image folder and links it; placeholder drops them to '<!-- image -->'.us  Also write the human-reviewable control artifacts from both workflows: the table-side before/after HTML, annotated PDF (Set-of-Mark boxes on the fused tables), and â€” when any table carries flagged decisions â€” the flags HTML review queue, plus the document-side split-page HTML of the unified DoclingDocument. Rendered from the result already produced, no second pass.Úartifacts_dirc                 óÂ  • SSK Jn  U" U5      n	[        U 5      n
U
R                  n[        R                  " 5       n [        X+X©XXFXq5
        [        UU S3S
U[        [        R                  " 5       U-
  S5      S.5        g	! [         aT  n[        UU S3SUS[        U5      R                   SU 3[        [        R                  " 5       U-
  S5      S.5        e S	nAff = f)aa  
Fuse the document (docling) and table (Set-of-Mark/Camelot) extractions.

Two views of the same page enrich each other: the Camelot bodies move into
the docling spine, regions SoM merged are split, charts and image tables are
annotated, and tables docling found that SoM missed are surfaced explicitly.

Two control flows over one fusion core:

- Local (default): the document and table extractions run in-process, then
  fuse.
- Standalone (--artifacts-dir): load the two extractions' artifacts from a
  directory (as a cloud job would from S3) and fuse only, no engines.

Writes the unified DoclingDocument (markdown + JSON), the corrected
Set-of-Mark/Camelot tables (JSON), and a fusion report (per-region match
kinds and any surfaced errors). With --review, also writes the table-side
before/after HTML and annotated PDF and the document-side split-page HTML.
r   )rd  z.fuse.complete.jsonr+  Úfuserc   r2   rt  Nr/  )r–   rÜ   r-  )r”  rd  r   r;   rE  Ú
run_fusionr?   r   r   rF  rG  )r   r   rµ  r[  r]  r!   rç   r^  rd  rm  r  r  Úfuse_startedrU  s                 r   r·  r·    sé   € õF 7á
˜Ó
%€CÜ˜hÓ'€FØ�;‰;€Dô
 —9’9“;€LðÜ�=¨°XÀsÐX^Ôkô ØØˆ&Ð#Ð$à ØÜ"¤4§9¢9£;°Ñ#=¸qÓAñ	
õøô ó ÜØØˆfÐ'Ð(à"Ø ØÜ  ›I×.Ñ.Ð/¨r°#°Ð7Ü!&¤t§y¢y£{°\Ñ'AÀ1Ó!Eñô
	
ð 	ûðús   ¼B  Â 
CÂ
ACÃCr  rm  c
                 óF  • SSK Jn
Jn  U (       a¶  SSKJn  SSKJn  SSKJn  U" U U S3U S3U S3U S	3/5      n[        R                  " S
U SU 35        UR                  Xñ5      n[        R                  " Xñ S	3-  R                  5       5       Vs/ s H  nU" S60 UD6PM     nn[        R                   " U" UUX#5      5      nOHSSKJn  [        R                  " SU SU 35        U
" ['        U5      U" XcS9US9nUR)                  U5      nSSKJn  SSKJn  U" U5      nU" S UR2                   5       5      n[        R                  " S[5        UR6                  R8                  5       35        [        R                  " S[5        UR8                  5       35        [        R                  " S[;        U5       35        UR<                   H  n[        R>                  " SU 35        M     [A        U	5       nUU S3-  nURC                  [        RD                  " UR6                  RG                  5       SS9SS9  UU S3-  nUR6                  RI                  UUS9  URJ                  bc  UU S3-  nURC                  [        RD                  " URJ                  RL                   Vs/ s H  nURO                  5       PM     snS[P        S9SS9  UU S	3-  n U RC                  [        RD                  " UR8                   Vs/ s H  nURO                  5       PM     snS[P        S9SS9  UU S 3-  n!U!RC                  [        RD                  " [;        U5      UR2                   V"s/ s H  n"U"RO                  5       PM     sn"UR<                  S!.S[P        S9SS9  [        R                  " S"U S#U 35        [        R                  " S$U  35        [        R                  " S%U! 35        SS&KJ)n#  U#" UR8                  5      URT                  -   n$U$(       ap  UU S'3-  n%U%RC                  [        RD                  " U$ V&s/ s H  n&U&RO                  5       PM     sn&SS9SS9  [        R                  " S(U% S)[5        U$5       S*35        U(       aê  SS+K+J,n'J-n(J.n)  U)" UUR8                  4/UU S,3-  5      n*U'" UR8                  UUU S-3-  5      n+UU S.3-  n,UR6                  R_                  U,US/S09  [        R                  " S1U* 35        [        R                  " S2U+ 35        [        R                  " S3U, 35        U(" UUR8                  4/UU S43-  5      n-U-(       a  [        R                  " S5U- 35        SSS5        gs  snf s  snf s  snf s  sn"f s  sn&f ! , (       d  f       g= f)7zSOne fusion run, artifacts in to artifacts out. The command wrapper owns the marker.r   )ÚDocumentFusionÚfuse_artifacts)rÇ   )ÚParseResult)Úresolve_artifactsz.docling.jsonz.confidence.jsonr#  r�  zFusing from artifacts (rï   rj  zFusing (rl  )r  r¡  rm  )ÚCounterrê   c              3   ó8   #   • U  H  oR                   v •  M     g 7fr1  )Úkind)rn   Úms     r   rp   Úrun_fusion.<locals>.<genexpr>±  s   é € Ð3¢N˜q—F–F¢Nùs   ‚z  - Unified document tables: z   - Set-of-Mark/Camelot tables: z  - Match kinds: r  z.unified.jsonr‚  r†  r$  r%  z.unified.mdró   Nrƒ  z.fusion.json)Úmatch_kindsÚmatchesr;  z  - Unified: z / r÷   z  - Report: r~  r…  r‡  r.  rˆ  r‰  r�  rŽ  z.unified.htmlTrô   z  - Review HTML (tables): r�  z  - Unified HTML (split-page): r�  r‘  r   )0Úquber.core.fusionr»  r¼  r›  rÇ   rþ   r½  Úquber.files.cacher¾  r   r™  Úloadrß   rB  rC  rW   rX   r˜  rk  Úparser_for_preset_lazyÚ	fuse_syncÚcollectionsr¿  rý   rë   rÅ  rv   rÜ   rº   Údictr;  r@   r   rœ  r�  Úexport_to_dictr  rÿ   r»   rž  r=   r  Úheading_flagsrŸ  rŠ  r‹  rŒ  r  ).rµ  r  r  rm  r   r!   r]  rç   r^  r   r»  r¼  rÇ   r½  r¾  Úadirrÿ   rz  Ú
som_tablesrg   rk  Úfusionr¿  rë   r  Úkindsr1   r  Úunified_jsonÚ
unified_mdÚ
cells_jsonr“   Útables_jsonÚreport_jsonrÂ  r  r’  r¢  r£  rŠ  r‹  rŒ  Úreview_htmlÚ	boxed_pdfÚunified_htmlr¥  s.                                                 r   r¸  r¸  }  s<  € ÷ AæÝ=Ý2Ý7ñ !Øà�&˜Ð&Ø�&Ð(Ð)Ø�&˜Ð$Ø�&˜Ð%ð	ó
ˆô 	�ŠÐ-¨d¨V°3°x°jÐAÔBØ× Ñ  Ó,ˆÜ37·:²:¸tÈÈlÐF[Ñ?[×>fÑ>fÓ>hÔ3iÓjÒ3i¨a‘nÑ) qÔ)Ñ3iˆ
ÐjÜ—’™^¨E°:¸vÓKÓL‰åHä�Š�h˜v˜h c¨(¨Ð4Ô5ÙÜ)¨&Ó1Ù(¨SÑ:Øñ
ˆð
 ×!Ñ! &Ó)ˆå#å8á! *Ó-€NáÑ3 F§N¢NÓ3Ó3€EÜ
‡K‚KÐ/´°F·O±O×4JÑ4JÓ0KÐ/LÐMÔNÜ
‡K‚KÐ2´3°v·}±}Ó3EÐ2FÐGÔHÜ
‡K‚KÐ#¤D¨£K =Ð1Ô2Ø�}Œ}ˆÜ�Š�t˜C˜5�\Ö"ñ ô 
�ZÔ	  CØ ˜v ]Ð3Ñ3ˆØ×Ñ¤§
¢
¨6¯?©?×+IÑ+IÓ+KÐTUÑ VÐahÐÑiØ˜d˜V ;Ð/Ñ/ˆ
Ø�‰×(Ñ(¨ÀÐ(ÑOð �<‰<Ñ#Ø $  {Ð3Ñ3ˆJØ×!Ñ!Ü—
’
°F·L±L×4FÒ4FÓGÒ4F¨q˜AŸL™LžNÑ4FÑGÐPQÔ[^Ñ_Ø ð "ñ ð
 ˜t˜f LÐ1Ñ1ˆØ×ÑÜ�JŠJ°·²Ó>²¨1˜Ÿ™ž±Ñ>ÀqÔRUÑVØð 	ñ 	
ð
 ˜t˜f LÐ1Ñ1ˆØ×ÑÜ�JŠJä#'¨£;Ø8>¿ºÓGº°1 §¡¦¹ÑGØ$Ÿm™mñð
 Üñð ð 	ñ 	
ô 	�Š�m L >°°Z°LÐAÔBÜ�Š�l ; -Ð0Ô1Ü�Š�l ; -Ð0Ô1å9á˜6Ÿ=™=Ó)¨F×,@Ñ,@Ñ@ˆÞØ $  {Ð3Ñ3ˆJØ×!Ñ!¤$§*¢*ÁeÓ-LÂeÀ¨a¯l©l®nÁeÑ-LÐUVÑ"WÐbiÐ!ÑjÜ�KŠK˜+ j \°´C¸³J°<Ð?OÐPÔQæ÷
 aÑ`á,¨v°v·}±}Ð.EÐ-FÈÐQUÐPVÐVbÐNcÑHcÓdˆKÙ,¨V¯]©]¸FÀCÈTÈFÐR\ÐJ]ÑD]Ó^ˆIØ D 6¨Ð!7Ñ7ˆLØ�O‰O×(Ñ(¨À.ÐbfÐ(ÑgÜ�KŠKÐ4°[°MÐBÔCÜ�KŠKÐ-¨i¨[Ð9Ô:Ü�KŠKÐ9¸,¸ÐHÔIÙ*¨V°V·]±]Ð,CÐ+DÀcÈtÈfÐT_ÐL`ÑF`ÓaˆJÞÜ—’Ð=¸j¸\ÐJÔK÷C 
!Ð	 ùò5 kùòP Hùò ?ùò  Hùò" .M÷] 
!Õ	 úsL   ÂU9Ç6B.VÊ$U>Ê>?VË=VÌA	VÍ VÍ:B<VÐ6VÑD VÕ>VÖ
V c                 ó   • SSK Jn  U" U 5      $ )zABuild a parser, importing the GPU/ML stack only when fusion runs.r   rì   )rþ   rí   )r!   rí   s     r   rÉ  rÉ  ü  s   € å4á˜VÓ$Ð$r   c                 ó¾  • SSK Jn  SSKJn  SSKJnJn  SSKJn  SSK	J
nJn	  SSKJn
  UnU" U5      nU" UU" 5       U" 5       SUS	9n[        R                  " S
U  35        UR!                  [#        U 5      5      n[$        R&                  " SS9 n[#        U5      nU" XS[)        U5      S9n/ n[+        USS9 H3  u  nnUSUS S3-  nUR-                  US5        UR/                  U5        M5     [        R                  " S[1        U5       S35        U
" [#        U 5      UUU5      nSSS5        WR2                  (       a�  [        R                  " S[1        UR4                  5       S35        UR4                   HO  n[        R                  " SUR6                   SUR8                   SUR:                   SUR<                  S S3	5        MQ     O[        R                  " S 5        UR>                  (       aZ  [        R                  " S![1        UR>                  5       S35        UR>                   H  n[        R                  " S"U 35        M     gg! , (       d  f       GN/= f)#uô   
Run the Camelot-vs-LLM table-count validation hook.

Surfaces page-level mismatches between Camelot's detected count and
the LLM's image-based count. Per plan Â§7, mismatches are surfaced
explicitly; we do not silently judge which is correct.
r   )Úconvert_from_pathr`  )rb  rd  re  )rh  ri  )Úcamelot_vs_llm_count_syncFrn  zExtracting tables: zquber-validate-)ÚprefixÚpng)r]  rÝ   Úoutput_folderr2   )Ústartzpage-Ú04dz.pngÚPNGzRunning validation across r¼   Nz
MISMATCHES (z):z  page z
: camelot=z llm=z (delta z+dr‡   z
No mismatches detected.z	
ERRORS (z  ) Ú	pdf2imagerÝ  r“  ra  r”  rb  rd  r•  rf  r–  rh  ri  Úquber.core.validaterÞ  rT   rU   rš  r   ÚtempfileÚTemporaryDirectoryr=   rÌ   r   re   rv   Úhas_mismatchesÚ
mismatchesr  Úcamelot_countÚ	llm_countÚdeltar;  )r   r[  r]  rÝ  ra  rb  rd  rf  rh  ri  rÞ  r   rm  r¡  rº   ÚtmpÚtmp_pathÚimagesÚpage_imagesrÙ   Úimgr“   ÚreportrÂ  rF   s                            r   Úvalidaterô    sÿ  € õ" ,å6ß?Ý0ßNÝ=à%0€KÙ
˜Ó
%€Cñ !9ØÙ!Ó#Ù“Ø Øñ!€Iô 
‡J‚JÐ$ X JÐ/Ô0Ø×*Ñ*¬4°«>Ó:€Fä	×	$Ò	$Ð,=Ò	>À#Ü˜“9ˆÙ" 8¸%ÌsÐS[Ë}Ñ]ˆØ"$ˆÜ ¨aÔ0‰FˆAˆsØ˜U 1 S '¨Ð.Ñ.ˆAØ�H‰H�Q˜ÔØ×Ñ˜qÖ!ñ 1ô
 	�
Š
Ð/´°KÓ0@Ð/AÀÐHÔIÙ*¬4°«>¸6À;ÐPSÓTˆ÷ 
?ð ××Ü�
Š
�^¤C¨×(9Ñ(9Ó$:Ð#;¸2Ð>Ô?Ø×"Ô"ˆAÜ�JŠJ˜ §¡ ¨
°1·?±?Ð2CÀ5ÈÏÉÈÐU]Ð^_×^eÑ^eÐfhÐ]iÐijÐkÖlò #ô 	�
Š
Ð.Ô/Ø‡}‡}Ü�
Š
�Z¤ F§M¡MÓ 2Ð3°2Ð6Ô7Ø—”ˆAÜ�JŠJ˜˜A˜3�xÖ ò ð ÷% 
?Ö	>ús   ÂBIÉ
Iz--hostz	127.0.0.1z&Interface to bind (default: 127.0.0.1)z--porti¥  z Port to serve on (default: 8101)z--reloadz'Restart on source changes (development)ÚhostÚportÚreloadc                 ó.   • SSK nUR                  SXUS9  g)z'Serve the answering playground web app.r   Nzquber.playground.app:app)rõ  rö  r÷  )ÚuvicornrX   )rõ  rö  r÷  rù  s       r   Ú
playgroundrú  D  s   € ó à‡K�KÐ*°È€KÒPr   rs  c                  ó   • [        5         g)zMain entry point for the CLI.N)r   r   r   r   Úmainrü  Z  s   € ä…Er   Ú__main__)<Ú__doc__rW   rß   rO   rç  rE  Úimportlib.metadatar   Úpathlibr   Útypingr   rT   Úlogurur   Úquber.agents.factoryr   r	   r”  r
   rÇ  r   Úquber.files.outputr   r   Úquber.settingsr   ÚgroupÚversion_optionr   ÚcommandÚargumentÚoptionÚChoicer‹   Úintr=   ÚboolrZ   rz   r”   r�   r¥   r°   rµ   r¾   r¦   rÿ   r  r  rs  r´  r·  r¸  rÉ  rô  rú  Úadd_commandrü  rF  )r“   s   0r   Ú<module>r     sð  ðñ8ót Û Û 
Û Û Ý &Ý Ý ã Ý ç ;Ý -Ý .ß CÝ 'ð ‡‚ƒØ×Ò™g gÓ.Ñ/ñ	ó 0ó ð	ð
 ‡�ƒØ‡‚�
ÓØ‡‚ˆn˜d¨HÐ;_Ñ`Ø‡‚ØØØ	�Š©Ó6ª 1—w”w©Ñ6Ó	7Ø	Añ	ð ‡‚ˆi˜Ð$dÑeØ‡‚Ð ¨!°#Ð<lÑmØ‡‚ØØ	�ŠÐ(¨(Ð3Ó	4ØØ	`ñ	ð ‡‚ˆk˜4¨Ð4LÑMðN/ØðN/àðN/ð �s‰mðN/ð �C‰=ð	N/ð
 ðN/ð ðN/ð óN/ó Nóó nó fóó aó ó ð$N/ðb ‡�ƒØ‡‚� %§*¢*°DÀEÐTXÑ"YÑZØ‡‚ˆn˜d¨HÐ;kÑlØ‡‚Ø�$˜UŸ\š\¹MÓ*JºM°q¯7¬7¹MÑ*JÓKÐRiñð ‡‚ˆi˜Ð$;Ñ<Ø‡‚ØØØ	Ø	Fñ	ð ‡‚ˆk 7Ð1YÑZðN7ØðN7àðN7ð �s‰mðN7ð �C‰=ð	N7ð
 ðN7ð óN7ó [óó =óó mó [ó ðN7ðb ‡�ƒØ‡‚ØØØ	�Š©Ó6ª 1—w”w©Ñ6Ó	7Ø	1ñ	ð ‡‚ˆg�t TÐ0TÑUð7?�X˜c‘]ð 7?¨ó 7?ó Vóó ð7?ðt ‡�ƒñ	ó ð	ð
 ‡�ƒØ‡‚ˆh Ð+fÑgØ‡‚ˆk˜4¨Ð4LÑMðˆtð ˜dó ó Nó hó ðð$ ‡�ƒØ‡‚� %§*¢*°DÑ"9Ñ:Ø‡‚Ð%¨tÐ:]Ñ^Ø‡‚ˆk˜4¨Ð4LÑMð˜3ð °Tð ÀDó ó Nó _ó ;ó ðð" ‡�ƒØ‡‚� %§*¢*°DÀEÐTXÑ"YÑZØ‡‚ˆkÐ#4Ð;mÑnØ‡‚Ð%¨tÐ:]Ñ^Ø‡‚ˆk˜4¨Ð4LÑMð˜#ð ¨ð À$ð ÐQUó ó Nó _ó oó [ó ð
ð& ‡�ƒØ‡‚ˆk˜4¨Ð4LÑMð�4ó ó Nó ðð6 ‡�ƒØ‡‚Ø�u—|’| W¨hÐ$7Ó8Ð?gñð ‡‚ˆj˜uŸ|š|¨V°U¨OÓ<ÐCkÑlØ‡‚ˆn b¨sÐ9bÑcØ‡‚ˆk˜4¨Ð4LÑMð. (¨3¡-ð .¸À#¹ð .ÐTWð .Ðbfó .ó Nó dó móó ð.ðb ‡��*€ÐØ‡‚�
ÓØ‡‚ˆn˜d¨HÐ;jÑkØ‡‚ØØ	Ø	�ŠÒ2Ó	3ØØ	:ñð ‡‚ØØØ	iñð
 ‡‚ØØ	�ŠÒ?Ó	@ØØ	vñ	ð ‡‚ØØ	�ŠÐ(¨(Ð3Ó	4ØØ	`ñ	ð ‡‚ØØ	�ŠÒ4Ó	5Øð 
Iñ	ðCLØðCLàðCLð 
ðCLð ð	CLð
 ðCLð ðCLð óCLóóóóóó ló ó ðBCLðL ‡��%€ÐØ‡‚�ÓØ‡‚ˆn˜d¨HÐ;jÑkØ‡‚ØØØ	lñð
 ‡‚ˆh˜S¨$Ð5]Ñ^ð;�ð ; ð ;¨X°c©]ð ;À(È3Á-ó ;ó _óó ló ó ð;ð. ‡��(€ÐØ‡‚�ÓØ‡‚ØØð
)ñð ‡‚ˆn˜d¨HÐ;jÑkØ‡‚ØØð
ñð ‡‚ØØ	�Š�{ EÐ*Ó	+Øð
Vñ	ðt�3ð t˜sð t°ð t¸HÀS¹Mð tÐRUó tóóó lóó ó ð2tðn ‡��'€ÐØ‡‚�
ÓØ‡‚ˆn˜d¨HÐ;jÑkØ‡‚ØØ	�ŠÒ,Ó	-ØØ	Bñ	ð ‡‚ØØØ	Gñð
 ‡‚ˆg˜s¨Ð3KÑLØ‡‚ØØ	�ŠÒFÓ	GØð
Oñ	ð ‡‚ØØð
OñðsØðsàðsð ˜#‘ðsð ð	sð
 
ðsð ðsð ósóóó Móóó ló ó ð@sðl ‡�ƒØ‡‚�
ÓØ‡‚ˆn˜d¨HÐ;MÑNØ‡‚ˆg˜s¨Ð3KÑLØ‡‚ØØØ	Vñð
")�3ð ") Cð ")¨cð ")Àó ")óó Mó Oó ó ð")ðJ ‡�ƒØ‡‚�
ÓØ‡‚ˆn˜d¨HÐ;jÑkØ‡‚ØØð
Nñð ‡‚ØØ	�ŠÒ,Ó	-ØØ	Bñ	ð ‡‚ˆg˜s¨Ð3KÑLØ‡‚ˆj˜uŸ|š|Ð->ÀÐ,IÓJÐTeÑfØ‡‚ØØ	�ŠÒ?Ó	@Øð
ñ	ð ‡‚ØØð
ñ	ð>Øð>àð>ð ˜C‘=ð>ð ˜#‘ð	>ð
 
ð>ð ð>ð ð>ð ó>ó	óó gó Móóó ló ó ðL>ðB|LØ˜C‘=ð|Là
ð|Lð ð|Lð 
ð	|Lð
 ð|Lð ð|Lð 
ð|Lð ð|Lð ð|Lð ô|Lð~% 3ô %ð ‡�ƒØ‡‚�
 §¢°4Ñ!8Ñ9Ø‡‚ØØ	�ŠÒ,Ó	-ØØ	Bñ	ð ‡‚ˆg˜s¨Ð3KÑLð5!�sð 5!¨°#©ð 5!¸Só 5!ó Móó :ó ð5!ðp ‡�ƒØ‡‚ˆh Ð2ZÑ[Ø‡‚ˆh ¨3Ð5WÑXØ‡‚ˆj $Ð-VÑWðQ�Sð Q ð Q¨Tó Qó Xó Yó \ó ðQð ‡��˜G€Ñ $Ø ‡��˜i€Ñ (ò
ð
 ˆzÓÙ…Fð ùò' 7ùòB +Kùò~ 7s   Ãj9Ç$j>Êk