
    <i}-                     f    S r SSKrSSKJrJr  S rS rS rS rS r	S	 r
S
 rS rS rSS jrS rg)z*Utility functions for STIX2 data markings.    N)
exceptionsutilsc                 v    [        U 5       H)  u  p#SR                  U5      nXA:X  d  M  U(       d  M&  U/s  $    / $ )a  Walk an SDO or SRO generating selectors to match against ``selector``.

If a match is found and the the value of this property is present in the
objects. Matching value of the property will be returned.

Args:
    obj: An SDO or SRO object.
    selector (str): A string following the selector syntax.

Returns:
    list: Values contained in matching property. Otherwise empty list.

.)iterpathjoin)objselectoritemsvaluepaths        N/home/james-whalen/.local/lib/python3.13/site-packages/stix2/markings/utils.py_evaluate_expressionr      s9     !xx7N	 & I    c                 L    [        [        X5      5      n[        U5      S:  a  gg)z)Evaluate each selector against an object.   TN)listr   len)r	   r
   resultss      r   _validate_selectorr      s&    '67G
7|q r   c                 P    [        U 5      R                  S:X  a  U R                  $ U $ )NMarkingDefinition)type__name__id)markings    r   _get_marking_idr   '   s$    G}!44zzNr   c                     U(       a0  U H)  n[        X5      (       a  M  [        R                  " X5      e   g[        R                  " X5      e)z7Given an SDO or SRO, check that each selector is valid.N)r   r   InvalidSelectorError)r	   	selectorsss      r   validater"   -   sA    A%c-- 55c==  	

)
)#
99r   c                 >    U b  [        U [        5      (       a  U $ U /$ g)z1Convert input into a list for further processing.N)
isinstancer   )datas    r   convert_to_listr&   8   s&    dD!!K6M	 r   c                     U b=  [        U [        5      (       a  U  Vs/ s H  n[        U5      PM     sn$ [        U 5      /$ gs  snf )z1Convert input into a list of marking identifiers.N)r$   r   r   )r%   xs     r   convert_to_marking_listr)   A   sE    dD!!0451OA&55#D)**	 5s   Ac                 <   U (       d  g[         R                  " [        5      nU  H  nUR                  S5      (       a1  XR                  S5         R	                  UR                  S5      5        UR                  S5      (       d  Mb  XR                  S5         R	                  UR                  S5      5        M     UR                  5        VVs/ s H<  u  p4[        R                  " U5      (       a  U[        U5      S.OU[        U5      S.PM>     snnnU$ s  snnf )a  Compress granular markings list.

If there is more than one marking identifier matches. It will collapse into
a single granular marking.

Example:
    >>> compress_markings([
    ...     {
    ...         "selectors": [
    ...             "description"
    ...         ],
    ...         "marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
    ...     },
    ...     {
    ...         "selectors": [
    ...             "name"
    ...         ],
    ...         "marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
    ...     }
    ... ])
    [
        {
            "selectors": [
                "description",
                "name"
            ],
            "marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
        }
    ]

Args:
    granular_markings: The granular markings list property present in a
        SDO or SRO.

Returns:
    list: A list with all markings collapsed.

Nmarking_refr    langr+   r    r,   r    )	collectionsdefaultdictsetgetupdater   r   
is_markingsorted)granular_markingsmap_granular_markingitemr    
compresseds         r   compress_markingsr;   J   s   N ""3'D-..%%m45<<=M=Q=QR]=^_''%%f-.556F6J6J;6WX . $(::<		
 $0 %% !vi/@Ay(9:; $0		
  	
s   ADc           	      J   / nU  H  nUR                  S5      nUR                  S5      nUR                  S5      nU(       a%  UR                  U Vs/ s H  nXF/S.PM
     sn5        U(       d  Mk  UR                  U Vs/ s H  nXV/S.PM
     sn5        M     U$ s  snf s  snf )a  Expand granular markings list.

If there is more than one selector per granular marking. It will be
expanded using the same marking_ref.

Example:
    >>> expand_markings([
    ...     {
    ...         "selectors": [
    ...             "description",
    ...             "name"
    ...         ],
    ...         "marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
    ...     }
    ... ])
    [
        {
            "selectors": [
                "description"
            ],
            "marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
        },
        {
            "selectors": [
                "name"
            ],
            "marking_ref": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9"
        }
    ]

Args:
    granular_markings: The granular markings list property present in a
        SDO or SRO.

Returns:
    list: A list with all markings expanded.

r    r+   r,   r-   r.   )r2   extend)r6   expandedr   r    r+   r,   r
   s          r   expand_markingsr?      s    N H$KK,	kk-0{{6"OO %.$- %0jI$- 4OO %.$- "
;$- %( Os   B
?B 
c                     S[        U 5      0$ )zLReturn a dictionary with the required structure for a granular marking.
    r6   )r?   )r8   s    r   build_granular_markingrA      s      1A!BCCr   c              #   .  #    Uc  / n[        [        U R                  5       5      5       H  u  p#UR                  U5        X4v   [	        U[
        5      (       a  [        X15       H  nUv   M	     O[	        U[        5      (       az  U Ht  nSR                  UR                  U5      5      nUR                  U5        X4v   [	        U[
        5      (       a  [        XA5       H  nUv   M	     UR                  5         Mv     UR                  5         M     g7f)a  Generator which walks the input ``obj`` model.

Each iteration yields a tuple containing a list of ancestors and the
property value.

Args:
    obj: An SDO or SRO object.
    path: None, used recursively to store ancestors.

Example:
    >>> for item in iterpath(obj):
    >>>     print(item)
    (['type'], 'campaign')
    ...
    (['cybox', 'objects', '[0]', 'hashes', 'sha1'], 'cac35ec206d868b7d7cb0b55f31d9425b075082b')

Returns:
    tuple: Containing two items: a list of ancestors and the
        property value.

Nz[{0}])iterr5   r   appendr$   dictr   r   formatindexpop)r	   r   varnamevarobjr9   rG   
descendants          r   r   r      s     , |syy{ 34Gnfd## .
 / %%v||D'9:E"l"dD))&.t&:
(( '; 
  	
/ 5s   DDc                 v   U R                  SS5      S:X  Ga"  U S   S   nUS:X  az  US:X  a  SnOSnU S	   S
:w  a  [        R                  " U S	   U5      e[        R                  " U S   5      S:w  a.  [        R                  " [        R                  " U S   5      U5      eg US:X  az  US:X  a  SnOSnU S	   S:w  a  [        R                  " U S	   U5      e[        R                  " U S   5      S:w  a.  [        R                  " [        R                  " U S   5      U5      eg US:X  az  US:X  a  SnOSnU S	   S:w  a  [        R                  " U S	   U5      e[        R                  " U S   5      S:w  a.  [        R                  " [        R                  " U S   5      U5      eg US:X  az  US:X  a  SnOSnU S	   S:w  a  [        R                  " U S	   U5      e[        R                  " U S   5      S:w  a.  [        R                  " [        R                  " U S   5      U5      eg [        R                  " U S	   S5      eg )Ndefinition_type tlp
definitionwhitez2.0z{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp", "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition"}z{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp", "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "name": "TLP:WHITE", "type": "marking-definition", "spec_version": "2.1"}r   z8marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9createdz2017-01-20T00:00:00.000Zgreenz{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp", "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition"}z{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp", "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "name": "TLP:GREEN", "type": "marking-definition", "spec_version": "2.1"}z8marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41daamberz{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp", "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition"}z{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp", "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "name": "TLP:AMBER", "type": "marking-definition", "spec_version": "2.1"}z8marking-definition--f88d31f6-486f-44da-b317-01333bde0b82redz{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp", "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition"}z{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp", "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "name": "TLP:RED", "type": "marking-definition", "spec_version": "2.1"}z8marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5edz)Does not match any TLP Marking definition)r2   r   TLPMarkingDefinitionErrorr   format_datetime)marking_objspec_versioncolorwgars          r   check_tlp_markingr_     s    ("-6L)%0Gu$w L 
 4 $^^ ::;t;LaPP&&{9'=>B\\ ::5;P;PQ\]fQg;hjkll ] gu$w L 
 4 $^^ ::;t;LaPP&&{9'=>B\\ ::5;P;PQ\]fQg;hjkll ] gu$w L 
 4 $^^ ::;t;LaPP&&{9'=>B\\ ::5;P;PQ\]fQg;hjkll ] e^u$w L 
 4 $^^ ::;t;LaPP&&{9'=>B\\ ::5;P;PQ\]fQg;hjkll ] 66{47HJuvvQ 7r   )N)__doc__r/   stix2r   r   r   r   r   r"   r&   r)   r;   r?   rA   r   r_    r   r   <module>rc      sK    0  #.:+;|=@D0fKwr   