From 9aff9c8eb0846cd1cb58b9afbe503490a522d05d Mon Sep 17 00:00:00 2001 From: Michael Basil Date: Fri, 21 Jun 2013 20:03:55 +0100 Subject: [PATCH] Pull to refresh, closes #360 Add ActionBar-PullToRefresh library Stretch ListView to fill_parent vertical so that pull-to-refresh is detected even when list doesn't fill screen vertically Add pull-to-refresh and remove sync button Update ActionBar-PullToRefresh to v0.4 and actually make work with pre-Honeycomb --- .../.gitignore | 28 + .../README.md | 123 +++ .../extras/actionbarsherlock/.project | 33 + .../actionbarsherlock/AndroidManifest.xml | 9 + .../extras/actionbarsherlock/pom.xml | 43 + .../actionbarsherlock/project.properties | 18 + .../actionbarsherlock/res/values/styles.xml | 24 + .../PullToRefreshAttacher.java | 115 +++ .../extras/pom.xml | 19 + .../header.png | Bin 0 -> 47838 bytes .../library/.project | 33 + .../library/AndroidManifest.xml | 9 + .../library/pom.xml | 31 + .../library/project.properties | 15 + .../library/res/anim/fade_in.xml | 22 + .../library/res/anim/fade_out.xml | 22 + .../progress_primary_holo_dark.9.png | Bin 0 -> 869 bytes .../progress_primary_holo_dark.9.png | Bin 0 -> 559 bytes .../progress_primary_holo_dark.9.png | Bin 0 -> 1282 bytes .../progress_horizontal_holo_center.xml | 27 + .../library/res/layout/default_header.xml | 52 ++ .../res/values-ar/pull_refresh_strings.xml | 21 + .../res/values-cs/pull_refresh_strings.xml | 21 + .../res/values-de/pull_refresh_strings.xml | 21 + .../res/values-es/pull_refresh_strings.xml | 21 + .../res/values-fi/pull_refresh_strings.xml | 21 + .../res/values-fr/pull_refresh_strings.xml | 21 + .../res/values-he/pull_refresh_strings.xml | 21 + .../res/values-it/pull_refresh_strings.xml | 21 + .../res/values-iw/pull_refresh_strings.xml | 21 + .../res/values-ja/pull_refresh_strings.xml | 21 + .../res/values-ko/pull_refresh_strings.xml | 21 + .../res/values-nl/pull_refresh_strings.xml | 22 + .../res/values-pl/pull_refresh_strings.xml | 22 + .../values-pt-rBR/pull_refresh_strings.xml | 22 + .../res/values-pt/pull_refresh_strings.xml | 22 + .../res/values-ro/pull_refresh_strings.xml | 22 + .../res/values-ru/pull_refresh_strings.xml | 22 + .../res/values-zh/pull_refresh_strings.xml | 22 + .../library/res/values/ids.xml | 25 + .../res/values/pull_refresh_strings.xml | 23 + .../library/res/values/styles.xml | 24 + .../library/InstanceCreationUtils.java | 89 +++ .../library/PullToRefreshAttacher.java | 743 ++++++++++++++++++ .../viewdelegates/AbsListViewDelegate.java | 43 + .../viewdelegates/ScrollViewDelegate.java | 35 + .../viewdelegates/WebViewDelegate.java | 35 + .../pom.xml | 111 +++ project.properties | 4 +- res/layout/main.xml | 2 +- res/menu/main.xml | 5 - .../todotxt/todotxttouch/TodoTxtTouch.java | 56 +- 52 files changed, 2165 insertions(+), 38 deletions(-) create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/.gitignore create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/README.md create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/.project create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/AndroidManifest.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/pom.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/project.properties create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/res/values/styles.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/src/uk/co/senab/actionbarpulltorefresh/extras/actionbarsherlock/PullToRefreshAttacher.java create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/pom.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/header.png create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/.project create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/AndroidManifest.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/pom.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/project.properties create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/anim/fade_in.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/anim/fade_out.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable-hdpi/progress_primary_holo_dark.9.png create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable-mdpi/progress_primary_holo_dark.9.png create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable-xhdpi/progress_primary_holo_dark.9.png create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable/progress_horizontal_holo_center.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/layout/default_header.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ar/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-cs/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-de/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-es/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-fi/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-fr/pull_refresh_strings.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-he/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-it/pull_refresh_strings.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-iw/pull_refresh_strings.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ja/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ko/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-nl/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pl/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pt-rBR/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pt/pull_refresh_strings.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ro/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ru/pull_refresh_strings.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-zh/pull_refresh_strings.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/ids.xml create mode 100755 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/pull_refresh_strings.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/styles.xml create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/InstanceCreationUtils.java create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/PullToRefreshAttacher.java create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/AbsListViewDelegate.java create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/ScrollViewDelegate.java create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/WebViewDelegate.java create mode 100644 dependencies/ActionBar-PullToRefresh-e8e6d2b58c/pom.xml diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/.gitignore b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/.gitignore new file mode 100644 index 00000000..40df3b38 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/.gitignore @@ -0,0 +1,28 @@ +#Android generated +bin +gen +gen* + +#Eclipse +.classpath +.settings + +#IntelliJ IDEA +.idea +*.iml +*.ipr +*.iws +out + +#Maven +target +release.properties +pom.xml.* + +#Ant +build.xml +local.properties +proguard.cfg + +#OSX +.DS_Store diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/README.md b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/README.md new file mode 100644 index 00000000..2e872fc7 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/README.md @@ -0,0 +1,123 @@ +# ActionBar-PullToRefresh + +![ActionBar-PullToRefresh](https://github.com/chrisbanes/ActionBar-PullToRefresh/raw/master/header.png) + +ActionBar-PullToRefresh provides an easy way to add a modern version of the pull-to-refresh interaction to your application. + +Please note that this is __not__ an update to [Android-PullToRefresh](https://github.com/chrisbanes/Android-PullToRefresh), this has been created from new. You should think of this as Android-PullToRefresh's younger, leaner cousin. + +### This is a Preview +Please note that this is currently in a preview state. This basically means that the API is not fixed and you should expect changes between releases. + +--- + +## Sample + +Eventually the sample will be available to download on Google Play. As we're not stable yet you can find the APKs [here](https://drive.google.com/folderview?id=0BxAFUoBj0OjaYTd3SUkzYjIydG8&usp=sharing). + +#### Video + +[![Sample Video](http://img.youtube.com/vi/YOYtPF-4RPg/0.jpg)](https://www.youtube.com/watch?v=YOYtPF-4RPg) + +--- + +## Supported Views + +ActionBar-PullToRefresh has in-built support for: + + * AbsListView derivatives (ListView & GridView). + * ScrollView + * WebView + +If the View you want to use is not listed above, you can easily add support in your own code by providing a `ViewDelegate`. See the `ViewDelegate` section below for more info. + +--- + +## Usage +You just need to create an instance of `PullToRefreshAttacher`, giving it the Activity and the View for which will scroll. + +``` java +private PullToRefreshAttacher mPullToRefreshHelper; + +@Override +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Get View for which the user will scroll… + View scrollableView = findViewById(R.id.blah); + + // Create a PullToRefreshAttacher instance + mPullToRefreshHelper = new PullToRefreshAttacher(this); + + // Set the Refreshable View and provide the refresh listener + mPullToRefreshAttacher.setRefreshableView(scrollableView, this); +} +``` +See the [ListView](https://github.com/chrisbanes/ActionBar-PullToRefresh/blob/master/samples/stock/src/uk/co/senab/actionbarpulltorefresh/samples/stock/ListViewActivity.java) sample for more info. + +### Fragments + +One thing to note is that the `PullToRefreshAttacher` **needs** to be created in the `onCreate()` phase of the Activity. If you plan on using this library with Fragments then the best practice is for your Activity to create the `PullToRefreshAttacher`, and then have your fragments retrieve it from the Activity. + +An example is provided in the [Fragment & Tabs](https://github.com/chrisbanes/ActionBar-PullToRefresh/blob/master/samples/stock/src/uk/co/senab/actionbarpulltorefresh/samples/stock/FragmentTabsActivity.java) sample. + +--- + +## Customisation + +There are many ways you can customise the pull-to-refresh experience to your needs. See the [GridView](https://github.com/chrisbanes/ActionBar-PullToRefresh/blob/master/samples/stock/src/uk/co/senab/actionbarpulltorefresh/samples/stock/GridViewActivity.java) sample for more info on all of these. + +### ViewDelegate + +ViewDelegates provide support for handling scrollable Views. The main use of a `ViewDelegate` is to being able to tell when a scrollable view is scrolled to the top. There is currently inbuilt support for: + + * AbsListView classes (through [AbsListViewDelegate](https://github.com/chrisbanes/ActionBar-PullToRefresh/blob/master/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/AbsListViewDelegate.java)) + * ScrollView (through [ScrollViewDelegate](https://github.com/chrisbanes/ActionBar-PullToRefresh/blob/master/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/ScrollViewDelegate.java)) + * WebView (through [WebViewDelegate](https://github.com/chrisbanes/ActionBar-PullToRefresh/blob/master/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/WebViewDelegate.java)) + +So what if you want the view you want to use a view which isn't in the list above? Well you can just provide your own `ViewDelegate`. + +``` java +// Create a PullToRefresh Attacher +mPullToRefreshAttacher = new PullToRefreshAttacher(this); + +// Create ViewDelegate which can handle your scrollable view. +// In this case we're creating a ficticious class +PullToRefreshAttacher.ViewDelegate delegate = new XYZViewDelegate(); + +// Set the Refreshable View, along with your ViewDelegate +mPullToRefreshAttacher.setRefreshableView(xyzView, delegate, listener); +``` + +### Options +When instatiating a `PullToRefreshAttacher` you can provide an `Options` instance which contains a number of configuration elements: + + * `headerLayout`: Layout resource to be inflated as the header view (see below). + * `headerTransformer`: The HeaderTransformer for the heard view (see below). + * `headerInAnimation`: The animation resource which is used when the header view is shown. + * `headerOutAnimation`: The animation resource which is used when the header view is hidden. + * `refreshScrollDistance`: The vertical distance (percentage of the scrollable view height) that the user needs to scroll for a refresh to start. + +### HeaderTransformers +HeaderTransformers are responsible for updating the header view to match the current state. If you do not provide a HeaderTransformer, there is a default implementation created for you called `DefaultHeaderTransformer`. This default implementation is what provides the default behaviour (growing progress bar, etc). + +### Customised Header View layout +If you feel that the default header view layout does not provide what you require, you can provide your own which is inflated for you. For the majority of cases, you will probably want to provide your own `HeaderTransformer` as well, to update your custom layout. + +--- + +## License + + Copyright 2013 Chris Banes + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/.project b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/.project new file mode 100644 index 00000000..22ff9d10 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/.project @@ -0,0 +1,33 @@ + + + ActionBar-PullToRefresh-extras + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/AndroidManifest.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/AndroidManifest.xml new file mode 100644 index 00000000..758fbb59 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/pom.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/pom.xml new file mode 100644 index 00000000..3eb85559 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + com.github.chrisbanes.actionbarpulltorefresh + extra-abs + apklib + ActionBar-PullToRefresh Extras: ActionBarSherlock + + + com.github.chrisbanes.actionbarpulltorefresh + extras + 0.4 + + + + + com.google.android + android + + + ${project.groupId} + library + apklib + ${project.version} + + + com.actionbarsherlock + actionbarsherlock + apklib + 4.3.1 + + + + + + + com.jayway.maven.plugins.android.generation2 + android-maven-plugin + + + + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/project.properties b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/project.properties new file mode 100644 index 00000000..faac031b --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/project.properties @@ -0,0 +1,18 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-17 +android.library.reference.1=../../library + +android.library.reference.2=../../../JakeWharton-ActionBarSherlock-c47975f/actionbarsherlock +android.library=true diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/res/values/styles.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/res/values/styles.xml new file mode 100644 index 00000000..43edae55 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + \ No newline at end of file diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/src/uk/co/senab/actionbarpulltorefresh/extras/actionbarsherlock/PullToRefreshAttacher.java b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/src/uk/co/senab/actionbarpulltorefresh/extras/actionbarsherlock/PullToRefreshAttacher.java new file mode 100644 index 00000000..1cd7bc15 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock/src/uk/co/senab/actionbarpulltorefresh/extras/actionbarsherlock/PullToRefreshAttacher.java @@ -0,0 +1,115 @@ +/* + * Copyright 2013 Chris Banes + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock; + +import com.actionbarsherlock.app.SherlockActivity; +import com.actionbarsherlock.app.SherlockExpandableListActivity; +import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.actionbarsherlock.app.SherlockListActivity; +import com.actionbarsherlock.app.SherlockPreferenceActivity; + +import android.app.Activity; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.util.TypedValue; + +public class PullToRefreshAttacher extends + uk.co.senab.actionbarpulltorefresh.library.PullToRefreshAttacher { + + public PullToRefreshAttacher(Activity activity) { + super(activity); + } + + public PullToRefreshAttacher(Activity activity, Options options) { + super(activity, options); + } + + @Override + protected EnvironmentDelegate createDefaultEnvironmentDelegate() { + return new AbsEnvironmentDelegate(); + } + + @Override + protected HeaderTransformer createDefaultHeaderTransformer() { + return new AbsDefaultHeaderTransformer(); + } + + public static class AbsEnvironmentDelegate extends EnvironmentDelegate { + /** + * @return Context which should be used for inflating the header layout + */ + public Context getContextForInflater(Activity activity) { + if (activity instanceof SherlockActivity) { + return ((SherlockActivity) activity).getSupportActionBar().getThemedContext(); + } else if (activity instanceof SherlockListActivity) { + return ((SherlockListActivity) activity).getSupportActionBar().getThemedContext(); + } else if (activity instanceof SherlockFragmentActivity) { + return ((SherlockFragmentActivity) activity).getSupportActionBar() + .getThemedContext(); + } else if (activity instanceof SherlockExpandableListActivity) { + return ((SherlockExpandableListActivity) activity).getSupportActionBar() + .getThemedContext(); + } else if (activity instanceof SherlockPreferenceActivity) { + return ((SherlockPreferenceActivity) activity).getSupportActionBar() + .getThemedContext(); + } + return super.getContextForInflater(activity); + } + } + + public static class AbsDefaultHeaderTransformer extends DefaultHeaderTransformer { + + @Override + protected Drawable getActionBarBackground(Context context) { + // Super handles ICS+ anyway... + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + return super.getActionBarBackground(context); + } + + // Need to get resource id of style pointed to from actionBarStyle + TypedValue outValue = new TypedValue(); + context.getTheme().resolveAttribute(R.attr.actionBarStyle, outValue, true); + // Now get action bar style values... + TypedArray abStyle = context.getTheme().obtainStyledAttributes(outValue.resourceId, + R.styleable.SherlockActionBar); + try { + return abStyle.getDrawable(R.styleable.SherlockActionBar_background); + } finally { + abStyle.recycle(); + } + } + + @Override + protected int getActionBarSize(Context context) { + // Super handles ICS+ anyway... + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + return super.getActionBarSize(context); + } + + TypedArray values = context.getTheme() + .obtainStyledAttributes(R.styleable.SherlockTheme); + try { + return values.getDimensionPixelSize(R.styleable.SherlockTheme_actionBarSize, 0); + } finally { + values.recycle(); + } + } + + } +} diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/pom.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/pom.xml new file mode 100644 index 00000000..d82fd8ba --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + com.github.chrisbanes.actionbarpulltorefresh + extras + pom + ActionBar-PullToRefresh Extras + + + com.github.chrisbanes.actionbarpulltorefresh + parent + 0.4 + + + + actionbarsherlock + + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/header.png b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/header.png new file mode 100644 index 0000000000000000000000000000000000000000..4832eb027368004132e3585e680281b403d8d3be GIT binary patch literal 47838 zcmX_n1z1$w_w~>NN(xAcfC58zNHcVY4Bg#b(v5_4r-0PZE!`k3UD6`bp>%y0|G)RU zk1~(Lb>`fC_St8xwbzMIR+PfTAi)5EK$tSp;;JAJ5(Nl^5DrEJ-Wg2F69Hb3T%a;) zU@&-jLunoOC%U7wmJ0~<4DabL!qkf29q=ZZtAwWOdk1q@4I_lY^18M#_H*i)!k*_naZ*jdr;NJeeC{?`lTfB(3O4ZQof!tZ{aqfX1VqfMTc8)Lf z?YJ;m9)9J{bF-W%V}Js_hhUy@qpj^BJpBi8s^(A1T=iB`mI8Z`s#ibT#Vs0I3Km*m=yC-dC ztEaBcN0xg%L!2N+&0U>p_IX(Pf(9r6N7se}yZyh<1|~7Bq0jsAectKEyj4Y;V^TH- zxpu#{?cM79luy;eiIIsOe%xt_cy!hOo-RIMFuY0drFv40G*yZxGH6g(-rb-EwBB*p zZB_RdooqF`=laF2%it76;t%SlaKwYUTEc@BTn2<(a6n5!6Xe$v2%zMKJ>TWv7o3&+ z(N=ZQ3jEN(>ipHce-Q@)*w4wiYxA1C^(_>vie7v9$+CV8cwDazDqX#p=0lM3^k<>7 zhT#t*ZByL|Pci>eKKZ=O@wzQQZGUGT{t`q1y9PtX-@+QO#Li zjM!y6@%~{w$Z+~a-r1-fizEi))6+>0rxIMErBq&iDh{81U93nhk03IwYqGVKhfXs8 zDi&Y!UksAyV2Lxg=lnM{_690W|{D+bDvc^v~DmxtE?}1rB6gf1t>oqac zzOsgV>H5F89Gsw>+(6N=aCjbAYugBen(_|*2 z#qTksgr!~U(?Hc5HS4_7KacJIyN5BYVWI9Qe%(``nBirel#nz?MB)>@MnCa?snC2o zDQMYiLTO-laO}$hewzW< z6&$D)L&0>QH0}{i!H)C1k?@+A&dL7@k8|dGE*ZUBM`ab9XrcVUC8^u&mCi`>De>9w zDHc%j+ndt${g;g%wEDt1 zF0n67h+G6i?J8uipY-eJ%OJVfkQiX(y9rv{|>-;xJ5B3F%L9}ePEYA(on;9t}ikz_J zGgr_2K{pyO&&~# zJ9UGXv{I7~(2IqRw;*JOBp|!DoyXto4EG<<9#exvrYB#l!4v+swpt07^N;V@hv%%q z?rz4!*uI-|o-4&m$6|sqb1^h#OKoc`hA^GTZic)gx`jwV+=pN$-R(p(5_>5yNk#Klq5bi(*+&CI{fXE0GLhuEGp=_1aAX5jLvTQb(JBv*+@nQ@RGb%7-T!vHq30KiEcc!5O8%|Z zk!i~7ra#|^ z59+YnUNtdUd!8ck_jXXA#v$53oydT%&Sk-=1jAtJ8tO1)MA6v6t;^fsZi+&&_LdHX11#B7&qnMTa#ji=DS z4YpCLpOg4v#*hiAXDG2KkpmDZ6kv3q9_el($`G~zX%!d>9fqVPi~yzr3WQq|nUq5^ z;3aTW@NNbi4t!w-{DWW^+zLzy#25mH8;9UZ5}C--Igx>W@?z!nHQG*da-_?%r_0kM zmbzxxz1=*ubY*2HiWuCC?1|>tR`+*!ssWdYiV1>Mk`v?#WBQvF4l{6?(ipK9D$dtY z2mSBUbIJ&9!Uz`5`dxV;Q4_ z#_@d1HFT8tUj_T4b%CUYext-f6h|o80u2zEAj`8L*i7geM6;n73K0%T+(J-I`LPf| zA|VS{c}dD50l4mDnIH7}DDfe{-Jv)^Z23vGdCIabMZ}U|N&<#RIJ?als{nay-hM`< zH}E=f%=NtY_|jW&)exfm{=Eqi5Je(NjG3BO)11@0uAGDlG>NC0ZB?C}#l^*~``Yx$ z?9atynV(RijH_N_3$qS55Kg%nu=P~|PRH^06Tfp5pPU;P-gvI`Yaf0^vXV@=ogaOl z+>Trz7Y3NJ+pyYQ^?vkM`X_~HYik=Hq1=2(Qk*S!ruL2qQSW5s(RN!Ztul&sGx9#T#?HS4!z^1W%iwUEmLeM>kdZtD1&TA!YzsjaDanTf zDu3Jgg9J^n(rO&TD<%u4ppaL=mDSwC&%+Nej;7-W1%Tf5A%IXAlJLTDiUypGM8iRd zP_kubAT>NZJm{0Za}q!hfm&lIqX7<3jb>9eeSrqS+59q{?n=`e%`;LPv862QETj8z zFQcdgNIk#YiQ~)gpl)See5~-^jo~3oO#Lbi6}9EY#8OjElKtcT)~QLSZRguAkv`5k zIK96(P@PSK^6;6hMN6aT`1}&ksOWoqiAhcZ6BLsW0twN`d^o%a5wwf~N>Uza zl%M|Tqyz<1t4*uv&G&3LDk!-5`ilAb>bbc!4DQ!3wpKMA%SuUk>v(&6+fc>FH9ql; zAGSrD`w^nFeCwn7dy6NQmaFW?737nL;~hN44v%ukpp?pU!OL*2jF_tf1iI?5-p0eF zC7DY`9d3(@17%2(bloO0B9w_^d@%*|k@*nD!|d!# z4Xb9#8oO1XCYVpE$l~-c)()wb<3Qm+T^kqj5+IKzfW61*c?y`_$hbL2k=47Hic)I` zeg?bS@ZVj9#JxRNg;-j=!^1<12_N^0GPz{-CkADY#f7=o^q9{qB(49r(UlyfH6~)y zgf=fsf}t^D&{k-5D{z~5d_I7hHLQKE^Y}q^MNL6oHxaRnGiEEKcLP>7KbpoSm^hU6 zcz0KrB3I)npsT`G(A@0jEC!P(9ApJkn{$)K4sz_O(Wj4^)}@%?hA+e@fH$U)O`cy% zlZIR23pFWz7g1AFyL)3J2{z(5Lq$Vl8leiI=ySz0f4LbMt{k-9!uuu!f?+O1*vSd~ zi2lYML%I4Df41VEvg+1#Dy13CI1N3DxrA>cEGmHrAWAGK7=%!$siMhY?r){dY&|@z z0D`8Nr7zmjWWoq^_4EXNz23i{c7?%M44R#PjavA&``QM5c_KG7afAL%&Hy?FNz)Di zutez2jS<&vkF)`xY?tMi4Dh>t9T9E?zjF^HT5K8u0>M-7WPt1DRbPeTYf@L+?W~%O z5Hf40Mbl!D^L~FF!O6|dq~B6sTB8C>_GFw}o9Aa`jgx+ByKElIL7Rs|6H;wR_)NiHOi?xBm$_t~ppTj(9+$!+cs(N$`P)+OnaXb51p#B_-{Y#hgi|1kL<(jx)RP2Mb zwdLg|_mvj2k<{C^)uWtBhC{pdcHb1Uy_P&Hl1p16X!JpgXHZYttDh1PL|#ZB=J%c) z%tGR&Z{dW{66OA%Hxb57#ybb%HNVG&C%C~)MU z^MtrTpiK7=a=$#hm#9b;jDjw2&mTr6bIR1sDq6gB3=hRbRYH=P1T`vBAK*<*(->-y zwHu|xBJTZu7*mo6g=5)(N2@5<$~vRNb0~o!mF4)+@o}?IuJdO0B_O3}Gwbty*!0{l zRG;Q_)4TL)hr`dNz}H}k0GwAZko^1YF~Nw^GxGTvMvjw-*!8$7Q_VdejVIcuW9Qi3 zQ7;+lw)7j<07Y^*@XUL|9UpA`@ep^A0uGrhFy>G8NfE?vQO}p%;$Mu@98bxIMCLCv zrc1vyp0uRN#y}08UCvlg7B^ ztveAI$|(9#f9EwN0Dp1V6>J4`IL8ULc1 z7#M_#nQ49S@dS$f-wy+ZxzlG_zhb`yZol*+jSxo+4A>9M^LgjiQT&zn1^uXz zg(#0k7gnU{3;f8p8YswbLlB!0x0Zcc3}h`9G$m&#(=$(y`u%Y{T)*rLynn{k|bBu9Ru zkcFe!GS{?GgYyD~+Q9&Wv824bytLHH&Ti%UU|gB?tH&{UNZiDZ%eG=o=pPCexMm~H zw9*g%{Llt;UgLb#8cH?x_1{yRZMg|&p&r|3_2M<#7$mjbU#54(sq(BcSl_V~TlHPh zfUS-hD`d%t_$BH)bZ-~MTx6&x_oukj`TMW~5aeOAAGbd0XM3`Y4)5*mq9fn648Dl% zHy=$~ou9YR`t`BH;Yl0=bB=Qzd9!|d>Df#f7+350sne-(a?P$OXDo+5BSs?YMzVq| zVXc+FTu+!d8k2W}emmV?;}x7lF*&8ROBLU2Z^lZ4ztVoOr7*AKAu(3i+-8HIRp^KB zhH99?TT?q-I%Q+&Ni+3`58Aq@5wg;Z+n^wBJO!G@v4lBM90uyTqN{*w&#Son$r3Xy zgY|G8WIy>K=7bNrzLPZ)rRjdXV)<%gnQAp8$Z#(pAL{T+iRt*KGRz8Y{5RFD3(L{h~_Yw`U#a>Na z?Tc!uE1zIXl>zW1!=%wh=SbZxR!b%0#zA5{-^(R(09D$vui2H`d#^xEU~`6NZ?#L$ z(u@-MrILl;ZB$8mA*RAjfk9bYo{7dBq8w1*gx62K$o+l72e)>2cVh;(j6Z+cNO);X z6!UAk=|hbIgwsk~>ErRw$rcD)r?=`MHqnYIHq%X^FJg7|q9C1rlUUsJ2m_&Oiuncecy!9jGtv2xm5!$r;uBBHV_kh2W8|&gi8HABUr#2~BerOqQ%qHz&vKYa2V{ zSHK`1m2wOk;;}YRqQ$7C) zciBrTv^P52bnU-R-T4A3v8rTqNarDT(;hdSAd|T?sDsm3^%g@`a8HPXUO#d_oI1P! zIZoVk712W9M1%lq2VPR5S?8rdfg=v)9{-}a~M_pH&b@w0X_{@=F&cgFP>S<2E((GKDuoTKngzM zL0=6zk%i-gTMW7+|8m~#BQ?F;yu7xyp)KUt^%U^iV)@@1`3}fD_actaU!a@d;T~AW z(hy16mgCWMy~*T_q~7$gEyFWPOW|DK{aiE-I#s=@qpOwS@86zx))H#A*pFuNcnl}e zbsNU1F3rvY0;eotDin&Cn8r`7t=wDsR<29j`??y5 zs$vD38BPUB^e1}xb4GFUNb5MaWR+DCNcJECAr3JX16G!-QQdaa8${XJFZ^8BuPCc) zUFVgk4qw)SPEP(1{7GG-Xv*ejsoq~fE}UWg8#x?l%UuSEv|E;^`e=?m5fud83h6xS zC&<1gzla~ANbwxkVb?TN;f!P*XtZO9?7=$4RMGkDv)WP;$h&DBR#N>fsN~Z^=aA`C zqa6&UXHKfYq)SRLB6Z4rO(zf^RmPW^J4jOPe+~Pr+}zT5y?%Z3uHF$wb@36@#TpH4 zm9c}t-G)QqZ=Qfof@j-{DsTAyti|JJuTzpWv?>W;YXPWC>rbJz6pNmQM5$C+|4hff z!F}nyRv^vlsaD%*h(PHXfhIW5khO%K9v|iWDoWP}*6Q9egH52i6}5J1Y*MM%_nCYR zDU>{!;qyRQd#iXviD%>>>a{hn?bVjc(`;#*#$oL0=GWutK~ASOy?FCIP(q1K@~Okl zoaE}X~EPx#T7zVdPIKf&`RF=EBzGp}#G3hkpe*;Ybb z=%iwb_G85QW~2H&iObmg`(&NyE;g%4=BeJsTHfKaob0e$c|IBwppy5ST+8G)nxw7= z;}fJ2d2I2FR20b5^v=b(4+$}wSsHn&+`UBK=-KqfT|Tksw^omceRZ~ZBm%BIM703jC^WAF9)E$8sMmj+ zvW9-NF(@*IbOknT1^YH0iR$E{&vQnP2QnC-0RqEsauNHnzAcaZJ*pntqr*-v+aB2ODbx_rWq z=eM$7>@zOzJgieH{~UgxzPT>m9WgM~u){3(=fsD%tyGjJq9qm!DF za9$K-xJwOO0qgZ=N}LR?ENI22w9c{6VL)Ia&tntKz5k+v{C3my*F$m7GYv1P4)KXp zd5`e(ZktKlj2RwlogDO7qpWRGDm8pA8*{S3U;F6L_|6{Ju(Vt(33|BZrHIiHE>j40 zz%|TRU~)Dyt%+HduSTF$t}M@IKroTUnA)R}HgSj*p>NZMxgf>>N=7?8L5&a7dmyGi zkh}{0`jVP?>y36WGdgvnk(^-UeH6A!3CqW|a;x-R*OsqB9Zyw043U!Jr(6cn&u5!x zIhg*pEPI5NfA#FR9?!koJ8xPaaJ<2dpEqOTA-H|3p5E@#(cP!!)JQSL6UK6@vA>T#ero<< zlrdDxsNS-|<>yYtk-LB_X>Sm*_epi{tnBLz{-2VC!t{&$P^|Q{hzS-Z`;%}QFOAJ; zxp|Q1Ln~x`;5PAJMvHMPFeUn>b5H%;z4_y>>*C|@e7rxYbVh{yqP|GIAM#;CWpBVSh0%R;!QIA2vP zk)*Zv)$Ppw284}OFFNN3aj%i-4dOq7O}$ko@{vA&6{(Ubz}>Y9CK`U*4AnT$NH}6U zIlc*t^Pp3oNAquN6{8MvaF9q61w|4Z50N4B<`AjK?-3iV4^AV-%uQZ50~ zi%lU>$2dQUZc*&?n_f^tDFY7sny9oxc+bZ?&)6UMKRc54@hBi_IGmLWVS^$ou~_!g zj!!A_BTW3}KrJhpVlC_5x)20LP$tq)i!Yqjn1fH;weDSy_`Gf-ya&>J7{#UE{4oP9 zII(DTQ*8<8L<pp#i!iKG;pAf&3o}yd|IDw%+m0csLlR{@{hA~9 z@uPF33K^BF9?55sKc}3GY$>$rl_av*fjHC10j_+9ByDo65p1G<_-7ema@4=bYhvZ2 zYn5Le2U1VI%yhKHULN8sfmHWtKfjwYM$&)4z;J_?2)S_ovpGnHrRSCQIm&%ijnrHZ zQH2KLSp#BSNg6*gbX&yzG-c6cCU7>ver;+VnB+>)a<9hz$cV~Fdub|C^VD2v|+DtIeoJ~ zO<*bxox)>cEbl5zlQVx819S-VHkJNatZTp5JSMXo`xqcY{g#*~EZ+A z=WxmvT#Z-{k%>YZdi@NanPiNFAu>qi`eBUX30?L#S}KLlwi$wR!>B;e?!A45!CO~x zC&mm zzNwWT3=?3jEE9q7(O&cir(M{ra^Gi(3EV?K)5M>N^16se`)}g>0(a-A(tRKQI z7I--72(Oe&|0c6>*rlAFKWcgd3w$lJ2Jm#GcCyY35NX~jvuZj`+en{ee)Z&YF;z-X zOA#TGiQzCVqvGToLGg9PdgeJK@{pAT4Y>QcRgJ(;|I^PB<=bA5sA#S2@{ zalr!Svv=A!L8e&;zJeLi?=oTWu zsu|qgD6H8wPShZOvxM!v%+m6*sYX@*)h#*~o9bZtiN5?-*$-!z@Lx=Sj(nNicWr;= z8XV{Wa2znEIG!ui0DWw}dzG`z-RB_2W!{vQLn=VmjD0PgQq^VbLRC^N&+cs`MHLUI zZX>)kMU|g6E>i{e5~O-_RnOwei0LzqG|E#JUSVQkv9k=%dJ?fwVeqQ-eGC`Jj?IQ; z*|X>e?UbnG!B^ad`YSU#1wa%>12qT~pMT!?0qxFHPYimkpARhY7*B$`q$s^;rS7Pr z)tufja!A)G)L$b4`gvv!f3~`guH15Kw2vh6!=+d81lL77@$J>h)kBl9U9JVWXQT0v zpuUd_Vpz7_uT>u7BY*p{e)9yZ#UC{*b+qL*1uOkzuOUxvps2w?<39to?V=tC$&xJ98b znd`rZkvKRWO8=VVl*Pg_Ov^;y1xu7+pGBk>F9?o>?_)#Cd`&5=mW4u+(3`5n1%%oF z9}}bI#>&0y--GzSa{jX}#{*rzXvJRW3?fjna{TS(F+o~sgafrQY`@6LM4D-<_`sim z`@0=d03H~b#__WUPDYVJI$!^H!93;amX-`0=kvW;PXY3%e$5iO(Gk?{SYq=>R(?4@ zvIo~11*a|CBcQ9xY-06R4F(&_=6`9DHD;cfnTbF_9*YDT_zEaXt8E{Ia;q8}8=ITc zaeA<3XJ^N91Y1A+8XXuIpnG35GdE|Q0f=)8vs?-~^_G+ChJCdM&1-kDF8WuAH|N;5 z*2RDQT5|Ewa4@P?i%=NGI&1<_80hDOqB(mHc0mCr8HXEYnWGQP?bfR2a~1@>-`w>O zK)tN4dOPvzgHHI-7NeGmg{r~9@sq1nz@C`I5$t;b@JVF?hOaKZ!jim1VXHRgN>bh4 zrW>*o<%Mdbm*PF~IF+g|D=x0ZhLZ{F?tLzz-V;ZEwgh-d%b& z31;fJJE~p4#t}qLu227F3P)DQZfD{~vq1wOWBqBKqR8|jktvAymr>`^{RPw>EeTDY z6a7qjdY?YfLci5A<}`6?<3O{svs0P%_}uoA=J&VxZES2_M2HKJza}FaHLv61;yO^a zvpcM}ns&A3pY%(Tk%w1U+1i>?DXAp&N4=b%nOR7|1U;12MVRm}x_)-zR_6kVfF$)y zJkOCp$_=|R{iNUY+ke{VTXK$;Ed31;T(FV4Eqm>$h&gZC%D=GPr!zhxOH7so5WN}^ zGTwW1oxK7>VHCLcO!1@d$?CbjJ47==LvY>u%Ek}I)=_WJ0uP%LCb_$O)L5BvdstQ6 zZ+MM$_xH9vb=+L?m^|ro)AZ7<bza8PEWv3ejzKXCjR1H)b2DRaQ9!%}Xf`6_~8Pn+YALegRS~#W$#RR0DEw zn$z3M3-r0Mk^9L?AT#%YmB`k{=FhcHkrmeS=M*78s|$f*YOSio+IniVqvZp!gG5o) z{*ThFQdd;aukmakRB7@>mF}**Au|w54d6 zSVf6ULzZO7Z?1D|ifC5Ua0q#ox>lzBE!oF{eLjQKxFJS~c&sOg5*`0wa{<@{H(N4@ zcHv>aD!P*0JhkgAwqm;W4#O(`T3nwPiq^Sx<%U~ z=NOlxsqH{whDkx4TDiuY!w5+ebWj>w!H1i_G^@`+arsmdVi{qx`-$rK{zTqLpg3L+ zMyFqiT|oqf%YCEI{mwcT{h6w-I@Fe%f5)$M5I;L#8oI00lh9?8B$9jmuNEu#e1BIv zm~Dds!Y6y4QF*OlSLtJD@%2NXLGMFmwl5bxQ7@1&4tI-R#*{+o0LRs)@Xc#Mz~Gcn z!=@f}wP||u8%+jeX*s1K$jaQgJ1hY(^8C%5GX-ZfP)Oyx$c`Iwq|1=hxl;(gLynWg zpT(PU*V__uFu*)3v>V`+m6Zhr!8lX{#QgmHJLB0lL}9>o;nfbTtyYi$p}4zTN%(Hz6SwEVE(+0dd)p*nWONcpli= zZtb&cp>EhUwbCjxhJ^&XD4=%t+QsFerK@{jXExCyEKFjuFM$mIV$!+2@d8@@gFf>> zKveA^7}~XSO-@pl!_m5GfiWG>?uyO6z@Om`1ANTsfz`D)fnC1XC{opqZZSx$n+~1$ zPGnvaUXOMD$`zP}EK-0;Il|!HuG7Zi9lvJtbxD17k=oGu3UVZT!)*$aG}^J)Dq~AU z0~9A)h(#`-d8W*rdHDM`(O#de2LCdJI*p&Jl2h>Sm$c!X^|NazpuSNMsKKtN5)@Fz z5Tj}Fj8c5CwXgMQZ+JQOOkn>tCbRCgNvA@UK05)yERUk;tB}lLz^GZ5>IoS4)-EM& zFBv8$VvAod5a%?FdiTBy)6f|M+=DSP<$f!-S^16c{Jf#1Betm)S6_b0XsBh?bssXuoU_F zWNaaCt#60v@?re-><>CDLeQ1iaN`dBuOD0Y>$ATX3wBdGmRo`F0sZ8qA+cfc<$N@c z{@Yf-$M`5+?c`G?d+hy&>tv{GwmUv}-i&VGgXGims+RaF ze_W(+q${nmu)PBfYXNOF5L0?NPeOU=B%cm74~--3&sl;(wX9l?d6$*${3JYjlaQy# z;KRcRt4>#%1i$_1uF@SP|3M&p?-WUES-fcqOb6h866qh)N;c2m@Yk|IT{_WxvZ&-} zm<(Rf=s#pWOusG!@VD_&d5{_5oA!$%jr`rW-59nX_{hMq_uO_-9gia=$xQdFbOwRR zWp0WHXCoC!(G3LtStYJzneo9enhOGOpkA~S^JET_IOIGTNS5c_KZ$SNKQ<0;^@4DA zYhn*%06$TV>{kO~0AH?ozq^^~tY{%HA>$t%hG&-xUcQD~uv{GYzPY(RbsePs132Ed zFK^3ewvi_WkE!{zv5pn%vz)3z#^?a71F~H)qG`P9>FuYo63Dl{ z+oWrfbT%4|XNi3?Ob7jD7w>ys7^f4YtlOZi$tVp#;cHd~?fusizL>7d-UhLl)1Lv#VuV|$yF{=dxA?K^YBP9iUQ=GUP?Zk!-A!+rvqLyp zw#NCnP;M+&FOg0P3=0U_J560f71`fo<7KG;z~Cod&IkNLUm8XEomfBgrgUDV3m}&xQg?%qK%qeaQSL(A_-tE9%*yx*czkBJeGl5cYk2PY44J%D7 zvaEbBi8was>XU2?#L_Pu-XQUbIhD+gk53UDQg2DX}@g@ zZZnFk<}39W?ls$1F-f`W8yYY#5A2aR72d;=3GpLf=Hpq(@-zj()I}q*0L4NEZQ>U1 z4}T=QmhP7s>_0f5);9pHiNA=VLd2rxMj3QgZA?_D4vWKhk#wRm{h6tGV&@sX;H!(5 zv>bvOE|>aRWt9tf5Pg#0sKJFG5V-q#YuCe{o3|}br9*BT2a4{LW`%P7F|RDzyCxPk z^~3oPpX>clc4Yx;NDE?s8hrz>B~(fpLLG0VEG>YE=9a zg!1fpFDPJlx_BauO>F+WILFI+vDR$E(X%J_8ae1}Qe+;#=k#vnsb_!}&+u}r>5T08sED&isumAenQLDvF z|M2Gpt>S2|@T1b>UnT#Gy4=~B8Nh+HHJZ+moSY1*HtY`C$@PDzdc3LPv0bS4Jl&l8 zcZHLCmDJU_9Iv*=YzbWdOiY?O_J6#M|7O?X$R4|=PkX7CBoXrDM(-d~^iRSFp;GcG z!%(`*f{K^Eh}C|)G0s1PGMj$bhVGrAZ0-B!l)r9?oF)2|6#P!w{cZ7PX_D)=1_OO7$AXp99Hk7{QpXYW4{&xqVS{H zMPWKi;9b)?+dx`H-`(lp>(0lATWnz7f$8)Eo>B1jpbn(0qqDray1KG*-%#a?Y0_ps zmNAmb(s_H-3i>`Z<@|7Wz4my&*2HMjA4vdkwvf1o2ft}flbQwLyIx_>_SJVTzkC+g zhChmiesA+v_^JJ`Nay+dwZA*`kNA@K;%mC@WZGtl!(UB!U?ID6<{|?xk7eClE9z= zw@xafmh;|BDUgjhIXRk)b4yDZipA5re-9Sx)_neqx$Vy>ntcow9nv zu`TKr0jLOYrTV5O;NJ0Z#c56*ZSDNY-vggWfn}?tG%;79)7sj4dAOW9WLl})Y@A_E z6<<&kgl5o4vwKL#P6(HBZ zN3l1*55+wa2b-}IFE`%%34=6Kk`;>yBx>w*V6YItzpr04-*{LHU&R6i0>Je0%?^yrarWIVPqiFW0BJ^k6sXI9=d@>o!adg8Q+CI?i~83U2c&-x%CZFQJs- zqs00~h!mwKu3~rtGEGt8r5oTy|svYk%18`V^ zsjV{-%5eOw_GCjo0nx6SA8~F0a;;mmbIpMW6&tr!;IcNT-?56;5TOJPrE55hfA}r; zq|(*b=Zrl3^lpEt_?%8l5+R?cppaChx|X7$z^SpgW07QMvlcAMxOsQrk5ya=G6WRX z2_YFwH)`&Qc)%;f>u~?x^yePN@H_F}=bn3ed$>>_xnM9@%$BQ%$DnZyU_hGdzF{wf z4WUwTb~1B4cAGRvY8{5v_OL!znD+b_rmy~pw;|t(;T%r7_NF!93tx8b6TtjXyay6@R$XSj?q8#huStXP(8hDW z0cRVg@D*l%Tm~sC>bcdY0iMV8o*_z&ema?Jn&!H9UPMMY6XS4KKdW7Jo&>G7O^`8O zPx~jFG7lXgo2{>(uXl67l%Pga9HaeLPdet$UqFnhjP<`%1$N5D3#h*9BSwmmGEkEL2Z@QY_7j)Bc zxb}MAQ$xY725d_HNqiSZ>{A@pZwh=+)b-P*_N(E^FhgNcBTI)I@7msJ30{bT_Fn41L_;!p#3HL4T&O>Vm`0hi%mJHEN>)+YW}2}8jR>adyX;4zW9e4DMJj$@`t^VDF9QW-!9&wG-*iExymX&6r6 z8ihntjzo_K2hRbjZ*K#B;bVtpfm)9EjQac_ti!LzN+Esvm(AQ@1c~`rs^=g;DJKTO zSbr)_aG@d-ZQpT);Pf=xvmGOYSV^(-4Dk??e%W$|D>ER0vG4Bvhsl?N@A6tT4Hp~7 zf`WZMy#YCXbh%uu0bu)&qQ81|2KTptfJ?KC96YMKKKWc<56|$699`^CE}T@$RrhDjhq(n!9y+;HJDf3cfSGMMrXM#(8i(w*d+4%`t^%bX>k>T zhx~DB6_u3BM7gH?cY?`}Ae2Sb>uAQyWuez1qjm+*NyTTEJEl6N+~6(*$c|y!+VQ2Q z00ra4bC7gN?Njn5umI@Y0;_oZmE5aElOJ{CYi(U6nMF$LRAKqXQP_OBz6pFz6pLO* z+)PMX9f%C6KFMpt_i}U>sA`b}(JmeM1md`BMfhQYh|nfwigtU>sPD=AES8)ahp2<> z-E;Y$YNr_5$)h=s~^Ikfq z)w}F>{!}izwnfETjg<(%w?5l(u7*5gt;v>7(*nokZfmI32DZ;%OU+9T9VS?uqI{@K zU7;61*+xtkdFKBYQm9B=#sKjNATk+rqA;L3P{&qyVo)GZy#DRCoWA1MG`%ocu|$0i zExRl;wb{~D5LO7m3ejYh&2s*vUvcNi-fn$WL;A`q^$7xo#15p@03i4fL|M9?`4Kvm zVH!eblV`Tefc^|vk#LMNij0VCX$#e+>*Gn)s3(9^7F8;{4m(u&3on*GHwuxar!cxAvk^wc|XOmWy+DN9l|IX>dnt z(SqW;$L8EWaB1>iA6ZkSRe+?Zb={qMyjXkC0jLUhre2--*jB8tzJbB<k^u&EEdLZSRjN(7ohcb+d{ zfb2AYF=JJ9bfR#9!%M){91;gmElW<42=TNaC$gQILGtBxZx7&T1>pD1@!X7%r>XP1 zzY(WmbK9E<3kxIWFxO0JFda%5%j7YM2G}WZE+p6QW_Pj9foFwct%HVDj$RS|myz@L+2Zn7imSLtf2WSr7z|FsYnMa=j-70iSpeg_~ zTpOSom3pm;S-foi4|lG7V_9(Nx9n!a_{)t?Q4B`=e@wjxJeB|ZKaRw)XI8=?BiSRf za5AzZ$=*daWo2_j*@?<3BxJ9IWbaM(-XbGpkNhq*new@=n`3-=EW`1MN`8_8sTy!f}4 z@8?;;)F?m=uwUw3fI`?;?m>nm=;GjxuNuk#yFF$5y_}RhUgPyfLdjwoul%!bd=8@A z_kDfO@|ha*k<^6UrbPkTk`8OXU>S~o^W9l&$9!bf^BW)3xL;F-H$%IoIUQKzKyWF+ z3Q*3q5+c9?rmLG3H=v`VL*^(>=IFPk|M1 z$fjd#ECnqQ^-e1x`=rbk;kcKX^uMe4b_*~a1m<*qRR3%5EgY$K8Th?z(;Du)I+-(>+aR?&{d4As5aJsIk@4Mq3qiTItbau*kYcV05eKuU-o2xo zo1PxzV3)Z3?}dJG0IjKy;0Lv1pF8e+SlgmIdJ;Ejy5NP&=8;I#+1G9gHy&$8)PEZ* zf1es7`;+iyZtz3TSsIf6s6DQLf@?D zYG^;2l(CAE|2(p3FDfpSE5pw_QpCo& zDH9rE(k}Mhi$X1|_Ph-^Au5Qf8rly13q9vK71O`xFfQY6O*3u5j_(p#?uWcN5w(%4 zU)DRf$Y210=WZ*7$&}~Bv$`>5b$0&DHXuDQ3KBYYg1BdT{og_X)I z0v|rio!(AUc(HNdN6(uh#ZK9d{^U)L^`1Vld-7pnrBJFu7&(%(o7QGl5fQ%r*DIva zewQ#)Y?4Nk@k{Ug;E|GkV*TZA{y%NWG7*A`tG5b;3`Egl4Tfg=7f{D#tGndVg{t{02Ht2$@RrNx5Yz1YR+ecc_Hv{)D+U-NMI ztJF{ZBk;eH&Di&I&w!zWN`x;v?_up<>vI1CQ`N2~@1>jWGOf);$1EM-gXujpnmtxc zntHs)nk)16qYWv?^7=UdM9uR-2-z-Ye5}rrk})2dVPYl~tx7fOpT<6{7j5geUQMv~ zQW^>^iN%WfuQa02r|tJukSlW2U;MF1Ea!C8xwS^~#IN3nW950XN|^58&F3R*a>~YB z2RFC&?6JszaB} zT88=7dxd9bGBqvdKP+Rb*Rw{xs!5&})^a&N2R2H(%mHkljAtzEGSl1q&9P)ySg?5* zH|RBdx_IKJ{O>ji(pneAKW~0XRZ=cSqjyUG;`Fe7rD6WkVz1ZY0+97=f#PP8d*9A> zJ-gl(*P#N)ao#3vI8EGo7Vr7%mFP452h9@}S83<{Ms5*b>*e0`VRbxk49+rvj!|6f z^takN$Kl_vaY^_Kcx3AsRH$Q$1D_9=!kKMK|@|)qB?yAun6?W|t1F+4FLB_zUx7Pei`_eM~|m89_B-`F!a!nV~sGrRR9>N~4E` zC0jtNY+dq__L&Ex(qI{g8i3o@Eu{zpW0svBmn>q$l3c7W3-JG3cR=mI|QVJWkb9R;`Udg@M*V)+_Acoy= zUa>(wnmnmnQAWzTCpjnxC#m~M#RL%{;d0jp%ZiDRy+@>>!Jc8m20uLi0-|7lA?CgR z2UGXxeRoD)&1WwAtNarh!g=4{Ma;oGnVDI+>pU+cH*Pob>Mi6;-xt*N5I z&CA=}+uKT~Brl(5P;T22L9eByMLS5CQIyE%be)nz1tW}cISOu zT-=8b`bI{KG&J7;nVO!hJyOYZg>xXH<)bF#dCAo+eR4nk}Sh8aOs9>!n?32JSfEi zlkXBDdUr{ih$N&#*wMetLj`-<+r6Ml)Xg_=JKUZN3kw6lM+@rv$jJKhD(|ftF;31E zKCw+ays7*|EL9S>+M2 zvuewCL@h^u_~|=QJPqmBIDJ=>+d)gbs+n|oCYe9A&zbjK4VTYhZ1b4@nE4MQ;V^Pr zhqB_-`W$-mpAlDiV9ZXPx0QW8Dy+{)j~FEzJ!aq2)nx>AslELl0L_$CRNyNEQP32= zCjfE(?RtFwzTEEJm5Bqk<~&&(9|+icbxOmF=>DJUxHvk@8J*bfUsM7Y2z zGjytf65vjxV#bi|hI_Sk&gU;*wzs!IKb!PB*$AiQKVOW~gpb+X**V{NSIa2jx(JFR zrT|@t6hk1Nlpet%TmAD#CwFLfrS}4uhvWSTr``|3S>L~ZudarLUjY}dtc(smp+79S z;}Y`M)YNSO0kd+0LetvR_;@JlPL|%8g5qIP>j#^@sIZW~Zln%hp2CUF60Oz8QEw5P z!Fx#>)n-4>tA zvox}xZq-Mj8d5x_>0zl34}XI#{Q2|eo}M09ygS|bB zI7!QA#DWG9c?vF^WJ-^f5bRuD<0=t0w&0d;N{Wgm-<{{++IWaFg7)ZTVPOFa_4SpT z4Gj$-RZ%lB74+NKc$buvz#b>TyX)a`09zwVJ!yDkh8W|axoMikocW^~3?@I43 zV+$QJm8>NZmA9_){Eaex&Z)Mbb$`%a!U)Q_C@#f2L$=C6Y{7SP?gcX!PDwS^T{Gl>IcP-)8T{+0pLG z1RUezU(`N;E9o`_Z~xN;W|*r0yi#O%xc7Q~1$fI~lt8s;Dr~(S=1uoQ zbAGrWOZ-Eo^23z`awdupRA7)$%*T|I%VH2ruXR7(|J&_-rE67_3?X^LTkCtY0>RZD z!~L2UjYEc;&dlK5FH&2BR^ivh$ctTE!3WEIPI|jStR9uE{(dEJ5-=w`s849if#c`?ITm) zD@gf_k?N`{2&JNPKc4%eW3+RmJvNi=8qq1h3Q(XxTO>iP!jezJT#NI=R+)j3YuB#n zBqP!1rzYDU9kggBiCMg$+8iK=e>@-3--WTi<-!t&6J_1dj@mTHI8#{n}3Yb4ub zI9LMQ92*|TVP05uDoOmlde-mAPGZ)7Q}_DUS7X`_*MT^$2P&ub9t(7 zV(oo*skKC^w%QpICh7kzT&PexSmDPQS8=Ia5q$YI?83WYk>Nf7YnDhKUcKl2EGbcf zEr2lAu4?_nn+wT8|DjImc3)^AVW`?nj4>`N6*I(oT117so42jOlC(ssh2v7c$tqN! zHqSHngv!6Bo%=1tp2@sOaz$Tr03t0}Va^`e&{dfj6d!BPt>uoTzo6@p<*RqO@jClJ zbitYGX2ffC?bD4~DWwBJEUZP$N!YY$H&a<_p>9#CqOMo^5?SVH=g7Oc8F}ox5(%&d zSw8yi1EKOBc|ymlfA?z@jM^UW5b~h=9-n>MHhAkGxAs6Z_~W0g%nNt>>Vk_G@9A^Q zG84|?uF2j~NZ>La9&M5EHg8Id6tp~K!NMw0036IB@452Ae=*|yve&d@#jXbW$6CWj zN~dD~*Y57smt+=)DIZN?E6NLqSw#GPjS52a;xB9$7u?hu#_IoQxor|cm>2HQrL9f< zq^Cvo)yt@BdVg6|t1K>NY96iD*4Fgh*x}`?xoJ!6fQKdfO>LREdw@K#Yw82OYEe)h z<2qr8g?w&&mP|9}PLI{)0b8BE?_y|jlIM+d&)zp8E}O?l<#HNbra37%n9dcwYB_8l zL34g;glTQWF99PK{6t+oAcZJc}5#qXO(H|^6R0GOsl_(oTlz5jHbVu zMGt~QEg}qq(Zg8Ok_Gh|6hj-$OUG~zs4QsmD$m z;|V3=68bL$X(KYk)XdyQ^$o*qu1#7UP#Tob9+%P}EncsDCruIPNt~lMs$pJ)P@0Q_ z2VSp$cWTT0dla(-NK%I2=9k5g6-&qRbhv9O%)BZuZ?iGBhJ=Rh_PBle6{Ub+wr5a% z>)HNbxhpM2Nk3MgtncHk6Js-iu$P-N{wX}=r6Vu7V(StUneaLZu(7r&>51~@i12>f zt+{D)QQNoR#u9YoE2xxRauvK^naWK4p5K{~)6;FkU5Y_P>@|X*z-WSXBwoZNZYoIB z51)CcFAxdiY6)b2%55?#1!o9eHP*Q8ThO2?Yc>34x_*#G^J<_Lawpf7FzNwU5HHDa zw#t?|{p0qPzVxg{K0>)&whV@<{)AybfOMB2V4)|~24^QxHs3UdE!+OcG*HS^Sajx3 ziX2|&>^if*u}VQd)U)8C#vi`-TQjM3oDuy#>}J20(#`iA z6*p%6L) zjNT=|LGkn3q7|x$=s&+*a{e;z2ZuW8I;Kt*Ks^GoZ83@YuDf*V?ZWv-NJnm}K8k$zEp?yET|zF`iduC$xSxbZ@a zyjM$zz}m3l)m$f7vyKjB1JV37s+_NBn4`m3f8&MO?t6^|^ecw-c4@JRyqy;2Q$`vv zvn=LN>KE~i=*e$T(2xG#HIajk$v!tUy6>`0kThk`;D-ANq(4*Ne;6h@XK1Z@vnm&o z9{dd0Ug0NQ0KCEM0V!AY-o5u=Cc?ZJaCuWxQ(IdbfI>cLX=!2MXJ%$~7R601Ergd- zvHk1U%z$nXBjomFFUk8Zx?6T@yo7f86wXS{6f#*+3zItT%G1Y2jb7pJn5wkqd@u1_ z@(CWn{zJ0DJ3ZpvlbjnndbFEywihB`L;a|HrHcKQ@{Nw@%UD>mri(B`H}n!)1i=?a zxivn<4gw8Cxz^Is(%IRTziGMc5GE;Kx#HG(%_9%cHMoP;M+(V^h)(9i`C)jHmZ@p4 z%OrdUGA8NoVElnpm-+egb$0gd55h{hL+^FUf#JVn(+?Fl5yBKF;jMixJ}J!6_S@F z{-WQkg*~Va2g}SS)+y$sFGx;A?b*1+s z^XjGs$|jaEtuA&@oo@Aspw;WOitkDNyp5RzH}CBK=##Mcd_=2s(#kJ9ICEb8tjW#) zxDa14UjE!QlKG9OkyFX}(S;rDxfOo*gW&E)C85FUukz`t%M6bpq0JH;`I(wU5X3cf ze8|~(f<6HOA}KKuz^7HQUIM>q!QgKiJ|nto*Ng!e4Gm#Rwu_^W7jxo0Pf96JZ{p%; z`Av-U^hW#p)3kF|DZse|gAB>V$qp&xNCrEVjM0oOa`AX}@*`JV-(6EFYTbK2>S13! z?L1w>T1>pHw7?P}OQbZ@M#yh3)Wcz~!vZpK+^50+B-8w#R$FhwJMB?qz=Y zLWu%L49E|gJb%|dcJjUDlb33|7;+Bb|h5p`6VSn zJUo8_@tMRyO!D*d^YlEdnDLVm7ayITW@2WBUjx2O0s>S2Gq+FP(m7!f5x;Ciq04HMFY7xyk$Dh7u~K6S>jr+OYY%=g>{^Cv z(fwYqan9MO>N%{f4Jabc&dyXa-|+EL^Imy=8Q*j@nlbG4>j4`P5GWzLOFNYtWMpK# z<26ky%=x`>B?|?=5;B4!WQ4mt^>gelXb-Pc+8qOe*exs1A?tlnfxms_2-GMeNjs`O z;VCt|I))u1B9J_O2E`5P%YDti+UYw%Ecrp$bFO{&JxHJ7#+v0SAmD{h|5Bg7Z#RWAb=h~G!zYDRFQf(MG7wKIQs+ zb+)tg5-uai9%u@B?u5IeiS>EcR0C4J1=|whbKxQZpzX>%u2WG}^`3vl`D0RlwDiXh zAFu&K%(WE%1Crl$+=O*vq|fWK((m6#2miM66iud9m6W(PDO-SL6h`=1isu*tmmp1$ zx3{+kZbOx1)r@}NL!hXWfU^Ug8;rFBLaG*Z#uRwTQSD)ktpC5SCGk>`f%qkexIn7d z$yfgNw!4w40kft2K%cdr{N6u^?&8TdY8%h1v=|yaOF#F305%}@ z74u4~Y@MC^>~GEa=>?mSy#rRqgB9L9+<`fRb|LzrV zUB{q* zdZU_&jv`X=*};^@i7Wc;+qbX?j&pApNQ3KGsP62%%!Ewz_Apek(pXF%d=|CdgJ;xR#jJ({Sqn04hm7t|CaS5@WAXds5}s)6p>t7y2H zD({I&@EW1A#kdBHtKF4xOV^)Eez(PX^N$+^Q;&5X5e%s4RC>WqDEzV0aq#n?25=M5 zko*7sft>w8?F;N6+w$?MD#>^iQSeOE*VltGUT$z32w$KrK>Ftu5`tP4n4DaluRsR_ zS(p2$5OA#5?sAHZ|Fr!rm;@{Zj*XjZ*iN66i(c|E8-EF)Fs>v&mEP?V{zEIG?y&T< zyHX?TCLdpdwM8RL7W5Jl$~UeacE~>lehvO!d4|Z18*DOd zTV*~bKE8RAC(@+QfBA#;C@*YS5bJkD3bVd^d17ttU3+UI)qC@=YwypWclZyUJCsJZ zPS*O%Bt3?J3ZJ3NifqW%MS9K{pkr25_2%VI4z~P(?;4XQhL-5wJ12P)DdFMa$VeO( z)4-6IXzC|!@m!Sa-zFSy^7ES(TPVN*x61cmYNWs4WpA|~pUIO&TKW`#UB#rUs;#Z9 zmDM6pJYc8*)|ZB!o}PlD7z`G0p#a9&162(H$RK|oy!hU7a`pKY(^UZbz@oF|yX9?e zZqDp?nD%`9ZXK0~;2-tK5c1ZLH_z@Dj)db5LikSg-PhM_;T|K*g9cMgC$AFj{)kU( zOcHEtjf3DMe#lx6;Ah%vC8d?we=>jkS?;d1+^%%7p+<^iIRyBH)@X0Sv-bA(zb0mp zt-kZ)Pne%NI?`M#f&dDh2XNmy9*q2c4l&x~ob_L3IV#XM9v>a*c@zj7}HO)4+m0haI~PY?D*XzhMv= zp1ER(`dzSJ!GFHW%E}m`r_i|iOTW$d`1t(%JPnVY0QiQ$DFdz8?u{==DgfmO_e$@A zt49XtZ8&jw*EV?+{ny~JG6w1BuwW%08@-~*oi5>CPZb?FwX-Pspu>(1m61rA@Fk!O z9S@k}>s-UZc5rWg&HLw0jBMe^)=cfpU^SI6B2{D)QqSa_q*VLN?I}_geIgzqt0u}k zmh@}G1;!IF=1+tnUS$a|2OBG^kdP27D=Pr9gydvt*cO3-*wC^n!T`-Xa9km5hWsJQ zpe`pTXJTUF?Okn#wf@%kl(M0IX-{>{LgrK=U^j2L|9DFNAmeR zJ9%=_BW*OLawg|@_BbX@oZS5U?l^}$Fuj#2?J^zSk_}|SC3v{_yZ)^}e7ii&CCau( zW+dHBr}xoP`Se|1JhnDB!I1I}II@!!nTs*oa9wHCI@QaRo_TJMQ0b*?<3SojRt51e++7e-B zUg7Rr4+#x!vkH5LkHvD|^L2@)x_W%C_N6-0wvnJEwO`J{4JpfZ2qGd_TxJLYSMjI} zKI7#bWU7bSu&qQuGPX5UVzyl0`oC1&KaOCDgk3__hi5hb!Ab#OIRZ1+t}rr`$P&~JfE{YJWe897QgdW^xlh<|c&p)af_Tbvq&m$K1P7RL}{w z_g0%331Cas5*yx0i%dz*xol@c)RxyL_qhNaB$4(L@7Ex|=PM^4GuI-(pA{3gGff#b zTyO#TW=4txvhwme41Q5}oMCtv*-%ziMu9)~E9XI~Rc^hRCu9MSt?7;5r8<@lqea+0 zAps(gs2P{hZs#_h&G7->h_-2N$u;(=Tn<7IZpde(CIsCjh*eetzP*#b_D?&P(0KM5 zXR0UaMJU*<`U!bbG&oZ}e=02ORVvpqGCBq1QLX;oQGiZyXcmwK1wOX&_~p+34tD$3 ze!uiIrT?PE@-L$({`35N(Ms+1UHV!8WB+abb^P$!t*WlhN1jN|LuAiCkhD9hOmD^Nb3Tv;jnU>e%2b3TIeeTHN~bg zffv$oC&&fh$g~vt!1Q7@&8haxefozN*#C~;RzO|#0`d_cpG~l%f?7hiu)Mqs%3Z)e z$C5_H&VE`t%Lo*QdT`n8x_GVTPgrpn6J02?pWZTk5j1Np<;Zs9ei~T^-zrOfF*yoY zd`gC=8%P#Ss~@jpvT_t+OW&l3yL0mKIrgV30JMSu+#OwAU2SciAbkU3r($9{2Zhlf zU)S`f&zOyfqM{a zCq4cuV3(O9^WZN2W9W&xlwH83V;Sj*G8 zASoGH^s86;MP`BhHW5)#iU;L{h?nn7`9E^h$3FI9y0|VL& zcX_R)hN(2AV*z+=%Zl*(hTxMja^1KQn019b2K+%HWQX0!vmnUO!~)2O{s}yZh_4IS zC?T02CoZ!?O|J9NJmTr~Wz+K=TJ(J|9W?DLd_m0XZC`oQN9=mg1h~51huyHGwDjQ5 znD97GBPjXs)E8f0-#a3<>0{qrET28w%}&LsF_B4kaw!wKS2)6N^xe71Erh@JbjPOf zk*aFAyyfSSM>ukr)e8@%i4dT<{Eevob^$ZRulRt*IT&lAc0FBN0)dQZxBB|;6rhdl zWBm`9Xl-O9{Z)-*A$B+|GgCn_%-g8@7C=@^P@H~aEkM^|NluJ+soYZ8Chva*V5AD^ z=0t_2#lk>raAiAlkh=aDFcu|$mt|1lxh3eswST)LBlL-h*U-q!zt zPk5Jl{(*tPTH>bX8K^uCA^@D`EudC0jWxBLAME*0f}Q;&jS|-Pa8vX@Ql*5Q)ba zg2aB1owSWMLsQ_>k|LBL36bCh8)k(0496<}nk4=v$HmWIn3uPA9Ul<1oEbLc8#;=r zm>7d1Nc=~WV9y=1Cw;yiK+$Jg4#ffL+!saO@Sa?+hX5_`qGoynoe~!({5O&SK`AO0 z+!s;dd*ZGsS~#jb9AF>o)JCx^&QN=oNSa8wh=us(^-p(<5;=m`EF;K~(%%u-Saeqb zKvZu=!SeV%b%9BP)M@WB^8(u=eVTENW$!&oE!J18$EBo1NQmODXOM3(t$xAAVxher zVS8T!A2t+&%EFz`1uw4{V+S!I4<7O1^;YRk4m;V=o=EX^oF0qUw z>1f%$23sBm-)5Jc$Q!s=X7dDZx+vgA0s^4@SnR5j&E2*M)`2^7B$s{!;dK!Z5u|id z%Q9aA7A;Vz2ZzWKEwD@;*J%8?0L1j8gW8MRJUkKSAKtt{nF6+!S5zDr0U8>SR#a33 zehmUU$pE_0Pr`IW6iv^B?hUeNp*X?cG-#NrTd8^|&LLJ)Q{!0C+SKHEjPMnbfR8aZn%v+<=+Hyfi&=0iK=KA|`MjO;qx4=M>>95but#7@ zJI`6{+@a%PL#HX1)@z6~D2TxTAg`o^$+++u2P{c88QjJzaa}1&=#FLOs3zKqtUpqa z1XEFtkJlGs$n^vT1s!M9H8l^Oi-b4N7rw*}Y#1z!fw4;o3CsJHarauW05}(e*`v!G z*>+9BSR)9tJ&0&{4gtP{fea>-gJbAq+^!I6Q;&;%rweyL@ZfoIocw+3$YLjd^w>_|_batNrqQt(=Cj-_rS{CL-yLyzBje?9ZDol{3*(_hblmpZOfXkwy zZlDc78DxKpjF{M&(YhScU9NVH2pusLmgt!O8r5}2j(O|E=ZvJ=1YfHt+R6TVQDYeX z7HFLsZ!yEwn1s}S*NcqoG*nA5eB#007aCCY6W`(6J38)roBRPfT+^xhqs)v&ak97z zsz^06D+}CIQ2g5UoXm_oKEjrnE=I*Fk_z`nEmO_z=VU z_XEgn!N9b+`Av_fyu3VcEqv06ThMI0vH;XD&k4tD!9DyS)wQd(LHofKz~oYvB| zbvlBD#(#~bzFw-FkE~NsSO2#Y0IZ|mI~+E zrrYNXk*(Qym!@YPQGaVP_wuUbv_6KE_qT~k6L1}?_1~wjESaR-yH4=1;;tMK=A|J# zBKo?yej}eMczA+IWisNXn3Qf(gHqeu4 z!%D}sjph}*q&(5`r$Da44Wk@O&slP7T2Sja8uEr7hnp0-A=iToaDgPQR}g<1!&Rvs zd)|zKWliwy>m6Cym}dJ$rU)=~%owfoE;qR*k*gjufY%55uRit-<20J{CzMvj3jZ=@ z^0Z`q^8~P@P;}$%XUh>=;|TjJajyW70flwsNj~#Y-OLqJ<0ND2KN>h)k=5 z)z8}qqEb1bArIsGTFa-q3TG)m!h(hwJFA^IbwCV)QK>$90~@CY5*#d?mearOYo3=| z0wDde0-Kz&-j9CM8`FLpT}OA5`ZZDsneTI*(-$aFvS{9fVKV_tuT_b9Ume5;_wCvG zR~LDPqh>5LPLtYkc$zX-uT!!f(we4{)|gztTTZGKWV12xOdvheb@f=z77^RddZFAX z@Q$yS3N0={0HrYi=$HND#gM3=)5$D8t`4*`m;-U!Kx!C(s42KwF1~$+qG8aGl7N?! zJ{8ZLRmsf0_a3;k;0?1LL@X@pEFSfG?9>Kx;u>HXp(fN|DjrB9vU6KGVs z#}Roz$3B3mkqvNbj*X2`?Kc8v@(#n1#ygCaG$(P|L9sAPk1KDMb{akj+Dl?WB0Qcp zj+|LDcM_WR;VD_BwSH3;#j@9R1%d^2b95M6!5X{9TxO6DF^*`5XpPU9QQ!m4R2}lU zq%kDbi3(uNPR~`vfE)%+9TW-46b(IF4PoOH*ZFRjfq?;^3Ywx72slwuQTt0afVK*R z?Nn4=8wvv5T!~ER*Vu@BmJw_p1;5DisTO z=?#yH5S#Yyvw?_wgw&t zk%xzeXf!VB9$4I~jT6FE|*m$Z^~BG|AEZ0^ay3pB21erR?`Yt^#u}!v9NFR%l2_ zr1i}}3c3M3G5+h~V86f$r~{5WMB-0GEkg(Y+Sh_Fnjg<0q1>P*oa^N^{00vfxq|$x zn@fR`IT`CMGvGyW2?@Q~yjuZ&K))^T8LDB=OMXfSj46;b)ROC3Eh@0?E=DNB#okdD z>Ch!oY-B4&`zG)iGf+{L0x1fi=+DoS&6`|YU_M*&@`E)C0ww6kzt`5Zx#KZ5R$bj; zAg%!3`fUd@(-FS}$(a`7GHvZ)bJj;chWDH5?(gf|d5pxT=ddo(V7@hR+h~xeeH4>W zXwjRS5XHsBFkV9l1Li6!D(2>MFiiu7m5t;ZJ~A@$>Ex|AT~(5S9~f4;K7R4y7~{@^ zQ({+5fEgnfd1_;Wuz}e(BA-)!erb-%?!ci%{=W}n|Bm~i+2#*vu5NxJ zw2i@79|HpeAOfweSD?>MA}TyOTI_=wrtcBs{U!$8W5GJV<?N0z^0FD{VtU$Ul`=1t1Ir^{VWS#$w_6LXrJ$Ds_g@wQ{ z+Ll9j#VhlVW0s?WJ`V}7#2|3ZVHIG>1^B2g!D~U|1LI+HlYDDyD-{Y{$uQ4?-}I-n zfIxttZtf6G_~m};IfQwHu#gb+)~a+)s{_yc^Jl7}o}EY{7@o(+4bb;Nv932;U0Vam zN;`K5I%2UmSFVSU7EU?Rsw~O3HgzS*)c!2!krp6d9magPtI|(Cl*rqhf%=xp!GAV; zq7NUnRkn~Lbxch)P51WqOD>!8(hxm-gg_!Uzt&<7|5GWXsdy9>j~*JH2EiKBf!TWq zLaR;ICNw##)um7aH1cwiKeJ_*3n7{uI|OVSm=$?NuScI=ifxL(%9RW$eGFCr(gWGWz>Qg2b1_+3|6R;B^QbEBh=YuBB}o zgF!@#3nN_tiU^*|MqG?QqF-_^!z-|4&0-y}lnE5z*Dz*+|E4P_~+2=t%L6lY@hh8LW(8MTd9~YzzIf zMvw^HB(I^kBqa26s0&fB+atrmJ{5wkJ0m?^`@w@&pMpMxZQ}Gag->Ce(#9p^qc1V1 ziuIn_38NWTXD;_on@<@gxPy4_t}ZyhQfv7;8q z8yG{MjzI#&$9%R`@)v9gV^!2^t<;qewBB1FyH)@Ot*m?mb{)+37#j?5Xi zac_QKh?<<71b-47-kX*9$h~f{83=`$+D}CofLQkf{pu?5OHeg(v$LV_+XBr903%@t z#&bUh`hm>RB2{>Ex^@mgFh>wgV9P)U_313W%pq)cW-6+<`1mXI^hcP+ih=@+3Er^6 z(b(2@4MJLk;sVGj7+ZTm;huBI~bM{Mb}4*EirBB9UX~qiF|x~APxfIVUXX`+uPgGVGAc< zZx3|HoUz9gxDqO0oEhe+V$`o8R=|A&{qSk|I9!^DzloxDcR;>2bgYCYB;|yXUIT|( zwa?McHIGSX{f|#caj2M3=NN>V_1Uv$FboKKsllE7j@R(Xtt54h2j=E!iWxV!xZtBu zc6Pw+BKG<;aKSO1qeG}l<(W!G^Z-`rzkmA!o&VixZ21-%9ta&}MX$}uExI28dsq$4 z-Q7=iq38jk5b(|5__%Gc9su19cW)^Dp-&ya+7{e$VCX({FN2jkQZer1M^i&XOnJl5 zEpu_y3-J@g)R&>5AHk0g6fty}Ucb&`^5c7M?#&xFUg<8sf=#fpvAzx&0=jR2fq>=_ z@VC6ExpV8*t(!MhGYP1d{+|~hM`zsr+xz$LVR1oq2{I`SHMJfO4f?*0&M!C>Sny8O z8{eSm9-{gy<__8VVR2NLGsN|eiB9I#`w9~$OTA<>`q81GRN(v%hoP(M>yUQn z7BIvdSn#K-J@{K)K(1kI19s}{oRWy`PtcJe0fQY*O6ml1FcLla-6eQIJhU+u z_5lcua1$VjuBN3RL>Nf&6Bc+-tM~0hl-t{DZr8Y1^Y-OqqV*zaf!OR>s^w^>}l>?$^M&c z20=xHA+q~P1`g(7c#@JFocx8w#q~JxQSiM2WZ5hOGb8V*rt}XE<_{_WY}N_{vKw~f zm23sNQ^?=2@+LOi6YK1qo$qIb_q2E0+2eqL7ZMl~eXH42m!^ac5`S$GO|#cP&?!Tq zh@iM9N{IRAOJL7{ye_`EEa|T~RullHrY?0V2jIt~sed!c6RsbveDtWEvJugRUJiJC zT}6fW5k&&5J(!nJVhHBCkwVjt;3SHT4J3yrdF>s7w46%%=EH|dcvxnC3&@Zo(M9T% zDKB87!NpBAh)+sVHOw5cr9gpE9~K^%@~`|$yd8$CdFN;`?8I~C#z@@eWFNUy zf276MtjL`RH4tG*SN*fU79Pd#GT~jD6-IDXEMFIZo3@V5+qk&974YECft%~cLt-~# z%j;NeZ0M0XB}57~gnqV7C`8(<>H?on{&#IXJv|WJKxV4(K6r6Np$T=B{Zv)_RQixD z(SHYAxeI7gs_I!U!*=XlIyS!1|GBG6tzrv2834iapbKj1{oA)?;L!v$xiwzC4igsG zn5>BZyGArLG$n+=zV8U-(f75r-(-CO77E@{1)dzBS-~NINCQL%gVzY8z@PIf5osHI zFI5{noYk6u)B5i9x5mABgRX#%tFasE&%59fjF^N~X?pXH^Kx>AI(%NY`R>Rr;8wC~ zKjMMlx<7q=nPk9&!`H+|I%JE?ja+ElMO8z?{ox}XNVvQ_JbTtu!IVb^MF>_#ChmAP zc~c4$G;?^S;+vYsG%nlFjf+^d5(=i2!veb-N~(NelOSv1nr>xf1-HA1hOOg}AP?^8 zt1Sx^Xm|2F_4}9kKte(SECXG%K}+Cv@P}tnj!#TTNlKziRf%{se-^=+@Aob)T0JeK z54mDk@RQCIS653bR*YmjmBMKjRsu8B0r|&_ykL^ZQ}5^9^ZNUDc@kDQSaCTcY3+#@ zzIp9FA#hWGX_(=wN^OgGVGa>h1cJjRdsNs(w?{Ck8@gEQm+f)nZORQI6@!!4sgpIP zWyLy$VMp#w020Ma+5b}!ZHV3E*W@PUtEH#c#sp7k4OSHIpXHq6t!O=1WNYj0{^x>s zML!D+EvsX&mibSgWcFOHFfC;L_&a;M_yNGSjN=ws4y}GsbrqHL8hB1O<&!Vakp|z* zec-WwJ#6Kw+aWe@o|MBg+M2nq?-!6?tB)h-Q2iKNb~$`Hu;C-Hu7AvpMMGEd9PRCW zfRBTO4>#Ekm;1&Imvxy;r0*ZcKZiw5{Yp>Hj{p5>g-O&fSMpL^yNB0H!1;9XxwM?L zE&_sckcySs{USa#tCiH3FY$&8SK2*U5(|td)QiES{Yfb3oL@~#WG5vgWk`*K>SQGh zT3^r(@$FVH?FV0!NK`}w$iu4*e}#pG&u$j^Z0UeYF#G4`O>S=7DUPZyWgeIf<9`fh zKth#ApLMS9F;CFm;xFS;67i-jc2X9nH&%Kof5`-5`#p{lU|Uq1s7o3ZT#T(*ChPLV zcNfp{3JRW(LHq2AGS_#eR+s?NNxC}8pWO4$D^^y#Gwp6D&|oV$c5=<0(Mj1`fUMG6 z;Vq6%P8U;KeyvPiu0%XXlCYFnP~_kx4Q-TbEE4Bi#mU6hM7$$LHa##!5=4rS6x8=v zN=0$mhn)?)O>G~QQIPBVsY(1N89LUuy2d!-Ufq6YYLTkvv-OrAThX!b>BEOtZt9ON zlol#fzcM>%aF<7kmQ+_3kUaOc5@h9b#QA2O*HuZZo4rIRw zL#7ImtD=-+djIaZ_tPCD6iLRaza-iyF?@&I(3NUQ>}QNd(wbo$mi@S08pLTQ@hje0 z*|fd*baUQJY^X7P!SUmKHkeGhhCOg*VUm-0E5G#Tgp02XYFl93 zW!LXQ*)&HJs!!l;QGub_B4!LXNpNoJd>W(AZb^ToC|FOoaNkH({BMy^1I$2*RIG4{ zBpLpD{dLxK<+H5q1k;9g{nLRP!{IBmu>42cgcGgh%3hd`tGYt!>VHu#Zyu?UF=fkag*7Jok}W_%E}OE}0S0%H*b z4|#dC^CEzkV{3R$AW0uyOGM0-1a8X+LE~cbRrkn{SEde4X7HZ$`iTDWX6{9bY2&`HklNQgAPL`dtQqWK%pjwy7S_p-ke`p@c)-<+CKt}Ismol zcY~EcKZrSu?*SD`#Ox1rGDP=8XxdIlxCPEG;IO|A+19!#`Gt+JZ~s``xy;M@AaEuV z@Afi3y?mCLwSHXt^^VK43wt--P@i{OUax;IHPqL~@_z6%HL2BMaV+~ZINeUkiK&9} z^*GU3wJK}JYxfUB?gK(^9kOZ_m944_VRP3Sm0?JrM`r!o*BWM$V=ljoE9wO*1lZ-I zcki;Gd-%t058!8r*w9}IxRV!&Gza}3gV>=%HQ~*hol(o^GiV#sP*pW7v1;ds>Jd2F z|26gAzH=v)iTmcwbwIf?(CToP?6%ddBzWKc2r`uyKMmu^E|E$1 zK~F0<#=!?mi2@@SxEBqerZO-`$UmeKF!pt`vAxT1+m6UpBVq8Y#yR zK!}Yd3sQe=^Od7s=J`SAP*jQw?vro#y%JHPOEBb1@ifow9rOj8My)FC7C%_9txq42 zFJda*S9OYbSHP-#{J{Q1;p3J3OR{{DvXT#c+}z5yC+bWypc~rl^w4FW6MsmLZ5WsM zmOR;aJA!+%FWbCKT5-WQQqWe_dI5k45I}%2K!=2YbI?2jl)8GePfE~}e**itH$_Sb0nI>A zF9GQfP8LwS{QeZTHZ(S#oSa+|Ax$Gp$_ZR)zaN|Y>6T@s`MiH#sUIscl0=I6@G)`@ z793|Hi_+s(2HrdFUu$ZNM?WkN>^be~4K>^v>fDBhNg>PbS49^bD?hi5JyRRMXj2?H z>hGzrY$c6lBtT02f9<_xTa{fGE^GjzA}mt6OF}@pL>CQG(kU(7AR?i3hlF%@H-dsU z-7PKB(jZb&`i|vu?Dq%k&zr+9!ip>AoYx#@jY)GR&@12hqTC{*X5aNbW;!^PN+ry8A1#}_4gi1a_Y6Z4Ku0r!*WB`H) zW`AOOdW+9r?|dsbs_e`)QllI29KG-DbHPwy0$c$YzvWe0HTQS5aym~HAyn-y zW5a=#{6_uboPs-ov``RAS`MNYb;vO{#i*-fTc%T>E%}wYf~QA`Hnyc_XuW%)0#*MU z4vP&Zi->ndt`(Kn_{4f$qX`8|iO5rMA0qbkynZ+cXi=$3OW(RTT&=|hBOH8km^3vr zV5OJ+QV)1JP_ZDeh2?I*{BUpn)8A8{zYYI%RCg0{LAdir?#ZYBoVLG~6cv&9c_7xz2|7dQhUbrJ z-Qur4!tPEVce6XU^r#1Q(r}|@BGgRIwh8cWv)?A&&;SWQ3lUo+S@BUg{rHR5;?mOH zK)-GmplA<)Tbp(G$PM2~?@l5j)Ru6j*fTv;6!HyF!ROxgw}nIQ#Da^khl5)Jw7DgY z#-NS`wl)2;iOJnZhs~;`7{A_BWAKQqFn7uy5|XA{$DODVE9HzbCuZuExuomGmKIuB zSRg3$d_i2i^z{z~gHAo(z2U(4n3yWqSHIZuQR1wvbj0K(Ce{QpJo^W$(OTvrt3M#m z?+kzDa1{D+s>xA6OQ4hPbN4uQ{IVwm9jQHhbePyNgdI_g|RFO(-8qHeRoB?tRWc$2S)phiS22z61V zV2m{7bysvukdjJv66pGJs*S1L2xe?q{+QAf%4q$cULn2neT7iiga1*`OiN1Yeb|jp zv|JTSt6QdIx^rM3!D*FhxKagDXNytdFXRg^(uzTwqN#7BDKXWMlhgi&ENf0Lhkz7^ zg*cYJIvkGYDl6MBD)C;Jeu^OF&bLO`)vErU$eOUaGWgOH6&@5plE{O45VP&^cm~;l zF4bj-h@A<|7ZHG@L2EQwpJ;PflJXryIWSfqNKAbI$X@<-JT8nK*q9nCX=-V0aJ*Zq zP>isaC5lPK)1Jz8)Q{TSWS_KU@(9~~{E6|2DHSQ#J+P10eMv>dpV-*Sd5A#+B@_-J zh6DJiuZH3Ew`idB@uwazQmph*J|rx|D+CGi{F5hl0+34%0>IM0{=VceLVgcBC@p$X zA%GCey-3pYK&M)jE@Hc&0xFd0@w3tWl?ufWJPmXlJgZW8?%Hx%>*C1@)n7o}mTu!p z*QY#XSj|-f@J1GiO-ELbB9Xr)+O^MMZbhYY&;(=h`V|Rw7*{0@{&>=WP5cf}yq`ZE zj3Rv7jhN5^^pXQZy5+USS%-hW3i#}w(Jy^D{ebU-`A_QiasaLFWY|PaAE{+O5->PF zmLeYrdC)vyo`3Bfx<503_5RdB+!1*5$TUAs2PU*z5+lccUqxm9V!MR-lI|<0!d1cN zjz5p25?Ol3nq3Xb{<;I9`awLE<<9BhN7ka6d4YZi~hundorDi^~ritA_!%o-e^drC&@7*zt@3U3laUVb z>O@1NvppJvjSXm+DTRI9S#*CqNR>&XmVBWE2^+tG9)ohy+?+Axvzox;3+}I`k3wpL zHA>9tf-AXGm}E;PQ27`<%kHSs@;WsCx>#RbwfX+Jv8hR?Wa3Z%m&?0vgp?M_(rF7t z%Dky`3q+neTY6aH0p6R1FJ)?)+q1{Z#T`UlCRNK7Tpni;H!UCdnK%!OwP%usRXMAJ zWos9k)52$)1sSMHz?w5L~M5kwJAy|jEYX+)E`C*BRPrElheF+}DQ(EOJcZ2Uk zK2LgT2!H}6{f-RpdURxQ(Gqkoh=gmZ6ELQ<6?o+681Efu?n?k7q!`AR7GGR25Z19jtghHomavVqUix^{T zpeKF=9+I=gvM$@zNra?|;Ep6@KUq{{B75>->LS`O>4N;apIW#5dSYUd!*SRR&#lj5 zEzCaew}(nOq%f<2wneOY$JupRoSw#@4u63u_kg*6gJ|DRUnI}5Ah>B~F#EbsPL3oJ)lY}sIe{rc8NlFHE5KK%@qk?vB zFSyWI;kwZYGwgqBR7G;b!&aV$DZKx;-_vJ^Q0;5e~*v*aZhlp>oFUgvWzVcg8<(qZPsr$~5 zp7X)L!*VR8B05#yUp&AmwdlWqWI;Ao&2mpbnf{y&`vCL|$tti0!+yR5OvEfK#hICl zAPn(nhA`jbkdP2ymChiS>c$w(YuZ9qiB6*IJ*00Vbu}11;_Z1zi;}usix0avsn3NT zyKE>!jxFpMfS4(=ha6GZ_W(rPxJA75+wRM}MXLYL0>sWU)hbOjwUHX-3`J>aX;{AJ zn(A|A7fxr)u+of`wyZ`4y)OmG2pP| zehZ$s*kyd+$_U77ZoUE*ko~~}BfkXLlR<_aptLAWm#EE@N5Oz z{Q(OLw9Bk0eHLo80$1!w0}ZDI&ywZ%xSh*9;P+7|MKuW)2;Llyx72BHCV{rle(@qB zI{N4Nc7+(sHz53gpj-cY_2q9vW~L#eFTjT~DW+|exSU1hKC_t z;L}=yE)bK(bvo)S6DU{Y#00PNk7p$l#iJGg?t-INRbO8eSc<&oLwrAv$gV&}aCvz+tXZZ5?%l#>iM;3Y zZgaNe-Hzla;s;j4Z=i95DQs1TQOp0!*UFer_2%#)F%5SAc>?O7A%ucdACrcdCOi;J zGclw)TbNwLy%O{Y<~7YQ$Uy%A0cODB{o}h(P%-F`0J{bh5BM<@SLZW3HFQ7`Mamz zN6x>amM$D%C$2*1SHE5Sg<`hfNq0SL%kmhO(ArYUBh;rP2Jr(O=QnN{|Nk+Ppg@3f zo9gTh*+`>j9gv=J2)#@7rJDTtjPn1y(MXvmqJ&WHWwskt7itzu1CT3Na zTuw`X#wFm6x+>JD9SF^{p20*5nzZ+zxzPA?^XXk!rC-#z-WL2n$^&cZ>1fqnLD9Qz zrC@s^CTY5iZFU>-%rR{HA9V=jhX2o6wMb4`zc&v+Q}Hd}zQ{2Cs;UMz9LKev_njIH zX4Ch6aZ8!%z}SZ@~KN9#Bl*% zxp4mvga-Cqoi2#k-MfWwnx(L0e1+U_LJt=V&(iqEZ==C7ts;OOw)4ESD_Qi-3E&ri z^Ftv7Zn8QZTS!TO|AIjd6hf5u?*}3J1_uZG`l@xxpf;9IV3So)sGHk8T7fMyP!KnV zSKLAQf|7|F_Y4cGeL$=d!to*q{(ll(nHk(VosSBi7g=R$Ok_GJiD1?9@$r$6=m4G@ z?r*o_{QUg8y**Pu1K#v?OT~LA($dUR@AB>I|IBO9n_S^o-hPYOXF-N4MOEg&2Z z-T{QN8a*#RKMppwHw2S|dJcXGH6m<(|G9XBf`UpWtWb53CQP)jheA17B1jB2KCFJLI)i2pLX&Uf-nEF9I_o? zw7I8$V>=trcyZmA3L?e~MtJrzZT`=~VBPa;32QBD>&}mLp z?;ng{RMz=<-bzk^R~djQ7)j^P6#Nzvi(x9`K{dA=nDT_tafd*Em3TwrH&yGAOa0pk_$PkWY9w@H&-yaN3Fr!NHBIFX%OR1Gib_fuVm{uW&{$ktglhuWET9aG zt4}G!)L7JkrIO0QC8W-7`3!b0BiZ~YWv_4xO1AiLdvo|?>YnJcR0%{|Fqhsv4*PZ7 zdmb*=u8~~GN<3A=M@L5oVY1iN@zj-5tqK=pgaTm+@Tw4bB+&GpkjoD08`x_BX~sty z0a+|!@DkwZyDF{&;S8)i3rn9>UG-dhdpjUNZ{R7<|J}X4+cCef0_`R}5)*gltpsYd zd*T3VOea1iZuo&R0_UDnfph)-t>J-z%b8(sH!#jXL{F7#X3RKJLsixJU|DiOX|)fY zxZqzxB_S>aQEeT2G#!9Q2cF(QZvid^^%5MpsMBf>|AObrf+}l#AB4e+GBB7y7y{r_ zSQti}MOZ@Km%kgG*Av*Z+ZAj5Pj;gp7si*$+M+t13vuy`}bg}z0gD$h64a66@CtT6Vj;4 zQxJ9o0u8=AkRD7yAcU5T@$>S+9%La5vntOi&@+I% z+X&m}>|r>H`S-m=a+gg?t||-ZEz%B(rp++O#{_K<2Ol3ivGI@~(j7FP`}C?};Yyn* zOtMJr5BPsU1{AZ=4^g`66NwH{`}odn~NpucI{Gng@f?{ zT}DoR%RFRF&gPL~Z-bmg9!t^XffIRml-sYx9(4`vT-V#0th)~@|I=#{#)%NTP{7g1 zHVyv7;`!y)ZDHc0BP^;PnhS#C&h)gPKylR#;0ab9l=!$UQ8 z^1C)05m=>Tw^Mq@=3`it_G6pLsC67#hqHh*g34}a{5Qi)%9M^Ao@wrdWw&G^K%ji<@33)VA_NVAmminSKLWTFac+;+KrsD0F3^&hY zZpq=dPcR3*^skv<7mmkVm=3;AKZtmx7`9R{-reu3X}B)Cnclu_vsm|S+5=s4MfY+A zzLMr*{Vh7{e1FdG$r3~daewu*Q`hF!66VaH&5Rk^yiL~4QhA}9PxND3)-p#j)ibm6 zMjdVxk}^NrWK$kh?i>?n@6Am+_IfH@Cwn>&nKF`Afz7y zR31iyT11jDE}Y_PY|TnfEE@l>_-O&6q!E}h*IG^)q# zyQNjW9W!eCkS0t?(cR$_dDO#HTr6?&5p@d*$tw*>Od5!>6eZ~A8&xWgq#i=6BuG-aXaN91S@ZoJ-=P z1B&EcxPMg~>O(l)1vrrv%|k3*7XG$-{s^QU`YkrC`9V>n-^ob{_RaXZBf@;fEz=EJ z;=5)i(de8_ZlAljwe;{~YW?IehWegdOW<9xo;5vJ;>C{5{m9Br)|ZqZjczmS5^~>w zXFk1`frZ+jdB=AfO)atd%rr81JeW&o9T}c3&kJYPhz@5)!bPKJ#?mC(FCX}x9-*D& zZJeDSuU^6F*c##ZQ^0_aw9B%XAQ?+=oztN2MPL*Z1tk{eZso&2g@KY}Z+) z;)K!Vygigt35&_nSCkRFg#F1gt{$7>^*V{09D4!l8>#JYFlgqCKQIA5` zeZ|PFR5vDblrCypht0D)gJz;X6Z@-ssV7qZ1 zZRI~x_ZCTtHZ?eAbeuVr6n!+#HlNrbbAI>5J*Etdf!X?K8{^+JAs>E7{dT??FYU<) zsY?p!#(%vcXY#oHLQQwXI1}rk3r(67I1ST^i!C)#6Yyrx8~*Caa*dL<#$MCOdfQox z^D9~RhAy(t?<8;W$l+qzaMq~Ula;5x^(%S3@f)|P2<^_xS(4e|Ha^djO1ma!P_J9>Y%Zf6qe4v<>;1K$D@kD+4{~mVx+weTnB25?cLv= zC;CS`oi+}TR*M}8x_I`5O1{0IHrS7nVueecq;zfRrVFWsS+kk;?(k9AD`xfS(F*6T zK(E1RG~}aQO>uiNgV*F}bGubDR4;>lmTzr}?C%Ecr>1%iom12JN9(p_EktXSK>ou- zihauj4{!3VJ^WiGrkiffgC;X~C2a+Qu_Ff;-7TJFVG(qW1bw}9NMny@85dm(I_xOD zTgS-7X183ab4|fynO4^w_p3K;Z8MIh1HwJ+gQTH6%`ELxq0cx^96rIqdqgPwVy&5@fH=I|-P|=v> zMqcL%tH}ME{Bp1fZS28jMHHtCFG(q5p1!h>=rQ3jlX`8brRWK3;&~Y*?IAbG(Xlo4 zOC$8lrO21yYYpt+_F`id@IY9Vj6LhDNcY0$_ zeQ{C-84sDBndQDH=GNy`IHdfVwxg@}SC*{(6{FEuR0|KWY6a2@SNTq9ONdP0>PW`X zkz@LeFuD!XYLnZwR%WqZ`+a#eM2&xVYI#pAEYqtdsT&GnU6p=H%g7M*zQl>56#cX7 z^QYeS(v$0hH=Yy-dA?Bxr5JABGI=&v8`}$wdkbKHd<7-m0pviif9M~zppRZQUE?fu zGkS`sW4j1{hi@lsEn9=k8+Qzh!AZXxs*)dgA+-~HDK3mX|Xy!|XS>T_@O$;}p8*>|+<{+}aAt%uTW=1g0EVn}=aj%Olv=Z*cn*@?J6YA;3?_QG>=sR()(UAfws@5Zy< zeZ!eKcEI)geT6QGyx3xu!%+SLMZm?jvWH9D=(bf{)!%yQZ{5VIQ?B}&IVxuxqbp2b zJoYay`xmaJ_Q5-3!2=@aF&{0b^|gOXCgUw8t#*G#+bUSCw^N~!$ol#^#D^_GDdYX; z@WtnYAG$OhVQZahTaWx5j(>gfJ|1xqeU4H6u(Z#pk)4&oxHfjsR$%EFg^N1oc*UgI zQx$WuLhX+!NBy3^3Ga+3zYm-&92POAjjuO+dBwThriw`e`V;jD(?VD8|Px)E&t))tFBTEh^th$K9> z-;-y>&E(6{Hc@o7K^|rbM zomY@>{}|eFd;io>A@K1!*?|TR0%BrHs_gwS?;2cQKJQeYhjI6f8m^@_wZCs3wow^e zNd@R0teSx8@%9}Y-xoNP;Y_i|Yil5`?FCVZk|Gd-s+!=!daonf)NkLtA?G@qNXT%< z9g|Th5l3=kkkfl=6=D8TH9?ePR2;7oE_x7 zo1B5*c0<~Qir;4|b2C%Xz|3Ono}5OAhgY$ITd$(!*A{Dc_vs7K$CMw;!mEq;?ys-+ zuWdmu=A9iI*T&*v1$|!Ixm@)-NKDy!i4L6zMB zoyLx*-GP%%fu41+N`V&Abd9mCAn;3@-o7 zin%bld^^p4v$N#smgs{}V9ST^AD)d~erG*J1xsqNK|+~@8Y!3U+@x!>fqgkZk_1esIQqI{<1?Ze{jVs~vXWr+@AVdk#h#p~@3 z@nrhwnqw6<=3|rh>aM;RFz;_dv-JmDu_|IEXel&JNcS?$neUz| zzrtKC&F^A6z7HQFPHpx16?7-I`}P^MH?e~X?Vv;x}akBDbHBbDPuX^@nHIrJ~eNJj0vxy_j zYl>Wlv^699d)HDbQ^2HD28#=WYAe5(f5KdqT@&^xPK|nH2_?nl zK+mX8aM>|2(^~d<&?f3HncT7neS~=kw=()eyV32*u&=j*GH7~c`V_VpoC4~M^_QeH z^XTY$|^7=F^JDGyTu2+^0es+=NU8UWxg*#3XNhZHpN@WdgBTkV^%~6RNn$ou3aSP#CPj!}zvuHy9)_mG}kzYi%?=?61 zpu;+OFu%CO3Kl1Ief5+kyX5@xZS(E8@6t0wT5HK|RCkC<{896btW!a0@y%OvnayEh z)v)(G3bm7RW)k7flf)}}MrFDAtgb~W+L8T_%J!8L)(XG%g~$g~WizL`mIq6v)=f64 zU2dIZ44HQYC)PFH~y&LZn~&*n&t|061~ zz4$DHr4r7y>=jHCjJxlJm1UcvLGM3OZ@WQxb@-jBrg*!lJOwa}{Gybma;tqW^{E!y zai!UMLM|?UglBNon-4BKXcea(RE*Ez6k4Ro6AY8|ujV=a9C}|PlBDO2>LyNMWW;%7 z-1I)7hR^m9#%%HPnt0Y!g*u+~@VWr!Ngd6PZG;abSwd+oHA3T_7soxPwYH73h~U+q zB#<17DRtc>X(rC88PdWR=a~%cSXJj@RNcChIj{N-M&9%}VnzKIp)n?n9H#C42k84I z;jP{Iw$D%F;rdTrR2~=a<(%5~Ej9QAcpqP+n-JiDA=^}L8V!~=h3 zE(}>5mHe9VTc@-23RFleuHX)YsqT9MxbS1#y_0!wtW%&79rCF1jk8AcsNRc6dIlI{8GZ8Gu)?L07(HmhEl<1bgYkI*o0(2Iea1naujbk|qf9DlXH-cq=pkO~zI z;@4Gx@3GgKu+>IB>ey&}ggwVldu + + ActionBar-PullToRefresh + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/AndroidManifest.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/AndroidManifest.xml new file mode 100644 index 00000000..fdee7f07 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/pom.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/pom.xml new file mode 100644 index 00000000..363cb076 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + com.github.chrisbanes.actionbarpulltorefresh + library + apklib + ActionBar-PullToRefresh Library + + + com.github.chrisbanes.actionbarpulltorefresh + parent + 0.4 + + + + + com.google.android + android + + + + + + + com.jayway.maven.plugins.android.generation2 + android-maven-plugin + + + + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/project.properties b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/project.properties new file mode 100644 index 00000000..484dab07 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/project.properties @@ -0,0 +1,15 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-17 +android.library=true diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/anim/fade_in.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/anim/fade_in.xml new file mode 100644 index 00000000..fd820b3a --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/anim/fade_in.xml @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/anim/fade_out.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/anim/fade_out.xml new file mode 100644 index 00000000..aad49484 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/anim/fade_out.xml @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable-hdpi/progress_primary_holo_dark.9.png b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable-hdpi/progress_primary_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..b73abba7dab936f85dd105f9719e77ae2f449d95 GIT binary patch literal 869 zcmV-r1DgDaP)%+0;GyQ+?h z-24HJL=dJwICM4Lb^6EoP8HRP2qXnBUIG{b2te42Cb+CY!3;^mvMK%V88I;p2U@x3@>v zC*>QiyW?YC?N;^YXj?~zt(tMNrA9i=Gfi;28Kyp}qLHG^aBpKAxz3t#w%K<6`Q_ux z{rmN5n9YC>(0aRX$CIg=l}7E6Yh1GuBXf%8eYG@pE2Wbnc}dwQ7-~F}%}Q9Py2Z$A z3NKO330GLitWf)@q~~SklV3i&H@m{7;H@{%yA|8*s@-Wv=10j=Dx#I2blI9-DH^k) zaJjrF>}VFUs!z^EaCMZ~4=NEK8|{^1IIjY54-3HW_v)&h8x~6t0lP>Bi|04muqRi@*hj za3T!k7xT}HkbybU1K_(WmUh6m=)>FC*BNkIz2WwlUrEbJgR>FKYZ+&R3Wfd$(U50@8TK9-Dg00000NkvXXu0mjfTRoGy literal 0 HcmV?d00001 diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable-mdpi/progress_primary_holo_dark.9.png b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable-mdpi/progress_primary_holo_dark.9.png new file mode 100644 index 0000000000000000000000000000000000000000..b86f4b51dd1490095a45f7b57ba78039fd67cb42 GIT binary patch literal 559 zcmV+~0?_@5P)R5*>jl|O5gK@i4&Gqd~VF2Ws& zCK^S=SZN`mb~ZK^mKK(N7AyTm_BL7xHiBRgiIRArA?EIq`}6MZSX>Uo+*t^(4@@%; z`|Lb3?5wyuBH}ay0cc7bz_mf~{{j#HbnK~f_aV}`1+Tv!%66TkzCNM-x#wK$@afx{ z^K8@MbO?(Cc#d4%-Icgh+P5=+)#mB%C!DH5#2y7&I^R_|;gZ`=wmRVa4cLBKk7P>!>@o>oaTF|YJBblrhN!5Y0q$*!l xy7}b!aQB^%DUuksiJ$GjAcSh&ejBF#xEEfc@Y@`7k-!_An#cSfPaX!4Z@pHnk zZSXVgmSM-jC+*g)FMr?u|G=kjjNnrOfE~Dg8@=@&46BR(zW>ip;mQ@R-`mr4ttG#E zAb|1RJvZYEl*@x3UfSU9US}@74L2U=8-G3GJ{h;O1Gl%tji16M+_;aXEAZeiABl|( zhSd;j>-_N1e*|x_-+rvlmpD2Y;=&}fG79zcBlb&)O6U!TDpJi(Od34Qh;~fVciAdD z9Z!aFJFj>4KCFA2BsXtnb8f;rz#YUcx^np)F2A#-zJX!3506T$bs|?4IhxZoMV=mV zSo%mkWHzzXA4#L83rBIE&Bis^o9wm_a$N~<60)*`X3fql5L=uG{fCfcKG?pc+!HytWgOKgC zk&B5YLLDUq&;Y#mr%(QRLRDXGp9g%0@p^Exc>Ym48a zpRb_(^+R<-7Z>StbfD-N)X346iKcdG31!Sn$)d0rl z>;@B36iY$6F%Dr#GU;PWGZ#M3raAt{&$jlSzvG+0AwKA!d5{3it3C8dsb+9XtqmbN zT3ZPj15r$bO_f!Paav%946?vjMvF2ENJAoQFXG}N0+Lo%LkBSr)RF4pMNwr7^E>$S z4$0+pu78I6!v{>?JjxZ%Xtfe`J!z(6&E~ykeTghR>m#C0Qc@8E(%@)HtEz}p#(1ca zh@>r~L{Z=xeRU*`2Fghow`x>}j;J~BH9p!cQD1B-r#LOHesj|Q_aE!(e+z5VtLm@7 z(7|l~k#dkc-s5}iNW&X*)xI!HLrEK@9m~gaNmZj+jVxlgI99FFN;<0g=&dkloCKvI zR1HykX(kW-XQO6*uh}v;m9JRV8n%HyocZy|-0!2SE3mN(#~oq=^3gv1wb1an^!?8H)|&hz3*NwYfxElFN2d!~ zhaUrTwDE7$kEi6Z;5+LKYm2&k{z>mTn)=?4evtg})tG*R*yeGPJw5q+HJ0%%2zY&1 s{uU4{sl6=qjxQyambjMjV&As@2ZJMV?lAp8y8r+H07*qoM6N<$f=mipq5uE@ literal 0 HcmV?d00001 diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable/progress_horizontal_holo_center.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable/progress_horizontal_holo_center.xml new file mode 100644 index 00000000..549bbabb --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/drawable/progress_horizontal_holo_center.xml @@ -0,0 +1,27 @@ + + + + + + + + + + \ No newline at end of file diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/layout/default_header.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/layout/default_header.xml new file mode 100644 index 00000000..262b7fd4 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/layout/default_header.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ar/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ar/pull_refresh_strings.xml new file mode 100644 index 00000000..2c08aa14 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ar/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + اسحب للتحديث… + تحميل… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-cs/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-cs/pull_refresh_strings.xml new file mode 100755 index 00000000..fcc16b7d --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-cs/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + Tažením aktualizujete… + Načítání… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-de/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-de/pull_refresh_strings.xml new file mode 100755 index 00000000..736e4671 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-de/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + Ziehen zum Aktualisieren… + Laden… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-es/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-es/pull_refresh_strings.xml new file mode 100755 index 00000000..242e2025 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-es/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + Desliza el dedo hacia abajo para actualizar. + Cargando… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-fi/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-fi/pull_refresh_strings.xml new file mode 100755 index 00000000..2bd3b353 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-fi/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + Päivitä vetämällä alas… + Päivitetään… + \ No newline at end of file diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-fr/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-fr/pull_refresh_strings.xml new file mode 100755 index 00000000..7e15e015 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-fr/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + Tirez pour rafraîchir… + Chargement… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-he/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-he/pull_refresh_strings.xml new file mode 100644 index 00000000..361131cd --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-he/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + משוך לרענון… + טוען… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-it/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-it/pull_refresh_strings.xml new file mode 100755 index 00000000..cf4438c0 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-it/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + Tira per aggiornare… + Caricamento… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-iw/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-iw/pull_refresh_strings.xml new file mode 100644 index 00000000..361131cd --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-iw/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + משוך לרענון… + טוען… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ja/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ja/pull_refresh_strings.xml new file mode 100644 index 00000000..e79021b2 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ja/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + 画面を引っ張って… + 読み込み中… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ko/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ko/pull_refresh_strings.xml new file mode 100755 index 00000000..6df2dc1f --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ko/pull_refresh_strings.xml @@ -0,0 +1,21 @@ + + + + + 당겨서 새로 고침… + 로드 중… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-nl/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-nl/pull_refresh_strings.xml new file mode 100755 index 00000000..eafe6812 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-nl/pull_refresh_strings.xml @@ -0,0 +1,22 @@ + + + + + Sleep om te vernieuwen… + + Laden… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pl/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pl/pull_refresh_strings.xml new file mode 100755 index 00000000..382c090c --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pl/pull_refresh_strings.xml @@ -0,0 +1,22 @@ + + + + + Pociągnij, aby odświeżyć… + + Wczytywanie… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pt-rBR/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pt-rBR/pull_refresh_strings.xml new file mode 100755 index 00000000..460c260a --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pt-rBR/pull_refresh_strings.xml @@ -0,0 +1,22 @@ + + + + + Puxe para atualizar… + + Carregando… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pt/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pt/pull_refresh_strings.xml new file mode 100755 index 00000000..a92ec0d0 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-pt/pull_refresh_strings.xml @@ -0,0 +1,22 @@ + + + + + Puxe para atualizar… + + A carregar… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ro/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ro/pull_refresh_strings.xml new file mode 100644 index 00000000..856ea6bb --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ro/pull_refresh_strings.xml @@ -0,0 +1,22 @@ + + + + + Trage pentru a reîmprospăta… + + Încărcare… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ru/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ru/pull_refresh_strings.xml new file mode 100755 index 00000000..821c7695 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-ru/pull_refresh_strings.xml @@ -0,0 +1,22 @@ + + + + + Потяните для обновления… + + Загрузка… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-zh/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-zh/pull_refresh_strings.xml new file mode 100755 index 00000000..91bbaa22 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values-zh/pull_refresh_strings.xml @@ -0,0 +1,22 @@ + + + + + 下拉刷新… + + 正在载入… + diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/ids.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/ids.xml new file mode 100644 index 00000000..09b7de13 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/ids.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/pull_refresh_strings.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/pull_refresh_strings.xml new file mode 100755 index 00000000..2c86a546 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/pull_refresh_strings.xml @@ -0,0 +1,23 @@ + + + + + + Pull to refresh… + Loading… + + \ No newline at end of file diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/styles.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/styles.xml new file mode 100644 index 00000000..baf15c7c --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + \ No newline at end of file diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/InstanceCreationUtils.java b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/InstanceCreationUtils.java new file mode 100644 index 00000000..b0c9e188 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/InstanceCreationUtils.java @@ -0,0 +1,89 @@ +/* + * Copyright 2013 Chris Banes + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.co.senab.actionbarpulltorefresh.library; + +import android.content.Context; +import android.util.Log; +import android.view.View; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import uk.co.senab.actionbarpulltorefresh.library.viewdelegates.AbsListViewDelegate; +import uk.co.senab.actionbarpulltorefresh.library.viewdelegates.ScrollViewDelegate; +import uk.co.senab.actionbarpulltorefresh.library.viewdelegates.WebViewDelegate; + +class InstanceCreationUtils { + + private static final String LOG_TAG = "InstanceCreationUtils"; + + private static final Class[] VIEW_DELEGATE_CONSTRUCTOR_SIGNATURE = new Class[]{}; + private static final Class[] TRANSFORMER_CONSTRUCTOR_SIGNATURE = new Class[]{}; + + private static final HashMap BUILT_IN_DELEGATES; + static { + BUILT_IN_DELEGATES = new HashMap(); + BUILT_IN_DELEGATES.put(AbsListViewDelegate.SUPPORTED_VIEW_CLASS, AbsListViewDelegate.class); + BUILT_IN_DELEGATES.put(ScrollViewDelegate.SUPPORTED_VIEW_CLASS, ScrollViewDelegate.class); + BUILT_IN_DELEGATES.put(WebViewDelegate.SUPPORTED_VIEW_CLASS, WebViewDelegate.class); + } + + static PullToRefreshAttacher.ViewDelegate getBuiltInViewDelegate(final View view) { + final Set> entries = BUILT_IN_DELEGATES.entrySet(); + for (final Map.Entry entry : entries) { + if (entry.getKey().isInstance(view)) { + return InstanceCreationUtils.newInstance(view.getContext(), + entry.getValue(), VIEW_DELEGATE_CONSTRUCTOR_SIGNATURE, null); + } + } + return null; + } + + static T instantiateViewDelegate(Context context, String className, Object[] arguments) { + try { + Class clazz = context.getClassLoader().loadClass(className); + return newInstance(context, clazz, VIEW_DELEGATE_CONSTRUCTOR_SIGNATURE, arguments); + } catch (Exception e) { + Log.w(LOG_TAG, "Cannot instantiate class: " + className, e); + } + return null; + } + + static T instantiateTransformer(Context context, String className, Object[] arguments) { + try { + Class clazz = context.getClassLoader().loadClass(className); + return newInstance(context, clazz, TRANSFORMER_CONSTRUCTOR_SIGNATURE, arguments); + } catch (Exception e) { + Log.w(LOG_TAG, "Cannot instantiate class: " + className, e); + } + return null; + } + + private static T newInstance(Context context, Class clazz, Class[] constructorSig, + Object[] arguments) { + try { + Constructor constructor = clazz.getConstructor(constructorSig); + return (T) constructor.newInstance(arguments); + } catch (Exception e) { + Log.w(LOG_TAG, "Cannot instantiate class: " + clazz.getName(), e); + } + return null; + } + +} diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/PullToRefreshAttacher.java b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/PullToRefreshAttacher.java new file mode 100644 index 00000000..2233e28a --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/PullToRefreshAttacher.java @@ -0,0 +1,743 @@ +/* + * Copyright 2013 Chris Banes + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.co.senab.actionbarpulltorefresh.library; + +import android.app.Activity; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.util.Log; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.view.animation.Interpolator; +import android.widget.FrameLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +/** + * FIXME + */ +public class PullToRefreshAttacher implements View.OnTouchListener { + + /** + * Default configuration values + */ + private static final int DEFAULT_HEADER_LAYOUT = R.layout.default_header; + private static final int DEFAULT_ANIM_HEADER_IN = R.anim.fade_in; + private static final int DEFAULT_ANIM_HEADER_OUT = R.anim.fade_out; + private static final float DEFAULT_REFRESH_SCROLL_DISTANCE = 0.5f; + + private static final boolean DEBUG = false; + private static final String LOG_TAG = "PullToRefreshAttacher"; + + private final EnvironmentDelegate mEnvironmentDelegate; + private final HeaderTransformer mHeaderTransformer; + + private final View mHeaderView; + private final Animation mHeaderInAnimation, mHeaderOutAnimation; + + private final int mTouchSlop; + private final float mRefreshScrollDistance; + + private float mInitialMotionY, mLastMotionY, mPullBeginY; + private boolean mIsBeingDragged, mIsRefreshing, mIsHandlingTouchEvent; + + private View mRefreshableView; + private ViewDelegate mViewDelegate; + + private OnRefreshListener mRefreshListener; + + private boolean mEnabled = true; + + /** + * FIXME + * @param activity + */ + public PullToRefreshAttacher(Activity activity) { + this(activity, new Options()); + } + + /** + * FIXME + * @param activity + * @param options + */ + public PullToRefreshAttacher(Activity activity, Options options) { + if (options == null) { + Log.i(LOG_TAG, "Given null options so using default options."); + options = new Options(); + } + + // Copy necessary values from options + mRefreshScrollDistance = options.refreshScrollDistance; + + // EnvironmentDelegate + mEnvironmentDelegate = options.environmentDelegate != null + ? options.environmentDelegate + : createDefaultEnvironmentDelegate(); + + // Header Transformer + mHeaderTransformer = options.headerTransformer != null + ? options.headerTransformer + : createDefaultHeaderTransformer(); + + // Create animations for use later + mHeaderInAnimation = AnimationUtils.loadAnimation(activity, options.headerInAnimation); + mHeaderOutAnimation = AnimationUtils.loadAnimation(activity, options.headerOutAnimation); + if (mHeaderOutAnimation != null) { + mHeaderOutAnimation.setAnimationListener(new AnimationCallback()); + } + + // Get touch slop for use later + mTouchSlop = ViewConfiguration.get(activity).getScaledTouchSlop(); + + // Get Window Decor View + final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView(); + + // Create Header view and then add to Decor View + mHeaderView = LayoutInflater.from(mEnvironmentDelegate.getContextForInflater(activity)) + .inflate(options.headerLayout, decorView, false); + if (mHeaderView == null) { + throw new IllegalArgumentException("Must supply valid layout id for header."); + } + mHeaderView.setVisibility(View.GONE); + + // Create DecorChildLayout which will move all of the system's decor view's children + the + // Header View to itself. See DecorChildLayout for more info. + DecorChildLayout decorContents = new DecorChildLayout(activity, decorView, mHeaderView); + + // Now add the DecorChildLayout to the decor view + decorView.addView(decorContents, ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT); + + // Notify transformer + mHeaderTransformer.onViewCreated(activity, mHeaderView); + } + + /** + * Set the view which will be used to initiate refresh requests and a listener to be invoked + * when a refresh is started. This version of the method will try to find a handler for the + * view from the built-in view delegates. + * + * @param view - View which will be used to initiate refresh requests. + * @param refreshListener - Listener to be invoked when a refresh is started. + */ + public void setRefreshableView(View view, OnRefreshListener refreshListener) { + setRefreshableView(view, null, refreshListener); + } + + /** + * Set the view which will be used to initiate refresh requests, along with a delegate which + * knows how to handle the given view, and a listener to be invoked when a refresh is started. + * + * @param view - View which will be used to initiate refresh requests. + * @param viewDelegate - delegate which knows how to handle view. + * @param refreshListener - Listener to be invoked when a refresh is started. + */ + public void setRefreshableView(View view, ViewDelegate viewDelegate, + OnRefreshListener refreshListener) { + // If we already have a refreshable view, reset it and our state + if (mRefreshableView != null) { + mRefreshableView.setOnTouchListener(null); + setRefreshingInt(false, false); + } + + // Update Refresh Listener + mRefreshListener = refreshListener; + + // Check to see if view is null + if (view == null) { + Log.i(LOG_TAG, "Refreshable View is null."); + mViewDelegate = null; + return; + } + + // View to detect refreshes for + mRefreshableView = view; + mRefreshableView.setOnTouchListener(this); + + // ViewDelegate + if (viewDelegate == null) { + viewDelegate = InstanceCreationUtils.getBuiltInViewDelegate(view); + if (viewDelegate == null) { + throw new IllegalArgumentException("No view handler found. Please provide one."); + } + } + mViewDelegate = viewDelegate; + } + + /** + * Manually set this Attacher's refreshing state. The header will be displayed or hidden as + * requested. + * @param refreshing - Whether the attacher should be in a refreshing state, + */ + public final void setRefreshing(boolean refreshing) { + setRefreshingInt(refreshing, false); + } + + /** + * @return true if this Attacher is currently in a refreshing state. + */ + public final boolean isRefreshing() { + return mIsRefreshing; + } + + /** + * @return true if this PullToRefresh is currently enabled (defaults to true) + */ + public boolean isEnabled() { + return mEnabled; + } + + /** + * Allows the enable/disable of this PullToRefreshAttacher. If disabled when refreshing then + * the UI is automatically reset. + * + * @param enabled - Whether this PullToRefreshAttacher is enabled. + */ + public void setEnabled(boolean enabled) { + mEnabled = enabled; + + if (!enabled) { + // If we're not enabled, reset any touch handling + resetTouch(); + + // If we're currently refreshing, reset the ptr UI + if (mIsRefreshing) { + reset(false); + } + } + } + + /** + * Call this when your refresh is complete and this view should reset itself (header view + * will be hidden). + * + * This is the equivalent of calling setRefreshing(false). + */ + public final void setRefreshComplete() { + setRefreshingInt(false, false); + } + + /** + * @return The HeaderTransformer currently used by this Attacher. + */ + public HeaderTransformer getHeaderTransformer() { + return mHeaderTransformer; + } + + @Override + public final boolean onTouch(View view, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN && event.getEdgeFlags() != 0) { + return false; + } + + // If we're not enabled don't handle any touch events + if (!isEnabled()) { + return false; + } + + switch (event.getAction()) { + case MotionEvent.ACTION_MOVE: { + // If we're already refreshing ignore it + if (mIsRefreshing) { + return false; + } + + final float y = event.getY(); + + // As there are times when we are not given the ACTION_DOWN, we need to check here + // whether we should handle the event + if (!mIsHandlingTouchEvent) { + if (canRefresh(true) && mViewDelegate.isScrolledToTop(mRefreshableView)) { + mIsHandlingTouchEvent = true; + mInitialMotionY = y; + } else { + // We're still not handling the event, so fail-fast + return false; + } + } + + // We're not currently being dragged so check to see if the user has scrolled enough + if (!mIsBeingDragged && (y - mInitialMotionY) > mTouchSlop) { + mIsBeingDragged = true; + onPullStarted(y); + } + + if (mIsBeingDragged) { + final float yDx = y - mLastMotionY; + + /** + * Check to see if the user is scrolling the right direction (down). + * We allow a small scroll up which is the check against negative touch slop. + */ + if (yDx >= -mTouchSlop) { + onPull(y); + // Only record the y motion if the user has scrolled down. + if (yDx > 0f) { + mLastMotionY = y; + } + } else { + resetTouch(); + } + } + break; + } + + case MotionEvent.ACTION_DOWN: { + // If we're already refreshing, ignore + if (canRefresh(true) && mViewDelegate.isScrolledToTop(mRefreshableView)) { + mIsHandlingTouchEvent = true; + mInitialMotionY = event.getY(); + } + break; + } + + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: { + resetTouch(); + break; + } + } + + // Always return false as we only want to observe events + return false; + } + + private void resetTouch() { + if (mIsBeingDragged) { + // We were being dragged, but not any more. + mIsBeingDragged = false; + onPullEnded(); + } + mIsHandlingTouchEvent = false; + mInitialMotionY = mLastMotionY = mPullBeginY = 0f; + } + + void onPullStarted(float y) { + if (DEBUG) { + Log.d(LOG_TAG, "onPullStarted"); + } + // Show Header + if (mHeaderInAnimation != null) { + mHeaderView.startAnimation(mHeaderInAnimation); + } + mHeaderView.setVisibility(View.VISIBLE); + mPullBeginY = y; + } + + void onPull(float y) { + if (DEBUG) { + Log.d(LOG_TAG, "onPull"); + } + + final float pxScrollForRefresh = mRefreshableView.getHeight() * mRefreshScrollDistance; + final float scrollLength = y - mPullBeginY; + + if (scrollLength < pxScrollForRefresh) { + mHeaderTransformer.onPulled(scrollLength / pxScrollForRefresh); + } else { + setRefreshingInt(true, true); + } + } + + void onPullEnded() { + if (DEBUG) { + Log.d(LOG_TAG, "onPullEnded"); + } + if (!mIsRefreshing) { + reset(true); + } + } + + protected EnvironmentDelegate createDefaultEnvironmentDelegate() { + return new EnvironmentDelegate(); + } + + protected HeaderTransformer createDefaultHeaderTransformer() { + return new DefaultHeaderTransformer(); + } + + private void setRefreshingInt(boolean refreshing, boolean fromTouch) { + if (DEBUG) { + Log.d(LOG_TAG, "setRefreshingInt: " + refreshing); + } + // Check to see if we need to do anything + if (mIsRefreshing == refreshing) { + return; + } + + if (refreshing && canRefresh(fromTouch)) { + startRefresh(fromTouch); + } else { + reset(fromTouch); + } + } + + /** + * @param fromTouch - Whether this is being invoked from a touch event + * @return true if we're currently in a state where a refresh can be started. + */ + private boolean canRefresh(boolean fromTouch) { + return !mIsRefreshing && (!fromTouch || mRefreshListener != null); + } + + private void reset(boolean fromTouch) { + // Update isRefreshing state + mIsRefreshing = false; + + if (mHeaderView.getVisibility() != View.GONE) { + // Hide Header + if (mHeaderOutAnimation != null) { + mHeaderView.startAnimation(mHeaderOutAnimation); + // HeaderTransformer.onReset() is called once the animation has finished + } else { + // As we're not animating, hide the header + call the header transformer now + mHeaderView.setVisibility(View.GONE); + mHeaderTransformer.onReset(); + } + } + } + + private void startRefresh(boolean fromTouch) { + // Update isRefreshing state + mIsRefreshing = true; + + // Call OnRefreshListener if this call has originated from a touch event + if (fromTouch) { + mRefreshListener.onRefreshStarted(mRefreshableView); + } + // Call Transformer + mHeaderTransformer.onRefreshStarted(); + + // Make sure header is visible. + if (mHeaderView.getVisibility() != View.VISIBLE) { + if (mHeaderInAnimation != null) { + mHeaderView.startAnimation(mHeaderInAnimation); + } + mHeaderView.setVisibility(View.VISIBLE); + } + } + + /** + * Simple Listener to listen for any callbacks to Refresh. + */ + public interface OnRefreshListener { + /** + * Called when the user has initiated a refresh by pulling. + * @param view - View which the user has started the refresh from. + */ + public void onRefreshStarted(View view); + } + + public static abstract class HeaderTransformer { + /** + * Called whether the header view has been inflated from the resources defined in + * {@link Options#headerLayout}. + * + * @param headerView - inflated header view. + */ + public abstract void onViewCreated(Activity activity, View headerView); + + /** + * Called when the header should be reset. You should update any child views to reflect this. + *

+ * You should not change the + * visibility of the header view. + */ + public abstract void onReset(); + + /** + * Called the user has pulled on the scrollable view. + * @param percentagePulled - value between 0.0f and 1.0f depending on how far the user has pulled. + */ + public abstract void onPulled(float percentagePulled); + + /** + * Called when a refresh has begun. Theoretically this call is similar to that provided + * from {@link OnRefreshListener} but is more suitable for header view updates. + */ + public abstract void onRefreshStarted(); + } + + /** + * FIXME + */ + public static abstract class ViewDelegate { + + /** + * Allows you to provide support for View which do not have built-in support. In this + * method you should cast view to it's native class, and check if it is + * scrolled to the top. + * + * @param view The view which has should be checked against. + * @return true if view is scrolled to the top. + */ + public abstract boolean isScrolledToTop(View view); + } + + /** + * FIXME + */ + public static class EnvironmentDelegate { + + /** + * @return Context which should be used for inflating the header layout + */ + public Context getContextForInflater(Activity activity) { + if (Build.VERSION.SDK_INT >= 14) { + return activity.getActionBar().getThemedContext(); + } else { + return activity; + } + } + } + + public static final class Options { + /** + * EnvironmentDelegate instance which will be used. If null, we will create an instance of + * the default class. + */ + public EnvironmentDelegate environmentDelegate = null; + + /** + * The layout resource ID which should be inflated to be displayed above the Action Bar + */ + public int headerLayout = DEFAULT_HEADER_LAYOUT; + + /** + * The header transformer to be used to transfer the header view. If null, an instance of + * {@link DefaultHeaderTransformer} will be used. + */ + public HeaderTransformer headerTransformer = null; + + /** + * The anim resource ID which should be started when the header is being hidden. + */ + public int headerOutAnimation = DEFAULT_ANIM_HEADER_OUT; + + /** + * The anim resource ID which should be started when the header is being shown. + */ + public int headerInAnimation = DEFAULT_ANIM_HEADER_IN; + + /** + * The percentage of the refreshable view that needs to be scrolled before a refresh + * is initiated. + */ + public float refreshScrollDistance = DEFAULT_REFRESH_SCROLL_DISTANCE; + } + + private class AnimationCallback implements Animation.AnimationListener { + + @Override + public void onAnimationStart(Animation animation) { + } + + @Override + public void onAnimationEnd(Animation animation) { + if (animation == mHeaderOutAnimation) { + mHeaderView.setVisibility(View.GONE); + mHeaderTransformer.onReset(); + } + } + + @Override + public void onAnimationRepeat(Animation animation) { + } + } + + /** + * Default Header Transformer. + */ + public static class DefaultHeaderTransformer extends HeaderTransformer { + private TextView mHeaderTextView; + private ProgressBar mHeaderProgressBar; + + private CharSequence mPullRefreshLabel, mRefreshingLabel; + + private final Interpolator mInterpolator = new AccelerateInterpolator(); + + @Override + public void onViewCreated(Activity activity, View headerView) { + // Get ProgressBar and TextView. Also set initial text on TextView + mHeaderProgressBar = (ProgressBar) headerView.findViewById(R.id.ptr_progress); + mHeaderTextView = (TextView) headerView.findViewById(R.id.ptr_text); + + // Labels to display + mPullRefreshLabel = activity.getString(R.string.pull_to_refresh_pull_label); + mRefreshingLabel = activity.getString(R.string.pull_to_refresh_refreshing_label); + + View contentView = headerView.findViewById(R.id.ptr_content); + if (contentView != null) { + contentView.getLayoutParams().height = getActionBarSize(activity); + contentView.requestLayout(); + } + + Drawable abBg = getActionBarBackground(activity); + if (abBg != null) { + // If we do not have a opaque background we just display a solid solid behind it + if (abBg.getOpacity() != PixelFormat.OPAQUE) { + View view = headerView.findViewById(R.id.ptr_text_opaque_bg); + if (view != null) { + view.setVisibility(View.VISIBLE); + } + } + + mHeaderTextView.setBackgroundDrawable(abBg); + } + + // Call onReset to make sure that the View is consistent + onReset(); + } + + @Override + public void onReset() { + // Reset Progress Bar + if (mHeaderProgressBar != null) { + mHeaderProgressBar.setVisibility(View.GONE); + mHeaderProgressBar.setProgress(0); + mHeaderProgressBar.setIndeterminate(false); + } + + // Reset Text View + if (mHeaderTextView != null) { + mHeaderTextView.setVisibility(View.VISIBLE); + mHeaderTextView.setText(mPullRefreshLabel); + } + } + + @Override + public void onPulled(float percentagePulled) { + if (mHeaderProgressBar != null) { + mHeaderProgressBar.setVisibility(View.VISIBLE); + final float progress = mInterpolator.getInterpolation(percentagePulled); + mHeaderProgressBar.setProgress(Math.round(mHeaderProgressBar.getMax() * progress)); + } + } + + @Override + public void onRefreshStarted() { + if (mHeaderTextView != null) { + mHeaderTextView.setText(mRefreshingLabel); + } + if (mHeaderProgressBar != null) { + mHeaderProgressBar.setVisibility(View.VISIBLE); + mHeaderProgressBar.setIndeterminate(true); + } + } + + /** + * Set Text to show to prompt the user is pull (or keep pulling). + * @param pullText - Text to display. + */ + public void setPullText(CharSequence pullText) { + mPullRefreshLabel = pullText; + if (mHeaderTextView != null) { + mHeaderTextView.setText(mPullRefreshLabel); + } + } + + /** + * Set Text to show to tell the user that a refresh is currently in progress. + * @param refreshingText - Text to display. + */ + public void setRefreshingText(CharSequence refreshingText) { + mRefreshingLabel = refreshingText; + } + + protected Drawable getActionBarBackground(Context context) { + int[] android_styleable_ActionBar = { android.R.attr.background }; + + // Need to get resource id of style pointed to from actionBarStyle + TypedValue outValue = new TypedValue(); + context.getTheme().resolveAttribute(android.R.attr.actionBarStyle, outValue, true); + // Now get action bar style values... + TypedArray abStyle = context.getTheme().obtainStyledAttributes(outValue.resourceId, + android_styleable_ActionBar); + try { + // background is the first attr in the array above so it's index is 0. + return abStyle.getDrawable(0); + } finally { + abStyle.recycle(); + } + } + + protected int getActionBarSize(Context context) { + int[] attrs = { android.R.attr.actionBarSize }; + TypedArray values = context.getTheme().obtainStyledAttributes(attrs); + try { + return values.getDimensionPixelSize(0, 0); + } finally { + values.recycle(); + } + } + } + + /** + * This class allows us to insert a layer in between the system decor view and the actual decor. + * (e.g. Action Bar views). This is needed so we can receive a call to fitSystemWindows(Rect) + * so we can adjust the header view to fit the system windows too. + */ + final static class DecorChildLayout extends FrameLayout { + private ViewGroup mHeaderViewWrapper; + + DecorChildLayout(Context context, ViewGroup systemDecorView, View headerView) { + super(context); + + // Move all children from decor view to here + for (int i = 0, z = systemDecorView.getChildCount() ; i < z ; i++) { + View child = systemDecorView.getChildAt(i); + systemDecorView.removeView(child); + addView(child); + } + + /** + * Wrap the Header View in a FrameLayout and add it to this view. It is wrapped + * so any inset changes do not affect the actual header view. + */ + mHeaderViewWrapper = new FrameLayout(context); + mHeaderViewWrapper.addView(headerView); + addView(mHeaderViewWrapper, ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + } + + @Override + protected boolean fitSystemWindows(Rect insets) { + if (DEBUG) { + Log.d(LOG_TAG, "fitSystemWindows: " + insets.toString()); + } + + // Adjust the Header View's padding to take the insets into account + mHeaderViewWrapper.setPadding(insets.left, insets.top, insets.right, insets.bottom); + + // Call return super so that the rest of the + return super.fitSystemWindows(insets); + } + } + +} diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/AbsListViewDelegate.java b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/AbsListViewDelegate.java new file mode 100644 index 00000000..cb31bf19 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/AbsListViewDelegate.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013 Chris Banes + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.co.senab.actionbarpulltorefresh.library.viewdelegates; + +import android.view.View; +import android.widget.AbsListView; + +import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshAttacher; + +/** + * FIXME + */ +public class AbsListViewDelegate + extends PullToRefreshAttacher.ViewDelegate { + + public static final Class SUPPORTED_VIEW_CLASS = AbsListView.class; + + @Override + public boolean isScrolledToTop(View view) { + AbsListView absListView = (AbsListView) view; + if (absListView.getCount() == 0) { + return true; + } else if (absListView.getFirstVisiblePosition() == 0) { + final View firstVisibleChild = absListView.getChildAt(0); + return firstVisibleChild != null && firstVisibleChild.getTop() >= 0; + } + return false; + } +} diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/ScrollViewDelegate.java b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/ScrollViewDelegate.java new file mode 100644 index 00000000..5b4602fe --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/ScrollViewDelegate.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013 Chris Banes + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.co.senab.actionbarpulltorefresh.library.viewdelegates; + +import android.view.View; +import android.widget.ScrollView; + +import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshAttacher; + +/** + * FIXME + */ +public class ScrollViewDelegate extends PullToRefreshAttacher.ViewDelegate { + + public static final Class SUPPORTED_VIEW_CLASS = ScrollView.class; + + @Override + public boolean isScrolledToTop(View view) { + return view.getScrollY() <= 0; + } +} diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/WebViewDelegate.java b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/WebViewDelegate.java new file mode 100644 index 00000000..46c5df11 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/library/src/uk/co/senab/actionbarpulltorefresh/library/viewdelegates/WebViewDelegate.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013 Chris Banes + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.co.senab.actionbarpulltorefresh.library.viewdelegates; + +import android.view.View; +import android.webkit.WebView; + +import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshAttacher; + +/** + * FIXME + */ +public class WebViewDelegate extends PullToRefreshAttacher.ViewDelegate { + + public static final Class SUPPORTED_VIEW_CLASS = WebView.class; + + @Override + public boolean isScrolledToTop(View view) { + return view.getScrollY() <= 0; + } +} diff --git a/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/pom.xml b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/pom.xml new file mode 100644 index 00000000..e83502e1 --- /dev/null +++ b/dependencies/ActionBar-PullToRefresh-e8e6d2b58c/pom.xml @@ -0,0 +1,111 @@ + + + 4.0.0 + + com.github.chrisbanes.actionbarpulltorefresh + parent + pom + 0.4 + ActionBar-PullToRefresh Project + A modern implementation of the pull-to-refresh for Android + https://github.com/chrisbanes/ActionBar-PullToRefresh + + + org.sonatype.oss + oss-parent + 7 + + + + + Apache License Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + https://github.com/chrisbanes/Android-BitmapCache + scm:git:git://github.com/chrisbanes/ActionBar-PullToRefresh.git + scm:git:git@github.com:chrisbanes/ActionBar-PullToRefresh.git + + v0.4 + + + + + Chris Banes + http://www.senab.co.uk + chrisbanes + + + + + library + samples + extras + + + + + UTF-8 + UTF-8 + 1.6 + 4.1.1.4 + 16 + 3.6.0 + 3.1 + 2.4.1 + + + + + + com.google.android + android + ${android.version} + provided + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler.version} + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-release-plugin + ${maven-release.version} + + v@{project.version} + + + + com.jayway.maven.plugins.android.generation2 + android-maven-plugin + ${android-maven.version} + + + ${android.platform} + + true + ${sourceCompatibility} + ${sourceCompatibility} + + true + + + + src + + diff --git a/project.properties b/project.properties index bdbc006e..61face42 100644 --- a/project.properties +++ b/project.properties @@ -11,6 +11,6 @@ split.density=false # Project target. target=android-16 -android.library.reference.1=dependencies/JakeWharton-ActionBarSherlock-c47975f/actionbarsherlock -android.library.reference.2=dependencies/chuckbjones-SwipeToDismissUndoList-ec6bf93 +android.library.reference.1=dependencies/chuckbjones-SwipeToDismissUndoList-ec6bf93 +android.library.reference.2=dependencies/ActionBar-PullToRefresh-e8e6d2b58c/extras/actionbarsherlock android.library=false diff --git a/res/layout/main.xml b/res/layout/main.xml index 154f7036..0f1927d8 100644 --- a/res/layout/main.xml +++ b/res/layout/main.xml @@ -56,7 +56,7 @@ You should have received a copy of the GNU General Public License along with Tod android:layout_width="fill_parent" android:layout_height="0dip" android:background="@color/white" android:layout_weight="1"> diff --git a/res/menu/main.xml b/res/menu/main.xml index 93f6f936..31ac9b78 100644 --- a/res/menu/main.xml +++ b/res/menu/main.xml @@ -24,11 +24,6 @@ You should have received a copy of the GNU General Public License along with Tod

- = android.os.Build.VERSION_CODES.GINGERBREAD_MR1) { - if (m_app.syncInProgress()) { - refreshMenu.setActionView(progress); - } else { - refreshMenu.setActionView(null); - } - } else { - if (m_app.syncInProgress()) { - refreshMenu.setEnabled(false); - } else { - refreshMenu.setEnabled(true); - } - } - - } + + m_pullToRefreshAttacher.setRefreshComplete(); if (redrawList) { // hide action bar @@ -1218,6 +1209,11 @@ private void updateSyncUI(boolean redrawList) { setFilteredTasks(false); } } + + @Override + public void onRefreshStarted(View view) { + syncClient(false); + } public class TaskAdapter extends ArrayAdapter { private LayoutInflater m_inflater;