+
    f7i~  c                  sF  a  0 t $ R t^ RIHt ^ RIt^ RIHtHt ^ RIH	t	 ^ RI
Hu Ht ^ RIHtHtHtHt ^ RIHt ^ RIHt ]]]]]]]],          R3,          3,          ]3,          3,          tR	 R
 ltR R ltR R ltR R lt R R lt!R R lt"R R lt#R R lt$R R lt%R R lt&R R lt'R R  lt(R! R" lt)R# R$ lt*R% R& lt+R' R( lt,R) R* lt-R+ R, lt.R- R. lt/R/ R0 lt0R1 R2 lt1R3 R4 lt2R5 R6 lt3R7 R8 lt4R9 R: lt5R; R< lt6R= R> lt7R? R@ lt8RA RB lt9RC RD lt:RE RF lt;RG RH lt<RI RJ lt=RrRK RL llt>]! ]?]@3RM3]?]@3RM3]?]@3RM3]RM3]RM3]RM3RN7      tARO]BRP&   RQ RR ltCRrRS RT lltD]! ]?]@3RM3]?]@3RM3]RM3]RM3]RM3RU7      tERO]BRV&   RW RX ltFRY RZ ltGR[ R\ ltHR]tIR^]BR_&   ]! ]R`3]?]@3RM3]?]@3RM3]?]@3RM3]?]@3RM3]?]@3RM3]?]@3RM3]RM3Ra7      tJRO]BRb&   Rc tKRsRd Re lltLRf Rg ltMRh Ri ltNRj Rk ltORltPRm Rn ltQRo Rp ltR]SRq8X  d   ^ RITtT]TP                  ! 4        R# R# )tz"Various low level data validators.)annotationsN)MappingSequence)open)AnyTypeOptionalUnion)IntFloat)numberTypes.c                    V ^8  d   QhRRRR/#    valuer   returnbool Zformat   "B/usr/lib64/python3.14/site-packages/fontTools/ufoLib/validators.py__annotate__r      s     
 
 
 
    c                sp    \        V \        4      '       d   R# R F  p\        W4      '       d   K   R# 	  R# )zM
Some objects will likely come in that aren't
dicts but are dict-ish enough.
TF)keysvaluesitems)
isinstancer   Zhasattr)r   Zattr   & r   isDictEnoughr      s1    
 %!!+u## , r   c               $    V ^8  d   QhRRRRRR/# )r   r   r   typz	Type[Any]r   r   r   r   r   r   r   r   #   s!     " " ") " "r   c                s    \        W4      # ) 
Generic. (Added at version 2.)
)r   )r   r   s   &&r   genericTypeValidatorr   #   s     e!!r   c               r   )r   r   r   validValueszSequence[int]r   r   r   r   r   r   r   r   *   s!      C m  r   c                s    \        V \        \        34      '       g   R# \        V 4      p\        V4      pW#,
          '       d   R# V  F  p\        V\        4      '       d   K   R# 	  R# )r   FT)r   listtuplesetint)r   r    Z	valuesSetZvalidValuesSetr   s   &&   r   genericIntListValidatorr%   *   sV     ftUm,,FI%N!!%%%  r   c               r
   r   r   r   r   r   r   r   :   s      # $ r   c                H    \        V \        4      '       g   R# V ^ 8  d   R# R# z 
Generic. (Added at version 3.)
FTr   r$   r      &r   genericNonNegativeIntValidatorr+   :   !     eS!!qyr   c               r
   r   r   r   r   r   r   r   E   s      S T r   c                r&   r'   )r   r	   r)   r*   r   !genericNonNegativeNumberValidatorr-   E   s!     e[))qyr   c               r   )r   r   r   	prototypeGenericDictr   r   r   r   r   r   r   r   P   s!         r   c                s^   \        V \        4      '       g   R# VP                  4        F  w  pw  r4V'       g   K  W 9  g   K   R# 	  V P                  4        F  pW!9  g   K   R# 	  V P                  4        F1  w  r%W,          w  rdVf   V'       g   K  \        WV4      '       d   K0   R# 	  R# r'   )r   r   r   r   )r   r.   keyr   ZrequiredZvZprototypeTypes   &&     r   genericDictValidatorr1   P   s    
 eW%% ) 1_c	 !2 zz|  ++-"+.9X!++   r   c               r
   r   r   r   r   r   r   r   r   s      c d r   c                s    . ROpW9   # )
Version 2+.
)ZregularZitalicZboldzbold italicr   )r   Zoptionsr   r   "fontInfoStyleMapStyleNameValidatorr3   r   s     ;Gr   c               r
   r   r   r   r   r   r   r   z   s      S T r   c                s   \        V \        4      '       g   R# \        V 4      ^ 8X  d   R# . ROp\        \        R3\        R3R7      p. pV  Ff  p\        WB4      '       g    R# VR,          pVR,          p\        V4      pV'       g    R# \        Wa4      pV'       g    R# VP                  V4       Kh  	  V\        V4      8w  d   R# R# )
Version 3+.
FT)rangeMaxPPEMrangeGaspBehaviorr5   r6   )i    i   r   i   )
r   r!   lendictr$   r1   r+   r%   ZappendZsorted)	r   ZvalidBehaviorsdictPrototypeZ	ppemOrderZrangeRecordZppemZbehaviorZppemValidityZbehaviorValiditys	   &        r   )fontInfoOpenTypeGaspRangeRecordsValidatorr:   z   s     eT""
5zQ!N!%4[T4L"M I#K??>*235d;28L  F9%%r   c               r
   r   r   r   r   r   r   r      s     9 9 9 9r   c                s   \        V \        4      '       g   R# \        V 4      ^8X  g   R# V P                  R4      ^8w  d   R# V P	                  R4      w  rVP                  R4      ^8w  d   R# VP                  R4      ^8w  d   R# VP	                  R4      w  r4p\        V4      ^8w  d   R# \        V4      ^8w  d   R# \        V4      ^8w  d   R#  \        V4      p\        V4      p\        V4      pT^8  g   T^8  d   R# \        P                  ! Yg4      ^,          p	T^8  g   Y8  d   R# TP	                  R4      w  rp\        T
4      ^8w  d   R# \        T4      ^8w  d   R# \        T4      ^8w  d   R#  \        T
4      p\        T4      p\        T4      pT^ 8  g   T^8  d   R# T^ 8  g   T^;8  d   R# T^ 8  g   T^;8  d   R# R#   \         d     R# i ; i  \         d     R# i ; i)r2   FZ Z/Z:T)	r   strr7   Zcountsplitr$   
ValueErrorcalendarZ
monthrange)r   ZstrDateZstrTimeZstrYearZstrMonthZstrDayZintYearZintMonthZintDayZmonthMaxDayZstrHourZ	strMinuteZ	strSecondZintHourZ	intMinuteZ	intSeconds   &               r   $fontInfoOpenTypeHeadCreatedValidatorr?      s   
 eS!!u:{{31{{3'G}}SQ}}SQ 'c 2Gv
7|q
8}
6{ag,x=V !|x"}%%g8;KzV)$+MM#$6!G	
7|q
9~
9~g,	N		N	 {gl1}	B1}	B9  &  s$   !G 9!G GGG-,G-c               r
   r   r   r   r   r   r   r      s        r   c                s    \        V \        4      '       g   R# \        \        R3\        R3\        R3\        R3\        R3R7      pV  F  p\        W!4      '       d   K   R# 	  R# )r4   FT)ZnameIDZ
platformIDZ
encodingIDZ
languageIDZstring)r   r!   r8   r$   r;   r1   )r   r9   Z
nameRecord   &  r   $fontInfoOpenTypeNameRecordsValidatorrA      s`     eT""!%T{;;;T{"M 
#J>>  r   c               r
   r   r   r   r   r   r   r      s      3 4 r   c                r&   r2   FTr(   r)   r*   r   'fontInfoOpenTypeOS2WeightClassValidatorrC      r,   r   c               r
   r   r   r   r   r   r   r           
 
# 
$ 
r   c                sZ    \        V \        4      '       g   R# V ^8  d   R# V ^	8  d   R# R# rB   r(   r)   r*   r   &fontInfoOpenTypeOS2WidthClassValidatorrE      s+     eS!!qyqyr   c               r
   r   r   r   r   r   r   r   r   r   r   r      s      s t r   c                s    \        V \        \        34      '       g   R# \        V 4      ^
8w  d   R# V  F  p\        V\        4      '       d   K   R# 	  R# )z
Version 2.
FTr   r!   r"   r7   r$   r   r   r   r   *fontInfoVersion2OpenTypeOS2PanoseValidatorrI      sF     ftUm,,
6{b%%%  r   c               r
   rF   r   r   r   r   r   r           s t r   c                s    \        V \        \        34      '       g   R# \        V 4      ^
8w  d   R# V  F&  p\        V\        4      '       g    R# V^ 8  g   K%   R# 	  R# r4   FTrG   rH   r   r   *fontInfoVersion3OpenTypeOS2PanoseValidatorrL     sP     ftUm,,
6{b%%%19	  r   c               r
   rF   r   r   r   r   r   r     s      C D r   c                s    \        V \        \        34      '       g   R# \        V 4      ^8w  d   R# V  F  p\        V\        4      '       d   K   R# 	  V w  r#V^ 8  g   V^8  d   R# V^ 8  g   V^8  d   R# R# rB   rG   )r   r   ZclassIDZ
subclassID   &   r   'fontInfoOpenTypeOS2FamilyClassValidatorrN     sn     ftUm,,
6{a%%%  !G{glA~br   c               r
   rF   r   r   r   r   r   r   2  s      S T r   c                s    \        V \        \        34      '       g   R# \        V 4      ^8  d   R# \        V 4      ^,          '       d   R# V  F  p\        V\        4      '       d   K   R# 	  R# rB   r   r!   r"   r7   r	   rH   r   r    fontInfoPostscriptBluesValidatorrP   2  V     ftUm,,
6{R
6{Q%--  r   c               r
   rF   r   r   r   r   r   r   B  s      # $ r   c                s    \        V \        \        34      '       g   R# \        V 4      ^
8  d   R# \        V 4      ^,          '       d   R# V  F  p\        V\        4      '       d   K   R# 	  R# rB   rO   rH   r   r   %fontInfoPostscriptOtherBluesValidatorrR   B  rQ   r   c               r
   rF   r   r   r   r   r   r   R  s      S T r   c                s    \        V \        \        34      '       g   R# \        V 4      ^8  d   R# V  F  p\        V\        4      '       d   K   R# 	  R# rB   rO   rH   r   r    fontInfoPostscriptStemsValidatorrS   R  sF     ftUm,,
6{R%--  r   c               r
   r   r   r   r   r   r   r   `  s      # $ r   c                s@    \        \        ^^4      4      pW9  d   R# R# rB   )r!   Zrange)r   r    r   r   .fontInfoPostscriptWindowsCharacterSetValidatorrT   `  s      uQ|$Kr   c               r
   r   r   r   r   r   r   r   j  s        r   c                sP    \        \        R3R7      p\        W4      '       g   R# R# )r4   T)idF)r8   r;   r1   r   r9   r   r   %fontInfoWOFFMetadataUniqueIDValidatorrW   j  s#     "&#t!5M55r   c               r
   r   r   r   r   r   r   r   t  s      s t r   c           	         R\         R3R\         R3R\         R3R\         R3/p\        W4      '       g   R# RV 9   d   V P                  R4      R9  d   R# R# )r4   nameTurlFdirclassZltrZrtlr;   r1   getrV   r   r   #fontInfoWOFFMetadataVendorValidatorr`   t  s\    
 	dU|U|#u	"M  55~%))E*.@r   c               r
   r   r   r   r   r   r   r     s        r   c                sd   \        \        R3R7      p\        W4      '       g   R# \        V R,          4      '       g   R# R\        R3R\        R3R\        R3R\        R3R	\        R3/pV R,           F9  p\        W!4      '       g    R# RV9   g   K   VP                  R4      R
9  g   K8   R# 	  R# )r4   T)creditsFra   rY   rZ   Zroler[   r\   r]   )r8   r!   r1   r7   r;   r_   )r   r9   Zcreditr@   r   $fontInfoWOFFMetadataCreditsValidatorrb     s     "&tTl!;M55uY  dU|eU|#uM 	""#F::F?vzz%0F	 #
 r   c               r
   r   r   r   r   r   r   r     s     
 
C 
D 
r   c                s    \        \        R3\        R3R7      p\        W4      '       g   R# V R,           F  p\	        V4      '       d   K   R# 	  R# )r4   FT)rZ   textrc   r8   r;   r!   r1   fontInfoWOFFMetadataTextValuer   r9   rc   r@   r   (fontInfoWOFFMetadataDescriptionValidatorrg     sI     "&3,dD\!JM55f,T22  r   c               r
   r   r   r   r   r   r   r     s        r   c                s    \        \        R3\        R3\        R3R7      p\        W4      '       g   R# RV 9   d%   V R,           F  p\	        V4      '       d   K   R# 	  R# )r4   F)rZ   rc   rU   rc   Trd   rf   r@   r   $fontInfoWOFFMetadataLicenseValidatorrh     s[     "&%Le}#u"M  55&MMD066 " r   c               r
   r   r   r   r   r   r   r     rD   r   c                    \        \        R3R7      p\        W4      '       g   R# V R,           F  p\        V4      '       d   K   R# 	  R# r4   T)rc   Frc   r8   r!   r1   re   rf   r@   r   &fontInfoWOFFMetadataTrademarkValidatorrl     C     "&D$<!8M55f,T22  r   c               r
   r   r   r   r   r   r   r     rD   r   c                ri   rj   rk   rf   r@   r   &fontInfoWOFFMetadataCopyrightValidatorrn     rm   r   c               r
   r   r   r   r   r   r   r     s        r   c                s    R\         R3R\         R3R\         R3/p\        W4      '       g   R# RV 9   d   V P                  R4      R9  d   R# R# )r4   rY   Tr[   Fr\   r]   r^   rV   r   r   %fontInfoWOFFMetadataLicenseeValidatorro     sS    
 	dU|#u"M
  55~%))E*.@r   c               r
   r   r   r   r   r   r   r     s        r   c           	     rX   r4   rc   TZlanguageFr[   r\   r]   r^   rV   r   r   re   re     \    
 	dS%LU|#u	"M  55~%))E*.@r   c               r
   r   r   r   r   r   r   r     s      3 4 r   c                s    \        V \        4      '       g   R# V '       g   R# V  F  p\        V4      '       d   K   R# 	  R# rK   )r   r!   &fontInfoWOFFMetadataExtensionValidator)r   Z	extensionr   r   'fontInfoWOFFMetadataExtensionsValidatorrs     s7     eT""	5i@@  r   c               r
   r   r   r   r   r   r   r     s      # $ r   c                s
   \        \        R3\        R3\        R3R7      p\        W4      '       g   R# RV 9   d%   V R,           F  p\	        V4      '       d   K   R# 	  V R,           F  p\        V4      '       d   K   R# 	  R# )r4   FT)namesr   rU   rt   r   )r8   r!   r;   r1   *fontInfoWOFFMetadataExtensionNameValidator*fontInfoWOFFMetadataExtensionItemValidator)r   r9   rY   ZitemrM   r   rr   rr     s|     "&UmD$<S%L"M  55%'NND=dCC # g9$??  r   c               r
   r   r   r   r   r   r   r     s      c d r   c                s    \        \        R3\        R3\        R3R7      p\        W4      '       g   R# V R,           F  p\	        V4      '       d   K   R# 	  V R,           F  p\        V4      '       d   K   R# 	  R# )r4   FT)rU   rt   r   rt   r   )r8   r;   r!   r1   ru   +fontInfoWOFFMetadataExtensionValueValidator)r   r9   rY   ZvalrM   r   rv   rv     st     "&<d|T4L"M  55g9$??  X:3??  r   c               r
   r   r   r   r   r   r   r   (  s      c d r   c           	     rX   rp   r^   rV   r   r   ru   ru   (  rq   r   c               r
   r   r   r   r   r   r   r   9  rJ   r   c           	     rX   rp   r^   rV   r   r   rw   rw   9  rq   r   c               r   r   r   r   identifierszOptional[set[str]]r   r   r   r   r   r   r   r   O  s"      s 1C t r   c                    \        V \        4      '       g   R# Vf   \        4       pV  FH  p\        V4      '       g    R# VP	                  R4      pVf   K.  W19   d    R# VP                  V4       KJ  	  R# r4   F
identifierT)r   r!   r#   guidelineValidatorr_   add)r   ry   Zguider|      &&  r   guidelinesValidatorr   O  sg     eT""e!%((YY|,
!(OOJ'  r   F)xyanglerY   colorr|   r/   _guidelineDictPrototypec               r
   r   r   r   r   r   r   r   l  s     ! !c !d !r   c                s   \        V \        4      '       g   R# V P                  R4      pV P                  R4      pV P                  R4      pVf   Vf   R# Ve   Vf   Ve   R# Ve   Ve   Vf   R# Ve   V^ 8  d   R# VR8  d   R# V P                  R4      pVe   \        V4      '       g   R# V P                  R4      pVe   \	        V4      '       g   R# R# )	r4   Fr   r   r   ih  r|   r   T)r1   r   r_   identifierValidatorcolorValidator)r   r   r   r   r|   r      &     r   r}   r}   l  s      '>??		#A		#AIIgEyQYyAI}5=193;<(J&9*&E&EIIgE!6!6r   c               r   rx   r   r   r   r   r   r     s"      C .@ D r   c                rz   r{   )r   r!   r#   anchorValidatorr_   r~   )r   ry   Zanchorr|   r   r   anchorsValidatorr     sg     eT""ev&&ZZ-
!(OOJ'  r   )r   r   rY   r   r|   _anchorDictPrototypec               r
   r   r   r   r   r   r   r     s      3 4 r   c                s.   \        V \        4      '       g   R# V P                  R4      pV P                  R4      pVe   Vf   R# V P                  R4      pVe   \        V4      '       g   R# V P                  R4      pVe   \	        V4      '       g   R# R# )r4   Fr   r   r|   r   T)r1   r   r_   r   r   )r   r   r   r|   r      &    r   r   r     s      ';<<		#A		#AyAI<(J&9*&E&EIIgE!6!6r   c               r
   r   r   r   r   r   r   r     s      s t r   c                s    ^ p^~p\        V \        4      '       g   R# V '       g   R# \        V 4      ^d8  d   R# V  F  p\        V4      pWA8  g	   WB8  g   K   R# 	  R# )z{
Version 3+.

>>> identifierValidator("a")
True
>>> identifierValidator("")
False
>>> identifierValidator("a" * 101)
False
FT)r   r;   r7   Zord)r   ZvalidCharactersMinZvalidCharactersMaxZcir   r   r   r     s[     eS!!
5zCF!Q%;  r   c               r
   r   r   r   r   r   r   r     s     C C# C$ Cr   c                s   \        V \        4      '       g   R# V P                  R4      p\        V4      ^8w  d   R# V F[  pVP	                  4       pRp \        V4      pRpV'       g    \        V4      pRpV'       g    R# ^ Xu;8:  d   ^8:  d   KU    R#   R# 	  R#   \         d     LKi ; i  \         d     LFi ; i)a  
Version 3+.

>>> colorValidator("0,0,0,0")
True
>>> colorValidator(".5,.5,.5,.5")
True
>>> colorValidator("0.5,0.5,0.5,0.5")
True
>>> colorValidator("1,1,1,1")
True

>>> colorValidator("2,0,0,0")
False
>>> colorValidator("0,2,0,0")
False
>>> colorValidator("0,0,2,0")
False
>>> colorValidator("0,0,0,2")
False

>>> colorValidator("1r,1,1,1")
False
>>> colorValidator("1,1g,1,1")
False
>>> colorValidator("1,1,1b,1")
False
>>> colorValidator("1,1,1,1a")
False

>>> colorValidator("1 1 1 1")
False
>>> colorValidator("1 1,1,1")
False
>>> colorValidator("1,1 1,1")
False
>>> colorValidator("1,1,1 1")
False

>>> colorValidator("1, 1, 1, 1")
True
FZ,T)r   r;   r<   r7   Zstripr$   r=   float)r   ZpartsZpartZ	convertedZnumberr   r   r   r     s    V eS!!KKE
5zQzz|		YFI t 	 Fa  % &   		  s$   B*B0B-,B-0B>=B>s   PNG

ZbytespngSignatureT)fileNameZxScaleZxyScaleZyxScaleZyScaleZxOffsetZyOffsetr   _imageDictPrototypec                s    \        V \        4      '       g   R# V R,          '       g   R# V P                  R4      pVe   \        V4      '       g   R# R# )r4   Fr   r   T)r1   r   r_   r   )r   r   r   r   imageValidatorr   C  sG      ':;;IIgE!6!6r   c               s(    V ^8  d   QhRRRRRRRR/# )	r   pathzOptional[str]datazOptional[bytes]fileObjzOptional[Any]r   ztuple[bool, Any]r   r   r   r   r   r   S  s0      

  	r   c                sP   V f   Vf   Vf   Q hV e0   \        V R4      ;_uu_ 4       pVP                  ^4      pRRR4       MDVe   VR,          pM6Ve3   VP                  4       pVP                  ^4      pVP                  V4       X\        8w  d   R# R#   + '       g   i     L; i)z;
Version 3+.

This checks the signature of the image data.
NZrb:Ni   N)Fz,Image does not begin with the PNG signature.TN)r   ZreadZtellZseekr   )r   r   r   ZfZ	signatureZposs   &&&   r   pngValidatorr   S  s     t/73FFF$q	I 		H			llnLLO	SL DD s   BB%	c               r   )r   r   r   ufoPathOrFileSystemzUnion[str, fs.base.FS]r   tuple[bool, Optional[str]]r   r   r   r   r   r   q  s)     D DD%;DDr   c                s   \        V\        P                  P                  4      '       d   TpM\        P                  P                  V4      pRp\        V \        4      '       g   RV3# \        4       p\        4       p/ pV  EF"  p\        V\        4      '       g   RV3u # \        V4      ^8X  g   RV3u # V F!  p\        V\        4      '       d   K  RV3u u # 	  Vw  rV
R8w  d%   V
P                  R4      '       g   RRV
,          3u # \        V	4      ^ 8X  d   R
u # VP                  V
4      '       g   RRV
,          3u # V	R8X  d   V
R8w  d   Ru # W9   d   RRV	,          3u # VP                  V	4       W9   d   RR	V
,          3u # VP                  V
4       WV	&   EK%  	  RVP                  4       9   pV'       g   R# R# )z8
Check the validity of layercontents.plist.
Version 3+.
z1layercontents.plist in not in the correct format.FZglyphszglyphs.z3Invalid directory name (%s) in layercontents.plist.z A glyphset does not exist at %s.zpublic.defaultz1The layer name %s is used by more than one layer.z0The directory %s is used by more than one layer.)Fz(Empty layer name in layercontents.plist.)FzIThe name public.default is being used by a layer that is not the default.)Fz1The required default glyph set is not in the UFO.r   )r   fsZbaseZFSZosfsZOSFSr!   r#   r7   r;   
startswithZexistsr~   r   )r   r   Z
fileSystemZbogusFileMessageZusedLayerNamesZusedDirectoriesZcontentsZentryr   Z	layerNameZdirectoryNameZfoundDefaults   &&          r   layerContentsValidatorr   q  s    %rwwzz22(
WW\\"56
JeT""&&&UNeOH%&&***5zQ***Aa%%...  $) 	H$ ++I66I#$ 
 y>QDD  //<}LLL((]h-F 
 &CiO  	9%+B]R  	M*+W Z x00LIIr   c               r
   r   r   r   r   r   r   r   r   r   r   r     s     T T3 T#= Tr   c                s   Rp\        V 4      '       g   RV3# / p/ pV P                  4        EF  w  rE\        V\        4      '       g   RV3u # \        V\        \
        34      '       g   RV3u # V'       g   R	u # VP                  R4      '       g   Ki  VP                  R4      '       g   VP                  R4      '       g   K  \        R4      \        V4      8X  d   R
u # VP                  R4      '       d   TpMTpV FA  p\        V\        4      '       g   RRV,          3u u # Wv9   d   RRV,          3u u # WFV&   KC  	  EK  	  R# )a  
Check the validity of the groups.
Version 3+ (though it's backwards compatible with UFO 1 and UFO 2).

>>> groups = {"A" : ["A", "A"], "A2" : ["A"]}
>>> groupsValidator(groups)
(True, None)

>>> groups = {"" : ["A"]}
>>> valid, msg = groupsValidator(groups)
>>> valid
False
>>> print(msg)
A group has an empty name.

>>> groups = {"public.awesome" : ["A"]}
>>> groupsValidator(groups)
(True, None)

>>> groups = {"public.kern1." : ["A"]}
>>> valid, msg = groupsValidator(groups)
>>> valid
False
>>> print(msg)
The group data contains a kerning group with an incomplete name.
>>> groups = {"public.kern2." : ["A"]}
>>> valid, msg = groupsValidator(groups)
>>> valid
False
>>> print(msg)
The group data contains a kerning group with an incomplete name.

>>> groups = {"public.kern1.A" : ["A"], "public.kern2.A" : ["A"]}
>>> groupsValidator(groups)
(True, None)

>>> groups = {"public.kern1.A1" : ["A"], "public.kern1.A2" : ["A"]}
>>> valid, msg = groupsValidator(groups)
>>> valid
False
>>> print(msg)
The glyph "A" occurs in too many kerning groups.
z,The group data is not in the correct format.Fzpublic.zpublic.kern1.zpublic.kern2.zpublic.kernN.z-The group data %s contains an invalid member.z1The glyph "%s" occurs in too many kerning groups.)FzA group has an empty name.)Fz@The group data contains a kerning group with an incomplete name.r   )r   r   r   r;   r!   r"   r   r7   )r   bogusFormatMessageZfirstSideMappingZsecondSideMappingZ	groupNameZ	glyphListZd	glyphNames   &       r   groupsValidatorr     sQ   X H(((')(* %	)c++,,,)dE]33,,,66	**''88AUAUB B '3y>9  ##O44$%&	!)S11G)S  >KiW   )) '/ !.F r   c               r
   )r   r   r   r   r   r   r   r   r   r   r     s     $ $3 $#= $r   c                s   Rp\        V \        4      '       g   RV3# V P                  4        F  w  r#\        V\        4      '       g   RV3u # \        V\        4      '       g   RV3u # VP                  4        FA  w  rE\        V\        4      '       g	   RV3u u # \        V\        4      '       d   K;  RV3u u # 	  K  	  R# )a  
Check the validity of the kerning data structure.
Version 3+ (though it's backwards compatible with UFO 1 and UFO 2).

>>> kerning = {"A" : {"B" : 100}}
>>> kerningValidator(kerning)
(True, None)

>>> kerning = {"A" : ["B"]}
>>> valid, msg = kerningValidator(kerning)
>>> valid
False
>>> print(msg)
The kerning data is not in the correct format.

>>> kerning = {"A" : {"B" : "100"}}
>>> valid, msg = kerningValidator(kerning)
>>> valid
False
>>> print(msg)
The kerning data is not in the correct format.
z.The kerning data is not in the correct format.Fr   )r   r   r   r;   r	   )r   r   ZfirstZ
secondDictZsecondr   r   r   kerningValidatorr     s    . JdG$$(((!ZZ\%%%,,,J00,,,'--/MFfc**000{33000	 0 * r   z-The lib data is not in the correct format: %sc               r
   r   r   r   r   r   r   r   G  s     @ @C @$> @r   c                sN   \        V 4      '       g,   R\        V 4      P                  ,          pR\        V,          3# V P	                  4        F  w  r \        V\        4      '       g"   RR\        V4      P                  : RV: 23u # VR8X  g   KE  Rp\        V \        \        34      '       g)   R\        V 4      P                  ,          pRW1,          3u # V  FC  p\        V\        4      '       d   K  R\        V4      P                  ,          pRW1,          3u u # 	  K  	  R	# )
a>  
Check the validity of the lib.
Version 3+ (though it's backwards compatible with UFO 1 and UFO 2).

>>> lib = {"foo" : "bar"}
>>> fontLibValidator(lib)
(True, None)

>>> lib = {"public.awesome" : "hello"}
>>> fontLibValidator(lib)
(True, None)

>>> lib = {"public.glyphOrder" : ["A", "C", "B"]}
>>> fontLibValidator(lib)
(True, None)

>>> lib = "hello"
>>> valid, msg = fontLibValidator(lib)
>>> valid
False
>>> print(msg)  # doctest: +ELLIPSIS
The lib data is not in the correct format: expected a dictionary, ...

>>> lib = {1: "hello"}
>>> valid, msg = fontLibValidator(lib)
>>> valid
False
>>> print(msg)
The lib key is not properly formatted: expected str, found int: 1

>>> lib = {"public.glyphOrder" : "hello"}
>>> valid, msg = fontLibValidator(lib)
>>> valid
False
>>> print(msg)  # doctest: +ELLIPSIS
public.glyphOrder is not properly formatted: expected list or tuple,...

>>> lib = {"public.glyphOrder" : ["A", 1, "B"]}
>>> valid, msg = fontLibValidator(lib)
>>> valid
False
>>> print(msg)  # doctest: +ELLIPSIS
public.glyphOrder is not properly formatted: expected str,...
expected a dictionary, found %sFz;The lib key is not properly formatted: expected str, found z: zpublic.glyphOrderz/public.glyphOrder is not properly formatted: %sz expected list or tuple, found %szexpected str, found %sr   )	r   type__name___bogusLibFormatMessager   r   r;   r!   r"   )r   reasonr0   ZbogusGlyphOrderMessager   r   r   fontLibValidatorr   G  s    Z 2T%[5I5II,v555kkm
#s##9%%s, 
 %%%V"edE]33;d5k>R>RR4==="	!)S115Y8P8PPF "8"AAA # $  r   c               r
   r   r   r   r   r   r   r     s     # #S #%? #r   c                sL   \        V 4      '       g,   R\        V 4      P                  ,          pR\        V,          3# V P	                  4        FS  w  r \        V\        4      '       g   RV,          pR\        V,          3u # VR8X  g   K>  \        V 4      '       d   KQ  Ru # 	  R# )a  
Check the validity of the lib.
Version 3+ (though it's backwards compatible with UFO 1 and UFO 2).

>>> lib = {"foo" : "bar"}
>>> glyphLibValidator(lib)
(True, None)

>>> lib = {"public.awesome" : "hello"}
>>> glyphLibValidator(lib)
(True, None)

>>> lib = {"public.markColor" : "1,0,0,0.5"}
>>> glyphLibValidator(lib)
(True, None)

>>> lib = {"public.markColor" : 1}
>>> valid, msg = glyphLibValidator(lib)
>>> valid
False
>>> print(msg)
public.markColor is not properly formatted.
r   Fzkey (%s) should be a stringzpublic.markColor)Fz+public.markColor is not properly formatted.r   )r   r   r   r   r   r   r;   r   )r   r   r0   r@   r   glyphLibValidatorr     s    0 2T%[5I5II,v555kkm
#s##2S8F06999$$!%((KK $ r   Z__main__)N)NNN)V__conditional_annotations__Z__doc__Z
__future__r    r>   Zcollections.abcr   r   Zior   ZfontTools.misc.filesystemZmiscZ
filesystemr   Ztypingr   r   r   r   ZfontTools.annotationsr   ZfontTools.ufoLib.utilsr	   r8   r;   r"   r   r   r/   r   r   r%   r+   r-   r1   r3   r:   r?   rA   rC   rE   rI   rL   rN   rP   rR   rS   rT   rW   r`   rb   rg   rh   rl   rn   ro   re   rs   rr   rv   ru   rw   r   r$   r   r   Z__annotations__r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ZdoctestZtestmod)r   s   @r   <module>r      sq   ( "  -  & & - - * .3eD%S	3*?$?@$FGGH
" D<9x&
"&  "0
 

 "&$",& (,U|UU|U<

u,U|(  !R& %)U|UU|U
u,U|% k 6>CT +e *#'4[%L% 5\5!5\5!%L% 5\5!5\5!,	$ [ 	 <DXTx$V I @P#L zOO r   