
    ~+h                     <   d dl m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 ddl	m
Z
 dd	lmZmZmZmZmZmZmZmZ dd
lmZ ddlmZmZ ddlmZmZ ddlmZmZmZ ddlmZm Z  dZ!d Z" G d de#      Z$d Z% G d dee      Z& G d de#      Z'd Z(ddZ)ddZ*d Z+y)    )contextmanagerN)path)six)map)zip   )
get_filter)FileHunkUrlHunk
FilterToolmergemerge_filtersselect_filtersMoreThanOneFilterError	NoFilters)
SKIP_CACHE)BundleError
BuildError)cmp_debug_levels	hash_func)ConfigurationContextDictConfigStorageBaseEnvironment)is_urlcalculate_sri_on_file)Bundleget_all_bundle_filesc                 
    d| v S )Nz%(version)s )ss    C/var/www/html/venv/lib/python3.12/site-packages/webassets/bundle.pyhas_placeholderr"      s    A    c                   B    e Zd ZdZd	dZd Zd Zd Zd	dZe	d        Z
y)
ContextWrapperaz  Implements a hierarchy-aware configuration context.

    Since each bundle can provide settings that augment the values of
    the parent bundle, and ultimately the environment, as the bundle
    hierarchy is processed, this class is used to provide an interface
    that searches through the hierarchy of settings. It's what you get
    when you are given a ``ctx`` value.
    Nc                 "    ||c| _         | _        y N)_parent_overwrites)selfparent
overwritess      r!   __init__zContextWrapper.__init__#   s    )/&d&r#   c                     	 | j                   
t               | j                   j                  |   S # t        $ r( | j                  j                  j	                  |      cY S w xY wr'   )r)   KeyErrorconfigr(   get)r*   keys     r!   __getitem__zContextWrapper.__getitem__&   s\    	0'j ##**3// 	0<<&&**3//	0s   .1 .A"!A"c                     	 | j                  | j                  |      S # t        t        t        f$ r | j                  | j
                  |      cY S w xY wr'   )getattrr)   r/   AttributeErrorEnvironmentErrorr(   )r*   items     r!   __getattr__zContextWrapper.__getattr__.   sJ    	4<< 0 0$77.*:; 	4<<d33	4s    0AAc                 f    t        |t              rt        |j                  |      S t        ||      S r'   )
isinstancer   r5   r0   )r*   objectr8   s      r!   r5   zContextWrapper.getattr4   s,     ff%6==$//64((r#   c                 H    	 | j                  |      S # t        $ r |cY S w xY wr'   )r3   r/   )r*   r2   defaults      r!   r1   zContextWrapper.get<   s,    	##C(( 	N	s    !!c                 z    t        | j                  t              r| j                  S | j                  j                  S )z"Find the root environment context.)r;   r(   r   environmentr*   s    r!   r@   zContextWrapper.environmentB   s,     dllO4<<||'''r#   r'   )__name__
__module____qualname____doc__r-   r3   r9   r5   r1   propertyr@   r   r#   r!   r%   r%      s4    <04) ( (r#   r%   c                     t        | |      S )zReturn a context object where the values from ``overwrites``
    augment the ``parent`` configuration. See :class:`ContextWrapper`.
    )r%   )r+   r,   s     r!   wraprH   J   s     &*--r#   c                       e Zd ZdZd Zy)BundleConfigzA configuration dict that also supports Environment-like attribute
    access, i.e. ``config['resolver']`` and ``config.resolver``.
    c                 \    t        j                  | |       t        j                  | |        y r'   )r   r-   r   )r*   bundles     r!   r-   zBundleConfig.__init__U   s"    ""40%%dD1r#   N)rB   rC   rD   rE   r-   r   r#   r!   rJ   rJ   Q   s    2r#   rJ   c                   v   e Zd ZdZd Zd Zed        Zd Zd Z	 eee	      Z
d Zd Z eee      Zd	 Zd
 Z eee      Zd Zd Z eeed      Zd$dZed        Zd Zd Z eeed      Zd Zd$dZd%dZd Zed        Zed        Z d Z!d Z" ee!e"      Z#	 	 	 d&dZ$	 	 d&dZ%d'dZ&d  Z'd! Z(d" Z)d# Z*y)(r   a  A bundle is the unit webassets uses to organize groups of media files,
    which filters to apply and where to store them.

    Bundles can be nested arbitrarily.

    A note on the connection between a bundle and an "environment" instance:
    The bundle requires a environment that it belongs to. Without an
    environment, it lacks information about how to behave, and cannot know
    where relative paths are actually based. However, I don't want to make the
    ``Bundle.__init__`` syntax more complicated than it already is by requiring
    an Environment object to be passed. This would be a particular nuisance
    when nested bundles are used. Further, nested bundles are never explicitly
    connected to an Environment, and what's more, the same child bundle can be
    used in multiple parent bundles.

    This is the reason why basically every method of the Bundle class takes an
    ``env`` parameter - so a parent bundle can provide the environment for
    child bundles that do not know it.
    c                    |j                  dd       | _        || _        |j                  dd       | _        |j                  dd       | _        |j                  dg       | _        |j                  dg       | _        |j                  dd      | _        |j                  di       | _        |j                  d	d      | _	        t        |       | _        | j                  j                  |j                  d
i              d|v r"|j                  d      }||| j                  d<   |r(t        dt        |j                               d   z        y )Nenvoutputfiltersdependsversionremove_duplicatesTextrar   r0   debugz$got unexpected keyword argument '%s'r   )pop_envcontentsrP   rQ   rR   rS   rT   rU   r   rJ   _configupdate	TypeErrorlistkeys)r*   rY   optionsrV   s       r!   r-   zBundle.__init__o   s   KKt,	 kk(D1{{9d3{{9b1{{9b1!(-@$!G[["-
[[$/
#D)GKK"56gKK(E (-W%B 034 5 5 r#   c           	          d| j                   j                  d| j                  d| j                  d| j                  d	S )N<z output=z
, filters=z, contents=>)	__class__rB   rP   rQ   rY   rA   s    r!   __repr__zBundle.__repr__   s.    NN##KKLLMM	
 	
r#   c                     | j                   S r'   )rZ   rA   s    r!   r0   zBundle.config   s     ||r#   c                 :    | j                   j                  dd       S NrV   )r0   r1   rA   s    r!   
_get_debugzBundle._get_debug   s    {{w--r#   c                 "    || j                   d<   y rg   )r0   r*   values     r!   
_set_debugzBundle._set_debug   s    $Gr#   c                     | j                   S r'   )_filtersrA   s    r!   _get_filterszBundle._get_filters       }}r#   c                    |d| _         yt        |t        j                        rmt        j                  r*t        t        j                  |j                  d            }nOt        t        j                  t        |      j                  d            }nt        |t        t        f      r|}n|g}|D cg c]  }t        |       c}| _         yc c}w )zFilters may be specified in a variety of different ways, including
        by giving their name; we need to make sure we resolve everything to an
        actual filter instance.
        Nr   ,)rn   r;   r   string_typesPY3r   strstripsplitunicoder]   tupler	   )r*   rk   rQ   fs       r!   _set_filterszBundle._set_filters   s    
 =DMeS--.wwciiS)9:gmmWU^-A-A#-FGe}-GgG0781A88s   2Cc                     | j                   S r'   )	_contentsrA   s    r!   _get_contentszBundle._get_contents   s    ~~r#   c                      || _         d | _        y r'   )r}   _resolved_contentsrj   s     r!   _set_contentszBundle._set_contents   s    "&r#   c                     | j                   sHt        |       s=i }| j                  D ]*  }|j                  |j	                  |j                         , |S | j                   S r'   )_extra	has_filesrY   rU   r[   )r*   resultrL   s      r!   
_get_extrazBundle._get_extra   sT    {{9T? F-- 0<<+MM&,,/0 M;;r#   c                     || _         y r'   )r   rj   s     r!   
_set_extrazBundle._set_extra   s	    r#   zA custom user dict of
    extra values attached to this bundle. Those will be available in
    template tags, and can be used to attach things like a CSS
    'media' value.)docNc                 0   |st        | j                  |       }t        | dd      |rg }| j                  D ]}  	 |j                  j                  |      }t        |t              s|g}| j                  r!	 |j                  | j                  |             |j                  t        fd|              | j                   r| j#                  |      }|| _        | j$                  S # t        $ r}t        |      d}~ww xY w# t        t        f$ r Y }w xY w)aF  Return an actual list of source files.

        What the user specifies as the bundle contents cannot be
        processed directly. There may be glob patterns of course. We
        may need to search the load path. It's common for third party
        extensions to provide support for referencing assets spread
        across multiple directories.

        This passes everything through :class:`Environment.resolver`,
        through which this process can be customized.

        At this point, we also validate source paths to complain about
        missing files early.

        The return value is a list of 2-tuples ``(original_item,
        abspath)``. In the case of urls and nested bundles both tuple
        values are the same.

        Set ``force`` to ignore any cache, and always re-resolve
        glob  patterns.
        r   Nc                     | fS r'   r   )rr8   s    r!   <lambda>z)Bundle.resolve_contents.<locals>.<lambda>   s    tQi r#   )rH   rO   r5   rY   resolverresolve_sourceIOErrorr   r;   r]   rP   removeresolve_output
ValueErrorextendr   rT   _filter_duplicatesr   )r*   ctxforceresolvedr   er8   s         @r!   resolve_contentszBundle.resolve_contents   s   , txx&C 4-t4<H B) \\88dCF "&$/$XF ;;d&9&9#&>? $7 @A)B0 %%228<&.D#&&&5  )%a.() '4 s)   C'7 D'	D 0C;;D DDc                     t               }g }| D ].  \  }}||vs|j                  |       |j                  ||f       0 |S r'   )setaddappend)r   
seen_filesr   r8   r   s        r!   r   zBundle._filter_duplicates  sN     U
 	)GD!
"q!tQi(	) r#   c                     | j                   S r'   )_dependsrA   s    r!   _get_dependszBundle._get_depends  rp   r#   c                 Z    t        |t        j                        r|gn|| _        d | _        y r'   )r;   r   rs   r   _resolved_dependsrj   s     r!   _set_dependszBundle._set_depends  s$    #-eS5E5E#FE!%r#   zAllows you to define an additional set of files (glob syntax
    is supported), which are considered when determining whether a
    rebuild is required.
    c                 >   | j                   sg S t        | dd       [g }| j                   D ]C  }	 |j                  j                  ||      }t        |t              s|g}|j                  |       E || _	        | j                  S # t        $ r}t        |      d }~ww xY w)Nr   )
rR   r5   r   r   r   r   r;   r]   r   r   )r*   r   r   r8   r   r   s         r!   resolve_dependszBundle.resolve_depends  s    ||I4,d3;H () \\88dCF "&$/$XF'( &.D"%%%  )%a.()s   B	BBBc                    |st        | j                  |       }| j                  r|r|d}|j                  r|j                  j	                  | |      }|s6ddlm} |j                  r"	 |j                  j                  | |      }|sJ nd}|st        d| d      || _        | j                  S # |$ r}|}Y d}~2d}~ww xY w)a  Return the current version of the Bundle.

        If the version is not cached in memory, it will first look in the
        manifest, then ask the versioner.

        ``refresh`` causes a value in memory to be ignored, and the version
        to be looked up anew.
        Nr   )VersionIndeterminableErrorz"versions" option not setzCannot find version of zb. There is no manifest which knows the version, and it cannot be determined dynamically, because: )	rH   rO   rS   manifestqueryr   versionsdetermine_versionr   )r*   r   refreshrS   r   r   reasons          r!   get_versionzBundle.get_version0  s     txx&C||wG||,,,,T37?<<#"%,,"@"@s"K&w 9F! ?CF#L M M #DL|| 6 #!"#s   & B/ /C 4B;;C c                     |st        | j                  |       }|j                  j                  || j                  |       }t        |      r|d|xs | j                  |      iz  }|S )znReturn the full, absolute output path.

        If a %(version)s placeholder is used, it is replaced.
        rS   )rH   rO   r   resolve_output_to_pathrP   r"   r   )r*   r   rS   rP   s       r!   r   zBundle.resolve_outputS  s_    
 txx&C44S$++tL6"y'*JT5E5Ec5JKKFr#   c                     t        t        | j                        | j                  t        | j                        t        | j                        f      S )zThis is used to determine when a bundle definition has changed so
        that a rebuild is required.

        The hash therefore should be built upon data that actually affect the
        final build result.
        )r   ry   rY   rP   rQ   boolrV   rA   s    r!   idz	Bundle.id_  s@     %.[[4<<($**%' ( 	(r#   c                 8    t        |        xr | j                   S )zReturn true if this is a container bundle, that is, a bundle that
        acts only as a container for a number of sub-bundles.

        It must not contain any files of its own, and must have an empty
        ``output`` attribute.
        )r   rP   rA   s    r!   is_containerzBundle.is_containero  s     T?"64;;6r#   c              #   b   K   | j                   }|| _         	 d  || _         y # || _         w xY wwr'   rX   )r*   rO   old_envs      r!   bindzBundle.bindy  s,     ))		 DIDIs   /# /	,/c                 H    | j                   t        d      | j                   S )Nz)Bundle is not connected to an environment)rX   r   rA   s    r!   _get_envzBundle._get_env  s"    99IJJyyr#   c                     || _         y r'   r   )r*   rO   s     r!   _set_envzBundle._set_env  s	    	r#   c           
         |xs g }|xs g }||n|j                   }t        || ||      }|du rd}t        | j                  |      }	|	D ]#  }
|
j	                  |       |
j                          % t        |	|      }t        |t        ||            }t        |	|      }| j                  |d      }|xs t        | j                  |            }t        |j                  ||d   |d   d	      }g }|D ]  \  }}t        |t              r8|j                  t        ||      |||||
      }|:|j!                  |i f       N	 |j#                  |d|gd|it%        |      st'        |      gng       }||d}|j1                  ||d|      }|j!                  ||f        t3        |      dk(  ry	 	 |j#                  |d|g      }|j1                  ||d      S # t(        $ r}t+        |      d}~wt,        $ r' t%        |      rt/        ||      }nt'        |      }Y w xY w# t(        $ r}t+        |      d}~wt,        $ r( t5        |D cg c]  \  }}|	 nc c}}w c}}      }Y w xY w# t6        $ r}t+        |      d}~ww xY w)a   Internal recursive build method.

        ``parent_debug`` is the debug setting used by the parent bundle. This
        is not necessarily ``bundle.debug``, but rather what the calling method
        in the recursion tree is actually using.

        ``parent_filters`` are what the parent passes along, for us to be
        applied as input filters. Like ``parent_debug``, it is a collection of
        the filters of all parents in the hierarchy.

        ``extra_filters`` may exist if the parent is a container bundle passing
        filters along to its children; these are applied as input and output
        filters (since there is no parent who could do the latter), and they
        are not passed further down the hierarchy (but instead they become part
        of ``parent_filters``.

        ``disable_cache`` is necessary because in some cases, when an external
        bundle dependency has changed, we must not rely on the cache, since the
        cache key is not taking into account changes in those dependencies
        (for now).
        N)r>   TF)r   r   r   )rP   output_path)no_cache_readkwargs)disable_cacheopensource)r   	cache_key)rO   )r   source_pathinput)r   concatrP   )rV   _effective_debug_levelr   rQ   set_contextsetupr   r   r   r   r   cacher;   r   _merge_and_applyrH   r   
apply_funcr   r
   r   r   r   r   applylenr   r   )r*   r   rP   r   parent_debugparent_filtersextra_filtersr   current_debug_levelrQ   filterselected_filtersfilters_to_runfilters_to_pass_downresolved_contentsactually_skip_cache_here
filtertoolhunksr8   cnthunkr   	item_datafinalh_s                             r!   r   zBundle._merge_and_apply  s   2 (-2%+ (4'?|SYY4}l< $&"'  m<
  	Fs# LLN	 *'3FG 'n^=PQS,WnE !11#T1B $1#SD9M9Mc9R4S II%=$Qi#)!9./
 * -	0ID##v&++cNFE3F( , G #LL$,-%00& !)$/ :@8C=/" 1 ND8 (,C@	 "''ng3< ( >dI./[-	0b u:?	 5"--nhP$ '7BB_ . ($Q-'  -c{&s4'}-8 * $ m# 5U3TQq3345 	 
 Q-	 sf   0G3H$ 	H!#G..0H! H!$	I,-H88I,II,)I/ +I,,I/ /	J8JJc                    |xs g }| j                   st        d| z        |rd}n|t        | j                         s2t        j                  | j                  || j                               sd}n5|j                  r|j                  j                  | |      nd}|t        k(  rd}|s%t        | j                  || j                               S | j                  || j                   | j                  |d      g|||      }|t        d| z        |r!|j                  |j                                nt        | j                         r|j                  st        d| z        d}|j                  r|j                  j                  | ||      }| j                  ||      }	t        j                  |	      }
t        j                  |
      st!        j"                  |
       |j%                  |	       || _        |j(                  r|j(                  j+                  | ||       |j                  r |r|j                  j-                  | ||	|       |j                  r|j                  j/                  | |       |S )	a  Internal bundle build function.

        This actually tries to build this very bundle instance, as opposed to
        the public-facing ``build()``, which first deals with the possibility
        that we are a container bundle, i.e. having no files of our own.

        First checks whether an update for this bundle is required, via the
        configured ``updater`` (which is almost always the timestamp-based one).
        Unless ``force`` is given, in which case the bundle will always be
        built, without considering timestamps.

        A ``FileHunk`` will be returned, or in a certain case, with no updater
        defined and force=False, the return value may be ``False``.

        TODO: Support locking. When called from inside a template tag, this
        should lock, so that multiple requests don't all start to build. When
        called from the command line, there is no need to lock.
        zNo output target found for %sT?)rS   )r   r   Nz!Nothing to build for %s, is emptyz^You have not set the "versions" option, but %s uses a version placeholder in the output target)rP   r   r"   r   existsr   updaterneeds_rebuildr   r
   r   writedatar   r   dirnameosmakedirssaverS   r   rememberset_version
build_done)r*   r   r   r   rP   r   update_neededr   rS   output_filename
output_dirs              r!   _buildzBundle._build@  s   ( &+{{<tCDD  M -KK 3 3C EF M ;;  KK55dC@$( j( $D//T[[ABB$$$++t2232DEm % M <@4GHHLL%t{{+CLL F! !
 G||,,88sDI"11#w1GO o6J;;z*J'IIo&"DL||%%dC9|| ((sOWM
 ;;KK""4-r#   c           
          t        | j                  |       }g }| j                  |      D ]+  \  }}}|j                  |j	                  |||||             - |S )a.  Build this bundle, meaning create the file given by the ``output``
        attribute, applying the configured filters etc.

        If the bundle is a container bundle, then multiple files will be built.

        Unless ``force`` is given, the configured ``updater`` will be used to
        check whether a build is even necessary.

        If ``output`` is a file object, the result will be written to it rather
        than to the filesystem.

        The return value is a list of ``FileHunk`` objects, one for each bundle
        that was built.
        )r   rP   r   )rH   rO   	iterbuildr   r   )	r*   r   rP   r   r   r   rL   r   new_ctxs	            r!   buildzBundle.build  sg     488T".2nnS.A 	.*FM7LLeF+ ' - .	. r#   c              #   4  K   | j                   r| j                  |      D ]l  \  }}|j                   r@|j                  t        ||            D ]!  \  }}}|t	        || j
                        |f # R|| j
                  t        ||      f n y| g |f yw)a  Iterate over the bundles which actually need to be built.

        This will often only entail ``self``, though for container bundles
        (and container bundle hierarchies), a list of all the non-container
        leafs will be yielded.

        Essentially, what this does is "skip" bundles which do not need to be
        built on their own (container bundles), and gives the caller the child
        bundles instead.

        The return values are 3-tuples of (bundle, filter_list, new_ctx), with
        the second item being a list of filters that the parent "container
        bundles" this method is processing are passing down to the children.
        N)r   r   r   rH   r   rQ   )r*   r   rL   r   childchild_filtersr   s          r!   r   zBundle.iterbuild  s      !2237 	B	&&",,T#v->?%5}g ")-F#% %% !$,,S&0AAA	B C-s   BBc                 h   d}t        | j                        s|j                  dk7  r| j                  ||j                        }| j                  }t        |      r|d|iz  }|j
                  j                  ||      }|j                  s!|j                  t        | j                        s|d|}|S )zDReturn the output url, modified for expire header handling.
        NF)r   rS   r   )r"   rP   
url_expirer   
auto_buildr   resolve_output_to_url)r*   r   rS   urls       r!   _make_output_urlzBundle._make_output_url  s    
 4;;'3>>U+B &&sCNN&CGkk3G,,Cll00c:>>&t{{/K '*C
r#   c           
         |j                  dd      }t        || |      }|dk(  rd}n|du rd}n|du rd}nt        d|z        |r| j                  s| j                  r||j
                  r | j                  |g||dd| |rC| j                  |      t        |j                  j                  || j                  |             dgS | j                  |      gS g }| j                  |      D ]  \  }	}
t        |
t              rG|j                   |	j                  t!        ||
      t#        || j                        g|d|i|       ^t%        |
      r)|r|j'                  |
dd       |j'                  |
       d}	 |j                  j)                  ||
|	      }|r&t        |j                  j                  ||
|	            }|r|j'                  ||d       |j'                  |        |S # t*        $ rT t-        ||
      }|j                  j)                  |||	      }|r&t        |j                  j                  |||	            }Y w xY w)	zReturn a list of urls for this bundle, and all subbundles,
        and, when it becomes necessary, start a build process.
        calculate_sriFr   TzInvalid debug value: %s)r   r   )urisriN)rW   r   r   rQ   rP   r   r   r  r   r   r   r   r;   r   r   _urlsrH   r   r   r   resolve_source_to_urlr   pull_external)r*   r   r   argsr   r  rV   supposed_to_mergeurlsorgr   r  r  externals                 r!   r  zBundle._urls  sr   
 

?E: 'sD-@G $d] %e^ $7%?@@ $,,$++ ~~C -!-}E -%+- $ 5 5c : 5cll6Y6YZ]_c_j_jlp6q rt u u --c233
 D 11#6  )Sc6*KK			S#%mT\\B!" !" '4	!"
 !!" # C[$C$=>C(Cq!ll@@c3O("78[8[\_adfi8j"kC %C$<=C(A )B K & q $1c#:!ll@@hPST("78[8[\_aikn8o"pCqs   AG44AIIc                     t        | j                  |       }g }| j                  |      D ],  \  }}}|j                   |j                  ||g|i |       . |S )a  Return a list of urls for this bundle.

        Depending on the environment and given options, this may be a single
        url (likely the case in production mode), or many urls (when we source
        the original media files in DEBUG mode).

        Insofar necessary, this will automatically create or update the files
        behind these urls.

        :param calculate_sri: Set to true to calculate a sub-resource integrity
        string for the URLs. This changes the returned format.

        :return: List of URIs if calculate_sri is False. If calculate_sri is
                 true: list of {'uri': '<uri>', 'sri': '<sri-hash>'}.
        )rH   rO   r   r   r  )r*   r  r   r   r  rL   r   r   s           r!   r  zBundle.urls.  sb      488T".2nnS.A 	O*FM7KKWmMdMfMN	Or#   )NFNN)NNNN)NNN)+rB   rC   rD   rE   r-   rd   rF   r0   rh   rl   rV   ro   r{   rQ   r~   r   rY   r   r   rU   r   staticmethodr   r   r   rR   r   r   r   r   r   r   r   r   r   rO   r   r   r   r   r  r  r  r   r#   r!   r   r   Z   sQ   (5,
  
.%Z,E9( |\2G' }5H
Z 2 E
<'| 	 	& |\	G&"!F

(  7 7    
8X
&C@D<@'+tCl BF!Un. :*L\r#   r   c                    t        |      }t        j                  d|dt        j                  |            }t        j                  | j                  |      }t        j
                  |      rd } ||       ||      kD  r|S t        j                  |      }t        j                  |      st        j                  |       t        |      j                  |       |S )zHelper which will pull ``filename`` into
    :attr:`Environment.directory`, for the purposes of being able to
    generate a url for it.
    zwebassets-externalr   c                 @    t        j                  |       j                  S r'   )r   statst_mtime)ps    r!   r   zpull_external.<locals>.<lambda>U  s    rwwqz** r#   )r   r   joinbasename	directoryisfiler   r   r   r   r
   r   )r   filenamehashed_filenamerel_path	full_pathgsr  s          r!   r
  r
  E  s      )Oyy-"DMM($;<>H		#--2I {{9*i=2h<'Y'I;;y!
IXI&r#   c           
         |st        | j                  |       }t        |t              st        |      }g }| j	                  |      D ]w  \  }}t        |t
              r&|j                  t        |t        ||                   nt        |      s|j                  |       |j                  | j                  |             y |S )zReturn a flattened list of all source files of the given bundle, all
    its dependencies, recursively for all nested bundles.

    Making this a helper function rather than a part of the official
    Bundle feels right.
    )rH   rO   r;   r%   r   r   r   r   r   r   r   )rL   r   filesr   cs        r!   r   r   _  s     6::v&c>*S!E'', 21a LL-ac1>?LLOV++C012 Lr#   c                    || j                   j                  }|j                  j                  d      |j                  j                  }n&t	        |j
                  |      }t        |d      rdnd}|t        ||      dkD  r|S |S )a@  This is a helper used both in the urls() and the build() recursions.

    It returns the debug level that this bundle, in a tree structure
    of bundles, should use. It looks at any bundle-specific ``debug``
    attribute, considers an automatic upgrade to "merge" due to filters that
    are present, and will finally use the value in the ``default`` argument,
    which in turn defaults to ``env.debug``.

    It also ensures our rule that in a bundle hierarchy, the debug level may
    only ever be lowered. Nested bundle may lower the level from ``True`` to
    ``"merge"`` to ``False``, but never in the other direction. Which makes
    sense: If a bundle is already being merged, we cannot start exposing the
    source urls a child bundle, not if the correct order should be maintained.

    And while in theory it would seem possible to switch between full-out
    production (debug=False) and ``"merge"``, the complexity there, in
    particular with view as to how certain filter types like input() and
    open() need to be applied to child bundles, is just not worth it.
    NrV   Tr   r   )r@   rV   r0   r1   r   rQ   r   r   )r   rL   r   r>   levelrQ   s         r!   r   r   t  s    ( //''}}!-##
  >)'48d
 GU+a/LNr#   c           	      t    t        | j                  D cg c]  }t        |t              r| c}      S c c}w r'   )anyrY   r;   r   )rL   r#  s     r!   r   r     s*    M1z!V7LQMN Ms   55r'   r  ),
contextlibr   r   r   	webassetsr   webassets.six.movesr   r   r   r	   r   r
   r   r   r   r   r   r   r   r   
exceptionsr   r   utilsr   r   rO   r   r   r   r   r   __all__r"   r<   r%   rH   rJ   r   r
  r   r   r   r   r#   r!   <module>r.     s    % 	   # # G G G  / . I I 0 ..(V .(b.2$&: 2hV hV4*'TO	r#   