From 15f8262818ab3d2e743b817395ea7a0ac29cab09 Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Sun, 19 Jun 2016 13:40:28 -0400 Subject: Initial esdocs documentation (#1083) --- README.md | 1994 +--------------------------------------------------- lib/cargo.js | 4 +- lib/index.js | 2 +- lib/queue.js | 4 +- package.json | 4 +- support/esdoc.json | 6 + 6 files changed, 16 insertions(+), 1998 deletions(-) create mode 100644 support/esdoc.json diff --git a/README.md b/README.md index 28c108d..51c9903 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,8 @@ There are many more functions available so take a look at the docs below for a full list. This module aims to be comprehensive, so if you feel anything is missing please create a GitHub issue for it. -## Common Pitfalls [(StackOverflow)](http://stackoverflow.com/questions/tagged/async.js) +## Common Pitfalls [(StackOverflow)](http://stackoverflow.com/questions/tagged/async.js) + ### Synchronous iteration functions If you get an error like `RangeError: Maximum call stack size exceeded.` or other stack overflow issues when using async, you are likely using a synchronous iteratee. By *synchronous* we mean a function that calls its callback on the same tick in the javascript event loop, without doing any I/O or using any timers. Calling many callbacks iteratively will quickly overflow the stack. If you run into this issue, just defer your callback with `async.setImmediate` to start a new call stack on the next tick of the event loop. @@ -209,1994 +210,3 @@ import waterfall from 'async-es/waterfall'; import async from 'async-es'; ``` -## Documentation - -Some functions are also available in the following forms: -* `Series` - the same as `` but runs only a single async operation at a time -* `Limit` - the same as `` but runs a maximum of `limit` async operations at a time - -### Collections - -* [`each`](#each), `eachSeries`, `eachLimit` -* [`forEachOf`](#forEachOf), `forEachOfSeries`, `forEachOfLimit` -* [`map`](#map), `mapSeries`, `mapLimit` -* [`filter`](#filter), `filterSeries`, `filterLimit` -* [`reject`](#reject), `rejectSeries`, `rejectLimit` -* [`reduce`](#reduce), [`reduceRight`](#reduceRight) -* [`transform`](#transform) -* [`detect`](#detect), `detectSeries`, `detectLimit` -* [`sortBy`](#sortBy) -* [`some`](#some), `someLimit`, `someSeries` -* [`every`](#every), `everyLimit`, `everySeries` -* [`concat`](#concat), `concatSeries` - -### Control Flow - -* [`series`](#seriestasks-callback) -* [`parallel`](#parallel), `parallelLimit` -* [`whilst`](#whilst), [`doWhilst`](#doWhilst) -* [`until`](#until), [`doUntil`](#doUntil) -* [`during`](#during), [`doDuring`](#doDuring) -* [`forever`](#forever) -* [`waterfall`](#waterfall) -* [`compose`](#compose) -* [`seq`](#seq) -* [`applyEach`](#applyEach), `applyEachSeries` -* [`queue`](#queue), [`priorityQueue`](#priorityQueue) -* [`cargo`](#cargo) -* [`auto`](#auto) -* [`autoInject`](#autoInject) -* [`retry`](#retry) -* [`retryable`](#retryable) -* [`iterator`](#iterator) -* [`times`](#times), `timesSeries`, `timesLimit` -* [`race`](#race) - -### Utils - -* [`apply`](#apply) -* [`nextTick`](#nextTick) -* [`memoize`](#memoize) -* [`unmemoize`](#unmemoize) -* [`ensureAsync`](#ensureAsync) -* [`constant`](#constant) -* [`asyncify`](#asyncify) -* [`wrapSync`](#wrapSync) -* [`log`](#log) -* [`dir`](#dir) -* [`noConflict`](#noConflict) -* [`timeout`](#timeout) -* [`reflect`](#reflect) -* [`reflectAll`](#reflectAll) - -## Collections - -Collection methods can iterate over Arrays, Objects, Maps, Sets, and any object that implements the ES2015 iterator protocol. - - - - -### each(coll, iteratee, [callback]) - -Applies the function `iteratee` to each item in `coll`, in parallel. -The `iteratee` is called with an item from the list, and a callback for when it -has finished. If the `iteratee` passes an error to its `callback`, the main -`callback` (for the `each` function) is immediately called with the error. - -Note, that since this function applies `iteratee` to each item in parallel, -there is no guarantee that the iteratee functions will complete in order. - -__Arguments__ - -* `coll` - A collection to iterate over. -* `iteratee(item, callback)` - A function to apply to each item in `coll`. - The iteratee is passed a `callback(err)` which must be called once it has - completed. If no error has occurred, the `callback` should be run without - arguments or with an explicit `null` argument. The array index is not passed - to the iteratee. If you need the index, use [`forEachOf`](#forEachOf). -* `callback(err)` - *Optional* A callback which is called when all `iteratee` functions - have finished, or an error occurs. - -__Examples__ - - -```js -// assuming openFiles is an array of file names and saveFile is a function -// to save the modified contents of that file: - -async.each(openFiles, saveFile, function(err){ - // if any of the saves produced an error, err would equal that error -}); -``` - -```js -// assuming openFiles is an array of file names - -async.each(openFiles, function(file, callback) { - - // Perform operation on file here. - console.log('Processing file ' + file); - - if (file.length > 32) { - console.log('This file name is too long'); - callback('File name too long'); - } else { - // Do work to process file here - console.log('File processed'); - callback(); - } -}, function(err){ - // if any of the file processing produced an error, err would equal that error - if (err) { - // One of the iterations produced an error. - // All processing will now stop. - console.log('A file failed to process'); - } else { - console.log('All files have been processed successfully'); - } -}); -``` - -__Related__ - -* eachSeries(coll, iteratee, [callback]) -* eachLimit(coll, limit, iteratee, [callback]) - ---------------------------------------- - - - - -### forEachOf(coll, iteratee, [callback]) - -Like `each`, except that it passes the key (or index) as the second argument to the iteratee. - -__Arguments__ - -* `coll` - A collection to iterate over. -* `iteratee(item, key, callback)` - A function to apply to each item in `coll`. -The `key` is the item's key, or index in the case of an array. The iteratee is -passed a `callback(err)` which must be called once it has completed. If no -error has occurred, the callback should be run without arguments or with an -explicit `null` argument. -* `callback(err)` - *Optional* A callback which is called when all `iteratee` functions have finished, or an error occurs. - -__Example__ - -```js -var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"}; -var configs = {}; - -async.forEachOf(obj, function (value, key, callback) { - fs.readFile(__dirname + value, "utf8", function (err, data) { - if (err) return callback(err); - try { - configs[key] = JSON.parse(data); - } catch (e) { - return callback(e); - } - callback(); - }); -}, function (err) { - if (err) console.error(err.message); - // configs is now a map of JSON data - doSomethingWith(configs); -}) -``` - -__Related__ - -* forEachOfSeries(coll, iteratee, [callback]) -* forEachOfLimit(coll, limit, iteratee, [callback]) - ---------------------------------------- - - - -### map(coll, iteratee, [callback]) - -Produces a new collection of values by mapping each value in `coll` through -the `iteratee` function. The `iteratee` is called with an item from `coll` and a -callback for when it has finished processing. Each of these callback takes 2 arguments: -an `error`, and the transformed item from `coll`. If `iteratee` passes an error to its -callback, the main `callback` (for the `map` function) is immediately called with the error. - -Note, that since this function applies the `iteratee` to each item in parallel, -there is no guarantee that the `iteratee` functions will complete in order. -However, the results array will be in the same order as the original `coll`. - -__Arguments__ - -* `coll` - A collection to iterate over. -* `iteratee(item, callback)` - A function to apply to each item in `coll`. - The iteratee is passed a `callback(err, transformed)` which must be called once - it has completed with an error (which can be `null`) and a transformed item. -* `callback(err, results)` - *Optional* A callback which is called when all `iteratee` - functions have finished, or an error occurs. Results is an array of the - transformed items from the `coll`. - -__Example__ - -```js -async.map(['file1','file2','file3'], fs.stat, function(err, results){ - // results is now an array of stats for each file -}); -``` - -__Related__ - -* mapSeries(coll, iteratee, [callback]) -* mapLimit(coll, limit, iteratee, [callback]) - ---------------------------------------- - - - - -### filter(coll, iteratee, [callback]) - -__Alias:__ `select` - -Returns a new array of all the values in `coll` which pass an async truth test. -This operation is performed in parallel, -but the results array will be in the same order as the original. - -__Arguments__ - -* `coll` - A collection to iterate over. -* `iteratee(item, callback)` - A truth test to apply to each item in `coll`. - The `iteratee` is passed a `callback(err, truthValue)` , which must be called with a boolean argument once it has completed. **Callback arguments changed in 2.0** -* `callback(err, results)` - *Optional* A callback which is called after all the `iteratee` - functions have finished. - -__Example__ - -```js -async.filter(['file1','file2','file3'], function(filePath, callback) { - fs.access(filePath, function(err) { - callback(null, !err) - }); -}, function(err, results){ - // results now equals an array of the existing files -}); -``` - -__Related__ - -* filterSeries(coll, iteratee, [callback]) -* filterLimit(coll, limit, iteratee, [callback]) - ---------------------------------------- - - - -### reject(coll, iteratee, [callback]) - -The opposite of [`filter`](#filter). Removes values that pass an `async` truth test. - -__Related__ - -* rejectSeries(coll, iteratee, [callback]) -* rejectLimit(coll, limit, iteratee, [callback]) - ---------------------------------------- - - - -### reduce(coll, memo, iteratee, [callback]) - -__Aliases:__ `inject`, `foldl` - -Reduces `coll` into a single value using an async `iteratee` to return -each successive step. `memo` is the initial state of the reduction. -This function only operates in series. - -For performance reasons, it may make sense to split a call to this function into -a parallel map, and then use the normal `Array.prototype.reduce` on the results. -This function is for situations where each step in the reduction needs to be async; -if you can get the data before reducing it, then it's probably a good idea to do so. - -__Arguments__ - -* `coll` - A collection to iterate over. -* `memo` - The initial state of the reduction. -* `iteratee(memo, item, callback)` - A function applied to each item in the - array to produce the next step in the reduction. The `iteratee` is passed a - `callback(err, reduction)` which accepts an optional error as its first - argument, and the state of the reduction as the second. If an error is - passed to the callback, the reduction is stopped and the main `callback` is - immediately called with the error. -* `callback(err, result)` - *Optional* A callback which is called after all the `iteratee` - functions have finished. Result is the reduced value. - -__Example__ - -```js -async.reduce([1,2,3], 0, function(memo, item, callback){ - // pointless async: - process.nextTick(function(){ - callback(null, memo + item) - }); -}, function(err, result){ - // result is now equal to the last value of memo, which is 6 -}); -``` - ---------------------------------------- - - - -### reduceRight(coll, memo, iteratee, [callback]) - -__Alias:__ `foldr` - -Same as [`reduce`](#reduce), only operates on `coll` in reverse order. - ---------------------------------------- - - - -### detect(coll, iteratee, [callback]) - -__Alias:__ `find` - -Returns the first value in `coll` that passes an async truth test. The -`iteratee` is applied in parallel, meaning the first iteratee to return `true` will -fire the detect `callback` with that result. That means the result might not be -the first item in the original `coll` (in terms of order) that passes the test. - -If order within the original `coll` is important, then look at `detectSeries`. - -__Arguments__ - -* `coll` - A collection to iterate over. -* `iteratee(item, callback)` - A truth test to apply to each item in `coll`. The iteratee is passed a `callback(err, truthValue)` which must be called with a boolean argument once it has completed. **Callback arguments changed in 2.0** -* `callback(err, result)` - *Optional* A callback which is called as soon as any iteratee returns - `true`, or after all the `iteratee` functions have finished. Result will be - the first item in the array that passes the truth test (iteratee) or the - value `undefined` if none passed. - -__Example__ - -```js -async.detect(['file1','file2','file3'], function(filePath, callback) { - fs.access(filePath, function(err) { - callback(null, !err) - }); -}, function(err, result){ - // result now equals the first file in the list that exists -}); -``` - -__Related__ - -* detectSeries(coll, iteratee, [callback]) -* detectLimit(coll, limit, iteratee, [callback]) - ---------------------------------------- - - - -### sortBy(coll, iteratee, [callback]) - -Sorts a list by the results of running each `coll` value through an async `iteratee`. - -__Arguments__ - -* `coll` - A collection to iterate over. -* `iteratee(item, callback)` - A function to apply to each item in `coll`. - The iteratee is passed a `callback(err, sortValue)` which must be called once it - has completed with an error (which can be `null`) and a value to use as the sort - criteria. -* `callback(err, results)` - *Optional* A callback which is called after all the `iteratee` - functions have finished, or an error occurs. Results is the items from - the original `coll` sorted by the values returned by the `iteratee` calls. - -__Example__ - -```js -async.sortBy(['file1','file2','file3'], function(file, callback){ - fs.stat(file, function(err, stats){ - callback(err, stats.mtime); - }); -}, function(err, results){ - // results is now the original array of files sorted by - // modified date -}); -``` - -__Sort Order__ - -By modifying the callback parameter the sorting order can be influenced: - -```js -//ascending order -async.sortBy([1,9,3,5], function(x, callback){ - callback(null, x); -}, function(err,result){ - //result callback -} ); - -//descending order -async.sortBy([1,9,3,5], function(x, callback){ - callback(null, x*-1); //<- x*-1 instead of x, turns the order around -}, function(err,result){ - //result callback -} ); -``` - ---------------------------------------- - - - -### some(coll, iteratee, [callback]) - -__Alias:__ `any` - -Returns `true` if at least one element in the `coll` satisfies an async test. -If any iteratee call returns `true`, the main `callback` is immediately called. - -__Arguments__ - -* `coll` - A collection to iterate over. -* `iteratee(item, callback)` - A truth test to apply to each item in the array - in parallel. The iteratee is passed a `callback(err, truthValue)` which must be called with a boolean argument once it has completed. **Callback arguments changed in 2.0** -* `callback(err, result)` - *Optional* A callback which is called as soon as any iteratee returns - `true`, or after all the iteratee functions have finished. Result will be - either `true` or `false` depending on the values of the async tests. - -__Example__ - -```js -async.some(['file1','file2','file3'], function(filePath, callback) { - fs.access(filePath, function(err) { - callback(null, !err) - }); -}, function(err, result){ - // if result is true then at least one of the files exists -}); -``` - -__Related__ - -* someSeries(coll, iteratee, callback) -* someLimit(coll, limit, iteratee, callback) - ---------------------------------------- - - - -### every(coll, iteratee, [callback]) - -__Alias:__ `all` - -Returns `true` if every element in `coll` satisfies an async test. -If any iteratee call returns `false`, the main `callback` is immediately called. - -__Arguments__ - -* `coll` - A collection to iterate over. -* `iteratee(item, callback)` - A truth test to apply to each item in the collection in parallel. The iteratee is passed a `callback(err, truthValue)` which must be called with a boolean argument once it has completed. **Callback arguments changed in 2.0** -* `callback(err, result)` - *Optional* A callback which is called after all the `iteratee` - functions have finished. Result will be either `true` or `false` depending on - the values of the async tests. - -__Example__ - -```js -async.every(['file1','file2','file3'], function(filePath, callback) { - fs.access(filePath, function(err) { - callback(null, !err) - }); -}, function(err, result){ - // if result is true then every file exists -}); -``` - -__Related__ - -* everySeries(coll, iteratee, callback) -* everyLimit(coll, limit, iteratee, callback) - ---------------------------------------- - - - -### concat(coll, iteratee, [callback]) - -Applies `iteratee` to each item in `coll`, concatenating the results. Returns the -concatenated list. The `iteratee`s are called in parallel, and the results are -concatenated as they return. There is no guarantee that the results array will -be returned in the original order of `coll` passed to the `iteratee` function. - -__Arguments__ - -* `coll` - A collection to iterate over. -* `iteratee(item, callback)` - A function to apply to each item in `coll`. - The iteratee is passed a `callback(err, results)` which must be called once it - has completed with an error (which can be `null`) and an array of results. -* `callback(err, results)` - *Optional* A callback which is called after all the `iteratee` - functions have finished, or an error occurs. Results is an array containing - the concatenated results of the `iteratee` function. - -__Example__ - -```js -async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ - // files is now a list of filenames that exist in the 3 directories -}); -``` - -__Related__ - -* concatSeries(coll, iteratee, [callback]) - - -## Control Flow - - - -### series(tasks, [callback]) - -Run the functions in the `tasks` collection in series, each one running once the previous -function has completed. If any functions in the series pass an error to its -callback, no more functions are run, and `callback` is immediately called with the value of the error. -Otherwise, `callback` receives an array of results when `tasks` have completed. - -It is also possible to use an object instead of an array. Each property will be -run as a function, and the results will be passed to the final `callback` as an object -instead of an array. This can be a more readable way of handling results from -[`series`](#series). - -**Note** that while many implementations preserve the order of object properties, the -[ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) -explicitly states that - -> The mechanics and order of enumerating the properties is not specified. - -So if you rely on the order in which your series of functions are executed, and want -this to work on all platforms, consider using an array. - -__Arguments__ - -* `tasks` - A collection containing functions to run, each function is passed - a `callback(err, result)` it must call on completion with an error `err` (which can - be `null`) and an optional `result` value. -* `callback(err, results)` - An optional callback to run once all the functions - have completed. This function gets a results array (or object) containing all - the result arguments passed to the `task` callbacks. - -__Example__ - -```js -async.series([ - function(callback){ - // do some stuff ... - callback(null, 'one'); - }, - function(callback){ - // do some more stuff ... - callback(null, 'two'); - } -], -// optional callback -function(err, results){ - // results is now equal to ['one', 'two'] -}); - - -// an example using an object instead of an array -async.series({ - one: function(callback){ - setTimeout(function(){ - callback(null, 1); - }, 200); - }, - two: function(callback){ - setTimeout(function(){ - callback(null, 2); - }, 100); - } -}, -function(err, results) { - // results is now equal to: {one: 1, two: 2} -}); -``` - ---------------------------------------- - - - -### parallel(tasks, [callback]) - -Run the `tasks` collection of functions in parallel, without waiting until the previous -function has completed. If any of the functions pass an error to its -callback, the main `callback` is immediately called with the value of the error. -Once the `tasks` have completed, the results are passed to the final `callback` as an -array. - -**Note:** `parallel` is about kicking-off I/O tasks in parallel, not about parallel execution of code. If your tasks do not use any timers or perform any I/O, they will actually be executed in series. Any synchronous setup sections for each task will happen one after the other. JavaScript remains single-threaded. - -It is also possible to use an object instead of an array. Each property will be -run as a function and the results will be passed to the final `callback` as an object -instead of an array. This can be a more readable way of handling results from -[`parallel`](#parallel). - - -__Arguments__ - -* `tasks` - A collection containing functions to run. Each function is passed - a `callback(err, result)` which it must call on completion with an error `err` - (which can be `null`) and an optional `result` value. -* `callback(err, results)` - An optional callback to run once all the functions - have completed successfully. This function gets a results array (or object) containing all - the result arguments passed to the task callbacks. - -__Example__ - -```js -async.parallel([ - function(callback){ - setTimeout(function(){ - callback(null, 'one'); - }, 200); - }, - function(callback){ - setTimeout(function(){ - callback(null, 'two'); - }, 100); - } -], -// optional callback -function(err, results){ - // the results array will equal ['one','two'] even though - // the second function had a shorter timeout. -}); - - -// an example using an object instead of an array -async.parallel({ - one: function(callback){ - setTimeout(function(){ - callback(null, 1); - }, 200); - }, - two: function(callback){ - setTimeout(function(){ - callback(null, 2); - }, 100); - } -}, -function(err, results) { - // results is now equals to: {one: 1, two: 2} -}); -``` - -__Related__ - -* parallelLimit(tasks, limit, [callback]) - ---------------------------------------- - - - -### whilst(test, fn, callback) - -Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped, -or an error occurs. - -__Arguments__ - -* `test()` - synchronous truth test to perform before each execution of `fn`. -* `fn(callback)` - A function which is called each time `test` passes. The function is - passed a `callback(err)`, which must be called once it has completed with an - optional `err` argument. -* `callback(err, [results])` - A callback which is called after the test - function has failed and repeated execution of `fn` has stopped. `callback` - will be passed an error and any arguments passed to the final `fn`'s callback. - -__Example__ - -```js -var count = 0; - -async.whilst( - function () { return count < 5; }, - function (callback) { - count++; - setTimeout(function () { - callback(null, count); - }, 1000); - }, - function (err, n) { - // 5 seconds have passed, n = 5 - } -); -``` - ---------------------------------------- - - - -### doWhilst(fn, test, callback) - -The post-check version of [`whilst`](#whilst). To reflect the difference in -the order of operations, the arguments `test` and `fn` are switched. The `test` function is also passed the non-error callback results of `fn`. - -`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. - ---------------------------------------- - - - -### until(test, fn, callback) - -Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped, -or an error occurs. `callback` will be passed an error and any arguments passed -to the final `fn`'s callback. - -The inverse of [`whilst`](#whilst). - ---------------------------------------- - - - -### doUntil(fn, test, callback) - -Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`. The `test` function is also passed the non-error callback results of `fn`. - ---------------------------------------- - - - -### during(test, fn, callback) - -Like [`whilst`](#whilst), except the `test` is an asynchronous function that is passed a callback in the form of `function (err, truth)`. If error is passed to `test` or `fn`, the main callback is immediately called with the value of the error. - -Additionaly `during` passes any arguments passed by the iteratee function (2nd function) to the test function (1st function). The test callback will allways be the last parameter. - -__Example__ - -```js -var count = 0; - -async.during( - function (result, callback) { - if(!callback) { - callback = result; - result = null; - } - return callback(null, !result || result.counter < 5); - }, - function (callback) { - count++; - setTimeout(function() { - callback(null, { counter: count }); - }, 1000); - }, - function (err) { - // 5 seconds have passed - } -); -``` - ---------------------------------------- - - - -### doDuring(fn, test, callback) - -The post-check version of [`during`](#during). To reflect the difference in -the order of operations, the arguments `test` and `fn` are switched. - -Also a version of [`doWhilst`](#doWhilst) with asynchronous `test` function. - ---------------------------------------- - - - -### forever(fn, [errback]) - -Calls the asynchronous function `fn` with a callback parameter that allows it to -call itself again, in series, indefinitely. - -If an error is passed to the callback then `errback` is called with the -error, and execution stops, otherwise it will never be called. - -```js -async.forever( - function(next) { - // next is suitable for passing to things that need a callback(err [, whatever]); - // it will result in this function being called again. - }, - function(err) { - // if next is called with a value in its first parameter, it will appear - // in here as 'err', and execution will stop. - } -); -``` - ---------------------------------------- - - - -### waterfall(tasks, [callback]) - -Runs the `tasks` array of functions in series, each passing their results to the next in -the array. However, if any of the `tasks` pass an error to their own callback, the -next function is not executed, and the main `callback` is immediately called with -the error. - -__Arguments__ - -* `tasks` - An array of functions to run, each function is passed a - `callback(err, result1, result2, ...)` it must call on completion. The first - argument is an error (which can be `null`) and any further arguments will be - passed as arguments in order to the next task. -* `callback(err, [results])` - An optional callback to run once all the functions - have completed. This will be passed the results of the last task's callback. - - - -__Example__ - -```js -async.waterfall([ - function(callback) { - callback(null, 'one', 'two'); - }, - function(arg1, arg2, callback) { - // arg1 now equals 'one' and arg2 now equals 'two' - callback(null, 'three'); - }, - function(arg1, callback) { - // arg1 now equals 'three' - callback(null, 'done'); - } -], function (err, result) { - // result now equals 'done' -}); -``` -Or, with named functions: - -```js -async.waterfall([ - myFirstFunction, - mySecondFunction, - myLastFunction, -], function (err, result) { - // result now equals 'done' -}); -function myFirstFunction(callback) { - callback(null, 'one', 'two'); -} -function mySecondFunction(arg1, arg2, callback) { - // arg1 now equals 'one' and arg2 now equals 'two' - callback(null, 'three'); -} -function myLastFunction(arg1, callback) { - // arg1 now equals 'three' - callback(null, 'done'); -} -``` - -Or, if you need to pass any argument to the first function: - -```js -async.waterfall([ - async.apply(myFirstFunction, 'zero'), - mySecondFunction, - myLastFunction, -], function (err, result) { - // result now equals 'done' -}); -function myFirstFunction(arg1, callback) { - // arg1 now equals 'zero' - callback(null, 'one', 'two'); -} -function mySecondFunction(arg1, arg2, callback) { - // arg1 now equals 'one' and arg2 now equals 'two' - callback(null, 'three'); -} -function myLastFunction(arg1, callback) { - // arg1 now equals 'three' - callback(null, 'done'); -} -``` - ---------------------------------------- - - - -### compose(fn1, fn2...) - -Creates a function which is a composition of the passed asynchronous -functions. Each function consumes the return value of the function that -follows. Composing functions `f()`, `g()`, and `h()` would produce the result of -`f(g(h()))`, only this version uses callbacks to obtain the return values. - -Each function is executed with the `this` binding of the composed function. - -__Arguments__ - -* `functions...` - the asynchronous functions to compose - - -__Example__ - -```js -function add1(n, callback) { - setTimeout(function () { - callback(null, n + 1); - }, 10); -} - -function mul3(n, callback) { - setTimeout(function () { - callback(null, n * 3); - }, 10); -} - -var add1mul3 = async.compose(mul3, add1); - -add1mul3(4, function (err, result) { - // result now equals 15 -}); -``` - ---------------------------------------- - - - -### seq(fn1, fn2...) - -Version of the compose function that is more natural to read. -Each function consumes the return value of the previous function. -It is the equivalent of [`compose`](#compose) with the arguments reversed. - -Each function is executed with the `this` binding of the composed function. - -__Arguments__ - -* `functions...` - the asynchronous functions to compose - - -__Example__ - -```js -// Requires lodash (or underscore), express3 and dresende's orm2. -// Part of an app, that fetches cats of the logged user. -// This example uses `seq` function to avoid overnesting and error -// handling clutter. -app.get('/cats', function(request, response) { - var User = request.models.User; - async.seq( - _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data)) - function(user, fn) { - user.getCats(fn); // 'getCats' has signature (callback(err, data)) - } - )(req.session.user_id, function (err, cats) { - if (err) { - console.error(err); - response.json({ status: 'error', message: err.message }); - } else { - response.json({ status: 'ok', message: 'Cats found', data: cats }); - } - }); -}); -``` - ---------------------------------------- - - - -### applyEach(fns, args..., callback) - -Applies the provided arguments to each function in the array, calling -`callback` after all functions have completed. If you only provide the first -argument, then it will return a function which lets you pass in the -arguments as if it were a single function call. - -__Arguments__ - -* `fns` - A collection of asynchronous functions to all call with the same arguments -* `args...` - any number of separate arguments to pass to the function -* `callback` - the final argument should be the callback, called when all - functions have completed processing - - -__Example__ - -```js -async.applyEach([enableSearch, updateSchema], 'bucket', callback); - -// partial application example: -async.each( - buckets, - async.applyEach([enableSearch, updateSchema]), - callback -); -``` - -__Related__ - -* applyEachSeries(tasks, args..., [callback]) - ---------------------------------------- - - - -### queue(worker, [concurrency]) - -Creates a `queue` object with the specified `concurrency`. Tasks added to the -`queue` are processed in parallel (up to the `concurrency` limit). If all -`worker`s are in progress, the task is queued until one becomes available. -Once a `worker` completes a `task`, that `task`'s callback is called. - -__Arguments__ - -* `worker(task, callback)` - An asynchronous function for processing a queued - task, which must call its `callback(err)` argument when finished, with an - optional `error` as an argument. If you want to handle errors from an individual task, pass a callback to `q.push()`. -* `concurrency` - An `integer` for determining how many `worker` functions should be - run in parallel. If omitted, the concurrency defaults to `1`. If the concurrency is `0`, an error is thrown. - -__Queue objects__ - -The `queue` object returned by this function has the following properties and -methods: - -* `length()` - a function returning the number of items waiting to be processed. -* `started` - a function returning whether or not any items have been pushed and processed by the queue -* `running()` - a function returning the number of items currently being processed. -* `workersList()` - a function returning the array of items currently being processed. -* `idle()` - a function returning false if there are items waiting or being processed, or true if not. -* `concurrency` - an integer for determining how many `worker` functions should be - run in parallel. This property can be changed after a `queue` is created to - alter the concurrency on-the-fly. -* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once - the `worker` has finished processing the task. Instead of a single task, a `tasks` array - can be submitted. The respective callback is used for every task in the list. -* `unshift(task, [callback])` - add a new task to the front of the `queue`. -* `saturated` - a callback that is called when the number of running workers hits the `concurrency` limit, and further tasks will be queued. -* `unsaturated` - a callback that is called when the number of running workers is less than the `concurrency` & `buffer` limits, and further tasks will not be queued. -* `buffer` A minimum threshold buffer in order to say that the `queue` is `unsaturated`. -* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`. -* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`. -* `paused` - a boolean for determining whether the queue is in a paused state -* `pause()` - a function that pauses the processing of tasks until `resume()` is called. -* `resume()` - a function that resumes the processing of queued tasks when the queue is paused. -* `kill()` - a function that removes the `drain` callback and empties remaining tasks from the queue forcing it to go idle. - -__Example__ - -```js -// create a queue object with concurrency 2 - -var q = async.queue(function (task, callback) { - console.log('hello ' + task.name); - callback(); -}, 2); - - -// assign a callback -q.drain = function() { - console.log('all items have been processed'); -} - -// add some items to the queue - -q.push({name: 'foo'}, function (err) { - console.log('finished processing foo'); -}); -q.push({name: 'bar'}, function (err) { - console.log('finished processing bar'); -}); - -// add some items to the queue (batch-wise) - -q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { - console.log('finished processing item'); -}); - -// add some items to the front of the queue - -q.unshift({name: 'bar'}, function (err) { - console.log('finished processing bar'); -}); -``` - ---------------------------------------- - - - -### priorityQueue(worker, concurrency) - -The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects: - -* `push(task, priority, [callback])` - `priority` should be a number. If an array of - `tasks` is given, all tasks will be assigned the same priority. -* The `unshift` method was removed. - ---------------------------------------- - - - -### cargo(worker, [payload]) - -Creates a `cargo` object with the specified payload. Tasks added to the -cargo will be processed altogether (up to the `payload` limit). If the -`worker` is in progress, the task is queued until it becomes available. Once -the `worker` has completed some tasks, each callback of those tasks is called. -Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) for how `cargo` and `queue` work. - -While [queue](#queue) passes only one task to one of a group of workers -at a time, cargo passes an array of tasks to a single worker, repeating -when the worker is finished. - -__Arguments__ - -* `worker(tasks, callback)` - An asynchronous function for processing an array of - queued tasks, which must call its `callback(err)` argument when finished, with - an optional `err` argument. -* `payload` - An optional `integer` for determining how many tasks should be - processed per round; if omitted, the default is unlimited. - -__Cargo objects__ - -The `cargo` object returned by this function has the following properties and -methods: - -* `length()` - A function returning the number of items waiting to be processed. -* `payload` - An `integer` for determining how many tasks should be - process per round. This property can be changed after a `cargo` is created to - alter the payload on-the-fly. -* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called - once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` - can be submitted. The respective callback is used for every task in the list. -* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued. -* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`. -* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`. -* `idle()`, `pause()`, `resume()`, `kill()` - cargo inherits all of the same methods and event callbacks as [`queue`](#queue) - -__Example__ - -```js -// create a cargo object with payload 2 - -var cargo = async.cargo(function (tasks, callback) { - for(var i=0; i - -### auto(tasks, [concurrency], [callback]) - -Determines the best order for running the functions in `tasks`, based on their requirements. Each function can optionally depend on other functions being completed first, and each function is run as soon as its requirements are satisfied. - -If any of the functions pass an error to their callback, the `auto` sequence will stop. Further tasks will not execute (so any other functions depending on it will not run), and the main `callback` is immediately called with the error. - -Functions also receive an object containing the results of functions which have completed so far as the first argument, if they have dependencies. If a task function has no dependencies, it will only be passed a callback. - - -```js -async.auto({ - // this function will just be passed a callback - readData: async.apply(fs.readFile, 'data.txt', 'utf-8') - showData: ['readData', function (results, cb) { - // results.readData is the file's contents - // ... - }] -}, callback); -``` - - -__Arguments__ - -* `tasks` - An object. Each of its properties is either a function or an array of requirements, with the function itself the last item in the array. The object's key of a property serves as the name of the task defined by that property, i.e. can be used when specifying requirements for other tasks. The function receives one or two arguments: - * a `results` object, containing the results of the previously executed functions, only passed if the task has any dependencies, **Argument order changed in 2.0** - * a `callback(err, result)` function, which must be called when finished, passing an `error` (which can be `null`) and the result of the function's execution. **Argument order changed in 2.0** -* `concurrency` - An optional `integer` for determining the maximum number of tasks that can be run in parallel. By default, as many as possible. -* `callback(err, results)` - An optional callback which is called when all the tasks have been completed. It receives the `err` argument if any `tasks` pass an error to their callback. Results are always returned; however, if an error occurs, no further `tasks` will be performed, and the results object will only contain partial results. - -__Example__ - -```js -async.auto({ - get_data: function(callback){ - console.log('in get_data'); - // async code to get some data - callback(null, 'data', 'converted to array'); - }, - make_folder: function(callback){ - console.log('in make_folder'); - // async code to create a directory to store a file in - // this is run at the same time as getting the data - callback(null, 'folder'); - }, - write_file: ['get_data', 'make_folder', function(results, callback){ - console.log('in write_file', JSON.stringify(results)); - // once there is some data and the directory exists, - // write the data to a file in the directory - callback(null, 'filename'); - }], - email_link: ['write_file', function(results, callback){ - console.log('in email_link', JSON.stringify(results)); - // once the file is written let's email a link to it... - // results.write_file contains the filename returned by write_file. - callback(null, {'file':results.write_file, 'email':'user@example.com'}); - }] -}, function(err, results) { - console.log('err = ', err); - console.log('results = ', results); -}); -``` - -This is a fairly trivial example, but to do this using the basic parallel and series functions would look like this: - -```js -async.parallel([ - function(callback){ - console.log('in get_data'); - // async code to get some data - callback(null, 'data', 'converted to array'); - }, - function(callback){ - console.log('in make_folder'); - // async code to create a directory to store a file in - // this is run at the same time as getting the data - callback(null, 'folder'); - } -], -function(err, results){ - async.series([ - function(callback){ - console.log('in write_file', JSON.stringify(results)); - // once there is some data and the directory exists, - // write the data to a file in the directory - results.push('filename'); - callback(null); - }, - function(callback){ - console.log('in email_link', JSON.stringify(results)); - // once the file is written let's email a link to it... - callback(null, {'file':results.pop(), 'email':'user@example.com'}); - } - ]); -}); -``` - -For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding new tasks much easier (and the code more readable). - ---------------------------------------- - -### autoInject(tasks, [callback]) - -A dependency-injected version of the [`auto`](#auto) function. Dependent tasks are specified as parameters to the function, before the usual callback parameter, with the parameter names matching the names of the tasks it depends on. This can provide even more readable task graphs which can be easier to maintain. - -If a final callback is specified, the task results are still provided as a composite `results` object, exactly like auto. - -The autoInject function is purely syntactic sugar and its semantics are otherwise equivalent to [`auto`](#auto). - -__Arguments__ - -* `tasks` - An object, each of whose properties is a function of the form - 'func([dependencies...], callback). The object's key of a property serves as the name of the task defined by that property, i.e. can be used when specifying requirements for other tasks. - * The `callback` parameter is a `callback(err, result)` which must be called when finished, passing an `error` (which can be `null`) and the result of the function's execution. The remaining parameters name other tasks on which the task is dependent, and the results from those tasks are the arguments of those parameters. -* `callback(err, results)` - An optional callback which is called when all the tasks have been completed. It receives the `err` argument if any `tasks` pass an error to their callback. Results are always returned; however, if an error occurs, no further `tasks` will be performed, and the results object will only contain partial results. - - -__Example__ - -The example from [`auto`](#auto) can be rewritten as follows: - -```js -async.autoInject({ - get_data: function(callback){ - // async code to get some data - callback(null, 'data', 'converted to array'); - }, - make_folder: function(callback){ - // async code to create a directory to store a file in - // this is run at the same time as getting the data - callback(null, 'folder'); - }, - write_file: function(get_data, make_folder, callback){ - // once there is some data and the directory exists, - // write the data to a file in the directory - callback(null, 'filename'); - }, - email_link: function(write_file, callback){ - // once the file is written let's email a link to it... - // write_file contains the filename returned by write_file. - callback(null, {'file':write_file, 'email':'user@example.com'}); - } -}, function(err, results) { - console.log('err = ', err); - console.log('email_link = ', results.email_link); -}); -``` - -If you are using a JS minifier that mangles parameter names, `autoInject` will not work with plain functions, since the parameter names will be collapsed to a single letter identifier. To work around this, you can explicitly specify the names of the parameters your task function needs in an array, similar to Angular.js dependency injection. The final results callback can be provided as an array in the same way. - -```js -async.autoInject({ - //... - write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback){ - callback(null, 'filename'); - }], - email_link: ['write_file', function(write_file, callback){ - callback(null, {'file':write_file, 'email':'user@example.com'}); - }] - //... -}, function(err, results) { - console.log('err = ', err); - console.log('email_link = ', results.email_link); -}); -``` - -This still has an advantage over plain `auto`, since the results a task depends on are still spread into arguments. - - ---------------------------------------- - - - -### retry([opts = {times: 5, interval: 0}| 5], task, [callback]) - -Attempts to get a successful response from `task` no more than `times` times before -returning an error. If the task is successful, the `callback` will be passed the result -of the successful task. If all attempts fail, the callback will be passed the error and -result (if any) of the final attempt. - -__Arguments__ - -* `opts` - Can be either an object with `times` and `interval` or a number. - * `times` - The number of attempts to make before giving up. The default is `5`. - * `interval` - The time to wait between retries, in milliseconds. The default is `0`. The interval may also be specified as a function of the retry count (see example). - * If `opts` is a number, the number specifies the number of times to retry, with the default interval of `0`. -* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)` - which must be called when finished, passing `err` (which can be `null`) and the `result` of - the function's execution, and (2) a `results` object, containing the results of - the previously executed functions (if nested inside another control flow). -* `callback(err, results)` - An optional callback which is called when the - task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`. **Callback made optional in 2.0, use `retryable` for previous behavior.** - -The [`retry`](#retry) function can be used as a stand-alone control flow by passing a callback, as shown below: - -```js -// try calling apiMethod 3 times -async.retry(3, apiMethod, function(err, result) { - // do something with the result -}); -``` - -```js -// try calling apiMethod 3 times, waiting 200 ms between each retry -async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { - // do something with the result -}); -``` - -The interval may also be specified as a function of the retry count: - -```js -// try calling apiMethod 10 times with exponential backoff -// (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds) -async.retry({ - times: 10, - interval: function(retryCount) { - return 50 * Math.pow(2, retryCount); - } -}, apiMethod, function(err, result) { - // do something with the result -}); -``` - -```js -// try calling apiMethod the default 5 times no delay between each retry -async.retry(apiMethod, function(err, result) { - // do something with the result -}); -``` - -It can also be embedded within other control flow functions to retry individual methods -that are not as reliable, like this: - -```js -async.auto({ - users: api.getUsers.bind(api), - payments: async.retry(3, api.getPayments.bind(api)) -}, function(err, results) { - // do something with the results -}); -``` - - ---------------------------------------- - - - -### retryable([opts = {times: 5, interval: 0}| 5], task) - -A close relative of `retry`. This method wraps a task and makes it retryable, rather than immediately calling it with retries. - -__Arguments__ - -* `opts` - optional options, exactly the same as from `retry` -* `task` - the asynchronous function to wrap - -__Example__ - -```js -async.auto({ - dep1: async.retryable(3, getFromFlakyService), - process: ["dep1", async.retryable(3, function (results, cb) { - maybeProcessData(results.dep1, cb) - })] -}, callback) -``` - ---------------------------------------- - - - -### iterator(tasks) - -Creates an iterator function which calls the next function in the `tasks` array, -returning a continuation to call the next one after that. It's also possible to -“peek” at the next iterator with `iterator.next()`. - -This function is used internally by the `async` module, but can be useful when -you want to manually control the flow of functions in series. - -__Arguments__ - -* `tasks` - An array of functions to run. - -__Example__ - -```js -var iterator = async.iterator([ - function(){ sys.p('one'); }, - function(){ sys.p('two'); }, - function(){ sys.p('three'); } -]); - -node> var iterator2 = iterator(); -'one' -node> var iterator3 = iterator2(); -'two' -node> iterator3(); -'three' -node> var nextfn = iterator2.next(); -node> nextfn(); -'three' -``` - -## Utils - - - -### apply(function, arguments..) - -Creates a continuation function with some arguments already applied. - -Useful as a shorthand when combined with other control flow functions. Any arguments -passed to the returned function are added to the arguments originally passed -to apply. - -__Arguments__ - -* `function` - The function you want to eventually apply all arguments to. -* `arguments...` - Any number of arguments to automatically apply when the - continuation is called. - -__Example__ - -```js -// using apply - -async.parallel([ - async.apply(fs.writeFile, 'testfile1', 'test1'), - async.apply(fs.writeFile, 'testfile2', 'test2'), -]); - - -// the same process without using apply - -async.parallel([ - function(callback){ - fs.writeFile('testfile1', 'test1', callback); - }, - function(callback){ - fs.writeFile('testfile2', 'test2', callback); - } -]); -``` - -It's possible to pass any number of additional arguments when calling the -continuation: - -```js -node> var fn = async.apply(sys.puts, 'one'); -node> fn('two', 'three'); -one -two -three -``` - ---------------------------------------- - - - -### nextTick(callback, [args...]), setImmediate(callback, [args...]) - -Calls `callback` on a later loop around the event loop. In Node.js this just calls `setImmediate`. In the browser it will use `setImmediate` if available, otherwise `setTimeout(callback, 0)`, which means other higher priority events may precede the execution of `callback`. - -This is used internally for browser-compatibility purposes. - -__Arguments__ - -* `callback` - The function to call on a later loop around the event loop. -* `args...` - any number of additional arguments to pass to the callback on the next tick - -__Example__ - -```js -var call_order = []; -async.nextTick(function(){ - call_order.push('two'); - // call_order now equals ['one','two'] -}); -call_order.push('one') - -async.setImmediate(function (a, b, c) { - // a, b, and c equal 1, 2, and 3 -}, 1, 2, 3) -``` - ---------------------------------------- - - - -### times(n, iteratee, [callback]) - -Calls the `iteratee` function `n` times, and accumulates results in the same manner -you would use with [`map`](#map). - -__Arguments__ - -* `n` - The number of times to run the function. -* `iteratee` - The function to call `n` times. -* `callback` - see [`map`](#map) - -__Example__ - -```js -// Pretend this is some complicated async factory -var createUser = function(id, callback) { - callback(null, { - id: 'user' + id - }) -} -// generate 5 users -async.times(5, function(n, next){ - createUser(n, function(err, user) { - next(err, user) - }) -}, function(err, users) { - // we should now have 5 users -}); -``` - -__Related__ - -* timesSeries(n, iteratee, [callback]) -* timesLimit(n, limit, iteratee, [callback]) - ---------------------------------------- - - -### race(tasks, [callback]) - -Runs the `tasks` array of functions in parallel, without waiting until the -previous function has completed. Once any the `tasks` completed or pass an -error to its callback, the main `callback` is immediately called. It's -equivalent to `Promise.race()`. - -__Arguments__ - -* `tasks` - An array containing functions to run. Each function is passed - a `callback(err, result)` which it must call on completion with an error `err` - (which can be `null`) and an optional `result` value. -* `callback(err, result)` - A callback to run once any of the - functions have completed. This function gets an error or result from the - first function that completed. - -__Example__ - -```js -async.race([ - function(callback){ - setTimeout(function(){ - callback(null, 'one'); - }, 200); - }, - function(callback){ - setTimeout(function(){ - callback(null, 'two'); - }, 100); - } -], -// main callback -function(err, result){ - // the result will be equal to 'two' as it finishes earlier -}); -``` - ---------------------------------------- - - - -### memoize(fn, [hasher]) - -Caches the results of an `async` function. When creating a hash to store function -results against, the callback is omitted from the hash and an optional hash -function can be used. - -If no hash function is specified, the first argument is used as a hash key, which may work reasonably if it is a string or a data type that converts to a distinct string. Note that objects and arrays will not behave reasonably. Neither will cases where the other arguments are significant. In such cases, specify your own hash function. - -The cache of results is exposed as the `memo` property of the function returned -by `memoize`. - -__Arguments__ - -* `fn` - The function to proxy and cache results from. -* `hasher` - An optional function for generating a custom hash for storing - results. It has all the arguments applied to it apart from the callback, and - must be synchronous. - -__Example__ - -```js -var slow_fn = function (name, callback) { - // do something - callback(null, result); -}; -var fn = async.memoize(slow_fn); - -// fn can now be used as if it were slow_fn -fn('some name', function () { - // callback -}); -``` - ---------------------------------------- - - - -### unmemoize(fn) - -Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized -form. Handy for testing. - -__Arguments__ - -* `fn` - the memoized function - ---------------------------------------- - - - -### ensureAsync(fn) - -Wrap an async function and ensure it calls its callback on a later tick of the event loop. If the function already calls its callback on a next tick, no extra deferral is added. This is useful for preventing stack overflows (`RangeError: Maximum call stack size exceeded`) and generally keeping [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) contained. - -__Arguments__ - -* `fn` - an async function, one that expects a node-style callback as its last argument - -Returns a wrapped function with the exact same call signature as the function passed in. - -__Example__ - -```js -function sometimesAsync(arg, callback) { - if (cache[arg]) { - return callback(null, cache[arg]); // this would be synchronous!! - } else { - doSomeIO(arg, callback); // this IO would be asynchronous - } -} - -// this has a risk of stack overflows if many results are cached in a row -async.mapSeries(args, sometimesAsync, done); - -// this will defer sometimesAsync's callback if necessary, -// preventing stack overflows -async.mapSeries(args, async.ensureAsync(sometimesAsync), done); - -``` - ---------------------------------------- - - - -### constant(values...) - -Returns a function that when called, calls-back with the values provided. Useful as the first function in a `waterfall`, or for plugging values in to `auto`. - -__Example__ - -```js -async.waterfall([ - async.constant(42), - function (value, next) { - // value === 42 - }, - //... -], callback); - -async.waterfall([ - async.constant(filename, "utf8"), - fs.readFile, - function (fileData, next) { - //... - } - //... -], callback); - -async.auto({ - hostname: async.constant("https://server.net/"), - port: findFreePort, - launchServer: ["hostname", "port", function (options, cb) { - startServer(options, cb); - }], - //... -}, callback); - -``` - ---------------------------------------- - - - - -### asyncify(func) - -__Alias:__ `wrapSync` - -Take a sync function and make it async, passing its return value to a callback. This is useful for plugging sync functions into a waterfall, series, or other async functions. Any arguments passed to the generated function will be passed to the wrapped function (except for the final callback argument). Errors thrown will be passed to the callback. - -__Example__ - -```js -async.waterfall([ - async.apply(fs.readFile, filename, "utf8"), - async.asyncify(JSON.parse), - function (data, next) { - // data is the result of parsing the text. - // If there was a parsing error, it would have been caught. - } -], callback) -``` - -If the function passed to `asyncify` returns a Promise, that promises's resolved/rejected state will be used to call the callback, rather than simply the synchronous return value. Example: - -```js -async.waterfall([ - async.apply(fs.readFile, filename, "utf8"), - async.asyncify(function (contents) { - return db.model.create(contents); - }), - function (model, next) { - // `model` is the instantiated model object. - // If there was an error, this function would be skipped. - } -], callback) -``` - -This also means you can asyncify ES2016 `async` functions. - -```js -var q = async.queue(async.asyncify(async function (file) { - var intermediateStep = await processFile(file); - return await somePromise(intermediateStep) -})); - -q.push(files); -``` - ---------------------------------------- - - - -### log(function, arguments) - -Logs the result of an `async` function to the `console`. Only works in Node.js or -in browsers that support `console.log` and `console.error` (such as FF and Chrome). -If multiple arguments are returned from the async function, `console.log` is -called on each argument in order. - -__Arguments__ - -* `function` - The function you want to eventually apply all arguments to. -* `arguments...` - Any number of arguments to apply to the function. - -__Example__ - -```js -var hello = function(name, callback){ - setTimeout(function(){ - callback(null, 'hello ' + name); - }, 1000); -}; -``` -```js -node> async.log(hello, 'world'); -'hello world' -``` - ---------------------------------------- - - - -### dir(function, arguments) - -Logs the result of an `async` function to the `console` using `console.dir` to -display the properties of the resulting object. Only works in Node.js or -in browsers that support `console.dir` and `console.error` (such as FF and Chrome). -If multiple arguments are returned from the async function, `console.dir` is -called on each argument in order. - -__Arguments__ - -* `function` - The function you want to eventually apply all arguments to. -* `arguments...` - Any number of arguments to apply to the function. - -__Example__ - -```js -var hello = function(name, callback){ - setTimeout(function(){ - callback(null, {hello: name}); - }, 1000); -}; -``` -```js -node> async.dir(hello, 'world'); -{hello: 'world'} -``` - ---------------------------------------- - - - -### noConflict() - -Changes the value of `async` back to its original value, returning a reference to the -`async` object. - ---------------------------------------- - - - -### timeout(function, miliseconds) - -Sets a time limit on an asynchronous function. If the function does not call its callback within the specified miliseconds, it will be called with a timeout error. The code property for the error object will be `'ETIMEDOUT'`. - -Returns a wrapped function that can be used with any of the control flow functions. - -__Arguments__ - -* `function` - The asynchronous function you want to set the time limit. -* `miliseconds` - The specified time limit. -* `info` - *Optional* Any variable you want attached (`string`, `object`, etc) to - timeout Error for more information. - -__Example__ - -```js -async.timeout(function nameOfCallback(callback) { - doAsyncTask(callback); -}, 1000, 'more info about timeout'); -``` - ---------------------------------------- - - -### reflect(function) - -Wraps the function in another function that always returns data even when it errors. -The object returned has either the property `error` or `value`. - -__Arguments__ - -* `function` - The function you want to wrap - -__Example__ - -```js -async.parallel([ - async.reflect(function(callback){ - // do some stuff ... - callback(null, 'one'); - }), - async.reflect(function(callback){ - // do some more stuff but error ... - callback('bad stuff happened'); - }), - async.reflect(function(callback){ - // do some more stuff ... - callback(null, 'two'); - }) -], -// optional callback -function(err, results){ - // values - // results[0].value = 'one' - // results[1].error = 'bad stuff happened' - // results[2].value = 'two' -}); -``` - ---------------------------------------- - - -### reflectAll(tasks) - -A helper function that wraps an array of functions with reflect. - -__Arguments__ - -* `tasks` - The array of functions to wrap in reflect. - -__Example__ - -```javascript -let tasks = [ - function(callback){ - setTimeout(function(){ - callback(null, 'one'); - }, 200); - }, - function(callback){ - // do some more stuff but error ... - callback(new Error('bad stuff happened')); - } - function(callback){ - setTimeout(function(){ - callback(null, 'two'); - }, 100); - } -]; - -async.parallel(async.reflectAll(tasks), -// optional callback -function(err, results){ - // values - // results[0].value = 'one' - // results[1].error = Error('bad stuff happened') - // results[2].value = 'two' -}); -``` diff --git a/lib/cargo.js b/lib/cargo.js index 01329e7..23b6fd8 100644 --- a/lib/cargo.js +++ b/lib/cargo.js @@ -3,7 +3,7 @@ import queue from './internal/queue'; /** * A cargo of tasks for the worker function to complete. Cargo inherits all of * the same methods and event callbacks as {@link async.queue}. - * @typedef {Object} cargo + * @typedef {Object} CargoObject * @property {Function} length - A function returning the number of items * waiting to be processed. Invoke with (). * @property {number} payload - An `integer` for determining how many tasks @@ -52,7 +52,7 @@ import queue from './internal/queue'; * @param {number} [payload=Infinity] - An optional `integer` for determining * how many tasks should be processed per round; if omitted, the default is * unlimited. - * @returns {cargo} A cargo object to manage the tasks. Callbacks can + * @returns {CargoObject} A cargo object to manage the tasks. Callbacks can * attached as certain properties to listen for specific events during the * lifecycle of the cargo and inner queue. * @example diff --git a/lib/index.js b/lib/index.js index 091f657..a8a3ab8 100644 --- a/lib/index.js +++ b/lib/index.js @@ -3,7 +3,7 @@ * for working with asynchronous JavaScript. Although originally designed for * use with [Node.js](http://nodejs.org) and installable via * `npm install --save async`, it can also be used directly in the browser. - * @module async + * @namespace async */ import applyEach from './applyEach'; import applyEachSeries from './applyEachSeries'; diff --git a/lib/queue.js b/lib/queue.js index ac1987a..912b05f 100644 --- a/lib/queue.js +++ b/lib/queue.js @@ -2,7 +2,7 @@ import queue from './internal/queue'; /** * A queue of tasks for the worker function to complete. - * @typedef {Object} queue + * @typedef {Object} QueueObject * @property {Function} length - a function returning the number of items * waiting to be processed. Invoke with (). * @property {Function} started - a function returning whether or not any @@ -64,7 +64,7 @@ import queue from './internal/queue'; * @param {number} [concurrency=1] - An `integer` for determining how many * `worker` functions should be run in parallel. If omitted, the concurrency * defaults to `1`. If the concurrency is `0`, an error is thrown. - * @returns {queue} A queue object to manage the tasks. Callbacks can + * @returns {QueueObject} A queue object to manage the tasks. Callbacks can * attached as certain properties to listen for specific events during the * lifecycle of the queue. * @example diff --git a/package.json b/package.json index d3429f3..1e14cfe 100644 --- a/package.json +++ b/package.json @@ -33,14 +33,15 @@ "chai": "^3.1.0", "coveralls": "^2.11.2", "es6-promise": "^2.3.0", + "esdoc": "^0.4.7", "eslint": "^2.11.1", "fs-extra": "^0.26.7", - "jscs-jsdoc": "^1.3.2", "karma": "^0.13.2", "karma-browserify": "^4.2.1", "karma-firefox-launcher": "^0.1.6", "karma-mocha": "^0.2.0", "karma-mocha-reporter": "^1.0.2", + "minami": "^1.1.1", "mocha": "^2.2.5", "native-promise-only": "^0.8.0-a", "nyc": "^2.1.0", @@ -57,6 +58,7 @@ "scripts": { "coverage": "nyc npm test && nyc report", "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", + "doc": "esdoc -c ./support/esdoc.json", "lint": "eslint lib/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ karma.conf.js", "mocha-browser-test": "karma start", "mocha-node-test": "mocha mocha_test/ --compilers js:babel-core/register", diff --git a/support/esdoc.json b/support/esdoc.json new file mode 100644 index 0000000..215d29a --- /dev/null +++ b/support/esdoc.json @@ -0,0 +1,6 @@ +{ + "source": "./lib", + "destination": "./docs", + "excludes": ["internal"], + "scripts": ["./dist/async.js"] +} -- cgit v1.2.1 From c0b433b4e165fab24b7b95b90d5536c520b7bd87 Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Sun, 19 Jun 2016 13:56:02 -0400 Subject: Update typedef invoke docs --- lib/cargo.js | 14 +++++++------- lib/queue.js | 20 ++++++++++---------- package.json | 1 - 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/lib/cargo.js b/lib/cargo.js index 23b6fd8..4bc5279 100644 --- a/lib/cargo.js +++ b/lib/cargo.js @@ -5,14 +5,14 @@ import queue from './internal/queue'; * the same methods and event callbacks as {@link async.queue}. * @typedef {Object} CargoObject * @property {Function} length - A function returning the number of items - * waiting to be processed. Invoke with (). + * waiting to be processed. Invoke like `cargo.length()`. * @property {number} payload - An `integer` for determining how many tasks * should be process per round. This property can be changed after a `cargo` is * created to alter the payload on-the-fly. * @property {Function} push - Adds `task` to the `queue`. The callback is * called once the `worker` has finished processing the task. Instead of a * single task, an array of `tasks` can be submitted. The respective callback is - * used for every task in the list. Invoke with (task, [callback]). + * used for every task in the list. Invoke like `cargo.push(task, [callback])`. * @property {Function} saturated - A callback that is called when the * `queue.length()` hits the concurrency and further tasks will be queued. * @property {Function} empty - A callback that is called when the last item @@ -20,13 +20,13 @@ import queue from './internal/queue'; * @property {Function} drain - A callback that is called when the last item * from the `queue` has returned from the `worker`. * @property {Function} idle - a function returning false if there are items - * waiting or being processed, or true if not. Invoke with (). + * waiting or being processed, or true if not. Invoke like `cargo.idle()`. * @property {Function} pause - a function that pauses the processing of tasks - * until `resume()` is called. Invoke with (). + * until `resume()` is called. Invoke like `cargo.pause()`. * @property {Function} resume - a function that resumes the processing of - * queued tasks when the queue is paused. Invoke with (). + * queued tasks when the queue is paused. Invoke like `cargo.resume()`. * @property {Function} kill - a function that removes the `drain` callback and - * empties remaining tasks from the queue forcing it to go idle. Invoke with (). + * empties remaining tasks from the queue forcing it to go idle. Invoke like `cargo.kill()`. */ /** @@ -48,7 +48,7 @@ import queue from './internal/queue'; * @category Control Flow * @param {Function} worker - An asynchronous function for processing an array * of queued tasks, which must call its `callback(err)` argument when finished, - * with an optional `err` argument. Invoked with (tasks, callback). + * with an optional `err` argument. Invoked with `(tasks, callback)`. * @param {number} [payload=Infinity] - An optional `integer` for determining * how many tasks should be processed per round; if omitted, the default is * unlimited. diff --git a/lib/queue.js b/lib/queue.js index 912b05f..db1c239 100644 --- a/lib/queue.js +++ b/lib/queue.js @@ -4,24 +4,24 @@ import queue from './internal/queue'; * A queue of tasks for the worker function to complete. * @typedef {Object} QueueObject * @property {Function} length - a function returning the number of items - * waiting to be processed. Invoke with (). + * waiting to be processed. Invoke with `queue.length()`. * @property {Function} started - a function returning whether or not any - * items have been pushed and processed by the queue. Invoke with (). + * items have been pushed and processed by the queue. Invoke with `queue.started()`. * @property {Function} running - a function returning the number of items - * currently being processed. Invoke with (). + * currently being processed. Invoke with `queue.running()`. * @property {Function} workersList - a function returning the array of items - * currently being processed. Invoke with (). + * currently being processed. Invoke with `queue.workersList()`. * @property {Function} idle - a function returning false if there are items - * waiting or being processed, or true if not. Invoke with (). + * waiting or being processed, or true if not. Invoke with `queue.idle()`. * @property {number} concurrency - an integer for determining how many `worker` * functions should be run in parallel. This property can be changed after a * `queue` is created to alter the concurrency on-the-fly. * @property {Function} push - add a new task to the `queue`. Calls `callback` * once the `worker` has finished processing the task. Instead of a single task, * a `tasks` array can be submitted. The respective callback is used for every - * task in the list. Invoke with (task, [callback]), + * task in the list. Invoke with `queue.push(task, [callback])`, * @property {Function} unshift - add a new task to the front of the `queue`. - * Invoke with (task, [callback]). + * Invoke with `queue.unshift(task, [callback])`. * @property {Function} saturated - a callback that is called when the number of * running workers hits the `concurrency` limit, and further tasks will be * queued. @@ -39,11 +39,11 @@ import queue from './internal/queue'; * @property {boolean} paused - a boolean for determining whether the queue is * in a paused state. * @property {Function} pause - a function that pauses the processing of tasks - * until `resume()` is called. Invoke with (). + * until `resume()` is called. Invoke with `queue.pause()`. * @property {Function} resume - a function that resumes the processing of - * queued tasks when the queue is paused. Invoke with (). + * queued tasks when the queue is paused. Invoke with `queue.length()`. * @property {Function} kill - a function that removes the `drain` callback and - * empties remaining tasks from the queue forcing it to go idle. Invoke with (). + * empties remaining tasks from the queue forcing it to go idle. Invoke with `queue.kill()`. */ /** diff --git a/package.json b/package.json index 1e14cfe..3972813 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ "karma-firefox-launcher": "^0.1.6", "karma-mocha": "^0.2.0", "karma-mocha-reporter": "^1.0.2", - "minami": "^1.1.1", "mocha": "^2.2.5", "native-promise-only": "^0.8.0-a", "nyc": "^2.1.0", -- cgit v1.2.1 From 90c4f893a30044b67d48a62e42d2c42f379a822f Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Wed, 29 Jun 2016 01:30:17 -0400 Subject: Initial jsdoc documentation (using minami template) --- lib/apply.js | 3 ++- lib/applyEach.js | 3 ++- lib/applyEachSeries.js | 5 +++-- lib/asyncify.js | 3 ++- lib/auto.js | 3 ++- lib/autoInject.js | 5 +++-- lib/cargo.js | 8 +++++--- lib/compose.js | 3 ++- lib/concat.js | 3 ++- lib/concatSeries.js | 5 +++-- lib/constant.js | 3 ++- lib/detect.js | 3 ++- lib/detectLimit.js | 5 +++-- lib/detectSeries.js | 5 +++-- lib/dir.js | 3 ++- lib/doDuring.js | 5 +++-- lib/doUntil.js | 5 +++-- lib/doWhilst.js | 5 +++-- lib/during.js | 5 +++-- lib/each.js | 3 ++- lib/eachLimit.js | 5 +++-- lib/eachOf.js | 3 ++- lib/eachOfLimit.js | 5 +++-- lib/eachOfSeries.js | 5 +++-- lib/eachSeries.js | 5 +++-- lib/ensureAsync.js | 3 ++- lib/every.js | 3 ++- lib/everyLimit.js | 5 +++-- lib/everySeries.js | 5 +++-- lib/filter.js | 3 ++- lib/filterLimit.js | 5 +++-- lib/filterSeries.js | 5 +++-- lib/forever.js | 3 ++- lib/index.js | 2 +- lib/iterator.js | 3 ++- lib/log.js | 3 ++- lib/map.js | 3 ++- lib/mapLimit.js | 5 +++-- lib/mapSeries.js | 5 +++-- lib/mapValues.js | 3 ++- lib/mapValuesLimit.js | 5 +++-- lib/mapValuesSeries.js | 5 +++-- lib/memoize.js | 3 ++- lib/nextTick.js | 3 ++- lib/parallel.js | 3 ++- lib/parallelLimit.js | 5 +++-- lib/priorityQueue.js | 5 +++-- lib/queue.js | 6 ++++-- lib/race.js | 3 ++- lib/reduce.js | 3 ++- lib/reduceRight.js | 5 +++-- lib/reflect.js | 3 ++- lib/reflectAll.js | 5 +++-- lib/reject.js | 5 +++-- lib/rejectLimit.js | 5 +++-- lib/rejectSeries.js | 5 +++-- lib/retry.js | 3 ++- lib/retryable.js | 5 +++-- lib/seq.js | 5 +++-- lib/series.js | 3 ++- lib/setImmediate.js | 3 ++- lib/some.js | 3 ++- lib/someLimit.js | 5 +++-- lib/someSeries.js | 5 +++-- lib/sortBy.js | 3 ++- lib/timeout.js | 3 ++- lib/times.js | 5 +++-- lib/timesLimit.js | 5 +++-- lib/timesSeries.js | 5 +++-- lib/transform.js | 3 ++- lib/unmemoize.js | 5 +++-- lib/until.js | 5 +++-- lib/waterfall.js | 3 ++- lib/whilst.js | 3 ++- package.json | 4 ++++ support/jsdoc.json | 21 +++++++++++++++++++++ 76 files changed, 214 insertions(+), 114 deletions(-) create mode 100644 support/jsdoc.json diff --git a/lib/apply.js b/lib/apply.js index 1cf7cb3..44f77e4 100644 --- a/lib/apply.js +++ b/lib/apply.js @@ -9,7 +9,8 @@ import rest from 'lodash/rest'; * * @name apply * @static - * @memberOf async + * @memberOf module:async + * @method * @category Util * @param {Function} function - The function you want to eventually apply all * arguments to. Invokes with (arguments...). diff --git a/lib/applyEach.js b/lib/applyEach.js index 3337f57..c84430f 100644 --- a/lib/applyEach.js +++ b/lib/applyEach.js @@ -9,7 +9,8 @@ import map from './map'; * * @name applyEach * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Array|Object} fns - A collection of asynchronous functions to all * call with the same arguments diff --git a/lib/applyEachSeries.js b/lib/applyEachSeries.js index 0a01891..1181d94 100644 --- a/lib/applyEachSeries.js +++ b/lib/applyEachSeries.js @@ -6,8 +6,9 @@ import mapSeries from './mapSeries'; * * @name applyEachSeries * @static - * @memberOf async - * @see async.applyEach + * @memberOf module:async + * @method + * @see [async.applyEach]{@link module:async.applyEach} * @category Control Flow * @param {Array|Object} fns - A collection of asynchronous functions to all * call with the same arguments diff --git a/lib/asyncify.js b/lib/asyncify.js index e3f6f87..f5a19f7 100644 --- a/lib/asyncify.js +++ b/lib/asyncify.js @@ -16,7 +16,8 @@ import initialParams from './internal/initialParams'; * * @name asyncify * @static - * @memberOf async + * @memberOf module:async + * @method * @alias wrapSync * @category Util * @param {Function} func - The synchronous function to convert to an diff --git a/lib/auto.js b/lib/auto.js index bb8ee87..6b5c3d2 100644 --- a/lib/auto.js +++ b/lib/auto.js @@ -26,7 +26,8 @@ import onlyOnce from './internal/onlyOnce'; * * @name auto * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Object} tasks - An object. Each of its properties is either a * function or an array of requirements, with the function itself the last item diff --git a/lib/autoInject.js b/lib/autoInject.js index 40a250d..5805d56 100644 --- a/lib/autoInject.js +++ b/lib/autoInject.js @@ -26,8 +26,9 @@ function parseParams(func) { * * @name autoInject * @static - * @memberOf async - * @see async.auto + * @memberOf module:async + * @method + * @see [async.auto]{@link module:async.applyEach} * @category Control Flow * @param {Object} tasks - An object, each of whose properties is a function of * the form 'func([dependencies...], callback). The object's key of a property diff --git a/lib/cargo.js b/lib/cargo.js index 4bc5279..e17c8f5 100644 --- a/lib/cargo.js +++ b/lib/cargo.js @@ -4,6 +4,7 @@ import queue from './internal/queue'; * A cargo of tasks for the worker function to complete. Cargo inherits all of * the same methods and event callbacks as {@link async.queue}. * @typedef {Object} CargoObject + * @memberOf module:async * @property {Function} length - A function returning the number of items * waiting to be processed. Invoke like `cargo.length()`. * @property {number} payload - An `integer` for determining how many tasks @@ -43,8 +44,9 @@ import queue from './internal/queue'; * * @name cargo * @static - * @memberOf async - * @see async.queue + * @memberOf module:async + * @method + * @see [async.queue]{@link module:async.queue} * @category Control Flow * @param {Function} worker - An asynchronous function for processing an array * of queued tasks, which must call its `callback(err)` argument when finished, @@ -52,7 +54,7 @@ import queue from './internal/queue'; * @param {number} [payload=Infinity] - An optional `integer` for determining * how many tasks should be processed per round; if omitted, the default is * unlimited. - * @returns {CargoObject} A cargo object to manage the tasks. Callbacks can + * @returns {module:async.CargoObject} A cargo object to manage the tasks. Callbacks can * attached as certain properties to listen for specific events during the * lifecycle of the cargo and inner queue. * @example diff --git a/lib/compose.js b/lib/compose.js index 227c2ea..ba22878 100644 --- a/lib/compose.js +++ b/lib/compose.js @@ -12,7 +12,8 @@ var reverse = Array.prototype.reverse; * * @name compose * @static - * @memberOf async + * @memberof module:async + * @method * @category Control Flow * @param {...Function} functions - the asynchronous functions to compose * @returns {Function} an asynchronous function that is the composed diff --git a/lib/concat.js b/lib/concat.js index be7410d..43d519f 100644 --- a/lib/concat.js +++ b/lib/concat.js @@ -10,7 +10,8 @@ import doParallel from './internal/doParallel'; * * @name concat * @static - * @memberOf async + * @memberOf module:async + * @method * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A function to apply to each item in `coll`. diff --git a/lib/concatSeries.js b/lib/concatSeries.js index fef87b7..1272d73 100644 --- a/lib/concatSeries.js +++ b/lib/concatSeries.js @@ -6,8 +6,9 @@ import doSeries from './internal/doSeries'; * * @name concatSeries * @static - * @memberOf async - * @see async.concat + * @memberOf module:async + * @method + * @see [async.concat]{@link module:async.queue} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A function to apply to each item in `coll`. diff --git a/lib/constant.js b/lib/constant.js index a5e32fa..5cfc79c 100644 --- a/lib/constant.js +++ b/lib/constant.js @@ -8,7 +8,8 @@ import initialParams from './internal/initialParams'; * * @name constant * @static - * @memberOf async + * @memberOf module:async + * @method * @category Util * @param {...*} arguments... - Any number of arguments to automatically invoke * callback with. diff --git a/lib/detect.js b/lib/detect.js index a4e246c..1fb4fe5 100644 --- a/lib/detect.js +++ b/lib/detect.js @@ -16,7 +16,8 @@ import findGetResult from './internal/findGetResult'; * * @name detect * @static - * @memberOf async + * @memberOf module:async + * @method * @alias find * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/detectLimit.js b/lib/detectLimit.js index 2e8ba7a..335add4 100644 --- a/lib/detectLimit.js +++ b/lib/detectLimit.js @@ -10,8 +10,9 @@ import findGetResult from './internal/findGetResult'; * * @name detectLimit * @static - * @memberOf async - * @see async.detect + * @memberOf module:async + * @method + * @see [async.detect]{@link module:async.detect} * @alias findLimit * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/detectSeries.js b/lib/detectSeries.js index 59b34a5..798199e 100644 --- a/lib/detectSeries.js +++ b/lib/detectSeries.js @@ -9,8 +9,9 @@ import findGetResult from './internal/findGetResult'; * * @name detectSeries * @static - * @memberOf async - * @see async.detect + * @memberOf module:async + * @method + * @see [async.detect]{@link module:async.detect} * @alias findSeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/dir.js b/lib/dir.js index 8b467af..035e4d2 100644 --- a/lib/dir.js +++ b/lib/dir.js @@ -9,7 +9,8 @@ import consoleFunc from './internal/consoleFunc'; * * @name log * @static - * @memberOf async + * @memberOf module:async + * @method * @category Util * @param {Function} function - The function you want to eventually apply all * arguments to. diff --git a/lib/doDuring.js b/lib/doDuring.js index e018fe4..2a40c05 100644 --- a/lib/doDuring.js +++ b/lib/doDuring.js @@ -7,8 +7,9 @@ import during from './during'; * Also a version of {@link async.doWhilst} with asynchronous `test` function. * @name doDuring * @static - * @memberOf async - * @see async.during + * @memberOf module:async + * @method + * @see [async.during]{@link module:async.during} * @category Control Flow * @param {Function} fn - A function which is called each time `test` passes. * The function is passed a `callback(err)`, which must be called once it has diff --git a/lib/doUntil.js b/lib/doUntil.js index 01f114c..ee9f257 100644 --- a/lib/doUntil.js +++ b/lib/doUntil.js @@ -6,8 +6,9 @@ import doWhilst from './doWhilst'; * * @name doUntil * @static - * @memberOf async - * @see async.doWhilst + * @memberOf module:async + * @method + * @see [async.doWhilst]{@link module:async.doWhilst} * @category Control Flow * @param {Function} fn - A function which is called each time `test` fails. * The function is passed a `callback(err)`, which must be called once it has diff --git a/lib/doWhilst.js b/lib/doWhilst.js index 96c4664..655ede9 100644 --- a/lib/doWhilst.js +++ b/lib/doWhilst.js @@ -8,8 +8,9 @@ import whilst from './whilst'; * * @name doWhilst * @static - * @memberOf async - * @see async.whilst + * @memberOf module:async + * @method + * @see [async.whilst]{@link module:async.whilst} * @category Control Flow * @param {Function} fn - A function which is called each time `test` passes. * The function is passed a `callback(err)`, which must be called once it has diff --git a/lib/during.js b/lib/during.js index 1013bc8..943b3dd 100644 --- a/lib/during.js +++ b/lib/during.js @@ -9,8 +9,9 @@ import rest from 'lodash/rest'; * * @name during * @static - * @memberOf async - * @see async.whilst + * @memberOf module:async + * @method + * @see [async.whilst]{@link module:async.whilst} * @category Control Flow * @param {Function} test - asynchronous truth test to perform before each * execution of `fn`. Invoked with (callback). diff --git a/lib/each.js b/lib/each.js index 90ba3ee..e0a5e1c 100644 --- a/lib/each.js +++ b/lib/each.js @@ -13,7 +13,8 @@ import doLimit from './internal/doLimit'; * * @name each * @static - * @memberOf async + * @memberOf module:async + * @method * @alias forEach * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/eachLimit.js b/lib/eachLimit.js index d5f200c..544157a 100644 --- a/lib/eachLimit.js +++ b/lib/eachLimit.js @@ -6,8 +6,9 @@ import withoutIndex from './internal/withoutIndex'; * * @name eachLimit * @static - * @memberOf async - * @see async.each + * @memberOf module:async + * @method + * @see [async.each]{@link module:async.each} * @alias forEachLimit * @category Collection * @param {Array|Object} coll - A colleciton to iterate over. diff --git a/lib/eachOf.js b/lib/eachOf.js index 1defd47..e621007 100644 --- a/lib/eachOf.js +++ b/lib/eachOf.js @@ -7,7 +7,8 @@ import doLimit from './internal/doLimit'; * * @name eachOf * @static - * @memberOf async + * @memberOf module:async + * @method * @alias forEachOf * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/eachOfLimit.js b/lib/eachOfLimit.js index 5810f8f..767cedd 100644 --- a/lib/eachOfLimit.js +++ b/lib/eachOfLimit.js @@ -6,8 +6,9 @@ import _eachOfLimit from './internal/eachOfLimit'; * * @name eachOfLimit * @static - * @memberOf async - * @see async.eachOf + * @memberOf module:async + * @method + * @see [async.eachOf]{@link module:async.eachOf} * @alias forEachOfLimit * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/eachOfSeries.js b/lib/eachOfSeries.js index dee4838..475ae03 100644 --- a/lib/eachOfSeries.js +++ b/lib/eachOfSeries.js @@ -6,8 +6,9 @@ import doLimit from './internal/doLimit'; * * @name eachOfSeries * @static - * @memberOf async - * @see async.eachOf + * @memberOf module:async + * @method + * @see [async.eachOf]{@link module:async.eachOf} * @alias forEachOfSeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/eachSeries.js b/lib/eachSeries.js index 3d8af62..8a5465a 100644 --- a/lib/eachSeries.js +++ b/lib/eachSeries.js @@ -6,8 +6,9 @@ import doLimit from './internal/doLimit'; * * @name eachSeries * @static - * @memberOf async - * @see async.each + * @memberOf module:async + * @method + * @see [async.each]{@link module:async.each} * @alias forEachSeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/ensureAsync.js b/lib/ensureAsync.js index 55d59fe..bd0b29a 100644 --- a/lib/ensureAsync.js +++ b/lib/ensureAsync.js @@ -11,7 +11,8 @@ import initialParams from './internal/initialParams'; * * @name ensureAsync * @static - * @memberOf async + * @memberOf module:async + * @method * @category Util * @param {Function} fn - an async function, one that expects a node-style * callback as its last argument. diff --git a/lib/every.js b/lib/every.js index a2377ea..c28d6b0 100644 --- a/lib/every.js +++ b/lib/every.js @@ -7,7 +7,8 @@ import doLimit from './internal/doLimit'; * * @name every * @static - * @memberOf async + * @memberOf module:async + * @method * @alias all * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/everyLimit.js b/lib/everyLimit.js index 7d2b042..f06a14d 100644 --- a/lib/everyLimit.js +++ b/lib/everyLimit.js @@ -7,8 +7,9 @@ import notId from './internal/notId'; * * @name everyLimit * @static - * @memberOf async - * @see async.every + * @memberOf module:async + * @method + * @see [async.every]{@link module:async.every} * @alias allLimit * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/everySeries.js b/lib/everySeries.js index 24ee4ed..7b99d6d 100644 --- a/lib/everySeries.js +++ b/lib/everySeries.js @@ -6,8 +6,9 @@ import doLimit from './internal/doLimit'; * * @name everySeries * @static - * @memberOf async - * @see async.every + * @memberOf module:async + * @method + * @see [async.every]{@link module:async.every} * @alias allSeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/filter.js b/lib/filter.js index 7f48ae1..9dce1be 100644 --- a/lib/filter.js +++ b/lib/filter.js @@ -8,7 +8,8 @@ import doLimit from './internal/doLimit'; * * @name filter * @static - * @memberOf async + * @memberOf module:async + * @method * @alias select * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/filterLimit.js b/lib/filterLimit.js index 615b170..7504608 100644 --- a/lib/filterLimit.js +++ b/lib/filterLimit.js @@ -7,8 +7,9 @@ import doParallelLimit from './internal/doParallelLimit'; * * @name filterLimit * @static - * @memberOf async - * @see async.filter + * @memberOf module:async + * @method + * @see [async.filter]{@link module:async.filter} * @alias selectLimit * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/filterSeries.js b/lib/filterSeries.js index 6fde694..a170ce6 100644 --- a/lib/filterSeries.js +++ b/lib/filterSeries.js @@ -6,8 +6,9 @@ import doLimit from './internal/doLimit'; * * @name filterSeries * @static - * @memberOf async - * @see async.filter + * @memberOf module:async + * @method + * @see [async.filter]{@link module:async.filter} * @alias selectSeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/forever.js b/lib/forever.js index 4708d21..44eb19c 100644 --- a/lib/forever.js +++ b/lib/forever.js @@ -13,7 +13,8 @@ import ensureAsync from './ensureAsync'; * * @name forever * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Function} fn - a function to call repeatedly. Invoked with (next). * @param {Function} [errback] - when `fn` passes an error to it's callback, diff --git a/lib/index.js b/lib/index.js index a8a3ab8..091f657 100644 --- a/lib/index.js +++ b/lib/index.js @@ -3,7 +3,7 @@ * for working with asynchronous JavaScript. Although originally designed for * use with [Node.js](http://nodejs.org) and installable via * `npm install --save async`, it can also be used directly in the browser. - * @namespace async + * @module async */ import applyEach from './applyEach'; import applyEachSeries from './applyEachSeries'; diff --git a/lib/iterator.js b/lib/iterator.js index b37c18a..49206ff 100644 --- a/lib/iterator.js +++ b/lib/iterator.js @@ -8,7 +8,8 @@ * * @name iterator * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Array} tasks - An array of functions to run. * @returns The next function to run in the series. diff --git a/lib/log.js b/lib/log.js index b18733e..4386450 100644 --- a/lib/log.js +++ b/lib/log.js @@ -8,7 +8,8 @@ import consoleFunc from './internal/consoleFunc'; * * @name log * @static - * @memberOf async + * @memberOf module:async + * @method * @category Util * @param {Function} function - The function you want to eventually apply all * arguments to. diff --git a/lib/map.js b/lib/map.js index 19642c8..96c1e80 100644 --- a/lib/map.js +++ b/lib/map.js @@ -20,7 +20,8 @@ import doLimit from './internal/doLimit'; * * @name map * @static - * @memberOf async + * @memberOf module:async + * @method * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A function to apply to each item in `coll`. diff --git a/lib/mapLimit.js b/lib/mapLimit.js index 0cf049b..b773d58 100644 --- a/lib/mapLimit.js +++ b/lib/mapLimit.js @@ -6,8 +6,9 @@ import map from './internal/map'; * * @name mapLimit * @static - * @memberOf async - * @see async.map + * @memberOf module:async + * @method + * @see [async.map]{@link module:async.map} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. diff --git a/lib/mapSeries.js b/lib/mapSeries.js index c241bef..abbeb0a 100644 --- a/lib/mapSeries.js +++ b/lib/mapSeries.js @@ -6,8 +6,9 @@ import doLimit from './internal/doLimit'; * * @name mapSeries * @static - * @memberOf async - * @see async.map + * @memberOf module:async + * @method + * @see [async.map]{@link module:async.map} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A function to apply to each item in `coll`. diff --git a/lib/mapValues.js b/lib/mapValues.js index 83ffc43..a1f7967 100644 --- a/lib/mapValues.js +++ b/lib/mapValues.js @@ -17,7 +17,8 @@ import doLimit from './internal/doLimit'; * * @name mapValues * @static - * @memberOf async + * @memberOf module:async + * @method * @category Collection * @param {Object} obj - A collection to iterate over. * @param {Function} iteratee - A function to apply to each value and key in diff --git a/lib/mapValuesLimit.js b/lib/mapValuesLimit.js index 762b871..9d2333c 100644 --- a/lib/mapValuesLimit.js +++ b/lib/mapValuesLimit.js @@ -6,8 +6,9 @@ import eachOfLimit from './eachOfLimit'; * * @name mapValuesLimit * @static - * @memberOf async - * @see async.mapValues + * @memberOf module:async + * @method + * @see [async.mapValues]{@link module:async.mapValues} * @category Collection * @param {Object} obj - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. diff --git a/lib/mapValuesSeries.js b/lib/mapValuesSeries.js index 163d474..35f1c95 100644 --- a/lib/mapValuesSeries.js +++ b/lib/mapValuesSeries.js @@ -6,8 +6,9 @@ import doLimit from './internal/doLimit'; * * @name mapValuesSeries * @static - * @memberOf async - * @see async.mapValues + * @memberOf module:async + * @method + * @see [async.mapValues]{@link module:async.mapValues} * @category Collection * @param {Object} obj - A collection to iterate over. * @param {Function} iteratee - A function to apply to each value in `obj`. diff --git a/lib/memoize.js b/lib/memoize.js index 5b06cff..7cb22c2 100644 --- a/lib/memoize.js +++ b/lib/memoize.js @@ -24,7 +24,8 @@ function has(obj, key) { * * @name memoize * @static - * @memberOf async + * @memberOf module:async + * @method * @category Util * @param {Function} fn - The function to proxy and cache results from. * @param {Function} hasher - An optional function for generating a custom hash diff --git a/lib/nextTick.js b/lib/nextTick.js index 9a1d6a0..f6c9fca 100644 --- a/lib/nextTick.js +++ b/lib/nextTick.js @@ -12,7 +12,8 @@ import { hasNextTick, hasSetImmediate, fallback, wrap } from './internal/setImm * * @name nextTick * @static - * @memberOf async + * @memberOf module:async + * @method * @alias setImmediate * @category Util * @param {Function} callback - The function to call on a later loop around diff --git a/lib/parallel.js b/lib/parallel.js index 5a01b5f..e61e337 100644 --- a/lib/parallel.js +++ b/lib/parallel.js @@ -21,7 +21,8 @@ import doLimit from './internal/doLimit'; * * @name parallel * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Array|Object} tasks - A collection containing functions to run. * Each function is passed a `callback(err, result)` which it must call on diff --git a/lib/parallelLimit.js b/lib/parallelLimit.js index 2eb8b2f..d313bb8 100644 --- a/lib/parallelLimit.js +++ b/lib/parallelLimit.js @@ -7,8 +7,9 @@ import parallel from './internal/parallel'; * * @name parallel * @static - * @memberOf async - * @see async.parallel + * @memberOf module:async + * @method + * @see [async.parallel]{@link module:async.parallel} * @category Control Flow * @param {Array|Collection} tasks - A collection containing functions to run. * Each function is passed a `callback(err, result)` which it must call on diff --git a/lib/priorityQueue.js b/lib/priorityQueue.js index 36cacaf..6fa02ce 100644 --- a/lib/priorityQueue.js +++ b/lib/priorityQueue.js @@ -12,8 +12,9 @@ import queue from './queue'; * * @name priorityQueue * @static - * @memberOf async - * @see async.queue + * @memberOf module:async + * @method + * @see [async.queue]{@link module:async.queue} * @category Control Flow * @param {Function} worker - An asynchronous function for processing a queued * task, which must call its `callback(err)` argument when finished, with an diff --git a/lib/queue.js b/lib/queue.js index db1c239..799cc97 100644 --- a/lib/queue.js +++ b/lib/queue.js @@ -3,6 +3,7 @@ import queue from './internal/queue'; /** * A queue of tasks for the worker function to complete. * @typedef {Object} QueueObject + * @memberOf module:async * @property {Function} length - a function returning the number of items * waiting to be processed. Invoke with `queue.length()`. * @property {Function} started - a function returning whether or not any @@ -54,7 +55,8 @@ import queue from './internal/queue'; * * @name queue * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Function} worker - An asynchronous function for processing a queued * task, which must call its `callback(err)` argument when finished, with an @@ -64,7 +66,7 @@ import queue from './internal/queue'; * @param {number} [concurrency=1] - An `integer` for determining how many * `worker` functions should be run in parallel. If omitted, the concurrency * defaults to `1`. If the concurrency is `0`, an error is thrown. - * @returns {QueueObject} A queue object to manage the tasks. Callbacks can + * @returns {module:async.QueueObject} A queue object to manage the tasks. Callbacks can * attached as certain properties to listen for specific events during the * lifecycle of the queue. * @example diff --git a/lib/race.js b/lib/race.js index 2b8ad39..d656701 100644 --- a/lib/race.js +++ b/lib/race.js @@ -11,7 +11,8 @@ import once from './internal/once'; * * @name race * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Array} tasks - An array containing functions to run. Each function * is passed a `callback(err, result)` which it must call on completion with an diff --git a/lib/reduce.js b/lib/reduce.js index 8f529a0..7754f33 100644 --- a/lib/reduce.js +++ b/lib/reduce.js @@ -13,7 +13,8 @@ import eachOfSeries from './eachOfSeries'; * * @name reduce * @static - * @memberOf async + * @memberOf module:async + * @method * @alias inject * @alias foldl * @category Collection diff --git a/lib/reduceRight.js b/lib/reduceRight.js index fda0505..d1ffa55 100644 --- a/lib/reduceRight.js +++ b/lib/reduceRight.js @@ -7,8 +7,9 @@ var slice = Array.prototype.slice; * * @name reduceRight * @static - * @memberOf async - * @see async.reduce + * @memberOf module:async + * @method + * @see [async.reduce]{@link module:async.reduce} * @alias foldr * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/reflect.js b/lib/reflect.js index 63adefb..e650461 100644 --- a/lib/reflect.js +++ b/lib/reflect.js @@ -9,7 +9,8 @@ import rest from 'lodash/rest'; * * @name reflect * @static - * @memberOf async + * @memberOf module:async + * @method * @category Util * @param {Function} fn - The function you want to wrap * @returns {Function} - A function that always passes null to it's callback as diff --git a/lib/reflectAll.js b/lib/reflectAll.js index ac9ea06..6167e6c 100644 --- a/lib/reflectAll.js +++ b/lib/reflectAll.js @@ -5,8 +5,9 @@ import reflect from './reflect'; * * @name reflectAll * @static - * @memberOf async - * @see async.reflect + * @memberOf module:async + * @method + * @see [async.reflect]{@link module:async.reflect} * @category Util * @param {Array} tasks - The array of functions to wrap in `async.reflect`. * @returns {Array} Returns an array of functions, each function wrapped in diff --git a/lib/reject.js b/lib/reject.js index f4c7a45..fb7ad9d 100644 --- a/lib/reject.js +++ b/lib/reject.js @@ -6,8 +6,9 @@ import doLimit from './internal/doLimit'; * * @name reject * @static - * @memberOf async - * @see async.filter + * @memberOf module:async + * @method + * @see [async.filter]{@link module:async.filter} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A truth test to apply to each item in `coll`. diff --git a/lib/rejectLimit.js b/lib/rejectLimit.js index a8e2082..5942428 100644 --- a/lib/rejectLimit.js +++ b/lib/rejectLimit.js @@ -7,8 +7,9 @@ import doParallelLimit from './internal/doParallelLimit'; * * @name rejectLimit * @static - * @memberOf async - * @see async.reject + * @memberOf module:async + * @method + * @see [async.reject]{@link module:async.reject} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. diff --git a/lib/rejectSeries.js b/lib/rejectSeries.js index 8fc7a41..6a3016a 100644 --- a/lib/rejectSeries.js +++ b/lib/rejectSeries.js @@ -6,8 +6,9 @@ import doLimit from './internal/doLimit'; * * @name rejectSeries * @static - * @memberOf async - * @see async.reject + * @memberOf module:async + * @method + * @see [async.reject]{@link module:async.reject} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A truth test to apply to each item in `coll`. diff --git a/lib/retry.js b/lib/retry.js index 69c3eb3..6a98b99 100644 --- a/lib/retry.js +++ b/lib/retry.js @@ -10,7 +10,8 @@ import constant from 'lodash/constant'; * * @name retry * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an * object with `times` and `interval` or a number. diff --git a/lib/retryable.js b/lib/retryable.js index b9c0fbb..45ef5ac 100644 --- a/lib/retryable.js +++ b/lib/retryable.js @@ -7,8 +7,9 @@ import initialParams from './internal/initialParams'; * * @name retryable * @static - * @memberOf async - * @see async.retry + * @memberOf module:async + * @method + * @see [async.retry]{@link module:async.retry} * @category Control Flow * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional * options, exactly the same as from `retry` diff --git a/lib/seq.js b/lib/seq.js index 4b3e49c..3048beb 100644 --- a/lib/seq.js +++ b/lib/seq.js @@ -11,8 +11,9 @@ import reduce from './reduce'; * * @name seq * @static - * @memberOf async - * @see async.compose + * @memberOf module:async + * @method + * @see [async.compose]{@link module:async.compose} * @category Control Flow * @param {...Function} functions - the asynchronous functions to compose * @returns {Function} a function that composes the `functions` in order diff --git a/lib/series.js b/lib/series.js index 3345519..713c839 100644 --- a/lib/series.js +++ b/lib/series.js @@ -24,7 +24,8 @@ import eachOfSeries from './eachOfSeries'; * * @name series * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Array|Object} tasks - A collection containing functions to run, each * function is passed a `callback(err, result)` it must call on completion with diff --git a/lib/setImmediate.js b/lib/setImmediate.js index 68f94d7..7485b40 100644 --- a/lib/setImmediate.js +++ b/lib/setImmediate.js @@ -10,7 +10,8 @@ import setImmediate from './internal/setImmediate'; * * @name setImmediate * @static - * @memberOf async + * @memberOf module:async + * @method * @alias nextTick * @category Util * @param {Function} callback - The function to call on a later loop around diff --git a/lib/some.js b/lib/some.js index 4f4e2b1..13ef62f 100644 --- a/lib/some.js +++ b/lib/some.js @@ -8,7 +8,8 @@ import doLimit from './internal/doLimit'; * * @name some * @static - * @memberOf async + * @memberOf module:async + * @method * @alias any * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/someLimit.js b/lib/someLimit.js index 50beb65..b9d5cc5 100644 --- a/lib/someLimit.js +++ b/lib/someLimit.js @@ -7,8 +7,9 @@ import identity from 'lodash/identity'; * * @name someLimit * @static - * @memberOf async - * @see async.some + * @memberOf module:async + * @method + * @see [async.some]{@link module:async.some} * @alias anyLimit * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/someSeries.js b/lib/someSeries.js index 18fd5ca..fa3e0e3 100644 --- a/lib/someSeries.js +++ b/lib/someSeries.js @@ -6,8 +6,9 @@ import doLimit from './internal/doLimit'; * * @name someSeries * @static - * @memberOf async - * @see async.some + * @memberOf module:async + * @method + * @see [async.some]{@link module:async.some} * @alias anySeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/sortBy.js b/lib/sortBy.js index 539a829..8d8fd0d 100644 --- a/lib/sortBy.js +++ b/lib/sortBy.js @@ -9,7 +9,8 @@ import map from './map'; * * @name sortBy * @static - * @memberOf async + * @memberOf module:async + * @method * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A function to apply to each item in `coll`. diff --git a/lib/timeout.js b/lib/timeout.js index 1ce5378..f5974ff 100644 --- a/lib/timeout.js +++ b/lib/timeout.js @@ -7,7 +7,8 @@ import initialParams from './internal/initialParams'; * * @name timeout * @static - * @memberOf async + * @memberOf module:async + * @method * @category Util * @param {Function} asyncFn - The asynchronous function you want to set the * time limit. diff --git a/lib/times.js b/lib/times.js index 1d5b6c3..62843c6 100644 --- a/lib/times.js +++ b/lib/times.js @@ -7,8 +7,9 @@ import doLimit from './internal/doLimit'; * * @name times * @static - * @memberOf async - * @see async.map + * @memberOf module:async + * @method + * @see [async.map]{@link module:async.map} * @category Control Flow * @param {number} n - The number of times to run the function. * @param {Function} iteratee - The function to call `n` times. Invoked with the diff --git a/lib/timesLimit.js b/lib/timesLimit.js index b4db62c..302c803 100644 --- a/lib/timesLimit.js +++ b/lib/timesLimit.js @@ -7,8 +7,9 @@ import range from 'lodash/_baseRange'; * * @name timesLimit * @static - * @memberOf async - * @see async.times + * @memberOf module:async + * @method + * @see [async.times]{@link module:async.times} * @category Control Flow * @param {number} count - The number of times to run the function. * @param {number} limit - The maximum number of async operations at a time. diff --git a/lib/timesSeries.js b/lib/timesSeries.js index 28a5434..2a46a73 100644 --- a/lib/timesSeries.js +++ b/lib/timesSeries.js @@ -6,8 +6,9 @@ import doLimit from './internal/doLimit'; * * @name timesSeries * @static - * @memberOf async - * @see async.times + * @memberOf module:async + * @method + * @see [async.times]{@link module:async.times} * @category Control Flow * @param {number} n - The number of times to run the function. * @param {Function} iteratee - The function to call `n` times. Invoked with the diff --git a/lib/transform.js b/lib/transform.js index 55fd067..4025fd7 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -9,7 +9,8 @@ import eachOf from './eachOf'; * * @name transform * @static - * @memberOf async + * @memberOf module:async + * @method * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {*} [accumulator] - The initial state of the transform. If omitted, diff --git a/lib/unmemoize.js b/lib/unmemoize.js index e7d9765..e8537d9 100644 --- a/lib/unmemoize.js +++ b/lib/unmemoize.js @@ -4,8 +4,9 @@ * * @name unmemoize * @static - * @memberOf async - * @see async.memoize + * @memberOf module:async + * @method + * @see [async.memoize]{@link module:async.memoize} * @category Util * @param {Function} fn - the memoized function * @returns {Function} a function that calls the original unmemoized function diff --git a/lib/until.js b/lib/until.js index 910e049..0b5fde8 100644 --- a/lib/until.js +++ b/lib/until.js @@ -9,8 +9,9 @@ import whilst from './whilst'; * * @name until * @static - * @memberOf async - * @see async.whilst + * @memberOf module:async + * @method + * @see [async.whilst]{@link module:async.whilst} * @category Control Flow * @param {Function} test - synchronous truth test to perform before each * execution of `fn`. Invoked with (). diff --git a/lib/waterfall.js b/lib/waterfall.js index 9478bd9..cd75b91 100644 --- a/lib/waterfall.js +++ b/lib/waterfall.js @@ -13,7 +13,8 @@ import onlyOnce from './internal/onlyOnce'; * * @name waterfall * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Array} tasks - An array of functions to run, each function is passed * a `callback(err, result1, result2, ...)` it must call on completion. The diff --git a/lib/whilst.js b/lib/whilst.js index ee1c19a..d6e6591 100644 --- a/lib/whilst.js +++ b/lib/whilst.js @@ -7,7 +7,8 @@ import rest from 'lodash/rest'; * * @name whilst * @static - * @memberOf async + * @memberOf module:async + * @method * @category Control Flow * @param {Function} test - synchronous truth test to perform before each * execution of `fn`. Invoked with (). diff --git a/package.json b/package.json index 3972813..c386f5b 100644 --- a/package.json +++ b/package.json @@ -36,11 +36,14 @@ "esdoc": "^0.4.7", "eslint": "^2.11.1", "fs-extra": "^0.26.7", + "ink-docstrap": "^1.2.1", + "jsdoc": "^3.4.0", "karma": "^0.13.2", "karma-browserify": "^4.2.1", "karma-firefox-launcher": "^0.1.6", "karma-mocha": "^0.2.0", "karma-mocha-reporter": "^1.0.2", + "minami": "^1.1.1", "mocha": "^2.2.5", "native-promise-only": "^0.8.0-a", "nyc": "^2.1.0", @@ -58,6 +61,7 @@ "coverage": "nyc npm test && nyc report", "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", "doc": "esdoc -c ./support/esdoc.json", + "jsdocs": "jsdoc -c ./support/jsdoc.json", "lint": "eslint lib/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ karma.conf.js", "mocha-browser-test": "karma start", "mocha-node-test": "mocha mocha_test/ --compilers js:babel-core/register", diff --git a/support/jsdoc.json b/support/jsdoc.json new file mode 100644 index 0000000..ac95082 --- /dev/null +++ b/support/jsdoc.json @@ -0,0 +1,21 @@ +{ + "tags": { + "allowUnknownTags": true, + "dictionaries": ["jsdoc"] + }, + "source": { + "include": [ "./lib" ] + }, + "plugins": ["plugins/markdown"], + "opts": { + "readme": "README.md", + "template": "node_modules/minami", + "encoding": "utf8", + "destination": "./docs", + "recurse": true + }, + "templates": { + "cleverLinks": false, + "theme": "cerulean" + } +} -- cgit v1.2.1 From 7eaa3b3a9bee0df38ebc0b640a97de42ca05d5da Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Wed, 29 Jun 2016 01:35:29 -0400 Subject: jsdocs: using proxy modules as categories, modifying minami theme jsdocs: style fix in outputted html jsdoc: added documentation to support script --- lib/apply.js | 5 +- lib/applyEach.js | 5 +- lib/applyEachSeries.js | 9 ++- lib/asyncify.js | 5 +- lib/auto.js | 5 +- lib/autoInject.js | 11 +-- lib/cargo.js | 15 +++-- lib/compose.js | 5 +- lib/concat.js | 5 +- lib/concatSeries.js | 9 ++- lib/constant.js | 9 ++- lib/detect.js | 9 ++- lib/detectLimit.js | 11 +-- lib/detectSeries.js | 11 +-- lib/dir.js | 7 +- lib/doDuring.js | 11 +-- lib/doUntil.js | 9 ++- lib/doWhilst.js | 9 ++- lib/during.js | 9 ++- lib/each.js | 5 +- lib/eachLimit.js | 9 ++- lib/eachOf.js | 8 ++- lib/eachOfLimit.js | 9 ++- lib/eachOfSeries.js | 9 ++- lib/eachSeries.js | 9 ++- lib/ensureAsync.js | 5 +- lib/every.js | 5 +- lib/everyLimit.js | 9 ++- lib/everySeries.js | 9 ++- lib/filter.js | 5 +- lib/filterLimit.js | 9 ++- lib/filterSeries.js | 9 ++- lib/forever.js | 5 +- lib/index.js | 16 +++++ lib/iterator.js | 5 +- lib/log.js | 5 +- lib/map.js | 5 +- lib/mapLimit.js | 9 ++- lib/mapSeries.js | 9 ++- lib/mapValues.js | 7 +- lib/mapValuesLimit.js | 9 ++- lib/mapValuesSeries.js | 9 ++- lib/memoize.js | 5 +- lib/nextTick.js | 5 +- lib/parallel.js | 5 +- lib/parallelLimit.js | 11 +-- lib/priorityQueue.js | 11 +-- lib/queue.js | 9 ++- lib/race.js | 5 +- lib/reduce.js | 5 +- lib/reduceRight.js | 9 ++- lib/reflect.js | 5 +- lib/reflectAll.js | 7 +- lib/reject.js | 9 ++- lib/rejectLimit.js | 9 ++- lib/rejectSeries.js | 9 ++- lib/retry.js | 5 +- lib/retryable.js | 9 ++- lib/seq.js | 9 ++- lib/series.js | 5 +- lib/setImmediate.js | 5 +- lib/some.js | 5 +- lib/someLimit.js | 9 ++- lib/someSeries.js | 9 ++- lib/sortBy.js | 5 +- lib/timeout.js | 5 +- lib/times.js | 11 +-- lib/timesLimit.js | 13 ++-- lib/timesSeries.js | 11 +-- lib/transform.js | 5 +- lib/unmemoize.js | 9 ++- lib/until.js | 9 ++- lib/waterfall.js | 5 +- lib/whilst.js | 5 +- package.json | 3 +- support/fix-jsdoc-html.js | 166 ++++++++++++++++++++++++++++++++++++++++++++++ support/jsdoc.json | 3 +- 77 files changed, 575 insertions(+), 173 deletions(-) create mode 100644 support/fix-jsdoc-html.js diff --git a/lib/apply.js b/lib/apply.js index 44f77e4..8c43e34 100644 --- a/lib/apply.js +++ b/lib/apply.js @@ -1,6 +1,9 @@ import rest from 'lodash/rest'; /** + * ``` + * import apply from 'async/apply' + * ``` * Creates a continuation function with some arguments already applied. * * Useful as a shorthand when combined with other control flow functions. Any @@ -9,7 +12,7 @@ import rest from 'lodash/rest'; * * @name apply * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @category Util * @param {Function} function - The function you want to eventually apply all diff --git a/lib/applyEach.js b/lib/applyEach.js index c84430f..656014c 100644 --- a/lib/applyEach.js +++ b/lib/applyEach.js @@ -2,6 +2,9 @@ import applyEach from './internal/applyEach'; import map from './map'; /** + * ``` + * import applyEach from 'async/applyEach' + * ``` * Applies the provided arguments to each function in the array, calling * `callback` after all functions have completed. If you only provide the first * argument, then it will return a function which lets you pass in the @@ -9,7 +12,7 @@ import map from './map'; * * @name applyEach * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array|Object} fns - A collection of asynchronous functions to all diff --git a/lib/applyEachSeries.js b/lib/applyEachSeries.js index 1181d94..892e355 100644 --- a/lib/applyEachSeries.js +++ b/lib/applyEachSeries.js @@ -2,13 +2,16 @@ import applyEach from './internal/applyEach'; import mapSeries from './mapSeries'; /** - * The same as `applyEach` but runs only a single async operation at a time. + * ``` + * import applyEachSeries from 'async/applyEachSeries' + * ``` + * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time. * * @name applyEachSeries * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.applyEach]{@link module:async.applyEach} + * @see [async.applyEach]{@link module:ControlFlow.applyEach} * @category Control Flow * @param {Array|Object} fns - A collection of asynchronous functions to all * call with the same arguments diff --git a/lib/asyncify.js b/lib/asyncify.js index f5a19f7..9baa238 100644 --- a/lib/asyncify.js +++ b/lib/asyncify.js @@ -2,6 +2,9 @@ import isObject from 'lodash/isObject'; import initialParams from './internal/initialParams'; /** + * ``` + * import asyncify from 'async/asyncify' + * ``` * Take a sync function and make it async, passing its return value to a * callback. This is useful for plugging sync functions into a waterfall, * series, or other async functions. Any arguments passed to the generated @@ -16,7 +19,7 @@ import initialParams from './internal/initialParams'; * * @name asyncify * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @alias wrapSync * @category Util diff --git a/lib/auto.js b/lib/auto.js index 6b5c3d2..c6f291c 100644 --- a/lib/auto.js +++ b/lib/auto.js @@ -10,6 +10,9 @@ import rest from 'lodash/rest'; import onlyOnce from './internal/onlyOnce'; /** + * ``` + * import auto from 'async/auto' + * ``` * Determines the best order for running the functions in `tasks`, based on * their requirements. Each function can optionally depend on other functions * being completed first, and each function is run as soon as its requirements @@ -26,7 +29,7 @@ import onlyOnce from './internal/onlyOnce'; * * @name auto * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Object} tasks - An object. Each of its properties is either a diff --git a/lib/autoInject.js b/lib/autoInject.js index 5805d56..fc6399c 100644 --- a/lib/autoInject.js +++ b/lib/autoInject.js @@ -12,7 +12,10 @@ function parseParams(func) { } /** - * A dependency-injected version of the {@link async.auto} function. Dependent + * ``` + * import autoInject from 'async/autoInject' + * ``` + * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent * tasks are specified as parameters to the function, after the usual callback * parameter, with the parameter names matching the names of the tasks it * depends on. This can provide even more readable task graphs which can be @@ -22,13 +25,13 @@ function parseParams(func) { * specified as named parameters after the initial error parameter. * * The autoInject function is purely syntactic sugar and its semantics are - * otherwise equivalent to {@link async.auto}. + * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}. * * @name autoInject * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.auto]{@link module:async.applyEach} + * @see [async.auto]{@link module:ControlFlow.auto} * @category Control Flow * @param {Object} tasks - An object, each of whose properties is a function of * the form 'func([dependencies...], callback). The object's key of a property diff --git a/lib/cargo.js b/lib/cargo.js index e17c8f5..9bdc613 100644 --- a/lib/cargo.js +++ b/lib/cargo.js @@ -2,9 +2,9 @@ import queue from './internal/queue'; /** * A cargo of tasks for the worker function to complete. Cargo inherits all of - * the same methods and event callbacks as {@link async.queue}. + * the same methods and event callbacks as [`queue`]{@link module:ControlFlow.queue}. * @typedef {Object} CargoObject - * @memberOf module:async + * @memberOf module:ControlFlow * @property {Function} length - A function returning the number of items * waiting to be processed. Invoke like `cargo.length()`. * @property {number} payload - An `integer` for determining how many tasks @@ -31,6 +31,9 @@ import queue from './internal/queue'; */ /** + * ``` + * import cargo from 'async/cargo' + * ``` * Creates a `cargo` object with the specified payload. Tasks added to the * cargo will be processed altogether (up to the `payload` limit). If the * `worker` is in progress, the task is queued until it becomes available. Once @@ -38,15 +41,15 @@ import queue from './internal/queue'; * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) * for how `cargo` and `queue` work. * - * While [queue](#queue) passes only one task to one of a group of workers + * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers * at a time, cargo passes an array of tasks to a single worker, repeating * when the worker is finished. * * @name cargo * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.queue]{@link module:async.queue} + * @see [async.queue]{@link module:ControlFlow.queue} * @category Control Flow * @param {Function} worker - An asynchronous function for processing an array * of queued tasks, which must call its `callback(err)` argument when finished, @@ -54,7 +57,7 @@ import queue from './internal/queue'; * @param {number} [payload=Infinity] - An optional `integer` for determining * how many tasks should be processed per round; if omitted, the default is * unlimited. - * @returns {module:async.CargoObject} A cargo object to manage the tasks. Callbacks can + * @returns {module:ControlFlow.CargoObject} A cargo object to manage the tasks. Callbacks can * attached as certain properties to listen for specific events during the * lifecycle of the cargo and inner queue. * @example diff --git a/lib/compose.js b/lib/compose.js index ba22878..0f87239 100644 --- a/lib/compose.js +++ b/lib/compose.js @@ -3,6 +3,9 @@ import seq from './seq'; var reverse = Array.prototype.reverse; /** + * ``` + * import compose from 'async/compose' + * ``` * Creates a function which is a composition of the passed asynchronous * functions. Each function consumes the return value of the function that * follows. Composing functions `f()`, `g()`, and `h()` would produce the result @@ -12,7 +15,7 @@ var reverse = Array.prototype.reverse; * * @name compose * @static - * @memberof module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {...Function} functions - the asynchronous functions to compose diff --git a/lib/concat.js b/lib/concat.js index 43d519f..05043c3 100644 --- a/lib/concat.js +++ b/lib/concat.js @@ -2,6 +2,9 @@ import concat from './internal/concat'; import doParallel from './internal/doParallel'; /** + * ``` + * import concat from 'async/concat' + * ``` * Applies `iteratee` to each item in `coll`, concatenating the results. Returns * the concatenated list. The `iteratee`s are called in parallel, and the * results are concatenated as they return. There is no guarantee that the @@ -10,7 +13,7 @@ import doParallel from './internal/doParallel'; * * @name concat * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/concatSeries.js b/lib/concatSeries.js index 1272d73..374d8ee 100644 --- a/lib/concatSeries.js +++ b/lib/concatSeries.js @@ -2,13 +2,16 @@ import concat from './internal/concat'; import doSeries from './internal/doSeries'; /** - * The same as `concat` but runs only a single async operation at a time. + * ``` + * import concatSeries from 'async/concatSeries' + * ``` + * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time. * * @name concatSeries * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.concat]{@link module:async.queue} + * @see [async.concat]{@link module:Collections.concat} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A function to apply to each item in `coll`. diff --git a/lib/constant.js b/lib/constant.js index 5cfc79c..5c325a1 100644 --- a/lib/constant.js +++ b/lib/constant.js @@ -2,13 +2,16 @@ import rest from 'lodash/rest'; import initialParams from './internal/initialParams'; /** + * ``` + * import constant from 'async/constant' + * ``` * Returns a function that when called, calls-back with the values provided. - * Useful as the first function in a `waterfall`, or for plugging values in to - * `auto`. + * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to + * [`auto`]{@link module:ControlFlow.auto}. * * @name constant * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @category Util * @param {...*} arguments... - Any number of arguments to automatically invoke diff --git a/lib/detect.js b/lib/detect.js index 1fb4fe5..606ebe2 100644 --- a/lib/detect.js +++ b/lib/detect.js @@ -5,6 +5,9 @@ import eachOf from './eachOf'; import findGetResult from './internal/findGetResult'; /** + * ``` + * import detect from 'async/detect' + * ``` * Returns the first value in `coll` that passes an async truth test. The * `iteratee` is applied in parallel, meaning the first iteratee to return * `true` will fire the detect `callback` with that result. That means the @@ -12,14 +15,14 @@ import findGetResult from './internal/findGetResult'; * that passes the test. * If order within the original `coll` is important, then look at - * `detectSeries`. + * [`detectSeries`]{@link module:Collections.detectSeries}. * * @name detect * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @alias find - * @category Collection + * @category Collections * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A truth test to apply to each item in `coll`. * The iteratee is passed a `callback(err, truthValue)` which must be called diff --git a/lib/detectLimit.js b/lib/detectLimit.js index 335add4..6911fb9 100644 --- a/lib/detectLimit.js +++ b/lib/detectLimit.js @@ -5,16 +5,19 @@ import eachOfLimit from './eachOfLimit'; import findGetResult from './internal/findGetResult'; /** - * The same as `detect` but runs a maximum of `limit` async operations at a + * ``` + * import detectLimit from 'async/detectLimit' + * ``` + * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a * time. * * @name detectLimit * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.detect]{@link module:async.detect} + * @see [async.detect]{@link module:Collections.detect} * @alias findLimit - * @category Collection + * @category Collections * @param {Array|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. * @param {Function} iteratee - A truth test to apply to each item in `coll`. diff --git a/lib/detectSeries.js b/lib/detectSeries.js index 798199e..ac2f41c 100644 --- a/lib/detectSeries.js +++ b/lib/detectSeries.js @@ -5,15 +5,18 @@ import eachOfSeries from './eachOfSeries'; import findGetResult from './internal/findGetResult'; /** - * The same as `detect` but runs only a single async operation at a time. + * ``` + * import detectSeries from 'async/detectSeries' + * ``` + * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time. * * @name detectSeries * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.detect]{@link module:async.detect} + * @see [async.detect]{@link module:Collections.detect} * @alias findSeries - * @category Collection + * @category Collections * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A truth test to apply to each item in `coll`. * The iteratee is passed a `callback(err, truthValue)` which must be called diff --git a/lib/dir.js b/lib/dir.js index 035e4d2..52ca709 100644 --- a/lib/dir.js +++ b/lib/dir.js @@ -1,15 +1,18 @@ import consoleFunc from './internal/consoleFunc'; /** + * ``` + * import dir from 'async/dir' + * ``` * Logs the result of an `async` function to the `console` using `console.dir` * to display the properties of the resulting object. Only works in Node.js or * in browsers that support `console.dir` and `console.error` (such as FF and * Chrome). If multiple arguments are returned from the async function, * `console.dir` is called on each argument in order. * - * @name log + * @name dir * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @category Util * @param {Function} function - The function you want to eventually apply all diff --git a/lib/doDuring.js b/lib/doDuring.js index 2a40c05..7df8f60 100644 --- a/lib/doDuring.js +++ b/lib/doDuring.js @@ -1,15 +1,18 @@ import during from './during'; /** - * The post-check version of {@link async.during}. To reflect the difference in + * ``` + * import doDuring from 'async/doDuring' + * ``` + * The post-check version of [`during`]{@link module:ControlFlow.during}. To reflect the difference in * the order of operations, the arguments `test` and `fn` are switched. * - * Also a version of {@link async.doWhilst} with asynchronous `test` function. + * Also a version of [`doWhilst`]{@link module:ControlFlow.doWhilst} with asynchronous `test` function. * @name doDuring * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.during]{@link module:async.during} + * @see [async.during]{@link module:ControlFlow.during} * @category Control Flow * @param {Function} fn - A function which is called each time `test` passes. * The function is passed a `callback(err)`, which must be called once it has diff --git a/lib/doUntil.js b/lib/doUntil.js index ee9f257..68fb4a1 100644 --- a/lib/doUntil.js +++ b/lib/doUntil.js @@ -1,14 +1,17 @@ import doWhilst from './doWhilst'; /** - * Like {@link async.doWhilst}, except the `test` is inverted. Note the + * ``` + * import doUtil from 'async/doUtil' + * ``` + * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the * argument ordering differs from `until`. * * @name doUntil * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.doWhilst]{@link module:async.doWhilst} + * @see [async.doWhilst]{@link module:ControlFlow.doWhilst} * @category Control Flow * @param {Function} fn - A function which is called each time `test` fails. * The function is passed a `callback(err)`, which must be called once it has diff --git a/lib/doWhilst.js b/lib/doWhilst.js index 655ede9..344339d 100644 --- a/lib/doWhilst.js +++ b/lib/doWhilst.js @@ -1,16 +1,19 @@ import whilst from './whilst'; /** - * The post-check version of {@link async.whilst}. To reflect the difference in + * ``` + * import doWhilst from 'async/doWhilst' + * ``` + * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in * the order of operations, the arguments `test` and `fn` are switched. * * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. * * @name doWhilst * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.whilst]{@link module:async.whilst} + * @see [async.whilst]{@link module:ControlFlow.whilst} * @category Control Flow * @param {Function} fn - A function which is called each time `test` passes. * The function is passed a `callback(err)`, which must be called once it has diff --git a/lib/during.js b/lib/during.js index 943b3dd..e6016bb 100644 --- a/lib/during.js +++ b/lib/during.js @@ -2,16 +2,19 @@ import noop from 'lodash/noop'; import rest from 'lodash/rest'; /** - * Like {@link async.whilst}, except the `test` is an asynchronous function that + * ``` + * import during from 'async/during' + * ``` + * Like [`whilst`]{@link module:ControlFlow.whilst}, except the `test` is an asynchronous function that * is passed a callback in the form of `function (err, truth)`. If error is * passed to `test` or `fn`, the main callback is immediately called with the * value of the error. * * @name during * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.whilst]{@link module:async.whilst} + * @see [async.whilst]{@link module:ControlFlow.whilst} * @category Control Flow * @param {Function} test - asynchronous truth test to perform before each * execution of `fn`. Invoked with (callback). diff --git a/lib/each.js b/lib/each.js index e0a5e1c..eb8f242 100644 --- a/lib/each.js +++ b/lib/each.js @@ -2,6 +2,9 @@ import eachLimit from './eachLimit'; import doLimit from './internal/doLimit'; /** + * ``` + * import each from 'async/each' + * ``` * Applies the function `iteratee` to each item in `coll`, in parallel. * The `iteratee` is called with an item from the list, and a callback for when * it has finished. If the `iteratee` passes an error to its `callback`, the @@ -13,7 +16,7 @@ import doLimit from './internal/doLimit'; * * @name each * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @alias forEach * @category Collection diff --git a/lib/eachLimit.js b/lib/eachLimit.js index 544157a..6a263aa 100644 --- a/lib/eachLimit.js +++ b/lib/eachLimit.js @@ -2,13 +2,16 @@ import eachOfLimit from './internal/eachOfLimit'; import withoutIndex from './internal/withoutIndex'; /** - * The same as `each` but runs a maximum of `limit` async operations at a time. + * ``` + * import eachLimit from 'async/eachLimit' + * ``` + * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time. * * @name eachLimit * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.each]{@link module:async.each} + * @see [async.each]{@link module:Collections.each} * @alias forEachLimit * @category Collection * @param {Array|Object} coll - A colleciton to iterate over. diff --git a/lib/eachOf.js b/lib/eachOf.js index e621007..d8f46f7 100644 --- a/lib/eachOf.js +++ b/lib/eachOf.js @@ -2,15 +2,19 @@ import eachOfLimit from './eachOfLimit'; import doLimit from './internal/doLimit'; /** - * Like `each`, except that it passes the key (or index) as the second argument + * ``` + * import eachOf from 'async/eachOf' + * ``` + * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument * to the iteratee. * * @name eachOf * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @alias forEachOf * @category Collection + * @see [async.each]{@link module:Collections.each} * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A function to apply to each * item in `coll`. The `key` is the item's key, or index in the case of an diff --git a/lib/eachOfLimit.js b/lib/eachOfLimit.js index 767cedd..e81d590 100644 --- a/lib/eachOfLimit.js +++ b/lib/eachOfLimit.js @@ -1,14 +1,17 @@ import _eachOfLimit from './internal/eachOfLimit'; /** - * The same as `eachOf` but runs a maximum of `limit` async operations at a + * ``` + * import eachOfLimit from 'async/eachOfLimit' + * ``` + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a * time. * * @name eachOfLimit * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.eachOf]{@link module:async.eachOf} + * @see [async.eachOf]{@link module:Collections.eachOf} * @alias forEachOfLimit * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/eachOfSeries.js b/lib/eachOfSeries.js index 475ae03..103d088 100644 --- a/lib/eachOfSeries.js +++ b/lib/eachOfSeries.js @@ -2,13 +2,16 @@ import eachOfLimit from './eachOfLimit'; import doLimit from './internal/doLimit'; /** - * The same as `eachOf` but runs only a single async operation at a time. + * ``` + * import eachOfSeries from 'async/eachOfSeries' + * ``` + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time. * * @name eachOfSeries * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.eachOf]{@link module:async.eachOf} + * @see [async.eachOf]{@link module:Collections.eachOf} * @alias forEachOfSeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/eachSeries.js b/lib/eachSeries.js index 8a5465a..87fabfb 100644 --- a/lib/eachSeries.js +++ b/lib/eachSeries.js @@ -2,13 +2,16 @@ import eachLimit from './eachLimit'; import doLimit from './internal/doLimit'; /** - * The same as `each` but runs only a single async operation at a time. + * ``` + * import eachSeries from 'async/eachSeries' + * ``` + * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time. * * @name eachSeries * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.each]{@link module:async.each} + * @see [async.each]{@link module:Collections.each} * @alias forEachSeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/ensureAsync.js b/lib/ensureAsync.js index bd0b29a..6ef698e 100644 --- a/lib/ensureAsync.js +++ b/lib/ensureAsync.js @@ -2,6 +2,9 @@ import setImmediate from './internal/setImmediate'; import initialParams from './internal/initialParams'; /** + * ``` + * import ensureAsync from 'async/ensureAsync' + * ``` * Wrap an async function and ensure it calls its callback on a later tick of * the event loop. If the function already calls its callback on a next tick, * no extra deferral is added. This is useful for preventing stack overflows @@ -11,7 +14,7 @@ import initialParams from './internal/initialParams'; * * @name ensureAsync * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @category Util * @param {Function} fn - an async function, one that expects a node-style diff --git a/lib/every.js b/lib/every.js index c28d6b0..6355218 100644 --- a/lib/every.js +++ b/lib/every.js @@ -2,12 +2,15 @@ import everyLimit from './everyLimit'; import doLimit from './internal/doLimit'; /** + * ``` + * import every from 'async/every' + * ``` * Returns `true` if every element in `coll` satisfies an async test. If any * iteratee call returns `false`, the main `callback` is immediately called. * * @name every * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @alias all * @category Collection diff --git a/lib/everyLimit.js b/lib/everyLimit.js index f06a14d..a8cd65a 100644 --- a/lib/everyLimit.js +++ b/lib/everyLimit.js @@ -3,13 +3,16 @@ import eachOfLimit from './eachOfLimit'; import notId from './internal/notId'; /** - * The same as `every` but runs a maximum of `limit` async operations at a time. + * ``` + * import everyLimit from 'async/everyLimit' + * ``` + * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time. * * @name everyLimit * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.every]{@link module:async.every} + * @see [async.every]{@link module:Collections.every} * @alias allLimit * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/everySeries.js b/lib/everySeries.js index 7b99d6d..4333584 100644 --- a/lib/everySeries.js +++ b/lib/everySeries.js @@ -2,13 +2,16 @@ import everyLimit from './everyLimit'; import doLimit from './internal/doLimit'; /** - * The same as `every` but runs only a single async operation at a time. + * ``` + * import everySeries from 'async/everySeries' + * ``` + * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time. * * @name everySeries * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.every]{@link module:async.every} + * @see [async.every]{@link module:Collections.every} * @alias allSeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/filter.js b/lib/filter.js index 9dce1be..b576df2 100644 --- a/lib/filter.js +++ b/lib/filter.js @@ -2,13 +2,16 @@ import filterLimit from './filterLimit'; import doLimit from './internal/doLimit'; /** + * ``` + * import filter from 'async/filter' + * ``` * Returns a new array of all the values in `coll` which pass an async truth * test. This operation is performed in parallel, but the results array will be * in the same order as the original. * * @name filter * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @alias select * @category Collection diff --git a/lib/filterLimit.js b/lib/filterLimit.js index 7504608..d9a43c8 100644 --- a/lib/filterLimit.js +++ b/lib/filterLimit.js @@ -2,14 +2,17 @@ import filter from './internal/filter'; import doParallelLimit from './internal/doParallelLimit'; /** - * The same as `filter` but runs a maximum of `limit` async operations at a + * ``` + * import filterLimit from 'async/filterLimit' + * ``` + * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a * time. * * @name filterLimit * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.filter]{@link module:async.filter} + * @see [async.filter]{@link module:Collections.filter} * @alias selectLimit * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/filterSeries.js b/lib/filterSeries.js index a170ce6..1afa9b2 100644 --- a/lib/filterSeries.js +++ b/lib/filterSeries.js @@ -2,13 +2,16 @@ import filterLimit from './filterLimit'; import doLimit from './internal/doLimit'; /** - * The same as `filter` but runs only a single async operation at a time. + * ``` + * import filterSeries from 'async/filterSeries' + * ``` + * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time. * * @name filterSeries * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.filter]{@link module:async.filter} + * @see [async.filter]{@link module:Collections.filter} * @alias selectSeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/forever.js b/lib/forever.js index 44eb19c..7f060ca 100644 --- a/lib/forever.js +++ b/lib/forever.js @@ -4,6 +4,9 @@ import onlyOnce from './internal/onlyOnce'; import ensureAsync from './ensureAsync'; /** + * ``` + * import forever from 'async/forever' + * ``` * Calls the asynchronous function `fn` with a callback parameter that allows it * to call itself again, in series, indefinitely. @@ -13,7 +16,7 @@ import ensureAsync from './ensureAsync'; * * @name forever * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Function} fn - a function to call repeatedly. Invoked with (next). diff --git a/lib/index.js b/lib/index.js index 091f657..28b87d6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -5,6 +5,22 @@ * `npm install --save async`, it can also be used directly in the browser. * @module async */ + +/** + * A collection of `async` functions for manipulating collections, such as + * arrays and objects. + * @module Collections + */ + +/** + * A collection of `async` functions for controlling the flow through a script. + * @module ControlFlow + */ + + /** + * A collection of `async` utility functions. + * @module Utils + */ import applyEach from './applyEach'; import applyEachSeries from './applyEachSeries'; import apply from './apply'; diff --git a/lib/iterator.js b/lib/iterator.js index 49206ff..1d67145 100644 --- a/lib/iterator.js +++ b/lib/iterator.js @@ -1,4 +1,7 @@ /** + * ``` + * import iterator from 'async/iterator' + * ``` * Creates an iterator function which calls the next function in the `tasks` * array, returning a continuation to call the next one after that. It's also * possible to “peek” at the next iterator with `iterator.next()`. @@ -8,7 +11,7 @@ * * @name iterator * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array} tasks - An array of functions to run. diff --git a/lib/log.js b/lib/log.js index 4386450..240bba1 100644 --- a/lib/log.js +++ b/lib/log.js @@ -1,6 +1,9 @@ import consoleFunc from './internal/consoleFunc'; /** + * ``` + * import log from 'async/log' + * ``` * Logs the result of an `async` function to the `console`. Only works in * Node.js or in browsers that support `console.log` and `console.error` (such * as FF and Chrome). If multiple arguments are returned from the async @@ -8,7 +11,7 @@ import consoleFunc from './internal/consoleFunc'; * * @name log * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @category Util * @param {Function} function - The function you want to eventually apply all diff --git a/lib/map.js b/lib/map.js index 96c1e80..59bb682 100644 --- a/lib/map.js +++ b/lib/map.js @@ -2,6 +2,9 @@ import mapLimit from './mapLimit'; import doLimit from './internal/doLimit'; /** + * ``` + * import map from 'async/map' + * ``` * Produces a new collection of values by mapping each value in `coll` through * the `iteratee` function. The `iteratee` is called with an item from `coll` * and a callback for when it has finished processing. Each of these callback @@ -20,7 +23,7 @@ import doLimit from './internal/doLimit'; * * @name map * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/mapLimit.js b/lib/mapLimit.js index b773d58..1d3d3b2 100644 --- a/lib/mapLimit.js +++ b/lib/mapLimit.js @@ -2,13 +2,16 @@ import doParallelLimit from './internal/doParallelLimit'; import map from './internal/map'; /** - * The same as `map` but runs a maximum of `limit` async operations at a time. + * ``` + * import mapLimit from 'async/mapLimit' + * ``` + * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time. * * @name mapLimit * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.map]{@link module:async.map} + * @see [async.map]{@link module:Collections.map} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. diff --git a/lib/mapSeries.js b/lib/mapSeries.js index abbeb0a..5e39065 100644 --- a/lib/mapSeries.js +++ b/lib/mapSeries.js @@ -2,13 +2,16 @@ import mapLimit from './mapLimit'; import doLimit from './internal/doLimit'; /** - * The same as `map` but runs only a single async operation at a time. + * ``` + * import mapSeries from 'async/mapSeries' + * ``` + * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time. * * @name mapSeries * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.map]{@link module:async.map} + * @see [async.map]{@link module:Collections.map} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A function to apply to each item in `coll`. diff --git a/lib/mapValues.js b/lib/mapValues.js index a1f7967..1f19e3e 100644 --- a/lib/mapValues.js +++ b/lib/mapValues.js @@ -3,7 +3,10 @@ import doLimit from './internal/doLimit'; /** - * A relative of `map`, designed for use with objects. + * ``` + * import mapValues from 'async/mapValues' + * ``` + * A relative of [`map`]{@link module:Collections.map}, designed for use with objects. * * Produces a new Object by mapping each value of `obj` through the `iteratee` * function. The `iteratee` is called each `value` and `key` from `obj` and a @@ -17,7 +20,7 @@ import doLimit from './internal/doLimit'; * * @name mapValues * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @category Collection * @param {Object} obj - A collection to iterate over. diff --git a/lib/mapValuesLimit.js b/lib/mapValuesLimit.js index 9d2333c..0f3584a 100644 --- a/lib/mapValuesLimit.js +++ b/lib/mapValuesLimit.js @@ -1,14 +1,17 @@ import eachOfLimit from './eachOfLimit'; /** - * The same as `mapValues` but runs a maximum of `limit` async operations at a + * ``` + * import mapValuesLimit from 'async/mapValuesLimit' + * ``` + * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a * time. * * @name mapValuesLimit * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.mapValues]{@link module:async.mapValues} + * @see [async.mapValues]{@link module:Collections.mapValues} * @category Collection * @param {Object} obj - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. diff --git a/lib/mapValuesSeries.js b/lib/mapValuesSeries.js index 35f1c95..e9746a1 100644 --- a/lib/mapValuesSeries.js +++ b/lib/mapValuesSeries.js @@ -2,13 +2,16 @@ import mapValuesLimit from './mapValuesLimit'; import doLimit from './internal/doLimit'; /** - * The same as `mapValues` but runs only a single async operation at a time. + * ``` + * import mapValuesSeries from 'async/mapValuesSeries' + * ``` + * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time. * * @name mapValuesSeries * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.mapValues]{@link module:async.mapValues} + * @see [async.mapValues]{@link module:Collections.mapValues} * @category Collection * @param {Object} obj - A collection to iterate over. * @param {Function} iteratee - A function to apply to each value in `obj`. diff --git a/lib/memoize.js b/lib/memoize.js index 7cb22c2..3e2ee32 100644 --- a/lib/memoize.js +++ b/lib/memoize.js @@ -9,6 +9,9 @@ function has(obj, key) { } /** + * ``` + * import memoize from 'async/memoize' + * ``` * Caches the results of an `async` function. When creating a hash to store * function results against, the callback is omitted from the hash and an * optional hash function can be used. @@ -24,7 +27,7 @@ function has(obj, key) { * * @name memoize * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @category Util * @param {Function} fn - The function to proxy and cache results from. diff --git a/lib/nextTick.js b/lib/nextTick.js index f6c9fca..1959c84 100644 --- a/lib/nextTick.js +++ b/lib/nextTick.js @@ -3,6 +3,9 @@ import { hasNextTick, hasSetImmediate, fallback, wrap } from './internal/setImmediate'; /** + * ``` + * import nextTick from 'async/nextTick' + * ``` * Calls `callback` on a later loop around the event loop. In Node.js this just * calls `setImmediate`. In the browser it will use `setImmediate` if * available, otherwise `setTimeout(callback, 0)`, which means other higher @@ -12,7 +15,7 @@ import { hasNextTick, hasSetImmediate, fallback, wrap } from './internal/setImm * * @name nextTick * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @alias setImmediate * @category Util diff --git a/lib/parallel.js b/lib/parallel.js index e61e337..9df6bd6 100644 --- a/lib/parallel.js +++ b/lib/parallel.js @@ -2,6 +2,9 @@ import parallelLimit from './parallelLimit'; import doLimit from './internal/doLimit'; /** + * ``` + * import parallel from 'async/parallel' + * ``` * Run the `tasks` collection of functions in parallel, without waiting until * the previous function has completed. If any of the functions pass an error to * its callback, the main `callback` is immediately called with the value of the @@ -21,7 +24,7 @@ import doLimit from './internal/doLimit'; * * @name parallel * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array|Object} tasks - A collection containing functions to run. diff --git a/lib/parallelLimit.js b/lib/parallelLimit.js index d313bb8..7057bd0 100644 --- a/lib/parallelLimit.js +++ b/lib/parallelLimit.js @@ -2,14 +2,17 @@ import eachOfLimit from './internal/eachOfLimit'; import parallel from './internal/parallel'; /** - * The same as `parallel` but runs a maximum of `limit` async operations at a + * ``` + * import parallelLimit from 'async/parallelLimit' + * ``` + * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a * time. * - * @name parallel + * @name parallelLimit * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.parallel]{@link module:async.parallel} + * @see [async.parallel]{@link module:ControlFlow.parallel} * @category Control Flow * @param {Array|Collection} tasks - A collection containing functions to run. * Each function is passed a `callback(err, result)` which it must call on diff --git a/lib/priorityQueue.js b/lib/priorityQueue.js index 6fa02ce..4162311 100644 --- a/lib/priorityQueue.js +++ b/lib/priorityQueue.js @@ -7,14 +7,17 @@ import setImmediate from './setImmediate'; import queue from './queue'; /** - * The same as {@link async.queue} only tasks are assigned a priority and + * ``` + * import priorityQueue from 'async/priorityQueue' + * ``` + * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and * completed in ascending priority order. * * @name priorityQueue * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.queue]{@link module:async.queue} + * @see [async.queue]{@link module:ControlFlow.queue} * @category Control Flow * @param {Function} worker - An asynchronous function for processing a queued * task, which must call its `callback(err)` argument when finished, with an @@ -24,7 +27,7 @@ import queue from './queue'; * @param {number} concurrency - An `integer` for determining how many `worker` * functions should be run in parallel. If omitted, the concurrency defaults to * `1`. If the concurrency is `0`, an error is thrown. - * @returns {queue} A priorityQueue object to manage the tasks. There are two + * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two * differences between `queue` and `priorityQueue` objects: * * `push(task, priority, [callback])` - `priority` should be a number. If an * array of `tasks` is given, all tasks will be assigned the same priority. diff --git a/lib/queue.js b/lib/queue.js index 799cc97..5f032d7 100644 --- a/lib/queue.js +++ b/lib/queue.js @@ -3,7 +3,7 @@ import queue from './internal/queue'; /** * A queue of tasks for the worker function to complete. * @typedef {Object} QueueObject - * @memberOf module:async + * @memberOf module:ControlFlow * @property {Function} length - a function returning the number of items * waiting to be processed. Invoke with `queue.length()`. * @property {Function} started - a function returning whether or not any @@ -48,6 +48,9 @@ import queue from './internal/queue'; */ /** + * ``` + * import queue from 'async/queue' + * ``` * Creates a `queue` object with the specified `concurrency`. Tasks added to the * `queue` are processed in parallel (up to the `concurrency` limit). If all * `worker`s are in progress, the task is queued until one becomes available. @@ -55,7 +58,7 @@ import queue from './internal/queue'; * * @name queue * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Function} worker - An asynchronous function for processing a queued @@ -66,7 +69,7 @@ import queue from './internal/queue'; * @param {number} [concurrency=1] - An `integer` for determining how many * `worker` functions should be run in parallel. If omitted, the concurrency * defaults to `1`. If the concurrency is `0`, an error is thrown. - * @returns {module:async.QueueObject} A queue object to manage the tasks. Callbacks can + * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can * attached as certain properties to listen for specific events during the * lifecycle of the queue. * @example diff --git a/lib/race.js b/lib/race.js index d656701..8efece4 100644 --- a/lib/race.js +++ b/lib/race.js @@ -4,6 +4,9 @@ import noop from 'lodash/noop'; import once from './internal/once'; /** + * ``` + * import race from 'async/race' + * ``` * Runs the `tasks` array of functions in parallel, without waiting until the * previous function has completed. Once any the `tasks` completed or pass an * error to its callback, the main `callback` is immediately called. It's @@ -11,7 +14,7 @@ import once from './internal/once'; * * @name race * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array} tasks - An array containing functions to run. Each function diff --git a/lib/reduce.js b/lib/reduce.js index 7754f33..d870c9d 100644 --- a/lib/reduce.js +++ b/lib/reduce.js @@ -1,6 +1,9 @@ import eachOfSeries from './eachOfSeries'; /** + * ``` + * import reduce from 'async/reduce' + * ``` * Reduces `coll` into a single value using an async `iteratee` to return each * successive step. `memo` is the initial state of the reduction. This function * only operates in series. @@ -13,7 +16,7 @@ import eachOfSeries from './eachOfSeries'; * * @name reduce * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @alias inject * @alias foldl diff --git a/lib/reduceRight.js b/lib/reduceRight.js index d1ffa55..b3090d9 100644 --- a/lib/reduceRight.js +++ b/lib/reduceRight.js @@ -3,13 +3,16 @@ import reduce from './reduce'; var slice = Array.prototype.slice; /** - * Same as `reduce`, only operates on `coll` in reverse order. + * ``` + * import reduceRight from 'async/reduceRight' + * ``` + * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `coll` in reverse order. * * @name reduceRight * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.reduce]{@link module:async.reduce} + * @see [async.reduce]{@link module:Collections.reduce} * @alias foldr * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/reflect.js b/lib/reflect.js index e650461..a8b7438 100644 --- a/lib/reflect.js +++ b/lib/reflect.js @@ -2,6 +2,9 @@ import initialParams from './internal/initialParams'; import rest from 'lodash/rest'; /** + * ``` + * import reflect from 'async/reflect' + * ``` * Wraps the function in another function that always returns data even when it * errors. * @@ -9,7 +12,7 @@ import rest from 'lodash/rest'; * * @name reflect * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @category Util * @param {Function} fn - The function you want to wrap diff --git a/lib/reflectAll.js b/lib/reflectAll.js index 6167e6c..160334c 100644 --- a/lib/reflectAll.js +++ b/lib/reflectAll.js @@ -1,13 +1,16 @@ import reflect from './reflect'; /** + * ``` + * import reflectAll from 'async/reflectAll' + * ``` * A helper function that wraps an array of functions with reflect. * * @name reflectAll * @static - * @memberOf module:async + * @memberOf module:Utils * @method - * @see [async.reflect]{@link module:async.reflect} + * @see [async.reflect]{@link module:Utils.reflect} * @category Util * @param {Array} tasks - The array of functions to wrap in `async.reflect`. * @returns {Array} Returns an array of functions, each function wrapped in diff --git a/lib/reject.js b/lib/reject.js index fb7ad9d..dd54453 100644 --- a/lib/reject.js +++ b/lib/reject.js @@ -2,13 +2,16 @@ import rejectLimit from './rejectLimit'; import doLimit from './internal/doLimit'; /** - * The opposite of `filter`. Removes values that pass an `async` truth test. + * ``` + * import reject from 'async/reject' + * ``` + * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test. * * @name reject * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.filter]{@link module:async.filter} + * @see [async.filter]{@link module:Collections.filter} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A truth test to apply to each item in `coll`. diff --git a/lib/rejectLimit.js b/lib/rejectLimit.js index 5942428..78c2def 100644 --- a/lib/rejectLimit.js +++ b/lib/rejectLimit.js @@ -2,14 +2,17 @@ import reject from './internal/reject'; import doParallelLimit from './internal/doParallelLimit'; /** - * The same as `reject` but runs a maximum of `limit` async operations at a + * ``` + * import rejectLimit from 'async/rejectLimit' + * ``` + * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a * time. * * @name rejectLimit * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.reject]{@link module:async.reject} + * @see [async.reject]{@link module:Collections.reject} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {number} limit - The maximum number of async operations at a time. diff --git a/lib/rejectSeries.js b/lib/rejectSeries.js index 6a3016a..a691536 100644 --- a/lib/rejectSeries.js +++ b/lib/rejectSeries.js @@ -2,13 +2,16 @@ import rejectLimit from './rejectLimit'; import doLimit from './internal/doLimit'; /** - * The same as `reject` but runs only a single async operation at a time. + * ``` + * import rejectSeries from 'async/rejectSeries' + * ``` + * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time. * * @name rejectSeries * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.reject]{@link module:async.reject} + * @see [async.reject]{@link module:Collections.reject} * @category Collection * @param {Array|Object} coll - A collection to iterate over. * @param {Function} iteratee - A truth test to apply to each item in `coll`. diff --git a/lib/retry.js b/lib/retry.js index 6a98b99..b137a0d 100644 --- a/lib/retry.js +++ b/lib/retry.js @@ -3,6 +3,9 @@ import noop from 'lodash/noop'; import constant from 'lodash/constant'; /** + * ``` + * import retry from 'async/retry' + * ``` * Attempts to get a successful response from `task` no more than `times` times * before returning an error. If the task is successful, the `callback` will be * passed the result of the successful task. If all attempts fail, the callback @@ -10,7 +13,7 @@ import constant from 'lodash/constant'; * * @name retry * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an diff --git a/lib/retryable.js b/lib/retryable.js index 45ef5ac..ad47351 100644 --- a/lib/retryable.js +++ b/lib/retryable.js @@ -2,14 +2,17 @@ import retry from './retry'; import initialParams from './internal/initialParams'; /** - * A close relative of `retry`. This method wraps a task and makes it + * ``` + * import retryable from 'async/retryable' + * ``` + * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method wraps a task and makes it * retryable, rather than immediately calling it with retries. * * @name retryable * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.retry]{@link module:async.retry} + * @see [async.retry]{@link module:ControlFlow.retry} * @category Control Flow * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional * options, exactly the same as from `retry` diff --git a/lib/seq.js b/lib/seq.js index 3048beb..5f4e74e 100644 --- a/lib/seq.js +++ b/lib/seq.js @@ -3,17 +3,20 @@ import rest from 'lodash/rest'; import reduce from './reduce'; /** + * ``` + * import seq from 'async/seq' + * ``` * Version of the compose function that is more natural to read. Each function * consumes the return value of the previous function. It is the equivalent of - * {@link async.compose} with the arguments reversed. + * [compose]{@link module:ControlFlow.compose} with the arguments reversed. * * Each function is executed with the `this` binding of the composed function. * * @name seq * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.compose]{@link module:async.compose} + * @see [async.compose]{@link module:ControlFlow.compose} * @category Control Flow * @param {...Function} functions - the asynchronous functions to compose * @returns {Function} a function that composes the `functions` in order diff --git a/lib/series.js b/lib/series.js index 713c839..1877e81 100644 --- a/lib/series.js +++ b/lib/series.js @@ -2,6 +2,9 @@ import parallel from './internal/parallel'; import eachOfSeries from './eachOfSeries'; /** + * ``` + * import series from 'async/series' + * ``` * Run the functions in the `tasks` collection in series, each one running once * the previous function has completed. If any functions in the series pass an * error to its callback, no more functions are run, and `callback` is @@ -24,7 +27,7 @@ import eachOfSeries from './eachOfSeries'; * * @name series * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array|Object} tasks - A collection containing functions to run, each diff --git a/lib/setImmediate.js b/lib/setImmediate.js index 7485b40..1b545a5 100644 --- a/lib/setImmediate.js +++ b/lib/setImmediate.js @@ -1,6 +1,9 @@ import setImmediate from './internal/setImmediate'; /** + * ``` + * import setImmediate from 'async/setImmediate' + * ``` * Calls `callback` on a later loop around the event loop. In Node.js this just * calls `setImmediate`. In the browser it will use `setImmediate` if * available, otherwise `setTimeout(callback, 0)`, which means other higher @@ -10,7 +13,7 @@ import setImmediate from './internal/setImmediate'; * * @name setImmediate * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @alias nextTick * @category Util diff --git a/lib/some.js b/lib/some.js index 13ef62f..83bed71 100644 --- a/lib/some.js +++ b/lib/some.js @@ -2,13 +2,16 @@ import someLimit from './someLimit'; import doLimit from './internal/doLimit'; /** + * ``` + * import some from 'async/some' + * ``` * Returns `true` if at least one element in the `coll` satisfies an async test. * If any iteratee call returns `true`, the main `callback` is immediately * called. * * @name some * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @alias any * @category Collection diff --git a/lib/someLimit.js b/lib/someLimit.js index b9d5cc5..b3920f1 100644 --- a/lib/someLimit.js +++ b/lib/someLimit.js @@ -3,13 +3,16 @@ import eachOfLimit from './eachOfLimit'; import identity from 'lodash/identity'; /** - * The same as `some` but runs a maximum of `limit` async operations at a time. + * ``` + * import someLimit from 'async/someLimit' + * ``` + * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time. * * @name someLimit * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.some]{@link module:async.some} + * @see [async.some]{@link module:Collections.some} * @alias anyLimit * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/someSeries.js b/lib/someSeries.js index fa3e0e3..feec58f 100644 --- a/lib/someSeries.js +++ b/lib/someSeries.js @@ -2,13 +2,16 @@ import someLimit from './someLimit'; import doLimit from './internal/doLimit'; /** - * The same as `some` but runs only a single async operation at a time. + * ``` + * import someSeries from 'async/someSeries' + * ``` + * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time. * * @name someSeries * @static - * @memberOf module:async + * @memberOf module:Collections * @method - * @see [async.some]{@link module:async.some} + * @see [async.some]{@link module:Collections.some} * @alias anySeries * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/sortBy.js b/lib/sortBy.js index 8d8fd0d..f96b1ab 100644 --- a/lib/sortBy.js +++ b/lib/sortBy.js @@ -4,12 +4,15 @@ import property from 'lodash/_baseProperty'; import map from './map'; /** + * ``` + * import sortBy from 'async/sortBy' + * ``` * Sorts a list by the results of running each `coll` value through an async * `iteratee`. * * @name sortBy * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/timeout.js b/lib/timeout.js index f5974ff..f2643ac 100644 --- a/lib/timeout.js +++ b/lib/timeout.js @@ -1,13 +1,16 @@ import initialParams from './internal/initialParams'; /** + * ``` + * import timeout from 'async/timeout' + * ``` * Sets a time limit on an asynchronous function. If the function does not call * its callback within the specified milliseconds, it will be called with a * timeout error. The code property for the error object will be `'ETIMEDOUT'`. * * @name timeout * @static - * @memberOf module:async + * @memberOf module:Utils * @method * @category Util * @param {Function} asyncFn - The asynchronous function you want to set the diff --git a/lib/times.js b/lib/times.js index 62843c6..e6e4187 100644 --- a/lib/times.js +++ b/lib/times.js @@ -2,19 +2,22 @@ import timesLimit from './timesLimit'; import doLimit from './internal/doLimit'; /** + * ``` + * import times from 'async/times' + * ``` * Calls the `iteratee` function `n` times, and accumulates results in the same - * manner you would use with {@link async.map}. + * manner you would use with [map]{@link module:Collections.map}. * * @name times * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.map]{@link module:async.map} + * @see [async.map]{@link module:Collections.map} * @category Control Flow * @param {number} n - The number of times to run the function. * @param {Function} iteratee - The function to call `n` times. Invoked with the * iteration index and a callback (n, next). - * @param {Function} callback - see {@link async.map}. + * @param {Function} callback - see {@link module:Collections.map}. * @example * * // Pretend this is some complicated async factory diff --git a/lib/timesLimit.js b/lib/timesLimit.js index 302c803..01a6399 100644 --- a/lib/timesLimit.js +++ b/lib/timesLimit.js @@ -2,20 +2,23 @@ import mapLimit from './mapLimit'; import range from 'lodash/_baseRange'; /** -* The same as {@link times} but runs a maximum of `limit` async operations at a -* time. + * ``` + * import timesLimit from 'async/timesLimit' + * ``` + * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a + * time. * * @name timesLimit * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.times]{@link module:async.times} + * @see [async.times]{@link module:ControlFlow.times} * @category Control Flow * @param {number} count - The number of times to run the function. * @param {number} limit - The maximum number of async operations at a time. * @param {Function} iteratee - The function to call `n` times. Invoked with the * iteration index and a callback (n, next). - * @param {Function} callback - see {@link async.map}. + * @param {Function} callback - see [async.map]{@link module:Collections.map}. */ export default function timeLimit(count, limit, iteratee, callback) { mapLimit(range(0, count, 1), limit, iteratee, callback); diff --git a/lib/timesSeries.js b/lib/timesSeries.js index 2a46a73..adef004 100644 --- a/lib/timesSeries.js +++ b/lib/timesSeries.js @@ -2,17 +2,20 @@ import timesLimit from './timesLimit'; import doLimit from './internal/doLimit'; /** - * The same as {@link async.times} but runs only a single async operation at a time. + * ``` + * import timesSeries from 'async/timesSeries' + * ``` + * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time. * * @name timesSeries * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.times]{@link module:async.times} + * @see [async.times]{@link module:ControlFlow.times} * @category Control Flow * @param {number} n - The number of times to run the function. * @param {Function} iteratee - The function to call `n` times. Invoked with the * iteration index and a callback (n, next). - * @param {Function} callback - see {@link async.map}. + * @param {Function} callback - see {@link module:Collections.map}. */ export default doLimit(timesLimit, 1); diff --git a/lib/transform.js b/lib/transform.js index 4025fd7..854df2f 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -3,13 +3,16 @@ import isArray from 'lodash/isArray'; import eachOf from './eachOf'; /** + * ``` + * import transform from 'async/transform' + * ``` * A relative of `reduce`. Takes an Object or Array, and iterates over each * element in series, each step potentially mutating an `accumulator` value. * The type of the accumulator defaults to the type of collection passed in. * * @name transform * @static - * @memberOf module:async + * @memberOf module:Collections * @method * @category Collection * @param {Array|Object} coll - A collection to iterate over. diff --git a/lib/unmemoize.js b/lib/unmemoize.js index e8537d9..f0c65a3 100644 --- a/lib/unmemoize.js +++ b/lib/unmemoize.js @@ -1,12 +1,15 @@ /** - * Undoes a {@link async.memoize}d function, reverting it to the original, + * ``` + * import unmemoize from 'async/unmemoize' + * ``` + * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original, * unmemoized form. Handy for testing. * * @name unmemoize * @static - * @memberOf module:async + * @memberOf module:Utils * @method - * @see [async.memoize]{@link module:async.memoize} + * @see [async.memoize]{@link module:Utils.memoize} * @category Util * @param {Function} fn - the memoized function * @returns {Function} a function that calls the original unmemoized function diff --git a/lib/until.js b/lib/until.js index 0b5fde8..23a3ca5 100644 --- a/lib/until.js +++ b/lib/until.js @@ -1,17 +1,20 @@ import whilst from './whilst'; /** + * ``` + * import whilst from 'async/whilst' + * ``` * Repeatedly call `fn` until `test` returns `true`. Calls `callback` when * stopped, or an error occurs. `callback` will be passed an error and any * arguments passed to the final `fn`'s callback. * - * The inverse of {@link async.whilst}. + * The inverse of [whilst]{@link module:ControlFlow.whilst}. * * @name until * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method - * @see [async.whilst]{@link module:async.whilst} + * @see [async.whilst]{@link module:ControlFlow.whilst} * @category Control Flow * @param {Function} test - synchronous truth test to perform before each * execution of `fn`. Invoked with (). diff --git a/lib/waterfall.js b/lib/waterfall.js index cd75b91..36a66f7 100644 --- a/lib/waterfall.js +++ b/lib/waterfall.js @@ -6,6 +6,9 @@ import rest from 'lodash/rest'; import onlyOnce from './internal/onlyOnce'; /** + *``` + * import waterfall from 'async/waterfall' + * ``` * Runs the `tasks` array of functions in series, each passing their results to * the next in the array. However, if any of the `tasks` pass an error to their * own callback, the next function is not executed, and the main `callback` is @@ -13,7 +16,7 @@ import onlyOnce from './internal/onlyOnce'; * * @name waterfall * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Array} tasks - An array of functions to run, each function is passed diff --git a/lib/whilst.js b/lib/whilst.js index d6e6591..1cfb157 100644 --- a/lib/whilst.js +++ b/lib/whilst.js @@ -2,12 +2,15 @@ import noop from 'lodash/noop'; import rest from 'lodash/rest'; /** + * ``` + * import whilst from 'async/whilst' + * ``` * Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when * stopped, or an error occurs. * * @name whilst * @static - * @memberOf module:async + * @memberOf module:ControlFlow * @method * @category Control Flow * @param {Function} test - synchronous truth test to perform before each diff --git a/package.json b/package.json index c386f5b..55eb20d 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "benchmark": "bestiejs/benchmark.js", "bluebird": "^2.9.32", "chai": "^3.1.0", + "cheerio": "^0.20.0", "coveralls": "^2.11.2", "es6-promise": "^2.3.0", "esdoc": "^0.4.7", @@ -61,7 +62,7 @@ "coverage": "nyc npm test && nyc report", "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", "doc": "esdoc -c ./support/esdoc.json", - "jsdocs": "jsdoc -c ./support/jsdoc.json", + "jsdocs": "jsdoc -c ./support/jsdoc.json && node support/fix-jsdoc-html.js", "lint": "eslint lib/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ karma.conf.js", "mocha-browser-test": "karma start", "mocha-node-test": "mocha mocha_test/ --compilers js:babel-core/register", diff --git a/support/fix-jsdoc-html.js b/support/fix-jsdoc-html.js new file mode 100644 index 0000000..3a39fa7 --- /dev/null +++ b/support/fix-jsdoc-html.js @@ -0,0 +1,166 @@ +var async = require('../dist/async'); +var fs = require('fs-extra'); +var path = require('path'); + +var $ = require('cheerio'); +var _ = require('lodash'); + +var docsDir = path.join(__dirname, '../docs'); +var asyncFile = path.join(__dirname, '../dist/async.js'); + +var pageTitle = 'ASYNC'; + +var docFilename = 'docs.html'; +var mainModuleFile = 'module-async.html'; +var mainSectionId = '#main'; +var sectionTitleClass = '.page-title' + +var HTMLFileBegin = '\n\n\n'; +var HTMLFileHeadBodyJoin = '\n'; +var HTMLFileEnd = ''; + +var pageTitlePadding = '12px'; + +var additionalFooterText = ' Documentation has been modified from the original. ' + + ' For more information, please see the async repository.'; + +fs.copySync(asyncFile, path.join(docsDir, 'scripts/async.js'), { clobber: 'true'}); + +function generateHTMLFile(filename, $page, callback) { + // generate an HTML file from a cheerio object + var HTMLdata = HTMLFileBegin + $page.find('head').html() + + HTMLFileHeadBodyJoin + $page.find('body').html() + + HTMLFileEnd; + + fs.writeFile(filename, HTMLdata, callback); +} + +function extractModuleFiles(files) { + return _.filter(files, function(file) { + return _.startsWith(file, 'module') && file !== mainModuleFile; + }); +} + +function combineFakeModules(files, callback) { + var moduleFiles = extractModuleFiles(files); + + fs.readFile(path.join(docsDir, mainModuleFile), 'utf8', function(err, mainModuleData) { + if (err) return callback(err); + + var $mainPage = $(mainModuleData); + // each 'module' (category) has a separate page, with all of the + // important information in a 'main' div. Combine all of these divs into + // one on the actual module page (async) + async.eachSeries(moduleFiles, function(file, fileCallback) { + fs.readFile(path.join(docsDir, file), 'utf8', function(err, moduleData) { + if (err) return fileCallback(err); + var $modulePage = $(moduleData); + var moduleName = $modulePage.find(sectionTitleClass).text(); + $modulePage.find(sectionTitleClass).attr('id', moduleName.toLowerCase()); + $mainPage.find(mainSectionId).append($modulePage.find(mainSectionId).html()); + return fileCallback(); + }); + }, function(err) { + if (err) return callback(err); + + generateHTMLFile(path.join(docsDir, docFilename), $mainPage, callback); + }); + }); +} + +function applyPreCheerioFixes(data) { + var fixedPageTitleStyle = '\n' + var closingHeadTag = '' + + var asyncScript = '\n'; + var closingBodyTag = ''; + + var rIncorrectCFText = />ControlFlowmodule:(\w+)\.(\w+)'+methodName+'<'; + }); +}; + +function fixToc($page, moduleFiles) { + // remove `async` listing from toc + $page.find('li').find('a[href="'+mainModuleFile+'"]').parent().remove(); + + // change toc title + $page.find('nav').children('h3').text(pageTitle); + + // make everything point to the same 'docs.html' page + _.each(moduleFiles, function(filename) { + $page.find('[href^="'+filename+'"]').each(function() { + var $ele = $(this); + var href = $ele.attr('href'); + + // category titles should sections title, while everything else + // points to the correct listing + if (href === filename) { + var moduleName = $ele.text().toLowerCase().replace(/\s/g, ''); + $ele.attr('href', docFilename+'#'+moduleName); + } else { + $ele.attr('href', href.replace(filename, docFilename)); + } + }); + }); +} + +function fixFooter($page) { + // add a note to the footer that the documentation has been modified + var $footer = $page.find('footer'); + var text = $footer.text(); + $footer.append(additionalFooterText); +}; + +function fixModuleLinks(files, callback) { + var moduleFiles = extractModuleFiles(files); + + async.each(files, function(file, fileCallback) { + var filePath = path.join(docsDir, file); + fs.readFile(filePath, 'utf8', function(err, fileData) { + if (err) return fileCallback(err); + var $file = $(applyPreCheerioFixes(fileData)); + + fixToc($file, moduleFiles); + + fixFooter($file); + $file.find('[href="'+mainModuleFile+'"]').attr('href', docFilename); + generateHTMLFile(filePath, $file, fileCallback); + }); + }, callback); +} + +fs.readdir(docsDir, function(err, files) { + if (err) { + throw err; + } + + var HTMLFiles = _.filter(files, function(file) { + return path.extname(file) === '.html'; + }); + + combineFakeModules(HTMLFiles, function(err) { + if (err) throw err; + + HTMLFiles.push(docFilename); + + fixModuleLinks(HTMLFiles, function(err) { + if (err) throw err; + console.log('Docs generated successfully'); + }); + }); +}); diff --git a/support/jsdoc.json b/support/jsdoc.json index ac95082..544db31 100644 --- a/support/jsdoc.json +++ b/support/jsdoc.json @@ -15,7 +15,6 @@ "recurse": true }, "templates": { - "cleverLinks": false, - "theme": "cerulean" + "cleverLinks": false } } -- cgit v1.2.1 From d8abc2bd97ea25e4eb915a39a9802cda5bfea135 Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Tue, 21 Jun 2016 11:15:53 -0400 Subject: Genetate import path using jsdoc plugin --- lib/apply.js | 3 --- lib/applyEach.js | 3 --- lib/applyEachSeries.js | 3 --- lib/asyncify.js | 3 --- lib/auto.js | 3 --- lib/autoInject.js | 3 --- lib/cargo.js | 3 --- lib/compose.js | 3 --- lib/concat.js | 3 --- lib/concatSeries.js | 3 --- lib/constant.js | 3 --- lib/detect.js | 3 --- lib/detectLimit.js | 3 --- lib/detectSeries.js | 3 --- lib/dir.js | 3 --- lib/doDuring.js | 3 --- lib/doUntil.js | 3 --- lib/doWhilst.js | 3 --- lib/during.js | 3 --- lib/each.js | 3 --- lib/eachLimit.js | 3 --- lib/eachOf.js | 3 --- lib/eachOfLimit.js | 3 --- lib/eachOfSeries.js | 3 --- lib/eachSeries.js | 3 --- lib/ensureAsync.js | 3 --- lib/every.js | 3 --- lib/everyLimit.js | 3 --- lib/everySeries.js | 3 --- lib/filter.js | 3 --- lib/filterLimit.js | 3 --- lib/filterSeries.js | 3 --- lib/forever.js | 3 --- lib/iterator.js | 3 --- lib/log.js | 3 --- lib/map.js | 3 --- lib/mapLimit.js | 3 --- lib/mapSeries.js | 3 --- lib/mapValues.js | 3 --- lib/mapValuesLimit.js | 3 --- lib/mapValuesSeries.js | 3 --- lib/memoize.js | 3 --- lib/nextTick.js | 3 --- lib/parallel.js | 3 --- lib/parallelLimit.js | 3 --- lib/priorityQueue.js | 3 --- lib/queue.js | 3 --- lib/race.js | 3 --- lib/reduce.js | 3 --- lib/reduceRight.js | 3 --- lib/reflect.js | 3 --- lib/reflectAll.js | 3 --- lib/reject.js | 3 --- lib/rejectLimit.js | 3 --- lib/rejectSeries.js | 3 --- lib/retry.js | 3 --- lib/retryable.js | 3 --- lib/seq.js | 3 --- lib/series.js | 3 --- lib/setImmediate.js | 3 --- lib/some.js | 3 --- lib/someLimit.js | 3 --- lib/someSeries.js | 3 --- lib/sortBy.js | 3 --- lib/timeout.js | 3 --- lib/times.js | 3 --- lib/timesLimit.js | 3 --- lib/timesSeries.js | 3 --- lib/transform.js | 3 --- lib/unmemoize.js | 3 --- lib/until.js | 3 --- lib/waterfall.js | 3 --- lib/whilst.js | 3 --- support/jsdoc-import-path-plugin.js | 21 +++++++++++++++++++++ support/jsdoc.json | 2 +- 75 files changed, 22 insertions(+), 220 deletions(-) create mode 100644 support/jsdoc-import-path-plugin.js diff --git a/lib/apply.js b/lib/apply.js index 8c43e34..465ed10 100644 --- a/lib/apply.js +++ b/lib/apply.js @@ -1,9 +1,6 @@ import rest from 'lodash/rest'; /** - * ``` - * import apply from 'async/apply' - * ``` * Creates a continuation function with some arguments already applied. * * Useful as a shorthand when combined with other control flow functions. Any diff --git a/lib/applyEach.js b/lib/applyEach.js index 656014c..c106114 100644 --- a/lib/applyEach.js +++ b/lib/applyEach.js @@ -2,9 +2,6 @@ import applyEach from './internal/applyEach'; import map from './map'; /** - * ``` - * import applyEach from 'async/applyEach' - * ``` * Applies the provided arguments to each function in the array, calling * `callback` after all functions have completed. If you only provide the first * argument, then it will return a function which lets you pass in the diff --git a/lib/applyEachSeries.js b/lib/applyEachSeries.js index 892e355..f0919cb 100644 --- a/lib/applyEachSeries.js +++ b/lib/applyEachSeries.js @@ -2,9 +2,6 @@ import applyEach from './internal/applyEach'; import mapSeries from './mapSeries'; /** - * ``` - * import applyEachSeries from 'async/applyEachSeries' - * ``` * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time. * * @name applyEachSeries diff --git a/lib/asyncify.js b/lib/asyncify.js index 9baa238..e235311 100644 --- a/lib/asyncify.js +++ b/lib/asyncify.js @@ -2,9 +2,6 @@ import isObject from 'lodash/isObject'; import initialParams from './internal/initialParams'; /** - * ``` - * import asyncify from 'async/asyncify' - * ``` * Take a sync function and make it async, passing its return value to a * callback. This is useful for plugging sync functions into a waterfall, * series, or other async functions. Any arguments passed to the generated diff --git a/lib/auto.js b/lib/auto.js index c6f291c..ce9f259 100644 --- a/lib/auto.js +++ b/lib/auto.js @@ -10,9 +10,6 @@ import rest from 'lodash/rest'; import onlyOnce from './internal/onlyOnce'; /** - * ``` - * import auto from 'async/auto' - * ``` * Determines the best order for running the functions in `tasks`, based on * their requirements. Each function can optionally depend on other functions * being completed first, and each function is run as soon as its requirements diff --git a/lib/autoInject.js b/lib/autoInject.js index fc6399c..1b7bed4 100644 --- a/lib/autoInject.js +++ b/lib/autoInject.js @@ -12,9 +12,6 @@ function parseParams(func) { } /** - * ``` - * import autoInject from 'async/autoInject' - * ``` * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent * tasks are specified as parameters to the function, after the usual callback * parameter, with the parameter names matching the names of the tasks it diff --git a/lib/cargo.js b/lib/cargo.js index 9bdc613..d86cb67 100644 --- a/lib/cargo.js +++ b/lib/cargo.js @@ -31,9 +31,6 @@ import queue from './internal/queue'; */ /** - * ``` - * import cargo from 'async/cargo' - * ``` * Creates a `cargo` object with the specified payload. Tasks added to the * cargo will be processed altogether (up to the `payload` limit). If the * `worker` is in progress, the task is queued until it becomes available. Once diff --git a/lib/compose.js b/lib/compose.js index 0f87239..ff2e0ab 100644 --- a/lib/compose.js +++ b/lib/compose.js @@ -3,9 +3,6 @@ import seq from './seq'; var reverse = Array.prototype.reverse; /** - * ``` - * import compose from 'async/compose' - * ``` * Creates a function which is a composition of the passed asynchronous * functions. Each function consumes the return value of the function that * follows. Composing functions `f()`, `g()`, and `h()` would produce the result diff --git a/lib/concat.js b/lib/concat.js index 05043c3..db23737 100644 --- a/lib/concat.js +++ b/lib/concat.js @@ -2,9 +2,6 @@ import concat from './internal/concat'; import doParallel from './internal/doParallel'; /** - * ``` - * import concat from 'async/concat' - * ``` * Applies `iteratee` to each item in `coll`, concatenating the results. Returns * the concatenated list. The `iteratee`s are called in parallel, and the * results are concatenated as they return. There is no guarantee that the diff --git a/lib/concatSeries.js b/lib/concatSeries.js index 374d8ee..c5dfb61 100644 --- a/lib/concatSeries.js +++ b/lib/concatSeries.js @@ -2,9 +2,6 @@ import concat from './internal/concat'; import doSeries from './internal/doSeries'; /** - * ``` - * import concatSeries from 'async/concatSeries' - * ``` * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time. * * @name concatSeries diff --git a/lib/constant.js b/lib/constant.js index 5c325a1..c7dd50f 100644 --- a/lib/constant.js +++ b/lib/constant.js @@ -2,9 +2,6 @@ import rest from 'lodash/rest'; import initialParams from './internal/initialParams'; /** - * ``` - * import constant from 'async/constant' - * ``` * Returns a function that when called, calls-back with the values provided. * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to * [`auto`]{@link module:ControlFlow.auto}. diff --git a/lib/detect.js b/lib/detect.js index 606ebe2..3aff790 100644 --- a/lib/detect.js +++ b/lib/detect.js @@ -5,9 +5,6 @@ import eachOf from './eachOf'; import findGetResult from './internal/findGetResult'; /** - * ``` - * import detect from 'async/detect' - * ``` * Returns the first value in `coll` that passes an async truth test. The * `iteratee` is applied in parallel, meaning the first iteratee to return * `true` will fire the detect `callback` with that result. That means the diff --git a/lib/detectLimit.js b/lib/detectLimit.js index 6911fb9..da54bd6 100644 --- a/lib/detectLimit.js +++ b/lib/detectLimit.js @@ -5,9 +5,6 @@ import eachOfLimit from './eachOfLimit'; import findGetResult from './internal/findGetResult'; /** - * ``` - * import detectLimit from 'async/detectLimit' - * ``` * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a * time. * diff --git a/lib/detectSeries.js b/lib/detectSeries.js index ac2f41c..fd29343 100644 --- a/lib/detectSeries.js +++ b/lib/detectSeries.js @@ -5,9 +5,6 @@ import eachOfSeries from './eachOfSeries'; import findGetResult from './internal/findGetResult'; /** - * ``` - * import detectSeries from 'async/detectSeries' - * ``` * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time. * * @name detectSeries diff --git a/lib/dir.js b/lib/dir.js index 52ca709..912b558 100644 --- a/lib/dir.js +++ b/lib/dir.js @@ -1,9 +1,6 @@ import consoleFunc from './internal/consoleFunc'; /** - * ``` - * import dir from 'async/dir' - * ``` * Logs the result of an `async` function to the `console` using `console.dir` * to display the properties of the resulting object. Only works in Node.js or * in browsers that support `console.dir` and `console.error` (such as FF and diff --git a/lib/doDuring.js b/lib/doDuring.js index 7df8f60..d12d668 100644 --- a/lib/doDuring.js +++ b/lib/doDuring.js @@ -1,9 +1,6 @@ import during from './during'; /** - * ``` - * import doDuring from 'async/doDuring' - * ``` * The post-check version of [`during`]{@link module:ControlFlow.during}. To reflect the difference in * the order of operations, the arguments `test` and `fn` are switched. * diff --git a/lib/doUntil.js b/lib/doUntil.js index 68fb4a1..0c5bb71 100644 --- a/lib/doUntil.js +++ b/lib/doUntil.js @@ -1,9 +1,6 @@ import doWhilst from './doWhilst'; /** - * ``` - * import doUtil from 'async/doUtil' - * ``` * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the * argument ordering differs from `until`. * diff --git a/lib/doWhilst.js b/lib/doWhilst.js index 344339d..a425999 100644 --- a/lib/doWhilst.js +++ b/lib/doWhilst.js @@ -1,9 +1,6 @@ import whilst from './whilst'; /** - * ``` - * import doWhilst from 'async/doWhilst' - * ``` * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in * the order of operations, the arguments `test` and `fn` are switched. * diff --git a/lib/during.js b/lib/during.js index e6016bb..55af1b9 100644 --- a/lib/during.js +++ b/lib/during.js @@ -2,9 +2,6 @@ import noop from 'lodash/noop'; import rest from 'lodash/rest'; /** - * ``` - * import during from 'async/during' - * ``` * Like [`whilst`]{@link module:ControlFlow.whilst}, except the `test` is an asynchronous function that * is passed a callback in the form of `function (err, truth)`. If error is * passed to `test` or `fn`, the main callback is immediately called with the diff --git a/lib/each.js b/lib/each.js index eb8f242..aab1d3d 100644 --- a/lib/each.js +++ b/lib/each.js @@ -2,9 +2,6 @@ import eachLimit from './eachLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import each from 'async/each' - * ``` * Applies the function `iteratee` to each item in `coll`, in parallel. * The `iteratee` is called with an item from the list, and a callback for when * it has finished. If the `iteratee` passes an error to its `callback`, the diff --git a/lib/eachLimit.js b/lib/eachLimit.js index 6a263aa..a46eb9d 100644 --- a/lib/eachLimit.js +++ b/lib/eachLimit.js @@ -2,9 +2,6 @@ import eachOfLimit from './internal/eachOfLimit'; import withoutIndex from './internal/withoutIndex'; /** - * ``` - * import eachLimit from 'async/eachLimit' - * ``` * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time. * * @name eachLimit diff --git a/lib/eachOf.js b/lib/eachOf.js index d8f46f7..b51fefb 100644 --- a/lib/eachOf.js +++ b/lib/eachOf.js @@ -2,9 +2,6 @@ import eachOfLimit from './eachOfLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import eachOf from 'async/eachOf' - * ``` * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument * to the iteratee. * diff --git a/lib/eachOfLimit.js b/lib/eachOfLimit.js index e81d590..55d60e3 100644 --- a/lib/eachOfLimit.js +++ b/lib/eachOfLimit.js @@ -1,9 +1,6 @@ import _eachOfLimit from './internal/eachOfLimit'; /** - * ``` - * import eachOfLimit from 'async/eachOfLimit' - * ``` * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a * time. * diff --git a/lib/eachOfSeries.js b/lib/eachOfSeries.js index 103d088..32003a8 100644 --- a/lib/eachOfSeries.js +++ b/lib/eachOfSeries.js @@ -2,9 +2,6 @@ import eachOfLimit from './eachOfLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import eachOfSeries from 'async/eachOfSeries' - * ``` * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time. * * @name eachOfSeries diff --git a/lib/eachSeries.js b/lib/eachSeries.js index 87fabfb..1b8e589 100644 --- a/lib/eachSeries.js +++ b/lib/eachSeries.js @@ -2,9 +2,6 @@ import eachLimit from './eachLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import eachSeries from 'async/eachSeries' - * ``` * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time. * * @name eachSeries diff --git a/lib/ensureAsync.js b/lib/ensureAsync.js index 6ef698e..c60d07e 100644 --- a/lib/ensureAsync.js +++ b/lib/ensureAsync.js @@ -2,9 +2,6 @@ import setImmediate from './internal/setImmediate'; import initialParams from './internal/initialParams'; /** - * ``` - * import ensureAsync from 'async/ensureAsync' - * ``` * Wrap an async function and ensure it calls its callback on a later tick of * the event loop. If the function already calls its callback on a next tick, * no extra deferral is added. This is useful for preventing stack overflows diff --git a/lib/every.js b/lib/every.js index 6355218..147c54a 100644 --- a/lib/every.js +++ b/lib/every.js @@ -2,9 +2,6 @@ import everyLimit from './everyLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import every from 'async/every' - * ``` * Returns `true` if every element in `coll` satisfies an async test. If any * iteratee call returns `false`, the main `callback` is immediately called. * diff --git a/lib/everyLimit.js b/lib/everyLimit.js index a8cd65a..1ba2858 100644 --- a/lib/everyLimit.js +++ b/lib/everyLimit.js @@ -3,9 +3,6 @@ import eachOfLimit from './eachOfLimit'; import notId from './internal/notId'; /** - * ``` - * import everyLimit from 'async/everyLimit' - * ``` * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time. * * @name everyLimit diff --git a/lib/everySeries.js b/lib/everySeries.js index 4333584..3cdadf0 100644 --- a/lib/everySeries.js +++ b/lib/everySeries.js @@ -2,9 +2,6 @@ import everyLimit from './everyLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import everySeries from 'async/everySeries' - * ``` * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time. * * @name everySeries diff --git a/lib/filter.js b/lib/filter.js index b576df2..b858fea 100644 --- a/lib/filter.js +++ b/lib/filter.js @@ -2,9 +2,6 @@ import filterLimit from './filterLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import filter from 'async/filter' - * ``` * Returns a new array of all the values in `coll` which pass an async truth * test. This operation is performed in parallel, but the results array will be * in the same order as the original. diff --git a/lib/filterLimit.js b/lib/filterLimit.js index d9a43c8..6d429e8 100644 --- a/lib/filterLimit.js +++ b/lib/filterLimit.js @@ -2,9 +2,6 @@ import filter from './internal/filter'; import doParallelLimit from './internal/doParallelLimit'; /** - * ``` - * import filterLimit from 'async/filterLimit' - * ``` * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a * time. * diff --git a/lib/filterSeries.js b/lib/filterSeries.js index 1afa9b2..781e4eb 100644 --- a/lib/filterSeries.js +++ b/lib/filterSeries.js @@ -2,9 +2,6 @@ import filterLimit from './filterLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import filterSeries from 'async/filterSeries' - * ``` * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time. * * @name filterSeries diff --git a/lib/forever.js b/lib/forever.js index 7f060ca..0147395 100644 --- a/lib/forever.js +++ b/lib/forever.js @@ -4,9 +4,6 @@ import onlyOnce from './internal/onlyOnce'; import ensureAsync from './ensureAsync'; /** - * ``` - * import forever from 'async/forever' - * ``` * Calls the asynchronous function `fn` with a callback parameter that allows it * to call itself again, in series, indefinitely. diff --git a/lib/iterator.js b/lib/iterator.js index 1d67145..fafd960 100644 --- a/lib/iterator.js +++ b/lib/iterator.js @@ -1,7 +1,4 @@ /** - * ``` - * import iterator from 'async/iterator' - * ``` * Creates an iterator function which calls the next function in the `tasks` * array, returning a continuation to call the next one after that. It's also * possible to “peek” at the next iterator with `iterator.next()`. diff --git a/lib/log.js b/lib/log.js index 240bba1..848661d 100644 --- a/lib/log.js +++ b/lib/log.js @@ -1,9 +1,6 @@ import consoleFunc from './internal/consoleFunc'; /** - * ``` - * import log from 'async/log' - * ``` * Logs the result of an `async` function to the `console`. Only works in * Node.js or in browsers that support `console.log` and `console.error` (such * as FF and Chrome). If multiple arguments are returned from the async diff --git a/lib/map.js b/lib/map.js index 59bb682..24af6fb 100644 --- a/lib/map.js +++ b/lib/map.js @@ -2,9 +2,6 @@ import mapLimit from './mapLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import map from 'async/map' - * ``` * Produces a new collection of values by mapping each value in `coll` through * the `iteratee` function. The `iteratee` is called with an item from `coll` * and a callback for when it has finished processing. Each of these callback diff --git a/lib/mapLimit.js b/lib/mapLimit.js index 1d3d3b2..efaff2b 100644 --- a/lib/mapLimit.js +++ b/lib/mapLimit.js @@ -2,9 +2,6 @@ import doParallelLimit from './internal/doParallelLimit'; import map from './internal/map'; /** - * ``` - * import mapLimit from 'async/mapLimit' - * ``` * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time. * * @name mapLimit diff --git a/lib/mapSeries.js b/lib/mapSeries.js index 5e39065..24ce126 100644 --- a/lib/mapSeries.js +++ b/lib/mapSeries.js @@ -2,9 +2,6 @@ import mapLimit from './mapLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import mapSeries from 'async/mapSeries' - * ``` * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time. * * @name mapSeries diff --git a/lib/mapValues.js b/lib/mapValues.js index 1f19e3e..240fc67 100644 --- a/lib/mapValues.js +++ b/lib/mapValues.js @@ -3,9 +3,6 @@ import doLimit from './internal/doLimit'; /** - * ``` - * import mapValues from 'async/mapValues' - * ``` * A relative of [`map`]{@link module:Collections.map}, designed for use with objects. * * Produces a new Object by mapping each value of `obj` through the `iteratee` diff --git a/lib/mapValuesLimit.js b/lib/mapValuesLimit.js index 0f3584a..bced034 100644 --- a/lib/mapValuesLimit.js +++ b/lib/mapValuesLimit.js @@ -1,9 +1,6 @@ import eachOfLimit from './eachOfLimit'; /** - * ``` - * import mapValuesLimit from 'async/mapValuesLimit' - * ``` * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a * time. * diff --git a/lib/mapValuesSeries.js b/lib/mapValuesSeries.js index e9746a1..b97fcd1 100644 --- a/lib/mapValuesSeries.js +++ b/lib/mapValuesSeries.js @@ -2,9 +2,6 @@ import mapValuesLimit from './mapValuesLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import mapValuesSeries from 'async/mapValuesSeries' - * ``` * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time. * * @name mapValuesSeries diff --git a/lib/memoize.js b/lib/memoize.js index 3e2ee32..31c041c 100644 --- a/lib/memoize.js +++ b/lib/memoize.js @@ -9,9 +9,6 @@ function has(obj, key) { } /** - * ``` - * import memoize from 'async/memoize' - * ``` * Caches the results of an `async` function. When creating a hash to store * function results against, the callback is omitted from the hash and an * optional hash function can be used. diff --git a/lib/nextTick.js b/lib/nextTick.js index 1959c84..62d20de 100644 --- a/lib/nextTick.js +++ b/lib/nextTick.js @@ -3,9 +3,6 @@ import { hasNextTick, hasSetImmediate, fallback, wrap } from './internal/setImmediate'; /** - * ``` - * import nextTick from 'async/nextTick' - * ``` * Calls `callback` on a later loop around the event loop. In Node.js this just * calls `setImmediate`. In the browser it will use `setImmediate` if * available, otherwise `setTimeout(callback, 0)`, which means other higher diff --git a/lib/parallel.js b/lib/parallel.js index 9df6bd6..1f6a3cc 100644 --- a/lib/parallel.js +++ b/lib/parallel.js @@ -2,9 +2,6 @@ import parallelLimit from './parallelLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import parallel from 'async/parallel' - * ``` * Run the `tasks` collection of functions in parallel, without waiting until * the previous function has completed. If any of the functions pass an error to * its callback, the main `callback` is immediately called with the value of the diff --git a/lib/parallelLimit.js b/lib/parallelLimit.js index 7057bd0..926fa85 100644 --- a/lib/parallelLimit.js +++ b/lib/parallelLimit.js @@ -2,9 +2,6 @@ import eachOfLimit from './internal/eachOfLimit'; import parallel from './internal/parallel'; /** - * ``` - * import parallelLimit from 'async/parallelLimit' - * ``` * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a * time. * diff --git a/lib/priorityQueue.js b/lib/priorityQueue.js index 4162311..9ea24bc 100644 --- a/lib/priorityQueue.js +++ b/lib/priorityQueue.js @@ -7,9 +7,6 @@ import setImmediate from './setImmediate'; import queue from './queue'; /** - * ``` - * import priorityQueue from 'async/priorityQueue' - * ``` * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and * completed in ascending priority order. * diff --git a/lib/queue.js b/lib/queue.js index 5f032d7..109ba50 100644 --- a/lib/queue.js +++ b/lib/queue.js @@ -48,9 +48,6 @@ import queue from './internal/queue'; */ /** - * ``` - * import queue from 'async/queue' - * ``` * Creates a `queue` object with the specified `concurrency`. Tasks added to the * `queue` are processed in parallel (up to the `concurrency` limit). If all * `worker`s are in progress, the task is queued until one becomes available. diff --git a/lib/race.js b/lib/race.js index 8efece4..893e860 100644 --- a/lib/race.js +++ b/lib/race.js @@ -4,9 +4,6 @@ import noop from 'lodash/noop'; import once from './internal/once'; /** - * ``` - * import race from 'async/race' - * ``` * Runs the `tasks` array of functions in parallel, without waiting until the * previous function has completed. Once any the `tasks` completed or pass an * error to its callback, the main `callback` is immediately called. It's diff --git a/lib/reduce.js b/lib/reduce.js index d870c9d..8145db7 100644 --- a/lib/reduce.js +++ b/lib/reduce.js @@ -1,9 +1,6 @@ import eachOfSeries from './eachOfSeries'; /** - * ``` - * import reduce from 'async/reduce' - * ``` * Reduces `coll` into a single value using an async `iteratee` to return each * successive step. `memo` is the initial state of the reduction. This function * only operates in series. diff --git a/lib/reduceRight.js b/lib/reduceRight.js index b3090d9..69fd158 100644 --- a/lib/reduceRight.js +++ b/lib/reduceRight.js @@ -3,9 +3,6 @@ import reduce from './reduce'; var slice = Array.prototype.slice; /** - * ``` - * import reduceRight from 'async/reduceRight' - * ``` * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `coll` in reverse order. * * @name reduceRight diff --git a/lib/reflect.js b/lib/reflect.js index a8b7438..ac5345d 100644 --- a/lib/reflect.js +++ b/lib/reflect.js @@ -2,9 +2,6 @@ import initialParams from './internal/initialParams'; import rest from 'lodash/rest'; /** - * ``` - * import reflect from 'async/reflect' - * ``` * Wraps the function in another function that always returns data even when it * errors. * diff --git a/lib/reflectAll.js b/lib/reflectAll.js index 160334c..a9fe48f 100644 --- a/lib/reflectAll.js +++ b/lib/reflectAll.js @@ -1,9 +1,6 @@ import reflect from './reflect'; /** - * ``` - * import reflectAll from 'async/reflectAll' - * ``` * A helper function that wraps an array of functions with reflect. * * @name reflectAll diff --git a/lib/reject.js b/lib/reject.js index dd54453..f882a93 100644 --- a/lib/reject.js +++ b/lib/reject.js @@ -2,9 +2,6 @@ import rejectLimit from './rejectLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import reject from 'async/reject' - * ``` * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test. * * @name reject diff --git a/lib/rejectLimit.js b/lib/rejectLimit.js index 78c2def..2a57bc7 100644 --- a/lib/rejectLimit.js +++ b/lib/rejectLimit.js @@ -2,9 +2,6 @@ import reject from './internal/reject'; import doParallelLimit from './internal/doParallelLimit'; /** - * ``` - * import rejectLimit from 'async/rejectLimit' - * ``` * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a * time. * diff --git a/lib/rejectSeries.js b/lib/rejectSeries.js index a691536..0844864 100644 --- a/lib/rejectSeries.js +++ b/lib/rejectSeries.js @@ -2,9 +2,6 @@ import rejectLimit from './rejectLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import rejectSeries from 'async/rejectSeries' - * ``` * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time. * * @name rejectSeries diff --git a/lib/retry.js b/lib/retry.js index b137a0d..5c22af3 100644 --- a/lib/retry.js +++ b/lib/retry.js @@ -3,9 +3,6 @@ import noop from 'lodash/noop'; import constant from 'lodash/constant'; /** - * ``` - * import retry from 'async/retry' - * ``` * Attempts to get a successful response from `task` no more than `times` times * before returning an error. If the task is successful, the `callback` will be * passed the result of the successful task. If all attempts fail, the callback diff --git a/lib/retryable.js b/lib/retryable.js index ad47351..00fd8f2 100644 --- a/lib/retryable.js +++ b/lib/retryable.js @@ -2,9 +2,6 @@ import retry from './retry'; import initialParams from './internal/initialParams'; /** - * ``` - * import retryable from 'async/retryable' - * ``` * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method wraps a task and makes it * retryable, rather than immediately calling it with retries. * diff --git a/lib/seq.js b/lib/seq.js index 5f4e74e..01355b1 100644 --- a/lib/seq.js +++ b/lib/seq.js @@ -3,9 +3,6 @@ import rest from 'lodash/rest'; import reduce from './reduce'; /** - * ``` - * import seq from 'async/seq' - * ``` * Version of the compose function that is more natural to read. Each function * consumes the return value of the previous function. It is the equivalent of * [compose]{@link module:ControlFlow.compose} with the arguments reversed. diff --git a/lib/series.js b/lib/series.js index 1877e81..1969943 100644 --- a/lib/series.js +++ b/lib/series.js @@ -2,9 +2,6 @@ import parallel from './internal/parallel'; import eachOfSeries from './eachOfSeries'; /** - * ``` - * import series from 'async/series' - * ``` * Run the functions in the `tasks` collection in series, each one running once * the previous function has completed. If any functions in the series pass an * error to its callback, no more functions are run, and `callback` is diff --git a/lib/setImmediate.js b/lib/setImmediate.js index 1b545a5..f820b46 100644 --- a/lib/setImmediate.js +++ b/lib/setImmediate.js @@ -1,9 +1,6 @@ import setImmediate from './internal/setImmediate'; /** - * ``` - * import setImmediate from 'async/setImmediate' - * ``` * Calls `callback` on a later loop around the event loop. In Node.js this just * calls `setImmediate`. In the browser it will use `setImmediate` if * available, otherwise `setTimeout(callback, 0)`, which means other higher diff --git a/lib/some.js b/lib/some.js index 83bed71..ff777e5 100644 --- a/lib/some.js +++ b/lib/some.js @@ -2,9 +2,6 @@ import someLimit from './someLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import some from 'async/some' - * ``` * Returns `true` if at least one element in the `coll` satisfies an async test. * If any iteratee call returns `true`, the main `callback` is immediately * called. diff --git a/lib/someLimit.js b/lib/someLimit.js index b3920f1..ad65721 100644 --- a/lib/someLimit.js +++ b/lib/someLimit.js @@ -3,9 +3,6 @@ import eachOfLimit from './eachOfLimit'; import identity from 'lodash/identity'; /** - * ``` - * import someLimit from 'async/someLimit' - * ``` * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time. * * @name someLimit diff --git a/lib/someSeries.js b/lib/someSeries.js index feec58f..cc30c36 100644 --- a/lib/someSeries.js +++ b/lib/someSeries.js @@ -2,9 +2,6 @@ import someLimit from './someLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import someSeries from 'async/someSeries' - * ``` * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time. * * @name someSeries diff --git a/lib/sortBy.js b/lib/sortBy.js index f96b1ab..ab6c420 100644 --- a/lib/sortBy.js +++ b/lib/sortBy.js @@ -4,9 +4,6 @@ import property from 'lodash/_baseProperty'; import map from './map'; /** - * ``` - * import sortBy from 'async/sortBy' - * ``` * Sorts a list by the results of running each `coll` value through an async * `iteratee`. * diff --git a/lib/timeout.js b/lib/timeout.js index f2643ac..7caba44 100644 --- a/lib/timeout.js +++ b/lib/timeout.js @@ -1,9 +1,6 @@ import initialParams from './internal/initialParams'; /** - * ``` - * import timeout from 'async/timeout' - * ``` * Sets a time limit on an asynchronous function. If the function does not call * its callback within the specified milliseconds, it will be called with a * timeout error. The code property for the error object will be `'ETIMEDOUT'`. diff --git a/lib/times.js b/lib/times.js index e6e4187..bdd2e6b 100644 --- a/lib/times.js +++ b/lib/times.js @@ -2,9 +2,6 @@ import timesLimit from './timesLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import times from 'async/times' - * ``` * Calls the `iteratee` function `n` times, and accumulates results in the same * manner you would use with [map]{@link module:Collections.map}. * diff --git a/lib/timesLimit.js b/lib/timesLimit.js index 01a6399..68d5ede 100644 --- a/lib/timesLimit.js +++ b/lib/timesLimit.js @@ -2,9 +2,6 @@ import mapLimit from './mapLimit'; import range from 'lodash/_baseRange'; /** - * ``` - * import timesLimit from 'async/timesLimit' - * ``` * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a * time. * diff --git a/lib/timesSeries.js b/lib/timesSeries.js index adef004..672428d 100644 --- a/lib/timesSeries.js +++ b/lib/timesSeries.js @@ -2,9 +2,6 @@ import timesLimit from './timesLimit'; import doLimit from './internal/doLimit'; /** - * ``` - * import timesSeries from 'async/timesSeries' - * ``` * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time. * * @name timesSeries diff --git a/lib/transform.js b/lib/transform.js index 854df2f..6098522 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -3,9 +3,6 @@ import isArray from 'lodash/isArray'; import eachOf from './eachOf'; /** - * ``` - * import transform from 'async/transform' - * ``` * A relative of `reduce`. Takes an Object or Array, and iterates over each * element in series, each step potentially mutating an `accumulator` value. * The type of the accumulator defaults to the type of collection passed in. diff --git a/lib/unmemoize.js b/lib/unmemoize.js index f0c65a3..4b2db4d 100644 --- a/lib/unmemoize.js +++ b/lib/unmemoize.js @@ -1,7 +1,4 @@ /** - * ``` - * import unmemoize from 'async/unmemoize' - * ``` * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original, * unmemoized form. Handy for testing. * diff --git a/lib/until.js b/lib/until.js index 23a3ca5..7b0b0b5 100644 --- a/lib/until.js +++ b/lib/until.js @@ -1,9 +1,6 @@ import whilst from './whilst'; /** - * ``` - * import whilst from 'async/whilst' - * ``` * Repeatedly call `fn` until `test` returns `true`. Calls `callback` when * stopped, or an error occurs. `callback` will be passed an error and any * arguments passed to the final `fn`'s callback. diff --git a/lib/waterfall.js b/lib/waterfall.js index 36a66f7..b3f0dbc 100644 --- a/lib/waterfall.js +++ b/lib/waterfall.js @@ -6,9 +6,6 @@ import rest from 'lodash/rest'; import onlyOnce from './internal/onlyOnce'; /** - *``` - * import waterfall from 'async/waterfall' - * ``` * Runs the `tasks` array of functions in series, each passing their results to * the next in the array. However, if any of the `tasks` pass an error to their * own callback, the next function is not executed, and the main `callback` is diff --git a/lib/whilst.js b/lib/whilst.js index 1cfb157..3311f4c 100644 --- a/lib/whilst.js +++ b/lib/whilst.js @@ -2,9 +2,6 @@ import noop from 'lodash/noop'; import rest from 'lodash/rest'; /** - * ``` - * import whilst from 'async/whilst' - * ``` * Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when * stopped, or an error occurs. * diff --git a/support/jsdoc-import-path-plugin.js b/support/jsdoc-import-path-plugin.js new file mode 100644 index 0000000..3f0937f --- /dev/null +++ b/support/jsdoc-import-path-plugin.js @@ -0,0 +1,21 @@ +const path = require('path'); + +exports.handlers = { + jsdocCommentFound: function(e) { + var moduleName = path.parse(e.filename).name; + + + var lines = e.comment.split(/\r?\n/); + + var importLines = [ + '```', + `import ${moduleName} from 'async/${moduleName}';`, + '```' + ]; + + if (moduleName !== 'index') { + e.comment = [lines[0], ...importLines, ...lines.slice(1)].join("\n"); + } + + } +}; diff --git a/support/jsdoc.json b/support/jsdoc.json index 544db31..a0e0daa 100644 --- a/support/jsdoc.json +++ b/support/jsdoc.json @@ -6,7 +6,7 @@ "source": { "include": [ "./lib" ] }, - "plugins": ["plugins/markdown"], + "plugins": ["plugins/markdown", "./jsdoc-import-path-plugin"], "opts": { "readme": "README.md", "template": "node_modules/minami", -- cgit v1.2.1 From 6974bf11cd52cbb867d031b141618be4509cc37f Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Tue, 21 Jun 2016 22:45:53 -0400 Subject: jsdoc: moving jsdoc related files to subdirectory --- docs/styles/jsdoc-custom.css | 3 + support/fix-jsdoc-html.js | 166 ----------------------------- support/jsdoc-import-path-plugin.js | 21 ---- support/jsdoc.json | 20 ---- support/jsdoc/jsdoc-custom.css | 3 + support/jsdoc/jsdoc-fix-html.js | 168 ++++++++++++++++++++++++++++++ support/jsdoc/jsdoc-import-path-plugin.js | 21 ++++ support/jsdoc/jsdoc.json | 20 ++++ 8 files changed, 215 insertions(+), 207 deletions(-) create mode 100644 docs/styles/jsdoc-custom.css delete mode 100644 support/fix-jsdoc-html.js delete mode 100644 support/jsdoc-import-path-plugin.js delete mode 100644 support/jsdoc.json create mode 100644 support/jsdoc/jsdoc-custom.css create mode 100644 support/jsdoc/jsdoc-fix-html.js create mode 100644 support/jsdoc/jsdoc-import-path-plugin.js create mode 100644 support/jsdoc/jsdoc.json diff --git a/docs/styles/jsdoc-custom.css b/docs/styles/jsdoc-custom.css new file mode 100644 index 0000000..04316d7 --- /dev/null +++ b/docs/styles/jsdoc-custom.css @@ -0,0 +1,3 @@ +.page-title { + padding-top: 12px; +} diff --git a/support/fix-jsdoc-html.js b/support/fix-jsdoc-html.js deleted file mode 100644 index 3a39fa7..0000000 --- a/support/fix-jsdoc-html.js +++ /dev/null @@ -1,166 +0,0 @@ -var async = require('../dist/async'); -var fs = require('fs-extra'); -var path = require('path'); - -var $ = require('cheerio'); -var _ = require('lodash'); - -var docsDir = path.join(__dirname, '../docs'); -var asyncFile = path.join(__dirname, '../dist/async.js'); - -var pageTitle = 'ASYNC'; - -var docFilename = 'docs.html'; -var mainModuleFile = 'module-async.html'; -var mainSectionId = '#main'; -var sectionTitleClass = '.page-title' - -var HTMLFileBegin = '\n\n\n'; -var HTMLFileHeadBodyJoin = '\n'; -var HTMLFileEnd = ''; - -var pageTitlePadding = '12px'; - -var additionalFooterText = ' Documentation has been modified from the original. ' + - ' For more information, please see the async repository.'; - -fs.copySync(asyncFile, path.join(docsDir, 'scripts/async.js'), { clobber: 'true'}); - -function generateHTMLFile(filename, $page, callback) { - // generate an HTML file from a cheerio object - var HTMLdata = HTMLFileBegin + $page.find('head').html() - + HTMLFileHeadBodyJoin + $page.find('body').html() - + HTMLFileEnd; - - fs.writeFile(filename, HTMLdata, callback); -} - -function extractModuleFiles(files) { - return _.filter(files, function(file) { - return _.startsWith(file, 'module') && file !== mainModuleFile; - }); -} - -function combineFakeModules(files, callback) { - var moduleFiles = extractModuleFiles(files); - - fs.readFile(path.join(docsDir, mainModuleFile), 'utf8', function(err, mainModuleData) { - if (err) return callback(err); - - var $mainPage = $(mainModuleData); - // each 'module' (category) has a separate page, with all of the - // important information in a 'main' div. Combine all of these divs into - // one on the actual module page (async) - async.eachSeries(moduleFiles, function(file, fileCallback) { - fs.readFile(path.join(docsDir, file), 'utf8', function(err, moduleData) { - if (err) return fileCallback(err); - var $modulePage = $(moduleData); - var moduleName = $modulePage.find(sectionTitleClass).text(); - $modulePage.find(sectionTitleClass).attr('id', moduleName.toLowerCase()); - $mainPage.find(mainSectionId).append($modulePage.find(mainSectionId).html()); - return fileCallback(); - }); - }, function(err) { - if (err) return callback(err); - - generateHTMLFile(path.join(docsDir, docFilename), $mainPage, callback); - }); - }); -} - -function applyPreCheerioFixes(data) { - var fixedPageTitleStyle = '\n' - var closingHeadTag = '' - - var asyncScript = '\n'; - var closingBodyTag = ''; - - var rIncorrectCFText = />ControlFlowmodule:(\w+)\.(\w+)'+methodName+'<'; - }); -}; - -function fixToc($page, moduleFiles) { - // remove `async` listing from toc - $page.find('li').find('a[href="'+mainModuleFile+'"]').parent().remove(); - - // change toc title - $page.find('nav').children('h3').text(pageTitle); - - // make everything point to the same 'docs.html' page - _.each(moduleFiles, function(filename) { - $page.find('[href^="'+filename+'"]').each(function() { - var $ele = $(this); - var href = $ele.attr('href'); - - // category titles should sections title, while everything else - // points to the correct listing - if (href === filename) { - var moduleName = $ele.text().toLowerCase().replace(/\s/g, ''); - $ele.attr('href', docFilename+'#'+moduleName); - } else { - $ele.attr('href', href.replace(filename, docFilename)); - } - }); - }); -} - -function fixFooter($page) { - // add a note to the footer that the documentation has been modified - var $footer = $page.find('footer'); - var text = $footer.text(); - $footer.append(additionalFooterText); -}; - -function fixModuleLinks(files, callback) { - var moduleFiles = extractModuleFiles(files); - - async.each(files, function(file, fileCallback) { - var filePath = path.join(docsDir, file); - fs.readFile(filePath, 'utf8', function(err, fileData) { - if (err) return fileCallback(err); - var $file = $(applyPreCheerioFixes(fileData)); - - fixToc($file, moduleFiles); - - fixFooter($file); - $file.find('[href="'+mainModuleFile+'"]').attr('href', docFilename); - generateHTMLFile(filePath, $file, fileCallback); - }); - }, callback); -} - -fs.readdir(docsDir, function(err, files) { - if (err) { - throw err; - } - - var HTMLFiles = _.filter(files, function(file) { - return path.extname(file) === '.html'; - }); - - combineFakeModules(HTMLFiles, function(err) { - if (err) throw err; - - HTMLFiles.push(docFilename); - - fixModuleLinks(HTMLFiles, function(err) { - if (err) throw err; - console.log('Docs generated successfully'); - }); - }); -}); diff --git a/support/jsdoc-import-path-plugin.js b/support/jsdoc-import-path-plugin.js deleted file mode 100644 index 3f0937f..0000000 --- a/support/jsdoc-import-path-plugin.js +++ /dev/null @@ -1,21 +0,0 @@ -const path = require('path'); - -exports.handlers = { - jsdocCommentFound: function(e) { - var moduleName = path.parse(e.filename).name; - - - var lines = e.comment.split(/\r?\n/); - - var importLines = [ - '```', - `import ${moduleName} from 'async/${moduleName}';`, - '```' - ]; - - if (moduleName !== 'index') { - e.comment = [lines[0], ...importLines, ...lines.slice(1)].join("\n"); - } - - } -}; diff --git a/support/jsdoc.json b/support/jsdoc.json deleted file mode 100644 index a0e0daa..0000000 --- a/support/jsdoc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "tags": { - "allowUnknownTags": true, - "dictionaries": ["jsdoc"] - }, - "source": { - "include": [ "./lib" ] - }, - "plugins": ["plugins/markdown", "./jsdoc-import-path-plugin"], - "opts": { - "readme": "README.md", - "template": "node_modules/minami", - "encoding": "utf8", - "destination": "./docs", - "recurse": true - }, - "templates": { - "cleverLinks": false - } -} diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css new file mode 100644 index 0000000..04316d7 --- /dev/null +++ b/support/jsdoc/jsdoc-custom.css @@ -0,0 +1,3 @@ +.page-title { + padding-top: 12px; +} diff --git a/support/jsdoc/jsdoc-fix-html.js b/support/jsdoc/jsdoc-fix-html.js new file mode 100644 index 0000000..669225d --- /dev/null +++ b/support/jsdoc/jsdoc-fix-html.js @@ -0,0 +1,168 @@ +var async = require('../../dist/async'); +var fs = require('fs-extra'); +var path = require('path'); + +var $ = require('cheerio'); +var _ = require('lodash'); + +var docsDir = path.join(__dirname, '../../docs'); +var asyncFile = path.join(__dirname, '../../dist/async.js'); +var customStyleSheet = path.join(__dirname, './jsdoc-custom.css'); + +var pageTitle = 'ASYNC'; + +var docFilename = 'docs.html'; +var mainModuleFile = 'module-async.html'; +var mainSectionId = '#main'; +var sectionTitleClass = '.page-title' + +var HTMLFileBegin = '\n\n\n'; +var HTMLFileHeadBodyJoin = '\n'; +var HTMLFileEnd = ''; + +var pageTitlePadding = '12px'; + +var additionalFooterText = ' Documentation has been modified from the original. ' + + ' For more information, please see the async repository.'; + +function generateHTMLFile(filename, $page, callback) { + // generate an HTML file from a cheerio object + var HTMLdata = HTMLFileBegin + $page.find('head').html() + + HTMLFileHeadBodyJoin + $page.find('body').html() + + HTMLFileEnd; + + fs.writeFile(filename, HTMLdata, callback); +} + +function extractModuleFiles(files) { + return _.filter(files, function(file) { + return _.startsWith(file, 'module') && file !== mainModuleFile; + }); +} + +function combineFakeModules(files, callback) { + var moduleFiles = extractModuleFiles(files); + + fs.readFile(path.join(docsDir, mainModuleFile), 'utf8', function(err, mainModuleData) { + if (err) return callback(err); + + var $mainPage = $(mainModuleData); + // each 'module' (category) has a separate page, with all of the + // important information in a 'main' div. Combine all of these divs into + // one on the actual module page (async) + async.eachSeries(moduleFiles, function(file, fileCallback) { + fs.readFile(path.join(docsDir, file), 'utf8', function(err, moduleData) { + if (err) return fileCallback(err); + var $modulePage = $(moduleData); + var moduleName = $modulePage.find(sectionTitleClass).text(); + $modulePage.find(sectionTitleClass).attr('id', moduleName.toLowerCase()); + $mainPage.find(mainSectionId).append($modulePage.find(mainSectionId).html()); + return fileCallback(); + }); + }, function(err) { + if (err) return callback(err); + + generateHTMLFile(path.join(docsDir, docFilename), $mainPage, callback); + }); + }); +} + +function applyPreCheerioFixes(data) { + var customStyle = '\n' + var closingHeadTag = '' + + var asyncScript = '\n'; + var closingBodyTag = ''; + + var rIncorrectCFText = />ControlFlowmodule:(\w+)\.(\w+)'+methodName+'<'; + }); +}; + +function fixToc($page, moduleFiles) { + // remove `async` listing from toc + $page.find('li').find('a[href="'+mainModuleFile+'"]').parent().remove(); + + // change toc title + $page.find('nav').children('h3').text(pageTitle); + + // make everything point to the same 'docs.html' page + _.each(moduleFiles, function(filename) { + $page.find('[href^="'+filename+'"]').each(function() { + var $ele = $(this); + var href = $ele.attr('href'); + + // category titles should sections title, while everything else + // points to the correct listing + if (href === filename) { + var moduleName = $ele.text().toLowerCase().replace(/\s/g, ''); + $ele.attr('href', docFilename+'#'+moduleName); + } else { + $ele.attr('href', href.replace(filename, docFilename)); + } + }); + }); +} + +function fixFooter($page) { + // add a note to the footer that the documentation has been modified + var $footer = $page.find('footer'); + var text = $footer.text(); + $footer.append(additionalFooterText); +}; + +function fixModuleLinks(files, callback) { + var moduleFiles = extractModuleFiles(files); + + async.each(files, function(file, fileCallback) { + var filePath = path.join(docsDir, file); + fs.readFile(filePath, 'utf8', function(err, fileData) { + if (err) return fileCallback(err); + var $file = $(applyPreCheerioFixes(fileData)); + + fixToc($file, moduleFiles); + + fixFooter($file); + $file.find('[href="'+mainModuleFile+'"]').attr('href', docFilename); + generateHTMLFile(filePath, $file, fileCallback); + }); + }, callback); +} + +fs.copySync(asyncFile, path.join(docsDir, 'scripts/async.js'), { clobber: 'true'}); +fs.copySync(customStyleSheet, path.join(docsDir, 'styles/jsdoc-custom.css'), { clobber: 'true'}); + +fs.readdir(docsDir, function(err, files) { + if (err) { + throw err; + } + + var HTMLFiles = _.filter(files, function(file) { + return path.extname(file) === '.html'; + }); + + combineFakeModules(HTMLFiles, function(err) { + if (err) throw err; + + HTMLFiles.push(docFilename); + + fixModuleLinks(HTMLFiles, function(err) { + if (err) throw err; + console.log('Docs generated successfully'); + }); + }); +}); diff --git a/support/jsdoc/jsdoc-import-path-plugin.js b/support/jsdoc/jsdoc-import-path-plugin.js new file mode 100644 index 0000000..3f0937f --- /dev/null +++ b/support/jsdoc/jsdoc-import-path-plugin.js @@ -0,0 +1,21 @@ +const path = require('path'); + +exports.handlers = { + jsdocCommentFound: function(e) { + var moduleName = path.parse(e.filename).name; + + + var lines = e.comment.split(/\r?\n/); + + var importLines = [ + '```', + `import ${moduleName} from 'async/${moduleName}';`, + '```' + ]; + + if (moduleName !== 'index') { + e.comment = [lines[0], ...importLines, ...lines.slice(1)].join("\n"); + } + + } +}; diff --git a/support/jsdoc/jsdoc.json b/support/jsdoc/jsdoc.json new file mode 100644 index 0000000..a0e0daa --- /dev/null +++ b/support/jsdoc/jsdoc.json @@ -0,0 +1,20 @@ +{ + "tags": { + "allowUnknownTags": true, + "dictionaries": ["jsdoc"] + }, + "source": { + "include": [ "./lib" ] + }, + "plugins": ["plugins/markdown", "./jsdoc-import-path-plugin"], + "opts": { + "readme": "README.md", + "template": "node_modules/minami", + "encoding": "utf8", + "destination": "./docs", + "recurse": true + }, + "templates": { + "cleverLinks": false + } +} -- cgit v1.2.1 From c5813f8ef23fe1a46acdac178faa354b6fbaca7f Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Wed, 29 Jun 2016 01:41:24 -0400 Subject: jsdoc: added gulp for minifying and concating files --- docs/styles/jsdoc-custom.css | 3 --- gulpfile.js | 40 ++++++++++++++++++++++++++++++++++++++++ package.json | 14 ++++++++++++-- support/jsdoc/jsdoc-custom.js | 12 ++++++++++++ 4 files changed, 64 insertions(+), 5 deletions(-) delete mode 100644 docs/styles/jsdoc-custom.css create mode 100644 gulpfile.js create mode 100644 support/jsdoc/jsdoc-custom.js diff --git a/docs/styles/jsdoc-custom.css b/docs/styles/jsdoc-custom.css deleted file mode 100644 index 04316d7..0000000 --- a/docs/styles/jsdoc-custom.css +++ /dev/null @@ -1,3 +0,0 @@ -.page-title { - padding-top: 12px; -} diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..1634d43 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,40 @@ +var gulp = require('gulp'); + +var cleanCSS = require('gulp-clean-css'); +var concatCSS = require('gulp-concat-css'); +var rename = require('gulp-rename'); +var streamify = require('gulp-streamify'); +var sourcemaps = require('gulp-sourcemaps'); +var uglify = require('gulp-uglify'); + +var browserify = require('browserify'); +var buffer = require('vinyl-buffer'); +var source = require('vinyl-source-stream'); + +gulp.task('css', function() { + return gulp.src([ + 'node_modules/bootstrap/dist/css/bootstrap.css', + 'support/jsdoc/jsdoc-custom.css' + ]) + .pipe(sourcemaps.init()) + .pipe(concatCSS('jsdoc-custom.css')) + .pipe(cleanCSS({compatibility: 'ie8'})) + .pipe(rename({suffix: '.min'})) + .pipe(sourcemaps.write()) + .pipe(gulp.dest('docs/styles')); +}); + +gulp.task('js', function() { + // http://stackoverflow.com/questions/24992980/how-to-uglify-output-with-browserify-in-gulp + return browserify('support/jsdoc/jsdoc-custom.js') + .bundle() + .pipe(source('jsdoc-custom.js')) + .pipe(buffer()) + .pipe(sourcemaps.init()) + .pipe(uglify()) + .pipe(rename({suffix: '.min'})) + .pipe(sourcemaps.write()) + .pipe(gulp.dest('docs/scripts')); +}); + +gulp.task('jsdoc', [ 'css', 'js' ]); diff --git a/package.json b/package.json index 55eb20d..a9eaa7b 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,8 @@ "babelify": "^7.2.0", "benchmark": "bestiejs/benchmark.js", "bluebird": "^2.9.32", + "bootstrap": "^3.3.6", + "browserify": "^13.0.1", "chai": "^3.1.0", "cheerio": "^0.20.0", "coveralls": "^2.11.2", @@ -37,7 +39,13 @@ "esdoc": "^0.4.7", "eslint": "^2.11.1", "fs-extra": "^0.26.7", - "ink-docstrap": "^1.2.1", + "gulp": "^3.9.1", + "gulp-clean-css": "^2.0.10", + "gulp-concat-css": "^2.3.0", + "gulp-rename": "^1.2.2", + "gulp-sourcemaps": "^1.6.0", + "gulp-uglify": "^1.5.4", + "jquery": "^3.0.0", "jsdoc": "^3.4.0", "karma": "^0.13.2", "karma-browserify": "^4.2.1", @@ -56,13 +64,15 @@ "rsvp": "^3.0.18", "semver": "^4.3.6", "uglify-js": "~2.4.0", + "vinyl-buffer": "^1.0.0", + "vinyl-source-stream": "^1.1.0", "yargs": "~3.9.1" }, "scripts": { "coverage": "nyc npm test && nyc report", "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", "doc": "esdoc -c ./support/esdoc.json", - "jsdocs": "jsdoc -c ./support/jsdoc.json && node support/fix-jsdoc-html.js", + "jsdocs": "jsdoc -c ./support/jsdoc/jsdoc.json && node support/jsdoc/jsdoc-fix-html.js && gulp jsdoc", "lint": "eslint lib/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ karma.conf.js", "mocha-browser-test": "karma start", "mocha-node-test": "mocha mocha_test/ --compilers js:babel-core/register", diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js new file mode 100644 index 0000000..2d942de --- /dev/null +++ b/support/jsdoc/jsdoc-custom.js @@ -0,0 +1,12 @@ +var async = require('../../dist/async.js'); +var $ = require('jquery'); + +defineGlobal('$', $); +defineGlobal('jQuery', $); +defineGlobal('async', async); + +require('bootstrap'); + +function defineGlobal(name, lib) { + global[name] = lib; +} -- cgit v1.2.1 From b1b866ee4702c7248f41448a8a561fc4a06a0ae5 Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Thu, 23 Jun 2016 03:28:11 -0400 Subject: jsdoc: added fixed header (using jsdelivr for jQuery, no gulpfile) --- gulpfile.js | 40 --------------------------- package.json | 11 +------- support/jsdoc/head-data.html | 3 ++ support/jsdoc/jsdoc-custom.css | 32 +++++++++++++++++++++ support/jsdoc/jsdoc-custom.js | 23 ++++++++++------ support/jsdoc/jsdoc-fix-html.js | 61 +++++++++++++++++++++++++++++------------ support/jsdoc/navbar.html | 47 +++++++++++++++++++++++++++++++ 7 files changed, 140 insertions(+), 77 deletions(-) delete mode 100644 gulpfile.js create mode 100644 support/jsdoc/head-data.html create mode 100644 support/jsdoc/navbar.html diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 1634d43..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,40 +0,0 @@ -var gulp = require('gulp'); - -var cleanCSS = require('gulp-clean-css'); -var concatCSS = require('gulp-concat-css'); -var rename = require('gulp-rename'); -var streamify = require('gulp-streamify'); -var sourcemaps = require('gulp-sourcemaps'); -var uglify = require('gulp-uglify'); - -var browserify = require('browserify'); -var buffer = require('vinyl-buffer'); -var source = require('vinyl-source-stream'); - -gulp.task('css', function() { - return gulp.src([ - 'node_modules/bootstrap/dist/css/bootstrap.css', - 'support/jsdoc/jsdoc-custom.css' - ]) - .pipe(sourcemaps.init()) - .pipe(concatCSS('jsdoc-custom.css')) - .pipe(cleanCSS({compatibility: 'ie8'})) - .pipe(rename({suffix: '.min'})) - .pipe(sourcemaps.write()) - .pipe(gulp.dest('docs/styles')); -}); - -gulp.task('js', function() { - // http://stackoverflow.com/questions/24992980/how-to-uglify-output-with-browserify-in-gulp - return browserify('support/jsdoc/jsdoc-custom.js') - .bundle() - .pipe(source('jsdoc-custom.js')) - .pipe(buffer()) - .pipe(sourcemaps.init()) - .pipe(uglify()) - .pipe(rename({suffix: '.min'})) - .pipe(sourcemaps.write()) - .pipe(gulp.dest('docs/scripts')); -}); - -gulp.task('jsdoc', [ 'css', 'js' ]); diff --git a/package.json b/package.json index a9eaa7b..5c9006b 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,6 @@ "babelify": "^7.2.0", "benchmark": "bestiejs/benchmark.js", "bluebird": "^2.9.32", - "bootstrap": "^3.3.6", - "browserify": "^13.0.1", "chai": "^3.1.0", "cheerio": "^0.20.0", "coveralls": "^2.11.2", @@ -39,13 +37,6 @@ "esdoc": "^0.4.7", "eslint": "^2.11.1", "fs-extra": "^0.26.7", - "gulp": "^3.9.1", - "gulp-clean-css": "^2.0.10", - "gulp-concat-css": "^2.3.0", - "gulp-rename": "^1.2.2", - "gulp-sourcemaps": "^1.6.0", - "gulp-uglify": "^1.5.4", - "jquery": "^3.0.0", "jsdoc": "^3.4.0", "karma": "^0.13.2", "karma-browserify": "^4.2.1", @@ -72,7 +63,7 @@ "coverage": "nyc npm test && nyc report", "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", "doc": "esdoc -c ./support/esdoc.json", - "jsdocs": "jsdoc -c ./support/jsdoc/jsdoc.json && node support/jsdoc/jsdoc-fix-html.js && gulp jsdoc", + "jsdocs": "jsdoc -c ./support/jsdoc/jsdoc.json && node support/jsdoc/jsdoc-fix-html.js", "lint": "eslint lib/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ karma.conf.js", "mocha-browser-test": "karma start", "mocha-node-test": "mocha mocha_test/ --compilers js:babel-core/register", diff --git a/support/jsdoc/head-data.html b/support/jsdoc/head-data.html new file mode 100644 index 0000000..74ed991 --- /dev/null +++ b/support/jsdoc/head-data.html @@ -0,0 +1,3 @@ + + + diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index 04316d7..4209b6e 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -1,3 +1,35 @@ .page-title { padding-top: 12px; } + +.navbar-top { + position: fixed; + height: 50px; + width: 100%; + z-index: 10; + top: 0; + left: 0; + background-color: #101010; +} + +body { + height: 100%; + width: 100%; + padding-left: 0px; +} + +body nav { + float: none; + position: fixed; + top: 50px; + left: 0px; + bottom: 0px; + padding-left: 12px; + overflow-y: auto; +} + +#main { + float: none; + margin-left: 250px; + padding-top: 50px; +} diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index 2d942de..3513a4d 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -1,12 +1,17 @@ -var async = require('../../dist/async.js'); -var $ = require('jquery'); - -defineGlobal('$', $); -defineGlobal('jQuery', $); -defineGlobal('async', async); +// https://github.com/twbs/bootstrap/issues/1768 +function shiftWindow() { + scrollBy(0, -50); +} -require('bootstrap'); +function fixAnchorPosition() { + if (location.hash) { + shiftWindow(); + } +} -function defineGlobal(name, lib) { - global[name] = lib; +function init() { + fixAnchorPosition(); + window.addEventListener("hashchange", shiftWindow); } + +$(init); diff --git a/support/jsdoc/jsdoc-fix-html.js b/support/jsdoc/jsdoc-fix-html.js index 669225d..10ebc0c 100644 --- a/support/jsdoc/jsdoc-fix-html.js +++ b/support/jsdoc/jsdoc-fix-html.js @@ -9,7 +9,7 @@ var docsDir = path.join(__dirname, '../../docs'); var asyncFile = path.join(__dirname, '../../dist/async.js'); var customStyleSheet = path.join(__dirname, './jsdoc-custom.css'); -var pageTitle = 'ASYNC'; +var pageTitle = 'Methods:'; var docFilename = 'docs.html'; var mainModuleFile = 'module-async.html'; @@ -67,11 +67,10 @@ function combineFakeModules(files, callback) { }); } -function applyPreCheerioFixes(data) { - var customStyle = '\n' +function applyPreCheerioFixes(data, headLinks) { var closingHeadTag = '' - var asyncScript = '\n'; + var customScript = '\n'; var closingBodyTag = ''; var rIncorrectCFText = />ControlFlowmodule:(\w+)\.(\w+)'); + // $body.find('div').prepend($bodyContent); + $body.prepend($headerContent); + // $mainContent.wrap('
'); + // $file.find('nav').wrap('
'); + // $file.find('footer').appendTo($mainContent); +}; + function fixToc($page, moduleFiles) { // remove `async` listing from toc $page.find('li').find('a[href="'+mainModuleFile+'"]').parent().remove(); // change toc title $page.find('nav').children('h3').text(pageTitle); + $page.find('nav').children('h2').remove(); // make everything point to the same 'docs.html' page _.each(moduleFiles, function(filename) { @@ -128,23 +141,35 @@ function fixFooter($page) { function fixModuleLinks(files, callback) { var moduleFiles = extractModuleFiles(files); - async.each(files, function(file, fileCallback) { - var filePath = path.join(docsDir, file); - fs.readFile(filePath, 'utf8', function(err, fileData) { + async.map(['head-data.html', 'navbar.html'], function(filename, fileCallback) { + fs.readFile(path.join(__dirname, filename), 'utf8', function(err, data) { if (err) return fileCallback(err); - var $file = $(applyPreCheerioFixes(fileData)); + return fileCallback(null, data); + }); + }, function(err, results) { + if (err) return callback(err); - fixToc($file, moduleFiles); + var $headerContent = $(results[1]); + async.each(files, function(file, fileCallback) { + var filePath = path.join(docsDir, file); + fs.readFile(filePath, 'utf8', function(err, fileData) { + if (err) return fileCallback(err); + var $file = $(applyPreCheerioFixes(fileData, results[0])); - fixFooter($file); - $file.find('[href="'+mainModuleFile+'"]').attr('href', docFilename); - generateHTMLFile(filePath, $file, fileCallback); - }); - }, callback); + addStaticHeader($file, $headerContent); + fixToc($file, moduleFiles); + fixFooter($file); + $file.find('[href="'+mainModuleFile+'"]').attr('href', docFilename); + generateHTMLFile(filePath, $file, fileCallback); + }); + }, callback); + }); } -fs.copySync(asyncFile, path.join(docsDir, 'scripts/async.js'), { clobber: 'true'}); -fs.copySync(customStyleSheet, path.join(docsDir, 'styles/jsdoc-custom.css'), { clobber: 'true'}); +fs.copySync(path.join(__dirname, '../../dist/async.js'), path.join(docsDir, 'scripts/async.js'), { clobber: true }); +fs.copySync(path.join(__dirname, './jsdoc-custom.js'), path.join(docsDir, 'scripts/jsdoc-custom.js'), { clobber: true }); +fs.copySync(path.join(__dirname, './jsdoc-custom.css'), path.join(docsDir, 'styles/jsdoc-custom.css'), { clobber: true }); + fs.readdir(docsDir, function(err, files) { if (err) { diff --git a/support/jsdoc/navbar.html b/support/jsdoc/navbar.html new file mode 100644 index 0000000..083c92d --- /dev/null +++ b/support/jsdoc/navbar.html @@ -0,0 +1,47 @@ + + + -- cgit v1.2.1 From be65c0d2b4286dde3805fce5a4f051261b10c2af Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Wed, 29 Jun 2016 01:45:59 -0400 Subject: jsdoc: added searchbar, need to still implement functionality @megawac --- package.json | 2 +- support/jsdoc/head-data.html | 8 +++++- support/jsdoc/jsdoc-custom.css | 6 +++++ support/jsdoc/jsdoc-custom.js | 37 +++++++++++++++++++++++++- support/jsdoc/jsdoc-fix-html.js | 57 +++++++++++++++++++++++++++++------------ support/jsdoc/navbar.html | 14 +++++----- 6 files changed, 96 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 5c9006b..250e062 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "coverage": "nyc npm test && nyc report", "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", "doc": "esdoc -c ./support/esdoc.json", - "jsdocs": "jsdoc -c ./support/jsdoc/jsdoc.json && node support/jsdoc/jsdoc-fix-html.js", + "jsdoc": "jsdoc -c ./support/jsdoc/jsdoc.json && node support/jsdoc/jsdoc-fix-html.js", "lint": "eslint lib/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ karma.conf.js", "mocha-browser-test": "karma start", "mocha-node-test": "mocha mocha_test/ --compilers js:babel-core/register", diff --git a/support/jsdoc/head-data.html b/support/jsdoc/head-data.html index 74ed991..6ecc3eb 100644 --- a/support/jsdoc/head-data.html +++ b/support/jsdoc/head-data.html @@ -1,3 +1,9 @@ + + + + + + + - diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index 4209b6e..b2ab483 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -33,3 +33,9 @@ body nav { margin-left: 250px; padding-top: 50px; } + +.tt-menu { + background-color: white; + z-index: 11; + overflow-y: auto; +} diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index 3513a4d..2b7871f 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -9,9 +9,44 @@ function fixAnchorPosition() { } } +function initSearchBar() { + var methodNames = new Bloodhound({ + datumTokenizer: Bloodhound.tokenizers.whitespace, + queryTokenizer: Bloodhound.tokenizers.whitespace, + prefetch: './methodNames.json' + }); + + var sourceFiles = new Bloodhound({ + datumTokenizer: Bloodhound.tokenizers.whitespace, + queryTokenizer: Bloodhound.tokenizers.whitespace, + prefetch: './sourceFiles.json' + }); + + $('.typeahead').typeahead({ + hint: true, + highlight: true, + minLength: 1 + }, + { + name: 'Methods', + source: methodNames, + templates: { + header: '

Methods

' + } + }, + { + name: 'Files', + source: sourceFiles, + templates: { + header: '

Source Files

' + } + }); +} + function init() { fixAnchorPosition(); - window.addEventListener("hashchange", shiftWindow); + window.addEventListener("hashchange", shiftWindow, false); + initSearchBar(); } $(init); diff --git a/support/jsdoc/jsdoc-fix-html.js b/support/jsdoc/jsdoc-fix-html.js index 10ebc0c..8ebc618 100644 --- a/support/jsdoc/jsdoc-fix-html.js +++ b/support/jsdoc/jsdoc-fix-html.js @@ -40,6 +40,29 @@ function extractModuleFiles(files) { }); } +function getSearchableInfo($page, callback) { + var $sourceLinks = $page.find('a[href$=".js.html"]'); + var sourceFiles = $sourceLinks.map(function() { + return $(this).attr('href'); + }).toArray().sort(); + + var $methodLinks = $page.find('nav').find('a'); + var methods = $methodLinks.map(function() { + var methodName = $(this).text(); + return (methodName === 'Home' ? null : methodName); + }).toArray().sort(); + + fs.mkdirsSync(path.join(docsDir, 'data')); + async.parallel([ + function(fileCallback) { + fs.writeJson(path.join(docsDir, 'data/sourceFiles.json'), sourceFiles, fileCallback); + }, + function(fileCallback) { + fs.writeJson(path.join(docsDir, 'data/methodNames.json'), methods, fileCallback); + } + ], callback); +} + function combineFakeModules(files, callback) { var moduleFiles = extractModuleFiles(files); @@ -62,7 +85,10 @@ function combineFakeModules(files, callback) { }, function(err) { if (err) return callback(err); - generateHTMLFile(path.join(docsDir, docFilename), $mainPage, callback); + getSearchableInfo($mainPage, function(err) { + if (err) return callback(err); + generateHTMLFile(path.join(docsDir, docFilename), $mainPage, callback); + }); }); }); } @@ -95,14 +121,7 @@ function applyPreCheerioFixes(data, headLinks) { function addStaticHeader($file, $headerContent) { var $body = $file.find('body'); var $mainContent = $body.find('#main'); - // var $bodyContent = $body.children(); - // $body.children().remove(); - // $body.prepend('
'); - // $body.find('div').prepend($bodyContent); $body.prepend($headerContent); - // $mainContent.wrap('
'); - // $file.find('nav').wrap('
'); - // $file.find('footer').appendTo($mainContent); }; function fixToc($page, moduleFiles) { @@ -170,7 +189,6 @@ fs.copySync(path.join(__dirname, '../../dist/async.js'), path.join(docsDir, 'scr fs.copySync(path.join(__dirname, './jsdoc-custom.js'), path.join(docsDir, 'scripts/jsdoc-custom.js'), { clobber: true }); fs.copySync(path.join(__dirname, './jsdoc-custom.css'), path.join(docsDir, 'styles/jsdoc-custom.css'), { clobber: true }); - fs.readdir(docsDir, function(err, files) { if (err) { throw err; @@ -180,14 +198,19 @@ fs.readdir(docsDir, function(err, files) { return path.extname(file) === '.html'; }); - combineFakeModules(HTMLFiles, function(err) { + async.waterfall([ + function(callback) { + combineFakeModules(HTMLFiles, function(err) { + if (err) return callback(err); + HTMLFiles.push(docFilename); + return callback(null); + }); + }, + function(callback) { + fixModuleLinks(HTMLFiles, callback); + } + ], function(err) { if (err) throw err; - - HTMLFiles.push(docFilename); - - fixModuleLinks(HTMLFiles, function(err) { - if (err) throw err; - console.log('Docs generated successfully'); - }); + console.log('Docs generated successfully'); }); }); diff --git a/support/jsdoc/navbar.html b/support/jsdoc/navbar.html index 083c92d..ef20e2b 100644 --- a/support/jsdoc/navbar.html +++ b/support/jsdoc/navbar.html @@ -1,8 +1,4 @@ - - + + -- cgit v1.2.1 From c45cab8d6ace1baa6044d0d6421196601f3e3c19 Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Mon, 27 Jun 2016 11:27:08 -0400 Subject: Updated nav /cc @hargasinki --- support/jsdoc/jsdoc-custom.css | 17 +++++----- support/jsdoc/navbar.html | 73 ++++++++++++++++-------------------------- 2 files changed, 37 insertions(+), 53 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index b2ab483..78e5668 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -2,16 +2,14 @@ padding-top: 12px; } -.navbar-top { - position: fixed; - height: 50px; - width: 100%; - z-index: 10; - top: 0; - left: 0; +.navbar-fixed-top { background-color: #101010; } +.navbar .ion-social-github { + font-size: 1.2em; +} + body { height: 100%; width: 100%; @@ -31,7 +29,10 @@ body nav { #main { float: none; margin-left: 250px; - padding-top: 50px; + position: fixed; + top: 50px; + overflow-y: auto; + height: 100%; } .tt-menu { diff --git a/support/jsdoc/navbar.html b/support/jsdoc/navbar.html index ef20e2b..996c1ce 100644 --- a/support/jsdoc/navbar.html +++ b/support/jsdoc/navbar.html @@ -1,45 +1,28 @@ - + \ No newline at end of file -- cgit v1.2.1 From 22bced8a054fd5bca76247ea38e7e46836629fbf Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Mon, 27 Jun 2016 17:11:46 -0400 Subject: Fix search, WIP search linking --- README.md | 12 +++++++++--- support/jsdoc/jsdoc-custom.css | 11 ++++++++--- support/jsdoc/jsdoc-custom.js | 26 +++++--------------------- support/jsdoc/navbar.html | 4 ++-- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 51c9903..6e07343 100644 --- a/README.md +++ b/README.md @@ -161,11 +161,15 @@ The source is available for download from [GitHub](https://raw.githubusercontent.com/caolan/async/master/dist/async.min.js). Alternatively, you can install using npm: - npm install --save async +```bash +$ npm install --save async +``` As well as using Bower: - bower install async +```bash +$ bower install async +``` You can then `require()` async as normal: @@ -203,7 +207,9 @@ Usage: We also provide async as a collection of ES2015 modules, in an alternative `async-es` package on npm. - npm i -S async-es +```bash +$ npm install --save async-es +``` ```js import waterfall from 'async-es/waterfall'; diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index 78e5668..2a96957 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -6,6 +6,10 @@ background-color: #101010; } +.navbar-fixed-top .navbar-right { + padding-right: 10px; +} + .navbar .ion-social-github { font-size: 1.2em; } @@ -27,12 +31,13 @@ body nav { } #main { + position: fixed; float: none; + overflow-y: auto; margin-left: 250px; - position: fixed; + top: 50px; - overflow-y: auto; - height: 100%; + height: calc(100% - 50px); } .tt-menu { diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index 2b7871f..5072fb7 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -1,15 +1,4 @@ -// https://github.com/twbs/bootstrap/issues/1768 -function shiftWindow() { - scrollBy(0, -50); -} - -function fixAnchorPosition() { - if (location.hash) { - shiftWindow(); - } -} - -function initSearchBar() { +$(function initSearchBar() { var methodNames = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.whitespace, queryTokenizer: Bloodhound.tokenizers.whitespace, @@ -40,13 +29,8 @@ function initSearchBar() { templates: { header: '

Source Files

' } + }).on('typeahead:select', function(ev, suggestion) { + var $el = document.getElementById('.' + suggestion) + $('html, body').animate({ scrollTop: $el.offsetTop }, 500); }); -} - -function init() { - fixAnchorPosition(); - window.addEventListener("hashchange", shiftWindow, false); - initSearchBar(); -} - -$(init); +}); diff --git a/support/jsdoc/navbar.html b/support/jsdoc/navbar.html index 996c1ce..e23b12e 100644 --- a/support/jsdoc/navbar.html +++ b/support/jsdoc/navbar.html @@ -16,12 +16,12 @@
  • Home
  • Docs
  • -
  • +
  • -- cgit v1.2.1 From dce18f0924ebc29f7a9a2eaaab692fe7bc8b7bab Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Tue, 28 Jun 2016 00:43:32 -0400 Subject: fixed searhing issues --- support/jsdoc/jsdoc-custom.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index 5072fb7..925847b 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -30,7 +30,18 @@ $(function initSearchBar() { header: '

    Source Files

    ' } }).on('typeahead:select', function(ev, suggestion) { - var $el = document.getElementById('.' + suggestion) - $('html, body').animate({ scrollTop: $el.offsetTop }, 500); + var protocol = window.location.protocol + var host = window.location.host; + var currentPath = window.location.pathname; + // handle searching source files + if (suggestion.indexOf('.html') !== -1) { + window.location.href = protocol + '//' + host + '/' + suggestion; + // handle searching from one of the source files or the home page + } else if (currentPath !== '/docs.html') { + window.location.href = protocol + '//' + host + '/docs.html#.' + suggestion; + } else { + var $el = document.getElementById('.' + suggestion); + $('#main').animate({ scrollTop: $el.offsetTop }, 500); + } }); }); -- cgit v1.2.1 From 01b0a19ec8427c799a5ebc28b1d1160e1b4bb915 Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Tue, 28 Jun 2016 01:06:04 -0400 Subject: jsdoc: improved tt-menu styling, closes #8, @megawac --- support/jsdoc/jsdoc-custom.css | 20 +++++++++++++++++++- support/jsdoc/jsdoc-custom.js | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index 2a96957..845de0b 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -35,13 +35,31 @@ body nav { float: none; overflow-y: auto; margin-left: 250px; - top: 50px; height: calc(100% - 50px); } .tt-menu { background-color: white; + padding: 10px; + width: 100%; + border-radius: 4px; + border: 1px solid #D3D3D3; z-index: 11; overflow-y: auto; } + +.tt-cursor { + background-color: #D3D3D3; +} + +.search-bar-header-first { + margin: 5px 0px; + border-bottom: 1px solid #D3D3D3; +} + +.search-bar-header { + margin: 5px 0px; + border-top: 1px solid #D3D3D3; + border-bottom: 1px solid #D3D3D3; +} diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index 925847b..a59a58a 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -20,7 +20,7 @@ $(function initSearchBar() { name: 'Methods', source: methodNames, templates: { - header: '

    Methods

    ' + header: '

    Methods

    ' } }, { -- cgit v1.2.1 From 93c24e117e1112b10a1995083fca8190723fd746 Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Tue, 28 Jun 2016 01:52:51 -0400 Subject: jsdoc: added searching through issues, @megawac --- support/jsdoc/jsdoc-custom.js | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index a59a58a..06dc503 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -11,6 +11,31 @@ $(function initSearchBar() { prefetch: './sourceFiles.json' }); + var githubIssues = new Bloodhound({ + datumTokenizer: Bloodhound.tokenizers.whitespace, + queryTokenizer: Bloodhound.tokenizers.whitespace, + remote: { + url: 'https://api.github.com/search/issues?q=%QUERY+repo:caolan/async', + cache: false, + wildcard: '%QUERY', + transform: function(response) { + return $.map(response.items, function(issue) { + // if (issue.state !== 'open') { + // return null; + // } + return { + url: issue.html_url, + name: issue.number + ': ' + issue.title, + number: issue.number + }; + }).sort(function(a, b) { + return b.number - a.number; + }); + } + } + }); + + $('.typeahead').typeahead({ hint: true, highlight: true, @@ -29,12 +54,23 @@ $(function initSearchBar() { templates: { header: '

    Source Files

    ' } + }, + { + name: 'Issues', + source: githubIssues, + display: 'name', + templates: { + header: '

    Issues

    ' + } }).on('typeahead:select', function(ev, suggestion) { var protocol = window.location.protocol var host = window.location.host; var currentPath = window.location.pathname; - // handle searching source files - if (suggestion.indexOf('.html') !== -1) { + // handle issues + if (typeof suggestion !== 'string') { + window.location.href = suggestion.url; + // handle source files + } else if (suggestion.indexOf('.html') !== -1) { window.location.href = protocol + '//' + host + '/' + suggestion; // handle searching from one of the source files or the home page } else if (currentPath !== '/docs.html') { -- cgit v1.2.1 From cbf97ead6fd117155610c6e180a1a0785c131250 Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Tue, 28 Jun 2016 02:49:57 -0400 Subject: jsdoc: added substr matching, closes #9, @megawac --- support/jsdoc/jsdoc-custom.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index 06dc503..6aae265 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -1,12 +1,26 @@ +function matchSubstrs(methodName) { + var tokens = []; + + var len = methodName.length; + + for (var size = 1; size <= len; size++){ + for (var i = 0; i+size<= len; i++){ + tokens.push(methodName.substr(i, size)); + } + } + + return tokens; +} + $(function initSearchBar() { var methodNames = new Bloodhound({ - datumTokenizer: Bloodhound.tokenizers.whitespace, + datumTokenizer: matchSubstrs, queryTokenizer: Bloodhound.tokenizers.whitespace, prefetch: './methodNames.json' }); var sourceFiles = new Bloodhound({ - datumTokenizer: Bloodhound.tokenizers.whitespace, + datumTokenizer: matchSubstrs, queryTokenizer: Bloodhound.tokenizers.whitespace, prefetch: './sourceFiles.json' }); @@ -16,7 +30,7 @@ $(function initSearchBar() { queryTokenizer: Bloodhound.tokenizers.whitespace, remote: { url: 'https://api.github.com/search/issues?q=%QUERY+repo:caolan/async', - cache: false, + cache: true, wildcard: '%QUERY', transform: function(response) { return $.map(response.items, function(issue) { -- cgit v1.2.1 From b2f314f74c11364268e280735a457dd8183b310b Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Tue, 28 Jun 2016 03:01:03 -0400 Subject: final tweaks before publishing --- support/jsdoc/jsdoc-custom.css | 4 ++++ support/jsdoc/jsdoc-custom.js | 10 ++++++++-- support/jsdoc/jsdoc-fix-html.js | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index 845de0b..8a1ed46 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -30,6 +30,10 @@ body nav { overflow-y: auto; } +footer { + margin-left: 0px; +} + #main { position: fixed; float: none; diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index 6aae265..3dc26b0 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -16,13 +16,19 @@ $(function initSearchBar() { var methodNames = new Bloodhound({ datumTokenizer: matchSubstrs, queryTokenizer: Bloodhound.tokenizers.whitespace, - prefetch: './methodNames.json' + prefetch: { + url: './methodNames.json', + cache: false + } }); var sourceFiles = new Bloodhound({ datumTokenizer: matchSubstrs, queryTokenizer: Bloodhound.tokenizers.whitespace, - prefetch: './sourceFiles.json' + prefetch: { + url: './sourceFiles.json', + cache: false + } }); var githubIssues = new Bloodhound({ diff --git a/support/jsdoc/jsdoc-fix-html.js b/support/jsdoc/jsdoc-fix-html.js index 8ebc618..3541e91 100644 --- a/support/jsdoc/jsdoc-fix-html.js +++ b/support/jsdoc/jsdoc-fix-html.js @@ -155,6 +155,7 @@ function fixFooter($page) { var $footer = $page.find('footer'); var text = $footer.text(); $footer.append(additionalFooterText); + $page.find('#main').append($footer); }; function fixModuleLinks(files, callback) { -- cgit v1.2.1 From 0e11bf597567f3f0927cee293351fd017c33c680 Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Tue, 28 Jun 2016 12:41:04 -0400 Subject: Attempt to fix search on subroutes --- support/jsdoc/jsdoc-custom.js | 45 ++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index 3dc26b0..e86160c 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -1,18 +1,15 @@ -function matchSubstrs(methodName) { - var tokens = []; - - var len = methodName.length; - - for (var size = 1; size <= len; size++){ - for (var i = 0; i+size<= len; i++){ - tokens.push(methodName.substr(i, size)); +$(function initSearchBar() { + function matchSubstrs(methodName) { + var tokens = []; + var len = methodName.length; + for (var size = 1; size <= len; size++){ + for (var i = 0; i+size<= len; i++){ + tokens.push(methodName.substr(i, size)); + } } + return tokens; } - return tokens; -} - -$(function initSearchBar() { var methodNames = new Bloodhound({ datumTokenizer: matchSubstrs, queryTokenizer: Bloodhound.tokenizers.whitespace, @@ -55,7 +52,6 @@ $(function initSearchBar() { } }); - $('.typeahead').typeahead({ hint: true, highlight: true, @@ -83,18 +79,27 @@ $(function initSearchBar() { header: '

    Issues

    ' } }).on('typeahead:select', function(ev, suggestion) { - var protocol = window.location.protocol - var host = window.location.host; - var currentPath = window.location.pathname; + var host; + if (location.origin != "null") { + host = location.origin; + } else { + host = location.protocol + '//' + location.host; + } + + var _path = location.pathname.split("/"); + + var currentPage = _path[_path.length - 1]; + host += _path.slice(1, -1).join("/") + "/"; + // handle issues if (typeof suggestion !== 'string') { - window.location.href = suggestion.url; + location.href = suggestion.url; // handle source files } else if (suggestion.indexOf('.html') !== -1) { - window.location.href = protocol + '//' + host + '/' + suggestion; + location.href = host + suggestion; // handle searching from one of the source files or the home page - } else if (currentPath !== '/docs.html') { - window.location.href = protocol + '//' + host + '/docs.html#.' + suggestion; + } else if (currentPage !== 'docs.html') { + location.href = host + 'docs.html#.' + suggestion; } else { var $el = document.getElementById('.' + suggestion); $('#main').animate({ scrollTop: $el.offsetTop }, 500); -- cgit v1.2.1 From 66a6b67b55d9b5c5726fcc22cab98ba1e00ad503 Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Wed, 29 Jun 2016 02:10:33 -0400 Subject: added missing slash to searching on subroutes --- support/jsdoc/jsdoc-custom.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index e86160c..cb36d46 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -14,7 +14,7 @@ $(function initSearchBar() { datumTokenizer: matchSubstrs, queryTokenizer: Bloodhound.tokenizers.whitespace, prefetch: { - url: './methodNames.json', + url: './data/methodNames.json', cache: false } }); @@ -23,7 +23,7 @@ $(function initSearchBar() { datumTokenizer: matchSubstrs, queryTokenizer: Bloodhound.tokenizers.whitespace, prefetch: { - url: './sourceFiles.json', + url: './data/sourceFiles.json', cache: false } }); @@ -85,11 +85,11 @@ $(function initSearchBar() { } else { host = location.protocol + '//' + location.host; } - + var _path = location.pathname.split("/"); - + var currentPage = _path[_path.length - 1]; - host += _path.slice(1, -1).join("/") + "/"; + host += "/" + _path.slice(1, -1).join("/") + "/"; // handle issues if (typeof suggestion !== 'string') { -- cgit v1.2.1 From 38dc8712e023b6ea88507e0618fee03b05778d90 Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Wed, 29 Jun 2016 03:10:40 -0400 Subject: fixed eslint issues in jsdoc files --- support/jsdoc/jsdoc-custom.js | 11 ++++------- support/jsdoc/jsdoc-fix-html.js | 5 ----- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.js b/support/jsdoc/jsdoc-custom.js index cb36d46..a53aaf6 100644 --- a/support/jsdoc/jsdoc-custom.js +++ b/support/jsdoc/jsdoc-custom.js @@ -1,3 +1,4 @@ +/* eslint no-undef: "off" */ $(function initSearchBar() { function matchSubstrs(methodName) { var tokens = []; @@ -56,22 +57,19 @@ $(function initSearchBar() { hint: true, highlight: true, minLength: 1 - }, - { + }, { name: 'Methods', source: methodNames, templates: { header: '

    Methods

    ' } - }, - { + }, { name: 'Files', source: sourceFiles, templates: { header: '

    Source Files

    ' } - }, - { + }, { name: 'Issues', source: githubIssues, display: 'name', @@ -87,7 +85,6 @@ $(function initSearchBar() { } var _path = location.pathname.split("/"); - var currentPage = _path[_path.length - 1]; host += "/" + _path.slice(1, -1).join("/") + "/"; diff --git a/support/jsdoc/jsdoc-fix-html.js b/support/jsdoc/jsdoc-fix-html.js index 3541e91..bf7f6eb 100644 --- a/support/jsdoc/jsdoc-fix-html.js +++ b/support/jsdoc/jsdoc-fix-html.js @@ -6,8 +6,6 @@ var $ = require('cheerio'); var _ = require('lodash'); var docsDir = path.join(__dirname, '../../docs'); -var asyncFile = path.join(__dirname, '../../dist/async.js'); -var customStyleSheet = path.join(__dirname, './jsdoc-custom.css'); var pageTitle = 'Methods:'; @@ -20,7 +18,6 @@ var HTMLFileBegin = '\n\n\n'; var HTMLFileHeadBodyJoin = '\n'; var HTMLFileEnd = ''; -var pageTitlePadding = '12px'; var additionalFooterText = ' Documentation has been modified from the original. ' + ' For more information, please see the async repository.'; @@ -120,7 +117,6 @@ function applyPreCheerioFixes(data, headLinks) { function addStaticHeader($file, $headerContent) { var $body = $file.find('body'); - var $mainContent = $body.find('#main'); $body.prepend($headerContent); }; @@ -153,7 +149,6 @@ function fixToc($page, moduleFiles) { function fixFooter($page) { // add a note to the footer that the documentation has been modified var $footer = $page.find('footer'); - var text = $footer.text(); $footer.append(additionalFooterText); $page.find('#main').append($footer); }; -- cgit v1.2.1 From 6b9624a3ef86ff920866eaa9aff82a8b3a74529a Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Wed, 29 Jun 2016 10:22:50 -0400 Subject: Ensure all items are visible in TOC --- support/jsdoc/jsdoc-custom.css | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index 8a1ed46..5cac4b7 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -21,13 +21,11 @@ body { } body nav { - float: none; position: fixed; top: 50px; - left: 0px; - bottom: 0px; padding-left: 12px; overflow-y: auto; + height: calc(100% - 50px); } footer { -- cgit v1.2.1 From 308b799fc1d82278cb139e1b4e1c13d1c6b968d2 Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Wed, 29 Jun 2016 18:09:44 -0400 Subject: fix code and import path styling --- support/jsdoc/jsdoc-custom.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index 8a1ed46..746a278 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -30,6 +30,12 @@ body nav { overflow-y: auto; } +/* fix bootstrap's styling */ +pre { + background: #fff; + padding: 0px; +} + footer { margin-left: 0px; } -- cgit v1.2.1 From f2cd951d15326de4a585b264d57189658109f757 Mon Sep 17 00:00:00 2001 From: Ray Myers Date: Wed, 22 Jun 2016 18:24:00 -0700 Subject: Fixed callback being able to be called twice in asyncify --- lib/asyncify.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/asyncify.js b/lib/asyncify.js index e235311..dec39d2 100644 --- a/lib/asyncify.js +++ b/lib/asyncify.js @@ -68,7 +68,7 @@ export default function asyncify(func) { if (isObject(result) && typeof result.then === 'function') { result.then(function(value) { callback(null, value); - })['catch'](function(err) { + }, function(err) { callback(err.message ? err : new Error(err)); }); } else { -- cgit v1.2.1 From e2b466e6e7509909e4eccc0eba6a293f89b63a4f Mon Sep 17 00:00:00 2001 From: Ray Myers Date: Wed, 22 Jun 2016 18:51:06 -0700 Subject: Added test case to make sure that callback isn't called multiple times in asyncify --- mocha_test/asyncify.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/mocha_test/asyncify.js b/mocha_test/asyncify.js index aae878e..025083a 100644 --- a/mocha_test/asyncify.js +++ b/mocha_test/asyncify.js @@ -74,6 +74,13 @@ describe('asyncify', function(){ 'rsvp' ]; + // Both Bluebird and native promises emit these events. We handle it because Bluebird + // will report these rejections to stderr if we don't, which is a great feature for + // normal cases, but not here, since we expect unhandled rejections: + process.on('unhandledRejection', function () { + // Ignore. + }); + names.forEach(function(name) { describe(name, function() { @@ -111,6 +118,25 @@ describe('asyncify', function(){ done(); }); }); + + it('callback error', function(done) { + var promisified = function(argument) { + return new Promise(function (resolve) { + resolve(argument + " resolved"); + }); + }; + var call_count = 0; + async.asyncify(promisified)("argument", function () { + call_count++; + if (call_count === 1) { + throw new Error("error in callback"); + } + }); + setTimeout(function () { + expect(call_count).to.equal(1); + done(); + }, 15); + }); }); }); }); -- cgit v1.2.1 From 9e973605fccb4f29816626e89a026f5187774607 Mon Sep 17 00:00:00 2001 From: Ray Myers Date: Thu, 23 Jun 2016 11:38:57 -0700 Subject: Remove unhandled rejection listener after asyncify tests are complete --- mocha_test/asyncify.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mocha_test/asyncify.js b/mocha_test/asyncify.js index 025083a..880f2f2 100644 --- a/mocha_test/asyncify.js +++ b/mocha_test/asyncify.js @@ -77,8 +77,14 @@ describe('asyncify', function(){ // Both Bluebird and native promises emit these events. We handle it because Bluebird // will report these rejections to stderr if we don't, which is a great feature for // normal cases, but not here, since we expect unhandled rejections: - process.on('unhandledRejection', function () { - // Ignore. + function ignoreRejections() {} + + before(function () { + process.on('unhandledRejection', ignoreRejections); + }); + + after(function () { + process.removeListener('unhandledRejection', ignoreRejections); }); names.forEach(function(name) { -- cgit v1.2.1 From 3b6b6a185dda1daba7cb73f6a1fb015823843bb4 Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Sat, 18 Jun 2016 03:04:49 -0300 Subject: Allow use es6 object method shorthand --- lib/autoInject.js | 15 +++++++++++---- mocha_test/autoInject.js | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/autoInject.js b/lib/autoInject.js index 1b7bed4..89e8c5e 100644 --- a/lib/autoInject.js +++ b/lib/autoInject.js @@ -5,10 +5,19 @@ import clone from 'lodash/_copyArray'; import isArray from 'lodash/isArray'; import trim from 'lodash/trim'; -var argsRegex = /^(function[^\(]*)?\(?\s*([^\)=]*)/m; +var FN_ARGS = /^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m; +var FN_ARG_SPLIT = /,/; +var FN_ARG = /(=.+)?(\s*)$/; +var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; function parseParams(func) { - return trim(func.toString().match(argsRegex)[2]).split(/\s*\,\s*/); + func = func.toString().replace(STRIP_COMMENTS, ''); + func = func.match(FN_ARGS)[2].replace(' ', ''); + func = func.split(FN_ARG_SPLIT); + func = func.map(function (arg){ + return trim(arg.replace(FN_ARG, '')); + }); + return func; } /** @@ -109,8 +118,6 @@ export default function autoInject(tasks, callback) { taskFn = params.pop(); newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn); - } else if (taskFn.length === 0) { - throw new Error("autoInject task functions require explicit parameters."); } else if (taskFn.length === 1) { // no dependencies, use the function as-is newTasks[key] = taskFn; diff --git a/mocha_test/autoInject.js b/mocha_test/autoInject.js index d699453..2ba6d55 100644 --- a/mocha_test/autoInject.js +++ b/mocha_test/autoInject.js @@ -110,5 +110,25 @@ describe('autoInject', function () { " }); " + "}) " )(); + + /* eslint {no-eval: 0}*/ + eval("(function() { " + + " it('should work with es6 obj method syntax', function (done) { " + + " async.autoInject({ " + + " task1 (cb){ cb(null, 1) }, " + + " task2 ( task3 , cb ) { cb(null, 2) }, " + + " task3 (cb) { cb(null, 3) }, " + + " task4 ( task2 , cb ) { cb(null) }, " + + " task5 ( task4 = 4 , cb ) { cb(null, task4 + 1) } " + + " }, (err, results) => { " + + " expect(results.task1).to.equal(1); " + + " expect(results.task3).to.equal(3); " + + " expect(results.task4).to.equal(undefined); " + + " expect(results.task5).to.equal(5); " + + " done(); " + + " }); " + + " }); " + + "}) " + )(); } }); -- cgit v1.2.1 From 674697629d1c3dded7fae2b88f54c2f481b4f221 Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Sat, 18 Jun 2016 03:44:59 -0300 Subject: Fix test to pass NodeJs 4 NodeJS 4 seems to have arrowFunctions but not defaults in functions. --- mocha_test/autoInject.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mocha_test/autoInject.js b/mocha_test/autoInject.js index 2ba6d55..e658167 100644 --- a/mocha_test/autoInject.js +++ b/mocha_test/autoInject.js @@ -110,6 +110,18 @@ describe('autoInject', function () { " }); " + "}) " )(); + } + + + var defaultSupport = true; + try { + eval('function x(y = 1){ return y }'); + }catch (e){ + defaultSupport = false; + } + + if(arrowSupport && defaultSupport){ + // Needs to be run on ES6 only /* eslint {no-eval: 0}*/ eval("(function() { " + -- cgit v1.2.1 From 016fc4b873744a3da3429361036cbc3406ee8b86 Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Thu, 23 Jun 2016 15:19:57 -0300 Subject: Consider non-explicit parameters in validation --- lib/autoInject.js | 7 ++++++- mocha_test/autoInject.js | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/autoInject.js b/lib/autoInject.js index 89e8c5e..4b4f6e7 100644 --- a/lib/autoInject.js +++ b/lib/autoInject.js @@ -13,7 +13,7 @@ var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; function parseParams(func) { func = func.toString().replace(STRIP_COMMENTS, ''); func = func.match(FN_ARGS)[2].replace(' ', ''); - func = func.split(FN_ARG_SPLIT); + func = func ? func.split(FN_ARG_SPLIT) : []; func = func.map(function (arg){ return trim(arg.replace(FN_ARG, '')); }); @@ -123,6 +123,11 @@ export default function autoInject(tasks, callback) { newTasks[key] = taskFn; } else { params = parseParams(taskFn); + if (taskFn.length === 0 && params.length === 0) { + throw new Error("autoInject task functions require explicit parameters."); + } + console.log(taskFn.length, params) + params.pop(); newTasks[key] = params.concat(newTask); diff --git a/mocha_test/autoInject.js b/mocha_test/autoInject.js index e658167..9c2d1fb 100644 --- a/mocha_test/autoInject.js +++ b/mocha_test/autoInject.js @@ -85,6 +85,20 @@ describe('autoInject', function () { }, done); }); + it('should throw error for function without explicit parameters', function (done) { + try { + async.autoInject({ + a: function (){} + }); + } catch (e) { + // It's ok. It detected a void function + return done(); + } + + // If didn't catch error, then it's a failed test + done(true) + }); + var arrowSupport = true; try { new Function('x => x'); -- cgit v1.2.1 From 7bc2b8f9b627f9eaf196063459921bbe21389ebf Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Thu, 23 Jun 2016 20:13:41 -0300 Subject: cleanup console.log --- lib/autoInject.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/autoInject.js b/lib/autoInject.js index 4b4f6e7..31bd622 100644 --- a/lib/autoInject.js +++ b/lib/autoInject.js @@ -126,7 +126,6 @@ export default function autoInject(tasks, callback) { if (taskFn.length === 0 && params.length === 0) { throw new Error("autoInject task functions require explicit parameters."); } - console.log(taskFn.length, params) params.pop(); -- cgit v1.2.1 From f38d2299b807fac19f27be2d73ea6ac273905b38 Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Wed, 29 Jun 2016 13:52:53 -0300 Subject: Create logo folder and add .ai --- logo/async-logo.ai | 2213 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2213 insertions(+) create mode 100644 logo/async-logo.ai diff --git a/logo/async-logo.ai b/logo/async-logo.ai new file mode 100644 index 0000000..009e1f6 --- /dev/null +++ b/logo/async-logo.ai @@ -0,0 +1,2213 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R 56 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + Web + + + Adobe Illustrator CC 2015 (Macintosh) + 2016-06-29T13:36:34-03:00 + 2016-06-29T13:38:45-03:00 + 2016-06-29T13:38:45-03:00 + + + + 256 + 136 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+IMWElDQ19QUk9GSUxFAAEBAAAMSExpbm8CEAAAbW50clJHQiBYWVogB84AAgAJ AAYAMQAAYWNzcE1TRlQAAAAASUVDIHNSR0IAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1IUCAgAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARY3BydAAAAVAAAAAz ZGVzYwAAAYQAAABsd3RwdAAAAfAAAAAUYmtwdAAAAgQAAAAUclhZWgAAAhgAAAAUZ1hZWgAAAiwA AAAUYlhZWgAAAkAAAAAUZG1uZAAAAlQAAABwZG1kZAAAAsQAAACIdnVlZAAAA0wAAACGdmlldwAA A9QAAAAkbHVtaQAAA/gAAAAUbWVhcwAABAwAAAAkdGVjaAAABDAAAAAMclRSQwAABDwAAAgMZ1RS QwAABDwAAAgMYlRSQwAABDwAAAgMdGV4dAAAAABDb3B5cmlnaHQgKGMpIDE5OTggSGV3bGV0dC1Q YWNrYXJkIENvbXBhbnkAAGRlc2MAAAAAAAAAEnNSR0IgSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAS c1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAFhZWiAAAAAAAADzUQABAAAAARbMWFlaIAAAAAAAAAAAAAAAAAAAAABYWVogAAAA AAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9kZXNj AAAAAAAAABZJRUMgaHR0cDovL3d3dy5pZWMuY2gAAAAAAAAAAAAAABZJRUMgaHR0cDovL3d3dy5p ZWMuY2gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAA AAAAAAAuSUVDIDYxOTY2LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAA AAAAAAAuSUVDIDYxOTY2LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAA AAAAAAAAAAAAAAAAAAAAAGRlc2MAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBp biBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAACxSZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24gaW4g SUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2aWV3AAAAAAATpP4AFF8uABDP FAAD7cwABBMLAANcngAAAAFYWVogAAAAAABMCVYAUAAAAFcf521lYXMAAAAAAAAAAQAAAAAAAAAA AAAAAAAAAAAAAAKPAAAAAnNpZyAAAAAAQ1JUIGN1cnYAAAAAAAAEAAAAAAUACgAPABQAGQAeACMA KAAtADIANwA7AEAARQBKAE8AVABZAF4AYwBoAG0AcgB3AHwAgQCGAIsAkACVAJoAnwCkAKkArgCy ALcAvADBAMYAywDQANUA2wDgAOUA6wDwAPYA+wEBAQcBDQETARkBHwElASsBMgE4AT4BRQFMAVIB WQFgAWcBbgF1AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB4QHpAfIB+gIDAgwCFAIdAiYCLwI4 AkECSwJUAl0CZwJxAnoChAKOApgCogKsArYCwQLLAtUC4ALrAvUDAAMLAxYDIQMtAzgDQwNPA1oD ZgNyA34DigOWA6IDrgO6A8cD0wPgA+wD+QQGBBMEIAQtBDsESARVBGMEcQR+BIwEmgSoBLYExATT BOEE8AT+BQ0FHAUrBToFSQVYBWcFdwWGBZYFpgW1BcUF1QXlBfYGBgYWBicGNwZIBlkGagZ7BowG nQavBsAG0QbjBvUHBwcZBysHPQdPB2EHdAeGB5kHrAe/B9IH5Qf4CAsIHwgyCEYIWghuCIIIlgiq CL4I0gjnCPsJEAklCToJTwlkCXkJjwmkCboJzwnlCfsKEQonCj0KVApqCoEKmAquCsUK3ArzCwsL Igs5C1ELaQuAC5gLsAvIC+EL+QwSDCoMQwxcDHUMjgynDMAM2QzzDQ0NJg1ADVoNdA2ODakNww3e DfgOEw4uDkkOZA5/DpsOtg7SDu4PCQ8lD0EPXg96D5YPsw/PD+wQCRAmEEMQYRB+EJsQuRDXEPUR ExExEU8RbRGMEaoRyRHoEgcSJhJFEmQShBKjEsMS4xMDEyMTQxNjE4MTpBPFE+UUBhQnFEkUahSL FK0UzhTwFRIVNBVWFXgVmxW9FeAWAxYmFkkWbBaPFrIW1hb6Fx0XQRdlF4kXrhfSF/cYGxhAGGUY ihivGNUY+hkgGUUZaxmRGbcZ3RoEGioaURp3Gp4axRrsGxQbOxtjG4obshvaHAIcKhxSHHscoxzM HPUdHh1HHXAdmR3DHeweFh5AHmoelB6+HukfEx8+H2kflB+/H+ogFSBBIGwgmCDEIPAhHCFIIXUh oSHOIfsiJyJVIoIiryLdIwojOCNmI5QjwiPwJB8kTSR8JKsk2iUJJTglaCWXJccl9yYnJlcmhya3 JugnGCdJJ3onqyfcKA0oPyhxKKIo1CkGKTgpaymdKdAqAio1KmgqmyrPKwIrNitpK50r0SwFLDks biyiLNctDC1BLXYtqy3hLhYuTC6CLrcu7i8kL1ovkS/HL/4wNTBsMKQw2zESMUoxgjG6MfIyKjJj Mpsy1DMNM0YzfzO4M/E0KzRlNJ402DUTNU01hzXCNf02NzZyNq426TckN2A3nDfXOBQ4UDiMOMg5 BTlCOX85vDn5OjY6dDqyOu87LTtrO6o76DwnPGU8pDzjPSI9YT2hPeA+ID5gPqA+4D8hP2E/oj/i QCNAZECmQOdBKUFqQaxB7kIwQnJCtUL3QzpDfUPARANER0SKRM5FEkVVRZpF3kYiRmdGq0bwRzVH e0fASAVIS0iRSNdJHUljSalJ8Eo3Sn1KxEsMS1NLmkviTCpMcky6TQJNSk2TTdxOJU5uTrdPAE9J T5NP3VAnUHFQu1EGUVBRm1HmUjFSfFLHUxNTX1OqU/ZUQlSPVNtVKFV1VcJWD1ZcVqlW91dEV5JX 4FgvWH1Yy1kaWWlZuFoHWlZaplr1W0VblVvlXDVchlzWXSddeF3JXhpebF69Xw9fYV+zYAVgV2Cq YPxhT2GiYfViSWKcYvBjQ2OXY+tkQGSUZOllPWWSZedmPWaSZuhnPWeTZ+loP2iWaOxpQ2maafFq SGqfavdrT2una/9sV2yvbQhtYG25bhJua27Ebx5veG/RcCtwhnDgcTpxlXHwcktypnMBc11zuHQU dHB0zHUodYV14XY+dpt2+HdWd7N4EXhueMx5KnmJeed6RnqlewR7Y3vCfCF8gXzhfUF9oX4BfmJ+ wn8jf4R/5YBHgKiBCoFrgc2CMIKSgvSDV4O6hB2EgITjhUeFq4YOhnKG14c7h5+IBIhpiM6JM4mZ if6KZIrKizCLlov8jGOMyo0xjZiN/45mjs6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aUIJSKlPSV X5XJljSWn5cKl3WX4JhMmLiZJJmQmfyaaJrVm0Kbr5wcnImc951kndKeQJ6unx2fi5/6oGmg2KFH obaiJqKWowajdqPmpFakx6U4pammGqaLpv2nbqfgqFKoxKk3qamqHKqPqwKrdavprFys0K1Erbiu La6hrxavi7AAsHWw6rFgsdayS7LCszizrrQltJy1E7WKtgG2ebbwt2i34LhZuNG5SrnCuju6tbsu u6e8IbybvRW9j74KvoS+/796v/XAcMDswWfB48JfwtvDWMPUxFHEzsVLxcjGRsbDx0HHv8g9yLzJ Osm5yjjKt8s2y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc 1+DYZNjo2WzZ8dp22vvbgNwF3IrdEN2W3hzeot8p36/gNuC94UThzOJT4tvjY+Pr5HPk/OWE5g3m lucf56noMui86Ubp0Opb6uXrcOv77IbtEe2c7ijutO9A78zwWPDl8XLx//KM8xnzp/Q09ML1UPXe 9m32+/eK+Bn4qPk4+cf6V/rn+3f8B/yY/Sn9uv5L/tz/bf///+4ADkFkb2JlAGTAAAAAAf/bAIQA BgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoKDBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8f Hx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f Hx8fHx8fHx8fHx8fHx8f/8AAEQgAiAEAAwERAAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQF AwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMB AgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPBUtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdU ZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eX p7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZqbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUE BQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEyobHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PS NeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG 1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/a AAwDAQACEQMRAD8A6n578+eZNL8yXFjYzrHbxKnFSisasoJ3IzpOzOzMObDxSu7PV0Wv7QyYsnDG qpIJfzL87wyvFLc+nLGxSSN4lVlZTQhgRUEHM+PYmmIsXXvcM9q5waNfJb/ytDzl/wAti/8AItP6 Yf5D0/cfmj+Vs/ePk7/laHnL/lsX/kWn9Mf5D0/cfmv8rZ+8fJ3/ACtDzl/y2L/yLT+mP8h6fuPz X+Vs/ePk7/laHnL/AJbF/wCRaf0x/kPT9x+a/wArZ+8fJ3/K0POX/LYv/ItP6Y/yHp+4/Nf5Wz94 +Tv+Voecv+Wxf+Raf0x/kPT9x+a/ytn8vknnkrz95m1LzLZ2V5cLJbzFw68FXohYbgeIzB7S7Lw4 cJnG726uZoe0MuXKIyqnrecy75jOtedo7XUDpOlWUurasorJBCeKR/8AGSQggdf60zZafs4yh4mS Qhj7z19wcHPrRGXBAGc/xzQ41j8ySK/oC2Wv7JuVJH3NlngaP/VJf6Vh42q/mD5u/S35kf8AVitf +klf+asfA0f+qS/0q+Nqv5kfm79LfmR/1YrX/pJX/mrHwNH/AKpL/Sr42q/mR+aybzN56sVM995c WW1XeQ2s6u6jx4jkT92GOj0s9o5al5hidTqIbyx7eRZDoWu6drenpf2EnOJvhZTsyOOqOOxGa/U6 aeGfDPm5uDPHLHijyTDKG52KuxV2KuxV2KuxV2KuxV2KuxV2KuxVK/Mmr3WkaW9/b2TX/pMDNEjc WWP9p+jV4+GZOkwRyz4DLhv7+5o1OY44cQHEq6Jrmna1YJe2EokibZl/aRqbo47EZHUaaeGfDMbp wZ45Y8USj8obnhH5of8AKZ3n+rH/AMQGdp2H/i495eV7W/vvgFI6n5dXzLrd3fRNeW13PcJbGMAh Unkas45U+JV+yPfLvBzeDjjE8JiI38By/W1+Lj8WZkOIEmvief6ldpvy8SPn9VuJPVFI1DnlHx4C rDkBU8pKb/srtucgI6smrjt9vP8AZ8yyJ0wHI/iv2/IIez1jyzZaldmOzM9gwR7JZUVnWVAVBcOX qKSMSK0LAbUyzJgzThG5VLr7vhXcPgwhmxRkaFx6e9EXF3+XMkkciW12GYsbhSBxqV24hZFoA46C nXbplcIawAgmPl+KZynpibqX4+KpHrnkz9MXM0lpKbL1bJ7IGNOSrawNG4cKy/bYg0BoTufDInTa nwwARxVO9/50rFe5kM+DjJIPDca+AVY9V/LGG8t54tOunVTznWajgmgFOPPiepPz9sgcOtMSDKPl X9jIZdKJAiMvx8WOa+2jGeEaYhVTEr3DFqgyuKlQKADiOw71HSmbHSjJR4+/b3ODqOCxwd26Zflx /wAplp3+s/8AybbMPtr/ABaXw+9yuyv78fH7nuerXhstKvbwUrbQSzCvT92hb+Gcbgx8eSMe8gPU Zp8MDLuBSD8t9Oit/LMF6fjvNSLXN3Od2dmY0qfYfjXxzO7WymWYx/hhsA4fZuMDEJfxS3Kt5zbz s8NpaeVUgjluXZbvUbgqVtowBRljP22bt8J+XfNY7BIU/K7XZU53vnjWnum3dreY28Vf8mIFqffi qGXVvN3kXVbK38xagNb8sahMttFqsihLi1lf7AmpsyH+Yk9zt0Kr0rFWO6NZ6Jp3mbVLaxnJu71E u7myWnpw8TxqKdDIXrT+zNhqMmXJhgZD0x2B6n+ynCwwxwyyETvLcju/tZFmvc1RvL2ysrdri8uI 7a3T7c0zrGg+bMQMVSi28+eSrqcW8Gu2MkzGiILiOrGtKLvufliqe4q1JIkaNJIwRFFWdjQADqST iqQnz/5HE/oHX7D1K8afWYqV/wBblTFU9jkjljWSNg8bgMjqQQQehBGKrUubaSaSBJUeeHj60SsC 6chVeSjcVHSuExNWixdKmBKQ+cfM36B01XhjE+o3TiGxtzX4pD3IG9B/QZnaDR+POiahHeR8nE1m p8KO28jsAkNr5f8ANOoTSJfebHg1ONUkubC04/uVkqUDBWTrQ02+/MuWu00DUMQI7y40dJnkLlkI PcEruzptpOYLn8yfTmXZ4zMlVPg1Jdvpwfylh/1GH4+CfyOX/VZfj4pvaeUtWvbdLmz86XVzbybx zQkSIw9mWQg4/wApYf8AUYfj4L+Ry/6rL8fFW/wN5i/6m2++4/8AVTH+UsP+ow/HwX8jl/1WX4+K SabYeXPKetNK/nO2huGY/W7OUxAPvuJEElVO+x7YdV2rHNDhljHkb5fYjT9nHFLiE/ftz+16PZX9 jf263NjcxXVu32ZoHWRD8mUkZpnaJDrflDy9qV+11eWgknYAM/JhWgoOhGZWLW5sceGMiA4+TS45 m5RBKA/5V75S/wCWEf8ABv8A1yz+U9R/PLX+Qw/zQ7/lXvlL/lhH/Bv/AFx/lPUfzyv5DD/NDv8A lXvlL/lhH/Bv/XH+U9R/PK/kMP8ANDv+Ve+Uv+WEf8G/9cf5T1H88r+Qw/zQ7/lXvlL/AJYR/wAG /wDXH+U9R/PK/kMP80O/5V75S/5YR/wb/wBcf5T1H88r+Qw/zQ7/AJV75S/5YR/wb/1x/lPUfzyv 5DD/ADQjdG8m+XdP1CO7tLQRzx14PyY0qCD1OV5ddmyR4ZSJDZj0mKBuMQCmfmr/AJRfWP8AmBuf +TLY6L+/h/Xj966v+6n/AFT9yF8h/wDKH6V/xgH6zlnaf+MT97DQf3Mfcn2YLlqE99ZW9fXuIoeN OXqOq0r0rU4q84/ODzn5Lm8m6jpB1OC5v7hV+r29uwmYSI6upYpyCfZ/aI2xVm2lyahe+UbKWCVY r+5sYnSdhyCyvEDyIPXc5PEYiQMhcerDICYnh2LEvJWkPpPn3VLOS4a6nFmkk9w/V5JGR3P3nN72 jnGXSwkBwji2HkLdRosPh6iUSbPDz+T0XOfd0kOt+SNA13VrbUdXie9FpHwgspXJtQxJJkMXRnNa b7U7YqvvvJHk++tGtLjRrNoGBACwojLX+RkCsp91OKpF+Xc17p2p655Purh7uPQ5IX024lPKQ2ly hdI2bv6VOP6tsVQmv2Q82fmGfLepSuuhaVZpey2CMUF1NK9F9QqQSieHj88VZUPJnlAWv1QaLY/V 6UMf1eKmwp/L1364qxbSbNvJXniz0K0kY+WvMKTvY2jsWFrdwKJHVGYkhJF7HviqO81g+XvMVn5s iFLKfjY64oG3pMf3U5p/I1AfagzOwfvIHH15x/U4ef8AdzGTpyP62aKwYBlNQdwR0IzBcxgmjH/F HnWfWmHLSdFrbaf3V5j9qQfr/wCBzeaj/BtMMf8AlMm8vd3fjzdTh/f5zP8AghsPf+P0Ma1LQNR8 w/m7rukrdSWmjSW9nNq/ong8yRxAJBzG4Dlzy9hmjds9Fs/I/k6ztltrfRLJYgKUaCNyf9ZmDMx9 ycVYrPplv5J876TLpC/VtC8xytZ3+nLX0UuuPKGWJf2S1OJA2piqP/MK81O9v9H8oaZctZza20r3 95HtJFZ268pAp7NJXiD/AFxVNtM/L/yXptoltbaNaMqAAySwpLIx8XkcMzH6cVYt5k0W18i6rZea dBT6lpc1xFa69psXw27RTNwWdY/sq8bEdP61VZ7df3p+QxVL7jVtOtpGjnuFidACwbagNN/xxVEQ zRTRLLEweNxVWHQjFWHXWta4WvViuJI44pY+JCBpFV/rHJORtuCGsaUBV+w5fGGxVFF9a1D04Wu5 YY4pIllnhAjlLyqrPGwHIKYtxTf7Q6kZlGoQBr1S7+749/6PNxhc5kX6Y/f+z9K3QJLkarP6zzi5 NzLbKjRsyy2sBdUmeRunxDryp2C770zyykKPIN0cYibHNGS+dNMjvpLJYLiSaOVoG4KhHNadKuCa lqDbBjgZSoLOfCLVNE8zHU717V7U2zrCs4rIjmjBWFQDXdZFIIFOtaHbGQj0J+X7SmJl1ZDbf3w+ n9WQZIfzV/yi+sf8wNz/AMmWzK0X9/D+vH73H1f91P8Aqn7kL5D/AOUP0r/jAP1nLO0/8Yn72Gg/ uY+5jfm6/wBf8w+bV8laLeNplpb263euajFtMEc0SGI7ULVB/sBBwXLV7b8kPy5iRfW0+S8mBq1x PcTl2PiwR0Q/8DiqH88+TPKuh/l/rr6Vpdvayi1YesqAy0qNvUar/jirLvKf/KLaN/zA23/JlcVS HS//ACaWs/8AMDD/AMy83Gb/ABGH9c/pdZi/xuf9UfoZnmndmw/X/OerHXH8ueVdPTUdXgRJL+5u HMdpaLJunqlfiZmG/Fd6eO+KqB0784bgFJdY0iyDf7straWVl+QmPHb3xVBeRNKvtM8/+Y7e+1KX Vbs2ljJLeTAISWMuyouyqOwGKp/5q8kQa1d2+qWd7NpGvWamO21O2oTwJr6cqHaRKmvE4qk3+LfO nllvT82aZ+ktNXYa7pSluI8bi2+0vuy7eFcVZNpeo+VvMsdtquny2+o/U3Y21woBeF3Xi2zAPGxU 7ggYqj9S0+21HT7iwul529zG0Ui+zClR7jtkoTMSCOYYziJAg9XmreaNU0zy9c+UH5SeY7eddNtG pQyW8o/dTKf9T4fbY5vNNpI5Moyn+7A4j7x0dRn1MoY/C/yl8I93e9A8taJDomi2unR0JiX964/a kbd2+k9PbNVq9Qc2QzPX7nZabAMWMRHRjXl3/wAmt5u/5htO/wCTbZjN7OMVYP8AmT/x0/Jv/bcg /wCIPirtW/8AJvaB/wBsy7/4kMVZxiqHv9PsdRtJLO+gjurWWnqQSqHRuLBhVTtswBxVTuv70/IY qh5IYZKepGr0II5AHcGoO/gcVXgAbDpiqQznyZFM8UlvZmVDSQLAr0buCVU0PtmdGOpIsGVe9w5H ADREfkqW0vlKWVLeGK1DuaRoYVTketF5KKn2GRnizgcRv52yhkwk0K+SZR6dp8TiSK1ijkX7LrGo I+RAzFM5Hq5AgB0aOmaaZTKbSEykljJ6a8iT1NaVrkvGnVWa96PCjd0LVkggjNUjVD0qoANPoyBJ LIAIi2/vh9P6sCVDzSpbyzq6gVJsrgAe/pNmTov76H9aP3tGq/up/wBU/chPIf8Ayh+lf8YB+s5b 2n/jE/e16D+5j7mMSXkXl384LiW/YQ2HmiziW2uXNE+tWtE9IselV/EjMFy3ouKvNvz0812WmeUJ 9IEgbUtWAjihG5WJWDSSMOwoOI9z7HFWaeU/+UW0b/mBtv8AkyuKpFpYP/K0tZPb6lD/AMy83Gb/ ABGH9c/pdZi/xuf9UfoZlmndmwLydcwad59816NeMI7++uI9Rsi+xnt3jpROnL0iCPv8DirPSQoJ JoBuSegGKvOvI2u2etfmX5vurKQTWkUVnbxSrQq3pB1cqR1HPlQ98VR2m6tNpf5mavpOp3Di31uK 3u9E9ViY+UUfpTwpX4Q1RyoO2Ks3xV5xYW1jb/nTcLoaqkL6aX19If7oTmT93yUfCJCKH7/fFXo5 IAqdgMVYF5ahTzJ5yvfM7qDY2H+h6YafbKg1kr3oGJFf5h4ZvNWfy+njhH1z9Uv1fju83UaYePnO X+GO0f1s9zRu3YP5d/8AJrebv+YbTv8Ak22Ks4xVg/5k/wDHT8m/9tyD/iD4qpeeJl0Tzr5a8zXP w6WvrabfzHpD9YFYXbwXmPiJ6YqzxWVlDKQVIqCNwQcVYX+Z+r3KWNj5e0u4eLXNbuoYrb0HKyxw pIJJZqruFCpQn5++Kspuv70/IYqpYq7FWHNNpH6D0ezu7KfUrm5jaaGwtv8AdnGnqySBniiKhpBU yHqfHMrW/wB9L3uPpP7qPuW28l9HYXsCWxsYbTULVoLW5KTvHFIYm4qVeRFPqHkvxNx6DtQ6OuMg /wA2X3FGqvh2/nD72V32oWtjD6ty/BCaD6BU/QAKk9sx4YzLl0b5TEVljqlnfAm3Ynj1qKdCVND0 2ZSCOoPXGWMgX0RGYJpF5Bmq2398Pp/ViqJmhjmhkhlXlHKpR18VYUIwxkQbHMIkARRYJoetHybI 3l/Xuaaers2l6nxLRtGx5cH4g0YE/R8qZvNTp/zY8XF9f8UetupwZvy37vJ9P8Mkx8xX/wCXPmLT X07Vr6zuLZviWsqh0emzowNVYf57Zrv5Pz/zJfJzfzuH+dH5sSTS3s1FtpX5nvb2C7Rw3Cw3Mir/ ACiVnQig6bY/yfn/AJkvkn87h/nR+apD5S/LZdN1KO58xLfazqkLQz61dTJLMvID+7BNFG3zptXH +T8/8yXyX87h/nR+bKf8beUdD0e1tLe+F+1tDHb28MFJJZPTUItePwgmmW4eys8zRjwjvOzVl7Rw xGx4j3BU8laTqSSX+vaunp6lq7K3od4YUFI0PvTqPYd8l2jngRHFj3hj6956lGiwyuWSf1T+wMpz WOewbzjN+W2tuLbV75Ir+xciG8t2ZLiBwd+EqA9+o3FczYdnZ5AEQNFxZa7DE0ZC2Oyaf5Pu1+ra r571PUNNHWykmZA47rK6xhnH3ZL+S9R/MLH+UMH84J7oeoflloeo3F5pmoR26T28FsLVQ3pItuXI K/Byq3P4iSa4/wAl6j+YV/lDB/OCt5k1j8sfMdkLTVbyKZYzzglX1Elif+aNwtVOP8l6j+YV/lDB /ODHvq/lzj6H/KxNX+p0p6frfvaeHrely6Y/yXqP5hX+UMH84Mh8tav+WPluya00q9iiWRuc8z+o 8sr/AM8jstWP4eGP8l6j+YV/lDB/OCD86/mLpE+mNpejXayXV9SF7liYooo22Yl347kbZn6DsycJ eJlFRjvXUlw9Zr4yjwYzcpfYnGheY/Imj6Tbadb6zZ8LdKFvVSrMd2Y7/tMa5gamGbNkMzE7uZgn ixwERIbI/wDx15N/6vVn/wAjl/rlH5XL/NLb+Zx/zglVlq/kC08w6lrseu25utTjginjaaPgotwV UrSh3B3qcfyuX+aV/M4/5wTX/HXk3/q9Wf8AyOX+uP5XL/NK/mcf84JVrmr+QdZn0ua5123RtKu0 vYBHNGAzoCAr1r8PxdsfyuX+aV/M4/5wR1/5r8gahZTWV9qdjcWlwpSaGSVCrKfHfH8rl/mlfzOP +cGHRaV5Psk+r6R5/vNO0/otkl5FIka0I4xF1LIPpx/K5f5pX8zj/nBNvLEX5Z6JeyXsOtx3+sXP wSanf3SzXDA/shzxVR8gPfB+Vy/zSn8zj/nBmd1/en5DKG5AXcOoPIptrhYUpRlZOe9evUdsVV4V lWNRK4eQfacDiCflirFbrRdfh+p/UAI7vTlkhtrxGRkkt5GUmOaGQL/vtfstsRsdyMzchxZJcXFw k8xXVxMfiYxw8NgebenaDrIa6S55MdQuobu8uppIyw9EIAkaRKo39IAV6DxPVgceO5CXEaNbd4pM xOexFCx17t071q2vZrcGz/vlDLQMUajrSqsKbg07jbvXMfGY0QTVt2QHYjekJ5b0y+tTNLdxLEzl uKh2lchnL/E7FiaV6k779MMyBERBve0QBMrIpW0K31iKS+bUpC4kmrajnzAjApsKClTU45ZA1Vfj 8ftXGCOad2398Pp/VlLajMVU57e3uIjFcRJNE32o5FDKfmDUZKMzE2DRYyiJCiLS/wDwr5X/AOrP Y/8ASND/AM05kfnc/wDPn/pi0/lMX8yPyDv8K+V/+rPY/wDSND/zTj+dz/z5/wCmK/lMX8yPyDv8 K+V/+rPY/wDSND/zTj+dz/z5/wCmK/lMX8yPyCvaaHolnL6tnp9tbS9PUhhjRvvUA5XPU5ZipSkR 5ks4YMcTcYgfBG5S2uxVLZfLPluWR5ZdKs5JZCWd2t4izMTUkkruTmRHWZgKE5V7y0HTYibMY/IL f8K+V/8Aqz2P/SND/wA05L87n/nz/wBMUflMX8yPyDv8K+V/+rPY/wDSND/zTj+dz/z5/wCmK/lM X8yPyDv8K+V/+rPY/wDSND/zTj+dz/z5/wCmK/lMX8yPyDv8K+V/+rPY/wDSND/zTj+dz/z5/wCm K/lMX8yPyDv8K+V/+rPY/wDSND/zTj+dz/z5/wCmK/lMX8yPyC1vKPlRvtaLYH520J/41yJ1eU85 y+ZZDTYxyjH5Br/B/lL/AKslh/0iw/8ANOR/MZP50vmU+Bj/AJo+Tv8AB/lL/qyWH/SLD/zTj+Yy fzpfMr4GP+aPk7/B/lL/AKslh/0iw/8ANOP5jJ/Ol8yvgY/5o+Tv8H+Uv+rJYf8ASLD/AM04/mMn 86XzK+Bj/mj5O/wf5S/6slh/0iw/804/mMn86XzK+Bj/AJo+Tv8AB/lL/qyWH/SLD/zTj+Yyfzpf Mr4GP+aPk7/B/lL/AKslh/0iw/8ANOP5jJ/Ol8yvgY/5o+Ta+UfKisGXRbBWU1VhbQggjuPhx/MZ P50vmV8DH/NHyRV1/en5DKW1SxV2KrTLEK1dduu4xVDz6rpcD+nPeQRPQHi8iKaHoaE5bDBOQuMS R7muWaETRIHxal1fSoo45Zb2COKWvpSNKgV6bHiSaGntg8Kd1RseSfFjV2Fp1vRVtzcm/thbBuBm M0fAORULyrStO2RlAx5ikxkDyK6y1fSb5mSyvYLp0FXWGVJCAe5Ck0yLJMLb++H0/qxVDeaNfTQd Gl1N4TcLEyL6QbiTzYL1ofHMrR6Xx8ghdW4+q1HhQM6tbaeYFuvLkWtLEkQmjEgimlWNF5Nx+OUi gA8afRkNTh8LIYXdM8GXxICXK0L/AIxgdbY29v6zXCzMvGVKSfV5GjdbcivrOSlVUUqu5p0yhta1 rzVNbW0q2Nv6t9FIySwv+woZQrkVSvqeqnEch9rr8JzJhhAHFL6fvPd9/wCC0Syknhj9X3IIav5v kvobErbLqUTiSa1jVhCbcpUs87O5G7caLHXl4rvg48VH0n/Tcv8AYrwZLHqHy/amWv8AmoaP5fTW JbOQliitaORG6s/UMaMPhPhk9FpDnycF0x1eo8GHFVsQ/wCV22v/AFaX/wCRw/5ozc/6HZfz/s/a 6v8Alsfzftd/yu21/wCrS/8AyOH/ADRj/odl/P8As/av8tj+b9rv+V22v/Vpf/kcP+aMf9Dsv5/2 ftX+Wx/N+13/ACu21/6tL/8AI4f80Y/6HZfz/s/av8tj+b9rv+V22v8A1aX/AORw/wCaMf8AQ7L+ f9n7V/lsfzftd/yu21/6tL/8jh/zRj/odl/P+z9q/wAtj+b9rMvKXmVPMWlHUEtzbAStF6ZbmfhA NagL/Nmn12jOnnwE3tbs9JqfGhxVW6dZhuU7FXYq7FXYq7FXYq7FXYq7FUHdf3p+QxVKTrUauFa1 uN67iJmoQSADQd6YqjYJlmhSVVZQ4qFccWHzB6Yqgohei3QLdRoQlAGTdTQ7H4u21cVeXebZdHt/ MWoLf6fNNK7q8MqTeipjKKFopRtts7Ps2OSWCHBIAe6+vveW15gM0uKJJ99dPcxq7+oQW0T39hcy xTwUsZhL6Sh1Z/UpVGDjkR8sGqJOQ8JFjmjAAIbg78kHcyaGmjfWrzSbqbThNHFIYpzGDP6UlGEh jdRxr9mncfTou1LuNnvdv2dVGh3J1+T8mjT+evU0fT7q2iSCQyNLMJ1VCKcWKxx9XpQ/7eap2b36 2/vh9P6sVUfMWhW+u6VLptxI8UUpVi8dOQ4MGHUEdsydJqTgyCYFkNGpwDLAxKEl0C6tfLcGkaVM BJbGP0p5yAR6UgkDfYkWvJR+zjkzDLkM57X3ftWGI44CMN670jn8pebJ7B7N7uApP6gu3MhZpRLM 8xrytyqFWlYKYwpA+Qoawd8/kP1ovN3R+39SaPouuzi6a5Fo0148TSPG8i8UgYNHGtUbYEE79ycc mTGQIi+Efi0QhMEk1ZautD16bUH1CGaK1vGVU9WKQmiqCCvGSF1IaoO46gZV6PNt9fkidU8rQat5 di0e8leMJwLyxtzYsnfk43qeu2W6XVHBk44i/e16jTjNDhlt7mNf8qX0H/luuv8Akn/zTm1/0Q5f 5sft/W67+Rcf86X2O/5UvoP/AC3XX/JP/mnH/RDl/mx+39a/yLj/AJ0vsd/ypfQf+W66/wCSf/NO P+iHL/Nj9v61/kXH/Ol9jv8AlS+g/wDLddf8k/8AmnH/AEQ5f5sft/Wv8i4/50vsd/ypfQf+W66/ 5J/804/6Icv82P2/rX+Rcf8AOl9jv+VL6D/y3XX/ACT/AOacf9EOX+bH7f1r/IuP+dL7GWeWPLdr 5e002FtLJLGZGl5y05VYAU+ED+XNXrNXLPPjkKNU7DS6YYY8INptmI5LsVdirsVdirsVdirsVdir sVS3UrhoHaRvTWIAVd3K0qab/Ce+KoRtQVVDM8CqxCqTNQEmtB9n2OKti9JcIpgLsaBRLU169lxV W5Xf++4/+Rh/5oxV3K7/AN9x/wDIw/8ANGKu5Xf++4/+Rh/5oxV3K7/33H/yMP8AzRiruV3/AL7j /wCRh/5oxVWs2uDOvNEC71Ick9PAqMVTDFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY q7FXYq7FXYq7FUBqEEM/KKZBJGwHJD0NDXFUGNL00IyC1iCOKOoRQCN/b/LP34q3HpmnxyJJHbxp JGOKMqgEAdtu3tiq66vbS1Cm4kCczxjXqzGlaKoqT9GWQxSnyDCeSMeZUP01p387/wDIqX/mnJ/l p/gj9bDx4fgFFQTw3ESzQOskT7q6moPbqMqlAxNEUWyMhIWOSpkWTsVVbb++H0/qxVGYq7FXYq7F XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqg7r+9PyGKqWKuxVK7+4t7bUGurlu MFvZTSSP3VAylyKb9Fy8f3R/rD7i0n+8H9X9ISJrSSxu9NvLTSIdKV7mOK4kMo+sSpNVOEqxqyyN vyq0hoRXfKG5kOjiVVvElZWZLmShRBGKNR+gr/N1J3zI1Fekj+aPNowXvf8AOKYZjt7sVVbb++H0 /qxVGYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqg7r+9PyGKqWKux VLNX06W5YlYkuIZYJLW5t3Yx8o5abqwDbinT8cvxyiYmMtt7aZxlxCQ3SiXRNfuJbRruV7pLCZLi 2jeSJavHUVlZIl5NQkbUHsTvjwY/5x+X7V45/wA37f2J/p1tNBC5nKm4mkaWXhXiCx2Va0JCqAK9 +uRzTEjtyApligQN+ZNovKmx2Kqtt/fD6f1YqjMVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd irsVdirsVdirsVdirsVQd1/en5DFVCSWOKNpJXCRqKs7EAAeJJxVbBcQTxiWCRZYz0dGDKae4xVb De2c5cQTxymP+8COrcf9ah2xVdPcQQW73ErhII1MjyHoFAqT92SjAyIiOZYykIizyScebbQiNhaX AExIh5+jGXo3HZZJFbr7Zky0oBozhfvP6A0DUWLEZfZ+tq68w3lvcW7Pp8sVi7FLiWcxRlCfssD6 hDDrVevh4ZIafHwm5x4unPfy5IOefEKgeHry/WniOrqHQhkYAqwNQQehBzCcpWtv74fT+rFUZirs VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdiqDuv70/IYqk+uTIFtbYWkV7 cXMwW3hnIWMNGjSeozcZKcQm1FJrTFUgls5f0hq9hczW1j9fsoPgtgwUSSSvCjuSV5GQkIaAEigr tiqPgt7b9JWEdxYppV/blxA0AVoJ4vTYPCkihDxpR+DqD8NQDSuKrFgnkvk8uFD9RtXW6eTsbUGs EB/56ArT+RPfNhAiMDl/iPpHv6n5faXBkDKQxfwjc+7oPn9gVPL2iaW9lfyTW0c8l5fX31hpFDll F3KgXevwhR0+nvmvc5DeWoIru5gN2PrL2emWgt2mo5UySTpI9T+06wpyPtiqeaTZ2lmbyC1dfR+s F/q6ABYGeNGaMAdORPqf7LFU0tv74fT+rFUZirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd irsVdirsVdirsVdiqDuv70/IYqkvmC1uri3hFtbGeaOT1I5Fn+rvE4UqHVuLg7MQQRSh3y3FGBPq PD8L/SGvJKQ+kX8aSOPSNZDXUlzpjXk17CsFzNNfqGZUJKlfThjEZUttwAp1675d4WD+ef8AS/8A HmrxMv8AMH+m/Yq29r5oS6iubi0kvnt6m2S4vYQkbMpQuBFbRcm4sVq1dq+Jw+Fg/nn/AEv/AB5H iZv5g/037EdpcWvWwnmubOKW8u5PUnkWbioAHFEUFSeKKKfOp746ieOVCJIjEbbfM/FcMZxsyA4j zV7IapaQtFFYKVaWWYlrgE8p5WlbpGNuTmmUcMO/7G7il3fagP0PqUaW/wBUhks57eP0BcxXERd4 68uLrJDJG1DuPhqN6dTjww7/ALF4pd32ptoli9payLIjLPLI0s8jyCV5XYAc2YKg6AKAAAAABtkJ AdGcSeqa2398Pp/VkUozFXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F VCa3Z35AgDFVn1R/EYq76o/iMVd9UfxGKu+qP4jFXfVH8Rirf1Rv5hirvqjfzDFV0VuyOGJBpiqv irsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdir//Z + + + + proof:pdf + uuid:65E6390686CF11DBA6E2D887CEACB407 + xmp.did:b0716df5-7d69-4ba7-9fcc-0e8e60ff24fb + uuid:5c9a1129-eb89-d240-927f-33e49b2d8a80 + + xmp.iid:5ead5f55-4cab-4e6d-af67-1ca67f8e3259 + xmp.did:5ead5f55-4cab-4e6d-af67-1ca67f8e3259 + uuid:65E6390686CF11DBA6E2D887CEACB407 + proof:pdf + + + + + saved + xmp.iid:cd586ae3-cf98-40e9-9423-2755b0606a2c + 2016-06-29T13:18:40-03:00 + Adobe Illustrator CC 2015 (Macintosh) + / + + + saved + xmp.iid:b0716df5-7d69-4ba7-9fcc-0e8e60ff24fb + 2016-06-29T13:36:34-03:00 + Adobe Illustrator CC 2015 (Macintosh) + / + + + + Web + Document + 1 + True + False + + 2048.000000 + 300.000000 + Pixels + + + + + Futura-Medium + Futura + Medium + TrueType + 10.0d3e2 + False + Futura.ttc + + + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + White + RGB + PROCESS + 255 + 255 + 255 + + + Black + RGB + PROCESS + 0 + 0 + 0 + + + RGB Red + RGB + PROCESS + 255 + 0 + 0 + + + RGB Yellow + RGB + PROCESS + 255 + 255 + 0 + + + RGB Green + RGB + PROCESS + 0 + 255 + 0 + + + RGB Cyan + RGB + PROCESS + 0 + 255 + 255 + + + RGB Blue + RGB + PROCESS + 0 + 0 + 255 + + + RGB Magenta + RGB + PROCESS + 255 + 0 + 255 + + + R=193 G=39 B=45 + RGB + PROCESS + 193 + 39 + 45 + + + R=237 G=28 B=36 + RGB + PROCESS + 237 + 28 + 36 + + + R=241 G=90 B=36 + RGB + PROCESS + 241 + 90 + 36 + + + R=247 G=147 B=30 + RGB + PROCESS + 247 + 147 + 30 + + + R=251 G=176 B=59 + RGB + PROCESS + 251 + 176 + 59 + + + R=252 G=238 B=33 + RGB + PROCESS + 252 + 238 + 33 + + + R=217 G=224 B=33 + RGB + PROCESS + 217 + 224 + 33 + + + R=140 G=198 B=63 + RGB + PROCESS + 140 + 198 + 63 + + + R=57 G=181 B=74 + RGB + PROCESS + 57 + 181 + 74 + + + R=0 G=146 B=69 + RGB + PROCESS + 0 + 146 + 69 + + + R=0 G=104 B=55 + RGB + PROCESS + 0 + 104 + 55 + + + R=34 G=181 B=115 + RGB + PROCESS + 34 + 181 + 115 + + + R=0 G=169 B=157 + RGB + PROCESS + 0 + 169 + 157 + + + R=41 G=171 B=226 + RGB + PROCESS + 41 + 171 + 226 + + + R=0 G=113 B=188 + RGB + PROCESS + 0 + 113 + 188 + + + R=46 G=49 B=146 + RGB + PROCESS + 46 + 49 + 146 + + + R=27 G=20 B=100 + RGB + PROCESS + 27 + 20 + 100 + + + R=102 G=45 B=145 + RGB + PROCESS + 102 + 45 + 145 + + + R=147 G=39 B=143 + RGB + PROCESS + 147 + 39 + 143 + + + R=158 G=0 B=93 + RGB + PROCESS + 158 + 0 + 93 + + + R=212 G=20 B=90 + RGB + PROCESS + 212 + 20 + 90 + + + R=237 G=30 B=121 + RGB + PROCESS + 237 + 30 + 121 + + + R=199 G=178 B=153 + RGB + PROCESS + 199 + 178 + 153 + + + R=153 G=134 B=117 + RGB + PROCESS + 153 + 134 + 117 + + + R=115 G=99 B=87 + RGB + PROCESS + 115 + 99 + 87 + + + R=83 G=71 B=65 + RGB + PROCESS + 83 + 71 + 65 + + + R=198 G=156 B=109 + RGB + PROCESS + 198 + 156 + 109 + + + R=166 G=124 B=82 + RGB + PROCESS + 166 + 124 + 82 + + + R=140 G=98 B=57 + RGB + PROCESS + 140 + 98 + 57 + + + R=117 G=76 B=36 + RGB + PROCESS + 117 + 76 + 36 + + + R=96 G=56 B=19 + RGB + PROCESS + 96 + 56 + 19 + + + R=66 G=33 B=11 + RGB + PROCESS + 66 + 33 + 11 + + + + + + Grays + 1 + + + + R=0 G=0 B=0 + RGB + PROCESS + 0 + 0 + 0 + + + R=26 G=26 B=26 + RGB + PROCESS + 26 + 26 + 26 + + + R=51 G=51 B=51 + RGB + PROCESS + 51 + 51 + 51 + + + R=77 G=77 B=77 + RGB + PROCESS + 77 + 77 + 77 + + + R=102 G=102 B=102 + RGB + PROCESS + 102 + 102 + 102 + + + R=128 G=128 B=128 + RGB + PROCESS + 128 + 128 + 128 + + + R=153 G=153 B=153 + RGB + PROCESS + 153 + 153 + 153 + + + R=179 G=179 B=179 + RGB + PROCESS + 179 + 179 + 179 + + + R=204 G=204 B=204 + RGB + PROCESS + 204 + 204 + 204 + + + R=230 G=230 B=230 + RGB + PROCESS + 230 + 230 + 230 + + + R=242 G=242 B=242 + RGB + PROCESS + 242 + 242 + 242 + + + + + + Web Color Group + 1 + + + + R=63 G=169 B=245 + RGB + PROCESS + 63 + 169 + 245 + + + R=122 G=201 B=67 + RGB + PROCESS + 122 + 201 + 67 + + + R=255 G=147 B=30 + RGB + PROCESS + 255 + 147 + 30 + + + R=255 G=29 B=37 + RGB + PROCESS + 255 + 29 + 37 + + + R=255 G=123 B=172 + RGB + PROCESS + 255 + 123 + 172 + + + R=189 G=204 B=212 + RGB + PROCESS + 189 + 204 + 212 + + + + + + + Adobe PDF library 10.01 + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]/Properties<>/XObject<>>>/TrimBox[0.0 0.0 1454.0 2874.0]/Type/Page>> endobj 8 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 1024.0 1024.0]/Type/Page>> endobj 9 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 2700.0 1024.0]/Type/Page>> endobj 10 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/TrimBox[0.0 0.0 2048.0 300.0]/Type/Page>> endobj 70 0 obj <>stream +HtK,E +n 1Tm#0< +'-?s̬g te7O1CeC_W1f!|"xVc3NK/9F6~rPzaka/Y =~MR+rTǛvUG>m`9j0G\4lYZa 37c~rlcw;_&fq}DYQ_ezvڟrb_f=_gΌzQ +46OdFkSl+/Ξٙ柄nc߄!6< #GU]" b50O{~e|1]2`X=i S˃zVli$ƹsy˸$F\GgY-6ig-d$ %A2^4@D^F9ےRQ3El~M`݌H׸G,5v#*q˓#;o:VF8 YyGpaCCA R9[9JQMF4R}Ϛ83޺DpZY_mp-+lAm>v(J^J0*$r&aCܖc]0&3R$&XU5N|yN9p *D028g"+F q{Zf2SdNPAIrI\r_}ie:zLSPf:,EP - [4\d${O?&p93UyfI*,{A-mql: L'5+k%]nY'rS״wzƤz}8¸IC + CX=eqrQ ,@iC m' +@юYʁՐʰ{TWJJSUFJ0N\Obc+Edͳ*ܲ.(S#y"q9tꮙ"%,kP 0#QdžhU~GqK5,G 15@,ܬFG.Q)iK 8{y_0Bٸe{@W/֤OI_z{*oF^3!AWN~dlQ?Keuyz}?^?XT]:՜CHvͯxbH/9vokTUĥB}wh'qK9"|H>cO@ջJ84{^V|l~n0るN%*8Wd:!SJ]c)AFQFN%uAu0çPMS; }yj/br}KY4Y7fN}&_?j x_E]D+^Yl$s%E.\Չ.\pJzWlcdvB&͛3QU4y-YS͍/O{Y3kJ^(Bt.)jj*)oJ\w'=-O[R.!Z5uS 9w)% +3%*'h}A o苢=+lk%]neEJB`*5(iHJAAz?i#= 1EXH5<2U*ke%Z#kOF> +:Tp={z&j[:_`Zϩ6> endobj 56 0 obj <> endobj 73 0 obj [/View/Design] endobj 74 0 obj <>>> endobj 62 0 obj <> endobj 61 0 obj [/ICCBased 75 0 R] endobj 75 0 obj <>stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 60 0 obj <> endobj 76 0 obj <> endobj 77 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 17.0 %%AI8_CreatorVersion: 19.0.0 %%For: (Ivan Seidel) () %%Title: (async-logo.ai) %%CreationDate: 6/29/16 1:38 PM %%Canvassize: 16383 %%BoundingBox: -91 -2917 5695 83 %%HiResBoundingBox: -91 -2916.99054223728 5694.92631728028 83 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 13.0 %AI12_BuildNumber: 44 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 1700 -1500 3748 -1200 %AI3_TemplateBox: 250.5 -200.5 250.5 -200.5 %AI3_TileBox: 2576.59841918945 -1406.69291305542 2871.40158081055 -1293.30708694458 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI17_Begin_Content_if_version_gt:17 1 %AI9_OpenToView: 591 163 0.25 1287 764 18 0 0 -5 38 0 0 0 1 1 0 1 1 0 1 %AI17_Alternate_Content %AI9_OpenToView: 591 163 0.25 1287 764 18 0 0 -5 38 0 0 0 1 1 0 1 1 0 1 %AI17_End_Versioned_Content %AI5_OpenViewLayers: 7 %%PageOrigin:-150 -500 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 78 0 obj <>stream +%%BoundingBox: -91 -2917 5695 83 %%HiResBoundingBox: -91 -2916.99054223728 5694.92631728028 83 %AI7_Thumbnail: 128 68 8 %%BeginData: 8166 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD80FFCF85365B365B5A5B365B5A5B365B5A5B365B5A5B365B5A5B %365B5A5B365B5A5B365B5AFD09FF85AF85A985AF85A985AF85A985AFA9FD %46FF36FD20375BFD06FFAF85375B37615B5B37615B5B37615B5B375B37AF %FD39FFAF37AFFD07FFCA5B0F5B5B37303737373037373730373137303731 %3730373737303731373037373736FD05FFA93736AFFFFFA9FD07FFA9FFFF %FFA9850FA9FD39FF8537A9FD07FF5A375B8531615B37375B373737858561 %375B37855B615B61375B615B375B3737375BFD05FF615BFD06FFA87DA77D %A8FD07FF8537FD2BFFA9AF85A985AF85A985AF85A985AF855B0FAFFD06FF %5B0F5B853785FF8585A9AF853785AFA9AF85AFA95BA9AFAFAF85FF858531 %37373736FD04FFAF37FD05FFA852527D527D5252A8FD06FF85A9FD28FFAF %3737375B375B375B375B375B375B375B5B5B37AFFD05FF5B37378537855B %A9858585A937615BFD0485A9378585AF858585AF6137375B375BA8FFFFFF %8561FD05FF527DFD05FF7D52A8FD2FFF3185FD17FFA85B0F3737370F370F %5B0F370F370F370F370F370F370F370F370F37373731370F3736FD04FF85 %36FD0DFF7D52FD05FF6185FD07FFA87D527D52A8FD07FFA87D7D527DA8FF %FFFFA8A9FD08FF375BFFA8FFFF7D7D527D7DFD07FFA87D527D7DFD04FF5A %5B5A5B5B5B5A615B5B5A615B5B5A615B5B5A615B5B5A615B5B5A5B5B5B5A %615B85FD04FF8561FD0EFF52FD04FF850FAFFD06FFA85252A8A8A8527DFD %05FFA8527DA8A87D527DFFFFFF5AA9FD06FFA937A9FF52A8527D7DA87D7D %52FD05FF7D527DA87D7D52A8FFFFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD04FF8537FD0EFF527DFFFF %85375B85FD06FFA8A8FD05FF527DFFFFFFA852FD05FFA8527DFFFFA930FD %06FF5B5BFFFF7D277DFD05FF7D52FFFFFF7D52A8FD04FFA827A8FD27FF85 %61FD0EFF52A8FFFFAFFF37A9FD0EFF52FFFFFF52A8FD06FFA87DFFFFFF5A %84FD04FFAF31FFFFFF527DFD07FF52A8FFFF52A8FD06FF7D7DFFFFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFCAFFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FD04FF8537FD08FFA8A8A87D7D27527DFD04FF5B84FD0EFF52A8FFFF527D %FD07FF27FFFFFFA85AA9FFFFFF3761FFFFFF52A8FD07FF52A8FFA852FD07 %FFA852FD0DFFA8FFA8FFFFAF84AF85FD11FF8561FD06FF7DFD04527D52A8 %52A8FD04FF37AFFD0DFFA852FFFFFFA852A8FD06FFA8FD04FF5A85FFFFA9 %37AFFFFFFF52FD08FF7D7DFFA87DFD08FF7DFFFFA8FFA8FFA8FFA8FFA8FF %A8A87D7D7EA97EA87EA8A8FD05FFA9FFA8FFA8FFA8FD04FF855BFD05FF52 %527DFFA8FD04FF7D7DFD04FF5B85FD07FFA8A87D7DFD0452A8FFFFFF7D52 %52A8FD0AFF30FFFF5B5BFD04FF52A8FD07FF52A8FFA852FD15FFCA7DA87D %CA85A9CAA87DFFA8FFA8A884847EA9FD08FF8561FD04FF7D52FD08FF52A8 %FD04FF37A9FD06FFA85252A87DA8A8FF7DFD06FFA852527DFD08FF857EAF %37FD05FF52FD08FF7D7DFFA87DFD0BFFA8FFFD05A8FFA8FF7E847E7E7E85 %A8A97EA87DFF7D7D59847D7DA8FFA8FFA8FD04FF8536FD04FF527DFD08FF %527DFFFFFFA95B85FD05FFA8527DFD06FF7DA8FD07FF7D5252A8FD06FFA8 %5A3085FD04FFA852A8FD07FF527DFFA852FD10FFA8FD04FFAF85A985AFA8 %AFA8AFA9AFFFFF85A9A9FFA8FD09FF8561FD04FF52FD09FF52A8FD04FF37 %A9FD05FFA852FD07FF7DFFFFFF7DFD06FFA827A8FD06FF8537AFFD05FF52 %FD08FF7D7DFFA87DFD08FF7DFFFFA8FFA8FFFFFFA8FFA8FFCAFFCFFFCFFF %FFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FD06FF8537FD04FF52A8FD08FF527D %FD04FF5B85FD05FF7D7DFD07FF7DA8FFA852FD07FFA852FD06FF5B5BFD05 %FFA87DA8FD07FF527DFFA852FD07FFA852FD11FFA9FD0FFFA8FD05FF8561 %FD04FF7D7DFD07FFA827A8FD04FF37A9FD06FF52FD07FF52FFFFFF52A8FD %06FF7D7DFD05FF8537FD07FF52FD08FF7D7DFFFF52A8FD06FFA852FFFFA8 %FFA8FFA8FFA8FFA8FFA8857E857E855AAFCAFFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FD04FF855BFD05FF27A8FD05FFA827527DFD04FF5B84FD06FF5252FD %05FF5252A8FFFFA827FD05FFA8527DFD05FF3785FD07FF52A8FD07FF52A8 %FFFF7D52A8FD04FFA827A8FD0CFF85A9A87DA8A8FFA9FD13FFA95BFD05FF %A8527DA8FFA87D27A852A8FD04FF37FD08FF7D52A8A8A8527D52FD04FFA8 %527DA8A87D527DFD05FF8537FD08FF52FD08FF7D7DFFFFFF7D527DA8A87D %52A8FFFFFFA8FFA8FFA8FFA8FFA8FF85FFA8FFA8A88585CFFFA8FFCFFFA8 %FFA8FFA8FFA8FFA8FD05FF3785FD06FF7652275252A8FF7DA8FFFFFF5B5B %FD09FFA8767D52A8FFA8A8FD04FFCF7D7D527DA8FD05FFA93785FD08FFA8 %A8FD07FF7DA8FD04FFA87D527D7DA8FD0DFFA985FFCA7DA87DAF85FFFFFF %A9FFAFFD0EFFAF3785FD10FF5B37A9FD20FF6137FD22FFA8FFA8FFA8FFA8 %FFA8AF84FF7DFD04A885A8FF84847D85A8FFA8FFA8FFA8FFA8FD06FFA937 %375A615B615A615B615B615B615A613737A9FD07FF845B375B365B375B36 %5B375B365B375B365B375B365B375B36370EFD205A84FD0BFFA9A9A8A1FF %FF7DFF85FFFFAFA8A884FFFFFFA9FD0DFFFD0F85AFFD09FFAFFD1A857E85 %7E857E857E857E857E857E857E857E857E857E857E857E857E857E857E85 %84FFFFA8FFA8FFA8A8A8FFCFFF5AFF7D7D7DA88585CAFF85A87DA8A9FF7D %7EAFFFA8FD64FFA8FFA8FD04FFAF85A984858585AFFFFFFF848484FFFFA9 %7EFFFFFFA8FD60FFA8FFA8FFA8FFA8FFA8FFCAFFA8FFA8FFA8FFA8FFA8FF %A9FFA8FFA9FFA8FFA8FFA8FDDFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD0FFFAFAF84A95BA9FD5BFFCF %FD0BFFA8FD07FF3785FFFFA8FFA8A8A8AFFFA95984A8A87DFFFFAF37615B %5B5B615B5B5B615B5B5B615B5B5B615B5B5B615B5B375BA9FD2CFFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8A9848584FF84847EA9A87D7DA8A8FFA8FFA8 %FFFFFFA9375AFFFFA87DA87DA8A88584A8FFA8A7FFA8FFA9370E3731370E %3731370E3731370E3731370E3731370E3731370EA9FD3AFFAFFD04375A36 %2F36367D2752277DFD08FF0F61FFFFA8A8A8FF7DFF85FFA8FFA8A8CFFFFF %AFFD1A3785FD2CFFA8FFA8FFFFFFA8FFA8FFA8FFA8A884858585375B847E %5A847DA87D7D7DFFA8FD05FFAF8585FFA97E59A97D7E8485FD04A8847EA8 %FFA9855B855B855B855B855B855B855B855B855B855B855B855B855BAFFD %2FFFA8A8A8FD05FFA8FFCFAF3761375B365A365A367D527D527DFFFFA8FD %09FF85AF85AF85A9A8AFA9AFA9FFA9FD4AFFA8FFA8A87DA8A8FFA8FFA8FF %A8FFA85B303737852F362F5A7D5227527DFFA8FFA8FD7AFFA8FD64FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FD60FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FD60FFA8A8A8FFFD05A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FD60FFA8FFA8FFA8FFA8A8A8FD76FFA8FFA8FFFFFF %A8FFFFFFA8FFA8FFA8FFCAFFA8FFA8FFA8FFA8FFA8FFA8FFA8FD70FFA9FF %AFFD0DFFA8FD60FFA8FFA8FFA8FFA8FFA8FFA8FF84A9848484A984FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FD6AFFA9AFFFA87DA8FFAFA9FD6CFFA8FFA8FF %A8FFA8FFA8FFCFA984FFFFFF7DA885A9CAFFA8FFA8FFA8FFA8FFA8FFA8FD %6AFFA9AFFD05A8AFA9FD6CFFA8FFA8FFA8FFA8FFA8FFA8AFA9A8A8FFA8A8 %A8A9CAFFA8FFA8FFA8FFA8FFA8FFA8FD6AFFA9AFA7FFFFA1A7FFA9FD6CFF %A8FFA8FFA8FFA8FFA8FFA8AF85FF7DA87DA885AFCFFFA8FFA8FFA8FFA8FF %A8FD6DFFAF85AF84AF85AFFD0CFFA8FD60FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFCAFFA8FFA8FFA8FFA8FFA8FFA8FFA8FDDFFFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFCFFFCAFFCFFFA8FFA8FFA8FFA8FFA8FD70FF %CFAF85A985A9855B85FD66FFA8FFA8FFA8A87DFFFFFFA8A8A8FFA8FFCF85 %5AA87E8484AF8484A8FFA8FFA8FFA8FD64FFA8FF7DFF7DFD04A8A9FFFF85 %A87DFF7DCAFD05A8FD64FFA8FFA8FFFFFFA87DA8A8A8FFA8A884FF85A97D %A8FFFF7DA8A8FFA8A8FFFFA8FD65FFA87DA87DFFFFA87DFFFFFF7E85FFA8 %A8FFFFA87DFD07FFA8FD60FFA8FFA8FF7DFFFFA87DA8FFA87DFFCF8584FF %7DA8A8FFA8A8A8FFA8A8A8FFA8FFA8FD63FFA8A8FF7DFFA8CAA8A8CFFF85 %FFFFA8A8FFFFA8A8A8FFA8A8FD64FFA8FFA8FFA8A87DA8A8AF7D7EA8FF5B %A9A8FFA8AFA8FFA8FF7EA87EFFA8FFA8FFA8FD63FF855B8585855A858585 %5A85A8A984A984A984A984A9A8A9A9FD64FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FDDFFFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FDFCFFFD62 %FFFF %%EndData endstream endobj 79 0 obj <>stream +%AI12_CompressedDataxr%&p=1L3}&N7/ؖB=QAWQUd5eMRR $ea]?N_#wݯ~uv}pw۝<}w|~3iߣË\vg}/|vͫ׿7xk\Gᄎ_4:ίOxb Oۿ_{w5 wo_~u>#; q ;)?o>~Y*DZZ7~ぼ}~ۇO^^{wvowgprv^m^x_ݼWۅN?/.o^_c\=x~lׯ_1{!;t=|^|O>~x Ng;,%/]u#Ӌj޾5wj^K}qkL >`p{#7r)8x3a(e|qĴ>`RvvHf{~0x6Gw}L9onuO>=z.ל޿ >Ѩ;,S޿|}%c'_\uu,97\,RI/[su˼XF/Y>%`b ;٥wf~|vnzfN_?\bfJs^MjF6B)'7r!zw7en@11f=s"֏jzL>̚}q߂O?{U$mJy߿ҹ=\C]wc<W7ywrz쓳__\\|p}lOJOWZJj;zys 8WRRٝ\׋WWo-s(s3껓;-{ee零wڕZ}?NOe_]}+t%k~Żr'}۫{ۯOƛW}Q^{ ' sINSsۻW_^|ջ[~onnυʿ\ߞy_?r߻W_^kG)p'k0%mۍp`~s#ˇ/ \7o^>98͋-sqr5r +]:~#BKSW7m=;씩Tם|y-E;w@d}׫wS};,tD/ʸ:wC>x\? +}>B,+Ӳ?i+x:o^s㜓bW/eCݝ|o^_>i+}q!9Ӌ/I;HݽXq#ouɺ_Z1hav/y{D4 +wWG<[ņpHKkљpa?\~u'7{% j| }Cxɛ믮v tr/G8__g ?oY߳k,w_迫/m'#ww~|]k?s-~zwwwWr}G 0oikzgdh07/ȟ[}&_ϵȟߧLV_YS?ׯvjW{*-YIy/z& AߎhqӭD<y8hfk4tJ~xO_x79c3)ݛy-|Ͽίw,H<뻷ͨ񵯯ni+ s,xjt|]ܽyK^WO'G=rT;.owgz/HliwxYH_8wS%H.'SJ?˔4*.,E/Uǖ?v"U +:'?i\Ssٔu ytn.i9tҹ/RlZB?]ٚcV:-R7M_Lrv$YV;.fT>LӬr/O9׶[Mü_,8JdS5ç9s.$WXu21$)daH\!p,\2X>x,Ka)4C:Kj~C0a8.Kۍn#:gxEcNݩ? t8OOOHg,>!Èpq2;g 8NggggXlFfxΝǼ /p1^+v.)ělN_,"-aNWi,EJW),_$HXݥiMf/~9_3MsXEiXHqBwW-]$Hʐwe?gt$;s5[YS-fc=_wjleDf0Fo=bqenFDG4QҐSs +9yI.'GiwAiN!'9I>'BAA\^d ieeOe&G/fd.d`2C'[|й|t9Iz`n~ c̃YPB(蝂 0 :('%fqOA61RG K,s v7ܗX!C:R $࠿9@Gr@}e|9>pb1CppXn瘋KnjqcqXXg8Nq N(ʀW +=ʃ6pAlloHe'6bRJaCN'(r +d=iN +d;L.^IˆE RӇ?zٗ*0s'wr N˗W4 +WrV3+,QNL Tm2S%X!Uj }ys$ˉIZ1 )8| +8Z2!,iμTfq5-T˟Znj\D|_*UZB*nKoX,.ӡNݤ*Ie'u̪6S)IhtJDXH]PJg&!JsX:^6nMSw4CC+ʊ~?mXh**LUhfʩh?ǜn˪Shüm|ZD-l}'J#MqJ)aJcNS:l(t "M~-Pw>Ǩ΂DsΊt",~{l]r{lˢwz񜢇wm f90.Ǻ&icxk7֏%T' t9zcR x 25BMܠݻ>c?j}"# "vC*3jqt4ҁQ*ݨTiI]>iAI{{kp>Z +3c'%k1/>v@g$?vY6#. zGd ;B,օP|r4-.ܿo *>FaD¡dC&`(̜a"jzԳÚ=vfO:LʪHNYa쳭d3]Y+l8QW ^q<{Ϸa2঎m+dwp<D&"&M#zy'ɥ~Ü7XUfV[' CE܉:Z[Ycd,U,Ę]Dy)˞,{AQˢ[)cEUWY $vV Y!v`"Ŋ t(;kfؘ/O#[/f{vm䞿 PSNv7mMn8)bCF*fDn7 `:us䆸`?l?f/bA󖛷WzɊ+Ϙu4Ke;8e&Ҵ՚[k/ڄ},X99Vn񇯌}KභÜ?>tPnvFGuyfʧӜ;\\Rz9qwBNף>,=qCmL?IU6wVs{zo:m, .˓py.~kS'kcǏx w r{4J" jGB fIt}c~iѾ{r~K/~ZY#_5vNnop^.;*-W'/p-Dtq#uyʣ ¢( +z貿/_g̻u0Mmȶ6 56a7H&kp@p:$g +iCIȜehS9;ľ67aar-vJdbfId遊=K*>:/Cߋб`{ZBӋ(GGJhۆG'p頂=5W~=AnHY֫|?7"ߑƐ} Y.28qMJNZሯQ911qp Y㶪Q#3>oQ7TQ'X;3==b9BAK~Mnr܇/UT?nJi͛{Qf}悿.lw]9ɥ " >"ĄIRI<2GP1P-ɋzVk>.E +B8dŻ0;hK="mi$*P| 6EdCȵ$aᆜƜ2/2&g(N~w7))?iJÔNtSiYDnf"uO)R3TiH]:mّtH̺ݶOPm Hm%8üK:kMy,bd].ucqj }/Z.3S0}(5Ornksae.ⲑO|\NE5J.uv+nK]4AJN̢Zfd"9NP40fu&YtNn3#)SW=Jxf oQxCdmSbOTQ`I +'*#\x%a1T=t;!mL,1[cv̑CL9ve\GN$M<:QI x94с& Uŭ2LQ%vq3Eg3sسYc-QV$vm +MZ-4VuڰI&l<+5zu*ms+|Oe*7u/_¢D;o X"`<F (0Xeb + +0jhMMop.~v +&P!Hn +0xy i>q]X^`&S"t7eW1z ^5fCfW4q[q6mjuYQkez̞3gma禳yŎh6RE*8IP_(/g?BA~ PWxۼiOccli11ٱ7{;J8W fC [K!`3=Lm{Ka9u*d.} +4W9<:hD9fơ{ZEcx.1҆wt:NN8L;y}4yyzޤou?Y|۔N5}v?|662Wc6MUU3+Mh-V ladO84]oޚ+23ҰB*0Hߵ8$@I^AlPMJ&7nLQ<YzF0HG1i;c!x/2ػ!ˣ/lo-UPhnu8&Cs՟,ǣd "n܆7g׮>k_-Y98H_x|҇>Ī|0BWa[럢myX8[djVk={ + | G>ՙax ']0q>1nȨV B{Y9";VYnN3E D!9e e p@*j%^+ +i^M*KC ^\w]C7Ղ;4Rjo \0/_/z=v͇섰X0k$(.г3/\L½h~yaSz lCpyj GnHF'1^2*F2x\B+\X{K@"+(]/+%JQFl> 66ծyymaF Ɛj}h{FQ=;Tqo0(^bad:g 0T.bЫgt8SlwN Ɠ)#gk&A +`cX@,q +Sl9r޸YSN#8}jZ.7K#5|u +ن݂Tffx9 Bs} bg'7.a鋎^r5K]#=˘xbnbn@b%w<#o~lv +Zڨpk ,ٴ Л!A+=7󶂑{Γp++e}ҋc2;}5(K鴑u=dM8EI$ՍYOE8zj@Tzd[~.fWzBJ=vce_c 3nzV8>%l\Mџ$-ί^G!_q)C~\f(2 +Ef\V9>Lo֊Uo˛dw11b.cHWb..\B>~e.Y|:6X!ױR+<~ g`&?ˌF(F>>MTGYug\(+:?HJ@7)@}Vtt)PCFugg_Lܑ6⇦_*ԥ1Lr^\So\&<#)YUqK&֙/ƛ;dr=0]7_W%/WgBW{kAojnZciMV4mƪ>r*^a;v XT_4\af{4vp"k;rn'Ij+?C{rNjD=c뛇;z7l՟?Zo`r-CU_BOd(Xg0v39~ ]B7HRAJ9MPVVֲ +uj8R +FuEbq0cCX%L :gQg cń +}hTfT+:߀yRFnc! V\2X\Rxb -^݇-btGZ} +KS +nqې69QIQԸsao.6 ~ ?Lݺy%`mi:-3Di9R:? t R#&2Zb&jUMjl +,m`~Y +,_1ZTexw>~G }-s|zp} 7]AϿq?Fi1~O#;oΚB`S(=?5y/7?`Lv_+}3S[ؽA~T/zY-;98ypsw{u=99ݽ}ū`Ϯ_>fꑑ_{\|"+_zdɂ5حʥtSfcB\}h ]Ma+i~5IΘ}vqd;. {E'e!֌1l0#M Bo!]C%+*!oC>6 (mqǽm $~=iˆq;IrE?#}}x|M{C<!p\DgzF|hHOb}61^9 $/`it0\1 CwoʃH }98#q{^3bA$wf8.}! {SF@PE٥nyLZ1Wq[رf; '91P"̕`Pd4>2{w7챴) XUXAt,u@VHƒևZ< ;hx쑟K^O@xW~M V [$"R9Dd sc1ˋʙUu1@ =~O'&tɢ/l~}úˌS$ SG)+md`1 -bcaq D }na v`Gax$ Fs͉c_W>j{-Vꊭ~a ׬ +5tKJwK :n" Q4qކDbӓT%]KXZ$ yyCdY#2.ql6BTp -d.WoC^2`w@x0؍ݢ*u&V 6˶}+Ӗ]|R=:S3G."'oFl]rGo63n$] +쯏@2@ը<K/l+& 4嵗gyVV=xljյ4UΑ+#^ +o^})޿UndϮ^_=\z&V\˸ov',p% +_2AeFPT(O%C٬7dVMf\KFbHf6<4acmW" yo9ĤRQ2 ǀLK_[ի.fvR] 0ġ3ig,Tɐp{&}Ra*ވgmSBZ =6z 2g_ QC[bp:LjЋfcLۚJ&,`PMF7z"@.ED2=x&p{ C[3C*Y¬b0ab 49KȞ`LG}p#;  ,OV)Ff,xAIJ?S*RI9-8}| ׇA{0<zsuȔxhԑN#;79ꎌ{&a1[flqɷb+*g 61/LL_lb@ײ:#wL+3hSU$NmJV}VS+c|fw9 %Ҟ?, mu^㹃!Lp큼蹑ChL = SI8\.B +`v9L{Owm;m{3Ayɨ D2~TgfaC; (AT8 NJF&J=HtW`'=$xJ +e  +nIz$u9Cf>΅A2!Z@tS2]U&x2-ً@Q$h*2QHXC}KfKB6 ijw|=ұ<9].9Yٍԁhp*KA pSvL>?/ +h f`o)=lJHK`y!c0p,`.j04.Q8`8a)ֱC*SYn.$~a!qʝnђs+qIXtcwF*)Q= @_VhXS{'xk{0`דbP3a͖@`mO+`J;Lj2ϑaO {9xAjO^G F>o),1!"M56>ROVZDZs,a)LNL8|#nĀYp8]<_12X ccbƩ fMk؝頧-E9 "Х)&rEaI+ڒH6&䋰IG6ډ*MF@S + M@*4>*4T eݓf X<< l kMlmahRR>c߳~J챵PlH!kmJrt&QeIU mAA-F=۩KSbR4]iFYVgX>PEuLƯ~dQK X1Gc>JF9!\8"-vܻ@3ݞlѮmrFr<7MoգP96vOJ?Y>F6,֥, F8J\oY}V8j @)7TەTEਟ iec[1MTN82;K8ΈUO'rO=aVd/8YAjix3֫,]JFr\-791w`y{*} ;㘥4)q)PO ULcdm)Gt841Mb /8,cp^P1*)1.k ȎҔi,KYYW\q$A&K]\ȿ֛G􊡩K3 +|65KT-WM3Uwmik>g~̱a[0W63[xʹ1L.İ=,L_H +^;Ǖ +cQ}0>dն\mS7O,b? N02/ٴ U}qץ@3ŭOʨ4<7joA\?:=ey1=i08FH-nqdq]$G+vrTzv  tEGQ'D)5kHI[B'?!rt= [}KT2RISOMߵ}b+}n.-cBݗ''489 oMH|Hwh +Yn^R4A閵hy +PJ8Р^QפZh NQMr!L|HLYƿ+%|a&:x۷~g 9:VΙtp0+3ى!_!Q6/MZEsy_6Dga (kKMk7@@i QѕWWNZD2nƧDFOs7|q6؛S4^'+m~1~<Ǹ{1(MD:h[ulJl:nS9znt)Q}Ҧ(G"JR//TdCTds?Ԕ%ݨݦ+OQ7S(|'7y7GMirjvthO/ֻdl:oH7ګ TrE bǦko]R-yԵ6.[(=5ؿH䏻g8#Փmէl֋1v:Ntc5%ϟRgloތfӅfO%-m R\x{%#ј ."BRm[-`QOnX83}yuMW[RFJoh8ЎL[O3MWPߝɇ|;* HԨT&snK%FI|v:sJE,Ж(O=V= Kxg)G̨VHبҺG7fDZ J[M3MWcP@$0r0g; {Tapv6Q<D\~"p/lu;Y6 @DQpTv09ġxJH^`BbBvzيxw{D_=(k$2JSfg  J Yv" +_xL +yf*19?tC$-aK|;N#jsj+{3QJ7,^X-!{Fl-G) 4E]Mq!.p숥Ag=5-Ѯ"U|=Өs0e !?O]m|F`Ұ(<"( "¤eۅ95Eހ&A8\E'!^ ){z'VZyK#ECS!1q.MuD9B,rociP">Ͻ9(@YНrX%XJ(yvXӖ(7F)]a( Q*rFBbyk{Cq%ű!yDAD(~ 6ƕJ=,`%ZgCf!E \GWkb%XЖ`,W~4} Gꧢ>>R>ŏ5D՜,{S<@]8f +AQJdcnR@oSᕝmT/ |+ܪcFFodAXŔ!>1I*h\QT'dud,IH=V?67&A0k`˞v.{v *59xUB .1=!IbzOp+uꃴP;KԴ6:BkxKyAU mzl<1C':o3( +0(90v1;0di Њ9"(BFfHV]@ cX=dԥ bcu+MJKUZ0}a"ti?. #VӌnӕfiO,mBzAxv>Q%ՌДĘF,Ad2( !nΕ c6`bā-^ґgXmc8b'[W-8q`5^=hZ-Nu`FkD-rJnLIo /73W`pT= ҙO6+Vpү'^oh 6M\+N\SBEik_1S]mMt&: g=tUJ$+ KTN5 G t9CPL5?n(c "5*:Z>mEFF_LV۶$fb<|hA-Ajď`d)dFi?c:Q1(h؛Rf/!5ghj6N y .h(#TSg XѩJUV C$ѽQ*l9bvESoQWQnCb6O[t2Az%4r\]^cZ9xYD&A[5YtF?5DrGθ/ _m:G.B" +-ИlR^S6ДFM8 ȫ 7>. ՟V aӕbRK֠fc&M, []A#w]{k6%"o:CfF)(`#rg+Yp´5% +m +1n/MojJ5c'&i<nh0 *Ív0h +m2CzSfXf-cFA'ƒMA-Ey +,@AArz +Zq#!:2*@ƶ +GhY Z*V_7Mu)j⫾da,gԌM]O;u_v_Q;/A^+ M#afG[YrU1=:eN9]~L-QӶV=FqF ^vɯ>eJ9X‹6z(^p .U%2 H6]xjF6 E@]@>oK[l(76K 6@hj<iC"8Ch{V,J=iKT_a]jTA7'bt(3N /KUVSmۓh:eKS LL9țEU+ׯHTQU,3rCV(&_GLgF%`预2F7)56GnbhBkW6j) +S穔Q۵һ!džiҋ > +|oa\=y14!-m['pylMs)Wn7=v_sR;C>/]+X1W"2.9"C{ zQW1vH7ZS=`{ _2WLum3JOU*AHM|kD 'xAJVjzlz|| +47Ϡ=[6abrQkGГ^sPO\Η: Ė: vit;1+.3r׊jsC.jIzM۷yAn1$6[Fmbt}zN%΋Q{7e(2fu G,Fi6S?}ʪ ^3 ׽i UQw˷\1)nW7!*b6={/kRm=@7}yj*~6*$1j$qJ +iiTEO"g4O0d,b4lPeCD}حIE~$_BSvJы5Iq놚@H<$*ChFy by *7CbPl^&M)ZZ} Aw^L$~ DhPV&M% 7/UKi!huPvBZ^n{](Kpm55]yj~BaԙѰ.G#6Kcxh}9D[Aę!}I9YUtߙԖPik`Az Jh\KSb]8Pmr8e-Iq/Ǧ'kۅ#Q \dڛ 2r{r $ж,0^1?P܂'HQVdI#K\Sn TL:1d8 "o#[|1zȈ>CdJGe[ׂyAGq-vXM0s +(L.P + +qn$߷`iSkaDѓ }}5CC5,4U + Lkѵ1m0 +SQ ( + ^u +vkά`,7'ql|%z &Amۙ36 +0knښ{5S4 +U;GI?fnCp1nQ5!m kl$8nk -ngpj,*}Z+ LɥJ}.F"|,ӷ0W6UYJd3~j--R͟QJ:QxCVgԑ4_aP\SaMaU +=oᤆ%57P pF+߂qA7;1XPCpȅOD +J] T^miά610LqN]Hi36 +inT:4Q9Aё+Lb +m-͙58 m"d/T̸:P*I%(*4FsHyV[X'ה=2k!R49j"^x[0G +b`y4)[@sf-TXDSESKi꺎 O?^Um}hά8tn`ͻm@ =?nE6ڙ26x +gn{!4S4 +u;Ʈ .mm2kTѹ @xGi#߽플- 9s35Q{>-}(ea:6<[^~'Q6B[0FE#bo)#( + ,0ɶ8+xGE10eS;5Ի-DR-?=߻/};҃N>ZU&_߼yۇN>}(Z;;Y6dd٣ ~q^8֧z,]~ҿF_ܽ:?TzO7_}o6}6?tth._u8SwA =xj *4V$צҲho4 ˿WZg"HOvxG{V~?Xf޷yW/vsNg/wD>`M_ʘjWu@OV+Fky>ɩ* ~ -RDGT02 Rf2"pF2xK3}fբ +"ϧ+D: tt8`yA{Pl57d'Tu=b `x~Έ3^]t3'}">WT IhAܖzJr!~9^G5@dnf"Imgmr}-u[d4J g/^ E)ޝl']O"P!R9DC_: W <C8bTQqXƱ9$H)3GƐLb_(%'ΠX|{mGF>T/=ARTT/p(ůd$ "UK=-YH{IDl>Z*\!/z1pz@b C1d NKH6G}â H>"p354V6B*^[Λ{eӊFZtOGDE4NG_Q zH ?~Xqߒ[Z^#zZ63F5f'Mh@)ZBY0%%tM5XUCY;PF/tA/q†*A oH83eY̦LARd Ч8@HxŗzHId%)!D754Qq2̸f"Z >w +#(\R0r,ы12.-´ФK_aߤwD1".CcDtIhh%Wc<× ObAM'dnc:Qf%|\@Qr yQH{Wһ=/q<%Ε$"zԑz%yƒbT\kwh06^3D4:fLp @zx'!Dk:$d'Nk: Љ^Q6SQ%Aq-*SD,8D(L^EQD2eE *o:|\vq^\9Ry +S/FQi.Kv b@LjHE" +F050== r9HX"\i8}vf& 37=:ȅzBrEyˢeT=یu bl|u f|:$R$=2J{ +N8CLd2)&( hPq+եJw##&n@$hECGW8x*ġ ȡK -ඤiM.VN8A!?Aō#LASb́=,''(S :Ǹm$4~(GQRtK +蔫WbWQQYIAq%(.\G<>+&E/k݆wr53 2SM) +L'$:HKڒd01Ӊ`Phh=5dI%y=XAKUlHbl#3[$3 60 w%`qc[/|սVY +L< _ ,2 P"n,SаyxWO,1#Ugzh3irN8|2t"Z흘Kh%O/rƑnŞ +V%B +Az?;ʑh2g2h3ĈZ!9BkCh" $Υ#*6$ @(93QGwQLŔ: +!L#9O'cҷFĮ7_C[nCeWQ CuG0| "bU aP*·۝sMdHqy9s72iӧ-lhe̴2U$.`G1DoVs &p-H+?3dۑB G#ɐ=z_Q`| |BSb2C zA 3C\J%AH╇ÒCTG|z VXR"=>W 5Fn$RJ[JW^eEC Z4 )`rn9?8_HtZYpd_ErPH#D%&i4UJ~! I5j}Yu+3EI9f%d.D>SucvHeҐ)̨Qhfu ̈e& FBʼG0nc +F]OezP@ٳ⿔Sh*wljʝ괒!}%D@=b;9NVv' +qbXa2+f聤ܚ\J=`ӆC%Wdf =23ˆ>x}Kvc 7y$MՍIbyaOfqeeN3JA=PJKXe)P1 fBqPu!D9„{E*"qLSɇN+|&4wTc\Emlaʹ2SVg *mu xn"6exw81Da伐H)ir0F y!+,ت?U<]UNn,;JVD|6ճ'd/DԙPCO0*(P_GN~q_.xDf1Lbz,JN*80.2L5dBސdQjq+-,yYs TPaq֊tJḲ"$ˊK]xG8H0~T8KYY!m194 ; +?3** 77r%(ZqkT&d@gXսV +hp  HnbW3dȬNԽδT z /= ᮝ&H΋ޕ'>Va3R&JfP{!^WTNDݕ'oFGaq]SiErؓw5<ĥh(YQ(o}+|9&xQ}sTEf`MȔ ff߇ݬ2K=ɤ: L$ lAVeUʫ*&?glL[ q1c :OhAEA%A@xA32 -s%c:E!B4}d?Q,a9 1A^uzh#O!J-Ai3XEYJdޅVKX#,J1 +i!M`3JT⊖Lә;IuZR<-ZZ/$!4؁FRi |!X< INwY|uruRƙV+q&EnP}Љ?j ToE a|}z\|Pz8p,*hȽNBcufi3+=cOs1#CC l1tvDVV C1[U?w-Zp3M==":Ozm 1z̫kbl} ʴΠq"t%ߞyIN֨s}9b1U^f^z%p CC،R^ͻpW|wuꕾɑH|YG6J7^fNRq":wDZ_G<&c-B_;v݅_Ǭf ͐m!`d&F0 eHx}%g!Jt#NM睗ϵיo#: ɽć UyugD3 [J1o;†+2'K|JU)WG9xG6F%q k"%+iVس SGYFũDmQ_1] M-|\F)aNpqoK4zRiq=W#~KUuyX4]E[HI1D]LcC=6L0~bʌqybWh\AvZnKh49rT0JO0u^Gg)>i€u3T y9Mpj  @Kj1>tNA9S[3VGp`2nkhjF-u"r<שGp]kyjTs'FD)3lS/s_,0`nf㉧QM_:3\Vl6aZU䊨(^E2Rd5eK-V"(M1H}m+rF‹",LC|qU{79}6 @[ns,A%c0()PB{Jw],TWI&!AP_d?j>A⺳7 ťsd#^4FUejC#оܞq.S|2B0T2L& 4/ ,y# +#pSS,#iEy.__q-oB~yjݨ_?qsY&RHz31VGĀC= +XV +yY$ݨ6̷[̀4\|J<2 +MDXB&z1;Kz~"qwC~_,pW چxz#~qې'1`IԔ_RMxYFmp97HH;`ƘB-+6 + =<28h;WH\U|)'-˼)!#?dN,26(-?}ǚ%<7r~8=9c2^˥D!S.г"ǎ+bfXVTaG탂;>ؾxl=~H](ʈc +̛}^CԏH fM v#g]Um7wsSI@G!F5Hon5]\d.K6V1zs,'Veȶ\K+$ |$v1#>C@%B0 +tfW$'pJqbi3ϧ0v#ocS*ʽ .X{SK҈w4$LȔi*[9#ґk߫6QJ8 梳 <E:ȦΆ +hI-9, fG>(VbZʬ$bDyFt|怈s;$:զ3x8:}?PzP\ i-v+#>Zf#8%hw0EPG\ ʻGa@oϙ(Z)NL W[Jc6N&եn氍.eS4xg/_4)ŏuNziGBxp/(KpN%#I3?pI4(J#4ix]'A^'J|Fi*,oi7kCwTS؛Gi(jA=f4-?EfVEQ_$ +Q;RFsc=vz*/~N%!M X^FF@P)GOF%-LG9il7g[ +톒oߤqɛ6- !h[>[x)(g!+x<|9̗0KFW2Rxl(z\QoyE 1VW眿-#cfJ|t6wKۿ ?xB|p"&!޼q;'{g^G:POgﶥpǍe#'HZ3{0>V)y*zN7qQ2h +7VVJ!aN\^w]}3̙azQ2dvRː!WBav1m~ױĜI*\f+tGkMzD`J%c:qR1(9D8zx@+ Y %7l~+ }]636{ +^BzNjX0 "(၇@ނFB]/qRb"aW My*ʏn7t9G(Ǡ<N8B *ԕBoyE1w1 Xw}%şEJ紺)vU(.x}Fo*K{ :W*ߴTJJ&AUkEFQb9GCԕ!w_\BgB}9~  ll'x*|W 7SH$Q,J]3in8>z-z gusK +vG2 RܜL|O,4}0#$ {nn  4 TEI[y;hu?7 (񊗞+ hnpVF(S殡Q`[qSX[($K{KhfyR'% .)ऎA6ͫ/SLc>ej K=z'փFĶ<񹣝ePTQ-LuO?5H(zBXQVufabCzÖq..%S468fBO+pn+e  j {<6ڹ%d"I*"[X5(lIQd߹FK*WlH6YVyf:33 +S%؆j2Ip1}s R u8Ue">?']Q뷋Æ&HkgN7j势 8 ~QmV +q+S* F r(WZ~Br{CŪ0$4Rv|.;fv~t23Eg$Nk>_9p=6kΏKpߵ2\vhU{'"29H͹ FIsLeyR]9ۖt $J9qI^sxf2j\DxI%"EbuK/Qa֢J.4tKhLPJ 1\]8eXmռ/B5 Ռ0)T";BdVV:9EƧ.0@-Q8gXe0}3 *bf;AMEI %Y ځ_ Zu5u1>Urvs֒> +=1Y"qi&"]eʡ>B  cFtB ?υJynq-lT'PRr aɝR_OƴՏx NC]muEjTKAzhK׈5vWQ{e^FK%a% (:S/a8\toL~_d{@sz?槽w/Wհ 5iIU[MaӇ/Vi봣4FؓsG) Iqc +sT]A"QB ?lAKS +m|lתF <<g,G֠'Kl:zP!]{8b#B)uN=VP~2ˤаg%1=PtE +\ T 9*jT78ڱ=nE2g锼2l;$]*8< vŬT}ekTӇNGZ!ws a9_YcI^^_T6 u~U{ksTOՀZbRB/ce-pkD\#%$:2Q9N1X͆R*x— ud 2, c|qC +:A㈏h:ZQT0N{`a)AVsTqpFx-U}Q8ыs"92QBw+96sx26Ғ,C}C<@"<Խ+jPi,hTtSJXk(2 0adXq|-Y՘zβ o@dxbgܺ}6.g~CIIo7)!]$X(}|l5DI _⢠vɫB>R-WN x*YyF>txϦU8b4sU`ߞWPeT]"B ZD(5%}Qz?ގI==ZL4uI1X.(QT u6gh9Gqzw5[ sp[|3aÔԓ&阀RI4 9fȑvPk]#Ps}ݰ! TVQ6xJ9c†zԪ -XA+FĪ +>b"JU3/ak`ںX)_pϳsQsKUd㙅c##׵[UcVtĀLH3#SS#vX+k +NzqMa.@⼼e~q? +: +ݳf3u#"ԍXg=igoYEm|ӫ2B[!EnpWMe;b:RNhC;$S̶ &ﺖyޯju^\T<"̓2Ջ2p:6g"T49若3*ir0TOb ws4_4t}n U (esa)#2FNo +30-[qˠEFv~Pf+#DB3Ċ|ސƟC`mA1bv}p49\~e ӆQF91Ayia݂m w:ʪ d]X,B7@ubz:һevZ} %Pb-`-p Ѩ.ayh (RQ<\%b#& $Iݖ|R,XTaƂyk2Gbɣ*y6N.6՚e[UV>/8%#G([yRzd uĒѨ~: +(x׵tIRu^7ύ&|"#@DUɿ =떨"Jrs`R*}0gQ3EYgnP`N iI/?輳}#$wʑ\)k.}zg/aɚy9.hpZiyDCڷY^H<Ҙ`ٿ-f|Ac?;Z? .兔ur+L:G'N@*Po|6Lsh̖׆Mاk183#T6{4p# ra~fvRlx}p.g)L3ΟϮnG^T<:6ǚاgdUo::3o-L:I@;~ ꪎTiU|ǾcLjyBI-,4`t==z.^'U@8X81M;I࿡~r਽ep{kynTw!kMs*6K)ʡ۴0a +KG}kCH2RAZ4rrQŴqPG8,޶X9UHĝx{<Ɏe;c P-_>sݙs e:s3)vY. mMC1}s-;#vIgNZiLȍ$sJQ&~]mCߋUʌ:=%A]Oc>G|O\a˾ykڋ]WzMO$ՔfUbl%o}JJm\9ZߡlfUr V# F%'ɴ歔'ʱf"B#֨yXnur䎢! _u#}_VXdW P8qsjp6b/o~q ~窪a YC7v {qT,5hT&ĵ~ *d,-Gggx)PoJ 4icC̼͹?q"}|N{av{SlyFDG]'f55%{ʥ3ﺎS ;L!5ꮯƱ-0];i 2U9kY w!Åa-͹k^(4ֻ,%?;LR`m|Ž8ŻZQb=?X4S>)n#%LEʿm&)ؙkpqW}F qNǬdSӬ ٘xW[ I +9V-❡~cn; NEicYuFty,:˹^emg h"X4LIn-<)u {4LlPϕh)D .g=ln_M^a Xpvä6=Z +,8)plJ-RbʸD; 㼻XR]Q;aƑ"u1μYr"R~P#[*ȵȏ 3T*,k;jTvF<"'SgsgÇ`(EDgvLcP͆`əB]P@=R_=_׷ its\t}<;k~mu$SkW ܟgMOVŸyI|*43Yz\y[ /5p-=+Q/i;u \옽X?8!sÂ\Q c0Ёr|PVȟ!aj7DB!pi53}$P✪%,I!Юr pŢ1,+ۺ+3-e z{[x"!%J^9pK ]J<>DIѹV{1T?Ъ S:(vZIKӬa0bsȊ9ŗ $; Dzhr8Ci>;I|;vU@2{D)18soGRˆK9]u*"-Ɲ!ws 6a2> N28A.|E<$LX'bLh&r^3 +hcIz,*&z`16 +rkLz(c!":`Cm}=۴b>z{n7U"6~VmW]Z8O?~?__ÿ[w?o{_vo[4ԟ6bV37Bw|.)-FQ]f5Y7j0! `/n[3#8̲ TS~lqf#7 90"4"ۇ5:O[Wu8I{e',;V-N(*.P +LH&SҹPhU Vg/ٟRo=IDh|Csu_3D$" h_9(T|}@oj}uI`ThzRW"=a7ύЫg|U"qs7eކVW)XxAV]?+:1Q5͑≧yīTF[ڏ$xo|g_$(,%U{w%Oʻdgq3=̱ u m|}?s;~r;B,f?yryRڻqG%b#QQsqYf#߈g6y?1xyK`{-Q*NzBxo:#.흝Nq'Ni +LweP@]ߐP˸6ML_b)JFLB̴|>-buaѨ +F Ԅd~'RN&sPnP' |H~!棻p2;4҂'(=, *Acn6stSH J{sܠtW$wM> Ź(Mtd[vOO ,6䋃;~~ms^c,جs"LOq[m7E4 <fjP7I7{lX9 Q?M&F Hoj_Xq:^لqA o?fDa∇oB4\|6+))k7"7'\+7"'WXE#vS1klw ED]tn7C|, ]ا2K Ů)@k]q(! ??0xjҽذRHcp|՞!8"g}9dO< كTոEovOuqcny#?y8:#EzToLasOՃbxj'[+7 dPU8G=Mʓ3K'm,6A+2oiTV24iO4(ـGSFj3ƊVfAѰfCkfp~"aPtHnrB}gl2= <7'9`f:Hl3oaNJYIiٲwH3tfe}973iPeXx˿Q[S7o9.К-te|F/oe [b''xɇܓĄ3ܦ$S@DqÑ'1D&] |D㍀7rcӱfǔˆk!7&Y#&1OzO~m,0@-3'5{rS0fcQo͞Krso0h4O-Eha԰IoaCo(aN!wJPlz_Ф;fU k7cf0,:+ȱ7x˹t1Ar+MX̘=[j|x%S-z/a=˸ÖeF2l2/߶sOs}uTb/ƽx`'o.8F"aO~msQPy},ص_LeͿy'~mi+>{AK PZ*> J{P4^7޵v6KJŢ]V61SeLwMQa#Ş=|̞ܽEc%c=yo=%YOԜ" j*¯=B[dfǏZRY WrNWN+=}"\1h"JAAk#-/(/d>Jmgs\ +P^E~}h}E"Y-7w$;LdhM+@(E?P̗(ZR٦gK|hsB' Gc{~B*:w9?I>фM"xAR;&%1[pxMcϰVѹ2HC To Z{8SY/m7U2>L8S)gK{Xh TDkŪH;֍h H^&0^@?Iŝ/RΆsfi,@oYӿ)|ȵ8pYb +Ytf8xe>*E=f~d^oD^{b|dIPgn,o\P\)4lvF97_4ȸ!x\J#dfŇU`ٯW9t?o+EO륗VݠW"&2ߕK{R]yS sGĴe +t<7t|#5rq1n+5qpunC{BP↹zzOI=j H,WRRn ph`FvAc~okd#y놹Ff{%G`[7U%o;N! ةhC]Y(PPzXzeP#J uQ"3}C]#&Jp3P>4yS]mp=rJ7ՆZ}ZM9{wea}ԍweP8f5Mi4ae85|٤y= 7+ U<9\~UB}`_e>qs^mľSc^}E.R0A/+E>T tn+Zz\cҨ9>zʮdQ#bPQsYA|W1`>X|_i<~G_ XzX-}o<ٮYpk_,XyKqu\Y\q2`]@hjp ?XA`99 +#.iq$}̀Z +fz$`,;}_OTe6-ՃM~R: ͻ3p)?_7/x+x/ķװM7̳w2bx"h⫍Dg&Qq{_iw_ݍ~_;8ƍ~qX7+_ +&:v^Y'u$S vc2|![F$o+&~MsmHW^#)0*;>j=wD6W1@KzT{*|*%y(lV_ZLttTd^#azao_z0#tԁ^L%fsq|Oy<KȺIC8?F1* \SL\xL%FY H^7k+oR^f72*A}JD8KJ>ƑM C\Ȟ7ph&ۡ" cF7k=M-.PPI7FY2VpoPK?rahԵ.F n.  &lht~rC?1#>ufN\hOm\P -}dz-iw88`"ɘtj&#Ȳ~9ѓǷ\"M ;Mf[@6ǒ=!i5EeGx4/gBʰ-~iA21 G@٘4Rz 1/ǯIpD]/&aj3h̃Icl Pk0LᘯM/Lba` +6!ߎTם4Mn#Œ&SॖCpu䅿9'+vu=9߰K;:1h`ߨte"9µ0#ߊzdHHnV'́3-<9/#GRGv8)Z َEot$]DY Mpo[F-^#:nbΈ;e5l#^F^ch64mصz&Zޑ&|Ž|E*)O|b?s6M%g0*q{ByGg鸑|H*rAEJD:_u 80߰kR^vCS>fvfRD>:4&Zp~]7ؐ cxeo|!OBO6pg/7"yx OD!.+FPC/7q<9dkΘ3j;{\PrvNX[W6vm4{"7rlHgך&9?z>A4^Zi BV3G9yaWq]\0BAI&$9fPQU2N.uuZW(,F0 TdVi^S@@{q/ ׷Z/I$KjA-|/ixC +@$@&foZ $0 +PuO|yi¡- x@4A࣫&>!FHxu縡5pê h- Jj7 +vX%U]^ h"@ @Ws(P1b݂-OZ!RAwGm7 o'd$@'Ṽ].x$@4 I"Ҁ1@w]o$@cB YG$@Ui((7~Xz*ZQSo Ŭjj+a=k(^Pޑ9DyW $uL lU7o g7/*?7 +U,bYA Ѓi +9< H:wn]/L&/D7o@7Oxalbs.܄nx]h O)Wh,QxK3FʫDWH۬{>SuPn  u `L~4fܙfw\y<1s#"`8 ('*rY1,⼖b\73:6pE4Y|x-~N(9*;ao?OS@q˓\Q;n'/r$E7S(@b{?ƅKDHz";ZDi1JG?NJj?~;%(IE/zL?HHZ#cI7O?*ml3=h+}3`x{1T"sH :0Ǜ !wbEgo0Ѓ'2P ]~Vht%ެ4O$et5n;*aIZdzXQd*G . +=nU'Q~s)8b^6pOПeB>PKh@,I0s_.Z/s7*F9t$}}\~ŗ#yERB+_:khż*uՂmg/_V8 n Y{g !ΰ)o?N:sqg;^?g3)7O hkZz~s^ "dfkW|n j]>~7W-' gf1Q}$7[y'1PbZ<6zoCJiJ{pֵ[ ٳ|gal) +uG 'AJc}}GǪ.k0oLcp<ɥ&=x%#L";4mf}_k#@6i$16u%+rH7jٔ\iJrr|(/s0UG_Izk8nLRW qkxϝf!F ro!G|5]Ƙ_#h,oՍ92d;ڍ7"ZȠ|-e%|BF.fX4FX z (!^.27-|-BNp}RjdOnaCaCV 7.7Y{/g?st]'5H:~-%gMC~B`>2{/7s?`ր,0a[o:pJ*Ro7gq!X<,?P>m,FrX4ϼ'1"hKI'/)ǻ7Q%g6%fv}#wڱy\T%(O|ta__ʉS/dNbʱ@)CBt' )CڏzƤ!9_덺Qp q:c#b9o!5ykJ +XOZM!"qLC?@jJ +'`&&|W\E4d5$a[1"ؠ8w $z]W?tClr =tdfdil]R "Ak$gѶRTy.ck6vk +b\c #b?slIqr y%|l+1~/д"9hŃQ(Eܖ^4'g^/a%ոjlnqJ~pX=BCFA,8[?}nj%>#GfD-EeeRWGcQb!RtAXǹ\z9jԶ.)EG@,e9MyI:1JhVyN<)\e'h s5E +*t@ýJqr (6b7/ܟ#]6cm-\ 1_(oGEAu8=y +3$0+%B*ˬAjqPvcP6Ÿ-g;1 RMs9>IWH~9Qz`"Ƃ&L(Bf/ k+Wd\'GAA^C܀;3sFzhPg/?v|; e@^GRG1.xuxE^8p0L8N~9{MzP1믲zx2 +iV_dc'S=OLds9ė VPNYpig0-AZfV(BXH]T=XD?93uгA:K->Z+zeypNk85Jg/*j}O,89g|H#z`7E01MZTQTm|FХS4+m:ز]uX +vL˔i/=P& o/˞QIf:'\QPst23+ +yRUG]FZ8^?}|HǏ,x@>7,м[>?Wq)^2(U|tNYM jd9ir0d+51~‚y$Y 穴x@ħjcJqFn +sڛۗ^$blv#|*7-s.ctl0lu[I줸NN%'8NGd~3=:cDoŠ9uBǙ)*Ds֪JۘciesYutlX]qd|q4ԢlG`̳A[{m`M8׃7C@ I['|UٯJt`f. ls{ \*,zY=mmY/": 3U42L2B`Y=K:PӢ#f1<ә3S7sntZQf !HBXY}`Hrjg-k +yꈨ,U?ϓǤ 0oT$'n}=k@vw,C6bN5s:^G/V G == t1у[K|6I=¾u%8Π\lKJ9(G}c # ZS|W~8y2,@mˢ{+ +ZjcUCqSαʵféǸ27O@Ë_H=щS0R=3t #Ƣzn)yq2<3csaHAk|tmg[ܵ#xR=؝]oz0 q*`GF6쁩Jlp'K+0T+30Cꩌ~9z Aء;mxbHuU qC?v'VMdZXF޾- HPP02!q6 M|0C&KuNJyi|:me!a8igE u6dmSNPܾnfcgq gRMhyt㪠Btgw%nWJꪷ /m%(?8tDL"=Tڣ"kgqa',c5Rm)*H+% <י{DI]`%jD14`5eA|XF5\pcZ+/L©Qyc */X+UDnbm +8/-INs߷=I+YU? ꖿa!>(8ZX1g!be6D&(e"f6ye\Cٍ ?) +swDkv;Q:Mdw'r*0 +68 Zv wTҪ &A 1PYs8˹օ]jk_]%W6Rԡ$blv)`a<.gV*Vf/ v)GF 7!  9h$6eiO'0'Eϼ1)tS V6orhE;笺^z4Mؙ3rL~-q+k:x 8mo--$DS{ +o@ =ŠY/i v^2|K5&e ʒjٶ},625vbͱF&.\[!., ɢj/u'm֜R}7+3Xݰ'L ~".`%W;~hwԋޒ'mg)Kc݃RvhT w ji +=dؔ萄Y$oh&L_ 1(0eH(h/^G(`@EI^d!ft,Z{a@;1<0j9+TwxYH+RvfPe`oD;UT}ԇk1nmвh|anb}vy7sMxRzgqQ/iyz}=#v&BS|;,;ep.{ь["I;Avҙ;k9RKDeX5wZ5 oq&S=8,4IGA9ʑj_7,UCz =`i>&v`]1A ȬG`o%~x{\6OHb۠q~=EcZp)xfh|*uOفߏTsnbBT}ZC3 +r0B@!i] +Cnc$r6ْly/ +e G&G}.7bm}㷕 +^#z.P'HV|`HѠtO9Mۋ5;j!9}$z!"|xs7\݆='.t\@*,(ڹ +G@8$gpI#eD/#v†/[qsIp*J>%FlC'*_X"{bc=(9{Q NY!aղ9cܩig4"yggDeO=%qJReL **aͷ!!Fɏ=؁r$ +G͑-8CX¢Sjivƒ^xaG#a$Jv1>=1Bk/!((餄Db',YeKT:,e &B8CZFJ + %Ռ]+=c +{n=qYFV.TS^-TRM% v@Uz`=pi4uSCAfʴ 5>C\;0|]1(r(FCC:Iٱӂ\CSfG}u*_`/FZ쵨?B=T+v~|#9h 5/15Q5 l/ØRSئ常m`vqΦ~ #l8~։s[ |'RSE2r).V׸_cCX9UԻŹu%kE(X R.d$y~QA#LcYǚ2J{\?:㒤%" Ɂek@J\LS+ɢdfhhqq8*^8ıd*'n0ӢZz\*RNfU 9EHuM_6 ǧh9M0ńb[f?26V\]*/Q~! Jh.cvd^ʋKbdR7 Gc%q¥1?ofPh3#EdnGK*=XVZ^x`r!IW,/5̼廐NG:.ɳ|Je`>UOjeĊ5KbӬlq|p11i zɂJ ͓+PB 'ps~#~ζKU]>Ga:JYTn(Ll9r:t!5)ynn;ZV\ml5F{Hʮlm6/0lC84BO쾷4y& ^Ilvnt);X(DX~`%* dnaYI(jA|J֜[$ۣG5r1'BR6kI>}9l{JfֈP=]Xm_ASvl9l*QglBJD5S*z,}"v+HXGި7L@5Q׭ +U!!]l<4*R){]֔ _ci8 @S xd(v +-vcK7U G tÞ\>_m%3&+= 9f]˖nE`~թ=܊!sKN[.9x9Uc!ebvb2E_8Z + I#Qſ,rjB4gr*lKf0n-NbRpHmD6>9}G$(z-Gt)_Qa>.(QyZ#9eOX)Kș{4BKR\8EP6<6 =LhYy`Y!c,O1Fw]-SATk%U="Z=?zzy棄?9OY<ԜtыR }"L]d)h#L?Qjŋڠ-J.6SfQc37%56@gl:;pzP(B5#JYW=QVE&=upb i:v +Y>TKu +0".ZTe(zځ}zl A6rá$*HGcjK#qDfW"u$Wg0BnBmدUND!AT\X'ǜB?fWJŃWa4jU!5GL`fJF%Ba cL0:8"K!_↜E%ˡ u2,8UKCc_z}Dt^kz٫8IbNļ 0_!y(_jҬd%_=uwA,JkH-%0ˠ8"ˇ,vOF7MY2x`i }˴$.„WN{yNl;i%*SzQ? +O2`EbyZaޟ˚f+*[P :b]W1)\&LߪEJF=u܈ *+DtIhlPO_}ُ^E QXFkv047`iIs\Xz1Ѳz \}e4X'oK (6 z#/`W Q_%(T3±< qNpfN @|HdkPyhWʚ +٣+v!/gYH@>\:KúwSk1 y=}7?٥&}{ɒkD N^\K1|q=\kxK_8LoH=3XhbcI%*謁u3XBdGQ FU"B~#s(C.l+#>cD1 +TP2;w=4Pawe%JfS(/IpUâOM<.%yC-8a‰.GԱj=C̍jd +C-*˫8Ϣ:np_{pC`2- ,"6Sh -{F^9@y 첒-L̳Sw` @5gZQVSX[[_^{'"eSk ]#8=-Fv)#??Nwpaw; N{aN6p m(_v_9>@}2SBzL{· oT9 blL溊C&Z qc"FϝQ=:7nmei_yVis`|X% D+#3>P7wix25F7hã]a?%vO?>b)q +J? K,ΜuӾs@kCeQ@KvӜʼ]H PDOac~P+,g(,9+3c-Ms +z [+MC#O[l%oywsSTa^;οP Xm`:e%p?I&[. +H8#JRq,X1ر=]QnuiwJQu +1MR T +Wȓ7޲$JR ::֢֒W:jLZ +J[e8M-Ϊ.!,O8v1,SX,acw_a;*!Ģkr!p:w[~k-*ibsc>mIY_hb0;9o(:B-z%?e,(p,ϭh_=ujbXyOL:7%E!JbKtD($Ңa!PI}W~rg3q8D~# yCpQ^.$ʉ&\ĊJ7[xR֪n'x|-ve<1gbZTR44μrIJ+P_{9'KmaiI4R`L:kQyЉ*^gpD7kګ[n]%;@NqRFۍ ((V[K%gI>e ^ps3c{%˶"Ē @HgnZsPK>X*>;an"_]GX@AYqXU!n*7r*{W; 6T>u/jUHLQYCK!3~I:$ZA/6 _E'QK;+IDq @4ϓm'U0|%Ln0p ̀G2RP~nS_߆V6s$1-,S uhr_=TsX~_IN;VO::bIY\$PVjASyNwPrw8PLY,bFR>J!ՔD!lClukKcIvZdrFhcAh3 #pY)_5I]Pr&!%-刜\IHIj +gw'{SS0di.0!85 S&R tXb e CstP/e ٽοGni{tĿChѣI!_,5rVV -|RFfzEO;RK3^DVrb>#Q;@Aё@_\6o򎑔N3!gϓjΐ"t%aAmvݷkH6KZETY^hv"Z s},zLd}}:US9Ek7!$,:ln\j%2 D*!؈s B$vV %sAANLMΘzp!̸//MfbRptg5\V4}+Cr]_.Dzh=V kLvn$/jwR$NnA۪xr@lF5/ DK m3B{f_5o~=nNC݆ - S'J)L?!nO&H-?!:@#k9"?iVo#^ɉ8}AB|?Wވ3y +2 /`0@xTJx9?|^ AƻhlaHHxiX0\,ZXk %I!@LUuݻ, +d$(.[zϹ@pz={uήx#[ȜfW+YceH()?Ǵ?CMCFVO#LV ,vӱ$ p5ΔdK"q% CO(q QR`/+koO?Iy, n$ eDD}LYLY*qRIN`_Z^j$`+N(;Tdغc{cA4b=+XH{{ 6 GsF`Dl1DIgv! eq:Sǹ\r^7ڗ;qμ|4#2zy5Dl<(Q=r+)'bЀMwvyD,4Sj ع&3`fuCZt7k>=r%w|0[t@䍣w;ؙ':-m8S@!嫆To$:t-X,h2OF,ŅInFsTbJvэv?v,> +|fU,,q㽒EeXˆj5 ۿ9dcqDu:8ǂ&пQ'}S]dO p#[t( 0HB#} #6t!Fu0hzwCȔdR]ڛ-BjITe _ :HV3$( h^dphWFǦ^L7j +U`w%:oHRObw? VIrb=b>>4r-j9?٣yY#JA &a+oddՉqv6P#W2 x{' dF:B@YtGE{ohņg +"(Q< ǥ2}J1A i)T\S&5f +$rfрp3d!x00gs0CPHL2r}6K CK`KUxb9ʔ'/SӒEY푃!ִRs8}?[17zV` z`cdC,/;YsG : U^=VI]eAQς&&_ɂJPZ8!P.]YPD;!1@hx|H\6s;zִ,^4\V-DA>"Wx4LrzxPDRzf%LP5GW9`r^. v; J0N +ȡ#+tмmDgr|j CݣhcP/Pb(!C.S U$c@f+>hޔ\R?gwXɘ -7ņ#MiD LlE8l[>g:tEq0 ؠpes]?)pT!$4 |X(ɆEFӐOr{@[}lڽ{HQFf=ů*^j<Go=zUF]W F685{@>RKʴe{ o0ƾEZ,lʕl`TH~H̊l":#"(Rw%ɳDp 0r|1C4ÃcL^<L_:7w R_i_Aݣ=J1գJj݊#PlkBY#2)'jHmS@fBo79l`o>M,jCw2NpRݤ6sr쀢Ŵ3orU$0tcaPc=5JھewĆFƝHf#L+4Q LdP(PM;)5kS/Ph+9€fM;s3\f-==Fّv#5 .LOP==Wg`ճ}}j9#73bR#6`$O3~^-V9nrc08`6_#C &̞g4Lu'zV4Xa貀6?Kdg0Ӫzejh闽5TUnZZƄ5C%ވ(' "$yP}^{?i^֪Bug|Jv&7e.tlLTȫ˛qe/[聍k2,3xK{irKҰ5XGn6[u9:u=}aY8'~d"*ΚpP:=GFY2,wEo))DH0ok[\^} 1SYՋ)KɺyŭEu倴tKDQEO{'Fr #eW=#_/MvJ'4[ Yi,ykxOOX`:")A>QW(.@COHF|`|l=EGaj8$YȈWOgSQo+"|JPt6J)AՂem͖ hKwSaYNf0Kr_\{mJ,{hb,`01,Ndo$_#1=`W +RƯA2mt])=4QuOR^G +MH,ȈΊ( Ё׌y|gzǀ=X/f˔֒WmyB\HP̗D dE1ܮ4, QwD5Ok3SF%<=E4g,2̓@ROfFe +bX<& +@0AxM**–#DSɡ|yvr6wjʗ/Br-)E~'|:Y9~)bQa`NҒRPv (?$\cvFP_zd׳@G. _s2zžc&ó0+*Q ɒ +cR 4W,BCSNm˩BzJV[CR .:0ג4ngBp"/.S1CUdS[RK^FK.`EL+K DŽs +ud.$(1^USXxeKRz7]gU$/jP E[/92#>m!.ʑѦ (nfZ=,-`]>TB+ +Q&ܝ gHgC -j `/)I =3~ʗW +&l3w'nK cgYSX C•iMЃI(B ~y`+],_4rc;:ד &Q7m]qڸ(Ɔ#S>*UoQF+z99~T%aM)i;H#ּ9r X #xRVsLACRV.+zǑ&l(\, mƳ O'Տӓ: j$4-KWV~1OŐޟDpg~o߿>|gٿ{/``~ 1K@4$Q;D' *dFJJp(JM}g^3@dZ*g~ N lJҤr*(nye5*bOm')?!ϵP endstream endobj 80 0 obj <>stream +J@bLTxvC +g )Hb״ 2= Ї:"logKڟ`B&oceå +҇[d$[38q+"C!$䩶tEVjo + 1@'҈@RҰJ9#1Po]z9s|,c5b#^vҬ` wh:Pi{S&#v2ZI'ʁLZ p(8௪W(R6|3\rh̉>č]~MD{ӃoB;j +Ǎ$^ )o"j:MjM͆25TUEf? ϺyQ檕 +@ qr=0VNT= - h"r`Q0!uBJ6Cq,zp(W2w4y8 ?J2't٧;DA +G&8HܲA>tP\*iO{PV{ܟd C6C@:+a7$}U~FCocfnu:z?5_l% CP ֱxD&| F_ǽ1lQ"0@fV8EnN$Vl#MB|ӣCJY{)$ȓ~eêGFЛOs9dEn9ǀq`޳㛳SNAb~ +BY #0 x 02G@ 8r\:d8jxX|J4>P&_wYz #yh +.GQSB*rU Bz(3RjrǍWUЈw[H8K{hzH#0O4JdA-ݲ7^QHl> &FOh4 QrJCe$ +9%CNrYj+f-2n2#K R/<|<[(#-U8\dSm+͎>?zQ W_ A/WAlp7|WhӴ[%&7*€=<'g_T÷\@}SGdZdMTb`€oP!g!xpTPͨX>P]BB\}PԥGʚGmJ NzMG k@' aLI.jc@g,}~BX߲sn ZX +2DJY5mEwXql% &MnyW!"{ΡuT!LjнI(S_h0bѻ@vTuRF + 5hjs?ZAƻJZw{N{u.ȥq'#j]r;}kFT#A_\dZ|ԖH)Br:;گ@| [DR))dp*a3]059xaK#E륜HG;T7 ߉o[ދkh_c#Sj)rN4!$>[Y&?tPoB]e{{MQ3D8,=p`{\_6 }0pGrʁΖ|'oRhH[V1p=s MCkK<z;>Ԏ_5} Xa@vuS +ᐰ1PWy-_C}7t`TdҘn4#-#*2^Z=qlȿiHAMBsP]' }r#FS N1d%FҔ +DDRҪs$3t7KOWo"fS( ʥ68Х AAQ"'Cu86 s'Vv}bH0RVXGJ9_Z6Xwb 9_vL{fMR=*$у(bצ* ۏgGoUI=qNxJH)gݏL"ՂB)%x5;P +ꀸTלREn꓀~dGp8 d RI0)(}y=e4Wc*iO(૰rɳ*|/Vb*I3ijhbGTRnACֶo0"%q\֏^s&wl7-rm5x  u@1H8_aggf};nnA͆SX0WPޣP9\hX4'idZu6} v@E AjЃfG'Q1"Li7i~Dڗ ez{qj]ʞ~R-JQVȄaz&GM3!'A$p0ir0dEzQ`J6={Vk{DL^)Rw\vጿ{.e>?] Cd<Wdg(?ՇSfՄ*y~hho5ה=$k2ih{+%~t=v)G 5uuk X-[M!C%d!?C O/d[^323[-%}[]nK7_Akr3lC9; +'cxc5T#I$}6 _U>{ + DK +S֎[Z4s0{pܥmYxptڝ7W+RXR8)j#D. ^͓ ThH9=Sj#(RRA7S /ml㴗YfVjNO;*W!c녆}[A!0R zH!@=W ]A!wG*Dx,y.Ptٞ-ԶQw$6\Ѫ@5_"79,?JJ!vi&mam>=X%z,"DLc4>u%Huv_N H'v,Z~ZF"E K嶄5;vaCTnD+Le, qƁL6Yh)vUÜDxP.I86{ldEA{0-%C6 +X<{VWb<8`p$FB{năuYiȈ +?'* v~XL WC %W"P!9\+4 +̱))< ph|E'&OZLә0Iԕ$* e1iY^ :uHʪ*Os6TYXCafbrw +h+?@MX3e s}YhLҞS5*,ѫhU#b,ˣf'$ϰ$'=?xt!5`v# +'crហAaDߑm;Dz)h=*LŪT_OضXjAGB6M FܡXHR4Aƻ7<ԋx^5\Lt~@HiCH&0dD~BJpNwrSFZV =<gH Wf.5U<CWʄ9j;V*2DFH #S,#%C;n/IV:Rm^\ujiKCV+|q$e4aaAYx{p4X`8^x$VQNF{IƝ@|-%Jd8R8a}7(PȵH mM*4D {U2vj(ˠr.zڦ sQӾOwādŒ~_$(ۈ,DIk3;Y1硦I1S@v`BbRn%Z@0'эHCr@|Ƣ_D +?X=5S] ,m'`(}P$}9?(O(Ӑm p |Zo2˭if8HT3F2]SN89H,è) =K d-6X#XϐQ¢;{0Q96pU$Ȥ>Z<2 WkAcq5RHT#mzoI. n&WB/2x:Me`=9EBt|j47BM~$ ()j$r#*dNt>Q`S擔N,Beb,< +(tcC@> U/JYq;x9!jJT5L}UKna=QEI/ "p{b*AY(D` `yrÒe9\"KCd4:(t=R~4[jfvǔ:=,r"o){9h2U,/W(cO +=S9STK%z,~K=ɹEbQs-OH0nվSww*)Aݡ7߉T ArR#(ڲoJ< ڞ' #G8)\ Qb^]>L]r^mHJRt&~n²JĿWZ#dk|/JKݿ>,^6,m%#g0qRtH3:-DTve{R.u}Oq}Yg(dKW5l%%(yk Yx=W#V +dDA W=f: +^aҋ b:5 +D*oA3txV,Ys7QJ$C/()w[؈P*NSNȘX<Ck &qh*:hıl;mZEPDQēgJLLBYzdYO!!@qnp Kv ;T\q&r-rDR *sEKV Vʨ#.I/i +|9Zt,m!& 1z Ni .a;'jKVv0'b$(.&:n[ ØJ|ʑÐZT~$SDJ,kOoỵ  Fi^DWI9rf4YL9oyy"Cbxy?;eN<%AQI`-qGV|> +D. N8B .X=q@JOTӭw(0PK#UwζSGK~m X&Sf'>[U90 g6G<9娧}-2%zJw&Rb^SHcAGV}%StPB +P@k;$"rj3Өl?ǵj`I2X9P|@d1-B"|pODT;tT_ʬr%C-:v i8kpgKV#9lܐ怄B N.pReo((AႨc@zj:ilzJ87<صʡ8R߃b #+h\Sbc}ΕN7،Y!O{s.Bݷ0L@} v0 `J%$1fACfP1 Qo$+%a)A܀vfPƀ0n4벴H؇-fFoՁ}EboQXyo/$w.3L H>IhHv} KV_+^#$R΃'rh_=C!$`dn.,2 +ORfq` ,'`Va: O9QP +X# JF e<5ٵ3Un*c#KHS>&E JZ6.RbɠH26}|Vr{ݧ  66iie#'-m=:%Hd9'U瑍_2ֿk8.6Κz>PV>}ciuT +ʍ.1&t 'Lɴ-Ety/$Y@`k?R=iwQXk *ڢUc_!9+$YLtkG/K^zDia1x g%ƳAz~%ņP2_!/ !%/r]j'2G + 3v]S.@c,PH@vC&0UKPn>FL쁛R/M-;=JTD2zh,|z +/P+Hx(,ƂK02F E)fltr* -?P7Xo ' 0ak6|[tbt0zώ !1kCn"6 /|r'Pbv}|<(RR(C GAaA.f0ukx Iua$h^xÍ|@L`3RÓBG_v-> ¦} d 2J-wh=TՌ)fމطGC~A] w$[t!>hNHd䉹JQ\Zx;Y}kE؞Tbu9U^yB>m_mz( g,oq~bFT:$b( w(>DlJ8cNܶ% 3mٚ kt e(/KU0ڮ-gB S"ECk +ViVH)k6LkZ"]LJ5j Y}P0W-)۫ ۉf_&yDI(ܧp*;J'r +m64Y`b$@Pb-if/ +hQ ;1pshU.eZ3%&e#jm5jO8^DӑtSK{F,H9LLH 3+;sтGJ A/}$FEޯV(R<5Ik=3s| OC".J%!u%㿙8E?ҥ2Jϼnǫ9i?lTf顦+kǐ]Ƀ:~ζeQm|X.Wl%!Pr.) N'^qФ!$B;][>ؿ8)Yi_IA)?2E_q6GDr7K nVG֐=ΈV"{ߐ$ +T Lv?DG%׶(#%}RIR/*|Ʃ| 8/Z(|6Lx1d0Uf"Chх%pQjǎ~5>8(daEܖRLg͈7 ;zS="$u*@ %էiu䡁%vE ߩՈ&Ni42_d#* 42~˜ޱj|0$/BRi}~ϑO52;zNi igQz yyAxXs bH"!$M"BklroauSkZ{uEt2zNe1F煭ݡLV o(#M`jG=[4u,?,r5P|DiɬK xD@0jXlY' pE ;L{sv$E0K:wd)@9NNR|1mMdj&hs)2M \8.""fgI%n6u9q~9.@^b -Zn^.XSr I*}r*ahw[$%m{K+(~5t^r +Ļ= уja/C,DH]h {e\V&66y$Z4?N=w+=xlԣ~Q\b;'RZ@i{IsωJˤjil9RMA~#e":-ѱ΂Pv?et]0dF籱.kRGӁt>Ri$ ?_@#_f Yؑ-8fƠ @/0ѣKF@䢢MpbylӎuCKq}JEJV{Mq2D vP2p5_)<Yg=,XK{Sa,Vn%y FipHҡeB>vWŔ)kӏ ^u!\QIK~kY}=K$g1+<% ٮo`3Akt:j2 1˔-˙JHU=L95Fo֒H$R>xE (NloaH-5>0:3U4s^6z )\#P99lQH9Ə7 ]HZa%'*6:-bd"R1vE I@de]y%+ޓuWd O/Gv{N׌HSC4|<Ŋx1 NK榰=X'=X'ECC`jSe$JGMw?l'=F~_ˮxEΜ_uĹ#b/9O]W$c#ˬRiVvo=vë1C'ªMIrY{|f:㺿N+G4kĆM_8 2Mӟڅ5j( W[Z\_t1x򌪱feJ,.^?K͔Ks]o;Pj\w:uT;X(^r 6:aQuF׭ðc)mOqēY&d2z8ok/E-]ۇOg#0e5*D<`ڒÃOV!@/Sk6;6xO2kFʼ/앃(eC(>=5op1fDjD K=MȫU5Jj,=;/p!0rst |HY+%"\O q A:E!AڌrN +;YDVqC$7ZcYYw$,c4]>+H({TuvZf$[PHa`|].f *Vukײ*{če J'v@T%2XPviQ4z &=L} ʋ Q/YL 6LI`b  \P!=*xLM' XB=vl&Tgs&E6 +!]Ԁ!Kn19>н(/%O4ChcƙtOaYÁrMKmkЁLދߏZ'҇1|tk>{~`%A-E N7[x.7hoж:7- -;PsfRrMmlvtzM1IgWS0_d3'}ZmlFΌCMfLe"_h.U+A[E,Қ3zT5'c|A8CӴXLeq;XUx T7}oUHDrX{,\Ҝ8-9}%lCfڙE>ZM2>'#.vgHtޓedB쇘9j:U,(Fcx0z" /_Trfthǹ._(Y!L$d",u-RR*s}0*p>(1}ГsN'obH#=Z3,fT2u=>u4 X1"<$lPvjE]צ2M}` hk&Q6lX=lǢiK )D~6y.FfA=s2֜oULh2[pFX +$C7]gPFdH<׬ +jqK`>1#/KHƢ<ı gKXD ʁ8A TH&ڴA\:Z³5UgFGU7DV\͎bA>e|G ~Q|5p0;BR/}|s6Ėc=誑TWA}áA2TA* ,Pbf`5p@m}:/r*̒\/@+ ꥃځ$,[rU<dµ〳Ӟ |6 O#~ 8CGf&QlA[.i$v̎fq2k?ºÎ \Q/ZuBRohwqomR_?v"eN`HOt ץ;ќ؊eC5X&!e߾hg +8nI:֚ +7{>.v{H lTQ ,Qs Eɂ1LTÔ!4,ě/C( C mbp @"~J9EMHctKTxhx9%$^z{Ap"sK}ը!=fZDKO LY88n+TqZ=듶5nղU+鋢G']ߗ)5/="UIzj>pRs53(5DҼr')E쳋I54 Ā+z^,ЬlH/fWU ;a|bC #igQM^Y64U@ñ 4@!Lxp^ROk`5V# 04ADӪK"0C%☪Y!҄ZD +#m~~!9!f}u@-=grpͱ_Y11ظ?ZX[(׵Gh59E 3JyW~gij C-8h^5gyY|`n[y1 h%Kd)頃j*RftҁnPr +踢T\31q[Yrϳw"fVh}o/Yſ8{XTHp{dst9S ;]y^,؁ܤ4{`aJ@ XOD +=nXRW +Jt&);]Rۗ%Q8ln2yӥQΌb$pc#o5DګoQ=NH Ց5RĽe::KQ~=ZW3j+@?Qħ|JH1p17_oȃnJ4*Z?.Y{M> vZDI̽f*;bH&*y1KLk8~5O'y- :X) JMn ρNc4Y^.jWS.Uxg5,(,rt\($HB uWf8SNXu2i'Jp ͺdC>hp'RCR3tp#5,(@vIRG9yauj)K}X-GnNXULjL:pl2c ^^/İ')7yfsXe\HUf9Ksb}dž/Ĕl/'EuVZNfqD 3:TCJF|RzY-._ (f?!`7R:rCCbƐH^~bʝ%tI/O8QpғꠤՒ{Er-M*W&=W6[Abܦҥ|B-8I]TGQ):QKiSL:ruװ +'(,W@1DpI6;,OD2q;M:7! a.l 6݇rzBQ}<)-8yvp<'+#aysPtePRr/B+*L + <%িBVL^m. cx [oP +-Q|Vo8/'_?_o~}~7ٿ{g_Ԝ?|???ׯ,qY~?vo~oK?9~zw~?_ww? N_O?o~_o/w{7߸/=G9ϟݯ7o*믤//u}ko_7ꛖ`b~Ѽ#Kl$|O5b:Ɂ.]a$ kX+~\$6fJD,1%h0^F :y ]A}=L-QUcbFn̔> sscWF}{cu>f +onD(~ɍXzcŋ)D#;q3D+ԓ @ +tnIOv49ѻaϬps~&R/ן/KASֺqإ/wy֫1h$|N0=ωxW\~}i>HDѸ?hL~XJϟqō;|ѷ!YBujۈb4Kxoh"|rLȇ(;;hli~ңgk(ʰw+[suu>w_:gj!q4q ĝ-v .Y4Q.q{=_c)6ĺ1+\沞@'!s:C,[4$cF$(hm蛰qc#|FDP#u|㫷=F$VFu/vZ<}y0٫zvdU<_kjɔ`p$zRڝәۡ9z`__if9|>9a7?L`s"C@W(?f +_~oŘGLgW7%~-~siVƙJvF9Npr> ޾zA _#0- +Nn|_n{ssy۷yts918o + kWo49&Y"yti? I2NrCNb@j4b +dXEќS͆h5>艧W4̾łi^83hxh+} SE4׳ɤ@wF \KqK+`bb{>络wqZ[65>*DyrDcI +VڈqP_|-gs,ѳ~qN̖r3oAr;>l7'D5"~(6?^ 8Fnk'#.{ڳXG;UF9cars3xs7cjkQLj;?Qʯ%JR='5) u|OǙ^u :OK, eƞJi~ >}DB!oaB>eEh^ RggJmlŜ 5#L΀yy%Ѽ?a](4힠d?Ddoy7Q . 9kp8G39Aa\ٞHplMFikJN1vЈ[rOIӽ9FȝRugC^%|V%Xb6k>=!s^s| kqgܰ$K@9EUd:TLgثc@N\ >.N =sظ| {g(4Swcj|M b +r"əjw E +qVN ΐ[i,YG9>2ϋ(:uhLgmH3tE\2ҒFk=nbr)·/bO Z`9~+Rgx3*yL:~~M .ii"n8Xaj:w?x$BȈ6kIg4\n)ظv"9Y2:'sfm ipϢՓ8OQZOuB#\Gs |05ZL@Fs,4/;hDI$y)XJŧqҝ˙AЖn'[߀b%dŋsCgx7NXOs\O'Os3D6ZΚ '|'AT³>N+%Thb9Xw\LynyxDcgz:'Ḫ8lqD6CW\Nq>^r}Wxz~+EƻzY8k w%&79 /w1 ۂwjMk]K}$w9}_HkIjfogQws_ǍDl,#؉~7*mIsyJ8H +s9'`9iG&Y@h#"9Q)rR9}tU~"V7b\?kjjs>O u:H|P<ZڻY3QC"BgC }ʟ-OI+7oyZ)g:kW[Mɕ7(<^.ٹ1u/6$^Ub.nj9oOyhq7kt^|.#Tӏ +xmQMʷIX Xh |W94hvY`G9ZMpNp*bw~x0o ҹrQ~?N4^-DjV2^X́{vsLh1./n9q+M+AgS ۷ +yhu__}Iϕd&zp:1vBNuR>}Gzyoظ'}O$:FbjG7YwXNKHrc2zEAe2vxn7gpnS)]j_)$fd8o!gyrWڠOE6pw;'E?} }vƏ( ۭdFu$f׺9A=t8#Q+jЈ[3s= F \FM_2vsc+E9bFEۈ*)NO=N9~39߱F3Xn*i3z! nlw,Po*EQn +ӟֻaϸZQ'hx;=oY"CzS8\l꼘L]<itp`sʲM5 ^s=/.7'hwc[jC1>'@Wݪ}fw{9'<,ZYTn0PY$@b3@[apR/nL +d@0@j Hr1LX><[|SOYZ;8yDžx#zB}W ϽgZ<ϳN-h43g;(5!jQEs_1\Z^LRD-wŕhЙeʜ,O cĮ3(sFwg;S߿PԢq;)QQ+QNpp5m^W~v'/F=/MOw&2͊Ef\qLUJ YAufqah]:gkK~`/LEahF,VMTUhrZgN/q#/9g:P欷%"IRC>s+sn\Rr2 +ߤO3hZjWann j5O6gA Γ9S!ELyf~GD`ou".da +aw2-3泷J!^oGocu{*hg[ʡtR㥃FwC{MkϿN/E.yc/vpNώ~#W4>ܳh̗֞y(,zwwXNL.Yi( D&-پ;7}n~RNqݳu_+:ϋJ4aKR7#Vzh."= bK:|΄bLy>rK=CrXH?w1=;Sn0oCoIy䞕Z8D7`P/;"B8ٻuOo=E$kX|S=2wj;^| zdiI?;rWO}Y=S5H 郄,mQkGd_3Q\"7CWU+*Ezl KRmWZ_\FLܦV@&\  ?\TQ;\ +_kPl!cV:}-I 츁eϱ^\k U4Z;% @G8kL%@Q#A*;»H$䠕.5DJ۷W +34 dِ-N[uz9Ů^ŋt`l$NIJXNQ.ޚEIf B;%^ISVt6HNŐWoS._+S %M?/~تNH'FӉaD?GN X' ث 9X|xe#5߷V{('*ˮ\Vɣ hrbFٕp9΢m,Vz2VjyV*u`IQ*pF+JNi%+`'5&2S|C4>Ir ّ|/R|F+qT^WC|[*7 S!9s2~#RLVYlz$6J;HZ;ei6:#' e^zl26A$RddlF lWffc^)9 +mF1J +-151Qޠ 8\z5Tccwi$KH?n4(=P#wU֣@,-er ~[M d5m \@:%_Q&8MJ%~H55& ız6˥zpq b,.5|3^'X6vI$rNqNj$kjōh'')]QNg Z)C4\ZiԨ6XiQIZz{5ɣkPu;[{|JԤ~!TG^Xp GȍvjŐJipRR +bLH2MJrR".&;Yw)>sq_+N8qXUH0,ɕ.7jk-G/5@˾^1dZ+ؓF6x;3<{ecʔ#}8dwN*#5Z(b6G޳CJQ-VxH=hyA)et fPZP[RO%w*;a.mH9-j}I"od + + IR# d,-}Jy6Kf#B$ !|:ׅ(Y˴H7SdH-!!PO,}%m6nВkm ױkb^ +3މ@^^KʍĬ!) N! \q6`p↲R&.)XR|B:PFЬ%ӑg%!FQCz%;#oؐx!DM;Xp%Ѣ%rhe e8UT[%:&s_[%Fkbl+UrnU^-vQK8KHpV/RVqJ*t`Y8b.ZJrUvnTkDtdƠY'/p2U+m}MZI[, /"5v81Qւ-[uvxS]YyZiIX +j|bQÇeIQ̥=ageAj핝ZR\Rj$ 2sl%"~TkLQ +NR ,h- +S.ͥT~Ѓ$$XBh-PNQH͊ؒ"Pk¢!}̭рSŠYzJN UV\jYXio q]Y*e)$+]Ƶj˔I7IH%P4I +hF.Y@kt*ڑ;ljWp\CRNyvJZ^HF"Kf+`/פFoTmQʷh% Ujd' !uB%eAm*Q|#u"*RW., 6JMvj̷pP|G8vHƒ#oW3*?6JTCj##ϲ M'"HFs+*FEkXFVk([5j=hm;gf͊^fQZ~9Y d(HبKjRSc X0f:W;/N_Rij&|L姵W̲*8*@F)gV6jrF%ȓjB#ШhIxF;^:5vɵDNb|L#YsjnNnH|JeY81hVI$eZ4Ky h+r/[š%DN j(h(9-5eтA?sJP;=HDk՝;Uw²u'WH.<+$iSHI;[-Ze"}Cd/#V8fK2)ݔ[Kq72.:R!I'!҂_JIhQJc@;eZcKW͈'-9Juo$k"nJYµu,TtZB2 izvQj'!e$^qԁvד5|_o)D/!1RVh 8eRM8Ubv*Ét`iP+)5g2*Gn?\AjTJC +,: s:Nlp[Z[RO*:!U)UR2(<9߳\Z,[VԹѠ~KXmċ?UŧMK@ (ZN0ÛfiY#*y9zR# ZpiWVZREUzYض.EJ~,eFO:+wy̛=P4* WV/6p:eo[IY<Ш!ԙxq#A:ڮs櫵Ux_g,B9Ik nTr4j06q)ߌdO +F#!Lz*WxajYVnP&Jɩpٗ#!x;vJS㭛2usZUFR-G_  @րG + \DdsC?Ad?W iռ9KU Ҫ.+8^VY-r0wY洢R._-T:-UF.. =(FϸF+ú; +AVf9f~j|VZe9jqEj,'WU Xm챦{`Wroz]UKx_+!݌="-vr^$>\Tf.D?UN(dƉByFV'򇛣 Fe*G3>=_R_aM@auB?aM`!zTW9ZL/ĔQ˃Z.f4Ӈ%$ +؈IMBP?~Q|lH1y[6# 85=̫CAt`\_.(cÅZHVUxОʠWP''d^ilbU&wlp`nM 'ܝ NeW]=\n]\]a=U#-Sĵ^NOzEhw?~̍Q7=,7S6׽Cf `B +Q{P6dI\=+ЏU*"sėaBr1+C{A~0o몮f{Z9^VEAٽbGAE ky7~V&$KxEjWF#mw5V1E_Ȫ]rtY؋Icc\ݙr0zvqppW;]ͫ-sQV̚N+.Zʩf/pP-uFك[]0 )32VN9Bt9*GØ&5-v=#z}E~|h |Lvur?#z_ V|D0!ab-W!y!֌#s~)Bt;h|{c|a_0a찫#z~ái A]JGb}ňabL&yiE@7}Mw&wWէ+buw>Lp<渪blh.$eA!rQ0C{FBS^1Aŀ|bTH1gG|bx?/\HnxWHl|j(dl$Dd Rl +-ﳕ? 1y>d+FC蠔~." $wz$I&5㸰A>do>*m8 H~ah7n_w6y ב"#竜iİn\`W# +eH78sVKqeѽѼ+ݛGk~EGYw}˃1+{VDv3ѫ@?]h.NGx77V6J"w{ gt@~UR_3&1+ȾqyЕYًMkHt} +!l_aUdo1`9`"2ۇ-l0Ɍ O! />P& a|BzҾa=xb+Fq_ +ۊ)5yH4QA +ЖuXtP-fo" 3Z'%@7`'\ߠ3~ W\PJ+fUT/K1<R(!me:At3Xސ^ +!/!`( s\N6O&gMmSއvP@XsVGqucTҫ|ƺ |\tp60?ڏyH'ՏcJGrq%#䁰Y4W!%#z_ WXO˿;Wj|բ%*=AZĬ2rH'Q+EO+?hmwc"zn6v<.v0VGt'73m4#[drŅ#Gp)2~ioR#=)`T .P?+> s$ ={X; t*ԁ9ߘތolo>"s +-nO4ތjI5㐮zb}#z 1􍓄m`ބ.h/dqBBA7 Y&.ó ]؇ :` gMO68;_;,.D ZI|b +wB~,Px\Xx'XKB |ޞ]Sٲvt6|ZG(30f +L1AI@$wm`Yj-:4C4QmgN^HXKWx.0}Q8CvM@vMl#+FZW:Z60=͟wW?ua>w8О0wdOřv ߇B2JtcGՋE!h| ˢ`=xdV:f$x׸QLx`kBXѝ^ُOZ?!g2^6^ҝE IWuhV|8 o +#I-;%ztvYZ7qW*wAGF [0abX,H&0# IG  P)%!Y2B* r o0˰5W9l)9DLi~OHi %;D@ +FHC*}{Br0|t(C1i.s$>f,<##ٜټSg0{&u*kOЙpy"v&0B5!ed*Hǁl"-Dd36| +8Gv d.Fk_r_<&h}|V'C +cɃC~uF6p?3,3qH"9= C,4/lG .;4.1݆ti5ȨYu% ac1e#/dsw}d$7e + 1Ldߑ>z#z<0SƳ>2h{؀LLp!ml`Щ/ \"mH& ,'[@WgxwЕ`+8|f߉l~";VΈqEsypwlO~dʔ>vOfd Cac>ƿ 2Md +}ĦnzUdK3eØwC5rWwwd|%C&+C!NfF3'`aM>x(d+> +o`}>_З.fj 1 o&55\)U|c>i'i-֠CW +qwA 5p"A+yc $; a9,s0q#r`;0U}0AFAE~A&A9w`̥ǧ"Eϖ:TtS``>va\چ$kιtWvu\!8#F_ҡu˚\0׃ƏE6A$zZ=(d|kсh>8CPn]vgz!l:bA'|td{9{F 9 Est?C}U7g`7ʠnha(x ih7MЫSRn:+q3veD<#{ẁ|⸩helH7x3@25_i{ȸ\3mw F7zwsb. z{ [|B͆ 1 >. /.(ṀKt5"R2 }`Ma6H=hM~b8–QÐ^DxOTeñE6 ٷa#l0>`5g}Tz\ô>rωpwk +c150䚔LxGkd3Cۚnx! ~KНuBHFށlѰJiz-?eˏicΈ8.]RfKӎ-.jQ9/ˊMkj]tc&$s "j%7O<&XA|OEAޘX6~$Scl,2!Bbû|Ύ)|ɘ&ԏR]8BB !d4Yާ.}N՝5ṃ ,fԾl8ߛC>mxU->F:s*Z'''U5*]-A֌|HS6X5;_׽7a%}p*Sum%t}pi{ lW/e*!l5ۥw#tn2 +| K% +r +~;o9Dr~'Y8[hQ#"p:.alh\` ˀw'l\ dM B룫 ŠgW٤\פc_[v3ts*}<aA1|H@!0޴"jOˌ_|Iǖ sVY_ 8 +s'0>[1u +'aO;bH 0>!=8/ ׹57." +1 +dt+ғC!e@qS0_H#(nx-7ޓX;CSM?cvNfg*> Fcg +2']t&͚ny  6Gt/+&]\LhLc=&pl^(9aug ?VN'JvMgJL +v%}=saU5ƖOW_gD |`]c,Y:47@,k%3{U  M5q-q[Nc.l.BlAȦuGtPwe6xsw +` #F5kL]5:{a|];挪:5{0Ӹlnj:UhG!}˕S%W ʮ5m혂?˾W3>¼ q%6iûl7ƛ_ eb>uxt>oGk0a$ 6<& $V|ud߁#csF/C[H.wd.s 4\yvBci{:o$J=RBpW#kAH|0G |x>؟+846EHc^:y<#C><t(Ltq ]|x:O¥'Ԍ\7ہu!xvms16{'l|;MdMs +l5h^_r_{Tw-yCp8]?ǖ~!G٢k;Oج&k>]>-HbKL=\H0qQNASX45' +8p{h=v,6oTIqĘ1`6C#nYKAwxa߀q,~SqX~;#;)e 25ེ;mCq̦[KhIT9: +*,SAE;לyM03Xo4bڶy]("N>Զ Lk2fB¡jꩺKtq1C t7ҙ QHsRkb xH)wȕ?p~& ??=";xvY4ޟ,<vi)d9 )fdGdcDwx:hZ;f/ڻkp.^`qʈ օ]]Lmei % ~I0웁9&Ձiﰞ#}~.|7nPHC bKl$fX!x1! =KH~\ lkޏcZr+XS[&3f:"ie`7  qU>'3-cjF/eqe9+C |/& 9KǸ%׿W8tߏA6r[ 8Wt/#/$5]XG7mXr኏ؚZ|Ina]4 p!Al +.s >|7cZ5ŪٟZQ񰨚L.ҷC!LpV߰/x9|bXnG”1ޝcb!ZSZJgsT T4>.4VqFGbKѪ%)Q:5OzGq㟞ax?dbR^aXalQ3sad숚:Dvk5qzkfزo-2! zb(H˳Z>]JxEn}4T@uld;߷=S ϐoxj`$c~(1{d1='2'W!>?p9`4Cԁ OWxbӵ>eسwbAɠG0献)iy0t,K)[mSko9o ? } n U:x9eKK B8?> sZ6~XF_:tR<YZ0A5kN*CwfRFT  lWP' +! d". .\Xmþa8cW~ήn{)1Ȍ[nŭ .G{!ĸqB\j!$k0\z aM1fP"z$~݄K@EZ@^B놯>fϕЛZa>C)BFCk0: a~wnX])n5_VӁn`6\m|8$` 1;&m5[5t "ӆ;_m@iaMMgdj]32SbډBbJXlߑ-㊷̕;?88{+g\9l˅9t/a~L 4O1pS ]xcNaJerNL9!#\glÕ/U#7@x^!oWobq5wq{GjI 1 ˊnN['$AzzC|Q/rXD: Ŝ}&b<&w0k Ȗ7^ Cz1,0?L׶B֎BT5Ari5&g@Nia;²c{\;DZ#4g0Zq'2k"]ל\~GC~ǮbbJq!`2[0[/徽|*6gߔ e[{~z}"S fc⌎KnŠ{lhX4SqSÅm)ӆ-?Mf֍QkØor_OEk}(Q'KH6c +V1U??O E| T-m2]{}'- f”|cdDnƷm>a=y?˜iJ)Ϡq<y pK_k,KN8/K4#;S ]],X tѱLdHfMjpxM ǙNw瀼/Bxp%*r}Gv^X vtfUhObp>+SƂ±#-d}>Z߃_4(!r@>0G :{Go/>lOC>p-er_&[_1h>1I>#݂ +1y#썓] skjkk>xSQ̞FS-]dTm| |;i3{"NoG?Ym|{&[=Oo{1G`MjO;3)_q\(3O֔j_f_$#c]=aSW~|Z`' x4[-l1}D~Ŀ9mILùB|ӕ8~С_r[ڝ  ki9y5qY֦3-p@kQ  S=>8H?q c 1?+}c/mo 1Z>THZ 춺+$gW/+/Im\Y .nXlRx1}dA_Iߋ|Y;>|`GtĦq%d@>|i0X=1!~ B? /1S{q,|X=3؈XFX3hAd?tsE2^5t-8ɟX7Zw}6"ӺlI\X& /<31swr`JwAd )OM-Wf_S"z"$?ejpǨm +p6ѭw_(a<cjh~i6 _6ƹ'C|SG{ ۰EPsYq, > ǡ+OjMOs!>8W|e6CWD+Fp?bc 9`ۏGXU}Yt9>I} hFW_)~E@7-tiu|WT$cZ1%'tE=kh7\\ ;p,h_;RcTrL+.驺, +r yc^ +?>ALQl8^b. [r̎=eHѸN~n1j<)]~Xc(0'b Ą >?!{F\VVȒSz̎Q=kN6:C60 mS0E6r>]S+c띙LZ:>]|=2zӯ۟a/:8>/}l0Q?րϛO9Bޏ҃3t9ێTåO 1!M{tåϰ[1n}4ϸ Sf`K+m7 9;b_*=d3MK̠LgSgۿ7;po/v657즆+\Sk| #gܾe/>1mc>s+#h@t+jG߻gqc=fTɏ6M̤[hl7 =e0m滳m掙{t}̓nm>]|ʆO?f:mLc [zF6㐪>41ȯ{|PLI?)ǛLpi<㿋SN,wf}X,gA~0vKRo{҇_ї-?{0^wn~ŴESWLӽ/ NnnR||ޑR&qEd qM8+1-`3$o_@#>˱G,>W[[n{0hM{^9vډʉzokM@67_/sL/Akj 1 Ӻ3Mv\z'KM^-v^Jz|}S~̛?x9wY8ر=xW[{{f!aѭ"+ko^IG(;W8{+|v0huEOD:$f6:xnc&=g̵]y5+ۯocAZ-wunnwcЯFK3w~w/s>y/sgK/ @/>xPj<+Gٝ$P![|p.r1;BSM?υ}Dvwvmtoi9\=^ #Wq2'NGK]iaw}wjoL_/ew7Q=c/<a= `.? a< +}%00`oއFӡFnoGоu7{ܞ\BcǛ@o<ۿ1E3?.E64z2ib]p)W9^pK_ og}/61~El,csK?-45k>u&™N8#|{O8ai4s & h: +/ +p??e$v.ۋ,Ջ4Յ"{*:Ue\*+YhG꿒E^պ==W!<[ >hϣo< +G|'{'cM^})vb뻾wϼ}?Q̑'pNݳ…X5+QnWuoo +'y?^. \Z|Ⓑosu|uVb;܋l|rLiu,%O?җǟmLmfP7t׋涧Kac/{o]];s~h6}²z?\-`iKM_93y +/7%ۯd?9Spwޏy8^ÿ#ܽ_I=w/tǪWر.Vc]؍;͵mr}uYc)5%Cč㩖3ͯ^.˘xǖ:OnNc<}of3yeL\U4i'lOsŊGUzgz]owh?vDkحλ<j4K=W 2tOO??*^`E +,'U9X\jU`GKJ;jėW+bnr>f '2i'~#k*:7ݹt73{Ws=}Spe)[˟X)>Ϝ}o=XNK-U/.sOo]lAW g2.6w]ۆֻ&׍7bEl/u ]/_H/\N?s7} Sѩifdo\H~x7G +3\Pv1FASڍɵ7 +֊wf7"vIK֭)&Vl_rB9zʬKUr+/gWEܪ^`9Y}e+wm?@ԵpmvOnp_uM,-;67wh]˥1]__o{3aן? [lʧǪbW3!#;2[.]7s?^ +v}]u+1};*n^(x)b׍7"K. /:s5#\,JTe.ėo\Yx!6חxrt\q ws?h9#o/`?L_(~TBz |+q.Cu?s,b+R5^Ѷaogr<~SdwדQwkUWqFTۑ%݉,9~UrFTѫѺ[{%jK)UWk?Pp Xz~7x'+SnϦ>Sl9Nqӫ9sMF}ԝ0$]!^9omⵊTp'2mE.Ϳg?;)w[hr{~n/Ζ *^tUt{UcÍښwۚŗG7}Om/hHW[w#bո2W5c+M=z6j iTs3׮fr?߈ݎ.]Qq6u^UK%IWKjΦ_k?Kr7H?^̩=QLZUJ$_MM%|ѳQ~J\zR,5v}ٵjk[h|})t1$FF'SZ|KI{ǖYv|5ߞ&;>{xnD⯖_ɮ?ZLZe[͕Z};6U*ZhNNq/;]}7*tljzfo+W>;Zͽ~mz(^vVxqUN?yx=[||߽YwE5 qo?xU7זIRdG߄,}uɳ7o/p^afoo&j:tӯ&,FXR7 \)vv5k-7^LSV|z%u' y%Y|~(vkS+ OV:Xyoj//xzy7s&]/kVדLѣx;/y>=PS]XGmmͭڌy ԓ_bG8xbٙ7~IIE[.kmjjjjFOj;UgBsJO>UUQFWV:B5ըn֪&NWMQM2Su Tξ_Å#?Ɨ7]JQu%1JqC{E{ETQ(n{&"QD"AQ`cu9c'g>멻gNxϳu=7W UUwU׼iA}Bߞ^ʼ{ޓMls]#A >[4ji9*84?$Bg#m܆!}tc~fL4t@Kk4RO;}x"xJ> q_6)޾.,T)MOr^ %A+-܆R'8S5?5p 5#ig#HhƼpVrLBQwO+jy v^-h6욢oW +cK9uַ\+n~Yrolrڧu +nF]⇬G6 %篍~6m2#?CV_wF8mi r|a胰{mI׷žzטz%~cٳ8cҺFg\%؅Gr^̪S~w^+bd? GQ$2=6~E_ِ߯hxᑊZ𢿿Fg64?WtB^ǯtB~ӥ3Mg7lZV?Pݼֺ8ﺕ]?Q0߽dsZ3棑!gǜ:d܆?̽yF~׆/=lU Hd5Y!Eh~HC7_V]ɯ1ȇu5B\y%^}nὴX7~~Kػ8P:Vy5m5hl62 +adZA{[u3>M]W#iϾNTy=/|b^܇m~r`˓빛n:{9 7_)i(f/S&dnwv{6ާk(i0}=7Y8v%+ȈG{u*kw7߼P-#:/gߪkG@UM _/N<ݎAkAYO}toH4B + S3dm%cD4Ls2԰AF:H3/4uYr\qN0{{!-OhȻUݤ"骘'[뱍i8me'v#`k &߆mkYO9gӺFH Kߠb+J&Hùh#0YG8 3y`22@ldMvj WBT}wUClvTqf_*yzxW^-ovvȻ\n iAh)_ZH?{ܕ7r? d5~V9!&UP _0 =zy0gk̴-Dd?y +23o!0^M#Smmh%?3M)C5n|mtXu&}',_ bГZ^o~nVË6s_~q'-sp.QVz_X2qzlfn5p sckc!aa2П6YI5'YO@\DQ9µ)tvB}񦿌X/f^KMeSѥ *n9ǰ뿖?Y-/6%ms,,6_?{T\{n(<McN}42ױLl7푥R4vuzK ] N8U}}8n곕 No|v|nYu/W?ӌ-7fw( M"g1?Ö :\3}hAc̭\E83GbM! >|32gxT94mzd+X,8|ܻJymۅFl;XѦw7s/탬-?^uJsIKv c}%B<0y[8ֿ5Y¼ S ]ᖑa}9{!QRˍ!bc^k=rͽn626u~0>!26bF@";UȖNG#k#vel3Й5gf֚WrSw^Syee_:?Ǣc}a=SS3>a} {!(죐rbhN;ޮi3@OC O$OQ0H'd6JdUhUSh͍ޥPupq`4U ؐktcV>WKe?& g/}[$#B>sgq/懿)Fw_W0?I *_WrG, &810[4a:W0/X/B{!JtS B#)pS耕덽lo̻od iB_o%eϣ{bɚo̦OMOg PTݼB^y†<9SzsR/mt]1 j E2E!ׇB>{gEw)"UW>)?.T?|PRk;|}BXߥm)i:SP;{0wsZGr[(7tOZx^88J﹔rc|xߤ}fi@|@_ LuE}ℽCܾy+08\kt>K \e(@8*X=4:C?,stc WqN'EF! h1 m4?:bl80]wpO؎;*ߑ8j0W.L۽t߹fޭ|r<`?ԉlГke.s?? UHEH,@yx w"O +5Go7_0IMFn˼DHFWTq[ +-8 -:\Q2L#<982)$tUtǥEϗ?0:SRyiUg}%}?yH_̕~@i`6Üa2FȺ-bv>xH;IkMw/9"xH +n_|] EPz~} +~~W_7O ~OXj4B5|=©c&ꃆ&pD/" M{fuYRe[=Irs6@Mk!_l S͚m`-Nߊ q>R^,c1]|hp[2 f{BdxfM⤭ >~ʆ#븑{N]ϔVlyJTHJՐ&7 wU%KftّIԚrCTPW*[Va>b+R4tCGf:~]L"jcgjSWMa:FL*#zmdwz$?^B}Ȝ|ϼ :^&}B/.Tl?& ^[U' u9?z6sJryHV[rv@*M*"U[F-s|Gc \=iH: +>>EW\jLQQ:\X&Z |#r#%su4Vi,yl{ Ljɜy:~52ʉ;_Ob4`xSyh +[eMלTퟂ)ONk32GI*NȒZ\q`-4\ ,1%:쐍)``⫠-΄Y,;e'{u@žo@֏Ku?.ӊt;>8S>n&UUDyY7?/{Bɳx0a&Z4krssC~"}}8#byH$,^CVk ڃ`_FA돥))=T:5u=q:f7ǔz"RPevp-@}_8@~d~+v|N 5at݅p j |lU{fċp޿zJ++K:ts+ Ғ}jTM*atehIh<MF$h+Uu\P4\ +5СB<DxP/1Lv9Sn%xї΃ʎ]jų)Ƥ&/eo.&凧P fѵ'f0%}}d^-|+bP[?Rڀ^40QC̬PkRezm}N(M=Yp#"(Œ-;lK5ݟ 4q\1IF*3csu̡o~ Wi'rc!Vb:r;?Hxz ?`}y,_ND_c}&Ya.K./-񓓬 ;xlv~r-0D-X+ՉNKK\i}:{T@pb_xB K)h$S#pnO'dJ'jhhiu\)fiC(pu4lk"zm :ٜ.9~|u\.[;+vߓ1He;:KB{(.>SzZ,ȉ]ÆͭIU*ћ.{ Rj:cRyϻetU{v Yfggra oFO'7C, 6D7d$c¯NXk@SJ_xr~=0%AG3hQAL +W2y[,gq~b[d֛qM3*GM̚j#>@^Ul@c \\2NM1V3 t<-c +9-W/|< 4aڏ?X

    (hhPq:" +l:hWhˣs}cv,!/GTX_y 舃 ,'dJ dZg!tC5AK%m +|_;/WFR6L5M"[_y*wߧ¾yTR\#oG;Q^|zqc]ȋP+Z%}wYr7_wuD^qrtePWg Z92l@Þ1eWjezlWB4A۟Z45Ueq9f豱֥l0Ao2e|y?rN2a+X{@KAihp)e&*hqe'^a΃YƃpfTr)ևR ,T̅;/Ҡc}|6TU`md"!C :l$(0e:, x:(1H#:tpbX 9pXLX'8FPgh3k*Cd\4)@+?֜+6@7zߋM46~aN`)wݓ<&WiA{6dٹ0G-'WC`[RIqh&rUf#Ԝ eH%S%hxKciC*["QMnПRÒdru:tVeʔ 6tkT{]ODm,/y}.`A;4eV$iIPW 8 mOo)H8e8`3O6' WhBe;f :ul|io87W&nkۮf(f6Yb#E;+t0M@k TLekM=y-`epɵ c 楄 UViPQ5Pl@)&,!–}"LWh?[@+X]2#Ŭ^?I5! +e^['uGf$-w=s`\3[n8C>\Du?^eTk +Ly<@sBt!wf b=jeN"NLӦbZhy9"IBt9C$!1tJ1~&tAKpSʌY3X@DlO+GB\Wb&)1K_qӑz^ApPn熺/νhcy*;3줧yyHTwpzPu&\BFhc{ȵ]\j?or&k&2I ئ+ َk@ˮ2#VtaPX*t:[/.T+w|ɬ.5hy񊍽Ӏ;x%3b*5*est)qsIEdp3 1Do;1s--+4Ŋط r5A']w`2`'.=0:0:0 +r0:x?sj~@UZDr]DEӹE\˵eQ€Wre6)k?;R'A;0Z0mp`=}]udzqK؍GɅ&9zW4S7]=JV{g ]>[gBHGjqw{ +PlOu]YD!| s@s jPZ,0Aλjh~4]3NѹRg j؝|a}KvV g28]p xaF;Ίe}`A$%gDe.ve" Ō T[*BܯB=2Oχc8lyjl<F=:}B6?u?tw=W.;x ^Y"*TMLɁVˆ\>s?`keLT@xhaŞRlmRT`ί?8~\"X_29ʑag8';kO]K:'UDP UT"b>2}(h`q>uN(e^O6>]=]k5qѧ_V%?ظNQw*ae7V +Z\r1?f\gIa Pу}#U=[7ۊY~IXNg;kX3Qa +2`g/rgg q %0j s4+!*hCxfk-6Y`8|>R6Ao<^Yew{b`RJy?;+5(:\ T34KuOPk#|5Cl.e^ʷ<^C*x/r5'ĮJiy+9yDBPu~m)# >0;M'ɂb**!Gr6qrN[`m:lsq.çU췢>q=#,HIӑ;;kN ag홡>aL*.o2jG*vM*T@$hI[8^C!Z+ lM8~m2δ_]J xsH.~5aߣt*_ J)6ab4Wf|m4|m1`e,-巾U> =ȐFB>=D(+T\894Pa +qjq{`A@(5a a|A0z,B +かL26-I|$OܯSv q.]e,tӇ>atS{r6|m>T}Nb75\\NhвfȚ)X*㳴 Y,yl˹#z++kb|5nwi8ka;>k:pmKRQ`Wku;%fYU8{Rn8:ClDjU{r]"ĉj0pEr W!NKCɅjÚrU!pPi ܖA]$% bCfTFn <X 1fꪲ[F r>> +|PcB֙ +zmX~˯Շ80`XRT3=.߀ O%>`٦&(o,q +(MYM\j.# +@U f75o }±ӚמFMwtXPxTdnpAqr)a֎"/A[ObN%y[~hlwB.LזMm5Vw'<*l#T)XWnܮ10H.ꊝvl<ruIB֬*zg6\ X6N9V\2;4/{ o2-w,蕕G'} !g8gEv+ܗ گ{ݸ9C%{'匣"LR15aXXwƸR˃pl(C2i b"Ӈ@| b.̓u OQ*5b] `aUA7^`ʑ:Z*C MRԌ}="վ +Ŷbe`aNŶ__µ]_\s2a|$f7 P5Ym81ĕj<fRSG|R`!R8%aݚn93j86p!)bՁ_A*دW{X&nǏGyVeq|OH9lp, {OHú[sa.b7ذ[^O垇 [sΞMf^ kW_qJMDh@ >>ׂ="6xL4Dh Lhc"WjxVx\=ԍ&(J,=8K{"l]Ep,j~R,,=XkOk pM#!&q xy !j`o9 +ss~EA-@;,7Y6OQc *xzyGWOX_ed 5=\ ko >wyt9N*0vZ{3,c1jLb't*,MKZp & zsǟ<*9Q_oIv\[՟uLX[Fh5z>ܯ!WcMocKu\uZ.ΧC-*|L66MGnD‡=$;+S5P,mr[ ; $ιM)ե +ۨdL$k|i(q4&u8 rxrq:dlc_3EAe* + =[ػ ++R w q$᦯`L >u)c. ΄' [ [ pnavm a5ly56G>6p x)R+ '9\lG ֓*'P:{8&>bcRq {iKu[7 XtW26B::}xha +D`~A_$F*} K[e<emǧGuϑ0ckyp¥_/Rv{0Ԑ7Gf +||>>||>>||>>||>>||>>?'Dž$^ҐI"A3ܢ’BӬ%ߏvv IH d4zYA S?5cLiDHZ_[Gea!1? (8p +.kV$ ^Bb#­ɫeyS fY;?Df["_l~X_J=Ze/5sXh?aֱd֬ >y???'=jzDD8HZuχ4Z"~?Âsg98Xg@V߿-g0{R &N$c~7]?ejf:ߘ<=&2ˍ^a/3w +[B +Wҡ4Po *15Kj6΂:OIctXH͓sЧ"Z'PӴ"u(Z;0P5AI#Z 2Q(E:VJ jHm)!*$FKh9tmzy"ѤM/.:S/AU&Vj,Gǧ*3̕e}ST]c9@ƄUPԙL\oD4ۭq٭5%lR~ڄK6e Pi,O48,ȾrSlD "6(؏Oh VEj:r8 RM" Q(h8ɠց!~ +|/9zT"VCCkzUЉeuR]yhhAU+5@KG$CPͮ2 +[#O1zِ4m>rш-җ|L +Zj}GdMFDj+WbskJeWØȨ6r^|Mʬ͖NkFPT#J+3ŤQ)ʵTEvheJ ..UjIA;8h c>("pU*1UO4|CР`BVk!AQLXљe>30q4 I,9` 5\JS>&KYZtHm8M6bhH(RH.1|Uٞiʃ3T) f|l AjKH_Z)ԇKt.,[C]$==*Зp_@jxz@pqv%X>[S:[2Ԧ@-7Renb $|HJ֔ r>e&R~G"_vA4h"RSP[@ hHpfemh.ք[#S%j:PӬ ?+oV+F U,ғ+4dJlG5+Fˍz4m L4 v"]f̍ 48.am~ z?ʤ2ce$|u#H?e֏+̈́IVEim/ԟJv٪6ZkhClʄ\}b6LqE\q_Cƌ*jaI=3ԪlBuMo.MIF\sYDg <Ԣ,e^9G0s9 +HN+uQDTTr3Mb3A$$H2>笿f>{߹ tתYc9j |nRե0ׄ>fywkh=: 6Y8Of,A8g=uAxC79B^`17WR ̀ (8;:WP<a<H3x"scpf YH8K#i3huz1(8; s \sR={B(8<@44BN!5/<)#s8mFUEJ ,Zڏ)]JpgR9h-'O|5n\XGv!d-gѸ syAoF/s0&E ~A[6ρy܂8;κ +g Nc"f5mȇN8Ƕ BA-߳>qN\N{a<Øt &hca:a<~!-  '\ƃ^-etn$s~44p/g!Agt@ůD+,M_g ^E4;wW`9s)F@6V}Tk mF:Z /ùpp"B+ )(9#/\8[gКA߽ .%c3(1Ě,ΈEa'[3 (Ϡs0c3ݠgewi3u3Esh¼J8\X"xXwQ~> =Blk Vt Z"pf3p=}>[1Qh˰Frt/P|MY${u1hJ{$8c ӱ#6JD5-hwSn (J,8>}3# P.V+T>"Xcs~V/>/wg >}c} tȣՠM;0fҮIsA:o%ICTh6& pR QM&Fm08h΅qrG!70^&) CL Ҫo q8''m~2Ѝ[@|O(gz0B4I,/,/ØsXƞ'Αrl8-8!5Oa<"(w2?:-/$>s +I[k^^NZ4`߁CXylG< o? F'efQ#c M,zL;pv~ӱʱ9PN,<8j7D| >S3Z4$(#O0PrB7 8#̂8AU0 7,s&p +;E273ـ)| Ѡ .  vS cPO}Y˂&$֠Eu:c44ʸ 4ܥOnڃKl~j:_arNѳxGόg#„oblCΌ\`m\&nz%z(U]B & +O_S7`tSV@6HAtEm!p9Хy1jZs{~KY=k EB_>Wڰ(֊Ҟޣ؃ .NdCFN cjq@{c4]LN1!uUMƝgl7 +g?GhTsm<60!9#t!@N*;壺Z4zF>k:T(v:-JA;/8# Z Hۏy3>;1зDHp| uտGXѯb$ ո@]kצooEFUlP/*h }E۠=M(BI언(7hz}o!c tоV5q3iX +BD:s0_XLT^JA?I/d-$o`w;W@#ԁVÝ +\ku'o_Ae+QN 2Зoqp&t:y<[s|2a=dJ^FR뷜$p F^S@ t y7OZֲkY: :Iě^>Rv<@c\ 080pa&p!~^?0BmjTul@*T endstream endobj 81 0 obj <>stream +68^>轉5yѽm\9% zC,[P Epa 2N_{ŸG11 B)yީ%$&?_Xqӳ#cφM%ryamJkbN3gBtڞ+呄:jMأ[5\O քtO,EJ\7ִ{ PX5=0/N^OJ>n?@zg,~;?3e[ |j耻)ɐӠw-8jo܅["i\KhFlb mds +|  {8V:(Q(wŽFc@oaW-yW>0ܹz8SױW%V.'[6W#uV#pPw9~y|'mVCz}+s:l + N^g$O +h^:G#EBX\z|&⾳o\/s'WW`$3alZ ^§yowb t7G5x$(ࡄL^udj~I=&'y{'&GDŽ_<&cq>ʺ|21;I`p1\<&``_ƀk:e6 \hC߷ :f +~%dC+֤]O?3-N2gk2&py(}NO'ۍu-:A3fK(bmCF}77 k9n yqQ$OLԇQ #Cr5NcAob? +}?"zwȣA?}#C1`m=&R1!z_q E1<rjO[X8y>d^O^__5_6pF9J\C8 st9?pTZ5ʄXVch?5 +mc"z>ӨEzzBX8)cbxL0w;|r.=HQM=OE%8wxQIe~q5jX?;e>na 0J7Lbm;U6kn)^nR'+Өz(` +xl^ AO=yG/54BAS0~MdE#=Fvi&z '>75,wcZ_Q΄~!aOB]>r&prP%z f:S[c<&tA_h< )OGA{LhP&I0ǝƊ5O8k[{%8v@;qs[`\ Nz<taL(Ma:W"bǨF ܆5r%â&CN]r*?z@ =&cϰBSLj%>I\-cccByL؎-dI waMy*|7[A 5Cr:sWLTb9iݥ +m-m`z`3SYPCjuЄNJNM,XZ*t+rEo;tsS!> 2j*A5B]MeNPTj~Я=tagd37/Qhp´r5:`6{`/f(Sk2c"j`J5<&h1Qܣ!n%sWKK`<2wn4׸<&=BTN":g(7ְ϶o<xo{+*x\uI+?HU(B*k7Ը,@_[F>[1*J-N9C%L\&Z jA*uC݃pyطb!H;Lth֚nTՔ}-\Yi_|)x?فoϵ^U~\V:F`ϑ;nRRQpz1iR;M=vg\q4wLkhSm!58J (Fmܧ䰦OOH[~v!òE6SikM^xB[>TF +vRMm;+>ًG/;DC>= W.䝼С%m:k< (FhK_{{%Z%/ /Z*V"6 kT_\*H>De''/E5(Os G(|ȵK +wFwb#~Dȳus< ˭jLе"&bfQ{a(YGmGr9(Af&"1 {@<h LqCLU=p {)^*5{ta/cpZ0`Q\TkCУ +BTE ` ::7A{5#<恗jEk`/ !V3k4Ows?ޣpk"1=*X z&ijb_/{ / T{8~bvR>f7B?c[s9RQ6&8IY?{"Vx뜡siIx=^tRS(b}y_ {߁z~7z#$o5B}haʳP߀7a胍0f k؋~ B }~E/k{Z>CQ#Ÿ.>"&?X k+KcK`-] sVaQ_yQĸ r3x{%{t_W( xQO65KqOք`z>i 0BLGŽ؊׭NN4X]4:fh۰`te24u(g}}%[CWܟuwy?})k!.y){`M +/ ?f'զCe&{r(gmuTTo9€{ȇq|5I(E;zU'Nh*tjX7ahOhz>~\9K3a~Y*-tJFę0*KETtdF* EjH~j^xпOqqMw* fxOw 3wsz2E]Vg4{=1[x-k 򚍙4Qx״ ~A7#zVg)zPk +\F[ǧ>ەVo%k@Kw +Yv/5[Nm;@OJmotNQWU*h +ÞnI 5qhmC1yu"z8޳<7w9oG +9SޏnBU}a +O½W{ +\}ԓAl@(|xRnr(FEpNk9g7+t Ү$Ҫo|t +Z3i9lYF^YK(X;~ ?;uL^䵱̳# ؗk$=J&7]Vbw0w;h!.WG}Π>s2{Bу:3%gNU^Z~f2z(Ao6@\BQWU^tBlꈯ֑U,}NLoQc25 ~ sQWթ=ۃZ͏폺1@/C(b^8.x}Dp ]}(>l=yQ8Pt뾜&[o0$':n B]a/D >> +7_'%WMgwDu&*ʷ3yTb#W+gQ%bugnڝ1ݦpHO|grэZ1ԛTF +pKf k1?!zdŻt@uذ='g}bQ?>4e +:NRE^Ϛ~ق,(,dBWX:E +'{3O˿^< +0:]un?:-~Zan[=Ե.mv%l>0!o|yG=$_L=ʼf*ҥ=3A!DyV*h1l_(PS(6ɦ.MQ2:rcl`Mc9⥐_eYy]"QQ//UGk o~W{? s~Sm3LK:.nܭ9!.*7*/8RZe_(|QwRtE \JisL:ۄNW/fJ}v~* 2~`pYL+ׄ zVaos0Ѱo&e~5U}tbDj"{ ?RUPz>]~ TdL6GMxNUy +kq^Qѝ&#S;5&!佘a^ +N _6>i<48h@˼j7VU9 k-&='Ij|~Wqa[Ύzo̔0ƽo^ZvLnHmLN8_ =Ӝoٞ#5>x~=imFe- 燐j0W4 wܟ/K.:n6ܴ#_bR_tYYXőWD>l|hm #e7 +LM^K:n6gfZ=L6j, j%Wy>)=oܐ(~]u֢'&a:=OvġK*B c4T)TnĩAc2=n[LfԺ5-VhO^E8@up5جn7xi9x=i'˨+_?;'ze?tAt:o&мy'F}5Ql[HQwM0]e+dd=޳^~~j};N4Øu? +j˝~Sӽ\Y/{pνu9M?NXeŧWz%Uy%'yՅ%kMK6'R)~|k6}s9-D{Ԥqaz8H_+kGy~P x / ܕ9^ߵ6QVOڡ$U#cm#~Tj2*WO>;.Y+Zk )]:՗{,XDqWy}PydxtQ[qdģ)"ͯ?636MSu5]o_e440&_z1.ȇ̇TiYIѫ&kQQ& n+\o|l4왯~VgZZ^Mj* J>[Mīa ݷKNU7gޕP"5})>8%ݧNğ-[Zub]7:Ĝ踟lے, qn Ϊtܮwί(oV\YXYVg^]k^~,+szPUZoݔg4:\0XdDo g@!}!O xuQN"MQlyyQ_K(t G?UFP<ϝ⁲Hj lwC|AAIqKh&xij.,5?\kRQ_qq{$k^-[,),lxlQ7GG-ښKlANPd'u!):HXU^R\Lup4s'#| +H/,:7ĠJIO998}iZm|;=&$764׺eXҁ8UWՎ7j]3+ݣ9E7E7Gw'7'a.5qe^1Y1N161gbOHL{IDECD_dzԴr!#z#nM3)Wr1I$1&7U"D:Pp9%)jǭek($v GlyشMذe/va.2B4쿭TmT/nљ7xDJޒK;nΎg>TExQbDy@R[ROi. > ni1?2] +۳fv;MڹIE#@ 梇"~عKIFM)kE,@#ߚCL#%fT$.#g#)l!VOlճ&W:ۭ]ñ?mɷq;I[·.QoK\ +#sN-NOJyw $ݥR#}O%_/R}N͑qu-.9ua5/Ov+NQ#ox҈kXd`A,Q\O,P[a1@L$c +II("P$o'G*]|>Q9qhj ;e+go4"\6y Zz}o] IH|Q-V%AU#}\*ySu3yM[TaKTz47|c>'Ңt~,q[zWh?b㮃eĚ+ur^Y3U,d.P$b1B%>G2?z<'YDˤĆMb7$s6/ ?Hb bb]/f\)]=k;hn.q/vy[_| +`?7q-6u+"b[bp:{N+@q8xocлWc3= ^2j7L"ƌN&FLF?"fO[CjF3DycsEuTlv->';-*WL;1Q/]"BM><K|T}睛$'Ʋ#;-9е9,mXT[!{ʼn54z$tM3QMG#GOߛ}' Y*7U:q냯:ԴyE[b]|]4keQLIa^{K_q,}\TU-X=s.N~K9]:44B?e~﨟LnRb"bEbG0Ѷ,%,Uا'qOs}Y[3uGLGUD\Xy@lh4 +].n)Rknﭙ2m#fL183dq +_5 Gh<=<7}N@:ML'Xےf!ȩ?w> +-- lˊzغ)] + JĽbWX\ <[]8{c]0׵H7ϓ ~!T1f~$z\׆{43>;$Z'7uj%ĭQ7^h۽3ՙ8O7{&61l,vOj)Lm)uKp}=ŧI4W9ĉ6&sÅ_}59X|S'ʉӷ J{ڟ9M7R^Ho}3mGREgZy[B1i>xxVƠ. +(4W/a4Y_tƣW'i#fdSFȡq0i SF.!&.&[C̖;LN:fr+pEEʈX`'[.K)0^i#OS(BGSf’Ĭ+c3ƭ%fNDV8D,\IM;M gqs٥wEIe +⋊s)@xꝫHvpʫ+/}bhG-"q7c TXؐDBZN(,nIJo/\^`R]4[xf, A\%-5]DwdeͻPno_X #8<c62%33~1gzb}ҵ"bSĢ-aI[% -",ybI*95~iK֕!Iςbʞ{'4J*)LB9>M}k`s@c`sr]kpRhV՘9ڔq8~mzu!7z1oRbUuWr֢3}!?c1s>|m ++ Bbz+bFΰiJy܊%6ܱc W>_[׈Ʃ95\gKFGkZGSrWTKD.]k%A>.3.*$4f97Svzn11f11ktm9P|*!n2&o&p!+Db%Bl4}*'Y˹T_ EQQE!ѥ{ՠk{X*}r\y%%9>-\mb[n)sqkC)+Oȏ^i.ǙI(cO~MF! nn!#,7[KT=݉*/* +hbeSp+ulOْgk6wBVoۜ_ +'܇||uI6tΜv.pDF\6AabB~" PD±9}ΔC׷=a11cB1u!7b Bq ΜX$dD'XL5%ݷ~¾[ܢMV>k3"^z-z!mDV9}}ħzāVԊZ2h +c6́翰d C5͵h L_)X?bPM" 4b B~2!P`L,؅~IrsWqz_o^J*}2 b?пGvO.JۧW +k9 5?y1roD׸q+O-ߓ9$}3vL^1qcVNS~V:0߉q?s9'0c1iE5j6 +ҞXnIq~0rmћKm~;v'#׻շb֠։['nuy7v]]U<-V +m;-W49V'jX!ڸh,p]9;UGRz4D[X2 OR,yćg+r Tz6:/X/ 6[^Z7yUnh|mȖ]/"cF촺6j{}m3*zmB毜̗b/^=\6_+e^x +zlY9o[2C_ '?N:Ŝ0Xv3m؅o"~Q4 6&o?I,S'kZ5*ĊĚm,Ri=N5nq=Xsu rb0 2>mUMdn\wѸ"X\?bQ;;'JQ8#~̴~pG5s-. +nJ/wܾ>Z[_)q  =Wvܖn gbt~ e~)Y(oAhp13"nS9hjͅ!cl#MZ_zAg!5ed+Kl1J1g<_}~u>qG5s| +Ui5rAQ;[1:/zzwn1(#ggYjM/ O ~+yacWb ?6n;ɤ }m¤ !E-I˫`QoEn9GoM5Yb QXJXmOl?ysvʉ{nn4ty!*}}yל*Rhzx l9r1򺧏=k;ZgbbNiaۜ.E@@wo~C'8vw-VS~>޵o*쮃䕏*G/G4_pJLX|c:kLeSUsJ9ggZ.'mK ai;Ԉm;7:F;,h~fӖnj@J~ЭX4~)ttһ6E=]aY'Ϳׯϻ:B C3)u@=m>شMGani v ӵLܣ}X8g Ѳ>g\"ʢ6{3|;!$흫[sۧ'xDh226oQ߅t)a}Սy0(;i*kv!Mw-zOnp3J7n&f|Rf,ce7P2{bSl^m7gwǗm5 H\DXo9rԕ/k4=7ǭVQ<=:AX:XviueL>hH X戥DSell^&Z-b¹Į%=X9P=on8A=b c 6炦ZxO8n4hɲ]*lZ*rsPxkzl-gYG^kxY8tj;͙Vq˦<)x=sF)[QpǓs=a/[md䀘}n^\/;ts*Wӿ0m%b\bӼyqxsYfΗ91_Tª*gGUo*xAYͺxT1 ztȜ3umhz~(|%GIQ~A@Z R݌m:4lPPnz?Hلr$rrXnnZ>zGajbx\P?8}^%[t~er%1}6y>nc2r6r@ +t:ga!&2g<ø +q6lgw0NO\H{'֞0*0|lTV&ʯ56*N3uMʞr>S_5ĬIČ@u [T&|$~s3x9e=ׄѽ<3t6HDVR!Tn't,m +a8ϜvQY]C0z]啨/} +\٪a]#bbw1Na |s9uJCF<]xPI ?[*o]60|3mR`_q1A?AN>ޥ.]W˻M c3/vߵ b6)SN(YMZAUoVfn{ةu۴q[T ]jƯPmh䴴q:8M}ij=U>6ZZViY u5bā ]40>644GE  xA;{K\^@2\ӞiYԶE-a.CX(zYyH _Ew"C%'mfJO)~Α=`hֺ򽾈 ~B3}q^ۣdux ySTLTm5]|՜{aM#BEI] +qp~q}Cc=}V$$@ r9#P{ZJ(sN(HP9`qڎ؀1&:m9snٷn}dPs9'y?eLȷ3tIY4q{OT-uqN9|>#qI'ZcHgjo~\i~ڿnv}8|Uܯf WskqYN?| v߼/sѯyst>Z>}n=:mnײu:{,9run>)`,yA%c6H+jG7^AR|Nm13_28]ƖOVs'jFk޳$ͺdvL<3wc*_3Xyy_ϣu~sowO|Nc5~O_{K^WS|_ykO7fvL46C-vmج8n :/eZ9Z\?+=T_g|A8;tcP>Mh(LۙmU:ԟuq7ן=4nOыцۘT($:r_ondҞ=(FãB?ewI}"tBOZXkt3Z&Xꃳli~|WVv|OkG +ftŃ֦ jݛk{޻}v@tf8wbX? ^ ̅>On>>ݞd')C5o-^ Ux{bܸ?z9 ~f6~7}h)r?kfY)^~!ƔN ;}tsFMduJ=[l٦%b_cEY'bmó +)[Zb33^{&Ƭ.g_wF[rVT/?u[)3NjgA;^3a8G_r~!}11?E|f|\r#+4sC,tF%J(η}El 3"=Oy_cKh| ?ۃyqkV?OgL0cqԟv]ƫq$Gs޷_ ??vs1R_`Ssn= Bӧws ǷynpݲItKf?{:}D!2?8 M5wާ [%U; +0K +9.NM)w"fTD()8ZIc?cU?W6Ou2?" BZ89~hvnF0Ʒ}P.lW5t|N|Å馯X{w_{b(;7/$ON0XLٶWoԭ@unN/7 :0" V]u}_9pנCBѤtoYU 0GL!eP9t+Ϟܙ\.fM'mJMV`ܱ۫[+3ʋ .#\я\eMV!K}`5Uins|=4 6ك#p=M;4Y^1SH'T:1v\tHhG%;oח?یJCk5w/o^.99oRoaw/ C? +Z ҋ'Y'!N'N&X.^<8K;9$3'qYb{۩z}R? y<sШ2ʲŜ47Wţ CKy]Ӱ^ gpW7n{m*..;t +o@c CI5w{7ixQ|&\2 *}})t7'7wcr{fL?>a>v\1?=hGTXq0}oh-^O?H7 |ezIK0 +|{|2[s?{a?Sw1գv?C_+j6Ϙr `oCe14gP3X-ДW <<:  Ѕ&:Ϯ6N>ڈ -:0 hVW&; +ӄ"gY}!2_!d8KG'ǜV'; آ|Bb0T'`Օft<*cuN\^1$p[/U&ʀ蝐PEby w@{lI?sgf}kf3[悻jd`Cs`bsG5Kh#SmQy#33%U\Y۷M/c&tġ$؃}B!b) v-f@{|P5dDKZ*\si)iT]Z{{51EwS}~D؍IAW> է7U}^fU^R\>x Ɩ7WY btƚ#KGqm[Ijh:QL(gw07`n w=KiQЊbz>2eW?X]:h*q.I/\o[sa/԰UbJx5Xv~.,jXkhs+%׍51Yd/0_Z$Co2u1<ۛ@N21֘=c#-!̌ӶHEceZr幅Ыc1լ58ZwfTJB jȻ+>V\`e+6'&*1"B11Dm§T !!$gQ;19&؀_g9q +X1٣',Y`a ɲk Y# RIm$UcuN&_z%5XMwG_[f'}هƃozL ZQc州?z9=q/RX|.$֎A:lknM};u4oj=X.rH%~ hrC烓l |%𰍜^7A>MOk習e]X>?ƋH:dYCI6^~zNe/bvyv`s$^%/hBdp0ZNd6R2VLdk)mx.R^^N,ې^UݵjJNfRyĊuw~E컿4Cbt0KG"&a 8v-Mf4A)7$ۀ!4c6u'"m%T".s;h +֣X0Zjě)n1]Yt ,F%>2FHkO jE'>gr߽C?b˭5K}a\8&3Wԃ N)] `;oNm?4' ]6gygI Q\d(%֒ Kq-Rm}%Vm\^y>Wr S# )-UV:9 `GAlЧbQ-$<-fM9]o!? oUڿ_ֆ'yl|gQw+u"̦ Ks 7iDeFqA6)6r+aBX m> /)Ιrl{>V8M- V}y6? s^1G9zz)=)?u%-Ĉ2;1*ώcOtڛƻzi&s#)7bNT1guo:{qzzi=/vN{gA:z8}cUח> w}WC7^x DW(Em3J5b'λ{mn6Bl^l#|韽ѷ@zBY,OWwf1žOirkCbm[w'Å[-0.5bu^16`Too$Zri:ǵPy?$ +y)đ,*pT2g^ߥ_|?#dO&bs($׌NXqy!|؉ХbmrM7w@ @ 1"nBo ZClH|Ļ[O +QbCRe\hi:Y/]z©dhqiKD[G{s_G/S/&;u?Ÿ<{=H.|F<ΘPrf7i c*ِ j?9ki?c쾿5/YQtx6l^j?g/v}  X3B;_mN(z"q:кvz˞IRa{k{/>`JWCN*97W-VO' u|Kvg^}$oc$6+Fg5 ! J-eIGfwz1뀁V~Vsmtp\=NdN;T{?\fO"-dW].tLŝ`yoBHS{Kv(^=aMѶIZnL-q4PM'f@,BXxe7?PZ"wB)T +0HEltXzt+?{?Nj7kqݯ } >z?JZܨ){d5hQ8rYn_b/:gZI^}mz塁/ysZ|gHܬq`N QXwjRAhBY>pSN?COS5JVF1zZ\Q` iLHӶ`4i*'C Բp3cbǗ9xh^@J` .jIUbݤM2̛YھdgUthjY,K,kR +8h%@kY41ی81$""g7^{=iq4ǂW0U=rz& ZU}{YB6˙bK7m!Y0s]wi94kq1} b|GeۛYM3S<R2|3IN CRc~cgM;J_BGrg* י,PY<#B;veM%bVp,ײ/dU('nx{ jطl5|vA@]>T7=]w;ԝz7tMo 1 M5cR?f12s\nw—0V|v&rVT?L[h+:f'a=\2X쩥33 kȕ%Bߓh`y2zu^; Fwvl}}L:}z_,ЌZx(-"} yr}-77*G/.W/,!f[i,a~AZRJ~'fRW*vjt=΍o6-!$YˉL/Yv}_@/%; VI{j&WvxɨUdfgXmbJ(bB_=\>W+:9xf-SL9S!g {~@Qg<z|jihnF˻w]d:CgbV\\ _:`ǂGg=uʑfz5X=/oNʡE'YvD?ǠĖ[\R+w y{ :/N0[iYΦࠣ.')NE |hLjVORӝ̓僳R%YFA `g1"v;{=\=^M)nQFo+(,~|\? D0ԨwYR'wUҚM.`T=C}T&>9B=Wb$c>#}_|nSnt-*>0yJ@6뫆i_Mg*s?m7;gpm;Kll r[βZT,&6SO;2BDV[,oG v|~ {,0-i`+Y!FZq|T\[J_`jĬs<4OeRɷ'>YD0Scd+\`Η  1#`+/wEYM3? rfP4SזW6~ݨC-F28E:,_+YܖO*e@?ʃϼQYiGu~pkT>` {o{ZVd첀yIEķzfW;\p~+6ɦX@n|Sש}=zfIY1=r/%4?3]`gG/̇Tzj;Zo/&vX!gU3,c}^,w7!FP|-uق|X8qk>wylw6K7K'D\[$3 Ӌr}||]uזgxOjՍZ)BX\w~)z/yEkXEFer;lAk)(=5T5*NK u' ?bd68#Y=u#mAӁa1x4kPFl;-u:]`nȥCs0cB}sE+qvrBhaĀa\\ b:!i#S./O|=o߈"q` Ả%Xtb:4zeUKH fvoʍ,n >qlSmnNc;HG,COC]g{bzY+b7M%8obGS?_Ybkn+l.7X|`3wcXbZ3XiJo,NVupї`Y˓R7|+_"&QO׃99Z(1<-\ObkKG#rGqZ58CW..$> +I> 51K&7{V8ZA H-w̹%Zkatom&zrCWHrD(`8zshV}{[كq;?.C8`޲r֚q>@)81 ,ح=\뱿fu.T}~ ଣ7(1WSye8òA,ֽX{~sVE>by=gġgѷbZ/x7zwבήwFΊK>K (w#WTڛ +B݋/Lzm 31d0U7&EZ{{Vɇ]`9x3Jb9XHL,#ie*ͷ7?1cO-XJo3bL%_9S'rѿZ.dٴ/d5\Z|`e5 +9w_N,O]PZ-r 0 ;[jKX{rz+҉Ξ׈3@Ie,rO7-wОN|i~gbΑf!Nr<.8ƨB-nr0ĬzgZ&,qު|e핵\_-v}Cjyg#[_)҂;bYɀ F~گa9 kL*w/>µ~;:̢٣cG)3$ȑ,ګ'UQf Ka7 {pZ3^.c>s:XD{Ҿz!Fmzy[%fRl(m05Sf,m"7 +xZqfK-ퟋXWx/VN8vFI*':s| ,M8+)RF3y6bv}E6r<8虰<k\aG`2G+bggkLIe׮OY Vh~k5#rB rsO PA<|핲|6e74o,mnG,xeا˪: :mG.U+` _i3).\^NLp#sN+Go.kn,Ӛ' φs/nz"Vx 80t;oi'_w~jŁŴ+wMzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz?_lޠ |WAB|tML8.[\y& +X*`VEo,c?jŚu.+A.̿ՅobDxD,!8(:[ٗW^f.7oXbݚ]b5V]qÿ|;^MooK_߿䐃ebQpX`#C;. .ʽ){%OAqYBFWذEsYa W'y䲎M?_U;ĭn Dwno6X ZrA>޾aǔ`c!AO;d=lo#K|C3l<:o߃:>#i֞ݾO_ +{yK|X-L,2(=F]I7#4rzK1Ԋ[gakѐ<β4,X]YL19v$AT"3F)(i9)&cPH9찭)QKd\I!>ǞB3l )Ml 9"H ! 6)ذh l='鸠h+)8ɶ|x"I@KqIHq(2IjZ~,"Bp 賗0f{z&GF3RnT!QLco/7LGkVmFdFΉ)t $kJ5@ey::|@/ZBO 6d},A~K&H$輁38`a|ԠX5e)}{t/QjE@A:) +җ>ƧueLkXQGbcUIgb\D+;H;zcvbhM>O.gbTvEc^Q#1vRatƏ1ZR40=4\6e-zT>NIw"Y,Z1#ҁy2 ϥYj^tH +kA !o6f4\7GHBrș Iѹv!Us&)Ʌc! + +/W%:g>!O!` +:/NF^ee|Df Ci#`?ƠH+>4ϞFb)f +y k׆_\h%f<  % ~{tm`l& L<ɠK2GQvHP7BjTD{.Ɩ`[rOv?i)4`V +Ia4g*Z@쾩YǧYjY<̀Z?_ I8HKpoCc[l #hY5Q9\5NNo!av `tQ+bXCo$ !NLXKKU,ۦ;k119!!ݐȩѿJ;+AY+;5_q{Z0$Ǘ:B>F!{ԑbzz$!]L;Oe \P<H7{q= nM@,,.DA^VHfBV x<aŀ $g!/uL~F @Nd1rF9 pi6BlhHOIG./Tʮ,"ٷ$R ek2y$a'1 jIO 6jfqc4FygOc)Lc<'=C;= lj3r!H81FYFn{H*9,Kop&I䒱jJx?bE7 crMlO;iEݳբ.#[X WshI2fv;],8IcGT+/.l2$Ī+ !OL(bA $5HG@:+fI3ٵ`5bb!1Nυ ![/$Hd6RD^R3Rf/dkcdX\$x#pm_®8S,,*JeeJZ[o \ +䧛7Wp%4W(eMDl{]jxS談R2k+1N׮d`6!#GROư2dzTNL5 ΃YArB5x%ȃho$&hc&l}l +˅|{|WbX\K>b,~f %f/^ht_*PgA#^]YlYe6דj')z<m$ ~[Hm  @KW"Vl},,OVR_FՌ Icח@[+./p4ʜcrbK!Y-朜 04bz1c*)@!AhÀdPdgxVR;JRx+UVo_lY7R1b"\Ǘ[ \w'ՐzCnj5,n}"OY7@EergY|Y|2!Jri-XARѬnʴ\N +MozK{f\7zoes9_{q!7$Ȱ:X;(LlCmHJ&d!fB(xzmSPr T:[~Jza +X"XbAh-1ZOpX#p1gd +h^B7!u{^ +guH%>3gY.HaXִƘE{(Η8>rd,VDF +Rw֓$>P3 _ ܅>_18_0@M821| b^)[a=.@O,ޢdo\R^&|r+!1!b9PH@2'HJ"gEǢgf9kfYŜ)/W廾NԪqgCYlrhz~݄wlxTg $ 娲ш@p#%B*x:)dBDHȎ '?6?A%B +)$5j:Q'--di&>ޔ$ Y3$ʼn^Wak&d$cePcὑcA |V;/9?x1惯>5\sm|"Fb rtX⡌$X72"k+,kлVbY]xfqjI!cܙpՕ,fC:ͨ&XvhP!1G 9k&NA<IQ~: (٭vz9]S넖bk>&ӎd4nR\Y iE䠐c~ Dw֊o,XgXBG;X^;:JT + C\cC}QOLz=B{K}yT/{I9rE$o>!!N͗{SN}'_|ʉC?;?LHvCX.%ފWҧg> kבS~D $U~Jչj +uTCuQO΃e~Du>%j,/Zz5MH#a ; ,UE6Vc^+I9|e/0BȉpJ-0uhŎM6$QxÍb;Ŷ %>'d,__+˅<ګk#ggأ\\HRkK\",_>G$5쑐2l`t48~w齡pTIz!7)` EKH.ߑU@BԚ_کBb(rs@3X "=! +[#?R;PGfzz~t<b)=Yΐ6Ь6BN@XK;#rg~g@2U1y P1X |B΄z {Vą[l!#7Kw!䤗H)Ɋl}Ȭډ=P QlFBGHf7tVgCmP= #a:Bߒ*GJzKUh|g5?: jDx[Ũ8Ã(6 }$!iZ?dӱuP=&n~@*zN:ۋ{,W3/.H3#n\% z:%X$`ч",vilV QhFBH#x%Ғ] 8/*hNT[?B5gIjŅbϷ{=?/+tLռFaP%c\DFDVG '?԰Z\ yYRt.2|RXا^tsswJSr'f!_~(ꉺkp 6*JX-Ϯu_F mslu'$Dew$DoH!!.T15[O<Ξ\S99MY(i#ksN<mO$)z(_{%?ooh*qDk$'o=z-ENz^S< %iՙŨPc%B$$W;?z(/|SqOvIabaJhyosw._`F޺|k 7~m1b(7>}I'n:B#dwF݀z=> MJo<+_iBBF$!Kv!8_ gvDdy[/sdы~VZH([Kgo{@kÝ|j !Ԍԃ@gL%'gk}k+qÜtϠ;@)Ǟs|*qa@"7t W8ފ`r暝L︴D+럏=%i = 3ųBL7Fβ~Wx#~u@f|Xcjgr'YmpcH`ŒYcJ+ZBHTG -BK-nEH3B9`H2Z2 +{\Tf.uwz+L֎o߰v~|Y:tRpi/v)O܄V:vhOh쥢FG/ Hʅ|w䊵 }{5 5Q/>ڱ;g@J]}A^+,8؛GJ%йbi:!cgpERUחj'0lأ +8+<5x RY}vRs-$2կ5H+eTQ_}Ss;&A/ +}'&QI7#-7tg!C܈}*o5vp}m B7ߠX)KH]g6MBN+q=AB~}Y0}X9>؎.g62],48hBwZL%q/.N^ejʡbǧ;{~ /vgXG&1-<|ń~b "LR鹹8#|2rN4j3qT}v!!K.O?6i^ &Bmg&X>,$;ݍ: Q..O!sSl+rx-ڊ,{CA݊^jŅTo^[JBgZ8(fjJ帷س^=#%8> aϔ^G cyV>(IkXEӱU;d 7)WW3f/΃{G9I˵{fyv`_eĴ YyXmۅAog빿}L~Ou}o1j6Fx~PdpTsVpokﬦ4[8zܚWLx771"w,+yY/`= }N8f9vAg%S5ֻ\qi9,͓+bk`>45N 3ojhNUl/EQ(Yь3q-3bs [`ā) +zf N|k1V[E^~YQgp.E{JgjnZt,̷®qN4{.ե`5rR)R/?@9+򰌦IE.<}a//ẗ́H ou]<(:@1&4\C{(5'=!;g\3'w'o}2Gΰϯ4@ k +~oc~bGY>rZ`& bOvCmÞPj/\sa|mdGob+Yuy+ 樕-o(0g_l !zU6pa7.8*6~VH;6A,+~[x <:1ׅ{ȇ/(t>x؎fU +Qg dk,xsE\sĚkuf:sɍBY\ݵٿc8}kÿo{9(\UNՓ^~O4kyb'Ү.nͲjiYj5G -Sf/,$0}J<Zڃ 愹=g@f idrn$WNeIvbui*?^M[ȤN$dr Ĭ2mA~ Rw7wѕ[}jxZѡ#`3 #z#ZA%+!;Av{Ga=~'IE}7m/[ E2]Jm/:I}x5POA}'5_Xċ1UfF &(ASԢCth@s+|+ԭ"ilz$h oGgZsӋM26#е׌\DP|${cTAEt-{wzqCn'Kdc-n=tՋlH݄[MZxj +}TI֧e qs&4Q]ޠ!;n`~`Oԋ(vp\1;ͩ]B"֘ +a>Tч?MW_z'ӷvϊdv!9΍(ڋbW`~  1- +;TR:F$$A:_ +L#b^(eN=A1G?IZQ77hD>nyVOޫ'H%RԹYUyc8_r+KiA qE85}>w~v G?x_=D!%z +[C}Ӂɉ z؏Bs~)aE5 .8ԬMٓ‡b,&/[g+.l:Api!֌]FŷyfL5QIjRnk]aAu)6^ؓ<_s_4x|1"&RTq)Q:v:OVؒ?K~}5K>5ꛢJ?A}όYXrQG 4ȇW(,0QdV>ѯfG-~^sE;B݌ E`H^.d_/VT-U*Nx6Ν?"Qif-2Vo؃7H8U;UI<+NKˮTyWzU9 +_5=z\61]:^k:+U| F> ?V '_/7Qoxuȩ,ɹδhڠ'G㿹 G;B=UJ]Aގ-nšz3a^ۚԸv>NI}pO>6Y>~&.o~'vռA}&xfmNV\Pg%k3?j0k0#g}b En9+|}Rf=0RouuNFwqGMS}y6wO <}+ov +Teyt}=l;.&5E_hOΊ6/ +%'yM</)2V)}Du{L6x/WS>'K&N)5Xop}33zDr}^X:N63a-+pFXba6ڦA]MZ+P\tvcAwv-Eu;lу.3To癞Xhs >U1L&EKC-KZ$MfUGWEWzEvĈZ D+uZ&Ưr +i<6/q0l#qKg'?4Ȇ_Iqwu˸MF"]m֛CQ@߆Wфw6Nw!/󚾞 [јX<4V;ͺո9~we"Z) ijglBW\`K)փbE…{_-G]lO?՝m64;wugqm㟩в=(w%KĿ ;]IF OܣG%comL=Eugf_x;mI&j:"xqud:Ү=1ѧ9(ɻ9(1C*ꪸA\2+xh&jrW u?:?*fǑ7Q5v|9n&zvFVTh/|v$Ƃ *eMgNɶI6EDŧӜxMObbنi-V>Jn;hˡdװY1p=[l2@I/`dOneﳨS=/w;KQέ!fȢfvk%uUMUUN.Q~R۶Xgg4O.K>?ɔ/|WۉF:]@h9L6UKȮg߸؋>LPtFQyC4j:^z3RgmˁѢ2?'ޏ,)k^!\ +j)λzZhXV5gWmfӪaᘹ᠅iUi[YYoE}y^ָ:vkT]> K`L~BX(I5.Ocw&e"힗ۓStO2)(t"R5r ZGtbB4+Ѷ+3Y4VJxϋJn 5K58G#9)75NnyUiwԩޜ(@~o:FX ls6:!: ڿ?ƫ6L&M H$ݍ\N;}O5~2ߘ2h(h_IIau7Ns' ӆw!yo۴禆65v߿e=PC^\j@ㄎ7]"k#"S\b yƣ|oLǞ4DJoWyEeyG9GŜoMКs3K". z! ڃD'Xʢ:BGfά}y#,_?ĆJ y +6m1DbK68N5:(h6i)zKe~glդ,Fk#.a^ҸFh_K0-E4_o& 'h /ekհDulb?-LNu'4FDH̨^kTKC4rV[Cdzi½'"Z~)FX Xu&7E$Ɍ%Nڡ﬍*ɊJc[=- ''#0*N2.Y[ArR|. 6S^ķ:0ҦVuHrlܛjFhqdo^wcpb~MsdAGt{$1V0ƎE_ }^*)pς>jD}xA_n1F_>>p?vklYǕgm6Ǩd @&J%ܱ__*F!sOi^=jz`1ؽ_{lۯvgeEF<ljϽnonD{Q--N+\ùL)dd.DOEa~ }镞90ol@y\ӖlM%YcK޻Dp(v ^TS+QY737bGK_#NMWB[CǾz,_ܝw\CEAr>-scZI/e +$XzXxXh=lB0 340sO`X-WX v0LT?Bfr~ + 'C¡}c7ſJ+)@QU9vgǒnw%n%.5QuqvAm瞫I^ <ӟa}ZާN.%uijufiv^V'{W͓6Z `*$)%2@'OfVO5$|6>WvxF.3K:P"}%)EŔ_܈N/]_]RXGdGenQ﫝"nS_Z_>zwľ1>,-Fg6:jr +l^|xܦeZf<ЙʀxCi Myu6,;,lg 4|qaܘ]v#**)vxU}L2p`08dOJ]#$ +=Q_]C.DtE~m4-sa*s`@ߡ2GkCiݿ[>MB8>vw/ԼGd4N}Ž]/#OvD_iJc߾,I4h zG)qc ҧQm15Α߳6)(}[Ik)Yyp_?Pe_lє `Z#] +80Gs?8^J +Ix;y{"genqb^{Ĕy[Z' QZɽjȤjh[zdwlalps2/)zmaSc0gSsb0O~=X6> jZا'A9eg2P=lۖ2TW+^k9ٓ#ATGœ!G!-Bz%lʊ%~<+w?=鰇f?|_m̿EswJkݣhac$o2vx-53=ak{BGgrG[BSK1>xD'FOТ]"p3+?}41 SρOk6{G(s4^aj#_>1yJ{${TW%,GH\j#Y$Kb9 Tyq;~xC9eLen:v|ΓY ʭsdqR>i񫀂0gz0[n7m+XHNW-wP#Ů0oxbB{mXCu3$D=2kPN~֒ +gIgǕ{t茌6F[im<'f_w@tJMS7ų @qh>`N`0v0 , o*X0ɒȡ7ln,OT}ݥ^>z=RGʽoxwOirMwNvMDuZ-DCy +/E`$E8() U`@aV0mX0s7X\ s?-7JO=843mz*}"iM#UZ^&--u旻GC5}]#QUڡ?n~gpׂp)K6h`:.X iktM$ئtRyOrx-7K`n[-yf =rasJR2(FWu{`lo ɩgļL62,] L ->6lMς{q,IX*jKuvpbY}(meўݶ65(E@TKw^ Ş 0KߕH\ccǚΉMU ('N3:9L6GCswK?ۡo!dp,P8ƴmfS|arBЛ*F[P򵷴#ScsTOkdM9/ O5εp 0@qfWCK-+wЧeRUF (43O mM/Qw_8cݞ}ӯ, "z4oa. m4%a9i9SSP[J ZKvѬu[&/ [ꕪ`j]d:`b?>38ז/9-=V(kY`&}ly)`ljBݞ5SwuNWzJ<}Z [{f>u:rLAq]?b4&;D^r:ẽhV OZ` a ]urm@1oX )Y`V)U/FA`;!{O?zGM֬45*X a~|դa ޡW)7|R)H?(IF;^3ЕSS-h4Ӫ 92_'!%C595ڵ=eKduSDGsx[RSkYݭRۜW,G2c)yڟ6`3~l[ 'm{?y=l|k 蜹ϯu>(yR{JoSk(ߣשw.Rϡ7i74Ϡt|}ž16,]Y0wvelkOCt|汼,UˬtKYf̐__*`*M 61_vw7>MP~ ǧާVOBp`˼'3v^q!;GݫgRP\)':Цv2/!X c3;l3_5tI FR94q9RS)7G +&x5=h{Zoڏ:56 y8 6Sn>ULN˪94GcU φ#~ kASfekAar0ς9֜`>>k${$G?O|1gmؿжFi+6 į *iCv+m32zE%=y+XC{u[>m~_jNB><dV^m_'BQMYkq ـ4AF JwYǛ@PM&wvM~qr0w +0XGk~; gO:pvTyCyc:[ZuT{3zJ];Lb1w]ml<r? ^XPegYxwjbg}xgsWŬk6c}̇1c8D˨QOƟ c B6篞 /te; l/?Lu&[F=Xu4_/v}w+ *Qjnv'u$pԘ.f5 oIB}D|aW#v{qI=7e0܍q .D65|%+y]SS@agZxlTo32ktlY +LZW/a?5`>2pX~M~ʠz7:.A e4۸_ +uĎ5@[jѪ7:.wD֤#'UOLѺx3/ۈqOt/[cx6̎N|4~>nޑ#*``e Ϟn}ehqgM}Ia]3/n/z{jm926,Wƹhrlį/YLZN^gd L՞7)j^ʝXiGw.RT06/YU5{eTCmcEx~F- +ڗy^d80u;zVZ^V71u1n@]MZLYA8]N 4=8l fg2nl.x77x/d/>,cD|C/{}7א+qmS&uM*DEw&4Ѿ +)r =̅Z7_/9f+0Z z֡w[\ZCo&<_8h.v[`|,^pL"DLACM0R|4Wayf3uXgq +~9&އn&677 ;,2DTL oՈ#xꢜ^B8( 0*3e7z|43/sW9v01*,s-is񮧭rYZݯZ؞=pbvגNȅԶq,g\Tn +mh?bF9szV1=FB 'hCV7zCW5o|9FrtV n3C }I_Ω0ط߭5 /m%@<9tYKi>%w%|o&Kx^מ1z勿:}>z Dy𽻖1r3`]P^>lmtm9Zf>q>Wн|z=s T1mꇔڡÀg8cic*n\1@{989B{-&*>\Ոաxg~lj|"'DfP9,ыvŜ#{ziOAy%΃ߴ8i=JX賟xO~|50.39U/mnOq3}@1 i]o`)l0]Eԁh{QZ4sZF@4\b 9 M=SכygoA{DG*, OsY{^K“Tcgn"*D^k h?3vZ3a)痷Ҳ]eꝬ[2*l2ȸ|n/aE+o}==lX޵/>ýMw6qg6~k9'jX,l~rq5~M^КFѣ[ ] ՌN=⼬ѕ67F#yY<$6~JVUIο@#\^*7F bf n1in;Il@b?NOV5#ou A3_ZM,&W^h x}o)~! 4.H-ho>E_FrldoZ{d}D'#ӖqJd| +f#ywǴ."0v]TGqSPJ ^J^m1ղo嘘{k('6Nڗq9sӈMqUfb1x򝜴!%o\{|m#3gNmZp`pxnt m0?3tX@G x{G-d1=,n?ڡu"f7f>ZO0ݯ %2Qnҥſ]B0 e}F{CaK {#=islUoe0NU]Ŷtg,eW&a9&uXާ w6ʵ5ǐ!^!',0znK^}ڈ8p(^+xI{X-<6Z"ċ'3{\K&t (؂EډG!yZ2iNJ5m$#C@K0+Yc&n8s$A0^,qT郸bESM_&,eE=֒qՇ 1pXE/k-vHiR!>W*fUwDn5ʹI :JJ +^u Ym*u[b,,' ]f!!/Xw4G#ccxxT^5q + +F@@:H˅0pV 'atg f*coyۈ^m,({.e8| }_Mnƀ2.]F\ [@pO^Fx8  +IpZ.da:6s&~gc0E!,oTcI^lPy6|rTuU68A ktbyHXtNm~i>M @Z8LF)K;=" vkbE!'즠-zX+6Ty +qS Cs\JO:İ'aNb'i`,A{o暟#<{L u7yUw^@'Xt#XB08[t ({9k~ +ˈڅtPwwu{-b!"eq 냗z 0ZHO5wQ]8ph~2l3r}|]<ĉG,UFGo9 iCz,#@'F EBTJ:b13L^Ry5bF<({a0 Y}X{ ޥ΋|ImmawŌ};8!Mf,cB"7È>42 3,0?KߪC@vMX_G|02T_K"&׊-9TA: "eB5H@C¬F9M\>g~fsV3$3G}&֧w2,&;ɓӮ188p<W +z o;>XqHG ZKCl"2O[pt~%eFpΝOcdd NC琸8qyo@ډKOY7qZ.vKZ-v^j0q}CLeMB,nƭ31SҊ#H1G x~ 嗲4oQ0G,ni9Fiv)H׃~UHoѠ6ɐŸq;YO^򚍴+yuuk5b>x8cwZRHcƌˇM F1iîKoQ%+ifu1f's yQbbjd|1}?4!"F|qBњQ?_H<&Jn%R4߫#Z"eqQ{$ -E֩ +3& ^<4[muGy]^]E>c>jb=( u .%.>l7C31.loD1::!8e Gi@e t i ~(`Fr<\t ؤ,Li!:*2,d_lqFA[Œay$[; Q"6r-b)\V+"%fXhnxUy MZ& zi +}w1jȿ`;246Lcty~-fmIsŭ ,j-QFv!Zvaq2Cлs#‹1s[^u bӋ֣XxL<{~3gFM(W@"& !-.uV!&4ju~[Qˣdq3 y`\& )d>b\t ~϶#:?)K^08%5隤!.<##,.s2w6o`M߂nS=xN:j;RX9ӑI+кG@;Auk ]M= *yzs"[ل9yݬV +Zg4 N:MCNx}?AXE\nF; mAv1>=^ +cv \ IH[G㑧e[t{ q0e'S }&THw.F:3fChft 2֛.4=:in-؈ewk7xB=&iHaqa#?pS6ʥR4I,!'RY2Y|PG!ed1,F+Ѷ: iS0 6}%?#[;KߪO`qi#˃Võ(xBDwFY9MA& ~J=?#%-e3| Aqunmx$ەacXƝ_qD%o܄-,2f3806%Eeb.GY#2)y +k|F1fMIH 1u} l8s":›ٛE)ބ,#kY̙z_utTY=ZIФqwih-!^U+ 1bD n".ݼ=wA߾{1(T*U眽Zsל.n?TܴB<83YhT-@5>T.%hga>B;K%33o/ta zaC_OY#EJ?kgVT|#d[5I$;G]A_Q Šaб"c/_HUpG;"=51ଆ}VK'Y7ڔмOygwJΫNb#1 bHh!bX_O$΁8!2Ql2UZkɡ{<};\>+?h){Z2ZIú5f b,|4zm󉇦1K%=Жι\qzeɉZrOoQ#BL45QLX⠍$HN}{^C@ohhqS}ܯĈ1{@{wA-Wpa14~(?wV`}S3}Өf[lXfGZA\ܜO'͸ +N}Eװ~7BbEjUa*l{P-'3iUѲYwP3: ze΂^2rΊhgHoE>鉹 qk` \)g +E|H6"o囡_y[1TXC}iT~iUiBp>xL`ObvY׽2,cGN3 4^=ee 3;mb)ʠf] ,ɻ뙛Ȍ72&2F#bJ:rmo +jT 6~DpcOrVŞW 7,䬴%g8,bOT;k<2Td)ZGO]WB'O擶O"4hf%M?q%~ +2F_yw p>9M 1M+[FB<9?rn$xa*T=Zr g;*uSFjw v)\ܼjgQݓWv[tg) +-vͅnMXO$'C;+J%U;vO/IGR$c `hId~~ m$[;(vZХf?ԣhxk'^ +n>w/h~ yW泻^+ڿQ˕\ n޽6:72 %Cz5&f +j66 uDox_0;#'`vx*mV.3 oNg@˗JysI.gQ?RtwtnYHwcv',>*wuz-~F mJA9#3b*'Xm4I؋o,z$ArCj3 5q-_Ѵ)"hZ\圙.y{̀.ՄWYh;urK\8j%5Y jyf$4dT #!)g,ԗ9@*'if_Yle.] %J#?an"Eyi9.1q%x-b=sİQ~SoA+:-5-,{#mYèk$պWEIU~ wP{U.A},Y{m6b'ſHf[lbm{JnJA#ye.V7Xu,7ia=RcRh74FFuvQ$y^/db\L9!FR}1;Vq?Gf $WM!*CSO-pDw-`z, :V}twu "U]gSۄL0Ea\X[lyOҙC?A@TĚ>Ƅqu)&\eEΒv1Gˡf읊.~V5\ 9JzV +jrMzN,d.}A$KaEc($~-L|oتo|lD1BwTk.H~ S|eeeÏR^GC:{ϒ +G1n|i{)hmc{rEɕET߉X4H>2/u)pLDGTſ<ʪьjf (I>dnFu9mFAucѠA19 +vr>>| 47q1uY+}yaTؒ:3H=Ώ}`0!dRDqFf+Q +FCd_]HR2j0I&9>ձ.4`ɽpu;ex(lRU+9-= WT&<+70,6|E泎,A.w)'+ևVI}d>kgŔ m#sXw׼o7 B:~2uh&[ta1%\yYh*uTՆ#vO>X6N9ʦ\eEHQް{.EMݳ9~)TMƕ$Zs/CƐ$@}BDuz q&ќR! GRLM5#@w%Nr2K q|b +-D]䓽,$%$T/QMSBsrρ䲨EOfOG-1u +<{@GkBTBd,tPF/u~֬!jĘC-ET` tMRτӱF z\QߠvW=㝂tyl"(;EMS9l? 94o 棘5uT/" +wzrG*EXz3utGcRiR`SB򾒢 ʢ y'g@g +B +yqe2 ~1{6ms"8q 3s=4[6/\@bg+Vb!f_Z@}up>0+ޗ2{ ' q+e7Vҵi{佈x]{2P NkUJ?*&1= 7L+.1Tg~bg*jXfPM,pnRBEqr9ñ'u +Cǒ?WHWC~]#-hDMבCB zyYfPjh֌'9 +9|9)E!W%v  eyOҖ%Xqp}Xb S/!t jw +Gp-3tZ~N0!sLo\5]D={Fi0r7G(N_7Aa+ n04ؠLg#x?yJ(Fkecs[?qꋋN؆4圵I,1P__5!˾b(3NQ\(HQpyzQY>d 5>D֏I u'珀V-mGCMM?_7%xc|SQGu>3|M,d +p4r仸IXor[Pۆ4gBT7o +"\=-س%nW8 ~ȝ῁#nwZ~HF<^OrL_1jv>йE60i(j>\ \q?)qT +Z9&{E'EAgr82g=uR=1BuӵR&<0FG6Ƒk^邒!Ov6G{&`+tA_#{ %}CRT\3X1iRxeƩSYasڰR' pO~~j|ju)Nf}{?D80GhM_/Ǘr|9_/Ǘr|9_/Ǘr|9_/Ǘr|9_/Ǘr|9?'bf^o 6[{Mkj'mN[l )xbjS6{YͱZb5{)+6̝cEv 9-0maoj0E^NN[ȓ6~Oz3/ݬs/2XdɜY -Xl_^4ւy<׀]7{*cȀ5șΤéD缅k>F2K>y<\Wm7|g|]Z`?7q"=?Rs-Zn~#[X[i1xM6Z&ZƦZx2C#Af!߬ei rrv>fe?mXL.Z&*OmZCVzlZ3̤[umk(5q m.m!-֟)O`zO^@7⃄|EGYkLrA8M,lDȤ,tRJ㍂B 24Z +n:rr=J[rO \z eb*7邔Ĭ62Y&24[zLehܵoIm̺0Wm@^aH@„ْOF8InaAVYBP>6s2!_K i|Sxu' p}N=ZFhhQ}auj6 +p[YDQ BXؼU@(gOK2J65r0 VIݢK /]^( +f~[!%? +d_05/ykO&#bJ-=X{O]Y~6| @J;]H;4KB!}ahP\h>mp+RB+E ?A Ր`0Q-%2hS6bh,*T%/m "Eqξi zɸFCW].k-ov!ke oO CGλCA /31b5<-: ޗy[-3J"YhY^h,b\c2g(A44cs>9C9>>h\"35M ҄[p'=t,EG{ΑDW-M4}M=g&8O_*AƁ % AS%% N)X=O;9Mh2GO+5E#{q|{HI*j&IhO} 񟚆dⓉD6ܒb]z6#FFS.mFLT84-[ވ_|R ^zsx/J1JM=qD)fD51fȻ4ui[LX1d4HTg3?^<Mt;zfE4Sbc8Dd w@o¯ T= '7XG7]4veTfBr*9KlqRfQ%ORz%mJ ,qQڻ@S\fi3=> g86E3hÖ{9甁,=:DJ -m 7^'S#*={xK ./]AU9-hȆm.>x҆¯A8Fa17%Fͤ͋I ?J NJq'|0dIbbMbž)Eo|!` ik/4݊ÅɃy 8k i@< Vn2(bKhE$?Ԏȑs=胬 +ׄ[! Lsa>.JV: bt4Ӳhj /C#l1fHRp -#vi3?H1_=sB{`_4!RJ|-)6d6Sc:z7h%҂xDsh_2Vzpz0 +dJ6 2A)uT~=SH7i0 (t-A%,B lrėҦW2'@. .GcX{mJ@$k5ZѠNI \(Xz9GXJ0axhj !@B}T@(H7ƐÄ知Oɦc>IC) (͠>s($om.)[1ɴAWKh!2%(I @MD~)36`6lM? bM7HM`YMUc@KC ѐ_N eG A'Ij^f}RP2H<-JOқ%d $scJ"24h=)c\½-$^*ůCtn7;`>,6lJzlmtOOLce\ 0v3N]Lͷ A%qd\I"Q *Jc|kYN/Ń|8ئZġ tMdhs-o3h8qO0 [ +"O lh% p2z3^b$*wm`RPLEC`/` 2R; Q$ '֏LFI*;W)d|B$@yjaTW؊א5 HB$f7F$r<gI|I|2_ ֧M8D0%t%yK`_EH>=O c@E/l~6C)g>[JE~G-f6@خL?j/%Fu1(ILHl媃%N PZ< +ʓzO??a` 1s"9I =$C0 mMQ g4IB- X!owնI >:ƙ,dIa~!6ܖJHW>dl\z(8Ys\osħ2CAP |}2zt[AjsӘYZy[-JIc7۵ RL W^: 9!'zk:LjE{=hq>Fb## `4@{a!%py rF\Ș=Rʜ y:K?=ͻD.C-val$Į0)9oo 9'ɟ@F&{yPO<$o:vMDN*+q9[wP!=lg [ڜS endstream endobj 82 0 obj <>stream +h+q` JPik,Ձ]Z )& t#'z%e5ǔ}(X烡r{yLpp؟袍,Ɓp(9=9+B=QCJ=֓h'+.i>oR :PIL~ !R"IC%pd S>aWFO(R8Ql`0Ο/Q_e}c +$ +f?H;, _ b'cәټبoQl9ʇ LmIt&1ϛjiSGN}u1%2GYfAIt@vf<ye,%/]:|q&?S,=26Z!¬g@!H$ 5Fs/@d'~{*AMX!&F)I|w'5291_>X׃^Ckėqquiw/6y>](է0{luց֛!vkt֌![RpwF ?ڔH쐒s03[RQ +p"K)q'RB]|]9΍SF'y*͛Ciȵr>ӐGg'*n,f3/fSaу$`71p>) -`th261 ka ɽ#w}ˇ2@$ hAJA +'=u ~,yP`DP1G v:I\csH*ͻLI ) ,1 D6;>y|GE)u*B[`_JJ-u|]n FV%yxFhk {a>vr!XM6+"GLكHsH:yxěPN\/a@O8N" F|݆ cKquh綅 wNM3Q|eC> /]8{nG9Rѐܟ0M S!D O B=$b|ډBbdh4_-Α!"@J0 ̆:4W# D!x4 1' eK!\F0F`2SZu PS /b{w|c Bx~ #R Xi JZWp} ?G e{ ȽW!,&9vZsx&)Z~PԽY b^Dg1{& $M`J}1[޸-=%u3| +]PҊź7L>N 2%K;77P7IU68"&8Y&@k ,}ޝvb.=7N|H|;"%#GQ7)d]$)v 4?KP v\DE1 #bKrO֨IJ;DkE=#4|>HAچC~ĊcR_ +߉@r6Tt9}=]K,2X.lZp K2w2!Jz,GA ȉPc i1r Ɓ%TlqBʩYTX3K,;~NCҌmu؅?. veb*7 +>YT +uIZ9l 5,=7yu knZ_3qe(x1)%v) 3T4{+8)X3tK聽!T ck]Tm` +G|PA2(m8=.0b_.5b$Q +b7*9fzBDXTP#);ڝ{**_,g*`/Υ~︁WcrzXAwHle]|zcrjA {);Z )7kL6Hޯ<ȇ)=S/Bu:FzleE "e$F kXx``JL !GEP D^ARM LD/k|ߛ dN-7.L7J KA\?ȵ؅!#hq{ *B5On[tW]+S:P?DEɅB_Dc9gc +䟜!RIQK J'sjB`~k(**'M6KqSZEIwT.i$Ee*vYB.HF&V2]O@D +~ǖ| *v*vY»'c)Ś0LQ\%fg +9F'OVs;^*ޭ@]Z=){Br47%#*3#!N +[rO1.}8ɽ 1Zm`563rt= D fG R a%Ϟ4H?>{`fɥqbe:6B6Z{HF#O6P̣3`3?.?]l-Q}  nKښ%OJ=!XS +)Z^(FG^Y($ɵ9cEL*+C v-8ϹXQiD)b\85 Oat;:0͢aThW4/o`\KDɻ"@5b,_P{dN}9_7k<͡{*|`JI^?%A"},)*k4${ggS <@bC=Ɗ)_ִlXT]Eɹ2k7cMR>^}ut~fQ)BLM= bsCC"vWWڼ9{Ǿ=b|lc#=io'Ϥ`(R` ֣9keN9Kp/x2QzRQ #T;&R<5y0k@ C(ϼE$7%8\ӦTxbXgcj'Qnx64*v6QSPKR؅b-7"+ S)Y2=WѼj]CʎX3 9Eo}`ߏ!E +׀{Qr}uu.l A4kQKC<$9Uisꢻtb׫ LY#DDׁ 8l H♪UwC Wo©$΋[BG ]JєkG[=?$. N>6]kBT`kX_!cb9=Z>w.ɣwO2O͇"[_SRj.LꨛJgx_#'A- +}2GX{F R)'qJc{+C]rSeM4_CmiAp~LE2."!T!n< ƚ`X= %_PLX#Y <[t_k|?b#!tdbL7g ?)81[JsڤIlebYZy5}g]S +a&c[iRQ+JT*vx0"A?,>kr3s{23BJaʐᨵ`/ 7[kfQrIOU8,QggZT=JK:m 'xH~hZ寧Ԅ}ivt:e>p2kE,ӏRbkTuL_^=G׎u!KQ~OXkfCPO:WLx*uj}d.8M=x,e}҇pA[1'kV\ `/m+?UT6/C]^S897g9 +|A tVuB-1n}V(J..̥ui27_6Ź{` +ϗ\F'eu^4ɻA^ֺߖ6XiDJkw>!k*:;"2&ul7BQjĤSiGh{~s,}=N}u4fO{Ԗ,uP3Vl p tpcج󘂻1 FzmKc7a,8CUؗeyS9cRYq1Dqi>O|+D+Ӽ&$'Mǚcľc3ܫ(f Atܑ.L% ^!2F}SAliLyt ;uDZĚQ3Kgʻ?1u+q:qh6ilEW]]D s΁_V?Mcu$fJ1-4 |`*kڗ⵨;yu.EI˄}^Y[,kĬEXG%Լ؝sĤӹi ڻ̔KqT*-4AJelf_ cFrq3UW +5~Fu!'0Q; nK{U"ö2*jIN?Jpę9sD1cSNUf (WxgVd"wU+v\}cb54Q^Jy&[HQqn Kttx} {ּ\*|-t*g$t2~fWپJҦQTݨjn,T#T!|PF4$؞{eVYV<^u< D\u2bU?) +h]89SYd | [޹IZ*/zp*rq{&2٧g3)jTVwdj; |mFX**sD(m^ +;]+,f+Cv_DCOկG陨\fu={׵L9΢r5ē3i>'A."PC|'$/fB A'i$Q79V{lYfS𛤸woɲۖyK0i1iz]}{jlZCsS[Q{{ߚsGs.;dp#RYn˹=O,CY;S_Mؽ̕ߙs0̡܉.A8)JZ*of?Y+b6f^1;kb4QlU6lMZeUr>eXPT?]}r7/mT`<=VŝyMKNy]|Y8|\JCxswKd=@ȯ򣿚(Np?8ʯZqWox-64[_c}`iֽڀsr./@,q#U]_i-k*Mn:= P+Ug=C/U'TH)|՝BK!|r:ĺCET 5B![ O ,Y!/ybo?ZsٵnEGտoo'*ZqWvϾͼ-Rz+a㽅˧)g3Uo~|TzK\uxaBpKRh9vmӅ6'nyu=Z~n:ֺZ,?Ԍ.T;m7[BT?YjctYG;mnب89V_{_~̞ybNOl+ko;/=ۯ=?;)^y7+_xՏ6D$n0{ s𕜩AQGE՘g w(ql##EU|#SՉ&Gط]@a~fẍGm3m{5T`{P}b8B|^zmqMbhPHeXӤRԫ,ʹUgty_Z6 }SH~gVqcY׋,~[*TߠRjqV]`p#rk֗Z]PĜb!OcH㶿@0"1xyqb?~e^.~&|"ؖ&}&F|א^YטVs7p}wtd8>=RdZ|Օ&=Ha?%Ӄށ^^JEvwT'#xߺV_tn=*hZ\nwzK{{۽ K7{lr6{ge^beʑE,oT/f޴d +/7T ;ncy߬wp7<̿oK>d98^(~Hgz1^=M0g+/R`焳mV}Tz6K۬TGZlذ'ܩ*řwA.E}v1r۝Y=T +;ͅ>]crbVnwK឴G>/$6WXz;6?NJlOpUչ£sg[ +ٽd.w]I/gfךVXhR#Mn۽Wn }ih~`G~Ye]uۙܳNDw=Xߺ?[4z- vm2g7[K,{K_Œōy͎tS^x3^Ksס{yy ewۋͩ As-ë<%,ts}H1G }:˫R$WE改>+d"y,N|gccn}: +F=H)?v&+_|[n[&F/٘U4(c WX<}GszBSJa(5{7q n5op_?ړ8ȵ? szr$^z١k Cr^?p=mp1I}s#5)0[!gi|\3gx-xDžAq=eceѲÀ|?W_M\)6TQ:K`d}-E^5J/ldޓdCgƍ^ :ulleb线7n[yێ1W\s!(ƨԲqFoN(Z?̇]d(&ʰt?f30fq!}~^jX`r 'ٲq# 'k.ӓ%a2 C d~Ywcvt3{Voe +_q'NOƷ\˫}-ZMb^ԗnGp9WoTݍk+I~?lMu}Vcn׺4G1@kUɓ d3fNS0v@c ddded..OKW$?M͙'ȾWh>=s#Z}>U]t6%O}%I]p%)f|^ՄWcv\;t9*ܕ+'/F$sysSK_%??LR1ҷb'| +: ֿ6Y6ebCzҦWG8S-?z^ZOe#ϐZh'[עočaGًo:S]v_ɻz%IM p62ױ7j4elĢt4ýMY=rd\d'iE ;UrR5[NNxEk}eZ?;}W ]Pjͷ;Ӟvw^u[ydR* XIr-qıL~[d9 )"'4&"79[_dclGUEhz`+[;V>[}@5/OW$t;J%YNE\TOd0Mqs.-=bb;*GϿE=T}b;;\ +} ͣ~{;B%YoƿQagdW4 }d6gy皕Jd9i56wAVDz-Av%h>Տ;EMuO&m%b*W++ηl>vBЕKE[O/"kso\_\5eiתx.L_k4.ɲ BOBFxC8Xxfhl 6e? -AVRcԅ245GN3M_/T5jW*(U,ۊ oHk]6vԙld[wڋܺNvSv*fzn| Hl̉#9 +9KS-kXhaL T?dɧ5W5jjʚTvO9moL76r*yb쪚FT>TJJ~R)O۠rP^*Ղ֛7Z]o.gEMGwlSX Kde4M콒fE5y4/k/'5ZZyKwisՏ\,;n'TnU+Sٺ4<7s߭PXERUfVYvܹns#7zO5BU]1>]dn'Fܒ|ͣYZGñ3x|U9[QhY̰Y-rP9ZU|pu ׎֞P-_T!>?])V%xݰof'nb],6U/RCpwgCoc_~+ y`=fة8_&HԹ!1F +4; _:0h<dg-2Nmy1N9Wtc=#UPU(ӯQ_kxJ/YԏPz^CMXtCJB'Dlk[dY>|%RPw[^cϝ9w~:fٿaP3|&zӑ24cIZrq=N-W|J"V} T1;A%? +j*׏*߯*ϪU![u/|T_..3Qz\~8ޮv>`O8qZ\Eݏxi=zg utqlfKq9ƟZ^srU_U"}Uݞ]ox|j]ֶݷZ;oh}8[ +k(<ϪoZ]q;~@׿9'vnW{.n?-޾ jE4EҴEE[_Q +VO_䋫MP`Xx?V{~ \-r72gWq73v_MŃڝp0Oa~U.k7қ:k501c +95jgƭr^ QN\.//o1Z⅖9-BIZAGx˞^-J~1$>-S|^{/sz\%@Yc}TDžwRRk"_7Y^38Y2xFv+_ʅ/%7kK6SMvhw4/ L?f'>ߩX\_5:*J?Pdv I\8urnVc$ sֳ[/.bRkǑ=ѱ:lx6h +}_{=3ف}x4ٕg)οK\>~.FyGf c!vi\K5v= :L&gh"^- OעbRHˮע/<ʠO$[/ԝ!,Bcfn".J4Isנi!YusC*{^,oڮX,qdjP݀tCw҆3܁Lz ;-cbj }HDPuJΖvYJ;.-v^\,vсt Rzw+K=+fF{)N_|NIu7).O}t^(}oMg,VWj[A 6d,pjP\.xZc~y"yW*.2 Zez|jSo&P.s# +\. +]!Y-yau[ѝ7 ؚCgɆS[o:y'@[3`%tj>{w/YwnWR}s }ZumOj%Ux9Z{( yשt?=6Gu{JjvKBѨ̎=i+U3s@7W"׈H/4J-4 K.m~ +'Ǿлzkw۲Zj/WK/zgkN'鰹OV{ӻ{Jz,4-vS|X6poN{cE;U_Tr***k*^tFM@bv`xFPXr39:"_Q b"2"}E$a/K_[zTR=8SQPk%sY['PW}/V;lآ. x}+ȩӤLő/"wo>HիwRis'r46ŘN|I%?Ty)JFIt2LݥsDT*IͼK>'9@TRUzB%銥J=F@|Ev< wMNpl@l 9n &u!٘m8:OOTVS0~;_*˕)0UroWt9T˧sG;pT_Vq 9ZtR5kDK@L Izx?Zs@^֎hDuO@ x"A2eFhJaH(mG~衻dKG~t +1;&SC߻Pm[MuԎ]rް%g93ӛNKMbJCGCyMPͅxWT;P]+D;,DE[Lqbc:_.uP9&PMFb!ReraV-\cb +B/h)2M@n9Gpz +J]o}lq%2/d󺱿7My(Νu%=K_#ɍ=_y,\x'ZcȦUۭ$=)U|s|ͣ(3G + _6Y=0w|Q@y$C'b'r7AteUo,zxlfh=rW~TI̽OZBNLew44#[d6W5`4]6ْ\$[-m7$;c+M4r +r;ruF5賔U8̴Gh 7 +W}Se@Obq{ݳDM % NIZ1^Vbɷ__^MYsi{i]}1/VGM|zۣt7d7c7nJo2%c˞:291љ.e-+1^,t!eR3C@7*#bcHPg6a[̖GзŽ͢ +ur}x8bfȆs[+nޯ}_]zOBl%z^ A- {)?^ >?U1JakϢ߻;>n&]wp&] B⽿ft{%"{iqbbvZz؆c S}HAe EpuZ}Nq[/ef7TyGUE@K{{л~0\Cɂa+vՁ=&H8*Bo^vTy7Ao{#B/&Ԥ %9gKݐ7 /߸N{Sqk5p@ +%XDxE-/BGd͜-뱦z`}w4}ftz\F1+D/]ڣ SSӥ;^M.=;-eH)"v$$[ nsRhIC@gu%c>K2/yd6n\mqycA;+oKm{Dz>n8Ao%cw#O3w1 :/p6:z=edϮ҂^sijxtJ:t;6ݤ~r-0*:E 4Duys#S88)($KmZ9 ]R թH\[&3IM`P -&Ք=94}@Ub&##Y:ʒi\LA9Sk=d5\=v' >u} e>Hwqэ9]z ;lH qؖ+jH7CCzO|+-FtF1=n55v ~Ձ9<)챐VFev"s?'R2Rh~T$l\L%v&rȞҋJ(' L\L~=;YwZ9M|Ł`rM-' LvX- LbXGvj>#_15ρ>|ШՆ>ik>$j`L'񅽖0_wE֍~A?_o<0Azk=tjX#_{/C/(K ^+ӹ;qb }mb`ը-&LWAAwwqHϵx :W+K貱^<ԚơiMɗ MҌl5k,+ NӔ'h Ս>[ :I4(ƱBuitJ<-'q3=7W*FJ[^9' UV|xC/=e Lsׁzq}I F,<q koܸo|@_.DUNo5\ mnd宙?FHOX9mf)\%AS- ]6,rJlĦ7iMFBB>\a \\pyC\z8pa}/*~=BѰvB4jqU}6Ĵ[ 3ap~C%x hI)K!ow|o \@M z4QР +t% + NЦb 2%'o<<+PKb4HL."Q]' +~3qYڠ=y7Z[ZQ- }.ɔY>ʰ#c A4sKC%៤?9lAÞ9eg & yz\>[PWK4A۟ް4鴆҄B3Kx2jЛHEghHt c p`-!F]V13J 9&T:\G5vL;ͨzS1jj ,T[.?ROh!qFXƱvg9T$Wod#ո1CN &z880:,(d:(9JX@LXpb&5[ 9pX<X' 8GP"rٴz#6:w%:ET"OhC[s<\ypE"A :lH(e5،ؔqVvAOGN#5H%U$i[siCb[L&7O~)h3ZR&Z ۠%d5g&RžbsVd.,O829>ʓxd;'HKKpgp\m/ H8e8pL/6' W 4DRaB +\ +K]#"CD\Xѫj8@^tY$jNyI7 G | 37xr3 %좭);DL^MXB6JCIO_z$g4ֻtĖf:Dpnt`uIqa86ń0 {U툞s[ | N-C]wb +LGOМ>wb6L +-CllX'HNGeiqp-2|D텋K_ȟXzSl` +hg}cxȚ5pז __*BJd~"e]EMdGs܄6INsrTf=jC`b2OVq7n뤠VL!q?{f [{2QIo1 u".TuZrh5`t|5uX!&2^ 3VgLشxõ\^.m:|j!Y,ۆbCYb.~2;VyH6&HǶQ!V7tҹfov"Q ZVʢ^ek0j~C@&m7 3ZDr +k+ +گ8mAKSsn))-~ @[A6x\BFnpد:C{2eϥrz_4![{*38AΕ ې ~Bn%ѮzNuY.F*+zz7܍뾽º wk 5pšpز=W+_weN9A =9.bʇﳲ޻Lu'`͇A/kKWU̖ }'|%fAZWA֏Fl"ۑO3)M餍P"~ im&~}# lw.Z[J􎁭 ;fiFN y=o<ќh!C| %8`g[q^vX~QT+y#߀a]pɊfs@Ul=X-^vrQgp=_YMN4TORT`ld6\Q-nqd6XvN̵DqĘMOA++7Ԕz1hB="PlH +翄 ЦWNXz3}ix=/*+30.̂\4H`[R>A|`m==O}AKjAL qWjqm>J!u1h\ \Cy^۞ɫOuqbԹd-yj8RE; :;?k@\4_^V65!;lzɛQO+N\'i:=|iC|,0>Wk zG;`wp/yy`*q'oNTjF%jA\$ܬ:#`;aqU&,yFH@ʗy ֕J5-Kqz܊rCEL0NlX6O4ms"r[4ɕFY@6 lxK;4dgɻ%v縄Wmk#VCNȧeS3х:|d+_zǩK5ofxcb|)Y=_z#t yDwn?t-;?Kg;ɺ!pwNaқɺbysKa-\ Z!+`a䜄W \`"ʣԥmuE"AGjd6lΪOvV-p~Tl /j\`gqqzGs +^a|xh-sJl^ 1&Z9Y |&&[,%ZqUW4IiNh-Y/ey8gJ(bF 3љ3\n8h{stFׁ C[(yb(;Ś `g)X<1n 8$5YDOvVdXe~dYierψ]D5TY"B<2=bMgq<7Xf57m5HihfpMmI4x̟{Ic7НW/eӀ)f%+BEgjÚ>g ` 1Yt QVVh\!?`19R6DM"!l'ú|agTɋ:M6a./Jql(MYR^FdgM5"@% +I=VґEǂ7SNwXu ֳ!i5ƐqyIGsk +'콁RY7{BN +k"]y\!lBؿlڦqtx&a9Ib쬾{n}oXKVh,֙ YKY,%C4!(&0wA_r ҎɄgfo>p"!<{ aogl6>xyE4&>5;)zϻW#˫7g=3o=D# X` klgM;frS4X{^DBzT|Ԏ(#`bgpMA.)$VCQ?%UFk(rk͔ۦr6S j а=P{[.<a$, ,l;~]Vk"O/SfF!"IHԒ% .쓅@Y;Y|Uwe)lQ!<s@N܄Ogb a$TἣxquMYf- ju}Ͱb6@&B̀vr]G"=3鮋up&쬂N`gi\'E;A7",𓁝U:R+;+OvV68Fpm)y;/f ߀X`*|B^X$q[\\YM\ ; 4tdgeJQv־SԪR*T >;^"eaϼoMD38\e&o(4kt\ՕBj2`0؟Cj>8/Š%GTA +.WkV|ǵKXzZlyA01L-:t,X_+m!o//i$ˆo;W򹃢<`Wʒ +aqX7Qp9>w ܘn[2q]tp|  -އ.FK ޶&Sp+!{eIP=` /X]_t\[,', fC_k_8`Z,Ys>=Y>9vV(;Kht)y~9ފcӚav) wUTb`*aW ϐ\o=pmKj{o +w=mp>$9>_aFk š|}"1̅pEj#󄮫-!OIBLC3aG\bTyl"ƔBicB֙JGl9WXL,!# lKs~a'p$߇LVyh3*7}B=JbV+`V>KK /(0PY B3۸F|pl /'pyb;no><4(n|p&%ܿ"I7z¿3KHVi%4_8s w**[9>e4Y,N\yɤ;Cp= +|%>|7΀n|tXYf<,n1*׫8& !nq~).Fqn(ERQc ?b~%p=9FJ+l-`a՝l##}(.:N X[p=e .? kZ e.<0QȽ^`RuOmC/tY!a]T#/38Ԋ>÷-<잌57k2] |ϧ1:\X,y +Tx,x,: XC w"Ls`✏ufB⭖O-av8!a ǜdg|Yٰ + !g&ѐ#gST̒^3JlɫZ&.@WK'A>1_/ϗlܭ&  xyM!!j`Wl5 +sssERAr `@0V3'Źp n>d ;7UTLN&`;x,}@Xy9rdG@\&P5<Ң4nrqi3p)~]3%m^Y۱E\|9GOφkj:ʷ]|lE=0!q{ՙzzQ<crY:g>!)5MXch|\3z?E~$P@ $cumc_3Yid#$!X + +=[![ػ +>/en57䑄VcL >s)c$> ΄'  [pna6ڄtš CaGO#+`:;c |J"A\-a[?_9!2>O~(a3ȽRMQѱ8߆m=XtWrkLNvmr?l>2;7_(LR!{oFz-\l.9rn3'؊NNd'_#_/} m 80G`&VMx|<>x|<>x|<>x|<>x|<>3<"ֆp3\}KB7F^6&<5&1!4%~>kmmC"S/mg`6.f$24nEmmD)11 и?]N_x˜?v\>ŋlNj?"qk3`  lfpBHK<[$\l8/k#c#x?.@fCNw!Ϟ|a??͢em-w~S 3fOlh2GGۇE'E51!L]DԼV|dHBSFjC#MEiK"ҵduWZx(U T&RꞾZ=Ċu ZAIt|.BW' F0OTM*l$$S/(oy_%(V؝B&QcAD]7ԊE]\Bo\t; FY +:1eS:!dMtFI\.’ʆ #DŽ|]>gȒ@* =t+DmV&*R GT"M(hY:(݄1GhJl6N&&MN!1@$J5A'~,>l]y^zlEBǨiZ@νj tخïp=S6kYΩ|A$6ҐKm?o2᳚L袱A Pl +ZFV Tk]E['A';A!ꠌ(VD6(0ĒP5?ڒ8/C@2tJe>&_SoPX돠]٘ +]:J +n(B\R܆d yPtfi F\|>%!HTyC@>I5YE&-__/ԗU.h"m2>_em~P1Pdԙ2#Qʪ62t myN$|}-eHQJvItAQPoc2uQ5)`<EJ" +ÆCP`C7h (01lxQ-R +R +:|RCYTQ*jn+yfˮ۠ \ >E&kڃ,Fzt+͕h7 |]s%"!zYf!LlS^?(^_\.t\ |J\/U@S=Cm4PQ $<]e]n(§Ug%]$ǍtEiy}||XTt>IX<!IbXj!֫ +(Џ(4ZLdjbZ@i>(rc󆍯=x1Fe|Э̧%:RE(R@,X!.ѮjP5V\'iH؏'j֗3'(Rjyz,BUfכ吭 |f%j%GP18eZSyj1t d& +'@#taC, _WP:E{/Vl3[NTTA7|>vb}&tɀ]T2暼btP%aSV,iK  .+2#Εd!BN qCTKMo2 WA >+c :g}2]nv)BMmћAJD '1)Z"JQ +]DkB׳BA\:ꀢ-7(˃1!Z s HGSb)̵88r}Yz ( ]RAgq2蘉.֥C5A(K /!uYJ82ʭӁnDyU-t,b}$O|tXH;g.iPn<ǰ?&]Xfw l1pm_S#e8@/6SgS 5F2@n#Ԟv\w?[@T! Op]VMWzCt,Lp^h:ɵ+>:AAy2ix\pQuttUwu~D*Px8D}ئ]37!y> 6:fASp.$$A)QAR= |Q2ygc!PPE%lvg!]8qgx?,P% ʑElҭmTH|%yd&@? +j'D,p%VD#ܐ_r8G P|.f:*X)|ñyy̥. cm+H# +*/e'UOw%wLx|mAEi<9>(y5Ankkp y" Q9? "q$"~ؖ $ٌtq㼅!C8\7\NEPIl90_`N**;*O(3fA1>0w@r8lk$΁RvD3\3i@xQZN&>,k1!$6σ,mc j}53t)\0!jy!|668u lN3Yq.#><fPSjeR!?dCc5$M*"Yă ,mPC G4amM(cB4P4Dl:cPOu4@: jz +0Ÿ-cyZ@C{$ Xt߽[_j_==_: +&QX{mmspĜb;uD11sPə&gE$ f'8*f=߽߹t3ҵj]FL91М6&Z.$o5w*p< "q7 v +Ѫ (?11Ǒңgڟ|R@ +kc4 @qZvcKP +RHB*φO",p'!=J|sb5@< +{رn1/5EPrg k (pg =X׀ vBW +!+.thzC +8% *J +{WQb==96Mc^߇8/"w (ۿNPq6JA9Sj3!PUL{i1RWcNc&@bDQ?݇ |T) eP>n0C1;1H^-w\`4@":p1J1{WH]ň/] Ǚ +X@ =yn "z7֣۠[NIqړ5~&`Qߠq@ip?KxPPu[}ƃJ-q𽲐_Rcf(, WTt +J9tRVzto3O,o&::En;qv} y }FBwjp$DYυc>d; q&x#Ұst)#\Ulj5I2-P*W+y-Nx)QJK~♮F1~HrpAQ&" XƆ~)y?Q?pf( pN̟@Mb[@v{]8~ZNjN>ĝ +'Z|,`,e;PvX.>8\υyąCam#PޤV*P%Nǰ)RJc ws,`=Zrc QJ/\O]h@`"dC'3T,qkEa8A9(DE>Ԑ.\YDI5 @.*bZ +epNhү4+Cſ i>Q~e=/!dD(u6(5r:!9[_\UXP'6~1O4|o9S<.aiQX?A^;Oe#R4IŞO99ij$qZLB:z+Y(=J2Ezs98]QN6Px9\ox(q3Q;sX b``q1~~w,1 Tn.`B/,QLfm׉~or~\|m'hQe 1P#aE~d#^Cj8q>sHSC@֦xAБV2Wی$wt{=P qXa b@t⟃Cޒ9F" +sMI:$U #eNrO ʚa^[`GǂFfgyxէ&p>5,HgC^`ÚKcBf>b4~2̱ѐӠv-9{,ki%qN3p:c19TDRҸZmp q@՜kpb^QyD[X3pJѥ۶5N\%=~8QVzo3IM<9I"a,GDpt& s%P) &v븣cH}_r| ܍8*`~e(ӓGX'n鳥Ѫ[axnI's.Ib ԙD]ƹeGGCگUꞦ9 ǡ&KY BCGd7?8.)^Ft8x +-q8O7?pW!?p0lnn"' G ,枠 +kӁH{H 5V:󿻸?~*z'0Jo-=Kb)N0/clCTk^b PK傞 .#G= ۈD 6Έ䏳!CffRDs0)Tprqگhd .H1'gl\ȘlX +p+cb*r=8F+]'̀z1xzfdx YBVt;-s[(vBL7 8+u" H|X SjJMwp@.<6B= ,Fp&N5`PDzPĘ+"8ko.6iQi[A m=}!\]H B bLLeHB'-uIӤ6sXWC%~ Q@%x(.d-T+?_뒝8(U ԯ0|z(x;?%GRvg4An C\PHD +8\ugx~6`<@8B"~7JmIZ>H~RC:N|n0Ruw99u#hPvω<#qz]KQG%JdRڵHRا)Q+%q(\8<=6pep:J)p!z)212C!.sN=do݉=j3{n=,wUY8gBc'1 p^PB=/6k=ܰ T-Cp4q0`!}Cກ5O;;5 "_m k%98uA=MIb_l!q0':+jV\p&($œBl`V+O!}Tx5eU\F(C܆)s%i;eB6Sb._A}^O7&x#q[X Q%pD@CGlYB q/7Sʴy-En0$5 !i"Mi]2S.-2G0l5yAyk,9a6 x9ԏNPCڜ*;z~ UAe8KaN  S ݯc92~(N&JfAjXB&|"j8kwj04]Rdž篓FjvIrbk\Ko'n!9KaPt Pq'Ϗښ'Ξ`)s.P6%CCgB&z8suq.*X$ir5OkOlP3<\^m2_j4W)kJ4dYeqrNLbUkP$A@/{г %n5; $-tVuA;9z<>!}r`H1/8%熠e$\&TxAxs$n'ks)%LJ&/ԞлTBf:`%{.g>x)Qw$we>`:͡x<3r1%[ +M9x,O7 Gd,3~&qw(Q_v +5⼆y*QƯsZ\j')Z3pG;:ڥuӯN$Δ[)ImcB VuCzBTPK|9z5mQ݂ZgY$P |Kbk PQgRa`An"| j;xg182i:$kp I37]ۇ@=5` gs9 Q\zp{׈*}s8AWyUyXD?]9[5_Ui}3 o5Lz?혿]89LǠ~"Q>}8$y_g9sT!?rStX8+ {MFM'A0Q{N rQC1ƊP{{<,>ֈ813{@=j:*v?<0;.e Yn| SAzCP +Rd5r.aG >9x Q(Nq j2R+|/ aWb9ps$13*_ j&>Ob;pb_. g   +=k*٫(%crOņ^NUn3c&~'"3qjz9j>I3~1QgHܣ^ ud0w)8|.&g8]s<:k8X}w9_YgÜa8|Wླྀ GN !ZL7u%a:='y9tv(9Ꜭ +=Z>Ip=VLf]:[8h-S*G=F~2aGFHq>$J伄'j/ |#0g q-qsx/Y+g߀^ҠUe0г^=q:&/^g|1ԅgc/C ?3Ƒ8 +Hk5ro%q +z:Rg2סJ_O l;*QŧƳGG{8f+8!H +.m8R)PW!cr ߃ 8`][ ·3 sy٬ PL3] YAJ((|ԥހz zę=F ~8/yY/@jp*Xdu7OPS5w %Ӊ+}=0}#6l"qqM{yīzx9m8E:@z$8 5cpj`p-e.]{0W 99OW'8…<[ BN% $ +aր*q-P'}9+!.q8N\sL."&)"3w.6h2fBPԴzRLH*/T|FqF ѵNB}=p{S6㜥q\?swpaV(8L_7612fU82;poINvia:B|3l5٨C&ub18z#z^qI >^.3 qw8 18(+ y^,fL +G;%MaܳgR%k+v2zLWr~/Yyw1s!iѧJ5=.}p.e/vq1o6[K'?0*fq\Jr-mU&ٕVFY$ęTDs+Ī-P?]2褪-C8'\;#6!֣&n <Ĺ& @SQ1%.?XhӁ&5i#8:^_LjE+suhxN]|Nkd4d53J +7ީMN`]өmpvހ$h;JֽM߲>{~Xi/{_[Ff#Z(IN%wCWѡoVR1Y5N,,b22[+ 5` ;w[.4s>ܼ]z%}(Lrŝ02!Vr⾖PAzZ,|L{ +!( } οj$i]Pbݙ-sqy&;,v^G~MF͊f#z]2ޚi(zwm̔?k'/+W;v0$^i!JYRN6q=a^GK٤M&sK$UWh9pEK2੖?̘'3Ч^m3es9,<+~j#Fә}tbfMjʲx}ԭ&쵏>sVr%;MRYnngE?KUXm-Tz~hšcC^u kԡ+bZqVMjZ~\^֥S5!qi8%5j@ςJ{Ae.ܣ\4n?7?zn8G>In. <[8N.״,enw,XՄz>%X\rJZRhiGonUMl{}xo\xZ$`|D?(tɸ^]ǂ]W,Vm֧$B-_ʟt˥$Zv5H2L.p.^Du_$>-Z'Io3gRY_D߶ +~h)A#Pޚ@qoQ-ѓ.Pb}Aw`ˎ}d:J_wHOHn57-rKzgkuN#Jl$!VwStlFAXl㐙RFkUrLZkbsY i<9 {VXtw#W.~z\y}-gp'm\~6U^8~=o_t'+󘬵䂬ԑ}Ί^d}Ч[R?ig{mRinwcZ vmqf~^XG7YF9sX|m?n}5n}4殷RtNIzL=ܛc\iΣllE id!7O%w"~H|I7fO;},z߆K?cjކ|kg_v?3a8:DO^=M1.*AX2kseWegl<;#e/^Gf(z1¬_D1o$͔Wv%޾+v>>$(dr[xޫ1 Q\zQ/fT7k@@w~/O~מl_$@KVѦ4OY`\x鹘}tonҞZvo535g<ƾ`=G};֧){p̲E4S*}`k\$-irl:,)jYVXa'+t?'ytJu1i^ y cY^eǥq̳0عIw z?txsgGY" t6\4]v50-aIb#*yQW2Ԧ^ScSK^6^dB^j+ 9ɓzeJsn[VZ[ܪbJN{l#ɯ?*}V{DeA5u1uO=o;Jj: #xJ⾎q{zH|>j[E%8Tf:bw胭5ŝK;]8ѐ{%Kaї~x%P:A1Ny\3.@l%r{2,:[aeּH=폣wW6: +[嵄Of v; 66@ c$q6KSkmBqFҩ-|!q7hsIN/ߞ(h&,8õ5xj͊k.&᭷¯?Qd^XXIdV[bרcM)2ntDo#6x`]Oعz8eꓲ?vPo "*|c-~6O= 7{H;.z% ` +>Yn&zEoZ-Dn0';*$U%9^Zcٷ o9lQ^!+)w?|o%u(hj +JVSㄽO%w>J"N7$&z&y&&Wʚ3'zDׇ^QU~%7|"_T@ٺ]Ep{1ŽG'}Vd^U>nbM撏 ~M5]N:t=Y^}>((LTc?Uy3giZ:K7I޴H뙂m~uaێc_zь~g$[-);aYo͸mM<՘STTQy)"6Lpa}XACXqmHEmH .1<9"=*7X}ZEI_uH‡!{󛐽-o%ьM#w1Ӳ qGK[*TnYvWDN' (I~!yבuRO6e^D!.$f_筸ף#bB+" k +mC_4؆_jBjBW:F}ZH/uW$y(|*bMKxYX"e^K|O"%i-}t²Ӳ0Ъ(B(Oأ-jIj8--9kYuw@kUdUKa8 u7abz/nTCrʡI݅8E[EHօQ7*jbcj<5g&z߆po{6&xոE^t +ǭ +x:F>+r}\䢸U[u-;J9@#<'o=,-U9ވ,:׵¯/ڳ,4֭246+&?xf +p| +*-N/R8FZ~!~otW׼KX8ۇnTfVek~Ѧ#'/ ̀y +kUen# +mR띣v݊r7{7aw e`ʈ؀ 1ŞQ^QQ뒣NԥDhʊl8R!D!P'n O~cXu13hSVwbvu?qcvlw[e +mA{wU{ĺE\;g74LIMW.;v\ mPt^4?i[祆̰+V}|q1nFQ zEMUo':WEDO(oMuUܸ6Im>D$ʈD؄k]#lp~+- *̉9ݔ_Vx53,j,ܦ+7pkVؘ:XZ&?#AP[&w>l4 +b_k :Rt?&#k>%/Fش_`{O{p5oUx[N97_=k7^{:p) WKd~SXYv!}ďBjcDtoS{;+.ջ6 }XS,^(^ëHaﯧ &NcSayRiP6l7@k7mCZhڭh&Zn4(:dmn-Kisu) H~^qWTx"6WV}c Zob\Z⛐'6"2Xy†^x۰-7lù?3m(AKT쁓L4 h~VLo }CyQʓXih@5:t>RV]-@̎'|o6Ţ?NѯןYzS9usx~Cأ7Ie%>+=*B^ s\LѻERezbφ5 {(aPϛeN .5v=0A9_gpdS;_SU[fO&cFh$ +Ԕ'Њhe'#?m̾GvOC$ݝ.iW[wcUſJ3ŨoŃ"ȗo/yDxkᩥrӁ|/vIp=%7W:mJڤWCK-D:VǕ/O6̘^yL54FC4 $3#R&ύğ?ZVʹҎqOg䳀'QQoEWxG]4-27- [xo,r[1BE@"ȺIlXE̋5 s1煗y+7ݢ\K"gcsf=!wN-3ƨM2͞mE+t;O)n~x5gѯ{Ds +y^\Tv^QyWs׈/+JscҊhw9%r:y +q0~}{p?G: +MAEUv"u4%:^lu?0="Oq9# +T2{EQ[#neUۆc]X랜H/ZgC̘:ď_x|܃ɕp90&]o<61HLiz"=:֧FUy$-psXW#kBusnx}*+ +}x* 4j[]\~549?8'_f-Egi‭ ϼ͞瓞*n<~#u{BiGJIkғH粈(xxE]FA od82y2|m8~u7` +<0?M48V [LމkM^Wp.D|9!ʭ,4Z$YСƋ8D=±25/ZPx6朶M +ݴw7A%V اpT1 ^M܄N؀T&GǯCGD@G,G&kwY;~+/6;*羖WM޸vbo[zwKJSSBIK"e782H g2?ΟJq,& \& Y& [&\@bVs։S6t3[^>\ܛ<زW e.o +\c_r-*o\wv+xz,MIdCIc< y>a-RMU݆A3昡sh\32]MTha({^ WlU{Lxsm5i.)uɯK\0 Ӯ[^cEd W+c&*D CI#ⱭFפ P?fmwFL".-*GJ[B~Q¯bΞ)Hz*0-^xl޺(WRh-q,sm-w{}*>B5yi CTcD(GT-݈8nE'oC3gShΚh6[4WvC35 {Z(@+-.*mm_dwr(93/" Ok_z)3ƞj-<ԑ!%Ӽϛ:uſg8PñR8xEN"ks4o2b0b1v1<9HmR[nf:nuEsM",znyMڞzJ }uWd wE[qkbwvj{K=#t^&Y?%XxxMs8<&*TƬ s2CAC4 ßVO+YSLHeRTVZ3DR^R?je~F9Z_oC6 /SciF*:k?:&uU;C-)R7ߚ7c4 F#!,5}<M4u6h?13TnAӧmC3T4lS4cfޏ긣b_jҡBoz%ǴjNTgAey_z(%w> b~Q}a-i/2j86C ʂ = 4yR4ylb][4o5Hf܊fx9}2Nۀ1)AVJ|hI ZĢ+m>?M~o7ۘv={͌q7pCVlI//i`(ʭ&">.4+jgO2:?m0("?F?| r8z:Ӂ[C{&mx/<_%oS7EvO9n[ȍg W6N+_2ğ0)|!>pr)q()v o|WT%vg. Xet:n9-;vhMZ;p[z芳p~6hOuM#֍\fmސM^壶?mh\h5MzuȨ5b왪,0,]+bL3oj"21MC|f[uD $h3uB3`qAKsh$9xEy}P-TW!m?SyG xʠn%6OЊ㓝Ns_ += x΀FQ B +ҷ0w<(oZ\?%[q>[seU'༓I!o) P?=N?tOj4k%k ҝђ4ZT-\:0`C6ߞٺA-on[Q_ش] |~sN훭fۙRΥW%i1y+Q}QƉ{W徻qusc[Sg+xD?p-^!%!^AIfVS7֥6=>0b.>][cVF)/vB%f+~^`Yk?,NGIg^`}w:;y˝# 6* n?6^"Ǜ3n[m{!-`D3c>8 {J]GfiJ1wfx~RY/b{?bћRx6F~{ &R~Nc;Ϯ&"25"#ҭ*(BP }ί׻ǯY6VNG鷪 ˻xMJZk6 ]Q9F*A JpQUz$l5w8ςx^%tT1 t>jT8 c1 ub"IiKP;>;'~a=5`׳VUYWii ϮLeU4v 4~,̣סY +c;ϗr?iW~2ߺéÍu2?} n{/J辁?l=H;Ǩ7w6xs Nfn/ ]ͮmu凾Xh.AlxEaY5WtHyV6ѕo:Tf6}风]tޗ]Oy?g`1猥+Dh#7@٘G^n?a[x-5y̓}6h!ɱv4q=ޜj;WAs7-a|4}6 46c.>u&fℲQCD' Rf0+L/ S>l=?6nщ[OYSגL\XeצA ֋yME4R:~\#G'[U߳q^LM=ԋߤl#ҚOYI+'&j"M+dė5{=7+gF}ТTV.sG(Z'ry'$KŖlȬe䯊,K +Oksڤٱ-^'6dHM8rEh1!;K FgsFج4MF{YBd.DeHk\e&F~4it!VF篢O!ϳ{șk%+NntaV3k[yJRxmbWi[ҸP<~t nٗ5H`ݳ?32Cq +K:5b:W`z1cq[hjӑhup{IMoa^; "@xWQ"'Th|f)9?tSD΃֧D{4|Xv" (ޮٲ p!JI$Rb< c +V cW 1׈^2ٻMLU^ź'Ϡ/U()w.{`Q\*˫:%A#&>?3sgSY(/LIЄ`p)r-0xϳtﯮEl*D;8n0Tl:*(w!wk{Izuf.9O{0 L|:rQGmYv#}_ o,7w-Gta|֢ײu$Oʟ~;Of4݅/eťg8q;4 +{4|/.4ІyKжkv-d)V}eI ;M^msuTn'&:6Ϟ\o7st1kDqWn$._E'PG1}FTv | "Ӵ.u\^6$FW7¯7&RAod74y3(Q&ǔwU6CDׯG&}f0{u$hhvuJNkK^E@|˜Uأ#YITrV7qSLX({VvhWSiTtlCx\ݲ28)Ɓ+4md|fNg,6q˜h1 hHta{D]oF7j7ܓ.H~i܋^շV$%zb9*<є]x&(g1"K7{Sҽ,vkķn%ma>Oɛ +Z7Q!/|32/2e[y3ֿ1kd1HCɐ쬲tXC ں^!=M}t-ۺߋF|TIWimَuLДF іs./{dap#wV>wR"ɴץD5EE3GF.)k:fȽ. *p?3ul#a힢*5,v٭WjǕ4اnrFe yS } fms{iؖ5f1D DgBǙ T߈[TGFx]½l';;ة+N}ɝjnĈ7}*2-~:g>sN8x?:>J6n)yU}Y M[QCxv{+l9.k9$}hh n=\Tynǽoj1Q,5vUn0ǕL&5H+ ,4(imox>7V١Ƅ[:6P~:`4qZN:DSVؼ4 7*e.m\=J z܅s@S#7d$*dO2..i1Ԗ-k[]tSD5v)i͙aofLЗUҥ 0:(ҧvV:ZK2M¼iH{dlhJtME(AesXɞCh4(y>OSTJnS<ϻ-TnPp.W"vcjqe/{T{쵻m3[f]}4\=^Te.Z2j&tX$o?Xx~ԞS5m8~nSDبc#V6J+G >7xFY(>|fh%/כIoK[O*m8^^ԩـqb&V[u#w-d.=hǍLdz&"\|%ts h +E+ 3<#<;N[󅵛umi'2Y + [;3|";jZ:Vm[,IpO½e\lV Ebˣ"1b-B8=V>IyMRce0¸[7FG-E*̧) H !5I$(b% ̂*܈ygaߎ7G?c}/o| +C羝[?E6{'y<9ƝX3ʷ`iiTTa|mg:r1ƍ58:׾k_8܊ؿ lzobHojU@Vd}\_=o/n<9 ]ok-x}Y?܏ƚ]_ugyw5^}7ӻ八^_&U?^鳣%5+K&Lv%SL)Q9dʭ>mN[Uz[uIucOs1 <1_8[J<0fm(O^xٵ}F l::6r+̧Ն^&Uޣ1O3a_GmN?4l}{gW4'?syu]ëCw 4a0o۶3k/b]]2Y(/~s%Mw O޴ÿ a:WX+S/|+w^g1KhcW9Rf&LS1ͷ{/Ƌ,r.[bov Cq}eo:럺·܏&/»/.uJКۗ .4jm|n[3 +co_2aG߼O ,?pI`+}*"a_+.󧶜cә{Nؑύ< os7.<[ 7^&C?lſj~*Vx]oYr)o)#C=1->׶ab4-5:xcLZh]]22lZ;kd݇ `2z__?-' Ϲ<= Y~jO*w/[o}5/̿Uƣc+w]ҵ9.OXx:{7yf/w{,~%/vce \_n7|qņȐuOPNbѩ3f`v=Ek-Z߮7''|sp՞Kwn\Uk÷t/@=XESN-+bI._rH_r(G{ss UyKG9iЖ;|mkΘm2]_m]=*b%8^OGL>r9_1N*0=İog^xZ G]qPoxgyg]jmyц> Ϗc<Xkh9{pns7v]smCM+* vl>;ȕ2@wFwVz +=$Ճ1[]cc`Oq{bip}sB`r豏o=;x~ɿ{ϳok}裏}ur-]W/BUY\߳LcM+Ir. /]ubϦW,|\EcoCq#?y5cuj-gS;w11C]W{sC}Ƹ0_6D=O cyLXt gWĿ,e.{Ws ~Nu;֕@c^\By@#C];FVy\}2Ut9{ޓ0ü c = ck_F"/}^|S73N(нόl8`XO{sO=3Os7q` I<#1hx˔b9ˠO9ychx[]S2a(|_4³`i -/]3dMK*J }fdV >h1caLW_45 c(~c) +~os{ %o#X]yC9Uᖡs !% ,soᦳ[(9>(X}h QfWJ| w Eড়Z"̉ZyЂ`# 4-zS( o&VC1َ9;1w_O< ?Ygw?aņcԳgBq-7TKw @{}OCOm}z]}Oifo}o9/4#ɖ;cxeuM sfgԔ\oǸ\*O8u=t>{7T8#x6}O +}f3f|~p?Y=0&-1o*L/9߲~s8.I96p\Vxw\BkϬwEXR5{.żOcc.7̷o,QUD6<7I?s9p7e~;{˛w:9eS|}s8q)òя~T_0gkpKvu\X{ #:jc9{7׿07K"/YscmxsļUyC0bsy!Hb໚ܡ)1V[^q֭{`6^On_.XȨ_1ugb;e:gMScYhG" [N aLѽ _VxnCc0,ZʹS.% yi|t[xP.;֟Yk7_ccHʃ Rbq|;~~cq(dvO}iOnNOfyj2FW7bAG"6m/^?c׮=|z祫}-p7.~/ ~𪧯mYDv/]4Dr[b^>ȣOȦWG W+:?c\G`^>ף_ΌlzÁqq 71<ұ,BOfp68Ϙ{``߾oo%_ë >Ջ_}[j־gYw#9p.p180v +=1SA}ompԋ7-`e#qE:V +zcb\nʝG>|s̝5oƅ0'8X0q&מY_5 +sPLنE#vSW0>7XlÍyf|: sPngR5O\Upno]q&T s*-wxW{};;˃?֏W7xѿ˛AQyqyZ+_76U>7 1'.-q.+n}z8^C`^=Y9Bc\̉i4G1"Q1"|<׳(w:;^̝]۪]1ckSsgFՀȁk#ߐ?oܵm4 \).\?ԉ͂>*CG+Fʍ8BW,ocrrI:R˝uoŹ-wpCK|e; %ofZΪ0/u Ai?Ҿ\P֮~2gvv QwJ|o\ȺWbmهj~׆m=>cg}Z_0,xTt'J0̕p>׼fyC%UYpIuy8=)A?gЖ %7Ω̪Tή)=v׭} +̃~96E8w@`7<;cYuFpYqd~(%~̝([+G޵eo>:~7evy1wG`|o̿6 ]K0#4>iB`-\GS%WEᖕ(?YT^E~_N瞂} -T'u*>3[kshGD֋sw]]򵘯ssϜ)9Sv "|ɮByd.2[y,ו; c'FYY#(wֳ7Hdžݞl;Ƶڥ;/k^U߱[? )_M|0/ Ų||ׅ;U{߻!té}9i. /sxwX1c^PhyİKO߀6X|Y%;O>)؟f}= @0Vk^~jýէip~ sP~E>gܽw=s]xOM/^+mb8qޤv~[X%?Ox>#⬽k#+]80yS +_5w%j;F:Ή)}lM}?"M tbC=MCQw1l=sZdNMÐ@#j[6mmb_.rY*u`jÙ S CqP.wHkgN00HoQvH`+VuyQ0O`k712EW-ȟv+E23z OKW5 '6^ 'sgQrg3uͷί]g ٚ 1g C ;t_wt\dBwdkk.ϩ[tl|pe;G^av[{:ӈ<"8-G~!R~'C{߻)໓N F9wyP# N]yto*rܹ||ͩ-F8ohp^l0s{.]V97B랸Ϙbü[qO >]⮩+7/9cп8/no +o<<[%I _ ss9eq.*071sm!=hb`\>@|Ho02? G^Ig ,YhOy\8|k#kykWےѫk}َ|O}Mkp:t@~;Uґ?}=g0? +p29;37MO^C91-|dny~/D^%+*{~).7YQ}ZhK֞Cv]\\fք@-xx}"? S +ɼp57tg>C{& PebqYo>~w7vX@|dl3$m;mVd %|O/]߿We(Sim:;^ԱX?{2p.noWr".}B̩8ژyY6\j53#|3p f VI9@Gm]D E64!ص'"вp汄Q~Ũ'Ø>y( 9(pKlZG^90_hPjپP~\;GYNx? saWEs@uя& UB]{vߡ/"O~<1VOn:\#zk11ޣ|¼ˇ>ѳײo,,݁cLoZ;쁋yed;65S~ + +m X B`pզ'E} ~ w$\75*8w貵ټ{)a^s} ;bm{vw{{dzIJ352q䕡C[zU\`<2':P`pےQ gm9/0Ȩ}<Lo@9旮YS2-A;}wh'zkx6غd$6W ZA}u̧ ي;2nvzqxCHʛ޹\s?hdJpɮ13R>htj"# ء8ƃ^S>Gy0W,γ /ڭ>"A80؏hD uO bayΡR0?[f9:bq/z=O](_-<$]c^G7?swż "hvH/myN9=$>Xo\ڄ]ў#p#rlmykM8;x쏳Gks!hAߍ<=&x܃ gRi\:)~)~)~)~)~)~)~)~)~)~NgܸMSfp_mJgXo'[.$fUzgLMvRz~mm| Y QmkbфmR ~Ust7F1Wj\No\`  +&p, XTQI`y9. kzHTghU'Rdku*ok+etvdܾ Dhle{% +?١YxCgG f<8/hJZw6qFkF0q:MMz[?0Tϝq[-0E{|iQceԧdXcGy W\lf7x2ieղeyz*&x~G:ҟ&D5]9~sELvt:ƘUR(E-RC{O?c՚tw;{N'Y&ieuN*v شTNf댜Q1Dδa*ޙ'*B-Uх9𣹈 C㴿{mdR1Eqb8} o+*wVZ%KE;)+w3͋7ZjOE-a윌vl Ěm.`>Tt.`7]ͩ(؍x{ ,0'\R@m|@˲}U,%~9T> 8F居{^)h ɠuHAlw4M-GA98FBd#d`G;^y2 l\d],6 \u4>v=;7Ej询*q@[w6&ԤEzuq ++a}Q}r;TE#j} e\-F~ΚTs1n`Z~G[K}>_,kJ%d \O!T܋frGS:oeUܪƨTm³ U4sQ%*w)",kLE_hu` e3"L^gVD:[.<M;:/,HB Ǐ}VPsV,57,<(W8䵣'u"Lb%w`|f891hW1'SѦx1=ϠsrMDC宷YTۼd"9ײ eJAw*t Viy$fkՐecaY}#@]p,Œ`ݸ.myw]ɺ-TQ,OV̋X"֘ۓ]Y|w_.HȤs;r1@g-rxy5rQQ:ooKDc-֎YѶI-Qrr!JN-I5]Y]xY*ї[|}օx + B)sqxsn#sq*C\fsR\L.R\sלk5n*9לk鹉wNA;u"%suF >jbonlU$[i.ܳnYw΍I ;r*yf|_#"_Eq +y c +.ӣlT,:jlr)>79ya>stream +ԺP[ /0L8cRX6 1&ENȠ>[6FH1pbf <m +(mwtMaR+a}\}L璳PDNHJviȈ7K|;BdVTwW fD711VYmѼM&v j0XO[v<ho̾af~G>Ts1wrL?\(8׬ye!Z`KMNЦ/D92&$ҙr|#Ee SkJPe.')ZEU& 9`yXN]ܖlK`-`DPT +z*O'xrpAzk9އ+Ϊ3MVbA/GpeDK!, zyҌ=K&3" qD:mޠg4!SF!)AgB^Z|ab$(*H>`:g ޔ~}Z* ESȱZP" S+be>ƴP J's"7x, 0`>7 bE\!E&ݲAEI<)W8ugF1[s, +E<n(|&Pc=Gv!}2 +Ǟ 4RA7R<_#`0,&5 \ ƚ*i~" <1V>U€Tz>/Ihi8 +K$N *woҥPx@6%ո~jk +ABg'[ + +cW屹Vۨ^ҐL/kjM.LP:meXN㫪]rx(3 ۜyʬ "+*[zdc8xD)2 g,("+%;9RcsP nnZdcYpքM);5eDEAnB ڠsntWW7eVIƙ D\#L:Ŭ  ev +0@ZJEu@8]$BrDڂlQ;+ b>B6 cl2@%ؑY0&f.MfnL6iLDt|ώ4{\XpR5ິwhǀGHPsx'"Q^AK cyV"X&-P N;Wƒ4=oRe`Sƫd2L+dO7)nzK]莜u㔕wvt$[ K'(8Ew=8N|-It2{qt~U~+uʨFR 7b6kS +EB g4JtO6k`֦7TjuM}cj9[N@c` ~A AX*y8\) qh-;YTʈELAt +dӋdS覾NUt*nJJ + 87榢M7:fLg[R4LH\4X((OUB݃EZǜMFMl ^0,38$amq/)oWO0r"֕\ ` Zo)NG{Z<^ػ23djlfW,˳28*Q DiO8ڸ1sy$lY/$J ֙$IL={7R9)1ȍ] N2!`~m"0:'U3'EWbM[E4dA˴+~(s"{XM|A ȜA[<ӗI$4fV~bq3r#555T~GOkpA<!12 XrB_™eV~bq31AɄs`T +3Cq8{S=H˺3Vߐ6T~N粬88Eq0`i_y8WѝI ;+^pݦ73k88Eq0`lPPDq/8ӺhzmnQ n[ff+7XE=p_y3Lze Fr IJim=Ѽ>'Ѫp`I9).Wuэd=punZ&ZUN,֦f)S9ItW3̈́87z7!rM)ȓh)U Aak1ԣwaF[[\3]<> :݋Yk!VHCpy'EOtas镧[ '^O[CnqVU6eJʿy' +n+R5)!N^mp 朾p,2NA%[Ah(:!f#D_a\&=Zim҃ѾXmQcxc3vjk^Uq{`g*)Mp)ȱ<=CR) l<GZ^s1r0W.'igm +qG*֔\t܍Ǝ,'6]3ڦkp۾@Z :O&Lkxf)HtWOhRE᪫KH߅T+Y06 Q3y<^:& @%. 9 a՚I2ܧ-ԷM쨉5&SM N9qmw\N1y+fLW9j"+6%be3\wGW"VoZyj<}iqq&&١>TYhB+)':ao;0\40`YXӀaArbP9LCY'`h",*|ȫcr氨(Ǝѐ*հuVqʤm%}j2f^Ӳ5k] ON-]E#.0\(pLt'&6'~Vxƕ:FrҏȕXm"ي/ʓɵ=X Epdʧ,!f,]e,Qi-3uDEʛq@2Ҷ[) A|I`4IB1bɟ49.]-25$7䜠2Hq˧pD'sV_Jq86E#j'5H,~ ^Ji> QO"nN3<",<:iS8 #@8}-4¨RD '\"=YuޱD|!/2 WBO>ߛy_ø@,4 .2LWA/(E^Qqt亀H4*ҌC'X0I؞2_eaedF)8xDq1Zdc\ݦn (EF7( $톆qM"C-S.[`6: Z<,Al|FS؜qԖ)ю$Tqzw{hx%>(@VMlLZ&KeֹdI WT7s)V#V.5e,T$mm`eњ|zFXCOVgG,̡H@LC*#NIvzem"(¸WYV h2ś,[4l+%Pe k\=\UVewߟFG u"iiW? M +fO̩֗ΎMU%1÷rczpꕇޘ+͕+-{YѩG{Ix^vAW Sgǻ6GHNQwqrp}78 [v*Be +(h +=sr$4 T @ PRa~PaDkZp!R u1{,m*uMjBE7RUu.ah7Ôq0CFtjalF`r3Dk[SQ\( .ZjaZp(J"FA3LA <$^J#d\pINsuA?P+֩D>&% ~Y"!cI30Ky3pBW 7Pic1dbUH4jnh4` 0BS\њj2Bё֤ KLj! YqTA#`""_y|.ydN3tEr +F -5ȧc |*Igz )%+x1M-q˟rL"MR PftA^ndz Xh O^J, d2 L6J]*Q6Lrę)&9!UzbHjk6 2T5߫ˢ i[F k"D1ɀ +F1|3g4 +lWl3@: DMW]iXj-4HcT5ݫ$ˢT˒s(vD.ai&N;j&LQ2v jK¡kð &(ak!i扉dHGM|tUD2͆2L3R)׫L$AL 5by&-4LCB/ckh$ˤNf"Qӌy"2L3L4Ӭ+j~&i`DKT\{^ZLPЋxk2if +2g?&iV`)ӌ-b `"2hf)ik/7K恩a L w}`}`fl4cu +)i֌f"`tJV3@: KX\A044kj5ݫʤ3hA443FZt ZiA*b Eթt!:LGSW{A#ek[NӽJLz/FDGžf4R DA4JR7HCt VRBZ +Ɇ&Z^P&5A! *SmBcH2ͤש$!:LeZ[SW{i-3h]/aiܫ4ʤCkTO:0Em sv? 9_ +uX]XvU?*91}|VܰfY (PK(W" +z&zw+Xd7K," \fIZ_h!ZڗŖ(w*wae/OK1T2k1&j}9Z!h_d^ϔf&hySke/P­>-`% Elp z&p7 :@K:>kQOaYe-. 6Y;}yjLn}ҁ~pOd}(e--.!.YK@}ZǪ^JZ^b D}e..6 EyjOe-!9,"lbc2d粐d2}It$6L0ÂR7:aLLfoad2nۗ%'M#l_[7}Y2ٹi}Q0gڇ)F־,NuC+ m òɰM#k_Lke|ehEAW֬/n,Y3YeWd"ašBW6z7_} 0]}̰P})̰Y͔}9,>۫fJP۪fBXffB`ff:hM T3s_N3S3!s_R3lP3!s_V3R3%s_Z˦Oϔ1t/goMzq OFrCBt,dC-;\@;4/9Lp=0SȆt%I#;icVًrFYħ,XJbn8Ѣ1è6^R09)rZrhcۨy%g*9Byf5UcMAqؾ7}q+?,E2K +&[G$LB;l*1tF5o_51 +* ԧr齦,]SwK\s|~Z>C]@M+ %d\'_:ɔ̔;]̌{ұ+?9 ֥9՞mi%fsob2#]u6lmYcS~axʬIںdK!Z ZWuӞnZmDփiqEEQ;~i7=adЍp~=KOWtJa,KU2.RԛC nP(^WYjjXjAlQ͔D9Ң^)!KKƋF q48q;^Db:K :eͶU_M[?!6*IpzF,v4Co\k +>3æhhWh ֬fK .UhLe6=/'3fIL %m&}yIgX#*g8٨hxpz1V:)k3cA/Mjuwko 4!`Ռ%E>0C voc.Ō$E2/S97z}-N0qN6v'; 9e|-Cf a3.2Y,[a&n71~|cECbb]hg<һ myh^bT ANN''2,=ag?At8^(2%.N,CQuT^!ne3n\)?7\6 +2C x&>xެv8AD`gc]X~+2(JKinP2ͫ%*}.0 ;'Kz$ Q$sH{=̦9,|ft䲛)XJ 4k7X~ ENՉio]Vвͪ(5׌B)K79:i +!`*ӊiev1 EP7*&$[MYZ{ڽV!B$*+;;$, vw?m7*s. bE?\Ģ`|etX1AkQ$k_8ޠ&C(;ģ _ jI#w,jg9B> (И(% 2tr Hm tt:([FPTN&Ueut%S^ .`I")* +7B9 h0h `ChPNOAaI0!E]S/V?VvQWV֭ck88^n{Zaan<3/P &f|`=N0.@56GShC;oNJFw^m EU/h96r+K r mA8AlQA}&p&"gr1 +̛T='ci&%v)X|_8$*s:ȕ xӾU=>z!-/DX3Ų <y'Nc%EteZ.=ǽt6(Ѭ~V%Vj̆%Nf!o"cl&wbdcg{:=נ.*e rԁxwuAqh\sQPbl

    6+K٪RMh7cE4koTjmaIv6M~v^:>Iv6hVjVb^4՘&lv[u1o§юkungL{VnQcіl{y 1Ы-FbG#^p,NV4[ٌDj7pÓb=vJ=!V}R oϰǜkk^e<:O{z/uz?Y/~Sh~"\9bܦYD4v"DШ~$GI1Cddz3{ rWr5yf4෾$Z̖)>Ǡр#6 #$qW}ie%uF,}w{L-#g.8Fc瑳`,㍙E- = 4dK?(*>X ,z y9_?B UslJg&'!Ên- t,dž'9IJ GXՠ\Ga9^iISp"sEKLJ߅#MNwae./op!g̿-~9:b;ǟfE=)`ox KNlh (IœK5yx @Ax#zG k (wU.'#=^/ů&?][o};~H>C ++5_&ViT-ϱ4K Nceѱ#;JLsY~$#E4Z,kvo(j(3?Uc,Σ 9|F4W3^`7K: +iZ,]iJ.6-VŅ鼧j޸'5 eT?ljԵ^7p÷(3),迷YOu/< +xF@CYD, <%ı"Q>k(2C ~1:nth<)D<!dŢA /9elM+Jר6-;(rmܜE,4Rvye-M(CIbx0Op8O]U"~ Q[ + +|?Qwk<pyjW +75L?$"(76"_I5I?_Wpq߄ǃnzr\ vc +bY%jQ%?$B/2&D@$$IN=/% +]ϳ$KR,2SEi zu)]kSQ@D/XsD ȑc O; ,4!7;f)8ޜ9=ђhE(2{ >9cZc(|A,z:9^qa6Rki ަ߂>^ʟ@x; ^ +~izf{5]f{,w>#ji?m#*/:iߙoxA1!f9D!5/R¤ғ`c>.z}`UOgPyz DY3V s# +1YlZ +!cC!ET֊~` B=XyE|o1cba1t׹?r-eQ;c\!jg(hUc;=/Joh;x~@/ +@ᒫIv_ +"1Im4" ៕Td6U_8~/5K/dE%D%8"aU=?ׂ0NW_?Rs Go`]Eʿ.d%M_ȊF:Vt +#_GoV!v$BBol'0bDXY)|K; +q(z)I"N헱jJUh__r*UPJiQ[eOk{;ݼ|askc 2'ߏPmOM5oMzqc q=D5o i27r~O dh^s,J{?HR abϟcyU?ڳ(qC2Uj$Œ9RѼ6?{[.4 9`qv|HS&=INq() 7.jJiZ`u{؟o`i$'З&hٞ^ő<#G,̞ɁQ:RHg%Cy. +]Qw`,G Z>$/CoHtӹa0rY@!j A0sU5 ;\IgE.rQJY܎ilq7rFE9IQ@?$LPgғV,@2 T2b +llz9 +,R/svREY \AA4 O@ , ]Th'i4Y +$T4NU y, IFِ< I8 HD4 +![Eڪ0ӪiEJ!:1!2{q2A/xO ͰW HBe2"2b`QIۀAJ״id]醹>p9.$΂=(: q*C!\p4x(axU=ЂeaCH@w$! q,E9,D9Z`aQ2~B40"7TP4Lݡ &*^8HI6Paˑb ó!(j 1\)2Ċb ChɀҼDE1 + J7~@'2#t(AڃDt@@aOe|0`(8X,ϲH< ȈdKlI<8!%NVU[%Z;E1C^ $TuԲBHMd +AH"<Y Qv8cEp UBTԥ91ΈkVP0HbP D RBXmӚIHr9Pr,_u$ (YYT`` 𕷜v)>atÛ%9G kCKI +&D0z$AX hh*t1֎//I`JQ'? "lB%FifͰ՜UN*U.$~$p?V69 `E&$\s _C,hԺYhP!?J +xVxNT|H`P)AyJHcbHܦP ,a0@=28JUL`!*ωR?BNe_vpK˺F#x`"+@/xx &-b#D!vJj%òG9I3X;V !{Nb265N³&CHK2WJcKV1a7+y`s6c@X9L 2B +ȵjݬ-sxzA.16e!6 Q@8I9`!'E(y54k2J-;RB U6\@AN@5ȋ <@_$6E W1%Щ#PA֬@ɓXVQl%j cGM3E(&f-r-}qhOu۝A#i" "q`ށ*C `L~ b>e/dj_$}t ~0ו"+7A8R##$>4j$l J&*A(jT/&!tx42̱6_F1 +y 8@SZ||<'LT46Di-&k(\ ()bXzIZ1jOvEm=*h;Ij&=1b3!ri??ù'QE*@GbCk65UʭڿB?!(HlJ +YaI!zeE%E[dm`̐}P_$+hVpV^l$`$q+9b$0z$)v /#EpyxkY˰N +J2fA,[!<7$lCҪq~cIN} &d~8X gV1p݈7=h)Myi@Yـ̀$cC6dž**gkM=4' +ke[`yPg&XUGC  tX~<N|nOeږ$xpPN PH}_rWM!C҈wihb߅U_(xwĶlѦ {;,,XCEbp]x`w +ǡ7d! Z\@)FaL}R':X_dB$g}?{ &bgAewSbu[-˝=2 Vu<" "9|.rCiD4NiPň@$hoE4ӐyLtA|F@4b3 8;0c(|de"R@-l-$0$a+P}TC!ŀ@kC4A@8#1*a)keQV\:N A.@"{7 +0 +WBhܝG_yi|y( ;ʋt.g8*_?p+IB|T}YL0h,oߐy窷;ʿiwvI]ŲTBW-5]bÊԮgiOnOgw5Z *B̪oSUvr8I{)Ηem;pQz$~~i LjXXwh]i,p|HuWJu' _Wu-6W[C ;^MI0,sQO;,Fu⧔<tR:!Zmo@P A ~'!obXBMg ee~{8 <#XZ$'/2@-p sD@r`=՞^vT꪿~럣LoiwS,0vv~vZ]69H`<\ HN_ףz_ZfGnfݜscoNmC94M2?\TZCJpϫvWYLW]xj-Mr!4'bim{:^+wn;<*Ir:DŸ׶%gS%>dU^>V90xސM,Jk0h.;َm_]&YƩtZ|eHQXM#ݶ{";N׹ Dl|{t+J{,/)1e[e:!KL +.$ +t*ST OɆS, f9 y.tP]DZj8D޸j7 IQ"U(^~,RD#jQ$s 5pb7ŘFN>3*BZx/z=X_^|}T'm +813-\=rohm".b,5# /Iz3Ǒvw} HsMGo0buiOhxy]CSkyjGJ-BNT X] B +~&i=ݯׯ|,/.F?@g|̔͗$AS] XBg&I߮`.beOQU[N9lFV Ѵ1&L=恾dIq[3}o9EX'v|rXm1"6Pё`iXhRAv +(tګ}T$ԎFSm +DŽƻih @oz\mb~LޡfkpR丳a^G6zIA6eXSCxrRׁG7j8G4Tj^ˡנN҂qWvb8xȀ(vCJp*ȎA ƿ̐_G4t$YVl#%oN(ܧ=˧IASnGw0\kta!Bp~*@pf`)BM6aGRqap^cdw Pr9x 6ȌPHպ[o],C{z:=(jp CNQ:5 ZErh^oSB0_ +(A1I' +9e>aةN10ĵԐLePbӰzL*Ӡ}|<ǡ9HS(~wwAӊtTWSlF;Ţ>JD 1RSG 1MV<6`fRT5hBf ^zPƘV#q0!8ۘC4 KХs(OZvre^I09l*6G#% U7C,F|(mWdmpm+ӑe",&W8{Py؎\yX,qZ-Wzfr?b .Vk= ~ B.|#7_>_3B}IZ\qF_kBeEc_&>k̞s>Aw9䆆O;AOMk'lD_?tmbԨ_ZB03gS#e:ušLo|塓A5Q\۳\^2Szӥ-QI1 eD 5x +M?ˋU!W?<%zWd&hc|\7D3Ž'|ޓp|'tU,|&f6{-T8m|؛.ϫ.͔7}GpR,Y͊04/5_|{3;?{yd$Xx~D64JC҃m;MCOB<'):H$z[E 5%ȕO9; g:iT?0 aI6X,4JY,W U+jqZ<8Wh!q}e] k=#?mbu-6_rAy;;VX}gY\W';S[X۫'V!~M[BY&o 7,H ;d:Z%+V,W^K2I[RO7KƱdqK޾|*K&,rsu[`$ƖZᚱ4Z-:( z;}YӼYz ˠ+[F2qy,iYT9giRhoeHVam툕&ggv+.Z ϟ1g_=|ZS5ZbZ~W5cέMn} `j}Yެ@D +u܀fuY +elp6kmuas0W#{i5.o#:hM׶xo[Fdm$j>2Go{jkW+[X>Ǚ6KlkGbxa\ .]ki.BorJ΋<_\{[ŝoh¹`z۞.ץ}Xnr%ݻu>ɛm^#fO=7ٯKQ:|{c^/ݙk3w8fK[#p|r יݑ%d;|Qmhc1Oyplӱn~4_mٙ,-gR9ϱ+gkZ:_k{:g›s3_sƢW`wq!.~W&w]Tt5u˲k$8&Y~Lyn\^w3vWj{T`=p<o:9:@|(R +4˗vLiZ/NP`j V:(gC\Kn&MF4ѹYbpI{U>;HFkYhdcSdL-yڤEE^*LRrgURtu5ߏ23|Rp? +nʭ-uSmb>z)XUyZ!M%7*yf/ל Oy|vulL]c#x&enZfvJ*O֭8Ԩmշ2 +مr/s5QF-^+eb}օevU͠tFn<ⷍU=2iQy=]7G˝1gVb8h2\uEH4:/OhiQ /gw=O%z{ĞѮ9e?>?wKqf܄;/ZeQLV,1i[Eo99y}ts*lZ{[v"wjkV;+O+lgnmM>uB.͚O>S$~5OS*`2C J6};Ys4Vc6OM-|ԞޤNDz= +Ӈ-ٟYgY6R +9'<6bn-F"*e\x-3c?[ueU<\ymOl&1Xyƅ8C22jpt|"z*L[|".Hߐ.VMgQ輇nw2>BN=j+;:*?ơK~}^.O4qnwrwg7 k*i|,+7ͶכVspF}_۫f?2m j}Q~n=?W%, *.5}=_Nb~B##pC^ +a?_|Uw6L]df +4#Blavx}OЫ)Ty/O$.6THʀ?D`UsH*҄N;~ܲ;zU"ASp gB4lxMi,ْr}*NUlX:P<'s:ØI8k]QZmbRW}ut;u? E a;Vs6Dʺca9Gk\ \,ybblj'd+~1G 敖r}&U]ʬ)-yɺz1_9r oǗWuHSŒ_?pJƧ]:"%~J(:8_i.(Kc(k|dZi%J" GҘ4wQ$'E)?F.v\jZl#u#=k-u +㑲e%7*nm9~kq4Mr=?6鏗$%f:QmFgfE+1uQv|9QO@/I%^f޴Ͼͺr#+xtv$GԈ$Uxwd3~ylש>9>1%>.5m.۞C.o7eo]Li7y{GslĚE('؛G"d=<~-Sӿ>oG4_y9F#A~ +nnnxgoD/3"u[,Qu7E:Qh`>v"jUd:&Laa|°m7fB#3odj5j0!8<ϛ\^T/\wOƢotʦd(a#81Gk^lQI卿_YoucqB]u9Ԉ{tKOZ~5MDD\Hbjgy_P9+%*ljPeS:{KNhk?6)G-Ùfѯs{@^S|bn-gmׅOMniBsH^ RCTܶB~H?'߹y]{Ǣ t r'yb:8gKԯx^hg3KdwXf|*P;t0Lۢ`v<9 tQmA9n $J]!o:﨤ʟuR2< |U逻lme̝؎橴Di=Dsލo[XS)c|CK&tg/3?Ekzbuܞګ=ě}g eO/I^BT|} ~kǕ$H}e[Xr SrUq &q->}&1B.3Fq0YZ;bI/-FeWw&& WZIS>ZĸAP+Er W)D5.cVyn-:_66ddDO1O*t_Ez ײKZl ^I^T)xړ!"(1!CfX6k^feJYGB=e_ܧ +(}١CUwhDq =V!PPm^0caqRl8Lb\a /-C\)tiAKz/'Fa$<'ə=gϽYº8m_f6uO$t#fd] ?l>k glKm'`weCYL7{K.{JٴWc }yq/?ə;Oο +z*<ӥ$qw0UΉv_q=;5e?R-DB~UJi77UȩPL6~qj~?vSͺH6>RX/A#ѭvܴn O*Q.u !_E{r:oA(U2O2$Ak /ؗD(R=uOi(2pj?Q<\@#ˎ(RIrۣ+*ްD/}kKs W{ϕ +al]C>ng=l$$೯/[63߾SL؏-r1y[0")hnojMLrdGËT!='F#~z}^M1ȺJ1"Q|ltEJt(& 8r0{fW ŕ4*&7~ԍۈ>i(x0|3>.R~fX%0>E)qx=`˷kyو-?, 5bAUnV'QjÃͦ}7L +QjV/{3r>}(%}bJLEQ6 :Rs -9nxɤ4i.o}g í ^PKW|mؘPjSwzt& <_ҹ<:yfOμDKelW{Mz~\Poh8kv"o -HvNm#Jvׯx`Wp8$荥 +xEp4c%6w&4h " ̰܌5ɰO搊 ;FLs:$ઉJ8SGKu(2s#/* _AtR}_rHN;#XDalg)(R ڮU!CTdD'H pW}.uj{[ա}dLf``pK_-K+&!5<WRJQ&Kj-gva!<*fKq6+P7D+]3Y{DESdcEET&L=@>VZ3 murVV*yQc(%,{ *۔Ǜ>NgR!b3`~U@ۄY&~_]=菖h;Qx]J%]DGp mt8 +o]D)m[TnL#ӏdB6PH]@-ޘC!aYe` N@Wwa C;Sߑc!QþF>[Dl!gS{̾G:9I^/]0 waTeM]E8/f0 (˰<1 }PPx:Pq.V"!v@Y/Ў,iv.m |])R(wK?%uN#cg'09^ I/^/U9֝ WH!:E ^RR哜 _xյ`% ZGv2g֗l! 8꿾kaMT/?/Cĝe"bC>,iMzC2RH? G1~OPnm=1p_kentDEлݤ.W វ/`Sr4Qg/޸oUh{+PrdB`IȎAmH\EC^c.hNpd%9H؋3{4[8keny߇ý^ڞjr'yzpIÓb6Bi bK}X3l6NlR5t<5\yg7PT#RljpE+.Di( L-cv{܅&2{R-0 :A\,YLIe$g삅PJ"nC#:ƉŨٳ͑̎ nRʷ@)fHH3by5?V 6~Q%gƀ1&t97vp=_ ?$Ӣ (Ծn@_ڵD#$Wۚq ,5)oSx44J,*j/b*7C! +gn^Q9(nt%W*z/bt2 ~{*;.|ZY "5I^!2ٯX)J7bCo̵7\Rtc`yGEy [+YA>sTU{ +TY+ +v\?)@ M׾H̺C9.fګm#fK=@\Txx>7uw5X}Jͺw<xQ\DbqW~PbFsi/1?@Cn-3ɘD[~$ɷd8ktgg83Snn7ƾ`OvD{GbCOsywnw}U$ӃPnxR7kOiZAgbY[|TaD0@YK}ˬ5L)=a*1:)#RœJ*֞͏׷ofZ)}0x,%U*[bzgDS#rVAْ ! |ZQ*ZϘ#i ~}-xE,{m@#k}bKr7hqRF1=4ՊI6AH_=]X3\ 9jށ)sKcX, WY(Z9xelԚ.t8X"; :(!cGr=glPz:ga h*jG(It2=}ZUԍhL 4@!P"{ Mcz@׶e2k4EG ~VL7z@nOi%LLE#yx!/;ݕZ}lt| I~Z9?W^ZY =P䃴K'MhyU1N2.PksOlܙ]VzY 'o'7Q E[?z}Fh*b9_LMMPtZmkNO, C\07EP$%@{Bh1شugx@o*ÏG&pH`gUhxZWOuJh4fV!oiehۺɩjm=1i*u;{*} sw!<*A\Kr\y5j=,Px([6. `@\fW-l)}لjAF"@q^6H?_v|V t5rK@÷JqWrYRh1u q(C@Jt s?=bmrI۶3FUS؃bO^S= 9>{Adc͏O+g n6gv= KI_Rmg^ٔ=͙=VQ>n{MJj}.z8UJ*zJVŞ(*,M}Qej{K)s8l{7ʎ<<쁊V߅ +C( r6dw"/yhL b(({{L`قCCJ f;}[̈JrmbW j{JøReS +Yp-W;}ҟ+wץSrSоK4ËիkOG̎϶ |Ҥ'EMhU ^,+\[̷R}L 5:>F҂S&ݎ bh)vudV:t~@{U@MJ=)ǶA!"1<ΞXDǑsU^Dtׇj֯5=>%}E<_?_CPH',aJY }̟QR\g-S K#z|sWɈ,vܡf6 CFzMjŔypFg'I%CEE ر-K͖@ꨤUN>y!&k`TNYh˩b:R㉰SK;[O08)b: +Y u~64^W5uAz&Y\O +ןq~1vʮ¼fZQq#VJYǛ5h0oV*=az&K_pX=\;x6adN:3*%bIʼnMPMD׶ؖ?4% ;[WE%r cIULa|} l(5v +͝ +j( }qeu?l<%M  s|·r gลpvH<?>U6WF>GgRPpfYOR}.8YܚpҎGIQ_%|a83 +"bmHVW-͵_+ Ѫc Z>+ *nNUXQq"ɘӈy[`9HڔFфڔ.ḥʘ>o;/tLD%"4CKXgi/%ҹFZGap^iT8p.K{}ТCI[a7ElY˫߀U׎sݙaz[3PAsr:ފ#~^&OkXZWzF9aS7.GO*(zOQ3bZɃufsD}KK[ 1!*zzLyt$ZCOi+G_hȬ ~D[O3 1dJ'[J)pj֟ƷHDӥ|Q,%8?/{[*^HPoX0>6oH M p̣I'>.l}g+lO*R Yxi 'fvٶ:ј m((K +v򾥧 @Xg{(.< wz7D.4>婨6: B҆()ܧц/_MTXJǴ2kaz׫Uk =CD,`lQyn.S i۪ ƚvc}ɹ7iYjmu,tm>3GzMVF-4jIM^Rꩥէ];%\%K~r72m4ZN$Cm!y0Ow},DKSɷ`&F*D)[lƝMxlJFaaLɧK 1)\~ ]R;ڸ2?gjG+p7-5t+SCwNS-5t+ʷ\ 5t+SC^j;^AtJ;PCNH>;\u,MJθ+=jMiu-qs,<!c{f&L'Q5%Ey"L'3VkS7W՜ =E|&gfHI1%4"`J4%ɈyO f=rɶ}~6ш}T2ɰT)ѥ}B2D| gfB&"f"Uc6y9p8RdON517"|rm?S2S2Ybzvȴ=vm*p.GaC>LɽܩZ0~U6--jҌhN^׋}Ȕ6WE)BqJ9Sq)kz5f3w&F-0؉[tOΝ+zX~#ƎT|cG!?1D"Ձ_~%J~U&v~30U pSeņNNHՅT􇝽&7 M1*`ut  ^;mӅrCg''#nqi?#_RoFgywڑ˺P[lEؑƕ>% +J>Z~tX+?Aehz/ާNs-H[Z ?SEdtpF9'RJ2>oP÷S4fe;j6c@7om:~ްF^[Zԭ41>fB7L9H:mꔁuqz^3QBbT: dsiԜoىEsgeN=pr~"XX=f־2TMHz8LcP ~N+- zfK5~0[t<)}_;]YoXER%їŲleږK<'r%S0kK'V\|50 +Z <lP'nbWrq坖h jozƳW &"0ņ+v :-M7aA7eK8huh`C4 {eCswwU(G0&M{q03w~>&~;YhΥF5HQm0U>~KE*i5Sts\h[ѝ2 i"JR"1shVz|&4 r$j-]6 Nllo-gI7]_/۽Ro* +|)_i ~N7pT'K/T |C t^<"Ka:k%ÆgI&$q*< cY7rf}2 [i[XK_yk\9SlrƬiQp",}V\usٚUeJU ^wn}@,6.;a +%m 4g{l=; Ш}حR +wv@vrjPw>RagͶ@J]=(vcnFno^w" +ܭWm#wGwSjdY^ȟJ'4l%%"LH{ &Ud);Qc9)wi= ֭>#JP_*jf3/vWrK{R'I59W&9=Wy=o񤾴XMydՑG}wD0yZa-\|tӧ5`zJ&3b +&R)M}zql}_5^-atz~γj::>tz!g'N/ GjjDNo(;jb{E}^1QEAoQTUJHBt={$̚%7>MW-w=7׌྄tU;Tm{h[Jk8fܣROթr/{4]z޿tiMhzc%ewrGӝUSt6-/u4]Mp{.qU'lkg4]=vꍥk}Uꕋ]>jMh&cF.q4]_MWU%]hzGRt-?W^h4]Z/m4]D*[j0ԓk.3 UN_ni<𩦴8vzu*L?ZYBkgT9s&zZ ~M \\Z+]<\mlw zC=l7=}n呏7l8W5K@ 9 +u.gB]ii:G?Kݥ/4+`WzS3FD˷4&uY$3?6iZ ٬uT[H_ǡ*- dةsd㯗㯗 ۍjksVw:5OD[m">nHS=ͅxj.325S?sdJ+ܵ:b+ܝvIVWpwx[+5zFi.e\EWKwޭ]-pwYN*6ZDڿ\=lOxk㭜Nso v.>6JyiCtkMW9[m2skut8d IaL bڭ<˹'6vc{W-ԍs={K#fG+g?W6EqスbU MxF4ʼnȩk~Y1 +]r˻jiH=Y;ueW}2`}6="]<,ڒZZ)K n"ycgKZz}H͎WNNrAz&V=Z}v9땕̭oO7WJȩd浝o72wgʪpC7^߽]ӾzVm6(SE=Vh~:߮%V-s72]\ծ63#hдw7_ohZcqc08dm1MVxavG _oQ͋57xn]lM._j?SG54K/|U:gZ/oűۭߕ퉺;ʗOꜸ8w֬hP][:=ܽ6yj&$G|W1k6Fת5ݤlrVŷlvjTZ[] (Jk|loj.-|'MK_Ӗt-:z9ORpjk5S]Frv͔sdmwOkn0/.}^]$ +Xt/d0YN<$5x%MoK^Jakكjn9g$p\כk/'!jufnn+ QՁ`ެ 9ˣۚ[#"~^@:]dU[XQTOP/)훏ou(c +x'Ufo+57vF`{{>cg j}.s5|_¥5lz9(V6FM:~Qm:]QX9Bv^d`3sQ<(fƭoGͩOUS{(U~Ǣ|grQ[^7-W?kyp,ʗ>lEp(_1#(_y֢|7{Sc՝wZ5~ʍW\67Y17K}KѺ~SSswX]Pk5_~WkLnTUF[Z#ZZׯyPuYk+<~5Ǽ&m:C9wNQ{S1Lxh{5{95[[;~uKjUb5Z9k] U3\`]YgU-\ׯJGΕ=6z=dTwP.-kBLM۴ qRnY=ppuWuN^II S鸻Y4lWHtOO,u=+<=4>1V믃SӃ zv^9н suL'V{?~y}ݷ'?m]λ[ogz,|q;|Ѝc|vѓƵww;9y0rׇЍkCsSwŇ;]{<ke{$K\}>4dqߣRg}ʍ=|dĝ'wn 5^ 뙺iÍ_=ܚ=1Fщ1HxrjZI_>z?U%q+@)m]N>Zx~){baLړ3?W3kgo.ytgis՝G+/n^L>i~yoh\KuxZʭ]yߧݏ#ͣlH|{D6a}XXع:4֔KkK}[};3|]G.}x83;j}٭웗oolwDVͥ[O$o3~\uG'_"mmϗ>~zo+UvKWonc{LNQh282ٳM]nsd"ƒM+#grtD`r^?ģ>^/lMߖ6NxXxŃK3F?T^4?x#~|?\꭭lyV(lsa{Q v罞O.=~ѽlrdy=u\,x?=K}Յd$ف+L=:዁\>$;}*ƊX9.>:9O34ʥ~UyZHbcOaYN4فl޵遗7{Ht+J+~JC)(1ZyBx?*ʧ۱gcxS[Ù4 t!}M9 +ٛs͸RåCvsY, /샫7n''hGL85:B&EՇcɶ*4*$D=̳RT>=rŧT!4<3o =tn\flTMոi/빑w<H΍b}u4:l(XJZnsb;_:76V[@ݲdjއⶣ4W,M+15 Ozf6jN:?o{p} 7:Q/ztp%>ȫ-KŃůiÑ+qK{|/&cE֢Skh/6f,қ4Jsk?fvn̼r}g}vmk9wuNtvݝ<_C[C3g#cCާFKYn6{|86Qb{L4׋Cz΋{83[ȯu/o)@t-lTaw_~q=Zus(N2ËqKzzz6 +}^(5Q$G2xlu/W۫~p8~)x7,cPd`H+5o·NWϮC׹mdzͽ^W(WdtHG]u#{k&K9nM +3We~y/.CBI.Kb/?PijmC8^._7OOm/_y4F'fts0 C.=;z#ܶ5^˯-laZlKw͕ύt~_b/Utt>^/ܷh|J +rwH$8.)N?/\wWVI|n|uURvMbzsWwi$:r4%5웝ZRܓd ɉXr}oVqWEOCTپ;lx{oUw7\a|G^ȯz6и䮒};XȾ~\ϫ[gKubB~j~`;9ztGvnfgd؉)6&? 5%cr@ε$7P/[q{>nh^EKsQout9fWwͿbtO2UtGhgVReZFZi>;г;ĕ;'f2+pwG\ZJנBo[ɑUyR ̿^UiǩAR]%_WepMFիɯ_Fṕ"y;ߞKƼWʾKғEu770_+`{okB)ځSiXKmwyk3Ng}MURŵ6T||ϛаp77r,- KNztR׽{JuU '?dC(6^R\R,/>?*J|5sMn*`bTFn<WJ`~RF&TS(&83}_nX;LRk6نP;|_ɉ=T rFf.YR`UTS[&\]%Q)wWuu,|s BύG{QItP(,z œ֣Wy&sݷc)OGoFqF~VtD/}җ=QQ~?z"YKq܃B_~'<Ɲy& ˙7޶zOϩRػݷ3ݿyٷ'bs>|ѣgtCy32S{TԒ'I5޸# LUc$C6'bzrg9?ykw-ީG,iwVvjݱ=Y]8OR^/YcWFsV>u{KR`zIURky`(kRMSWs?[]'[KQea[ +73M|<؎8dk_~ƽJm7QkɨhO,^o-lD[ -g-6]ߎYr3[ٿp*{dk7 Kk kqٻzfU7P<2r,:Pg7q]]h,R+Ec~gJŠE/"`d(QqU,kJ݇g>4QKFVS{/-g>XVzhHkQxt3dkJVuǭw'J?ֺ } wSb4ri4ϕukw6Wr˩ҵZ@s+Nk*k! +:xqFBV.ψ~eZZt\.skMʶlyf7\o}TOl+|'WXWy&Oq;nBK`Se'WqL?/V7W #Qy:RAfF>ZR(8XLt ;oVF뛣F9ߖ󵌅GaI +y$ح^NSyivzwsSģrJF7Vs,V4C֔?>~ |ѷ+O~rvO0LCL5QtbGD$.Q-޳BÏ GCi`F:HxW^5I>td5s0J +KSU;RB^ܲ%QUϟǏVOA*?Kn2p;+vSy,WOo<|}u4lth?>H8̴})ϲ^Vζ4E +_D0QQi`>O/ެX[jjUy.f~VfGz]:Y~6rWWGߕ*??z7?ߘ|.Gogㇷ_zS#7gR)EU'aH8v;Sliꪉʼ.deH&rW&sW2~}:>{/Wnter/G_O?W+3W2KWW_=:2\l'Bz{xkVdk3}+Q{ho~{8p^qz zs+Gѭ|;*>L6go6It6~+͹8yܭ=]/oU%*fD+ǝkG֒wVgB:>}㽵'7nxDa`ǽ6[_O_* \QhUW(41B\G3)WI͉Wsy. aS }p=խD +ugT"Rh0\eY.y:oA2\~ rRc.}qQ W?.ck}3U0/oAnk W̛m Wy.&Dgq5 W?_ rʳ10]Mj1fN;5!>E5''\PyyNҽ .m.lbՏK&\cU3=Xi~4=9]L"&\{?uf9+[lC]YnwRplse{f{߽ԁϮج^ c\;&NoSϱ_.|}HmR'6λ++_;{/VgE<~w\wg~4ս+Tq&O/y/1NjzWFo.~]{xzwMt_az-]?kOޥNҲ=qEK/?'m6xRLHV؛nHlsC_$q~e$Em`+~nZ;;_kgUN^NkgWEjkgWovv;_kgvvc[i}ɘR{k͗;_kgL5Z;+,.g+:qcڗtCfWoo?}`|/s|ҕRl'SW7O+{eiw?ts~98+3vool^R?q?zK诣_ M܏7ҷ諻]la2;65&S;dzSS\v"NIlnz";95V&[AW?77/>D?Wr+<{r]|'' cWFDarlr|*sWE򹱉BW蟍hnwdajr2cWrcD.?-LGZtJquJ>?sSѧ/Mw}Ϗ?RvX~Jϓ_^_^^zW83:ʬ_?X{Y8)GsW +W^\EX|/S|2+?FDV~D;8?=>=ٵe_%cGut u:l>GuR>gt:,=:}$dH>hv>Dt@CN:տE":;NWNl a:h.ޯ:n]NNx.Mw$N]_ӡ9uztնN0r]Bctz'0 =t:k;NcutzxJw[N(tT>NGe2]de&+4q2H@ +4Y @ +4q2H@ +4q2de&.@\ e @ +4q2e M\ q2de&.@\ q2e @ q2e @ .@\ q2e @ .@\ e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ q2e @ .@\ qe3 Ze @ .@\ q2e @ .@\ q2Z$fee @ .@\ v2sde2V2e 8_\&1sL\G\ e3&eMe x\&1p)Y ˊ$f.1+@pq ?ץge2\#.'MY ?$fY~kV&.".we3@V&1ee2ɸLb?72N$f u0+,}%J:ߒuzgxN:5N#3tz0%I't:kCwN`m: u:N?.Mw$NG\ӻ?Xíߥ?LB1NXNl:_uLw<"-:}NTF>&t@C?@]#?RӁߣGst :}:}:tN/U +e<,ϼ}_vӉII6F(N/){6 CХD XPDEbK$nlyOw?=sy}=}?{!B!K&E ۺ(>HBJ">B\~!. !W`!J%1!$랡[!K@vʰOiRįenFۖIIeQ/K٩eZ,YU9^b:vr7 R rW4hC !T4#Bl +`M 1iܰAes-{e$SVtX& ۪J_#FM6oAӽg/d0LnV F(# !d%4V\ 6PMMݑ@3[6oڤ2zel̑L9e2KqLM8&Z)IӮ=0"vYF5jcB Ȉ̈%%ppq͐"L4ӥSvHQXf2R03irUR[,]5jz5o!qӷ߀A_F-ʸqO( !d%0?n@50͐+hLexkְm)eLe)X̴D'&v5~1["ܵ(I@1 \`I&O<LUB&&KXFt4 @5xf L̴lXy]L*'qZrd r=`qL6;"ջOA0FL4yHe3fB6KX1ctΔP̈́ƌ <A޽tlߦLHɕYB*lSjZˤ תS:Sn= PŔa )S\YfϞ=̵#@,Ay,XGd3mFmdxfLQ>R23iԠ^eKz&qZ rI&Zf2-ծ۠Qf-cz-0pHQ r3 9sA. !%K.]LX +B!CrՈȼd ̟7wD3c:!m,ӲYF ֶ3Ieʬ]F2 +1M"cȘD׺~+4tQi09 d2qʕ?*B!F1ʕbeKiϛ35rAE,Ӱ=Ie+c$ǼdʮL-mܴEv .^2zU r eW@.k֬]v(!lb15W8͊ Ϩf&]2xLZh*mhȦ2Vi^A22;LS,yb1j&O[p125kE+חn-!d' KH.-]^vjf%2 L1F,ӡe`fR`R/+dRZ2kdKdX֡=cN8eڃ3EK0*Gחnl޼e˖`!l#QyfΆhKA336eℱ2y=A +fTT&^vLWr~vL:uק:f͚;e+VZٰql߾cc`a!`㰄;op M7@4kVZbْzhI2}wԮux*S]ddt%S-DafZ,_8`ǔ-X,fbvRٽ{Ϟ={}BFcDݻ!f;LY<Ytygΰ40̚5ihR?f[R/)+e)xKF料ݹ@-ڴtn3GULM[B0;w#bٿ8!T$ XpivlߺeRՌ$3seؿw;oӢ)RZ7ne2W$XKFewը LtӯhȰ11.5P-`f~By'|ɧ,OBNFDF\x xfҙG<򥋬eƔ RԯO^.%LW]zYbS3ͼdiX̖`fS!߮UƺS$SU:? iˮL22L{47ղGDfѲݰeN1/A1ܹw}=B!8P9 ͼdXf-]r"Meƌ,˚7Ӕq:2IYl`D[2:LeM*̊UkK7m{l1_9,9 s..BXbX±9+y d3'^9n,spǶm*]j2S'%2_MY)c:s/3E2L&PX?mj3.\DFe{z +9v%Qè_D+B&E9jd3Or,ԡ{`Tf¹3O2۔1e e.#g-Y y:uӒo͞x9vG$cxm ?裏>V~A!$;0x,i.ͼj?rCܶgz~}=B~>#N/3suLj̲%LiCLSt2yL%L.Ӿ 3aʌY/d݆-;v;#{1g%ňa.~K!1(@3̜\Ǟ?rɃvزa#ϟ5cʄ1#U;e:%0>Y&|iɌ}`s,jǤ#881Ev3!T<6@4h惋eN8g+V-Y0L~O 00g\YNɘe2vsHF%3wT6o߹W:2HdN:Hc0^do! V73%e^2Oܻsf-MA7:sB-*dnΉ`6Li,_vÖ?3Ȝ~ͷHGƈbD0,L!$X߈hD32eμk%yޱeUMSfefgLl%$ek1d 0x%uR-;piȼ֙scb0?*B!$;0QϨfeΟ;&y{d4e&=|y:s%̒喌rf0'L1[[2{2koj샸c0F.!T F=Z0{S2ܶI2gL0zN/s01?dQ2e2t] ˴T[2jtdΜ|,ĽoBA8b2zҦRv.(K<,dŴ e-bY6]8pL.ӾRizI"w/\_:* !d+G32^ٷ%9OLZ {ҡHƴKƼj8k12%c'N9wU6lylρ'y_sX_q B!Ěf2~_Iwz^8r{۲aݪΜ6qlI@yz](cWc^Se2I$R%?yKV2ۖ;D Q_B!ĊA2gH۔οL/[dC2U2-!:^2|LytWC23f_rMw퓾K~=V-De q _BHXӯ$}oZzg@2Y//'d^d&`\2}! KW f\fg޽pQe6ZYL1fB!$Dc4#3'/>xA%#^&sW.]L=\$L̷F2;ԧȂ S-dJ7ؽ_&Iߴd$&21F1;߄B*Өfe4LR)sL/ۿ{RY(3)tɿԄ%&XF*fz?9ì ed5HfL0HkW-#l*U*3L.dZfe1 !dG3j-z4e>h9*U*˺unת{o(dmе=8}icL1 7B!CfeT,MӅ2mݰN$D4A7$L$ɼrJ'}/LKƩ!1]!$4#T˴)#1ez٩W$3HȑL%O7a~h"Hf֝{ZV2LB"cCL!_jb2ڔBYypέ!EF2CY/F2_b f3iɘD&cBiHSN/p]F2ݒ7/'E|mqɼmg023N"lrBdLbevql'd.d%scY>߰1˜L,a!$8eV2o>IJ$sKm$3M%hd23,^-c!$-2P&E2dLNYy9{dB62 MIffY1޵LKHՌ'2>%'ئLd^dZWdCd̂Y&*B*dˤH_.w$A̼KFLI''2>܄#9IgWܒ%S3Q2dJF ɘeI&ۇB\J2JsYH0Q25%k&.eHe%CBHH]J2ːLKysSe$L!_Rʔd1̕S2%IdJBHIHdxɄ(B"s$ԒA&/-_<ɬdb.K\cL!_ZŞYdVP2B %C!5(B!'L 'BHVI^(#?LBFP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkP2B\! !נd!%C!5(B!ABq JBkI %C!qLL2d!\#(B!ABq/d_B2H/_)B2_/dYœ -C!*d !|F VdOoR%Å2u$K7ɒyrJso$2%CBH62%{#;v%ӹ ɼtY25⎹d^*C2d.D8Y*U2~v)2Rϥ$٧*gS%ȑLAdr%5$Q$T&H,I3R$D_̟2I)ƬKfNHcHI !o1<,$HfnK%$s:de !d%V2J%$JF2%.'K -C!YoDJ.'ʒ-F2߽3Y*>H"x矖!lwLA$ˏ?H:T#<$$@\2{U2~Jן~?1L'1g!$ W'=gJӯd%@Y7.'cdV۸5.Ξ љOe!!%583(O\8dn\Hf̈InIfAHH̻>HY(2,C!";F~|9eG\xH$sHfYK]n#̆=3GrJ"](Oe3%LV?V2^9v'}lHfH[vnK#F2s$D2?0eTF,c5CBHE{:Id2yGE2z9I2sd8dh%3A [#yyy N/32Me$jBHq qZ2vt#'_};Y2fcL3B*Xǘ ̦%cf0ƫ'R D2C2DZ2_M̝1ɴ4 ɬ)ݼc'9:d +fLL3ljBҐ|U1HN.3.;‘O߽csHfJfL˘dLW?d~zndvW"3 ko޾{!}ֿ,S/C*Xj&4B* U11Șj~ZhׯY ̘,߷$sם얟^d&@\2} Q!KV^i}1ϼm̤2Z1qDC!$ h6cl"ce^|,yg>oMW\2? +L M2߼: +kx_˶٧aYXm~LWceڔqReD33Bb1d2]i~l%gMd ߧ۶a=L Hk/ڐL L?Hfܤ-^ak0t2o+ӿ;4#QBVǿKL#ٖI3y>yyOSɴdj_3|!&O iӱk~KM6sbyBƔe'^}#V/ͧR0f3*} !jIcc~[MdLL/>wXb1ϛ9mҸA{vF%xbUH~ޜ,]{,.Zj](c;;2όef3*B!Y0>גȼ;o17J!Y27'?k#;õۤy]z.h/1Ke)w/H*3hxƘBHH ÈbcX&̅wϾm[22LɘG9t`a]:i޺~Ow\d|'H; ɴES^1et9*1_댴?oB bc~ˏ?^G`ֵ!̽wZ$S A2|֕I3J?d$0d Sf^dL/۩M^egB,ՌzƘOB*+T#Ų=s^zA[2;er% fϘ2a>{F2!͌)oQB=~Y>1_T-߫g _!dY  IǞ?{bY3&y +T297Xn̒.E2e25~-0ؽN~ͷϼ̯f3BHP{5Q̯c{ovIKfU͛9}Qdqؤ23XchhT5!T,N`[Q8c8FeґDԖM}z: ܖs#o_d~CLc[Յ2ezكs)#zVRSp>d'B4Ϭn!T06K8OHGHǼ)Id}~iKFcGe2GCE2?K+I%7:KeLB^6a4e?nÖ|RS˼ D#Q~K!1Xo0?xqyݻH"z:Lkɔ_dLSƬzWc6jT={8t2 ,[jZhfӖ]}?@7qBH"߷o/ پu&(fU+-Yh3vLMJLo>SV8-'w2^1k(L.zTyݻvjZ:2ywX,%sŒ7ed~5 endstream endobj 84 0 obj <>stream +Im:tG^~2L{py -A6#׬hJ7lܸiffVBHpyM7n(`֮Yb,Z0oMhӯo^;whtd-Kkɔ[22^&Ɍ2͵`ֳ̘L:YK3T4}t `e!la ɥ?:*f Y͘:cczbYx"#njU2d/gi?4nڢu1 /=n¤)D3s/Xxɲ+V> mF1Æ._'8F2R, xM"#OmW2H&V/3Z_0\K22]/7`̘q FL3s֬ٳgs-!d'KPFl5kAÌc3p@ݺHCV852&mZV~dֿ`f fo-ӱ{SпH53rxfD3yԩӦMـ 3 !d%,C.ӧM:udffHULQ>{uKGԲ2;,/ZA2M^mT۪V?m,ӲMd߷?! 4Pͤɓ'OSiB 'A/qc0C//ڵiiS;KZU]#T˾T-TK|7!jwՐLvdF4So@ pfhf8 x@H!$p,r7z= +.T4_(iLm[l8&Y.)Xۿ<ղT82o'IkBQL&ZB2c5ӧLbd(fe,!lc2"3s "~)ILAG1ڴjѬI#qL4լ!2Id|뛱jY9%T/KNe~,i.SA&M#i߱sWhWoL?͠Pfp0BI!$ۘ,yz}NBB!Ob ߻wbӥ3vmZC1M)EAf Yfe2슪e Ih +f߷nU,#XFz J6Ӽem۵iu YzB&N8ЌݣGLڶnղd1 4FmhMIdeeH&^fS 9f_@̽߇ti#i:uEd) !TLP tܹ"AI}%[GҘϣ#2OMd.Y-T/KLel[Zե1BIg6k.iCǎM'1N]!T4IqX#3"4t{~4aXDBW171 D|ղzY|Y2?p,s̪ݥɌ̢SxiJ\oB*&(KxF]Z_T00SVT*eUM9A1Hv$1ts2UݹF3h#i3yЍ'FkB!"!KpFFn֬)b]+6ɽ[1UoKpLl)?)+тX[o3ɌL ԫiirh*4#Ry,!qF 2a"`*FӘn͹93{9C%227t-J2sgu/t&U4ކҘBHef ш D/ + >QL;%o1昄b[2S4fjH:# DVu5uaҀBHe ш԰Kڵk!Q}԰gJFW+Jd22`lS2ΌhFz35r5 PXT@6B!%H#VGE/H#^M#S*KvLB +$!тYezk2533@4>lD7BBHeg ӈA 2GsIbbR&ȉ$H$$e`dF54j p B82b~ h#Uarcu̷ceLeJf QϨh$jrk@7!ʂ%L#Z^ +F RYc(I&203ӘIՌx D#Q5b*djBxҢh ?W_ 0bTŘv},\dr^滚hzƈF9!ʆ ^5ʌb4]))dRSOHoxFDcLsq!ʅ.`aS-%94d()`X4fljF3"kMusQ!ʅ&z1~h IUvLcXVf,nX27g=iFms1!ʇo/"mĨan4&cH2L\3<F\#1I"BHH &Tߤv^4Fbcb`ffbxij5jMB*'V/ˏ~FQLŔrJ&etYr2hF=ij5F7IH!$f~QaIJc̼혔Y2LgшiD5*YBXq#$ä11\a,eb%3MfT36Q8QՈkmb!RqBU/1alq[*I)%X&U3gh45*p!TN`}kc4dvI Ēgh4+7B*/N}L0F142ɚIFM&B#c"I5Lb1 IOfD36ѨiT5V6IR!JGB6/"k8Li̕;&eR5xFEBH & +1Lbc-LgT44kC!m#4$*jhd&Ƙƨ&&"RH 6=&A1iiuL$j&3F44q٤CB*Bt,-.$)8&2ɚI5Ml!|qE&&0s5hdXL(q$/%@Ȥk24xM4I{F!b35ULe⚉y&&D\8B*i;ֿf$\ ǤX&gD6B*;)+35r̥4(tBKɠ$$!/ab2X&3eBk̞I uC!_X2 ÔDC! Oƨb ]C!_TeB CBȗ EC!_#Bɲ_ rȶPE!rm]B!B!B!B!BQjKtmZjf<{%#R5f%1.ԵUNʩj(ΫS;Zf^Os7l_?8y6# ŋ.4xrVUś`MOn(¡?On C/D9\ EBp F<k$*@$< sjxPECp0gH~O'E^'7ja#/P +}(ʳMWS*Tw\]9ժtR%{N% ((,з_T^)_-.(P2hh-Fv?VC h?^3{fCG.*ƱϭUa񈡅#:8mʦ 7oۛMY +?}_dD4i08 Ӌ} +43p‚F#?OtMzC +GO(DprI`8")0NW&'J89] z=|NɩB!k8}k}%^熽H$y=F׋ F(#G>g$ӷJH^'s2|fՆ( 88fؼ z>>&3>G+1oX$^a V {Bh5Fsj#a$l?``D=a$!nԋ;>M r_!\ 'rxߠ; cB@nk tqs8NO'9/hnXp؋6#o㋆89yO87)¦al"cO! G(!7r^d`n$c bxhn~ Ľ&aO`Pu +cpuz"a?Sć7ȥ-1 + (M,rC^; y#rq$pЛ#;">pBEA$lR Na8X6=Q'f#|7s䪉#82^:F/{_jPn0ċr=83ƾ-LDDCΊ}AS$sf$`"zdlcFpՅQ\i62|8$wt3FʔMf:,Mʍ ZG#`6ʰ.\?t*=?4ǹ}݌k3 abJXR +_a <0_88pzr v^8h0ӎ  &>}ѨL p؟z`;VMVMC @ؓ/Q*"8>>ܗ{L9lEܐ|r) ~5q^/ :#[@w=A|ċ^ǁǡ'>{N $p#*pq Fa d &xh.Ë y@a:r{%6`P6cԂ1)Gg2'ɧxeL)-8 `T"'#q7Wl <09pnqo0EH05ml`+A v781$@[ +;$Dv8~=lY7 #p 0p.ًvP2 .zy5%'!2b\'}vQ @-s=Hb0 F>|sIxr8AXF΃ CrqgeH/ׄ߇jX} +b¡'ȅkX ADa(P '&py{r ȏK ؈ss0 D"~qsPNKg ݋ ^Ic8) $ {P.am4 e:pA譀…Q}f +lp( WAz K2ls酫q +p2Mr8qdn&dHrd|Q BEDJs$jJ$8dgjs҈ۅe؇tSbT7=(5$;zǥmA9Ge@TrU&%n#mDx^ls㒕 a _.8㑁"?}XSoI}JWMx xG_<0WkGvQR3\CЅ Ehf(+" G`[4.=4|a $,Wo]GW|iη= "$q##_R da'@,rCĊ; + Lp%!Qq@=IqSXd =CG  zt]@f(2Q ˥# +[vC%q& {1lDFĎi3!T) I#q ʕD|W%D@8 BB|^DC* RGA+X"m0+BXF{~( Аq*Nᰌq4"^0+ǠJƱlQ_f,S!GDSJGe|Q\OH FFD&Q +Q9Fe⠉,u0"5\\ȹ2nҷJI$A)Ēpʔ$_&#.*7AXhwN|TkTْyʠvH[3]"4#a73>P*N^U A$ 6#Z!ʁjj58I'/`rF3) `F!+!@z8r_2~j wlXE_ID&ױB_A}^%RԻ~廧xKTjwt{@̍,ׁϦ^Uq==Q reVS2 =0eSլ%cwqB ")#c v0@ ^`GB_vgHLC:1%Ybl$(_Mz1,?!ez BRI$Ca_h4l/EH}=ɶv .wq#ZFNSOsw7BrED^D qw=Fø69}l{)ۚBV49XQA.%^) 2a# `ڢB/,7,G; !&t/G@ׯ1\_d aH0'"?>Mu!X\g^'(y|] MTIBlB#m)ZF\ +wRkT˅FA}ΐ.)O4P6B/F:@-"1}7z0}e)AfQ'<$}/q` /R `TT$F\EiLD(ITzI+JWFZ9rqEK_wj@h—!5F} %.Q@w 0"5i@bӈ4D*!6AqFfqiLȯr)a.Ȅ5sdܥذߜ|G|(. " ƃ^$(Uy\$QQ8#Gl6G@ƖA|eX-(cc\|8/̫ kwQ +!G=6A|10𛽒%3$Cf-TF CҾ}<qa3FT#P!$6ќ@ +-B^FD!=ZLJc[*!G> +70$e +D#(ULD&r;HQp\R +(B\3 c4xd%;f,oaIb'_cTG~B%!vx|ZGT BnH" --U!-}g> z"Hi4ppBBK/,A\8rF]$e +Ľ%5hJi#J_" q% +I5u(BDGB&2!2þ>)BX tXH˵ID*mN컖5 `t-/9}tA[C^{D?t nF~&A^V,yE& L"*9…+MfqK!D47҈U~ʝ`hXiGC9N?o?{M21ăA|XJ ν|8n5e$z@AZiD"̨ 0#5ÔM"zd6Cb4 +2|-w)}cL, tbg\}\IO^OaoJbn'?b${BP-JLHWp=hK9@W6{/;*/O#d}B*A֋:SCѰN<:CtxI8AS1BiidRnD2hϔaPK t8͘!JDԨ3#e#\^\ aRɤ `<&5 +xHA >ij'>;Q 8%yqȐ]/l"B\H((xO~QRoBku@rv$*p#&9TB^iH?mfk25K&2He>IAc "-ޛ-[r\gOoh&|v +J&Udwe@* S*}y")R MC^Ç5MT6R$X]U]:) siڈQ׮K +m'68߱htݟG/х1qC +1D 1.fk#!ןws*5|ۢdL?,IqO)eLgHHӈVEÅI8r#n!Vl6eH\OkƈVH['c!ꞃMVp1 15JF +F/3~Y|U$%'B3| +d 4"TkT[e%^Fr)7F݊Ro45?Ȗuij(9jiʉ&@bKRk +,7}X!ƹ0uuP|n|DiMshLE qj!RXCjds:V[B"3_??8<动C~;ղ;OOZޟbOl.;n;!:Kor뗹Oʐ"f?gJbH +B%}\:M" Jo$N}}uTK+xqfcmgJ6nea85&g{c4Q@CȺх5QVǢJs +|C^vJ 0dMډhNE*pnʼnlN'SO8%EIֹK{-E8#VǁKI _GȠXIb9mq.[el2~`r",nS ӥҋ&2T%+6{|.Z9U1LwW1K9$;m-R66BK;`OHGÊ.k;}Ukݴ<_VNۇ_*qNǃ0J{񛬓S+"rMs]\8'6Hk2:kTԡ+%Kysb& d;K,fX,yZlQdX+,}^ Ϗ}~'\NGl)oɞ! M(3D# +.0~[$)ɹb&]u:Z[ڔHSilhOގ(6T{=p4Ñ8axՎ>(el 2]bӳ|$J$ldv"җvهDIR^$3oPҳ[$$d뿃yz%oO~Aӫ?!g/́D'd"$| Щ/Lg[84MBٚy~dTPh<9>OgDr>zNb h_9$/=2n2'\") Z`_ '_ɰ_Sq\"dW[Ye9qXIPViY}O/侍B"4+ dt.|HEN2D6>3Ϙv J?C+ XC>HlSٴ2110&uU;)pr t1 ¥2|fQG"$M>*-gpCRm;l*93t1Hۙt4l @~p82N&mu n)E qiejqYe7xŵɩ9&! MsbJ#sT=Xzՠx{o Yee%ǝU< NS$N;9h 7dG@4&{DBR >SBܐ/NVYꈶ⋥$b93GpHB##U9ٶ E\c'>y 2)[؟yl +)p>u]PC(O$+mp\$-= tCCC@k4נ=v7 +%>ie"w,* +}=ZDAiWH2c:_u""2䘲Υxa$q_N[$qڂį"}+}KϜ$k~ƶ̙dQg"Z/u L׎7.!6{MS,guqNXZ&'ѧG%QAN:~K;ۊh=4Is6 (< ".PT ͫ"iõ6V*j/Z#% ;}֜/nkn}*bQAR8Fl,+mh+Q쎑VҴ8PI;B'M[EC ߩOVwG'x*"r]+b:~ .>8. ϣ_Ĉ`kFF0 ݊·A8#Z9 0/>k!6' 3Ƽ$uObc)tOX_զ/Hg F6=Q=h +,bdk$>LW-ljS_i =gr.[ՠM v]n_er(kשp|V'TT d"ٴV8rŷëDN{IGDyFCeVjoWQ#>f ݂_Et ѱ+r9yh::[;ulB%!ŅV26I2|th98c#bpCm<:`3 S&kcoVq{_vcUb-p(pM#%D,MF\oO߈{(ٜ$$em"gF*#<1Q?ޔ*]+$sPq0'IY ΃@ȮY}*o5rض8`h^|z ^c4Z\yvNydr\WM1%O-{dP|7@wؓK؏VլVէW$}9^o,.TYM^@&DܙDH2ݞEJod,9Rdt oj=m$>yGJԸ2VH|| dr\s 1g4F Vuژ.o؝r\yNm%|ܚ?ep7/kI()\? Ig눠ZuY,&eU +uF@ƹIsS'~EF6~WyP.ĉ|otwF"pvL +urU$Zߓ+ -sNY?;/i)EM+RU?-T|(*':*`mn"p曆-cxK@Dxn1cjZ(//OCq؆ŕ(1bzNr$(P@`v%rH2od+Ȫ$0d4*1BBo6D'U+w" +-fe:݅hie$cv |4jWu 6MK>ŋ/M5P7~㣜IEfO yd4 +q>zmy#wPW-O)g̽%]aqE«@5Fl 'Sk0f@0~HVO\w]=yd`H2/o!^ICb=:H~!{(,ZlU $gM~] +V4@,M \r`mS4,"^PD+KUHv,(' {tkCVW껹<$_H<=oG "R ҭĉÑ܍m;z @NXdžyξ_ br΋>H TT1-\9_ ^&d6OzmY/] ?DHԕq$Q(8ueHu^?rJ?ᑘN TotCƯڔLH> v&i-m>}s>֯u8.ԫk#>/n;D)W0yXpPY 92,uVOh#15؎SC;";Fh$/ AtMM V +Z؎r9ܘDScNgi J| +X A5nUsL6k3ܱKJ~蜉`\qu"4smDs6}p$J f&(=9g1egs"Y}ՉざAwi7!mD@@T-:ާH>DB]e nrj}[0OiB/0 ϶ãUB>uٸq"`ґ:X(&ku}@aknvO%=/" k ԃ9dASIuu`̪Br kqĘ#gyWj!E؅Fkd53I~4v]HkHhdϕRoTŚߨC-@o݆+,H'B (] &21Mv2RJi0aU`: mሤGw8]GW&io#0b@F nYwX~RJ^4\Á6;ox;-<& FF4$9RIi90b$>\Rٱ3pZaWǕF;8! +mft$3EV/_QO6 +.p̹D]3ʏ,r0ZJ+\3đ[ye-~渚̮a"4n %j9Qy$ናɸg|#" )2 Lii)=m*RA⫸qǚ6 \pI?zK/+S. Vo]9N>Go0Qճh9á?4G:LXkr' DW'2{O#{6+|kM@`% :uIK us4mlOL& +pzih,z US s&y׌G$ݰs;|OwC`=_J=[@H. s4} \Oi/_,N+YQ(Ez8VR +Jl^tqE%-tWb_`pz KTaY'z3"aS#aΏQC,ܒ1G /GY7JI 5Gc:%{4P" at. "ԙ7r#$Ɩ{bAQ$熶d|rˍ K9s-*5M 23k;'e[8H,6lNE#ZPи2}&Hzu$iQߗ;,nC'c[ /v LWuy(y/>*Bo}q K)g[57Щ g"IN$bfv2A6ַ@7k} NPq^5f>ER3$kʙ4ZI:x=2^u\W㶺O64usұeW:pgyilogK`F  +%$)'fW'b#V-:9S6:.y:hw\.?8F%}6<M4%!EaϪRs)ryUh:[G#V6^ Q\rAm*F9 nPMU4 C)s+@RJ QfĔ"h+"$tbIUvʤ>CϷ  ,sntC"|KC+@$6?ow#fm~>/СDI$cQi;JffAGj3jI ^UT6N'VbOp+w.oZtczdA'!ָ-!`# RrQߙHX#`@ӼӨ³ H]= `KC +.o@ 9k.tz/X͚|3%t F1;ilG2ӽQ,hŝP:aPqْYiZmu!LZlyp%cѻV#tN<ы[a/f۳K ]Kd"8eafHSfh]s-iGTO^[b֜N!p*Q |HcaƳ̌ty`y I3c/P@S] v +E!xfW;]\ ߌo0.WnҞ[XALfsd&Ȫ{qF嘮dvpj5bh l8`d HJrttRD2Ns\/y<ܷ9&RDM.vù)fZ0T-&M 92dBR?Ϗ!hJ܅+ MإU`^PT=MMYFWu 7wC8-*|n#6t%g+-qҥZZe+4V +iI ["UVbjln|w{$hKIZ/tfT={k^* 6Qؠ6"OtqrW )0ZBe"pI_Dfh: ֶODDRhT'8qȹH/?MxS.^AWi7X IqY@:łu ݤQ)h4fhd̤ E ŗl5`2O;FCe&#/:|:|:G"s;˗E3* +cxQh$<&DKzIM3ŔfCV@Œ_ݢm ciyZyJ}vJ1 cjjHi5^?yuv)]w;gxuGHEBxt`,]O; lT?^f+9F9x0m|; +]\n-= ׊:ydLoc͵A`/M$#4SB; *zFܮ+n"a. tӧ%aͻ*nEELk:2Ҏdj s@)dM AMsqݕV2Hz-JLw`'&G +!yV4n%=e&-Zj(7mDJ:zFE }5L~NUe A w=uI^ː_ЎQ< -&YxA1f)t]3`RB/Jy\Zuw?>6Cg* {N>W?yo}W~g9ooo?߼۷ve.i߼6H//GFs,o|{"|NLJ_~}w_: /|7=|Uzɫ%O_(˧y7チ|w?NxUz'|)@X</7>;~#Sc?z<_}w_ `&pf$:joIƾ ;? g=7#xQy;x|z )ew%NIECx'cY9dr.\H_~gnܕfH+b]} lHE]Xځ^PYhǾxkp+^МO 7'g}O'%O?Q~T>ݛo\ܟ0n{h{KTۋLӏX'm?g|ty9ޫxj nN~!c䌸>J9{n 3M;uh䓑\š( o!*xm8@~$C[/#4"G!Zɮ/SEWӂlgI&_d/?}N0/$|SH{tJs\-džԩWG%-\)xo3d1N ?3H72bx[s-Ű@mi|6MW)1rJ/HNbxAt+T;(_‹%B.3(K<&giyc,D :nyƧ }"̿8̖ Wo\gXU>vǪ?4Ǟ4Ǟh84> y|s75 +|x5bYsOV;m!I?ϷAx*zkb"{_}A7OJw1xG2}Wߗ81\,o?/m=vuV u55*mLfV߽m~PJnPy%iϟ3#9?צK +z˛-_n#}Stg9O_eJ"YmA4+t,; +T 2R.#x.)m:*kB״T R?/n̛J@šտкy0$_qz3=z83nw1`($^:7r㉡v\{@qzU"Psn1 ݳh'y-]2t,2PRB'd{'9oIH^rXn^*D}(jݞ؝hT~:yIaK!D41Sn ^$rRod{s'@j&Q`F#D$gj[e /%K&_ L8h)&=JDK$*`B̯ҿeHǡa'2.{yQn\W  I]8?=u8R0JM{{UU}t`BS aIc;- ?>\hm ߽ wB/?ZRJQ]~D wJ;q؏Wzypjv:Ѐv:Jx +P/ Hc|x6;Jcwd}f#D3uc$q=gxtہ;!.(#=} qt!. YBBIN@7C!`}!zBpq_5NG!~$: lHK}~yoxF4c뎌n-I!c܉ '}Oo98/fx|u2)u:2hN9R3439]ނiQS: љ;y *Au>}3#ItiO? T};Tܣ~(֟XgKHjhqot9+][!d_CP({oCZk&0؊ ]71'#C$4 ̞LL8^xD?8=CЛ'I|ND#zA4/`LG?&B3v|"cXOdp6GNS>,n(Sa uoq`W)7=h%HP S~91dw=hzImb:cb65Um6]LKM Ku*ȽhކU8 ΠKc t"B..4J<4askit:)8+G$FYWHzCY7VT3O41:2jzQ_pHKyx*һ#=u#{]g +)g<|]6d\져L?l$؃-Ј Ib1@^kΒ׼?蠁$=:xKC/RҤJ&mD͍7" +uBrH`hG!ԫq QZ|}(!`80$`t(' -ms㖣`NJR H2%acbWkHvIG'cvBx<<+8}]nr} 1!rh1_&Ewc"ľ1oR Bx9~~$OX|_"Ցp8Jj$Lg}}~+^(C+_6VVMQɮM¯. +q`dMhLKB}Xh!p0hƽ[ugYR*ݿ^CC#,Ddzї Ze PYbq8EʮǑE*a ,K +-1cDH,MW:SN\3Qz*"5*}9"ð%QdhwR8667;`% h߄!sa킲n'+8MA&K.  .2Baڳ hJЧAQӘi76:&)Mi TvD"'fn@Tec=hvWMRS$+ȄPK4 (~澇&"#FPKQ|DL}C'p'auҍl󔕥7!B;+="?-f{XLGZJ$ nlp7x. ?}4^FҴnM!vtm.u!e:/񂆀uIYo5-6ݍ}ߨ=rq#X'X}F[<-1"EC!HR<Ίe +M&^D32z(3 iQqҤ3%fE=QW7ItِLkGrV&Sdò:#MF܏5 +ƻ3.HF!ڐD6WƙTGee5m$EIqerfdF5nd& `Z; I' JP_t7x\D&Щ!|&/(x낣eiRNE=wˉ=GΛ1KZ`ZIwfj|oiBGJu2O'ȐŞEL2"ϫq7$`OMŤu57ImUrFa.aqNa9WlrK2":FguyiyD o,v躍%NEr[Л $ЮpÿȊKBww EfIMTǏW'ۼ +]:#\ +ؚGWi- wC@l_ ."wA4֡jq~nhd xhώ+ϧFK^f? V]GGV/k9p@/71<=Bu'pT/Q5-iZ*dREsk5̙> !ad+#PI8:2hʔY]v&J~r(,+Y"X>. jW9}" eJ}͂Ug" ! i/$]z)Vjթ8|5e冑ZV"9̞Gx J.CE5:h-7{a[R-8Q@/$Ͱx9E.D_ݪ;Hb^HqJcNABFWe|EAd DLZ ÑBfwX2)# ¹us em ;0NO8rH"Q_9cԧ|u44Tonc$ UرReG"b2k:$83~I2iFVbo: KW\bD $Њ6-䮐T~ؤP/ ODC(XK8y4'hf>;>"MWעj/)4l }Gt#. ݱ7n:M03Baa u1$fv^WKdnqH=qy3>@L18nB[ 5Ic2bYU}ahLN򱐩$:gDκ'8a:O~"tFciIk qs6Q ̊MlMaJ{hA &4.'&s"9~DbU7. YWD=9;Nr1KB} ;1H9my2gG\/wx').\$9d^wBlps'8eIp u`%$%- dB> +eøWRåH48zܯpuHb_|W2.-4T 1N/I :p"ZqG zx{x!Ԟ8^'&s&933(Ih)D`(zBVDfkx~_. Sbvcвy5EBxѮQk zguEbϕx}Z%RUcX'$ =y7,eN8C9jaT]Yz6&tpNܒOk4d +8:#:H/4T +HqDI$ } )v\@ci?i~yKBvBqE!2p^X?f|nĊ!ŸS6{d2aHEC&]I8;޺h#Ar#QMf`W&s`#9R(/( 6bAj#e֠|,I#O p!>mMm-yG}UZ$I3n[dx:B-+ge+1f HX W^K1RItH&w7!ʍfJaRVTOPյe=plm(v0E67n-i?۠ ڂTX:V Q_b:櫸H& 2}94ZZ k%˒(K;|<)'XIX/&qZ5t Zk:sYlXbz6MAM,31iń T)Йo_%\ hY;;iAWktEi%0_!wGUYI`% -aq*pSJ @/ͯj`aMH2MNhgɤNӡ{kŮ5"->H% i>!{X5 Hm%x% Q*s\$mϦQe&ɩX e9/cZg9DE(!oUvS8#\!J*lPxZ]6q]߽MGRnI,D'tS]L +|.<.O@/+ԧ;?߹h2$!g)Z`%q^ƧDɋ[?͆NGSѳ;kO_[^9 wKс_|*G iY@lc9(ɤ S;/'b" #I:B!X8t1e;@'#,I[AF&rDete3M0+JI]ÉU +B@'YBSEo&S Ғ1 +UFk] #i2gKa#wd%!2IB]zw +I{wCFjv`4 ~? ~`N zgt *@/@Б8u H#2rp (ʼnć9A4=$0vD X>Z xxA&7٫c$;)F&T'e~jO:P@~ċVG7.kT.SOeN\Pdǭr-99Xz^@*f {>Հג22βq$}.ϐv/q}淮V]\Po%L{VFRDLN v9X'DY@b}afE qorPܵ>]6 +.U>gW,E R|hj34 +^ !:$(ɐQQ L%7S8PD`hXh:Hq+N0"^(H6z i|l2gOɆ:gjFA" HԠ, "ER}6X@n~ܘI5aץbXeIAJ9:s JJdx\CMk? \ѩ̑rpx#%ɞ);oy+m'(a(;;< rf㛹9Fb9|\*&d-سx"r?D@A? +Gy(l,RKϫ$c:ol/C EA499(!0g +'I4kН;`i֮ЮM 'n +vB 2 "\rtނHG޸d_jl+BrB̧1tBt|OJ(l:)ؘv"B?ȣoJ0m+xb CGMCxy }_EIU*03ˤ ˺d 5 X"B<ToR5:Th'$6 T'pS ہ(P(8tX@z~!f_<`%IOv6ʌDɑb#I!}6ET}`r=W O2d1WZ!+JIЯ>R!S1ſ !BCe^8QJm 12~8\䑦FܯtH؉o烶"jj3:0D.F%(%$Q niQ " hȼ>"m M/j׃Κ#ɎXVܿ}(ءa=3ND7e葲w`c0mڳ-R%!o8 au*$_s\vHՁqm{X ye>Oiu.ڱtpη ̞#**O`nv|ܼ0 x7tg x` qe $9eX"G4Ey\*sñF:F iͰ:L2jwpH z{3}25#@a;B 9h!gV(eT,D)Fe4{DVHSrئqޯ:et#Y5Xf@6j Q){r}8_u|f8q<}8"fH 4@s%aNpHJ Б\T:$jrȊRaےSRk<yr 4.gC=xO $]sBsқι 1;7>Q"WՈH +jsAH^7hfz!# +@k ߑF+YHc]KC"2w@[uږ? +Ql:u7Pie1D?~Xv%qSsX~TSoJvJ5b 9 r +y,V> -<ț?T*iL#FR+ѰWRࣅ_"4- ,TU$x1zu5LH! inDJvgag;&r~k^͒*` gg)% iX9<[I܂I}':Urޗ)ONhpH8@j:nXHkW^T7GuQsNUHGZuNrb*TeAbL$eAn{]lߦB_&G { h64F 2~Z&8@MFiPDZ$\java3<-+Uh;muJ, K`ካ-l`7t& 0h-f)QĐ \ ÷ALoTI"(^_ <APjx83 8 ᦝQAEB'zKJ-kL>:cta\NxXhn6ͯ`s]zY(W)NDQ*noC(ӷݖ @Sh3,G82f$$˜& q @9;\Q#pv/SIb6{!#n +U(ðDdJJ"tlnHeqƩHaȲ@›H+vSX-ْ dR:Z/"p=zFbOv]t3Z mXM[R*gCx_?% m"~l^j34m<߄qX@oߔAē0z3c5xGbڧkD{Gnuϑq@4- Ŋ j$MN9}فɸ(>>Յ02NJSdd~=N(~Ёi)3rvᢅqH8"lU8XQ8`!s@nL*+fͦ&zp^/Q-w⚄؟3D\ɂ=90>' 5mrL%I¬!&TS9,>iAD?j;;3;$ K--;#m7@g\Xn:?+:GC3'NDoW +BqyRy Z@A NWR3bsp'fl]ˍ{oS6-4ƅ hQTG0rNΆ'zJa(+l 0LIF`1FB\ ` + j]coy6Na6]Iedbc2_vB5|?lFҁ9TfŠdÏN0k*#]{sqڭRFOg!.#FRUv*TۮܘT 0Qiq<]RDnwr3|Y9dz[&!fHR8Si#H`#ձz=x/ (#>T%U͊L +W,KtGXUq#TM˭t.hB3n|Lj :ބ'D9H1- +"9 J]+u废H߹ZTyD3x>k1RZKwl5zKJ/)L ߃ֶ$ܝ?dj۠ب"UăI>=Mn3t>=0]udJړcB.\xwlNB DfhuO8% \: +eU-!33FZ߮:4 36 +w xJOnD# 4@mcl +މ&!&,Eiix) 8ʛC/ PoQ?~YvTn˜i>ld!0`a0ѱƦ%AJ,, Ʈ1%B g%XRtf$S :!O,c\*xHm*N&NJZ$n}$WuJ;W6 z85~6"u %>yuC8zfmģQN+!b`JS-o|g_7~ۿ|o߼?o7ͻ}?܀xy7~z}#9V|7ߞH?S/'o>,E_a*?#K>2ih=_M_^} _ W߿a?Joxͻo~ͷ7_ݏ?cGWh6 .Y@FVX`~M7߿=ٖ?ĭ'~W_ݗ|ǏGhRn,E$mϊ-hμpg0a0̿FDԿb~I/cWoO>y_߽|#w?˛w۷_.?߿wO endstream endobj 72 0 obj [/ICCBased 75 0 R] endobj 68 0 obj <>stream +HlK$Dy@qS3j Z Iz%c8B)X̎{;/ry{.!Z?ﹿz#!,ZywiUNb̨*PX{g;}VMOn)Ȣec}j SEB Ӭa\ow49=gG0#[9ZaNqf 6͘-d> ~cb롴ŮǑ 7C6r2*70(Va}|T6p=HrLcau@#c 1*lGmc 4cO!]cPtm&aJ nc!bYY\JXzuYC9-͓kӺ +JN P`n~Yh|B ; G'gZ5/pK1ݚi5g TȐ",t)4X-1`FN%[,͂le6y`\CHeNS4"=7 1!u:Ӻ԰7 w=~2՝ȣ'),Ik!sbkzt.7iĢN +`9*, `d\$ފ?W2&y) +eI*_-fVʱG:`iyõ_ +C)[hvy/Ϩ U*@|Ui+ɽK)qBopv5F%]RjQRE6NrA)u!O* DTR1j=G^0&G#;կ + YD%"lX$(7 TMA:(ZIQnj/[q+9TA22yFhy?CyڨnAk.jY^r4*bG6=`=hԝB~: rBhǞcmovM7 [D0p;p.CU]U?Qz +=ϐ89t#v\<$RlٶsZ.x{7d8W)\מ mc0~w%s-6.gt3eV+HqTͶXRp"^*5ӟnf,hrҀH=ˤF[O>q 8W౞'j8QR#y yi9vMJ=~sԡq/K-IDXe鹐ڶjH`YroPn@SLV4U%2)rKƮ:x]1WJg=;2w,4u5c7MO~lhLx D$?q$jSoVU#7=3M-}:ePv31<ꝟIegd6I+cCU<0ٝyժBT1O})"$3′]"]Щg?~+A7*O5E{oVTj^槎Mfgr; {f9>s{9>-IO$=pP'xjs"渪$ /êWOՃCNj%J9"0LEfT@Fr /N7;kЈz*rz`-q*54m|4*HX*J+ +<0;6ժ[qiN ]QMT/X qY96 bk L귷.eBߩ3۱RO(ߝ)D1F:`r~IBP%Sԣ+Re J*ܕnQYجrW >k$\6|6xmētWUpVmi-ҳ*sNzNNz]S}0[%AOVtKsDƕbc3S 2KٷkUV +VʟxxŒ5?Ù@t s :-ڌ\oj̣>=DQguhzlˀL߃c- CRKo='y endstream endobj 69 0 obj <> endobj 85 0 obj [/ICCBased 75 0 R] endobj 66 0 obj <>stream +H\A7 Eu +]dHiIY$qVU]MHoo緒~-ߎh{~???ǧKz|O%+M>純?x+/~|K +$l>uj|?Ns8#{iMs8.~ߎ)=+5ɞek8j.z?DkI-=id=dKt \&%镧d i&oYTjS:9[+"y)Yu+'W Z& }cw8,F9P5axeݣ[BiT;őв^vEPeo顅` L6u BM}S7 +DXd$SVMUxL-i# hp(6yO4bF; G܈GyÌ,:qjHcOZ5%ݖH 1Zڸmb +ݎ_22[lZ`61|9.L-Npeú:TY.Z#fA acl-@Gh Wj,,xB[01{5`l1/>!ƔĤ\{cGhY# "1χpr~nUr$~9}@v3 .s_( +;:?]z_>'Ɨ? endstream endobj 67 0 obj <> endobj 86 0 obj [/ICCBased 75 0 R] endobj 58 0 obj <>stream +Hݎ S"I, Hgͼ?HtcӦlIY,/__n/_[:V]~o_~<Җ6ny矏=~g-߯ؾ4b˿FFz9FXۊk;ڈ~lsUai-\o~oN;h2ʡe6͎>d6QkMJ?2zزsBR)LGa?o&726at/,uF;m,s#FXx@|үM|)f5]8'66'gY$6N'AOeփtk`9ힹ8AUTazJvىce]/*NZQ xDl@cvo\pH\#@ Y28XK#Z*v$kӌԱ!:I PgjCbApgt6J̍(5@gc.t=f\L ?~)q,# y >6.˾0阄D58To5؃ڎDTqA\='uvG=m pU9F?2ErWv4q)#g/f:Sp+ g8bgs XʑK|;mtdgBOw0q(PZ\j&8}qe4$y1>]HJneO$K~Qunf`G:xY]ϷF̀b3B9+F*O HO\A/4˔9q$i47akq`yZײ C(وqޢu.'1MRWnl;NԦRAF +#ۢ8U&(@ r =;zmMEJ +MjtuAG&X ǜ(D Hb"Pes1U /uJEA ΨׁAkFLƺLk4(Pc9HA.ia?>қ.+yշ[6HvgI0-&Qaj~Ǐ|??Ξ^g ׂg5[Z%z>-bysWR~9s"; + ֎LH9`]TV !\e>7ӤksLӤ {se]8m^ݪeS .鷟y! ij/{'$P"#P?B9pDs \V2JG~?Usyt.FC\+fd9] *FN,\ѤX9,3!,S9ވKv=nmOpL\Af# `,^t\ssE(LUM*"&NYҜե]a8fb"e0Ʋu)v9D<3FThKyFAj XO݆wĩkuDDNM(@9uO[ Nr;ڼ:zY L5?zUSlS.L9սGQCݫzg9ߞr@9Q 5ҪTAe<) +˛HIQMiyVq ~ K.%P7-*jTH]IOJyvb4|eCt>0 SJ(+`aB+ , / +GWτظqpw½ġd{Ins١sy(= ICj[k +&Z6j5'IyQ6%Gt9M0uOXjR75ĮR Lo:r!%|]Wvǔ[n͛G|:8Sb}NiFڸU2?0JM`;gN>y*Tk"NIy]7=zj9("45s#gLK1syMx=Dxh7H*: ;ԝ [ͷ eWam|^s~CT8_!h*{rh {Y$I\Y2\Z5 hs"AZl>SAå<΋tJ#0h}<ӥGatia䒭uQ&;A*~)np$O3]}^!0ںB;ͭBr[\΄3G~-Qy={R2Dd +ܤ3!]U\HGE*l4sgtQԖC.II"uSꒆ:ql0Fuh!ʁKXզ7o'T4Ju(TN/[(UvC Io@ Cߞp'ÇpR/4-p}zg4% +˰/ebIr}~[)|R@A>4ȮBuh/oDp'3eU2rJA DȻpjn )zHGu`_& ٬m@|٪^c޻$f4 .^.mj#Ms6$U|65\dsB>^JNͪ7ŵ}2ϫ}P n[TH"E%&6xiqёCrq4#4G<{Wh{r40trߣt~p;q/O2z# Dj [zyk}Hk* +Ub̷- ,i=k!UTr/IKS1嬙H +L/& Wr +r"4:}+ɯ MaKA\ТҚڎ=/&VE=,ƝcaΚZ~"Lҽ.=*PVOB+vR~v 4qzⲺAj= U_RNb%P&Jڇ46=0뒅oI*Yr%Ie+M8c[,(<8$`ۤ{X3£ꎵm kQ悖;B7QK !RMcJAь.6).q#9<\4OQK88O!2=O)IJmq9 +Bj(&oE^MTR7V7){EݎIiKARiP}ԋk AC&K^so T~p!=H/Ms2zN|K>)<ѕKS@?-g|@N묏S(i}ʱO<|H>jZS%dSŦX(q(*\@f*즬BFVyS?7EV2is󰾼=}'FBIdty>9dla{W;a?*UXۤ2д֝misWM4– ]SBć%[|Ah1(b~P[\vy?Cp>pw88R(y%}G~c^Y +EMai Բ<5rnےɴO@ZI&P -jEWZOu5url{L.wr3,Jz*uM)BG1zL X/ލ2zk;IP 랆"IT +/M628MTbhny evh+b6%B6q +om4mT +1yO!f8BE^7 \zH(_Ql|gƖ,cG[#{<Yr߈xS +5 +mpRI:DCtJjB֝WD3Upk3[``ql#:T|ΘO'oMEtQ͂ŖmjT$9H Cy+ /TWCxzht]Es"Bƍ'L|d$8<>."S@ՂXg% \Ө{+DON{^8 #o[ap.#㼞'eb@^XWH+Aa9x$j]e3ifں_юc}6EHoEl=S]h}3NaԖEaw?zdX HEZz߬rbTxYseux#p'վ=| .BaW坓yS?-s |3hsݻ~*&Aص՛a +)j_}{s*_|Oݫ!{[\Pskꎎ^?2 jM ~zD`2A$V])FkC|` q뱋1ÁIdGdE6>NMRRAmh"<{4k0L( };z˶Gb{ Sœuwd{L^pua-4$7mVkUFV%N_uY2G>^Whkw?,j*ZFr*!ALFCkGiڭfm+x*oSjTqaxV;PemX);f PnIUpz^[@(do.kd T\w|jJ XoFw KНQCy a:%y +?Sc ( mkOYEEB#0}>ꢶm=yF׀g/ ]*m҄vgq #]?U5Aik#jE$6 ^n?Bݏ endstream endobj 59 0 obj <> endobj 65 0 obj <>/ExtGState<>/ProcSet[/PDF/ImageC/ImageI]/XObject<>>>/Subtype/Form>>stream +q +/GS0 gs +1637 0 0 454 -91 2503 cm +/Im0 Do +Q + endstream endobj 88 0 obj <> endobj 91 0 obj <>stream +Hա 0dK *ݍ` Lt$>2=D2R@a(Y ! 0<B@cX !1t<:@cx c2d<:&@c 1tL:&@c c2dL12&@c  c2d<12&@c  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL:&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12{u6 @uP4lRF@5󄽬12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2dL12&@dȘ  c2d.@a2TL12&@dȘ  c2dL12&@dȘ  p"b2dL12&@dcL]L12ϓqx` c2d^MecLLy=`cLu&@h2.ǘ Ld\5oc2y7`ǘ +Oe8cLĻɸ g}|pcLsF&21ɸ 2L~0i1&ɸ 32L|0l1.qz0c\N?e`1.[K.e81.K[c3<۵q06bl  `6.?n&WeՑr./*e endstream endobj 89 0 obj [/Indexed 61 0 R 1 93 0 R] endobj 92 0 obj <>/Filter/FlateDecode/Height 454/Intent/RelativeColorimetric/Length 20778/Name/X/Subtype/Image/Type/XObject/Width 1637>>stream +Hg_iQb݀@  0DP$#quְO.hB3 ;c1c1c1c1cacšJOb1vBw1N)ct#01N5cT 0c ma@q0_3ed0;30؟М1)yd1v~JIi*s01\ )1/1c켵5L*a%1X;@TΜ1I$c*8^h|9 bI%rc}Gp#Ǚcǘb|!"1vbv&Rf?b\¸}q>4Oy1~'ڃ 3̜1.b¸|ǒ|ck}\xq3s|egC&K)cduXhI3'bCWǗDX +cqsw̜1b0-2 jkJw̱9`Gbȯ0c{ȱhh3f0foL1a/-5c.KL"3Qߘ,k" +Ѽe)60 nXǽXh3L1FŁt1XPXc1xU8dZcr!ƌuq\)ӕ3 nV;hkh3gB!Q&*Ǖc10͋BTc,y>Mˌ3ne.Q?c3&N#X^4-%UjcA˹mFCgf|Tfc\3Ĩc_/U:c{6(k58 I3ʜ11jXaE3 bJ|46B 99 e$SPpP#¨#/|{Ԩkb1̅VZ#ֈ4FrsF),\P cW# 1&mL|ƄÆ00F"hV]+c`e՚Hh0hdhfaטq)qTe8C&ј¢"- Q(]*mR*cm(gԜ12)shei\1Fq546jbd@fDx.tWc,8,'Z6B͈ 3֖ƆX]Mu #qđ!gcLm̘6C FFIrGXC=`1\X3n4.l Fvs0*cQN<5e\ʤBȄB֘=c:511J̝eV`y`~~!ZP-2 B(yƕy 4 +qsF3өnjKU&:ڔ2qc111 :2*(`fDȲ"[c1v%auqq5FgFG~3}=]mL*SW&7(S&y`)d1e֘65cnb& 3^m6c!}< >,@@g& 37՘ikiʔie2P&''yʤ2Ř!).q* \9(Ȉ7aUETyxkk zjzc,s,c1GY4ܓ9# ޼>+ʴ))$NLQb)G&a_1HIiYyNiP` ˊƈYXT<.Oϟ@/]b1vfma<ބ4 ̴a3LG(SW[]-/+-)|)?;eE GKWTVcz36!+fťU ̓϶ ,^~1X0RWygG7 fuei<ScZOQJiq$2)5ds1E+e*11ft!fyeц_^ +.pewݻw{{{勵1 B&6BB%h6ahfn:ʴ42Uъ+%2e2R&2d2 29pׯ_'ct2.307@#<3k+K 2f''ƆnAnGʊrLL<3e23SNDdLEW혱;0c,1/^yn3l*߾}/oc7}0́6Ҽ{{wDlh9$2\2Q=dZ;{13s1B F̮`U~迪1KgYu6Ј33*܌UUO2 +\LA\ mLk4]9?뻫498DgFҩRB j iқ@tPB PBST@΀Œꮻ/iyda2y˙lnAČ'̂/ZbeyY_Vp8g3&Y_^F, ,6:<$P&;9\䰘t@9w2lE!'$eRGNݡq˜pc?@/o*߿wÙ64ư>ܙgpfʌ B]̴,"4CȰ2w! ̷dy/ 8,2&.1%jtdj4e 1b_F¼{Dˇ?~?q8g!Eq@μ~oJizt_مLu92)q1a~bhpLB[oN bsl>iHxtl|RjFNAqY%ydzFTSsE=a b~F _>"X>}/83mha84` BvnjB52K^ʲₜԤUhogce'g`HL|9+JuNuqif2dKd_BǾ˾![+'QzBDd_RҢ2߿{(]]Wy_ޏu-'iln`d$446Is 0 c,+Ϲzym8[>y\K]EQNFz^q!Gf  s7BF^IUCK?{Ȥ_Vюim`Λe7po ?F5 ̓Q3LP 0v5=e]l,L Oji*#d$Dxwd8Hd|2=|¢:"odfixӗF 윂r:1@Ctnpj403cT& ';2aT_3fFzښjG'!*,g7 |mk +!dd9a`Lsr <M Ҙ{Cb`À0sHGq8}`8@,rfbнARFS}ʲhEG rs9vTYA!#&,̶|add~ƱsB_PDLRaYEcO61wq +p1)% +zͭ& ;xoxB63#rigК7xa1[o+`\HIx!24UeGα'@B62[H" Ȉ22rZ M-lxPâbe`Tݨkhf:юc'Hb,-=}smNiLMd1nTe]I + xq05<('Ȉ2<\$2?nF#B懷߻_ZFNIUC[O/0$":>19=dmݽL#a Zp8f^1 HЀ3s0fvw1S&=91>:"$H_O[CUINFz^q!'"_dD d42+;'7/1R3s K+aȴ0Y]=}ȘYX1@%j8/z6%`Rfl)SYZt1&2!$O #*$@ >@Fb߁CG4uNSݽ&\Nˢkn51;u1h b0Ht +o8?$A3h[f׻w;Mj Âݝ)'t4Ք:Od]N.=|$2 +G?yÇw)9jNAIEumC3up1O1H :dp87 ry,fsCmuEIAKqQTks';@"#,k:dddvFȈ!ddTHd,lxRC"S2s Kn52ڈ!3<:Fxf f]'vp8ƶ4h,1Pflt2mƺU)!T_36$2* +1]_ *2bR*k24ut <s1)5WTNoneu!3`bj혥h b0lYp͌ 1 ([ffj2]zyQ-35bL@?OWG[ SSZ*JI "Adz?2 J cfiw64B崬յ -rȌO=$!Ao8ۜ7LPC8C0C*pnfr2̖Yi.Dru4#Q}#G#/(B #odfiz>6J՜uΞ{LL/<~B?p81|Ilg(ăz:u7*K +r_I=dgif(G #"ly/22rJ$2+;g7Kr KnjjeuAVc #-%)2;m_2Jj:' ).>ԐLZ^q9o`hdlrz! /_10p8n3cK32+_.?)pnzrldh^^GLI[S Nh)H õ_h=2.Ԑ,Z~qEum#pht|rf~ V~#!aplhHfe~[yMѡvFcmuEq>-+5)>&"`m!~^]\_v@{ #2&cN,8 D9C &hF0qKwqAԂlZ,EPJ +-Sf3ml{nWp]o{hcO>o-]|e*2GWջ^=dڃp1Va +8.2P]OU_W[U^|i+/[֫/>cYVd[RE_UdfXY"KX.=3+;’c'=M~kȄ#1jXpR<4*3jX)o468V]QR@NvVfU+-}5%Vdf>"s1kμ<Xzݦ9y5O:5Ch,1vaN;RX4 +4"DdnK.:2,TyeϿZa˶]&2UN44z[;‘Xg|Ș (yD2֔EmMƆǪMdvm۲aWȼB;2$#ss/|DG +2XVd|hG71egƪ/2=]LgE[Ɗ:2,?w{"siwL;52~#q]{udJTdN:ڂp+1dI91(32ꌆC@{Io٨#ứ{Ӧ*;"*2w(&udb*2)C&_ Z2)"ӑ1Cޞ"3*2ν#Ro5G27@ֈO.Vґ)U9`"Td.+2/b"vcFV22.wLGXGD 8rTL^pLULVƵ&20Vd.jȼLʚxd;XW{Pp]1ETZIF͑"sPd6yϊL4tfJVFGFWFGSGypdҭȼg"G +kGGcEljdh 8-^ddΎF̵&2Wod%2F/9d~/Lr)7ldjG}&2*2ELdF&& LL lG&SG&oȜ19gE&u8ntNs&2gLLXd.S##"_ hxGfGS#s\:ny`ȔIVfȔLCg"12N&#3yȜ'2ഔȜN|dn#2w6N/ /2iD׎L"#*oGwȤDdb @?/2D']+cGW"'D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb ~g^,8苍o1!͚@V$h"d!Y0`fլԠ.ꢂ +AP-X@igΔvN +-%{<3C7?Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @/27"3@d #s !21^d֍'2}*2 u^d ud&Sd&>2LHL9LmD&2bd #1i4Ԧ?2GLј26ƌ"3{"s<ל|782.h2jGLӊ5829y-92O bԑ95\dzMdnZ:}4.2td2Md#0 Lre70421@<2y*2MdNqda#>2TlDF5FrL)2<0VdyDnj̬Ddj\nLGPGD&1e PHAVbȘ;tdnWM"2Y?ȼXy@*2?7z}~.;2Δ2TJ4F ;2]&2~^GPE&DGf*2o|"3@v3 K+ȴDTdzSƩ 41OjL|DtdZT?s2'@NoMdT;{td8yD;"SRqQG Ebvd̔ѕ3Ck ~ogĺ"`G[YGbEDu'2S"gRrd>\Gf=~ґ)P\inimk Ek8I QCFG;:Z[= uUd +td~:gV?IKSvryeڌYs,ґЊF+2?=WPRnE%#vuǧ >1ud-MVdK +يF+2,Z0w֌iHF'2Ud~OG7nݱgLqyUu \ Gb:2Ne$:H>1:2ݱH8qJvUW߳cёymNd7$2㑙j"/Udؽg/UU׺^_G&)cU&[O 7{Ģujʊ/=q;|iE L~kdGf9-ё3 [wg/U^o6[;C᨞2Ne * ec7Fh8o6\,+p޾eg,Y4ά<1&:TVGtw4%lGǎUTV#X:{D$d -cӳ̅exe^x+AP(.-1nkxdc;)- dRiaNfJBLDH AO[S]YQVR\LT䛑 99 QL,lݼ|B"'gT7SzF'gYKʬ  ?( +ڍs6o,g&G{5%9#B|m-L%Q!I!/CfG")#c`la0ˏ##%rm=O踤2veFeV^Bf0g4w( + -& $ +vd5דIeEyYiIq|ܜl-M zo^WQ‘9}6d~dNdΞ &.%K0qtSPRQ]Jvu 2&2K+̙@h  +Bd[ l2`uwQ)u%9Qa=]m,Lښ*RbΝȜFdsĐ9CFRVA"c`ln_\N"74u=CPeY̬g 456( +ڽEa1ư3:15=39IaBPmk_0afg&FhknGizr|LDhoWG UIK\x^XH"s~|[ +BdJ)kj[ۻ#G%f+SFkliǕ|12o:3d5% +B|{b1Pb#/qc[jHed&E[jk(I] +n!w;2>2\<.K*(ihY9yE+[PRN"{3LNMaj5x, +B|{ V35 qcɤ,xd"Â}<ݜ̌u4Ԕd.9 +d>}/Iy%54ut ĮLJFv^QiE (C 14P@  +Bvs< }3F1iT`LS=(/;#;2~cL00;BB ޑE@HC JB KgEd]Qw9y:{F̘>sVN偐4712;$23 +H{2#SE2GǯO3/?~?/$ cd{ n#c6T٩TWLM \mVf?24746 l.>AaQ)9WWxT6=\Z!?<3s\ g>|D矀 8V"|\1gpc cVsӲ#S(,̌ l&vCdn3@ԜǷ:8yxF$$eIWw@:6)ig z3 pZ 1l{ s^ ܘ(ccҁNȔ=e%'Dy{9;m2ނLE :2Iq!^"W';k% ! s!d~,J`k"E&MϦL}SkGw̢ju}pgޜ4gޝ hCtp8D0,wg sr.ܘU"iPwGkS=ud&FE.N+K3#.Š~Dod 92w6O`#ttq ON̈́+S\^U󴡹RFFl3N@[ІðȰoW 6"FlknxZSU^ G&359>:"4Qh#YȰ;#A滿B{ 2247465]Eb߀(te$Ej[SL+TkK3{ Hs`s ᴑfaafNK fmUyXWHLTXpX`g癛sLBFW_Cd2F&VֶN.peB#bdUV?F)3&S,3-pf?88lq8-l 0 ƺYPL(c?,+.ɀ#Ga1 `qF&f< L82iY K<NLN,h@흝]fp8F16lnYY&R:2xPʘȫ#cokM.ŠӐ1_̵2w2+`9ĕW/0$<*6!95#Taugͭ3Cґ1ʹ\>Ρq8=]˧0c#ҡ~gOkdg&'Fy{GF@C}-1Kdn_#Cg8\#teԕF|LIy壚'u 3 I3!MNNNHpoӗK,2,L6|`À0ݝ1 uOjU|fLDh:2|td ~EF@FA1+cE^wO/߀ЈDRIQIYEUu-L[{GWwO/@384<,6cи }VM2,ȈT:<<4twuVWUIHc#B|<#cGƘ<2t2%ѹ2ԕaWƄ2BGg7/ 8,T&+d ? ia*)ᴓf(6 #_0 LS#ILeyiq^niLdXpX($ ydԑzd'AQ,62|`61eeǏ>`a^>9xwonZcf'Ɔ}ݱ2U + L d@d0e +Us!gDZۣ]=I흻?z5ywHj|{Ac43X2 6 y +ɣX_5L{gȄϕ1ΐĐ Lrϔiv&eW׮ona3:<g^WA͛ cy7+R9:y}mu1&1h rg8e̙ ST\L:3e:cݽCqQf~q5̙C/DP۫W71N;/ˋ01b6֯]]^cGCݱN3d!SZ\$0d22CefV0fnܾ f3F%+c3˅'7C ^ džwV seԄcZj0d*ddO?2 (S>_[$tD\e.^_lna +4X4'2ˍ+;GeOڴ,_cjWW*cgȜ]d +tȔ UU745[ezã3s`f ̬o`l2@{{<|ndc}X3{{6FY1s3ӓ^kLsSC}mMuUHLI;d]c>L 2ʪ5uMQ&֭蘙,kfe + ݽlCm{1N3kƇsgww(076][]synFgc"Mu5*C)Cw^dL +auFP#6_acWS6Iu/`\a$1 $)f9#HckTSc\-/#!C̱ƜʜecaFQh F1j`1v>fk^#$͘$+3>ghDF0ֿ]8I11yYA|G3ʌ3R#m\qcbΫֿ]0v(1Ό9krc\dҔIeq@#kcCVFLfcBe1cqЈ4B1Xf;g3JXl|0˹<ڼc#F9ndoLfeRqQhTk cyY`a҈Ƥ+d&HX1X`҄x$3Bc1Ըظ3˽Rᅮ/ + +!&m|12q@cIbVA1ƾ{ǽh$#Sό Ƌ c/&1_cLFe^$1QJr3gt(Ao0/̯3siؔ##Uyi?Qb53ShҤIU/Z\/s3ibVY23wfMG6۽{S,1-Lؙ$4qmw% +Ө1{ICm v=d&LO4䯝4MLPUg +`@&qclB#7Ê'= +SL)4 /\ŠKyLL3j0^cv.*<͵}!!s|0 endstream endobj 93 0 obj <>stream + endstream endobj 90 0 obj <> endobj 94 0 obj <> endobj 95 0 obj [0.0 0.0 0.0] endobj 96 0 obj <>/ProcSet[/PDF/ImageB]/XObject<>>>/Subtype/Form>>stream +q +/GS0 gs +1637 0 0 454 -91 2503 cm +/Im0 Do +Q + endstream endobj 97 0 obj <> endobj 99 0 obj <>/Filter/FlateDecode/Height 454/Intent/RelativeColorimetric/Length 20778/Name/X/Subtype/Image/Type/XObject/Width 1637>>stream +Hg_iQb݀@  0DP$#quְO.hB3 ;c1c1c1c1cacšJOb1vBw1N)ct#01N5cT 0c ma@q0_3ed0;30؟М1)yd1v~JIi*s01\ )1/1c켵5L*a%1X;@TΜ1I$c*8^h|9 bI%rc}Gp#Ǚcǘb|!"1vbv&Rf?b\¸}q>4Oy1~'ڃ 3̜1.b¸|ǒ|ck}\xq3s|egC&K)cduXhI3'bCWǗDX +cqsw̜1b0-2 jkJw̱9`Gbȯ0c{ȱhh3f0foL1a/-5c.KL"3Qߘ,k" +Ѽe)60 nXǽXh3L1FŁt1XPXc1xU8dZcr!ƌuq\)ӕ3 nV;hkh3gB!Q&*Ǖc10͋BTc,y>Mˌ3ne.Q?c3&N#X^4-%UjcA˹mFCgf|Tfc\3Ĩc_/U:c{6(k58 I3ʜ11jXaE3 bJ|46B 99 e$SPpP#¨#/|{Ԩkb1̅VZ#ֈ4FrsF),\P cW# 1&mL|ƄÆ00F"hV]+c`e՚Hh0hdhfaטq)qTe8C&ј¢"- Q(]*mR*cm(gԜ12)shei\1Fq546jbd@fDx.tWc,8,'Z6B͈ 3֖ƆX]Mu #qđ!gcLm̘6C FFIrGXC=`1\X3n4.l Fvs0*cQN<5e\ʤBȄB֘=c:511J̝eV`y`~~!ZP-2 B(yƕy 4 +qsF3өnjKU&:ڔ2qc111 :2*(`fDȲ"[c1v%auqq5FgFG~3}=]mL*SW&7(S&y`)d1e֘65cnb& 3^m6c!}< >,@@g& 37՘ikiʔie2P&''yʤ2Ř!).q* \9(Ȉ7aUETyxkk zjzc,s,c1GY4ܓ9# ޼>+ʴ))$NLQb)G&a_1HIiYyNiP` ˊƈYXT<.Oϟ@/]b1vfma<ބ4 ̴a3LG(SW[]-/+-)|)?;eE GKWTVcz36!+fťU ̓϶ ,^~1X0RWygG7 fuei<ScZOQJiq$2)5ds1E+e*11ft!fyeц_^ +.pewݻw{{{勵1 B&6BB%h6ahfn:ʴ42Uъ+%2e2R&2d2 29pׯ_'ct2.307@#<3k+K 2f''ƆnAnGʊrLL<3e23SNDdLEW혱;0c,1/^yn3l*߾}/oc7}0́6Ҽ{{wDlh9$2\2Q=dZ;{13s1B F̮`U~迪1KgYu6Ј33*܌UUO2 +\LA\ mLk4]9?뻫498DgFҩRB j iқ@tPB PBST@΀Œꮻ/iyda2y˙lnAČ'̂/ZbeyY_Vp8g3&Y_^F, ,6:<$P&;9\䰘t@9w2lE!'$eRGNݡq˜pc?@/o*߿wÙ64ư>ܙgpfʌ B]̴,"4CȰ2w! ̷dy/ 8,2&.1%jtdj4e 1b_F¼{Dˇ?~?q8g!Eq@μ~oJizt_مLu92)q1a~bhpLB[oN bsl>iHxtl|RjFNAqY%ydzFTSsE=a b~F _>"X>}/83mha84` BvnjB52K^ʲₜԤUhogce'g`HL|9+JuNuqif2dKd_BǾ˾![+'QzBDd_RҢ2߿{(]]Wy_ޏu-'iln`d$446Is 0 c,+Ϲzym8[>y\K]EQNFz^q!Gf  s7BF^IUCK?{Ȥ_Vюim`Λe7po ?F5 ̓Q3LP 0v5=e]l,L Oji*#d$Dxwd8Hd|2=|¢:"odfixӗF 윂r:1@Ctnpj403cT& ';2aT_3fFzښjG'!*,g7 |mk +!dd9a`Lsr <M Ҙ{Cb`À0sHGq8}`8@,rfbнARFS}ʲhEG rs9vTYA!#&,̶|add~ƱsB_PDLRaYEcO61wq +p1)% +zͭ& ;xoxB63#rigК7xa1[o+`\HIx!24UeGα'@B62[H" Ȉ22rZ M-lxPâbe`Tݨkhf:юc'Hb,-=}smNiLMd1nTe]I + xq05<('Ȉ2<\$2?nF#B懷߻_ZFNIUC[O/0$":>19=dmݽL#a Zp8f^1 HЀ3s0fvw1S&=91>:"$H_O[CUINFz^q!'"_dD d42+;'7/1R3s K+aȴ0Y]=}ȘYX1@%j8/z6%`Rfl)SYZt1&2!$O #*$@ >@Fb߁CG4uNSݽ&\Nˢkn51;u1h b0Ht +o8?$A3h[f׻w;Mj Âݝ)'t4Ք:Od]N.=|$2 +G?yÇw)9jNAIEumC3up1O1H :dp87 ry,fsCmuEIAKqQTks';@"#,k:dddvFȈ!ddTHd,lxRC"S2s Kn52ڈ!3<:Fxf f]'vp8ƶ4h,1Pflt2mƺU)!T_36$2* +1]_ *2bR*k24ut <s1)5WTNoneu!3`bj혥h b0lYp͌ 1 ([ffj2]zyQ-35bL@?OWG[ SSZ*JI "Adz?2 J cfiw64B崬յ -rȌO=$!Ao8ۜ7LPC8C0C*pnfr2̖Yi.Dru4#Q}#G#/(B #odfiz>6J՜uΞ{LL/<~B?p81|Ilg(ăz:u7*K +r_I=dgif(G #"ly/22rJ$2+;g7Kr KnjjeuAVc #-%)2;m_2Jj:' ).>ԐLZ^q9o`hdlrz! /_10p8n3cK32+_.?)pnzrldh^^GLI[S Nh)H õ_h=2.Ԑ,Z~qEum#pht|rf~ V~#!aplhHfe~[yMѡvFcmuEq>-+5)>&"`m!~^]\_v@{ #2&cN,8 D9C &hF0qKwqAԂlZ,EPJ +-Sf3ml{nWp]o{hcO>o-]|e*2GWջ^=dڃp1Va +8.2P]OU_W[U^|i+/[֫/>cYVd[RE_UdfXY"KX.=3+;’c'=M~kȄ#1jXpR<4*3jX)o468V]QR@NvVfU+-}5%Vdf>"s1kμ<Xzݦ9y5O:5Ch,1vaN;RX4 +4"DdnK.:2,TyeϿZa˶]&2UN44z[;‘Xg|Ș (yD2֔EmMƆǪMdvm۲aWȼB;2$#ss/|DG +2XVd|hG71egƪ/2=]LgE[Ɗ:2,?w{"siwL;52~#q]{udJTdN:ڂp+1dI91(32ꌆC@{Io٨#ứ{Ӧ*;"*2w(&udb*2)C&_ Z2)"ӑ1Cޞ"3*2ν#Ro5G27@ֈO.Vґ)U9`"Td.+2/b"vcFV22.wLGXGD 8rTL^pLULVƵ&20Vd.jȼLʚxd;XW{Pp]1ETZIF͑"sPd6yϊL4tfJVFGFWFGSGypdҭȼg"G +kGGcEljdh 8-^ddΎF̵&2Wod%2F/9d~/Lr)7ldjG}&2*2ELdF&& LL lG&SG&oȜ19gE&u8ntNs&2gLLXd.S##"_ hxGfGS#s\:ny`ȔIVfȔLCg"12N&#3yȜ'2ഔȜN|dn#2w6N/ /2iD׎L"#*oGwȤDdb @?/2D']+cGW"'D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb ~g^,8苍o1!͚@V$h"d!Y0`fլԠ.ꢂ +AP-X@igΔvN +-%{<3C7?Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @ !21D "Cdb @/27"3@d #s !21^d֍'2}*2 u^d ud&Sd&>2LHL9LmD&2bd #1i4Ԧ?2GLј26ƌ"3{"s<ל|782.h2jGLӊ5829y-92O bԑ95\dzMdnZ:}4.2td2Md#0 Lre70421@<2y*2MdNqda#>2TlDF5FrL)2<0VdyDnj̬Ddj\nLGPGD&1e PHAVbȘ;tdnWM"2Y?ȼXy@*2?7z}~.;2Δ2TJ4F ;2]&2~^GPE&DGf*2o|"3@v3 K+ȴDTdzSƩ 41OjL|DtdZT?s2'@NoMdT;{td8yD;"SRqQG Ebvd̔ѕ3Ck ~ogĺ"`G[YGbEDu'2S"gRrd>\Gf=~ґ)P\inimk Ek8I QCFG;:Z[= uUd +td~:gV?IKSvryeڌYs,ґЊF+2?=WPRnE%#vuǧ >1ud-MVdK +يF+2,Z0w֌iHF'2Ud~OG7nݱgLqyUu \ Gb:2Ne$:H>1:2ݱH8qJvUW߳cёymNd7$2㑙j"/Udؽg/UU׺^_G&)cU&[O 7{Ģujʊ/=q;|iE L~kdGf9-ё3 [wg/U^o6[;C᨞2Ne * ec7Fh8o6\,+p޾eg,Y4ά<1&:TVGtw4%lGǎUTV#X:{D$d -cӳ̅exe^x+AP(.-1nkxdc;)- dRiaNfJBLDH AO[S]YQVR\LT䛑 99 QL,lݼ|B"'gT7SzF'gYKʬ  ?( +ڍs6o,g&G{5%9#B|m-L%Q!I!/CfG")#c`la0ˏ##%rm=O踤2veFeV^Bf0g4w( + -& $ +vd5דIeEyYiIq|ܜl-M zo^WQ‘9}6d~dNdΞ &.%K0qtSPRQ]Jvu 2&2K+̙@h  +Bd[ l2`uwQ)u%9Qa=]m,Lښ*RbΝȜFdsĐ9CFRVA"c`ln_\N"74u=CPeY̬g 456( +ڽEa1ư3:15=39IaBPmk_0afg&FhknGizr|LDhoWG UIK\x^XH"s~|[ +BdJ)kj[ۻ#G%f+SFkliǕ|12o:3d5% +B|{b1Pb#/qc[jHed&E[jk(I] +n!w;2>2\<.K*(ihY9yE+[PRN"{3LNMaj5x, +B|{ V35 qcɤ,xd"Â}<ݜ̌u4Ԕd.9 +d>}/Iy%54ut ĮLJFv^QiE (C 14P@  +Bvs< }3F1iT`LS=(/;#;2~cL00;BB ޑE@HC JB KgEd]Qw9y:{F̘>sVN偐4712;$23 +H{2#SE2GǯO3/?~?/$ cd{ n#c6T٩TWLM \mVf?24746 l.>AaQ)9WWxT6=\Z!?<3s\ g>|D矀 8V"|\1gpc cVsӲ#S(,̌ l&vCdn3@ԜǷ:8yxF$$eIWw@:6)ig z3 pZ 1l{ s^ ܘ(ccҁNȔ=e%'Dy{9;m2ނLE :2Iq!^"W';k% ! s!d~,J`k"E&MϦL}SkGw̢ju}pgޜ4gޝ hCtp8D0,wg sr.ܘU"iPwGkS=ud&FE.N+K3#.Š~Dod 92w6O`#ttq ON̈́+S\^U󴡹RFFl3N@[ІðȰoW 6"FlknxZSU^ G&359>:"4Qh#YȰ;#A滿B{ 2247465]Eb߀(te$Ej[SL+TkK3{ Hs`s ᴑfaafNK fmUyXWHLTXpX`g癛sLBFW_Cd2F&VֶN.peB#bdUV?F)3&S,3-pf?88lq8-l 0 ƺYPL(c?,+.ɀ#Ga1 `qF&f< L82iY K<NLN,h@흝]fp8F16lnYY&R:2xPʘȫ#cokM.ŠӐ1_̵2w2+`9ĕW/0$<*6!95#Taugͭ3Cґ1ʹ\>Ρq8=]˧0c#ҡ~gOkdg&'Fy{GF@C}-1Kdn_#Cg8\#teԕF|LIy壚'u 3 I3!MNNNHpoӗK,2,L6|`À0ݝ1 uOjU|fLDh:2|td ~EF@FA1+cE^wO/߀ЈDRIQIYEUu-L[{GWwO/@384<,6cи }VM2,ȈT:<<4twuVWUIHc#B|<#cGƘ<2t2%ѹ2ԕaWƄ2BGg7/ 8,T&+d ? ia*)ᴓf(6 #_0 LS#ILeyiq^niLdXpX($ ydԑzd'AQ,62|`61eeǏ>`a^>9xwonZcf'Ɔ}ݱ2U + L d@d0e +Us!gDZۣ]=I흻?z5ywHj|{Ac43X2 6 y +ɣX_5L{gȄϕ1ΐĐ Lrϔiv&eW׮ona3:<g^WA͛ cy7+R9:y}mu1&1h rg8e̙ ST\L:3e:cݽCqQf~q5̙C/DP۫W71N;/ˋ01b6֯]]^cGCݱN3d!SZ\$0d22CefV0fnܾ f3F%+c3˅'7C ^ džwV seԄcZj0d*ddO?2 (S>_[$tD\e.^_lna +4X4'2ˍ+;GeOڴ,_cjWW*cgȜ]d +tȔ UU745[ezã3s`f ̬o`l2@{{<|ndc}X3{{6FY1s3ӓ^kLsSC}mMuUHLI;d]c>L 2ʪ5uMQ&֭蘙,kfe + ݽlCm{1N3kƇsgww(076][]synFgc"Mu5*C)Cw^dL +auFP#6_acWS6Iu/`\a$1 $)f9#HckTSc\-/#!C̱ƜʜecaFQh F1j`1v>fk^#$͘$+3>ghDF0ֿ]8I11yYA|G3ʌ3R#m\qcbΫֿ]0v(1Ό9krc\dҔIeq@#kcCVFLfcBe1cqЈ4B1Xf;g3JXl|0˹<ڼc#F9ndoLfeRqQhTk cyY`a҈Ƥ+d&HX1X`҄x$3Bc1Ըظ3˽Rᅮ/ + +!&m|12q@cIbVA1ƾ{ǽh$#Sό Ƌ c/&1_cLFe^$1QJr3gt(Ao0/̯3siؔ##Uyi?Qb53ShҤIU/Z\/s3ibVY23wfMG6۽{S,1-Lؙ$4qmw% +Ө1{ICm v=d&LO4䯝4MLPUg +`@&qclB#7Ê'= +SL)4 /\ŠKyLL3j0^cv.*<͵}!!s|0 endstream endobj 98 0 obj <> endobj 64 0 obj <> endobj 100 0 obj <> endobj 101 0 obj <>stream +HV{X?gfvXTE ,"eY5DajQ+(|Q"Q"BX4+H5JSϪ(`hbTDZjl?z̽wY" zC>4ifDj3G;u$d&gٷ8 Y0>+,=-9sbBF ezgv3-H.0<ɫ0P.MLsei %3qc}fMY70 ǰl>"xcLG~Vg0JzN7ޯ%Dp?ͩ0|i .+Pz)AL5s`9Va0=̞Q(=>JOTV*?5}jO@:@=Y=_֥Nk7c:F(yB˳X7P)++6_(ekT + +z]FHb)QX!<<ʮ¸L {bm~3&}SXV-YS._P_1ndիz)kUT~-qF>PJ>`_&JJOEi!.E;/cSN]u޼ˣ;@+03,}OVTldSeVR-yZ EO G>T7ʮ~2$l^:G䋽8h[USYii⚵ sn9`]k_ +lsy=']6NIM42-(77Xw}6n.3]R^n2UnxmVsaiu IÐ`#1mӷ*4NS ?zLc1zVX\\81PjdSNI3j7r’ni;Ophw1q!(z[Q*l})y +PJtY>ُ5- +iOo?5N1!V{Dmmԕm8Hux-Jԃȩ^ +7Jr^jJs#7Xk1Ż+̻onyi@@J3mwP!T.dtcU]8I2Kz*xIi"=aiFbβvuitqo4 +.MɐN#lfwby+v(ґ[R:Όщ>4ǬB0wv[os}mWAesoڲRϙ7 W6gz4{'xť&*nhH4gN!pvݺWlAccF5oLr/^KVm4ΞQM*(#}u~:wj +6l7u}`LŠDQ\2>P+ҡMj}g&NFM$Z%NGuZ8mMtns.Gʜ|w{Cѵu &TϨpaоӄZQ 1%SǓW8 ֯oZ{?k:+#N|_(%xz #.uF筿7G :-⑟vpu9k׾h6Zmw[p6nz=mhO奯RZimE yLaԁ4w/SFsBvL+IIm{7;2bEHdh -bg}ˋz'U;R=Bb%%3k|9a8$#l?2@jBHJvvu[n ֭m߱vnǻSZc3G&C&xK3.2U?s[\8sg;>-`G?~Zu<ͩ^>yIaU$7nQ6]qlKgOXpњByqYl۴|W"jO#r*΀ tvVAKܩ"PFq+*}^)֋NUF5_`, 1}-OF>csLxT<+ZRWx +L=R Px.Џaf>dKaӐ0@z`C$].pP#M.5CD +u-Vػ9"S4Rݟ 2EPsc`ՌۀFPPw9iGN$Vh@L5{ ۟ysGFkD\'ҁt="RCHxq+&D$Pvxz7!;<| 7iDR}O}wy0gM߫3˰!6c ijJY!$J_fz$Qc_dː69ύD皸(go-HYoc+?\zRt(SQwpVbPm&kDP~(Bo\\ +yZZŪ;!fHB})޾tfgȟy}yR'gRι_|e`QIU>^~kZf%_ (?oQ-7[?٢+F ókfiWzljUzY#gV8&'Thk Y)-z[Z8kUƅ$i嘧+"( ?i7Kd(zt--OW׬p1VJSy?6c Ӷeg, c؆s;p.|\ 9$Wj|w᧸F< <]{7n\; ğE^‹xm r?pִ0I.+E|.S.N v"\Kp).7V܆7܉{p/xqxO)o)x|]@AE2DƩLh&&\TOM4n.KR~^NWЕt]Mеt]O7ЍtLЭ&_t'Ew=t/G az=NOГ=Mгg&IgsFx{_P|{wkIB~$6ֿ.KFr*5N܎5ek_i|&6 myƔhKe1+Hc2CHU..S Y|UyF To[}Z_ۨ =̭=rfFJ#Ůhݑ G-lv`="&sC76bQѶ햚0ZFIܢS- F6p_OMZfƕ=ǫG ==IK+_@oDL,h4Qv[MhG 7S'HkAEosj 'AѪcH9cxcxݾi(Z1LW׀0CzZaIWZl0R*UezTrF ӭ#B\o=69QGDJ-cŰ_+tEvK̕H;AM$RpB%c6f')7b6#fvJZڊ2H{y^xFagsgFrv%W[<R-KlMif6\O#=f{u5x:ڶQpҖZIu]5[f&#M> endobj 87 0 obj [/ICCBased 75 0 R] endobj 5 0 obj <> endobj 26 0 obj [/View/Design] endobj 27 0 obj <>>> endobj 57 0 obj [56 0 R] endobj 102 0 obj <> endobj xref 0 103 0000000004 65535 f +0000000016 00000 n +0000000159 00000 n +0000052682 00000 n +0000000000 00000 f +0000498128 00000 n +0000000000 00000 f +0000052752 00000 n +0000053184 00000 n +0000053543 00000 n +0000053903 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000498198 00000 n +0000498229 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000056673 00000 n +0000498314 00000 n +0000436975 00000 n +0000445245 00000 n +0000059656 00000 n +0000056973 00000 n +0000056860 00000 n +0000497979 00000 n +0000490554 00000 n +0000445307 00000 n +0000435826 00000 n +0000436878 00000 n +0000433230 00000 n +0000435729 00000 n +0000054265 00000 n +0000056611 00000 n +0000433195 00000 n +0000056744 00000 n +0000056775 00000 n +0000057008 00000 n +0000059730 00000 n +0000060014 00000 n +0000061335 00000 n +0000069710 00000 n +0000135298 00000 n +0000200886 00000 n +0000266474 00000 n +0000332062 00000 n +0000397650 00000 n +0000435791 00000 n +0000436940 00000 n +0000498093 00000 n +0000445608 00000 n +0000447735 00000 n +0000468863 00000 n +0000445671 00000 n +0000447778 00000 n +0000468809 00000 n +0000468977 00000 n +0000469040 00000 n +0000469070 00000 n +0000469338 00000 n +0000490442 00000 n +0000469411 00000 n +0000490962 00000 n +0000491200 00000 n +0000498339 00000 n +trailer <]>> startxref 498526 %%EOF \ No newline at end of file -- cgit v1.2.1 From 84934da234f112a3c15e17293a3964275fc47982 Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Wed, 29 Jun 2016 13:53:12 -0300 Subject: Generate Header and update Readme --- README.md | 2 +- logo/async-logo_readme.jpg | Bin 0 -> 74404 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 logo/async-logo_readme.jpg diff --git a/README.md b/README.md index 6e07343..cce3244 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Async.js +![Async Logo](https://raw.githubusercontent.com/ivanseidel/async/master/logo/async-logo_readme.svg) [![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async) [![NPM version](https://img.shields.io/npm/v/async.svg)](https://www.npmjs.com/package/async) diff --git a/logo/async-logo_readme.jpg b/logo/async-logo_readme.jpg new file mode 100644 index 0000000..da17973 Binary files /dev/null and b/logo/async-logo_readme.jpg differ -- cgit v1.2.1 From fb980004ac338ee24d5d27eb276d63fa086071cd Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Wed, 29 Jun 2016 13:53:29 -0300 Subject: create favicon .png and .ico --- logo/async-logo_favicon.png | Bin 0 -> 2516 bytes logo/favicon.ico | Bin 0 -> 22382 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 logo/async-logo_favicon.png create mode 100755 logo/favicon.ico diff --git a/logo/async-logo_favicon.png b/logo/async-logo_favicon.png new file mode 100644 index 0000000..0c47303 Binary files /dev/null and b/logo/async-logo_favicon.png differ diff --git a/logo/favicon.ico b/logo/favicon.ico new file mode 100755 index 0000000..4a90dff Binary files /dev/null and b/logo/favicon.ico differ -- cgit v1.2.1 From da21809e6879e0ce915c7919f24853b074a13383 Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Wed, 29 Jun 2016 13:53:39 -0300 Subject: Ignore logo folder by npm --- .npmignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.npmignore b/.npmignore index 4274f79..ff2c636 100644 --- a/.npmignore +++ b/.npmignore @@ -1,4 +1,5 @@ lib +logo scripts support/dependencies.json support/module_template.md -- cgit v1.2.1 From 01471b98ac136f23ff15635549a0eb1147ab9858 Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Wed, 29 Jun 2016 13:54:52 -0300 Subject: fix filename --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cce3244..b3f795a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Async Logo](https://raw.githubusercontent.com/ivanseidel/async/master/logo/async-logo_readme.svg) +![Async Logo](https://raw.githubusercontent.com/ivanseidel/async/master/logo/async-logo_header.jpg) [![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async) [![NPM version](https://img.shields.io/npm/v/async.svg)](https://www.npmjs.com/package/async) -- cgit v1.2.1 From 1166fd5a344de9ea78e80fe63af1bad0e764c7ea Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Wed, 29 Jun 2016 13:55:27 -0300 Subject: Fix filename (again) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b3f795a..b98b91c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Async Logo](https://raw.githubusercontent.com/ivanseidel/async/master/logo/async-logo_header.jpg) +![Async Logo](https://raw.githubusercontent.com/ivanseidel/async/master/logo/async-logo_readme.jpg) [![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async) [![NPM version](https://img.shields.io/npm/v/async.svg)](https://www.npmjs.com/package/async) -- cgit v1.2.1 From 674692da0708eb89d163d0c0967693cb7915cdeb Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Wed, 29 Jun 2016 15:01:56 -0300 Subject: Switch github content URL's to kaolin --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b98b91c..4000fdd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Async Logo](https://raw.githubusercontent.com/ivanseidel/async/master/logo/async-logo_readme.jpg) +![Async Logo](https://raw.githubusercontent.com/caolan/async/master/logo/async-logo_readme.jpg) [![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async) [![NPM version](https://img.shields.io/npm/v/async.svg)](https://www.npmjs.com/package/async) -- cgit v1.2.1 From ec7d0ad8089b71430198725e651cec9553d68bd7 Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Wed, 29 Jun 2016 15:34:25 -0300 Subject: Include logo in .svg --- logo/async-logo.svg | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 logo/async-logo.svg diff --git a/logo/async-logo.svg b/logo/async-logo.svg new file mode 100644 index 0000000..d108be7 --- /dev/null +++ b/logo/async-logo.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + -- cgit v1.2.1 From bb7f849a6fcd85697fd7536dd93fa84b2a09f1b7 Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Wed, 29 Jun 2016 18:28:03 -0400 Subject: displaying logo on site --- support/jsdoc/jsdoc-custom.css | 12 +++++++++++- support/jsdoc/jsdoc-fix-html.js | 4 ++-- support/jsdoc/navbar.html | 6 ++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index a87a406..9cc2d3f 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -21,11 +21,13 @@ body { } body nav { + float: none; position: fixed; top: 50px; + left: 0px; + bottom: 0px; padding-left: 12px; overflow-y: auto; - height: calc(100% - 50px); } /* fix bootstrap's styling */ @@ -38,6 +40,14 @@ footer { margin-left: 0px; } +.navbar-brand { + padding: 5px; +} + +.navbar-brand img { + height: 40px; +} + #main { position: fixed; float: none; diff --git a/support/jsdoc/jsdoc-fix-html.js b/support/jsdoc/jsdoc-fix-html.js index bf7f6eb..667d869 100644 --- a/support/jsdoc/jsdoc-fix-html.js +++ b/support/jsdoc/jsdoc-fix-html.js @@ -6,7 +6,6 @@ var $ = require('cheerio'); var _ = require('lodash'); var docsDir = path.join(__dirname, '../../docs'); - var pageTitle = 'Methods:'; var docFilename = 'docs.html'; @@ -18,7 +17,6 @@ var HTMLFileBegin = '\n\n\n'; var HTMLFileHeadBodyJoin = '\n'; var HTMLFileEnd = ''; - var additionalFooterText = ' Documentation has been modified from the original. ' + ' For more information, please see the async repository.'; @@ -184,6 +182,8 @@ function fixModuleLinks(files, callback) { fs.copySync(path.join(__dirname, '../../dist/async.js'), path.join(docsDir, 'scripts/async.js'), { clobber: true }); fs.copySync(path.join(__dirname, './jsdoc-custom.js'), path.join(docsDir, 'scripts/jsdoc-custom.js'), { clobber: true }); fs.copySync(path.join(__dirname, './jsdoc-custom.css'), path.join(docsDir, 'styles/jsdoc-custom.css'), { clobber: true }); +fs.copySync(path.join(__dirname, '..', '..', 'logo', 'favicon.ico'), path.join(docsDir, 'favicon.ico'), { clobber: true }); +fs.copySync(path.join(__dirname, '..', '..', 'logo', 'async-logo.svg'), path.join(docsDir, 'img', 'async-logo.svg'), { clobber: true }); fs.readdir(docsDir, function(err, files) { if (err) { diff --git a/support/jsdoc/navbar.html b/support/jsdoc/navbar.html index e23b12e..86e2792 100644 --- a/support/jsdoc/navbar.html +++ b/support/jsdoc/navbar.html @@ -1,6 +1,8 @@ - \ No newline at end of file + -- cgit v1.2.1 From 209fb1eb12342cc6efe80a600d8a2566f806e28a Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Wed, 29 Jun 2016 18:46:41 -0400 Subject: force favicon refresh --- support/jsdoc/head-data.html | 1 + 1 file changed, 1 insertion(+) diff --git a/support/jsdoc/head-data.html b/support/jsdoc/head-data.html index 6ecc3eb..c8bd13c 100644 --- a/support/jsdoc/head-data.html +++ b/support/jsdoc/head-data.html @@ -1,6 +1,7 @@ + -- cgit v1.2.1 From f42ad6ef775aa9553aeb42b9d25147f0e94b32be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Aldana?= Date: Thu, 30 Jun 2016 01:52:11 -0500 Subject: First commit, reflectAll allow to accept object of functions --- lib/reflectAll.js | 13 +++++++- mocha_test/parallel.js | 84 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/lib/reflectAll.js b/lib/reflectAll.js index ac9ea06..d1ad247 100644 --- a/lib/reflectAll.js +++ b/lib/reflectAll.js @@ -1,4 +1,5 @@ import reflect from './reflect'; +import isArray from 'lodash/isArray'; /** * A helper function that wraps an array of functions with reflect. @@ -40,5 +41,15 @@ import reflect from './reflect'; * }); */ export default function reflectAll(tasks) { - return tasks.map(reflect); + var results; + if (isArray(tasks)) { + results = tasks.map(reflect); + } else { + var keys = Object.keys(tasks); + results = {}; + keys.forEach(function(key) { + results[key] = reflect.call(this, tasks[key]) + }); + } + return results; } diff --git a/mocha_test/parallel.js b/mocha_test/parallel.js index 5362491..fe99676 100644 --- a/mocha_test/parallel.js +++ b/mocha_test/parallel.js @@ -4,7 +4,7 @@ var assert = require('assert'); var isBrowser = require('./support/is_browser'); var getFunctionsObject = require('./support/get_function_object'); -describe('parallel', function() { +describe.only('parallel', function() { it('parallel', function(done) { var call_order = []; @@ -241,6 +241,88 @@ describe('parallel', function() { }); }); + it('parallel object with reflect all (values and errors)', function(done) { + var tasks = { + one: function(callback) { + setTimeout(function() { + callback(null, 'one'); + }, 200); + }, + two: function(callback) { + callback('two'); + }, + three: function(callback) { + setTimeout(function() { + callback(null, 'three'); + }, 100); + } + }; + + async.parallel(async.reflectAll(tasks), function(err, results) { + expect(results).to.eql({ + one: { value: 'one' }, + two: { error: 'two' }, + three: { value: 'three' } + }); + done(); + }) + }); + + it('parallel empty object with reflect all', function(done) { + var tasks = {}; + + async.parallel(async.reflectAll(tasks), function(err, results) { + expect(results).to.eql({}); + done(); + }) + }); + + it('parallel empty object with reflect all (errors)', function(done) { + var tasks = { + one: function(callback) { + callback('one'); + }, + two: function(callback) { + callback('two'); + }, + three: function(callback) { + callback('three'); + } + }; + + async.parallel(async.reflectAll(tasks), function(err, results) { + expect(results).to.eql({ + one: { error: 'one' }, + two: { error: 'two' }, + three: { error: 'three' } + }); + done(); + }) + }); + + it('parallel empty object with reflect all (values)', function(done) { + var tasks = { + one: function(callback) { + callback(null, 'one'); + }, + two: function(callback) { + callback(null, 'two'); + }, + three: function(callback) { + callback(null, 'three'); + } + }; + + async.parallel(async.reflectAll(tasks), function(err, results) { + expect(results).to.eql({ + one: { value: 'one' }, + two: { value: 'two' }, + three: { value: 'three' } + }); + done(); + }) + }); + it('parallel does not continue replenishing after error', function(done) { var started = 0; var arr = [ -- cgit v1.2.1 From 2564a54efc7bd97cf4ff0b8629ecda66741a1142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Aldana?= Date: Thu, 30 Jun 2016 01:59:33 -0500 Subject: Remove only from parallel test --- mocha_test/parallel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mocha_test/parallel.js b/mocha_test/parallel.js index fe99676..bad98af 100644 --- a/mocha_test/parallel.js +++ b/mocha_test/parallel.js @@ -4,7 +4,7 @@ var assert = require('assert'); var isBrowser = require('./support/is_browser'); var getFunctionsObject = require('./support/get_function_object'); -describe.only('parallel', function() { +describe('parallel', function() { it('parallel', function(done) { var call_order = []; -- cgit v1.2.1 From d9c8d5e486d2fd63246c131a1ea07e72e0504361 Mon Sep 17 00:00:00 2001 From: Hubert Argasinski Date: Thu, 30 Jun 2016 19:01:39 -0400 Subject: accidentially undid toc fix --- support/jsdoc/jsdoc-custom.css | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index 9cc2d3f..8d988d4 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -21,13 +21,11 @@ body { } body nav { - float: none; position: fixed; top: 50px; - left: 0px; - bottom: 0px; padding-left: 12px; overflow-y: auto; + height: calc(100% - 50px); } /* fix bootstrap's styling */ -- cgit v1.2.1 From b83ce9494533141505eebff25ef57d66b72ba5ac Mon Sep 17 00:00:00 2001 From: Alexander Early Date: Thu, 30 Jun 2016 16:27:48 -0700 Subject: add docs publishing script. Related to #1202 --- Makefile | 6 ++++++ package.json | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 701f27d..e180aa9 100644 --- a/Makefile +++ b/Makefile @@ -117,3 +117,9 @@ release-major release-minor release-patch release-prerelease: all $(MAKE) build-es-config cd build/ && npm publish cd build-es/ && npm publish + $(MAKE) doc + +.PHONY: doc +doc: + npm run-script jsdoc + gh-pages-deploy diff --git a/package.json b/package.json index 250e062..16e9f7e 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "esdoc": "^0.4.7", "eslint": "^2.11.1", "fs-extra": "^0.26.7", + "gh-pages-deploy": "^0.4.2", "jsdoc": "^3.4.0", "karma": "^0.13.2", "karma-browserify": "^4.2.1", @@ -70,5 +71,8 @@ "mocha-test": "npm run mocha-node-test && npm run mocha-browser-test", "test": "npm run-script lint && npm run mocha-node-test" }, - "license": "MIT" + "license": "MIT", + "gh-pages-deploy": { + "staticpath": "docs" + } } -- cgit v1.2.1 From a42facc6678552277a75c14c0cd78bcb14f714ac Mon Sep 17 00:00:00 2001 From: Alexander Early Date: Thu, 30 Jun 2016 16:34:30 -0700 Subject: make docs publishing fail if there are uncommitted changes --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index e180aa9..158a5db 100644 --- a/Makefile +++ b/Makefile @@ -121,5 +121,7 @@ release-major release-minor release-patch release-prerelease: all .PHONY: doc doc: + git diff-files --quiet # fail if unstanged changes + git diff-index --quiet HEAD # fail if uncommited changes npm run-script jsdoc gh-pages-deploy -- cgit v1.2.1 From 399d74a372b7c5779ea70f470bbffc13806a16a1 Mon Sep 17 00:00:00 2001 From: Alexander Early Date: Thu, 30 Jun 2016 16:38:23 -0700 Subject: remove unused esdoc config --- package.json | 2 -- support/esdoc.json | 6 ------ 2 files changed, 8 deletions(-) delete mode 100644 support/esdoc.json diff --git a/package.json b/package.json index 16e9f7e..d395a03 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,6 @@ "cheerio": "^0.20.0", "coveralls": "^2.11.2", "es6-promise": "^2.3.0", - "esdoc": "^0.4.7", "eslint": "^2.11.1", "fs-extra": "^0.26.7", "gh-pages-deploy": "^0.4.2", @@ -63,7 +62,6 @@ "scripts": { "coverage": "nyc npm test && nyc report", "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", - "doc": "esdoc -c ./support/esdoc.json", "jsdoc": "jsdoc -c ./support/jsdoc/jsdoc.json && node support/jsdoc/jsdoc-fix-html.js", "lint": "eslint lib/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ karma.conf.js", "mocha-browser-test": "karma start", diff --git a/support/esdoc.json b/support/esdoc.json deleted file mode 100644 index 215d29a..0000000 --- a/support/esdoc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "source": "./lib", - "destination": "./docs", - "excludes": ["internal"], - "scripts": ["./dist/async.js"] -} -- cgit v1.2.1 From f6e88771c260342332a08128e5b3eb141a757622 Mon Sep 17 00:00:00 2001 From: Alexander Early Date: Thu, 30 Jun 2016 16:51:53 -0700 Subject: copy minami theme into project --- .gitignore | 1 + package.json | 1 - support/jsdoc/jsdoc.json | 2 +- support/jsdoc/theme/LICENSE | 61 + support/jsdoc/theme/README.md | 77 + support/jsdoc/theme/publish.js | 660 +++++++ .../theme/static/fonts/OpenSans-Bold-webfont.eot | Bin 0 -> 19544 bytes .../theme/static/fonts/OpenSans-Bold-webfont.svg | 1830 +++++++++++++++++++ .../theme/static/fonts/OpenSans-Bold-webfont.woff | Bin 0 -> 22432 bytes .../static/fonts/OpenSans-BoldItalic-webfont.eot | Bin 0 -> 20133 bytes .../static/fonts/OpenSans-BoldItalic-webfont.svg | 1830 +++++++++++++++++++ .../static/fonts/OpenSans-BoldItalic-webfont.woff | Bin 0 -> 23048 bytes .../theme/static/fonts/OpenSans-Italic-webfont.eot | Bin 0 -> 20265 bytes .../theme/static/fonts/OpenSans-Italic-webfont.svg | 1830 +++++++++++++++++++ .../static/fonts/OpenSans-Italic-webfont.woff | Bin 0 -> 23188 bytes .../theme/static/fonts/OpenSans-Light-webfont.eot | Bin 0 -> 19514 bytes .../theme/static/fonts/OpenSans-Light-webfont.svg | 1831 +++++++++++++++++++ .../theme/static/fonts/OpenSans-Light-webfont.woff | Bin 0 -> 22248 bytes .../static/fonts/OpenSans-LightItalic-webfont.eot | Bin 0 -> 20535 bytes .../static/fonts/OpenSans-LightItalic-webfont.svg | 1835 ++++++++++++++++++++ .../static/fonts/OpenSans-LightItalic-webfont.woff | Bin 0 -> 23400 bytes .../static/fonts/OpenSans-Regular-webfont.eot | Bin 0 -> 19836 bytes .../static/fonts/OpenSans-Regular-webfont.svg | 1831 +++++++++++++++++++ .../static/fonts/OpenSans-Regular-webfont.woff | Bin 0 -> 22660 bytes .../static/fonts/OpenSans-Semibold-webfont.eot | Bin 0 -> 20028 bytes .../static/fonts/OpenSans-Semibold-webfont.svg | 1830 +++++++++++++++++++ .../static/fonts/OpenSans-Semibold-webfont.ttf | Bin 0 -> 39476 bytes .../static/fonts/OpenSans-Semibold-webfont.woff | Bin 0 -> 22908 bytes .../fonts/OpenSans-SemiboldItalic-webfont.eot | Bin 0 -> 20962 bytes .../fonts/OpenSans-SemiboldItalic-webfont.svg | 1830 +++++++++++++++++++ .../fonts/OpenSans-SemiboldItalic-webfont.ttf | Bin 0 -> 40252 bytes .../fonts/OpenSans-SemiboldItalic-webfont.woff | Bin 0 -> 23764 bytes support/jsdoc/theme/static/scripts/linenumber.js | 25 + .../static/scripts/prettify/Apache-License-2.0.txt | 202 +++ .../theme/static/scripts/prettify/lang-css.js | 2 + .../theme/static/scripts/prettify/prettify.js | 28 + .../jsdoc/theme/static/styles/jsdoc-default.css | 601 +++++++ .../jsdoc/theme/static/styles/prettify-jsdoc.css | 111 ++ .../theme/static/styles/prettify-tomorrow.css | 132 ++ support/jsdoc/theme/tmpl/augments.tmpl | 10 + support/jsdoc/theme/tmpl/container.tmpl | 183 ++ support/jsdoc/theme/tmpl/details.tmpl | 143 ++ support/jsdoc/theme/tmpl/example.tmpl | 2 + support/jsdoc/theme/tmpl/examples.tmpl | 13 + support/jsdoc/theme/tmpl/exceptions.tmpl | 32 + support/jsdoc/theme/tmpl/layout.tmpl | 46 + support/jsdoc/theme/tmpl/mainpage.tmpl | 10 + support/jsdoc/theme/tmpl/members.tmpl | 38 + support/jsdoc/theme/tmpl/method.tmpl | 105 ++ support/jsdoc/theme/tmpl/params.tmpl | 124 ++ support/jsdoc/theme/tmpl/properties.tmpl | 108 ++ support/jsdoc/theme/tmpl/returns.tmpl | 19 + support/jsdoc/theme/tmpl/source.tmpl | 8 + support/jsdoc/theme/tmpl/tutorial.tmpl | 19 + support/jsdoc/theme/tmpl/type.tmpl | 7 + 55 files changed, 17415 insertions(+), 2 deletions(-) create mode 100644 support/jsdoc/theme/LICENSE create mode 100644 support/jsdoc/theme/README.md create mode 100644 support/jsdoc/theme/publish.js create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.eot create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.svg create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.woff create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.eot create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.svg create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.woff create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.eot create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.svg create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.woff create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.eot create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.svg create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.woff create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.eot create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.svg create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.woff create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.eot create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.svg create mode 100644 support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.woff create mode 100755 support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.eot create mode 100755 support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.svg create mode 100755 support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.ttf create mode 100755 support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.woff create mode 100755 support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.eot create mode 100755 support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.svg create mode 100755 support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.ttf create mode 100755 support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.woff create mode 100644 support/jsdoc/theme/static/scripts/linenumber.js create mode 100644 support/jsdoc/theme/static/scripts/prettify/Apache-License-2.0.txt create mode 100644 support/jsdoc/theme/static/scripts/prettify/lang-css.js create mode 100644 support/jsdoc/theme/static/scripts/prettify/prettify.js create mode 100644 support/jsdoc/theme/static/styles/jsdoc-default.css create mode 100644 support/jsdoc/theme/static/styles/prettify-jsdoc.css create mode 100644 support/jsdoc/theme/static/styles/prettify-tomorrow.css create mode 100644 support/jsdoc/theme/tmpl/augments.tmpl create mode 100644 support/jsdoc/theme/tmpl/container.tmpl create mode 100644 support/jsdoc/theme/tmpl/details.tmpl create mode 100644 support/jsdoc/theme/tmpl/example.tmpl create mode 100644 support/jsdoc/theme/tmpl/examples.tmpl create mode 100644 support/jsdoc/theme/tmpl/exceptions.tmpl create mode 100644 support/jsdoc/theme/tmpl/layout.tmpl create mode 100644 support/jsdoc/theme/tmpl/mainpage.tmpl create mode 100644 support/jsdoc/theme/tmpl/members.tmpl create mode 100644 support/jsdoc/theme/tmpl/method.tmpl create mode 100644 support/jsdoc/theme/tmpl/params.tmpl create mode 100644 support/jsdoc/theme/tmpl/properties.tmpl create mode 100644 support/jsdoc/theme/tmpl/returns.tmpl create mode 100644 support/jsdoc/theme/tmpl/source.tmpl create mode 100644 support/jsdoc/theme/tmpl/tutorial.tmpl create mode 100644 support/jsdoc/theme/tmpl/type.tmpl diff --git a/.gitignore b/.gitignore index 5b7b0d2..9af6394 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ tmp build build-es .idea +docs diff --git a/package.json b/package.json index d395a03..57352fd 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "karma-firefox-launcher": "^0.1.6", "karma-mocha": "^0.2.0", "karma-mocha-reporter": "^1.0.2", - "minami": "^1.1.1", "mocha": "^2.2.5", "native-promise-only": "^0.8.0-a", "nyc": "^2.1.0", diff --git a/support/jsdoc/jsdoc.json b/support/jsdoc/jsdoc.json index a0e0daa..e800aed 100644 --- a/support/jsdoc/jsdoc.json +++ b/support/jsdoc/jsdoc.json @@ -9,7 +9,7 @@ "plugins": ["plugins/markdown", "./jsdoc-import-path-plugin"], "opts": { "readme": "README.md", - "template": "node_modules/minami", + "template": "support/jsdoc/theme", "encoding": "utf8", "destination": "./docs", "recurse": true diff --git a/support/jsdoc/theme/LICENSE b/support/jsdoc/theme/LICENSE new file mode 100644 index 0000000..a45c814 --- /dev/null +++ b/support/jsdoc/theme/LICENSE @@ -0,0 +1,61 @@ +# License + +Minami is free software, licensed under the Apache License, Version 2.0 (the +"License"). Commercial and non-commercial use are permitted in compliance with +the License. + +Copyright (c) 2014-2015 Nijiko Yonskai and the +[contributors to Minami](https://github.com/Nijikokun/minami/graphs/contributors). +All rights reserved. + +You may obtain a copy of the License at: +http://www.apache.org/licenses/LICENSE-2.0 + +In addition, a copy of the License is included with this distribution. + +As stated in Section 7, "Disclaimer of Warranty," of the License: + +> Licensor provides the Work (and each Contributor provides its Contributions) +> on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +> express or implied, including, without limitation, any warranties or +> conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +> PARTICULAR PURPOSE. You are solely responsible for determining the +> appropriateness of using or redistributing the Work and assume any risks +> associated with Your exercise of permissions under this License. + +The source code for JSDoc 3 is available at: +https://github.com/Nijikokun/minami + +# Third-Party Software + +Minami includes or depends upon the following third-party software, either in +whole or in part. Each third-party software package is provided under its own +license. + +## JSDoc 3 + +JSDoc 3 is free software, licensed under the Apache License, Version 2.0 (the +"License"). Commercial and non-commercial use are permitted in compliance with +the License. + +Copyright (c) 2011-2015 Michael Mathews and the +[contributors to JSDoc](https://github.com/jsdoc3/jsdoc/graphs/contributors). +All rights reserved. + +You may obtain a copy of the License at: +http://www.apache.org/licenses/LICENSE-2.0 + +In addition, a copy of the License is included with this distribution. + +As stated in Section 7, "Disclaimer of Warranty," of the License: + +> Licensor provides the Work (and each Contributor provides its Contributions) +> on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +> express or implied, including, without limitation, any warranties or +> conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +> PARTICULAR PURPOSE. You are solely responsible for determining the +> appropriateness of using or redistributing the Work and assume any risks +> associated with Your exercise of permissions under this License. + +The source code for JSDoc 3 is available at: +https://github.com/jsdoc3/jsdoc diff --git a/support/jsdoc/theme/README.md b/support/jsdoc/theme/README.md new file mode 100644 index 0000000..5eea506 --- /dev/null +++ b/support/jsdoc/theme/README.md @@ -0,0 +1,77 @@ +# Minami + +A clean, responsive documentation template theme for JSDoc 3. + +![Minami Screenshot](http://puu.sh/gOyNe/66c3adcb97.png) + +## Uses + +- [the Taffy Database library](http://taffydb.com/) +- [Underscore Template library](http://documentcloud.github.com/underscore/#template) +- [Montserrat](http://www.google.com/fonts/specimen/Monsterrat) & Helvetica Neue + +## Install + +```bash +$ npm install --save-dev minami +``` + +## Usage + +Clone repository to your designated `jsdoc` template directory, then: + +```bash +$ jsdoc entry-file.js -t path/to/minami +``` + +### Node.js Dependency + +In your projects `package.json` file add a generate script: + +```json +"script": { + "generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose" +} +``` + +In your `.jsdoc.json` file, add a template option. + +```json +"opts": { + "template": "node_modules/minami" +} +``` + +### Example JSDoc Config + +```json +{ + "tags": { + "allowUnknownTags": true, + "dictionaries": ["jsdoc"] + }, + "source": { + "include": ["lib", "package.json", "README.md"], + "includePattern": ".js$", + "excludePattern": "(node_modules/|docs)" + }, + "plugins": [ + "plugins/markdown" + ], + "templates": { + "cleverLinks": false, + "monospaceLinks": true + }, + "opts": { + "destination": "./docs/", + "encoding": "utf8", + "private": true, + "recurse": true, + "template": "./node_modules/minami" + } +} +``` + +## License + +Licensed under the Apache2 license. \ No newline at end of file diff --git a/support/jsdoc/theme/publish.js b/support/jsdoc/theme/publish.js new file mode 100644 index 0000000..fbfd614 --- /dev/null +++ b/support/jsdoc/theme/publish.js @@ -0,0 +1,660 @@ +/*global env: true */ +'use strict'; + +var doop = require('jsdoc/util/doop'); +var fs = require('jsdoc/fs'); +var helper = require('jsdoc/util/templateHelper'); +var logger = require('jsdoc/util/logger'); +var path = require('jsdoc/path'); +var taffy = require('taffydb').taffy; +var template = require('jsdoc/template'); +var util = require('util'); + +var htmlsafe = helper.htmlsafe; +var linkto = helper.linkto; +var resolveAuthorLinks = helper.resolveAuthorLinks; +var scopeToPunc = helper.scopeToPunc; +var hasOwnProp = Object.prototype.hasOwnProperty; + +var data; +var view; + +var outdir = path.normalize(env.opts.destination); + +function find(spec) { + return helper.find(data, spec); +} + +function tutoriallink(tutorial) { + return helper.toTutorial(tutorial, null, { tag: 'em', classname: 'disabled', prefix: 'Tutorial: ' }); +} + +function getAncestorLinks(doclet) { + return helper.getAncestorLinks(data, doclet); +} + +function hashToLink(doclet, hash) { + if ( !/^(#.+)/.test(hash) ) { return hash; } + + var url = helper.createLink(doclet); + + url = url.replace(/(#.+|$)/, hash); + return '' + hash + ''; +} + +function needsSignature(doclet) { + var needsSig = false; + + // function and class definitions always get a signature + if (doclet.kind === 'function' || doclet.kind === 'class') { + needsSig = true; + } + // typedefs that contain functions get a signature, too + else if (doclet.kind === 'typedef' && doclet.type && doclet.type.names && + doclet.type.names.length) { + for (var i = 0, l = doclet.type.names.length; i < l; i++) { + if (doclet.type.names[i].toLowerCase() === 'function') { + needsSig = true; + break; + } + } + } + + return needsSig; +} + +function getSignatureAttributes(item) { + var attributes = []; + + if (item.optional) { + attributes.push('opt'); + } + + if (item.nullable === true) { + attributes.push('nullable'); + } + else if (item.nullable === false) { + attributes.push('non-null'); + } + + return attributes; +} + +function updateItemName(item) { + var attributes = getSignatureAttributes(item); + var itemName = item.name || ''; + + if (item.variable) { + itemName = '…' + itemName; + } + + if (attributes && attributes.length) { + itemName = util.format( '%s%s', itemName, + attributes.join(', ') ); + } + + return itemName; +} + +function addParamAttributes(params) { + return params.filter(function(param) { + return param.name && param.name.indexOf('.') === -1; + }).map(updateItemName); +} + +function buildItemTypeStrings(item) { + var types = []; + + if (item && item.type && item.type.names) { + item.type.names.forEach(function(name) { + types.push( linkto(name, htmlsafe(name)) ); + }); + } + + return types; +} + +function buildAttribsString(attribs) { + var attribsString = ''; + + if (attribs && attribs.length) { + attribsString = htmlsafe( util.format('(%s) ', attribs.join(', ')) ); + } + + return attribsString; +} + +function addNonParamAttributes(items) { + var types = []; + + items.forEach(function(item) { + types = types.concat( buildItemTypeStrings(item) ); + }); + + return types; +} + +function addSignatureParams(f) { + var params = f.params ? addParamAttributes(f.params) : []; + f.signature = util.format( '%s(%s)', (f.signature || ''), params.join(', ') ); +} + +function addSignatureReturns(f) { + var attribs = []; + var attribsString = ''; + var returnTypes = []; + var returnTypesString = ''; + + // jam all the return-type attributes into an array. this could create odd results (for example, + // if there are both nullable and non-nullable return types), but let's assume that most people + // who use multiple @return tags aren't using Closure Compiler type annotations, and vice-versa. + if (f.returns) { + f.returns.forEach(function(item) { + helper.getAttribs(item).forEach(function(attrib) { + if (attribs.indexOf(attrib) === -1) { + attribs.push(attrib); + } + }); + }); + + attribsString = buildAttribsString(attribs); + } + + if (f.returns) { + returnTypes = addNonParamAttributes(f.returns); + } + if (returnTypes.length) { + returnTypesString = util.format( ' → %s{%s}', attribsString, returnTypes.join('|') ); + } + + f.signature = '' + (f.signature || '') + '' + + '' + returnTypesString + ''; +} + +function addSignatureTypes(f) { + var types = f.type ? buildItemTypeStrings(f) : []; + + f.signature = (f.signature || '') + '' + + (types.length ? ' :' + types.join('|') : '') + ''; +} + +function addAttribs(f) { + var attribs = helper.getAttribs(f); + var attribsString = buildAttribsString(attribs); + + f.attribs = util.format('%s', attribsString); +} + +function shortenPaths(files, commonPrefix) { + Object.keys(files).forEach(function(file) { + files[file].shortened = files[file].resolved.replace(commonPrefix, '') + // always use forward slashes + .replace(/\\/g, '/'); + }); + + return files; +} + +function getPathFromDoclet(doclet) { + if (!doclet.meta) { + return null; + } + + return doclet.meta.path && doclet.meta.path !== 'null' ? + path.join(doclet.meta.path, doclet.meta.filename) : + doclet.meta.filename; +} + +function generate(type, title, docs, filename, resolveLinks) { + resolveLinks = resolveLinks === false ? false : true; + + var docData = { + type: type, + title: title, + docs: docs + }; + + var outpath = path.join(outdir, filename), + html = view.render('container.tmpl', docData); + + if (resolveLinks) { + html = helper.resolveLinks(html); // turn {@link foo} into foo + } + + fs.writeFileSync(outpath, html, 'utf8'); +} + +function generateSourceFiles(sourceFiles, encoding) { + encoding = encoding || 'utf8'; + Object.keys(sourceFiles).forEach(function(file) { + var source; + // links are keyed to the shortened path in each doclet's `meta.shortpath` property + var sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened); + helper.registerLink(sourceFiles[file].shortened, sourceOutfile); + + try { + source = { + kind: 'source', + code: helper.htmlsafe( fs.readFileSync(sourceFiles[file].resolved, encoding) ) + }; + } + catch(e) { + logger.error('Error while generating source file %s: %s', file, e.message); + } + + generate('Source', sourceFiles[file].shortened, [source], sourceOutfile, false); + }); +} + +/** + * Look for classes or functions with the same name as modules (which indicates that the module + * exports only that class or function), then attach the classes or functions to the `module` + * property of the appropriate module doclets. The name of each class or function is also updated + * for display purposes. This function mutates the original arrays. + * + * @private + * @param {Array.} doclets - The array of classes and functions to + * check. + * @param {Array.} modules - The array of module doclets to search. + */ +function attachModuleSymbols(doclets, modules) { + var symbols = {}; + + // build a lookup table + doclets.forEach(function(symbol) { + symbols[symbol.longname] = symbols[symbol.longname] || []; + symbols[symbol.longname].push(symbol); + }); + + return modules.map(function(module) { + if (symbols[module.longname]) { + module.modules = symbols[module.longname] + // Only show symbols that have a description. Make an exception for classes, because + // we want to show the constructor-signature heading no matter what. + .filter(function(symbol) { + return symbol.description || symbol.kind === 'class'; + }) + .map(function(symbol) { + symbol = doop(symbol); + + if (symbol.kind === 'class' || symbol.kind === 'function') { + symbol.name = symbol.name.replace('module:', '(require("') + '"))'; + } + + return symbol; + }); + } + }); +} + +function buildMemberNav(items, itemHeading, itemsSeen, linktoFn) { + var nav = ''; + + if (items && items.length) { + var itemsNav = ''; + + items.forEach(function(item) { + var methods = find({kind:'function', memberof: item.longname}); + var members = find({kind:'member', memberof: item.longname}); + + if ( !hasOwnProp.call(item, 'longname') ) { + itemsNav += '
  • ' + linktoFn('', item.name); + itemsNav += '
  • '; + } else if ( !hasOwnProp.call(itemsSeen, item.longname) ) { + itemsNav += '
  • ' + linktoFn(item.longname, item.name.replace(/^module:/, '')); + if (methods.length) { + itemsNav += "
      "; + + methods.forEach(function (method) { + itemsNav += "
    • "; + itemsNav += linkto(method.longname, method.name); + itemsNav += "
    • "; + }); + + itemsNav += "
    "; + } + itemsNav += '
  • '; + itemsSeen[item.longname] = true; + } + }); + + if (itemsNav !== '') { + nav += '

    ' + itemHeading + '

      ' + itemsNav + '
    '; + } + } + + return nav; +} + +function linktoTutorial(longName, name) { + return tutoriallink(name); +} + +function linktoExternal(longName, name) { + return linkto(longName, name.replace(/(^"|"$)/g, '')); +} + +/** + * Create the navigation sidebar. + * @param {object} members The members that will be used to create the sidebar. + * @param {array} members.classes + * @param {array} members.externals + * @param {array} members.globals + * @param {array} members.mixins + * @param {array} members.modules + * @param {array} members.namespaces + * @param {array} members.tutorials + * @param {array} members.events + * @param {array} members.interfaces + * @return {string} The HTML for the navigation sidebar. + */ +function buildNav(members) { + var nav = '

    Home

    '; + var seen = {}; + var seenTutorials = {}; + + nav += buildMemberNav(members.classes, 'Classes', seen, linkto); + nav += buildMemberNav(members.modules, 'Modules', {}, linkto); + nav += buildMemberNav(members.externals, 'Externals', seen, linktoExternal); + nav += buildMemberNav(members.events, 'Events', seen, linkto); + nav += buildMemberNav(members.namespaces, 'Namespaces', seen, linkto); + nav += buildMemberNav(members.mixins, 'Mixins', seen, linkto); + nav += buildMemberNav(members.tutorials, 'Tutorials', seenTutorials, linktoTutorial); + nav += buildMemberNav(members.interfaces, 'Interfaces', seen, linkto); + + if (members.globals.length) { + var globalNav = ''; + + members.globals.forEach(function(g) { + if ( g.kind !== 'typedef' && !hasOwnProp.call(seen, g.longname) ) { + globalNav += '
  • ' + linkto(g.longname, g.name) + '
  • '; + } + seen[g.longname] = true; + }); + + if (!globalNav) { + // turn the heading into a link so you can actually get to the global page + nav += '

    ' + linkto('global', 'Global') + '

    '; + } + else { + nav += '

    Global

      ' + globalNav + '
    '; + } + } + + return nav; +} + +/** + @param {TAFFY} taffyData See . + @param {object} opts + @param {Tutorial} tutorials + */ +exports.publish = function(taffyData, opts, tutorials) { + data = taffyData; + + var conf = env.conf.templates || {}; + conf.default = conf.default || {}; + + var templatePath = path.normalize(opts.template); + view = new template.Template( path.join(templatePath, 'tmpl') ); + + // claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness + // doesn't try to hand them out later + var indexUrl = helper.getUniqueFilename('index'); + // don't call registerLink() on this one! 'index' is also a valid longname + + var globalUrl = helper.getUniqueFilename('global'); + helper.registerLink('global', globalUrl); + + // set up templating + view.layout = conf.default.layoutFile ? + path.getResourcePath(path.dirname(conf.default.layoutFile), + path.basename(conf.default.layoutFile) ) : + 'layout.tmpl'; + + // set up tutorials for helper + helper.setTutorials(tutorials); + + data = helper.prune(data); + data.sort('longname, version, since'); + helper.addEventListeners(data); + + var sourceFiles = {}; + var sourceFilePaths = []; + data().each(function(doclet) { + doclet.attribs = ''; + + if (doclet.examples) { + doclet.examples = doclet.examples.map(function(example) { + var caption, code; + + if (example.match(/^\s*([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) { + caption = RegExp.$1; + code = RegExp.$3; + } + + return { + caption: caption || '', + code: code || example + }; + }); + } + if (doclet.see) { + doclet.see.forEach(function(seeItem, i) { + doclet.see[i] = hashToLink(doclet, seeItem); + }); + } + + // build a list of source files + var sourcePath; + if (doclet.meta) { + sourcePath = getPathFromDoclet(doclet); + sourceFiles[sourcePath] = { + resolved: sourcePath, + shortened: null + }; + if (sourceFilePaths.indexOf(sourcePath) === -1) { + sourceFilePaths.push(sourcePath); + } + } + }); + + // update outdir if necessary, then create outdir + var packageInfo = ( find({kind: 'package'}) || [] ) [0]; + if (packageInfo && packageInfo.name) { + outdir = path.join( outdir, packageInfo.name, (packageInfo.version || '') ); + } + fs.mkPath(outdir); + + // copy the template's static files to outdir + var fromDir = path.join(templatePath, 'static'); + var staticFiles = fs.ls(fromDir, 3); + + staticFiles.forEach(function(fileName) { + var toDir = fs.toDir( fileName.replace(fromDir, outdir) ); + fs.mkPath(toDir); + fs.copyFileSync(fileName, toDir); + }); + + // copy user-specified static files to outdir + var staticFilePaths; + var staticFileFilter; + var staticFileScanner; + if (conf.default.staticFiles) { + // The canonical property name is `include`. We accept `paths` for backwards compatibility + // with a bug in JSDoc 3.2.x. + staticFilePaths = conf.default.staticFiles.include || + conf.default.staticFiles.paths || + []; + staticFileFilter = new (require('jsdoc/src/filter')).Filter(conf.default.staticFiles); + staticFileScanner = new (require('jsdoc/src/scanner')).Scanner(); + + staticFilePaths.forEach(function(filePath) { + var extraStaticFiles = staticFileScanner.scan([filePath], 10, staticFileFilter); + + extraStaticFiles.forEach(function(fileName) { + var sourcePath = fs.toDir(filePath); + var toDir = fs.toDir( fileName.replace(sourcePath, outdir) ); + fs.mkPath(toDir); + fs.copyFileSync(fileName, toDir); + }); + }); + } + + if (sourceFilePaths.length) { + sourceFiles = shortenPaths( sourceFiles, path.commonPrefix(sourceFilePaths) ); + } + data().each(function(doclet) { + var url = helper.createLink(doclet); + helper.registerLink(doclet.longname, url); + + // add a shortened version of the full path + var docletPath; + if (doclet.meta) { + docletPath = getPathFromDoclet(doclet); + docletPath = sourceFiles[docletPath].shortened; + if (docletPath) { + doclet.meta.shortpath = docletPath; + } + } + }); + + data().each(function(doclet) { + var url = helper.longnameToUrl[doclet.longname]; + + if (url.indexOf('#') > -1) { + doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop(); + } + else { + doclet.id = doclet.name; + } + + if ( needsSignature(doclet) ) { + addSignatureParams(doclet); + addSignatureReturns(doclet); + addAttribs(doclet); + } + }); + + // do this after the urls have all been generated + data().each(function(doclet) { + doclet.ancestors = getAncestorLinks(doclet); + + if (doclet.kind === 'member') { + addSignatureTypes(doclet); + addAttribs(doclet); + } + + if (doclet.kind === 'constant') { + addSignatureTypes(doclet); + addAttribs(doclet); + doclet.kind = 'member'; + } + }); + + var members = helper.getMembers(data); + members.tutorials = tutorials.children; + + // output pretty-printed source files by default + var outputSourceFiles = conf.default && conf.default.outputSourceFiles !== false + ? true + : false; + + // add template helpers + view.find = find; + view.linkto = linkto; + view.resolveAuthorLinks = resolveAuthorLinks; + view.tutoriallink = tutoriallink; + view.htmlsafe = htmlsafe; + view.outputSourceFiles = outputSourceFiles; + + // once for all + view.nav = buildNav(members); + attachModuleSymbols( find({ longname: {left: 'module:'} }), members.modules ); + + // generate the pretty-printed source files first so other pages can link to them + if (outputSourceFiles) { + generateSourceFiles(sourceFiles, opts.encoding); + } + + if (members.globals.length) { + generate('', 'Global', [{kind: 'globalobj'}], globalUrl); + } + + // index page displays information from package.json and lists files + var files = find({kind: 'file'}); + var packages = find({kind: 'package'}); + + generate('', 'Home', + packages.concat( + [{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}] + ).concat(files), + indexUrl); + + // set up the lists that we'll use to generate pages + var classes = taffy(members.classes); + var modules = taffy(members.modules); + var namespaces = taffy(members.namespaces); + var mixins = taffy(members.mixins); + var externals = taffy(members.externals); + var interfaces = taffy(members.interfaces); + + Object.keys(helper.longnameToUrl).forEach(function(longname) { + var myModules = helper.find(modules, {longname: longname}); + if (myModules.length) { + generate('Module', myModules[0].name, myModules, helper.longnameToUrl[longname]); + } + + var myClasses = helper.find(classes, {longname: longname}); + if (myClasses.length) { + generate('Class', myClasses[0].name, myClasses, helper.longnameToUrl[longname]); + } + + var myNamespaces = helper.find(namespaces, {longname: longname}); + if (myNamespaces.length) { + generate('Namespace', myNamespaces[0].name, myNamespaces, helper.longnameToUrl[longname]); + } + + var myMixins = helper.find(mixins, {longname: longname}); + if (myMixins.length) { + generate('Mixin', myMixins[0].name, myMixins, helper.longnameToUrl[longname]); + } + + var myExternals = helper.find(externals, {longname: longname}); + if (myExternals.length) { + generate('External', myExternals[0].name, myExternals, helper.longnameToUrl[longname]); + } + + var myInterfaces = helper.find(interfaces, {longname: longname}); + if (myInterfaces.length) { + generate('Interface', myInterfaces[0].name, myInterfaces, helper.longnameToUrl[longname]); + } + }); + + // TODO: move the tutorial functions to templateHelper.js + function generateTutorial(title, tutorial, filename) { + var tutorialData = { + title: title, + header: tutorial.title, + content: tutorial.parse(), + children: tutorial.children + }; + + var tutorialPath = path.join(outdir, filename); + var html = view.render('tutorial.tmpl', tutorialData); + + // yes, you can use {@link} in tutorials too! + html = helper.resolveLinks(html); // turn {@link foo} into foo + fs.writeFileSync(tutorialPath, html, 'utf8'); + } + + // tutorials can have only one parent so there is no risk for loops + function saveChildren(node) { + node.children.forEach(function(child) { + generateTutorial('Tutorial: ' + child.title, child, helper.tutorialToUrl(child.name)); + saveChildren(child); + }); + } + + saveChildren(tutorials); +}; diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.eot b/support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.eot new file mode 100644 index 0000000..5d20d91 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.eot differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.svg b/support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.svg new file mode 100644 index 0000000..3ed7be4 --- /dev/null +++ b/support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.woff b/support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.woff new file mode 100644 index 0000000..1205787 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Bold-webfont.woff differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.eot b/support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.eot new file mode 100644 index 0000000..1f639a1 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.eot differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.svg b/support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.svg new file mode 100644 index 0000000..6a2607b --- /dev/null +++ b/support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.woff b/support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.woff new file mode 100644 index 0000000..ed760c0 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-BoldItalic-webfont.woff differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.eot b/support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.eot new file mode 100644 index 0000000..0c8a0ae Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.eot differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.svg b/support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.svg new file mode 100644 index 0000000..e1075dc --- /dev/null +++ b/support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.woff b/support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.woff new file mode 100644 index 0000000..ff652e6 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Italic-webfont.woff differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.eot b/support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.eot new file mode 100644 index 0000000..1486840 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.eot differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.svg b/support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.svg new file mode 100644 index 0000000..11a472c --- /dev/null +++ b/support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.woff b/support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.woff new file mode 100644 index 0000000..e786074 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Light-webfont.woff differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.eot b/support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.eot new file mode 100644 index 0000000..8f44592 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.eot differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.svg b/support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.svg new file mode 100644 index 0000000..431d7e3 --- /dev/null +++ b/support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.svg @@ -0,0 +1,1835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.woff b/support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.woff new file mode 100644 index 0000000..43e8b9e Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-LightItalic-webfont.woff differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.eot b/support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.eot new file mode 100644 index 0000000..6bbc3cf Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.eot differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.svg b/support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.svg new file mode 100644 index 0000000..25a3952 --- /dev/null +++ b/support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.svg @@ -0,0 +1,1831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.woff b/support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.woff new file mode 100644 index 0000000..e231183 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Regular-webfont.woff differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.eot b/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.eot new file mode 100755 index 0000000..d8375dd Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.eot differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.svg b/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.svg new file mode 100755 index 0000000..eec4db8 --- /dev/null +++ b/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.ttf b/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.ttf new file mode 100755 index 0000000..b329084 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.ttf differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.woff b/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.woff new file mode 100755 index 0000000..28d6ade Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-Semibold-webfont.woff differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.eot b/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.eot new file mode 100755 index 0000000..0ab1db2 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.eot differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.svg b/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.svg new file mode 100755 index 0000000..7166ec1 --- /dev/null +++ b/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.svg @@ -0,0 +1,1830 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.ttf b/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.ttf new file mode 100755 index 0000000..d2d6318 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.ttf differ diff --git a/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.woff b/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.woff new file mode 100755 index 0000000..d4dfca4 Binary files /dev/null and b/support/jsdoc/theme/static/fonts/OpenSans-SemiboldItalic-webfont.woff differ diff --git a/support/jsdoc/theme/static/scripts/linenumber.js b/support/jsdoc/theme/static/scripts/linenumber.js new file mode 100644 index 0000000..8d52f7e --- /dev/null +++ b/support/jsdoc/theme/static/scripts/linenumber.js @@ -0,0 +1,25 @@ +/*global document */ +(function() { + var source = document.getElementsByClassName('prettyprint source linenums'); + var i = 0; + var lineNumber = 0; + var lineId; + var lines; + var totalLines; + var anchorHash; + + if (source && source[0]) { + anchorHash = document.location.hash.substring(1); + lines = source[0].getElementsByTagName('li'); + totalLines = lines.length; + + for (; i < totalLines; i++) { + lineNumber++; + lineId = 'line' + lineNumber; + lines[i].id = lineId; + if (lineId === anchorHash) { + lines[i].className += ' selected'; + } + } + } +})(); diff --git a/support/jsdoc/theme/static/scripts/prettify/Apache-License-2.0.txt b/support/jsdoc/theme/static/scripts/prettify/Apache-License-2.0.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/support/jsdoc/theme/static/scripts/prettify/Apache-License-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/support/jsdoc/theme/static/scripts/prettify/lang-css.js b/support/jsdoc/theme/static/scripts/prettify/lang-css.js new file mode 100644 index 0000000..041e1f5 --- /dev/null +++ b/support/jsdoc/theme/static/scripts/prettify/lang-css.js @@ -0,0 +1,2 @@ +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", +/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); diff --git a/support/jsdoc/theme/static/scripts/prettify/prettify.js b/support/jsdoc/theme/static/scripts/prettify/prettify.js new file mode 100644 index 0000000..eef5ad7 --- /dev/null +++ b/support/jsdoc/theme/static/scripts/prettify/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p ul { + padding: 0 10px; +} + +nav > ul > li > a { + color: #000; +} + +nav ul ul { + margin-bottom: 10px +} + +nav ul ul a { + color: hsl(207, 1%, 60%); + border-left: 1px solid hsl(207, 10%, 86%); +} + +nav ul ul a, +nav ul ul a:active { + padding-left: 20px +} + +nav h2 { + font-size: 12px; + margin: 0; + padding: 0; +} + +nav > h2 > a { + display: block; + margin: 10px 0 -10px; + color: hsl(202, 71%, 50%) !important; +} + +footer { + color: hsl(0, 0%, 28%); + margin-left: 250px; + display: block; + padding: 15px; + font-style: italic; + font-size: 90%; +} + +.ancestors { + color: #999 +} + +.ancestors a { + color: #999 !important; + text-decoration: none; +} + +.clear { + clear: both +} + +.important { + font-weight: bold; + color: #950B02; +} + +.yes-def { + text-indent: -1000px +} + +.type-signature { + color: #aaa +} + +.name, .signature { + font-family: Consolas, Monaco, 'Andale Mono', monospace +} + +.details { + margin-top: 14px; + border-left: 2px solid #DDD; + line-height: 30px; +} + +.details dt { + width: 120px; + float: left; + padding-left: 10px; +} + +.details dd { + margin-left: 70px +} + +.details ul { + margin: 0 +} + +.details ul { + list-style-type: none +} + +.details li { + margin-left: 30px +} + +.details pre.prettyprint { + margin: 0 +} + +.details .object-value { + padding-top: 0 +} + +.description { + margin-bottom: 1em; + margin-top: 1em; +} + +.code-caption { + font-style: italic; + font-size: 107%; + margin: 0; +} + +.prettyprint { + font-size: 13px; + border: 1px solid #ddd; + border-radius: 3px; + box-shadow: 0 1px 3px hsla(0, 0%, 0%, 0.05); + overflow: auto; +} + +.prettyprint.source { + width: inherit +} + +.prettyprint code { + font-size: 100%; + line-height: 18px; + display: block; + margin: 0 30px; + background-color: #fff; + color: #4D4E53; +} + +.prettyprint > code { + padding: 15px +} + +.prettyprint .linenums code { + padding: 0 15px +} + +.prettyprint .linenums li:first-of-type code { + padding-top: 15px +} + +.prettyprint code span.line { + display: inline-block +} + +.prettyprint.linenums { + padding-left: 70px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.prettyprint.linenums ol { + padding-left: 0 +} + +.prettyprint.linenums li { + border-left: 3px #ddd solid +} + +.prettyprint.linenums li.selected, .prettyprint.linenums li.selected * { + background-color: lightyellow +} + +.prettyprint.linenums li * { + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.params, .props { + border-spacing: 0; + border: 1px solid #ddd; + border-collapse: collapse; + border-radius: 3px; + box-shadow: 0 1px 3px rgba(0,0,0,0.1); + width: 100%; + font-size: 14px; +} + +.params .name, .props .name, .name code { + color: #4D4E53; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 100%; +} + +.params td, .params th, .props td, .props th { + margin: 0px; + text-align: left; + vertical-align: top; + padding: 10px; + display: table-cell; +} + +.params td { + border-top: 1px solid #eee +} + +.params thead tr, .props thead tr { + background-color: #fff; + font-weight: bold; +} + +.params .params thead tr, .props .props thead tr { + background-color: #fff; + font-weight: bold; +} + +.params td.description > p:first-child, .props td.description > p:first-child { + margin-top: 0; + padding-top: 0; +} + +.params td.description > p:last-child, .props td.description > p:last-child { + margin-bottom: 0; + padding-bottom: 0; +} + +dl.param-type { + border-bottom: 1px solid hsl(0, 0%, 87%); + margin-bottom: 30px; + padding-bottom: 30px; +} + +.param-type dt, .param-type dd { + display: inline-block +} + +.param-type dd { + font-family: Consolas, Monaco, 'Andale Mono', monospace +} + +.disabled { + color: #454545 +} + +/* navicon button */ +.navicon-button { + display: none; + position: relative; + padding: 2.0625rem 1.5rem; + transition: 0.25s; + cursor: pointer; + user-select: none; + opacity: .8; +} +.navicon-button .navicon:before, .navicon-button .navicon:after { + transition: 0.25s; +} +.navicon-button:hover { + transition: 0.5s; + opacity: 1; +} +.navicon-button:hover .navicon:before, .navicon-button:hover .navicon:after { + transition: 0.25s; +} +.navicon-button:hover .navicon:before { + top: .825rem; +} +.navicon-button:hover .navicon:after { + top: -.825rem; +} + +/* navicon */ +.navicon { + position: relative; + width: 2.5em; + height: .3125rem; + background: #000; + transition: 0.3s; + border-radius: 2.5rem; +} +.navicon:before, .navicon:after { + display: block; + content: ""; + height: .3125rem; + width: 2.5rem; + background: #000; + position: absolute; + z-index: -1; + transition: 0.3s 0.25s; + border-radius: 1rem; +} +.navicon:before { + top: .625rem; +} +.navicon:after { + top: -.625rem; +} + +/* open */ +.nav-trigger:checked + label:not(.steps) .navicon:before, +.nav-trigger:checked + label:not(.steps) .navicon:after { + top: 0 !important; +} + +.nav-trigger:checked + label .navicon:before, +.nav-trigger:checked + label .navicon:after { + transition: 0.5s; +} + +/* Minus */ +.nav-trigger:checked + label { + transform: scale(0.75); +} + +/* × and + */ +.nav-trigger:checked + label.plus .navicon, +.nav-trigger:checked + label.x .navicon { + background: transparent; +} + +.nav-trigger:checked + label.plus .navicon:before, +.nav-trigger:checked + label.x .navicon:before { + transform: rotate(-45deg); + background: #FFF; +} + +.nav-trigger:checked + label.plus .navicon:after, +.nav-trigger:checked + label.x .navicon:after { + transform: rotate(45deg); + background: #FFF; +} + +.nav-trigger:checked + label.plus { + transform: scale(0.75) rotate(45deg); +} + +.nav-trigger:checked ~ nav { + left: 0 !important; +} + +.nav-trigger:checked ~ .overlay { + display: block; +} + +.nav-trigger { + position: fixed; + top: 0; + clip: rect(0, 0, 0, 0); +} + +.overlay { + display: none; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 100%; + height: 100%; + background: hsla(0, 0%, 0%, 0.5); + z-index: 1; +} + +@media only screen and (min-width: 320px) and (max-width: 680px) { + body { + overflow-x: hidden; + } + + nav { + background: #FFF; + width: 250px; + height: 100%; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: -250px; + z-index: 3; + padding: 0 10px; + transition: left 0.2s; + } + + .navicon-button { + display: inline-block; + position: fixed; + top: 1.5em; + right: 0; + z-index: 2; + } + + #main { + width: 100%; + min-width: 360px; + } + + #main h1.page-title { + margin: 1em 0; + } + + #main section { + padding: 0; + } + + footer { + margin-left: 0; + } +} + +@media only print { + nav { + display: none; + } + + #main { + float: none; + width: 100%; + } +} diff --git a/support/jsdoc/theme/static/styles/prettify-jsdoc.css b/support/jsdoc/theme/static/styles/prettify-jsdoc.css new file mode 100644 index 0000000..834a866 --- /dev/null +++ b/support/jsdoc/theme/static/styles/prettify-jsdoc.css @@ -0,0 +1,111 @@ +/* JSDoc prettify.js theme */ + +/* plain text */ +.pln { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* string content */ +.str { + color: hsl(104, 100%, 24%); + font-weight: normal; + font-style: normal; +} + +/* a keyword */ +.kwd { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a comment */ +.com { + font-weight: normal; + font-style: italic; +} + +/* a type name */ +.typ { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a literal value */ +.lit { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* punctuation */ +.pun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp open bracket */ +.opn { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* lisp close bracket */ +.clo { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a markup tag name */ +.tag { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute name */ +.atn { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a markup attribute value */ +.atv { + color: #006400; + font-weight: normal; + font-style: normal; +} + +/* a declaration */ +.dec { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* a variable name */ +.var { + color: #000000; + font-weight: normal; + font-style: normal; +} + +/* a function name */ +.fun { + color: #000000; + font-weight: bold; + font-style: normal; +} + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; +} diff --git a/support/jsdoc/theme/static/styles/prettify-tomorrow.css b/support/jsdoc/theme/static/styles/prettify-tomorrow.css new file mode 100644 index 0000000..81e74d1 --- /dev/null +++ b/support/jsdoc/theme/static/styles/prettify-tomorrow.css @@ -0,0 +1,132 @@ +/* Tomorrow Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* Pretty printing styles. Used with prettify.js. */ +/* SPAN elements with the classes below are added by prettyprint. */ +/* plain text */ +.pln { + color: #4d4d4c; } + +@media screen { + /* string content */ + .str { + color: hsl(104, 100%, 24%); } + + /* a keyword */ + .kwd { + color: hsl(240, 100%, 50%); } + + /* a comment */ + .com { + color: hsl(0, 0%, 60%); } + + /* a type name */ + .typ { + color: hsl(240, 100%, 32%); } + + /* a literal value */ + .lit { + color: hsl(240, 100%, 40%); } + + /* punctuation */ + .pun { + color: #000000; } + + /* lisp open bracket */ + .opn { + color: #000000; } + + /* lisp close bracket */ + .clo { + color: #000000; } + + /* a markup tag name */ + .tag { + color: #c82829; } + + /* a markup attribute name */ + .atn { + color: #f5871f; } + + /* a markup attribute value */ + .atv { + color: #3e999f; } + + /* a declaration */ + .dec { + color: #f5871f; } + + /* a variable name */ + .var { + color: #c82829; } + + /* a function name */ + .fun { + color: #4271ae; } } +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { + color: #060; } + + .kwd { + color: #006; + font-weight: bold; } + + .com { + color: #600; + font-style: italic; } + + .typ { + color: #404; + font-weight: bold; } + + .lit { + color: #044; } + + .pun, .opn, .clo { + color: #440; } + + .tag { + color: #006; + font-weight: bold; } + + .atn { + color: #404; } + + .atv { + color: #060; } } +/* Style */ +/* +pre.prettyprint { + background: white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + font-size: 12px; + line-height: 1.5; + border: 1px solid #ccc; + padding: 10px; } +*/ + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { + margin-top: 0; + margin-bottom: 0; } + +/* IE indents via margin-left */ +li.L0, +li.L1, +li.L2, +li.L3, +li.L4, +li.L5, +li.L6, +li.L7, +li.L8, +li.L9 { + /* */ } + +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { + /* */ } diff --git a/support/jsdoc/theme/tmpl/augments.tmpl b/support/jsdoc/theme/tmpl/augments.tmpl new file mode 100644 index 0000000..446d28a --- /dev/null +++ b/support/jsdoc/theme/tmpl/augments.tmpl @@ -0,0 +1,10 @@ + + + +
      +
    • +
    + diff --git a/support/jsdoc/theme/tmpl/container.tmpl b/support/jsdoc/theme/tmpl/container.tmpl new file mode 100644 index 0000000..c52d297 --- /dev/null +++ b/support/jsdoc/theme/tmpl/container.tmpl @@ -0,0 +1,183 @@ + + + + + + + + + +
    + +
    + +

    + + + + + +

    + +
    + + + + +
    + + + +
    + +
    +
    + + +
    + + + + + + + + + +
    + + + + + +

    Example 1? 's':'' ?>

    + + + +
    + + +

    Extends

    + + + + + +

    Requires

    + +
      +
    • +
    + + + +

    Classes

    + +
    +
    +
    +
    + + + +

    Mixins

    + +
    +
    +
    +
    + + + +

    Namespaces

    + +
    +
    +
    +
    + + + +

    Members

    + + + + + + + +

    Methods

    + + + + + + + +

    Type Definitions

    + + + + + + + + + +

    Events

    + + + + + +
    + +
    + + + diff --git a/support/jsdoc/theme/tmpl/details.tmpl b/support/jsdoc/theme/tmpl/details.tmpl new file mode 100644 index 0000000..d1ff696 --- /dev/null +++ b/support/jsdoc/theme/tmpl/details.tmpl @@ -0,0 +1,143 @@ +" + data.defaultvalue + ""; + defaultObjectClass = ' class="object-value"'; +} +?> + + +
    Properties:
    + + + + + +
    + + +
    Version:
    +
    + + + +
    Since:
    +
    + + + +
    Inherited From:
    +
    • + +
    + + + +
    Overrides:
    +
    • + +
    + + + +
    Implementations:
    +
      + +
    • + +
    + + + +
    Implements:
    +
      + +
    • + +
    + + + +
    Mixes In:
    + +
      + +
    • + +
    + + + +
    Deprecated:
    • Yes
    + + + +
    Author:
    +
    +
      +
    • +
    +
    + + + + + + + + +
    License:
    +
    + + + +
    Default Value:
    +
      + > +
    + + + +
    Source:
    +
    • + , +
    + + + +
    Tutorials:
    +
    +
      +
    • +
    +
    + + + +
    See:
    +
    +
      +
    • +
    +
    + + + +
    To Do:
    +
    +
      +
    • +
    +
    + +
    diff --git a/support/jsdoc/theme/tmpl/example.tmpl b/support/jsdoc/theme/tmpl/example.tmpl new file mode 100644 index 0000000..e87caa5 --- /dev/null +++ b/support/jsdoc/theme/tmpl/example.tmpl @@ -0,0 +1,2 @@ + +
    diff --git a/support/jsdoc/theme/tmpl/examples.tmpl b/support/jsdoc/theme/tmpl/examples.tmpl new file mode 100644 index 0000000..04d975e --- /dev/null +++ b/support/jsdoc/theme/tmpl/examples.tmpl @@ -0,0 +1,13 @@ + +

    + +
    + \ No newline at end of file diff --git a/support/jsdoc/theme/tmpl/exceptions.tmpl b/support/jsdoc/theme/tmpl/exceptions.tmpl new file mode 100644 index 0000000..9cef6c7 --- /dev/null +++ b/support/jsdoc/theme/tmpl/exceptions.tmpl @@ -0,0 +1,32 @@ + + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + Type +
    +
    + +
    +
    +
    +
    +
    + +
    + + + + + +
    + diff --git a/support/jsdoc/theme/tmpl/layout.tmpl b/support/jsdoc/theme/tmpl/layout.tmpl new file mode 100644 index 0000000..3b58d97 --- /dev/null +++ b/support/jsdoc/theme/tmpl/layout.tmpl @@ -0,0 +1,46 @@ + + + + + <?js= title ?> - Documentation + + + + + + + + + + + + + + + + + +
    + +

    + + + +
    + +
    + +
    + Documentation generated by JSDoc on using the Minami theme. +
    + + + + + diff --git a/support/jsdoc/theme/tmpl/mainpage.tmpl b/support/jsdoc/theme/tmpl/mainpage.tmpl new file mode 100644 index 0000000..b38a185 --- /dev/null +++ b/support/jsdoc/theme/tmpl/mainpage.tmpl @@ -0,0 +1,10 @@ + + + +
    +
    +
    + diff --git a/support/jsdoc/theme/tmpl/members.tmpl b/support/jsdoc/theme/tmpl/members.tmpl new file mode 100644 index 0000000..154c17b --- /dev/null +++ b/support/jsdoc/theme/tmpl/members.tmpl @@ -0,0 +1,38 @@ + +

    + + +

    + + + +
    + +
    + + + +
    Type:
    +
      +
    • + +
    • +
    + + + + + +
    Fires:
    +
      +
    • +
    + + + +
    Example 1? 's':'' ?>
    + + diff --git a/support/jsdoc/theme/tmpl/method.tmpl b/support/jsdoc/theme/tmpl/method.tmpl new file mode 100644 index 0000000..be60b8d --- /dev/null +++ b/support/jsdoc/theme/tmpl/method.tmpl @@ -0,0 +1,105 @@ + + + +

    Constructor

    + + +

    + + +

    + + + + +
    + +
    + + + +
    Extends:
    + + + + +
    Type:
    +
      +
    • + +
    • +
    + + + +
    This:
    +
    + + + +
    Parameters:
    + + + + + + +
    Requires:
    +
      +
    • +
    + + + +
    Fires:
    +
      +
    • +
    + + + +
    Listens to Events:
    +
      +
    • +
    + + + +
    Listeners of This Event:
    +
      +
    • +
    + + + +
    Throws:
    + 1) { ?>
      +
    • +
    + + + + +
    Returns:
    + 1) { ?>
      +
    • +
    + + + + +
    Example 1? 's':'' ?>
    + + diff --git a/support/jsdoc/theme/tmpl/params.tmpl b/support/jsdoc/theme/tmpl/params.tmpl new file mode 100644 index 0000000..1dc3ecf --- /dev/null +++ b/support/jsdoc/theme/tmpl/params.tmpl @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    + + + + + + <optional>
    + + + + <nullable>
    + + + + <repeatable>
    + +
    + + + + +
    Properties
    + +
    diff --git a/support/jsdoc/theme/tmpl/properties.tmpl b/support/jsdoc/theme/tmpl/properties.tmpl new file mode 100644 index 0000000..40e0909 --- /dev/null +++ b/support/jsdoc/theme/tmpl/properties.tmpl @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeAttributesDefaultDescription
    + + + + + + <optional>
    + + + + <nullable>
    + +
    + + + + +
    Properties
    +
    diff --git a/support/jsdoc/theme/tmpl/returns.tmpl b/support/jsdoc/theme/tmpl/returns.tmpl new file mode 100644 index 0000000..23fefa4 --- /dev/null +++ b/support/jsdoc/theme/tmpl/returns.tmpl @@ -0,0 +1,19 @@ + +
    + +
    + + + +
    +
    + Type +
    +
    + +
    +
    + \ No newline at end of file diff --git a/support/jsdoc/theme/tmpl/source.tmpl b/support/jsdoc/theme/tmpl/source.tmpl new file mode 100644 index 0000000..e559b5d --- /dev/null +++ b/support/jsdoc/theme/tmpl/source.tmpl @@ -0,0 +1,8 @@ + +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/support/jsdoc/theme/tmpl/tutorial.tmpl b/support/jsdoc/theme/tmpl/tutorial.tmpl new file mode 100644 index 0000000..88a0ad5 --- /dev/null +++ b/support/jsdoc/theme/tmpl/tutorial.tmpl @@ -0,0 +1,19 @@ +
    + +
    + 0) { ?> +
      +
    • +
    + + +

    +
    + +
    + +
    + +
    diff --git a/support/jsdoc/theme/tmpl/type.tmpl b/support/jsdoc/theme/tmpl/type.tmpl new file mode 100644 index 0000000..ec2c6c0 --- /dev/null +++ b/support/jsdoc/theme/tmpl/type.tmpl @@ -0,0 +1,7 @@ + + +| + \ No newline at end of file -- cgit v1.2.1 From f6594f2eb86a71ab08f8d13134013d246381a3bd Mon Sep 17 00:00:00 2001 From: Alexander Early Date: Thu, 30 Jun 2016 16:57:49 -0700 Subject: exclude jsdoc scripts from linting --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 158a5db..439a9da 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ DIST = dist SRC = lib/index.js SCRIPTS = ./support JS_SRC = $(shell find lib/ -type f -name '*.js') -LINT_FILES = lib/ mocha_test/ $(shell find perf/ -maxdepth 2 -type f) support/ karma.conf.js +LINT_FILES = lib/ mocha_test/ $(shell find perf/ -maxdepth 2 -type f) $(shell find support/ -maxdepth 2 -type f -name "*.js") karma.conf.js UMD_BUNDLE = $(BUILDDIR)/dist/async.js UMD_BUNDLE_MIN = $(BUILDDIR)/dist/async.min.js -- cgit v1.2.1 From 2115e805960a1239ffa306c2eb17a4cac4f6756f Mon Sep 17 00:00:00 2001 From: Alexander Early Date: Thu, 30 Jun 2016 17:02:37 -0700 Subject: exclude jsdoc theme from linting --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 57352fd..7cfb1e2 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "coverage": "nyc npm test && nyc report", "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", "jsdoc": "jsdoc -c ./support/jsdoc/jsdoc.json && node support/jsdoc/jsdoc-fix-html.js", - "lint": "eslint lib/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/ karma.conf.js", + "lint": "eslint lib/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/build/ support/*.js karma.conf.js", "mocha-browser-test": "karma start", "mocha-node-test": "mocha mocha_test/ --compilers js:babel-core/register", "mocha-test": "npm run mocha-node-test && npm run mocha-browser-test", -- cgit v1.2.1 From 7405cf083e436b3d157ba543f5bc979ada561bee Mon Sep 17 00:00:00 2001 From: Alexander Early Date: Thu, 30 Jun 2016 17:27:47 -0700 Subject: copy custom head data into theme --- support/jsdoc/head-data.html | 10 ---------- support/jsdoc/jsdoc-custom.css | 16 ---------------- support/jsdoc/jsdoc-fix-html.js | 17 ++++++++--------- support/jsdoc/theme/static/styles/jsdoc-default.css | 13 +++++++++++++ support/jsdoc/theme/tmpl/layout.tmpl | 12 ++++++++++++ 5 files changed, 33 insertions(+), 35 deletions(-) delete mode 100644 support/jsdoc/head-data.html diff --git a/support/jsdoc/head-data.html b/support/jsdoc/head-data.html deleted file mode 100644 index c8bd13c..0000000 --- a/support/jsdoc/head-data.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/support/jsdoc/jsdoc-custom.css b/support/jsdoc/jsdoc-custom.css index 8d988d4..b42226d 100644 --- a/support/jsdoc/jsdoc-custom.css +++ b/support/jsdoc/jsdoc-custom.css @@ -1,19 +1,3 @@ -.page-title { - padding-top: 12px; -} - -.navbar-fixed-top { - background-color: #101010; -} - -.navbar-fixed-top .navbar-right { - padding-right: 10px; -} - -.navbar .ion-social-github { - font-size: 1.2em; -} - body { height: 100%; width: 100%; diff --git a/support/jsdoc/jsdoc-fix-html.js b/support/jsdoc/jsdoc-fix-html.js index 667d869..a7fb920 100644 --- a/support/jsdoc/jsdoc-fix-html.js +++ b/support/jsdoc/jsdoc-fix-html.js @@ -88,8 +88,7 @@ function combineFakeModules(files, callback) { }); } -function applyPreCheerioFixes(data, headLinks) { - var closingHeadTag = '' +function applyPreCheerioFixes(data) { var customScript = '\n'; var closingBodyTag = ''; @@ -100,7 +99,7 @@ function applyPreCheerioFixes(data, headLinks) { var rIncorrectModuleText = />module:(\w+)\.(\w+)'+methodName+'<'; }); -}; +} function addStaticHeader($file, $headerContent) { var $body = $file.find('body'); $body.prepend($headerContent); -}; +} function fixToc($page, moduleFiles) { // remove `async` listing from toc @@ -149,12 +148,12 @@ function fixFooter($page) { var $footer = $page.find('footer'); $footer.append(additionalFooterText); $page.find('#main').append($footer); -}; +} function fixModuleLinks(files, callback) { var moduleFiles = extractModuleFiles(files); - async.map(['head-data.html', 'navbar.html'], function(filename, fileCallback) { + async.map(['navbar.html'], function(filename, fileCallback) { fs.readFile(path.join(__dirname, filename), 'utf8', function(err, data) { if (err) return fileCallback(err); return fileCallback(null, data); @@ -162,12 +161,12 @@ function fixModuleLinks(files, callback) { }, function(err, results) { if (err) return callback(err); - var $headerContent = $(results[1]); + var $headerContent = $(results[0]); async.each(files, function(file, fileCallback) { var filePath = path.join(docsDir, file); fs.readFile(filePath, 'utf8', function(err, fileData) { if (err) return fileCallback(err); - var $file = $(applyPreCheerioFixes(fileData, results[0])); + var $file = $(applyPreCheerioFixes(fileData)); addStaticHeader($file, $headerContent); fixToc($file, moduleFiles); diff --git a/support/jsdoc/theme/static/styles/jsdoc-default.css b/support/jsdoc/theme/static/styles/jsdoc-default.css index af6f87c..9b4282e 100644 --- a/support/jsdoc/theme/static/styles/jsdoc-default.css +++ b/support/jsdoc/theme/static/styles/jsdoc-default.css @@ -51,6 +51,7 @@ h1 { } h1.page-title { + padding-top: 12px; font-size: 48px; margin: 1em 30px; } @@ -209,6 +210,18 @@ nav > h2 > a { color: hsl(202, 71%, 50%) !important; } +.navbar-fixed-top { + background-color: #101010; +} + +.navbar-fixed-top .navbar-right { + padding-right: 10px; +} + +.navbar .ion-social-github { + font-size: 1.2em; +} + footer { color: hsl(0, 0%, 28%); margin-left: 250px; diff --git a/support/jsdoc/theme/tmpl/layout.tmpl b/support/jsdoc/theme/tmpl/layout.tmpl index 3b58d97..bd199b2 100644 --- a/support/jsdoc/theme/tmpl/layout.tmpl +++ b/support/jsdoc/theme/tmpl/layout.tmpl @@ -2,8 +2,14 @@ + <?js= title ?> - Documentation + + + + + + + + + + + -- cgit v1.2.1 From 0e1bdc5c86ff20963c0a91ce725101859b0488fd Mon Sep 17 00:00:00 2001 From: Alexander Early Date: Thu, 30 Jun 2016 17:32:40 -0700 Subject: copy custom navbar into theme --- support/jsdoc/jsdoc-fix-html.js | 38 ++++++++++++------------------------ support/jsdoc/navbar.html | 30 ---------------------------- support/jsdoc/theme/tmpl/layout.tmpl | 32 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 56 deletions(-) delete mode 100644 support/jsdoc/navbar.html diff --git a/support/jsdoc/jsdoc-fix-html.js b/support/jsdoc/jsdoc-fix-html.js index a7fb920..3d67884 100644 --- a/support/jsdoc/jsdoc-fix-html.js +++ b/support/jsdoc/jsdoc-fix-html.js @@ -96,7 +96,7 @@ function applyPreCheerioFixes(data) { var rIncorrectCFText = />ControlFlowmodule:(\w+)\.(\w+)module:(\w+)\.(\w+) - - - - diff --git a/support/jsdoc/theme/tmpl/layout.tmpl b/support/jsdoc/theme/tmpl/layout.tmpl index bd199b2..27b0ce4 100644 --- a/support/jsdoc/theme/tmpl/layout.tmpl +++ b/support/jsdoc/theme/tmpl/layout.tmpl @@ -27,6 +27,38 @@ + + +