pax_global_header00006660000000000000000000000064126536362570014531gustar00rootroot0000000000000052 comment=8d4a92447a5c62bff9f89756caeb4c9c8770579b pinkie-2.0.4/000077500000000000000000000000001265363625700130135ustar00rootroot00000000000000pinkie-2.0.4/.editorconfig000066400000000000000000000003471265363625700154740ustar00rootroot00000000000000root = true [*] indent_style = tab end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [{package.json,*.yml}] indent_style = space indent_size = 2 [*.md] trim_trailing_whitespace = false pinkie-2.0.4/.gitattributes000066400000000000000000000000141265363625700157010ustar00rootroot00000000000000* text=auto pinkie-2.0.4/.gitignore000066400000000000000000000000311265363625700147750ustar00rootroot00000000000000node_modules .nyc_output pinkie-2.0.4/.travis.yml000066400000000000000000000001751265363625700151270ustar00rootroot00000000000000sudo: false language: node_js node_js: - 'stable' - '4' - 'iojs' - '0.12' - '0.10' after_success: npm run coverage pinkie-2.0.4/appveyor.yml000066400000000000000000000010531265363625700154020ustar00rootroot00000000000000environment: matrix: - nodejs_version: '5' - nodejs_version: '4' - nodejs_version: '0.12' - nodejs_version: '0.10' install: - ps: Install-Product node $env:nodejs_version - set CI=true - npm -g install npm@latest || (timeout 30 && npm -g install npm@latest) - set PATH=%APPDATA%\npm;%PATH% - npm install || (timeout 30 && npm install) matrix: fast_finish: true build: off version: '{build}' shallow_clone: true clone_depth: 1 test_script: - node --version - npm --version - npm run test || (timeout 30 && npm run test) pinkie-2.0.4/index.js000066400000000000000000000134571265363625700144720ustar00rootroot00000000000000'use strict'; var PENDING = 'pending'; var SETTLED = 'settled'; var FULFILLED = 'fulfilled'; var REJECTED = 'rejected'; var NOOP = function () {}; var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function'; var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; var asyncQueue = []; var asyncTimer; function asyncFlush() { // run promise callbacks for (var i = 0; i < asyncQueue.length; i++) { asyncQueue[i][0](asyncQueue[i][1]); } // reset async asyncQueue asyncQueue = []; asyncTimer = false; } function asyncCall(callback, arg) { asyncQueue.push([callback, arg]); if (!asyncTimer) { asyncTimer = true; asyncSetTimer(asyncFlush, 0); } } function invokeResolver(resolver, promise) { function resolvePromise(value) { resolve(promise, value); } function rejectPromise(reason) { reject(promise, reason); } try { resolver(resolvePromise, rejectPromise); } catch (e) { rejectPromise(e); } } function invokeCallback(subscriber) { var owner = subscriber.owner; var settled = owner._state; var value = owner._data; var callback = subscriber[settled]; var promise = subscriber.then; if (typeof callback === 'function') { settled = FULFILLED; try { value = callback(value); } catch (e) { reject(promise, e); } } if (!handleThenable(promise, value)) { if (settled === FULFILLED) { resolve(promise, value); } if (settled === REJECTED) { reject(promise, value); } } } function handleThenable(promise, value) { var resolved; try { if (promise === value) { throw new TypeError('A promises callback cannot return that same promise.'); } if (value && (typeof value === 'function' || typeof value === 'object')) { // then should be retrieved only once var then = value.then; if (typeof then === 'function') { then.call(value, function (val) { if (!resolved) { resolved = true; if (value === val) { fulfill(promise, val); } else { resolve(promise, val); } } }, function (reason) { if (!resolved) { resolved = true; reject(promise, reason); } }); return true; } } } catch (e) { if (!resolved) { reject(promise, e); } return true; } return false; } function resolve(promise, value) { if (promise === value || !handleThenable(promise, value)) { fulfill(promise, value); } } function fulfill(promise, value) { if (promise._state === PENDING) { promise._state = SETTLED; promise._data = value; asyncCall(publishFulfillment, promise); } } function reject(promise, reason) { if (promise._state === PENDING) { promise._state = SETTLED; promise._data = reason; asyncCall(publishRejection, promise); } } function publish(promise) { promise._then = promise._then.forEach(invokeCallback); } function publishFulfillment(promise) { promise._state = FULFILLED; publish(promise); } function publishRejection(promise) { promise._state = REJECTED; publish(promise); if (!promise._handled && isNode) { global.process.emit('unhandledRejection', promise._data, promise); } } function notifyRejectionHandled(promise) { global.process.emit('rejectionHandled', promise); } /** * @class */ function Promise(resolver) { if (typeof resolver !== 'function') { throw new TypeError('Promise resolver ' + resolver + ' is not a function'); } if (this instanceof Promise === false) { throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); } this._then = []; invokeResolver(resolver, this); } Promise.prototype = { constructor: Promise, _state: PENDING, _then: null, _data: undefined, _handled: false, then: function (onFulfillment, onRejection) { var subscriber = { owner: this, then: new this.constructor(NOOP), fulfilled: onFulfillment, rejected: onRejection }; if ((onRejection || onFulfillment) && !this._handled) { this._handled = true; if (this._state === REJECTED && isNode) { asyncCall(notifyRejectionHandled, this); } } if (this._state === FULFILLED || this._state === REJECTED) { // already resolved, call callback async asyncCall(invokeCallback, subscriber); } else { // subscribe this._then.push(subscriber); } return subscriber.then; }, catch: function (onRejection) { return this.then(null, onRejection); } }; Promise.all = function (promises) { if (!Array.isArray(promises)) { throw new TypeError('You must pass an array to Promise.all().'); } return new Promise(function (resolve, reject) { var results = []; var remaining = 0; function resolver(index) { remaining++; return function (value) { results[index] = value; if (!--remaining) { resolve(results); } }; } for (var i = 0, promise; i < promises.length; i++) { promise = promises[i]; if (promise && typeof promise.then === 'function') { promise.then(resolver(i), reject); } else { results[i] = promise; } } if (!remaining) { resolve(results); } }); }; Promise.race = function (promises) { if (!Array.isArray(promises)) { throw new TypeError('You must pass an array to Promise.race().'); } return new Promise(function (resolve, reject) { for (var i = 0, promise; i < promises.length; i++) { promise = promises[i]; if (promise && typeof promise.then === 'function') { promise.then(resolve, reject); } else { resolve(promise); } } }); }; Promise.resolve = function (value) { if (value && typeof value === 'object' && value.constructor === Promise) { return value; } return new Promise(function (resolve) { resolve(value); }); }; Promise.reject = function (reason) { return new Promise(function (resolve, reject) { reject(reason); }); }; module.exports = Promise; pinkie-2.0.4/license000066400000000000000000000021501265363625700143560ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) Vsevolod Strukchinsky (github.com/floatdrop) 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. pinkie-2.0.4/media/000077500000000000000000000000001265363625700140725ustar00rootroot00000000000000pinkie-2.0.4/media/logo.png000066400000000000000000002354451265363625700155550ustar00rootroot00000000000000PNG  IHDR\rf:IDATxdۖɪֳm۶gkgBam6<{/bvd]5sjk&fھ}{i°4Mۿmܾ{cb{fWl7N;z{M[[!{]akX{m9fCYnfJfmcfX&?7= αǽF/B~t5p֞kOGC>x^LJR%eB:W4 L{؃${ZW{^Rk}M6jÒYfV Yi4(iVdWg_mz 9 gV{άT+5'*TU%u I *S0$ў%V7PlӚs%xsk ov/X:_wޘ5Y_<~ӡ\ |̯ ] VǙa?~qO|MUse_͓ ɄD(Ms $  Lrp̔#7hbl%vyk W(mq0%1f Zpzt>ý ⋠a {J]>f:> B%\TLa@( 4@n2ӽd}Ā֙AaǞdؕ<L 5YwO w^ȷ<;ou3Ywz_.C?׺dOu 2%Q!u$T@R&!gT,LV|Cpz(*0n R{C6:h 0<~|y; ׀m?}.c_W $4*(')3 $ATt 9 ~J*ȈI, I)$)DI0]m?|08*h8- !md;[3x١n`fQ^Հ'W0գCw3D"T$dUfTM!DB! Yљ3a&(0^" Q0dij{9p=m0k \~{vuhAX"{6~[nF0k¯ >29< cY?ſ͜,sE%R2Ed"Sl@MHgS$00$ 0@Ptb¢ D @ 0 ^A@4ãB9N{Xn0c~Pxsrɑ?v$:iKsP$mć42OrL:c"I@d1}GA(1D U h!˶7pݟll5`- ~V{hckg,3F0kV{ϙW(?YX}|='qb# ɰ4,3Y$X/DB:SP ՐdEk`z$@4ay&m*خMvXZ5Y߱#^WvӋ'!ʻ:[IuY6 A&YE`D|_Bf` @ [ HV#ڸF 39lf2 ^sk0 !`*!t_u.{W,XB7;lfg|T/16'AW_9?O(L aI*2hŇ 9L dt2h,$PeD d1<AL6t;n`*0j}95G&%KFY#5˽Ԩ>K֧_׻+ߢ\P$eB@(Q* *dBĆEϠj$J }dNx8Ī)#4mFk86*HaqG{@RbR %9m/rѿ~bm+ss[Ÿ@ޠ{;x3sT$)$&(eIR:jTՀsH" 9J!4m<, A@le"0rmpdO@{E.[:W̼3330*S*Sz\qBc絤PV*]ҽYw|`Yz<B?uϽϟw׿d xf;,/HF ha,TbC4Rj ߨhm2;CAi6`[ޞmPDZyz wx}Os~={q~ ?0GY$b񇝼+ߐP@l :;ر& #k#h?^{2U{ uGDxwR|*7Goo-tG}ӟo~:|K?u_!y(&yjG AD#4B ` A@E';CRMT6U- *VĚ@cv{gjoi-mu5LSDq{{g=Cll_ |09ɏ}DNBDYxK(0}q; @:$P^!(M/r=3s^ )A۱uo@x[8|5IF/Y"R6x>|سc 蛘O.(`֯g'q o˸ϙ'MO ]ɡ*Ph0:HWH"0R 4Hvb 6nйW6Dy/ -/g`%18`@#y"a0Ȩ7:j0c#\#~'3]]*]C5{QP3>1pO]$Xa7 h% `@#$uR P^|z MО8@=*k}-#oJT-N KoHJ{k !S4煬6 5'xܹ7nߋ@g~ryG}s}Ϫ6M&$ddd9deH"$T{P ZƧuMmAIz)R( }wE/@c{oBkݑNd}'4^Nus>l;0Fyz9FH6cjdAb#ҚW=c?w-/ ]}e} sϽa;~Yn% RCHx@ %pȠ6r A!z?dc@ DVY]Q06`7D !& 3y 5ZI@F0SOW l.>"=[ R +J;|vԧK~9+crdnTڠVW8(I"ZBFv7Hr&d)Kl((S8ys,eF T m#;ȞY$ #z(bmӎ-<ŀhaI`Ho<;A59qY!m/2r:R,~]MͰ}^`+#={y_ \:^&y gbZ͏ vo? R`4 ؒkJ3%F2(iCҼ]PFzk ca 3P -cQBoж=eRdѸ 34)yo;LKTZUT&|vLսƉ\ 2S`n34cs{(凚]Hw ]Gloo<郔9̤a%zplu[n'ځ"z;Y --j_E" QTZ/#@UX ځXgw9Hz 45̷̧o^#o\޼J|=ܼB޸|oy*qz[6u7\4T0 xǞLNٽ; u񹿩+ ;_\>l8Z+8v )v z KA0m@ nk$gGLD٢{3Y#-jZH:D0b G6}#En_#߀o\ܠozrFNd#'ԙ|3z77=vr+R=0@&}1HB{{m^? |7~{ݎwU6;z'8Ϙo_ 9EU2MZ8W 1^4^e l[h@ ^e~C=?S DDoi0x#衶:r ${F^hi^d3|<AU}~ה9̷>ͧ2aBfrv2ĝ#},]6veхb4 6N`s!^K>Wg}%uw`ľǗ}%~ݭNy*f4 x],m[A~R{m45p Ձ`,Fl:لzl"45kVӄGI @Fur 0mpj[Ϩ7[ B%jp~~-` cD> lw'4JN X8lD;&;wD5Ig{&,*1+l+wb.n͐/x'@@s'dbvWtWw Ẉ|i҉3!2PzP[BZYs}O]ǘ9'3!J:Q_C'mtXl˜0J@#Qt'gwp/ ib?'<º}Nh(gH-Q/gD قWJ<HD)I"se?ZQ&JH:qg"g "b#s^|ǟ; ^|peq??G?0]*K46 !&i~ִf!lAe;і~nH[0ea۶PƵ*\iI$7:Fe˦D[Ve7= 9߹NܼĶBc*)ےk֮4.3ӹl Iei Jl3&%! 8ɢF]?2 ʦywbznUS=5;Y(4oiВ ]tLĴm@ke@ LPBdﵽL͸ؖ vc&"TuJ~ uGF AZ@B NX搅~k7;Iѹ1]4NN@jDD)j&r6N"'H9|_%//6ۄS @ . ?/}ބlb=dw-@ 7` leIKiRc>c$G߀y|[Jl~)[NlIRSwqIJm'?ZVZ/,BKMҐݙC taO~Yg!" J]rFK9djJF@aCE10uG-{⬈Fv~d-nwD)L 9;PicP'!pV9%~G}ʏ> +?o7kbz;@XCL[ . H8B ( F{uۦu{Kp4 ` ~0 #H]lBj ^У*"A3rp+ 7:yzqIo? x~| QoCC`QAN 0liRsΪkpG8}nkߝB ɉ0 v޴:vW^WOx9/C"40.B5*@#Zصl@ F`!=),Enj(`xC@W (ĊNݓw9wb{]}DZeYdhFvue3124pu\C]{^z|YEKp\yc;%^Dic)Cu"Y!zj{gBw=c0E7a1-)%.lгp澿Gʕk#F3P_y9xX`W&dyO}DOI_ jfMfak <FCC `ȳ;dVRjtkj6a*@MP]a>e+c>>ԏ1S@?[ ū/zryZj$[Z{쀐 BFMmK+U ɒ@H ;-X<̥&5ehE2F\m+@IZ*\AN$#"%%" rJqYyBAHa, CDDY VKBz {jN˙`N6v:yfYʙS5S[ ) i-™H!۩(؝P3 \p: u{պdž'_zio> WJ}J՗~V޺Պù[` ޶;({FB,Jh~-!DODW Ѭg ՕV-fNjXAԵ%$q ֽܶ'jDĐ-<#*8 hdCkedf {;]7.S`Q.WJ?;AuOqZoNc%]p4iXiI9Di'i+L9ge^T 4E:W_xG|H@" 0C˿|hew1  F&lcř J.-Cn@al?T `3O`@@ V2Hh`7 _;~.k'Rw6Wk/!x=gb1 ay-fpgE%*4G"pzo^fbsofdn0 `d{`LFRV}nA _لKl[j5靮(J "Y&6rNtpAK?Q. >e@}VO(n^rg|fheC B^T[K݄t!$Q(4D&KA*ى$7w@R!Ȓ B2iEcG$EXea VzVbdlwB" J`a ݖ^ƃyv@a$%HRX$-۪azj5n+ K3#N|Ɣ Nie@)4N%:svr[Ң #l ~P%d uNSpmSe;A `>iYrډ"RLh{⹆P.%g86}9} udR6@?̧7>/||?$vT7diI"5͠l $$!ĄU9"[pֶ$%-", 昄B%WUR`))~C R`(: q"< & DVKT˨r"HIN R8e ÃHwG(D&3-t ү(5e4Ib_=$Q,$AJ,{9OfJ#iu?̢V`a^}l.33effeݟa~4R*3i*#,¤|,UQOf82&\I<9$0K%EdrG[,iO:qǵ!("F~y.V?g_؜W߿ߟvD H7o~oGERi&eOᰂ=ndx:xuYސ0cVǡY%tj%(j^g ԨvxZ7}%)je22f@oؽmRrէ])yWjlTL}\HnA)/ur4XY2!Yn K.ouǥD3J^ZDm=_qX j RiA/ ZFZGxTC$eӗE! rCDG!K\|z* :IhN@ii3Ľ}}W;Kdz\Se"А:k{!%<ZFGqpP| `9t [,a ᐖC+c􇧣Ň{O=)gG7g hHyFqE| (C<"Sò+^Z&kmT(EWm\iHyy7|&|. 2*_b *!!Ⳙii& Y6)!D ~5 /A1&ȴG RN}>FiOg)kթr8)ǁjd&k T0"Qhɐ&8i!']iܡ]8[PFU*R85Ctx^Z=W[˞ /gEtq]=E*vTBzuz&51ጣuVéN6,)EqA)M:4'w[8Yqw-B>ɯEأL F"Z2$및XMK5# )7YѸi-Ԝ!<vO97$b{yu̵\I}@cd{EU35@Tje@DJ; uM;B\QL L21fKdq$ӽ7E7cmqծo(߽ן'>} F(5`ʖ,Y/6\?yzN$؊Η!@37oln/IDPT;2 fMZ~X@'5cxm/%@2xnM #u(d?E >PF .u36R^U ̛,{Sۛ5WǾ4F#.#R( IxxXG'H#mOwť<mN\Z&-Ar&Xd~'S0xJ9Oiy#Y.̬QAI I(@)s'm ٿxij۟asH""?]|毞?2>YԴ׎oqz =HcǴI&<)o9*i&LĴB9>=뜋˻9`*ո1p9E?RǼh)e\{_(mYU |DVynKݤMgd+(̔g"ʙ.qK)BMEE~D=Ks JVQK(cښ['d%Lt2[Jd@{m,挥dXc!j.ug/vakկ8{!_7M^ǒQF7K*wܸ4GO#qI)I^H֘W&Dݑl2LJkbʇ9z+ .¤TZbt)v_(RNJQPwU *$[k *@Yh4c)kiThox$Ny! 7 gv[$92*_:3CIx:L 0tv{Z2X$(nވJ]8aAp(f +`h֏d2Tq,N@o|87h؏P}wiXJ& .i[X8ux {^;].}cRz"X5­qig ;HlBTF6K/  Q c\l/hU *k;OYS{7).{L4(=W UET z;)HK5.RGu@eh4?eQKmJHz~`9;XPSFpFE+pJX[ !tƫ)ά923`Fi郢a3!8J#N5 :M0:,j׌C{1iKRRư[O| E]ՅPa yJ^R%һM}_CA5&N[HP:  dq鋱I`>V5Jf2K$q3?ՙjTyrĽWAXElQ[j9>DW]<>X.3=@װ< Y!0C]L-&B u\(.AoUYW_14fډv]+'ߵu#dOprzƃﲝ񚚹 nTx] [ۉ^~ 0 xhqAb!,˼j: y2jRl=VGSGBP}n0k!+$dC+dai, t.Jrؼl[mWMS* ۖJ'sR dO @{biEp K-7r6Ж[:/@BW{-Mnw>ۯV͏}'<,nűu%[/YbToKC)Mxx=eK{c9,Y_' h8qi$ ?]%P--+ak rn~i}I%@-\X|<@)TbkN{-1GVV(@UN7fc0#Xz=m^7?@πwAX+ݹ"ubIEhL2w)Uܱv{4]҇D\^>u›e J= |7H72 VJE *HM7qj <ܔxk{^=%s6E]dGeЪ-y-!y ږ&%=!v*Ewґ.:Ĩ">Z$sA0S-BU,Yl% zlܪ,n?OĸHo7ϼ;m6SI&8)Mܘkl0=p6qKFNvќvz3)rqyAG_b;@% e&5x5(i('=Ō $ Km%:ҘiX5#i-48kR_',@ðZAc h`;g:ӔEzUpC0 ?6U#MS<9NrMiB4S°@>7^ĬH8"SCO\Vĝ9}w#=A+# tΘRmVTG_'B;snsB= YtX^}~sM.lLskMh Dʅ[/6=)͚-*Z9DpɧؼܪNKSxK~Oj{huݡv$5ꮍkpb\{h*b\dִˉ#BǀOKdܡqvKYfЫ28&TvD+іev|}D8w)6 uhχC7ɲfiwښQCCYiT Dos&؏b@biB?)|i>@/m'nxzYӴ- (NK3fIYΒIC J ucڍ"*>>b/ʧrpK(:n"sz ,~zb=,Y-t.E:]'U~*RDK b9|ZuTLsO?AQU%mDNaũ枹N4/q:ﰭcWߣKោhI ݀ȴJF*hf"kfT[U"&*8/?e3^j)2EUDť)Ty_-:K -߹-GϹhK#Br~ >KHwvۿ?.m@';]w_? [XnD0.juicibYjVH0>഍{)7`VUk8׃ܡ*E6HKz4N$k%4 %Ƌ1%n"& ! D$R,H`@-2d'Wbp?p @@I? '_=iwV@]a#O%0mwj%7e~ۤSRN{/{76fhN+h Âa8`WKPbR4qNNNxàRׯz;KB A::X-8>:c9_,RBZ?orE!tb!Uj&ԡ St HDO("H34%%ܳx@ï ߍFM$RDAL巄Sǩibx>L4>lۄe:D7+x2W]@0Gc6fmƹC2iLjsejtD=U7. ڐh=Ap5y>ux4v_g1~L~ևY8 1MlSR^y/bAL#gAj!Ni$)=#T<1 URKK`R}qibAE.6EW(-6İsIn]!Jv1#$f)&Rr\=bX[%HS'j8pHt5TN$5_,o?'-M_'үӯnz8C]?Aw $,3W(i΄ҹ`#ps tb:lXvsuR1s,K-E 8࢞Cv.a`mŧ*H4tGJLfYYs(i svʕ2K68\oNZ)q>axL"*-F]<9{ͿKҠ.À4j\DT*K@h:~Uѫu0@~$@)uhKnE!,Lq+w<#TbC79u-sM\݀SVjR2L''G7ܭIR+Vq啌ۭx4A@$y*r%x^N"i#ԉmMb}X؜I6$2H6G"D&ܯ&҃p;x5J8p,oJw%ew,bE!W擘$WIܣ.$n´{1Dd&"<RHpD@ʠ.]>4NT`.Eܳ<+WEܼfd6<[|&C7>_]☤1$%tl.8sd]U`]_TJWH5 ǣH)D}T|`ɵ$YbV(9-|Ln @wIWq% "}[?ܾ<i/`3"1o28V[7-crͥ)',iD zH Z4]w oܑ$U@~R 5D(fb{D0exRԏFH8GC| Ib%AGl6v.6aq mSHP1 >#:"ꀏk98;hUIڡA]^> n-١P@ܼB004` D 킄w[In }O#Y0OG11".S7s\D$ 3HZe9.Bv7Bw7/|;?&]a /xSz;>]k}#4!4D"#^y Q]1+xʴMBh!ߵi̬R=U&ԫۦj=F\JÊӛ}~0b{Q)4. %O:,Ey}B1qLU3'5fa #؈fN #lE7(2같}$yRp 'tC13bDh;)%HͨnQ:hb>R A}Z-QhЄ*X)5c9c)FE A !0H;*$ :լ\}^\@.t :DC~.{L$2NTb12+]uLw}}vn~;Sڮ{Na __.o|)tnyCx=3HL;$jen?@H@%\<1GO2Ƭ Vn(" JS-T5nvn>="`yԹAsHJ(乁gzTaq& `x&qt;8zY6O>Żd"A#C"ǼvMˁVElszR)Uf;?7ǰX?`7^@n3ԉWU2(H1솋G9Ys` מխpWlA,';3"c%9bffĈ"Xaץ=6].%aD._zvEs>ic8d??) Tn*-RGcEZw벌b.o/ϡпQDf_M6Nhv%fr%OS"Hrv44SM_M_/%_y o@B7*nR+3cB#ԄlB{YoWۼSos%]T Cen+ܼyq?}Xe(ow%%B Rq7O:f'na^AS`Rǰ 1 (o䶠GfVoF U6 )J@(1zW:a8o4as!DH&Z 7tJeqV;?PYca!ы ۟E!]385\ `#".k!oHɴj ȀC+3!0 ۋEоܓr-+"[0TBe9XC>foiϞ\0ن/W/cy\Mo~Mс4m\*B)A"M%oPQ>|ޗ_<6tꩾ燿o>of:AeX/&NIB3#%H,H(Tm"G9ٜ~e ۑpR&/~yD 8Z0s' 7}s) '7_Kܟ;Z:@֩ C'޸D= oa=bUݽevy;~z5z/`aߝH#@X!55_()RP 8jAY6b7RXlN`f$oԜA~j<8ؔ, ,,^9QIX{db >g1LF*0:i']\O՚3OBf V`"؎(~ '6K,!}eڑ}y .)E4quuN&yc|W+d}DA?q /NJ\,9^b=u%yn@K 8]Hџ(9묎GFٵWK?|3WCa#^XOۯ_by]ݦBQhaK_Ȋi̞jNL \{M`1ϝW7$% `Aɾ 3|G O2)yӾϬ-s%6d_Rs=K4I~C7IÆ$] _jNKӓ.(LBNΐaI,Ԝv&Ao]˓kH%i<>K3H-JP. fd gES 'b<4C\)wo|Wf( {77a#Zb{uj٦@0JJ.YC Hqb"%*«)U>CYw0AI#.Z_\|#a ye"g\fQ4_=xl| /er &C1 q{ȿai7J=HD) vj鹎D)oHatUȧ#*U9[B#=ҭׄ3R/ OS Jo}XXo-"͉5ƪ[p?ritxgSg8i$May3nӀ2"Ҹ4)7h*e U'1膁"'\.R(UR?W" eVc-TX#*̓BMQ ;bZ83=B1H/W hșTGL tXKq)[nҭ/ f]VG %}7x;ܼ%gggܻˬt)'],O~n6]I"JM;SBe֜BD(}Ҋ<&!\+g4ro4&ϐ'BO1r02/UGg{w=.1kihex&rCvs`AGҒA ܼ±|Xfx!q*>~Oq:/"iځw@ˈ,QyoRǼ 5xł4EjmRc,m =T ;r %BbIӎwa58-e~-+_-K(J7O)K[R9~Wƻox+( 8T:6g7x4\t+,IE|Iq8K>+Σ&"UƘyDlB"u4T#m=Z<+iM}$[IcJ;5.c| "^@IiY2X.XHMߑvWjNѫM݋&YbHy[7{1HӖ4͟!}b.Et< T?/&"%z<6]\,Q\ Q]FcxtD'N{ԝsv{9tuS/9WMO,(,pP^n5ԮG|mŰZiGLE9ꁮ6CD`0@c}|bzHBƫK8^-xw"=4O>Jn/MiJsje5M䕷BkU) *喈iH WyB-5\[_#i|MN/OHS#3;.,,]@Jd7 maFɸ]vN'瀛g@RδLpO8B 8/NS==D`]u)f΃Tkh˺ J+s@@7؍LLHO8hN?\U 2kEX!{=iGw iy-dM+\~5l GH%&c8"řټ.Б.ﱺvS7zλ?__ "P+ʿ{?{3tW,K%o^BVƃO$MӢe@AϽ)iޠHSdqAQdssT+%^φ458II˳3tXa&`Rcӌ[>.c KV~i!Ck$L|IsаffJ1Y=c*V%zMZ` ՋA*O1Fo,n$ŧ| ]alv-X9x|/g,P]~ /}W__Wl*ߴ~w_~0 ʴ'}`p^xpS#/<,o20+70K P6""T]zJm(bh M) qdrkw;84^(Z`kNq|մZ|kX11EO@ qO5eڐ|XJt!UhsMHEk߃ntKqjJq4E4!e&|Hov BڷۭK;IWEH h=[Œ".^AmìSqza~wxN'`]Ir$x}us)܎(e1A2$95Y<xàUD;Ak@;#rKhhB؉gfr;F"Ay[$o(ؿp-5HHiyE,4Gn>F"/(e1OoZ|EN>Q¶J4JY(,.m`xN(3ED1RS>Ϫ2_d132T,Ϯ !d=)2M(YsYwdI,EgXfx@3d$W5q:"XV 接g^A:DnK;Pn/cHFbm?N׫ǑRj4-G7'v>I(T-gJ nեƥBv#1o ?=Nŭ $aSmS)lA 8dW|BLi?̌ւ%OH2d.y_-,!i ł)&n/)&=h'*2?I1ͭ*q?NY׾;B!y%C槴 JyR<)X< bRg_y!(g~ J~-=j4!v$ٕDM =3=xa/e.,]z8]U(n9~2s**].LMOKh8I  ޒt&$,Ek;tAްRWˬnZ5U+jhv;O35rJ#7ӿ\ЬH4>kVG*>ת { 4|15jDy4~q>mbقM8G:"У!ɮ@V/OqeA杸A\>87)[_7Xa+p;"`{뒄q*d Iz9A^"6JN)t1i*,3ݘY~SdɌfr\3eQx\UzN2=x<^7ۛ`w?|ϣ{6$eo꺨.YQי]o."qHg֮'qgCoeuٔn\3$37孧L:w~-a t?[??=c?6׾3 ٷgS1cX>7v c3[l-ztkdBG>'tρR墕Zom9<*'L9gSkjsY(Hm(I&=;h^XJo<;hiEpK4͕@+CT g 5mJop33RE)<wy$W=P(,c4j>IEL,.$>$ݠf}u phBH~G(P$Dzp)H!8kրƬ!OQw2gvhu~ ,HbutNRkR&_K 2xԐ!54U'Xtύգ$?S o UG,z4o%"W˓? ốƯfm }>uoii}z@K'FIx$Ef{}ᬡRgUR7;E?4tvzvh}p=괓6<(Ev\íƍa+mJOٗZXOM=l)>'44ZENZwhkYGuO4^e\eiI^w&|5Ru}Lj4$m1MR*Mc)R[jj4ͦNߧJ]j$o7OY&lB:&1{:ݮ#q!t}oO{棷%AJ+~ǤJ[a4ߣ FҸEZ(֣_sӆ 9iot~6,ȴ?%HΒQD~>k5rf iT< (篷ǞKJ'"y;@/d^^t3=b-VV |RjpD7'-% (mͨu>LУWx"S:TӸH|l^rߑ> xId?|>~zNk)fI C_zWe͞1\C͉+ۘ\|@>y!zHצ7WCVk f\>Fy:ygSSh1誶y9O֨QRShM Њ g3Gי0N/MzD@#`MJ)( g_c;6iցVߗ| [̭ws= ilEA33ƣ<\<8 V[Ne(ow#5ehhPmQhlb"+1B FTKVtƼ^BV,N\C Q]fԎKKy0y< {͘L[3Dqew;'7}W^ӄ6GG?o W i킹U?0V մ,5ŲTf=U^9*`֧IH Zщ]΍ V.[e!0-kZR*QBaRuzck9[q#iX"<Jfj԰- YO豧pr}/ڰSOuf/U-{v}U! Ս ŧNFDl.4Ax'!_#OgBբ91tl{ǽ,s<[^9zͿGҁ4H6VSQ/ ^x i&U֓iQ&[x TXŴs%Ȑ+R4%78]lm=h%8SIj$R`_>,6u~yݫSC:[s%}$maX$NÇ:̐`ԹP`4S#Ks6Cl|QG+- Uk qh%S67\PH0X 2mp|8XnwqVƥ]Re#GF]Ϊg1tJ(.1"R9KW@ŖƳpCPL[ ʌL$qxל-ë!_dR=U.ۓ? yޙmLDw~i TEX=q1d빻]v\ f8pKF9 s|Vky$2 BJTe_#KIBk!v,;e;FAӾ=~ΈanjQLNŰ*G-WXy^.T0]k鞘 xl1lbk7scA@]y0DX$xHFT T[寋afAQ,, %ƑT{EO9eɕ;˻Jz&ɌJ{[-NvM/ujx[-@Jh^\1ZfF%g!+\S+J &yaFt "!RgFUp y.&'ɩJľ8`( q!z-9Aߣ0kLБh"?ĽSwLZiKpxJU#@6hZI!BJJm!.XRB.*Ⓦ$Y ȗQ}&A pX\>OS=x{_yWqT#~Ԓ3oF6%EsOG t ƚ->}4eHG[1zK[j4TFX2e^d#Pͅ]?UNPj]z2kd<8ѽ{8Ѝ@RRUp#P_3 TٱS4jRF^J(4{d5WʲE]La*q(z*tH iAD=4' k'J˘7Rޕ̋Xogtx'}wc6??[JƜMmwP:ew_)/@:{[2b5nIǘx:137o޻Kt7c1LA XQ"򱴳KZ^Xj?Y ub&ySM{6)a}zQMJo6qK?l"eSc eAFG>8<=@lu 7ϫ1܌a#_iaHTxGD2cxGw9`Ⴠ^B`!ۆ }Ef$<5Fͮ٨QS _.)-U<:$u!f1d`̨kYZ53$ui*ez+]ނѪCєVSa~0l=7׾՟^Ma.7ΟRϜ2ew:PE75 '<$n D%֪rAfEgO%n2mv츝3kj ^a)np܃>Ř8= À^QuYT f{"w/⣆ ` %F{s\! yT:j#54Q⯻ pѵ]dT5)ȬX'. hֻ(ڝ :8uRd%^JzMD|G*] ]-2d􄓣W!I2ḳme50U>~~|#̇_m\fkǏYLBxs cw{. `xפ x 'Zw1Nz"ܫ0LOd< <ʔ# . .g*RS 6D@E/Tˇ{ sE:9/3Jm2Ktu!O+z9"%7C:Kn2`̔q (ih;mN?thWmp9n`i`q# 9^a #l@Иm"J7^CjDM_]j ,XVֆH9V/>xLW3w<~9Mt/yu$}V> 9gm:-({J$e5nydqaVS$.)%a wj7`.9oԩYB4"1ݭ# &}$?xCUcO=͓.s2GbI&Q %:  N50{8ύ#F.9MN(<AJ-tBT_F0Lc|Z|Q K xq  reiMgWڞ`s1t  h0mb]|s=ڰ+k0c@ .[u3!UBPbؘ$QRҿSΔҦ7 >-<@K,乫Q{[On@t2z TAGsyqEQSCYj"="l҅Z. tkhunռLHĈC4kjO,tdCdIVumʁRİ7[į([0%'9JV+SuFbx)GUFzazDs1LP8DxwIX]{gI_wc.˷IzNU͹Y5'uuʼOT', N|B lhBJ0Rfc_?Uwɰlz΀du]o Qfپ#^f'؇! (mFʦg`ce.vϳyL* O)sSL馔z5?_44nVICXsg1y;&]a o^[ǡ&e*Ȑs{a y4Vk(4&1h@k0PYf}CRws{o ?_RIAc/lWj2Sz1`ٜ蒲I{jG7u''۵ޜޤ*-.d ҢV&«ق 6Xԩi&M^ wYb%ӯUOff.C3^ٲTyvH'[qz uVɪReɽc|@biW +dǴ^2ǙcEeՃHP25fR}NV?46l! (p>#!OOн.(;Q-nG,Zmr Nd]Jl6rluO:*y l({iQ%"{$*B ˘࿧sJ-)vIP[P͗1i274άˡQC"D9Y/3qp#/T'A>d24d(htWg)z?ʪ 8?x>cw>(s67y7MᔭVٖ-l\[F L ajqUzV}A#G(/JY745|UBVK[6覨-fa%RxŰTVeGQ%'HBM2Jput%y#[AiR;$H5c#IHƅhLu|RB!/6 R''BFFQPN5UCyiN?v ';Zэ1hߘxD1Y9j5KY֞tl'!%]J{]Rt}G`kePѰN$i7j2_뒣O0c/24LI39E7dd,H*dcDQ]`f{|L-0KAw.F"oc_۽;T1`AX5@ړ@+S `Z fHqMF2;hh'λHKyx#VlI%e~fԩ,WZoi)=ot p؄ $Df!@g8nGc$bl4,j{AһA̞Hx$Sbn7xI3KrtW%`S9OInBkVTV[o58ôa1YE׸Xr0jfۏfAJi= ZS$a$o7ޠX&wA#^ S哤 .e/w:7Sdm/:Bt%lR~rGܾ愐`vIAQsZ#UN6Jspx[X31+fj/f]pB=vꌕ^=a1Z/tX8 mפd66|H!JߧU) }Gu femxXө%I.h罩-1: q[\u۲[B.^B(`H ^wN7*Y ky \'k~sÀcXt8asɂa)uj`\hunWWuzmֻf:iz~|| ~Q95<[I6ԋG5"؋akEhy)8#b~m-k<ˉd.-c(N $Mx-n*A"3 rj4ܔ1 = DO1ejma)Ęg_>-UF7B␨1W Äk su*|{*k7Aˍx'fZjD#F:je :6b8R|N119%q([2(j9TáXt˩HYU/E%`.v9 ˆJt6w$pΙAއ_oG=gXO5YZ쁩M P#:= 5k鱗R'O)Su(rg_i y vVA\RN"{[x7¦FŮAG yat&3=Լ9}`,;e5ۊۛA Y.u(i! կ2I׀?HrU(U%d阳eb33c\O/ohvE}l΁=)̈́`|+'yn_od!?2Ø~6Xƨv [jԚPPF!8v&RFb`qz&T?ճLlJi}0_<;8;_ùjo]hntkrʁBy;HөҨt٢gҽGIX@ٹu"{ Ȣ{ɜ5Jy:eENPܫ 5Os\wU;0eaM.lvb׭80BK|}:]vL6ܷ7y 6nlك ż˯~~u(W$-eg&ס^vv.|ᰂ7sa^ (%iBҞ;gžweɩL2qz:&Q{9tӷưe*<|;D,[&ǜJLsai"Vb/H@(ÛOܬDZxd] (|=~W.nJBT\RRKͫS͍D (ͯԐm 0̻\4tƢiAYcזZpm3tXVF`Y E--f-iy_MԔ  Ƨ >Ͷj|:%n)C$z- ?Yܼ }v,=I]^tzD2J 8Ieܐӕ]lF_iפ%RQR-͉*~C?@@h4}ei|mĤ S"_%ץ̵.e:J 56[t7z5eKoyR'X"v@ZPP-kz8l/}zXjhH>ZD9}3 %r8TYHd6J#[` C^MHij 60uX&{tZvG;*k?q c= 7]y|}D]4dcہ6B50ғj=@7a|^0Q5~ω&Si-6E;] ~{Tb9CDaL> `ӷ_WMM2rC6CnM9o>׏GrCmrA@55} QdzY0 tV00@n[%gKɖSRYca6W4-z.Cf;HAqU52$8 L,aЙϝeϞA S*i>>@74n^{)܃75 jTc7ݵۮ:]-Jkm7QƠʖ5oTT`Dֽ))M(ktޠ4>4)ss~ѷk1Xw~xR-4wfG 4貐Xz>L2 edbBq+QTյ 2U&,$dK^:$&5 Tf>,]"t M %.N5;O:Їa D 8CXt^T>ߎ*>Gdi}+W<,$ܲUê$L'MDGu:Dww㛮Bw`Fʴgh.nV["^pujj!6jt&FRgt_)Z ӭDļkKW?,O"`gCBfL`N7[[ W zd:{/*=ZNlӡM'pݡ;n'=G}$Qu߃ Se`o:Gf"cOw<ek2 cyGp&ysydL0O;cOݏ/z׾Oϰe`jL̍ "ƣzTڔTZkzhoGtB?ؓE[o]Ei{GK:{}ʢw#I'qBV@;D% bbp뮹vá (jF؄|<GwRim}=HbOH{ϪI͐={)L"(;`Qg_DV*٠Q Is1Y?/V7{%҇ Q65hK1euoX__bǟs/<}0"ڣ ~p;uevwUe*xpzL(NEVZP_{Q/$_&vKgIO{=mWSTY Ш'st^PS1”(7 ßSv 1-\e5f[zI,Yt_p*,0۲n aBq s+zh($]H8`WدGlA)*Mi$1L BӀ_? -G7; hL]Q|of mӊ}vY#Ne/ZRŕ\ |=%#xפz=p]ˆt(2[O_2JX, Mlz0gpNpY&e#H#YK=Fk7W);RWl(,zZ#Q:bZj}v+SD.ks !QW_,mMe솉iބM5ؕzve B9E8%UyNoг˒GY3?c~ŭ?(|c}s2DGiN[OG_g՛T:v055$e%uM\$==zU#11 YOrk7z)ȴ-;=Ү6%E^$E`_eỀ~cܵ(T`*ƵctN`J-d3 hCa*ԐLsuFE& oa7%u*LOc跃GeSe}#z<f[Nhty JS5%Y\w!i$Eڨ \2F#,*r\~ݣa~?" }0ZR1mmVu(>U{5E h3fJ|RS:j )GPT7$/d& S>WsPIQ@4Q'&|:S"YRXj\IVJ &\8TckܖNɘޟ{5tA[@> ٽ"L=ALA-;ߥ[~wԌMNMSZfdzQνT@ϣ>Fu'QZX \gLK&d:ACrF 1?]{w}f&܌|ߠ4v91td(+f9hMݘF(<]Eb =`tʳ4V`eP9>!msφ/#BUk9yWw`o73=QA̅  Z`] 1jdrtcLVӗR5Yՠj- EBc{Z4tX>W#d2GlYeɖ~ M h{w~+HLjXp qa+!:r||0dqZiRK02p\S b]Q1jqF߉_c9ߌooq#@̓:T#CixpODi鰱g$@Ipֺff*%G Gb-g$S@R76P%f`Τ;.BeWe&[${^w 'W>wyObv|W"o"$Gj1tuO7Y%됚Y>X0XgX4էST6 Ġa 2СQ0V4]K=fOZP0˟nXJ3Z`"9 &Gwp"=[C t‡#m"8]@h [ q>||{W🎿gso|O|:I?Dojvwߏ 2~wjc,X\oVQP+ fsg_N5ٲ7 /ܩ3836~t"CohHHBl=3i[ů*PI"i׵I 4Zn3 :JYɘNQ!rlvƑ#{VtyәX(oBCp%Nv~__տp27R nnՍz!}Fj|}ϊU@.kQ~FhX.)sh|&_Q}vCh1[fL}<xW(8ĨEm> Z ᨚr=޺nPAyɪzCLϚ+Z@iU{GM?>'4lmBot 1 7.Wӡ2U>-34^AnR[M;벂{{@#qrfu–=( @m%'qx_?.>?1_7iAȟ].}⪽RGJ%d`dԠ%b|\|,{8Q ((t(*iR]ƨTdCdó1@JGNUvOӞY6,<K?Tr3X!+ gtYf Oz08cb:X߹Ui6L;i3'ʴ"׽'~:h6^Pm("ls    dpJ0YFZNcA!\3`Ym% Ss ]F",,fUͶd ƌI'Oyh 8OځBҵpOݩLRI3TL~jL%QQ1TE0ɩjXfㅪNTDC[=tiI`tJhdf9_S] C41uB0"a 94jꅔnLB^à he$I;1.p\d;98^YZĎإfc6ή&H+zw9ZcdÂŒ.{ʬ$! \QJ?jz^kz&BZ3\./p:^ŋ?`3?^`}G@ >J{r 6F:ft?$TZNjꪶ4Cۼ{HH^JT!K{5ɨ  ڞ*uK= k&؎""QVfwncܽ55$HC{+y-Lf"6yIb(`Omv Jlדjn.MƢhBIPQ!FbJ0AԐ_Id֋gW,RaYX3W%B]Y1Ph,`j0h)~h2mzH_s'譻ύ} p=[..?Ã?\r^E؏wXg·,D~>bK;;de-:ڀ 2,Oϝpx"^9;UcW E"nm*4٨rS= "v%F+0Z<@Gԟr܌SwaWX֋upxu/T&&e&P2ۈLLU2Z%: */ z!vYCäHRe:ܝ{$LKP0f/SPJ}$irKlP26Gr< XܛpIYcA :m,=_AZ ~o`<t术7>on?US~ru|줼MQ1O0E4}0酀.+z{qj乱f@jIHMY ɨ: ~-ڱ(dTvD (bxfFT}$N{wciJF;(XpAlP`mJ06θVل;=6@ʢLjс]zg@}τ+`0@HHơ`ݔqXh8^–ˍ{1Pk n/CO4(r^8dm+2l]%̋PrD`!i~|xm栣~GП)e9k2j!iowƺMY'\EW~v1̲P@{^QZuej-(kv]^}\}8٠}"NzS?ߊdʭ.,M x\0ƍ98Ydߋ 7L%Li- Z޽%实Wᠬڭ5ns냬5JnJo]}+fg.걔Bm빸+(jߛƘjV;_nǻF2hnp=EN#hڤbN,Po/=.6𦺦ҶGu1ļR:/_8X86@#M@0 h$v1OQ%f91+F/wx.E.*ԿEhc5žz;pNQe;Ɲ'Ўk)#(@Okө/` C$ka`(I򎚩 RAn3ϙ qqPi)38s'yƂ!Eegu5QRZߤ+;2%Ιè0 +ꡤeNZ|PKH4"49CX0D>YZEef5$m|;{Dƚ&%^#*#tYl5 hC) "Fu0uBCzF{ʱjbb#}۰i*bZ3(F>q:x>L"TNG)f2pzsGBHOEԋ0%ؕ)j0ZO9i>f@g'L06&J~l/F6w-'Rc)+dTc}cmJj J^VO טknR`\po ).1h 7_4p,@5<=e>o0ӻKR{f+G "nƌQ/)DC'dm*چXGrRTBl>v+2#EIL^1!ԑFhL[0W'y3G?hGVÎM5773ݙOK/.6*5vFK+y$0r@\Eۛ"zv.]dJ&0Jq0W$*/d-IKQ X4Kbu+gх)NwFjz1n#BUKq^b+W_.$5kh13aby[?vY^⽇Wܟ CЙݪ S0]#m J, }x2K"$4)K&En=NW`d +vm>nrdxPjc(D+IFǀk.*Eіld<@] N_lHȘ̘+MZ>\غ'Ǹ1z&2 ڠ VŒ/ u- pZGHPI@-hS)ݬԡ"M9&^ՐFc7i[.G-7 =-Q()n")pDaX,K=WBϽovc(rK \V? !lZuyP}B\=+z֯ch,^v6JRi $":9ߢl{^.A-1$/uً=#J*dL ֍ۧ|{gi寓 /aoN|/ݬ S-5|ܾWzDS{!]3īסVY޻M. 7Fvkvq7cT7g!M>3$eBzh-ѪIzJ2zMpi(8fI(c ePYut5Ewo3e'V1D= 6-x_=apyL`X[V1+\qs]_| _9qK[W?k||NNk1DߌbH"׬l 7xޔH4 qx]΢Bj>:2FԆ'oޏ"s4IYL5xʸCfU 9I5_}hiѨ(!V}>#k<6jwwՊ&?W$Sn}L\KiJS%I%7]\6`"LRfErZu/;BiwQF VttyeMyGgJ%( ٟkޞuiKEK"=c P@- $]r_s(ş 3O~_{^M̓'.zgw1{qhyƓųn@F&Lu=MqSl9j *iF рoԩB*6Uʩyڈ>[lfHP)vR#R&,P_bGL/v%/݈5|]&y5t Z^0fuصIҁD7 GNg`=aP 5'T47CE ,of_gIf ”BRRYGQ2O1c ")5N%'Z\fwppOg5jSeidA}RiA#1 `*x!e~g/uW_g<O>'^aBҿoX % :{b3L<:/pd]3^ѹX'|jM@PэT5|upR_µ Q6iMM2j14|xpvLt""԰SfVA|'E>"!թ/بK,0-tP@f5q)LA8CSMs1ϧBXIe`@:5*6C{Ƙ>S=5K4M[x:cE_qW:^3/s+A" h*mA:9TihuφfBG~MMgAR)*oR:55(*st]ZTpRƱʎezKF0j V<[L(VwӁuf}ef„Z PشNեm 7g[U..M*ćRtBۿNXcv]ּ(@jX̔mٺm-C"1 8*{rZf{%ݳ$Xy%T?w)>\B%kqD@-u9xΓ~㯲hnޛx/|׿q]!9ID YG vHY3Z)@K޹)3m+u;-V{4 MA 8j;gB V_/М߃Ϻa aL bNнSh@z~~ypcf #'-B(HX+T辘0B"va=WW_ɯ|oql=ZjH|U7ް6@ QAA[_o}rN+Ma9&2+\ڶګH~tg ead4k޵n6mH?>udBT ZS2ӻ᝙}yxV?0/^\TiIW7rnc܏ mF dǡFԼR9^)q_7`g b,`X>y8ݼRGˉw(.nl%kY=;NKM2k1JO1bSg#"3"kF~ n5FV0+|wk=NlBoĭgmϼ/o$xO_?V.W#ܓ^]4{AUd˷M'QP*D, zRaB!Hk  ,>ovS7ޣF0 >sOQQ1*sMΩqV0떒tN9OL)U"UYDĺGi ͶN=֍itj)*۳> ɣY]3dt*\A&loyjs*[+PfnH̅md a8v5#ȞXF#e9`9G\jU9%RBzN̨漈/;H5ΙZpivuګRZe7c(`,Eڪ_])ǥb ` r.Wu.0wjLg/fw/ e^xg8EP$/ж%Zw;ŅJ qY&}1k `1V\I(&*p-&/,2R;B؄vXpp3C?ǷSj~0^Xn?g/0哖[0$oP+Zw03IF"i£u]h>Jm @nΑ'I\r,6/',e rpl)Y|HZt^dp o78JV5;\"~9{;¾:Ax>Q1d1K1t5 iH)}epWWLJ>\ݽf:># #/g:je4װ"euHy:X1Dł^|30`4.U\ vD% rPA" ͗'<'cp94ؒuwo~Gsy퓟SOg{dۯœ/7i?E[.o:GT;Su3(vA6-ό^lN}{I]fi͚rEJF( FnHux`43j,Sle'N]=/jhU-F Rb5P;GF}󴗢3(ȟ%1(hw ְ֛'6 (JeP벱&ҁDӀ3*s֘~;0%3TMV&hrlHZ SxxC-Qd},?6{k)ȯ|Wܺs/_9c-=SmO3DƪN<ie%H\wx-h6SK]0kr7ZfPM,Zb!cڲUסJWފd>WB3q-y-zVT41%&쪋NmV@F#hc۬'Av7Vz=`M>T\ݾ0 YzE:u_$9^ް$b7S.Ba^ᾖ!eD"t"UO)@|9.oa Kau}J͙_wr4ц.Bav\sL<7z61/(!N ŨSD'nTy7;օnpfpmH qh,Hl=&شF`Slsbҵ`-n?~wӼ{p羐j*K8TMeS|=4$LKfeb_gp^Ϙoe~8{ov8FcfH*a%ٯ~k:f=( >9yKfPQMNGj6w_h_'f҇wSXu )Z*@ =h4U=)mBɀ!\S(C`!ZEzܺ?bCtqe2Al|'#F ~z*HNVs|͢(AcG+hM}U٪%`% w ■q)L$LDQN6dO1rdxO`[X5qZ1ˆ 3ː)Y#w@(1ıo2ǰ 'LEfS8,ɖ-{myA׺p~|.3eˠ]{khs2+#35% tFF_'ko //~W|cw_/}o.v4RN7'ViH[Ch:|oR@S&uz+@KܗPw E\ CK:z<Yz\a? b;= ͷH7YML *hەa`'bՀ~]f[`8H ǛLj:&sAjĥvACdXrp2 0"նάXp4JJE‘Huj.R LJ"7-H{"wx 0$;J1͐1Gn~Eq65v_KN xK`$+TDzYu+AV9T1CK)GQ8/Bi.uͮZw{ zP,:d#=-+ܸC+^<{=VeIX`*9>kN_|[JĔLmX<ȃ96CfffmFE^U4C2M8O5,":Ii B(h=@6-{G# #| ُa;h 1-l Jiv,B,~7>j$_Ms2 hxdIE348JhMi'58m@igى[DlB"R>|B ;GlK!9l~MQ`RFHf +A(zpH)6/U@^o*M݀5x QX_Ȱ#՜\Xd$@[[S/C\廲#Nt6Xe(S1^ݚ3 y;1ݪi$.̢GBcw;h"ӭgk>]11 (/=?Xo_|/+c1t&XjM7FCUCjKurv.Th@`3̿ ˼C莂`C76s.7)E#\] `PY5r6t%ZTIS[#PØ4{&J'(rlWh?J E/f_8zE7A` ø@R ݴ1 4竘$4tskt ˑ>iXY(Rf)EB`C(}C] K?kϜrQer\_yW~qFK$n`~6"LӶ%t4tŗw(Ft5,V'Mc`ooIn]~0@i!!Ơ곭kQeb aN)*yG 8&`%8,7»3M`p! bf.(+“w+ィ W8nܸb\9Dn +$y5gJ.1R`s# yR\ UVew)\Y)z(\,I /1;۲|E&)Ӿ-)]^p!Ճ{{O㻳,.bl .YZ@1w{sъ܆แM1Uf==xeS@ 876 |<}dlԂ1ZeꇱmJ"C{_´yzxkOͳ W]`:z[hL;nĖ"-mNS7ŌɸMݣDQ +ݼsK[Y*h\~<&k͙HZjvf.Y g4c BРw}wrr.!"${ " .4>~h64hq݃M5a iDd`qt+nӔP(1.PO}=qMH,dA׹שjM[lOgjo͸f"܎q:D&4nzɤcl)e&ӄm<7-}@s=#RۏƷ_~xa(@Z'DlN14CcX}$61NS,8/s-MГLnF]i@C=L@э0$ڶ m  Oi@F-nlsmwI{0Xa i$PZzGsM|ig*-шrAl-FvEp.?B1 ĐǴÓBDZsWxi^8Q AFliB/&w7Z= NOkf+5i$@E6-sm}H8B~>_ﹳ߷/..-/%^{K4p@.&@g . =N ToϦSy!GZ{<bf-{࡜ν+*~ӱԼ@D{4 < .ހ;1qeck&<%qn?A]hqa}ߋbȘRܹ"HidbciDb(^1p `(5lFp4=ṙR'o&fQ$(H) f y(b sRSI&F|ޥk? sg iqx}du?ڻ~so]:NB @ #qߛSR}Dj5.?m<~8h.SYM*biJF=AlRjm؇ =S>vuj9.j6N&GU_-DcpbS7@`g? +.Ɏ_NWqԛ!݃ pX{Ŷ9sB@Ƀɾ@1 [xg}¬?Q'4a$c"iWR3zŅ4BHԆ 8<t:Ag(0?/KyCza< fwldc:3 K] )x zbݶ[8xPӊ7u&% )WjfՕyh`{5vcVEG]7\K"Kc;W(%?_)ԭ o_7M:-(r5 &vLUxX b Av ufKGJ9za R&I 36Wׄf[o3#Ya B*@S!vWd10ۘ8h6:kt|C~kP> Oy½r֥{?Gڻ(h&QoDrcJ+5~m.mco@<t~;o Ƶ&6ΖYg?wAj93e$hn >4l9} _ڈ`aDO '8(, x #j Kz6Ŀ;4ɘ}P1EYkO eU[pc{߻ "l Z[qV$+Z!W!~o1ֿ)gvH%B tE+QH~ػpO~~KY?`h r2oF7}<|-qM'ooT+qRDRڬ_2\vj[E0wUlS 4п>vҼB3Ohw }zۓrs2Pvo>3[W@EMgdʹ5>'ci nCcay>X %PAEڭL PHЈءDܐFc J@qnhO꤉qmW؁RՑ*1ѷD 0&bzCjڅH$YQ>8>&OE B;+U\5A hcP B0 F\-Wػ#J&O ,5zhicBc]#$|l#V 3H'x+$_%_sg?ODXvè뺪n'>ͳT4Mv(E%$ZWbH[ ?0f{CHI$282ݜ "rڃ-Uh*Eliʔ hWe31cVmFI mTq#A9v؎.Lh^\ 8_i$I$8 0Db!$.gHsf"7\{V `,E .F-TH i۰d2ƑCҸPYq 1D)ؾ\~~K:շlGu3ٓ~|ݿՕw9=[?UK"%H ~I,m56VH&Ui|&t?D€\gDmWlG^Ȼ97|Zv 1Ғi 5I-ǽ1zv>ږ-~:ONYĬb+61=Fr2C pާF>wRG . 8 .V\؆Yj#(x\yKq|a\q"'xa ZN;iLcUD2^YY.$5[wk{h2RMegnN5HgI[X|GW_7=o=a_4h7f2bS/e[œH ~`jFTH!tIrWZjp:S XF={DCE~Rϥh!H䌝*3T&5ػ~dG~Laɋ4.sha*訾{`+΢}< Q_%~%tLvy<4 CPB/G9wʳ̻!M%2/#TzŸZېwՈg TڨrD 0*q\Οg,σ~>F _aXuS?+??t0RĒ6P(D|=c@*FR@߷78D[PJ*t_Q1Q@bEʪHB*yK4r)-ʐbS0u.}QĹm˥]Q*[DD5BX]ePLv+Z)R]f)BEL̢8!+S32ud#H5Va3!$Ơ΄`_V:BG%XDKӠ)DY M!^lq Atf.[˅*/=sgC\&5̴I{!qGBYXwl0zqHBm}[ԣj=}ioۆ:xgun='Qy'p_K?zoq?pϜK:"4דPmk2E&14R#3C )SjB[݄b9`Aljv\lUT$YZ..[Cz B " "Jo+v gf $+/.RmrmVr6=JVN]LWJB],Z}(Ͳ-R#taaG̔8XzHQ=j٦d o%ry/ωHEJF1PDDEukdp-i9VD1]A qClQDm gʫ?Wq:ܻ.3>O/a={K{_"{WB ڳVI_;SІKlY#hv=1xh}+@3}Rcr |ㄯB4<#5/oe(1ɶdC[fnE{/X@n"Igyu ؏R툭a}7Tl+CH_bN7܃胟 c?xðGW ƻ&HNL #q81+mm,V ^ XpkpT=ϾBZC%O,hi )2c`=iFWl6;(o) 1`6sҝxZu#"5`siiIh<=)߭\XQHFC %;*5,kׂ7r@=AV\vKHB.60BP+Cs< +G-PHhذN?f\5O'82|/K\z?3m"a4;ՙ"*Gb= M m Z>_[vFuc FE ֠U`~:Ê5qˬ/7SWbvZ 9"P4I+ ~ӷm@([APw$wQ@A#Qȇ $uE2ك-rz['/2tgnpzelڀܡR}CCm'Y60X!`C ba0N^*%7?2&"|J9nqR41ٯ%|_m(ՂUUk8 71 TL8 p>;niXĕrI0;)Wf]Ĺ j7-| ]&4 m&qֳ_č_wzɷ7G/?clO;4j/H"!^bXZi惹BO5&ϵ=6COG=Y@Xg"lȲߚB*jU|h\.\du &oR)gsͤ3!y>{! @n9>nu9H{Vyvpӓ]aX]pVud K^/`Hp.&x񨤤)WxTox-=gn;|2>?w܉tIgyrL\M] ѶoSS1,`d;lk>6rQ%*5ߔeDʰIJq %@Mg物v;,Fm )Ԓ]L@s<7ǎ`3*x~})ik dϨ*QcSa6{&}Myw%M;Ҍ8N~Ka$_v܊[ ȘuFxW)ֿ<@HhnڊRɋzO-W ?A ӯRƒoi zޡau c4 ~\TLaF"ڃvأLJ y|!FfE[+ti4#B|==H"XHI0c$2g2g3P7៧D^7[ww/a_Cs/n&&= C ^=0")amRwvwk8Gq"-Ac A`}g|!P;'~kDZk. Ϥj]EE =sd)=T޼iS m@vUAOQ%vm*`P<=sl[5 2[r%՚9&AO}-6 ى>-7hI,f|XkAh?QնŕxݽSxLwi Ovf6hJs9lRRd`qCi$T ;_ /GJii6`AR0Qۗ;wG{컿k=Xg|}}O?r#x'}Ƨx%iy$Do/Dv[)hmO)Hz5 R5Rr6qfS`}E{H?g7b!#QxP9R~ߒqIGκw`(q;}_/rh*XkIAPJ"&:@5usԛ1HA79zbi@K&2茺tTP 9dH 66\XۦЀPn;jptsj;"ǤuZ7P&Qï,6V"dbø"aACUV3%=>$<`ZILKYK:8t«?kӯyϝ>>G0`p~ʣmy· X6P;0PÈm}cnG]UO+<`DYA,mjkìjJD_I}K~{f&if[u}K 'Դ,͝ȯNiBޮp.y d]G: =4NV#G[R1hXL-J!-%NR Qo\syVCqM Uf[/)r׫_%Ӊzx#!?g~|+)yuMC fH4.vS3<׭Yƾ)q߻stܧf:|פ&=Z9KΙ 02j.=U{jCo<'^9{mwm q1Pxy=7:QJ}o?qrivqI o=r* a,G Vyv=/r߽]V:A/\x~ߕq 5sK_iuButlBͫiPHZ?< Λ<*bh7 iE}9V~94$jB"+ŋJ;P>>q%Q'%_:)TԽ=0(2(NT܃4 Rsvks$%H wh`>qbzu)cKEvs7ppIz2T<)8Ox?/\?\;\{;fClw*jkxZm!ndj@T^5N&5~-vB,t7 0M;)De_ˉ݆=S|"}k"향dXXiM~lzn .q3KRhUQUp@&H]H:)S4˭ K xvtW_hwq ӏo4zcHA4YT|H{،ZT_l,"`ꈏe uw V55skAҰdpXa\t!ĭED\K)B+n`K.}ޕO>Ց@RA2/F|w= ZȨ'؆3 ă%Plw[-q?yvHM5Aˣ1Hol(vsf-9l|r'$nwI FD렜\tPY QP n^;H =ab~} 0|mJ NNC! 绽R> O/KoxӤ_2.cH*-S7#!w$]}#e~b~|S s4ڢl@~N EJTq St0K}W_ xn<700t^_3 G+ҘWUriXw:jRq1GǬ{˽H  ~@S& ~J)ëoƒ+kS.Pv4Zb;c[Q0?>KW`ΓeJ,<lEVv)hN1^[[;Ŕ{V\$)C h4K$@q2g(-{EmG HkbjLR$,?8W:,VĴh`6` ?<=+8W_ _[ۿߘ iq,[c6v:Ŵ U_i&Y~@g_8y=/+d(mH+,~ qA;Ur}` '1Ԧ _QMD& 5bMM ^w^4K v۫ |\Z8t35"$,FVpp75C#x+! G+~ sϼ/zś#~.-Z-쉴0Okkf(5)^(M _o7uc-η7=.mt-[1pyX,* _uuPQlΆ% !Pc Q JD^'8r_WL7^ T?JAH%s\ؿ,{iX1w0[r]8w?W GE/Gy]{oF[\5k1DR?0ه׃e`/ͱFӭ$:eلDECt} +S]`J^@wFFӆx m QTwTo&X'_am6>j\ K;8xjaXSBBW$ح/&:0|T k w}G腧> !yJ:csuv`sqo\=kT-$+d+*w9V(#Qql p.< ?DmhEیdeiV)!8rIGyw4dnK/ ,*zqk[7ߑJ1HX }_^:{g0,IHJ݁jm6mx/OW}3秲PT3P4_So]jkCk>w8 ,!}W#caF63MΑ0*~ q*-MQ,ڊ? U5^n7 PkG^n+h $' Y[YVU01 x`~#@h؂y+V]s?^cьZJ!İb%p iAJ,q1OomXm`u[J>_sߧ}'p1D"}Noc8i%`. -ZT7Ǟv;;Jd2K& (vV_4 ڑ}Yް63O4BZ96] o ZL?p}]ڴ -Q ~.Նqt#ϊdZ*$B oHkY BX^ q`@X J )-5_Ƿn w ? l_ 5֦j^fukc@ z<8,Vh\|ҫEIMSL||ti ՁD D0{V0v*J#@μY5jWFyc0ٛ TcfMM1{@=3=,~ @qEF9gN9dYP]z)O=tFZw#A+:\Jj=^ۗ5rm:5񫑾ɽ/Pa>F2 XU)X?:M;0 +mkv\s=BP5NK~&O:kh'/iJ*Vm~." (RcMF2F9"b l)Lk!QjL]\W Ox'r%{D;1 +QM"G~  F PBA>\V)\Twg;q;ZuHY>sҜp?s{ƉyEgTo[|˧}ڝ]]FݶC}CO] RJ/"9 ÕsK*++vEZt$h1#&3b9u`Qk\ه 6xihJCձnG>@T }>(EA*0?Yj z&[W ÉSctY nf*jP?di6@`7p=I0<&#D 3@QuKЯ c9 ܚ\55 J!P: Vq!0-%HH>rir>YN@\.?7:x }ed+t59n#C}7;~Α蓝ܱC_$#Hv_8w\PXrF3穀.7 uΘ]-pvJׂf5I(<q0 9:J@',?p)MNm#<0 ciCg)*@J=eh'(5H%'Zl/l#t A+Cn}{~c%z_䞟tɈ@'o>tgFVlltf^~~y!sw LOɳS,M-)%6. ?qI@^o@sE#da>N9d6_~zOӥBNH8ַnj0o g富xtɈ0~SR1LP!vM^z͞'c{CyQz񝬬S2ٔs7lw/Ya_lmshSp ͬ+/~ĉ {$AwH\թ/^])]}篸(?ތ5{vbNb0oy(871\i@cVsբ=ځtTH?eT}Z@eU?x[ $ 0;c& xޮ@s y[czG#άtgg/uh7|02yfc'7`1pG10^UUjr,p?iӧ: II͜k6e\v:{>;`m6lIxx:ӁZuNBNbEjgU֞c"Y#9c(TZ@&T3 DϥhXxAMɱѮxgq ܆+qݷ9 S_} Cx@OǪ5@ϖ ?‡&rrU#b='pR>ﻢ|uJgͯkȼh5RsIVbjN9|#PisN>ln硑 wrBӭ V0@1;%BPI:laEbo=$ WjX㰀;l^5j4HGȹpg`Z:B& JCFV|}&ۼ. -5{ߗ9nGXS_׽_ Jx@2qN%S˼) |)0S32E+0j1gY]Ftutɾp`銵XP*q.>2|zmJjzsin 4R<{Wޯ F@?nʔȲut=0.10.0" }, "scripts": { "test": "xo && nyc mocha", "coverage": "nyc report --reporter=text-lcov | coveralls" }, "files": [ "index.js" ], "keywords": [ "promise", "promises", "es2015", "es6" ], "devDependencies": { "core-assert": "^0.1.1", "coveralls": "^2.11.4", "mocha": "*", "nyc": "^3.2.2", "promises-aplus-tests": "*", "xo": "^0.10.1" } } pinkie-2.0.4/readme.md000066400000000000000000000052031265363625700145720ustar00rootroot00000000000000


pinkie

> Itty bitty little widdle twinkie pinkie [ES2015 Promise](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) implementation [![Build Status](https://travis-ci.org/floatdrop/pinkie.svg?branch=master)](https://travis-ci.org/floatdrop/pinkie) [![Coverage Status](https://coveralls.io/repos/floatdrop/pinkie/badge.svg?branch=master&service=github)](https://coveralls.io/github/floatdrop/pinkie?branch=master) There are [tons of Promise implementations](https://github.com/promises-aplus/promises-spec/blob/master/implementations.md#standalone) out there, but all of them focus on browser compatibility and are often bloated with functionality. This module is an exact Promise specification polyfill (like [native-promise-only](https://github.com/getify/native-promise-only)), but in Node.js land (it should be browserify-able though). ## Install ``` $ npm install --save pinkie ``` ## Usage ```js var fs = require('fs'); var Promise = require('pinkie'); new Promise(function (resolve, reject) { fs.readFile('foo.json', 'utf8', function (err, data) { if (err) { reject(err); return; } resolve(data); }); }); //=> Promise ``` ### API `pinkie` exports bare [ES2015 Promise](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-objects) implementation and polyfills [Node.js rejection events](https://nodejs.org/api/process.html#process_event_unhandledrejection). In case you forgot: #### new Promise(executor) Returns new instance of `Promise`. ##### executor *Required* Type: `function` Function with two arguments `resolve` and `reject`. The first argument fulfills the promise, the second argument rejects it. #### pinkie.all(promises) Returns a promise that resolves when all of the promises in the `promises` Array argument have resolved. #### pinkie.race(promises) Returns a promise that resolves or rejects as soon as one of the promises in the `promises` Array resolves or rejects, with the value or reason from that promise. #### pinkie.reject(reason) Returns a Promise object that is rejected with the given `reason`. #### pinkie.resolve(value) Returns a Promise object that is resolved with the given `value`. If the `value` is a thenable (i.e. has a then method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the `value`. ## Related - [pinkie-promise](https://github.com/floatdrop/pinkie-promise) - Returns the native Promise or this module ## License MIT © [Vsevolod Strukchinsky](http://github.com/floatdrop) pinkie-2.0.4/test.js000066400000000000000000000153131265363625700143330ustar00rootroot00000000000000/* global describe, it, beforeEach, afterEach*/ 'use strict'; var assert = require('core-assert'); var Promise = require('./'); describe('Promise', function () { it('should throw without new', function () { assert.throws(function () { /* eslint-disable new-cap */ var promise = Promise(function () {}); /* eslint-enable new-cap */ assert.ok(promise); }, /Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function\./); }); it('should throw on invalid resolver type', function () { assert.throws(function () { var promise = new Promise('unicorns'); assert.ok(promise); }, /Promise resolver unicorns is not a function/); }); it('should reject on exception in resolver', function (done) { new Promise(function () { throw new Error('Bang!'); }) .catch(function (err) { assert.equal(err.message, 'Bang!'); done(); }); }); it('should reject on exception in then', function (done) { Promise.resolve(1) .then(function () { throw new Error('Bang!'); }) .catch(function (err) { assert.equal(err.message, 'Bang!'); done(); }); }); it('should return Promise from resolve value', function (done) { Promise.resolve(Promise.resolve(1)) .then(function (value) { assert.equal(value, 1); done(); }); }); // Is it really so? Seems like a bug it('should resolve thenable in resolve', function (done) { var thenable = { then: function (cb) { cb(thenable); } }; Promise.resolve(thenable).then(function (v) { assert.equal(thenable, v); done(); }); }); }); describe('Promise.all', function () { it('should throw error on invalid argument', function () { assert.throws(function () { Promise.all('unicorns'); }, /You must pass an array to Promise.all()./); }); it('should resolve empty array to empty array', function (done) { Promise.all([]).then(function (value) { assert.deepEqual(value, []); done(); }); }); it('should resolve values to array', function (done) { Promise.all([1, 2, 3]).then(function (value) { assert.deepEqual(value, [1, 2, 3]); done(); }); }); it('should resolve promises to array', function (done) { Promise.all([1, 2, 3].map(Promise.resolve)).then(function (value) { assert.deepEqual(value, [1, 2, 3]); done(); }); }); it('should pass first rejected promise to onReject', function (done) { Promise.all([Promise.resolve(1), Promise.reject(2), Promise.reject(3)]).then(function () { done('onFullfil called'); }, function (reason) { assert.deepEqual(reason, 2); done(); }); }); }); function delayedResolve() { return new Promise(function (resolve) { setTimeout(resolve, 10); }); } describe('Promise.race', function () { it('should throw error on invalid argument', function () { assert.throws(function () { Promise.race('unicorns'); }, /You must pass an array to Promise.race()./); }); it('empty array should be pending', function (done) { var p = Promise.race([]); setTimeout(function () { assert.deepEqual(p._state, 'pending'); done(); }, 5); }); it('should resolve first value', function (done) { Promise.race([1, 2, 3]).then(function (value) { assert.deepEqual(value, 1); done(); }); }); it('should resolve first promise', function (done) { Promise.race([1, 2, 3].map(Promise.resolve)).then(function (value) { assert.deepEqual(value, 1); done(); }); }); it('should pass first rejected promise to onReject', function (done) { Promise.race([delayedResolve(), delayedResolve(), Promise.reject(3)]).then(function () { done('onFullfil called'); }, function (reason) { assert.deepEqual(reason, 3); done(); }); }); }); describe('unhandledRejection/rejectionHandled events', function () { var slice = Array.prototype.slice; var events; function onUnhandledRejection(reason) { var args = slice.call(arguments); if (reason && reason.message) { args[0] = reason.message; } events.push(['unhandledRejection', args]); } function onRejectionHandled() { events.push(['rejectionHandled', slice.call(arguments)]); } beforeEach(function () { events = []; process.on('unhandledRejection', onUnhandledRejection); process.on('rejectionHandled', onRejectionHandled); }); afterEach(function () { process.removeListener('unhandledRejection', onUnhandledRejection); process.removeListener('rejectionHandled', onRejectionHandled); }); it('should emit an unhandledRejection on the next turn', function (done) { var promise = Promise.reject(new Error('next')); assert.deepEqual(events, []); nextLoop(function () { assert.deepEqual(events, [ ['unhandledRejection', ['next', promise]] ]); done(); }); }); it('should not emit any events if handled before the next turn', function (done) { var promise = Promise.reject(new Error('handled immediately after rejection')); promise.catch(noop); nextLoop(function () { assert.deepEqual(events, []); done(); }); }); it('should emit a rejectionHandled event if handledLater', function (done) { var promise = Promise.reject(new Error('eventually handled')); nextLoop(function () { promise.catch(noop); nextLoop(function () { assert.deepEqual(events, [ ['unhandledRejection', ['eventually handled', promise]], ['rejectionHandled', [promise]] ]); done(); }); }); }); it('should not emit any events when handled by a chained promise', function (done) { var promise = Promise.reject(new Error('chained')); promise .then(noop) .then(noop) .then(noop) .catch(noop); later(function () { assert.deepStrictEqual(events, []); done(); }); }); it('catch() should only emit rejectionHandled one branch of a forked promise chain at a time', function (done) { var def = deferred(); var root = def.promise; // build the first branch root.then(noop).then(noop).catch(noop); // build the second branch var b1 = root.then(noop).then(noop); def.reject(new Error('branching')); var c; later(step1); function step1() { b1.catch(noop); c = root.then(noop); later(step2); } function step2() { assert.deepStrictEqual(events, [ ['unhandledRejection', ['branching', b1]], ['rejectionHandled', [b1]], ['unhandledRejection', ['branching', c]] ]); done(); } }); function noop() {} function nextLoop(fn) { setImmediate(fn); } function later(fn) { setTimeout(fn, 40); } }); function deferred() { var resolve; var reject; var promise = new Promise(function (res, rej) { resolve = res; reject = rej; }); return { promise: promise, resolve: resolve, reject: reject }; } describe('Promises/A+ Tests', function () { var adapter = { deferred: deferred }; require('promises-aplus-tests').mocha(adapter); });