Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
collections.cpython-313.pyc549 linesDownload Raw Back to __pycache__
1�

2��j���3�|�%SrSSKJr SSKrSSKrSSKrSSKJr SSKJr SSKJr SSKJ	r	 SSKJ4r5 SS	KJr SS6KJr SSKJ
r
 SSKJr SS
KJr SSKJr SSKJr SSKJr SSKJr SSKJr SSKrSSKJr SSKJr SSKJr SSKJr SSKJr SSK J!r! \R$(a*SSK"J#r# SSK"J$r$ SSK%J&q& SSK%J'q' SSK%J(q( SS K%J)q) SS!K*J+r+ /S"Qr,\RZ"5r.\/S#4r/\"S$\S%9r0\"S&\S%9r1\"S'\S%9r2\"S(S)S%9r3\"S*S+S%9r4"S,S-\!5r5"S.S#\!5r6"S/S05r7\(aSXS2jr8O\Rr"S35r8"S4S15r:SYS5jr;SZS6jr<S7r=S8r>S9r?S:r@S;rAS<rBSYS=jrCS>rDS?rESYS@jrFS[SAjrGS[SBjrH\I\J4rKS\SCjrLS\SDjrMS[SEjrN"SFSG\\05rO"SHSI\\05rP"SJSK\7\1\245rQ\R�"\S\O\I\P\T\Q05rUSL\VSM'\R�"\SSNSOSPSQ.\G"54\ISRSOSPSQ.\N"54\TSSST0\H"5405rWSU\VSV'SWrX\X"\Y"55 g)]aLSupport for collections of mapped entities.8 9The collections package supplies the machinery used to inform the ORM of10collection membership changes.  An instrumentation via decoration approach is11used, allowing arbitrary types (including built-ins) to be used as entity12collections without requiring inheritance from a base class.13 14Instrumentation decoration relays membership change events to the15:class:`.CollectionAttributeImpl` that is currently managing the collection.16The decorators observe function call arguments and return values, tracking17entities entering or leaving the collection.  Two decorator approaches are18provided.  One is a bundle of generic decorators that map function arguments19and return values to events::20 21  from sqlalchemy.orm.collections import collection22 23 24  class MyClass:25      # ...26 27      @collection.adds(1)28      def store(self, item):29          self.data.append(item)30 31      @collection.removes_return()32      def pop(self):33          return self.data.pop()34 35The second approach is a bundle of targeted decorators that wrap appropriate36append and remove notifiers around the mutation methods present in the37standard Python ``list``, ``set`` and ``dict`` interfaces.  These could be38specified in terms of generic decorator recipes, but are instead hand-tooled39for increased efficiency.  The targeted decorators occasionally implement40adapter-like behavior, such as mapping bulk-set methods (``extend``,41``update``, ``__setslice__``, etc.) into the series of atomic mutation events42that the ORM requires.43 44The targeted decorators are used internally for automatic instrumentation of45entity collection classes.  Every collection class goes through a46transformation process roughly like so:47 481. If the class is a built-in, substitute a trivial sub-class492. Is this class already instrumented?503. Add in generic decorators514. Sniff out the collection interface through duck-typing525. Add targeted decoration to any undecorated interface method53 54This process modifies the class at runtime, decorating methods and adding some55bookkeeping properties.  This isn't possible (or desirable) for built-in56classes like ``list``, so trivial sub-classes are substituted to hold57decoration::58 59  class InstrumentedList(list):60      pass61 62Collection classes can be specified in ``relationship(collection_class=)`` as63types or a function that returns an instance.  Collection classes are64inspected and instrumented during the mapper compilation phase.  The65collection_class callable will be executed once to produce a specimen66instance, and the type of that specimen will be instrumented.  Functions that67return built-in types like ``lists`` will be adapted to produce instrumented68instances.69 70When extending a known type like ``list``, additional decorations are not71generally not needed.  Odds are, the extension method will delegate to a72method that's already instrumented.  For example::73 74  class QueueIsh(list):75      def push(self, item):76          self.append(item)77 78      def shift(self):79          return self.pop(0)80 81There's no need to decorate these methods.  ``append`` and ``pop`` are already82instrumented as part of the ``list`` interface.  Decorating them would fire83duplicate events, which should be avoided.84 85The targeted decoration tries not to rely on other methods in the underlying86collection class, but some are unavoidable.  Many depend on 'read' methods87being present to properly instrument a 'write', for example, ``__setitem__``88needs ``__getitem__``.  "Bulk" methods like ``update`` and ``extend`` may also89reimplemented in terms of atomic appends and removes, so the ``extend``90decoration will actually perform many ``append`` operations and not call the91underlying method at all.92 93Tight control over bulk operation and the firing of events is also possible by94implementing the instrumentation internally in your methods.  The basic95instrumentation package works under the general assumption that collection96mutation will not raise unusual exceptions.  If you want to closely97orchestrate append and remove events with exception management, internal98instrumentation may be the answer.  Within your method,99``collection_adapter(self)`` will retrieve an object that you can use for100explicit control over triggering append and remove events.101 102The owning object and :class:`.CollectionAttributeImpl` are also reachable103through the adapter, allowing for some very sophisticated behavior.104 105�)�annotationsN)�Any)�Callable)�cast)�106Collection)�Dict)�Iterable)�List)�NoReturn)�Optional)�Set)�Tuple)�Type)�
TYPE_CHECKING)�TypeVar)�Union�)�NO_KEY�)�exc)�util��NO_ARG)�inspect_getfullargspec)�Protocol)�AttributeEventToken)�CollectionAttributeImpl��attribute_keyed_dict��column_keyed_dict��keyfunc_mapping��KeyFuncDict)�
InstanceState)107�108collection�collection_adapterr#r!rr%�mapped_collection�column_mapped_collection�attribute_mapped_collection�MappedCollection�_AdaptedCollectionProtocol�_T)�bound�_KT�_VT�_COL�Collection[Any]�_FN�Callable[..., Any]c��\rSrSrSSjrSrg)�_CollectionConverterProtocol�c��g�N�)�selfr's  �`D:\code\apps\devtools\python\user_packages\Python313\site-packages\sqlalchemy/orm/collections.py�__call__�%_CollectionConverterProtocol.__call__�s��#�r;N)r'r2�returnr2)�__name__�109__module__�__qualname__�__firstlineno__r>�__static_attributes__r;r@r=r7r7�s��5r@r7c�H�\rSrSr%S\S'S\S'S\S'S\S'S	\S110'Srg)
r-��CollectionAdapter�_sa_adapterr5�_sa_appender�_sa_removerzCallable[..., Iterable[Any]]�_sa_iteratorr7�
_sa_converterr;N)rBrCrDrE�__annotations__rFr;r@r=r-r-�s ��"�"�$�$�#�#�.�.�/�/r@c���\rSrSrSr\S5r\S5r\S5r\S5r	\\111R"SS5S	55r\SS112j5r
\S5r\S5r\S
5rSrg)r'�aBDecorators for entity collection classes.113 114The decorators fall into two groups: annotations and interception recipes.115 116The annotating decorators (appender, remover, iterator, converter,117internally_instrumented) indicate the method's purpose and take no118arguments.  They are not written with parens::119 120    @collection.appender121    def append(self, append): ...122 123The recipe decorators all require parens, even those that take no124arguments::125 126    @collection.adds("entity")127    def insert(self, position, entity): ...128 129 130    @collection.removes_return()131    def popitem(self): ...132 133c��SUlU$)aTag the method as the collection appender.134 135The appender method is called with one positional argument: the value136to append. The method will be automatically decorated with 'adds(1)'137if not already decorated::138 139    @collection.appender140    def add(self, append): ...141 142 143    # or, equivalently144    @collection.appender145    @collection.adds(1)146    def add(self, append): ...147 148 149    # for mapping type, an 'append' may kick out a previous value150    # that occupies that slot.  consider d['a'] = 'foo'- any previous151    # value in d['a'] is discarded.152    @collection.appender153    @collection.replaces(1)154    def add(self, entity):155        key = some_key_func(entity)156        previous = None157        if key in self:158            previous = self[key]159        self[key] = entity160        return previous161 162If the value to append is not allowed in the collection, you may163raise an exception.  Something to remember is that the appender164will be called for each object mapped by a database query.  If the165database contains rows that violate your collection semantics, you166will need to get creative to fix the problem, as access via the167collection will not work.168 169If the appender method is internally instrumented, you must also170receive the keyword argument '_sa_initiator' and ensure its171promulgation to collection events.172 173�appender��_sa_instrument_role��fns r=rS�collection.appender�s��V",����	r@c��SUlU$)a�Tag the method as the collection remover.174 175The remover method is called with one positional argument: the value176to remove. The method will be automatically decorated with177:meth:`removes_return` if not already decorated::178 179    @collection.remover180    def zap(self, entity): ...181 182 183    # or, equivalently184    @collection.remover185    @collection.removes_return()186    def zap(self): ...187 188If the value to remove is not present in the collection, you may189raise an exception or return None to ignore the error.190 191If the remove method is internally instrumented, you must also192receive the keyword argument '_sa_initiator' and ensure its193promulgation to collection events.194 195�removerrTrVs r=rZ�collection.removers��2"+����	r@c��SUlU$)z�Tag the method as the collection remover.196 197The iterator method is called with no arguments.  It is expected to198return an iterator over all collection members::199 200    @collection.iterator201    def __iter__(self): ...202 203�iteratorrTrVs r=r]�collection.iterators��",����	r@c��SUlU$)ahTag the method as instrumented.204 205This tag will prevent any decoration from being applied to the206method. Use this if you are orchestrating your own calls to207:func:`.collection_adapter` in one of the basic SQLAlchemy208interface methods, or to prevent an automatic ABC method209decoration from wrapping your implementation::210 211    # normally an 'extend' method on a list-like class would be212    # automatically intercepted and re-implemented in terms of213    # SQLAlchemy events and append().  your implementation will214    # never be called, unless:215    @collection.internally_instrumented216    def extend(self, items): ...217 218T)�_sa_instrumentedrVs r=�internally_instrumented�"collection.internally_instrumented,s��$#����	r@z1.3z�The :meth:`.collection.converter` handler is deprecated and will be removed in a future release.  Please refer to the :class:`.AttributeEvents.bulk_replace` listener interface in conjunction with the :func:`.event.listen` function.c��SUlU$)a	Tag the method as the collection converter.219 220This optional method will be called when a collection is being221replaced entirely, as in::222 223    myobj.acollection = [newvalue1, newvalue2]224 225The converter method will receive the object being assigned and should226return an iterable of values suitable for use by the ``appender``227method.  A converter must not assign values or mutate the collection,228its sole job is to adapt the value the user provides into an iterable229of values for the ORM's use.230 231The default converter implementation will use duck-typing to do the232conversion.  A dict-like collection will be convert into an iterable233of dictionary values, and other types will simply be iterated::234 235    @collection.converter236    def convert(self, other): ...237 238If the duck-typing of the object does not match the type of this239collection, a TypeError is raised.240 241Supply an implementation of this method if you want to expand the242range of possible types that can be assigned in bulk or perform243validation on the values about to be assigned.244 245�	converterrTrVs r=rd�collection.converterAs��J"-����	r@c�^�U4SjnU$)a�Mark the method as adding an entity to the collection.246 247Adds "add to collection" handling to the method.  The decorator248argument indicates which method argument holds the SQLAlchemy-relevant249value.  Arguments can be specified positionally (i.e. integer) or by250name::251 252    @collection.adds(1)253    def push(self, item): ...254 255 256    @collection.adds("entity")257    def do_stuff(self, thing, entity=None): ...258 259c�>�ST4UlU$)N�fire_append_event��_sa_instrument_before�rW�args �r=�	decorator�"collection.adds.<locals>.decorator{����(;�S�'A�B�$��Ir@r;�rlrms` r=�adds�collection.addsis���$	��r@c�^�U4SjnU$)a�Mark the method as replacing an entity in the collection.260 261Adds "add to collection" and "remove from collection" handling to262the method.  The decorator argument indicates which method argument263holds the SQLAlchemy-relevant value to be added, and return value, if264any will be considered the value to remove.265 266Arguments can be specified positionally (i.e. integer) or by name::267 268    @collection.replaces(2)269    def __setitem__(self, index, item): ...270 271c�(>�ST4UlSUlU$)Nrh�fire_remove_event)rj�_sa_instrument_afterrks �r=rm�&collection.replaces.<locals>.decorator�s���(;�S�'A�B�$�&9�B�#��Ir@r;rps` r=�replaces�collection.replaces�s��� 	�272�r@c�^�U4SjnU$)a�Mark the method as removing an entity in the collection.273 274Adds "remove from collection" handling to the method.  The decorator275argument indicates which method argument holds the SQLAlchemy-relevant276value to be removed. Arguments can be specified positionally (i.e.277integer) or by name::278 279    @collection.removes(1)280    def zap(self, item): ...281 282For methods where the value to remove is not known at call-time, use283collection.removes_return.284 285c�>�ST4UlU$�Nrurirks �r=rm�%collection.removes.<locals>.decorator�ror@r;rps` r=�removes�collection.removes�s���"	��r@c��SnU$)auMark the method as removing an entity in the collection.286 287Adds "remove from collection" handling to the method.  The return288value of the method, if any, is considered the value to remove.  The289method arguments are not inspected::290 291    @collection.removes_return()292    def pop(self): ...293 294For methods where the value to remove is known at call-time, use295collection.remove.296 297c��SUlU$r|)rvrVs r=rm�,collection.removes_return.<locals>.decorator�s��&9�B�#��Ir@r;)rms r=�removes_return�collection.removes_return�s�� 	��r@r;N)rl�intrAzCallable[[_FN], _FN])rBrCrDrE�__doc__�staticmethodrSrZr]rar�298deprecatedrdrqrxr~r�rFr;r@r=r'r'�s����4�+��+�Z����6��������(�	�_�_�
�	?������@����.����,����,���r@r'rIc��g)z7Fetch the :class:`.CollectionAdapter` for a collection.Nr;)r's r=r(r(�s�r@rJc��\rSrSr%SrSrS\S'S\S'S\S	'S299\S'S\S
'S\S'S\S'S.SjrS/Sjr\	S0Sj5r300\	S1Sj5rSrS2S3Sjjr
SrS/SjrS4SjrS5SjrS6SjrSrS2S3SjjrS5SjrS2S7S jjrS/S!jrS"rS#rS$rS\4S%jrS\4S&jrS\4S'jrS\4S(jrS\4S)jr S\4S*jr!S+r"S,r#S-r$g)8rIi�aQBridges between the ORM and arbitrary Python collections.301 302Proxies base-level collection operations (append, remove, iterate)303to the underlying Python collection, and emits add/remove events for304entities entering or leaving the collection.305 306The ORM uses :class:`.CollectionAdapter` exclusively for interaction with307entity collections.308 309 310)�attr�_key�_data�owner_state�311_converter�invalidated�emptyrr��strr�z)Callable[..., _AdaptedCollectionProtocol]r��InstanceState[Any]r�r7r��boolr�r�c��XlURUl[R"U5UlX lXlURUl	SUl312SUlg�NF)r��keyr��weakref�refr�r�rJrNr�r�r�)r<r�r��datas    r=�__init__�CollectionAdapter.__init__�sN���	��H�H��	��[�[��&��313�&�����,�,��� �����314r@c�0�[R"S5 g)Nz%This collection has been invalidated.)r�warn�r<s r=�_warn_invalidated�#CollectionAdapter._warn_invalidateds���	�	�9�:r@c�"�UR5$)z$The entity collection being adapted.)r�r�s r=r��CollectionAdapter.data315s���z�z�|�r@c�h�URRURUR5L$)z�return True if the owner state still refers to this collection.316 317This will return False within a bulk replace operation,318where this collection is the one being replaced.319 320)r��dictr�r�r�s r=�_referenced_by_owner�&CollectionAdapter._referenced_by_owners*�����$�$�T�Y�Y�/�4�:�:�<�?�?r@c�6�UR5R$r:�r�rKr�s r=�
bulk_appender�CollectionAdapter.bulk_appenders���z�z�|�(�(�(r@Nc�>�UR5RXS9 g)z8Add an entity to the collection, firing mutation events.��
_sa_initiatorNr��r<�item�	initiators   r=�append_with_event�#CollectionAdapter.append_with_events��321	
�322�323��!�!�$�!�@r@c��UR(aS5eSUlXRRUR'g)Nz7This collection adapter is already in the 'empty' stateT)r�r��_empty_collectionsr�)r<�	user_datas  r=�324_set_empty�CollectionAdapter._set_empty#s:���325�326�	E�D�	E����327�9B���+�+�D�I�I�6r@c���UR(dS5eSUlURRRUR5URR328UR'g)Nz3This collection adapter is not in the 'empty' stateF)r�r�r��popr�r�r�s r=�_reset_empty�CollectionAdapter._reset_empty*sZ���J�J�	A�@�	A����329����/�/�3�3�D�I�I�>�	
�����d�i�i�(r@c�.�[R"S5e)NzZThis is a special 'empty' collection which cannot accommodate internal mutation operations)�sa_exc�InvalidRequestErrorr�s r=�
_refuse_empty�CollectionAdapter._refuse_empty3s���(�(�
+�330�	331r@c��UR(aUR5 UR5RUSS9 g�z=Add or restore an entity to the collection, firing no events.Fr�N�r�r�r�rK�r<r�s  r=�append_without_event�&CollectionAdapter.append_without_event9s0���:�:���� ��332�333��!�!�$�e�!�<r@c��UR(aUR5 UR5RnUH334nU"USS9 M gr�r�)r<�itemsrSr�s    r=�append_multiple_without_event�/CollectionAdapter.append_multiple_without_event@s:���:�:���� ��:�:�<�,�,���D��T��/�r@c�6�UR5R$r:�r�rLr�s r=�bulk_remover�CollectionAdapter.bulk_removerHs���z�z�|�'�'�'r@c�>�UR5RXS9 g)z=Remove an entity from the collection, firing mutation events.r�Nr�r�s   r=�remove_with_event�#CollectionAdapter.remove_with_eventKs��	
�335�336�� � �� �?r@c��UR(aUR5 UR5RUSS9 g)z7Remove an entity from the collection, firing no events.Fr�N)r�r�r�rLr�s  r=�remove_without_event�&CollectionAdapter.remove_without_eventQs.���:�:���� ��337�338�� � ��U� �;r@c��UR(aUR5 UR5Rn[	U5H	nU"X1S9 M g)z>Empty the collection, firing a mutation event for each entity.r�N�r�r�r�rL�list)r<r�rZr�s    r=�clear_with_event�"CollectionAdapter.clear_with_eventWs>��339�:�:���� ��*�*�,�*�*����J�D��D�2�r@c��UR(aUR5 UR5Rn[	U5H340nU"USS9 M g)z'Empty the collection, firing no events.Fr�Nr�)r<rZr�s   r=�clear_without_event�%CollectionAdapter.clear_without_eventbs@���:�:���� ��*�*�,�*�*����J�D��D��.�r@c�P�[UR5R55$)z(Iterate over entities in the collection.)�iterr�rMr�s r=�__iter__�CollectionAdapter.__iter__ks���D�J�J�L�-�-�/�0�0r@c�b�[[UR5R555$)z!Count entities in the collection.)�lenr�r�rMr�s r=�__len__�CollectionAdapter.__len__ps!���4��341�342��1�1�3�4�5�5r@c��g�NTr;r�s r=�__bool__�CollectionAdapter.__bool__ts��r@c�0�U(dgUSLa�UR(aUR5 UR(aUR5 UH@nURRURURRUUU5 MB ggr��r�r�r�r�r��fire_append_wo_mutation_eventr�r��r<r�r�r�r�s     r=�#_fire_append_wo_mutation_event_bulk�5CollectionAdapter._fire_append_wo_mutation_event_bulkws|�����E�!�����&�&�(��z�z��!�!�#����	�	�7�7��$�$��$�$�)�)������"r@c��USLa~UR(aUR5 UR(aUR5 URRURURRXU5$U$)a*Notify that a entity is entering the collection but is already343present.344 345 346Initiator is a token owned by the InstrumentedAttribute that347initiated the membership mutation, and should be left as None348unless you are passing along an initiator value from a chained349operation.350 351.. versionadded:: 1.4.15352 353Fr��r<r�r�r�s    r=r��/CollectionAdapter.fire_append_wo_mutation_event�sm���E�!�����&�&�(��z�z��!�!�#��9�9�:�:�� � �$�"2�"2�"7�"7��#��
��Kr@c��USLa~UR(aUR5 UR(aUR5 URRURURRXU5$U$)z�Notify that a entity has entered the collection.354 355Initiator is a token owned by the InstrumentedAttribute that356initiated the membership mutation, and should be left as None357unless you are passing along an initiator value from a chained358operation.359 360F)r�r�r�r�r�rhr�r�r�s    r=rh�#CollectionAdapter.fire_append_event�sm���E�!�����&�&�(��z�z��!�!�#��9�9�.�.�� � �$�"2�"2�"7�"7��#��
��Kr@c�0�U(dgUSLa�UR(aUR5 UR(aUR5 UH@nURRURURRUUU5 MB ggr��r�r�r�r�r�rur�r�r�s     r=�_fire_remove_event_bulk�)CollectionAdapter._fire_remove_event_bulk�sz�����E�!�����&�&�(��z�z��!�!�#����	�	�+�+��$�$��$�$�)�)������"r@c��USLaUR(aUR5 UR(aUR5 URRURURRXU5 gg)z�Notify that a entity has been removed from the collection.361 362Initiator is the InstrumentedAttribute that initiated the membership363mutation, and should be left as None unless you are passing along364an initiator value from a chained operation.365 366FNr�r�s    r=ru�#CollectionAdapter.fire_remove_event�sf���E�!�����&�&�(��z�z��!�!�#��I�I�'�'�� � �$�"2�"2�"7�"7��#�
�"r@c��UR(aUR5 URRURURR367UUS9 g)z�Notify that an entity is about to be removed from the collection.368 369Only called if the entity cannot be removed after calling370fire_remove_event().371 372)r�r�N)r�r�r��fire_pre_remove_eventr�r�)r<r�r�s   r=r��'CollectionAdapter.fire_pre_remove_event�sN������"�"�$��	�	�'�'�������!�!���		(�	373r@c��URURURRURURUR374S.$)N)r�r��	owner_clsr�r�r�)r�r��class_r�r�r�r�s r=�__getstate__�CollectionAdapter.__getstate__�sB���9�9��+�+��)�)�0�0��I�I��+�+��Z�Z�
375�	376r@c�4�USUlUSUl[R"US5UlUSR377UlXSlUSUl[USUR5RUlURSS5Ul
g)Nr�r�r�r�r�r�F)r�r�r�r�r�rNr�rJr��getattr�implr��getr�)r<�ds  r=�__setstate__�CollectionAdapter.__setstate__�s����e�H��	��]�+����[�[��6��+��378��F�)�1�1��� $�&�	���]�+����A�k�N�D�I�I�6�;�;��	��U�U�7�E�*��379r@)r�r�r�r�r�r�r�)r�rr�r�r�r-)rA�None)rAr-)rAr�r:)r�rr��Optional[AttributeEventToken]rAr380)rAr)r�rrAr381)r�z
Iterable[Any]rAr382)r�rrAr383)%rBrCrDrEr��	__slots__rOr�r��propertyr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rr�r�rhr�rur�rrrFr;r@r=rIrI�s���384��I�"�!�385
�I�5�4�#�#�,�,����K��%��(��)�	�,;������@��@�)�EI�A��A�$A�A�	
�A�C�386�387�=�0�(�EI�@��@�$A�@�	
�@�<�:>�	3�6�	3�	
�	3�/�1�3886�� $���,=A�f��415�&��,8<���(15�&��&/3��389� 390�+r@c���[U[5(de[RnU"U=(d S5nUR	U=(d S5nU"U=(d S5RU5nURU5nUR
5n	U=(d SHn391X�;aU	"X�S9 MX�;dMU	"U392SS9 M  U(aURXcS9 URX�S9 gg)aLoad a new collection, firing events based on prior like membership.393 394Appends instances in ``values`` onto the ``new_adapter``. Events will be395fired for any instance not present in the ``existing_adapter``.  Any396instances in ``existing_adapter`` not present in ``values`` will have397remove events fired upon them.398 399:param values: An iterable of collection member instances400 401:param existing_adapter: A :class:`.CollectionAdapter` of402 instances to be replaced403 404:param new_adapter: An empty :class:`.CollectionAdapter`405 to load with ``values``406 407 408r;r�F)r�N)	�409isinstancer�r�IdentitySet�intersection�410differencer�r�r�)�values�existing_adapter�new_adapterr��idset�existing_idset�	constants�	additions�removalsrS�members           r=�bulk_replacers���&�f�d�#�#�#�#����E��+�1�r�2�N��+�+�F�L�b�9�I��f�l��#�.�.�y�9�I��(�(��3�H��(�(�*�H��,�B�,�����V�5�
�
 ��V�5�1�	���<�<��	=�	411�	�0�0��0�O�	r@c��U[;a412[UnO[[U5n[U"55nU[;a[Un[U"55n[R5(a<[
USS5[U5:wa[U5 [R5 U$U$![R5 f=f)aWPrepare a callable for future use as a collection class factory.413 414Given a collection class factory (either a type or no-arg callable),415return another factory that will produce compatible instances when416called.417 418This function is responsible for converting collection_class=list419into the run-time behavior of collection_class=InstrumentedList.420 421r`N)422�__canned_instrumentationr�_CollectionFactoryType�type�__instrumentation_mutex�acquirer�id�_instrument_class�release)�factory�impl_factory�clss   r=�prepare_instrumentationr)6s���"�*�*�/��8���2�G�<��423�|�~�424�C��&�&�0��4���<�>�"���&�&�(�(�	.��s�.��5��C��@�!�#�&�#�+�+�-���<���
$�+�+�-�s�2%B/�/Cc��URS:Xa[R"S5e[U5up[	XU5 [XU5 [
XU5 g)z6Modify methods in a class and install instrumentation.�__builtin__zGCan not instrument a built-in type. Use a subclass, even a trivial one.N)rCr��
ArgumentError�_locate_roles_and_methods�_setup_canned_roles�_assert_required_roles�_set_collection_attributes�r(�roles�methodss   r=r$r$fsT���~�~��&��"�"�
,�425�	426�427/�s�3�N�E���G�,��3�w�/��s�7�3r@c���0n0nURH�n[U5R5H�upE[U5(dM[	US5(a%UR428nUS;deUR
Xd5 SnSn[	US5(aURup�U	S;deX�4n[	US5(aURn	U	S;deU	nU(a	Xx4-X$'M�U(dM�SSU4X$'M� M� X4$)z_search for _sa_instrument_role-decorated methods in429method resolution order, assign to roles.430 431rU)rSrZr]rdNrj)rhrurv)	�__mro__�varsr��callable�hasattrrU�432setdefaultrjrv)r(r2r3�supercls�name�method�role�before�after�op�arguments           r=r-r-{s���E�MO�G��K�K�� ��N�0�0�2�L�D��F�#�#���v�4�5�5��1�1��� ����� � ��,�15�F�#'�E��v�6�7�7�%�;�;����G�G�G�G�����v�5�6�6��0�0���G�G�G�G���� &�� 1��
��� $�d�E� 1��
�?3� �B�>�r@c�n�[R"U5nU[;a�Uce[UupEUR5HupgUR	Xg5 M UR5HFup�[XS5n433U434(dMX�;dM![
U435S5(aM4[XU	"U43655 MH gg)z�see if this class has "canned" roles based on a known437collection type (dict, set, list).  Apply those roles438as needed to the "roles" dictionary, and also439prepare "decorator" methods440 441Nr`)r�duck_type_collection�__interfacesr�r9rr8�setattr)r(r2r3�collection_type�canned_roles�442decoratorsr=r;r<rmrWs           r=r.r.�s����/�/��4�O��,�&��*�*�*�#/��#@� ��&�,�,�.�J�D����T�(�/�",�!1�!1�!3��F���d�+�B����)���$6�7�7���Y�r�]�3�"4�'r@c� �SU;d[XS5(d#[R"SUR-5eUSU;a$[[	XS5S5(dSX!S'SU;d[XS5(d#[R"SUR-5eUSU;a$[[	XS5S5(dSX!S'SU;d[XS5(d#[R"S	UR-5eg443)zLensure all roles are present, and apply implicit instrumentation if444needed445 446rSz>Type %s must elect an appender method to be a collection classr`)rhrNrZz<Type %s must elect a remover method to be a collection class)rurNr]z>Type %s must elect an iterator method to be a collection classN)r8r�r,rBrr1s   r=r/r/�s1��447���g�c��3D�&E�&E��"�"�
!�#&�<�<�
0�448�	449�450�z�	�'�	)�'���:�&�'�);�3�3�&D��j�!�"����W�S�	�2B�%C�%C��"�"�
!�#&�<�<�
0�451�	452�453�y�	��	(����9�%�&�(:�2�2�%C��i� �!����g�c��3D�&E�&E��"�"�
!�#&�<�<�
0�454�	455�'Fr@c�B�UR5H*unupEn[UU[[X5XEU55 M, UR5Hups[USU-[X55 M  SUl[US5(dSUl[U5Ulg)zcapply ad-hoc instrumentation from decorators, class-level defaults456and implicit role declarations457 458z_sa_%sNrN)	r�rE�_instrument_membership_mutatorrrJr8rNr#r`)r(r2r3�method_namer>rAr?r=s        r=r0r0�s���4593:�-�-�/�.��.�f�����*���)�6�U�
�	460�3B�#�[�[�]�����X��_�g�c�&?�@�+��C�O��3��(�(� ����c�7�C�r@c��^^^^^^�T(a�[[R"[T5S55n[	T[4615(a&Tm[
U5T:�=(a UT=(d SmOTU;aURT5mOSmTmAUUUUUU4SjnSUl[TS5(aTRUl462TRUlTRUlU$)zERoute method args and/or return value through the collection463adapter.rNc��>�T(abTc%T464U;a[R"ST-5eUT465nO:[U5T:�aUTnO%T466U;aUT467nO[R"ST-5eURSS5nUSLaSnOUSRnT(aU(a[UT5"WU5 T(aU(dT	"U0UD6$T	"U0UD6nUb[UT5"XS5 U$)NzMissing argument %sr�Fr)r�r,r�r�rJr)�args�kw�valuer��executor�resr?rAr>r<�	named_arg�pos_args      ������r=�wrapper�/_instrument_membership_mutator.<locals>.wrappers��������B�&� �.�.�-��8����9�
���t�9�w�&� ��M�E��"�_��y�M�E� �.�.�-��8����F�F�?�D�1�	�����H��A�w�*�*�H��h��H�f�%�e�Y�7��H��4�&�2�&�&��$�%�"�%�C�����%�(��8��Jr@TrU)
r�r�flatten_iteratorrrr�r��indexr`r8rUrBr�)r<r>rAr?�fn_argsrVrTrUs````  @@r=rKrK�s�������!�!�"8��"@��"C�D�468���h��$�$��G��G��x�/�E�G�H�4E�M��I��7�"�!�-�-��1���� �I��!�!�F $�G���v�,�-�-�&,�&@�&@��#����G���n�n�G�O��Nr@c�X�USLa%URnU(aURXSS9 ggg)z=Run set wo mutation events.469 470The collection is not mutated.471 472FN�r�)rJr�)r'r�r�rRs    r=�__set_wo_mutationr]7s<���E�!��)�)����2�2���
3�
��"r@c�V�USLa#URnU(aURXUS9nU$)zVRun set events.473 474This event always occurs before the collection is actually mutated.475 476Fr\)rJrh�r'r�r�r�rRs     r=�__setr`Es4���E�!��)�)����-�-�d�s�-�K�D��Kr@c�X�USLa%URnU(aURXUS9 ggg)z�Run del events.477 478This event occurs before the collection is actually mutated, *except*479in the case of a pop operation, in which case it occurs afterwards.480For pop operations, the __before_pop hook is called before the481operation occurs.482 483Fr\N)rJrur_s     r=�__delrbSs7���E�!��)�)����&�&�t��&�D��"r@c�N�URnU(aURU5 gg)z;An event which occurs on a before a pop() operation occurs.N)rJr�)r'r�rRs   r=�__before_poprdbs#���%�%�H���&�&�}�5�r@c��^484�Sm485U4864SjnU4874SjnU4884SjnU4894SjnU4904SjnU4914SjnU4924SjnU4934S	jnU4944S495jn[5R5n	U	RS5 U	$)z:Tailored instrumentation wrappers for any list-like class.c�d�SUl[[UR5RUlgr�)r`rr�rBr�rVs r=�_tidy�_list_decorators.<locals>._tidyl�"��"����T�2�;�;�/�7�7��496r@c�*>^�SU4SjjnT"U5 U$)Nc�8>�[XU[5nT"X5 gr:)r`r)r<r�r�rWs   �r=�append�0_list_decorators.<locals>.append.<locals>.appendqs�����]�F�;�D��t�Nr@r:r;)rWrlrgs` �r=rl� _list_decorators.<locals>.appendps���	�	�f�
��
r@c�*>^�SU4SjjnT"U5 U$)Nc�8>�[XU[5 T"X5 gr:�rbr�r<rQr�rWs   �r=�remove�0_list_decorators.<locals>.remove.<locals>.removeys����$�}�f�5��t�Or@r:r;�rWrsrgs` �r=rs� _list_decorators.<locals>.removexs���	�497	�f�
��
r@c�&>^�U4SjnT"U5 U$)Nc�2>�[XSU5nT"XU5 gr:)r`)r<rYrQrWs   �r=�insert�0_list_decorators.<locals>.insert.<locals>.insert�s����$�t�U�3�E��t�E�"r@r;)rWryrgs` �r=ry� _list_decorators.<locals>.insert�s���	#�	�f�
��
r@c�&>^�U4SjnT"U5 U$)Nc�>�[U[5(d+XnUb
[XSU5 [XSU5nT498"XU5 gUR=(d SnUR499=(d SnUS:aU[
U5-
nURb
URnO[
U5nUS:aU[
U5-
nUS:XaTX Lag[XVU5Hn[
U5U:�dMX	M [U5HupxURXu-U5 M g[[XVU55n	[
U5[
U	5:wa%[S[
U5<S[
U	5<35e[X�5HupxURXx5 M g)Nrrz#attempt to assign sequence of size z to extended slice of size )r�slicerbr`�step�startr��stop�range�	enumerateryr��500ValueError�zip�__setitem__)r<rYrQ�existingrr�r��ir��rngrWs          �r=r��:_list_decorators.<locals>.__setitem__.<locals>.__setitem__�s\����e�U�+�+��;���'��$�$��6��d�4��7���4��&��z�z��Q�����(�q���1�9��S��Y�&�E��:�:�)� �:�:�D��t�9�D��!�8��C��I�%�D��1�9��}��"�5��5���t�9�u�,� $��6�$-�U�#3������A�I�t�4�$4��u�U�$�7�8�C��5�z�S��X�-�(� #�5�z�3�s�8�5���501$'�s�?����(�(��1�$3r@r;�rWr�rgs` �r=r��%_list_decorators.<locals>.__setitem__�s���&	2�P	�k���r@c�&>^�U4SjnT"U5 U$)Nc�>�[U[5(dXn[XSU5 T"X5 gXHn[XSU5 M T"X5 gr:)rr~rb�r<rYr�rWs   �r=�__delitem__�:_list_decorators.<locals>.__delitem__.<locals>.__delitem__�sK����e�U�+�+��{���d�$��.��4��502!�K�D��$�d�E�2�(��4�r@r;�rWr�rgs` �r=r��%_list_decorators.<locals>.__delitem__�s���	 �	�k���r@c�>�SnT"U5 U$)Nc�J�[U5HnURU5 M gr:�r�rl�r<�iterablerQs   r=�extend�0_list_decorators.<locals>.extend.<locals>.extend�s���h������E�"�(r@r;)rWr�rgs  �r=r�� _list_decorators.<locals>.extend�s���	#�	�f�
��
r@c�>�SnT"U5 U$)Nc�L�[U5HnURU5 M U$r:r�r�s   r=�__iadd__�4_list_decorators.<locals>.__iadd__.<locals>.__iadd__�s#���h������E�"�(��Kr@r;)rWr�rgs  �r=r��"_list_decorators.<locals>.__iadd__�����	�	�h���r@c�*>^�SU4SjjnT"U5 U$)Nc�H>�[U5 T"X5n[XSU5 U$r:�rdrbr�s   �r=r��*_list_decorators.<locals>.pop.<locals>.pop�s%�������d�?�D��$�d�E�*��Kr@������r;�rWr�rgs` �r=r��_list_decorators.<locals>.pop�s���	�	�c�503��504r@c�*>^�SU4SjjnT"U5 U$)Nc�B>�UHn[XSU5 M T"U5 gr:�rbr�s   �r=�clear�._list_decorators.<locals>.clear.<locals>.clear�s ������d�$��.���t�Hr@r�r;�rWr�rgs` �r=r��_list_decorators.<locals>.clear�s���	�505	�e���r@rg��locals�copyr�)rlrsryr�r�r�r�r�r��lrgs          @r=�_list_decoratorsr�isU���8����*�X�"�	���	��
�
��A��E�E�'�N��Hr@c�^�SmU4SjnU4SjnU4SjnU4SjnU4SjnU4SjnU4Sjn[5R5nURS	5 U$)506zBTailored instrumentation wrappers for any dict-like mapping class.c�d�SUl[[UR5RUlgr�)r`rr�rBr�rVs r=rg�_dict_decorators.<locals>._tidy�rir@c�*>^�SU4SjjnT"U5 U$)Nc�X>�X;a[XUX15 [XX15nT"XU5 gr:)rbr`)r<r�rQr�rWs    �r=r��:_dict_decorators.<locals>.__setitem__.<locals>.__setitem__�s,����{��d��I�}�:��$�}�:�E��t�%� r@r:r;r�s` �r=r��%_dict_decorators.<locals>.__setitem__�s���	!�	�k���r@c�*>^�SU4SjjnT"U5 U$)Nc�>>�X;a[XUX!5 T"X5 gr:r�)r<r�r�rWs   �r=r��:_dict_decorators.<locals>.__delitem__.<locals>.__delitem__s����{��d��I�}�:��t�Mr@r:r;r�s` �r=r��%_dict_decorators.<locals>.__delitem__s���	�507	�k���r@c�&>^�U4SjnT"U5 U$)Nc�H>�UHn[XUSU5 M T"U5 gr:r�)r<r�rWs  �r=r��._dict_decorators.<locals>.clear.<locals>.clears$������d��I�t�S�1���t�Hr@r;r�s` �r=r��_dict_decorators.<locals>.clears���	�508	�e���r@c�4>^�[4U4SjjnT"U5 U$)Nc�>�[U5 X;nU[La	T"X5nO	T"XU5nU(a
[XSU5 U$r:)rdrrb)r<r��default�_to_delr�rWs     �r=r��*_dict_decorators.<locals>.pop.<locals>.popsC�������k�G��&� ��$�}���$�W�-����d�$��,��Kr@rr�s` �r=r��_dict_decorators.<locals>.pops���#)�		�	�c�509��510r@c�&>^�U4SjnT"U5 U$)Nc�N>�[U5 T"U5n[XSSS5 U$)Nrr��r<r�rWs  �r=�popitem�2_dict_decorators.<locals>.popitem.<locals>.popitem)s)�������d�8�D��$�Q���q�)��Kr@r;)rWr�rgs` �r=r��!_dict_decorators.<locals>.popitem(s���	�	�g���r@c�">�SSjnT"U5 U$)Nc�x�X;aURX5 U$URU5nX2La[XS5 U$r:)r��__getitem__r])r<r�r�rQs    r=r9�8_dict_decorators.<locals>.setdefault.<locals>.setdefault3s?����� � ��.����(�(��-���#�%�d�4�8��r@r:r;)rWr9rgs  �r=r9�$_dict_decorators.<locals>.setdefault2s���		�	�j���r@c�,>�[4SjnT"U5 U$)Nc�V�U[Lar[US5(a8[U5H(nX0;d	XXLaXX'M[XUS5 M* O)UH#up4X0;dXULaX@U'M[XS5 M% UH(nX0;d	XX#LaX#X'M[XUS5 M* g)N�keys)rr8r�r])r<�__otherrPr�rQs     r=�update�0_dict_decorators.<locals>.update.<locals>.updateBs����f�$��7�F�+�+�#�G�}���?�d�i�w�|�.K�(/��D�I�-�d�C�L�$�G�	 -�'.�511���?�d�i�u�.D�(-��I�-�d�4�@�	'.�512���?�d�i�r�w�&>� "��D�I�%�d�s�G�T�:�	r@r�rWr�rgs  �r=r�� _dict_decorators.<locals>.updateAs���!'�	;�(	�f�
��
r@rgr�)	r�r�r�r�r�r9r�r�rgs	        @r=�_dict_decoratorsr��sJ���8����
��
��0	��
�
��A��E�E�'�N��Hr@c�>�[U[UR4-5$)zGAllow only set, frozenset and self.__class__-derived513objects in binops.)r�_set_binop_bases�	__class__�r<�objs  r=�_set_binops_check_strictr�as���c�+�t�~�~�.?�?�@�@r@c��[U[UR4-5=(d [R"U5[514:H$)z5Allow anything set-like to participate in set binops.)rr�r�rrC�setr�s  r=�_set_binops_check_looser�gs8��	�3�(�D�N�N�+<�<�=�	1��$�$�S�)�S�0�r@c��^�SmU4SjnU4SjnU4SjnU4SjnU4SjnU4SjnU4SjnU4S	jnU4S515jnU4Sjn	U4Sjn516U4S
jnU4Sjn[5R5n
U
RS5 U
$)z9Tailored instrumentation wrappers for any set-like class.c�d�SUl[[UR5RUlgr�)r`rr�rBr�rVs r=rg�_set_decorators.<locals>._tidyrs"��"����S�"�+�+�.�6�6��517r@c�*>^�SU4SjjnT"U5 U$)Nc�\>�X;a[XU[5nO[XU5 T"X5 gr:)r`rr]rrs   �r=�add�)_set_decorators.<locals>.add.<locals>.addws(���� ��d�=�&�A��!�$�}�=��t�Or@r:r;)rWr�rgs` �r=r��_set_decorators.<locals>.addvs���	�	�c�518��519r@c�*>^�SU4SjjnT"U5 U$)Nc�B>�X;a[XU[5 T"X5 gr:rqrrs   �r=�discard�1_set_decorators.<locals>.discard.<locals>.discard������}��d�=�&�9��t�Or@r:r;)rWr�rgs` �r=r�� _set_decorators.<locals>.discard�s���	�	�g���r@c�*>^�SU4SjjnT"U5 U$)Nc�B>�X;a[XU[5 T"X5 gr:rqrrs   �r=rs�/_set_decorators.<locals>.remove.<locals>.remove�r�r@r:r;rus` �r=rs�_set_decorators.<locals>.remove�s���	�	�f�
��
r@c�&>^�U4SjnT"U5 U$)Nc�P>�[U5 T"U5n[XS[5 U$r:)rdrbrr�s  �r=r��)_set_decorators.<locals>.pop.<locals>.pop�s'�������d�8�D�
�$�d�F�+��Kr@r;r�s` �r=r��_set_decorators.<locals>.pop�s���	�	�c�520��521r@c�>�SnT"U5 U$)Nc�J�[U5HnURU5 M gr:)r�rsr�s  r=r��-_set_decorators.<locals>.clear.<locals>.clear�s���T�522�����D�!�#r@r;r�s  �r=r��_set_decorators.<locals>.clear�s���	"�	�e���r@c�>�SnT"U5 U$)Nc�8�UHnURU5 M gr:)r��r<rQr�s   r=r��/_set_decorators.<locals>.update.<locals>.update�s���������r@r;r�s  �r=r��_set_decorators.<locals>.update�s���	�	�f�
��
r@c�>�SnT"U5 U$)Nc�f�[X5(d[$UHnURU5 M U$r:)r��NotImplementedr�rs   r=�__ior__�1_set_decorators.<locals>.__ior__.<locals>.__ior__�s-��+�D�8�8�%�%����������Kr@r;)rWr523rgs  �r=r524� _set_decorators.<locals>.__ior__�s���	�	�g���r@c�>�SnT"U5 U$)Nc�8�UHnURU5 M gr:)r�rs   r=�difference_update�E_set_decorators.<locals>.difference_update.<locals>.difference_update�s�������T�"�r@r;)rWrrgs  �r=r�*_set_decorators.<locals>.difference_update�s���	#�	�� � � r@c�>�SnT"U5 U$)Nc�f�[X5(d[$UHnURU5 M U$r:)r�r	r�rs   r=�__isub__�3_set_decorators.<locals>.__isub__.<locals>.__isub__�s.��+�D�8�8�%�%������T�"���Kr@r;)rWrrgs  �r=r�!_set_decorators.<locals>.__isub__�r�r@c�>�SnT"U5 U$)Nc��URU5[U5p2X2-525X#-526pTUHnURU5 M UHnURU5 M gr:)rr�rsr��r<�other�want�haversr�r�s       r=�intersection_update�I_set_decorators.<locals>.intersection_update.<locals>.intersection_update�sN���*�*�5�1�3�t�9�$��+�t�{�C������D�!���������r@r;)rWrrgs  �r=r�,_set_decorators.<locals>.intersection_update�s���	�	�!�"�"�"r@c�>�SnT"U5 U$)Nc���[X5(d[$URU5[U5p2X2-527X#-528pTUHnUR	U5 M UHnURU5 M U$r:)r�r	rr�rsr�rs       r=�__iand__�3_set_decorators.<locals>.__iand__.<locals>.__iand__�sd��+�D�8�8�%�%��*�*�5�1�3�t�9�$��+�t�{�C������D�!�����������Kr@r;)rWr"rgs  �r=r"�!_set_decorators.<locals>.__iand__�����529	�	�h���r@c�>�SnT"U5 U$)Nc��URU5[U5p2X2-530X#-531pTUHnURU5 M UHnURU5 M gr:)�symmetric_differencer�rsr�rs       r=�symmetric_difference_update�Y_set_decorators.<locals>.symmetric_difference_update.<locals>.symmetric_difference_update�sN���2�2�5�9�3�t�9�$��+�t�{�C������D�!���������r@r;)rWr)rgs  �r=r)�4_set_decorators.<locals>.symmetric_difference_update�s���	�	�)�*�*�*r@c�>�SnT"U5 U$)Nc���[X5(d[$URU5[U5p2X2-532X#-533pTUHnUR	U5 M UHnURU5 M U$r:)r�r	r(r�rsr�rs       r=�__ixor__�3_set_decorators.<locals>.__ixor__.<locals>.__ixor__�sd��+�D�8�8�%�%��2�2�5�9�3�t�9�$��+�t�{�C������D�!�����������Kr@r;)rWr.rgs  �r=r.�!_set_decorators.<locals>.__ixor__�r%r@rgr�)r�r�rsr�r�r�r534rrrr"r)r.r�rgs              @r=�_set_decoratorsr1osh���7�535�	�	�536���	�!�	�#�� +�� 	��
�
��A��E�E�'�N��Hr@c��\rSrSrSrSrg)�InstrumentedListiz-An instrumented version of the built-in list.r;N�rBrCrDrEr�rFr;r@r=r3r3���7r@r3c��\rSrSrSrSrg)�InstrumentedSetiz,An instrumented version of the built-in set.r;Nr4r;r@r=r7r7s��6r@r7c��\rSrSrSrSrg)�InstrumentedDictiz-An instrumented version of the built-in dict.r;Nr4r;r@r=r9r9r5r@r9z/util.immutabledict[Any, _CollectionFactoryType]rrlrsr�)rSrZr]r�r]rzMutil.immutabledict[Any, Tuple[Dict[str, str], Dict[str, Callable[..., Any]]]]rDc��SSKJq SSKJq SSKJq SSKJq SSKJq SSKJq SSKJq SS	KJq [[5 [[5 [[5 g)537Nrr"r rr$)r))r*)r+)r,)r)r#r!rr%r*r+r,r$r3r7)�lclss r=�__gor<As7��3�4�7�.�4�;�>�3��&�'��o�&��k�"r@)r'r3rArIr:)r&z4Union[Type[Collection[Any]], _CollectionFactoryType]rAr)rAzDict[str, Callable[[_FN], _FN]])r<rr�rrAr�)Zr��538__future__r�operator�	threading�typingrrrrrr	r539rrr
rrrrrr��baser�rr�r�sql.baser�util.compatr�util.typingr�540attributesrrr)rr!r#r%�stater&�__all__�Lockr!rr.r0r1r2r4r7r-r'r(�541attrgetterrIrr)r$r-r.r/r0rKr]r`rbrdr�r�r��	frozensetr�r�r�r1r3r7r9�
immutabledictr�r�rrOrDr<r�r;r@r=�<module>rMs���b�F#���
������������� ��������0�"�	���/�3�7�4�2�.�$���$�.�.�*��"�"�&B�"B�C���T����
�e�3���
�e�3����v�.�/��
�e�/�0��6�8�6�0��0�J�J�Z�F�"�,�,�]�;��z+�z+�z	'P�T-�
A�-��-�`4�**�Z4�2542�@#�0;�|��E�6�J
�Ze
�P��#��A��_
�D8�t�B�x�8�7�c�"�g�7�8�t�C��H�~�8�543	����"����"�	544���I�� 	����$�#�&�
�545
��
546�	��8��L���547�548	
�549�H�%�'7�'9�:���

���4#�4�V�X�r@
codekingpro/portable-devtools · Team Ai