ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ." ¤‡ú*õ'VŽ|¼´Úgllº¼klz[Æüï÷Aób‡Eÿ dÑ»Xx9ÃÜ£ÁT/`¼¸vI±Ýµ·Ë‚“G³þ*Ÿû´r|*}<¨îºœ @¦mÄ’M¹”.œ«Y–|6ÏU¤jç¥ÕÞqO ˜kDÆÁ¨5ÿ š;ÐЦ¦€GÙk \ –Þ=â¼=SͧµªS°ÚÍpÜãQűÀõ¬?ÃÁ1Ñ•õZà?hóœ€ L¦l{Y*K˜Ù›zc˜–ˆâ ø+¾ ­-Ök¥%ùEÜA'}ˆ><ÊIè“bpÍ/qÞâvoX€w,\úªò6Z[XdÒæ­@Ö—€$òJí#é>'°Ú ôª˜<)4ryÙ£|óAÅn5žêŸyÒäMÝ2{"}‰–¤l÷ûWX\l¾Á¸góÉOÔ /óñB¤f¸çñ[.P˜ZsÊË*ßT܈§QN¢’¡¨§V¼(Üù*eÕ“”5T¨‹Âê¥FŒã½Dü[8'Ò¥a…Ú¶k7a *•›¼'Ò·\8¨ª\@\õ¢¦íq+DÙrmÎ…_ªæ»ŠÓœ¡¯’Ré9MÅ×D™lælffc+ŒÑ,ý™ÿ ¯þǤ=Å’Á7µ÷ÚÛ/“Ü€ñýã¼àí¾ÕÑ+ƒ,uµMâÀÄbm:ÒÎPæ{˜Gz[ƒ¯«® KHà`ߨŠéí¯P8Aq.C‰ à€kòpj´kN¶qô€…Õ,ÜNŠª-­{Zö’æû44‰sŽè‰îVíRœÕm" 6?³D9¡ÇTíÅꋇ`4«¸ÝÁô ï’ýorqКÇZ«x4Žâéþuïf¹µö[P ,Q£éaX±`PÉÍZ ¸äYúg üAx ’6Lê‚xÝÓ*äQ  Ï’¨hÍ =²,6ï#rÃ<¯–£»ƒ‹,–ê•€ aÛsñ'%Æ"®ÛüìBᝠHÚ3ß°©$“XnœÖ’î2ËTeûìxîß ¦å¿çÉ ðK§þ{‘t‚Ϋ¬jéîZ[ ”š7L¥4VÚCE×]m¤Øy”ä4-dz£œ§¸x.*ãÊÊ b÷•h:©‡¦s`BTÁRû¾g⻩‹jø sF¢àJøFl‘È•Xᓁà~*j¯ +(ÚÕ6-£¯÷GŠØy‚<Ç’.F‹Hœw(+)ÜÜâÈzÄäT§FߘãÏ;DmVœ3Àu@mÚüXÝü•3B¨òÌÁÛ<·ÃÜ z,Ì@õÅ·d2]ü8s÷IôÞ¯^Ç9¢u„~ëAŸï4«M? K]­ÅàPl@s_ p:°¬ZR”´›JC[CS.h‹ƒïËœ«Æ]–÷ó‚wR×k7X‰k›‘´ù¦=¡«‰¨¨Â')—71ó’c‡Ðúµ `é.{§p¹ój\Ž{1h{o±Ý=áUÊïGÖŒõ–-BÄm+AZX¶¡ ïHðæ¥JmÙ;…䡟ˆ¦ ° äšiÉg«$üMk5¤L“’çÊvïâï ,=f“"íἊ5ô¬x6{ɏžID0e¸vçmi'︧ºð9$ò¹÷*£’9ÿ ²TÔ…×>JV¥}Œ}$p[bÔ®*[jzS*8 ”·T›Í–ñUîƒwo$áè=LT™ç—~ô·¤ÈÚ$榍q‰„+´kFm)ž‹©i–ËqÞŠ‰à¶ü( ‚•§ •°ò·‡#5ª•µÊ﯅¡X¨šÁ*F#TXJÊ ušJVÍ&=iÄs1‚3•'fý§5Ñ<=[íÞ­ PÚ;ѱÌ_~Ä££8rÞ ²w;’hDT°>ÈG¬8Á²ÚzŽ®ò®qZcqJêäÞ-ö[ܘbň±çb“ж31²n×iƒðÕ;1¶þÉ ªX‰,ßqÏ$>•î íZ¥Z 1{ç൵+ƒÕµ¥°T$§K]á»Ûï*·¤tMI’ÂZbŽÕiÒ˜}bÓ0£ª5›¨ [5Ž^ÝœWøÂÝh° ¢OWun£¤5 a2Z.G2³YL]jåtì”ä ÁÓ‘%"©<Ôúʰsº UZvä‡ÄiÆÒM .÷V·™ø#kèýiíÌ–ª)µT[)BˆõÑ xB¾B€ÖT¨.¥~ð@VĶr#¸ü*åZNDŽH;âi ],©£öØpù(šºãö¼T.uCê•4@ÿ GÕÛ)Cx›®0ø#:ÏðFÒbR\(€€Ä®fã4Þ‰Fä¯HXƒÅ,†öEÑÔÜ]Öv²?tLÃvBY£ú6Êu5ÅAQ³1‘’¬x–HŒÐ‡ ^ ¸KwJôÖŽ5×CÚ¨vÜ«/B0$×k°=ðbÇ(Ï)w±A†Á† 11Í=èQšµ626ŒÜ/`G«µ<}—-Ö7KEHÈÉðóȤmݱû±·ø«Snmá=“䫚mݱŸ¡¶~ó·“äUóJæúòB|E LêŽy´jDÔ$G¢þÐñ7óR8ýÒ…Ç› WVe#·Ÿ p·Fx~•ݤF÷0Èÿ K¯æS<6’¡WШ; ´ÿ ¥Êø\Òuî†åÝ–VNœkÒ7oòX¨Á­Ø÷FÎÑä±g÷ÿ M~Çî=p,X´ ÝÌÚÅ‹’ÃjÖ.ØöÏñ qïQ¤ÓZE†° =6·]܈ s¸>v•Ž^Ý\wq9r‰Î\¸¡kURÒ$­*‹Nq?Þª*!sŠÆ:TU_u±T+øX¡ ®¹¡,ÄâÃBTsÜ$Ø›4m椴zÜK]’’›Pƒ @€#â˜`é¹=I‡fiV•Ôî“nRm+µFPOhÍ0B£ €+¬5c v•:P'ÒyÎ ‰V~‚Ó†ÖuókDoh$å\*ö%Ю=£«…aȼ½÷Û.-½VŒŠ¼'lyî±1¬3ó#ÞE¿ÔS¤gV£m›=§\û"—WU¤ÚǼÿ ÂnÁGŒÃ ‚õN D³õNÚíŒÕ;HôyÄÈ©P¹Ä{:?R‘Ô¨âF÷ø£bÅó® JS|‚R÷ivýáâ€Æé¡è³´IئÑT!§˜•ت‚¬â@q€wnïCWÄ@JU€ê¯m6]Ï:£âx'+ÒðXvÓ¦Úm=–´7œ $ì“B£~p%ÕŸUþ« N@¼üï~w˜ñø5®—'Ôe»¤5ã//€ž~‰Tþ›Å7•#¤× Íö pÄ$ùeåì*«ÓŠEØWEÈsßg ¦ûvžSsLpºÊW–âµEWöˬH; ™!CYõZ ÃÄf æ#1W. \uWâ\,\Çf j’<qTbên›Î[vxx£ë 'ö¨1›˜ÀM¼Pÿ H)ƒêêŒA7s,|F“ 꺸k³9Ìö*ç®;Ö!Ö$Eiž•¹ÒÚ†ýóéÝû¾ÕS®ó$’NÝäŸz¤5r¦ãÄÃD÷Üø!°ø‡Ô&@m™Ì^Ãä­d q5Lnÿ N;.6½·N|#ä"1Nƒx“ã<3('&ñßt  ~ªu”1Tb㫨9ê–›–bìd$ߣ=#ÕãÒmU¯eí$EFù5ýYô櫨æì™Ç—±ssM]·á¿0ÕåJRÓªîiƒ+O58ÖñªŠÒx" \µâá¨i’¤i —Ö ” M+M¤ë9‚‰A¦°Qõ¾ßøK~¼Ã‘g…Ö´~÷Ï[3GUœÒ½#…kàÔ®Ò”‰³·dWV‰IP‰Ú8u¹”E ÖqLj¾êÕCBš{A^Âß;–¨`¯¬ìö ˼ ×tìø.tƐm*n¨y4o&Àx¥n¦×î‡aupáÛj8¿m›è¶ã!o½;ß0y^ý×^EÑ¿ÒjzŒ­)vÚÑnÄL …^ªô× ‡—‚3k Îý­hï]içå–îÏ*÷ñþ»Ô CÒjøjÍznˆ´ ¹#b'Fô‹ ‰v¥'’à'T´ƒHýÍ%M‰ ƒ&ÆÇŒï1 ‘ –Þ ‰i¬s žR-Ÿ kЬá¬7:þ 0ŒÅÒÕ/aÙ¬ÃÝ#Úøœ ©aiVc‰. ¹¦ãµ” ›Yg¦›ÆÎýº°f³7ƒhá·¸­}&D9¡ÂsÉÙÞèŠõØàC™¨ñbFC|´Ü(ŸƒÚÒ-%»'a Ì¿)ËÇn¿úÿ ÞŽX…4ÊÅH^ôΑí@ù¹Eh¶“L8Çjù ¼ÎåVªóR©Ï5uà V4lZß®=€xÖŸ–ÑÈ ÷”¨°¾__yM1tÉ?uÆþIkÄgæ@þ[¢†°XÃJ£j·:nkÅ¢u ‘}âGzö­/IµèЬ¼48q¦F°ŽR¼=ûì{´¯RýicS ÕÛ íNtÍÙï£,w4rêì®»~x(©Uñ§#Ñ&œÕ¤>ÎåÍÓ9’Ö{9eV­[Öjâ²ãu]˜å2›qÑšÕJç0€sÄ|Êëè0튔bÁ>“{×_F`Ø©ºê:µä,v¤ðfc1±"«ÔÍän1#=· Âøv~H½ÐßA¾¿Ü€Óš]Õ; I¾÷ç‚Qi†î¹9ywÔKG˜áñ zQY—§ÃÕZ07§X‚ Áh;ÁM)iÌCH-¯T‘ë|A0{Ò½LÚ–TâÖkÜ’dÀ“rmm»”جPF³ÖcbE§T€ÒxKºû’Ó®7±²(\4ŽÃ¸Uu@j™yĵ;³µ!Á¢b.W¤=mõ´êµK k ¸K^ÜÛ#p*Ü14qkZç5ïë †°5Ï%ÍÛ<Õ¤×Ô¥ê†C Õ´¼ú$ƒÖ“”]Ù¬qÞÚ[4©ý!ûÏ—Áb쳐XµA¬â~`›Çr¸8ìùÝ䫦<>ä÷«?xs´ÇÑ /á;¹øüÊÈÙà{"@Žïzâ¬[âß‚ U_<ÇŸ½4èN˜ú61®qŠu ¦þF£»äJ_ˆÙÎ~ ÞAã–݄ϗrŠD;xTž‘ô`É«…suãO`?³à™ô Lý#Íc5öoæØ‚y´´÷«ZR§<&JÇ+éâô´€i!Àˆ0æAoàðLèÖ-2ŸõW.’t^–(KÁmHµV@xÜÇy®Ñø­â^:Ú3w· 7½¹°ñ¸â¹®:',«Mœ—n­Á+Ãbš LÈ‘ÄnRÓÅœ%¦²‰¨ùQ:¤f‚ "PÕtô¸…cæl…&˜Ú˜Ôkv‹ž+vŠ,=¢v­6—Xy*¥t£«<™:“aîϲ=¦6rO]XI¿Œ÷¤zÚ­›¶ 6÷”w\d ü~v®ˆÌk«^m<ÿ ¢‰Õ\)ùºŽ;… lîÙÅEŠ®cѾ@vnMÏ,¼“ñ•ŽBxðÃzãÇç%3ˆ"}Ù•Åî> BÉú;Ò]V+P˜F_´ßé> Øše|ï‡ÄOmFæÇ ãqÞ$/xÐx­z`ï9"œÜij‚!7.\Td…9M‡•iŽ‹¾‘50ÞŽn¥ß4ÉôO ¹*í^QêËÜÇÌ8=ާs‰'ÂëÙ«á%Pú[O †ÅP¯Vsް.‰,kc¶ ¬A9n˜XÎ-ÞšN["¹QÕ‰ƒMýÁߺXJæÍaLj¾×Ãmã¾ãÚ uñÒþåQô¦¥ /ÄUx:‚ÍÜ’ Đ©ØÝ3V¨‰ÕnÐ6ó*óúK­«…c ¯U òhsý­jóÔj#,ímŒRµ«lbïUTŒÑ8†Ä0œÏr`ð¡¬É Ї ë"À² ™ 6¥ f¶ ¢ÚoܱԷ-<Àî)†a¶ž'Ú»¨TXqØæ¶÷YÄHy˜9ÈIW­YÀuMFë ºÏ’AqÌ4·/Ú †ô'i$øä­=Ä Ý|öK×40è|È6p‘0§)o¥ctî§H+CA-“ xØ|ÐXАç l8íºð3Ø:³¤¬KX¯UÿÙ var mapping = require('./_mapping'), fallbackHolder = require('./placeholder'); /** Built-in value reference. */ var push = Array.prototype.push; /** * Creates a function, with an arity of `n`, that invokes `func` with the * arguments it receives. * * @private * @param {Function} func The function to wrap. * @param {number} n The arity of the new function. * @returns {Function} Returns the new function. */ function baseArity(func, n) { return n == 2 ? function(a, b) { return func.apply(undefined, arguments); } : function(a) { return func.apply(undefined, arguments); }; } /** * Creates a function that invokes `func`, with up to `n` arguments, ignoring * any additional arguments. * * @private * @param {Function} func The function to cap arguments for. * @param {number} n The arity cap. * @returns {Function} Returns the new function. */ function baseAry(func, n) { return n == 2 ? function(a, b) { return func(a, b); } : function(a) { return func(a); }; } /** * Creates a clone of `array`. * * @private * @param {Array} array The array to clone. * @returns {Array} Returns the cloned array. */ function cloneArray(array) { var length = array ? array.length : 0, result = Array(length); while (length--) { result[length] = array[length]; } return result; } /** * Creates a function that clones a given object using the assignment `func`. * * @private * @param {Function} func The assignment function. * @returns {Function} Returns the new cloner function. */ function createCloner(func) { return function(object) { return func({}, object); }; } /** * A specialized version of `_.spread` which flattens the spread array into * the arguments of the invoked `func`. * * @private * @param {Function} func The function to spread arguments over. * @param {number} start The start position of the spread. * @returns {Function} Returns the new function. */ function flatSpread(func, start) { return function() { var length = arguments.length, lastIndex = length - 1, args = Array(length); while (length--) { args[length] = arguments[length]; } var array = args[start], otherArgs = args.slice(0, start); if (array) { push.apply(otherArgs, array); } if (start != lastIndex) { push.apply(otherArgs, args.slice(start + 1)); } return func.apply(this, otherArgs); }; } /** * Creates a function that wraps `func` and uses `cloner` to clone the first * argument it receives. * * @private * @param {Function} func The function to wrap. * @param {Function} cloner The function to clone arguments. * @returns {Function} Returns the new immutable function. */ function wrapImmutable(func, cloner) { return function() { var length = arguments.length; if (!length) { return; } var args = Array(length); while (length--) { args[length] = arguments[length]; } var result = args[0] = cloner.apply(undefined, args); func.apply(undefined, args); return result; }; } /** * The base implementation of `convert` which accepts a `util` object of methods * required to perform conversions. * * @param {Object} util The util object. * @param {string} name The name of the function to convert. * @param {Function} func The function to convert. * @param {Object} [options] The options object. * @param {boolean} [options.cap=true] Specify capping iteratee arguments. * @param {boolean} [options.curry=true] Specify currying. * @param {boolean} [options.fixed=true] Specify fixed arity. * @param {boolean} [options.immutable=true] Specify immutable operations. * @param {boolean} [options.rearg=true] Specify rearranging arguments. * @returns {Function|Object} Returns the converted function or object. */ function baseConvert(util, name, func, options) { var isLib = typeof name == 'function', isObj = name === Object(name); if (isObj) { options = func; func = name; name = undefined; } if (func == null) { throw new TypeError; } options || (options = {}); var config = { 'cap': 'cap' in options ? options.cap : true, 'curry': 'curry' in options ? options.curry : true, 'fixed': 'fixed' in options ? options.fixed : true, 'immutable': 'immutable' in options ? options.immutable : true, 'rearg': 'rearg' in options ? options.rearg : true }; var defaultHolder = isLib ? func : fallbackHolder, forceCurry = ('curry' in options) && options.curry, forceFixed = ('fixed' in options) && options.fixed, forceRearg = ('rearg' in options) && options.rearg, pristine = isLib ? func.runInContext() : undefined; var helpers = isLib ? func : { 'ary': util.ary, 'assign': util.assign, 'clone': util.clone, 'curry': util.curry, 'forEach': util.forEach, 'isArray': util.isArray, 'isError': util.isError, 'isFunction': util.isFunction, 'isWeakMap': util.isWeakMap, 'iteratee': util.iteratee, 'keys': util.keys, 'rearg': util.rearg, 'toInteger': util.toInteger, 'toPath': util.toPath }; var ary = helpers.ary, assign = helpers.assign, clone = helpers.clone, curry = helpers.curry, each = helpers.forEach, isArray = helpers.isArray, isError = helpers.isError, isFunction = helpers.isFunction, isWeakMap = helpers.isWeakMap, keys = helpers.keys, rearg = helpers.rearg, toInteger = helpers.toInteger, toPath = helpers.toPath; var aryMethodKeys = keys(mapping.aryMethod); var wrappers = { 'castArray': function(castArray) { return function() { var value = arguments[0]; return isArray(value) ? castArray(cloneArray(value)) : castArray.apply(undefined, arguments); }; }, 'iteratee': function(iteratee) { return function() { var func = arguments[0], arity = arguments[1], result = iteratee(func, arity), length = result.length; if (config.cap && typeof arity == 'number') { arity = arity > 2 ? (arity - 2) : 1; return (length && length <= arity) ? result : baseAry(result, arity); } return result; }; }, 'mixin': function(mixin) { return function(source) { var func = this; if (!isFunction(func)) { return mixin(func, Object(source)); } var pairs = []; each(keys(source), function(key) { if (isFunction(source[key])) { pairs.push([key, func.prototype[key]]); } }); mixin(func, Object(source)); each(pairs, function(pair) { var value = pair[1]; if (isFunction(value)) { func.prototype[pair[0]] = value; } else { delete func.prototype[pair[0]]; } }); return func; }; }, 'nthArg': function(nthArg) { return function(n) { var arity = n < 0 ? 1 : (toInteger(n) + 1); return curry(nthArg(n), arity); }; }, 'rearg': function(rearg) { return function(func, indexes) { var arity = indexes ? indexes.length : 0; return curry(rearg(func, indexes), arity); }; }, 'runInContext': function(runInContext) { return function(context) { return baseConvert(util, runInContext(context), options); }; } }; /*--------------------------------------------------------------------------*/ /** * Casts `func` to a function with an arity capped iteratee if needed. * * @private * @param {string} name The name of the function to inspect. * @param {Function} func The function to inspect. * @returns {Function} Returns the cast function. */ function castCap(name, func) { if (config.cap) { var indexes = mapping.iterateeRearg[name]; if (indexes) { return iterateeRearg(func, indexes); } var n = !isLib && mapping.iterateeAry[name]; if (n) { return iterateeAry(func, n); } } return func; } /** * Casts `func` to a curried function if needed. * * @private * @param {string} name The name of the function to inspect. * @param {Function} func The function to inspect. * @param {number} n The arity of `func`. * @returns {Function} Returns the cast function. */ function castCurry(name, func, n) { return (forceCurry || (config.curry && n > 1)) ? curry(func, n) : func; } /** * Casts `func` to a fixed arity function if needed. * * @private * @param {string} name The name of the function to inspect. * @param {Function} func The function to inspect. * @param {number} n The arity cap. * @returns {Function} Returns the cast function. */ function castFixed(name, func, n) { if (config.fixed && (forceFixed || !mapping.skipFixed[name])) { var data = mapping.methodSpread[name], start = data && data.start; return start === undefined ? ary(func, n) : flatSpread(func, start); } return func; } /** * Casts `func` to an rearged function if needed. * * @private * @param {string} name The name of the function to inspect. * @param {Function} func The function to inspect. * @param {number} n The arity of `func`. * @returns {Function} Returns the cast function. */ function castRearg(name, func, n) { return (config.rearg && n > 1 && (forceRearg || !mapping.skipRearg[name])) ? rearg(func, mapping.methodRearg[name] || mapping.aryRearg[n]) : func; } /** * Creates a clone of `object` by `path`. * * @private * @param {Object} object The object to clone. * @param {Array|string} path The path to clone by. * @returns {Object} Returns the cloned object. */ function cloneByPath(object, path) { path = toPath(path); var index = -1, length = path.length, lastIndex = length - 1, result = clone(Object(object)), nested = result; while (nested != null && ++index < length) { var key = path[index], value = nested[key]; if (value != null && !(isFunction(value) || isError(value) || isWeakMap(value))) { nested[key] = clone(index == lastIndex ? value : Object(value)); } nested = nested[key]; } return result; } /** * Converts `lodash` to an immutable auto-curried iteratee-first data-last * version with conversion `options` applied. * * @param {Object} [options] The options object. See `baseConvert` for more details. * @returns {Function} Returns the converted `lodash`. */ function convertLib(options) { return _.runInContext.convert(options)(undefined); } /** * Create a converter function for `func` of `name`. * * @param {string} name The name of the function to convert. * @param {Function} func The function to convert. * @returns {Function} Returns the new converter function. */ function createConverter(name, func) { var realName = mapping.aliasToReal[name] || name, methodName = mapping.remap[realName] || realName, oldOptions = options; return function(options) { var newUtil = isLib ? pristine : helpers, newFunc = isLib ? pristine[methodName] : func, newOptions = assign(assign({}, oldOptions), options); return baseConvert(newUtil, realName, newFunc, newOptions); }; } /** * Creates a function that wraps `func` to invoke its iteratee, with up to `n` * arguments, ignoring any additional arguments. * * @private * @param {Function} func The function to cap iteratee arguments for. * @param {number} n The arity cap. * @returns {Function} Returns the new function. */ function iterateeAry(func, n) { return overArg(func, function(func) { return typeof func == 'function' ? baseAry(func, n) : func; }); } /** * Creates a function that wraps `func` to invoke its iteratee with arguments * arranged according to the specified `indexes` where the argument value at * the first index is provided as the first argument, the argument value at * the second index is provided as the second argument, and so on. * * @private * @param {Function} func The function to rearrange iteratee arguments for. * @param {number[]} indexes The arranged argument indexes. * @returns {Function} Returns the new function. */ function iterateeRearg(func, indexes) { return overArg(func, function(func) { var n = indexes.length; return baseArity(rearg(baseAry(func, n), indexes), n); }); } /** * Creates a function that invokes `func` with its first argument transformed. * * @private * @param {Function} func The function to wrap. * @param {Function} transform The argument transform. * @returns {Function} Returns the new function. */ function overArg(func, transform) { return function() { var length = arguments.length; if (!length) { return func(); } var args = Array(length); while (length--) { args[length] = arguments[length]; } var index = config.rearg ? 0 : (length - 1); args[index] = transform(args[index]); return func.apply(undefined, args); }; } /** * Creates a function that wraps `func` and applys the conversions * rules by `name`. * * @private * @param {string} name The name of the function to wrap. * @param {Function} func The function to wrap. * @returns {Function} Returns the converted function. */ function wrap(name, func, placeholder) { var result, realName = mapping.aliasToReal[name] || name, wrapped = func, wrapper = wrappers[realName]; if (wrapper) { wrapped = wrapper(func); } else if (config.immutable) { if (mapping.mutate.array[realName]) { wrapped = wrapImmutable(func, cloneArray); } else if (mapping.mutate.object[realName]) { wrapped = wrapImmutable(func, createCloner(func)); } else if (mapping.mutate.set[realName]) { wrapped = wrapImmutable(func, cloneByPath); } } each(aryMethodKeys, function(aryKey) { each(mapping.aryMethod[aryKey], function(otherName) { if (realName == otherName) { var data = mapping.methodSpread[realName], afterRearg = data && data.afterRearg; result = afterRearg ? castFixed(realName, castRearg(realName, wrapped, aryKey), aryKey) : castRearg(realName, castFixed(realName, wrapped, aryKey), aryKey); result = castCap(realName, result); result = castCurry(realName, result, aryKey); return false; } }); return !result; }); result || (result = wrapped); if (result == func) { result = forceCurry ? curry(result, 1) : function() { return func.apply(this, arguments); }; } result.convert = createConverter(realName, func); result.placeholder = func.placeholder = placeholder; return result; } /*--------------------------------------------------------------------------*/ if (!isObj) { return wrap(name, func, defaultHolder); } var _ = func; // Convert methods by ary cap. var pairs = []; each(aryMethodKeys, function(aryKey) { each(mapping.aryMethod[aryKey], function(key) { var func = _[mapping.remap[key] || key]; if (func) { pairs.push([key, wrap(key, func, _)]); } }); }); // Convert remaining methods. each(keys(_), function(key) { var func = _[key]; if (typeof func == 'function') { var length = pairs.length; while (length--) { if (pairs[length][0] == key) { return; } } func.convert = createConverter(key, func); pairs.push([key, func]); } }); // Assign to `_` leaving `_.prototype` unchanged to allow chaining. each(pairs, function(pair) { _[pair[0]] = pair[1]; }); _.convert = convertLib; _.placeholder = _; // Assign aliases. each(keys(_), function(key) { each(mapping.realToAlias[key] || [], function(alias) { _[alias] = _[key]; }); }); return _; } module.exports = baseConvert;