pax_global_header00006660000000000000000000000064131722017630014514gustar00rootroot0000000000000052 comment=3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e DeepCopy-1.7.0/000077500000000000000000000000001317220176300132315ustar00rootroot00000000000000DeepCopy-1.7.0/.gitattributes000077500000000000000000000002101317220176300161200ustar00rootroot00000000000000# Auto detect text files and perform LF normalization * text=auto *.png binary tests/ export-ignore phpunit.xml.dist export-ignore DeepCopy-1.7.0/.gitignore000077500000000000000000000000501317220176300152170ustar00rootroot00000000000000/composer.phar /composer.lock /vendor/* DeepCopy-1.7.0/.travis.yml000077500000000000000000000013721317220176300153500ustar00rootroot00000000000000language: php sudo: false php: - '5.6' - '7.0' - '7.1' - nightly matrix: fast_finish: true include: - php: '5.6' env: COMPOSER_FLAGS="--prefer-lowest" allow_failures: - php: nightly cache: directories: - $HOME/.composer/cache/files before_install: - | if [ "$TRAVIS_PHP_VERSION" = "nightly" ]; then COMPOSER_FLAGS="$COMPOSER_FLAGS --ignore-platform-reqs" fi; install: - composer update --no-interaction --no-progress --no-suggest --prefer-dist $COMPOSER_FLAGS - wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.0/coveralls.phar before_script: - mkdir -p build/logs script: - vendor/bin/phpunit --coverage-clover build/logs/clover.xml after_script: - php coveralls.phar -v DeepCopy-1.7.0/LICENSE000066400000000000000000000020651317220176300142410ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2013 My C-Sense Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. DeepCopy-1.7.0/README.md000066400000000000000000000227211317220176300145140ustar00rootroot00000000000000# DeepCopy DeepCopy helps you create deep copies (clones) of your objects. It is designed to handle cycles in the association graph. [![Build Status](https://travis-ci.org/myclabs/DeepCopy.png?branch=master)](https://travis-ci.org/myclabs/DeepCopy) [![Coverage Status](https://coveralls.io/repos/myclabs/DeepCopy/badge.png?branch=master)](https://coveralls.io/r/myclabs/DeepCopy?branch=master) [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/myclabs/DeepCopy/badges/quality-score.png?s=2747100c19b275f93a777e3297c6c12d1b68b934)](https://scrutinizer-ci.com/g/myclabs/DeepCopy/) [![Total Downloads](https://poser.pugx.org/myclabs/deep-copy/downloads.svg)](https://packagist.org/packages/myclabs/deep-copy) ## Table of Contents 1. [How](#how) 1. [Why](#why) 1. [Using simply `clone`](#using-simply-clone) 1. [Overridding `__clone()`](#overridding-__clone) 1. [With `DeepCopy`](#with-deepcopy) 1. [How it works](#how-it-works) 1. [Going further](#going-further) 1. [Matchers](#matchers) 1. [Property name](#property-name) 1. [Specific property](#specific-property) 1. [Type](#type) 1. [Filters](#filters) 1. [`SetNullFilter`](#setnullfilter-filter) 1. [`KeepFilter`](#keepfilter-filter) 1. [`DoctrineCollectionFilter`](#doctrinecollectionfilter-filter) 1. [`DoctrineEmptyCollectionFilter`](#doctrineemptycollectionfilter-filter) 1. [`DoctrineProxyFilter`](#doctrineproxyfilter-filter) 1. [`ReplaceFilter`](#replacefilter-type-filter) 1. [`ShallowCopyFilter`](#doctrinecollectionfilter-type-filter) 1. [Edge cases](#edge-cases) 1. [Contributing](#contributing) 1. [Tests](#tests) ## How? Install with Composer: ```json composer require myclabs/deep-copy ``` Use simply: ```php use DeepCopy\DeepCopy; $copier = new DeepCopy(); $myCopy = $copier->copy($myObject); ``` ## Why? - How do you create copies of your objects? ```php $myCopy = clone $myObject; ``` - How do you create **deep** copies of your objects (i.e. copying also all the objects referenced in the properties)? You use [`__clone()`](http://www.php.net/manual/en/language.oop5.cloning.php#object.clone) and implement the behavior yourself. - But how do you handle **cycles** in the association graph? Now you're in for a big mess :( ![association graph](doc/graph.png) ### Using simply `clone` ![Using clone](doc/clone.png) ### Overridding `__clone()` ![Overridding __clone](doc/deep-clone.png) ### With `DeepCopy` ![With DeepCopy](doc/deep-copy.png) ## How it works DeepCopy recursively traverses all the object's properties and clones them. To avoid cloning the same object twice it keeps a hash map of all instances and thus preserves the object graph. To use it: ```php use function DeepCopy\deep_copy; $copy = deep_copy($var); ``` Alternatively, you can create your own `DeepCopy` instance to configure it differently for example: ```php use DeepCopy\DeepCopy; $copier = new DeepCopy(true); $copy = $copier->copy($var); ``` You may want to roll your own deep copy function: ```php namespace Acme; use DeepCopy\DeepCopy; function deep_copy($var) { static $copier = null; if (null === $copier) { $copier = new DeepCopy(true); } return $copier->copy($var); } ``` ## Going further You can add filters to customize the copy process. The method to add a filter is `DeepCopy\DeepCopy::addFilter($filter, $matcher)`, with `$filter` implementing `DeepCopy\Filter\Filter` and `$matcher` implementing `DeepCopy\Matcher\Matcher`. We provide some generic filters and matchers. ### Matchers - `DeepCopy\Matcher` applies on a object attribute. - `DeepCopy\TypeMatcher` applies on any element found in graph, including array elements. #### Property name The `PropertyNameMatcher` will match a property by its name: ```php use DeepCopy\Matcher\PropertyNameMatcher; // Will apply a filter to any property of any objects named "id" $matcher = new PropertyNameMatcher('id'); ``` #### Specific property The `PropertyMatcher` will match a specific property of a specific class: ```php use DeepCopy\Matcher\PropertyMatcher; // Will apply a filter to the property "id" of any objects of the class "MyClass" $matcher = new PropertyMatcher('MyClass', 'id'); ``` #### Type The `TypeMatcher` will match any element by its type (instance of a class or any value that could be parameter of [gettype()](http://php.net/manual/en/function.gettype.php) function): ```php use DeepCopy\TypeMatcher\TypeMatcher; // Will apply a filter to any object that is an instance of Doctrine\Common\Collections\Collection $matcher = new TypeMatcher('Doctrine\Common\Collections\Collection'); ``` ### Filters - `DeepCopy\Filter` applies a transformation to the object attribute matched by `DeepCopy\Matcher` - `DeepCopy\TypeFilter` applies a transformation to any element matched by `DeepCopy\TypeMatcher` #### `SetNullFilter` (filter) Let's say for example that you are copying a database record (or a Doctrine entity), so you want the copy not to have any ID: ```php use DeepCopy\DeepCopy; use DeepCopy\Filter\SetNullFilter; use DeepCopy\Matcher\PropertyNameMatcher; $object = MyClass::load(123); echo $object->id; // 123 $copier = new DeepCopy(); $copier->addFilter(new SetNullFilter(), new PropertyNameMatcher('id')); $copy = $copier->copy($object); echo $copy->id; // null ``` #### `KeepFilter` (filter) If you want a property to remain untouched (for example, an association to an object): ```php use DeepCopy\DeepCopy; use DeepCopy\Filter\KeepFilter; use DeepCopy\Matcher\PropertyMatcher; $copier = new DeepCopy(); $copier->addFilter(new KeepFilter(), new PropertyMatcher('MyClass', 'category')); $copy = $copier->copy($object); // $copy->category has not been touched ``` #### `DoctrineCollectionFilter` (filter) If you use Doctrine and want to copy an entity, you will need to use the `DoctrineCollectionFilter`: ```php use DeepCopy\DeepCopy; use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter; use DeepCopy\Matcher\PropertyTypeMatcher; $copier = new DeepCopy(); $copier->addFilter(new DoctrineCollectionFilter(), new PropertyTypeMatcher('Doctrine\Common\Collections\Collection')); $copy = $copier->copy($object); ``` #### `DoctrineEmptyCollectionFilter` (filter) If you use Doctrine and want to copy an entity who contains a `Collection` that you want to be reset, you can use the `DoctrineEmptyCollectionFilter` ```php use DeepCopy\DeepCopy; use DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter; use DeepCopy\Matcher\PropertyMatcher; $copier = new DeepCopy(); $copier->addFilter(new DoctrineEmptyCollectionFilter(), new PropertyMatcher('MyClass', 'myProperty')); $copy = $copier->copy($object); // $copy->myProperty will return an empty collection ``` #### `DoctrineProxyFilter` (filter) If you use Doctrine and use cloning on lazy loaded entities, you might encounter errors mentioning missing fields on a Doctrine proxy class (...\\\_\_CG\_\_\Proxy). You can use the `DoctrineProxyFilter` to load the actual entity behind the Doctrine proxy class. **Make sure, though, to put this as one of your very first filters in the filter chain so that the entity is loaded before other filters are applied!** ```php use DeepCopy\DeepCopy; use DeepCopy\Filter\Doctrine\DoctrineProxyFilter; use DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher; $copier = new DeepCopy(); $copier->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher()); $copy = $copier->copy($object); // $copy should now contain a clone of all entities, including those that were not yet fully loaded. ``` #### `ReplaceFilter` (type filter) 1. If you want to replace the value of a property: ```php use DeepCopy\DeepCopy; use DeepCopy\Filter\ReplaceFilter; use DeepCopy\Matcher\PropertyMatcher; $copier = new DeepCopy(); $callback = function ($currentValue) { return $currentValue . ' (copy)' }; $copier->addFilter(new ReplaceFilter($callback), new PropertyMatcher('MyClass', 'title')); $copy = $copier->copy($object); // $copy->title will contain the data returned by the callback, e.g. 'The title (copy)' ``` 2. If you want to replace whole element: ```php use DeepCopy\DeepCopy; use DeepCopy\TypeFilter\ReplaceFilter; use DeepCopy\TypeMatcher\TypeMatcher; $copier = new DeepCopy(); $callback = function (MyClass $myClass) { return get_class($myClass); }; $copier->addTypeFilter(new ReplaceFilter($callback), new TypeMatcher('MyClass')); $copy = $copier->copy([new MyClass, 'some string', new MyClass]); // $copy will contain ['MyClass', 'some string', 'MyClass'] ``` The `$callback` parameter of the `ReplaceFilter` constructor accepts any PHP callable. #### `ShallowCopyFilter` (type filter) Stop *DeepCopy* from recursively copying element, using standard `clone` instead: ```php use DeepCopy\DeepCopy; use DeepCopy\TypeFilter\ShallowCopyFilter; use DeepCopy\TypeMatcher\TypeMatcher; use Mockery as m; $this->deepCopy = new DeepCopy(); $this->deepCopy->addTypeFilter( new ShallowCopyFilter, new TypeMatcher(m\MockInterface::class) ); $myServiceWithMocks = new MyService(m::mock(MyDependency1::class), m::mock(MyDependency2::class)); // All mocks will be just cloned, not deep copied ``` ## Edge cases The following structures cannot be deep-copied with PHP Reflection. As a result they are shallow cloned and filters are not applied. There is two ways for you to handle them: - Implement your own `__clone()` method - Use a filter with a type matcher ## Contributing DeepCopy is distributed under the MIT license. ### Tests Running the tests is simple: ```php vendor/bin/phpunit ``` DeepCopy-1.7.0/composer.json000066400000000000000000000014201317220176300157500ustar00rootroot00000000000000{ "name": "myclabs/deep-copy", "type": "library", "description": "Create deep copies (clones) of your objects", "keywords": ["clone", "copy", "duplicate", "object", "object graph"], "license": "MIT", "autoload": { "psr-4": { "DeepCopy\\": "src/DeepCopy/" }, "files": [ "src/DeepCopy/deep_copy.php" ] }, "autoload-dev": { "psr-4": { "DeepCopy\\": "fixtures/", "DeepCopyTest\\": "tests/DeepCopyTest/" } }, "require": { "php": "^5.6 || ^7.0" }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", "phpunit/phpunit": "^4.1" }, "config": { "sort-packages": true } } DeepCopy-1.7.0/doc/000077500000000000000000000000001317220176300137765ustar00rootroot00000000000000DeepCopy-1.7.0/doc/clone.png000066400000000000000000000301341317220176300156050ustar00rootroot00000000000000PNG  IHDR{hsRGBgAMA a pHYsod/IDATx^ۏmYY7V jh ҉ 7+!rabl AnL nJ@0!^4!!4ghQ0 &Ч{Ms>_c9kQU֚c̱'yfUWZo9f]wp= {$ H0 a`@= {$ H0 a`@= {$ H0 a`@= {$ H0 a`@= {$ Hǐg P=Tk0}j վǐJSO~:(M9*s@;C*M?4yd{ IqҥU}|2Uv=Tʏ~#A#}Z 怾Ўǐ4J`N怾ЎǐJS:(M9*s@;C*M9*s@;C*M9*s@;C*M?4yd{ I4yd{ 492#1$M92#1$M92#1TJ`N怾Ўǐ4J`N怾ЎǐJSw:(M9*s@;C*M9*s@;C*M9*s@;C*M;4yd{ I4yd{ 4o۪92#1$M92#17׼5]wa=O_Ӹ7W]Ji̩9`:j_c2#1F} 7|K_nSsG:UghGcH|\T}_?xK^rؘU뮻Sos<7]wqd?^zvs9a!7}s2^}ݫF򗿼9K(M96lkmyYooRGVۦjp2#1To,M {|.ЎǐJSɂ߾jz?|>#SOs@>;aʕ+v]v=SߤNkmvcK(M92޿2?Ri*&~ 5=?o|^<seh%=(s@;CoRYxՌ7^M/G[7&zZߵ9gRM~Ӛy%'۽կi4yjNUv=T#<}?&viO|]0|ы^zwm,s@;CoRM9xԶK}_>rIV<sj=ؿRv=TJ.e>ig'?<@V<sj=̽ϥ7tӑwm2#1M~zի^u1zj'&Zs?O}s˥m[9a!nT(Y[o~J`N-9g{ЎǐJSw}9o}nSi̩0}}o>rJuehGcH-5e/{YuZ}=rv=&Zs׃Y?-ЎǐJS+>i|;*r-͑˗/W4yjc^ zVv=ԪoZFK:(M9*s@;C*M9*s@;C*M9*s@;C*MP&}9a!i}&}9a!rJ`N怾Ўǐ4J`N怾Ўǐ4J`N怾ЎǐJST0's@_ehGcH|_0's@_ehGcH{ェ92#1$M92#1T/J`N怾Ўǐ4J`N怾ЎǐJSn馃o*cv]<svUO{nᆃ믿 OxBu?{l'1Zu^wuOyS{]&jmTBSOzғS+>wJ<0?a׾&U6=_y-T`.go?_>8_>tZys}{[zsTf$˿|//~ {]4HvmrPT K]`aY>j/!~?S'7.];VMwwX;s=?=j4y4_~m/_:ܿ/mmvg?>~y>^0aGY{ _{}?| _8x;qWep4|,-oy=g}{WfRYC-uCQa%~ʁ؄׽uJ@ʁl`>0SBj 'JѵX*;r0G `)J[?U*dz]`7˴%dQpŨ?˔ 9,9U>mZj?6 {DJ#dg-D$$eߺ:or[sM-@cۄ=@tY <5 ,S*'6zMd~H]vZ-$)҄Q;rSVvHY༲O)7PI9m]K\٭^lTc.Jއ<=l@uvٯd3g*KǡaN](;MdTvTqTeI.˾tN"#;ҸɎvXk}]7W.[aqdϸ'ӁaA؃JNk_M}n=ԔF]0 x%`Mvٹ%ryNvjUYg T:<@~;Y=d x, 3%_'eeJ@IXˁ̲U>m)ԔW}!1 {0owܔ˒``qK*ɾW~'K'O;Yd`v!'7P)+/F&O]`/#Ks/>oSW~O 0 TN[gWng x {3V)r2g@Sn:r^-X/=Zvr46Sh(vdv:mIJ+RLco%#~q4 g*>:i8VSp'Z-Yf {rv*;;ϳsV`3L٭Ryuv'+/_ x.c#챗NʎN-;ټ ?Tmr6ؾ=;JnWvr`ߔuv9Xt`rjӼ/t{%,`;)A9t T:gI/oNco$XcYCQvH`Ǧ7Pd]w67'<^sµ)^Ȏ C|"kze;7P9jgKc/#ٱ؁쎳lή@%p\ xgqa=g=ټ2xh)}?uv v_Xg= p-aMi2]*ӃN v9uvۓq/nbǰaj+T~[l[tz([g;y-=Z%9{ );FɿQ%TV]Yg'IsNi'Vy,2lrШVuvn\{<|L{ ٤d+AL% $إ?l T# { %Gx$GyA yO97J9^yYg*ʾ3ZKNxr{ #;CrԷ?9j_AƗ@0i첝]{e2aͨrjuv*ٍC$5gzS9p9<]gw\Oj}|h:슰G+; dj7(`ޖ `4?0'a.e'Xfg>24C*KF хڬ]uЕ!6=C& T_9czUyKɁh.XY)sMe@ٙVEF TrU5tq ^eYSztq./7Ps:;9.@@; BأrYUvJ+Ù!wYg~ݴ Tc*<'r``9S 0"af2eGg'Yy+g<Ƨ@%$z玀a&.;ݼ Q@;3Le&7P<k |̥>tU78rI_}^yKyN"OcVd x .s_l.AP&s|#{hz&;h7Jm/eHdgQ^P'12fGm̶ Rڭ 7YgWn1y}ruvƧ7P1s^y嵼\<6#s9_vvRF9k`5mu\Aٳ8a`X@/VuvlK^y><5ؙНawN2\q TMBam'٩3an* IYgL幘a ˀvGc'ʙ ~BBL,G 3y}%g@Tޟ`uɮW;,Kcr X.]Ck*y:A5^e-幚랇تwO9U3ZԆR0<t(d=fHѷQ(7fQn6YgWnbs;.祀aP7y4jK @=!\M__*~ {\X2dp^8tq./7PΎ<1{\H٥b?^\soۦ6JB.8<k$ ,u?HBУre@5J\ӫbxDT y`WmrA8!pCoV ̥rIJseg!q\V(gm+2Ğt uv6J^s^༄=_bJPz TZ=rְ|?m)︿xlGU9ʜAy`&NJ lc^xp'<<vA$jΆՆRXekKxn9E9~s ]8Z%N6ύM*s[.9')v6[`n+RParYY.d]l`70adh=u-מ߄=M^dhgdd]' ~ٮuv2=띟@iք=|O]Yg TvrP`wI}]^^?yxFc*7ήvRX٥ۥˀ2oDޞJ@(LPI7PIuv vX} !g%!SmrveS7_^9XR{=J^Cz0aod)N5!ChM%%dXgׇ<yl{Sjg<F'$2pȥa9 : T<^*P(Dd'o veq.UnBC4{<B2ۑ>a-vÇRXO7}9}9kΒO_c<# ن(2Lv:;O|8OuD3]gw Ty9R#ٕW xeup:ao`>Ax%؝tTYg`g$y_;] x6-G3 u]dh6TDzp^ xppzsE L9 2$..7kئ'yM΢'5L(l7^E]~Mev vJv-<>:.ף! d_"d(<:rJ9/gKZ?7ze$s2I Tr zo ;>?<苰7|9T]>:;"ο#\!לa_xEy;{XuvAqZcyPM^*@? ei7PMPy'-Am-,eΰ xao2|+o*e/z~y=5\%m ~ʠJ6=*ǥKV+z@_@CG*Gi}m{jecnz@_@C217= aO zMhCS;/s*=:?PA}m{jecnz@_@C217= aO zMhCS;/s*=:}{SA}m{jecnz@_@C~217= aO zMhCS;/s*=:};QA}m{jecnz@_@Co۪217= aO zMhCkT3ăOկszI׼RwWK6{ַ~An*u{,s[BX7xc5_??~K6FuZR31%it&鷺/UfO@Co~G>n7m zW^nSz@_K^#q=s5ghCkT {a﮻nSz@;X /nKaFȀ|]b6=A-9k\}=ThCkT {!O؃k|3b>Cm~zֳ hCkTžA{ӛT~9J6{A}h5=?\ݮV~sT z̭pҥk8`~Sn7JІר{uF ~]r]Oec[^-o9O{z6g=س^Za/+ݴ^W>'zz+ېW<ȣ=v/~W?mVn aQMY+}}򓟬~ˠ6$%%M_/}KT= s7VyXn aQ]$쥖4 ئ\™K9yM<=x;qM=@`.C 2LT=կS屨}JS[{Fғ=רa/k^ZnZCY>e屘~Jn{'\{B|`5|͇P]aw]z)/|pu|y4\Ԟ+qE/Z}߷zkuJ6Fu;wtMˠǶ};\W\׽ȟcUZw@^HKM'?<@uʠ6+9rCu?w'>QZ?K7]?m}ݫ-a/qַu {uʠǶRa?uӳ iN~O}SW_|gu֥@^h[ 쬟?gzYJ^.q._\ݮVszVe/{Yu^ʠܖ>9+w>0!׿z(=E+_#C^.ݪmKz@j3|w_uiM/N]z!53zKR=涄ʝuo#^gS/rͶ=m Nj{KS>W~OecnKrZۤ$^h^{okV=涄^wyg~\=y;x_^.ǡki/S5{-s[B8r3?77hCS;/s*=:e-j_=Uz!쩝A}m{jecnz@_@C]:վ zMhCS;/s*=:]rEuP=Uz!쩝A}m{jecnz@_@C˗/ʠJ6=217=ރ>:(s*=ˠJ6=217=<:(s*=ˠJ6{ zMhCS;/s*=ˠJ6{w zMhCS;/s*=:{ェ217= aO zMhc/~QuP=Uz!쩝A}m T_ec.j_zKSAԞ}0!^k_k ն`Nz@얰Iڛw%Q[yڕ7a`{$ H0 a`@= {$ H0 a`@= {$ H0 a`@= {$ H0 a`@= {$ ($IENDB`DeepCopy-1.7.0/doc/deep-clone.png000066400000000000000000000332711317220176300165250ustar00rootroot00000000000000PNG  IHDRN`sRGBgAMA a pHYsod6NIDATx^۫g}?)-aBK#B/ze(C;QA QBo4z5rXT nDD$XVѨbE$XV ,QPu@X +hTQPu@X +hTQPu@X +t>Ѩ(: Vhb4XѨ(: VhbJhTd+J1UhTd+J17[oum۶_WZF@IQo';w~~ӟfFhb4W^yeE{۶ "s?k53J:VX)&bZokE 'zvQPRu?\=Z +to*k]j.<#i!%E[̫9sfr%L7^ݾ}m~ӧOخThb5_^sUWM{iB4*JWߗ}ۥuTvE:VX)&RZoMTѭDHys3߳X +t1=䠕r-pzkّ~ "jg; 'OnX +DjTɹVp ~hTePGY?X +t1#BG@ʥw'zhTeP7^$]X +DiTIz5\3m(wu׊m}-Mg3Ѩ():fsrX +DhTMh\n?Lh4*Jgյ~RV 3g??5ӧOgK|}vQPRu@ꫧ?/n[2J1z2XBRxe mhTT{PGVShb˜.|YcH.ɱcDz?7Z4*J(eĻvZsz5b@+ SQ77|DjFkE뀒׿䢋.~owYqnZVݨ֓ЍhѨ(:d=+Za`09[`=n6wo>/.R4*J(ۧ\q'OfZa`j_.~7M./ҲKvQPRu@>;nZa`0rG̋/)=rIٳg'FF@I%{nX&Zhbj5lBGnZfFbhTTk裏.Za`Zj==f3{7zҨ(:`+X +t1;ZwY3vk˚V:{QPRuՍ&=gY{u0RLF{汕Asqm1F@I57tӲo4V87+t1]>)ҝ/x<_%z2.w嶭 Jӽw_LOgE:VX)tQPu@X +t1 "QPu@X +hTQPu@X +hTQPu@X +tԩS %YĊu0RF+%YĊu0RLWO<)QPu@X +hTQPu@X +hTQPu@X +tĉ %YĊu0RF+%YĊu0RLW?.QPu@X +hTQPu@X +hTQPu@X +tرc %YĊu0RF+%YĊu0RLW=*QPu@X +hTQPu@X +hTQPu@X +tȑ# %YĊu0RF+%YĊu0RLW>,QPu@X +hTQPu@X +t^Ѩ(: Vhb4XѨ(: VhbX2vܹ3kϚEG\Zt3RLH.:wd۶m;vd=Bҟ-oߞEG\ZtRome,__tJUvۊB9RH&BsϞ=mJJY: Ԯ^&BsKnh TFoo=MD@)uJU{7-&bofo|c!͢QPRm5^zjꭹm"&Y˿gYtʠ9sfzݻ~]vҟ=7|g G=뮛^}ճ_q32I'B7iha02jwT2imU:ڝ%NGZs4v4X{.!\BsС~@<0V@vca`%4GT >4v|_/f`%,XO`\I>?1tVBQ˙hdrW?L4Cc`%G 7}, Wl+*+鷛>UCCd`%,n+Z1Т7{X }};̙3+v}l++yb8c @ 2Vg'WX2+U985ie~&X& PXqw@-,Hq-2RMwSYl"rt_p,6-2R+˲( Sr-3R\O.AjvrObX)ʙ\@mn ǙmZd`E>P[sX)" F.C!kT۳hsV/tTkT{=UXʚVNA%AOL ,ǖήv?&0o-}tOlCTV6xr01':+ oUZ+ä^i_II2oVVpyĽ'MOx ng3<9`8מQFZ Z``eO~e+?S f`eʥ̃r [z[˘'+K z"0[;i-ΰ}) V.芊2)̛}y1\l#`̓KN[u ,BkTHf3 #)n`?{ "Y ֑@Jq@Lnݠ$g,RcJ *s P_:խYVX4,Ȥ FI=w}x}2HjPLM.?Y.jsv2Hנ<<9!HhPDϜ9s,D=:ڔXGߠ<\PVhE5N䂨ҙU^X4tCl:`ѥ}4)0iE"Kh^;r O+\8i .,:@!xy"-޿ٯu4(Z'lWhQTփBX#i+#n-'^e`GSi'lMVuӾ6ցp:Cxr0R/g`!UOf\-q8C8G*OX3,L?ڸT *!c`m3P +Iw rK {ڠU3)+PW]1SX'5K$:Ua`m#KdZr_qpX},Q>cӿE" 0Fk#< ~ǕX9+ G`96`l*4҇V=~ϓ1q;urv1Pg<V_}r `ۂEҐq0XJ62OUhx A@-ϭBe` #ؘ4/h]z}]wmA>H&k0>h9.mAy݉'~K`k҃ϐ_iδJk|AZ=9hM:`հt 8W) 5*/-_% ؚ}a'u<9h+`|Z3AiH`,Z,#@ \X+ߧ8 "s.k@YTsXtd`-}*P#@$޽YZ#;PGjPKu\kA@]iH횔w58xyL[ ߿p *PݻOCL+PuZ@(N\4){Nk+>W?`@L @ĔnJKW=e`]t_'A\%^@+@&,Z+ݰaoS>sb1.37I`6z/D`z"8x mqyL9C|vy:;h2c`݂ҁZY@{rޙArWGXc`݂nqvj0t )}CRa`5@Z:x mKϭ1nAʚ~C` fT|Ow@'繻rz<&u;eоw Vݿ;x 훽bz&utGRSҍ٩AtHtYwДXˀYziAߓX7=ܳTKB;>ǩu`Xr[ou끲 Нy?鲝8鲁tY!ІyMMLΚtq_2[/=~( _K:ڒoڕ>2ٳ&]إzоs<@M=cMÒ>CT?@b=`=Pu|[Z9ge@@=ozF }zb륗^:ܹs}__f@)}˃rb~(? #~~(?Ȋ_}H ;'âĊ@-jAJ 5_Js2,j@ԢĊZ@ij@P #Mqix≳[0j@ԢĊZ@ij@P_|Hv~`QԀXQE-ԀXiXGvNE 5ZԂXQ (M j@?iadXԀXQE-ԀXiXGvNE 5ZԂXQ (M juiadXԀXQE-ԀXiX?3 vNE 5ZԂXQ (M juiadXԀXQE-ԀXiX?S vNE 5ZԂXQ (M juiadXԀXQE-ԀXiXGvNE 5ZԂXQ (M j@O>iadXԀXQE-ԀXiXGvNE 5ZԂXQ (M j@?iadXԀXQE-ԀXiXGvNE 5ZԂXQ (M juiadXԀXQE-ԀXiX?# vNE 5ZԂXQ (M juiadXԀXQE-ԀXiX?C vNE 5ZԂXQ (M juiadXԀXQE-ԀXiX{y'۶mP?ɯ~ϋvNVnl Hя~Qf-(Nvܙ?OS:jլkeQ}>zhX?ݙ֓~nĴs2,-Ԁټ+6\eNĨRiPZ0EV@ 5VYJKCk ;'B g#k /ٟ)jԬ%f~UƤf g}:B (>aSOMwj[oe_m#aikv:e/8BPf-Xt?sK.Yw߽b}-ۦfP (f HYtoP lȏbhX{J#VX)z m2ҜSNe]-oˀ"5ZjւEBxԜyD-Z5DoP X5('z =꺞kfFRX׻;jժ%|uP|`M7:G~xWNxvr-O~&RZ95p:*gJjY '-TO_PmdK?t5]s_7;޽{{RKj5ZjւH}7ͲkJQu``6tis=I|i8MCjV뮻ni\}l(u]5Zjւ(}~vyQ (F ԁj4-윴#]. ޱcDze]6y\ jԬ"ojԀh}>RhXI9ݎ٤{[?.r~E$ )Qk@eRA1Lݾ/}ޚ\}~?ݶTJQ"hu``%t;N:-v~65.fEgak5fb}/_.:5|a5E-5 Jwjsx<ӝ+XzRn\?cCevNꫯ.ݻ{[1?NT@vC@-5kA>K۵kצQ (F ցj4ٝp_:-윴Kv~Jo_5on;R']tҽj>lvQ (V #ׁj4 .;v,]s_zRϧ\Yk@F2{;nW;jԬ|[Z@ij@>PyǦ;SjdV}ݷlgJhXiyG'NnK&픹aiˎnkHwܑ.BjY J"5]V-Ձj4niَ.m%- K 5 e9r$m?~6RCJG `}~v1}XMQ (f HYtoP lqL ;'B HIOݳgϲZ٣)靳/Vl)jԬ󳵣@Z@i5k@"|uP|`M/#"IځyϏvN%=!5V,ogתjլ][-k/[%hiadXZ{rO?YѢPKZ>?{Fc`e,jր̻ϷXZtkƥ~Z95 VjQ bE-45 VZ֑aQbE  VJSb``iZ95 VjQ bE-45 VZtCO ;'âĊ@-jAJ 5:Ҵs2,j@ԢĊZ@ij@P'OiadXԀXQE-ԀXiXGvNE 5ZԂXQ (M juiadXԀXQE-ԀXiXO8!ɰPZ+jB 04- +jP+-Ԁ%@Z95 VjQ bE-45 VZ֑aQbE  VJSb``iZ95 VjQ bE-45 VZcǎIs2,j@ԢĊZ@ij@P #M ;'âĊ@-jAJ 5zQ vNE 5ZԂXQ (M juiadXԀXQE-ԀXiXGvNE 5ZԂXQ (M j@ȑ# - +jP+-HɰPZ+jB (>>|XaQbE  VJSb``iZ95 VjQ bE-45 VZ^{MaQbE  VJSb``iZ95 VjQ bE-45 VZV;'Ò~J퇭fǎ]ve~"ydXrԏ@iٟd۶m??ܹ3MKQ (%ID֜nm(I ZgϞ5&ݮ@IUJRjh?^Vo~sZ d=/TX8 mdrԋ@-?''}ek!jC+9sf{e·~믿>l`<89$C6 0g޽{g[:g[6 j:˚t5}` gζ^veKpnV^}եa;ۺj A{(Ӯ]Y yX* X* X  xX 18X ` ` `l `, ` ` 8X+p1 WCa`  0`^ 0^ 0^ 02^ 0B^ 0b^Df`92+ph ,8@VV  + &+k +8@iV+p lW%X4 x(V+py307^̓ ` ,W[e``,+ExQV `# 8zX+ps1PW1PW9V  @8^$VB  @h^e` Ґ``*kX @U݀KX @UX1 b`%+Uug}&b`%+UXcJ$VO?TJ$V2ƊH Te`+X> +X+V"1PU7 } V"1P5V Db`*kX @U݀GIX @UX1?1 b`%+UEXoɶm۲я~駟Ϝg Db`n@W^ܹ3;P}/srYϾ{_*V"1PUu3k /ٟep͡J$VJ}ɵ^bhꪫ&o֊_~gZO>b۔Gms̙%\6b`%+UX۷lP\mP߿nvO=t? /dlWyH T H^̞-Mo6КC-wygzw/sugYs-*V"1PU5oW\qԩSJ_ڵkg{衇-*V"1PUu^g2gy֛ٟg`e T H͒9}3imwK.hs|vM?nm4V"1PU5Y\09zhv2{iɓ'cm۷O~_f[T Db`n@J–΋/h8O86G}t)wqDz_liso3X @U5֔ni: 3GnOLYms \"V"1PU5=wϞ=!jP./~bmx1)=lV}u=I3<]f/>WYÇg֢c`%+UEX{r\~Ǐgl;ng."V"1PU7 Ks$]{gʔ[O|XJ$V2ƊH T HH Te`+X$V D``ܰ$c`%+vm+& @8x s +X @HVB2 d` $+!X @HVB2 d` $+!X @HVB2 d` $+!X @HVB2 d` $+M&X&Nk6IENDB`DeepCopy-1.7.0/doc/deep-copy.png000066400000000000000000000252171317220176300164000ustar00rootroot00000000000000PNG  IHDR^:DsRGBgAMA a pHYsod*$IDATx^ɯee`~#b 82&BL8˜8@84!N1LҌT&0F#*^>{jWm~ȭ}Z9i *3|P Tg:'> @uO3|P Tg:'> @uO3|P Tg:'> @uO3|P Tg:'U}_z>jI|$(OܿoIMr:hOg}& Вu@XIUNt/rmjYu TO?T}F`+D3|R+-Yu TO>DD%\ ᓪ4\th: Wf*M'W4Z>+r$@Kb@4'Ui:Вu@XIU]裏$A4Z>JMr:hOtrE%\ ᓪ"Jh:d+D3|R+-Yu T>@D%\ ᓪ4\th: Wf*M'W4Z>+r׿$A4Z>JMr:hO?OIMr:hOtrE%\ ᓪtꪵN:i=r_MVߟ}ٵ38c5;?'"D3|RUWg9\ێ%-e\}c C_efMgpT8^{M2V|Ή=ZIU]{Fwyg{z( G?Ѣq~탟3h:m~ᵳ:k%]wQ]y)СCGm*D3|RU<Ӌh;U{8.C4ZʶXUr_JxŶ%CCjXIU]{wG~S)M߬Jy?/{4ZʶXEgO3]?3e}7>*[Lzť4]#NM2V߷3Q.}W>*Sl t4NRu{ ϩ>+rg?٢ WZ|7pyc@K[|2|*KLʃ.õ^{6>itN4Zʰ{hm>*ClG&%9>v?O4F 뀨+rғ̹{64SO]{nh:h˥gy憯s- n>*l6W\qņFdj,Nj@K뀖Z;];mTf観 j.--EZ3Y ᓪ"WȚ{Cx饗[΍7޸]v.S4Z\Ko+r͛3'`nR. [t8p`p,th)jТ du Tt6~(⋃+ˍg+-"-Ejkßa, ᓪf|ds;cjR:vO]fȕ7nΖo펗Cmh@ /0mh:ߗzn5!F?Q߳Efp Fq mɵ@K/ɜ>+rL)|K_Z4m&_sYomRu@^=NC ~ڱ ᓪZ79~4Z>+r @Kb@4'Ui:Вu@XIUNh:d+D3|RUW^}UIMr:hOtrE%\ ᓪ"wAIMr:hOtrE%\ ᓪ4\th: Wf8p@D%\ ᓪ4\th: WfȽ+ -Yu T䊦@Kb@4'Ui:Вu@XIU]{%A4Z>JMr:hOK/$ Вu@XIUNh:d+D3|R+-Yu T_|QD%\ ᓪ4\th: WfȽ -Yu T䊦@Kb@4'UuE矗th: Wf*M'W4Z>+r-sgq)g,?ПՎ@ C=vN>j'vI'޽{3lgܵk׎@ C=vJo:Yvb|^/%oɐ_ .ܦeSZz6R(Y.C۴ bZM?񢐗&S2Њuc>in+ϕW^(_ɘ~?MzNSzh饥:MƔ5K~O~2MXВ;|>={x}?{;?9Q`3J,=ul.:;Q&'VNyR\)cަw(]-ufdʙha9:VHgwNl*g ٭ Sedݻ^Kp?\s5G> 馛};v' P\@4Sed4pw_ NyPtk9]'1ÜeES{\3OFax|D35Oқ`=x9`S|;ǿ?b$5}_<KM~3Ws?t>I˥&u}x.sǍv+d$% hp W_&ᓔdr69?܂98>IǑ\L;2pv|,d$7o'0EN4G:dr)Yw0|#xΕPpx)p5cL yq1󼇝b, rn54nƨy-_Ef%+'aܧZiw >rgϞ=G>v10|{xL2cPu:S:sr& 4\=9c?XZ΀:n!3'Maȓm*p d6ĕPdb29+N;;L&Oq?b[<80ږ[qIKl<ٶ(nNIur vg21|Re7DrM<'I5eqG彼m7EOp-rk:{=QJwJ'Кᓕrfm<Z=`3D1|2 x8* @ =5hJ<=v<UrњsmQ8 v'DҒۡhD'WҌSj[y5>vLlV l3f?^NgAЂm) <1 z[4w޹ l#cUNt8;s1!pe5>gǦ~p<TN_ZYmVɖlih'CAݻwrr?/5>4OMei_ͪ>gp8(9?tjON4ndyt/|9=_eX8߽{|)'/8l;OB{٠oRǮLМH9 Q|}Ľlᓅ~!TSǾ0M;Ux+>6:PUǮ{.l)8KV>Yqp;~-8'`ʎO-g'?ls\.*8Z0^baJwa={lN&>!?DY 3e_*( 1|T$+f*اEfSsgb\ 0.Ox 35QCk:zSS>b3|Όт 1hj`sF<͎V\#hv>gVLi6e\xS(g?6Yfl!hɾC={|{>'4O%Kb9D4g>'k6lK$O/d`4s42>QjrL'-XΓsƓme_m6LY>><>'e dUxz@}eQ[|#91 ٕ}%:ze1adVn9!^Ȍtoad<>'400&:z6ȘF۷G2Dh6Q 3*a9} u{([ u(a9G9;Oؙ~uc.e17j3e_.q'l+H <>G ӓmgνL+g!G*Oؼ3L9B S߿Xj=]ϑqfsf\XNsDb.,r]}=cO׿3޳h aN\ 5=>̕S) \\39G|;-}’;Ga܎3\kG:ׁ0oC(C(̑𙘧|+g|m q2|&ld̍op4㌛3BOO\`Nrú2wg2;l G_`[o݁ 5⪀q1|&R^8.s 0en런q;x>qy lKn)r lq395e_r0v7w l+ lKnp l_wI \.;S:Խ:0V+P`k^C>9kQn\`lo_J[q0|r40F7z;ӿo<ȓ| A<V;  V*7ggh2pz.0ay>bP{s2|6ԿÓmP Zو1Ж#@F+<*W gxxooh:<g@_? J- \m1geμ@2pv {~x᳢}-vru@GOԂZ.g?<܇bݎɶVJ7xzu/6 + !P\0e^^%nk"{<sIP0.nvZ']`cܢ|wmx0>Coн',U gܢnZvP4tͥr\X끲0u ƭ׶X=uor뭷zLr)0X`'빻z`u []bSvHHa7Y0~W2Xs Kl#%lJ>(rVyw ʒ/| u [tu,NKp+_X!ttן)t;r{qi,u}ĥ62UW]Xj>7;#}n7eG-˥{8ki0cIw6KmN za=s@;gܤK.dإ)G;U^R]R߉e`g |$Maz{H(`0|nB}kׅV^w}7 :ַe="U/˓gk׮/~>@+CR^_.1Z%>'`aO hehDh2|ј'5 WК+5gIDh̓+jQԂ\Q hM ȕ`Q{`Ԁ\QZ@kj@Dր&租~* >Ԣ@ WZSr%>gyRrE Z+jY |$H<E-Ԁ\%rGcԀ\QZ@kj@D1Oj@DQ rE-55 W"k@?ј'5 WК+59Dh̓+jQԂ\Q hM ȕd裏$A"w4I 5(jAJd 0|(;@ WZSr%>gyRrE Z+jY ~$H<E-Ԁ\%rGcԀ\QZ@kj@Dր&| 1Oj@DQ rE-55 W"ksFј'5 WК+59Dh̓+jQԂ\Q hM ȕd׿% 1Oj@DQ rE-55 W"ksFј'5 WК+5S$rGcԀ\QZ@kj@D1Oj@DQ rE-55 W"kχzhNRN9唵_/s"w4i 5xꪫk@ɯ5(ug8{w ~NYZ}>{M?m|c3͘yC X3FYSϏDRɘyC xG@N;m^%s]x2O5}~Lu 4>{エy;y睷on ;N!:4mDhj@;S}oX5駟>@ZP>|xڰu]wvW^ym"kZ@k5v[m4o.S"w4i 5dlwze n%jQ"kA>߯,_J?KEZ%@d h2|is/~eG|7JG.;61Oc ̭ցn!jQ"kA>oo8R,5*jEր}~u >wД;,7r˫:[om&s-PY jv?vj*ZT hX"ky, ʡkvFD. 9Z@kQ5EcMrow}s]{~vmdJٔl8b<iٳgھ}Ȱ5tQY ~ݹKUɾ@d h2|뭳f)ڮ))GC˖(2t'wG\=wRRDւL}Kj}=g5kJ[M9}裏~݌јXJ)z袋Q_P?@knJQY fQ X끌}>K41-X#w4\bS.ٽ{gvM7o>ډ3Z*e]d@d h2|##YS`)+_?Sb҄JրrrSnJjrDa޺}oh>_ /nm[.?HD2lug)S߇ܮy+"k׮5ٶ0oݾ7_Nd8xEg@>TIzYN3g=ܳovCoaG[˒izʽc6?F\o\rvS@Z}\gy?fV-z CZ"ksMiyNƴyrt~Ik5+wQY "SO=v/># nUɾ@d 0|)wSO=u_.C"w4<_rpD|msZG-`ư@d h2|k^)7X7X/v1-RˏR_g5J3Dy'7ݼ@ZвkUɾc5æ|:?c1Ocg5si,u@ Jd-h_|vZd hR"k@᳜ΚktR.M);vY1OcO<Ć[R_bp QY ZvYZd hT"ksM/߰SCeI<,ˑ_|qp~.J i5(v_^f?:Y M^fHvRvƇ~xgJ<t)%jLY j~ڡZd RϏDwr^1Oc˹_9眳+ ~lQY jK'sY>?:Y tt֔7N#Y1OcJdK_?e@ZPϗKs?lʢ5Zd 8VVZ"k9%rGcԀ\QZ@kj@Dր&gZ1Oj@DQ rE-55 W"ksFј'5 WК+59Dh̓+jQԂ\Q hM ȕd,7J|"w4I 5(jAJd 0|(;@ WZSr%4><( 1Oj@DQ rE-55 W"ksFј'5 WК+59Dh̓+jQԂ\Q hM ȕd_z%IyRrE Z+jY 3J<E-Ԁ\%rGcԀ\QZ@kj@Dր&/( 1Oj@DQ rE-55 W"ksFј'5 WК+5 /HDh̓+jQԂ\Q hM ȕ`Q"w4I 5(jAJd h2|> ;@ WZSr%>gyRrE Z+jY +;4I|Z%>j `a"v4ih6J|Z$>59ꫯ>/*Ԁ|jA@Kj@`#hC  K ͇KѠ3J\ ֆCdO @uO3|P Tg:'> @uO3|P Tg:'> @uO3|P Tg:'> @uO3|P Tg:'> @uO*[[{-IENDB`DeepCopy-1.7.0/doc/graph.png000066400000000000000000000144441317220176300156140ustar00rootroot00000000000000PNG  IHDR]ݽsRGBgAMA a pHYsodIDATx^ݹoTqҦB2NED("҄%R2U@$+$& Q5+P@J?\YHk̽g&S*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$sPJ(@H իWA(@(!) ܗ/_$ W/ÇG~[O $ aIPPDBRϟ?'BBIPPDB+ QgψPPDB+ QӧOPPDB+ QD E $  QD E $c  QD E $QBBIa>z8E $QBBIa>|8E $QBBIaÆʔ)S6mZԩSTBBIa>x@.Νtuuehپ}{XPPDBrO5g1cFBBIa޿_*wޭ,[,+/2+G?G! QZgϞ..ZrW^PPDBRݓʮ]۶m[M!f'OF?{(@(!Io߾]3gNMݹs'$J1CBIxѬ͛7?+\) Qm*Qɺu벢oߺu'j>O! QVo+|9ZBBIa=49r$+ V_7ڟ#._\CBIJh_.]֭[8g}qPPDBR?5/u8~xkf{9 Q5vڵqV8+cǎE (@HR)@dɒg8ˍ7j.uPPDBRvs:D3}ŋ_[(@(!I׬Y-f޽ѯ- QPeboV\BBIa=6rPܹ3_=S(@(!I?WX=&3gTfΜ}-[y E $k/ ӧOה؞={bN/^} ;K(@(!{/cq%h$X .Ǝ+ '5 (@H ^<-wMyƊ[LDY@X$cǎׁcL+ Q]n۬2k֬>qIך?~ab (@HZ" {ePPDB+ QD E ${U  QD E ${  QD E $QBBIaڻCBIPPDBR.]"BBIPPDB+ QH$ W(@(!) ܡ!  QD E $QBBIa$ W(@(!) ܁  QD E ${  QD E $̞=3OѾ؟: PԩS+SLtvvFC{ﱣ#% Jcƍo fO>ᅬ!7oξŋGig(@F 𫯾J=vx~(@F___ӳ~L>1Vw}3Ďiu(@xGuww|TǼy߻ _("0l'S@3D/<{gΟ?=]|G S- 'Of?ϦMF> rvޝ{YA#^( {X6v ~6$Zg@(@w|WjæDR-i?[x4YQH^jcg( IKX|H d3Ҋ/V@j(@$HpVPDRR9^ E(@$CBϊ" ~PH9> EJ(@^ 72RAԸ59lB (@'8 bx}eGlBQ(v26m r@YP(^'΃!g"3ᑏ:(@H^T u {~PBB :g|v|X(!͞Nah`g(Pp:G % \cǧvBx6+3Qp+?Mzo (@Ďre+; B |h= m@İ.P mÎO%\ڂD[. x+=+?[#V@Qh9vaX+h' -ŎOLmbag(ZDKPagAQh v|Vt{8D#;Cr:L ]|h6ZD:.4  5h%JXh`ځuf0^v+ DCx^P4Ĥ;Ea(@L ;>Q4vQ &h c'<ɯᑏoGbB ɢ1nsW/l(06 ®;xgk4<@(0: o뮠 c سPlX(@Pdúeg(FCbT rŽcg(ކ`g(B;>Q6\h(@dobg(b(@d;( *!z Gd y`%kZÚ׺"]`xRU 0QAx?PJ8vLDQ.;>7寎|eF&34-`_xRr`+=+pE;>agh(bWΡޑL(+V|Z>`ɰh.X2DT`gh9Q%O^>` whM}8e2C ˍ} o/ P;Ӏb?'& P@bY#܃F _x . P6O7Ez(@<43T \;>{zzF> (@]h@:ad.{J0ܺ;(D8Y츏C(<;\t"_~a'P;Cţ?Q";>rg~኎=# ]< Ёp3v^˚绝(X> ;?2hq$ pܹHWWWD\-@֟Z켷.\1j(@Ҵ[.W^Q]  ]/_$+3$ '>>|x43WTgtx8H}؂hf 4]_Qs :(@pT?t1|EuP.~b .gϞQ] @+3@>}JDuC3WTgH.f 4]_Q :(@pT?t1|EuHǏ.~b IQ] @+3@=zDDuC3WTgH.f|!q]_Q i8:(L2eB6mZԩSѯ9fXٰaCtXx .o]I(] 3>ΝtuuEX@(EU?t)̀|z7Vf̘Q~zkz .ͯ-EUnݺ=.]v]=ST?t)ݻw+˖-9-̈́gϾ,Qa ELZOG] 3~\,0zq^: ޽{nsњEqO[crqmp kbæzg@]ǎ?ܲeK: Uk<-Z+@{A{Ѳsy?v^ _zgݷ_ű9s2sٳ'z\Q`h_B3f@UZϟ_}+ ]vykEآžר.~R.}Κ5+z[y IQ]  ]vm]_Q i8:(@pT?t1|EuHn]_Q i8: ]_Q i8:(@pT?t1|EuH)>:(@pT?t1|EuHQ,)>:(@pT?t1|EuP.~b .@⣺+3$ GuC3WTgt Q] @+3$ GuC3WTgtQ] @+3@.~b IQ]  ].\ +3$ GuC3WTgt_Q[[ 4-jb Y17n|/HZ]i 8G!). NQ$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$QU*uWIENDB`DeepCopy-1.7.0/fixtures/000077500000000000000000000000001317220176300151025ustar00rootroot00000000000000DeepCopy-1.7.0/fixtures/f001/000077500000000000000000000000001317220176300155505ustar00rootroot00000000000000DeepCopy-1.7.0/fixtures/f001/A.php000066400000000000000000000003601317220176300164400ustar00rootroot00000000000000aProp; } public function setAProp($prop) { $this->aProp = $prop; return $this; } } DeepCopy-1.7.0/fixtures/f001/B.php000066400000000000000000000003721317220176300164440ustar00rootroot00000000000000bProp; } public function setBProp($prop) { $this->bProp = $prop; return $this; } } DeepCopy-1.7.0/fixtures/f002/000077500000000000000000000000001317220176300155515ustar00rootroot00000000000000DeepCopy-1.7.0/fixtures/f002/A.php000066400000000000000000000006631317220176300164470ustar00rootroot00000000000000prop1; } public function setProp1($prop) { $this->prop1 = $prop; return $this; } public function getProp2() { return $this->prop2; } public function setProp2($prop) { $this->prop2 = $prop; return $this; } } DeepCopy-1.7.0/fixtures/f003/000077500000000000000000000000001317220176300155525ustar00rootroot00000000000000DeepCopy-1.7.0/fixtures/f003/Foo.php000066400000000000000000000005201317220176300170030ustar00rootroot00000000000000name = $name; } public function getProp() { return $this->prop; } public function setProp($prop) { $this->prop = $prop; return $this; } }DeepCopy-1.7.0/fixtures/f004/000077500000000000000000000000001317220176300155535ustar00rootroot00000000000000DeepCopy-1.7.0/fixtures/f004/UnclonableItem.php000066400000000000000000000003011317220176300211570ustar00rootroot00000000000000cloned = true; } } DeepCopy-1.7.0/fixtures/f006/000077500000000000000000000000001317220176300155555ustar00rootroot00000000000000DeepCopy-1.7.0/fixtures/f006/A.php000066400000000000000000000005251317220176300164500ustar00rootroot00000000000000aProp; } public function setAProp($prop) { $this->aProp = $prop; return $this; } public function __clone() { $this->cloned = true; } } DeepCopy-1.7.0/fixtures/f006/B.php000066400000000000000000000005251317220176300164510ustar00rootroot00000000000000bProp; } public function setBProp($prop) { $this->bProp = $prop; return $this; } public function __clone() { $this->cloned = true; } } DeepCopy-1.7.0/fixtures/f007/000077500000000000000000000000001317220176300155565ustar00rootroot00000000000000DeepCopy-1.7.0/fixtures/f007/FooDateInterval.php000066400000000000000000000003101317220176300213070ustar00rootroot00000000000000cloned = true; } } DeepCopy-1.7.0/fixtures/f007/FooDateTimeZone.php000066400000000000000000000003101317220176300212550ustar00rootroot00000000000000cloned = true; } } DeepCopy-1.7.0/fixtures/f008/000077500000000000000000000000001317220176300155575ustar00rootroot00000000000000DeepCopy-1.7.0/fixtures/f008/A.php000066400000000000000000000003221317220176300164450ustar00rootroot00000000000000foo = $foo; } public function getFoo() { return $this->foo; } } DeepCopy-1.7.0/fixtures/f008/B.php000066400000000000000000000000671317220176300164540ustar00rootroot00000000000000 Filter, 'matcher' => Matcher] pairs. */ private $filters = []; /** * Type Filters to apply. * * @var array Array of ['filter' => Filter, 'matcher' => Matcher] pairs. */ private $typeFilters = []; /** * @var bool */ private $skipUncloneable = false; /** * @var bool */ private $useCloneMethod; /** * @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will be used * instead of the regular deep cloning. */ public function __construct($useCloneMethod = false) { $this->useCloneMethod = $useCloneMethod; $this->addTypeFilter(new DateIntervalFilter(), new TypeMatcher(DateInterval::class)); $this->addTypeFilter(new SplDoublyLinkedListFilter($this), new TypeMatcher(SplDoublyLinkedList::class)); } /** * If enabled, will not throw an exception when coming across an uncloneable property. * * @param $skipUncloneable * * @return $this */ public function skipUncloneable($skipUncloneable = true) { $this->skipUncloneable = $skipUncloneable; return $this; } /** * Deep copies the given object. * * @param mixed $object * * @return mixed */ public function copy($object) { $this->hashMap = []; return $this->recursiveCopy($object); } public function addFilter(Filter $filter, Matcher $matcher) { $this->filters[] = [ 'matcher' => $matcher, 'filter' => $filter, ]; } public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher) { $this->typeFilters[] = [ 'matcher' => $matcher, 'filter' => $filter, ]; } private function recursiveCopy($var) { // Matches Type Filter if ($filter = $this->getFirstMatchedTypeFilter($this->typeFilters, $var)) { return $filter->apply($var); } // Resource if (is_resource($var)) { return $var; } // Array if (is_array($var)) { return $this->copyArray($var); } // Scalar if (! is_object($var)) { return $var; } // Object return $this->copyObject($var); } /** * Copy an array * @param array $array * @return array */ private function copyArray(array $array) { foreach ($array as $key => $value) { $array[$key] = $this->recursiveCopy($value); } return $array; } /** * Copies an object. * * @param object $object * * @throws CloneException * * @return object */ private function copyObject($object) { $objectHash = spl_object_hash($object); if (isset($this->hashMap[$objectHash])) { return $this->hashMap[$objectHash]; } $reflectedObject = new ReflectionObject($object); $isCloneable = $reflectedObject->isCloneable(); if (false === $isCloneable) { if ($this->skipUncloneable) { $this->hashMap[$objectHash] = $object; return $object; } throw new CloneException( sprintf( 'The class "%s" is not cloneable.', $reflectedObject->getName() ) ); } $newObject = clone $object; $this->hashMap[$objectHash] = $newObject; if ($this->useCloneMethod && $reflectedObject->hasMethod('__clone')) { return $newObject; } if ($newObject instanceof DateTimeInterface || $newObject instanceof DateTimeZone) { return $newObject; } foreach (ReflectionHelper::getProperties($reflectedObject) as $property) { $this->copyObjectProperty($newObject, $property); } return $newObject; } private function copyObjectProperty($object, ReflectionProperty $property) { // Ignore static properties if ($property->isStatic()) { return; } // Apply the filters foreach ($this->filters as $item) { /** @var Matcher $matcher */ $matcher = $item['matcher']; /** @var Filter $filter */ $filter = $item['filter']; if ($matcher->matches($object, $property->getName())) { $filter->apply( $object, $property->getName(), function ($object) { return $this->recursiveCopy($object); } ); // If a filter matches, we stop processing this property return; } } $property->setAccessible(true); $propertyValue = $property->getValue($object); // Copy the property $property->setValue($object, $this->recursiveCopy($propertyValue)); } /** * Returns first filter that matches variable, `null` if no such filter found. * * @param array $filterRecords Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and * 'matcher' with value of type {@see TypeMatcher} * @param mixed $var * * @return TypeFilter|null */ private function getFirstMatchedTypeFilter(array $filterRecords, $var) { $matched = $this->first( $filterRecords, function (array $record) use ($var) { /* @var TypeMatcher $matcher */ $matcher = $record['matcher']; return $matcher->matches($var); } ); return isset($matched) ? $matched['filter'] : null; } /** * Returns first element that matches predicate, `null` if no such element found. * * @param array $elements Array of ['filter' => Filter, 'matcher' => Matcher] pairs. * @param callable $predicate Predicate arguments are: element. * * @return array|null Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and 'matcher' * with value of type {@see TypeMatcher} or `null`. */ private function first(array $elements, callable $predicate) { foreach ($elements as $element) { if (call_user_func($predicate, $element)) { return $element; } } return null; } } DeepCopy-1.7.0/src/DeepCopy/Exception/000077500000000000000000000000001317220176300174665ustar00rootroot00000000000000DeepCopy-1.7.0/src/DeepCopy/Exception/CloneException.php000066400000000000000000000001771317220176300231230ustar00rootroot00000000000000setAccessible(true); $oldCollection = $reflectionProperty->getValue($object); $newCollection = $oldCollection->map( function ($item) use ($objectCopier) { return $objectCopier($item); } ); $reflectionProperty->setValue($object, $newCollection); } } DeepCopy-1.7.0/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php000066400000000000000000000013011317220176300272000ustar00rootroot00000000000000setAccessible(true); $reflectionProperty->setValue($object, new ArrayCollection()); } } DeepCopy-1.7.0/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php000066400000000000000000000006231317220176300252150ustar00rootroot00000000000000__load(); } } DeepCopy-1.7.0/src/DeepCopy/Filter/Filter.php000066400000000000000000000005341317220176300207150ustar00rootroot00000000000000callback = $callable; } /** * Replaces the object property by the result of the callback called with the object property. * * {@inheritdoc} */ public function apply($object, $property, $objectCopier) { $reflectionProperty = ReflectionHelper::getProperty($object, $property); $reflectionProperty->setAccessible(true); $value = call_user_func($this->callback, $reflectionProperty->getValue($object)); $reflectionProperty->setValue($object, $value); } } DeepCopy-1.7.0/src/DeepCopy/Filter/SetNullFilter.php000066400000000000000000000007421317220176300222250ustar00rootroot00000000000000setAccessible(true); $reflectionProperty->setValue($object, null); } } DeepCopy-1.7.0/src/DeepCopy/Matcher/000077500000000000000000000000001317220176300171135ustar00rootroot00000000000000DeepCopy-1.7.0/src/DeepCopy/Matcher/Doctrine/000077500000000000000000000000001317220176300206625ustar00rootroot00000000000000DeepCopy-1.7.0/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php000066400000000000000000000005571317220176300255170ustar00rootroot00000000000000class = $class; $this->property = $property; } /** * Matches a specific property of a specific class. * * {@inheritdoc} */ public function matches($object, $property) { return ($object instanceof $this->class) && $property == $this->property; } } DeepCopy-1.7.0/src/DeepCopy/Matcher/PropertyNameMatcher.php000066400000000000000000000007701317220176300235610ustar00rootroot00000000000000property = $property; } /** * Matches a property by its name. * * {@inheritdoc} */ public function matches($object, $property) { return $property == $this->property; } } DeepCopy-1.7.0/src/DeepCopy/Matcher/PropertyTypeMatcher.php000066400000000000000000000020461317220176300236200ustar00rootroot00000000000000propertyType = $propertyType; } /** * {@inheritdoc} */ public function matches($object, $property) { try { $reflectionProperty = ReflectionHelper::getProperty($object, $property); } catch (ReflectionException $exception) { return false; } $reflectionProperty->setAccessible(true); return $reflectionProperty->getValue($object) instanceof $this->propertyType; } } DeepCopy-1.7.0/src/DeepCopy/Reflection/000077500000000000000000000000001317220176300176225ustar00rootroot00000000000000DeepCopy-1.7.0/src/DeepCopy/Reflection/ReflectionHelper.php000066400000000000000000000041761317220176300235750ustar00rootroot00000000000000getProperties() does not return private properties from ancestor classes. * * @author muratyaman@gmail.com * @see http://php.net/manual/en/reflectionclass.getproperties.php * * @param ReflectionClass $ref * * @return ReflectionProperty[] */ public static function getProperties(ReflectionClass $ref) { $props = $ref->getProperties(); $propsArr = array(); foreach ($props as $prop) { $propertyName = $prop->getName(); $propsArr[$propertyName] = $prop; } if ($parentClass = $ref->getParentClass()) { $parentPropsArr = self::getProperties($parentClass); foreach ($propsArr as $key => $property) { $parentPropsArr[$key] = $property; } return $parentPropsArr; } return $propsArr; } /** * Retrieves property by name from object and all its ancestors. * * @param object|string $object * @param string $name * * @throws PropertyException * @throws ReflectionException * * @return ReflectionProperty */ public static function getProperty($object, $name) { $reflection = is_object($object) ? new ReflectionObject($object) : new ReflectionClass($object); if ($reflection->hasProperty($name)) { return $reflection->getProperty($name); } if ($parentClass = $reflection->getParentClass()) { return self::getProperty($parentClass->getName(), $name); } throw new PropertyException( sprintf( 'The class "%s" doesn\'t have a property with the given name: "%s".', is_object($object) ? get_class($object) : $object, $name ) ); } } DeepCopy-1.7.0/src/DeepCopy/TypeFilter/000077500000000000000000000000001317220176300176175ustar00rootroot00000000000000DeepCopy-1.7.0/src/DeepCopy/TypeFilter/Date/000077500000000000000000000000001317220176300204745ustar00rootroot00000000000000DeepCopy-1.7.0/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php000066400000000000000000000011771317220176300247430ustar00rootroot00000000000000 $propertyValue) { $copy->{$propertyName} = $propertyValue; } return $copy; } } DeepCopy-1.7.0/src/DeepCopy/TypeFilter/ReplaceFilter.php000066400000000000000000000010141317220176300230450ustar00rootroot00000000000000callback = $callable; } /** * {@inheritdoc} */ public function apply($element) { return call_user_func($this->callback, $element); } } DeepCopy-1.7.0/src/DeepCopy/TypeFilter/ShallowCopyFilter.php000066400000000000000000000003371317220176300237450ustar00rootroot00000000000000copier = $copier; } /** * {@inheritdoc} */ public function apply($element) { $newElement = clone $element; $copy = $this->createCopyClosure(); return $copy($newElement); } private function createCopyClosure() { $copier = $this->copier; $copy = function (SplDoublyLinkedList $list) use ($copier) { // Replace each element in the list with a deep copy of itself for ($i = 1; $i <= $list->count(); $i++) { $copy = $copier->recursiveCopy($list->shift()); $list->push($copy); } return $list; }; return Closure::bind($copy, null, DeepCopy::class); } } DeepCopy-1.7.0/src/DeepCopy/TypeFilter/TypeFilter.php000066400000000000000000000003021317220176300224120ustar00rootroot00000000000000type = $type; } /** * @param mixed $element * * @return boolean */ public function matches($element) { return is_object($element) ? is_a($element, $this->type) : gettype($element) === $this->type; } } DeepCopy-1.7.0/src/DeepCopy/deep_copy.php000066400000000000000000000004041317220176300202060ustar00rootroot00000000000000copy($value); }