§
    ùH¶j,-  ã                  óŠ  — d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
Z
ddlZddlmZ ddlmZ ddlmZ ddlmZmZ ddlZddlmZmZ dd	lmZmZ dd
lmZ ddlm Z  ddl!m"Z" ddl#m$Z$  ed¦  «        Z% G d„ dej&        ¦  «        Z' G d„ dej&        ¦  «        Z( G d„ dej&        ¦  «        Z)e*dk    r ej+        ¦   «          dS dS )z‘Comprehensive test suite for Multimodal OCR Engine, Image Preprocessing,
and its integration into Document Management and Banking UNC workflows.
é    )ÚannotationsN)Údate)ÚDecimal)ÚPath)Ú	MagicMockÚpatch)ÚImageÚ	ImageDraw)ÚFILE_MAGIC_SIGNATURESÚAgentSecurityGuard)ÚUncClassifierAndRouter)ÚDocumentExtractorMixin)ÚImagePreprocessor)ÚMultimodalOcrServicezTc:\Projects\DSCons\Finance\UNC-2026\Techcombank-2026\DebitNote26.06.2026_Minh An.pdfc                  ó:   — e Zd ZdZd
d„Zd
d„Zd
d„Zd
d„Zd
d„Zd	S )ÚTestImagePreprocessorzKUnit tests for Pure Python / Pillow / Numpy image preprocessing algorithms.ÚreturnÚNonec                óH  — t          j        ddd¬¦  «        }t          j        |¦  «        }t	          ddd¦  «        D ] }|                     d|fd	|fgd
d¬¦  «         Œ!|                     ddd¬¦  «        }t          j        |dd¬¦  «        }|  	                    t          |¦  «        dd¬¦  «         t          j        |dd¬¦  «        \  }}|                      |t           j         ¦  «         |                      |j        d¦  «         |                      |j        d¦  «         dS )z8Test text skew angle estimation and automated deskewing.ÚRGB)iX  i,  ©éÿ   r   r   ©Úcoloré(   i  é   é2   i&  )r   r   r   é   )ÚfillÚwidthg      @T)ÚexpandÚ	fillcolorg      $@g      à?)Ú	max_angleÚ
angle_stepg      ð?)Údeltar   N)r	   Únewr
   ÚDrawÚrangeÚlineÚrotater   Úestimate_skew_angleÚassertAlmostEqualÚabsÚdeskewÚassertIsInstanceÚassertGreaterr    Úheight)ÚselfÚimgÚdrawÚyÚskewedÚangleÚdeskewedÚ
rotated_bys           ú6C:\Projects\DSCons\tests\test_multimodal_ocr_engine.pyÚtest_estimate_skew_and_deskewz3TestImagePreprocessor.test_estimate_skew_and_deskew'   s/  € õ Œi˜˜z°ÐAÑAÔAˆÝŒ~˜cÑ"Ô"ˆÝ�r˜3 Ñ#Ô#ð 	Dð 	DˆAØ�IŠI˜˜A�w  a Ð)°	ÀˆIÑCÔCÐCÐCð —’˜C¨¸�ÑHÔHˆõ "Ô5°fÈÐY\Ð]Ñ]Ô]ˆØ×Ò�s 5™zœz¨3°cÐÑ:Ô:Ð:õ  1Ô7¸È$Ð[^Ð_Ñ_Ô_Ñˆ�*Ø×Ò˜h­¬Ñ4Ô4Ð4Ø×Ò˜8œ>¨1Ñ-Ô-Ð-Ø×Ò˜8œ?¨AÑ.Ô.Ð.Ð.Ð.ó    c                ó‚  — t          j        ddd¬¦  «        }t          j        |¦  «        }|                     ddd¬¦  «         t          j        |¦  «        }d	|d
d…d
d…f<   t          j        |¦  «        }t          j	        |¦  «        }t          j
        |¦  «        }|                      |j        |j        ¦  «         dS )z3Test auto-contrast enhancement and noise reduction.r   )éÈ   r>   )é´   r?   r?   r   )r   éP   zCONG TRINH 2026)éd   rA   rA   ©r   r   r   é<   N)r	   r&   r
   r'   ÚtextÚnpÚarrayÚ	fromarrayr   Úenhance_contrastÚdenoiseÚassertEqualÚsize)r2   r3   r4   ÚarrÚ	noisy_imgÚenhancedÚdenoiseds          r:   Ú!test_enhance_contrast_and_denoisez7TestImagePreprocessor.test_enhance_contrast_and_denoise<   s´   € åŒi˜˜z°ÐAÑAÔAˆÝŒ~˜cÑ"Ô"ˆØ�	Š	�(Ð-°Oˆ	ÑDÔDÐDõ Œh�s‰mŒmˆØˆˆBˆrˆE�2�b�5ˆLÑÝ”O CÑ(Ô(ˆ	å$Ô5°iÑ@Ô@ˆÝ$Ô,¨XÑ6Ô6ˆØ×Ò˜œ¨¬Ñ1Ô1Ð1Ð1Ð1r<   c                ót  — t          j        ddd¬¦  «        }t          j        |¦  «        }|                     g d¢d¬¦  «         t          j        |¦  «        }t          j        |¦  «        }t          t          j
        |¦  «        ¦  «        }|                      |                     dd	h¦  «        ¦  «         d
S )zCTest Otsu global binarization produces pure black and white pixels.r   )rA   rA   )r>   r>   r>   r   )é   rR   r@   r@   )r   r   r   rB   r   r   N)r	   r&   r
   r'   Ú	rectangler   Úadaptive_binarizerE   rF   ÚsetÚuniqueÚ
assertTrueÚissubset)r2   r3   r4   Úbin_imgÚbin_arrÚunique_valss         r:   Útest_adaptive_binarizez,TestImagePreprocessor.test_adaptive_binarizeK   s¤   € åŒi˜˜z°ÐAÑAÔAˆÝŒ~˜cÑ"Ô"ˆØ�ŠÐ'Ð'Ð'¨lˆÑ;Ô;Ð;å#Ô5°cÑ:Ô:ˆÝ”(˜7Ñ#Ô#ˆÝ�"œ) GÑ,Ô,Ñ-Ô-ˆà�Š˜×,Ò,¨a°¨XÑ6Ô6Ñ7Ô7Ð7Ð7Ð7r<   c                óŒ  — t                                ¦   «         s|                      d¦  «         t                                ¦   «         }t	          j        |dd¬¦  «        }|                      t          |¦  «        d¦  «         |                      |d         j	        d¦  «         |                      |d         j
        d¦  «         dS )z8Test PyMuPDF rasterization of real AEC / Bank PDF pages.ú,Real Debit Note file not found on filesystemé   é–   )Ú	max_pagesÚdpir   iô  N)ÚREAL_DEBIT_NOTE_PATHÚexistsÚskipTestÚ
read_bytesr   Úrender_pdf_to_imagesrJ   Úlenr0   r    r1   )r2   Ú	pdf_bytesÚimagess      r:   Útest_render_pdf_to_imagesz/TestImagePreprocessor.test_render_pdf_to_imagesW   s®   € å#×*Ò*Ñ,Ô,ð 	JØ�MŠMÐHÑIÔIÐIå(×3Ò3Ñ5Ô5ˆ	Ý"Ô7¸	ÈQÐTWÐXÑXÔXˆØ×Ò�˜V™œ aÑ(Ô(Ð(Ø×Ò˜6 !œ9œ?¨CÑ0Ô0Ð0Ø×Ò˜6 !œ9Ô+¨SÑ1Ô1Ð1Ð1Ð1r<   c                óö   — t          j        ddd¬¦  «        }t          j        |d¬¦  «        }|                      |                     d¦  «        ¦  «         |                      t          |¦  «        d¦  «         d	S )
z5Test image serialization to standard base64 data URI.r   )r   r   r   r   ÚJPEG©Úformatzdata:image/jpeg;base64,r   N)r	   r&   r   Úimage_to_data_urirW   Ú
startswithr0   rh   )r2   r3   Údata_uris      r:   Útest_image_to_data_uriz,TestImagePreprocessor.test_image_to_data_urib   sp   € åŒi˜˜x¨Ð?Ñ?Ô?ˆÝ$Ô6°sÀ6ÐJÑJÔJˆØ�Š˜×+Ò+Ð,EÑFÔFÑGÔGÐGØ×Ò�3˜x™=œ=¨"Ñ-Ô-Ð-Ð-Ð-r<   N©r   r   )	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r;   rP   r\   rk   rs   © r<   r:   r   r   $   s~   € € € € € ØUÐUð/ð /ð /ð /ð*2ð 2ð 2ð 2ð
8ð 
8ð 
8ð 
8ð	2ð 	2ð 	2ð 	2ð.ð .ð .ð .ð .ð .r<   r   c                  ó2   — e Zd ZdZd	d„Zd	d„Zd	d„Zd	d„ZdS )
ÚTestMultimodalOcrServicez9Unit and functional tests for the Multimodal OCR Service.r   r   c                ó,   — t          ¦   «         | _        d S )N)r   Úservice)r2   s    r:   ÚsetUpzTestMultimodalOcrService.setUpm   s   € Ý+Ñ-Ô-ˆŒˆˆr<   c                ó¦  — t                                ¦   «         s|                      d¦  «         t                                ¦   «         }| j                             |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S )zcVerify 100% extraction accuracy on actual Techcombank Debit Note (Core Law 1: Zero Synthetic Data).r^   zDebitNote26.06.2026_Minh An.pdfÚpdfÚ	bank_codeÚTECHCOMBANKÚref_noÚFT26177032980455Úamountg    ÁH·AÚamount_in_wordsuJ   Ba trÄƒm chÃ­n mÆ°Æ¡i triá»‡u sÃ¡u trÄƒm bá»‘n mÆ°Æ¡i bá»‘n nghÃ¬n Ä‘á»“ngÚsender_accountÚ07898888Úsender_namezVND-TGTT-CT TNHH XD DINH SONÚreceiver_accountÚ
1058177339Úreceiver_namezCONG TY CO PHAN MINH AN BG 688Úreceiver_bankzNGOAI THUONG VN (VCB)Útxn_datez
2026-06-26Ú	directionÚoutflowz0CTY TNHH XD DINH SON TRA TIEN CHO MINH AN BG 688ÚdescriptionÚ N)	rc   rd   re   rf   r}   Úextract_banking_unc_datarJ   ÚgetÚassertIn)r2   ri   Údatas      r:   Ú(test_extract_banking_unc_real_debit_notezATestMultimodalOcrService.test_extract_banking_unc_real_debit_notep   s  € å#×*Ò*Ñ,Ô,ð 	JØ�MŠMÐHÑIÔIÐIå(×3Ò3Ñ5Ô5ˆ	ØŒ|×4Ò4ØØ-Øñ
ô 
ˆð 	×Ò˜Ÿš +Ñ.Ô.°Ñ>Ô>Ð>Ø×Ò˜Ÿš (Ñ+Ô+Ð-?Ñ@Ô@Ð@Ø×Ò˜Ÿš (Ñ+Ô+¨[Ñ9Ô9Ð9Ø×Ò˜ŸšÐ"3Ñ4Ô4ð  7Cñ  	Dô  	Dð  	DØ×Ò˜ŸšÐ"2Ñ3Ô3°ZÑ@Ô@Ð@Ø×Ò˜Ÿš -Ñ0Ô0Ð2PÑQÔQÐQØ×Ò˜ŸšÐ"4Ñ5Ô5°|ÑDÔDÐDØ×Ò˜Ÿš /Ñ2Ô2Ð4TÑUÔUÐUØ×Ò˜Ÿš /Ñ2Ô2Ð4KÑLÔLÐLØ×Ò˜Ÿš *Ñ-Ô-¨|Ñ<Ô<Ð<Ø×Ò˜Ÿš +Ñ.Ô.°	Ñ:Ô:Ð:Ø�ŠÐHÈ$Ï(Ê(ÐS`ÐbdÑJeÔJeÑfÔfÐfÐfÐfr<   c                ó  — d}| j                              |                     d¦  «        dd|¬¦  «        }|                      |                     d¦  «        d¦  «         |                      d|                     d	d
¦  «        ¦  «         |                      |                     d¦  «        d¦  «         |                      |                     d¦  «        d¦  «         |                      |                     d¦  «        d¦  «         dS )zHTest heuristic metadata extractor for construction procurement dossiers.u  TRUNG TÃ‚M Dá»ŠCH Vá»¤ Sá»° NGHIá»†P CÃ”NG XÃƒ KIáº¾N MINH
Sá»‘: IB2600471890
THÃ”NG BÃ�O Má»œI THáº¦U
Vá»� viá»‡c: GÃ³i tháº§u sá»‘ 05: XÃ¢y dá»±ng cá»‘ng há»™p Ä‘oáº¡n tá»« nhÃ  Ã´ng Ä�Ã¨n Ä‘áº¿n nhÃ  bÃ  Lanh
NgÃ y ban hÃ nh: 22/08/2026
Ä�Ã£ kÃ½ sá»‘ bá»Ÿi GiÃ¡m Ä‘á»‘c trung tÃ¢mzutf-8zTBMT_CongHop_OngDen.txtÚtxt)Úfile_contentÚfilenameÚfile_formatÚtext_contentÚdocument_codeÚIB2600471890u   GÃ³i tháº§u sá»‘ 05Údocument_titler’   Údocument_groupÚlegalÚdocument_typeÚTBÚsignature_statusÚfully_executedN)r}   Úextract_document_metadataÚencoderJ   r”   r•   )r2   Úsample_textÚmetas      r:   Ú(test_extract_document_metadata_heuristiczATestMultimodalOcrService.test_extract_document_metadata_heuristic‰   sû   € ð:ð 	ð Œ|×5Ò5Ø$×+Ò+¨GÑ4Ô4Ø.ØØ$ð	 6ñ 
ô 
ˆð 	×Ò˜Ÿš /Ñ2Ô2°NÑCÔCÐCØ�ŠÐ+¨T¯XªXÐ6FÈÑ-KÔ-KÑLÔLÐLØ×Ò˜ŸšÐ"2Ñ3Ô3°WÑ=Ô=Ð=Ø×Ò˜Ÿš /Ñ2Ô2°DÑ9Ô9Ð9Ø×Ò˜ŸšÐ"4Ñ5Ô5Ð7GÑHÔHÐHÐHÐHr<   c                óú  — d}|                       t          j        |d¦  «        ¦  «         d}|                       t          j        |d¦  «        ¦  «         |                       t          j        |d¦  «        ¦  «         d}|                       t          j        |d¦  «        ¦  «         d}d	}|                       t          j        |d
¦  «        ¦  «         |                       t          j        |d¦  «        ¦  «         dS )zQEnsure webp and tiff image formats pass AgentSecurityGuard Zero-Trust validation.s   ‰PNG

   IHDRÚpngs
   ÿØÿà JFIFÚjpgÚjpegs   RIFF$   WEBPVP8Úwebps   II*    s   MM *   ÚtiffÚtifN)rW   r   Úvalidate_magic_bytes)r2   Ú	png_bytesÚ	jpg_bytesÚ
webp_bytesÚtiff_leÚtiff_bes         r:   Ú$test_security_magic_bytes_for_imagesz=TestMultimodalOcrService.test_security_magic_bytes_for_images    sé   € ð ;ˆ	Ø�ŠÕ*Ô?À	È5ÑQÔQÑRÔRÐRð 4ˆ	Ø�ŠÕ*Ô?À	È5ÑQÔQÑRÔRÐRØ�ŠÕ*Ô?À	È6ÑRÔRÑSÔSÐSð 4ˆ
Ø�ŠÕ*Ô?À
ÈFÑSÔSÑTÔTÐTð -ˆØ,ˆØ�ŠÕ*Ô?ÀÈÑPÔPÑQÔQÐQØ�ŠÕ*Ô?ÀÈÑOÔOÑPÔPÐPÐPÐPr<   Nrt   )ru   rv   rw   rx   r~   r—   r«   r¹   ry   r<   r:   r{   r{   j   sx   € € € € € ØCÐCð.ð .ð .ð .ðgð gð gð gð2Ið Ið Ið Ið.Qð Qð Qð Qð Qð Qr<   r{   c                  ó*   — e Zd ZdZdd„Zdd„Zdd„ZdS )	Ú)TestOcrIntegrationWithBankingAndDocumentszOIntegration tests verifying OCR hooks in banking router and document extractor.r   r   c                ót  — t                                ¦   «         s|                      d¦  «         t                                ¦   «         }t	          j        d|¬¦  «        \  }}}|                      |¦  «         |                      |d¦  «         |                      | 	                    dd¦  «        dd¦  «         d	S )
a�  Test UncClassifierAndRouter.detect_unc_and_bank detects Techcombank from content bytes.
        
        Note: When the classifier already identifies the bank via keyword matching
        (is_unc=True AND bank_code is set), it correctly skips the expensive OCR
        deep inspection path. In that case, ocr_matched will be False because OCR
        was unnecessary, not because it failed.
        r^   zDocument_Scan_Receipt_01.pdf)r›   Úcontentr‚   Ú
confidencer   gš™™™™™é?z;Detection confidence should be >= 0.8 for automated routingN)
rc   rd   re   rf   r   Údetect_unc_and_bankrW   rJ   ÚassertGreaterEqualr”   )r2   ri   Úis_uncr�   Údetailss        r:   Ú"test_unc_classifier_deep_ocr_matchzLTestOcrIntegrationWithBankingAndDocuments.test_unc_classifier_deep_ocr_match¹   sÅ   € õ $×*Ò*Ñ,Ô,ð 	JØ�MŠMÐHÑIÔIÐIå(×3Ò3Ñ5Ô5ˆ	å%;Ô%OØ3Øð&
ñ &
ô &
Ñ"ˆ�	˜7ð
 	�Š˜ÑÔÐØ×Ò˜ MÑ2Ô2Ð2ð 	×ÒØ�KŠK˜ aÑ(Ô(¨#ØIñ	
ô 	
ð 	
ð 	
ð 	
r<   c                óz  — t          ¦   «         }t          j        ddd¬¦  «        }t          j        ¦   «         }|                     |d¬¦  «         |                     ¦   «         }t          d¦  «        }|j         	                    dd¬	¦  «         | 
                    |¦  «         	 |                     t          |¦  «        d
¦  «        }|                      |t          ¦  «         |                     ¦   «         r|                     ¦   «          dS dS # |                     ¦   «         r|                     ¦   «          w w xY w)zQTest DocumentExtractorMixin handles images gracefully using MultimodalOcrService.r   )rA   r   r   r   ÚPNGrn   z(storage/secure_vault/test_ocr_sample.pngT)ÚparentsÚexist_okr­   N)r   r	   r&   ÚioÚBytesIOÚsaveÚgetvaluer   ÚparentÚmkdirÚwrite_bytesÚextract_textÚstrr/   rd   Úunlink)r2   Ú	extractorr3   Úimg_bufÚpng_dataÚtemp_img_pathÚextracted_texts          r:   Útest_extractor_mixin_with_imagezITestOcrIntegrationWithBankingAndDocuments.test_extractor_mixin_with_imageÕ   s6  € å*Ñ,Ô,ˆ	õ Œi˜˜y°Ð@Ñ@Ô@ˆÝ”*‘,”,ˆØ�Š� ˆÑ'Ô'Ð'Ø×#Ò#Ñ%Ô%ˆõ ÐGÑHÔHˆØÔ×"Ò"¨4¸$Ð"Ñ?Ô?Ð?Ø×!Ò! (Ñ+Ô+Ð+ð	'Ø&×3Ò3µC¸Ñ4FÔ4FÈÑNÔNˆNØ×!Ò! .µ#Ñ6Ô6Ð6à×#Ò#Ñ%Ô%ð 'Ø×$Ò$Ñ&Ô&Ð&Ð&Ð&ð'ð 'øˆ}×#Ò#Ñ%Ô%ð 'Ø×$Ò$Ñ&Ô&Ð&Ð&ð'øøøs   Â%>D Ä+D:c                óò  — t                                ¦   «         s|                      d¦  «         t                                ¦   «         }t	          ¦   «         }|                     t          t           ¦  «        d|¬¦  «        }|                      |                     d¦  «        d¦  «         |  	                    |                     dd¦  «        d¦  «         t          |j        d	d¦  «        pt          |j        d
d¦  «        } |¦   «         5 }|                     ¦   «         5 }|                     d¦  «         ddd¦  «         n# 1 swxY w Y   |                     ¦   «          ddd¦  «         dS # 1 swxY w Y   dS )z^Test ingest_statement_file parses real Techcombank Debit Note via OCR and inserts transaction.r^   N)Ú	file_pathr�   rš   r�   r‚   Útotal_parsedr   r_   Úget_connectionÚ_open_connectionzNDELETE FROM erp_bank_transactions WHERE reference_number = 'FT26177032980455';)rc   rd   re   rf   r   Úingest_statement_filerÐ   rJ   r”   rÀ   ÚgetattrÚ_clientÚcursorÚexecuteÚcommit)r2   ri   ÚrouterÚresÚget_connÚconnÚcurs          r:   Ú/test_ingest_statement_file_with_real_debit_notezYTestOcrIntegrationWithBankingAndDocuments.test_ingest_statement_file_with_real_debit_noteë   sÚ  € å#×*Ò*Ñ,Ô,ð 	JØ�MŠMÐHÑIÔIÐIå(×3Ò3Ñ5Ô5ˆ	Ý'Ñ)Ô)ˆà×*Ò*ÝÕ.Ñ/Ô/ØØ"ð +ñ 
ô 
ˆð 	×Ò˜Ÿš Ñ-Ô-¨}Ñ=Ô=Ð=Ø×Ò §¢¨¸Ñ :Ô :¸AÑ>Ô>Ð>õ ˜6œ>Ð+;¸TÑBÔBÐwÅgÈfÌnÐ^pÐrvÑFwÔFwˆØˆX‰ZŒZð 	˜4Ø—’‘”ð  #Ø—’Ødñô ð ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð �KŠK‰MŒMˆMð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s6   Ä	E,ÄE Ä4E,Å E	ÅE,ÅE	ÅE,Å,E0Å3E0Nrt   )ru   rv   rw   rx   rÃ   r×   rè   ry   r<   r:   r»   r»   ¶   sV   € € € € € ØYÐYð
ð 
ð 
ð 
ð8'ð 'ð 'ð 'ð,ð ð ð ð ð r<   r»   Ú__main__),rx   Ú
__future__r   ÚbuiltinsÚ@py_builtinsÚ_pytest.assertion.rewriteÚ	assertionÚrewriteÚ
@pytest_arrÈ   ÚosÚunittestÚdatetimer   Údecimalr   Úpathlibr   Úunittest.mockr   r   ÚnumpyrE   ÚPILr	   r
   Ú3app.modules.agents.application.agent_security_guardr   r   Ú9app.modules.banking.application.unc_classifier_and_routerr   Ú:app.modules.core.application.document_processing.extractorr   Ú3app.modules.core.application.ocr.image_preprocessorr   Ú7app.modules.core.application.ocr.multimodal_ocr_servicer   rc   ÚTestCaser   r{   r»   ru   Úmainry   r<   r:   ú<module>r      s:  ððð ð #Ð "Ð "Ð "Ð "Ð "à  € € € € € € € € € € € € €	€	€	€	Ø 	€	€	€	Ø €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø *Ð *Ð *Ð *Ð *Ð *Ð *Ð *à Ð Ð Ð Ø  Ð  Ð  Ð  Ð  Ð  Ð  Ð  ðð ð ð ð ð ð ð ðð ð ð ð ð ðð ð ð ð ð ð RÐ QÐ QÐ QÐ QÐ QØ XÐ XÐ XÐ XÐ XÐ Xà�tØ[ñô Ð ð
C.ð C.ð C.ð C.ð C.˜HÔ-ñ C.ô C.ð C.ðLIQð IQð IQð IQð IQ˜xÔ0ñ IQô IQð IQðXNð Nð Nð Nð N°Ô0Añ Nô Nð Nðb ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr<   