oscache-2.4.1.orig/0000755000175000017500000000000011375310622014020 5ustar twernertwerneroscache-2.4.1.orig/.project0000644000175000017500000000055610214177117015476 0ustar twernertwerner oscache org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature oscache-2.4.1.orig/readme.txt0000644000175000017500000000310510402251540016006 0ustar twernertwernerOSCACHE ------- OSCache is a high performance and widely used J2EE caching solution. For a full list of features, see: http://www.opensymphony.com/oscache/features.html REQUIREMENTS ------------ OSCache can be used as a standalone caching solution for any Java application. OSCache's tag library and the caching filter for dynamic binary content, like PDFs or images, require a Servlet 2.3 / JSP 1.2 compliant container. INSTALLATION AND DOCUMENTATION ----------- For installation instructions, see docs/install.html. For futher documentation, see docs/index.html. WHAT'S NEW ----------- For a complete list of changes for this and previous releases, see docs/changelog.html. FURTHER INFORMATION ----------- For further instructions and documentation see the OSCache website at: http://www.opensymphony.com/oscache The development of the OSCache project is hosted at: http://oscache.dev.java.net From there you can access the latest code from CVS, subscribe to the mailing lists and search and submit bug reports. To get help, please ask on the users mailing list, do not email the developers directly - they will reply on list to help everyone. The OSCache mailing lists are available at http://oscache.dev.java.net/servlets/ProjectMailingListList Since OSCache was originally hosted at SourceForge, you may also want to search the old mailing list archives at: http://sourceforge.net/mailarchive/forum.php?forum_id=4754 OPENSYMPHONY ------------ OSCache is part of the OpenSymphony project. For more information about OpenSymphony, see: http://www.opensymphony.com Enjoy!oscache-2.4.1.orig/ivyconf.xml0000644000175000017500000000367710643520716016240 0ustar twernertwerner oscache-2.4.1.orig/pom.xml0000644000175000017500000002745010643520716015351 0ustar twernertwerner 4.0.0 opensymphony oscache 2.4.1 OSCache OSCache is a caching solution that includes a JSP tag library and set of classes to perform fine grained dynamic caching of JSP content, servlet responses or arbitrary objects. http://www.opensymphony.com/oscache/ OpenSymphony http://www.opensymphony.com/ JIRA http://jira.opensymphony.com/browse/CACHE opensymphony OpenSymphony Maven Repository scp://maven2.opensymphony.com/opt/repository/maven2 User discussion and support list for OSCache mailto:users@oscache.dev.java.net https://oscache.dev.java.net/servlets/ProjectMailingListList https://oscache.dev.java.net/servlets/SummarizeList?listName=users http://forums.opensymphony.com/forum.jspa?forumID=4 http://svn.opensymphony.com/svn/oscache/trunk/ The OpenSymphony Software License 1.1 http://opensymphony.com/webwork/license.action This license is derived and fully compatible with the Apache Software License - see http://www.apache.org/LICENSE.txt src/java src/test src/java **/* **/*.java **/*.html src/etc **/*.tld **/*.xml **/*.properties src/test **/* **/*.java **/*.html org.apache.maven.plugins maven-idea-plugin 1.5 target,test-output,.clover,build true org.apache.maven.plugins maven-site-plugin 2.0-beta-5 org.apache.maven.plugins maven-compiler-plugin true 1.4 1.4 org.apache.maven.plugins maven-surefire-plugin 2.3 **/*Test.java org.apache.maven.plugins maven-javadoc-plugin attach-source jar UTF-8 OSCache Packages com.opensymphony.oscache* private http://java.sun.com/j2se/1.4.2/docs/api http://jakarta.apache.org/commons/logging/apidocs/ http://logging.apache.org/log4j/docs/api/ org.apache.maven.plugins maven-source-plugin attach-source jar org.codehaus.mojo cobertura-maven-plugin clean org.apache.maven.plugins maven-jar-plugin true true ${pom.url} install org.apache.maven.plugins maven-project-info-reports-plugin maven-surefire-report-plugin org.codehaus.mojo jxr-maven-plugin org.codehaus.mojo cobertura-maven-plugin org.apache.maven.plugins maven-changes-plugin jira-report commons-logging commons-logging 1.1 javax.jms jms 1.1 javax.servlet servlet-api 2.3 jgroups jgroups-all 2.2.8 true org.hibernate hibernate 3.2.3.ga true junit junit 3.8.2 test httpunit httpunit 1.6 test junitperf junitperf 1.9.1 test groboutils groboutils-core 5 test oscache-2.4.1.orig/LICENSE.txt0000644000175000017500000000500307716767072015664 0ustar twernertwerner/* ==================================================================== * The OpenSymphony Software License, Version 1.1 * * (this license is derived and fully compatible with the Apache Software * License - see http://www.apache.org/LICENSE.txt) * * Copyright (c) 2001 The OpenSymphony Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * OpenSymphony Group (http://www.opensymphony.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "OpenSymphony" and "The OpenSymphony Group" * must not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact license@opensymphony.com . * * 5. Products derived from this software may not be called "OpenSymphony" * or "OSCore", nor may "OpenSymphony" or "OSCore" appear in their * name, without prior written permission of the OpenSymphony Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== */ oscache-2.4.1.orig/.classpath0000644000175000017500000000226410641701561016010 0ustar twernertwerner oscache-2.4.1.orig/build.xml0000644000175000017500000004150710621641410015643 0ustar twernertwerner oscache-2.4.1.orig/ivy.xml0000644000175000017500000000467410643656511015373 0ustar twernertwerner OSCache is a caching solution that includes a JSP tag library and set of classes to perform fine grained dynamic caching of JSP content, servlet responses or arbitrary objects. It provides both in memory and persistent on disk caches, and can allow your site to have graceful error tolerance (eg if an error occurs like your db goes down, you can serve the cached content so people can still surf the site almost without knowing). oscache-2.4.1.orig/lib/0000755000175000017500000000000011375310622014566 5ustar twernertwerneroscache-2.4.1.orig/lib/.cvsignore0000644000175000017500000000000510316156440016561 0ustar twernertwerner*.jaroscache-2.4.1.orig/.cvsignore0000644000175000017500000000012310445266656016032 0ustar twernertwernerbuild build.test build.properties dist *.i* .settings .fbprefs .fbwarnings .clover oscache-2.4.1.orig/OSCache.ipr0000644000175000017500000002522510316437443016014 0ustar twernertwerner oscache-2.4.1.orig/docs/0000755000175000017500000000000011375310614014751 5ustar twernertwerneroscache-2.4.1.orig/docs/api.css0000644000175000017500000000206310173136245016236 0ustar twernertwernertd, li, br, div, p { font-family : verdana, arial, helvetica, sans-serif; font-size: 11px; } body { margin: 0; padding: 0; color: #333333; background-color: white; font-size: 11px; font-family: verdana, arial, helvetica, sans-serif; line-height: 19px; } TD.NavBarCell1 { font-size: 10px; font-family: Verdana, Sans-Serif; font-weight: bold; color: #666666; background-color: #99CCFF; } TD.NavBarCell1Rev { font-family: Verdana, Sans-Serif; font-size: 11px; font-weight: bold; color: #dedede; background-color: #669900; } TR.TableHeadingColor { background-color: #99CCFF; } HR { size: 1; color: #000000; height: 1; } a { text-decoration: none; } a:link { color: #003366; } a:visited { color: #cc6600; } a:active { background-color: transparent; color: #cc6600; } li { padding-bottom: 2pt; } h2 { color: #006699; margin-bottom: 10px; margin-top: 10px; } h3 { color: #006699; } h4 { font: 11px verdana, arial, helvetica, sans-serif; font-weight: bold; color: #cc6600; } h5, h6 { color: #032588; } oscache-2.4.1.orig/docs/navpanel.jsp0000644000175000017500000000451110215474740017277 0ustar twernertwerner

About

Overview
Feature List
Download
Changelog
Requirements

Documentation

Installation Guide
FAQ
Configuration
Tag Reference
The Caching Filter
Cron Expressions
OSCache and Hibernate
Clustering
API Reference

Services

JIRA
- Issue Overview
- Roadmap
- Changelog
Wiki
- OSCache page

Sponsor Companies

These companies have contributed a lot to OSCache and we thank them.
Pyxis Technologies
Atlassian

oscache-2.4.1.orig/docs/index.html0000644000175000017500000000251710317264107016753 0ustar twernertwerner OSCache

OSCache is a caching solution that includes a JSP tag library and set of classes to perform fine grained dynamic caching of JSP content, servlet responses or arbitrary objects. It provides both in memory and persistent on disk caches, and can allow your site to have graceful error tolerance (eg if an error occurs like your db goes down, you can serve the cached content so people can still surf the site almost without knowing). Take a look at the great features of OSCache.

Here you will find documentation and download information for the latest version of OSCache.

Reports:

Documentation for the currently developing release can always be found on the OSCache Wiki. If you have edits or corrections to make to the documentation here, you may edit them directly on the wiki as well. oscache-2.4.1.orig/docs/wiki/0000755000175000017500000000000011375310614015714 5ustar twernertwerneroscache-2.4.1.orig/docs/wiki/OSCache 2.2.html0000644000175000017500000004415410615670431020343 0ustar twernertwerner OSCache - OSCache 2.2

Release Notes - Final

(6th November 2005 - by Lars Torunski)

Additionally to the 2.2 RC improvements, the final release was enhanced by:

  • Allow cache group definition in CacheFilter
  • Option to specify when to send Expires-Header
  • Allow disabling initial set of the last modified header
  • Continuous Integration and Dependency Management with Ivy
  • Update to JGroups 2.2.8

JIRA Issue List

OpenSymphony JIRA (12 issues)
T Key Summary Status
Bug CACHE-223 completeUpdate never being called after startUpdate() has been called, OSCache hangs for that key ClosedClosed
Task CACHE-211 Create check sums for the distribution files ClosedClosed
Task CACHE-210 Review: If last test-base and last test-web overwrite previous unit test reports ClosedClosed
Improvement CACHE-204 Allow disabling initial set of the last modified header ClosedClosed
Task CACHE-203 Change JSP tag URI in pages of example war ClosedClosed
Bug CACHE-202 Expires header should not be inital set in fragments ClosedClosed
Bug CACHE-201 Defined interface for ICacheKeyProvider not used in CacheFilter ClosedClosed
Task CACHE-199 Continuous Integration and Dependency Management with Ivy ClosedClosed
Task CACHE-198 Update to JGroups 2.2.8 ClosedClosed
Improvement CACHE-196 Option to specify when to send Expires-Header ClosedClosed
Improvement CACHE-195 Allow cache group generation in CacheFilter ClosedClosed
Task CACHE-194 Update Documentation ClosedClosed

oscache-2.4.1.orig/docs/wiki/Statistics_attachments/0000755000175000017500000000000011375310610022435 5ustar twernertwerneroscache-2.4.1.orig/docs/wiki/Statistics_attachments/StatisticListenerImpl.java0000644000175000017500000001504110235065411027600 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.extra; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.base.events.*; /** * A simple implementation of a statistic reporter which uses the * CacheMapAccessEventListener, CacheEntryEventListener and ScopeEventListener. * It uses the events to count the cache hit and misses and of course the * flushes. *

* We are not using any synchronized so that this does not become a bottleneck. * The consequence is that on retrieving values, the operations that are * currently being done won't be counted. */ public class StatisticListenerImpl implements CacheMapAccessEventListener, CacheEntryEventListener, ScopeEventListener { private static transient final Log log = LogFactory.getLog(StatisticListenerImpl.class); /** * Hit counter */ private int hitCount = 0; /** * Miss counter */ private int missCount = 0; /** * Stale hit counter */ private int staleHitCount = 0; /** * Hit counter sum */ private int hitCountSum = 0; /** * Miss counter sum */ private int missCountSum = 0; /** * Stale hit counter */ private int staleHitCountSum = 0; /** * Flush hit counter */ private int flushCount = 0; /** * Constructor, empty for us */ public StatisticListenerImpl() { log.info("Creation of StatisticListenerImpl"); } /** * This method handles an event each time the cache is accessed * * @param event The event triggered when the cache was accessed * @see com.opensymphony.oscache.base.events.CacheMapAccessEventListener#accessed(CacheMapAccessEvent) */ public void accessed(CacheMapAccessEvent event) { String result = "N/A"; // Retrieve the event type and update the counters CacheMapAccessEventType type = event.getEventType(); // Handles a hit event if (type == CacheMapAccessEventType.HIT) { hitCount++; result = "HIT"; } // Handles a stale hit event else if (type == CacheMapAccessEventType.STALE_HIT) { staleHitCount++; result = "STALE HIT"; } // Handles a miss event else if (type == CacheMapAccessEventType.MISS) { missCount++; result = "MISS"; } if (log.isDebugEnabled()) { log.debug("ACCESS : " + result + ": " + event.getCacheEntryKey()); log.debug("STATISTIC : Hit = " + hitCount + ", stale hit =" + staleHitCount + ", miss = " + missCount); } } /** * Logs the flush of the cache. * * @param info the string to be logged. */ private void flushed(String info) { flushCount++; hitCountSum += hitCount; staleHitCountSum += staleHitCount; missCountSum += missCount; if (log.isInfoEnabled()) { log.info("FLUSH : " + info); log.info("STATISTIC SUM : " + "Hit = " + hitCountSum + ", stale hit = " + staleHitCountSum + ", miss = " + missCountSum + ", flush = " + flushCount); } hitCount = 0; staleHitCount = 0; missCount = 0; } /** * Event fired when a specific or all scopes are flushed. * * @param event ScopeEvent * @see com.opensymphony.oscache.base.events.ScopeEventListener#scopeFlushed(ScopeEvent) */ public void scopeFlushed(ScopeEvent event) { flushed("scope " + ScopeEventListenerImpl.SCOPE_NAMES[event.getScope()]); } /** * Event fired when an entry is added to the cache. * * @param event CacheEntryEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryAdded(CacheEntryEvent) */ public void cacheEntryAdded(CacheEntryEvent event) { // do nothing } /** * Event fired when an entry is flushed from the cache. * * @param event CacheEntryEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryFlushed(CacheEntryEvent) */ public void cacheEntryFlushed(CacheEntryEvent event) { // do nothing, because a group or other flush is coming if (!Cache.NESTED_EVENT.equals(event.getOrigin())) { flushed("entry " + event.getKey() + " / " + event.getOrigin()); } } /** * Event fired when an entry is removed from the cache. * * @param event CacheEntryEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryRemoved(CacheEntryEvent) */ public void cacheEntryRemoved(CacheEntryEvent event) { // do nothing } /** * Event fired when an entry is updated in the cache. * * @param event CacheEntryEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryUpdated(CacheEntryEvent) */ public void cacheEntryUpdated(CacheEntryEvent event) { // do nothing } /** * Event fired when a group is flushed from the cache. * * @param event CacheGroupEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheGroupFlushed(CacheGroupEvent) */ public void cacheGroupFlushed(CacheGroupEvent event) { flushed("group " + event.getGroup()); } /** * Event fired when a key pattern is flushed from the cache. * * @param event CachePatternEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cachePatternFlushed(CachePatternEvent) */ public void cachePatternFlushed(CachePatternEvent event) { flushed("pattern " + event.getPattern()); } /** * An event that is fired when an entire cache gets flushed. * * @param event CachewideEvent * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheFlushed(CachewideEvent) */ public void cacheFlushed(CachewideEvent event) { flushed("wide " + event.getDate()); } /** * Return the counters in a string form * * @return String */ public String toString() { return "StatisticListenerImpl: Hit = " + hitCount + " / " + hitCountSum + ", stale hit = " + staleHitCount + " / " + staleHitCountSum + ", miss = " + missCount + " / " + missCountSum + ", flush = " + flushCount; } }oscache-2.4.1.orig/docs/wiki/OSCache 1.3.html0000644000175000017500000000167510402251442020333 0ustar twernertwerner OSCache - OSCache 1.3

Release Notes

(9th June, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Fixed a single bug in the file caching - should now work
  • Added property to set the cache key (not sure if this is useful)
  • Cleaned up a lot of the code, refactored slightly so that the tags are more light weight and rely more on the Administrator and CacheHashMap for functionality.
oscache-2.4.1.orig/docs/wiki/OSCache 1.2.5.html0000644000175000017500000000155010402251442020465 0ustar twernertwerner OSCache - OSCache 1.2.5

Release Notes

(18th May, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Added ability to turn off file caching (just remove or comment out cache.properties)
  • Removed a pesky (but ineffectual) bug where session caches being removed from disk were throwing NullPointerExceptions
oscache-2.4.1.orig/docs/wiki/Requirements.html0000644000175000017500000000505510360177376021303 0ustar twernertwerner OSCache - Requirements

OSCache can be used directly to provide caching for any Java application. Using the OSCache tag library requires Servlet 2.3 and JSP 1.2 support (included in J2EE 1.3) to run properly. There is no dependency on a servlet container if the OSCache API is used directly.

So far OSCache has been tested in the following application servers and web containers:

This does not mean it will not run on other servers! It should run on any specification compliant container. If you have run OSCache successfully in other servers, please let us know and we'll add to this list.

The Caching Filter (for caching entire pages, and binary content such as GIFs and PDFs) requires Servlet 2.3 support. It is known to work on Orion, BEA WebLogic Server and Tomcat 4.0.

OSCache requires at least Java 1.4 for the installation.

oscache-2.4.1.orig/docs/wiki/FAQ.html0000644000175000017500000003602410402251442017207 0ustar twernertwerner OSCache - FAQ

Got a question you'd like to ask? Ask us and we'll add it to the FAQ.

Questions

What can I use OSCache for exactly?

OSCache can be used on three different levels:

  • JSP Caching - The first and simplest approach is to use the supplied taglibs to cache portions of JSP pages after the page has been rendered. This sounds simple but it's remarkably powerful and useful for almost every JSP application.
  • Request Caching - OSCache comes with a filter that allows you to cache entire HTTP responses - including dynamically generated images!
  • General-Purpose Cache - You can also use OSCache as a general-purpose caching solution by calling its API directly from your code. This allows arbitrary Java objects to be cached, and provides more control over the cache's behaviour. Note that any Java application can use OSCache in this manner; there is no requirement for a web server to be present when calling the API directly.

All three approaches can be mixed and matched within the same application.

Where is the data cached?

Out of the box, OSCache is capable of caching data in memory (so it is very fast), and/or to disk (so your cache can be persistent across server restarts). Support is also provided for managing a cluster of caches across multiple servers.

In addition to these capabilities, it is possible to plug in custom persistence code and custom event handlers, so you could easily extend OSCache to persist cached objects to say a database or an LDAP directory.

Can OSCache cache Java objects rather than portions of JSP pages? I mean if I create a Product object, can I cache it and use it later so that I don't have to fetch data again?

Yes, however to do this you will need to write code that talks to the OSCache API directly. The taglibs are currently only designed to cache rendered JSP content. This should hopefully not be too big a limitation since any creation or manipulation of java objects should generally be performed in beans or MVC action classes rather than JSP scriptlets anyway.

What other features does OSCache have?

There is a full list of features in the Feature List documentation.

Can you give me some examples of how the OSCache tags are used?

Example 1
<cache:cache time="600">
        <%= myBean.getTitle() %>
    </cache:cache>

This will only access your EJB once every 10 minutes. Every other request it will just serve the cached JSP content that was produced the first time (this results in much faster page loading).

Example 2
<cache:cache key="foobar" scope="session">
        <%= myBean.getTitle() %>
    </cache:cache>

This time the cache is keyed (you could have a programmatic key here too, like <%= foobarString %>) and it's scoped by session.

This is revolutionary as far as caching goes. You can now have cached content, that's different for every user! No more full page caches with no dynamic content!

Example 3
(a very powerful & useful way to use the taglibs):

    <cache:cache>
        <% try { %>
            <%= myBean.getTitle() %>>
        <% } catch (Exception e) { %>
            <% application.log("Exception occurred in myBean.getTitle(): " + e); %>
            <cache:usecached />
        <% } %>
    </cache:cache>

If a RemoteException occurs trying to get the EJB title (for example the database goes down) the cached content will be served so the user will not suspect a thing. No error page as per a normal JSP application. What does this mean? It means greater error tolerance in your JSP apps!

One example of where this is useful - when our machine restarts, our app server loads faster than the database server. No problem - because the cache is persistent, it serves cached content while the database boots, then seamlessly kicks in to the database for a cache refresh when the database is ready.

See the Tag Reference and the example web application for further taglib examples.

Can OSCache tags be nested?

You can't currently nest <cache> tags within one another - not that you'd probably want to. It is because of the cache object being placed in the page scope for use by programmers within the tag.

We're not sure if anyone actually uses this so we might remove it to allow for tag nesting (presumably across includes or something).

What control do you have over the cache size? I can imagine the size of the in-memory cache getting very big. Is it possible to set a max cache size and then remove the least-recently-used entries from the cache?

You can limit the memory cache by the number of objects that are cached. When an object is added to the cache and the limit is exceeded, another object will be removed from the cache to make room.

Currently the disk cache can either be set to unlimited, or tied to the same size as the memory cache (ie, objects will be removed from the disk cache at the same time as they are removed from the memory cache. Depending on the useage patterns of your cache, restarting your application could mean that the disk cache might continue to grow). We understand that this is not ideal and there is room for improvement here. Stay tuned!

How does OSCache decide which object to remove? What caching algorithm does OSCache use?

The caching algorithm is configurable. OSCache currently ships with 3 different algorithms - LRU (Least Recently Used), FIFO (First In First Out), and Unlimited. Should one of those not prove suitable, it is also possible to specify a custom algorithm class.

How does OSCache's clustering work?

The clustering is implemented as a listener that catches 'flush' events. These events are then broadcast across the network (using either the JavaGroups library or JMS) so that other nodes in the cluster can flush the relevant object(s) from their local cache. Note that for performance reasons, when objects are added to a cache they are not broadcast to other nodes. This means that each node in the cluster maintains their own relatively indedependent cache, yet still remains fresh.

If this mechanism does not suit your requirements, you can always code up a different solution by writing a custom event handler.

What happens if I need to expire data in the cache?

Cache entries can be flushed explicitly in several ways:

  • Individual entries can be flushed by specifying the cache key of the entry to flush eg <cache:flush key="myKey" scope="application"/>
  • When adding an entry to the cache, it can optionally be placed into one or more groups. An entire group of entries can then be flushed by specifying the name of the group to flush. eg <cache:flush group="group1" scope="application"/>
  • A pattern can be specified; all keys that contain the supplied pattern will be flushed. eg <cache:flush pattern="menu" scope="application"/> will flush all keys that contain the string "menu". (note that this approach is now deprecated. The cache grouping is more flexible and performs better than pattern flushing.)

In addition, cached data can be expired at retrieval time by specifying a maximum age for the data, or by indicating what dates and/or times the data should expire. See the time, duration and cron attributes of the <cache> tag for more information.

Can you tell me more about grouping cache entries? How might this be used?

This is a powerful feature that makes it easy to manage your cache content. Suppose you are rendering a website and the pages that you are caching depend on various factors. Perhaps they use various shared templates, some database content, and maybe some of them depend on an external data feed. By creating a cache group for each of these factors, each cached page can be placed into the group(s) that the page is dependent on. Then when say an external datafeed is updated it is trivial to flush all pages that depend on that datafeed.

Example 1:displayProduct.jsp
...
    <cache:cache key="myKey1" groups="product100,datafeed">
        <%= myProductBean.getProduct(100).getName() %>
        <%= myDatafeedBean.getDataFeed().getTotal() %>
    </cache:cache>
    ...
Example 2:updateDatafeed.jsp
...
    <%= myDatafeedBean.refreshDatafeed() %>

    <%-- Flush all cache entries that depend on the datafeed --%>
    <cache:flush group="datafeed" scope="application">
    ...

I don't want to use the taglibs, I want to access OSCache directly from within my application. Where do I start?

We'd suggest the best place to start would be to look at the GeneralCacheAdministrator class. It provides a simple wrapper for a single cache instance and should give you all the basic functionality you need. If you want to work with multiple caches or manipulate your cache beyond what GeneralCacheAdministrator provides, consider either writing your own administrator class using GeneralCacheAdministrator as a starting point, or just create and use the Cache class directly. See the Javadocs for more information.

Where else can I go for help if I can't find an answer to my question here?

The best place to try is on the OSCache mailing list. It reaches a wide audience and is your best chance of getting a fast response. Remember to search the archives first to see if your question has already been answered.

Got a question you'd like to ask? Ask us and we'll add it to the FAQ.

oscache-2.4.1.orig/docs/wiki/JSP Tags.html0000644000175000017500000004046010615667236020134 0ustar twernertwerner OSCache - Tags

OSCache comes with a JSP tag library that controls all its major functions. The tags are listed below with descriptions, attributes and examples of use.

For instructions on installing OSCache in a web application, see the Installation Guide. You just have to add the following line declaring the OSCache custom tag library for use on the jsp page:

Taglib URI

<%@ taglib uri="http://www.opensymphony.com/oscache" prefix="cache" %>

In OSCache releases before 2.1.1 you have to change the URI to /oscache, see CACHE-61.

Summary

The tags are:

  • cache - The main caching tag
  • usecached - A nested tag to force using a cached version.
  • flush - To flush caches programmatically.
  • addgroup - It allows a single group name to be dynamically added to a cached block. This tag must be nested inside <cache:cache/>.
  • addgroups - It allows a comma-delimited list of group names to be dynamically added to a cached block. This tag must be nested inside <cache:cache/>.
Tag Legend
  • For all listed attributes, req means it that attribute is required and any value in [ ] is a default value. All attributes can accept runtime expressions.
  • From the title of the tag you can see whether or not the tag has a body:
    • <tag></tag> tags always have a body
    • <tag /> does not have a body
    • <tag /></tag> can have a body or not depending on the circumstances.

<cache></cache>

Description:

This is the main tag of OSCache. The body of the tag will be cached according to the attributes specified. The first time a cache is used the body content is executed and cached.

Each subsequent time the tag is run, it will check to see if the cached content is stale. Content is considered stale due to one (or more) of the following being true:

  • The cached body content has been in the cache for longer than the time specified by the time or duration attribute.
  • The cron attribute matches a date/time that is more recent than the time the body content was originally cached.
  • The scope the body content is cached in was flushed since the content was originally cached.

If the cached body content is stale, the tag will execute the body again and recache the new body content. Otherwise it will serve the cached content and the body will be skipped (resulting in a large speed increase).

Attributes:

  • key - [The request URI + query string] - The cache key, any string. This should be unique for the given scope since duplicate keys will map to the same cache entry. The default value uses an escaped version of the URI and query string of the current page.
    It is possible to specify multiple cache tags in the same page without specifying keys - in this situation an index is appended to the key of subsequent tags. However this usage is discouraged since if the flow of the page is inconsistent, or cache tags are nested, the indicies will potentially change each time the page is executed, resulting in seemingly jumbled cache entries.
  • scope - [application] - The scope of this cache (valid values are "application" and "session").
  • time - [3600] The amount of time to cache this content for (in seconds). (Default is 3600 seconds, one hour). Supplying a negative value for this attribute means that the content never expires.
  • duration - [] - The duration of this cache (this attribute is an alternative to time). duration can be specified using Simple Date Format or ISO-8601 date format.
  • cron - [] - A cron expression that determines when this cached content will expire. This allows content to be expired at particular dates and/or times, rather than once a cache entry reaches a certain age. See Cron Expressions to read more about this attribute.
  • refresh - [false] - A boolean. If true, the cache will be refreshed regardless of whether it is considered stale or not. This enables you to decide at runtime whether or not to rebuild the content.
  • mode - [] - Setting this to "silent" will prevent the body of the tag from being written to the output stream. This may be useful if you want to preload the cache with content without actually displaying that content to the user.
  • groups - [] - A comma-delimited list of group names can be provided. This allows cache entries to be grouped according to your needs. Grouping is useful when you have cached content that depends on other parts of your application or data - when that dependency changes, flushing the relevant group will cause all cache entries in that group to be expired.
  • language - [] - The ISO-639 language code to distinguish different content cached under an otherwise identical key. This is useful on a multilingual site where the same JSP code is used to render content in different languages depending on the current user's preferences.
  • refreshpolicyclass - [] - A fully-qualified classname that extends com.opensymphony.oscache.web.WebEntryRefreshPolicy. This allows you to programmatically determine whether cached content should be exipired.
  • refreshpolicyparam - [] - Any arbitrary parameters that you need to pass through to the refreshpolicyclass. Specifying this attribute without specifying a refreshpolicyclass will have no effect.
    Examples
    This will cache the JSP content using the current URI as a key (which means this must be the only cache tag on the page to work).
    
        <cache:cache>
             ... some jsp content ...
        </cache:cache>
    
        This will cache the content with a constant key in the user's session scope. Any page that uses this key will access one shared cache.
    
        <cache:cache key="foobar" scope="session">
             ... some jsp content ...
        </cache:cache>
    
        This will cache the content with a programmatic key (here a product ID) for 30 minutes. It will also refresh if the variable needRefresh 
    is true.
    
        <cache:cache key="<%= product.getId() %>" time="1800" refresh="<%= needRefresh %>">
             ... some jsp content ...
        </cache:cache>
    
        This will cache the content with a programmatic key, expiring it every morning at 2am. It will also refresh if the variable needRefresh 
    is true.
    
        <cache:cache key="<%= product.getId() %>" cron="0 2 * * *" refresh="<%= needRefresh %>">
             ... some jsp content ...
        </cache:cache>
    
        Suppose we had a dynamic list of categories that we pull from a database, and we also store currency exchange rates that get updated 
    occasionally by calling a webservice. Suppose also that we have some content that displays information about both the categories and the 
    current exchange rate values. The following example caches the body content and assigns it to two cache groups, "currencyData" and 
    "categoryList". When the exchange rates or the category list is updated, the appropriate group can be flushed causing this content (along 
    with any other content associated with that group) to be exipired and then rebuilt the next time the page is processed:
    
        <cache:cache key="<%= product.getId() %>" time="-1" group="currencyData, categories">
             ... display category list ...
             ... display currency information ...
        </cache:cache>

<usecached />

Description:

This tag is nested within a <cache> tag and tells its parent whether or not to use the cached version.

Attributes:

  • use - [true] - A boolean that tells the tag whether or not to use the cached version. (true = use cached version). This is useful for
    programmatic control of the cache.
    Example
    This is a good example of error tolerance. If an exception occurs, the cached version of this content will be output instead.
    
        <cache:cache>
             <% try { %>
             ... some jsp content ...
             <% } catch (Exception e) { %>
                  <cache:usecached />
             <% } %>
        </cache:cache>

<flush />

Description:

This tag is used to flush caches at runtime. It is especially useful because it can be coded into the administration section of your site so that admins can decide when to flush the caches.

Attributes:

  • scope - [all] - This decides what scope will be flushed. Valid values are "application", "session" and null. A null scope will flush all caches, regardless of their scope.
  • key - [] - When a key and a scope are both given, just that single cache entry will be marked to be flushed. When it is next accessed, it will be refreshed. It is not valid to specify a key without a scope.
  • group - [] - Specifying a group will cause all cache entries in the group to be flushed. It is not valid to specify a group without a scope.
  • pattern - [] - Any keys that contain this string will be flushed from the specified scope. It is not valid to specify a pattern without a scope. (Note: pattern flushing has been deprecated - you are encouraged to use the grouping functionality instead. It is more flexible and provides better performance.)
  • language - [] - The ISO-639 language code to distinguish different content cached under an otherwise identical key. This is useful on a multilingual site where the same JSP code is used to render content in different languages depending on the current user's preferences.
Example
This will flush the application scope.

    <cache:flush scope="application" />

    This will flush the cache entry with key "foobar" in the session scope.

    <cache:flush scope="session" key="foobar" />

    This will flush all cache entries in the "currencyData" group from the application scope.

    <cache:flush scope="application" group="currencyData" />

<addgroup />

Description:

This tag must be nested inside a <cache:cache/> tag. It allows a single group name to be dynamically added to a cached block. It is useful when the group a cached block should belong to are unknown until the block is actually rendered. As each group is 'discovered', this tag can be used to add the group to the block's group list.

Attributes:

  • group - req - The name of the group to add the enclosing cache block to.
Example
This will add the cache block with the key 'test1' to groups 'group1' and 'group2'.

    <cache:cache key="test1">
         <cache:addgroup group="group1" />
         ... some jsp content ...
         <cache:addgroup group="group2" />
         ... some more jsp content ...
    </cache:cache>

<addgroups /> (New! Since 2.3)

Description:

This tag must be nested inside a <cache:cache/> tag. It allows a comma-delimited list of groups names to be dynamically added to a cached block with a single tag statement. As a group list is 'discovered', this tag can be used to add the groups to the block's group list.

Attributes:

  • groups - req - The comma-delimited list of groups names to add the enclosing cache block to.
Example
This will add the cache block with the key 'test1' to groups 'group1' and 'group2'.

    <cache:cache key="test1">
         ... some jsp content ...
         <cache:addgroups groups="group1,group2" />
         ... some jsp content ...
    </cache:cache>
oscache-2.4.1.orig/docs/wiki/styles/0000755000175000017500000000000011375310610017233 5ustar twernertwerneroscache-2.4.1.orig/docs/wiki/styles/site.css0000644000175000017500000007110310615666657020740 0ustar twernertwernerbody, p, td, table, tr, .bodytext, .stepfield { font-family: Verdana, arial, sans-serif; font-size: 11px; line-height: 16px; color: #000000; font-weight: normal; } #PageContent { text-align: left; background-color: #fff; padding: 0px; margin: 0px; padding-bottom:20px; } /* ** when this stylesheet is used for the Tiny MCE Wysiwyg editor's edit area, we can't ** use an id=PageContent or class=wiki-content, so we must ** set the body style to that used for PageContent, and p to that used for wiki-content. */ body { margin: 0px; padding: 0px; text-align: center; background-color: #f0f0f0; } @media print { body { background-color: #fff; } } .monospaceInput { font:12px monospace } .wiki-content p, .commentblock p { margin: 16px 0px 16px 0px; padding: 0px; } .wiki-content-preview { padding: 5px; border-left: 1px solid #3c78b5; border-right: 1px solid #3c78b5; } ul, ol { margin-top: 2px; margin-bottom: 2px; padding-top: 0px; padding-bottom: 0px; } pre { padding: 0px; margin-top: 5px; margin-left: 15px; margin-bottom: 5px; margin-right: 5px; text-align: left; } .helpheading { font-weight: bold; background-color: #D0D9BD; border-bottom: 1px solid #3c78b5; padding: 4px 4px 4px 4px; margin: 0px; margin-top: 10px; } .helpcontent { padding: 4px 4px 20px 4px; background-color: #f5f7f1; } .code { border: 1px dashed #3c78b5; font-size: 11px; font-family: Courier; margin: 10px; line-height: 13px; } .focusedComment { background: #ffffce; } .commentBox, .focusedComment { padding: 10px; margin: 5px 0 5px 0; border: 1px #bbb solid; } .codeHeader { background-color: #f0f0f0; border-bottom: 1px dashed #3c78b5; padding: 3px; text-align: center; } .codeContent { text-align: left; background-color: #f0f0f0; padding: 3px; } .preformatted { border: 1px dashed #3c78b5; font-size: 11px; font-family: Courier; margin: 10px; line-height: 13px; } .preformattedHeader { background-color: #f0f0f0; border-bottom: 1px dashed #3c78b5; padding: 3px; text-align: center; } .preformattedContent { background-color: #f0f0f0; padding: 3px; } .panel { border: 1px dashed #3c78b5; margin: 10px; margin-top: 0px; } .panelHeader { background-color: #f0f0f0; border-bottom: 1px dashed #3c78b5; padding: 3px; text-align: center; } .panelContent { background-color: #f0f0f0; padding: 5px; } .anonymousAlert { background-color: #f0f0f0; border: 1px dashed red; font-size: 11px; padding: 10px 5px 10px 5px; margin: 4px; line-height: 13px; } .lockAlert { background-color: #f0f0f0; width: 50%; border: 1px dashed red; font-size: 11px; padding: 10px 5px 10px 5px; margin: 4px; line-height: 13px; } .code-keyword { color: #000091; background-color: inherit; } .code-object { color: #910091; background-color: inherit; } .code-quote { color: #009100; background-color: inherit; } .code-comment { color: #808080; background-color: inherit; } .code-xml .code-keyword { color: inherit; font-weight: bold; } .code-tag { color: #000091; background-color: inherit; } .breadcrumbs { background-color: #f0f0f0; border-color: #3c78b5; border-width: 1px 0px 1px 0px; border-style: solid; font-size: 11px; padding: 3px 0px 3px 0px; } .navmenu { border: 1px solid #ccc; } .menuheading { font-weight: bold; background-color: #f0f0f0; border-bottom: 1px solid #3c78b5; padding: 4px 4px 2px 4px; } .menuitems { padding: 4px 4px 20px 4px; } .rightpanel { border-left: 1px solid #ccc; border-bottom: 1px solid #ccc; } #helpheading { text-align: left; font-weight: bold; background-color: #D0D9BD; border-bottom: 1px solid #3c78b5; padding: 4px 4px 4px 4px; margin: 0px; } #helpcontent { padding: 4px 4px 4px 4px; background-color: #f5f7f1; } .helptab-unselected { font-weight: bold; padding: 5px; background-color: #f5f7f1; } .helptab-selected { font-weight: bold; background-color: #D0D9BD; padding: 5px; } .helptabs { margin: 0px; background-color: #f5f7f1; padding: 5px; } .infopanel-heading { font-weight: bold; padding: 4px 0px 2px 0px; } .pagebody { } .pageheader { padding: 5px 5px 5px 0px; border-bottom: 1px solid #3c78b5; } .pagetitle { font-size: 22px; font-weight: bold; font-family: Arial, sans-serif; color: #003366; } .newpagetitle { color: #ccc !important; } .steptitle { font-size: 18px; font-weight: bold; font-family: Arial, sans-serif; color: #003366; margin-bottom: 7px; } .substeptitle { font-size: 12px; font-weight: bold; font-family: Arial, sans-serif; color: #003366; margin: 2px 4px 4px 4px; padding: 2px 4px 1px 4px; } .stepdesc { font-family: Verdana, arial, sans-serif; font-size: 11px; line-height: 16px; font-weight: normal; color: #666666; margin-top: 7px; margin-bottom: 7px; } .steplabel { font-weight: bold; margin-right: 4px; color: black; float: left; width: 15%; text-align: right; } .stepfield { background: #f0f0f0; padding: 5px; } .submitButtons{ margin-top:5px; text-align:right; } .formtitle { font-size: 12px; font-weight: bold; font-family: Arial, sans-serif; color: #003366; } .sectionbottom { border-bottom: 1px solid #3c78b5; } .topRow { border-top: 2px solid #3c78b5; } .tabletitle { font-size: 14px; font-weight: bold; font-family: Arial, sans-serif; padding: 3px 0px 2px 0px; margin: 8px 4px 2px 0px; color: #003366; border-bottom: 2px solid #3c78b5; } .pagesubheading { color: #666666; font-size: 10px; padding: 0px 0px 5px 0px; } HR { color: 3c78b5; height: 1; } A:link, A:visited, A:active, A:hover { color: #003366; } h1 A:link, h1 A:visited, h1 A:active { text-decoration: none; } h1 A:hover { border-bottom: 1px dotted #003366; } .wiki-content > :first-child, .commentblock > :first-child { margin-top: 3px; } .logocell { padding: 10px; } input { font-family: verdana, geneva, arial, sans-serif; font-size: 11px; color: #000000; } textarea, textarea.editor { font-family: verdana, geneva, arial, sans-serif; font-size: 11px; color: #333333; } /* use logoSpaceLink instead. .spacenametitle { font: 21px/31px Impact, Arial, Helvetica; font-weight: 100; color: #999999; margin: 0px; } .spacenametitle img { margin: 0 0 -4px 0; } .spacenametitle a { text-decoration: none; color: #999999; } .spacenametitle a:visited { text-decoration: none; color: #999999; }*/ .spacenametitle-printable { font: 20px/25px Impact, Arial, Helvetica; font-weight: 100; color: #999999; margin: 0px; } .spacenametitle-printable a { text-decoration: none; color: #999999; } .spacenametitle-printable a:visited { text-decoration: none; color: #999999; } .blogDate { font-weight: bold; text-decoration: none; color: black; } .blogSurtitle { background: #f0f0f0; border: 1px solid #ddd; padding: 3px; margin: 1px 1px 10px 1px; } .blogHeading { font-size: 20px; line-height: normal; font-weight: bold; padding: 0px; margin: 0px; } .blogHeading a { text-decoration: none; color: black; } .endsection { align: right; color: #666666; margin-top: 10px; } .endsectionleftnav { align: right; color: #666666; margin-top: 10px; } h1 { font-size: 24px; line-height: normal; font-weight: bold; background-color: #f0f0f0; color: #003366; border-bottom: 1px solid #3c78b5; padding: 2px; margin: 36px 0px 4px 0px; } h2 { font-size: 18px; line-height: normal; font-weight: bold; background-color: #f0f0f0; border-bottom: 1px solid #3c78b5; padding: 2px; margin: 27px 0px 4px 0px; } h3 { font-size: 14px; line-height: normal; font-weight: bold; background-color: #f0f0f0; padding: 2px; margin: 21px 0px 4px 0px; } h4 { font-size: 12px; line-height: normal; font-weight: bold; background-color: #f0f0f0; padding: 2px; margin: 18px 0px 4px 0px; } h4.search { font-size: 12px; line-height: normal; font-weight: normal; background-color: #f0f0f0; padding: 4px; margin: 18px 0px 4px 0px; } h5 { font-size: 10px; line-height: normal; font-weight: bold; background-color: #f0f0f0; padding: 2px; margin: 14px 0px 4px 0px; } h6 { font-size: 8px; line-height: normal; font-weight: bold; background-color: #f0f0f0; padding: 2px; margin: 14px 0px 4px 0px; } .smallfont { font-size: 10px; } .descfont { font-size: 10px; color: #666666; } .smallerfont { font-size: 9px; } .smalltext { color: #666666; font-size: 10px; } .smalltext a { color: #666666; } .smalltext-blue { color: #3c78b5; font-size: 10px; } .surtitle { margin-left: 1px; margin-bottom: 5px; font-size: 14px; color: #666666; } /* css hack found here: http://www.fo3nix.pwp.blueyonder.co.uk/tutorials/css/hacks/ */ .navItemOver { font-size: 10px; font-weight: bold; color: #dedede; background-color: #669900; cursor: hand; voice-family: '\'}\''; voice-family:inherit; cursor: pointer;} .navItemOver a { color: #dedede; background-color:#669900; text-decoration: none; } .navItemOver a:visited { color: #dedede; background-color:#669900; text-decoration: none; } .navItemOver a:hover { color: #dedede; background-color:#669900; text-decoration: none; } .navItem { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #99CCFF; } .navItem a { color: #666666; text-decoration: none; } .navItem a:hover { color: #666666; text-decoration: none; } .navItem a:visited { color: #666666; text-decoration: none; } div.padded { padding: 4px; } div.thickPadded { padding: 10px; } h3.macrolibrariestitle { margin: 0px 0px 0px 0px; } div.centered { text-align: center; margin: 10px; } div.centered table {margin: 0px auto; text-align: left; } .tableview table { margin: 0; } .tableview th { text-align: left; color: #003366; font-size: 12px; padding: 5px 0px 0px 5px; border-bottom: 2px solid #3c78b5; } .tableview td { text-align: left; border-color: #ccc; border-width: 0px 0px 1px 0px; border-style: solid; margin: 0; padding: 4px 10px 4px 5px; } .grid { margin: 2px 0px 5px 0px; border-collapse: collapse; } .grid th { border: 1px solid #ccc; padding: 2px 4px 2px 4px; background: #f0f0f0; text-align: center; } .grid td { border: 1px solid #ccc; padding: 3px 4px 3px 4px; } .gridHover { background-color: #f9f9f9; } td.infocell { background-color: #f0f0f0; } .label { font-weight: bold; color: #003366; } label { font-weight: bold; color: #003366; } .error { background-color: #fcc; } .errorBox { background-color: #fcc; border: 1px solid #c00; padding: 5px; margin: 5px; } .errorMessage { color: #c00; } .success { background-color: #dfd; } .successBox { background-color: #dfd; border: 1px solid #090; padding: 5px; margin-top:5px; margin-bottom:5px; } blockquote { padding-left: 10px; padding-right: 10px; margin-left: 5px; margin-right: 0px; border-left: 1px solid #3c78b5; } table.confluenceTable { margin: 5px; border-collapse: collapse; } /* Added as a temporary fix for CONF-4223. The table elements appear to be inheriting the border: none attribute from the sectionMacro class */ table.confluenceTable td.confluenceTd { border-width: 1px; border-style: solid; border-color: #ccc; padding: 3px 4px 3px 4px; } /* Added as a temporary fix for CONF-4223. The table elements appear to be inheriting the border: none attribute from the sectionMacro class */ table.confluenceTable th.confluenceTh { border-width: 1px; border-style: solid; border-color: #ccc; padding: 3px 4px 3px 4px; background-color: #f0f0f0; text-align: center; } td.confluenceTd { border-width: 1px; border-style: solid; border-color: #ccc; padding: 3px 4px 3px 4px; } th.confluenceTh { border-width: 1px; border-style: solid; border-color: #ccc; padding: 3px 4px 3px 4px; background-color: #f0f0f0; text-align: center; } DIV.small { font-size: 9px; } H1.pagename { margin-top: 0px; } IMG.inline {} .loginform { margin: 5px; border: 1px solid #ccc; } /* The text how the "This is a preview" comment should be shown. */ .previewnote { text-align: center; font-size: 11px; color: red; } /* How the preview content should be shown */ .previewcontent { background: #E0E0E0; } /* How the system messages should be shown (DisplayMessage.jsp) */ .messagecontent { background: #E0E0E0; } /* How the "This page has been modified..." -comment should be shown. */ .conflictnote { } .createlink { color: maroon; } a.createlink { color: maroon; } .templateparameter { font-size: 9px; color: darkblue; } .diffadded { background: #ddffdd; padding: 1px 1px 1px 4px; border-left: 4px solid darkgreen; } .diffdeleted { color: #999; background: #ffdddd; padding: 1px 1px 1px 4px; border-left: 4px solid darkred; } .diffnochange { padding: 1px 1px 1px 4px; border-left: 4px solid lightgrey; } .differror { background: brown; } .diff { font-family: lucida console, courier new, fixed-width; font-size: 12px; line-height: 14px; } .diffaddedchars { background-color:#99ff99; font-weight:bolder; } .diffremovedchars { background-color:#ff9999; text-decoration: line-through; font-weight:bolder; } .greybackground { background: #f0f0f0 } .greybox { border: 1px solid #ddd; padding: 3px; margin: 1px 1px 10px 1px; } .borderedGreyBox { border: 1px solid #cccccc; background-color: #f0f0f0; padding: 10px; } .greyboxfilled { border: 1px solid #ddd; background: #f0f0f0; padding: 3px; margin: 1px 1px 10px 1px; } .navBackgroundBox { padding: 5px 5px 5px 5px; font-size: 22px; font-weight: bold; font-family: Arial, sans-serif; color: white; background: #99CCFF; text-decoration: none; } .previewBoxTop { background-color: #f0f0f0; border-width: 1px 1px 0px 1px; border-style: solid; border-color: #3c78b5; padding: 5px; margin: 5px 0px 0px 0px; text-align: center; } .previewContent { background-color: #fff; border-color: #3c78b5; border-width: 0px 1px 0px 1px; border-style: solid; padding: 10px; margin: 0px; } .previewBoxBottom { background-color: #f0f0f0; border-width: 0px 1px 1px 1px; border-style: solid; border-color: #3c78b5; padding: 5px; margin: 0px 0px 5px 0px; text-align: center; } .functionbox { background-color: #f0f0f0; border: 1px solid #3c78b5; padding: 3px; margin: 1px 1px 10px 1px; } .functionbox-greyborder { background-color: #f0f0f0; border: 1px solid #ddd; padding: 3px; margin: 1px 1px 10px 1px; } .search-highlight { background-color: #ffffcc; } /* normal (white) background */ .rowNormal { background-color: #ffffff; } /* alternate (pale yellow) background */ .rowAlternate { background-color: #f7f7f7; } /* used in the list attachments table */ .rowAlternateNoBottomColor { background-color: #f7f7f7; } .rowAlternateNoBottomNoColor { } .rowAlternateNoBottomColor td { border-bottom: 0px; } .rowAlternateNoBottomNoColor td { border-bottom: 0px; } /* row highlight (grey) background */ .rowHighlight { background-color: #f0f0f0; } TD.greenbar {FONT-SIZE: 2px; BACKGROUND: #00df00; BORDER: 1px solid #9c9c9c; PADDING: 0px; } TD.redbar {FONT-SIZE: 2px; BACKGROUND: #df0000; BORDER: 1px solid #9c9c9c; PADDING: 0px; } TD.darkredbar {FONT-SIZE: 2px; BACKGROUND: #af0000; BORDER: 1px solid #9c9c9c; PADDING: 0px; } TR.testpassed {FONT-SIZE: 2px; BACKGROUND: #ddffdd; PADDING: 0px; } TR.testfailed {FONT-SIZE: 2px; BACKGROUND: #ffdddd; PADDING: 0px; } .toolbar { margin: 0px; border-collapse: collapse; } .toolbar td { border: 1px solid #ccc; padding: 2px 2px 2px 2px; color: #ccc; } td.noformatting { border-width: 0px; border-style: none; text-align: center; padding: 0px; } .commentblock { margin: 12px 0 12px 0; } /* * Divs displaying the license information, if necessary. */ .license-eval, .license-none, .license-nonprofit { border-top: 1px solid #bbbbbb; text-align: center; font-size: 10px; font-family: Verdana, Arial, Helvetica, sans-serif; } .license-eval, .license-none { background-color: #ffcccc; } .license-eval b, .license-none b { color: #990000 } .license-nonprofit { background-color: #ffffff; } /* * The shadow at the bottom of the page between the main content and the * "powered by" section. */ .bottomshadow { height: 12px; background-image: url("$req.contextPath/images/border/border_bottom.gif"); background-repeat: repeat-x; } /* * Styling of the operations box */ .navmenu .operations li, .navmenu .operations ul { list-style: none; margin-left: 0; padding-left: 0; } .navmenu .operations ul { margin-bottom: 9px; } .navmenu .label { font-weight: inherit; } /* * Styling of ops as a toolbar */ .toolbar div { display: none; } .toolbar .label { display: none; } .toolbar .operations { display: block; } .toolbar .operations ul { display: inline; list-style: none; margin-left: 10px; padding-left: 0; } .toolbar .operations li { list-style: none; display: inline; } /* list page navigational tabs */ #foldertab { padding: 3px 0px 3px 8px; margin-left: 0; border-bottom: 1px solid #99CCFF; font: bold 11px Verdana, sans-serif; } #foldertab li { list-style: none; margin: 0; display: inline; } #foldertab li a { padding: 3px 0.5em; margin-left: 3px; border: 1px solid #99CCFF; border-bottom: none; background: #99CCFF; text-decoration: none; } #foldertab li a:link { color: #666666; } #foldertab li a:visited { color: #666666; } #foldertab li a:hover { color: #dedede; background: #669900; border-color: #669900; } #foldertab li a.current { background: white; border-bottom: 1px solid white; color: black; } #foldertab li a.current:link { color: black; } #foldertab li a.current:visited { color: black; } #foldertab li a.current:hover { background: white; border-bottom: 1px solid white; color: black; } /* alphabet list */ ul#squaretab { margin-left: 0; padding-left: 0; white-space: nowrap; font: bold 8px Verdana, sans-serif; } #squaretab li { display: inline; list-style-type: none; } #squaretab a { padding: 2px 6px; border: 1px solid #99CCFF; } #squaretab a:link, #squaretab a:visited { color: #fff; background-color: #99CCFF; text-decoration: none; } #squaretab a:hover { color: #dedede; background-color: #669900; border-color: #669900; text-decoration: none; } #squaretab li a#current { background: white; color: black; } .blogcalendar * { font-family:verdana, arial, sans-serif; font-size:x-small; font-weight:normal; line-height:140%; padding:2px; } table.blogcalendar { border: 1px solid #3c78b5; } .blogcalendar th.calendarhead, a.calendarhead { font-size:x-small; font-weight:bold; padding:2px; text-transform:uppercase; background-color: #99CCFF; color: #ffffff; letter-spacing: .3em; text-transform: uppercase; } .calendarhead:visited {color: white;} .calendarhead:active {color: white;} .calendarhead:hover {color: white;} .blogcalendar th { font-size:x-small; font-weight:bold; padding:2px; background-color:#f0f0f0; } .blogcalendar td { font-size:x-small; font-weight:normal; } .searchGroup { padding: 0 0 10px 0; background: #f0f0f0; } .searchGroupHeading { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #99CCFF; padding: 2px 4px 1px 4px; } .searchItem { padding: 1px 4px 1px 4px; } .searchItemSelected { padding: 1px 4px 1px 4px; font-weight: bold; background: #ddd; } /* permissions page styles */ .permissionHeading { border-bottom: #bbb; border-width: 0 0 1px 0; border-style: solid; font-size: 16px; text-align: left; } .permissionTab { border-width: 0 0 0 1px; border-style: solid; background: #99CCFF; color: #666666; font-size: 10px; } .permissionSuperTab { border-width: 0 0 0 1px; border-style: solid; background: #669900; color: #dedede; } .permissionCell { border-left: #bbb; border-width: 0 0 0 1px; border-style: solid; } /* warning panel */ .warningPanel { background: #FFFFCE; border:#F0C000 1px solid; padding: 8px; margin: 10px; } /* alert panel */ .alertPanel { background: #FFCCCC; border:#C00 1px solid; padding: 8px; margin: 10px; } /* info panel */ .infoPanel { background: #D8E4F1; border:#3c78b5 1px solid; padding: 8px; margin: 10px; } /* side menu highlighting (e.g. space content screen) */ .optionPadded { padding: 2px; } .optionSelected { background-color: #ffffcc; padding: 2px; border: 1px solid #ddd; margin: -1px; } .optionSelected a { font-weight: bold; text-decoration: none; color: black; } /* information macros */ .noteMacro { border-style: solid; border-width: 1px; border-color: #F0C000; background-color: #FFFFCE; text-align:left; margin-top: 5px; margin-bottom: 5px} .warningMacro { border-style: solid; border-width: 1px; border-color: #c00; background-color: #fcc; text-align:left; margin-top: 5px; margin-bottom: 5px} .infoMacro { border-style: solid; border-width: 1px; border-color: #3c78b5; background-color: #D8E4F1; text-align:left; margin-top: 5px; margin-bottom: 5px} .tipMacro { border-style: solid; border-width: 1px; border-color: #090; background-color: #dfd; text-align:left; margin-top: 5px; margin-bottom: 5px} .informationMacroPadding { padding: 5px 0 0 5px; } table.infoMacro td, table.warningMacro td, table.tipMacro td, table.noteMacro td, table.sectionMacro td { border: none; } table.sectionMacroWithBorder td.columnMacro { border-style: dashed; border-width: 1px; border-color: #cccccc;} .pagecontent { padding: 10px; text-align: left; } /* styles for links in the top bar */ .topBarDiv a:link {color: #ffffff;} .topBarDiv a:visited {color: #ffffff;} .topBarDiv a:active {color: #ffffff;} .topBarDiv a:hover {color: #ffffff;} .topBarDiv {color: #ffffff;} .topBar { background-color: #669900; } /* styles for extended operations */ .greyLinks a:link {color: #666666; text-decoration:underline;} .greyLinks a:visited {color: #666666; text-decoration:underline;} .greyLinks a:active {color: #666666; text-decoration:underline;} .greyLinks a:hover {color: #666666; text-decoration:underline;} .greyLinks {color: #666666; display:block; padding: 10px} .logoSpaceLink {color: #999999; text-decoration: none} .logoSpaceLink a:link {color: #999999; text-decoration: none} .logoSpaceLink a:visited {color: #999999; text-decoration: none} .logoSpaceLink a:active {color: #999999; text-decoration: none} .logoSpaceLink a:hover {color: #003366; text-decoration: none} /* basic panel (basicpanel.vmd) style */ .basicPanelContainer {border: 1px solid #99CCFF; margin-top: 2px; margin-bottom: 8px; width: 100%} .basicPanelTitle {padding: 5px; margin: 0px; background-color: #f0f0f0; color: black; font-weight: bold;} .basicPanelBody {padding: 5px; margin: 0px} .separatorLinks a:link {color: white} .separatorLinks a:visited {color: white} .separatorLinks a:active {color: white} .greynavbar {background-color: #f0f0f0; border-top: 1px solid #99CCFF; margin-top: 2px} div.headerField { float: left; width: auto; height: 100%; } .headerFloat { margin-left: auto; width: 50%; } .headerFloatLeft { float: left; margin-right: 20px; margin-bottom: 10px; } #headerRow { padding: 10px; } div.license-personal { background-color: #669900; color: #666666; } div.license-personal a { color: #666666; } .greyFormBox { border: 1px solid #cccccc; padding: 5px; } /* IE automatically adds a margin before and after form tags. Use this style to remove that */ .marginlessForm { margin: 0px; } .openPageHighlight { background-color: #ffffcc; padding: 2px; border: 1px solid #ddd; } .editPageInsertLinks, .editPageInsertLinks a { color: #666666; font-weight: bold; font-size: 10px; } /* Style for label heatmap. */ .top10 a { font-weight: bold; font-size: 2em; color: #003366; } .top25 a { font-weight: bold; font-size: 1.6em; color: #003366; } .top50 a { font-size: 1.4em; color: #003366; } .top100 a { font-size: 1.2em; color: #003366; } .heatmap { list-style:none; width: 95%; margin: 0px auto; } .heatmap a { text-decoration:none; } .heatmap a:hover { text-decoration:underline; } .heatmap li { display: inline; } .minitab { padding: 3px 0px 3px 8px; margin-left: 0; margin-top: 1px; margin-bottom: 0px; border-bottom: 1px solid #99CCFF; font: bold 9px Verdana, sans-serif; text-decoration: none; float:none; } .selectedminitab { padding: 3px 0.5em; margin-left: 3px; margin-top: 1px; border: 1px solid #99CCFF; background: white; border-bottom: 1px solid white; color: #000000; text-decoration: none; } .unselectedminitab { padding: 3px 0.5em; margin-left: 3px; margin-top: 1px; border: 1px solid #99CCFF; border-bottom: none; background: #99CCFF; color: #ffffff; text-decoration: none; } a.unselectedminitab:hover { color: #dedede; background: #669900; border-color: #669900; } a.unselectedminitab:link { color: white; } a.unselectedminitab:visited { color: white; } a.selectedminitab:link { color: black; } a.selectedminitab:visited { color: black; } .linkerror { background-color: #fcc;} a.labelOperationLink:link {text-decoration: underline} a.labelOperationLink:active {text-decoration: underline} a.labelOperationLink:visited {text-decoration: underline} a.labelOperationLink:hover {text-decoration: underline} a.newLabel:link {background-color: #ddffdd} a.newLabel:active {background-color: #ddffdd} a.newLabel:visited {background-color: #ddffdd} a.newLabel:hover {background-color: #ddffdd} ul.square {list-style-type: square} .inline-control-link { background: #ffc; font-size: 9px; color: #666; padding: 2px; text-transform: uppercase; text-decoration: none; } .inline-control-link a:link {text-decoration: none} .inline-control-link a:active {text-decoration: none} .inline-control-link a:visited {text-decoration: none} .inline-control-link a:hover {text-decoration: none} .inline-control-link { background: #ffc; font-size: 9px; color: #666; padding: 2px; text-transform: uppercase; text-decoration: none; cursor: pointer; } div.auto_complete { width: 350px; background: #fff; } div.auto_complete ul { border: 1px solid #888; margin: 0; padding: 0; width: 100%; list-style-type: none; } div.auto_complete ul li { margin: 0; padding: 3px; } div.auto_complete ul li.selected { background-color: #ffb; } div.auto_complete ul strong.highlight { color: #800; margin: 0; padding: 0; } /******* Edit Page Styles *******/ .toogleFormDiv{ border:1px solid #A7A6AA; background-color:white; padding:5px; margin-top: 5px; } .toogleInfoDiv{ border:1px solid #A7A6AA; background-color:white; display:none; padding:5px; margin-top: 10px; } .inputSection{ margin-bottom:20px; } #editBox{ border:1px solid lightgray; background-color:#F0F0F0; } /******* Left Navigation Theme Styles ********/ .leftnav li a { text-decoration:none; color:white; margin:0px; display:block; padding:2px; padding-left:5px; background-color: #99CCFF; border-top:1px solid #99CCFF; } .leftnav li a:active {color:white;} .leftnav li a:visited {color:white;} .leftnav li a:hover {background-color: #669900; color:white;} /* Added by Shaun during i18n */ .replaced { background-color: #33CC66; } .topPadding { margin-top: 20px; } /* new form style */ .form-block { padding: 6px; } .form-error-block { padding: 6px; background: #fcc; border-top: #f0f0f0 1px solid; border-bottom: #f0f0f0 1px solid; margin-bottom: 6px; padding: 0 12px 0 12px; } .form-element-large { font-size: 16px; font-weight: bold; font-family: Arial, sans-serif; color: #003366; } .form-element-small { font-size: 12px; font-weight: bold; font-family: Arial, sans-serif; color: #003366; } .form-header { background: lightyellow; border-top: #f0f0f0 1px solid; border-bottom: #f0f0f0 1px solid; margin-bottom: 6px; padding: 0 12px 0 12px; } .form-header p, .form-block p, .form-error-block p { line-height: normal; margin: 12px 0 12px 0; } .form-example { color: #888; font-size: 11px; } .form-divider { border-bottom: #ccc 1px solid; margin-bottom: 6px; } .form-buttons { margin-top: 6px; border-top: #ccc 1px solid; border-bottom: #ccc 1px solid; background: #f0f0f0; padding: 10px; text-align: center; } .form-buttons input { width: 100px; } .form-block .error { padding: 6px; margin-bottom: 6px; }oscache-2.4.1.orig/docs/wiki/What is OSCache.html0000644000175000017500000000621210315621364021330 0ustar twernertwerner OSCache - is OSCache

OSCache is a widely used, high performance J2EE caching framework.

The Problems Solved

OSCache solves fundamental problems for dynamic websites:

  1. Caching Dynamic Content - Dynamic content of some form must often be executed during each request, but sometimes that content doesn't change every request. Caching the whole page does not help because sections of the page change every request.
    • OSCache solves this problem by providing a means to cache sections of JSP pages.
  2. Caching Binary Content - Generated images and PDFs can be very costly in terms of server load.
    • OSCache solves this problem through a Servlet 2.3 CachingFilter which can cache any URI (such as an entire page or a generated image/PDF)
  3. Error Tolerance - If one error occurs somewhere on your dynamic page, chances are the whole page will be returned as an error, even if 95% of the page executed correctly.
    • OSCache solves this problem by allowing you to serve the cached content in the event of an error, and then reporting the error appropriately.
Brief Feature List

In addition to it's servlet-specific features, OSCache can be used as a generic caching solution for any Java application. A few of its generic features include:

  • Caching of Arbitrary Objects - You are not restricted to caching portions of JSP pages or HTTP requests. Any Java object can be cached.
  • Comprehensive API - The OSCache API gives you full programmatic control over all of OSCache's features.
  • Persistent Caching - The cache can optionally be disk-based, thereby allowing expensive-to-create data to remain cached even across application restarts.
  • Clustering - Support for clustering of cached data can be enabled with a single configuration parameter. No code changes required.
  • Expiry of Cache Entries - You have a huge amount of control over how cached objects expire, including pluggable RefreshPolicies if the default functionality does not meet your requirements.

We encourage you to take a look at the full Feature List to see what else OSCache has to offer.

oscache-2.4.1.orig/docs/wiki/OSCache 1.6.html0000644000175000017500000000231010402251442020321 0ustar twernertwerner OSCache - OSCache 1.6

Release Notes

(5th September, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Changed the CacheEntry so that it caches Object rather than String (allowing image caching) (Serge Knystautas, sergek@lokitech.com)
  • Cached objects are now serialized to disk so cannot be read by humans anymore (this allows us to cache Object) (Serge Knystautas, sergek@lokitech.com)
  • Added a Servlet 2.3 CacheFilter (and associated response classes) that caches whole requests (Serge Knystautas, sergek@lokitech.com)
  • Minor changes to CacheAdministrator (the way Cache and CacheEntry's are retrieved) - merging Serge and Todd's changes
oscache-2.4.1.orig/docs/wiki/License.html0000644000175000017500000000141110615670675020175 0ustar twernertwerner OSCache - License

All OpenSymphony projects use the OpenSymphony License, which is a modified Apache License. You can find the license at http://www.opensymphony.com/oscache/license.action

oscache-2.4.1.orig/docs/wiki/7147/0000755000175000017500000000000011375310613016315 5ustar twernertwerneroscache-2.4.1.orig/docs/wiki/7147/CacheChainModel_v3.jpg0000644000175000017500000022757610615666657022423 0ustar twernertwernerÿØÿàJFIF``ÿÛC   %# , #&')*)-0-(0%()(ÿÛC   (((((((((((((((((((((((((((((((((((((((((((((((((((ÿÀq"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ú¦Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Šó¯išö½à½W¼ñLjçPÓíîåX­ôðŠòF¬BƒjN2N2MmÿÂ/«ÿÐ÷âOûñ§ò-uTW+ÿ¾¯ÿC߉?ïÆÿÈ´Â/«ÿÐ÷âOûñ§ò-uTW+ÿ¾¯ÿC߉?ïÆÿÈ´Â/«ÿÐ÷âOûñ§ò-uTW+ÿ¾¯ÿC߉?ïÆÿÈ´Â/«ÿÐ÷âOûñ§ò-uTW+ÿ¾¯ÿC߉?ïÆÿȵŸwm¬h>$𪷊µ}JÛPÔ$´žÞò0Œ‚ÎâPAŠ`CDŸÅë@ÕQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@W!©_xŽóÆ—ÚF‡}¤XÛYéö·lך|—O#Í% ÏP±ûÆ€:ú+•ûŽ?èaðßþgÿäÊ>Ããú|7ÿ‚ÿù2€:ª+•ûŽ?èaðßþgÿäÊ>Ããú|7ÿ‚ÿù2€:ª+•ûŽ?èaðßþgÿäÊ>Ããú|7ÿ‚ÿù2€:ª+•ûŽ?èaðßþgÿäÊ>Ããú|7ÿ‚ÿù2€:ª+•ûŽ?èaðßþgÿäÊ>Ããú|7ÿ‚ÿù2€:ª+•ûŽ?èaðßþgÿäʵà]RûWðù¸ÕZÙ¯b½¼³‘í¢h£"êXCfb¹ƒÇ’y ‚Š( Wá?ü’ÏÿØËÿD%uUÊü'ÿ’YàßûÙè„®cꇋ›þè"Q…M¼:jØÛJ!>V$UÜýî;ÆÞ6©”Ôj»¶{Ç´[ˆZê4€øWÿ¡7Ãø+ƒÿ‰£þÇÿèMðßþ àÿâkª¢€9_øWÿ¡7Ãø+ƒÿ‰£þÇÿèMðßþ àÿâkª¬Áâ ¬þÖº¶žm2Î)³%C»8ÉV ô ô4‘ÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üMX—Æš~'ŸA:…·Û­­…ÕÎgVÝ€»òÀäîÀe'—:‘ëd“à z›M: "EKH¤1 £<‚#rìèhþÇÿèMðßþ àÿâhÿ…qàú|7ÿ‚¸?øš×ohËl× «éÂÝX¡”ܦÐÁK‘œã!Alzz yÖô¡¬ÇS±Ý€mäûBm˜`¡ÏÍœŽž´‹ÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üMtº•ÜóAkym<Ðñ,qʬÑõ0އ¯¥Z WþÇÿèMðßþ àÿâhÿ…qàú|7ÿ‚¸?øšê¨ Âz&• üIñ%®‡¦Xé¶Ï¤é²4Vvé 3™¯bœ3ì+º®WMÿ’§âûéŸú>þºª(¢Š(¢Š+ŠÔ#ÕuêZm·ˆµ-&ÊÏL³¸X좵mòK-Ò±c42¦ uõ®Ö¹]7þJŸˆì ¦èûú?áÕÿè{ñ'ýøÓ¿ùøEõúüIÿ~4ïþE®ªŠåáÕÿè{ñ'ýøÓ¿ùøEõúüIÿ~4ïþE®’òîÚÊ-åÄ6ñT+„˜à žä©¨•ÿ„_Wÿ¡ïÄŸ÷ãNÿäZ?áÕÿè{ñ'ýøÓ¿ùºª(•ÿ„_Wÿ¡ïÄŸ÷ãNÿäZ?áÕÿè{ñ'ýøÓ¿ùºª(•ÿ„_Wÿ¡ïÄŸ÷ãNÿäZµð÷PºÕüá­KP—ν¼Ó-®'“h]òQy•7÷²9àžwBñOˆµ9&M?V{Û™téï’ŽÑÍ –çÈØ¨ E„ŒŒŽÒ:ä|À€XØè¯×|s­-µæ«k­=´ZKªi¶­“À<ÁË£< ¬BFU(È%¸mÍðý¦žÚü×6søbãWOÜùÖ¶–AutC©È Ip%-°&Xƒ1·<ä€}Ey3ø³Å)­ê¾sXÃmm& «h›î.¼¨QÌ2-ºÂ¼¶ØÛ-6Ö´aˆ¦‰ânû^Ó´ˆ|B×6÷—0¯Ûcû4Ìíµ`¬‘,dµ)ÁÈ,ܨöJ+Ë!ñαgo¦ÄM¶§p×·–REåí¸”Ay$ ÿ)EO@7psGêtW+ðÓþEËÏû jßúq¸®ª¹_†Ÿò.^ØkVÿÓÅuTQEr¿ ÿä–x7þÀ¶_ú!+ª®Wá?ü’ÏÿØËÿD%uTQEPÕµ?H{Ô®’Üß\­¶üþòf U¹ Ý}(ýBÓXÓï5}CKµºŽ[ý=bk¨W9ˆH Löä)?þ±W袊(®WÆ_ò1øþÃRéºòºªå|eÿ#?ì5'þ›¯(ª¢Š(¢Š(¢Š(¢Š(®WRÿ’§áïûêú>ºªåu/ù*~ÿ°.§ÿ£ì(ª¢Š(Ôü-{qãË]sͶº³gî.‹“ƒ‚wŒÿsŸÝ´x²|<» ø:ÖY–K½J6E¡sg®ÑĬâHv¹¢<‚äŠôÊ(Ìu?†÷7Ö2E#›MñmΗsª}´^ÚÅc%ÊIƒj`²iaÊßëø]¤6à ’Õé”PŠkº‰ot"h®u;íVÏW»–Æ_*âÎ8ÿâ_9ˆ²4ÎÅ>ШJyÞS G²ñ,ºž—o¨ë:|÷è·;K›!}Šì¾]ç’Lò9T ·nXñë”PŒx‚?'ü$³Ç}¨Ö-PÛZZióÇåIölMçlÝŸ$.?3vAã-[Ú•®³§ø²[KYu¹|:Íeqw –YdùÅà”Dü°Òв'ÝV$»ŸI¢€<‹M‡ÅoâhÜjÔRßÁöHnì$–i-xó<ÉË‚|ÁûÄiì<¿«Ó/¼@þ<ºµ)s6„»ÿysn" Àû´oÃåGªäñµZ^ÊŠ+•øOÿ$³Á¿ö²ÿÑ ]Ur¿ ÿä–x7þÀ¶_ú!(ª¢Š(¢Š(•ðoüŒ~;ÿ°Ôún³ªþ5¾ñ®³¦G¦%Êio´Oin.$0Ý•*q…äzå%BIcÁ¿ò1øïþÃQÿéºÎºªóRçWÔ|Mswm¤j0\ézF«j»ß6I%·6æ]v3:Â[£'  zÒßS»µ:ôÖÖ g 3‹²×$<ës¬äÈÄÆ Àݰ… Þ»ExÔ¾'²Ö,Å̺ô·ñÝÙ4Œ%¹–Ý£–XÆÝ¿¹©’UÚáBdm@¥Sá}†£ö/$“x†å´ÛtŽî×VÓ¬Zyl‡Êclì¬c-'ÊXç<׳Q@/¦ÇãXô›©5{ÝVâ鬑nà´²š.SÑõ4º³òR)š fö‚ûØìÿ' ·•ÑüXÿ’Yã/ûÞÿ臮ª¹_‹òK‹©Yj0#ùo%¤é2«t•$Èâ€/ÑEQQ\\ÁlЭÄñDÓ?•w ½ðNÕÏS€N¡¢;˜$¹–Þ9âkˆB´‘+‚È;I@88õÁ  h¢Š(¢Š+•øiÿ"åçý†µoý8ÜWU\¯ÃOù/?ì5«éÆâ€:ª(¢€9_„ÿòK<ÿ`[/ý•ÕWü.Ôv|3ðŠlé1íÒ-ÇO™rœÞ]?ö§ýGtoûãÿ¶Ò¸µÉøÿB»×΃¦V(¯e{‰CaF²¹\y"I#àd瞀‘ûSþ£º7ýñÿÛhþÔÿ¨îÿ|öÚ. žñÚx‚k½=&¸Õ,¬^X<õ ÉöË©g„|À1H¥âð%wVF›áë;Äöö7~ÚÍm¨Kk¦n‚%Ó@Cå¦%JŒ`å†âoQþÔÿ¨îÿ|öÚ?µ?ê;£ßý¶‹oÃ6—vÒ¬õ;µ_ÛÚEÄùÿ["  ߉þ5¥X_ÚŸõÑ¿ïþÛGö§ýGtoûãÿ¶Ñp7k•ñ—üŒ~ÿ°ÔŸún¼«¿ÚŸõÑ¿ïþÛX ¼ûGм ŸÚZ}Ö5yNËuÃø—Þs÷Ûý¼¢Š)€QEQEQEW+©ÉSð÷ýu?ýa]Urº—ü•?ØSÿÑöÕV§®\G¬K¥é6ööU»˜<þJ¢32Æ3ƒ–c˜ã)ÉVíajº-Ôº¿öž…ܰ-­ÃIoç #R̘— ¥ß‘óœ©ãê/Òtµ·£ÜÚË%ºÜɶ’O³FsóLQYbPC Î@ùO<¯âOišF›«M‹»Ë{™ÜnEšHbi.Ò»°§ dŽN85CÆŸÄ)$Ûb—N6-ö›9‘°ãÎBB¹Þ7„\l#4ýWÁWWz·¢ZëFÛLÔ–ÿ1ý•]Õî„…²Å¹UyYÀOA» ˆü[£HÓªÝH%†EˆÄöò¬Ž[qBˆWs«rAk`œgÜxÎ /c·ÒÒÖa%¸ž9nî~Ì’î†$Ê’dR„26åsÖ«x¯áý—‰5×Ô¯ÚÚuÙh#µº´YáݺåÕŽ2ݰÇJ‚zYµðŒ¶Z$ZU¥Îš,V"†Õô¨¾Î¬]زF…Bçy%†¥‹C¦üBÓ®XKûMJÂm6ò;…ìæ’IehV]±ª!óeÆwÊ¡ó±Ô˜bø“¥]k7Z}ŠLÂdMÄöóÅ5ÅÑ·1îòŽXc«nRWˤKðú[k í,µ—1Iqos‹¸Zo1¢´Kb³aÔȬ±ÆýT‡\äŽ*+?†ÆÔÈ#ÕIgµ™ÁµÇü{êR^ \>|׌ñº@Ú@-ø£âv :Äæúêá¯âÓÂÁcpèÒ4ŠŽ©"ÆUÝbQIbWn7+béÂÈOu2)k›«tŽÝ%™›È•ãr n6|ØRà3 1ç5Ÿ‡—ºŽµ-êk±[Änâ¾DŽË $‘Ì’¢ÌDdE1¨E|—<çRÏÁÓX<6šÇÚ“¤²[ïO.òçí …7U„`6yÚxç{Jñžƒ«jÙé×Í;ÊHŠU‚AÌqXæ+å» *¬HÁÈà×C\n‰àûý;ÄÃTŸ\ጊ¶‚nX®?|ÈÂ6¨ÄjÜ ±ç=•rºoü•?ÿØLÿÑ÷õÕW+¦ÿÉSñýtÏý]UQEQEÊé¿òTüCÿ`]3ÿGß×U\®›ÿ%OÄ?öÓ?ô}ýuTQEfjÚî¤È±ßNË#FÒùqÄò°EÆç*€£#$ñZóGqsA"É ŠC)ãÍjVÚ†â¹õ‹ :MIo,¢²hÒTŒÀÑ<®¬w‘ò·œC’6.öä¾#ø[VÖ\µ¦‹óǤùVrÀÑkt‡å2°1Œ˜ö¼`1ä3( @¥êÚ…®‘¥^êZ„¾M•œ/q<›Kl³IÀ€3V«Ëæëû"úÊs>•z/¨`¦pb’&P[p– nQ’:€ =/R´Õ y¬e2*HÑ8dddqÕYX§§wr¸OéÚ–½áø–_Å"½ð–{ñI#B#e•˜Bï»fU™”(È%•k Hðž«kjñêš/ö”>L°YÚý±bmöÉÝX:Ÿ4O1¹X >èôí3PµÔíž{|Ø’i­Ù¶•Ä‘HÑÈ9££ ô8ÈÈæªx‡_Óü? ¬š“\ÿ¥Möx#¶´–æI$ØÏ€‘+1ùQÎq€מ_x+X}:9t¸Ç^›SÖ·êê;YÅñ·%ÉMò[>Á’€A#.oj¶§O˜éþ$¿¶‹Q†y­áÔm-glî£/ƒìê¿<ÑÅ÷¸€±iwðêv^[%ÊE&v­Í´–ò 9ŽEV^ÀÈÁKi}mw=ä6ò‰%³”A:€væ4)ÿ€H‡ñ®"/ &­¨øûKD¼þƇN¿†{]féo%I^{fŒHÆY7äG#™‚€¿t€)àŸ‡º…Ò†³¡Ûy“êך¤¬ao9±Þ „¹ûQrz‚f-“— Úë•ø±ÿ$³Æ_ö½ÿÑY:.˜Ïñ'R‰$¦i’5üh½#º¹@ÞU¹—Bµ¾,É,ñ—ýoôCÐUEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\®›ÿ%OÄ?öÓ?ô}ýuUÇ[µÒüS×þË 2Ä—MÝæJS¿¾Æ0§4¡ãý>çSðµÅµ”&áüëyd· ¸…'凞øÕÓîÁàšâu‹kQ‹Æ§‡ôù ¶ðZ?ö]Å•÷ÚV<Åî|˃¼†® (Rß5zO›©ÿÏ—þ7ÿ£ÍÔÿçÎËÿ›ÿÒ¸Úë~'–ÎÙµÉ':¬–Oûé-M‘òÍÏšç(&ç Ç#÷AÍÝê^"‹Dð„s6½oqceke©Ë(–?:ìßi¨À;`HÄyà9%X;`_ÁæêóçeÿMÿÆê+˜ï.£ÝiºtчIÉpÌ£VÁ‹¨eÄÚ‹ç:¶“«k0iÇ óZ¦¿,Út·Ñ»ËmÓfòå¿Ì \“´·8(:‘Uímu”jÇMÔ­îµk>áŒÑΡ®î²…”/¹ˆ2§Ï…Á*kÔüÝOþ|ì¿ð)¿øÝn§ÿ>v_øßün‹æ^ÓõG_];Q—Ä1hb;Æ{¸š{D ŽÞgÞ{’71np ¡¥Ïâ«™4ËøüA©·J3£-Àˆ£‹qrJ(® Ì]ZE*Äm\õÏ7SÿŸ;/ü oþ7G›©ÿÏ—þ7ÿ¢àxíÅß‹ –62êñk­£É.¢n7Éœ]Y‰Z÷®à#3íÛ´`€¬¶:? Yëïâ]>-ZûU¹Ó•/æó>Ï=œ{–K/)Hi]ÈÏžG˜Ùa¼cg^ÎÊÂK $’ÇFÒ-¤í » c¦H‹žµsÍÔÿçÎËÿ›ÿÑp/W+ðÓþEËÏû jßúq¸­Ï7SÿŸ;/ü oþ7X?  Ý«ÿljÛ‚œ€´.: þTÀë(¢Šó†^>ðuŸÃo ÚÞx³Ãð\Á¤ÚG,RêP«Æë ¬ dAéácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øªÄÕüYáÍ{žµÐõý#R¹MZY+;ØæuA§ÞÄ+Œ3î+Ñh Š( Š( Š( Š( ¸¯&ÿ‰žMÌßñ(Ô¾[y|¶¾±ç;—l×k\‡Š¥gãMW°Ñ/µkh4ûÛIVÎXãydµd$M$`‚!~„öõ  /#þ¡úÏþÿöê<ú‡ë?øÿÛª—ü%¿ýž$ÿ¿úwÿ%Qÿ F¯ÿB'‰?ïþÿÉT¬ß#þ¡úÏþÿöê<ú‡ë?øÿÛª—ü%¿ýž$ÿ¿úwÿ%Qÿ F¯ÿB'‰?ïþÿÉTX ¾GýCõŸüÿíÔyõÖð?ÿ·U/øJ5úŸeiÞK<—LädÉÔŽþ•×Ó¢Š(¢Š(®®¾ÍñO]ÿN²´Ý¢é¿ñò¹ÝûûîŸ:ôüzŠîk€»ñ‡áÿŠzßöö³¦éž~‹§y_mºH|ͳßnÛ¸Œã#8é‘@ö§ýGtoûãÿ¶Ñý©ÿQÝþøÿíµKþ?ÿèrðßþ ÿâ¨ÿ…àú¼7ÿƒH?øªVïö§ýGtoûãÿ¶Ñý©ÿQÝþøÿíµKþ?ÿèrðßþ ÿâ¨ÿ…àú¼7ÿƒH?øª,ßíOúŽèß÷Çÿm£ûSþ£º7ýñÿÛj—ü,ÿÐåá¿üAÿÅQÿ Àÿô9xoÿñTX ¿ÚŸõÑ¿ïþÛGö§ýGtoûãÿ¶Õ/øXþÿ¡ËÃø4ƒÿŠ£þ?ÿèrðßþ ÿ⨰µ?ê;£ßý¶©|'ÿ’YàßûÙè„£þ?ÿèrðßþ ÿâ¨øOÿ$³Á¿ö²ÿÑ Bª¢Š)€QEÁø~óìþ*ñÊiiö¹Õâ;.,â_gÏß^?Õ¿ý©ÿQÝþøÿíµËé,ðæƒâßZëšþ‘¦Ü¾­‹åìp»!ÓìÀ`ÆAö5·ÿ Àÿô9xoÿñT¬ßíOúŽèß÷Çÿm£ûSþ£º7ýñÿÛj—ü,ÿÐåá¿üAÿÅQÿ Àÿô9xoÿñTX ¿ÚŸõÑ¿ïþÛGö§ýGtoûãÿ¶Õ/øXþÿ¡ËÃø4ƒÿŠ£þ?ÿèrðßþ ÿ⨰µ?ê;£ßý¶íOúŽèß÷Çÿmª_ð±üÿC—†ÿðiÿGü,ÿÐåá¿üAÿÅQ`.ÿjÔwFÿ¾?ûmsuÿ ü\ŸÛ:L›´‹±±æoÜ¿÷‡ŸÀÖ×ü,ÿÐåá¿üAÿÅW5ñ7ÇÞ¼ømâË[?x~{™ô›¸âŠ-Jy¡p@l’IE€ôú(¢˜Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@qÖöv·õÿµ[C>ÝMÛæ lf{ìã?Jìk[ðŸ‡5뤺×4 #R¹D¬·–QÌꀒRq’N=Í\þÇÓ?èeÿ~ü(þÇÓ?èeÿ~ü+þÇÿèMðßþ àÿâhÿ…qàú|7ÿ‚¸?øšV@ncéŸô²ÿ¿ þcéŸô²ÿ¿ þ‡ÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üM@ncéŸô²ÿ¿ þcéŸô²ÿ¿ þ‡ÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üM@ncéŸô²ÿ¿ þcéŸô²ÿ¿ þ‡ÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üM@ncéŸô²ÿ¿ þcéŸô²ÿ¿ þåþx:ïÅ^’ ÆÂ1«¦€%¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(•ñ—üŒ~ÿ°ÔŸún¼®ª¹_ÈÇàOû Iÿ¦ëÊâ¿á6ñWü/Ÿì¯øGu¿øC¼Ÿ±}¯û>_'ÏûÞ~ý¸ÛŸ“9Æ>n”ëôV¹ªÞïiºN˜¶Â{«{‹¶’à1P´JTGÌÆeç°àô®OOñþ£6‡.¯46Ÿe³ð½§ˆnbHØ<­,w,cC¿ 3 ã!»ŽsétW þ*Õlüg¦xzú;%¸ž,Уªˆ¤¶½Ì$³êx*ÝéŸâ½kTÔlìl×NŠk†Ö~ycr¡lï’Þ>Ž9eo›Üä` ¤¿¢¼vïÇ×0kvúú›¯ìÛŸ Ú]8Ѥ³Gy:¶1çìÂ<÷Ü3ŠÚðö­ªX|=·2ë郞©{e%ö¨;7—u:|±Ç´ÈØŒ ¨ ÏË‚éW“¯Äv]+^½Š-0.ƒ§½ýÊ´2fç˸½‰Õ>pcÜ-27([7mÿx§PÒüFÃq¥Éf.í-ÐC+ωäŽ=í.à‘d!V,ä€;š+Íußßé6_ÚïmjúWÛu_ +yø³†éÉÝ»3Zœ|¼:“•Ÿþ}HØÞ¼VR–ŠïN·†âïKº±ŽO´Ý,,¡&‹ 9Ü :ñÔP¡ÑQÛ –Ú%¹xäœ çP^Ø®êÿT³Óô§Ô®æòì‘…ö’H8Æ ’rd’ªóxwGŸÄ1ë³éÖÒëÂ-㻑i!H'I•X€HRc<κñΛ ÖšQ'žÂöÒæàO É"42CÉT/»2¶x|¶Èë‹ZŒô=mšâø´SÀ·K,I4i }Ù]ÑJƇ ăϣµÒµY¼K¢ë£X‰-tûÛiã·/€óMnèpù‚¬, ¹8!@8^NïÀ¾"“ÀV>MBÔ¤^‹JhÄïK:ÂÈò!2£|€IÃd­uƒÆz\Váîåo1弎8í žáœ[Na€±îÈ;r s‚Ê75è6ØÏ|^;ˆée‚ &!o»,ŽŠV488g x5—á¿ _išýõĶÍÛ[‚3?l¿Žâ,dˆ„7¡Æ29¬uðf¿iᯠéúyÒ£Ô4ý&ÛOmEnfŠ[i#PÐ"tÈÈÂwÉùˆ›EPEPEPEPEP+ã/ùü ÿa©?ôÝyR醣'޵Ý6öhÞÚ K˜#0Ì–éNORH…3Î=äœÿjV6^)ø} åíµ¼³kRyi,ªŒÿè7Iò‚yùäxîê:‘]‚Û@·R],1 ™cyB ìŠXª“Ô€]È·S@ÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQ\ÿˆ|HÚF«a¦ÛhÚ–­{y × “@»#‰¢V,f–1ÖdÀž¾•Wþ_þ„Oßý;ÿ’¨ª¢¹_øJ5úöÖǮӎ•‰}ã¸mo5dMW¹°Ò¤Xîõ ¹… †9²Ê$l$©÷Päœ Ðßð®<ÿBo†ÿðWÿGü+ÿЛá¿üÁÿÄ×A.£eìvrÞ[%Üœ¤ *‡~½9=åTàñ.…<—Iµ¦Jö®±\*]FÆf ªà”– z“ŠËÿ…qàú|7ÿ‚¸?øš?á\xþ„ß ÿà®þ&º 7Q²Õ,ÖïL¼¶¼µrBÍo*È„ƒƒ†RGb­P+ÿ ãÀÿô&øoÿpñ5Â5–·áŒÓX|8ð¯‡×D¹Òm$ղؤN$¼ò˜Á9b$Fÿt´r=–¹]7þJŸˆì ¦èûú>Ýãú¼7ÿƒéÿù·xãþ…ï ÿàúþC«rk‘øêÓF{x’ÊâÆæé%Égv‰í—è£÷äc’HÏç~€9_·xãþ…ï ÿàúþC£íÞ8ÿ¡{Ãø>Ÿÿ몢€9_·xãþ…ï ÿàúþC£íÞ8ÿ¡{Ãø>Ÿÿ몢€9_·xãþ…ï ÿàúþC®+ÂvÞ$ñWüWoñ /ì0Úÿg[húÕÌ0´-Г«½›`eS„*ô®ûFñeŽ­«¶Ÿ7QËþ•弨¡%û4þDÛH$ü®W¨ 1ß´ßù*~!ÿ°.™ÿ£ïèÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(…Ô¾xOTº²ºÔàÕï.l_̵–ã\¾‘íß îŒ™‰S•S‘ŽƒÒ´?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~º[»„µµšâQ+G 4Œ"¤rÉÚŠ 1ôzRÐ+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£Ôøýt:eõ¶§¦Ú_ØJ&³º‰'†UF•†}A“UÔmt« //åò­ãÀ-´±%ˆUP$±$$’äÐ?ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£Ôøýu(ÁÑXdÈò)h•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñúÄño†ít CL¿ñ\¦­¦ÇûÝvödd’öÝYR¬ ³=kÑk•ø—ÿ"åŸý†´Ÿý8ÛÐUEPEPEPEPEPEPEPEPEPEPEÀiÚ ñOŒdÔ¯µ¿ô]N+x#¶Öní£Ž?°Ú¾E*¨ùÎq’XÐEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEq^±]#Çþ Óm®õ)¬—LÓî;ÝB{½’<·ŠÅLÎÅr#L€qòŠé5½sKЭÖ}cP¶²ŽÍ RçÑGV>Ã&€4h®{Ã~,³ñ«¨XÚZj05¤0\o¼¶h©+JªÈ­‡Æa¼£¶3] QEQErº—ü•?ØSÿÑö»®jpèº&¡ª]¬oco%Ì«îr¨¥ˆQÜàp+ Rÿ’§áïûêú>´ê©ˆåW9ôÛ-[M¿b¶:…ɬÄC2¿îÛ;_ƒ÷NN 6=gK’ÕîcÔ¬žÝ$XšUJ+±TœàY@ɵÇ÷²¥Ì2][À—6ší«Ëo1~Ýv’ÂÑ©žÈ楓ÂZ΢·wé¥YÜÏ>’>Íi+¼;¡36J)ÞêYBíÀ ƒv9yñýšš€ÕlZÅ÷ì'VGجϴƒ‚B£’@§ÐÔZWˆ"¿c{+ë=öÿjG È'iVÁW)?„Zñ_Š »K„ѧ´x—*PîbXç1äsˆãO˜dnšAÔÝ–ÇÄZ–©Xêré0´ÖRZÆÑÆÓ¬’2%tp_X¾aÉiYxD¾²–òÇYÓnm!m’O ÒÕWMñv‹¨jwßÛ­ÌwÞ%y}¨ùͺ».¡e\‘ÜÜžNÇÁ:ÊëPê×eç[µ¬‰l×rN®b[´*Ò4`ã*ÊBà2—Í5—‚u$Óõ…tˆ.¯¼Ce«¢Ú+$qÅ Ú³§+çÉ—žŒ_'nâW«ø›KÓ4}gQ71Ý&“m%ÕÔ6Ò+ʪŠÌFÜŒ”’9«z¶«k¥}•¯dŽ(§‘Ë$±Æ±…‰å,w°È }ܑԡ˜y¥ŸÂë«? êúdE%ÔÚ ÎÕΡw>ö•p£±HW*¥‚)ç¦ÁÑñLJ|Wã= ìwVš&™Ö,$³.­..¤‚YgŽO³…Š8H‘SqÄqeãùC<„îA¬]7áUôVW¶wšO†eº¸¶¶ŠsÌ-ydÑÙ[Û“ùî¼NêD‹÷‡‘^ÓEp‡€ÞçÆ—Ã?Åõ­î$¿ºa0¢(Qn#æ0Á›¡cÀX‘ü<×dm$]M¦”²Äáf}’"^ÙÎÅcòÂÄ-äZð Q–+ëTPœx‹ÀÚŽ£q¬µ¿öpº ¾ŠYÃÇÙ-á)…_âx™Ž@¤ä2z ”/og2Ï%đƨÓHi,pÉëÀÅMEÊé¿òTüCÿ`]3ÿGß×U\®›ÿ%OÄ?öÓ?ô}ýtiö²ê¶ú“Å›Ûxe·ŠMÇåŽFœc891GÉxêsjŠ(¢Š(¢Š(*ÇÃÚ]…äWV–¾]Ä_jØÞc}¦eš~ ÇÍ"«{cŠÊÓ䩸‡þÀºgþ¿®ª¹]7þJŸˆì ¦èûúꨢŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šòßh*ÔÓÆÌ·7¶×Úe彂Et±Â$xYc aêT“Æã¸ä0ò§×¼6§w¯ÝO¥[ÜÜO¯XËlòùlMK(îG'…dK•e<ºŒ`‚¹ôº(Ä-¾kQøA±Xﬣ³Ñ­ì~˧ËgÇxŽæYËÉ…w–Wó#ùø98ÿ£á mu Êîú_ çYÒ) [ U¥É'Œ}šI>^¸w\eˆ>ŸEx®à­~& ’¶IlVüG,H·Ž·6²2oV28xÒáII|1Ý·?4úçõ]GW½¸²³Ô´­:XÕ-lì¯-G•0rZf2G ƒvSýG#ËÉÉlc¢€8Ý2ÇÄ ãË«¢÷0èM¿÷wPü¸»ŽÌ¾Xz.G;‚ÅÙQEQEQEQEQEQEQEQEQEÊüKÿ‘rÏþÃZOþœm몮Wâ_ü‹–öÒôão@UQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@r¾ ÿ‘ÇöÿMÖuÕW+àßùüwÿa¨ÿôÝg@UQ@Q@Q@Q@Q@Q@Emp—1—ŒJ;lj#hÎUŠžŒƒƒÐŒH ×%ã[\ë:dº[ÜÉ¥¦>Ñ­À·üÀ¶X°ÎWé†6•àÉ®u[(üA¥Áq¥«kÏ,s”‘ ¸ÔcšÜ•ÉÎc Ý>Rpq@…i}mw=ä6ò‰%³”A:€væ4)ÿ€H‡ñ«5á¾øy®Zø{ÊšÒK û›Ë ÝFkCjÓ]ªéé±±2; ‘$§x*Û‰s:¯x.KmBäköîÈép[Cý ðÜ6ã5é’2UF"ž5ÀP¡X ,$¼Ò5;M^Å/4éLÖ²²]Œªàä Ê{0àŽA"®W…ø_áþ­¥Zøu‡ µ¼±],›ˆ » ä}©KîÞ°œ²Ç„pKÌÌNçÁZÔúv…l,®m¯, [Q¶º…¤Ô°G(hß.D¹•A\m^¹ÃEy|~ñ=–áûMMJ-÷™åº¾ŽDPÒ–EtŒ"¶Õ'*ŠÜ ÏGêQEQEQEQEQEQEå-³ñ5ßÄýSþ›µŠÙ4}?í°G*Ã<ËçÞíÊÈáHù³À'# ¸­^øGB¿S¨é×·/ÈnuÀZiO »fe÷VCô»¦ÿÉSñýtÏý]5Ä\ÀðÜD’Âãk¤ŠXzzÐu·qñKZoêZe˜þÅÓŒ¦òÁî·æ{í»vMÞùÎs‘ÓöÑj«£®¯ldÕ¶81Ú:@çaòŒ¥°8Èó9ÁåsÅOøSDðíååΉ§Çd÷iJ±#Ú…Ê…Lí@ Žp u­ºçô»OEêºÎ‰sd3æEm¤ËÁÆ®\p~éÈqœ‰µ»oÍt¡êºE°@;Í2K—/“’n#cm=<àmQ@öÑj«£®¯ldÕ¶81Ú:@çaòŒ¥°8Èó9ÁåsÆ~—i⨯â}WYÑ.l†|È­´™`‘¸8õËÎÝ9Ž3‘ÐQ@0|Ñ>!è?ø“y®;HºûKx5âko0 ›)“œJú Ïÿ¨†³ÿ€ý¦±üU|ºGü?©\ÚjSY.™¨[´–Z|÷{$ylÙCQŠäFø$cå5oþÍ#þ|üIÿ„æ£ÿÆ)X ¾ýD5Ÿüÿí4yÿõÖðÿ´Õ/øO4ùóñ'þšÿ£þÍ#þ|üIÿ„æ£ÿÆ(°|ÿúˆk?øÿÚhóÿê!¬ÿàÿiª_ðžióçâOü'5þ1Gü'šGüùø“ÿ ÍGÿŒQ`.ùÿõÖðÿ´ÑçÿÔCYÿÀþÓT¿á<Ò?çÏÄŸøNj?übøO4ùóñ'þšÿ¢À]óÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦©Ây¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1E€»çÿÔCYÿÀþÓGŸÿQ gÿ?ûMRÿ„óHÿŸ?á9¨ÿñŠ?á<Ò?çÏÄŸøNj?üb‹wÏÿ¨†³ÿ€ý¦?þ¢Ïþöš¥ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅ?…‡>œîvίªüλXÿÄÂã’00}°+®®Wá“þi$–ÞæßÏÔõ+„Žæ†O.KéÝ G—*Êp@8"ºª`QEQEÊø7þF?ÿØj?ý7Y×U\¯ƒäcñßý†£ÿÓuoêú…¾“¤ÞêWÎRÒ虀ÎÔE,Çò³lõ«´Y&ÖôÁ¦Y­©»7 pb ÷–NÖçÃóÅjj–6ú¦™w§ßF%´º…à™ñ#)Vˆ&±cÐõitëËMCÄIæÚ½¤2Û@ x÷ IËn”qó «þÈÍ:ׯZ%ÌR:\Ï#ÆžLösC3ݳlNØ6ÇÁƒµ±ÐÕñGMJâ)]×OŽÖ ‘x±Èê7Ëf|[n9£§|>–ÓRRþÒ¶[èZ !ò,Œp«Æ·(IC# —LÍFsŒµ¨x*çQ²ñ4wÚÉšç[Ñ—Iy¨_+èï d´à/\F2Ä’hïˆ|i¥én«p’}¢âÆÞæQ ‹3Ã;IJ³p r2HÁÈàÔ+ãHŸVðÖŸŒ¦]XȳfEbeŽFÚãø˜´2'eçœ-Oá>›t5ϳ:ÚmM/ówý—Ý+Ý#«fcóS+£iÆvу¶¾ …gÙ’qÝ­ÀiXÈwH~ÌT¶ýæBŒÚZ¥º×/uõDÝÞ›©-¦¶ó#Á·¶‡¦ñ—f%\ä#§­lŸh[àT¿YDæÅÈ„ÎTD7(* oR=zsKÿ v‡ök»ƒ|¶¯zòŸ }ùã÷Š=S=G¨®#þ]OO‡LÒtÙî$±[Í.êògH•%{An ]œ[dùçp67fÕÂ}7Oðþ­¥iÇN³[Ý"m%.`ÒâIöȸß,ƒæ•†Œ¨8$äà€D³¹ŽòÜM™å’Àoœ3†ãŽB0FA¹½7þJŸˆì ¦èûúê«•Ó䩸‡þÀºgþ¿ ªŠ( Š( Š( ¹]7þJŸˆì ¦èûúê«•Ó䩸‡þÀºgþ¿ ªŠ( Š( Š( Š( Š( Š( Š( Š( Š(  /Äöº”ö¢ÚÚ÷ì·eŵãF<™¶äðAÈA`Á-rÓKy”Ouž)7(FTä³|ÄB1íȵB]cNí€ß[³ŒËp‹*–‰@$–ät=j»kö±è–Â=¼W‹,wGÆ;·0\ªîf“…lg¡×¢²o|Aam´±Ê.–{űO³2¿ïKm`yLj-Ü&xŒy70ÿÄ£Mùn%óþúûœîn=³Vÿá(ÕÿèDñ'ýÿÓ¿ù*¢ð¸Ô¯ŸeiÞK<—LädÉÔŽþ”X¾Š(¦EPEP\3>ÏŠzïúEì9ÑtßøöƒÍÏïïºüÓ½w5Êé¿òTüCÿ`]3ÿGßÐß?þ¢Ïþöš<ÿúˆk?øÿÚj?xÇGð…µ´ºÌÒ¹“dPÃ’VPF÷9Ú€åÐ ³*¶å¥Ì–°ÝYÍöӢɱ8d‘d2‘ÁA8I%'³)ÆI)5£1üÿúˆk?øÿÚhóÿê!¬ÿàÿi­Ú)X“ Ïÿ¨†³ÿ€ý¦?þ¢ÏþöšÝ¢‹…çÿÔCYÿÀþÓGŸÿQ gÿ?ûMnÑE€Âóÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦·h¢ÀayÿõÖðÿ´ÑçÿÔCYÿÀþÓ[´Q`0¼ÿúˆk?øÿÚhóÿê!¬ÿàÿi­Ú(°^ýD5Ÿüÿí4yÿõÖðÿ´ÖíX /?þ¢Ïþöš<ÿúˆk?øÿÚkvŠ,ŸÿQ gÿ?ûMýD5Ÿüÿí5»E Ïÿ¨†³ÿ€ý¦?þ¢ÏþöšÝ¢‹…çÿÔCYÿÀþÓGŸÿQ gÿ?ûMnÑE€Âóÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦·h¢ÀayÿõÖðÿ´ÑçÿÔCYÿÀþÓ[´Q`0¼ÿúˆk?øÿÚhóÿê!¬ÿàÿi­Ú(°^ýD5Ÿüÿí4yÿõÖðÿ´ÖíX /?þ¢Ïþöš<ÿúˆk?øÿÚkvŠ,ŸÿQ gÿ?ûMýD5Ÿüÿí5»E Ïÿ¨†³ÿ€ý¦?þ¢ÏþöšÝ¢‹…çÿÔCYÿÀþÓGŸÿQ gÿ?ûMnÑE€Âóÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦·h¢ÀayÿõÖðÿ´×9ãÙwhöíšœŸñ:Ò¾I­6!ÿ‰…¿VòÆ?:ô å~%ÿȹgÿa­'ÿN6ôXªŠ(¦EPEPEPEPEPEPEPEPEP\¯ƒäcñßý†£ÿÓuuUÁø~Mž*ñÈûV¡üMâùmí¼Å?ñ/³ç>[síšï(¬/?þ¢Ïþöš<ÿúˆk?øÿÚi\ Ú+ Ïÿ¨†³ÿ€ý¦?þ¢Ïþöš.í…çÿÔCYÿÀþÓGŸÿQ gÿ?ûMvŠÂóÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦‹»EayÿõÖðÿ´ÑçÿÔCYÿÀþÓEÀÝ¢°¼ÿúˆk?øÿÚhóÿê!¬ÿàÿi¢à[ñ>”ºï†µm!åhWP´šÐÈ£%ˆWpúg5‰«i¾&Õl/ šçL·Ž[u·[d_69²Ëæ³³¦W(a€ÜKà ?þ¢Ïþöš<ÿúˆk?øÿÚh¸Ňƒu›¨5çÓf¿3ÞI*Ͻ¢ /•R€,É!6ü ï`róÁ³Ï­‰¢Piés`±C+åZZƒ*"¨\ç‘Àã`äb¶üÿúˆk?øÿÚhóÿê!¬ÿàÿi¢àyõÃ-JÇä&ÖmNKÓ#–ãT¼‘fŽGS;û’ \íŽ3†þ"8~+ð߈ü_§YÛj0i:jDò‰#·½’pUÐBHc såKsÆ:„ç“·¦óÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦‹ÉëŸïux¯–[‹hÌ·—:„A‚ „Iol®»~hü•a"ô$ãæšôh¬©DŒ…¢ªñÐp8übùÿõÖðÿ´ÑçÿÔCYÿÀþÓEÀÝ¢°¼ÿúˆk?øÿÚhóÿê!¬ÿàÿi¢ànÑX^ýD5Ÿüÿí4yÿõÖðÿ´Ñp7h¬/?þ¢Ïþöš<ÿúˆk?øÿÚh¸´VŸÿQ gÿ?ûMýD5Ÿüÿí4\ Ú+ Ïÿ¨†³ÿ€ý¦?þ¢Ïþöš.í…çÿÔCYÿÀþÓGŸÿQ gÿ?ûM…ñm÷‰l¾'êŸðY‰­ßGÓþÛ:D³Í‰ïv˜âg@ùù³É#ålÖ‡‡,<%â Ñý£©ÜxƒX‹çkmh”’ê,ÙQSê#ަ´¼6ûþ&xŒù×3Ä£Mù®"òØ~úûŒm^=ñ]¹ éZô ±§Û^"¡–0Z3ê­ÕO¸ Ó¹—Z¶ø£¬¯‡´Ý2í±tá ¼¾{P€O}·nÈdÝß9ÛŒ¹ã±¶—UmËuec­±È¶ŽíÞã;šb ƒÆO—ÆO Žs¼7á;MUÔ/­¯u+—»† }——&*8šVUVl¾33ýæ=ºWC@þ—wâ©oâMWFÑ-¬Ž|Émµig‘x8Â5²ÎÞžqƒ6·sâ8n‘t=+H¼¶( Iy©Éláòr­¼€Œcé㌪(>Ú]U´c-Õ•Œz¶Ç"Ú;·x Œìiˆ6>_<69ÏÒîüU-üIªèÚ%µ‘Ï™-¶­,ò/F¶@yÀûÓÎ0z (æ¿€÷Ä=oâŸü\˜u(¼ëì_mÓE¦s=¯™·»º&z㎙¯¥+•Ô¿ä©ø{þÀºŸþ°®ª€8?Æ—òJnµ ÞßC}Rm*+¸oL²‰Vé­‘¤ˆÆ¡UäP×|n\ñ’.Ây¢B¾ºÙ šáìðÏ2D‘O$%åq Ѱ%ð¹ 0=?ÁwñÊmu bÞãCMRmV+HlŒR™Zé®Qd”ÈÁ•$`FÔLí\ñj]|=¼f‹ìzävån®® ¿býô^}Ü—Ê‘dR¬<À§~õ;AØ2A·uãÌhWVVÍ©&¤tô´’vD9ÔMŠHòˆÛ`, ãi8 pMjhÞ&Xj’ëPÁ§Ï¦]}’äE9ž-å#uØûT¶D¨1´Ù¬;‡1ÜÙ_Ù]_E=ýú^ÜÃ5 t—n nÂ[(Æ#ž Žªw5¿èú„¥ðí½•–šÏ‹o ²C$‹ ÌxÚÊYFTðFGzžhó]ÁiÌ­u3:,Ú_1J4jû—nStdîÇÊÛºdÖQø‹áæ½²‚äU¸’Aæ\Å4ñÇ ’4³G¶U>X0Pwgj±áŸ[hÕµý¡°·Hb»ŒÚØéñÚÅ™ÚØä?Â-€Ën'wPÃkÕÖmodñ ¬V³K2Eo`#3Á<^dŠ]£2?9TU8 ¡ÈÚ«'Ä}µMÆÒ=Fiµ;±k†Ó®bhAŠIFVŒ­åà€FöÎØÜGñ–‚‘—kð#ù ¹‰ñ y%d;~uÞè7.@Ü2@5‡¢øîÂm>iµˆ]¬oÒò ´híÑDÂÊ¥b¬Ë3CT…ꎗðŸMÒ­í¡ÓŽj¶ïhRX4¸’yV ¨§Ä²™Øù*¹È–!Ž(«Æ$–Âeº›>cÄ`6²‰Õ‘C00•ó•¹^Œ§¡•&Ô5ë Ma¿¹šWO2ßÌDŽK{X™Ü7Ö‘¸lޤ`õ5Ûñ*ës›«÷žÞæk»­2nLƈ JGîÃyhHUàä®Òr5ô]k)§^C¥8Ò5i-î„Á›f7#ºcåWQA'¤µñ¿‡îVfKæHãŒÌ$šÞX’XÃ*@•rè2…†Y}E?@Ð/4smk©»F²R––‰n•1…G“'r ápªx-Œ×5oðÑĽֳçKoÈæ[m²;¬öóÇ,¬\ùŽÜnàÜpœ€jˆš2ëz•”í,VÖ0Á$·Iäiƒ,©³1*•‹¾ƒï\øƒL¶ÔEŒ×An<Ä„üŒU$¸ŒàmVlŒA9ê+œ¿ðM楋ÿ´u±,¾ Ò—KR¶ÑT\TnËôŒàœä›uçÃí6ãÆøƒÉÓšêk¨.ÞYô覸F‰@ŽfÉH:AÉR¤æ€44ÿ¥ß‚4/É V˪%ƒù2JÄFn^% ¹P’A”ò€N2PÂ¥ÏÄÙÛM¦;ݵĶB%x¤€IÅÄPù¨Î˜pžr’88S´š¡¤ø+\·ðΓáýC^Ón4Ý3ìAƒKxf?ežs†rÂTáG-žÛKføn%Ò|)`úžSCÓáÓÜýŸþ>U'³”œnù7 2¸çfsòà€w6jq]Z9{yFär¥wQ8=AèFà×Ë¿·?üÉ?öýÿ¶õôæ‡e&›¤ZYMqö–·ŒD%Ù³rŽ#'œc>§ž:WÌ·?üÉ?öýÿ¶ôõUQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@rºoü•?ÿØLÿÑ÷õÕW+¦ÿÉSñýtÏý@[ûGø[TŠðøßM\ÛYØ-½Õ´`’‰I&ò¿Ä§Ì °hnP¾Ýß„Š|+ðYºÔ­^]ZCs©iús‚‰JDSø H¬Û:þóæùË ï¼eãÂÖÒë3HæM‘C fIYAÜ çj–?@2̪ۖ—0^ZÃug4SÛN‹$RÄá’DaÊGAWTñeB4eð&íúþgeLUya¡B_m¯^¿™äž+Ö®ÖMëHÕá!¼´»’{x¾Ê÷ÿÙWìr€âäûËžIÜ)Ÿð–xt«†Ô5« xžâÚ5¼²™eîŽVpóKoQd¤xÊHAm§Ôc¢¹N3ÍþëÚÆ½­ÝC¨jÐXÛ#lX£s}®þ ¹ØÝ·Œœmù—¢‚Tè mkXñºë$*ÃåXÄäàÃoöxæóÿ ó]ÎáÎb_îŒw—©hn¤÷O{ld7VâÖ|HÊ%ˆ1`ŒŒ–ëÙ˜tb j3_ø_Âwš­çÙ5 Ûhe’ ¢ý¢V·,Ña<|Ï…Áýß]¡ƒÅ6ƒ«Á¯C Ì“CýŸqdl–·ÿÈŒÑyÇ¥u@( )³Õo¼=«.‡ý£ö”zªG§ˆ×v£þ[Ý]ò7`<· p¾NZæõ¿]7ÁÔ‚ú²ZMà˜gŠ+kE {4–ò,±…EÂ*(Œá…“ò©ïTPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\¯Ä¿ù,ÿì5¤ÿéÆÞºªå~%ÿȹgÿa­'ÿN6ôÕQEQEQEQEQEQEQEQEQEQEW+àßùüwÿa¨ÿôÝg]Ur¾ ÿ‘ÇöÿMÖtÿøë@ð¾§aa¬^gº;‰+o K)þË »¹û¨ì½=|Ïñûºމâ‹ÿéͨZjóA• M/•1HàDd^y*¥X}âLdå“éž´ñ‚þ ivš‹îÖ-ŒqÊßë¾Ë — Áòaº¿(òð¹P+ªµ*Q¥ BW“Ývþ¿­,vW£BiΜï'{®Ý¿§ë³G¦Q^5âsQµ×íotB=jæ øbžX|¥Dk­1\—E*á·ª6ãi*s4ž'ךÖÎ ÝrÚÑæ¼¸Ž;›IP‚±ùòÛ„wÜîÇ,€À£g”ã=~Šñ‹MwTñ7„Ρ©ÞXõŸ¢ÛÇ,`ÊÚ\ìÙ·+ãæ# zü¸«ñUñç5aÕï?âcu­éBÖ!á-Öù£ÚvÞ~ʱž~ëœaðôî4W–ŸøŒxº [ý>]).,á†k‰ÿ}¨@ñ#I2ǹIi0Êñ¢”Éz»ÃZž½­Ùø.)5û¨%Ö´ u[‰â··,’(² 1frrÞ=>] ¡Ex®—ãÝcQ“A½mLC%ÊéF]8G#­Ð·ó++Jê ÌÑC ¸b¿6¿¹ÐþÙ\sd4½Áè÷Cn±ë…–WÕêzÆxnHìôßZßìý/N¾š;{°È¬FåvÁ@#y$p*F*×Ä–×H’íÊhÑß«jg$/‘åÉ·v?ƒÍòKvÚxÍu4Wœkš¥Ž‘á…—ÃŒš~Ÿu©ykA†0c,LrJ qÆY@ µ”³,ÎÒј…ó`'pýÀÎO˜XÝ(®ODÖu#ã=KA½_:;u’ín D2ü…À÷ûBzþç'“]eQEQEQEQEQEQErºoü•?ÿØLÿÑ÷õÕW+¦ÿÉSñýtÏý]UQEQEQEq^$Mÿ<8<›™¿âQ©|¶òùl?}cÎw/Ù­#þ¡úÏþÿöêÍñ@Ô¬üi¡êö%ö­mŸ{i*Ù˼o,–¬„‰¤ŒD/О޵/ü%¿ýž$ÿ¿úwÿ%R°|ú‡ë?øÿÛ¨ò?ê¬ÿàÿnª_ð”jÿô"x“þÿéßü•Gü%¿ýž$ÿ¿úwÿ%Q`.ùõÖð?ÿ·QäÔ?YÿÀÿþÝT¿á(ÕÿèDñ'ýÿÓ¿ù*øJ5úão›,²¼®ás´rNNp2}M_®SŒñÍfæâ²ÖnÖ?á&ÔWwXlïâ‰qè"Q ^åvÍiøÛľ"²ÔàƒAºÓ…öt70Þ_LSír³°*;y œÉDØß¼ãÛÑ­l-­nîîmãÙ5Û+ÎC;*… Œà  ’ÏAV¨€m_U>2}ïS6V¶wBîK­±)ž YÚÜîRùXò0çÉ;›5ÍkÙ¿fñÚü¯øXßk¹þËÝÿ_ëÙ<Ÿâòvy[öüŸwñW¬ÛiÖ¶×÷—°ÆEÕÞÏ:BÅ‹P2~P9à`e˜õ$›tåãS¹Ó¼eâ(ì.OÚn(žßÂöêt›[m¥"ÄÄÄ×ImJÑÁ¹¤«¢'—È 9ö«ˆRâÞXeÝåÈ¥k8#r>£šm•¬6pZYÄÛAÅh0¨Š0@ã~ ÕugÂzd×>&º±¾3é×z…½¬@ضÀ4Œ„"ǹ‰’ÞPo¸[Ö¼Aek¨è—Öšƒlµ’&ùÁ;ÁìT€Aì@5¡UuK mSOžÆþ?6ÖuÙ,{Ї^êpG¡È<ÆðÆ£5ÿ…ü'yªÞ}“P½¶†Y Ê/Ú%krÍÇÌø\ÝõÚÿaÿÂcÿר¿°¾ÁØ?´1öo´ù’yÙÝòù›|¹ù¾öÞõè ( ¶¹žÎïÃêƘ£LÖ ¹ÓÌ•-ÍÝ©·® ÉŒD aœü¼3YÐx·ÅB[¢°iºd·‰o¥¸uµX&mƒˆŒ‚ w6éeûË’# {•U±Óílé­"µÔÆâfÉ&I±'ÙT@@–¹«êmS\þƾf´†­l¼Ï´ `¤•Tßþ±äPXžV]HÈ­¯„`ø[áQ=Ô·S. ÈòíÞ®Œí”9NFï—æ%²O_EQEQEQEQEQEQEQEQEQEQEQEQEÊüKÿ‘rÏþÃZOþœm몮Wâ_ü‹–öÒôão@UQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@r¾ ÿ‘ÇöÿMÖuÕW+àßùüwÿa¨ÿôÝg@ñOŽ´ êvÅà†{£¸2¶ñò²ŸàŒ°Û¸ûŸºŽËÓ×Ìÿ¼+­èž(¿ñN™ Ú…¦¯4yPÄÒùSŽFEç’ªU‡Þ$Æ@>Y>—ákOø/à®™k¨ÉbØ¢Lù}– .FNÊ|˜_î¯Ê<¼.T ê­J”iBP•ä÷]¿¯ëK•èÐ…s§;ÉÞë·oéúìÑé´WŒ]xÓÄO{o¤ê6³i°ÞÜBºó‹E –¶ŽŠ[ȧsK3³å`0 >:ƒxÊÂMcR–æöÅpÐ2Ž ú ¤´jcG[z ã8„doÞ[”ã=¶Šð]sV×µ x.kÏÞůea¬\É6éöcÝ€fÆ@L\´»#1/D܇±Õ[y œÙ'iQÅni¾(Ô¥ø…Ÿö£Km6¥qc-‹¤+ä"E;£l æ)&C4„:Ê€”Óê­í…µóÚ½Ì{ÞÖa<,©GŒ‚£0#¡ƒkÎ>)¨¼OGzÛ`±ð”òÚäd™ng¹UŠ!žÂB?ˆææ¹â=v ôæ·7’ëYÝ›™D1ØÆ˜AãîÄ726L™à´»Ó4û].Ð[XÅåB¤#qbÌÌY˜’I$±$’rI«Uå£Ä(^ŠîÞKmÆ­“tpÎ'8•KÆ…óoæHr ƒ*0ÜÍ­IáùuË)¡:0`7ï2@¶íb1‘šÁñ>§w¬C¢ÇâíOÂGMM^YïÁ½´šÂð²Íº;t<„ڹܬÀ±û €}Ey¦Šîïá­ÃzÞ•o¦\éÚÏÚ¼;g vÌñ\[ªùHÆU\œ7''wC¼·ÃíoZ¿žÞyu»¨®|GªÚË4b8‘š'Ú31ð¾blî¸Éó {¥ÉèšÎ¤|g©h7«çGn²]­ÁH†C¸ÿhO_Üäòk¬ Š( Š( Š( WMÿ’§âûéŸú>þºªåtßù*~!ÿ°.™ÿ£ï몠Š( Š( Š( Šå|M¨kŸð•i6ƒu¦Ú}ªÊîòY¯lÞçýKÛ¢ªªË3ç’I'îŽ(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ðΡ®ÂU«èÚõÖ›wö[+KȦ²³{oõÏpŒ¬­,™Ç ¼x ªŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹]7þJŸˆì ¦èûúê«•Ó䩸‡þÀºgþ¿ -ý£ü-ªEx|o¦‰.m¬ìÞêÚ0ID¤“y_âSæX Ç´7(_nï ;Å>ø?¬ÝjV¯&­!¹Ôtý=Á 1)HŠi›o_Þ|ß9a]÷Œ¼c£øBÚÚ]fi\ɲ(aŒÉ+(#{„í@rÇèY•[j ­õ æµ'´¹Œh¼27˜!pèaLì`¥¶œ0f­†“ê·~8Ô/5½\ÜMs£Z´pC³¸[›¥ÝhcvÚ¢2[98*bÛèzn‘e¦Íq5¬oçÜmóe–W•Ü.v‚ÎIÀÉÀÎO©«õÊqž9¬ÜÜB¶ZÒ ÚÇü$ÚŠà®â« üQ.=J$ ܱîÙ­?x—ÄVZœh7Zp±þΆæËéŠ}®VvBÇo!“(›÷œ{z5­…µ­ÝÝͼ{&»eyÈc‡eP¡±œ´2@è*Õp «ê§ÆO¢ÝêfÊÖÎè]Éu¶%3Á+"Û[Ê@ß#KFù#sf¹­oû7ìÞ û_•ÿ íw?Ù{¿ãëýaû'“ü^NÏ+~ß“ïîþ*õ›m:ÖÚþòöȺ»ÙçHX±`ƒ OÊ< ³¤“n€<¼jw:wŒ¼E…ÉûMLj¬Óì>XaqÚY$¯»Zeø#yÈu¬x§ÅÛø^ÝN“kbm´¤X˜˜šâ)-¢iZ8#·#´€tDòùG>Õq \[Ë »¼¹£mb§`àŽGÔsM²µ‚ÆÎ K8’h#X¢Fè€#Ž,Æ6?ÏÔœ‘í¶‘ÞCåLÓ*ç9†g‰¿ï¤ ÓtË ].Æ;K„6ñçj‚O$’I'’I$’y$’h#ÃZ…Ýî»âÈnfߎ£µºmb›;yO då¥cÎj¹ÿEø™vÜG¥Ë5ÚŽ›á–%‰ˆõ+,£=Ä`®¢ªÃ§ÚèÜßÇ/.U#–RÄ’©ª2xs ±=I  ­fKÉ|­·‡¯¾Ý©ˆoÒ]ÈvÜ XþPÈãg<Ÿ1'$ñÞÿ„sþ_ÿ åyû¤þØòÖy>Cãí]üï7ÉÆÿŸïöÍz…áZ·yƒ|akqݘ´Ñ~ѶèâÊO¶Xƈ ^K£ÈÁŽH1‡R2¸ÐѼcãì$¹¿m69ÚžÞyå°f¹$fO!yq´¬QÉ1‚ zÞ¡§Úê ÞÄ%X&KˆÔ“"«ßg¸¨j€<ÇOš[ŸŠz%ÂøžêþÀYêVñ¨‚(â‘ÃZ·—¸'ïÛrþ¤²ïôê( Š( Š( Š( Š( Š( ¹_‰ò.YÿØkIÿÓ½uUÊüKÿ‘rÏþÃZOþœm誢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®WÁ¿ò1øïþÃQÿéºÎºªå|ÿ#Žÿì5þ›¬èþ)ñÖá}NÂÃX¼ÏtwVÞ>@–Sü–ws÷QÙz;˜æŠC Vêc‘£oÁ”‚?_5ü~ð®·¢x¢ÿÅ:d3jš¼ÐEåCKåLR8žJ©Vx“ùdú/‡­üAà‚Ú®¥s³X·ºµ†VÊÍåC-ò/—Œ`í†M›S·xS]U©R(J¼žë·õýic²½£Ntçy;Ývíý?]š=KÓ-4¸¥ŽÊ"‚Y Ò3;;ÈäY™‰$àÉèíW+ÌôŸ][øšÔõE—íöÈ-¯¤_H›C‚ª>^íLoòÉàWðæãR¼Õ|=y­ê×7Ú…æ¹kw"L°¨_3ÃÎÅÐF‹ò–.ƒ¨ý×6òܧï´W‚ëš¶½¨xcÁs^xŽö(õ{+ bæHá·O³îì0&2bå¤mÙ‰z&ä=Ž©â/§Ä4ø_M¶Óc¾µ‚(ç™Ä·0º#HëÀŰZ@HЦ?˜’@=&ŠñK/ø–_jËë³™¬¼'aâ!ÙàÙ$ÏËåõš+È|q­ÜÝx;Æj:Ÿ•8µÕà:GÙÌÅ(÷¹7*£ïbTïÚH«~'×üM¢ë÷ZMäW¨ZÊwº½)n¶±ÏöÀÃzDáSu´J¥‘È2ž„zN™§Úév‚ÚÆ/*Í!‹fbÌÄ’I%‰$“’MZ¯ï&²ÕüUö¯jßà¼m×dšõ€ºŽeWÀ4W·?t!f †%Hc=ëfï_–×Y¸µ†Ë^±Òb†(aaåÜ¥’³eÑŽå7,ëÛpùƒ/Ë@—Ey'‰õ{íNÒc×n”ZxcO˜;E :\Kö¸Ý_äÿ–f$O9ˆn$ïÝÛx]¼ñ5Õý¨¶’)¾ÎT®‘ ˜ÀfóSþ@-ËèèÞ8ñ5•¿F+[Ò£¢\JfYôÊÅêäõ&£ñKKqà}6úkøm^[ÈYZK›_234Šbh|Â6Éù@â€:Ê+Ïou-Nðæ·©x>èC6ê÷ˆ$¶Bκg÷`…où fiCñf©q+Zßë¾F›×u‚°¹b¶ö²Ä…‚,gwŸ+2"g;ˆ¨[iÖ¶×÷—°ÆEÕÞÏ:BÅ‹P2~P9à`e˜õ$›uäš~£¨YÜëz½®¥!Ä:]´ðý”G×Ú-ôèÙ#!eʨ`A6î•Ëkþ ×µÏHž+Ÿ@·³•´ù®­î®Ñÿ´mÆb‰R0 †G•‹á±¹¨èJ+Ê´ ³Ót ëû6¥­Ëmqsá‹a…@±šR o•|Üćq=6‚0>nLֵȼG¬ÞË®Ý5Óɧéq$‘@DMnâÎG #mK`à5Áè<°€ëEqéªêšoí4)ä’úÞò5ž)åTVHã‰Öbvï¹éÖrvQEÊé¿òTüCÿ`]3ÿGß×U\®›ÿ%OÄ?öÓ?ô}ýuTQEQEQEÊê_òTü=ÿ`]OÿGØWU\®¥ÿ%OÃßöÔÿô}…uTçÞ ñF½saáß¶™<%‚6ƒì6Ò@Ö²µ³\l`ò>õØŽ7 ¸ pwq[\ø¤-£Ž=7@Õ'¼’êÞ4ŠC—‰îb…Û`clʪ@¹× (r»Þð=¶€šb>©©ê‘ép-¾ž—ƶ¨gÊ#2Û>]͹°Hdæ”_ 4¨â¶Œ_êem#Úå¢Ì ³A2c÷1W¶—ÜXgqn0‹~#E¤Úk‘ZØÜGikvö²Ý„Ë40É.Ò‚O4&#'qUR:7#:ú‡-,…Ú>Ÿ©=Ý»E›`‘£2I¿Ë“s¸ECå¸Ë²ò»N ÒÔþéZˆ»Iï5oq%ÌÞH1®"š9H&2N|÷#ql…Ê›WÞ°¼‘î$½ÔE÷›‰v]$’1Ȩ€:2²4¿yXåÉÎp@oøXºsý„[iº­Ë\¤’2‘–ˆ$ð\Hdn!ó#†RjêË­x<-e ómžðÙM$ó=}žl™ \e,çi%rÄã8ÀÚ]ëv‰%Æ· ¤–«jgabŽÒG"òc ’dÈÎ’¸ÛȬÍ;âŸzÆcóKQZ )H˵£‘“îÃ) °*’¿„í¿³ï,¯oõ;ëk›W²Ûq?ú¨`ª• IÆ>vËð>j§mà;nÅã_êß§’cºc¼mœ¨XÂŒ­ÄªFÜzd’@)Üøõ¬µ-Mï4»åÒì´ë{Ù¿rkPÒܤÏ(gE)7Ü1Š(ø³¡Ø[x‚ÓJ¼µŸ[Óíoš^D`ÓÛDîÈÑ«ù€-¹!AÚpyߟÁZݵÍî¥1Ö4Á¥ÜË,ÁäòÁœîRW†ÍÌŸì€`š—ìo´ýRÁ¯µ(týA.–[hf µÊ°•ÀÛ’rîÀ6T3gÅOãoÁá[[+ËÂÿfy&óBD™#´žà€K¨SˆO'w¦íËŸ¬xÔÛ[Ý,6SZ^ÚÞiÉ,wʸ6×7Kœ69ÀÚ&Æâ)ó.8-Õüºæšö:ÿˆõ½J#æì2‹XÚ?2Ú{wÛåÀ¹Ê\1ç<ªöÈ:º¿„ì5]BêòæK÷"ÅdDeÚE¥ÃÜF0TðÌìÕx<ж—zºŽŸäqKs®ôY@ ´ô$q‘ƒŽ¼òÈ®Mÿ’§âûéŸú>þ·ô‹ÒôÛ{e–X ]ˆÒ[hè2è0>‚°4ßù*~!ÿ°.™ÿ£ï誢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®WMÿ’§âûéŸú>þºªåtßù*~!ÿ°.™ÿ£ïèËhÿ j‘^é¢K›k;·º¶ŒQ#i$ÞWø”ù„1í ÊÛ»ðƒNñO…~ë7Z•«É«Hnu?OpCF JR"ŸÀZEfÛ×÷Ÿ7ÎXW}ã/èþ¶¶—Yš@×2lŠc2JÊÞá;P±ú–eVÚ‚k}BÆ9­gIí.cÐI•taÊêzr>⺧ˆ«*£/7o×ó;*b«Ë ømzõüÏ#¾ñ–¸º¤öz©©h£O_]ªÚÅš/ æ\ºS;)m§ «Gá¤ú­ßŽ5 ÍoW7\èÖ­ãìîæéwFZݶ¨Œ–ÀÎN ˜¶ú›¤Yi³\Mkù÷|Ùe•åw  ³’p2p3“êjýrœgŽk77­–´ƒv±ÿ 6¢¸+¸ªÃgKA‰÷,{¶kOÆÞ%ñ–§ Öœ,³¡¹†òúbŸk•P±ÛÈdàFJ&ÆýçÞkamkwwsoÉ®Ù^ráÙT(lgíd z µ@jú©ñ“è·z™²µ³ºr]m‰LðJȶÖçr7ÈÒÇ‘‡>HÁÜÙ®k[þÍû7ˆ>×åÂÆû]Ïö^ïøúÿX~Éäÿ“³Êß·äûû¿Š½fÛNµ¶¿¼½†2.®öyÒ,X “òÏ,Ç©$Û /Îã/Gar~Óqâ+4û–\Dö–I+îÆG–™~ÆÞrkÀÞ)ñDöþ·S¤ÚØ›m)&&&¸ŠKhšVŽíÈÀ- ]<¾@Qϵ\B—òÃ.ï.E(ÛX©Á8#‘õÓl­`±³‚ÒÎ$†ÚÖ(£A…DQ€ z ñ«¨ë>Ó&¹ñ5ÕñŸN»Ô,ííbÀý¶á¤d!=ÌH|–òƒ}ÀêÞ‰ãfKÇu£^Eæ>©gbflwßE«Üdnu#¨ ô"ºj†ÒÚHš;tØ#ÊFIù‹±çÕ˜ŸÆ€<âó^ñ=·Ž–—6+aÝ¥²¹Hžò& ²£·;ŽLƒrº*”ù€^¼÷nµÛñÓÚê7š­å”wWÑE<0o»nõtGdIZÅÀ#…Ú¿%{uã⯮…}5þ¿¥ZD“Zwm8“Ë®dS<–© GåB7«c%X‚éU|®jMg¬kÖÚ¬ò+øšÂÖX䶉í'ŽÂï€y *Ѳ«Ý‚¬{mäŸ|7=ž…á½`išF•m&… lº|…žýÝaq<ãË@nîzß7­ 7Æ>0žÖÚ]BçMµ–áìR[x$3MjòßÁ #)?’I«;± 8«Ú¨ %°ñ úV‘e£­E¥X=î·º«Ánš+çHP€‚=î Žp ¹CݳTµ_jz•–ˆL–7²jZM-mÉ kId•›i*S$y$/É´òë^ÏEyN©ªOeâ BëHÔþÔóéþ·PÄryñͨ\DÒ| !Ü®OÊçŒqŒ›ÍG_³øƒ¨ºj·ºŒú5†©meo$p*ÞÌ-¬ncöF2äÌßwiÛã¼ßí”P’é¾)ñF§ªiÉ`÷vñÍg!¸6hÐÌìYÚÞ8Æ]!P ±O0–þÊ7ñu;û+‹á塹Ô7Û›‡[ûˆV1ÛÈψã‹1óõ'${Eí¤wùS4ʹÎa™âoûé4Ý2Â×K±ŽÒÂ! ¼yÚ “É$’Iä’I$žI$šÂÐ5™&ñ‰moï"ÁªGcc íRÐ`•z?<ŽH {(O­]ÂW{iuªÿg,7ÖðZZ}”KöØž4f~›¹f‘w)<½Í‘šë綆ymä•7=¼†XŽOÊÅY3ÿ|³Ʀ ƒÆºÜÓïo5 º…îi©éðI CûFòE;íP–>æÌääAñ\Öáþ±sq¨¼ÖÚ„šþÖa8b¿1¸`¡·³*òpA‰­x!D†{ ØEköpáæÄÒ†ÇÌWpaºäãÃÆ:µÆ±m±®ÿe$–7J‚ÍË(m|™vº–ýï™#`œ Þ_ß\×±UY4ûY5[}IâÍí¼2ÛÅ&ãòÇ#FÎ1œ˜£äŒ¼u9òßkÚåõͼW 4›ÝO]†Úñ`·ˆ×r÷Ër Ä!ùWûV)ýTÓôë]?í?dŒ¡¹®&bÅ‹ÈÝI$“Ð@@o¤«$70Þ\ÜjŒ«"+EªZHóczn¿ÖµùßÅäìóvnù>æßá¬íc[¼Ó<â(4ûˆç-/ˆšâÆ[t•"ˆ=ì‹9ܤ02*!S•;ö‘•j÷Z«ªiöº­„ÖZ„BkI†Ù"$€ã9ÁÇP{Ž„px4åÓø³Æ)¬jþLZkýµƒMó]®%XRCò„.ò±Í)R$ÀˆMJê[ïø>X<_swi­åZÅ’Îç îPƒ¹•P Ã/šrK4e}^Š+•ø—ÿ"åŸý†´Ÿý8Û×U\¯Ä¿ù,ÿì5¤ÿéÆÞ€:ª(¢€ (¢€ (¢€ (¢€2­|E£Ýë·º-¾£lú½–ß>Ïx eÓÉXŒŽjÝî¡kesaÌ»%¾˜ÛÛ®ÒwÈ#yàqòFç'Œu WŸÜüðî¡ñ6ûÆÚ³\Þ_Ìñ<o1ÅŽ$@~^Xü™äãœc½t¾,¶ž}{ÁrA ²Go«I$̈H …Ú†b: Ì«“Ý€î( ´¸K«Xn"¬s"È¢XÚ7ŒÈÀ2ŸP@#¡™¨ZêvÏ=Œ¾lI4ÖìÛJâH¤häÑцzdds^'à _[ø2ÎêçGº‹Z´ÔtÞÙ–h¡úlwr2ur;+û¼oèÚEìSjGQ°ÔÞÖíµˆíº”–ÑÚòá‹!8¦G$8hà €z½À|)³†ÄêØéMeb!':tšwžø}àÛ¾åã2(÷“²»ú(¢Š(¢Š(¢Š+•ðoüŒ~;ÿ°Ôún³®ª¹_ÿÈÇã¿û Gÿ¦ë:Š|u x_S°°Ö/3ÝÄ•·%”ÿe†ÝÇÜýÔv]ÝKOµÔí’ è¼Ø’h®wÄ‘H²Fx=ã¡ÆE|ãñûºމâ‹ÿéͨZjóA• M/•1HàDd^y*¥X}âLdå“èþµñƒ> ø~ÇQ¹òõ˜ïlí]²²ùQOºmùb”&åp§ê­J”iBP•ä÷]¿¯ëK•èÐ…s§;ÉÞë·oéúìÑê4W™^kÞ'¶ñÀÒÒæÅl »´¶Cw)ÞDÑ¡–AvçqÉnWERŸ0 ×'CñwˆeÓ´{»LÌe²ðõä¨ÐF†þso*p£Þ1Îãýß–¹N3Øè¯4ƒÄš¦¡â/ì›}U"Ôå½¾µžÁbžÂÝ_³ÝF~bŸ›*ÞvùjŒ¾,ñUÎ¥h–Ð$×ÐéÒ-Ä‚­Œq9¸ËåÉôää«/ÈKP¬Ñ^-§ëšÊÞ_êÝÛj\[h6¦âÙKÆÑË«]øo7f6êA$•À Ó/5~Ïâ¢éªÞê3èÖ¥µ•¼‘À«{0¶±¹Ž7ÙË“3}ݧl Œ~óx±Mam6¡m}$y»¶WH¤ A øÜ§v©ÁÈÊƒÔ µ^G£øÄ×Úž—cu«X¬W·éngÓä.€Ù]ÊÀ»ÛF€îŠ& µ™yÝÁÍuâmrÎÎ WûFy’ãTÕôáh¶‘Ê-ÅóÄèªÞAöT\oÇ_š€=ZªgZÿjÿiɽò>Î$,NØ÷n àdã$ «œíã>ë·º¦£ªÚÝj£U·†ÚÚâ+ðÉÌ:²‡‰J(c‚AÈ,NBòz}ä¶gÁZ¯œ`½Ô4‹»Fãhf‰æ¹ÓÌìrʰP\PµQ^mªx‹Ä©ñM>Óm´Øï­`Š9æq-Ì.ˆÒ:İ1l"©æd›^Õõ[ß­Ž­©›uÒì¥M±/ö•ÉóAÊäG6Øöÿ¬çåR(¿¢¼oDþÍû6öO+þ7Úí¿µvÿÇ×úÁö¿;ø¼žnÍß'ÜÛü5¬kwšg‚üEŸqå¥ñ\XËn’¤Q½‘g;”†ED*r§~Ò2­@ëEy$þ,ñŠk¿“šÿgmE`Ó|×k‰VÀ|¡˼¬gsJT‰0â“Rº–ûÄþ–ÜÝÚA«GçyV±F¤³¹Â»” îeT0Ëæœ’ÍPWªšVk¥XEeaŽÞ,íRÅÉ$’If$±$’I$’I5…ñ;÷^Õobâ÷OˆÞÙ·qqÝï0 GpÄt5½$‘VÞ3}²V†V[=ÉûÕ dÁ¾L¨È ~÷I\:}­Œ—rZŲK¹Œó¹bÍ#$’zP@Uªó½Ti_ð’x‚/HÂêi!:J©o;ÉGÿàsæ ¼Òv󂻸ÅTñ'Š5+?µ­¶¨ÑÇ õ·Ø!U’)žy6•28ýé@衆Ü1_˜Óè¯Ôu›Í[Ã:Y¾Õ·jW:T×ZoÙ@û çR¶ÞÆÂJí|—Û‘€ ;Xñ?ŠtýNûI¶¾¶’ÞÊòxTÔ%KSkk£`þF¡§¾w66gýä–9$ 1’'åEˆ¯ˆ/< ¨Ë¯yÿ­oJ°Á n·ÍÓ°¶óöUŒó÷\㇠q¢¼òÆÿ[½²ñdºN³-üš\±E` p»ÎÒ|³*L…Üep”8]½g„µs¯hú§—²+¦‘àÿn1„Oÿ@øÐÏìë_í_í#7¾GÙÄ…‰ÛíÄœ œd“µs£袀 *¶§+Á¦ÝËÛ"Dì§Á‘X÷—Í]$7š§ŸHA’Ȭd¨'㎹çµb]kš^…ñ/ÄëöÖQ6¦*¤ \ù÷ü(êÇØdÕïøIu}[åðχî '¥ö¬Mœ8õXÈ2·âŠ÷«#QðƯüXÕ§¼^ÙèÚÙnígxfƒt÷Û¶²‘ÁÚ¹ àdV¿Ù¼_£Ç­ÝŸˆ­ü³¼ÖèiÜûOv xRã]ƚ曯jp_,Z}Ük¨‚8ZI.•‚Œ³ˆSï1éÚ»ó=?FÓ¼eãíjûÄþ Ó,mâ]fÆ)vÈ%»ioó# 4y*Ƕk¼¶Ñ4«]éºeŒ:K#Æl£·E€£çzù`mÁÜr1ÎO­hQ\þ—௠éñ_i^Ñ,obÏ—qmaR&A ªÈ$} ©µ¿ øs^ºK­s@Ò5+”AËyeΨ !Ae'$ãÜÐÕŸm¢iVº1Ò-tËt–GŒÙGn‹GÎõòÀÛƒ¸äcœŸZÏÒüá]"þ+í+ÃZ%ìYòî-¬"ŠDÈ á•A¡4çúO޼1ñâf’ž¸¶Ö~ä_›„¸†XV=óYí?<|Ÿ•ºþ¿¡ÿeÿÔ Fÿ¾ÿûUy—ƒ¾ ²ñRk>ÿ‰ŸŸe5Ü:Ö¡äíÜñ:4m»gî8 Žã­zÛ¼qÿB÷†ÿð}?ÿ!Ò°²ÿê£ßýªì¿úhß÷ßÿjª_nñÇý ÞÿÁôÿü‡GÛ¼qÿB÷†ÿð}?ÿ!Ñ`.ÿeÿÔ Fÿ¾ÿûUÙõÑ¿ï¿þÕT¾Ýãú¼7ÿƒéÿù·xãþ…ï ÿàúþC¢À]þËÿ¨ÿ}ÿöª?²ÿê£ßýª©}»Çô/xoÿÓÿònñÇý ÞÿÁôÿü‡E€»ý—ÿP-þûÿíTeÿÔ Fÿ¾ÿûURûwŽ?è^ðßþ§ÿä:>Ýãú¼7ÿƒéÿù‹wû/þ Z7ý÷ÿÚ¨þËÿ¨ÿ}ÿöª¥öïнá¿üOÿÈt}»Çô/xoÿÓÿòïö_ý@´oûïÿµQý—ÿP-þûÿíUKíÞ8ÿ¡{Ãø>ŸÿèûwŽ?è^ðßþ§ÿä:,ßì¿úhß÷ßÿj¬ Áö‰ž#O²[ZçHÓNËs•?¾¾çî¯?‡j·öïнá¿üOÿÈtxgO×?á*Õõz×M´ûU•¥œPÙ^=Ïú—¸vffŠÖMVßRx³{o ¶ñI¸ü±ÈѳŒg&(ù##oN@<¡|e®¶­¦»Ö²»gÓ#¹Ò]"Eh0 NÖS+€Ó0E »pÅ~iüKâ+Ö6«u©Å Ùñ-½¡Òd±I‡Ù×P‰L•% M² À.á¶‘ëTPèúž±á MwýÖ¬Ñkz­¤ö÷Kq$—‹lìE#t‚.:¤’>P{IáRø‹sm¨Æ’ÚÚé1½¼RUÚi%IŽ…Ž5öüG=¡§ZêfûdfQm:ÜF»ˆEÎÒ@8l@  ÛÝ.Òöæ+™ã´E‘$±ÈѲ£€r¤)ö*ä@ïƒ.IðU§Úõ¶Ž é,á¹gLËw*YÁÈ«çïüÄÆø¡©\húÃjv/²îËÂzåÌ-€vº5“)Á@ê z …¾Ÿcoge AkoÅh0T`øTôä~ —V⇴ë¿^›[Û[ÂÞT3q žS/în·D^w~ý†Kle«¤xÇÆéò\ß¾›µ´R\A ¼òع$fO!yq´¬QÉ1‚2öjŽæ¹âȺ˜ähÛðe ÀÐŽ]xÓÄO{o¤ê6³i°ÞÜBºó‹E –¶ŽŠ[ȧsK3³å`0qáM[T¾ñ¶º”ÑmBÓ®Þ(¢*ž|Ïr$eÞ¡ÀýÒ€;€s]—¦ZiqK”E²¤fvw‘ȳ3IÀ“ÐÚ®PEPEPEPEPEPEPEPEPEPEPEPEPEP\/ÆÍV áìú½âJöÚ~¡§]ʱ]’;è…œŒ‘]Õr¿ÿä\³ÿ°Ö“ÿ§z©¤üJÑ5=*Îþ /®¡IÐÂ?|øVPÃæH™[¯UbbG5oþÍ#þ|üIÿ„æ£ÿÆ+WÄúí§†ôK­SP´ñ¼…bMÌÁQœÐ•IÉ rEjÐ+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÏüñ]í|[â*+˜l¯5¡å¥ÊªÈ6YZ¡ÈRGU=úb»ý?R±Ô‘ßN½¶»DÆæ‚U.@aœàƒô Ö-÷‚t{ÍNóPgÕ๼u’±ë–©#ª,aŠE*®v¢ ãøEt´W+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£ÔøýuTW+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£ÔøýuTW+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£ÔøýuTW+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£ÔøýuTW+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£ÔøýuUWO°¶ÓÒd³ÊIfyÙC7¹Ë ã'$’ORkŸÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:ª©§éÖºÚ~ÉCs;\LÅ‹‘º’I' €°?áÒ?çóÄŸøQê?ü~ø@ôùüñ'þzÿ ªªêš}®«a5–¡šÒa¶H‰ 8ÎpqÔã¡ sÿðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐA¨éöº”pÇ{›S$ê…ˆ]èw) p@ Œ€zV«•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:ª+•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:ª+•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:ª+•ÿ„HÿŸÏáG¨ÿñúâµ_L>.h[x£Äèé—WoöÅëy²Bñ >iŸrçí(p8ýÎ9ÜpëW–ñÝÚOm6ÿ*dhßc²6ÁÃ)O=Av¢ÒÚ;Xm­bH­áEŽ8ÐaQ@Àz+šÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:ª+•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:k¨VâÚX’!BG\Ч>$ðɺ…ÛG"•a¶!FðV/ü zGüþx“ÿ =GÿÑÿ‘ÿ?ž$ÿÂQÿãôi¿òTüCÿ`]3ÿGß×UXº†4ÝêîêÃíÏst‘Ç,·—óÝ»$eÊ(3;‘Î>ñ­ª(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+•Ó䩸‡þÀºgþ¿®ª¹]7þJŸˆì ¦èûúòßÚ?ÂÚ¤W‡Æúh’æÚÎÁmî­£”HÚI7•þ%>a€Ì{Cr…öîü Ó¼Sá_ƒúÍÖ¥jòjÒGOÓÜу”ˆ§ð‘Y¶õýçÍó–ßxËÆ:?„-­¥Öf5Ì›"†Ì’²‚7¸AÎÔ,~€e™U¶ šßP±ŽkYÒ{K˜ÃÇ4e]d2ºž„‚¸®©â*Ê„hËàMÛõüÎʘªòÃB„¾Û^½3Èï¼e®.©=ž…ªEªZ(ÓÄ—×j¶±Cæ‹Ã#y‚n†ÎÆ [iÃjå¼C5õõ®¯uâ}nÉã»¶Ñ Žæ5“O1®®èÒñÄÒ"¨Fs•Vó›øL{}÷MÒ,´Ù®&µüû¾l²Êò»…ÎÐYÉ88ÀÉõ5~¹N3Ëô««]ÀO'„õ/ L%Ö¬­Œþ±Ž e3\ÛÄáI /±ù9x¹ëæ•â~é¼A{#è:N¯ £Iº¬ò-¥Ò þùÎ>[uãfÿx¢€8K›ízËÆº¾’á/¥Žö;—Š0b·q¸ŒP ä@€X ޹\Ö7‹·\^xŠêußwg­è––ˆN?sö‹9F=7Êî¤ÿ°3÷EzOöu¯ö¯ö‘Œ›ß#ìâBÄívâÎN2@ÉÚ¹ÎÑ…[ eÔßPXöÞ<"1Tœl27u4ç> ñ>½á¹4»»1í­Äחד dŽTÙˆÊËIò•Éò±»=]y¯kë5•…þ§œ5 855£D[(cˆ›²¢dáC°e\´rÜNªŸÙÖ¿Ú¿ÚF2o|³‰ ¶=Ûˆ88É'jç;F<ëÄ?ðŽÿÂK¯ÿÂuäý£tØÞwúÏ'ÈLý—¿æùÙÙóýÎÛk*}OYÑî.îî®L^&Ò˜Áå«ý²ñZ𘜰ãç á½–ŠññOŠ-šò (é6–ÑÜß¼RÜžQ©ÝG°$vòHT!v;3–$‘{Çzž§ªx?Å–¿ÛwZ™‹T…4»{Ewh¢I<¢ieóQ·ž—jáö°õm3OµÒì’ÒÂ! º` “’ÌY‰'’KI<’I«TNÎ8.´h"’àjvÒÛª´òar¥~ómáÉÀžÎx2äŸZ}¯QkhྒΖṯÇxÑB¥œLб®~ñßÁ A®²x–xd‰Ë„u*J9FÁáqÍGago§ØÛÙÙBZÛÆ±E U~ËxÕ­¢×ô9ué"O,ws9Ä?i>_“æg»|ð7q¸¯|V&¿ª 3Oðõ–ƒª^i–7^yŠIœ+®ÈÃÎ×yÛBÌ£å#o>—Ey—…ãE|û¯Ý®¯¯èMãMSÁ Qj‘Áq¬B/­±Â†ql­(%ÆäÚäî#¬Öõ­GNÒõ·ÐõkXìt ÚjÖɧÛD-n[Gj‚¬,° [ ckIõj(ɾÏ©Á¬Úh®ÞÎw®ÜÜùÑÀdÌ:„"48Œm “³©_Ýjšnª»æÒ™m¥¹ÀS4»¤9 ` Åöy0?{ŽÕÖUM?NµÓþÓöHÊ™Úâf,X¼Ô’I=t0nŠ( Š( Š( Š( Š( Š( Š( Š( Š( ¹_‰ò.YÿØkIÿÓ½uUÊüKÿ‘rÏþÃZOþœmèWÅšGü$Öto?ìÿÚ6SYùÛ7ù~bÝ·#8Îq‘ŸZÕ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šå<áá#¢çËÑì4£ˆ|½ÆÛÎÌ¿xòþoNÛzœñÕÑEQEQEQEQEQEQEQEQEQEQEQEQEÊê_òTü=ÿ`]OÿGØWU\®¥ÿ%OÃßöÔÿô}…[ð¦±yªÝkÐêñ[˧ß-ªÇ-…kh&ù›øŽf# Æ9ÆNýU²Óíl®oç¶‹d·Ó ‹†ÜNùi<ž>HÐ``qž¤šµ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@rºoü•?ÿØLÿÑ÷õÕW+¦ÿÉSñýtÏý@[ûGø[TŠðøßM\ÛYØ-½Õ´`’‰I&ò¿Ä§Ì °hnP¾Ý?†Ö^(ð‡À¯Þê¬öÚ£Ey©ØÀàµSeRŒ ÆLŠï´çïüÿ1a^‘ã/èþ¶¶—Yš@×2lŠc2JÊÞá;P±ú–eVÒ»ƒNñ5¼¦+Ý'R¶hØÅ&RxdL®§¡Vàƒß ×TñeB4eð&íúþgeLUya¡B_m¯^¿™ÀOâëË/Ú™5d“ÃqÞ·š„Ñ$QžÞït Ä ¡eK^N’Ns_áíþ¥ñ ÄWÚŽ­u:OlVÖÖD‰#ò£Ôo£]  l¢,YÉÎf;óòmõj+”ãñOŠ'·ð½º&ÖÄÛiH±115ÄR[DÒ´pGnFi*è‰åòŽ}ªâ¸·–wyr)FÚÅNÁÁ¨æ›ekœ–q$6ÐF±E *"ŒÐx߈5]GYðž™5ω®¬oŒúuÞ¡gok6í° #!±îbCä·”îVõ~êæãÃw÷¸ŽkØ7˜¼²®$’';á$äJ4gº’z[5 ¥´6‘4vé±G”Œ“ó;cÏ«1?yuÿŠ5K«=.î=fm>×Y¸¸žÉ–80)aA$ˆà³‚d ±·Ùƒ—ðóÅ÷ â)/µ‹¸­¬5açÏò’^6¤´H§“¸«\m@Nì¸ítPŒxWÅþ0¿›@“験G¦oó¥+-âËoÍ"E »æi@e‘J|À(ÉÛÖ¤ðüºå”ž3¾²Ô<:úT ¦Þj [\NYüÙ Ddeò à­°šôÊ(Ç­®g³»ðÄú†£q¦(Ó5…‚îtó%Kswjmë‚rcXg?/ ÀÖt-ñP–è¬n™-Äâ[énmV †›`â# ‚]ͺY~òäˆÂ†^åUltû[ºkH„mu1¸™²I’B,IöUÐPe®jú„†ÛT×?±¯™­!‚+[/3íX#i%E•7ÿ¬y'•—R2+ká˜>øTOu-Ô˧B²<»w«„£;@åS‘»åù‰l“×Ñ@g†äŽÏMñu¡½þÏÒôë飷» €ZÄ`ŽW`\7’@7  `b¶<_g5ƙՒ3ßéÓ-íº¯ÞvPC ÷xÚDÿÖŽ™§Úév‚ÚÆ/*Í!‹fbÌÄ’I%‰$“’MZ ,Ô5ÑoªE®O«Ç£iZÔ3µ)#_•!-¢Æ?yæ\L2FsUôOêïaws¨ô‡¹Ö-#Ô§ŽÝY+é6ò±l©ù¥cÜá°Šõº(øM:Üø9§]ø—TÔß2FѱÍüç%¤õÚFGJì(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ å~%ÿȹgÿa­'ÿN6õÕW+ñ/þEË?û i?úq· ªŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹]KþJŸ‡¿ì ©ÿèû ê«•Ô¿ä©ø{þÀºŸþ° ªŠò¯üQÖþ€<·öð¶©áñ¾š$¹¶³°[{«hÁ%6’Må‰O˜A`3ÐÜ¡}½ÁM+Ä^øU©K¯1µ½¸–{ûXd‰ÜÚÆÑ©¡_˜eùŒe¾~~r½fŠè–*¤èƃøSº:ç«<ÖMVßRx³{o ¶ñI¸ü±ÈѳŒg&(ù##oN@<¡|e®¶­¦»Ö²»gÓ#¹Ò]"Eh0 NÖS+€Ó0E »pÅ~gC®ê¶«àXnu¯/QÔ%”ÞY-„M&›)²º?»‘ˆÙÂ\)þê}~Šñ¿ jzî›à/YÙj\É«iPXG,©=¥à+¿¢Œ”ŒÍò°?ñìe‹Õx–êò/ëW6¶ßk»Ò4µévÇ‘-Ä0|çB¹ê„Ï_s§ZÜßÙÞÏ{‹MþC8Bã vçÇ# ŽVk iµ ké#ÍݲºE bWÆå8<ƒµNFT Pk~%š×K&ÓÅ­2I=¼r^ XbÛ£‘ˆ3:˜1Eá‘™I y‘JãZøÛ^{MP¶¦M奖ë"2o®Rîö‚ ¬€§9`íV=>Ö=VãRH±{q VòɸüÑÆÒ2 gY9'w=<£Sñž»k¯_f^5üËq}nšK¤K´Åoq$Cb¯˜¥šÃ4„:¶å@Ë›ã­BëSþÚ°Ó|Bú“ês¬XF³G 6§ËYvÇ̹œùe}Ίà[UÕãñ6™£ZjM{k¨-½äì‘Öñ©ûGÜP§syÇÉÛ€£ú¦©=—ˆ5 ­#SûSϧøjÞ=CÉçÇ6¡qIò€‡r¹?(ž1Æ=/û:×ûWûHÆMï‘öq!bvÇ»qg' dí\çhźñ;ÍG_³øƒ¨ºj·ºŒú5†©meo$p*ÞÌ-¬ncöF2äÌßwiÛã¼ß¥¦ø§ÄMž©§%ƒÝÛÇ5ýœ†àÙ£C3±gkxãt…@*Å<Â[økÖª ÛHï!ò¦i•sœÃ3Äß÷ÒhÅÇü]so¾ÊâÂ8@¹hnu öæáÖþâŒD¶ò3â8âÌccüýIÉŸá­Bî÷]ñd73o‚ÇQŽÚÝ6±M¼§2rÒ±ç5¯¦XZév1ÚXD!·;Ty$’I<’I$“É$“Vh—?è¿"ŽÛˆïô¹f»QÓ|2ı1¥e”g¸Œáª-­5möÎk¡©YÜ›‹y˜² º¼Y@ÉÌÞ~b[$Ù‡Oµ‡Q¹¿Ž,^\ªG,¥‰%S;Tdðæ8bz“V¨ËumGS:lW¹7>xູ’<3ȱ=Ö:|–Í$Øäbaèj¤>)Ôî5»»)àÖÒ×KÖKºX£&ûË ]@ù|É$Œì¶ÀH$=vŠóß_ÅãϼZŒšžÍ+MSvðyAÏ›xH(HÈÎ>é;”סQEQEQEQEQEQEQEQEQEb]Þ®®D×:‚"˱ÖÐÌ„çllG-ßúV&y|6›å–U]{GeM´ÞÚ6ÀÁËÍu¯bÞ|ÒEyqšÁ™P!Úu' ÌøþÛìÞ„™d•å×4—f“nsöûUì袀;*(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ åu/ù*~ÿ°.§ÿ£ì+ª®WRÿ’§áïûêú>€: }:ÎÚþòöÞÚ(îï6}¢U\4»qïÀ®Oâ†õ¿[jV¶Ñ-Þœö‹ “`!m8i8l‘]µçZ†¡ø·Sñ$n$ºžo*Ý!š_ÜÉme±=ž@<o¼qVÇÀº—ü!°éà‰¯ü3g Þ‰œî·$Š]6‚±;ŒUy¯O¢€8­C—×ÛÛ%¶oñªÅ–n"·ûõn>ñû4˜#•É8O xRÿH}ªKV]DŸIÆìLŒZ×c¨*8+năаwZí¨ /ð¿ÃýWJðZéصÈÔ4{­ÈîSe¤v ÉPrM¤›xç+œdã¶Ð4©ôí[Ä·S¼M§¨%Ü! %PZÛÂCdpwBÇŒðG¸TPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\þ³á+WÕ[R¹:”7­ [´–Z¥Õ¦øÑ”0†E ƒ#à‘Ÿ˜×AEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEyϼ5§hž¼»²ºñê ¶ 4oj=ÄŒ GŸÈÞËŸlÕOxJÞ{í;[Õ|Iu«éWOkq?ü$ñ™—‡ŠM«0tn™ÀÆwÕÑêßñ9øƒ¥iÃæµÑá:Àìf}Ñ@§ðóÛê¨}(ÔâMñN¾-®·ÓçôÄHOâ¦uϲJ“þ=#þðuÔÖ·ž,ðü0;G,RêP«ÆêpUl‚ ƒ]-r¿ ?ä\¼ÿ°Ö­ÿ§Š?ácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*¸Mc⿃£øÍá»UÖ¬e¶þɽõ®¡kHžY!uW“~âÕÆ=^>»Ž=–¹_‹òK+±½Ó|-}W"/lû e]ɺÚKæsÇÉ3ɹ¥ºñ~‰¿›m¨[_‘=¤ œÉ+'ÚeH¢f¸RdSŸL‘ž”Sþ_þ„Oßý;ÿ’¨ÿ„£Wÿ¡ÄŸ÷ÿNÿäªÓ¶ñ•1d’úÒ „ÒCåIsrRI8V=L2:¬ ¬?xÓEд¦Ôï.ám8XÍ~.#ž"®‘˜ÆËT.ÐFH‚ÊøJ5úmfÖæ=BÏzŲ‘%ó¤g¬hAÁbä.3ÔÓ ñV—<ÚRÇ)òu>]N‚TD!ŒÂ bOùèGn$q _ð”jÿô"x“þÿéßü•Gü%¿ýž$ÿ¿úwÿ%VÇöþöf¹þÖÓþήËö”Ú¨p3œgk+cЃޫë(Ñ´˜f’ïQ²O!N­wffK¾öPFǜᗖP@3ÿá(ÕÿèDñ'ýÿÓ¿ù*øJ5úÃk·›³fýŠìdã8é“ZµÍ|5¹žóÀ: ÅÜÒÏq%¢3Ë+–g8êIäšéh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+•øiÿ"åçý†µoý8ÜWU\¯ÃOù/?ì5«éÆâ€:ª(¢€ (¢€ (¢€ (¢€ ÅñˆôýNÔ§šöÈ\YZÉrÐK>Ó„Ÿæ ¬àaIÈV8€zVÕpZÏÃÏ·IâCmªy)­Ù\ÙÈ%·óZ/=0Y[p<0SŽê“…`î¥ãN»¸¶º¸¸ó­åJ"³šP²WTÊ!˜:…Ë1Ú¹n*–…ãíRðΕ¬\<¶K}gëE,2fn79Ûò¦r‡ ÀnŽi÷žûOöÇúnßí fËWÿUŸ/ìÿeýßÞçwÙ~÷ßÐãžxü&Ó¤³Òâ»m6ök2 %f½Òâ¹+ ,Þ[F$,M®A<«¼7åkfªïçåÜ+GJð ö›áë1nàΩ¤ÝÇ<ŒÛžD±WÝÇ~Ë!‘ó.HÉÇUçÿÔCYÿÀþÓGŸÿQ gÿ?ûM¾½ÒÿáKç´’=DŸJ“c3yŽM°IòBø†Mcx7áæ§£ÛhQê3XLÖWÖ÷3”fmñÇ£­™Q•>rïàmç¯ÚyÿõÖðÿ´ÑçÿÔCYÿÀþÓEÀæ5].ãCøUá]&õã’êÂëAµ•ã$«:^Z«$FAÆ@¯D¯?ñì»´{öÍNOøi_$Ö›ÿÄÂß«ycz0 (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ÏÐ5X5Í×R´IR …Þ‹(€Î9Á#·­hVW…tìÙi~Ú>Ì›<Ý›7rNq“޾´«EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\¯ÃOù/?ì5«éÆâºªå~ȹyÿa­[ÿN7ÕQEQEQEQEp>5ñf£§øš-#J”@#´W`Þj¼»•vÛ²ìÿW!Ëp1ÐÐ}Esz7‰áº–ÎÂmòê.÷1LcˆF‹öwò䔩vÚ…¶í˜ü람Ýǰjº"jVÖí¬‹4‰q ºGÊ"ÆKHB¶Ð»›ø%IÚ;j+Ït/ˆR_6‹oy¥ÞE«Ýé)¨M¦G<ƒq 2¿›µWä~gç%[*vWÇ:Ld`3Aw”ë: ؉vìÉÏÌê$n $u4W#q⩇Ž,ô›x#m5¦k)®;¾Õä<áœ|±¦O%Ç#iŽñ ®õT–Öyá·Õ³c’ÕåÖ%G,Ã.dÞÜ Ûœ7w”W;¦x¿MÔn8–â8¦µ–öÞâD;ˆceWtç8ÐòC2+™Õ>$Μš.‡¨Ýùßbo³¼p£ÉÌ€$ŠÍ0 “ ¤d¶ÒJ ,@="Šâm|yrk©ÄñÛY‹Ë›y"N%‚Õ–9y-ˉ ÇÊHlhÙxÆÊçW‹NkKëyäºk<ÌŠfù᜘²þÝk`PKEPEPEP\¯Åù%ž2ÿ°-ïþˆzê«•ø±ÿ$³Æ_ö½ÿÑ@Å„µoêP¾Ó­¼g21e½žR·ñöV1ß ö©>"xÏF¿øqâûg“OÔßF¼ c¨Äm¦cä?Ü €ÿT,=ëÓj¦©¦XêÖOiªÙ[^Ú¿Þ†â%‘ê"€2´½Q²¿ŠâçÅšÞ¡guµÌVkäɎ݌熜ŒŠ›[ѯµ¤–Ïĺ¾• C œv¬ŒrNâe…Û<ÁÇŽ¹Ú¢€3í¬.aÑ”šµô÷%>ß"B'³†ÂÆ#ÊäcäÇ óœý/AÔl¯â¸¹ñf·¨D™ÝmsšÆùrc·Fã9ᇠg#"º ([ѯµ¤–Ïĺ¾• C œv¬ŒrNâe…Û<ÁÇ޹µmasŒl¤Õ¯§¹(éöù8-œ61W#&8œèQ@þ— ê6Wñ\\ø³[Ô"Lî¶¹ŠÍc|‚91Û£qœðÃ3‘‘Skz5ö£t’Ùø—WÒ£Ta³ŽÕ‘ŽIÜL°»g88àq×;TP}µ…Ì:1²“V¾žä£§ÛäHDà¶pØXÄy\Œ|˜àdsŸ¥è:•üW>,Öõ“;­®b³Xß ŽLvèÜg<0ä ädWAEbëz5ö£t’Ùø—WÒ£Ta³ŽÕ‘ŽIÜL°»g88àq×6­¬.aÑ”šµô÷%>ß"B'³†ÂÆ#ÊäcäÇ ó (æ á_ˆ<ñ¶ÛÇ:½Ïö®‘>§xÌÖ6ó]]…šÊÉ,PÂÉ* Àféî¿ðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]Uç^-ñ%®½aa§é– {—Õ´Ù?{¡^Š‘ÞÁ#³;Ä@UbI#¥z-PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\×Ã{™îü§Ow4³Ìþfé%rÌq#’yè+¥¬ýUƒ[Ò㿵IRÐ ”vCОêhBŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹_†Ÿò.^ØkVÿÓÅuUçþ°ó´{ù?²tËŒëZ¯ï&|;ÄÂã¯îÏÓ­z…ý—ÿP-þûÿíTeÿÔ Fÿ¾ÿûU+»EaeÿÔ Fÿ¾ÿûUÙõÑ¿ï¿þÕEÀÝ¢°¿²ÿê£ßýªì¿úhß÷ßÿj¢àn×5'…¥ÿ„’ïX´ñ¯f×f?:Ö$¶h˜"í/ 8Nu'¦jÇö_ý@´oûïÿµQý—ÿP-þûÿíT\ X«ëòE-Ìsë(c–TeÝ •+ˆøã’ÏÎ~f=°K_é–ºF¡¥[\_Ŧ^[Ü[ý•'Äp¬ä´…x³ g `*÷ö_ý@´oûïÿµQý—ÿP-þûÿíT\ ë¿Y\êÒjcPÔáÔ$È’âY )´?s ¬cWùpÁ‰*W¥Y‹Áz\7QËŸGqo:B¬¾Zˆ"ò⌠gbýð3ÜçUì¿úhß÷ßÿj£û/þ Z7ý÷ÿÚ¨¸Ö_<=g}a¨Aeë·åµ1bêåØ86@¹`ÛÛ `tÆÅcxkÀzV­{ˆ¿²á½7ÌVf¼FcäM +°± Uš0ÁS8Wö_ý@´oûïÿµQý—ÿP-þûÿíT\ û/éÖšUÍ‚]ß¼rX>—nîèZÎÙ†<¸¾\0¼°bv®IÀ«_ðˆiëªE·I(éÛ>ø¹ÿ±´˜öégz?Ì¿¹~GîÇ?ˆ¢àuzïŠ4m Ò-Nþ(îdŽÕ–y܉vü®WÅž/ñ5¿…µcDðòYÛXYMv'ÖdØÒжËsãd#Ò£x+RðoœÞ¹±»†V-%¾©Y¤?õõî?YCïY¿<\Ὴìµý#QÑîæÒnâ¤Î·‘Ú,ÑåFIØO¥0=NŠçô¿ iÚeüW–×:ÛËv­Î·yqÈ#˜ä••º÷rM­øjÇYºK‹ÉõxäTg«]Z&'”ŠERy<‘žƒ< Ú¢³í´‹kméqÉ|mŠ<{佚IðÙÏï™Ì™äàîÈã`V~—á-;L¿ŠòÚç[ycÎÕ¹Öï.#9s’²·^àààŽ@ ‚ŠÅÖü5c¬Ý%Åäú¼r*À³Õ®­“ÊE"©<žHÏAžZ¶Ò-­´c¥Ç%ñ¶(ñï’öi'Ãg?¾g2g“ƒ»#Œ@W?¥øKNÓ/â¼¶¹ÖÞXóµnu»ËˆÎAÇ$¬­×¸88#*moÃV:ÍÒ\^O«Ç" Œ =ZêÑ0 <¤R*“ÉäŒôàPÕŸm¤[[hÇKŽKãlQãß%ìÒO†Î|ÎdÏ'vG#³ô¿ iÚeüW–×:ÛËv­Î·yqÈ#˜ä••º÷rtV.·á«fé./'Õã‘PFž­uh˜žR)IäòFz ð*Õ¶‘mm£.9/±G|—³I>9ýó9“<œÙ`Œ á|o©xWÅ)𗇥½Ñ5‰cÖ¥û^˜ÒÅp˲Æì2,œm}½Gë ÿ…qàú|7ÿ‚¸?øšò]àÚxã^ƒâ¨µÙocÔõkÈÖÒXX¼BKK©éšFiÙ‚HËg$×­|Xÿ’Yã/ûÞÿ臠þÇÿèMðßþ àÿâhÿ…qàú|7ÿ‚¸?øšå<}}¡øî_ éú«á­cÏïRUMJÝ?Ðo|È–EÎve‡#<ã[A°}×ïx–ö¦ÃÄ“=ü6°y–9±žò“'dL^'ž³dã$ÓþÇÿèMðßþ àÿâhÿ…qàú|7ÿ‚¸?øšó? >öá¯/®´8tkß #»Ö Yì]SF1neg@Ã̉•NáóFz©õI<9àûÃS蚆š{o/D¶H,å–Fa C¾ßß…Œ€ä•‰éÀEÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üMr6:¾¥aâ-_MÔuhì­cºu¹ÕÖÖg™4û¡¾M»œÉ3d‚qA€-©jú^¥©ÝÛ^Ë­jRk&æÞÚêÎ8÷Ä‚YÇA$A¤_/®qRI2ôÏøWÿ¡7Ãø+ƒÿ‰£þÇÿèMðßþ àÿâk’¶ñV¡©kúv›£xˆ_iwwpÀuH!„így$°”®TÁ r S&8 ®§¬ê:¿„ôí&KK­fòçU»µ»ŽØE³ÙÙÝÉŽw²F7쉕½;GA@gü+ÿЛá¿üÁÿÄÑÿ ãÀÿô&øoÿpñ5æ>ñ§oâ í¯¤ŸL¹µ´Ó4½VæqËhˆÚ“$Ñîp Éù”yÙç}<}«&îiu1 ÊÇtúTRÛ,oªÎ—×1-¸FPÀ„Š´ãÍÉ<ïÿá\xþ„ß ÿà®þ&øWÿ¡7Ãø+ƒÿ‰®kS¾Ôïüu¡Ô^x|Dúl –ð;B­¢´þb3ÆÄ8vlFe!”â¸ÿ ÝêZ_ƒo5[-^çíÚG‚´ÛÙ ‰™¤ˆß1·“)«+Fq‡ã–Ü «ÿ ãÀÿô&øoÿpñ5Í|Mðƒ¬þx²êÏÂ~‚æ &îH¥‹M…^7X\†R ‚V^­âïÛiú¥ä:™ M~ö8Ì?³ïDq§ÝÎ\+¸QŒ6X÷??ä–xËþÀ·¿ú!誢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¬¯ éØZ,:Ÿçùo+ù›6ç|ŒøÆOMØëÚµkšøus=ß…’[©¥ž_µÞ.ù³aneU=€@t´QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEÊü4ÿ‘róþÃZ·þœn+ª®Wá§ü‹—ŸöÕ¿ôãq@v­ñšÊÏÆ“X[ÚÆg³¿ºL™’u8b‘ŽJFA}æÉ*Uúµ¥Ì–°ÝYÍöӢɱ8d‘d2‘ÁAà¿>ßë(Šë—ÛØj·NÚ§žç6á·ÈîYQœ“°C1ˆÝ¼¿Dñ/ƒîWÁÞÐt;»Õ²Ò¤‚)Df4öñÂÑûÔ11Ücbpvœ`ãXaÉc{ÛÞõ;1_Vä§ì/ÍozýüŽîªêÚ…®‘¥^êZ„¾M•œ/q<›Kl³IÀ€3^n<©eh¶j.”{ T\Ï’ _<Ì¡Š*)‡„*.OÆBäáxÃÁî úü–"­íØÔ¢7 $#í1Kkr¯˜Ïæ°ÜÐå_«´^SŒöú­w}mi=œ7ˆå¼”Áxâ7¨ÿ€Fçð¯2¿ðïˆ^Ú:ÛKÏØõ}WPŽéî•"”\Å|bc‰ rŠÇår>a—£ü>ž?躓øf¬lní®)"´G¼»Ä‘ÂÆÅö’ cå©Ë2…Pif ¥˜€ d’p¬MÅš6·xÖºuÔ.Ã$~e¼±,è ÄΠJ¼™ G<Šóß|=Ö?²um?U¿ÔÍþ‹>›qw4–Æ'šN<ÕH£Y3•÷ÅyÉ#OXÓ¼aâ+†éqáß³Ø\[âGµš 'x¤DxTÌ 3+-£aÜÄzÝõµ¤öpÜJ#–òS AýãˆÞB£þŸÂ©ê> Ó4뿳^\ìŸ0¢6m¦i„1d€@Ý#`gОŠHó-/áåÄ:ö…©]é·7¢ÇR†r5²g‰E¼èÏÃ(Änʼn.ÞJœ‹oM»»Õ ¼Ö´é·ZÚïö‹C©Ïr¡Hm—o$”&% À*˜Ãƒ¸ õIåX ’Y”Kˆ]°xP 'Ø Ó,n࿲‚îÎTšÚxÖX¤Cêà ¨5 ŸÙ¬4h1o›gon¿¸;m‘Wîü§h 88ãŠæümÿM¡¹Óžê)碌‚ÙÑwE—, UÈËF±÷†Î`tòß[E¨[ØÉ&Û«ˆä–$*~eB¡¹é‘½xÎO8èpZ_[^Mw´›ÞÒ_"o”€¯µ_#‡^™ôê¬ïY\\YCw§B&Ô´ù…Õ´{‚ù„¯Oz3¨'€XÕÂø‹Âz¤ðÚY6¡q{§ˆ ¼ŽdEÓ¯ÚYd–è‡`Ø-"°3\`ЧÛ\%Ìeã…ñâHÚ3•b§†ã àô#5“¨ZêúUž¥§ËçY^B—I´®øÝC)ÁŒ‚8#5ç°øoX‚;7›LŽú(¯µ‰~Ã%ÊÆ»ç½im® s€©» ,¾f@ܸ®»À7z_<9§êQˆ¯­4Ûh.vȱ*°ÈààƒÓŠÞ¢Š(®WâÇü’ÏØ÷ÿD=uUÊüXÿ’Yã/ûÞÿ臠ª‚h¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€9»G®øÒ'™†µ&ÿľóÔú×AöëúÞÿßPÿñÊçüsÏ®ø7.ëRd£”?ò¼î"ºì«ùé{ÿ“ñT€>Ýqÿ@»ßûêþ9GÛ®?è{ÿ}CÿÇ(þÊ·ÿž—¿ø7ÿGöU¿üô½ÿÀÉ¿øª5ûuÇýïï¨øån¸ÿ ]ïýõÿ£û*ßþz^ÿàdßüUÙVÿóÒ÷ÿ&ÿâ¨Ôí×ô ½ÿ¾¡ÿã”}ºãþw¿÷Ô?ürì«ùé{ÿ“ñTe[ÿÏKßü ›ÿŠ£P·\Ð.÷þú‡ÿŽQöëúÞÿßPÿñÊ?²­ÿç¥ïþMÿÅQý•oÿ=/ð2oþ*@¯zò^CåM¦êj¹Îa¹H›þúIA¦ét»í,4[¸mãÎÕä’I$É’I$’y$’j×öU¿üô½ÿÀÉ¿øª?²­ÿç¥ïþMÿÅQ¨Û®?è{ÿ}CÿÇ(ûuÇýïï¨øåÙVÿóÒ÷ÿ&ÿâ¨þÊ·ÿž—¿ø7ÿF n¸ÿ ]ïýõÿ®[â­äíð¿Æ ÚmÚ£ÞÌÑ`~áù8|×Sý•oÿ=/ð2oþ*¹oŠºlü/ñƒ¬—d®xFë¹X¨~ ¶ ÛÑEÀ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+?BÕ`Ö¬ ݪJ‘‰ç·Ä€º)^&èOãÛ:V…exgHþÃÒÚÏÏóóuss¿fßõÓ¼»q“Ó~3ßã¥jÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW+ðÓþEËÏû jßúq¸®ª¹_†Ÿò.^ØkVÿÓÅqÚ·Æk+?Maohn4KžÎþé2fIÔáŠF9)÷›$¨!TKêÖ—0^ZÃug4SÛN‹$RÄá’DaÊGAW‚üPø#¬x¢+¯ \CoaªÝ;jž{œÛ†ß#¸eFrNÂA Ä#vòýľ¹_xoAÐîïVËJ’¥˜ ÓÛÇ FïPÄÇqˆeÁÚqƒŒub=‡$=ïo{ÔìÅ}[’Ÿ°¿5½ë÷ò;º««jºF•{©jù6Vp½Äòm-²4RÌp'Íy¸ðF¥ý•¢Ù¨¸hnQì5Qsæ=&îâÞòû[ÖëO¸y/’X­.–q ìHãòÓæ~N9”—ÖÑêPX< ^O“ÇY#(®ß‘ü ©ÙøƒL¼Ô–ÂÚç̺a9U¶@ñ¤¸lm;ZTSÏRGð¶8Ï xcPOŠ—Šï4ÈìEê\FÅÚ6˜£C§,JÅ ÈÞãŒàqw/CÔ/4¿ -½˜ºmOŸOÕ#gE2N·fHØ1ë<™=<8ȯÑ^mªxKW¹øƒ&ª÷:“Ú›ëYí„[$PˆыÆÓ ²¹*ŒĘ;y4žÒxŽy¤µÖz5Ôº^—2ª´CæI#©chíŽÜ¶b Œn ­µñn‹uª> ·iÚF…ÛȰÉ"çr$Å|·aµ²ªÄŒ8«¶úŕΙs¨[<³Û[¼ñÉåBîûávŽETsÈÀ8ã9ÄiÚ.´4³émLöŒú±š3ÑÛH®¥7™æ?–¡ƒ({|Íß—ñ§†õ[ëçû?ìÒÿÄîG¹«5ÜW?j[„RNYæ…À镘oª×wÖÖ“ÙÃq(Ž[ÉL)÷Ž#y øn òÙüâ7Ö5{˜uI/§mDÛÝùÖËoÌ’yí³t+>ÐcÜjìþŠë_ðæ¢ž·µ]3PŠgó&ŽWÛöyº©%FÙ,÷òÁ#(™ôMCP¶Ó’¼—ÊI¦HŠ’7¹Â‚@ã'’R*ÕrßÏ™àmVÎ?øü¿ˆÙÙ¨ûÆâO–2?ÝbžÁIè oÉgU·Øï•a•Vój~éKG˜òNïŸ pºä‚ ºÏŠô}óì×÷2,ª‚Y<»yeXç+"‘ð~g pyâ´ Ô­'Ô§°†`÷pÁË 9ZEFÏC“nzŒóë6µ¯É§è­«Å¬J—È'‰$%%Àùº ”~vù}y›ïjÖÖ²XYÛ}²DðþŸ¥Zj&UCou ¸hÁ;¾]èÞ¼àgsàÕ-®æ2ñ‰B‡xñ$mʱSÃqpz‚ S¾¶Ó4Û»ûùD6v±<óJÀˆ ³1Ç ׊Áá-_]‚{ÛkOìÏöD³–Ú-ŽÚÔ‚bÓDì‘â`ñ|ØN‡#ž)ðMæµ ø‡MºÐà¾Ôo´ZN{•‚Cl»y$¡1(VTÆÀP«ÑU´È¢ƒM´†ÞÌXÃ(‰jªª P IQ´q…$qÇf€ å~,É,ñ—ýoôC×U\¯Åù%ž2ÿ°-ïþˆzꨢŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÊñ§ø‚Xõ%¹ÿE›íImw-´‘ɱ“!âeaò»Œg1¬¯ø@ôùüñ'þzÿ©|i©j¶sø~ÏCšÆ SPkFšòÙçHÑm§˜‹$d’aïw=j/°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÿÁ ÿü™GØ|qÿC†ÿðC?ÿ&PUEsþÕ/µ›U­šö+ÛË9Ú&Š7ò.¥„0Vf+‘8Üy'šè(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®káíÌ÷^yTÔ¡ß#–;RötQ“Ø*€`íYÿ¤¾¹ðÇü#ÚU½´×¾$óôˆÞæá¡Ž ö“¹•G'#òã’G"¼×à_Ã|+þÛýφõ_í/#þbsÁåù~gý;6sæ{côïôW+öïнá¿üOÿÈt}»Çô/xoÿÓÿòuTW+öïнá¿üOÿÈt}»Çô/xoÿÓÿòuTW+öïнá¿üOÿÈt}»Çô/xoÿÓÿòuTW+öïнá¿üOÿÈt}»Çô/xoÿÓÿòuTW+öïнá¿üOÿÈt}»Çô/xoÿÓÿòuTW âøÇAÐ5=^óÃ~{m>Ö[¹V-vbì‘¡b@3€q’+º Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹_†Ÿò.^ØkVÿÓÅuUÊü4ÿ‘róþÃZ·þœn(ŽÕ¾3YYøÒk {Cq¢XÌöw÷I“2N§ R1ÉHÈ ¼Ù%A ¢_V´¹‚òÖ«9¢žÚtY"–' ’# †R8 ‚"¼â‡ÁýcÅ]xRâ{ VéÛTóÜæÜ6ùÀë*3’vf ·—èž%ð}Êø;Ãz‡wz¶ZTE(ŒÀfžÞ8Z0?z†&;ŒlC.ÓŒc«ì9!ìo{{Þ§f+êÜ”ý…ù­ï_¿‘ÝÕ][PµÒ4«ÝKP—ɲ³…î'“im‘¢–c€ 8ðkÍÇ‚5/ì­ÍEÃCraª‹™â’Akç™”1EE8Pð…E‰øÈ\œ/x#]Ô_’ÃDU½»”Fá$„}¦)mnRóüÖš«á±µv€ËÊqžßU®ï­­'³†âQ·’˜ RïFòðÜþæWþñ ÛC§[iyû¯ªêÝ=Ò¤R‹˜¯Œ@lq"á®QXà0<®GÌ2ô‡ÓÇâ½R ÁݵÂÅ$Vˆñ·—x’8XØ !ÞÒBA,|µ9fPªì¶¡k¤iWº–¡/“eg ÜO&ÒÛ#E,Çpà Öv‹â3Y»kKC}ÐŒÊ!½°¸´v@@,¢dRÀPHÎ23ÔW˜Úø ÄxOÄv³É©_j—~º°fž{U†æåÔ…*5vÉÎgʇ#œ’:™¼wcq¯®‹wzÒjT¶öW·×ó\Éa9Ú­+³c±øïÉû zäzG/ãÔ´Áwoq¦ý¹$»ŠþkB»•ÜlDpFŠAybRNæ~2^M#Â~"µðìн³­ÌÚFŒ×q}¡suw ’5äeƒcsÆ#Œ¾pA^p¼zåå²øg]}.â÷I³m*öKùE“Ék;YáHd«‘~ÓµXýУ“Wþø>ëÃZõãN×’[ƒÄsÍ%¨¾³Ñ®¥Òô¹•P­¢2IK€Glvå³cqÓ´]hh:…gÒÚ(4™íõc4f9£¶‘]J(o3Ì-CPöù›¸oo¬Y\é—:…³Ë=µ»ÏžT.ï¾häU@71 ŒPsŽ3‘Zâ4ðÞ«oàý|ÿgýš_øÈ÷"Uf»ŠçíB pŠIË<и2££3©?‚gµ[8ÿãòþ#gf£ï‰>XÈÿuˆb{' 4ÔÕX5 Y罆9‡™dâ;€À®ÂQ\uê6°9uA’8Ϋo!±ß*Ã*­æÔýÒ–1äß>à?uÉ.yÿèwWššµŠ)¶Ô¡‘ß´ˆA,{í2ÇÇ9•OE  ØuKYôTÕ`3KdöÿiBHÒ2Ü1É#¢¸ôÆiúž¡k¦[$÷ÒùQ<ÐÛ«m-™%‘cŒpWuè3“Íy/м#â ý?\±²ÒœÞHš©þÑóâ { ðN°Z¿pÚd€|ÁTy9šÚñG‡u›¯\Oo¦Ç{çjúmÔW­p¨mm"’ÜË©äÑÉ&8~s¹UH¥W+ñcþIgŒ¿ì {ÿ¢ºªå~,É,ñ—ýoôCÐUEck¾(Ñ´'Hµ;ø£¹f;TYåÿr$Ûð¹_x¿ÄÖþÖuÃÉgmae5ØŸY“cH#BØX-Î?Jô:(¢€ (¢€ (¢€ (¢€ (¢€ (¢€9_ÈÇàOû Iÿ¦ëÊÐñ¾«>ƒà½W³HžçOÓî.âYA(ÏlÀ0d àŠæ¼Eâ=Qñ¿ƒtÍ?YÓnõ+mj>Ò ¤’h¶Ø^+n@r¸bÈàœW_â* {@Ôô‹Ç•-µ Ym%hˆ©"%Igã Ð!mâ]j¶¥sumw¿S°±E} ïLdY®¢ŠBRy ?Ë/ÊÀ9ÝÈúWŽuGoê:ÄKÑŸRymcÐn¼6ÒËí¼i<—s±X…R~ðÀÁ#¿×4¨5›(ínžTŽ;«{°c ðÌ“ ä FöÏNµ ÙXézfÖ¸´ºšêiR|6ï´Jòȧ|¹‘€˜ÎzÐ=¦«¯éú¶‘oâ!¦¼Z´Ke£[L"yv33 ÛŸ8 È/<`|8ñ®¯®èÑjš«‘&–/ͧ‡/->rªÛ#¸šC½Hq»†kªÒ<)Ÿ}ms>¥©j?dR–qÞHŒ¶ §nÕŽÞ79fÁ#<œ³Áޗö¶qxƒW¿Ó­mVÒÞÒñm¶DŠ) (䀸åSœœŸ¨|AÒ­î-&uÓË+OtaF³žë·‚¤$*äín@1d5/]Á®xvÂê¡u+Ño,“¤h#Co,¡2rG–IQ’ 1Œ4ßð¯t6Ó!ÓÝ&{8îçº1–\IæÁ-¹°>âÅ1ENNnÿÂ)ÝY]\jš¥ÅÅ•Äw0<³+l+‘mÛ·n%1Æãwd)¾ñõŽ¥¤éWN—2%ÊY¤÷Kn#Š)îcãF]ìT·›¸b‚Ç9«Þñž¿5ŠCg}j/ìF£f÷*n!ýÞâ»]ˆ*eŒÀgp+¸sTt¯‡zf˜št×Ú—Ø-Ôµ›ùšŒFöi Óí,ZÊÊ®ÚV¶t2ÆcÊ*§–ÖèW!‰àB@ ž1´Qkc~÷Ï~úoØÂÆ%YÖ¸ÚrápcPAÝ™z ‘ÈÛ|JÔn#…¡ÒÙ­ÞÇC½[É#DYEíÈÀffRWvÅÉÃ#d‘°¿acá Kilg–òúêòÛPmMîfdßq3[½¾d p#|¡q±}óJÛáö—mi§ÛÅs~#³µÓ­΄ȶ3  -òõݸ`çŒí ;ˆÚm¯ÚRòÃR·¸´Žâ[È#-lFr®T.æ'ùKpHûß)è´-f `_a¸‚k+ƒm<3¨VGØ®:0RDaÏFç aê¿ô­N÷\ºžâùdÖ-n­'è¥Ä6йL©Á iÏ%³œ€7ôÍ* :÷Vºåi5;¥»˜9+ˆb„Ààm…O9äŸ`1~ȹyÿa­[ÿN7ÕW+ðÓþEËÏû jßúq¸®ª€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€9_ÈÇàOû Iÿ¦ëʛǾ)‡ÂZ,W²›!$÷1ÚÅöë±kæ<—”«mCºsŒw¨|eÿ#?ì5'þ›¯*ÇŠ4MKSÕ4[í/R³´m:I$1ÝYµÂ»:lÈÛ,eHRã<ýóÅT³ñÞ–<=aªjïö»óYUξ\lCLWýNq#]®¤ã8­y|I¤Åª¶-ê%Ú±F ¬\Gæ”/¡¼¿Ÿns·œb¹{‡m-´6¿Û3›<îž+#5ËO6`I¸¡6Ðn0wMªøçVÔ57½ÖBÙ_A=¼‰okåO$rÆèIìu@ãiòà ‹–?6à yü_¥ >îæÖG¹{q T(ò™›d!w€vùU¾é9çƒKo®^ÙX^]x«OƒKŠßaY-îÒK¸à*á÷çhC’ʱé¤ü<±°Ðîìã]2Öæâ{{“6™¦Ef‹$,‘‹’ØuÉ Ç«câ¯ÞxkQ½%ν?ž÷1ÊÉ2A墰ÃärÛËnÉe\åFÚ³/Œt¬#½’ü-»¬ŽO•&èÖ6Ù!‘vîŒ#|¬X ¤`â‘|Wd¾'¼ÑîJÁäTØí’SJéÓ V0¯Éɰ0„Öv๴9¬d²ÕÝY- µ¼&ÝI¹òä’BË’D{ÚgÝÁã ŒÔ:Ãøµ1x—ú„ÛßI(Ž=­ºâ!0981ÔéÎsÇJןÅúPÓîîmd{—·âB)™¶Bx‡o•[x5ZïÄZ¾—¡jWÚÞ‰oo=¸O³Çÿ›ûmDÞQY[qPr„|ùÅ'á冇wgé–·7ÛÜ™´Í2+4Y ‘dˆì\–îHf=[£?†nïn"›SÕÞãÐݼ+HvBÇ&ã´ù…\±$ tÆÐ ®üg Úiö÷·Å-ç2ío"BPDvÊΡs¡v`žŠmïŒ4« VþÒúê(–Ñ;#2¤,aUVXX¶ã€ä¶Ð¹8rü<–[ ;9u©^ÝÌfvóÌÓ°Pø_7s)Îì `Œκøyö»½n{S{jã}ŸîÅ$ªeO½Îèb†,öò÷`çhÓø±ÿ$³Æ_ö½ÿÑ]Ur¿?ä–xËþÀ·¿ú!몠Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹_†Ÿò.^ØkVÿÓÅuUÊü4ÿ‘róþÃZ·þœn(ŽÕ¾3YYøÒk {Cq¢XÌöw÷I“2N§ R1ÉHÈ ¼Ù%A ¢_V´¹‚òÖ«9¢žÚtY"–' ’# †R8 ‚"¼â‡ÁýcÅ]xRâ{ VéÛTóÜæÜ6ùÀë*3’vf ·—èž%ð}Êø;Ãz‡wz¶ZTE(ŒÀfžÞ8Z0?z†&;ŒlC.ÓŒc«ì9!ìo{{Þ§f+êÜ”ý…ù­ï_¿‘ÝÔV× sxÄ¡C¼x’6ŒåX©á€8È8=Á‚ yðF¥ý•¢Ù¨¸hnQì5QsÒÞZ3å$œ-ƒû¾›B“ÁiÚ.´4³émLöŒú±š3ÑÛH®¥7™æ?–¡ƒ({|ÍÜ··Ö,®tËBÙåžÚÝçŽO*wß ´r* ˜†F(9ÇÈ­ ñxoU·ð~¾³þÍ/üNä{‘*³]Åsö¡¸E$åžh\™QÑ™€ÔŸÁ#}cW¹‡QÔ’úvÔM½ßl¶ñ¬É €qžÛ7Gò³í=Àð€=JîúÚÒ{8n%Ëy)‚ þñÄo!QÿÏáVkÌgðtWZÿ‡5ð…½ªéš„S?™4r¾ß³Ì…ÕI*6ÈÐ1`w¿– DϧPEPEPEPEPEPEP\¯Åù%ž2ÿ°-ïþˆzÐÔmÚmNc•ä« X[§Ø“$ÏŒW1ñï+Û[ÚÈ|?pZ;vÜ€ùsó«ží@à­KÁ¾sxBæÆîX´–ú¤!fÿ×Ôk¸ýdY½füLñpO†þ+²×ôGG»›I»Š6’?:ÞGh\³G•$a>•êt Œƒ@þ—á-;L¿ŠòÚç[ycÎÕ¹Öï.#9s’²·^àààŽ@©µ¿ Xë7Iqy>¯Š‚0,õk«DÀ$ò‘HªO'’3Ðg[TP}¶‘mm£.9/±G|—³I>9ýó9“<œÙ`Œ ÏÒü%§i—ñ^[\ëo,yÚ·:ÝåÄg Žc’VVëÜÈÐQ@ºß†¬u›¤¸¼ŸWŽEAzµÕ¢`yH¤U'“Éè3À«VÚEµ¶Œt¸ä¾6Å=ò^Í$ølç÷ÌæLòpwdq‚0+BŠçô¿ iÚeüW–×:ÛËv­Î·yqÈ#˜ä••º÷rM­øjÇYºK‹ÉõxäTg«]Z&'”ŠERy<‘žƒ< Ú¢€3í´‹kméqÉ|mŠ<{佚IðÙÏï™Ì™äàîÈã`V~—á-;L¿ŠòÚç[ycÎÕ¹Öï.#9s’²·^àààŽ@®‚ŠÅÖü5c¬Ý%Åäú¼r*À³Õ®­“ÊE"©<žHÏAžZ¶Ò-­´c¥Ç%ñ¶(ñï’öi'Ãg?¾g2g“ƒ»#ŒZPÎvß“ÁßtOEª®«©«]ƶp·È$µº”o™ÚB6c%rÇ’kÛÿ²ÿê£ßýª«øÓMÕo'ðýæ‡ Œ÷:^ ×m åËÀ’#[O Ö9 ÌÝìzT_nñÇý ÞÿÁôÿü‡JÀ]þËÿ¨ÿ}ÿöª?²ÿê£ßýª©}»Çô/xoÿÓÿònñÇý ÞÿÁôÿü‡E€»ý—ÿP-þûÿíTeÿÔ Fÿ¾ÿûURûwŽ?è^ðßþ§ÿä:>Ýãú¼7ÿƒéÿù‹wû/þ Z7ý÷ÿÚ¨þËÿ¨ÿ}ÿöª¥öïнá¿üOÿÈt}»Çô/xoÿÓÿòïö_ý@´oûïÿµQý—ÿP-þûÿíUKíÞ8ÿ¡{Ãø>ŸÿèûwŽ?è^ðßþ§ÿä:,ßì¿úhß÷ßÿj£û/þ Z7ý÷ÿÚª—Û¼qÿB÷†ÿð}?ÿ!Ñöïнá¿üOÿÈtX ¿ÙõÑ¿ï¿þÕGö_ý@´oûïÿµU/·xãþ…ï ÿàúþC£íÞ8ÿ¡{Ãø>Ÿÿè°²ÿê£ßýªì¿úhß÷ßÿjª_nñÇý ÞÿÁôÿü‡GÛ¼qÿB÷†ÿð}?ÿ!Ñ`#øX»<+:yiÝ_Uî¯üL.8?]usþÒï´›}Um–ö[ÛËÉÚV–4ó(fU- Ú9Šè)€QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEÇ|@]ÚÇÇ—4Ÿñ:“ä†MŽâ_yѲ1ùÖ§‘ÿPýgÿÿûuRñÔ:‡Úü1¦éw:Ÿöv¦×Ám$I'–Ö—1dy®ŠpÒ§³ŒÕ sÇ×Z•q©jž ñ,Và4æX9 n‰$’I¥`7<ú‡ë?øÿÛ¨ò?ê¬ÿàÿn¬»êö6÷–~ ñ¶×¬±H³éøtaGúWpEOÿ F¯ÿB'‰?ïþÿÉTX ¾GýCõŸüÿíÔyõÖð?ÿ·U/øJ5úø¸ý‡V\i3ÞîQû—ä4ä{`×¢WxßS×µïëúEŸü@—:†ŸqiKq§„W’6PX‹¢q’3€kÑhHŠ(¦EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^kàøWHÒõWĺ%ìZÖ«æ[Üßʼn›û‚2¬ÀŒ‚Њôª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(¸ñ×ÃÛ—q⟠Jà`4š…»=9jæþ"øÏÀÏðÛÅÖºW‰<4×7:MÔiµüås …P²Ä“€=ëÕ¨ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹ÿÄßÅú†¼ÁnÇW¼¶Äv§ë)?뉮º¼ÉõÍKÂú‡‹üC­øK[–ßy“íVòÙ2%•º¤¸ÿ=dÆÜæLb€7þÄ´jÞ~?².H¶¶’þò{.^?ûe]upV³ë7ŸtÍI<+«éÖÒZËg5ÜÖevž&Äs»¯½qùjOjïh¢Š(¢Š(¢Š«ªÍso¥ÞMajnï#…ÞpÁ|וL±dàd(ƒ¿Ñÿá6ÔüW0“ËKXF‘§Mÿ<çB³I0úJ!_¬×øGXþÞðÞŸ©ü©gˆyÑwŠQòȇÝ\2þÄøsÄþÐô-ûÁ¾#{Û§0ù‚[ö›¢’O+quÆí’¾N=:+oÀ ©Å©xˆ^h—ÚN›qt/-Rî[vmò/ï”dpõ/’FL‡Ò€;*(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ å~,É,ñ—ýoôC×U\¯Åù%ž2ÿ°-ïþˆzꨢŠ(¢Š(¢Š(¢Šå|eÿ#?ì5'þ›¯+ª®WÆ_ò1øþÃRéºòºª(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¬ý{X²ÐtÇÔ57•-‘ã÷P¼ÎÏ#¬hªˆ 1,Êõ¬_øO4ùóñ'þšÿ ªŠåá<Ò?çÏÄŸøNj?übøO4ùóñ'þšÿ ªŠåá<Ò?çÏÄŸøNj?übøO4ùóñ'þšÿ ªŠåá<Ò?çÏÄŸøNj?übøO4ùóñ'þšÿ ªŠåá<Ò?çÏÄŸøNj?übøO4ùóñ'þšÿ ª¹_‹òK~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTW+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTU]'PµÕô«=KO—β¼…. “i]ñº†S‚pFjo[Ò´Tº×5;6ÙÜF²Þ\$(ÎA!Abp DZ  _ÈÇàOû Iÿ¦ëÊê«å¿ß'ѼoáøüqáýbÆÁ¢³£›ö†Kˆ£ äÝŽH9Çï_ð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UWKÔ¬u{¯´«Ûkë)såÜ[J²Æø$2’#ê Z Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Wâ_ü‹–öÒôão]Ur¿ÿä\³ÿ°Ö“ÿ§zꨦ¥©Zi±Ä÷²ìódF¡K´ŽA;UTN8 'µA¦ëv:”¦;7™ÝK«ƒ‹å²lʾTllH¤+`I€HƒÅ_n¶µ`{Ãâ@ÐÜyAò2ù‘77Í·—*ÍÉû§Ïµÿ ø£QµÕG‘4á´-bÂÄ\OLëiäÇ#´±xæÃd€¡wõõª«©êºe²O}/•Í º¶ÒÙ’Y8ÇõwQžƒ98× iákë?%ý­˜ŠÕ5וdYbÉôÜ?Îï’¸Él1æ¹O øsTÔ¼%àë½6ÀCn–ZKÜ7šƒíÛ.¬¦c¡¥I5Åá…Am{¥@#@L­Ó$“ÔàPwUu-B×LµûEôÂ(·*A%™Ž@’IÀšòoè:µ÷ôÙ´uþËk }‘nüÁþ•q$1'Âò¾X 9ÁöŒ…®èžÕ4¹#Ô#‹R¸’Êî ´³»žÑ|ò°MÑâ|†s—1®všô­/R´Õ y¬e2*HÑ8dddqÕYX§§wr¸OéÚ–½áø–_Å"½ð–{ñI#B#e•˜Bï»fU™”(È%•k Hðž«kjñêš/ö”>L°YÚý±bmöÉÝX:Ÿ4O1¹X >èôí'PµÕô«=KO—β¼…. “i]ñº†S‚pFišž©g¦~Ù)WöE#Hò0ª ±àÀ¯&Öáðׇm´Ës¦ß¶¶¯-¼‘+Ëà=$vÜIÛ@Å–¿¦_Oc ¥ÚË%ìÜÀ[çŽ&DçZTžœi×}áÙ5ßh²ëº=›é«§ß¥Õ»–5–I­š0AÆâBHI†zí5Åé~ñ“AºÔô’ÚŲéFKó,2:¬bÜ\©•œÈ+6V<#/9fb¬ì¶× sxÄ¡C¼x’6ŒåX©á€8È8=Á‚ K^5'5i¬Œí$e’鯵)£t;¾GÛ=»8ÆìdÀ{-r¿ ÿä–x7þÀ¶_ú!(ñ—üŒ~ÿ°ÔŸún¼£á?ü’ÏÿØËÿD%2ÿ‘ÀŸö“ÿM×”ÕVkëÚ:}£~«§¯ÙãyfÍÊ)ï3sÀÉéZUãÚý®§cá ¬¼5g«Iö}.ñm`žÄ­Î˜âÖQ†t<›öÆ–c¿;Ž ÃYúÞ·¥h6©u®jv:m³¸e¼¸HQœ‚B‚Ä àc^kãó,þ%¿‹F_ÛkÂÚhޤÖsÝÿr€&m– Û|ÂØAþ#Y–¾ Ž]ãRÕ|BöÐj‘Jnl49š[\ØÝ£²Ç+\»ež$c³`-òòIÏ¥êV:µ’^iW¶×¶³ÛJ²#}I­W“ËiªÛxvûnX.õ¡#^$rAw4fQæMº¬ƒ÷‰°Â'€Ù˺>!K],ÜIq\CP}¥ ÅÜ‹MË»Ê ÍÈhÈÚw»lªÍ¨Y"Ý3]ÛªÚ¸Žà™TXª°Wçå;]Nf¸¯#ÑáñÒiòI¨_ßÍxm¢ûlØIÆûL~w—#ÌÊÎ"óÂùHªr ÁÚ*îŸavÒj:„šfª4ë_Çzmî¢gžêÙtø¢Y’ZM²mp9Ý`àŠõ+;»{ÛužÎx® lí’'§qSWŸx¡žmÎÒ´Ý^ÆÞïRßrÖÉ4Rºyg÷­?¿ ̨¸]¯œ3|»ÈÒ?·¾Êë®ÂMäG ±Øý‹že[ÉÔo-t-¶™IB7ÍœS´¹‚òÖ«9¢žÚtY"–' ’# †R8 ‚"›{ykc}s ´9Æùœ"çÓ&¼jÏMñV•àÿ àj[]\xv¶Ç2Ë*[K–Kµb,<·½Ð¥¶õܹZ-¶­a¨iÚ¶½&¡ªØÚOymÓfW„È òäXšIfe']Ìw8ðf€=*+ûId·Ž+¨KˆšxUdÉ• ê;¨.™#¹}EX¯>›DMKÄ~HôíCJÓ³5-ÿg‘íÞ{‹FU2F~BØgÚû¤tW-¥Ïâ«™4ËøüA©·J3£-Àˆ£‹qrJ(® Ì]ZE*Äm\ö[k˜.£2ZÍÑ«¼e£pÀ:1W\Žá”©ˆ#µK^5%¿Š&°ñµÃ¿ˆVêÆÒêëIT’u\-ö¤b  âAå­° ‚ 4|¶½–€9_†Ÿò.^ØkVÿÓÅuUÊü4ÿ‘róþÃZ·þœn+ª Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Gâ›lð¬æ${u}(ﺿñ0·äò8üEhÿjÔwFÿ¾?ûmfüV¹‚ÏÂQ]^MÐjÚT’Ë+…HÑu rY‰à$š—þ?ÿèrðßþ ÿâ©0.ÿjÔwFÿ¾?ûmÚŸõÑ¿ïþÛT¿ácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ¢À]þÔÿ¨îÿ|öÚ?µ?ê;£ßý¶©ÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿE€»ý©ÿQÝþøÿí´jÔwFÿ¾?ûmRÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*‹wûSþ£º7ýñÿÛhþÔÿ¨îÿ|öÚ¥ÿ Àÿô9xoÿñTÂÇð?ý^ÿÁ¤üUïö§ýGtoûãÿ¶Ñý©ÿQÝþøÿíµKþ?ÿèrðßþ ÿâ¨ÿ…àú¼7ÿƒH?øª,ßíOúŽèß÷Çÿm£ûSþ£º7ýñÿÛj—ü,ÿÐåá¿üAÿÅQÿ Àÿô9xoÿñTX ¿ÚŸõÑ¿ïþÛGö§ýGtoûãÿ¶Õ/øXþÿ¡ËÃø4ƒÿŠ£þ?ÿèrðßþ ÿ⨰µ?ê;£ßý¶íOúŽèß÷Çÿmª_ð±üÿC—†ÿðiÿGü,ÿÐåá¿üAÿÅQ`„ÿòK<ÿ`[/ý•ŽL«®øÀˆòmI…w*üKï;€•IðŸþIgƒì eÿ¢£ñÌ1\k¾ŠxÒXÛZ“(êø—Þv4Àè<ÝOþ|ì¿ð)¿øÝn§ÿ>v_øßünì}3þÖ_÷áÂì}3þÖ_÷á– n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF `ü0,|3td ¯ý±«n rþиèp3ùWY\ŸÃXü3t‘ª¢.±«*ªŒ¡qÀÖS¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¯ýµ¿ä–i_ö‹ÿDOEñUQ@Q@Q@Q@Q@Q@Q@Q@þËŸòB|3ÿo_úU-z­PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPÿÙoscache-2.4.1.orig/docs/wiki/API Usage.html0000644000175000017500000001126210615670675020256 0ustar twernertwerner OSCache - Usage

Beside the JSP tag library and the CacheFilter you can use OSCache through its straightforward API. You can use the GeneralCacheAdministrator to create, flush and administrate the cache. The GeneralCacheAdministrator has a cache instance and delegates different Cache's methods. Furthermore the GeneralCacheAdministrator is in charge of load the cache.properties and create a cache instance with the properties definded. You have to store an instance of the GeneralCacheAdministrator in a static value or use a singleton pattern to access the same GeneralCacheAdministrator.

Typical use with fail over

String myKey = "myKey";
String myValue;
int myRefreshPeriod = 1000;
try {
    // Get from the cache
    myValue = (String) admin.getFromCache(myKey, myRefreshPeriod);
} catch (NeedsRefreshException nre) {
    try {
        // Get the value (probably from the database)
        myValue = "This is the content retrieved.";
        // Store in the cache
        admin.putInCache(myKey, myValue);
    } catch (Exception ex) {
        // We have the current content if we want fail-over.
        myValue = (String) nre.getCacheContent();
        // It is essential that cancelUpdate is called if the
        // cached content is not rebuilt
        admin.cancelUpdate(myKey);
    }
}

Typical use without fail over

String myKey = "myKey";
String myValue;
int myRefreshPeriod = 1000;
try {
    // Get from the cache
    myValue = (String) admin.getFromCache(myKey, myRefreshPeriod);
} catch (NeedsRefreshException nre) {
    try {
        // Get the value (probably from the database)
        myValue = "This is the content retrieved.";
        // Store in the cache
        admin.putInCache(myKey, myValue);
        updated = true;
    } finally {
        if (!updated) {
            // It is essential that cancelUpdate is called if the
            // cached content could not be rebuilt
            admin.cancelUpdate(myKey);
        }
    }
}

Note

Be Careful

If a NeedsRefreshException is raised you have to invoke admin.putInCache or even admin.cancelUpdate to avoid deadlock situation.

oscache-2.4.1.orig/docs/wiki/Hibernate 2.1 Cache Adapter.html0000644000175000017500000001460310347636213023321 0ustar twernertwerner OSCache - Hibernate 2.1 Cache Adapter

Patched version of OSCache.java originally created by Mathias Bogaert.

OSCache.java
import java.util.Properties;

import net.sf.hibernate.cache.Cache;
import net.sf.hibernate.cache.CacheException;
import net.sf.hibernate.cache.Timestamper;
import net.sf.hibernate.util.PropertiesHelper;
import net.sf.hibernate.util.StringHelper;

import com.opensymphony.oscache.base.Config;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.NeedsRefreshException;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;

/**
 * Adapter for the OSCache implementation
 */
public class OSCache implements Cache {
    
    /** 
     * The <tt>OSCache</tt> cache capacity property suffix. 
     */
    public static final String OSCACHE_CAPACITY = "cache.capacity";

    private static final Properties OSCACHE_PROPERTIES = new Config().getProperties();
	/** 
	 * The OSCache 2.0 cache administrator. 
	 */
	private static GeneralCacheAdministrator cache = new GeneralCacheAdministrator();

    private static Integer capacity = PropertiesHelper.getInteger(OSCACHE_CAPACITY, OSCACHE_PROPERTIES);

    static {
        if (capacity != null) cache.setCacheCapacity(capacity.intValue());
    }
    
	private final int refreshPeriod;
	private final String cron;
	private final String regionName;
    private final String[] regionGroups;
	
	private String toString(Object key) {
		return String.valueOf(key) + StringHelper.DOT + regionName;
	}

	public OSCache(int refreshPeriod, String cron, String region) {
		this.refreshPeriod = refreshPeriod;
		this.cron = cron;
		this.regionName = region;
        this.regionGroups = new String[] {region};
	}

	public Object get(Object key) throws CacheException {
		try {
			return cache.getFromCache( toString(key), refreshPeriod, cron );
		}
		catch (NeedsRefreshException e) {
			cache.cancelUpdate( toString(key) );
			return null;
		}
	}

	public void put(Object key, Object value) throws CacheException {
		cache.putInCache( toString(key), value, regionGroups );
	}

	public void remove(Object key) throws CacheException {
		cache.flushEntry( toString(key) );
	}

	public void clear() throws CacheException {
		cache.flushGroup(regionName);
	}

	public void destroy() throws CacheException {
		synchronized (cache) {
		    cache.destroy();
        }
	}

	public void lock(Object key) throws CacheException {
		// local cache, so we use synchronization
	}

	public void unlock(Object key) throws CacheException {
		// local cache, so we use synchronization
	}

	public long nextTimestamp() {
		return Timestamper.next();
	}

	public int getTimeout() {
		return CacheEntry.INDEFINITE_EXPIRY;
	}

}
oscache-2.4.1.orig/docs/wiki/OSCache 2.1.html0000644000175000017500000006244210615670675020354 0ustar twernertwerner OSCache - OSCache 2.1

Release Notes

(18th January 2005 - by Andres March)

New Features:

  • Added HashDiskPersistenceListner CACHE-132 that hashes file names in order to eliminate nasty characters and overly long names
  • Added property that allows cache entries to only be persisted when the memory capacity has been exceeded. The property is called: cache.persistence.overflow.only. It defaults to false for backwards compatibility meaning all cache entries are persisted when a listener has been registered. See CACHE-133
  • Check If-Modified-Since header in cache filter to increase performance, see CACHE-58 and CACHE-70

Improvements:

  • Updated jgroups jar regarding changed package name CACHE-85 , CACHE-126 and configuration based upon recommendations from Bela Ban (javagroups maintainer).
  • More evenly distributed disk caching, see CACHE-94
  • Public access for configuration properties, see CACHE-92
  • Public method to clear cache, see CACHE-104 , CACHE-68
  • Output the scope name's in toString() of ScopeEventListenerImpl, see CACHE-95
  • Call get() method on put() method call, see CACHE-105
  • Library updates
  • Moved all docs to wiki
  • Website documentation updates.

Bug Fixes:

  • CACHE-73 - NullpointerException after deserialization of AbstractConcurrentReadCache
  • CACHE-98 - Disk cache not getting served first time for long keys
  • CACHE-107 - flushEntry does not behave correctly in cluster
  • CACHE-118 - Updating groups doesn't work
  • CACHE-119 - flush does not work correctly in a clustered environment

OpenSymphony JIRA (21 issues)
T Key Summary
New Feature CACHE-133 added cache.persistence.overflow.only property
New Feature CACHE-132 Added HashDiskPersistenceListner
Bug CACHE-126 java.lang.NoClassDefFoundError: org/javagroups/blocks/NotificationBus$Consumer
Bug CACHE-119 flush does not work correctly in a clustered environment
Bug CACHE-118 Updating groups doesn't work
Bug CACHE-107 flushEntry does not behave correctly in cluster
Improvement CACHE-105 call get() method on put() method call
Improvement CACHE-104 Destroy cache
Improvement CACHE-103 upgrade to Commons Collections 3.1
Improvement CACHE-102 upgrade to Commons Logging 1.0.4
Bug CACHE-98 Disk cache not getting served first time for long keys
Improvement CACHE-95 Output the scope name's in toString()
Improvement CACHE-94 More evenly distributed disk caching
Improvement CACHE-92 public access for configuration properties
Bug CACHE-89 java.lang.NullPointerException : AbstractCacheAdministrator.finalizeListeners
Improvement CACHE-85 upgrade to JavaGroups 2.2.7
Bug CACHE-73 NullpointerException after deserialization of AbstractConcurrentReadCache
Bug CACHE-72 NullPointerException in AbstractConcurrentReadCache.clear
Bug CACHE-71 Flush and refresh of cached pages fail under heavy load
Bug CACHE-70 last modified problem
New Feature CACHE-58 Check If-Modified-Since header in cache filter

oscache-2.4.1.orig/docs/wiki/OSCache 2.1.1.html0000644000175000017500000006165510615670431020506 0ustar twernertwerner OSCache - OSCache 2.1.1

Release Notes

(1st May 2005 - by Andres March)

Improvements:

  • The taglib URI was changed to http://www.opensymphony.com/oscache in CACHE-61
  • The DiskPersistenceListener escapes '?' now and guarantees that the filenames will be unique based on the cache key, see CACHE-110
  • Session objects in cache tags are created only if necessary, see CACHE-88
  • The disk persistence configuration key can be accessed now, see CACHE-111

Bug Fixes:

  • The CacheFilter doesn't send back a 304 (not modified) response when client cache is de-activated anymore, see CACHE-116
  • CacheFilter doesn't support correctly i18N by setting encoding not properly, CACHE-38 and CACHE-159
  • Cron expressions - leap days not always matched correctly, CACHE-157
  • FindBugs doesn't report that the usage of GetResource may be unsafe if class Config is extended anymore, see CACHE-108
  • ConcurrentModificationException on flushGroup, see CACHE-127
  • Exception not thrown when not serializable object is persisted instead stack trace is persisted, see CACHE-112
  • A few concurrency issues were fixed, see CACHE-170, CACHE-167, CACHE-127

Changes that may affect backwards compatibility:

  • The improvement CACHE-88 may change the behaviour of the application, because a session object isn't created anymore even if it wasn't necessary. A web application may react different to a not existing session object.
  • The URI change of CACHE-61 from /oscache to http://www.opensymphony.com/oscache affects all JSP's which explicit use the old URI.

JIRA Issue List

OpenSymphony JIRA (15 issues)
T Key Summary Status
Bug CACHE-170 Data race handling Cache.updateStates results in Thread hangs when the blocking mode is used in concurrence ClosedClosed
Bug CACHE-167 removeEntry not synchronized ClosedClosed
Bug CACHE-159 CacheFilter does not set encoding properly ClosedClosed
Bug CACHE-157 Cron expressions - leap days not always matched correctly ClosedClosed
Task CACHE-131 JavaDoc: Missing class description - CacheContextListener ClosedClosed
Bug CACHE-127 ConcurrentModificationException on flushGroup ClosedClosed
Bug CACHE-116 CacheFilter sends back a 304 (not modified) response when client cache is de-activated ClosedClosed
Bug CACHE-112 Exception not thrown when not serializable object is persisted instead stack trace is persisted! ClosedClosed
Improvement CACHE-111 public access for disk persistence configuration key ClosedClosed
Improvement CACHE-110 DiskPersistenceListener should escape '?' ClosedClosed
Task CACHE-109 cache.blocking parameter missing in oscache.properties ClosedClosed
Bug CACHE-108 FindBugs reports: Usage of GetResource may be unsafe if class Config is extended ClosedClosed
Improvement CACHE-88 Don't create session object in cache tags unless necessary ClosedClosed
Improvement CACHE-61 Taglib URI Attribute ClosedClosed
Bug CACHE-38 oscache filter doesn't support correctly i18N ClosedClosed

oscache-2.4.1.orig/docs/wiki/Cron Expressions.html0000644000175000017500000001702110402251442022000 0ustar twernertwerner OSCache - Expressions

Prior to version 2.0 of OSCache, content expiry could only be specified in terms of how long a piece of content had been in the cache, ie, it was based on the age of the content. If you needed to expire it at a particular time of day or on a specific date, you had to write a custom RefreshPolicy class.

OSCache 2.0 now gives you the ability to expire content at specific dates and/or times based on a cron expression.

What is a Cron Expression?

Many of you are probably already familiar with the unix cron program. For those that aren't, cron is a daemon process that allows users to execute commands or scripts automatically at user-configurable dates and times. The important part as far as OSCache is concerned is the cron expression syntax that allows users to dictate when commands should be executed - you can now use the same syntax to expire content in OSCache! A cron expression is a simple text string that specifies particular dates and/or times that are matched against.

How Does OSCache Match Against an Expression?

OSCache uses cron expressions in a manner that might seem 'backwards' to what you might initially expect. When using a cron expression to test if a cache entry is stale, OSCache finds the date and time (prior to the current time) that most recently matches the supplied expression. This date/time is used as the expiry time - entries that were placed in the cache prior to this expiry time are considered stale and result in a NeedsRefreshException being thrown.

As an example, suppose you specify a cron expiry that matches every hour, on the hour ("0 * * * *"). If the current time is 10:42pm, then any content that was placed in the cache prior to 10:00pm would be considered stale.

What is the Difference Between the Refresh Period and a Cron Expression?

The difference between the refresh period and a cron expression is that the refresh period specifies the maximum allowable age of a cache entry, whilst a cron expression specifies specific expiry times, regardless of how old an entry is. Eg imagine caching an object at 10:29am. With a refresh period of 30 minutes that entry would expire at 10:59am. With a cron expression of "0,30 * * * *" that entry would expire at 10:30am.

The Cron Expression Syntax

A cron expression consists of the following 5 fields:

  • Minute - specifies what minute of the hour to expire content on. It is a number between 0 and 59.
  • Hour - determines what hour of the day content will expire on. It is specified using the 24-hour clock, so the values must be between 0 (midnight) and 23 (11pm).
  • DOM - the Day of the Month. This is a number from 1 to 31. It indicates what day the content should expire on. For example, to expire content on the 10th of every month, set this field to 10.
  • Month - month of the year to expire the content. This can be specified either numerically (1 through 12), or by using the actual month name (eg 'January'). Month names are case-insensitive and only the first three characters are taken into account - the rest are ignored.
  • DOW - The Day of the Week that the content should be expired on. This can be a numeric value (0-6, where 0 = Sunday, 1 = Monday, ..., 6 = Saturday), or you can use the actual day name. As is the case with month names, DOW names are case-insensitive and only the first three characters matter.

If you don't want to specify a value for a particular field (ie you want the cron expression to match all values for that field), just use a * character for the field value.

As an example, an expression that expired content at 11:45pm each day during April would look like this: "45 23 * April *".

OSCache also allows you to optionally specify lists, ranges and intervals (or even a combination of all three) within each field:

  • Lists - items in a list are delimited using the ',' character. Content expiry times will be matched against all values in the list for that field. For example, "0,15,30,45 * * * *" will expire content every quarter-hour on the quarter hour.
  • Ranges - ranges are specified using the '-' character. A range will include all values from the start to the end value (inclusive). For example, "* * * Jan-June *" will expire content every minute only during the first 6 months of the year.
  • Intervals - an interval is specified using the '/' character. The value to the left of the '/' character indicates either the starting point or the range of values that should be incremented over, while the value to the right of the '/' specifies the interval or step size. Some examples -
    "10/20 * * * *" is equivalent to "10,30,50 * * * *", 
    while "10-45/20 * * * *" would only match 10 and 30 minutes past the hour, since 50 is outside the specified range.
    Supplying '*' as the left-hand value of an interval will match the same values as if you had specified a range over all possible values.
    Eg "*/10 * * * *" matches minutes 0,10,20,30,40 and 50.
    

To have a look at further examples of both valid and invalid syntax, it is suggested you take a look at the JUnit test cases in the com.opensymphony.oscache.util.TestFastCronParser class. This class is located under the src/core/test directory. For examples of how to specify cron expiry times using the taglibs, see the Tag Reference and the cronTest.jsp file in the example web application.

Notes

  • You can specify both a cron expression and a refresh interval at the same time if you like. This is useful in cases where you always want to expire content at midnight, but you also never want it to be more than 6 hours old.
  • Specifying out of range values, such as a 13 in the month field, will cause a ParseException to be thrown.
  • If a DOM is specified that cannot exist given the allowable months, a ParseException will be thrown. For example, "* * 31 Feb *" will fail because no date will ever match the 31st February!
  • The DOM and DOW fields cannot both be specified at the same time. One must always be set to '*' otherwise a ParseException will be thrown.
  • Leap years and local daylight savings time are taken into account. Eg "0 0 29 Feb *" will match midnight on the 29th February, ie only once every 4 years.
  • Currently the time used to match the cron expression against is always based on the local time on the server. If there is demand support for specifying an alternate timezone may
oscache-2.4.1.orig/docs/wiki/OSCache 2.3.2.html0000644000175000017500000001520110615670675020505 0ustar twernertwerner OSCache - OSCache 2.3.2

Release Notes

(23rd July 2006 - by Lars Torunski)

This maintenance release of 2.3.1 has one enhancement:

  • The removeEntry method in the Cache removes the entry from its groups now

Bug fixes:

  • Method addGroupMappings leads to inconsistent memory cache if a persistent cache group exists
  • Cache group is updated if entry is removed (duplicate)

JIRA Issue List

OpenSymphony JIRA (3 issues)
T Key Summary Status
Bug CACHE-244 Cache group is not updated if entry is removed ClosedClosed
Improvement CACHE-188 removeEntry should update group mappings ClosedClosed
Bug CACHE-181 addGroupMappings leads to inconsistent Memory-Cache ClosedClosed

oscache-2.4.1.orig/docs/wiki/Roadmap.html0000644000175000017500000007766410615670431020213 0ustar twernertwerner OSCache - Roadmap

Scope

This page and the mailing list are provided for discussion purposes about the roadmap of OSCache and discussing new features and improvements. See also the JIRA - Road Map for more details or vote for issues in JIRA - Popular Issues .

OSCache 3.0

The primary goal of this release is to make OSCache more reliable and easier to use and maintain.

  • Reliability and maintainability will be achieved by replacing the core cache storage classes with simpler ones that sync on coarse-grained cache operations. The memory cache, for instance, will use a hash map for its internal storage. Existing features will be provided at a higher level, so to avoid conflicting with the storage management logic.
  • Usability will be improved through a refactored API that extends the java.util.Map interface. Some of the the things the new API will change:
    • Remove NeedsRefreshException (if you have to ask, then you shouldn't care).
    • Support for Object keys instead of only strings.
    • Support for cache regions to enable easier management of multiple caches.
    • Configuration via Spring (yes, it's a buzzword).
    • Administration and statistics.

Furthermore we discuss a Chain Caching Model internal.

OpenSymphony JIRA (22 issues)
T Key Summary Status
Task CACHE-289 Change AbstractConcurrentReadCache to use backport-util-concurrent classes OpenOpen
Task CACHE-225 Update to JGroups 2.2.9.1 OpenOpen
New Feature CACHE-220 Using a weak referenced cache for overflow capability OpenOpen
Improvement CACHE-172 Easier API usage for developers OpenOpen
Improvement CACHE-158 cache.capacity and GeneralCacheAdministrator.setCacheCapacity problem In ProgressIn Progress
Bug CACHE-152 Still NullPointerException in LRUCache (list is null) OpenOpen
Bug CACHE-151 limiting Cache size on disk OpenOpen
New Feature CACHE-149 get all values API is missing OpenOpen
Improvement CACHE-145 Allow clustered cached to send update notices when a cached object is modified OpenOpen
Improvement CACHE-142 DiskPersistenceListener - use properties in cache.path OpenOpen
Improvement CACHE-140 Option to avoid bypassing the Cache if browser has resource already OpenOpen
New Feature CACHE-123 Provide a "default content" feature instead of the "missing cached content" string OpenOpen
New Feature CACHE-121 Need some admin functions from Cache class OpenOpen
Improvement CACHE-117 add 'oscache.cluster.group_name" to take care of different clustered-applications OpenOpen
New Feature CACHE-100 Provide support for automatic failover to cached version in cache tag OpenOpen
Improvement CACHE-81 cache.contains() OpenOpen
New Feature CACHE-79 Allow the list of current groups to be obtained from a cache. OpenOpen
Improvement CACHE-78 Determining used cache algorithm OpenOpen
Improvement CACHE-67 On caching pages with session IDs in URLs ReopenedReopened
New Feature CACHE-49 Add Http1.1 Compression (GZip) and increase efficiency OpenOpen
New Feature CACHE-21 Cache manager OpenOpen
New Feature CACHE-12 Accessing caches from outside the Servlet Context OpenOpen

oscache-2.4.1.orig/docs/wiki/OSCache 1.7.3.html0000644000175000017500000000146310402251442020473 0ustar twernertwerner OSCache - OSCache 1.7.3

Release Notes

(11th November 2001 - by Francois Beauregard, fbeauregard@pyxis-tech.com)

  • TestCacheEntry had a test method with improper name (flush -> testFlush)
  • Pluggable entry refresh policy now available in the cache tag
oscache-2.4.1.orig/docs/wiki/Home.html0000644000175000017500000000620110615670144017474 0ustar twernertwerner OSCache - Home

Welcome to the OSCache wiki.

OSCache is a caching solution that includes a JSP tag library and set of classes to perform fine grained dynamic caching of JSP content, servlet responses or arbitrary objects. It provides both in memory and persistent on disk caches, and can allow your site to have graceful error tolerance (eg if an error occurs like your db goes down, you can serve the cached content so people can still surf the site almost without knowing). Take a look at the great features of OSCache.

This wiki is used for additional information as well as documentation for the latest developing version (see previous releases).

  • Download - Download Source and Binaries.
  • Versions
    • Change Log - See what's new in the latest version of OSCache.
    • Roadmap - See the expected future releases of OSCache.

OSCache's official homepage is http://www.opensymphony.com/oscache/. There you can find the documentation of the latest production release of OSCache.

oscache-2.4.1.orig/docs/wiki/CacheFilter.html0000644000175000017500000002721310615670675020774 0ustar twernertwerner OSCache - CacheFilter

OSCache comes with a servlet filter that enables you to transparently cache entire pages of your website, and even binary files. Caching of binary files is extremely useful when they are generated dynamically, e.g. PDF files or images.

A tutorial describes how to cache entire pages of your website and what performance improvements can be done with the CacheFilter.

Beginning with release 2.4 you are be able to set/override the CacheFilter initialization parameters at runtime.

Cacheable Content

Cacheable content

Note that the filter will only cache content that has a status of 200 (HttpServletResponse.SC_OK).

Configuring the filter

To configure the filter, use the oscache.properties to configure the core settings of OSCache and add something like the following to your web.xml file:

<filter>
    <filter-name>CacheFilter</filter-name>
    <filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
    <init-param>
        <param-name>time</param-name>
        <param-value>600</param-value>
    </init-param>
    <init-param>
        <param-name>scope</param-name>
        <param-value>session</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>CacheFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
</filter-mapping>

Obviously you will want to set the URL pattern to match only the content you want to cache; this example will cache all JSP pages for 10 minutes in session scope. The default duration is one hour and the default scope for the cache is application scope.

If the ICacheKeyProvider parameter isn't set, the CacheFilter will use the HTTP request URI and the QueryString to create the cache key.

You can change the CacheFilter settings using the following initialization parameters.

Parameter: time

The time parameter sets the cache time (in seconds) for the content. The default cache time is one hour.

Specifying -1 (indefinite expiry) as the cache time will ensure a content does not become stale until it is either explicitly flushed or the expires refresh policy causes the entry to expire.

Parameter: scope

The scope parameter lets you set the scope to cache content in. Valid values for the scope are application (default) and session.

Parameter: cron (NEW! Since 2.3)

A cron expression that determines when the page content will expire. This allows content to be expired at particular dates and/or times, rather than once a cache entry reaches a certain age. See Cron Expressions to read more about this attribute. Please consider that the (default) time value is still evaluated, hence the time value should be set to indefinite expiry.

Parameter: fragment (NEW! Since 2.2)

Defines if the filter handles fragments of a page. Acceptable values are auto for auto detect, no for false and yes for true. The default value is auto detect which checks the javax.servlet.include.request_uri request attribute. Fragments of a page shouldn't be gzipped or evaluate the last modified header.

Parameter: nocache (NEW! Since 2.2)

Defines which objects shouldn't be cached. Acceptable values are off (default) for caching all objects and sessionIdInURL for don't cache page if the session id is contained in the URL.

Parameter: lastModified (NEW! Since 2.2)

Defines if the last modified header will be sent in the response. Acceptable values are off for don't sending the header, even it is set in the filter chain, on for sending it if it is set in the filter chain and initial (default) the last modified information will be set based on current time.

Parameter: max-age (NEW! Since 2.3.1)

Specifies the maximum amount of time in seconds that the cache content will be considered new in the browser's cache. The browser will retrieve the content from it's own cache for the amount of time without requesting the web server again. The default max-age time is 60 seconds. Combined with the last modified header the transaction overhead and server load is reduced excellently which speed ups the server response time. Further parameters are no init for don't initializing the max-age cache control and time to set max-age based on the time parameter and creation time of the content (expiration timestamp minus current timestamp) by each request.

Parameter: expires (NEW! Since 2.2)

Defines if the expires header will be sent in the response. Acceptable values are off for don't sending the header, even it is set in the filter chain, on (default) for sending it if it is set in the filter chain and time the expires information will be intialized based on the time parameter and creation time of the content.
Value 'time'

The parameter time would force the CacheFilter to send the expires header, because the value is set always. The developer must consider that some browsers evaluate the value and will use the cached content in the browsers cache, until the content is expired. Consequently a flush of the cache in the web application won't update a page in the browser cache. Hence different users may see see a different status of page.

Parameter: ICacheKeyProvider (NEW! Since 2.2)

Specify a class which implements the interface ICacheKeyProvider. A developer can implement a class which provides cache keys based on the request, the servlect cache administrator and the cache.

Parameter: ICacheGroupsProvider (NEW! Since 2.2)

Specify a class which implements the interface ICacheGroupsProvider. A developer can implement a class which provides cache groups based on the request, the servlect cache administrator and the cache.

Parameter: EntryRefreshPolicy (New! Since 2.3)

Specify a class which implements the interface EntryRefreshPolicy. A developer can implement a class which provides a different custom cache invalidation policy for a specific cache entry. If not specified, the default policy is timed entry expiry as specified with the time parameter described above.

Parameter: disableCacheOnMethods (New! Since 2.4)

Specify HTTP method names in a comma separated list for which cacheing should be disabled. The default value is <code>null</code> for cacheing all requests without regarding the method name. See HttpServletRequest#getMethod, e.g.:

<init-param>
        <param-name>disableCacheOnMethods</param-name>
        <param-value>POST,PUT,DELETE</param-value>
    </init-param>

Parameter: oscache-properties-file (New! Since 2.4)

By specifying a OSCache properties file for a CacheFilter, the developer can run multiple caches each with different configurations tailored to the requirements of the application. In each properties file the developer has to define a unique cache.key otherwise the default properties file is used. If the parameter is not specified, the default properties file will be used. The file has to be put into the classpath, e.g. WEB-INF/classes.

oscache-2.4.1.orig/docs/wiki/OSCache 1.0 beta 0.html0000644000175000017500000000155310402251442021337 0ustar twernertwerner OSCache - OSCache 1.0 beta 0

Release Notes

(26th November, 2000 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Initial release of OSCache
  • Conceptualised a few things I've been working on over the past month.
  • Added persistent on disk caching and error tolerance (through <usecached /> tag)
oscache-2.4.1.orig/docs/wiki/OSCache 1.7.0.html0000644000175000017500000000647110402251442020474 0ustar twernertwerner OSCache - OSCache 1.7.0

Release Notes

(26th September 2001 - by Francois Beauregard, fbeauregard@pyxis-tech.com, and
Alain Bergevin, abergevin@pyxis-tech.com, of Pyxis Technologies Inc.)

This version include some refactoring, corrections and new features.
Here are the highlights:

  • CacheAdministrator has been split in 3. We have now AbstractCacheAdministrator, and ServletCacheAdministrator and GeneralCacheAdministrator extends it
  • Packages have been adjusted. We now have oscache.base, oscache.general and oscache.Servlet.
    Adjustement must be made to the oscache.tld
  • ServletCacheHashMap has been created in order to reflect specific needs for Servlets. It extends CacheHashMap
  • Support for multiple cache tag in a single page, without supplying a key. Nested cache tag are not yet supported (you need to manage keys in that case).
  • OSCache can now cache any objects (not only JSP content) using GeneralCacheAdministrator
  • GenerateKey now support suffixes (used to deal with multiple cache tags)
  • A complete JUnit test suite has been created for osCache, including a JSP and a Servlet
  • Added the required libraries for the test unit. The JUnit JAR has been upgraded to version 3.7
  • Required libraries are now HHTPUnit, Tidy, JUnit 3.7 and JUnitPerf
  • The cBuffer variable used for keyGeneration has been moved locally to GenerateKey since it was a threading issue
  • The build file has been modified to include test running
  • The flushAll method is now abstract since CacheAbstractAdministrator can't know all valid scopes
  • Removed the retry logic for disk cache read and write (not used anymore)
  • Fixed an issue with the needsRefresh method which returned an invalid value when invoked first by returning true and then invoked having to return false. Both case returned true.
  • The doStartTag method in CacheTag has been modified to prevent returning null when cache content is missing (cache file deleted)
  • The doAfterBody method in CacheTag has been modified in order to prevent hitting the cache twice in some situation
  • The useBody method in CacheTag has been renamed to setUseBody in order to reflect its usage
  • LoadProperties interface added to CacheProperties
  • Added a NeedsRefreshException
  • Retrofited the changed made by Kesav Kumar in order to retrieve the sessionId correctly
  • Added code toughness to avoid working with invalid parameters in public methods
  • Magic numbers and strings are now declared as constants
  • Many methods are now declared as final or protected
  • Imports are now more accurate, no more *
  • Comments and some headers modified to reflect JavaDoc standard
oscache-2.4.1.orig/docs/wiki/SVN and Compiling OSCache.html0000644000175000017500000000346410615666742023146 0ustar twernertwerner OSCache - and Compiling OSCache

SVN

The OSCache SVN repository is hosted at http://svn.opensymphony.com/svn/oscache. You can get the sources anonymously by using e.g. Subclipse a Subversion Eclipse Plugin.

If you want to build OSCache from SVN, you have to checkout the project OpenSymphony also.

Compiling OSCache

Run build.xml with Ant 1.6.5 (or higher) under Java 1.4 or later. From the OSCache directory, type

  • ant - to build the oscache.jar
  • ant dist - to build the complete distribution (only for full SVN checkout)
  • ant clean - to clean up

You may need to add the Ivy jar to your $ANT_HOME/lib directory if it is not there already.

oscache-2.4.1.orig/docs/wiki/navpanel.jsp0000644000175000017500000000004510214210770020226 0ustar twernertwerner<%@ include file="../navpanel.jsp" %>oscache-2.4.1.orig/docs/wiki/OSCache 1.7.1.html0000644000175000017500000000260310402251442020466 0ustar twernertwerner OSCache - OSCache 1.7.1

Release Notes

(26th September 2001 - by Francois Beauregard, fbeauregard@pyxis-tech.com, and
Alain Bergevin, abergevin@pyxis-tech.com, of Pyxis Technologies Inc.)

  • Cache Events
  • Persistence mechanism refactored
  • Cache Algorithms FIFO + LRU (Limit the size of the cache)
  • AbstractConcurrentReadCache from Doug Lea's ConcurrentReaderHashMap.
    Should give oscache performance improvement
  • Disk Persistence does not need any locking strategies. Everything is handled by AbstractConcurrentReadCache
  • Pluggable entry refresh policies
  • Unlimited cache size for disk
  • Specify Duration using Simple Date Format or ISO-8601 as suggested by Fredrik Lindgren)
    The next one that would make sense I think is being able to specify a specific time of day.
oscache-2.4.1.orig/docs/wiki/OSCache 2.3.1.html0000644000175000017500000001535110615670675020512 0ustar twernertwerner OSCache - OSCache 2.3.1

Release Notes

(19th June 2006 - by Lars Torunski)

This maintenance release of 2.3 has one enhancement:

  • CacheFilter: Default initialization of the Cache-Control max-age

Bug fixes:

  • Cache.flushAll(Date flushDate) won't throw NeedsRefreshException when flush date is not yet reached anymore
  • No NoSuchElementException at Cache.putInCache() anymore

JIRA Issue List

OpenSymphony JIRA (3 issues)
T Key Summary Status
Bug CACHE-246 java.util.NoSuchElementException during at com.opensymphony.oscache.base.Cache.putInCache() ClosedClosed
Bug CACHE-241 Cache.flushAll(Date flushDate) throws NeedsRefreshException when flush date is not yet reached ClosedClosed
Improvement CACHE-240 Default initialization of the Cache-Control max-age ClosedClosed

oscache-2.4.1.orig/docs/wiki/OSCache 2.0.1.html0000644000175000017500000000340710402251442020463 0ustar twernertwerner OSCache - OSCache 2.0.1

Release Notes

(4th November 2003 - by Chris Miller)

Improvements:

  • CACHE-56 Refresh period is no longer mandatory.
  • CACHE-51 Added an <cache:addgroup /> tag. This allows cache groups to be dynamically added from within a <cache:cache /> tag.
  • Website documentation is now bundled with the OSCache distribution.

Bug Fixes:

  • CACHE-59 Silent mode could not be reset.
  • CACHE-60 Fixed deadlock problem when cancelUpdate() was called while under load.

Changes that may affect backwards compatibility:

  • StringUtil.split() now returns a List rather than a String[].
oscache-2.4.1.orig/docs/wiki/OSCache 1.0 beta 1.html0000644000175000017500000000162610402251442021341 0ustar twernertwerner OSCache - OSCache 1.0 beta 1

Release Notes

(20th February, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Fixed a few bugs.
  • Greatest of which there is no longer a disk leakage from session caches on disk.
  • Also session caching bugs fixed, usecached bugs fixed - lots of work done here.
  • Implemented to flush individual keys.
oscache-2.4.1.orig/docs/wiki/Chain Caching Model_attachments/0000755000175000017500000000000011375310612023665 5ustar twernertwerneroscache-2.4.1.orig/docs/wiki/Chain Caching Model_attachments/CacheChainModel_v3.jpg0000644000175000017500000022757610445266451027761 0ustar twernertwernerÿØÿàJFIF``ÿÛC   %# , #&')*)-0-(0%()(ÿÛC   (((((((((((((((((((((((((((((((((((((((((((((((((((ÿÀq"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?ú¦Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Šó¯išö½à½W¼ñLjçPÓíîåX­ôðŠòF¬BƒjN2N2MmÿÂ/«ÿÐ÷âOûñ§ò-uTW+ÿ¾¯ÿC߉?ïÆÿÈ´Â/«ÿÐ÷âOûñ§ò-uTW+ÿ¾¯ÿC߉?ïÆÿÈ´Â/«ÿÐ÷âOûñ§ò-uTW+ÿ¾¯ÿC߉?ïÆÿÈ´Â/«ÿÐ÷âOûñ§ò-uTW+ÿ¾¯ÿC߉?ïÆÿȵŸwm¬h>$𪷊µ}JÛPÔ$´žÞò0Œ‚ÎâPAŠ`CDŸÅë@ÕQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@W!©_xŽóÆ—ÚF‡}¤XÛYéö·lך|—O#Í% ÏP±ûÆ€:ú+•ûŽ?èaðßþgÿäÊ>Ããú|7ÿ‚ÿù2€:ª+•ûŽ?èaðßþgÿäÊ>Ããú|7ÿ‚ÿù2€:ª+•ûŽ?èaðßþgÿäÊ>Ããú|7ÿ‚ÿù2€:ª+•ûŽ?èaðßþgÿäÊ>Ããú|7ÿ‚ÿù2€:ª+•ûŽ?èaðßþgÿäÊ>Ããú|7ÿ‚ÿù2€:ª+•ûŽ?èaðßþgÿäʵà]RûWðù¸ÕZÙ¯b½¼³‘í¢h£"êXCfb¹ƒÇ’y ‚Š( Wá?ü’ÏÿØËÿD%uUÊü'ÿ’YàßûÙè„®cꇋ›þè"Q…M¼:jØÛJ!>V$UÜýî;ÆÞ6©”Ôj»¶{Ç´[ˆZê4€øWÿ¡7Ãø+ƒÿ‰£þÇÿèMðßþ àÿâkª¢€9_øWÿ¡7Ãø+ƒÿ‰£þÇÿèMðßþ àÿâkª¬Áâ ¬þÖº¶žm2Î)³%C»8ÉV ô ô4‘ÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üMX—Æš~'ŸA:…·Û­­…ÕÎgVÝ€»òÀäîÀe'—:‘ëd“à z›M: "EKH¤1 £<‚#rìèhþÇÿèMðßþ àÿâhÿ…qàú|7ÿ‚¸?øš×ohËl× «éÂÝX¡”ܦÐÁK‘œã!Alzz yÖô¡¬ÇS±Ý€mäûBm˜`¡ÏÍœŽž´‹ÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üMtº•ÜóAkym<Ðñ,qʬÑõ0އ¯¥Z WþÇÿèMðßþ àÿâhÿ…qàú|7ÿ‚¸?øšê¨ Âz&• üIñ%®‡¦Xé¶Ï¤é²4Vvé 3™¯bœ3ì+º®WMÿ’§âûéŸú>þºª(¢Š(¢Š+ŠÔ#ÕuêZm·ˆµ-&ÊÏL³¸X좵mòK-Ò±c42¦ uõ®Ö¹]7þJŸˆì ¦èûú?áÕÿè{ñ'ýøÓ¿ùøEõúüIÿ~4ïþE®ªŠåáÕÿè{ñ'ýøÓ¿ùøEõúüIÿ~4ïþE®’òîÚÊ-åÄ6ñT+„˜à žä©¨•ÿ„_Wÿ¡ïÄŸ÷ãNÿäZ?áÕÿè{ñ'ýøÓ¿ùºª(•ÿ„_Wÿ¡ïÄŸ÷ãNÿäZ?áÕÿè{ñ'ýøÓ¿ùºª(•ÿ„_Wÿ¡ïÄŸ÷ãNÿäZµð÷PºÕüá­KP—ν¼Ó-®'“h]òQy•7÷²9àžwBñOˆµ9&M?V{Û™téï’ŽÑÍ –çÈØ¨ E„ŒŒŽÒ:ä|À€XØè¯×|s­-µæ«k­=´ZKªi¶­“À<ÁË£< ¬BFU(È%¸mÍðý¦žÚü×6søbãWOÜùÖ¶–AutC©È Ip%-°&Xƒ1·<ä€}Ey3ø³Å)­ê¾sXÃmm& «h›î.¼¨QÌ2-ºÂ¼¶ØÛ-6Ö´aˆ¦‰ânû^Ó´ˆ|B×6÷—0¯Ûcû4Ìíµ`¬‘,dµ)ÁÈ,ܨöJ+Ë!ñαgo¦ÄM¶§p×·–REåí¸”Ay$ ÿ)EO@7psGêtW+ðÓþEËÏû jßúq¸®ª¹_†Ÿò.^ØkVÿÓÅuTQEr¿ ÿä–x7þÀ¶_ú!+ª®Wá?ü’ÏÿØËÿD%uTQEPÕµ?H{Ô®’Üß\­¶üþòf U¹ Ý}(ýBÓXÓï5}CKµºŽ[ý=bk¨W9ˆH Löä)?þ±W袊(®WÆ_ò1øþÃRéºòºªå|eÿ#?ì5'þ›¯(ª¢Š(¢Š(¢Š(¢Š(®WRÿ’§áïûêú>ºªåu/ù*~ÿ°.§ÿ£ì(ª¢Š(Ôü-{qãË]sͶº³gî.‹“ƒ‚wŒÿsŸÝ´x²|<» ø:ÖY–K½J6E¡sg®ÑĬâHv¹¢<‚äŠôÊ(Ìu?†÷7Ö2E#›MñmΗsª}´^ÚÅc%ÊIƒj`²iaÊßëø]¤6à ’Õé”PŠkº‰ot"h®u;íVÏW»–Æ_*âÎ8ÿâ_9ˆ²4ÎÅ>ШJyÞS G²ñ,ºž—o¨ë:|÷è·;K›!}Šì¾]ç’Lò9T ·nXñë”PŒx‚?'ü$³Ç}¨Ö-PÛZZióÇåIölMçlÝŸ$.?3vAã-[Ú•®³§ø²[KYu¹|:Íeqw –YdùÅà”Dü°Òв'ÝV$»ŸI¢€<‹M‡ÅoâhÜjÔRßÁöHnì$–i-xó<ÉË‚|ÁûÄiì<¿«Ó/¼@þ<ºµ)s6„»ÿysn" Àû´oÃåGªäñµZ^ÊŠ+•øOÿ$³Á¿ö²ÿÑ ]Ur¿ ÿä–x7þÀ¶_ú!(ª¢Š(¢Š(•ðoüŒ~;ÿ°Ôún³ªþ5¾ñ®³¦G¦%Êio´Oin.$0Ý•*q…äzå%BIcÁ¿ò1øïþÃQÿéºÎºªóRçWÔ|Mswm¤j0\ézF«j»ß6I%·6æ]v3:Â[£'  zÒßS»µ:ôÖÖ g 3‹²×$<ës¬äÈÄÆ Àݰ… Þ»ExÔ¾'²Ö,Å̺ô·ñÝÙ4Œ%¹–Ý£–XÆÝ¿¹©’UÚáBdm@¥Sá}†£ö/$“x†å´ÛtŽî×VÓ¬Zyl‡Êclì¬c-'ÊXç<׳Q@/¦ÇãXô›©5{ÝVâ鬑nà´²š.SÑõ4º³òR)š fö‚ûØìÿ' ·•ÑüXÿ’Yã/ûÞÿ臮ª¹_‹òK‹©Yj0#ùo%¤é2«t•$Èâ€/ÑEQQ\\ÁlЭÄñDÓ?•w ½ðNÕÏS€N¡¢;˜$¹–Þ9âkˆB´‘+‚È;I@88õÁ  h¢Š(¢Š+•øiÿ"åçý†µoý8ÜWU\¯ÃOù/?ì5«éÆâ€:ª(¢€9_„ÿòK<ÿ`[/ý•ÕWü.Ôv|3ðŠlé1íÒ-ÇO™rœÞ]?ö§ýGtoûãÿ¶Ò¸µÉøÿB»×΃¦V(¯e{‰CaF²¹\y"I#àd瞀‘ûSþ£º7ýñÿÛhþÔÿ¨îÿ|öÚ. žñÚx‚k½=&¸Õ,¬^X<õ ÉöË©g„|À1H¥âð%wVF›áë;Äöö7~ÚÍm¨Kk¦n‚%Ó@Cå¦%JŒ`å†âoQþÔÿ¨îÿ|öÚ?µ?ê;£ßý¶‹oÃ6—vÒ¬õ;µ_ÛÚEÄùÿ["  ߉þ5¥X_ÚŸõÑ¿ïþÛGö§ýGtoûãÿ¶Ñp7k•ñ—üŒ~ÿ°ÔŸún¼«¿ÚŸõÑ¿ïþÛX ¼ûGм ŸÚZ}Ö5yNËuÃø—Þs÷Ûý¼¢Š)€QEQEQEW+©ÉSð÷ýu?ýa]Urº—ü•?ØSÿÑöÕV§®\G¬K¥é6ööU»˜<þJ¢32Æ3ƒ–c˜ã)ÉVíajº-Ôº¿öž…ܰ-­ÃIoç #R̘— ¥ß‘óœ©ãê/Òtµ·£ÜÚË%ºÜɶ’O³FsóLQYbPC Î@ùO<¯âOišF›«M‹»Ë{™ÜnEšHbi.Ò»°§ dŽN85CÆŸÄ)$Ûb—N6-ö›9‘°ãÎBB¹Þ7„\l#4ýWÁWWz·¢ZëFÛLÔ–ÿ1ý•]Õî„…²Å¹UyYÀOA» ˆü[£HÓªÝH%†EˆÄöò¬Ž[qBˆWs«rAk`œgÜxÎ /c·ÒÒÖa%¸ž9nî~Ì’î†$Ê’dR„26åsÖ«x¯áý—‰5×Ô¯ÚÚuÙh#µº´YáݺåÕŽ2ݰÇJ‚zYµðŒ¶Z$ZU¥Îš,V"†Õô¨¾Î¬]زF…Bçy%†¥‹C¦üBÓ®XKûMJÂm6ò;…ìæ’IehV]±ª!óeÆwÊ¡ó±Ô˜bø“¥]k7Z}ŠLÂdMÄöóÅ5ÅÑ·1îòŽXc«nRWˤKðú[k í,µ—1Iqos‹¸Zo1¢´Kb³aÔȬ±ÆýT‡\äŽ*+?†ÆÔÈ#ÕIgµ™ÁµÇü{êR^ \>|׌ñº@Ú@-ø£âv :Äæúêá¯âÓÂÁcpèÒ4ŠŽ©"ÆUÝbQIbWn7+béÂÈOu2)k›«tŽÝ%™›È•ãr n6|ØRà3 1ç5Ÿ‡—ºŽµ-êk±[Änâ¾DŽË $‘Ì’¢ÌDdE1¨E|—<çRÏÁÓX<6šÇÚ“¤²[ïO.òçí …7U„`6yÚxç{Jñžƒ«jÙé×Í;ÊHŠU‚AÌqXæ+å» *¬HÁÈà×C\n‰àûý;ÄÃTŸ\ጊ¶‚nX®?|ÈÂ6¨ÄjÜ ±ç=•rºoü•?ÿØLÿÑ÷õÕW+¦ÿÉSñýtÏý]UQEQEÊé¿òTüCÿ`]3ÿGß×U\®›ÿ%OÄ?öÓ?ô}ýuTQEfjÚî¤È±ßNË#FÒùqÄò°EÆç*€£#$ñZóGqsA"É ŠC)ãÍjVÚ†â¹õ‹ :MIo,¢²hÒTŒÀÑ<®¬w‘ò·œC’6.öä¾#ø[VÖ\µ¦‹óǤùVrÀÑkt‡å2°1Œ˜ö¼`1ä3( @¥êÚ…®‘¥^êZ„¾M•œ/q<›Kl³IÀ€3V«Ëæëû"úÊs>•z/¨`¦pb’&P[p– nQ’:€ =/R´Õ y¬e2*HÑ8dddqÕYX§§wr¸OéÚ–½áø–_Å"½ð–{ñI#B#e•˜Bï»fU™”(È%•k Hðž«kjñêš/ö”>L°YÚý±bmöÉÝX:Ÿ4O1¹X >èôí3PµÔíž{|Ø’i­Ù¶•Ä‘HÑÈ9££ ô8ÈÈæªx‡_Óü? ¬š“\ÿ¥Möx#¶´–æI$ØÏ€‘+1ùQÎq€מ_x+X}:9t¸Ç^›SÖ·êê;YÅñ·%ÉMò[>Á’€A#.oj¶§O˜éþ$¿¶‹Q†y­áÔm-glî£/ƒìê¿<ÑÅ÷¸€±iwðêv^[%ÊE&v­Í´–ò 9ŽEV^ÀÈÁKi}mw=ä6ò‰%³”A:€væ4)ÿ€H‡ñ®"/ &­¨øûKD¼þƇN¿†{]féo%I^{fŒHÆY7äG#™‚€¿t€)àŸ‡º…Ò†³¡Ûy“êך¤¬ao9±Þ „¹ûQrz‚f-“— Úë•ø±ÿ$³Æ_ö½ÿÑY:.˜Ïñ'R‰$¦i’5üh½#º¹@ÞU¹—Bµ¾,É,ñ—ýoôCÐUEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\®›ÿ%OÄ?öÓ?ô}ýuUÇ[µÒüS×þË 2Ä—MÝæJS¿¾Æ0§4¡ãý>çSðµÅµ”&áüëyd· ¸…'凞øÕÓîÁàšâu‹kQ‹Æ§‡ôù ¶ðZ?ö]Å•÷ÚV<Åî|˃¼†® (Rß5zO›©ÿÏ—þ7ÿ£ÍÔÿçÎËÿ›ÿÒ¸Úë~'–ÎÙµÉ':¬–Oûé-M‘òÍÏšç(&ç Ç#÷AÍÝê^"‹Dð„s6½oqceke©Ë(–?:ìßi¨À;`HÄyà9%X;`_ÁæêóçeÿMÿÆê+˜ï.£ÝiºtчIÉpÌ£VÁ‹¨eÄÚ‹ç:¶“«k0iÇ óZ¦¿,Út·Ñ»ËmÓfòå¿Ì \“´·8(:‘Uímu”jÇMÔ­îµk>áŒÑΡ®î²…”/¹ˆ2§Ï…Á*kÔüÝOþ|ì¿ð)¿øÝn§ÿ>v_øßün‹æ^ÓõG_];Q—Ä1hb;Æ{¸š{D ŽÞgÞ{’71np ¡¥Ïâ«™4ËøüA©·J3£-Àˆ£‹qrJ(® Ì]ZE*Äm\õÏ7SÿŸ;/ü oþ7G›©ÿÏ—þ7ÿ¢àxíÅß‹ –62êñk­£É.¢n7Éœ]Y‰Z÷®à#3íÛ´`€¬¶:? Yëïâ]>-ZûU¹Ó•/æó>Ï=œ{–K/)Hi]ÈÏžG˜Ùa¼cg^ÎÊÂK $’ÇFÒ-¤í » c¦H‹žµsÍÔÿçÎËÿ›ÿÑp/W+ðÓþEËÏû jßúq¸­Ï7SÿŸ;/ü oþ7X?  Ý«ÿljÛ‚œ€´.: þTÀë(¢Šó†^>ðuŸÃo ÚÞx³Ãð\Á¤ÚG,RêP«Æë ¬ dAéácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øªÄÕüYáÍ{žµÐõý#R¹MZY+;ØæuA§ÞÄ+Œ3î+Ñh Š( Š( Š( Š( ¸¯&ÿ‰žMÌßñ(Ô¾[y|¶¾±ç;—l×k\‡Š¥gãMW°Ñ/µkh4ûÛIVÎXãydµd$M$`‚!~„öõ  /#þ¡úÏþÿöê<ú‡ë?øÿÛª—ü%¿ýž$ÿ¿úwÿ%Qÿ F¯ÿB'‰?ïþÿÉT¬ß#þ¡úÏþÿöê<ú‡ë?øÿÛª—ü%¿ýž$ÿ¿úwÿ%Qÿ F¯ÿB'‰?ïþÿÉTX ¾GýCõŸüÿíÔyõÖð?ÿ·U/øJ5úŸeiÞK<—LädÉÔŽþ•×Ó¢Š(¢Š(®®¾ÍñO]ÿN²´Ý¢é¿ñò¹ÝûûîŸ:ôüzŠîk€»ñ‡áÿŠzßöö³¦éž~‹§y_mºH|ͳßnÛ¸Œã#8é‘@ö§ýGtoûãÿ¶Ñý©ÿQÝþøÿíµKþ?ÿèrðßþ ÿâ¨ÿ…àú¼7ÿƒH?øªVïö§ýGtoûãÿ¶Ñý©ÿQÝþøÿíµKþ?ÿèrðßþ ÿâ¨ÿ…àú¼7ÿƒH?øª,ßíOúŽèß÷Çÿm£ûSþ£º7ýñÿÛj—ü,ÿÐåá¿üAÿÅQÿ Àÿô9xoÿñTX ¿ÚŸõÑ¿ïþÛGö§ýGtoûãÿ¶Õ/øXþÿ¡ËÃø4ƒÿŠ£þ?ÿèrðßþ ÿ⨰µ?ê;£ßý¶©|'ÿ’YàßûÙè„£þ?ÿèrðßþ ÿâ¨øOÿ$³Á¿ö²ÿÑ Bª¢Š)€QEÁø~óìþ*ñÊiiö¹Õâ;.,â_gÏß^?Õ¿ý©ÿQÝþøÿíµËé,ðæƒâßZëšþ‘¦Ü¾­‹åìp»!ÓìÀ`ÆAö5·ÿ Àÿô9xoÿñT¬ßíOúŽèß÷Çÿm£ûSþ£º7ýñÿÛj—ü,ÿÐåá¿üAÿÅQÿ Àÿô9xoÿñTX ¿ÚŸõÑ¿ïþÛGö§ýGtoûãÿ¶Õ/øXþÿ¡ËÃø4ƒÿŠ£þ?ÿèrðßþ ÿ⨰µ?ê;£ßý¶íOúŽèß÷Çÿmª_ð±üÿC—†ÿðiÿGü,ÿÐåá¿üAÿÅQ`.ÿjÔwFÿ¾?ûmsuÿ ü\ŸÛ:L›´‹±±æoÜ¿÷‡ŸÀÖ×ü,ÿÐåá¿üAÿÅW5ñ7ÇÞ¼ømâË[?x~{™ô›¸âŠ-Jy¡p@l’IE€ôú(¢˜Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@qÖöv·õÿµ[C>ÝMÛæ lf{ìã?Jìk[ðŸ‡5뤺×4 #R¹D¬·–QÌꀒRq’N=Í\þÇÓ?èeÿ~ü(þÇÓ?èeÿ~ü+þÇÿèMðßþ àÿâhÿ…qàú|7ÿ‚¸?øšV@ncéŸô²ÿ¿ þcéŸô²ÿ¿ þ‡ÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üM@ncéŸô²ÿ¿ þcéŸô²ÿ¿ þ‡ÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üM@ncéŸô²ÿ¿ þcéŸô²ÿ¿ þ‡ÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üM@ncéŸô²ÿ¿ þcéŸô²ÿ¿ þåþx:ïÅ^’ ÆÂ1«¦€%¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(•ñ—üŒ~ÿ°ÔŸún¼®ª¹_ÈÇàOû Iÿ¦ëÊâ¿á6ñWü/Ÿì¯øGu¿øC¼Ÿ±}¯û>_'ÏûÞ~ý¸ÛŸ“9Æ>n”ëôV¹ªÞïiºN˜¶Â{«{‹¶’à1P´JTGÌÆeç°àô®OOñþ£6‡.¯46Ÿe³ð½§ˆnbHØ<­,w,cC¿ 3 ã!»ŽsétW þ*Õlüg¦xzú;%¸ž,Уªˆ¤¶½Ì$³êx*ÝéŸâ½kTÔlìl×NŠk†Ö~ycr¡lï’Þ>Ž9eo›Üä` ¤¿¢¼vïÇ×0kvúú›¯ìÛŸ Ú]8Ѥ³Gy:¶1çìÂ<÷Ü3ŠÚðö­ªX|=·2ë郞©{e%ö¨;7—u:|±Ç´ÈØŒ ¨ ÏË‚éW“¯Äv]+^½Š-0.ƒ§½ýÊ´2fç˸½‰Õ>pcÜ-27([7mÿx§PÒüFÃq¥Éf.í-ÐC+ωäŽ=í.à‘d!V,ä€;š+Íußßé6_ÚïmjúWÛu_ +yø³†éÉÝ»3Zœ|¼:“•Ÿþ}HØÞ¼VR–ŠïN·†âïKº±ŽO´Ý,,¡&‹ 9Ü :ñÔP¡ÑQÛ –Ú%¹xäœ çP^Ø®êÿT³Óô§Ô®æòì‘…ö’H8Æ ’rd’ªóxwGŸÄ1ë³éÖÒëÂ-㻑i!H'I•X€HRc<κñΛ ÖšQ'žÂöÒæàO É"42CÉT/»2¶x|¶Èë‹ZŒô=mšâø´SÀ·K,I4i }Ù]ÑJƇ ăϣµÒµY¼K¢ë£X‰-tûÛiã·/€óMnèpù‚¬, ¹8!@8^NïÀ¾"“ÀV>MBÔ¤^‹JhÄïK:ÂÈò!2£|€IÃd­uƒÆz\Váîåo1弎8í žáœ[Na€±îÈ;r s‚Ê75è6ØÏ|^;ˆée‚ &!o»,ŽŠV488g x5—á¿ _išýõĶÍÛ[‚3?l¿Žâ,dˆ„7¡Æ29¬uðf¿iᯠéúyÒ£Ô4ý&ÛOmEnfŠ[i#PÐ"tÈÈÂwÉùˆ›EPEPEPEPEP+ã/ùü ÿa©?ôÝyR醣'޵Ý6öhÞÚ K˜#0Ì–éNORH…3Î=äœÿjV6^)ø} åíµ¼³kRyi,ªŒÿè7Iò‚yùäxîê:‘]‚Û@·R],1 ™cyB ìŠXª“Ô€]È·S@ÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQ\ÿˆ|HÚF«a¦ÛhÚ–­{y × “@»#‰¢V,f–1ÖdÀž¾•Wþ_þ„Oßý;ÿ’¨ª¢¹_øJ5úöÖǮӎ•‰}ã¸mo5dMW¹°Ò¤Xîõ ¹… †9²Ê$l$©÷Päœ Ðßð®<ÿBo†ÿðWÿGü+ÿЛá¿üÁÿÄ×A.£eìvrÞ[%Üœ¤ *‡~½9=åTàñ.…<—Iµ¦Jö®±\*]FÆf ªà”– z“ŠËÿ…qàú|7ÿ‚¸?øš?á\xþ„ß ÿà®þ&º 7Q²Õ,ÖïL¼¶¼µrBÍo*È„ƒƒ†RGb­P+ÿ ãÀÿô&øoÿpñ5Â5–·áŒÓX|8ð¯‡×D¹Òm$ղؤN$¼ò˜Á9b$Fÿt´r=–¹]7þJŸˆì ¦èûú>Ýãú¼7ÿƒéÿù·xãþ…ï ÿàúþC«rk‘øêÓF{x’ÊâÆæé%Égv‰í—è£÷äc’HÏç~€9_·xãþ…ï ÿàúþC£íÞ8ÿ¡{Ãø>Ÿÿ몢€9_·xãþ…ï ÿàúþC£íÞ8ÿ¡{Ãø>Ÿÿ몢€9_·xãþ…ï ÿàúþC®+ÂvÞ$ñWüWoñ /ì0Úÿg[húÕÌ0´-Г«½›`eS„*ô®ûFñeŽ­«¶Ÿ7QËþ•弨¡%û4þDÛH$ü®W¨ 1ß´ßù*~!ÿ°.™ÿ£ïèÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(…Ô¾xOTº²ºÔàÕï.l_̵–ã\¾‘íß îŒ™‰S•S‘ŽƒÒ´?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~º[»„µµšâQ+G 4Œ"¤rÉÚŠ 1ôzRÐ+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£Ôøýt:eõ¶§¦Ú_ØJ&³º‰'†UF•†}A“UÔmt« //åò­ãÀ-´±%ˆUP$±$$’äÐ?ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£Ôøýu(ÁÑXdÈò)h•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~ºª(•ÿ„HÿŸÏáG¨ÿñúÄño†ít CL¿ñ\¦­¦ÇûÝvödd’öÝYR¬ ³=kÑk•ø—ÿ"åŸý†´Ÿý8ÛÐUEPEPEPEPEPEPEPEPEPEPEÀiÚ ñOŒdÔ¯µ¿ô]N+x#¶Öní£Ž?°Ú¾E*¨ùÎq’XÐEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEq^±]#Çþ Óm®õ)¬—LÓî;ÝB{½’<·ŠÅLÎÅr#L€qòŠé5½sKЭÖ}cP¶²ŽÍ RçÑGV>Ã&€4h®{Ã~,³ñ«¨XÚZj05¤0\o¼¶h©+JªÈ­‡Æa¼£¶3] QEQErº—ü•?ØSÿÑö»®jpèº&¡ª]¬oco%Ì«îr¨¥ˆQÜàp+ Rÿ’§áïûêú>´ê©ˆåW9ôÛ-[M¿b¶:…ɬÄC2¿îÛ;_ƒ÷NN 6=gK’ÕîcÔ¬žÝ$XšUJ+±TœàY@ɵÇ÷²¥Ì2][À—6ší«Ëo1~Ýv’ÂÑ©žÈ楓ÂZ΢·wé¥YÜÏ>’>Íi+¼;¡36J)ÞêYBíÀ ƒv9yñýšš€ÕlZÅ÷ì'VGجϴƒ‚B£’@§ÐÔZWˆ"¿c{+ë=öÿjG È'iVÁW)?„Zñ_Š »K„ѧ´x—*PîbXç1äsˆãO˜dnšAÔÝ–ÇÄZ–©Xêré0´ÖRZÆÑÆÓ¬’2%tp_X¾aÉiYxD¾²–òÇYÓnm!m’O ÒÕWMñv‹¨jwßÛ­ÌwÞ%y}¨ùͺ».¡e\‘ÜÜžNÇÁ:ÊëPê×eç[µ¬‰l×rN®b[´*Ò4`ã*ÊBà2—Í5—‚u$Óõ…tˆ.¯¼Ce«¢Ú+$qÅ Ú³§+çÉ—žŒ_'nâW«ø›KÓ4}gQ71Ý&“m%ÕÔ6Ò+ʪŠÌFÜŒ”’9«z¶«k¥}•¯dŽ(§‘Ë$±Æ±…‰å,w°È }ܑԡ˜y¥ŸÂë«? êúdE%ÔÚ ÎÕΡw>ö•p£±HW*¥‚)ç¦ÁÑñLJ|Wã= ìwVš&™Ö,$³.­..¤‚YgŽO³…Š8H‘SqÄqeãùC<„îA¬]7áUôVW¶wšO†eº¸¶¶ŠsÌ-ydÑÙ[Û“ùî¼NêD‹÷‡‘^ÓEp‡€ÞçÆ—Ã?Åõ­î$¿ºa0¢(Qn#æ0Á›¡cÀX‘ü<×dm$]M¦”²Äáf}’"^ÙÎÅcòÂÄ-äZð Q–+ëTPœx‹ÀÚŽ£q¬µ¿öpº ¾ŠYÃÇÙ-á)…_âx™Ž@¤ä2z ”/og2Ï%đƨÓHi,pÉëÀÅMEÊé¿òTüCÿ`]3ÿGß×U\®›ÿ%OÄ?öÓ?ô}ýtiö²ê¶ú“Å›Ûxe·ŠMÇåŽFœc891GÉxêsjŠ(¢Š(¢Š(*ÇÃÚ]…äWV–¾]Ä_jØÞc}¦eš~ ÇÍ"«{cŠÊÓ䩸‡þÀºgþ¿®ª¹]7þJŸˆì ¦èûúꨢŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šòßh*ÔÓÆÌ·7¶×Úe彂Et±Â$xYc aêT“Æã¸ä0ò§×¼6§w¯ÝO¥[ÜÜO¯XËlòùlMK(îG'…dK•e<ºŒ`‚¹ôº(Ä-¾kQøA±Xﬣ³Ñ­ì~˧ËgÇxŽæYËÉ…w–Wó#ùø98ÿ£á mu Êîú_ çYÒ) [ U¥É'Œ}šI>^¸w\eˆ>ŸEx®à­~& ’¶IlVüG,H·Ž·6²2oV28xÒáII|1Ý·?4úçõ]GW½¸²³Ô´­:XÕ-lì¯-G•0rZf2G ƒvSýG#ËÉÉlc¢€8Ý2ÇÄ ãË«¢÷0èM¿÷wPü¸»ŽÌ¾Xz.G;‚ÅÙQEQEQEQEQEQEQEQEQEÊüKÿ‘rÏþÃZOþœm몮Wâ_ü‹–öÒôão@UQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@r¾ ÿ‘ÇöÿMÖuÕW+àßùüwÿa¨ÿôÝg@UQ@Q@Q@Q@Q@Q@Emp—1—ŒJ;lj#hÎUŠžŒƒƒÐŒH ×%ã[\ë:dº[ÜÉ¥¦>Ñ­À·üÀ¶X°ÎWé†6•àÉ®u[(üA¥Áq¥«kÏ,s”‘ ¸ÔcšÜ•ÉÎc Ý>Rpq@…i}mw=ä6ò‰%³”A:€væ4)ÿ€H‡ñ«5á¾øy®Zø{ÊšÒK û›Ë ÝFkCjÓ]ªéé±±2; ‘$§x*Û‰s:¯x.KmBäköîÈép[Cý ðÜ6ã5é’2UF"ž5ÀP¡X ,$¼Ò5;M^Å/4éLÖ²²]Œªàä Ê{0àŽA"®W…ø_áþ­¥Zøu‡ µ¼±],›ˆ » ä}©KîÞ°œ²Ç„pKÌÌNçÁZÔúv…l,®m¯, [Q¶º…¤Ô°G(hß.D¹•A\m^¹ÃEy|~ñ=–áûMMJ-÷™åº¾ŽDPÒ–EtŒ"¶Õ'*ŠÜ ÏGêQEQEQEQEQEQEå-³ñ5ßÄýSþ›µŠÙ4}?í°G*Ã<ËçÞíÊÈáHù³À'# ¸­^øGB¿S¨é×·/ÈnuÀZiO »fe÷VCô»¦ÿÉSñýtÏý]5Ä\ÀðÜD’Âãk¤ŠXzzÐu·qñKZoêZe˜þÅÓŒ¦òÁî·æ{í»vMÞùÎs‘ÓöÑj«£®¯ldÕ¶81Ú:@çaòŒ¥°8Èó9ÁåsÅOøSDðíååΉ§Çd÷iJ±#Ú…Ê…Lí@ Žp u­ºçô»OEêºÎ‰sd3æEm¤ËÁÆ®\p~éÈqœ‰µ»oÍt¡êºE°@;Í2K—/“’n#cm=<àmQ@öÑj«£®¯ldÕ¶81Ú:@çaòŒ¥°8Èó9ÁåsÆ~—i⨯â}WYÑ.l†|È­´™`‘¸8õËÎÝ9Ž3‘ÐQ@0|Ñ>!è?ø“y®;HºûKx5âko0 ›)“œJú Ïÿ¨†³ÿ€ý¦±üU|ºGü?©\ÚjSY.™¨[´–Z|÷{$ylÙCQŠäFø$cå5oþÍ#þ|üIÿ„æ£ÿÆ)X ¾ýD5Ÿüÿí4yÿõÖðÿ´Õ/øO4ùóñ'þšÿ£þÍ#þ|üIÿ„æ£ÿÆ(°|ÿúˆk?øÿÚhóÿê!¬ÿàÿiª_ðžióçâOü'5þ1Gü'šGüùø“ÿ ÍGÿŒQ`.ùÿõÖðÿ´ÑçÿÔCYÿÀþÓT¿á<Ò?çÏÄŸøNj?übøO4ùóñ'þšÿ¢À]óÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦©Ây¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1E€»çÿÔCYÿÀþÓGŸÿQ gÿ?ûMRÿ„óHÿŸ?á9¨ÿñŠ?á<Ò?çÏÄŸøNj?üb‹wÏÿ¨†³ÿ€ý¦?þ¢Ïþöš¥ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅ?…‡>œîvίªüλXÿÄÂã’00}°+®®Wá“þi$–ÞæßÏÔõ+„Žæ†O.KéÝ G—*Êp@8"ºª`QEQEÊø7þF?ÿØj?ý7Y×U\¯ƒäcñßý†£ÿÓuoêú…¾“¤ÞêWÎRÒ虀ÎÔE,Çò³lõ«´Y&ÖôÁ¦Y­©»7 pb ÷–NÖçÃóÅjj–6ú¦™w§ßF%´º…à™ñ#)Vˆ&±cÐõitëËMCÄIæÚ½¤2Û@ x÷ IËn”qó «þÈÍ:ׯZ%ÌR:\Ï#ÆžLösC3ݳlNØ6ÇÁƒµ±ÐÕñGMJâ)]×OŽÖ ‘x±Èê7Ëf|[n9£§|>–ÓRRþÒ¶[èZ !ò,Œp«Æ·(IC# —LÍFsŒµ¨x*çQ²ñ4wÚÉšç[Ñ—Iy¨_+èï d´à/\F2Ä’hïˆ|i¥én«p’}¢âÆÞæQ ‹3Ã;IJ³p r2HÁÈàÔ+ãHŸVðÖŸŒ¦]XȳfEbeŽFÚãø˜´2'eçœ-Oá>›t5ϳ:ÚmM/ówý—Ý+Ý#«fcóS+£iÆvу¶¾ …gÙ’qÝ­ÀiXÈwH~ÌT¶ýæBŒÚZ¥º×/uõDÝÞ›©-¦¶ó#Á·¶‡¦ñ—f%\ä#§­lŸh[àT¿YDæÅÈ„ÎTD7(* oR=zsKÿ v‡ök»ƒ|¶¯zòŸ }ùã÷Š=S=G¨®#þ]OO‡LÒtÙî$±[Í.êògH•%{An ]œ[dùçp67fÕÂ}7Oðþ­¥iÇN³[Ý"m%.`ÒâIöȸß,ƒæ•†Œ¨8$äà€D³¹ŽòÜM™å’Àoœ3†ãŽB0FA¹½7þJŸˆì ¦èûúê«•Ó䩸‡þÀºgþ¿ ªŠ( Š( Š( ¹]7þJŸˆì ¦èûúê«•Ó䩸‡þÀºgþ¿ ªŠ( Š( Š( Š( Š( Š( Š( Š( Š(  /Äöº”ö¢ÚÚ÷ì·eŵãF<™¶äðAÈA`Á-rÓKy”Ouž)7(FTä³|ÄB1íȵB]cNí€ß[³ŒËp‹*–‰@$–ät=j»kö±è–Â=¼W‹,wGÆ;·0\ªîf“…lg¡×¢²o|Aam´±Ê.–{űO³2¿ïKm`yLj-Ü&xŒy70ÿÄ£Mùn%óþúûœîn=³Vÿá(ÕÿèDñ'ýÿÓ¿ù*¢ð¸Ô¯ŸeiÞK<—LädÉÔŽþ”X¾Š(¦EPEP\3>ÏŠzïúEì9ÑtßøöƒÍÏïïºüÓ½w5Êé¿òTüCÿ`]3ÿGßÐß?þ¢Ïþöš<ÿúˆk?øÿÚj?xÇGð…µ´ºÌÒ¹“dPÃ’VPF÷9Ú€åÐ ³*¶å¥Ì–°ÝYÍöӢɱ8d‘d2‘ÁA8I%'³)ÆI)5£1üÿúˆk?øÿÚhóÿê!¬ÿàÿi­Ú)X“ Ïÿ¨†³ÿ€ý¦?þ¢ÏþöšÝ¢‹…çÿÔCYÿÀþÓGŸÿQ gÿ?ûMnÑE€Âóÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦·h¢ÀayÿõÖðÿ´ÑçÿÔCYÿÀþÓ[´Q`0¼ÿúˆk?øÿÚhóÿê!¬ÿàÿi­Ú(°^ýD5Ÿüÿí4yÿõÖðÿ´ÖíX /?þ¢Ïþöš<ÿúˆk?øÿÚkvŠ,ŸÿQ gÿ?ûMýD5Ÿüÿí5»E Ïÿ¨†³ÿ€ý¦?þ¢ÏþöšÝ¢‹…çÿÔCYÿÀþÓGŸÿQ gÿ?ûMnÑE€Âóÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦·h¢ÀayÿõÖðÿ´ÑçÿÔCYÿÀþÓ[´Q`0¼ÿúˆk?øÿÚhóÿê!¬ÿàÿi­Ú(°^ýD5Ÿüÿí4yÿõÖðÿ´ÖíX /?þ¢Ïþöš<ÿúˆk?øÿÚkvŠ,ŸÿQ gÿ?ûMýD5Ÿüÿí5»E Ïÿ¨†³ÿ€ý¦?þ¢ÏþöšÝ¢‹…çÿÔCYÿÀþÓGŸÿQ gÿ?ûMnÑE€Âóÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦·h¢ÀayÿõÖðÿ´×9ãÙwhöíšœŸñ:Ò¾I­6!ÿ‰…¿VòÆ?:ô å~%ÿȹgÿa­'ÿN6ôXªŠ(¦EPEPEPEPEPEPEPEPEP\¯ƒäcñßý†£ÿÓuuUÁø~Mž*ñÈûV¡üMâùmí¼Å?ñ/³ç>[síšï(¬/?þ¢Ïþöš<ÿúˆk?øÿÚi\ Ú+ Ïÿ¨†³ÿ€ý¦?þ¢Ïþöš.í…çÿÔCYÿÀþÓGŸÿQ gÿ?ûMvŠÂóÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦‹»EayÿõÖðÿ´ÑçÿÔCYÿÀþÓEÀÝ¢°¼ÿúˆk?øÿÚhóÿê!¬ÿàÿi¢à[ñ>”ºï†µm!åhWP´šÐÈ£%ˆWpúg5‰«i¾&Õl/ šçL·Ž[u·[d_69²Ëæ³³¦W(a€ÜKà ?þ¢Ïþöš<ÿúˆk?øÿÚh¸Ňƒu›¨5çÓf¿3ÞI*Ͻ¢ /•R€,É!6ü ï`róÁ³Ï­‰¢Piés`±C+åZZƒ*"¨\ç‘Àã`äb¶üÿúˆk?øÿÚhóÿê!¬ÿàÿi¢àyõÃ-JÇä&ÖmNKÓ#–ãT¼‘fŽGS;û’ \íŽ3†þ"8~+ð߈ü_§YÛj0i:jDò‰#·½’pUÐBHc såKsÆ:„ç“·¦óÿê!¬ÿàÿi£Ïÿ¨†³ÿ€ý¦‹ÉëŸïux¯–[‹hÌ·—:„A‚ „Iol®»~hü•a"ô$ãæšôh¬©DŒ…¢ªñÐp8übùÿõÖðÿ´ÑçÿÔCYÿÀþÓEÀÝ¢°¼ÿúˆk?øÿÚhóÿê!¬ÿàÿi¢ànÑX^ýD5Ÿüÿí4yÿõÖðÿ´Ñp7h¬/?þ¢Ïþöš<ÿúˆk?øÿÚh¸´VŸÿQ gÿ?ûMýD5Ÿüÿí4\ Ú+ Ïÿ¨†³ÿ€ý¦?þ¢Ïþöš.í…çÿÔCYÿÀþÓGŸÿQ gÿ?ûM…ñm÷‰l¾'êŸðY‰­ßGÓþÛ:D³Í‰ïv˜âg@ùù³É#ålÖ‡‡,<%â Ñý£©ÜxƒX‹çkmh”’ê,ÙQSê#ަ´¼6ûþ&xŒù×3Ä£Mù®"òØ~úûŒm^=ñ]¹ éZô ±§Û^"¡–0Z3ê­ÕO¸ Ó¹—Z¶ø£¬¯‡´Ý2í±tá ¼¾{P€O}·nÈdÝß9ÛŒ¹ã±¶—UmËuec­±È¶ŽíÞã;šb ƒÆO—ÆO Žs¼7á;MUÔ/­¯u+—»† }——&*8šVUVl¾33ýæ=ºWC@þ—wâ©oâMWFÑ-¬Ž|Émµig‘x8Â5²ÎÞžqƒ6·sâ8n‘t=+H¼¶( Iy©Éláòr­¼€Œcé㌪(>Ú]U´c-Õ•Œz¶Ç"Ú;·x Œìiˆ6>_<69ÏÒîüU-üIªèÚ%µ‘Ï™-¶­,ò/F¶@yÀûÓÎ0z (æ¿€÷Ä=oâŸü\˜u(¼ëì_mÓE¦s=¯™·»º&z㎙¯¥+•Ô¿ä©ø{þÀºŸþ°®ª€8?Æ—òJnµ ÞßC}Rm*+¸oL²‰Vé­‘¤ˆÆ¡UäP×|n\ñ’.Ây¢B¾ºÙ šáìðÏ2D‘O$%åq Ѱ%ð¹ 0=?ÁwñÊmu bÞãCMRmV+HlŒR™Zé®Qd”ÈÁ•$`FÔLí\ñj]|=¼f‹ìzävån®® ¿býô^}Ü—Ê‘dR¬<À§~õ;AØ2A·uãÌhWVVÍ©&¤tô´’vD9ÔMŠHòˆÛ`, ãi8 pMjhÞ&Xj’ëPÁ§Ï¦]}’äE9ž-å#uØûT¶D¨1´Ù¬;‡1ÜÙ_Ù]_E=ýú^ÜÃ5 t—n nÂ[(Æ#ž Žªw5¿èú„¥ðí½•–šÏ‹o ²C$‹ ÌxÚÊYFTðFGzžhó]ÁiÌ­u3:,Ú_1J4jû—nStdîÇÊÛºdÖQø‹áæ½²‚äU¸’Aæ\Å4ñÇ ’4³G¶U>X0Pwgj±áŸ[hÕµý¡°·Hb»ŒÚØéñÚÅ™ÚØä?Â-€Ën'wPÃkÕÖmodñ ¬V³K2Eo`#3Á<^dŠ]£2?9TU8 ¡ÈÚ«'Ä}µMÆÒ=Fiµ;±k†Ó®bhAŠIFVŒ­åà€FöÎØÜGñ–‚‘—kð#ù ¹‰ñ y%d;~uÞè7.@Ü2@5‡¢øîÂm>iµˆ]¬oÒò ´híÑDÂÊ¥b¬Ë3CT…ꎗðŸMÒ­í¡ÓŽj¶ïhRX4¸’yV ¨§Ä²™Øù*¹È–!Ž(«Æ$–Âeº›>cÄ`6²‰Õ‘C00•ó•¹^Œ§¡•&Ô5ë Ma¿¹šWO2ßÌDŽK{X™Ü7Ö‘¸lޤ`õ5Ûñ*ës›«÷žÞæk»­2nLƈ JGîÃyhHUàä®Òr5ô]k)§^C¥8Ò5i-î„Á›f7#ºcåWQA'¤µñ¿‡îVfKæHãŒÌ$šÞX’XÃ*@•rè2…†Y}E?@Ð/4smk©»F²R––‰n•1…G“'r ápªx-Œ×5oðÑĽֳçKoÈæ[m²;¬öóÇ,¬\ùŽÜnàÜpœ€jˆš2ëz•”í,VÖ0Á$·Iäiƒ,©³1*•‹¾ƒï\øƒL¶ÔEŒ×An<Ä„üŒU$¸ŒàmVlŒA9ê+œ¿ðM楋ÿ´u±,¾ Ò—KR¶ÑT\TnËôŒàœä›uçÃí6ãÆøƒÉÓšêk¨.ÞYô覸F‰@ŽfÉH:AÉR¤æ€44ÿ¥ß‚4/É V˪%ƒù2JÄFn^% ¹P’A”ò€N2PÂ¥ÏÄÙÛM¦;ݵĶB%x¤€IÅÄPù¨Î˜pžr’88S´š¡¤ø+\·ðΓáýC^Ón4Ý3ìAƒKxf?ežs†rÂTáG-žÛKføn%Ò|)`úžSCÓáÓÜýŸþ>U'³”œnù7 2¸çfsòà€w6jq]Z9{yFär¥wQ8=AèFà×Ë¿·?üÉ?öýÿ¶õôæ‡e&›¤ZYMqö–·ŒD%Ù³rŽ#'œc>§ž:WÌ·?üÉ?öýÿ¶ôõUQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@rºoü•?ÿØLÿÑ÷õÕW+¦ÿÉSñýtÏý@[ûGø[TŠðøßM\ÛYØ-½Õ´`’‰I&ò¿Ä§Ì °hnP¾Ýß„Š|+ðYºÔ­^]ZCs©iús‚‰JDSø H¬Û:þóæùË ï¼eãÂÖÒë3HæM‘C fIYAÜ çj–?@2̪ۖ—0^ZÃug4SÛN‹$RÄá’DaÊGAWTñeB4eð&íúþgeLUya¡B_m¯^¿™äž+Ö®ÖMëHÕá!¼´»’{x¾Ê÷ÿÙWìr€âäûËžIÜ)Ÿð–xt«†Ô5« xžâÚ5¼²™eîŽVpóKoQd¤xÊHAm§Ôc¢¹N3ÍþëÚÆ½­ÝC¨jÐXÛ#lX£s}®þ ¹ØÝ·Œœmù—¢‚Tè mkXñºë$*ÃåXÄäàÃoöxæóÿ ó]ÎáÎb_îŒw—©hn¤÷O{ld7VâÖ|HÊ%ˆ1`ŒŒ–ëÙ˜tb j3_ø_Âwš­çÙ5 Ûhe’ ¢ý¢V·,Ña<|Ï…Áýß]¡ƒÅ6ƒ«Á¯C Ì“CýŸqdl–·ÿÈŒÑyÇ¥u@( )³Õo¼=«.‡ý£ö”zªG§ˆ×v£þ[Ý]ò7`<· p¾NZæõ¿]7ÁÔ‚ú²ZMà˜gŠ+kE {4–ò,±…EÂ*(Œá…“ò©ïTPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\¯Ä¿ù,ÿì5¤ÿéÆÞºªå~%ÿȹgÿa­'ÿN6ôÕQEQEQEQEQEQEQEQEQEQEW+àßùüwÿa¨ÿôÝg]Ur¾ ÿ‘ÇöÿMÖtÿøë@ð¾§aa¬^gº;‰+o K)þË »¹û¨ì½=|Ïñûºމâ‹ÿéͨZjóA• M/•1HàDd^y*¥X}âLdå“éž´ñ‚þ ivš‹îÖ-ŒqÊßë¾Ë — Áòaº¿(òð¹P+ªµ*Q¥ BW“Ývþ¿­,vW£BiΜï'{®Ý¿§ë³G¦Q^5âsQµ×íotB=jæ øbžX|¥Dk­1\—E*á·ª6ãi*s4ž'ךÖÎ ÝrÚÑæ¼¸Ž;›IP‚±ùòÛ„wÜîÇ,€À£g”ã=~Šñ‹MwTñ7„Ρ©ÞXõŸ¢ÛÇ,`ÊÚ\ìÙ·+ãæ# zü¸«ñUñç5aÕï?âcu­éBÖ!á-Öù£ÚvÞ~ʱž~ëœaðôî4W–ŸøŒxº [ý>]).,á†k‰ÿ}¨@ñ#I2ǹIi0Êñ¢”Éz»ÃZž½­Ùø.)5û¨%Ö´ u[‰â··,’(² 1frrÞ=>] ¡Ex®—ãÝcQ“A½mLC%ÊéF]8G#­Ð·ó++Jê ÌÑC ¸b¿6¿¹ÐþÙ\sd4½Áè÷Cn±ë…–WÕêzÆxnHìôßZßìý/N¾š;{°È¬FåvÁ@#y$p*F*×Ä–×H’íÊhÑß«jg$/‘åÉ·v?ƒÍòKvÚxÍu4Wœkš¥Ž‘á…—ÃŒš~Ÿu©ykA†0c,LrJ qÆY@ µ”³,ÎÒј…ó`'pýÀÎO˜XÝ(®ODÖu#ã=KA½_:;u’ín D2ü…À÷ûBzþç'“]eQEQEQEQEQEQErºoü•?ÿØLÿÑ÷õÕW+¦ÿÉSñýtÏý]UQEQEQEq^$Mÿ<8<›™¿âQ©|¶òùl?}cÎw/Ù­#þ¡úÏþÿöêÍñ@Ô¬üi¡êö%ö­mŸ{i*Ù˼o,–¬„‰¤ŒD/О޵/ü%¿ýž$ÿ¿úwÿ%R°|ú‡ë?øÿÛ¨ò?ê¬ÿàÿnª_ð”jÿô"x“þÿéßü•Gü%¿ýž$ÿ¿úwÿ%Q`.ùõÖð?ÿ·QäÔ?YÿÀÿþÝT¿á(ÕÿèDñ'ýÿÓ¿ù*øJ5úão›,²¼®ás´rNNp2}M_®SŒñÍfæâ²ÖnÖ?á&ÔWwXlïâ‰qè"Q ^åvÍiøÛľ"²ÔàƒAºÓ…öt70Þ_LSír³°*;y œÉDØß¼ãÛÑ­l-­nîîmãÙ5Û+ÎC;*… Œà  ’ÏAV¨€m_U>2}ïS6V¶wBîK­±)ž YÚÜîRùXò0çÉ;›5ÍkÙ¿fñÚü¯øXßk¹þËÝÿ_ëÙ<Ÿâòvy[öüŸwñW¬ÛiÖ¶×÷—°ÆEÕÞÏ:BÅ‹P2~P9à`e˜õ$›tåãS¹Ó¼eâ(ì.OÚn(žßÂöêt›[m¥"ÄÄÄ×ImJÑÁ¹¤«¢'—È 9ö«ˆRâÞXeÝåÈ¥k8#r>£šm•¬6pZYÄÛAÅh0¨Š0@ã~ ÕugÂzd×>&º±¾3é×z…½¬@ضÀ4Œ„"ǹ‰’ÞPo¸[Ö¼Aek¨è—Öšƒlµ’&ùÁ;ÁìT€Aì@5¡UuK mSOžÆþ?6ÖuÙ,{Ї^êpG¡È<ÆðÆ£5ÿ…ü'yªÞ}“P½¶†Y Ê/Ú%krÍÇÌø\ÝõÚÿaÿÂcÿר¿°¾ÁØ?´1öo´ù’yÙÝòù›|¹ù¾öÞõè ( ¶¹žÎïÃêƘ£LÖ ¹ÓÌ•-ÍÝ©·® ÉŒD aœü¼3YÐx·ÅB[¢°iºd·‰o¥¸uµX&mƒˆŒ‚ w6éeûË’# {•U±Óílé­"µÔÆâfÉ&I±'ÙT@@–¹«êmS\þƾf´†­l¼Ï´ `¤•Tßþ±äPXžV]HÈ­¯„`ø[áQ=Ô·S. ÈòíÞ®Œí”9NFï—æ%²O_EQEQEQEQEQEQEQEQEQEQEQEQEÊüKÿ‘rÏþÃZOþœm몮Wâ_ü‹–öÒôão@UQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@r¾ ÿ‘ÇöÿMÖuÕW+àßùüwÿa¨ÿôÝg@ñOŽ´ êvÅà†{£¸2¶ñò²ŸàŒ°Û¸ûŸºŽËÓ×Ìÿ¼+­èž(¿ñN™ Ú…¦¯4yPÄÒùSŽFEç’ªU‡Þ$Æ@>Y>—ákOø/à®™k¨ÉbØ¢Lù}– .FNÊ|˜_î¯Ê<¼.T ê­J”iBP•ä÷]¿¯ëK•èÐ…s§;ÉÞë·oéúìÑé´WŒ]xÓÄO{o¤ê6³i°ÞÜBºó‹E –¶ŽŠ[ȧsK3³å`0 >:ƒxÊÂMcR–æöÅpÐ2Ž ú ¤´jcG[z ã8„doÞ[”ã=¶Šð]sV×µ x.kÏÞůea¬\É6éöcÝ€fÆ@L\´»#1/D܇±Õ[y œÙ'iQÅni¾(Ô¥ø…Ÿö£Km6¥qc-‹¤+ä"E;£l æ)&C4„:Ê€”Óê­í…µóÚ½Ì{ÞÖa<,©GŒ‚£0#¡ƒkÎ>)¨¼OGzÛ`±ð”òÚäd™ng¹UŠ!žÂB?ˆææ¹â=v ôæ·7’ëYÝ›™D1ØÆ˜AãîÄ726L™à´»Ó4û].Ð[XÅåB¤#qbÌÌY˜’I$±$’rI«Uå£Ä(^ŠîÞKmÆ­“tpÎ'8•KÆ…óoæHr ƒ*0ÜÍ­IáùuË)¡:0`7ï2@¶íb1‘šÁñ>§w¬C¢ÇâíOÂGMM^YïÁ½´šÂð²Íº;t<„ڹܬÀ±û €}Ey¦Šîïá­ÃzÞ•o¦\éÚÏÚ¼;g vÌñ\[ªùHÆU\œ7''wC¼·ÃíoZ¿žÞyu»¨®|GªÚË4b8‘š'Ú31ð¾blî¸Éó {¥ÉèšÎ¤|g©h7«çGn²]­ÁH†C¸ÿhO_Üäòk¬ Š( Š( Š( WMÿ’§âûéŸú>þºªåtßù*~!ÿ°.™ÿ£ï몠Š( Š( Š( Šå|M¨kŸð•i6ƒu¦Ú}ªÊîòY¯lÞçýKÛ¢ªªË3ç’I'îŽ(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ûŽ?èaðßþgÿäÊꨮWì>8ÿ¡‡Ãø!Ÿÿ“(ðΡ®ÂU«èÚõÖ›wö[+KȦ²³{oõÏpŒ¬­,™Ç ¼x ªŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹]7þJŸˆì ¦èûúê«•Ó䩸‡þÀºgþ¿ -ý£ü-ªEx|o¦‰.m¬ìÞêÚ0ID¤“y_âSæX Ç´7(_nï ;Å>ø?¬ÝjV¯&­!¹Ôtý=Á 1)HŠi›o_Þ|ß9a]÷Œ¼c£øBÚÚ]fi\ɲ(aŒÉ+(#{„í@rÇèY•[j ­õ æµ'´¹Œh¼27˜!pèaLì`¥¶œ0f­†“ê·~8Ô/5½\ÜMs£Z´pC³¸[›¥ÝhcvÚ¢2[98*bÛèzn‘e¦Íq5¬oçÜmóe–W•Ü.v‚ÎIÀÉÀÎO©«õÊqž9¬ÜÜB¶ZÒ ÚÇü$ÚŠà®â« üQ.=J$ ܱîÙ­?x—ÄVZœh7Zp±þΆæËéŠ}®VvBÇo!“(›÷œ{z5­…µ­ÝÝͼ{&»eyÈc‡eP¡±œ´2@è*Õp «ê§ÆO¢ÝêfÊÖÎè]Éu¶%3Á+"Û[Ê@ß#KFù#sf¹­oû7ìÞ û_•ÿ íw?Ù{¿ãëýaû'“ü^NÏ+~ß“ïîþ*õ›m:ÖÚþòöȺ»ÙçHX±`ƒ OÊ< ³¤“n€<¼jw:wŒ¼E…ÉûMLj¬Óì>XaqÚY$¯»Zeø#yÈu¬x§ÅÛø^ÝN“kbm´¤X˜˜šâ)-¢iZ8#·#´€tDòùG>Õq \[Ë »¼¹£mb§`àŽGÔsM²µ‚ÆÎ K8’h#X¢Fè€#Ž,Æ6?ÏÔœ‘í¶‘ÞCåLÓ*ç9†g‰¿ï¤ ÓtË ].Æ;K„6ñçj‚O$’I'’I$’y$’h#ÃZ…Ýî»âÈnfߎ£µºmb›;yO då¥cÎj¹ÿEø™vÜG¥Ë5ÚŽ›á–%‰ˆõ+,£=Ä`®¢ªÃ§ÚèÜßÇ/.U#–RÄ’©ª2xs ±=I  ­fKÉ|­·‡¯¾Ý©ˆoÒ]ÈvÜ XþPÈãg<Ÿ1'$ñÞÿ„sþ_ÿ åyû¤þØòÖy>Cãí]üï7ÉÆÿŸïöÍz…áZ·yƒ|akqݘ´Ñ~ѶèâÊO¶Xƈ ^K£ÈÁŽH1‡R2¸ÐѼcãì$¹¿m69ÚžÞyå°f¹$fO!yq´¬QÉ1‚ zÞ¡§Úê ÞÄ%X&KˆÔ“"«ßg¸¨j€<ÇOš[ŸŠz%ÂøžêþÀYêVñ¨‚(â‘ÃZ·—¸'ïÛrþ¤²ïôê( Š( Š( Š( Š( Š( ¹_‰ò.YÿØkIÿÓ½uUÊüKÿ‘rÏþÃZOþœm誢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®WÁ¿ò1øïþÃQÿéºÎºªå|ÿ#Žÿì5þ›¬èþ)ñÖá}NÂÃX¼ÏtwVÞ>@–Sü–ws÷QÙz;˜æŠC Vêc‘£oÁ”‚?_5ü~ð®·¢x¢ÿÅ:d3jš¼ÐEåCKåLR8žJ©Vx“ùdú/‡­üAà‚Ú®¥s³X·ºµ†VÊÍåC-ò/—Œ`í†M›S·xS]U©R(J¼žë·õýic²½£Ntçy;Ývíý?]š=KÓ-4¸¥ŽÊ"‚Y Ò3;;ÈäY™‰$àÉèíW+ÌôŸ][øšÔõE—íöÈ-¯¤_H›C‚ª>^íLoòÉàWðæãR¼Õ|=y­ê×7Ú…æ¹kw"L°¨_3ÃÎÅÐF‹ò–.ƒ¨ý×6òܧï´W‚ëš¶½¨xcÁs^xŽö(õ{+ bæHá·O³îì0&2bå¤mÙ‰z&ä=Ž©â/§Ä4ø_M¶Óc¾µ‚(ç™Ä·0º#HëÀŰZ@HЦ?˜’@=&ŠñK/ø–_jËë³™¬¼'aâ!ÙàÙ$ÏËåõš+È|q­ÜÝx;Æj:Ÿ•8µÕà:GÙÌÅ(÷¹7*£ïbTïÚH«~'×üM¢ë÷ZMäW¨ZÊwº½)n¶±ÏöÀÃzDáSu´J¥‘È2ž„zN™§Úév‚ÚÆ/*Í!‹fbÌÄ’I%‰$“’MZ¯ï&²ÕüUö¯jßà¼m×dšõ€ºŽeWÀ4W·?t!f †%Hc=ëfï_–×Y¸µ†Ë^±Òb†(aaåÜ¥’³eÑŽå7,ëÛpùƒ/Ë@—Ey'‰õ{íNÒc×n”ZxcO˜;E :\Kö¸Ý_äÿ–f$O9ˆn$ïÝÛx]¼ñ5Õý¨¶’)¾ÎT®‘ ˜ÀfóSþ@-ËèèÞ8ñ5•¿F+[Ò£¢\JfYôÊÅêäõ&£ñKKqà}6úkøm^[ÈYZK›_234Šbh|Â6Éù@â€:Ê+Ïou-Nðæ·©x>èC6ê÷ˆ$¶Bκg÷`…où fiCñf©q+Zßë¾F›×u‚°¹b¶ö²Ä…‚,gwŸ+2"g;ˆ¨[iÖ¶×÷—°ÆEÕÞÏ:BÅ‹P2~P9à`e˜õ$›uäš~£¨YÜëz½®¥!Ä:]´ðý”G×Ú-ôèÙ#!eʨ`A6î•Ëkþ ×µÏHž+Ÿ@·³•´ù®­î®Ñÿ´mÆb‰R0 †G•‹á±¹¨èJ+Ê´ ³Ót ëû6¥­Ëmqsá‹a…@±šR o•|Üćq=6‚0>nLֵȼG¬ÞË®Ý5Óɧéq$‘@DMnâÎG #mK`à5Áè<°€ëEqéªêšoí4)ä’úÞò5ž)åTVHã‰Öbvï¹éÖrvQEÊé¿òTüCÿ`]3ÿGß×U\®›ÿ%OÄ?öÓ?ô}ýuTQEQEQEÊê_òTü=ÿ`]OÿGØWU\®¥ÿ%OÃßöÔÿô}…uTçÞ ñF½saáß¶™<%‚6ƒì6Ò@Ö²µ³\l`ò>õØŽ7 ¸ pwq[\ø¤-£Ž=7@Õ'¼’êÞ4ŠC—‰îb…Û`clʪ@¹× (r»Þð=¶€šb>©©ê‘ép-¾ž—ƶ¨gÊ#2Û>]͹°Hdæ”_ 4¨â¶Œ_êem#Úå¢Ì ³A2c÷1W¶—ÜXgqn0‹~#E¤Úk‘ZØÜGikvö²Ý„Ë40É.Ò‚O4&#'qUR:7#:ú‡-,…Ú>Ÿ©=Ý»E›`‘£2I¿Ë“s¸ECå¸Ë²ò»N ÒÔþéZˆ»Iï5oq%ÌÞH1®"š9H&2N|÷#ql…Ê›WÞ°¼‘î$½ÔE÷›‰v]$’1Ȩ€:2²4¿yXåÉÎp@oøXºsý„[iº­Ë\¤’2‘–ˆ$ð\Hdn!ó#†RjêË­x<-e ómžðÙM$ó=}žl™ \e,çi%rÄã8ÀÚ]ëv‰%Æ· ¤–«jgabŽÒG"òc ’dÈÎ’¸ÛȬÍ;âŸzÆcóKQZ )H˵£‘“îÃ) °*’¿„í¿³ï,¯oõ;ëk›W²Ûq?ú¨`ª• IÆ>vËð>j§mà;nÅã_êß§’cºc¼mœ¨XÂŒ­ÄªFÜzd’@)Üøõ¬µ-Mï4»åÒì´ë{Ù¿rkPÒܤÏ(gE)7Ü1Š(ø³¡Ø[x‚ÓJ¼µŸ[Óíoš^D`ÓÛDîÈÑ«ù€-¹!AÚpyߟÁZݵÍî¥1Ö4Á¥ÜË,ÁäòÁœîRW†ÍÌŸì€`š—ìo´ýRÁ¯µ(týA.–[hf µÊ°•ÀÛ’rîÀ6T3gÅOãoÁá[[+ËÂÿfy&óBD™#´žà€K¨SˆO'w¦íËŸ¬xÔÛ[Ý,6SZ^ÚÞiÉ,wʸ6×7Kœ69ÀÚ&Æâ)ó.8-Õüºæšö:ÿˆõ½J#æì2‹XÚ?2Ú{wÛåÀ¹Ê\1ç<ªöÈ:º¿„ì5]BêòæK÷"ÅdDeÚE¥ÃÜF0TðÌìÕx<ж—zºŽŸäqKs®ôY@ ´ô$q‘ƒŽ¼òÈ®Mÿ’§âûéŸú>þ·ô‹ÒôÛ{e–X ]ˆÒ[hè2è0>‚°4ßù*~!ÿ°.™ÿ£ï誢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®WMÿ’§âûéŸú>þºªåtßù*~!ÿ°.™ÿ£ïèËhÿ j‘^é¢K›k;·º¶ŒQ#i$ÞWø”ù„1í ÊÛ»ðƒNñO…~ë7Z•«É«Hnu?OpCF JR"ŸÀZEfÛ×÷Ÿ7ÎXW}ã/èþ¶¶—Yš@×2lŠc2JÊÞá;P±ú–eVÚ‚k}BÆ9­gIí.cÐI•taÊêzr>⺧ˆ«*£/7o×ó;*b«Ë ømzõüÏ#¾ñ–¸º¤öz©©h£O_]ªÚÅš/ æ\ºS;)m§ «Gá¤ú­ßŽ5 ÍoW7\èÖ­ãìîæéwFZݶ¨Œ–ÀÎN ˜¶ú›¤Yi³\Mkù÷|Ùe•åw  ³’p2p3“êjýrœgŽk77­–´ƒv±ÿ 6¢¸+¸ªÃgKA‰÷,{¶kOÆÞ%ñ–§ Öœ,³¡¹†òúbŸk•P±ÛÈdàFJ&ÆýçÞkamkwwsoÉ®Ù^ráÙT(lgíd z µ@jú©ñ“è·z™²µ³ºr]m‰LðJȶÖçr7ÈÒÇ‘‡>HÁÜÙ®k[þÍû7ˆ>×åÂÆû]Ïö^ïøúÿX~Éäÿ“³Êß·äûû¿Š½fÛNµ¶¿¼½†2.®öyÒ,X “òÏ,Ç©$Û /Îã/Gar~Óqâ+4û–\Dö–I+îÆG–™~ÆÞrkÀÞ)ñDöþ·S¤ÚØ›m)&&&¸ŠKhšVŽíÈÀ- ]<¾@Qϵ\B—òÃ.ï.E(ÛX©Á8#‘õÓl­`±³‚ÒÎ$†ÚÖ(£A…DQ€ z ñ«¨ë>Ó&¹ñ5ÕñŸN»Ô,ííbÀý¶á¤d!=ÌH|–òƒ}ÀêÞ‰ãfKÇu£^Eæ>©gbflwßE«Üdnu#¨ ô"ºj†ÒÚHš;tØ#ÊFIù‹±çÕ˜ŸÆ€<âó^ñ=·Ž–—6+aÝ¥²¹Hžò& ²£·;ŽLƒrº*”ù€^¼÷nµÛñÓÚê7š­å”wWÑE<0o»nõtGdIZÅÀ#…Ú¿%{uã⯮…}5þ¿¥ZD“Zwm8“Ë®dS<–© GåB7«c%X‚éU|®jMg¬kÖÚ¬ò+øšÂÖX䶉í'ŽÂï€y *Ѳ«Ý‚¬{mäŸ|7=ž…á½`išF•m&… lº|…žýÝaq<ãË@nîzß7­ 7Æ>0žÖÚ]BçMµ–áìR[x$3MjòßÁ #)?’I«;± 8«Ú¨ %°ñ úV‘e£­E¥X=î·º«Ánš+çHP€‚=î Žp ¹CݳTµ_jz•–ˆL–7²jZM-mÉ kId•›i*S$y$/É´òë^ÏEyN©ªOeâ BëHÔþÔóéþ·PÄryñͨ\DÒ| !Ü®OÊçŒqŒ›ÍG_³øƒ¨ºj·ºŒú5†©meo$p*ÞÌ-¬ncöF2äÌßwiÛã¼ßí”P’é¾)ñF§ªiÉ`÷vñÍg!¸6hÐÌìYÚÞ8Æ]!P ±O0–þÊ7ñu;û+‹á塹Ô7Û›‡[ûˆV1ÛÈψã‹1óõ'${Eí¤wùS4ʹÎa™âoûé4Ý2Â×K±ŽÒÂ! ¼yÚ “É$’Iä’I$žI$šÂÐ5™&ñ‰moï"ÁªGcc íRÐ`•z?<ŽH {(O­]ÂW{iuªÿg,7ÖðZZ}”KöØž4f~›¹f‘w)<½Í‘šë綆ymä•7=¼†XŽOÊÅY3ÿ|³Ʀ ƒÆºÜÓïo5 º…îi©éðI CûFòE;íP–>æÌääAñ\Öáþ±sq¨¼ÖÚ„šþÖa8b¿1¸`¡·³*òpA‰­x!D†{ ØEköpáæÄÒ†ÇÌWpaºäãÃÆ:µÆ±m±®ÿe$–7J‚ÍË(m|™vº–ýï™#`œ Þ_ß\×±UY4ûY5[}IâÍí¼2ÛÅ&ãòÇ#FÎ1œ˜£äŒ¼u9òßkÚåõͼW 4›ÝO]†Úñ`·ˆ×r÷Ër Ä!ùWûV)ýTÓôë]?í?dŒ¡¹®&bÅ‹ÈÝI$“Ð@@o¤«$70Þ\ÜjŒ«"+EªZHóczn¿ÖµùßÅäìóvnù>æßá¬íc[¼Ó<â(4ûˆç-/ˆšâÆ[t•"ˆ=ì‹9ܤ02*!S•;ö‘•j÷Z«ªiöº­„ÖZ„BkI†Ù"$€ã9ÁÇP{Ž„px4åÓø³Æ)¬jþLZkýµƒMó]®%XRCò„.ò±Í)R$ÀˆMJê[ïø>X<_swi­åZÅ’Îç îPƒ¹•P Ã/šrK4e}^Š+•ø—ÿ"åŸý†´Ÿý8Û×U\¯Ä¿ù,ÿì5¤ÿéÆÞ€:ª(¢€ (¢€ (¢€ (¢€2­|E£Ýë·º-¾£lú½–ß>Ïx eÓÉXŒŽjÝî¡kesaÌ»%¾˜ÛÛ®ÒwÈ#yàqòFç'Œu WŸÜüðî¡ñ6ûÆÚ³\Þ_Ìñ<o1ÅŽ$@~^Xü™äãœc½t¾,¶ž}{ÁrA ²Go«I$̈H …Ú†b: Ì«“Ý€î( ´¸K«Xn"¬s"È¢XÚ7ŒÈÀ2ŸP@#¡™¨ZêvÏ=Œ¾lI4ÖìÛJâH¤häÑцzdds^'à _[ø2ÎêçGº‹Z´ÔtÞÙ–h¡úlwr2ur;+û¼oèÚEìSjGQ°ÔÞÖíµˆíº”–ÑÚòá‹!8¦G$8hà €z½À|)³†ÄêØéMeb!':tšwžø}àÛ¾åã2(÷“²»ú(¢Š(¢Š(¢Š+•ðoüŒ~;ÿ°Ôún³®ª¹_ÿÈÇã¿û Gÿ¦ë:Š|u x_S°°Ö/3ÝÄ•·%”ÿe†ÝÇÜýÔv]ÝKOµÔí’ è¼Ø’h®wÄ‘H²Fx=ã¡ÆE|ãñûºމâ‹ÿéͨZjóA• M/•1HàDd^y*¥X}âLdå“èþµñƒ> ø~ÇQ¹òõ˜ïlí]²²ùQOºmùb”&åp§ê­J”iBP•ä÷]¿¯ëK•èÐ…s§;ÉÞë·oéúìÑê4W™^kÞ'¶ñÀÒÒæÅl »´¶Cw)ÞDÑ¡–AvçqÉnWERŸ0 ×'CñwˆeÓ´{»LÌe²ðõä¨ÐF†þso*p£Þ1Îãýß–¹N3Øè¯4ƒÄš¦¡â/ì›}U"Ôå½¾µžÁbžÂÝ_³ÝF~bŸ›*ÞvùjŒ¾,ñUÎ¥h–Ð$×ÐéÒ-Ä‚­Œq9¸ËåÉôää«/ÈKP¬Ñ^-§ëšÊÞ_êÝÛj\[h6¦âÙKÆÑË«]øo7f6êA$•À Ó/5~Ïâ¢éªÞê3èÖ¥µ•¼‘À«{0¶±¹Ž7ÙË“3}ݧl Œ~óx±Mam6¡m}$y»¶WH¤ A øÜ§v©ÁÈÊƒÔ µ^G£øÄ×Úž—cu«X¬W·éngÓä.€Ù]ÊÀ»ÛF€îŠ& µ™yÝÁÍuâmrÎÎ WûFy’ãTÕôáh¶‘Ê-ÅóÄèªÞAöT\oÇ_š€=ZªgZÿjÿiɽò>Î$,NØ÷n àdã$ «œíã>ë·º¦£ªÚÝj£U·†ÚÚâ+ðÉÌ:²‡‰J(c‚AÈ,NBòz}ä¶gÁZ¯œ`½Ô4‹»Fãhf‰æ¹ÓÌìrʰP\PµQ^mªx‹Ä©ñM>Óm´Øï­`Š9æq-Ì.ˆÒ:İ1l"©æd›^Õõ[ß­Ž­©›uÒì¥M±/ö•ÉóAÊäG6Øöÿ¬çåR(¿¢¼oDþÍû6öO+þ7Úí¿µvÿÇ×úÁö¿;ø¼žnÍß'ÜÛü5¬kwšg‚üEŸqå¥ñ\XËn’¤Q½‘g;”†ED*r§~Ò2­@ëEy$þ,ñŠk¿“šÿgmE`Ó|×k‰VÀ|¡˼¬gsJT‰0â“Rº–ûÄþ–ÜÝÚA«GçyV±F¤³¹Â»” îeT0Ëæœ’ÍPWªšVk¥XEeaŽÞ,íRÅÉ$’If$±$’I$’I5…ñ;÷^Õobâ÷OˆÞÙ·qqÝï0 GpÄt5½$‘VÞ3}²V†V[=ÉûÕ dÁ¾L¨È ~÷I\:}­Œ—rZŲK¹Œó¹bÍ#$’zP@Uªó½Ti_ð’x‚/HÂêi!:J©o;ÉGÿàsæ ¼Òv󂻸ÅTñ'Š5+?µ­¶¨ÑÇ õ·Ø!U’)žy6•28ýé@衆Ü1_˜Óè¯Ôu›Í[Ã:Y¾Õ·jW:T×ZoÙ@û çR¶ÞÆÂJí|—Û‘€ ;Xñ?ŠtýNûI¶¾¶’ÞÊòxTÔ%KSkk£`þF¡§¾w66gýä–9$ 1’'åEˆ¯ˆ/< ¨Ë¯yÿ­oJ°Á n·ÍÓ°¶óöUŒó÷\㇠q¢¼òÆÿ[½²ñdºN³-üš\±E` p»ÎÒ|³*L…Üep”8]½g„µs¯hú§—²+¦‘àÿn1„Oÿ@øÐÏìë_í_í#7¾GÙÄ…‰ÛíÄœ œd“µs£袀 *¶§+Á¦ÝËÛ"Dì§Á‘X÷—Í]$7š§ŸHA’Ȭd¨'㎹çµb]kš^…ñ/ÄëöÖQ6¦*¤ \ù÷ü(êÇØdÕïøIu}[åðχî '¥ö¬Mœ8õXÈ2·âŠ÷«#QðƯüXÕ§¼^ÙèÚÙnígxfƒt÷Û¶²‘ÁÚ¹ àdV¿Ù¼_£Ç­ÝŸˆ­ü³¼ÖèiÜûOv xRã]ƚ曯jp_,Z}Ük¨‚8ZI.•‚Œ³ˆSï1éÚ»ó=?FÓ¼eãíjûÄþ Ó,mâ]fÆ)vÈ%»ioó# 4y*Ƕk¼¶Ñ4«]éºeŒ:K#Æl£·E€£çzù`mÁÜr1ÎO­hQ\þ—௠éñ_i^Ñ,obÏ—qmaR&A ªÈ$} ©µ¿ øs^ºK­s@Ò5+”AËyeΨ !Ae'$ãÜÐÕŸm¢iVº1Ò-tËt–GŒÙGn‹GÎõòÀÛƒ¸äcœŸZÏÒüá]"þ+í+ÃZ%ìYòî-¬"ŠDÈ á•A¡4çúO޼1ñâf’ž¸¶Ö~ä_›„¸†XV=óYí?<|Ÿ•ºþ¿¡ÿeÿÔ Fÿ¾ÿûUy—ƒ¾ ²ñRk>ÿ‰ŸŸe5Ü:Ö¡äíÜñ:4m»gî8 Žã­zÛ¼qÿB÷†ÿð}?ÿ!Ò°²ÿê£ßýªì¿úhß÷ßÿjª_nñÇý ÞÿÁôÿü‡GÛ¼qÿB÷†ÿð}?ÿ!Ñ`.ÿeÿÔ Fÿ¾ÿûUÙõÑ¿ï¿þÕT¾Ýãú¼7ÿƒéÿù·xãþ…ï ÿàúþC¢À]þËÿ¨ÿ}ÿöª?²ÿê£ßýª©}»Çô/xoÿÓÿònñÇý ÞÿÁôÿü‡E€»ý—ÿP-þûÿíTeÿÔ Fÿ¾ÿûURûwŽ?è^ðßþ§ÿä:>Ýãú¼7ÿƒéÿù‹wû/þ Z7ý÷ÿÚ¨þËÿ¨ÿ}ÿöª¥öïнá¿üOÿÈt}»Çô/xoÿÓÿòïö_ý@´oûïÿµQý—ÿP-þûÿíUKíÞ8ÿ¡{Ãø>ŸÿèûwŽ?è^ðßþ§ÿä:,ßì¿úhß÷ßÿj¬ Áö‰ž#O²[ZçHÓNËs•?¾¾çî¯?‡j·öïнá¿üOÿÈtxgO×?á*Õõz×M´ûU•¥œPÙ^=Ïú—¸vffŠÖMVßRx³{o ¶ñI¸ü±ÈѳŒg&(ù##oN@<¡|e®¶­¦»Ö²»gÓ#¹Ò]"Eh0 NÖS+€Ó0E »pÅ~iüKâ+Ö6«u©Å Ùñ-½¡Òd±I‡Ù×P‰L•% M² À.á¶‘ëTPèúž±á MwýÖ¬Ñkz­¤ö÷Kq$—‹lìE#t‚.:¤’>P{IáRø‹sm¨Æ’ÚÚé1½¼RUÚi%IŽ…Ž5öüG=¡§ZêfûdfQm:ÜF»ˆEÎÒ@8l@  ÛÝ.Òöæ+™ã´E‘$±ÈѲ£€r¤)ö*ä@ïƒ.IðU§Úõ¶Ž é,á¹gLËw*YÁÈ«çïüÄÆø¡©\húÃjv/²îËÂzåÌ-€vº5“)Á@ê z …¾Ÿcoge AkoÅh0T`øTôä~ —V⇴ë¿^›[Û[ÂÞT3q žS/în·D^w~ý†Kle«¤xÇÆéò\ß¾›µ´R\A ¼òع$fO!yq´¬QÉ1‚2öjŽæ¹âȺ˜ähÛðe ÀÐŽ]xÓÄO{o¤ê6³i°ÞÜBºó‹E –¶ŽŠ[ȧsK3³å`0qáM[T¾ñ¶º”ÑmBÓ®Þ(¢*ž|Ïr$eÞ¡ÀýÒ€;€s]—¦ZiqK”E²¤fvw‘ȳ3IÀ“ÐÚ®PEPEPEPEPEPEPEPEPEPEPEPEPEP\/ÆÍV áìú½âJöÚ~¡§]ʱ]’;è…œŒ‘]Õr¿ÿä\³ÿ°Ö“ÿ§z©¤üJÑ5=*Îþ /®¡IÐÂ?|øVPÃæH™[¯UbbG5oþÍ#þ|üIÿ„æ£ÿÆ+WÄúí§†ôK­SP´ñ¼…bMÌÁQœÐ•IÉ rEjÐ+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTP+ÿ æ‘ÿ>~$ÿÂsQÿãÏüñ]í|[â*+˜l¯5¡å¥ÊªÈ6YZ¡ÈRGU=úb»ý?R±Ô‘ßN½¶»DÆæ‚U.@aœàƒô Ö-÷‚t{ÍNóPgÕ๼u’±ë–©#ª,aŠE*®v¢ ãøEt´W+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£ÔøýuTW+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£ÔøýuTW+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£ÔøýuTW+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£ÔøýuTW+ÿ‘ÿ?ž$ÿÂQÿãô¤Ïç‰?ð£ÔøýuUWO°¶ÓÒd³ÊIfyÙC7¹Ë ã'$’ORkŸÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:ª©§éÖºÚ~ÉCs;\LÅ‹‘º’I' €°?áÒ?çóÄŸøQê?ü~ø@ôùüñ'þzÿ ªªêš}®«a5–¡šÒa¶H‰ 8ÎpqÔã¡ sÿðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐUEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =GÿÐA¨éöº”pÇ{›S$ê…ˆ]èw) p@ Œ€zV«•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:ª+•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:ª+•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:ª+•ÿ„HÿŸÏáG¨ÿñúâµ_L>.h[x£Äèé—WoöÅëy²Bñ >iŸrçí(p8ýÎ9ÜpëW–ñÝÚOm6ÿ*dhßc²6ÁÃ)O=Av¢ÒÚ;Xm­bH­áEŽ8ÐaQ@Àz+šÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:ª+•ÿ„HÿŸÏáG¨ÿñú?áÒ?çóÄŸøQê?ü~€:k¨VâÚX’!BG\Ч>$ðɺ…ÛG"•a¶!FðV/ü zGüþx“ÿ =GÿÑÿ‘ÿ?ž$ÿÂQÿãôi¿òTüCÿ`]3ÿGß×UXº†4ÝêîêÃíÏst‘Ç,·—óÝ»$eÊ(3;‘Î>ñ­ª(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+•Ó䩸‡þÀºgþ¿®ª¹]7þJŸˆì ¦èûúòßÚ?ÂÚ¤W‡Æúh’æÚÎÁmî­£”HÚI7•þ%>a€Ì{Cr…öîü Ó¼Sá_ƒúÍÖ¥jòjÒGOÓÜу”ˆ§ð‘Y¶õýçÍó–ßxËÆ:?„-­¥Öf5Ì›"†Ì’²‚7¸AÎÔ,~€e™U¶ šßP±ŽkYÒ{K˜ÃÇ4e]d2ºž„‚¸®©â*Ê„hËàMÛõüÎʘªòÃB„¾Û^½3Èï¼e®.©=ž…ªEªZ(ÓÄ—×j¶±Cæ‹Ã#y‚n†ÎÆ [iÃjå¼C5õõ®¯uâ}nÉã»¶Ñ Žæ5“O1®®èÒñÄÒ"¨Fs•Vó›øL{}÷MÒ,´Ù®&µüû¾l²Êò»…ÎÐYÉ88ÀÉõ5~¹N3Ëô««]ÀO'„õ/ L%Ö¬­Œþ±Ž e3\ÛÄáI /±ù9x¹ëæ•â~é¼A{#è:N¯ £Iº¬ò-¥Ò þùÎ>[uãfÿx¢€8K›ízËÆº¾’á/¥Žö;—Š0b·q¸ŒP ä@€X ޹\Ö7‹·\^xŠêußwg­è––ˆN?sö‹9F=7Êî¤ÿ°3÷EzOöu¯ö¯ö‘Œ›ß#ìâBÄívâÎN2@ÉÚ¹ÎÑ…[ eÔßPXöÞ<"1Tœl27u4ç> ñ>½á¹4»»1í­Äחד dŽTÙˆÊËIò•Éò±»=]y¯kë5•…þ§œ5 855£D[(cˆ›²¢dáC°e\´rÜNªŸÙÖ¿Ú¿ÚF2o|³‰ ¶=Ûˆ88É'jç;F<ëÄ?ðŽÿÂK¯ÿÂuäý£tØÞwúÏ'ÈLý—¿æùÙÙóýÎÛk*}OYÑî.îî®L^&Ò˜Áå«ý²ñZ𘜰ãç á½–ŠññOŠ-šò (é6–ÑÜß¼RÜžQ©ÝG°$vòHT!v;3–$‘{Çzž§ªx?Å–¿ÛwZ™‹T…4»{Ewh¢I<¢ieóQ·ž—jáö°õm3OµÒì’ÒÂ! º` “’ÌY‰'’KI<’I«TNÎ8.´h"’àjvÒÛª´òar¥~ómáÉÀžÎx2äŸZ}¯QkhྒΖṯÇxÑB¥œLб®~ñßÁ A®²x–xd‰Ë„u*J9FÁáqÍGago§ØÛÙÙBZÛÆ±E U~ËxÕ­¢×ô9ué"O,ws9Ä?i>_“æg»|ð7q¸¯|V&¿ª 3Oðõ–ƒª^i–7^yŠIœ+®ÈÃÎ×yÛBÌ£å#o>—Ey—…ãE|û¯Ý®¯¯èMãMSÁ Qj‘Áq¬B/­±Â†ql­(%ÆäÚäî#¬Öõ­GNÒõ·ÐõkXìt ÚjÖɧÛD-n[Gj‚¬,° [ ckIõj(ɾÏ©Á¬Úh®ÞÎw®ÜÜùÑÀdÌ:„"48Œm “³©_Ýjšnª»æÒ™m¥¹ÀS4»¤9 ` Åöy0?{ŽÕÖUM?NµÓþÓöHÊ™Úâf,X¼Ô’I=t0nŠ( Š( Š( Š( Š( Š( Š( Š( Š( ¹_‰ò.YÿØkIÿÓ½uUÊüKÿ‘rÏþÃZOþœmèWÅšGü$Öto?ìÿÚ6SYùÛ7ù~bÝ·#8Îq‘ŸZÕ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šå<áá#¢çËÑì4£ˆ|½ÆÛÎÌ¿xòþoNÛzœñÕÑEQEQEQEQEQEQEQEQEQEQEQEQEÊê_òTü=ÿ`]OÿGØWU\®¥ÿ%OÃßöÔÿô}…[ð¦±yªÝkÐêñ[˧ß-ªÇ-…kh&ù›øŽf# Æ9ÆNýU²Óíl®oç¶‹d·Ó ‹†ÜNùi<ž>HÐ``qž¤šµ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@rºoü•?ÿØLÿÑ÷õÕW+¦ÿÉSñýtÏý@[ûGø[TŠðøßM\ÛYØ-½Õ´`’‰I&ò¿Ä§Ì °hnP¾Ý?†Ö^(ð‡À¯Þê¬öÚ£Ey©ØÀàµSeRŒ ÆLŠï´çïüÿ1a^‘ã/èþ¶¶—Yš@×2lŠc2JÊÞá;P±ú–eVÒ»ƒNñ5¼¦+Ý'R¶hØÅ&RxdL®§¡Vàƒß ×TñeB4eð&íúþgeLUya¡B_m¯^¿™ÀOâëË/Ú™5d“ÃqÞ·š„Ñ$QžÞït Ä ¡eK^N’Ns_áíþ¥ñ ÄWÚŽ­u:OlVÖÖD‰#ò£Ôo£]  l¢,YÉÎf;óòmõj+”ãñOŠ'·ð½º&ÖÄÛiH±115ÄR[DÒ´pGnFi*è‰åòŽ}ªâ¸·–wyr)FÚÅNÁÁ¨æ›ekœ–q$6ÐF±E *"ŒÐx߈5]GYðž™5ω®¬oŒúuÞ¡gok6í° #!±îbCä·”îVõ~êæãÃw÷¸ŽkØ7˜¼²®$’';á$äJ4gº’z[5 ¥´6‘4vé±G”Œ“ó;cÏ«1?yuÿŠ5K«=.î=fm>×Y¸¸žÉ–80)aA$ˆà³‚d ±·Ùƒ—ðóÅ÷ â)/µ‹¸­¬5açÏò’^6¤´H§“¸«\m@Nì¸ítPŒxWÅþ0¿›@“験G¦oó¥+-âËoÍ"E »æi@e‘J|À(ÉÛÖ¤ðüºå”ž3¾²Ô<:úT ¦Þj [\NYüÙ Ddeò à­°šôÊ(Ç­®g³»ðÄú†£q¦(Ó5…‚îtó%Kswjmë‚rcXg?/ ÀÖt-ñP–è¬n™-Äâ[énmV †›`â# ‚]ͺY~òäˆÂ†^åUltû[ºkH„mu1¸™²I’B,IöUÐPe®jú„†ÛT×?±¯™­!‚+[/3íX#i%E•7ÿ¬y'•—R2+ká˜>øTOu-Ô˧B²<»w«„£;@åS‘»åù‰l“×Ñ@g†äŽÏMñu¡½þÏÒôë飷» €ZÄ`ŽW`\7’@7  `b¶<_g5ƙՒ3ßéÓ-íº¯ÞvPC ÷xÚDÿÖŽ™§Úév‚ÚÆ/*Í!‹fbÌÄ’I%‰$“’MZ ,Ô5ÑoªE®O«Ç£iZÔ3µ)#_•!-¢Æ?yæ\L2FsUôOêïaws¨ô‡¹Ö-#Ô§ŽÝY+é6ò±l©ù¥cÜá°Šõº(øM:Üø9§]ø—TÔß2FѱÍüç%¤õÚFGJì(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ å~%ÿȹgÿa­'ÿN6õÕW+ñ/þEË?û i?úq· ªŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹]KþJŸ‡¿ì ©ÿèû ê«•Ô¿ä©ø{þÀºŸþ° ªŠò¯üQÖþ€<·öð¶©áñ¾š$¹¶³°[{«hÁ%6’Må‰O˜A`3ÐÜ¡}½ÁM+Ä^øU©K¯1µ½¸–{ûXd‰ÜÚÆÑ©¡_˜eùŒe¾~~r½fŠè–*¤èƃøSº:ç«<ÖMVßRx³{o ¶ñI¸ü±ÈѳŒg&(ù##oN@<¡|e®¶­¦»Ö²»gÓ#¹Ò]"Eh0 NÖS+€Ó0E »pÅ~gC®ê¶«àXnu¯/QÔ%”ÞY-„M&›)²º?»‘ˆÙÂ\)þê}~Šñ¿ jzî›à/YÙj\É«iPXG,©=¥à+¿¢Œ”ŒÍò°?ñìe‹Õx–êò/ëW6¶ßk»Ò4µévÇ‘-Ä0|çB¹ê„Ï_s§ZÜßÙÞÏ{‹MþC8Bã vçÇ# ŽVk iµ ké#ÍݲºE bWÆå8<ƒµNFT Pk~%š×K&ÓÅ­2I=¼r^ XbÛ£‘ˆ3:˜1Eá‘™I y‘JãZøÛ^{MP¶¦M奖ë"2o®Rîö‚ ¬€§9`íV=>Ö=VãRH±{q VòɸüÑÆÒ2 gY9'w=<£Sñž»k¯_f^5üËq}nšK¤K´Åoq$Cb¯˜¥šÃ4„:¶å@Ë›ã­BëSþÚ°Ó|Bú“ês¬XF³G 6§ËYvÇ̹œùe}Ίà[UÕãñ6™£ZjM{k¨-½äì‘Öñ©ûGÜP§syÇÉÛ€£ú¦©=—ˆ5 ­#SûSϧøjÞ=CÉçÇ6¡qIò€‡r¹?(ž1Æ=/û:×ûWûHÆMï‘öq!bvÇ»qg' dí\çhźñ;ÍG_³øƒ¨ºj·ºŒú5†©meo$p*ÞÌ-¬ncöF2äÌßwiÛã¼ß¥¦ø§ÄMž©§%ƒÝÛÇ5ýœ†àÙ£C3±gkxãt…@*Å<Â[økÖª ÛHï!ò¦i•sœÃ3Äß÷ÒhÅÇü]so¾ÊâÂ8@¹hnu öæáÖþâŒD¶ò3â8âÌccüýIÉŸá­Bî÷]ñd73o‚ÇQŽÚÝ6±M¼§2rÒ±ç5¯¦XZév1ÚXD!·;Ty$’I<’I$“É$“Vh—?è¿"ŽÛˆïô¹f»QÓ|2ı1¥e”g¸Œáª-­5möÎk¡©YÜ›‹y˜² º¼Y@ÉÌÞ~b[$Ù‡Oµ‡Q¹¿Ž,^\ªG,¥‰%S;Tdðæ8bz“V¨ËumGS:lW¹7>xູ’<3ȱ=Ö:|–Í$Øäbaèj¤>)Ôî5»»)àÖÒ×KÖKºX£&ûË ]@ù|É$Œì¶ÀH$=vŠóß_ÅãϼZŒšžÍ+MSvðyAÏ›xH(HÈÎ>é;”סQEQEQEQEQEQEQEQEQEb]Þ®®D×:‚"˱ÖÐÌ„çllG-ßúV&y|6›å–U]{GeM´ÞÚ6ÀÁËÍu¯bÞ|ÒEyqšÁ™P!Úu' ÌøþÛìÞ„™d•å×4—f“nsöûUì袀;*(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ åu/ù*~ÿ°.§ÿ£ì+ª®WRÿ’§áïûêú>€: }:ÎÚþòöÞÚ(îï6}¢U\4»qïÀ®Oâ†õ¿[jV¶Ñ-Þœö‹ “`!m8i8l‘]µçZ†¡ø·Sñ$n$ºžo*Ý!š_ÜÉme±=ž@<o¼qVÇÀº—ü!°éà‰¯ü3g Þ‰œî·$Š]6‚±;ŒUy¯O¢€8­C—×ÛÛ%¶oñªÅ–n"·ûõn>ñû4˜#•É8O xRÿH}ªKV]DŸIÆìLŒZ×c¨*8+năаwZí¨ /ð¿ÃýWJðZéصÈÔ4{­ÈîSe¤v ÉPrM¤›xç+œdã¶Ð4©ôí[Ä·S¼M§¨%Ü! %PZÛÂCdpwBÇŒðG¸TPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\þ³á+WÕ[R¹:”7­ [´–Z¥Õ¦øÑ”0†E ƒ#à‘Ÿ˜×AEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEr¿ðéóùâOü(õþ?Gü zGüþx“ÿ =Gÿ×UEyϼ5§hž¼»²ºñê ¶ 4oj=ÄŒ GŸÈÞËŸlÕOxJÞ{í;[Õ|Iu«éWOkq?ü$ñ™—‡ŠM«0tn™ÀÆwÕÑêßñ9øƒ¥iÃæµÑá:Àìf}Ñ@§ðóÛê¨}(ÔâMñN¾-®·ÓçôÄHOâ¦uϲJ“þ=#þðuÔÖ·ž,ðü0;G,RêP«ÆêpUl‚ ƒ]-r¿ ?ä\¼ÿ°Ö­ÿ§Š?ácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ®ªŠåácøþ‡/ ÿàÒþ*¸Mc⿃£øÍá»UÖ¬e¶þɽõ®¡kHžY!uW“~âÕÆ=^>»Ž=–¹_‹òK+±½Ó|-}W"/lû e]ɺÚKæsÇÉ3ɹ¥ºñ~‰¿›m¨[_‘=¤ œÉ+'ÚeH¢f¸RdSŸL‘ž”Sþ_þ„Oßý;ÿ’¨ÿ„£Wÿ¡ÄŸ÷ÿNÿäªÓ¶ñ•1d’úÒ „ÒCåIsrRI8V=L2:¬ ¬?xÓEд¦Ôï.ám8XÍ~.#ž"®‘˜ÆËT.ÐFH‚ÊøJ5úmfÖæ=BÏzŲ‘%ó¤g¬hAÁbä.3ÔÓ ñV—<ÚRÇ)òu>]N‚TD!ŒÂ bOùèGn$q _ð”jÿô"x“þÿéßü•Gü%¿ýž$ÿ¿úwÿ%VÇöþöf¹þÖÓþήËö”Ú¨p3œgk+cЃޫë(Ñ´˜f’ïQ²O!N­wffK¾öPFǜᗖP@3ÿá(ÕÿèDñ'ýÿÓ¿ù*øJ5úÃk·›³fýŠìdã8é“ZµÍ|5¹žóÀ: ÅÜÒÏq%¢3Ë+–g8êIäšéh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+•øiÿ"åçý†µoý8ÜWU\¯ÃOù/?ì5«éÆâ€:ª(¢€ (¢€ (¢€ (¢€ ÅñˆôýNÔ§šöÈ\YZÉrÐK>Ó„Ÿæ ¬àaIÈV8€zVÕpZÏÃÏ·IâCmªy)­Ù\ÙÈ%·óZ/=0Y[p<0SŽê“…`î¥ãN»¸¶º¸¸ó­åJ"³šP²WTÊ!˜:…Ë1Ú¹n*–…ãíRðΕ¬\<¶K}gëE,2fn79Ûò¦r‡ ÀnŽi÷žûOöÇúnßí fËWÿUŸ/ìÿeýßÞçwÙ~÷ßÐãžxü&Ó¤³Òâ»m6ök2 %f½Òâ¹+ ,Þ[F$,M®A<«¼7åkfªïçåÜ+GJð ö›áë1nàΩ¤ÝÇ<ŒÛžD±WÝÇ~Ë!‘ó.HÉÇUçÿÔCYÿÀþÓGŸÿQ gÿ?ûM¾½ÒÿáKç´’=DŸJ“c3yŽM°IòBø†Mcx7áæ§£ÛhQê3XLÖWÖ÷3”fmñÇ£­™Q•>rïàmç¯ÚyÿõÖðÿ´ÑçÿÔCYÿÀþÓEÀæ5].ãCøUá]&õã’êÂëAµ•ã$«:^Z«$FAÆ@¯D¯?ñì»´{öÍNOøi_$Ö›ÿÄÂß«ycz0 (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ÏÐ5X5Í×R´IR …Þ‹(€Î9Á#·­hVW…tìÙi~Ú>Ì›<Ý›7rNq“޾´«EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\¯ÃOù/?ì5«éÆâºªå~ȹyÿa­[ÿN7ÕQEQEQEQEp>5ñf£§øš-#J”@#´W`Þj¼»•vÛ²ìÿW!Ëp1ÐÐ}Esz7‰áº–ÎÂmòê.÷1LcˆF‹öwò䔩vÚ…¶í˜ü람Ýǰjº"jVÖí¬‹4‰q ºGÊ"ÆKHB¶Ð»›ø%IÚ;j+Ït/ˆR_6‹oy¥ÞE«Ýé)¨M¦G<ƒq 2¿›µWä~gç%[*vWÇ:Ld`3Aw”ë: ؉vìÉÏÌê$n $u4W#q⩇Ž,ô›x#m5¦k)®;¾Õä<áœ|±¦O%Ç#iŽñ ®õT–Öyá·Õ³c’ÕåÖ%G,Ã.dÞÜ Ûœ7w”W;¦x¿MÔn8–â8¦µ–öÞâD;ˆceWtç8ÐòC2+™Õ>$Μš.‡¨Ýùßbo³¼p£ÉÌ€$ŠÍ0 “ ¤d¶ÒJ ,@="Šâm|yrk©ÄñÛY‹Ë›y"N%‚Õ–9y-ˉ ÇÊHlhÙxÆÊçW‹NkKëyäºk<ÌŠfù᜘²þÝk`PKEPEPEP\¯Åù%ž2ÿ°-ïþˆzê«•ø±ÿ$³Æ_ö½ÿÑ@Å„µoêP¾Ó­¼g21e½žR·ñöV1ß ö©>"xÏF¿øqâûg“OÔßF¼ c¨Äm¦cä?Ü €ÿT,=ëÓj¦©¦XêÖOiªÙ[^Ú¿Þ†â%‘ê"€2´½Q²¿ŠâçÅšÞ¡guµÌVkäɎ݌熜ŒŠ›[ѯµ¤–Ïĺ¾• C œv¬ŒrNâe…Û<ÁÇŽ¹Ú¢€3í¬.aÑ”šµô÷%>ß"B'³†ÂÆ#ÊäcäÇ óœý/AÔl¯â¸¹ñf·¨D™ÝmsšÆùrc·Fã9ᇠg#"º ([ѯµ¤–Ïĺ¾• C œv¬ŒrNâe…Û<ÁÇ޹µmasŒl¤Õ¯§¹(éöù8-œ61W#&8œèQ@þ— ê6Wñ\\ø³[Ô"Lî¶¹ŠÍc|‚91Û£qœðÃ3‘‘Skz5ö£t’Ùø—WÒ£Ta³ŽÕ‘ŽIÜL°»g88àq×;TP}µ…Ì:1²“V¾žä£§ÛäHDà¶pØXÄy\Œ|˜àdsŸ¥è:•üW>,Öõ“;­®b³Xß ŽLvèÜg<0ä ädWAEbëz5ö£t’Ùø—WÒ£Ta³ŽÕ‘ŽIÜL°»g88àq×6­¬.aÑ”šµô÷%>ß"B'³†ÂÆ#ÊäcäÇ ó (æ á_ˆ<ñ¶ÛÇ:½Ïö®‘>§xÌÖ6ó]]…šÊÉ,PÂÉ* Àféî¿ðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]UÊÿÂy¤ÏŸ‰?ðœÔøÅðžióçâOü'5þ1]Uç^-ñ%®½aa§é– {—Õ´Ù?{¡^Š‘ÞÁ#³;Ä@UbI#¥z-PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\×Ã{™îü§Ow4³Ìþfé%rÌq#’yè+¥¬ýUƒ[Ò㿵IRÐ ”vCОêhBŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹_†Ÿò.^ØkVÿÓÅuUçþ°ó´{ù?²tËŒëZ¯ï&|;ÄÂã¯îÏÓ­z…ý—ÿP-þûÿíTeÿÔ Fÿ¾ÿûU+»EaeÿÔ Fÿ¾ÿûUÙõÑ¿ï¿þÕEÀÝ¢°¿²ÿê£ßýªì¿úhß÷ßÿj¢àn×5'…¥ÿ„’ïX´ñ¯f×f?:Ö$¶h˜"í/ 8Nu'¦jÇö_ý@´oûïÿµQý—ÿP-þûÿíT\ X«ëòE-Ìsë(c–TeÝ •+ˆøã’ÏÎ~f=°K_é–ºF¡¥[\_Ŧ^[Ü[ý•'Äp¬ä´…x³ g `*÷ö_ý@´oûïÿµQý—ÿP-þûÿíT\ ë¿Y\êÒjcPÔáÔ$È’âY )´?s ¬cWùpÁ‰*W¥Y‹Áz\7QËŸGqo:B¬¾Zˆ"ò⌠gbýð3ÜçUì¿úhß÷ßÿj£û/þ Z7ý÷ÿÚ¨¸Ö_<=g}a¨Aeë·åµ1bêåØ86@¹`ÛÛ `tÆÅcxkÀzV­{ˆ¿²á½7ÌVf¼FcäM +°± Uš0ÁS8Wö_ý@´oûïÿµQý—ÿP-þûÿíT\ û/éÖšUÍ‚]ß¼rX>—nîèZÎÙ†<¸¾\0¼°bv®IÀ«_ðˆiëªE·I(éÛ>ø¹ÿ±´˜öégz?Ì¿¹~GîÇ?ˆ¢àuzïŠ4m Ò-Nþ(îdŽÕ–y܉vü®WÅž/ñ5¿…µcDðòYÛXYMv'ÖdØÒжËsãd#Ò£x+RðoœÞ¹±»†V-%¾©Y¤?õõî?YCïY¿<\Ὴìµý#QÑîæÒnâ¤Î·‘Ú,ÑåFIØO¥0=NŠçô¿ iÚeüW–×:ÛËv­Î·yqÈ#˜ä••º÷rM­øjÇYºK‹ÉõxäTg«]Z&'”ŠERy<‘žƒ< Ú¢³í´‹kméqÉ|mŠ<{佚IðÙÏï™Ì™äàîÈã`V~—á-;L¿ŠòÚç[ycÎÕ¹Öï.#9s’²·^àààŽ@ ‚ŠÅÖü5c¬Ý%Åäú¼r*À³Õ®­“ÊE"©<žHÏAžZ¶Ò-­´c¥Ç%ñ¶(ñï’öi'Ãg?¾g2g“ƒ»#Œ@W?¥øKNÓ/â¼¶¹ÖÞXóµnu»ËˆÎAÇ$¬­×¸88#*moÃV:ÍÒ\^O«Ç" Œ =ZêÑ0 <¤R*“ÉäŒôàPÕŸm¤[[hÇKŽKãlQãß%ìÒO†Î|ÎdÏ'vG#³ô¿ iÚeüW–×:ÛËv­Î·yqÈ#˜ä••º÷rtV.·á«fé./'Õã‘PFž­uh˜žR)IäòFz ð*Õ¶‘mm£.9/±G|—³I>9ýó9“<œÙ`Œ á|o©xWÅ)𗇥½Ñ5‰cÖ¥û^˜ÒÅp˲Æì2,œm}½Gë ÿ…qàú|7ÿ‚¸?øšò]àÚxã^ƒâ¨µÙocÔõkÈÖÒXX¼BKK©éšFiÙ‚HËg$×­|Xÿ’Yã/ûÞÿ臠þÇÿèMðßþ àÿâhÿ…qàú|7ÿ‚¸?øšå<}}¡øî_ éú«á­cÏïRUMJÝ?Ðo|È–EÎve‡#<ã[A°}×ïx–ö¦ÃÄ“=ü6°y–9±žò“'dL^'ž³dã$ÓþÇÿèMðßþ àÿâhÿ…qàú|7ÿ‚¸?øšó? >öá¯/®´8tkß #»Ö Yì]SF1neg@Ã̉•NáóFz©õI<9àûÃS蚆š{o/D¶H,å–Fa C¾ßß…Œ€ä•‰éÀEÿ ãÀÿô&øoÿpñ4¸ð?ý ¾ÿÁ\üMr6:¾¥aâ-_MÔuhì­cºu¹ÕÖÖg™4û¡¾M»œÉ3d‚qA€-©jú^¥©ÝÛ^Ë­jRk&æÞÚêÎ8÷Ä‚YÇA$A¤_/®qRI2ôÏøWÿ¡7Ãø+ƒÿ‰£þÇÿèMðßþ àÿâk’¶ñV¡©kúv›£xˆ_iwwpÀuH!„így$°”®TÁ r S&8 ®§¬ê:¿„ôí&KK­fòçU»µ»ŽØE³ÙÙÝÉŽw²F7쉕½;GA@gü+ÿЛá¿üÁÿÄÑÿ ãÀÿô&øoÿpñ5æ>ñ§oâ í¯¤ŸL¹µ´Ó4½VæqËhˆÚ“$Ñîp Éù”yÙç}<}«&îiu1 ÊÇtúTRÛ,oªÎ—×1-¸FPÀ„Š´ãÍÉ<ïÿá\xþ„ß ÿà®þ&øWÿ¡7Ãø+ƒÿ‰®kS¾Ôïüu¡Ô^x|Dúl –ð;B­¢´þb3ÆÄ8vlFe!”â¸ÿ ÝêZ_ƒo5[-^çíÚG‚´ÛÙ ‰™¤ˆß1·“)«+Fq‡ã–Ü «ÿ ãÀÿô&øoÿpñ5Í|Mðƒ¬þx²êÏÂ~‚æ &îH¥‹M…^7X\†R ‚V^­âïÛiú¥ä:™ M~ö8Ì?³ïDq§ÝÎ\+¸QŒ6X÷??ä–xËþÀ·¿ú!誢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¬¯ éØZ,:Ÿçùo+ù›6ç|ŒøÆOMØëÚµkšøus=ß…’[©¥ž_µÞ.ù³aneU=€@t´QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEÊü4ÿ‘róþÃZ·þœn+ª®Wá§ü‹—ŸöÕ¿ôãq@v­ñšÊÏÆ“X[ÚÆg³¿ºL™’u8b‘ŽJFA}æÉ*Uúµ¥Ì–°ÝYÍöӢɱ8d‘d2‘ÁAà¿>ßë(Šë—ÛØj·NÚ§žç6á·ÈîYQœ“°C1ˆÝ¼¿Dñ/ƒîWÁÞÐt;»Õ²Ò¤‚)Df4öñÂÑûÔ11Ücbpvœ`ãXaÉc{ÛÞõ;1_Vä§ì/ÍozýüŽîªêÚ…®‘¥^êZ„¾M•œ/q<›Kl³IÀ€3^n<©eh¶j.”{ T\Ï’ _<Ì¡Š*)‡„*.OÆBäáxÃÁî úü–"­íØÔ¢7 $#í1Kkr¯˜Ïæ°ÜÐå_«´^SŒöú­w}mi=œ7ˆå¼”Áxâ7¨ÿ€Fçð¯2¿ðïˆ^Ú:ÛKÏØõ}WPŽéî•"”\Å|bc‰ rŠÇår>a—£ü>ž?躓øf¬lní®)"´G¼»Ä‘ÂÆÅö’ cå©Ë2…Pif ¥˜€ d’p¬MÅš6·xÖºuÔ.Ã$~e¼±,è ÄΠJ¼™ G<Šóß|=Ö?²um?U¿ÔÍþ‹>›qw4–Æ'šN<ÕH£Y3•÷ÅyÉ#OXÓ¼aâ+†éqáß³Ø\[âGµš 'x¤DxTÌ 3+-£aÜÄzÝõµ¤öpÜJ#–òS AýãˆÞB£þŸÂ©ê> Ó4뿳^\ìŸ0¢6m¦i„1d€@Ý#`gОŠHó-/áåÄ:ö…©]é·7¢ÇR†r5²g‰E¼èÏÃ(Änʼn.ÞJœ‹oM»»Õ ¼Ö´é·ZÚïö‹C©Ïr¡Hm—o$”&% À*˜Ãƒ¸ õIåX ’Y”Kˆ]°xP 'Ø Ó,n࿲‚îÎTšÚxÖX¤Cêà ¨5 ŸÙ¬4h1o›gon¿¸;m‘Wîü§h 88ãŠæümÿM¡¹Óžê)碌‚ÙÑwE—, UÈËF±÷†Î`tòß[E¨[ØÉ&Û«ˆä–$*~eB¡¹é‘½xÎO8èpZ_[^Mw´›ÞÒ_"o”€¯µ_#‡^™ôê¬ïY\\YCw§B&Ô´ù…Õ´{‚ù„¯Oz3¨'€XÕÂø‹Âz¤ðÚY6¡q{§ˆ ¼ŽdEÓ¯ÚYd–è‡`Ø-"°3\`ЧÛ\%Ìeã…ñâHÚ3•b§†ã àô#5“¨ZêúUž¥§ËçY^B—I´®øÝC)ÁŒ‚8#5ç°øoX‚;7›LŽú(¯µ‰~Ã%ÊÆ»ç½im® s€©» ,¾f@ܸ®»À7z_<9§êQˆ¯­4Ûh.vȱ*°ÈààƒÓŠÞ¢Š(®WâÇü’ÏØ÷ÿD=uUÊüXÿ’Yã/ûÞÿ臠ª‚h¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€9»G®øÒ'™†µ&ÿľóÔú×AöëúÞÿßPÿñÊçüsÏ®ø7.ëRd£”?ò¼î"ºì«ùé{ÿ“ñT€>Ýqÿ@»ßûêþ9GÛ®?è{ÿ}CÿÇ(þÊ·ÿž—¿ø7ÿGöU¿üô½ÿÀÉ¿øª5ûuÇýïï¨øån¸ÿ ]ïýõÿ£û*ßþz^ÿàdßüUÙVÿóÒ÷ÿ&ÿâ¨Ôí×ô ½ÿ¾¡ÿã”}ºãþw¿÷Ô?ürì«ùé{ÿ“ñTe[ÿÏKßü ›ÿŠ£P·\Ð.÷þú‡ÿŽQöëúÞÿßPÿñÊ?²­ÿç¥ïþMÿÅQý•oÿ=/ð2oþ*@¯zò^CåM¦êj¹Îa¹H›þúIA¦ét»í,4[¸mãÎÕä’I$É’I$’y$’j×öU¿üô½ÿÀÉ¿øª?²­ÿç¥ïþMÿÅQ¨Û®?è{ÿ}CÿÇ(ûuÇýïï¨øåÙVÿóÒ÷ÿ&ÿâ¨þÊ·ÿž—¿ø7ÿF n¸ÿ ]ïýõÿ®[â­äíð¿Æ ÚmÚ£ÞÌÑ`~áù8|×Sý•oÿ=/ð2oþ*¹oŠºlü/ñƒ¬—d®xFë¹X¨~ ¶ ÛÑEÀ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š+?BÕ`Ö¬ ݪJ‘‰ç·Ä€º)^&èOãÛ:V…exgHþÃÒÚÏÏóóuss¿fßõÓ¼»q“Ó~3ßã¥jÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW+ðÓþEËÏû jßúq¸®ª¹_†Ÿò.^ØkVÿÓÅqÚ·Æk+?Maohn4KžÎþé2fIÔáŠF9)÷›$¨!TKêÖ—0^ZÃug4SÛN‹$RÄá’DaÊGAW‚üPø#¬x¢+¯ \CoaªÝ;jž{œÛ†ß#¸eFrNÂA Ä#vòýľ¹_xoAÐîïVËJ’¥˜ ÓÛÇ FïPÄÇqˆeÁÚqƒŒub=‡$=ïo{ÔìÅ}[’Ÿ°¿5½ë÷ò;º««jºF•{©jù6Vp½Äòm-²4RÌp'Íy¸ðF¥ý•¢Ù¨¸hnQì5Qsæ=&îâÞòû[ÖëO¸y/’X­.–q ìHãòÓæ~N9”—ÖÑêPX< ^O“ÇY#(®ß‘ü ©ÙøƒL¼Ô–ÂÚç̺a9U¶@ñ¤¸lm;ZTSÏRGð¶8Ï xcPOŠ—Šï4ÈìEê\FÅÚ6˜£C§,JÅ ÈÞãŒàqw/CÔ/4¿ -½˜ºmOŸOÕ#gE2N·fHØ1ë<™=<8ȯÑ^mªxKW¹øƒ&ª÷:“Ú›ëYí„[$PˆыÆÓ ²¹*ŒĘ;y4žÒxŽy¤µÖz5Ôº^—2ª´CæI#©chíŽÜ¶b Œn ­µñn‹uª> ·iÚF…ÛȰÉ"çr$Å|·aµ²ªÄŒ8«¶úŕΙs¨[<³Û[¼ñÉåBîûávŽETsÈÀ8ã9ÄiÚ.´4³émLöŒú±š3ÑÛH®¥7™æ?–¡ƒ({|Íß—ñ§†õ[ëçû?ìÒÿÄîG¹«5ÜW?j[„RNYæ…À镘oª×wÖÖ“ÙÃq(Ž[ÉL)÷Ž#y øn òÙüâ7Ö5{˜uI/§mDÛÝùÖËoÌ’yí³t+>ÐcÜjìþŠë_ðæ¢ž·µ]3PŠgó&ŽWÛöyº©%FÙ,÷òÁ#(™ôMCP¶Ó’¼—ÊI¦HŠ’7¹Â‚@ã'’R*ÕrßÏ™àmVÎ?øü¿ˆÙÙ¨ûÆâO–2?ÝbžÁIè oÉgU·Øï•a•Vój~éKG˜òNïŸ pºä‚ ºÏŠô}óì×÷2,ª‚Y<»yeXç+"‘ð~g pyâ´ Ô­'Ô§°†`÷pÁË 9ZEFÏC“nzŒóë6µ¯É§è­«Å¬J—È'‰$%%Àùº ”~vù}y›ïjÖÖ²XYÛ}²DðþŸ¥Zj&UCou ¸hÁ;¾]èÞ¼àgsàÕ-®æ2ñ‰B‡xñ$mʱSÃqpz‚ S¾¶Ó4Û»ûùD6v±<óJÀˆ ³1Ç ׊Áá-_]‚{ÛkOìÏöD³–Ú-ŽÚÔ‚bÓDì‘â`ñ|ØN‡#ž)ðMæµ ø‡MºÐà¾Ôo´ZN{•‚Cl»y$¡1(VTÆÀP«ÑU´È¢ƒM´†ÞÌXÃ(‰jªª P IQ´q…$qÇf€ å~,É,ñ—ýoôC×U\¯Åù%ž2ÿ°-ïþˆzꨢŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÊñ§ø‚Xõ%¹ÿE›íImw-´‘ɱ“!âeaò»Œg1¬¯ø@ôùüñ'þzÿ©|i©j¶sø~ÏCšÆ SPkFšòÙçHÑm§˜‹$d’aïw=j/°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÃãú|7ÿ‚ÿù2°øãþ† ÿà†þL þ=#þÿÁ ÿü™GØ|qÿC†ÿðC?ÿ&PUEsþÕ/µ›U­šö+ÛË9Ú&Š7ò.¥„0Vf+‘8Üy'šè(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®káíÌ÷^yTÔ¡ß#–;RötQ“Ø*€`íYÿ¤¾¹ðÇü#ÚU½´×¾$óôˆÞæá¡Ž ö“¹•G'#òã’G"¼×à_Ã|+þÛýφõ_í/#þbsÁåù~gý;6sæ{côïôW+öïнá¿üOÿÈt}»Çô/xoÿÓÿòuTW+öïнá¿üOÿÈt}»Çô/xoÿÓÿòuTW+öïнá¿üOÿÈt}»Çô/xoÿÓÿòuTW+öïнá¿üOÿÈt}»Çô/xoÿÓÿòuTW+öïнá¿üOÿÈt}»Çô/xoÿÓÿòuTW âøÇAÐ5=^óÃ~{m>Ö[¹V-vbì‘¡b@3€q’+º Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹_†Ÿò.^ØkVÿÓÅuUÊü4ÿ‘róþÃZ·þœn(ŽÕ¾3YYøÒk {Cq¢XÌöw÷I“2N§ R1ÉHÈ ¼Ù%A ¢_V´¹‚òÖ«9¢žÚtY"–' ’# †R8 ‚"¼â‡ÁýcÅ]xRâ{ VéÛTóÜæÜ6ùÀë*3’vf ·—èž%ð}Êø;Ãz‡wz¶ZTE(ŒÀfžÞ8Z0?z†&;ŒlC.ÓŒc«ì9!ìo{{Þ§f+êÜ”ý…ù­ï_¿‘ÝÕ][PµÒ4«ÝKP—ɲ³…î'“im‘¢–c€ 8ðkÍÇ‚5/ì­ÍEÃCraª‹™â’Akç™”1EE8Pð…E‰øÈ\œ/x#]Ô_’ÃDU½»”Fá$„}¦)mnRóüÖš«á±µv€ËÊqžßU®ï­­'³†âQ·’˜ RïFòðÜþæWþñ ÛC§[iyû¯ªêÝ=Ò¤R‹˜¯Œ@lq"á®QXà0<®GÌ2ô‡ÓÇâ½R ÁݵÂÅ$Vˆñ·—x’8XØ !ÞÒBA,|µ9fPªì¶¡k¤iWº–¡/“eg ÜO&ÒÛ#E,Çpà Öv‹â3Y»kKC}ÐŒÊ!½°¸´v@@,¢dRÀPHÎ23ÔW˜Úø ÄxOÄv³É©_j—~º°fž{U†æåÔ…*5vÉÎgʇ#œ’:™¼wcq¯®‹wzÒjT¶öW·×ó\Éa9Ú­+³c±øïÉû zäzG/ãÔ´Áwoq¦ý¹$»ŠþkB»•ÜlDpFŠAybRNæ~2^M#Â~"µðìн³­ÌÚFŒ×q}¡suw ’5äeƒcsÆ#Œ¾pA^p¼zåå²øg]}.â÷I³m*öKùE“Ék;YáHd«‘~ÓµXýУ“Wþø>ëÃZõãN×’[ƒÄsÍ%¨¾³Ñ®¥Òô¹•P­¢2IK€Glvå³cqÓ´]hh:…gÒÚ(4™íõc4f9£¶‘]J(o3Ì-CPöù›¸oo¬Y\é—:…³Ë=µ»ÏžT.ï¾häU@71 ŒPsŽ3‘Zâ4ðÞ«oàý|ÿgýš_øÈ÷"Uf»ŠçíB pŠIË<и2££3©?‚gµ[8ÿãòþ#gf£ï‰>XÈÿuˆb{' 4ÔÕX5 Y罆9‡™dâ;€À®ÂQ\uê6°9uA’8Ϋo!±ß*Ã*­æÔýÒ–1äß>à?uÉ.yÿèwWššµŠ)¶Ô¡‘ß´ˆA,{í2ÇÇ9•OE  ØuKYôTÕ`3KdöÿiBHÒ2Ü1É#¢¸ôÆiúž¡k¦[$÷ÒùQ<ÐÛ«m-™%‘cŒpWuè3“Íy/м#â ý?\±²ÒœÞHš©þÑóâ { ðN°Z¿pÚd€|ÁTy9šÚñG‡u›¯\Oo¦Ç{çjúmÔW­p¨mm"’ÜË©äÑÉ&8~s¹UH¥W+ñcþIgŒ¿ì {ÿ¢ºªå~,É,ñ—ýoôCÐUEck¾(Ñ´'Hµ;ø£¹f;TYåÿr$Ûð¹_x¿ÄÖþÖuÃÉgmae5ØŸY“cH#BØX-Î?Jô:(¢€ (¢€ (¢€ (¢€ (¢€ (¢€9_ÈÇàOû Iÿ¦ëÊÐñ¾«>ƒà½W³HžçOÓî.âYA(ÏlÀ0d àŠæ¼Eâ=Qñ¿ƒtÍ?YÓnõ+mj>Ò ¤’h¶Ø^+n@r¸bÈàœW_â* {@Ôô‹Ç•-µ Ym%hˆ©"%Igã Ð!mâ]j¶¥sumw¿S°±E} ïLdY®¢ŠBRy ?Ë/ÊÀ9ÝÈúWŽuGoê:ÄKÑŸRymcÐn¼6ÒËí¼i<—s±X…R~ðÀÁ#¿×4¨5›(ínžTŽ;«{°c ðÌ“ ä FöÏNµ ÙXézfÖ¸´ºšêiR|6ï´Jòȧ|¹‘€˜ÎzÐ=¦«¯éú¶‘oâ!¦¼Z´Ke£[L"yv33 ÛŸ8 È/<`|8ñ®¯®èÑjš«‘&–/ͧ‡/->rªÛ#¸šC½Hq»†kªÒ<)Ÿ}ms>¥©j?dR–qÞHŒ¶ §nÕŽÞ79fÁ#<œ³Áޗö¶qxƒW¿Ó­mVÒÞÒñm¶DŠ) (䀸åSœœŸ¨|AÒ­î-&uÓË+OtaF³žë·‚¤$*äín@1d5/]Á®xvÂê¡u+Ño,“¤h#Co,¡2rG–IQ’ 1Œ4ßð¯t6Ó!ÓÝ&{8îçº1–\IæÁ-¹°>âÅ1ENNnÿÂ)ÝY]\jš¥ÅÅ•Äw0<³+l+‘mÛ·n%1Æãwd)¾ñõŽ¥¤éWN—2%ÊY¤÷Kn#Š)îcãF]ìT·›¸b‚Ç9«Þñž¿5ŠCg}j/ìF£f÷*n!ýÞâ»]ˆ*eŒÀgp+¸sTt¯‡zf˜št×Ú—Ø-Ôµ›ùšŒFöi Óí,ZÊÊ®ÚV¶t2ÆcÊ*§–ÖèW!‰àB@ ž1´Qkc~÷Ï~úoØÂÆ%YÖ¸ÚrápcPAÝ™z ‘ÈÛ|JÔn#…¡ÒÙ­ÞÇC½[É#DYEíÈÀffRWvÅÉÃ#d‘°¿acá Kilg–òúêòÛPmMîfdßq3[½¾d p#|¡q±}óJÛáö—mi§ÛÅs~#³µÓ­΄ȶ3  -òõݸ`çŒí ;ˆÚm¯ÚRòÃR·¸´Žâ[È#-lFr®T.æ'ùKpHûß)è´-f `_a¸‚k+ƒm<3¨VGØ®:0RDaÏFç aê¿ô­N÷\ºžâùdÖ-n­'è¥Ä6йL©Á iÏ%³œ€7ôÍ* :÷Vºåi5;¥»˜9+ˆb„Ààm…O9äŸ`1~ȹyÿa­[ÿN7ÕW+ðÓþEËÏû jßúq¸®ª€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€9_ÈÇàOû Iÿ¦ëʛǾ)‡ÂZ,W²›!$÷1ÚÅöë±kæ<—”«mCºsŒw¨|eÿ#?ì5'þ›¯*ÇŠ4MKSÕ4[í/R³´m:I$1ÝYµÂ»:lÈÛ,eHRã<ýóÅT³ñÞ–<=aªjïö»óYUξ\lCLWýNq#]®¤ã8­y|I¤Åª¶-ê%Ú±F ¬\Gæ”/¡¼¿Ÿns·œb¹{‡m-´6¿Û3›<îž+#5ËO6`I¸¡6Ðn0wMªøçVÔ57½ÖBÙ_A=¼‰okåO$rÆèIìu@ãiòà ‹–?6à yü_¥ >îæÖG¹{q T(ò™›d!w€vùU¾é9çƒKo®^ÙX^]x«OƒKŠßaY-îÒK¸à*á÷çhC’ʱé¤ü<±°Ðîìã]2Öæâ{{“6™¦Ef‹$,‘‹’ØuÉ Ç«câ¯ÞxkQ½%ν?ž÷1ÊÉ2A墰ÃärÛËnÉe\åFÚ³/Œt¬#½’ü-»¬ŽO•&èÖ6Ù!‘vîŒ#|¬X ¤`â‘|Wd¾'¼ÑîJÁäTØí’SJéÓ V0¯Éɰ0„Öv๴9¬d²ÕÝY- µ¼&ÝI¹òä’BË’D{ÚgÝÁã ŒÔ:Ãøµ1x—ú„ÛßI(Ž=­ºâ!0981ÔéÎsÇJןÅúPÓîîmd{—·âB)™¶Bx‡o•[x5ZïÄZ¾—¡jWÚÞ‰oo=¸O³Çÿ›ûmDÞQY[qPr„|ùÅ'á冇wgé–·7ÛÜ™´Í2+4Y ‘dˆì\–îHf=[£?†nïn"›SÕÞãÐݼ+HvBÇ&ã´ù…\±$ tÆÐ ®üg Úiö÷·Å-ç2ío"BPDvÊΡs¡v`žŠmïŒ4« VþÒúê(–Ñ;#2¤,aUVXX¶ã€ä¶Ð¹8rü<–[ ;9u©^ÝÌfvóÌÓ°Pø_7s)Îì `Œκøyö»½n{S{jã}ŸîÅ$ªeO½Îèb†,öò÷`çhÓø±ÿ$³Æ_ö½ÿÑ]Ur¿?ä–xËþÀ·¿ú!몠Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹_†Ÿò.^ØkVÿÓÅuUÊü4ÿ‘róþÃZ·þœn(ŽÕ¾3YYøÒk {Cq¢XÌöw÷I“2N§ R1ÉHÈ ¼Ù%A ¢_V´¹‚òÖ«9¢žÚtY"–' ’# †R8 ‚"¼â‡ÁýcÅ]xRâ{ VéÛTóÜæÜ6ùÀë*3’vf ·—èž%ð}Êø;Ãz‡wz¶ZTE(ŒÀfžÞ8Z0?z†&;ŒlC.ÓŒc«ì9!ìo{{Þ§f+êÜ”ý…ù­ï_¿‘ÝÔV× sxÄ¡C¼x’6ŒåX©á€8È8=Á‚ yðF¥ý•¢Ù¨¸hnQì5QsÒÞZ3å$œ-ƒû¾›B“ÁiÚ.´4³émLöŒú±š3ÑÛH®¥7™æ?–¡ƒ({|ÍÜ··Ö,®tËBÙåžÚÝçŽO*wß ´r* ˜†F(9ÇÈ­ ñxoU·ð~¾³þÍ/üNä{‘*³]Åsö¡¸E$åžh\™QÑ™€ÔŸÁ#}cW¹‡QÔ’úvÔM½ßl¶ñ¬É €qžÛ7Gò³í=Àð€=JîúÚÒ{8n%Ëy)‚ þñÄo!QÿÏáVkÌgðtWZÿ‡5ð…½ªéš„S?™4r¾ß³Ì…ÕI*6ÈÐ1`w¿– DϧPEPEPEPEPEPEP\¯Åù%ž2ÿ°-ïþˆzÐÔmÚmNc•ä« X[§Ø“$ÏŒW1ñï+Û[ÚÈ|?pZ;vÜ€ùsó«ží@à­KÁ¾sxBæÆîX´–ú¤!fÿ×Ôk¸ýdY½füLñpO†þ+²×ôGG»›I»Š6’?:ÞGh\³G•$a>•êt Œƒ@þ—á-;L¿ŠòÚç[ycÎÕ¹Öï.#9s’²·^àààŽ@©µ¿ Xë7Iqy>¯Š‚0,õk«DÀ$ò‘HªO'’3Ðg[TP}¶‘mm£.9/±G|—³I>9ýó9“<œÙ`Œ ÏÒü%§i—ñ^[\ëo,yÚ·:ÝåÄg Žc’VVëÜÈÐQ@ºß†¬u›¤¸¼ŸWŽEAzµÕ¢`yH¤U'“Éè3À«VÚEµ¶Œt¸ä¾6Å=ò^Í$ølç÷ÌæLòpwdq‚0+BŠçô¿ iÚeüW–×:ÛËv­Î·yqÈ#˜ä••º÷rM­øjÇYºK‹ÉõxäTg«]Z&'”ŠERy<‘žƒ< Ú¢€3í´‹kméqÉ|mŠ<{佚IðÙÏï™Ì™äàîÈã`V~—á-;L¿ŠòÚç[ycÎÕ¹Öï.#9s’²·^àààŽ@®‚ŠÅÖü5c¬Ý%Åäú¼r*À³Õ®­“ÊE"©<žHÏAžZ¶Ò-­´c¥Ç%ñ¶(ñï’öi'Ãg?¾g2g“ƒ»#ŒZPÎvß“ÁßtOEª®«©«]ƶp·È$µº”o™ÚB6c%rÇ’kÛÿ²ÿê£ßýª«øÓMÕo'ðýæ‡ Œ÷:^ ×m åËÀ’#[O Ö9 ÌÝìzT_nñÇý ÞÿÁôÿü‡JÀ]þËÿ¨ÿ}ÿöª?²ÿê£ßýª©}»Çô/xoÿÓÿònñÇý ÞÿÁôÿü‡E€»ý—ÿP-þûÿíTeÿÔ Fÿ¾ÿûURûwŽ?è^ðßþ§ÿä:>Ýãú¼7ÿƒéÿù‹wû/þ Z7ý÷ÿÚ¨þËÿ¨ÿ}ÿöª¥öïнá¿üOÿÈt}»Çô/xoÿÓÿòïö_ý@´oûïÿµQý—ÿP-þûÿíUKíÞ8ÿ¡{Ãø>ŸÿèûwŽ?è^ðßþ§ÿä:,ßì¿úhß÷ßÿj£û/þ Z7ý÷ÿÚª—Û¼qÿB÷†ÿð}?ÿ!Ñöïнá¿üOÿÈtX ¿ÙõÑ¿ï¿þÕGö_ý@´oûïÿµU/·xãþ…ï ÿàúþC£íÞ8ÿ¡{Ãø>Ÿÿè°²ÿê£ßýªì¿úhß÷ßÿjª_nñÇý ÞÿÁôÿü‡GÛ¼qÿB÷†ÿð}?ÿ!Ñ`#øX»<+:yiÝ_Uî¯üL.8?]usþÒï´›}Um–ö[ÛËÉÚV–4ó(fU- Ú9Šè)€QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEÇ|@]ÚÇÇ—4Ÿñ:“ä†MŽâ_yѲ1ùÖ§‘ÿPýgÿÿûuRñÔ:‡Úü1¦éw:Ÿöv¦×Ám$I'–Ö—1dy®ŠpÒ§³ŒÕ sÇ×Z•q©jž ñ,Và4æX9 n‰$’I¥`7<ú‡ë?øÿÛ¨ò?ê¬ÿàÿn¬»êö6÷–~ ñ¶×¬±H³éøtaGúWpEOÿ F¯ÿB'‰?ïþÿÉTX ¾GýCõŸüÿíÔyõÖð?ÿ·U/øJ5úø¸ý‡V\i3ÞîQû—ä4ä{`×¢WxßS×µïëúEŸü@—:†ŸqiKq§„W’6PX‹¢q’3€kÑhHŠ(¦EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^kàøWHÒõWĺ%ìZÖ«æ[Üßʼn›û‚2¬ÀŒ‚Њôª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(•ÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*ºª(¸ñ×ÃÛ—q⟠Jà`4š…»=9jæþ"øÏÀÏðÛÅÖºW‰<4×7:MÔiµüås …P²Ä“€=ëÕ¨ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¹ÿÄßÅú†¼ÁnÇW¼¶Äv§ë)?뉮º¼ÉõÍKÂú‡‹üC­øK[–ßy“íVòÙ2%•º¤¸ÿ=dÆÜæLb€7þÄ´jÞ~?².H¶¶’þò{.^?ûe]upV³ë7ŸtÍI<+«éÖÒZËg5ÜÖevž&Äs»¯½qùjOjïh¢Š(¢Š(¢Š«ªÍso¥ÞMajnï#…ÞpÁ|וL±dàd(ƒ¿Ñÿá6ÔüW0“ËKXF‘§Mÿ<çB³I0úJ!_¬×øGXþÞðÞŸ©ü©gˆyÑwŠQòȇÝ\2þÄøsÄþÐô-ûÁ¾#{Û§0ù‚[ö›¢’O+quÆí’¾N=:+oÀ ©Å©xˆ^h—ÚN›qt/-Rî[vmò/ï”dpõ/’FL‡Ò€;*(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ å~,É,ñ—ýoôC×U\¯Åù%ž2ÿ°-ïþˆzꨢŠ(¢Š(¢Š(¢Šå|eÿ#?ì5'þ›¯+ª®WÆ_ò1øþÃRéºòºª(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¬ý{X²ÐtÇÔ57•-‘ã÷P¼ÎÏ#¬hªˆ 1,Êõ¬_øO4ùóñ'þšÿ ªŠåá<Ò?çÏÄŸøNj?übøO4ùóñ'þšÿ ªŠåá<Ò?çÏÄŸøNj?übøO4ùóñ'þšÿ ªŠåá<Ò?çÏÄŸøNj?übøO4ùóñ'þšÿ ªŠåá<Ò?çÏÄŸøNj?übøO4ùóñ'þšÿ ª¹_‹òK~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTW+ÿ æ‘ÿ>~$ÿÂsQÿãÂy¤ÏŸ‰?ðœÔøÅuTU]'PµÕô«=KO—β¼…. “i]ñº†S‚pFjo[Ò´Tº×5;6ÙÜF²Þ\$(ÎA!Abp DZ  _ÈÇàOû Iÿ¦ëÊê«å¿ß'ѼoáøüqáýbÆÁ¢³£›ö†Kˆ£ äÝŽH9Çï_ð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UÊÿÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿ@UWKÔ¬u{¯´«Ûkë)såÜ[J²Æø$2’#ê Z Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Wâ_ü‹–öÒôão]Ur¿ÿä\³ÿ°Ö“ÿ§zꨦ¥©Zi±Ä÷²ìódF¡K´ŽA;UTN8 'µA¦ëv:”¦;7™ÝK«ƒ‹å²lʾTllH¤+`I€HƒÅ_n¶µ`{Ãâ@ÐÜyAò2ù‘77Í·—*ÍÉû§Ïµÿ ø£QµÕG‘4á´-bÂÄ\OLëiäÇ#´±xæÃd€¡wõõª«©êºe²O}/•Í º¶ÒÙ’Y8ÇõwQžƒ98× iákë?%ý­˜ŠÕ5וdYbÉôÜ?Îï’¸Él1æ¹O øsTÔ¼%àë½6ÀCn–ZKÜ7šƒíÛ.¬¦c¡¥I5Åá…Am{¥@#@L­Ó$“ÔàPwUu-B×LµûEôÂ(·*A%™Ž@’IÀšòoè:µ÷ôÙ´uþËk }‘nüÁþ•q$1'Âò¾X 9ÁöŒ…®èžÕ4¹#Ô#‹R¸’Êî ´³»žÑ|ò°MÑâ|†s—1®všô­/R´Õ y¬e2*HÑ8dddqÕYX§§wr¸OéÚ–½áø–_Å"½ð–{ñI#B#e•˜Bï»fU™”(È%•k Hðž«kjñêš/ö”>L°YÚý±bmöÉÝX:Ÿ4O1¹X >èôí'PµÕô«=KO—β¼…. “i]ñº†S‚pFišž©g¦~Ù)WöE#Hò0ª ±àÀ¯&Öáðׇm´Ës¦ß¶¶¯-¼‘+Ëà=$vÜIÛ@Å–¿¦_Oc ¥ÚË%ìÜÀ[çŽ&DçZTžœi×}áÙ5ßh²ëº=›é«§ß¥Õ»–5–I­š0AÆâBHI†zí5Åé~ñ“AºÔô’ÚŲéFKó,2:¬bÜ\©•œÈ+6V<#/9fb¬ì¶× sxÄ¡C¼x’6ŒåX©á€8È8=Á‚ K^5'5i¬Œí$e’鯵)£t;¾GÛ=»8ÆìdÀ{-r¿ ÿä–x7þÀ¶_ú!(ñ—üŒ~ÿ°ÔŸún¼£á?ü’ÏÿØËÿD%2ÿ‘ÀŸö“ÿM×”ÕVkëÚ:}£~«§¯ÙãyfÍÊ)ï3sÀÉéZUãÚý®§cá ¬¼5g«Iö}.ñm`žÄ­Î˜âÖQ†t<›öÆ–c¿;Ž ÃYúÞ·¥h6©u®jv:m³¸e¼¸HQœ‚B‚Ä àc^kãó,þ%¿‹F_ÛkÂÚhޤÖsÝÿr€&m– Û|ÂØAþ#Y–¾ Ž]ãRÕ|BöÐj‘Jnl49š[\ØÝ£²Ç+\»ež$c³`-òòIÏ¥êV:µ’^iW¶×¶³ÛJ²#}I­W“ËiªÛxvûnX.õ¡#^$rAw4fQæMº¬ƒ÷‰°Â'€Ù˺>!K],ÜIq\CP}¥ ÅÜ‹MË»Ê ÍÈhÈÚw»lªÍ¨Y"Ý3]ÛªÚ¸Žà™TXª°Wçå;]Nf¸¯#ÑáñÒiòI¨_ßÍxm¢ûlØIÆûL~w—#ÌÊÎ"óÂùHªr ÁÚ*îŸavÒj:„šfª4ë_Çzmî¢gžêÙtø¢Y’ZM²mp9Ý`àŠõ+;»{ÛužÎx® lí’'§qSWŸx¡žmÎÒ´Ý^ÆÞïRßrÖÉ4Rºyg÷­?¿ ̨¸]¯œ3|»ÈÒ?·¾Êë®ÂMäG ±Øý‹že[ÉÔo-t-¶™IB7ÍœS´¹‚òÖ«9¢žÚtY"–' ’# †R8 ‚"›{ykc}s ´9Æùœ"çÓ&¼jÏMñV•àÿ àj[]\xv¶Ç2Ë*[K–Kµb,<·½Ð¥¶õܹZ-¶­a¨iÚ¶½&¡ªØÚOymÓfW„È òäXšIfe']Ìw8ðf€=*+ûId·Ž+¨KˆšxUdÉ• ê;¨.™#¹}EX¯>›DMKÄ~HôíCJÓ³5-ÿg‘íÞ{‹FU2F~BØgÚû¤tW-¥Ïâ«™4ËøüA©·J3£-Àˆ£‹qrJ(® Ì]ZE*Äm\ö[k˜.£2ZÍÑ«¼e£pÀ:1W\Žá”©ˆ#µK^5%¿Š&°ñµÃ¿ˆVêÆÒêëIT’u\-ö¤b  âAå­° ‚ 4|¶½–€9_†Ÿò.^ØkVÿÓÅuUÊü4ÿ‘róþÃZ·þœn+ª Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Gâ›lð¬æ${u}(ﺿñ0·äò8üEhÿjÔwFÿ¾?ûmfüV¹‚ÏÂQ]^MÐjÚT’Ë+…HÑu rY‰à$š—þ?ÿèrðßþ ÿâ©0.ÿjÔwFÿ¾?ûmÚŸõÑ¿ïþÛT¿ácøþ‡/ ÿàÒþ*øXþÿ¡ËÃø4ƒÿŠ¢À]þÔÿ¨îÿ|öÚ?µ?ê;£ßý¶©ÂÇð?ý^ÿÁ¤üUð±üÿC—†ÿðiÿE€»ý©ÿQÝþøÿí´jÔwFÿ¾?ûmRÿ…àú¼7ÿƒH?øª?ácøþ‡/ ÿàÒþ*‹wûSþ£º7ýñÿÛhþÔÿ¨îÿ|öÚ¥ÿ Àÿô9xoÿñTÂÇð?ý^ÿÁ¤üUïö§ýGtoûãÿ¶Ñý©ÿQÝþøÿíµKþ?ÿèrðßþ ÿâ¨ÿ…àú¼7ÿƒH?øª,ßíOúŽèß÷Çÿm£ûSþ£º7ýñÿÛj—ü,ÿÐåá¿üAÿÅQÿ Àÿô9xoÿñTX ¿ÚŸõÑ¿ïþÛGö§ýGtoûãÿ¶Õ/øXþÿ¡ËÃø4ƒÿŠ£þ?ÿèrðßþ ÿ⨰µ?ê;£ßý¶íOúŽèß÷Çÿmª_ð±üÿC—†ÿðiÿGü,ÿÐåá¿üAÿÅQ`„ÿòK<ÿ`[/ý•ŽL«®øÀˆòmI…w*üKï;€•IðŸþIgƒì eÿ¢£ñÌ1\k¾ŠxÒXÛZ“(êø—Þv4Àè<ÝOþ|ì¿ð)¿øÝn§ÿ>v_øßünì}3þÖ_÷áÂì}3þÖ_÷á– n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF n§ÿ>v_øßün7SÿŸ;/ü oþ7Gö>™ÿ@ë/ûð¿áGö>™ÿ@ë/ûð¿áF `ü0,|3td ¯ý±«n rþиèp3ùWY\ŸÃXü3t‘ª¢.±«*ªŒ¡qÀÖS¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¯ýµ¿ä–i_ö‹ÿDOEñUQ@Q@Q@Q@Q@Q@Q@Q@þËŸòB|3ÿo_úU-z­PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPÿÙoscache-2.4.1.orig/docs/wiki/Chain Caching Model_attachments/cache sequences.pdf0000644000175000017500000023024610445266451027416 0ustar twernertwerner%PDF-1.3 %Äåòåë§ó ÐÄÆ 2 0 obj << /Length 4 0 R /Filter /FlateDecode >> stream xÚÝ[Ys·~ï_Gº*áh\y³h%•ŠU‘#%yó ÐK­ì%eS´]þ÷éÆ1ƒÁìAZ±+2¥8==@_÷‡Yÿ ¾?ˆ§—•¸ú(”øx%¤pRŠ@Ÿðàn#®…hÈ´xÏÒ:K«æؿÈŸŠYøòÉð¯.éi* Ÿ¨ò¤«¡œ¬PZÓ¿7ÂÅÁBžìÄ+Z`¾—¤œ´@/‡éÉ*o“Æè}º¡È$ý:ˆdíõú¶£å:YA;a% /ù‡6ñ/q;ÛøË·÷÷›»[ Í?}É[¿M7ùtÓ_¶žt•íÏ §²-ª`ߤŒ~nDLŸ;þŒü©Ëçv”`³ðs’÷>ÿüå—|uÿËnO_î”xöÅeïâå‡ÛûÍí½xöâ’–¿¹»Ú|ÿãÛ¸K+3ìÒÑÒ?š4VN˜(¬ñ¼¾§¹Qâ‹ͳŸ³®y<4.ÖžÌc€î}öš\~­…²ƒ³¨£F‰×¤ùOj ‡‰××ââòíÕv#>¯¿Ï_Ïžõ,¶%±gØÛ³°1ï™V¥…ÕªìYŸ²g˜íY,öLñ'eôÎ ´ó=¿x›ö›¥¥µ¤rŽ'K_ܶ"I!Rty(ȋȻÍÝÌl—[³ñPþM¾édõ¡De'RæPžJ™ó”?(øÇ<å'* ge‘NY”îúÕÒˆµ¥,Ñ*äDâAÊ ¾TRi”ú_æ’rªI&s^2)ŒÐ¬ft6öÀl‚宪iלN¦ìî:»îç“rƒµÑúN:]nS²À~²(£‚©Ùwñþ¶1Ý\ór%EaÐM²äYʘ²E}b¶ˆ”-&×¾+e <$[fëdmÚÁ0VçláA®;A…'I­gK7ð¸lS¶èhÁ"–¸±g–ž`öâ–Ù¢ñ¬ÚóI1”][a$cD->îì]÷1BST8£&ÌwýåûÛï~ˆ Z˜6MHPXU]íσˆ¹«ÇM›!PÊÛHºõ|Ó__¼ØÜ|¸ûåëÏ>ƒ“qàXÍ„e~Æ©òl^5Q¥Þ“~ç}E8ˆ˜ ÝçË}G°NÀÖ§mZ(F“‡»4ŒeH<Æ„Fú8*¬† œ‹ H©2¡BhBŽçªÔÑ¢—õ$ªâ<~E4t¡¦j V‡²ïx.,÷=⡌11E—Èðùî݇»yßiâÐx[ä/ÞßooD?‰>qLèÑ6#|(9fœ6(0*­’5,äË¿wzr+ƒ± ÎÅ?_ºÈúkôä)g­d¾\ð%ÍöðåMV¼Î»MÈ9lC”¥šlÆ¿µôþ­6ü[k5Ð’¤‚]yJ½¾íhÉe­=Ô Ám‚Àt×™ÔVÉÚR›ã´ÍÍRÄ—J34J½‚ÃÞ<ýáìYB‚ öÔ:‡^ˆ[ëÄî°Ú ý™=uCìÛ©Rú¼Ì^ÝvÛÁÉíÐÑ]Ãã:ßϬ#ª7áÙ™Dq¾ë¶õ FJºýÐï?~·‚Vµ‚Ç¢• ±vCPgónÈ1zκ¡Ã¼ÈCAºïÄnhÁ¸VÖWú>µ)ÝK7Äe¸m¥_5úiNª&XðÒµ°€Ç#¿¸(Oi‡~?À0µCŽºÒ©Rö<`8°ñ¶‚‡÷Có4‚GçÔb1âGŠŠ ?ÜyÅâpTŒýÐ~TÀãú¡=¾@¯MÃ·Ò Z„Yt5’47мP{”ð¦1,×%„!:磋¼Ïd=ÆÇ»Íý×ûÏ·›«{ñ]¶Åx£°qðAkíË›”A„Czv:Ñ-¿´ÖzÓ1I·tÂ$1ŸJÚ“L>êj»žÌšOgµ4É®t«ö³ŠÓÍ GÍ*N6+Ų(ÔWaŠzê[ù…Àå|®'\KºÍ´G0Áe‹ íÒÈZÃ#ncÒh›ÆY’½ad ã¸ôó3ºç$G^dOéäO>©£&­|‹þI’ôeHéÇê«þ^e¦ä¦´æ÷oi°ãu’[_̓ÄùG©´ôS áC™ßçãlJÁ½‚†:Œ14½–CT%"UÌ/ï&9MýA‰HÈ«2Ûm×óD7Z׈T!E$ìG¤‚ÕÖ—ùýÝ<Ȩ·²Î /a®6?þù Pf†è0àjäF7Xc•uЄõÈEd£…ìu³¸°ð2LëDcíò“Éù*ÃŽ’ÉûÐ÷¾õ ½t3ÎVØ:ŸýJMþ²AVï«ìÙQŽÌ5z¿<®ÊlW´-½X¼¯L¨p$@bÂ90Oµf IÄC0¿îUhë*{•òñ ±,Y É/{•GÔÒñˆ®æÑ–Ç%kN¿¡X?70&e4š|ä€jœí ëaC&öÉ|=W€!½¤§OÞkä0fßÁ®<®ÊlW´õQMEfhUâFº:«µ`‰ŸoG=Š8‰ËQ†!ÉT%švµÖëÛŽ–ëCç.>‘dòÃ$(Wš•Ey©j SÕ¬!ìŽ !3™ä(üëyKÖ^e¶+Ú a©®×„Pÿgpè•Meë8dY.˜42¹tîÒÈN¾šGÛF²Âá±Äq’]mMéMÓ‘XžíA#Œ‰ãÈ‹9Ô½K_hñN”ˆI‰ãrÐLbN';îÒÓ ˆlWtõÓF§öÙ¢,'ƒã jÚP$ ×èáR›ÓÆÆ’5,b›õ¥e=°ÔÑ_‹Og¶”“DKò,/…*K`§°8©r9‰©¯Â\F1¦$ã’’n¬¥£¯êz!XÙ)qˆÊYiJ# {yòãøwjpžš·ÿ@Æ2JÇ0Ž…†M-k}ñ‡Eu"¾ Æ1…¦zú•´ò:Pïdæ{,ÛûéíîÇÍéôeô7d‚‘A¨Ò—<›ÓtªC_ÐØ®r€ÞÖoƒúRe¶+Ú>é `ôG}.Nñ9œäsqºÏá¨ÏÅAŸOöÇ|.Nñùòõc˭Ї­ÌQnÅ_ÌáÀß ,ÜŠ“¹UmÉÊ­Ðã>·jôCíT:ÑgF¥ò· x”´¦«Eÿ$9#@°$@Ê`C€òl¥ž( ÚB¢¡%@èìŒ!ehé·œ] VÛ„Á­´ÀÚ*ÒÛF5¬U|ZDtšùA‰²Tñ_rô/{dJÖè­cvö¿¯ã(ÒN­ô0t®WéEøW ñáQ&>Ê{ÈćF#ñÉ’‡hof"ùEW%>iLj0>tˆO~3׋סŸ*³]Ñv€ø 2Ë.ÛFJ é Ù§(˜±ºô§÷W÷›oz]žôÁ)³ÞåÙÁ' 5Ä£ö[S~µÌñùïk^¼¹1: áb y°y‹Õ)H/Mc„.âŸÔð™1¹uàì‘@>=Ê$°‰pè“@>ÀÊ$G™j…æÑ¶‘ä3£ÓI ò¶!y¶ÒËN´ñjIQãŒ"±š˜lPH T™íжC$P…ÌW „¢Ð&³ÒªNek@î!ª¹ R3H%wÙ&-À¸ÁIVÚÇ‹¿vo‰…b•Ûtz<²OäÿuÀ4 ¹ºxè.žò×{6—‹ßëåpØëñÖY¯vºa½y–#}"¦ Çù£%¹ÆøË5¦žì–;ÊlW´¢¹dކææYKszJJÃDsö Ï¥"1®(k­×·K-+'ü‰Œê€ ÑͳÑM[U5]0ÊΘ.5«ã¢’ò*²]QvJ ´Ç&&ÈE3uÕ£˜,§'4‚|z¢3Ýæ«ÎŒ§'Yò”·r†ZÚ·¨{½*E„R*ŒDêpÚ!¥“Äö{•ç·÷ óŽ_`©öé×<¯¸Û+ë3ö÷²¾¯þ OÃß6 endstream endobj 4 0 obj 3041 endobj 1 0 obj << /Type /Page /Parent 54 0 R /Resources 3 0 R /Contents 2 0 R /MediaBox [0 0 800 600] >> endobj 3 0 obj << /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ColorSpace << /Cs1 5 0 R /Cs2 6 0 R /Cs3 9 0 R >> /Font << /F1.0 12 0 R /F2.0 53 0 R >> /XObject << /Im10 35 0 R /Im12 41 0 R /Im9 33 0 R /Im8 31 0 R /Im5 23 0 R /Im3 17 0 R /Im6 25 0 R /Im16 51 0 R /Im11 39 0 R /Im7 27 0 R /Im4 19 0 R /Im2 13 0 R /Im13 43 0 R /Im1 10 0 R /Im14 47 0 R /Im15 49 0 R >> /Pattern << /P1 7 0 R /P6 45 0 R /P4 29 0 R /P2 15 0 R /P3 21 0 R /P5 37 0 R >> /Properties << /Pl1 55 0 R >> >> endobj 7 0 obj << /Length 56 0 R /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 1 /BBox [ 0 0 300 300 ] /XStep 300 /YStep 300 /Matrix [ 1 0 0 -1 26 574 ] /Resources 8 0 R /Filter /FlateDecode >> stream xÚ+TT(TÐH-JN-()MÌQ(Ê (€ .„"“sô=s Í\òzɇ¬ endstream endobj 56 0 obj 53 endobj 8 0 obj << /ProcSet [ /PDF /ImageB /ImageC /ImageI ] /XObject << /Im17 57 0 R >> >> endobj 45 0 obj << /Length 59 0 R /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 1 /BBox [ 0 0 300 300 ] /XStep 300 /YStep 300 /Matrix [ 1 0 0 -1 689 574.5 ] /Resources 46 0 R /Filter /FlateDecode >> stream xÚ+TT(TÐH-JN-()MÌQ(Ê (€ .„"“sô=s Í\òzɇ¬ endstream endobj 59 0 obj 53 endobj 46 0 obj << /ProcSet [ /PDF /ImageB /ImageC /ImageI ] /XObject << /Im17 57 0 R >> >> endobj 29 0 obj << /Length 60 0 R /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 1 /BBox [ 0 0 300 300 ] /XStep 300 /YStep 300 /Matrix [ 1 0 0 -1 416 574.5 ] /Resources 30 0 R /Filter /FlateDecode >> stream xÚ+TT(TÐH-JN-()MÌQ(Ê (€ .„"“sô=s Í\òzɇ¬ endstream endobj 60 0 obj 53 endobj 30 0 obj << /ProcSet [ /PDF /ImageB /ImageC /ImageI ] /XObject << /Im17 57 0 R >> >> endobj 15 0 obj << /Length 61 0 R /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 1 /BBox [ 0 0 300 300 ] /XStep 300 /YStep 300 /Matrix [ 1 0 0 -1 148 574 ] /Resources 16 0 R /Filter /FlateDecode >> stream xÚ+TT(TÐH-JN-()MÌQ(Ê (€ .„"“sô=s Í\òzɇ¬ endstream endobj 61 0 obj 53 endobj 16 0 obj << /ProcSet [ /PDF /ImageB /ImageC /ImageI ] /XObject << /Im17 57 0 R >> >> endobj 21 0 obj << /Length 62 0 R /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 1 /BBox [ 0 0 300 300 ] /XStep 300 /YStep 300 /Matrix [ 1 0 0 -1 282 574 ] /Resources 22 0 R /Filter /FlateDecode >> stream xÚ+TT(TÐH-JN-()MÌQ(Ê (€ .„"“sô=s Í\òzɇ¬ endstream endobj 62 0 obj 53 endobj 22 0 obj << /ProcSet [ /PDF /ImageB /ImageC /ImageI ] /XObject << /Im17 57 0 R >> >> endobj 37 0 obj << /Length 63 0 R /Type /Pattern /PatternType 1 /PaintType 1 /TilingType 1 /BBox [ 0 0 300 300 ] /XStep 300 /YStep 300 /Matrix [ 1 0 0 -1 555 574 ] /Resources 38 0 R /Filter /FlateDecode >> stream xÚ+TT(TÐH-JN-()MÌQ(Ê (€ .„"“sô=s Í\òzɇ¬ endstream endobj 63 0 obj 53 endobj 38 0 obj << /ProcSet [ /PDF /ImageB /ImageC /ImageI ] /XObject << /Im17 57 0 R >> >> endobj 39 0 obj << /Length 40 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace 9 0 R /Interpolate true /SMask 64 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0 FÁH endstream endobj 40 0 obj 23 endobj 49 0 obj << /Length 50 0 R /Type /XObject /Subtype /Image /Width 68 /Height 18 /ColorSpace 9 0 R /Interpolate true /SMask 66 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚíÁ1 õOmo à7X endstream endobj 50 0 obj 26 endobj 47 0 obj << /Length 48 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace 9 0 R /Interpolate true /SMask 68 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0 FÁH endstream endobj 48 0 obj 23 endobj 51 0 obj << /Length 52 0 R /Type /XObject /Subtype /Image /Width 42 /Height 18 /ColorSpace 9 0 R /Interpolate true /SMask 70 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0 FÁ(>Ü endstream endobj 52 0 obj 25 endobj 35 0 obj << /Length 36 0 R /Type /XObject /Subtype /Image /Width 42 /Height 18 /ColorSpace 9 0 R /Interpolate true /SMask 72 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0 FÁ(>Ü endstream endobj 36 0 obj 25 endobj 33 0 obj << /Length 34 0 R /Type /XObject /Subtype /Image /Width 68 /Height 18 /ColorSpace 9 0 R /Interpolate true /SMask 74 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚíÁ1 õOmo à7X endstream endobj 34 0 obj 26 endobj 41 0 obj << /Length 42 0 R /Type /XObject /Subtype /Image /Width 33 /Height 15 /ColorSpace 9 0 R /Interpolate true /SMask 76 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0äÍ endstream endobj 42 0 obj 20 endobj 13 0 obj << /Length 14 0 R /Type /XObject /Subtype /Image /Width 59 /Height 17 /ColorSpace 9 0 R /Interpolate true /SMask 78 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚíÁ  ÷Om7 € Á endstream endobj 14 0 obj 26 endobj 23 0 obj << /Length 24 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace 9 0 R /Interpolate true /SMask 80 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0 FÁH endstream endobj 24 0 obj 23 endobj 10 0 obj << /Length 11 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace 9 0 R /Interpolate true /SMask 82 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0 FÁH endstream endobj 11 0 obj 23 endobj 31 0 obj << /Length 32 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace 9 0 R /Interpolate true /SMask 84 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0 FÁH endstream endobj 32 0 obj 23 endobj 43 0 obj << /Length 44 0 R /Type /XObject /Subtype /Image /Width 42 /Height 18 /ColorSpace 9 0 R /Interpolate true /SMask 86 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0 FÁ(>Ü endstream endobj 44 0 obj 25 endobj 19 0 obj << /Length 20 0 R /Type /XObject /Subtype /Image /Width 41 /Height 16 /ColorSpace 9 0 R /Interpolate true /SMask 88 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0 FÁ`° endstream endobj 20 0 obj 23 endobj 25 0 obj << /Length 26 0 R /Type /XObject /Subtype /Image /Width 33 /Height 15 /ColorSpace 9 0 R /Interpolate true /SMask 90 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0äÍ endstream endobj 26 0 obj 20 endobj 27 0 obj << /Length 28 0 R /Type /XObject /Subtype /Image /Width 66 /Height 18 /ColorSpace 9 0 R /Interpolate true /SMask 92 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚíÁ  ÷Omo ì endstream endobj 28 0 obj 26 endobj 17 0 obj << /Length 18 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace 9 0 R /Interpolate true /SMask 94 0 R /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚc`£`Œ‚Q0 FÁH endstream endobj 18 0 obj 23 endobj 57 0 obj << /Length 58 0 R /Type /XObject /Subtype /Image /Width 300 /Height 300 /ColorSpace 96 0 R /Interpolate true /BitsPerComponent 8 /Filter /DCTDecode >> stream ÿØÿàJFIFHHÿá.ExifMM*bj(1r2†‡iœÈHHAdobe Photoshop 7.02002:12:11 19:58:26 ÿÿ , ,(&HHÿí#ÜPhotoshop 3.08BIM%8BIMê­ com.apple.print.PageFormat.PMHorizontalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMHorizontalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2002-11-27T21:28:02Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMOrientation com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMOrientation 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2002-11-27T21:28:02Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2002-11-27T21:28:02Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2002-11-27T21:28:02Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2002-11-27T21:28:02Z com.apple.print.ticket.stateFlag 0 com.apple.print.subTicket.paper_info_ticket com.apple.print.PageFormat.PMAdjustedPageRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPageRect 0.0 0.0 734 576 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2002-12-12T03:58:25Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPaperRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPaperRect -18 -18 774 594 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2002-12-12T03:58:25Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMPaperName na-letter com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2000-07-28T22:57:04Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMUnadjustedPageRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPageRect 0.0 0.0 734 576 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2002-11-27T21:28:02Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMUnadjustedPaperRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPaperRect -18 -18 774 594 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2002-11-27T21:28:02Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.ppd.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.ppd.PMPaperName Letter com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2000-07-28T22:57:04Z com.apple.print.ticket.stateFlag 1 com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PaperInfoTicket com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PageFormatTicket 8BIMéxHHÞ@ÿîÿîRg(üHHØ(dÿh 8BIMíHH8BIM&?€8BIM x8BIM8BIMó 8BIM 8BIM' 8BIMõH/fflff/ff¡™š2Z5-8BIMøpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè8BIM@@8BIM8BIMS,,tile_paper_blue,,nullboundsObjcRct1Top longLeftlongBtomlong,Rghtlong,slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlong,Rghtlong,urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM 8BIM!UAdobe PhotoshopAdobe Photoshop 7.08BIMÿáHhttp://ns.adobe.com/xap/1.0/ adobe:docid:photoshop:3ca8f770-0ed5-11d7-b622-c0de5f439c2f ÿâ8ICC_PROFILE(ADBEmntrRGB XYZ ÏacspAPPLnoneöÖÓ-ADBE cprtü2desc0dwtpt”bkpt¨rTRC¼gTRCÌbTRCÜrXYZìgXYZbXYZtextCopyright 1999 Adobe Systems Incorporateddesc Apple RGBXYZ óQÌXYZ curvÍcurvÍcurvÍXYZ y½AR¹XYZ Vø¬/XYZ &"±pÿîAdobed@ÿÛ„      ÿÀ,,ÿÝ&ÿÄ„!1AQaq"2‘¡#±ÁBR3ðÑbár‚CñS$’Ò!1AQqaÿÚ ?ð; ·f\&( I÷ç®¶õÏ*¾ÌÀB‡ÜÉŽ§ŒjtYÛ@Yã킪ß%®µˆÖ¸­]°K9iZÈÄŸM7†ìÌ½ÌØTwPÑÃaµ*“mÅ1B$Ÿ–_q޹m©i©™œ»ÒqSúey·2WH,‹šÄ^êR$,sïùk]@º™Rêƒ)¢y™Ÿá¥>ǵ­ š²£Š›“ÈLòÖ+KÚÇP• ñ,!] ìgo®µ¬§kž³Ú°Èu$\ÑÒ@š­ñíñ­LlrÎ"ÍŒâ5e…”e¼S©Y óHS±gNàš»Ql…¬#²Å–$“ù’?-fUPîÅQ`bÀxÅ„uÖª2»m®À½Å`x0g¨%ÁA+-™ug‰’ [qÑJÕ‰v’de-Ç—ÇOÕÄeÚw NüI:)U.Ê–n¬#s;rÓ";:AÞæ²D“ÊNÚ¼»­–g]fËÚ:ÿÓYÕk›C+^¡,»uY€3´ .Š 4îIY1*Ò½`l>³«Ô­S9v*DÀD'c¿ A¨žCŽ ×‘Çþ£NªB)gRÈ@ûgâ}â5q4mj%aYûn6Eþ˜=cM@=wöëžÓ-‚ Áê`1t#Ç»¸‰r¨ÆW%çë¦54"ºžæ<]ˆÚ? 8;%d^Ë"¢0È7õÚ7Ð2ıI`Èøq*8Ï('K;Á°µT:–'8xŽŠ¨QUM‰85`(‰üN–µîzj!ë+2’ÿs(ë#ßMþãçÙï4Ì÷`a2ã©«ÿÐðJël‘V|›ˆëË]dŸxVºÖ‰Ûfª$’ß#í´êÚ±=¶B[,ƒÛ}G= Uod:™P÷·å3¨) Y ²–VÈ.º£,†¨5¡ÙcâÐ>šQ(¸6#6*²-'yÃSL9n´ÌÀ/îmøüõt1@·6°ŽÅ\Àr8@ÓÔKjª²¥•â}˱#§=f¬jÙ‘í‚,€\™ôƒ;é£k¯ÇîÝ9 ÉÆÞÇq«$¶Šë*ör°ø°G¦Ú¶a(žû+VرšÔ‚¤G3¦ñ0!®R©Ûì8‚D ðn¦tÚ¡²´nàÓ̆ïIáÐ Ð0ŠÕQi¨"FD‚½9iÀ©"ÂNÎïóÔÚf$ešÕŒ˜éÏLÈÿ¦ÌäW^¸;Žt`Z­­E$«îÁ À=”v^;Yaw4ªÆûpSpVæä û+#‰×VP¦kZê̪ÔÂFý ;ê¸=€%v%Î8É#cÊ Þ4¤hØWH«û›ˆë;i +lZ‘lj‰$·Èûm:´¨Om–Ï Ä6ßQÏR¡¬9##2ÙÒ?ë:B°;­.1ÈVÙ.ÐÇsv|(ZÏ)Ö–e› J£©Øu ²6Óiú…·©*ÌF$ú ´JÛÑscY³" 0fÜ·ÓÃÓÌ¡˜ê 9ã:zhìºcRÜ€Iž#žþÚQ–y_Ø")ÿ6߇--0¼|w†wãúÎÞšŠú?·Nßs÷?¥þ]xηœõÿÑðºŠXL6RÄq鮳\ö8ÚÖ¢¬Z%C´ õ ~Zhm}ÌB}³DóØ X¬ÛU„5mÂÀØœ†ü7<MK[–î 1ÿ ñ÷ÒBȲP)%;$÷ÒÔ„R-¸‹Á['Ý-í©IPÙÁ,ÅÑ€Q×몄2€à|£î…ôéÂ5=ስ•”|küw3¦h`ETR@xâñ&}#Aªa±¨)XÉ™öãõÕhuBÕ1(Û0#¯A¨$æ ŠÙ‚üXeø@;΢«@Ê –A#hŸ¦ªs±d\N AkIœ4 `CVÖXO ö#ÔóÃ#*Ôå‹eó1ÀžR5G:£¬XRÙ€˜ƒÐA‚B26:±N*G_—PmI`?,À3+$ûµ•Za«.*PLÁÏ®´Êgªôo“Š È1aŽú–)Xs[¬ü”'ðßQD÷öÝ•jWÛ€‰=HêêaiäÜØŒ!ñI?"¼xjj⦋Â(O <8j —¸¬Œ31˜2'Øç Ij¼nð¸çW÷†Å§¤ <=hzžµn65»)‚:o ¤3+Ú¬·4cŒê¢wd­YÉZ(Ù}A‘¨§)É‚†À2#‡©<8ê…º…ãp@;xÔ¡±±;výœ 0ÇPn«l6ÿ\ËXa’GMµ}KRÃ*Š1ÌÄ€5tnˆœsÿ®>>Ý4â?ÿÒðv6Usµ"ŸéÅ€÷õ×[}s¥]eˆÂÙîŒP@*¯©jÀ"®ˆâ¶;ãĉþã¿ 2ŒÌŒNÊðÉ].J­`ÂB(a¿òÒ‡xþÁØÜªGË´G9tÕŸÊZì+c}I@ ÿ“û½ |ýÔˆ©ÖÇf–ã¿OoM5q«_‘a*î\¹?`· NбQÅñÜ…†'~¼¦¨¹³I´DÙ×@ê VÄ~±‰áêcHS³Xg#O•H ý#×W1› †tɃ(GèxêjŠÊËØˆ]ürß`GÏòÓ ÑXg QeBIÀå°çÓñÓ UUŠÊ×`Žãf“׆ÃZ•¹˜)i ´ ßÚ8ë5J:0VÍQ÷e}8êa§(­YrîQâÀ½õ Éf©³‡1 ,Ñ ¤€)~ÚÀýAù@Ô‹M±ëJ &O?Á¹jÔ¦»^²!b„„tJ¥‡©mrË$€¬Ýdi¡ÝÄ‚±]v¯Â@•â'WL%ê²”KÖ@ÊäzÎ¥€J«ÖŽñÄîwæÇ~€ž‹/Ä ˜€¡b q;o¾®i¥íR•.]ƒD%‰QëºÊŸ]6åYfƒX$¬6Û&:êÈš]5=—:ZP«ƒ‹˜é;êH¶kÀZmûì nG¡ꡣȭ‘V¿Ól›ä¢xÌ]06©e&Ÿ"¶½¶W#ˆ?]([Wm$+‹–ñ'žú™ƒ•©%Cl2,úƒÇI€r¾Äl-"¡%˜|DÎѼiÕRíTe±ú;G3·]â îF'­5ä€w$p‘¥©„5†Êñ˜sz{jj²ŠUUY¬lŽêXÄÃI [iµÉ €ƒrkçõ?陋ù5 þ¦*– õÕ´þÙÍæÅfäIÞO"¦gMÖ­–ZÅ’¦,Ì0 6ßO@ÜÖ£àj Üž'¤è'o ­ EÃq„Çs¦.žl*¤²G]ÏÓyÒ õ$«>U™@ƒŒLnNÓ¦˜ÊÕ,¯°ßÉAå˜Ðk›P3ð ý^ÑÃ@ok°‚ª˜€I礪Œ®–|G÷)<ýõì­ëUZlO"¼2°‚±¹&=u« Aãnám›pk"Hߎó© v}ɯ“òöé5teµ‡¶³e‘Ø(ß 9¥‚kVŠˆ9Ä’ ,1ÜȘԤ6žÀ˜Ûôö2ziЖVKT›‘öc¿×]©âÏqª·ÄTŒ@ŸnºgÊj§ljû*°¤¡œç™˜ßV‰ïñëfVõä Ø‘;:–•cض«²"ñ—rf:€:j)½ÛU\5†àÊd®ü~›jê&O!)fP¡²Q›1“Ξ¬vþ•`“ȱ¦Çi`ÕÉP ˜ØmõÐAfÁbVáÉh)[šº¬6ù-pØ2âD‰çÇWDÄ`Ó'I›#aÒvÖUZ[S¨˜5±ø( }cˆÖµ0 UÚÒ¶#/‰åÃm”¦ÅemÙA#›mÔD8DZ,P…@èÆ"úé© o¯,.'´¼qŽ[˜Ó¢~Ó´¥¶(…í¶¦.ª+Ûjà‚µ’ñ‘ÂcŽÚ¨UçÇ­Ý’ÌÝÄ wŸ}.ô[­êœašÅI;$N¨A7×sWa*–%G·¦§tTõÚ¨ÎvÐ ³üDƒ«‰¬Ï³*³Ùr Ĥí¦àjX‚¦]8b·¾ñ«/ -Vµ[Ôbí›3n}àêx‰*‚eGI娭?­Š3°*A©XìÀpqÓÐÞçm¥*CkŽÄmøïºÃk¬âª€Ä”Ÿ¨á륢Ĭ°*X|T} [[šÊ/±ÊÀŸMM0š³º ®Ç2Ãøƒðã¤éEñjØU[%ŠGt1†ÜލöX„ªœJó˜Û@¼<‹Z²rTbÀ ýt…%ñ»¹eD—<î=6EÛEµ!Sɪ$±‚IôêìÄÃ4áKBcOXOÐWfænݔ֩^Ãã´Q×L«¢ï[–S܉‰å<=ãMGÿ×üð…kVQLܱó²r>  ‡×][Ÿ}Z­©fˆi›Ü·È å­N³òœØk³3bŽÙƒZOÈž‰ÔÕs‹îsÜÔ€gr¹pÛßK´ØL­§*›— ÒPxΕ…cðwȈý$N–wk°ªÃ`LŸmµpMb^ŽYêPÇG"5, s×¶ê2l=Ï=ªÄvÊ(8‚>ÒO®ƒQí ií Àƒ°ª-¬GrÇ®IĨÚ}9êÈ”ÀUQ\ÍÅJ¿"'TeÆ´jòqI“ˆ•1í©HÁ,Ùº­ÅàeÐ: ’¬Ä”þ‡-ݾÚÊœ Çt ò}E,V¯bKNMëí ³Ç äAûòâgŒpÕ‰@X#‚ Åf;KýDð‘ fä—ñÀÇ|c„è•ÚïµxµR\RØIN’:i &ô¤œxl:c¤…j±j‚õƒ.IØG^gé %…v×YS÷0a· ç¥!a°DhYŒ"Ënƒ1Q´ i6Zƒ}¸ôÕm²–G®°êÃ,Coºn&¯:¡ŽøŽcòÐ[ûÅìåÙ\c#(Ÿº?-kíÄοÿÐðZÐ…RÚ‚D4d#<ƺÏ÷¥gí+2“Œ[ƒ´˜MUµB¶±ëDE` Ø“=yþ:°­²ÑR7t¸ÅE`“òÒÜèê?nõ”jH ?ŒOBbë§4#ä–ØPÆ5IU¤“ @KѦۀù>ê6à7ÔÁ¢»Yþ_!'6m€çòÓ 0Å„³‚é¢ã×mPA/ÅZß!q†Å$€'øé”OMmb½WX3‰;z†©!Lì«â(¬‘ž˜k|‹-c»ã6)@@>ñ†­¿‚:¦Ï´Î p9§¡:B–T–‘¡€khÆ`ñÔþJµÊµ…”1 ½tÞ˜ám `[õé'§]6ú ¨Ê‚C…8 <ýFúÒ%ò©®ÕGpYWâH?žÜ†¥š±mxv«VXžòŒõ™V¨½Ô+<ÜFç„ÇUkZªXsA´4d#;ÈÓ0(³7iYÔ¶2Al"Òvúj*º{l„”JÆQ;g¯?ÇZ‰K²Ë3b¶"V¤ÂK4ÿ-JìqQc î´zFŠetœgäoiIÛ 1¼o¦!–ÕÝ((èAØÀs¾Ý4³@l…’Êì !ß„õ“ ëœ…݉ÌÎN”-X¨rÔ}ÛÊz¸ÕñØ…Anùµ\Í(2;γcMt¾D’Ûl‡„s×W¨/ÛaTÇß)3Ç_ñÿÑð NNÿ¸¨3}Á™¤뮲®xË /jÕˆeˆe§Ð[-P¦›µî•Þä‰NÄL4tGe™N7Å1°ë¶¬+j¼Ô,PøÅ¤â@“õÔ— w‘]uvbL±yðᥘB»µKE,øˆ$òè7ÛE^_¶²è¿ÝA~‘:Ó)|›+±òD݈fc—MfÕ†+Öé[xõ´ XnÑÄêþ‚ €Zλ:ü˜œ`ޱ¨eô°VkÀ’Àí'„HÒÒGU€t©·#ä,I?†V® ®JòYøÀ”h EB¢Wâã‹J ü÷ÐrTŽ ‚L­#nDN˜Ð1ò[:ÛtP@úï?M>Õ@ñÙ‰–mÅ~\§m¾š¿ùÖ9u*„ÐATË~|Le¡í²ÕV;ï n @*ø¢þÄ´óŽ I93ö™H"T©*AØG¾ z\ªÖµ)Lüˆè'aª¢ºÔÚfCb1Ê@:HSö†ÈÆx~¼õDÔœÿqR–ûƒH:;)µÉøÈ3'ùêK‡©Í¶¾6µVý Až¢xêjªÍÆJþ?̈(~*u¤gsÆÂ;c·ÝŒû­ôØ?ÿÓüöÕ=òv;£‚Dñøï®¯ú´­P(.´;&F¶qå¶úÖ&‘Y¶·²º»Šóðƒ$ŒsÔ+G“uˆ•¾G3 ·"¿†›LulŽ’嬆ùº‘±è}OEuª —÷ ~ä‰os¾¦.…1GV¨7qX€ Áà h/k,zÝÖ°,-ºƒ· òÖµî´56*£âÁr‰þãΦŽoˆ±.ý;åŒIå ž:Xj”òM4…¼|«bd}À_mj\õ0“uάõüêòg†ß冀pšÜ‘ÏažHPDú_m@uàá–À;vÌ> ¤ô×*ªUm]•D>5pÐÝžÊV¡"Š žFAÔ¨vItf‚¬±à:ðÕœ(ng{r/a“}”HËˉd…´“'˜笪ڔª)ZƒѾ$uŽºÔJqzè ae•Cq=Lᆵ"!Êl1òWœ’6nʘÔâÀšMTå,Í“®rxîBºOÂdqØ:²&•efÖG¡ ½`üA„bòu3U#Uecù;’8$OŽÿÏYÅÕiZ QšÐì’k ¿-·ßZÄOY¶·²º»Šàü É'cõ!D<ËÙš\ìÌ&÷}©l‚<ƒ•„bxâG=¥˜8±lBš˜|Ltñúé(ç¸ãþ )&q¥v}Á“¦˜e_qq^Ä%s‰‘Êx‘«Å×V@uoÔ?$2áSLgíÅ£¹U…Y +ŒtdHÓ ;DZé«`_yæc„jË…šܽÌ?lK“!hˆã·=7|3 ï_âøý½Éïš?ÿÔðoؔɕZÛ,$ªƒ®·êç~ÄxžCxàøî³Ä9, ú’N§óýgÍ9‘X+vË×Á€;X«€] OÛñBÖ ecÌ¿ö©õÒóÃöšÆ·>Øg?¨»þP5• º°åù³ cמȎMÊ£2Bâq׎ª{ ˜›}Ô6ä¦5xžHFUò÷—f®9}`êïå0GÈK ×Rµ.¿kÀ,:Îúi„äžDH$|€±ž§®§«áµ%jAud* 3ÖtˆSZ«ñ-•†wÈ@ž£MWí’¥ þ¡w;ûéàÔB;b¢+èXóÒ-H£€ˆ"yl4à¬s_i™Z‰É©ènxZØ«b WŸ¨Ð T—µ¤)7"Z8pŽZfš0¬ŠÆ`/`2.Ò}§ÛWô ‡z”xþ¢¢g–ó:‹XPöÉ60\· ´Á¶yØ3›¡LXØI髼12öû6?êVíñ@å#ýµêæÐ­ƒýÄž§ 'Q¿±)™Ukl±@dÕgWêi>'|p|w\¸‡%”¿¦ÒN§ós…†²+bݳe|¸õ3¦*ÔÙÛñ)V9,QÿÕðu`XÐ! Y¡£œ“ËÛ]kžmegà€Öƒ%´“$¤ Ë<žóZõ!ÌýãúñÒÝ3Í[Ù[ZìqB“¼Ž[zêe]¾MkUÑXÝìL²xêü‰^‹SÈ{,l¼|Ž ™;£Rή¨LC-W¤³“Ãõ:Oõ?Gµ¨§øwƒäÉØí­!a+ eˆ ¬ƒƒ1Ä<÷˜•£;vÍ”–rOçËQTÕE•“6âOÞΜHúêɆ˜k©Žm›ØFY:jâ#¬Ø…Ú§ÊËÁ Jƒq"yë1L­š!U¬uùgò#ä i8ÍidtÑ^ÌÃIÛˆŸ®Šk8¬) 5·¶·ïΟ¤j‚¥Ò@POÄ’ ðÛA¾Mg³´]]rØï2], A”5ÒÍmÒå zÏ Ž¾¢§=Â*e—}õœ‰u7‘äTRÉRËÍ$õæHþ–¬„%®j`˜©pdþ‚55UQM5VÖážû›¸TBƒÒvMY’%ºB`À3) HŽ„qÔ¤`¹+ ÝF.vRŒƒÌ¨Ž²©êÀ²Ð) Y¡£œ“ËÛWP½•ŸÓE(ƒ%´“$P4ÑÏä÷šÖ©Hs÷ŽÒ ©n˜MΫ5Œ]T*Ðg¡ÛKV+ªžïŒf°—)÷Õ“c;ÒוgŒë2q íQUßâWs#×gîUÄ¥l1m½Ï jÿ:’‘Záš5D ÄœŸ´î5"…jC`Å]åSqÀíi‚f;©‚Iù«HúÎãY_Å|ÍÎçŠ=‹09ÉW PÉ[ÕciC ¨Ö„°¿¸íKáöùÇN:ÏÈÿÖðJêEU-HDëüƺØçµ¬êµ*5˜Ðÿpª2M¶Ð!üKÂÈsª¸ûĘà7üõ0ÓMVömkb¨",Aüus‚±×½[V•Œ«µî'ÖH:Ц¶[D«Ûÿ¢O¯ý5b3ü6ä2•’I$òƒ§lM둊^S2y¿å©èÌ«LXVjî|HçË@æìµV÷™Á%&L{b5x1·ñ«ThÄ ÌžOƒåIgfÅ ¬-bqõY&u~õ|ªps1:ž>_n§Ä×Ü$®\v"Dÿ>ˉªî›>;AàþDmËRItf b䘂Bó ïª1îu.ŠŠV½úzî–‰Ûɹ,ͱjŸìC¹–Ë'ðÔÚa™º¦ ÊÆÃó !§™ŸMZÔKTBw±Ý½§SW1ªÊ”`pv]Šãý§œë\e•UC$]_l‰$(‚ÑÖzi$ôÒŠ×=®UOÁ‰¡ÒȺWŽk´ãY+báv$ ÆRFþÚ¤Z ³÷iw¹ãE8€NܶԪªº•QKR‘º–õ±΢ ¬øøö}¨È}6ÛWà%üK,vd9×_÷‰1Ào¬áª·íØ×"@" ;á¶®ïRзxè€à:þ;õÕÓ¯5‹QP˜@Àì`άJZÔõ²«Ù*ؘR>¿ž¦+¯f!i6'l –õaøqÜi ª¦keuÞP`ÉØ™YiEOS•²ŠÁNDó7Õ‰AãŠOîngã$Àå4…SB8 ”Ö$¼ü Í´¿ŠÉx´”·âE|iÓÃÑXîþ>I•Èõ® i|˜ºvž×©@8GÈŽí«»l–®Õp`µŒw‘Ä&50v îdeÏy‘÷夢§Zʳ3ÅÃû"Nûžºµ#æþêÄ8œðŸ´‘<&7ÎÖ°`V߬áU'*U ñÚxrõ¢”ßÇ)Á™Iކ4øO’Öû;yb  ie ñ®š``—†P¿äã¼u$΂×Ä*«3nSqíÐëHSµ9ýµÖ ƒd`p©qHSZ†«&ÜJ¼gÔêp¬ÝÆ@Ô)ØIU“?.z´+µOhÝû„ÉL¥j§ˆèy LO‚ċ͙?÷ÇßNuuWcƒã²ˆ;†cèN™¾>?’¶ªÓ`c±n;ï®S`ûª‹ÑÙsñ±²&H÷4(%ìQK« ^®G–Ý5:·åÔkÖËŠ™Â?«—]2›ÈqˆYÙw'Òy{éÑÁó©Ô¸Ì,A-z·¦À7W¹*îA!`ðë:}utÖãºZ¶ümøüxÒ éâz2¦ÚÀñ–Ëì&-B §_»œêçà2µ·m¤«¶Ì†â'¦’#ªª¶gk€cØÏ¦’­ÞîVÁ,Û úƒËNŒU©™Ã²à`Ôõ¨œ„Äè ²û)bÙ2ƒëÃmgq¬`#É‚ÁU‹šAb}D¿¦žž)ñÝPÚôüe@ÌòÐ#VT¡FjÝé ²œÁe<Á'@9ïv×(DZˤ{F ÿÐðSaÊYÀMðzÔ‰ôŽMuºç“w•-ïÑ­KÜ8jjâŸË H@¡i;”pÒ±Óa«?¤±Ö4fž2›6S`VC]?B{‹÷©gAÚ–b°'‡ËÛRª“R» P„dÈBˆ)[CVFÞ†WMOŠmÍØÌ%`’R:OçKF˜×YCa,•Á$}F¨azÊ=oNR¤ª´íþ¸êhM** ƒ0µ¶r¦"v“¤Zy°þ¥,à!û‰#ŸÓWP^:lU{a)Iù„i:S+Σ6)N8o òöõÒqýVSãÒ¿2 1¼N®òRrFnùÛ#ñœpÔÓžÚg2mÏ馆‹ ÷ÙŸtoˆŸøêïä"³x±™s3‘ Àïê'Ps{ÑU®ðÙñŽšpêr´åcWX)[í&us=h°£ÂB¬îzƒ°Ö³Oj’è2}¬dŽ»L†³±á·b¸ÚU„üdñõ2M¨ö-²³ä­¥ä«Näã³”ôXl¤¹|Ødê¾»¦!Å)¥6‹K)$Àžz¹!êZЪØ3€Ð{gí÷÷ÔŠ%ºÃ€ÍfÅÙ’^²8é¦ktxÕWã“c¯Iúj ÕYeMªëXfO¾´‰™1|®¸*N]È$8£øÆ³ŠXW¨µ‰huv 6ܤ“ü4ñWø×Ù=Ðc±ŸÀε+6ÖäåJ²†¥Dêêb4±®xDOÓ8›+°ã¸ÖwWÀd¹wŒ”0¶p3ÈIßOø­R¢Çe{R"7#xžiö0§ó)¹Öº¬Díg$ž¥þ´Ã; ` î²>Aäe±ßFÚ¸i"äf*Y‹!&°ß ñᶦ˜ ùÞŒ.V‘—2=ŒAÕÙLÀ±„Üݺæ+U•õß@«×´X–†@1Lxûu(gtå·îarë:ÿÒðªì>geÿnŠäv Ë]vëð>X1‘ýDeø“øê k¾iií0;@c#úŠËñ'‡YÔTµ­Ž]-ý&b‡Œm¤Së±E ]Ï#(NM*võÖ¢’õ­qR‹{Ò¬¤Až]THÔù6’…)ª¸$"$ÿÈγ–¨×ƪ–®²•`È“øžº¹†ˆ‡¶àd++ €ŽRzê ê©›ÉÇ&²>ÂÀƒõ'I:·ÃmªÐ•±tÌïÂÓ‚ßÓ+Ûa#…¢À‰á¦Ÿ‹«÷ƒ§iDiYS{ovZ8ã'(÷éª?ÿÓð |wo•@RË;t]uÜ®w®W-{öÃ%xU&2>œ†›Ð]€è Œ…̇Pwü4ÃR×UkkV¥reU~Gê}ºêIÕwíì¬/Á¤”VÁ= é˜jw7*KJ¬9òÖUpµÕq%B‘¨Èó­k8ÐsªÏ’¶ÕHn| éð›lKòÌ$îjBŽ»ƒ¤½,ã®kGmÍŽX€ËñÄs÷Ò‘‹SXÂÇ&­ÀLÀçLV¸Æðëó&°þ#i#®—вÞ=Z‚× wp`ïψ9**ϼտ‹[ ÎÓǘ3¶²¦~•™û…<òÐ3°ÕåZÒŠãÜbDí$ v¸šÊk(,zÊ•O‹ã:‘:HUÚ‡­Œ1N¼ue)vyv± Õµ_8îvþÓ:–’-{è¬\‹,bd^ƒŽµoˆ¡k.²* ˜'Ž“À§g@ÀŒÈù|ˆ…G ΠÛç—}¬© =J¸<§qù鋦]JÔ™×I|¾Í€Ît³R¶­‰±)²²C(Æ õ`þ:—‹§ã»KÔ Cb‡nƒë«Är¹kß¶ WˆTRc#éÇøiò °u¹áLïÃW H•¥v”­ée&w묪â¬l¬WH¼±Ó˜<絪¹.FDìɵL²ñnYI_2õ4b«RDÇç´í¬^5xÏܱ²¯¶î³‡Ü@禬êXÒÄ@äAÆwÐaƒÃdÀOllIž íªµÝj` ¨,\±ÊOHÛm@ËkP”€Æà– ‰YËÜñÕ°Ž‡Ë½‰Ê8ÈûzjÿÔð»×X̓‘Õ‚õÛ]us²“ߦŸüYN9/Æ8OóÔØalêo¼Önn}BERÁví®JFõíðˆÜ ¸ëHVHK&,ÇhùDzÈÔUkk"ÒM»ðÝ1â;êþоچ-X*í¹?C×S÷Ÿ&ÔK †D?'-¶‚:tÔ»VcdÖjjÐYi;«“Ïûˆ+Z·~ŸŽÿPË-Ο »•º„kœZ¬…ÁB†€E‡Íf;‹*qê#ùêᬲ…Uœ«À%âNÓ¹ÒÃBì;/e•ƒ‹ 5>%!ŒÚ¶e%‰;‰äúd4vÔõWˆ´XXõ}=§K0× +Oƒ£ ÄÌr5v`į7„kU#0ü&z©€Š] &÷,L AžN®IðlÇçƒïðo¸íÏ–§ÕuKªËUÁœš1éÆ: T*§µØ5¥b&L€Ðj@BÚC»2šjR³Ê×W`; Úka^Œÿõ¥ ûªªÈ8eÛVƒ·Èj\¸ þl ·Ý[»N­HG~›VWâÊqÉ~1ÃúgóÔÕÂÙ”3ßy¬þ¡¹õ xè+‚{®Oþ²@ ¸ž£Zý#0ùÙjùL\…j@ú™Ôÿ£¼f±­×6!Üêúôþt¢ªºÖæ7 Y‰98m¾5g½½Ý©¥«)¼ÖZ-ÛyâÚÏT«­¹˜)¯¹@ ns¿óÒ©‰U.ª°.å±$‘Êtâ Ü:Þî®ë5 SŒzÿó¦JUûkñ½]ev-Šâ#–ÆvÔ³uW`¦—=´0`• ÇÞú²˜_ЪÂĘ́ˆÛyÔáÒ*¢¢Ø/˜ì–fœxmôÏõmt†î=¥ëX’ü t鉭f×+`nHí¿Mb òØkYYÒ«Jí rÐÐCÓmIMvPö‹Ùíà£þ'–úÔÄCcÚÎEJë@á…Ÿ]e¥4‹UQÞäÀÛ¬ˆYé;X•j¶Ø½¡m„“™+ˆŽjvᬩ}÷°K*? ‚ q«m£Ÿ:ÆGôÀ9 ‘‡ü}FˆoîÃVár;‚«Á‡9'M1—X/Ä»?ÊÒ7ÈÎÛéHœA’¶’ÿYâzn¢ŸPvjÂ1eù AÛqž¬J¼]6”+nÀ(R6¶kz˜/~Ò÷ªš¸ wúˆ›ù\$\lWî÷ jK%|dõßmMü˜q\9î ‚”€ïË–¨–ê¹cQntÈj¬Uã×.º–›Ùb¥p4»Ô<Ìÿ-0Ò®K(¬–û[ÄG±“Y‹:mw±eÿó»öÕe‚ËËàú²¦([k»Õc~„ó¦êf «PÜUmÄ“úa€-¦1ÃV^‰¾]¶]ILHÙIàÀbx gm^C‰},v® Œ†2ÀòޝÖÄÝ ©Õ«†Vl€³©ŠWmìfeUEJBÁç×m=‚3½68W {ƒ ¢³MMÍî] ÄQ³ÝÊ»³ —ì‰ë3ùiªÿÖð…ËšËB+Ae#ýt×[²¹Þƒ$®ë{jÅ›3·ðÓåIÉÝ•+v‰ƒ›2ëðÔ®É0›bØ©ÆIÜêèä:»>jÊà–¤Ìûúé1 ¶úû% u¿t|±‘Çï«o Bćªº¿Qÿ $ùóë QË‹+Ì€’$ðøê¦‚ë…LÉÙ ÿJ‚13Ö&t´Ít‚„¾h–Aj æ4 |;½¦ LB3Ÿ™nžÚ%–¡Éc\#=$è-²¥•*”•9C|¤î=uw ­•¥®Ù)y2ÀÈs¬¨í¦µAs†_=G5·®­‰¥%Ï[•%Z¦QÒI”tM\REï3[]T|ˆhØž½=¯S…Uã¸6¶VRV{!Æ_ƒIW®IŠ %ŸöVJ)]Žnµ•Ö£Æ#ëÇ-¥€ ,+‰iƒ}@ŠXn½¢„UŒ«Aæ#†¤Z²«¨í¸¢ÀΧæ¼A<äòÖ¥Ÿ’Åkœ0=»ŽìLj°S¼ë7ªúG–¾ë±f…Ï8øû±Öüd¥z,±Yì´"´Hÿ]58)]ΔƒÛV%³; O•+'wT­ØZ$ÎLʬ«´±…v6 †ÁHs’w:JXÉÉ«~çd ¹bcþÞgAÇ¢Ë,ºÑlÈA\“‰æH]ÃÓ,cw‰6¢‰7ØX:^Ãå3|–±ã¢T›XŒ—oM k?¡Em^64ò6*Ò³Æ[kA}šëÜai’µLÙ‘å©A»“± ówŒ@ñõÑD,µ?Qr±Kñ:Κ†ÏË< Îå¼Çšÿ×ð3sxãÆÊò%m׆ºÝÇ=š¢»]§îœÀ…?S«-B—ÇWî6Õ±Uc1ÐL]Mn.Q=%>ܔϸ߆¥) ”[. ƒÀ>œ=0-mª§íÙS:ZÐÍÓ¯;êj®­R¾ïe«Ã€| ’y kô…XVÎS¶Ž`9i ¿MKÀª-ŠÖ¥˜|•XöAE4¨iïµ6¸Ú’(?-Y¢³Æ_ÙÍ‹`sñRØ3#RÌktêûö ±,6<ˆ˜‰à;P檫KekVcáY‡W -Jå‹1jÀ„2‡-AŠõظ¥?<â°I"}Žã@àŒ…È›0$ž'¡µFùVÕ=U”Á¡˜9ÜŸÈijH4ò™À­̪%eŒƒÎ&gWLGoŸþ»‚§˜=8שׂ@­ÄË×Û(‚Rxþ ªéZ\RûÖwgªí­KùLOmf÷¹ 52·ßèá¶¥š³…ÕMTk© ;bÎx°éÃRp—¶£*«blÌ[ O´@ÓÑ¥Yèý¸Ä;Gp:ˆ‰¸êü`kxãÅÓ&ÆÑÑSpÍQ]®Ó‚÷9—)úYP¥ñÕ͇jˆØ…n]ÓS[ƒšÓ¤®ë’´ú¿ J£¥âVY/ADÄï¤J½†-Ý!ªƒˆ¬¤u¯õÎçånaš ‰åZq3À(£â Üj*^û›Íu1*ÎLâüN³«‡^®ã"ØÝ”b ’gÛV¤"ß±_!¦°Ÿt‚Ãn µ,]&ËeÌQD")*'ØŸç« ª.ícÛ=øŒ£o~=5QÿÐð¤©dÕW†ÈÖýÌÛ€9·?Ã]vŽtª<{<[/P™ÔÂlfú5$Å·K°wl,·\ja²ÃÓ˜í©} ¨¢79ª¸©§'VÚjÝZ«±@èDF¥ -dŸÔµIÄWös;L]UÛd²WÆV/³Ôê8Ö ^'³˜’Àã€þz€‘é¬33ÿŽ2l¤’#}Y€ì²§Í;¿=˜;€H~ij3Ç¥luí?qœ}¤|CLnt´Vø°åAýPIV­B¤Ê5l% v.Ö–k•­ (ÛÔoùjj—äÔ—vì²Ìœ3W#cʃ¥é8&©Rµ®µk2…næðxÉ#}=uWYWmÈù…2XñÓK~Eu[jÏS!ÅËr'RÊmÅÅxؘŸ¹wÃsÏICÐxõ‹åÜ"e†ÜyG=Ym?6Œ«iÄqü'® ÑA¹4)]ÓrAô;j暨|³8P:#iƒª„Õsg¨“aùR GB í¿=M\/%P¯Úšxä‚zFúƒµjVªÖîñ èv#Òå¤Ö¹"xý“`–wÜÔqçËW"&©?bì  È8º™ÊzãÀN¤â޺ߕŒZëU8 ËŸáô)¥=°ÜïVáUaÏMÀÏZÄÐ]xñÔÔ•­”òf$oÈÔ·8²¾R^퇋bÒ?¥âXÞgWí©„Ø¨$HþÒgáè¥Rñ§»ˆ´¤ ÎÄQ¨ ÇHPÂ0ˆf:ïøé!T”S,Ä@ DOQ­#çâªbÆ´?ŽÄsxë*e˜@6©Em—ƒÿ#Ç@tö»­†ÆÜ:LNŠÿÑðå[ƒ=¨_/èy °Fò]uÝs¼.³L!Ä÷X•$“Ïå¤ÁF ‘‰Ä8š†A„¤ê¡/ŽkšÂ‹¨=憥‘zŒ%Ïp, £¨ùp@é¬õB•²ÑBbC@Ãú‡§M0ÕµyëU]£b­§f ß!¤‰á­Oé/ó¨­y ¯ã€fJ»m5›ßqWŠŸÓåy5Öøä»ƒõßóÕþgå)¶<\Q ã<=‰#†­ôJ¢ÿÛÇEjXnû…ã¾ûjv)ö3Ãg\¤ü•O> q#«Gz‹-pEk-È'úêÈ ªxõ;Ø Þç[<“Ëž¤/’®E•/É+-}coËSWÇÇí¢*‘+ œLqñÒàÛ+©Às’Ü"ñ€éèAQ]ªÁÍ…¢k™ùR6Ô‘PV°ÔI-ñÛ#=4Ü\Ñ„V¶ÐÄ8}Ñnßc´hŒí±É"YJ©&étÅ.µ”5²»ö‰áþÓ©V¢Ôd(^ªX§c#Û¶Þú°)–Ë3u­©K2 øž^ú€üVýÇtŒ“¶7@#ðcÇOç¥àÞ=Lõ³f瀒OÔ«°Âî°=ä³c–uMA“\v»F1Ç,¹ðûg†¢¿ÿÒðCå)gí†Ä¶+¼…õá®·\ö-«ÈZJÿ‘E‚(B:íÇSäõA·õ²â£ìa‡`5t6ëÉé6['‰ƒ·3:¶þ-KBár€¤mÿl¦˜_“â’¯pÙ"q‚£ë©gÉ(Qû¥C8¤W9S÷ëÈiꂊ+ýL“#'! 'Œ˜ÔµeŒ‚·Æ„µ± C4Gª€xëU!)t´K„¥Ìö‚ÁúÀ‚}N±/dppäÇrVF'òÖ‘†ŽÉ&yܘ}53 З°=¡ÅD A‰âdpÓEF”4Ï‘XfÚ\¤’7&NµœêjUwˆ­xÊŽ8A‰ÖT4ù­dX?6%Løi:\[[íÄ΃’O.YH» A<ýtk«ü]Ü 2¯§;Ù$.I`ù7³}(ÇFíÒΉÜq½m qçÇKªh¬ÔX1v‚Êgn" NÚ Ýí.«O‘víAÄ@÷ŽUk¬9#U™V$zÇ×NÔ.ªëÍd*¶ïò0gnêH§•°ª‹ ¹æ0M_Ò Ÿ%óEO µÕÈ ‚8«)€òhQ“㲉nM;íÃ}Oê–¶BܬªBgS¹}74·%†/*õ€Eh$°'#† >ÔvË>rMqÁzHßW 8 ûlµ¬ ‘>›ÎŸb“Û©³Tbwb«òé=uDî‚Òò WÌ‚8ìu/•U·©+j1}À _hÔ½XuÔè‹k-…›@åÃH”~Bª …,‚[0dÇ Õ¤+÷5Y•kK9àµ1ÚAâ54Å E™Þ~   RDï‰å«ïSÇ |U“Ÿë8ÈÖü™ ©¬t/] n~¼L‘ËR©Ëi²–]‚ÀþÚº`.ÀŸ¾³Â}gD%,;)cŸ ¨Ú'QT±Yæx“0}ƵQÄ–-YÁ± èH Ž3—.ƒ<£øêÿÔð¿%‹sUDâ#ë¸×]ý9Ø+ªº&ºMlÌE•«Èûºêgå´Su ßã“r‚'26åÂ`é%…º;à앃UfA‚àôÒ ëˆï ì@?Y:(‡iP¼‹e”2’'øhuX¡{f$"í>àí«bDU­©Yg\Á[§¸:ÊšÌ%#'`Q'óÕÕß[•!2Ÿ’’$ÈãÓL¨W@VÆ`|FÀ{ê)0ä†î0N dèk±b7mWlÙ`=cW~á« “LËcÛ¦ša×àR¬êŒ'´6,#®­H‚º¬Zì{”£ZE“Ô:Î5T¥Œ@ñê^ïrx–™õßMøGv.¥¬S]“‹«F[Ž'W14´[HµÜ­kðV€£'QKZ„.pæí<ÀÚ4½8¢ù~€¯n㨠Ævà5säÒϘ…ë,¬ñ=€·);>Æ|ä€Ej@`X©ß0 én™„¯H+pE T©°HõÔÃ@l¬ðv³UŒ˜‰ž<êÐåUYk‘÷3œAãG¦Ú³¥áV—šðbÛ%`ñˆþ:_HÚd“*Mi&ÀCB²Ô¨„0èÊ.Q>t ÒÀUÚ „±ž×M aœYmARx‘òÛ©¡-á£bÙ·ØÅ†üøŽ]O©¦-‡Ç¦Îù¬¿òÕ—Jci±Õ­R匨i‘Óý @ÏÛâØ€­%~U' }9jᤷªÙ©fuب‰Â"{êiŠsÜÖr­÷P cô᫦"ʸ˻oz'³ýqӤƲ¯ÿÕðʪª–ùÛu…LሠèNúë¤Ï\í¿–¥KŠë8.î¦Ðo:¼ ºk,n £D…ôÂ5) g†Í@F­šSˆ÷ÜF¦®ÞÀ×—’¥âX(ÇHj`l½ì\«­ ’Q°ž'ž$íôÒÕÚêòl(×X•ª±Í€ióÕÊ›û¾ÖE ÔA wR}wÛñÓ뾚1B(øYl˜ ºa k]»–©¬™{ á© U+½šê¬}Œ¨Ó4ÒªpSR·ÏØH¢G[ÉTbËÁò0Džšz9â¦eTcñ;#ðËJŠï´RÆÔ®”c- þ:²T¢> ùºùƒI!ÝIõßmýu~»é­:*ŽÝ¸vØã@Ï0Ö5¡,seÈÕ1ÉìU<·MµÓä¹¾›…ù@2»r#LÓÂju U‚UÈsö‘h•—ÈÉ™–aò;‰>úzxçU¤ºª» IÄA€ÃOЯhíÖW&ÛbO"9þ:I¥RâÃH¦Ëj€¨g‘몈µµÜ½µH0¯Óme£ü| p¬ö2Or¶øÀ^`÷Õ‰O&§öìÜEfAB6'm[S ÎÚê žYH¥çÿªbxè¥ÿWnp‹Ù‹¡AS!SZe1?cc]¥Û‡QÔêzx}~#ÁzÜÔPÉ ·;êÏå4?¸ò'üõFxá ='(Ÿ®›LÿÖñ ;Žé}`­›!޳®¾þ\äNµ€{ËŠ³7ê\Ë–ÄðÄgJ•s¹åÚbÑÃùëH…-¹ï¿³[A, ©RXžCXÛ¼h´_#ÇíXl\HÄqcêx &Ôà\ªœ£“Hž>¿ÏTT©e%‚0.N Ù ûpÖ§Ô×·‘äºÔÎJ‰)^8“¾ÒN³m¤È™j𩌆af>\Φ*»‘)¢ÆØÕŒ·ôA«fD.»l´°¶¾ßÇb€'Ôó5[ä ¥É®§Ž?&ž³RP»;¬„ı¤êo&–[Xà6".@“Ðé¦*¨•\¨8 P̬ Èì8o­Oñ)·‘äºÒÎJ )^8“¾ÒN¥¶¬È™jð©Ì†atÇË™ÖpWr%XÀ";ú°qÑkVdBë¶Ë‹ kíÂìk9ñ<çMÕo, ¦Æ5Tñ±ù4ò3RP«;¬Œ ®ë-¡1¨9üªY, c…'õ IŽWìa¿þpŠô‚®~Bc¯4ât‹.­ÙPÆ@d˜±zêZ¸I…ù†HÜþƒ«Se¶‘ýD‘·¹°3ãSš–C6Ѳýt« š(1†l}9ꂵ«j[)¹ÆÁJÂ;Áã¥DÈ×R– Ù$¢¹úóÔ꘭c{' Hæh)Q]uWs²ïÄ+±<öþz¨–ûû%ÚÏÕ6픎ü½µ-Åç°Ü>([ YñÛH_FªZÕv¥åX°ÈÉ#ØòÓ¸)S!ÎE¡€”€=‰;h¦»ò{†6†1í°å¥D=»û½Í¸Ïoã1N‘©Õÿ×ð·sBõœÜF>Ÿö“ë¼s¾µ,øšàíÿ§}%ø ¯Ç‡%•,!L7ÅNñf50Ó©¥ˆò,,¬¥¾Áï¸õßž¬…¡²Ën* vªµ_¸ÆòHØiiˆTšë±HjìVÁÆAÆüJÁÖTäþŽÕªQ~ç'DÑ{(„Ã+*©Ž[#Çœk{Dö[K ¸2ÁÊ™ ôÖ|h)kÚ+uEU†žäϸ鶚¬¨Ð¡í%SxÒ l±˜Œ }À‰ /"ÒÐBùD6JØÿ+Y;óˆßK´™ X°Tú‚Œ@óÔQ q ¨’òÐ`úï¾}z1L2²ª˜àá²lqùëwDïm ¹!peƒ•2AßmgÅ ØöŠÝP*Ážà3ÒGÓOTÔ*Ї¸8¤˜Ò lv`J0…û€¼ˆ#K@y äyÙ)Ä|µ“¿>év¬áJ¡•R-#%æ6#PgbÓ[b+̰d¿ò;0Ö-hCw± Ãä´Ö`Ç<6Ð!-z™–°.­Êî ²ÆÂHùÃSU^w+rQ$6Ê'œðÕÚ††e |„PÄHí¶cÐí¸ã«ûDÂicnJAU `°Fúž+ª°ØC¼:’º˜~;i mÄ“kwpŒrßJ@P -¨”æãhBšÅ*øör[ÁŽR ó#†¯ˆ:J…E¼MrErZîLsãÇIþ†fþ=ª”Üh¤ƒ$ ôËbN®áé=û-wÒ>ËLc—ý»qMÕ̡ȪºØg°²£¼ž;/]*’ÒJyuÚÄÇiLôßp5|ôýݸ¼#.)‰™ÔÑÿÐðŠ«[-eßrvë$z)×[;\í– ÷ëäAn'¡¯€õ/JÚµV› ,À†ñ¦˜Q¸f{$Àس6ØF¦¨ØG‘ã1fRg#ŒÆÇãÇñÔÿ@c±ÍëÈ ×|`îLLj(VšÆBÛ–ãR”ø€yñ¸Š)ã±TQæxêÇ Òhÿ‰2=µs ÑÙa? ”’Ǹ$wᆖ¡i°Kg$áöGzŠxu¯$Ù¤bJu÷å«âÒŽÌ”:«§Ü&&zzýusðhMiã“+ ø͇¯?mOAUþMÊVÛ †$%€ŸcÃIm\…« âÛC+¬§Äu3#SÖ”ñت(ó+=Õõ*¬4+ù Ûx÷5y³¥Xs™àFñ©)…”±ë$ªØIf%˜O F}Ê£öýÇœ#çˆË M1ÿÑðñlW½‘°•-3Æ"']oÕÏk¨K*±ßPò¬ÎÿÄž^Ú“…kÛµj©n ³F1ìwÐQ]¾=ª*ÅQÄ«`d¶ÙžSÃZ–!me'&¬9jçäDu8©«eUuíª—™Ü‘'Œõem¬´€TKé§¢¤nÓ„-Etâ²¼¸ƒ¾¯‚7{S½^NÕØÿäV,}‰Øm©ª V¸îv #‰å#ŽˆgU ±™ï}Õ™¶‰Û¨Õ’B—eŸ/ñF_Èœõ([1µ K Í«¸ ÏãÈéèrUMu÷‚W`Co$ô嫆”ï‘`¬ $d3é©¶ŠQ»N´$WN+’òâú»‚'{W½^V5v?ù‹èNÀF¦ÕPµ†ª;¨Hâܤqü4Ä7ƧǥŒÏ}›«;m±Û¨Ö¤‘)VYóÿ§åñ²w sŽz–¨¬4°ÜÚ»…^GP5*¦ºû‚ÀÅv7ËNZ¹0Ôö•¶Ö{ˆ 㱈á©zB¡‚´º ‘ ­Ã¦¢¸ù‡ôÐ ÂCY±"G ÷ÓLRmªÛ–RVÖ™ò8¹>º»©˜æòœZësT4ÁYuvæÆ¾ÌOÄ™à[¦1V‹~% Eãõ-vžpe;MS[M²²°¤‘mŒøêá§þåë¨xßFûVÞN¯Û&&5®î3ÜÊøüPÀm¸núK ]QÕ^Ö*U`Ñ<ÏM(Ø«Çve—¸}9ë7üS&X?«SL¡Ÿ¬ X‚5ö—«4p .AHoM3YÛl‚€¢Æß\¶Xi†»4Ï{ü¼Fqã1 ÿÒðº+EáÛ !—¿~{Èÿ¦ºéíeõë‹Ë¹ûÝ~íôšRî5 ‹T/ŠŒ³ÞyJ±¶Eè.Xb y=.| ;ž6B§ÏyˆƒãÃN(Õº@‹(-Y²ºÂ=lY‰á¹ßc©‹«b¥V¸Ÿ“ò àl5¤.ÚÒ»^á .Ã(Ûߎ¥ ™Új…l͵ƒiü&utFðưn­ÑÎ8ÎDG8ŽÊ©¯Ç'äÀ’¦ 69 ùF¬‰ .êEUZ€$”eO#¦…Ù IÜ0DpõÔQöÅqÅ™@DP¸NgA“IÕV®ÿò;è4lM·dQ'a–ü€Ž_M~5–ÞIUbÔ¬9íÄî+ÏßVu/ Ö + ~0vë;ÃWP·´‰PHÍa™‡ÛóÓWñ•@ Auc-c6àyjB­J"÷¡pê" t¦us¸š]ô­dœX\øg ™ä4³ ]ÜpYX”R ëò囹Uyl©J3:ƒ‚Ô"=Èæu%0a¿sä1Jڮ܃D¼´€NžÓ¡ål®±i¯lēę+µØd*¨I³yƒÊ$êÍÐÞßÜÃ3–3žØDÄÌðŸËLˆÿÓð– Çæý’°²¤õyk®®u¸•³àYˆ°qž{hÚÞ€ÿºr¨À2º[s±–g«?À1©äÞ;¨ÄùýÄõë§9¦…k‘@’9¢É-m™¨ûÆ¢«$£dȲF*… Á‰$“ÃZd–²ÌlLˆ%ƒ ÿ®š­:Á±,îï,±öž›ÄϾ˜i}Ê\…B[%BÊúÆš+¢UóÆ›BäÇ‘Þ µw‰‰YÍv†ñÀI#s¤Ä Mü(éò ypÊ–°ã”úîcIKÊ‹ 7™È@EB¾²`môÕçʤ¬’†®Lwlb`p뾊 ¨«"C)`Çb «}$I BèålWWî6YõžZb¾¤g8Ê阞+¾‹2Áû¹D÷?«®=='NÿÔñïwWöÙvöžçq×_߇9ÿúûv~æg!ÇûwˆÖnüµÆ§c´qžÞ,¸ÄïÇ×NÛþz»ßãןM/¡—aŸÎ;ÌDòã¼k*o‰ßÆü¾éÂcé«üêR|Îî#<£ú&zŽ8òÔ« 9Çêv¢DDÌ}tQóƒÛíD=6ãÛ)ný¦oöÎcìá”|fu›‹4Æÿ=qÛËú³‰ôá· >Ev·îã9 ¿¶7ã­\A[ÜÌvÃ.÷}ÚQ]ÞÝ™c–|£‡¤sÖbÓÛ·îe‰ïqŸüµh;?ÕÆ~DŽ1´êhî¶=ÜùñÆ'~;j kÛŽçôNsÇÓùë\Øâ½©à{¼r‰Ú#–ˆJN7wgý>¾‘ÏQ\½ÞÕ1‡ǬèâçÇ·é”òˆÿçV«;Ø|{½É9eÂdGÝËRèÏ#oÌw»þS¥"ÿ?cž8zεÄÿÙ endstream endobj 58 0 obj 38240 endobj 68 0 obj << /Length 69 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚ•’ko¢@†e`D.rQ[­ŽxA­JUkQÐê*·([k?ôÿÿãfc6ÙdßsrÞ¼“¹<'“ù€¤ „$ î<òθ 4' "OSà s,›%ï³ÅÈÕ–®kªÄ@Š¢HBçKJEfàµK½dA抭©½z›éÕ‚ > stream xÚ­Tks¢H¼”‡¢™Œ H”ˆF#QD”—<yˆ“šÔîþÿß±3;_&[535§Šº]ô¹§oWÓ77%F‚ †¡ÒÛ A%€ÿ!\9(Q¥© ŠV¢ ÿÀ¬Œ¡à þHB)Fïï(êS‹©W4ÀÅhàXP0‚nÐIQý¹Å6pôú÷+þ› &ØÉÆ^ ˜fo2î4¨*]¯–]#q”[†ïvØV‡çî‡Sé¡I‚º@áh!a ÑÌ/±* ÒZóín_xŽúǰ  Ÿfòd$)Êtª¹®ö$´Y®×ž üg …Š1ÚóøýŸWOž¨îv9yV SWä¥¾Ñæi¹1Lkëltg˜k÷pŒÕL’µi™]_ ›8|SBë¢uþëï÷ÌT]`¬¬0Í"Ï ãdØN”%QǾÓ­œ^OiäÚÞ>I³C²µWEn œ•£·÷/_.û­»-3È/ç4JòãñxH’óKâ¹QÉ)q ??eÉ!Ó> stream xÚ•Smsš@Vy5$Q±"!¦IPB¢( "AD|IZÓi3íÿÿ=u2íL¿ÔÛÙÝÙ»g÷žÍd€ÊÎd3GHäqŠ,æsIpL-’§9Q¨”Jå†X+a9ÝÙƒÙÚÇÁßÁlàÕ›þ }!«}³Ó`iš&0¬HÒ MáE‚‚g!_ èCIQ$Ž“4 ñ¡HP¢™¤5š¥ çVàE±~~Zæ%Yjpå*/ ˜֚²ð©Ö€IŽã›’Pe ƒÒ“/ïo«åöý[Ô»m?w-éJ ]õê³fôT‰—ÛÆÐìjZ·oèªú`šºRÆAe÷ëÏ÷·í_ߟF/ôúºá†a0µ ÃöCG¿½ÑÜ›xazc'H‚áu‡¯2гÙn‹ÍÛ6›“xN-'ŒC¨îÄ_¬c»7 Òô)ðŸÖ/Ë8˜§+¿+±Ø°l%É£iºÉrîØ³Åëfîºþlâ†qàǫׅ;°£õ*z|Œ×/iÌŸ“QëßIèN¬Ž,·­©;yqú<³­ñ°k8ÓélþœFcÊ6K8pžxãv@÷ŸSiu®ùS¶~­ëmͰƖq§un.¯:Ý^hÃKîG»Ò~Gë™8,]J9ä@‰Ê§*SĘ*Ï×’ÒR¤_çÊ•º JÊeKQnú„Ò»DYù:_c‹àƒˆ$ž;C’S:¿O’D')z''ç¢fO= ò…a9 E$†´ƒ¼ßm 5å ¡“'Κª®«Í3ü#‡üçš (Îr<ϱxÉ'Y-À^ðzÜJîk½ü[øD/já endstream endobj 79 0 obj 634 endobj 84 0 obj << /Length 85 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚ•’ko¢@†e`D.rQ[­ŽxA­JUkQÐê*·([k?ôÿÿãfc6ÙdßsrÞ¼“¹<'“ù€¤ „$ î<òθ 4' "OSà s,›%ï³ÅÈÕ–®kªÄ@Š¢HBçKJEfàµK½dA抭©½z›éÕ‚ > stream xÚ­Tks¢H¼”‡¢™Œ H”ˆF#QD”—<yˆ“šÔîþÿß±3;_&[535§Šº]ô¹§oWÓ77%F‚ †¡ÒÛ A%€ÿ!\9(Q¥© ŠV¢ ÿÀ¬Œ¡à þHB)Fïï(êS‹©W4ÀÅhàXP0‚nÐIQý¹Å6pôú÷+þ› &ØÉÆ^ ˜fo2î4¨*]¯–]#q”[†ïvØV‡çî‡Sé¡I‚º@áh!a ÑÌ/±* ÒZóín_xŽúǰ  Ÿfòd$)Êtª¹®ö$´Y®×ž üg …Š1ÚóøýŸWOž¨îv9yV SWä¥¾Ñæi¹1Lkëltg˜k÷pŒÕL’µi™]_ ›8|SBë¢uþëï÷ÌT]`¬¬0Í"Ï ãdØN”%QǾÓ­œ^OiäÚÞ>I³C²µWEn œ•£·÷/_.û­»-3È/ç4JòãñxH’óKâ¹QÉ)q ??eÉ!Ó> stream xÚ•RÛr¢@Œ ä¦fU Á "«¢QD%!h4ejÿÿK’u“ÊËÖöË©ééê3gú\]ýJ@1 CRú$ä+ñ®ÉðUŽ&±Ï«J@XF‘oJ‚ivEªS8†æÞ¹!ŠÃjK¨Q8(ÜÑ? œ½Õ¥7Éu–ahHàå Ã7ºº© U&ÈJNâ ×(˜Aùs½'‰·m¹U宥NO{ðÃ…ÑêÕÆM[n²D®EYe™¥þDëÊmõ~nJG›X3kžÒ­cªý»©=IL>V†Ç¥ ¡cxQXS/Ü.ÝÍËÛ){\'ˆ“ÈÕ®Ë_¤-©? _·ÇMœEžíg§}’$Qt8ŸS€ x€—¦þÃPUu7~ýõº‹’}äÍWqO»xw|;ï£Ø2ò±gbN¼hÌB…K{øöÌ]¯ýÇ4}r6HP|Ööýp8vVkojŽ-{6OLMúÝØ^Ìu™'KZ¿- ²¢YÛ½^G–ÅÆ¦Ðjæ§®TƒErÁÖx¶R¡YžçhŠb8Žeè $!IŠaÙKè×å½\*šÇùôû*ý¿ÅF’ endstream endobj 81 0 obj 461 endobj 72 0 obj << /Length 73 0 R /Type /XObject /Subtype /Image /Width 42 /Height 18 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚu’ksš@†a—‹. Fãe£ÆE—à^@L$ÆjMlg:Mzùÿ¿¢«i§iû~Ø93Ï;çÞ‡ãNá¹ÿ†ÿƒxžM¢(²Böü?‹‚Œ°ª©i1­é†®)é´‚‘,JHÕ4Œ$xªçeR»(`ITòõ–ÕjT …29Ï(™b­^­2©c•£›á ™O§ Óâ(´-§o•s%k4êÙM¢Ë€­”Fw8ô‹Á¨ØK»ûÀc÷ªÔp—ñÄQ¢ <•J7ðGA²ök®¸ï_^_>íï¢d3·.Z³M2õ'ž•—/dÍÛÐëùÛ™©gª·Ï_¿{=¬ëݲk:ËÝÊÏÂ>Q /åÚóصÇû¥CŠæäùõËËç§»ùj·úÁz»ô¦±w©²æâ1&‡íô¦iÏvŸ÷OÛE=¾Kâd÷P{²¼mh ‹í¤½x¿O&ƒ~p¿Šæñr:‡›Íf=¿1é$vë*ä„Là =ÚGw‘ߣΰOÛÎÀi^Û^¸}»^£Á¬[Fƒ¨dûãNãÊ¢f*9Ï—.Há¬Xo¶[—¥¡ÞÈ4$À)[£ÎuùÌÈåôŒŠUŒÒc”Bj–ÝgË–Ó**ì?y˜2È%É!Ibj}`9Zñ抄óÕZQÁÑ*!¥ºršÿVʪ¡céÍ&%YῃÂ/íx&"øË'v‚?æOÅ endstream endobj 73 0 obj 556 endobj 70 0 obj << /Length 71 0 R /Type /XObject /Subtype /Image /Width 42 /Height 18 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚu’ksš@†a—‹. Fãe£ÆE—à^@L$ÆjMlg:Mzùÿ¿¢«i§iû~Ø93Ï;çÞ‡ãNá¹ÿ†ÿƒxžM¢(²Böü?‹‚Œ°ª©i1­é†®)é´‚‘,JHÕ4Œ$xªçeR»(`ITòõ–ÕjT …29Ï(™b­^­2©c•£›á ™O§ Óâ(´-§o•s%k4êÙM¢Ë€­”Fw8ô‹Á¨ØK»ûÀc÷ªÔp—ñÄQ¢ <•J7ðGA²ök®¸ï_^_>íï¢d3·.Z³M2õ'ž•—/dÍÛÐëùÛ™©gª·Ï_¿{=¬ëݲk:ËÝÊÏÂ>Q /åÚóصÇû¥CŠæäùõËËç§»ùj·úÁz»ô¦±w©²æâ1&‡íô¦iÏvŸ÷OÛE=¾Kâd÷P{²¼mh ‹í¤½x¿O&ƒ~p¿Šæñr:‡›Íf=¿1é$vë*ä„Là =ÚGw‘ߣΰOÛÎÀi^Û^¸}»^£Á¬[Fƒ¨dûãNãÊ¢f*9Ï—.Há¬Xo¶[—¥¡ÞÈ4$À)[£ÎuùÌÈåôŒŠUŒÒc”Bj–ÝgË–Ó**ì?y˜2È%É!Ibj}`9Zñ抄óÕZQÁÑ*!¥ºršÿVʪ¡céÍ&%YῃÂ/íx&"øË'v‚?æOÅ endstream endobj 71 0 obj 556 endobj 64 0 obj << /Length 65 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚ•RÛr¢@Œ ä¦fU Á "«¢QD%!h4ejÿÿK’u“ÊËÖöË©ééê3gú\]ýJ@1 CRú$ä+ñ®ÉðUŽ&±Ï«J@XF‘oJ‚ivEªS8†æÞ¹!ŠÃjK¨Q8(ÜÑ? œ½Õ¥7Éu–ahHàå Ã7ºº© U&ÈJNâ ×(˜Aùs½'‰·m¹U宥NO{ðÃ…ÑêÕÆM[n²D®EYe™¥þDëÊmõ~nJG›X3kžÒ­cªý»©=IL>V†Ç¥ ¡cxQXS/Ü.ÝÍËÛ){\'ˆ“ÈÕ®Ë_¤-©? _·ÇMœEžíg§}’$Qt8ŸS€ x€—¦þÃPUu7~ýõº‹’}äÍWqO»xw|;ï£Ø2ò±gbN¼hÌB…K{øöÌ]¯ýÇ4}r6HP|Ööýp8vVkojŽ-{6OLMúÝØ^Ìu™'KZ¿- ²¢YÛ½^G–ÅÆ¦Ðjæ§®TƒErÁÖx¶R¡YžçhŠb8Žeè $!IŠaÙKè×å½\*šÇùôû*ý¿ÅF’ endstream endobj 65 0 obj 461 endobj 82 0 obj << /Length 83 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚ•RÛr¢@Œ ä¦fU Á "«¢QD%!h4ejÿÿK’u“ÊËÖöË©ééê3gú\]ýJ@1 CRú$ä+ñ®ÉðUŽ&±Ï«J@XF‘oJ‚ivEªS8†æÞ¹!ŠÃjK¨Q8(ÜÑ? œ½Õ¥7Éu–ahHàå Ã7ºº© U&ÈJNâ ×(˜Aùs½'‰·m¹U宥NO{ðÃ…ÑêÕÆM[n²D®EYe™¥þDëÊmõ~nJG›X3kžÒ­cªý»©=IL>V†Ç¥ ¡cxQXS/Ü.ÝÍËÛ){\'ˆ“ÈÕ®Ë_¤-©? _·ÇMœEžíg§}’$Qt8ŸS€ x€—¦þÃPUu7~ýõº‹’}äÍWqO»xw|;ï£Ø2ò±gbN¼hÌB…K{øöÌ]¯ýÇ4}r6HP|Ööýp8vVkojŽ-{6OLMúÝØ^Ìu™'KZ¿- ²¢YÛ½^G–ÅÆ¦Ðjæ§®TƒErÁÖx¶R¡YžçhŠb8Žeè $!IŠaÙKè×å½\*šÇùôû*ý¿ÅF’ endstream endobj 83 0 obj 461 endobj 94 0 obj << /Length 95 0 R /Type /XObject /Subtype /Image /Width 43 /Height 16 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚ•RÛr¢@Œ ä¦fU Á "«¢QD%!h4ejÿÿK’u“ÊËÖöË©ééê3gú\]ýJ@1 CRú$ä+ñ®ÉðUŽ&±Ï«J@XF‘oJ‚ivEªS8†æÞ¹!ŠÃjK¨Q8(ÜÑ? œ½Õ¥7Éu–ahHàå Ã7ºº© U&ÈJNâ ×(˜Aùs½'‰·m¹U宥NO{ðÃ…ÑêÕÆM[n²D®EYe™¥þDëÊmõ~nJG›X3kžÒ­cªý»©=IL>V†Ç¥ ¡cxQXS/Ü.ÝÍËÛ){\'ˆ“ÈÕ®Ë_¤-©? _·ÇMœEžíg§}’$Qt8ŸS€ x€—¦þÃPUu7~ýõº‹’}äÍWqO»xw|;ï£Ø2ò±gbN¼hÌB…K{øöÌ]¯ýÇ4}r6HP|Ööýp8vVkojŽ-{6OLMúÝØ^Ìu™'KZ¿- ²¢YÛ½^G–ÅÆ¦Ðjæ§®TƒErÁÖx¶R¡YžçhŠb8Žeè $!IŠaÙKè×å½\*šÇùôû*ý¿ÅF’ endstream endobj 95 0 obj 461 endobj 86 0 obj << /Length 87 0 R /Type /XObject /Subtype /Image /Width 42 /Height 18 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚu’Ys¢@…¥»ÙD â’A㎨ˆÄز1„¸d›©©šÔüÿ¿1­VMå!9/÷Ö=§««û~¹ÜI•ûVŸ, @„è“@¨ËôÔK¹!“/ˆò•¢%e–¥‰C¦¼ÀÓ”œßz›ý!M’OÇö e £a.|oØj4MgÚ¿æapÓ[¹ËíË!^ÇOOq°öœÉÜŽçQ–† Û´nñmS¦)(ÔgázîÞ?g«¹¿{;diŒ×ÉC´¼{xûõš.­þ,ô­ ÔZÆx2‹ÏÉýûËaŸ†QvÌ¢ ûý÷ãÅ´'aì¨mƒ }>$ÑãÏ?¯Á°3‰’™F’bÓ‹±mãÝ1ÛnïÃŽüÅ"LÓGû}ŠÇæ,ÚL~pæ5'À“ƒ7‘7·zÛ¶¬ÙÒsFä] w:¹!6Ë l©ç.íùùA¿]¯–«š¦ÖŒÖM½¦éºnÜ´-÷Î1$DQ¨ šö@¯(d›²Às¼P ’,ò§F,ª±Ý.qdI€‘Ô£*²Ì…Ñ ÏBüU­iTòˆ:R(*" ¿B¼¬\åipa‰f9¯áŸM Ñ7,Sÿ½ÝkO[ endstream endobj 87 0 obj 539 endobj 76 0 obj << /Length 77 0 R /Type /XObject /Subtype /Image /Width 33 /Height 15 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚ…Qio‚@•DØE ¥å*mÕV¬¸¥Õ äдMMMzüÿŸQVýÞ—LöíìäÍΛRé?P€.(rꘄžyqcy+  YŽcYŠá¡Èœ¨èºÌ³eT«AŽ)ÀòuíR†å“"àä–;°¥Š †Z—$©Zmؽ»¦*Á£ à5wùÜS dv{mÇiµ«9ðã[«UhªÇk÷Bl´ñ gþÔùq¾~u4Ècš&ž!_Ý/£ Ú$I®Ö¯Ÿû]àè\oýŽÙÂë4ÉvY’¤i¾ÿù=¤cZLò÷x2xxÚdÅ[´ 7iþñõ}È&¶Hxm¿mC¾ÃÕËrŽgË JwÛ,ÂŽÄRdÌö4³±‡½ápÐítÝ‘7™bìõ-© ˆQªsÛï¶›×¶eº¦jºiÙ–iZºB¦ VWëF½VE„ À !Á"ørñI²,†% .3dqô‰A¬þP„3‡ endstream endobj 77 0 obj 374 endobj 88 0 obj << /Length 89 0 R /Type /XObject /Subtype /Image /Width 41 /Height 16 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚRi“šPHðqˆ›9<ˆŠ¢Ã+»ò·BR›Êÿÿ%·¶Öý”ô§™®®™šžn4þ (š¦)P$‰¼u5hV:mB~ È7šaè%¡kL§ã¾ªèêlÖƒ© ×nC¦®^“M±¿Œö;϶ŽcªdYÈ d]—%Q…J^í-u•à Ö+?I·öHûôQé}U5æó‰aŒF†ÖaÑ ÄñþR w6±B\ÇheŽ,7ð––„Þ·ðû6X ¥&IÐyZæþXUGþùùç%CÞÚC8‹Ã(IïÓ ãSl«-ðNˆË§ó9CÛþõ\“,Çç§3Æþõê]Q 5]yšAqä…[wÀSµ=½etØÎb±²gæÂY»þ.F;³qǶLë«ÙmWÃg“¡¦êÚgYÑ{}c25ÇÆ`ÐÓu­+wYh’¯/¼“*9Øb!ÇñB[’ÚÏs\Í´ ÛÄM(®©xy}í¯ï»â]8þ¿ôD‡ endstream endobj 89 0 obj 439 endobj 90 0 obj << /Length 91 0 R /Type /XObject /Subtype /Image /Width 33 /Height 15 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚ…Qio‚@•DØE ¥å*mÕV¬¸¥Õ äдMMMzüÿŸQVýÞ—LöíìäÍΛRé?P€.(rꘄžyqcy+  YŽcYŠá¡Èœ¨èºÌ³eT«AŽ)ÀòuíR†å“"àä–;°¥Š †Z—$©Zmؽ»¦*Á£ à5wùÜS dv{mÇiµ«9ðã[«UhªÇk÷Bl´ñ gþÔùq¾~u4Ècš&ž!_Ý/£ Ú$I®Ö¯Ÿû]àè\oýŽÙÂë4ÉvY’¤i¾ÿù=¤cZLò÷x2xxÚdÅ[´ 7iþñõ}È&¶Hxm¿mC¾ÃÕËrŽgË JwÛ,ÂŽÄRdÌö4³±‡½ápÐítÝ‘7™bìõ-© ˆQªsÛï¶›×¶eº¦jºiÙ–iZºB¦ VWëF½VE„ À !Á"ørñI²,†% .3dqô‰A¬þP„3‡ endstream endobj 91 0 obj 374 endobj 92 0 obj << /Length 93 0 R /Type /XObject /Subtype /Image /Width 66 /Height 18 /ColorSpace /DeviceGray /Decode [ 0 1 ] /Interpolate true /BitsPerComponent 8 /Filter /FlateDecode >> stream xÚ•TÛr¢J•›Ü/ƒ"""ÆE@DE ^ÑhD3΃9u&5çÿÿá´&S3Î~èÞݵ×êÕUkïTê”úëøÁ A `»‰ ”"¿J!$M1,Ç1d#–Æ‘(ˆ¤ìZ !/K•ªš±\) ħ"äªìKÝ%~]gïò96 _äà¥Þl»£¡YÓÛžo*PÄP$Åp¼ÀsÇÒAsæI$÷߯ç÷·ãù㟗Ùé{®Ñh¹þ8ûC¯ßiµ:ž?è´ ×÷û˶-Ó²œaàj<!tÉ ÇÝÞòüóãýüã¿“h2ß¼,o¼Xo^vÛxµZ›ô/ š÷8ŒrUo:²œÙé|J’Óûù°Š“ÓÛn-¶»Í6I6ëíþõ5IöûÝfs8ÆžÑö7ÇÃÜ5ºÑÔ–HÀ û³‘i…»ÝÌ÷§»ãvNoÛy´X/£Ùf=â×}rødxÝŽ%µÿ6m?XÏ3G ¬6˜ŽÌ6déº,¢q°Ü¾Ìƒá8õAÐïgóÅêò‹0œMÌ"Ÿ{šw^­b†‘U `„’íÉÈz2ì¦r—-5»Ùt†~ÏjµÍVýÑ0ë-Û¶ÝáÈs Ã2TÌ<ëi[Q­`ÔÈ¥a¿«÷y endstream endobj 93 0 obj 762 endobj 55 0 obj << /Type /PropertyList /Style << /Type /Style /Subtype /Shadow /Offset [ 0 -1 ] /Radius 3 /ColorSpace 9 0 R /Color [ 0 0 0 0.5 ] >> >> endobj 97 0 obj << /Length 98 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >> stream xÚ}’OHQÇ¿³%B¬e&RðN¶Wí`ŒÝõoʶ¬k¦²Î¾ÙÞÌn%Bˆ.AÖ1ºXÑI:†‚b]"è(‚—í73»îˆÚƒ7ï3¿ÿ¿ß{@](mšz€yÃÉþ(»;>Áê7P‡A+­Xf$‘v™lqdí}…䜛áãõÿ] ‚U€Æ¬ÇמöxÀáû¶iO:¬äÒb“¸M¤’1âWÄg³>žöq†[ ñ2ñMÅ'"()Y'æ±ld4ƒä—‰»2–’'&ßÀSg^™öÐ}8õ¹&›°€åwÀ¥Öš,Ô \V:k²Ý¤;©iÝR;;\‘Œu?ÊåÝV þ°ÿ¼\þûº\ÞC9¾u¥(J•IÒÀëÃ]ýÜàBS˜s_ QP5ûFz¼Úë׋Gõ%«t{3qW°D÷0vz ¼ü \}\ø$€Ôu¡ºmþÀÍ+˜…–ÍÙ¬C–;XØ9:Y„^g±BÞ,Ú\°ACioci]g®©Å·¸(ñL;òz±Úï9ÚAnŒŽÐIó ¨Üê­°4“I÷ÐÝ x#Ã{zwA¼¨j}ƒÎ…Ðþ¤Š¾Q¥óš=˜ò8Ðmèñá Ã(Äo{1±cÚÑd5¾Ué­ÊgÒ·t¶üÆlaȱi"ßÐ\.5æ±”šËÅâ^Å8tph0èk€!‰~D† TÒhd¡‘”»6‚ØÂì±–:>f¤ß&Ÿm×çŠäíxÝA4Ž…¶ƒLþ&ÿ–·ä%ù­ük±¥ªiÄ”¦¬?ûCqÌÕ¸m¥&/¾By#¤Õ‘%iþ 'ËW©¯:ÕXl©Errð'ñ=_—Ü—)Œi7Ò¬›©äê,úF|ÙNšٮͯ6×rm^™Ü ®ÍšUáHWü «Ãÿ5;¿?ÿͰh endstream endobj 98 0 obj 706 endobj 6 0 obj [ /ICCBased 97 0 R ] endobj 99 0 obj << /Length 100 0 R /N 1 /Alternate /DeviceGray /Filter /FlateDecode >> stream xÚ•SMkQ½3VÜ„*¢¥tõ–E’0~,¬»˜¤iÒcš¢AÇ™—dšùòÍ$šÐU7nD»n@—.ºpQèFQ(Õ_à¢~€(t)ž™‰ÉØ*ê…÷Þ™ûν÷Üû¢±uÕuM™Y¶/ ÕLýjý;ò†d§ÁTÍs3•ÊB€mÇætÀöÞ’œÛ© ýŸÖ¹§á|åÜñ]ŸHR€O´kÕ,px\sEà¯Ïéžf?!:t|ØÉ·¹04VjU„Ó0̸ֿÝÿ“³‰Ð·ËaÏÒÄK­#ºƒkIzEäó»~ð‘uÜž0š-Ÿž™9ÏR쌢œeLˆ³¬c¹Ÿ V´µt’©¦ÉBªÇ÷¸èr=M–ÙùÙÛQ¬·—qNɸ—`ÉÕÕÜ<ð9ø'tžË_€³aÌÓX› 1»„óüÌð‹µÈ/oØfy!òË%Û)_N‚óØõ/Vñò}¯»˜äùº¬–*8'À)µù€3 ŽßoÕ®ƒÿf¿•-G~é;ÕÉ$NÙØmb4G* ²°«”"Ø¡î ð *„,¯AµÁ/¿±fE˜T‰á€¹‹ØÝ0ö6uÀ¢‘©L«Ie]ù¤z°*nÚë‡_/¨<Ê©`UQf ÿ¤ÒǽOcˤ&¼ÖpÞ B…JQpƒŒ©xG {mjÈë ò{å½Xu>Ô9ª}+ÌßµuC†‡=Ó½CÔÝ2nGjÁÞZÙ˜ŒWÝ{~};±µ²o6z8ÝlØÕ3Š¿3¬×Är†lþÛ‰jñú¿äÁßúŸ±ðQ endstream endobj 100 0 obj 631 endobj 5 0 obj [ /ICCBased 99 0 R ] endobj 101 0 obj << /Length 102 0 R /N 3 /Filter /FlateDecode >> stream xÚ}’OHQÇ¿³&B¬Ei&R0'õàÊ æÁØ]ÿ¦l˺þEŠuöíîèììôfv+ñBt ´¢‹¤cxðÐ!ˆëRBÝ$ƒ@ð²ýff×Q{ðæ}æ÷ÿ÷{(oŒéºê´fòHO@+ÖQŽJxA+&º?°™lqdí}`>KßþýÜղѪ?o­ oÍ?kÀÿW%§„€@ :éð‹'îµø®©›ÄË©XœX'nâÑHøñ™¤‹']g†L¼D|]Ö9ÅñD‰{srÒŠ¹C,iqE#ù%ⶸ!§‰É×óØš…S¦Ùt\Ê>•dã°ô¸X_’5ÖF€åÖ’l7bÏG¨Y3­-¶Hð€ò­|~·¨x ì?Éçÿ¾Ìç÷_QŽoÀ{UÎò\aF‚ðpú°WuÓWdѺ¯0Ï$•¹Fz¼Úé׉GõEŠt;3±W°H÷0rè<ÿ4¼ªÞáJ z ž(n“ݳó3ú}®$S¦Ø"I-¢Ï:ZE?½&3i=k2.öirs“SUÑ65DÎ Æs,ÞŒ´š-ö{–¶—iCƒtÒ¼< ftX˜ŠÇ:énÐL¼g]Ö» ^H(Ý}Ö…ÐþàÝC ç³/ê°§CSC†– ÝtbbG7‘b|#7ØU”OÅn„é¬#yût¦ß²©!߯™TtÄa!:“ † ¼‚1¨`P ÑWƒˆz€:82HF! …¤Ì¶áĦµTv±HúmòÙ¶}î KÞ–×0!Ì5D¥¯ÒoiSZ”^K¿ê²%Í¿­Èkó(®•¹· -ÔäÄ—)¯Ÿ´*’$Môd¸*uU—ÐêJ‘¬ìQhÏÕ%seòaÒŽ4mgÊÙ:ƒ¾~W¶“¦G¶«³+µ¥\›§–'6¼«³‡f•9Ò;èêðÉÎíÏþ® x endstream endobj 102 0 obj 726 endobj 9 0 obj [ /ICCBased 101 0 R ] endobj 103 0 obj << /Length 104 0 R /N 3 /Filter /FlateDecode >> stream xÚc``Òptqre``ÈÍ+) rwRˆˆŒR`?ÏÀÆÀ̉ÉÅŽ> v^~^**`d`øv D20\Ö™Å@àJ.(*Ò€Ø(%µ8h¤R^Rgœd‹$eƒÙ+@ì¢ g {Í—aŸ±“ ì; vÐ@öút0›‰l„-b—¤V€ìepÎ/¨,ÊLÏ(Q0´´´TpLÉOJU®,.IÍ-VðÌKÎ/*È/J,IM9 ì>ˆ» rR€!Æ@] ës 8\ÅÎ Ä ¹´¨ Œg ófTîe`p b``Ù‰ ûÁÀ°FŸA–!¦¦ÄÀ TÏÀ°±ó¥P> endstream endobj 104 0 obj 277 endobj 96 0 obj [ /ICCBased 103 0 R ] endobj 54 0 obj << /Type /Pages /MediaBox [0 0 800 600] /Count 1 /Kids [ 1 0 R ] >> endobj 105 0 obj << /Type /Catalog /Pages 54 0 R /Version /1.4 >> endobj 106 0 obj << /Length 107 0 R /Length1 5092 /Filter /FlateDecode >> stream xÚ•X XTgzþ¾s™™37``fî·†‹¢2ˆˆ€ ¨rñ Þ@XÝÂFcLÔZ›º‰±»&ugɬ%»qóØm­M²iÓë¦nbóD­kÓÔ9ôûÏ›ìnš§ç™sùÿùÏ÷ß{Þïýþs@{€ϺMÍ^LÁvêùÚ/¯Û¾Õ¶ÃÖÿ€î~G[sëíës¿0Ñ=×AúBñ?B"¨×±iëÎw¥ jϧvÇÆîu͉óãR¨}šßÔ¼ÓËUò¨ý!µm››7µ½{Я£ö#j'x»{·rÍ|@hµWx·´yç¼Níj3¿X<,"ü’Ù€†©žßoÅúÿÛÚE²øÍM š™kI9j¿å~â€v#A0M¡feD8X bf|$í*²n„2X KåX9kò!>.èÅ.q;Ž—Ð‡ç°WcVcVbcºqÎÃ|t¡S11c1­hÁ F#êQ‹ä`Âð9<€ûpîÀ§p>†à&Ü€ëð/p Þƒwà*\‚7áç0çÁ£àƒWá œ†“pÃÓ°†a=´h"UGÅÝÂ%ᤰWhœB¬`"…^æ#yûœ;Î↹,¼†o‘ßgñ4¾ˆ§ð<ŠGp?á^Ä]؃›°ƒ¢jÁ&ŠlÅTdåXJ±¹q®×tT,#ŬÄò€b`Þ¿WÈ[?¼§ày¹ZüAFƒ^ç×JµÊ/ <‡>Hû)òñE¶E¶ŽæV¯œkêNÇ„Õé¸[o™k™oóÁò:Ÿbµ×ûpað7:ÒÓL!–¹éiÔ›žöfzš¯d»…>öá?ùÀQD­"_Ùvg£»ú0øoÑ…£˜LÑÙ‡M66¬ÆßæØ¸ú®é[àÿ¾ÅVÒQœž–šN‘ˆñEî»ßí²²{â»þ,õ„Izš›íßò7CãÛáüû4†ÆMüÁ¸1K[<RUÝOÖáä¾±bˆ~²_ÛH›Ól¶’N§‰áiÔ‘b§+ MÀŒW“g¶ÛHYëÈÔŒB`Fú£m¤ÞIsÕÔuÒ±¶ÎîóÔ[g.Ûêë ÈN³#(vFêÉB×”….Ř A‘i‹m>>¡ªnYoO±Õç)®·Úí¶ßŪ:ßÅbŠƒ5ã);#¦|¶’ÏQ)t1+`¥†l‰ú‘‘©—`÷]±ŽP$JÃ>†0Õ1Ê>¾d =UÊ_‡ÝÊ:v‡ü¨/&ÛÑi‹kêJÈ‚”©Ÿ‹”ä*‰O fñHj@ä%œWƒo\¥£ójV¦Ëd7ÅÛMvâÑ'܉‰õ*J²=¢¢°r,¿Z$ý2y$Õ}A*­:5 ÜîL´gp\nNH^¾Ýˆœ9,$œ_-?\ò¯ô޽?ˆï‹{÷¾ ÇÎ?öæÿ nuõÿ›|øÓ»òsטîáä˜˽=m;H¯R÷vÆvgDµ½Crs¸„D{ †po÷žýa¹ü?Þ—ö>ñ—ÛPêüí/ð}¿üwÿyrÞŽ°ûÓ»ØõÁîe÷åÝ,nRgÕ)±‹¢ÖB¸Ç£áµjI«Ö‹JdßíNÍLFÞÎÛÑ®ãT§äÚž‰3½r-׆ÿuå*FÊ·Å®G§p\V Bíä=qˆ|µA‚'–!Ã"zɦTœ)HN½9BR"HÉŒ7rŽÙq >q®lÑ”ŽÙF4‡Å +»óÅ¡þ¿iù™üÑû71ú…;˜Úþöú~½ÇûÖ`›×céy–ÖK(ž| £Ë;åg<Ë›Fwtþ¤=k~2ÅwŽâsS|&°B¶'Щ8bDK’¤W*‘ñj攑ç6CˆÁ¡Ñrêr.•Á«VmLöìÎÉ9$¶&WvžÊýçÏËŸ›'’9ϯ?בüø·¼òû?k=}Ÿ;ùϲ\µMì²f-p¼ðnÇ/x]9Iø?ÂòG³Ç D ¤Sóz/Ïž'›Hf®|u _äv‰]_ý{WÇ8ݧ‡ O¬^¯•ôjI8”´ˆ"êÐ h°WÔÈufÊétºÝN73ˆŨ„vÕ¸Ü(Ùå§ä.ª,gñUÜÅ;d'¾÷è†Ø5ñÓ(+šK¼Cs…C,8= Öt^ŠÙÑj²-1^0C‘Ûd˜…^µ6HÁËíN¡é3¸Te¾ìzŠDÎ*K9 ÔÄ;²{Óü¦U¥N¹‘{ëÕ›—5ÌY¸r±\û½ƒu ÖóÅРcâ–Øuàï:Å$nx‰jªG*œ˜¼§ªVüŠö„‡Š„]¸^§÷B˜Ö«Ój§|`Má—K^Lш.UÕû®O|Ï'¿öüáÒ§›V\JoýêYÏN´Ýæ&&º‡_«©æŽ0 J'ï G=$“2<晓bæ"²(l+RÀ6­”œÈ1ꨀË*–{R,©¨Â‡™íÎ0œD£x#‘:!‘307‡h]Èåç$8f«Ô¦BΕn6……»²óãsóé*O8²ô©ÆúEA{»‡óמzrñ’óüÖí—kž<»òÆMó¬Ù²nÏöy‰ñe®ØwºsÁ’m…»*S""ºòÚŽj Ë\óÊQyÇœühÕïrjwå%¸D±ñ×)¶˜@ކ ¥iX¼Q+ÅrÔ¯ähŸå9šA)ªøj11Ç š—Ï_Oo,ÿ«Ûƒ™Yý·Üs°Ì·®éùò-sóFÖ9MÑ¡=¯ŒžñÚ¬òÇs¶ö/ëαÅLã;D>гdy©B0jAˆV_n ¬I hqÂ«ÕøX ˆ0m šÉK;›=ßÌKÈÍaÒAt‹W05 C.óéŽó.ýèÜòý{QóÆÀíçåsÍ«ºñÌšíëo&/v×%•¤64Œß çËbê!K§˜´ã !ž«ô‚Dj *ÜʼnAŠåiýTÄÌ„vÓå|¹O~7búä-xKަê÷>^ã™Í€¿]Ä$ªÓ¼%ÂeºN3]Ç{ÌÀT=LüO„\ªJmœ1ÉJ°Z´fI+±ÛQkÃÖ â§ÀBwZvAÄbnš dV©”šÕÃòñÇ—,nÊ”Õ&-L™¯a¨/ûÑæœÆUåá+ÑßÿòR.vã†=Ûîµ%Uj'ÎòãÏ®¨ ͨÊmimyýɯq€ü5C2Ó ÆU€ZÔ«Š¹à[€ùkÒæÆ…2_–¿ÒÉ`®´çdZ•¹W•Éå0­×hNi„Ãc4[ÑœfÐê­i‚¤#‚mß7еJÈÓ)V¬©£èéµ'å//\¿Ü[öü¿zæÆáry_gëºÎ®–ÖN”ß¹w¼÷ÕKþ²·ox¸oçýÓ<áŒOu ½·r|‰¥Z«ÕH”î*)h†‰ü Ý•'Î?ØW][Ñíb¡Î~uë‚Uü%ùXeû~¹œÿbÕ_Ç)s4’¢9R`®'+1x;‰•ª6ö ÍÄH…ÚžÉrâ,nô†`57jøZì¬Â˜˜fäÒ"%1Pg ,æ >€©èêå_Ǫ§ª†›—µXóÆ>ÛºcŶÔÒfWaFfÍÎg`òŸ$' ää•G&fÍN{nCÅz)Áñeh”-23"2ՖѼ•ùm!¿Š©Ä‰LO{“§whU¦N+™u$4^q˜Cƒ á€V†”3E)ˆ¶Htä"-ªÍSe:Ÿ?:çW ò®—ðV2ÖÉ?2>V´âÀw‘³”Ím•³„ó”Ëjò¨U"q€R™Xç̤eý¬(œŸ¨ \7áÞw>ãÇÇó¹Z~›¬ÂqP0˜Ç%”® šÿßh |´¸˜»sãô™­ºÕÃ*6NšùZBgu‹Lü—ö}µ^N–zÿè;J”àâX9 ƒ >lrLu´â¨Usb0œSŸ¥ó#8§º'„ÃP*Xhÿíß—h^®ö‰éÐÃÎê;ÐËúÄX(å@ù7Á"œ¥Õ,ûŽcƒJ€Óps° ŸÂ_sn;7ÆsüAþ2ÿP˜-Ìž.‹z±P ÄQ°ŠTªÊ2öUH)É<1{ ™©¸TP[S_^]ŸúxçÆ5Í›{Ó‹º7¶*ù©l“.Xÿ'¿ïD±¥5e‹â tÎ ™ s¨².‚R(‡ÅPA,…*XÕ°VÀJX @ï·©~ÏŠ,1ÓŸæRþ$Á`ýôòÑ¿»@èó÷ö [zýâ–¯à÷®Ü,¬ð¯ ¿AOÜókÔ*êµ2šíé1~r_t8lO‰Šp§¶ÀETü/k÷ˆ endstream endobj 107 0 obj 3725 endobj 108 0 obj << /Type /FontDescriptor /Ascent 923 /CapHeight 682 /Descent -235 /Flags 32 /FontBBox [ -576 -235 1182 923 ] /FontName /TSYJRY+GillSans-Bold /ItalicAngle 0 /StemV 0 /MaxWidth 1190 /XHeight 502 /FontFile2 106 0 R >> endobj 109 0 obj [ 297 500 500 500 500 500 500 500 385 385 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 833 500 743 822 500 500 500 500 500 500 500 633 958 500 500 500 500 748 500 500 865 500 500 500 500 500 500 500 500 500 500 500 571 500 511 500 596 500 563 636 306 500 647 306 990 636 640 500 500 493 484 469 500 500 500 500 583 ] endobj 12 0 obj << /Type /Font /Subtype /TrueType /BaseFont /TSYJRY+GillSans-Bold /FontDescriptor 108 0 R /Widths 109 0 R /FirstChar 32 /LastChar 121 /Encoding /MacRomanEncoding >> endobj 110 0 obj << /Length 111 0 R /Length1 8444 /Filter /FlateDecode >> stream xÚ½9 x”Õ•÷Þÿ1dæÿçÉ$™†$À„L˜1Lù IÂ#B™ÈH &á•AƒfCbd‘ÒD¤T©õAÕÊE*,Z¬èÒmeÕuûÀº¶©jÑ™ì¹ÿ ¨­»ýú}ûíýçü÷}Ϲçœ{ιó#ŒJE›ƒ¤å«›:°„_„–×^]¾a½+ï¾é#„w\ZÑqûêûþ˜Þ‹sBüÉÛWu¯˜YrûGi‹2ª[[ššßßQBÊ`þäVhHñp·@ý.¨m]½þ®µ÷hýPß õ»V­]ÞT¡-ë@(Ó õi«›îê`úU¨×Bݵ¦iuKHwGÔ×CÝݱvÝz¦ˆ¹u ÝÖqGKÇÒ¹÷œ‚úç@àEÑýÐñèºjH¶|•ì•&ý£‰à“eU2W#Í×Fh¿u^ УCz$@Y0 #2!ºg ²"äiÈŽÒ‘e(ã3UíO¼ÿ61»í£~õ¦)>ýŸ%uþßÓy€W†“püGå{ àq´`Ý?„ãSx®§=ð,§ž9hi'Ï ¹ÆT èzzö¢Ó°þhé@ÇqÎG¿‚g Ú‡ZÑzò,z„æh#yu —Ñ3è1²ŒÌ#z4„‡ÁÌ!f ÙB“z¢#Z˜%K%ÅEÁÉ…7ü“ |ùó¼ÆËÍÉëãv9³23éö4›Õb6 ¢ ×¥¦h5jϱ Á(Ëi3êÚU^‡ÛíMLÖÓ¿Y—™lñc·ŒŒßäø«IUÏü«zÖú<™å*ÏŒ ºðATõ{™dl–Å‚MsSrRes»§²M¶Ïhnl„Ñ%W]ñ%IQÖ>˜¢á™Ñ¢˜‡jS ˜%ÛqWMÃJTU–$H­›˜'½2É®¤Ð.K[¡à©€• ÇôUÏðè©m_ïB0ízÉ”(a™Ÿ!«¼®6Yj’ÑV×Á¼SÑmÃ"ZÖèMmö47-Î5“]ÙZKùXI¡±Õ%³°¸òr@‹«²ÕõPvT¶6ÂÛS³¾µš53êܧ²òJÙà•gˆ™/9˜heZ›‹V£Ñ—¼ï–ú¯÷ºé; ¥ÁÑJ,‹U¶—ÃVÒ|t?l6üf5{*›Ûš\ò¦eíÀø5m£ŒwGE¹êª²ï$“šÛ)]íMt/•í®èÖe?Û:U¶‚ðšþÞ¨h´’"mj.O¬>C–j• Õ6Ô+LöV„’MÉÐÃ*=!wB Õ êgPÂTKªÔ—9܆ÐõjÍõ*µåKQ¶“”Z2.£Úz· µ¨>ä>ÕÓr-”9U6Pî"Ѓ$Û(ZŠn°gF²èvS Þ:,¡eP‘7ÝRŸ¨»Ð2Ç!$ù¼ FÚsêzeíÙt½çÆôF`9¬¸O‹¬Î¹ñD«©²µDÆÖÿ¥»%Ñ/›fÔ3J”ˆƒ¡%­¬A©lóByœ7 Bø…G½2WÊQr‰°Tz =Õ·4Ô»*£7´ ÑRt]¤$[ü…çç,Ø%QÆ¥ N¬%à×,™±AçÄa4”W=Œ45õ1~ 4ŒGû‡+Pæ1pÝÌÒÛ û¡<—«²­T*»ó a‚J繪õ„\QWtVsÔUåjmj‘)9t´DC>ÞÂú¶„e)ä¸Ql …J`=tVY'‚Ú“+´++À1ô½¼jÐ윚z8ý›À¸H!Ø'¨Ð)еSÀPFí½A)ä=miIš¿4ï…G«,„5`‰P4š¬‘x4êˆÂN”{£dÃ0RÆÀqÆRÒ%yÜTå*=nèUÀÚ‚®(D°A8Ä@{+!ÕÃÞaÄŠÇ¡™SÊŒˆ¾ÙA`-±`’Ûà6dà CÛµMú‚æ  W‘¸—ôp1Y%­ÚXÆ\ÞóûJQYÙ¤àµØ"bOn>ÎÍ)¼ÉHR;{:‹qngVçêÉ‹ŸãŽÇ??óhìbüžìûŸÛzñ¿>ÄG‘%Úam#¬m¦kkXäÐеůÖ6y&§ã›´87`ËÂÔ «ôxKǽk&—õ´w8;`ýù¹wƽ/až9ô®ÂÙ;³ûŸÛvñÃßþkë¿(8æêq-VCÜ—%éÒȬcžeSð¾‘bŸ±Ø‡ÊF¾I¶Âi8ôOøßË?uÞ¦³½‹«Í“篪]»_Ys"Ì˦ *É«Úådñ| ì–°l ³ 1ê])Fs¸@[£•µŒ–Q÷jSžO¯úc¥¾p à£HËFy¸óŽاÛìOÀ&-&“ÒØKdù—¸®CñºŸÄçRð¶Ž^á–¿h4SÒH† Ëãö)+Þ/bâØÁ´V·S¯wk±–%vëΣ,fMvæL•¦U»ªËB5étö^r$ÓÔ£:š!^ãÀÐFeá1}ùF @ÝÈÒp$Ænëq!ƒˆÜ~«Í’ãƒ,fð—aƒ›ÙŽ/Ä!=oÂÏአoJïzÕâîzM¨DÊÑïÒj12êvaÆØÃsµL·Œiáîà8™SsœVß‹ž7'98Bµ•ªÃ¤‚€ÁM‡{±Á|òC伟xåòÆ7~öÝóçßÙ¸™»ó­#O.Š=ƾ¯^·òMê›F¯± Ê`UVKewœÃoà‰"Y™y1Ïõ±Œ™¹#YwûS7Æw²5Èõ§ÃÿÔ"7|éöXqñH¸¸6­,™––p S)•hÏK(Œ)/ØÀêÏÆMŒ=ùsü8×u­Ÿ»ûKoâ½ÂÌfžFnä…{@wuú­é+ÓïNߚΙœ'ÉJ…9ÂáµÌÿÈäÏ¥œóEÊcX!EC8ŽyÐŽíö ÏîvóF3¹bÆfs†.e dzLù„ÝšrÉ6”!šSÊÇôcŽ›¸¿ˆ?ÂŒ¿‹ Ƣݞ™/.{ÅGEV|°±;ÂÀd1ö^)å÷¥Ø%[€ÂpxĸÇN3z|i“ P'l.ÆsÀ´è±gL.ïC-WØJÏU!˜0[a `,-fkÀOθÜUÓªÇwYÖG7õ¬ûàÉÁííg² t?Ùž;«d1ïöMZ;.sICoãâ-ãj&=¹çlÏ<ûÂ…q;6ø²«‹ŠoNð¬x6 ²ÔÁmyª”ÓÂuqýCô¶!.Õ†!­u¶9d&戨ªÓ:"ôëŽÙ©‰±Nªè#ee1¿Ÿ8SÀ„AÃú\“Áª(Ø–î#î;p1þç‹¡—KŽ„—u?¼cÝ 8w¿©‹~þbü/9™¤+®Ïxv`˳Š}¿Â@†V´îJ=%éÍÖ Î2[‚H¢/פ½!ˆ%›#nR'é ANcdL F@:¢Ó!É`¢“i•ÆEÆv¾›ßÂsÆÂæ1,^öúïñ¥)ă(|^ 4M*ȶëáxI»È+ g["oÅG¯½6³satÃÝ<³³íÍÃŒÞ|kÙÿ\ÿãû¶? ¼lzQüˆ J®*±N\ÉÞͲºÁ6Ä…! °4%µŸœ¦´€¹‰Å¨cTÈ(†Îã¢à·Ùq?xÊyÿhüî×>ýÙ’U‹ßÿƒª ·mÕߊÉÛç0Ÿ³‘™ÞC=07ߥȴvôcf'ðÐ ž¥YJ³!ÈKK§Ü›$‚<øøÝ‚[,ZûàÃ}bÙÁnp3ÖEL»žX#f32ÓRŽ#úàSb—Ä8øë†jñˆ¢¾”i`;Ü@cRyó±B¾Ñ’í·*ÏìŒu«~ØwxwíkwŸì¼üÂÑõàóªõË–õà“›÷v**ø§ Û~‰U£èͺÕ6(Å ÷2·1»Q6š„J1‘ò7Xžp*ç çÊRÆ4Îd šÍ bã8ƒ)(Œ~²Qße NÛ>V—G7šj4ó7€Oe‚ãoI“¦`p0ÝÁåHЗ3ȈvdÕœ S¶•€ñÒh‚Ó¦Ä)¸ucÇsœ/¢Ñ” ¾!M\%d³Ú´í³½hãl¶L!ò {Ÿ›¸ÝèÞÂï’ÂÈüÌ™fÈd33§Ž ʼn©;¦á°øi’iaC‚uðò|ÔLƒQ0ØŠ½T½  ^e 70ÚŠÃÔ<€f‚0A$ã¶x²0µÖ*ª—É*a,”P'˜ƒ“KOCËn¥¸àÍãøîã“',èÛuûÜ–5å–pæå?¾¿dþŒs¸nvëŠysooí^Ò…Qwÿ~Ұ뙂 %7omŠ\ã­ÙrË›#{¿¿ùÄä)%y7p[sÕÌðÒ™77~ùμ©Ìœ.Ý¢è]s8è¿€ü’›ïuÂŒ©Ó«Ñè#H—ðkáŠÀ!Aˆ~8Þ¨ 6 Q“ÿÆn&3ƒç݉’4q‚$9Â9¦MÌ“¦{'L÷|Ù ¸F¯Æ½¸\ÁeFeÒXØ@':RQÕ0'‘šE³ËÌ 0èItÀ|; Ӵ⥿AlVåNÃ…&JSó½åÓóŽ ”ÍæeyùÓ¤ÅwAX®AwHe„`–cÏ0ÄÌ0ŠK<Ã!ˆo‘Ï9ˆ†9p€xH–Õ Â,7)§î×Óþ9£¥a0 ~ê;ô—ˆpÊJÅvßÒpéøFñŠj%Îǃ)·È›oÇïÄo¼pä³;>tÙwmk"6ï‡× “Ac$cÒ#p‰`\̯™+@#1„¡ JÄé°^?p½‹Îƨdì‰Ý$9ñ è†xÆÊä0 #µÁ¨éW7#±ßp̤¸†/a ; ?È[À/€ÞBFÝ rÜø½ºïÎ=R×Ò×pœÙÝ5úÞþØÇ$u{w_l-œz‚æŒ^aÝÌž¤-»µñ$u‰ÆAÞZ(”(Ø"¡ÁÂ["ÌI»Ñ(öBß„Y§Ñ‚)¾ˆF[¶¯ RüKlÿþßÎÇÿ€í¯Fö?;pß3‡˜=ñ?½~6þœòÊ«X÷ø³ý›ŸúÑæÈ³ Ù¶¨Z¬Šd»Ø~–ÑkÅ!µ 9tCX˜m ™ˆ)"Â%á4Ò§ô£c¶oúÈ‘„}7A¸Å*TåÒp+AQ>îÂeŸaC|ôlýʾ¾Ú%›~8·?îåVúÎùøÕܸ™={Õ{h[C´,!Ëí ‰ zʬ3‚oÖ ²¢ ,æáÒÇ®_L¤$€*- Sã÷ûÊc ÒxB¥8*Š íæÍ·w4.½¥¾ï(³ûWâ…Ö} û×Å ý<¾ä 9¸<èÉÒeïÏ$éégR4æ”[Ð郘šZ{ª´ŠvwŽ8Þ=O‹ÝUbµéQ¬‡G¯JV= ÃRp7„Éé)¬È¹M&:±Ühš$½4™,C¢¨2ƒ«ÊÐÀ`Â&)- zÁT›$·†¨"(롬fý"‹-ËÂôI‹è`™Ÿz%÷x‚:ðå#ôJ¦œv°Ô¸*—B¯îh`TÃP {½ú|o‡…ƒ…ÔQíÈ¥þ‹2èº÷wâ¤q¨ûƒ`ñ‚Âzyõ÷<ðØí…Ó§Ìžþûƒ[l*iòŒ¢Üq…þe[´ß7çð²‰Ù®’ñÙ÷>Ò¹Óƒ”xù ÙÏÖ! š&¹06sƒDÐjÕƒ:“W˜"T pŽ´ZáúM‹É€‘Š |¥œlDí÷ÐPÑ€-ôV©Š@Rn>)4xpöÄÿ3²luÛ== ÓÇØö1<®yáñøÔGÊŸž2Ë õÐMÊ9†ØªÄjB“¤L4¬Ï2ÁdÔ±&8À¦ã–”~õ1³r”bJÜZ.¥ñ»0éÜá.EORrr®dpöâ]ÕG¶Þ{ë‘®²ªÅƒ?&Bì“ëzÉw¨™œ<àìœ<ê”ʉÙ` Ò*Î`bƘЋ™ÄE^XBØGŽ8†E„o¤WÀ¾‘'<ÏJ ¬Ï°Ã0Í¡u±A¹Ò\hø›7ì½~_0‘Ã/ÇÛ§ÆÏ~Îìþ²žÙ{•ÊÎ4å… ­—¦«T<Ërt`ÊŽÀv# IÅógèí”cU,˜pl†XaP#ÞGÃþ8v c8Ÿ œJ‚®0†îÒRj·‹ªÀTC®Ð5 .U¿” M£Ðöz¬ëÜùöžê®í"{ȯbQþÿÃn½ü›¥BégØ‘øftªð®U×sêU‰gš_ã WÕÇÇÁ-ºî‹õñÃêÚ¿ùN—¥†&R fmEìø4šÇ"´‡ûµreh/?„–°f´ƒ½V¦¡¯›éƒ1fÔÀ\@µÐ†`N>=zê}Pî‡1=l;šyãEÛ3ª%O+{`.Ïô)¸ ๠=ˆŽ£«¸Ÿ$f²€<Â1›˜‹ìv3w÷]î->ŸÍoæ_UU7«þ ÎW·ªkØÄÞPºò£*Œ•¨ ÍD7£Ùhš‹æ¡ù@É´-Buh1ªG!´„~XòJ‡Ïwœ'¯w¼NÄð£—qÁå— Áïcñn<‡wœÆ§kNwœfÄS¸ñTÇ)â;Qvbþ á¨ó(ùSÄã¼1;ß‹8p&ÒìܵÓï*u>:t`èÅ!f âwö|Ð7Éy 'ËùóÞfçY€~ªs¾ÛçwöA¹§×ïŒôf8;z±Ø+÷žêejzqÖ]ÖÌ;­¬Ž.kúz«}µÃ:¬FRZ檵V[ƪµ6Ǫµö•k¬Ž•kzïHo7ÓÎÑÌmfKÆŠ6‹cE›½¥ÕìhiíïLxÆ5÷C»vlØ °`  ÐÐ Ðàx‰ÚùPXíØåÛ«[¶ Ô«ý€>¨÷ô,oR;—øÃ·ªKêëÔÎÅM‹ÔÎFÿ­ðªp-i“-–B‹ñ&‹°¤ú-šI¾ÀÂø,(ß’7Q˜àÕ/ääêÇf c> endobj 113 0 obj [ 278 1000 1000 1000 1000 1000 1000 1000 323 323 1000 1000 219 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 500 1000 740 1000 1000 1000 656 1000 1000 1000 823 510 1000 1000 1000 1000 1000 604 1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 427 500 438 510 479 1000 427 1000 219 219 479 219 1000 500 552 500 1000 396 385 333 500 438 1000 1000 438 ] endobj 53 0 obj << /Type /Font /Subtype /TrueType /BaseFont /TINZSI+GillSans /FontDescriptor 112 0 R /Widths 113 0 R /FirstChar 32 /LastChar 121 /Encoding /MacRomanEncoding >> endobj 114 0 obj << /CreationDate (D:20060308221508-08'00') /ModDate (D:20060308221508-08'00') /Producer (Mac OS X 10.4.5 Quartz PDFContext) >> endobj xref 0 115 0000000000 00000 n 0000003157 00000 n 0000000022 00000 n 0000003262 00000 n 0000003137 00000 n 0000062272 00000 n 0000061479 00000 n 0000003744 00000 n 0000004037 00000 n 0000063138 00000 n 0000008242 00000 n 0000008463 00000 n 0000068196 00000 n 0000007759 00000 n 0000007983 00000 n 0000004908 00000 n 0000005204 00000 n 0000009684 00000 n 0000009905 00000 n 0000008964 00000 n 0000009185 00000 n 0000005296 00000 n 0000005592 00000 n 0000008002 00000 n 0000008223 00000 n 0000009204 00000 n 0000009422 00000 n 0000009441 00000 n 0000009665 00000 n 0000004518 00000 n 0000004816 00000 n 0000008482 00000 n 0000008703 00000 n 0000007279 00000 n 0000007503 00000 n 0000007037 00000 n 0000007260 00000 n 0000005684 00000 n 0000005980 00000 n 0000006072 00000 n 0000006293 00000 n 0000007522 00000 n 0000007740 00000 n 0000008722 00000 n 0000008945 00000 n 0000004128 00000 n 0000004426 00000 n 0000006555 00000 n 0000006776 00000 n 0000006312 00000 n 0000006536 00000 n 0000006795 00000 n 0000007018 00000 n 0000075207 00000 n 0000063594 00000 n 0000060499 00000 n 0000004018 00000 n 0000009924 00000 n 0000048349 00000 n 0000004407 00000 n 0000004797 00000 n 0000005185 00000 n 0000005573 00000 n 0000005961 00000 n 0000054820 00000 n 0000055487 00000 n 0000051593 00000 n 0000052549 00000 n 0000048371 00000 n 0000049044 00000 n 0000054038 00000 n 0000054800 00000 n 0000053256 00000 n 0000054018 00000 n 0000049064 00000 n 0000050020 00000 n 0000057646 00000 n 0000058226 00000 n 0000050040 00000 n 0000050880 00000 n 0000052569 00000 n 0000053236 00000 n 0000055507 00000 n 0000056174 00000 n 0000050900 00000 n 0000051573 00000 n 0000056881 00000 n 0000057626 00000 n 0000058246 00000 n 0000058891 00000 n 0000058911 00000 n 0000059491 00000 n 0000059511 00000 n 0000060479 00000 n 0000056194 00000 n 0000056861 00000 n 0000063556 00000 n 0000060650 00000 n 0000061459 00000 n 0000061515 00000 n 0000062251 00000 n 0000062308 00000 n 0000063117 00000 n 0000063175 00000 n 0000063535 00000 n 0000063678 00000 n 0000063744 00000 n 0000067561 00000 n 0000067583 00000 n 0000067815 00000 n 0000068377 00000 n 0000074516 00000 n 0000074538 00000 n 0000074765 00000 n 0000075383 00000 n trailer << /Size 115 /Root 105 0 R /Info 114 0 R /ID [ <19889596efdcdf4d19caf91bfdfa15df> <19889596efdcdf4d19caf91bfdfa15df> ] >> startxref 75527 %%EOF oscache-2.4.1.orig/docs/wiki/Chain Caching Model_attachments/CacheChainModel_v1.pdf0000644000175000017500000001421510445266451027730 0ustar twernertwerner%PDF-1.4 %ª«¬­ 4 0 obj << /Type /Info /Producer /CreationDate >> endobj 6 0 obj <> stream xœc`ìà? õÿ1À@©ÇT‰_íÔãW98Õ#k$êáZzˆ–A¥~ŒJÒ3®\†)…¿Ô¢®zd)¬â˜‚tP?§£µ‘ endstream endobj 7 0 obj 78 endobj 8 0 obj <> stream xœíÔá € `½GëÍL21ºÍ¹ ¹cÿB÷W!0ëgƒÐónß!1„<ééÞ^2ªcôxlÇSiž)oc]Î3ªíȈ‰==ñv¬”äÉö‡OýÞË##C£§Ûƒý‘xŒ0zº=ÆþH`ªþÐãÑŸÆÒ—¶” è±{TýQÁð=BfÔÿaèi£Gæy¹ú37ô0 ã‘ê÷(° endstream endobj 9 0 obj 169 endobj 10 0 obj <> stream xœÍÔÁ ÐýÿOÛ!:ˆCòàtG{†lŒ½lðæ3ëe­½ƒž®ÓícKRÔø8j²”Øß:õæß]ã“ùG|uþnOoÐ{||ñ´ÕÓ”°Àƒí5ëÅ9÷œÈb endstream endobj 11 0 obj 93 endobj 12 0 obj <> stream xœí×1€ …anÎÑ<Ú:4©m “ÿ¥Dø†’ÆÖÈ¿Óû]Î ž}> stream xœ­œM“ܶ†ïû+x´Seß }‹EeW\IUrˆr˜(#i­]{#É•tn’V³³å²ç•ˆDƒ8c=©ôÏW:ý'¸ez}ºÒø7ù¿é¿^8]-.¦Ïü„’7Wª~Âß¿»úÇÕm2¿M~Q“‹K°‹k¢rò>ŸÃÛŒçlél/0c<ÜÞï·c91ƒ/L½¨Jª*øvŒèâì⚨œˆ1-HuÄû jÎΕŠÝY)[:³Ò8g]„.‚Å(“7xiçËJûýB‘]\‚]\•»ª3ye;U\—?q]Ì9r*Ê!u^)Óàg×eO=¬W¹>U‰U5V五ž‹F¶OõáÆÜIW÷÷™\\‚]\•“÷ùÞn÷ í g·ƒ8Uléy&«°ŸØÅ%ØÅ5Q9\z,è€7Ôœ+ænphQIV“¦9˜ÂO¨L^DG©àênŸS]\‚]\•ûœ3yeƒS\$k~¢¤Áî}q8`NEá¾¹¤©Æº¸ÎO˜Yî ±SÙ®Yí' r]ÊŽ8ñŸP…;º°• ÛûL..Á.®‰ÊÉû|o»ŸóÒÙK¾¸¿ûøKó‹6Ü~dº©¤ª|ã$ªº¸»¸&*Ç1Zeñ9yÊ*fçJÓ‹1[Ü£°i¼\¼€² n.ͬLc±$\µ„pqM¥Üê°ÙÐVÇéZ‹~˜½§ÐÚ1ß\ß¾ÿïúpBÖ¬Ë:×GjKgÅ6µz7ÖÞuX½ ®Êà áÐЪögéÅß•SŸvI Ï0|9JÉG¬¬öëkrõ¦¾´Sƒ^ZÍØšì~Îë›SV347¤}žPqÿdf—`×DåÚÄ/•½<ÌÞÜ£¥“‡›·w÷×Þúƒ$ÍŠ5ð¤fìX¬³ª-%Âfä>ðµ‡ñ¸ýUE¿$>ÅO—ÊéÚ“^Ÿ¦g#¾\pôvÞÑTåìþ…\ãAb'¤–1¢bªTá?½¡ŠiË ®îÆHuq vqMTN¼Ð9“W+®ñƒß˜üÚ >µ™ñ¡OŸòáï5t¾¹I*8¸W1í¥XÁÕ]ÌÕÅ%ØÅ5Q9sÚ_ðfªR*(-•騢ÅvNMþü?lÆdÐD µM•KméÑÀÒ£Mßl‡z¨ `h–êÕ—[RíB_CafiG—4èÂéÕ”©A(©(3êøézw³t½Y<€kÖqÁ§Ê¿ =Ny©Ä³¼è ŸŸ¯_2ÓîÒ„ðÁƒ ëé1,”îdKgVüûÝõÖq…4($0•ZÒc¡¥7oaHS9¡hÀ hiH¥û¨í ¶v ­¡/Õ€dØÊã`k\¶ÆÅ\;îB;ˆë› H×°4W¯¥€ô ¬÷ÇÍyu€9?£ mÕã˜ÐÒÍ4Fg‘€–†ŒÒ¸‡:~:Ü|<|8þt<Ý}:6ò9S5õ ó©Mä3¾ŠûŒ|ɱÀ!1¨\oX´Ppµ×™`Q½Us8zM4_Ì-méѼîÓöí"¡u˜€úq``é¡v­kêŠÓBHúÜ.T5®:üW»P âÚd´_(,P¥zF–ft߃°víÓJ¹ ’ʆRCºKm;­Œ.¨šGZ2ÊèŠ2ú/ç‚Ô4*ܬ;²Î©Äg¦³)ëKTX/<(…ŠÝ£¿lé|¹¡ñxö–XžºMPKKºÉlû¬F2/„• - é&óÒG퓹v ®¡8+Õ€¤ØNæ—ªq1W»P âÚ%3……*WÏHµŒ@ÙÒ5’Ù J é&³ ‹f2gTÍ"- $sEÉüâØJæºí+ †—=Ìqþ¬d~Ü3š¼N„-æŒê&+ü"!^eeÜb>’#‹<Š(Ù¥¤²ö xºòæÊãHõJ=ž§ž…eVVR.wêAöê•ÒOFk¬K•ù³TÅ5¼3xèŽÚzGíÜÑ-U·c}âûZó¿¸ð]ˆWz ­C!ƒYçBæ•I©9ùñý*8z‹Ö¬Ôþí¹Î~cŒ›ø V– ×YUØ¿§&×¥pèoh ‘z™•ßaˆ]\‚]\•ã#á OeÏbïŽÁÒô:GÂÏá`åúîö÷­£á6´Šóù¤p¬ŒkmmÜÊÅ5Q¹öwÂð¡izz»¼‰R™îWV³¥·ü1Þ^ß~8Þ¿9¼>îßÁ€É¯@9ü^lÄóaRë× t°K..Á.®‰ÊɃÝóx<¬G¯5Êå`7q¿p¶¢,ZÒEÙ>j·p7µM ÅG©$3èÆæÂÝÔ¸L‹¹fÜ…f×ö\MÕ°Wo¥€Ô ¬ýÂ}Y U0T cBKwXìî3¡@ą̊PjHwá>÷Q÷xžö=Li·‡›ínˆÊùÈüÒ¦þÚÞK¦£µ»ãsòDPùœœ28ÚY*58'Ëè F­¬N«ŠBŒ4*˜MíéÎ#¶OldõB¨@·J@KCºY½ôQûíx J×úÃJ Hzv㟮oßïó¨ÃhýPõÛyÚfªR½’ªÊ–ÞÑò~lÀ:·À"AÆRSº«¦y06š©Q5¡4~¶tP¿|ü0ÈëŒÔ4Þܬ‘¼VÃórÎkï';çl굘o¬àj÷Ð+™{ßEêæ5üÔ!“ÊfS{ºg_¡Ol³™Š¢éB@KCº(ÓGíòZÕnT5„‘Ô ÛÇl5.Uãb®w¡ÄÕHê ✒H3¡¹Ú?­á‡UsŠ¡ÔAJ÷‡E+¥ ªæ’€–† Rº‹z{¤tAjê>7kd;¥S‰ÏKiËÒÕìÊ“E¨þ×e³eôƒÀFJûe¦-ÆB‘viOw¥5÷‰ûoW,®¢\0”ÒE¹>j÷튙ºU©ßI5 ̓nlÈŒª#A@çqÿ™Aÿ½¾9îC²î ŠñfÝ“!†'¿ŽO~³!•͇ °ÆÊ‡  ðwŸx••YŸü>Ž—ž{Oì°F[)è‚«¬Œ}ž©¼¥ò8R³RçmÎ`K¿ŠC¯½"^êß§¡.+8r¬Ìwu¹0ÖÕl÷ŽÚzGíÜÑ-Õ´c}âûÊ'¿ÙõÀɯ§“_¿;ù]ð'°åÿo€?”Šð3G¡Z'¿ÙuþákXŸü.øX‚늬ªñ %r] ‡žs†æ@ü{,?¹-ʵN~ÉÅ%ØÅ5Q¹ÞÉï9ìÝÎÌãüÏÙ "FÓÄ–#H%•nø’‹K°‹k¢rí_ØhZ½”}¯µy%2K¥»'¾Ùò˜ßÿy¥Þ endstream endobj 5 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 947 649 ] /Resources 3 0 R /Contents 14 0 R >> endobj 15 0 obj << /Type /Font /Subtype /Type1 /Name /F5 /BaseFont /Times-Roman /Encoding /WinAnsiEncoding >> endobj 16 0 obj << /Type /Font /Subtype /Type1 /Name /F6 /BaseFont /Times-Italic /Encoding /WinAnsiEncoding >> endobj 17 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 18 0 obj 3295 endobj 1 0 obj << /Type /Pages /Count 1 /Kids [5 0 R ] >> endobj 2 0 obj << /Type /Catalog /Pages 1 0 R >> endobj 3 0 obj << /Font << /F5 15 0 R /F1 17 0 R /F6 16 0 R >> /ProcSet [ /PDF /ImageB /ImageC /Text ] /XObject << /Im3 10 0 R /Im1 6 0 R /Im2 8 0 R /Im4 12 0 R >> >> endobj xref 0 19 0000000000 65535 f 0000005539 00000 n 0000005597 00000 n 0000005646 00000 n 0000000015 00000 n 0000005082 00000 n 0000000310 00000 n 0000000572 00000 n 0000000590 00000 n 0000000987 00000 n 0000001006 00000 n 0000001285 00000 n 0000001304 00000 n 0000001687 00000 n 0000001707 00000 n 0000005189 00000 n 0000005299 00000 n 0000005410 00000 n 0000005518 00000 n trailer << /Size 19 /Root 2 0 R /Info 4 0 R >> startxref 5827 %%EOF oscache-2.4.1.orig/docs/wiki/Chain Caching Model_attachments/oscache.fpr.gz0000644000175000017500000001463510445266451026443 0ustar twernertwerner‹í]KsãF’¾÷¯ Ã{ðÌ„µ ØX±Kò“³C^ãxŒYPŠh-ï#JäÔ–ÂÚXSFï ­Ùè›gé·Šÿ+D‘w}(”)è,Û¢/¼à;U* ¿§§á;/Ê`9™Ç- I7¸"Œ4eJTЏÑWÏEäõ[Š-ŵ»ñ“óT_s²PúÓ—ÄM¼uNJ¹E¸EðNÞN/Ï|s'‘»HæI´¡ fQ7d*%¢°ˆÓ'´è±!ú,Enó&ØÔûð…‰ˆ×ÿå/ó¼ƒVz”•Hvc d6’5£Âv¤õf?ÒΞòÁÂù÷h°t5„w¢öÍ(ÍÎF¾‰åy°9 'ËvjÄÝ—ÍZD‹|iå­.²ô·~,ëLØ»üSsT:;P£˜¾NˆÞy±wååÙ Ù§.½xí»÷âNøs‚ùèl‡CÄ»:ŠTg™Ù\» ‘£z8ôõÞ/Y]t(úõXnsJ*†ÈgžçPVâ@XÈ”‡@eÓ%¥·ôª ·JŸ¥ øÁS“Ûò¢ÿL¿ñŽìºT?ò>XÜDaàý /É­x$âôŒÍòEóœ@Eò<¾ ó!ûðuÎ “t²ÿNÄÎö‰\…»AÞw{$õyÊΛœd齑ÒizîBôVŽÞ¸wî[áf¨˜\láäœò½*|6íÄÄEÏ“Ž ¶öUÝò`ÔÈåÓ/zX"²Èߊ èã¹IyW›D\ºÛiÎÃ2pWíG…ògôQãÜÛ ¥Ýe¦V¹ý¨_ãUFñÃEþ‡ý×<=o¼`5ËÈÃý÷v8het£\ÞĨ›áŒU7£1´ScÃ-Bßw×Ù©[Œ†€<2ºV.cÔµ5"oÐu=êLÝu­\YË©kÊ6N×5 w¦j F!Ü+-„ªNÊà,K>¥Q+”êØ Åá9Ø[H°‚:¹)ä·Cr„^+GXʵrª µ?pb)~¡=\ H¬ç^ñí!ÁS«¢ªrFÊOT4ÆŸ¨ºAÐtTçÑ+N‡£:ÎXõUUçN)€OTœGg&³×eU{VÏã^¨ÐjÊ£pŸÜÀ]‰¨Çáq8Jú£œ¨nþ=v÷œ±;0ø–ÀÛÁîÈ[#zºoí¢wڤìèX㡃ÞÍFÊèE€KäÑ; ò´d¦V¹u5’ç ä­42ºQ¦àÔ Å§–PΔt€(©s‚3ꚢI¨zBØOºPµ€=+$=ÓY#GÓ´2#zîïåRgCü™ì¼AS\¢&ôÕ3‰m_ƒ”WV¦?ü¾÷ü Î{!æ.Óßd_J  ¹Ø¤‰ÄÝ…¸Nr­`¡ûÁ…-s BáO!‡Q:[gámV4”„!šmÉjTØ«ÐwÏEªý01YféEb‘oo¼ò+ÓH ŠK±È[Ýìå…0¥œëGÂ]ÞÎkpÉF·}h½Ü ö2 —I¥­¡…xÔa*ãTa©“ÞÄÎhZOd û\5b…=̘Öj *:Û Ÿþ%÷;æ•Mõ}V*޲_´¥8J}|/(L§CƒY5Læ-.kd”£L©¼T( /MK…p$·…«)ЃJå9>FáfÝç9óJÇy‰f«>ÏñÌò<§‰ÊM–GÏsÈmœysº?´¯äÍsð”ýÖä9e:òy2L9Ïr¹ÉL­Õ¡SVØôddtcB5'˜´‘G„§„ÅÓö®~§±i­CM+ó±2jz8&lµ%ÊFVÞ«p«býdÈëi!e`½]-R63&ŠU¢œ–íWR®)t?£‹=€î)ñaÝ7„X³SžRÞu5èþùìHÕô£ô†4±É§‘~Ô ïȤlPm)N—¿ŸóŸ$2¥ÌÉÏéA2×$±¿Ìþª|]D'KÅŒÉê\ Ž~ÄCÙÇ]DÞmª“l£MÒo‘#Þ\혱ÀFù ?Ø=÷4|¬´‘0•kå¤Ò?Ÿ¿½¿ór/ø¿ #/¹!5¿¸4é¶>–ºýj›_f2¨•õËSd`^giµ%ÏHÃJ9!Z:j¨DÙ¦slJŸºJ:Çk\TÓ9¶} ÒÛæq?m :«=ß| ‚Ò¾ù$V‘QŽ ÅJpu‘Š‘Í6pgl{ºf5Ã!¥ ® M›¥´À L>MéÉïc}­ã96HÔ"ñQøåÈ- Үɟ 7„D«Ò±+_XªÂ]O¹¶ð1=saËÕ.î\“ÎþG‘T‰ÚÁ} éró`$pKƒG*aÕÁ¦t÷ý`©¥ýR¼ÊÑK5›ä)‘}£,!÷Ò$ ¢Å/Q€ËKMbŸwxör ð”Jeh³ÏWvº¤ô¦Ü³ÏÓŰÏ[`íh£¤6û¼E÷°ÿÍžû¼©–/R#5úþ;±rùþz„ +Rë(\]¸Á*·¯;’tK:Ã=×KWš3)uõ].h,¨Ðä–O)µp}ÿíýçímâ’ÒùÚÛ®{áežÿ¶ÜeϞ퓉bä$ë\ènŽ“ÍvG£Ý&õUB‡¸L&z¬°ñìÞߘ5=E×4›3\„¯½?ÜûÃ{¸›xü™øÃS´Vª÷í^ôa*s%'0œŹë·ÿÖ·ÊÒaØþû¼qõ¡LJl^Øå¦_ƒ/x º`²WSö ·ê‚¡ ·wÁzŒdK@Göf_MÚ»{'…²Çn„h•?.U«K×îi”¬¶nƒ·3=Üvn3ïÓc“­J̨Zài·<2תïߟÍTéÔ–ßÈÆöi;ø%íæôžÄÌjÂ-.eQ¯ÅtU˜ôP¶H¨Di–‘¨ «%&ü)јCËjÑ|©É-ÚE>ûmô‘0<6Ò¬ùpþá·V¯Ö£ Þ1÷X+œ=Ú„Ìñ ƒ|ZYÀ›*±€«ë:×'‘œ1…élàhí0 °‚D£ Éc`ÂY£ƒ)™©5ášnŒ‚‰ÛÆ3Æ­ɱÆÍ aRw±PÓТªÁ=WAüum.9tx™äÀ a:Ä(PÖ¾1 ‡‰`Ó1»åÆ(À«„rл-ÙšÍwÜM¦8ŠFù‰ ±k¸‰OÎé¡—fUTD‡‰?Á„ÕÎ\b6>åÙ #2+`µÏs¹eÏ„¼ ¯'ÎyE'ã&nBbÈ{¸fFÚ´=AÉYŒÎgJéÁ|eã‘PÈÉgàEýzùŒw^üýRD±'YhÞùwAê yyÙŒ1¾–5›ÖôÙŒ£­a¦š¦1šžn?›¡¾ì9sGÞèe° Ôl5—ÁsËLM.ƒà?Éç2À+7•sàí„2Sk‚çjk‘‡µW ú/£®‚¥µÒÊ¡T+wàÕw/·YÚªS‹zAš7š™¿ñ–¶Ž M¡XW‹© ®ŠÂ™ )^›7Å;1ÕØMžv¹%¡cîÙÃ3¦>2í#Ó„'>‰Û0ºïQ •—õ1Q‰¾Æ²“¥ËäùÐîöQ éÕÎ FÃH’N±.ÕŒ $I”À6PŒ8FÎÜž1õñÌLÈš3ƒP \4òt›?ÁΖ#dçÖ™™Ï™€@rWV‚T„êÚâ„ÁqÏL@i¹áˆS¦S-–ÐäëÌ8c²ˆ6W']êW'!²é¹:3½,–8A»Ö´¸:YXtv“Æ+T±Íbì´ 5;)W3ÎØ‰ßHk!ÁZbæF{¼{NÜ:Rnù%F@øÚâÃj}¥vÙ¦•bP‹®9ΰvÑÉpÛšÛNx¹tF<Ê™¢.ˆf>æL yq© åR2?šxª>q(ÜÙeÀ-ö$Q%[êŒ%¾ð@¶¿(¢zQî®÷/¯;í6ªqT‰ýíœìè~â.Èx7Ž18ÎÒØb‚Љíó ?E)J”NO|pªÙ)&ò,#ø -ÍL>ýÂTéb#ø-ò>§VèÑ|#˜GCVê ,ÚèNÕ&¤,fUOŒÌ¦n0vt\4éèsTÙwiÁŸu@ÄY†àØ•_¼"}±ì£u ZwF„BÞ#N’"âÕ¶±|Á-HbùŽÐ–ìöR¥Ï™’·–Ȇ´¶!J4£D7DqÞø†ŽÁJé€ y2SkòÊ{«Á˜ƒÓÞ·¡œkAßP«>ðˆ¤C&ÐRŽ@²*y]ƒ%ÎêÚZJK‹•é0HÓ}Ýé(Hi=_ì0å#®‚Û¼übK3d` 45– Ä4Ï–ó2‹ÿص_¼Ûµ/.½µèq —Ò‘^\¢Ï¶w²~™¶òaó9×!.¡²ä9 cræžBl˜8Å”Céw“&À›e” ðΙ©5!giÎŒµOæÜ1"˨‡$ÔËF&tœj½]SØë$ìrÐv¡jÀHf:/Ò£CÈ Š)¼JÆ~LÀk-Ê­YíÖÍXÆÞÇž±'Ø@Ïz¾°.×þ‡{ç¾n™|ÇÕÚ ;}åŽ B‰‹±PÛ*!œÞµÅ˜“‰&ø 䉂U#NIR5àd*F6ƒIV+_xx½ O(nñ+s ûphd¶ÐŽTkÄj…CËÈ‚œÔ¦ Ukâ‡,ÝFò98‰‡Ñ ÑžÜ6¬™€Ë£“Û¾s“ô7qé” iϘ ¥tf¿°`¶•ÅËT+:6°J[a½s¦B͉Jñ«¦ÛL…íJØãÜ {¤Ka™n…5âZXîÛv¸òÄFÜ kQp‰ZÖ¡™uÃFÜ Ë\6Lá¶îBÕ&”?ðÞ=¢€Š]¨Ú z[‡)gàq 7½-Ó °“S”ÿæ2 nå<Ù\¤ôJs?ˆ,²sŽ!ªZJ-\ß{ÿY\‹(»nRR:ãí¼ýz¿D€â……e\J<^¾È§ÜÙ”³¦B¦4§•Hß=µÔ¹¤KJCUÁÜ‘Uüà©ÉÉѦßxG6ÿêGÞ‹›( ¼t[ÞŠG"ÞøI¹~&§„t(y_Ê-üíùÚÍM~aáÊ>ÕÔ…‹b‘š§ÀwñtÎ ¼9¦?0[BÉtµ('—ïÏþ8< 8­?°µÛj÷ç@ÈØÒx‚¦H´Ï…/ܨ?úc ßÑoS6ÐÛUh)v”›rÑ#Ó=F\ó8²y bNyÔŒ¸åѲX¹tõøbW7hBŒV×J¨=Ö3ß.nÆ ÞWCoÓD!ìÌA¹ð²SZÆoÝJ½~]ôæ¼ C¿hÍ‹ `é7Qäf«îMcÜ'y”sJpVêd÷'¸J8»q3§6õð²Nbãû× \òx”wáæª¸[d;¥÷/@ñÁÝ$&\†U+¼<ùx<ÂyêqzY±n9 ¦˜…_«Bœr%eƒøî+,k¼ƒUõ5ì±2ÄþUÌò·«?Ä"¡‚¥¿Ü„QRý“®Ž±ÿë./*ˤU>%—Þ¿€‚yÿzË\VÁ°áíI¸A|»¾ ƒû“0Î/¸é[à{·^êŠ×ϕ҃44Ø,²Î§ìQ0ÞMâù'Qzþyré&Êœ$7¥ë(,=s¸ÂÒp{‘lÖ¿æJŠrvb%@_S¤¤Sµ­.Ü`•ãÈWÅ(ÿó¿æ(¹˜ZŠ#I·¥3´Æ„Qgº—a’¹¡©4&Õí¢juÕ¥û9Aº-šխ܊Ó4¼L{&ʷ¤¿JQ×Û’(ß–Þš“ÇЛ¦ÑÊ3ÉìÐ2&õ嚺â®iâmi -ÞáÔš¦Íåª3Éäš›Dx•W\ÕµgŒÚ¬¶"‰ÑTW™˜³R­¶Â‡*¬¥:ƒVªÕVQÉ ¨ëÎO1GumÅÓ)zú3ÉøÚ (ªiuíÅÙ(æ(¯­hâ ¦©A“ °­È¢Hà©+Ž*ß–ÞÚ )*‰O]å™dvm¹ÇØþ¸ÇGçø*ód¡Í“"éªcÜ‚ Aê*³ŸWÆáUèh× “åî˜*ÛÚÊ ’vòÈ„-áߢtG´oscache-2.4.1.orig/docs/wiki/icons/0000755000175000017500000000000011375310613017026 5ustar twernertwerneroscache-2.4.1.orig/docs/wiki/icons/user_16.gif0000644000175000017500000000176010173132432021001 0ustar twernertwernerGIF89a÷K ÿÿÿqÛ+ÆÚÅÿ»sÿņÖçԯѪnœkxÞ2|ß6ÿƈ”éOÓѲÿÀ}jÙ$W™S"a}uÿ·läªdêâÑêâÒÿÇ‹ìãÓä«eÿË”uÝ/ŸíZÿÄ„ÿÉÿ›ìW¼‡:ÿÇŒ†ã@?–+cÖóíâ9“$ÿ¿z…ÒSÚXáҸȳ†°~+›z*:%áøÐg× ¬z(ÿ¦w!¦x.uÖ3yÒA¬7‚‰‚8//9Š‚<<‘ ;; ‘ =¥= ‘B6..6©$1!1$Š35‚?# ,?B24 %(:2B@*"&')+-0@BAçèéAB;oscache-2.4.1.orig/docs/wiki/icons/emoticons/0000755000175000017500000000000011375310613021026 5ustar twernertwerneroscache-2.4.1.orig/docs/wiki/icons/emoticons/forbidden.gif0000644000175000017500000000114510315621364023453 0ustar twernertwernerGIF89aæÿÿÿ÷ÿÿï÷ÿæ÷÷æï÷ÞïïÿææÖï÷÷ææÞæïÿµ¥ÿµ”÷­¥ï­¥ÿ¥„楥ÿœ{ÿ™fÿ”sÿŒc÷Œk÷Œcÿ„Zï„s÷„Zæ„sÞ„sÖ{sÿsJÿsBÎ{{÷sJïsRÅ{{ÿkBÿk:÷kJ÷kBÿf3÷cB÷c:÷Z:ÿZ)ïZ:ÿR)ÿR!ÿR÷R!ïR1ÞR:ÿJ÷J)ÎRBïJ!æJ1ÞJ1ÿBÿB÷BæB!ÿ:ÞB!æ:ÿ3½:1æ1ÿ)Þ1÷)Ö1ï)Þ)µ11Ö)÷!Ö)­11Î)ï!Å)æ!µ)!Ö!Î!Å!µ!!”)1Œ):µ!”!)­¥œ¥œÿÿÿ!ù_,€_‚ƒ„……05;6†_ 3#/C … ) —&*29G ƒ3 #*-¤: ÚÛQ[‚7#9 ¸VL‚,998€ý¢Ä –,!(£áDŒir…K-A ¤<$J”+^j@eI’&Q¬dá"ÒHºxaâ"¤›ƒ;oscache-2.4.1.orig/docs/wiki/icons/emoticons/star_yellow.gif0000644000175000017500000000106710315621364024066 0ustar twernertwernerGIF89aæ Š4™™™ÿÌ÷݃Ѹ`ò㽇…oùÕHïÛ›ýå­šUÕÁˆÈôÿÜ1¯¢lÁžØÒ½ÿÿfÚÁuļ¥ÖÆ“õïÜзoÿïSÿì£ÿÓìՀűG¿·žÿñxöÝŒ½°X£›æÕ¥÷ØfÁ«jÖζؼGÿÿ™þàh•Žzÿ÷­ÿÛNÿÒÌÌÌÿçcñà­»­„º·³òñîµ™&òèÍÙ×Й™fÿ󗘊DÿçÞÅwÔ¸iÿïL½´`ÿã0ÿð‰ÍÁÿÞÿÿ½¯¢ÿÿ¡þç‰õß’ÿ÷qôá§ÝÅnéWòÛŒÿÐôçÅÙÂEÿÝøõðÀ£'ÿÛ=ÿïeÿéKÕÀjÿýsû浟TŽ­Ýɖ̶r¾¬vôéËÞÖΙŠDÞÆ‚ÿé9ÿÛ+ÞÅsÄ«b!ùO,”€O‚ƒ„…†‚9_‡†!Y3‹„:\LZ‘‚..c‡!:IG¥W#[/$‚A)VEJ³ >& ‚ 6D¿"*TƒH>88'KNX…?%-QK+@P ‡2=aãa`‡MSëë4†BUU-7^RUF†C Ob à1…¡ 5à baÆ¥H;oscache-2.4.1.orig/docs/wiki/icons/emoticons/biggrin.gif0000644000175000017500000000127010173132432023132 0ustar twernertwernerGIF89aæ{øÛúÝñÏþå"þä!¢˜|ePÝÝØäåãïòôéÂüá ’…cîñòùÛïÌâ·xgX   i?ƒcr16yÇxÇyS ‚n@, yxØÙby#89‚MjÙçx$"‚eèÙo‚VÈê 8Æ~fäÑ£¬áÂ<[¼Üa†…z2jÔ˜‡‹”5‚D,àãÆŒy.DQ!C!7,(<ÉP(jÀ€‡‚ æQpÂChƒØÑÌŒqÅà "À11RÅ„! ÐPrdE‡*¥ gÈŽ,dœ|š´'A‡ %&L(Q¡ƒ$º€ ;oscache-2.4.1.orig/docs/wiki/icons/emoticons/error.gif0000644000175000017500000000117110315621364022647 0ustar twernertwernerGIF89aæ¢ØÔØä`:Û&ÑŒŒÿýøÇÜA)ìwOÝêîÛ8È'Ô¹½ÿMãåå·ñ;ñfCæQ3ÿàºâ¬ ñññ ÿ¤gÌ2ÿnñA÷O)ð3Ò· ÿsDÿêàÞ‰ÿJñôô躰® ï)õÜÖŸ ý¡‘ÿšVÒ5ÿf3î×ÓãL1ëT8Åÿ<÷÷÷ã3øÙÏÖ?(ùDäÇÀÌ™™ôãß蛓äíî×äØÙÿøï¾ ÿ„Eå@Ç! ¦ ¼ øb;õ4ª æ ÷iH® ö8úg@ÿïêì[<îJ&Ê-ïJ!÷HÿR(ÿÞÐßH,ܸ¶ÿŽVÓ7!¶ ÿÿÿ¦ õîîØàC Ïí3ìT.÷4ÿßÔ÷÷ÿï]?° ÑàíñõeBÿíÞø(­à××ð_=Â'ÿ«mïB!ÿKïÁ°ÿ \Ó6ìßÙöE¿ÿZ)!ùÿ,Ö€Z‚ƒ„…‚)LIIeN/.U5:‚Et*@,y6ww P‚ipu 3"1F'KH, ƒ^UuxyÇyx0‚f?DÆxÈÅ iO‚G9wÇØæyw$‚EèèC‚6óõò`»—¯‹~MÈ![˜nŠõX˜ÃÀÃdÛ$ˆ¡qC *80†LY…f@è(”ÎŒwrá™9s’NÊŠð x“¨‰l  JC͇5@ áÉ-ìü"d„ 2J”˜æ +c¾ªte”Bv  òi’ž.„!"Ä’ì .;oscache-2.4.1.orig/docs/wiki/icons/emoticons/thumbs_up.gif0000644000175000017500000000043010315621364023521 0ustar twernertwernerGIF89aÄÿÿÿÿߪÔßÿÿßUÔߪÀÜÀÿ¿UÔ¿ªÔ¿Uª¿ªÿŸUÔŸªÔŸUªŸª  ¤ªŸUÔUÔªUª!ù,• Ì!žh*2Æcª0Àˆ«‡¡7ĈÀÀPò†Ãa»¦aùˆBC@Gd0/ÀA1ȧ\£ ’%Üsš˜M-±7(u2K|s\ #pƒ†: €'yr} M ‹}  l'P\Ÿ­( –Ÿ ¯7 ¸F'¹7!;oscache-2.4.1.orig/docs/wiki/icons/emoticons/lightbulb_on.gif0000644000175000017500000000104710315621364024170 0ustar twernertwernerGIF89aæ´•¤ûÐ%fffÿõ“Ó³KèÖ˜ÿãRå¹øøøÌ™3À¿Âéêìÿî{ÿßHßË÷ëËÍ ÿù¶Ç¥MøÛNëÆ-ÜÜÜÿêlçÔ¦ÿÙ:Å’ pvƒþóÕùÇݵ3ܪÿ÷¬¤¥§ÿñˆúã–ÁŠóâ¶™™™ÿÌ3üöãÿæfÿðqüÔTë¾þÛ9ôÅ!Å–Ý´Cÿÿ™âÁUÒ¤<ÿØ+ÿü±ÿî‡ÂÃÄþêpÿÿÌÿßSÿõšçº ÿÞBúÌ%ÿèYðÈ2ÿ÷Œ¶‚÷îÙùÛRÜ­ÿü©ùã™Â‰Ÿž¡üÓ5ÿü¿!ù ,„€ ‚ƒ„…†HA-†ƒ,L6+Ž$E:G<#@=†A<¦ž@ †-!##*†=#*99*.70†3ÅK*;†)F..KÐ;DŽ 5Ž‚15//?4ß‚&CIIç‚ J ï '8" ö‚üÞ;oscache-2.4.1.orig/docs/wiki/icons/emoticons/smile.gif0000644000175000017500000000127310173132432022625 0ustar twernertwernerGIF89aæ{þå"ÿå"þä!üá ñÏúÝùÛäåãéÂïòôÝÝØïÌeP¢˜|ýâ!’…cîñòö×â·xg<æ¼ðΣ™~uc6õÖžv å¼_IØØÑòÑÑÏÅÔÒÉäºbMå»wf:¡–zëÆÕ¡ lNoV ›qjP ´ÔÓÊçİ“Þ¯¢| šoiMͪ­­}Ÿ•x濚~§ŠiU r_1߲ط¾ Ò²ëÅïòóÕÔÌ¥›Ð› fP§ž„»Š sa3ÐÎÄÕ¢ gSâ·oT Þ±¤ƒhK¦‚ éÇóÔzi?ä¼Ù¬›pΠا ìÉïÑmP¶îÌݯ¨†Û®¡—{‰dlS À’ Ó°Ù§ ×ÖÏm Ø×ÐiT ÔŸ Íš {j@’r ¤“†exf;Ι ½Œ Þ°ÒÐÇøÛC4ÿæ"õùý!ù{,ÿ€{‚ƒ„…†„ CGo""UD- ‡‚ e:@_[4P+ ‡9\xxVp… ;qxx,l ƒBr/zÈz1‚w)TÇyÉy&b]‚c5xÈÙèzx %‚>êê!f‚ Sê%¨'ß¾, þ¹0G0»MÜ$Ü3áL Çr»ø¤ÎA%Â0°mà2’Ш¸!èƒðä±…kI0Š P"Â)*dÈC´(‚'°D¤€‰— A °ÀÄ0'lFhM5W$Œ!ÁŽ:dx¤9Ti††KÚ ‘åÓ¤= @\ Á‰ $Ý\(;oscache-2.4.1.orig/docs/wiki/icons/emoticons/star_green.gif0000644000175000017500000000107110315621364023646 0ustar twernertwernerGIF89aæYÇ%®Þ–|·Ç±€§m–Ë|aË,ÈâDz昅á]j—Z’µƒÚñμܶ{ÖS¤ÐµÅ­¼î¥Ãed§E—©x¶`޼{¥óŒkÏ;Èÿ´¢ð‡ãóÚ˜ã}±Ý¡žÁ“Úp¶æ¡‰ØaÌÌ̼ʶf›OŒ›†ËãËÊ鼌àkÆþ¬­Ô¢ÚÞØ¬ÚœpÐB ¦œÏÜʃ³oŸÑ†˜Æ~‹Át¢ß…f°F¸Û®Äο‡ž}~Æa³Þž±í“žµ’¸ì¡™×€›ç´Ø¢Žåm»¿¹Ãî­_©:ë÷æ£À—Êî¹vØIÙßÕÝU¯ÞœÁè²¶å ‚·rfÌ3£ï‹»ß°ËÚÃm™]–ÀƒÛúË¢Õˆk×6’äp¹ä«ŠÓh¼Ó±‰–È„ Ó‰ÿÿÿ!ù_,–€_‚ƒ„…†‚:‡† 6*‹„V&‘‚E] E†'^3Q@¦0TFR‚UGLY,´ =)‚@CMKÀK>Z;2ƒ614WD#…[?!O-H57‡Jä $‡/9AìA(X+†<S ?.† )N(|)ÂÅI††àHBH„!—";oscache-2.4.1.orig/docs/wiki/icons/emoticons/help_16.gif0000644000175000017500000000117210173132432022750 0ustar twernertwernerGIF89aæ\øjF¯88Çrròßߟã¹¹ž ÇssùuRú}[ÿÿÿü—yüŽoÌ9&ýŸƒú…eûŽoû…e¾\\øoKú}\åaGüÓÆôeCùoKþ§ŒÎA-ý—yÿ´šÞƒÿÑÂþ­“ý ƒùŒoãS7û°œÿ¼¥þìæÿÐÀõËÂÖthÖqeõ}_òdBÎ;'ýª’ýòþ¿¬ûƶÿèàèycý»©è|eÿÔÅÿ²šý§‹þÎÀÿ÷õüµ£ü¥‹þ±™ÿ¹¢ÿíèù…gý—zö‡iùuSùtSûŸ‡ú|[ý²œÿù÷ùnLþ®“ôjHûnýÎÁù~^õ‰lú’wÿ½¨ôjGþ¹£ú…dþ¹¡þ²™ùnKØuhüǸýÙÏþÓÅØseÿÿÿ!ù\,×€\‚\ƒƒ'%%'Ž(&$$&(š\)=P5Z6IT)„XU 1G>7<0…W- F / R-[†2 @ 8 ;Ü 4‡A 3 .çæNˆ*SK9Lõõ*‰ Š$ ¢àG )TP¤Ášè€HQˆ†E”L˜€!D–V0 ™ÅXªRŽP0"eÊ·¸ ÐàBÊ'./48å +Vˆ` U£B‡-j;oscache-2.4.1.orig/docs/wiki/icons/emoticons/check.gif0000644000175000017500000000113410315621364022572 0ustar twernertwernerGIF89aælœàwOÀ&×ìÊ.°„µ„™²Ö²fÈC¨ ˆ9Œ;¿è¿úöüùêúm&:µ…Ìz§Éªï÷ï…ÑáÑyÓL,'fÌ3 £§åƒ•Üw@¦AsP¾;êæìE»"r2ˆØ^. *…%£ßïÛ}!”lÆSŒÅŒ:µ!f3žõðöˆ¿Ž*ª ©~ÓY|)ÿÿÿZÅ,G¼!'­ éóÜ/¨$z$­Bµ!¸ß¸†»†1¨(‘sÊVl:›Ý{TÃ):”:B«BËŽMÀ' )¥)3¯"ª ÿ÷ÿ@¹–Ûxq6‰Øa†­>´+ÿÿÿ!ùW,¹€W‚ƒ„…†HG##*†‚ LB31(>… @"E7 K™ƒLŸ  <‚H)S«6J N&OI?‚6 E 8&55Q/ ‚#3%0–ÌË` â‰!òAAÁ‹'B<è ÑЄ vtXPà¡£—ƒ;oscache-2.4.1.orig/docs/wiki/icons/emoticons/tongue.gif0000644000175000017500000000127210173132432023014 0ustar twernertwernerGIF89aæ|ñÏúÝþå"þä!üá ùÛePÝÝØ¢˜|ïòôÿéÂäåãëÆòÑ’…cîñòxg<â·ðÎÿmgÿå"ö×ýâ!弨ØÑžv Õ¡ ¡–zõÖuc6ÔÒÉbMäºæ¼_IÑÏÅå»wf:ïÌ£™~ÒÐǽŒ Ø·ÐÎÄ­}hKëÅçÄìÉÎ lNΙ ا š~r_1Õ¢ iMlS Ù¬mP›piU â·oT xf;¤ƒ×ÖϨ†ïÑÛ®Л ¶ÔŸ ¥›Ÿ•x“†eÙ§ gS¦‚ fP‰dÕÔÌÀ’ iT jP éÇ伿¿Ó°¤»Š oV šoͪ¢| §ž„{j@Ò²sa3ݯØ×а“›q߲͚ ÔÓʧŠm ´zi?Þ°¡—{óÔÞ±îÌïòó’r ¾ Þ¯­øÛC4ÿæ"õùý!ù|,ÿ€|‚ƒ„…†„ R`a nJj ‡‚ :kbs1^BU ‡6EyyWu…>Zyy mTƒtLfzÇ{Çz"_‚)\qz{ØÙz F<$‚pxyÙç{y'‚+èÙ!S‚Vóõ°ÝË'Ã@?yÕpìGƒ|"d±@`›²‹Ýä¨"ˆÅ*$£@rY³&g–"‹Z ÈÔÃëΑ,AxðdÁ„¦ô(Ð3aš =  :à †'ÐÓ™ - #Tf ›J”ð¦(7†ª”CƒI¶tqñiŸP˜1Š’ì .;oscache-2.4.1.orig/docs/wiki/icons/emoticons/thumbs_down.gif0000644000175000017500000000043310315621364024047 0ustar twernertwernerGIF89aÄÿÿÿÿßÿÿߪÔßÿÿßUÔߪÀÜÀÿ¿ªÿ¿UÔ¿ªÔ¿Uª¿ªÿŸUÔŸªÿŸÔŸUªŸª  ¤ÔŸªŸUÔªUª!ù,˜ Žcñ(è@®€y"ò< [ÊSAXÆÃ0JäAÉC ,ÆHáLW,¢²¨Tír,sB‰€IUàÌV¹•¸ªm›Í ÑÃÆöÍC" 3{tor „oh,NQ—, œ ^Ÿ+ƒB‹¨"B_¯‚…·S3¶»ŽžÀ$!;oscache-2.4.1.orig/docs/wiki/icons/emoticons/star_blue.gif0000644000175000017500000000107110315621364023475 0ustar twernertwernerGIF89aæuÑ’¹åY©á‘Ôðb‹ÉÍÎâ{±åN×´Ñíd¯ìÓëÿ™·à0Øi˜Û}Åí¥â÷š¿ìW§ág·ý¶Óö­ÑîGœÞ§¾æW ß(ƒÕxÇÿгâ6Úh­éÍÜóq á™ÌÿæÿÿS¢ë”Âêv©ëÇÊáÃæÿ¦åö¯¿àCŠÏ`¨ñ"{Ó‘½ì¢ÆîpÁÿzÁê€Æìa¯äd˜Ó…£Þ¦Îîr²áV Ùc”Þg¤â‰ÇüÃÏìM–ßœºá¼èj«î¬Úÿ”½æŸÈö1‚Ð¯ëø±ÂáR¥Þ1ŒÞa¢ßŒµã­Öï¥Å÷‹Âòƒ´æg»ÿÎÞ÷v²ð¼èc­Þáñÿ½Õö\ åƒÉÿ=”ÚBŒÖvÅÿf´æQ˜ÜœÀçk­÷!ù ,–€ ‚ƒ„…†‚T‡†%,+ ‹„L$‘‚QCCS‡>W-!;¥:)[N‚ M,ZG³G<"‚8J"ëÅëÆ“†eÕ¡ xg<¤š½Œ `KΛ ·ôÕ˜níÌkOÙ¬½ çÀuc6ܯ”s ƨ¬|äºÐÎÄÔŸ qX oT 佩‡æ¼À’ gR¡—{­hL¦…Ÿ•xÕ¢ ͪا jNÙ§ Ι Þ¯žy ¡–z£™}‹eÙ¹xf;ïÑ›«gRnT šo¥‚ ß²’†díÊÑ› Μ º‰ ݯiT•‰hvd8׳kQ ïÍ®‘ïòó¸ëÊÒÐÇyh=kNhT™nÒ²‘n C4ÿæ"õùý!ùv,ÿ€v‚ƒ„…†„ "" ‡‚ YWrh^IFg ‡VU>6… p7kc ƒ%i uÈu Odj‚<-ÇÉut$50m‚PDÚttÈê Q‚eS!Ùëu9An‚(¼°‡/Ù>À|¤‚¹‚ÈÚ½[±Ð 3ÒäæÍC *‚Žü PL]²eÍ€0Ñ2DŽ30 @çV.:¼œ|yÓAP….[$\Ø ]º ¸˜ˆS¢Â BXLÑ€#&ˆ1 0B¢æÄP!ƒJšHqu¨Ò2ìã¢È§Iv¡8¡Aà ‘ð 6;oscache-2.4.1.orig/docs/wiki/icons/emoticons/warning.gif0000644000175000017500000000107110315621364023162 0ustar twernertwernerGIF89aæîäÑ® ëÍ„¶“ ðàPÝ¿zrt@öÒ8øðßϪG¼ž7ðâÃ56?ÚÆôߪóéãÔºñâlá¾^âЩɭ}ðã”ñÏE¶Ž(ÝÍ &'8ÿÿŽˆÝÜFË¥C@7÷÷*ÚÎ öäXõèAðÞ‰çÔw!òå+ìÚvÀ™(´ŒÿûÓ®W÷îØóç¥ùõíÜZΦ4ÝÃiÔ¬;ýã2ï߇ï޸ضJüõ¼–Ã?ÿèGèÓ‚öîúågüöåöî!¿˜ èÓ¤»”›5÷æ¥öé±÷êÉöæþò&åÉ#Ó°1ñãVöë@¸ìÜ{Ø­Búññá”Ç¡@Ï­'ëÙ‡81 <WJL,‡?3&!# †UO; +'@ …G75"I8„PR(YX=/CƒB2$(0#N8Ú‚S.OY04V]õë^ÆLMQ öõT¢ ƒHŠA†äX¸C„M#;oscache-2.4.1.orig/docs/wiki/icons/emoticons/information.gif0000644000175000017500000000175510315621364024053 0ustar twernertwernerGIF89a÷1ÿÿÿDªŠ¦ÕzÖI„ÊáëøḟîAk·¬ËäJ­ö)—íN¨yàþîßlÕÕÿ#„ÚTºŸÄðrŸÚ¢ÿZºünÍWµÿÿõ²âÿ&­ÿ™ÿkÞéïù/}ÐL³cÁ©Öõ3uÇ{ãÄÐìvÕ<§ö±Èì‘ï`¾]ÃP˜ÚN¿ÿ÷$‘éaÅÿ÷òïÞQ­q×&zÏÿùì{ ÕÕîþrÏ B¥•©Ô´Ëî0…ÖX¾O°øšöOµƒélÇáúÿußJkµ yÚQ«%â*™í”÷!{ÖmÌJ°_ʼnïûïãfÌÿI²ú!J­”Øÿ¹çÿ—ô{¢×ÿh,!ùY,ʳH° Af 1²Ã @|<ñ!D% ¢ð ã‚E$8Ñ‘Q 4R²È…ÈN ¼1 ˆM62àxðDB€†YF¼ A´Ã… ‚@à%B¢^©FJ>flrŠ×­I¹Bk–\¨M’!ƒ†±4ž4ÍBAÁ"Ĉ!Â&£‡¢$°Yƒ‡’ÀØ@ら#D}ð(8aÀ”€¤b³Á>äÈ1Ëc‡° ;oscache-2.4.1.orig/docs/wiki/icons/emoticons/star_red.gif0000644000175000017500000000106710315621364023325 0ustar twernertwernerGIF89aæý&Ö¡“¦ŒÇu_Õ¸±·gK÷—ƒÿp;â‡sÑP&ÚÖÔú¢ùhHð¤—å½²ÿƒ^ÿU ÷©–Øg>Ú@é‚fÑ“~þØÐÛ–…ÿ†R·§¤åÌÅö›„ë­£ø«ËÄÃÔzRÿFÿ¶yûì齜“òœŒÂ[;ÿ̽ÿ’Zÿ:°–ŽØnÿd:÷‰ÿY&ð‹pÿ•væÜÙð“{êj<÷€fÜM#ü²£¸Ž~ùĸüâÝÜÊÅ÷­”裗ÿqNþ…hÌ™™ïÇÅڿ¹ÿ@ ÿ ŠÜzéÔÎÿY#ÿ‹UßybïËÊÿ™€ÿn:ÿ3ÿs?î§›ÿ¦ÿ¬’Ðva×¼µä„i蘅÷­¥Õ~WÿMü; ³—‹ÿa,ý˜èàÞèhDÿÿÿ!ù_,”€_‚ƒ„…†‚ ‡†;8‹„1J?U‘‚"AA*‡7,1IVOO RE‚&55 $´ DQ‚@QDÀ,3 'H'†!#¥¸B‹¡)6`R ÀÃ¥H;oscache-2.4.1.orig/docs/wiki/icons/home_16.gif0000644000175000017500000000112210173132432020743 0ustar twernertwernerGIF89aæDÂÁ¢rCL#Q!ŒŒŒjjjOOOØ¥rÌÈÇÈÿéÓœIIIÑÑÑÿÿÿOPOøÅ’õΧ֣o¾‹WæææÉ—cÖ£pþݽ³LPOOYXXnnm³M„„ƒyyxzzy½ŠWÉÈÈ×ÖÖïðï‹ÌËÌææåPOPccbÖÖÖÖÖ×ÇãþÉ–cÛÛÜæçåÌÌÌXXXÌÌÍã°|¾‹Væçæåææh±æî»ˆÈÈÈŒŒ„„„ÛÛÛÊ–cnnnïïïcbb´Mã°}ÜÛÜÿÿÿ!ùD,¯€D‚ƒD„ˆ„ ‡D‰…  ‰(8™ŠB3¤‚¨ª²Ž…-´?#¶=‡ ´µÉª4†A´56/&À‡:ÉÉ Þ$ƒCæ<,.;„*"7+„ 4(@°B@` °„ƒ‡2RŠ‘ã_À B`Ô@èÁ2„ùà„A;oscache-2.4.1.orig/docs/wiki/icons/comment_16.gif0000644000175000017500000000026210173132432021461 0ustar twernertwernerGIF89a³3ŒÅääå{»å‰‰‰ÌÌÌ»»»xxxäÿÿ¯¯®¨ÔÿöööÜÝÜÿÿÿÿñÜÆÅÅÿÿÿ!ù,_ðdª­B  GhL(2Â!x[lK‰I)t`ß íÿ `èÑÈ$ÒWñ-žÐ'Ó¨Àᦾ‚v«enh.Wmã Åò«lðøƒj@ÈïsZïíùrvx;oscache-2.4.1.orig/docs/wiki/icons/mail_16.gif0000644000175000017500000000057510173132432020750 0ustar twernertwernerGIF89aÕ7ÿÿÿ¡¡ eee¶¶¶€€€i®àÅÅÅîï¡øøøüýüíìí$zºÊËËåää™ÌÿÞÿÿÚØÚkkk››šÓÑÓ›œšøøùóôô“’‘stsŽäâãqqqÞÞßãâäààáhhh𙙉‰‰wvvéééùøø““’ÙÙÙ}~}ãä䈈ˆsttžžƒƒƒ‰ˆˆ}||lll~}}ÓÕÔîîï••”‰Šˆÿÿÿ!ù7,šÀ€p(nÈä-h: £òÆr>Ñi`è…VЬŠ4˜Áf([\ïåÒ¨k”"íÀï6J.$D†D0)g  %# '&›« 13*©­/ M(©¡2É+›ÎIÂVNIÉÞßßA;oscache-2.4.1.orig/docs/wiki/Documentation.html0000644000175000017500000001444410615670675021436 0ustar twernertwerner OSCache - Documentation

1. Overview

  1. What is OSCache
  2. License
  3. Feature List - Details on OSCache's features and how they are best used.
  4. Requirements - What is required to run OSCache.
  5. FAQ - Frequently Asked Questions about OSCache.
  6. OSCache in the Wild - A list of sites that are using OSCache in production.

2. OSCache versions

  1. Change Log - See what's new in the latest version of OSCache (see also JIRA - Change Log).
  2. Roadmap - See the expected future releases of OSCache (see also JIRA - Road Map).
  3. Build and Test Reports - Unit Test Results, Clover Coverage Report and Ivy Dependency Report

3. Tutorial

  1. Installation Guide - How to install OSCache and where to get it.
  2. CacheFilter Tutorial - How to cache entire pages of your website.
  3. Clustering OSCache - How to use OSCache in a cluster.
  4. Statistics - How to implement a cache listener to provide cache hits and misses information.
  5. JMX Monitoring - JMX Monitoring and Administration via Spring.
  6. API Usage - How to use the GeneralCacheAdministrator.
  7. Taking the load off: OSCache helps database cope by Andres March.
  8. SVN and Compiling OSCache - How to access CVS and compile OSCache.

4. Reference Guide

  1. Configuration - Configuration options for OSCache.
  2. JSP Tags - Detailed documentation on OSCache's tags and how to use them.
  3. CacheFilter Configuration - How to configure OSCache to cache entire servlet responses.
  4. Cron Expressions - How to use the cron expression syntax to expire content.
  5. JavaDoc API - The OSCache API documentation in JavaDoc format.

5. Third-party integration

  1. Hibernate - How to integrate OSCache with Hibernate.
  2. Hibernate 2.1 and pre OSCache 2.4 support - Hibernate 2.1 integration and pre OSCache 2.4 classes.
  3. Spring - Simple configuration with no special support from Spring (taken from the Spring Integration).
  4. JPOX - Integration of OSCache with JPOX transparent persistence JDO implementation.

6. Links

  1. Current Release Home
  2. Support Forum
  3. Download Source and Binaries
  4. The current development release is available by the Ivy Repository
  5. SVN Access beginning with release 2.4 or CVS Access until release 2.3.2
  6. dev.java.net Project
  7. Mailing List
oscache-2.4.1.orig/docs/wiki/Complete Change Log.html0000644000175000017500000044235010643520716022235 0ustar twernertwerner OSCache - Complete Change Log

OSCache 2.4.1

Release Notes

(7th July 2007 - by Lars Torunski)

This maintenance release of 2.4.1 has two bug fixes:

  • The cacheFlushed method is not being invoked on the CacheEntryEventListener
  • CacheFilter max-age parameter MAX_AGE_NO_INIT not set properly

JIRA Issue List

OpenSymphony JIRA (3 issues)
T Key Summary Status
Bug CACHE-297 max-age parameter not set on ResponseContent object returned from cache when using MAX_AGE_NO_INIT ClosedClosed
Bug CACHE-296 For a Cache class the cacheFlushed method is not being invoked on the CacheEntryEventListener. ClosedClosed
Bug CACHE-279 LRUCache loses entries when updated by mutliple threads. ClosedClosed

OSCache 2.4

Release Notes

(1st Mai 2007 - by Lars Torunski)

New features and enhancements

Furthermore the next major release 2.4 enhances the CacheFilter and allows a better integration with the Spring Framework and JMX Monitoring.

  • Setting CacheFilter parameters runtime
  • Lazy initialization in CacheFilter in order to ease spring integration
  • Allow disabling cacheing for special http methods (e.g. POST/DELETE/PUT) in CacheFilter
  • CacheFilter allow reentrance over different filter configurations
  • Hibernate 3.2 integration support
  • JMX Monitoring/Administration via Spring
  • Improve oscache.properties loading
  • Performance improvment for large disk persistence usage

Upgrade Guide

  • Due to the enhancements in the CacheFilter and method signature changes, it's recommended to recompile your code.
  • Due to changes for CACHE-284 the handling of the listeners have been changed: Before OSCache 2.4 objects which implemented different CacheEventListener (e.g. CacheEntryEventListener and CacheMapAccessEventListener) had to be added twice, because the listeners where registrated only for one special event listener. With OSCache 2.4 only the object has to be added to the list without the 2nd parameter 'type of the listener'.

JIRA Issue List

OpenSymphony JIRA (29 issues)
T Key Summary Status
Bug CACHE-260 NullPointerException in AbstractConcurrentReadCache ClosedClosed
New Feature CACHE-295 Hibernate 3.2 integration support ClosedClosed
Improvement CACHE-215 Setting CacheFilter parameters runtime ClosedClosed
Improvement CACHE-99 Use lazy initialization in cache filter in order to ease spring integration ClosedClosed
Bug CACHE-258 NullPointerException when using putCache(key, val) in LRUCache ClosedClosed
Task CACHE-273 Update to Commons Logging 1.1 ClosedClosed
Task CACHE-253 Migrate from CVS to SVN ClosedClosed
Task CACHE-261 Check javadoc of Cache.cancelUpdate on key not being updated ClosedClosed
Sub-task CACHE-163 CacheFilter easier sub-classing via pre- and post-processes ClosedClosed
Sub-task CACHE-162 CacheFilter easier sub-classing via useCache ClosedClosed
Improvement CACHE-272 Allow disabling of cacheing special http methods (e.g. POST/DELETE/PUT) in CacheFilter ClosedClosed
Improvement CACHE-277 CacheFilter should allow reentrance over different filter configurations ClosedClosed
Improvement CACHE-283 Improve oscache.properties loading ClosedClosed
New Feature CACHE-266 ServletCacheAdministrator no longer a "Servlet Singleton" ClosedClosed
Improvement CACHE-267 SplitServletOutputStream doesn't pass flush() on to underlying stream ClosedClosed
Task CACHE-141 CacheFilter easier sub-classing ClosedClosed
Bug CACHE-288 Error in the HashDiskPersistenceListener byteArrayToHexString ClosedClosed
Bug CACHE-264 problem with not escaped group names and their filenames for disk persistence ClosedClosed
Bug CACHE-255 AbstractConcurrentReadCache#put(Object key, Object value) may return a wrong value ClosedClosed
Improvement CACHE-249 Performance improvment for large disk persistence usage ClosedClosed
Improvement CACHE-293 Allow to specify a different oscache.properties file for Hibernate ClosedClosed
Bug CACHE-278 Filter ignores max-age parameter when serving from cache ClosedClosed
Bug CACHE-284 Cache.dispatchCacheEntryEvent and Cache.addEventListener implementations are inconsistent ClosedClosed
Improvement CACHE-274 new method getIntialContext JMSBroadcastingListener ClosedClosed
Task CACHE-263 Run FindBugs 1.1.3 against current source code ClosedClosed
Bug CACHE-292 CacheFilter max-age default and error-case initialisation are wrong ClosedClosed
Improvement CACHE-290 Bad Practice ClosedClosed
New Feature CACHE-178 JMX Monitoring/Administration via Spring ClosedClosed
Improvement CACHE-252 Log warning if user tries to set max entries on an unlimited cache ClosedClosed

OSCache 2.3.2

Release Notes

(23rd July 2006 - by Lars Torunski)

This maintenance release of 2.3.1 has one enhancement:

  • The removeEntry method in the Cache removes the entry from its groups now

Bug fixes:

  • Method addGroupMappings leads to inconsistent memory cache if a persistent cache group exists
  • Cache group is updated if entry is removed (duplicate)

JIRA Issue List

OpenSymphony JIRA (3 issues)
T Key Summary Status
Bug CACHE-244 Cache group is not updated if entry is removed ClosedClosed
Improvement CACHE-188 removeEntry should update group mappings ClosedClosed
Bug CACHE-181 addGroupMappings leads to inconsistent Memory-Cache ClosedClosed

OSCache 2.3.1

Release Notes

(19th June 2006 - by Lars Torunski)

This maintenance release of 2.3 has one enhancement:

  • CacheFilter: Default initialization of the Cache-Control max-age

Bug fixes:

  • Cache.flushAll(Date flushDate) won't throw NeedsRefreshException when flush date is not yet reached anymore
  • No NoSuchElementException at Cache.putInCache() anymore

JIRA Issue List

OpenSymphony JIRA (3 issues)
T Key Summary Status
Bug CACHE-246 java.util.NoSuchElementException during at com.opensymphony.oscache.base.Cache.putInCache() ClosedClosed
Bug CACHE-241 Cache.flushAll(Date flushDate) throws NeedsRefreshException when flush date is not yet reached ClosedClosed
Improvement CACHE-240 Default initialization of the Cache-Control max-age ClosedClosed

OSCache 2.3

Release Notes

(6th March 2006 - by Lars Torunski)

This release includes additional improvements to the CacheFilter:

  • CRON expressions to expire content at specific dates and/or times
  • Pluggable EntryRefreshPolicy
  • Reduced memory consumption

Disk persistence:

  • Faster disk persistence
  • Avoid DiskPersistenceListener deadlocks if process has no rights to delete cache file

Further changes are:

  • new JSP tag addgroups
  • interface to get a list of the cache event listeners
  • commons collection dependency removed
  • Java 1.3 support dropped

JIRA Issue List

OpenSymphony JIRA (14 issues)
T Key Summary Status
Improvement CACHE-235 Pluggable EntryRefreshPolicy for CacheFilter ClosedClosed
Task CACHE-230 CacheFilter Tutorial ClosedClosed
Bug CACHE-229 Tomcat 5.5.12 throws IllegalStateException on getId() / fixed Servlet Spec 2.4 ClosedClosed
New Feature CACHE-228 Add CRON expressions to CacheFilter to expire content at specific dates and/or times. ClosedClosed
Task CACHE-227 Remove commons collections from distribution ClosedClosed
Task CACHE-226 Drop Java 1.3 support ClosedClosed
New Feature CACHE-222 Add new JSP tag addGroups ClosedClosed
Improvement CACHE-217 Avoid DiskPersistenceListener deadlocks if process has no rights to delete cache file ClosedClosed
Task CACHE-216 Review CacheFilter against Servlet 2.4 spec. ClosedClosed
Improvement CACHE-214 Reduce memory consumption of ResponseContent ClosedClosed
New Feature CACHE-200 add 'getCacheEventListenerList()' to Cache class ClosedClosed
Improvement CACHE-197 Speed up disk persistence ClosedClosed
Bug CACHE-183 HashDiskPersistenceListener / MessageDigest not thread safe ClosedClosed
Task CACHE-136 SequencedHashMap is deprecated in commons collections 3.1 ClosedClosed

OSCache 2.2 Final

Release Notes - Final

(6th November 2005 - by Lars Torunski)

Additionally to the 2.2 RC improvements, the final release was enhanced by:

  • Allow cache group definition in CacheFilter
  • Option to specify when to send Expires-Header
  • Allow disabling initial set of the last modified header
  • Continuous Integration and Dependency Management with Ivy
  • Update to JGroups 2.2.8

JIRA Issue List

OpenSymphony JIRA (12 issues)
T Key Summary Status
Bug CACHE-223 completeUpdate never being called after startUpdate() has been called, OSCache hangs for that key ClosedClosed
Task CACHE-211 Create check sums for the distribution files ClosedClosed
Task CACHE-210 Review: If last test-base and last test-web overwrite previous unit test reports ClosedClosed
Improvement CACHE-204 Allow disabling initial set of the last modified header ClosedClosed
Task CACHE-203 Change JSP tag URI in pages of example war ClosedClosed
Bug CACHE-202 Expires header should not be inital set in fragments ClosedClosed
Bug CACHE-201 Defined interface for ICacheKeyProvider not used in CacheFilter ClosedClosed
Task CACHE-199 Continuous Integration and Dependency Management with Ivy ClosedClosed
Task CACHE-198 Update to JGroups 2.2.8 ClosedClosed
Improvement CACHE-196 Option to specify when to send Expires-Header ClosedClosed
Improvement CACHE-195 Allow cache group generation in CacheFilter ClosedClosed
Task CACHE-194 Update Documentation ClosedClosed

OSCache 2.2 RC

Release Notes - Release Candidate

(18th September 2005 - by Lars Torunski)

Besides bugs being fixed, major improvements have been made to the CacheFilter in many ways:

  • Default initialization of the last modified header which reduces transaction overhead and server load
  • Support of GZip filters in the filter chain
  • Custom key generation by subclassing CacheFilter or by implementing a special interface
  • Preserving more http headers, e.g. the expires header
  • Special handling for fragments of a page
  • Avoids session creation for application scope pages
  • Multiple matching cache filters won't dead-lock the response anymore

JIRA Issue List

OpenSymphony JIRA (22 issues)
T Key Summary Status
Bug CACHE-189 AbstractDiskPersistenceListener.store hangs on exception ClosedClosed
Bug CACHE-185 Filtered requests will be re-requested twice ClosedClosed
Bug CACHE-184 Filter deadlock with external apps (mostly spiders) ClosedClosed
Improvement CACHE-179 Provider interface for method createCacheKey ClosedClosed
Bug CACHE-174 Regression in fix of CACHE-170: UpdateStateEntry may leak when entry are removed ClosedClosed
Bug CACHE-173 NullPointerException while flushing inexistant group ClosedClosed
Bug CACHE-170 Data race handling Cache.updateStates results in Thread hangs when the blocking mode is used in concurrence ClosedClosed
Improvement CACHE-169 Default initialization of the last modified header ClosedClosed
Sub-task CACHE-161 CacheFilter easier sub-classing via isCacheable ClosedClosed
Bug CACHE-160 ExpiresRefreshPolicy always set in CacheFilter ClosedClosed
New Feature CACHE-155 Support of GZip filters in the filter chain ClosedClosed
Bug CACHE-154 NullPointerException in JavaGroupsBroadcastingListener ClosedClosed
Bug CACHE-148 getInstance call not thread-safe ClosedClosed
Bug CACHE-144 CacheTag doesn't clear variables in doStartTag / doFinally ClosedClosed
Improvement CACHE-143 Report expected expiry to clients/browsers/proxy ClosedClosed
Task CACHE-138 Document new parameters in the wiki ClosedClosed
New Feature CACHE-135 CacheFilter for fragements of a page ClosedClosed
Bug CACHE-129 CacheFilter will create useless sessions for application-scope pages ClosedClosed
Bug CACHE-128 Multiple matching filters will dead-lock the response ClosedClosed
New Feature CACHE-120 New nocache option when body contains a jsessionid ClosedClosed
Bug CACHE-83 CacheHttpServletResponseWrapper & ResponseContent dont preserver Http headers ClosedClosed
Improvement CACHE-69 Custom Key Generation on CacheFilter ClosedClosed

OSCache 2.1.1

Release Notes

(1st May 2005 - by Andres March)

Improvements:

  • The taglib URI was changed to http://www.opensymphony.com/oscache in CACHE-61
  • The DiskPersistenceListener escapes '?' now and guarantees that the filenames will be unique based on the cache key, see CACHE-110
  • Session objects in cache tags are created only if necessary, see CACHE-88
  • The disk persistence configuration key can be accessed now, see CACHE-111

Bug Fixes:

  • The CacheFilter doesn't send back a 304 (not modified) response when client cache is de-activated anymore, see CACHE-116
  • CacheFilter doesn't support correctly i18N by setting encoding not properly, CACHE-38 and CACHE-159
  • Cron expressions - leap days not always matched correctly, CACHE-157
  • FindBugs doesn't report that the usage of GetResource may be unsafe if class Config is extended anymore, see CACHE-108
  • ConcurrentModificationException on flushGroup, see CACHE-127
  • Exception not thrown when not serializable object is persisted instead stack trace is persisted, see CACHE-112
  • A few concurrency issues were fixed, see CACHE-170, CACHE-167, CACHE-127

Changes that may affect backwards compatibility:

  • The improvement CACHE-88 may change the behaviour of the application, because a session object isn't created anymore even if it wasn't necessary. A web application may react different to a not existing session object.
  • The URI change of CACHE-61 from /oscache to http://www.opensymphony.com/oscache affects all JSP's which explicit use the old URI.

JIRA Issue List

OpenSymphony JIRA (15 issues)
T Key Summary Status
Bug CACHE-170 Data race handling Cache.updateStates results in Thread hangs when the blocking mode is used in concurrence ClosedClosed
Bug CACHE-167 removeEntry not synchronized ClosedClosed
Bug CACHE-159 CacheFilter does not set encoding properly ClosedClosed
Bug CACHE-157 Cron expressions - leap days not always matched correctly ClosedClosed
Task CACHE-131 JavaDoc: Missing class description - CacheContextListener ClosedClosed
Bug CACHE-127 ConcurrentModificationException on flushGroup ClosedClosed
Bug CACHE-116 CacheFilter sends back a 304 (not modified) response when client cache is de-activated ClosedClosed
Bug CACHE-112 Exception not thrown when not serializable object is persisted instead stack trace is persisted! ClosedClosed
Improvement CACHE-111 public access for disk persistence configuration key ClosedClosed
Improvement CACHE-110 DiskPersistenceListener should escape '?' ClosedClosed
Task CACHE-109 cache.blocking parameter missing in oscache.properties ClosedClosed
Bug CACHE-108 FindBugs reports: Usage of GetResource may be unsafe if class Config is extended ClosedClosed
Improvement CACHE-88 Don't create session object in cache tags unless necessary ClosedClosed
Improvement CACHE-61 Taglib URI Attribute ClosedClosed
Bug CACHE-38 oscache filter doesn't support correctly i18N ClosedClosed

OSCache 2.1

Release Notes

(18th January 2005 - by Andres March)

New Features:

  • Added HashDiskPersistenceListner CACHE-132 that hashes file names in order to eliminate nasty characters and overly long names
  • Added property that allows cache entries to only be persisted when the memory capacity has been exceeded. The property is called: cache.persistence.overflow.only. It defaults to false for backwards compatibility meaning all cache entries are persisted when a listener has been registered. See CACHE-133
  • Check If-Modified-Since header in cache filter to increase performance, see CACHE-58 and CACHE-70

Improvements:

  • Updated jgroups jar regarding changed package name CACHE-85 , CACHE-126 and configuration based upon recommendations from Bela Ban (javagroups maintainer).
  • More evenly distributed disk caching, see CACHE-94
  • Public access for configuration properties, see CACHE-92
  • Public method to clear cache, see CACHE-104 , CACHE-68
  • Output the scope name's in toString() of ScopeEventListenerImpl, see CACHE-95
  • Call get() method on put() method call, see CACHE-105
  • Library updates
  • Moved all docs to wiki
  • Website documentation updates.

Bug Fixes:

  • CACHE-73 - NullpointerException after deserialization of AbstractConcurrentReadCache
  • CACHE-98 - Disk cache not getting served first time for long keys
  • CACHE-107 - flushEntry does not behave correctly in cluster
  • CACHE-118 - Updating groups doesn't work
  • CACHE-119 - flush does not work correctly in a clustered environment

OpenSymphony JIRA (21 issues)
T Key Summary
New Feature CACHE-133 added cache.persistence.overflow.only property
New Feature CACHE-132 Added HashDiskPersistenceListner
Bug CACHE-126 java.lang.NoClassDefFoundError: org/javagroups/blocks/NotificationBus$Consumer
Bug CACHE-119 flush does not work correctly in a clustered environment
Bug CACHE-118 Updating groups doesn't work
Bug CACHE-107 flushEntry does not behave correctly in cluster
Improvement CACHE-105 call get() method on put() method call
Improvement CACHE-104 Destroy cache
Improvement CACHE-103 upgrade to Commons Collections 3.1
Improvement CACHE-102 upgrade to Commons Logging 1.0.4
Bug CACHE-98 Disk cache not getting served first time for long keys
Improvement CACHE-95 Output the scope name's in toString()
Improvement CACHE-94 More evenly distributed disk caching
Improvement CACHE-92 public access for configuration properties
Bug CACHE-89 java.lang.NullPointerException : AbstractCacheAdministrator.finalizeListeners
Improvement CACHE-85 upgrade to JavaGroups 2.2.7
Bug CACHE-73 NullpointerException after deserialization of AbstractConcurrentReadCache
Bug CACHE-72 NullPointerException in AbstractConcurrentReadCache.clear
Bug CACHE-71 Flush and refresh of cached pages fail under heavy load
Bug CACHE-70 last modified problem
New Feature CACHE-58 Check If-Modified-Since header in cache filter

OSCache 2.0.2

Release Notes

(22nd January 2004 - by Mathias Bogaert)

Improvements:

  • Website documentation updates.
  • Added OSCache in the Wild.

Bug Fixes:

  • CACHE-63 NullPointerException in GeneralCacheAdministrator#destroy().
  • CACHE-44 Multi threading issues with LRU Cache.
  • CACHE-66 DiskPersistenceListener is not Serializable.
  • GeneralCacheAdministrator now creates the cache from within the constructor. This prevents possible threading issues if the cache is not initialized during application startup.

OSCache 2.0.1

Release Notes

(4th November 2003 - by Chris Miller)

Improvements:

  • CACHE-56 Refresh period is no longer mandatory.
  • CACHE-51 Added an <cache:addgroup /> tag. This allows cache groups to be dynamically added from within a <cache:cache /> tag.
  • Website documentation is now bundled with the OSCache distribution.

Bug Fixes:

  • CACHE-59 Silent mode could not be reset.
  • CACHE-60 Fixed deadlock problem when cancelUpdate() was called while under load.

Changes that may affect backwards compatibility:

  • StringUtil.split() now returns a List rather than a String[].

OSCache 2.0

Release Notes

(22nd September 2003 - by Chris Miller)

Improvements:

  • Minor FastCronParser speedup.
  • Made ClusterNotification constants public.
  • Dropped some of the logging levels from INFO down to DEBUG.
  • Release has been split into two - a binary release and a full release (includes source).

Bug Fixes:

  • CACHE-52 Fixed a problem that caused no output on Tomcat for small JSP files.
  • CACHE-53 Updated documentation to explain that a PersistenceListener must be specified to enable caching to disk.
  • CACHE-55 JMS was throwing an exception on Weblogic.
  • Altering the cache capacity on the fly using the administrator classes wasn't working correctly.

OSCache 2.0 beta 2

Release Notes

(4th August 2003 - by Chris Miller)

New Features:

  • Now supports JavaGroups version 2.1.
  • JMS Clustering support has been added -Romulus Pasca.
  • Clustering code has been refactored. As a result of this, some of the clustering configuration has changed since beta 1 - please see the updated clustering documentation for details.
  • Performance enhancement: When running under JRE 1.3.x, the LRUCache will now attempt to use the Jakarta commons collections SequencedHashMap. If the commons-collections.jar is not present then the code resorts to using a LinkedList and a warning is logged. Note that under JRE 1.4.x and higher the commons-collections.jar is not required.
  • Config.getProperties() method added.

Bug Fixes:

  • CACHE-48 FastCronParser no longer requires JDK 1.4.x.
  • CACHE-45 Fixed a serialization bug.
  • The CachewideEvent was not holding the event date.
  • Prevented an error from being logged in the CachewideEvent handling (even though no problem had occurred).
  • Fixed a subtle bug in the concurrent unit test.
  • The ServletCacheAdministrator's app scope cache is created on startup (via the CacheContextListener).

OSCache 2.0 beta 1

Release Notes

(19th July 2003 - by Chris Miller)

New Features:

  • CACHE-11 Cache grouping support. This allows cache entries to be placed into an arbitrary group or groups and flushed with a single flushGroup() call.
  • CACHE-30 Added support for expiring cache entries based on a cron expression. Entries that are older than the date/time that most recently matches the cron expression will be considered stale. This is exposed to the cache tag via the 'cron' attribute. See cronTest.jsp for examples.
  • Event listener support has been refactored and improved. It is now possible to specify a comma-delimited list of event listeners using this property. Previously only one class could be specified. Events listed here should implement the CacheEntryEventListener and/or the ScopeEventListener interfaces.
  • New event CacheMapAccessEvent.STALE_HIT. This event is fired when an attempt is made to retrieve and entry from the cache, and the entry is found but is stale.
  • Clustering support has been added as an event listener. Currently it is implemented using JavaGroups . To enable, just add the BroadcastingCacheEventListener class to the cache.event.listeners property.
  • Now uses Jakarta Commons Logging for all log messages. This means that the cache.debug configuration property is now ignored - use whatever logging configuration is appropriate for your logging setup instead. -Fabian Crabus
  • CACHE-14, Matthias Nott Now allows for content to be cached indefinitely without expiration.
  • The build.xml <javac ...> directives now specify debug="true".
  • Performance boost: When OSCache is running on JRE 1.4 or higher, LRUCache and FIFOCache use a LinkedHashSet instead of a LinkedList.
  • Japloy is now used to ensure source is consistently formatted.
  • Test cases now work on non-windows platforms. Also coverage reports added courtesy of clover.

Changes that may affect backwards compatibility:

  • The cache.entryevent.classes property in the configuration file has been renamed to cache.event.listeners, since it accepts CacheEntryEventListener, ScopeEventListener and CacheMapAccessEventListener types.
  • The cache.persistence.classes property has been renamed to cache.persistence.class since it is only possible to specify one PersistenceListener.
  • For consistency, cache.unlimited_disk is now cache.unlimited.disk and cache.useHostDomainInKey is now cache.use.host.domain.in.key.
  • The oscache.tld file now uses a taglib 1.2 DTD.
  • To build OSCache, JDK 1.4.x or higher is required. There is however no runtime dependency on JDK 1.4.x.
  • The Cache.flushPattern() method and <cache:flush pattern="..."/> are deprecated. You are instead encouraged to group your cache entries when you add them to the cache and then use the Cache.flushGroup() method or the <cache:flush group="..."/> tag to flush an entire cache group.
  • Disk persistence now puts all files in the same directory. This has a number of side effects. Keys >255 chars will cause problems. Also, similar keys might get mapped to the same file. For example, it is very inadvisable to have two keys with the names 'my_key' and 'my.key'.
  • GeneralCacheAdministrator is no longer static. Users that relied on this behaviour can still hold onto a static reference to it with minor code changes.
  • When a NeedsRefreshException is thrown, it is now vital that the cache entry is either updated, or Cache.cancelUpdate(key) is called to release the lock on this cache entry. This is a consequence of the fix for CACHE-42 .
  • CacheProperties class was removed. It didn't work on 1.7.5 anyway. The same effect can be achieved by specifying a subclass of Properties.
  • Autogenerated cache keys now contain the request method (eg, HEAD, GET, etc).
  • OSCache has been repackaged from "com.opensymphony.module.oscache.*" to "com.opensymphony.oscache.*". Any code or configuration files that refer to "com.opensymphony.module.oscache" will need to be updated.

Bug Fixes:

  • CACHE-4 WebSphere 3.5.x compatibility.
  • CACHE-5 Added a mode attribute to the cache tag to allow content to be cached but not sent to the output stream. See oscacheTest.jsp for an example.
  • CACHE-7 "cache" Tag has no "setEncoding" method.
  • CACHE-9 It could be useful being able to specify directories relative to the web application dir. for config file and cache dir. Use new properties aware getInstance method.
  • CACHE-10 Cannot write and use custom class implementing CacheProperties.
  • CACHE-13 AbstractConcurrentReadCache loops indefinitely when persistRetrieve() returns null.
  • CACHE-14 You can now specify an unlimited refresh time by supplying a negative value for the duration.
  • CACHE-17 An example war is now included - "ant example-war". Once deployed this can be tested using "ant test-web".
  • CACHE-26 Security hole whereby certain keys can overwrite any file.
  • CACHE-28 URLs can now be used as keys with disk persistence.
  • CACHE-31 and CACHE-33 The cache tag's refresh attribute will now be taken into account even if a custom refresh policy has been specified.
  • CACHE-34 Setting properties with AbstractCacheAdministrators. New getInstance method added to ServletCacheAdministrator that takes in properties.
  • CACHE-35 CacheFilter needs to distinguish between HEAD and GET requests.
  • CACHE-39 and CACHE-44 Synchronization with LRUCache fixed.
  • CACHE-42 Threads will no longer race to (re)build expired or new cache entries. By default stale content will be served if available. This behaviour can be changed by setting oscache.blocking=true, which will instead cause threads to block until the new cache entry is available.
  • CACHE-43 Taglibs have been made spec-compliant. They now follow the guidelines at http://jakarta.apache.org/taglibs/guidelines.html.
  • Some synchronization issues were fixed in LRUCache.getItem() and AbstractConcurrentReadCache.setMaxEntries().
  • ScopeEventListener classes were previously not able to be specified in the configuration even though the dispatching code was implemented. ScopeEventListeners can now be specified using the cache.event.listeners configuration property.
  • CacheMapAccessEvents now only fire when an attempt is made to retrieve the actual cache content for external use. Previously these events were being fired in circumstances that were not of statistical interest - for example HIT and MISS events were being fired when updating or flushing entries from the cache.
  • Minor bug in oscacheTestMultipleTagNoKey.jsp - some of the tag refresh times weren't correctly specified.
  • cachetest.jsp - the 'refresh' functionality wasn't working because the addition of the refresh parameter caused the cache key to be different. The key is now specified explicitly.
  • EntryRefreshPolicy is now serializable so it can be persisted to the disk cache.
  • ServletCacheAdministrator now sorts request parameters and filters out jsessionid so they have no impact on the generated cache key.
  • CacheFilter only caches successful responses (status code == SC_OK).

Known Problems: (these have existed for some time in the 1.x.x versions and will be addressed in an upcoming 2.x.x release)

  • Session caches (created using the ServletCacheAdministrator) have some known limitations:
    o Due to a workaround in the code, it is possible for a system under heavy load to get its persistent session caches confused across sessions.
    o Session caches will not work in a clustered environment.
    o Session caches have the same settings global settings applied to them as the application scope cache. This means that if you want a persistent cache for the application scope cache, the session caches will use it too.

OSCache 1.7.5

Release Notes

(5th January 2002 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Fixed up logging system slightly. All errors should now be logged with logError() and normal messages with log()
  • Fixed bug in build file which put oscache.properties inside the oscache.jar (resulting in it being loaded badly in some containers)
  • Changed cache.capacity in the default oscache.properties file to 1000. This means up to 1000 items will be cached in the default setup, and LRUCache will be used (100 seemed too small)

OSCache 1.7.4

Release Notes

(3rd December 2001 - by Francois Beauregard, fbeauregard@pyxis-tech.com, and
Mike Cannon-Brookes, mike@atlassian.com)

  • Made all servlet cache components serializable (fixes bug reported on list with JRun)

OSCache 1.7.3

Release Notes

(11th November 2001 - by Francois Beauregard, fbeauregard@pyxis-tech.com)

  • TestCacheEntry had a test method with improper name (flush -> testFlush)
  • Pluggable entry refresh policy now available in the cache tag

OSCache 1.7.2

Release Notes

(31st October 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Cleaned up all JavaDoc messages to ensure consistency and readability (removed unnecessary CVS tags, added <code> and <pre> where needed, added @return and @param to all methods)
  • Renamed nbMaxEntries to cacheCapacity and cache.size property to cache.capacity (to fit better with Collections API where capacity is max size, size is current size)
  • Renamed algoClass to algorithmClass for clarity.
  • Fixed up build.xml so that test classes are compiled to a different location and not included in oscache.jar (to make it smaller footprint)

OSCache 1.7.1

Release Notes

(26th September 2001 - by Francois Beauregard, fbeauregard@pyxis-tech.com, and
Alain Bergevin, abergevin@pyxis-tech.com, of Pyxis Technologies Inc.)

  • Cache Events
  • Persistence mechanism refactored
  • Cache Algorithms FIFO + LRU (Limit the size of the cache)
  • AbstractConcurrentReadCache from Doug Lea's ConcurrentReaderHashMap.
    Should give oscache performance improvement
  • Disk Persistence does not need any locking strategies. Everything is handled by AbstractConcurrentReadCache
  • Pluggable entry refresh policies
  • Unlimited cache size for disk
  • Specify Duration using Simple Date Format or ISO-8601 as suggested by Fredrik Lindgren)
    The next one that would make sense I think is being able to specify a specific time of day.

OSCache 1.7.0

Release Notes

(26th September 2001 - by Francois Beauregard, fbeauregard@pyxis-tech.com, and
Alain Bergevin, abergevin@pyxis-tech.com, of Pyxis Technologies Inc.)

This version include some refactoring, corrections and new features.
Here are the highlights:

  • CacheAdministrator has been split in 3. We have now AbstractCacheAdministrator, and ServletCacheAdministrator and GeneralCacheAdministrator extends it
  • Packages have been adjusted. We now have oscache.base, oscache.general and oscache.Servlet.
    Adjustement must be made to the oscache.tld
  • ServletCacheHashMap has been created in order to reflect specific needs for Servlets. It extends CacheHashMap
  • Support for multiple cache tag in a single page, without supplying a key. Nested cache tag are not yet supported (you need to manage keys in that case).
  • OSCache can now cache any objects (not only JSP content) using GeneralCacheAdministrator
  • GenerateKey now support suffixes (used to deal with multiple cache tags)
  • A complete JUnit test suite has been created for osCache, including a JSP and a Servlet
  • Added the required libraries for the test unit. The JUnit JAR has been upgraded to version 3.7
  • Required libraries are now HHTPUnit, Tidy, JUnit 3.7 and JUnitPerf
  • The cBuffer variable used for keyGeneration has been moved locally to GenerateKey since it was a threading issue
  • The build file has been modified to include test running
  • The flushAll method is now abstract since CacheAbstractAdministrator can't know all valid scopes
  • Removed the retry logic for disk cache read and write (not used anymore)
  • Fixed an issue with the needsRefresh method which returned an invalid value when invoked first by returning true and then invoked having to return false. Both case returned true.
  • The doStartTag method in CacheTag has been modified to prevent returning null when cache content is missing (cache file deleted)
  • The doAfterBody method in CacheTag has been modified in order to prevent hitting the cache twice in some situation
  • The useBody method in CacheTag has been renamed to setUseBody in order to reflect its usage
  • LoadProperties interface added to CacheProperties
  • Added a NeedsRefreshException
  • Retrofited the changed made by Kesav Kumar in order to retrieve the sessionId correctly
  • Added code toughness to avoid working with invalid parameters in public methods
  • Magic numbers and strings are now declared as constants
  • Many methods are now declared as final or protected
  • Imports are now more accurate, no more *
  • Comments and some headers modified to reflect JavaDoc standard

OSCache 1.6.1

Release Notes

(16th September, 2001 - by Todd Gochenour, tgochenour@peregrine.com)

  • Removed attribute "encoding" in all areas, since Object serialization stores strings in UTF-8 format, encoding is no longer necessary.
  • Added Synchronization to getCacheEntry() to insure multiple threads do not access HashMap and get erroneous results.
  • Implemented property cache.useHostDomainInKey (true/false) to prepend URL request server name to cache key when cache used by multiple servers. The "cache.domainname" property found in oscache.properties (not used in code) was removed.
  • Corrected file caching logic so that multiple processes can share cache information (file locking). Missing still is the ability to signal processes that a cache needs to be flushed when using Memory Caching along with File Caching.
  • Unit testing revealed some minor configuration bugs which were corrected.

OSCache 1.6

Release Notes

(5th September, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Changed the CacheEntry so that it caches Object rather than String (allowing image caching) (Serge Knystautas, sergek@lokitech.com)
  • Cached objects are now serialized to disk so cannot be read by humans anymore (this allows us to cache Object) (Serge Knystautas, sergek@lokitech.com)
  • Added a Servlet 2.3 CacheFilter (and associated response classes) that caches whole requests (Serge Knystautas, sergek@lokitech.com)
  • Minor changes to CacheAdministrator (the way Cache and CacheEntry's are retrieved) - merging Serge and Todd's changes

OSCache 1.5

Release Notes

(6th August, 2001 - by Todd Gochenour, tgochenour@peregrine.com)

  • Added boolean "cache.memory" attribute to oscache.properties to eliminate memory consumption and rely strictly on disk storage.
  • Added three interfaces "CacheLog", "CacheProperties", and "CacheContents" to allow plugable implementations for these functions. The CacheContents interface allows the pages to be cached using a database.
  • Added "Language" attribute to CacheTag and FlushTag to distinguish a page that supports I18N generation. The ISO-639 language code is used when the scope of the page is "Application". The code defines a subdirectory under the "application" directory of file caching.
  • Modified the CacheAdministrator.generateKey() function to append the request's QueryString to the URI when automatically generating keys. The QueryString is encoded using the MD5 digest base64 algorithms.
  • Added attribute "encoding" to a CacheTag so that the file IO does proper conversion when reading and writing the cache files. (per suggestion of Pedro Gomez)
  • Added retries when SecurityException is thrown. Java has no built in exclusive file locking implementations. The file is written to a lock file and then renamed as an atomic operation so that multiple processes on the same box can reliable access cache data.
  • Added "pattern" attribute to FlushTag which invokes a CacheHashMap.flushPattern() function to scan for and flush all keys that contain the value of the pattern. (per suggestion of Todd Rudrick)
  • Added support for a CacheTag time value of zero which turns off caching for that tag. (per suggestion of Pedro Gomez)

OSCache 1.3

Release Notes

(9th June, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Fixed a single bug in the file caching - should now work
  • Added property to set the cache key (not sure if this is useful)
  • Cleaned up a lot of the code, refactored slightly so that the tags are more light weight and rely more on the Administrator and CacheHashMap for functionality.

OSCache 1.2.5

Release Notes

(18th May, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Added ability to turn off file caching (just remove or comment out cache.properties)
  • Removed a pesky (but ineffectual) bug where session caches being removed from disk were throwing NullPointerExceptions

OSCache 1.2.1

Release Notes

(10th May, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Speed improvements in CacheEntry and CacheAdministrator (by Kesav Kumar - kesavk@voquette.com)
  • Fixed DOCTYPE in taglib.tld (also Kesav!)
  • Removed backup / swap / temp files from zip (and changed build file)

OSCache 1.2

Release Notes

(28th March, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Fixed a large bug that resulted in CacheEntry's not refreshing. Large enough in a Caching library to demand a new point release

OSCache 1.1

Release Notes

(25th March, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Moved up to 1.1 because a lot of documentation improving and some small bug fixing has been done
  • Javadocs should now be very readable for all classes and methods
  • Fixed a NullPointer that was being thrown in CacheEntry.needsRefresh()
  • Cleaned up the build file so it now produces releasable zip files easily
  • Added servlet.jar so that the compiling now works OOB (Out Of the Box)

OSCache 1.0 beta 2

Release Notes

(20th March, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Fixed more bugs.
  • Moved things around so that the CacheAdministrator has more functionality and is now a Singleton (per web app context). This means no more depedency on ServletContextListener to start the CacheAdministrator.
  • Therefore we are now Servlet 2.2 / JSP 1.1 compliant! w00!

OSCache 1.0 beta 1

Release Notes

(20th February, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Fixed a few bugs.
  • Greatest of which there is no longer a disk leakage from session caches on disk.
  • Also session caching bugs fixed, usecached bugs fixed - lots of work done here.
  • Implemented to flush individual keys.

OSCache 1.0 beta 0

Release Notes

(26th November, 2000 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Initial release of OSCache
  • Conceptualised a few things I've been working on over the past month.
  • Added persistent on disk caching and error tolerance (through <usecached /> tag)
oscache-2.4.1.orig/docs/wiki/Statistics.html0000644000175000017500000002620210615670144020741 0ustar twernertwerner OSCache - Statistics

Description

With the cache event handlers a listerner can be implemented to provide cache hits and misses information. You can copy and paste the following code to get a statistic of your OSCache integration. Just change the used logger and the sample helps you to improve the cache key creation and to decide which scope to use. The SimpleStatisticListenerImpl should be configured via the cache.event.listeners in the oscache.properties.

Sample Code

SimpleStatisticListenerImpl.java
/*
 * Copyright (c) 2002-2007 by OpenSymphony
 * All rights reserved.
 */
package com.opensymphony.oscache.extra;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.base.events.*;

/**
 * A simple implementation of a statistic reporter which uses the
 * CacheMapAccessEventListener, CacheEntryEventListener and ScopeEventListener.
 * It uses the events to count the cache hit and misses and of course the
 * flushes.
 * <p>
 * We are not using any synchronized so that this does not become a bottleneck.
 * The consequence is that on retrieving values, the operations that are
 * currently being done won't be counted.
 */
public class SimpleStatisticListenerImpl implements CacheMapAccessEventListener, CacheEntryEventListener, ScopeEventListener {

    private static transient final Log log = LogFactory.getLog(SimpleStatisticListenerImpl.class);

    /**
     * Hit counter
     */
    private int hitCount = 0;

    /**
     * Miss counter
     */
    private int missCount = 0;

    /**
     * Stale hit counter
     */
    private int staleHitCount = 0;

    /**
     * Hit counter sum
     */
    private int hitCountSum = 0;

    /**
     * Miss counter sum
     */
    private int missCountSum = 0;

    /**
     * Stale hit counter
     */
    private int staleHitCountSum = 0;

    /**
     * Flush hit counter
     */
    private int flushCount = 0;

    /**
     * Constructor, empty for us
     */
    public SimpleStatisticListenerImpl() {
        log.info("Creation of SimpleStatisticListenerImpl");
    }

    /**
     * This method handles an event each time the cache is accessed
     * 
     * @param event The event triggered when the cache was accessed
     * @see com.opensymphony.oscache.base.events.CacheMapAccessEventListener#accessed(CacheMapAccessEvent)
     */
    public void accessed(CacheMapAccessEvent event) {
        String result = "N/A";

        // Retrieve the event type and update the counters
        CacheMapAccessEventType type = event.getEventType();

        // Handles a hit event
        if (type == CacheMapAccessEventType.HIT) {
            hitCount++;
            result = "HIT";
        }
        // Handles a stale hit event
        else if (type == CacheMapAccessEventType.STALE_HIT) {
            staleHitCount++;
            result = "STALE HIT";
        }
        // Handles a miss event
        else if (type == CacheMapAccessEventType.MISS) {
            missCount++;
            result = "MISS";
        }

        if (log.isDebugEnabled()) {
            log.debug("ACCESS : " + result + ": " + event.getCacheEntryKey());
            log.debug("STATISTIC : Hit = " + hitCount + ", stale hit ="
                    + staleHitCount + ", miss = " + missCount);
        }
    }
    
    /**
     * Logs the flush of the cache.
     * 
     * @param info the string to be logged.
     */
    private void flushed(String info) {
        flushCount++;

        hitCountSum += hitCount;
        staleHitCountSum += staleHitCount;
        missCountSum += missCount;

        if (log.isInfoEnabled()) {
            log.info("FLUSH : " + info);
            log.info("STATISTIC SUM : " + "Hit = " + hitCountSum
                    + ", stale hit = " + staleHitCountSum + ", miss = "
                    + missCountSum + ", flush = " + flushCount);
        }

        hitCount = 0;
        staleHitCount = 0;
        missCount = 0;
    }

    /**
     * Event fired when a specific or all scopes are flushed.
     * 
     * @param event ScopeEvent
     * @see com.opensymphony.oscache.base.events.ScopeEventListener#scopeFlushed(ScopeEvent)
     */
    public void scopeFlushed(ScopeEvent event) {
        flushed("scope " + ScopeEventListenerImpl.SCOPE_NAMES[event.getScope()]);
    }

    /**
     * Event fired when an entry is added to the cache.
     * 
     * @param event CacheEntryEvent
     * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryAdded(CacheEntryEvent)
     */
    public void cacheEntryAdded(CacheEntryEvent event) {
        // do nothing
    }

    /**
     * Event fired when an entry is flushed from the cache.
     * 
     * @param event CacheEntryEvent
     * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryFlushed(CacheEntryEvent)
     */
    public void cacheEntryFlushed(CacheEntryEvent event) {
        // do nothing, because a group or other flush is coming
        if (!Cache.NESTED_EVENT.equals(event.getOrigin())) {
            flushed("entry " + event.getKey() + " / " + event.getOrigin());
        }
    }

    /**
     * Event fired when an entry is removed from the cache.
     * 
     * @param event CacheEntryEvent
     * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryRemoved(CacheEntryEvent)
     */
    public void cacheEntryRemoved(CacheEntryEvent event) {
        // do nothing
    }

    /**
     * Event fired when an entry is updated in the cache.
     * 
     * @param event CacheEntryEvent
     * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryUpdated(CacheEntryEvent)
     */
    public void cacheEntryUpdated(CacheEntryEvent event) {
        // do nothing
    }

    /**
     * Event fired when a group is flushed from the cache.
     * 
     * @param event CacheGroupEvent
     * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheGroupFlushed(CacheGroupEvent)
     */
    public void cacheGroupFlushed(CacheGroupEvent event) {
        flushed("group " + event.getGroup());
    }

    /**
     * Event fired when a key pattern is flushed from the cache.
     * 
     * @param event CachePatternEvent
     * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cachePatternFlushed(CachePatternEvent)
     */
    public void cachePatternFlushed(CachePatternEvent event) {
        flushed("pattern " + event.getPattern());
    }

    /**
     * An event that is fired when an entire cache gets flushed.
     * 
     * @param event CachewideEvent
     * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheFlushed(CachewideEvent)
     */
    public void cacheFlushed(CachewideEvent event) {
        flushed("wide " + event.getDate());
    }

    /**
     * Return the counters in a string form
     *
     * @return String
     */
    public String toString() {
        return "SimpleStatisticListenerImpl: Hit = " + hitCount + " / " + hitCountSum
                + ", stale hit = " + staleHitCount + " / " + staleHitCountSum
                + ", miss = " + missCount + " / " + missCountSum
                + ", flush = " + flushCount;
    }
}
oscache-2.4.1.orig/docs/wiki/OSCache 1.7.2.html0000644000175000017500000000233610402251442020472 0ustar twernertwerner OSCache - OSCache 1.7.2

Release Notes

(31st October 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Cleaned up all JavaDoc messages to ensure consistency and readability (removed unnecessary CVS tags, added <code> and <pre> where needed, added @return and @param to all methods)
  • Renamed nbMaxEntries to cacheCapacity and cache.size property to cache.capacity (to fit better with Collections API where capacity is max size, size is current size)
  • Renamed algoClass to algorithmClass for clarity.
  • Fixed up build.xml so that test classes are compiled to a different location and not included in oscache.jar (to make it smaller footprint)
oscache-2.4.1.orig/docs/wiki/Hibernate 3 Cache Adaptor.html0000644000175000017500000001725210315621364023174 0ustar twernertwerner OSCache - Hibernate 3 Cache Adaptor

Patched version of OSCache.java for Hibernate 3 - originally created by Mathias Bogaert.

OSCache.java
import java.util.Properties;
import java.util.Map;

import org.hibernate.util.PropertiesHelper;
import org.hibernate.util.StringHelper;
import org.hibernate.cache.*;

import com.opensymphony.oscache.base.Config;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.NeedsRefreshException;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;

/**
 * Adapter for the OSCache implementation
 */
public class OSCache implements Cache {
    
    /** 
     * The <tt>OSCache</tt> cache capacity property suffix. 
     */
    public static final String OSCACHE_CAPACITY = "cache.capacity";

    private static final Properties OSCACHE_PROPERTIES = new Config().getProperties();
	/** 
	 * The OSCache 2.0 cache administrator. 
	 */
	private static GeneralCacheAdministrator cache = new GeneralCacheAdministrator();

    private static Integer capacity = PropertiesHelper.getInteger(OSCACHE_CAPACITY,
                                                                  OSCACHE_PROPERTIES);

    static {
        if (capacity != null) cache.setCacheCapacity(capacity.intValue());
    }
    
	private final int refreshPeriod;
	private final String cron;
	private final String regionName;
    private final String[] regionGroups;
	
	private String toString(Object key) {
		return String.valueOf(key) + "." + regionName;
	}

	public OSCache(int refreshPeriod, String cron, String region) {
		this.refreshPeriod = refreshPeriod;
		this.cron = cron;
		this.regionName = region;
        this.regionGroups = new String[] {region};
	}

	public Object get(Object key) throws CacheException {
		try {
			return cache.getFromCache( toString(key), refreshPeriod, cron );
		}
		catch (NeedsRefreshException e) {
			cache.cancelUpdate( toString(key) );
			return null;
		}
	}

	public void put(Object key, Object value) throws CacheException {
		cache.putInCache( toString(key), value, regionGroups );
	}

	public void remove(Object key) throws CacheException {
		cache.flushEntry( toString(key) );
	}

	public void clear() throws CacheException {
		cache.flushGroup(regionName);
	}

	public void destroy() throws CacheException {
		synchronized (cache) {
		    cache.destroy();
        }
	}

	public void lock(Object key) throws CacheException {
		// local cache, so we use synchronization
	}

	public void unlock(Object key) throws CacheException {
		// local cache, so we use synchronization
	}

	public long nextTimestamp() {
		return Timestamper.next();
	}

	public int getTimeout() {
		return Timestamper.ONE_MS * 60000; //ie. 60 seconds
	}

	public Map toMap() {
		throw new UnsupportedOperationException();
	}    

	public long getElementCountOnDisk() {
		return -1;
	}

	public long getElementCountInMemory() {
		return -1;
	}
    
	public long getSizeInMemory() {
		return -1;
	}

	public String getRegionName() {
		return regionName;
	}

	public void update(Object key, Object value) throws CacheException {
		put(key, value);
	}    

	public Object read(Object key) throws CacheException {
		return get(key);
	}
}
oscache-2.4.1.orig/docs/wiki/OSCache in the Wild.html0000644000175000017500000000605610315621364022066 0ustar twernertwerner OSCache - OSCache in the Wild

The following are some of the sites that are using OSCache in production. This is far from an exhaustive list of course! If you have or know of a site using OSCache, please let us know so we can add it to the list. While not required, any performance figures, load levels or case studies that you can include would be greatly appreciated.

oscache-2.4.1.orig/docs/wiki/OSCache 1.7.5.html0000644000175000017500000000212510402251442020471 0ustar twernertwerner OSCache - OSCache 1.7.5

Release Notes

(5th January 2002 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Fixed up logging system slightly. All errors should now be logged with logError() and normal messages with log()
  • Fixed bug in build file which put oscache.properties inside the oscache.jar (resulting in it being loaded badly in some containers)
  • Changed cache.capacity in the default oscache.properties file to 1000. This means up to 1000 items will be cached in the default setup, and LRUCache will be used (100 seemed too small)
oscache-2.4.1.orig/docs/wiki/Clustering.html0000644000175000017500000001347210402251442020721 0ustar twernertwerner OSCache - Clustering

New in OSCache 2.0 is support for clustering of caches. OSCache currently ships with implementations that allow you to use either JavaGroups or JMS as the underlying broadcast protocol.

Caches across a cluster only broadcast messages when flush events occur. This means that the content of the caches are built up independently on each server, but whenever content becomes stale on one server it is made stale on them all. This provides a very high performing solution since we never have to pass cached objects around the cluster. And since there is no central server that is in charge of the cluster, the clustering is very robust.

Configuring OSCache to cluster is very simple. Follow either the JMS or the JavaGroups instructions below depending on which protocol you want to use.

JMS Configuration

Configure your JMS server. OSCache requires that a JMS ConnectionFactory and a Topic are available via JNDI. See your JMS server's documentation for details.

Add the JMS broadcasting listener to your oscache.properties file like this:

cache.event.listeners=com.opensymphony.oscache.plugins.clustersupport.JMSBroadcastingListener

(Note that this listener requires JMS 1.1 or higher, however legacy support for 1.0.x is also provided. If your JMS server only supports JMS 1.0.x then use JMS10BroadcastingListener instead of JMSBroadcastingListener. The rest of this documentation applies equally to both the 1.1 and 1.0 listeners.)

The JMS listener supports the following configuration parameters:

  • cache.cluster.jms.topic.factory - The JNDI name that binds the JMS topic connection factory. This should match the name that is specified in your JMS server's configuration. Typically it will be something like "java:comp/env/jms/TopicConnectionFactory"
  • cache.cluster.jms.topic.name - The JNDI name of the topic that will be used for the OSCache sending the messages. This should match the name of a topic that is configured on your JMS server. Typically this value will be something like "java:comp/env/jms/OSCacheTopic".
  • cache.cluster.jms.node.name - A name that uniquely identifies this node in the cluster. This is used to prevent nodes from processing their own broadcast messages. Each node in the cluster must have a different value, for example "node1", "node2", ... .

If you are running OSCache from a standalone application or are not running in an environment where new InitialContext() will find your JNDI InitialContextFactory or provider URL, you will have to specify them either in a jndi.properties file or as system properties. See the InitalContext documentation for details.

JavaGroups Configuration

Just make sure you have jgroups-all.jar file in your classpath (for a webapp put it in WEB-INF/lib), and add the JavaGroups broadcasting listener to your oscache.properties file like this:

cache.event.listeners=com.opensymphony.oscache.plugins.clustersupport.JavaGroupsBroadcastingListener

In most cases, that's it! OSCache will now broadcast any cache flush events across the LAN. The jgroups-all.jar library is not included with the binary distribution due to its size, however you can obtain it either by downloading the full OSCache distribution, or by visiting the JavaGroups website.

If you want to run more than one OSCache cluster on the same LAN, you will need to use different multicast IP addresses. This allows the caches to exist in separate multicast groups and therefore not interfere with each other. The IP to use can be specified in your oscache.properties file by the cache.cluster.multicast.ip property. The default value is 231.12.21.132, however you can use any class D IP address. Class D address fall in the range 224.0.0.0 through 239.255.255.255.

If you need more control over the multicast configuration (eg setting network timeout or time-to-live values), you can use the cache.cluster.properties configuration property. Use this instead of the cache.cluster.multicast.ip property. The default value is:

UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;\
mcast_send_buf_size=150000;mcast_recv_buf_size=80000):\
PING(timeout=2000;num_initial_members=3):\
MERGE2(min_interval=5000;max_interval=10000):\
FD_SOCK:VERIFY_SUSPECT(timeout=1500):\
pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):\
UNICAST(timeout=300,600,1200,2400):\
pbcast.STABLE(desired_avg_gossip=20000):\
FRAG(frag_size=8096;down_thread=false;up_thread=false):\
pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)

See the JavaGroups site for more information. In particular, look at the documentation of Channels in the User's Guide.

oscache-2.4.1.orig/docs/wiki/CacheFilter Tutorial.html0000644000175000017500000002645010615670675022562 0ustar twernertwerner OSCache - CacheFilter Tutorial

Introduction

OSCache comes with a servlet filter that enables you to transparently cache entire pages of your website, and even binary files. Caching of binary files is extremely useful when they are generated dynamically, e.g. PDF files or images. In addition by using the last modified header the transaction overhead and server load is reduced excellently which speed ups the server response time.

How to configure OSCache to cache entire servlet responses is described in the configuration page of the CacheFilter. This short tutorial should demonstrate how to make your web site more responsive, and save load on your server. Using the CacheFilter the user will appreciate a faster loading site and will visit it more often.

Improvements

Major improvements have been made to the CacheFilter in the releases 2.2 and 2.3:

  • Default initialization of the last modified header which reduces transaction overhead and server load
  • CRON expressions to expire content at specific dates and/or times
  • Preserving more http headers, e.g. the expires header
  • Special handling for fragments of a page
  • Custom cache key generation by subclassing CacheFilter or by implementing a special interface
  • Custom cache groups generation by subclassing CacheFilter or by implementing a special interface
  • Support of GZip filters in the filter chain
  • Avoids session creation for application scope pages
  • Reduced memory consumption
  • Multiple matching cache filters won't dead-lock the response anymore
  • The cache won't be serve the same response twice before the client begins to cache it anymore

Cacheable Content

Cacheable content

Note that the filter will only cache content that has a status of 200 (HttpServletResponse.SC_OK).

Configuring the filter

Example 1

To configure the filter, add something like the following to your web.xml file (obviously you will want to set the URL pattern to match only the content you want to cache; this example will cache all JSP pages for 10 minutes in session scope):

<filter>
    <filter-name>CacheFilter</filter-name>
    <filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
    <init-param>
        <param-name>time</param-name>
        <param-value>600</param-value>
    </init-param>
    <init-param>
        <param-name>scope</param-name>
        <param-value>session</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>CacheFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
</filter-mapping>

The default duration is one hour and the default scope for the cache is application scope. You can change these settings using initialization parameters.

Example 2

The initialization of the last modified header based on the current time reduces transaction overhead and server load, because the browser can ask the server if the cached content in the browser cache was changed on the server since the last request. If the content wasn't changed , the server will response with the status 304 (not modified).

Furthermore if the expires parameter is the set to time, the server will send the date and time after which the content is considered stale. Then common browsers won't request the server anymore until the cached content is considered stale. The example will cache the content for one hour by default and the expires date and time will be calculated based on the creation time and the time parameter (default is one hour).

<filter>
    <filter-name>CacheFilterStaticContent</filter-name>
    <filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
    <init-param>
        <param-name>expires</param-name>
        <param-value>time</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>CacheFilterStaticContent</filter-name>
    <url-pattern>*.jsp</url-pattern>
</filter-mapping>

Using the filter

Example 1: ICacheKeyProvider

A simple example how to use the ICacheKeyProvider parameter of the CacheFilter. The cache key in constructed with the http request URI and with two request parameters pageid and pagination.

import javax.servlet.http.HttpServletRequest;

import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.web.ServletCacheAdministrator;
import com.opensymphony.oscache.web.filter.ICacheKeyProvider;

public class ExampleCacheKeyProvider implements ICacheKeyProvider {

    public String createCacheKey(HttpServletRequest httpRequest, ServletCacheAdministrator scAdmin, Cache cache) {

        // buffer for the cache key
        StringBuffer buffer = new StringBuffer(100);
        
        // part 1 of the key: the request uri
        buffer.append(httpRequest.getRequestURI());
        
        // separation
        buffer.append('_');

        // part 2 of the key: the page id
        buffer.append(httpRequest.getParameter("pageid"));
        
        // separation
        buffer.append('_');
        
        // part 3 of the key: the pagination
        buffer.append(httpRequest.getParameter("pagination"));
        
        return buffer.toString();
    }

}

You can use session attributes values for the cache key also, if request parameters aren't available or e.g. security settings have to be add to the cache key.

Example 2: Flush

The flush example shows how to flush a CacheFilter with scope application based on group names. In this example the http servlet request of the user is required to get the cache object.

import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.web.ServletCacheAdministrator;

import java.util.Collection;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.PageContext;

public class OSCacheAdmin {
    
    /**
     * flush the CacheFilter according to dependent group
     *
     * @param request the HttpServletRequest of the user
     * @param groupNames a string collection of group names
     */
    public static void flushCacheGroup(HttpServletRequest request, Collection groupNames) {
    	Cache cache = ServletCacheAdministrator.getInstance(request.getSession().getServletContext()).getCache(request, PageContext.APPLICATION_SCOPE); 
        Iterator groups = groupNames.iterator();
        while (groups.hasNext()) {
            String group = (String) groups.next();
            cache.flushGroup(group);
        }
    }
}

If you're CacheFilter is running with scope session, you have to get the cache as follows:

Cache cache = ServletCacheAdministrator.getInstance(request.getSession(true).getServletContext()).getCache(request, PageContext.SESSION_SCOPE);
oscache-2.4.1.orig/docs/wiki/index.html0000644000175000017500000011446510641651526017731 0ustar twernertwerner OSCache - Index

Space Index

0-9 ... 0 A ... 1 B ... 0 C ... 8 D ... 1 E ... 0
F ... 2 G ... 0 H ... 7 I ... 2 J ... 2 K ... 0
L ... 1 M ... 0 N ... 0 O ... 32 P ... 0 Q ... 0
R ... 2 S ... 3 T ... 0 U ... 0 V ... 0 W ... 1
X ... 0 Y ... 0 Z ... 0 !@#$ ... 0    

0-9

A

API Usage
Beside the JSP tag library JSP Tags and the CacheFilter you can use OSCache through its straightforward API. You can use the GeneralCacheAdministrator http://www.opensymphony.com/oscache/api/com/opensymphony/oscache/general/GeneralCacheAdministrator.html to create, flush ...

B

C

CacheFilter
OSCache comes with a servlet filter that enables you to transparently cache entire pages of your website, and even binary files. Caching of binary files is extremely useful when they are generated dynamically, e.g. PDF files or images. A tutorial CacheFilter Tutorial ...
CacheFilter Tutorial
Introduction OSCache comes with a servlet filter that enables you to transparently cache entire pages of your website, and even binary files. Caching of binary files is extremely useful when they are generated dynamically, e.g. PDF files or images. In addition by using ...
Chain Caching Model
Discussion Lars wrote: Would it be possible to use the intercepting filter pattern to support all possible cache models with a lot of combination capabilities? It's possible to define the capacity for each cache etc. DiskPersistence, SoftReferenceCache etc. would implement the Command interface ...
Change Log
Release Notes 2007 OSCache 2.4.1 OSCache 2.4 2006 OSCache 2.3.2 OSCache 2.3.1 OSCache 2.3 2005 OSCache 2.2 OSCache 2.2 RC OSCache 2.1.1 OSCache 2.1 2004 OSCache 2.0.2 2003 OSCache 2.0.1 ...
Clustering
New in OSCache 2.0 is support for clustering of caches. OSCache currently ships with implementations that allow you to use either JavaGroups or JMS as the underlying broadcast protocol. Caches across a cluster only broadcast messages when flush events occur. This means ...
Complete Change Log
OSCache 2.4.1 OSCache 2.4 OSCache 2.3.2 OSCache 2.3.1 OSCache 2.3 OSCache 2.2 Final OSCache 2.2 RC OSCache 2.1.1 OSCache 2.1 OSCache 2.0.2 OSCache 2.0.1 OSCache 2.0 OSCache 2.0 beta 2 ...
Configuration
guide only covers the configuration of OSCache by using the oscache.properties file. To see how to install OSCache and where to place the oscache.properties file, see the Installation Guide. The following properties are able to be set in the oscache.properties file: cache.memory Valid values are true or false ...
Cron Expressions
Prior to version 2.0 of OSCache, content expiry could only be specified in terms of how long a piece of content had been in the cache, ie, it was based on the age of the content. If you needed to expire it at a particular time of day or on a specific date, you ...

D

Documentation
1. Overview # What is OSCache # License # Feature List Details on OSCache's features and how they are best used. # Requirements What is required to run OSCache. # FAQ Frequently Asked Questions about OSCache. # OSCache in the Wild A list of sites that are using OSCache ...

E

F

FAQ
Got a question you'd like to ask? Ask us and we'll add it to the FAQ. Questions What can I use OSCache for exactly? #uses Where is the data cached? #data Can OSCache cache Java objects rather than portions ...
Feature List
OSCache Features Fast inmemory caching OSCache allows you to store dynamic content (eg for 30 minutes) in memory. Each further request is served directly from the memory cache, resulting in dramatic speed increases. The cache is keyed programmatically ...

G

H

Hibernate
Hibernate http://www.hibernate.org/ is a powerful, ultrahigh performance object/relational persistence and query service for Java. Hibernate lets you develop persistent objects following common Java idiom including association, inheritance, polymorphism, composition and the Java collections framework ...
Hibernate 2.1 and pre OSCache 2.4 support
page is intended to give integration support for Hibernate 2.1 and for pre OSCache 2.4 releases. It's recommended to use the new Hibernate 3.2 Hibernate classes. Hibernate http://www.hibernate.org/ is a powerful, ultrahigh performance object/relational persistence and query service for Java ...
Hibernate 2.1 Cache Adapter
Patched version of OSCache.java originally created by Mathias Bogaert. import java.util.Properties; import net.sf.hibernate.cache.Cache; import net.sf.hibernate.cache.CacheException; import net.sf.hibernate.cache.Timestamper; import net.sf.hibernate.util.PropertiesHelper; import net.sf.hibernate.util.StringHelper; import com.opensymphony.oscache.base.Config; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.base.NeedsRefreshException; import com.opensymphony.oscache.general.GeneralCacheAdministrator; / Adapter for the OSCache implementation ...
Hibernate 2.1 Cache Provider
Patched version of OSCacheProvider.java originally created by Mathias Bogaert. import java.util.Properties; import net.sf.hibernate.cache.Cache; import net.sf.hibernate.cache.CacheException; import net.sf.hibernate.cache.CacheProvider; import net.sf.hibernate.cache.Timestamper; import net.sf.hibernate.util.PropertiesHelper; import net.sf.hibernate.util.StringHelper; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.base.Config; / Support for OpenSymphony OSCache. This implementation assumes ...
Hibernate 3 Cache Adaptor
Patched version of OSCache.java for Hibernate 3 originally created by Mathias Bogaert. import java.util.Properties; import java.util.Map; import org.hibernate.util.PropertiesHelper; import org.hibernate.util.StringHelper; import org.hibernate.cache.; import com.opensymphony.oscache.base.Config; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.base.NeedsRefreshException; import com.opensymphony.oscache.general.GeneralCacheAdministrator; / Adapter for the OSCache implementation ...
Hibernate 3 Cache Provider
Patched version of OSCacheProvider.java for Hibernate 3.0 originally created by Mathias Bogaert. import java.util.Properties; import org.hibernate.util.PropertiesHelper; import org.hibernate.util.StringHelper; import org.hibernate.cache.; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.base.Config; / Support for OpenSymphony OSCache. This implementation assumes that identifiers have wellbehaved Home
Welcome to the OSCache wiki. OSCache is a caching solution that includes a JSP tag library and set of classes to perform fine grained dynamic caching of JSP content, servlet responses or arbitrary objects. It provides both in memory and persistent on disk caches, and can ...

I

Index
Installation Guide
installation guide shows you how to configure OSCache 2.4 for use inside your JSP pages. It assumes you have downloaded the latest version https://oscache.dev.java.net/servlets/ProjectDocumentList, which requires at least Java 1.4 and a Servlet 2.3 ...

J

JMX Monitoring
New in OSCache 2.4 is support for JMX monitoring and administration via the Spring Framework http://www.springframework.org. In oscache.properties, enable the statistic listener: cache.event.listeners= com.opensymphony.oscache.extra.StatisticListenerImpl Then add this to the Spring application context JSP Tags
OSCache comes with a JSP tag library that controls all its major functions. The tags are listed below with descriptions, attributes and examples of use. For instructions on installing OSCache in a web application, see the Installation Guide. You just have to add the following ...

K

L

License
All OpenSymphony projects use the OpenSymphony License, which is a modified Apache License. You can find the license at http://www.opensymphony.com/oscache/license.action

M

N

O

OSCache 1.0 beta 0
Release Notes (26th November, 2000 by Mike CannonBrookes, mike@atlassian.com) Initial release of OSCache Conceptualised a few things I've been working on over the past month. Added persistent on disk caching and error tolerance (through tag
OSCache 1.0 beta 1
Release Notes (20th February, 2001 by Mike CannonBrookes, mike@atlassian.com) Fixed a few bugs. Greatest of which there is no longer a disk leakage from session caches on disk. Also session caching bugs fixed, usecached bugs fixed lots of work ...
OSCache 1.0 beta 2
Release Notes (20th March, 2001 by Mike CannonBrookes, mike@atlassian.com) Fixed more bugs. Moved things around so that the CacheAdministrator has more functionality and is now a Singleton (per web app context). This means no more depedency on ServletContextListener to start ...
OSCache 1.1
Release Notes (25th March, 2001 by Mike CannonBrookes, mike@atlassian.com) Moved up to 1.1 because a lot of documentation improving and some small bug fixing has been done Javadocs should now be very readable for all classes and methods ...
OSCache 1.2
Release Notes (28th March, 2001 by Mike CannonBrookes, mike@atlassian.com) Fixed a large bug that resulted in CacheEntry's not refreshing. Large enough in a Caching library to demand a new point release
OSCache 1.2.1
Release Notes (10th May, 2001 by Mike CannonBrookes, mike@atlassian.com) Speed improvements in CacheEntry and CacheAdministrator (by Kesav Kumar kesavk@voquette.com) Fixed DOCTYPE in taglib.tld (also Kesav!) Removed backup / swap / temp files from zip (and changed build file
OSCache 1.2.5
Release Notes (18th May, 2001 by Mike CannonBrookes, mike@atlassian.com) Added ability to turn off file caching (just remove or comment out cache.properties) Removed a pesky (but ineffectual) bug where session caches being removed from disk ...
OSCache 1.3
Release Notes (9th June, 2001 by Mike CannonBrookes, mike@atlassian.com) Fixed a single bug in the file caching should now work Added property to set the cache key (not sure if this is useful) Cleaned up a lot of the code, refactored slightly so ...
OSCache 1.5
Release Notes (6th August, 2001 by Todd Gochenour, tgochenour@peregrine.com) Added boolean "cache.memory" attribute to oscache.properties to eliminate memory consumption and rely strictly on disk storage. Added three interfaces "CacheLog", "CacheProperties", and "CacheContents" to allow plugable implementations for these functions ...
OSCache 1.6
Release Notes (5th September, 2001 by Mike CannonBrookes, mike@atlassian.com) Changed the CacheEntry so that it caches Object rather than String (allowing image caching) (Serge Knystautas, sergek@lokitech.com) Cached objects are now serialized to disk so cannot be read ...
OSCache 1.6.1
Release Notes (16th September, 2001 by Todd Gochenour, tgochenour@peregrine.com) Removed attribute "encoding" in all areas, since Object serialization stores strings in UTF8 format, encoding is no longer necessary. Added Synchronization to getCacheEntry() to insure multiple threads do ...
OSCache 1.7.0
Release Notes (26th September 2001 by Francois Beauregard, fbeauregard@pyxistech.com, and Alain Bergevin, abergevin@pyxistech.com, of Pyxis Technologies Inc.) This version include some refactoring, corrections and new features. Here are the highlights: CacheAdministrator has been split in 3. We have ...
OSCache 1.7.1
Release Notes (26th September 2001 by Francois Beauregard, fbeauregard@pyxistech.com, and Alain Bergevin, abergevin@pyxistech.com, of Pyxis Technologies Inc.) Cache Events Persistence mechanism refactored Cache Algorithms FIFO LRU (Limit the size of the cache) AbstractConcurrentReadCache from Doug Lea's ...
OSCache 1.7.2
Release Notes (31st October 2001 by Mike CannonBrookes, mike@atlassian.com) Cleaned up all JavaDoc messages to ensure consistency and readability (removed unnecessary CVS tags, added and
 where needed, added @return and @param to all methods ... 
OSCache 1.7.3
Release Notes (11th November 2001 by Francois Beauregard, fbeauregard@pyxistech.com) TestCacheEntry had a test method with improper name (flush > testFlush) Pluggable entry refresh policy now available in the cache tag
OSCache 1.7.4
Release Notes (3rd December 2001 by Francois Beauregard, fbeauregard@pyxistech.com, and Mike CannonBrookes, mike@atlassian.com) Made all servlet cache components serializable (fixes bug reported on list with JRun
OSCache 1.7.5
Release Notes (5th January 2002 by Mike CannonBrookes, mike@atlassian.com) Fixed up logging system slightly. All errors should now be logged with logError() and normal messages with log() Fixed bug in build file which put oscache.properties inside ...
OSCache 2.0
Release Notes (22nd September 2003 by Chris Miller) Improvements: Minor FastCronParser speedup. Made ClusterNotification constants public. Dropped some of the logging levels from INFO down to DEBUG. Release has been split into two a binary release ...
OSCache 2.0 beta 1
Release Notes (19th July 2003 by Chris Miller) New Features: CACHE11 http://jira.opensymphony.com/browse/CACHE11 Cache grouping support. This allows cache entries to be placed into an arbitrary group or groups and flushed with a single flushGroup() call. CACHE30 http ...
OSCache 2.0 beta 2
Release Notes (4th August 2003 by Chris Miller) New Features: Now supports JavaGroups version 2.1. JMS Clustering support has been added Romulus Pasca. Clustering code has been refactored. As a result of this, some of the clustering ...
OSCache 2.0.1
Release Notes (4th November 2003 by Chris Miller) Improvements: CACHE56 http://jira.opensymphony.com/browse/CACHE56 Refresh period is no longer mandatory. CACHE51 http://jira.opensymphony.com/browse/CACHE51 Added an tag. This allows cache groups to be dynamically added ...
OSCache 2.0.2
Release Notes (22nd January 2004 by Mathias Bogaert) Improvements: Website documentation updates. Added OSCache in the Wild. Bug Fixes: CACHE63 http://jira.opensymphony.com/browse/CACHE63 NullPointerException in GeneralCacheAdministrator#destroy(). CACHE44 http://jira.opensymphony.com/browse/CACHE44 Multi threading issues ...
OSCache 2.1
Release Notes (18th January 2005 by Andres March) New Features: Added HashDiskPersistenceListner CACHE132 http://jira.opensymphony.com/browse/CACHE132 that hashes file names in order to eliminate nasty characters and overly long names Added property that allows cache entries ...
OSCache 2.1.1
Release Notes (1st May 2005 by Andres March) Improvements: The taglib URI was changed to {{http://www.opensymphony.com/oscache}} in CACHE61 http://jira.opensymphony.com/browse/CACHE61 The DiskPersistenceListener escapes '?' now and guarantees that the filenames will be unique based on the cache key, see CACHE110 http ...
OSCache 2.2
Release Notes Final (6th November 2005 by Lars Torunski) Additionally to the 2.2 RC OSCache 2.2 RC improvements, the final release was enhanced by: Allow cache group definition in CacheFilter Option to specify when to send ExpiresHeader Allow disabling ...
OSCache 2.2 RC
Release Notes Release Candidate (18th September 2005 by Lars Torunski) Besides bugs being fixed, major improvements have been made to the CacheFilter in many ways: Default initialization of the last modified header which reduces transaction overhead ...
OSCache 2.3
Release Notes (6th March 2006 by Lars Torunski) This release includes additional improvements to the CacheFilter: CRON expressions to expire content at specific dates and/or times Pluggable EntryRefreshPolicy Reduced memory consumption Disk persistence: Faster disk persistence Avoid ...
OSCache 2.3.1
Release Notes (19th June 2006 by Lars Torunski) This maintenance release of 2.3 has one enhancement: CacheFilter: Default initialization of the CacheControl maxage Bug fixes: Cache.flushAll(Date flushDate) won't throw NeedsRefreshException when flush date is not yet ...
OSCache 2.3.2
Release Notes (23rd July 2006 by Lars Torunski) This maintenance release of 2.3.1 has one enhancement: The removeEntry method in the Cache removes the entry from its groups now Bug fixes: Method addGroupMappings leads to inconsistent memory cache ...
OSCache 2.4
Release Notes (1st Mai 2007 by Lars Torunski) New features and enhancements Furthermore the next major release 2.4 enhances the CacheFilter and allows a better integration with the Spring Framework http://www.springframework.org/ and JMX Monitoring. Setting CacheFilter parameters runtime ...
OSCache 2.4.1
Release Notes (1st July 2007 by Lars Torunski) This maintenance release of 2.4.1 has two bug fixes: The cacheFlushed method is not being invoked on the CacheEntryEventListener CacheFilter maxage parameter MAXAGENOINIT not set properly JIRA Issue List
OSCache in the Wild
following are some of the sites that are using OSCache in production. This is far from an exhaustive list of course! If you have or know of a site using OSCache, please let us know so we can add it to the list. While not required, any ...

P

Q

R

Requirements
OSCache can be used directly to provide caching for any Java application. Using the OSCache tag library JSP Tags requires Servlet 2.3 and JSP 1.2 support (included in J2EE 1.3) to run properly. There is no dependency on a servlet container if the OSCache ...
Roadmap
Scope This page and the mailing list https://oscache.dev.java.net/servlets/ProjectMailingListList are provided for discussion purposes about the roadmap of OSCache and discussing new features and improvements. See also the JIRA Road Map http://jira.opensymphony.com/browse/CACHE?report=com.atlassian.jira.plugin.system.project:roadmappanel ...

S

Spring
Configuring a {{GeneralCacheAdministrator}} A GeneralCacheAdministrator API Usage instance that picks up configuration from an oscache.properties Configuration file can be configured within Spring using the following code: Notice that a {{destorymethod ...
Statistics
Description With the cache event handlers http://www.opensymphony.com/oscache/api/com/opensymphony/oscache/base/events/packagesummary.html a listerner can be implemented to provide cache hits and misses information. You can copy and paste the following code to get a statistic ...
SVN and Compiling OSCache
SVN The OSCache SVN repository is hosted at http://svn.opensymphony.com/svn/oscache. You can get the sources anonymously by using e.g. Subclipse http://subclipse.tigris.org a Subversion http://subversion.tigris.org Eclipse Plugin. If you want to build OSCache from SVN ...

T

U

V

W

What is OSCache
OSCache is a widely used, high performance J2EE caching framework. OSCache solves fundamental problems for dynamic websites: # Caching Dynamic Content Dynamic content of some form must often be executed during each request, but sometimes that content doesn't ...

X

Y

Z

!@#$

oscache-2.4.1.orig/docs/wiki/OSCache 1.2.1.html0000644000175000017500000000156410402251442020466 0ustar twernertwerner OSCache - OSCache 1.2.1

Release Notes

(10th May, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Speed improvements in CacheEntry and CacheAdministrator (by Kesav Kumar - kesavk@voquette.com)
  • Fixed DOCTYPE in taglib.tld (also Kesav!)
  • Removed backup / swap / temp files from zip (and changed build file)
oscache-2.4.1.orig/docs/wiki/OSCache 2.4.1.html0000644000175000017500000001510710643520716020501 0ustar twernertwerner OSCache - OSCache 2.4.1

Release Notes

(7th July 2007 - by Lars Torunski)

This maintenance release of 2.4.1 has two bug fixes:

  • The cacheFlushed method is not being invoked on the CacheEntryEventListener
  • CacheFilter max-age parameter MAX_AGE_NO_INIT not set properly

JIRA Issue List

OpenSymphony JIRA (3 issues)
T Key Summary Status
Bug CACHE-297 max-age parameter not set on ResponseContent object returned from cache when using MAX_AGE_NO_INIT ClosedClosed
Bug CACHE-296 For a Cache class the cacheFlushed method is not being invoked on the CacheEntryEventListener. ClosedClosed
Bug CACHE-279 LRUCache loses entries when updated by mutliple threads. ClosedClosed

oscache-2.4.1.orig/docs/wiki/OSCache 1.0 beta 2.html0000644000175000017500000000171410402251442021340 0ustar twernertwerner OSCache - OSCache 1.0 beta 2

Release Notes

(20th March, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Fixed more bugs.
  • Moved things around so that the CacheAdministrator has more functionality and is now a Singleton (per web app context). This means no more depedency on ServletContextListener to start the CacheAdministrator.
  • Therefore we are now Servlet 2.2 / JSP 1.1 compliant! w00!
oscache-2.4.1.orig/docs/wiki/OSCache 1.7.4.html0000644000175000017500000000144510402251442020474 0ustar twernertwerner OSCache - OSCache 1.7.4

Release Notes

(3rd December 2001 - by Francois Beauregard, fbeauregard@pyxis-tech.com, and
Mike Cannon-Brookes, mike@atlassian.com)

  • Made all servlet cache components serializable (fixes bug reported on list with JRun)
oscache-2.4.1.orig/docs/wiki/OSCache 2.0.html0000644000175000017500000000323610402251442020324 0ustar twernertwerner OSCache - OSCache 2.0

Release Notes

(22nd September 2003 - by Chris Miller)

Improvements:

  • Minor FastCronParser speedup.
  • Made ClusterNotification constants public.
  • Dropped some of the logging levels from INFO down to DEBUG.
  • Release has been split into two - a binary release and a full release (includes source).

Bug Fixes:

  • CACHE-52 Fixed a problem that caused no output on Tomcat for small JSP files.
  • CACHE-53 Updated documentation to explain that a PersistenceListener must be specified to enable caching to disk.
  • CACHE-55 JMS was throwing an exception on Weblogic.
  • Altering the cache capacity on the fly using the administrator classes wasn't working correctly.
oscache-2.4.1.orig/docs/wiki/OSCache 1.2.html0000644000175000017500000000160410402251442020322 0ustar twernertwerner OSCache - OSCache 1.2

Release Notes

(28th March, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Fixed a large bug that resulted in CacheEntry's not refreshing. Large enough in a Caching library to demand a new point release
oscache-2.4.1.orig/docs/wiki/OSCache 2.3.html0000644000175000017500000005163710615670675020362 0ustar twernertwerner OSCache - OSCache 2.3

Release Notes

(6th March 2006 - by Lars Torunski)

This release includes additional improvements to the CacheFilter:

  • CRON expressions to expire content at specific dates and/or times
  • Pluggable EntryRefreshPolicy
  • Reduced memory consumption

Disk persistence:

  • Faster disk persistence
  • Avoid DiskPersistenceListener deadlocks if process has no rights to delete cache file

Further changes are:

  • new JSP tag addgroups
  • interface to get a list of the cache event listeners
  • commons collection dependency removed
  • Java 1.3 support dropped

JIRA Issue List

OpenSymphony JIRA (14 issues)
T Key Summary Status
Improvement CACHE-235 Pluggable EntryRefreshPolicy for CacheFilter ClosedClosed
Task CACHE-230 CacheFilter Tutorial ClosedClosed
Bug CACHE-229 Tomcat 5.5.12 throws IllegalStateException on getId() / fixed Servlet Spec 2.4 ClosedClosed
New Feature CACHE-228 Add CRON expressions to CacheFilter to expire content at specific dates and/or times. ClosedClosed
Task CACHE-227 Remove commons collections from distribution ClosedClosed
Task CACHE-226 Drop Java 1.3 support ClosedClosed
New Feature CACHE-222 Add new JSP tag addGroups ClosedClosed
Improvement CACHE-217 Avoid DiskPersistenceListener deadlocks if process has no rights to delete cache file ClosedClosed
Task CACHE-216 Review CacheFilter against Servlet 2.4 spec. ClosedClosed
Improvement CACHE-214 Reduce memory consumption of ResponseContent ClosedClosed
New Feature CACHE-200 add 'getCacheEventListenerList()' to Cache class ClosedClosed
Improvement CACHE-197 Speed up disk persistence ClosedClosed
Bug CACHE-183 HashDiskPersistenceListener / MessageDigest not thread safe ClosedClosed
Task CACHE-136 SequencedHashMap is deprecated in commons collections 3.1 ClosedClosed

oscache-2.4.1.orig/docs/wiki/Hibernate.html0000644000175000017500000001315510641651526020515 0ustar twernertwerner OSCache - Hibernate

Hibernate is a powerful, ultra-high performance object/relational persistence and query service for Java. Hibernate lets you develop persistent objects following common Java idiom - including association, inheritance, polymorphism, composition and the Java collections framework. Extremely fine-grained, richly typed object models are possible.

Hibernate 3.2 features support for plugin cache providers and is designed to integrate with distributed caches (3.2 also implements more aggressive use of the cache). net.sf.hibernate.cache.CacheProvider is the extension point for user-defined cache integration.

Hibernate Core 3.2.3 GA or higher is required.

Warning

Unfortunately, at this time the OSCacheProvider distributed with Hibernate 3.2 is not suited to clustering with OSCache. A patch has been submitted to the Hibernate team but not yet applied. Even if you do not require clustering, we recommend use of OSCacheProvider and OSCache for Hibernate 3.2 delivered by OSCache 2.4 and higher. The OSCache only allows a single cache.capacity setting and saves memory.

hibernate.cache.provider_class

OSCache and Hibernate 3.2 integrate though OSCacheProvider.

Clustering

The clustered cache invalidation only works for entity updates when usage="nonstrict-read-write".

To enable OSCache for Hibernate's second level cache add the following line to Hibernate's configuration e.g. hibernate.cfg.xml:

hibernate.cfg.xml
<property name="hibernate.cache.provider_class">com.opensymphony.oscache.hibernate.OSCacheProvider</property>

The default refresh period is CacheEntry.INDEFINITE_EXPIRY. The first time a cacheable query is done, the cache has no effect on speed. On the second and successive queries, the cache will be populated and available to be hit.

Object Identifiers

Object identifiers must have well-behaved toString() methods, because OSCache uses the toString() method for the key of the cache. Therefore it needs to create a unique identifier for the object being stored.

Cache Region Configuration

To modify the refresh period, CRON expression, add the region configuration to your oscache.properties file, as demonstrated below:

[region].refresh.period = 4000
[region].cron = * * 31 Feb *

The com.mypackage.domain.Customer is Hibernate's internal cache region, which defaults to the classname, and which can be altered by setting Hibernate's configuration property hibernate.cache.region_prefix .

Configure a different configuration file for Hibernate

To configure a different configuration file use the following parameter in the Hibernate's configuration:

hibernate.cfg.xml
<property name="com.opensymphony.oscache.configurationResourceName">path to oscache-hibernate.properties</property>
oscache-2.4.1.orig/docs/wiki/Hibernate 3 Cache Provider.html0000644000175000017500000001063210315621364023367 0ustar twernertwerner OSCache - Hibernate 3 Cache Provider

Patched version of OSCacheProvider.java for Hibernate 3.0 - originally created by Mathias Bogaert.

OSCacheProvider.java
import java.util.Properties;
import org.hibernate.util.PropertiesHelper;
import org.hibernate.util.StringHelper;
import org.hibernate.cache.*;
import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.Config;

/**
 * Support for OpenSymphony OSCache. This implementation assumes
 * that identifiers have well-behaved <tt>toString()</tt> methods.
 */
public class OSCacheProvider implements CacheProvider {

	/** 
	 * The <tt>OSCache</tt> refresh period property suffix. 
	 */
	public static final String OSCACHE_REFRESH_PERIOD = "refresh.period";
	/** 
	 * The <tt>OSCache</tt> CRON expression property suffix. 
	 */
	public static final String OSCACHE_CRON = "cron";
	
	private static final Properties OSCACHE_PROPERTIES = new Config().getProperties();

	/**
	 * Builds a new {@link Cache} instance, and gets it's properties from the OSCache {@link Config}
	 * which reads the properties file (<code>oscache.properties</code>) from the classpath.
	 * If the file cannot be found or loaded, an the defaults are used.
	 *
	 * @param region
	 * @param properties
	 * @return
	 * @throws CacheException
	 */
	public Cache buildCache(String region, Properties properties) throws CacheException {

		int refreshPeriod = PropertiesHelper.getInt(
			StringHelper.qualify(region, OSCACHE_REFRESH_PERIOD), 
			OSCACHE_PROPERTIES, 
			CacheEntry.INDEFINITE_EXPIRY
		);
		String cron = OSCACHE_PROPERTIES.getProperty( StringHelper.qualify(region, OSCACHE_CRON) );

		// construct the cache        
        return new OSCache(refreshPeriod, cron, region);
	}

	public long nextTimestamp() {
		return Timestamper.next();
	}

	public boolean isMinimalPutsEnabledByDefault() {
		return false;
	}

	/**
	 * Callback to perform any necessary cleanup of the underlying cache implementation
	 * during SessionFactory.close().
	 */
	public void stop() {
	}

	/**
	 * Callback to perform any necessary initialization of the underlying cache implementation
	 * during SessionFactory construction.
	 *
	 * @param properties current configuration settings.
	 */
	public void start(Properties properties) throws CacheException {
	}    
}
oscache-2.4.1.orig/docs/wiki/OSCache 1.6.1.html0000644000175000017500000000273510402251442020473 0ustar twernertwerner OSCache - OSCache 1.6.1

Release Notes

(16th September, 2001 - by Todd Gochenour, tgochenour@peregrine.com)

  • Removed attribute "encoding" in all areas, since Object serialization stores strings in UTF-8 format, encoding is no longer necessary.
  • Added Synchronization to getCacheEntry() to insure multiple threads do not access HashMap and get erroneous results.
  • Implemented property cache.useHostDomainInKey (true/false) to prepend URL request server name to cache key when cache used by multiple servers. The "cache.domainname" property found in oscache.properties (not used in code) was removed.
  • Corrected file caching logic so that multiple processes can share cache information (file locking). Missing still is the ability to signal processes that a cache needs to be flushed when using Memory Caching along with File Caching.
  • Unit testing revealed some minor configuration bugs which were corrected.
oscache-2.4.1.orig/docs/wiki/Spring.html0000644000175000017500000001103210615666742020055 0ustar twernertwerner OSCache - Spring

Configuring a GeneralCacheAdministrator

A GeneralCacheAdministrator instance that picks up configuration from an oscache.properties file can be configured within Spring using the following code:

<bean id="cacheAdministrator" class="com.opensymphony.oscache.general.GeneralCacheAdministrator" destroy-method="destroy"/>

Notice that a destory-method is configured to ensure that the GeneralCacheAdministrator is closed down gracefully.

If you'd prefer to keep all your configuration inside the Spring configuration, you can omit the oscache.properties file and pass in any properties you want to the GeneralCacheAdministrator constructor like so:

<bean id="cacheAdministrator" class="com.opensymphony.oscache.general.GeneralCacheAdministrator" destroy-method="destroy">
    <constructor-arg index="0">
        <props>
            <prop key="cache.memory">true</prop>
        </props>
    </constructor-arg>
</bean>

Configuring a Cache

You can configure a Cache instance directly using the following snippet of code:

<bean id="cache" class="com.opensymphony.oscache.base.Cache">
    <constructor-arg index="0">
        <value>true</value> <!-- useMemoryCaching -->
    <constructor-arg>
    <constructor-arg index="1">
        <value>true</value> <!-- unlimitedDiskCache -->
    <constructor-arg>
    <constructor-arg index="2">
        <value>true</value> <!-- overflowPersistence -->
    <constructor-arg>
</bean>

Alternatively, you can pick up the Cache from the GeneralCacheAdministrator like so:

<bean id="cacheAdministrator" class="com.opensymphony.oscache.general.GeneralCacheAdministrator" destroy-method="destroy"/>

<bean id="cache" factory-bean="cacheAdministrator" factory-method="getCache"/>
oscache-2.4.1.orig/docs/wiki/Chain Caching Model.html0000644000175000017500000002453310615670675022205 0ustar twernertwerner OSCache - Chain Caching Model

Discussion

Lars wrote:
Would it be possible to use the intercepting filter pattern to support all possible cache models with a lot of combination capabilities? It's possible to define the capacity for each cache etc.

DiskPersistence, SoftReferenceCache etc. would implement the Command interface of Commons Chain or a new interface of OSCache.

http://jakarta.apache.org/commons/chain/
http://java.sun.com/blueprints/corej2eepatterns/Patterns/InterceptingFilter.html

Andres wrote:
I think that is a good idea but it may be overkill for the most use cases. Also, not every cache interceptor could have all the capabilities. In particular, how would you imagine a realistic use case for a cache.get() call. Should multiple interceptors return values?

I think disk persistence is still in, although I don't think it will be like it is now. We will be accepting Object keys, so any cache impl will need to accept them. I have been thinking about a lightweight object db that has persistence built-in but I'm not sure.

This is definitely an interesting topic and I'd like to discuss it more.
Now is the time to make these sort of decisions.

Lars wrote:
The cache interceptors are cascaded. If the first interceptor doesn't return a value then the 2nd interceptor will be requested.

Andres wrote:
The scenarios below basically describe a more flexible implementation of the 2 cache (memory and disk) architecture in place.  There is no doubt that a chained design can be better.  I would be mindful of the abuse that can occur with a inifinitely flexible system.  I prefer though to allow people to shoot themselves in the foot but make it extremely easy not to do so by providing very simple out of the box implementations.  I have attached a simple sequence diagram.  I think further documenting the scenarios you have below as well as all the other use cases we intend to provide is the best course of action at this point.  All the old code has been torn out.  We are at the point where we should be conscious of the new design that we allow to take shape.

Lars wrote:
The interface needed for the Cache Link (which you describe in a simple sequence diagram) is exactly the same interface as the EvictionAlgorithm. The Cache Chain has to handle in which Cache Link a cache content should be. Furthermore the Cache Chain has to put an evicted cache content from the memory cache to the disk cache.

1.) How do you want to synchronize the access to the same cache content? In OSCache 2 this is done by the EntryUpdateState based on the key.
2.) Should the Cache Chain contain all the cache keys without knowing in which Cache Link the content is? Or should each Cache Link contain it's own cache keys?

Some other points:
3.) Please update the java doc of EvictionAlgorithm, because some parameters are wrong.
4.) currently you synchronize the cache events, I think there maybe a performance loss, because in my environments a lot of events are fired

I added a simple class diagramm and saved the diagramm in the Fujaba format.

Andres wrote:

The cache chain should have no knowledge of what is in any of the cache links. However, the issue of eviction is clear. When a put() is called, the link should return an evicted entry or null if the cache is not full. The chain will then know if it needs to continue the put into the next link. To clarify the interfaces, I think a Chain interface should extend Map. The Link and EvictionAlgorithm should themselves be interfaces. Link could have implementations such as memory, disk, database. EvictionAlgorithm could have implementations such as LRU, FIFO, etc....

1.) In my branch, I have synchronized the entire cache on each cache access. I think this will still be fast enough and will surely be more stable. basically, get, put, and remove are sync'd. I do not think we need to achieve a highly concurrent cache in order to provide a solution that is hundreds of times faster than db or disk access.

However, we could add functionality the improves performance but does not cause deadlocks, such as a write behind feature on puts, so that puts get queued and another thread does the work when it has time.

2.) I don't think this would be wise. I don't think the chain should have knowledge of the keys. I think all it should have is references to the links and stateless logic. Either way each link would need to keep its own keys, therefore putting them in the chain would add another map that would have to be accessed and slow performance.

There are 3 places I believe the keys must exist: in the store (duh), in the algorithm (or we could generalize this as any metrics collector), and in the groups map.

Group functionality is a similar issue. I had wanted to drop this functionality but it seems the people that use cache tags (I never have yet) really depend on them. This functionality is unique to OSCache as far as I am aware.
Maintaining the groups in each link could kill performance. I think we need a GroupManager that exists outside of the cache links and is referenced from the chain. This way it is only called once per chain. One disadvantage would be that when a group is removed each remove would have to be called on each link until it found the correct store.

3./4.) Yeah, that is sort of borrowed code and is not necessary. However, we need to be mindful of the access to the listener list. The easiest way is to probably make the list implementation a SynchronizedArrayList or something.

The way I am thinking the current code in my branch could be moved over to a chain model is:

  1. most of the BaseCache code gets put into the chain minus the algorithm and group map code.
  2. the MemoryCache gets turned into one of the link implementations and gets the algorithm reference
  3. the group map code gets refactored into a GroupManager and called from the chain.

Lars wrote:
I think the implementations of the CacheChain interface could be a SimplePipeCacheChain and a SizeBasedCacheChain. The SimplePipeCacheChain is comparable to the current architectur. The SizeBasesCacheChain puts the cache objects to the different CacheLinks based on the cache content sizes, e.g. large images a stored to disk and not in memory.

The default CacheChain should be the SimplePipeCacheChain. The SizeBasedCacheChain can be implemented as part of a 3.1 release.

Scenarios to be checked and tested

Configuration with a LRU algorithm: (1) MemoryCache -> (2) SoftRefCache -> (3) DiskPersistCache

Scenario A: Get for a object in SoftRefCache

  1. the cache object x1 is in the SoftRefCache
  2. the 1st getEntry will return null for the MemoryCache
  3. the 2nd getEntry will find the cache object x1 in SoftRefCache
  4. cache object x1 has to be removed from the SoftRefCache and has to put into the 1st cache (or maybe in the previous cache <- design decission).
  5. the cache object x1 will edge out the cache object xi (LRU) from the MemoryCache and the cache object xi has to me removed from the MemoryCache and to put in the next cache (SoftRefCache).

Scenario B: Get for a object in DiskPersistCache

  1. the cache object x2 is in the DiskPersistCache
  2. the 1st getEntry will return null for the MemoryCache
  3. the 2nd getEntry will return null for the SoftRefCache
  4. the 3rd getEntry will find the cache object x2 in DiskPersistCache
  5. cache object x2 has to be removed from the DiskPersistCache and has to put into the 1st cache. The cache object x2 will edge out xj in MemoryCache, which has to be put in SoftRefCache. Hence xj will edge out xk in SoftRefCache, which has to be put in DiskPersistCache

Scenario C: Put a new object

  1. the new cache object x3 should be put into the cache
  2. the cache object x3 will be edge out a cache object xa from MemoryCache
  3. xa has to be put into SoftRefCache, where xa will edge out xb
  4. xb has to be put in DiskPersistCache, where xb will edge out xc
  5. until DiskPersistCache is not unlimited the xc cache object has to be removed from cache. Hence the cache key for xc has to be removed from the map.

Scenario D: Put a stale object or get a stale object

TODO

oscache-2.4.1.orig/docs/wiki/Feature List.html0000644000175000017500000002306510615670431021101 0ustar twernertwerner OSCache - Feature List

OSCache Features

Fast in-memory caching

  • OSCache allows you to store dynamic content (eg for 30 minutes) in memory. Each further request is served directly from the memory cache, resulting in dramatic speed increases.
  • The cache is keyed programmatically. This means you can calculate a cache key that works for your situation. For example an ecommerce site might use product ID as keys, or content site might use an article date and article ID combination.
  • The cache is stored in standard scopes that any JSP programmer is familiar with (application or session). The session scope allows you to have different cached content per user. This is one unlike any other caching system we've ever seen.

Persistent on-disk caching

  • OSCache can also write the cache to disk. This provides caching across server restarts, and caching of datasets that do not fit into memory. Caching can be configured to use memory or file caching, or a combination of both.
  • If you want to persist the cache to somewhere other than disk, you can plug in a custom PersistenceListener. This allows you to persist the cache to anywhere (for example to a database via JDBC or to LDAP via JNDI).
  • When using both disk caching and memory caching. It is possible to limit the cache size to avoid using too much memory but let disk cache unlimited, resulting in browser style complementary disk cache. When cached objects are removed from memory, they are still on disk. If the item is needed again and it is not expired the cache file will be used. This also gives fault tolerance if the server crashes.
  • Persistence can also be switched to overflow mode using the property oscache.persistence.overflow.only. This changes the default behavior (of persisting every cache entry when there is a listener) to only persist when the memory cache capacity has been reached.

Excellent Performance

  • Written with performance in mind.
  • Mulitple cache requests can be handled concurrently.
  • Only one requesting thread needs to update an expired cache entry even if multiple threads are requesting it simultaneously. Other threads can be configured to either receive the recently-expired object, or block until the cached object is updated. Similarly, when a new entry is being added to the cache, other threads requesting that entry will block until it is ready rather than run off and race to build the same object. In a high load environment this can provide enormous performance benefits.
  • Automatically takes advantage of JRE 1.4 or higher if available.

Clustering support

  • OSCache can easily be configured to cluster across multiple boxes. This provides both scalability and failover support without any changes required in your caching code.

Flexible Caching System

  • OSCache allows you to cache portions of JSP pages, arbitrary Java objects, and even entire servlet responses.
  • Cache capacity can be set allowing you to limit the number of cached objects.
  • Multiple caching algorithms are supported such as LRU (Least Recently Used), FIFO (First In First Out), or unlimited. It is also possible to plug in your own custom algorithm.
  • You are given a huge amount of control over the way cached objects expire. Objects can be cached indefinitely, expired once they reach a certain age, or expired based on a cron expression. Programmatic flushing is also possible, and if that is still not enough pluggable RefreshPolicies allow custom refresh strategies.
  • Cached objects can be grouped together however you like, allowing for powerful management of cached data. This is an extremely useful feature that is far more powerful than what other caching solutions typically offer (such as the flushing of cache keys that match a particular pattern).
  • Fully event driven! OSCache fires events for various happenings 'under the hood' such as cache entry events (adding, updating, flushing and removing) and cache accesses (hit, stale hit and miss). It is easy to add your own event handlers.
  • Multiple caches can be created, each with their own unique configuration.

Simple JSP Tag Library

  • The tag library to perform and control the caching is very simple. See the Tag Reference for more information.

Caching Filter

  • A Servlet 2.3 Filter allows for caching of entire pages and generated binary files (like dynamically created images or PDF files).
  • Caching of binary files is extremely useful when they are generated dynamically and the average creation time is long.
  • The CacheFilter is using the last modified header to reduce excellently the transaction overhead and server load which speed ups the server response time.

Comprehensive API

  • For the ultimate control, OSCache can be used through its straightforward API. You can instantiate, configure and control multiple caches programmatically. It would be possible for example to create one small in-memory cache that held currency conversion rates and was updated daily at 2am, while another cache could be purely disk based and used for holding dynamically created images.

Exception Handling

  • OSCache provides a way for your site to gracefully tolerate errors. This is not error prevention, rather if an error occurs it should not stop your site from functioning. For example if your database goes down, normally your product descriptions will not be browsable. Using OSCache you can cache those descriptions so you can still browse them.

Cache Flushing

  • Flushing of caches can be controlled via JSP Tags, so these functions can easily be built into your administration interface.
  • There is programmatic control over what caches are flushed (eg all caches or just a particular scope).
  • Cached objects can be expired in a number of ways. Objects can be told to expire once they reach a certain age, or, through the use of cron expressions, on particular dates and/or times (eg it is trivial to make an object expire every weekday at 3am). If this is not enough, you can expire objects programmatically as required, or plug in your own custom RefreshPolicy class that can dynamically decide when an object should be flushed.
  • Entire groups of objects can be easily flushed from the cache. For example suppose you were caching product data as well as entire pages of your website. When a product was updated, you could flush not just the product object but also all the pages that contain information about that product. No more waiting for the cached objects to expire before the updated content shows up on your site!

Portable caching

  • Pure Java, this means it is platform independent.
  • OSCache is compliant with Servlet 2.3 and JSP 1.2 standards, which means it should work in the latest generation of servlet containers and application servers.

i18n Aware

  • The caching is i18n aware and supports all encodings.

Solid Reputation

  • Thousands of downloads, hundreds of users on the mailing list.
  • Comprehensive JUnit test suite that covers every aspect of OSCache, including a web stress test and various concurrent cache access scenarios. To back this up, the kind folks at Cortex have supplied us with a Clover license to provide detailed code coverage analysis of our unit tests.
  • We have solid issue tracking using JIRA to keep track of any feature requests, bug reports and development progress. JIRA is provided courtesy of Atlassian.
oscache-2.4.1.orig/docs/wiki/OSCache 1.1.html0000644000175000017500000000206110402251442020317 0ustar twernertwerner OSCache - OSCache 1.1

Release Notes

(25th March, 2001 - by Mike Cannon-Brookes, mike@atlassian.com)

  • Moved up to 1.1 because a lot of documentation improving and some small bug fixing has been done
  • Javadocs should now be very readable for all classes and methods
  • Fixed a NullPointer that was being thrown in CacheEntry.needsRefresh()
  • Cleaned up the build file so it now produces releasable zip files easily
  • Added servlet.jar so that the compiling now works OOB (Out Of the Box)
oscache-2.4.1.orig/docs/wiki/Configuration.html0000644000175000017500000002433410615670675021433 0ustar twernertwerner OSCache - Configuration

This guide only covers the configuration of OSCache by using the oscache.properties file. To see how to install OSCache and where to place the oscache.properties file, see the Installation Guide.
The following properties are able to be set in the oscache.properties file:

cache.memory

Valid values are true or false, with true being the default value. If you want to disable memory caching, just comment out or remove this line.

Note: disabling memory AND disk caching is possible but fairly stupid

cache.capacity

The maximum number of items that a cache will hold. By default the capacity is unlimited - the cache will never remove any items. Negative values will also be treated as meaning unlimited capacity.

cache.algorithm

The default cache algorithm to use. Note that in order to use an algorithm the cache size must also be specified. If the cache size is not specified, the cache algorithm will be Unlimited cache regardless of the value of this property. If you specify a size but not an algorithm, the cache algorithm used will be com.opensymphony.oscache.base.algorithm.LRUCache.

OSCache currently comes with three algorithms:

  • com.opensymphony.oscache.base.algorithm.LRUCache - Least Recently Used. This is the default when a cache.capacity is set.
  • com.opensymphony.oscache.base.algorithm.FIFOCache - First In First Out.
  • com.opensymphony.oscache.base.algorithm.UnlimitedCache - Content that is added to the cache will never be discarded. This is the default when no value is set for the cache.capacity property.

cache.blocking

When a request is made for a stale cache entry, it is possible that another thread is already in the process of rebuilding that entry. This setting specifies how OSCache handles the subsequent 'non-building' threads. The default behaviour (cache.blocking=false) is to serve the old content to subsequent threads until the cache entry has been updated. This provides the best performance (at the cost of serving slightly stale data). When blocking is enabled, threads will instead block until the new cache entry is ready to be served. Once the new entry is put in the cache the blocked threads will be restarted and given the new entry.

Note that even if blocking is disabled, when there is no stale data available to be served threads will block until the data is added to the cache by the thread that is responsible for building the data.

cache.unlimited.disk

Indicates whether the disk cache should be treated as unlimited or not. The default value is false. In this case, the disk cache capacity will be equal to the memory cache capacity set by cache.capacity.

cache.persistence.class

Specifies the class to use for persisting cache entries. This class must implement the PersistenceListener interface. OSCache comes with an implementation that provides filesystem based persistence. Set this property to com.opensymphony.oscache.plugins.diskpersistence.HashDiskPersistenceListener to enable this implementation. By specifying your own class here you should be able to persist cache data using say JDBC or LDAP. NOTE: This class hashes the toString() of the object being cached to produce the file name of the entry. If you prefer readable file names, the parent DiskPersistenceListener can still be used but it will have issues with illegal filesystem characters or long names.

Note

The HashDiskPersistenceListener and DiskPersistenceListener classes require cache.path to be set in order to know where to persist the files to disk.

cache.path

This specifies the directory on disk where the caches will be stored. The directory will be created if it doesn't already exist, but remember that OSCache must have permission to write to this location. Avoid sharing the same cache path between different caches, because OSCache has not been designed to handle this.

Note

For Windows machines, the backslash character '\' needs to be escaped. ie in Windows:

    cache.path=c:\\myapp\\cache
    or *ix:
    cache.path=/opt/myapp/cache

cache.persistence.overflow.only (NEW! Since 2.1)

Indicates whether the persistence should only happen once the memory cache capacity has been reached. The default value is false for backwards compatibility but the recommended value is true when the memory cache is enabled. This property drastically changes the behavior of the cache in that the persisted cache will now be different then what is in memory.

cache.event.listeners

This takes a comma-delimited list of fully-qualified class names. Each class in the list must implement one (or more) of the following interfaces:

  • CacheEntryEventListener - Receives cache add/update/flush and remove events.
  • CacheMapAccessEventListener - Receives cache access events. This allows you to keep statistical information to track how effectively the cache is working.

No listeners are configured by default, however some ship with OSCache that you may wish to enable:

  • com.opensymphony.oscache.plugins.clustersupport.BroadcastingCacheEventListener - provides clustering support for OSCache. Enabling this will cause cache flush events to be broadcast to other instances of OSCache running on your LAN. See Clustering OSCache for further information about this event listener.
  • com.opensymphony.oscache.extra.CacheEntryEventListenerImpl - a simple listener implementation that maintains a running count of all of the entry events that occur during a cache's lifetime.
  • com.opensymphony.oscache.extra.CacheMapAccessEventListenerImpl - a simple listener implementation that keeps count of all the cache map events (cache hits and misses, and stale hits) that occur on a cache instance.

It is also of course quite straightforward to write your own event listener. See the JavaDoc API for further details and Statistics for an example.

cache.key

This is the key that will be used by the ServletCacheAdministrator (and hence the custom tags) to store the cache object in the application and session scope. The default value when this property is not specified is "__oscache_cache". If you want to access this default value in your code, it is available as com.opensymphony.oscache.web.ServletCacheAdministrator.DEFAULT_CACHE_KEY.

cache.use.host.domain.in.key

If your server is configured with multiple hosts, you may wish to add host name information to automatically generated cache keys. If so, set this property to true. The default value is false.

Additional Properties

In additon to the above basic options, any other properties that are specified in this file will still be loaded and can be made available to your event handlers. For example, the JavaGroupsBroadcastingListener supports the following additional properties:

cache.cluster.multicast.ip

The multicast IP to use for this cache cluster. Defaults to 231.12.21.132.

cache.cluster.properties

Specifies additional configuration options for the clustering. The default setting is

UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;\
mcast_send_buf_size=150000;mcast_recv_buf_size=80000):\
PING(timeout=2000;num_initial_members=3):\
MERGE2(min_interval=5000;max_interval=10000):\
FD_SOCK:VERIFY_SUSPECT(timeout=1500):\
pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):\
UNICAST(timeout=300,600,1200,2400):\
pbcast.STABLE(desired_avg_gossip=20000):\
FRAG(frag_size=8096;down_thread=false;up_thread=false):\
pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)

See the Clustering OSCache documentation for further details on the above two properties.

oscache-2.4.1.orig/docs/wiki/OSCache 2.0 beta 1.html0000644000175000017500000002612210615670144021352 0ustar twernertwerner OSCache - OSCache 2.0 beta 1

Release Notes

(19th July 2003 - by Chris Miller)

New Features:

  • CACHE-11 Cache grouping support. This allows cache entries to be placed into an arbitrary group or groups and flushed with a single flushGroup() call.
  • CACHE-30 Added support for expiring cache entries based on a cron expression. Entries that are older than the date/time that most recently matches the cron expression will be considered stale. This is exposed to the cache tag via the 'cron' attribute. See cronTest.jsp for examples.
  • Event listener support has been refactored and improved. It is now possible to specify a comma-delimited list of event listeners using this property. Previously only one class could be specified. Events listed here should implement the CacheEntryEventListener and/or the ScopeEventListener interfaces.
  • New event CacheMapAccessEvent.STALE_HIT. This event is fired when an attempt is made to retrieve and entry from the cache, and the entry is found but is stale.
  • Clustering support has been added as an event listener. Currently it is implemented using JavaGroups . To enable, just add the BroadcastingCacheEventListener class to the cache.event.listeners property.
  • Now uses Jakarta Commons Logging for all log messages. This means that the cache.debug configuration property is now ignored - use whatever logging configuration is appropriate for your logging setup instead. -Fabian Crabus
  • CACHE-14, Matthias Nott Now allows for content to be cached indefinitely without expiration.
  • The build.xml <javac ...> directives now specify debug="true".
  • Performance boost: When OSCache is running on JRE 1.4 or higher, LRUCache and FIFOCache use a LinkedHashSet instead of a LinkedList.
  • Japloy is now used to ensure source is consistently formatted.
  • Test cases now work on non-windows platforms. Also coverage reports added courtesy of clover.

Changes that may affect backwards compatibility:

  • The cache.entryevent.classes property in the configuration file has been renamed to cache.event.listeners, since it accepts CacheEntryEventListener, ScopeEventListener and CacheMapAccessEventListener types.
  • The cache.persistence.classes property has been renamed to cache.persistence.class since it is only possible to specify one PersistenceListener.
  • For consistency, cache.unlimited_disk is now cache.unlimited.disk and cache.useHostDomainInKey is now cache.use.host.domain.in.key.
  • The oscache.tld file now uses a taglib 1.2 DTD.
  • To build OSCache, JDK 1.4.x or higher is required. There is however no runtime dependency on JDK 1.4.x.
  • The Cache.flushPattern() method and <cache:flush pattern="..."/> are deprecated. You are instead encouraged to group your cache entries when you add them to the cache and then use the Cache.flushGroup() method or the <cache:flush group="..."/> tag to flush an entire cache group.
  • Disk persistence now puts all files in the same directory. This has a number of side effects. Keys >255 chars will cause problems. Also, similar keys might get mapped to the same file. For example, it is very inadvisable to have two keys with the names 'my_key' and 'my.key'.
  • GeneralCacheAdministrator is no longer static. Users that relied on this behaviour can still hold onto a static reference to it with minor code changes.
  • When a NeedsRefreshException is thrown, it is now vital that the cache entry is either updated, or Cache.cancelUpdate(key) is called to release the lock on this cache entry. This is a consequence of the fix for CACHE-42 .
  • CacheProperties class was removed. It didn't work on 1.7.5 anyway. The same effect can be achieved by specifying a subclass of Properties.
  • Autogenerated cache keys now contain the request method (eg, HEAD, GET, etc).
  • OSCache has been repackaged from "com.opensymphony.module.oscache.*" to "com.opensymphony.oscache.*". Any code or configuration files that refer to "com.opensymphony.module.oscache" will need to be updated.

Bug Fixes:

  • CACHE-4 WebSphere 3.5.x compatibility.
  • CACHE-5 Added a mode attribute to the cache tag to allow content to be cached but not sent to the output stream. See oscacheTest.jsp for an example.
  • CACHE-7 "cache" Tag has no "setEncoding" method.
  • CACHE-9 It could be useful being able to specify directories relative to the web application dir. for config file and cache dir. Use new properties aware getInstance method.
  • CACHE-10 Cannot write and use custom class implementing CacheProperties.
  • CACHE-13 AbstractConcurrentReadCache loops indefinitely when persistRetrieve() returns null.
  • CACHE-14 You can now specify an unlimited refresh time by supplying a negative value for the duration.
  • CACHE-17 An example war is now included - "ant example-war". Once deployed this can be tested using "ant test-web".
  • CACHE-26 Security hole whereby certain keys can overwrite any file.
  • CACHE-28 URLs can now be used as keys with disk persistence.
  • CACHE-31 and CACHE-33 The cache tag's refresh attribute will now be taken into account even if a custom refresh policy has been specified.
  • CACHE-34 Setting properties with AbstractCacheAdministrators. New getInstance method added to ServletCacheAdministrator that takes in properties.
  • CACHE-35 CacheFilter needs to distinguish between HEAD and GET requests.
  • CACHE-39 and CACHE-44 Synchronization with LRUCache fixed.
  • CACHE-42 Threads will no longer race to (re)build expired or new cache entries. By default stale content will be served if available. This behaviour can be changed by setting oscache.blocking=true, which will instead cause threads to block until the new cache entry is available.
  • CACHE-43 Taglibs have been made spec-compliant. They now follow the guidelines at http://jakarta.apache.org/taglibs/guidelines.html.
  • Some synchronization issues were fixed in LRUCache.getItem() and AbstractConcurrentReadCache.setMaxEntries().
  • ScopeEventListener classes were previously not able to be specified in the configuration even though the dispatching code was implemented. ScopeEventListeners can now be specified using the cache.event.listeners configuration property.
  • CacheMapAccessEvents now only fire when an attempt is made to retrieve the actual cache content for external use. Previously these events were being fired in circumstances that were not of statistical interest - for example HIT and MISS events were being fired when updating or flushing entries from the cache.
  • Minor bug in oscacheTestMultipleTagNoKey.jsp - some of the tag refresh times weren't correctly specified.
  • cachetest.jsp - the 'refresh' functionality wasn't working because the addition of the refresh parameter caused the cache key to be different. The key is now specified explicitly.
  • EntryRefreshPolicy is now serializable so it can be persisted to the disk cache.
  • ServletCacheAdministrator now sorts request parameters and filters out jsessionid so they have no impact on the generated cache key.
  • CacheFilter only caches successful responses (status code == SC_OK).

Known Problems: (these have existed for some time in the 1.x.x versions and will be addressed in an upcoming 2.x.x release)

  • Session caches (created using the ServletCacheAdministrator) have some known limitations:
    o Due to a workaround in the code, it is possible for a system under heavy load to get its persistent session caches confused across sessions.
    o Session caches will not work in a clustered environment.
    o Session caches have the same settings global settings applied to them as the application scope cache. This means that if you want a persistent cache for the application scope cache, the session caches will use it too.
oscache-2.4.1.orig/docs/wiki/OSCache 2.2 RC.html0000644000175000017500000007605210615670431020632 0ustar twernertwerner OSCache - OSCache 2.2 RC

Release Notes - Release Candidate

(18th September 2005 - by Lars Torunski)

Besides bugs being fixed, major improvements have been made to the CacheFilter in many ways:

  • Default initialization of the last modified header which reduces transaction overhead and server load
  • Support of GZip filters in the filter chain
  • Custom key generation by subclassing CacheFilter or by implementing a special interface
  • Preserving more http headers, e.g. the expires header
  • Special handling for fragments of a page
  • Avoids session creation for application scope pages
  • Multiple matching cache filters won't dead-lock the response anymore

JIRA Issue List

OpenSymphony JIRA (22 issues)
T Key Summary Status
Bug CACHE-189 AbstractDiskPersistenceListener.store hangs on exception ClosedClosed
Bug CACHE-185 Filtered requests will be re-requested twice ClosedClosed
Bug CACHE-184 Filter deadlock with external apps (mostly spiders) ClosedClosed
Improvement CACHE-179 Provider interface for method createCacheKey ClosedClosed
Bug CACHE-174 Regression in fix of CACHE-170: UpdateStateEntry may leak when entry are removed ClosedClosed
Bug CACHE-173 NullPointerException while flushing inexistant group ClosedClosed
Bug CACHE-170 Data race handling Cache.updateStates results in Thread hangs when the blocking mode is used in concurrence ClosedClosed
Improvement CACHE-169 Default initialization of the last modified header ClosedClosed
Sub-task CACHE-161 CacheFilter easier sub-classing via isCacheable ClosedClosed
Bug CACHE-160 ExpiresRefreshPolicy always set in CacheFilter ClosedClosed
New Feature CACHE-155 Support of GZip filters in the filter chain ClosedClosed
Bug CACHE-154 NullPointerException in JavaGroupsBroadcastingListener ClosedClosed
Bug CACHE-148 getInstance call not thread-safe ClosedClosed
Bug CACHE-144 CacheTag doesn't clear variables in doStartTag / doFinally ClosedClosed
Improvement CACHE-143 Report expected expiry to clients/browsers/proxy ClosedClosed
Task CACHE-138 Document new parameters in the wiki ClosedClosed
New Feature CACHE-135 CacheFilter for fragements of a page ClosedClosed
Bug CACHE-129 CacheFilter will create useless sessions for application-scope pages ClosedClosed
Bug CACHE-128 Multiple matching filters will dead-lock the response ClosedClosed
New Feature CACHE-120 New nocache option when body contains a jsessionid ClosedClosed
Bug CACHE-83 CacheHttpServletResponseWrapper & ResponseContent dont preserver Http headers ClosedClosed
Improvement CACHE-69 Custom Key Generation on CacheFilter ClosedClosed

oscache-2.4.1.orig/docs/wiki/Hibernate 2.1 and pre OSCache 2.4 support.html0000644000175000017500000001425410615666742025507 0ustar twernertwerner OSCache - Hibernate 2.1 and pre OSCache 2.4 support
Info

This page is intended to give integration support for Hibernate 2.1 and for pre OSCache 2.4 releases.
It's recommended to use the new Hibernate 3.2 classes.

Hibernate is a powerful, ultra-high performance object/relational persistence and query service for Java. Hibernate lets you develop persistent objects following common Java idiom - including association, inheritance, polymorphism, composition and the Java collections framework. Extremely fine-grained, richly typed object models are possible.

Hibernate 2.1 features support for plugin cache providers and is designed to integrate with distributed caches (2.1 also implements more aggressive use of the cache). net.sf.hibernate.cache.CacheProvider is the extension point for user-defined cache integration.

Hibernate 2.1.1 or higher is required.

hibernate.cache.provider_class

OSCache and Hibernate 2.1 integrate though OSCacheProvider.

Warning

Unfortunately, at this time the OSCacheProvider distributed with Hibernate 2.1.x is not suited to clustering with OSCache. A patch has been submitted to the Hibernate team but not yet applied. Even if you do not require clustering, we recommend use of these patched versions of OSCacheProvider and OSCache for Hibernate 2.x and OSCacheProvider and OSCache for Hibernate 3.x. Just cut-n-paste the code and use the provider class you create as the hibernate.cache.provider_class as shown below.

To enable OSCache in Hibernate's configuration, add the following line to hibernate.cfg.xml:

hibernate.cfg.xml
<property name="hibernate.cache.provider_class">my.patched.provider.package.OSCacheProvider</property>

The default refresh period is CacheEntry.INDEFINITE_EXPIRY. The first time a cacheable query is done, the cache has no effect on speed. On the second and successive queries, the cache will be populated and available to be hit.

Object Identifiers

Object identifiers must have well-behaved toString() methods, because OSCache uses the toString() method for the key of the cache. Therefore it needs to create a unique identifier for the object being stored.

Cache Region Configuration

To modify the refresh period, CRON expression, add the region configuration to your oscache.properties file, as demonstrated below:

[region].refresh.period = 4000
[region].cron = * * 31 Feb *

# The maximum cache capacity can only be set per region if you use the 
# net.sf.hibernate.cache.OSCacheProvider distributed with Hibernate.
[region].capacity = 5000

# The patched version distributed with OSCache only allows a single cache.capacity setting and saves memory.

The com.mypackage.domain.Customer is Hibernate's internal cache region, which defaults to the classname, and which can be altered by setting Hibernate's configuration property hibernate.cache.region_prefix .

Source Code

oscache-2.4.1.orig/docs/wiki/Installation Guide.html0000644000175000017500000001204010641651526022263 0ustar twernertwerner OSCache - Installation Guide

This installation guide shows you how to configure OSCache 2.4 for use inside your JSP pages. It assumes you have downloaded the latest version, which requires at least Java 1.4 and a Servlet 2.3 container (part of J2EE 1.3). Read the Requirements for more details.

If you intend to use OSCache via the API rather than via the taglibs, these instructions do not apply. Just make sure oscache.jar and commons-logging.jar are somewhere on your application's classpath.

Extraction Steps

  1. Extract the downloaded file to a directory of your choosing.
  2. Put the oscache.jar file in the /WEB-INF/lib directory
  3. Make sure commons-logging.jar is on your classpath (normally this also means putting it in /WEB-INF/lib).
  4. Put the /etc/oscache.properties file in the /WEB-INF/classes directory and edit the properties contained within it (for example if you want disk caching, configure the persistence listener and edit the cache.path property to point to where you want the cache files stored on disk). See the Configuration Guide for further details on what options are available.
  5. Your directory structure should now look something like this:

    $WEB_APPLICATION/WEB-INF/lib/oscache.jar
    $WEB_APPLICATION/WEB-INF/classes/oscache.properties

Windows

Remember to escape any \ characters in Windows paths - e.g. if you want cache files to go in c:\cachedir, the cache.path property should be set to c:\ \cachedir.

Installation Steps

  1. Now add the appropriate JSP Tags to your JSP files and you're done.
  2. It should work properly. Tell us on the mailing list if it doesn't work in your container.

Further Information

Logging

OSCache uses Jakarta Commons Logging for logging any messages. Please see the Commons Logging documentation for details on logging configuration.

Debugging

Note that OSCache has been compiled with debugging information enabled so you should be able to use your favourite debugger to step through the source if need be.

oscache-2.4.1.orig/docs/wiki/OSCache 1.5.html0000644000175000017500000000432510402251442020330 0ustar twernertwerner OSCache - OSCache 1.5

Release Notes

(6th August, 2001 - by Todd Gochenour, tgochenour@peregrine.com)

  • Added boolean "cache.memory" attribute to oscache.properties to eliminate memory consumption and rely strictly on disk storage.
  • Added three interfaces "CacheLog", "CacheProperties", and "CacheContents" to allow plugable implementations for these functions. The CacheContents interface allows the pages to be cached using a database.
  • Added "Language" attribute to CacheTag and FlushTag to distinguish a page that supports I18N generation. The ISO-639 language code is used when the scope of the page is "Application". The code defines a subdirectory under the "application" directory of file caching.
  • Modified the CacheAdministrator.generateKey() function to append the request's QueryString to the URI when automatically generating keys. The QueryString is encoded using the MD5 digest base64 algorithms.
  • Added attribute "encoding" to a CacheTag so that the file IO does proper conversion when reading and writing the cache files. (per suggestion of Pedro Gomez)
  • Added retries when SecurityException is thrown. Java has no built in exclusive file locking implementations. The file is written to a lock file and then renamed as an atomic operation so that multiple processes on the same box can reliable access cache data.
  • Added "pattern" attribute to FlushTag which invokes a CacheHashMap.flushPattern() function to scan for and flush all keys that contain the value of the pattern. (per suggestion of Todd Rudrick)
  • Added support for a CacheTag time value of zero which turns off caching for that tag. (per suggestion of Pedro Gomez)
oscache-2.4.1.orig/docs/wiki/Change Log.html0000644000175000017500000000727610641651324020506 0ustar twernertwerner OSCache - Change Log

Release Notes

See also JIRA - Change Log or read the complete release notes at once.

oscache-2.4.1.orig/docs/wiki/Hibernate 2.1 Cache Provider.html0000644000175000017500000001066310615670144023534 0ustar twernertwerner OSCache - Hibernate 2.1 Cache Provider

Patched version of OSCacheProvider.java originally created by Mathias Bogaert.

OSCacheProvider.java
import java.util.Properties;

import net.sf.hibernate.cache.Cache;
import net.sf.hibernate.cache.CacheException;
import net.sf.hibernate.cache.CacheProvider;
import net.sf.hibernate.cache.Timestamper;
import net.sf.hibernate.util.PropertiesHelper;
import net.sf.hibernate.util.StringHelper;

import com.opensymphony.oscache.base.CacheEntry;
import com.opensymphony.oscache.base.Config;

/**
 * Support for OpenSymphony OSCache. This implementation assumes
 * that identifiers have well-behaved <tt>toString()</tt> methods.
 */
public class OSCacheProvider implements CacheProvider {

	/** 
	 * The <tt>OSCache</tt> refresh period property suffix. 
	 */
	public static final String OSCACHE_REFRESH_PERIOD = "refresh.period";
	/** 
	 * The <tt>OSCache</tt> CRON expression property suffix. 
	 */
	public static final String OSCACHE_CRON = "cron";
	
	private static final Properties OSCACHE_PROPERTIES = new Config().getProperties();

	/**
	 * Builds a new {@link Cache} instance, and gets it's properties from the OSCache {@link Config}
	 * which reads the properties file (<code>oscache.properties</code>) from the classpath.
	 * If the file cannot be found or loaded, an the defaults are used.
	 *
	 * @param region
	 * @param properties
	 * @return
	 * @throws CacheException
	 */
	public Cache buildCache(String region, Properties properties) throws CacheException {

		int refreshPeriod = PropertiesHelper.getInt(
			StringHelper.qualify(region, OSCACHE_REFRESH_PERIOD), 
			OSCACHE_PROPERTIES, 
			CacheEntry.INDEFINITE_EXPIRY
		);
		String cron = OSCACHE_PROPERTIES.getProperty( StringHelper.qualify(region, OSCACHE_CRON) );

		// construct the cache        
        return new OSCache(refreshPeriod, cron, region);
	}

	public long nextTimestamp() {
		return Timestamper.next();
	}

	/**
	 * Callback to perform any necessary initialization of the underlying cache implementation
	 * during SessionFactory construction.
	 *
	 * @param properties current configuration settings.
	 */
	public void start(Properties properties) throws CacheException {
	}

	/**
	 * Callback to perform any necessary cleanup of the underlying cache implementation
	 * during SessionFactory.close().
	 */
	public void stop() {
	}

}
oscache-2.4.1.orig/docs/wiki/JMX Monitoring.html0000644000175000017500000000754610615666742021376 0ustar twernertwerner OSCache - Monitoring

New in OSCache 2.4 is support for JMX monitoring and administration via the Spring Framework.

In oscache.properties, enable the statistic listener:

cache.event.listeners= com.opensymphony.oscache.extra.StatisticListenerImpl

Then add this to the Spring application context

<!-- create mbeanserver, this doesn't need to be done if running on an Appserver with 
it's own JMX server, such as Tomcat -->
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>

<!-- create a connector on port 1109 -->
<bean id="registry"
	class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
	<property name="port">
		<value>1109</value>
	</property>
</bean>

<bean id="serverConnector" depends-on="registry"
	class="org.springframework.jmx.support.ConnectorServerFactoryBean">
	<property name="objectName">
		<value>connector:name=rmi</value>
	</property>
	<property name="serviceUrl">
		<value>service:jmx:rmi://localhost/jndi/rmi://localhost:1109/jmxconnector</value>
	</property>			
</bean>  

<!-- export the oscache stats beans -->
<bean id="exporter"
      class="org.springframework.jmx.export.MBeanExporter">
	<property name="beans">
		<map>   
                <entry key="bean:name=StatisticListenerImpl">
				<value>StatisticListenerImpl</value>
		</entry>	                
		</map>
	</property>
</bean>

<!-- oscache stats bean -->
<bean id="StatisticListenerImpl" class="com.opensymphony.oscache.extra.StatisticListenerImpl"/>
oscache-2.4.1.orig/docs/wiki/OSCache 2.0 beta 2.html0000644000175000017500000000412010402251442021333 0ustar twernertwerner OSCache - OSCache 2.0 beta 2

Release Notes

(4th August 2003 - by Chris Miller)

New Features:

  • Now supports JavaGroups version 2.1.
  • JMS Clustering support has been added -Romulus Pasca.
  • Clustering code has been refactored. As a result of this, some of the clustering configuration has changed since beta 1 - please see the updated clustering documentation for details.
  • Performance enhancement: When running under JRE 1.3.x, the LRUCache will now attempt to use the Jakarta commons collections SequencedHashMap. If the commons-collections.jar is not present then the code resorts to using a LinkedList and a warning is logged. Note that under JRE 1.4.x and higher the commons-collections.jar is not required.
  • Config.getProperties() method added.

Bug Fixes:

  • CACHE-48 FastCronParser no longer requires JDK 1.4.x.
  • CACHE-45 Fixed a serialization bug.
  • The CachewideEvent was not holding the event date.
  • Prevented an error from being logged in the CachewideEvent handling (even though no problem had occurred).
  • Fixed a subtle bug in the concurrent unit test.
  • The ServletCacheAdministrator's app scope cache is created on startup (via the CacheContextListener).
oscache-2.4.1.orig/docs/wiki/OSCache 2.0.2.html0000644000175000017500000000277110402251442020467 0ustar twernertwerner OSCache - OSCache 2.0.2

Release Notes

(22nd January 2004 - by Mathias Bogaert)

Improvements:

  • Website documentation updates.
  • Added OSCache in the Wild.

Bug Fixes:

  • CACHE-63 NullPointerException in GeneralCacheAdministrator#destroy().
  • CACHE-44 Multi threading issues with LRU Cache.
  • CACHE-66 DiskPersistenceListener is not Serializable.
  • GeneralCacheAdministrator now creates the cache from within the constructor. This prevents possible threading issues if the cache is not initialized during application startup.
oscache-2.4.1.orig/docs/wiki/OSCache 2.4.html0000644000175000017500000006501710641651526020351 0ustar twernertwerner OSCache - OSCache 2.4

Release Notes

(1st Mai 2007 - by Lars Torunski)

New features and enhancements

Furthermore the next major release 2.4 enhances the CacheFilter and allows a better integration with the Spring Framework and JMX Monitoring.

  • Setting CacheFilter parameters runtime
  • Lazy initialization in CacheFilter in order to ease spring integration
  • Allow disabling cacheing for special http methods (e.g. POST/DELETE/PUT) in CacheFilter
  • CacheFilter allow reentrance over different filter configurations
  • Hibernate 3.2 integration support
  • JMX Monitoring/Administration via Spring
  • Improve oscache.properties loading
  • Performance improvment for large disk persistence usage

Upgrade Guide

  • Due to the enhancements in the CacheFilter and method signature changes, it's recommended to recompile your code.
  • Due to changes for CACHE-284 the handling of the listeners have been changed: Before OSCache 2.4 objects which implemented different CacheEventListener (e.g. CacheEntryEventListener and CacheMapAccessEventListener) had to be added twice, because the listeners where registrated only for one special event listener. With OSCache 2.4 only the object has to be added to the list without the 2nd parameter 'type of the listener'.

JIRA Issue List

OpenSymphony JIRA (29 issues)
T Key Summary Status
Bug CACHE-260 NullPointerException in AbstractConcurrentReadCache ClosedClosed
New Feature CACHE-295 Hibernate 3.2 integration support ClosedClosed
Improvement CACHE-215 Setting CacheFilter parameters runtime ClosedClosed
Improvement CACHE-99 Use lazy initialization in cache filter in order to ease spring integration ClosedClosed
Bug CACHE-258 NullPointerException when using putCache(key, val) in LRUCache ClosedClosed
Task CACHE-273 Update to Commons Logging 1.1 ClosedClosed
Task CACHE-253 Migrate from CVS to SVN ClosedClosed
Task CACHE-261 Check javadoc of Cache.cancelUpdate on key not being updated ClosedClosed
Sub-task CACHE-163 CacheFilter easier sub-classing via pre- and post-processes ClosedClosed
Sub-task CACHE-162 CacheFilter easier sub-classing via useCache ClosedClosed
Improvement CACHE-272 Allow disabling of cacheing special http methods (e.g. POST/DELETE/PUT) in CacheFilter ClosedClosed
Improvement CACHE-277 CacheFilter should allow reentrance over different filter configurations ClosedClosed
Improvement CACHE-283 Improve oscache.properties loading ClosedClosed
New Feature CACHE-266 ServletCacheAdministrator no longer a "Servlet Singleton" ClosedClosed
Improvement CACHE-267 SplitServletOutputStream doesn't pass flush() on to underlying stream ClosedClosed
Task CACHE-141 CacheFilter easier sub-classing ClosedClosed
Bug CACHE-288 Error in the HashDiskPersistenceListener byteArrayToHexString ClosedClosed
Bug CACHE-264 problem with not escaped group names and their filenames for disk persistence ClosedClosed
Bug CACHE-255 AbstractConcurrentReadCache#put(Object key, Object value) may return a wrong value ClosedClosed
Improvement CACHE-249 Performance improvment for large disk persistence usage ClosedClosed
Improvement CACHE-293 Allow to specify a different oscache.properties file for Hibernate ClosedClosed
Bug CACHE-278 Filter ignores max-age parameter when serving from cache ClosedClosed
Bug CACHE-284 Cache.dispatchCacheEntryEvent and Cache.addEventListener implementations are inconsistent ClosedClosed
Improvement CACHE-274 new method getIntialContext JMSBroadcastingListener ClosedClosed
Task CACHE-263 Run FindBugs 1.1.3 against current source code ClosedClosed
Bug CACHE-292 CacheFilter max-age default and error-case initialisation are wrong ClosedClosed
Improvement CACHE-290 Bad Practice ClosedClosed
New Feature CACHE-178 JMX Monitoring/Administration via Spring ClosedClosed
Improvement CACHE-252 Log warning if user tries to set max entries on an unlimited cache ClosedClosed

oscache-2.4.1.orig/docs/wiki/border/0000755000175000017500000000000011375310612017167 5ustar twernertwerneroscache-2.4.1.orig/docs/wiki/border/border_bottom.gif0000644000175000017500000000016510173132432022516 0ustar twernertwernerGIF89a ³ééé²²²™™™yyyÝÝÝÌÌÌðððþ!ùÿ, "ÈI¹8“Á»B(Ž‚až¨Q¬l[p,Gmßx®ï|;oscache-2.4.1.orig/docs/wiki/border/spacer.gif0000644000175000017500000000005310173132432021126 0ustar twernertwernerGIF89a€ÿÿÿ!ù,D;oscache-2.4.1.orig/docs/meta.xml0000644000175000017500000001527010643656412016434 0ustar twernertwerner OSCache 10001 CACHE CACHE true 4 12 Overview wiki/What%20is%20OSCache.html Feature List wiki/Feature%20List.html Requirements wiki/Requirements.html Installation Guide wiki/Installation%20Guide.html Configuration Guide wiki/Configuration.html wiki/Documentation.html FAQ wiki/FAQ.html Tag Reference wiki/JSP%20Tags.html The Caching Filter wiki/CacheFilter.html Cron Expressions wiki/Cron%20Expressions.html OSCache and Hibernate wiki/Hibernate.html Clustering wiki/Clustering.html Andres March me at andresmarch dot com Lars Torunski ltorunski at t-online dot de Chris Miller chris_overseas at hotmail dot com 2.4.1 07/07/2007 21705 https://oscache.dev.java.net/files/documents/629/61427/oscache-2.4.1-full.zip Full 2.4 05/01/2007 21660 https://oscache.dev.java.net/files/documents/629/57136/oscache-2.4-full.zip Full 2.3.2 07/23/2006 21651 https://oscache.dev.java.net/files/documents/629/37840/oscache-2.3.2-full.zip Full 2.3.1 06/19/2006 21630 https://oscache.dev.java.net/files/documents/629/36361/oscache-2.3.1-full.zip Full 2.3 03/06/2006 21570 https://oscache.dev.java.net/files/documents/629/30345/oscache-2.3-full.zip Full 2.2 Final 11/06/2005 21550 https://oscache.dev.java.net/files/documents/629/23623/oscache-2.2-full.zip Full 2.2 RC 09/18/2005 21450 https://oscache.dev.java.net/files/documents/629/20854/oscache-2.2-rc-full.zip Full 2.1.1 5/01/2005 21441 https://oscache.dev.java.net/files/documents/629/13962/oscache-2.1.1-full.zip Full 2.1 1/18/2005 21223 https://oscache.dev.java.net/files/documents/629/10654/oscache-2.1-full.zip Full 2.0.2 1/22/2004 21251 https://oscache.dev.java.net/files/documents/629/2653/oscache-2.0.2-full.zip Full 2.0.1 1/04/2003 21250 https://oscache.dev.java.net/files/documents/629/1580/oscache-2.0.1-full.zip Full 2.0 09/22/2003 21222 https://oscache.dev.java.net/files/documents/629/1051/oscache_2_0_full.zip Full oscache-2.4.1.orig/OSCache.iml0000644000175000017500000001336610316437443016006 0ustar twernertwerner jar://$MODULE_DIR$/lib/clover.jar!/ jar://$MODULE_DIR$/lib/commons-collections.jar!/ jar://$MODULE_DIR$/lib/commons-logging.jar!/ jar://$MODULE_DIR$/lib/httpunit.jar!/ jar://$MODULE_DIR$/lib/jgroups-all.jar!/ jar://$MODULE_DIR$/lib/jms.jar!/ jar://$MODULE_DIR$/lib/junit.jar!/ jar://$MODULE_DIR$/lib/junitperf.jar!/ oscache-2.4.1.orig/www/0000755000175000017500000000000011375310606014646 5ustar twernertwerneroscache-2.4.1.orig/www/index.html0000644000175000017500000000107710235725472016655 0ustar twernertwerner A caching solution that includes a JSP tag library and set of classes to perform fine grained dynamic caching of JSP content, servlet responses or arbitrary objects. It provides both in memory and persistent on disk caches, and can allow your site to have graceful error tolerance (eg if an error occurs like your db goes down, you can serve the cached content so people can still surf the site almost without knowing).

The OSCache Homepage is at www.opensymphony.com/oscache

oscache-2.4.1.orig/www/project_tools.html0000644000175000017500000000047410235725472020434 0ustar twernertwerner
OpenSymphony
Documentation
Bug Tracker
Wiki
oscache-2.4.1.orig/build.properties0000644000175000017500000000052310641701561017236 0ustar twernertwerner# OSCache build properties name=oscache fullname=OSCache version=2.4.1 status=integration cvs.tag=v2_4_1 # The URL to use for testing the example webapp. Comment this out to disable the webapp tests. #test.web.baseURL=http://localhost:7001/oscache-example/ #test.web.deployDir=C:/Programme/bea/user_projects/domains/mydomain/applications oscache-2.4.1.orig/src/0000755000175000017500000000000011375310610014604 5ustar twernertwerneroscache-2.4.1.orig/src/test/0000755000175000017500000000000011375310606015570 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/0000755000175000017500000000000011375310607016512 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/oscacheDiskAndMemory.properties0000644000175000017500000000036310254455232024665 0ustar twernertwerner# CACHE IN MEMORY cache.memory=true # CACHE SIZE cache.capacity=100 # CACHE PERSISTENCE CLASS cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener # CACHE DIRECTORY cache.path=/tmp/cachetagscache oscache-2.4.1.orig/src/test/java/com/0000755000175000017500000000000011375310606017267 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/com/opensymphony/0000755000175000017500000000000011375310606022037 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/0000755000175000017500000000000011375310607023445 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/general/0000755000175000017500000000000011375310607025062 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/general/TestCompleteGeneral.java0000644000175000017500000000307510623613771031643 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.general; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test class for the com.opensymphony.oscache.general package. * It invokes all the test suites of all the other classes of the package. * * $Id: TestCompleteGeneral.java 465 2007-05-19 15:30:01Z larst $ * @version $Revision: 465 $ * @author Alain Bergevin */ public final class TestCompleteGeneral extends TestCase { /** * Constructor for the osCache Cache project main test program */ public TestCompleteGeneral(String str) { super(str); } /** * Main method which is called to perform the tests *

* @param args Arguments received */ public static void main(String[] args) { // Run the test suite junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner(); testRunner.setLoading(false); String[] args2 = {TestCompleteGeneral.class.getName()}; testRunner.start(args2); } /** * Test suite required to test this project *

* @return suite The test suite */ public static Test suite() { // Add all the tests suite of all the project classes TestSuite suite = new TestSuite("Test all General cache package"); suite.addTest(TestGeneralCacheAdministrator.suite()); suite.addTest(TestConcurrent.suite()); return suite; } } ././@LongLink0000000000000000000000000000014500000000000011565 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/general/TestGeneralCacheAdministrator.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/general/TestGeneralCacheAdministrator.java0000644000175000017500000003351010577205037033634 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.general; import java.util.Date; import com.opensymphony.oscache.base.*; import com.opensymphony.oscache.extra.CacheEntryEventListenerImpl; import com.opensymphony.oscache.extra.CacheMapAccessEventListenerImpl; import junit.framework.Test; import junit.framework.TestSuite; /** * Test all the public methods of the GeneralCacheAdministrator class. Since * this class extends the TestAbstractCacheAdministrator class, the * AbstractCacheAdministrator is tested when invoking this class. * * $Id: TestGeneralCacheAdministrator.java 425 2007-03-18 09:45:03Z larst $ * @version $Revision: 425 $ * @author Alain Bergevin */ public class TestGeneralCacheAdministrator extends TestAbstractCacheAdministrator { // Constants used thru all the tests private static final String KEY = "Test General Cache Admin Key"; private static final int NO_REFRESH_NEEDED = CacheEntry.INDEFINITE_EXPIRY; private static final int REFRESH_NEEDED = 0; private static final String CONTENT = "Content for the general cache admin test"; private static final String WILL_NOT_FLUSH_PATTERN = "This key won't flush"; private static final String GROUP1 = "group1"; private static final String GROUP2 = "group2"; private static final String GROUP3 = "group3"; // Constants for listener counters private static final int NB_CACHE_HITS = 7; private static final int NB_CACHE_STALE_HITS = 7; private static final int NB_CACHE_MISSED = 1; private static final int NB_ADD = 7; private static final int NB_UPDATED = 2; private static final int NB_FLUSH = 3; private static final int NB_REMOVED = 0; private static final int NB_GROUP_FLUSH = 2; private static final int NB_PATTERN_FLUSH = 1; // Static instance of a cache administrator static GeneralCacheAdministrator admin = null; // Declare the listeners private CacheEntryEventListenerImpl cacheEntryEventListener = null; private CacheMapAccessEventListenerImpl cacheMapAccessEventListener = null; /** * Class constructor *

* @param str Test name (required by JUnit) */ public TestGeneralCacheAdministrator(String str) { super(str); } /** * Test suite required to test this project *

* @return suite The test suite */ public static Test suite() { return new TestSuite(TestGeneralCacheAdministrator.class); } /** * Abstract method used by the TestAbstractCacheAdministrator class *

* @return An administrator instance */ public AbstractCacheAdministrator getAdmin() { return admin; } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // At first invocation, create a administrator admin = new GeneralCacheAdministrator(); assertNotNull(admin); cacheEntryEventListener = new CacheEntryEventListenerImpl(); cacheMapAccessEventListener = new CacheMapAccessEventListenerImpl(); // Register the listeners on the cache map admin.getCache().addCacheEventListener(cacheEntryEventListener); admin.getCache().addCacheEventListener(cacheMapAccessEventListener); } /** * Validate the CacheEntryEventListener's data */ public void testCacheEntryEventListenerCounters() { populate(); assertEquals(NB_ADD, cacheEntryEventListener.getEntryAddedCount()); assertEquals(NB_REMOVED, cacheEntryEventListener.getEntryRemovedCount()); assertEquals(NB_UPDATED, cacheEntryEventListener.getEntryUpdatedCount()); assertEquals(NB_GROUP_FLUSH, cacheEntryEventListener.getGroupFlushedCount()); assertEquals(NB_PATTERN_FLUSH, cacheEntryEventListener.getPatternFlushedCount()); assertEquals(NB_FLUSH, cacheEntryEventListener.getEntryFlushedCount()); } /** * Validate the CacheEntryEventListener's data */ public void testCacheMapAccessEventListenerCounters() { populate(); int missCount = cacheMapAccessEventListener.getMissCount(); if (NB_CACHE_MISSED != missCount) { fail("We expected " + NB_CACHE_MISSED + " misses but got " + missCount + "." + " This is probably due to existing disk cache, delete it and re-run" + " the test"); } assertEquals(NB_CACHE_HITS, cacheMapAccessEventListener.getHitCount()); assertEquals(NB_CACHE_STALE_HITS, cacheMapAccessEventListener.getStaleHitCount()); } /** * Ensure that item may be flushed by key pattern */ public void testFlushPattern() { // Put some content in cache admin.putInCache(KEY, CONTENT); // Call flush pattern with parameters that must NOT flush our object admin.flushPattern(WILL_NOT_FLUSH_PATTERN); admin.flushPattern(""); admin.flushPattern(null); // Ensure that our object is not gone assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, false)); // This time we flush it for real admin.flushPattern(KEY.substring(1, 2)); assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, true)); } /** * Ensure that item may be flushed by the entry itself */ public void testFlushEntry() { // Put some content in cache admin.putInCache(KEY, CONTENT); // Call flush pattern with parameters that must NOT flush our object admin.flushEntry(WILL_NOT_FLUSH_PATTERN); // Ensure that our object is not gone assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, false)); // This time we flush it for real admin.flushEntry(KEY); assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, true)); } /** * Ensure that item may be flushed by flush all */ public void testFlushAll() { // Put some content in cache admin.putInCache(KEY, CONTENT); // Ensure that our object is not gone assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, false)); // This time we flush it for real admin.flushAll(); assertNotNull(checkObj(KEY, NO_REFRESH_NEEDED, true)); } /** * Ensure that the cache groupings work correctly */ public void testGroups() { // Flush a non-existent group - should be OK and will still fire a GROUP_FLUSHED event admin.flushGroup(GROUP1); // Add some items to various group combinations admin.putInCache("1", "item 1"); // No groups admin.putInCache("2", "item 2", new String[] {GROUP1}); // Just group 1 admin.putInCache("3", "item 3", new String[] {GROUP2}); // Just group 2 admin.putInCache("4", "item 4", new String[] {GROUP1, GROUP2}); // groups 1 & 2 admin.putInCache("5", "item 5", new String[] {GROUP1, GROUP2, GROUP3}); // groups 1,2 & 3 admin.flushGroup(GROUP3); // This should flush item 5 only assertNotNull(checkObj("5", NO_REFRESH_NEEDED, true)); assertNotNull(checkObj("4", NO_REFRESH_NEEDED, false)); admin.flushGroup(GROUP2); // This should flush items 3 and 4 assertNotNull(checkObj("1", NO_REFRESH_NEEDED, false)); assertNotNull(checkObj("2", NO_REFRESH_NEEDED, false)); assertNotNull(checkObj("3", NO_REFRESH_NEEDED, true)); assertNotNull(checkObj("4", NO_REFRESH_NEEDED, true)); admin.flushGroup(GROUP1); // Flushes item 2 assertNotNull(checkObj("1", NO_REFRESH_NEEDED, false)); assertNotNull(checkObj("2", NO_REFRESH_NEEDED, true)); // Test if regrouping a cache entry works admin.putInCache("A", "ABC", new String[] {"A"}); admin.putInCache("A", "ABC", new String[] {"A", "B"}); admin.putInCache("B", "DEF", new String[] {"B"}); admin.flushGroup("B"); assertNotNull(checkObj("A", NO_REFRESH_NEEDED, true)); } /** * Test the main cache functionalities, which are storing and retrieving objects * from it */ public void testPutInCacheAndGetFromCache() { // Put some item in cache and get it back right away. It should not need // to be refreshed admin.putInCache(KEY, CONTENT); String cacheContent = (String) checkObj(KEY, NO_REFRESH_NEEDED, false); assertTrue(CONTENT.equals(cacheContent)); // Get the item back again and expect a refresh cacheContent = (String) checkObj(KEY, REFRESH_NEEDED, true); assertTrue(CONTENT.equals(cacheContent)); // Call the put in cache with invalid values invalidPutInCacheArgument(null, null); admin.putInCache(KEY, null); // This will still update the cache - cached items can be null // Call the getFromCache with invalid values invalidGetFromCacheArgument(null, 0); // Try to retrieve the values assertNull(checkObj(KEY, NO_REFRESH_NEEDED, false)); // Try to retrieve an item that is not in the cache Object obj = checkObj("Not in cache", NO_REFRESH_NEEDED, true); assertNull(obj); } /** * Test the main cache functionalities, which are storing and retrieving objects * from it */ public void testPutInCacheAndGetFromCacheWithPolicy() { String key = "policy"; // We put content in the cache and get it back admin.putInCache(key, CONTENT, new DummyAlwayRefreshEntryPolicy()); // Should get a refresh try { admin.getFromCache(key, -1); fail("Should have got a refresh."); } catch (NeedsRefreshException nre) { admin.cancelUpdate(key); } } protected void tearDown() throws Exception { if (admin != null) { admin.getCache().removeCacheEventListener(cacheEntryEventListener); admin.getCache().removeCacheEventListener(cacheMapAccessEventListener); } } /** * Bug CACHE-241 */ public void testFlushDateTomorrow() { GeneralCacheAdministrator cacheAdmin = new GeneralCacheAdministrator(null); cacheAdmin.putInCache("key1", "key1value"); try { assertNotNull(cacheAdmin.getFromCache("key1")); } catch (NeedsRefreshException e1) { fail("Previous cache key1 doesn't exsits in GCA for the test!"); } cacheAdmin.flushAll(new Date(System.currentTimeMillis() + 5000)); // flush in 5 sec. try { cacheAdmin.getFromCache("key1"); } catch (NeedsRefreshException e) { cacheAdmin.cancelUpdate("key1"); fail("NRE is thrown, but key will expire in 5s."); // it fails here } } /** * Utility method that tries to get an item from the cache and verify * if all goes as expected *

* @param key The item key * @param refresh The timestamp specifiying if the item needs refresh * @param exceptionExpected Specify if we expect a NeedsRefreshException */ private Object checkObj(String key, int refresh, boolean exceptionExpected) { // Cache content Object content = null; try { // try to find an object content = admin.getFromCache(key, refresh); if (exceptionExpected) { fail("Expected NeedsRefreshException!"); } } catch (NeedsRefreshException nre) { admin.cancelUpdate(key); if (!exceptionExpected) { fail("Did not expected NeedsRefreshException!"); } // Return the cache content from the exception content = nre.getCacheContent(); } return content; } /** * Method that try to retrieve data from the cache but specify wrong arguments *

* @param key The cache item key * @param refresh The timestamp specifiying if the item needs refresh */ private void invalidGetFromCacheArgument(String key, int refresh) { try { // Try to get the data from the cache admin.getFromCache(key, refresh); fail("getFromCache did NOT throw an IllegalArgumentException"); } catch (IllegalArgumentException ipe) { // This is what we expect } catch (NeedsRefreshException nre) { admin.cancelUpdate(key); // Ignore this one } } /** * Method that try to insert data in the cache but specify wrong arguments *

* @param key The cache item key * @param content The content of the cache item */ private void invalidPutInCacheArgument(String key, Object content) { try { // Try to put this data in the cache admin.putInCache(key, content); fail("putInCache did NOT throw an IllegalArgumentException"); } catch (IllegalArgumentException ipe) { // This is what we expect } } private void populate() { for (int i = 0; i < 7; i++) { String[] groups = ((i & 1) == 0) ? new String[] {GROUP1, GROUP2} : new String[] { GROUP3 }; admin.putInCache(KEY + i, CONTENT + i, groups); } //register one miss. checkObj("Not in cache", NO_REFRESH_NEEDED, true); //register 7 hits for (int i = 0; i < 7; i++) { try { admin.getFromCache(KEY + i, NO_REFRESH_NEEDED); } catch (NeedsRefreshException e) { admin.cancelUpdate(KEY + i); } } for (int i = 0; i < 7; i++) { try { admin.getFromCache(KEY + i, 0); } catch (NeedsRefreshException e) { admin.cancelUpdate(KEY + i); } } admin.putInCache(KEY + 1, CONTENT); admin.putInCache(KEY + 2, CONTENT); admin.flushPattern("blahblah"); admin.flushGroup(GROUP1); admin.flushGroup(GROUP2); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/general/TestConcurrent.java0000644000175000017500000001014510623613771030713 0ustar twernertwerner/* * Copyright (c) 2002-2007 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.general; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.opensymphony.oscache.base.AbstractCacheAdministrator; import com.opensymphony.oscache.base.NeedsRefreshException; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Testing concurrent API accesses. * * @author $Author: larst $ * @version $Revision: 385 $ */ public class TestConcurrent extends TestCase { private static transient final Log log = LogFactory.getLog(GeneralCacheAdministrator.class); //TestConcurrency.class // Static instance of a cache administrator private GeneralCacheAdministrator admin = null; // Constants needed in the tests private final String KEY = "ConcurrentKey"; private final String VALUE = "ConcurrentContent"; private static final int THREAD_COUNT = 5; private static final int CACHE_SIZE_THREAD = 2000; private static final int CACHE_SIZE = THREAD_COUNT * CACHE_SIZE_THREAD; public TestConcurrent(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestConcurrent.class); } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // At first invocation, create a new Cache if (admin == null) { Properties config = new Properties(); config.setProperty(AbstractCacheAdministrator.CACHE_CAPACITY_KEY, Integer.toString(CACHE_SIZE)); admin = new GeneralCacheAdministrator(config); assertNotNull(admin); log.info("Cache Size = " + admin.getCache().getSize()); } } /** * Tests concurrent accesses. * @see http://jira.opensymphony.com/browse/CACHE-279 */ public void testConcurrentCreation10000() { Thread[] thread = new Thread[THREAD_COUNT]; log.info("Ramping threads..."); for (int idx = 0; idx < THREAD_COUNT; idx++) { CreationTest runner = new CreationTest(idx); thread[idx] = new Thread(runner); thread[idx].start(); } log.info("Waiting...."); boolean stillAlive; do { try { Thread.sleep(200); } catch (InterruptedException e) { // do nothing } stillAlive = false; for (int i = 0; i < thread.length; i++) { stillAlive |= thread[i].isAlive(); } } while (stillAlive); log.info("All threads finished. Cache Size = " + admin.getCache().getSize()); assertTrue("Unexpected amount of objects in the cache: " + admin.getCache().getSize(), CACHE_SIZE == admin.getCache().getSize()); } private class CreationTest implements Runnable { private String prefixKey; public CreationTest(int idx) { prefixKey = KEY + "_" + Integer.toString(idx) + "_"; Thread.currentThread().setName("CreationTest-"+idx); log.info(Thread.currentThread().getName() + " is running..."); } public void run() { for (int i = 0; i < CACHE_SIZE_THREAD; i++) { String key = prefixKey + Integer.toString(i); try { // Get from the cache admin.getFromCache(key); } catch (NeedsRefreshException nre) { // Get the value // Store in the cache admin.putInCache(key, VALUE); } } log.info(Thread.currentThread().getName() + " finished."); } } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/0000755000175000017500000000000011375310606025125 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/0000755000175000017500000000000011375310606030243 5ustar twernertwerner././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/TestJMS10BroadcastingListener.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/TestJMS10Broadcasti0000644000175000017500000000365210263555404033624 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.clustersupport; import com.opensymphony.oscache.base.Config; import junit.framework.Test; import junit.framework.TestSuite; /** * Test all the public methods of the broadcasting listener and assert the * return values * * @author Chris Miller */ public final class TestJMS10BroadcastingListener extends BaseTestBroadcastingListener { public TestJMS10BroadcastingListener(String str) { super(str); } /** * This methods returns the name of this test class to JUnit. * * @return The test for this class */ public static Test suite() { return new TestSuite(TestJMS10BroadcastingListener.class); } /** * Returns a configured JavaGroupsBroadcastingListener instance * for testing. */ public AbstractBroadcastingListener getListener() { return new JMS10BroadcastingListener(); } /** * Return the configuration for the JMS listener */ Config getConfig() { Config config = new Config(); // There needs to be an application resource file present "jndi.properties" that contains the following // parameters: // config.set(Context.INITIAL_CONTEXT_FACTORY, "com.evermind.server.ApplicationClientInitialContextFactory"); // config.set(Context.PROVIDER_URL, "ormi://localhost:23791/"); // config.set(Context.SECURITY_PRINCIPAL, "admin"); // config.set(Context.SECURITY_CREDENTIALS, "xxxxxx"); config.set("cache.cluster.jms.topic.factory", "java:comp/env/jms/TopicConnectionFactory"); config.set("cache.cluster.jms.topic.name", "java:comp/env/jms/OSCacheTopic"); config.set("cache.cluster.jms.node.name", "cacheNode1"); return config; } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/TestCompleteClustering.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/TestCompleteCluster0000644000175000017500000000314710263555404034147 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.clustersupport; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test class for the com.opensymphony.oscache.plugins.clustersupport package. * It invokes all the test suites of all the other classes of the package. * * @author Chris Miller */ public final class TestCompleteClustering extends TestCase { /** * Constructor for the osCache project main test program */ public TestCompleteClustering(String str) { super(str); } /** * Main method which is called to perform the tests *

* @param args Arguments received */ public static void main(String[] args) { // Run the test suite junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner(); testRunner.setLoading(false); String[] args2 = {TestCompleteClustering.class.getName()}; testRunner.start(args2); } /** * Test suite required to test this project *

* @return suite The test suite */ public static Test suite() { // Add all the tests suite of all the project classes TestSuite suite = new TestSuite("Test all OSCache clustering"); suite.addTest(TestJavaGroupsBroadcastingListener.suite()); suite.addTest(TestJMSBroadcastingListener.suite()); suite.addTest(TestJMS10BroadcastingListener.suite()); return suite; } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/ListenForClusterTests.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/ListenForClusterTes0000644000175000017500000000750010577205037034117 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.clustersupport; import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.base.Config; import com.opensymphony.oscache.base.FinalizationException; import com.opensymphony.oscache.base.InitializationException; import java.util.ArrayList; import java.util.Iterator; /** *

This should be used in conjunction with the cluster test cases. Run this * program to set up listeners for the various clustering implementations so * you can see that the test messages are being received correctly.

* *

A shutdown hook is installed so the listeners can be shut down cleanly.

* * @author Chris Miller */ public final class ListenForClusterTests { ArrayList listeners = new ArrayList(); Cache cache; private void mainLoop() { Thread shutdownHook = new ShutdownHookThread(""); Runtime.getRuntime().addShutdownHook(shutdownHook); System.out.println(); System.out.println("------------------------------------------------"); System.out.println("Waiting for cluster messages... (CTRL-C to exit)"); System.out.println("------------------------------------------------"); while (true) { try { Thread.sleep(250); } catch (InterruptedException ie) { } } } private void initListeners() { BaseTestBroadcastingListener testcase = null; AbstractBroadcastingListener listener; Cache cache = new Cache(true, false, false); // Add the JavaGroups listener try { testcase = new TestJavaGroupsBroadcastingListener("JavaGroups"); listener = testcase.getListener(); listener.initialize(cache, testcase.getConfig()); cache.addCacheEventListener(listener); listeners.add(listener); } catch (InitializationException e) { System.out.println("The JavaGroups listener could not be initialized: " + e); } // Add the JMS listener try { testcase = new TestJMSBroadcastingListener("JMS"); listener = testcase.getListener(); Config config = testcase.getConfig(); config.set("cache.cluster.jms.node.name", "cacheNode2"); listener.initialize(cache, config); cache.addCacheEventListener(listener); listeners.add(listener); } catch (InitializationException e) { System.out.println("The JMS listener could not be initialized: " + e); } } /** * Starts up the cluster listeners. */ public static void main(String[] args) { ListenForClusterTests listen = new ListenForClusterTests(); listen.initListeners(); listen.mainLoop(); } /** * Inner class that handles the shutdown event */ class ShutdownHookThread extends Thread { protected String message; public ShutdownHookThread(String message) { this.message = message; } /** * This is executed when the application is forcibly shutdown (via * CTRL-C etc). Any configured listeners are shut down here. */ public void run() { System.out.println("Shutting down the cluster listeners..."); for (Iterator it = listeners.iterator(); it.hasNext();) { try { ((AbstractBroadcastingListener) it.next()).finialize(); } catch (FinalizationException e) { System.out.println("The listener could not be shut down cleanly: " + e); } } System.out.println("Shutdown complete."); } } } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/BaseTestBroadcastingListener.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/BaseTestBroadcastin0000644000175000017500000000622510577205037034063 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.clustersupport; import com.opensymphony.oscache.base.*; import junit.framework.TestCase; import java.util.Date; /** * A base class that provides the framework for testing a cluster listener * implementation. * * @author Chris Miller */ public abstract class BaseTestBroadcastingListener extends TestCase { /** * The persistance listener used for the tests */ protected static AbstractBroadcastingListener listener = null; /** * A cache instance to use for the tests */ protected static Cache cache = null; /** * The number of tests in this class. This is used to keep * track of how many tests remain; once we reach zero we shut * down the broadcasting listener. */ int testsRemaining = 0; /** * Cache group */ private final String GROUP = "test group"; /** * Object key */ private final String KEY = "Test clustersupport persistence listener key"; public BaseTestBroadcastingListener(String str) { super(str); } /** * Tests the listener by causing the cache to fire off all its * events */ public void testListener() { CacheEntry entry = new CacheEntry(KEY, null); cache.putInCache(KEY, entry); cache.putInCache(KEY, entry, new String[] {GROUP}); cache.flushEntry(KEY); cache.flushGroup(GROUP); cache.flushAll(new Date()); // Note that the remove event is not called since it's not exposed. } /** * This method is invoked before each testXXXX methods of the * class. It set up the broadcasting listener required for each test. */ public void setUp() { // At first invocation, create a listener if (listener == null) { testsRemaining = countTestCases(); // This seems to always return 1 even if there are multiple tests? listener = getListener(); assertNotNull(listener); cache = new Cache(true, false, false); assertNotNull(cache); try { listener.initialize(cache, getConfig()); } catch (InitializationException e) { fail(e.getMessage()); } cache.addCacheEventListener(listener); } } /** * Once all the tests are complete this will shut down the broadcasting listener. */ protected void tearDown() throws Exception { if (--testsRemaining == 0) { try { listener.finialize(); listener = null; } catch (FinalizationException e) { fail(e.getMessage()); } } } /** * Child classes implement this to return the broadcasting listener instance * that will be tested. */ abstract AbstractBroadcastingListener getListener(); /** * Child classes implement this to return the configuration for their listener * @return */ abstract Config getConfig(); } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/TestJMSBroadcastingListener.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/TestJMSBroadcasting0000644000175000017500000000364210263555404034007 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.clustersupport; import com.opensymphony.oscache.base.Config; import junit.framework.Test; import junit.framework.TestSuite; /** * Test all the public methods of the broadcasting listener and assert the * return values * * @author Chris Miller */ public final class TestJMSBroadcastingListener extends BaseTestBroadcastingListener { public TestJMSBroadcastingListener(String str) { super(str); } /** * This methods returns the name of this test class to JUnit. * * @return The test for this class */ public static Test suite() { return new TestSuite(TestJMSBroadcastingListener.class); } /** * Returns a configured JavaGroupsBroadcastingListener instance * for testing. */ public AbstractBroadcastingListener getListener() { return new JMSBroadcastingListener(); } /** * Return the configuration for the JMS listener */ Config getConfig() { Config config = new Config(); // There needs to be an application resource file present "jndi.properties" that contains the following // parameters: // config.set(Context.INITIAL_CONTEXT_FACTORY, "com.evermind.server.ApplicationClientInitialContextFactory"); // config.set(Context.PROVIDER_URL, "ormi://localhost:23791/"); // config.set(Context.SECURITY_PRINCIPAL, "admin"); // config.set(Context.SECURITY_CREDENTIALS, "xxxxxx"); config.set("cache.cluster.jms.topic.factory", "java:comp/env/jms/TopicConnectionFactory"); config.set("cache.cluster.jms.topic.name", "java:comp/env/jms/OSCacheTopic"); config.set("cache.cluster.jms.node.name", "cacheNode1"); return config; } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/TestJavaGroupsBroadcastingListener.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/clustersupport/TestJavaGroupsBroad0000644000175000017500000000261410263555404034064 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.clustersupport; import com.opensymphony.oscache.base.Config; import junit.framework.Test; import junit.framework.TestSuite; /** * Test all the public methods of the broadcasting listener and assert the * return values * * @author Chris Miller */ public final class TestJavaGroupsBroadcastingListener extends BaseTestBroadcastingListener { public TestJavaGroupsBroadcastingListener(String str) { super(str); } /** * This methods returns the name of this test class to JUnit. * * @return The test for this class */ public static Test suite() { return new TestSuite(TestJavaGroupsBroadcastingListener.class); } /** * Returns a configured JavaGroupsBroadcastingListener instance * for testing. */ public AbstractBroadcastingListener getListener() { return new JavaGroupsBroadcastingListener(); } /** * Get the configuration for this listener */ public Config getConfig() { Config config = new Config(); // Just specify the IP and leave the rest of the settings at // default values. config.set("cache.cluster.multicast.ip", "231.12.21.132"); return config; } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/diskpersistence/0000755000175000017500000000000011375310606030324 5ustar twernertwerner././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/diskpersistence/TestDiskPersistenceListener.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/diskpersistence/TestDiskPersistenc0000644000175000017500000001475310577077021034057 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.diskpersistence; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.base.Config; import com.opensymphony.oscache.base.persistence.CachePersistenceException; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import java.io.File; import java.io.FilenameFilter; import java.util.HashSet; import java.util.Properties; import java.util.Set; /** * Test all the public methods of the disk persistance listener and assert the * return values * * $Id: TestDiskPersistenceListener.java 422 2007-03-17 23:47:29Z larst $ * @version $Revision: 422 $ * @author Alain Bergevin */ public final class TestDiskPersistenceListener extends TestCase { /** * Cache dir to persist to */ public static final String CACHEDIR = "/tmp/diskcache"; /** * The persistance listener used for the tests */ private DiskPersistenceListener listener = null; /** * Object content */ private final String CONTENT = "Disk persistance content"; /** * Cache group */ private final String GROUP = "test group"; /** * Object key */ private final String KEY = "Test disk persistance listener key"; private CacheFileFilter cacheFileFilter = new CacheFileFilter(); public TestDiskPersistenceListener(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestDiskPersistenceListener.class); } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // At first invocation, create a listener listener = new DiskPersistenceListener(); Properties p = new Properties(); p.setProperty("cache.path", CACHEDIR); p.setProperty("cache.memory", "false"); p.setProperty("cache.persistence.class", "com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener"); listener.configure(new Config(p)); } /** * Test the cache directory removal */ public void testClear() { // Create an new element since we removed it at the last test testStoreRetrieve(); // Remove the directory, and assert that we have no more entry try { listener.clear(); assertTrue(!listener.isStored(KEY)); } catch (CachePersistenceException cpe) { cpe.printStackTrace(); fail("Exception thrown in test clear!"); } } /** * Test that the previouly created file exists */ public void testIsStored() { try { listener.store(KEY, CONTENT); // Retrieve the previously created file assertTrue(listener.isStored(KEY)); // Check that the fake key returns false assertTrue(!listener.isStored(KEY + "fake")); } catch (Exception e) { e.printStackTrace(); fail("testIsStored raised an exception"); } } /** * Test the cache removal */ public void testRemove() { // Create an entry if it doesn't exists try { if (!listener.isStored(KEY)) { listener.store(KEY, CONTENT); } // Remove the previously created file listener.remove(KEY); } catch (CachePersistenceException cpe) { cpe.printStackTrace(); fail("Exception thrown in test remove!"); } } /** * Force CachePersistenceException to get a 100% in the unit test */ public void testCachePersistenceException() { try { for (int i = 0; i < 2; i++) { if (i == 1) throw new CachePersistenceException("test"); } fail("CachePersistenceException not thrown!"); } catch (CachePersistenceException cpe) { // ignore } try { for (int i = 0; i < 2; i++) { if (i == 1) throw new CachePersistenceException(); } fail("CachePersistenceException not thrown!"); } catch (CachePersistenceException cpe) { // ignore } } /** * Test the disk store and retrieve */ public void testStoreRetrieve() { // Create a cache entry and store it CacheEntry entry = new CacheEntry(KEY); entry.setContent(CONTENT); try { listener.store(KEY, entry); // Retrieve our entry and validate the values CacheEntry newEntry = (CacheEntry) listener.retrieve(KEY); assertTrue(entry.getContent().equals(newEntry.getContent())); assertEquals(entry.getCreated(), newEntry.getCreated()); assertTrue(entry.getKey().equals(newEntry.getKey())); // Try to retrieve a non-existent object assertNull(listener.retrieve("doesn't exist")); } catch (Exception ex) { ex.printStackTrace(); fail("Exception raised!"); } } /** * Test the storing and retrieving of groups */ public void testStoreRetrieveGroups() { // Store a group Set groupSet = new HashSet(); groupSet.add("1"); groupSet.add("2"); try { listener.storeGroup(GROUP, groupSet); // Retrieve it and validate its contents groupSet = listener.retrieveGroup(GROUP); assertNotNull(groupSet); assertTrue(groupSet.contains("1")); assertTrue(groupSet.contains("2")); assertFalse(groupSet.contains("3")); // Try to retrieve a non-existent group assertNull(listener.retrieveGroup("abc")); } catch (Exception ex) { ex.printStackTrace(); fail("Exception raised!"); } } protected void tearDown() throws Exception { listener.clear(); assertTrue("Cache not cleared", new File(CACHEDIR).list(cacheFileFilter).length == 0); } private static class CacheFileFilter implements FilenameFilter { public boolean accept(File dir, String name) { return !"__groups__".equals(name); } } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/diskpersistence/TestUnSerializable.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/diskpersistence/TestUnSerializable0000644000175000017500000000544110254455232034024 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ /* * Created on Mar 11, 2005 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package com.opensymphony.oscache.plugins.diskpersistence; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import java.io.File; /** * @author admin * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class TestUnSerializable extends TestCase { final String CACHE_DIRECTORY_PATH = TestDiskPersistenceListener.CACHEDIR + "/application"; GeneralCacheAdministrator cache; /* (non-Javadoc) * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { // TODO Auto-generated method stub super.setUp(); java.util.Properties properties = new java.util.Properties(); properties.setProperty("cache.path", TestDiskPersistenceListener.CACHEDIR); properties.setProperty("cache.persistence.class", "com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener"); properties.setProperty("cache.persistence.overflow.only", "true"); // properties.setProperty("cache.memory", "false"); properties.setProperty("cache.capacity", "2"); properties.setProperty("cache.unlimited.disk", "false"); cache = new GeneralCacheAdministrator(properties); cache.getCache().getPersistenceListener().clear(); } /* (non-Javadoc) * @see junit.framework.TestCase#tearDown() */ protected void tearDown() throws Exception { // TODO Auto-generated method stub super.tearDown(); } public void testNotSerializableObject() throws Exception { cache.putInCache("1", new UnSerializable()); cache.putInCache("2", new UnSerializable()); assertTrue(isDirectoryEmpty(CACHE_DIRECTORY_PATH)); cache.putInCache("3", new UnSerializable()); cache.putInCache("4", new UnSerializable()); assertTrue(isDirectoryEmpty(CACHE_DIRECTORY_PATH)); cache.flushAll(); } /** * @param filePath * @return */ private boolean isDirectoryEmpty(String filePath) { File file = new File(filePath); return !file.exists() || (file.list().length == 0); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestUnSerializable.class); } public static class UnSerializable { int asdfasdfasdf = 234; } } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/diskpersistence/TestCompleteDiskPersistence.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/diskpersistence/TestCompleteDiskPe0000644000175000017500000000332010576756253033773 0ustar twernertwerner/* * Copyright (c) 2002-2007 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.diskpersistence; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test class for the com.opensymphony.oscache.plugins.diskpersistence package. * It invokes all the test suites of all the other classes of the package. * * $Id: TestCompleteDiskPersistence.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Lars Torunski */ public final class TestCompleteDiskPersistence extends TestCase { /** * Constructor for the osCache Cache Extra package main test program */ public TestCompleteDiskPersistence(String str) { super(str); } /** * Main method which is called to perform the tests *

* @param args Arguments received */ public static void main(String[] args) { // Run the test suite junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner(); testRunner.setLoading(false); String[] args2 = {TestCompleteDiskPersistence.class.getName()}; testRunner.start(args2); } /** * Test suite required to test this project *

* @return suite The test suite */ public static Test suite() { // Add all the test suites of all the project classes TestSuite suite = new TestSuite("Test all diskpersistence plugins"); suite.addTest(TestDiskPersistenceListener.suite()); suite.addTest(TestHashDiskPersistenceListener.suite()); //suite.addTest(TestUnSerializable.suite()); return suite; } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/diskpersistence/TestHashDiskPersistenceListener.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/plugins/diskpersistence/TestHashDiskPersis0000644000175000017500000001605310575626726034016 0ustar twernertwerner/* * Copyright (c) 2002-2007 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.diskpersistence; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.base.Config; import com.opensymphony.oscache.base.persistence.CachePersistenceException; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import java.io.File; import java.io.FilenameFilter; import java.util.HashSet; import java.util.Properties; import java.util.Set; /** * Test all the public methods of the disk persistance listener and assert the * return values * * $Id: TestHashDiskPersistenceListener.java 413 2007-03-13 23:03:50Z larst $ * @version $Revision: 413 $ * @author Alain Bergevin */ public final class TestHashDiskPersistenceListener extends TestCase { /** * The persistance listener used for the tests */ private HashDiskPersistenceListener listener = null; /** * Object content */ private final String CONTENT = "Disk persistance content"; /** * Cache group */ private final String GROUP = "test group"; /** * Object key */ private final String KEY = "Test disk persistance listener key"; private CacheFileFilter cacheFileFilter = new CacheFileFilter(); public TestHashDiskPersistenceListener(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestHashDiskPersistenceListener.class); } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // At first invocation, create a listener listener = new HashDiskPersistenceListener(); Properties p = new Properties(); p.setProperty("cache.path", TestDiskPersistenceListener.CACHEDIR); p.setProperty("cache.memory", "false"); p.setProperty("cache.persistence.class", "com.opensymphony.oscache.plugins.diskpersistence.HashDiskPersistenceListener"); p.setProperty("cache.persistence.disk.hash.algorithm", "MD5"); listener.configure(new Config(p)); } /** * Test the cache directory removal */ public void testClear() { // Create an new element since we removed it at the last test testStoreRetrieve(); // Remove the directory, and assert that we have no more entry try { listener.clear(); assertTrue(!listener.isStored(KEY)); } catch (CachePersistenceException cpe) { cpe.printStackTrace(); fail("Exception thrown in test clear!"); } } /** * Test that the previouly created file exists */ public void testIsStored() { try { listener.store(KEY, CONTENT); // Retrieve the previously created file assertTrue(listener.isStored(KEY)); // Check that the fake key returns false assertTrue(!listener.isStored(KEY + "fake")); } catch (Exception e) { e.printStackTrace(); fail("testIsStored raised an exception"); } } /** * Test the cache removal */ public void testRemove() { // Create an entry if it doesn't exists try { if (!listener.isStored(KEY)) { listener.store(KEY, CONTENT); } // Remove the previously created file listener.remove(KEY); } catch (CachePersistenceException cpe) { cpe.printStackTrace(); fail("Exception thrown in test remove!"); } } /** * Test the disk store and retrieve */ public void testStoreRetrieve() { // Create a cache entry and store it CacheEntry entry = new CacheEntry(KEY); entry.setContent(CONTENT); try { listener.store(KEY, entry); // Retrieve our entry and validate the values CacheEntry newEntry = (CacheEntry) listener.retrieve(KEY); assertTrue(entry.getContent().equals(newEntry.getContent())); assertEquals(entry.getCreated(), newEntry.getCreated()); assertTrue(entry.getKey().equals(newEntry.getKey())); // Try to retrieve a non-existent object assertNull(listener.retrieve("doesn't exist")); } catch (Exception ex) { ex.printStackTrace(); fail("Exception raised!"); } } /** * Test the storing and retrieving of groups */ public void testStoreRetrieveGroups() { // Store a group Set groupSet = new HashSet(); groupSet.add("1"); groupSet.add("2"); try { listener.storeGroup(GROUP, groupSet); // Retrieve it and validate its contents groupSet = listener.retrieveGroup(GROUP); assertNotNull(groupSet); assertTrue(groupSet.contains("1")); assertTrue(groupSet.contains("2")); assertFalse(groupSet.contains("3")); // Try to retrieve a non-existent group assertNull(listener.retrieveGroup("abc")); } catch (Exception ex) { ex.printStackTrace(); fail("Exception raised!"); } } private static final byte[] BYTES_1 = {0x00}; private static final byte[] BYTES_2 = {0x00, 0x00}; private static final byte[] BYTES_3 = {0x00, 0x00, 0x00}; private static final byte[] BYTES_4 = {0x01}; /** * Test against bug issue CACHE-288. */ public void testByteArrayToHexString() { assertFalse("ByteArrayToHexStrings 1 and 2 shouldn't be equal", HashDiskPersistenceListener.byteArrayToHexString(BYTES_1). equals(HashDiskPersistenceListener.byteArrayToHexString(BYTES_2))); assertFalse("ByteArrayToHexStrings 1 and 3 shouldn't be equal", HashDiskPersistenceListener.byteArrayToHexString(BYTES_1). equals(HashDiskPersistenceListener.byteArrayToHexString(BYTES_3))); assertFalse("ByteArrayToHexStrings 1 and 4 shouldn't be equal", HashDiskPersistenceListener.byteArrayToHexString(BYTES_1). equals(HashDiskPersistenceListener.byteArrayToHexString(BYTES_4))); assertFalse("ByteArrayToHexStrings 1 and 4 shouldn't be equal", HashDiskPersistenceListener.byteArrayToHexString(BYTES_1). equals(HashDiskPersistenceListener.byteArrayToHexString(BYTES_4))); } protected void tearDown() throws Exception { listener.clear(); assertTrue("Cache not cleared", new File(TestDiskPersistenceListener.CACHEDIR).list(cacheFileFilter).length == 0); } private static class CacheFileFilter implements FilenameFilter { public boolean accept(File dir, String name) { return !"__groups__".equals(name); } } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/0000755000175000017500000000000011375310606024356 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/events/0000755000175000017500000000000011375310606025662 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/events/TestCompleteEvents.java0000644000175000017500000000340210576763237032337 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.events; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test class for the com.opensymphony.oscache.base.events package. * It invokes all the test suites of all the other classes of the package. * * $Id: TestCompleteEvents.java 419 2007-03-17 13:01:19Z larst $ * @version $Revision: 419 $ * @author Alain Bergevin */ public final class TestCompleteEvents extends TestCase { /** * Constructor for the oscache module main test program */ public TestCompleteEvents(String str) { super(str); } /** * Main method which is called to perform the tests *

* @param args Arguments received */ public static void main(String[] args) { // Run the test suite junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner(); testRunner.setLoading(false); String[] args2 = {TestCompleteEvents.class.getName()}; testRunner.start(args2); } /** * Test suite required to test this project *

* @return suite The test suite */ public static Test suite() { // Add all the tests suite of all the project classes TestSuite suite = new TestSuite("Test all base cache modules"); suite.addTest(TestCacheEntryEvent.suite()); suite.addTest(TestCacheMapAccessEvent.suite()); suite.addTest(TestScopeEvent.suite()); suite.addTest(TestCachewideEvent.suite()); suite.addTest(TestCachePatternEvent.suite()); suite.addTest(TestCacheGroupEvent.suite()); return suite; } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/events/TestCacheGroupEvent.java0000644000175000017500000000413010576763337032424 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.events; import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * This is the test class for the CacheGroupEvent class. It checks that the * public methods are working properly * * $Id: TestCacheEntryEvent.java 385 2006-10-07 06:57:10Z larst $ * @version $Revision: 385 $ * @author Lars Torunski */ public final class TestCacheGroupEvent extends TestCase { /** * Constants required for the test */ private final String TEST_GROUP = "testGroup"; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestCacheGroupEvent(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestCacheGroupEvent.class); } /** * Test the CacheEntryEvent class */ public void testCacheEntryEvent() { // Create all the required objects GeneralCacheAdministrator admin = new GeneralCacheAdministrator(); Cache map = new Cache(admin.isMemoryCaching(), admin.isUnlimitedDiskCache(), admin.isOverflowPersistence()); // three parameters CacheGroupEvent event = new CacheGroupEvent(map, TEST_GROUP, null); // Get back the values and assert them assertEquals(event.getMap(), map); assertEquals(event.getGroup(), TEST_GROUP); assertNull(event.getOrigin()); // two parameters CachePatternEvent event2 = new CachePatternEvent(map, TEST_GROUP); // Get back the values and assert them assertEquals(event2.getMap(), map); assertEquals(event.getGroup(), TEST_GROUP); assertNull(event2.getOrigin()); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/events/TestCachewideEvent.java0000644000175000017500000000304610576763237032264 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.events; import java.util.Date; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * This is the test class for the CachewideEvent class. It checks that the * public methods are working properly * * $Id: TestCacheEntryEvent.java 385 2006-10-07 06:57:10Z larst $ * @version $Revision: 385 $ * @author Lars Torunski */ public final class TestCachewideEvent extends TestCase { /** * Constructor *

* @param str The test name (required by JUnit) */ public TestCachewideEvent(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestCachewideEvent.class); } /** * Test the CacheEntryEvent class */ public void testCacheEntryEvent() { // Create all the required objects GeneralCacheAdministrator admin = new GeneralCacheAdministrator(); Date date = new Date(); CachewideEvent event = new CachewideEvent(admin.getCache(), date, null); // Get back the values and assert them assertEquals(event.getDate(), date); assertEquals(event.getCache(), admin.getCache()); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/events/TestScopeEvent.java0000644000175000017500000000325510254455232031445 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.events; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import java.util.Date; /** * This is the test class for the ScopeEvent class. It checks that the * public methods are working properly * * $Id: TestScopeEvent.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Alain Bergevin */ public final class TestScopeEvent extends TestCase { private final int SCOPE = 3; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestScopeEvent(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestScopeEvent.class); } /** * Test the ScopeEvent class */ public void testScopeEvent() { Date date = new Date(); // Create an object and check the parameters ScopeEvent event = new ScopeEvent(ScopeEventType.ALL_SCOPES_FLUSHED, SCOPE, date, null); assertEquals(event.getEventType(), ScopeEventType.ALL_SCOPES_FLUSHED); assertEquals(event.getScope(), SCOPE); assertTrue(event.getDate().equals(date)); event = new ScopeEvent(ScopeEventType.SCOPE_FLUSHED, SCOPE, date, null); assertEquals(event.getEventType(), ScopeEventType.SCOPE_FLUSHED); assertEquals(event.getScope(), SCOPE); assertTrue(event.getDate().equals(date)); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/events/TestCacheMapAccessEvent.java0000644000175000017500000000307410254455232033156 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.events; import com.opensymphony.oscache.base.CacheEntry; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * This is the test class for the CacheMapAccessEvent class. It checks that the * public methods are working properly * * $Id: TestCacheMapAccessEvent.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Alain Bergevin */ public final class TestCacheMapAccessEvent extends TestCase { private final String KEY = "Test cache map access event key"; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestCacheMapAccessEvent(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestCacheMapAccessEvent.class); } /** * Test the CacheMapAccessEvent class */ public void testCacheMapAccessEvent() { // Create an object and check the parameters CacheEntry entry = new CacheEntry(KEY); CacheMapAccessEvent event = new CacheMapAccessEvent(CacheMapAccessEventType.HIT, entry); assertEquals(event.getCacheEntry(), entry); assertEquals(event.getCacheEntryKey(), KEY); assertEquals(event.getEventType(), CacheMapAccessEventType.HIT); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/events/TestCacheEntryEvent.java0000644000175000017500000000450510576763237032436 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.events; import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * This is the test class for the CacheEntryEvent class. It checks that the * public methods are working properly * * $Id: TestCacheEntryEvent.java 419 2007-03-17 13:01:19Z larst $ * @version $Revision: 419 $ * @author Alain Bergevin */ public final class TestCacheEntryEvent extends TestCase { /** * Constants required for the test */ private final String KEY = "Test cache entry event key"; private final String KEY_2 = "Test cache entry event key 2"; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestCacheEntryEvent(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestCacheEntryEvent.class); } /** * Test the CacheEntryEvent class */ public void testCacheEntryEvent() { // Create all the required objects GeneralCacheAdministrator admin = new GeneralCacheAdministrator(); Cache map = new Cache(admin.isMemoryCaching(), admin.isUnlimitedDiskCache(), admin.isOverflowPersistence()); // test with key CacheEntry entry = new CacheEntry(KEY); CacheEntryEvent event = new CacheEntryEvent(map, entry, null); // Get back the values and assert them assertEquals(event.getEntry(), entry); assertEquals(event.getKey(), KEY); assertEquals(event.getMap(), map); assertNull(event.getOrigin()); CacheEntry entry2 = new CacheEntry(KEY_2); CacheEntryEvent event2 = new CacheEntryEvent(map, entry2); // Get back the values and assert them assertEquals(event2.getEntry(), entry2); assertEquals(event2.getKey(), KEY_2); assertEquals(event2.getMap(), map); assertNull(event2.getOrigin()); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/events/TestCachePatternEvent.java0000644000175000017500000000416410576763237032753 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.events; import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * This is the test class for the CachePatternEvent class. It checks that the * public methods are working properly * * $Id: TestCacheEntryEvent.java 385 2006-10-07 06:57:10Z larst $ * @version $Revision: 385 $ * @author Lars Torunski */ public final class TestCachePatternEvent extends TestCase { /** * Constants required for the test */ private final String TEST_PATTERN = "testPattern"; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestCachePatternEvent(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestCachePatternEvent.class); } /** * Test the CacheEntryEvent class */ public void testCacheEntryEvent() { // Create all the required objects GeneralCacheAdministrator admin = new GeneralCacheAdministrator(); Cache map = new Cache(admin.isMemoryCaching(), admin.isUnlimitedDiskCache(), admin.isOverflowPersistence()); // three parameters CachePatternEvent event = new CachePatternEvent(map, TEST_PATTERN, null); // Get back the values and assert them assertEquals(event.getMap(), map); assertEquals(event.getPattern(), TEST_PATTERN); assertNull(event.getOrigin()); // two parameters CachePatternEvent event2 = new CachePatternEvent(map, TEST_PATTERN); // Get back the values and assert them assertEquals(event2.getMap(), map); assertEquals(event.getPattern(), TEST_PATTERN); assertNull(event2.getOrigin()); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/GroupConcurrencyProblemTestCase.java0000644000175000017500000000275010254455232033511 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.TestCase; /** * DOCUMENT ME! * * @author $author$ * @version $Revision: 254 $ */ public class GroupConcurrencyProblemTestCase extends TestCase { private static GeneralCacheAdministrator cache = new GeneralCacheAdministrator(); public static void main(String[] args) { System.out.println("START"); // Create some clients and start them running. for (int i = 0; i < 100; i++) { System.out.println("Creating thread: " + i); new Client(i, cache).start(); } System.out.println("END"); } } /* Inner class to hammer away at the cache. */ class Client extends Thread { private static final int MAX_ITERATIONS = 1000; private GeneralCacheAdministrator cache; private int id; public Client(int newId, GeneralCacheAdministrator newCache) { super(); id = newId; cache = newCache; } public void run() { for (int i = 0; i < MAX_ITERATIONS; i++) { /* Put an entry from this Client into the shared group. */ cache.putInCache(Integer.toString(id), "Some interesting data", new String[] { "GLOBAL_GROUP" }); // Flush that group. cache.flushGroup("GLOBAL_GROUP"); } } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/algorithm/0000755000175000017500000000000011375310606026344 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/algorithm/TestFIFOCache.java0000644000175000017500000000350610254455232031522 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.algorithm; import junit.framework.Test; import junit.framework.TestSuite; /** * Test class for the FIFOCache class. It tests that the algorithm reacts as * expected when entries are removed * * $Id: TestFIFOCache.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Alain Bergevin */ public final class TestFIFOCache extends TestQueueCache { /** * FIFO Cache object */ private static FIFOCache cache = null; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestFIFOCache(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestFIFOCache.class); } /** * Abstract method used by the TestAbstractCache class *

* @return A cache instance */ public AbstractConcurrentReadCache getCache() { return cache; } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // Create a cache instance on first invocation if (cache == null) { cache = new FIFOCache(); assertNotNull(cache); } } /** * Test the cache algorithm */ public void testRemoveItem() { // Add 2 elements in the cache and ensure that the one to remove is the first // inserted cache.itemPut(KEY); cache.itemPut(KEY + 1); assertTrue(KEY.equals(cache.removeItem())); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/algorithm/TestLRUCache.java0000644000175000017500000000405410254455232031440 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.algorithm; import junit.framework.Test; import junit.framework.TestSuite; /** * Test class for the LRUCache class. It only tests that the algorithm reacts as * expected when entries are removed. All the other tests related to the LRU * algorithm are in the TestNonQueueCache class, since those tests are shared * with the TestUnlimitedCache class. * * $Id: TestLRUCache.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Alain Bergevin */ public final class TestLRUCache extends TestQueueCache { /** * LRU Cache object */ private static LRUCache cache = null; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestLRUCache(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestLRUCache.class); } /** * Abstract method used by the TestAbstractCache class *

* @return A cache instance */ public AbstractConcurrentReadCache getCache() { return cache; } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // Create a cache instance on first invocation if (cache == null) { cache = new LRUCache(); assertNotNull(cache); } } /** * Test the cache algorithm */ public void testRemoveItem() { // Add 3 elements cache.itemPut(KEY); cache.itemPut(KEY + 1); cache.itemPut(KEY + 2); // Get the last element cache.itemRetrieved(KEY); // The least recently used item is key + 1 assertTrue((KEY + 1).equals(cache.removeItem())); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/algorithm/TestCompleteAlgorithm.java0000644000175000017500000000326410254455232033473 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.algorithm; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test class for the com.opensymphony.oscache.base.algorithm package. * It invokes all the test suites of all the other classes of the package, * except abstract ones because they are tested via final ones. * * $Id: TestCompleteAlgorithm.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Alain Bergevin */ public final class TestCompleteAlgorithm extends TestCase { /** * Constructor for the oscache project main test program */ public TestCompleteAlgorithm(String str) { super(str); } /** * Main method which is called to perform the tests *

* @param args Arguments received */ public static void main(String[] args) { // Run the test suite junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner(); testRunner.setLoading(false); String[] args2 = {TestCompleteAlgorithm.class.getName()}; testRunner.start(args2); } /** * Test suite required to test this project *

* @return suite The test suite */ public static Test suite() { // Add all the tests suite of all the project classes TestSuite suite = new TestSuite("Test all base algorithm cache modules"); suite.addTest(TestFIFOCache.suite()); suite.addTest(TestLRUCache.suite()); suite.addTest(TestUnlimitedCache.suite()); return suite; } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/algorithm/TestUnlimitedCache.java0000644000175000017500000000503210444305145032723 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.algorithm; import junit.framework.Test; import junit.framework.TestSuite; /** * Test class for the Unlimited cache algorithm. Most of the tests are done * in the TestNonQueueCache class, so only algorithm specific tests are done * here. Since this is an unlimited cache, there's not much to test about * the algorithm. * * $Id: TestUnlimitedCache.java 365 2006-06-15 16:27:17Z ltorunski $ * @version $Revision: 365 $ * @author Alain Bergevin */ public final class TestUnlimitedCache extends TestQueueCache { /** * Unlimited Cache object */ private static UnlimitedCache cache = null; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestUnlimitedCache(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The test for this class */ public static Test suite() { return new TestSuite(TestUnlimitedCache.class); } /** * Abstract method used by the TestAbstractCache class *

* @return A cache instance */ public AbstractConcurrentReadCache getCache() { return cache; } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // Create a cache instance on first invocation if (cache == null) { cache = new UnlimitedCache(); assertNotNull(cache); } } /** * Test the getter and setter for the max entries. It overrides the TestQueueCache * one since it shouldn't have any effect in unlimited cache */ public void testGetSetMaxEntries() { // Check that the max entries cannot be changed int entryCount = getCache().getMaxEntries(); getCache().setMaxEntries(entryCount - 1); assertEquals(entryCount, getCache().getMaxEntries()); } /** * Test the cache algorithm */ public void testRemoveItem() { // Add an item, and ensure that it is not removable cache.itemPut(KEY); assertNull(cache.removeItem()); } /** * Test that groups are correctly updated on puts and removes */ public void testGroups() { // test not possible, because can't reduce cache max entries for this test } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/algorithm/TestAbstractCache.java0000644000175000017500000001670010577205037032546 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.algorithm; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Set; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.base.Config; import com.opensymphony.oscache.base.persistence.CachePersistenceException; import com.opensymphony.oscache.base.persistence.PersistenceListener; import junit.framework.TestCase; /** * Test class for the AbstractCache class. It tests all public methods of * the AbstractCache and assert the results. It is design to run under JUnit. * * $Id: TestAbstractCache.java 425 2007-03-18 09:45:03Z larst $ * @version $Revision: 425 $ * @author Alain Bergevin */ public abstract class TestAbstractCache extends TestCase { /** * Invalid cache capacity */ protected final int INVALID_MAX_ENTRIES = 0; /** * Cache capacity */ protected final int MAX_ENTRIES = 3; /** * Constructor *

* @param str The test name (required by JUnit) */ protected TestAbstractCache(String str) { super(str); } /** * Test the method that verify if the cache contains a specific key */ public abstract void testContainsKey(); /** * Test the get from the cache */ public abstract void testGet(); /** * Test the capacity setting */ public void testGetSetMaxEntries() { getCache().setMaxEntries(MAX_ENTRIES); assertEquals(MAX_ENTRIES, getCache().getMaxEntries()); // Specify an invalid capacity try { getCache().setMaxEntries(INVALID_MAX_ENTRIES); fail("Cache capacity set with an invalid argument"); } catch (Exception e) { // This is what we expect } } /** * Test the setting of the memory cache */ public void testGetSetMemoryCache() { getCache().setMemoryCaching(true); assertTrue(getCache().isMemoryCaching()); } /** * Test the iterator retrieval */ public abstract void testIterator(); /** * Test the put into the cache */ public abstract void testPut(); /** * Test the remove from the cache */ public abstract void testRemove(); /** * Test the specific details about the cache algorithm */ public abstract void testRemoveItem(); /** * Test the PersistenceListener setter. Since the persistance listener is * an interface, just call the setter with null */ public void testSetPersistenceListener() { getCache().setPersistenceListener(null); } // Abstract method that returns an instance of an admin protected abstract AbstractConcurrentReadCache getCache(); /** * Test that groups are correctly updated on puts and removes * See CACHE-188 and maybe CACHE-244 */ public void testGroups() { String KEY = "testkey"; String KEY2 = "testkey2"; String GROUP_NAME = "group1"; CacheEntry entry = new CacheEntry(KEY, null); entry.setContent("testvalue"); entry.setGroups(new String[] {GROUP_NAME}); getCache().put(KEY, entry); Map m = getCache().getGroupsForReading(); assertNotNull("group must exist", m.get(GROUP_NAME)); try { Set group = (Set)m.get(GROUP_NAME); assertEquals(1, group.size()); Object keyFromGroup = group.iterator().next(); assertEquals(KEY, keyFromGroup); } catch (ClassCastException e) { fail("group should have been a java.util.Set but is a " + m.get(GROUP_NAME).getClass().getName()); } assertNotNull(getCache().remove(KEY)); m = getCache().getGroupsForReading(); assertNull("group should have been deleted (see CACHE-188)", m.get(GROUP_NAME)); getCache().clear(); // Test if persistence options are correctly considered for groups try { PersistenceListener listener = new MockPersistenceListener(); getCache().setPersistenceListener(listener); getCache().setOverflowPersistence(false); getCache().put(KEY, entry); assertTrue(listener.isStored(KEY)); Set group = listener.retrieveGroup(GROUP_NAME); assertNotNull(group); assertTrue(group.contains(KEY)); getCache().remove(KEY); assertFalse(listener.isStored(KEY)); getCache().clear(); // test overflow persistence getCache().setOverflowPersistence(true); getCache().setMaxEntries(1); getCache().put(KEY, entry); assertFalse(listener.isStored(KEY)); // is it correct that the group is persisted, even when we use overflow only? // assertFalse(listener.isGroupStored(GROUP_NAME)); CacheEntry entry2 = new CacheEntry(KEY2); entry2.setContent("testvalue"); entry2.setGroups(new String[] {GROUP_NAME}); getCache().put(KEY2, entry2); // oldest must have been persisted to disk: assertTrue(listener.isStored(KEY)); assertFalse(listener.isStored(KEY2)); assertNotNull(getCache().get(KEY2)); } catch (CachePersistenceException e) { e.printStackTrace(); fail("Excpetion was thrown"); } } public void testMisc() { getCache().clear(); assertTrue(getCache().capacity() > 0); final String KEY = "testkeymisc"; final String CONTENT = "testkeymisc"; CacheEntry entry = new CacheEntry(KEY, null); entry.setContent(CONTENT); if (getCache().contains(entry) == false) { getCache().put(KEY, entry); } assertTrue(getCache().contains(entry)); CacheEntry entry2 = new CacheEntry(KEY+"2", null); entry.setContent(CONTENT+"2"); getCache().put(entry2.getKey(), entry2); Enumeration enumeration = getCache().elements(); assertTrue(enumeration.hasMoreElements()); while (enumeration.hasMoreElements()) enumeration.nextElement(); } private static class MockPersistenceListener implements PersistenceListener { private Map entries = new HashMap(); private Map groups = new HashMap(); public void clear() throws CachePersistenceException { entries.clear(); groups.clear(); } public PersistenceListener configure(Config config) { return this; } public boolean isGroupStored(String groupName) throws CachePersistenceException { return groups.containsKey(groupName); } public boolean isStored(String key) throws CachePersistenceException { return entries.containsKey(key); } public void remove(String key) throws CachePersistenceException { entries.remove(key); } public void removeGroup(String groupName) throws CachePersistenceException { groups.remove(groupName); } public Object retrieve(String key) throws CachePersistenceException { return entries.get(key); } public Set retrieveGroup(String groupName) throws CachePersistenceException { return (Set)groups.get(groupName); } public void store(String key, Object obj) throws CachePersistenceException { entries.put(key, obj); } public void storeGroup(String groupName, Set group) throws CachePersistenceException { groups.put(groupName, group); } } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/algorithm/TestQueueCache.java0000644000175000017500000001531610501105341032051 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base.algorithm; import com.opensymphony.oscache.base.Config; import com.opensymphony.oscache.base.persistence.PersistenceListener; import com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener; import com.opensymphony.oscache.plugins.diskpersistence.TestDiskPersistenceListener; import java.util.Iterator; import java.util.Properties; /** * Test class for the QueueCache class, which is the base class for FIFO * and LIFO algorithm classes. All the public methods of QueueCache are tested * here. * * $Id: TestQueueCache.java 383 2006-09-10 22:00:01Z larst $ * @version $Revision: 383 $ * @author Alain Bergevin */ public abstract class TestQueueCache extends TestAbstractCache { /** * Entry content */ protected final String CONTENT = "Test Queue Cache content"; /** * Entry key */ protected final String KEY = "Test Queue Cache key"; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestQueueCache(String str) { super(str); } /** * Test the specific algorithms */ public abstract void testRemoveItem(); /** * Test the clear */ public void testClear() { getCache().clear(); assertEquals(0, getCache().size()); } /** * Test the ContainsKey method */ public void testContainsKey() { getCache().put(KEY, CONTENT); assertTrue(getCache().containsKey(KEY)); getCache().clear(); } /** * Test the get method */ public void testGet() { // Add an entry and verify that it is there getCache().put(KEY, CONTENT); assertTrue(getCache().get(KEY).equals(CONTENT)); // Call with invalid parameters try { getCache().get(null); fail("Get called with null parameters!"); } catch (Exception e) { /* This is what we expect */ } getCache().clear(); } /** * Test the getter and setter for the max entries */ public void testGetSetMaxEntries() { // Check that the cache is full, then chop it by one and assert that // an element has been removed for (int count = 0; count < MAX_ENTRIES; count++) { getCache().put(KEY + count, CONTENT + count); } assertEquals(MAX_ENTRIES, getCache().size()); getCache().setMaxEntries(MAX_ENTRIES - 1); assertEquals(MAX_ENTRIES - 1, getCache().getMaxEntries()); assertEquals(MAX_ENTRIES - 1, getCache().size()); // Specify an invalid capacity try { getCache().setMaxEntries(INVALID_MAX_ENTRIES); fail("Cache capacity set with an invalid argument"); } catch (Exception e) { // This is what we expect } getCache().clear(); } /** * Test the iterator */ public void testIterator() { // Verify that the iterator returns MAX_ENTRIES and no more elements int nbEntries = getCache().size(); Iterator iterator = getCache().entrySet().iterator(); assertNotNull(iterator); for (int count = 0; count < nbEntries; count++) { assertNotNull(iterator.next()); } assertTrue(!iterator.hasNext()); } /** * Test the put method */ public void testPut() { // Put elements in cache for (int count = 0; count < MAX_ENTRIES; count++) { getCache().put(KEY + count, CONTENT + count); } // Call with invalid parameters try { getCache().put(null, null); fail("Put called with null parameters!"); } catch (Exception e) { /* This is what we expect */ } getCache().clear(); } /** * Test the put method with overflow parameter set */ public void testPutOverflow() { // Create a listener PersistenceListener listener = new DiskPersistenceListener(); Properties p = new Properties(); p.setProperty("cache.path", TestDiskPersistenceListener.CACHEDIR); p.setProperty("cache.memory", "true"); p.setProperty("cache.persistence.overflow.only", "true"); p.setProperty("cache.persistence.class", "com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener"); listener.configure(new Config(p)); getCache().setPersistenceListener(listener); getCache().clear(); getCache().setMaxEntries(MAX_ENTRIES); getCache().setOverflowPersistence(true); if (getCache() instanceof UnlimitedCache) { return; // nothing to test since memory will never overflow. } // Put elements in cache for (int count = 0; count <= MAX_ENTRIES; count++) { getCache().put(KEY + count, CONTENT + count); } try { int numPersisted = 0; // Check that number of elements persisted == 1 if it is an overflow cache or all // if it is not overflow and writes every time. for (int count = 0; count <= MAX_ENTRIES; count++) { if (getCache().getPersistenceListener().isStored(KEY + count)) { numPersisted++; } } if (getCache().isOverflowPersistence()) { assertTrue("Only 1 element should have been persisted ", numPersisted == 1); } else { assertTrue("All elements should have been persisted ", numPersisted == (MAX_ENTRIES + 1)); } } catch (Exception e) { fail(); } getCache().clear(); } /** * Test if bug CACHE-255 disappeared. */ public void testBugCache255() { if (!getCache().isMemoryCaching()) { return; // nothing to test since memory won't be used. } if (getCache() instanceof UnlimitedCache) { return; // nothing to test since memory will never overflow. } // fill up the cache for (int count = 0; count < MAX_ENTRIES; count++) { getCache().put(KEY + count, CONTENT + count); } // get the old value Object oldValue = getCache().put(KEY + MAX_ENTRIES, CONTENT + MAX_ENTRIES); assertEquals("Evicted object content should be the same", CONTENT + "0", oldValue); getCache().clear(); } /** * Test the remove from cache */ public void testRemove() { getCache().put(KEY, CONTENT); // Remove the object and assert the return assertNotNull(getCache().remove(KEY)); getCache().clear(); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/TestCache.java0000644000175000017500000002302710511647706027075 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base; import java.util.Properties; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.Assert; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test the public methods of the Cache class * * $Id: TestCache.java 385 2006-10-07 06:57:10Z larst $ * @version $Revision: 385 $ * @author Alain Bergevin */ public class TestCache extends TestCase { // Static variables required thru all the tests private static Cache map = null; private final String CONTENT = "Content for the cache test"; // Constants needed thru all the tests private final String ENTRY_KEY = "Test cache key"; private final int NO_REFRESH_NEEDED = CacheEntry.INDEFINITE_EXPIRY; private final int REFRESH_NEEDED = 0; /** * Class constructor. *

* @param str The test name (required by JUnit) */ public TestCache(String str) { super(str); } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // At first invocation, create a new Cache if (map == null) { GeneralCacheAdministrator admin = new GeneralCacheAdministrator(); map = admin.getCache(); assertNotNull(map); } } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestCache.class); } /** * Verify that items may still be flushed by key pattern */ public void testFlushPattern() { // Try to flush with a bad pattern and ensure that our data is still there map.putInCache(ENTRY_KEY, CONTENT); map.flushPattern(ENTRY_KEY + "do not flush"); getBackContent(map, CONTENT, NO_REFRESH_NEEDED, false); // Flush our map for real map.flushPattern(ENTRY_KEY.substring(1, 2)); getBackContent(map, CONTENT, NO_REFRESH_NEEDED, true); // Check invalid values map.flushPattern(""); map.flushPattern(null); } /** * Tests that with a very large amount of keys that added and trigger cache overflows, there is no memory leak * @throws Exception */ public void testBug174CacheOverflow() throws Exception { Properties p = new Properties(); p.setProperty(AbstractCacheAdministrator.CACHE_ALGORITHM_KEY, "com.opensymphony.oscache.base.algorithm.LRUCache"); p.setProperty(AbstractCacheAdministrator.CACHE_CAPACITY_KEY, "100"); GeneralCacheAdministrator admin = new GeneralCacheAdministrator(p); int cacheCapacity = 100; int maxAddedCacheEntries = cacheCapacity*10; String baseCacheKey= "baseKey"; String cacheValue ="same_value"; admin.setCacheCapacity(cacheCapacity); Cache cache = admin.getCache(); //Add lots of different keys to trigger cache overflow for (int keyIndex=0; keyIndex * @param map The Cache in which the data is stored * @param content The content expected to be retrieved * @param refresh Time interval to determine if the cache object needs refresh * @param exceptionExpected Specify if a NeedsRefreshException is expected */ private void getBackContent(Cache map, Object content, int refresh, boolean exceptionExpected) { try { assertEquals(content, map.getFromCache(ENTRY_KEY, refresh)); if (exceptionExpected) { fail("NeedsRefreshException should have been thrown!"); } } catch (NeedsRefreshException nre) { map.cancelUpdate(ENTRY_KEY); if (!exceptionExpected) { fail("NeedsRefreshException shouldn't have been thrown!"); } } } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/TestCacheEntry.java0000644000175000017500000001005710254455232030111 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test the public methods of the CacheEntry class * * $Id: TestCacheEntry.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Alain Bergevin */ public class TestCacheEntry extends TestCase { // Static variables required thru the tests static CacheEntry entry = null; static long beforeCreation = 0; static long afterCreation = 0; private final String CONTENT = "Content for the cache entry test"; // Constants used thru the tests private final String ENTRY_KEY = "Test cache entry key"; private final int NO_REFRESH_NEEDED = 1000000; private final int REFRESH_NEEDED = 0; /** * Class constructor *

* @param str The test name (required by JUnit) */ public TestCacheEntry(String str) { super(str); } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // At first invocation, create a cache entry object if (entry == null) { // Log the time before and after to verify the creation time // in one of the tests beforeCreation = System.currentTimeMillis(); entry = new CacheEntry(ENTRY_KEY); afterCreation = System.currentTimeMillis(); } } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestCacheEntry.class); } /** * Verify the flush */ public void testFlush() { // Set the content so it shouldn't need refresh entry.setContent(CONTENT); assertTrue(!entry.needsRefresh(NO_REFRESH_NEEDED)); // Flush the entry. It should now needs refresh entry.flush(); assertTrue(entry.needsRefresh(NO_REFRESH_NEEDED)); } /** * Verify that the creation time is correct */ public void testGetCreated() { assertBetweenOrEquals(beforeCreation, entry.getCreated(), afterCreation); } /** * Retrieve the item created by the setup */ public void testGetKey() { assertTrue(entry.getKey().equals(ENTRY_KEY)); } /** * Verify that the last modification time is between the time before and * after the alteration of the item */ public void testGetLastUpdate() { // again. Then we ensure that the update time is between our timestamps long before = System.currentTimeMillis(); entry.setContent(CONTENT); long after = System.currentTimeMillis(); assertBetweenOrEquals(before, entry.getLastUpdate(), after); } /** * Verify that the "freshness detection" function properly */ public void testNeedsRefresh() { // Set the entry content so it shouldn't need refresh // Invoke needsRefresh with no delay, so it should return true. // Then invoke it with a big delay, so it should return false assertTrue(entry.needsRefresh(REFRESH_NEEDED)); assertTrue(!entry.needsRefresh(NO_REFRESH_NEEDED)); } /** * Set the content of the item created by setup and then retrieve it and * validate it */ public void testSetGetContent() { entry.setContent(CONTENT); assertTrue(CONTENT.equals(entry.getContent())); // Ensure that nulls are allowed entry.setContent(null); assertNull(entry.getContent()); } /** * Ensure that a value is between two others. Since the execution may be * very fast, equals values are also considered to be between */ private void assertBetweenOrEquals(long first, long between, long last) { assertTrue(between >= first); assertTrue(between <= last); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/TestConcurrency2.java0000644000175000017500000004211110641701561030433 0ustar twernertwerner/* * Copyright (c) 2002-2007 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner; import net.sourceforge.groboutils.junit.v1.TestRunnable; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.Properties; /** * Test the Cache class for any concurrency problems * * $Id: TestConcurrency.java 404 2007-02-24 10:21:00Z larst $ * @version $Revision: 404 $ */ public class TestConcurrency2 extends TestCase { private static transient final Log log = LogFactory.getLog(GeneralCacheAdministrator.class); //TestConcurrency2.class // Static variables required thru all the tests private static GeneralCacheAdministrator admin = null; // Constants needed in the tests private final String KEY = "key"; private final String VALUE = "This is some content"; private final int ITERATION_COUNT = 1000; private final int THREAD_COUNT = 3; private final int UNIQUE_KEYS = 1013; /** * Class constructor. *

* @param str The test name (required by JUnit) */ public TestConcurrency2(String str) { super(str); } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // At first invocation, create a new Cache if (admin == null) { Properties config = new Properties(); config.setProperty(AbstractCacheAdministrator.CACHE_CAPACITY_KEY, "70"); config.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "false"); admin = new GeneralCacheAdministrator(config); assertNotNull(admin); } } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestConcurrency2.class); } /** * Check that the cache handles simultaneous attempts to access a * new cache entry correctly */ public void testNewEntry() { String key = "new"; try { admin.getFromCache(key, -1); fail("NeedsRefreshException should have been thrown"); } catch (NeedsRefreshException nre) { // Fire off another couple of threads to get the same cache entry GetEntry getEntry1 = new GetEntry(key, VALUE, -1, false); GetEntry getEntry2 = new GetEntry(key, VALUE, -1, false); // OK, those threads should be blocked waiting for the new cache // entry to appear. Sleep for a bit to simulate the time taken to // build the cache entry PutInCache putInCache = new PutInCache(key, VALUE, 500); // pass that instance to the MTTR TestRunnable[] trs = {getEntry1, getEntry2, putInCache}; MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(trs); // kickstarts the MTTR & fires off threads try { mttr.runTestRunnables(5000); } catch (Throwable e) { fail("Thread should have blocked until a new cache entry was ready"); } } } /** * Check that the cache handles simultaneous attempts to access a * new cache entry correctly */ public void testNewEntryCancel() { final String key = "newCancel"; final String NEW_VALUE = VALUE + "..."; try { admin.getFromCache(key, -1); fail("NeedsRefreshException should have been thrown"); } catch (NeedsRefreshException nre) { // Fire off another thread to get the same cache entry // We can't use GrobeUtils, because joining functionality is missing GetEntrySimple getEntry = new GetEntrySimple(key, NEW_VALUE, CacheEntry.INDEFINITE_EXPIRY, true); Thread thread = new Thread(getEntry); thread.start(); // The above thread will be blocked waiting for the new content try { Thread.sleep(500); } catch (InterruptedException ie) { } // Now cancel the update (eg because an exception occurred while building the content). // This will unblock the other thread and it will receive a NeedsRefreshException. admin.cancelUpdate(key); // Wait a bit for the other thread to update the cache try { Thread.sleep(500); } catch (InterruptedException ie) { } try { Object newValue = admin.getFromCache(key, CacheEntry.INDEFINITE_EXPIRY); assertEquals(NEW_VALUE, newValue); } catch (NeedsRefreshException e) { admin.cancelUpdate(key); e.printStackTrace(); fail("A NeedsRefreshException should not have been thrown. content=" + e.getCacheContent() + ", "+e.getMessage()); } } } /** * Verify that we can concurrently access the cache without problems */ public void testPut() { Thread[] thread = new Thread[THREAD_COUNT]; for (int idx = 0; idx < THREAD_COUNT; idx++) { OSGeneralTest runner = new OSGeneralTest(); thread[idx] = new Thread(runner); thread[idx].start(); } boolean stillAlive; do { try { Thread.sleep(100); } catch (InterruptedException e) { // do nothing } stillAlive = false; int i = 0; while ((i < thread.length) && !stillAlive) { stillAlive |= thread[i++].isAlive(); } } while (stillAlive); } /** * Check that the cache handles simultaneous attempts to access a * stale cache entry correctly */ public void testStaleEntry() { String key = "stale"; assertFalse("The cache should not be in blocking mode for this test.", admin.isBlocking()); admin.putInCache(key, VALUE); try { // This should throw a NeedsRefreshException since the refresh // period is 0 admin.getFromCache(key, 0); fail("NeedsRefreshException should have been thrown"); } catch (NeedsRefreshException nre) { // Fire off another thread to get the same cache entry. // Since blocking mode is currently disabled we should // immediately get back the stale entry GetEntry getEntry = new GetEntry(key, VALUE, 0, false); Thread thread = new Thread(getEntry); thread.start(); // Sleep for a bit to simulate the time taken to build the cache entry try { Thread.sleep(200); } catch (InterruptedException ie) { } // Putting the entry in the cache should mean that threads now retrieve // the updated entry String newValue = "New value"; admin.putInCache(key, newValue); getEntry = new GetEntry(key, newValue, -1, false); thread = new Thread(getEntry); thread.start(); try { Object fromCache = admin.getFromCache(key, -1); assertEquals(newValue, fromCache); } catch (NeedsRefreshException e) { admin.cancelUpdate(key); fail("Should not have received a NeedsRefreshException"); } // Give the GetEntry thread a chance to finish try { Thread.sleep(200); } catch (InterruptedException ie) { } } } /** * A test for the updating of a stale entry when CACHE.BLOCKING = TRUE */ public void testStaleEntryBlocking() { // A test for the case where oscache.blocking = true admin.destroy(); Properties p = new Properties(); p.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "true"); admin = new GeneralCacheAdministrator(p); assertTrue("The cache should be in blocking mode for this test.", admin.isBlocking()); // Use a unique key in case these test entries are being persisted String key = "blocking"; String NEW_VALUE = VALUE + " abc"; admin.putInCache(key, VALUE); try { // Force a NeedsRefreshException admin.getFromCache(key, 0); fail("NeedsRefreshException should have been thrown"); } catch (NeedsRefreshException nre) { // Fire off another thread to get the same cache entry. // Since blocking mode is enabled this thread should block // until the entry has been updated. GetEntry getEntry = new GetEntry(key, NEW_VALUE, 0, false); Thread thread = new Thread(getEntry); thread.start(); // Sleep for a bit to simulate the time taken to build the cache entry try { Thread.sleep(20); } catch (InterruptedException ie) { } // Putting the entry in the cache should mean that threads now retrieve // the updated entry admin.putInCache(key, NEW_VALUE); getEntry = new GetEntry(key, NEW_VALUE, -1, false); thread = new Thread(getEntry); thread.start(); try { Object fromCache = admin.getFromCache(key, -1); assertEquals(NEW_VALUE, fromCache); } catch (NeedsRefreshException e) { admin.cancelUpdate(key); fail("Should not have received a NeedsRefreshException"); } } } private static final int RETRY_BY_THREADS = 100000; private static final int NB_THREADS = 4; /** * Checks whether the cache handles simultaneous attempts to access a * stable cache entry correctly when the blocking mode is enabled. * * Basically N threads are concurrently trying to access a same stale cache entry and each is cancelling its update. Each thread repeat this operation M times. * The test is sucessfull if after some time, all threads are properly released */ public void testConcurrentStaleGets() { GeneralCacheAdministrator staticAdmin = admin; //admin = new GeneralCacheAdministrator(); //avoid poluting other test cases try { // A test for the case where oscache.blocking = true //admin.destroy(); Properties p = new Properties(); p.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "true"); admin = new GeneralCacheAdministrator(p); assertTrue("The cache should be in blocking mode for this test.", admin.isBlocking()); String key = "new"; //First put a value admin.putInCache(key, VALUE); try { //Then test without concurrency that it is reported as stale when time-to-live is zero admin.getFromCache(key, 0); fail("NeedsRefreshException should have been thrown"); } catch (NeedsRefreshException nre) { //Ok this is was is excpected, we can release the update admin.cancelUpdate(key); } //Then ask N threads to concurrently try to access this stale resource and each should receive a NeedsRefreshException, and cancel the update TestRunnable[] spawnedThreads = new TestRunnable[NB_THREADS]; for (int threadIndex = 0; threadIndex < NB_THREADS; threadIndex++) { spawnedThreads[threadIndex] = new GetStaleEntryAndCancelUpdate(key, 0, RETRY_BY_THREADS); } MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(spawnedThreads); //kickstarts the MTTR & fires off threads try { mttr.runTestRunnables(120 * 1000); } catch (Throwable e) { fail("at least one thread did not complete"); e.printStackTrace(); } } finally { // avoid poluting other test cases admin = staticAdmin; } } private class GetEntry extends TestRunnable { String key; String value; boolean expectNRE; int time; GetEntry(String key, String value, int time, boolean expectNRE) { this.key = key; this.value = value; this.time = time; this.expectNRE = expectNRE; } public void runTest() { try { // Get from the cache Object fromCache = admin.getFromCache(key, time); assertEquals(value, fromCache); } catch (NeedsRefreshException nre) { if (!expectNRE) { admin.cancelUpdate(key); fail("Thread should have blocked until a new cache entry was ready"); } else { // Put a new piece of content into the cache admin.putInCache(key, value); } } } } private class GetEntrySimple extends GetEntry { GetEntrySimple(String key, String value, int time, boolean expectNRE) { super(key, value, time, expectNRE); } public void run() { runTest(); } } private class PutInCache extends TestRunnable { String key; String value; long wait; PutInCache(String key, String value, long wait) { this.key = key; this.value = value; this.wait = wait; } public void runTest() { try { Thread.sleep(wait); } catch (InterruptedException ie) { fail("PutInCache thread shouldn't be interrupted."); } admin.putInCache(key, value); } } /** * Basically requests a stale entry, expects to receive a NeedsRefreshException, and always cancels the update. */ private class GetStaleEntryAndCancelUpdate extends TestRunnable { String key; int retries; int time; GetStaleEntryAndCancelUpdate(String key, int time, int retries) { this.key = key; this.time = time; this.retries = retries; } public void runTest() { for (int retryIndex = 0; retryIndex < retries; retryIndex++) { try { // Get from the cache Object fromCache = admin.getFromCache(key, time); assertNull("Thread index [" + retryIndex + "] expected stale request [" + retryIndex + "] to be received, got [" + fromCache + "]", fromCache); } catch (NeedsRefreshException nre) { try { admin.cancelUpdate(key); } catch (Throwable t) { log.error("Thread index [" + retryIndex + "]: Unexpectedly caught exception [" + t + "]", t); fail("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]"); } } catch (Throwable t) { log.error("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]", t); fail("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]"); } } } } private class OSGeneralTest extends TestRunnable { public void doit(int i) { int refreshPeriod = 500 /*millis*/; String key = KEY + (i % UNIQUE_KEYS); admin.putInCache(key, VALUE); try { // Get from the cache admin.getFromCache(KEY, refreshPeriod); } catch (NeedsRefreshException nre) { // Get the value // Store in the cache admin.putInCache(KEY, VALUE); } // Flush occasionally if ((i % (UNIQUE_KEYS + 1)) == 0) { admin.getCache().flushEntry(key); } } public void runTest() { int start = (int) (Math.random() * UNIQUE_KEYS); System.out.print(start + " "); for (int i = start; i < (start + ITERATION_COUNT); i++) { doit(i); } } } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/DummyAlwayRefreshEntryPolicy.java0000644000175000017500000000172710254455232033042 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base; /** * This is an dummy implementation of an EntryRefreshPolicy. It is just to * illustrate how to use it. * * $Id: DummyAlwayRefreshEntryPolicy.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Francois Beauregard */ public final class DummyAlwayRefreshEntryPolicy implements EntryRefreshPolicy { /** * Dummy implementation of an entry refresh policy. A real implementation * whould do some logic to determine if this entry needs to be refreshed. * It can be calling a bean or checking some files, or even manually manage * the time expiration. * *

* @param entry The entry for wich to determine if a refresh is needed * @return True or false */ public boolean needsRefresh(CacheEntry entry) { return true; } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/TestCompleteBase.java0000644000175000017500000000371310641701561030427 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base; import com.opensymphony.oscache.base.algorithm.TestCompleteAlgorithm; import com.opensymphony.oscache.base.events.TestCompleteEvents; import com.opensymphony.oscache.util.TestFastCronParser; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test class for the com.opensymphony.oscache.base package. * It invokes all the test suites of all the other classes of the package. * * $Id: TestCompleteBase.java 476 2007-07-01 10:35:29Z larst $ * @version $Revision: 476 $ * @author Alain Bergevin */ public final class TestCompleteBase extends TestCase { /** * Constructor for the osCache project main test program */ public TestCompleteBase(String str) { super(str); } /** * Main method which is called to perform the tests *

* @param args Arguments received */ public static void main(String[] args) { // Run the test suite junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner(); testRunner.setLoading(false); String[] args2 = {TestCompleteBase.class.getName()}; testRunner.start(args2); } /** * Test suite required to test this project *

* @return suite The test suite */ public static Test suite() { // Add all the tests suite of all the project classes TestSuite suite = new TestSuite("Test all base cache modules"); suite.addTest(TestFastCronParser.suite()); suite.addTest(TestCacheEntry.suite()); suite.addTest(TestCache.suite()); suite.addTest(TestConcurrency.suite()); suite.addTest(TestConcurrency2.suite()); suite.addTest(TestCompleteAlgorithm.suite()); suite.addTest(TestCompleteEvents.suite()); return suite; } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/TestConcurrency.java0000644000175000017500000004342510570010614030353 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.BitSet; import java.util.Properties; /** * Test the Cache class for any concurrency problems * * $Id: TestConcurrency.java 404 2007-02-24 10:21:00Z larst $ * @version $Revision: 404 $ * @author Chris Miller */ public class TestConcurrency extends TestCase { private static transient final Log log = LogFactory.getLog(GeneralCacheAdministrator.class); //TestConcurrency.class // Static variables required thru all the tests private static GeneralCacheAdministrator admin = null; // Constants needed in the tests private final String KEY = "key"; private final String VALUE = "This is some content"; private final int ITERATION_COUNT = 5; //500; private final int THREAD_COUNT = 6; //600; private final int UNIQUE_KEYS = 1013; /** * Class constructor. *

* @param str The test name (required by JUnit) */ public TestConcurrency(String str) { super(str); } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // At first invocation, create a new Cache if (admin == null) { Properties config = new Properties(); config.setProperty(AbstractCacheAdministrator.CACHE_CAPACITY_KEY, "70"); config.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "false"); admin = new GeneralCacheAdministrator(); assertNotNull(admin); } } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestConcurrency.class); } /** * Check that the cache handles simultaneous attempts to access a * new cache entry correctly */ public void testNewEntry() { String key = "new"; try { admin.getFromCache(key, -1); fail("NeedsRefreshException should have been thrown"); } catch (NeedsRefreshException nre) { // Fire off another couple of threads to get the same cache entry GetEntry getEntry = new GetEntry(key, VALUE, -1, false); Thread thread = new Thread(getEntry); thread.start(); getEntry = new GetEntry(key, VALUE, -1, false); thread = new Thread(getEntry); thread.start(); // OK, those threads should now be blocked waiting for the new cache // entry to appear. Sleep for a bit to simulate the time taken to // build the cache entry try { Thread.sleep(500); } catch (InterruptedException ie) { } // Putting the entry in the cache should unblock the previous threads admin.putInCache(key, VALUE); } } /** * Check that the cache handles simultaneous attempts to access a * new cache entry correctly */ public void testNewEntryCancel() { String key = "newCancel"; String NEW_VALUE = VALUE + "..."; try { admin.getFromCache(key, -1); fail("NeedsRefreshException should have been thrown"); } catch (NeedsRefreshException nre) { // Fire off another thread to get the same cache entry GetEntry getEntry = new GetEntry(key, NEW_VALUE, -1, true); Thread thread = new Thread(getEntry); thread.start(); // The above thread will be blocked waiting for the new content try { Thread.sleep(500); } catch (InterruptedException ie) { } // Now cancel the update (eg because an exception occurred while building the content). // This will unblock the other thread and it will receive a NeedsRefreshException. admin.cancelUpdate(key); // Wait a bit for the other thread to update the cache try { Thread.sleep(500); } catch (InterruptedException ie) { } try { Object newValue = admin.getFromCache(key, -1); assertEquals(NEW_VALUE, newValue); } catch (NeedsRefreshException e) { admin.cancelUpdate(key); fail("A NeedsRefreshException should not have been thrown"); } } } /** * Verify that we can concurrently access the cache without problems */ public void testPut() { Thread[] thread = new Thread[THREAD_COUNT]; for (int idx = 0; idx < THREAD_COUNT; idx++) { OSGeneralTest runner = new OSGeneralTest(); thread[idx] = new Thread(runner); thread[idx].start(); } boolean stillAlive; do { try { Thread.sleep(100); } catch (InterruptedException e) { // do nothing } stillAlive = false; int i = 0; while ((i < thread.length) && !stillAlive) { stillAlive |= thread[i++].isAlive(); } } while (stillAlive); } /** * Check that the cache handles simultaneous attempts to access a * stale cache entry correctly */ public void testStaleEntry() { String key = "stale"; assertFalse("The cache should not be in blocking mode for this test.", admin.isBlocking()); admin.putInCache(key, VALUE); try { // This should throw a NeedsRefreshException since the refresh // period is 0 admin.getFromCache(key, 0); fail("NeedsRefreshException should have been thrown"); } catch (NeedsRefreshException nre) { // Fire off another thread to get the same cache entry. // Since blocking mode is currently disabled we should // immediately get back the stale entry GetEntry getEntry = new GetEntry(key, VALUE, 0, false); Thread thread = new Thread(getEntry); thread.start(); // Sleep for a bit to simulate the time taken to build the cache entry try { Thread.sleep(200); } catch (InterruptedException ie) { } // Putting the entry in the cache should mean that threads now retrieve // the updated entry String newValue = "New value"; admin.putInCache(key, newValue); getEntry = new GetEntry(key, newValue, -1, false); thread = new Thread(getEntry); thread.start(); try { Object fromCache = admin.getFromCache(key, -1); assertEquals(newValue, fromCache); } catch (NeedsRefreshException e) { admin.cancelUpdate(key); fail("Should not have received a NeedsRefreshException"); } // Give the GetEntry thread a chance to finish try { Thread.sleep(200); } catch (InterruptedException ie) { } } } /** * A test for the updating of a stale entry when CACHE.BLOCKING = TRUE */ public void testStaleEntryBlocking() { // A test for the case where oscache.blocking = true admin.destroy(); Properties p = new Properties(); p.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "true"); admin = new GeneralCacheAdministrator(p); assertTrue("The cache should be in blocking mode for this test.", admin.isBlocking()); // Use a unique key in case these test entries are being persisted String key = "blocking"; String NEW_VALUE = VALUE + " abc"; admin.putInCache(key, VALUE); try { // Force a NeedsRefreshException admin.getFromCache(key, 0); fail("NeedsRefreshException should have been thrown"); } catch (NeedsRefreshException nre) { // Fire off another thread to get the same cache entry. // Since blocking mode is enabled this thread should block // until the entry has been updated. GetEntry getEntry = new GetEntry(key, NEW_VALUE, 0, false); Thread thread = new Thread(getEntry); thread.start(); // Sleep for a bit to simulate the time taken to build the cache entry try { Thread.sleep(200); } catch (InterruptedException ie) { } // Putting the entry in the cache should mean that threads now retrieve // the updated entry admin.putInCache(key, NEW_VALUE); getEntry = new GetEntry(key, NEW_VALUE, -1, false); thread = new Thread(getEntry); thread.start(); try { Object fromCache = admin.getFromCache(key, -1); assertEquals(NEW_VALUE, fromCache); } catch (NeedsRefreshException e) { admin.cancelUpdate(key); fail("Should not have received a NeedsRefreshException"); } } } /** * Checks whether the cache handles simultaneous attempts to access a * stable cache entry correctly when the blocking mode is enabled. * * Basically N threads are concurrently trying to access a same stale cache entry and each is cancelling its update. Each thread repeat this operation M times. * The test is sucessfull if after some time, all threads are properly released */ public void testConcurrentStaleGets() { GeneralCacheAdministrator staticAdmin = admin; admin = new GeneralCacheAdministrator(); //avoid poluting other test cases try { // A test for the case where oscache.blocking = true //admin.destroy(); Properties p = new Properties(); p.setProperty(AbstractCacheAdministrator.CACHE_BLOCKING_KEY, "true"); admin = new GeneralCacheAdministrator(p); assertTrue("The cache should be in blocking mode for this test.", admin.isBlocking()); int nbThreads = 50; int retryByThreads = 10000; String key = "new"; //First put a value admin.putInCache(key, VALUE); try { //Then test without concurrency that it is reported as stale when time-to-live is zero admin.getFromCache(key, 0); fail("NeedsRefreshException should have been thrown"); } catch (NeedsRefreshException nre) { //Ok this is was is excpected, we can release the update admin.cancelUpdate(key); } //Then ask N threads to concurrently try to access this stale resource and each should receive a NeedsRefreshException, and cancel the update Thread[] spawnedThreads = new Thread[nbThreads]; BitSet successfullThreadTerminations = new BitSet(nbThreads); //Track which thread successfully terminated for (int threadIndex = 0; threadIndex < nbThreads; threadIndex++) { GetStaleEntryAndCancelUpdate getEntry = new GetStaleEntryAndCancelUpdate(key, 0, retryByThreads, threadIndex, successfullThreadTerminations); Thread thread = new Thread(getEntry); spawnedThreads[threadIndex] = thread; thread.start(); } // OK, those threads should now repeatidely be blocked waiting for the new cache // entry to appear. Wait for all of them to terminate long maxWaitingSeconds = 100; int maxWaitForEachThread = 5; long waitStartTime = System.currentTimeMillis(); boolean atLeastOneThreadRunning = false; while ((System.currentTimeMillis() - waitStartTime) < (maxWaitingSeconds * 1000)) { atLeastOneThreadRunning = false; //Wait a bit between each step to avoid consumming all CPU and preventing other threads from running. try { Thread.sleep(500); } catch (InterruptedException ie) { } //check whether all threads are done. for (int threadIndex = 0; threadIndex < nbThreads; threadIndex++) { Thread inspectedThread = spawnedThreads[threadIndex]; try { inspectedThread.join(maxWaitForEachThread * 1000); } catch (InterruptedException e) { fail("Thread #" + threadIndex + " was interrupted"); } if (inspectedThread.isAlive()) { atLeastOneThreadRunning = true; log.error("Thread #" + threadIndex + " did not complete within [" + ((System.currentTimeMillis() - waitStartTime) / 1000) + "] s "); } } if (!atLeastOneThreadRunning) { break; //while loop, test success. } } assertTrue("at least one thread did not complete within [" + ((System.currentTimeMillis() - waitStartTime) / 1000) + "] s ", !atLeastOneThreadRunning); for (int threadIndex = 0; threadIndex < nbThreads; threadIndex++) { assertTrue("thread [" + threadIndex + "] did not successfully complete. ", successfullThreadTerminations.get(threadIndex)); } } finally { admin = staticAdmin; //Avoid po } } private class GetEntry implements Runnable { String key; String value; boolean expectNRE; int time; GetEntry(String key, String value, int time, boolean expectNRE) { this.key = key; this.value = value; this.time = time; this.expectNRE = expectNRE; } public void run() { try { // Get from the cache Object fromCache = admin.getFromCache(key, time); assertEquals(value, fromCache); } catch (NeedsRefreshException nre) { if (!expectNRE) { admin.cancelUpdate(key); fail("Thread should have blocked until a new cache entry was ready"); } else { // Put a new piece of content into the cache admin.putInCache(key, value); } } } } /** * Basically requests a stale entry, expects to receive a NeedsRefreshException, and always cancels the update. */ private class GetStaleEntryAndCancelUpdate implements Runnable { String key; int retries; int time; private final BitSet successfullThreadTerminations; private final int threadIndex; GetStaleEntryAndCancelUpdate(String key, int time, int retries, int threadIndex, BitSet successfullThreadTerminations) { this.key = key; this.time = time; this.retries = retries; this.threadIndex = threadIndex; this.successfullThreadTerminations = successfullThreadTerminations; } public void run() { for (int retryIndex = 0; retryIndex < retries; retryIndex++) { try { // Get from the cache Object fromCache = admin.getFromCache(key, time); assertNull("Thread index [" + retryIndex + "] expected stale request [" + retryIndex + "] to be received, got [" + fromCache + "]", fromCache); } catch (NeedsRefreshException nre) { try { admin.cancelUpdate(key); } catch (Throwable t) { log.error("Thread index [" + retryIndex + "]: Unexpectedly caught exception [" + t + "]", t); fail("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]"); } } catch (Throwable t) { log.error("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]", t); fail("Thread index [" + retryIndex + "] : Unexpectedly caught exception [" + t + "]"); } } //Once we successfully terminate, we update the corresponding bit to let the Junit know we succeeded. synchronized (successfullThreadTerminations) { successfullThreadTerminations.set(threadIndex); } } } private class OSGeneralTest implements Runnable { public void doit(int i) { int refreshPeriod = 500 /*millis*/; String key = KEY + (i % UNIQUE_KEYS); admin.putInCache(key, VALUE); try { // Get from the cache admin.getFromCache(KEY, refreshPeriod); } catch (NeedsRefreshException nre) { // Get the value // Store in the cache admin.putInCache(KEY, VALUE); } // Flush occasionally if ((i % (UNIQUE_KEYS + 1)) == 0) { admin.getCache().flushEntry(key); } } public void run() { int start = (int) (Math.random() * UNIQUE_KEYS); System.out.print(start + " "); for (int i = start; i < (start + ITERATION_COUNT); i++) { doit(i); } } } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/base/TestAbstractCacheAdministrator.java0000644000175000017500000000572110511647706033323 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.base; import junit.framework.TestCase; /** * Test class for the AbstractCacheAdministrator class. It tests some of the * public methods of the admin. Some others cannot be tested since they are * linked to the property file used for the tests, and since this file * will change, the value of some parameters cannot be asserted * * $Id: TestAbstractCacheAdministrator.java 385 2006-10-07 06:57:10Z larst $ * @version $Revision: 385 $ * @author Alain Bergevin */ public abstract class TestAbstractCacheAdministrator extends TestCase { // Constants used in the tests //private final String CACHE_PATH_PROP = "cache.path"; //private final String CONTENT = "Content for the abstract cache admin test"; //private final String ENTRY_KEY = "Test Abstract Admin Key"; private final String INVALID_PROP_NAME = "INVALID_PROP_NAME"; //private final String TEST_LOG = "test log"; /** * Constructor for the this test class. *

* @param str Test name (required by JUnit) */ protected TestAbstractCacheAdministrator(String str) { super(str); } /** * Cannot be tested since CacheContents is an interface */ public void testCacheContents() { } /** * We cannot test this method because the value depends on the property */ public void testGetCachePath() { } /** * Validate that the properties retrieved by the admin are the same as the one * specified in the property file. Do not test cache path or memory cache * since it changes with the tests */ public void testGetProperty() { // Check if all the default properties are OK assertNull(getAdmin().getProperty(INVALID_PROP_NAME)); assertNull(getAdmin().getProperty("")); try { assertNull(getAdmin().getProperty(null)); fail("NullPointerException expected (property Key null)."); } catch (Exception e) { } } /** * We cannot test this method because the value depends on the property */ public void testIsFileCaching() { } /** * We cannot test this method because the value depends on the property */ public void testIsMemoryCaching() { } /** * Perform a call to the log method. Unfornately, there is no way to check * if the logging is done correctly, we only invoke it */ public void testLog() { // Invoke the log // The other log method is not tested since it calls the same as we do //TODO /*getAdmin().log(TEST_LOG, System.out); getAdmin().log("", System.out); getAdmin().log(null, System.out); getAdmin().log(TEST_LOG, null); */ } // Abstract method that returns an instance of an admin protected abstract AbstractCacheAdministrator getAdmin(); } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/util/0000755000175000017500000000000011375310607024422 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/util/TestFastCronParser.java0000644000175000017500000003347310511647706031037 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.util; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; /** * * @author Chris Miller * @author $Author: larst $ * @version $Revision: 385 $ */ public class TestFastCronParser extends TestCase { public TestFastCronParser(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestFastCronParser.class); } /** * Tests to see if the cron class can calculate the previous matching * time correctly in various circumstances */ public void testEvaluations() { // Minute tests cronCall("01/01/2003 0:00", "45 * * * *", "31/12/2002 23:45", false); cronCall("01/01/2003 0:00", "45-47,48,49 * * * *", "31/12/2002 23:49", false); cronCall("01/01/2003 0:00", "2/5 * * * *", "31/12/2002 23:57", false); // Hour tests cronCall("20/12/2003 10:00", "* 3/4 * * *", "20/12/2003 07:59", false); cronCall("20/12/2003 0:00", "* 3 * * *", "19/12/2003 03:59", false); // Day of month tests cronCall("07/01/2003 0:00", "30 * 1 * *", "01/01/2003 23:30", false); cronCall("01/01/2003 0:00", "10 * 22 * *", "22/12/2002 23:10", false); cronCall("01/01/2003 0:00", "30 23 19 * *", "19/12/2002 23:30", false); cronCall("01/01/2003 0:00", "30 23 21 * *", "21/12/2002 23:30", false); cronCall("01/01/2003 0:01", "* * 21 * *", "21/12/2002 23:59", false); cronCall("10/07/2003 0:00", "* * 30,31 * *", "30/06/2003 23:59", false); // Test month rollovers for months with 28,29,30 and 31 days cronCall("01/03/2002 0:11", "* * * 2 *", "28/02/2002 23:59", false); cronCall("01/03/2004 0:44", "* * * 2 *", "29/02/2004 23:59", false); cronCall("01/04/2002 0:00", "* * * 3 *", "31/03/2002 23:59", false); cronCall("01/05/2002 0:00", "* * * 4 *", "30/04/2002 23:59", false); // Other month tests (including year rollover) cronCall("01/01/2003 5:00", "10 * * 6 *", "30/06/2002 23:10", false); cronCall("01/01/2003 5:00", "10 * * February,April-Jun *", "30/06/2002 23:10", false); cronCall("01/01/2003 0:00", "0 12 1 6 *", "01/06/2002 12:00", false); cronCall("11/09/1988 14:23", "* 12 1 6 *", "01/06/1988 12:59", false); cronCall("11/03/1988 14:23", "* 12 1 6 *", "01/06/1987 12:59", false); cronCall("11/03/1988 14:23", "* 2,4-8,15 * 6 *", "30/06/1987 15:59", false); cronCall("11/03/1988 14:23", "20 * * january,FeB,Mar,april,May,JuNE,July,Augu,SEPT-October,Nov,DECEM *", "11/03/1988 14:20", false); // Day of week tests cronCall("26/06/2003 10:00", "30 6 * * 0", "22/06/2003 06:30", false); cronCall("26/06/2003 10:00", "30 6 * * sunday", "22/06/2003 06:30", false); cronCall("26/06/2003 10:00", "30 6 * * SUNDAY", "22/06/2003 06:30", false); cronCall("23/06/2003 0:00", "1 12 * * 2", "17/06/2003 12:01", false); cronCall("23/06/2003 0:00", "* * * * 3,0,4", "22/06/2003 23:59", false); cronCall("23/06/2003 0:00", "* * * * 5", "20/06/2003 23:59", false); cronCall("02/06/2003 18:30", "0 12 * * 2", "27/05/2003 12:00", false); cronCall("02/06/2003 18:30", "0 12 * * Tue,Thurs-Sat,2", "31/05/2003 12:00", false); cronCall("02/06/2003 18:30", "0 12 * * Mon-tuesday,wed,THURS-FRiday,Sat-SUNDAY", "02/06/2003 12:00", false); // Leap year tests cronCall("01/03/2003 12:00", "1 12 * * *", "28/02/2003 12:01", false); // non-leap year cronCall("01/03/2004 12:00", "1 12 * * *", "29/02/2004 12:01", false); // leap year cronCall("01/03/2003 12:00", "1 23 * * 0", "23/02/2003 23:01", false); // non-leap year cronCall("01/03/2004 12:00", "1 23 * * 0", "29/02/2004 23:01", false); // leap year cronCall("01/03/2003 12:00", "* * 29 2 *", "29/02/2000 23:59", false); // Find the previous leap-day cronCall("01/02/2003 12:00", "* * 29 2 *", "29/02/2000 23:59", false); // Find the previous leap-day cronCall("01/02/2004 12:00", "* * 29 2 *", "29/02/2000 23:59", false); // Find the previous leap-day // Interval and range tests cronCall("20/12/2003 10:00", "* */4 * * *", "20/12/2003 08:59", false); cronCall("20/12/2003 10:00", "* 3/2 * * *", "20/12/2003 09:59", false); cronCall("20/12/2003 10:00", "1-30/5 10-20/3 * jan-aug/2 *", "31/07/2003 19:26", false); cronCall("20/12/2003 10:00", "20-25,27-30/2 10/8 * * *", "19/12/2003 18:29", false); } /** * Tests a range of invalid cron expressions */ public void testInvalidExpressionParsing() { FastCronParser parser = new FastCronParser(); try { parser.setCronExpression(null); fail("An IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException e) { // Expected } catch (ParseException e) { fail("Expected an IllegalArgumentException but received a ParseException instead"); } /** * Not enough tokens */ cronCall("01/01/2003 0:00", "", "", true); cronCall("01/01/2003 0:00", "8 * 8/1 *", "", true); /** * Invalid syntax */ cronCall("01/01/2003 0:00", "* invalid * * *", "", true); cronCall("01/01/2003 0:00", "* -1 * * *", "", true); cronCall("01/01/2003 0:00", "* * 20 * 0", "", true); cronCall("01/01/2003 0:00", "* * 5-6-7 * *", "", true); cronCall("01/01/2003 0:00", "* * 5/6-7 * *", "", true); cronCall("01/01/2003 0:00", "* * 5-* * *", "", true); cronCall("01/01/2003 0:00", "* * 5-6* * *", "", true); cronCall("01/01/2003 0:00", "* * * * Mo", "", true); cronCall("01/01/2003 0:00", "* * * jxxx *", "", true); cronCall("01/01/2003 0:00", "* * * juxx *", "", true); cronCall("01/01/2003 0:00", "* * * fbr *", "", true); cronCall("01/01/2003 0:00", "* * * mch *", "", true); cronCall("01/01/2003 0:00", "* * * mAh *", "", true); cronCall("01/01/2003 0:00", "* * * arl *", "", true); cronCall("01/01/2003 0:00", "* * * Spteber *", "", true); cronCall("01/01/2003 0:00", "* * * otber *", "", true); cronCall("01/01/2003 0:00", "* * * nvemtber *", "", true); cronCall("01/01/2003 0:00", "* * * Dcmber *", "", true); cronCall("01/01/2003 0:00", "* * * * mnday", "", true); cronCall("01/01/2003 0:00", "* * * * tsdeday", "", true); cronCall("01/01/2003 0:00", "* * * * wdnesday", "", true); cronCall("01/01/2003 0:00", "* * * * frday", "", true); cronCall("01/01/2003 0:00", "* * * * sdhdatr", "", true); /** * Values out of range */ cronCall("01/01/2003 0:00", "* * 0 * *", "", true); cronCall("01/01/2003 0:00", "* 50 * * *", "", true); cronCall("01/01/2003 0:00", "* * * 1-20 *", "", true); cronCall("01/01/2003 0:00", "* * 0-20 * *", "", true); cronCall("01/01/2003 0:00", "* * 1-40 * *", "", true); cronCall("01/01/2003 0:00", "* * * 1 8", "", true); cronCall("01/01/2003 0:00", "* * 0/3 * *", "", true); cronCall("01/01/2003 0:00", "* * 30 2 *", "", true); // 30th Feb doesn't ever exist! cronCall("01/01/2003 0:00", "* * 31 4 *", "", true); // 31st April doesn't ever exist! } /** * This tests the performance of the cron parsing engine. Note that it may take * a couple of minutes o run - by default this test is disabled. Comment out the * return statement at the start of this method to enable the * benchmarking. */ public void testPerformance() { if (true) { // return; // Comment out this line to benchmark } SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm"); Date date = null; try { date = sdf.parse("21/01/2003 16:27"); } catch (ParseException e) { fail("Failed to parse date. Please check your unit test code!"); } Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); calendar.setTime(date); long baseTime = calendar.getTimeInMillis(); long time = 0; try { // Give HotSpot a chance to warm up iterate("28 17 22 02 *", baseTime, time, 10000, true); // Number of iterations to test int count = 1000000; // Test the best-case scenario long bestCaseTime = iterate("* * * * *", baseTime, time, count, true); System.out.println("Best case with parsing took " + bestCaseTime + "ms for " + count + " iterations. (" + (bestCaseTime / (float) count) + "ms per call)"); // Test a near worst-case scenario long worstCaseTime = iterate("0-59,0-13,2,3,4,5 17-19 22-23,22,23 2,3 *", baseTime, time, count, true); System.out.println("Worst case with parsing took " + worstCaseTime + "ms for " + count + " iterations. (" + (worstCaseTime / (float) count) + "ms per call)"); // Test the best-case scenario without parsing the expression on each iteration bestCaseTime = iterate("* * * * *", baseTime, time, count, false); System.out.println("Best case without parsing took " + bestCaseTime + "ms for " + count + " iterations. (" + (bestCaseTime / (float) count) + "ms per call)"); // Test a near worst-case scenario without parsing the expression on each iteration worstCaseTime = iterate("0-59,0-13,2,3,4,5 17-19 22-23,22,23 2,3 *", baseTime, time, count, false); System.out.println("Worst case without parsing took " + worstCaseTime + "ms for " + count + " iterations. (" + (worstCaseTime / (float) count) + "ms per call)"); } catch (ParseException e) { } } /** * Tests that a range of valid cron expressions get parsed correctly. */ public void testValidExpressionParsing() { FastCronParser parser; // Check the default constructor parser = new FastCronParser(); assertNull(parser.getCronExpression()); try { parser = new FastCronParser("* * * * *"); assertEquals("* * * * *", parser.getCronExpression()); // Should be the same as what we gave it assertEquals("* * * * *", parser.getExpressionSummary()); parser.setCronExpression("0 * * * *"); assertEquals("0 * * * *", parser.getCronExpression()); // Should be the same as what we gave it assertEquals("0 * * * *", parser.getExpressionSummary()); parser.setCronExpression("5 10 * * 1,4,6"); assertEquals("5 10 * * 1,4,6", parser.getExpressionSummary()); parser.setCronExpression("0,5-20,4-15,24-27 0 * 2-4,5,6-3 *"); // Overlapping ranges, backwards ranges assertEquals("0,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,24,25,26,27 0 * 2,3,4,5,6 *", parser.getExpressionSummary()); } catch (ParseException e) { e.printStackTrace(); fail("Cron expression should have been valid: " + e); } } /** * Makes a call to the FastCronParser. * * @param dateStr The date string to use as the base date. The format must be * "dd/MM/yyyy HH:mm". * @param cronExpr The cron expression to test. * @param result The expected result. This should be a date in the same format * as dateStr. * @param expectException Pass in true if the {@link FastCronParser} is * expected to throw a ParseException. */ private void cronCall(String dateStr, String cronExpr, String result, boolean expectException) { SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm"); Date date = null; try { date = sdf.parse(dateStr); } catch (ParseException e) { fail("Failed to parse date " + dateStr + ". Please check your unit test code!"); } Calendar calendar = Calendar.getInstance(); calendar.setTime(date); long baseTime = calendar.getTimeInMillis(); FastCronParser parser = null; try { parser = new FastCronParser(cronExpr); if (expectException) { fail("Should have received a ParseException while parsing " + cronExpr); } long time = parser.getTimeBefore(baseTime); assertEquals(result, sdf.format(new Date(time))); } catch (ParseException e) { if (!expectException) { fail("Unexpected ParseException while parsing " + cronExpr + ": " + e); } } } /** * Used by the benchmarking */ private long iterate(String cronExpr, long baseTime, long time, int count, boolean withParse) throws ParseException { long startTime = System.currentTimeMillis(); if (withParse) { FastCronParser parser = new FastCronParser(); for (int i = 0; i < count; i++) { parser.setCronExpression(cronExpr); time = parser.getTimeBefore(baseTime); } } else { FastCronParser parser = new FastCronParser(cronExpr); for (int i = 0; i < count; i++) { time = parser.getTimeBefore(baseTime); } } long endTime = System.currentTimeMillis(); long duration = (endTime - startTime); duration += (time - time); // Use the time variable to prevent it getting optimized away return duration; } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/extra/0000755000175000017500000000000011375310606024567 5ustar twernertwerner././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/extra/TestCacheMapAccessEventListenerImpl.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/extra/TestCacheMapAccessEventListenerImpl.0000644000175000017500000000451310254455232033550 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.extra; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.base.events.CacheMapAccessEvent; import com.opensymphony.oscache.base.events.CacheMapAccessEventType; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test the cache map access event listener implementation * * $Id: TestCacheMapAccessEventListenerImpl.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Alain Bergevin */ public class TestCacheMapAccessEventListenerImpl extends TestCase { /** * Key used for this test */ private final String KEY = "Test Cache Map Access Event Listener Impl Key"; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestCacheMapAccessEventListenerImpl(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestCacheMapAccessEventListenerImpl.class); } /** * Test the basic implementation of the listener */ public void testCacheMapAccessEventListenerImpl() { // Build objects required for the tests CacheEntry entry = new CacheEntry(KEY); CacheMapAccessEventListenerImpl listener = new CacheMapAccessEventListenerImpl(); // Genereate events listener.accessed(new CacheMapAccessEvent(CacheMapAccessEventType.HIT, entry)); listener.accessed(new CacheMapAccessEvent(CacheMapAccessEventType.HIT, entry)); listener.accessed(new CacheMapAccessEvent(CacheMapAccessEventType.STALE_HIT, entry)); listener.accessed(new CacheMapAccessEvent(CacheMapAccessEventType.MISS, entry)); // Assert the counters assertEquals(listener.getHitCount(), 2); assertEquals(listener.getStaleHitCount(), 1); assertEquals(listener.getMissCount(), 1); // Reset the counts listener.reset(); assertEquals(listener.getHitCount(), 0); assertEquals(listener.getStaleHitCount(), 0); assertEquals(listener.getMissCount(), 0); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/extra/TestScopeEventListenerImpl.java0000644000175000017500000000362410254455232032702 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.extra; import com.opensymphony.oscache.base.events.ScopeEvent; import com.opensymphony.oscache.base.events.ScopeEventType; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import java.util.Date; /** * Test the scope event listener implementation * * $Id: TestScopeEventListenerImpl.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Alain Bergevin */ public class TestScopeEventListenerImpl extends TestCase { private static final int PAGE_SCOPE = 1; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestScopeEventListenerImpl(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestScopeEventListenerImpl.class); } /** * Test the basic implementation of this listener */ public void testScopeEventListenerImpl() { // Construct the object we need for the test ScopeEventListenerImpl listener = new ScopeEventListenerImpl(); // Generates events listener.scopeFlushed(new ScopeEvent(ScopeEventType.ALL_SCOPES_FLUSHED, PAGE_SCOPE, new Date())); listener.scopeFlushed(new ScopeEvent(ScopeEventType.SCOPE_FLUSHED, PAGE_SCOPE, new Date())); // Assert the counters assertEquals(listener.getApplicationScopeFlushCount(), 1); assertEquals(listener.getPageScopeFlushCount(), 2); assertEquals(listener.getRequestScopeFlushCount(), 1); assertEquals(listener.getSessionScopeFlushCount(), 1); assertEquals(listener.getTotalScopeFlushCount(), 5); } } ././@LongLink0000000000000000000000000000014500000000000011565 Lustar rootrootoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/extra/TestCacheEntryEventListenerImpl.javaoscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/extra/TestCacheEntryEventListenerImpl.java0000644000175000017500000000642210576756253033673 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.extra; import java.util.Date; import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.base.events.CacheEntryEvent; import com.opensymphony.oscache.base.events.CacheGroupEvent; import com.opensymphony.oscache.base.events.CachePatternEvent; import com.opensymphony.oscache.base.events.CachewideEvent; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test the cache entry event listener implementation * * $Id: TestCacheEntryEventListenerImpl.java 418 2007-03-17 12:18:51Z larst $ * @version $Revision: 418 $ * @author Alain Bergevin */ public class TestCacheEntryEventListenerImpl extends TestCase { /** * Key used for this test */ private final String KEY = "Test Cache Entry Event Listener Impl Key"; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestCacheEntryEventListenerImpl(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestCacheEntryEventListenerImpl.class); } /** * Test the basic implementation */ public void testCacheEntryEventListenerImpl() { // Construct the objects required for the tests CacheEntry entry = new CacheEntry(KEY); GeneralCacheAdministrator admin = new GeneralCacheAdministrator(); Cache cache = new Cache(admin.isMemoryCaching(), admin.isUnlimitedDiskCache(), admin.isOverflowPersistence()); CacheEntryEvent event = new CacheEntryEvent(cache, entry, null); CacheEntryEventListenerImpl listener = new CacheEntryEventListenerImpl(); // Assert the counters assertEquals(listener.getEntryAddedCount(), 0); assertEquals(listener.getEntryFlushedCount(), 0); assertEquals(listener.getEntryRemovedCount(), 0); assertEquals(listener.getEntryUpdatedCount(), 0); assertEquals(listener.getGroupFlushedCount(), 0); assertEquals(listener.getPatternFlushedCount(), 0); assertEquals(listener.getCacheFlushedCount(), 0); // Generate an event of each type listener.cacheEntryAdded(event); listener.cacheEntryFlushed(event); listener.cacheEntryRemoved(event); listener.cacheEntryUpdated(event); listener.cacheFlushed(new CachewideEvent(cache, new Date(), null)); listener.cacheGroupFlushed(new CacheGroupEvent(cache, "testGroup", null)); listener.cachePatternFlushed(new CachePatternEvent(cache, "testPattern", null)); // Assert the counters assertEquals(listener.getEntryAddedCount(), 1); assertEquals(listener.getEntryFlushedCount(), 1); assertEquals(listener.getEntryRemovedCount(), 1); assertEquals(listener.getEntryUpdatedCount(), 1); assertEquals(listener.getGroupFlushedCount(), 1); assertEquals(listener.getPatternFlushedCount(), 1); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/extra/TestCompleteExtra.java0000644000175000017500000000330110576752034031052 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.extra; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test class for the com.opensymphony.oscache.extra package. * It invokes all the test suites of all the other classes of the package. * * $Id: TestCompleteExtra.java 417 2007-03-17 11:42:20Z larst $ * @version $Revision: 417 $ * @author Alain Bergevin */ public final class TestCompleteExtra extends TestCase { /** * Constructor for the osCache Cache Extra package main test program */ public TestCompleteExtra(String str) { super(str); } /** * Main method which is called to perform the tests *

* @param args Arguments received */ public static void main(String[] args) { // Run the test suite junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner(); testRunner.setLoading(false); String[] args2 = {TestCompleteExtra.class.getName()}; testRunner.start(args2); } /** * Test suite required to test this project *

* @return suite The test suite */ public static Test suite() { // Add all the test suites of all the project classes TestSuite suite = new TestSuite("Test all extra cache modules"); suite.addTest(TestCacheEntryEventListenerImpl.suite()); suite.addTest(TestCacheMapAccessEventListenerImpl.suite()); suite.addTest(TestScopeEventListenerImpl.suite()); suite.addTest(TestStatisticListenerImpl.suite()); return suite; } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/extra/TestStatisticListenerImpl.java0000644000175000017500000000716610576763237032621 0ustar twernertwerner/* * Copyright (c) 2002-2007 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.extra; import java.util.Date; import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.base.CacheEntry; import com.opensymphony.oscache.base.events.CacheEntryEvent; import com.opensymphony.oscache.base.events.CacheGroupEvent; import com.opensymphony.oscache.base.events.CachePatternEvent; import com.opensymphony.oscache.base.events.CachewideEvent; import com.opensymphony.oscache.base.events.ScopeEvent; import com.opensymphony.oscache.base.events.ScopeEventType; import com.opensymphony.oscache.general.GeneralCacheAdministrator; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test the cache entry event listener implementation * * $Id: TestCacheEntryEventListenerImpl.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ */ public class TestStatisticListenerImpl extends TestCase { private static final int PAGE_SCOPE = 1; /** * Key used for this test */ private final String KEY = "Test Statistikc Listener Impl Key"; /** * Constructor *

* @param str The test name (required by JUnit) */ public TestStatisticListenerImpl(String str) { super(str); } /** * This methods returns the name of this test class to JUnit *

* @return The name of this class */ public static Test suite() { return new TestSuite(TestStatisticListenerImpl.class); } /** * Test the basic implementation */ public void testCacheEntryEventListenerImpl() { // Construct the objects required for the tests CacheEntry entry = new CacheEntry(KEY); GeneralCacheAdministrator admin = new GeneralCacheAdministrator(); Cache cache = new Cache(admin.isMemoryCaching(), admin.isUnlimitedDiskCache(), admin.isOverflowPersistence()); CacheEntryEvent event = new CacheEntryEvent(cache, entry, null); StatisticListenerImpl listener = new StatisticListenerImpl(); // Assert the counters assertEquals(listener.getEntriesAdded(), 0); assertEquals(listener.getFlushCount(), 0); assertEquals(listener.getEntriesRemoved(), 0); assertEquals(listener.getEntriesUpdated(), 0); assertEquals(listener.getHitCount(), 0); assertEquals(listener.getHitCountSum(), 0); assertEquals(listener.getMissCount(), 0); assertEquals(listener.getMissCountSum(), 0); assertEquals(listener.getStaleHitCount(), 0); assertEquals(listener.getStaleHitCountSum(), 0); // Generate an event of each type listener.cacheEntryAdded(event); listener.cacheEntryFlushed(event); listener.cacheEntryRemoved(event); listener.cacheEntryUpdated(event); listener.scopeFlushed(new ScopeEvent(ScopeEventType.ALL_SCOPES_FLUSHED, PAGE_SCOPE, new Date())); listener.scopeFlushed(new ScopeEvent(ScopeEventType.SCOPE_FLUSHED, PAGE_SCOPE, new Date())); listener.cacheFlushed(new CachewideEvent(cache, new Date(), null)); listener.cacheGroupFlushed(new CacheGroupEvent(cache, "testGroup")); listener.cachePatternFlushed(new CachePatternEvent(cache, "testPattern")); // Assert the counters assertEquals(listener.getEntriesAdded(), 1); assertEquals(listener.getFlushCount(), 6); assertEquals(listener.getEntriesRemoved(), 1); assertEquals(listener.getEntriesUpdated(), 1); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/web/0000755000175000017500000000000011375310607024222 5ustar twernertwerneroscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/web/TestOscacheJsp.java0000644000175000017500000001616310511647706027762 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.web; import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.WebResponse; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test test the JSPs distributed with the package. It checks that the * cache integration is OK. * * $Id: TestOscacheJsp.java 385 2006-10-07 06:57:10Z larst $ * @version $Revision: 385 $ * @author Alain Bergevin */ public final class TestOscacheJsp extends TestCase { // The instance of a webconversation to invoke pages WebConversation wc = null; private final String APPLICATION_SCOPE = "scope=application&"; // Constants definition private final String BASE_URL_SYSTEM_PRP = "test.web.baseURL"; private final String FIRST_PAGE = "oscacheTest.jsp?"; private final String FORCE_CACHE_USE = "forcecacheuse=yes&"; private final String FORCE_REFRESH = "refresh=true"; //private final String PAGE_SCOPE = "scope=page&"; //private final String REQUEST_SCOPE = "scope=request&"; private final String SECOND_PAGE = "oscacheTestMultipleTagNoKey.jsp?"; private final String SESSION_SCOPE = "scope=session&"; private final int CACHE_TAG_EXPIRATION = 2000; private final int HALF_CACHE_TAG_EXPIRATION = CACHE_TAG_EXPIRATION / 2; /** * Constructor required by JUnit *

* @param str Test name */ public TestOscacheJsp(String str) { super(str); } /** * Returns the test suite for the test class *

* @return Test suite for the class */ public static Test suite() { return new TestSuite(TestOscacheJsp.class); } /** * Setup method called before each testXXXX of the class */ public void setUp() { // Create a web conversation to invoke our JSP if (wc == null) { wc = new WebConversation(); } } /** * Test the cache module under load */ public void testOscacheBasicForLoad() { String baseUrl = constructURL(FIRST_PAGE); // Connect to the JSP using the application scope String stringResponse = invokeJSP(baseUrl, CACHE_TAG_EXPIRATION); // Assert that a page was properly generated. // This does not ensure that the cache is working properly. // Though, it ensures that no exception or other weird problem occured assertTrue(stringResponse.indexOf("This is some cache content") > 0); // Invoke the JSP page containing 2 cache tag baseUrl = constructURL(SECOND_PAGE); // Connect to the JSP using the application scope stringResponse = invokeJSP(baseUrl, CACHE_TAG_EXPIRATION); // Assert that a page was properly generated. // This does not ensure that the cache is working properly. // Though, it ensures that no exception or other weird problem occured assertTrue(stringResponse.indexOf("This is some cache content") > 0); } /** * Test the cache module using a JSP */ public void testOscacheJsp() { String baseUrl = constructURL(FIRST_PAGE); // Connect to a session scope to allow the JSP compilation compileJSP(baseUrl + SESSION_SCOPE); // Connect to the JSP using the application scope String stringResponse = invokeJSP(baseUrl, HALF_CACHE_TAG_EXPIRATION); // Connect again, we should have the same content since it expires // only each 2 seconds assertTrue(stringResponse.equals(invokeJSP(baseUrl, HALF_CACHE_TAG_EXPIRATION))); // Connect again, the content should be different String newResponse = invokeJSP(baseUrl, CACHE_TAG_EXPIRATION + (CACHE_TAG_EXPIRATION / 4)); assertTrue(!stringResponse.equals(newResponse)); stringResponse = newResponse; // Connect again, but request the cache content so no refresh should occur assertTrue(stringResponse.equals(invokeJSP(baseUrl, FORCE_CACHE_USE, 0))); // Connect again, the content should have changed newResponse = invokeJSP(baseUrl, HALF_CACHE_TAG_EXPIRATION); assertTrue(!stringResponse.equals(newResponse)); stringResponse = newResponse; // Connect for the last time, force the cache // refresh so the content should have changed assertTrue(!stringResponse.equals(invokeJSP(baseUrl, FORCE_REFRESH, 0))); // Invoke the JSP page containing 2 cache tag baseUrl = constructURL(SECOND_PAGE); compileJSP(baseUrl + SESSION_SCOPE); stringResponse = invokeJSP(baseUrl, CACHE_TAG_EXPIRATION); // Invoke the same page en check if it's identical assertTrue(stringResponse.equals(invokeJSP(baseUrl, CACHE_TAG_EXPIRATION))); } /** * Compile a JSP page by invoking it. We compile the page first to avoid * the compilation delay when testing since the time is a crucial factor *

* @param URL The JSP url to invoke */ private void compileJSP(String URL) { try { // Invoke the JSP wc.getResponse(URL); } catch (Exception ex) { ex.printStackTrace(); fail("Exception raised!!"); } } /** * Reads the base url from the test.web.baseURL system property and * append the given URL. *

* @param Url Url to append to the base. * @return Complete URL */ private String constructURL(String Url) { String base = System.getProperty(BASE_URL_SYSTEM_PRP); String constructedUrl = null; if (base != null) { if (!base.endsWith("/")) { base = base + "/"; } constructedUrl = base + Url; } else { fail("System property test.web.baseURL needs to be set to the proper server to use."); } return constructedUrl; } /** * Utility method to invoke a JSP page and then sleep some time before returning *

* @param baseUrl The URL of the JSP to invoke * @param sleepTime THe time to sleep before returning * @return The text value of the reponse (HTML code) */ private String invokeJSP(String baseUrl, int sleepTime) { return invokeJSP(baseUrl, "", sleepTime); } /** * Utility method to invoke a JSP page and then sleep some time before returning *

* @param baseUrl The URL of the JSP to invoke * @param URLparam The URL parameters of the JSP to invoke * @param sleepTime The time to sleep before returning * @return The text value of the reponse (HTML code) */ private String invokeJSP(String baseUrl, String URLparam, int sleepTime) { try { // Invoke the JSP and wait the specified sleepTime WebResponse resp = wc.getResponse(baseUrl + APPLICATION_SCOPE + URLparam); Thread.sleep(sleepTime); return resp.getText(); } catch (Exception ex) { ex.printStackTrace(); fail("Exception raised!!"); return null; } } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/web/TestOscacheServlet.java0000644000175000017500000001547610324516101030642 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.web; import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.WebResponse; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test test the osCacheServlet distributed with the package. It checks that the * cache integration is OK. * * $Id: TestOscacheServlet.java 314 2005-10-16 18:30:25Z ltorunski $ * @version $Revision: 314 $ * @author Alain Bergevin */ public final class TestOscacheServlet extends TestCase { // The instance of a webconversation to invoke pages static WebConversation wc = null; private final String APPLICATION_SCOPE = "scope=application&"; // Constants definition private final String BASE_URL_SYSTEM_PRP = "test.web.baseURL"; private final String FORCE_CACHE_USE = "forcecacheuse=yes&"; private final String FORCE_REFRESH = "forceRefresh=true&"; private final String KEY = "key=ServletKeyItem&"; private final String REFRESH_PERIOD = "refreshPeriod="; private final String SERVLET_URL = "/cacheServlet/?"; private final int NO_REFRESH_WANTED = 2000; private final int REFRESH_WANTED = 0; /** * Constructor required by JUnit *

* @param str Test name */ public TestOscacheServlet(String str) { super(str); } /** * Returns the test suite for the test class *

* @return Test suite for the class */ public static Test suite() { return new TestSuite(TestOscacheServlet.class); } /** * This method is invoked before each testXXXX methods of the * class. It set ups the variables required for each tests. */ public void setUp() { // Create a web conversation on first run if (wc == null) { wc = new WebConversation(); } } /** * Test the cache module using a servlet */ public void testOscacheServlet() { // Make a first call just to initialize the servlet String newResponse = invokeServlet(NO_REFRESH_WANTED); // Connect to the servlet using the application scope String previousReponse = invokeServlet(NO_REFRESH_WANTED); // Call again an verify that the content hasn't changed newResponse = invokeServlet(NO_REFRESH_WANTED); assertTrue("new response " + newResponse + " should be the same to " + previousReponse, previousReponse.equals(newResponse)); // Call again an verify that the content is updated newResponse = invokeServlet(REFRESH_WANTED); assertFalse("new response " + newResponse + " expected it to be different to last one.", previousReponse.equals(newResponse)); previousReponse = newResponse; // Call short delay so content should be refresh, but it will not since // we ask to use the item already in cache newResponse = invokeServlet(REFRESH_WANTED, FORCE_CACHE_USE); assertTrue("new response " + newResponse + " should be the same to " + previousReponse, previousReponse.equals(newResponse)); // Call with long delay so the item would not need refresh, but we'll ask // a refresh anyway newResponse = invokeServlet(NO_REFRESH_WANTED, FORCE_REFRESH); assertFalse("new response " + newResponse + " expected it to be different to last one.", previousReponse.equals(newResponse)); // Verify that the cache key and the cache entry are present in the output and // that their values are correct assertTrue("response '" + previousReponse + "' does not contain oscache string", previousReponse.indexOf("oscache") != -1); assertTrue("response '" + previousReponse + "' does not contain /Test_key string", previousReponse.indexOf("/Test_key") != -1); } /** * Test the cache module using a servlet and basic load */ public void testOscacheServletBasicForLoad() { // Call Servlet String stringResponse = invokeServlet(NO_REFRESH_WANTED); // Assert that a page was properly generated. // This does not ensure that the cache is working properly. // Though, it ensures that no exception or other weird problem occured assertTrue(stringResponse.indexOf("This is some cache content") > 0); // Call again stringResponse = invokeServlet(REFRESH_WANTED); // idem comment assertTrue(stringResponse.indexOf("This is some cache content") > 0); // Call again stringResponse = invokeServlet(REFRESH_WANTED, FORCE_CACHE_USE); // idem comment assertTrue(stringResponse.indexOf("This is some cache content") > 0); // Call again stringResponse = invokeServlet(NO_REFRESH_WANTED, FORCE_REFRESH); // idem comment assertTrue(stringResponse.indexOf("This is some cache content") > 0); } /** * Reads the base url from the test.web.baseURL system property and * append the given URL. *

* @param Url Url to append to the base. * @return Complete URL */ private String constructURL(String Url) { String base = System.getProperty(BASE_URL_SYSTEM_PRP); String constructedUrl = null; if (base != null) { if (base.endsWith("/")) { base = base.substring(0, base.length() - 1); } constructedUrl = base + Url; } else { fail("System property test.web.baseURL needs to be set to the proper server to use."); } return constructedUrl; } /** * Utility method to invoke a servlet *

* @param refresh The time interval telling if the item needs refresh * @return The HTML page returned by the servlet */ private String invokeServlet(int refresh) { // Invoke the servlet return invokeServlet(refresh, ""); } /** * Utility method to invoke a servlet *

* @param refresh The time interval telling if the item needs refresh * @param URL The URL of the servlet * @return The HTML page returned by the servlet */ private String invokeServlet(int refresh, String URL) { // wait 10 millis to change the time, see System.currentTimeMillis() in OscacheServlet try { Thread.sleep(10); } catch (InterruptedException ignore) { } // Invoke the servlet try { String request = constructURL(SERVLET_URL) + APPLICATION_SCOPE + KEY + REFRESH_PERIOD + refresh + "&" + URL; WebResponse resp = wc.getResponse(request); return resp.getText(); } catch (Exception ex) { ex.printStackTrace(); fail("Exception raised! " + ex.getMessage()); return ""; } } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/web/TestLoadCompleteWeb.java0000644000175000017500000000504710254455232030740 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.web; import com.clarkware.junitperf.LoadTest; import com.clarkware.junitperf.RandomTimer; import junit.extensions.RepeatedTest; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test class for the com.opensymphony.oscache.web package. * It invokes all the test suites of all the other classes of the package. * The test methods will be invoked with many users and iterations to simulate * load on request * * $Id: TestLoadCompleteWeb.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Alain Bergevin */ public final class TestLoadCompleteWeb extends TestCase { /** * Constructor for the osCache Cache project main test program */ public TestLoadCompleteWeb(String str) { super(str); } /** * Main method which is called to perform the tests *

* @param args Arguments received */ public static void main(String[] args) { // Run the test suite junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner(); testRunner.setLoading(false); String[] args2 = {TestLoadCompleteWeb.class.getName()}; testRunner.start(args2); } /** * Test suite required to test this project *

* @return suite The test suite */ public static Test suite() { final int clientThreads = 10; // Simulate 10 client threads final int iterations = 20; // Simulate each user doing 20 iterations TestSuite suite = new TestSuite("Test all osCache web"); // Ramp up a thread each 500 ms (+-100ms) until total number of threads reached RandomTimer tm = new RandomTimer(300, 100); // JSP Test repeatedTest = new RepeatedTest(new TestOscacheJsp("testOscacheBasicForLoad"), iterations); Test loadTest = new LoadTest(repeatedTest, clientThreads, tm); suite.addTest(loadTest); // Servlet repeatedTest = new RepeatedTest(new TestOscacheServlet("testOscacheServletBasicForLoad"), iterations); loadTest = new LoadTest(repeatedTest, clientThreads, tm); suite.addTest(loadTest); // Filter repeatedTest = new RepeatedTest(new TestOscacheFilter("testOscacheFilterBasicForLoad"), iterations); loadTest = new LoadTest(repeatedTest, clientThreads, tm); suite.addTest(loadTest); return suite; } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/web/CheckDeployment.java0000644000175000017500000000304510254455232030144 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.web; import java.io.FileNotFoundException; import java.io.IOException; import java.net.ConnectException; import java.net.URL; import java.net.URLConnection; /** * User: hani * Date: Jun 12, 2003 * Time: 3:34:20 PM */ public class CheckDeployment { public static void main(String[] args) { if (args.length == 0) { throw new IllegalArgumentException("No url specified to check"); } try { if (!args[0].endsWith("/")) { args[0] = args[0] + "/"; } URL url = new URL(args[0] + "oscache.txt"); URLConnection c = url.openConnection(); c.getInputStream(); System.exit(0); } catch (java.net.MalformedURLException e) { System.out.println("Invalid url for oscache webapp:" + args[0]); } catch (ConnectException ex) { System.out.println("Error connecting to server at '" + args[0] + "', ensure that the webserver for the oscache example application is running"); } catch (FileNotFoundException e) { System.out.println("Error connecting to webapp at '" + args[0] + "', ensure that the example-war app is deployed correctly at the specified url"); } catch (IOException e) { System.out.println("Error connecting to webapp at '" + args[0] + "', ensure that the example-war app is deployed correctly at the specified url"); } System.exit(1); } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/web/TestOscacheFilter.java0000644000175000017500000001627310603706646030456 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.web; import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.WebResponse; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Tests the caching filter distributed with the package. * * $Id: TestOscacheFilter.java 435 2007-04-01 10:47:02Z larst $ * @version $Revision: 435 $ * @author Chris Miller */ public final class TestOscacheFilter extends TestCase { // The instance of a webconversation to invoke pages WebConversation wc = null; private final String BASE_PAGE = "filter/filterTest.jsp"; // Constants definition private final String BASE_URL_SYSTEM_PRP = "test.web.baseURL"; private final String PARAM_1 = "abc=123"; private final String PARAM_2 = "xyz=321"; private final String SESSION_ID = "jsessionid=12345678"; // Constants definition to access OscacheServlet private final String SERVLET_URL = "cacheServlet/?"; private final String FORCE_REFRESH = "forceRefresh=true&"; /** * Constructor required by JUnit *

* @param str Test name */ public TestOscacheFilter(String str) { super(str); } /** * Returns the test suite for the test class *

* @return Test suite for the class */ public static Test suite() { return new TestSuite(TestOscacheFilter.class); } /** * Setup method called before each testXXXX of the class */ public void setUp() { // Create a web conversation to invoke our filter if (wc == null) { wc = new WebConversation(); } compileJSP(constructURL(BASE_PAGE)); } /** * Test the OSCache filter */ public void testOscacheFilter() { String baseUrl = constructURL(BASE_PAGE); // Flush the cache to avoid getting refreshed content from previous tests flushCache(); // Call the page for the second time String stringResponse = invokeURL(baseUrl, 200); // Connect again, we should have the same content String newResponse = invokeURL(baseUrl, 0); assertTrue("new response " + newResponse + " should be the same to " + stringResponse, stringResponse.equals(newResponse)); // Try again with a session ID this time. The session ID should get filtered // out of the cache key so the content should be the same newResponse = invokeURL(baseUrl + "?" + SESSION_ID, 200); assertTrue("new response by a session id request " + newResponse + " should be the same to " + stringResponse, stringResponse.equals(newResponse)); // Connect again with extra params, the content should be different newResponse = invokeURL(baseUrl + "?" + PARAM_1 + "&" + PARAM_2, 500); assertFalse("new response " + newResponse + " expected it to be different to last one.", stringResponse.equals(newResponse)); stringResponse = newResponse; // Connect again with the parameters in a different order. We should still // get the same content. newResponse = invokeURL(baseUrl + "?" + PARAM_2 + "&" + PARAM_1, 0); assertTrue("order of parameters shouldn't change the response", stringResponse.equals(newResponse)); // Connect again with the same parameters, but throw the session ID into // the mix again. The content should remain the same. newResponse = invokeURL(baseUrl + "?" + SESSION_ID + "&" + PARAM_1 + "&" + PARAM_2, 0); assertTrue("a session id shouldn't change the response either", stringResponse.equals(newResponse)); } /** * Test the OSCache filter with fast requests */ public void testOSCacheFilterFast() { String baseUrl = constructURL(BASE_PAGE); for (int i = 0; i < 10; i++) { // Flush the cache to avoid getting refreshed content from previous tests flushCache(); // build the url String url = baseUrl + "?i=" + i; String response = invokeURL(url, 100); for (int j = 0; j < 5; j++) { String newResponse = invokeURL(url, 100); assertTrue("Fast: new response (i="+i+",j="+j+") " + newResponse + " should be the same to " + response, response.equals(newResponse)); } } } /** * Test the cache module using a filter and basic load */ public void testOscacheFilterBasicForLoad() { String baseUrl = constructURL(BASE_PAGE); for (int i = 0; i < 5; i++) { String stringResponse = invokeURL(baseUrl, 0); // Check we received something slightly sane assertTrue(stringResponse.indexOf("Current Time") > 0); } } /** * Compile a JSP page by invoking it. We compile the page first to avoid * the compilation delay when testing since the time is a crucial factor * * @param URL The JSP url to invoke */ private void compileJSP(String URL) { try { // Invoke the URL wc.getResponse(URL); } catch (Exception ex) { ex.printStackTrace(); fail("Exception raised!!"); } } /** * Flushes the cache to avoid recieving content from previous tests */ private void flushCache() { String flushUrl = constructURL(SERVLET_URL + FORCE_REFRESH); String stringResponse = invokeURL(flushUrl, 0); assertTrue("Flushing the cache failed!", stringResponse.indexOf("This is some cache content") > 0); // avoid that flush time is equal to last update time of a new entry try { Thread.sleep(5); } catch (InterruptedException ignore) { } } /** * Reads the base url from the test.web.baseURL system property and * append the given URL. *

* @param Url Url to append to the base. * @return Complete URL */ private String constructURL(String url) { String base = System.getProperty(BASE_URL_SYSTEM_PRP); String constructedUrl = null; if (base != null) { if (!base.endsWith("/")) { base = base + "/"; } constructedUrl = base + url; } else { fail("System property test.web.baseURL needs to be set to the proper server to use."); } return constructedUrl; } /** * Utility method to request a URL and then sleep some time before returning *

* @param url The URL of the page to invoke * @param sleepTime The time to sleep before returning * @return The text value of the reponse (HTML code) */ private String invokeURL(String url, int sleepTime) { try { // Invoke the JSP and wait the specified sleepTime WebResponse resp = wc.getResponse(url); Thread.sleep(sleepTime); return resp.getText(); } catch (Exception ex) { ex.printStackTrace(); fail("Exception raised!!"); return null; } } } oscache-2.4.1.orig/src/test/java/com/opensymphony/oscache/web/TestCompleteWeb.java0000644000175000017500000000307310254455232030135 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.web; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test class for the com.opensymphony.oscache.web package. * It invokes all the test suites of all the other classes of the package. * * $Id: TestCompleteWeb.java 254 2005-06-17 05:07:38Z dres $ * @version $Revision: 254 $ * @author Alain Bergevin */ public final class TestCompleteWeb extends TestCase { /** * Constructor for the osCache project main test program */ public TestCompleteWeb(String str) { super(str); } /** * Main method which is called to perform the tests *

* @param args Arguments received */ public static void main(String[] args) { // Run the test suite junit.swingui.TestRunner testRunner = new junit.swingui.TestRunner(); testRunner.setLoading(false); String[] args2 = {TestCompleteWeb.class.getName()}; testRunner.start(args2); } /** * Test suite required to test this project *

* @return suite The test suite */ public static Test suite() { // Add all the tests suite of all the project classes TestSuite suite = new TestSuite("Test all osCache web"); suite.addTest(TestOscacheJsp.suite()); suite.addTest(TestOscacheServlet.suite()); suite.addTest(TestOscacheFilter.suite()); return suite; } } oscache-2.4.1.orig/src/test/java/oscacheDiskOnlyHash.properties0000644000175000017500000000033710576756253024536 0ustar twernertwerner# CACHE IN MEMORY cache.memory=false # CACHE PERSISTENCE CLASS cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.HashDiskPersistenceListener # CACHE DIRECTORY cache.path=/tmp/cachetagscache oscache-2.4.1.orig/src/test/java/oscacheMemoryOnly.properties0000644000175000017500000000024310576752034024275 0ustar twernertwerner# CACHE IN MEMORY cache.memory=true # CACHE LISTENERS cache.event.listeners=com.opensymphony.oscache.extra.StatisticListenerImpl # CACHE SIZE cache.capacity=1000oscache-2.4.1.orig/src/test/java/oscacheDiskOnly.properties0000644000175000017500000000032310254455232023707 0ustar twernertwerner# CACHE IN MEMORY cache.memory=false # CACHE PERSISTENCE CLASS cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener # CACHE DIRECTORY cache.path=/tmp/cachetagscache oscache-2.4.1.orig/src/test/java/oscacheMemoryAndOverflowToDisk.properties0000644000175000017500000000041110254455232026706 0ustar twernertwerner# CACHE IN MEMORY cache.memory=true # CACHE PERSISTENCE CLASS cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener # CACHE DIRECTORY cache.path=/tmp/cachetagscache # CACHE OVERFLOW cache.persistence.overflow.only=true oscache-2.4.1.orig/src/etc/0000755000175000017500000000000011375310610015357 5ustar twernertwerneroscache-2.4.1.orig/src/etc/oscache.properties0000644000175000017500000001256110576751524021126 0ustar twernertwerner# CACHE IN MEMORY # # If you want to disable memory caching, just uncomment this line. # # cache.memory=false # CACHE KEY # # This is the key that will be used to store the cache in the application # and session scope. # # If you want to set the cache key to anything other than the default # uncomment this line and change the cache.key # # cache.key=__oscache_cache # USE HOST DOMAIN NAME IN KEY # # Servers for multiple host domains may wish to add host name info to # the generation of the key. If this is true, then uncomment the # following line. # # cache.use.host.domain.in.key=true # CACHE LISTENERS # # These hook OSCache events and perform various actions such as logging # cache hits and misses, or broadcasting to other cache instances across a cluster. # See the documentation for further information. # # cache.event.listeners=com.opensymphony.oscache.plugins.clustersupport.JMSBroadcastingListener, \ # com.opensymphony.oscache.extra.CacheEntryEventListenerImpl, \ # com.opensymphony.oscache.extra.CacheMapAccessEventListenerImpl, \ # com.opensymphony.oscache.extra.ScopeEventListenerImpl, \ # com.opensymphony.oscache.extra.StatisticListenerImpl # CACHE PERSISTENCE CLASS # # Specify the class to use for persistence. If you use the supplied DiskPersistenceListener, # don't forget to supply the cache.path property to specify the location of the cache # directory. # # If a persistence class is not specified, OSCache will use memory caching only. # # cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener # cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.HashDiskPersistenceListener # CACHE OVERFLOW PERSISTENCE # Use persistent cache in overflow or not. The default value is false, which means # the persistent cache will be used at all times for every entry. true is the recommended setting. # # cache.persistence.overflow.only=true # CACHE DIRECTORY # # This is the directory on disk where caches will be stored by the DiskPersistenceListener. # it will be created if it doesn't already exist. Remember that OSCache must have # write permission to this directory. # # Note: for Windows machines, this needs \ to be escaped # ie Windows: # cache.path=c:\\myapp\\cache # or *ix: # cache.path=/opt/myapp/cache # # cache.path=c:\\app\\cache # CACHE ALGORITHM # # Default cache algorithm to use. Note that in order to use an algorithm # the cache size must also be specified. If the cache size is not specified, # the cache algorithm will be Unlimited cache. # # cache.algorithm=com.opensymphony.oscache.base.algorithm.LRUCache # cache.algorithm=com.opensymphony.oscache.base.algorithm.FIFOCache # cache.algorithm=com.opensymphony.oscache.base.algorithm.UnlimitedCache # THREAD BLOCKING BEHAVIOR # # When a request is made for a stale cache entry, it is possible that another thread is already # in the process of rebuilding that entry. This setting specifies how OSCache handles the # subsequent 'non-building' threads. The default behaviour (cache.blocking=false) is to serve # the old content to subsequent threads until the cache entry has been updated. This provides # the best performance (at the cost of serving slightly stale data). When blocking is enabled, # threads will instead block until the new cache entry is ready to be served. Once the new entry # is put in the cache the blocked threads will be restarted and given the new entry. # Note that even if blocking is disabled, when there is no stale data available to be served # threads will block until the data is added to the cache by the thread that is responsible # for building the data. # # cache.blocking=false # CACHE SIZE # # Default cache size in number of items. If a size is specified but not # an algorithm, the cache algorithm used will be LRUCache. # cache.capacity=1000 # CACHE UNLIMITED DISK # Use unlimited disk cache or not. The default value is false, which means # the disk cache will be limited in size to the value specified by cache.capacity. # # cache.unlimited.disk=false # JMS CLUSTER PROPERTIES # # Configuration properties for JMS clustering. See the clustering documentation # for more information on these settings. # #cache.cluster.jms.topic.factory=java:comp/env/jms/TopicConnectionFactory #cache.cluster.jms.topic.name=java:comp/env/jms/OSCacheTopic #cache.cluster.jms.node.name=node1 # JAVAGROUPS CLUSTER PROPERTIES # # Configuration properites for the JavaGroups clustering. Only one of these # should be specified. Default values (as shown below) will be used if niether # property is set. See the clustering documentation and the JavaGroups project # (www.javagroups.com) for more information on these settings. # #cache.cluster.properties=UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;\ #mcast_send_buf_size=150000;mcast_recv_buf_size=80000):\ #PING(timeout=2000;num_initial_members=3):\ #MERGE2(min_interval=5000;max_interval=10000):\ #FD_SOCK:VERIFY_SUSPECT(timeout=1500):\ #pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):\ #UNICAST(timeout=300,600,1200,2400):\ #pbcast.STABLE(desired_avg_gossip=20000):\ #FRAG(frag_size=8096;down_thread=false;up_thread=false):\ #pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true) #cache.cluster.multicast.ip=231.12.21.132 oscache-2.4.1.orig/src/etc/META-INF/0000755000175000017500000000000011375310610016517 5ustar twernertwerneroscache-2.4.1.orig/src/etc/META-INF/taglib.tld0000644000175000017500000001072410621641410020470 0ustar twernertwerner 1.6 1.2 oscache http://www.opensymphony.com/oscache OSCache Tag Library OSCache - see http://www.opensymphony.com/oscache cache com.opensymphony.oscache.web.tag.CacheTag JSP A tag to cache post-processed JSP contents time false true duration false true cron false true refreshpolicyclass false true refreshpolicyparam false true scope false true refresh false true mode false true key false true groups false true language false true usecached com.opensymphony.oscache.web.tag.UseCachedTag A tag to tell the cache to use the cached version use false true flush com.opensymphony.oscache.web.tag.FlushTag A tag to flush the cache scope false true key false true group false true language false true pattern false true addgroup com.opensymphony.oscache.web.tag.GroupTag A tag to add a group to an ancestor cache tag group true true addgroups com.opensymphony.oscache.web.tag.GroupsTag A tag to add a comma-delimited list of groups to an ancestor cache tag groups true true oscache-2.4.1.orig/src/etc/findBugsExcludeFilter.xml0000644000175000017500000000013710632446351022332 0ustar twernertwerner oscache-2.4.1.orig/src/etc/jalopy.xml0000644000175000017500000003461710313343477017422 0ustar twernertwerner 14 false [A-Z][a-zA-Z0-9]+ [A-Z][a-zA-Z0-9]+ [a-z][\w]+ [a-z][\w]+ [a-zA-Z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-zA-Z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-zA-Z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-zA-Z][\w]+ [A-Z][a-zA-Z0-9]+ \w+ [a-z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-z][\w]+ [a-z]+(?:\.[a-z]+)* [a-z][\w]+ [a-z][\w]+ [a-z][\w]* false false false false false false false false false false false false false false false false false false false 6 30000 30000 30000 30000 30000 30000 true 1 true false true false false bak 0 1 0 1 0

0
1 1 1 1 1 0 0 1 1 1 0 1
0
1 false false true true true true true false false false false false false true true false false false false true 1 0 0 0 false */ * @throws $exceptionType$ DOCUMENT ME! * @param $paramType$ DOCUMENT ME! * @return DOCUMENT ME! /**| * DOCUMENT ME! false false false / false false Inner Classes Constructors Instance fields Instance initializers Inner Interfaces Methods Static fields/initializers
To change template for new class use|OpenSymphon 0 /*| * Copyright (c) 2002-2003 by OpenSymphony| * All rights reserved.| */ true
disabled 3 *:0|gnu:2|java:2|javax:2 disabled true true true false true false 1 1 0 1 4 55 -1 4 -1 0 8 -1 1 false false false false true true true false true true true true false static|field|initializer|constructor|method|interface|class true false public|protected|private|abstract|static|final|synchronized|transient|volatile|native|strictfp true true true true false false false false false false true false false true true true true true true false false 0 false false false false false false false false false false false false false false false false 80 false false false false false false false false oscache-2.4.1.orig/src/java/0000755000175000017500000000000011375310607015533 5ustar twernertwerneroscache-2.4.1.orig/src/java/overview.html0000644000175000017500000000027010316317501020260 0ustar twernertwerner This document is the API specification for OSCache - note, OSCache is built on top of OSCache. oscache-2.4.1.orig/src/java/com/0000755000175000017500000000000011375310607016311 5ustar twernertwerneroscache-2.4.1.orig/src/java/com/opensymphony/0000755000175000017500000000000011375310607021061 5ustar twernertwerneroscache-2.4.1.orig/src/java/com/opensymphony/oscache/0000755000175000017500000000000011375310610022460 5ustar twernertwerneroscache-2.4.1.orig/src/java/com/opensymphony/oscache/general/0000755000175000017500000000000011375310610024075 5ustar twernertwerneroscache-2.4.1.orig/src/java/com/opensymphony/oscache/general/package.html0000644000175000017500000000104510254455232026363 0ustar twernertwerner Provides a generic administrator class for the cache.

Package Specification

Related Documentation

For overviews, tutorials, examples, guides, and tool documentation, please see: oscache-2.4.1.orig/src/java/com/opensymphony/oscache/general/GeneralCacheAdministrator.java0000644000175000017500000002432110254455232032011 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.general; import com.opensymphony.oscache.base.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.Date; import java.util.Properties; /** * A GeneralCacheAdministrator creates, flushes and administers the cache. * * EXAMPLES : *

 * // ---------------------------------------------------------------
 * // Typical use with fail over
 * // ---------------------------------------------------------------
 * String myKey = "myKey";
 * String myValue;
 * int myRefreshPeriod = 1000;
 * try {
 *     // Get from the cache
 *     myValue = (String) admin.getFromCache(myKey, myRefreshPeriod);
 * } catch (NeedsRefreshException nre) {
 *     try {
 *         // Get the value (probably by calling an EJB)
 *         myValue = "This is the content retrieved.";
 *         // Store in the cache
 *         admin.putInCache(myKey, myValue);
 *     } catch (Exception ex) {
 *         // We have the current content if we want fail-over.
 *         myValue = (String) nre.getCacheContent();
 *         // It is essential that cancelUpdate is called if the
 *         // cached content is not rebuilt
 *         admin.cancelUpdate(myKey);
 *     }
 * }
 *
 *
 *
 * // ---------------------------------------------------------------
 * // Typical use without fail over
 * // ---------------------------------------------------------------
 * String myKey = "myKey";
 * String myValue;
 * int myRefreshPeriod = 1000;
 * try {
 *     // Get from the cache
 *     myValue = (String) admin.getFromCache(myKey, myRefreshPeriod);
 * } catch (NeedsRefreshException nre) {
 *     try {
 *         // Get the value (probably by calling an EJB)
 *         myValue = "This is the content retrieved.";
 *         // Store in the cache
 *         admin.putInCache(myKey, myValue);
 *         updated = true;
 *     } finally {
 *         if (!updated) {
 *             // It is essential that cancelUpdate is called if the
 *             // cached content could not be rebuilt
 *             admin.cancelUpdate(myKey);
 *         }
 *     }
 * }
 * // ---------------------------------------------------------------
 * // ---------------------------------------------------------------
 * 
* * @version $Revision: 254 $ * @author Francois Beauregard * @author Alain Bergevin */ public class GeneralCacheAdministrator extends AbstractCacheAdministrator { private static transient final Log log = LogFactory.getLog(GeneralCacheAdministrator.class); /** * Application cache */ private Cache applicationCache = null; /** * Create the cache administrator. */ public GeneralCacheAdministrator() { this(null); } /** * Create the cache administrator with the specified properties */ public GeneralCacheAdministrator(Properties p) { super(p); log.info("Constructed GeneralCacheAdministrator()"); createCache(); } /** * Grabs a cache * * @return The cache */ public Cache getCache() { return applicationCache; } /** * Remove an object from the cache * * @param key The key entered by the user. */ public void removeEntry(String key) { getCache().removeEntry(key); } /** * Get an object from the cache * * @param key The key entered by the user. * @return The object from cache * @throws NeedsRefreshException when no cache entry could be found with the * supplied key, or when an entry was found but is considered out of date. If * the cache entry is a new entry that is currently being constructed this method * will block until the new entry becomes available. Similarly, it will block if * a stale entry is currently being rebuilt by another thread and cache blocking is * enabled (cache.blocking=true). */ public Object getFromCache(String key) throws NeedsRefreshException { return getCache().getFromCache(key); } /** * Get an object from the cache * * @param key The key entered by the user. * @param refreshPeriod How long the object can stay in cache in seconds. To * allow the entry to stay in the cache indefinitely, supply a value of * {@link CacheEntry#INDEFINITE_EXPIRY} * @return The object from cache * @throws NeedsRefreshException when no cache entry could be found with the * supplied key, or when an entry was found but is considered out of date. If * the cache entry is a new entry that is currently being constructed this method * will block until the new entry becomes available. Similarly, it will block if * a stale entry is currently being rebuilt by another thread and cache blocking is * enabled (cache.blocking=true). */ public Object getFromCache(String key, int refreshPeriod) throws NeedsRefreshException { return getCache().getFromCache(key, refreshPeriod); } /** * Get an object from the cache * * @param key The key entered by the user. * @param refreshPeriod How long the object can stay in cache in seconds. To * allow the entry to stay in the cache indefinitely, supply a value of * {@link CacheEntry#INDEFINITE_EXPIRY} * @param cronExpression A cron expression that the age of the cache entry * will be compared to. If the entry is older than the most recent match for the * cron expression, the entry will be considered stale. * @return The object from cache * @throws NeedsRefreshException when no cache entry could be found with the * supplied key, or when an entry was found but is considered out of date. If * the cache entry is a new entry that is currently being constructed this method * will block until the new entry becomes available. Similarly, it will block if * a stale entry is currently being rebuilt by another thread and cache blocking is * enabled (cache.blocking=true). */ public Object getFromCache(String key, int refreshPeriod, String cronExpression) throws NeedsRefreshException { return getCache().getFromCache(key, refreshPeriod, cronExpression); } /** * Cancels a pending cache update. This should only be called by a thread * that received a {@link NeedsRefreshException} and was unable to generate * some new cache content. * * @param key The cache entry key to cancel the update of. */ public void cancelUpdate(String key) { getCache().cancelUpdate(key); } /** * Shuts down the cache administrator. */ public void destroy() { finalizeListeners(applicationCache); } // METHODS THAT DELEGATES TO THE CACHE --------------------- /** * Flush the entire cache immediately. */ public void flushAll() { getCache().flushAll(new Date()); } /** * Flush the entire cache at the given date. * * @param date The time to flush */ public void flushAll(Date date) { getCache().flushAll(date); } /** * Flushes a single cache entry. */ public void flushEntry(String key) { getCache().flushEntry(key); } /** * Flushes all items that belong to the specified group. * * @param group The name of the group to flush */ public void flushGroup(String group) { getCache().flushGroup(group); } /** * Allows to flush all items that have a specified pattern in the key. * * @param pattern Pattern. * @deprecated For performance and flexibility reasons it is preferable to * store cache entries in groups and use the {@link #flushGroup(String)} method * instead of relying on pattern flushing. */ public void flushPattern(String pattern) { getCache().flushPattern(pattern); } /** * Put an object in a cache * * @param key The key entered by the user * @param content The object to store * @param policy Object that implements refresh policy logic */ public void putInCache(String key, Object content, EntryRefreshPolicy policy) { Cache cache = getCache(); cache.putInCache(key, content, policy); } /** * Put an object in a cache * * @param key The key entered by the user * @param content The object to store */ public void putInCache(String key, Object content) { putInCache(key, content, (EntryRefreshPolicy) null); } /** * Puts an object in a cache * * @param key The unique key for this cached object * @param content The object to store * @param groups The groups that this object belongs to */ public void putInCache(String key, Object content, String[] groups) { getCache().putInCache(key, content, groups); } /** * Puts an object in a cache * * @param key The unique key for this cached object * @param content The object to store * @param groups The groups that this object belongs to * @param policy The refresh policy to use */ public void putInCache(String key, Object content, String[] groups, EntryRefreshPolicy policy) { getCache().putInCache(key, content, groups, policy, null); } /** * Sets the cache capacity (number of items). If the cache contains * more than capacity items then items will be removed * to bring the cache back down to the new size. * * @param capacity The new capacity of the cache */ public void setCacheCapacity(int capacity) { super.setCacheCapacity(capacity); getCache().setCapacity(capacity); } /** * Creates a cache in this admin */ private void createCache() { log.info("Creating new cache"); applicationCache = new Cache(isMemoryCaching(), isUnlimitedDiskCache(), isOverflowPersistence(), isBlocking(), algorithmClass, cacheCapacity); configureStandardListeners(applicationCache); } } oscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/0000755000175000017500000000000011375310607024147 5ustar twernertwerneroscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/clustersupport/0000755000175000017500000000000011375310607027265 5ustar twernertwerneroscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/clustersupport/package.html0000644000175000017500000000126210254455232031546 0ustar twernertwerner Provides support for broadcasting flush events so that OSCache can function across a cluster.

Package Specification

Related Documentation

For overviews, tutorials, examples, guides, and tool documentation, please see: @since 2.0 ././@LongLink0000000000000000000000000000014500000000000011565 Lustar rootrootoscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/clustersupport/ClusterNotification.javaoscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/clustersupport/ClusterNotification.java0000644000175000017500000000450310254455232034121 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.clustersupport; import java.io.Serializable; /** * A notification message that holds information about a cache event. This * class is Serializable to allow it to be sent across the * network to other machines running in a cluster. * * @author Chris Miller * @author $Author: dres $ * @version $Revision: 254 $ */ public class ClusterNotification implements Serializable { /** * Specifies a notification message that indicates a particular cache key * should be flushed. */ public static final int FLUSH_KEY = 1; /** * Specifies a notification message that indicates an entire cache group * should be flushed. */ public static final int FLUSH_GROUP = 2; /** * Specifies a notification message that indicates all entries in the cache * that match the specified pattern should be flushed. */ public static final int FLUSH_PATTERN = 3; /** * Specifies a notification message indicating that an entire cache should * be flushed. */ public static final int FLUSH_CACHE = 4; /** * Any additional data that may be required */ protected Serializable data; /** * The type of notification message. */ protected int type; /** * Creates a new notification message object to broadcast to other * listening nodes in the cluster. * * @param type The type of notification message. Valid types are * {@link #FLUSH_KEY} and {@link #FLUSH_GROUP}. * @param data Specifies the object key or group name to flush. */ public ClusterNotification(int type, Serializable data) { this.type = type; this.data = data; } /** * Holds any additional data that was required */ public Serializable getData() { return data; } /** * The type of notification message. */ public int getType() { return type; } public String toString() { StringBuffer buf = new StringBuffer(); buf.append("type=").append(type).append(", data=").append(data); return buf.toString(); } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootoscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/clustersupport/AbstractBroadcastingListener.javaoscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/clustersupport/AbstractBroadcastingList0000644000175000017500000001532610254455232034136 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.clustersupport; import com.opensymphony.oscache.base.*; import com.opensymphony.oscache.base.events.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.Date; /** * Implementation of a CacheEntryEventListener. It broadcasts the flush events * across a cluster to other listening caches. Note that this listener cannot * be used in conjection with session caches. * * @version $Revision: 254 $ * @author Chris Miller */ public abstract class AbstractBroadcastingListener implements CacheEntryEventListener, LifecycleAware { private final static Log log = LogFactory.getLog(AbstractBroadcastingListener.class); /** * The name to use for the origin of cluster events. Using this ensures * events are not fired recursively back over the cluster. */ protected static final String CLUSTER_ORIGIN = "CLUSTER"; protected Cache cache = null; public AbstractBroadcastingListener() { if (log.isInfoEnabled()) { log.info("AbstractBroadcastingListener registered"); } } /** * Event fired when an entry is flushed from the cache. This broadcasts * the flush message to any listening nodes on the network. */ public void cacheEntryFlushed(CacheEntryEvent event) { if (!Cache.NESTED_EVENT.equals(event.getOrigin()) && !CLUSTER_ORIGIN.equals(event.getOrigin())) { if (log.isDebugEnabled()) { log.debug("cacheEntryFlushed called (" + event + ")"); } sendNotification(new ClusterNotification(ClusterNotification.FLUSH_KEY, event.getKey())); } } /** * Event fired when an entry is removed from the cache. This broadcasts * the remove method to any listening nodes on the network, as long as * this event wasn't from a broadcast in the first place. */ public void cacheGroupFlushed(CacheGroupEvent event) { if (!Cache.NESTED_EVENT.equals(event.getOrigin()) && !CLUSTER_ORIGIN.equals(event.getOrigin())) { if (log.isDebugEnabled()) { log.debug("cacheGroupFushed called (" + event + ")"); } sendNotification(new ClusterNotification(ClusterNotification.FLUSH_GROUP, event.getGroup())); } } public void cachePatternFlushed(CachePatternEvent event) { if (!Cache.NESTED_EVENT.equals(event.getOrigin()) && !CLUSTER_ORIGIN.equals(event.getOrigin())) { if (log.isDebugEnabled()) { log.debug("cachePatternFushed called (" + event + ")"); } sendNotification(new ClusterNotification(ClusterNotification.FLUSH_PATTERN, event.getPattern())); } } public void cacheFlushed(CachewideEvent event) { if (!Cache.NESTED_EVENT.equals(event.getOrigin()) && !CLUSTER_ORIGIN.equals(event.getOrigin())) { if (log.isDebugEnabled()) { log.debug("cacheFushed called (" + event + ")"); } sendNotification(new ClusterNotification(ClusterNotification.FLUSH_CACHE, event.getDate())); } } // -------------------------------------------------------- // The remaining events are of no interest to this listener // -------------------------------------------------------- public void cacheEntryAdded(CacheEntryEvent event) { } public void cacheEntryRemoved(CacheEntryEvent event) { } public void cacheEntryUpdated(CacheEntryEvent event) { } public void cacheGroupAdded(CacheGroupEvent event) { } public void cacheGroupEntryAdded(CacheGroupEvent event) { } public void cacheGroupEntryRemoved(CacheGroupEvent event) { } public void cacheGroupRemoved(CacheGroupEvent event) { } public void cacheGroupUpdated(CacheGroupEvent event) { } /** * Called by the cache administrator class when a cache is instantiated. * * @param cache the cache instance that this listener is attached to. * @param config The cache's configuration details. This allows the event handler * to initialize itself based on the cache settings, and also to receive additional * settings that were part of the cache configuration but that the cache * itself does not care about. If you are using cache.properties * for your configuration, simply add any additional properties that your event * handler requires and they will be passed through in this parameter. * * @throws InitializationException thrown when there was a problem initializing the * listener. The cache administrator will log this error and disable the listener. */ public void initialize(Cache cache, Config config) throws InitializationException { this.cache = cache; } /** * Handles incoming notification messages. This method should be called by the * underlying broadcasting implementation when a message is received from another * node in the cluster. * * @param message The incoming cluster notification message object. */ public void handleClusterNotification(ClusterNotification message) { if (cache == null) { log.warn("A cluster notification (" + message + ") was received, but no cache is registered on this machine. Notification ignored."); return; } if (log.isInfoEnabled()) { log.info("Cluster notification (" + message + ") was received."); } switch (message.getType()) { case ClusterNotification.FLUSH_KEY: cache.flushEntry((String) message.getData(), CLUSTER_ORIGIN); break; case ClusterNotification.FLUSH_GROUP: cache.flushGroup((String) message.getData(), CLUSTER_ORIGIN); break; case ClusterNotification.FLUSH_PATTERN: cache.flushPattern((String) message.getData(), CLUSTER_ORIGIN); break; case ClusterNotification.FLUSH_CACHE: cache.flushAll((Date) message.getData(), CLUSTER_ORIGIN); break; default: log.error("The cluster notification (" + message + ") is of an unknown type. Notification ignored."); } } /** * Called when a cluster notification message is to be broadcast. Implementing * classes should use their underlying transport to broadcast the message across * the cluster. * * @param message The notification message to broadcast. */ abstract protected void sendNotification(ClusterNotification message); } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootoscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/clustersupport/JavaGroupsBroadcastingListener.javaoscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/clustersupport/JavaGroupsBroadcastingLi0000644000175000017500000002060110254455232034075 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.clustersupport; import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.base.Config; import com.opensymphony.oscache.base.FinalizationException; import com.opensymphony.oscache.base.InitializationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jgroups.Address; import org.jgroups.Channel; import org.jgroups.blocks.NotificationBus; import java.io.Serializable; /** *

A concrete implementation of the {@link AbstractBroadcastingListener} based on * the JavaGroups library. This Class uses JavaGroups to broadcast cache flush * messages across a cluster.

* *

One of the following properties should be configured in oscache.properties for * this listener: *

* Please refer to the clustering documentation for further details on the configuration of this listener.

* * @author Chris Miller */ public class JavaGroupsBroadcastingListener extends AbstractBroadcastingListener implements NotificationBus.Consumer { private final static Log log = LogFactory.getLog(JavaGroupsBroadcastingListener.class); private static final String BUS_NAME = "OSCacheBus"; private static final String CHANNEL_PROPERTIES = "cache.cluster.properties"; private static final String MULTICAST_IP_PROPERTY = "cache.cluster.multicast.ip"; /** * The first half of the default channel properties. They default channel properties are: *
    * UDP(mcast_addr=*.*.*.*;mcast_port=45566;ip_ttl=32;\
    * mcast_send_buf_size=150000;mcast_recv_buf_size=80000):\
    * PING(timeout=2000;num_initial_members=3):\
    * MERGE2(min_interval=5000;max_interval=10000):\
    * FD_SOCK:VERIFY_SUSPECT(timeout=1500):\
    * pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):\
    * UNICAST(timeout=300,600,1200,2400):\
    * pbcast.STABLE(desired_avg_gossip=20000):\
    * FRAG(frag_size=8096;down_thread=false;up_thread=false):\
    * pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)
    * 
* * Where *.*.*.* is the specified multicast IP, which defaults to 231.12.21.132. */ private static final String DEFAULT_CHANNEL_PROPERTIES_PRE = "UDP(mcast_addr="; /** * The second half of the default channel properties. They default channel properties are: *
    * UDP(mcast_addr=*.*.*.*;mcast_port=45566;ip_ttl=32;\
    * mcast_send_buf_size=150000;mcast_recv_buf_size=80000):\
    * PING(timeout=2000;num_initial_members=3):\
    * MERGE2(min_interval=5000;max_interval=10000):\
    * FD_SOCK:VERIFY_SUSPECT(timeout=1500):\
    * pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):\
    * UNICAST(timeout=300,600,1200,2400):\
    * pbcast.STABLE(desired_avg_gossip=20000):\
    * FRAG(frag_size=8096;down_thread=false;up_thread=false):\
    * pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)
    * 
* * Where *.*.*.* is the specified multicast IP, which defaults to 231.12.21.132. */ private static final String DEFAULT_CHANNEL_PROPERTIES_POST = ";mcast_port=45566;ip_ttl=32;mcast_send_buf_size=150000;mcast_recv_buf_size=80000):" + "PING(timeout=2000;num_initial_members=3):MERGE2(min_interval=5000;max_interval=10000):FD_SOCK:VERIFY_SUSPECT(timeout=1500):" + "pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800;max_xmit_size=8192):UNICAST(timeout=300,600,1200,2400):pbcast.STABLE(desired_avg_gossip=20000):" + "FRAG(frag_size=8096;down_thread=false;up_thread=false):pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)"; private static final String DEFAULT_MULTICAST_IP = "231.12.21.132"; private NotificationBus bus; /** * Initializes the broadcasting listener by starting up a JavaGroups notification * bus instance to handle incoming and outgoing messages. * * @param config An OSCache configuration object. * @throws com.opensymphony.oscache.base.InitializationException If this listener has * already been initialized. */ public synchronized void initialize(Cache cache, Config config) throws InitializationException { super.initialize(cache, config); String properties = config.getProperty(CHANNEL_PROPERTIES); String multicastIP = config.getProperty(MULTICAST_IP_PROPERTY); if ((properties == null) && (multicastIP == null)) { multicastIP = DEFAULT_MULTICAST_IP; } if (properties == null) { properties = DEFAULT_CHANNEL_PROPERTIES_PRE + multicastIP.trim() + DEFAULT_CHANNEL_PROPERTIES_POST; } else { properties = properties.trim(); } if (log.isInfoEnabled()) { log.info("Starting a new JavaGroups broadcasting listener with properties=" + properties); } try { bus = new NotificationBus(BUS_NAME, properties); bus.start(); bus.getChannel().setOpt(Channel.LOCAL, new Boolean(false)); bus.setConsumer(this); log.info("JavaGroups clustering support started successfully"); } catch (Exception e) { throw new InitializationException("Initialization failed: " + e); } } /** * Shuts down the JavaGroups being managed by this listener. This * occurs once the cache is shut down and this listener is no longer * in use. * * @throws com.opensymphony.oscache.base.FinalizationException */ public synchronized void finialize() throws FinalizationException { if (log.isInfoEnabled()) { log.info("JavaGroups shutting down..."); } // It's possible that the notification bus is null (CACHE-154) if (bus != null) { bus.stop(); bus = null; } else { log.warn("Notification bus wasn't initialized or finialize was invoked before!"); } if (log.isInfoEnabled()) { log.info("JavaGroups shutdown complete."); } } /** * Uses JavaGroups to broadcast the supplied notification message across the cluster. * * @param message The cluster nofication message to broadcast. */ protected void sendNotification(ClusterNotification message) { bus.sendNotification(message); } /** * Handles incoming notification messages from JavaGroups. This method should * never be called directly. * * @param serializable The incoming message object. This must be a {@link ClusterNotification}. */ public void handleNotification(Serializable serializable) { if (!(serializable instanceof ClusterNotification)) { log.error("An unknown cluster notification message received (class=" + serializable.getClass().getName() + "). Notification ignored."); return; } handleClusterNotification((ClusterNotification) serializable); } /** * We are not using the caching, so we just return something that identifies * us. This method should never be called directly. */ public Serializable getCache() { return "JavaGroupsBroadcastingListener: " + bus.getLocalAddress(); } /** * A callback that is fired when a new member joins the cluster. This * method should never be called directly. * * @param address The address of the member who just joined. */ public void memberJoined(Address address) { if (log.isInfoEnabled()) { log.info("A new member at address '" + address + "' has joined the cluster"); } } /** * A callback that is fired when an existing member leaves the cluster. * This method should never be called directly. * * @param address The address of the member who left. */ public void memberLeft(Address address) { if (log.isInfoEnabled()) { log.info("Member at address '" + address + "' left the cluster"); } } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootoscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/clustersupport/JMSBroadcastingListener.javaoscache-2.4.1.orig/src/java/com/opensymphony/oscache/plugins/clustersupport/JMSBroadcastingListener.0000644000175000017500000001674410531135551033756 0ustar twernertwerner/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */ package com.opensymphony.oscache.plugins.clustersupport; import com.opensymphony.oscache.base.Cache; import com.opensymphony.oscache.base.Config; import com.opensymphony.oscache.base.FinalizationException; import com.opensymphony.oscache.base.InitializationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.jms.*; import javax.naming.InitialContext; import javax.naming.NamingException; /** * A JMS based clustering implementation. This implementation is independent of the * JMS provider and uses non-persistent messages on a publish subscribe protocol. * * @author Romulus Pasca */ public class JMSBroadcastingListener extends AbstractBroadcastingListener { private final static Log log = LogFactory.getLog(JMSBroadcastingListener.class); /** *The JMS connection used */ private Connection connection; /** * Th object used to publish new messages */ private MessageProducer messagePublisher; /** * The current JMS session */ private Session publisherSession; /** * The name of this cluster. Used to identify the sender of a message. */ private String clusterNode; /** *

Called by the cache administrator class when a cache is instantiated.

*

The JMS broadcasting implementation requires the following configuration * properties to be specified in oscache.properties: *