resolved conflicts for merge of 1adaa571 to gingerbread-plus-aosp
Change-Id: I6c2ea537a9f6dce3c5d54b8c3c720b49058fea68
diff --git a/apps/Development/src/com/android/development/PackageSummary.java b/apps/Development/src/com/android/development/PackageSummary.java
index 58ab0f7..d621d4e 100644
--- a/apps/Development/src/com/android/development/PackageSummary.java
+++ b/apps/Development/src/com/android/development/PackageSummary.java
@@ -251,7 +251,7 @@
private final static void setItemText(Button item, PackageInfo pi,
String className)
{
- item.setText(className.substring(pi.packageName.length()+1));
+ item.setText(className.substring(className.lastIndexOf('.')+1));
}
private final class ActivityOnClick implements View.OnClickListener
diff --git a/build/sdk.atree b/build/sdk.atree
index 161136e..250d97b 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -60,7 +60,7 @@
sdk/sdk-build.prop platforms/${PLATFORM_NAME}/build.prop
# the uper-jar file that apps link against. This is the public API
-out/target/common/obj/PACKAGING/android_jar_intermediates/android.jar platforms/${PLATFORM_NAME}/android.jar
+${OUT_DIR}/target/common/obj/PACKAGING/android_jar_intermediates/android.jar platforms/${PLATFORM_NAME}/android.jar
# the aidl precompiled include
obj/framework.aidl platforms/${PLATFORM_NAME}/framework.aidl
diff --git a/build/tools/make_windows_sdk.sh b/build/tools/make_windows_sdk.sh
deleted file mode 100755
index 1154452..0000000
--- a/build/tools/make_windows_sdk.sh
+++ /dev/null
@@ -1,258 +0,0 @@
-#!/bin/bash
-# Quick semi-auto file to build Windows SDK tools.
-#
-# Limitations and requirements:
-# - Expects the emulator has been built first, will pick it up from prebuilt.
-# - Run in Cygwin
-# - Expects to have one of the existing SDK (Darwin or Linux) to build the Windows one
-# - Needs Cygwin packages: autoconf, bison, curl, flex, gcc, g++, git,
-# gnupg, make, mingw-zlib, python, zip, unzip
-# - Must NOT have cygwin package readline (its GPL license might taint the SDK if
-# it gets compiled in)
-# - Does not need a Java Development Kit or any other tools outside of cygwin.
-# - If you think you may have Windows versions of tools (e.g. make) installed, it may
-# reduce confusion levels to 'export PATH=/usr/bin'
-
-PROG_NAME="$0"
-SDK_ZIP="$1"; shift
-DIST_DIR="$1"; shift
-TEMP_DIR="$1"; shift
-[ -z "$TEMP_DIR" ] && TEMP_DIR=${TMP:-/tmp}
-
-set -e # Fail this script as soon as a command fails -- fail early, fail fast
-
-function die() {
- echo "Error:" $*
- echo "Aborting"
- exit 1
-}
-
-function usage() {
- local NAME
- NAME=`basename ${PROG_NAME}`
- echo "Usage: ${NAME} linux_or_mac_sdk.zip output_dir [temp_dir]"
- echo "If temp_dir is not given, \$TMP is used. If that's missing, /tmp is used."
- status
- exit 2
-}
-
-function status() {
- echo "Current values:"
- echo "- Input SDK: ${SDK_ZIP:-missing}"
- echo "- Output dir: ${DIST_DIR:-missing}"
- echo "- Temp dir: ${TEMP_DIR:-missing}"
-}
-
-function check() {
- [ -f "$SDK_ZIP" ] || usage
- [ -d "$DIST_DIR" ] || usage
-
-
- # We need mgwz.dll in the SDK when compiling with Cygwin 1.5
- # Right now we don't support building with Cygwin 1.7 yet, as it lacks this DLL.
- NEED_MGWZ=1
- # We can skip this check for debug purposes.
- echo $*
- [[ "$1" == "-no-mgwz" ]] && NEED_MGWZ=""
- CYG_MGWZ_PATH=/cygdrive/c/cygwin/bin/mgwz.dll
- [[ -n $NEED_MGWZ && ! -f $CYG_MGWZ_PATH ]] && \
- die "Cygwin is missing $CYG_MGWZ_PATH. Use -no-mgwz to override."
-
-
- # Use the BUILD_ID as SDK_NUMBER if defined, otherwise try to get it from the
- # provided zip filename.
- if [ -f config/build_id.make ]; then
- BUILD_ID=`cat config/build_id.make | sed -n '/BUILD_ID=/s/^[^=]\+=\(.*\)$/\1/p'`
- [ -n "$BUILD_ID" ] && SDK_NUMBER="$BUILD_ID"
- fi
- if [ -z "$SDK_NUMBER" ]; then
- # Look for a pattern like "anything_sdknumber.extension"
- # The pattern is now "any-thing_sdknumber_anything-else.extension"
- #
- # The bottom line is that the SDK number is whatever is enclosed by
- # the LAST couple of underscores. You can have underscores *before* the
- # SDK number if you want, but not after, e.g these are valid:
- # android_sdk_4242_platform.zip or blah_42_.zip
- #
- # Note that the root directory name in the zip must match the zip
- # name, too, so there's no point just changing the zip name to match
- # the above format.
- #
- # SDK_NUMBER will be empty if nothing matched.
- filename=`basename "$SDK_ZIP"`
- SDK_NUMBER=`echo $filename | sed -n 's/^.*_\([^_./]\+\)_[^_.]*\..*$/\1/p'`
- fi
-
- [ -n "$SDK_NUMBER" ] || die "Failed to extract the SDK number from $SDK_ZIP. Check its format."
-
- [ $OSTYPE == "cygwin" ] || die "This expects to run under Cygwin"
- [ -e `which zip` ] || die "Please install 'zip' package in Cygwin"
- [ -f "build/envsetup.sh" ] || die "Please run this from the 'android' directory"
-
- echo "Using SDK ${SDK_NUMBER}"
-}
-
-function build() {
-
- # IMPORTANT: For Cygwin to be able to build Android targets here,
- # you will generally need to edit build/core/main.mk and add directories
- # where Android.mk makefiles are to be found to the SDK_ONLY==true section.
-
- echo
- echo "Building..."
- [ -n "$MAKE_OPT" ] && echo "Make options: $MAKE_OPT"
-
- . build/envsetup.sh
-
- # Disable parallel build: it generates "permission denied" issues when
- # multiple "ar.exe" are running in parallel.
- make \
- aapt adb aidl \
- etc1tool \
- prebuilt \
- dexdump dmtracedump \
- fastboot \
- hprof-conv \
- mksdcard \
- sdklauncher sqlite3 \
- zipalign \
- || die "Build failed"
-
- # Fix permissions. Git/cygwin may not make this +x as needed.
- chmod +x prebuilt/windows/sdl/bin/sdl-config
-
- # It's worth building the emulator with -j 4 so do it separately
- make -j 4 emulator || die "Build failed"
-}
-
-function package() {
- echo
- echo "Packaging..."
- DEST_NAME="android-sdk_${SDK_NUMBER}_windows"
- DEST_NAME_ZIP="${DEST_NAME}.zip"
-
- TEMP_SDK_DIR="$TEMP_DIR/$DEST_NAME"
-
- # Unzip current linux/mac SDK and rename using the windows name
- [ -e "$TEMP_SDK_DIR" ] && rm -rfv "$TEMP_SDK_DIR" # cleanup dest first if exists
- UNZIPPED=`basename "$SDK_ZIP"`
- UNZIPPED="$TEMP_DIR/${UNZIPPED/.zip/}"
- [ -e "$UNZIPPED" ] && rm -rfv "$UNZIPPED" # cleanup unzip dir (if exists)
- unzip "$SDK_ZIP" -d "$TEMP_DIR"
- mv -v "$UNZIPPED" "$TEMP_SDK_DIR"
-
- # Assert that the package contains only one platform
- PLATFORMS="$TEMP_SDK_DIR/platforms"
- THE_PLATFORM=`echo $PLATFORMS/*`
- PLATFORM_TOOLS=$THE_PLATFORM/tools
- echo "Platform found: " $THE_PLATFORM
- [[ -d "$THE_PLATFORM" ]] || die \
- "Error: One platform was expected in $SDK_ZIP. " \
- "Instead found " $THE_PLATFORM
- [[ -d "$PLATFORM_TOOLS" ]] || die "Missing folder $PLATFORM_TOOLS."
-
- # Package USB Driver
- if type package_usb_driver 2>&1 | grep -q function ; then
- package_usb_driver $TEMP_SDK_DIR
- fi
-
- # Remove obsolete stuff from tools & platform
- TOOLS="$TEMP_SDK_DIR/tools"
- LIB="$TEMP_SDK_DIR/tools/lib"
- rm -v "$TOOLS"/{adb,android,apkbuilder,ddms,dmtracedump,draw9patch,emulator,etc1tool}
- rm -v "$TOOLS"/{hierarchyviewer,hprof-conv,layoutopt,mksdcard,sqlite3,traceview,zipalign}
- rm -v "$LIB"/*/swt.jar
- rm -v "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump}
-
- # Copy all the new stuff in tools
- # Note: some tools are first copied here and then moved in platforms/<name>/tools/
- cp -v out/host/windows-x86/bin/*.{exe,dll} "$TOOLS"/
- mkdir -pv "$LIB"/x86
- cp -v prebuilt/windows/swt/swt.jar "$LIB"/x86/
- mkdir -pv "$LIB"/x86_64
- cp -v prebuilt/windows-x86_64/swt/swt.jar "$LIB"/x86_64/
-
- # Copy the SDK Manager (aka sdklauncher) to the root of the SDK (it was copied in tools above)
- # and move it also in SDK/tools/lib (so that tools updates can update the root one too)
- cp "$TOOLS/sdklauncher.exe" "$TEMP_SDK_DIR/SDK Manager.exe"
- mv "$TOOLS/sdklauncher.exe" "$LIB/SDK Manager.exe"
-
- # If you want the emulator NOTICE in the tools dir, uncomment the following line:
- # cp -v external/qemu/NOTICE "$TOOLS"/emulator_NOTICE.txt
-
- # We currently need libz from MinGW for aapt
- [[ -n $NEED_MGWZ ]] && cp -v $CYG_MGWZ_PATH "$TOOLS"/
-
- # Update a bunch of bat files
- cp -v sdk/files/post_tools_install.bat "$LIB"/
- cp -v sdk/files/find_java.bat "$LIB"/
- cp -v sdk/apkbuilder/etc/apkbuilder.bat "$TOOLS"/
- cp -v sdk/ddms/app/etc/ddms.bat "$TOOLS"/
- cp -v sdk/traceview/etc/traceview.bat "$TOOLS"/
- cp -v sdk/hierarchyviewer2/app/etc/hierarchyviewer.bat "$TOOLS"/
- cp -v sdk/layoutopt/app/etc/layoutopt.bat "$TOOLS"/
- cp -v sdk/draw9patch/etc/draw9patch.bat "$TOOLS"/
- cp -v sdk/sdkmanager/app/etc/android.bat "$TOOLS"/
-
- # Put the JetCreator tools, content and docs (not available in the linux SDK)
- JET="$TOOLS/Jet"
- JETCREATOR="$JET/JetCreator"
- JETDEMOCONTENT="$JET/demo_content"
- JETLOGICTEMPLATES="$JET/logic_templates"
- JETDOC="$TEMP_SDK_DIR/docs/JetCreator"
-
- # need to rm these folders since a Mac SDK will have them and it might create a conflict
- rm -rfv "$JET"
- rm -rfv "$JETDOC"
-
- # now create fresh folders for JetCreator
- mkdir -v "$JET"
- mkdir -v "$JETDOC"
-
- cp -rv external/sonivox/jet_tools/JetCreator "$JETCREATOR"/
- cp -rv external/sonivox/jet_tools/JetCreator_content "$JETDEMOCONTENT"/
- cp -rv external/sonivox/jet_tools/logic_templates "$JETLOGICTEMPLATES"/
- chmod -vR u+w "$JETCREATOR" # fixes an issue where Cygwin might copy the above as u+rx only
- cp -v prebuilt/windows/jetcreator/EASDLL.dll "$JETCREATOR"/
-
- cp -v external/sonivox/docs/JET_Authoring_Guidelines.html "$JETDOC"/
- cp -rv external/sonivox/docs/JET_Authoring_Guidelines_files "$JETDOC"/
- cp -v external/sonivox/docs/JET_Creator_User_Manual.html "$JETDOC"/
- cp -rv external/sonivox/docs/JET_Creator_User_Manual_files "$JETDOC"/
-
- # Copy or move platform specific tools to the default platform.
- cp -v dalvik/dx/etc/dx.bat "$PLATFORM_TOOLS"/
- mv -v "$TOOLS"/{aapt.exe,aidl.exe,dexdump.exe} "$PLATFORM_TOOLS"/
- # Note: mgwz.dll must be both in SDK/tools for zipalign and in SDK/platform/XYZ/tools/ for aapt
- [[ -n $NEED_MGWZ ]] && cp -v "$TOOLS"/mgwz.dll "$PLATFORM_TOOLS"/
-
- # Fix EOL chars to make window users happy - fix all files at the top level only
- # as well as all batch files including those in platforms/<name>/tools/
- find "$TEMP_SDK_DIR" -maxdepth 1 -type f -writable -print0 | xargs -0 unix2dos -D
- find "$TEMP_SDK_DIR" -maxdepth 3 -name "*.bat" -type f -writable -print0 | xargs -0 unix2dos -D
-
- # Done.. Zip it. Clean the temp folder ONLY if the zip worked (to ease debugging)
- pushd "$TEMP_DIR" > /dev/null
- [ -e "$DEST_NAME_ZIP" ] && rm -rfv "$DEST_NAME_ZIP"
- zip -9r "$DEST_NAME_ZIP" "$DEST_NAME" && rm -rfv "$DEST_NAME"
- popd > /dev/null
-
- # Now move the final zip from the temp dest to the final dist dir
- mv -v "$TEMP_DIR/$DEST_NAME_ZIP" "$DIST_DIR/$DEST_NAME_ZIP"
-
- # We want fastboot and adb (and its DLLs) next to the new SDK
- for i in fastboot.exe adb.exe AdbWinApi.dll AdbWinUsbApi.dll; do
- cp -vf out/host/windows-x86/bin/$i "$DIST_DIR"/$i
- done
-
- echo "Done"
- echo
- echo "Resulting SDK is in $DIST_DIR/$DEST_NAME_ZIP"
-}
-
-check $*
-status
-build
-package
-
-echo "Done"
diff --git a/build/tools/patch_windows_sdk.sh b/build/tools/patch_windows_sdk.sh
index 14acdac..dc74e9a 100755
--- a/build/tools/patch_windows_sdk.sh
+++ b/build/tools/patch_windows_sdk.sh
@@ -18,7 +18,12 @@
# Verbose by default. Use -q to make more silent.
V="-v"
-if [[ "$1" == "-q" ]]; then V=""; shift; fi
+Q=""
+if [[ "$1" == "-q" ]]; then
+ Q="$1"
+ V=""
+ shift
+fi
TEMP_SDK_DIR=$1
WIN_OUT_DIR=$2
@@ -48,8 +53,8 @@
TOOLS=$TEMP_SDK_DIR/tools
PLATFORM_TOOLS=$TEMP_SDK_DIR/platform-tools
LIB=$TEMP_SDK_DIR/tools/lib
-rm $V $TOOLS/{android,apkbuilder,ddms,dmtracedump,draw9patch,emulator,etc1tool}
-rm $V $TOOLS/{hierarchyviewer,hprof-conv,layoutopt,mksdcard,sqlite3,traceview,zipalign}
+rm $V $TOOLS/{dmtracedump,etc1tool,hprof-conv,sqlite3,zipalign}
+rm $V $TOOLS/proguard/bin/*.sh
rm $V $LIB/*/swt.jar
rm $V $PLATFORM_TOOLS/{adb,aapt,aidl,dx,dexdump}
@@ -61,33 +66,6 @@
mkdir -pv $LIB/x86_64
cp $V ${TOPDIR}prebuilt/windows-x86_64/swt/swt.jar $LIB/x86_64/
-# Copy the SDK Manager (aka sdklauncher) to the root of the SDK (it was copied in tools above)
-# and move it also in SDK/tools/lib (so that tools updates can update the root one too)
-cp $TOOLS/sdklauncher.exe $TEMP_SDK_DIR/"SDK Manager.exe"
-mv $TOOLS/sdklauncher.exe $LIB/"SDK Manager.exe"
-
-# Copy the emulator NOTICE in the tools dir
-cp $V ${TOPDIR}external/qemu/NOTICE $TOOLS/emulator_NOTICE.txt
-
-# aapt under cygwin needs to have mgwz.dll
-[[ -n $NEED_MGWZ ]] && cp $V $CYG_MGWZ_PATH $TOOLS/
-
-# Update a bunch of bat files
-cp $V ${TOPDIR}sdk/files/post_tools_install.bat $LIB/
-cp $V ${TOPDIR}sdk/files/find_java.bat $LIB/
-cp $V ${TOPDIR}sdk/apkbuilder/etc/apkbuilder.bat $TOOLS/
-cp $V ${TOPDIR}sdk/ddms/app/etc/ddms.bat $TOOLS/
-cp $V ${TOPDIR}sdk/traceview/etc/traceview.bat $TOOLS/
-if [ -f ${TOPDIR}sdk/hierarchyviewer2/app/etc/hierarchyviewer.bat ]; then
- cp $V ${TOPDIR}sdk/hierarchyviewer2/app/etc/hierarchyviewer.bat $TOOLS/
-else
- # That's ok because currently GB uses Tools_r7 but we'll ship Tools_r8 from master-open.
- echo "WARNING: Ignoring ${TOPDIR}sdk/hierarchyviewer2/app/etc/hierarchyviewer.bat [ok for GB+Tools r8]"
-fi
-cp $V ${TOPDIR}sdk/layoutopt/app/etc/layoutopt.bat $TOOLS/
-cp $V ${TOPDIR}sdk/draw9patch/etc/draw9patch.bat $TOOLS/
-cp $V ${TOPDIR}sdk/sdkmanager/app/etc/android.bat $TOOLS/
-
# Put the JetCreator tools, content and docs (not available in the linux SDK)
JET=$TOOLS/Jet
JETCREATOR=$JET/JetCreator
@@ -118,10 +96,6 @@
cp $V ${TOPDIR}dalvik/dx/etc/dx.bat $PLATFORM_TOOLS/
mv $V $TOOLS/{adb.exe,aapt.exe,aidl.exe,dexdump.exe} $TOOLS/Adb*.dll $PLATFORM_TOOLS/
-# When building under cygwin, mgwz.dll must be both in SDK/tools for zipalign
-# and in SDK/platform/XYZ/tools/ for aapt
-[[ -n $NEED_MGWZ ]] && cp $V $TOOLS/mgwz.dll $PLATFORM_TOOLS/
-
# Fix EOL chars to make window users happy - fix all files at the top level
# as well as all batch files including those in platforms/<name>/tools/
if [[ -x $UNIX2DOS ]]; then
@@ -129,6 +103,9 @@
find $TEMP_SDK_DIR -maxdepth 3 -name "*.bat" -type f -print0 | xargs -0 $UNIX2DOS
fi
+# Execute the packaging script in the sdk directory
+${TOPDIR}sdk/build/patch_windows_sdk.sh $Q ${TEMP_SDK_DIR} ${WIN_OUT_DIR} ${TOPDIR}
+
# Just to make it easier on the build servers, we want fastboot and adb (and its DLLs)
# next to the new SDK, so up one dir.
for i in fastboot.exe adb.exe AdbWinApi.dll AdbWinUsbApi.dll; do
diff --git a/build/tools/windows_sdk.mk b/build/tools/windows_sdk.mk
index f02822f..e7e63c7 100644
--- a/build/tools/windows_sdk.mk
+++ b/build/tools/windows_sdk.mk
@@ -22,16 +22,18 @@
$(error Need a unix2dos command. Please 'apt-get install tofrodos')
endif
+include $(TOPDIR)sdk/build/windows_sdk_tools.mk
+
WIN_TARGETS := \
aapt adb aidl \
- emulator etc1tool \
+ etc1tool \
dexdump dmtracedump \
fastboot \
hprof-conv \
- mksdcard \
prebuilt \
- sdklauncher sqlite3 \
- zipalign
+ sqlite3 \
+ zipalign \
+ $(WIN_SDK_TARGETS)
# LINUX_SDK_NAME/DIR is set in build/core/Makefile
WIN_SDK_NAME := $(subst $(HOST_OS)-$(HOST_ARCH),windows,$(LINUX_SDK_NAME))
@@ -72,6 +74,10 @@
$(TOPDIR)development/build/tools/patch_windows_sdk.sh \
$(subst @,-q,$(hide)) \
$(WIN_SDK_DIR)/$(WIN_SDK_NAME) $(OUT_DIR) $(TOPDIR)
+ $(hide) \
+ $(TOPDIR)sdk/build/patch_windows_sdk.sh \
+ $(subst @,-q,$(hide)) \
+ $(WIN_SDK_DIR)/$(WIN_SDK_NAME) $(OUT_DIR) $(TOPDIR)
$(hide) ( \
cd $(WIN_SDK_DIR) && \
rm -f $(WIN_SDK_NAME).zip && \
diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
index 68c9411..a1f3060 100644
--- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java
+++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
@@ -337,9 +337,9 @@
synchronized (Monkey.this) {
mAbort = true;
}
- return (mKillProcessAfterError) ? -1 : 1;
+ return (mKillProcessAfterError) ? -1 : 0;
}
- return 1;
+ return 0;
}
}
@@ -981,6 +981,9 @@
int eventCounter = 0;
int cycleCounter = 0;
+ boolean shouldReportAnrTraces = false;
+ boolean shouldReportDumpsysMemInfo = false;
+ boolean shouldAbort = false;
boolean systemCrashed = false;
// TO DO : The count should apply to each of the script file.
@@ -991,8 +994,8 @@
mRequestProcRank = false;
}
if (mRequestAnrTraces) {
- reportAnrTraces();
mRequestAnrTraces = false;
+ shouldReportAnrTraces = true;
}
if (mRequestAnrBugreport){
getBugreport("anr_" + mReportProcessName + "_");
@@ -1003,8 +1006,8 @@
mRequestAnrBugreport = false;
}
if (mRequestDumpsysMemInfo) {
- reportDumpsysMemInfo();
mRequestDumpsysMemInfo = false;
+ shouldReportDumpsysMemInfo = true;
}
if (mMonitorNativeCrashes) {
// first time through, when eventCounter == 0, just set up
@@ -1018,12 +1021,29 @@
}
}
if (mAbort) {
- System.out.println("** Monkey aborted due to error.");
- System.out.println("Events injected: " + eventCounter);
- return eventCounter;
+ shouldAbort = true;
}
}
+ // Report ANR, dumpsys after releasing lock on this.
+ // This ensures the availability of the lock to Activity controller's appNotResponding
+ if (shouldReportAnrTraces) {
+ shouldReportAnrTraces = false;
+ reportAnrTraces();
+ }
+
+ if (shouldReportDumpsysMemInfo) {
+ shouldReportDumpsysMemInfo = false;
+ reportDumpsysMemInfo();
+ }
+
+ if (shouldAbort) {
+ shouldAbort = false;
+ System.out.println("** Monkey aborted due to error.");
+ System.out.println("Events injected: " + eventCounter);
+ return eventCounter;
+ }
+
// In this debugging mode, we never send any events. This is
// primarily here so you can manually test the package or category
// limits, while manually exercising the system.
diff --git a/docs/howto_SDK_git_cygwin.txt b/docs/howto_SDK_git_cygwin.txt
deleted file mode 100644
index 622c592..0000000
--- a/docs/howto_SDK_git_cygwin.txt
+++ /dev/null
@@ -1,189 +0,0 @@
-Copyright (C) 2009 The Android Open Source Project
-
-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.
-
-
-Subject: How to get the android source code using Cygwin and Git
-Date: 2009/04/27
-Updated: 2009/05/21
-Updated: 2010/03/30
-
-
-Table of content:
- 1- Goals and Requirements
- 2- Getting the code, the simple way
- 3- SSH issues
- 4- Advanced Tricks
-
-
--------------------------
-1- Goals and Requirements
--------------------------
-
-This document explains how to checkout the Android source from the git
-repositories under Windows.
-
-As stated in development/docs/howto_build_SDK.txt, one can't build the whole
-Android source code under Windows. You can only build the SDK tools for
-Windows.
-
-There are a number of caveats in checking out the code from Git under Windows.
-This document tries to explain them.
-
-First you will need to meet the following requirements:
-- You must have Cygwin installed. But wait! You CANNOT use the latest Cygwin 1.7.
- Instead you MUST use the "legacy Cygwin 1.5" that you can find at this page:
-
- http://cygwin.org/win-9x.html
-
- Don't mind the page title, just grab setup-legacy.exe and it will works just fine
- under XP or Vista.
-
-- You must install Cyginw using the "Unix / Binary" mode.
- If you don't do that, git will fail to properly compute some SHA1 keys.
-
-- You need the "git" and "curl" packages to checkout the code.
- If you plan to contribute, you might want to get "gitk" also.
-
- Note: if you want to build the SDK, check the howto_build_SDK.txt file
- for a list of extra required packages.
- The short summary is that you need at least these:
- autoconf, bison, curl, flex, gcc, g++, git, gnupg, make, mingw-zlib, python, unzip, zip
- and you must avoid the "readline" package.
-
-
------------------------------------
-2- Getting the code, the simple way
------------------------------------
-
-Out of the box, "repo" and "git" will work just fine under Cygwin:
-
- $ repo init -u git://android.git.kernel.org/platform/manifest.git
- $ repo sync
-
-And you're done. You can build as explained in howto_build_SDK.txt and ignore
-the rest of this document.
-
-
--------------
-3- SSH issues
--------------
-
-If you maintain your own private repository using an SSH server, you might get
-some "mux/ssh" errors. In this case try this:
-
- $ repo init -u ssh://my.private.ssh.repo/platform/manifest.git
- $ export GIT_SSH=ssh
- $ repo sync
-
-
-------------------
-4- Advanced Tricks
-------------------
-
-There is one remaining issue with the default repo/git options:
-
-If you plan on contributing, you will notice that even after a fresh "repo
-sync" some projects are marked as having modified files. This happens on the
-"bionic" and the "external/iptables" project. The issue is that they have files
-which have the same name yet differ only by their case-sensitivity. Since the
-Windows filesystem is not case-sensitive, this confuses Git.
-
-Solution: we can simply ignore these projects as they are not needed to build
-the Windows SDK.
-
-To do this you just need to create a file .repo/local_manifest.xml that
-provides a list of projects to ignore:
-
-<?xml version="1.0" encoding="UTF-8"?>
-<manifest>
- <remove-project name="platform/external/iptables" />
-</manifest>
-
-The other thing we can do is tell git not to track the files that cause
-problems:
-
- cd bionic
- git update-index --assume-unchanged \
- libc/kernel/common/linux/netfilter/xt_CONNMARK.h \
- libc/kernel/common/linux/netfilter/xt_MARK.h \
- libc/kernel/common/linux/netfilter_ipv6/ip6t_HL.h
-
- cd external/tcpdump;
- git update-index --assume-unchanged \
- tests/print-X.new \
- tests/print-XX.new
-
-
-Here's a script that takes care of all these details. It performs the repo
-init, creates the appropriate local_manifest.xml, does a repo sync as
-needed and tell git to ignore the offending files:
-
-------------
-#!/bin/bash
-
-set -e # fail on errors
-
-URL=ssh://android-git.corp.google.com:29418/platform/manifest.git
-BRANCH=donut
-if [ "$1" == "-b" ]; then shift; BRANCH=$1; shift; fi
-
-# repo init if there's no .repo directory
-if [[ ! -d .repo ]]; then
- repo init -u $URL -b $BRANCH
-fi
-
-# create a local_manifest to exclude projects that cause problems under Windows
-# due to the case-insenstivines of the file system.
-L=.repo/local_manifest.xml
-if [[ ! -f $L ]]; then
-
- cat > $L <<EOF
-<?xml version="1.0" encoding="UTF-8"?>
-<manifest>
-<remove-project name="platform/external/iptables" />
-</manifest>
-EOF
-fi
-
-# sync using the native ssh client if necessary
-[[ $URL != ${URL/ssh/} ]] && export GIT_SSH=ssh
-repo sync $@
-
-
-# These files cause trouble too, we need to ignore them
-(cd bionic;
-git update-index --assume-unchanged \
- libc/kernel/common/linux/netfilter/xt_CONNMARK.h \
- libc/kernel/common/linux/netfilter/xt_MARK.h \
- libc/kernel/common/linux/netfilter_ipv6/ip6t_HL.h
-)
-(cd external/tcpdump;
-git update-index --assume-unchanged \
- tests/print-X.new \
- tests/print-XX.new
-)
-------------
-
-Simply extract this to a "my_sync.sh" file and try the following:
- $ mkdir android_src
- $ cd android_src
- $ chmod +x mysync.sh
- $ ./mysync.sh
-
-
--end-
-
-
-
-
diff --git a/docs/howto_build_SDK.txt b/docs/howto_build_SDK.txt
deleted file mode 100644
index e09440b..0000000
--- a/docs/howto_build_SDK.txt
+++ /dev/null
@@ -1,305 +0,0 @@
-Copyright (C) 2009 The Android Open Source Project
-
-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.
-
-
-Subject: How to build an Android SDK & ADT Eclipse plugin.
-Date: 2009/03/27
-Updated: 2010/03/30
-
-
-Table of content:
- 0- License
- 1- Foreword
- 2- Building an SDK for MacOS and Linux
- 3- Building an SDK for Windows
- 4- Building an ADT plugin for Eclipse
- 5- Conclusion
-
-
-
-----------
-0- License
-----------
-
- Copyright (C) 2009 The Android Open Source Project
-
- 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.
-
-
-
------------
-1- Foreword
------------
-
-This document explains how to build the Android SDK and the ADT Eclipse plugin.
-
-It is designed for advanced users which are proficient with command-line
-operations and know how to setup the pre-required software.
-
-Basically it's not trivial yet when done right it's not that complicated.
-
-
-
---------------------------------------
-2- Building an SDK for MacOS and Linux
---------------------------------------
-
-First, setup your development environment and get the Android source code from
-git as explained here:
-
- http://source.android.com/download
-
-For example for the cupcake branch:
-
- $ mkdir ~/my-android-git
- $ cd ~/my-android-git
- $ repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake
- $ repo sync
-
-Then once you have all the source, simply build the SDK using:
-
- $ cd ~/my-android-git
- $ . build/envsetup.sh
- $ lunch sdk-eng
- $ make sdk
-
-This will take a while, maybe between 20 minutes and several hours depending on
-your machine. After a while you'll see this in the output:
-
- Package SDK: out/host/darwin-x86/sdk/android-sdk_eng.<build-id>_mac-x86.zip
-
-Some options:
-
-- Depending on your machine you can tell 'make' to build more things in
- parallel, e.g. if you have a dual core, use "make -j4 sdk" to build faster.
-
-- You can define "BUILD_NUMBER" to control the build identifier that gets
- incorporated in the resulting archive. The default is to use your username.
- One suggestion is to include the date, e.g.:
-
- $ export BUILD_NUMBER=${USER}-`date +%Y%m%d-%H%M%S`
-
- There are certain characters you should avoid in the build number, typically
- everything that might confuse 'make' or your shell. So for example avoid
- punctuation and characters like $ & : / \ < > , and .
-
-
-
-------------------------------
-3- Building an SDK for Windows
-------------------------------
-
-A- SDK pre-requisite
---------------------
-
-First you need to build an SDK for MacOS and Linux. The Windows build works by
-updating an existing MacOS or Linux SDK zip file and replacing the unix
-binaries by Windows binaries.
-
-
-
-B- Cygwin pre-requisite & code checkout
----------------------------------------
-
-You must have Cygwin installed. But wait! You CANNOT use the latest Cygwin 1.7.
-Instead you MUST use the "legacy Cygwin 1.5" that you can find at this page:
-
- http://cygwin.org/win-9x.html
-
-Don't mind the page title, just grab setup-legacy.exe and it will works just fine
-under XP or Vista.
-
-
-Now configure it:
-- When installing Cygwin, set Default Text File Type to Unix/binary, not DOS/text.
- This is really important, otherwise you will get errors when trying to
- checkout code using git.
-- Packages that you must install or not:
- - Required packages: autoconf, bison, curl, flex, gcc, g++, git, gnupg, make,
- mingw-zlib, python, zip, unzip.
- - Suggested extra packages: diffutils, emacs, openssh, rsync, vim, wget.
- - Packages that must not be installed: readline.
-
-Once you installed Cygwin properly, checkout the code from git as you did
-for MacOS or Linux. Make sure to get the same branch, and if possible keep
-it as close to the other one as possible:
-
- $ mkdir ~/my-android-git
- $ cd ~/my-android-git
- $ repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake
- $ repo sync
-
-
-
-C- Building the Windows SDK
----------------------------
-
-Now it's time to build that Windows SDK. You need:
-- The path to the MacOS or Linux SDK zip.
-- A directory where to place the final SDK. It will also hold some temporary
- files.
-- The build number will be extracted from the SDK zip filename, but this will
- only work if that build number has no underscores in it. It is suggested you
- just define SDK_NUMBER (and not BUILD_NUMBER!) on the command line before
- invoking the script.
-
- Note that the "SDK number" is really a free identifier of your choice. It
- doesn't need to be strictly a number. As always it is suggested you avoid
- too much punctuation and special shell/make characters. Underscores cannot
- be used.
-
-
-To summarize, the steps on the command line would be something like this:
-
- $ mkdir ~/mysdk
- $ export SDK_NUMBER=${USER}-`date +%Y%m%d-%H%M%S`
- $ cd ~/my-android-git
- $ development/build/tools/make_windows_sdk.sh /path/to/macos/or/linux/sdk.zip ~/mysdk
-
-This will take a while to build some Windows-specific binaries, including the
-emulator, unzip the previous zip, rename & replace things and rezip the final
-Windows SDK zip file. A typical build time should be around 5-10 minutes.
-
-
-
--------------------------------------
-4- Building an ADT plugin for Eclipse
--------------------------------------
-
-Requirements:
-- You can currently only build an ADT plugin for Eclipse under Linux.
-- You must have a working version of Eclipse 3.4 "ganymede" RCP installed.
-- You need X11 to run Eclipse at least once.
-- You need a lot of patience. The trick is to do the initial setup correctly
- once, after it's a piece of cake.
-
-
-
-A- Pre-requisites
------------------
-
-Note for Ubuntu or Debian users: your apt repository probably only has Eclipse
-3.2 available and it's probably not suitable to build plugins in the first
-place. Forget that and install a working 3.4 manually as described below.
-
-- Visit http://www.eclipse.org/downloads/ to grab the
- "Eclipse for RCP/Plug-in Developers (176 MB)" download for Linux.
- 32-bit and 64-bit versions are available, depending on your Linux installation.
-
- Note: we've always used a 32-bit one, so use the 64-bit one at your own risk.
-
- Note: Eclipse comes in various editions. Do yourself a favor and just stick
- to the RCP for building this plugin. For example the J2EE contains too many
- useless features that will get in the way, and the "Java" version lacks some
- plugins you need to build other plugins. Please just use the RCP one.
-
-- Unpack "eclipse-rcp-ganymede-SR2-linux-gtk.tar.gz" in the directory of
- your choice, e.g.:
-
- $ mkdir ~/eclipse-3.4
- $ cd ~/eclipse-3.4
- $ tar xvzf eclipse-rcp-ganymede-SR2-linux-gtk.tar.gz
-
- This will create an "eclipse" directory in the current directory.
-
-- Set ECLIPSE_HOME to that "eclipse" directory:
-
- $ export ECLIPSE_HOME=~/eclipse-3.4/eclipse
-
- Note: it is important you set ECLIPSE_HOME before starting the build.
- Otherwise the build process will try to download and install its own Eclipse
- installation in /buildroot, which is probably limited to root.
-
-- Now, before you can build anything, it is important that you start Eclipse
- *manually* once using the same user that you will use to build later. That's
- because your Eclipse installation is not finished: Eclipse must be run at
- least once to create some files in ~/.eclipse/. So run Eclipse now:
-
- $ ~/eclipse-3.4/eclipse/eclipse &
-
- Wait for it load, create a workspace when requested and then simply quit
- using the File > Quit menu. That's it. You won't need to run it manually
- again.
-
-
-
-B- Building ADT
----------------
-
-Finally, you have Eclipse, it's installed and it created its own config files,
-so now you can build your ADT plugin. To do that you'll change directories to
-your git repository and invoke the build script by giving it a destination
-directory and an optional build number:
-
- $ mkdir ~/mysdk
- $ cd ~/my-android-git # <-- this is where you did your "repo sync"
- $ development/tools/eclipse/scripts/build_server.sh ~/mysdk $USER
-
-The first argument is the destination directory. It must be absolute. Do not
-give a relative destination directory such as "../mysdk". This will make the
-Eclipse build fail with a cryptic message:
-
- BUILD SUCCESSFUL
- Total time: 1 minute 5 seconds
- **** Package in ../mysdk
- Error: Build failed to produce ../mysdk/android-eclipse
- Aborting
-
-The second argument is the build "number". The example used "$USER" but it
-really is a free identifier of your choice. It cannot contain spaces nor
-periods (dashes are ok.) If the build number is missing, a build timestamp will
-be used instead in the filename.
-
-The build should take something like 5-10 minutes.
-
-
-When the build succeeds, you'll see something like this at the end of the
-output:
-
- ZIP of Update site available at ~/mysdk/android-eclipse-v200903272328.zip
-or
- ZIP of Update site available at ~/mysdk/android-eclipse-<buildnumber>.zip
-
-When you load the plugin in Eclipse, its feature and plugin name will look like
-"com.android.ide.eclipse.adt_0.9.0.v200903272328-<buildnumber>.jar". The
-internal plugin ID is always composed of the package, the build timestamp and
-then your own build identifier (a.k.a. the "build number"), if provided. This
-means successive builds with the same build identifier are incremental and
-Eclipse will know how to update to more recent ones.
-
-
-
--------------
-5- Conclusion
--------------
-
-This completes the howto guide on building your own SDK and ADT plugin.
-Feedback is welcome on the public Android Open Source forums:
- http://source.android.com/discuss
-
-If you are upgrading from a pre-cupcake to a cupcake or later SDK please read
-the accompanying document "howto_use_cupcake_sdk.txt".
-
--end-
-
diff --git a/docs/howto_use_cupcake_sdk.txt b/docs/howto_use_cupcake_sdk.txt
deleted file mode 100644
index b131230..0000000
--- a/docs/howto_use_cupcake_sdk.txt
+++ /dev/null
@@ -1,371 +0,0 @@
-Subject: How to build use a Cupcake Android SDK & ADT Eclipse plugin.
-Date: 2009/03/27
-
-
-Table of content:
- 0- License
- 1- Foreword
- 2- Installation steps
- 3- For Eclipse users
- 4- For Ant users
- 5- Targets, AVDs, Emulator changes
- 6- Conclusion
-
-
-
-----------
-0- License
-----------
-
- Copyright (C) 2009 The Android Open Source Project
-
- 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.
-
-
-
------------
-1- Foreword
------------
-
-This explains how to use the "new" SDK provided starting with cupcake.
-The new SDK has as a different structure than the pre-cupcake ones.
-
-This means:
-- The new SDK does not work with older Eclipse plugins (ADT 0.8)
-- The old SDKs (1.0 and 1.1) do NOT work with this Eclipse plugin (ADT 0.9)
-
-
-
-----------------------
-2- Installation steps
-----------------------
-
-First you will need to grab the zip of the SDK for your platform or build it
-yourself. Please refer to the accompanying document "howto_build_SDK.txt" if
-needed.
-
-Unzip the SDK somewhere. We'll call that directory "SDK" in command-line
-examples.
-
-Grab the new ADT Eclipse plugin zip file or build it yourself. Keep it
-somewhere (no need to unzip).
-
-
-
---------------------
-3- For Eclipse users
---------------------
-
-
-Below we'll explain how you can upgrade your Eclipse install to the new plugin.
-If you already have a working Eclipse installation with a pre-0.9 ADT,
-another suggestion is to simply install a new copy of Eclipse and create a
-new empty workspace. This is just a precaution. The update process should
-be otherwise harmless.
-
-
-
-A- Setting up Eclipse
----------------------
-
-- You must have Eclipse 3.3 or 3.4. Eclipse 3.2 is not longer supported.
-
- There are many flavors, or "editions", of Eclipse. To develop, we'd recommend
- the "Java" edition. The "RCP" one is totally suitable too. The J2EE one is
- probably overkill.
-
-
-- If updating an existing Eclipse, use Help > Software Update and please
- uninstall the two features of the previous ADT: the "editors" feature and the
- ADT feature itself.
-
- => If you don't you will get a conflict on editors when installing
- the new one.
-
-- Using Help > Software Update, add a new "archived site", point it to the new
- adt.zip (e.g. android-eclipse-<some-id>.zip), select the "Install" button at
- the top right and restart eclipse as needed.
-
-- After it restarts, please use Window > Preferences > Android and select
- the new SDK folder that you unzipped in paragraph 2.
-
-
-
-B- Updating older projects
---------------------------
-
-If you have pre-0.9 projects in your Eclipse workspace, or if you import them
-from your code repository, these projects will fail to build at first.
-
-First right-click on the project and select "Properties":
-
-- In the properties, open the Android panel and select the platform to use.
- The SDK comes with a 1.5 platform. Select it and close the properties panel.
-- Do a clean build.
-
-
-The new plugin creates a "gen" folder in your project where it puts the R.java
-and all automatically generated AIDL java files. If you get an error such as:
-
- "The type R is already defined"
-
-that means you must check to see if your old R.java or your old auto-generated
-AIDL Java files are still present in the "src" folder. If yes, remove them.
-
-Note: this does not apply to your own hand-crafted parcelable AIDL java files.
-
-Note: if you want to reuse the project with an older Eclipse ADT install,
- simply remove the "gen" folder from the build path of the project.
-
-
-C- New Wizards
---------------
-
-The "New Android Project" wizard has been expanded to use the multi-platform
-capabilities of the new SDK.
-
-There is now a "New XML File" wizard that lets you create skeleton XML resource
-files for your Android projects. This makes it easier to create a new layout, a
-new strings file, etc.
-
-Both wizard are available via File > New... as well as new icons in the main
-icon bar. If you do not see the new icons, you may need to use Window > Reset
-Perspective on your Java perspective.
-
-
-Please see step 5 "Emulator changes" below for important details on how to run
-the emulator.
-
-
-
-----------------
-4- For Ant users
-----------------
-
-
-A- build.xml has changed
-------------------------
-
-You must re-create your build.xml file.
-
-First if you had customized your build.xml, make a copy of it:
-
- $ cd my-project
- $ cp build.xml build.xml.old
-
-
-Then use the new "android" tool to create a new build.xml:
-
- $ SDK/tools/android update project --path /path/to/my-project
-
-or
-
- $ cd my-project
- $ SDK/tools/android update project --path .
-
-
-A "gen" folder will be created the first time you build and your R.java and
-your AIDL Java files will be generated in this "gen" folder. You MUST remove
-the old R.java and old auto-generated AIDL java files manually. (Note: this
-does not apply to your own hand-crafted parcelabe AIDL java files.)
-
-
-B- Where is activitycreator?
-----------------------------
-
-Note that the "activitycreator" tool has been replaced by the new "android"
-tool too. Example of how to create a new Ant project:
-
- $ SDK/tools/android create project --path /path/to/my/project --name ProjectName
- --package com.mycompany.myapp --activity MyActivityClass
- --target 1 --mode activity
-
-
-Please see paragraph 5 below for important details on how to run the emulator
-and the meaning of that "--target 1" parameter.
-
-
-
-----------------------------------
-5- Targets, AVDs, Emulator changes
-----------------------------------
-
-This applies to BOTH Eclipse and Ant users.
-
-One major change with the emulator is that now you must pre-create an "Android
-Virtual Device" (a.k.a "AVD") before you run the emulator.
-
-
-
-A- What is an AVD and why do I need one?
-----------------------------------------
-
-What is an "AVD"? If you forget, just run:
-
- $ SDK/tools/emulator -help-virtual-device
-
- An Android Virtual Device (AVD) models a single virtual device running the
- Android platform that has, at least, its own kernel, system image and data
- partition.
-
-There is a lot more explanation given by the emulator. Please run the help
-command given above to read the rest.
-
-The bottom line is that you can create many emulator configurations, or "AVDs",
-each with their own system image and most important each with their own user
-data and SD card data. Then you tell Eclipse or the emulator which one to use
-to debug or run your applications.
-
-
-Note for Eclipse users: eventually there will be a user interface to do all of
-these operations. For right now, please use the command line interface.
-
-
-B- Listing targets and AVDs
----------------------------
-
-There is a new tool called "android" in the SDK that lets you know which
-"target" and AVDs you can use.
-
-A target is a specific version of Android that you can use. By default the SDK
-comes with an "Android 1.5" target, codenamed "cupcake". In the future there
-will be more versions of Android to use, e.g. "Android 2.0" or specific add-ons
-provided by hardware manufacturers. When you want to run an emulator, you need
-to specify a given flavor of Android: this is the "target".
-
-
-To learn about available targets in your SDK, use this command:
-
- $ SDK/tools/android list targets
-
-This will give you an output such as:
-
- Available Android targets:
- [1] Android 1.5
- API level: 3
- Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
-
-Note the "[1]". Later you will need to reference this as "--target 1" on the
-command line.
-
-
-Similarly you can list the available AVDs:
-
- $ SDK/tools/android list avds
-
-Which might output something as:
-
- Available Android Virtual Devices:
- Name: my_avd
- Path: C:\Users\<username>\.android\avd\my_avd.avd
- Target: Android 1.5 (API level 3)
- Skin: 320x480
- Sdcard: 16M
-
-
-
-C- Creating an AVD
-------------------
-
-To create a configuration:
-
- $ SDK/tools/android create avd --name my_avd_name --target 1
-
-
-where "target 1" is the index of a target listed by "android list targets".
-
-The AVD name is purely an identifier used to refer to the AVD later.
-Since it is used as directory name, please avoid using shell or path specific
-characters.
-
-To learn the various options available when creating an AVD, simply type:
-
- $ SDK/tools/android create avd
-
-The android tool will automatically print an explanation of required arguments.
-
-
-
-D- Invoking an AVD from the command-line
-----------------------------------------
-
-To use this AVD in the emulator from the command-line, type:
-
- $ SDK/tools/emulator @my_avd_name
-
-
-For more options, please consult the emulator help:
-
- $ SDK/tools/emulator -help-virtual-device
-
-
-
-E- Invoking an AVD from Eclipse
--------------------------------
-
-By default Android projects in Eclipse have an "automatic target" mode.
-In this mode, when a project is deployed in debug or run, it checks:
-- If there's one running device or emulator, this is used for deployment.
-- If there's more than one running device or emulator, a "device chooser" is
- shown to let the user select which one to use.
-- If there are no running devices or emulators, ADT looks at available AVDs.
- If one matches the project configuration (e.g. same API level), it is
- automatically used.
-
-Alternatively you can edit the "launch configuration" on your Android project
-in Eclipse by selecting the menu Run > Run Configurations. In the "target" tab
-of the configuration, you can choose:
-
-- Manual or automatic targetting mode.
-
- - Manual means to always present the device chooser.
- - Automatic is the behavior explained above.
-
-- In automatic mode, which AVD is preferred. If none is selected, the first
- suitable is used.
-
-
-F- AVD concurrency
-------------------
-
-You can no longer run several emulators at the same time on the same
-configuration.
-
-Before this used to put the second or more emulators in a transient read-only
-mode that would not save user data.
-
-Now you just need to create as many AVDs as you want to run emulators.
-
-For example if you are working on a client/server application for Android, you
-could create a "client" AVD and a "server" AVD then run them both at once. The
-emulator window will show you the AVD name so that you know which one is which.
-
-Example:
-
- $ SDK/tools/android create avd --name client --target 1 --sdcard 16M --skin HVGA
- $ SDK/tools/android create avd --name server --target 1 --sdcard 32M --skin HVGA-P
- $ SDK/tools/emulator @server &
- $ SDK/tools/emulator @client &
-
-
-
--------------
-6- Conclusion
--------------
-
-This completes the howto guide on how to use the new Cupcake SDK.
-Feedback is welcome on the public Android Open Source forums:
- http://source.android.com/discuss
-
--end-
-
diff --git a/host/windows/usb/android_winusb.inf b/host/windows/usb/android_winusb.inf
index b2daf89..47cf2f7 100755
--- a/host/windows/usb/android_winusb.inf
+++ b/host/windows/usb/android_winusb.inf
@@ -6,7 +6,7 @@
Class = AndroidUsbDeviceClass
ClassGuid = {3F966BD9-FA04-4ec5-991C-D326973B5128}
Provider = %ProviderName%
-DriverVer = 08/11/2009,2.0.0010.00002
+DriverVer = 12/06/2010,4.0.0000.00000
CatalogFile.NTx86 = androidwinusb86.cat
CatalogFile.NTamd64 = androidwinusba64.cat
@@ -38,14 +38,11 @@
%CompositeAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB&MI_01
;
;Google NexusOne
-%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02
+%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02&MI_01
-%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_4E11
-%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01
+%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_4E11
+%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E22&MI_01
-;
-; Dell's Mini5
-%CompositeAdbInterface% = USB_Install, USB\VID_413C&PID_B007&MI_01
[Google.NTamd64]
; HTC Dream
@@ -61,13 +58,10 @@
;
;Google NexusOne
%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02
-%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02&MI_01
+%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02&MI_01
%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_4E11
-%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01
+%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E22&MI_01
-;
-; Dell's Mini5
-%CompositeAdbInterface% = USB_Install, USB\VID_413C&PID_B007&MI_01
[USB_Install]
Include = winusb.inf
@@ -88,7 +82,7 @@
KmdfService = WINUSB, WinUSB_Install
[WinUSB_Install]
-KmdfLibraryVersion = 1.7
+KmdfLibraryVersion = 1.9
[USB_Install.HW]
AddReg = Dev_AddReg
@@ -101,11 +95,11 @@
CopyFiles = CoInstallers_CopyFiles
[CoInstallers_AddReg]
-HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01007.dll,WdfCoInstaller","WinUSBCoInstaller.dll"
+HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01009.dll,WdfCoInstaller","WinUSBCoInstaller2.dll"
[CoInstallers_CopyFiles]
-WinUSBCoInstaller.dll
-WdfCoInstaller01007.dll
+WinUSBCoInstaller2.dll
+WdfCoInstaller01009.dll
[DestinationDirs]
CoInstallers_CopyFiles=11
@@ -115,12 +109,12 @@
2 = %DISK_NAME%,,,\amd64
[SourceDisksFiles.x86]
-WinUSBCoInstaller.dll = 1
-WdfCoInstaller01007.dll = 1
+WinUSBCoInstaller2.dll = 1
+WdfCoInstaller01009.dll = 1
[SourceDisksFiles.amd64]
-WinUSBCoInstaller.dll = 2
-WdfCoInstaller01007.dll = 2
+WinUSBCoInstaller2.dll = 2
+WdfCoInstaller01009.dll = 2
[Strings]
ProviderName = "Google, Inc."
diff --git a/host/windows/usb/legacy/driver/android_usb.inf b/host/windows/usb/legacy/driver/android_usb.inf
deleted file mode 100755
index f8bbf9a..0000000
--- a/host/windows/usb/legacy/driver/android_usb.inf
+++ /dev/null
@@ -1,130 +0,0 @@
-;/*++
-;
-;Abstract:
-; Installation inf for the Android USB Bulk device
-;
-;--*/
-
-[Version]
-Signature="$WINDOWS NT$"
-Class=USB
-ClassGuid={F72FE0D4-CBCB-407d-8814-9ED673D0DD6B}
-Provider=%GOOG%
-DriverVer=06/25/2009,1.0.0010.00001
-CatalogFile.NTx86=androidusb86.cat
-CatalogFile.NTamd64=androidusba64.cat
-
-; ================= Class section =====================
-
-[ClassInstall32]
-Addreg=AndroidUsbClassReg
-
-[AndroidUsbClassReg]
-HKR,,,0,%ClassName%
-HKR,,Icon,,-5
-
-[DestinationDirs]
-DefaultDestDir = 12
-
-; ================= Device section =====================
-
-[Manufacturer]
-%MfgName%=Google,NTx86,NTamd64
-
-; For Win2K
-[Google]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0C03&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C03&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For XP and later
-[Google.NTx86]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0C03&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C03&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For AMD64 and later
-[Google.NTamd64]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0C03&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C03&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-[androidusb.Dev.NT]
-CopyFiles=androidusb.Files.Ext
-
-[androidusb.Dev.NT.Services]
-Addservice = androidusb, 0x00000002, androidusb.AddService
-
-[androidusb.AddService]
-DisplayName = %androidusb.SvcDesc%
-ServiceType = 1 ; SERVICE_KERNEL_DRIVER
-StartType = 3 ; SERVICE_DEMAND_START
-ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %10%\System32\Drivers\androidusb.sys
-AddReg = androidusb.AddReg
-LoadOrderGroup = Base
-
-[androidusb.AddReg]
-HKR,"Parameters","MaximumTransferSize",0x10001,4096
-HKR,"Parameters","DebugLevel",0x10001,2
-HKR, Parameters\Wdf, VerboseOn, 0x00010001, 1
-HKR, Parameters\Wdf, VerifierOn, 0x00010001, 1
-HKR, Parameters\Wdf, DbgBreakOnError, 0x00010001, 1
-
-[androidusb.Files.Ext]
-androidusb.sys
-
-[SourceDisksNames]
-1=%Disk_Description%,,,
-
-[SourceDisksFiles]
-androidusb.sys = 1
-
-;-------------- WDF Coinstaller installation
-[DestinationDirs]
-CoInstaller_CopyFiles = 11
-
-[androidusb.Dev.NT.CoInstallers]
-AddReg=CoInstaller_AddReg
-CopyFiles=CoInstaller_CopyFiles
-
-[CoInstaller_CopyFiles]
-wdfcoinstaller01005.dll
-
-[SourceDisksFiles]
-wdfcoinstaller01005.dll=1 ; make sure the number matches with SourceDisksNames
-
-[CoInstaller_AddReg]
-HKR,,CoInstallers32,0x00010000, "wdfcoinstaller01005.dll,WdfCoInstaller"
-
-[androidusb.Dev.NT.Wdf]
-KmdfService = androidusb, androidusb_wdfsect
-
-[androidusb_wdfsect]
-KmdfLibraryVersion = 1.5
-
-;---------------------------------------------------------------;
-
-[Strings]
-GOOG = "Google, Inc"
-MfgName = "Google, Inc"
-Disk_Description= "ADB Interface Installation Disk"
-androidusb.SvcDesc = "ADB Interface Driver"
-ClassName = "ADB Interface"
-USB\VID_18D1&PID_DDDD.DeviceDescTest="ADB Testing Interface"
-USB\VID_0BB4&PID_0C01.DeviceDescRelease="HTC Dream"
-USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease="HTC Dream Composite ADB Interface"
-USB\VID_0BB4&PID_0C03&MI_01.DeviceDescRelease="HTC Magic Composite ADB Interface"
-USB\VID_0BB4&PID_0FFF.DeviceDescRelease="HTC Bootloader"
diff --git a/host/windows/usb/legacy/driver/android_usb.rc b/host/windows/usb/legacy/driver/android_usb.rc
deleted file mode 100755
index 0e7571e..0000000
--- a/host/windows/usb/legacy/driver/android_usb.rc
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * 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.
- */
-
-#include <windows.h>
-
-// Don't let the resource editor in here
-#ifdef APSTUDIO_INVOKED
- #error this file is not editable by Visual C++
-#endif //APSTUDIO_INVOKED
-
-
-#define VER_FILETYPE VFT_DRV
-#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
-#define VER_FILEDESCRIPTION_STR "ADB Interface"
-#define VER_INTERNALNAME_STR "androidusb.sys"
-#define VER_ORIGINALFILENAME_STR "androidusb.sys"
-#define VER_FILEOS VOS_NT
-#define VER_FILEFLAGSMASK (VS_FF_DEBUG | VS_FF_PRERELEASE)
-
-#if DBG
- #define VER_FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE
-#else // DBG
- #define VER_FILEFLAGS VS_FF_PRERELEASE
-#endif // DBG
-
-#include "common.ver"
diff --git a/host/windows/usb/legacy/driver/android_usb_bulk_file_object.cpp b/host/windows/usb/legacy/driver/android_usb_bulk_file_object.cpp
deleted file mode 100755
index 9f8ac6b..0000000
--- a/host/windows/usb/legacy/driver/android_usb_bulk_file_object.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbBulkPipeFileObject
- that encapsulates extension to a bulk pipe file objects.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_bulk_file_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbBulkPipeFileObject::AndroidUsbBulkPipeFileObject(
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj)
- : AndroidUsbPipeFileObject(dev_obj, wdf_fo, wdf_pipe_obj) {
- ASSERT_IRQL_PASSIVE();
-
-#if DBG
- WDF_USB_PIPE_INFORMATION pipe_info;
- WDF_USB_PIPE_INFORMATION_INIT(&pipe_info);
- WdfUsbTargetPipeGetInformation(wdf_pipe_obj, &pipe_info);
- ASSERT(WdfUsbPipeTypeBulk == pipe_info.PipeType);
-#endif // DBG
-}
-
-#pragma code_seg()
-
-AndroidUsbBulkPipeFileObject::~AndroidUsbBulkPipeFileObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_bulk_file_object.h b/host/windows/usb/legacy/driver/android_usb_bulk_file_object.h
deleted file mode 100755
index f563daa..0000000
--- a/host/windows/usb/legacy/driver/android_usb_bulk_file_object.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_BULK_PIPE_FILE_OBJECT_H__
-#define ANDROID_USB_BULK_PIPE_FILE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbBulkPipeFileObject
- that encapsulates extension to a bulk pipe file objects.
-*/
-
-#include "android_usb_pipe_file_object.h"
-
-/** AndroidUsbBulkPipeFileObject class encapsulates extension to a KMDF file
- object that represent opened bulk pipe. Instances of this class must be
- allocated from NonPagedPool.
-*/
-class AndroidUsbBulkPipeFileObject : public AndroidUsbPipeFileObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- @param dev_obj[in] Our device object for which this file has been created
- @param wdf_fo[in] KMDF file object this extension wraps
- @param wdf_pipe_obj[in] KMDF pipe for this file
- */
- AndroidUsbBulkPipeFileObject(AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbBulkPipeFileObject();
-};
-
-#endif // ANDROID_USB_BULK_PIPE_FILE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_device_file_object.cpp b/host/windows/usb/legacy/driver/android_usb_device_file_object.cpp
deleted file mode 100755
index a5e764e..0000000
--- a/host/windows/usb/legacy/driver/android_usb_device_file_object.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbDeviceFileObject
- that encapsulates an extension for a KMDF file object that represent
- opened device.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_device_file_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbDeviceFileObject::AndroidUsbDeviceFileObject(
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo)
- : AndroidUsbFileObject(AndroidUsbFileObjectTypeDevice, dev_obj, wdf_fo) {
- ASSERT_IRQL_PASSIVE();
-}
-
-#pragma code_seg()
-
-AndroidUsbDeviceFileObject::~AndroidUsbDeviceFileObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-void AndroidUsbDeviceFileObject::OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- switch (ioctl_code) {
- case ADB_IOCTL_GET_USB_DEVICE_DESCRIPTOR:
- device_object()->OnGetUsbDeviceDescriptorCtl(request, output_buf_len);
- break;
-
- case ADB_IOCTL_GET_USB_CONFIGURATION_DESCRIPTOR:
- device_object()->OnGetUsbConfigDescriptorCtl(request, output_buf_len);
- break;
-
- case ADB_IOCTL_GET_USB_INTERFACE_DESCRIPTOR:
- device_object()->OnGetUsbInterfaceDescriptorCtl(request, output_buf_len);
- break;
-
- case ADB_IOCTL_GET_ENDPOINT_INFORMATION:
- device_object()->OnGetEndpointInformationCtl(request,
- input_buf_len,
- output_buf_len);
- break;
-
- case ADB_IOCTL_GET_SERIAL_NUMBER:
- device_object()->OnGetSerialNumberCtl(request, output_buf_len);
- break;
-
- default:
- AndroidUsbFileObject::OnEvtIoDeviceControl(request,
- output_buf_len,
- input_buf_len,
- ioctl_code);
- break;
- }
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_device_file_object.h b/host/windows/usb/legacy/driver/android_usb_device_file_object.h
deleted file mode 100755
index 6deed6c..0000000
--- a/host/windows/usb/legacy/driver/android_usb_device_file_object.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_DEVICE_FILE_OBJECT_H__
-#define ANDROID_USB_DEVICE_FILE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbDeviceFileObject that
- encapsulates an extension for a KMDF file object that represent opened
- device.
-*/
-
-#include "android_usb_file_object.h"
-
-/** AndroidUsbDeviceFileObject class encapsulates an extension for a KMDF
- file object that represent opened device. Instances of this class must be
- allocated from NonPagedPool.
-*/
-class AndroidUsbDeviceFileObject : public AndroidUsbFileObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- @param dev_obj[in] Our device object for which this file has been created
- @param wdf_fo[in] KMDF file object this extension wraps
- */
- AndroidUsbDeviceFileObject(AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbDeviceFileObject();
-
- /** \brief IOCTL event handler
-
- This method is called when a device control request comes to the file
- object this extension wraps. We override this method to handle the
- following IOCTL requests:
- 1. ADB_CTL_GET_USB_DEVICE_DESCRIPTOR
- 2. ADB_CTL_GET_USB_CONFIGURATION_DESCRIPTOR
- 3. ADB_CTL_GET_USB_INTERFACE_DESCRIPTOR
- 4. ADB_CTL_GET_ENDPOINT_INFORMATION
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param ioctl_code[in] The driver-defined or system-defined I/O control code
- that is associated with the request.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code);
-};
-
-#endif // ANDROID_USB_DEVICE_FILE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_device_object.cpp b/host/windows/usb/legacy/driver/android_usb_device_object.cpp
deleted file mode 100755
index 1e7101f..0000000
--- a/host/windows/usb/legacy/driver/android_usb_device_object.cpp
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/driver/android_usb_device_object.h b/host/windows/usb/legacy/driver/android_usb_device_object.h
deleted file mode 100755
index 698dc87..0000000
--- a/host/windows/usb/legacy/driver/android_usb_device_object.h
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_DEVICE_OBJECT_H__
-#define ANDROID_USB_DEVICE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbDeviceObject that
- encapsulates an extension for KMDF device (FDO) object.
-*/
-
-#include "android_usb_wdf_object.h"
-
-// Forward declaration for file object extension
-class AndroidUsbFileObject;
-
-/** AndroidUsbDeviceObject class encapsulates an extension for KMDF FDO device
- object. Instances of this class must be allocated from NonPagedPool.
-*/
-class AndroidUsbDeviceObject : public AndroidUsbWdfObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- */
- AndroidUsbDeviceObject();
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- ~AndroidUsbDeviceObject();
-
- public:
- /** \brief Creates and initializes FDO device object extension
-
- This method is called from driver's OnAddDevice method in response to
- AddDevice call from the PnP manager
- @param device_init[in] A pointer to a framework-allocated WDFDEVICE_INIT
- structure.
- @return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise,
- it returns one of the error status values defined in ntstatus.h.
- */
- NTSTATUS CreateFDODevice(PWDFDEVICE_INIT device_init);
-
- /** \brief Resets target device
-
- When executing this method instance of this class may be deleted!
- This method must be called at PASSIVE IRQL.
- @return STATUS_SUCCESS or an appropriate error code
- */
- NTSTATUS ResetDevice();
-
- private:
- /** \name Device event handlers and callbacks
- */
- ///@{
-
- /** \brief Handler for PnP prepare hardware event
-
- This method performs any operations that are needed to make a device
- accessible to the driver. The framework calls this callback after the PnP
- manager has assigned hardware resources to the device and after the device
- has entered its uninitialized D0 state. This callback is called before
- calling the driver's EvtDeviceD0Entry callback function.
- This method is called at PASSIVE IRQL.
- @param resources_raw[in] A handle to a framework resource-list object that
- identifies the raw hardware resources that the PnP manager has
- assigned to the device.
- @param resources_translated[in] A handle to a framework resource-list
- object that identifies the translated hardware resources that the
- PnP manager has assigned to the device.
- @return Successful status or an appropriate error code
- */
- NTSTATUS OnEvtDevicePrepareHardware(WDFCMRESLIST resources_raw,
- WDFCMRESLIST resources_translated);
-
- /** \brief Handler for PnP release hardware event
-
- This method performs operations that that are needed when a device is no
- longer accessible. Framework calls the callback function if the device is
- being removed, or if the PnP manager is attempting to redistribute hardware
- resources. The framework calls the EvtDeviceReleaseHardware callback
- function after the driver's device has been shut off, the PnP manager has
- reclaimed the hardware resources that it assigned to the device, and the
- device is no longer accessible. (The PCI configuration state is still
- accessible.) Typically, a EvtDeviceReleaseHardware callback function unmaps
- memory that the driver's EvtDevicePrepareHardware callback function mapped.
- Usually, all other hardware shutdown operations should take place in the
- driver's EvtDeviceD0Exit callback function.
- This method is called at PASSIVE IRQL.
- @param wdf_device[in] A handle to a framework device object.
- @param resources_translated[in] A handle to a framework resource-list
- object that identifies the translated hardware resources that the
- PnP manager has assigned to the device.
- @return Successful status or an appropriate error code
- */
- NTSTATUS OnEvtDeviceReleaseHardware(WDFCMRESLIST resources_translated);
-
- /** \brief Handler for create file event (request)
-
- This method performs operations that are needed when an application
- requests access to an item within this device path (including device
- itself). This method is called synchronously, in the context of the
- user thread that opens the item.
- This method is called at PASSIVE IRQL.
- @param request[in] A handle to a framework request object that represents
- a file creation request.
- @param wdf_fo[in] A handle to a framework file object that describes a
- file that is being created with this request.
- @return Successful status or an appropriate error code
- */
- void OnEvtDeviceFileCreate(WDFREQUEST request, WDFFILEOBJECT wdf_fo);
-
- /** \brief Entry point for PnP prepare hardware event
-
- This callback performs any operations that are needed to make a device
- accessible to the driver. The framework calls this callback after the PnP
- manager has assigned hardware resources to the device and after the device
- has entered its uninitialized D0 state. This callback is called before
- calling the driver's EvtDeviceD0Entry callback function.
- This callback is called at PASSIVE IRQL.
- @param wdf_dev[in] A handle to a framework device object.
- @param resources_raw[in] A handle to a framework resource-list object that
- identifies the raw hardware resources that the PnP manager has
- assigned to the device.
- @param resources_translated[in] A handle to a framework resource-list
- object that identifies the translated hardware resources that the
- PnP manager has assigned to the device.
- @return Successful status or an appropriate error code
- */
- static NTSTATUS EvtDevicePrepareHardwareEntry(WDFDEVICE wdf_dev,
- WDFCMRESLIST resources_raw,
- WDFCMRESLIST resources_translated);
-
- /** \brief Entry point for PnP release hardware event
-
- This callback performs operations that that are needed when a device is no
- longer accessible. Framework calls the callback function if the device is
- being removed, or if the PnP manager is attempting to redistribute hardware
- resources. The framework calls the EvtDeviceReleaseHardware callback
- function after the driver's device has been shut off, the PnP manager has
- reclaimed the hardware resources that it assigned to the device, and the
- device is no longer accessible. (The PCI configuration state is still
- accessible.) Typically, a EvtDeviceReleaseHardware callback function unmaps
- memory that the driver's EvtDevicePrepareHardware callback function mapped.
- Usually, all other hardware shutdown operations should take place in the
- driver's EvtDeviceD0Exit callback function.
- This callback is called at PASSIVE IRQL.
- @param wdf_dev[in] A handle to a framework device object.
- @param resources_translated[in] A handle to a framework resource-list
- object that identifies the translated hardware resources that the
- PnP manager has assigned to the device.
- @return Successful status or an appropriate error code
- */
- static NTSTATUS EvtDeviceReleaseHardwareEntry(WDFDEVICE wdf_dev,
- WDFCMRESLIST resources_translated);
-
- /** \brief Entry point for create file event (request)
-
- This callback performs operations that that are needed when an application
- requests access to a device. The framework calls a driver's
- EvtDeviceFileCreate callback function when a user application or another
- driver opens the device (or file on this device) to perform an I/O
- operation, such as reading or writing a file. This callback function is
- called synchronously, in the context of the user thread that opens the
- device.
- This callback is called at PASSIVE IRQL.
- @param wdf_dev[in] A handle to a framework device object.
- @param request[in] A handle to a framework request object that represents
- a file creation request.
- @param wdf_fo[in] A handle to a framework file object that describes a
- file that is being created with this request.
- @return Successful status or an appropriate error code
- */
- static void EvtDeviceFileCreateEntry(WDFDEVICE wdf_dev,
- WDFREQUEST request,
- WDFFILEOBJECT wdf_fo);
-
- ///@}
-
- private:
- /** \name I/O request event handlers and callbacks
- */
- ///@{
-
- /** \brief Read event handler
-
- This method is called when a read request comes to a file object opened
- on this device.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be read.
- */
- void OnEvtIoRead(WDFREQUEST request, size_t length);
-
- /** \brief Write event handler
-
- This method is called when a write request comes to a file object opened
- on this device.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be written.
- */
- void OnEvtIoWrite(WDFREQUEST request, size_t length);
-
- /** \brief IOCTL event handler
-
- This method is called when a device control request comes to a file object
- opened on this device.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param ioctl_code[in] The driver-defined or system-defined I/O control code
- that is associated with the request.
- */
- void OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code);
-
- /** \brief Entry point for read event
-
- This callback is called when a read request comes to a file object opened
- on this device.
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param queue[in] A handle to the framework queue object that is associated
- with the I/O request.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be read.
- */
- static void EvtIoReadEntry(WDFQUEUE queue,
- WDFREQUEST request,
- size_t length);
-
- /** \brief Entry point for write event
-
- This callback is called when a write request comes to a file object opened
- on this device.
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param queue[in] A handle to the framework queue object that is associated
- with the I/O request.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be written.
- */
- static void EvtIoWriteEntry(WDFQUEUE queue,
- WDFREQUEST request,
- size_t length);
-
- /** \brief Entry point for device IOCTL event
-
- This callback is called when a device control request comes to a file
- object opened on this device.
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param queue[in] A handle to the framework queue object that is associated
- with the I/O request.
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param ioctl_code[in] The driver-defined or system-defined I/O control code
- that is associated with the request.
- */
- static void EvtIoDeviceControlEntry(WDFQUEUE queue,
- WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code);
-
- ///@}
-
- public:
- /** \name Device level I/O request handlers
- */
- ///@{
-
- /** \brief Gets USB device descriptor
-
- This method can be called at IRQL <= DISPATCH_LEVEL
- @param request[in] A handle to a framework request object for this IOCTL.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- void OnGetUsbDeviceDescriptorCtl(WDFREQUEST request, size_t output_buf_len);
-
- /** \brief Gets USB configuration descriptor for the selected configuration.
-
- This method can be called at IRQL <= DISPATCH_LEVEL
- @param request[in] A handle to a framework request object for this IOCTL.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- void OnGetUsbConfigDescriptorCtl(WDFREQUEST request, size_t output_buf_len);
-
- /** \brief Gets USB configuration descriptor for the selected interface.
-
- This method can be called at IRQL <= DISPATCH_LEVEL
- @param request[in] A handle to a framework request object for this IOCTL.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- void OnGetUsbInterfaceDescriptorCtl(WDFREQUEST request, size_t output_buf_len);
-
- /** \brief Gets information about an endpoint.
-
- This method can be called at IRQL <= DISPATCH_LEVEL
- @param request[in] A handle to a framework request object for this IOCTL.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- void OnGetEndpointInformationCtl(WDFREQUEST request,
- size_t input_buf_len,
- size_t output_buf_len);
-
- /** \brief Gets device serial number.
-
- Serial number is returned in form of zero-terminated string that in the
- output buffer. This method must be called at low IRQL.
- @param request[in] A handle to a framework request object for this IOCTL.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- void OnGetSerialNumberCtl(WDFREQUEST request, size_t output_buf_len);
-
- ///@}
-
- private:
- /** \name Internal methods
- */
- ///@{
-
- /** \brief Creates default request queue for this device.
-
- In KMDF all I/O requests are coming through the queue object. So, in order
- to enable our device to receive I/O requests we must create a queue for it.
- This method is called at PASSIVE IRQL.
- @return STATUS_SUCCESS or an appropriate error code.
- */
- NTSTATUS CreateDefaultQueue();
-
- /** \brief Configures our device.
-
- This method is called from the prepare hardware handler after underlying
- FDO device has been created.
- This method is called at PASSSIVE IRQL.
- @return STATUS_SUCCESS or an appropriate error code.
- */
- NTSTATUS ConfigureDevice();
-
- /** \brief Selects interfaces on our device.
-
- This method is called from the prepare hardware handler after underlying
- FDO device has been created and configured.
- This method is called at PASSSIVE IRQL.
- @return STATUS_SUCCESS or an appropriate error code.
- */
- NTSTATUS SelectInterfaces();
-
- /** \brief Gets pipe index from a file name
-
- This method is called from OnEvtDeviceFileCreate to determine index of
- the pipe this file is addressing.
- This method is called at PASSIVE IRQL.
- @param file_path[in] Path to the file that being opened.
- @return Pipe index or INVALID_UCHAR if index cannot be calculated.
- */
- UCHAR GetPipeIndexFromFileName(PUNICODE_STRING file_path);
-
- /** \brief Creates file object extension for a pipe
-
- This method is called from OnEvtDeviceFileCreate to create an appropriate
- file object extension for a particular pipe type.
- This method is called at PASSIVE IRQL.
- @param wdf_fo[in] KMDF file to extend.
- @param wdf_pipe_obj[in] KMDF pipe for this extension
- @param pipe_info[in] Pipe information
- @param wdf_file_ext[out] Upon successfull completion will receive instance
- of the extension.
- @return STATUS_SUCCESS or an appropriate error code
- */
- NTSTATUS CreatePipeFileObjectExt(WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj,
- const WDF_USB_PIPE_INFORMATION* pipe_info,
- AndroidUsbFileObject** wdf_file_ext);
-
- ///@}
-
- private:
- /** \name Debugging support
- */
- ///@{
-
-#if DBG
- /// Prints USB_DEVICE_DESCRIPTOR to debug output
- void PrintUsbDeviceDescriptor(const USB_DEVICE_DESCRIPTOR* desc);
-
- /// Prints WDF_USB_DEVICE_INFORMATION to debug output
- void PrintUsbTargedDeviceInformation(const WDF_USB_DEVICE_INFORMATION* info);
-
- /// Prints USB_CONFIGURATION_DESCRIPTOR to debug output
- void PrintConfigDescriptor(const USB_CONFIGURATION_DESCRIPTOR* desc,
- ULONG size);
-
- /// Prints WDF_USB_DEVICE_SELECT_CONFIG_PARAMS to debug output
- void PrintSelectedConfig(const WDF_USB_DEVICE_SELECT_CONFIG_PARAMS* config);
-
- /// Prints USB_INTERFACE_DESCRIPTOR to debug output
- void PrintInterfaceDescriptor(const USB_INTERFACE_DESCRIPTOR* desc);
-
- /// Prints WDF_USB_PIPE_INFORMATION to debug output
- void PrintPipeInformation(const WDF_USB_PIPE_INFORMATION* info,
- UCHAR pipe_index);
-
-#endif // DBG
-
- ///@}
-
- public:
- /// Gets WDF device handle for this device
- __forceinline WDFDEVICE wdf_device() const {
- return reinterpret_cast<WDFDEVICE>(wdf_object());
- }
-
- /// Gets target USB device descriptor
- __forceinline const USB_DEVICE_DESCRIPTOR* usb_device_descriptor() const {
- return &usb_device_descriptor_;
- }
-
- /// Gets target USB device information
- __forceinline const WDF_USB_DEVICE_INFORMATION* usb_device_info() const {
- return &usb_device_info_;
- }
-
- /// Gets selected interface descriptor
- __forceinline const USB_INTERFACE_DESCRIPTOR* interface_descriptor() const {
- return &interface_descriptor_;
- }
-
- /// Gets target (PDO) device handle
- __forceinline WDFUSBDEVICE wdf_target_device() const {
- return wdf_target_device_;
- }
-
- /// Checks if target device has been created
- __forceinline bool IsTaretDeviceCreated() const {
- return (NULL != wdf_target_device());
- }
-
- /// Gets USB configuration descriptor
- __forceinline const USB_CONFIGURATION_DESCRIPTOR* configuration_descriptor() const {
- return configuration_descriptor_;
- }
-
- /// Checks if device has been configured
- __forceinline bool IsDeviceConfigured() const {
- return (NULL != configuration_descriptor());
- }
-
- /// Gets number of interfaces for this device
- __forceinline UCHAR GetInterfaceCount() const {
- ASSERT(IsDeviceConfigured());
- return IsDeviceConfigured() ? configuration_descriptor()->bNumInterfaces : 0;
- }
-
- /// Checks if this is "single interface" device
- __forceinline bool IsSingleInterfaceDevice() const {
- return (1 == GetInterfaceCount());
- }
-
- /// Gets USB interface selected on this device
- __forceinline WDFUSBINTERFACE wdf_usb_interface() const {
- return wdf_usb_interface_;
- }
-
- /// Checks if an interface has been selected on this device
- __forceinline bool IsInterfaceSelected() const {
- return (NULL != wdf_usb_interface());
- }
-
- /// Gets number of pipes configured on this device
- __forceinline UCHAR configured_pipes_num() const {
- return configured_pipes_num_;
- }
-
- /// Gets index of the bulk read pipe
- __forceinline UCHAR bulk_read_pipe_index() const {
- return bulk_read_pipe_index_;
- }
-
- /// Gets index of the bulk write pipe
- __forceinline UCHAR bulk_write_pipe_index() const {
- return bulk_write_pipe_index_;
- }
-
- /// Checks if this is a high speed device
- __forceinline bool IsHighSpeed() const {
- return (0 != (usb_device_info()->Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED));
- }
-
- /// Checks if bulk read pipe index is known
- __forceinline bool IsBulkReadPipeKnown() const {
- return (INVALID_UCHAR != bulk_read_pipe_index());
- }
-
- /// Checks if bulk write pipe index is known
- __forceinline bool IsBulkWritePipeKnown() const {
- return (INVALID_UCHAR != bulk_write_pipe_index());
- }
-
- /// Gets device serial number string. Note that string may be
- /// not zero-terminated. Use serial_number_len() to get actual
- /// length of this string.
- __forceinline const WCHAR* serial_number() const {
- ASSERT(NULL != serial_number_handle_);
- return (NULL != serial_number_handle_) ?
- reinterpret_cast<const WCHAR*>
- (WdfMemoryGetBuffer(serial_number_handle_, NULL)) :
- NULL;
- }
-
- /// Gets length (in bytes) of device serial number string
- __forceinline USHORT serial_number_char_len() const {
- return serial_number_char_len_;
- }
-
- /// Gets length (in bytes) of device serial number string
- __forceinline USHORT serial_number_byte_len() const {
- return serial_number_char_len() * sizeof(WCHAR);
- }
-
- protected:
- /// Target USB device descriptor
- USB_DEVICE_DESCRIPTOR usb_device_descriptor_;
-
- /// Target USB device information
- WDF_USB_DEVICE_INFORMATION usb_device_info_;
-
- /// Selected interface descriptor
- USB_INTERFACE_DESCRIPTOR interface_descriptor_;
-
- /// USB configuration descriptor
- PUSB_CONFIGURATION_DESCRIPTOR configuration_descriptor_;
-
- /// Target (PDO?) device handle
- WDFUSBDEVICE wdf_target_device_;
-
- /// USB interface selected on this device
- WDFUSBINTERFACE wdf_usb_interface_;
-
- /// Device serial number
- WDFMEMORY serial_number_handle_;
-
- /// Device serial number string length
- USHORT serial_number_char_len_;
-
- /// Number of pipes configured on this device
- UCHAR configured_pipes_num_;
-
- /// Index of the bulk read pipe
- UCHAR bulk_read_pipe_index_;
-
- /// Index of the bulk write pipe
- UCHAR bulk_write_pipe_index_;
-};
-
-/** \brief Gets device KMDF object extension for the given KMDF object
-
- @param wdf_dev[in] KMDF handle describing device object
- @return Instance of AndroidUsbDeviceObject associated with KMDF object or
- NULL if association is not found.
-*/
-__forceinline AndroidUsbDeviceObject* GetAndroidUsbDeviceObjectFromHandle(
- WDFDEVICE wdf_dev) {
- AndroidUsbWdfObject* wdf_object_ext =
- GetAndroidUsbWdfObjectFromHandle(wdf_dev);
- ASSERT((NULL != wdf_object_ext) &&
- wdf_object_ext->Is(AndroidUsbWdfObjectTypeDevice));
- if ((NULL != wdf_object_ext) &&
- wdf_object_ext->Is(AndroidUsbWdfObjectTypeDevice)) {
- return reinterpret_cast<AndroidUsbDeviceObject*>(wdf_object_ext);
- }
- return NULL;
-}
-
-#endif // ANDROID_USB_DEVICE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_driver_defines.h b/host/windows/usb/legacy/driver/android_usb_driver_defines.h
deleted file mode 100755
index da976e5..0000000
--- a/host/windows/usb/legacy/driver/android_usb_driver_defines.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_DRIVER_DEFINES_H__
-#define ANDROID_USB_DRIVER_DEFINES_H__
-/** \file
- This file consists of constants, types and macros used (and useful) in driver
- development.
-*/
-
-/** \name IRQL assertions
- These assertions help to verify that code is running at expected IRQL
-*/
-///@{
-
-/// Asserts that current IRQL is less than provided level
-#define ASSERT_IRQL_LESS(irql_level) ASSERT(KeGetCurrentIrql() < irql_level)
-/// Asserts that current IRQL is less or equal than provided level
-#define ASSERT_IRQL_LESS_OR_EQUAL(irql_level) ASSERT(KeGetCurrentIrql() <= irql_level)
-/// Asserts that current IRQL is the same as provided level
-#define ASSERT_IRQL_IS(irql_level) ASSERT(irql_level == KeGetCurrentIrql())
-/// Asserts that current IRQL is less than DISPATCH_LEVEL
-#define ASSERT_IRQL_LOW() ASSERT_IRQL_LESS(DISPATCH_LEVEL)
-/// Asserts that current IRQL is above APC_LEVEL
-#define ASSERT_IRQL_HIGH() ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL)
-/// Asserts that current IRQL is at PASSIVE_LEVEL
-#define ASSERT_IRQL_PASSIVE() ASSERT_IRQL_IS(PASSIVE_LEVEL)
-/// Asserts that current IRQL is at APC_LEVEL
-#define ASSERT_IRQL_APC() ASSERT_IRQL_IS(APC_LEVEL)
-/// Asserts that current IRQL is at DISPATCH_LEVEL
-#define ASSERT_IRQL_DISPATCH() ASSERT_IRQL_IS(DISPATCH_LEVEL)
-/// Asserts that current IRQL is at APC or DISPATCH_LEVEL
-#define ASSERT_IRQL_APC_OR_DISPATCH() \
- ASSERT((KeGetCurrentIrql() == APC_LEVEL) || (KeGetCurrentIrql() == DISPATCH_LEVEL))
-/// Asserts that current IRQL is less or equal DISPATCH_LEVEL
-#define ASSERT_IRQL_LOW_OR_DISPATCH() \
- ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL)
-
-///@}
-
-#if DBG
-/** \brief Overrides DbgPrint to make sure that nothing gets printed
- to debug output in release build.
-*/
-ULONG __cdecl GoogleDbgPrint(char* format, ...);
-#else
-#define GoogleDbgPrint(Arg) NOTHING
-#endif
-
-/// Invalid UCHAR value
-#define INVALID_UCHAR (static_cast<UCHAR>(0xFF))
-
-/// Invalid ULONG value
-#define INVALID_ULONG (static_cast<ULONG>(-1))
-
-/** Enum AndroidUsbWdfObjectType enumerates types of KMDF objects that
- we extend in our driver.
-*/
-enum AndroidUsbWdfObjectType {
- // We start enum with 1 insetead of 0 to protect orselves from a dangling
- // or uninitialized context structures because KMDF will zero our extension
- // when it gets created.
-
- /// Device object context
- AndroidUsbWdfObjectTypeDevice = 1,
-
- /// File object context
- AndroidUsbWdfObjectTypeFile,
-
- /// Request object context
- AndroidUsbWdfObjectTypeRequest,
-
- /// Workitem object context
- AndroidUsbWdfObjectTypeWorkitem,
-
- /// Illegal (maximum) context id
- AndroidUsbWdfObjectTypeMax
-};
-
-/** Structure AndroidUsbWdfObjectContext represents our context that extends
- every KMDF object (device, file, pipe, etc).
-*/
-typedef struct TagAndroidUsbWdfObjectContext {
- /// KMDF object type that is extended with this context
- AndroidUsbWdfObjectType object_type;
-
- /// Instance of the class that extends KMDF object with this context
- class AndroidUsbWdfObject* wdf_object_ext;
-} AndroidUsbWdfObjectContext;
-
-// KMDF woodoo to register our extension and implement accessor method
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWdfObjectContext,
- GetAndroidUsbWdfObjectContext)
-
-/** Structure AndroidUsbWdfRequestContext represents our context that is
- associated with every request recevied by the driver.
-*/
-typedef struct TagAndroidUsbWdfRequestContext {
- /// KMDF object type that is extended with this context
- /// (must be AndroidUsbWdfObjectTypeRequest)
- AndroidUsbWdfObjectType object_type;
-
- /// System time request has been first scheduled
- // (time of the first WdfRequestSend is called for it)
- LARGE_INTEGER sent_at;
-
- /// KMDF descriptor for the memory allocated for URB
- WDFMEMORY urb_mem;
-
- /// MDL describing the transfer buffer
- PMDL transfer_mdl;
-
- /// Private MDL that we build in order to perform the transfer
- PMDL mdl;
-
- // Virtual address for the current segment of transfer.
- void* virtual_address;
-
- /// Number of bytes remaining to transfer
- ULONG length;
-
- /// Number of bytes requested to transfer
- ULONG transfer_size;
-
- /// Accummulated number of bytes transferred
- ULONG num_xfer;
-
- /// Initial timeout (in millisec) set for this request
- ULONG initial_time_out;
-
- // Read / Write selector
- bool is_read;
-
- // IOCTL selector
- bool is_ioctl;
-} AndroidUsbWdfRequestContext;
-
-// KMDF woodoo to register our extension and implement accessor method
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWdfRequestContext,
- GetAndroidUsbWdfRequestContext)
-
-/** Structure AndroidUsbWorkitemContext represents our context that is
- associated with workitems created by our driver.
-*/
-typedef struct TagAndroidUsbWorkitemContext {
- /// KMDF object type that is extended with this context
- /// (must be AndroidUsbWdfObjectTypeWorkitem)
- AndroidUsbWdfObjectType object_type;
-
- /// Pipe file object extension that enqueued this work item
- class AndroidUsbPipeFileObject* pipe_file_ext;
-} AndroidUsbWorkitemContext;
-
-// KMDF woodoo to register our extension and implement accessor method
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWorkitemContext,
- GetAndroidUsbWorkitemContext)
-
-#endif // ANDROID_USB_DRIVER_DEFINES_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_driver_object.cpp b/host/windows/usb/legacy/driver/android_usb_driver_object.cpp
deleted file mode 100755
index 770a13a..0000000
--- a/host/windows/usb/legacy/driver/android_usb_driver_object.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbDriverObject that
- encapsulates our driver object
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_device_object.h"
-#include "android_usb_driver_object.h"
-
-#pragma data_seg()
-
-/** Globally accessible instance of the AndroidUsbDriverObject.
- NT OS design allows us using of a global pointer to our driver object
- instance since it can't be created or destroyed concurently and its value
- is not going to change between creation and destruction.
-*/
-AndroidUsbDriverObject* global_driver_object = NULL;
-
-#pragma code_seg("INIT")
-
-extern "C" {
-
-/// Main entry point to the driver
-NTSTATUS DriverEntry(PDRIVER_OBJECT drv_object, PUNICODE_STRING reg_path) {
- // Just pass it down inside the class
- return AndroidUsbDriverObject::DriverEntry(drv_object, reg_path);
-}
-
-} // extern "C"
-
-NTSTATUS AndroidUsbDriverObject::DriverEntry(PDRIVER_OBJECT drv_object,
- PUNICODE_STRING reg_path) {
- ASSERT_IRQL_PASSIVE();
- ASSERT(NULL != drv_object);
- ASSERT((NULL != reg_path) &&
- (NULL != reg_path->Buffer) &&
- (0 != reg_path->Length));
-
- // Instantiate driver object
- global_driver_object = new(NonPagedPool, GANDR_POOL_TAG_DRIVER_OBJECT)
- AndroidUsbDriverObject(drv_object, reg_path);
- ASSERT(NULL != global_driver_object);
- if (NULL == global_driver_object)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- // Initialize driver object
- NTSTATUS status = global_driver_object->OnDriverEntry(drv_object, reg_path);
-
- if (!NT_SUCCESS(status)) {
- // Something went wrong. Delete our driver object and get out of here.
- delete global_driver_object;
- }
-
- return status;
-}
-
-AndroidUsbDriverObject::AndroidUsbDriverObject(PDRIVER_OBJECT drv_object,
- PUNICODE_STRING reg_path)
- : driver_object_(drv_object),
- wdf_driver_(NULL) {
- ASSERT_IRQL_PASSIVE();
- ASSERT(NULL != driver_object());
-}
-
-NTSTATUS AndroidUsbDriverObject::OnDriverEntry(PDRIVER_OBJECT drv_object,
- PUNICODE_STRING reg_path) {
- ASSERT_IRQL_PASSIVE();
- ASSERT(driver_object() == drv_object);
-
- // Initiialize driver config, specifying our unload callback and default
- // pool tag for memory allocations that KMDF does on our behalf.
- WDF_DRIVER_CONFIG config;
- WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAddEntry);
- config.EvtDriverUnload = EvtDriverUnloadEntry;
- config.DriverPoolTag = GANDR_POOL_TAG_DEFAULT;
-
- // Create a framework driver object to represent our driver.
- NTSTATUS status = WdfDriverCreate(drv_object,
- reg_path,
- WDF_NO_OBJECT_ATTRIBUTES,
- &config,
- &wdf_driver_);
- ASSERT(NT_SUCCESS(status));
- if (!NT_SUCCESS(status))
- return status;
-
- GoogleDbgPrint("\n>>>>>>>>>> Android USB driver has started >>>>>>>>>>");
-
- return STATUS_SUCCESS;
-}
-
-#pragma code_seg("PAGE")
-
-AndroidUsbDriverObject::~AndroidUsbDriverObject() {
- ASSERT_IRQL_PASSIVE();
-}
-
-NTSTATUS AndroidUsbDriverObject::OnAddDevice(PWDFDEVICE_INIT device_init) {
- ASSERT_IRQL_PASSIVE();
- GoogleDbgPrint("\n++++++++++ AndroidUsbDriverObject::OnAddDevice ++++++++++");
- // Instantiate our device object extension for this device
- AndroidUsbDeviceObject* wdf_device_ext =
- new(NonPagedPool, GANDR_POOL_TAG_KMDF_DEVICE) AndroidUsbDeviceObject();
- ASSERT(NULL != wdf_device_ext);
- if (NULL == wdf_device_ext)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- // Create and initialize FDO device
- NTSTATUS status = wdf_device_ext->CreateFDODevice(device_init);
- ASSERT(NT_SUCCESS(status));
- if (!NT_SUCCESS(status))
- delete wdf_device_ext;
-
- return status;
-}
-
-void AndroidUsbDriverObject::OnDriverUnload() {
- ASSERT_IRQL_PASSIVE();
- GoogleDbgPrint("\n<<<<<<<<<< Android USB driver is unloaded <<<<<<<<<<");
-}
-
-NTSTATUS AndroidUsbDriverObject::EvtDeviceAddEntry(
- WDFDRIVER wdf_drv,
- PWDFDEVICE_INIT device_init) {
- ASSERT_IRQL_PASSIVE();
- ASSERT((NULL != global_driver_object) && (global_driver_object->wdf_driver() == wdf_drv));
-
- // Pass it down to our driver object
- if ((NULL == global_driver_object) ||
- (global_driver_object->wdf_driver() != wdf_drv)) {
- return STATUS_INTERNAL_ERROR;
- }
-
- return global_driver_object->OnAddDevice(device_init);
-}
-
-VOID AndroidUsbDriverObject::EvtDriverUnloadEntry(WDFDRIVER wdf_drv) {
- ASSERT_IRQL_PASSIVE();
- ASSERT((NULL != global_driver_object) &&
- (global_driver_object->wdf_driver() == wdf_drv));
-
- // Pass it down to our driver object
- if ((NULL != global_driver_object) &&
- (global_driver_object->wdf_driver() == wdf_drv)) {
- global_driver_object->OnDriverUnload();
- // Now we can (and have to) delete our driver object
- delete global_driver_object;
- }
-}
-
-#if DBG
-
-#pragma code_seg()
-
-ULONG __cdecl GoogleDbgPrint(char* format, ...) {
- va_list arg_list;
- va_start(arg_list, format);
- ULONG ret =
- vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, arg_list);
- va_end(arg_list);
-
- return ret;
-}
-
-#endif // DBG
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_driver_object.h b/host/windows/usb/legacy/driver/android_usb_driver_object.h
deleted file mode 100755
index 568b977..0000000
--- a/host/windows/usb/legacy/driver/android_usb_driver_object.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_DRIVER_OBJECT_H__
-#define ANDROID_USB_DRIVER_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbDriverObject that
- encapsulates our driver object.
-*/
-
-/// Globally accessible pointer to the driver object
-extern class AndroidUsbDriverObject* global_driver_object;
-
-/** AndroidUsbDriverObject class encapsulates driver object and provides
- overall initialization / cleanup as well as management of globally used
- resources. We use KMDF framework for this driver because it takes care of
- most of the USB related "things" (like PnP, power management and other
- stuff) so we can concentrate more on real functionality. This driver is
- based on KMDF's usbsamp driver sample available at DDK's src\kmdf\usbsamp
- directory. Instance of this class (always one) must be allocated from
- NonPagedPool.
-*/
-class AndroidUsbDriverObject {
-
- public:
- /** \brief Driver initialization entry point.
-
- This method is a "gate" to our driver class from main DriverEntry routine.
- Since this method is called from within DriverEntry only it is placed in
- "INIT" code segment.
- This method is called at IRQL PASSIVE_LEVEL.
- @param drv_object[in] Driver object passed to DriverEntry routine
- @param reg_path[in] Path to the driver's Registry passed to DriverEntry
- routine
- @returns STATUS_SUCCESS on success or an appropriate error code.
- */
- static NTSTATUS DriverEntry(PDRIVER_OBJECT drv_object,
- PUNICODE_STRING reg_path);
-
- private:
- /** \brief Constructs driver object.
-
- Constructor for driver class must be as light as possible. All
- initialization that may fail must be deferred to OnDriverEntry method.
- Since this method is called from within DriverEntry only it is placed in
- "INIT" code segment.
- This method is called at IRQL PASSIVE_LEVEL.
- @param drv_object[in] Driver object passed to DriverEntry routine
- @param reg_path[in] Path to the driver's Registry passed to DriverEntry
- routine
- */
- AndroidUsbDriverObject(PDRIVER_OBJECT drv_object, PUNICODE_STRING reg_path);
-
- /** \brief Destructs driver object.
-
- Destructor for driver class must be as light as possible. All
- uninitialization must be done in OnDriverUnload method.
- This method must be called at PASSIVE IRQL.
- */
- ~AndroidUsbDriverObject();
-
- /** \brief Initializes instance of the driver object.
-
- This method is called immediatelly after driver object has been
- instantiated to perform actual initialization of the driver. Since this
- method is called from within DriverEntry only it is placed in
- "INIT" code segment.
- This method is called at IRQL PASSIVE_LEVEL.
- @param drv_object[in] Driver object passed to DriverEntry routine
- @param reg_path[in] Path to the driver's Registry passed to DriverEntry
- routine
- @returns STATUS_SUCCESS on success or an appropriate error code.
- */
- NTSTATUS OnDriverEntry(PDRIVER_OBJECT drv_object, PUNICODE_STRING reg_path);
-
- /** \brief Actual handler for KMDF's AddDevice event
-
- This method is called by the framework in response to AddDevice call from
- the PnP manager. We create and initialize a device object to represent a
- new instance of the device.
- This method is called at IRQL PASSIVE_LEVEL.
- @param device_init[in] A pointer to a framework-allocated WDFDEVICE_INIT
- structure.
- @return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise,
- it returns one of the error status values defined in ntstatus.h.
- */
- NTSTATUS OnAddDevice(PWDFDEVICE_INIT device_init);
-
- /** \brief Actual driver unload event handler.
-
- This method is called when driver is being unloaded.
- This method is called at IRQL PASSIVE_LEVEL.
- */
- void OnDriverUnload();
-
- /** \brief KMDF's DeviceAdd event entry point
-
- This callback is called by the framework in response to AddDevice call from
- the PnP manager. We create and initialize a device object to represent a
- new instance of the device. All the software resources should be allocated
- in this callback.
- This method is called at IRQL PASSIVE_LEVEL.
- @param wdf_drv[in] WDF driver handle.
- @param device_init[in] A pointer to a framework-allocated WDFDEVICE_INIT
- structure.
- @return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise,
- it returns one of the error status values defined in ntstatus.h.
- */
- static NTSTATUS EvtDeviceAddEntry(WDFDRIVER wdf_drv,
- PWDFDEVICE_INIT device_init);
-
- /** \brief Driver unload event entry point.
-
- Framework calls this callback when driver is being unloaded.
- This method is called at IRQL PASSIVE_LEVEL.
- */
- static VOID EvtDriverUnloadEntry(WDFDRIVER wdf_drv);
-
- public:
-
- /// Gets this driver's DRIVER_OBJECT
- __forceinline PDRIVER_OBJECT driver_object() const {
- return driver_object_;
- }
-
- /// Gets KMDF driver handle
- __forceinline WDFDRIVER wdf_driver() const {
- return wdf_driver_;
- }
-
- private:
- /// This driver's driver object
- PDRIVER_OBJECT driver_object_;
-
- /// KMDF driver handle
- WDFDRIVER wdf_driver_;
-};
-
-#endif // ANDROID_USB_DRIVER_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_file_object.cpp b/host/windows/usb/legacy/driver/android_usb_file_object.cpp
deleted file mode 100755
index 196faec..0000000
--- a/host/windows/usb/legacy/driver/android_usb_file_object.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbFileObject that
- encapsulates a common extension for all KMDF file object types.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_file_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbFileObject::AndroidUsbFileObject(AndroidUsbFileObjectType fo_type,
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo)
- : AndroidUsbWdfObject(AndroidUsbWdfObjectTypeFile),
- file_type_(fo_type),
- device_object_(dev_obj) {
- ASSERT_IRQL_PASSIVE();
- ASSERT(NULL != dev_obj);
- ASSERT(fo_type < AndroidUsbFileObjectTypeMax);
- ASSERT(NULL != wdf_fo);
- set_wdf_object(wdf_fo);
-}
-
-#pragma code_seg()
-
-AndroidUsbFileObject::~AndroidUsbFileObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-#pragma code_seg("PAGE")
-
-NTSTATUS AndroidUsbFileObject::Initialize() {
- ASSERT_IRQL_LOW();
- ASSERT(NULL != wdf_file());
- if (NULL == wdf_file())
- return STATUS_INTERNAL_ERROR;
-
- // Register context for this file object
- return InitializeContext();
-}
-
-#pragma code_seg()
-
-void AndroidUsbFileObject::OnEvtIoRead(WDFREQUEST request,
- size_t length) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
- ASSERT(WdfRequestGetFileObject(request) == wdf_file());
- // Complete zero reads with success
- if (0 == length) {
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
- return;
- }
-
- WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
-}
-
-void AndroidUsbFileObject::OnEvtIoWrite(WDFREQUEST request,
- size_t length) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
- ASSERT(WdfRequestGetFileObject(request) == wdf_file());
- // Complete zero writes with success
- if (0 == length) {
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
- return;
- }
-
- WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
-}
-
-void AndroidUsbFileObject::OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
- ASSERT(WdfRequestGetFileObject(request) == wdf_file());
-
- WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_file_object.h b/host/windows/usb/legacy/driver/android_usb_file_object.h
deleted file mode 100755
index f845478..0000000
--- a/host/windows/usb/legacy/driver/android_usb_file_object.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_FILE_OBJECT_H__
-#define ANDROID_USB_FILE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbFileObject that
- encapsulates a common extension for all KMDF file object types.
-*/
-
-#include "android_usb_wdf_object.h"
-#include "android_usb_device_object.h"
-
-/** Enumerator AndroidUsbFileObjectType defines possible types for our file
- object extension.
-*/
-enum AndroidUsbFileObjectType {
- /// File extends device FO
- AndroidUsbFileObjectTypeDevice,
-
- // File extends a pipe FO
- AndroidUsbFileObjectTypePipe,
-
- AndroidUsbFileObjectTypeMax,
-};
-
-/** AndroidUsbFileObject class encapsulates a common extension for all KMDF
- file object types. Instances of this class must be allocated from
- NonPagedPool.
-*/
-class AndroidUsbFileObject : public AndroidUsbWdfObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- @param fo_type[in] Type of the file object that this object extends
- @param dev_obj[in] Our device object for which this file has been created
- @param wdf_fo[in] KMDF file object for this extension
- */
- AndroidUsbFileObject(AndroidUsbFileObjectType fo_type,
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbFileObject();
-
- /** \brief Initializes the object
-
- This method verifies that instance has been created and calls base class's
- InitializeContext method to register itself with the wrapped FO. All
- derived classes must call this method when initializing.
- This method must be called at low IRQL.
- @return STATUS_SUCCESS on success or an appropriate error code
- */
- virtual NTSTATUS Initialize();
-
- /** \brief Read event handler
-
- This method is called when a read request comes to the file object this
- class extends.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be read.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoRead(WDFREQUEST request, size_t length);
-
- /** \brief Write event handler
-
- This method is called when a write request comes to the file object this
- class extends.
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be written.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoWrite(WDFREQUEST request, size_t length);
-
- /** \brief IOCTL event handler
-
- This method is called when a device control request comes to the file
- object this class extends.
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param ioctl_code[in] The driver-defined or system-defined I/O control code
- that is associated with the request.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code);
-
- public:
- /// Gets KMDF file handle for this extension
- __forceinline WDFFILEOBJECT wdf_file() const {
- return reinterpret_cast<WDFFILEOBJECT>(wdf_object());
- }
-
- /// Gets device object that owns this file
- __forceinline AndroidUsbDeviceObject* device_object() const {
- return device_object_;
- }
-
- /// Gets type of the file object that this extension wraps
- __forceinline AndroidUsbFileObjectType file_type() const {
- return file_type_;
- }
-
- /// Gets WDF device handle for device that owns this file
- __forceinline WDFDEVICE wdf_device() const {
- ASSERT(NULL != device_object());
- return (NULL != device_object()) ? device_object()->wdf_device() :
- NULL;
- }
-
- /// Gets target (PDO) device handle for the device that owns this file
- __forceinline WDFUSBDEVICE wdf_target_device() const {
- ASSERT(NULL != device_object());
- return (NULL != device_object()) ? device_object()->wdf_target_device() :
- NULL;
- }
-
- protected:
- /// Device object that owns this file
- AndroidUsbDeviceObject* device_object_;
-
- /// Type of the file object that this extension wraps
- AndroidUsbFileObjectType file_type_;
-};
-
-/** \brief Gets file KMDF object extension for the given KMDF file object
-
- This method can be called at any IRQL
- @param wdf_fo[in] KMDF file handle describing file object
- @return Instance of AndroidUsbFileObject associated with this object or NULL
- if association is not found.
-*/
-__forceinline AndroidUsbFileObject* GetAndroidUsbFileObjectFromHandle(
- WDFFILEOBJECT wdf_fo) {
- AndroidUsbWdfObject* wdf_object_ext =
- GetAndroidUsbWdfObjectFromHandle(wdf_fo);
- ASSERT(NULL != wdf_object_ext);
- if (NULL != wdf_object_ext) {
- ASSERT(wdf_object_ext->Is(AndroidUsbWdfObjectTypeFile));
- if (wdf_object_ext->Is(AndroidUsbWdfObjectTypeFile))
- return reinterpret_cast<AndroidUsbFileObject*>(wdf_object_ext);
- }
- return NULL;
-}
-
-/** \brief Gets file KMDF file object extension for the given request
-
- This method can be called at any IRQL
- @param request[in] KMDF request object
- @return Instance of AndroidUsbFileObject associated with this request or NULL
- if association is not found.
-*/
-__forceinline AndroidUsbFileObject* GetAndroidUsbFileObjectForRequest(
- WDFREQUEST request) {
- return GetAndroidUsbFileObjectFromHandle(WdfRequestGetFileObject(request));
-}
-
-#endif // ANDROID_USB_FILE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_inl.h b/host/windows/usb/legacy/driver/android_usb_inl.h
deleted file mode 100755
index d08ed18..0000000
--- a/host/windows/usb/legacy/driver/android_usb_inl.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_INL_H__
-#define ANDROID_USB_INL_H__
-/** \file
- This file consists of inline routines for the driver.
-*/
-
-/// Gets control code out of the entire IOCTL code packet
-__forceinline ULONG GetCtlCode(ULONG ioctl_code) {
- return (ioctl_code >> 2) & 0x0FFF;
-}
-
-/** \brief
- Converts string length from number of wide characters into number of bytes.
-*/
-__forceinline USHORT ByteLen(USHORT wchar_len) {
- return static_cast<USHORT>(wchar_len * sizeof(WCHAR));
-}
-
-/** \brief Gets byte length of a zero-terminated string not including
- zero terminator. Must be called at low IRQL.
-*/
-__forceinline USHORT ByteLen(const WCHAR* str) {
- ASSERT_IRQL_LOW();
- return (NULL != str) ? ByteLen(static_cast<USHORT>(wcslen(str))) : 0;
-}
-
-/** \brief
- Converts string length from number of bytes into number of wide characters.
- Can be called at any IRQL.
-*/
-__forceinline USHORT WcharLen(USHORT byte_len) {
- return byte_len / sizeof(WCHAR);
-}
-
-/** \brief Retrieves pointer out of the WDFMEMORY handle
-*/
-__forceinline void* GetAddress(WDFMEMORY wdf_mem) {
- ASSERT(NULL != wdf_mem);
- return (NULL != wdf_mem) ? WdfMemoryGetBuffer(wdf_mem, NULL) : NULL;
-}
-
-/** \brief Retrieves output memory address for WDFREQUEST
-
- @param request[in] A handle to KMDF request object
- @param status[out] Receives status of the call. Can be NULL.
-*/
-__forceinline void* OutAddress(WDFREQUEST request, NTSTATUS* status) {
- ASSERT(NULL != request);
- WDFMEMORY wdf_mem = NULL;
- NTSTATUS stat = WdfRequestRetrieveOutputMemory(request, &wdf_mem);
- ASSERT((NULL != wdf_mem) || (!NT_SUCCESS(stat)));
- if (NULL != status)
- *status = stat;
- return NT_SUCCESS(stat) ? GetAddress(wdf_mem) : NULL;
-}
-
-/** \brief Retrieves input memory address for WDFREQUEST
-
- @param request[in] A handle to KMDF request object
- @param status[out] Receives status of the call. Can be NULL.
-*/
-__forceinline void* InAddress(WDFREQUEST request, NTSTATUS* status) {
- ASSERT(NULL != request);
- WDFMEMORY wdf_mem = NULL;
- NTSTATUS stat = WdfRequestRetrieveInputMemory(request, &wdf_mem);
- ASSERT((NULL != wdf_mem) || (!NT_SUCCESS(stat)));
- if (NULL != status)
- *status = stat;
- return NT_SUCCESS(stat) ? GetAddress(wdf_mem) : NULL;
-}
-
-#endif // ANDROID_USB_INL_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.cpp b/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.cpp
deleted file mode 100755
index 32c88ca..0000000
--- a/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbInterruptPipeFileObject
- that encapsulates extension to an interrupt pipe file objects.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_interrupt_file_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbInterruptPipeFileObject::AndroidUsbInterruptPipeFileObject(
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj)
- : AndroidUsbPipeFileObject(dev_obj, wdf_fo, wdf_pipe_obj) {
- ASSERT_IRQL_PASSIVE();
-
-#if DBG
- WDF_USB_PIPE_INFORMATION pipe_info;
- WDF_USB_PIPE_INFORMATION_INIT(&pipe_info);
- WdfUsbTargetPipeGetInformation(wdf_pipe_obj, &pipe_info);
- ASSERT(WdfUsbPipeTypeInterrupt == pipe_info.PipeType);
-#endif // DBG
-
-}
-
-#pragma code_seg()
-
-AndroidUsbInterruptPipeFileObject::~AndroidUsbInterruptPipeFileObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.h b/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.h
deleted file mode 100755
index 7b23969..0000000
--- a/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_INTERRUPT_PIPE_FILE_OBJECT_H__
-#define ANDROID_USB_INTERRUPT_PIPE_FILE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbInterruptPipeFileObject
- that encapsulates extension to an interrupt pipe file objects.
-*/
-
-#include "android_usb_pipe_file_object.h"
-
-/** AndroidUsbInterruptPipeFileObject class encapsulates extension for a KMDF
- file object that represent opened interrupt pipe. Instances of this class
- must be allocated from NonPagedPool.
-*/
-class AndroidUsbInterruptPipeFileObject : public AndroidUsbPipeFileObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- @param dev_obj[in] Our device object for which this file has been created
- @param wdf_fo[in] KMDF file object this extension wraps
- @param wdf_pipe_obj[in] KMDF pipe for this file
- */
- AndroidUsbInterruptPipeFileObject(AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbInterruptPipeFileObject();
-};
-
-#endif // ANDROID_USB_INTERRUPT_PIPE_FILE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_new_delete.h b/host/windows/usb/legacy/driver/android_usb_new_delete.h
deleted file mode 100755
index d1ca03b..0000000
--- a/host/windows/usb/legacy/driver/android_usb_new_delete.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_NEW_DELETE_H__
-#define ANDROID_USB_NEW_DELETE_H__
-/** \file
- This file consists implementations of our 'new' and 'delete' operators
-*/
-
-#include "android_usb_pool_tags.h"
-
-/** \brief Checks if given pool type is one of NonPaged pool kinds.
-
- All numeric values for all NonPaged pool types are even numbers while all
- numeric values for all PagedPool types are odd numbers (see definition of
- POOL_TYPE enum). So this routine utilizes this to see whether given pool
- type is one of NonPaged pool kinds. This routine can be called at any IRQL.
- @param pool_type[in] Pool type
- @return True if pool type is one of NonPaged pool types, false otherwise
-*/
-__forceinline bool IsPoolNonPaged(POOL_TYPE pool_type) {
- return (0 == (pool_type & 0x1));
-}
-
-/** @name Operators new and delete
-
- In Kernel Mode development each memory allocation must specify type of the
- pool from which memory should be allocated, usualy PagedPool or NonPagedPool.
- Because of that "traditional" operator 'new' that takes only one parameter
- (memory size) is not good so we modify that operator by adding two more
- parameters: pool type and memory tag (last one is optional but highly
- encouraged). To prevent from mistakes, traditional operator 'new' is also
- defined. It will allocate requested number of bytes from NonPagedPool with
- default memory tag but it will always assert on checked (debug) builds.
- Since there is no infrastructure for C++ exceptions in Kernel Mode we are
- not using them to report memory allocation error. So, on failure operators
- 'new' are returning NULL instead of throwing an exception.
-*/
-///@{
-
-/** \brief Main operator new
-
- This is the main operator new that allocates specified number of bytes from
- the specified pool and assigns a custom tag to the allocated memory.
- Inherits IRQL restrictions for ExAllocatePoolWithTag (see the DDK doc).
- @param size[in] Number of bytes to allocate.
- @param pool_type[in] Type of the pool to allocate from.
- @param pool_tag[in] A tag to attach to the allocated memory. Since utilities
- that display tags use their ASCII representations it's advisable to
- use tag values that are ASCII symbols, f.i. 'ATag'. Note that due to
- inversion of bytes in stored ULONG value, to read 'ATag' in the tag
- displaying utility, the actual value passed to operator 'new' must be
- 'gaTA'
- @return Pointer to allocated memory on success, NULL on error.
-*/
-__forceinline void* __cdecl operator new(size_t size,
- POOL_TYPE pool_type,
- ULONG pool_tag) {
- ASSERT((pool_type < MaxPoolType) && (0 != size));
- // Enforce IRQL restriction check.
- ASSERT(IsPoolNonPaged(pool_type) || (KeGetCurrentIrql() < DISPATCH_LEVEL));
- return size ? ExAllocatePoolWithTag(pool_type,
- static_cast<ULONG>(size),
- pool_tag) :
- NULL;
-}
-
-/** \brief
- Short operator new that attaches a default tag to the allocated memory.
-
- This version of operator new allocates specified number of bytes from the
- specified pool and assigns a default tag (GANDR_POOL_TAG_DEFAULT) to the
- allocated memory. Inherits IRQL restrictions for ExAllocatePoolWithTag.
- @param size[in] Number of bytes to allocate.
- @param pool_type[in] Type of the pool to allocate from.
- @return Pointer to allocated memory on success, NULL on error.
-*/
-__forceinline void* __cdecl operator new(size_t size, POOL_TYPE pool_type) {
- ASSERT((pool_type < MaxPoolType) && (0 != size));
- // Enforce IRQL restriction check.
- ASSERT(IsPoolNonPaged(pool_type) || (KeGetCurrentIrql() < DISPATCH_LEVEL));
- return size ? ExAllocatePoolWithTag(pool_type,
- static_cast<ULONG>(size),
- GANDR_POOL_TAG_DEFAULT) :
- NULL;
-}
-
-/** \brief Traditional operator new that should never be used.
-
- Using of this version of operator 'new' is prohibited in Kernel Mode
- development. For the sake of safety it is implemented though to allocate
- requested number of bytes from the NonPagedPool and attach default tag
- to the allocated memory. It will assert on checked (debug) builds.
- Inherits IRQL restrictions for ExAllocatePoolWithTag.
- @param size[in] Number of bytes to allocate.
- @return Pointer to memory allocated from NonPagedPool on success or NULL on
- error.
-*/
-__forceinline void* __cdecl operator new(size_t size) {
- ASSERTMSG("\n!!! Using of operator new(size_t size) is detected!\n"
- "This is illegal in our driver C++ development environment to use "
- "this version of operator 'new'. Please switch to\n"
- "new(size_t size, POOL_TYPE pool_type) or "
- "new(size_t size, POOL_TYPE pool_type, ULONG pool_tag) ASAP!!!\n",
- false);
- ASSERT(0 != size);
- return size ? ExAllocatePoolWithTag(NonPagedPool,
- static_cast<ULONG>(size),
- GANDR_POOL_TAG_DEFAULT) :
- NULL;
-}
-
-/** \brief Operator delete.
-
- Frees memory allocated by 'new' operator.
- @param pointer[in] Memory to free. If this parameter is NULL operator does
- nothing but asserts on checked build. Inherits IRQL restrictions
- for ExFreePool.
-*/
-__forceinline void __cdecl operator delete(void* pointer) {
- ASSERT(NULL != pointer);
- if (NULL != pointer)
- ExFreePool(pointer);
-}
-
-/** \brief Operator delete for arrays.
-
- Frees memory allocated by 'new' operator.
- @param pointer[in] Memory to free. If this parameter is NULL operator does
- nothing but asserts on checked build. Inherits IRQL restrictions
- for ExFreePool.
-*/
-__forceinline void __cdecl operator delete[](void* pointer) {
- ASSERT(NULL != pointer);
- if (NULL != pointer)
- ExFreePool(pointer);
-}
-
-///@}
-
-#endif // ANDROID_USB_NEW_DELETE_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_pipe_file_object.cpp b/host/windows/usb/legacy/driver/android_usb_pipe_file_object.cpp
deleted file mode 100755
index e696b37..0000000
--- a/host/windows/usb/legacy/driver/android_usb_pipe_file_object.cpp
+++ /dev/null
@@ -1,738 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbPipeFileObject that
- encapsulates a common extension for pipe file objects.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_pipe_file_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbPipeFileObject::AndroidUsbPipeFileObject(
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj)
- : AndroidUsbFileObject(AndroidUsbFileObjectTypePipe, dev_obj, wdf_fo),
- wdf_pipe_(wdf_pipe_obj) {
- ASSERT_IRQL_PASSIVE();
- ASSERT(NULL != wdf_pipe_obj);
-}
-
-#pragma code_seg()
-
-AndroidUsbPipeFileObject::~AndroidUsbPipeFileObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-#pragma code_seg("PAGE")
-
-NTSTATUS AndroidUsbPipeFileObject::InitializePipe(
- const WDF_USB_PIPE_INFORMATION* pipe_info) {
- ASSERT_IRQL_LOW();
- ASSERT(IsPipeAttached());
- if (!IsPipeAttached())
- return STATUS_INTERNAL_ERROR;
-
- // Initialize base class
- NTSTATUS status = AndroidUsbFileObject::Initialize();
- ASSERT(NT_SUCCESS(status));
- if (!NT_SUCCESS(status))
- return status;
-
- // Save pipe information
- pipe_information_ = *pipe_info;
-
- // We will provide size check ourselves (less surprizes always better)
- WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(wdf_pipe());
-
- GoogleDbgPrint("\n===== File %p for %s pipe. max_transfer_size = %X, max_packet_size = %X",
- this, is_input_pipe() ? "read" : "write",
- max_transfer_size(), max_packet_size());
- return STATUS_SUCCESS;
-}
-
-#pragma code_seg()
-
-void AndroidUsbPipeFileObject::OnEvtIoRead(WDFREQUEST request,
- size_t length) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // Make sure that this is an input pipe
- if (is_output_pipe()) {
- GoogleDbgPrint("\n!!!! Attempt to read from output pipe %p", this);
- WdfRequestComplete(request, STATUS_ACCESS_DENIED);
- return;
- }
-
- // Make sure zero length I/O doesn't go through
- if (0 == length) {
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
- return;
- }
-
- // Get MDL for this request.
- PMDL request_mdl = NULL;
- NTSTATUS status = WdfRequestRetrieveOutputWdmMdl(request, &request_mdl);
- ASSERT(NT_SUCCESS(status) && (NULL != request_mdl));
- if (NT_SUCCESS(status)) {
- CommonBulkReadWrite(request,
- request_mdl,
- static_cast<ULONG>(length),
- true,
- 0,
- false);
- } else {
- WdfRequestComplete(request, status);
- }
-}
-
-void AndroidUsbPipeFileObject::OnEvtIoWrite(WDFREQUEST request,
- size_t length) {
-
- // Make sure that this is an output pipe
- if (is_input_pipe()) {
- GoogleDbgPrint("\n!!!! Attempt to write to input pipe %p", this);
- WdfRequestComplete(request, STATUS_ACCESS_DENIED);
- return;
- }
-
- // Make sure zero length I/O doesn't go through
- if (0 == length) {
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
- return;
- }
-
- // Get MDL for this request.
- PMDL request_mdl = NULL;
- NTSTATUS status = WdfRequestRetrieveInputWdmMdl(request, &request_mdl);
- ASSERT(NT_SUCCESS(status) && (NULL != request_mdl));
- if (NT_SUCCESS(status)) {
- CommonBulkReadWrite(request,
- request_mdl,
- static_cast<ULONG>(length),
- false,
- 0,
- false);
- } else {
- WdfRequestComplete(request, status);
- }
-}
-
-void AndroidUsbPipeFileObject::OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- switch (ioctl_code) {
- case ADB_IOCTL_GET_ENDPOINT_INFORMATION:
- OnCtlGetEndpointInformation(request, output_buf_len);
- break;
-
- case ADB_IOCTL_BULK_READ:
- OnCtlBulkRead(request, output_buf_len, input_buf_len);
- break;
-
- case ADB_IOCTL_BULK_WRITE:
- OnCtlBulkWrite(request, output_buf_len, input_buf_len);
- break;
-
- default:
- AndroidUsbFileObject::OnEvtIoDeviceControl(request,
- output_buf_len,
- input_buf_len,
- ioctl_code);
- break;
- }
-}
-
-void AndroidUsbPipeFileObject::OnCtlGetEndpointInformation(
- WDFREQUEST request,
- size_t output_buf_len) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // Verify output buffer
- if (output_buf_len < sizeof(AdbEndpointInformation)) {
- WdfRequestCompleteWithInformation(request,
- STATUS_BUFFER_TOO_SMALL,
- sizeof(AdbEndpointInformation));
- return;
- }
-
- // Get the output buffer
- NTSTATUS status;
- AdbEndpointInformation* ret_info =
- reinterpret_cast<AdbEndpointInformation*>(OutAddress(request, &status));
- ASSERT(NT_SUCCESS(status) && (NULL != ret_info));
- if (!NT_SUCCESS(status)) {
- WdfRequestComplete(request, status);
- return;
- }
-
- // Copy endpoint info to the output
- ret_info->max_packet_size = pipe_information_.MaximumPacketSize;
- ret_info->endpoint_address = pipe_information_.EndpointAddress;
- ret_info->polling_interval = pipe_information_.Interval;
- ret_info->setting_index = pipe_information_.SettingIndex;
- ret_info->endpoint_type =
- static_cast<AdbEndpointType>(pipe_information_.PipeType);
- ret_info->max_transfer_size = pipe_information_.MaximumTransferSize;
-
- WdfRequestCompleteWithInformation(request,
- STATUS_SUCCESS,
- sizeof(AdbEndpointInformation));
-}
-
-void AndroidUsbPipeFileObject::OnCtlBulkRead(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // Make sure that this is an input pipe
- if (is_output_pipe()) {
- GoogleDbgPrint("\n!!!! Attempt to IOCTL read from output pipe %p", this);
- WdfRequestComplete(request, STATUS_ACCESS_DENIED);
- return;
- }
-
- // Make sure zero length I/O doesn't go through
- if (0 == output_buf_len) {
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
- return;
- }
-
- // Verify buffers
- ASSERT(input_buf_len >= sizeof(AdbBulkTransfer));
- if (input_buf_len < sizeof(AdbBulkTransfer)) {
- WdfRequestComplete(request, STATUS_INVALID_BUFFER_SIZE);
- return;
- }
-
- // Get the input buffer
- NTSTATUS status;
- AdbBulkTransfer* transfer_param =
- reinterpret_cast<AdbBulkTransfer*>(InAddress(request, &status));
- ASSERT(NT_SUCCESS(status) && (NULL != transfer_param));
- if (!NT_SUCCESS(status)) {
- WdfRequestComplete(request, status);
- return;
- }
-
- // Get MDL for this request.
- PMDL request_mdl = NULL;
- status = WdfRequestRetrieveOutputWdmMdl(request, &request_mdl);
- ASSERT(NT_SUCCESS(status) && (NULL != request_mdl));
- if (NT_SUCCESS(status)) {
- // Perform the read
- CommonBulkReadWrite(request,
- request_mdl,
- static_cast<ULONG>(output_buf_len),
- true,
- transfer_param->time_out,
- true);
- } else {
- WdfRequestComplete(request, status);
- }
-}
-
-void AndroidUsbPipeFileObject::OnCtlBulkWrite(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // Make sure that this is an output pipe
- if (is_input_pipe()) {
- GoogleDbgPrint("\n!!!! Attempt to IOCTL write to input pipe %p", this);
- WdfRequestComplete(request, STATUS_ACCESS_DENIED);
- return;
- }
-
- // Verify buffers
- ASSERT(input_buf_len >= sizeof(AdbBulkTransfer));
- // Output buffer points to ULONG that receives number of transferred bytes
- ASSERT(output_buf_len >= sizeof(ULONG));
- if ((input_buf_len < sizeof(AdbBulkTransfer)) ||
- (output_buf_len < sizeof(ULONG))) {
- WdfRequestComplete(request, STATUS_INVALID_BUFFER_SIZE);
- return;
- }
-
- // Get the input buffer
- NTSTATUS status = STATUS_SUCCESS;
- AdbBulkTransfer* transfer_param =
- reinterpret_cast<AdbBulkTransfer*>(InAddress(request, &status));
- ASSERT(NT_SUCCESS(status) && (NULL != transfer_param));
- if (!NT_SUCCESS(status)) {
- WdfRequestComplete(request, status);
- return;
- }
-
- // Get the output buffer
- ULONG* ret_transfer =
- reinterpret_cast<ULONG*>(OutAddress(request, &status));
- ASSERT(NT_SUCCESS(status) && (NULL != ret_transfer));
- if (!NT_SUCCESS(status)) {
- WdfRequestComplete(request, status);
- return;
- }
-
- // Cache these param to prevent us from sudden change after we've chacked it.
- // This is common practice in protecting ourselves from malicious code:
- // 1. Never trust anything that comes from the User Mode.
- // 2. Never assume that anything that User Mode buffer has will remain
- // unchanged.
- void* transfer_buffer = transfer_param->GetWriteBuffer();
- ULONG transfer_size = transfer_param->transfer_size;
-
- // Make sure zero length I/O doesn't go through
- if (0 == transfer_size) {
- *ret_transfer = 0;
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, sizeof(ULONG));
- return;
- }
-
- // Make sure that buffer is not NULL
- ASSERT(NULL != transfer_buffer);
- if (NULL == transfer_buffer) {
- WdfRequestComplete(request, STATUS_INVALID_PARAMETER);
- return;
- }
-
- // At this point we are ready to build MDL for the user buffer.
- PMDL write_mdl =
- IoAllocateMdl(transfer_buffer, transfer_size, FALSE, FALSE, NULL);
- ASSERT(NULL != write_mdl);
- if (NULL == write_mdl) {
- WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
- return;
- }
-
- // Now we need to probe/lock this mdl
- __try {
- MmProbeAndLockPages(write_mdl,
- WdfRequestGetRequestorMode(request),
- IoReadAccess);
- status = STATUS_SUCCESS;
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- status = GetExceptionCode();
- ASSERTMSG("\n!!!!! AndroidUsbPipeFileObject::OnCtlBulkWrite exception",
- false);
- }
-
- if (!NT_SUCCESS(status)) {
- IoFreeMdl(write_mdl);
- WdfRequestComplete(request, status);
- return;
- }
-
- // Perform the write
- status = CommonBulkReadWrite(request,
- write_mdl,
- transfer_size,
- false,
- transfer_param->time_out,
- true);
- if (!NT_SUCCESS(status)) {
- // If CommonBulkReadWrite failed we need to unlock and free MDL here
- MmUnlockPages(write_mdl);
- IoFreeMdl(write_mdl);
- }
-}
-
-NTSTATUS AndroidUsbPipeFileObject::CommonBulkReadWrite(
- WDFREQUEST request,
- PMDL transfer_mdl,
- ULONG length,
- bool is_read,
- ULONG time_out,
- bool is_ioctl) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- ASSERT(IsPipeAttached());
- if (!IsPipeAttached()) {
- WdfRequestComplete(request, STATUS_INVALID_DEVICE_STATE);
- return STATUS_INVALID_DEVICE_STATE;
- }
-
- // Quick access check. Might be redundant though...
- ASSERT((is_read && is_input_pipe()) || (!is_read && is_output_pipe()));
- if ((is_read && is_output_pipe()) || (!is_read && is_input_pipe())) {
- WdfRequestComplete(request, STATUS_ACCESS_DENIED);
- return STATUS_ACCESS_DENIED;
- }
-
- // Set URB flags
- ULONG urb_flags = USBD_SHORT_TRANSFER_OK | (is_read ?
- USBD_TRANSFER_DIRECTION_IN :
- USBD_TRANSFER_DIRECTION_OUT);
-
- // Calculate transfer length for this stage.
- ULONG stage_len =
- (length > GetTransferGranularity()) ? GetTransferGranularity() : length;
-
- // Get virtual address that we're gonna use in the transfer.
- // We rely here on the fact that we're in the context of the calling thread.
- void* virtual_address = MmGetMdlVirtualAddress(transfer_mdl);
-
- // Allocate our private MDL for this address which we will use for the transfer
- PMDL new_mdl = IoAllocateMdl(virtual_address, length, FALSE, FALSE, NULL);
- ASSERT(NULL != new_mdl);
- if (NULL == new_mdl) {
- WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- // Map the portion of user buffer that we're going to transfer at this stage
- // to our mdl.
- IoBuildPartialMdl(transfer_mdl, new_mdl, virtual_address, stage_len);
-
- // Allocate memory for URB and associate it with this request
- WDF_OBJECT_ATTRIBUTES mem_attrib;
- WDF_OBJECT_ATTRIBUTES_INIT(&mem_attrib);
- mem_attrib.ParentObject = request;
-
- WDFMEMORY urb_mem = NULL;
- PURB urb = NULL;
- NTSTATUS status =
- WdfMemoryCreate(&mem_attrib,
- NonPagedPool,
- GANDR_POOL_TAG_BULKRW_URB,
- sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
- &urb_mem,
- reinterpret_cast<PVOID*>(&urb));
- ASSERT(NT_SUCCESS(status) && (NULL != urb));
- if (!NT_SUCCESS(status)) {
- IoFreeMdl(new_mdl);
- WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- // Get USB pipe handle for our pipe and initialize transfer request for it
- USBD_PIPE_HANDLE usbd_pipe_hndl = usbd_pipe();
- ASSERT(NULL != usbd_pipe_hndl);
- if (NULL == usbd_pipe_hndl) {
- IoFreeMdl(new_mdl);
- WdfRequestComplete(request, STATUS_INTERNAL_ERROR);
- return STATUS_INTERNAL_ERROR;
- }
-
- // Initialize URB with request information
- UsbBuildInterruptOrBulkTransferRequest(
- urb,
- sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
- usbd_pipe_hndl,
- NULL,
- new_mdl,
- stage_len,
- urb_flags,
- NULL);
-
- // Build transfer request
- status = WdfUsbTargetPipeFormatRequestForUrb(wdf_pipe(),
- request,
- urb_mem,
- NULL);
- ASSERT(NT_SUCCESS(status));
- if (!NT_SUCCESS(status)) {
- IoFreeMdl(new_mdl);
- WdfRequestComplete(request, status);
- return status;
- }
-
- // Initialize our request context.
- AndroidUsbWdfRequestContext* context =
- GetAndroidUsbWdfRequestContext(request);
- ASSERT(NULL != context);
- if (NULL == context) {
- IoFreeMdl(new_mdl);
- WdfRequestComplete(request, STATUS_INTERNAL_ERROR);
- return STATUS_INTERNAL_ERROR;
- }
-
- context->object_type = AndroidUsbWdfObjectTypeRequest;
- context->urb_mem = urb_mem;
- context->transfer_mdl = transfer_mdl;
- context->mdl = new_mdl;
- context->length = length;
- context->transfer_size = stage_len;
- context->num_xfer = 0;
- context->virtual_address = virtual_address;
- context->is_read = is_read;
- context->initial_time_out = time_out;
- context->is_ioctl = is_ioctl;
-
- // Set our completion routine
- WdfRequestSetCompletionRoutine(request,
- CommonReadWriteCompletionEntry,
- this);
-
- // Init send options (our timeout goes here)
- WDF_REQUEST_SEND_OPTIONS send_options;
- if (0 != time_out) {
- WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_TIMEOUT);
- WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&send_options, WDF_REL_TIMEOUT_IN_MS(time_out));
- }
-
- // Timestamp first WdfRequestSend
- KeQuerySystemTime(&context->sent_at);
-
- // Send request asynchronously.
- if (WdfRequestSend(request, wdf_pipe_io_target(),
- (0 == time_out) ? WDF_NO_SEND_OPTIONS : &send_options)) {
- return STATUS_SUCCESS;
- }
-
- // Something went wrong here
- status = WdfRequestGetStatus(request);
- ASSERT(!NT_SUCCESS(status));
- GoogleDbgPrint("\n!!!!! CommonBulkReadWrite: WdfRequestGetStatus (is_read = %u) failed: %08X",
- is_read, status);
- WdfRequestCompleteWithInformation(request, status, 0);
-
- return status;
-}
-
-void AndroidUsbPipeFileObject::OnCommonReadWriteCompletion(
- WDFREQUEST request,
- PWDF_REQUEST_COMPLETION_PARAMS completion_params,
- AndroidUsbWdfRequestContext* context) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- NTSTATUS status = completion_params->IoStatus.Status;
- if (!NT_SUCCESS(status)){
- GoogleDbgPrint("\n========== Request completed with failure: %X", status);
- IoFreeMdl(context->mdl);
- // If this was IOCTL-originated write we must unlock and free
- // our transfer MDL.
- if (context->is_ioctl && !context->is_read) {
- MmUnlockPages(context->transfer_mdl);
- IoFreeMdl(context->transfer_mdl);
- }
- WdfRequestComplete(request, status);
- return;
- }
-
- // Get our URB buffer
- PURB urb
- = reinterpret_cast<PURB>(WdfMemoryGetBuffer(context->urb_mem, NULL));
- ASSERT(NULL != urb);
-
- // Lets see how much has been transfered and update our counters accordingly
- ULONG bytes_transfered =
- urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
- // We expect writes to transfer entire packet
- ASSERT((bytes_transfered == context->transfer_size) || context->is_read);
- context->num_xfer += bytes_transfered;
- context->length -= bytes_transfered;
-
- // Is there anything left to transfer? Now, by the protocol we should
- // successfuly complete partial reads, instead of waiting on full set
- // of requested bytes being accumulated in the read buffer.
- if ((0 == context->length) || context->is_read) {
- status = STATUS_SUCCESS;
-
- // This was the last transfer
- if (context->is_ioctl && !context->is_read) {
- // For IOCTL-originated writes we have to return transfer size through
- // the IOCTL's output buffer.
- ULONG* ret_transfer =
- reinterpret_cast<ULONG*>(OutAddress(request, NULL));
- ASSERT(NULL != ret_transfer);
- if (NULL != ret_transfer)
- *ret_transfer = context->num_xfer;
- WdfRequestSetInformation(request, sizeof(ULONG));
-
- // We also must unlock / free transfer MDL
- MmUnlockPages(context->transfer_mdl);
- IoFreeMdl(context->transfer_mdl);
- } else {
- // For other requests we report transfer size through the request I/O
- // completion status.
- WdfRequestSetInformation(request, context->num_xfer);
- }
- IoFreeMdl(context->mdl);
- WdfRequestComplete(request, status);
- return;
- }
-
- // There are something left for the transfer. Prepare for it.
- // Required to free any mapping made on the partial MDL and
- // reset internal MDL state.
- MmPrepareMdlForReuse(context->mdl);
-
- // Update our virtual address
- context->virtual_address =
- reinterpret_cast<char*>(context->virtual_address) + bytes_transfered;
-
- // Calculate size of this transfer
- ULONG stage_len =
- (context->length > GetTransferGranularity()) ? GetTransferGranularity() :
- context->length;
-
- IoBuildPartialMdl(context->transfer_mdl,
- context->mdl,
- context->virtual_address,
- stage_len);
-
- // Reinitialize the urb and context
- urb->UrbBulkOrInterruptTransfer.TransferBufferLength = stage_len;
- context->transfer_size = stage_len;
-
- // Format the request to send a URB to a USB pipe.
- status = WdfUsbTargetPipeFormatRequestForUrb(wdf_pipe(),
- request,
- context->urb_mem,
- NULL);
- ASSERT(NT_SUCCESS(status));
- if (!NT_SUCCESS(status)) {
- if (context->is_ioctl && !context->is_read) {
- MmUnlockPages(context->transfer_mdl);
- IoFreeMdl(context->transfer_mdl);
- }
- IoFreeMdl(context->mdl);
- WdfRequestComplete(request, status);
- return;
- }
-
- // Reset the completion routine
- WdfRequestSetCompletionRoutine(request,
- CommonReadWriteCompletionEntry,
- this);
-
- // Send the request asynchronously.
- if (!WdfRequestSend(request, wdf_pipe_io_target(), WDF_NO_SEND_OPTIONS)) {
- if (context->is_ioctl && !context->is_read) {
- MmUnlockPages(context->transfer_mdl);
- IoFreeMdl(context->transfer_mdl);
- }
- status = WdfRequestGetStatus(request);
- IoFreeMdl(context->mdl);
- WdfRequestComplete(request, status);
- }
-}
-
-NTSTATUS AndroidUsbPipeFileObject::ResetPipe() {
- ASSERT_IRQL_PASSIVE();
-
- // This routine synchronously submits a URB_FUNCTION_RESET_PIPE
- // request down the stack.
- NTSTATUS status = WdfUsbTargetPipeAbortSynchronously(wdf_pipe(),
- WDF_NO_HANDLE,
- NULL);
- if (NT_SUCCESS(status)) {
- status = WdfUsbTargetPipeResetSynchronously(wdf_pipe(),
- WDF_NO_HANDLE,
- NULL);
- if (!NT_SUCCESS(status))
- GoogleDbgPrint("\n!!!!! AndroidUsbPipeFileObject::ResetPipe failed %X", status);
- } else {
- GoogleDbgPrint("\n!!!!! WdfUsbTargetPipeAbortSynchronously failed %X", status);
- }
-
- return status;
-}
-
-NTSTATUS AndroidUsbPipeFileObject::QueueResetPipePassiveCallback() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // Initialize workitem
- WDF_OBJECT_ATTRIBUTES attr;
- WDF_OBJECT_ATTRIBUTES_INIT(&attr);
- WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attr, AndroidUsbWorkitemContext);
- attr.ParentObject = wdf_device();
-
- WDFWORKITEM wdf_work_item = NULL;
- WDF_WORKITEM_CONFIG workitem_config;
- WDF_WORKITEM_CONFIG_INIT(&workitem_config, ResetPipePassiveCallbackEntry);
- NTSTATUS status = WdfWorkItemCreate(&workitem_config,
- &attr,
- &wdf_work_item);
- ASSERT(NT_SUCCESS(status) && (NULL != wdf_work_item));
- if (!NT_SUCCESS(status))
- return status;
-
- // Initialize our extension to work item
- AndroidUsbWorkitemContext* context =
- GetAndroidUsbWorkitemContext(wdf_work_item);
- ASSERT(NULL != context);
- if (NULL == context) {
- WdfObjectDelete(wdf_work_item);
- return STATUS_INTERNAL_ERROR;
- }
-
- context->object_type = AndroidUsbWdfObjectTypeWorkitem;
- context->pipe_file_ext = this;
-
- // Enqueue this work item.
- WdfWorkItemEnqueue(wdf_work_item);
-
- return STATUS_SUCCESS;
-}
-
-void AndroidUsbPipeFileObject::CommonReadWriteCompletionEntry(
- WDFREQUEST request,
- WDFIOTARGET wdf_target,
- PWDF_REQUEST_COMPLETION_PARAMS completion_params,
- WDFCONTEXT completion_context) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- AndroidUsbWdfRequestContext*
- context = GetAndroidUsbWdfRequestContext(request);
- ASSERT((NULL != context) && (AndroidUsbWdfObjectTypeRequest == context->object_type));
-
- AndroidUsbPipeFileObject* pipe_file_ext =
- reinterpret_cast<AndroidUsbPipeFileObject*>(completion_context);
- ASSERT((NULL != pipe_file_ext) &&
- (pipe_file_ext->wdf_pipe() == (WDFUSBPIPE)wdf_target));
-
- pipe_file_ext->OnCommonReadWriteCompletion(request,
- completion_params,
- context);
-}
-
-void AndroidUsbPipeFileObject::ResetPipePassiveCallbackEntry(
- WDFWORKITEM wdf_work_item) {
- ASSERT_IRQL_PASSIVE();
-
- AndroidUsbWorkitemContext* context =
- GetAndroidUsbWorkitemContext(wdf_work_item);
- ASSERT((NULL != context) &&
- (AndroidUsbWdfObjectTypeWorkitem == context->object_type));
- if ((NULL == context) ||
- (AndroidUsbWdfObjectTypeWorkitem != context->object_type)) {
- WdfObjectDelete(wdf_work_item);
- return;
- }
-
- // In the sample they reset the device if pipe reset failed
- AndroidUsbDeviceObject* wdf_device_ext =
- context->pipe_file_ext->device_object();
-
- NTSTATUS status = context->pipe_file_ext->ResetPipe();
- if (!NT_SUCCESS(status))
- status = wdf_device_ext->ResetDevice();
-
- WdfObjectDelete(wdf_work_item);
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_pipe_file_object.h b/host/windows/usb/legacy/driver/android_usb_pipe_file_object.h
deleted file mode 100755
index ce02d25..0000000
--- a/host/windows/usb/legacy/driver/android_usb_pipe_file_object.h
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_PIPE_FILE_OBJECT_H__
-#define ANDROID_USB_PIPE_FILE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbPipeFileObject that
- encapsulates a common extension for pipe file objects.
-*/
-
-#include "android_usb_file_object.h"
-
-/** AndroidUsbPipeFileObject class encapsulates extension for a KMDF file
- object that represents opened pipe. Instances of this class must be
- allocated from NonPagedPool.
-*/
-class AndroidUsbPipeFileObject : public AndroidUsbFileObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- @param dev_obj[in] Our device object for which this file has been created
- @param wdf_fo[in] KMDF file object this extension wraps
- @param wdf_pipe_obj[in] KMDF pipe for this file
- */
- AndroidUsbPipeFileObject(AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbPipeFileObject();
-
- /** \brief Initializes the pipe file object extension
-
- This method internally calls AndroidUsbFileObject::Initialize()
- This method must be called at low IRQL
- @param pipe_info[in] Pipe information
- @return STATUS_SUCCESS or an appropriate error code
- */
- virtual NTSTATUS InitializePipe(const WDF_USB_PIPE_INFORMATION* pipe_info);
-
- /** \brief Read event handler
-
- This method is called when a read request comes to the file object this
- extension wraps. This method is an override.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be read.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoRead(WDFREQUEST request, size_t length);
-
- /** \brief Write event handler
-
- This method is called when a write request comes to the file object this
- extension wraps. This method is an override.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be written.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoWrite(WDFREQUEST request, size_t length);
-
- /** \brief IOCTL event handler
-
- This method is called when a device control request comes to the file
- object this extension wraps. We hanlde the following IOCTLs here:
- 1. ADB_CTL_GET_ENDPOINT_INFORMATION
- 2. ADB_CTL_BULK_READ
- 3. ADB_CTL_BULK_WRITE
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param ioctl_code[in] The driver-defined or system-defined I/O control code
- that is associated with the request.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code);
-
- protected:
- /** \brief Handler for ADB_CTL_GET_ENDPOINT_INFORMATION IOCTL request
-
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- virtual void OnCtlGetEndpointInformation(WDFREQUEST request,
- size_t output_buf_len);
-
- /** \brief Handler for ADB_CTL_BULK_READ IOCTL request
-
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- */
- virtual void OnCtlBulkRead(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len);
-
- /** \brief Handler for ADB_CTL_BULK_WRITE IOCTL request
-
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- */
- virtual void OnCtlBulkWrite(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len);
-
- /** \brief Performs common bulk read / write on the pipe
-
- This method is called from bulk and interrupt pipe file extensions to
- perform read to / write from the pipe this file represents. Typicaly,
- this method is called from OnEvtIoRead / OnEvtIoWrite /
- OnEvtIoDeviceControl methods. One very special case for this method is
- IOCTL-originated write request. If this is IOCTL-originated write request
- we can't report transfer size through the request's status block. Instead,
- for IOCTL-originated writes, the output buffer must a) exist and b) point
- to an ULONG that will receive size of the transfer. Besides, for this type
- of writes we create / lock write buffer MDL ourselves so we need to unlock
- and free it in the completion routine.
- This method can be called at IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param transfer_mdl[in] MDL for the transferring buffer. The MDL must be
- locked prior to this call.
- @param length[in] The number of bytes to be read / written. If this method
- is actually IOCTL originated write request this parameter must be
- taken from AdbBulkTransfer.transfer_size by the caller of this
- method. AdbBulkTransfer is available at the beginning of the input
- buffer for bulk read / write IOCTLs.
- @param is_read[in] If true this is a read operation, otherwise it's write
- operation.
- @param time_out[in] Number of milliseconds for this request to complete.
- If this parameter is zero there will be no timeout associated with
- the request. Otherwise, if request doesn't complete within the given
- timeframe it will be cancelled.
- @param is_ioctl[in] If 'true' this method has been called from IOCTL
- handler. Otherwise it has been called from read / write handler. If
- this is IOCTL-originated write request we need to report bytes
- transferred through the IOCTL's output buffer.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @return STATUS_SUCCESS or an appropriate error code
- */
- virtual NTSTATUS CommonBulkReadWrite(WDFREQUEST request,
- PMDL transfer_mdl,
- ULONG length,
- bool is_read,
- ULONG time_out,
- bool is_ioctl);
-
- /** \brief Handles request completion for CommonBulkReadWrite
-
- This method is called from CommonReadWriteCompletionEntry.
- This method can be called at IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object that is being
- completed.
- @param params[in] A pointer to a WDF_REQUEST_COMPLETION_PARAMS structure
- that contains information about the completed request.
- @param context[in] Context associated with this request in
- CommonBulkReadWrite
- This method can be called IRQL <= DISPATCH_LEVEL.
- */
- virtual void OnCommonReadWriteCompletion(WDFREQUEST request,
- PWDF_REQUEST_COMPLETION_PARAMS completion_params,
- AndroidUsbWdfRequestContext* context);
-
- /** \brief Resets pipe associated with this file
-
- After reseting the pipe this object might be destroyed.
- This method must be called at PASSIVE IRQL.
- @param read_device_on_failure[in] If true and reset pipe has failed this
- method will attempt to reset the device.
- @return STATUS_SUCCESS on success or an appropriate error code
- */
- virtual NTSTATUS ResetPipe();
-
- /** \brief Queues a workitem to launch pipe reset at PASSIVE IRQL
-
- This method can be called at IRQL <= DISPATCH_LEVEL.
- @return STATUS_SUCCESS or an appropriate error code.
- */
- virtual NTSTATUS QueueResetPipePassiveCallback();
-
- private:
- /** \brief Request completion routine for CommonBulkReadWrite
-
- This method can be called at IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object that is being
- completed.
- @param wdf_target[in] A handle to an I/O target object that represents the
- I/O target that completed the request. In this case this is a pipe.
- @param params[in] A pointer to a WDF_REQUEST_COMPLETION_PARAMS structure
- that contains information about the completed request.
- @param completion_context[in] A handle to driver-supplied context
- information, which the driver specified in a previous call to
- WdfRequestSetCompletionRoutine. In our case this is a pointer
- to this class instance that issued the request.
- This method can be called IRQL <= DISPATCH_LEVEL.
- */
- static void CommonReadWriteCompletionEntry(WDFREQUEST request,
- WDFIOTARGET wdf_target,
- PWDF_REQUEST_COMPLETION_PARAMS params,
- WDFCONTEXT completion_context);
-
- /** \brief Entry point for pipe reset workitem callback
-
- This method is called at PASSIVE IRQL
- @param wdf_work_item[in] A handle to a framework work item object.
- */
- static void ResetPipePassiveCallbackEntry(WDFWORKITEM wdf_work_item);
-
- public:
- /// Gets KMDF pipe handle for this file
- __forceinline WDFUSBPIPE wdf_pipe() const {
- return wdf_pipe_;
- }
-
- /// Gets maximum transfer size for this pipe
- __forceinline ULONG max_transfer_size() const {
- ASSERT(0 != pipe_information_.MaximumTransferSize);
- return pipe_information_.MaximumTransferSize;
- }
-
- /// Gets maximum packet size this pipe is capable of
- __forceinline ULONG max_packet_size() const {
- ASSERT(0 != pipe_information_.MaximumPacketSize);
- return pipe_information_.MaximumPacketSize;
- }
-
- /// Gets transfer granularity
- // TODO: It looks like device USB is capable of handling
- // packets with size greater than pipe_information_.MaximumPacketSize!
- // So, looks like we are not bound by this parameter in this driver.
- __forceinline ULONG GetTransferGranularity() const {
- return max_transfer_size();
- }
-
- /// Checks if this is an input pipe
- __forceinline bool is_input_pipe() const {
- return WDF_USB_PIPE_DIRECTION_IN(pipe_information_.EndpointAddress) ?
- true : false;
- }
-
- /// Checks if this is an output pipe
- __forceinline bool is_output_pipe() const {
- return WDF_USB_PIPE_DIRECTION_OUT(pipe_information_.EndpointAddress) ?
- true : false;
- }
-
- /// Checks if pipe is attached to this file
- __forceinline bool IsPipeAttached() const {
- return (NULL != wdf_pipe());
- }
-
- /// Gets USBD pipe handle
- // TODO: Can we cache this?
- __forceinline USBD_PIPE_HANDLE usbd_pipe() const {
- ASSERT(IsPipeAttached());
- return (IsPipeAttached()) ? WdfUsbTargetPipeWdmGetPipeHandle(wdf_pipe()) :
- NULL;
- }
-
- /// Gets I/O target handle for this pipe
- // TODO: Can we cache this?
- __forceinline WDFIOTARGET wdf_pipe_io_target() const {
- ASSERT(IsPipeAttached());
- return (IsPipeAttached()) ? WdfUsbTargetPipeGetIoTarget(wdf_pipe()) :
- NULL;
- }
-
- protected:
- /// Cached pipe information
- WDF_USB_PIPE_INFORMATION pipe_information_;
-
- /// KMDF pipe handle for this file
- WDFUSBPIPE wdf_pipe_;
-};
-
-#endif // ANDROID_USB_PIPE_FILE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_pool_tags.h b/host/windows/usb/legacy/driver/android_usb_pool_tags.h
deleted file mode 100755
index 7e52e84..0000000
--- a/host/windows/usb/legacy/driver/android_usb_pool_tags.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_POOL_TAGS_H__
-#define ANDROID_USB_POOL_TAGS_H__
-/** \file
- This file consists definitions for pool tags used in memory allocations for
- the driver.
-*/
-
-/// Default pool tag for memory allocations (GAND)
-#define GANDR_POOL_TAG_DEFAULT 'DNAG'
-
-/// Pool tag for the driver object (GADR)
-#define GANDR_POOL_TAG_DRIVER_OBJECT 'RDAG'
-
-/// Pool tag for KMDF device object extension (GADx)
-#define GANDR_POOL_TAG_KMDF_DEVICE 'xDAG'
-
-/// Pool tag for target device configuration descriptor (GACD)
-#define GANDR_POOL_TAG_DEV_CFG_DESC 'DCAG'
-
-/// Pool tag for device file object extension (GADf)
-#define GANDR_POOL_TAG_DEVICE_FO 'fDAG'
-
-/// Pool tag for a bulk file object extension (GABx)
-#define GANDR_POOL_TAG_BULK_FILE 'xBAG'
-
-/// Pool tag for an interrupt file object extension (GAIx)
-#define GANDR_POOL_TAG_INTERRUPT_FILE 'xIAG'
-
-/// Pool tag for URB allocated in bulk read / write (GAbu)
-#define GANDR_POOL_TAG_BULKRW_URB 'ubAG'
-
-/// Pool tag for interface pairs (GAip)
-#define GANDR_POOL_TAG_INTERF_PAIRS 'piAG'
-
-#endif // ANDROID_USB_POOL_TAGS_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_wdf_object.cpp b/host/windows/usb/legacy/driver/android_usb_wdf_object.cpp
deleted file mode 100755
index 7210be6..0000000
--- a/host/windows/usb/legacy/driver/android_usb_wdf_object.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-/** \file
- This file consists of implementation of a class AndroidUsbWdfObject that
- encapsulates a basic extension to all KMDF objects. Currently, device and
- file object extensions ared derived from it.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_wdf_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbWdfObject::AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type)
- : wdf_object_(NULL),
- object_type_(obj_type) {
- ASSERT_IRQL_LOW();
- ASSERT(obj_type < AndroidUsbWdfObjectTypeMax);
-}
-
-#pragma code_seg()
-
-AndroidUsbWdfObject::~AndroidUsbWdfObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-#pragma code_seg("PAGE")
-
-NTSTATUS AndroidUsbWdfObject::InitObjectAttributes(
- PWDF_OBJECT_ATTRIBUTES wdf_obj_attr,
- WDFOBJECT parent) {
- ASSERT_IRQL_LOW();
-
- // Enforce file object extension exception.
- ASSERT(!Is(AndroidUsbWdfObjectTypeFile));
- if (Is(AndroidUsbWdfObjectTypeFile))
- return STATUS_INTERNAL_ERROR;
-
- // Initialize attributes and set cleanup and destroy callbacks
- WDF_OBJECT_ATTRIBUTES_INIT(wdf_obj_attr);
- WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(wdf_obj_attr,
- AndroidUsbWdfObjectContext);
- wdf_obj_attr->EvtCleanupCallback = EvtCleanupCallbackEntry;
- wdf_obj_attr->EvtDestroyCallback = EvtDestroyCallbackEntry;
- wdf_obj_attr->ParentObject = parent;
- wdf_obj_attr->SynchronizationScope = GetWdfSynchronizationScope();
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS AndroidUsbWdfObject::InitializeContext() {
- ASSERT_IRQL_LOW();
- ASSERT(IsAttached());
- if (!IsAttached())
- return STATUS_INTERNAL_ERROR;
-
- // Initialize our extension to that object
- AndroidUsbWdfObjectContext* context =
- GetAndroidUsbWdfObjectContext(wdf_object());
- ASSERT(NULL != context);
- if (NULL == context)
- return STATUS_INTERNAL_ERROR;
-
- // Make sure that extension has not been initialized
- ASSERT((0 == context->object_type) && (NULL == context->wdf_object_ext));
- if ((0 != context->object_type) || (NULL != context->wdf_object_ext))
- return STATUS_INTERNAL_ERROR;
-
- context->object_type = object_type();
- context->wdf_object_ext = this;
- ASSERT(this == GetAndroidUsbWdfObjectFromHandle(wdf_object()));
-
- return STATUS_SUCCESS;
-}
-
-#pragma code_seg()
-
-WDF_SYNCHRONIZATION_SCOPE AndroidUsbWdfObject::GetWdfSynchronizationScope() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // By default we don't want KMDF to synchronize access to our objects
- return WdfSynchronizationScopeNone;
-}
-
-void AndroidUsbWdfObject::OnEvtCleanupCallback() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
- GoogleDbgPrint("\n----- Object %p of type %u is cleaned up",
- this, object_type());
-}
-
-void AndroidUsbWdfObject::OnEvtDestroyCallback() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
- GoogleDbgPrint("\n----- Object %p of type %u is destroyed",
- this, object_type());
-}
-
-void AndroidUsbWdfObject::EvtCleanupCallbackEntry(WDFOBJECT wdf_obj) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- AndroidUsbWdfObjectContext* context = GetAndroidUsbWdfObjectContext(wdf_obj);
- ASSERT(NULL != context);
- if (NULL != context) {
- // For file objects we will be always called here even though we didn't
- // create any extension for them. In this case the context must not be
- // initialized.
- ASSERT(((0 == context->object_type) && (NULL == context->wdf_object_ext)) ||
- ((0 != context->object_type) && (NULL != context->wdf_object_ext)));
- if (NULL != context->wdf_object_ext) {
- ASSERT(context->wdf_object_ext->Is(context->object_type));
- context->wdf_object_ext->OnEvtCleanupCallback();
- }
- }
-}
-
-void AndroidUsbWdfObject::EvtDestroyCallbackEntry(WDFOBJECT wdf_obj) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- AndroidUsbWdfObjectContext* context =
- GetAndroidUsbWdfObjectContext(wdf_obj);
- ASSERT(NULL != context);
- if (NULL != context) {
- // For file objects we will be always called here even though we didn't
- // create any extension for them. In this case the context must not be
- // initialized.
- ASSERT(((0 == context->object_type) && (NULL == context->wdf_object_ext)) ||
- ((0 != context->object_type) && (NULL != context->wdf_object_ext)));
- if (NULL != context->wdf_object_ext) {
- ASSERT(context->wdf_object_ext->Is(context->object_type));
- context->wdf_object_ext->OnEvtDestroyCallback();
- delete context->wdf_object_ext;
- }
- }
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_wdf_object.h b/host/windows/usb/legacy/driver/android_usb_wdf_object.h
deleted file mode 100755
index d5e814c..0000000
--- a/host/windows/usb/legacy/driver/android_usb_wdf_object.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef ANDROID_USB_WDF_OBJECT_H__
-#define ANDROID_USB_WDF_OBJECT_H__
-/** \file
- This file consists of declaration of a class AndroidUsbWdfObject that
- encapsulates a basic extension to all KMDF objects. Currently, device and
- file object extensions ared derived from it.
-*/
-
-/** AndroidUsbWdfObject class encapsulates a basic extension to all KMDF
- objects. Currently, device and file object extensions ared derived from it.
- Instances of this and derived classes must be allocated from NonPagedPool.
-*/
-class AndroidUsbWdfObject {
- public:
- /** \brief Constructs the object.
-
- @param obj_type[in] Type of the object that this wrapper represents.
- This method must be called at low IRQL.
- */
- AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbWdfObject();
-
- /** \brief Initializes object attributes for new KMDF object.
-
- Each KMDF extension object must perform attribute initializations in order
- to register an extension with KMDF framework. Since all our extensions are
- derived from the base AndroidUsbWdfObject we use a single WDF object
- extension context for all KMDF objects that we extend. So we can initialize
- and register our context extension structure here. Note that object
- attributes for file object wrappers are initialized globaly, when device
- object is created. So file object extensions must not call this method.
- This method must be called at low IRQL.
- @param wdf_obj_attr[out] Object attributes to initialize.
- @param parent[in] Parent object for this object. Can be NULL.
- @return STATUS_SUCCESS on success or an appropriate error code.
- */
- virtual NTSTATUS InitObjectAttributes(PWDF_OBJECT_ATTRIBUTES wdf_obj_attr,
- WDFOBJECT parent);
-
- /** \brief Initializes context for this extension
-
- This method initializes AndroidUsbWdfObjectContext structure that KMDF
- allocated for the object that is being extended with this class.
- InitObjectAttributes method must be called prior to the call to this
- method. Besides, before calling this method, instance of this class must
- be already attached to the KMDF object it represents. Otherwise this
- method will fail with STATUS_INTERNAL_ERROR.
- This method must be called at low IRQL.
- @return STATUS_SUCCESS on success or an appropriate error code
- */
- virtual NTSTATUS InitializeContext();
-
-
- protected:
- /** \brief Returns syncronisation scope for this extension type.
-
- This method is called from InitObjectAttributes method to specify what
- type of synchronization is required for instances of this type. By
- default we return WdfSynchronizationScopeNone which makes KMDF not
- to synchronize access to this type of object.
- This method can be called at IRQL <= DISPATCH_LEVEL.
- */
- virtual WDF_SYNCHRONIZATION_SCOPE GetWdfSynchronizationScope();
-
- /** \brief Handler for cleanup event fired for associated KMDF object.
-
- The framework calls this callback function when either the framework or a
- driver attempts to delete the object.
- This method can be called at IRQL <= DISPATCH_LEVEL.
- */
- virtual void OnEvtCleanupCallback();
-
- /** \brief Handler for destroy callback
-
- The framework calls the EvtDestroyCallback callback function after the
- object's reference count has been decremented to zero. The framework
- deletes the object immediately after the EvtDestroyCallback callback
- function returns.
- This callback can be called at IRQL <= DISPATCH_LEVEL.
- */
- virtual void OnEvtDestroyCallback();
-
- /** \brief Removes driver's references on an object so it can be deleted.
-
- The framework calls the callback function when either the framework or a
- driver attempts to delete the object.
- This callback can be called at IRQL <= DISPATCH_LEVEL.
- @param wdf_obj[in] A handle to a framework object this class wraps.
- */
- static void EvtCleanupCallbackEntry(WDFOBJECT wdf_obj);
-
- /** \brief Called when framework object is being deleted
-
- The framework calls the EvtDestroyCallback callback function after the
- object's reference count has been decremented to zero. The framework
- deletes the object immediately after the EvtDestroyCallback callback
- function returns.
- This callback can be called at IRQL <= DISPATCH_LEVEL.
- @param wdf_obj[in] A handle to a framework object this class wraps.
- */
- static void EvtDestroyCallbackEntry(WDFOBJECT wdf_obj);
-
- public:
-
- /// Gets KMDF object extended with this instance
- __forceinline WDFOBJECT wdf_object() const {
- return wdf_object_;
- }
-
- /// Sets KMDF object associated with this extension
- __forceinline void set_wdf_object(WDFOBJECT wdf_obj) {
- ASSERT(NULL == wdf_object_);
- wdf_object_ = wdf_obj;
- }
-
- /// Gets KMDF object type for this extension
- __forceinline AndroidUsbWdfObjectType object_type() const {
- return object_type_;
- }
-
- /** \brief Checks if this extension represends KMDF object of the given type
-
- @param obj_type[in] Object type to check
- @return true if this wrapper represents object of that type and
- false otherwise.
- */
- __forceinline Is(AndroidUsbWdfObjectType obj_type) const {
- return (obj_type == object_type());
- }
-
- /// Checks if extension is attached to a KMDF object
- __forceinline bool IsAttached() const {
- return (NULL != wdf_object());
- }
-
- protected:
- /// KMDF object that is extended with this instance
- WDFOBJECT wdf_object_;
-
- /// KMDF object type for this extension
- AndroidUsbWdfObjectType object_type_;
-};
-
-/** \brief Gets our extension for the given KMDF object
-
- This method can be called at any IRQL
- @param wdf_obj[in] KMDF handle describing an object
- @return Instance of AndroidUsbWdfObject associated with this object or NULL
- if association is not found.
-*/
-__forceinline AndroidUsbWdfObject* GetAndroidUsbWdfObjectFromHandle(
- WDFOBJECT wdf_obj) {
- ASSERT(NULL != wdf_obj);
- if (NULL != wdf_obj) {
- AndroidUsbWdfObjectContext* context =
- GetAndroidUsbWdfObjectContext(wdf_obj);
- ASSERT((NULL != context) && (NULL != context->wdf_object_ext) &&
- (context->wdf_object_ext->Is(context->object_type)));
- if ((NULL != context) && (NULL != context->wdf_object_ext) &&
- context->wdf_object_ext->Is(context->object_type)) {
- return context->wdf_object_ext;
- }
- }
- return NULL;
-}
-
-#endif // ANDROID_USB_WDF_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/makefile b/host/windows/usb/legacy/driver/makefile
deleted file mode 100755
index 54a4d7b..0000000
--- a/host/windows/usb/legacy/driver/makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-!IF 0
-
-Copyright (C) 2006 The Android Open Source Project
-
-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.
-
-Module Name:
-
- makefile.
-
-Notes:
-
- DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
- file to this component. This file merely indirects to the real make file
- that is shared by all the components of Windows NT (DDK)
-
-!ENDIF
-
-!if "$(DDK_TARGET_OS)"=="Win2K"
-!message This driver is not intended to target the Windows 2000 platform.
-!elseif "$(DDK_TARGET_OS)"=="WinNET"
-!INCLUDE $(NTMAKEENV)\makefile.def
-!else
-!INCLUDE $(NTMAKEENV)\makefile.def
-!endif
-
diff --git a/host/windows/usb/legacy/driver/makefile.inc b/host/windows/usb/legacy/driver/makefile.inc
deleted file mode 100755
index ca0dbd3..0000000
--- a/host/windows/usb/legacy/driver/makefile.inc
+++ /dev/null
@@ -1,7 +0,0 @@
-_LNG=$(LANGUAGE)
-_INX=.
-STAMP=stampinf -f $@ -a $(_BUILDARCH)
-
-$(OBJ_PATH)\$(O)\$(INF_NAME).inf: $(_INX)\$(INF_NAME).inx
- copy $(_INX)\$(@B).inx $@
- $(STAMP)
diff --git a/host/windows/usb/legacy/driver/precomp.h b/host/windows/usb/legacy/driver/precomp.h
deleted file mode 100755
index bc798bc..0000000
--- a/host/windows/usb/legacy/driver/precomp.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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.
- */
-
-/** \file
- Standard precompile file
-*/
-#pragma warning(disable:4200)
-#pragma warning(disable:4201) // nameless struct/union
-#pragma warning(disable:4214) // bit field types other than int
-extern "C" {
-#include <initguid.h>
-#include <ntddk.h>
-#include <ntintsafe.h>
-#include <ntstrsafe.h>
-#include "usbdi.h"
-#include "usbdlib.h"
-#include <wdf.h>
-#include <wdfusb.h>
-} // extern "C"
-#pragma warning(default:4200)
-#pragma warning(default:4201)
-#pragma warning(default:4214)
-
-// Just to make adb_api.h compile. Since we will not reference any
-// of the API routines in the driver, only structures and constants,
-// we're fine with that.
-typedef void* LPOVERLAPPED;
-
-#include "adb_api.h"
-#include "adb_api_legacy.h"
-#include "android_usb_pool_tags.h"
-#include "android_usb_driver_defines.h"
-#include "android_usb_new_delete.h"
-#include "android_usb_inl.h"
diff --git a/host/windows/usb/legacy/driver/sources b/host/windows/usb/legacy/driver/sources
deleted file mode 100755
index 20dcc18..0000000
--- a/host/windows/usb/legacy/driver/sources
+++ /dev/null
@@ -1,32 +0,0 @@
-!IF 0
-
-Copyright (C) 2007 The Android Open Source Project
-
-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.
-
-Module Name:
-
- sources.
-
-Abstract:
-
- This file specifies the target component being built and the list of
- sources files needed to build that component. Also specifies optional
- compiler switches and libraries that are unique for the component being
- built.
-
-!ENDIF
-
-!include sources.inc
-
-SOURCES= $(MOST_SOURCES) android_usb.rc
diff --git a/host/windows/usb/legacy/driver/sources.inc b/host/windows/usb/legacy/driver/sources.inc
deleted file mode 100755
index 7aeec1d..0000000
--- a/host/windows/usb/legacy/driver/sources.inc
+++ /dev/null
@@ -1,83 +0,0 @@
-!IF 0
-
-Copyright (C) 2007 The Android Open Source Project
-
-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.
-
-Module Name:
-
- sources.
-
-Abstract:
-
- This file specifies the target component being built and the list of
- sources files needed to build that driver. Also specifies optional
- compiler switches and libraries that are unique for the component being
- built.
-
-!ENDIF
-
-TARGETNAME=androidusb
-!IF "$(DDKBUILDENV)"=="chk"
-TARGETPATH=..\build\Debug
-!ELSE
-TARGETPATH=..\build\Release
-!ENDIF
-TARGETTYPE=DRIVER
-KMDF_VERSION=1
-USECXX_FLAG=/TP
-USER_C_FLAGS=$(USER_C_FLAGS) /wd4100 /wd4002 /wd4509 /wd4390 /TP
-
-INCLUDES=$(INCLUDES); \
- $(IFSKIT_INC_PATH); \
- ..\..\api;
-
-TARGETLIBS=$(DDK_LIB_PATH)\usbd.lib
-
-MSC_WARNING_LEVEL=/W4 /WX /Wp64
-MSC_OPTIMIZATION = /Oi /Ob1
-C_DEFINES=$(C_DEFINES) -DEXPLODE_POOLTAGS -DRTL_USE_AVL_TABLES
-
-RCOPTIONS=$(RCOPTIONS) /dVER_COMPANYNAME_STR="\"Google Inc\""
-RCOPTIONS=$(RCOPTIONS) /dVER_LEGALCOPYRIGHT_YEARS="\"2007\""
-RCOPTIONS=$(RCOPTIONS) /dVER_LEGALCOPYRIGHT_STR="\"\251 Google Inc. All rights reserved.\""
-RCOPTIONS=$(RCOPTIONS) /dVER_PRODUCTNAME_STR="\"Google Android USB Driver\""
-RCOPTIONS=$(RCOPTIONS) /dVER_PRODUCTVERSION="1,00,01,001"
-RCOPTIONS=$(RCOPTIONS) /dVER_PRODUCTVERSION_STR="\"1.00\""
-
-!IF 0
-
-By overriding .rsrc section properties (!D removes Discardable attribute)
-we make sure that all our vtables will be placed properly into non-discardable
-data segment. Because of the nature of this driver we don't need to have
-vtables in NonPaged data sections because all our objects can be paged.
-Otherwise we may want to add /SECTION:.rsrc,X option that locks section in memory
-
-!ENDIF
-
-LINKER_FLAGS=$(LINKER_FLAGS) /MAP /MAPINFO:LINES /SECTION:.rsrc,!D
-
-MOST_SOURCES= \
- android_usb_driver_object.cpp \
- android_usb_wdf_object.cpp \
- android_usb_device_object.cpp \
- android_usb_file_object.cpp \
- android_usb_device_file_object.cpp \
- android_usb_pipe_file_object.cpp \
- android_usb_bulk_file_object.cpp \
- android_usb_interrupt_file_object.cpp
-
-PRECOMPILED_INCLUDE=precomp.h
-PRECOMPILED_PCH=precomp.pch
-PRECOMPILED_OBJ=precomp.obj
-
diff --git a/host/windows/usb/legacy/prebuilt/driver/WdfCoInstaller01005.dll b/host/windows/usb/legacy/prebuilt/driver/WdfCoInstaller01005.dll
deleted file mode 100644
index 12d2768..0000000
--- a/host/windows/usb/legacy/prebuilt/driver/WdfCoInstaller01005.dll
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/prebuilt/driver/android_usb.inf b/host/windows/usb/legacy/prebuilt/driver/android_usb.inf
deleted file mode 100644
index fff0440..0000000
--- a/host/windows/usb/legacy/prebuilt/driver/android_usb.inf
+++ /dev/null
@@ -1,126 +0,0 @@
-;/*++
-;
-;Abstract:
-; Installation inf for the Android USB Bulk device
-;
-;--*/
-
-[Version]
-Signature="$WINDOWS NT$"
-Class=USB
-ClassGuid={F72FE0D4-CBCB-407d-8814-9ED673D0DD6B}
-Provider=%GOOG%
-DriverVer=1/29/2009,1.0.0010.00000
-CatalogFile.NTx86=androidusb86.cat
-CatalogFile.NTamd64=androidusba64.cat
-
-; ================= Class section =====================
-
-[ClassInstall32]
-Addreg=AndroidUsbClassReg
-
-[AndroidUsbClassReg]
-HKR,,,0,%ClassName%
-HKR,,Icon,,-5
-
-[DestinationDirs]
-DefaultDestDir = 12
-
-; ================= Device section =====================
-
-[Manufacturer]
-%MfgName%=Google,NTx86,NTamd64
-
-; For Win2K
-[Google]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For XP and later
-[Google.NTx86]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For AMD64 and later
-[Google.NTamd64]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-[androidusb.Dev.NT]
-CopyFiles=androidusb.Files.Ext
-
-[androidusb.Dev.NT.Services]
-Addservice = androidusb, 0x00000002, androidusb.AddService
-
-[androidusb.AddService]
-DisplayName = %androidusb.SvcDesc%
-ServiceType = 1 ; SERVICE_KERNEL_DRIVER
-StartType = 3 ; SERVICE_DEMAND_START
-ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %10%\System32\Drivers\androidusb.sys
-AddReg = androidusb.AddReg
-LoadOrderGroup = Base
-
-[androidusb.AddReg]
-HKR,"Parameters","MaximumTransferSize",0x10001,4096
-HKR,"Parameters","DebugLevel",0x10001,2
-HKR, Parameters\Wdf, VerboseOn, 0x00010001, 1
-HKR, Parameters\Wdf, VerifierOn, 0x00010001, 1
-HKR, Parameters\Wdf, DbgBreakOnError, 0x00010001, 1
-
-[androidusb.Files.Ext]
-androidusb.sys
-
-[SourceDisksNames]
-1=%Disk_Description%,,,
-
-[SourceDisksFiles]
-androidusb.sys = 1
-
-;-------------- WDF Coinstaller installation
-[DestinationDirs]
-CoInstaller_CopyFiles = 11
-
-[androidusb.Dev.NT.CoInstallers]
-AddReg=CoInstaller_AddReg
-CopyFiles=CoInstaller_CopyFiles
-
-[CoInstaller_CopyFiles]
-wdfcoinstaller01005.dll
-
-[SourceDisksFiles]
-wdfcoinstaller01005.dll=1 ; make sure the number matches with SourceDisksNames
-
-[CoInstaller_AddReg]
-HKR,,CoInstallers32,0x00010000, "wdfcoinstaller01005.dll,WdfCoInstaller"
-
-[androidusb.Dev.NT.Wdf]
-KmdfService = androidusb, androidusb_wdfsect
-
-[androidusb_wdfsect]
-KmdfLibraryVersion = 1.5
-
-;---------------------------------------------------------------;
-
-[Strings]
-GOOG = "Google, Inc"
-MfgName = "Google, Inc"
-Disk_Description= "ADB Interface Installation Disk"
-androidusb.SvcDesc = "ADB Interface Driver"
-ClassName = "ADB Interface"
-USB\VID_18D1&PID_DDDD.DeviceDescTest="ADB Testing Interface"
-USB\VID_0BB4&PID_0C01.DeviceDescRelease="HTC Dream"
-USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease="HTC Dream Composite ADB Interface"
-USB\VID_0BB4&PID_0FFF.DeviceDescRelease="HTC Bootloader"
diff --git a/host/windows/usb/legacy/prebuilt/driver/androidusb.sys b/host/windows/usb/legacy/prebuilt/driver/androidusb.sys
deleted file mode 100644
index fe64531..0000000
--- a/host/windows/usb/legacy/prebuilt/driver/androidusb.sys
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/prebuilt/driver/androidusb86.cat b/host/windows/usb/legacy/prebuilt/driver/androidusb86.cat
deleted file mode 100644
index 12836dc..0000000
--- a/host/windows/usb/legacy/prebuilt/driver/androidusb86.cat
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/prebuilt/driver_amd_64/WdfCoInstaller01005.dll b/host/windows/usb/legacy/prebuilt/driver_amd_64/WdfCoInstaller01005.dll
deleted file mode 100644
index 32519fb..0000000
--- a/host/windows/usb/legacy/prebuilt/driver_amd_64/WdfCoInstaller01005.dll
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/prebuilt/driver_amd_64/android_usb.inf b/host/windows/usb/legacy/prebuilt/driver_amd_64/android_usb.inf
deleted file mode 100644
index fff0440..0000000
--- a/host/windows/usb/legacy/prebuilt/driver_amd_64/android_usb.inf
+++ /dev/null
@@ -1,126 +0,0 @@
-;/*++
-;
-;Abstract:
-; Installation inf for the Android USB Bulk device
-;
-;--*/
-
-[Version]
-Signature="$WINDOWS NT$"
-Class=USB
-ClassGuid={F72FE0D4-CBCB-407d-8814-9ED673D0DD6B}
-Provider=%GOOG%
-DriverVer=1/29/2009,1.0.0010.00000
-CatalogFile.NTx86=androidusb86.cat
-CatalogFile.NTamd64=androidusba64.cat
-
-; ================= Class section =====================
-
-[ClassInstall32]
-Addreg=AndroidUsbClassReg
-
-[AndroidUsbClassReg]
-HKR,,,0,%ClassName%
-HKR,,Icon,,-5
-
-[DestinationDirs]
-DefaultDestDir = 12
-
-; ================= Device section =====================
-
-[Manufacturer]
-%MfgName%=Google,NTx86,NTamd64
-
-; For Win2K
-[Google]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For XP and later
-[Google.NTx86]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For AMD64 and later
-[Google.NTamd64]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-[androidusb.Dev.NT]
-CopyFiles=androidusb.Files.Ext
-
-[androidusb.Dev.NT.Services]
-Addservice = androidusb, 0x00000002, androidusb.AddService
-
-[androidusb.AddService]
-DisplayName = %androidusb.SvcDesc%
-ServiceType = 1 ; SERVICE_KERNEL_DRIVER
-StartType = 3 ; SERVICE_DEMAND_START
-ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %10%\System32\Drivers\androidusb.sys
-AddReg = androidusb.AddReg
-LoadOrderGroup = Base
-
-[androidusb.AddReg]
-HKR,"Parameters","MaximumTransferSize",0x10001,4096
-HKR,"Parameters","DebugLevel",0x10001,2
-HKR, Parameters\Wdf, VerboseOn, 0x00010001, 1
-HKR, Parameters\Wdf, VerifierOn, 0x00010001, 1
-HKR, Parameters\Wdf, DbgBreakOnError, 0x00010001, 1
-
-[androidusb.Files.Ext]
-androidusb.sys
-
-[SourceDisksNames]
-1=%Disk_Description%,,,
-
-[SourceDisksFiles]
-androidusb.sys = 1
-
-;-------------- WDF Coinstaller installation
-[DestinationDirs]
-CoInstaller_CopyFiles = 11
-
-[androidusb.Dev.NT.CoInstallers]
-AddReg=CoInstaller_AddReg
-CopyFiles=CoInstaller_CopyFiles
-
-[CoInstaller_CopyFiles]
-wdfcoinstaller01005.dll
-
-[SourceDisksFiles]
-wdfcoinstaller01005.dll=1 ; make sure the number matches with SourceDisksNames
-
-[CoInstaller_AddReg]
-HKR,,CoInstallers32,0x00010000, "wdfcoinstaller01005.dll,WdfCoInstaller"
-
-[androidusb.Dev.NT.Wdf]
-KmdfService = androidusb, androidusb_wdfsect
-
-[androidusb_wdfsect]
-KmdfLibraryVersion = 1.5
-
-;---------------------------------------------------------------;
-
-[Strings]
-GOOG = "Google, Inc"
-MfgName = "Google, Inc"
-Disk_Description= "ADB Interface Installation Disk"
-androidusb.SvcDesc = "ADB Interface Driver"
-ClassName = "ADB Interface"
-USB\VID_18D1&PID_DDDD.DeviceDescTest="ADB Testing Interface"
-USB\VID_0BB4&PID_0C01.DeviceDescRelease="HTC Dream"
-USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease="HTC Dream Composite ADB Interface"
-USB\VID_0BB4&PID_0FFF.DeviceDescRelease="HTC Bootloader"
diff --git a/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusb.sys b/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusb.sys
deleted file mode 100644
index 70ce24f..0000000
--- a/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusb.sys
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusba64.cat b/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusba64.cat
deleted file mode 100644
index dd7850d..0000000
--- a/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusba64.cat
+++ /dev/null
Binary files differ
diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index a4d511e..debf9a1 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -10,12 +10,14 @@
<classpathentry kind="src" path="packages/apps/Contacts/src"/>
<classpathentry kind="src" path="packages/apps/DeskClock/src"/>
<classpathentry kind="src" path="packages/apps/Email/src"/>
+ <classpathentry kind="src" path="packages/apps/Gallery3D/src"/>
<classpathentry kind="src" path="packages/apps/HTMLViewer/src"/>
<classpathentry kind="src" path="packages/apps/Launcher2/src"/>
<classpathentry kind="src" path="packages/apps/Mms/src"/>
<classpathentry kind="src" path="packages/apps/PackageInstaller/src"/>
<classpathentry kind="src" path="packages/apps/Phone/src"/>
<classpathentry kind="src" path="packages/apps/QuickSearchBox/src"/>
+ <classpathentry kind="src" path="packages/apps/Provision/src"/>
<classpathentry kind="src" path="packages/apps/Settings/src"/>
<classpathentry kind="src" path="packages/apps/SoundRecorder/src"/>
<classpathentry kind="src" path="packages/apps/Stk/src"/>
@@ -32,7 +34,6 @@
<classpathentry kind="src" path="frameworks/base/cmds/input/src"/>
<classpathentry kind="src" path="frameworks/base/cmds/pm/src"/>
<classpathentry kind="src" path="frameworks/base/cmds/svc/src"/>
- <classpathentry kind="src" path="frameworks/base/common/java"/>
<classpathentry kind="src" path="frameworks/base/core/java"/>
<classpathentry kind="src" path="frameworks/base/core/config/sdk"/>
<classpathentry kind="src" path="frameworks/base/graphics/java"/>
@@ -50,6 +51,7 @@
<classpathentry kind="src" path="frameworks/base/voip/java"/>
<classpathentry kind="src" path="frameworks/base/vpn/java"/>
<classpathentry kind="src" path="frameworks/base/wifi/java"/>
+ <classpathentry kind="src" path="frameworks/ex/common/java"/>
<classpathentry kind="src" path="development/samples/ApiDemos/src"/>
<classpathentry kind="src" path="development/samples/ApiDemos/tests/src"/>
<classpathentry kind="src" path="development/samples/Compass/src"/>
@@ -93,8 +95,6 @@
<classpathentry kind="src" path="external/apache-http/src"/>
<classpathentry kind="src" path="external/bouncycastle/src/main/java"/>
<classpathentry kind="src" path="external/nist-sip/java"/>
- <classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/google-common_intermediates/javalib.jar"/>
- <classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/gsf-client_intermediates/javalib.jar"/>
<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/guava_intermediates/javalib.jar"/>
<classpathentry kind="lib" path="packages/apps/Calculator/arity-2.1.2.jar"/>
<classpathentry kind="output" path="out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes"/>
diff --git a/ide/eclipse/README.importing-to-eclipse.txt b/ide/eclipse/README.importing-to-eclipse.txt
new file mode 100644
index 0000000..dffa0ab
--- /dev/null
+++ b/ide/eclipse/README.importing-to-eclipse.txt
@@ -0,0 +1,6 @@
+To import the formatter, go to the preferences, section Java > Code Style >
+formatter, then click on import and choose
+development/ide/eclipse/android-formatting.xml
+
+To import the import order, to go into Java > Code Style > Organize Import,
+then click on import and choose development/ide/eclipse/android.importorder
diff --git a/pdk/README b/pdk/README
index d9f8996..0acb1eb 100644
--- a/pdk/README
+++ b/pdk/README
@@ -11,7 +11,7 @@
If that doesn't work, go through the instructions on
- http://source.android.com/download again.
+ http://source.android.com/source/download.html again.
2) from the root
diff --git a/pdk/docs/about/index.jd b/pdk/docs/about/index.jd
index 2f98b65..43d2a8d 100644
--- a/pdk/docs/about/index.jd
+++ b/pdk/docs/about/index.jd
@@ -3,10 +3,10 @@
doc.hidenav=true
@jd:body
<p>Android is an open-source software stack created for mobile phones and
-other devices. The Android Open Source Project (AOSP) is tasked with the
-maintenance and further development of Android. Many device manufacturers have
-brought to market devices running Android, and they are readibly available
-around the world.</p>
+other devices. The Android Open Source Project (AOSP), led by Google, is
+tasked with the maintenance and further development of Android. Many device
+manufacturers have brought to market devices running Android, and they are
+readibly available around the world.</p>
<p>Our primary purpose is to build an excellent software platform for everyday
users. A number of companies have committed many engineers to achieve this
goal, and the result is a full production quality consumer product whose
diff --git a/pdk/docs/about/philosophy.jd b/pdk/docs/about/philosophy.jd
index 1aa1ccf..1562e42 100644
--- a/pdk/docs/about/philosophy.jd
+++ b/pdk/docs/about/philosophy.jd
@@ -2,7 +2,7 @@
doc.type=about
doc.hidenav=true
@jd:body
-<p>Android is an open-source software stack for mobile phones and similar
+<p>Android is an open-source software stack for mobile phones and other
devices.</p>
<h2>Origin and Goal</h2>
<p>Android was originated by a group of companies known as the Open Handset
@@ -16,12 +16,11 @@
ideas a reality. We wanted to make sure that there was no central point of
failure, where one industry player could restrict or control the innovations
of any other. The solution we chose was an open and open-source platform.</p>
-<p>But the ultimate goal, of course, is to improve the mobile experience for
-real users by facilitating innovation. Accordingly, the primary goal of the
-AOSP is to make sure Android is a success as an end user product.</p>
+<p>The goal of the Android Open Source Project is to create a successful
+real-world product that improves the mobile experience for end users.</p>
<h2>Governance Philosophy</h2>
<p>The companies that have invested in Android have done so on its merits,
-because we collectively believe that an open platform is necessary. Android is
+because we believe that an open platform is necessary. Android is
intentionally and explicitly an open-source -- as opposed to free software --
effort: a group of organizations with shared needs has pooled
resources to collaborate on a single implementation of a shared product.
@@ -34,20 +33,19 @@
Anyone can (and will!) use the Android source code for any purpose, and we
welcome all such uses. However, in order to take part in the shared
ecosystem of applications that we are building around Android, device builders
-can take advantage of the Compatibility Program.</p>
+must participate in the Compatibility Program.</p>
<p>Though Android consists of multiple sub-projects, this is strictly a
project-management technique. We view and manage Android as a single,
holistic software product, not a "distribution", specification, or collection
-of replaceable parts. Conceptually, our notion is that device builders port
+of replaceable parts. Our intent is that device builders port
Android to a device; they don't implement a specification or curate a
distribution.</p>
<h2>How We Work</h2>
<p>We know that quality does not come without hard work. Along with many
partners, Google has contributed full-time engineers, product managers, UI
designers, Quality Assurance, and all the other roles required to bring
-modern devices to market. We integrate the open source administration and
+modern devices to market. We roll the open source administration and
maintenance into the larger product development cycle.</p>
-<p>In a nutshell:</p>
<ul>
<li>At any given moment, there is a current latest release of the Android
platform. This typically takes the form of a branch in the tree.</li>
@@ -56,18 +54,9 @@
features, and so on.</li>
<li>In parallel, Google works internally on the next version of the
Android platform and framework, working according to the product's needs and
-goals. Some of the work from the current latest tree will promoted into these
-releases.</li>
-<li>When the "n+1"th version is determined to be nearing completion, it will
-be published to the public source tree, and become the new latest
-release.</li>
-<li>Since Android is open source, nothing prevents device implementers from
-shipping devices on older (obsolete) Android builds. However, active work will
-be focused on the current platform release.</li>
+goals. We develop the next version of Android by working with a device partner
+on a flagship device whose specifications are chosen to push Android
+in the direction we believe it should go.</li>
+<li>When the "n+1"th version is ready, it will be published to the public
+source tree, and become the new latest release.</li>
</ul>
-<p>To meet our goals, Android needs to achieve widespread, compatible
-adoption. We believe that the best way to accomplish that is to make sure that
-we ship high-quality, flagship devices with an intense product and end-user
-focus. The "next release" of Android is driven by the product needs for the next
-generation of mobile devices; the resulting excellent product is then released
-to open source and becomes the new current version of the platform.</p>
diff --git a/pdk/docs/community/groups-charter.jd b/pdk/docs/community/groups-charter.jd
index 6d5b501..959917e 100644
--- a/pdk/docs/community/groups-charter.jd
+++ b/pdk/docs/community/groups-charter.jd
@@ -1,26 +1,66 @@
page.title=Android Discussion Groups Charter
doc.type=community
+doc.hidenav=true
@jd:body
-<h2>
-Audience
-</h2>
-<p>These discussion groups are intended for developers working with the Android platform. Everyone is welcome to join in, provided you follow our community's policies described below. Our users help each other, and many experts post to these groups, including members of the Open Handset Alliance.
+<h2>Audience</h2>
+<p>These discussion groups are intended for developers working with the
+Android platform. Everyone is welcome to join in, provided you follow our
+community's policies described below. Our users help each other, and many
+experts post to these groups, including members of the Open Handset Alliance.
</p>
-<p>No topic is off-limits, provided it relates to Android in some way. However, since these are very busy lists, search the archives before posting your question; you may find your question has already been answered.
+<p>No topic is off-limits, provided it relates to Android in some way.
+However, since these are very busy lists, search the archives before posting
+your question; you may find your question has already been answered.
</p>
-<h2>
-Mailing list rules
-</h2>
-<p>We love simplicity and hate restrictions, so we keep our policies minimal. The rules below describe what's expected of subscribers to the Android mailing lists.
+<h2>Mailing list rules</h2>
+<p>We love simplicity and hate restrictions, so we keep our policies minimal.
+The rules below describe what's expected of subscribers to the Android mailing
+lists.
</p>
<ul><li><b>Please be friendly</b>
-<br>Showing courtesy and respect to others is a vital part of the Android culture, and we expect everyone participating in the Android community to join us in accepting nothing less. Being courteous does not mean we can't constructively disagree with each other, but it does mean that we must be polite when we do so. There's never a reason to be antagonistic or dismissive toward anyone; if you think there is, think again before you post.<br><br>Mobile development is serious business, but it's also a lot of fun. Let's keep it that way. Let's strive to be one of the friendliest communities in all of open source.<br><br></li>
+<br>Showing courtesy and respect to others is a vital part of the Android
+culture, and we expect everyone participating in the Android community to join
+us in accepting nothing less. Being courteous does not mean we can't
+constructively disagree with each other, but it does mean that we must be
+polite when we do so. There's never a reason to be antagonistic or dismissive
+toward anyone; if you think there is, think again before you
+post.<br><br>Mobile development is serious business, but it's also a lot of
+fun. Let's keep it that way. Let's strive to be one of the friendliest
+communities in all of open source.<br><br></li>
+
<li><b>Allowed discussion topics</b>
-<br>Most topics are technical discussions of Android or users helping each other, but this group is intended for discussions of<i>everything</i>
-in the world of Android. We welcome announcements and discussion of products, libraries, publications, and other interesting Android-related news. We even welcome (polite!) discussion of articles and ideas critical of Android--after all, we can't improve if we don't listen. There are no restrictions on the subject matter, and we don't exclude discussions of commercial products if users are interested in talking about them.<br><br>However, we hate spam almost as passionately as we love courtesy and respect, so we reserve the right to limit discussions that amount to spam. Outright spam will result in the spammer being immediately and permanently banned from the list.
+<br>Most of our groups are for technical discussions of Android or users
+helping each other. Generally we don't put hard restrictions on the topics
+discussed in the group: as long as the topic is relevant to Android in some
+way, it's welcome on our groups. We welcome announcements and discussion of
+products, libraries, publications, and other interesting Android-related news,
+but <b>please do not cross-post</b>. Post only to the most relevant group for
+your message. We even welcome (polite!) discussion of articles and ideas
+critical of Android--after all, we can't improve if we don't listen.<br><br>
</li>
+
+<li><b>Working Lists</b>
+<br>Some of our groups are considered "working lists", by which we mean that the
+list is intended to be used in support of the completion of specific tasks. On
+these groups, we don't welcome off-topic conversations, and will generally ask
+you to take general discussions to a different list. Since these are lists
+where people are trying to get work done, we will be pretty aggressive about
+keeping the noise level low. We ask that you respect our contributors' time
+and keep general discussions to appropriate lists.<br><br>
+</li>
+
+<li><b>Spam</b>
+<br>We hate spam almost as passionately as we love courtesy and respect, so we
+reserve the right to limit discussions that amount to spam. Outright spam will
+result in the spammer being immediately and permanently banned from the list.
+<br><br></li>
</ul>
-<p>The most important rule is friendliness. Remember: disrespect and rudeness are not welcome in our community under any circumstances. We don't have a formal policy on dealing with troublemakers, and we hope we never need one.That said, we do pledge to do our best to be fair, and we will always try to warn someone before banning him or her.
+
+<p>The most important rule is friendliness. Remember: disrespect and rudeness
+are not welcome in our community under any circumstances. We don't have a
+formal policy on dealing with troublemakers, and we hope we never need
+one.That said, we do pledge to do our best to be fair, and we will always try
+to warn someone before banning him or her.
</p>
<h2>
Contacting the moderators
diff --git a/pdk/docs/community/index.jd b/pdk/docs/community/index.jd
index 6e6f59e..46adf37 100644
--- a/pdk/docs/community/index.jd
+++ b/pdk/docs/community/index.jd
@@ -1,7 +1,7 @@
-page.title=Community
+page.title=Android Community
doc.type=community
+doc.hidenav=true
@jd:body
-<h1>Android Community</h1>
<p>Welcome to the Android community!</p>
<p>The key to any community is, obviously, communication. Like most projects,
Android communicates via mailing lists. Because Android is an extremely large
@@ -37,6 +37,14 @@
<h2>Open Source Project discussions</h2>
<ul>
+<li><b>android-platform</b><br/>
+This list is for general discussion about the Android open-source project or
+the platform technologies.<br/><br/>
+Subscribe using Google Groups: <a
+href="http://groups.google.com/group/android-platform">android-platform</a><br/>
+Subscribe via email: <a href="mailto:android-platform+subscribe@googlegroups.com">android-platform+subscribe@googlegroups.com</a>
+</li>
+
<li><b>android-building</b><br/>
Subscribe to this list for discussion and help on building the Android source
code, and on the build system. If you've just checked out the source code and
@@ -58,14 +66,14 @@
Subscribe via email: <a href="mailto:android-porting+subscribe@googlegroups.com">android-porting+subscribe@googlegroups.com</a>
</li>
-<li><b>android-platform</b><br/>
-This list is for developers who want to contribute code to the Android
-user-space projects, such as the core system libraries, the Android
-services, the public APIs, or the built-in applications. Note: contributors
+<li><b>android-contrib</b><br/>
+This list is for developers who want to contribute code to Android. This is a
+working list, and is not appropriate for general discussion. We ask that
+general discussion go to android-platform. Note: contributors
to the Android kernel should go to the android-kernel list, below.<br/><br/>
Subscribe using Google Groups: <a
-href="http://groups.google.com/group/android-platform">android-platform</a><br/>
-Subscribe via email: <a href="mailto:android-platform+subscribe@googlegroups.com">android-platform+subscribe@googlegroups.com</a>
+href="http://groups.google.com/group/android-contrib">android-contrib</a><br/>
+Subscribe via email: <a href="mailto:android-contrib+subscribe@googlegroups.com">android-contrib+subscribe@googlegroups.com</a>
</li>
<li><b>android-kernel</b><br/>
@@ -88,27 +96,35 @@
under "subscribe via email" in the lists above.</p>
<p>To set up how you receive mailing list postings by email:</p>
<ol>
-<li>Sign into the group via the Google Groups site. For example, for the android-framework group you would
-visit <a
-href="http://groups.google.com/group/android-framework">http://groups.google.com/group/android-framework</a>.</li>
+<li>Sign into the group via the Google Groups site. For example, for the android-platform group you would
+visit <a href="http://groups.google.com/group/android-platform">http://groups.google.com/group/android-platform</a>.</li>
<li>Click "Edit my membership" on the right side.</li>
<li>Under "How do you want to read this group?" select one of the email options.</li>
</ol>
<h2>Android on IRC</h2>
-<p>We also have a presence on IRC via Freenode. We maintain two official IRC
-channels on irc.freenode.net:</p>
+<p>We also have a presence on IRC via <a href="http://freenode.net/">freenode</a>.
+We maintain two official IRC channels on
+<a href="irc://irc.freenode.net/">irc.freenode.net</a> (access via the web
+at <a href="http://webchat.freenode.net/">freenode webchat</a>):</p>
<ul>
-<li><b>#android</b> - dedicated to general Android discussion and porting concerns</li>
-<li><b>#android-dev</b> - dedicated to discussion about writing Android applications</li>
+<li><b><a href="irc://irc.freenode.net/android">#android</a></b>
+ — dedicated to general Android discussion and porting concerns</li>
+<li><b><a href="irc://irc.freenode.net/android-dev">#android-dev</a></b>
+ — dedicated to discussion about writing Android applications</li>
</ul>
<p>The channels above are official. There are a few other channels the
community is using, but are not official. These aren't official or officially
moderated/managed, so you use the channels below at your own risk. The Open
Handset Alliance doesn't endorse these channels, there's no warranty express
-or implied, and so on. There may be more.</p>
+or implied, and so on. There may be more channels than just these listed.</p>
<ul>
-<li><b>#android-offtopic</b> - for, well, off-topic discussions</li>
-<li><b>#android-root</b> - for discussion related to off-label uses of hardware</li>
-<li><b>#androidfra</b> - pour discuter d'Android en français</li>
+<li><b><a href="irc://irc.freenode.net/android-firehose">#android-firehose</a></b>
+ — displays in real-time the commits to the Android Open Source Project</li>
+<li><b><a href="irc://irc.freenode.net/android-fr">#android-fr</a></b>
+ — pour discuter d'Android en français</li>
+<li><b><a href="irc://irc.freenode.net/android-offtopic">#android-offtopic</a></b>
+ — for, well, off-topic discussions</li>
+<li><b><a href="irc://irc.freenode.net/android-root">#android-root</a></b>
+ — for discussion related to off-label uses of hardware</li>
</ul>
diff --git a/pdk/docs/compatibility/2.1/versions.jd b/pdk/docs/compatibility/2.1/versions.jd
new file mode 100644
index 0000000..9687a96
--- /dev/null
+++ b/pdk/docs/compatibility/2.1/versions.jd
@@ -0,0 +1,19 @@
+page.title=Permitted Version Strings for Android 2.1
+doc.type=compatibility
+@jd:body
+<p>As described in Section 3.2.2 of the <a
+href="{@docRoot}compatibility/android-2.1-cdd.pdf">Android 2.1 Compatibility
+Definition</a>, only certain strings are allowable for the system property
+<code>android.os.Build.VERSION.RELEASE</code>. The reason for this is that
+applications and web sites may rely on predictable values for this string, and
+so that end users can easily and reliably identify the version of Android
+running on their devices.</p>
+<p>Because subsequent releases of the Android software may revise this string,
+but not change any API behavior, such releases may not be accompanied by a new
+Compatibility Definition Document. This page lists the versions that are
+allowable by an Android 2.1-based system. The only permitted values for
+<code>android.os.Build.VERSION.RELEASE</code> for Android 2.1 are:</p>
+<ul>
+<li>2.1</li>
+<li>2.1-update1</li>
+</ul>
diff --git a/pdk/docs/compatibility/2.2/versions.jd b/pdk/docs/compatibility/2.2/versions.jd
new file mode 100644
index 0000000..87b12eb
--- /dev/null
+++ b/pdk/docs/compatibility/2.2/versions.jd
@@ -0,0 +1,20 @@
+page.title=Permitted Version Strings for Android 2.2
+doc.type=compatibility
+@jd:body
+<p>As described in Section 3.2.2 of the <a
+href="{@docRoot}compatibility/android-2.2-cdd.pdf">Android 2.2 Compatibility
+Definition</a>, only certain strings are allowable for the system property
+<code>android.os.Build.VERSION.RELEASE</code>. The reason for this is that
+applications and web sites may rely on predictable values for this string, and
+so that end users can easily and reliably identify the version of Android
+running on their devices.</p>
+<p>Because subsequent releases of the Android software may revise this string,
+but not change any API behavior, such releases may not be accompanied by a new
+Compatibility Definition Document. This page lists the versions that are
+allowable by an Android 2.2-based system.</p>
+<p>The value of <code>android.os.Build.VERSION.RELEASE</code> for Android 2.2
+MUST be one of the following strings:</p>
+<ul>
+<li>2.2</li>
+<li>2.2.1</li>
+</ul>
diff --git a/pdk/docs/compatibility/2.3/versions.jd b/pdk/docs/compatibility/2.3/versions.jd
new file mode 100644
index 0000000..5f634ed
--- /dev/null
+++ b/pdk/docs/compatibility/2.3/versions.jd
@@ -0,0 +1,20 @@
+page.title=Permitted Version Strings for Android 2.3
+doc.type=compatibility
+@jd:body
+<p>As described in Section 3.2.2 of the <a
+href="{@docRoot}compatibility/android-2.3-cdd.pdf">Android 2.3 Compatibility
+Definition</a>, only certain strings are allowable for the system property
+<code>android.os.Build.VERSION.RELEASE</code>. The reason for this is that
+applications and web sites may rely on predictable values for this string, and
+so that end users can easily and reliably identify the version of Android
+running on their devices.</p>
+<p>Because subsequent releases of the Android software may revise this string,
+but not change any API behavior, such releases may not be accompanied by a new
+Compatibility Definition Document. This page lists the versions that are
+allowable by an Android 2.2-based system.</p>
+<p>The value of <code>android.os.Build.VERSION.RELEASE</code> for Android 2.3
+MUST be one of the following strings:</p>
+<ul>
+<li>2.3</li>
+<li>2.3.1</li>
+</ul>
diff --git a/pdk/docs/compatibility/android-1.6-cdd.pdf b/pdk/docs/compatibility/android-1.6-cdd.pdf
new file mode 100644
index 0000000..ba7b4ad
--- /dev/null
+++ b/pdk/docs/compatibility/android-1.6-cdd.pdf
Binary files differ
diff --git a/pdk/docs/compatibility/android-2.1-cdd.pdf b/pdk/docs/compatibility/android-2.1-cdd.pdf
new file mode 100644
index 0000000..7fe54c6
--- /dev/null
+++ b/pdk/docs/compatibility/android-2.1-cdd.pdf
Binary files differ
diff --git a/pdk/docs/compatibility/android-2.2-cdd.pdf b/pdk/docs/compatibility/android-2.2-cdd.pdf
new file mode 100644
index 0000000..fbc1e77
--- /dev/null
+++ b/pdk/docs/compatibility/android-2.2-cdd.pdf
@@ -0,0 +1,4080 @@
+%PDF-1.4
+%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
+% 'BasicFonts': class PDFDictionary
+1 0 obj
+% The standard fonts dictionary
+<< /F1 2 0 R
+ /F2 4 0 R
+ /F3 105 0 R
+ /F4 107 0 R >>
+endobj
+% 'F1': class PDFType1Font
+2 0 obj
+% Font Helvetica
+<< /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'FormXob.a31102908a592e8f94c7b4e032ffcc37': class PDFImageXObject
+3 0 obj
+<< /BitsPerComponent 8
+ /ColorSpace /DeviceRGB
+ /Filter [ /ASCII85Decode
+ /DCTDecode ]
+ /Height 49
+ /Length 11548
+ /Subtype /Image
+ /Type /XObject
+ /Width 369 >>
+stream
+s4IA0!"_al8O`[\!<<*#!!*'"s5F.Y8OGjP:f:(Y8PDPQ!<E0#"70H8E,5RU!!$kRFE18L66KB5=s+('!!3-/!"JuF!'"CsF)XEA:eUihzzzzzzp=93Ezdk,!IE,5LSzzzzzzzzzzz!"O$O=]te*!A"3N!#0'J=]te*!C-Vb!#/mE=]te*!E9%!!#0X!E-)'[!GDH5!#/pV@:T?<!IOkI!%`.i;F:Ea!N5tu!"NX@;F:Ea!Or+0!"NI;;F:Ea!QY6@!"O0^B64+R!S@AP!&/;$Bl3nN!XJc+!'"M#F(51M!^H_c!+]V]@r22G!i,er!;^PLDe&hJ"/#Vo!%;>rEc_9]"3:HB!$kZL=s*eFzS#-/c9N;&m!jGd0=s*eFz2.HUdTBcIW)6m:H=s*eFz--ZDi'@d'_[`)?O=s*eFzo@O$D!!!!"('ntn1GSq1!!!!"$b$*9"d]2go2bnl#:TWQrR_)LqmZV*rMBPp"53_T_"M8\EcqE_z!!*,F!!$MOEcqE_z!!*,F!!$MOEcqE_z!!*,F!!%1PB64+Rz!!*'"d<#?g!!!!"zd<#?g!!!!"zd<#?g!!!!"!!$nIBl3nNz!&+BQW.4jJ;ZHdt1dD$@W^$Oa-C4]4'&*Bd:d>!\<'UEb1G]"41G]"41G`QQF(51Mz!")7n+A>Tf0K(cgzzzzzzzzzzzzzzzzzzz!!$kPF^kCOz!"o83!"<aS:/:ii!"o83!9eBD:fIDp!"o83!9eKI;agZd!"o83!9e$/7S*R[!"o83!9ds%6q[L[!"o83!9e`B6V[U]!"o83!9e$87T'3d!"o83!9e0+8l,Kf!"o83!9e!3<Drkt!"o83!9eB<:eUih!"o83!9eBD6;dd`!"o83!9e!878j0d!"o83!9e`B<*'&"!"o83!9eHG;H3\s!"o83!9e3:92Y`i!"o83!9ds)6q%(U!"o83!9e<::.tWf!"o83!9e-=8Q5Zi!"o83!9aDR!)NY<!)*Ah!&FU/!&ag7!!$kQDe&hJz,4GR4-BJ3-!!'kS8:U[?zzz!!%+PG]Woc!!#B)E-ZJ<B4uB06#^dZALnrqDIY:M+>PW)3<9*<!'ittBk@>F9hbU;!!!!)!!.jh!!E9%!!*'"!#bh;!!!!#TE5)r!!!!"!!!%>TE>/s!!!!"!!!!Rzs4[N@!!30%!<E3&!<E3&!WiE)"9S],!WiN-"9Sc2"U5/8"U,&6#71Y?#7(P<"UGJA#RLeE$46tB$OdCM$jd7J$NJi\6NI5i!WiE)"Tni1$3gY<$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$4?gK!"fJ:0`c7r!?qLF&HMtG!WU(<*rl9A"T\W)!<E3$z!!!!"!WrQ/"pYD?$4HmP!4<@<!W`B*!X&T/"U"r.!!.KK!WrE*&Hrdj0gQ!W;.0\RE>10ZOeE%*6F"?A;UOtZ1LbBV#mqFa(`=5<-7:2j.Ps"@2`NfY6UX@47n?3D;cHat='/U/@q9._B4u!oF*)PJGBeCZK7nr5LPUeEP*;,qQC!u,R\HRQV5C/hWN*81['d?O\@K2f_o0O6a2lBFdaQ^rf%8R-g>V&OjQ5OekiqC&o(2MHp@n@XqZ"J6*ru?D!<E3%!<E3%!<<*"!!!!"!WrQ/"pYD?$4HmP!4<C=!W`?*"9Sc3"U"r.!<RHF!<N?8"9fr'"qj4!#@VTc+u4]T'LIqUZ,$_k1K*]W@WKj'(*k`q-1Mcg)&ahL-n-W'2E*TU3^Z;(7Rp!@8lJ\h<``C+>%;)SAnPdkC3+K>G'A1VH@gd&KnbA=M2II[Pa.Q$R$jD;USO``Vl6SpZEppG[^WcW]#)A'`Q#s>ai`&\eCE.%f\,!<j5f=akNM0qo(2MHp@n@XqZ#7L$j-M1!YGMH!'^J^eG-NC01u",nG`Ffa4e4cpM":c88PCn1>L,"M]>S:ok/CblnWoh&#FYmpsZ*f6h'8mIO]^cdki!c&P7/NgtMOeqa+M.%A^H91+Y[F`*5e<*0Mi!INs5)nE7bT"_o(ZnRPP2Nh[.g9G3_gNKo-lLr5u4W\?PoW5p3@jts8l?<$bImu"h-G_]Y9cn@#KZ+/=&hgW]6hUSBAOXXZQb5utFf-?0\bAC!hWk54??CH'+Xo;O,jZG?r;L%q4D\)X+`4lUfe,0a9]im!P8(?-k&mdiO\P%4N?n)n$Q%8b5Fp!n'):A!Ka'XdT$0Jnj:W*cqej&YZfjBR'Fe(>,CGj$GbqP,0%C8O#^@IG;jCJ**k\`QbG[BRlGD?)2bH'P!Mo.J7I.habPKfAp*E`N;/hl%*^`@[$cPM&TPC,dJ*Zp1[)*CitkYc-sl>I+ngHfO/M)V4C(nk#UJIB;1SYM_H:A!sdj,-^>D82D8Dl2B[R=?+S!,173r#XEH9g\0]*Zr/drfuTXdO0tuK)O\?6HlmA+5R1C$_NdeK?,m`.fH'T-XM&0?-thFr#p\uZgaIr8Zpk6)S!%tSk+OlB=:NoQP#<P2]:Wr2f="DrKb/,Hs9gg6Wro\]p?!I/9;=5l-Q5-Z-+3EN[-)A?ml.3+HLm^=5jbW]qG/T`EJmkoT+fW-h,o[rOd)oNn6P2=CTdF(LUlW7b[`':!8PYA<L,<_K!Qd4$>c/lfIC1APF]KP1DaBXi7%4.e$[]KU;Z<[db]32%;q>L"]b>JZ[uV==1hB9*0-'#9;<UJ:9A#k3q:d?OD68Hn^W!\u#+g/bYBLAZRMZD0h>MM%_$IUNI'E$j\(?NWGP4B3u0_qSMQI"n=4?iVB/9ID:Og%=j<7bA@^)R9b3iD:0%hP1do%p#`.@(VkB)$2ELUM*<9Vrk%0LCtK[W9<E)&G$2U_1Ft7L)CcLP2`<EVa0&A%[Y7.ZH'R9if!jdcZr'8(FbLN,5Qqj!5Qqj^kn4j[E2oZab]!RT-B\\/\V2Xfj]Ngj6R/@D<X4^P*C6NEHZ]A=<B7]^iTko40+?10fd<OX->571\j`2]`cCAdG81rWJW:1PC]=AIr!hV7'kr+(nHXkZ[FFl47[\$92t)PF@rNAdP!B&(al$d8WJeVjK9]&kMG6S-Uq)sd036duDVJI9FH,!&U:LOC<@p/JSfQC#Y;FKK?F%2Re)V+ugY6!ZZ<K?7(0+7)'=@8]k\Dn:.<lI(,!Wr,iWL1j>)SHGR+N%)B8=LT_/S.MS/gRl3N%hQ;c.V8'W3Q`G.!XMlL+:j/TbI53XR@&WT$,QBQmLC>2Hr(B/TVD9oN.T8J>?"EJ09*"l#0TalHI&S#^<a]_fm.i]oa^,D@!\!&Aso"6sZ5;O_]!9(CeE]'J*:O.qL]^aPq7!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!9X82Hrf`t_7p8jN4`^a_VJg+@><Jio$8ff66IN^iE5Y9_ObP^)u^1+i/PZ._i7WSn4hD",-?@27R,t#BRf^t+8R0RpMUDk=_W=&e+ESsdPrA(as;]Y:a2Wf(]Y&2q=ZHV`7_U5ic=r$.QD0fGZ/h[C86u`hcVI5h$dMe.ZPt3a!^@8p4Mj1a/pu^o>;/G>?t>d$gS2=!TO]]X;OT1;mhAc,928sSepAkmHsDh_7h>/nA^aPm7159;`$;e>J+sodOE!EP"BTu,Ba&Hj!1#e>5>B$$2%e=DnL"f)d(A#e00Z]fJ`p[;H+^QO9lrs4U!t2'u\a@:0j+3`C3kH3h4`KQV)8[<i4s.h<b+-e^_)73f1j*lHKbGrX't@dnnS'ZIZZ1X&rTKiEkk+:*RgWbb0T>h\eV.f<K]lpo!'=L)pVaa8RC"/Z5>@P&12aXr75u`&!-"e/X%"8HYFP^\B3GKp;T;"RRl)[76bF?A([#?^V!d+CG^V%L,FN%maIXm=#!7-AgZ1qYJZ*oR^iK0cWR!R07Rl(qS,5:Cg&4+[/XqAD4AID)@]qrr>3(QT;sO2gZ=trX(aFE9GF>F/p&%"PlHP*o`C_*^/GQrr<N$:](TX]t<5,Xf[Z$T+,"-gS@]LK4mS@JNtOs,iF!3:ZGa^q\eWZ>X,Sc`!2,pJPDZd&_[g.*_Mp!"]P;n!"M'tkJgQ_]I#EfU&Cf(ou>P\KNBInc/%u6?YB;#F]1r&Ij:cYQi%O>iI8JC6)8:f):\;WXs?tNfbulGN0B4BJdS]\!<#"2V>PB/d@kppn8*P-f<i`%`1HcV+Lec4$V8G/a^`*o)tVB8*UCh^i1j<g:[n*DeJcjlEuqVr8bNV0)CHhPkXm;EYc5BUJ,)%,&,uX^Iae;s8M2N07hBYm:P@!^pknUD<s]4TKgc.eNBJ8!es=eTm$jO)Umo&TTCDC>"b4oYeUR'<.eKoq5IAaf5!9jc*<t*_a&0-u8TA6d(FCnW^,Al5-m_1)#UFE2-`m)]@:c;551&s#3mou1Mb1Ai`=`>SrS!iqgll)/r"=T%5PFU:Q*$!<$qAh:0uPuLb`FR;Hh6p5[uB>%P9$"5)iTe$SgnIfO0VUDk)4F];Jk*iWF*,DocW:=H_-Yqch=R3#Jf.r0+M`_(V5X+/0\#,Au_RRal'e9!#(!8!BbF^MW$-Oi1k`$P3!>NiV'Mj7DF*nF%%<%oa479jstZ9#OS@`Ho^`Xh[[:Pi![:3C)3Tshii9F._a`X'+qcq!?'g'jE@^Wq"OYiplFE1_`Q0JlJD[kdNZAf0Js7(VjKkP_u,&%Qt*LRGB>3b?8iO;Q!>@X'.bJK(s8,lUp/:1k)\/;DUmLhb=&rdC/qT`QJF*=T>qJ%SeTYgB7$h<)H:eC2B)7F['=t#gOhOJL6Hd=L$'ZuaMiDmlne1jZtO<j#rdV3%79(S!*>J2DW6ltm3"-\m&B%qP]f%crr=%1I08C<r0Y:_ra6Ybrf4Ri^[P"Eq')9*rJ`W5!9lAKD=+ZGhhs7;A8A2OgCMTXJp'jT;i5GjX/)6[D1+p"8u,be7Yci(4q8+X2ak.)o^-&]U\cU#CRCr*Ym)r(=3O&'mdg+2WS<TH#Eh4L!;?0<jm^U8Y6F]a(`$3%i;6-b`rXD*X5KSbmB&#]J'(-c&,Ps[rr>WeW;cj74'QM#!0=l)lu-9'@@DG9Q73Vj\soJu&_mplH("VW\@rm+T`l9*35lT[[_1+l.<g3t;,+M+HC%/"'S!r16#VM3TK)!?\BjfNA,&(ST>BD(r%?hSn:T#E']p@89=,!V%KJIr#oFe:#UCLj+E]Hmg"]`=T098oDXj+N#=).JN"mkiN,aaNVu@"XU)d1Q[]t4ba)to)!TAKCTuZ'rj^2@b'u]o$'4A%(ls+O0nS4ft&uO[Q_j]l=GJ;e"-W2`l]A2a;B:J@BpV.\3+hrRZ22'ML:hJ4Te0RS=6g$\$?rc;fbIIKG389C4UQEtijWp-6p$.&!f-Mg2DuTeb&+M%H^8Lu2d^Q(&J)qrA+8+oKo[bC:U;]6-%HV_;@iOPBdONH8[5o13n;jR#rmdA8!!hKQQ[l4;-0b9F`R*/ko\lXjLkqnd&*NBBPd$(!_dGA.k]8uHTH=a3oIks-rr<RAddABM?^&]gm77i0j@^.?4iod@:6gV3FoMH`;##87!+/WRkkH[ArOBW'gpMY.qR$8&dHOu'G?YZ:Tu<1po$_Q:4lmC5Qa+2fT3K8oVtP%O[>LGj9Zm<nIQL3m&&U;t%fZOf(t=K-)F>b,[5<HnAcsSRStM@o#GN.(^'B%8n?9m%>uL:3)K"TAl$$nVMoAM'7KfKGUuOO@+S>E*rl`(IDr)6/!3fB$!9d-`62pofgn#1UGd?5P?Sh(-N)OrFNO"N'e)%bXUGC*blBr[pX^tBiRWTU>MGDQs#sp-!bBl1\[sa-mUq%.cT$?fCj0+19"6anhmtpB`m[!_E>K729WGjOoTB78)5j=f%5j=Fn81'5V'Y&k+,`3HY(s!pG^2X)PJre"jn99V]1'$^@bX)ub!\on"`-u10LX?&$j9oW#!+)r1!9bW@O"AQGGciO?0GA6T:lQ8328%rs/&&\[$]LRRj4_JPn1PZ.hu3cJVi(-h$q&s4<q#oHnk3W+'#tiOOc$DD,b/BbB9G!23`j&Ib[7X2XgGjMJ&GR%/^^DPk2\rU-nKqPh`*d*Jb`@X(M4Q8%"89\QW@'sM4BcnJt8-9c*OnDl7.s[Bgpb<^5r9o"VpfLH)S]!XEZC"ZaY+qh((u[QgRfa80.5akRDklNd`AN5N2?ek4k(Bl6WgYiCP8@Fn6N"pt2j1NQ&@8EX"NL!(c\,paA"rXM4liY3!,^Q7[C`'SSh`#!$aWgGg)I$KchP+8IYK"TJJRY)iS_Uh77X]L0V_%.c#.0!oUS_pMIm/k$4TeXTQPV"NUDHKbo\LGEc@7oAdQp>+/G-@!PZ_B'He;m'@ge]OX\NuJ?L/V>U)E1o`mai>7C>PP])D1"><>N4Cu"im?P)R\[jm(IaTOi8!o3s.4\0[D]q*Aa4:h>@Jc\$YoRi<ZQ&dPX3+Z#[+B:g'G\@tEF?,bF(\?6/nqg=o@!@/NR*RbB]`/%nKlm!t<Irr<:<m?,F(GcZB1@5+&W5M%,0pt;j#fgaKOaj"B2m3d@br/`j7,d47*m!mrg?Opb]N\*W63kQ$1@S*>\.7t+V\Jb>2g@]rPrWpo#*^@V:X_h90>:$jRaH3luNK'E/Y3%:8!Pumo`Gm!.`MK]Wm+LA)Xt?E2i0)AV*RHO#c.kt&8a(?0%$&P%HLid)1H54FT2$rj3.uAQ!+3a'\aL/Mr];'O``J0Hd_a0>$%"O)bt5s@W4-nlIIHA>o7Lbhl#U1srX([D'Y&:lpj&r4&7QlI8`G_sHBeWnl'#C3_9^k/_4MPAGAZ7GD[L4tIF[\))d-d8,Xu<3+]Gk4ntR3%A%d"lZP6SB?N@_iFElbHharg(0E;-?r`TtqXh6Q?o3O7_dj"elJrs7H/Kms4,>KB$4O^0!\@+VXSkjb,Y%jA[)!/-qb\_`TC=C/PUBs4aN,5NZm3LG0>$fCeOE4B^.rTcV4ceX$m1\E=J@7A!G`iH8]?C0Q!+W7=<A)+-QZC"I>`^b`,k)9R1O]K+dd_^.eSZs\Itmg-NLdE[jOGk')?BR58!/b8aZ(/#E]_m@Ib#:cpV4,&_eV?WFI!eWYXr;d""U@c+KGU\"EB'$9OH[\BpLR?HA(Su(@\];b2!XD&kVp"9mm4OO3[?'-H7^?.Tfq$iuUVlh!YCngtTJam'c;n[-&p">nQ&04T3".)>HS;[ltbZ]JlhTVTre.H`6X()0In^2]^*C"D!)4N/hW0&,uWJItiD.nO9X92.$l/)F;')@=n(/j,t^33!)DP-jd]FJd-M9afK9]pa@Y"l?=rW)rQaQX4b;`>GHXVEXm%l1kn`8_8]ZkDt]dtorS('eb"^k08AlQ\[9F_`m[Q.:G?At43VA]WD3XW-'!8SJBg.S!#(^9Ge>A=*(MQFW@Tm$)(o\]Wj_V&f'`7Y``8OO;SU<M$faasmfn.JnDo$@nSu($Y%9=jg"IQ_B5fVGOoPK),k7#HO:REP!5lji(&n8%hc9[V^ppDBr"MF0D-Oe08thC8DhG%M&\?Gpk?g\oeeV'?Heg:?i\o%i,Y$\7)[^C+DVgc$)"b#<`8`hP2rZrK%g.`M)P.O>\*fMO-TH24gK(c:?dR33P+,%sa3XbcnF>rMrrCG*eN`OU3p?PYrnP6tIO"Wnf>4qB*i#Oe?d>n.bA^?]UlgZP)3j5cM#_K\-^$!Grr@Xi=P8`Cpm4koZ2L?Q_\&MKhln7cF4V9Tig9A]Yd0&E^V`3(.nJ6:od!,+;urOjjpe#FHu<bHACo)ao?K4k_Xog>XtgZDV&RkV;-HSiZhW!ErH;Q2$?]?+2UA3JU5JoRl9'"Yh"Y=;mtmYDmA'/_R.o39AuN1:=i)s?Z$C5HjcAD/=<40"1QH]B<f-]\r-6Z^HX/R-rL1,UM='5'jde!k@1j:lh6Y3bF,lYGoZ\-@\X*Z`/*@X'*!S<GC6`9Gbp^GD>drg<P0p=u8t0k`:<*V/1ZD3KYDIRBf!48MKlVEMh+A%UEH9''N9>18Z7@DcQN[!-)9%"%i*BFEa6]5SD\;2qHlfrPm'TK[,Zbc4nsJJDca$+'NEBSiS=pf**=d/`m1f.5'ua\I@;#8d`ta>LEN@7j^3+-;)^sFk92-&Mmnf9-daqHGL%0fT:WNJ8g1*XYphOC/%oLd&[04"&BeAHiPmj_)8J)Rl)p'D>\K1VRp:g<?ip4qD_o&&VnD9"EX53#$NJ^t2Vcu"%<@qd<\4$RW/BU#'&?gJU\<d:YphXJ\\@L1mMLpJMN+:$Jh5$d1[sJ%B[_7sT]=lF<LUqWjOl.5j8^q-&>[$@bd*E:a.-hMH&&<g(/,Lf@"3/%lq!7G`=RcoVD_19&^6*:#DBUa1jfTWUb@C:dg`3I^"`oW]r<5W<"tq+:iph7CmVP'2D(Rp:_j=`V6JN5gp,k;-oC-[Ur+5BL8@@rRLMo%!@FpUa'pK.`W+_u'9!1oJ&2VdtlWN,SoFfo+!RRsG>WdHZ[9"6k#dh)G^4WUArN:S\pnQk._T9AOi;Wd'YH7D1Y9SX5"Cbc<,\9=a!Q;U\rpDl"c>d2#e>\brR&hqu9%]SOO!7s&me4+jg3\*Z\J69`RbaQ<i,@?lj#sSu[*(FYB=lts+L7"Qe88^*<4Gp/6\)Eqj:6-"c?aT7?eJ)fh\3Xgn[$.u+$Lfl8pq=(7bUhN[CLj]B6bL7D+>P&.S'5h)'i_*I0&;$2I.9=g2<$88rm\a_[E2K$<7.h1#%T#:G:Z(_H$)jo.5:TX?EBs3'o&eQH?S%1U[(kpNt\T.:"qqf_J=^g2Fsfg#)Lkf7#1DGN!trM"LXcAb%.!#p`?QZ:MlT@>o*,KmmIQk8eRepoXEYI!#/*i*4N^[bnEOX(hO2@nA!_QSYjGFaoZM8cd'E8\c5?O0!#rWph>e;oE,6\W#c]X3,<Zq&o\;M=Dl=\ZGL1^CYKnWCo^+J&?bjhBhYMm%aR\$L:Tuo/0P;p$d<AIUXUqcB(FKeU`r<*"i`;?=3R@C4@-!-Be9dPMm8#3`X1spXd"-W3Y(^!KK!J5fnj%&Z-7`P&l2qqLXUtC2f.\j01M%4aBq-3.!KFMro_fXP6Nn)`EuY=mB(peMQt`IIWYSHu!g#G%a&l[d_9&RSqcCI7YP.":G@2gSF_H6P)/=&'V\,1;C9,_]O\\hQu1%ME_UC)>-X^$=i8PgHoM78<G0W`,"s(goMG83:2kmJYJnQ_,r6`?&c]nXHLP&p:")8-180YkrAA"mH,cf1tQg2aa\-QNi(Km&)!.D=c-WuBPs5*A#Wf`&i88elW_-.cbb/NGQYjpmu"c#Us5gmlh=5CXKIc1Pu8bKhW`QL1s@kd&'LIC7Xa#J;S_dn17iDS0[)9#`6Nt$,&r8M>h:O!]!^!]5uW0ddW_tfn*I79*uT<-j4D4T:LEVAjfP?1d]Kq4p?`hum^[O?)_`5I;B$jc)='bei%GuJ!5j9<GgUmpHJ1ZhBb$rIlsNX@A;#R^2M8Z@gRS2ZNbdi..FR.e*A"Z/K2lL+6Fs=kQYfJqjaLP/]Cc\F\Phe^I/EePp]nff/GOqgrr>pca+j%?#bf`nNo@)lg/.nB@:3Ug@6k7`,ie!)9'j</I03aE0C8]=X6I>>dOoI@I-YD\er[8e'j8ng#b[B4ahZg9H37KI7<I/?>W$/^5A8[#ifpnGD%99%pXF)LI,8Lorl8=kpo/PsX'Z-WYMk/'7[KlQq%.:BY40VW-L?8e3Wjm=b@_[m%.XTUO2#,lLAJZCY-n90%/`]-nFPJWdTkG-aV>\RiZn8aPtt\`GI@\Uq?su^=2dtfn)4erY7o+>%:&1EIJ(AtCQhB$8Chqa!6h_nJ8b`DN8l95-G6G+KcB"9(b*j7q9cKSdXK<7CO<@?FL"J@m^6o=9W@oG>4t-krMG#FBcdOhddA[#.5&:ko15$K8tfgM<!"%JgZ9]Cc8kRbpF_7-dB*EhrK]SG!8f!5GJbN,8&4R&l^%D&pH%0./`[DMHBm8[$a;W1ei8bqaQQA063sc2kH/1.gb"H*ES/K8=u!q3^ESXsc;cI;S_KC:GAdE\IumR*i7i"u$M]84f>\mKr$(q7j"%kMp`98u-2s`d*7cgFL-Ve[bT0;+&-m]Lp$H+)f8b4`p^cBAL-HV>DrV:3gHM%,9[BQ\P6Q56->?"^``/lZ*9/ED7npMB.*Zg<cRa;ib+")V[o+YJP47;*V4F-!ddPF'Wu4N,Z/jdZ4skZ)rM?k_:PQ;BZhC5n#1O9/RGjNb<&0H]8;ND3c>q-KduiP7^M5ufhC4*N<RAAbU1ohV\!ebpTX\8k#+:iI!K!@D%E*-/[mOKp79heieYA*"mOiX_@\B^2\AgY9=1+e;QL=56e[*qBmdAcSHmR3ZoH/d9):8%\G)GS._tHo3`5;a(8.f!#d"3e1m7InJrrBB,m2+cC*U'+'DYur$pk%Mb8>`f(Q/a;M^2O-Ee[@NI</)CNj,=oQb)5i_Sem,qKu1]lGu:VrBu4R2eYC<fH98=qg(c)ba][?<aaY**3dc2IjkuVhL";m&^8k^#3MI/1/ZpC9,`<cIFD;WS7EZ?p!W(EWp`JG&SJUYQ@IS'l4@.sf:eaY^:ct]bR7UI"AiCibaN=V+Y=5BI4Z:2]dr%!j>1"rSDW#bW@$G55NIb,2*Phl>`jrDC':p-^>8rXA4C)]drKk89`]TT)`Mfh?^#*Vh.+>M>]<gYKqZ_:;g.+j^j42tu"j';o;6_3@Z7%*X!k=kRIK["PH2DICh@\1`;&6\GP?g-@Q+5e^=A$Li$NS=VBu)ola+<P8hsaEKJ_*tD>f!OeP1^kt>Bhg[.2_\Tn?ZWi8b]C*i7I>+n@RV5V`q`OFM>B%RNiBWeLhV=MDKia![9&<##6u/3$_SC;W'*39]$.WQ=!Do)AQa[;cW!YnUnS+Mb,O5QF>8`a\dH-g=GjT5MA'3*]3C'm7$O1`*+OC05e/o>FS!&HO[SL:jH,S=7[C?-53#@)<VmRYAs)]M^O@/-`VE7$._&b2!OCj7i;S=2F'h,h-)X:l1c6R%t_a[.s!_!C0]1_Vn/X7DnOml-Jrn)rr@\d&AC:+bZ\VPnETK9I_XBbC+XH!M!\eZYuO/J@n'U"pL=>Qnot2M&T3%WIb4QPnG`KDDZ1+%BJt0acf\V>>=tq/85m`VRRBsP=N1m\Oq1KA5/O&.6iJ7c,$B;6b.3L'?rLFEjat-E\WhBfk1stN)>b4f="OrTIr7INps[8%hgl``4rCu_<o6`aNo@)lg//0"[jkXD\thgYESt[o,/*GEJkMXik1UQnaTJOOj!:T*VkUoG#EdBLk.&WWADFFpQWdO46]kU'C@5c.Pah)c-gVH'Ii*D`_0Ys&]>Ji]A'_3U_]A@R(4D$o+^:*136j3K3'8*dg;h#.0_%*@hhJ_7LV,KkHZ*]#ip(l(%#G5Xi-`U9g`'7R>6>4Xi7GY>?;u/2#p'hZOo&:.3&nWh0)963Ssm'*6@G$jI"?q8BVLC]"&P_L-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ii[!U5nkC5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Tg$Z~>endstream
+endobj
+% 'F2': class PDFType1Font
+4 0 obj
+% Font Helvetica-Bold
+<< /BaseFont /Helvetica-Bold
+ /Encoding /WinAnsiEncoding
+ /Name /F2
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER1': class PDFDictionary
+5 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (mailto:compatibility@android.com) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 55
+ 626.125
+ 145.135
+ 637.375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER2': class LinkAnnotation
+6 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 564.9375
+ 117.5275
+ 576.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER3': class LinkAnnotation
+7 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 55
+ 456.5763
+ 0 ]
+ /Rect [ 70
+ 553.6875
+ 114.1825
+ 564.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER4': class LinkAnnotation
+8 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 55
+ 613.3887
+ 0 ]
+ /Rect [ 70
+ 542.4375
+ 107.935
+ 553.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER5': class LinkAnnotation
+9 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 55
+ 530.11
+ 0 ]
+ /Rect [ 85
+ 529.1875
+ 190.045
+ 540.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER6': class LinkAnnotation
+10 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 55
+ 420.985
+ 0 ]
+ /Rect [ 85
+ 517.9375
+ 172.12
+ 529.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER7': class LinkAnnotation
+11 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 55
+ 344.6775
+ 0 ]
+ /Rect [ 100
+ 504.6875
+ 161.6875
+ 515.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER8': class LinkAnnotation
+12 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 55
+ 291.9275
+ 0 ]
+ /Rect [ 100
+ 493.4375
+ 178.3675
+ 504.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER9': class LinkAnnotation
+13 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 111 0 R
+ /XYZ
+ 55
+ 742.865
+ 0 ]
+ /Rect [ 100
+ 482.1875
+ 184.6225
+ 493.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER10': class LinkAnnotation
+14 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 111 0 R
+ /XYZ
+ 55
+ 678.865
+ 0 ]
+ /Rect [ 115
+ 468.9375
+ 221.725
+ 480.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER11': class LinkAnnotation
+15 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 111 0 R
+ /XYZ
+ 55
+ 246.615
+ 0 ]
+ /Rect [ 115
+ 457.6875
+ 195.46
+ 468.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER12': class LinkAnnotation
+16 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 111 0 R
+ /XYZ
+ 55
+ 160.115
+ 0 ]
+ /Rect [ 115
+ 446.4375
+ 206.7175
+ 457.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER13': class LinkAnnotation
+17 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 113 0 R
+ /XYZ
+ 55
+ 722.115
+ 0 ]
+ /Rect [ 115
+ 435.1875
+ 200.47
+ 446.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER14': class LinkAnnotation
+18 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 113 0 R
+ /XYZ
+ 55
+ 657.2975
+ 0 ]
+ /Rect [ 85
+ 421.9375
+ 180.0325
+ 433.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER15': class LinkAnnotation
+19 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 113 0 R
+ /XYZ
+ 55
+ 306.9225
+ 0 ]
+ /Rect [ 85
+ 410.6875
+ 160.0225
+ 421.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER16': class LinkAnnotation
+20 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 113 0 R
+ /XYZ
+ 55
+ 219.365
+ 0 ]
+ /Rect [ 100
+ 397.4375
+ 197.53
+ 408.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER17': class LinkAnnotation
+21 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 117 0 R
+ /XYZ
+ 55
+ 614.615
+ 0 ]
+ /Rect [ 100
+ 386.1875
+ 193.36
+ 397.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER18': class LinkAnnotation
+22 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 117 0 R
+ /XYZ
+ 55
+ 485.7975
+ 0 ]
+ /Rect [ 85
+ 372.9375
+ 194.2075
+ 384.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER19': class LinkAnnotation
+23 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 117 0 R
+ /XYZ
+ 55
+ 297.4225
+ 0 ]
+ /Rect [ 85
+ 361.6875
+ 157.5325
+ 372.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER20': class LinkAnnotation
+24 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 125 0 R
+ /XYZ
+ 55
+ 548.2975
+ 0 ]
+ /Rect [ 85
+ 350.4375
+ 196.285
+ 361.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER21': class LinkAnnotation
+25 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 125 0 R
+ /XYZ
+ 55
+ 450.4225
+ 0 ]
+ /Rect [ 85
+ 339.1875
+ 191.7025
+ 350.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER22': class LinkAnnotation
+26 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 125 0 R
+ /XYZ
+ 55
+ 385.365
+ 0 ]
+ /Rect [ 100
+ 325.9375
+ 147.94
+ 337.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER23': class LinkAnnotation
+27 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 125 0 R
+ /XYZ
+ 55
+ 266.865
+ 0 ]
+ /Rect [ 100
+ 314.6875
+ 161.695
+ 325.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER24': class LinkAnnotation
+28 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 125 0 R
+ /XYZ
+ 55
+ 159.615
+ 0 ]
+ /Rect [ 100
+ 303.4375
+ 144.61
+ 314.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER25': class LinkAnnotation
+29 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 133 0 R
+ /XYZ
+ 55
+ 645.115
+ 0 ]
+ /Rect [ 100
+ 292.1875
+ 143.3575
+ 303.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER26': class LinkAnnotation
+30 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 133 0 R
+ /XYZ
+ 55
+ 592.365
+ 0 ]
+ /Rect [ 100
+ 280.9375
+ 174.1975
+ 292.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER27': class LinkAnnotation
+31 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 133 0 R
+ /XYZ
+ 55
+ 418.1388
+ 0 ]
+ /Rect [ 70
+ 267.6875
+ 189.625
+ 278.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER28': class LinkAnnotation
+32 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 133 0 R
+ /XYZ
+ 55
+ 200.2013
+ 0 ]
+ /Rect [ 70
+ 256.4375
+ 197.1325
+ 267.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER29': class LinkAnnotation
+33 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 134 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 245.1875
+ 159.6025
+ 256.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER30': class LinkAnnotation
+34 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 134 0 R
+ /XYZ
+ 55
+ 675.235
+ 0 ]
+ /Rect [ 85
+ 231.9375
+ 147.5275
+ 243.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER31': class LinkAnnotation
+35 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 698.7975
+ 0 ]
+ /Rect [ 85
+ 220.6875
+ 155.035
+ 231.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER32': class LinkAnnotation
+36 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 480.1725
+ 0 ]
+ /Rect [ 85
+ 209.4375
+ 147.1225
+ 220.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER33': class LinkAnnotation
+37 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 141 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 196.1875
+ 174.1975
+ 207.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER34': class LinkAnnotation
+38 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 141 0 R
+ /XYZ
+ 55
+ 571.3262
+ 0 ]
+ /Rect [ 70
+ 184.9375
+ 155.8525
+ 196.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER35': class LinkAnnotation
+39 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 141 0 R
+ /XYZ
+ 55
+ 320.2975
+ 0 ]
+ /Rect [ 85
+ 171.6875
+ 124.18
+ 182.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER36': class LinkAnnotation
+40 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 607.115
+ 0 ]
+ /Rect [ 100
+ 158.4375
+ 244.645
+ 169.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER37': class LinkAnnotation
+41 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 511.115
+ 0 ]
+ /Rect [ 100
+ 147.1875
+ 171.685
+ 158.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER38': class LinkAnnotation
+42 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 469.615
+ 0 ]
+ /Rect [ 100
+ 135.9375
+ 205.0525
+ 147.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER39': class LinkAnnotation
+43 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 404.7975
+ 0 ]
+ /Rect [ 85
+ 122.6875
+ 131.695
+ 133.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER40': class LinkAnnotation
+44 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 253.9225
+ 0 ]
+ /Rect [ 85
+ 111.4375
+ 171.7075
+ 122.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER41': class LinkAnnotation
+45 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 165.2975
+ 0 ]
+ /Rect [ 85
+ 100.1875
+ 162.1225
+ 111.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER42': class LinkAnnotation
+46 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 148 0 R
+ /XYZ
+ 55
+ 710.0475
+ 0 ]
+ /Rect [ 85
+ 88.9375
+ 161.29
+ 100.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page1': class PDFPage
+47 0 obj
+% Page dictionary
+<< /Annots [ 5 0 R
+ 6 0 R
+ 7 0 R
+ 8 0 R
+ 9 0 R
+ 10 0 R
+ 11 0 R
+ 12 0 R
+ 13 0 R
+ 14 0 R
+ 15 0 R
+ 16 0 R
+ 17 0 R
+ 18 0 R
+ 19 0 R
+ 20 0 R
+ 21 0 R
+ 22 0 R
+ 23 0 R
+ 24 0 R
+ 25 0 R
+ 26 0 R
+ 27 0 R
+ 28 0 R
+ 29 0 R
+ 30 0 R
+ 31 0 R
+ 32 0 R
+ 33 0 R
+ 34 0 R
+ 35 0 R
+ 36 0 R
+ 37 0 R
+ 38 0 R
+ 39 0 R
+ 40 0 R
+ 41 0 R
+ 42 0 R
+ 43 0 R
+ 44 0 R
+ 45 0 R
+ 46 0 R ]
+ /Contents 237 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ]
+ /XObject << /FormXob.a31102908a592e8f94c7b4e032ffcc37 3 0 R >> >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER43': class LinkAnnotation
+48 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 148 0 R
+ /XYZ
+ 55
+ 583.6725
+ 0 ]
+ /Rect [ 85
+ 730.6775
+ 115.015
+ 741.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER44': class LinkAnnotation
+49 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 148 0 R
+ /XYZ
+ 55
+ 419.5475
+ 0 ]
+ /Rect [ 85
+ 719.4275
+ 152.53
+ 730.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER45': class LinkAnnotation
+50 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 148 0 R
+ /XYZ
+ 55
+ 310.4225
+ 0 ]
+ /Rect [ 85
+ 708.1775
+ 185.86
+ 719.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER46': class LinkAnnotation
+51 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 148 0 R
+ /XYZ
+ 55
+ 169.2975
+ 0 ]
+ /Rect [ 85
+ 696.9275
+ 126.265
+ 708.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER47': class LinkAnnotation
+52 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 152 0 R
+ /XYZ
+ 55
+ 388.5475
+ 0 ]
+ /Rect [ 85
+ 685.6775
+ 152.11
+ 696.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER48': class LinkAnnotation
+53 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 152 0 R
+ /XYZ
+ 55
+ 322.6725
+ 0 ]
+ /Rect [ 85
+ 674.4275
+ 135.4375
+ 685.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER49': class LinkAnnotation
+54 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 152 0 R
+ /XYZ
+ 55
+ 256.7975
+ 0 ]
+ /Rect [ 85
+ 663.1775
+ 119.605
+ 674.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER50': class LinkAnnotation
+55 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 152 0 R
+ /XYZ
+ 55
+ 202.1725
+ 0 ]
+ /Rect [ 85
+ 651.9275
+ 138.7825
+ 663.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER51': class LinkAnnotation
+56 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 152 0 R
+ /XYZ
+ 55
+ 104.2975
+ 0 ]
+ /Rect [ 85
+ 640.6775
+ 173.7925
+ 651.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER52': class LinkAnnotation
+57 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 154 0 R
+ /XYZ
+ 55
+ 612.2975
+ 0 ]
+ /Rect [ 85
+ 629.4275
+ 195.0625
+ 640.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER53': class LinkAnnotation
+58 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 154 0 R
+ /XYZ
+ 55
+ 343.1725
+ 0 ]
+ /Rect [ 85
+ 618.1775
+ 135.4525
+ 629.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER54': class LinkAnnotation
+59 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 154 0 R
+ /XYZ
+ 55
+ 222.3888
+ 0 ]
+ /Rect [ 70
+ 604.9275
+ 166.2775
+ 616.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER55': class LinkAnnotation
+60 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 159 0 R
+ /XYZ
+ 55
+ 632.8888
+ 0 ]
+ /Rect [ 70
+ 593.6775
+ 177.115
+ 604.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER56': class LinkAnnotation
+61 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 159 0 R
+ /XYZ
+ 55
+ 538.36
+ 0 ]
+ /Rect [ 85
+ 580.4275
+ 144.6025
+ 591.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER57': class LinkAnnotation
+62 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 159 0 R
+ /XYZ
+ 55
+ 461.235
+ 0 ]
+ /Rect [ 85
+ 569.1775
+ 190.465
+ 580.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER58': class LinkAnnotation
+63 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 159 0 R
+ /XYZ
+ 55
+ 384.11
+ 0 ]
+ /Rect [ 85
+ 557.9275
+ 182.5225
+ 569.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER59': class LinkAnnotation
+64 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 159 0 R
+ /XYZ
+ 55
+ 318.235
+ 0 ]
+ /Rect [ 85
+ 546.6775
+ 216.73
+ 557.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER60': class LinkAnnotation
+65 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 162 0 R
+ /XYZ
+ 55
+ 591.1387
+ 0 ]
+ /Rect [ 70
+ 533.4275
+ 161.2825
+ 544.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER61': class LinkAnnotation
+66 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 162 0 R
+ /XYZ
+ 55
+ 452.9513
+ 0 ]
+ /Rect [ 70
+ 522.1775
+ 148.375
+ 533.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER62': class LinkAnnotation
+67 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 162 0 R
+ /XYZ
+ 55
+ 226.0138
+ 0 ]
+ /Rect [ 70
+ 510.9275
+ 119.605
+ 522.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER63': class LinkAnnotation
+68 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 163 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 499.6775
+ 200.065
+ 510.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page2': class PDFPage
+69 0 obj
+% Page dictionary
+<< /Annots [ 48 0 R
+ 49 0 R
+ 50 0 R
+ 51 0 R
+ 52 0 R
+ 53 0 R
+ 54 0 R
+ 55 0 R
+ 56 0 R
+ 57 0 R
+ 58 0 R
+ 59 0 R
+ 60 0 R
+ 61 0 R
+ 62 0 R
+ 63 0 R
+ 64 0 R
+ 65 0 R
+ 66 0 R
+ 67 0 R
+ 68 0 R ]
+ /Contents 238 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER64': class LinkAnnotation
+70 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 417.365
+ 0 ]
+ /Rect [ 125.8675
+ 663.865
+ 170.05
+ 675.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER65': class LinkAnnotation
+71 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 404.115
+ 0 ]
+ /Rect [ 326.365
+ 565.865
+ 370.5475
+ 577.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER66': class LinkAnnotation
+72 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 390.865
+ 0 ]
+ /Rect [ 309.6925
+ 522.615
+ 353.875
+ 533.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER67': class PDFDictionary
+73 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.ietf.org/rfc/rfc2119.txt) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 189.625
+ 405.1775
+ 297.1675
+ 416.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER68': class PDFDictionary
+74 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/compatibility/index.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 205.45
+ 391.9275
+ 369.6775
+ 403.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER69': class PDFDictionary
+75 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 167.965
+ 378.6775
+ 254.6725
+ 389.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER70': class PDFDictionary
+76 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/packages.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 184.2325
+ 365.4275
+ 363.4825
+ 376.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER71': class PDFDictionary
+77 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/Manifest.permission.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 172.9525
+ 352.1775
+ 413.8825
+ 363.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER72': class PDFDictionary
+78 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/os/Build.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 157.96
+ 338.9275
+ 358.885
+ 350.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER73': class PDFDictionary
+79 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/compatibility/2.2/versions.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 186.715
+ 325.6775
+ 373.45
+ 336.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER74': class PDFDictionary
+80 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/webkit/WebView.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 171.7
+ 312.4275
+ 400.96
+ 323.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER75': class PDFDictionary
+81 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.whatwg.org/specs/web-apps/current-work/multipage/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 95.005
+ 299.1775
+ 307.1575
+ 310.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER76': class PDFDictionary
+82 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/ui_guidelines/widget_design.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 114.5275
+ 272.6775
+ 374.23
+ 283.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER77': class PDFDictionary
+83 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/ui/notifiers/notifications.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 114.94
+ 259.4275
+ 346.2925
+ 270.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER78': class PDFDictionary
+84 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://code.google.com/android/reference/available-resources.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 148.705
+ 246.1775
+ 368.8
+ 257.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER79': class PDFDictionary
+85 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/ui_guidelines/icon_design.html#statusbarstructure) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 162.8875
+ 232.9275
+ 477.1975
+ 244.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER80': class PDFDictionary
+86 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/app/SearchManager.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 129.535
+ 219.6775
+ 371.7325
+ 230.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER81': class PDFDictionary
+87 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/widget/Toast.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 96.6025
+ 206.4275
+ 313.3675
+ 217.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER82': class PDFDictionary
+88 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/resources/articles/live-wallpapers.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 127.4425
+ 193.1775
+ 351.265
+ 204.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER83': class PDFDictionary
+89 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://code.google.com/p/apps-for-android) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 129.955
+ 179.9275
+ 269.1925
+ 191.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER84': class PDFDictionary
+90 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/developing/tools/index.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 245.845
+ 166.6775
+ 453.865
+ 177.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER85': class PDFDictionary
+91 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/fundamentals.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 164.1325
+ 153.4275
+ 364.645
+ 164.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER86': class PDFDictionary
+92 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/manifest/manifest-intro.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 117.8575
+ 140.1775
+ 349.2025
+ 151.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER87': class PDFDictionary
+93 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/developing/tools/monkey.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 138.7075
+ 126.9275
+ 355.06
+ 138.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER88': class PDFDictionary
+94 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/content/pm/PackageManager.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 179.965
+ 113.6775
+ 452.1775
+ 124.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER89': class PDFDictionary
+95 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/screens_support.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 167.8825
+ 100.4275
+ 389.23
+ 111.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER90': class PDFDictionary
+96 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/content/res/Configuration.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 184.9825
+ 87.1775
+ 443.02
+ 98.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page3': class PDFPage
+97 0 obj
+% Page dictionary
+<< /Annots [ 70 0 R
+ 71 0 R
+ 72 0 R
+ 73 0 R
+ 74 0 R
+ 75 0 R
+ 76 0 R
+ 77 0 R
+ 78 0 R
+ 79 0 R
+ 80 0 R
+ 81 0 R
+ 82 0 R
+ 83 0 R
+ 84 0 R
+ 85 0 R
+ 86 0 R
+ 87 0 R
+ 88 0 R
+ 89 0 R
+ 90 0 R
+ 91 0 R
+ 92 0 R
+ 93 0 R
+ 94 0 R
+ 95 0 R
+ 96 0 R ]
+ /Contents 239 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER91': class PDFDictionary
+98 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/util/DisplayMetrics.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 161.6125
+ 730.6775
+ 396.28
+ 741.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER92': class PDFDictionary
+99 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/hardware/Camera.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 161.2075
+ 717.4275
+ 395.47
+ 728.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER93': class PDFDictionary
+100 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/hardware/SensorEvent.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 157.0525
+ 704.1775
+ 407.5825
+ 715.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER94': class PDFDictionary
+101 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/security/security.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 220.3975
+ 690.9275
+ 429.6475
+ 702.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER95': class PDFDictionary
+102 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/bluetooth/package-summary.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 119.9575
+ 677.6775
+ 388.825
+ 688.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER96': class LinkAnnotation
+103 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 377.615
+ 0 ]
+ /Rect [ 460.615
+ 462.365
+ 504.7975
+ 473.615 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER97': class LinkAnnotation
+104 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 364.365
+ 0 ]
+ /Rect [ 470.995
+ 311.74
+ 515.1775
+ 322.99 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'F3': class PDFType1Font
+105 0 obj
+% Font Courier
+<< /BaseFont /Courier
+ /Encoding /WinAnsiEncoding
+ /Name /F3
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER98': class LinkAnnotation
+106 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 351.115
+ 0 ]
+ /Rect [ 336.2725
+ 258.99
+ 380.455
+ 270.24 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'F4': class PDFType1Font
+107 0 obj
+% Font Times-Roman
+<< /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Name /F4
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER99': class LinkAnnotation
+108 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 337.865
+ 0 ]
+ /Rect [ 350.19
+ 182.99
+ 394.3725
+ 194.24 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page4': class PDFPage
+109 0 obj
+% Page dictionary
+<< /Annots [ 98 0 R
+ 99 0 R
+ 100 0 R
+ 101 0 R
+ 102 0 R
+ 103 0 R
+ 104 0 R
+ 106 0 R
+ 108 0 R ]
+ /Contents 240 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page5': class PDFPage
+110 0 obj
+% Page dictionary
+<< /Contents 241 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page6': class PDFPage
+111 0 obj
+% Page dictionary
+<< /Contents 242 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER100': class LinkAnnotation
+112 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 324.615
+ 0 ]
+ /Rect [ 381.61
+ 261.6775
+ 425.7925
+ 272.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page7': class PDFPage
+113 0 obj
+% Page dictionary
+<< /Annots [ 112 0 R ]
+ /Contents 243 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER101': class LinkAnnotation
+114 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 311.365
+ 0 ]
+ /Rect [ 447.265
+ 645.6775
+ 491.4475
+ 656.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER102': class LinkAnnotation
+115 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 311.365
+ 0 ]
+ /Rect [ 160.4575
+ 506.4275
+ 204.64
+ 517.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER103': class LinkAnnotation
+116 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 390.865
+ 0 ]
+ /Rect [ 125.4475
+ 429.3025
+ 169.63
+ 440.5525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page8': class PDFPage
+117 0 obj
+% Page dictionary
+<< /Annots [ 114 0 R
+ 115 0 R
+ 116 0 R ]
+ /Contents 244 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER104': class LinkAnnotation
+118 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 298.115
+ 0 ]
+ /Rect [ 500.1475
+ 503.0525
+ 548.5
+ 514.3025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER105': class LinkAnnotation
+119 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 284.865
+ 0 ]
+ /Rect [ 515.1475
+ 352.4275
+ 553.075
+ 363.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER106': class LinkAnnotation
+120 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 284.865
+ 0 ]
+ /Rect [ 55
+ 341.1775
+ 63.34
+ 352.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER107': class LinkAnnotation
+121 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 271.615
+ 0 ]
+ /Rect [ 313.045
+ 233.9275
+ 361.3975
+ 245.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER108': class LinkAnnotation
+122 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 258.365
+ 0 ]
+ /Rect [ 448.06
+ 201.9275
+ 496.4125
+ 213.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER109': class LinkAnnotation
+123 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 245.115
+ 0 ]
+ /Rect [ 124.615
+ 190.6775
+ 172.9675
+ 201.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER110': class LinkAnnotation
+124 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 231.865
+ 0 ]
+ /Rect [ 132.535
+ 126.6775
+ 180.8875
+ 137.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page9': class PDFPage
+125 0 obj
+% Page dictionary
+<< /Annots [ 118 0 R
+ 119 0 R
+ 120 0 R
+ 121 0 R
+ 122 0 R
+ 123 0 R
+ 124 0 R ]
+ /Contents 245 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER111': class LinkAnnotation
+126 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 218.615
+ 0 ]
+ /Rect [ 217.9075
+ 612.1775
+ 266.26
+ 623.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER112': class LinkAnnotation
+127 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 205.365
+ 0 ]
+ /Rect [ 73.7575
+ 548.1775
+ 122.11
+ 559.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER113': class LinkAnnotation
+128 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 192.115
+ 0 ]
+ /Rect [ 188.2975
+ 319.49
+ 236.65
+ 330.74 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER114': class LinkAnnotation
+129 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 178.865
+ 0 ]
+ /Rect [ 499.5925
+ 148.8025
+ 547.945
+ 160.0525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER115': class LinkAnnotation
+130 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 165.615
+ 0 ]
+ /Rect [ 257.9875
+ 128.0525
+ 306.34
+ 139.3025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER116': class LinkAnnotation
+131 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 152.365
+ 0 ]
+ /Rect [ 373.0375
+ 128.0525
+ 421.39
+ 139.3025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER117': class LinkAnnotation
+132 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 298.115
+ 0 ]
+ /Rect [ 493.5025
+ 128.0525
+ 541.855
+ 139.3025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page10': class PDFPage
+133 0 obj
+% Page dictionary
+<< /Annots [ 126 0 R
+ 127 0 R
+ 128 0 R
+ 129 0 R
+ 130 0 R
+ 131 0 R
+ 132 0 R ]
+ /Contents 246 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page11': class PDFPage
+134 0 obj
+% Page dictionary
+<< /Contents 247 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page12': class PDFPage
+135 0 obj
+% Page dictionary
+<< /Contents 248 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER118': class LinkAnnotation
+136 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 178.865
+ 0 ]
+ /Rect [ 207.1
+ 663.865
+ 255.4525
+ 675.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER119': class LinkAnnotation
+137 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 178.865
+ 0 ]
+ /Rect [ 239.6275
+ 628.115
+ 287.98
+ 639.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER120': class LinkAnnotation
+138 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 139.115
+ 0 ]
+ /Rect [ 98.3425
+ 592.365
+ 146.695
+ 603.615 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER121': class LinkAnnotation
+139 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 125.865
+ 0 ]
+ /Rect [ 392.7925
+ 329.6775
+ 441.145
+ 340.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER122': class LinkAnnotation
+140 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 112.615
+ 0 ]
+ /Rect [ 332.6125
+ 263.8025
+ 380.965
+ 275.0525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page13': class PDFPage
+141 0 obj
+% Page dictionary
+<< /Annots [ 136 0 R
+ 137 0 R
+ 138 0 R
+ 139 0 R
+ 140 0 R ]
+ /Contents 249 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER123': class LinkAnnotation
+142 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 99.365
+ 0 ]
+ /Rect [ 273.535
+ 719.4275
+ 321.8875
+ 730.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER124': class LinkAnnotation
+143 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 742.865
+ 0 ]
+ /Rect [ 460.75
+ 478.1775
+ 509.1025
+ 489.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER125': class LinkAnnotation
+144 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 99.365
+ 0 ]
+ /Rect [ 259.42
+ 263.3025
+ 307.7725
+ 274.5525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER126': class LinkAnnotation
+145 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 99.365
+ 0 ]
+ /Rect [ 381.79
+ 174.6775
+ 430.1425
+ 185.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page14': class PDFPage
+146 0 obj
+% Page dictionary
+<< /Annots [ 142 0 R
+ 143 0 R
+ 144 0 R
+ 145 0 R ]
+ /Contents 250 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER127': class LinkAnnotation
+147 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 99.365
+ 0 ]
+ /Rect [ 304.7875
+ 617.5525
+ 353.14
+ 628.8025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page15': class PDFPage
+148 0 obj
+% Page dictionary
+<< /Annots [ 147 0 R ]
+ /Contents 251 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER128': class LinkAnnotation
+149 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 729.615
+ 0 ]
+ /Rect [ 425.56
+ 574.4275
+ 473.9125
+ 585.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER129': class LinkAnnotation
+150 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 716.365
+ 0 ]
+ /Rect [ 433.0675
+ 332.0525
+ 481.42
+ 343.3025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER130': class LinkAnnotation
+151 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 716.365
+ 0 ]
+ /Rect [ 397.6375
+ 266.1775
+ 445.99
+ 277.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page16': class PDFPage
+152 0 obj
+% Page dictionary
+<< /Annots [ 149 0 R
+ 150 0 R
+ 151 0 R ]
+ /Contents 252 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER131': class LinkAnnotation
+153 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 689.865
+ 0 ]
+ /Rect [ 180.895
+ 286.6775
+ 229.2475
+ 297.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page17': class PDFPage
+154 0 obj
+% Page dictionary
+<< /Annots [ 153 0 R ]
+ /Contents 253 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER132': class LinkAnnotation
+155 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 703.115
+ 0 ]
+ /Rect [ 164.2225
+ 570.24
+ 212.575
+ 581.49 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER133': class LinkAnnotation
+156 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 703.115
+ 0 ]
+ /Rect [ 465.5875
+ 493.115
+ 513.94
+ 504.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER134': class LinkAnnotation
+157 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 703.115
+ 0 ]
+ /Rect [ 345.55
+ 393.49
+ 393.9025
+ 404.74 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER135': class LinkAnnotation
+158 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 703.115
+ 0 ]
+ /Rect [ 57.085
+ 327.615
+ 105.4375
+ 338.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page18': class PDFPage
+159 0 obj
+% Page dictionary
+<< /Annots [ 155 0 R
+ 156 0 R
+ 157 0 R
+ 158 0 R ]
+ /Contents 254 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER136': class LinkAnnotation
+160 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 404.115
+ 0 ]
+ /Rect [ 323.41
+ 539.74
+ 367.5925
+ 550.99 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER137': class PDFDictionary
+161 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (mailto:compatibility@android.com) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 193.8325
+ 174.615
+ 283.9675
+ 185.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page19': class PDFPage
+162 0 obj
+% Page dictionary
+<< /Annots [ 160 0 R
+ 161 0 R ]
+ /Contents 255 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page20': class PDFPage
+163 0 obj
+% Page dictionary
+<< /Contents 256 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'R164': class PDFCatalog
+164 0 obj
+% Document Root
+<< /Outlines 166 0 R
+ /PageMode /UseNone
+ /Pages 236 0 R
+ /Type /Catalog >>
+endobj
+% 'R165': class PDFInfo
+165 0 obj
+<< /Author ()
+ /CreationDate (D:20100802143410+08'00')
+ /Keywords ()
+ /Producer (pisa HTML to PDF <http://www.htmltopdf.org>)
+ /Subject ()
+ /Title (Android 2.2 Compatibility Definition) >>
+endobj
+% 'R166': class PDFOutlines
+166 0 obj
+<< /Count 11
+ /First 167 0 R
+ /Last 167 0 R
+ /Type /Outlines >>
+endobj
+% 'Outline.0': class OutlineEntryObject
+167 0 obj
+<< /Count -15
+ /Dest [ 47 0 R
+ /Fit ]
+ /First 168 0 R
+ /Last 230 0 R
+ /Parent 166 0 R
+ /Title (Android 2.2 Compatibility Definition) >>
+endobj
+% 'Outline.2.0': class OutlineEntryObject
+168 0 obj
+<< /Dest [ 47 0 R
+ /Fit ]
+ /Next 169 0 R
+ /Parent 167 0 R
+ /Title (Table of Contents) >>
+endobj
+% 'Outline.2.1': class OutlineEntryObject
+169 0 obj
+<< /Dest [ 97 0 R
+ /Fit ]
+ /Next 170 0 R
+ /Parent 167 0 R
+ /Prev 168 0 R
+ /Title (1. Introduction) >>
+endobj
+% 'Outline.2.2': class OutlineEntryObject
+170 0 obj
+<< /Dest [ 97 0 R
+ /Fit ]
+ /Next 171 0 R
+ /Parent 167 0 R
+ /Prev 169 0 R
+ /Title (2. Resources) >>
+endobj
+% 'Outline.2.3': class OutlineEntryObject
+171 0 obj
+<< /Count -8
+ /Dest [ 109 0 R
+ /Fit ]
+ /First 172 0 R
+ /Last 188 0 R
+ /Next 194 0 R
+ /Parent 167 0 R
+ /Prev 170 0 R
+ /Title (3. Software) >>
+endobj
+% 'Outline.3.0': class OutlineEntryObject
+172 0 obj
+<< /Dest [ 109 0 R
+ /Fit ]
+ /Next 173 0 R
+ /Parent 171 0 R
+ /Title (3.1. Managed API Compatibility) >>
+endobj
+% 'Outline.3.1': class OutlineEntryObject
+173 0 obj
+<< /Count -7
+ /Dest [ 109 0 R
+ /Fit ]
+ /First 174 0 R
+ /Last 180 0 R
+ /Next 181 0 R
+ /Parent 171 0 R
+ /Prev 172 0 R
+ /Title (3.2. Soft API Compatibility) >>
+endobj
+% 'Outline.4.0': class OutlineEntryObject
+174 0 obj
+<< /Dest [ 109 0 R
+ /Fit ]
+ /Next 175 0 R
+ /Parent 173 0 R
+ /Title (3.2.1. Permissions) >>
+endobj
+% 'Outline.4.1': class OutlineEntryObject
+175 0 obj
+<< /Dest [ 109 0 R
+ /Fit ]
+ /Next 176 0 R
+ /Parent 173 0 R
+ /Prev 174 0 R
+ /Title (3.2.2. Build Parameters) >>
+endobj
+% 'Outline.4.2': class OutlineEntryObject
+176 0 obj
+<< /Dest [ 111 0 R
+ /Fit ]
+ /Next 177 0 R
+ /Parent 173 0 R
+ /Prev 175 0 R
+ /Title (3.2.3. Intent Compatibility) >>
+endobj
+% 'Outline.4.3': class OutlineEntryObject
+177 0 obj
+<< /Dest [ 111 0 R
+ /Fit ]
+ /Next 178 0 R
+ /Parent 173 0 R
+ /Prev 176 0 R
+ /Title (3.2.3.1. Core Application Intents) >>
+endobj
+% 'Outline.4.4': class OutlineEntryObject
+178 0 obj
+<< /Dest [ 111 0 R
+ /Fit ]
+ /Next 179 0 R
+ /Parent 173 0 R
+ /Prev 177 0 R
+ /Title (3.2.3.2. Intent Overrides) >>
+endobj
+% 'Outline.4.5': class OutlineEntryObject
+179 0 obj
+<< /Dest [ 111 0 R
+ /Fit ]
+ /Next 180 0 R
+ /Parent 173 0 R
+ /Prev 178 0 R
+ /Title (3.2.3.3. Intent Namespaces) >>
+endobj
+% 'Outline.4.6': class OutlineEntryObject
+180 0 obj
+<< /Dest [ 113 0 R
+ /Fit ]
+ /Parent 173 0 R
+ /Prev 179 0 R
+ /Title (3.2.3.4. Broadcast Intents) >>
+endobj
+% 'Outline.3.2': class OutlineEntryObject
+181 0 obj
+<< /Dest [ 113 0 R
+ /Fit ]
+ /Next 182 0 R
+ /Parent 171 0 R
+ /Prev 173 0 R
+ /Title (3.3. Native API Compatibility) >>
+endobj
+% 'Outline.3.3': class OutlineEntryObject
+182 0 obj
+<< /Count -2
+ /Dest [ 113 0 R
+ /Fit ]
+ /First 183 0 R
+ /Last 184 0 R
+ /Next 185 0 R
+ /Parent 171 0 R
+ /Prev 181 0 R
+ /Title (3.4. Web Compatibility) >>
+endobj
+% 'Outline.5.0': class OutlineEntryObject
+183 0 obj
+<< /Dest [ 113 0 R
+ /Fit ]
+ /Next 184 0 R
+ /Parent 182 0 R
+ /Title (3.4.1. WebView Compatibility) >>
+endobj
+% 'Outline.5.1': class OutlineEntryObject
+184 0 obj
+<< /Dest [ 117 0 R
+ /Fit ]
+ /Parent 182 0 R
+ /Prev 183 0 R
+ /Title (3.4.2. Browser Compatibility) >>
+endobj
+% 'Outline.3.4': class OutlineEntryObject
+185 0 obj
+<< /Dest [ 117 0 R
+ /Fit ]
+ /Next 186 0 R
+ /Parent 171 0 R
+ /Prev 182 0 R
+ /Title (3.5. API Behavioral Compatibility) >>
+endobj
+% 'Outline.3.5': class OutlineEntryObject
+186 0 obj
+<< /Dest [ 117 0 R
+ /Fit ]
+ /Next 187 0 R
+ /Parent 171 0 R
+ /Prev 185 0 R
+ /Title (3.6. API Namespaces) >>
+endobj
+% 'Outline.3.6': class OutlineEntryObject
+187 0 obj
+<< /Dest [ 125 0 R
+ /Fit ]
+ /Next 188 0 R
+ /Parent 171 0 R
+ /Prev 186 0 R
+ /Title (3.7. Virtual Machine Compatibility) >>
+endobj
+% 'Outline.3.7': class OutlineEntryObject
+188 0 obj
+<< /Count -5
+ /Dest [ 125 0 R
+ /Fit ]
+ /First 189 0 R
+ /Last 193 0 R
+ /Parent 171 0 R
+ /Prev 187 0 R
+ /Title (3.8. User Interface Compatibility) >>
+endobj
+% 'Outline.6.0': class OutlineEntryObject
+189 0 obj
+<< /Dest [ 125 0 R
+ /Fit ]
+ /Next 190 0 R
+ /Parent 188 0 R
+ /Title (3.8.1. Widgets) >>
+endobj
+% 'Outline.6.1': class OutlineEntryObject
+190 0 obj
+<< /Dest [ 125 0 R
+ /Fit ]
+ /Next 191 0 R
+ /Parent 188 0 R
+ /Prev 189 0 R
+ /Title (3.8.2. Notifications) >>
+endobj
+% 'Outline.6.2': class OutlineEntryObject
+191 0 obj
+<< /Dest [ 125 0 R
+ /Fit ]
+ /Next 192 0 R
+ /Parent 188 0 R
+ /Prev 190 0 R
+ /Title (3.8.3. Search) >>
+endobj
+% 'Outline.6.3': class OutlineEntryObject
+192 0 obj
+<< /Dest [ 133 0 R
+ /Fit ]
+ /Next 193 0 R
+ /Parent 188 0 R
+ /Prev 191 0 R
+ /Title (3.8.4. Toasts) >>
+endobj
+% 'Outline.6.4': class OutlineEntryObject
+193 0 obj
+<< /Dest [ 133 0 R
+ /Fit ]
+ /Parent 188 0 R
+ /Prev 192 0 R
+ /Title (3.8.5. Live Wallpapers) >>
+endobj
+% 'Outline.2.4': class OutlineEntryObject
+194 0 obj
+<< /Dest [ 133 0 R
+ /Fit ]
+ /Next 195 0 R
+ /Parent 167 0 R
+ /Prev 171 0 R
+ /Title (4. Reference Software Compatibility) >>
+endobj
+% 'Outline.2.5': class OutlineEntryObject
+195 0 obj
+<< /Dest [ 133 0 R
+ /Fit ]
+ /Next 196 0 R
+ /Parent 167 0 R
+ /Prev 194 0 R
+ /Title (5. Application Packaging Compatibility) >>
+endobj
+% 'Outline.2.6': class OutlineEntryObject
+196 0 obj
+<< /Count -3
+ /Dest [ 134 0 R
+ /Fit ]
+ /First 197 0 R
+ /Last 199 0 R
+ /Next 200 0 R
+ /Parent 167 0 R
+ /Prev 195 0 R
+ /Title (6. Multimedia Compatibility) >>
+endobj
+% 'Outline.7.0': class OutlineEntryObject
+197 0 obj
+<< /Dest [ 134 0 R
+ /Fit ]
+ /Next 198 0 R
+ /Parent 196 0 R
+ /Title (6.1. Media Codecs) >>
+endobj
+% 'Outline.7.1': class OutlineEntryObject
+198 0 obj
+<< /Dest [ 135 0 R
+ /Fit ]
+ /Next 199 0 R
+ /Parent 196 0 R
+ /Prev 197 0 R
+ /Title (6.2. Audio Recording) >>
+endobj
+% 'Outline.7.2': class OutlineEntryObject
+199 0 obj
+<< /Dest [ 135 0 R
+ /Fit ]
+ /Parent 196 0 R
+ /Prev 198 0 R
+ /Title (6.3. Audio Latency) >>
+endobj
+% 'Outline.2.7': class OutlineEntryObject
+200 0 obj
+<< /Dest [ 141 0 R
+ /Fit ]
+ /Next 201 0 R
+ /Parent 167 0 R
+ /Prev 196 0 R
+ /Title (7. Developer Tool Compatibility) >>
+endobj
+% 'Outline.2.8': class OutlineEntryObject
+201 0 obj
+<< /Count -16
+ /Dest [ 141 0 R
+ /Fit ]
+ /First 202 0 R
+ /Last 220 0 R
+ /Next 221 0 R
+ /Parent 167 0 R
+ /Prev 200 0 R
+ /Title (8. Hardware Compatibility) >>
+endobj
+% 'Outline.8.0': class OutlineEntryObject
+202 0 obj
+<< /Count -3
+ /Dest [ 141 0 R
+ /Fit ]
+ /First 203 0 R
+ /Last 205 0 R
+ /Next 206 0 R
+ /Parent 201 0 R
+ /Title (8.1. Display) >>
+endobj
+% 'Outline.9.0': class OutlineEntryObject
+203 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Next 204 0 R
+ /Parent 202 0 R
+ /Title (8.1.2. Non-Standard Display Configurations) >>
+endobj
+% 'Outline.9.1': class OutlineEntryObject
+204 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Next 205 0 R
+ /Parent 202 0 R
+ /Prev 203 0 R
+ /Title (8.1.3. Display Metrics) >>
+endobj
+% 'Outline.9.2': class OutlineEntryObject
+205 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Parent 202 0 R
+ /Prev 204 0 R
+ /Title (8.1.4. Declared Screen Support) >>
+endobj
+% 'Outline.8.1': class OutlineEntryObject
+206 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Next 207 0 R
+ /Parent 201 0 R
+ /Prev 202 0 R
+ /Title (8.2. Keyboard) >>
+endobj
+% 'Outline.8.2': class OutlineEntryObject
+207 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Next 208 0 R
+ /Parent 201 0 R
+ /Prev 206 0 R
+ /Title (8.3. Non-touch Navigation) >>
+endobj
+% 'Outline.8.3': class OutlineEntryObject
+208 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Next 209 0 R
+ /Parent 201 0 R
+ /Prev 207 0 R
+ /Title (8.4. Screen Orientation) >>
+endobj
+% 'Outline.8.4': class OutlineEntryObject
+209 0 obj
+<< /Dest [ 148 0 R
+ /Fit ]
+ /Next 210 0 R
+ /Parent 201 0 R
+ /Prev 208 0 R
+ /Title (8.5. Touchscreen input) >>
+endobj
+% 'Outline.8.5': class OutlineEntryObject
+210 0 obj
+<< /Dest [ 148 0 R
+ /Fit ]
+ /Next 211 0 R
+ /Parent 201 0 R
+ /Prev 209 0 R
+ /Title (8.6. USB) >>
+endobj
+% 'Outline.8.6': class OutlineEntryObject
+211 0 obj
+<< /Dest [ 148 0 R
+ /Fit ]
+ /Next 212 0 R
+ /Parent 201 0 R
+ /Prev 210 0 R
+ /Title (8.7. Navigation keys) >>
+endobj
+% 'Outline.8.7': class OutlineEntryObject
+212 0 obj
+<< /Dest [ 148 0 R
+ /Fit ]
+ /Next 213 0 R
+ /Parent 201 0 R
+ /Prev 211 0 R
+ /Title (8.8. Wireless Data Networking) >>
+endobj
+% 'Outline.8.8': class OutlineEntryObject
+213 0 obj
+<< /Dest [ 148 0 R
+ /Fit ]
+ /Next 214 0 R
+ /Parent 201 0 R
+ /Prev 212 0 R
+ /Title (8.9. Camera) >>
+endobj
+% 'Outline.8.9': class OutlineEntryObject
+214 0 obj
+<< /Dest [ 152 0 R
+ /Fit ]
+ /Next 215 0 R
+ /Parent 201 0 R
+ /Prev 213 0 R
+ /Title (8.10. Accelerometer) >>
+endobj
+% 'Outline.8.10': class OutlineEntryObject
+215 0 obj
+<< /Dest [ 152 0 R
+ /Fit ]
+ /Next 216 0 R
+ /Parent 201 0 R
+ /Prev 214 0 R
+ /Title (8.11. Compass) >>
+endobj
+% 'Outline.8.11': class OutlineEntryObject
+216 0 obj
+<< /Dest [ 152 0 R
+ /Fit ]
+ /Next 217 0 R
+ /Parent 201 0 R
+ /Prev 215 0 R
+ /Title (8.12. GPS) >>
+endobj
+% 'Outline.8.12': class OutlineEntryObject
+217 0 obj
+<< /Dest [ 152 0 R
+ /Fit ]
+ /Next 218 0 R
+ /Parent 201 0 R
+ /Prev 216 0 R
+ /Title (8.13. Telephony) >>
+endobj
+% 'Outline.8.13': class OutlineEntryObject
+218 0 obj
+<< /Dest [ 152 0 R
+ /Fit ]
+ /Next 219 0 R
+ /Parent 201 0 R
+ /Prev 217 0 R
+ /Title (8.14. Memory and Storage) >>
+endobj
+% 'Outline.8.14': class OutlineEntryObject
+219 0 obj
+<< /Dest [ 154 0 R
+ /Fit ]
+ /Next 220 0 R
+ /Parent 201 0 R
+ /Prev 218 0 R
+ /Title (8.15. Application Shared Storage) >>
+endobj
+% 'Outline.8.15': class OutlineEntryObject
+220 0 obj
+<< /Dest [ 154 0 R
+ /Fit ]
+ /Parent 201 0 R
+ /Prev 219 0 R
+ /Title (8.16. Bluetooth) >>
+endobj
+% 'Outline.2.9': class OutlineEntryObject
+221 0 obj
+<< /Dest [ 154 0 R
+ /Fit ]
+ /Next 222 0 R
+ /Parent 167 0 R
+ /Prev 201 0 R
+ /Title (9. Performance Compatibility) >>
+endobj
+% 'Outline.2.10': class OutlineEntryObject
+222 0 obj
+<< /Count -4
+ /Dest [ 159 0 R
+ /Fit ]
+ /First 223 0 R
+ /Last 226 0 R
+ /Next 227 0 R
+ /Parent 167 0 R
+ /Prev 221 0 R
+ /Title (10. Security Model Compatibility) >>
+endobj
+% 'Outline.10.0': class OutlineEntryObject
+223 0 obj
+<< /Dest [ 159 0 R
+ /Fit ]
+ /Next 224 0 R
+ /Parent 222 0 R
+ /Title (10.1. Permissions) >>
+endobj
+% 'Outline.10.1': class OutlineEntryObject
+224 0 obj
+<< /Dest [ 159 0 R
+ /Fit ]
+ /Next 225 0 R
+ /Parent 222 0 R
+ /Prev 223 0 R
+ /Title (10.2. UID and Process Isolation) >>
+endobj
+% 'Outline.10.2': class OutlineEntryObject
+225 0 obj
+<< /Dest [ 159 0 R
+ /Fit ]
+ /Next 226 0 R
+ /Parent 222 0 R
+ /Prev 224 0 R
+ /Title (10.3. Filesystem Permissions) >>
+endobj
+% 'Outline.10.3': class OutlineEntryObject
+226 0 obj
+<< /Dest [ 159 0 R
+ /Fit ]
+ /Parent 222 0 R
+ /Prev 225 0 R
+ /Title (10.4. Alternate Execution Environments) >>
+endobj
+% 'Outline.2.11': class OutlineEntryObject
+227 0 obj
+<< /Dest [ 162 0 R
+ /Fit ]
+ /Next 228 0 R
+ /Parent 167 0 R
+ /Prev 222 0 R
+ /Title (11. Compatibility Test Suite) >>
+endobj
+% 'Outline.2.12': class OutlineEntryObject
+228 0 obj
+<< /Dest [ 162 0 R
+ /Fit ]
+ /Next 229 0 R
+ /Parent 167 0 R
+ /Prev 227 0 R
+ /Title (12. Updatable Software) >>
+endobj
+% 'Outline.2.13': class OutlineEntryObject
+229 0 obj
+<< /Dest [ 162 0 R
+ /Fit ]
+ /Next 230 0 R
+ /Parent 167 0 R
+ /Prev 228 0 R
+ /Title (13. Contact Us) >>
+endobj
+% 'Outline.2.14': class OutlineEntryObject
+230 0 obj
+<< /Count -5
+ /Dest [ 163 0 R
+ /Fit ]
+ /First 231 0 R
+ /Last 235 0 R
+ /Parent 167 0 R
+ /Prev 229 0 R
+ /Title (Appendix A - Bluetooth Test Procedure) >>
+endobj
+% 'Outline.11.0': class OutlineEntryObject
+231 0 obj
+<< /Dest [ 163 0 R
+ /Fit ]
+ /Next 232 0 R
+ /Parent 230 0 R
+ /Title (Setup and Installation) >>
+endobj
+% 'Outline.11.1': class OutlineEntryObject
+232 0 obj
+<< /Dest [ 163 0 R
+ /Fit ]
+ /Next 233 0 R
+ /Parent 230 0 R
+ /Prev 231 0 R
+ /Title (Test Bluetooth Control by Apps) >>
+endobj
+% 'Outline.11.2': class OutlineEntryObject
+233 0 obj
+<< /Dest [ 163 0 R
+ /Fit ]
+ /Next 234 0 R
+ /Parent 230 0 R
+ /Prev 232 0 R
+ /Title (Test Pairing and Communication) >>
+endobj
+% 'Outline.11.3': class OutlineEntryObject
+234 0 obj
+<< /Dest [ 163 0 R
+ /Fit ]
+ /Next 235 0 R
+ /Parent 230 0 R
+ /Prev 233 0 R
+ /Title (Test Pairing and Communication in the Reverse Direction) >>
+endobj
+% 'Outline.11.4': class OutlineEntryObject
+235 0 obj
+<< /Dest [ 163 0 R
+ /Fit ]
+ /Parent 230 0 R
+ /Prev 234 0 R
+ /Title (Test Re-Launches) >>
+endobj
+% 'R236': class PDFPages
+236 0 obj
+% page tree
+<< /Count 20
+ /Kids [ 47 0 R
+ 69 0 R
+ 97 0 R
+ 109 0 R
+ 110 0 R
+ 111 0 R
+ 113 0 R
+ 117 0 R
+ 125 0 R
+ 133 0 R
+ 134 0 R
+ 135 0 R
+ 141 0 R
+ 146 0 R
+ 148 0 R
+ 152 0 R
+ 154 0 R
+ 159 0 R
+ 162 0 R
+ 163 0 R ]
+ /Type /Pages >>
+endobj
+% 'R237': class PDFStream
+237 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 1796 >>
+stream
+Gatm<9lo&I&A<G1rrL0IdieGHa/r+lUmX9#'<=\8]tbm=USS5"U?p":c[qBl;R&e!c<0,cOB;Lpn*Sj5-mJ.Ng],5*TpIS-i\a/hU"LD_JH_KJTKd%d-XYUMh%#bQ0nrU52M:`<4f>o93$k(MM=+,7?rjjG.)f=5d;4Xf`UFc-pFE+CqB\`1k8*8!r<:IF6aL.SeN^LWYIfRNLRUm+*7K:_5O`/si]$8>na."-7'b,+`G=e*s4D+g32M;i,Z?I23h,<,8?[^oSB^4c_,GGngH@[]+ii$W#qkc_e'?#4d^-7JDskAc0;%tD4Q,d]^G<jOKYJ3/P!#s1b&PT&joE57p_fe2d6F[)B2&]k@H`t^Y#Jo69kBc3kZlG.D&QpM&V(@7bK(qi]iatL]5aJ"S=\7"P[GXjQtD1qR#oMiM[E`13XL2,!A&S/=5TNNgbe5%-7NDWP2FV*CDW7*DsIJ"Z`6@ZJ2M@nXkg*3EU1./]N`Y,;tOSl]BZ,GiGCZ"^KsaHA0s%W-Eq'OLa<!4>Q?>6C$.Kq`(+GF1%2X)GCQKm_,39!N9`sbbrQ\?#mhkk+JO9$!>UpZHjaHd*+WdP<=@pKVDO!FSLL?7bujGbK]tXH,fBE`HXJBPR#d/)#<To?P/c0q;sZ;L!;?@fL=%B^[Mr<3p"26ad?U7]GKT.emJm8Y$nRq@@ggD4M$T%lmq3uD?Lf.s/ItFt>p(9$mo6D)\jU1tDhgA1*^\E]0uRl`U]Q4;,nV:8"/]"[FQjW1FYTOMAK:K4#3$g&>c/!0J?d/J0#H<0isM/YC:?%c2=Q$GaNW]6Eau*^>q2b<]$YEDKXWB6>4cpp_"B,6&qU8&C`!!P$8W+E^D`"nR.`6>)j,dsSdZ9/;Ol03`03Ik$Ah4J.,Nf@MNb7QoPafiYH64:Cpg9:TtJZf&IQ=:mEtiNX.;'.Pk]O!HO@Cjd]?Mb;DPqN!3S>_b!N5"a#?!&)Bs,=_jUZ2AY>\YZoedDP^r"#arVk'&BskKg9!P>6Qr%.o_"ESOCohB55XjacmeH$!TY,sgR.nma&;\CJ=q9JqX1jiZBh#)cp0cXTUa%+PRh>bK0#/P:tPJ=f8'Za"kKu3_uTI==]A`&1E.4XMf<Bo\4qdGqF99ZlVr!8TLic9.ShK_T8dVEYfJn+gmD7eZWMt0hjuf6e(bpDHSU;Jj,WF<+^:Tnm8%0;7uR6\'.MVtT'qC(5jAg5W!qAt)Uh&b+9OC%Kqd>FKb4cF,K7U'`]]bs6VP&;;tVs<Wq"q(B"fk/PN2Vp5q?$l9FV,AT38+VP;>Ok>km%C79.l1XWHidVWl)F)mS@)O`H#::skt$<"BmPN<b5-$N34FVE.3e(PP'UcF)+Y,k:;e(G5ktZ?f6tV(2IG$WA^qB)pb6\#C:Pe>6#<QP%*pmJr!l,X:E$i1QGK!aSi#0nDdX7#r(?C=4/&[h1370q)'u:[58\Be3)SYc\-,`lI],p^76gD%Qja:%L?X5KKRi&B85m_3l:hU<l(4Wp.(.eWg:u!ZA=7<,O+\Ik"NSUtp,h',c3p\.;9mDm@;a3-efDo*e07DUtj\76(H\O6m5L'(*lKLqD]?rdH,m5"j=0ir=Z^%Ni^!lIO:b)HE+hQ<dJg*U2?12K$)AqcW\8%a]sMR;lC!(;f[SW.:?`\gj6$27hMC<n9,?J7^q?*jF7pV+:/l#=ep^S+Tl`:HNQV3BMl/k!.mZcurcGl#5/h3%tKn);8A[pP8@#2N?N,2fLO^2%0*;SaaOoJG^2P&'jCM#r\$^O+[,VS[GFuRkV.@e!'7cBaW\~>endstream
+endobj
+% 'R238': class PDFStream
+238 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 946 >>
+stream
+Gat=)mn_[l&H.X=s5?.ZPNM\(3)2ZSp`ZGa?jYQMOID>p`$KDSrqF%71hdgaVJ9(!Q[:pRq7UDD:-Z,cGm//O_N.UuoH:gL$s3Mo0/uNN#ESSpf5qUTk:nCkZP?"*Np@OGgdb/UoAkF&`P.FE;(*Qh!0PZA>/.*dRHR7`qeKg5`VU#,?V%rblIY`T>eaOYh+WW2\!Gcd<Zcg`9b(q-knPEYMb$/<+_Me6&1JdUM<'g`>%C>(pP6Ni0Fh5NlO*cgcY4FfA-<bVk4'0adeIL;I:NI0IG9rfD&.*sMuZ5kp='*fc2sWpqToLI@,GT6Y`Obd14fpZhe2"+),X9R)M*33he74q18_-:2Kkh#mhMfC%k4Q?NQnHk[2Y=&S?4U'cp1[Rj36C4"10h>=NKDI3O3B:e,a?-Ch?9DQe>:lb=nUFGYlT7"Vice;`(LRD%"CPal$'bBAGZaoumR\1\dA<Wl\M/OY\u@F"5c)8f?/=JWNLfC7_h.rK%c0fi@$rl8(tF1\5s!0:`(DK*t]DAdMU'KuE1%Rjf_\T[)`lZH-+FPMBf1qV2EGKVNR]N7R-?)t8DQDL3X+dG;&d\W(&k(EHkZFOUJO%:(+4)2KC#U+6r4N)<^hl`O3.Vjf0:F1%`t.;k'L0['K/1Z1:q-7W@ZPQr"NWld'_pftohp6t:dRu>B2pTuqfYTV`IjZFH`\!P9HLeRZW9J/RG\f<%;$JP*QMRFgNZm-qh!l$`[[L0Z^FP[neH)jRgX:Zierj3fK>II"$T.!:B5:jp[lHCY9Gp*Ap'q`uO7AK0@e`ND;7]@'>rn`gnTFUOSH-TJ:MG<Nc%_<V8M)sB\n9Uku@0;(RRrtV<3&>2q26?IDG2=-.(55UI:UHnDHqLm(D5eZ*GNP=[GULAs.b,lh%G^;\$b<pMVo9#`_Y:mN<u\JfSM&bLoaY,4EpsTNLkcQ~>endstream
+endobj
+% 'R239': class PDFStream
+239 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3247 >>
+stream
+GauHN>BA<(&q6a9s.ILu/=]>nqi*OBQa9Z-/kb=X&'HCo@r#\`Yq9J-)013)BuqEW4dj6[93_U/Htg"&YP!%IC^Z[#a3t"-)+&7RaEV>@b=8fAZ<Zajfa%08m.n!VqT!>gpKV7`3:PjohK]K7=dsIl0HJ@1d/*PoY\LQJ"ZZ-;1s:tl@CQa>eVF8"e<$R,;_HH*k9ZSqK4b/3U]7<C^2FM\giXsJI&mR"`#fi@0jR#TkE'7bgNS8'V[30.d!0+HbJD>9cS5g&pUMi#;T4ghr"1mb55J]@,NhWQS#r&C$'2-Gjq?&]I[<H#J`M]_P('T:8_#,0Jk2,+6D?J/)3p$>LmJE"d=R]5j)^Ma<31>I*p2abQtHSbC_#X[9Wlb.4=N9`&:fPVA)ING@*gp8n,*%OkKe/_QiI@.nZhC/Z4ni22Rb&3FM5k;K]/LW#Z=V.MYI6Y.!R?slea,RqR?P\;9*-7d^20ig`]_28sAYip.7L\^ea6N1NI\j8=lI^?DoP%klh.Z$=H,]p&<Rr4!Z*,5g!U>mu)iO=ABMuf&q6qD9Ig`htgeF9f7LJ<:HoHWOP>sH`<UkIh1JZp5\4u.+DT3"hL:lm"Y!U,3U5E[k+D4AOWVOQ^/F!Wp$1$!ZiNm4Mb#;_p=M,m!hDHMnf<eH,9%tgp7&Ef;,3si!ZLoOPjiLmjkG$LRVJS]+L'0hfhImhsmO'a6FuFaC'U<r1_:6]U0bK_PbqGB!pfRJK+Y=O"C3%ZkjDGC@m1l&9>u[T^A@?a8&8#VObPU(LDKsJj=[[gtE9;NQk"m55s_k#3#sSGu%e*OpVqmgR*HE^rTD#n'E_&,r5_U-/9*1<MIAe^M@=dW:RYQ\5Mf!h(f$V/:`jFVW.cuF2L&4NQ'L(Z#b)=+4,!hYk2=(!&rComXUCGDU:DA[JVbb[N:K;X!"-CRMc?-#>J6UneQ=7X[s(PF_MNIIE#k5*k8A?V!.-&\$PD(0+k`@/1#%>O?*LibNQsghNdW;5ck_Sd41,Z@OVJL1"]MU#jc=ugC=3,77t,ViZA?KdBsa;oVppOcr`Jt&aXi^!G8SS&*a9'\dW';'$VqtnIXchbKZEs8Z2k:10_M=-.>RTl3[3I!IF47l^NOt0I"e)(]+f7p['lclmTg;W'.O-B87K#(!7I3O'bqlQlF[]2,MsoD?E-h)5bkj2J:3j=26!7TS0!K(_@4g8N*5$Ki7:b?69G?<F9\n%7O97CV'?KV=#qCoEQ%-C!r$KA+WO.#_SG-#c1lU"Ji@COD6Ol%U#[#;58?H:b)*e<CZ8c">ek.fbj@(GM99i<;qTg4^Y(1J3XN<O<p8modpc5$HgNIq')DG?S8>[Su!^E5dg=d?:$_(FA_Vq*Yb_dI7Q'gZ;Lk7i)t80TpXnSF]ZBVWFR_7^,qU<93S,:#"Nh4,q2M7LR`>0;b]k]&njqfeAZU:#nrf]67d!*Y>Ra,Z0Y&tRR&em=61oV=Nsh\.[bH,irEN)((1mZ.Epe")gi[!IhoYi\.,r:V+n/7/VC^%mKl-iXn?U2!4S?hVqb(=#oLD:n4V*i!UYX2A\"8QV:%;+pH^Mc,ln<fRAd%.A5r^>[Tf(R%eBpCRO^'>qP-SabTu*K^!iJt#qUZ'h6DRq6L!l5e&apZgTJNCr]*i/+*[0iopUU/'baka[iAJ%[I"*6f>^k#3Sa!*&$#,@)n'Ig5&UfkoKh$qiYC10[[!)r/&PJmf9fFG^sIiRjW[`TPmK!kaRMNNrZioH_^KknKtAHh(;Lu]$fq9Z(.dPm,T6F\Wj>o!f+2:qa"Jd!o"uA(HE(F.BXrWNQ-@\Hcj)q->A$=\)+G]KFl`:?4(&BkJUM/*pS@3Z0HZ@X(ZB)$FbcZu6-GdiIQ1qqh=,75IX9m#mW9di;h@af%jAU=)^p%U[fqmkOSB%.\Mu:G?%4?kp-uuCJ0V6.^'@+&q7pnMq\(P;-A3_=7IXF;S$U+)P-Y=V't@qZ+39/r9L=Cs9SBAJVRHaLT]&QqCgc<*^St>(S<!_($uPN"g`[,&V!Z!SqSg=&ePE;U2qOX4!C0Y`3dJG?qaet<#P83s2Et<[$t`MDBf*7.'d;%u-inuG1s!^'(Oap$/qpV7rgM,NR)E@qr%BI.:n0l$F_^-l2N>`=@JJT>1K>'D"po6CCmr'6h1PR[4'-.lg[*r*n$+?j%K511WU"Y'cr_],Y=MLr,HaYS>[FOXH"1C3m]lm,meAi`%aA^V,]bW[%jU4EeK1,lQ4/<<$V>9i%Jl!JZ@ZE],DfJQVb#dr[_T(-4!6*Cm=05d8M8NtBqiii;#[iHk#KHg@6f6j.cIgj4&8kqg-K)V<A?KlDF_&&\gY:sA4bm6U9Ue%!d.tY*@-T$IFG+DL+S(h2YequJh?kRb@-occ9tiR%C`<%8`Y&k,Q_AKn^Z]68q,rD]*EEd/!:]"<g4H32?eB53GOME^^)@R<804H]donI_!E]e-nV'#NMI#*gE!DOLf&bWQ^f^-W[ZW^e4u=c8D7(S0m3UAFta@E,MHE:"pfRMjk>f6U[dSl1aUc#hc9fl+XLU&XuGel7Hj5*T8k'^g$Ylm:I:+(-RBJ:<@k26*lf2;ku>c:\5a#DloG#U"M)m)!bo9DUl8B:lZ4Itb#?J_.&;gU@Unn\ARq6.AX_S<fsS&&p:$U+&3C,54-(_!`ecZ3p$_,]FLjE<Z/[jK_I0\)1>Fqr2Kmn?$'C9cs83ja@(-huJI]76l4]p[a_4S.5tXtX'Fn$FGI;>USNoa(:;b(j-Og\'Gs*o*+^%T<I6k.TqCBO^d28A9$RJ=&$D+nFpc/h*hjc5R%/8(KAE'inDFT',n-"[-F8I_!Eh;uKZ-h/>M@brpU!k6?]L5>SM6ARnan4>koaE^>f^o+)0YZ=MU;UL/n&5)<=G3g4(Ch&Na7&e_?RAJd:5U!t:`gWAPn]Rd3;fmGY@h!;GsX@XkpaL2\5QrOHaoF:D&d`.S5^g9s3)i%YK^hb:!"itA(DK3&$D;r./a9@ChjqQL)]qbFcH@5'r_,UdJL60g#2Z8^!iUekg*X%DpBP0RC7GD(XT*TP[j%l0;*0+k684+"kYlorVs^.oiq%H1jVZKlJVmB^r1l/UW6EOcmq^b/u-LH:\FV6PM6_sM2?HqdGA)Ns6V68YB9L9H]lu\;=IJeR?)Z,*7E#Q>Z,n'G1a76(U]BDU)r6;?:&G5r%d8+[iOF@LR9d6VL<Vs[b0k9a09UR>FmM#Z78ZHhI(O6JRP<dp^jIPo4S(.k`(;@~>endstream
+endobj
+% 'R240': class PDFStream
+240 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2935 >>
+stream
+Gau`U=``=W&q3VVrW?nAf!?Yg]ID*013U+343hAGmC[9/JKc6F1F/XoUceYNgC<WPAKCCTDsU(1*8QVBYJ4s?/ofgieUOJ#+n(b.p;&&X8![rM"uIIG?c^dgm@/%jf56h/!V&8jLTkDFmZOR(NmZML>q[IIDr6(E[o4!iGncEQ6!Tbn1rr1H0b%!VUOV>V\HmX0b<O)=mooU,qY+4kiO=5F@P9]Nc!_8:bmUnS;h&oK_MbA$%*c)<BLI@Ga4iO!ELhnT3$-HiS:b)NnH1c;]Gnr6c+kUbMU!cF7^0rWbNt1OOtr5QB=+gd:+s03k/mQZX!CKk:IL[djQ"rg<Gd5Sbqc_;\_&Z/gWc]GAs09aA7`nqc0,R)cA!P-VCM-p/5sa5"!QBV%ijVp_@qt;O6=I!n2N7\^KYq@M9PB#alq&B_.<,ld'VeE7blJ1&hW6Zri<tK4sDU#Fi%S@KH:Tcf$I&Yk(]-n8<O<'1L;CC,AN^Dm):/YjBq:V=Zmulo2ggoid>R:OSXlDcGTaCK)"G;o?K=Zgp"/O]XfKK?1OE*Jh+f/WCZ4Ha+`ifjr'Xg@LH-n;iU;7__].D]<>4^I-5=AU4=l5@A&"?IZGIpT@^.WU=t]QT0GLuF&oEI)<BbKaXs!^\gS3e13%S!kJh/%cZ8L-O+[3oV2sCD%F0)oh@m.@eV5LWQr]rI.8pB5K4I[H*Qq!n,tk9Yek*a%mXK"$$J\/*<:QnWDD(rHdA_0,o:2m!=k@4g6,Fm-C]Wad'i1$`<'kNbj]]_L_$0<GL6;m4r(XT5^;r]G(U-Q9U#]]Td,HlZ@-$,JiWks_,!Uup$VOM_a'?;gCL2$5'l6?._tbTWTVpqf\/AAiX^ii>",LnJ(dJ:?-ggD3WsIobJJ-m_'&8c%eODeZ_q^8LnBO1r=LosS\MI844BH&D`=CI3k1$JF'*TUp?K5"j&j)s8@7ah^Rfu>LkXBI\2Na8]+n,AQbTZUH7ls*dPWTlZV`=pbjZ>c8G^r!p^_#I:7,WYdR.;/J*cZUcL`O:XVrU=K/$)q7m/ofaUM&`8^h=iKJ'>$&Bn7<ddg@hbL(.%9.&Q$%,UH8XL;]l7rG\`ed>gPn,\/2VSV9[0!@0\lq*BQnIaF"/Wm_DKPfChcZ3&YjFg!8qi9i5UGAK-2[bDd0VEp&C.9U,#5]tIA/bi-R2@3PK.Pc<lp*&3N.(PTi92cd"'/\a06"\$L.?bka1(;)m!-$5,$(0:R*MqAFaj*;=/(`/,!,=I7NXH./?EtT,&RK9petnTTfDiQfC?7]"3]"T*9r<<=JV%j?1>1-Kn.FT%r"7k1_B>;n++i7@nY3jC6u?TVfF3o0;KCS<@E:j3m1$qrXM&8_DHH&;$$Csc.s)=Rbd!1nkf4u?MuKmrQV"pOInj(\g"Ft!$2Y+!*K<Qim^NrWL(ZK\UUud2lRgep%8V$n+2HcNW`eQ:aC^3>OBDUr7D[/OdK-M'i7A?m!>s4_CJs^g1,g-eR(F)@39Gg0!0MD,)BE!ZHedM^m:2]AG>eW*j##OoojIHg+W"+5C!]m&/-g#9:%0-))QcSa>AHFPN<?SWr+E3AqU0Ne',#Cc-E-qbT3[!a4;"^54BkX+9G;Kia.Ifd&lJ-jqdtnOEsT'pOqhlMS)UomdBu@i5j-5Y@b*Cu#CJ`jNKL+</s`?$MCf*AJ#-sc26DbiZBVPT*.cYu06,T5k!TS5hX1:dT\>OcT@>u%Yb/aFILr,/pA:(mlli^Z["h?tC'2AlqPL6[^u(?IB6#:&KcZ>Mis>hmHr0?b9goAnmE>7",m_aG=Q?ZT6bpn"^9X6.XsP08[f&YDoE^<j4AR4R"pdNRZUelI9"Kb04f,*]2.Y?HVq=XC"-Q'LiBXS[nVJU/mR$8HUM2qRnnF#&VYPPb177'<dEZGu//U)3_,A%%Ho--CjJ)*id:55WZOb(46Yp1C5f'oN$:\7_62!LZ\j8&p6b6BQ"R_JYdo>q[Tl(iSA%J2F1t=A7"A[M%XcSePCP+Yg`u`A!(/lLr97X\"US]m@53m,SE4<AhVi"IKTLb2@U1-.o3k2W/loHET$M?@B%o)<hA'i.@Q)XG"Z#!c[80KaSO2m_+qfG#nigu#d8?)>@cSP,PJ]<IR9ZEP-V"mF*H#p2@L2h-,([W`6(II_,%IJf9-*LXDQ5VXc1+qm%"n`k&Ym6^OgoK6cqr"sS\i4W&W-2IQTMp)$dQCCl'_7uHj:1QRAS,laKd)e0`O$Wc,DjZ_VR$Pa=7hGiH9lW&=',qZ5_]TRR-Qd\]-OSbjJ5\(=kQ(F29ut:ZHD]h"jMa$WbfI$r#WgrY39Y"@]G<2#\qjh]mY+OO)L%,DD,f%0kYl[\:N25[#WYGR!f5o=n162chd(5h<X*Z=qj4!1.P,"k>EfMQWdZQNB<4<L9G&%FBb38``]-<#;9c<M(b7MA>6hGIC]1KlR2PjlBePq2cl(2TC3kH`]e/*q0T7dd:bgtmZoqYTXTVd_9kn.E7\bQg&]gj=2qY=htd5X\`CV]XXbU,B>ShrbGe2FIHOS8,h"bhZES&`eslc9lbnB%Ma=5G<X\%C#W=]s5=sjg_/r0p==\j[V+sOrpuDAU-0t)D'TAn!FmtIh9IRS,18'LB&9LcD;@&cO#S5aUE1'Gj^%ZuZS^3stI'DI"TIZCs/m/:UPLfoZ4MOta(2B_$&t,B.Jk,fsIf'9f']G[Om/MtmL]5!)b_$sK:3Fj9:=+C>fiDiX(#=IR&6ClI=.^&"q=^J_AnGtBMheMpFt<6ef?UfC^!I^r&Jm>]H[GHDFt7EhrLO+h4>)!!8Zg6-c?aFF-O^e-m1N'%4#>[@S^a5hT+>ZVHK)G(>h@70pH6gT0AZBjO]*<f4lW:2k$r$e1>aIq@*hXMCSEn'46IU2Z?Q9m>&]buE:lJS=gRS9USg*ro%])UD:Y*`hiP<crWagtZ<.~>endstream
+endobj
+% 'R241': class PDFStream
+241 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3185 >>
+stream
+Gb!SnlVH9V(B7^?s2,,u%r_]4+)sXB7SDrW<M1;ZPu^5_1A3!`efL_1Rl'lCh_Sbh4FZ$:E8(bs3-0Q33TloX(_*J6XmuF.+/*m/1qM8"VPDZ[Bk(_5<Zf_:p%HX3r_H2Gjr!?o1,XW\0Wq**/K7WcWhJZ(g:r%<;Dk.]WgljY[.9?V.6n+59]K),R7``oLDt>OStOWkB_?;Hr=AnrC\I6ffpHhJ3M5Rt=.P3+C.HlcUoE,e?#h6$24+mfFf&jKoXsN!-`UJ?R/PgFL_BuqUBFPA(V?96r&J-@0CE_C`U3Qar+:Di]):4?Z"0/<R`mI,C+@5FJCQm`=I_iJ1&<kYM4Q7O`lR!@'GL+`5g^>l#=#aW7]sMtY`DA/6PuQcL00R22B5&-fQPlLSOMZ8Oi7b5CJM:t0EaT.E/),946Be78W46Ecj9NHa<bL=q\D1"Z/o)K*YtL$60MO8JlZ*BVY8hn^0dSg]+oY1.)]aQ`=;qdEnp=+1KB7sVoZ?;>`eVh\K2EDU&\W]+Q*X,JhBoBfX\HPZ%9i*d'RsNGQ86SG)6=n#c%@L[C7G08aJZ.83f<Iim>\XG!McUn0!T(fg+=40F374R(Yp#2\oqA0YnpR'[g*Z\4#I/G_%F@+TXRt20M>.H&;Z$Lc7qX;`+>MLrA1e]Sh:C&2u(lNPqF/ChD,"^P`SX7Nn7gLZ>/)LD-LkIe*\#a-nc/opU8PGIb@)<e]8ChXTFpAubg"l<S=B%NQJRc"/R1.D3&TB?r>gk?1)[9p)-N\1WK2>sPC48=d^r8Al'=:`%P9Xng!;%$?52EL7W9=>N(_KsY<tUY!WYnT4uMo[hCZjlPm6/0C>`X781_I\J?]p6#_X/3hD!]OBNF^U)#?'IJ'7&bj&E*!PDfkNA&p`0LY-&_RLJm/ZOj^klpZGmi^VA2TVU)H725gthl4_-E!CokZ,eH1(tgB](na9;&LCZo@oS-'5;<5?J72ljJSbB:bq6Y3(3dhTlGWJh_VgIFnM/j23KZm;CpFB0DaBC'Snl0Y'%0ETHt`67.""<59)VCs;%unq=5X56kna0b<^"V=!"2-"ruB$]2b7e<oNY3\b6MS"SAkgCNo;Vrco]eS_Esl=3PXE(S`(QE_+2Cp])F<(1A*qG5hodmh2%2^[tE(jh$cgIm_u8@Q$c#i5N(p\EiLZ?Nck5bR-Y9)B6]j%6Nd4>5>7,2f,uo:XW?nF3aYNinAcT]:Mb*:q_OiFE(PT9a\&TAQi8%nZ(XT)$+jiT(%]ZX_g3rc*C4T@+OTJ=89$_R97+;[Qf9I^jkeiPnENiAl5o$&u]&XJ"m][;6qGr'O@p,CUJKmHjS$Y3;YVo)3Yk1(85I_%%q)IZ-4\#h/#($U2p@X\c,rE,b"HG;(7>RCU90@Y^R_5f1gP=U26!bDu?(BX(#-P[BeW/'Zu^gG#q=bQ<j,a5@9A*qQ?se1$"l7-/IfI%GoFcK->W-eZq])f9$&9WSfr:(`J&(oNlS-4ZuY")(0N')oe[PsDd#LUm[uBX!(gY!cU)5Q#\KhpE:`bEpf;_I9ihb`p4jeMcJU5U0uLfdW7N_'2.ERk.OlAGqs4N'9+-TDcn]Zl!s%d)Si@:Ut-Mq-Kk<2\`O8==4V[2'50O_+GmlE9iZ\m+ZBM5GlJ&G-%o]IRVcHk3j"I>@,7LA4n:\d!-#.\bs;Pq%ujRA@%:ZIR,8tSX:X^9A*<Im*[K,M=qcQ5_F3tNpjqK-MjcK$0dmUF6!2([;g832'6unX3J//?ghsLDAXslZlP0*/ni428?aHmhtXj]$()JrT#IEBQnT\;0=f3,B>G@,ZPn;/&M30#&*^X5E2b>X<QP$>]WGu76K7V"X_&&WR*Ur(ksfetiYqh%=UPN%"Zo2tF+e0]K0"^n(?a(]7p.r,,V@]G;Q`HE?lN$ZKeD,aJ-!S[h\&&^GgFU8b?!i0d]2lEB<+(=rEUs9oF+@C=li'KlC1m;n9sV]ign'F\2_Q^Q'Y:;[@o`A+'\!tGo_\<N$9q3d[M3?ginX9@`#9JY]IqtDb'@NUj,AoQQ&Mb_u9mqfNTnb&^h>UOEZq,L=l$P.jK:0:/0&AIGnKaDMDH_]tB>-:P4:8Lah)VVG3!+UdZuP/:I4r/>$PWS%n0/#/*)s?iL\R/hi$N6O.Jj?E/g.XtiS((AF\79\>jm?(8"Yig%dpl,JP:F9Fu_6ehkq$%r&N]7;kG?*_G,[NWZMQ#cSi41,/*o[A`2CtVF&`-Omrf5nl:CnN"HTQ(BC'F*r=T-^0php7XA&h:N?e:'*N$J+P+IK.A3gL[TcUW$4k\btL*0bCEG$@KQcYVBgeHpQ*8fK4eHp94&0?:Vc:3<'EgS?T1G.fWh(@):rU,s5?pr(P=So$Z;\pMAVaa.1"q(MOddO>/(95-APY!a`oQ!pHLf!>NP"aJ]?"^VspX:'.d^=[It+N@rh.e6rerOT8AfFk.7oA8?LEY>\m0#aIfc`2FEi!SQ@IpbH$]-O3Tsj=r-XZB(!r<$U(1%;3c`<=*g!'U[$!ee+HJL&E5q'%Ibm2A?7L^Hq@#Zt,4#W(IUU.\Xf$7Vf#dm'MMP8:[^n3bo'rPo4@u:8bu.&LrWPM,>d\n84QBLWX/I+p"\V7#X_dnZgK1C*YmC@4W%a.\Y.V!`OBa3hk*&Y^_<uU0;$UMW0.XZ9Xa**'I/7q=;VfJ4Y$SDN.hhArc#\.UPbg"te.hLY$A]H?l(iB^i]-j25h&nPc`pN"6`O\XtkkT'EZs@aLd%A,(!D?.+n0.ab?hVEnaZ7lae+:K8;P:>S83.6u=G&IKMp0:A7kf4cc1h5H=,1.$PeU+Jl9,$F)7UYp##A_&1M)sE6F^:<Y98l@0Q,sL:)!K_c/f3F2'Rq;j>Zk?_GZ\0r$]$]h%%D=kW#\`kD&]';nid,U7,E4aUh".%P1hnR3V-,$5)Ke.gN>\r?jVBM=AbY[NB5[4H8n5cFA3l?t(hBM0Z,/RgR[#sZNSjCI(hBM0Ysf*NV@pR'0C%YAGTrMiIAp&q?ul)--Y,e=2D4$D2_m+5Y0eMAgSB[7Z>gahd?FaVdAuf;8SY/911QMd%<T=C(n$-_!q4c2/Q][W9(_2T?>Cu"/R%r_@aoEu[-$"]F;qo1&`:W=RD$`*#'t`d<#Cj<OsEBW2,ZdM)RM2_>"'77,ac`ChrILaa=`N/2T_lXEXod2o+1QFE6A~>endstream
+endobj
+% 'R242': class PDFStream
+242 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2279 >>
+stream
+Gb!;e=`<%S&:Q:Zs"NrcAd_*Ja_0<T2a+V%VJ-u&('X7q9=2r5,#sf3li$K<6QNlS3SP<(P,>\+A%oK5r5OLJr:/V#0EHDYKKn>gi!1qUKAZCV0ROD7LJOOiF2*/Y][MTXn9Q+FZhE10;nm_Bp!-`id"2#A-b-0`D:J1Rh$si,n9kgSj8-,mcg/rDBC88ci2$63%)9[KRG7\(qu'QEpp;JD051ANBnC29>$g-p4Er5*QPM2QOtnOW+r5?ALRdZsG5K!T=2s&<f-G:*H*',b*6:Z$&OC$=.0(3h$<T8&I)[=1b4'Xq)QG?JGm"2(9JjUb&k:[%3L@P01_ud3Aipo*K`T(Y2^IB0e7+)HC]5n!RO;tTc!t@*2;H8JH)WdQRcR_A;J.A#at-fsI6GNN@&g$N3+oV6<G*N:+;,BF(+cqD\U[.(XO./Z!@:;s_kl0][+4;<Y4E*#X_&d:^a,-o)'FSMRLk^<CT_C.\n!/LTbn.?`une+2's[sQEc6[D'i+f+er;?pnc]s5cD%Z2'KCWRgIk\N;kje^03MMd#;&`S%<7I_W?1V]j5[r/3TYJUACSgrVE8VPM/7qI(tEJ&((P1QVWUkS0__CY@NHFO+h],PZ]b.l_uTVM6Apa'24--@PfW)B1&!u/EXMM+oWi67\:CkA;DQR.<XBu,VpWt1hI+67UBI:.-\Pu^?/BF:2/X,n--]4-_\#Dj-k*>?nNu;5s?Xc#mTZ'-b1Y(Xn^1epX^kn:Gp17inuHs%IOckO$sl%/m8]W[^&7<W\+t3TM7Lon:h#/4!SlW)Ao6GMQh;Z&\&%/Q.B$u=LStk&:B"JDFGPK8@:&]-5i#4dKgkaVG(LJ=L/bIIk&<>'Z;C[3P\%rmS>r5.2^&SNn'X4f:'KK4(T;Z1Z_jX"_HJVKs<aC)umQ7U/$J3\c^H",V&l?#uH=bmu*AK^XmOIO\iYiQ0Y?F\mBAt$Q$&TDsO08#=f*nV,hZTFa]eSk3tkKoqKO]os+@a]*l$e$oQ85n59LA4U[9->VGU5d&].RG5qJ"@2?7?IA":!Z,Z(pKSd3&cu*fuJbk\O=AdYa41<o,`u:dm@l7`c2.nt?f#QOVZRgF0@,J:aL=67Meb6[=b2^Hup%1bUH1;eqP@'X[hOUTmVDmuT\p2@qI%08N<m&N#mdc!3I[(131]`p3.sL_Yi>kWBXNRq,<SD=ALqD$>f*)9(o(l\5]D9.ScHjds1i6K<A(ZHLq4!Sa?NXtH-Dkb_nePO;O#2i$d`&=Pd!k:/;19e)Tg$Weq6;9-CMka#EW)W/e`e,hcsEbH7\;]tYbM:1L*b^D=$c^,7.Pup[/7?6&2K3NLr50cTe]R:Wm)8f'j!t)FDf,_dp]LI5W$o*KI\s:?=#WaR'g+V1:uVo)D%693WDie"-4@^YQZ$oCh.L1[jaJ.ZC)rg:olY:d',RkNV^jmd.d"NPs:&-GLY1PMo/imFMV>t9+Ss7Wr1Z-A"c6<,!Sa7VJgH$UMo][=#\>+,=[&ZVb=_d4="fB)5'ghR)Oe=RX;"0SEDCCK,)s]XBHdRA,bg=?(":igEn@Od-MK+aNPFZ9!Tc6"3c.2Ac2_+koEq:V:REAA:P`HG&)#U)W#,](GIEY=0/!HF]D@]B+(M;PUo^5<*2dnC>5Ok9-5*)nn,i^#r(G]@"k,u!@eWV[I`"f3u:35Y.I"HBhU>U%i`915^2g]O)&\q6+mA2?n1OO,.<&P7pJNB@STV**@m[sa.[9'ONAC1^UYXLG\t^GR!WD3kEBI?m2A2WBiB_W.kfn&KE#9+lPn*b'u%Br>GX=8W(`t:AM;&[7DXqM>fUd,ZIlnDO5n..OO@%W5%?=MKaBNs'CH/$gbj;uoc(;'Mp,\>)@l2V82UU8CF&>Apr?PaY1;^`<8QtO`afC(VnRdanT'P.m@mmDW2F)MBVf:Ob+!o)C1:&;9%6:1AaEOWodFaQ7`$iQfL:C.>YM,4WuD17]9]Q?;mMcdKkn=8Woa&'dLD9/:1W5.9i0@A'thq7.VDg,:(_$\pN:69LV/*q:&[K]IbC@nJ>/JHohds5qn<$_S)4IEm<dYM8&MC>gqGg>je@X3Wh.?DH.T\aDM7*B;A89G0=>7daGeqiZf-n$\j@#6(W1Gu+.AJF0*]>GDm)?SEH.*_=LWYY(t:AC;h_9rE]LdF+A6jDrQ^1k0InhL'UpK"6"o1_'FZ@E[qpZ1:"!Nj`(Ee)kg$(S4^h7dlQYD]IVtFH>fG\`PUL#%ckJpp[a<2MBA&)!)#)&<bfP&4*'AZ?+4=7(`r~>endstream
+endobj
+% 'R243': class PDFStream
+243 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2767 >>
+stream
+Gb!;eD0+IA&cSAir.k6tRE@Z1(9(@oTDY"n(YQN\jQg(::'Vsd$YPXL!Mg^sf68#R.8l=GfstARYnKbU!Bc9gG5#.dK,4H2pAZ6>3$,uRHOi4\``)@fX97K+S;lF?q;)$rq;^9@pce"fED5c2#Q%hINV-LmcgSaLgG_*m="`!8K3fA60mFbWgGhF"fOnJnZ=SOX/N!<N0`DO$J$Z3UCk$pf55`&'VXJ`C0:ME))OP:tP7s?VPlQ9p$'3T<apb'QdMYisbXEYP;M6`()Lg`T%M;KS1O^hsLq#1VJ4s>r!]roAp"1KiY*mr-r)*1`S+a7Xce>J<i)hKN#2H"nStmQ%c-?<9^"2U8f`&.1]\R&a*F5GXrAiKo')6hqaahk.)UK[3!cE'?'/5JlMEZm=<KkkL5j4H-6ZQ,iAti0`?.,)We.dKPqTjGHVO;EEhK(7Kh.tLs[@]mnOBNqb:/SU/EKl,[a`'I@nJq'm+p"B>a8kD7\/pV[+=t0AK"*<I$UhM-(1rTh#XX=?Bf4M*VZP)jU^0jLkeSj2"2Yf\'50Bl7`qOF7OsKo5=)6"N)8:-g7='`oM!S\eC,ISFZ[:Q@)JrbEoaIn]\6kJI`][da)t.c)-eAqKn,qjcJ^&+8f>`m\MMt-T`#SYn&*<VbR_1mnUV#NkU];9E_HBojj?EO6,403(I`S*B]mUHc_?=61:/[?jJ\.Y(n]^%<$Iek,p5/d^'A87]0ooA^FoEE,>5U-p6?UGRETe-P::+>9FD'&p*l*n4;&qtEluNMLbcn]ZM@bie?6)p*3C.BL0*Ad\@^;D-=hjcij]Vi8U1pm4I8<S!YD@(PU!W+`fHJL2g\p8/sOKY\Ne)6V^dSR4jA[c.=quQ>AtI"$GZGSJ)?e^4l6nF&HZgq\.r$a&kbi34F!W@j7Q^6,?3D(kX`0mfo"i9^^W@+r1LT,hX'WIG3A@o\G:V44%?PdT$CYOH+V,NYLMMJ)AH[6<-Gb'D_pkTqYD`=qOdQ7-9s,K#'8@:r7sD]blNhC'^a6>#2lsp9S1SE^N8%S[=NcM',gD?<g$4,pgJC$;&m7":`i\R^7'u@_lu_,@&<WF!Xn"G[USi?VtF#@pc]ne0g/Doh&-`9,='pb8/UAJZA8a0/(Mpt5X[q#.HNB\0l_W->a=eVjHnjoM^0!?kQds4ki:4dn?ar*qBX@<)0HVC2*AH9EleWo(!,/]o?[gjP^K<4/s7-S5?VD!/a9TB'BHOWa']i*n@@(>LeeCr<+<VeZ%QN"`"N8]HRNI,$9,Tk$11%QS!E_8r98I-kO$b=$H2<gJ.sM:BN1i2;=2YH)NpcoSdCGVL"-W3ROC[7+qmofo`;G7*,\VO-KG=USY7PK6&gNc-&N8fo7bPgk.dqA5K5e7!8>^3MI]K-K9:j[$iGaC1)NUR#sFRb>%\uR(#)iXAe?r:'uUlF_NB.SN$3pr;elt0>[Bds*1I+-bE6I562&NY)XdIg%*kbT8(0.%Tq"k4U+fKrkc679bprEZ2`Bp?dQ(5O"ueU;>;Q"Pe+l\]pd-Hi"X9o=NmFA;a+(*Qr:tUKZWMrBN(u==YSiPr54<?K.a?tXh2>J&FED>'-^S;@7P$&MW!NjRX0($jqfW"B_4>M41@-ua;92L]])E48B:l<Yd%DrK=u*`p#+S:RmSNOXC1FM.ITUa(&R&bo,#X<]$W^Q)IVKWo;STgQ--g37&D@'1kECu(#[kU!0Bi[1#+$eSY!hb5Zq#G`&rkFmdimQ0b1P5s8QfgDAjO*8Y"X?R4srXBXd?;nI\_#*]NnFoA`\`A((RbYbcj/F#t[Vkn*TXr1jM7"9i&UL<#/>%&a'9EVqKn\(>"e$IQ@<'.i@'Ej;*"jOoVhU4Vbaj4AQc)>\A,*;"/^^m^X9;krY&_<ot('YRUP)7.VT)]J.;&6&Y[jLKPW%rt(A1SmqN0^EZJ.c-IKg^.G!bUU9aq`LGa/GVQT&KGgC5Y=1/A?H)Yj-VGWhlHm*'"m4kN:M>Ys>rY!.g!'YA0.(luA[n)A89)D4IdB?^r6*r9L^D7;iCZ;bN^7s6_>JLs?7%O,;m.*QI+YA9<V'5B93%Kjg7!h4Z/pO;Lgtd'1fVJ))0$ZoXg4cAcnH#<E2TM)$;XMjW=m[;ID<!Y7g-+cZl64(koHt)f9^D2c:bEu<P&r)AJc4C$h8&6E=$k!9oSm=-h),'1$n<E>'-Lh]qKJ\g!Di+Z<Q0!Oo<NX9fgM);/J>`ZH2aNKE&nPPO0Q8NRjL0Y"(bk5@G.Cbn"qd[T(ln]P;Q&-#+;;Mh"`7^h&W'<ki,:ThnpL;H76@jGc7eR:5ZaWb-C+a\[2nP&,bb"kUF<frea8*t&7A^VL:YA=en8TifG2^^6)M&d!f34qX+2jmHd+?E;=o5E/e,iBQfki]2[5,ho^HCsPk+I<cIZRcc@4:Jer_7:#/dgXp<)c?%:$C)([3=J]*"0nE+[;AB5m1S=:kZIDU8k;#EF"U0=58;T.O/.%h',b7BscNk6RoOTMei/lqm9lB!'$F^F,qR&^l,gHB?Nf)rMh"86G'HF5lbWD2kH]/n9Vc]$tX1("BmbHn=p(e7C\@!C@#b/B8(fb?a+r"\/TP(pg55Zc'lPR+3"K&P=.m,:Y9N^M+!puGT<ARU-F?q8nn^@7`k,AaN#&NTh0%<r?7Jrh%>1dU"AWhIe#M8E:k5=><J\$)JIW]qBpPursY>1+4BDImPX4+BuG%\7s3ku-DfB:'#Rm"DP?(Gr[4`H(gBmcY<fgJDZpXhbr]RBBYX]H_m~>endstream
+endobj
+% 'R244': class PDFStream
+244 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2605 >>
+stream
+Gb!Sm>Ar7c'7CCQs"Ft3:^VJ8MPMX870,Jn>CW7cVid.:W;EeC=4/G.PtT9I^[KB!8PuoI;iY'-JIPt2fq$<S1M9`H=SQInT0Wm)152&ZgL(P"3X=DN/kdqVD#4(_htl*1*qrnV%%-MB4'U<R33qjcbdSR=i5*\0B=OttCuhqMd"?$@[a";"Y"q.UbbHaArKT%/2gPMR%l!rgn,AgUrk&0i\(ept"8>[D(_]B_EsB*JEpfCgM[2MDf.Z'qaH]G_QS,W&17cNX^kC$Z/mipb_sBO@hm+00gM?F%9:OSA68g0;)^FgbdCZi8?^jN.m1'B`eE`Qqku,<S8#:`X%L)k'h0&2bg"XXEeS>SU.WUq.i:>]7$8\CE.io)V9)ia7S>SA\Md"NrnKc=W)7!5HP>XjnWto8bcS!M'-YK!F3un&$`RZ(dgOAGGmYUOI^V^/%EV8VlibT:kafee7/l"-o;3]r$LX%8K&>[E?,R$M7ku\1)R2#H8ItsDJ,_Ut$Mio_]?iO1ZP)HllTh+i36(-oG6lkn@/if8V1)K_+)Xs[[.MOBNM!iCTSHfMqCW$/5e`kc+dir-Pffc,ule>m4PBZ1+Vb\8Zo@$3_o:T<r:Mt>k7-<Xd?_0JT^_m[8!$a?<Z*?7)dYP_^L<Of=f!Pc1*SA=4a'qfqW;eJ^n"mOF]!=?dKaG1]JuD);:h>rhH(e_A&c[!"H/V'1$U3U.a<SkP)423B*\8g*=br;%6=2p*F0=Fs*IM?BD?!Y8[*/WGqClf))9`"gcn_btT+5Jh!Psin8oH"COd\LaWh*oKdY!-)=LA-sg4r4J7"du@r/\&V,fjOt<-N'sL/RPEKL@e(,Q#`2)&6g'nCm(iPY!-b#&3)td\M]I$jfs^U7fUP>(]@Z+oPdW/'51XV(-`n`s0A+CXsB8hKZQ&$4bHqK=eX5R*,[B:@e$HTe!=p35[SJ&<b#D]9/]6]i:R7oV]9!JW-p+`7WhSBolQGi^c*9@328%B\[FAS1qD`M9%DA-/H3G1RQRB86#l+4'&jRre$;"<>,G:_NP0@Zg*Z>"Npr6B!I()@6hor#smkVZ9X)?2[H(h&,7p]3QDjGUkQl'?L0RL.Srd+AKpJV=P_/_keK^DU0VbC'bXo;d?g.7aRYRQ.Pt<pk2B1Wo4$P4?8^9]phX4"'75L$@:@FM3nDPD"PR8#Q@/b_S\`c@I0Ws$Do2]V8-)/8"JmTrfVBTX<)V5:$G@m3"/$BtmOl)GnY6Gfh-Op@A$1S="T+C$RJp[-@lAEf=)N5K8%4]fC?N0PZP4>4%4F'lAJdVIisHqk?cB&*>?K';(@aX;#aI`Q@&kbpJD+lT#eRSTQ6\6ph&k(0kj9p$8g7Os\<Mi/YskbkQ29=].J<+@]2hkceMnM;WI`V@eoX^!6?1`,c_u7(l<8b:-U/,a*mQ/1@:qC>F,-O<*O+03o>eR2bE*=EW_QH#B=jLTN#[KaZ/dF'&u.XnTst2[3LrqHmO8k-17ATI=!bb#gLWaM\Y-!6gY2f7\QS$i+ohsfJ4R5F#ScS5<PW`1jpCSb'"1EqaHXd5E`Hg'A8/u-N6FYbMOI72<=niYaC;+bb4PU$"55XOl]%>gX/&1:3)h3GOhj46P(#Y[hH(]B?,\]n;3e1U"EH*si4+\g1MCEb0)s9]V:L/+pOdEDWW,$nc)n7MMpA7li:YV7!pntU;jfKOLsTVI'C$JQWEOK++e0oKX4KNP.*!Dm<3>n&p0U&N\:(r/@+;Qrd6W]O>QjACc5cE+5>#=s'J`K3K%(TI:e!S!ogBVH)J^VT-l=Ki76LY03>":=f8!j8+"P9B+3@$.rf'c6q1b&$&[:R;h,?(N2>)B5fY'N+37c#GdF%0QJop`6C:a]pfO6BlKV%uj>nPGF?;W[0Bq[hVMkr\5XZ;c#O=$fu8!$ejpO7\SNf"\2..^00@oqFE5mBR>Ynbk5Sg61tA"a*RQ*N]XBl[Tpg)T1U\;Y*OCduHkBY6Z$7oIp!^8VqiV&*<8MjQ]d]\cC#\N"=^#:1/mnMoZ7k?-7D`)KZZ+lQPSJ"4J0q#F?Efpn9>#Gg\BX6BcaB7ZE![YLg.Zt-5-6rdB_>`?(&]J#%gR$E@p$*$5pk8H2LFtQ``XgtaQXP)[?Q/E-;flZpNC$hLO!=G@qa`o"02`.Q&230I/.+)%=':o.1/9OA*\[fg&gA2E3Q`fs'iX0CmG%']%4VVt*R+!.'NK/id2D&qja4/E#ZZQK$-HA1]gC,kWmGAhTGLF?_QX`e2<6:T;?K/g*=qmm.L:+9"H^u:$TnA#GIB9V1DDoe>m]()RMYJ\:AKNU#m/-4B>4u%`k,/=ZZq#T>O(5mT=&kY.ii)<hrfH3ao!:NX42BIArO%q?&gdE+L[X)@+8BsE1X?BbgrI1[@8qGo[B7gW&H0HN\_Tbb\oU`59^g3J)>6/g+QO1C;dhlWW/h,J*o/5"Cq+d0TdEF'0,DM^%;@.Gm@%Q+0<j8Amj.G3l)V@NEMgY*oRf-[2"/YbLr'6X?l?N4?@oPe3<#\DQnlJY3*PW(m@B#(jqBII_0Vd27XgP9I$`mW;4WPBM)=B;=QE2&84"?IZ>#Ll4_BkofnGT;.>-g0rW,51?K2~>endstream
+endobj
+% 'R245': class PDFStream
+245 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2902 >>
+stream
+Gau`UgN)&i&Uekgs.N(=CN!&U6%Tol09KbJf-u';?-0WVP_UD9,UWXIn-gEloC_A9_.>lg'Wa9`P3aBD\b)CUICab>_AIbhr]e[.?=1V=IL%*e_"AV_.#?gX"2)<rrp1$mL@t%="HuE]R,ORlo+93bk#no*:W(9_G0cf>WaWNe,$<-'E1K93#5B+gV]?SiN4'_tO4h=,MjJD]0=_"QGQ4(\^GI$]4u?j`:4nbMoIL8$JhU^K]U^^sP'6_t04*FeMZoS>G'R_JppfaNh1hiRr'oPB=G"\Q<+[m=V6TO[o@5_ro][8^P(:XJ:fOJp`T\H)YD'D?!U0em\9VM`GRMATS-j&."`6NP12@Ip4//oo-.@NSA?t!*r)d]=8_I#')fK&8rek[nbtAsZDC&Qeq7Qs:dW[H+iMC$:](]sR(_\C:\F_31A!i:/kn&_X_V$XtcTkW&44^qo9bj#!gF<=B+6U4g7)mr:&h!$F\ReU_rifCZ4G-=p>=l?re#L4J;Ija7-Ut->XKE!.37`opi-c(R7iBrnPLr_?H?+lKc;_mHc8brS.8h/6\WIuc#36tl[NPU4iFoIe)a)3LbJ0hJ\$GK#>bpOD7uT3oW3qLOW=Y:+XJunW+B*S>3^Zs]8UDgZW<cW`PL$hXD_9a8-p4P(Fb0E#-e!IKq!I<d$o&+5\?_sV(jH8oEJL<OIGmPFIM&,P5jra3@C7J1N*K"caFf;,a;m.Ffn`o3S&#QlLL+ZJ;WP)&_+DA&I;D=m]s5k7NRjRu#2dn4<b3`qVR,M%Ye/f_(aR$@&rjO5i6%$QpS6k^ZUnqr^R;DM[k$qJdXLA!EO`&^bN\Lao*rD3IZ86VO"1o6'6X,$ptT72+^Fe\c/@UGDT/IhFrYIm32<Yh-1Z(fjgn&EP1N\TPD;T,b.VkG0:k\J-J-^8UB*;,8%cBNkLGWc5(@eZGKQqk(7d]M%1:H.\3@2nDJGHPF.fKJes[SEQUW-T3?r?/^7dpPE71g"L_usAWC_tg4Z_ThN-U;:i%'?tX7@c]`,$2Qak'%gqe6<8KPK_0,QNckSQ<!o0]t/Q-9a#'c8%h^Q3]i+jECka%j\[3dtaCh-ZLL>dZ"hV^J#6X$>K#;?Xj;FOuK,V.ko>'b(reEO@D!iZ)m';hi[h%&l&76YYr%'`7F-eK@q]7e&p+eC^G!ud9!?5@U:@$X`DBQ1>F=B0USJ-cXAN!7J#X3^+[LBiaUl:0b9S.g)H6q282:/bQIWu11_b0paG.(_Pm=+DuO..UPhPP%^%58b?s*hJ!NG9c%7W946Jmd,C;4ON!bp6HO<hMX(MsLLS$,7<>=.H,,-3Un4'3tl5&7U.c[NCX-D]*c.g!A"h*-OP2[$h+lbKF1+hc_LCdXW#p`;_i?&K$Z^XYb764_iPSK55GL"un%OXe(S$Hi0mg6OZPUeL.)_(Bi&k8Cin?H*e-E>56.I3gVGFm^u$4D"Y7bLs^.O,lT8VGPl,JmR'P`SLG9;M*uf;/)-bd:fPQABU[bXIZF5.P$04`9.XD736FC(^ubWmeZ!m+,!rC78`B>YhfO@P/d`U*Mag^*8P,PK2,H2\M6a!1tk*^\:I[njEqTU*[QK,.aY3WpU@S<0WV9SWY@fGcf8%=!Q>)'mYjF[.C;1o(lDQ>O(ugTkF,.`$A2_l*Z(4Bh<F<E]IaHJm4c!j)+emr4^9q\4p9'p9u.Hjh<Hd7)[)k58B&+?$s("cC='G0t]Gm<0o!,d3lqe!W5qD)d1nRG"n^/UmLo0V3f:Z\7kKW1)TnL35lk?!'`()Q(,;mVG[*dE8&cEigPX--rAU;"U*Dc3G,1;+mV1n.?*Q/LS(GY/`V8L8roRR5US_f<<G1`-mWGl7H%'-CH<,cb:o3AB<%8k@<aG8JKIIU$CSesCUUdWOu\"9_3A5M$2>XIoVP*s1Y!M>*Rq!2GN$DOFS1uBK1MPsA;"O'gi^%<49dYWMotb?=?IL\*1FF7&9eFhG[O5-(T4IL*mM79\.W5`pZ1'YbT4,q@G=[\-+fSK-?;Kh%purZF%;/ebmP8Z1jMXI]F<`HS(e@Z9kRCO#J4i<QKK`9d;Gs5.aC,c7nh@"I`EG^\?F/g[3spA%joG,-'&d'V=_@mDsZgnhqHYPJrnEK.Vj;m@aQ]ZA;<3\7\J=-<Wsg\RTR_NFaXcWWE_J\DlO?kJL+\I=NWdaGN=^^o2AV![Z#&$ieK:WppCZ]"eVRO2nVsN,4lO$J%E7liRVH!1"\NoYU;5+pLr^4p2iD-VGtnNPO>,U6mI)]C7QslEl)6l3u(CYr6C:V]]2OBeLO>]/+:lTl\:(A;"eX&/q@^>\phZa3X$h5\kXVIpV3W,N'+@5\s;6Z,Kr9>D9;^n,,M@lXFqHd]Pp%P?=EW3SRQ(gSjP=E-FIJ2Pg5(S[a._1EYNK@=g&MFOV&E$;mjDjX4`h2U>.U>?/kPFN#_>0dp[!"6^^[t2.B?r)?u:*a*\!5^;+%t-!JAF%^87$*M0L5CJA=dSmp4AOAR7dAm_fA>Je#gpa.>JP^DKWVBU>W>!*]o<ts^r1Ac?T`>MU01lB`t?i0UZd^2I\C[Lq!qqg^BQh2?!;#4Mf<8Ut"HFEI`KIctQ>D2_(YW('RLklPbYP]V?LckQAC\0H6.k+.>&W^,'*;[\U5Pc/*q/kah0+J>To^QVeI`k!(:p!O@G]lX<j4`pFDjIYERmPZ+F8Jtb^";.MM'GX?:2XdP8bG]O9nV]=#iM8tV'0CnaVM?V_3)?_lsFXoFs'.ToW^<j@4;s(DQWLNL#50NoO&9j$Crgb`?ZKL;&27;^%JD@bspF`d^5R#/W;c31S3U#9!M4W2%T*cS.?`XAApe_leA>L2!<6Rl9PPPmrAK[@GOB/"05?'Zfn\dhVW*(%,_>2\&1L1Ij.qOq6U)$olUe;~>endstream
+endobj
+% 'R246': class PDFStream
+246 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2747 >>
+stream
+Gb!;egN)%.&q*PUrh7Lgj(ugWOeQa":Yn&mP8\(tM3ZfK>0d:=Jelo_^_!.QrV^mA,Xk>69OFZ/;Rr/!5bQNfFS>h"_[ukCpAZNCpr<Gbr21'S!/h!XcjO9%$1AY5?[]>3rG)*eKHTc]@sk3'm_bH"[s?H]a:H:pH2S(_op^Z4hJ=s%70^Kp@5lJ-.o*c4/NL1fMAnPJLMpSj5?Rj.0)qF>qmCnJD;Uf(FPboFa#nN=*s_a\^Yil>E=c9Enr-5ZN)3EiLG)^:&2Hl$QidFBjA!c%TNA5Q1&fsC_m?\/^g>8g&Zq_U]YHH70+s!Q7P&2qP_2T$i%.#I,/^,9bmi9B"X1-<kP3-7W;?2"1g]Rnj0mKt?re8m5J>\D^^RG(<?$biR\qXuKr2Bg?IC#JU%b\-cFd!>ei#Dfa%;_!'VI>s=IuE7E_F0#BfLMQTB3..gWnSb$]F&*O0FJ<W(^EqDm3Aa$,Q[[V'mWMnKq7/Q8XIt@l"j@&)JZVebq!BQ8jLTBGcf$N>]@ij<VUe3\2^k7&*m7b][C=M0Zt\eA.6NfNP3TY($3AjmiJ&-\Gp&o9=*#_j?YINGVqW#g!BrHl\Q?S_\T^JnQfh_Wd7.W"U<Qh"1JW"N^Cg0H*?>W$7WT1\V$(*l,'<[>T2?Kn0p?qG+*0TLWJn"[T)\/r`_Ki%U"T,i@Uo0eh($PK>E/W2_7=^E^CEJWOYibM1fD$C:4A.W,K7\F"&#X$Rq`7$6RgD';qWfkgHrn-%4,9")PZ*[>UcKcVcZdmj)?Bftk-(YAKYkLZm_pliL_&!:Tj&oK\HLC=5>DmF.MiTg4a4)]m#iU%6nLD.;G'+;kR.7P?_:eV`)f5BEH6Sj,P>*Xg'Rm1W`h!Dd_^M-38?E(eL@ZY5i-!1N.'U[aHCr7tYM8L)*n1A/cZ3XQaS4;cr$c*Llj=4-aY`\J[P0nnlRBa39JVU%#fg-+LQa[\r/*-FsgoSfP6Aq\5,_S0M8m_/Qj*2K*n,HK^N]jldCC^BaA=><S4T4Xdq2`j5*Lb8-*HkRHR3M0IP&rPQ7X_)L\VpnB@W3m:r!ee2Y^kJ#\';HXk`I?"=c\\DQF>;3MM+LS.-7R'W"5U%Q7FFJ=<fL3AI?W0aduF,=tFO#B/At\J=,a0_uWuK(,@<oB?^EsAgjkC'.%@TM%h07]<PPM%%:XpZ*B+R`Q9-pVr5.C)p<@nNnVtj%4LP"QL,#<;qrr[*[FL:s'B#$hFEc$fIrTiJsC1_V$3_Og^dF$e;R[!QjS5tP(\rcPE`l8m(a/=BcP9J,]^,;Imd;U:u#.i.LIW803<sFUd$`Fi8TaJD)j/GB\2j[G`D;=#81RIZ#e_%%4S=NMH-odeQ\%N-19>ZOSh>Cidg8j_=VJmR4PHL*]1<fc`lbF1a%'$mJH:K0>t`(V;rD4[36`&MtN*];R._1\Zn=ENG5j,Zp-_;)VE"3j[]cE42LFE>dks`>/_nr%pWl+#;/B\P6Z'b`uLB0c^3R:6S^O7+1SW8hi*c[&l#<8[V_A.$HcsA`!2?jb1M,#Ud8O[m80T9f#7u+O+usUc`+io-o2#FCMc@9WqA6hTEC'Ve(m?mIB*hD?F!eQk6,c]N\uUiW3_soPnt@n\s#9$`.R!oe[Z2'7.65R<#9Tr'k0a,FfB=^Xa?N^dGE(@l%L.V*''WoeUt6.am^,\XRc/<a2JW8HG_J+@9oEE5C9&i8&K:$5=?\\iAd8e/EYfBk,BV[5Oo)l%Nm0?5P#$<<2+`Bn<dT$rt\6[]#[I:rcV(lhTUI0&_)Ft"H.Cc-6]]#Y8%Pl/hg=^<YULL,%X$SiSe(6\I.1"Z(Lm]3?3@_amhOO^!YF1k-X#XPP96j?MdYK1<?Q/4mCbRe!k8Y)O2a-QoV?GX&GeDrDsfM?GGanK4+6mmXJ@]>[gthi0)bcnLQ>$G`D`>-?KCfB]K><%0)/#Nh'SPB>-=X2-@]o<6$TSi.slqD%H9(Cd7/bWag'pFs*.K]6]9gM=6^KT=K(U][nSQ>-:ZSR\B/InqWa9O$=^gEQcVa;2:6bj^1YX<*(I;h'LR.Jm+@?j\Vq-G?6&J*^f"sG7T"Pl23i95;UErA'rG*1:9_ib##sXlnQiC-ujG8N/Z5#Ph*Gf)-CMl[Sq`ao$3Ys.MF9"cbNpNqkHg?GoR39a@Pi[E=_?Hg;h<LfMge'L1a4-UFJc()dP)BW)m?@+dHV/gY5ei&lNB-QCliESlQ#IdHpb4K'0\Si0i$>b5O[<I_Rc0"-Y$(YD<>i:3U;U:V9t<4k14$]u0>*VS#=nY[ic]k4RuLqb:Od=@hWtUlmg7XabN`-h@T2!aeR6O7D;DgDG<Id4Mu(R"(QVpVXdni8AU9fEfCA)pa/FfEgYk2\5@Y)c%7Jh62V-bE=Fc"D(k':HXs#Sj4Jt\jOtd_kk&(_=FjRGM\;?L+`=%$>m(IT1T_.$'mKU@4jO>A`ce?133T/G;urm*XpH0jO[f%bq#+cA)A5Z],'^QM:**eo;F`m1mrT`q8(Dh1\l84FG>N+eG&"nhUimY!e'Nb*PhMhK]u=X^DXVfkJCP[&4?Zi0h?oT4sYcH[ZVi.r,D"Ns6tHd',N3*Md,8(iK9#n;,SB9Ye(`O7E1;`p/$pPJIU?p"h.??)FIj#[JR=(=4N>Lp,b`4G?`T<j6^DL-\8fIUReEaZIp8-+EVpQG:2c^DX62S\J-H5D$nRoI3"%,_0KNu:$KCA*W(JDgh%m.T2kB9]cV6dpQ%`M]RKO'-8H+L~>endstream
+endobj
+% 'R247': class PDFStream
+247 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 4322 >>
+stream
+Gb!;g?$DdJ(4Dg_k!/&a^!dP.JFVAg^H8o=1QA<]LVAieVbFq:(oNSpl`Z>%5^XSDC%1\1B2,Z)hF@fb9B&;u`28#)pA^V@OCq4,p<"P=99sAQGa:jcn&W]6YJ5Hts#ChMpPA-=F.[2NjUO:n7%#pAB9);A+2@eAUH3NdF"7ZHZHS-b=;7Y&TuOY)6^9S,>MPATa*C";J!9!/=S70Js1XDD5J#OlS\S^B+UQQ]B!rL,H5S`GjT`%O:MO;AiOhe+--j_dW3+8FMd5Vt1<JNU&s;@&[Z/Gj3_>P+*_Eo5D_M]I4aIPses8-sa3eSE(\(dO'9a]rVK!Ai8t'_5fo_1WYEi_4:Xf1F,#OelX?"&ebI9Qk?icG89tF]NA@LH6o:dMr]]]R1a]J#WNi_6r9p&]$/(%*>f5[8ZGY4^TMHmjjnE7D",`C]GP[A.7Hr!DE7=Gp=G0/m4h!UA+S0j_-$:Itr9>B;rd..:(:Menr_Q_qO[P_Dk2@1qf-+rd&-?5tY.Ykg]l_d;@(b2V7+DZcSL$i(+.;`e_LL.`!jICC;^'<FH(7cH\1%a<CmBdUbG-jKcjUWd+<g@K'"kt5-a$h/>j*\0_nmp8_OEH[u9Him9gNZ)gnpNgMj0Hc+Nc.O<8,0nel%n<\*c(S>D9[07\B?^hBQJ%]18^r_Q"1OUoX"tr3mV_C!"*n<m.B/]+gRjfK=5k7D<QggdC5L'RsS&O[,lIRl``pnNnA:0c-8GaNXH[[pQUaRX4(obPkTi+?W=_>S*X\]25f_M6]5$miFPdX430.-?=_:hTqUM\7`C7-.a>Bh@+sqIrCtCLN`LAGN`O<nl?5>^%#kVQSlQL2e4:hIE7V\13jH7#W/Xgu_iL_&.A.Eimh;XhSIA)hV`-[u;q,D.i\\B--r_q8k34?JG5=[2d!:3=KUY=#,4#*3=!!nOfS\ocl_VtR@%h\[E+$@iOKD\@rIG^4mJH.<[U"o`NYF;AM!*)8(0%LafEjkYGC::HB<qTW4kK,^;R;$tBGYUL=T\ct;;:GcPf7qYE9>H>P'XZinPJH2jnetMnp1lej>EDY%[U67-)p#6laa*7cWt5I1qLWN#F="nr*C[`I.f\#ZQ?f)WLNA;<F035WL%`b,3Yl>^m2aR)foCe3^8*hhE=)M\%FO:(C*KjR#Qn(AG"Pg/BiLr1.^Wl&)6ha1VLtpMgU_\?'Y%STjCDfDXn6@2!MSF00,ifloNhhl]-AK/CPoY=J6N8j>n_]6'p=Hfl(Yj?;3D19tjnOGAuBqW$6P-!/j'?89Y@$O-j5\KQ%ggL#:bbf4^]#K"7!O$nq;;h4i1`p?_J6-2DRjc#1!tT!Zf>ipu3s;\-*KlTMA.Xiu^;4L*!)>[2s6&DUS,d169\Q-,ibk0"F%8RrSh*d:'p38ZYJ:MG-!%S`&aqjVJTeQd-N%*dpt6Y)uQQW0MHo,;k$n2O(nG_`l<$br4MS$-cUZ6BhDiP;^YWdcDBa/jJtFKU):]7lr$ro2u&qe'NSG(?qVgI_%lnRNorG^"%GTD,\PdY#?>U:QZ6QIPVK8k8'ZM><TcJ6$NhLdkmlp.[06*]c.W1)q4]B4X&t9qRO#^i1+H:L8^^Eca[^X4]pa!Qpu9"]f$_"6:E73^)66i1[:aIDUIEN#sE$*^J15re&7P)jjnk4=%IqbF-cA3CHVS_rhRK)3,g-5n>LfnKql3`\9NG\b:O2<fZ#\_L5c?>p2C]p6"5!d+ahtW(<ZK[!@a+LY=299BtG25Va6`#BDN5-^u!6/mEgkHVe$e?bA68=q`8o334IP`b\1+oDaa30so-GnpVP,hsd5eBjT<%G]uS?`Pi=Y^Gr@9$Ecf]?bBkGMu5VuL)qqTaAqi3[K_V"F'IcGGgcoD-(C1hj)V\XGP6%Pq'l-D4E$fg5k*hY:@jb5Hgb_I3ha[?eq;`/\+Mj.2_?!?a\$jho1ufD9!"!N"-6s;dp:gK(JkiX=f.@b.0',6KJaU>Go=FO\VI2N"#S-fc"7j6f3\n,15nEPhNCZ[ELgc,;m5>PWREVlCSoCsE3;3][Lkmr!!WMZhqf7iHPT<Q*9QhfKpehdccFJ`PNQH>CY.cNk7R1L_G`X2#H.'[!VQ[cc!j/SR2So7H_<<C23K:(V<@/jl[n*GkO]eafD2>20RA19GIk>iqA51Rd(=s$*8(G_1>c]k/b[2s]ue'0Qoi<3)5%,bAq1M%T)hQ7N<XetJ(h0`8UL+(bEoEWAt=bl14./i,h[tkBB!a1UL!fP[`E@pfQVS<\NN@)%ML4f\QEfT05PE!kC[K8qU]Xm)-QhZ8XZ][#>*%]jN#bBQ*lZ%-1:6t@d8ljpL_nJj9_7!gW,IPjlsn91%Y"AUr0kcKN#W?G]mN(UMK^bb\$,(o.dTCdBl^2kG-.sg@+s,UMJdWjAW@AoliLp+atMbiG]`fiG]TbiG]IY_g<&I2t;nZpr(9j8*<_X2R/\A.$>0hRZCpFM2f^aI*YL;8K)A.'<^2IKp1uA"_W0on&2)!b4)gkoEcDLCd+:''(:5(LV5Hhd&&;;h7=+7&#ZjI_]S&L-NbfEjGJA2eN=m)o!S*f:i"SU<o>%BrEhF"%[*".a>p+uWlE=M;X1G!G`FEP*A[G[<ZJoI3U-P?nMMT2'&(])]E#Y^bD:(`eT"3a3+UKI]3P[nH^r@>\d4/[q$r#]iX;]_$9K(dmSt%rlDi^;oI>IuklO1N%8AJdGJU>CM]%QV4[n!ikY])1rnZLo-L:kF9SSLA"@nbW(%DeGp#7\YK+O:jadT4^r\:0S5fR@HU(S_S;q8iON786V\-t]'Jg>-O/:dplCsf0cHneSql#n2h<)_"C'eg2u6J.^2@te,4:$D7d<$C:jL8D0_&s"at#Z3H9PuWor9uEX(?Mf^c"b>lj[9c7oeek9JLap#E0nEM<Qqei?G_ZVTSCNXaCL]WiaX.orfNHWI%Hl60d-Fnn,NB]YdBO,n&%ETG<.^oU)^M(i)H>7*^VOriCMgVpB8B;6e.70`/#u"?gZCAHW$It7BsEbY.POOD&QR)6`U&TU0qC_^C2$n"$^6_@,f%J&*:BR;b("*4\Z?7PJJhad\5o?h2817m'*q^6QFM5]Ta8pH!`l6GY24i7#gNPS<i@=IhW1gFY-;&%4m]Lpe7Kf0A>G\L0KCm*Z%:h(bBL?Dm)B,[LCf^nknsp<$#GW13l06#(D[\:*5clMV.V2--EoLbklaZ*6s*.,.ZLV"Q,.L1I3=]8<cX/Z/V^#Wjk`>cR[P=E>r2$A0tq%oCbcocn[o%&&/:Be7RJo%\%i]0U9_[M.)tioQpOVK()RK<g>.`tTYH9)D=MI27TqeQX[`/l>#=lZi<WR$H<m`(&>G>4.ViE8fk/.4[(MIa,biF.=A6/IE@rj-@lfIFZ4%M4D2"KQbP7H",-(!^`Pek+dLCL+6#F&W4X8c6):MrO7Vj2Sdmpeqm)EO?It=X'8^Be,8B1?>$CtShR0\_mf`"42'.c9[@5/YS?RU#JV.Uu'->&N42rKspo%%kdWLV?=19QaQ$3PDl"*^jn+@IOG<:7Rh19/,DSO?Gf#E-^&!lK*m;<8iM-DLnVdn)rmHa&m);d-cH=&bhKX.@pq(g2C,(2T]B8&*L/3sWCOLX`Mj;?_`PC6i`a[`duOPqsaSqO4VldA)8]pnnFNWj!G'E>aG."A.1#b4oTZ\fhr\@@0foA<EgOIl3o=PHc![klaWpM>I!;(qMF>Rph[ZY[l.k9sC"P<>s\D=,+k7[S+2PIo?b,!V@VY#X;A"8(*&sf2_qjf/,%DD30"X'G.!RBI_1J!J)[B7+KX`G!Q02;a?/=TrG,F"@R&LX+l!VMV3AaF%/4d!O4tGi^j\Ce8S-W$GF0G.L8o%/03JQ+b<m,R'*=N=9j`jj9ieH2,2+T=A0i=(oF?J3YoSA@TJV5"'uj2jD+h-*-_N&f/,%TL"_k1?#p;X;)L2<J$>$M'c<f`G\[7d0nCi/9\8d`rkW%F=(%DuiMld.`Pe8jlZul'+[6O@C]V<cd#e'6N#sRR@`9CbDCBjr)bM'6n2`^]$E[4?94Nc"8q8jB<bs_mO<X$ZiYu_g7E(A`U(Xo2?8!/Q@tSMGMBic+Yc[_IdJ3\Z<)ZX>JZ+?@n^i]=pXZ"+MBW?r]72rs\-6VAcN=9G2W&i(2i>_^X5[FoWLP!'SnRnmf<IqJ5/scT\/@a\Z)=k0KdpgIDM6D6lj9b/To,:kRp\&eHg9m"W1rG4"rIe,g>.p$TYEu.0c.uD^p-D?**$18R8:H7YfGE:<qlPp(uX'QTB#3c+,^4`)rYjCh</9fJ7g*SNiW&(/C%AD$GP$!HuC_7op>[Z02eX2~>endstream
+endobj
+% 'R248': class PDFStream
+248 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2420 >>
+stream
+Gb"/(gMYb*&:H4YIi&;j+Ph0>e+[sVH:856*d@?)0=4,Oge+;5;Kf`\^GDZ2bHV^2D7W8q,">s51-%I<B'.=)5o9Qgq]D[8:T!XN"U!>.koA=u(r5c$4J1KFpVjgJq=nn/]j<B6ichi61H8gn[:%eWZec6op[@(@XPRV19L_C:VSH;a[rHiME?#C$bHC`k$TMb3#;H)]VSBb15If=3lHP*Ber74(>-+8Tqql9/g$].D2HIOl<e-1?`IIZ;cOp8+VNq9-,n+>,66_BmPD`8_AI()+2950!nYM=NUa!,Lk"8"@n?JgKKS!#h+uB<o@sX.SQ+88Y/.LO\D'q-\2%Qet70g[rCKq,hZ,Fs'DT=K`d>I7E/XZlu0jMn4%Aq3fV/9d@\SfQ2&79EcI)7@WWm]C1o43+b]!O(38]6de"ig*a_JR]s=.-=F8"GQ=aYZfK\[dtT1N<'Yh5AlNC3+(!=>"&kC=B2HncTL2pHX#0%MX2"Ag101=@QaPZ]/N2n:%_%$;PFOC,G>^ltT"pTK=-P-BfJ@Y\l-Y*IIL=K#tNu:TrbUP<bn9(Vo&TOpXC1;!CM_MtTX67mXn4'OJe%FrE'cK'Rp,+p3k/4ASR7d1HQiK5_LTcL-H@qUJZ.OUG@7-qHcPH/MH^%p;)!DfQ8IhnL@*,(G[V\jF8NkJ/ef,9a21"IG7,e+K/E\:;%i\]ROu(^(@Z:ieDF#agI90;[+Z;1$sK0Gn*?NVs`uET0oK\]4?k)oq,X4EcIA<VnrC^"+s@^/`TX]LG?R*11M1.06^AJ=PXi`$D[[$IBY;%r!Go7G!>99Z@<NH#)qq>Zd78WBs^+bd!kaXB*Hf@5FFD*m-"B()s8DAc.f)Lp+)%,Y]^RX03.e'3I3U#o4/26tqQM^f"iE@$.3F,-l.s+f90OkX&cjPbInoPGFCQh1>1SLcMf&q[bpTi"m,3f'U>tIjmep]'aE^`5b63KC:#D^+dVZ0<hg@bXa7Nd]OMt1]m+[R*]+2k&B$CbeU.Y;dZ\.63C8#Ohge_g&'Ca&*T$Cs5C<.is9ELP/tGZ2eS?hLNJg2"rj+pB737_7c><sfsQE];giNpn#N+">OL?4IFB=D6a<dM#tbW/8Ko=?5F2jHJ;N"5!Yl=t5YW@K.,W)tIHMA?2a*d/fS$CMTDq0]:%q'?4'KYiah!M/1=Re7<@4m-L]6B&-5pGmlX?)M<JHnYZ`HT08EFSRHmGPPX;S8"/kHWXis&HN,j33d6ZM;O@+%98!tKJpQ\i!K$V!3/mHngW*pq+L<@eg2<:@QK:k_W63qb]Do`hA)/6srKjM=!"iW%P'2o)l%j48LUdN%T49I?!SSrq0]c6`*>LO!;9m;kEr`&8o;GXbn?<V+j57k)*t:If=eSP>0Dd@lT?FNQ[L-BjE=Vk&n^=HOPW_$h>fT"Tm@GU8Q,#ZA&^]AR(4E7*SDSq!SOj<SAkIF>-sFJ^tQ-!4Gh>>W!\.sEP\[FZ[/<OT\BJY`lu04-\0+;Mc]47;eKGAQ_uCBVTpgbGe+Ro.4o3'=aZI'^Tmp+=mu8B)JA6M&9f6JfD+7dKgd%/[m@d3SCc-L!Cn'fAC+"1t>/%K%r%!H2f6NMU<UBuM<-6.MQIj)C>&b+L%._V18?a/ntk=\^poMM8&L_Ur&<W:D&Map(At6G(9"NkoTR>77l4\o0hO<flU`r>.6\2Us;]n:kR(f+Ms0e[0VN.RQr1RMp2[;r@#h.Kr6q1,4_6Am-*[,UZWi!lTI=69Kl6.peiIQ^"Ytqs3(=pF*W%[)gC<!mEN'[<sTgn-C<q($,8@T$7*H`<b)o[-)^a1AnE;Xqs:)+YRr?9!k(b[dQug(m7+9r]1Bd&s;Kbg%K;HU/7jV#\c11h\&B4+]Lsi-Y4/$FPA[l<?Q.5$@X&$2HHVkr\:/gAOM`s8p$hNO]kV+/]k2c3>rg_hN>M#"#J1`ilDiA\NAhB9W+760XJ<p(+B[!ZlH=0<TiOd0*XtP(t;]V4b(i8X51V<&tU!+V*YpZ#(8"]6/SD!o6k9IFn-^+b[t-:\_s*bai`YOnWSUZZ1POZAQThX0Y,?]0[]Ebe'Q+b0X9m#OtY`B720J'g>8Y&Es/Sf]Oej"j71hCmPau'QeGF!#/=:bQS+KuoXP:_`mRN%JVO0bIra0gb$cg3Br=Z=rBmo7Dg4f%g_gaSnU63#[F`lqUu.kn!`gI6Q+7I6hS7fbl&b&Xf.Qokf:Hn7k5Ya1"'fFIih\+;hr<#=Hi5%c#sT;_:0dgp=?#'ucjq;M@!;FVNa.dV[j]\ZbK1eE>UQN,VD6L?!D-D?S1)AE=e`8m##bK[VFg.ul*<C-`uZ8`nb>:-fOTB#N-Ca&\Q$HX/q`,,i\DQ[4aOWWY[":02\J&c`9qLmfj>0d:F8")bO3(3W;YN1f7`tOK_[!_0Z3j9rrJ0S1L0~>endstream
+endobj
+% 'R249': class PDFStream
+249 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3929 >>
+stream
+Gb!;f8U&t"&\e-*rs.>Race^/Xi[0(-An/.:2ERe*24FGDFi"aQSusO7eu_V!k<d*"[L,QG\fU*LT$2dmjh@gZH3/sg\gM_6HIJ3jMs2;YoRk+:MeAJaNXt\kF:),^@FL3-16,uENHq\S^);G>hJ^*.p0<ij-/ZXYJ@0o3!ua+l'%TifX:t,?lqN9QB*X7r-/-*c><4[Eq:flq'1+`RK*(ds5W]Z1kE?I\@7<F^n&+,QE+=[[UV<j2\89WXCW5J@6)8L/[X5g/?m21HX_!'@l_*AZC(P=96R\$m\2Zj?REYX`k2^HiCbh\A,1e6D-J6Y&9G3j,YE5793>@a^faj&O2"rWOCGuZAU-ki/L-VH-I8F2_)iECQY0+AL2BJGG3#g0rb@S]*Eu&.d@/)FbB^dCZ**X11U>ur.sH3=:=>OUnf3qLTCfJQqNg;>B<RLHG@A#`GZ&igR'%c+UC1_DFqF/i0J7&eK^g^6?b]3im5pV.SBtI8\>opU((8=W6*PVMPA?.@(&QY'/+'Cdhq*%dme.1Pk<.H\0QMO6QtFYnT`q-Z]A"EPm*b3jOalmk_BGBD_MW0%_\SdFU7*suins\6q0qS$#XCX)LMl,`_WV5E^JEIu!!KmTepB56!jS53NM;=4E2`#06WoSKjSI]iJ,+$e^]W%">X#P$]R'[cpN.LDkN$O,3KUQcVhC4]_=@uFL<L>OV?pIFBc7]m.5Olio9<eM!HHhQYdEreY?&e\0Jf:fcWWA\hgr0#=KCquJA.cJ;tO1gnRIkSAX8NqQ?1tU^trmjid3pK`\@I17KFK&#MGGtY#3!oJF!j:c^U<j+a][?)jW>AW7aKI=]4jdncEb']O`N3)**12,RrF9og*_XlXLVhk=+YgHSQa;i*3Vr=kZ766tGgmbOseu*Ir[ub0%/Y/*Y/!=*aue4NRg6!h=LG01Na$SE#,AV<`@:`>1C.\0^l0:"XNQ5JkF:)j8Q<cin/Hd3tko+;&R7[u6q!&=/ta!ZmBWh>XDZF_#ga^K%0J>3$^K2pW0JK]@A@%mY)%K/_BI%@5@l?E`Ko<59!0/B,%,G+gMpRtD_oGsU"A'W`^2!/363`ZjYU-PLM2'[ArD2g_*lpX-lB(E3aI9=0W]+G,hTdLpq+2ie,N^Hld?[LF>%9+"[<>9t$l'haJ=_<%Th=>TNL.!W"^lp8SB"McN&N&M1kNf(.#!S#-CW`s@Tfs(N=:Bp[CA7)^K<Vb$4Woo)eo[%THrI'/+NCggAJte>[ZD2[_XnOQpgPk&PB.7Z&8-uKAn1]VC_=J-(3$b&Y[bO@JjoUOT8/lg!1OKHGNW<B1g9[M[';!Q#Spfrh8d>m@k#g]Q/:oO?Ej\LTAIuR9+L'ea!JEZ1@Yfq?*&O(2Jn7$N:1Fd;nMf-3OMNb(aUXsKXe%6#ps>X+4=?M.r9uE<%?I@B\Y;*(Y@Ca8q\=t)/O1JUq@A9fBRTaG!(HBZ5<60Mi6->6*=gq%mi_dWCeLBEXB9T`g-WA:aJ[][[_p6\M@=5D'\3<saH&eoCa$.]q-)Fcb@DcQ'39"W9pMNEnOY1c6UcHunK,dFbi^OU0M,5Qih42j8`(s*g<"BQ5]J+Cqo]d"WRmPLpOmUq8YV_U/<.<&SKtK=2;d$##Q.r4YV&NCZGT<^BIYDW"]I]YZ">H0UTDTB]PN/#qmqi/T!j6[UG$j[?m82YZe[N4?]`Su&NK"L#bP_n"[6gMKCd4uYB\\IoVp];1(qV2qt5:Af5ZkoTKIY40'pplShD\!Rag/4C"ZhiKMN]Ir8Ng@f@UNfaDT;ALg3**%r/(XKW9i6V>0d`7/;l8`mY/n?G@1#9.oP0i_@tUh4>(8r,B*rq3K8jZQm[ng:(_HAI]a,OGTETeR_L*a;0bn"`FJPF_U4UlP!PgdKfK.VXSfd2p"X+9o`fQi)liY)e\899@\aj_Y9@)f]Uujcr*S(91p=X";&.#ODU,\W7]'gJ*_0fV(+G^W1>'8Q?IJLFrfID/bOj5o5P(LKVk;p\Hcc\W#d:YT^mB,*an3GbRhg1W'<,Y5+6\_3DGDIiRgFtI+cCOQA^c2*T^+QTj:A]RE5_n5^QhKBKM3pm<E98cM)&-<4n<*#1XfC;)eXJLk.B^`F8HTP@4"m_8ni_[+G#`*+&pYWRU0"Kl!qjld"^!FT.B"\8M9"\P9gq3j@B8+%VFfb4Gm!>\WruP#'%O6B\G.6NCF9DZg:T&un/5X?sS.W#E6.!Zq#qD`j[<s5N03hqMmOIQX]Z+I'?=*Thr,/l^Nnos/SNc5@UV2_R7ipKF:GQmK1j7N7`pDU1L8^Tk;_pJhE2#PMsG^15R.[PSKA&KOi\Z<$`n42fNY.aU</,Po1\it!\h.(9YB^X/3p5_;<.>gRm,f3QW1e*H3^N4dEArD#"6:Gc7]-b9ZZ$>R4qFa.L03=d\IXhZ`Lqj>l^rl<bd'C*mVPiF?SfKMr)Y+lk6`UA(-AM)"-R+)PH,4-qT>phIhNJKVg=<Fh]!tHpcb;6.=8"Fb!,b-/1;\I@gPd`=ki@I:*0L[)jI3TBM'&)5^0JR(r/9.)_csKu%aU?!*@iEW*Q738U$-I<0,9"i?'G-AT0JoN_/>4(M_cbtSUS6ig2UY))<JDch,q/0;Y9MpV6$]0W=ZB3SXMkcai@LZC6,HdaqT(SB4u(uh47rL0gNKBI,WpKCg0h*$Gl!4__cHF%&\428h"(r0_:-GI"S#5/e@XpQCVVsNl2Qjc2f:hh3Ht%M9IY2VJ3r-L@bf'-&fml!iD(HF&UZZc9SRX&`kJ>qmdq*Zo'Q&]R3$?(jN%[ZEP>k.H2>$7d/63$'3`Abe&Q"S='dGZ"odfc#ho=QTUR;[;teHLQ0FDi:K0M"npJ?EQ?cpqBAu$nl*/PYImNP<K!Qd&$HV1UnHWVZWb;6T)=VS)\Xa:]iDop?59?#/Y=Ts84[c9g\?o@U*_k:)^8MOQOB/9%42O.qTn1t&j)n6Um/(V[nY`-K'?_dV/M"1idZT=<\`5b`k#"EJ=6XqI,nm\9f3Oiu7g3U4V;DlO9[s&)B45Bo'r5u;IRdWu0oC(<I21HHoS;t>'PK[g-DV_JW^m1`$QXLeIOIMg3t\F`_nLUX99_&*8Wlp)kU>ZD7DfY98Ko'R3Z@kEd;XbRP)+jXNeT`W1`W3X,be_DUS1I4%7_><3Nt9_)l5gk0f:-QG<ls85\Zo:YK8@b#[o(^Q%%B[Y@a'J"Y*(VC)\/sI7e5K5rD5%_b*EdT2HSf:e_SMYgUqGVj)o\<0K^,XE6;k.AbuoK/Em7L3]O.BYM8/V#N'G+pfYLFQ><iV$J727%hs=qu5-I;S#+>8O@9hUS(C3%6pd<M.g#UB]rAe_\&n?+rXKC)Z#]HE.hthLk_1TL-DFj*,2Y>^re?LPQIH&.<E"L_O`uo<QSopB[g$aGoG9@ANspq9Gg0;cWB=16MaZK[#,3^YL9MJoH?G5()8r=V--CS6[R64.X8["Z]`aln>+`/PW"tc3$!Ap^8!#C%M*.9k@=(bbQMO5c%iFo&aAf#p+ShRm%@=k0WNM-9g`sV(s:AZj#X<l1^qF,Tj58dY1$!;6Z:`ub1/$&3j$mggr?IUUJ'/U^t6Mf,OT1S6:4&:]t#$3BnV^!*-2cO?:HfhY)b"ONa"kJVnId(d;#J!^c5m<Kq7qoED3PJdfJQp9b_d)Hc@eR7SF&W;`7M*C$ueWoGTG)OA=K!6DL@.a5cB8pn!S/DLg`0;65`BZr.74Nk#I#0;BHEJWFf8Na!0@g1"b_WteQ#FNUDh_A6ocHEE\UU/NthQ*j_`dVIso&=p*UY,K=nP[5l<L?OlH.5]1n"*g><WkVh2&%g`%HIBKF=2P:a1`ZqH_m5tHG7'BU7SmtW+YVDh!'"^",o9Ju69kctUS^k.0r6#rFFZ8a$7-Ke)F?[o>be/c;,h=%3"fS0am3%."g[)\]D~>endstream
+endobj
+% 'R250': class PDFStream
+250 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2421 >>
+stream
+Gb!SnCN%rc'`D>\s+/7X\jO\F00cmR5e"2>co"7-%n3bi""hnY(VN.-EP5_oHV$hqj2@6h(Mea.JPAuUH1'Y%k>H:j%t5Ms2bXMQGs\+;G)51Aac&2CouZ9=nnN4=j@9/1[X6pGf;4*"mb)8t8Csipkb.*!DEsM#:LI/"IaETTqZ3*1`,R21L@Oej!ug)BHhp7X8]U@nOicKknst7-Hi8:iI<^6c2?V!pD.h>mB_m/Pp$>7B>\?S00-G].#=DTs6JR$^%e4&Z'U/'X`Af+-3%\2&P2D.Y'9V?1:O$'I6=d&>@4!:%H'UoDSWb6B=is;o,K56J<Nn;h14i9c9[$.DmpX]3QBSe-N$i/Yl\dmBgEk0%=m4TDN#Ao&g/TO]:Pf_aE9L5og0o7J@h1`dX^LuXIJ*DOY?F3sjrcGl;0Yh:o;43IqFblrp5XID*V-+G1'ljm5B)mQ1?@_P\:/kNi:7ZjA#9sr&aR\,pP7$KJNbPsj"0/BZM^0P/A,S9Y/l1qp'FC2N2o8GA?6nN7ae@\+p*/1CkXhqKINY<*2A(IAOPWB'Jg=6kbU\P,*JdD:<CN[KLV8AMVV5L/k@cN(HNtN/<7%_FJr[Sd85O-,)&$bs4-l2!VAmo!IOmI#!sP&XG5uU$_8e\0[TF.8aVLqM8^9K.(q24(+s[M$ePuUHI)j^d';(TM]nb?:^,mVA2-K-98m)nB<7%"]-GW8*f2X4-Wcl)1g?j0j#i0=EK4O<GfDDoe:EI^YcO`iYF`-4Mq?#2[Z*p3U*gAm<\.E([AIo/F4:<-/465ZJ[";p]LIH)i;:DX;^%&Zlm4pL+T<?H#.,*MP##.5k_t3a-;bk3OF%Ja%+kCV!4rg6`A,H"GmdkC>7Z7l2qhaB^0+ujWQ4,4$8ROe;A9Kj*uiXV5p/$C!F@"n56IR`:'?GYFQ!9SQC*Fd7QDacXl8-J((<^2Z=<5[>!iX`.Cm[Nm^P"u087PY[NZYs5daoli!8Z:@uHT>or-Iln93N04B41u-`hhLgqnld6D;'oC5dFo9a$"KcbjZn+b:2%,d<]UGc(Um@.)O_=_@4Ce'!t7P'W9YLM71*i%@=+[-U1&#)"0RN%Y;2btTBO:/*]@9F:l1&C\nW3M(D]dfOoLZ!D$6lsaQL!(KYng*f_>n<t.0lbmC;CKQXN7n#2_[O*>ffe'9[dea2u':<lMfL.r4[m\c+C\)*7&s(abO8s$G@lSUq2n[?ADJ5fl,t@Y#lDe>F*>iTF=5Z.#*,$YC2jLU,[\,,Y/<7\gmGM8h%!D6%0]:B\":Ann@Ls<;Y.8$"[WJIcj\kgX`):W3!8kX7l%Hrp(^MHM2q:8WDK."3$Lf4bJ3c-sl\"+=4O.sf7N_fCXom1u+77;"-VuLXetVi'(K,qRe]JuDHd(.F25T3Z1:JkbrP5=+ceVT!Sfia?1/M&=&C4PrQX&JZ8&A8*9ah;@G=?82ikao`/4</`H;3m4f7!V0Fl*5D#hi@-a)]'f`<AiO14!cZjftfAg/#%6CsS4WB!`B!1-T-I]'q)jK`LLS<<&?Kpo:>e+0PEhe1D]q:N`d-RF\"="4%<^`3_(1-*RIAf%.t8EtX\)=Qd(qVXA$!V(IMI,"n'*N>4XrCoe.)llpQ.66X%Hp=9MK;;/FdhFWQ`8a\"a>0#J=!/Yk(hk@a!mgk3.#mY45dD,mr:Jh`U;/OrEW<tQM%:;gcYTrOJ(O3=ER[U/'U@r44T'Pa4iSun_Yf@8_>Xj*nU.DfOd_%+:C^S7m3_@&OOOCNK]]tm/b4)&/\#BA>R55.`f4J%,fU/BZa0!$4e>m[$,-FJG9*BrsVQs>V?(GcS)"\HN&\nCdYRf+O<eJlo3FC2uC`n#[,HUrgUo\,r,\#%uTj9lL7k2UJE#Jd(q&J*u0K3)U//K:3()2N3m(L+Bm#ctd0.dYn"*-oJ4rO0>nU0l+-@V`Zf`bu7s5a_2Xc/;^(sS3i3q)B%<SS#f#ApoQXcZ>Ilh5_k]?N8^JP-6#*B*Wt=iGHM*C*X_4G_q/<P5;!)hfRH<e5bI$P0f\]%.?NfR!./e^7;2E:s1M=!&c]0!I0Sgb(_I&CkG*A,Du^f],S"A5#+,5#c&pmp<;(0jh[9C:/rU=+6e:V&mSn\rTmAZ:#D2B@8h+BcS=Zjjd3sbsncYln*p%iUp1)l_p;Z85g4c*fgh>W7)jff*B8h[IW*:0Y=#ZY^<>/mo?DUS42I,lp__mc/@P6=_YIXUQ/EH@tM.;bo?*BlR.i1.*QNkr_A>cf=##'BQ%&DF_^JSeu*TOjK3_A@k3.EQ*Nf2Ya=W4kr1?A;BF%G(YW*Q/X!qn"R<oj'c"$eWbn4m:bo"nYW\"6_+RD.Xp"6d%?QKm^%&J-8fq5(WNQ'MG[#UR;][uF!hiIR`o2,:]X_^QO!GX!bkfTMY/6Zu4o#o+l077~>endstream
+endobj
+% 'R251': class PDFStream
+251 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2286 >>
+stream
+Gb!SmgN)%,&:MkuraF^LFC\K!,ua6$*BBHXS=>aT3cuMe&sCV'!!@aLr:f"N8Vr<FS+\gUh6Fs48R*$DGL'S45Tg"-s$+U+:8W""/:\jrko>9U)o2)'S5(.jqVj_*4a]5>0P'\bkNpt7?pA>mZ+(kZi=OS$+5s69Att`Q%Yla_+UAoK`q=&dQjmcQ^AftsfF*F0@/;fUJ+_R2pRa+`O8%O('*f-8.a@\j$]\=#FHC;i<\b7&c9>"#?pp]J"1Ju+BOaHi@)]HM^g%h.2t`qqZ&k4F=?4_tiYQf:Wue@/6A^s]n>-hD5D>B`IMu:ed5#9i<Xsm@,:n2AeQa_!j6*`A3Xo&8c*W`MCGqKeaS5pC#krL(pjDQ.8IqWtNVaPPIeV9rCS9P'q/@%Qk^'oIX?R[EN^fB*mBcR9XoLXrUUWcQCuB2@4CUY^;dC_CRi!:_86(nW]9pKuhr)PCB4V2go-+in"0MO(]7eRfdIu0_GdUX*BoY`qNC_rTY]h/,Ynr@p])(44@6:(:)uc#(cq;,kFk$BViSZ'Mr--J9r'tmO+hdau]\j)G+7GjqTpJC;0CFKd^OMGgI>>&p&X[>'&'l=^;@j=u=A5.j@N7ZuEX7`QE!P,Z),.1<[O\J/9;`Mal8a)<&"Z57PeA$HZ(A5RA.S\3[jnXrZOaq<dNFJB+<59j<J(.&;Tpq-EiBfhWS9b?PcgPMU:H3!91H[5+VHf%abGCORKoru0qbin$qKi?jbCm8[i\t<_3TdVjLi^B$RG1?'E\:`LKDdjj>2P%6;,h#5o%HJau4;5!Z(>^EtV&f1]1!%?@FkmImO].AFOSZdTti\m$u&m)aS7qb<Jt_-?e&^*!7#B"d4hMU)lA+;X!RsQB;d1&!u!2=<l#L[<9PNgnaRMrtrg44+fFV_YdbK7P9!l;(mmIXB`PtOm)q8O:kZIm!Oju,Wg*V3C=%<$7809aF`sXPO<s\L?sJsh\CqZ/igBVD+GV[fER;G![)j51;-.-o+kE^,/RCdRjr[XE<uh#>LscWo[tPu*S<1lqcrBebe$B65o`'ZSEhS%>2`8LbJ\(T1fdmBb^&3H^1dgZYVNlq/q`p755R_<Y^8s@0NjYjai]iGFf!XfL<+aa^5Pl!Au28ICirb8g8->=(/-hV;T;AeBR."fqTObSZ:#YXTo_n,,&"3m[(4;?DF^=-o^ESmgZt.C2Yg5+,p:r*,F4^%`=b_CQH4TgVX,u\f;hLQ#3PJ,dRD&,]1Pf-JsiR:"%UUqcF;V]MK7Q:]a['TqRH/?3XTf*lL$+%MAa(c/%MU_q(+/0kCc\h@#*>=Q`F-DTmnm)fO5S+R%eb1kT#$<9W4+84`Guj1$6X$#>5H[@"!ms;GQeaM$$K9<SO8bh!e8qEX#TXG*NHur3N:m,g4aS.kWV5TN9n.[m<bHJ;/eE$(T5=68E#$:7P2J6)Wm7OYq<=%djIPkr4OPk!!Pe<4B;6Oj[LI6Cr0Veka![@]J8C)nAR6r*o?SXV$m@/;//B+h<!6J068&og$$?[Frb!Aa0,'rn3`If\-]Y\IG781fE8U-Fau)OY8BM!\Z[nq(>p)da"i@WirjR,9qI-(0VD?5Ii_,78oroSfoqEd4=HK_H%[XE._Pm1L2mcRSO:ER>f^bH5,V5I*cq;Z.+Y%-d-DT<"):E%;!LA&]]^D-Y\7Cj=tiuh?^UAjtdoXG@@8amZ$ZFX:b,.FSFLkZLB3\\"h*W3Ts?nQMVLo:rt/W=`)I.@+%F\XO;GiaQU4Sf)?\#Jm6AF`-,M&fd6f7AIW(_s(Wn:JJAL%h#b7p9oQpQ=&(hY3NYi<8nWGnKrkEK7;;,d!\^?<7f$$B5!G2hP+@W*TD%3^jPB@7*Idk^rqL=@7f<nYoV*Odm[EPSm\K)/]i95:p[39[!h'38I1bF"R?SRJOR&-DdTohp?HQfh'.#!c=07=:gAI=,GU+S5k9p(!p>Gc-beFI/3^,X&QNFP0mcGH6X(8G8^>J/1bO/12nL`T5h:qfEb'l8e=0<!$6*@kcqDnZECtDj[I!14R2Dk3r3]&(p4If;+MFL\JT2LDu?:Kar[P'3^#VcW%ptY>K8^6#hF%N\2/j3C1c`l?A"nmT<VNg88kk0bJ;k=B7]?:uFp_MqG[(LQBN?b'7Z]A[mn+c`(pq3C?O^9c8He7U4^/\87^JnjTht1=!V6eT+&nQWRc%_<iH<=P]P''R<7tZTRi,6:3>%3#Wg_>"to_r***UILJa]VjBG7n@f<GId^6#%\<d?(.5<u.4\GEDH7^0RpeD7p.7+8l;QW!(*~>endstream
+endobj
+% 'R252': class PDFStream
+252 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2729 >>
+stream
+Gb!;eD/\/g')l41s+/fUk8nHB-,7O8qijaBG&bdMY2)/j2N*0Qka5RGF@ds]pXe:2.EPKK(HG2+35c(B]aTZPcTLe-j,lP'GkQ?K&G!"bq=2lXSknKAiXP.6bWh2uo@L1[fT2@`4rP'kVniYqWEo6hcRZ0GTKhrD&UAd&$ESR8633X97qA2&c_GFum,Ns(*T<00qkNRN`uDc:o0:=omrnN!mH7.4jl`Pu"TInH41fp>/3QF'b4YMckhLGL?sQ.7G&PgrXQ;pTc@.&ip;"dJI-"4D.DngmWQ<hPRnIeRiEm$i,9Du'YK_sG,s96.kjAnmUnUAVpjkETK/='i;h?jukh(7H-lr9?#ijKqj)GcI(hXF.N%AJ9=-WWi,\G$;3D6kk`GJo9n(O9).u@E7-<D:%F)l[b-OW[Y@E@J$`*b0N:SaeBBG#=N/CIbA*s@'UB5tRliFc7Y)jZ4i:-'o&_&,t)iqGbYXrro@lkM.TSH5H@[:CHLOt;U'f%)Ra?H47#7_fCFLO[:XKo%aAVecrtWNH2Yr1ZaNm8`JgO-bJC:n>c?B=%?)Y&5lKIQI?c^WGr2Ja<C!$Es3:G&uJeM&E),+u9d0J0o%a>6Kg4p]C?E3u20#_*^T3[58kNB*Nek9gT0&<(s*B6k\jadb'XtLllk=&VMdtItI`6+uVTH'"ri--R?'7Q8tn^Ym\kr83gTOW2R1;b&")oeg/]]`k?_u-bZc.qOEFZhAZXUO^9\Wm"e3`0i*%/nr;B*-ndW+aZ,TI(lnh*Se=q8\>JUU([.IM0f+@"ZeM,E5MC&4DpLl/P^:[<,**dRU'BdsQTH0UTGJl/-ZtmK#Hf1-0imLEjsUUhC2S&_>tUA9F4UH:hn?;]PZEn6ZBON)]/5K(64\pD(&I7li`pmMqYa3r>FVmLCEdAPGiXLm^&iFRh*@@&>.7#lBJQD3jDrVFK4fC8s&^laV00E@WG*s:><f#'i!VH&,sB5P@sFCWM+98TFeGc;-<;mRcJqf0VRf=TdO(:\5?@CA3gi^DE0+4=%0,^=Z=[9-Oo\C"kA$DCA=4lk6XeHe?bZN#mm0#AAV>3pQD>Wmk/b_4f,VsSb&Ea_U@l<Q>bN+1S`"Rg;TP"I,2Q-uFM>%"kdk=VW#%S:q3#<oGo$%@pP.^o"R9n(o'Z1OPRN.-*K>n?U!qBl\2aQj!oNOinle_!/MPdpNOKSB3/cf`3WRnMMC'ecGNPPiI-QpK`P8*dL085Qr+>!S]YelAiEBhCjH'^5..90gIRaG@fL,M:+G&qjQpdI/RBJ;CWN=6aZcpKgb=[\rOKI2&J?BMi;Z\LM<_,1<,hf[+(oq:b^rAYZ!F*UmJTBIDjO>g0ZEHU@^ucrsgtTG6QS`IG#?uj:]3dQi@bG&(i\>qeQ&Xi2=45sV>IP9]H#!s%a4$>>IHK-".*'5K^$Q@Z'bBDS.fOP>[ZW*#P-]*2FH^o+TRt,5ZUh>-U?&b/Nhn/=WW^`sDhlhP#kAc3/=b/7?rg1q#&1,kU<_>*WJmV--"eP,bJe.V"1W`gPa_DP3%ML?\i&DUoi_!qWef[NMdk]Y-0I#e&YO[_]Aud6ES,7#K?lHW+FJ/:7EBSej%fEA&ip^CAb;)URh<kKN[n!U5`9p4/,R0=D1-]Wr6]@CL^qA&bQcQ]\e2acjU>-m02Sla+k3[+>89id\/.&sC5kn*eqi"\q$Afi0_PI,b.'Ve/")hI%%nAX/na7YHpf,n98i14:2Q_Cg?;Rl"C!QRQ^K62\UjOTb/O:/Ui7X7[#>']&.;\B4]r5?@^R9b2n(3\<8EqM"(<2qLTlTK.?<7nfg:L(adg/a<O!j'`XV`*@fkVR.7\SIdqQ$lSU@]Oj`n^XMQeM_[^_@RFknc?4Y0`DH,kfQf?eggP_DNCY\c<T!3G*b#B]l>)k(V*[OKQ$BT0cSWr-RF>E?VcF,gBF[]mF4U9pIj%W)ll2Y@_');;>pTO]GJ.gQ?,*'9?jgVXdPD6?5P(@]sc;oX)aM!F.:\`D.?"SUb`(J)_UP&Thq;Z'07<2&KjP"V^Ue7')`-W&1BUQ`ScHlh[-0V1rVK];Z=0F]"sN3*gf.=T)d<Do5]Gab.V+UB5;D%bV#k`;]eG[0#uIs%#?U&?_@32XS[VM!]u?XBrTIEreJ2lQ7%9nOJh5XDAN@R/*0!pIN(3eV=f@tEeD-mkX56I&)Lo);GGNdJi)]S6h!`$M73E=4B5F.s\S.]B^eK!k:<>+nXZ;!_&H<G_p?C=07Ve#l-Q@3TU7%@2)'!<;uTYV9c$$gg7F:Ck`^0*P/_79G/QWP)s)rfMhl(<@KlF?HKFF"m"1l1D/KB';/1#*[nXJ?4b1`A6<N75lGJOnda`#kRj(-@.*pqNSY)S[J3n5GCZ.8&+6_D[@`Z)2AhWX:@WDc/.?*r,>LsU4J-eq%,I#*rlO*PXkN*&&dsVQ&75_79h$7Ol0c&-D</Dm\/hX$#cFg0,W*O,Zt5b5EP4Mk-@^.n,1:9mnT)@D3'^W!Z*^W'Y1>DLi+@fSBd3sL_P+j`W""WW?S+0Lh9lM7Ncj+_QMS2+U\aSZ-'<#BeqkRGuT%\DK^^BFFJ4P[e4Mgl#n&!Q!,mAB*9uEqi2!m_'``<^S1K$h4-TJbdWMV?8nBJ8"J7qlP%9,YCGoRZ/8[C1QM(1Q=T.-/=FjVQi'qCknOd'"WeFdF7Ug1B@*+7*=ma3h"4Ku32GVm-W4e$oba[\rLn^bPLm#;#A[!QrV~>endstream
+endobj
+% 'R253': class PDFStream
+253 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2810 >>
+stream
+Gb!#]gN)%.&q*PUrh4+6f%H3(Oh1"N*'9S4-=`+5bfnXMCC27/#nmkH!)g,rlaIfU.I(B3:1dG0?&;87dXCt6T*?9%)o"c7Dk$l69]>+!&Ae^MEsTBD(T-ZZCARk]BD3&T_g>[FU0u?c3IB(>3"O2F_4]TjUE46C5JpL=C84'Km.XnV65Tq%)V:l-#=4EZCqFVlJ?s4a!iCIao^?\p?eiujo#!,9edTDjd+"N]$k#Qk(cJVbP-7<u6)6$Q;m%mA$*>bks"KkXP-$aK$m]IDK2M:?!q[I1SnbS8[Uqk3RH0HDaHdf0EML#HV@ps%2g3/L*l&KI\=%6R)=F;N-&J:3BI6[4@`8tRZ\0\MAf4D.rK<RZ_[M<&V^nmr645]4QbY-hQ3c:rVRP@+<WfJ97&u"FV)-1m_G/:j^KFf6AOal$JXGd/Ud#:&_gmER[Z?6ml?o][Nl5V`9H1Fu[J7tRE=mbTAW.hm^hGf&*!@p%G=jsB?IGM+Bk?*<XI.+WbfVo2AlN2[ju`[nYh)##T(6k3oj6-!5qi"6,CKh1_a!>$3:&6$R9oJ#,c?8Mq=4=!]?A*r7)Sm8j]%DM%W\:1FI*s9BMLC[4PW<-e"42q5:U`G7^J_0`k>AcLukiTM^?*m7i-SU8Z%aHCW=aFmbEFo.$<YkFkFJlcZ1#;7`5QW"F$p[UIA)NmCp6,/M+K9(30df`B#BQh0(71V/^i_.D9Er3l@d?%lacED&oiOHS39(PjT1`\Bdi>O_rp<6W5N,:71rmMY)Y:TH?=a,@SseFo0)8EOfcgK@.Ij^E3jh"neWG&*i3t#+1<&?EGJmMu]GW$kT4k%ru`DqdC%"D"(L5ksNuucf[hQlV0&.l%654b^)]=(pl&E/MP/(MAnsN!m!VWrl^oF[qPC:)#g.Z0r#Y\k$jI:],Qka%p_tRY,JGGW5d%a0!c>kT_"+_N%2nBhu+,%>Q;m_gnNSg9/tn4aE$uLW;I-Z"8=oY)4SR3j[VAl7*.#ZQ<`U-:pJ4X$k)i!m5CML$n4`@5/H%<[.tJK]>EPYB@7_0.kO`O4M]e#i&_6!=%I:XM;;"&j.'HIjKu5!UAV+&8VO##'`<.OG'`i%eaLtfgRlOTrg6B_DoZe!:8iY"`<R7_^JBPh)4p1n`$Znc@l=Ch.IqIg7-=+C)+Oa0927,VHBp:Z$:V!5gH7OqhKKO%n\;`*<aoA"j#N$-N\1nJ-olV@cmSm0<R!+J$'.YL/l?RCA1Fi%X0g)IdrCR/QeSf#WR*k@"d;h_l[W.!VFpXIUqGFYj,9Is*sT0TTCrT\G<4Umr`d*%>U0AS<\1U;V9]C,+S87k<#,!>V?@Am9J001EOdPCPZuq_7a,feM?1`9Z#poU0cl"8=KSP$j]PmWMs>TfT!M_qFd8B7]cKsXNr>7!g5MrS6155:O0o=%gd?;'T\h"/Dd<GpUs-+&EX\dJMu$q;lUNo+9:@&Fr/MBGed2^Gh-H@9+#<p@^NB)Q.oC5(;2[g.I!Z4S=t>B%WrdmgSeEn^7X19ce`<8^50;"M/_qFISHZFj'UDXcB^(sVf>[Wnk@%22P'WA$@U:kX[/7A;h50ICgspf-6NAjuo@_[=6_^,nZirNZcm=@d3Dp_q'DCSZqXG!GDa(i!\.1p?;!HMNCJc)t\/OLC0aHZn<a&"1q?@+X#9R;0c^/PLbOXbue-LP9.sd[!Gp6;[\2VA2as*j^0$I-dO&Ei#IJA(&AVpYq\eg.6<%#QG9GQMgUVPC6j%=b+r"K[4(mgU"BZBH0$BL<_s,HK6NJis.$BMFr+6*[Nk,Xb*RBL%@[YoRYFB4__I"I`-nF6!C%R=.=04`?aNJ9@"0'\M3jBfog]7';KR0%aM$qEGd#<7786urUh+R0GOcQl3P-XinnFM@J4Ztllr&:@kqNYTamHYlUOT`0*:)0>]Oeb/h6k;.j%>?biio+j>d.sNp/V.l.:Iobs;cglRt_;7U6o+k-ifJg4bhs-bVlp$QeC@&mpE66]?5O<4(Z_&K.Y4EQ%QT)%hf^Z/SYARN_I<"q,$[<ElXuT_F[$;6Q<`+XZdt[#7NhV!lQ&>N/4J;<7X1aFL.E@Y?,Sq?UM/LO.Ip@\b2,XE.VHB<F2WR%g7>FfHC(uffO*L^il4%*acraP?fA:!8B!j+QVR`^!&42lN=A+m4Cr>d&k`Ngi@H"+njDSMi\\s)`U$Z0%EJ;X8ML(X?-.IO"Mp^)`=bVW'QpnQ-jm'R<]ui+ND^MU+12MA9>imJ6kD@$f;"\WJ%+0*sGLX"g;1+>iTh<6DN17-u*/-\foC)o4L:Pe$p.*020++G&V^R"hTO4mO^,b(\`$g-TDHnh[;;*6bF+_)%d/2N4oSX!'Xa%t-KuRL@;KJJsW*KeK;IUcK=&HS7PA3\Cp<KH2%d>T*JPpTq=JC``W[6bHbt7N\SN+Y-a9H+T<lA%]VgZ7Tq-.;ZY&=^i/at])^B/,c/C1>c<9u%krKY:.UkU\+]a(TA!(j.=BCY&<LhM:g>]]&T92e@Xnp2!6iMQ;0;k=j=4.*8`.8`RW<VN1e\krP\e?7.7-\!cAjr_j9'm5+:H(lk-m^ViY283q>^[=Ou^[7;-47ic4o6/KXYOIX@mVVj+Hcb-$HcbK=KC9g-c!1S\iO:VET%MMgiHC%_QY(Da3hpV+-YAUTI=KnV#_&NHs2==$oJM0:s/E%C]/J/D[>RaXkdA%AB@fd*[r5FZ-m$g8p?BtSa[./=?V^-$h".Il?LAI"LCJF#;=3DkHb9&-oj)a9;[dZ\d?;Y3C`gt/GAEL_pNPAO5CqWRM`ul&3N\%/B*^VLp-2MgcX-~>endstream
+endobj
+% 'R254': class PDFStream
+254 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2804 >>
+stream
+Gb!;e=``=e&q5%is$OQ'P*-rX4L/0qV-%o8>q9n=HFL?6q_/),ikthO`W27qn'aFP@fV*)W&UrfU`uKm]>*Ujl[]9nrd+Ds:'&(9_"eo[4<G=hn3SLU`ERT#Gkp?_rq!/K;$ao)9I$(VC%pQ0X4s/D)gHf7pFfn3Wa<$Ze<s#T=JXl#%X-n/[,]YmBM2G,k'(e(c+\bJDm9";DuYapqc#fXd[+PY9PSS4-1nY/DaNquXc.1t;U5bbdY.>^.AAoZ6`NQ7<4UXt&eVH:a:-q215jbg&1N)q59&%M8$Yg$"*!^oEhC/(eFC0`&hhfU<\d8-]u]Vl[IPhECKVuW8@0GG$7GSB=GmRpS>S8-(+[4f:nWus;-G#)MIHE7-0D"&UWMAQP7QMlWb!EkL@I#9NBH:jF*Xs6rZ*7h.0P66i!$9QWhTQM-FChFM88fWc2#WWNK(aGBE5oQ<Vq]-jlrg6`ZK$t-IHK,Jm^bHJ71)qpt3R1*N'R)!TWCtQU*#j3E'LLcHVUIp-KNGdCi7*-mZ_dh'BYKfodp9K[A'l?a2@8JAm5pMW,3m9MQVQ6n?QQK#lrID!%2R$RjXtNZ1Vf"j;gI9-!M'AE<o0EZ$+uVg;u=ocdW&;Cl7oifEH/h+_Fi$k9^Wa]<eBIpJZJbE`^G,QX=HauLulL+dsChSbg&&Ykt^8T$qR#dTE4;Lt*6Nq9M3f5^&qqg=^\;$IJT1+(3BHd+>hK`i;e2p8;UQGY<;=`[if%f,Z0EdhX"dCC\.QJbUl+4'L5bHP^%S:I^KSs'2Wd;EZ(W7OB;P\!C!?^CSPH,s7GM%#C!nq=8[@9iX:(^<)SO:VAaNISio-M0*JrqET\O:6I89WsnJ!3Y08JK&?`gebK/\)$)liq4QQ8@SJ=HSp%lAuF+Ib^,g\98ZhHHJMWFJYe,__e>*giR!NQa/1eSp1_(<aI_4$?oU!<]3@/:hX(:uHP\T5KgW2ZG3,U9\*F(1pF^k2f4O:jZ9(4OKnb62)32,K*INWCVLH!5Y-YDOcp+-C'SfaFb.G?lenNW>m`nrDi%h[jPM"@u/9D*^.m1.`n8uL%V]*)(AA28jpl7S4aV;`K2c)3XJ]pWAlql3t<dq1R2`r^6iX".VaV/oQHiaEGX[o[5>jOnQUX4'ohCbGW;l*ZYAfScX49Kfqpcc.`1M7bkm&3@+&U8%JC#DIV7[.RcC:rV3&L6<Z)O9lpW7'\uqjU%/#Rj[l;lXhpEKF!#ohe0/jZa&%OE%,q3LCA?R>D>N+]`Okn3huenN7OYf`^=\k:<.q%#%p.\C=teL#9k].g>t'"-'mfaKJjj1.Or[$N@^&1J7YMR9>BVjBJ4s%;+mOD6:8L:ViaIbsph@"`hI*1&5.Y)M&W!<bG%[Ob+U65mYT<5X+_;'Y,A#W:t<]W#l]PVH*XYk';MX/^?fa\]SK`#@l/N'=5V@Y0L1,$R0ijN#$6P?t,=\Vj\0\!@L9f8XC4>NY8pRDU+$X84%u%l%E$+Md(6l78oc;]\>4^Y8%sI9#ra6pa-*-V!H9C'M`8H?#OnWl+D%K6YpLE2AY+iA^;5LUOsbFPOP6$HQ4r^?+!U7%N@n4*$4RPJa3GKpt$>bm5SS`ae0T5n;?72XYGj"Y$hf4bVKYAW"*I]G?[o`!SMuhhH^&d/)O\WP?g?),>rHAW@/,5nLQt$NXq+[=:V'p8o/S,W\;uCJ&jMA\E><kI9Wu;VW>qq]e/s.-'jJMi!NSH]s7rIbWtNB$Q2UJ_@gi>[3lUs6783aSR+LH(\nQR7l>Bb2AIiL.;=CiBRtfhoUru).m;Y9r&K(,";</agai`X_-F`ldXLmY4Nai#']O3b+,jj[<<CsZ"e)a*B6tbeN/F^)6(*R*-&;5_GW8X@,KAsdDk,(RA:hW=F$P0"0J54_Q0FlD\%5..BS"\[7]FbfY:_n;c&B6iR<a.MJO@iGP=MQM*F377THZ%!j)-pZAm_]r2TJ$8`Z2ETjA4`#3r+&+-ZJ"'^ln[/Gu=F>>SQsge)^jJESQuL/!4Tif^C<2Pt0Z]+6tC,5pdH7-up^J4i_:US,AJOa.I]c/F\B(>Yq$7aQ[%rT^Fj[][!r0QPlJ[hN%O'E5FU*VX4lu;bX4RSs<65d[.&jd`d@bY-m\OSl/EN;\E_6[#,hF=2d>!=1ZmMigRtWhEA=!B[n[b/mabnBhTd`FH<>4+iIj50k`/L"$aqTUcnN&)DK.sjp63Q"<Be9XoJ%b65+3Hk<e^!anKNkF7J%o>3/(N7\IF*A/9;K^jUlfMLlpY_H7I9cP2rc+^,P^Nk%Ib5tJ7Eg2ab=h5;s<3P36]"LjEr[/uh"^>&g.%jISnIZF]MX6S,F/EC36+nK=6rrZeBA;JcAcE`&MX9kYU`:-h32p0k<!S!$`f`@D+-WQX@'l?(8QN)lCn[ul1DhUQKLGU`jH7PB]U?)5H:s44V2r/_1N'X#B>FELGlRtoCPI@8L!r$AWbUptYhXs*e[8s<k"s65pV2KZL)I4.[S/#Vl#C`W$_Eh90kRmFsa\W%ckp'RBk)MO[*'Yf%*H,bad,r!sl\FrK/*5$Gi4rJ+C[u,PJUK^e2a@<>rp=9F2+/goC1i-Bk'\@u)h)8X8Zr48HJ_()QhkZqPG,dJfHKMS5;-L/_`-UAG,'\Uo/2(m/>=UnkXH216*b9lC<^eZQdnCoWIumAqMUDY`t?F%:E'"eTK\(u+36O@$E\$a!-\2bBQ%&n6$$@5CoBN+N1"d7Bo!_2B<<eml<QOb`qF/%5K%q:<CAI_]CdieYc]KrKBg6&0@;gWAP1rcGH"B.0>)]&413AgD?~>endstream
+endobj
+% 'R255': class PDFStream
+255 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2377 >>
+stream
+Gb!#\>BAOW'7J2#rW=KC:.JnblJAGM8M?LR=/V<GSPIW=L]f"L,estar9<,5/3m*t/DG8"R7o`"6]f+Ofs>=8&[ESZK^S:gBC*5Fqtc)0Kb7Oc/0"n)[X--2?Tio4ao-ncl]X&]U0omq2b21]Fr<3aK%Y)W7MBtBr#'YegOj+SHob]:S:tC%AaE2?c@Q?C3HTbn%D)l^0A5Um>CGUns2FqaC4?!?e='MsI`.cJ2KXscO=BSmpF]^`%qd\2)VK8i8afeX8$=Zu9#[o?AYlKPKjk"n=g$E'f.30W9#Y"X/+%Mq2C2FJ^i[]L_Z*+ON5r1WL0;df<\VEkZI]&r(9oJb@1'+LWA_,bZ!O^dQ'>J3Z_GNObcTC;":kK\0?SLiVMcf5i]_75M]`H.+_C_p_Zk3FE!NlmHLCM0,[Df8=*mu4E[NZJ_599dYZ?H+.ta2G?^+aKpFk>l=Jbcj2RM6>H1C$>Io*&liTC;\"`FHKHt4ZgFT1ed:gX)qQq8$*<<<l2ngNja'fhI<h[&s&9>jTFGVLj,OUG_@LqpX.4ri4naGm2%JIar%4\MTUf\3X<e2_C$U.2260qm7HGNT%W)Wc,fZd'K:+9'CADd`V/Y=HEs7/`A.\#iJGcrclNPdOf;#A4--+R?GsLleBEN&Lb<9>OB?VFc!Y2j_ND"<GAF]j'rq&?s]N>:+?Q,[RrWl+Fou&;_'iS:;6[dh**534^U0$QX`/Q*C]nM:`rU:))rqA]QH%i=g+]/"VZ^&(ls3Q3/IM*)OL4HQ*AslY7t5'N3n#a!hOS-'(h!"EC`+R*!sJ+BKHbV0<jh!qsWHI^?^a4'?;er*kKeoLdTenEEJ:>I.dFn?pK9Q,<=o!<tPc8sFsT2g.Aq8.YK`*Q;hFZ8Q=>QdQe7V82n[1f1!N]9R@>!8a8Up4OE:7"t5f71.6[%EHr:?"o1JBKDT-r\&jPmGfrE@c8`.Ho\A,@DH46]R]Yb^cbm.+L8*0+mP+-4<+RCC",)JrSk"F5(BG31n=m3OH##]1aH"@L:;cV!cPNn1:DS1#)pH-g..fCT2W'WdgPSgH:[B!E'c%f=tSXHA:HSW]FD7FY;O(WjAEPM&,qd_*LE2;MFO#gK<>TDD!@/\?)^&E(la>]<_Fog4dCn;b\Uif&F#-Km4Cj-CXl;IJ6aIX,e(SArSW]bMpeik:Y.OD?TWgYPSYcZ7,>\UWD$sK4P3X@6(3tgg/;VF'V'iLWl3pIPc8&%I"WiTNk)-)AA4A!WdY:ch5;N=P\d0U%2QZ+G\Pq+iF'A[[Op(P'=)R>R0N8e2lV.cE\n1oI0pX1%HKE(/.m"nLN9Pg(f>B8IUZM)pe?_)8e_P_V]gVX4k_4FqaS4pY?^U$<uXL1aM6(MoF=h#TWSAg"Cdi#isZAug0l"<3_k=Z!]6.U';7DI<G!NYKJ;bgB`cdALAVUNi)COBWXYLA>QO/UO;UY'Oq/M?QIX!!ZDt&r::rZJ9:I6U3!s7!NTq0Z&Oi<\Q3"s!O`9Vk=k5M*[W42H#G]VrjZXBb\q*7:P)FS.Pr(L@\J.KP@ilP8+\Q8<D>Wc@h^20kW/%RU.<>@e.^nY-?=\((?EgHFUk*o-.<0Xt]+!u0\kSBB=>W`r.6^`kr!<KCTtUAOcs@llF()O=JNPEfR/4o*L*jTte<bLmX]p2be;!Z#"Osn6q"gdar.&U*M\+3c+1D+!WQm8IgT<^(GtQ=9objqT#!k34hKN9`Wl0U0q?&fGc$ic4^Xu25CWOgJJ@ag)L=Y\@'tSrahl9BA`;&:_V^XYr"H_%MC+D;`>%>54O&.fcN-\h^68)BV%4B8U)??!*JAuJmhtd8,Z`StZ^O+KQNo;7.Ucs:=E*R`J*7,fl1lQC-[,sph%UC2R\g"3Ic4pLmFicR<W!OKSmOUi6d:6;XbL[rGHO!i#K<hNqVCDo^NGbD_o[/rC^TPn*ZR1sWJGlRO3/jD.@F0Jo]^7*W[GFt.\o=ZnD2#&iQ=qAD@l-ZH.Tuca&OhW9On%hRBcQ$W9`bu>8NLa^g6H^18bZI10qP-<Vs:NUVnNp5*?)8l_]'F@C*)o8)b^g]46V,k`>4YY.dH0='j7&8Bnl<jUq7R3/(e).f^7)MEo0F,?$F*5'I/Zsl1("rb)o@MWScU*>hGRYS:YsF;=638hU07$e'4C><YmVD%pbuPXtIEU4Q.nigeJ+>I&J/ni)a1+oi%<9E%uW[E;nHmaq7AE#X*.:1&Xh:b^sj7L8R,fLSK,K+5qK)_]+'9O.pp(R*Ib=:8e!(V's+Eb!db^*HYi=ETJg!GQn&]R#=M,%-U4JqNcJ+#'bGLXh-S>c?LeecJ>n#b"AR'Kkm$N0pS[j\+VM4o&o&<1!OiAB.?=jI#'QEq6Rg95[?'p~>endstream
+endobj
+% 'R256': class PDFStream
+256 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2070 >>
+stream
+Gb!;f?$"^Z'RfFDs21D?1t_m_[]p9i9=!r,B:A3XkW\)sfE0RTQ7L(Nr;40jbVohTCM5a_)'[b^e^;pXk=TcgK-/_CNAH*c!W;cM"kSCC#i)T3Ku$9(2gG;dL\\O3j$=JDc\V^NB<BsC[Q?-`U5n\g!DHk8_H,J]8!27.!uPS,\dhbNqmshh$$;LSo+>IlpGs*Ep^Vp@9_Vo<pW*3PQVD6>2fq`3:Dec@q42EUhm1>r*&$q/CK00tHVn@?#HmOZ<nAn7/..gnlmH%))m7VP.aHQI##m)I/9jjP;U?eM?ai-+,H'kZL3!%7[Ggm$a01-b?p`h@B*D.KaASmIFpPQ';\W=TVe&1@`'iTl2'E<9r]gVqM.A@1JdQmfkJ0Si9AqX%"D8$gI=M4[k%4d`bKkZ"n:=@a^>&dH%F^SG-@sCG3feQPPrXas_\*<m'p!VI6`R#Jk)dpp(/rlfL;o<;k6e7t<2Smg'\Z:q(sW+c;!)*kU<I\ENrdKN]'F?.X%"'KH7nHCP3+6b[Am,4=cq,@bH)!XbAP&M%Y1@<6U@M)".k_pakMY[%qsX:5e:HB\TJ!j=2oh$[:M2V;l@?:F@5ANa'3$,!B/0@l+m*`CCr9aaMkZl[0&soi;lgjF8nf#a4g0\?fZ(G97^J[ZeoJUF!2skXa=8q,S58KZtE,/HsY^]#KI4BrglQb)j(jXqAP_))NRphhmlTp/CS4uL>:cn'6^*u2dm"iFLU!Vgf=M-q++3d+uUuTRXjDOjfPl@LTBJ'jd:0[loVB)1gWsD\*S&UG*3V/4:WB'"XV8!mW1S:/%";njAO\56s_YbJW(s5Kot;]JU)HT6Y`L7;G4W=BojJ=&NDR0/-o_/H#g@*Q01lj<c-4LquT2=XG*]t7"s-0,$&`E(/hW<_R"q`T,E/22R&&F@YUqs5WV0E9P=$D0F0^7&FPJCSY-qqHJ=Rqj$`hqY_UM=>dl\o%fVcoZ7tG@SP)E"oWZFF][5p0Z*Q/WEh+N`l,k^')V$pF\;(;Yi(Z]/BgqsjNEn1_?dO5?oJ%sF9CqiH6IjW@UY$L&bA.fqb!1%l<^faCrb_'%F1"jaQ>XIPfA.Bu`BPq*RpkcRW,1(?rOq0l&W/:=GU`;^5q8SikmT6nOS),mm@I(d1eSQ*8X[V_%9`JIoX8-g@HiO!:RECELm%r'hKS_6]ba9Ts&-[&1TMF;+U"$<YlIc29R$8()USU=F;3"-AOC8_n[U)4Nm].\,irMLNUauqpRV]WFtH=KP=/]G2%q=Dd*fc)H8Pr/4W6PBIb3df/ZH-o$d?31H'T5>\tDqup#jp;rSKKHhIt$91QH5H0Y7mb6`_-PCP(XeN-'8Mb'=&26hBm:iW.nO#gO5)JNl:e`"Iu9KTre7YdoEO"@TR]$XBd!M>jF&nbm.iSm>hkG8g_^Q6HlX8!A&70h]ZfP[lmHPEL0rJ6kV:YRq,M@K"?F"cXtn7#'h[<71gUe0,]mmr_FHI6jVf?Dh&V*?.^7Qqsca!`MYMP/[\H;5tDX5OaV4Ko9io%tG3Yf#bugC_Xa)\QP"E5.B=s0RhT)jYEt[^f4BDOjl?T';Va6YK$:S#o(:)5Otl3DFWO[Ms9>FLm7C\cuDjX2h)2aiH;i_jXWia&mNf]"A6Q&qPVMANhRf-UAH[A`:LGC4=#o=p:"D+P5(:d_X$upA%eXqLdt$T9gr<Lp`>PJ./I2CNt==1WN(-P_3-5^cbse'erBU@19J(eq3ACh!S$"nEkB$6ANn@.4reHdSD`T,_<J7iAqSu6iKc>,[qbfshIU\sq[`^G7GjQmOs)<+lH6nq4Qo/aN)hkZVA"\lBdANu)j=;uR[XM97We',@5P0Q$Z7\3hK%JW5/Yo0('I@S4<_6jY>h?VF$s?u`^snSj2:?Z`(Y*?+tmfYe(QA]CP(!12W`q)/uQk'rcCJJ\CAbX`MbYMr[^q_1M&18LlCGa$8GfOUS#N6j.%e>7d@gt.V*"OVW_&3B6&$:IWodU@Bn0lTN00uk(ZlkptAhh*;sA1(b?\,#Of$T<cI@d)X)q<$HA/o5m>Dl%*^&<H+i2dDhQ`GrWBM$(6n~>endstream
+endobj
+xref
+0 257
+0000000000 65535 f
+0000000113 00000 n
+0000000249 00000 n
+0000000455 00000 n
+0000012239 00000 n
+0000012426 00000 n
+0000012668 00000 n
+0000012897 00000 n
+0000013126 00000 n
+0000013355 00000 n
+0000013582 00000 n
+0000013810 00000 n
+0000014042 00000 n
+0000014274 00000 n
+0000014506 00000 n
+0000014737 00000 n
+0000014967 00000 n
+0000015199 00000 n
+0000015429 00000 n
+0000015661 00000 n
+0000015893 00000 n
+0000016123 00000 n
+0000016353 00000 n
+0000016585 00000 n
+0000016817 00000 n
+0000017048 00000 n
+0000017280 00000 n
+0000017510 00000 n
+0000017741 00000 n
+0000017971 00000 n
+0000018203 00000 n
+0000018435 00000 n
+0000018666 00000 n
+0000018898 00000 n
+0000019130 00000 n
+0000019361 00000 n
+0000019592 00000 n
+0000019824 00000 n
+0000020056 00000 n
+0000020288 00000 n
+0000020518 00000 n
+0000020749 00000 n
+0000020980 00000 n
+0000021212 00000 n
+0000021443 00000 n
+0000021675 00000 n
+0000021907 00000 n
+0000022120 00000 n
+0000022858 00000 n
+0000023089 00000 n
+0000023319 00000 n
+0000023549 00000 n
+0000023780 00000 n
+0000024010 00000 n
+0000024242 00000 n
+0000024473 00000 n
+0000024705 00000 n
+0000024937 00000 n
+0000025169 00000 n
+0000025401 00000 n
+0000025633 00000 n
+0000025864 00000 n
+0000026094 00000 n
+0000026324 00000 n
+0000026554 00000 n
+0000026783 00000 n
+0000027015 00000 n
+0000027246 00000 n
+0000027477 00000 n
+0000027692 00000 n
+0000028181 00000 n
+0000028416 00000 n
+0000028652 00000 n
+0000028887 00000 n
+0000029141 00000 n
+0000029409 00000 n
+0000029654 00000 n
+0000029926 00000 n
+0000030217 00000 n
+0000030494 00000 n
+0000030768 00000 n
+0000031049 00000 n
+0000031327 00000 n
+0000031622 00000 n
+0000031913 00000 n
+0000032194 00000 n
+0000032508 00000 n
+0000032796 00000 n
+0000033079 00000 n
+0000033366 00000 n
+0000033626 00000 n
+0000033906 00000 n
+0000034184 00000 n
+0000034474 00000 n
+0000034755 00000 n
+0000035051 00000 n
+0000035334 00000 n
+0000035612 00000 n
+0000036154 00000 n
+0000036443 00000 n
+0000036728 00000 n
+0000037021 00000 n
+0000037306 00000 n
+0000037604 00000 n
+0000037841 00000 n
+0000038062 00000 n
+0000038239 00000 n
+0000038460 00000 n
+0000038645 00000 n
+0000038863 00000 n
+0000039236 00000 n
+0000039509 00000 n
+0000039799 00000 n
+0000040021 00000 n
+0000040333 00000 n
+0000040573 00000 n
+0000040812 00000 n
+0000041034 00000 n
+0000041366 00000 n
+0000041605 00000 n
+0000041846 00000 n
+0000042079 00000 n
+0000042320 00000 n
+0000042560 00000 n
+0000042801 00000 n
+0000043025 00000 n
+0000043397 00000 n
+0000043637 00000 n
+0000043876 00000 n
+0000044112 00000 n
+0000044353 00000 n
+0000044593 00000 n
+0000044833 00000 n
+0000045058 00000 n
+0000045414 00000 n
+0000045688 00000 n
+0000045978 00000 n
+0000046215 00000 n
+0000046453 00000 n
+0000046691 00000 n
+0000046932 00000 n
+0000047157 00000 n
+0000047509 00000 n
+0000047749 00000 n
+0000047990 00000 n
+0000048229 00000 n
+0000048452 00000 n
+0000048794 00000 n
+0000049017 00000 n
+0000049329 00000 n
+0000049570 00000 n
+0000049811 00000 n
+0000050036 00000 n
+0000050368 00000 n
+0000050594 00000 n
+0000050906 00000 n
+0000051144 00000 n
+0000051383 00000 n
+0000051620 00000 n
+0000051843 00000 n
+0000052185 00000 n
+0000052419 00000 n
+0000052656 00000 n
+0000052962 00000 n
+0000053237 00000 n
+0000053379 00000 n
+0000053623 00000 n
+0000053752 00000 n
+0000053958 00000 n
+0000054115 00000 n
+0000054286 00000 n
+0000054454 00000 n
+0000054667 00000 n
+0000054838 00000 n
+0000055067 00000 n
+0000055226 00000 n
+0000055406 00000 n
+0000055590 00000 n
+0000055780 00000 n
+0000055962 00000 n
+0000056145 00000 n
+0000056312 00000 n
+0000056498 00000 n
+0000056722 00000 n
+0000056891 00000 n
+0000057060 00000 n
+0000057250 00000 n
+0000057426 00000 n
+0000057617 00000 n
+0000057836 00000 n
+0000057991 00000 n
+0000058168 00000 n
+0000058338 00000 n
+0000058508 00000 n
+0000058671 00000 n
+0000058863 00000 n
+0000059058 00000 n
+0000059287 00000 n
+0000059445 00000 n
+0000059622 00000 n
+0000059781 00000 n
+0000059969 00000 n
+0000060197 00000 n
+0000060395 00000 n
+0000060578 00000 n
+0000060757 00000 n
+0000060928 00000 n
+0000061098 00000 n
+0000061280 00000 n
+0000061460 00000 n
+0000061639 00000 n
+0000061804 00000 n
+0000061981 00000 n
+0000062167 00000 n
+0000062335 00000 n
+0000062512 00000 n
+0000062683 00000 n
+0000062850 00000 n
+0000063023 00000 n
+0000063205 00000 n
+0000063395 00000 n
+0000063551 00000 n
+0000063737 00000 n
+0000063972 00000 n
+0000064131 00000 n
+0000064320 00000 n
+0000064506 00000 n
+0000064686 00000 n
+0000064872 00000 n
+0000065052 00000 n
+0000065224 00000 n
+0000065448 00000 n
+0000065612 00000 n
+0000065800 00000 n
+0000065988 00000 n
+0000066201 00000 n
+0000066341 00000 n
+0000066640 00000 n
+0000068581 00000 n
+0000069671 00000 n
+0000073063 00000 n
+0000076143 00000 n
+0000079473 00000 n
+0000081897 00000 n
+0000084809 00000 n
+0000087559 00000 n
+0000090606 00000 n
+0000093498 00000 n
+0000097965 00000 n
+0000100530 00000 n
+0000104604 00000 n
+0000107170 00000 n
+0000109601 00000 n
+0000112475 00000 n
+0000115430 00000 n
+0000118379 00000 n
+0000120901 00000 n
+trailer
+<< /ID
+ % ReportLab generated PDF document -- digest (http://www.reportlab.com)
+ [(\022>\213\334V\233\247\366\264\322\211\021\001\252\337\213) (\022>\213\334V\233\247\366\264\322\211\021\001\252\337\213)]
+
+ /Info 165 0 R
+ /Root 164 0 R
+ /Size 257 >>
+startxref
+123088
+%%EOF
diff --git a/pdk/docs/compatibility/android-2.3-cdd.pdf b/pdk/docs/compatibility/android-2.3-cdd.pdf
new file mode 100644
index 0000000..eb77a7d
--- /dev/null
+++ b/pdk/docs/compatibility/android-2.3-cdd.pdf
@@ -0,0 +1,5223 @@
+%PDF-1.4
+%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
+% 'BasicFonts': class PDFDictionary
+1 0 obj
+% The standard fonts dictionary
+<< /F1 2 0 R
+ /F2 4 0 R
+ /F3 131 0 R
+ /F4 133 0 R
+ /F5 145 0 R >>
+endobj
+% 'F1': class PDFType1Font
+2 0 obj
+% Font Helvetica
+<< /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'FormXob.c4c4c9f90f2c427799b277ddd57a9a5b': class PDFImageXObject
+3 0 obj
+<< /BitsPerComponent 8
+ /ColorSpace /DeviceRGB
+ /Filter [ /ASCII85Decode
+ /DCTDecode ]
+ /Height 49
+ /Length 11548
+ /Subtype /Image
+ /Type /XObject
+ /Width 369 >>
+stream
+s4IA0!"_al8O`[\!<<*#!!*'"s5F.Y8OGjP:f:(Y8PDPQ!<E0#"70H8E,5RU!!$kRFE18L66KB5=s+('!!3-/!"JuF!'"CsF)XEA:eUihzzzzzzp=93Ezdk,!IE,5LSzzzzzzzzzzz!"O$O=]te*!A"3N!#0'J=]te*!C-Vb!#/mE=]te*!E9%!!#0X!E-)'[!GDH5!#/pV@:T?<!IOkI!%`.i;F:Ea!N5tu!"NX@;F:Ea!Or+0!"NI;;F:Ea!QY6@!"O0^B64+R!S@AP!&/;$Bl3nN!XJc+!'"M#F(51M!^H_c!+]V]@r22G!i,er!;^PLDe&hJ"/#Vo!%;>rEc_9]"3:HB!$kZL=s*eFzS#-/c9N;&m!jGd0=s*eFz2.HUdTBcIW)6m:H=s*eFz--ZDi'@d'_[`)?O=s*eFzo@O$D!!!!"('ntn1GSq1!!!!"$b$*9"d]2go2bnl#:TWQrR_)LqmZV*rMBPp"53_T_"M8\EcqE_z!!*,F!!$MOEcqE_z!!*,F!!$MOEcqE_z!!*,F!!%1PB64+Rz!!*'"d<#?g!!!!"zd<#?g!!!!"zd<#?g!!!!"!!$nIBl3nNz!&+BQW.4jJ;ZHdt1dD$@W^$Oa-C4]4'&*Bd:d>!\<'UEb1G]"41G]"41G`QQF(51Mz!")7n+A>Tf0K(cgzzzzzzzzzzzzzzzzzzz!!$kPF^kCOz!"o83!"<aS:/:ii!"o83!9eBD:fIDp!"o83!9eKI;agZd!"o83!9e$/7S*R[!"o83!9ds%6q[L[!"o83!9e`B6V[U]!"o83!9e$87T'3d!"o83!9e0+8l,Kf!"o83!9e!3<Drkt!"o83!9eB<:eUih!"o83!9eBD6;dd`!"o83!9e!878j0d!"o83!9e`B<*'&"!"o83!9eHG;H3\s!"o83!9e3:92Y`i!"o83!9ds)6q%(U!"o83!9e<::.tWf!"o83!9e-=8Q5Zi!"o83!9aDR!)NY<!)*Ah!&FU/!&ag7!!$kQDe&hJz,4GR4-BJ3-!!'kS8:U[?zzz!!%+PG]Woc!!#B)E-ZJ<B4uB06#^dZALnrqDIY:M+>PW)3<9*<!'ittBk@>F9hbU;!!!!)!!.jh!!E9%!!*'"!#bh;!!!!#TE5)r!!!!"!!!%>TE>/s!!!!"!!!!Rzs4[N@!!30%!<E3&!<E3&!WiE)"9S],!WiN-"9Sc2"U5/8"U,&6#71Y?#7(P<"UGJA#RLeE$46tB$OdCM$jd7J$NJi\6NI5i!WiE)"Tni1$3gY<$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$4?gK!"fJ:0`c7r!?qLF&HMtG!WU(<*rl9A"T\W)!<E3$z!!!!"!WrQ/"pYD?$4HmP!4<@<!W`B*!X&T/"U"r.!!.KK!WrE*&Hrdj0gQ!W;.0\RE>10ZOeE%*6F"?A;UOtZ1LbBV#mqFa(`=5<-7:2j.Ps"@2`NfY6UX@47n?3D;cHat='/U/@q9._B4u!oF*)PJGBeCZK7nr5LPUeEP*;,qQC!u,R\HRQV5C/hWN*81['d?O\@K2f_o0O6a2lBFdaQ^rf%8R-g>V&OjQ5OekiqC&o(2MHp@n@XqZ"J6*ru?D!<E3%!<E3%!<<*"!!!!"!WrQ/"pYD?$4HmP!4<C=!W`?*"9Sc3"U"r.!<RHF!<N?8"9fr'"qj4!#@VTc+u4]T'LIqUZ,$_k1K*]W@WKj'(*k`q-1Mcg)&ahL-n-W'2E*TU3^Z;(7Rp!@8lJ\h<``C+>%;)SAnPdkC3+K>G'A1VH@gd&KnbA=M2II[Pa.Q$R$jD;USO``Vl6SpZEppG[^WcW]#)A'`Q#s>ai`&\eCE.%f\,!<j5f=akNM0qo(2MHp@n@XqZ#7L$j-M1!YGMH!'^J^eG-NC01u",nG`Ffa4e4cpM":c88PCn1>L,"M]>S:ok/CblnWoh&#FYmpsZ*f6h'8mIO]^cdki!c&P7/NgtMOeqa+M.%A^H91+Y[F`*5e<*0Mi!INs5)nE7bT"_o(ZnRPP2Nh[.g9G3_gNKo-lLr5u4W\?PoW5p3@jts8l?<$bImu"h-G_]Y9cn@#KZ+/=&hgW]6hUSBAOXXZQb5utFf-?0\bAC!hWk54??CH'+Xo;O,jZG?r;L%q4D\)X+`4lUfe,0a9]im!P8(?-k&mdiO\P%4N?n)n$Q%8b5Fp!n'):A!Ka'XdT$0Jnj:W*cqej&YZfjBR'Fe(>,CGj$GbqP,0%C8O#^@IG;jCJ**k\`QbG[BRlGD?)2bH'P!Mo.J7I.habPKfAp*E`N;/hl%*^`@[$cPM&TPC,dJ*Zp1[)*CitkYc-sl>I+ngHfO/M)V4C(nk#UJIB;1SYM_H:A!sdj,-^>D82D8Dl2B[R=?+S!,173r#XEH9g\0]*Zr/drfuTXdO0tuK)O\?6HlmA+5R1C$_NdeK?,m`.fH'T-XM&0?-thFr#p\uZgaIr8Zpk6)S!%tSk+OlB=:NoQP#<P2]:Wr2f="DrKb/,Hs9gg6Wro\]p?!I/9;=5l-Q5-Z-+3EN[-)A?ml.3+HLm^=5jbW]qG/T`EJmkoT+fW-h,o[rOd)oNn6P2=CTdF(LUlW7b[`':!8PYA<L,<_K!Qd4$>c/lfIC1APF]KP1DaBXi7%4.e$[]KU;Z<[db]32%;q>L"]b>JZ[uV==1hB9*0-'#9;<UJ:9A#k3q:d?OD68Hn^W!\u#+g/bYBLAZRMZD0h>MM%_$IUNI'E$j\(?NWGP4B3u0_qSMQI"n=4?iVB/9ID:Og%=j<7bA@^)R9b3iD:0%hP1do%p#`.@(VkB)$2ELUM*<9Vrk%0LCtK[W9<E)&G$2U_1Ft7L)CcLP2`<EVa0&A%[Y7.ZH'R9if!jdcZr'8(FbLN,5Qqj!5Qqj^kn4j[E2oZab]!RT-B\\/\V2Xfj]Ngj6R/@D<X4^P*C6NEHZ]A=<B7]^iTko40+?10fd<OX->571\j`2]`cCAdG81rWJW:1PC]=AIr!hV7'kr+(nHXkZ[FFl47[\$92t)PF@rNAdP!B&(al$d8WJeVjK9]&kMG6S-Uq)sd036duDVJI9FH,!&U:LOC<@p/JSfQC#Y;FKK?F%2Re)V+ugY6!ZZ<K?7(0+7)'=@8]k\Dn:.<lI(,!Wr,iWL1j>)SHGR+N%)B8=LT_/S.MS/gRl3N%hQ;c.V8'W3Q`G.!XMlL+:j/TbI53XR@&WT$,QBQmLC>2Hr(B/TVD9oN.T8J>?"EJ09*"l#0TalHI&S#^<a]_fm.i]oa^,D@!\!&Aso"6sZ5;O_]!9(CeE]'J*:O.qL]^aPq7!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!9X82Hrf`t_7p8jN4`^a_VJg+@><Jio$8ff66IN^iE5Y9_ObP^)u^1+i/PZ._i7WSn4hD",-?@27R,t#BRf^t+8R0RpMUDk=_W=&e+ESsdPrA(as;]Y:a2Wf(]Y&2q=ZHV`7_U5ic=r$.QD0fGZ/h[C86u`hcVI5h$dMe.ZPt3a!^@8p4Mj1a/pu^o>;/G>?t>d$gS2=!TO]]X;OT1;mhAc,928sSepAkmHsDh_7h>/nA^aPm7159;`$;e>J+sodOE!EP"BTu,Ba&Hj!1#e>5>B$$2%e=DnL"f)d(A#e00Z]fJ`p[;H+^QO9lrs4U!t2'u\a@:0j+3`C3kH3h4`KQV)8[<i4s.h<b+-e^_)73f1j*lHKbGrX't@dnnS'ZIZZ1X&rTKiEkk+:*RgWbb0T>h\eV.f<K]lpo!'=L)pVaa8RC"/Z5>@P&12aXr75u`&!-"e/X%"8HYFP^\B3GKp;T;"RRl)[76bF?A([#?^V!d+CG^V%L,FN%maIXm=#!7-AgZ1qYJZ*oR^iK0cWR!R07Rl(qS,5:Cg&4+[/XqAD4AID)@]qrr>3(QT;sO2gZ=trX(aFE9GF>F/p&%"PlHP*o`C_*^/GQrr<N$:](TX]t<5,Xf[Z$T+,"-gS@]LK4mS@JNtOs,iF!3:ZGa^q\eWZ>X,Sc`!2,pJPDZd&_[g.*_Mp!"]P;n!"M'tkJgQ_]I#EfU&Cf(ou>P\KNBInc/%u6?YB;#F]1r&Ij:cYQi%O>iI8JC6)8:f):\;WXs?tNfbulGN0B4BJdS]\!<#"2V>PB/d@kppn8*P-f<i`%`1HcV+Lec4$V8G/a^`*o)tVB8*UCh^i1j<g:[n*DeJcjlEuqVr8bNV0)CHhPkXm;EYc5BUJ,)%,&,uX^Iae;s8M2N07hBYm:P@!^pknUD<s]4TKgc.eNBJ8!es=eTm$jO)Umo&TTCDC>"b4oYeUR'<.eKoq5IAaf5!9jc*<t*_a&0-u8TA6d(FCnW^,Al5-m_1)#UFE2-`m)]@:c;551&s#3mou1Mb1Ai`=`>SrS!iqgll)/r"=T%5PFU:Q*$!<$qAh:0uPuLb`FR;Hh6p5[uB>%P9$"5)iTe$SgnIfO0VUDk)4F];Jk*iWF*,DocW:=H_-Yqch=R3#Jf.r0+M`_(V5X+/0\#,Au_RRal'e9!#(!8!BbF^MW$-Oi1k`$P3!>NiV'Mj7DF*nF%%<%oa479jstZ9#OS@`Ho^`Xh[[:Pi![:3C)3Tshii9F._a`X'+qcq!?'g'jE@^Wq"OYiplFE1_`Q0JlJD[kdNZAf0Js7(VjKkP_u,&%Qt*LRGB>3b?8iO;Q!>@X'.bJK(s8,lUp/:1k)\/;DUmLhb=&rdC/qT`QJF*=T>qJ%SeTYgB7$h<)H:eC2B)7F['=t#gOhOJL6Hd=L$'ZuaMiDmlne1jZtO<j#rdV3%79(S!*>J2DW6ltm3"-\m&B%qP]f%crr=%1I08C<r0Y:_ra6Ybrf4Ri^[P"Eq')9*rJ`W5!9lAKD=+ZGhhs7;A8A2OgCMTXJp'jT;i5GjX/)6[D1+p"8u,be7Yci(4q8+X2ak.)o^-&]U\cU#CRCr*Ym)r(=3O&'mdg+2WS<TH#Eh4L!;?0<jm^U8Y6F]a(`$3%i;6-b`rXD*X5KSbmB&#]J'(-c&,Ps[rr>WeW;cj74'QM#!0=l)lu-9'@@DG9Q73Vj\soJu&_mplH("VW\@rm+T`l9*35lT[[_1+l.<g3t;,+M+HC%/"'S!r16#VM3TK)!?\BjfNA,&(ST>BD(r%?hSn:T#E']p@89=,!V%KJIr#oFe:#UCLj+E]Hmg"]`=T098oDXj+N#=).JN"mkiN,aaNVu@"XU)d1Q[]t4ba)to)!TAKCTuZ'rj^2@b'u]o$'4A%(ls+O0nS4ft&uO[Q_j]l=GJ;e"-W2`l]A2a;B:J@BpV.\3+hrRZ22'ML:hJ4Te0RS=6g$\$?rc;fbIIKG389C4UQEtijWp-6p$.&!f-Mg2DuTeb&+M%H^8Lu2d^Q(&J)qrA+8+oKo[bC:U;]6-%HV_;@iOPBdONH8[5o13n;jR#rmdA8!!hKQQ[l4;-0b9F`R*/ko\lXjLkqnd&*NBBPd$(!_dGA.k]8uHTH=a3oIks-rr<RAddABM?^&]gm77i0j@^.?4iod@:6gV3FoMH`;##87!+/WRkkH[ArOBW'gpMY.qR$8&dHOu'G?YZ:Tu<1po$_Q:4lmC5Qa+2fT3K8oVtP%O[>LGj9Zm<nIQL3m&&U;t%fZOf(t=K-)F>b,[5<HnAcsSRStM@o#GN.(^'B%8n?9m%>uL:3)K"TAl$$nVMoAM'7KfKGUuOO@+S>E*rl`(IDr)6/!3fB$!9d-`62pofgn#1UGd?5P?Sh(-N)OrFNO"N'e)%bXUGC*blBr[pX^tBiRWTU>MGDQs#sp-!bBl1\[sa-mUq%.cT$?fCj0+19"6anhmtpB`m[!_E>K729WGjOoTB78)5j=f%5j=Fn81'5V'Y&k+,`3HY(s!pG^2X)PJre"jn99V]1'$^@bX)ub!\on"`-u10LX?&$j9oW#!+)r1!9bW@O"AQGGciO?0GA6T:lQ8328%rs/&&\[$]LRRj4_JPn1PZ.hu3cJVi(-h$q&s4<q#oHnk3W+'#tiOOc$DD,b/BbB9G!23`j&Ib[7X2XgGjMJ&GR%/^^DPk2\rU-nKqPh`*d*Jb`@X(M4Q8%"89\QW@'sM4BcnJt8-9c*OnDl7.s[Bgpb<^5r9o"VpfLH)S]!XEZC"ZaY+qh((u[QgRfa80.5akRDklNd`AN5N2?ek4k(Bl6WgYiCP8@Fn6N"pt2j1NQ&@8EX"NL!(c\,paA"rXM4liY3!,^Q7[C`'SSh`#!$aWgGg)I$KchP+8IYK"TJJRY)iS_Uh77X]L0V_%.c#.0!oUS_pMIm/k$4TeXTQPV"NUDHKbo\LGEc@7oAdQp>+/G-@!PZ_B'He;m'@ge]OX\NuJ?L/V>U)E1o`mai>7C>PP])D1"><>N4Cu"im?P)R\[jm(IaTOi8!o3s.4\0[D]q*Aa4:h>@Jc\$YoRi<ZQ&dPX3+Z#[+B:g'G\@tEF?,bF(\?6/nqg=o@!@/NR*RbB]`/%nKlm!t<Irr<:<m?,F(GcZB1@5+&W5M%,0pt;j#fgaKOaj"B2m3d@br/`j7,d47*m!mrg?Opb]N\*W63kQ$1@S*>\.7t+V\Jb>2g@]rPrWpo#*^@V:X_h90>:$jRaH3luNK'E/Y3%:8!Pumo`Gm!.`MK]Wm+LA)Xt?E2i0)AV*RHO#c.kt&8a(?0%$&P%HLid)1H54FT2$rj3.uAQ!+3a'\aL/Mr];'O``J0Hd_a0>$%"O)bt5s@W4-nlIIHA>o7Lbhl#U1srX([D'Y&:lpj&r4&7QlI8`G_sHBeWnl'#C3_9^k/_4MPAGAZ7GD[L4tIF[\))d-d8,Xu<3+]Gk4ntR3%A%d"lZP6SB?N@_iFElbHharg(0E;-?r`TtqXh6Q?o3O7_dj"elJrs7H/Kms4,>KB$4O^0!\@+VXSkjb,Y%jA[)!/-qb\_`TC=C/PUBs4aN,5NZm3LG0>$fCeOE4B^.rTcV4ceX$m1\E=J@7A!G`iH8]?C0Q!+W7=<A)+-QZC"I>`^b`,k)9R1O]K+dd_^.eSZs\Itmg-NLdE[jOGk')?BR58!/b8aZ(/#E]_m@Ib#:cpV4,&_eV?WFI!eWYXr;d""U@c+KGU\"EB'$9OH[\BpLR?HA(Su(@\];b2!XD&kVp"9mm4OO3[?'-H7^?.Tfq$iuUVlh!YCngtTJam'c;n[-&p">nQ&04T3".)>HS;[ltbZ]JlhTVTre.H`6X()0In^2]^*C"D!)4N/hW0&,uWJItiD.nO9X92.$l/)F;')@=n(/j,t^33!)DP-jd]FJd-M9afK9]pa@Y"l?=rW)rQaQX4b;`>GHXVEXm%l1kn`8_8]ZkDt]dtorS('eb"^k08AlQ\[9F_`m[Q.:G?At43VA]WD3XW-'!8SJBg.S!#(^9Ge>A=*(MQFW@Tm$)(o\]Wj_V&f'`7Y``8OO;SU<M$faasmfn.JnDo$@nSu($Y%9=jg"IQ_B5fVGOoPK),k7#HO:REP!5lji(&n8%hc9[V^ppDBr"MF0D-Oe08thC8DhG%M&\?Gpk?g\oeeV'?Heg:?i\o%i,Y$\7)[^C+DVgc$)"b#<`8`hP2rZrK%g.`M)P.O>\*fMO-TH24gK(c:?dR33P+,%sa3XbcnF>rMrrCG*eN`OU3p?PYrnP6tIO"Wnf>4qB*i#Oe?d>n.bA^?]UlgZP)3j5cM#_K\-^$!Grr@Xi=P8`Cpm4koZ2L?Q_\&MKhln7cF4V9Tig9A]Yd0&E^V`3(.nJ6:od!,+;urOjjpe#FHu<bHACo)ao?K4k_Xog>XtgZDV&RkV;-HSiZhW!ErH;Q2$?]?+2UA3JU5JoRl9'"Yh"Y=;mtmYDmA'/_R.o39AuN1:=i)s?Z$C5HjcAD/=<40"1QH]B<f-]\r-6Z^HX/R-rL1,UM='5'jde!k@1j:lh6Y3bF,lYGoZ\-@\X*Z`/*@X'*!S<GC6`9Gbp^GD>drg<P0p=u8t0k`:<*V/1ZD3KYDIRBf!48MKlVEMh+A%UEH9''N9>18Z7@DcQN[!-)9%"%i*BFEa6]5SD\;2qHlfrPm'TK[,Zbc4nsJJDca$+'NEBSiS=pf**=d/`m1f.5'ua\I@;#8d`ta>LEN@7j^3+-;)^sFk92-&Mmnf9-daqHGL%0fT:WNJ8g1*XYphOC/%oLd&[04"&BeAHiPmj_)8J)Rl)p'D>\K1VRp:g<?ip4qD_o&&VnD9"EX53#$NJ^t2Vcu"%<@qd<\4$RW/BU#'&?gJU\<d:YphXJ\\@L1mMLpJMN+:$Jh5$d1[sJ%B[_7sT]=lF<LUqWjOl.5j8^q-&>[$@bd*E:a.-hMH&&<g(/,Lf@"3/%lq!7G`=RcoVD_19&^6*:#DBUa1jfTWUb@C:dg`3I^"`oW]r<5W<"tq+:iph7CmVP'2D(Rp:_j=`V6JN5gp,k;-oC-[Ur+5BL8@@rRLMo%!@FpUa'pK.`W+_u'9!1oJ&2VdtlWN,SoFfo+!RRsG>WdHZ[9"6k#dh)G^4WUArN:S\pnQk._T9AOi;Wd'YH7D1Y9SX5"Cbc<,\9=a!Q;U\rpDl"c>d2#e>\brR&hqu9%]SOO!7s&me4+jg3\*Z\J69`RbaQ<i,@?lj#sSu[*(FYB=lts+L7"Qe88^*<4Gp/6\)Eqj:6-"c?aT7?eJ)fh\3Xgn[$.u+$Lfl8pq=(7bUhN[CLj]B6bL7D+>P&.S'5h)'i_*I0&;$2I.9=g2<$88rm\a_[E2K$<7.h1#%T#:G:Z(_H$)jo.5:TX?EBs3'o&eQH?S%1U[(kpNt\T.:"qqf_J=^g2Fsfg#)Lkf7#1DGN!trM"LXcAb%.!#p`?QZ:MlT@>o*,KmmIQk8eRepoXEYI!#/*i*4N^[bnEOX(hO2@nA!_QSYjGFaoZM8cd'E8\c5?O0!#rWph>e;oE,6\W#c]X3,<Zq&o\;M=Dl=\ZGL1^CYKnWCo^+J&?bjhBhYMm%aR\$L:Tuo/0P;p$d<AIUXUqcB(FKeU`r<*"i`;?=3R@C4@-!-Be9dPMm8#3`X1spXd"-W3Y(^!KK!J5fnj%&Z-7`P&l2qqLXUtC2f.\j01M%4aBq-3.!KFMro_fXP6Nn)`EuY=mB(peMQt`IIWYSHu!g#G%a&l[d_9&RSqcCI7YP.":G@2gSF_H6P)/=&'V\,1;C9,_]O\\hQu1%ME_UC)>-X^$=i8PgHoM78<G0W`,"s(goMG83:2kmJYJnQ_,r6`?&c]nXHLP&p:")8-180YkrAA"mH,cf1tQg2aa\-QNi(Km&)!.D=c-WuBPs5*A#Wf`&i88elW_-.cbb/NGQYjpmu"c#Us5gmlh=5CXKIc1Pu8bKhW`QL1s@kd&'LIC7Xa#J;S_dn17iDS0[)9#`6Nt$,&r8M>h:O!]!^!]5uW0ddW_tfn*I79*uT<-j4D4T:LEVAjfP?1d]Kq4p?`hum^[O?)_`5I;B$jc)='bei%GuJ!5j9<GgUmpHJ1ZhBb$rIlsNX@A;#R^2M8Z@gRS2ZNbdi..FR.e*A"Z/K2lL+6Fs=kQYfJqjaLP/]Cc\F\Phe^I/EePp]nff/GOqgrr>pca+j%?#bf`nNo@)lg/.nB@:3Ug@6k7`,ie!)9'j</I03aE0C8]=X6I>>dOoI@I-YD\er[8e'j8ng#b[B4ahZg9H37KI7<I/?>W$/^5A8[#ifpnGD%99%pXF)LI,8Lorl8=kpo/PsX'Z-WYMk/'7[KlQq%.:BY40VW-L?8e3Wjm=b@_[m%.XTUO2#,lLAJZCY-n90%/`]-nFPJWdTkG-aV>\RiZn8aPtt\`GI@\Uq?su^=2dtfn)4erY7o+>%:&1EIJ(AtCQhB$8Chqa!6h_nJ8b`DN8l95-G6G+KcB"9(b*j7q9cKSdXK<7CO<@?FL"J@m^6o=9W@oG>4t-krMG#FBcdOhddA[#.5&:ko15$K8tfgM<!"%JgZ9]Cc8kRbpF_7-dB*EhrK]SG!8f!5GJbN,8&4R&l^%D&pH%0./`[DMHBm8[$a;W1ei8bqaQQA063sc2kH/1.gb"H*ES/K8=u!q3^ESXsc;cI;S_KC:GAdE\IumR*i7i"u$M]84f>\mKr$(q7j"%kMp`98u-2s`d*7cgFL-Ve[bT0;+&-m]Lp$H+)f8b4`p^cBAL-HV>DrV:3gHM%,9[BQ\P6Q56->?"^``/lZ*9/ED7npMB.*Zg<cRa;ib+")V[o+YJP47;*V4F-!ddPF'Wu4N,Z/jdZ4skZ)rM?k_:PQ;BZhC5n#1O9/RGjNb<&0H]8;ND3c>q-KduiP7^M5ufhC4*N<RAAbU1ohV\!ebpTX\8k#+:iI!K!@D%E*-/[mOKp79heieYA*"mOiX_@\B^2\AgY9=1+e;QL=56e[*qBmdAcSHmR3ZoH/d9):8%\G)GS._tHo3`5;a(8.f!#d"3e1m7InJrrBB,m2+cC*U'+'DYur$pk%Mb8>`f(Q/a;M^2O-Ee[@NI</)CNj,=oQb)5i_Sem,qKu1]lGu:VrBu4R2eYC<fH98=qg(c)ba][?<aaY**3dc2IjkuVhL";m&^8k^#3MI/1/ZpC9,`<cIFD;WS7EZ?p!W(EWp`JG&SJUYQ@IS'l4@.sf:eaY^:ct]bR7UI"AiCibaN=V+Y=5BI4Z:2]dr%!j>1"rSDW#bW@$G55NIb,2*Phl>`jrDC':p-^>8rXA4C)]drKk89`]TT)`Mfh?^#*Vh.+>M>]<gYKqZ_:;g.+j^j42tu"j';o;6_3@Z7%*X!k=kRIK["PH2DICh@\1`;&6\GP?g-@Q+5e^=A$Li$NS=VBu)ola+<P8hsaEKJ_*tD>f!OeP1^kt>Bhg[.2_\Tn?ZWi8b]C*i7I>+n@RV5V`q`OFM>B%RNiBWeLhV=MDKia![9&<##6u/3$_SC;W'*39]$.WQ=!Do)AQa[;cW!YnUnS+Mb,O5QF>8`a\dH-g=GjT5MA'3*]3C'm7$O1`*+OC05e/o>FS!&HO[SL:jH,S=7[C?-53#@)<VmRYAs)]M^O@/-`VE7$._&b2!OCj7i;S=2F'h,h-)X:l1c6R%t_a[.s!_!C0]1_Vn/X7DnOml-Jrn)rr@\d&AC:+bZ\VPnETK9I_XBbC+XH!M!\eZYuO/J@n'U"pL=>Qnot2M&T3%WIb4QPnG`KDDZ1+%BJt0acf\V>>=tq/85m`VRRBsP=N1m\Oq1KA5/O&.6iJ7c,$B;6b.3L'?rLFEjat-E\WhBfk1stN)>b4f="OrTIr7INps[8%hgl``4rCu_<o6`aNo@)lg//0"[jkXD\thgYESt[o,/*GEJkMXik1UQnaTJOOj!:T*VkUoG#EdBLk.&WWADFFpQWdO46]kU'C@5c.Pah)c-gVH'Ii*D`_0Ys&]>Ji]A'_3U_]A@R(4D$o+^:*136j3K3'8*dg;h#.0_%*@hhJ_7LV,KkHZ*]#ip(l(%#G5Xi-`U9g`'7R>6>4Xi7GY>?;u/2#p'hZOo&:.3&nWh0)963Ssm'*6@G$jI"?q8BVLC]"&P_L-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ii[!U5nkC5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Tg$Z~>endstream
+endobj
+% 'F2': class PDFType1Font
+4 0 obj
+% Font Helvetica-Bold
+<< /BaseFont /Helvetica-Bold
+ /Encoding /WinAnsiEncoding
+ /Name /F2
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER1': class PDFDictionary
+5 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (mailto:compatibility@android.com) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 55
+ 626.125
+ 145.135
+ 637.375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER2': class LinkAnnotation
+6 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 564.9375
+ 117.5275
+ 576.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER3': class LinkAnnotation
+7 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 55
+ 501.8263
+ 0 ]
+ /Rect [ 70
+ 553.6875
+ 114.1825
+ 564.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER4': class LinkAnnotation
+8 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 586.8887
+ 0 ]
+ /Rect [ 70
+ 542.4375
+ 107.935
+ 553.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER5': class LinkAnnotation
+9 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 503.61
+ 0 ]
+ /Rect [ 85
+ 529.1875
+ 190.045
+ 540.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER6': class LinkAnnotation
+10 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 362.485
+ 0 ]
+ /Rect [ 85
+ 517.9375
+ 172.12
+ 529.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER7': class LinkAnnotation
+11 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 286.1775
+ 0 ]
+ /Rect [ 100
+ 504.6875
+ 161.6875
+ 515.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER8': class LinkAnnotation
+12 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 137 0 R
+ /XYZ
+ 55
+ 701.615
+ 0 ]
+ /Rect [ 100
+ 493.4375
+ 178.3675
+ 504.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER9': class LinkAnnotation
+13 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 137 0 R
+ /XYZ
+ 55
+ 701.615
+ 0 ]
+ /Rect [ 100
+ 482.1875
+ 184.6225
+ 493.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER10': class LinkAnnotation
+14 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 137 0 R
+ /XYZ
+ 55
+ 637.615
+ 0 ]
+ /Rect [ 115
+ 468.9375
+ 221.725
+ 480.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER11': class LinkAnnotation
+15 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 137 0 R
+ /XYZ
+ 55
+ 271.615
+ 0 ]
+ /Rect [ 115
+ 457.6875
+ 195.46
+ 468.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER12': class LinkAnnotation
+16 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 137 0 R
+ /XYZ
+ 55
+ 185.115
+ 0 ]
+ /Rect [ 115
+ 446.4375
+ 206.7175
+ 457.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER13': class LinkAnnotation
+17 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 139 0 R
+ /XYZ
+ 55
+ 742.865
+ 0 ]
+ /Rect [ 115
+ 435.1875
+ 200.47
+ 446.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER14': class LinkAnnotation
+18 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 139 0 R
+ /XYZ
+ 55
+ 678.0475
+ 0 ]
+ /Rect [ 85
+ 421.9375
+ 180.0325
+ 433.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER15': class LinkAnnotation
+19 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 139 0 R
+ /XYZ
+ 55
+ 206.1725
+ 0 ]
+ /Rect [ 85
+ 410.6875
+ 160.0225
+ 421.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER16': class LinkAnnotation
+20 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 139 0 R
+ /XYZ
+ 55
+ 118.615
+ 0 ]
+ /Rect [ 100
+ 397.4375
+ 197.53
+ 408.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER17': class LinkAnnotation
+21 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 154 0 R
+ /XYZ
+ 55
+ 390.615
+ 0 ]
+ /Rect [ 100
+ 386.1875
+ 193.36
+ 397.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER18': class LinkAnnotation
+22 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 154 0 R
+ /XYZ
+ 55
+ 171.2975
+ 0 ]
+ /Rect [ 85
+ 372.9375
+ 194.2075
+ 384.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER19': class LinkAnnotation
+23 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 156 0 R
+ /XYZ
+ 55
+ 653.5475
+ 0 ]
+ /Rect [ 85
+ 361.6875
+ 157.5325
+ 372.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER20': class LinkAnnotation
+24 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 156 0 R
+ /XYZ
+ 55
+ 227.9225
+ 0 ]
+ /Rect [ 85
+ 350.4375
+ 196.285
+ 361.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER21': class LinkAnnotation
+25 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 156 0 R
+ /XYZ
+ 55
+ 130.0475
+ 0 ]
+ /Rect [ 85
+ 339.1875
+ 191.7025
+ 350.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER22': class LinkAnnotation
+26 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 165 0 R
+ /XYZ
+ 55
+ 710.865
+ 0 ]
+ /Rect [ 100
+ 325.9375
+ 147.94
+ 337.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER23': class LinkAnnotation
+27 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 165 0 R
+ /XYZ
+ 55
+ 592.365
+ 0 ]
+ /Rect [ 100
+ 314.6875
+ 161.695
+ 325.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER24': class LinkAnnotation
+28 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 165 0 R
+ /XYZ
+ 55
+ 485.115
+ 0 ]
+ /Rect [ 100
+ 303.4375
+ 144.61
+ 314.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER25': class LinkAnnotation
+29 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 165 0 R
+ /XYZ
+ 55
+ 312.115
+ 0 ]
+ /Rect [ 100
+ 292.1875
+ 143.3575
+ 303.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER26': class LinkAnnotation
+30 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 165 0 R
+ /XYZ
+ 55
+ 259.365
+ 0 ]
+ /Rect [ 100
+ 280.9375
+ 174.1975
+ 292.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER27': class LinkAnnotation
+31 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 170 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 267.6875
+ 197.1325
+ 278.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER28': class LinkAnnotation
+32 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 170 0 R
+ /XYZ
+ 55
+ 642.8262
+ 0 ]
+ /Rect [ 70
+ 256.4375
+ 159.6025
+ 267.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER29': class LinkAnnotation
+33 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 170 0 R
+ /XYZ
+ 55
+ 559.5475
+ 0 ]
+ /Rect [ 85
+ 243.1875
+ 147.5275
+ 254.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER30': class LinkAnnotation
+34 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 170 0 R
+ /XYZ
+ 55
+ 407.1725
+ 0 ]
+ /Rect [ 85
+ 231.9375
+ 160.45
+ 243.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER31': class LinkAnnotation
+35 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 171 0 R
+ /XYZ
+ 55
+ 620.5475
+ 0 ]
+ /Rect [ 85
+ 220.6875
+ 160.0375
+ 231.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER32': class LinkAnnotation
+36 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 171 0 R
+ /XYZ
+ 55
+ 297.6035
+ 0 ]
+ /Rect [ 85
+ 209.4375
+ 155.035
+ 220.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER33': class LinkAnnotation
+37 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 176 0 R
+ /XYZ
+ 55
+ 745.7975
+ 0 ]
+ /Rect [ 85
+ 198.1875
+ 147.1225
+ 209.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER34': class LinkAnnotation
+38 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 176 0 R
+ /XYZ
+ 55
+ 302.7638
+ 0 ]
+ /Rect [ 70
+ 184.9375
+ 174.1975
+ 196.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER35': class LinkAnnotation
+39 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 179 0 R
+ /XYZ
+ 55
+ 720.8887
+ 0 ]
+ /Rect [ 70
+ 173.6875
+ 155.8525
+ 184.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER36': class LinkAnnotation
+40 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 179 0 R
+ /XYZ
+ 55
+ 445.36
+ 0 ]
+ /Rect [ 85
+ 160.4375
+ 170.8675
+ 171.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER37': class LinkAnnotation
+41 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 179 0 R
+ /XYZ
+ 55
+ 369.0525
+ 0 ]
+ /Rect [ 100
+ 147.1875
+ 195.0475
+ 158.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER38': class LinkAnnotation
+42 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 722.115
+ 0 ]
+ /Rect [ 100
+ 135.9375
+ 171.685
+ 147.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER39': class LinkAnnotation
+43 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 680.615
+ 0 ]
+ /Rect [ 100
+ 124.6875
+ 205.0525
+ 135.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER40': class LinkAnnotation
+44 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 616.615
+ 0 ]
+ /Rect [ 100
+ 113.4375
+ 183.3775
+ 124.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER41': class LinkAnnotation
+45 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 509.365
+ 0 ]
+ /Rect [ 100
+ 102.1875
+ 201.7075
+ 113.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER42': class LinkAnnotation
+46 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 303.2975
+ 0 ]
+ /Rect [ 85
+ 88.9375
+ 145.03
+ 100.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page1': class PDFPage
+47 0 obj
+% Page dictionary
+<< /Annots [ 5 0 R
+ 6 0 R
+ 7 0 R
+ 8 0 R
+ 9 0 R
+ 10 0 R
+ 11 0 R
+ 12 0 R
+ 13 0 R
+ 14 0 R
+ 15 0 R
+ 16 0 R
+ 17 0 R
+ 18 0 R
+ 19 0 R
+ 20 0 R
+ 21 0 R
+ 22 0 R
+ 23 0 R
+ 24 0 R
+ 25 0 R
+ 26 0 R
+ 27 0 R
+ 28 0 R
+ 29 0 R
+ 30 0 R
+ 31 0 R
+ 32 0 R
+ 33 0 R
+ 34 0 R
+ 35 0 R
+ 36 0 R
+ 37 0 R
+ 38 0 R
+ 39 0 R
+ 40 0 R
+ 41 0 R
+ 42 0 R
+ 43 0 R
+ 44 0 R
+ 45 0 R
+ 46 0 R ]
+ /Contents 303 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ]
+ /XObject << /FormXob.c4c4c9f90f2c427799b277ddd57a9a5b 3 0 R >> >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER43': class LinkAnnotation
+48 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 249.49
+ 0 ]
+ /Rect [ 100
+ 730.6775
+ 152.95
+ 741.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER44': class LinkAnnotation
+49 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 111.74
+ 0 ]
+ /Rect [ 100
+ 719.4275
+ 192.9625
+ 730.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER45': class LinkAnnotation
+50 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 187 0 R
+ /XYZ
+ 55
+ 684.365
+ 0 ]
+ /Rect [ 100
+ 708.1775
+ 173.785
+ 719.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER46': class LinkAnnotation
+51 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 187 0 R
+ /XYZ
+ 55
+ 588.365
+ 0 ]
+ /Rect [ 100
+ 696.9275
+ 182.545
+ 708.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER47': class LinkAnnotation
+52 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 187 0 R
+ /XYZ
+ 55
+ 474.2975
+ 0 ]
+ /Rect [ 85
+ 683.6775
+ 127.105
+ 694.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER48': class LinkAnnotation
+53 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 187 0 R
+ /XYZ
+ 55
+ 232.24
+ 0 ]
+ /Rect [ 100
+ 670.4275
+ 169.195
+ 681.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER49': class LinkAnnotation
+54 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 187 0 R
+ /XYZ
+ 55
+ 116.99
+ 0 ]
+ /Rect [ 100
+ 659.1775
+ 169.2025
+ 670.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER50': class LinkAnnotation
+55 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 669.115
+ 0 ]
+ /Rect [ 100
+ 647.9275
+ 136.69
+ 659.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER51': class LinkAnnotation
+56 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 616.365
+ 0 ]
+ /Rect [ 100
+ 636.6775
+ 157.1125
+ 647.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER52': class LinkAnnotation
+57 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 516.365
+ 0 ]
+ /Rect [ 100
+ 625.4275
+ 155.86
+ 636.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER53': class LinkAnnotation
+58 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 440.865
+ 0 ]
+ /Rect [ 100
+ 614.1775
+ 165.8575
+ 625.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER54': class LinkAnnotation
+59 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 376.865
+ 0 ]
+ /Rect [ 100
+ 602.9275
+ 159.6175
+ 614.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER55': class LinkAnnotation
+60 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 335.365
+ 0 ]
+ /Rect [ 100
+ 591.6775
+ 177.5275
+ 602.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER56': class LinkAnnotation
+61 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 259.2975
+ 0 ]
+ /Rect [ 85
+ 578.4275
+ 158.365
+ 589.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER57': class LinkAnnotation
+62 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 194.24
+ 0 ]
+ /Rect [ 100
+ 565.1775
+ 155.8675
+ 576.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER58': class LinkAnnotation
+63 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 699.615
+ 0 ]
+ /Rect [ 100
+ 553.9275
+ 185.035
+ 565.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER59': class LinkAnnotation
+64 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 646.865
+ 0 ]
+ /Rect [ 100
+ 542.6775
+ 152.5375
+ 553.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER60': class LinkAnnotation
+65 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 539.615
+ 0 ]
+ /Rect [ 100
+ 531.4275
+ 213.7825
+ 542.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER61': class LinkAnnotation
+66 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 398.365
+ 0 ]
+ /Rect [ 100
+ 520.1775
+ 215.86
+ 531.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER62': class LinkAnnotation
+67 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 280.7975
+ 0 ]
+ /Rect [ 85
+ 506.9275
+ 130.015
+ 518.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER63': class LinkAnnotation
+68 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 193.24
+ 0 ]
+ /Rect [ 100
+ 493.6775
+ 190.8625
+ 504.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER64': class LinkAnnotation
+69 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 196 0 R
+ /XYZ
+ 55
+ 710.865
+ 0 ]
+ /Rect [ 100
+ 482.4275
+ 192.115
+ 493.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER65': class LinkAnnotation
+70 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 196 0 R
+ /XYZ
+ 55
+ 475.115
+ 0 ]
+ /Rect [ 100
+ 471.1775
+ 193.375
+ 482.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER66': class LinkAnnotation
+71 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 196 0 R
+ /XYZ
+ 55
+ 223.115
+ 0 ]
+ /Rect [ 100
+ 459.9275
+ 186.2875
+ 471.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER67': class LinkAnnotation
+72 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 196 0 R
+ /XYZ
+ 55
+ 158.2975
+ 0 ]
+ /Rect [ 85
+ 446.6775
+ 169.6225
+ 457.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER68': class LinkAnnotation
+73 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 196 0 R
+ /XYZ
+ 55
+ 93.24
+ 0 ]
+ /Rect [ 100
+ 433.4275
+ 223.375
+ 444.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER69': class LinkAnnotation
+74 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 197 0 R
+ /XYZ
+ 55
+ 592.365
+ 0 ]
+ /Rect [ 100
+ 422.1775
+ 212.1475
+ 433.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER70': class LinkAnnotation
+75 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 197 0 R
+ /XYZ
+ 55
+ 335.5475
+ 0 ]
+ /Rect [ 85
+ 408.9275
+ 115.015
+ 420.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER71': class LinkAnnotation
+76 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 197 0 R
+ /XYZ
+ 55
+ 171.0138
+ 0 ]
+ /Rect [ 70
+ 395.6775
+ 166.2775
+ 406.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER72': class LinkAnnotation
+77 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 202 0 R
+ /XYZ
+ 55
+ 621.6388
+ 0 ]
+ /Rect [ 70
+ 384.4275
+ 172.945
+ 395.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER73': class LinkAnnotation
+78 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 202 0 R
+ /XYZ
+ 55
+ 527.11
+ 0 ]
+ /Rect [ 85
+ 371.1775
+ 140.4325
+ 382.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER74': class LinkAnnotation
+79 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 202 0 R
+ /XYZ
+ 55
+ 449.985
+ 0 ]
+ /Rect [ 85
+ 359.9275
+ 186.295
+ 371.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER75': class LinkAnnotation
+80 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 202 0 R
+ /XYZ
+ 55
+ 372.86
+ 0 ]
+ /Rect [ 85
+ 348.6775
+ 178.3525
+ 359.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER76': class LinkAnnotation
+81 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 202 0 R
+ /XYZ
+ 55
+ 306.985
+ 0 ]
+ /Rect [ 85
+ 337.4275
+ 212.56
+ 348.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER77': class LinkAnnotation
+82 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 205 0 R
+ /XYZ
+ 55
+ 591.1387
+ 0 ]
+ /Rect [ 70
+ 324.1775
+ 183.79
+ 335.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER78': class LinkAnnotation
+83 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 205 0 R
+ /XYZ
+ 55
+ 475.86
+ 0 ]
+ /Rect [ 85
+ 310.9275
+ 182.5375
+ 322.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER79': class LinkAnnotation
+84 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 205 0 R
+ /XYZ
+ 55
+ 300.985
+ 0 ]
+ /Rect [ 85
+ 299.6775
+ 144.6025
+ 310.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER80': class LinkAnnotation
+85 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 205 0 R
+ /XYZ
+ 55
+ 137.36
+ 0 ]
+ /Rect [ 85
+ 288.4275
+ 180.88
+ 299.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER81': class LinkAnnotation
+86 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 208 0 R
+ /XYZ
+ 55
+ 686.8887
+ 0 ]
+ /Rect [ 70
+ 275.1775
+ 148.375
+ 286.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER82': class LinkAnnotation
+87 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 208 0 R
+ /XYZ
+ 55
+ 459.9513
+ 0 ]
+ /Rect [ 70
+ 263.9275
+ 119.605
+ 275.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER83': class LinkAnnotation
+88 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 209 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 252.6775
+ 200.065
+ 263.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page2': class PDFPage
+89 0 obj
+% Page dictionary
+<< /Annots [ 48 0 R
+ 49 0 R
+ 50 0 R
+ 51 0 R
+ 52 0 R
+ 53 0 R
+ 54 0 R
+ 55 0 R
+ 56 0 R
+ 57 0 R
+ 58 0 R
+ 59 0 R
+ 60 0 R
+ 61 0 R
+ 62 0 R
+ 63 0 R
+ 64 0 R
+ 65 0 R
+ 66 0 R
+ 67 0 R
+ 68 0 R
+ 69 0 R
+ 70 0 R
+ 71 0 R
+ 72 0 R
+ 73 0 R
+ 74 0 R
+ 75 0 R
+ 76 0 R
+ 77 0 R
+ 78 0 R
+ 79 0 R
+ 80 0 R
+ 81 0 R
+ 82 0 R
+ 83 0 R
+ 84 0 R
+ 85 0 R
+ 86 0 R
+ 87 0 R
+ 88 0 R ]
+ /Contents 304 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER84': class LinkAnnotation
+90 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 462.615
+ 0 ]
+ /Rect [ 125.8675
+ 663.865
+ 170.05
+ 675.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER85': class LinkAnnotation
+91 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 205 0 R
+ /XYZ
+ 55
+ 591.1387
+ 0 ]
+ /Rect [ 237.16
+ 579.115
+ 272.5975
+ 590.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER86': class LinkAnnotation
+92 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 436.115
+ 0 ]
+ /Rect [ 401.8075
+ 567.865
+ 445.99
+ 579.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER87': class PDFDictionary
+93 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.ietf.org/rfc/rfc2119.txt) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 189.625
+ 450.4275
+ 297.1675
+ 461.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER88': class PDFDictionary
+94 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/compatibility/index.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 205.45
+ 437.1775
+ 369.6775
+ 448.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER89': class PDFDictionary
+95 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 167.965
+ 423.9275
+ 254.6725
+ 435.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER90': class PDFDictionary
+96 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/packages.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 184.2325
+ 410.6775
+ 363.4825
+ 421.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER91': class PDFDictionary
+97 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/Manifest.permission.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 172.9525
+ 397.4275
+ 413.8825
+ 408.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER92': class PDFDictionary
+98 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/os/Build.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 157.96
+ 384.1775
+ 358.885
+ 395.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER93': class PDFDictionary
+99 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/compatibility/2.3/versions.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 186.715
+ 370.9275
+ 373.45
+ 382.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER94': class PDFDictionary
+100 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/webkit/WebView.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 171.7
+ 357.6775
+ 400.96
+ 368.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER95': class PDFDictionary
+101 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.whatwg.org/specs/web-apps/current-work/multipage/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 95.005
+ 344.4275
+ 307.1575
+ 355.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER96': class PDFDictionary
+102 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://dev.w3.org/html5/spec/Overview.html#offline) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 159.955
+ 331.1775
+ 327.52
+ 342.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER97': class PDFDictionary
+103 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://dev.w3.org/html5/spec/Overview.html#video) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 131.2
+ 317.9275
+ 296.68
+ 329.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER98': class PDFDictionary
+104 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.w3.org/TR/geolocation-API/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 172.045
+ 304.6775
+ 300.8425
+ 315.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER99': class PDFDictionary
+105 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.w3.org/TR/webdatabase/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 178.3
+ 291.4275
+ 298.765
+ 302.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER100': class PDFDictionary
+106 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.w3.org/TR/IndexedDB/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 170.7925
+ 278.1775
+ 283.75
+ 289.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER101': class PDFDictionary
+107 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/ui_guidelines/widget_design.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 114.5275
+ 251.6775
+ 374.23
+ 262.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER102': class PDFDictionary
+108 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/ui/notifiers/notifications.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 114.94
+ 238.4275
+ 346.2925
+ 249.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER103': class PDFDictionary
+109 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://code.google.com/android/reference/available-resources.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 148.705
+ 225.1775
+ 368.8
+ 236.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER104': class PDFDictionary
+110 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/ui_guidelines/icon_design.html#statusbarstructure) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 162.8875
+ 211.9275
+ 477.1975
+ 223.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER105': class PDFDictionary
+111 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/app/SearchManager.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 129.535
+ 198.6775
+ 371.7325
+ 209.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER106': class PDFDictionary
+112 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/widget/Toast.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 96.6025
+ 185.4275
+ 313.3675
+ 196.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER107': class PDFDictionary
+113 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/resources/articles/live-wallpapers.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 127.4425
+ 172.1775
+ 351.265
+ 183.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER108': class PDFDictionary
+114 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/developing/tools/index.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 245.845
+ 158.9275
+ 453.865
+ 170.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER109': class PDFDictionary
+115 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/fundamentals.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 164.1325
+ 145.6775
+ 364.645
+ 156.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER110': class PDFDictionary
+116 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/manifest/manifest-intro.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 117.8575
+ 132.4275
+ 349.2025
+ 143.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER111': class PDFDictionary
+117 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/developing/tools/monkey.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 138.7075
+ 119.1775
+ 355.06
+ 130.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER112': class PDFDictionary
+118 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/content/pm/PackageManager.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 179.965
+ 105.9275
+ 452.1775
+ 117.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER113': class PDFDictionary
+119 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/screens_support.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 167.8825
+ 92.6775
+ 389.23
+ 103.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER114': class PDFDictionary
+120 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/util/DisplayMetrics.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 161.6125
+ 79.4275
+ 396.28
+ 90.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page3': class PDFPage
+121 0 obj
+% Page dictionary
+<< /Annots [ 90 0 R
+ 91 0 R
+ 92 0 R
+ 93 0 R
+ 94 0 R
+ 95 0 R
+ 96 0 R
+ 97 0 R
+ 98 0 R
+ 99 0 R
+ 100 0 R
+ 101 0 R
+ 102 0 R
+ 103 0 R
+ 104 0 R
+ 105 0 R
+ 106 0 R
+ 107 0 R
+ 108 0 R
+ 109 0 R
+ 110 0 R
+ 111 0 R
+ 112 0 R
+ 113 0 R
+ 114 0 R
+ 115 0 R
+ 116 0 R
+ 117 0 R
+ 118 0 R
+ 119 0 R
+ 120 0 R ]
+ /Contents 305 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER115': class PDFDictionary
+122 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/content/res/Configuration.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 184.9825
+ 730.6775
+ 443.02
+ 741.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER116': class PDFDictionary
+123 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/hardware/SensorEvent.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 157.0525
+ 717.4275
+ 407.5825
+ 728.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER117': class PDFDictionary
+124 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/bluetooth/package-summary.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 119.9575
+ 704.1775
+ 388.825
+ 715.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER118': class PDFDictionary
+125 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation\(int\)) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 152.0425
+ 690.9275
+ 474.6625
+ 702.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER119': class PDFDictionary
+126 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/hardware/Camera.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 161.2075
+ 677.6775
+ 395.47
+ 688.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER120': class PDFDictionary
+127 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/security/security.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 220.3975
+ 664.4275
+ 429.6475
+ 675.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER121': class PDFDictionary
+128 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://code.google.com/p/apps-for-android) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 129.955
+ 651.1775
+ 269.1925
+ 662.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER122': class LinkAnnotation
+129 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 422.865
+ 0 ]
+ /Rect [ 460.615
+ 435.865
+ 504.7975
+ 447.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER123': class LinkAnnotation
+130 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 409.615
+ 0 ]
+ /Rect [ 470.995
+ 253.24
+ 515.1775
+ 264.49 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'F3': class PDFType1Font
+131 0 obj
+% Font Courier
+<< /BaseFont /Courier
+ /Encoding /WinAnsiEncoding
+ /Name /F3
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER124': class LinkAnnotation
+132 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 396.365
+ 0 ]
+ /Rect [ 336.2725
+ 200.49
+ 380.455
+ 211.74 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'F4': class PDFType1Font
+133 0 obj
+% Font Times-Roman
+<< /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Name /F4
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER125': class LinkAnnotation
+134 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 383.115
+ 0 ]
+ /Rect [ 350.19
+ 124.49
+ 394.3725
+ 135.74 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page4': class PDFPage
+135 0 obj
+% Page dictionary
+<< /Annots [ 122 0 R
+ 123 0 R
+ 124 0 R
+ 125 0 R
+ 126 0 R
+ 127 0 R
+ 128 0 R
+ 129 0 R
+ 130 0 R
+ 132 0 R
+ 134 0 R ]
+ /Contents 306 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page5': class PDFPage
+136 0 obj
+% Page dictionary
+<< /Contents 307 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page6': class PDFPage
+137 0 obj
+% Page dictionary
+<< /Contents 308 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER126': class LinkAnnotation
+138 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 369.865
+ 0 ]
+ /Rect [ 381.61
+ 160.9275
+ 425.7925
+ 172.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page7': class PDFPage
+139 0 obj
+% Page dictionary
+<< /Annots [ 138 0 R ]
+ /Contents 309 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER127': class LinkAnnotation
+140 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 356.615
+ 0 ]
+ /Rect [ 307.5925
+ 532.9275
+ 351.775
+ 544.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER128': class LinkAnnotation
+141 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 343.365
+ 0 ]
+ /Rect [ 183.8125
+ 500.9275
+ 232.165
+ 512.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER129': class LinkAnnotation
+142 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 330.115
+ 0 ]
+ /Rect [ 122.125
+ 487.6775
+ 170.4775
+ 498.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER130': class LinkAnnotation
+143 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 316.865
+ 0 ]
+ /Rect [ 108.775
+ 474.4275
+ 157.1275
+ 485.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER131': class LinkAnnotation
+144 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 303.615
+ 0 ]
+ /Rect [ 343.435
+ 453.6775
+ 391.7875
+ 464.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'F5': class PDFType1Font
+145 0 obj
+% Font Helvetica-Oblique
+<< /BaseFont /Helvetica-Oblique
+ /Encoding /WinAnsiEncoding
+ /Name /F5
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER132': class LinkAnnotation
+146 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 290.365
+ 0 ]
+ /Rect [ 110.4475
+ 442.4275
+ 158.8
+ 453.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER133': class LinkAnnotation
+147 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 356.615
+ 0 ]
+ /Rect [ 160.4575
+ 282.4275
+ 204.64
+ 293.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER134': class LinkAnnotation
+148 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 343.365
+ 0 ]
+ /Rect [ 183.8125
+ 250.4275
+ 232.165
+ 261.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER135': class LinkAnnotation
+149 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 330.115
+ 0 ]
+ /Rect [ 122.125
+ 237.1775
+ 170.4775
+ 248.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER136': class LinkAnnotation
+150 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 316.865
+ 0 ]
+ /Rect [ 108.775
+ 223.9275
+ 157.1275
+ 235.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER137': class LinkAnnotation
+151 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 303.615
+ 0 ]
+ /Rect [ 343.435
+ 203.1775
+ 391.7875
+ 214.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER138': class LinkAnnotation
+152 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 290.365
+ 0 ]
+ /Rect [ 110.4475
+ 191.9275
+ 158.8
+ 203.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER139': class LinkAnnotation
+153 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 436.115
+ 0 ]
+ /Rect [ 125.4475
+ 114.8025
+ 169.63
+ 126.0525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page8': class PDFPage
+154 0 obj
+% Page dictionary
+<< /Annots [ 140 0 R
+ 141 0 R
+ 142 0 R
+ 143 0 R
+ 144 0 R
+ 146 0 R
+ 147 0 R
+ 148 0 R
+ 149 0 R
+ 150 0 R
+ 151 0 R
+ 152 0 R
+ 153 0 R ]
+ /Contents 310 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER140': class LinkAnnotation
+155 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 277.115
+ 0 ]
+ /Rect [ 500.1475
+ 182.6775
+ 548.5
+ 193.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page9': class PDFPage
+156 0 obj
+% Page dictionary
+<< /Annots [ 155 0 R ]
+ /Contents 311 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER141': class LinkAnnotation
+157 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 263.865
+ 0 ]
+ /Rect [ 515.1475
+ 677.9275
+ 553.075
+ 689.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER142': class LinkAnnotation
+158 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 263.865
+ 0 ]
+ /Rect [ 55
+ 666.6775
+ 63.34
+ 677.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER143': class LinkAnnotation
+159 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 250.615
+ 0 ]
+ /Rect [ 313.045
+ 559.4275
+ 361.3975
+ 570.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER144': class LinkAnnotation
+160 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 237.365
+ 0 ]
+ /Rect [ 448.06
+ 527.4275
+ 496.4125
+ 538.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER145': class LinkAnnotation
+161 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 224.115
+ 0 ]
+ /Rect [ 124.615
+ 516.1775
+ 172.9675
+ 527.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER146': class LinkAnnotation
+162 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 210.865
+ 0 ]
+ /Rect [ 132.535
+ 452.1775
+ 180.8875
+ 463.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER147': class LinkAnnotation
+163 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 197.615
+ 0 ]
+ /Rect [ 217.9075
+ 279.1775
+ 266.26
+ 290.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER148': class LinkAnnotation
+164 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 184.365
+ 0 ]
+ /Rect [ 73.7575
+ 215.1775
+ 122.11
+ 226.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page10': class PDFPage
+165 0 obj
+% Page dictionary
+<< /Annots [ 157 0 R
+ 158 0 R
+ 159 0 R
+ 160 0 R
+ 161 0 R
+ 162 0 R
+ 163 0 R
+ 164 0 R ]
+ /Contents 312 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER149': class LinkAnnotation
+166 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 171.115
+ 0 ]
+ /Rect [ 499.5925
+ 695.865
+ 547.945
+ 707.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER150': class LinkAnnotation
+167 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 157.865
+ 0 ]
+ /Rect [ 257.9875
+ 675.115
+ 306.34
+ 686.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER151': class LinkAnnotation
+168 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 144.615
+ 0 ]
+ /Rect [ 373.0375
+ 675.115
+ 421.39
+ 686.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER152': class LinkAnnotation
+169 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 277.115
+ 0 ]
+ /Rect [ 493.5025
+ 675.115
+ 541.855
+ 686.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page11': class PDFPage
+170 0 obj
+% Page dictionary
+<< /Annots [ 166 0 R
+ 167 0 R
+ 168 0 R
+ 169 0 R ]
+ /Contents 313 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page12': class PDFPage
+171 0 obj
+% Page dictionary
+<< /Contents 314 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER153': class LinkAnnotation
+172 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 118.115
+ 0 ]
+ /Rect [ 378.895
+ 323.8025
+ 427.2475
+ 335.0525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER154': class LinkAnnotation
+173 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 171.115
+ 0 ]
+ /Rect [ 207.1
+ 219.365
+ 255.4525
+ 230.615 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER155': class LinkAnnotation
+174 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 171.115
+ 0 ]
+ /Rect [ 239.6275
+ 183.615
+ 287.98
+ 194.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER156': class LinkAnnotation
+175 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 131.365
+ 0 ]
+ /Rect [ 98.3425
+ 147.865
+ 146.695
+ 159.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page13': class PDFPage
+176 0 obj
+% Page dictionary
+<< /Annots [ 172 0 R
+ 173 0 R
+ 174 0 R
+ 175 0 R ]
+ /Contents 315 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER157': class LinkAnnotation
+177 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 118.115
+ 0 ]
+ /Rect [ 392.7925
+ 454.74
+ 441.145
+ 465.99 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER158': class LinkAnnotation
+178 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 104.865
+ 0 ]
+ /Rect [ 258.0025
+ 388.865
+ 306.355
+ 400.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page14': class PDFPage
+179 0 obj
+% Page dictionary
+<< /Annots [ 177 0 R
+ 178 0 R ]
+ /Contents 316 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER159': class LinkAnnotation
+180 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 91.615
+ 0 ]
+ /Rect [ 462.835
+ 689.1775
+ 511.1875
+ 700.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER160': class LinkAnnotation
+181 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 742.865
+ 0 ]
+ /Rect [ 259.42
+ 120.3025
+ 307.7725
+ 131.5525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page15': class PDFPage
+182 0 obj
+% Page dictionary
+<< /Annots [ 180 0 R
+ 181 0 R ]
+ /Contents 317 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER161': class LinkAnnotation
+183 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 742.865
+ 0 ]
+ /Rect [ 381.79
+ 717.4275
+ 430.1425
+ 728.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER162': class LinkAnnotation
+184 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 742.865
+ 0 ]
+ /Rect [ 304.7875
+ 508.1775
+ 353.14
+ 519.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER163': class LinkAnnotation
+185 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 118.115
+ 0 ]
+ /Rect [ 468.19
+ 385.8025
+ 516.5425
+ 397.0525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER164': class LinkAnnotation
+186 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 729.615
+ 0 ]
+ /Rect [ 382.21
+ 165.3025
+ 430.5625
+ 176.5525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page16': class PDFPage
+187 0 obj
+% Page dictionary
+<< /Annots [ 183 0 R
+ 184 0 R
+ 185 0 R
+ 186 0 R ]
+ /Contents 318 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER165': class LinkAnnotation
+188 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 729.615
+ 0 ]
+ /Rect [ 382.21
+ 717.4275
+ 430.5625
+ 728.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page17': class PDFPage
+189 0 obj
+% Page dictionary
+<< /Annots [ 188 0 R ]
+ /Contents 319 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER166': class LinkAnnotation
+190 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 716.365
+ 0 ]
+ /Rect [ 297.6025
+ 602.6775
+ 345.955
+ 613.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER167': class LinkAnnotation
+191 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 118.115
+ 0 ]
+ /Rect [ 68.335
+ 463.4275
+ 116.6875
+ 474.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER168': class LinkAnnotation
+192 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 118.115
+ 0 ]
+ /Rect [ 320.2675
+ 418.1775
+ 368.62
+ 429.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page18': class PDFPage
+193 0 obj
+% Page dictionary
+<< /Annots [ 190 0 R
+ 191 0 R
+ 192 0 R ]
+ /Contents 320 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER169': class LinkAnnotation
+194 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 703.115
+ 0 ]
+ /Rect [ 293.17
+ 545.9275
+ 341.5225
+ 557.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER170': class LinkAnnotation
+195 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 689.865
+ 0 ]
+ /Rect [ 425.56
+ 353.6775
+ 473.9125
+ 364.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page19': class PDFPage
+196 0 obj
+% Page dictionary
+<< /Annots [ 194 0 R
+ 195 0 R ]
+ /Contents 321 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page20': class PDFPage
+197 0 obj
+% Page dictionary
+<< /Contents 322 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER171': class LinkAnnotation
+198 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 676.615
+ 0 ]
+ /Rect [ 164.2225
+ 558.99
+ 212.575
+ 570.24 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER172': class LinkAnnotation
+199 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 676.615
+ 0 ]
+ /Rect [ 465.5875
+ 481.865
+ 513.94
+ 493.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER173': class LinkAnnotation
+200 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 676.615
+ 0 ]
+ /Rect [ 345.55
+ 382.24
+ 393.9025
+ 393.49 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER174': class LinkAnnotation
+201 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 676.615
+ 0 ]
+ /Rect [ 57.085
+ 316.365
+ 105.4375
+ 327.615 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page21': class PDFPage
+202 0 obj
+% Page dictionary
+<< /Annots [ 198 0 R
+ 199 0 R
+ 200 0 R
+ 201 0 R ]
+ /Contents 323 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER175': class LinkAnnotation
+203 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 449.365
+ 0 ]
+ /Rect [ 323.41
+ 430.615
+ 367.5925
+ 441.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER176': class LinkAnnotation
+204 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 449.365
+ 0 ]
+ /Rect [ 315.115
+ 321.615
+ 359.2975
+ 332.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page22': class PDFPage
+205 0 obj
+% Page dictionary
+<< /Annots [ 203 0 R
+ 204 0 R ]
+ /Contents 324 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER177': class LinkAnnotation
+206 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 663.365
+ 0 ]
+ /Rect [ 188.2975
+ 730.6775
+ 236.65
+ 741.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER178': class PDFDictionary
+207 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (mailto:compatibility@android.com) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 193.8325
+ 408.5525
+ 283.9675
+ 419.8025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page23': class PDFPage
+208 0 obj
+% Page dictionary
+<< /Annots [ 206 0 R
+ 207 0 R ]
+ /Contents 325 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page24': class PDFPage
+209 0 obj
+% Page dictionary
+<< /Contents 326 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'R210': class PDFCatalog
+210 0 obj
+% Document Root
+<< /Outlines 212 0 R
+ /PageMode /UseNone
+ /Pages 302 0 R
+ /Type /Catalog >>
+endobj
+% 'R211': class PDFInfo
+211 0 obj
+<< /Author ()
+ /CreationDate (D:20101215173620+08'00')
+ /Keywords ()
+ /Producer (pisa HTML to PDF <http://www.htmltopdf.org>)
+ /Subject ()
+ /Title (Android 2.3 Compatibility Definition) >>
+endobj
+% 'R212': class PDFOutlines
+212 0 obj
+<< /Count 17
+ /First 213 0 R
+ /Last 213 0 R
+ /Type /Outlines >>
+endobj
+% 'Outline.0': class OutlineEntryObject
+213 0 obj
+<< /Count -14
+ /Dest [ 47 0 R
+ /Fit ]
+ /First 214 0 R
+ /Last 296 0 R
+ /Parent 212 0 R
+ /Title (Android 2.3 Compatibility Definition) >>
+endobj
+% 'Outline.2.0': class OutlineEntryObject
+214 0 obj
+<< /Dest [ 47 0 R
+ /Fit ]
+ /Next 215 0 R
+ /Parent 213 0 R
+ /Title (Table of Contents) >>
+endobj
+% 'Outline.2.1': class OutlineEntryObject
+215 0 obj
+<< /Dest [ 121 0 R
+ /Fit ]
+ /Next 216 0 R
+ /Parent 213 0 R
+ /Prev 214 0 R
+ /Title (1. Introduction) >>
+endobj
+% 'Outline.2.2': class OutlineEntryObject
+216 0 obj
+<< /Dest [ 121 0 R
+ /Fit ]
+ /Next 217 0 R
+ /Parent 213 0 R
+ /Prev 215 0 R
+ /Title (2. Resources) >>
+endobj
+% 'Outline.2.3': class OutlineEntryObject
+217 0 obj
+<< /Count -8
+ /Dest [ 135 0 R
+ /Fit ]
+ /First 218 0 R
+ /Last 234 0 R
+ /Next 240 0 R
+ /Parent 213 0 R
+ /Prev 216 0 R
+ /Title (3. Software) >>
+endobj
+% 'Outline.3.0': class OutlineEntryObject
+218 0 obj
+<< /Dest [ 135 0 R
+ /Fit ]
+ /Next 219 0 R
+ /Parent 217 0 R
+ /Title (3.1. Managed API Compatibility) >>
+endobj
+% 'Outline.3.1': class OutlineEntryObject
+219 0 obj
+<< /Count -7
+ /Dest [ 135 0 R
+ /Fit ]
+ /First 220 0 R
+ /Last 226 0 R
+ /Next 227 0 R
+ /Parent 217 0 R
+ /Prev 218 0 R
+ /Title (3.2. Soft API Compatibility) >>
+endobj
+% 'Outline.4.0': class OutlineEntryObject
+220 0 obj
+<< /Dest [ 135 0 R
+ /Fit ]
+ /Next 221 0 R
+ /Parent 219 0 R
+ /Title (3.2.1. Permissions) >>
+endobj
+% 'Outline.4.1': class OutlineEntryObject
+221 0 obj
+<< /Dest [ 135 0 R
+ /Fit ]
+ /Next 222 0 R
+ /Parent 219 0 R
+ /Prev 220 0 R
+ /Title (3.2.2. Build Parameters) >>
+endobj
+% 'Outline.4.2': class OutlineEntryObject
+222 0 obj
+<< /Dest [ 137 0 R
+ /Fit ]
+ /Next 223 0 R
+ /Parent 219 0 R
+ /Prev 221 0 R
+ /Title (3.2.3. Intent Compatibility) >>
+endobj
+% 'Outline.4.3': class OutlineEntryObject
+223 0 obj
+<< /Dest [ 137 0 R
+ /Fit ]
+ /Next 224 0 R
+ /Parent 219 0 R
+ /Prev 222 0 R
+ /Title (3.2.3.1. Core Application Intents) >>
+endobj
+% 'Outline.4.4': class OutlineEntryObject
+224 0 obj
+<< /Dest [ 137 0 R
+ /Fit ]
+ /Next 225 0 R
+ /Parent 219 0 R
+ /Prev 223 0 R
+ /Title (3.2.3.2. Intent Overrides) >>
+endobj
+% 'Outline.4.5': class OutlineEntryObject
+225 0 obj
+<< /Dest [ 137 0 R
+ /Fit ]
+ /Next 226 0 R
+ /Parent 219 0 R
+ /Prev 224 0 R
+ /Title (3.2.3.3. Intent Namespaces) >>
+endobj
+% 'Outline.4.6': class OutlineEntryObject
+226 0 obj
+<< /Dest [ 139 0 R
+ /Fit ]
+ /Parent 219 0 R
+ /Prev 225 0 R
+ /Title (3.2.3.4. Broadcast Intents) >>
+endobj
+% 'Outline.3.2': class OutlineEntryObject
+227 0 obj
+<< /Dest [ 139 0 R
+ /Fit ]
+ /Next 228 0 R
+ /Parent 217 0 R
+ /Prev 219 0 R
+ /Title (3.3. Native API Compatibility) >>
+endobj
+% 'Outline.3.3': class OutlineEntryObject
+228 0 obj
+<< /Count -2
+ /Dest [ 139 0 R
+ /Fit ]
+ /First 229 0 R
+ /Last 230 0 R
+ /Next 231 0 R
+ /Parent 217 0 R
+ /Prev 227 0 R
+ /Title (3.4. Web Compatibility) >>
+endobj
+% 'Outline.5.0': class OutlineEntryObject
+229 0 obj
+<< /Dest [ 139 0 R
+ /Fit ]
+ /Next 230 0 R
+ /Parent 228 0 R
+ /Title (3.4.1. WebView Compatibility) >>
+endobj
+% 'Outline.5.1': class OutlineEntryObject
+230 0 obj
+<< /Dest [ 154 0 R
+ /Fit ]
+ /Parent 228 0 R
+ /Prev 229 0 R
+ /Title (3.4.2. Browser Compatibility) >>
+endobj
+% 'Outline.3.4': class OutlineEntryObject
+231 0 obj
+<< /Dest [ 154 0 R
+ /Fit ]
+ /Next 232 0 R
+ /Parent 217 0 R
+ /Prev 228 0 R
+ /Title (3.5. API Behavioral Compatibility) >>
+endobj
+% 'Outline.3.5': class OutlineEntryObject
+232 0 obj
+<< /Dest [ 156 0 R
+ /Fit ]
+ /Next 233 0 R
+ /Parent 217 0 R
+ /Prev 231 0 R
+ /Title (3.6. API Namespaces) >>
+endobj
+% 'Outline.3.6': class OutlineEntryObject
+233 0 obj
+<< /Dest [ 156 0 R
+ /Fit ]
+ /Next 234 0 R
+ /Parent 217 0 R
+ /Prev 232 0 R
+ /Title (3.7. Virtual Machine Compatibility) >>
+endobj
+% 'Outline.3.7': class OutlineEntryObject
+234 0 obj
+<< /Count -5
+ /Dest [ 156 0 R
+ /Fit ]
+ /First 235 0 R
+ /Last 239 0 R
+ /Parent 217 0 R
+ /Prev 233 0 R
+ /Title (3.8. User Interface Compatibility) >>
+endobj
+% 'Outline.6.0': class OutlineEntryObject
+235 0 obj
+<< /Dest [ 165 0 R
+ /Fit ]
+ /Next 236 0 R
+ /Parent 234 0 R
+ /Title (3.8.1. Widgets) >>
+endobj
+% 'Outline.6.1': class OutlineEntryObject
+236 0 obj
+<< /Dest [ 165 0 R
+ /Fit ]
+ /Next 237 0 R
+ /Parent 234 0 R
+ /Prev 235 0 R
+ /Title (3.8.2. Notifications) >>
+endobj
+% 'Outline.6.2': class OutlineEntryObject
+237 0 obj
+<< /Dest [ 165 0 R
+ /Fit ]
+ /Next 238 0 R
+ /Parent 234 0 R
+ /Prev 236 0 R
+ /Title (3.8.3. Search) >>
+endobj
+% 'Outline.6.3': class OutlineEntryObject
+238 0 obj
+<< /Dest [ 165 0 R
+ /Fit ]
+ /Next 239 0 R
+ /Parent 234 0 R
+ /Prev 237 0 R
+ /Title (3.8.4. Toasts) >>
+endobj
+% 'Outline.6.4': class OutlineEntryObject
+239 0 obj
+<< /Dest [ 165 0 R
+ /Fit ]
+ /Parent 234 0 R
+ /Prev 238 0 R
+ /Title (3.8.5. Live Wallpapers) >>
+endobj
+% 'Outline.2.4': class OutlineEntryObject
+240 0 obj
+<< /Dest [ 170 0 R
+ /Fit ]
+ /Next 241 0 R
+ /Parent 213 0 R
+ /Prev 217 0 R
+ /Title (4. Application Packaging Compatibility) >>
+endobj
+% 'Outline.2.5': class OutlineEntryObject
+241 0 obj
+<< /Count -5
+ /Dest [ 170 0 R
+ /Fit ]
+ /First 242 0 R
+ /Last 246 0 R
+ /Next 247 0 R
+ /Parent 213 0 R
+ /Prev 240 0 R
+ /Title (5. Multimedia Compatibility) >>
+endobj
+% 'Outline.7.0': class OutlineEntryObject
+242 0 obj
+<< /Dest [ 170 0 R
+ /Fit ]
+ /Next 243 0 R
+ /Parent 241 0 R
+ /Title (5.1. Media Codecs) >>
+endobj
+% 'Outline.7.1': class OutlineEntryObject
+243 0 obj
+<< /Dest [ 170 0 R
+ /Fit ]
+ /Next 244 0 R
+ /Parent 241 0 R
+ /Prev 242 0 R
+ /Title (5.1.1. Media Decoders) >>
+endobj
+% 'Outline.7.2': class OutlineEntryObject
+244 0 obj
+<< /Dest [ 171 0 R
+ /Fit ]
+ /Next 245 0 R
+ /Parent 241 0 R
+ /Prev 243 0 R
+ /Title (5.1.2. Media Encoders) >>
+endobj
+% 'Outline.7.3': class OutlineEntryObject
+245 0 obj
+<< /Dest [ 171 0 R
+ /Fit ]
+ /Next 246 0 R
+ /Parent 241 0 R
+ /Prev 244 0 R
+ /Title (5.2. Audio Recording) >>
+endobj
+% 'Outline.7.4': class OutlineEntryObject
+246 0 obj
+<< /Dest [ 176 0 R
+ /Fit ]
+ /Parent 241 0 R
+ /Prev 245 0 R
+ /Title (5.3. Audio Latency) >>
+endobj
+% 'Outline.2.6': class OutlineEntryObject
+247 0 obj
+<< /Dest [ 176 0 R
+ /Fit ]
+ /Next 248 0 R
+ /Parent 213 0 R
+ /Prev 241 0 R
+ /Title (6. Developer Tool Compatibility) >>
+endobj
+% 'Outline.2.7': class OutlineEntryObject
+248 0 obj
+<< /Count -7
+ /Dest [ 179 0 R
+ /Fit ]
+ /First 249 0 R
+ /Last 283 0 R
+ /Next 284 0 R
+ /Parent 213 0 R
+ /Prev 247 0 R
+ /Title (7. Hardware Compatibility) >>
+endobj
+% 'Outline.8.0': class OutlineEntryObject
+249 0 obj
+<< /Count -5
+ /Dest [ 179 0 R
+ /Fit ]
+ /First 250 0 R
+ /Last 254 0 R
+ /Next 255 0 R
+ /Parent 248 0 R
+ /Title (7.1. Display and Graphics) >>
+endobj
+% 'Outline.9.0': class OutlineEntryObject
+250 0 obj
+<< /Dest [ 179 0 R
+ /Fit ]
+ /Next 251 0 R
+ /Parent 249 0 R
+ /Title (7.1.1. Screen Configurations) >>
+endobj
+% 'Outline.9.1': class OutlineEntryObject
+251 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Next 252 0 R
+ /Parent 249 0 R
+ /Prev 250 0 R
+ /Title (7.1.2. Display Metrics) >>
+endobj
+% 'Outline.9.2': class OutlineEntryObject
+252 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Next 253 0 R
+ /Parent 249 0 R
+ /Prev 251 0 R
+ /Title (7.1.3. Declared Screen Support) >>
+endobj
+% 'Outline.9.3': class OutlineEntryObject
+253 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Next 254 0 R
+ /Parent 249 0 R
+ /Prev 252 0 R
+ /Title (7.1.4. Screen Orientation) >>
+endobj
+% 'Outline.9.4': class OutlineEntryObject
+254 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Parent 249 0 R
+ /Prev 253 0 R
+ /Title (7.1.5. 3D Graphics Acceleration) >>
+endobj
+% 'Outline.8.1': class OutlineEntryObject
+255 0 obj
+<< /Count -4
+ /Dest [ 182 0 R
+ /Fit ]
+ /First 256 0 R
+ /Last 259 0 R
+ /Next 260 0 R
+ /Parent 248 0 R
+ /Prev 249 0 R
+ /Title (7.2. Input Devices) >>
+endobj
+% 'Outline.10.0': class OutlineEntryObject
+256 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Next 257 0 R
+ /Parent 255 0 R
+ /Title (7.2.1. Keyboard) >>
+endobj
+% 'Outline.10.1': class OutlineEntryObject
+257 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Next 258 0 R
+ /Parent 255 0 R
+ /Prev 256 0 R
+ /Title (7.2.2. Non-touch Navigation) >>
+endobj
+% 'Outline.10.2': class OutlineEntryObject
+258 0 obj
+<< /Dest [ 187 0 R
+ /Fit ]
+ /Next 259 0 R
+ /Parent 255 0 R
+ /Prev 257 0 R
+ /Title (7.2.3. Navigation keys) >>
+endobj
+% 'Outline.10.3': class OutlineEntryObject
+259 0 obj
+<< /Dest [ 187 0 R
+ /Fit ]
+ /Parent 255 0 R
+ /Prev 258 0 R
+ /Title (7.2.4. Touchscreen input) >>
+endobj
+% 'Outline.8.2': class OutlineEntryObject
+260 0 obj
+<< /Count -8
+ /Dest [ 187 0 R
+ /Fit ]
+ /First 261 0 R
+ /Last 268 0 R
+ /Next 269 0 R
+ /Parent 248 0 R
+ /Prev 255 0 R
+ /Title (7.3. Sensors) >>
+endobj
+% 'Outline.11.0': class OutlineEntryObject
+261 0 obj
+<< /Dest [ 187 0 R
+ /Fit ]
+ /Next 262 0 R
+ /Parent 260 0 R
+ /Title (7.3.1. Accelerometer) >>
+endobj
+% 'Outline.11.1': class OutlineEntryObject
+262 0 obj
+<< /Dest [ 187 0 R
+ /Fit ]
+ /Next 263 0 R
+ /Parent 260 0 R
+ /Prev 261 0 R
+ /Title (7.3.2. Magnetometer) >>
+endobj
+% 'Outline.11.2': class OutlineEntryObject
+263 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 264 0 R
+ /Parent 260 0 R
+ /Prev 262 0 R
+ /Title (7.3.3. GPS) >>
+endobj
+% 'Outline.11.3': class OutlineEntryObject
+264 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 265 0 R
+ /Parent 260 0 R
+ /Prev 263 0 R
+ /Title (7.3.4. Gyroscope) >>
+endobj
+% 'Outline.11.4': class OutlineEntryObject
+265 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 266 0 R
+ /Parent 260 0 R
+ /Prev 264 0 R
+ /Title (7.3.5. Barometer) >>
+endobj
+% 'Outline.11.5': class OutlineEntryObject
+266 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 267 0 R
+ /Parent 260 0 R
+ /Prev 265 0 R
+ /Title (7.3.7. Thermometer) >>
+endobj
+% 'Outline.11.6': class OutlineEntryObject
+267 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 268 0 R
+ /Parent 260 0 R
+ /Prev 266 0 R
+ /Title (7.3.7. Photometer) >>
+endobj
+% 'Outline.11.7': class OutlineEntryObject
+268 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Parent 260 0 R
+ /Prev 267 0 R
+ /Title (7.3.8. Proximity Sensor) >>
+endobj
+% 'Outline.8.3': class OutlineEntryObject
+269 0 obj
+<< /Count -5
+ /Dest [ 189 0 R
+ /Fit ]
+ /First 270 0 R
+ /Last 274 0 R
+ /Next 275 0 R
+ /Parent 248 0 R
+ /Prev 260 0 R
+ /Title (7.4. Data Connectivity) >>
+endobj
+% 'Outline.12.0': class OutlineEntryObject
+270 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 271 0 R
+ /Parent 269 0 R
+ /Title (7.4.1. Telephony) >>
+endobj
+% 'Outline.12.1': class OutlineEntryObject
+271 0 obj
+<< /Dest [ 193 0 R
+ /Fit ]
+ /Next 272 0 R
+ /Parent 269 0 R
+ /Prev 270 0 R
+ /Title (7.4.2. IEEE 802.11 \(WiFi\)) >>
+endobj
+% 'Outline.12.2': class OutlineEntryObject
+272 0 obj
+<< /Dest [ 193 0 R
+ /Fit ]
+ /Next 273 0 R
+ /Parent 269 0 R
+ /Prev 271 0 R
+ /Title (7.4.3. Bluetooth) >>
+endobj
+% 'Outline.12.3': class OutlineEntryObject
+273 0 obj
+<< /Dest [ 193 0 R
+ /Fit ]
+ /Next 274 0 R
+ /Parent 269 0 R
+ /Prev 272 0 R
+ /Title (7.4.4. Near-Field Communications) >>
+endobj
+% 'Outline.12.4': class OutlineEntryObject
+274 0 obj
+<< /Dest [ 193 0 R
+ /Fit ]
+ /Parent 269 0 R
+ /Prev 273 0 R
+ /Title (7.4.5. Minimum Network Capability) >>
+endobj
+% 'Outline.8.4': class OutlineEntryObject
+275 0 obj
+<< /Count -4
+ /Dest [ 193 0 R
+ /Fit ]
+ /First 276 0 R
+ /Last 279 0 R
+ /Next 280 0 R
+ /Parent 248 0 R
+ /Prev 269 0 R
+ /Title (7.5. Cameras) >>
+endobj
+% 'Outline.13.0': class OutlineEntryObject
+276 0 obj
+<< /Dest [ 193 0 R
+ /Fit ]
+ /Next 277 0 R
+ /Parent 275 0 R
+ /Title (7.5.1. Rear-Facing Camera) >>
+endobj
+% 'Outline.13.1': class OutlineEntryObject
+277 0 obj
+<< /Dest [ 196 0 R
+ /Fit ]
+ /Next 278 0 R
+ /Parent 275 0 R
+ /Prev 276 0 R
+ /Title (7.5.2. Front-Facing Camera) >>
+endobj
+% 'Outline.13.2': class OutlineEntryObject
+278 0 obj
+<< /Dest [ 196 0 R
+ /Fit ]
+ /Next 279 0 R
+ /Parent 275 0 R
+ /Prev 277 0 R
+ /Title (7.5.3. Camera API Behavior) >>
+endobj
+% 'Outline.13.3': class OutlineEntryObject
+279 0 obj
+<< /Dest [ 196 0 R
+ /Fit ]
+ /Parent 275 0 R
+ /Prev 278 0 R
+ /Title (7.5.4. Camera Orientation) >>
+endobj
+% 'Outline.8.5': class OutlineEntryObject
+280 0 obj
+<< /Count -2
+ /Dest [ 196 0 R
+ /Fit ]
+ /First 281 0 R
+ /Last 282 0 R
+ /Next 283 0 R
+ /Parent 248 0 R
+ /Prev 275 0 R
+ /Title (7.6. Memory and Storage) >>
+endobj
+% 'Outline.14.0': class OutlineEntryObject
+281 0 obj
+<< /Dest [ 196 0 R
+ /Fit ]
+ /Next 282 0 R
+ /Parent 280 0 R
+ /Title (7.6.1. Minimum Memory and Storage) >>
+endobj
+% 'Outline.14.1': class OutlineEntryObject
+282 0 obj
+<< /Dest [ 197 0 R
+ /Fit ]
+ /Parent 280 0 R
+ /Prev 281 0 R
+ /Title (7.6.2. Application Shared Storage) >>
+endobj
+% 'Outline.8.6': class OutlineEntryObject
+283 0 obj
+<< /Dest [ 197 0 R
+ /Fit ]
+ /Parent 248 0 R
+ /Prev 280 0 R
+ /Title (7.7. USB) >>
+endobj
+% 'Outline.2.8': class OutlineEntryObject
+284 0 obj
+<< /Dest [ 197 0 R
+ /Fit ]
+ /Next 285 0 R
+ /Parent 213 0 R
+ /Prev 248 0 R
+ /Title (8. Performance Compatibility) >>
+endobj
+% 'Outline.2.9': class OutlineEntryObject
+285 0 obj
+<< /Count -4
+ /Dest [ 202 0 R
+ /Fit ]
+ /First 286 0 R
+ /Last 289 0 R
+ /Next 290 0 R
+ /Parent 213 0 R
+ /Prev 284 0 R
+ /Title (9. Security Model Compatibility) >>
+endobj
+% 'Outline.15.0': class OutlineEntryObject
+286 0 obj
+<< /Dest [ 202 0 R
+ /Fit ]
+ /Next 287 0 R
+ /Parent 285 0 R
+ /Title (9.1. Permissions) >>
+endobj
+% 'Outline.15.1': class OutlineEntryObject
+287 0 obj
+<< /Dest [ 202 0 R
+ /Fit ]
+ /Next 288 0 R
+ /Parent 285 0 R
+ /Prev 286 0 R
+ /Title (9.2. UID and Process Isolation) >>
+endobj
+% 'Outline.15.2': class OutlineEntryObject
+288 0 obj
+<< /Dest [ 202 0 R
+ /Fit ]
+ /Next 289 0 R
+ /Parent 285 0 R
+ /Prev 287 0 R
+ /Title (9.3. Filesystem Permissions) >>
+endobj
+% 'Outline.15.3': class OutlineEntryObject
+289 0 obj
+<< /Dest [ 202 0 R
+ /Fit ]
+ /Parent 285 0 R
+ /Prev 288 0 R
+ /Title (9.4. Alternate Execution Environments) >>
+endobj
+% 'Outline.2.10': class OutlineEntryObject
+290 0 obj
+<< /Count -3
+ /Dest [ 205 0 R
+ /Fit ]
+ /First 291 0 R
+ /Last 293 0 R
+ /Next 294 0 R
+ /Parent 213 0 R
+ /Prev 285 0 R
+ /Title (10. Software Compatibility Testing) >>
+endobj
+% 'Outline.16.0': class OutlineEntryObject
+291 0 obj
+<< /Dest [ 205 0 R
+ /Fit ]
+ /Next 292 0 R
+ /Parent 290 0 R
+ /Title (10.1. Compatibility Test Suite) >>
+endobj
+% 'Outline.16.1': class OutlineEntryObject
+292 0 obj
+<< /Dest [ 205 0 R
+ /Fit ]
+ /Next 293 0 R
+ /Parent 290 0 R
+ /Prev 291 0 R
+ /Title (10.2. CTS Verifier) >>
+endobj
+% 'Outline.16.2': class OutlineEntryObject
+293 0 obj
+<< /Dest [ 205 0 R
+ /Fit ]
+ /Parent 290 0 R
+ /Prev 292 0 R
+ /Title (10.3. Reference Applications) >>
+endobj
+% 'Outline.2.11': class OutlineEntryObject
+294 0 obj
+<< /Dest [ 208 0 R
+ /Fit ]
+ /Next 295 0 R
+ /Parent 213 0 R
+ /Prev 290 0 R
+ /Title (11. Updatable Software) >>
+endobj
+% 'Outline.2.12': class OutlineEntryObject
+295 0 obj
+<< /Dest [ 208 0 R
+ /Fit ]
+ /Next 296 0 R
+ /Parent 213 0 R
+ /Prev 294 0 R
+ /Title (12. Contact Us) >>
+endobj
+% 'Outline.2.13': class OutlineEntryObject
+296 0 obj
+<< /Count -5
+ /Dest [ 209 0 R
+ /Fit ]
+ /First 297 0 R
+ /Last 301 0 R
+ /Parent 213 0 R
+ /Prev 295 0 R
+ /Title (Appendix A - Bluetooth Test Procedure) >>
+endobj
+% 'Outline.17.0': class OutlineEntryObject
+297 0 obj
+<< /Dest [ 209 0 R
+ /Fit ]
+ /Next 298 0 R
+ /Parent 296 0 R
+ /Title (Setup and Installation) >>
+endobj
+% 'Outline.17.1': class OutlineEntryObject
+298 0 obj
+<< /Dest [ 209 0 R
+ /Fit ]
+ /Next 299 0 R
+ /Parent 296 0 R
+ /Prev 297 0 R
+ /Title (Test Bluetooth Control by Apps) >>
+endobj
+% 'Outline.17.2': class OutlineEntryObject
+299 0 obj
+<< /Dest [ 209 0 R
+ /Fit ]
+ /Next 300 0 R
+ /Parent 296 0 R
+ /Prev 298 0 R
+ /Title (Test Pairing and Communication) >>
+endobj
+% 'Outline.17.3': class OutlineEntryObject
+300 0 obj
+<< /Dest [ 209 0 R
+ /Fit ]
+ /Next 301 0 R
+ /Parent 296 0 R
+ /Prev 299 0 R
+ /Title (Test Pairing and Communication in the Reverse Direction) >>
+endobj
+% 'Outline.17.4': class OutlineEntryObject
+301 0 obj
+<< /Dest [ 209 0 R
+ /Fit ]
+ /Parent 296 0 R
+ /Prev 300 0 R
+ /Title (Test Re-Launches) >>
+endobj
+% 'R302': class PDFPages
+302 0 obj
+% page tree
+<< /Count 24
+ /Kids [ 47 0 R
+ 89 0 R
+ 121 0 R
+ 135 0 R
+ 136 0 R
+ 137 0 R
+ 139 0 R
+ 154 0 R
+ 156 0 R
+ 165 0 R
+ 170 0 R
+ 171 0 R
+ 176 0 R
+ 179 0 R
+ 182 0 R
+ 187 0 R
+ 189 0 R
+ 193 0 R
+ 196 0 R
+ 197 0 R
+ 202 0 R
+ 205 0 R
+ 208 0 R
+ 209 0 R ]
+ /Type /Pages >>
+endobj
+% 'R303': class PDFStream
+303 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 1782 >>
+stream
+Gatm=9lo&I&A<G1rrL0KdieGHa/sNTUm[&[-WZEPH@\XY7SAjN7+mcRT*6[c,V,!2m#acT+gD/nhqPUJL`umBgAGPUK[+5oofJ$Z6aJeI!Xgj^Lu-EP:VJbp\fEC,@LU9iCjPh)H:<&PE(i6&&j;bV^g$&PU)58?7'e26'Z4F*^RHstdS3<%O'SDckc\[n0:Mjjbl50KIc"FY*\Jd3;bY[1otZp5O^#2>`j]"X'?OFifC(3$r4BPZR=J'o:W],<K#M_uhSO3&k;$);P.0YLC=[@J6]S!i-b.6-9NrV5;pY$;^SuSB]R86ME5:Rd^G<dUKYJ3/&fk'pjZ)C?EIct*r!^t=oZt\8<[NUkE:g#2Y#K7U9k!</kX*TiBkgS3,6/0RbK(qiSQL%fgMpTWT:V9d'k&7!Gg-ktn3Sc%2[XX_F;"@64]qET>5b[;EEAobR&#NM8q';!X(kLFoV'J_3\(Qe$s4aTf@o*I*&im>ceI..Ha7OJr_RJ(0\gNbmcX0KQV8[eaTT&2'+q)@#FAj7n[S6339$[=K:',Qm(,D[\):pW#E6i0QhB&O;[EaUW@+EG(]bA;i,f?;"<:rlk>h]HEDmdnZdoggJ0q@=CVo_+4d+cGKKV#T'?nKcWeI!Q?qG49I$<qRU'LDP:km@6]rj7Oe*F8Y*2B!<?9]j=6b!4$+<dt.dZ#h((FI!T[_/)tPWHoJ)I)WnR_(gMF>$Xn(-4ruf,siM1`f!7#1:J-18Fu)R7.-"'g8Em'"-uf7<R"Q3b9<+(jk6c\m2-A<.M76C`!(eGB!d[Y-hQ(oc!Th6"K+s38^)I8(Yn`V674s1uV/$JJLBj3,h"d\;27n0\ZaqK#.qKp:&%N&#NXV_+$hALe%CHPSD0f(\+GjJO3fX+2utp7rdUVJIW/Tr(U`[3a8]nP:<DN>D,,CA:$-th.pe#4sb['k`GpJ5aq@<9hM:h'#6A/WB=,FqY1,i=[N=P6Wc-@:^.9LIEPPr64'$>V<jC6'S:T6T\\q3C+.$lS%a;o(@m+]b@`c*!]gK+,(McVFW6N/s&]Vp$kSZ,7R'!ePcQ%k"#Q+c%k-UL!Te`4j.MDXp=(tVf/;R'@%OcBO;OWS/.'H,[q?rGH/UDn&iU,:Y4'lRWN7S@!bg(%qoVird8siD%8:fAZ9)"MVbECaoTpe_dkj.Afq(n]kd\OA7*$,l9`&*4o[2[g`^EFB\`\:4e<>4W2Ca9$L5,=s$-7W*CSBtcE+).%?qW4oWptnBdh%]roMkc_S8);/[@(sVmc8W%GL4KEG>eT0gLh8NaiQJ.Q@*e^j-qNUQ!,3phkoWb8ap&+:]dS>8aYp?-ku>f9KK,%)1^@^>G5htrMLF.>kk3R"SHe6e7P\$URn%#1hFMrTV'HQ:>@@j#GhPA((jY>>aON`.2im56GPLTOFXBRU;-9DBA%*![lEM2)bh_>GX)*mB4*F-+*%R%BCNA%0nA4qS(q!,$bYBZ^ru9<HoM&"JrVi!,%)+?Fj,L1hT9S)H4ugiQUu*Dm2,V*(DV`HLh-13^&Z=RT??<akiV\D/Oc%=%SgLZn9CaNEKB_dST@'P$aX.Sl3C3uNo"!J\hf*Y5NuDkI\P7f/@W5<_H4#I*=-ec0gQfcKkf3:B+T0H"%>6\lU$9jIUAr[M-D.7afO'i48YS<`Pt[I(icTH3u2)dg)_M)hh&J!apQ4IHoL03B!nXT4_6)9C]%]Pm,upK+fdDNlH1dRlpPJh<bQiuEg!C.%mEbUrEDS_Mkja%S?gku:85tKD8u[<d-8YJM37pn~>endstream
+endobj
+% 'R304': class PDFStream
+304 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 1512 >>
+stream
+Gatm<>uTK=&:J2Gs0.ROSO'Y/b9)d1"2in%V+nIJl&0NadB.8^Z301Fhj&c2VSQ::6XUaB2tHC.ZY)32!rSbZhn0(OR_bm8$C&Bn#&$OoR/I,Ng&Bj3p-kUt70nj7=J/IYSAG;T4sP'_.2-[8^PAFR2]'FYM$2$pTTnBhq"aX'QjA%Md/KD:pqT)1lp$m9e_^;5IJnKkkNg<HM,NX6.$&:q45Jep+;>@kKEVYd;F2:cZu]'ZFNBRjB`7-c3I4/rF#N#N@smaeQR3tQ3_(Et&IG(JAXKdK8aG##Zji%YL^p;N[],8n,F$"$Edb&G1N*rA.>09=hin__d+(FW=8;nMZ9*2u2+gq[DObg-iMTr4@iceERD#EANKb0VC:S).pXt+Y(Z:*ZGGo]Vc%Ad*A'@g>HFgWhYb*/X9MB"tCU55fUX=lcpdKgc5ZbAp?:\b`3>qp)bdVge<u/$cfbeDU#4Djb1>O"13"!6NH[tq$<h$E-h[Zu,&7B4bW(kZ<`.$2G6DRuTa)+9KM[.@p7'>V5QJ@7@/dlB8.2uuUM8q3cca2@u2K%Z5kL7W=Qkcq&FDZ,jl_PT-'a0OPa+oYY9.Zkfh5k)fQOE0t=G"O^5H%I;lR0jO0G[m5S(eG_0[J/DoH10QkH)e`=BCd3)g-qpq8?kAJ7g7p1#&uip1#uk8AMo<)s(CF:M'tbg<>K.;;6s4GV,;0)3NN,AG'u:WuVB1gENQA-Be`]D'O`V+24chp#G)")fkhS=CET(c!nm4EHNE\F)[ja0h6>Njf24(X7miB+'Q[VX%JYX&jN/%fB+G#B?TXF'qX=lHmZ_EiX6CGpL,%2GFXrHA3PkmipU*,>KR+5/+]?N.J70X:C-]Y5`R9fL*b2p^(lq`hcai.\Z0P>W\FoS@6&C<FOg;W(On%q*+#5QO^-ho]1Y-[?K&oiMc$cp?C@e5d=N*^qm:-O]SNie5sHjk\Lb-k6WVH?g1Z]+mMGuE6_fdQi,h7&H%T!;'>e0Sd^1<Y;d/Cnl+&(<mu60e>V:r4"q/mKB&oGe)t:>2#0#uC3[W-d=48CT0R0+49j@8/?B3>J]7P_05_:WQ^g^'p0k0<ABl::,ZRV;B;3tDOf/.L5QeDU!?Ptr6T'Np<`a$QjMXB'&WH;)FQd(W(M@dAm6jPT63f4K[G&,3=F;D%>>/(LjiPk-CRZ5TiK2P?c/7tmHH>FWp/[qq/5.B>J(Q_nQ24W4.)#^$P[Gl8%$<aRu7[EHYUA>iF\.M_D,@U.ni+\\'Uq0JQJ0jKCcfDrWin(F3KYj1ukn'I,]*^1^0\&,,4a+t3,B/UE)cV'C(g5k3h0%]$ra[&6j#]h('_oM6iDc0Q_&N,!m[.1rp[:+rkt3gc;MLd!p>ag?rfot/W8XiuXgt"`DPWE'-$C!L#G<W,r.ZNOh^(:&Y$GCI+rmoj09li`3uRfW!0*ObLR#JTcEek00'%a0K2o,j_mqbM)n6gQ/6Eusc.)n9_SLDXI"XuDg#f>@=7%CUm-jl`Ut%jt~>endstream
+endobj
+% 'R305': class PDFStream
+305 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3315 >>
+stream
+GauHOgN)%.&q*PUrW2,+fZ]WjhJ[\_A\=5,GU?p9`t(79.>WX&N(JU%5V(]phZcVKU1.?V`@NMoM]s+U3K;MD!:1gIIN7s/=s3HdJuhTM3A-cEOQ0gm9g5=Z-Egd)1EWNC4ReL!i[B>$HM8G%iN2J+aS$T45g.c_^oGj@']D"[d%ipeKAgUMY?Qs)TUW=5O-l\$hTom+2k'Zn[/PjVHs9nSZ/(hh$*e42RJoHeT'_<T%io[qm"SiroI7Ub*4<J#OlKke[F[,<UJI^!4KDE"Gkk#lqgAn5"=N&a@Q%@CM)([R"YCI`-2\NH;2NeS,!iuo9Mk\Q^-NG_C8oREU4Ol59#O.f"e'F^$9i#]7Fd!VqIQfO8pO8G`MRU(aj^C*.l5"EL0X*(i>;^F4rA*@2U>\/lh.:k75hp^7RHGHROen@JF3#h*8PFPS7$SR#_Ec@Os3(WB,[AJoB%t]\[cTDbk/;JO?Dta<_pd?YOcRY[=/c#"Rrb[jaoUb+];q9N*"_m8:H;D]F#M&A:=;cEf$TD#DgH%n@m$.N0Q6KA6iPkE#g;ls"Rk=_peduVNTOTV=GTdh,hkRrjrD2DK$^o#GM,lC=(58e><VG,D+2rHI#KH=Ae2"H)Wb*=%-c8)t4Kfi(:*M(d<"=ZMtMr/-5o1k7oN1nB:t'>S9=Sa_+4Q+Na6/4=BF"KSMUq2a&.oqlqBcqGptWH`WWUcSR!EWa@S%c:a7DA+DBhB7;9I8-9FqN!PrK8+D`*lJFN6O;Q?3+&o0O<,)Kdb^X:F?o_-rkbIiqVTkWTXKXJ)lcbGn5'3A?_*Z:5`O4Q6kaiB"Ba/u<;n<4HG0n>10R,N6aba<iKI?nN>"s#X^b^Pbm[fQ;-f4Uq&BD3p22J;VA&1fSS0[D^g[FTPfafG2p4gMLgBA_P:<AM'mI6RdcDMi$./eZi"e.DTDMcdN25(XCp6HugM'=+mR&OCcft?H)-l97`l-t`hkW**e25.fm.d`4tIt1/W]0@c5k:I7WBIR`%NaL&#`d?ro-C+;#/XOH?dYnbV'pO6ES==+kcMi/Z96=ZC(4?emD]%8N1@/l$YTD#Q6i5,a=teFBT^-c4DX/1ln!Y;;gC4Rt@sciNJm)Y,3@X.e",o?r:67K'd4q.^bp?r\LFESflFtJN[$jYg7d1&Mi_l5UcLpP"?16)($JM/K3((q=!Se(fE)0S2o^alTMd;EQFM#mkL?(cj%ceOS*iGf%Mh_Z/To,ZX=<FmS$!QF9Kn1*#8.L8(Ts&63fH-/%Y7_!9:.$;YTO^a!:][2@LBn;$I,GU'?8;fP;]W@+X*Ue`Z!sS#"c%jg2OgtYc=&,n3Y1%SiubSmhNm'%]lI/C-5P[6JTU"7H)^%1RgF1ep;_N?2H;I6K+ArNkr8Kk3mm<Ne4cu5n]`@1opF$IU-b?f0Vq)JR)U-uc1%.$)g$3A"c)UM61#[0$iODn/7f1XJL#9YZ4'9r54h5=E&%'/ReOH1T.6[]1$U+PnG`5II^XH]BCHj,S*3%Y]m0)UW&RJKFH<#N5+[fYBA:L`?!kXIkinVI;>u-#Kh4d9.Hg@bKVQjSLQQMa"b34Fp"$F7b9^b"bqS3gQC+NFT/M8NG;U@QcZF"4T\\Eh#<(MNJ[5SMEYt>SkLK4mcWX/h\KD(PrLSmn7[Hoeh0:V#D1I/iC\@><@ShK#`sYo._pN\f;5!Z,6P#AA$%#ZZ!`M1$:Q55sZ"afbLBD>h3u1XfL9830>;lR3m0SS]a4QGK#4@gR)_#;25uo/FKTN)S?56&+LN8_==VXNs+I:4L]\6#KOgI1ei7ARj#CYrk(rrPl^3/cq<"ob(*K>ORi1[ZiGHEBoZY,A"i2X,t-P]K@QFr!b\ZiK]oO`XZ9Upop'p;h]pGL.#e$6]bAM!6UI5h`)d=D/6_3*3-X79ep4imhGYm7*mcBij2!3.?O%\j/;bthq*4$tLMZs$]2C/EiI'`d4o+r'$M'7N0uS-UK^q^%fi0njQ1oM8"e:msc5FfaU^2QbQmScj<.83nBOM8*t=g[=1l!T`^cWUe2=-WcpmkHa_+P^U`cajXfi;lP>]+B9_iZk`YP\l`umB,+81Z3oUYn2pr]MQug0Ym1QI&&G[ZFQDGs*=B-.F\QGB8N$]k`+QEHPn^'j,"=7'IEpsEdPDSN2\$6.egfiAY5M:7D[$-Z7X'"hiOIpPYe+/"6L=D\<<l.g(S]iZAX"E.k/ZCtN#[M^S&Ag9]JH4.Kj<+#qs+@cNr@q9k'lMu\)%?HV`a.e64nf1i)pq4GaM`?)_YL49@dP0a2(kN1^!#Ef7X!2'6t*YiCa4_)P.O0beigVi&=t'&9JK5YloPAAa9IY9);1jY*kG+L\iI4bX/Xsmt[[p]lG7X5r&r.O-d1#5jor>n(A`XP6k6Q**n\KT`_4Dibk1[mD]oofe?ZL0Pp)CS0Ob)B$=Bq:ZZ#8Jh2p.gUkYW+Ft4QlBb"e_<0fBr3!&;=Z30mcbt3;6\)OEq^p6rfiN5f-S(9O)O"Ma.bVJL3j9\RSi`7,n#fcDP/Q5lPluV3?6G:-`moC-jUbH,Y?7eRYtAL5MUhF#20oBMg'^EFA9SKP5WlIOPJkA::Ffk6j=PK>?)+<Rd=R&7SBl7k-s>*&)jTb^dOrJ\fF`ehiAbZ?Y%Sgp)Mia7jh"@<-8,pVD\Q'V7.5st/2`>H%hKqDqk$X(OJQf4Wn:+qZo]R#.T*+D(5Gn%:9s1:jlpruG*g:4NruRMNC"V10-G*jP_aD^Z+_K).ZRdA,#r23(0cEH:Eq5Z7Z'%jmUB<8a*'[u%:\\kZ*uf^O9m:ThpDDER[a]YQ8*Oc#@TUG[dWY$)/:)Imurhus'D@GqonIW\g;W.&Ug6j?S^=H@M&VJQGZ-$p+DZ%]d!dh]Q)R@:eE)nNr.T#8SjhX2&k0'nLVY)hVYV,J%a6bV+ES!P(Qa!*+`7rs8)PQOL%-GC?^K6,?sj<Ol[maKp2U,\=I#?H[@chiU@;JiRq@<&<c;gc1Lh;k$2B'ruQ57H_/c!7L\na0iQ.&a,2CZpROYfa$J4A1`s@'$O$=V-F%"?Qm/D@%<WI'9`HQ]&WAu30NOFk?0B8>K'Cn_[Z0[jqf'FZiT2).0ZP0Xfgh-oPGhMjllJHJD3)TRJ1YK^[Jk.j08Zp>a&0%R2=&lfcNVZA-+]J*kVJDu*^1L2N^;'e:\.ai@=;i"b8d&pa5L^JA]WH1gHR4kaF!nZXH),d<Q0Z[0iqs3'Z/$f.O[Gr@:ieWb/VM(fedY-0p+CqHl93i&E;($o)c=YHhnJF'stAX3W@*1Q'6tRWWY_K@jd<qC%Y3g_[_"klMi?.(1$~>endstream
+endobj
+% 'R306': class PDFStream
+306 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3224 >>
+stream
+Gau`V=``=W&q3VVrW?p/@@\tV+t4S]]]F+@1-7KCf$;Hb+".bb0LHH]5fr&9^YJl#:t@q)S%'FA7sCa*lg>:f?/iY,=+="d6Ja<8jJ,@QO"=>Mor1_&^QQdZlW6=CQWl*RI,]E.$=HYJga-I>)5E<MFhN=\]RC#^h,[B@B44%@3H8=3di]_i7PmAqNrCQ\jMHC6(4VFb5IC.Ao[f/d_f,Fl7%SnJR_pISRce?UX8_>$`RLU81,R08U(RA&T<DT:i4V.AcX8l2IP:l9E\a31W8k8f)7f%#A6dNN25MHIEl]Ffj.s1UV;Nds6rC4`U66u%?5+p(hTE@fUA1-i@uV8ZZ)ObokK+u\4-k_d8_T$B-^(U!A4=?^p#r1e$o;YH'21>bSi%Z0>6Z/Tf3YQ:81tZ,pO&nZO#fQk<.ROA4*j[;X=I="+\<l29R.4ON2SL,fOI:UM.LuH9/\Nq06[\T#=g/3cgV>r&g$LXGXA%JK;]TWl'+A%E8G/1<XDW?aP1X**ZL8R,A[D^r\IleZ.e>c/8lUBQe;`MAU66_o8#GV04fNT:;cQ=U@LLnR>cua*'gXlc;TCobnq[3#N]l]<?J_#ZhX60VsX>4(Y/2JLIEb7?`YXN!t&=)4f=oE^-hk_fm6QVASSmU*'npR>_:X%oq1/i=MfS`kP_VQ4q7JSl'(A6nKbYSa]@utQ@Nbm2^WUK'OY4/f'2peeU#D;2Q9*d'/`XpnFjaE!p'Y?er%>NOc$@Xfl?S5*kV#V.!fgT;NV\JKfWV^U617rdBsPON9N<dP8JJ'@HY-1cXYd[B.fQ5_cd#mO1k&Y/e-V;pO^_2ED+6-<#_\O5ZW`D9UI##)G&!rhm&EA>dC0J@%ARUB`GQ),0,+k@u3^RjQaXt7QM3#Ga=I<,HG[D@-s"2fE0,H.\=QrWJ'-N$h/(P=qNDq.'?Cbhc8_&Mc:tV]P/LQHn#D*SAYbn]\,Q%_'Z>+H]aZ!AB?W$`=He($a-=Xc)@R*^L.E@CcRTsPcK$\)+rpS=)]`.5^I08c1#/B#j;M*YMaL8g_Fb.%CB6-gG'&l\Kqt`2MF>=b,UhAMNh$*@!ucbc+7AX?mNk&3#+*cNp0):d[.FT!S/+[,.P.AAS#>l422eW#X*/>gd>]cd/!;j4onkd`t.?WnE5,I$ZRsH&EjO7[)Sb/gaP\1p0]kVj@ZL'lq#%]F+?9)Vb>bBOp3P6dik(BK`udq3#,o4#ofZM!V1m5aQ!?CC5O!(NOn(8"/?`f</J^pUcJmK(^!;af^k:.GPn6Q&[b=k,ZYg2TC`;MW*<9,*-\jm^L>;?<3-L9ehB0SaT@Y.RYMr!^k[N'!,1buaQV%)LN!?]`n&RKBk$+9KP'!naDCW1@1pLEL4M;j!7'4L#1GW7U\(ZtZ8E6Uaq\10!4A;@a+XX(5Hl/`&Y>=,CK!ifci:^_B]W&KFCp,3l:h#YKbB&3Q-#WcKYtXn8)XGe4+SL!Ap;'#AU@`n4/=dA%;bm^Ft*7B+e`8"L>.WI+D:%($[0,_qbEeGKQZ\OkN5me3q3(\Ud>%R`J6G-nNY&eW7gG.)oDRU/u.sXMB/%X^eeJL`TWVNj3<VNfS1akZPtj.d&iGT%aABm"mkA30@lp&>RSC6$]"g#;6-`rnj"t^)\n`E$8<H@_)?hbD,D,j>#KFsh`ol93XtPh$+.]d\?kJGl;:hl:`ZE!ds\G@1l4'+F'rdj-4t-Tq9V&1oP3rh4YlZC@/qP3[o4WPruI\:^qh+Kepa48WB5dOSFZ3:Y6uOp?>8<`<TFR?XIWmU)t9a")J\nFU(`'PF*q2,aj'qENsmbkjhHdd+i^5Z!UR"CPuUOY<65ce_Vti$%DI[g-8HqsbWX`&T't<-kk;tei`4u<#YMH:3H2@[&q.A9c+R%'p'p*XVM/R85YX&_e-7.!)'>[[K<,raDNL;"N`uHuYbN>#!`dcm["PAe\\[-uj+lG#3j</"!g:-JP&h;o!ZPPVDg(t&OZ'Y)?,$EB1r$s=Pcu?t>hgQ-E1ri5VtnLL[33fBX%2e(D`0[mm.6;jAGg.V0NI!KlngVgfn9^DmAT=XR1_Yd#'m>W&)n,M]AbgiMZPZ=,?pq?SEheXN!uB`!A;qD%l53L_HPXKq@02u4Qfiu@53;0;Kdu_oaoBX^n*kl#Yp,`T`gd5eSAmO(H<NN/NuJbCsH]M_jW-bXeJ+#WmTQGG_Ts9:#^6sb8KruK>ak:ZfZl2&;oV(Zhs7hZTf2rmU?P["6c0GC,=YVBm:`cHIU,l1-H/()o7,pH\DrPUW=A&jQica,Ekhbgm4duV@;%SdrF`9XRDZZN3NN,gKi,:M9]bih%ah%CNbS5"Eu6tq'%;co:UeQPKU*r19OH'Sc3T)k[=n&*-#PWR8%OeV_XEnP\'U))h_c`]YlrIDbuALD0_G1D_]U<L+sQ^U)S@g"e@RSb9@etAounBNHtV%I;<L<FAI0Zen(h``__VPD8$/H"dQ=pRP;-N]4:DOg;n'e^kJN:FnL>ei<;fY=K,6?$hoe8^[2f9_%AM]7.MYQFo[IHEWs?CT^[iAiZ%#t*bH+pK+Sg8(bZ#mD+8\g[`+Pr8-*<CAhN4CWR@#@aaa_%Xi^j\W[(A6bnXN&MG7/,cZZ_-WjC#*X2BgaX0mD&)kJ*,Mlegbe?G<foJ'G;2]OsGpD]R';gdR5UUr`9ckF^8bR0)9<gue#cJo)EMjOZY9@p1P<b^+`'3]M;k=JB#dGHUl?[_eIKmpf7p%%M#jh:RNSK<$j5&0N]7g\CYiLK]1PJkZGC(&5_UG!6V\cu61*L'b+,eUG341cNb0+r69DL72:9ZRFmPhKr)G)kOQOQr&f8Q`=('k^@iF^F;_Kd^&u"k+7jRhY8HO7AfPaO,j='g;$jXs7?PnUH+QohmsZ7Uq37pr@e.P[5+Cd)6=ug8N!tKM?H>LZTjeVIP"D^YNDk.5[6Lf#&9mm#`I5)G%!C%T);#,o'WObLB?4o.sM<a=lbt5JTQ.re\_q^R0'*h]'d%TJ/1%F"VG0qQnJU69?Z8(Y")IauR-2KHOQ=&'Cnbp@c"@#]!q^;U9[6CnoAc]O;^u@6Ls+B4#/\dam(<3H3.$Z3QoLg3ht_#A8%neDe,D@VKXjqKpq[g=,3U6&g:g*7p#4R[O/H3uY`-qqaJVb2]c4SCHDCm&W_>]-QSLg.>[H[-)8fS0M52c@84iY&`s5mV+Ckp:Y_C1e0s*4&N?/3g6O%jRoSR!D#KKNW~>endstream
+endobj
+% 'R307': class PDFStream
+307 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3151 >>
+stream
+Gb!SnD0+Gi')nJjr!/1X+7)(G(9'7Ih\99iFVEN/XE:>AmlE938Sgpo+\4-KYJ163Jfsh<T;/8r4#'/dqo[a6/nc9uiEPLF>96-"QK[[)8%O8;/#3]`+^0=[ZfTq#?hf\R^dgb&(trL'1qEKElKROrD:0Ni`X(tg^&bCJ&2_e[a!7t`OKNB'%/cO3M)JfeqtrNXUQa(S>5j)=s5;=Ti]geuMk<s[-55cU1:lD<;\iX)g!()mI;XueR?E^CQjmPRV"K_@Xr>1oqb?43g6lF`47F7po;VF9Ea2iGH+%sbhqr/>];rp;G':?bI]0MR;Tfo:Qsuh3O>f0bli6o=rtl!pTT.o/oPD)N7b5SWR%U??$9&gTpt;o+EkJN44\S0^^b+iQM&A?bboq1e/SF0IWE2idR,="?ii?)o"@2/<Hh],",#1"TI>mB]L=kf9LS.B&RA:X,dl*h'/6K%P^b\=e/N4/6oXk(oYXE^09D!m7J9qmI2?F`$S^e'';2EDna><4BOnifS/n9l-+(8V'TF7]QVC:5<*QrQXNEBhTZuRj&!#GWYL^iYn7_=XiD%n3dj?8&e5Wn_7^qr7X-XkrFi'ij2_/D4["O7%lcD67H$U!%.huJ!/DTl%L,;U(95UQCR4rF&@EWYZSML:TY2i=/i=1Tnaiia-SL9Ldl-d9,\7'=^TB&'W"%JP[5!IHM]-_8QCWR`]9GlWn[\orOBETEX;G<]A<+-qUABQSnYbaCCJ1gPUUe4[Ym?^Z3MK+Wq%N>^A1(.::GEZ@aC%Ae>.'qD]rV%-^Eb_o_""sALY&?/7t5P^t.`,pce<;BW8*q5$bGqhEj+^-V*r)cUU$;QfA'*S"#iG(PH&0?r"Ts`iq"2'Y!1I1a$2SbRAOqO>A$rYuTFT1m$g&#jEqmG=nd(7!drr(.b3ZKM1TT__U@5o->KB">r@X<6#+q07eUMNH@9a"pO8bcgReagDU8bQGgFDI("J&76-P:hpNB?-$+[u53=Bi*E0ZjhCEZ<2+lV2=,1PqM9n1_K*BB=BF,c_(JHAe=J!!OSN6CU[&uCa[B'#l=Nu6T;C"dJLB<g!B8jfg3/'\EG$c@(nTD7f@L2^#%$7NQK=G7fgp;[eU^i[Cq>"JGL;s*=l))9\4uWkWf8@X?SCE_(9I)TiFX?s1`=E?jsfi`fUAsAq'K'[eRA"h_"/:jiO<Z3N)L1NSrc@agBYi4U>ltAUOMV8CECd^,7+[QO(5#XH05u<$f6K4@B]EhLGB@*=i6!oa(cQ?Kl>eN^r$MG?o\7Z[g/-lU#$ojN^e9lA*Cn^:-:tT#'O/`VoJ-X(D2P/hHNMDaY[C0B"[W',RtcZfsi_5#3#[%$<9pns>CDF?+dLn9CtQ/PhHIT;@([d_/mie+3!r[u[lbN)(7MQ2\KS[)(F3EAa/S%0iSc9/cUupaKC=Kp[V.cZi5YV6X?4_5"f^(7p==5rcf',F]33^gV"^X?N&'Bn^r1R]he`aW&0t:K+dJg.ms`WT0-:j?I/<<1b[CFW#Q[b!]E#!Y"-j`\3q%A5.8C\:I6bCE`Iq&WNHdR$:N<`!-g>%kTP14hn=,-BO40//tlE2Vu#[;c[jr^,@kVH2DIEc&_T0%>@:-*rCSQipuXIP-\V:ToIg7Ls6))K$(!b'HCr_AlgZ;P@@mS$@Q4G)-f2#:hF_>Jf.g44F@o'`\;uan:4gkMWT\R+3%]i*>%F)*Bo:,>gq>FKe+u[nV(*SL]G&k+%a@n=d4cS@_qn>1.nlM7d?#f*(Y5r]&g'@N/O%\6),1Yk4!FOjC+F1aEeT3r7jscL+u&3LU%T)aIsR2'CIQaJGQ=.*@9d-^?B"MSiW,BAp)?>9(o*"f]j?&Qq`U10t6o/Zbqfbp%/1?E$Sj^Tr(3B7eD?@_W*HBGD&C-YD5\?-7P+s[E&lu9Q8rpH$h`DdtJeC#G5uAXTBFliorLJqCCjDi:Wg#f<RFj355B[X$/YEL;$:,-6;Sa@;EMn^[P;n/g.CaDqSS8-Tmh8eBWcVR"Wp4QlecV6L@SuhEjW7"ng.L*7i/\!lRi?BfnJ%a4/='Cg#"71s+YLM9s6*q!B]'Y7:os8_GM?oPW:O4jWIl]J\@M,9+1t6h=r/Y%`e@"Y*F$UIG9VLu_9:HLW7TR9e=!#Wq%^G*e8I*@^O^^Vb9o@cU+aX,a^UO!i!)oU#1(_p0I@\Vb)YKQ.nMchcLoh!rk.&E84ofkuH(.GM?,qcs#k(@,5SO.P^QHp#X/klKJpr4PYVVhe:0+<p/d<ZM7FjRee9Oegsq-Smpu>8u1F9$ACjkgh+>(DjPui?l?B]MhU5oI"sXS:#W3=EW9aemVQ+4e(`@f/BR[8Zq]un208\g[kpH0,@-/5Qm&!f*&(f([kLKnAlaMEI05f`lWQ5(Ho#"U]-@YYi"`7KPgfE7RdE?]D#bXim1l0%$1HX%Q\Zq_Bqdk;+?FXYc'i,7Nqkj*6PY1&]rb6E*oBUp)[+6ebH'Y`<#4q7!LIjegCP63Fk<O;!H"mD2Op$e:s/tJ0Kb(D/r&0'5R)4UVQRE;HVKFW"-cHin_9qUEt=65`p]gOb+2f/%$gPZ;DQ1+p!Q@b-]8&'qSO@G8^XnpQ37l`^dEb_Y\^X)#Aqt7Nqkj*/'@ePk\@[:!o/ag+X-G:ukHM9o_bm@L_1.'\M80$EG'eeY5#GIY6q-=BV,8\O`:e-\mOC<,,;&@"T5b+C-Tt(U]>1e0ic(N<W6s4d';Rm?9"&?]8>TGo9B.+C.qq1LK2SnV7J9Wjc`>F)\^h;AQ*%nA:Bf[_>d53tLCS<;W<q_%r4N2dV6&jGQHl;YVAi83U!D=1qQ`SUnbS8m.B2_$a&3gA4trm6$J?;<`^*"C#DT!PAgd$'/.e)I\'&bcWE@Wh-2UaH5qL8u"pNJZ>V`XK:R?_U=CQgt%WGIbPFe/`#SD6OF.)Q<BV[2G,a)`"1B23R!SJTLPZ/<P;UOAMrolQKF"(D66./`JN6mngb,13A79D<m-"baj*cJPrd"q4#nsl.nIt$"`IIH>pl>2jYDH<gFLkNON\1`4FrXU-7]F_YZb5mQfShpT2\JEj)2N(d&7Q\;Y>(,Q.<NO==OnafNPj9S^U.(Eb@5g^9B:s;JT10jlI*lVI..$,fC8EHPKSGo4tQU-'E)$:V5!.2ua&mKGOI~>endstream
+endobj
+% 'R308': class PDFStream
+308 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2527 >>
+stream
+Gb!;fa`?,q&A=tks3RUc,Z?TG;O`l?ChFW`ZIHg]_c5_!OcY55";lZRUA=ZM#!n.#/38u*@P=u\@d2L(IR$+CKJ%_.mb]u-\/<,I=!<5/N2I6\K0G7O_TVJe#@H7fkaN+Z&4OEKJ:0>ILN"/4c[o$'(IeL/5(%mUL@ms0i+tB'E=-+ki+j=)AfLsVR^26CbmYX&+2dk0N.6&Xs6783<58@AD9Ss5Vm0ptC'6K]P?3/<]+.K`5Z7:A&VSSk/KjIUpDB,\4"*cK7Z/P=2Rk/g9S1$^?[fWk?Ghe:0Ha"`]0VcI_U`nus)l6UkUbr*1&i4-90$YfL#iNA?@\V653M%"T,ur!<oc;Q3D\G::QP$'b@/C*2sr-'Y4+WD3#BATc4(#5hb&O[?OC4db#N=F.lY&aGV#^9L8d'jFucP+0GRh>-hVHVCWs,tS5A;9m]Yq2]`0[?#nC328S6Fb4O*F3f\?`i6^p0.:QL._6P.'Qo(-L9i/g,lYl41RCN?S!XE*/in[msN,2nt3%_@)_R!pr"KJ[f$V/50R<;h$P1g`\(B_0dN_+qbDRd-2Ys1@5OZg='hG8=rDh/0h[9A-1&b:RB<%XAI[eZFC:+3tAAHGOeM]kB@TH9i8;!k;,gAcc6&1h4(`#V#=E42)gVqqXDgG/2071stWtUkt8rL]OSI?m4.;ijmtT%T7)cjm"\R74+-1"?)Yk4UB:+$."s..puL,7I6UKU'OG:b@B-LiANT'Jn&_\L#K=J)"#c,HOektF/*Qr&rn"Q2]sct[F,9V9NF.<6Gsj3MC-`$e^PBckkJb\'B0b6,iq^FU7nQp]-8'&#r87l,!fsB:q>X,+Y5=%6q5e`:qo`J4P(`9#0:rN0k;_oAL\sbNLL2IKM"k/iZIj3(1M+h\d>Xdfg=UB8=@9@nb']>Q=l4s?ZS5]:Og6E%g-)(\/1[=(I5B_>$F$I)n!-HOO4=l$sP9+gqE":()_!?S>?qqcP2+e:PEho<(/jaf\tBr'>!>s4onkqJ/C/eE2hfJ&km=e!\s[N$)?B7Y/hF^4OO#f"Ob0HG*kk0U1Ub:XN''OJ/<TC8Mug0Km2^0A!14I>cYANmA:W&'KI't.nnn89[a/gE]MM'ms%=t=apB<09JmIqNZ9_*o"k+FST,^-0Y9471E7g3Z;t8RB8.In;=O8.jJsV#>?jK53H3V"HL;tmI[7rRt3p"^^$7f\\RgXg8[l"OC;s&=X-U\RPBGRYn8P2r(P$fBSb2RG)$@rqEO\X:?aI_;X,P?f7qOl_F&fUF>\'@bC_9cm)nHQh.Zhi4fGT7)l!9b)V.,!1c9r=0-5NK7jDX\=g['^V/oi:l34XUE%,pWdiN85HR+'T/D:K,QWOm-L>"j]ikI%m92F=0ToSt>%Via6f!rMJQbERUiD/oh5G7j9\384<ke8D0bEN=d*[pG+pCl_*-Lmn^^81$aq_Y&E!EJCkPLl=mGhsK[pZu4<IEMs4cgS*moU[*c)#^aBhpE=J4j^P)T'#;qcZ;3J[ccO*eD44)p9j8]W">"1G!W'/('ta/bQqM,=su@E-j;S&RULX.j:i47[SG>CXI.q%*R[SO"3&EGWXGmXN0k=T\h*2m*VpZRRV@uWU]W&MOW_Lf(5I*tdZZ[q\69KhOp-V9D@567?Z#GH_uE/UEoe4*J?+*EM_E4EFoj/%]nCeV6Jg2.K$mc70lqt1)?$C,96\9?0Tp[hICf-!=^!bLDstt#PEpDf%VSXLm92(Mk+hAp7;oN5B(K$RkXnk,G+n5EUUo;nFpE#(fc#/50LnWoYMV((XtXU(]n*"<$*J6Uhg6;Wa._-L`u<a6#[#SdFe3:7PNKZR'G4P['OeeP6g_=!8YK<t=Mm5nm=5A-EYL3GB6"6D%t992*7Y,_#BZ+pRV>R3iRtKRn'Tp/Z"aJ?]=m7[f%q2gec>`-\?)&g:?kMJ2bUc.kYs>F3?phbN9$:*A,$bK=2cJX>^M=]9:7'S+K=YSGmRPVRa,(lg/>O%)H::VcEOq2Kg>ekH-r$kbKDRe@8C#LoB1mKcug0D?L,F$i`Ja5P0^WOQ-,r6f<4"%chGXnG=49sARl"/aXQ6TA?2]WWRJ!j9pP!$ZaNEhDpm'mQKp!"Z+^-tW97V6BV[Lkq5ZgR`2]P(oL2V5[M5_1[fVDj$jkZ%AERu.f+=fX?=)&#KUEHU/Eam,M;GZ>Eg(mgALXaJ2\[^P>+gMW<7IplD;lO$8q'<ZCnL:WE:h$]IXU8K*_j$[qVr&'+%G..VJ;7Tr@f(sfc+8Q[dNI@<3>G]WXi(j0(0KWlWP^NXB^;aqnd$4`6@@*g+f248`s&lIQ>.=n:#d)I<e#*q>/"L^Kk<544XkEn!ummZX*NZJD]2%](:-BiI;4BgON.pf\W@jKEdI2@+[KR@5GKkVsKgjWR\(Fn$7j01T&)T/k(fU;:I/YN\!qK7hZPk`h.R#NF#9Pe`D\-`4,PK;Jr+H:W"9VQ#Es3\MZ+@B2eoAHd'Kh@,gVFhQR.cajdC7T>qStPM8fr_qPa>_[$2Cq043.~>endstream
+endobj
+% 'R309': class PDFStream
+309 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2436 >>
+stream
+Gb!;f>BAQ-&q8/#rkgoLXc8.dc0h'>8_i#p)_(0EF56"F,U=NV!<iJbW5$'Yi'ilA8!K4/M8lhQOT_nTDnfR/'L3Ue!rk2O!DZ/Snl5ZU#bq\/?.O_W'jQ]h5PsMK61K3'$Xq*\4WLeO4b1GC]Z(0C:([-WmeJZ/25h9/YbQXX7O\H@_qR.8XZ0]O>-dOFbS465(GP[cUEBF!^\QKZo$)+IKc,R"D^\>i.8>SOXM_UX:6"CU`3"Ybjb.[J$Y$9^fKT^F;\:+#]-_d#brSSc31<DP+3qE:9AoDe+sZNO<YgWbQCnu&R=KS"h*d_HS;)$[@3gfl;O*^!9r4DN/87cbH32KQX/W<Go4_gl`-9uBcj$SC3<*<`Keuu03!CgleN-R4d5!nEF?2p;`ef4J/7aET?,%JAC-m18Z8'L-]3%[YlPa3pW/`"b:d:`<7WKll0!.Ja`I].Y^i)KD`PP)6N^\m_<O1#0_t.4Xeknn7H[E$[IdRB@o49T[XPN49O,c,g)RS2UG`[9[c]/2E+:B9p6aFVf#)-7e3;N4[c3dLm7(Qr>Bm[l@7e$6m>WrA>DSZ*7",L9)`M_pP8B1d*VNb%YEpYk_(@i\<>iBUai$C]tY-EHl]tKN4pR]Ds%H"trr$+l\!fNhW'jP"W!bQS(M-u,=@mJD-,:hj95cim?JXW'A-CortAd!`"]-`EB0U's'L/]_d6H+bM1:T+;A<J5fKo7(l/M/HHRF6q`/e=T\"roXc$6t(Rb0mOK'O`@HPtn18VK-O3J8?R&@ck+AEdDG<?^-9nB=p8)je09K(&*>f^?UqXBHbIabHkR5+.g,,HZP"L%%7"ZMT72R[2<.D:p/S1+ObT[WmDmECN4_Lh$d<X,`la_A>E67,iV*9]lYrUoCi.5q.d?Q((]AOU((tdRq%TE]B0.I)hcrIngee3QY`Fk,X\"$S'C-M30-%PA#U+["[1pqC9C:?]hOu=8i^KL*eZDuO%GU/r^Un6DM(6HLInSL&YC"V[G[@L-_<!8ZY#d*1dDUC$]:l/'-d>ZC#K%I91*E`F^2m&_!j-en<,B(^qmPVq<%8A70Q:6E$6SR]*#X]_);@C(fK8<*?.1ULtb&BU6Th4,#M.U[k5^`jCWugGL`E,.0^4gA'[R/"%k%37,q30GQj.?R%QZTd\-%A3ArjsFD2pR)>d6JDX3tUPN(HQRR^4e0ZRRi0Z!p`/5]f!PNpb]RbP4U'K#"*QXL'b*5Fm]s*97UH-S6?>BZIW,\G-kJ)OoW*)BR&F'#a'XM<)c0C5lB6?^l0"4pRBhl<WjdT@Vi(W';F%-HVhQ=67"\pH9dM=82,6Pg%M).niKF*1g_N0@1'&P>>GA3m;H(0i2V=J[]f2Rgs;SlSnD=CN9dF'q`8!K462)0GI^^V:6/?Wen<#Uh`"g*9hO91TK+Eq^en2TYVM\GM_7=67WZ\E9VT\(fYAqS_G,+UOa*=_*f)\#\<kpQhgUgD&153G-_fBTBLQ^2h9%<&3RW>%MsPj,_H-Dtj"70#OEJWnKT.2qGK[*:@lmj'J+QS:]_idhE+/#I&CVa86k=J"uT7`W*[)2Sr@sZ&A=C\Fqf0;<p2-p#Dn.WJlr&e43qj;80NIM=j"^s8)"i\-W'p];GSWD<ibh2m9FC@L*!Mmp_!rnNP".[mG>s"Q=5F#e-+<hm3VA?=2gj(Zeq2#+O_$^q9t?]9?MoJpZWC-AE%':(<iAW$c(tF00G/]#TapNZV^mXJ,`M3l?Bo<RF1m=Y+\u)sr01n>O+J*)ZDbl9S<K$p;Cfe2Mi.<<f#-V2\oc50iu@pW-D`>J%;qlDE4H8LHPp3@oKP,Q22uDR:)QY'6&VR1#Qf$>tQGTEg,)8<$&NFIYecm:79YP'UlQQ_4i7[Z_,rh8X.5=!0\"l`_M6>/aU=eIFL9LS+%kDr+O.V=g/SP+Dd*L*oRap2\gB>1J'pPLnM#l\@3:`\U!(KqblC_(4F1Q#qu/X]AbX44@>!J0P.%:-CH&^AG>S-9lqWrSlX_^nT0)1g,E,Oj8pSniI9uS`n@"Vf5WDB\d/5(@o_T6uYt0)<]pf^$s:1R7QI"\KqB\l."Jp!H'Lg*s]A_#(MI!'2NY$cqi='./D,3YFe$XH-m>aL7*a4OtakW'T%fF<n@s$rem\hFD/6NR[SS6@%)H7M[ErKisVh\l1RWZh03?+;*'Hor*>2lc!GUYE,4E^r^JLpamr3f9gsC/8(F_HbWj:W@VH+<B!jqFLG9n$_-3pdT3]mhT6SlMKh"V-*$pg)"#kk+9P)(8Z:%UbitC=h!MgR*7KFu1?])(3,Rt#,%Q$^t:=n`M'ga1Rpl%\.(i+`>q*Q-(ZlmO],Hj&?T5JM9QblY2eZ%t+;n)\EaQe_OTQ!\q6M!.2l`8lN`94j'MDht3jW7$A3s7R0N;r<ILq5/,!Ud5?1s"YOZ[VsU6Uo<~>endstream
+endobj
+% 'R310': class PDFStream
+310 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2636 >>
+stream
+Gb"/)>Ar99&q1@Qs"FreN`%9@;'^9E3@J:UDW=cXgIOn5*;*`//u<E0$SQPM?f.8WP+o+V>R*iY^kOF\Qb0T]HugSCkhqMqr]1(q`<=K#2o+Xo_umnd(/.2:20o&ZKDIH_l*^cO0'h8:cc1)0Sf?cKf'etqf7po8:N0=/g8N=%4W>^K(^@ld>b?3+1Rki>W1RT1Xhcf\quN""eaC2Nh[eh(?ab[QGIk.^1MQQ4glTqM0XHUtPD+PYcqP_K_JLhj(e8l2#`q@=Ma2q5cX[_VSr+4;SGT@Sr?O0i7-KLrL3!pb>_W<cBRPf-W"+=N]if7+id)Da-YDgY`c.Vq;VW#9.`kj&/qh,^5JV,H$=T0M-[7+R^*j#!iGPf#$9sE!K+eE.+r2@rjUq_/Ba/9(1BCgHi%XS#'/s3nR0_Mg]<!)Q,UqN]*Dbmp9)^X_NqB+LH(8K'huV&Bl+7LP,mH-#M3UcRJ[UYM0J4.#^;'O5&P?m1TkF&e@HWBV/VE^)V=#7f6dg:Wl@T2@WR:/b_+:SQBssXRRUp7hNjJ.o$[i1YqO\"VApYi+b*dbt:Bg#WBaS\*A4EO]X\CI*!]="m\M/b1X`^DS)4FR%`H7Ni@'W%dlK)R?ppl<[_Un]W77O*Co$AQ5\1b0'i43gBaV4O1acCZSX]nmESWU`H8;a/)^K$F3Rt6d$=VSqAMkd%ae-pI5Qkuu_ma,p92G12?1N=2b[k$NGhbJ_!\>*5B-5LtX;*6s19u;'n>VrKRVR<+_2mMM08"]`Nr_Klh'H`-CO3V30h@#0*#=q6&,oO"$[]5t2U6[QaWUptq9NsEGZVKDIkYLI?r6/anR'oI>bWigl[kB61Ho#WQ]6Z9I^3r.mp4C#<DI8urY)4kk\!L0kkqfglDOoa?Mmq<5bNUgqF<72\[>N9eXf&:n?;5<,D=HZa[8Zof3:A)^rsm/'l92IMOIKo1I0!jGnO2ZS[gf@"^?jgO\VnlSW$:CLHE#UF(t%`Jd@$65jF/^R<nDIkEhLpi$4&a*^i^@@2j2-$oN4u5PhoNI.!p"m\iLp?2)Y]ODr$Thm(dBFRIM`$^c'^.rD(DEA9nRTpsncdd3W8eqpCt'F?R@WfH)Zm-C&3f\=G#YZXedidIE>4om&OCd;I_(>Hp^C4E=`]&YbIXYEW$6JP1<0SgS4)IY:S/&k]&)c1TOAr_;0$S]rB7?S0qNcVlTjIfuR$]7*FEY:guLk@nF\h7PAgK5Z3`qBU`sNHboS%H6<;!Nm#"GM$F(IdN:/j24=/.K6+Oa-?Nm+iWicprg#mc!q+=\dCtOTNh_E6UB.Ts!nrZ^9ll=OfB*KD8WRrd[U21GK3R\.M)eC16_h$o"-bI/VC(99dteSH@&UN()Z4!?Xo+`VNE)`V&4D3>837bWhMU^o7Fds2Qml[L#(7H?uuWi5hCA,Z8E6`/nXb,<tl/T)t\.KF3K*;TMh&SK><ANaRad/6_da/qYCd5)kCg\2b/.$S5PZ$C7onZl6a_g]G;C?UYng6r1B.G[?RhMoZ-DCj7B&@)@slt2dfu&]XGrI=<_"@/cu#SnBOHj)9BL5m61TA]0fl9H,F@6bmt$&12Zs8L'9-*M-cc;<nFe9r!'/l;6.GD-B*u,"q?2Qe#MikFep_#n+"q.U`d6!-[bWgq3(SD=;WEQ>EZT^WZZ@e5o\M@hW:d<EK(.n8)[c\gq/KP]aH>(#.mJE?:PkZ(d'=4$gN0UXg12.[jW+ig_=@_/#cI0:g\j1W</"K'[3%0^;Qt\(+i^!5.q/r]gmCMKZ1u63#'YWKpf`lN%#8!iZE24an@bl@u01'jVd4=Yge@UKuTi8DVd'$LZX58V@Ug0FEFCqX\3Iq?GV\Mai@.#j/a(HF$*O$*7G)A4E-"pF2'\XeN:l??_hC=G`[@c@RLb0S':dFLl`BK'*;9.Y.IYIcMa:L'lA@#CAmR?(OJd/]=SH8afoYoE03P4e5LXLC.Dd'8a:X[(U?.#/FDs*NCg8'19ono&c'N1lBq7/KJLi`#Vd"_F^KuaE(1Mg]Vo0cp8r:TrnBo_P#qLN'f.W(/4'a_o+a[7#&;HRY\<Y`GZAq\n8AT\6PlPFGTirOHf[YZ7If1,hs/gsmCJH>:*N:H>[;p(`-i]uKUSLu^%ZV^of:ae\6P/j;9]5$<+.=Wh\:lJ`X+Kjglk>-c)3YTgCusHV$j7D8>qR6SsEiJgE3=ho-8F*-\UtVWHnfEZ+Um3XWd"5NuX/jYeJE'C$TX['X9UNp/PnBBPHqI<B]TGF"J!/cQ/i)XM?bf_k#fRZ]p9m]JQ\m<g#>D$+lMr"_H0_hQ!eq)U2Ko?`V&mnMLMX%(Q?4R]lp9B>E_8%rD/lXU)[BKO7,9BOJXA*V[JVle#6V0\@r[401[5CDuj_OfkX%$;t`l3&X^h\L=%iA#B:16H?kuFjSe+%bORlU[=uInIZ&uTM%>JeQtG^:IuqACdfM/X^^A8Zk`'AH%<k%)L7^hA'lHd`D\dm$0GUrB#U#(4(r1\bt.6%m7du-lA6O$@dC_&@\\QoB4,6\T50(p7A<#.D9"2>a"/*eM3QQ6)T[?0Np5'$8XGoZ?0D`Wc^YG,2#?G,\+UGjK,*NRCqU"85UoUdR<0-B]Q,1Z+0o&n\-FI-qW'<o-5S6~>endstream
+endobj
+% 'R311': class PDFStream
+311 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2626 >>
+stream
+Gb!Sm>BAOW(4OS'rkk/:XHScK;-/,!fi^8#Y'6=-CSfLNH647BP)tb*$\39)^OFK08<C,nMfR;"AB,UL";3]'mp$IB!<6O&5KNr?T>NUk@Yfdn?U?l8`\@E)?HsWWqV?SZlLi79L;R[__*'mG1%aLP/Xd,<nSeQ]O!!>[E?I)r:8\bmk7GZG50!2Ni[gN0aas?<.l]P9$M+c^J**^0j?C?1?[fT.bUaf(pG0(m6$sHeZ"'Irq2@9>jR7J8EYZo4N]#gs-0+CPH5RZRpWNJdDa_GO]RG>jLGs/7^bX(jfJSFX/:"Nq1(HpcIMeY4BglJr/V-4(2#\mZL7>UTVa[pLQKO@.]MOba$We^Q9\-uf>]NR2H>oHXYn;06KBGj1I-I2&)j,0sX,V)8D%^,;]uMHY$o/Z]TNs,^0_$"iZ=elO^tUY3Z=\-rSJ?%@gK5e$VGenQc@mu>abOPCn(De<lf_IV!B>VW+<#BbH]I[%L"[*hN!3WT.dM&Kq3jr$2EV%ekrC@N.i'<raM=>+bEo'0*0KoAIX1T#/1qeo@O8uk,cECF']N"^V`)t5OYOII3X>Qf$bg3lTesq4[;^3u(8Z.IYUk\6&hb5CFGf2b0l:Z#Wj>-#A3<?nPNO>Zc:cFN,QcT7Y2-g5R;+$GG[#+nQ`AOA#P<WZ4L#L2;WNR'=*%u<lp9o5dO&Q-LR8$cqu4VP:mq_JriAMaW8J*u)-`csD?N$h(9Z7/=YCI5$b,an1Yb9T0Stb\"7]Z&@giX#p>-m67ce_ONDAr'lZ"bKN2NSOHU*JodHk]3OlfGZ:`IuqCP-I<9d;WIG6)VaN`K]SE1M9ESAe?QIrOZ1(0tEjD4dZI13Mu8L\uU3(_Y3m+j$*;=/j/(1Wp5r`1]?U9-JQfMlkb-:UE;">-0X)F!4VH@:1PS+S;]7e6C<LFP8+SD?Im\;.O?Y8*<o02Xr;1+,SN"O^@(a(-0N;lL<g/`0A'Z78Q6i?U`b=7a*!Fq.k1!bqSM>&#:j:"+3?q7F/Q'3gh#*itj<4Vdj6XNt0-a032+Pb$u^9]K,p_Xic%83_%hJp=6`)7a1(W8\Fe:Ho=,ur'/ij]Xo[0$^kO:b.C0tnT9-m:quMfVb(?_6CL#+HLdK2-l89LZ7YQA=<4(FZ'<%m8+'>UTub1ElY:Z:\Wd>?DV$A77`m)sWh,TsjGTFjlHps%C7\o[K\P:?fG'!%9>RsaF>'`8j2"SaiiB>I.lGWPe[A4%Z$":!UpjW>el=/%b?+G@(#="_?uOiDYR#D`/FKDsW[d#-n-V(JWiBE-;N386LIO_YD,<70DXlffe%9cq7$a^Z.uX:k9l"LjEWnbL/?(=FNoPP>^3L5FY5e?Oh;k^H"k,@+6eU]eg%D$L1Xb-td;4%U[J`)pof5.F9:o"YKdDF_[pZ9i?*>VP^K&mVncW/sJp_6-TDX*h;Z6g"H2S>%5Vtl##7;REao[X_/.]S#eT=9"JY#B&@o3*2dcmI6_6XQ5?WYWT=6$5e;7Bdbd.@Sh!&E\2#^;"2CeAkj+Bd8s&p:Sq%XaX/1a+An`/+Y@2sH'4.nCi)VN^ZkIg*5)[SU#kD[N;t*ET#P0kJ-T?ZuK-)'1T%g=IWrDc.LSnlB9IF?,\1<ba,m/]Ls'X1GH;<7IH#9<L/*(,a+-;^ANLQk]R?C3Pl'QJH3U7ME^eO[T+-/h.[8Jo.@6.c\o4U2!(KBOi!*qA(%^IW4`u<47l<7!&Qurlo96Wuon\R`;j+bk(9aC+6[g9+.R.S>W>/O]Y)n$(C&5PenfMWZj69*J5iD6%>uBP90nXc54PYo2C_.`YOKZ?996@ZLQ^-e$td%Kk;6?83183CBV7uj*r8Y0sV(CMq+=H`u&(mPoSIq?B&\.SUBU$:@M94Y>4dAJ#clbE'(no:">C\3<j&*V:"XMaV3Ef1Jf_]%AO7Gb9Tf@:^3ebF,dg"Xu;f1r\m^Ni\n\!C'q'kFuUK#\u*<BOuuDlpLYZ#n?bcOW$VWl3>8E@=_9:N/k_UWeBrN]H.bqXmBuOq[@Pi6q!)R3Do>cf)`PV>>=JM;%3b;uN,$11<L?69OB(?'Y*aR;()SQ,G'65jj%!:?1jZqMbX#qX$ZL%-l`$ne$9IG1Lr>@qf>CJ`0Om=\K(fK@Ols"g)Pbf=cQV.U.&S.5]0m7D\NS%ZIA*WYB"^8RHJeR5Z/L]S7C[s)=6,%4<dWeIRID]B[4.7^guQbkp-M;gMR?LHC@,Mon^5IBg791oaeK5^7p'=6+1SZQ9V^KJ"MY4Z9:!D0QE5eQEMq0Oj*3KLIL56\rqs[o7hWG=8JI5*lSKMULts%TI_%kIIqN`rYeL+N-J"Cb?%b2u?p)Ng"j8g`,J<rmPL@$HJZFtN07UsN]@^<T/dtFiP>Lm2:fNp%C9Y7;qT\9No1^e7b^EU/_B>G'B:dq/GDA[N3cN.9kJZOF'^FsmK*d@WW[0q_;;#Y;)l9:QqsL1X?2%:/]0_j'-9r)GMA<OSPo;(QB:2*b@MNT#_h;V6_lphQ5[WV1l=*T5\'<e($f&YtXi5#q\5H:%>L!"+X%2Y?*'7I/F1XQP%^/SP]X?1eWl^\4T#60fkfV$)$@&/&8F>s*?u#^8J`S_?pBG]u7GV$gN[sVod=22T`7n)~>endstream
+endobj
+% 'R312': class PDFStream
+312 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2892 >>
+stream
+Gb!;eD/\1M&cNgos'ah=9a[:9;Ueq>PHWU#!r+BlB*F'bl%^"aP-u^J%!QDSs1U9VE_4E:6G"t0,"=n_q_C8)bVRR]Hl1lcTDspLJ0.h]h;<YM"'BEU&%rNT\+$lWlW9_Sa017o6O3a35/fOqpHDjZbr]i-T(p,9p9.i^WkR5$mO`$L=JasQ*e)-%BudbCV(KacVqAj*J,C'_s+]'rH2HLokB$7agT`VWJ)UpFk+#lZde!D<QE><CDR-e!.Y^%tG,'s0<#-ck/.EGe8r2S]9QVlp\G>g2!P9!\7$?b^qZYklfP,bp;t7uhU?5jb9VF:&%q!Ig,9lBgO7GS*&lb;I16n7B<p@iDcQDUVNJlZOp:A=f+fqK9$nc-\(5jAkO7+SDGakWg<Zc6G#0K;Cg'E?4q#sQk1)[tJhsJ)bZ02F%[euH$#Te>Bi[m:MK0N>JQ.?AQ.pNPg8G2NIGHY@b&C/:e+6&-/Kt!R)n0*L)\a[Vp<sdZQ>l^MZpo0^mn0VT@qsh%b4!nHU1*fX6,fXkWnM240dV5j?":EdK/cfC2YDPXbHlK,&95rguM;$&7&1+Ua:g>-h',B%?6c^Aa[%V'hl6ah-^L'89=c(<UR/Y3iW/N+1I[<Nj"_)9.0^@!>R*,&NH-jg4&%TpBNb:X$2mSM_5:'4cr[u"igkmkFG.;8,eER<W:`nU<X3<<K)9E+o4:f;]Lc?HlK9H,_<cUtZ;uM7/22=)o.55sZk)PV[7"plYnC3gXT>=>+GUrF"fb!"$jq6UGT5X]0VHb(@ChYoN,/Fd-q@nus#It:uoDGLFb!Tq/pu0\+%rOFLS"U&SIerR(p;\L<YV&pbY>s_4D9<idb6%6Ja4V\lBFV[siG=)^l"m-'AKgA!_Wgj7WfW?;%^9#XV_UG@@qX,6B3T]inrun7Xm,M;7Gjk5p;j#J#h5`G<Dc;YBI+Qh43!?@^g%@pTcXt08:Zi5?n1UF]S0sN=_6)$e(3L*`MK'FAE$NnoE7"s6NZ#c&q/]S0A<F#_ahVH$\REhFm1rS,.E?V/nn,$1N0Rh:BqO,:`7[-T&Zoq;B[8L*9s3^%K.mb"#u)liB7.7foLFQ,StPgfM+seU7HpDPR,_Thu\P2V_17)pL&"ZnWtL]qusj"=_n@cl[m0;YjQ=OQLT_S`Kg_ZU)4BQE%rH;0Y3sK/19;!#3"2BlH"]NSKWu7mk.W2fogWh,6WB^`,^#m$2h9&I1sYYS4:5ofV:)%X.XHXB4=5sNi=]Z#sQoG+L9#R`u&bH@&"?dKs[!:l"q+'Qm5mX+sZUjU)(e*)F6I^Ne?Tso7Oh3&RiU!&?jiOi,rc(jZp="+Zmj5f.A=^/02#m>dij0?+=pDeWRb>IsiI*S_7l-4/GaL;<Y6u.AL1pQ@>:,_QQn?8MU$0@JrVhdMlAs*YGM1`>\RK$+Vg\^G&#N4LgTLBF3\a2Yk1qPkZ6mT1ll]MhAYG4e>C*DjcG0l1tIAKCL[Vc]`^bI5C4bf+k<WbjETJ8"]g7)Fmog-9L"!'>5/QdpZ9]GjnI?Z63m*c5-/16/i`865S`O76AX583.T@.'l*p'-*=2MQ#+;hGaCoWM,M*Uf'7G91hf=7][$,Qj;*&J_R:`<I,!2%m-0DaN\s%N&!\qdd%o5(oKK#aH@R?9\2Jaf"&rXXWU#el?u,sXaJs%hMKc3Kpd):Udd"I".!C#2a4Eg39oc6Vop?U%52qOmNJIDYZmM'G7dU.G9F1YnJh4rEmbs>M4E*),-6kM\[IA6M[gpF1Eq"HL;R(gcV*RdH.fXgAR"';-=[99a1*1D)jdV__DGN3Lp+'(^cXaIbYd!dI+2CG<Mlnk(YJ2\A7<f97k)T>S61?J9tG(UWakDXhNOm"^EYTk.RV=D,Zl\P``1`7nl+<b'1^O>C]n>TXQ<2>.'1@05Ib<TenGS?\ZQBc[`N?DK$kq]lc&S):WOYCHr^G79@]Ym2"fN`Pri]!-4u>\etkNIR0Ds@-4bN;oZ!Uq@gWPITa>jU/I?3Q8VG5ubu'<`fZoH\l5RmG)RAusL:=0H&,KUUZ*PlI.egNa+7X=LjPkAQ0g_t:dN*UXG_0N%_AX`=>+pXq_JN^8$_F%gr)qr0a7EX/(m'$LDr!Htdur]r&XJ)#53EZ9j3sL/,GQ)]dOG1#:;O*+PF6#Q+uRj&26mA81Ku!8S)YI')LXRQ;2$D"Z(ZIs@#ai."/NnY>>0l,&<%DY\"*\&n>b6'8%4]Tp08d9mX9lHjn46]C9:UOU`r0ko)q11rl\Yb9Kfn^mbeU$dp,`2)/Pq[>WeS#H8&VI*VN>kRj7G%:G8Sb7:O89@sPXHEbb??g0sG#pXKfXNuQH@Fh&9F9Vm^sc\3ZO2r"WWQ)]MKhGdmjWYdS/GF!:^2+o6>#bFX,QT'kG6&sYX)i]Yr<QB9"O7']R:^?s7IfUF4%OSN$(mk2SQ#4jq_GlLaN,<do(PIX^k6";CN*qfF0_T?;e:odinK<Z.])+H*;-,Id2]RPj67C6Bj9f=ToV]Ma\@M2lQU>Z9RWV#Wh*1e@a9IcAH*%aR+[sr;YqD?Sk/`Z-ipN<>_>g&Y*[*ZrK\;?Haca[%p4"R5B39=3)u*SRci)I&58"=T%*8V4H;?fC2s_OmAO]bB\RhCr`oQ.\S^38k#52PYEhjA6PJQbHVK5n&TiH]3I8j)8ESsa2(RfGo_j;nBDSc(eA86Ypi6GAPZ'?TtCTU3@oD?b_8a2PYfO3brD>B\31`.*S*6L*N?*#dTBR"S/PG69#BIqniVUYJ^beYc*jI6&[)XU`NTUj"kUFUPIUTIAa(`s4!)-qU*g"'MHG`"/?s'(og<IC/l0Z\@@1f9st,ZO#7bK4)B&KOS0-PtL(8q_T7U8PRXB.Q0a";W&nHrsZ.i^,K[orJ)m/r?j-~>endstream
+endobj
+% 'R313': class PDFStream
+313 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3636 >>
+stream
+GauHN=]=*H&q5%Xs$MKI(@O.JV3:\">7A5X^h07[1D.eo<4Akn7RpZ\K@sVHR8l:?-P?W"LM9_UQ!%ICH'Egl'E1o*s#M:`h3&b*TS-KZ\KTH\CpH/Hn!C4brK.%m-LTO)ZAb1R3gJlmm*km#0f']T*-1fM($nO#6Si49FiZ<\PT$b7qkM,uiLib@rf+,&*i3esniL"R;k!_Rrqhh-pnR9%N(sgrXiDS=a%UikBQuos_j[m!Eb]#VkHiAaMbn$DXqf9!K,ed<^:37((PUq/YAa3$(LE6!.+lDCQ03MYI?4,&f;J4oZ!`3h</]o]?bZr)D;0fOJEKkKG0oQ*fF,l)f]<d=>W`Mr@r^h:"n@2H0*2`_nurE\rUXJi]J)pfmh6bR,i4790Qc?rF3,ARDf=KoNTZ4Qn:Y&':rGI2/m7"ooNI>8S8Zk8,`Nui2Hfo=(Y65qY!nh>\+[==lumCH48Fqj;7V]nSVncI`G:T0LrG6/jmdh[iL&@u($>%R>:'?/Wn,s-A>!-:24.Z5Oe@J_dCE\kW[O><;&9[=S';D_ZmqgDHtpkGV^AITeWjRe1t_:/-g`Yfno[OBcW!/cKa7.)AWSU]]g8ph6(&GW4QW9G&P:]Wmkj^4QlL2If"1quV.(IUU2L:jfHFnHhBn*^SgI"<A@K9"SD8,F,u;Wg[.@S/NQ!Kb!0<jBA2N/];32G4P<@lQLnE9r*/et)h\2pjOT]BheGrqf=2A[6H7Fb2+W$cbrcrNh\@)KdLi4h&+r2=mn$Ye+$Qdfl")3pl0p/V<Q)_.i8B=gI-U@eT_A?H#aaK>0?pq-tM&o3QVlHhY5u)WQl35&tp`mt]1M$ZpqT1Om4cqWa*sbaq&M0G<H-4%2cRfj1<a/]TJ[=*J'W2(I>i,[J@\!MZP'-,nKNmq\-2ct%0h!gW"@AoI239O9;Eb/B-HP>MS`^@<\Bm,XEe@g"5oTQN6[hP!5UQZp.c7dC7&!tuh5-=P/X:bk8[a6.5WVT[[G^KH)E#83ALFeU`$'5T9E^@mL6-1Y()GBlE;hoBHC2IE@o):Z-@\a"[`IYo20AOA3`O3oJ\E"C0cYg/ZkkOYJ_=T7=!>=,rC*mO'LR=+l,Ac%.>P322!n#u"$_l1M$a`3q%1%BOb[KrC:S(1OD;6G2LGp\Zq9`E@DRc245'U;=kdC^b.C3H*6Ri2P54t+XU+YSA2bWDEV(:,)U9)P@1RA>Gm_V1Ar\!BPR>s&_Q<!NN1qgE(KCFRdudFfc3\#9!:=bWqZ145jS1l[!WXc#^l^]9iiifa=6tO(M"AI,Mr"=`O4/I>(XV^$Ud/a7.9iJ^iZNb[:*ZKZQ%qYi.*IVZn[dkfM_W2*S];P!mdAZ*ZHV-/0+kAXWuc7P);#\5Rq+qk/],dFSm#8I91Wq$Xat2;hb4"W7,c236eh/c"=A7'-@%+C%FZ-&*0r@:lc=:D$B<sM'Sbj^1A4dpZ39Vp^;@]S<bC>\8/aH4e6OJfCCc/5ZLUm5]5o)+j@$G9+9F8k_C-X^6'`,oSmX0BP!KB3T*eF$n`,__CI!'VK00:@e6#X=gPnTulLrR@.+?O?GjI`Nb6pr);7:DY[nu"nS=G++.O<GB\!5*3;dLN&W51##\mQSlrsXMtFH/r\<Lm*s0h\]gfA>%8:89gOfh%n!7&otA-_.t'QFlC.JX9g`gd%J_4Ni:W7YfHKbt[50)H5%PNo^6]%rY2Om[0'7LellsMD6>l)2[=GX%k!E/3(iiP2UHR;1lVAeR[K)Al:hPHmrg6>Jk-XfWo1+W\:7D>>a^')'b%'rCP]U"k6KWEi:7t#9R?qP](:fm6+1Ha=qM]S/KR<-'ui2hUFM:D[NRXcjk'6lT'm3-afhiU5kq7S',RKQ=KRqYh?ZX5\Ht%^dYo55OYkln3@D?T]J-dj3k3&c3EDhS(!_ol2qHR#=fA:/(De1I#uH0bf;9%FM9G4hN0nWbEgRtG^)VONXegMB;:&NS_4;D7LfT@@ieN*:STU)\:FI>D!Rc7BqW>Z5Zh!iFVLpiYUGi`#K>gqA@jGN7*&\)V^ArWD%g&9'+X[N7^59L2<^;rmfX&2F&]C,2kU(.MKj6cg29%uZ)[k:c%f"jm,Qb:\_K!neb8R94Q>VYqiCV44q"fBGu$:!RpWnKhGCb2a8Cqt?OAMaj*Z:NFr[Jop9TtZe,+R_o9R80i9S.tHK[J@g1;=/i1UF[nM]Eja1,ln%cgDi+\pAX^UtLe*S@.^?(INu_e(8VVIAanL8Aoljt5Nemt.LuPOo#tX^pJ%W71R@'(X\Rs"uRsFA,@+e[R83!EZbbW?DYYQQ@En"cF7>Vhffq]V#Fmi6cps!Q6)+LP>Q*Nh)cH;*:5j>Ad1hdGOSI@(sr<o62Sfg+7b=c%$\jEpr5J3Aa"bBX_qda3.<Tin-oujgFl(mi)Un@`e5^6$6p#Orr!@(UMT:a.GkaKX"l3aY+0di&"TRAJW##Bo!\gpuI$SK0(aqN!1T->dOq1pZVo?2+9$_mIAs%L#I_L-c+/sk!'=5Bh?/4j`5WeE5)6s6G>&_e^#VU;n.Up"+S[]&WMbh:nBA[FL3;24a05OT>:a2&)[ghNQ#TBr?NT+O\n/7e'nWE3;n-u<aq`JP#9BlW<N^pGes>L\m%sVZYKU#ldZaG(<%eBi0?+5#X>e*AD@Xh-"+To?<rPm=&?'d`FAA=hOP[XNf)]-Bpe[N^=\)phcG(]h8eh2re-HT"Pa2Xg[;68*A-,go,"n]]@Vt6rn$,<pIL0'If#4R(ASE1p^T3[ph*(]?h$'Rd()79<>)6=Q4-^mrQ`^'aaVP=bm1(9p(ZW4%f+u+/BZIOgQ'6^?'F9!_X(j,/u-.C17"*Nlq?jLLI!r,7@rX'k)3ij;Qi%-&c&.P-r6re2-[-IkpP"MjQB;(l6RjZSLNG]'?sRSI(!51D=O85f0.IpKBt2U:`H*kcW9AC<81arBm?:"[RHk8`h4aD)tZOl>lkm/kHgZZq>s:O9/S:1rEKDD:nP?NfA]_/0*Sc!k^,P6H;A?4"&>ltKk\8'e(!B[9;p0r\9FY'@j".qksJcY0;\!UGG$0j50L:HZ68n1Ps/uA3pO%,U?_>XbIW!KW/!duqm"`,-02V-SElGo3o\kfDY[_Z].E:5V-jNCqlQ45%I<E\a`FfTe4r0\X@5Lc>->2LM`%,KeP](*/SiaK=Nr/X3SfgA4^2P:_cjG>HnO#R1RC2NmG.PHKM0ijKU]"tT!ZRG<jbE)lt%cilKbf7H^`Sg<HB<(FK4lFa(d'XLhRP"Sujg0BNa*U<cuqj[LptHF??s\(h$^X#N9h4N2q96().A3m,gqu/Ic8s6@J:->`1sL]bJu5O>#0A>HF1>N>T.FUXt%51gd=uC9c>9RauiFdVE4ro"'-+nf8>[F&lO(.LRZH=K@aB\h:f;pPb]R<7OW-/L6:_C:74tV<]l)LeFoPKdgN6RTdpXM5Ks;\F^[VK"S8CNI6M7])H:&Rl.)AP,58Y^8$[PD:PI--5GW?:;7%![@u2m+^:"M7m-Wkcc5%O/i5.qb(XXpcCILMmlg_g9t:r)eogp$?S*R96ah#b=!AYCWjp[<#ZRk(foXhFQnOnf#e&aJ[A*fECrgC3b88Dm`&_jQhsga6E[;/Xop1HIIeA399;X`~>endstream
+endobj
+% 'R314': class PDFStream
+314 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 4060 >>
+stream
+Gb!;(a`?/pp?jF1"3OVB,ps>M[?or0nflg;bG/1^bXE=+$$A&ddO*Y14't3s=@a"Y5[!A#[O\6Ep'&56n/Mh(jL7SX)^G^&^-]$K/7dGtl3:CoiM*AKkhXe\BA_npMkbVOZ>F+>&Xp_LKha0RB$<uiZ9<=(r#+I.<J'AQ@cjAb"Bh$V^k=pCS/WN*2!OIVNK,Re-+`pd?2[11s%`TA'-Fuig<=B"aqaPJk,U9S=XLPpQL#/n%N$m,)N2/<>cO)dTK-VBf3sTn[cM#YYOR-'&l6]B&Y34c.?GjSmF_S<B>.39Ebt(gfX*IEYkJ/-mKhZf([p2kfIMfd4muc^Xo&8#]Zmd*Nf,*m*K#ZS_SS@$L.G)d*_MU-T[Df"o`!n(UduOp.8<%scoi\?Gj&`Ii:WK6>^W,$"!:mFBgI)$qXB;do1)gCp%cS&E':Kfdphu<PQ@2J/6T@GOpBgfru6YOe)/F+q7pV!$\Z4+$#HN8j)gMn&*is$L-9T)jlPOg1bCR,?Q\J0`<Eh:17\%2qB`_0@U)T1=KL2nAo(6[h+;$;J5XkUaEZt7e#/Wl2_8`b9`6e9kG4h8EFCEO]%8ThmRPadI:=*Ar3@Bo]:c?c/u)qr@s!iGT]`*Z3/j<TP2J#T[3tUNOuE.G2#3=@T#%Tj;ZHae*gEB+V,U+i)He\Md3T3HjNn*`n96a+!F(-#0^-"u`W7l(#KE3t(iHQM/$+CE+_uW'0k%!#)BaKFZ0IH:L/#;'0K.]t)E[7c;"CGo+K7750n;S\)n;.8.hMN<-1o7`P3TE@E5NrR,Zo[oZ:[E^IdEBG:A)&3NPn*?8HG$J%GG\/)AKI]JsOG`:BnuN$/2&[C<d/YVZqa]'nIMG>#A*5$q=Y:&$ga++?c/".L=B]YY?Q86c,Oh!uePAeR6e?QGUVWD<ePF'tThAK+T%7_`Z5\D/(LQ,b1/9UJVsBUDFN!7;kRTiK+H6>agJMOMhJsP=G,XN53/SUc'II,d,LiW!HLhY![5hXN%t1.RW!Z)[3<7-Uh6/BM7cQ`"7,%Dp-)thX84Ap6`iJT[@`_^U_[0X?KcZ"I-U#!<H.,;.uc8<a\AUJEQh*1:L,:66jIU!\4lg4PnD.e>F$iLK?S8%>-:&SFmF9\=S:$q65I]?5J+%DQ&K&H3E0'K%DF,(kS1e/ZF9G%]]oB6;h0LbP75(173K68u)+iNP#pX*(A!\!Kh(W,hAo/p:2C?`qcno$]%J$jdcft9B8L@8,N(AH;u<YpM(3C.p^+Hd/^C#\=OuZ:p,X$%//L)=n.!*]LH_eqXlm+/A9&(A(qZT5lot1;6NQ.kq[ODXi@p'lN7314>2omHbK_P51V1+S(Ye&3SFp1Tt0#:!.\dl.AY#lW7d&AO4S`H12iRt$7V,>C:5>=lbad@@t#,&OsaHm#Td.GQVQ//QMb?3)5cTB(5qn*&ZI"AF*;iEY/^8(0Y^5AmghO5N#Ch!LQRYSV*PmV>k<gYZueC5hKiMZ2=A*sdr9E34l52Q.):Yq(aV-nrA)OD!aU9McQAe9U*pK1?&0*Tp7Rm+7t-"%5M`+$#*g-d&o'-%,^rmh3%@N?&jg\s"5nmK0pVi>gT2ft<K%CZ+hPY$3'Tl$Q:TfKl@Ss_bt92A.n0\;$V]Z:<7QR+oh-"r_,h?/]_%&ZC^ZF((iB15]^p4B.j^#"U@cn7+!Wub67;i`VO-*%(2if%>f*ounJF^=4=6?9X29,bjp-?eF2'D*Nsj;6\@_kQ3@5pr0R$W1Zl]ER*_,B4Po5i(A8)l8*[*.f4BaIp!j)$Ns3M+nfq"h/>kZCGg@qNVfX>dVE>@q&%i1!q>bEWJD;(ftL:^.oCoV^la7"jb-qg9IdV#s(ITO1^DmX#k[%?*W5K$_XN.pp]SrQOsn/aljN[M!U,bm58MbVN:%\qNXQ:RH'`[8h"_ru4Y`V@uQ/;47`jRX6ps7E[?M3c?&B_eNoG8":]Xgr:"4Pj<8=IPfK_J&-r[:9P+\69oZo(;k'alh:)B#/;$f_/QWY9/1jEe,su/1fP[dFZpWhNnQkQHKj<)_JdQphSTR3J;SqO"A36)0=Q;]br+2hdYSi$c@"tf$#l;nPh@,ZY?\DB6$dj5`6Ic?<,rWU*.djRk2POc3VaX+hf+XN'M`4jp3];&..qZ$4VQ(e1>A,8uj1;P]TrKA="o`9mi>!U8T$bF?>eLjc#F)k2HER6gi?,fs,qWY2Lqc=n?jF5k;nS&6dnr"d1MILX8l((ubpRlPVM!Ruh%`pf%``RS3Hj*:le3RX/9&L`4o#FXnT*_ITJd1IFiAEqH>TLJtW`+PUkR)B]&654V^qheqI&n/GBF;*^.<42S\4O(^ADr.KkLfQ"R-!,G7X,/;'t/V]l2V8]:dDm=1+cR81?Y4rO<VYj9^,b)CN;+e<!JkafDV%TgT%;TZ2S\MQkYH*t:BXN;nO,iZ5LJVbi7NFmnak_'YCedV3=rm0P^,_R9/dqPmT@nO;^m#1g>rm+.LBpChfq_Un1+j9K;&s7IaGl[ZS:5sdb%.u"g/[:rQ7L]6JY.dj!qDIpFfu4sQd2-9dXAHV$usAWO]6s'W+G$"fp53i,EnoZMAfof6^+1ZV:NOB/RrrW;2heMdc/b%C2g1qE_P5$q,U-.UTBTb3&QO2S8+U"diiAuqhSaH23J`Q-;fEE@/amI)pMlX94ol<J]4$AO`4k8CA8Wo"'mk5LGe!829%TdKk*f-lUg-423o::KksAElUg0523o::KksAUlUg0523o::KhO_mp#M+qG)K-lIZGZaO"V7m^D/G<[]C%O3:KVAOgnk05^sE6o`;g#(If[DBQ-g^VBp`8Z>P5`\44s.VU/&,!1H57EK-j;9qe%7#rI>cH(rQc428/""%/7BUK]#0&ZUr"3&PBH:5rlB/)W$sL,`j\d[bc6;lhcF,rA>6$Ji)MdhKr\,rA>6$Ji)MdhLN&IUh.I3o-HePE%[V+*G//PdA[!K%_T/@@JK`!c(unN:CLZV?X`LS<b('r#(d!5qapiKn#%GUG=^j"m2&GD2e?gNn(K]4^@^91mUo&p>us5\828pLM?Aao<')#L(i>3$u7SrUs@0";X`&tIiFnE>Ea/3O#DFfGP!'G\DanYm;!]qIUl8*R??l`T[Sg[n@i.lIU8aRG_1gJc7-mUqoNhRO,dlp@uo#8cW%u2E@uH4\O"jY2Ur09>2bHj)eF<bMn[s)s&V"H)r2N/P/U(5F62._^sTPIT2W]oX6p8!W+i\7IEj$GFH46ZCRs2A=TC*sl'f&QD0+^#Zof*6?""F:"a#9KqL)2E]SrZJPP*8dY0?,$&m@Yl?]_*qT#D6')f%/M>?@DtDm&B^7.(-SI1r_,qL4cDh]q,?*:M9L$r;1[-:T<:`no^ffG3Tsa5;&"%JD4&pphK230+F+ki,ZCCiL$BYU@+oFD]>TWqMR-_Ulh]0V]R=qX>:P&["\iofYK_NS-NS)e%9Sdd=354ebdkh+$L4b.n&laGqfbll?fm:#[s.A37*hD6l<oUDVnJ(gS4h?@9>5$':[qO5O3cO(]Wo3%WFCo1N1"4W&lgF),q#O_$'.KI0751FGorHM;\MIh0(rGItJ3F"SanojY>T`)2EjS>:J!6W5ZH&90D"G.ND5BTi#Gj;@atKZ0WnaT9KRq8?IP#g)8%/XsU2NubGJP[o"'B[W:[#A<bV?"gO,F]Kkm8lfE,b*H1*\#VR[8Q*tA.oK+AX(R7h2qC0(6)&A3T,1_IKfrH@h"r8@,mATF8\=h3ZP*;dY,:VF;2f3`#)dA`do)$5jfX9\-.UA",Ue8r4Ap,apG48Y?819NTX/"jgGl'XhIO`oCl>>BL@s^]]`6A+:Y)+uDKb+oB1kAr7KqMcIL;gFmL;'7Ghkg*oE$*$?5Vm`5!'P#*7@Y$FKBfUabD?*PcRD<\a>YtNp`W$LA]t73_IZI^88&bhL11(LfU#h9(AHcrKfQNLm%S:W<$\adX^iB6bSqbCU-:B>N@F2f@1N`_78heZY<Q8k@;FO1A?Tn#QJ[lQq/1f#ueU7s!3.OW8688fc=&\]BqZR6`(2Y<UmrAZp;s0r>u>%CQn~>endstream
+endobj
+% 'R315': class PDFStream
+315 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2874 >>
+stream
+Gb!SnD0+Gi')nJjr.c;BEc,DgI$#hbT:BuOb?Wi0[;qg5EuuM;P#.>F6]b2f^]&BWOs3?.d#N16AF):a!!8)7B6TtRd"W]mg%o=m"2(/?GHYhe*LJFop+-_dDrA[ho4K0;[p;`NH/LZJ5Jh&:TA+<r=.`Xpd']DVCn<l/<UG)WhjTKo0T3cU/KDe'Bh.&!d?[/uPqCtCG$i&O0:;]4DuZm;r_WRalb53i4get0'Csf,E9*!+PE%p%d.4*K&SZ&Ur)+l>'!Nh8aDrlB/j^`?%Ej#0CemUT(3/\8Xmp*;)_-3UYH?94S::;lLPX.t5U`"4P(h:!6G=!;%tQ1N<uaVko5)YqR.G^CGljHMra>MlVND-d/n>#$s%m["/,d"b3/uR6c@UD))3+nV$ULXPe'eO]/Mue?%O#2;J6.'0'QG&]Qm]FIRK[uQ,*ZlgQQe.>eLOdAbE=F[&Q=Q;OGfu8$9,ufE"04<=^I\"E&E/NijpYVf,WtXkUIB'#JO=0!7.<q?j0.<-tDq4b\H\Ip%J&3&BHg`P&_WPDY+7./NJ[1En"G-'d8?7"IVqb1?#HH=h%lXf4kRO8rpaQ%DI2N<gL>8_+]a5Wb,JI(!=(p<A3>!+)g&M\Ug.>*)KkI[&dhM16]edLj5d@O0kSaR/m>]n>Q1CGF[\Xr<N,%5RW</B-L6L9@A;4P>IW&U6^%Y[M5[H6V!(Q=Unsnnf7CmfD]e.*`STYhk-EqG1OtUJmREXl*tGiV6\$@;cDTJQ?>#)T9HZ'Ot`?X>/H#%;\HI'mc_IJHe\;&A0faZLga8eg[MRB/cloE"J)ou*,9gddA)R;kZMTe7g+iqe>NJ&n\`fLBilY(5oi&\E3?W!k:qQ!UD`GI_T4]>.Q9IWksDpP+O($,<ba'V!W$$KG:`KXYU$emr7+m^;[A*`N95hg."WY<Ud:,Sk#6-\pQm5b@XM6$_L_G7qO?%,^DR8NEfh'A:etb0TbJC](aql4\pU$,849/>bZ2g=4_B@h[8luY-LTTn1gQCB!tD/+as+sU!/$@U,2OFFD$u\\!J;i<8:TATmPj.23r"Tno6@?FBr'dT5o1_DH"D35=X;QZR$n;lF54d`CV`9oaoh^MfZqg:jkmFDM`#mr_!OkBdY4k/"gs,X_a856GV7@(aquZ3oII?4\&Q4#cd\t,eRSKrB=6tCcoD2[Y)A46J\5*>r)"6s%f2B1"lUi7_fn_RL`ejICMktI=RcA$PM:tlo8bCV(HHFc64BjS$H$RIF\Rl"8q1=7NVj%#[eaf9#jMn_HReLbPpBqn_]d$Q-kaV,&Vj>56,]&RY7o5DBDO8^-O321dE*c9`#V#ipjG^`3D*sU1#D+-'k@.(RPJ6S@eSKje%!`Nqhdb`iRCDU)*O["3eORoI6]UJ@3%MW[`0=si,fM0Zcr7>h:Bq*koOaBR-[8T)MMnJ2#]+$U:S^rT52o3!\A^(HC_go35pP/(QleJE)Yp_4e'9^a9u5^H%IfZ"-N>rOHQ%f"=ochH("Ji9O-Ae]:3).0WRf*1XZo(A<\P1KZk3W6UNP5&sd16<HG]:HP6i<<scL]R;Y.g>O^ZCU%4'H-[\j)o,9*UcHM0S"H=bb:'+[AMgEWYZG[pkTdYhX/Id3Xc+4"tCnIdRo)MHgC('l_M9P4?Ci7BNQKN(n^eW];PA/TLUs"^N236YH6>sVXLZ?GJ[EZAAIX:uE!>fOYaV7=NNt]Ts@W6b9E]h,,=Tirh]`^-]gF#D%?D,7JdPG_OFhgr0?,$E'>.D9F""0qp<`VYhs!R;+EcY67**qb:#[q=S`>08[OeQX?>]^mtqFR`meqN87o^L6\0h"9jek0H<(Za;+Z!3OPc`E%Mh(?+o:H`1:7uI,%,L+O9C6(H*4_BrPDtNjYOMR\DSq#._D]_TS1cUQ5*4:Sd%mRh"oho@N6or&!:!VT"3UY65:V4)%Lq9iq?3a3,EUuB8e\&0kVm5[ho8'>,bbU3OdBUI1/s=dUAWS-:lY/"3EatdP;H\Qe>Qpkq)&:[OCCsU6#J58*2ug8C0'.XdR-r:n)S2q8:fJU9ghtD!;$s4;7)%qn#2.J!215aEfgUfHA1c&VArdqT#%qC>7ja`d_kH1OE+8e!IQ0F.Ih"rW!ut]]YBdC+Q^J,Ge/5kpW.0DUSV?[@/(t=:Vdb4h*t._ug0T2(KHN5c[DI2jLddF/AcWT&PX.T.*eDtFN^$SPES,>fORX/T;d"h#WDCNQbOl?rF++)1MC9Q[8q@pk:+UCBM5*m0]4(eU7VS70S;<,#Z-K(4Q;gprLCDQpK%ZpHfkBk>`q.-d/FSX'OEMX[3r-F=^1#Dmgm;cgPt3_d2r*ps"0Val0T=PKJ8CD/!45JGmt9tBeT]DmXsA>pJ'c?>4dW@cA=)7JDh3<iWViOHKq#e#V@7Nq8ku..]D?MQ@iTQPJIYRWOZ^E^&52'`HY^+T/=pXfT$q/T;_6q*rOD3NG45M;6(b[MgP5fZr&EV9Y;240bdOas=Ni]Z]/T2#`9a'/Z"%Pr,$gAqP-FaW#0'6Q_]u;<)>2%2A5/,e]+8k[>H)Xf,Eh'HeXY%[Uq,87%JK+Pg?Q-u&4nM)WZIq,pG*?\fssC;MMf!KN:hE.@StJ\&?%hS?N\Q6Y_:&MDVi=IMR`;m+/!f0Q/$%#]VR+o,o8T>/s9%K<%USR9asn!\2b9o)>3d4jf%t1PL%+E9.rbjKZ"8F@qjA[j16,@^+lNd1?S4(NG=^(HE_C#@($FMQ-1$$h7YB6<I3[g3N`$/i'cNNkWP/6U\'koO^dPd.3O=BeCgb,*UVIaUD^W`IZdr_8\%TEK^)[<A[ru5L)$'+c@CUQJq[c9KpU!N5g\s2\7mPt)/3]9Pub:A8T_i"i;'_Z!gRWA$N~>endstream
+endobj
+% 'R316': class PDFStream
+316 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2964 >>
+stream
+Gb!;fD/\1M&cNgos'ah=<=5-+8\G>l#PV-R)=@*EB3h]0h%)#V-#H!:1:s=rh64S]?'6BXfqP#OE*u%pq6D["bWPL@XF1rDO)I7X']?09G^Jh1+2E71rm2V$r#bF;q<M+Sm&sb[4rQa!G`r`Re%4tbV-dO"-A0YU7^.=>$:jdTM'h)$4G%hc^@1#t*1pi5GU&Yt@"7eUHN*CCbWio@cZ]/WmI-t<bKksER0:D`bGds[BJkc<e-kRo3+Q307*K.C.Lj-!)69ljJ)Btcn,F"IB74/CXtNNG+=&L;^4n>O>_q1l*=qPh%G+&tBtQt0fA>;-3qHtBj4hHtLP+Q1Fp,8rGeobR-H'QRGWI9.&&8]=1/JAPM$H7!*H.A.n=<0-QA^Gf7)&!$g0j&;C#!U?EV=0`2acIAq]3?49#b%k(kb1JjBRiKEs5gS7D^51)\I'$BpS7Qj*be.DPT;9nZnBoKDXMEZ?ZdM(?Gmq+<*dB0#aj;GahA4=#o>W%Ygf"Ee,=_`&Ior<(8*N[E*Us?`u1FbHaN(DC?KZje-n)""!?%)lA<=%'1t#d/6OA@A,\6B#@#G2j:GQ.TU?^:,Vq!m0t[cN`S(;<![>b8Pn>D#`7LP9aW6!iZeq<05eT=-4uXLcaTFf)@BYU@n(SJ5o0U0$H[R05V8HJ=RZbPSXpC]p5VN"T1\+/:Q1:CXh!<KL9KuP/!:$W+Xnm\fOWSsLdoju2]@1>>IJo6*-bm.-G*C^Wr\D];T**1aI(7A<$Y0+9cRT[.>`:1G??YI0N&f@Nn7ba=(GK-7;,44?d^(/#0qX4J4&X)$c7t>hTbe4=P\$SdAT#BXt8"1J\`O@bG"@\ruGP`(%l5]d'f`uZ$_k/TjZ=d05*M"m)L1&)L3KdjMGrB2m^Y?FI(G%FF#UF64B^5+]HC";he(2a1LbW0cllsX0W+B7^fK0rnrdm]g%q;Q-lm4]9RH6N]E9rRrG1)-t.k3[hM`MBYEks3D58Rb)9P:U\d!Hs"nQ_-Y"UC\d7#DU<KJuDX_7^/4[P0&::Za>&V0h5pR4nbr1.jhnlX3dTfIC,1WO4/=RQC'#cW$>[ghkZUX`%,8SS;n6>QL$N64PCDE1,Bo]_qJh58s2Cp:,%L6OA<9.mTCstt"`.G6Qpf;h06,^j<%OfUL:`J"DN(m]:;D%os7;,OJI^<!u"RSF'RTjL5"o^OAR=g_84%Y<:"1"]6_s-*I9";"]B:e!Po0U17:erFJ@n+1#*lPi^W-V<5Q;3)P2@$OLFQe`?14bSZKP,'HGJo7)!0r6`74OS8Urub)G"TYkQT*@0jMsYk-hR[23pu>egP3W11GO!trUTpQ<t`Ahi_=$0II%D5;urg,U)rr^q^W!.4VRSaV\DbfKe/+[=<LbMH)>[i?YM!b7SSG:Ko-B7I3Y,eM+-atF]coE>OhW/B6'SM<PnRC/.CrnpM\3pl_X;G9N?m-LI$@QL+2#on(hD@+BPIqW.M(O:6(XYS5Suu2ct"[?C#oH/GdFgr'r+(;]cNag!,0Lg,fde_XeR]<2$FP"dAeS_tnl=*QOe`@e\9EGq^.sVpj[f)kag-2=oI9QH[Vfg(gs__0]UrK^GjUrEcgH/L&YhWStc[]@?F9*XkAR0Ym!<qYIufGqeg&E7DC.^&1M2R]7bA]Pq6)@$OE6!l7M]cAGkh)^?G%JJWeYMJ,u%5aa3J<V<OSJDdEDE=nL[>.Bs!KW=(&I]J?:H*[^T\Y`A+;lR:gQo/SA>>]GmQ]MtY#G6:k(T3&&Lh8;5<?(7(9a]/!Whr>@B<<`^Y1UlOG^8(X%CF:LmN`[1#%nlC:MIiQa#5:u7mFbH2"_$dCSB=-S`jL2G=R-Xg[H@A^A8?SBF88$Dm^=t'UO[&4FpVmPI;jjhm`JT#NImV546!E99gc;91=(]I<MeO_njP9Sh\]P'j)2k<DA/1,ad/(A:Y>t!.$\+7+lm!X9OLb>M2@"Lu3JjLk==TXG=GjLgop!jHh*Ir4rBm9QWd5)OufM(Q/>`$8WQ?(g)6ciM`3&R$,;tmX)iqiVa_=MnV-<bj^KSIQ&db7jj\DZa4rK7Dfh+WZgQQ>,jumG!o6:bA;jR/PVX/"m%2V<8EtN"jQRCPR:4-(XMO#O+K#/mBVH0R)dW/EGp<YeRf1Xc#f;r%?e3/&A#3+KY+t*<2`)l;)K.qru6$]jI![kdlZ/60;VC6P*_W6I&ln[_ZjXUhU$(-NXT#m1dZbEPAlLn6n&D=Lt7g^bInH7_P2iMEd'?>0o*C%_2T,].JodFE/GrNVC];R/2$(I0Wn(;8j(]^`Xp(Gc.H@)P>OtR,WY3uF:595r:ho??bZtPLGn1=?ghic=^+fR!^a&7F*?=AW]Ebl[:sK\X]rAZ^-,n9b9^+si0mgYlIK)QbW/<f4Ou#d'dBN=%4f(p7s^Q/m`OQ$/ET#!Qp2&[hbo4,Z&f%]DFpO<<]o=:[eK+AP>7u;6'qB,i7ld.(Ukb,a$nP)M!9.bg7t!,VGrC#h^VH*V@<8M#)o@1.ciuc,Y=+*Bhp.UDC>H4Dj<'V"CDH_:J9mJcGN]dpbAk^[Q6$;`EZfF:-"L@g-r*i$aK!%csC*@02\')]"kA&QqL[d[TQ'XV'e&ics>o"$OQ6FMW]Xp@DfLL<%o2rGl&9ur+>h,3-2G#R@m]>WT]GWNq11t`2`KDoWE%./Wm/P=t,N61m-6#%-`OC$^?unaK(%^X(0-5[F3;5L"PU;EE$5I3*Wr.&G*R1Qj;5VaKbp$Vj#F^-0"7.l/;.IE@cNIX,;Rf@\@LTCFeCCn/%u/D5sh\gR)M)802)"doo7cVuBgtI`:11@m*.NL%Z4n6u"B&0Z4TAcUgRTmSo9OZ)=Q!dg)\.-@#>N%k4A^5u$=dIPoo9s3bk'PG0;H5-6!&9O5&lWBIo!=p$WV7a,Q>6YgR=;RlNQ`T%K+K<,TIJ3GD3%=4E.]2$C4ldOtq]l\V>eF<=b+2ZsI*<~>endstream
+endobj
+% 'R317': class PDFStream
+317 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2526 >>
+stream
+Gb!;eD/\/e&H6"/s5C18F#Sl^AGIP+0Ha$:Zrke[[>/0mL4PY(S#ms9'P5nnot-u*/B;[LQPLMQ,W6s2a60&+H]E->K0PCplULq>NT'+X#94Q";fFk]_>#<]NupU_@"4a,p7;Mlb6C+WAn0VI1T)4&K21$<Ha%nq#\S:[Ka)AGn%gsba'j31kGK%"X@Gp,m#R`(bNV0@nN.S;A!_[TIm9/>hV>SPi-Io;.;.LM:!JL:Ygu^@3F'LR<\aZAFW&uBSu\\i#i14l9+n'19U3WDrZ$;#:ZX.Vgdi0X+B-A@5\Q8L6DR)rlo=JoJ0a2q/->\sLM:?U/H@.mkls!sQXk;9%Y/L/JWBJ$hJfs;0jo6o_3I^AoG--gUSXS@2Qf:2dd56Fb:gTCH2K&pYCd%&HdHD3Dhnm`_!CZ]6QaLF&4W;3YUcu?^&T#sTnl*Q$Fejj3Z<Vdf!W6?>5/:;4Np3^].4:5-t%jO(a'Ag8a_ft=@f#Il^#`%Gi?fhaH./3e`!Qseq--Q:qdGqnZ>>^VL=T8_*,!)jlZTbR`"$,fn79/*d1q->R<XU)K?Vi>)4"bH%7_1dlD?lP2.3=XRC=7[g<X!OsH9@iI7'=J+W:=h&4SDJE:$FGc1A?;Y`7L_9BluaoDgkBjf]k5M2*!EF4$X:Q[`Qp#EL\\Ns[u10bHk6o,U8i0ME(ME-?<N'`oS:_;9th@eSo:)4Z<`N@?a9\caeoP7"f??Faf)N/RpD<,g^Z`%_>'masKMS15D3O'U>a[sePRZT;8qRNmZ:juH5e"!DNoAO=pWlI_`^=KSHZ+5Qpdl_sq=ZqQ5SH`W<<)J5_:I9Vm+:8gs0&7AG@NJ)_e9Z$e=`(YiMunQq%8.?tU:E+*4*ipt;P,>5\*HsH(sfb/P1I&_cW>iL9<78oBosa,/*V@s[BEM&VB7L=R\JN`?#kf<mTO1/:;6KD;A%@L#7[kTRbJrj'2hML(7K7M\qh<rYmr8d'*64&Q(lA7pKH[@6*!IAd$A4V$`U7."R&p\0Lk8_qC(CW=823\WQSRKQ:<>8D9,Vf+&n3bnB*`%V^VKZ^'0iH[k>r6`X)[!dd:RkD@dDDYg\8]=*=3Ooob9kW0u6"CW7J7r!Y7!VXCHB-<LkDVuhV\a+Gk:QIQYFQ,22mP)N\tAJV>m;rLkC[ZFs$(0rg3VAAZFXh,rt@ZRgB](kAUg)O\mghC)o4uH./(j)t>7e:.c,3-Q70`pu]fuio@?bW*Q&lrS4HC]le#$Zut336W58eGD2"]rC;T^9t;"4,=u5s9N]m_:-.GRYRYEucf/L9tadQ)^gWZ$SB+]PSKPRQ]&5+bR0C=cs[TGZ5PK:RmEG/q[N<HA?%gS%(r6?iTunWn_`.c[&HTF\\U#e,MbNrF/7u<ftW)#*nH7`kFro@Cm_Fe&oXcV2Fa[9Vq-^@dN0oX4L>Q5op`$A!YmP(Q=4Y6HQf5/+S,;'1#OKGeBRH]>gdnc[/06rFe]H:-_nEm_-uYEs;_^(E'X8LUl:\[Q)4_LrXmtFJ]nlp=4>d#kMBIHLp]RjE)eSN_k\S1J3nd8ekR&\I.brCjE6;-T?QoNq]2fUmKt+km%@h&GAh.LsV-DL^O6M:G9K][Y1DpKNS[4Q.B_7W\[Tf\VEL3+b0EtE%Z'3WnQb>f7#%=,:D)%0Cde*BDgN>;tJ0*[9i#PSciK8VkXiD37pkJpF;1-9'g5r[gS9j"UJ%r"V464.18EsYgbMbCit&-@?["o3u#KoJ.tr;#tT79c&^-kYUmOefN6e_e4Zj$r@l-TDBj,hG71gU31'*7Hm7;K(PR2fljIKdph8!]I-as3\(S)>S35dXV052$CN3Yh"-mQ+8dZTQ&94B8=ZPs-,"k^oMQ\OdqA+&QeK_"@=)1J'Rom4BIGSTq>86^HRaA\PG$Mp8:aO][rE6X-qCNZUF^f(16?gdhrPN1U"]<V3%u8mh!`Qr2+K&J:d32bg@g`?U.Tr+SM`AgPfm,G6Z0*n*iFMYbPFiadb!R(@0Q@k&:s5Lm`1DsDd`CG;02(\P/oG9NX'/T8lh`3kb%h?JVR.sDWKa-94R&f_m5h?GE(BCZRh3N1_9ZRJ;(/H6>DE&86EPb%\)#[qQZUM\Gg+&)LW6Q7.oQ.3#,ehi8):;tIl@$adl\79V;J'GaNl[tc`/9;-`I2=\2Gi]WX)UV'pfQ2O0+Jr1"CD/P;1M]ljP-Q%&h(D;Wdk.0rRY0H(dN<K669g4ZQ_jp/,n?om=_-s.>S9el,#u',%"sW#\hg/9F]TG$ieT[Bu=[G_kI7'%1eQm!/cDI;\F,8h4"A@roLK,Nj<'rU8a&*GJ)m*X"57-jRS)??r(/d$D*>4YYE#8;0WV$ln`3@/J_>11)DY/a.@?k..n/Jg;'8"*acL_,!V&e41MZ108SIA6AAY+qO8o`H-$T>7/,3CtdJe-2>)Y&FMdBgi-QJpP%GKrV)$=T(C3Ff5J^Eg]#T?cZ"G6Z:9fj>8PVt%pAc'L_<[OY>fm]'V/gJieugHHLl@Bm]l!Tiq`d!5PbUUKY/E~>endstream
+endobj
+% 'R318': class PDFStream
+318 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2852 >>
+stream
+Gb!;fgQL;L&q+ths.Lr=P:[4p;AVrp-YI;"?*SGij^DpPWIdZ3_O;``!0k]TrH88g7?&W=C-30ajkE<OJOZ9\h5?_P@#2Q!pNN,.I(t2EY6"tr=KEV^ZS=#f_TTpI-Qh.4TY>h0L+m/c"J7^L5(LhLq2Rn];%QK1p[ecp)RLGPCc7j",(h"GGT#,2*@!J9/Vib\?Gf2cr>$1KK>g(1p:n,p+.=:#\S4bPN_c$`]+(=5k@@2ss'K*B\.57SR7;AUIRnsoSd0]<r'-i0Bn8XSnk6%+GQTt`au-Y+je)tTch3"JE!t)&+QHJnK[i26^Z9)iJE4#oaT.Q[h+!4mqV++0GJe]>i90d(?i/H)5CJ^4.%ISV%T>9WbRi227aZkmA%])B.YXp!E;+9P$dbVEg4J,dLm?O8[]nk-.:@ktEs=gT2/8_ri-D&^9N\B:.rrh?0^N-r?cdGi*CaiU=8d*MnHJjBIH<%,"+CtSPr]ZdjCm1Po>^ac)mec[lA\n"B0l%6OPRnRrJ!J>.(%^N6m.o*i'ugURGs"O$D!q^[fT/H1e;`%?L_,_-K5K\V9']Z"JHDV,"P"O8:a=-Q2)?J$EX#9#Dd>"i(CBC:>-/iac"Ta4.c&Oa:M-lRBL1^Qo<7)=Q#ob@4W=]_/kZ$r)ALMo#a7R9;96XO4,ir"te_:Yd_oBd^lcHR<SqNGp9[0Ym2)h.0f8.5qg@"]g]X!E-u(T,m58;:PZt-7P&'p#!_NmIkN;#hf)i6G9&^>j1tc9!Lrdk+eej<ARYZ.6s_naI8@Y[b1pE_!,DVP)!$S8.9P\6fC5Me>/<'lj>pf?_SHX9.oODBmMBnschMiQ.j--!>AUiDM(U@dlYRX=OXlgZ_9._bL)+R-P8#SmP4PD=AaBj[\<11'\?YhZl^rWQqZ<'(K1#cFacVSi4c>quV6tQOHaj,,8r'mbG*RfVbG^]^TjJ#.(<2Z/m.)\[GV63?#og2OXU9*&GLK\EJ,UaJpPr="kSQ\'\B#r!kK8B[RM],$1?Lr1kW3b*)6K58:7XpSUqCFo7'h.<d$`+18!G_eM'-mJ#>``!qs:eI_?d<lOVgU/7&&iNS:cTZR>K7<pkQ`4jd]eTE_KJ(S21f",T8jq^)/*<Lash'6Ia,[^P1_Dh.l&&&bD^nci3WlZ`dDe;L!*SQKW#V!;/R&0_rpZnl%rd41N(*K*aL!"coLD*uIS:h5#$4mc0T&h$N66V-6r+LDW/dM<H)!41r?=k;*h)qer"=IP?3%dFqo:A'I&A@Xk,T7OqM7U1*;,MVf*t:Zt__Ao1O-bFG.T6nDCpmZc^ZZGLoTpNR_1T*%s_[3gU=>+)[833LC\XY=<6!qgMa=Q(XZKjs!jPcNJnJFoH"3j)f)5ZXa_@WH=(^Q01lYDjbb]t8:gCcE;.B="AU&.Gi(N4^g@N'a2??F=DUlPHSW/!1cnNo@n7.HA_&[\Fubo`;6.WMn5=rQ=`(hfsiOlS"1uNj5R[YSG--EMmk$@2];YNjS.Vj?do36T`-RU=MPh,iGOs.#H\R]$P/dC8K?Xm@9OpQcAbq\DNd@'19J>moq?melKe%b&u<"ha_NCh/O:`Gf[H^PaY&d)UF/=MGt=NU&,tHEO+.ZQbD*gIOA;62a`d</XL]7J#9Xl\9dZI,UtG$eJPqc,K*)IlO7[gnI0ClMWTqk?coTb*/n"H*S-1I!Ll4<YQe6&76i!E3jkbKX@42BqTP<!Nt$;qGf%c2:0*f-@m=JsibRL#!rBFT`$mW9bW?/,(u9P#1Vs@p6u)L+91*"BZ2LHF9+)H0W0SD?539DB`kt,+kH1u`N*8Taf#%8:hVq/Z(\K?N!#00lN6EOnKM:$X9)>IGd5Y[Q)*\)+#A?chP\W?DX*ee\;c$64f'1UorTfAA2]XKN)Et'PFQoN6KtX=U/;HBs<eZhBl#),"][Lu_<GP$(=;"G6X:_?kF=;8E!N8+gBM_W'4fHQqhNIT4?aZHA[^j"Y$dDu@GouAG4#^+uA$Fe.q=nD9YgK5[_P"`.$O+7D#`pn")(NPqi5#j\']8^I<*'JH_[r1JSQ'CPDIL?bd+M(_(-\5oNVE#WWNW.@UXK-YIMg=)7DRphOt2fS"+fDr2H>cm`VMd6=QZ371bX_@X":5FCHNVp#d#jQ\E/'CJIJD)#Hj@A)B3f9O"'u&ih`QaBr$E'.QZppgA>Le0!A@^>V<OQ8?'u/Gg5&s%/d1%?EKL)U1(6]r-8N!l)OoUO:tfF.&E&L09M,dAME&jp-ei[*fWr%KuX4=d31*@:7$-#kA-?IZ#DA,r+dmIH/JB746$2J1]Zl#1>WSo$!/LcI#9[#H)fUS03)`7C&eO```7=[SJe<=2P^&:nb[HQZ@CJ2[_$QA>!j;R<?bqfSuKim&o:l73Jae61IA2R6C(ArU^-2kk'PrB*ba3V+6$[U7L\0m<eot#_/g\#(qH1WJ'tu;5'l;fH6NX\i8QH%j<(446J3I@7\=\)"<uDg(q2_j/["IogOgpP\j[Z;QH&@6hF+0,N);uZd9e.$?o!DeIo6V[,F-TLaCKaW,(K3bkD4i.NE=Gil%=.8<;n=B26Sj*Cf/f?==K4JLa8=d:aTbfh6^Faa5(>Zl&60t:;_[Qc,gh9.Mtt-P0.,UF(q"7jMd:7lGAdSZE;Rg.kS\sP]Bp:6/[cd_-3T8ZP>MZ>[saOV+'fM^>7^'Q\ipW^nKU[@4Pffc63'6r9Q$5VnX@A>qVuHmiPie(KZTkqE"bjS?Ft&eo+0>7ErnrieiRG+Lu6-TpI)n2T0_.bkr(0b<&31kHct_h0gf'aP\(GkJEfnps3\,reA"VFUisg/X^#Gs+D4V;SK16DD1qD"]!TrGl$M$,?#1$~>endstream
+endobj
+% 'R319': class PDFStream
+319 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2269 >>
+stream
+Gb!;egN)%,&:MkuraEiC:<#akM%lf[.8>-19Un)M17_1r#De%$,UC/*TH3.[]*hq=>II-cDGlNYYsT+]h6Ub?0&Q_!p_ERRP60[?"[)Z.J7&eD'a,Zf@IY7b?9E]/aaXQ?lVRrJ0oI8]F6RrMLI(fr`M6!YNo9j*,IAA2)oZVONF5UK&2=#!mF.(MMeL:rs"\BB&)nt@p]-5MIf"?gqc!C8];sf,j7$F2\_`+ueoPl.g],8(p.p=NG)cF250,djJUnlU5?Yd"!+4jiS;(#(nk9l3B0nTdgd*WGhnFV!YVq(p@<MWl"Vohgqgq`#rr(HhNtb:-0cL?OARRF5>SSrL,8O#D`V*.=-XV^?U5Lea^q"P)\4j\ZPo;5QYX2Iq0[\UM;B^j(2qEfe\4+1RQaoXQW_7-!+2>+#\o3:Q^O0k*;mb0F_Wo8h_B-K<kWZ'Gq"s[i)k<VdHq#hRADSZGo[MDAYT2&WC(2-k=)7hP,t3jh4!W8/A]X%6I&\Rq8G,@ad0]EPcimc,iFGii(lmP@!Q18o1BFi"V8P\jXE]n-L*mq?og0TP*/$:rd.6@>i5cP6;JoA`aYV&0e-_FX<=aAl'o[,1l$++l(\SYh6"p/%.(HHM2VnotAeY)o?]S!;3ucBK3cpR(_41\F!;'VBd"qaZFXmgc2]d&K-bm?Cs8"#K@ZjeAAHogQ,8*;5M8:^<WmB)D;Fn4"2lo(@l)n3u\e)*oVEk!enEfU`CF-!%9$?tEM'Q$j;ro=#O@g;ZMt!$RSU<Q<9q<iRE6XCA<HIUPiur#^A$esP3P:<Gl#aFJh^\<b2@Sr+OpM>klrD?9R:]dcldj3RT0R7u1\'Vpi`\-40<S8,/G=]Km?9p:=]uG(OUHf[TVA=h\^dgUF=6mQQY_.5@bhR41D!%5H"+A*G$G;j.ms8;)qfdAVp.P.;E\Hu:QHg1lVqn9T37:iQ"$UfC`S+W!5'kBr[\GA?lZ8"K@+@ckbBK"M%UJ$Y;gqc*9,*8ToV=J7eOC=lHsLos*nO!?ZSmK_U\tN\'XJt_,%]UT#!%7EP,L1^@E7kK1m@Ms0F)UbLZ&UUPgEu4E,#-1oRaGkpuE\%IL7R:.)p4qOiVkSHU(jZ+RtnnrOe`4eT8S2e5l3/[5I6'$?sqXJ7-$:Ofp=%QSV9E4/!Bf6aA6$9r.,aFl![=o+>,5.L4i$uV7@Rs_%V/1YrCo]7^BCF-iS!rFp#K9bEdB]"ed4k"kspO&r1&)kk.rJe$Ad%b3*(WYuaSnjXR_sK4^Y]l2fraLVR^X7.E5dQ<jE&;B#8[lO@;VKEm<"MF-gV2,SZ\cHK@CI(U-IM1L;"-Hnm^<OobeA;e.6F`:p7>Nl1Nu-eiB[Y;J)BR)Lps!lV;&eBpMmEij68-Pl#msV#&O,NLUSe5klP[aE/TAGe[="qp;L7Lj#^>8QQJWTg>]FY&,E3CP4UhU><bjO%&$4;S!1j'K2$'h*P"AM?pX[mm)XLdM1m5,ep$EfWsA#=V89$>2P"b!D'1^L$uP6!caN#E&emWc`g7W_%=d1C@W-MFMT"CD?O0m)84M6T*d1^X@gF-0Xd+>Pac*CR=m\*sfM4@\I[p][.7DY!Ta*EZ?T52"^J#O*Bl:Mo=p$[?_WbmFI8_k0nN<u-5%X?kJ>QcpmU*-MOMOTX35!U1&X1KoZGCD_o6Q%-F1(R.\8uLN6IKoi;kGrSD7TKMa_6o([UD2T4$8:`n?(!.U7.[mi(.g0T#k4W2#0=WqQS4,g#,S5V(#;GY*E86KHnafG[B9r25Y[/ZG*=.5*]]>YBp:YE0INUPqQCu^*sSZJhoA(@Y#>E9_N&dX3:AtS4l42A\ijIr?2PFF$qXZ^kWS:5/2eaGPq,35gsZhfCldXp.4gPU=*)FXq!TYh**Wo:+FC$k%uCQAu`e#Sk,(.)raN19mTR91a;+BlBXG+BY$FW6kF[P2Mg@UddrZtmXff#5aHK&A3,pEDLkTD86K934F.L;XpkSb&>R?CeCVFZK%Dc25Ep>e<@(F)$?p/\6'G!<^/JiqdB%HgkG,=<,rU='fhg1h5KHhT;doShLsmNYgp@(pjD?sT$'RJRp.>?%=-b&tH<M-./(LRZr\n[t=mO,"lOq_CZ`96C%A(&Oi:H!8Z'C9KJ0WE*qT,M-5F<^e/8S=g%g/)IE2<-6<j_C"He-ur?_=p4&K+G\;]#ESD`"F>#eLAFeLn.&W7l!3fZMkJ)Hl)5J)cHcT4amimO=:J?kImNkPeYq!S'\2RHZ*(bKqk9J]EiN!E]SENr~>endstream
+endobj
+% 'R320': class PDFStream
+320 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2691 >>
+stream
+Gb!;e>BAQ-&q8/#rkgqR*LR\BX4o#@P*/N!fX6sPB9(;[+;0jaO9@q$[e9+$$h,K9ZKX>_Hc@+r,)O9JpY0U>EhSIWY5.BR!,q"=3d&:3@(lcQlZ?S7!@IEiYJ-B22h/Nm"j_5o4^>=9hh;`Q\E=:S*S9Vnh<S,jeL`]u35^1Ujq5,+K9&knm5T'2Zt8"iUanEFLW;+K'BVNHm=-k*?]'bK*bmKEHR,\\3r:S>PjGcJ:(o3LEKEd)JEM%4@e:aEE6&_(5fOB)>N'W,HHe8L&n7h+`."'W*&J1OZBk"begq9u=NVYOdsFEhTIs.kn7@h</J]Lb4/(9\EcIof9Z";[$BlLDPBZqjV_&HQ@/1EH;%iGU`u;pZJeFmo)SM\IJ5"pLHnhY._rVdh50`6?;HRO>#V&I[RGnHVU=UAS=7>`re4F_2*Qq9^2@b\jcD=_!)DnkH6PX9)UBYV:J14`P,*V<aHN:C3QN#6R^);+->uV6&Y2_P3IPR>,&<Z4gE-(Z@R#7BnjuR\3)XDW=?2"c:IO9sH@R\-"h;tOFj3gMA!$Lh<3fug+iTEa_>ZSmOS?>W?C"rcmIHT`0hDYOI$(:Wb<p2_H&gVjmVHbE&%RdrZUBiUF$t+=tDocYuOO8(+9pfoPV-Z+3X>fKo%34_]f5G$2MS\V):;;e_h#Y5E`,eE+S[G#p?L:c!Z^8#X\.OHtAHpL1Mj;TlE`PIE43J#;G[e@?#*0WV-K:afde381o&AY>_2+bbV8QZ\+TYYn.MheM`!/uCn^"_7T2k[aY7Y?*6-$Y#8nKMmE=4g6q95;cIg;$3=J<ZNMM-2s@U1Hel'A,c.72`RAcA.J*-pQp9G,$GTB!]02j<-9@*p3bi9NraR-#\LgH]Nq!57ebP=Of7lZo)c6n%[3k$2VfAHEC+3uh0B\h;$S0?Mc.9AtLsG\TBp`+.4m*rFOKgV.j(b`)r5o@d,:[]FQPVVNYYKqE]$9rk*D6d5&rNq5$>)`$te9GqYTe'\G!R*l89`<K.j2BN[0=WA)0TpgqK?A55&nE@.:?SY#:Le2eT"dbYqI'ZX@8=3<;_!<O\nO\fdro8<(O:>'.T*JNA[imq-&roY2d1_u'FYZg5CscI.oUi*em<W-P)AU>=ecQTPe3\YM?sAoY&PF$pXLNHDO!pb!$,aU8mr+Y^c/=oV;T+#F>efT4MQRq'L7ee08<C-Gm'ma33u`<bTJRiAmsGhg@FbZV:3)-O@(jhV0l2st']oHL-'c?*sEl#_6uGIfr,k5)70VlSg;a`993XG<9kg]V$-9j'g1a"6%+AM"uWI9:Ne.Hm(sN6GKqs3k\[OEXYTo4>#N5u&%Q=3U]g<r@QgpbtWmC:6DXM5F>+bu%e4f$la4M!MGWWnRK82!#/fVQ&_7mWP5D%/V:K)gZkO@1?F4j"DZjT-^?_^sGb8`>d4pa73\t-<(=(Y,o+p'W"oDRf?^n^XFsCBs,(@fa>u<b(caK/_?2M.AWgrc(a?r=u5O5ZaTbJR]kUi]`)<>k3HE"oY#0Jni^"(f/pW^hC4?XO-ao%i.j^FNMEMXo(S'Ca/Zl0E3^V>e""ol/388eF]Nm,H<AC>;Y.P\``609FNRan[G5Y\'i7^_2:V_0^F]/Kh$TQ.LL4]HDI2j]D,Tg_E$8[&AJ+&ZI4*LiE)+5_9"jAeFp<GGAU5K4>8K6cL'+:j`:i7_3Y'@HmY`BgnF1D5[s*lG0=2Oi,ifAL4PJ<OTeta>"/a@d?G$1-6Kh@eIF;qcJC;qZ:$rm9BG<"12PMV('e5oC)[i\\Mc5aA1`$Kn`c!4VGW35Q[:&RkanW/Al=Tqc(#DFlVg*+6Ubm:;q]@HImSIc#b`_WgOcsOoX%[n^<&A1*0lN)OLS2H%2Cr>%`]=9[.-A8&_S#Rueb_Q&YfaeIB;lW^[<I3`7BH9n4C,@L%jk#qc0Yt49'n:%jc8qp,u$o\=u7CS=GtEI.9=Sf.4fY#o^If\oX^([pd&/_h<Xci_d1'bS\a!pSu(mP>0Qdn5M7ri+eP=3#eSCE/W"i*1La]X@#*Oa`U`^+B]!Mp;X--*bU9ptk+$^',QF$I@1J=jp1k.sp+/+]F`AEoh_[8I/s/m0UI;nUp-#<@M.**2[adVc<"cL]:R7N(mCP*mW+a**.4,t>F.4IKpIK'c-pHh=<ZpV](tFo"Hd;1i*:QdO,?s-_IB#)G5j?]*fEkaT\)/!8Bb+^[^,"/o4KOATDK-%U;6`MqMN*e_O(q-6,(XkM9n:*T/SlIdm\';RfY"]s^`=E)2D)#<Ymm>f3aucH^?bMf?QU64@l*LmG-sQ7T$qVi*NIloO'=:h9s"Sa%'sDL=4T&H(>LF+LjL1,K2oVY;n2VSg*DH>YmM:H6<"U?Q>(WMP^\@WJaor);EqZu!Nd8CkM0P/J1268B!@NX3bgulSK:C[chKuPD%E5tM1;Y0.<?@o0+hPWDF$,GA:-C+6h,Ni'E^1&^_=C.=>"=9L@ng1OiCE?HHurHml_H`qB=I6Xq-q()knRIS`^<bi\pD@Ab.Q\6AW<De^lH6VI,<o2%;jVi7mM`X[M>%72"^+kEm)&fWsNI<9F&Qn;L6c[dGQ'a2fGTJLu7aP;+S08ur0>SgdPhVYr&(27&]!eF67SpcX$@)O%E(\gXKt@$0=l[ba*[Rsl4!hYhG63M-.'qD>tBSKGrF&^\>Z=+:6\B^E\~>endstream
+endobj
+% 'R321': class PDFStream
+321 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3044 >>
+stream
+Gb!;fCN&":')`jos'_!BFY;7VX*qVYj>_:#ELSqi[fqZ##e1N!b>o5jP-VFmoll.d?Mh%ZZ&;i=0^P&m%VO(W3AY[]IJaH>cR8sA1P^HeL(Fi&^4^G>N*uVeHoliRifj<NrU&VW$jOOiN6ejp&)f>r57=@e@5o+ArQ?"eC05=0%;(eYbYneb!&*C/[,Wt[e!>FZV/G6;4F7P/5@FID]D[faqc!=6O.4]o_dUpBRb`]YCVmD#$ob:-DHh>\_titT5/+XTqsDG)pL#RiSDo2>UVrl\>_?8_.rV@%3k8WI="O-^'`MROdbAQY`?.2t!PFbRK39p]5D4b^B%eX[1'=f"oeU<4ja"-9,Ol6R0u"A6s%:2'&;`C^)<eId4GClE=aKao*YK&@6=rBnf7;)f7>-OoF/I/")E2@Y[)d.ZT1._Yr;M9oaaus2DOi.7&C5d@gq#=&HV2p"[KDF0"G6\,Q-@J:-&_!*(G3ZjB`;O'GfIC@CVpN(bnH]>bkTi'49$$`(*uDn&T:<XrmI5'iZ>o0KZ&,ej5lJNpS0k_k3MHU+'\UQG[U9N)lGiodoT&rHf=$4S5-1lACR<[mc`DL5@;`F`U:g$MJJUoeiT,5"qo4gJR?,QLRSsHN^EJJ1?s?1c2*N[cTKT6YIf-1*$6N/QBR(%@//ehl:?d)hAr-\rb@HMYm5lrZtH<`.hVqWWU/Lp^Yo%-pArK2cdING\pt'?o.3p?`%VIO(aKPOkE/l(#]u3l;RuIhgK%;:f"jdX(@TNK9VBg],hSs'/JPZ@d,)]tpoQNEf'-ReVqOffI`F1hQC(9h]ZN!Ub4;]B#gl[oG^%/toEYEKS8/\f&j;26f9g!XLfWS;<Z$+nPYm"Z>:*%Id$#d`DI*FW@j5?>KMuiu4g+$`UpLC80olW*f2tcsSVc@Dm_0^fcMj5l[:CVLp^?VL7<skf=siG8oWAIE!3&de.eFu0:(t9=LkX+f[RQ$(YkVj1s2fE-kGYTS4n@u<-AfCeh$_,F1?qPYRqh;8BWnZab1SrCDhi,5P1EdI<D-2aZ.oBo$cdi4,aH<+cDemFC'3?B4rDrYh$I],*^r3M8m5p7aD*0IMWtDXK#mN"gq:'X\\W?K]-o[3>AtZtgjT>7$1</\[rc+Z.#"S8I78F[,I1l7HU+5E-nrs\A[g8ehn=E"_-f51_C:.:]KS\E;]*_*_0A4Q.mH\bqB/DA(.=4Hd[^grD9Eaq9RdF[6h./6RK2>iIT7&05#N(f$sAMhiPe<iN(m671KQ)Z'iXWc;`sOn?$#Vg/U:>dpZBC%Q_n#Chs<l$giT'Y:_4?ki^h#*@<Kg8oli["Y%6<;gRV_S@<WBF%J5pNhB`_=D#!Q,BHA>-2OO2`khMo3,F`'!Z.6P7gpq[5Dcn9HDd)sAWfl*'^ci/)(rpK!)P)SQMrW^9jp.@NI?i6+d!AH_lk]Q?%!;S!82<e2M8[&]=1Qh84TDELH0"j.bipZJd`1nj:;gkZJXAMd](Q2F,;\+EY4Mp#'HCU^.C$M!<*au&HV9PP;lk;b1.8JnP^O8,i_IQ],MBH%#/Lm7b@is(cL(Xe@YiN^,KrfC@4GZe-I!E<(^*a:$OP[0-Xn]VCigU$%3hu\:6.du9nb=iY*?steCmHI$U2SLgXjHoB-)F/K17KuD`G2B6E9In%jqm0+jW"BT\rim]%C2+9%%M6:SFh4dj<tP/N=Rt4=^">G]=nOb-uT';r#c"FB?)Lrof`8m#/s4G;IQ1NANH6[\QQNc)e5'Vi%fNC=KRa;B<Jm\<I?N/iFhT.:/JQYDX[kgNlE$\bHCJ[('+f?S<02lJlR)s*4LY#-d/g9AR.APf*As[X/#p:1f"-Y\*B$.%asJZQ3&bDhYW@BY(E$U?r7?ei@SLL1-ifYnaG^1ae-\G;:]/:08X0l%L>:qoDj$/n;AtZ)'(Q).'4eCg;C2?*"M8m<?X>f!`94..>llcj#ei,5">baZo_&QU(m>Me#MlmC&el4K#J6FNZ@V:dNiH<ha%8of@1eA`#KSQ7NcZT%5\K]1ja%)?Z_S+E.-Ts+jNsZNhCDqn[N/W\,-J>n8b!B>GJA=ada3"!*$54uRsfcK>A^k)8@]cq]PZ18)nFi:Yk)U<&1K=u%+5AO`/k%.Ot-",8\lg:k<fX:ftc6b?6cQ%SZ8#1V#SGnhb0BlRe+!?r+FE#eqA=-YeZC05$d^P&nm?GQERaV*@rOT6sHQ,gqPIHS-&-*=`Pm7_((%H$NR'%=4t>ra3F8Y;kr$,<ea:Rm<7A>ciCr\Xf;J)cM'$-q++-i93D`u%g+@p-Hf:=G5&;C:jW#hO":iQ@m$28H=oRcOY7;G>269D0`o?_KN!BPp$hm%0u)_74h954[<+H;-lbMYEh:;EU,ORJ=sfpI]&]Gg<#u&umV>89UtD/4$k67TJm4,GT.N`SFf2=K@!ikX>f@G`RU>'X/d>\OtEei@:gSCgBp.;e#VjX-&:ic!(Vi.j+#`;OEPSnR*Xe\+='))]4%6O;Y&<NGRL)6_:*V_YF_WCU[d9?pX'`VTVU)W0pBI^"p"5?W8'%@-6.DdCaH?3aHUGPK'frdcSogPq!]>HXoU)4-Yu$fC-O=$>Mc4;s%Cb&_;Caf>MJa1>Q+CbW=oWke'4]\R-qLWXc'aJ*UoX3!m?aC%`t*_aO(XiPrs905<J+L[%m.`sqR;\X)o%dnZiNJb[Ukm:p,f_@gjHLq+=6jWnE537#=eNMfrY^QT"OpD^dKPqAS,$6_^Q2-/_fA?fbpWNM1^S,G1ZN</[fB*n:ALK2`,[jAp%WIRL[LkJmY>iZj&?6otXXb@`lD0_R#1e+VG1A8-,4XW+;P_.Oh9UO(O\g'BYL;DqiRi2M0nRs\ID4r?D#Lg#YK?kece``.a_:6L(,_1)$Q"k.JFFE4TjD8Wkpl^-rl$%#kk>lOG6!4OfkkD%R7t@J`'K/jhBXLa:n.&G+!^pNNV]G\T-10Pap1R%A$j%T1nO@-U<l@dtX9V\e9G1%$J(!j&@J?6i)*QuoDT5!;FOQ_Mr&4pK7"NEI>,934!FEM8+4t7Y?2~>endstream
+endobj
+% 'R322': class PDFStream
+322 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2616 >>
+stream
+Gb!SmD/\/u')ipps'a8-k7fg!l<X//Nh'L,\929bm/[EK'tKM$9("IHU_MXg^R85fU0_Y7^$EX]Y[LWX3BK=KbVRQr6g3H(aFBs!i+`U;hhMbd@601J+7s"<&T4JL?[^njYe5D2LMf$f%IfdVmmFSjX7(X;V\aL]Y^ZNXXbQL8UL62(^bga!%.H%+V\M_<J<oQkO'TP(\+9g$s+'A.]_p+Rqka/PkC%8<@4u<[c!ucfP9:9<G]kZ?.[$IQ/<Qp]\]C&`%W4Mg:LP\Q&k!4d'J@E[Nc2,:bTW7NYo=6)Tb9(Q,if1#V1da&eM70!@jmkS/ea?U@#A%`UMP"+CM=?"XCrc'<9R%jZAR%4/7TEO>fLl6.;ZX4<^L?Fb\6XrJLdH@#R=DKb++fZTC^LV!81YPho^L.3>=N?[c-1P*1G<d2+d9?._CcNa5K[EAC0k.BVR4]-G_bU%[S+b(:!tfgfT:6@Z_%MKS+?k1#W\VIG_+'3.":WQ/C0LSO"T=mP1b]XPBa_@s:\(Bl?[R3'!pu`OFG*H>SQ08o>%a$>nYB086\OAHu[V<q76ij5IcQgJ=G+?LJ!c_]K0aO!^2W61^pnFnCu7Z,Cu-/l;[_M9srm_G"DBTO"]+8<m4iO`E=q]Z:J^O;1e:+bVIRlI[!i#Ok8B;*d4D!PM#^+E_3%EgkTOV;,O;;0%#'dUmn;\0[P&g5!W;'cX;49F@2dKrR%*'oVD&<2/pmJ+Jo*XV5>$q$'th4B?b8QZjMk#!PY:R..UDCRl:S_l_9&7-hZ(=dBVWEO[GaKk%-AX1Kf"@#c\r4A-`_fu:%m],I,/A=QsC_TJb($hPrM.hrjEn]"uk5a&o>EU'0ZJP1YboBd;FdiOX"A3!t+9*(U/n\s4746j:fKkGaPpCPDC0FYMn>]/MOH`SX>rHhn^m9La>n'cbS2*BCpb^>FY3U_2]3F$!P[.=jth3;&pl%*4.o/O'Z$/Go4F^IUNU^T,,Xqh1XG-1>srl.l8B[RU$%<DAO'M3``hjG[dN2C2@1LIm)i.M'6pM;9).MJm;[[$Vbl/F4:86kbjS[pdI^-65/gjRjLeT#gQ>?:8`h'S[1";DKFIttQlC&92+@4%_=fRTNJbUB$kLUTL>]EibY`oP-t./IBd'm*Tu`s%DMqai,OWZ6/Li0R4]VDl9Gr&VOeo],&RhsRC,ICf@8k(q*X+7Tmem(8*N#O^r-2aMggU-Eh'OQS>;f2h!,R$_ffE>sVr)haX@6K.q=6c7UNfF17,*1P-dHV%2;oLeITLa\Fr+c67L#IEDlPi4[,'tf'D)3H&O7bs/9Q;T%S4"!%'F^/H'P>.mqlI[3M66qD]R/ngo+&1\PN-&49p;<B%1u!en@SV,6n@O>Q>4=bu"\&[mXK/i<rCuPV]kq08j$sh8VeF3O3$t>`9P(RF>.Km\0ZK$Qds/f/mpLhf!bNX@U'CK!ah.\-^.%_dr=qpGZrT2AiP!4(:;G?dmAP0`=d,?=PSpP]$ND^2pD=890Gq5ai<'I.Pp?M?B22/.)og#L*\c4<+\f5Sj]=aQGMGp2EBG_J`tCW<Em8k?0#8le7NL@Fk*okOW$0-"i2uNoIlY38U_#QV@V)ajdC3;\0o3.@A[cJt,,u0;n1_YA]Uu:+`t&"16+s:D_mSOZ8&K4KX)msAZ,`C@@*Eigb]LB_]BI`6NKVnQQJJuhZI]V"BW$9ZXi8dra"CS8[bNhfrre^b)#cND:8l<$)Q20=5@j9QVL;22-Ju64pk+l1[%s&s.SC6t-Rp?rHsG(:$le:og@O9_J$)P)dK!0h3JXCW<k^2pA!"OpYqp2rb>@+qAfV]8'^ZRnSL:m.:P>#G,#ZR&Bq=9@m#!>M2D:sU*5EeBaa7=PG=&4kFiM8ml/T`:kR@=*nb<Zd:,&,q4?Q!>;N<U\=M'41-m7Yhm9"Sf%si`j\``LYq.k<fLV7*joJCgJXbJbJnud0#d0jRtiFp/iO]TTtm5Nd?mp=:@4%EbQVALV:8IW4cQ;Ls/TDFK$9UUen@rojoWXZU[E=%kkm@uT'4GW8&9%<FOWQV]>'aqOW.OIHd_U>9R4e0nj+C/O.bh"9N8nQ`'#s?r/NIp[",LIoM#PuVT1/d_,+jW11:bT#]$BET_TDpd%^uM_^5*sM*<[PY6XF71^^$#1[`Q#K*6\Rc#KN(CkE3rc0cZ.B&eR3R?H;]O#@hVTa-^F,.HiF>'o2M76aor^*[V$I7Lt.I(c1Nb[k:eE,P"!Z@2<C,RX6;6HVJI5<Q5N=COIVc<a`/HFPbnO'dZ6Kf=c7utGVgE5:J0+Q$V$Pl>E5X.Nj1HKg_*uL+6*`,DT41iWH/$%U)N7C^ohk<"Vu4sX(!Cf]SjeL)N9i,mbXL"e4iUH0D7Ink8Cs`Ja.CS_o\V%l38Xq9!'rWL/"r'j6!QZdr>A3ddkJUEMMukY<#kUAeG=,1E#oL]ZmD19b%ndMPUGR4$&V"1Jad0c&jq'Nh5!U/Mu%Q[9/@^Ba9#md,g0<M8Q']dcQ.i;E1F3J[0,([u#YkSJjWa-s.>Hh^@G`NVB/pU:89@*>R$"X7CE%VJ.))jAn_)^+_,h=j[\)oo#iG:0a<*Q1fNu3Gap-H4kSf;^rPh^\S`sR,$'~>endstream
+endobj
+% 'R323': class PDFStream
+323 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2886 >>
+stream
+Gb!;fD0+L@&cV29s+gOg,pQ97]pH+T)9&m#[8u9TkB8n/5<q?$%P^PF!V.N7qsFM2O$&OeSmo<kUld'5!UN#&GFf$lIXC4$S-&VmJFb]@GWmZZi.Xo3Mmr2%naaXHoAc+s;$ao)9I!fk)Y`16X2^[/)gHf7pFfn3Y$QP'e<s#T=JXl#%Sl'`FQ1f,kXa<QX#i<2]l.?L)_A]Za8]Ut5#i-.luOuQ,KFh'm9i[PIhRFs)Hlum,h9b^7.=I!a.=Pgauq"Ce00bM<0h<k.hN<5dtD]*I3l&QEOCrZAQd5cYuY,5A[3;rA.Zu"&sKM0Rdr#],Pe(/-WB1ao$jA%(Rn,C@[7Ci_-9rNnJW/ej[\.qFOjka]j17clqJMH)o;&Rc!_o^7,Ejg%bQek%=%2-Z@p0;;2K740ClNl+NJVN_dfqaHjMe?ko;#2iN)1^^ELOcKW6?_SN-H'9rE_)@]UM%Mp]U=r^"YQc.2QME30]XQ@Tj^DE:Z/9)t^.5m-qt7H"%=k5=B<VMW+\BE5n6Wq7)6;sC>N`ZLZM9VTo7PWnXL!8U\)n?ItB4&.,C"4khY/VDE3Ei'4u`m(lqp0?`20se8@a<eb[h'>,'eWMN+Kb3L3Y?6qJ^uAU87K/)a7aXW;Yi04i6"Ft5e8+IA3TTNOa+G]%S>gm[,a,eT=n)J2-"B@Ce=:?@?=Z\T`=b'[rlFMNVhkhk+bE@QCrJp>a7UmcC^Dgh&s1cs`E>CUIG)PHilmGPdEdXp2^1Zn=iP$HTb1=cZ`u=<ETt[DI%&V!"r2D=-Hc7-bqgJn"=d&+b,j9^__(%SI9fkaq=5465I:BWfTZD0n>_e8B<'$.*9pEL@&oeJ;P5o4/aWqrI`R%W-kbfH_gG$=U_7kq6R?YQ_H=2oe"/4r(bj0q%tC@,J&?=SoJM@$^VBc5GVJ;nFL:5k&Li$`Y^B4(`_O'(m'[.Ub3c+8e+M)'hIV;kGsFMO[&u^ij?.?9)ge/"XlbAh2$f[Eb7fM9Em27P]UBjIgE:>cmR)/Bk@&I:CHM&,RLDi2>JiiG%^%3/`W4k:"qcTB.nY\=n.'8)`8Q8I--\D?#<!PeY$SMs?0@lgiiohqgI&G_^E)5qh2g^S*]cAA$rQbFU2bNomHcMHh)f^O?dUdmn*22eF4Zh%3;@*,""u-C_o_gj7HQ]2,a_aO5I^NS[B16)'G4MtIdXu\NseD@e$WHO"L-h?@#V]4$''uQ9>ko03mm#&WR91VBfoQ[$5Wu\4*Q&oa8MD^O,.om,/W7pD%%<;7Uut%2_JmUjBE4+1.W90Q25(3E;fcJYo<fM]##mR35nE6FA?mVXL;'FK]U_;fO'9A![b#n_^khHgDY=Z'&R\o$E]f.f88K;XuNgZQ81'$)eD`kna9#e^C?kOQN[,LCKW(0<_jlpl8^BUJ*N:FMbCeGM;2JO;seG_G$kRc?#2Ds&Jpfe-](QOjJlfoo43!@`>o9;9"tWT=lbrbI4BoUGo"Q9>RHq?>\LGWs#fEna+>Db@VWVT1,[#G=t!"SEK9@+<oA]<*^6>'gC=61g5i//<ZhQ@W'VV0G(@#S0YN2:IX$hIRF!D=OH,U9[<IkeN=0!8H\V/^TTT$g)2@H<@;s;Th'ef;Al"E>Ff+cYQ>OoKRBkB,[O$8qQPLV&0T:U9*;8$#L^Y2kCtNM?iH'7V\Y904`akrVoWr+e4%ME7E.h(.B5+bkS@%spP@L2XT0RBU_b+=WC<[med)VX!^UO%9'4eC#-[We+"Cs"QS15ME@'tRs2.p#>UQnFkF5Uf*YD[mmAbK6h.94;jZ/i>1cM2gOmAil2Urg>.0SQj=p/oO*m!K$U9=`(%H#1kq.d@8!;49.V7(rcl;$u?HD<VR4>$=udRbqL63QU[*'"DXh5,JH[";<.6XXjb)^0H.HABaD@(f[gMeqheWI'A>o4VkP7$e/^^c:pX,V)9\XK-Cu$$4cM\nSkAs8+b4EhRK"364(5LMuZi[AmA^n9D4r(5hTVpW.8H'VpK,C=-kM8Ald^\9""!V+=V&Qnd&6gUE0pYjf4-=[6=%5I?>Ro&cR&.k--1e'?<2%97@Z"#on17'!<<2.8$3IM$!-bX;kY!N]V$F8lT]^D^h&$O*Z_(XJN!$BjbbIaIt<[*2TW7nd?n-5BFT*gC515THKM^ahN9id>cn*SSa(Dfb&/\M!a,>ZoG>lq)_k27TA,kk2`40n!Q*[ZVH8pWV7B.Tuij>M(9i$Ku1l1IS[56HJOsqAhoKmO1XghfmLfao7A9rL89d^Rq<C%/@HO(eri,aUV+X;8"HCRP/j`/JCdlL@aq@Q:HpL+P)Ym?d(H4FHhEEda6uJ:V*\<OTXo?c'n+eup]q=?qL+#$;r_S>=o+Z7$1-0M]\3uE'Kj?\BZmA>ga=@N2S6r<"1O=,W>p\\>4qs-#7F<a^IP-YAMn2iCH`d[Dt_t\rE8Qp%k5pSK]l19/>m`-*G-qOd?SU._D<Z'bp#tY=%X>W'pW%e43q&Is,F0h]Z/B;Kd=r2RTQc+'s.52kkn.OnU'h>1O+MNJNhg/AI&6Er\UE4fi=&&i#^.6fm!bp3OP$S2F?MB5D*XIoVqth7Os0-B6g3EJaY(fOGH))659&-bm+41ejmLgbT6G-A#q7,XDP//gpXg'hiASrRiMo,h3*0-GL4ZklfQ6[hnQk+3^@f9\hYUWBA\N>[Gc&*0^4:)S]C2mMHbKg0l^!^,A^rOpcm)7kJOdh6$B#URe'#NR1b7[,,*"$V?"_:[FAuhXBh,.Z(En@.V=2%n`DeT3:qlTcNreI^:to\fQ+=@5WZ,*YCZG6m6%?,7@EpMQ[q>aRZo^#_u1LcbH1WK!p,0K((>\Kq1e/<-&]BXGP#fq-1QNV_FlC61/J9Llo&%E"8<0V?i1^$oPl5~>endstream
+endobj
+% 'R324': class PDFStream
+324 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2692 >>
+stream
+Gau`UgN)%<&q+ths'abnD_VLuhSd[&f#k,;=XOuk>?c(gL;8n@#f+53"3K?%cflJN"=ZqeD3n1!\L:q6ds\h)oYn'Pi[<l<dmAk?/]9U*a!+9s@O:#R1_u#$ik*2$BCGXTDN7N4,"\N^"Rk]*+,d>_p:Fur*6$#fgc^,kWH!.0/@q3D`1df_*8rX5duC\I6<=Zma0*C>,^CgSIu;30q"e@npO2qtf0aCeanQ0bNpG'(H;:J^pHSH2`Og@QA(=,Rj$j6r:,MSupWAfM.q.bllU!W%o5E4gnaACEOit=02r[U0bs8A4/H%gN/!_[_Te[e?<&l>=&UpL.P@_0Z+!;abegaah1=P?R*ZI5Nij-e0d<MdnEh,h+:$JBBJ:8'kHdAS\1BQR0fSJ]f*.K/E!%5PdF96DC\/7C.]S!!jKokCs<*%oA>cf1!X9,JGV/5O<ptZ<nN.:Sb"lUo$%q=aB$fm5<Y"f4E3ZWZ0i"iODP1>Oo_*YS+*eEnQItX4Be%EtVU+QNT>N]!0F<T7nh\;KieL:tD<NZ[/H3Ot+f06\H6C_AKN?dr0NS97`3tK_FXK3jAE/,>p"cO>pL>G#STM?r%889/FicOrCo8g]dacCeoR3\[b_1+DDKRqFl4K#:J)a67H-j&'Q]nD/#4B%aQ"Cd)K,])1V8,*kR3C])B?>fRamtO@a2UVtmRl&*,kEXmA;(@hcfbF!HOefZM!9'=!iWEJ9\'ZWdaMKl,X91r'Y8MB(eTaMDnOaS>b(9?HQg93!5)guL=PjmH::g^g!/3%F1WNIF_imLoFs:nrS0ClaF%)t5$qb/:$R5+>aS])O.W;^P-,l4l%%o6_SVBjc>hZ0Bb"=:/Y.[jgj:<pmA6CBDGYg*KO<ZnrB>3Q8NQO>T[;TgK<5&FZ#=/G]lC2!>/c`-D&@405";DSX4AJe1m*Tc7S_p?B,YFr/=c!*'1aP/P!JuV&&`q2B'#_[Y>aq"nP6d[[VPml,,InNs7Ei##?#B3^PA0S6\[;n42jGl-^(/icM`#u6n6JCe:>AIB9oY5Bp)jW8c<5:jXBoa2-m#3Bj:P3[)cUjrl.,<6'M=q2.uF%uOJ3+',eMRkAP;@q9F(79,0fXo*\g]f_OPrqO+u'G'TW+=go4LM+s`fg8<p+hD8;6eU6=aMeL4P.Wq1V]J6@RoEV^H<IF%89VcHAZ"mZ_8AHU;hBIfTCI]ah_Ppm[[_-+g/rT[DH;AXI!b.:\)D@Y*S/?+O-UK%Mdg^jrCZ!)\q93d@7%35]PBuqTHIO$(R6m^5OaBPWbk,l(8*XfJQUF,JdfjQH'*\45iYC[D@h9ZnJKS`j&;CjHdFi/n^d.,lpoTG="bc:EF[WL0%4(E2\$#g,O7HQ1hFd:qY1RcMWG^]_9$n(*"`Pqcq71V7o3+a*%.4.I3!Q2k'&S_p0[GFoL-hSM)LXCKkEp"2Z^A[$dZVi'tMeF)gnM!RiUh_,m.[nS$ZMQ6jfB;;C30'l6&Ci"q+daeVJb9RL.+bX<fC*%'h\i\l"%e!se5.t78bXW<r5V_J/G:N6&?8eJcuaZ39*C[;kc1?gln[I_]l#M:QW^3-/C<8IG_0<&pu]';=5:a\BB2>g2Vmg620X@LV'sNFVLN<dIDDhu\:T(m*d%]E+Zbmkl,/FU?J!H25aGcR7Z%Pa<JSl:)jReE)c:eD]7&L5PFYS88)maNcsN<qWHs`\RL<)^)F0T]DKs77'#1EL4,/U1COMrpSi-j@CIM,.\SW92oYfN-'=/8cL')9/#`>MqMi2#@i7eYWKC$j_(Nn)=57Ob0_GH#%L\t-$\^td3gi0<"l_(sIA;A<)DcH4@O4GC)ik'lf,o8KGlniLBmq#MJmrF'5)ihK\d>gRJ<u?\<Ll1.N)P9cI&$k&R)l\(:!tFW`E'h4nI<S5/*u.HG^_Ok/Y>-ZmMcf#1P=b1%_MseTXkHjZO*WH">P')N(\><J*,"u=MFZn#/F(1_eHLHd"#5gP_lunR%#ArNhFU<`-VD/&gXI;)7B^@J9NmXbVajT>)aE"4I]`aE6u;(:W1heS`QZdl-F:IdZ$hQ5G]Z];QIH/)em<>Thb8;01SK[_Q)\ctNptb@.+mr@;'&>[_/9\^Rc@I4EFb]20pbM;W=_nB?tbgsg1q@*nPrklTa[.?crXZ`7_C<?ZQ=9%`9jrkKquK$SnT>$D*VTZ-]?,2(!PO=:$Vj-@Y[![lks)AHngY9+#P9lY(G7cAg:TFR8b:W42hYd&snc@Zrs>H_0;UG!<okA!k*'0W<1p(<0c91L^Q:$4,MbtB?LaDEpd/_N0b";1r>ucA\[@5NB8HT<-![&%nqa]:&B_*Ql3&V3.qa[F"a%Fh0NMc*XcY`0WUk]ik5b;`HO:p[E0X.>[0-[f'Y]W%=1YQTabq6rE5C@7fRr-\+%F^4KLHdTN"bc`Nn'?G)/=nm3,C:#dafLV4fWS)n"(G6RE$`MsCnoQmQlgO*9/;lG.++H1dlJrII'")<@V9dY8[Sk,totdAn"3Rra)GBgiQihT7?q\nd,@>NtZa^BseO(nNm:/'`d-T9!m"%Qduen!%U0K,2]ic7'i)k_;rU"#["W0<O;0B38P^Cf*%F\!-snMuZ4bH`BC3>X]?tl.^*W\EkfB:Y,5KqW(3IM>p:p89-Q?EO7N_*&r+kqJ%sa['.brF2rEWegScY]>&gpk9D=3kKj,/.TL2T~>endstream
+endobj
+% 'R325': class PDFStream
+325 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 1542 >>
+stream
+Gb!;cgN)%,&:O;3s'\DnElUL8;P^,^V,!Ii1/lea9g<1J5!UB,+TVT^!9MVcG6*ki-/TQK:",6E(L211Sis[k@#U_ns3+)c="4(B2Llp'[")ON-BS32DplOU)ugB$jm`JjOA'0>ZSNZ<.-S[lF;tHm%(CusG\XInBM)l.$u$#65]@XfG;i8gm&h?*O1p?W(`bp=):BW)ocO,+VYfDk^,=AYnr,R>gMl?@\MIf<s.^7FX'e!]VE)9V38'gMrpK8@64cR2S>/@VRD^oZNS_q^P&(@+>jU+mJC,%"FNIp0;H3o.V;Xi)>4Ht?[&O8TW9$VipuH:.%X39FR8LB;QoTmLfuu>:rCNTrH4O\rm(^O8V4aA8Nt/f]K$#(9L3,kpTF8Sdb76p"V>:S+5D,,.%@Z,&>dN5'S?isVE,A_a<\eAnSF)JC0QgAED;gf8-(It/^;I%_J<5_nNa;_Q]r>O+rcb^9%F(3!5<p$"`SgCZ+pC8Jksc8d"^=kEcBQm2Z\XR'kkI=Y`u_/Uj'WUnJ@hZ:3HKFWWiU.HZ1$#O,`]u/H5ZtZ0cEiNq)oRHOG&JFm#[Tu`20-I,/d_4%_*N=&1k>mEb[a#/lZ7tWFl*'%;*OKUL1eXM]E]S"?hA2lbgs=60'd7Fj>M(ag*4XglsE2)O#a3*Z$B_JL%]AeAD6(f#G!.9^=P:-TBf9P$n?eZ;<98nLe5mpkfNRY-'Y,RH[NdN^c``E0M?rV2o6.;TtBSPE1_;?&&$M5s.fS-+51ANP=/D6IJcr9WeiJO.k!:Kk/J5(Tj<X'%Iamgr[&o&;7jTD&tRm&9s-/j!SEX&2^rN>pplG/XP'.F>6q+_Q7;Q<C[<K(j/cYEA]ZqXH!]Rog^os8Xqo&m!#MuB.KiLLt%6$NS8iISm3:%Y&:(41cLCJX.g/1@K]tK1K\XS5V85+r?7'9B?Bo(68V5qa%h'g/HQ,QlSVpR]RiJN&sIF:N.jK&pW"MIPO\[<14uof%pM"5,<ATp]%8^67Ao'G%$XEV;QY=X0NMn6h7kZ1i,sNm4FJ!iIo+jhXLA[We_R3/;`VF\V?=l8OK)TI;kX]3L"I&IKd?0"ZE2G>l]3l'1Kn["Wf?SW[E'JtmAV$^]2P5I5NTkC1NQ@;qA5#\&s:k*$H6Mj7Um)(+kHP-H-!@9C@6E?)QABQ-@NCZ"BnpG&o5RO)QYX:0ha:d,-e)9V@n)ol[YWt8P_KKs1HW.#[T4.9@hWs]E:q[Ok9S-f6#Q;]uZbOJ_\5E$dn:K+6.r_`CaG.YXtKVJ_cn.C::Ia(F?6U;2(io^%:YO^/N@dI\M1\;f)Wi'M+9\PB(9=_]#trgpZG']=%e<qp7KB5l=2XnpIT;^Q;llk)6EW.OO-PS$\G(6)ZO)#f3A%D-\t/a>8hEU[QPIR70(V9Q<Mm&.QMpR4$HFA,\(VGLbcLWdT9#eiuq4Q.7Mb5\njZNJVR^mod4hXC#YY7tRL_:K7A$a9:&+fK=/E6G'.Lp3K^6IYf"BZh@D-7[%*BI+^A(=1CM5X$56fAah.S^u<+:MD\]]~>endstream
+endobj
+% 'R326': class PDFStream
+326 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2069 >>
+stream
+Gb!;fgMYb*&:H4YIi.7CcGJ.9GIqcb[RD!G[[4N$PS[MtD)RQUP#>Qbr=2D%^*]/PMOVIPi/eR34<0qQ6dg]QIVesA8c^P7nE5-;C^3ECYW^0^d78F?HN!,arn>o_^'B[.Kg*5W;/SbI?C"`&hmFIHk-&-#X*3;rBFP"b7OcuuL"4hil7oYneR`*;`"Y7mG7LD:0`".\s$_Ee/:W'#[O/?`9DA.96.ha_pO_@a7CH\dJK#N&L/ou6/$g5">t_T:@G+)@dk#)qi<"=ER?Y):]U6NkaoXa7*mqJ3oF^+B/J!H[o%_5]mf0gP*4Kjs9b8Aj-sZ:!-NtHqKG=kNKU\,>'Nc+sAP=C<7,m*57LFtH4V]XtP"!0-.e#lu!M<aOKo7JtSAk!jrRIh3lSVp"56#K9#<o'\EYfuZ9\4$I"L>tG'Cdn21D]50-00Xo4Q6[+BecMBK:(N%Lrq>(1koNY0<bd1AWeU;5hfu]irrfuL&P/*.'nkD;a<-ql?\oGWY#VoSk8dRUfig2\lC2`1f%eBA]BDWZKlEf,9Vj(O:s)9J7iFcZC\l54'i@fFffI=Ndr_)8?fA)N@'$j2>7M40Y[=0MbL[sQFSsu35]D]@]"l_O6]EKJ0YIE+F1]nO;NI`2uk.cocu0o_MQNdV\.4/TSU,CD:Ob6n<m+e2<W/NIG5_]a1$d.QHakHepnSe?tqM>XQ\Hn@AkbVB'kB/i7nleU:`Es0fmU/a/^4^!A!uAQkMl(>d>W0Jh*`XmbSqd^3u)S2E>bjfll+p4U0`B_aE'JRM53FF<hH_`!a)upcPV(MCP&fBGV5*`E<=A*n(6=Ju9OLrN2'YSd%P7]q-B6L(m&69_V@^`0BlgCk!s2S#2`[J'e3!KV2HU=6kMHWSg1Gj:X$iDaT7l[6pR#J.4E@NX90LX$&s6@.uK\2!70^mot6[.(8ku0,P+@@sd)?LK/!uXS'YPE*+4[%5#_-S,[[Z$^)dU9qLeV<r[]@X\k6u[7NoURTVPIhBMb9gbT"M;K>8Xig4T-H6HEcpD).I\<m]L2oc;KfAM0kCCMqp<P0g]fRm9@27<>UPl!-,7UoQ5iUEMP[g%b;>$/5Nh@ic>XUU!i_cnW*Tb[,jlCiq`KG(3k^oTdZ+-#HS:;+#-'d$#87C+RKpqZNF@6S2CQJ@Oh,T)?t,Ndjj&&u:!8eh;'_'TPb)YP<WP[UhIU(j!a+H/0W?/S%<iA<2]Lb0o:2ois9HGkafI&`qr^:<^i'4K_!74E8?W,(s9_LrP*.em>PB7Z%4j+cO])L\Y4[?5<W?<8W&;Bf'T<%=pDr47IV]>iH<,rt\=;+2RQ+$st'&L2$bY\]5[DEF\"-;`;N.rWap!3Un2I%_/IdmHMSYm;[I.4Yp59))m]e-e+R`G1e(InCa5%1hm\[0F"i.aU*gJ[#$/Uf3:V;G*c2dj:HI7'deX"kiiT*8m:Y/!h#.U6lU.RSQdP$S3]dacKcJ4!"(kXl=SjE(Te?2!n^8V6Y,8+gjsX)cT5)>3pXp.BNsCDE:9QL`u(pA/V`]iO;K6a>KSoD/*`Klb[BS<tA]=>@<Rm3'S"NSQ_r-p;@7O_fA!4X4hM^hti81j`HHGE;[MW:Sg""$Rt%ZcKXnbB9Elhdea/>_Jt=.b?UW-8aJk>kEHTTh]?`u1lg;II[Ngf=,I9]n",R4Sm=`H89u4)ifZ]RLg3^*&Y;$Oj=mE![EB#69W<7\L-)edkT5t&m01S7Zr[^0q7`*\%8N8cZlAg[\B4=F5MPj,Q_h&.r*B`>Cd>L/4*1rbMs%VOnII;:><Q4H7O:l:)OQY6Fm,:BlL)Q;`Xj\T,V`qAdca8Nf0If@aup/lqR*Wk(4G<sQOTuO>]j[Fd(%;/OqmhYWjFr[jLK#q,fVN%rbbKTeCH)>de5e?gp8[]'T1E&>hmHO<#O;[cY*M!W]=*6C(-h$o7TQ6crVV`ateC7iO5MAId1dj-"5@oWkig.A0R0^kZ06EEd$3J4hj-==K"%&Wb"aXc)P9$D(7N*rh1AiQ56KQGKN9'\CE/?F@1H_@n\&D!p)q0AeMYc?LaCA_Wt;'!RC6PAH~>endstream
+endobj
+xref
+0 327
+0000000000 65535 f
+0000000113 00000 n
+0000000263 00000 n
+0000000469 00000 n
+0000012253 00000 n
+0000012440 00000 n
+0000012682 00000 n
+0000012912 00000 n
+0000013142 00000 n
+0000013371 00000 n
+0000013598 00000 n
+0000013826 00000 n
+0000014058 00000 n
+0000014289 00000 n
+0000014521 00000 n
+0000014752 00000 n
+0000014982 00000 n
+0000015214 00000 n
+0000015444 00000 n
+0000015676 00000 n
+0000015908 00000 n
+0000016138 00000 n
+0000016368 00000 n
+0000016600 00000 n
+0000016832 00000 n
+0000017063 00000 n
+0000017295 00000 n
+0000017525 00000 n
+0000017756 00000 n
+0000017986 00000 n
+0000018218 00000 n
+0000018450 00000 n
+0000018682 00000 n
+0000018914 00000 n
+0000019146 00000 n
+0000019376 00000 n
+0000019608 00000 n
+0000019839 00000 n
+0000020071 00000 n
+0000020303 00000 n
+0000020535 00000 n
+0000020765 00000 n
+0000020998 00000 n
+0000021229 00000 n
+0000021461 00000 n
+0000021693 00000 n
+0000021925 00000 n
+0000022138 00000 n
+0000022876 00000 n
+0000023105 00000 n
+0000023336 00000 n
+0000023567 00000 n
+0000023798 00000 n
+0000024029 00000 n
+0000024259 00000 n
+0000024490 00000 n
+0000024720 00000 n
+0000024952 00000 n
+0000025182 00000 n
+0000025414 00000 n
+0000025646 00000 n
+0000025878 00000 n
+0000026109 00000 n
+0000026340 00000 n
+0000026571 00000 n
+0000026803 00000 n
+0000027035 00000 n
+0000027265 00000 n
+0000027496 00000 n
+0000027727 00000 n
+0000027958 00000 n
+0000028189 00000 n
+0000028421 00000 n
+0000028653 00000 n
+0000028882 00000 n
+0000029114 00000 n
+0000029345 00000 n
+0000029577 00000 n
+0000029808 00000 n
+0000030038 00000 n
+0000030268 00000 n
+0000030498 00000 n
+0000030727 00000 n
+0000030957 00000 n
+0000031187 00000 n
+0000031418 00000 n
+0000031646 00000 n
+0000031877 00000 n
+0000032108 00000 n
+0000032323 00000 n
+0000032992 00000 n
+0000033228 00000 n
+0000033462 00000 n
+0000033697 00000 n
+0000033951 00000 n
+0000034219 00000 n
+0000034464 00000 n
+0000034736 00000 n
+0000035027 00000 n
+0000035304 00000 n
+0000035578 00000 n
+0000035860 00000 n
+0000036139 00000 n
+0000036407 00000 n
+0000036671 00000 n
+0000036928 00000 n
+0000037179 00000 n
+0000037430 00000 n
+0000037727 00000 n
+0000038020 00000 n
+0000038303 00000 n
+0000038619 00000 n
+0000038909 00000 n
+0000039194 00000 n
+0000039483 00000 n
+0000039765 00000 n
+0000040045 00000 n
+0000040337 00000 n
+0000040620 00000 n
+0000040918 00000 n
+0000041202 00000 n
+0000041475 00000 n
+0000042076 00000 n
+0000042373 00000 n
+0000042667 00000 n
+0000042965 00000 n
+0000043283 00000 n
+0000043570 00000 n
+0000043856 00000 n
+0000044119 00000 n
+0000044358 00000 n
+0000044580 00000 n
+0000044758 00000 n
+0000044980 00000 n
+0000045166 00000 n
+0000045385 00000 n
+0000045780 00000 n
+0000046053 00000 n
+0000046343 00000 n
+0000046566 00000 n
+0000046878 00000 n
+0000047119 00000 n
+0000047361 00000 n
+0000047603 00000 n
+0000047845 00000 n
+0000048072 00000 n
+0000048270 00000 n
+0000048510 00000 n
+0000048750 00000 n
+0000048992 00000 n
+0000049234 00000 n
+0000049476 00000 n
+0000049718 00000 n
+0000049958 00000 n
+0000050181 00000 n
+0000050613 00000 n
+0000050836 00000 n
+0000051148 00000 n
+0000051390 00000 n
+0000051624 00000 n
+0000051866 00000 n
+0000052107 00000 n
+0000052349 00000 n
+0000052591 00000 n
+0000052832 00000 n
+0000053056 00000 n
+0000053438 00000 n
+0000053678 00000 n
+0000053917 00000 n
+0000054156 00000 n
+0000054380 00000 n
+0000054706 00000 n
+0000054996 00000 n
+0000055238 00000 n
+0000055476 00000 n
+0000055715 00000 n
+0000055938 00000 n
+0000056280 00000 n
+0000056518 00000 n
+0000056742 00000 n
+0000057064 00000 n
+0000057305 00000 n
+0000057530 00000 n
+0000057852 00000 n
+0000058093 00000 n
+0000058334 00000 n
+0000058575 00000 n
+0000058800 00000 n
+0000059142 00000 n
+0000059367 00000 n
+0000059679 00000 n
+0000059921 00000 n
+0000060162 00000 n
+0000060387 00000 n
+0000060719 00000 n
+0000060960 00000 n
+0000061185 00000 n
+0000061491 00000 n
+0000061781 00000 n
+0000062019 00000 n
+0000062258 00000 n
+0000062495 00000 n
+0000062718 00000 n
+0000063060 00000 n
+0000063298 00000 n
+0000063521 00000 n
+0000063843 00000 n
+0000064083 00000 n
+0000064322 00000 n
+0000064628 00000 n
+0000064903 00000 n
+0000065045 00000 n
+0000065289 00000 n
+0000065418 00000 n
+0000065624 00000 n
+0000065781 00000 n
+0000065953 00000 n
+0000066122 00000 n
+0000066335 00000 n
+0000066506 00000 n
+0000066735 00000 n
+0000066894 00000 n
+0000067074 00000 n
+0000067258 00000 n
+0000067448 00000 n
+0000067630 00000 n
+0000067813 00000 n
+0000067980 00000 n
+0000068166 00000 n
+0000068390 00000 n
+0000068559 00000 n
+0000068728 00000 n
+0000068918 00000 n
+0000069094 00000 n
+0000069285 00000 n
+0000069504 00000 n
+0000069659 00000 n
+0000069836 00000 n
+0000070006 00000 n
+0000070176 00000 n
+0000070339 00000 n
+0000070534 00000 n
+0000070763 00000 n
+0000070921 00000 n
+0000071099 00000 n
+0000071277 00000 n
+0000071454 00000 n
+0000071613 00000 n
+0000071801 00000 n
+0000072028 00000 n
+0000072239 00000 n
+0000072408 00000 n
+0000072587 00000 n
+0000072774 00000 n
+0000072956 00000 n
+0000073128 00000 n
+0000073349 00000 n
+0000073506 00000 n
+0000073691 00000 n
+0000073871 00000 n
+0000074036 00000 n
+0000074251 00000 n
+0000074413 00000 n
+0000074590 00000 n
+0000074758 00000 n
+0000074932 00000 n
+0000075106 00000 n
+0000075282 00000 n
+0000075457 00000 n
+0000075621 00000 n
+0000075846 00000 n
+0000076004 00000 n
+0000076189 00000 n
+0000076363 00000 n
+0000076553 00000 n
+0000076727 00000 n
+0000076942 00000 n
+0000077109 00000 n
+0000077293 00000 n
+0000077477 00000 n
+0000077643 00000 n
+0000077869 00000 n
+0000078044 00000 n
+0000078218 00000 n
+0000078367 00000 n
+0000078552 00000 n
+0000078786 00000 n
+0000078944 00000 n
+0000079132 00000 n
+0000079317 00000 n
+0000079496 00000 n
+0000079733 00000 n
+0000079905 00000 n
+0000080081 00000 n
+0000080251 00000 n
+0000080431 00000 n
+0000080603 00000 n
+0000080827 00000 n
+0000080991 00000 n
+0000081179 00000 n
+0000081367 00000 n
+0000081580 00000 n
+0000081720 00000 n
+0000082060 00000 n
+0000083987 00000 n
+0000085644 00000 n
+0000089104 00000 n
+0000092473 00000 n
+0000095769 00000 n
+0000098441 00000 n
+0000101022 00000 n
+0000103803 00000 n
+0000106574 00000 n
+0000109611 00000 n
+0000113392 00000 n
+0000117597 00000 n
+0000120616 00000 n
+0000123725 00000 n
+0000126396 00000 n
+0000129393 00000 n
+0000131807 00000 n
+0000134643 00000 n
+0000137832 00000 n
+0000140593 00000 n
+0000143624 00000 n
+0000146461 00000 n
+0000148148 00000 n
+trailer
+<< /ID
+ % ReportLab generated PDF document -- digest (http://www.reportlab.com)
+ [(\262~\267\007\250\024\326\216\224D*%\324\240\2522) (\262~\267\007\250\024\326\216\224D*%\324\240\2522)]
+
+ /Info 211 0 R
+ /Root 210 0 R
+ /Size 327 >>
+startxref
+150334
+%%EOF
diff --git a/pdk/docs/compatibility/android-cts-manual-r4.pdf b/pdk/docs/compatibility/android-cts-manual-r4.pdf
new file mode 100644
index 0000000..f16b6f9
--- /dev/null
+++ b/pdk/docs/compatibility/android-cts-manual-r4.pdf
Binary files differ
diff --git a/pdk/docs/compatibility/compatibility_toc.cs b/pdk/docs/compatibility/compatibility_toc.cs
index 5688d14..183c0de 100644
--- a/pdk/docs/compatibility/compatibility_toc.cs
+++ b/pdk/docs/compatibility/compatibility_toc.cs
@@ -7,12 +7,13 @@
<ul>
<li><h2>Getting Started</h2><ul>
<li><a href="<?cs var:toroot ?>compatibility/overview.html">Compatibility Overview</a></li>
- <li><a href="">Current CDD</a></li>
+ <li><a href="<?cs var:toroot ?>compatibility/android-2.3-cdd.pdf">Current CDD</a></li>
<li><a href="<?cs var:toroot ?>compatibility/cts-intro.html">CTS Introduction</a></li>
+ <li><a href="<?cs var:toroot ?>compatibility/cts-development.html">CTS Development</a></li>
</ul></li>
<li><h2>More Information</h2><ul>
- <li><a href="<?cs var:toroot ?>downloads/index.html">Downloads</a></li>
+ <li><a href="<?cs var:toroot ?>compatibility/downloads.html">Downloads</a></li>
<li><a href="<?cs var:toroot ?>faqs.html#compatibility">FAQs</a></li>
<li><a href="<?cs var:toroot ?>compatibility/contact-us.html">Contact Us</a></li>
</ul></li>
diff --git a/pdk/docs/compatibility/contact-us.jd b/pdk/docs/compatibility/contact-us.jd
index ba4e887..2aa2aa1 100644
--- a/pdk/docs/compatibility/contact-us.jd
+++ b/pdk/docs/compatibility/contact-us.jd
@@ -7,13 +7,12 @@
out of any of these options, please first read "Getting the Most from Our
Lists" on the <a href="{@docRoot}community/index.html">Community page.</a></p>
-<h3>Discussion Group</h3>
+<h3>For General Discussion</h3>
<p>The preferred way to reach us is via the <a
-href="http://groups.google.com/group/android-compatibility">android-compatibility
-mailing list</a>. Use this list for all your compatibility-related questions.
-Please be aware that this is a public forum.</p>
+href="mailto:compatibility@android.com">compatibility@android.com
+address</a>.</p>
-<h3>CTS Technical Questions</h3>
+<h3>For CTS Technical Questions</h3>
<p>If you have specific issues with the Compatibility Test Suite that require
you to disclose information you'd prefer not to be public, you can contact an
email address we've set up specifically this purpose: <a
@@ -23,9 +22,9 @@
list. Note also that this list is for specific technical questions; general
inquiries will also be directed back to the android-compatibility list.</p>
-<h3>Private Inquiries</h3>
+<h3>For Business Inquiries</h3>
<p>Finally, business inquiries about the compatibility program, including
requests to use branding elements and so on, can be sent to the address <a
-href="mailto:compatibility@android.com">compatibility@android.com</a>. Like
+href="mailto:android-partnerships@google.com">android-partnerships@google.com</a>. Like
the CTS address, this address is for specific, private inquiries; general
questions will be directed back to the android-compatibility list.</p>
diff --git a/pdk/docs/compatibility/cts-development.jd b/pdk/docs/compatibility/cts-development.jd
new file mode 100644
index 0000000..7a2f5af
--- /dev/null
+++ b/pdk/docs/compatibility/cts-development.jd
@@ -0,0 +1,130 @@
+page.title=CTS Development
+doc.type=compatibility
+@jd:body
+
+<h3>Initializing Your Repo Client</h3>
+
+<p>Follow the
+<a href="{@docRoot}source/download.html">instructions</a>
+to get and build the Android source code but specify "-b froyo"
+when issuing the "repo init" command. This assures that your CTS
+changes will be included in the next CTS release and beyond.</p>
+
+<h3>Setting Up Eclipse</h3>
+
+<p>Follow the
+<a href="{@docRoot}source/using-eclipse.html">instructions</a>
+to setup Eclipse but execute the following command to generate the
+.classpath file rather than copying the one from the development
+project:</p>
+
+<pre>
+cd /path/to/android/root
+./cts/development/ide/eclipse/genclasspath.sh > .classpath
+chmod u+w .classpath
+</pre>
+
+<p>This .classpath file will contain both the Android framework
+packages and the CTS packages.</p>
+
+<h3>Building and Running CTS</h3>
+
+<p>Execute the following commands to build CTS and start the interactive
+CTS console:</p>
+
+<pre>
+cd /path/to/android/root
+make cts
+cts
+</pre>
+
+<p>Provide arguments to CTS to immediately start executing a test:</p>
+
+<pre>
+cts start --plan CTS -p android.os.cts.BuildVersionTest
+</pre>
+
+<h3>Writing CTS Tests</h3>
+
+<p>CTS tests use JUnit and the Android testing APIs. Review the
+<a href="http://d.android.com/guide/topics/testing/testing_android.html">Testing
+and Instrumentation</a> tutorial while perusing the existing tests under the
+"cts/tests/tests" directory. You will see that CTS tests mostly follow the same
+conventions used in other Android tests.</p>
+
+<p>Since CTS runs across many production devices, the tests must follow
+these rules:</p>
+
+<ul>
+ <li>Must take into account varying screen sizes, orientations, and
+ keyboard layouts.</li>
+ <li>Only use public API methods. In other words, avoid all classes,
+ methods, and fields that are annotated with the "hide" annotation.</li>
+ <li>Avoid relying upon particular view layouts or depend on the
+ dimensions of assets that may not be on some device.</li>
+ <li>Don't rely upon root privileges.</li>
+</ul>
+
+<h4>Test Naming and Location</h4>
+
+<p>Most CTS test cases target a specific class in the Android API. These tests
+have Java package names with a "cts" suffix like "android.view.cts" and class
+names with the "Test" suffix like "ViewTest." Each test case consists of
+multiple tests, where each test usually exercises a particular API method of
+the API class being tested. Each test is annotated with a @TestTargetNew
+annotation to indicate what API method is being exercised. These tests are
+arranged in a directory structure where tests are grouped into different
+categories like "widgets" and "views."</p>
+
+<p>For example, the CTS test for "android.widget.TextView" is
+"android.widget.cts.TextVietTest" found under the
+"cts/tests/tests/widget/src/android/widget/cts" directory with its
+Java package name as "android.widget.cts" and its class name as
+"TextViewTest." The "TextViewTest" class has a test called "testSetText"
+that exercises the "setText" method and a test named "testSetSingleLine" that
+calls the "setSingleLine" method. Each of those tests have @TestTargetNew
+annotations indicating what they cover.</p>
+
+<p>Some CTS tests do not directly correspond to an API class but are placed in
+the most related package possible. For instance, the CTS test,
+"android.net.cts.ListeningPortsTest," is in the "android.net.cts," because it
+is network related even though there is no "android.net.ListeningPorts" class.
+Thus, use your best judgement when adding new tests and refer to other tests
+as examples.</p>
+
+<h4>New Test Packages</h4>
+
+<p>When adding new tests, there may not be an existing directory to place your
+test. In that case, refer to the example under "cts/tests/tests/example" and
+create a new directory. Furthermore, make sure to add your new package's
+module name from its Android.mk to "CTS_COVERAGE_TEST_CASE_LIST" in
+"cts/CtsTestCaseList.mk." This Makefile is used by "build/core/tasks/cts.mk"
+to glue all the tests together to create the final CTS package.</p>
+
+<h4>Test Stubs and Utilities</h4>
+
+<p>Some tests use additional infrastructure like separate activities
+and various utilities to perform tests. These are located under the
+"cts/tests/src" directory. These stubs aren't separated into separate test
+APKs like the tests, so the "cts/tests/src" directory does not have additional
+top level directories like "widget" or "view." Follow the same principle of
+putting new classes into a package with a name that correlates to the purpose
+of your new class. For instance, a stub activity used for testing OpenGL like
+"GLSurfaceViewStubActivity" belongs in the "android.opengl.cts" package under
+the "cts/tests/src/android/opengl" directory.</p>
+
+<h3>Other Tasks</h3>
+
+<p>Besides adding new tests there are other ways to contribute to CTS:</p>
+
+<ul>
+ <li>Fix or remove tests annotated with BrokenTest and KnownFailure.</li>
+</ul>
+
+<h3>Submitting Your Changes</h3>
+
+<p>Follow the
+<a href="{@docRoot}source/submit-patches.html">Android
+contributors' workflow</a> to contribute changes to CTS. A reviewer
+will be assigned to your change, and your change should be reviewed shortly!</p>
+
diff --git a/pdk/docs/compatibility/cts-intro.jd b/pdk/docs/compatibility/cts-intro.jd
index f1d2359..5d80a45 100644
--- a/pdk/docs/compatibility/cts-intro.jd
+++ b/pdk/docs/compatibility/cts-intro.jd
@@ -13,10 +13,14 @@
<h3>Workflow</h3>
<ol>
-<li>Obtain the CTS source code. The CTS is included in the Android source code available from the Android
-Open Source Project. (To get a copy of that source code, <a
-href="{@docRoot}source/download.html">read this page.</a></li>
+<li><a href="{@docRoot}compatibility/downloads.html">Download</a> the CTS.
<li>Attach at least one device (or emulator) to your machine.</li>
+<li>For CTS 2.1 R2 and beyond, setup your device (or emulator) to run the accessibility tests:
+ <ol>
+ <li>adb install -r android-cts/repository/testcases/CtsDelegatingAccessibilityService.apk</li>
+ <li>On the device, enable Settings > Accessibility > Accessibility > Delegating Accessibility Service</li>
+ </ol>
+</li>
<li>Launch the CTS. The CTS test harness loads the test plan onto the attached devices. For each test in the test harness:
<ul>
<li>The test harness pushes a .apk file to each device, executes the test through instrumentation, and records test results.</li>
diff --git a/pdk/docs/compatibility/downloads.jd b/pdk/docs/compatibility/downloads.jd
new file mode 100644
index 0000000..61bdfd9
--- /dev/null
+++ b/pdk/docs/compatibility/downloads.jd
@@ -0,0 +1,60 @@
+page.title=Android Compatibility Downloads
+doc.type=compatibility
+@jd:body
+<p>Thanks for your interest in Android Compatibility! The links below allow
+you to access the key documents and information.</p>
+
+<h2>Android 2.3</h2>
+<p>Android 2.3 is the release of the development milestone code-named
+Gingerbread. Android 2.3 is the current version of Android. Source code for
+Android 2.3 is found in the 'gingerbread' branch in the open-source tree. A
+CTS release for Android 2.3 has not yet been prepared, but one will be
+available soon.
+</p>
+<ul>
+ <li><a href="{@docRoot}compatibility/android-2.3-cdd.pdf">Android 2.3 Compatibility Definition Document (CDD)</a></li>
+ <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.3_r1-x86.zip">Android 2.3 R1 Compatibility Test Suite (CTS)</a></li>
+</ul>
+
+<h2>Android 2.2</h2>
+<p>Android 2.2 is the release of the development milestone code-named
+FroYo. Source code for Android 2.2 is found in the 'froyo' branch in the
+open-source tree.
+</p>
+<ul>
+ <li><a href="{@docRoot}compatibility/android-2.2-cdd.pdf">Android 2.2 Compatibility Definition Document (CDD)</a></li>
+ <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.2_r4-x86.zip">Android 2.2 R4 Compatibility Test Suite (CTS)</a></li>
+</ul>
+
+<h2>Android 2.1</h2>
+<p>Android 2.1 is the release of the development milestone code-named
+Eclair. Source code for Android 2.1 is found in the 'eclair' branch in the
+open-source tree. Note that for technical reasons, there is no compatibility
+program for Android 2.0 or 2.0.1, and new devices must use Android 2.1.
+</p>
+<ul>
+ <li><a href="{@docRoot}compatibility/android-2.1-cdd.pdf">Android 2.1 Compatibility Definition Document (CDD)</a></li>
+ <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.1_r5-x86.zip">Android 2.1 R5 Compatibility Test Suite (CTS)</a></li>
+</ul>
+
+<h2>Android 1.6</h2>
+<p>Android 1.6 was the release of the development milestone code-named Donut.
+Android 1.6 was obsoleted by Android 2.1. Source code for Android 1.6 is found
+in the 'donut' branch in the open-source tree.
+<ul>
+ <li><a href="{@docRoot}compatibility/android-1.6-cdd.pdf">Android 1.6 Compatibility Definition Document (CDD)</a></li>
+</ul>
+
+<h2>Compatibility Test Suite Manual</h2>
+<p>The CTS user manual is applicable to any CTS version, but CTS 2.1 R2 and
+beyond require
+<a href="{@docRoot}compatibility/cts-intro.html">additional steps</a>
+to run the accessibility tests.
+<ul>
+ <li><a href="{@docRoot}compatibility/android-cts-manual-r4.pdf">Compatibility Test Suite (CTS) User Manual</a></li>
+</ul>
+
+<h2>Older Android Versions</h2>
+<p>There is no Compatibility Program for older versions of Android, such as Android
+1.5 (known in development as Cupcake). New devices intended to be Android
+compatible must ship with Android 1.6 or later.</p>
diff --git a/pdk/docs/compatibility/index.jd b/pdk/docs/compatibility/index.jd
index 0c39a98..e4e30a8 100644
--- a/pdk/docs/compatibility/index.jd
+++ b/pdk/docs/compatibility/index.jd
@@ -1,17 +1,21 @@
page.title=Android Compatibility
doc.type=compatibility
@jd:body
-<p>Android is an open source product, and anyone can use the source code to build
-devices. The purpose of the Android compatibility program is to help Android
-device implementations remain compatible with all apps.</p>
-<p>A device is considered compatible if existing and new third-party
-applications run correctly on it. Poor device implementations that change APIs
-or alter behaviors will break these apps and so are not compatible. The
-Android compatibility program's aim is to ensure that these APIs are
-consistently implemented across devices.</p>
-<p>The latest version of the Android source code and compatibility program is
-1.6, which roughly corresponded to the Donut branch. The compatibility
-program for Android 2.x (corresponding to Eclair) is coming soon.</p>
+<p>Android's purpose is to establish an open platform for developers to build
+innovative mobile apps. Three key components work together to realize this
+platform.</p>
+<p>The Android Compatibility Program defines the technical details of Android
+platform and provides tools used by OEMs to ensure that developers’ apps run
+on a variety of devices. The Android SDK provides built-in tools that
+Developers use to clearly state the device features their apps require. And
+Android Market shows apps only to those devices that can properly run
+them.</p>
+<p>These pages describe the Android Compatibility Program and how to get
+access to compatibility information and tools. The latest version of the
+Android source code and compatibility program is 2.3, which
+corresponded to the Gingerbread branch.</p>
+
+
<h2>Why build compatible Android devices?</h2>
<h3>Users want a customizable device.</h3>
<p>A mobile phone is a highly personal, always-on, always-present gateway to
@@ -20,7 +24,7 @@
platform for running after-market applications.</p>
<h3>Developers outnumber us all.</h3>
-<p>No device manufacturer can hope to write all the software that anyone could
+<p>No device manufacturer can hope to write all the software that a person could
conceivably need. We need third-party developers to write the apps users want,
so the Android Open Source Project aims to make it as easy and open as
possible for developers to build apps.</p>
@@ -38,30 +42,23 @@
sure your device is compatible with Android. For more details about the
Android compatibility program in general, see <a
href="{@docRoot}compatibility/overview.html">the program overview</a>.</p>
-<p>Building a compatible device is a four-step process:</p>
+<p>Building a compatible device is a three-step process:</p>
<ol>
- <li><b>Obtain the Android software stack source code</b><p>This is the
+ <li><b>Obtain the Android software source code</b><p>This is the
<a href="{@docRoot}source/index.html">source code for the Android
platform</a>, that you port to your hardware.</p></li>
- <li><b>Comply with Android Compatibility Definition Document</b><p>
- This document enumerates the software and the hardware features of
+ <li><b>Comply with Android Compatibility Definition Document (CDD)</b><p>
+ The CDD enumerates the software and hardware requirements of
a compatible Android device.</p></li>
<li><b>Pass the Compatibility Test Suite (CTS)</b><p>You can use the CTS
(included in the Android source code) as an ongoing aid to compatibility
during the development process.</p></li>
- <li><b>Submit CTS report</b><p>[Optional] You can also submit your CTS report,
- so that it can be validated and recorded.</p><p><i>Note:
- the submission system is currently under construciton, and is not currently
- available.</i></p></li>
</ol>
-<h2>Benefits of compatibility</h2>
-<p>By submitting a validated CTS report, you receive public recognition of
-your device's compatibility. This also opens up additional options you can
-pursue such as use of the Android branding, access to Android Market, and
-more.</p>
-<p>As a consequence of some legal quirks, we aren't able to offer automatic
-licensing of either the Android Market or branding. To actually obtain access
-to these programs, you will need to <a
-href="{@docRoot}compatibility/contact-us.html">contact us</a> to obtain a
-license.</p>
+<h2>Joining the Ecosystem</h2>
+<p>Once you've built a compatible device, you may wish to include Android
+Market to provide your users access to the third-party app ecosystem.
+Unfortunately, for a variety of legal and business reasons, we aren't able to
+automatically license Android Market to all compatible devices. To inquire
+about access about Android Market, you can <a
+href="{@docRoot}compatibility/contact-us.html">contact us</a></p>
diff --git a/pdk/docs/compatibility/overview.jd b/pdk/docs/compatibility/overview.jd
index 039e2c2..31a4832 100644
--- a/pdk/docs/compatibility/overview.jd
+++ b/pdk/docs/compatibility/overview.jd
@@ -35,11 +35,13 @@
compatible.</p></li>
<li><b>Minimize costs and overhead associated with
compatibility.</b><p>Ensuring compatibility should be easy and inexpensive to
-device manufacturers. The testing tool (CTS) is free and will soon be available
-in open source. CTS is designed to be used for continuous self-testing during
-the device development process to eliminate the cost of changing your workflow
-or sending your device to a third party for testing. Meanwhile, there are no
-required certifications, and thus no corresponding costs and fees.</p></li>
+device manufacturers. The testing tool (CTS) is free, open source, and
+available for <a href="{@docRoot}compatibility/downloads.html">download</a>.
+CTS is designed to be used for continuous self-testing
+during the device development process to eliminate the cost of changing your
+workflow or sending your device to a third party for testing. Meanwhile, there
+are no required certifications, and thus no corresponding costs and
+fees.</p></li>
</ul>
<p>The Android compatibility program consists of three key components:</p>
<ul>
@@ -76,8 +78,9 @@
simply examine <a href="">the latest CDD</a>.</p>
<h3>Compatibility Test Suite (CTS)</h3>
-<p>The CTS is a free, commercial-grade test suite, available along with the
-Android source code. The CTS represents the "mechanism" of compatibility.</p>
+<p>The CTS is a free, commercial-grade test suite, available for
+<a href="{@docRoot}compatibility/downloads.html">download</a>.
+The CTS represents the "mechanism" of compatibility.</p>
<p>The CTS runs on a desktop machine and executes test cases directly on
attached devices or an emulator. The CTS is a set of unit tests designed to be
integrated into the daily workflow (such as via a continuous build system) of
diff --git a/pdk/docs/downloads/downloads_toc.cs b/pdk/docs/downloads/downloads_toc.cs
deleted file mode 100644
index 28f43af..0000000
--- a/pdk/docs/downloads/downloads_toc.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-<script type="text/javascript" language="JavaScript">
-<!--
-function nothing() {}
--->
-</script>
-
-<ul>
- <li><h2>PDK</h2><ul>
- <li><a href="">PDK 1.6</a></li>
- </ul></li>
-
- <li><h2>Compatibility</h2><ul>
- <li><a href="">Android 1.6</a></li>
- </ul></li>
-</ul>
-
-<script type="text/javascript">
-<!--
- buildToggleLists();
-//-->
-</script>
diff --git a/pdk/docs/downloads/index.jd b/pdk/docs/downloads/index.jd
deleted file mode 100644
index b6f5a2f..0000000
--- a/pdk/docs/downloads/index.jd
+++ /dev/null
@@ -1,44 +0,0 @@
-page.title=Downloads
-doc.type=downloads
-doc.hidenav=true
-@jd:body
-<p>This page provides access to various downloads. Note that if you're looking
-for the Android SDK (for application developers), you should visit <a
-href="http://developer.android.com/sdk/index.html">developer.android.com</a>.</p>
-
-<h2>Compatibility</h2>
-<p>The Compatibility Definition Document can be downloaded below. The
-Compatibility Test Suite is available in the open-source tree.</p>
-<table class="download">
- <tr>
- <th>Item</th>
- <th>File</th>
- <th>Size</th>
- </tr>
- <tr>
- <td>Android CDD 2.1</td>
- <td><a href="">android-cdd-2.1.pdf</a></td>
- <td>23070805 bytes</td>
- </tr>
- <tr class="alt-color">
- <td>Android CTS 2.1 Manual</td>
- <td><a href="">android-cts-manual-2.1.0.pdf</a></td>
- <td>23070805 bytes</td>
- </tr>
- <tr>
- <td>Android CDD 1.6</td>
- <td><a href="">android-cdd-1.6.pdf</a></td>
- <td>23070805 bytes</td>
- </tr>
- <tr class="alt-color">
- <td>Android CTS 1.6 Manual</td>
- <td><a href="">android-cts-manual-1.6.4.pdf</a></td>
- <td>23070805 bytes</td>
- </tr>
-</table>
-<p>For more information on how to build an Android-compatible device, see the
-<a href="{@docRoot}compatibility/index.html">Compatibility</a> page. Note that
-there is no compatibility program for Android 1.5 and earlier. Note also that
-there is no compatibility program for Android 2.0, since it was superceded by
-Android 2.1 after only a few weeks.
-</p>
diff --git a/pdk/docs/faqs.jd b/pdk/docs/faqs.jd
index a55d380..00db026 100644
--- a/pdk/docs/faqs.jd
+++ b/pdk/docs/faqs.jd
@@ -74,8 +74,8 @@
<p>Finally, Google works on the next version of the Android platform in tandem
with developing a flagship device. This branch pulls in changes from the
experimental and stable branches as appropriate.</p>
-<p>You can find more information on this topic at our Branches Releases
- page.</p>
+<p>You can find more information on this topic at our <a
+href="{@docRoot}source/code-lines.html">Branches and Releases</a> page.</p>
<h3>Why are parts of Android developed in private?</h3>
<p>It typically takes over a year to bring a device to market, but of course
@@ -86,16 +86,16 @@
<p>To address this, some parts of the next version of Android including the
core platform APIs are developed in a private branch. These APIs constitute
the next version of Android. Our aim is to focus attention on the current
- stable version of the Android source code, while we refine the next version
- of the platform using the flagship Android devices. This allows developers
+ stable version of the Android source code, while we create the next version
+ of the platform as driven by flagship Android devices. This allows developers
and OEMs to focus on a single version without having to track unfinished
- future work just to keep up.Other parts of the Android system that aren't
+ future work just to keep up. Other parts of the Android system that aren't
related to application compatibility are developed in the open, however.
It's our intention to move more of these parts to open development over
time.</p>
<h3>When are source code releases made?</h3>
-<p>When they are ready. Some parts of Android are developed in the open, and
+<p>When they are ready. Some parts of Android are developed in the open,
so that source code is always available. Other parts are developed first in
a private tree, and that source code is released when the next platform
version is ready.</p>
@@ -143,8 +143,7 @@
"Android compatible devices" from devices that merely run derivatives of the
source code. We welcome all uses of the Android source code, but only
Android compatible devices -- as defined and tested by the Android
- Compatibility Program -- may call themselves "Android" and participate in
- the Android ecosystem.</p>
+ Compatibility Program -- may participate in the Android ecosystem.</p>
<h3>How can I contribute to Android?</h3>
<p>There are a number of ways you can contribute to Android. You can report
@@ -170,8 +169,9 @@
<p>Once submitted, changes need to be accepted by a designated Approver.
Approvers are typically Google employees, but the same approvers are
responsible for all submissions, regardless of origin.</p>
-<p>You can find more information on this topic at the Submitting Patches
- page.</p>
+<p>You can find more information on this topic at the <a
+ href="{@docRoot}source/submit-patches.html">Submitting Patches</a>
+ page.</p>
<a name="compatibility"></a><h2>Compatibility</h2>
<h3>What does "compatibility" mean?</h3>
@@ -185,7 +185,7 @@
<p>In other words, compatibility is a prerequisite to participate in the
Android apps ecosystem. Anyone is welcome to use the Android source code,
but if the device isn't compatible, it's not considered part of the Android
- ecosystem, and irrelevant to developers.</p>
+ ecosystem.</p>
<h3>What is the role of Android Market in compatibility?</h3>
<p>Devices that are Android compatible may seek to license the Android Market
@@ -200,11 +200,11 @@
Compatibility Definition Document (CDD) spells out the specific device
configurations that will be considered compatible.</p>
<p>For example, though the Android source code could be ported to run on a
- device that doesn't have a camera, the CDD requires that in order to be
- compatible, all devices must have a camera. This allows developers to rely
- on a consistent set of device capabilities when writing their apps.</p>
+ phone that doesn't have a camera, the CDD requires that in order to be
+ compatible, all phones must have a camera. This allows developers to rely
+ on a consistent set of capabilities when writing their apps.</p>
<p>The CDD will evolve over time to reflect market realities. For instance,
- the 1.6 CDD only allows cell phones, but the 2.x CDD allows devices to omit
+ the 1.6 CDD only allows cell phones, but the 2.1 CDD allows devices to omit
telephony hardware, allowing for non-phone devices such as tablet-style
music players to be compatible. As we make these changes, we will also
augment Android Market to allow developers to retain control over where
@@ -214,13 +214,10 @@
devices.</p>
<h3>If my device is compatible, does it automatically have access to Android Market and branding?</h3>
-<p>Android Market is a service operated by Google. For legal and business
- reasons, Google isn't able to make that service available in all parts of
- the world. Similarly, Google is unable to license the Android trademark for
- use in all cases.</p>
-<p>As a result, achieving compatibility does not automatically entitle a
- device to include Android Market or use the Android name. Device
- manufacturers should contact Google to obtain access to those tools.</p>
+<p>Android Market is a service operated by Google. Achieving compatibility is
+ a prerequisite for obtaining access to the Android Market software and branding.
+ Device manufacturers should contact Google to obtain access to Android
+ Market.</p>
<h3>If I am not a manufacturer, how can I get Android Market?</h3>
<p>Android Market is only licensed to handset manufacturers shipping devices.
@@ -229,9 +226,9 @@
<h3>How can I get access to the Google apps for Android, such as Maps?</h3>
<p>The Google apps for Android, such as YouTube, Google Maps and Navigation,
- Gmail, and so on are not part of Android, and are licensed separately.
- Contact android-partnerships@google.com for inquiries related to those
- apps.</p>
+ Gmail, and so on are Google properties that are not part of Android, and
+ are licensed separately. Contact android-partnerships@google.com for
+ inquiries related to those apps.</p>
<h3>Is compatibility mandatory?</h3>
<p>No. The Android Compatibility Program is optional. Since the Android source
@@ -246,7 +243,7 @@
test a device.</p>
<h3>How long does compatibility take?</h3>
-<p>The process is automatic. The Compatibility Test Suite generates a report
+<p>The process is automated. The Compatibility Test Suite generates a report
that can be provided to Google to verify compatibility. Eventually we intend
to provide self-service tools to upload these reports to a public database.</p>
@@ -271,12 +268,15 @@
generally have much effect on third-party apps. As such, device builders are
free to customize the user interface as much as they like. The Compatibility
Definition Document does restrict the degree to which OEMs may alter the
- system user interface for the few areas that do impact third-party apps.</p>
+ system user interface for areas that do impact third-party apps.</p>
<h3>When are compatibility definitions released for new Android versions?</h3>
<p>Our goal is to release new versions of Android Compatibility Definition
Documents (CDDs) once the corresponding Android platform version has
- converged enough to permit it. Since the CDDs</p>
+ converged enough to permit it. While we can't release a final draft of a CDD
+ for an Android software version before the first flagship device ships with
+ that software, final CDDs will always be released after the first device.
+ However, wherever practical we will make draft versions of CDDs available.</p>
<h3>How are device manufacturers' compatibility claims validated?</h3>
<p>There is no validation process for Android device compatibility. However,
diff --git a/pdk/docs/images/code-lines.png b/pdk/docs/images/code-lines.png
index acfb77b..f86260c 100644
--- a/pdk/docs/images/code-lines.png
+++ b/pdk/docs/images/code-lines.png
Binary files differ
diff --git a/pdk/docs/index.jd b/pdk/docs/index.jd
index 217877d..d8f1739 100644
--- a/pdk/docs/index.jd
+++ b/pdk/docs/index.jd
@@ -1,7 +1,27 @@
page.title=Welcome to Android
home=true
@jd:body
-<div style="float: left; width: 45%; font-size: 1.3em;">
+<div style="float: right; width: 35%;">
+<h3 style="padding-top: 0px;">News</h3>
+<p><b>Compatibility Definition for Android 2.3</b><br/>
+The Compatibility Definition Document for Android 2.3 has been published.
+The 2.3 CDD allows device manufacturers to use the Android source code to ship
+a significantly wider variety of devices, including devices with extra-large
+screens, such as tablets. A release of the Compatibility Test Suite is not
+yet available, but will be soon. For more information, <a
+href="{@docRoot}compatibility/index.html">visit the Compatibility page.</a>
+</p>
+<p><b>Source Code Available for Android 2.3</b><br/>
+The source code for the Android 2.3 platform and software stack has been
+released! This release allows OEMs to begin preparing Android 2.3 for
+installation on new and existing devices, and allows hobbyists, enthusiasts,
+and researchers to develop custom builds. For information on how to obtain the
+software,
+<a href="{@docRoot}source/download.html">visit our 'Getting the Source' page.</a>
+</p>
+</div>
+<img style="float: right; padding-right: 1.5em;" src="{@docRoot}images/home-bugdroid.png" alt="Android Mascot"/>
+<div style="font-size: 1.3em;">
<p>Here you can find the information and source code you need to build an
Android-compatible device.</p>
<p>Android is an open-source software stack for mobile devices, and a
@@ -12,51 +32,40 @@
created Android, and made its source code open.</p>
<p><a href="{@docRoot}about/index.html">Learn more »</a></p>
</div>
-<div style="float: right; width: 35%;">
-<h3 style="padding-top: 0px;">News</h3>
-<p><b>Site redesign</b><br/>
-You're looking at the new and improved source.android.com! We've updated
-the layout and site design, and also added new information. We hope you find
-these improvements helpful.</p>
-<p><b>Introducing the Compatibility Program</b><br/>
-We're pleased to introduce the Android Compatibility Program. We've released
-two tools -- the Compatibility Definition Document and the Compatibility Test
-Suite -- to help device manufacturers build compatible devices. Full details
-of the Compatibility Program will be available in the first quarter of 2010.</p>
-</div>
-<img style="float: right; padding-right: 1.5em;" src="{@docRoot}images/home-bugdroid.png" alt="Android Mascot"/>
<div style="clear: both;"/>
<table border="0" style="border: 0px; margin: 0px; padding: 0px;"><tr><td align="center" style="border: 0px; margin: 0px; padding: 0px;">
<div class="rebox lil" style="float: left; width: 30%; margin: 1em;">
- <h2 style="color: white; background-color: #95C0D0; border: 0px;">Get Involved</h2>
+ <h2 style="color: white; background-color: #95C0D0; border: 0px;">Source</h2>
<div class="p">
- <p><img src="images/lil-wrench.png" alt="" style="margin: 1em;"/>
+ <p><img src="images/lil-wrench.png" alt="" style="margin: 1em; margin-bottom: 5em;"/>
If you're interested in contributing to the Android source code or helping
- out with the project in some other way, click here.</p>
- <p><a href="{@docRoot}source/index.html">More »</a></p>
+ out with the open-source project, our Source pages have the information
+ you need.</p>
+ <p><a href="{@docRoot}source/index.html">Get Involved »</a></p>
</div>
</div>
<div class="rebox lil" style="float: left; width: 30%; margin: 1em;">
- <h2 style="color: white; background-color: #95C0D0; border: 0px;">Build a Device</h2>
+ <h2 style="color: white; background-color: #95C0D0; border: 0px;">Porting</h2>
<div class="p">
- <p><img src="images/lil-wrench.png" alt="" style="margin: 1em;"/>
- If you're an engineer building a device intended to run the Android
- software stack, click here to find porting information and tips.</p>
- <p><a href="{@docRoot}porting/index.html">More »</a></p>
+ <p><img src="images/lil-wrench.png" alt="" style="margin: 1em; margin-bottom: 5em;"/>
+ If you're an engineer building a device
+ intended to run the Android software stack, look at our Porting pages for
+ information and tips.</p>
+ <p><a href="{@docRoot}porting/index.html">Build a Device »</a></p>
</div>
</div>
<div class="rebox lil" style="float: left; width: 30%; margin: 1em;">
<h2 style="color: white; background-color: #95C0D0; border: 0px;">Compatibility</h2>
<div class="p">
- <p><img src="images/lil-wrench.png" alt="" style="margin: 1em;"/>
- If you're an OEM or other organization building an Android device, click
- here to find out how to ensure that your device is fully compatible, and
- how to take advantage of the benefits of compatibility.</p>
- <p><a href="{@docRoot}compatibility/index.html">More »</a></p>
+ <p><img src="images/lil-wrench.png" alt="" style="margin: 1em; margin-bottom: 5em;"/>
+ If you're an organization building an Android device, you'll want to check out our
+ Compatibility pages to find out how to take advantage of the benefits of
+ compatibility.</p>
+ <p><a href="{@docRoot}compatibility/index.html">Get Compatible »</a></p>
</div>
</div>
</td></tr></table>
diff --git a/pdk/docs/porting/bluetooth.jd b/pdk/docs/porting/bluetooth.jd
index ceb8683..c792bd2 100755
--- a/pdk/docs/porting/bluetooth.jd
+++ b/pdk/docs/porting/bluetooth.jd
@@ -17,7 +17,8 @@
</div>
</div>
-<p>Android's Bluetooth stack uses BlueZ version 3.36 for GAP, SDP, and RFCOMM profiles, and is a SIG-qualified Bluetooth 2.0 + EDR host stack.</p>
+<p>Android's Bluetooth stack uses BlueZ for GAP, SDP, and RFCOMM profiles, and
+is a SIG-qualified Bluetooth stack. </p>
<p>Bluez is GPL licensed, so the Android framework interacts with userspace bluez code through D-BUS IPC to avoid proprietary code.</p>
@@ -33,7 +34,7 @@
<a name="androidBluetoothPorting"></a><h3>Porting</h3>
-<p>BlueZ is Bluetooth 2.0 compatible and should work with any 2.0 chipset. There are two integration points:</p>
+<p>BlueZ is Bluetooth 2.1 compatible and should work with any 2.1 chipset and is backward compatibile with older Bluetooth versions. There are two integration points:</p>
<p><ul>
<li>UART driver</li>
<li>Bluetooth Power On / Off</li>
@@ -67,7 +68,7 @@
<a name="androidBluetoothTroubleshooting"></a><h3>Troubleshooting</h3>
<p><strong>Debugging</strong></p>
-<p>To debug your bluetooth implementation, start by reading the logs (<code>adb logcat</code>) and look for ERRROR and WARNING messages regarding Bluetooth.
+<p>To debug your bluetooth implementation, start by reading the logs (<code>adb logcat</code>) and look for ERRROR and WARNING messages regarding Bluetooth.
Andoird uses Bluez, which comes with some useful debugging tools. The snippet below provides examples in a suggested order:</p>
<pre>
hciconfig -a # print BT chipset address and features. Useful to check if you can communicate with your BT chipset.
@@ -158,14 +159,79 @@
<li>QDID B015261: Host stack (SDP, L2CAP, GAP, RFCOMM, SPP, AVCTP, AVRCP, GAVDP, AVDTP, A2DP)</li>
<li>QDID B015262: EPL for HTC Sapphire (HSP, HFP)</li>
</ul>
+<h4>Android 2.0/2.1 release (eclair)</h4>
+<h4>Platform features</h4>
+<ul>
+ <li>Based on Bluez 4.47 with Linux Kernel 2.6.29</li>
+ <li>Bluetooth 2.1+EDR host stack</li>
+ <ul>
+ <li>Support for auto-pairing with '0000' devices</li>
+ <li>Support for Simple Secure Pairing</li>
+ </ul>
+ <li>Headset Profile 1.1 in Audio Gateway role</li>
+ <li>Handsfree Profile 1.5 in Audio Gateway role</li>
+ <ul>
+ <li>Three-way calling </li>
+ <li>Phonebook over AT commands </li>
+ <li>Volume synchronization</li>
+ <li>eSCO</li>
+ <li>Extensive bug fixes and compatibility improvements</li>
+ </ul>
+ <li>Stereo Bluetooth (A2DP 1.2) in Source role</li>
+ <ul>
+ <li>AVDTP 1.2 in Acceptor and Initiator roles</li>
+ <li>GAVDTP 1.0 in Acceptor and Initiator roles</li>
+ <li>44.1 khz, stereo, software SBC codec</li>
+ </ul>
+ <li>Remote Control (AVRCP 1.0) in Target role</li>
+ <ul>
+ <li>AVCTP 1.3 in Target role</li>
+ <li>play/pause/stop/prev/next</li>
+ </ul>
+ <li> Object Push Profile version 1.1 </li>
+ <ul>
+ <li>Adds ability to transfer pictures, videos</li>
+ <li>Transfer of contacts using vCard is not supported in this release.</li>
+ </ul>
+ <li>Phone Book Address Profile version 1.0</li>
+ <ul>
+ <li>Phone Book Server Equipment (PSE) role supported</li>
+ </ul>
+ <li>Using Java Bluetooth APIs, an Android application can peform the
+ following:</li>
+ <ul>
+ <li>Scan for other Bluetooth devices </li>
+ <li>Query the local Bluetooth adapter for paired Bluetooth devices </li>
+ <li>Establish RFCOMM channels </li>
+ <li>Connect to other devices through service discovery </li>
+ <li>Transfer data to and from other devices </li>
+ <li>Manage multiple connections </li>
+ </ul>
+ <li>Support for Bluetooth enabled car and desk docks</li>
+ <ul>
+ <li>Framework support for routing Phone Call Audio and A2DP streaming using
+ car and desk docks. </li>
+ </ul>
+</ul>
+
+<h4>Android 2.2 release (Froyo)</h4>
+<h4>Platform features</h4>
+<ul>
+ <li>Based on Bluez 4.47 with Linux Kernel 2.6.32</li>
+ <li>No new profiles added.</li>
+ <li>Added ability to share contacts using vCard</li>
+ <li>Added ability to export all contacts - useful to transfer contacts to car kits </li>
+ <li>Improved compatibility with headsets and car kits. </li>
+</ul>
+
<h5> </h5>
<h4>Future releases</h4>
<p>This section offers a rough guide of which features the team is developing for the next release. This feature list may change without notice. It isn't possible to post scheduling advice to the mailing lists.</p>
<ul>
- <li>Java Bluetooth API</li>
- <li>Bluez 4.x with Linux Kernel 2.6.29</li>
<li>More profiles...</li>
- <li>Bluetooth 2.1+EDR</li>
+ <li>Improved compatibility with headsets and car kits</li>
+ <li>Bluetooth emulator support</li>
+ <li>Bluetooth Low Energy </li>
</ul>
<p><strong>Development Notes</strong></p>
@@ -184,10 +250,4 @@
While not officially supported, you should be able to run <code>dund</code> or <code>pand</code> daemons and, using <code>pppd</code> or <code>iptables</code>, test tethering support. Next steps include plubming the DBUS APIs to these daemons up into the Android Java framework and adding code to setup the network paths via <code>pppd</code> and / or <code>iptables</code>.<br />
<br />
</li>
- <li><strong>Emulator Support</strong><br />
- The Android emulator does not support Bluetooth at this time and there currently aren't any plans for its support.<br />
- <br />
- </li>
- <li><strong>Bluetooth 2.1 and Simple Pairing Support</strong><br />
- In order to support these features, Android needs to move to a Bluez 4.x version. This change is not scheduled at this time.</li>
</ul>
diff --git a/pdk/docs/porting/instrumentation_testing.jd b/pdk/docs/porting/instrumentation_testing.jd
index c3765f4..045291f 100755
--- a/pdk/docs/porting/instrumentation_testing.jd
+++ b/pdk/docs/porting/instrumentation_testing.jd
@@ -335,7 +335,7 @@
<pre class="prettify">
public class FrameworkInstrumentationTestRunner extends InstrumentationTestRunner {
- @Override
+ @Override
public TestSuite getAllTests() {
InstrumentationTestSuite suite = new InstrumentationTestSuite(this);
@@ -345,7 +345,7 @@
return suite;
}
- @Override
+ @Override
public ClassLoader getLoader() {
return FrameworkInstrumentationTestRunner.class.getClassLoader();
}
@@ -373,7 +373,7 @@
super("com.example", MyActivity.class);
}
- @Override
+ @Override
public void setUp() throws Exception {
super.setUp();
mLeftButton = (Button) getActivity().findViewById(R.id.leftButton);
diff --git a/pdk/docs/source/building-dream.jd b/pdk/docs/source/building-dream.jd
index 89392fd..d130524 100644
--- a/pdk/docs/source/building-dream.jd
+++ b/pdk/docs/source/building-dream.jd
@@ -3,10 +3,10 @@
@jd:body
<p><i>The information on this page is a bit out of date. We'll update this
page as soon as we can.</i></p>
-<div>The basic manifest for cupcake (and above) defines which projects are
+<div>The basic manifest for 1.6 defines which projects are
needed to do a generic build for the emulator or for unlocked Dream devices
(e.g. the Android Dev Phone 1). You need to have an appropriate device running
-a matching official image.<br><br>To build donut or master for dream (your
+a matching official image.<br><br>To build donut for dream (your
device needs to be an ADP1 running an official 1.6 system):<br><ol><li>Follow
the <a href="{@docRoot}source/download.html">normal steps</a>
to setup repo and check out the sources.
@@ -22,17 +22,6 @@
</li>
<li>from this point, the fastboot tool (which is put automatically in your path) can be used to flash a device: boot the device into the bootloader by holding the back key while pressing the power key, and run "fastboot -w flashall".<br></li>
</ol>
-To build cupcake for dream (your device needs to be an ADP1 running an official 1.5 system):<br><ol><li>Follow the <a href="{@docRoot}source/download.html">normal steps</a>
-to setup repo and check out the sources.
-</li>
-<li>At the root of your source tree, run ". build/envsetup.sh" like you normally would for an emulator build.
-</li>
-<li>Run "make adb" if you don't already have adb in your path.<br></li>
-<li>in vendor/htc/dream-open/ there is a script called "extract-files.sh" that must be run (from that directory) to extract some proprietary binaries from your device (*). You only need to do this once.<br></li>
-<li>run "lunch htc_dream-eng" to specifically configure the build system for dream (the default is the equivalent of "lunch generic-eng", which doesn't contain dream-specific files).<br></li>
-<li>run make from the top of the source tree.
-</li>
-<li>from this point, the fastboot tool (which is put automatically in your path) can be used to flash a device: boot the device into the bootloader by holding the back key while pressing the power key, and run "fastboot -w flashall".<br></li>
-</ol>
-* The Dream device software contains some proprietary binaries.For contractual reasons, these cannot be redistributed to be used directly with the Android Open-Source Project, but the provided script may be used to extract these binaries from your development device so that they can be correctly included in your build.These libraries include the openGL|ES library, the Qualcomm camera library, the HTC Radio Interface Library, etc.
+<p>Note: these instructions work for the sapphire (ADP2) build target, as
+well. Simply replace "dream" with "sapphire" above.</p>
</div>
diff --git a/pdk/docs/source/code-lines.jd b/pdk/docs/source/code-lines.jd
index 61b400d..5ceb103 100644
--- a/pdk/docs/source/code-lines.jd
+++ b/pdk/docs/source/code-lines.jd
@@ -15,7 +15,7 @@
<h3>Notes and Explanations</h3>
<ul>
<li>A <i>release</i> corresponds to a formal version of the Android platform, such
-as 1.5, 2.0, and so on. Generally speaking, a release of the platform
+as 1.5, 2.1, and so on. Generally speaking, a release of the platform
corresponds to a version of the <code>SdkVersion</code> field used in
AndroidManifest.xml files, and defined in <code>frameworks/base/api</code> in
the source tree.</li>
@@ -23,34 +23,37 @@
stack is pulling code. These include obvious projects such as the Linux kernel
and WebKit, but over time we are migrating some of the semi-autonomous
Android projects (such as Dalvik, the Android SDK tools, Bionic, and so on) to
-work as "upstream" projects. These will be developed entirely in the public
-tree, and snapshots will be periodically pulled into releases.</li>
-<li>The diagram refers to "Eclair" and "Flan"; however, they are simply
+work as "upstream" projects. Generally, these projects are developed entirely in
+the public tree. For some upstream projects, development is done by contributing
+directly to the upstream project itself. See
+<a href="{@docRoot}source/submit-patches.html#upstream-projects">Upstream Projects</a>
+for details. In both cases, snapshots will be periodically pulled into releases.</li>
+<li>The diagram refers to "Eclair" and "FroYo"; however, they are simply
placeholders, and the diagram actually reflects the overall release and
branching strategy.</li>
-<li>At all times, the Release code-line (which may actually consist of
+<li>At all times, a release code-line (which may actually consist of
more than one actual branch in git) is considered the sole canonical source
-code for a given Android platform. OEMs and other groups building devices
-should pull only from a Release branch.</li>
-<li>We will be setting up an "Experimental" code-line to capture changes from
+code for a given Android platform version. OEMs and other groups building devices
+should pull only from a release branch.</li>
+<li>We will set up "experimental" code-lines to capture changes from
the community, so that they can be iterated on, with an eye toward stability.</li>
-<li>Changes that prove stable will eventually be pulled into a Release
+<li>Changes that prove stable will eventually be pulled into a release
branch. Note that this will only apply to bug fixes, app improvements, and
other things that do not affect the APIs of the platform.</li>
-<li>Changes will be pulled into Release branches from upstream projects
-(include the Android "upstream" projects) as necessary.</li>
+<li>Changes will be pulled into release branches from upstream projects
+(including the Android "upstream" projects) as necessary.</li>
<li>The "n+1"th version (that is, next major version of the framework and
-platform APIs) will be developed by Google internally. (See below for
-details.)</li>
-<li>Changes will be pulled from upstream, Release, and Experimental branches
+platform APIs) will be developed by Google internally. See below for
+details.</li>
+<li>Changes will be pulled from upstream, release, and experimental branches
into Google's private branch as necessary.</li>
<li>When the platform APIs for the next version have stabilized and been fully
tested, Google will cut a release of the next platform version. (This
specifically refers to a new <code>SdkVersion</code>.) This will also
-correspond to the internal code-line being made a public Release branch, and the
+correspond to the internal code-line being made a public release branch, and the
new current platform code-line.</li>
-<li>When a new platform version is cut, a corresponding Experimental
-code-line.</li>
+<li>When a new platform version is cut, a corresponding experimental
+code-line will be created at the same time.</li>
</ul>
<h3>About Private Code-Lines</h3>
<p>The source management strategy above includes a code-line that Google will
@@ -62,9 +65,9 @@
Google retains responsibility for the strategic direction of Android as a
platform and a product. Our approach is based on focusing on a small number of
flagship devices to drive features, and secure protections of Android-related
-intellectual property through patents and the like.</p>
+intellectual property.</p>
<p>As a result, Google frequently has possession of confidential
-information of third parties, and we must refrain from revealing patentable
+information of third parties, and we must refrain from revealing sensitive
features until we've secured the appropriate protections. Meanwhile, there are
real risks to the platform arising from having too many platform versions
extant at once. For these reasons, we have structured the open-source project
diff --git a/pdk/docs/source/code-style.jd b/pdk/docs/source/code-style.jd
index 8b5946e..957ab02 100644
--- a/pdk/docs/source/code-style.jd
+++ b/pdk/docs/source/code-style.jd
@@ -1,7 +1,6 @@
page.title=Code Style Guidelines for Contributors
doc.type=source
@jd:body
-<div>
<p>The rules below are not guidelines or recommendations, but strict rules.
Contributions to Android generally <b>will not be accepted if they do not
adhere to these rules.</b>
@@ -11,425 +10,615 @@
</h1>
<p>We follow standard Java coding conventions. We add a few rules:
</p>
-<ol><li><a href="#exceptionsIgnore">Exceptions</a>
-: Never catch and ignore them without explanation.
-</li>
-<li><a href="#exceptionsAll">Exceptions</a>
-: do not catch generic Exception, except in library code at the root of the stack.
-</li>
-<li><a href="#finalizers">Finalizers</a>
-: generally don't use them.
-</li>
-<li><a href="#imports">Imports</a>
-: Fully qualify imports
-</li>
+<ol><li><a href="#exceptionsIgnore">Exceptions</a>: Never catch and ignore them without explanation.</li>
+<li><a href="#exceptionsAll">Exceptions</a>: do not catch generic Exception, except in library code at the root of the stack.</li>
+<li><a href="#finalizers">Finalizers</a>: generally don't use them.</li>
+<li><a href="#imports">Imports</a>: Fully qualify imports</li>
</ol>
-<h1><a>Java Library Rules</a>
-</h1>
-<p>There are conventions for using Android's Java libraries and tools. In some cases, the convention has changed in important ways and older code might use a deprecated pattern or library. When working with such code, it's okay to continue the existing style (see <a href="#consistency">Consistency</a>
-). When creating new components never use deprecated libraries.
-</p>
-<h1><a>Java Style Rules</a>
-</h1>
-<p>Programs are much easier to maintain when all files have a consistent style. We follow the standard Java coding style, as defined by Sun in their <a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Code Conventions for the Java Programming Language</a>
-, with a few exceptions and additions. This style guide is comprehensive and detailed and is in common usage in the Java community.
-</p>
-<p>In addition, we enforce the following style rules:
-</p>
-<ol><li><a href="#javadoc">Comments/Javadoc</a>
-: write it; use standard style
-</li>
-<li><a href="#shortmethods">Short methods</a>
-: don't write giant methods
-</li>
-<li>Fields: should either be at the top of the file, or immediately before the methods that use them
-</li>
-<li><a href="#localvariables">Local variables</a>
-: limit the scope
-</li>
-<li><a href="#import_style">Imports</a>
-: android; third party alphabetical; java(x)
-</li>
-<li><a href="#indentation">Indentation</a>
-: 4 spaces, no tabs.
-</li>
-<li><a href="#linelen">Line length</a>
-: 100 columns
-</li>
-<li><a href="#field_names">Field names</a>
-: Non-public, non-static fields start with m. Static fields start s.
-</li>
-<li><a href="#braces">Braces</a>
-: Opening braces don't go on their own line.
-</li>
-<li><a href="#annotations">Annotations</a>
-: Use the standard annotations.
-</li>
-<li><a href="#acronyms">Acronyms are words</a>
-: Treat acronyms as words in names, yielding XmlHttpRequest, getUrl(), etc.
-</li>
-<li><a href="#todo">TODO style</a>
-: "TODO: write this description"
-</li>
-<li><a href="#consistency">Consistency</a>
-: Look at what's around you!
-</li>
-<li><a href="#logging">Logging</a>
-: Be careful with logging. It's expensive.
-</li>
+<h1>Java Library Rules</h1>
+<p>There are conventions for using Android's Java libraries and tools. In some
+cases, the convention has changed in important ways and older code might use a
+deprecated pattern or library. When working with such code, it's okay to
+continue the existing style (see <a href="#consistency">Consistency</a>). When
+creating new components never use deprecated libraries.</p>
+<h1>Java Style Rules</h1>
+<p>Programs are much easier to maintain when all files have a consistent
+style. We follow the standard Java coding style, as defined by Sun in their <a
+href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Code
+Conventions for the Java Programming Language</a>, with a few exceptions and
+additions. This style guide is comprehensive and detailed and is in common
+usage in the Java community.</p>
+<p>In addition, we enforce the following style rules:</p>
+<ol><li><a href="#javadoc">Comments/Javadoc</a>: write it; use standard style</li>
+<li><a href="#shortmethods">Short methods</a>: don't write giant methods</li>
+<li>Fields: should either be at the top of the file, or immediately before the methods that use them</li>
+<li><a href="#localvariables">Local variables</a>: limit the scope</li>
+<li><a href="#import_style">Imports</a>: android; third party alphabetical; java(x)</li>
+<li><a href="#indentation">Indentation</a>: 4 spaces, no tabs.</li>
+<li><a href="#linelen">Line length</a>: 100 columns</li>
+<li><a href="#field_names">Field names</a>: Non-public, non-static fields start with m.</li>
+<li><a href="#braces">Braces</a>: Opening braces don't go on their own line.</li>
+<li><a href="#annotations">Annotations</a>: Use the standard annotations.</li>
+<li><a href="#acronyms">Acronyms are words</a>: Treat acronyms as words in names, yielding XmlHttpRequest, getUrl(), etc.</li>
+<li><a href="#todo">TODO style</a>: "TODO: write this description"</li>
+<li><a href="#consistency">Consistency</a>: Look at what's around you!</li>
+<li><a href="#logging">Logging</a>: Be careful with logging. It's expensive.</li>
</ol>
-<h1><a>Javatests Style Rules</a>
-</h1>
-<ol><li><a href="#testmethodnames">Naming test methods</a>
-: testMethod_specificCase is ok
-</li>
+<h1>Javatests Style Rules</h1>
+<ol>
+<li><a href="#testmethodnames">Naming test methods</a>: testMethod_specificCase is ok</li>
</ol>
-<hr><h2>
-Java Language Rules
-</h2>
-<h2><a>Exceptions: do not ignore</a>
-</h2>
-Sometimes it is tempting to write code that completely ignores an exception like this:
-<pre>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>}<br>}<br><br></pre>
-<p>You must never do this. While you may think that your code will never encounter this error condition or that it is not important to handle it, ignoring exceptions like above creates mines in your code for someone else to trip over some day. You must handle every Exception in your code in some principled way. The specific handling varies depending on the case.
-</p>
-<blockquote>Anytime somebody has an empty catch clause they should have a creepy feeling. There are definitely times when it is actually the correct thing to do, but at least you have to think about it. In Java you can't escape the creepy feeling.<br><div>-<a href="http://www.artima.com/intv/solid4.html">James Gosling</a>
-</div>
-</blockquote>
-<p>Acceptable alternatives (in order of preference) are:
-</p>
-<ul><li>Throw the exception up to the caller of your method.
-<pre>void setServerPort(String value) throws NumberFormatException {<br>serverPort = Integer.parseInt(value);<br>}<br><br></pre>
-</li>
+<h2>Java Language Rules</h2>
+<h2><a name="exceptionsIgnore"></a>Exceptions: do not ignore</h2>
+<p>Sometimes it is tempting to write code that completely ignores an exception
+like this:</p>
+<pre>void setServerPort(String value) {
+ try {
+ serverPort = Integer.parseInt(value);
+ } catch (NumberFormatException e) { }
+}</pre>
+<p>You must never do this. While you may think that your code will never
+encounter this error condition or that it is not important to handle it,
+ignoring exceptions like above creates mines in your code for someone else to
+trip over some day. You must handle every Exception in your code in some
+principled way. The specific handling varies depending on the case.</p>
+<blockquote>Anytime somebody has an empty catch clause they should have a
+creepy feeling. There are definitely times when it is actually the correct
+thing to do, but at least you have to think about it. In Java you can't escape
+the creepy feeling.
+-<a href="http://www.artima.com/intv/solid4.html">James
+Gosling</a></blockquote>
+<p>Acceptable alternatives (in order of preference) are:</p>
+<ul>
+<li>Throw the exception up to the caller of your method.
+<pre>void setServerPort(String value) throws NumberFormatException {
+ serverPort = Integer.parseInt(value);
+}</pre></li>
<li>Throw a new exception that's appropriate to your level of abstraction.
-<pre>void setServerPort(String value) throws ConfigurationException {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>throw new ConfigurationException("Port " + value + " is not valid.");<br>}<br><br></pre>
-</li>
-<li>Handle the error gracefully and substitute an appropriate value in the catch {} block.
-<pre>/** Set port. If value is not a valid number, 80 is substituted. */<br>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>serverPort = 80; // default port for server <br>}<br></pre>
-</li>
-<li>Catch the Exception and throw a new RuntimeException. This is dangerous: only do it if you are positive that if this error occurs, the appropriate thing to do is crash.
-<pre>/** Set port. If value is not a valid number, die. */<br>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>throw new RuntimeException("port " + value " is invalid, ", e);<br>}<br></pre>
-Note that the original exception is passed to the constructor for RuntimeException. This wrapped exception paradigm is very useful but only works in Java 1.4. If your code must compile under Java 1.3, you will need to omit the exception that is the cause.<br><br></li>
-<li>Last resort: if you are confident that actually ignoring the exception is appropriate then you may ignore it, but you must also comment why with a good reason:
-<pre>/** If value is not a valid number, original port number is used. */<br>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>// Method is documented to just ignore invalid user input.<br>// serverPort will just be unchanged.<br>}<br>}<br></pre>
-</li>
+<pre>void setServerPort(String value) throws ConfigurationException {
+ try {
+ serverPort = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ throw new ConfigurationException("Port " + value + " is not valid.");
+ }
+}</pre></li>
+<li>Handle the error gracefully and substitute an appropriate value in the
+catch {} block.
+<pre>/** Set port. If value is not a valid number, 80 is substituted. */
+void setServerPort(String value) {
+ try {
+ serverPort = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ serverPort = 80; // default port for server
+ }
+}</pre></li>
+<li>Catch the Exception and throw a new RuntimeException. This is dangerous:
+only do it if you are positive that if this error occurs, the appropriate
+thing to do is crash.
+<pre>/** Set port. If value is not a valid number, die. */
+void setServerPort(String value) {
+ try {
+ serverPort = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ throw new RuntimeException("port " + value " is invalid, ", e);
+ }
+}</pre>
+Note that the original exception is passed to the constructor for
+RuntimeException. If your code must compile under Java 1.3, you will need to
+omit the exception that is the cause.</li>
+<li>Last resort: if you are confident that actually ignoring the exception is
+appropriate then you may ignore it, but you must also comment why with a good
+reason:
+<pre>/** If value is not a valid number, original port number is used. */
+void setServerPort(String value) {
+ try {
+ serverPort = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ // Method is documented to just ignore invalid user input.
+ // serverPort will just be unchanged.
+ }
+}</pre></li>
</ul>
-<h2><a>Exceptions: do not catch generic Exception</a>
-</h2>
-Sometimes it is tempting to be lazy when catching exceptions and do something like this:
-<pre>try {<br>someComplicatedIOFunction(); // may throw IOException <br>someComplicatedParsingFunction(); // may throw ParsingException <br>someComplicatedSecurityFunction(); // may throw SecurityException <br>// phew, made it all the way <br>} catch (Exception e) { // I'll just catch all exceptions <br>handleError(); // with one generic handler!<br>}<br><br></pre>
-You should not do this. In almost all cases it is inappropriate to catch generic Exception or Throwable, preferably not Throwable, because it includes Error exceptions as well. It is very dangerous. It means that Exceptions you never expected (including RuntimeExceptions like ClassCastException) end up getting caught in application-level error handling. It obscures the failure handling properties of your code. It means if someone adds a new type of Exception in the code you're calling, the compiler won't help you realize you need to handle that error differently. And in most cases you shouldn't be handling different types of exception the same way, anyway.
-<p>There are rare exceptions to this rule: certain test code and top-level code where you want to catch all kinds of errors (to prevent them from showing up in a UI, or to keep a batch job running). In that case you may catch generic Exception (or Throwable) and handle the error appropriately. You should think very carefully before doing this, though, and put in comments explaining why it is safe in this place.
-</p>
-<p>Alternatives to catching generic Exception:
-</p>
-<ul><li>Catch each exception separately as separate catch blocks after a single try. This can be awkward but is still preferable to catching all Exceptions. Beware repeating too much code in the catch blocks.
-</li>
-<li>Refactor your code to have more fine-grained error handling, with multiple try blocks. Split up the IO from the parsing, handle errors separately in each case.
-</li>
-<li>Rethrow the exception. Many times you don't need to catch the exception at this level anyway, just let the method throw it.
-</li>
+<h2><a name="exceptionsAll"></a>Exceptions: do not catch generic Exception</h2>
+<p>Sometimes it is tempting to be lazy when catching exceptions and do
+something like this:</p>
+<pre>try {
+ someComplicatedIOFunction(); // may throw IOException
+ someComplicatedParsingFunction(); // may throw ParsingException
+ someComplicatedSecurityFunction(); // may throw SecurityException
+ // phew, made it all the way
+} catch (Exception e) { // I'll just catch all exceptions
+ handleError(); // with one generic handler!
+}</pre>
+<p>You should not do this. In almost all cases it is inappropriate to catch
+generic Exception or Throwable, preferably not Throwable, because it includes
+Error exceptions as well. It is very dangerous. It means that Exceptions you
+never expected (including RuntimeExceptions like ClassCastException) end up
+getting caught in application-level error handling. It obscures the failure
+handling properties of your code. It means if someone adds a new type of
+Exception in the code you're calling, the compiler won't help you realize you
+need to handle that error differently. And in most cases you shouldn't be
+handling different types of exception the same way, anyway.</p>
+<p>There are rare exceptions to this rule: certain test code and top-level
+code where you want to catch all kinds of errors (to prevent them from showing
+up in a UI, or to keep a batch job running). In that case you may catch
+generic Exception (or Throwable) and handle the error appropriately. You
+should think very carefully before doing this, though, and put in comments
+explaining why it is safe in this place.</p>
+<p>Alternatives to catching generic Exception:</p>
+<ul>
+<li>Catch each exception separately as separate catch blocks after a single
+try. This can be awkward but is still preferable to catching all Exceptions.
+Beware repeating too much code in the catch blocks.</li>
+<li>Refactor your code to have more fine-grained error handling, with multiple
+try blocks. Split up the IO from the parsing, handle errors separately in each
+case.</li>
+<li>Rethrow the exception. Many times you don't need to catch the exception at
+this level anyway, just let the method throw it.</li>
</ul>
-Remember: exceptions are your friend! When the compiler complains you're not catching an exception, don't scowl. Smile: the compiler just made it easier for you to catch runtime problems in your code.
-<h2><a>Finalizers</a>
-</h2>
-<p><b>What it is</b>
-: Finalizers are a way to have a chunk of code executed when an object is garbage collected.
-</p>
-<p><b>Pros</b>
-: can be handy for doing cleanup, particularly of external resources.
-</p>
-<p><b>Cons</b>
-: there are no guarantees as to when a finalizer will be called, or even that it will be called at all.
-</p>
-<p><b>Decision</b>
-: we don't use finalizers. In most cases, you can do what you need from a finalizer with good exception handling. If you absolutely need it, define a close() method (or the like) and document exactly when that method needs to be called. See InputStream for an example. In this case it is appropriate but not required to print a short log message from the finalizer, as long as it is not expected to flood the logs.
-</p>
-<p>The one exception is it is OK to write a finalizer if all it does is make calls to X.assertTrue().
-</p>
-<h2><a>Imports</a>
-</h2>
-<h3>
-Wildcards in imports
-</h3>
-<p><b>What it is</b>
-: When you want to use class Bar from package foo,there are two possible ways to import it:
-</p>
-<ol><li>import foo.*;
-</li>
-<li>import foo.Bar;
-</li>
+<p>Remember: exceptions are your friend! When the compiler complains you're
+not catching an exception, don't scowl. Smile: the compiler just made it
+easier for you to catch runtime problems in your code.</p>
+<h2><a name="finalizers"></a>Finalizers</h2>
+<p><b>What it is</b>: Finalizers are a way to have a chunk of code executed
+when an object is garbage collected.</p>
+<p><b>Pros</b>: can be handy for doing cleanup, particularly of external
+resources.</p>
+<p><b>Cons</b>: there are no guarantees as to when a finalizer will be called,
+or even that it will be called at all.</p>
+<p><b>Decision</b>: we don't use finalizers. In most cases, you can do what
+you need from a finalizer with good exception handling. If you absolutely need
+it, define a close() method (or the like) and document exactly when that
+method needs to be called. See InputStream for an example. In this case it is
+appropriate but not required to print a short log message from the finalizer,
+as long as it is not expected to flood the logs.</p>
+<h2><a name="imports"></a>Imports</h2>
+<h3>Wildcards in imports</h3>
+<p><b>What it is</b>: When you want to use class Bar from package foo,there
+are two possible ways to import it:</p>
+<ol>
+<li><code>import foo.*;</code></li>
+<li><code>import foo.Bar;</code></li>
</ol>
-<p><b>Pros of #1</b>
-: Potentially reduces the number of import statements.
+<p><b>Pros of #1</b>: Potentially reduces the number of import statements.
</p>
-<p><b>Pros of #2</b>
-: Makes it obvious what classes are actually used. Makes code more readable for maintainers.
-</p>
-<p><b>Decision</b>
-:Use style #2 for importing all Android code. An explicit exception is made for java standard libraries (java.util.*, java.io.*, etc.) and unit test code (junit.framework.*).
-</p>
-<h2><a>Comments/Javadoc</a>
-</h2>
-<p>Every file should have a copyright statement at the top. Then a package statement and import statements should follow, each block separated by a blank line. And then there is the class or interface declaration. In the Javadoc comments, describe what the class or interface does.
-</p>
-<pre>/*<br>* Copyright (C) 2007 The Android Open Source Project <br>*<br>* Licensed under the Apache License, Version 2.0 (the "License");<br>* you may not use this file except in compliance with the License.<br>* You may obtain a copy of the License at <br>*<br>* http://www.apache.org/licenses/LICENSE-2.0<br>*<br>* Unless required by applicable law or agreed to in writing, software <br>* distributed under the License is distributed on an "AS IS" BASIS,<br>* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br>* See the License for the specific language governing permissions and <br>* limitations under the License.<br>*/<br><br>package com.android.internal.foo;<br><br>import android.os.Blah;<br>import android.view.Yada;<br><br>import java.sql.ResultSet;<br>import java.sql.SQLException;<br><br>/**<br>* Does X and Y and provides an abstraction for Z.<br>*/<br>public class Foo {<br>...<br>}<br></pre>
-<p>Every class and nontrivial public method you write <b>must</b>
-contain a Javadoc comment with at least one sentence describing what the class or method does. This sentence should start with a 3rd person descriptive verb. Examples:
-</p>
-<pre>/** Returns the correctly rounded positive square root of a double value. */<br>static double sqrt(double a) {<br>}<br><br>/**<br>* Constructs a new String by converting the specified array of <br>* bytes using the platform's default character encoding.<br>*/<br>public String(byte[] bytes) {<br>}<br></pre>
-<p>You do not need to write Javadoc for trivial get and set methods such as setFoo() if all your Javadoc would say is "sets Foo". If the method does something more complex (such as enforcing a constraint or having an important side effect), then you must document it. And if it's not obvious what the property "Foo" means, you should document it.
-</p>
-<p>Every method you write, whether public or otherwise, would benefit from Javadoc. Public methods are part of an API and therefore require Javadoc.
-</p>
-Android does not currently enforce a specific style for writing Javadoc comments, but you <b>should</b>
-follow the <a href="http://java.sun.com/j2se/javadoc/writingdoccomments/">Sun Javadoc conventions</a>
-.
-<h2><a>Short methods</a>
-</h2>
-To the extent that it is feasible, methods should be kept small and focused. It is, however, recognized that long methods are sometimes appropriate, so no hard limit is placed on method length. If a method exceeds 40 lines or so, think about whether it can be broken up without harming the structure of the program.
-<h2><a>Local variables</a>
-</h2>
-The scope of local variables should be kept to a minimum (<i>Effective Java</i>
-Item 29). By doing so, you increase the readability and maintainability of your code and reduce the likelihood of error. Each variable should be declared in the innermost block that encloses all uses of the variable.
-<p>Local variables should be declared at the point they are first used. Nearly every local variable declaration should contain an initializer. If you don't yet have enough information to initialize a variable sensibly, you should postpone the declaration until you do.
-</p>
-<p>One exception to this rule concerns try-catch statements. If a variable is initialized with the return value of a method that throws a checked exception, it must be initialized inside a try block. If the value must be used outside of the try block, then it must be declared before the try block, where it cannot yet be sensibly initialized:
-</p>
-<pre>// Instantiate class cl, which represents some sort of Set <br>Set s = null;<br>try {<br>s = (Set) cl.newInstance();<br>} catch(IllegalAccessException e) {<br>throw new IllegalArgumentException(cl + " not accessible");<br>} catch(InstantiationException e) {<br>throw new IllegalArgumentException(cl + " not instantiable");<br>}<br><br>// Exercise the set <br>s.addAll(Arrays.asList(args));<br></pre>
-<p>But even this case can be avoided by encapsulating the try-catch block in a method:
-</p>
-<pre>Set createSet(Class cl) {<br>// Instantiate class cl, which represents some sort of Set <br>try {<br>return (Set) cl.newInstance();<br>} catch(IllegalAccessException e) {<br>throw new IllegalArgumentException(cl + " not accessible");<br>} catch(InstantiationException e) {<br>throw new IllegalArgumentException(cl + " not instantiable");<br>}<br>}<br>...<br>// Exercise the set <br>Set s = createSet(cl);<br>s.addAll(Arrays.asList(args));<br></pre>
-Loop variables should be declared in the for statement itself unless there is a compelling reason to do otherwise:
-<pre>for (int i = 0; i n; i++) {<br>doSomething(i);<br>}<br><br>for (Iterator i = c.iterator(); i.hasNext(); ) {<br>doSomethingElse(i.next());<br>}<br><br><br></pre>
-<h2><a>Imports</a>
-</h2>
-The ordering of import statements is:Android importsImports from third parties (com, junit, net, org)<br>java and javax
-<p>To exactly match the IDE settings, the imports should be:
-</p>
-Alphabetical within each grouping.<br>Capital letters are considered to come before lower case letter (e.g. Z before a).There should be a blank line between each major grouping (android, com, junit, net, org, java, javax).
-<h4>
-Why?
-</h4>
-<p>Originally there was no style requirement on the ordering. This meant that the IDE's were either always changing the ordering, or IDE developers had to disable the automatic import management features and maintain the imports by hand. This was deemed bad. When java-style was asked, the preferred styles were all over the map. It pretty much came down to our needing to "pick an ordering and be consistent." So we chose a style, updated the javaguide and made the IDE's obey it. We expect that as IDE users work on the code, the imports in all of the packages will end up matching this pattern without any extra engineering effort.
-</p>
-<p>The style chosen such that:
-</p>
-The imports people want to look at first tend to be at the top (android)The imports people want to look at least tend to be at the bottom (java)Humans can easily follow the styleThe IDE's can follow the style
-<h3>
-What about static imports?
-</h3>
-The use and location of static imports have been mildly controversial issues. Some people would prefer static imports to be interspersed with the remaining imports, some would prefer them reside above or below all other imports. Additinally, we have not yet come up with a way to make all IDEs use the same ordering.
-<p>Since most people consider this a low priority issue, just use your judgement and please be consistent.
-</p>
+<p><b>Pros of #2</b>: Makes it obvious what classes are actually used. Makes
+code more readable for maintainers. </p>
+<p><b>Decision</b>: Use style #2 for importing all Android code. An explicit
+exception is made for java standard libraries (java.util.*, java.io.*, etc.)
+and unit test code (junit.framework.*).</p>
+<h2><a name="javadoc"></a>Comments/Javadoc</h2>
+<p>Every file should have a copyright statement at the top. Then a package
+statement and import statements should follow, each block separated by a blank
+line. And then there is the class or interface declaration. In the Javadoc
+comments, describe what the class or interface does.</p>
+<pre>/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * 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.
+ */
-<h2><a>Indentation</a>
-</h2>
-<p>We use 4 space indents for blocks. We never use tabs. When in doubt, be consistent with code around you.
-</p>
-<p>We use 8 space indents for line wraps, including function calls and assignments. For example, this is correct:
-</p>
-<pre>Instrument i <br>= someLongExpression(that, wouldNotFit, on, one, line);</pre>
-and this is not correct:
-<pre>Instrument i <br>= someLongExpression(that, wouldNotFit, on, one, line);</pre>
-<h2><a>Field Names</a>
-</h2>
-<ul><li>Non-public, non-static field names start with m.
-</li>
-<li>Static field names start with s.
-</li>
-<li>Other fields start with a lower case letter.
-</li>
-<li>Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.
-</li>
+package com.android.internal.foo;
+
+import android.os.Blah;
+import android.view.Yada;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Does X and Y and provides an abstraction for Z.
+ */
+public class Foo {
+ ...
+}</pre>
+<p>Every class and nontrivial public method you write <b>must</b> contain a
+Javadoc comment with at least one sentence describing what the class or method
+does. This sentence should start with a 3rd person descriptive verb.
+Examples:</p>
+<pre>/** Returns the correctly rounded positive square root of a double value. */
+static double sqrt(double a) {
+}
+
+/**
+ * Constructs a new String by converting the specified array of
+ * bytes using the platform's default character encoding.
+ */
+public String(byte[] bytes) {
+}</pre>
+<p>You do not need to write Javadoc for trivial get and set methods such as
+setFoo() if all your Javadoc would say is "sets Foo". If the method does
+something more complex (such as enforcing a constraint or having an important
+side effect), then you must document it. And if it's not obvious what the
+property "Foo" means, you should document it.</p>
+<p>Every method you write, whether public or otherwise, would benefit from
+Javadoc. Public methods are part of an API and therefore require Javadoc.</p>
+<p>Android does not currently enforce a specific style for writing Javadoc
+comments, but you <b>should</b> follow the <a
+href="http://java.sun.com/j2se/javadoc/writingdoccomments/">Sun Javadoc
+conventions</a>.</p>
+<h2><a name="shortmethods"></a>Short methods</h2>
+<p>To the extent that it is feasible, methods should be kept small and
+focused. It is, however, recognized that long methods are sometimes
+appropriate, so no hard limit is placed on method length. If a method exceeds
+40 lines or so, think about whether it can be broken up without harming the
+structure of the program.</p>
+<h2><a name="localvariables"></a>Local variables</h2>
+<p>The scope of local variables should be kept to a minimum (<i>Effective
+Java</i> Item 29). By doing so, you increase the readability and
+maintainability of your code and reduce the likelihood of error. Each variable
+should be declared in the innermost block that encloses all uses of the
+variable.</p>
+<p>Local variables should be declared at the point they are first used. Nearly
+every local variable declaration should contain an initializer. If you don't
+yet have enough information to initialize a variable sensibly, you should
+postpone the declaration until you do.</p>
+<p>One exception to this rule concerns try-catch statements. If a variable is
+initialized with the return value of a method that throws a checked exception,
+it must be initialized inside a try block. If the value must be used outside
+of the try block, then it must be declared before the try block, where it
+cannot yet be sensibly initialized:</p>
+<pre>// Instantiate class cl, which represents some sort of Set
+Set s = null;
+try {
+ s = (Set) cl.newInstance();
+} catch(IllegalAccessException e) {
+ throw new IllegalArgumentException(cl + " not accessible");
+} catch(InstantiationException e) {
+ throw new IllegalArgumentException(cl + " not instantiable");
+}
+
+// Exercise the set
+s.addAll(Arrays.asList(args));</pre>
+<p>But even this case can be avoided by encapsulating the try-catch block in a method:</p>
+<pre>Set createSet(Class cl) {
+ // Instantiate class cl, which represents some sort of Set
+ try {
+ return (Set) cl.newInstance();
+ } catch(IllegalAccessException e) {
+ throw new IllegalArgumentException(cl + " not accessible");
+ } catch(InstantiationException e) {
+ throw new IllegalArgumentException(cl + " not instantiable");
+ }
+}
+
+...
+
+// Exercise the set
+Set s = createSet(cl);
+s.addAll(Arrays.asList(args));</pre>
+<p>Loop variables should be declared in the for statement itself unless there
+is a compelling reason to do otherwise:</p>
+<pre>for (int i = 0; i n; i++) {
+ doSomething(i);
+}
+
+for (Iterator i = c.iterator(); i.hasNext(); ) {
+ doSomethingElse(i.next());
+}</pre>
+<h2><a name="import_style"></a>Imports</h2>
+<p>The ordering of import statements is:</p>
+<ol>
+<li>Android imports</li>
+<li>Imports from third parties (com, junit, net, org)</li>
+<li>java and javax</li>
+</ol>
+<p>To exactly match the IDE settings, the imports should be:</p>
+<ul>
+<li>Alphabetical within each grouping.</li>
+<li>Capital letters are considered to come before lower case letter (e.g. Z before a).</li>
+<li>There should be a blank line between each major grouping (android, com, junit, net, org, java, javax).</li>
</ul>
-<p>For example:
-</p>
-<pre>public class MyClass {<br>public static final int SOME_CONSTANT = 42;<br>public int publicField;<br>private static MyClass sSingleton;<br>int mPackagePrivate;<br>private int mPrivate;<br>protected int mProtected;<br>}</pre>
-<h2><a>Braces</a>
-</h2>
-<p>Braces do not go on their own line; they go on the same line as the code before them. So:
-</p>
-<pre>class MyClass {<br>int func() {<br>if (something) {<br>// ...<br>} else if (somethingElse) {<br>// ...<br>} else {<br>// ...<br>}<br>}<br>}<br></pre>
-<p>We require braces around the statements for a conditional. Except, if the entire conditional (the condition and the body) fit on one line, you may (but are not obligated to) put it all on one line. That is, this is legal:
-</p>
-<pre>if (condition) {<br>body; // ok <br>}<br>if (condition) body; // ok</pre>
-<p>but this is still illegal:
-</p>
-<pre>if (condition)<br>body; // bad <br></pre>
-<h2><a>Line length</a>
-</h2>
-<p>Each line of text in your code should be at most 100 characters long.
-</p>
-<p>There has been lots of discussion about this rule and the decision remains that 100 characters is the maximum.
-</p>
-<p>Exception: if a comment line contains an example command or a literal URL longer than 100 characters, that line may be longer than 100 characters for ease of cut and paste.
-</p>
-<p>Exception: import lines can go over the limit because humans rarely see them. This also simplifies tool writing.
-</p>
-<h2>
-Java 1.5 Annotations
-</h2>
-<p>Annotations should precede other modifiers for the same language element. Simple marker annotations (e.g. @Override) can be listed on the same line with the language element. If there are multiple annotations, or parameterized annotations, they should each be listed one-per-line in alphabetical order.
-</p>
-<p>Android -standard practices for the three predefined annotations in Java 1.5's are:
-</p>
-@DeprecatedThe @Deprecated annotation must be used whenever the use of the annotated element is discouraged. If you use the @Deprecated annotation, you must also have a @deprecated Javadoc tag and it should name an alternate implementation. In addition, remember that a @Deprecated method is <b>still</b>
-supposed to work.
-<p>If you see old code that has a @deprecated Javadoc tag, please add the @Deprecated annotation.
-</p>
-@OverrideThe @Override annotation must be used whenever a method overrides the declaration or implementation from a super-class.
-<p>For example, if you use the {@inheritdocs} Javadoc tag, and derive from a class (not an interface), you must also annotate that the method @Overrides the parent class's method.
-</p>
-@SuppressWarningsThe @SuppressWarnings annotation should only be used under circumstances where it is impossible to eliminate a warning. If a warning passes this "impossible to eliminate" test, the@SuppressWarnings annotation <b>must</b>
-be used, so as to ensure that all warnings reflect actual problems in the code.
-<p>When a @SuppressWarnings annotation is necessary, it must be prefixed with a TODO comment that explains the "impossible to eliminate" condition. This will normally identify an offending class that has an awkward interface. For example:
-</p>
-<pre>// TODO: The third-party class com.third.useful.Utility.rotate() needs generics <br>@SuppressWarnings({"generic-cast"})<br>ListStringblix = Utility.rotate(blax);<br></pre>
-When a @SuppressWarnings annotation is required, the code should be refactored to isolate the software elements where the annotation applies.
-<h2><a>Acronyms in names</a>
-</h2>
-<p>Treat acronyms and abbreviations as words. The names are much more readable:
-</p>
+<h4>Why?</h4>
+<p>Originally there was no style requirement on the ordering. This meant that
+the IDE's were either always changing the ordering, or IDE developers had to
+disable the automatic import management features and maintain the imports by
+hand. This was deemed bad. When java-style was asked, the preferred styles
+were all over the map. It pretty much came down to our needing to "pick an
+ordering and be consistent." So we chose a style, updated the style guide, and
+made the IDEs obey it. We expect that as IDE users work on the code, the
+imports in all of the packages will end up matching this pattern without any
+extra engineering effort.</p>
+<p>The style chosen such that:</p>
+<ul>
+<li>The imports people want to look at first tend to be at the top (android)</li>
+<li>The imports people want to look at least tend to be at the bottom (java)</li>
+<li>Humans can easily follow the style</li>
+<li>The IDE's can follow the style</li>
+</ul>
+<h3>What about static imports?</h3>
+<p>The use and location of static imports have been mildly controversial
+issues. Some people would prefer static imports to be interspersed with the
+remaining imports, some would prefer them reside above or below all other
+imports. Additinally, we have not yet come up with a way to make all IDEs use
+the same ordering.</p>
+<p>Since most people consider this a low priority issue, just use your
+judgement and please be consistent.</p>
-<table><tbody><tr><td>Good
-</td>
-<td>Bad
-</td>
-</tr>
-<tr><td>XmlHttpRequest</td>
-<td>XMLHTTPRequest
-</td>
-</tr>
-<tr><td>getCustomerId</td>
-<td>getCustomerID
-</td>
-</tr>
-</tbody>
-</table>
-
-<p>This style rule also applies when an acronym or abbreviation is the entire name:
-</p>
-
-<table><tbody><tr><td>Good
-</td>
-<td>Bad
-</td>
-</tr>
-<tr><td>class Html</td>
-<td>class HTML
-</td>
-</tr>
-<tr><td>String url;</td>
-<td>String URL;
-</td>
-</tr>
-<tr><td>long id;</td>
-<td>long ID;
-</td>
-</tr>
-</tbody>
-</table>
-
-<p>Both the JDK and the Android code bases are very inconsistent with regards to acronyms, therefore, it is virtually impossible to be consistent with the code around you. Bite the bullet, and treat acronyms as words.
-</p>
+<h2><a name="indentation"></a>Indentation</h2>
+<p>We use 4 space indents for blocks. We never use tabs. When in doubt, be
+consistent with code around you.</p>
+<p>We use 8 space indents for line wraps, including function calls and
+assignments. For example, this is correct:</p>
+<pre>Instrument i =
+ someLongExpression(that, wouldNotFit, on, one, line);</pre>
+<p>and this is not correct:</p>
+<pre>Instrument i =
+ someLongExpression(that, wouldNotFit, on, one, line);</pre>
+<h2><a name="field_names"></a>Field Names</h2>
+<ul>
+<li>Non-public, non-static field names start with m.</li>
+<li>Static field names start with s.</li>
+<li>Other fields start with a lower case letter.</li>
+<li>Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.</li>
+</ul>
+<p>For example:</p>
+<pre>public class MyClass {
+ public static final int SOME_CONSTANT = 42;
+ public int publicField;
+ private static MyClass sSingleton;
+ int mPackagePrivate;
+ private int mPrivate;
+ protected int mProtected;
+}</pre>
+<h2><a name="braces"></a>Braces</h2>
+<p>Braces do not go on their own line; they go on the same line as the code
+before them. So:</p>
+<pre>class MyClass {
+ int func() {
+ if (something) {
+ // ...
+ } else if (somethingElse) {
+ // ...
+ } else {
+ // ...
+ }
+ }
+}</pre>
+<p>We require braces around the statements for a conditional. Except, if the
+entire conditional (the condition and the body) fit on one line, you may (but
+are not obligated to) put it all on one line. That is, this is legal:</p>
+<pre>if (condition) {
+ body(); // ok
+}
+if (condition) body(); // ok</pre>
+<p>but this is still illegal:</p>
+<pre>if (condition)
+ body(); // bad</pre>
+<h2><a name="linelen"></a>Line length</h2>
+<p>Each line of text in your code should be at most 100 characters long.</p>
+<p>There has been lots of discussion about this rule and the decision remains
+that 100 characters is the maximum.</p>
+<p>Exception: if a comment line contains an example command or a literal URL
+longer than 100 characters, that line may be longer than 100 characters for
+ease of cut and paste.</p>
+<p>Exception: import lines can go over the limit because humans rarely see
+them. This also simplifies tool writing.</p>
+<h2><a name="annotations"></a>Java 1.5 Annotations</h2>
+<p>Annotations should precede other modifiers for the same language element.
+Simple marker annotations (e.g. @Override) can be listed on the same line with
+the language element. If there are multiple annotations, or parameterized
+annotations, they should each be listed one-per-line in alphabetical
+order.</p>
+<p>Android -standard practices for the three predefined annotations in Java
+1.5's are:</p>
+<h3>@Deprecated</h3>
+<p>The @Deprecated annotation must be used whenever the use of the annotated
+element is discouraged. If you use the @Deprecated annotation, you must also
+have a @deprecated Javadoc tag and it should name an alternate implementation.
+In addition, remember that a @Deprecated method is <b>still</b> supposed to
+work.</p>
+<p>If you see old code that has a @deprecated Javadoc tag, please add the @Deprecated annotation.</p>
+<h3>@Override</h3>
+<p>The @Override annotation must be used whenever a method overrides the
+declaration or implementation from a super-class.</p>
+<p>For example, if you use the @inheritdocs Javadoc tag, and derive from a
+class (not an interface), you must also annotate that the method @Overrides
+the parent class's method.</p>
+<h3>@SuppressWarnings</h3>
+<p>The @SuppressWarnings annotation should only be used under circumstances
+where it is impossible to eliminate a warning. If a warning passes this
+"impossible to eliminate" test, the @SuppressWarnings annotation <b>must</b> be
+used, so as to ensure that all warnings reflect actual problems in the
+code.</p>
+<p>When a @SuppressWarnings annotation is necessary, it must be prefixed with
+a TODO comment that explains the "impossible to eliminate" condition. This
+will normally identify an offending class that has an awkward interface. For
+example:</p>
+<pre>// TODO: The third-party class com.third.useful.Utility.rotate() needs generics
+@SuppressWarnings("generic-cast")
+List<String> blix = Utility.rotate(blax);</pre>
+<p>When a @SuppressWarnings annotation is required, the code should be
+refactored to isolate the software elements where the annotation applies.</p>
+<h2><a name="acronyms"></a>Acronyms in names</h2>
+<p>Treat acronyms and abbreviations as words. The names are much more readable:</p>
+<table><tbody>
+<tr><td>Good</td> <td>Bad</td></tr>
+<tr><td>XmlHttpRequest</td> <td>XMLHTTPRequest</td></tr>
+<tr><td>getCustomerId</td> <td>getCustomerID</td></tr>
+</tbody></table>
+<p>This style rule also applies when an acronym or abbreviation is the entire
+name:</p>
+<table><tbody>
+<tr><td>Good</td> <td>Bad</td></tr>
+<tr><td>class Html</td> <td>class HTML</td></tr>
+<tr><td>String url;</td> <td>String URL;</td></tr>
+<tr><td>long id;</td> <td>long ID;</td></tr>
+</tbody></table>
+<p>Both the JDK and the Android code bases are very inconsistent with regards
+to acronyms, therefore, it is virtually impossible to be consistent with the
+code around you. Bite the bullet, and treat acronyms as words.</p>
<p>For further justifications of this style rule, see <i>Effective Java</i>
-Item 38 and <i>Java Puzzlers</i>
-Number 68.
-</p>
-<h2><a>TODO style</a>
-</h2>
-<p>Use TODO comments for code that is temporary, a short-term solution, or good-enough but not perfect.
-</p>
-<p>TODOs should include the string TODO in all caps, followed by a colon:
-</p>
-<pre>// TODO: Remove this code after the UrlTable2 has been checked in.<br><br>// TODO: Change this to use a flag instead of a constant.</pre>
-<p>If your TODO is of the form "At a future date do something" make sure that you either include a very specific date ("Fix by November 2005") or a very specific event ("Remove this code after all production mixers understand protocol V7.").
-</p>
-<h2>
-Consistency
-</h2>
-<p>Our parting thought: BE CONSISTENT. If you're editing code, take a few minutes to look at the code around you and determine its style. If they use spaces around their if clauses, you should too. If their comments have little boxes of stars around them, make your comments have little boxes of stars around them too.
-</p>
-<p>The point of having style guidelines is to have a common vocabulary of coding, so people can concentrate on what you're saying, rather than on how you're saying it. We present global style rules here so people know the vocabulary. But local style is also important. If code you add to a a file looks drastically different from the existing code around it, it throws readers out of their rhythm when they go to read it. Try to avoid this.
-</p>
-<h2><a>Logging</a>
-</h2>
-<p>While logging is necessary it has a significantly negative impact on performance and quickly loses its usefulness if it's not kept reasonably terse. The logging facilities provides five different levels of logging. Below are the different levels and when and how they should be used.
-</p>
+Item 38 and <i>Java Puzzlers</i> Number 68.</p>
-<ul><li><b>ERROR:</b>
-This level of logging should be used when something fatal has happened, i.e. something that will have user-visible consequences and won't be recoverable without explicitly deleting some data, uninstalling applications, wiping the data partitions or reflashing the entire phone (or worse). This level is always logged. Issues that justify some logging at the ERROR level are typically good candidates to be reported to a statistics-gathering server.
-</li>
+<h2><a name="todo"></a>TODO style</h2>
+<p>Use TODO comments for code that is temporary, a short-term solution, or
+good-enough but not perfect.</p>
+<p>TODOs should include the string TODO in all caps, followed by a colon:</p>
+<pre>// TODO: Remove this code after the UrlTable2 has been checked in.
+
+// TODO: Change this to use a flag instead of a constant.</pre>
+<p>If your TODO is of the form "At a future date do something" make sure that
+you either include a very specific date ("Fix by November 2005") or a very
+specific event ("Remove this code after all production mixers understand
+protocol V7.").</p>
+
+<h2><a name="consistency"></a>Consistency</h2>
+<p>Our parting thought: BE CONSISTENT. If you're editing code, take a few
+minutes to look at the code around you and determine its style. If they use
+spaces around their if clauses, you should too. If their comments have little
+boxes of stars around them, make your comments have little boxes of stars
+around them too.</p>
+<p>The point of having style guidelines is to have a common vocabulary of
+coding, so people can concentrate on what you're saying, rather than on how
+you're saying it. We present global style rules here so people know the
+vocabulary. But local style is also important. If code you add to a a file
+looks drastically different from the existing code around it, it throws
+readers out of their rhythm when they go to read it. Try to avoid this.</p>
+
+<h2><a name="logging"></a>Logging</h2>
+<p>While logging is necessary it has a significantly negative impact on
+performance and quickly loses its usefulness if it's not kept reasonably
+terse. The logging facilities provides five different levels of logging. Below
+are the different levels and when and how they should be used.</p>
+
+<ul>
+<li><b>ERROR:</b>
+This level of logging should be used when something fatal has happened,
+i.e. something that will have user-visible consequences and won't be
+recoverable without explicitly deleting some data, uninstalling applications,
+wiping the data partitions or reflashing the entire phone (or worse). This
+level is always logged. Issues that justify some logging at the ERROR level
+are typically good candidates to be reported to a statistics-gathering
+server.</li>
<li><b>WARNING:</b>
-This level of logging should used when something serious and unexpected happened, i.e. something that will have user-visible consequences but is likely to be recoverable without data loss by performing some explicit action, ranging from waiting or restarting an app all the way to re-downloading a new version of an application or rebooting the device. This level is always logged. Issues that justify some logging at the WARNING level might also be considered for reporting to a statistics-gathering server.
-</li>
+This level of logging should used when something serious and unexpected
+happened, i.e. something that will have user-visible consequences but is
+likely to be recoverable without data loss by performing some explicit action,
+ranging from waiting or restarting an app all the way to re-downloading a new
+version of an application or rebooting the device. This level is always
+logged. Issues that justify some logging at the WARNING level might also be
+considered for reporting to a statistics-gathering server.</li>
<li><b>INFORMATIVE:</b>
-This level of logging should used be to note that something interesting to most people happened, i.e. when a situation is detected that is likely to have widespread impact, though isn't necessarily an error. Such a condition should only be logged by a module that reasonably believes that it is the most authoritative in that domain (to avoid duplicate logging by non-authoritative components). This level is always logged.
-</li>
+This level of logging should used be to note that something interesting to
+most people happened, i.e. when a situation is detected that is likely to have
+widespread impact, though isn't necessarily an error. Such a condition should
+only be logged by a module that reasonably believes that it is the most
+authoritative in that domain (to avoid duplicate logging by non-authoritative
+components). This level is always logged.</li>
<li><b>DEBUG:</b>
-This level of logging should be used to further note what is happening on the device that could be relevant to investigate and debug unexpected behaviors. You should log only what is needed to gather enough information about what is going on about your component. If your debug logs are dominating the log then you probably should be using verbose logging. This level will be logged, even on release builds, and is required to be surrounded by an if (LOCAL_LOG) or if (LOCAL_LOGD) block, where LOCAL_LOG[D] is defined in your class or subcomponent, so that there can exist a possibility to disable all such logging. There must therefore be no active logic in an if (LOCAL_LOG) block. All the string building for the log also needs to be placed inside the if (LOCAL_LOG) block. The logging call should not be re-factored out into a method call if it is going to cause the string building to take place outside of the if (LOCAL_LOG) block. There is some code that still says if (localLOGV). This is considered acceptable as well, although the name is nonstandard.
-</li>
+This level of logging should be used to further note what is happening on the
+device that could be relevant to investigate and debug unexpected behaviors.
+You should log only what is needed to gather enough information about what is
+going on about your component. If your debug logs are dominating the log then
+you probably should be using verbose logging. This level will be logged, even
+on release builds, and is required to be surrounded by an if (LOCAL_LOG) or if
+(LOCAL_LOGD) block, where LOCAL_LOG[D] is defined in your class or
+subcomponent, so that there can exist a possibility to disable all such
+logging. There must therefore be no active logic in an if (LOCAL_LOG) block.
+All the string building for the log also needs to be placed inside the if
+(LOCAL_LOG) block. The logging call should not be re-factored out into a
+method call if it is going to cause the string building to take place outside
+of the if (LOCAL_LOG) block. There is some code that still says if
+(localLOGV). This is considered acceptable as well, although the name is
+nonstandard.</li>
<li><b>VERBOSE:</b>
-This level of logging should be used for everything else. This level will only be logged on debug builds and should be surrounded by if (LOCAL_LOGV) block (or equivalent) so that it can be compiled out by default. Any string building will be stripped out of release builds and needs to appear inside the if (LOCAL_LOGV) block.
-</li>
+This level of logging should be used for everything else. This level will only
+be logged on debug builds and should be surrounded by if (LOCAL_LOGV) block
+(or equivalent) so that it can be compiled out by default. Any string building
+will be stripped out of release builds and needs to appear inside the if
+(LOCAL_LOGV) block.</li>
</ul>
-<p><i>Note:</i>
-Within a given module, other than at the VERBOSE level, an error should only be reported once if possible: within a single chain of function calls within a module, only the innermost function should return the error, and callers in the same module should only add some logging if that significantly helps to isolate the issue.
-</p>
-<p><i>Note:</i>
-In a chain of modules, other than at the VERBOSE level, when a lower-level module detects invalid data coming from a higher-level module, the lower-level module should only log this situation to the DEBUG log, and only if logging provides information that is not otherwise available to the caller. Specifically, there is no need to log situations where an exception is thrown (the exception should contain all the relevant information), or where the only information being logged is contained in an error code. This is especially important in the interaction between the framework and applications, and conditions caused by third-party applications that are properly handled by the framework should not trigger logging higher than the DEBUG level. The only situations that should trigger logging at the INFORMATIVE level or higher is when a module or application detects an error at its own level or coming from a lower level.
-</p>
-<p><i>Note:</i>
-When a condition that would normally justify some logging is likely to occur many times, it can be a good idea to implement some rate-limiting mechanism to prevent overflowing the logs with many duplicate copies of the same (or very similar) information.
-</p>
-<p><i>Note:</i>
-Losses of network connectivity are considered common and fully expected and should not be logged gratuitously. A loss of network connectivity that has consequences within an app should be logged at the DEBUG or VERBOSE level (depending on whether the consequences are serious enough and unexpected enough to be logged in a release build).
-</p>
-<p><i>Note:</i>
-A full filesystem on a filesystem that is acceessible to or on behalf of third-party applications should not be logged at a level higher than INFORMATIVE.
-</p>
-<p><i>Note:</i>
-Invalid data coming from any untrusted source (including any file on shared storage, or data coming through just about any network connections) is considered expected and should not trigger any logging at a level higher then DEBUG when it's detected to be invalid (and even then logging should be as limited as possible).
-</p>
-<p><i>Note:</i>
-Keep in mind that the '+' operator, when used on Strings, implicitly creates a StringBuilder with the default buffer size (16 characters) and potentially quite a few other temporary String objects, i.e. that explicitly creating StringBuilders isn't more expensive than relying on the default '+' operator (and can be a lot more efficient in fact). Also keep in mind that code that calls Log.v() is compiled and executed on release builds, including building the strings, even if the logs aren't being read.
-</p>
-<p><i>Note:</i>
-Any logging that is meant to be read by other people and to be available in release builds should be terse without being cryptic, and should be reasonably understandable. This includes all logging up to the DEBUG level.
-</p>
-<p><i>Note:</i>
-When possible, logging should be kept on a single line if it makes sense. Line lengths up to 80 or 100 characters are perfectly acceptable, while lengths longer than about 130 or 160 characters (including the length of the tag) should be avoided if possible.
-</p>
-<p><i>Note:</i>
-Logging that reports successes should never be used at levels higher than VERBOSE.
-</p>
-<p><i>Note:</i>
-Temporary logging that is used to diagnose an issue that's hard to reproduce should be kept at the DEBUG or VERBOSE level, and should be enclosed by if blocks that allow to disable it entirely at compile-time.
-</p>
-<p><i>Note:</i>
-Be careful about security leaks through the log. Private information should be avoided. Information about protected content must definitely be avoided. This is especially important when writing framework code as it's not easy to know in advance what will and will not be private information or protected content.
-</p>
-<p><i>Note:</i>
-System.out.println() (or printf() for native code) should never be used. System.out and System.err get redirected to /dev/null, so your print statements will have no visible effects. However, all the string building that happens for these calls still gets executed.
-</p>
-<p><i>Note:</i>
-<b>The golden rule of logging is that your logs may not unnecessarily push other logs out of the buffer, just as others may not push out yours.</b>
-</p>
-<h2>
-Javatests Style Rules
-</h2>
+<p><i>Note:</i> Within a given module, other than at the VERBOSE level, an
+error should only be reported once if possible: within a single chain of
+function calls within a module, only the innermost function should return the
+error, and callers in the same module should only add some logging if that
+significantly helps to isolate the issue.</p>
+<p><i>Note:</i> In a chain of modules, other than at the VERBOSE level, when a
+lower-level module detects invalid data coming from a higher-level module, the
+lower-level module should only log this situation to the DEBUG log, and only
+if logging provides information that is not otherwise available to the caller.
+Specifically, there is no need to log situations where an exception is thrown
+(the exception should contain all the relevant information), or where the only
+information being logged is contained in an error code. This is especially
+important in the interaction between the framework and applications, and
+conditions caused by third-party applications that are properly handled by the
+framework should not trigger logging higher than the DEBUG level. The only
+situations that should trigger logging at the INFORMATIVE level or higher is
+when a module or application detects an error at its own level or coming from
+a lower level.</p>
+<p><i>Note:</i> When a condition that would normally justify some logging is
+likely to occur many times, it can be a good idea to implement some
+rate-limiting mechanism to prevent overflowing the logs with many duplicate
+copies of the same (or very similar) information.</p>
+<p><i>Note:</i> Losses of network connectivity are considered common and fully
+expected and should not be logged gratuitously. A loss of network connectivity
+that has consequences within an app should be logged at the DEBUG or VERBOSE
+level (depending on whether the consequences are serious enough and unexpected
+enough to be logged in a release build).</p>
+<p><i>Note:</i> A full filesystem on a filesystem that is acceessible to or on
+behalf of third-party applications should not be logged at a level higher than
+INFORMATIVE.</p>
+<p><i>Note:</i> Invalid data coming from any untrusted source (including any
+file on shared storage, or data coming through just about any network
+connections) is considered expected and should not trigger any logging at a
+level higher then DEBUG when it's detected to be invalid (and even then
+logging should be as limited as possible).</p>
+<p><i>Note:</i> Keep in mind that the '+' operator, when used on Strings,
+implicitly creates a StringBuilder with the default buffer size (16
+characters) and potentially quite a few other temporary String objects, i.e.
+that explicitly creating StringBuilders isn't more expensive than relying on
+the default '+' operator (and can be a lot more efficient in fact). Also keep
+in mind that code that calls Log.v() is compiled and executed on release
+builds, including building the strings, even if the logs aren't being
+read.</p>
+<p><i>Note:</i> Any logging that is meant to be read by other people and to be
+available in release builds should be terse without being cryptic, and should
+be reasonably understandable. This includes all logging up to the DEBUG
+level.</p>
+<p><i>Note:</i> When possible, logging should be kept on a single line if it
+makes sense. Line lengths up to 80 or 100 characters are perfectly acceptable,
+while lengths longer than about 130 or 160 characters (including the length of
+the tag) should be avoided if possible.</p>
+<p><i>Note:</i> Logging that reports successes should never be used at levels
+higher than VERBOSE.</p>
+<p><i>Note:</i> Temporary logging that is used to diagnose an issue that's
+hard to reproduce should be kept at the DEBUG or VERBOSE level, and should be
+enclosed by if blocks that allow to disable it entirely at compile-time.</p>
+<p><i>Note:</i> Be careful about security leaks through the log. Private
+information should be avoided. Information about protected content must
+definitely be avoided. This is especially important when writing framework
+code as it's not easy to know in advance what will and will not be private
+information or protected content.</p>
+<p><i>Note:</i> System.out.println() (or printf() for native code) should
+never be used. System.out and System.err get redirected to /dev/null, so your
+print statements will have no visible effects. However, all the string
+building that happens for these calls still gets executed.</p>
+<p><i>Note:</i> <b>The golden rule of logging is that your logs may not
+unnecessarily push other logs out of the buffer, just as others may not push
+out yours.</b></p>
-<h2><a>Naming test methods</a>
-</h2>
-<a>When naming test methods, you can use an underscore to seperate what is being tested from the specific case being tested. This style makes it easier to see exactly what cases are being tested.</a>
-<p><a>Example:</a>
-</p>
-<pre><a>testMethod_specificCase1 <br>testMethod_specificCase2</a>
-</pre>
+<h2>Javatests Style Rules</h2>
+<h2><a name="testmethodnames"></a>Naming test methods</h2>
+<p>When naming test methods, you can use an underscore to seperate what is
+being tested from the specific case being tested. This style makes it easier
+to see exactly what cases are being tested.</p>
+<p><a>For example:</a></p>
+<pre>testMethod_specificCase1 testMethod_specificCase2</pre>
-<pre><a>void testIsDistinguishable_protanopia() {<br>ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA)<br>assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK))<br>assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))<br>}</a>
+<pre>void testIsDistinguishable_protanopia() {
+ ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA)
+ assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK))
+ assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))
+}
</pre>
-</div>
-</div>
-</div>
diff --git a/pdk/docs/source/download.jd b/pdk/docs/source/download.jd
index 329deff..65bcc70 100644
--- a/pdk/docs/source/download.jd
+++ b/pdk/docs/source/download.jd
@@ -1,303 +1,202 @@
page.title=Get Android Source Code
doc.type=source
@jd:body
-<div><br>This document describes how to set up your local work environment, how to use Repo to get the Android files, and how to build the files on your machine.<br><br>Related reading:<br></div>
-<ul><li>For an overview of the entire code-review and code-update process, see
-<a href="{@docRoot}source/life-of-a-patch.html">Life of a Patch</a>
-.</li>
-<li>For reference details about Repo, see <a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>
-.<br></li>
-</ul>
-<h2>
-What's in the source?</h2>
-<div>To see snapshots and histories of the files available in the public Android repositories, visit the <a href="http://android.git.kernel.org/">GitWeb</a>
-web interface.</div>
-<div></div>
-<div>The source is approximately 2.1GB in size. You will need 6GB free to complete the build.<br><br></div>
-<h2>
-Setting up your machine</h2>
-<div>To build the Android source files, you will need to use Linux or Mac OS. Building under Windows is not currently supported.</div>
-<div><br></div>
-<h3>
-Linux</h3>
-The Android build is routinely tested on recent versions of Ubuntu (6.06 and later), but reports of successes or failures on other distributions are welcome.<br><h4>
-Ubuntu Linux (32-bit x86)</h4>
-<div>To set up your Linux development environment, make sure you have the following:</div>
-<div><div><div><ul><li>Required Packages:</li>
-<ul><li>Git 1.5.4 or newer <span>and the GNU Privacy Guard.<br></span>
-</li>
-</ul>
-</ul>
+
+<div>
+ <p>This document describes how to set up your local work environment, how to use Repo to get the Android files, and how to build the files on your machine.</p>
+ <p>Related reading:
+ <ul>
+ <li>For an overview of the entire code-review and code-update process, see
+<a href="{@docRoot}source/life-of-a-patch.html">Life of a Patch</a>.</li>
+ <li>For reference details about Repo, see <a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>.</li>
+ </ul>
+ </p>
</div>
+
+<div>
+ <h2>What's in the source?</h2>
+ <p>To see snapshots and histories of the files available in the public Android repositories, visit the <a href="http://android.git.kernel.org/">GitWeb</a> web interface.</p>
+ <p>The source is approximately 2.6GB in size. You will need 6GB free to complete the build.</p>
</div>
+
+<div>
+ <h2>Setting up your machine</h2>
+ <p>To build the Android source files, you will need to use Linux or Mac OS. Building under Windows is not currently supported.</p>
+
+ <h3>Linux</h3>
+ <p>The Android build is routinely tested in house on recent versions of Ubuntu (10.04 and later), but most distributions should have the required build tools available. Reports of successes or failures on other distributions are welcome.</p>
+ <p>In general you will need:
+ <ul>
+ <li>Python 2.4, which you can download from <a href="http://www.python.org/download/">python.org</a>.</li>
+ <li>JDK 6 if you wish to build Gingerbread or newer; JDK 5 for Froyo or older. You can download either from <a href="http://java.sun.com/javase/downloads/">java.sun.com</a>.</li>
+ <li>Git 1.5.4 or newer. You can find it at <a href="http://git.or.cz/">http://git.or.cz/</a>.</li>
+ </ul>
+ </p>
+
+ <h4>Ubuntu Linux (64-bit)</h4>
+ <p>The Sun JDK is no longer in Ubuntu's main package repository. In order to download it, you need to add the appropriate repository and indicate to the system which JDK should be used.
+ <p>Java 6: for Gingerbread and newer
+ <div class=code>sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"<br/>
+ sudo add-apt-repository "deb-src http://archive.canonical.com/ubuntu lucid partner"<br/>
+ sudo apt-get update<br/>
+ sudo apt-get install sun-java6-jdk<br/>
+ sudo update-java-alternatives -s java-6-sun
+ </div>
+ </p>
+ <p>Java 5: for Froyo and older
+ <div class=code>sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu dapper main multiverse"<br/>
+ sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu dapper-updates main multiverse"<br/>
+ sudo apt-get update<br/>
+ sudo apt-get install sun-java5-jdk<br/>
+ sudo update-java-alternatives -s java-1.5.0-sun
+ </div>
+ </p>
+ </p>
+ <p>To set up your development environment, install the following required packages:
+ <div class=code>$ sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev</div>
+ </p>
+ <p>You might also want Valgrind, a tool that will help you find memory leaks, stack corruption, array bounds overflows, etc.</p>
+
+ <h4>Running Linux in a virtual machine</h4>
+If you are running Linux in a virtual machine, you will need at least 1.5GB of RAM and 10GB or more of disk space in order to build the Android tree.<br>
+</div>
+
+<div>
+ <h3>Mac OS X</h3>
+ <p>To build the Android files in a Mac OS environment, you need an Intel/x86 machine running MacOS 10.4 (Tiger), 10.5 (Leopard), or 10.6 (Snow Leopard). The Android build system and tools do not support the obsolete PowerPC architecture.</p>
+ <p>Android must be built on a case-sensitive file system because the sources contain files that differ only in case. We recommend that you build Android on a partition that has been formatted with the journaled file system HFS+. HFS+ is required to successfully build Mac OS applications such as the Android Emulator for OS X.</p>
+ <div>
+ <h4>Creating a case sensitive disk image</h4>
+ <p>If you want to avoid partitioning/formatting your hard drive, you can use a case-sensitive disk image instead. To create the image, launch Disk Utility and select "New Image". A size of 8 GB is sufficient, or more if you prefer. Be sure to select "case sensitive, journaled" as the volume format.</p>
+ <p>This will create a .dmg file which, once mounted, acts as a drive with the required formatting for Android development. For a disk image named "android.dmg" stored in your home directory, you can add the following to your <tt>~/.bash_profile</tt> to mount the image when you execute "mountAndroid":
+ <div class=code># mount the android file image<br/>
+ function mountAndroid{ hdiutil attach ~/android.dmg-mountpoint /Volumes/android; }</div>
+ Once mounted, you'll do all your work in the "android" volume. You can eject it (unmount it) just like you would with an external drive.</p>
+ </div>
+
+ <p>To set up your Mac OS development environment, follow these steps:
+ <ol>
+ <li>Install XCode from <a href="http://developer.apple.com/">http://developer.apple.com</a>. We recommend version 3.0 or newer. If you are not already registered as an Apple developer, you will have to create an Apple ID in order to download.</li>
+ <li>Install MacPorts from <a href="http://www.macports.org/install.php">http://www.macports.org/</a>.</li>
+ <li>Make sure that /opt/local/bin appears in your path BEFORE /usr/bin. If not, add
+ <div class=code>export PATH=/opt/local/bin:$PATH</div>
+ to your <tt>~/.bash_profile</tt>.</li>
+ <li>Get make, git, and GPG packages from port:
+ <div class=code>$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git-core gnupg</div>
+ If using Mac OS 10.4, also install bison:
+ <div class=code>$ POSIXLY_CORRECT=1 sudo port install bison</div>
+ </li>
+ <li>Temporary step: There is a bug in gmake 3.82 that prevents android from building. You can install version 3.81 using MacPorts by taking the following steps:
+ <p>Edit <tt>/opt/local/etc/macports/sources.conf</tt> and a line that says <div class=code>file:///Users/Shared/dports</div> above the rsync line. Then create this directory: <div class=code>$ mkdir /Users/Shared/dports</div>
+ In the new <tt>dports</tt> directory, run <div class=code>$ svn co --revision 50980 http://svn.macports.org/repository/macports/trunk/dports/devel/gmake/ devel/gmake/</div>
+ Create a port index for your new local repository: <div class=code>$ portindex /Users/Shared/dports</div>
+ Finally, install the old version of gmake with <div class=code>$ sudo port install gmake @3.81</div>
+ </p>
+ </li>
+ <li>Set an appropriate per-process file descriptor limit. To do this, add the following lines to your <tt>~/.bash_profile</tt>: <div class=code># set the number of open files to be 1024<br/>
+ ulimit -S -n 1024</div>
+ </li>
+ </ol>
+ </p>
</div>
+
+
+<div>
+ <h2>Installing Repo</h2>
+ <p>Repo is a tool that makes it easier to work with Git in the context of Android. For more information about Repo, see <a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>.</p>
+ <p>To install, initialize, and configure Repo, follow these steps:
+ <ol>
+ <li>Make sure you have a bin/ directory in your home directory, and that it is included in your path:
+ <div class=code>$ mkdir ~/bin<br/>
+ $ PATH=~/bin:$PATH</div>
+ </li>
+ <li>Download the Repo script and ensure it is executable:
+ <div class=code>$ curl http://android.git.kernel.org/repo > ~/bin/repo<br/>
+ $ chmod a+x ~/bin/repo</div>
+ </li>
+ </ol>
</div>
-<div><div><div><div><ul><ul><li>JDK 5.0, update 12 or higher.Java 6 is not supported, because of incompatibilities with @Override.<br></li>
-</ul>
-</ul>
+
+<div>
+ <h2>Initializing a Repo client</h2>
+ <p>After installing Repo, set up your client to access the android source repository:
+ <ol>
+ <li>Create an empty directory to hold your working files:
+ <div class=code>$ mkdir <i>directory</i><br/>
+ $ cd <i>directory</i></div>
+ </li>
+ <li>Run <tt>repo init</tt> to bring down the latest version of Repo with all its most recent bug fixes. You must specify a URL for the manifest, which specifies where the various repositories included in the Android source will be placed within your working directory.
+ <div class=code>$ repo init -u git://android.git.kernel.org/platform/manifest.git</div>
+ To check out a branch other than "master", specify it with -b:
+ <div class=code>$ repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake</div>
+ </li>
+ <li>When prompted, please configure Repo with your real name and email address. To use the Gerrit code-review tool, you will need an email address that is connected with a <a href="http://www.google.com/accounts">registered Google account</a>. Make sure this is a live address at which you can receive messages. The name that you provide here will show up in attributions for your code submissions.
+ </li>
+ </ol>
+ A successful initialization will end with a message stating that Repo is initialized in your working directory. Your client directory should now contain a <tt>.repo</tt> directory where files such as the manifest will be kept.</p>
</div>
+
+<div>
+ <h2>Getting the files</h2>
+ <p>To pull down files to your working directory from the repositories as specified in the default manifest, run
+ <div class=code>$ repo sync</div>
+ For more about <tt>repo sync</tt> and other Repo commands, see <a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>.</span>
+ <p>The Android source files will be located in your working directory under their project names.</p>
</div>
+
+<div>
+ <h2>Verifying Git Tags</h2>
+ <p>Load the following public key into your GnuPG key database. The key is used to sign annotated tags that represent releases.
+ <div class=code>$ gpg --import</div>
+ Copy and paste the key(s) below, then enter EOF (Ctrl-D) to end the input and process the keys.
+ <div class=code>-----BEGIN PGP PUBLIC KEY BLOCK-----<br>
+ Version: GnuPG v1.4.2.2 (GNU/Linux)<br><br>
+ mQGiBEnnWD4RBACt9/h4v9xnnGDou13y3dvOx6/t43LPPIxeJ8eX9WB+8LLuROSV <br>
+ lFhpHawsVAcFlmi7f7jdSRF+OvtZL9ShPKdLfwBJMNkU66/TZmPewS4m782ndtw7<br>
+ 8tR1cXb197Ob8kOfQB3A9yk2XZ4ei4ZC3i6wVdqHLRxABdncwu5hOF9KXwCgkxMD <br>
+ u4PVgChaAJzTYJ1EG+UYBIUEAJmfearb0qRAN7dEoff0FeXsEaUA6U90sEoVks0Z <br>
+ wNj96SA8BL+a1OoEUUfpMhiHyLuQSftxisJxTh+2QclzDviDyaTrkANjdYY7p2cq <br>
+ /HMdOY7LJlHaqtXmZxXjjtw5Uc2QG8UY8aziU3IE9nTjSwCXeJnuyvoizl9/I1S5<br>
+ jU5SA/9WwIps4SC84ielIXiGWEqq6i6/sk4I9q1YemZF2XVVKnmI1F4iCMtNKsR4<br>
+ MGSa1gA8s4iQbsKNWPgp7M3a51JCVCu6l/8zTpA+uUGapw4tWCp4o0dpIvDPBEa9<br>
+ b/aF/ygcR8mh5hgUfpF9IpXdknOsbKCvM9lSSfRciETykZc4wrRCVGhlIEFuZHJv <br>
+ aWQgT3BlbiBTb3VyY2UgUHJvamVjdCA8aW5pdGlhbC1jb250cmlidXRpb25AYW5k <br>
+ cm9pZC5jb20+iGAEExECACAFAknnWD4CGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIX <br>
+ gAAKCRDorT+BmrEOeNr+AJ42Xy6tEW7r3KzrJxnRX8mij9z8tgCdFfQYiHpYngkI <br>
+ 2t09Ed+9Bm4gmEO5Ag0ESedYRBAIAKVW1JcMBWvV/0Bo9WiByJ9WJ5swMN36/vAl <br>
+ QN4mWRhfzDOk/Rosdb0csAO/l8Kz0gKQPOfObtyYjvI8JMC3rmi+LIvSUT9806Up <br>
+ hisyEmmHv6U8gUb/xHLIanXGxwhYzjgeuAXVCsv+EvoPIHbY4L/KvP5x+oCJIDbk <br>
+ C2b1TvVk9PryzmE4BPIQL/NtgR1oLWm/uWR9zRUFtBnE411aMAN3qnAHBBMZzKMX <br>
+ LWBGWE0znfRrnczI5p49i2YZJAjyX1P2WzmScK49CV82dzLo71MnrF6fj+Udtb5+<br>
+ OgTg7Cow+8PRaTkJEW5Y2JIZpnRUq0CYxAmHYX79EMKHDSThf/8AAwUIAJPWsB/M <br>
+ pK+KMs/s3r6nJrnYLTfdZhtmQXimpoDMJg1zxmL8UfNUKiQZ6esoAWtDgpqt7Y7s <br>
+ KZ8laHRARonte394hidZzM5nb6hQvpPjt2OlPRsyqVxw4c/KsjADtAuKW9/d8phb <br>
+ N8bTyOJo856qg4oOEzKG9eeF7oaZTYBy33BTL0408sEBxiMior6b8LrZrAhkqDjA <br>
+ vUXRwm/fFKgpsOysxC6xi553CxBUCH2omNV6Ka1LNMwzSp9ILz8jEGqmUtkBszwo <br>
+ G1S8fXgE0Lq3cdDM/GJ4QXP/p6LiwNF99faDMTV3+2SAOGvytOX6KjKVzKOSsfJQ <br>
+ hN0DlsIw8hqJc0WISQQYEQIACQUCSedYRAIbDAAKCRDorT+BmrEOeCUOAJ9qmR0l <br>
+ EXzeoxcdoafxqf6gZlJZlACgkWF7wi2YLW3Oa+jv2QSTlrx4KLM=<br>
+ =Wi5D <br>
+ -----END PGP PUBLIC KEY BLOCK-----
+ </div>
+ After importing the keys, you can verify any tag with <div class=code>$ git tag -v <i>tagname</i></div>
+ </p>
</div>
+
+<div>
+ <h2>Building the code</h2>
+ <p>To build the files, run envsetup, lunch, and make from within your working directory:
+ <div class=code>$ cd ~/<i>directory</i><br/>
+ $ source build/envsetup.sh<br/>
+ $ lunch<br/>
+ $ make<br/>
+ </div>
+ If your build fails because of a missing <tt>run-java-tool</tt>, try setting the <tt>ANDROID_JAVA_HOME</tt> environment variable before making.
+ <div class=code>$ export ANDROID_JAVA_HOME=$JAVA_HOME</div>
+ </p>
</div>
-<div><div><div><div><ul><ul><li><span>flex, bison, gperf, libsdl-dev, libesd0-dev, libwxgtk2.6-dev (optional), build-essential, zip, curl.</span>
-</li>
-</ul>
-</ul>
-</div>
-</div>
-</div>
-</div>
-<blockquote><span>$ sudo apt-get install</span>
-<span>git-core gnupg</span>
-<span>sun-java5-jdk</span>
-<span>flex bison gperf <span>libsdl-dev libesd0-dev</span>
-libwxgtk2.6-dev build-essential zip <span>curl libncurses5-dev zlib1g-dev <br></span>
-</span>
-</blockquote>
-<div><div><div><div><ul><li><span><span>You might also want Valgrind, a tool that will help you find memory leaks, stack corruption, array bounds overflows, etc.</span>
-</span>
-</li>
-</ul>
-</div>
-</div>
-</div>
-</div>
-<blockquote><div><span>$ sudo apt-get install valgrind <br></span>
-</div>
-</blockquote>
-<ul><li><span><span>Intrepid (</span>
-</span>
-8.10) users may need a newer version of libreadline:</li>
-</ul>
-<div>$ sudo apt-get install lib32readline5-dev <br></div>
-</div>
-<div><div><div><div><div><div><h4>
-Ubuntu Linux (64-bit x86)</h4>
-This has not been as well tested. Please send success or failure reports to <a href="mailto:android-porting@googlegroups.com">android-porting@googlegroups.com</a>
-.</div>
-<div><br></div>
-<div>The Android build requires a 32-bit build environment as well as some other tools:<br></div>
-<div><ul><li>Required Packages:</li>
-<ul><li>Git, JDK, flex, and the other packages as listed above in the i386 instructions:<span><br></span>
-</li>
-<li>JDK 5.0, update 12 or higher.Java 6 is not supported, because of incompatibilities with @Override.</li>
-<li>Pieces from the 32-bit cross-building environment</li>
-<li>X11 development <br></li>
-</ul>
-</ul>
-</div>
-</div>
-</div>
-</div>
-<blockquote><span><span>$</span>
-sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl</span>
-sun-java5-jdk <span><span>zlib1g-dev</span>
-</span>
-gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev</blockquote>
-<ul><li>Set the system to use the right version of java by default:<br><br>$sudo update-java-alternatives -sjava-1.5.0-sun <br></li>
-</ul>
-<ul><li>X11: Ubuntu doesn't have packages for the X11 libraries, but that can be worked around with the following command:<br><br>$ sudo ln -s /usr/lib32/libX11.so.6 /usr/lib32/libX11.so <br><br></li>
-</ul>
-<div><div><div><div><div><h4>
-Running Linux in a virtual machine</h4>
-If you are running Linux in a virtual machine, you will need at least 1.5GB of RAM and 10GB or more of disk space in order to build the Android tree.<br><h4>
-Other Linux</h4>
-<p>There's no reason why Android cannot be built on non-Ubuntu systems. Please send any success or failure reports to <a href="mailto:android-porting@googlegroups.com">android-porting@googlegroups.com</a>
-<span>. In general you will need:</span>
-</p>
-<ul><li>Python 2.4, which you can <a href="http://www.python.org/download/">download from python.org</a>.</li>
-<li>JDK 5.0, update 12 or higher, which you can <a href="http://java.sun.com/javase/downloads/">download from java.sun.com</a>. Java 6 is not supported, because of incompatibilities with @Override.</li>
-<li>Git 1.5.4 or newer. You can find it at <a href="http://git.or.cz/">http://git.or.cz/</a>.</li>
-</ul>
-<p>Anything missing from this list? Please let us know!</p>
-<h4>
-<span><br></span>
-</h4>
-</div>
-<div><h3>
-Mac OS <br></h3>
-</div>
-<div><p><span>Requirements:</span>
-</p>
-<ul><li><span>To build the Android files in a Mac OS environment, you need an Intel/x86 machine running MacOS 10.4 ("Tiger") or 10.5 ("Leopard"). At the moment MacOS 10.6 ("Snow Leopard") is not supported. The Android build system and tools do not support the obsolete PowerPC architecture.</span>
-</li>
-<li><span>Android must be built on a case-sensitive file system.<br></span>
-</li>
-<ul><li>We recommend that you build Android on a partition that has been formatted with the "Case-sensitive Journaled HFS+" file system:</li>
-<ul><li>A case-sensitive file system is required because the sources contain files that differ only in case.</li>
-<li>Journaled systems are more robust. (This is optional, but recommended.)</li>
-<li>HFS+ is required to successfully build Mac OS applications such as the Android Emulator for OS X.</li>
-</ul>
-<li>If you want to avoid partitioning/formatting your hard drive, you can use a case-sensitive disk image instead.</li>
-<ul><li>To create the image:<br><ul><li>launch /Applications/Utilities/Disk Utility</li>
-<li>select "New Image"</li>
-<li>size: 8 GB (this will work, but you can choose more if you want to)</li>
-<li>volume format: case sensitive, journaled</li>
-</ul>
-</li>
-<li>This will create a .dmg file which, once mounted, acts as a drive with the required formatting for Android development. For a disk image named "android.dmg" stored in your home directory, you can add the following to your ~/.bash_profile to mount the image when you execute "mountAndroid":<br><br><div># command to mount the android file image <br>function mountAndroid{ hdiutil attach ~/android.dmg-mountpoint /Volumes/android; }<br></div>
-<br>Once mounted, you'll do all your work in the "android" volume. You can eject it (unmount it) just like you would with an external drive.</li>
-</ul>
-</ul>
-</ul>
-<ul></ul>
-To set up your Mac OS development environment, follow these steps:<br><ol><li>Install the XCode version 2.4 or later from <a href="http://developer.apple.com/">http://developer.apple.com</a>. We recommend version 3.0 or newer.<br></li>
-<li>Install MacPorts. To do this:</li>
-<ol><li>Download the tar file from <a href="http://www.macports.org/">http://www.macports.org/</a> and untar the files.</li>
-<li>Run the following:<span><br>$ ./configure <br></span>
-<span>$</span>
-<span>make <br></span>
-<span>$</span>
-<span>sudo make install</span>
-</li>
-<li>Make sure that /opt/local/bin is in your path before /usr/bin. by running <br>$ echo $PATH <br>If you don't see /opt/local/bin, edit $HOME/.bash_profile and add the line <br>export PATH=/opt/local/bin:$PATH <br>(or the equivalent for other shells) after any other PATH-related lines.<span>To verify that your path is now correct, o</span>
-pen a new terminal and <span>run</span>
-echo $PATH <span>again</span>
-.</li>
-<li>Ask MacPorts to update itself:<br><span></span>
-<span>$</span>
-<span>sudo port selfupdate</span>
-<br></li>
-</ol>
-<li>Get the following packages from port:<br>$<span>POSIXLY_CORRECT=1</span>
-sudo port install gmake libsdl git-core gnupg <br><span>If using Mac OS 10.4, also install:<br>$<span>POSIXLY_CORRECT=1</span>
-sudo port install bison <br></span>
-</li>
-<li>Upgrade GNU make to 3.81 or later by running.Mac OS doesn't come with a recent enough version.<br>$ sudo ln -s gmake /opt/local/bin/make <br></li>
-<li>Set an appropriate per-process file descriptor limit. To do this, add the following lines to your <i><span>.bash_profile</span>
-</i>
-file:<br># set the number of open files to be 1024<br>ulimit -S -n 1024</li>
-</ol>
-</div>
-</div>
-</div>
-<div><br></div>
-<h2>
-Installing Repo <br></h2>
-<div><p>Repo is a tool that makes it easier to work with Git in the context of
-Android. For more information about Repo, see <a
-href="{@docRoot}source/git-repo.html">Using Repo and Git</a>
-.<br></p>
-To install, initialize, and configure Repo, follow these steps:<br><br></div>
-<ol><li><span>Make sure you have a~/bindirectory in your home directory, and check to be sure that this bin directory is in your path:</span>
-<br>$ cd~<br><span><span>$ mkdir bin <br>$ echo $PATH <br></span>
-</span>
-</li>
-<li><span>Download thereposcript and make sure it is executable:</span>
-<br>$ curl http://android.git.kernel.org/repo~/bin/repo <div>$ chmod a+x ~/bin/repo</div>
-</li>
-</ol>
-</div>
-<div><p><br></p>
-<h2>
-Initializing a Repo client <br></h2>
-</div>
-<div><ol><li><span>Create an empty directory to hold your working files:</span>
-<span><br></span>
-<span>$ mkdir mydroid</span>
-<br><span>$ cd mydroid</span>
-<br></li>
-<li><span>Runrepo initto bring down the latest version of Repo with all its most recent bug fixes. You must specify a URL for the manifest:</span>
-<br><span>$ repo init</span>
--u git://android.git.kernel.org/platform/manifest.git</li>
-<ul><li><span>If you would like to check out a branch other than "master", specify it with -b, like:</span>
-<br><span>$ repo init</span>
--u git://android.git.kernel.org/platform/manifest.git -b cupcake <br></li>
-</ul>
-<li><span>When prompted, configure Repo with your real name and email address. If you plan to submit code, use an email address that is associated with a <a href="https://www.google.com/accounts">Google account</a>
-.</span>
-<br></li>
-</ol>
-<span><span>A successful initialization will end with a message such as</span>
-<br><span>repo</span>
-initialized in /mydroid</span>
-<br><span><span><br>Your client directory should now contain a.repodirectory where files such as the manifest will be kept.</span>
-<br><br></span>
-<span><span><b>What will my name and email be used for?</b>
-<br></span>
-<span><br>To use the Gerrit code-review tool,</span>
-<span>you will need an email address that is connected with a <a href="http://www.google.com/accounts">registered Google account</a>
-(which does not have to be a Gmail address). Make sure this is</span>
-<span>a live address</span>
-<span>at which you can receive messages</span>
-<span>.</span>
-<span>The real name that you provide here will show up in attributions for your code submissions.</span>
-</span>
-<br></div>
-<span><p><b>What is a manifest file?</b>
-</p>
-<p><span>The Android source files are divided among a number of different repositories.</span>
-<span>A manifest</span>
-<span>file contains a mapping of where the files from these repositories will be placed within your working directory w</span>
-<span>hen you synchronize your files.<br></span>
-</p>
-<p><span><br></span>
-</p>
-</span>
-<h2>
-Getting the files</h2>
-<div><span><span>To pull down files to your working directory from the repositories as specified in the default manifest, run</span>
-<br><br>$ repo sync <i><br></i>
-<br><span>For more aboutrepo syncand other Repo commands, see</span>
-<a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>
-<span>.</span>
-<br><br><span>The Android source files will be located in your working
-directory under their project names.</span>
-</span>
-<br></div>
-<span><h2>
-<br></h2>
-<h2>
-Verifying Git Tags</h2>
-<span>Load the following public key into your GnuPG key database.The key is used to sign annotated tags that represent releases.</span>
-<br><br></span>
-<span>$ gpg --import <br><br></span>
-<span><span>then paste the key(s) below, and press Control-D to end the input and process the keys.</span>
-After importing the keys, you can verify any tag with <br><br></span>
-<span>$ git tag -v <i>tagname</i>
-</span>
-<span><br><br><b><u>key 9AB10E78: "The Android Open Source Projectinitial-contribution@android.com"</u>
-</b>
-<br></span>
-<pre>-----BEGIN PGP PUBLIC KEY BLOCK-----<br>Version: GnuPG v1.4.2.2 (GNU/Linux)<br><br>mQGiBEnnWD4RBACt9/h4v9xnnGDou13y3dvOx6/t43LPPIxeJ8eX9WB+8LLuROSV <br>lFhpHawsVAcFlmi7f7jdSRF+OvtZL9ShPKdLfwBJMNkU66/TZmPewS4m782ndtw7<br>8tR1cXb197Ob8kOfQB3A9yk2XZ4ei4ZC3i6wVdqHLRxABdncwu5hOF9KXwCgkxMD <br>u4PVgChaAJzTYJ1EG+UYBIUEAJmfearb0qRAN7dEoff0FeXsEaUA6U90sEoVks0Z <br>wNj96SA8BL+a1OoEUUfpMhiHyLuQSftxisJxTh+2QclzDviDyaTrkANjdYY7p2cq <br>/HMdOY7LJlHaqtXmZxXjjtw5Uc2QG8UY8aziU3IE9nTjSwCXeJnuyvoizl9/I1S5<br>jU5SA/9WwIps4SC84ielIXiGWEqq6i6/sk4I9q1YemZF2XVVKnmI1F4iCMtNKsR4<br>MGSa1gA8s4iQbsKNWPgp7M3a51JCVCu6l/8zTpA+uUGapw4tWCp4o0dpIvDPBEa9<br>b/aF/ygcR8mh5hgUfpF9IpXdknOsbKCvM9lSSfRciETykZc4wrRCVGhlIEFuZHJv <br>aWQgT3BlbiBTb3VyY2UgUHJvamVjdCA8aW5pdGlhbC1jb250cmlidXRpb25AYW5k <br>cm9pZC5jb20+iGAEExECACAFAknnWD4CGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIX <br>gAAKCRDorT+BmrEOeNr+AJ42Xy6tEW7r3KzrJxnRX8mij9z8tgCdFfQYiHpYngkI <br>2t09Ed+9Bm4gmEO5Ag0ESedYRBAIAKVW1JcMBWvV/0Bo9WiByJ9WJ5swMN36/vAl <br>QN4mWRhfzDOk/Rosdb0csAO/l8Kz0gKQPOfObtyYjvI8JMC3rmi+LIvSUT9806Up <br>hisyEmmHv6U8gUb/xHLIanXGxwhYzjgeuAXVCsv+EvoPIHbY4L/KvP5x+oCJIDbk <br>C2b1TvVk9PryzmE4BPIQL/NtgR1oLWm/uWR9zRUFtBnE411aMAN3qnAHBBMZzKMX <br>LWBGWE0znfRrnczI5p49i2YZJAjyX1P2WzmScK49CV82dzLo71MnrF6fj+Udtb5+<br>OgTg7Cow+8PRaTkJEW5Y2JIZpnRUq0CYxAmHYX79EMKHDSThf/8AAwUIAJPWsB/M <br>pK+KMs/s3r6nJrnYLTfdZhtmQXimpoDMJg1zxmL8UfNUKiQZ6esoAWtDgpqt7Y7s <br>KZ8laHRARonte394hidZzM5nb6hQvpPjt2OlPRsyqVxw4c/KsjADtAuKW9/d8phb <br>N8bTyOJo856qg4oOEzKG9eeF7oaZTYBy33BTL0408sEBxiMior6b8LrZrAhkqDjA <br>vUXRwm/fFKgpsOysxC6xi553CxBUCH2omNV6Ka1LNMwzSp9ILz8jEGqmUtkBszwo <br>G1S8fXgE0Lq3cdDM/GJ4QXP/p6LiwNF99faDMTV3+2SAOGvytOX6KjKVzKOSsfJQ <br>hN0DlsIw8hqJc0WISQQYEQIACQUCSedYRAIbDAAKCRDorT+BmrEOeCUOAJ9qmR0l <br>EXzeoxcdoafxqf6gZlJZlACgkWF7wi2YLW3Oa+jv2QSTlrx4KLM=<br>=Wi5D <br>-----END PGP PUBLIC KEY BLOCK-----<br></pre>
-<span><br><h2>
-Building the code</h2>
-<span>To build the files, runmakefrom within your working directory:</span>
-<br><span>$ cd ~/mydroid</span>
-<span><br>$ make</span>
-<br></span>
-<p>If your build fails, complaining about a missing "run-java-tool", try setting the ANDROID_JAVA_HOME env var to $JAVA_HOME before making.E.g.,</p>
-<p>$ export ANDROID_JAVA_HOME=$JAVA_HOME</p>
-<h2>
-Using an IDE</h2>
-<ul><li><a href="{@docRoot}source/using-eclipse.html">Using Eclipse</a>
-for Android platform development <br></li>
-</ul>
-<h2>
-Troubleshooting</h2>
-<p><span><b>ImportError: No module na</b>
-<span><b>med</b>
-</span>
-<span><b>readline</b>
-</span>
-<b><br></b>
-</span>
-</p>
-<p><span>Mac users getting this should install Python 2.5.2.</span>
-</p>
-<p><span>Linux users that installed Python from source, make sure the dependencies for libreadline are installed, and rebuild Python.</span>
-</p>
-<span><h2>
-What's next?</h2>
-</span>
-<span>To learn about reporting an issue and searching previously reported issues,</span>
-<span>see</span>
-<a href="{@docRoot}source/report-bugs.html">Report bugs</a>
-<span>.</span>
-<span>For information about editing the files and uploading changes to the
-code-review server, see <a href="{@docRoot}source/submit-patches.html">Contribute</a>
-.</span>
-</div>
-</div>
-</div>
+
+<div>
+ <h2>What's next?</h2>
+ <p>See <a href="{@docRoot}source/using-eclipse.html">Using Eclipse</a> for instructions on how to use an IDE for Android platform development. To learn about reporting an issue and searching previously reported issues, see <a href="{@docRoot}source/report-bugs.html">Report bugs</a>. For information about editing the files and uploading changes to the code-review server, see <a href="{@docRoot}source/submit-patches.html">Contribute</a>.
</div>
diff --git a/pdk/docs/source/git-repo.jd b/pdk/docs/source/git-repo.jd
index cf10ab7..f777e58 100644
--- a/pdk/docs/source/git-repo.jd
+++ b/pdk/docs/source/git-repo.jd
@@ -1,6 +1,7 @@
page.title=Using Repo and Git
doc.type=source
@jd:body
+<div>
<p>To work with the Android code, you will need to use both Git and Repo.<br></p>
<ul><li><i>Git</i>
is an open-source version-control system designed to handle very large projects that are distributed over multiple repositories. In the context of Android, we use Git for local operations such as local branching, commits, diffs, and edits.<br><br></li>
@@ -22,8 +23,8 @@
In most situations, you can use Git instead of Repo, or mix Repo and Git
commands to form complex commands. Using Repo for basic across-network
operations will make your work much simpler, however.
-<br></div>
-<div><div><h2>
+<br>
+<div><h2>
Task reference <br></h2>
The task list below shows a summary of how to do common Repo and Git tasks.
For complete quick-start information and examples, see <a
@@ -288,14 +289,13 @@
Getting started with the Android source code:
<ul>
- <li><a href="http://source.android.com/download">Get source</a></li>
- <li><a href="http://source.android.com/submit-patches/code-style-guide">Code Style Guide</a></li>
+ <li><a href="http://source.android.com/source/download.html">Get source</a></li>
+ <li><a href="http://source.android.com/source/code-style.html">Code Style Guide</a></li>
</ul>
Repo and Git resources:
<ul>
- <li><a href="http://source.android.com/download/using-repo#TOC-Git-and-Repo-cheatsheet">Git and Repo cheat sheet</a></li>
- <li><a href="http://source.android.com/download/using-repo">Using Repo and Git</a></li>
+ <li><a href="http://source.android.com/source/git-repo.html">Using Repo and Git</a></li>
<li>The <a href="http://book.git-scm.com/">Git Community Book</a> maintained by Scott Chacon</li>
<li><a href="http://git.or.cz/gitwiki/FrontPage">GitWiki</a></li>
<li><a href="http://www.kernel.org/pub/software/scm/git/docs/">Git Manual Page</a></li>
@@ -304,7 +304,7 @@
Documentation on specific tasks:
<ul>
- <li><a href="http://source.android.com/documentation/building-for-dream">Building for an Android Developer Phone</a></li>
+ <li><a href="http://source.android.com/source/building-dream.html">Building for an Android Developer Phone</a></li>
</ul>
-->
@@ -317,4 +317,3 @@
At intervals, you use git commit to save a snapshot of the staged files and a log message that describes the change.<br><br><i>Manifest</i>
<br>A manifest file that contains a list of repositories and a mapping of where the files from these repositories will be located within your working directory. When you synchronize your files, the files contained in the repositories that are listed in the manifest will be pulled into your working directory.</div>
</div>
-</div>
diff --git a/pdk/docs/source/index.jd b/pdk/docs/source/index.jd
index 230a0b3..a9acbf4 100644
--- a/pdk/docs/source/index.jd
+++ b/pdk/docs/source/index.jd
@@ -3,7 +3,7 @@
@jd:body
<div>
<p>Thanks for your interest in Android! Here are some ways you can get involved
-and help Google improve Android. For background on the Android project and our
+and help us improve Android. For background on the Android project and our
goals, check out the <a href="{@docRoot}about/philosophy.html">Project
Philosophy page</a>.</p>
@@ -11,7 +11,7 @@
<p>One of the easiest and most effective ways you can help improve Android is
to file bugs. For more information, visit the <a
href="{@docRoot}source/report-bugs.html">Reporting Bugs</a> page.</p>
-<p>Please note that we can't guarantee that any particular bug can be fixed in
+<p>Please note that we can't guarantee that any particular bug will be fixed in
any particular release. To see what happens to your bug once you report it,
read <a href="{@docRoot}source/life-of-a-bug.html">Life of a Bug</a>.</p>
@@ -26,8 +26,10 @@
<h2>Contribute to the Code</h2>
<p>Code is King. We'd love to review any changes you submit, so please check
-out the source, pick a bug or feature, and get coding.</p>
-<p>You can get started with by learning about the <a
+out the source, pick a bug or feature, and get coding. Note that the smaller
+and more targetted your patch submissions, the easier it will be for us to
+review them.</p>
+<p>You can get started with Android by learning about the <a
href="{@docRoot}source/life-of-a-patch.html">Life of a Patch</a>, and by
learning about <code>git</code>, <code>repo</code>, and other tools using the
links to the left. If you need help along the way, you can join our <a
diff --git a/pdk/docs/source/licenses.jd b/pdk/docs/source/licenses.jd
index 846a92a..17cebeb 100644
--- a/pdk/docs/source/licenses.jd
+++ b/pdk/docs/source/licenses.jd
@@ -4,18 +4,15 @@
<div>
<p>The Android Open Source Project uses a few <a
href="http://www.opensource.org/">open source initiative</a> approved open
-source licenses to enable availability of source code and to accept
-contributions from individuals and corporations.</p>
+source licenses for our software.</p>
<h2>Android Open Source Project license</h2>
-<p>The preferred license for the Android Open Source Project is <a
-href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. Apache 2.0
-is a commercial and open source friendly open source license. The majority of
-the Android platform is licensed under the <a
-href="http://www.apache.org/licenses/">Apache 2.0 license</a>. While the
-project will strive to adhere to the preferred license, there may be
-exceptions which will be handled on a case-by-case basis. For example, the
-Linux kernel patches are under the GPLv2 license with system exceptions, which
-can be found on <a
+<p>The preferred license for the Android Open Source Project is the <a
+href="http://www.apache.org/licenses/LICENSE-2.0">Apache Software License,
+2.0</a> ("Apache 2.0"), and the majority of the Android software is licensed
+with Apache 2.0. While the project will strive to adhere to the preferred
+license, there may be exceptions which will be handled on a case-by-case
+basis. For example, the Linux kernel patches are under the GPLv2 license with
+system exceptions, which can be found on <a
href="http://www.kernel.org/pub/linux/kernel/COPYING">kernel.org</a>.
</p>
<h2>Contributor License Grants</h2>
@@ -25,15 +22,15 @@
href="{@docRoot}source/cla-individual.html">Individual
Contributor License Grant</a>. The grant can be executed online through the <a
href="https://review.source.android.com/#settings,agreements">code review
-tool</a>. The agreement clearly defines the terms under which intellectual
-property has been contributed to the Android Open Source Project.This license
+tool</a>. The grant clearly defines the terms under which intellectual
+property has been contributed to the Android Open Source Project. This license
is for your protection as a contributor as well as the protection of the
project; it does not change your rights to use your own contributions for any
other purpose.</p>
<p>For a <b>corporation</b> (or other entity) that has assigned employees to
work on the Android Open Source Project, a <a
href="{@docRoot}source/cla-corporate.html">Corporate
-Contributor License Grant</a> is available. This version of the Grant allows a
+Contributor License Grant</a> is available. This version of the grant allows a
corporation to authorize contributions submitted by its designated employees
and to grant copyright and patent licenses. Note that a Corporate Contributor
License Grant does not remove the need for any developer to sign their own
diff --git a/pdk/docs/source/life-of-a-bug.jd b/pdk/docs/source/life-of-a-bug.jd
index 1d58ae1..5d77f7a 100644
--- a/pdk/docs/source/life-of-a-bug.jd
+++ b/pdk/docs/source/life-of-a-bug.jd
@@ -57,7 +57,7 @@
which is considered the "master" copy. (For instance, Google maintains one
such private issue tracker, intended primarily for bugs which contain
sensitive information which can't be revealed publicly.)</p></li>
-<li><b>Assigned</b><li>Like <code>Unassigned</code>, but the bug has been
+<li><b>Assigned</b><p>Like <code>Unassigned</code>, but the bug has been
actually assigned to a specific contributor to fix.</p></li>
</ul>
<p>Typically, a given bug will start in <code>Unassigned</code>, where it
@@ -77,8 +77,8 @@
<li><b>Spam</b><p>A kind soul sent us some delicious pork products, that we,
regrettably, do not want.</p></li>
<li><b>Question</b><p>Someone mistook the issue tracker for a help forum.
-(This is not as uncommon as one might assume: many users whose native language
-isn't English can make this mistake.)</p></li>
+(This is not as uncommon as you might think: many users whose native language
+isn't English misunderstand the site and make this mistake.)</p></li>
<li><b>Unreproducible</b><p>An AOSP contributor attempted to reproduce the
behavior described, and was unable to do so. This sometimes means that the bug
is legitimate but simply rare or difficult to reproduce, and sometimes means
diff --git a/pdk/docs/source/overview-1.0.jd b/pdk/docs/source/overview-1.0.jd
deleted file mode 100644
index e1b5cd6..0000000
--- a/pdk/docs/source/overview-1.0.jd
+++ /dev/null
@@ -1,157 +0,0 @@
-page.title=Android 1.0 Features
-doc.type=source
-@jd:body
-<div><div><div><div>This page provides a high-level overview of Android 1.0
-features. To see the code itself, you can either use the <a href="http://android.git.kernel.org/">GitWeb</a>
-interface to view snapshots of the files, or you can <a
-href="{@docRoot}source/download.html">download</a>
-the source code onto your local machine.<br><br><b>Applications</b>
-<br><br>The Android platform comes with a variety of applications written using the Java programming language:<br><ul><li><i>Home</i>
-displays applications, widgets, and shortcuts. It also supports customizable wall paper.
-</li>
-<li><i>Phone</i>
-supports regular telephony functions as well as call controls, conference calls, supplementary services, and easy integration with <i>Contacts</i>
-.<br></li>
-<li><i>Web Browser</i>
-is a fully featured WebKit-based browser that supports HTML and XHTML.
-</li>
-<li><i>Email</i>
-provides access to email servers commonly found on the Internet and supports POP3, IMAP4, and SMTP.
-</li>
-<li><i>Media Player</i>
-enables managing, importing, and playing back content that has been encoded in various forms.<br></li>
-<li><i>Alarm Clock, Calculator, Calendar, Camera, Contacts, IM, MMS, Settings,</i>
-<i>Voice Dialer</i>
-, and many other applications are also included in this release.<br></li>
-</ul>
-<b>Application framework</b>
-<br><br></div>
-<div>The Android Application Framework has been designed to provide a rich set of APIs for third-party application developers. For more information, visit the <a href="http://developer.android.com/guide/index.html">Android SDK developer guide</a>
-.<b><br></b>
-</div>
-<div></div>
-<div><b>Android runtime</b>
-<b><br><br></b>
-Android applications run on Dalvik, a custom virtual machine (VM) designed for embedded use. The Dalvik VM runs dex executable files, which are typically compiled from source code written in Java.<br><br></div>
-<div>The dex executable format is designed to have these characteristics:<br><ul><li>Efficient on-device storage.
-</li>
-<li>Efficient runtime memory usage.
-</li>
-<li>Ease of interpretation.<br></li>
-</ul>
-Dalvik has the following runtime characteristics:
-<ul><li>Efficient support for multiple concurrent VM processes, including amortized initialization and heavily shared memory.
-</li>
-<li>Optimized interpreter.
-</li>
-<li>Efficient linkage to low-level native code.
-</li>
-<li>A familiar and rich set of core library functionality. For a complete list of supported libraries, see <a href="http://developer.android.com/reference/packages.html">http://developer.android.com/reference/packages.html</a>
-.
-</li>
-<li>Enhanced JDWP support, enabling easier debugging of multiple processes simultaneously.
-</li>
-<li>JNI support.
-</li>
-</ul>
-<b>Native libraries <br></b>
-<br>The Android platform makes use of many native libraries, including:<br><ul><li><i>Bionic</i>
-, a custom libc implementation optimized for embedded systems.
-</li>
-<li>Graphics libraries for 2D and 3D (OpenGL ES 1.0) graphics support.<br></li>
-<li>openCore to provide the bulk of Android's multimedia capability. It includes support for network streaming (HTTP and RTSP), as well as most of the codecs and media file parsers used by the system.<br></li>
-<li>sqlite to support having a lightweight transactional data store.
-</li>
-<li>WebKit library to power Android's WebKit based full web browser.<br></li>
-</ul>
-<br><b>System software</b>
-<b><br></b>
-<br></div>
-<div>About Android's operating system:
-<ul><li>Based on Linux 2.6.25 for ARM.<br></li>
-<li>Platform currently expects ARM V5T or better architecture. Support for earlier architectures could be added, but CPUs without an MMU would be difficult to support.
-</li>
-<li>A set of kernel enhancements are provided to support Android. The patches include alarm, ashmem, binder, power management, low memory killer, kernel degugger, and logger <b>.<br></b>
-</li>
-<li>While the platform is designed to be chipset agnostic, and will run on virtually any ARM-based Linux kernel environment, version 1.0 of the platform has been tested and verified on the MSM 7K chipsets <b>.</b>
-Over time we expect to see support for other major chipsets.
-Kernel patches for MSM based chipsets are also available.
-</li>
-<li>FAT32 file system is supported.
-</li>
-<li>Support for TCP/IP (TCP, UDP, etc).
-</li>
-</ul>
-</div>
-<div>A minimal reference bootloader for the supported chipset is provided. It is capable of booting Linux from RAM, debugger, and NAND Flash.<br></div>
-<div><br>About Android's support for debugging:<br><ul><li>Debugging native code is supported via GDB (GNU Project Debugger) over USB.
-</li>
-<li>Debugging managed code is supported via any JDWP-compatible debugger over USB.
-</li>
-<li>Logging and crash logs supported for debugging.
-</li>
-</ul>
-<b>Supported hardware <br></b>
-<ul><li>The platform will run on almost on any ARM based Linux kernel environment.
-</li>
-<li>The platform requires a minimum of 128 MB of RAM and 256 MB ofFlash memory. AnOEM may want to support more Flash memory to make it possible to download more third-party applications to user devices.<br></li>
-<li>The platform will interface with a baseband radio stack provided externally via a Radio Interface Layer (RIL).
-</li>
-<li>802.11 b/g Wi-Fi
-</li>
-<li>Standard USB interface, including USB 2.0
-</li>
-<li>Bluetooth 2.0 EDR (Enhanced Data Rate)
-</li>
-<li>Camera for still and video capture
-</li>
-<li>Removable storage
-</li>
-</ul>
-<b>Supported display</b>
-<br><ul><li>HVGA resolution <br></li>
-<li>16 bit color depth <br></li>
-<li>Landscape and portrait orientation, including dynamic runtime switching
-</li>
-<li>Finger-based touchscreen navigation
-</li>
-</ul>
-<b>Supported keypads and buttons</b>
-<br><ul><li>QWERTY
-</li>
-<li>5-way navigation
-</li>
-<li>Hardware buttons: Send, End, Home, Back, Menu</li>
-<li>Power button
-</li>
-<li>Volume keys (up and down)
-</li>
-<li>Camera trigger button, including detection for both partial press (to focus) and full press (to actually take a picture)
-</li>
-</ul>
-<b>Supported audio outputs</b>
-<br><ul><li>Audio output via the headphone jack (mono and stereo)
-</li>
-<li>64 kbps Bluetooth audio supported</li>
-</ul>
-<b>Supported notifications</b>
-<br><ul><li>LEDs
-</li>
-<li>Vibration
-</li>
-</ul>
-<b>Supported radio and telephony features <br></b>
-<ul><li>GPRS, EDGE, UMTS, HSDPA
-</li>
-<li>International roaming, SMS, MMS <br></li>
-<li>Emergency call support <br></li>
-<li>Supplementary Services for Telephony, for example call waiting and conference calling <br></li>
-<li>Unstructured Supplementary Service Data (USSD)
-</li>
-<li>Reference Radio Interface Layer (RIL)
-</li>
-</ul>
-</div>
-</div>
-</div>
-</div>
diff --git a/pdk/docs/source/overview-1.5.jd b/pdk/docs/source/overview-1.5.jd
deleted file mode 100644
index dd74874..0000000
--- a/pdk/docs/source/overview-1.5.jd
+++ /dev/null
@@ -1,198 +0,0 @@
-page.title=Android 1.5 Features
-doc.type=source
-@jd:body
-<h3><b>Release features - Android 1.5</b>
-</h3>
-<div><div><div><div><b>Previous release highlights</b>
-:<a href="{@docRoot}source/overview-1.0.html">Android 1.0</a>
-<br><br>This page provides a high-level overview of the new features added to
-Android 1.5. To see the code itself, you can either use the<a href="http://android.git.kernel.org/">GitWeb</a>
-interface to view snapshots of the files, or you can<a
-href="{@docRoot}source/download.html">download</a>
-the source code onto your local machine. You can use<i>repo init -u</i>
-git://android.git.kernel.org/platform/manifest.git<i>-b android-1.5</i>
-to download the source code for Android 1.5.<br><br><b>User interface refinements:</b>
-<br><ul><li>System-wide:
-<ul><li>Refinement of all core UI elements
-</li>
-<li>Animated window transitions (off by default)
-</li>
-<li>Accelerometer-based application rotations
-</li>
-</ul>
-</li>
-<li>UI polish for:
-<ul><li>In-call experience
-</li>
-<li>Contacts, Call log, and Favorites
-</li>
-<li>SMS MMS
-</li>
-<li>Browser
-</li>
-<li>Calendar
-</li>
-<li>Email
-</li>
-<li>Camera Gallery
-</li>
-<li>Application management
-</li>
-</ul>
-</li>
-</ul>
-<div><b><br>Performance improvements:</b>
-<br></div>
-<ul><li>Faster Camera start-up and image capture
-</li>
-<li>Much faster acquisition of GPS location (powered by SUPL AGPS)
-</li>
-<li>Smoother page scrolling in Browser
-</li>
-</ul>
-<br><b>Applications</b>
-<br><ul><li>Camera Gallery
-</li>
-<ul><li>Video recording
-</li>
-<li>Video playback (MPEG-4 3GP formats)
-</li>
-</ul>
-<li>Browser
-</li>
-<ul><li>Updated with latest Webkit browser Squirrelfish Javascript engines
-</li>
-<li>Copy 'n paste in browser
-</li>
-<li>Search within a page
-</li>
-<li>User-selectable text-encoding
-</li>
-<li>UI changes include:
-</li>
-<ul><li>Unified Go and Search box
-</li>
-<li>Tabbed bookmarks/history/most-visited screen
-</li>
-</ul>
-</ul>
-<li>Contacts
-</li>
-<ul><li>Shows user picture for Favorites
-</li>
-<li>Specific date/time stamp for events in call log
-</li>
-<li>One-touch access to a contact card from call log event
-</li>
-</ul>
-</ul>
-<b><br>Application framework</b>
-<br><br></div>
-<div><ul><li>On-screen soft keyboard
-</li>
-<ul><li>Works in both portrait and landscape orientation
-</li>
-<li>Support for user installation of 3rd party keyboards
-</li>
-<li>User dictionary for custom words
-</li>
-</ul>
-<li>Home screen
-</li>
-<ul><li>Widgets
-</li>
-<ul><li>Bundled home screen widgets include: analog clock, calendar, music player, picture frame, and search
-</li>
-</ul>
-<li>Live folders
-</li>
-</ul>
-<li>UI framework
-</li>
-<ul><li>Framework for easier background/UI thread interaction
-</li>
-<li>New SlidingDrawer widget
-</li>
-<li>Horizontal ScrollView widget
-</li>
-</ul>
-<li>Home Screen framework
-</li>
-<ul><li>APIs for creating secure home screen widgets
-</li>
-<li>APIs for populating live folders with custom content
-</li>
-</ul>
-<li>Media framework
-</li>
-<ul><li>Raw audio recording and playback APIs
-</li>
-<li>Interactive MIDI playback engine
-</li>
-<li>Video recording APIs for developers (3GP format)
-</li>
-<li>Video and photo sharing Intents
-</li>
-<li>Media search Intent
-</li>
-</ul>
-<li>Input Method framework
-</li>
-<ul><li>Text prediction engine
-</li>
-<li>Ability to provide downloadable IMEs to users
-</li>
-</ul>
-<li>Speech recognition framework
-</li>
-<ul><li>Support for using speech recognition libraries via Intent
-</li>
-</ul>
-<li>Misc API additions
-</li>
-<ul><li>LocationManager - Applications can get location change updates via Intent
-</li>
-<li>WebView - Touch start/end/move/cancel DOM event support
-</li>
-<li>SensorManager - redesigned sensor APIs
-</li>
-<li>GLSurfaceView - convenience framework for creating OpenGL applications
-</li>
-<li>Broadcast Intent for app update install succeeded - for smoother app upgrade experience
-</li>
-</ul>
-</ul>
-</div>
-<div></div>
-<div><br><b>System software</b>
-<br><br></div>
-<ul><li>New Linux kernel (version 2.6.27)
-</li>
-<li>SD card filesystem auto-checking and repair
-</li>
-<li>SIM Application Toolkit 1.0
-</li>
-</ul>
-<div><b><br>Supported hardware<br></b>
-<ul><li>Bluetooth</li>
-<ul><li>Stereo Bluetooth support (A2DP and AVCRP profiles)
-</li>
-<li>Auto-pairing
-</li>
-<li>Improved handsfree experience
-</li>
-</ul>
-</ul>
-<br><b>Developer tools</b>
-<br></div>
-<div><ul><li>Support for multiple versions of Android in a single SDK installation
-</li>
-<li>Improved JUnit support in ADT
-</li>
-<li>Easier application performance profiling
-</li>
-</ul>
-</div>
-</div>
-</div>
-</div>
diff --git a/pdk/docs/source/overview.jd b/pdk/docs/source/overview.jd
index 2763c52..5a31018 100644
--- a/pdk/docs/source/overview.jd
+++ b/pdk/docs/source/overview.jd
@@ -1,93 +1,36 @@
-page.title=Android 1.6 Platform Overview
+page.title=Android 2.1 Platform
doc.type=source
@jd:body
-<p>This page provides a high-level overview of the new features added to
-Android 1.6. To see the code itself, you can either use the <a
-href="http://android.git.kernel.org/">GitWeb</a>
-interface to view snapshots of the files, or you can <a
-href="{@docRoot}source/download.html">download</a>
-the source code onto your local machine. You can use <code>repo init -u
-git://android.git.kernel.org/platform/manifest.git -b android-1.6</code>
-to download the source code for Android 1.6.</p>
-<p><i>Note: platform overview information for Android 2.x has not yet been
-published, since the <a
-href="{@docRoot}compatibility/index.html">Compatibility Program</a> for
-Android 2.x has not yet launched. When the Compatibilty Definition Document
-for 2.x is released, this page will be updated to match.</i></p>
-<p>Information about older Android releases is also available:<ul>
-<li><a href="{@docRoot}source/overview-1.5.html">Android 1.5 Platform Overview</a></li>
-<li><a href="{@docRoot}source/overview-1.0.html">Android 1.0 Platform Overview</a></li>
-</ul></p>
-<h2>User interface refinements</h2>
-<h3>Quick Search Box for Android </h3>
-<p>Android 1.6 includes a redesigned search framework that provides a quick, effective, and consistent way for users to search across multiple sources—such as browser bookmarks history, contacts, and the web—directly from the home screen.
-</p>
-<p><br></p>
-<p>The system constantly learns which search results are more relevant based on what is clicked. So popular contacts or apps that have previously been picked will bubble up to the top when a user types the first few letters of a relevant query.
-</p>
-<p><br></p>
-<p>The search framework also provides developers a way to easily expose relevant content from their applications in Quick Search Box.
-</p>
-<h3>Camera, Camcorder, and Gallery </h3>
-<p>An updated user interface provides an integrated camera, camcorder, and gallery experience. Users can quickly toggle between still and video capture modes. Additionally, the gallery enables users to select multiple photos for deletion.<br></p>
-<p><br></p>
-<p>Android 1.6 also provides a much faster camera experience. Compared to the previous release, launching the camera is now 39% faster, and there is a 28% improvement in the time from completing one shot to the next.
-</p>
-<h3>VPN, 802.1x </h3>
-<p>A new Virtual Private Network (VPN) control panel in Settings allows users to configure and connect to the following types of VPNs:
-</p>
-<ul><li>L2TP/IPSEC pre-shared key based VPN
- </li>
-<li>L2TP/IPsec certificate based VPN
- </li>
-<li>L2TP only VPN
- </li>
-<li>PPTP only VPN
- </li>
-</ul>
-<h3>Battery usage indicator </h3>
-<p>A new battery usage screen lets users see which apps and services are consuming battery power. If the user determines that a particular service or application is using too much power, they can take action to save the battery by adjusting settings, stopping the application, or uninstalling the application.
-</p>
-<h3>Accessibility </h3>
-<p>Users will be able to download new accessibility services built on the new accessibility framework and enable them in Settings.
-</p>
-<h2>New Platform Technologies </h2>
-<h3>Expanded Search Framework </h3>
-<p>The Android search framework has been redesigned and expanded to provide third-party applications the opportunity to surface content from their applications in Quick Search Box, the global search tool. To do this, developers will need to make their app "searchable" and provide suggestions in response to user queries. To enable application search suggestions, users simply select each application from which they'd like to receive suggestions, under Searchable items in the Search settings.
-</p>
-<h3>Text-to-speech engine</h3>
-<p>Android 1.6 features a multi-lingual speech synthesis engine called Pico. It allows any Android application to "speak" a string of text with an accent that matches the language. The engine supports the following languages: English (American and British accents), French, Italian, German and Spanish. If you're using a T-Mobile G1 or Dream device, you'll need to download the SpeechSynthesis Data Installer from Android Market, which includes the "voices" needed by the text-to-speech engine.
-</p>
-<h3>Gestures </h3>
-<p>A new gestures framework provides application developers with a framework for creating, storing, loading, and recognizing gestures and associating them with specific actions.
-</p>
-<p>Developers can use the new GestureBuilder tool included in the Android 1.6 SDK to generate libraries of gestures to include with their application.
-</p>
-<h3>Accessibility </h3>
-<p>Android 1.6 provides a new accessibility framework. With this framework, developers can create accessibility plugins that respond to user input, such as making a sound when a new window is shown, vibrating when navigating to the top of a list, and providing spoken feedback.
-</p>
-<h3>Expanded support for screen densities and resolutions </h3>
-<p>Android 1.6 adds screen support that enables applications to be rendered properly on different display resolutions and densities. Developers can also specify the types of screens supported by their application.
-</p>
-<h3>Telephony support for CDMA </h3>
-<p>Android 1.6 includes support for CDMA in the telephony stack.
-</p>
-<h3>New version of OpenCore </h3>
-<p>Android 1.6 includes the updated OpenCore 2 media engine, which has:
-</p>
-<ul><li>Support for OpenMAX encoders
- </li>
-<li>Support for additional audio codecs in AuthorEngine
- </li>
-<li>Improved buffering model supports shared buffers allocated in the decoder
- </li>
-</ul>
-<h3>2.6.29 Linux kernel </h3>
-<p>Android 1.6 upgrades the Linux kernel from 2.6.27 to 2.6.29.
-</p>
-<h2>New Framework APIs</h2>
-<p>For a detailed overview of new APIs, see the <a
-href="http://developer.android.com/sdk/android-1.6.html#api-changes">Version
-Notes</a>. For a complete report of all API changes, see the <a
-href="http://developer.android.com/sdk/api_diff/4/changes.html">API
-Differences Report</a>.</p>
+<p>Our sister site, <a
+href="http://developer.android.com/">http://developer.android.com/</a>,
+includes feature overviews of the various Android platform versions.
+The links below will take you to developer.android.com where you can view this
+information.</p>
+<p>The links below will navigate you away from this site.</p>
+<h3><a href="http://developer.android.com/sdk/android-2.3-highlights.html">Android 2.3</a></h3>
+<p>Android 2.3 corresponded to the "Gingerbread" milestone branch, and has an API level of 9.</p>
+<h3><a href="http://developer.android.com/sdk/android-2.2-highlights.html">Android 2.2</a></h3>
+<p>Android 2.2 corresponded to the "FroYo" milestone branch, and has an API level of 8.</p>
+<h3><a href="http://developer.android.com/sdk/android-2.0-highlights.html">Android 2.1</a></h3>
+<p>Android 2.1 corresponded to the "Eclair" milestone branch, and has an API level of
+7.</p>
+<p>The Eclair branch was also used for 2.0 and 2.0.1; however, both of those
+releases were quickly obsoleted by the version 2.1 Eclair release. As Android
+2.1 includes key bug fixes and improvements not present in 2.0/2.0.1, only
+Android 2.1 should be used for new devices. As there is no compatibility
+program for 2.0 or 2.0.1, the officially compatible Eclair-based release is Android
+2.1. (The linked document refers to Android 2.0, because there were
+no new platform features added in 2.1.)</p>
+<h3><a href="http://developer.android.com/sdk/android-1.6-highlights.html">Android 1.6</a></h3>
+<p>Android 1.6 corresponded to the "Donut" milestone branch, and has an API level of
+4.</p>
+<h3><a href="http://developer.android.com/sdk/android-1.5-highlights.html">Android 1.5</a></h3>
+<p>Android 1.5 corresponded to the "Cupcake" milestone branch, and has an API
+level of 3.</p>
+<h3><a href="http://developer.android.com/sdk/android-1.1.html">Android 1.1</a></h3>
+<p>Android 1.1 has an API level of 2. Android 1.1 was known as
+"Petit Four" internally, though this name was not used officially.</p>
+<h3>Android 1.0</h3>
+<p>was the first release of Android, and has an API
+level of 1. Since it was the first released version of Android, no platform
+highlights were prepared for this release.</p>
diff --git a/pdk/docs/source/report-bugs.jd b/pdk/docs/source/report-bugs.jd
index 138080d..a6e56c6 100644
--- a/pdk/docs/source/report-bugs.jd
+++ b/pdk/docs/source/report-bugs.jd
@@ -77,7 +77,7 @@
public class TestObjectNull extends Activity {
/** Called when the activity is first created. */
- @Override
+ @Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
diff --git a/pdk/docs/source/roles.jd b/pdk/docs/source/roles.jd
index 451c821..f4fb891 100644
--- a/pdk/docs/source/roles.jd
+++ b/pdk/docs/source/roles.jd
@@ -15,22 +15,22 @@
<h2>Contributor</h2>
<p>A "Contributor" is anyone making contributions to the AOSP source code,
-including both employees of Google or other companies, as well as
-external developers who are contributing to Android on their own behalf.
-There is no distinction between Contributors who are employed by
-Google, and those who are not: all engineers use the same git/gerrit tools,
-follow the same code review process, and are subject to the same requirements
-on code style and so on.</p>
+including both employees of Google or other companies, as well as external
+developers who are contributing to Android on their own behalf. There is no
+distinction between Contributors who are employed by Google, and those who are
+not: all engineers use the same tools (<code>git</code>, <code>repo</code>,
+and <code>gerrit</code>), follow the same code review process, and are subject
+to the same requirements on code style and so on.</p>
<p/>
<h2>Developer</h2>
<p>A "Developer" is an engineer writing applications that run on Android
devices. There is, of course, no difference in skillset between a "Developer"
-and a "Contributor"; AOSP simply uses "Developer" to help identify our audience.
-Since the key purpose of Android is to cultivate an open development platform,
-"Developers" are one of the key customers of the Android platform. As such, we
-talk about them a lot, though this isn't technically a separate role in the
-AOSP <i>per se.</i></p>
+and a "Contributor", but AOSP uses "Developer" to distinguish between
+engineers using the platform and those contributing to it. Developers are
+(along with end users) the "customers" of the platform that the Contributors
+create. As such, we talk about Developers a lot, though this isn't technically
+a separate role in the AOSP <i>per se.</i></p>
<p/>
<h2>Verifier</h2>
@@ -62,12 +62,12 @@
releases.</li>
<li>Designate Verifiers and Approvers for submitted patches.</li>
<li>Be fair and unbiased while reviewing changes. Accept or reject patches
- based on technical merit and alignment with the Android platform.</li>
+ based on technical merit and alignment with the Android strategy.</li>
<li>Review changes in a timely manner and make best efforts to communicate
when changes are not accepted.</li>
<li>Optionally maintain a web site for the project for information and
documents specific to the project.</li>
<li>Act as a facilitator in resolving technical conflicts.</li>
- <li>Be the public face for the project and the go-to person for questions
+ <li>Be a public face for the project and the go-to person for questions
related to the project.</li>
</ul>
diff --git a/pdk/docs/source/submit-patches.jd b/pdk/docs/source/submit-patches.jd
index 2b7bae1..9e7d9df 100644
--- a/pdk/docs/source/submit-patches.jd
+++ b/pdk/docs/source/submit-patches.jd
@@ -1,6 +1,7 @@
page.title=Android Contributors' Workflow
doc.type=source
@jd:body
+<div>
<br>This page describes how to record changes to the Android files on your local client, upload those changes to the code-review server, and use Gerrit to track changes.<br><h2>
Prerequisites</h2>
Before you follow the instructions on this page, you will need to set up your
@@ -14,6 +15,9 @@
Open Source community, see <a href="{@docRoot}source/roles.html">Project roles</a>.</li>
<li>If you plan to contribute code to the Android platform, be sure to read
the <a href="{@docRoot}source/licenses.html">AOSP's licensing information</a>.</li>
+<li>Note that changes to some of the upstream projects used by Android should be
+made directly to that project, as described in
+<a href="#upstream-projects">Upstream Projects</a>.
</ul>
<h2>
Working with the code</h2>
@@ -129,8 +133,8 @@
</ul>
<h3>
Viewing diffs and comments</h3>
-To open the details of the change within Gerrit, click on the "Id number" or "Subject" of a change. To compare the established code with the updated code, click the file name under "Side-by-side diffs."<br></div>
-<div><h3>
+To open the details of the change within Gerrit, click on the "Id number" or "Subject" of a change. To compare the established code with the updated code, click the file name under "Side-by-side diffs."<br>
+<h3>
Adding comments</h3>
Anyone in the community can use Gerrit to add inline comments to code submissions. A good comment will be relevant to the line or section of code to which it is attached in Gerrit. It might be a short and constructive suggestion about how a line of code could be improved, or it might be an explanation from the author about why the code makes sense the way it is.<br><br>To add an inline comment, double-click the relevant line of the code and write your comment in the text box that opens. When you click Save, only you can see your comment.<br><br>To publish your comments so that others using Gerrit will be able to see them, click the Publish Comments button. Your comments will be emailed to all relevant parties for this change, including the change owner, the patch set uploader (if different from the owner), and all current reviewers.<br><br><h3>
After a submission is approved</h3>
@@ -142,6 +146,27 @@
.<br><br><h2>
Using GitWeb to track patch histories</h2>
To view snapshots of the files that are in the public Android repositories and view file histories, use the <a href="http://android.git.kernel.org/">Android instance of GitWeb</a>
-.<br></div>
-</div>
+.<br>
+<h2><a name="upstream-projects"></a>Upstream Projects</h2>
+Android makes use of a number of other open-source projects, such as the Linux
+kernel and WebKit, as described in
+<a href="{@docRoot}source/code-lines.html">Branches & Releases</a>. For the
+upstream projects detailed below, changes should be made directly upstream. Such
+changes will be incorporated into the Android tree as part of the usual process
+of pulling these projects.
+<h3>WebKit</h3>
+All changes to the WebKit project at <code>external/webkit</code> should be made
+upstream at <a href="http://www.webkit.org">http://www.webkit.org</a>. The
+process begins by filing a WebKit bug. This bug should use <code>Android</code>
+for the <code>Platform</code> and <code>OS</code> fields only if the bug is
+specific to Android. Bugs are far more likely to receive the reviewers'
+attention once a proposed fix is added and tests are included. See
+<a href="http://webkit.org/coding/contributing.html">Contributing Code to
+WebKit</a> for details.
+<h3>V8</h3>
+All changes to the V8 project at <code>external/v8</code> should be submitted
+upstream at
+<a href="http://code.google.com/p/v8">http://code.google.com/p/v8</a>. See
+<a href="http://code.google.com/p/v8/wiki/Contributing">Contributing to V8</a>
+for details.
</div>
diff --git a/pdk/docs/source/using-eclipse.jd b/pdk/docs/source/using-eclipse.jd
index 56df713..660de11 100644
--- a/pdk/docs/source/using-eclipse.jd
+++ b/pdk/docs/source/using-eclipse.jd
@@ -95,58 +95,6 @@
<p>When you're done, the "source folder" path in the list should look like android/packages/apps/<i>YourAppName</i>
/src. Depending on which app(s) you include, you may also need to include othersrc/main/java directories under android/dalvik/libcore. Do this if you find you cannot build with the default set.
</p>
-<h4>
-Eclipse setup to work on developer tools
-</h4>
-<p>To work on Java developer tools, the principle is the same, except you specify /path/to/tool when using the option "Create project from existing source."
-</p>
-<p>Once the project is created, you need to set up the Java Build Path:
-</p>
-<ol><li>Select the project you just created.
-</li>
-<li>Project Properties
-</li>
-<li>Select "Java Build Path" from the left-hand menu.
-</li>
-<li>Choose the "Source" tab.
-</li>
-<li>Expand the single <i>toolname</i>
-/src entry.
-</li>
-<li>Double click the "Excluded: (none)" item.
-</li>
-<li>Add to the excluded (bottom) list: "MakeFile" and "resources/".
-</li>
-<li>Close the dialog.
-</li>
-<li>Back in the "Source" tab, click "Add Folder...", and add <i>toolname</i>
-/src/resources.
-</li>
-<li>Click OK.
-</li>
-</ol>
-<h4>
-Eclipse setup to work on DDMS <br></h4>
-<p>For DDMS, you will need to make a project for
-</p>
-<ol><li>development/tools/ddms/libs/ddmlib
-</li>
-<li>development/tools/ddms/libs/ddmuilib
-</li>
-<li>development/tools/ddms/app
-</li>
-</ol>
-<p>Each project will need to reference the ones before it ("ddmuilib" references "ddmlib", and "app" references both of those). To do this:
-</p>
-<ol><li>Make sure you have all 3 projects defined.
-</li>
-<li>Right click on a project, "Build Path" "Configure Build Path..."
-</li>
-<li>Choose the "Project" tab.
-</li>
-<li>Click "Add..." and check the required projects.
-</li>
-</ol>
<h2><a>Eclipse formatting</a>
</h2>
<p>You can import files in development/ide/eclipse to make Eclipse
@@ -189,15 +137,6 @@
<pre>Ctrl-Shift-o = Organize imports <br>Ctrl-Shift-t = load class by name <br>Ctrl-Shift-r = load non-class resource by name <br>Ctrl-1 = quick fix <br>Ctrl-e = Recently viewed files <br>Ctrl-space = auto complete <br>Shift-Alt-r = refactor:rename <br>Shift-Alt-v = refactor:move <br></pre>
-<h2><a>Useful Plugins</a>
-</h2>
-<p>Eclipse has a plugin architecture that enables third parties to extend the IDE. Here are some plugins that make Eclipse easier to use for writing Android software:
-</p>
-
-<ul><li><a href="http://andrei.gmxhome.de/anyedit/">AnyEdit</a>
-- automatically fix whitespace issues when saving files. Can convert tabs to spaces, strip blanks at end-of-line, and ensure the last line of the file has an end-of-line character.
-</li>
-</ul>
<h2><a>"Eclipse is not working correctly, what should I do?"</a>
</h2>
<p>Make sure:
diff --git a/tools/monkeyrunner/etc/Android.mk b/pdk/micro-httpd.py
similarity index 66%
rename from tools/monkeyrunner/etc/Android.mk
rename to pdk/micro-httpd.py
index 2d757fd..96e4000 100644
--- a/tools/monkeyrunner/etc/Android.mk
+++ b/pdk/micro-httpd.py
@@ -1,5 +1,4 @@
-#
-# Copyright (C) 2009 The Android Open Source Project
+# Copyright (C) 2010 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,9 +11,9 @@
# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_PREBUILT_EXECUTABLES := monkeyrunner
-include $(BUILD_HOST_PREBUILT)
+import SimpleHTTPServer, SocketServer, os
+PORT = int(os.environ.get('HTTP_PORT', 8080))
+Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
+httpd = SocketServer.TCPServer(("", PORT), Handler)
+httpd.serve_forever()
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index 7adf48d..e88512f 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -524,7 +524,6 @@
<string name="linear_layout_8_right">Right</string>
<string name="linear_layout_10_from">From:</string>
<string name="linear_layout_10_to">To:</string>
- <string name="list_7_nothing">Nothing\u2026</string>
<string name="radio_group_snack">Snack</string>
<string name="radio_group_selection">"You have selected: "</string>
<string name="radio_group_none">(none)</string>
@@ -948,8 +947,8 @@
<!-- ============================ -->
<string name="sms_warning">
- WARNING: this demo can send actual text messages (one at a time), so be sure to
- test with the Android emulator or have a text messaging plan with your carrier.
+ WARNING: this demo can send actual text messages (one at a time), so be sure to
+ test with the Android emulator or have a text messaging plan with your carrier.
</string>
<string name="sms_enable_receiver">Enable SMS broadcast receiver</string>
<string name="sms_recipient_label">Recipient #</string>
@@ -959,4 +958,3 @@
<string name="reply">Reply</string>
<string name="dismiss">Dismiss</string>
</resources>
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java b/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
index 78b1fd7..39f24b6 100644
--- a/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
+++ b/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
@@ -52,8 +52,8 @@
getListView().setTextFilterEnabled(true);
}
- protected List getData(String prefix) {
- List<Map> myData = new ArrayList<Map>();
+ protected List<Map<String, Object>> getData(String prefix) {
+ List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
@@ -107,10 +107,11 @@
return myData;
}
- private final static Comparator<Map> sDisplayNameComparator = new Comparator<Map>() {
+ private final static Comparator<Map<String, Object>> sDisplayNameComparator =
+ new Comparator<Map<String, Object>>() {
private final Collator collator = Collator.getInstance();
- public int compare(Map map1, Map map2) {
+ public int compare(Map<String, Object> map1, Map<String, Object> map2) {
return collator.compare(map1.get("title"), map2.get("title"));
}
};
@@ -128,7 +129,7 @@
return result;
}
- protected void addItem(List<Map> data, String name, Intent intent) {
+ protected void addItem(List<Map<String, Object>> data, String name, Intent intent) {
Map<String, Object> temp = new HashMap<String, Object>();
temp.put("title", name);
temp.put("intent", intent);
@@ -136,11 +137,11 @@
}
@Override
+ @SuppressWarnings("unchecked")
protected void onListItemClick(ListView l, View v, int position, long id) {
- Map map = (Map) l.getItemAtPosition(position);
+ Map<String, Object> map = (Map<String, Object>)l.getItemAtPosition(position);
Intent intent = (Intent) map.get("intent");
startActivity(intent);
}
-
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/Animation.java b/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
index 90831f5..5ba41c4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
@@ -22,7 +22,6 @@
import com.example.android.apis.view.Controls1;
import android.app.Activity;
-import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java
index bb843e5..d5b3deb 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java
@@ -20,8 +20,6 @@
// class is in a sub-package.
import android.app.Activity;
import android.content.ComponentName;
-import android.content.Context;
-import android.os.RemoteException;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
@@ -29,7 +27,6 @@
import com.example.android.apis.R;
-
/**
* Front-end for launching {@link ContactsFilterInstrumentation} example
* instrumentation class.
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java
index 04bb671..6895363 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java
@@ -23,8 +23,6 @@
import android.os.Bundle;
import android.util.Log;
-import java.util.Map;
-
/**
* This is an example implementation of the {@link android.app.Instrumentation}
* class, allowing you to run tests against application code. The
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java b/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
index 35bdf13..494a2ea 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
@@ -19,7 +19,6 @@
import com.example.android.apis.ApiDemosApplication;
import com.example.android.apis.R;
-import android.app.Application;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
index c7a2dfb..7e061ed 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
@@ -49,9 +49,9 @@
static final String ACTION_BACKGROUND = "com.example.android.apis.BACKGROUND";
// BEGIN_INCLUDE(foreground_compatibility)
- private static final Class[] mStartForegroundSignature = new Class[] {
+ private static final Class<?>[] mStartForegroundSignature = new Class[] {
int.class, Notification.class};
- private static final Class[] mStopForegroundSignature = new Class[] {
+ private static final Class<?>[] mStopForegroundSignature = new Class[] {
boolean.class};
private NotificationManager mNM;
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java
index 1bb26e9..0e4b66e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java
@@ -20,8 +20,6 @@
// class is in a sub-package.
import android.app.Activity;
import android.content.ComponentName;
-import android.content.Context;
-import android.os.RemoteException;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
@@ -29,7 +27,6 @@
import com.example.android.apis.R;
-
/**
* Front-end for launching {@link LocalSampleInstrumentation} example
* instrumentation class.
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java
index e0f6163..aabfec3 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java
@@ -23,8 +23,6 @@
import android.os.Bundle;
import android.util.Log;
-import java.util.Map;
-
/**
* This is an example implementation of the {@link android.app.Instrumentation}
* class demonstrating instrumentation against one of this application's sample
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
index 859969c..0c7c108 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
@@ -45,6 +45,10 @@
public class LocalService extends Service {
private NotificationManager mNM;
+ // Unique Identification Number for the Notification.
+ // We use it on Notification start, and to cancel it.
+ private int NOTIFICATION = R.string.local_service_started;
+
/**
* Class for clients to access. Because we know this service always
* runs in the same process as its clients, we don't need to deal with
@@ -75,7 +79,7 @@
@Override
public void onDestroy() {
// Cancel the persistent notification.
- mNM.cancel(R.string.local_service_started);
+ mNM.cancel(NOTIFICATION);
// Tell the user we stopped.
Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
@@ -110,8 +114,7 @@
text, contentIntent);
// Send the notification.
- // We use a layout id because it is a unique number. We use it later to cancel.
- mNM.notify(R.string.local_service_started, notification);
+ mNM.notify(NOTIFICATION, notification);
}
}
//END_INCLUDE(service)
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java b/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java
index a6c20ea..25b5d56 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java
@@ -24,14 +24,11 @@
import android.app.NotificationManager;
import android.content.Intent;
import android.os.Bundle;
-import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
-import android.widget.LinearLayout;
import android.widget.RelativeLayout;
-
/**
* Activity used by StatusBarNotification to show the notification to the user.
*/
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java
index a0de699..b8b4e3f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java
@@ -21,14 +21,12 @@
import com.example.android.apis.R;
import android.app.Activity;
-import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
-
/**
* Controller to start and stop a service. The serivce will update a status bar
* notification every 5 seconds for a minute.
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
index e580978..3b8139f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
@@ -30,7 +30,6 @@
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
-import android.widget.RemoteViews;
/**
* This is an example of service that will update its status bar balloon
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java b/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
index 23461c6..63bbac2 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
@@ -18,9 +18,7 @@
import com.example.android.apis.R;
-import android.content.SharedPreferences;
import android.os.Bundle;
-import android.preference.Preference;
import android.preference.PreferenceActivity;
public class PreferencesFromXml extends PreferenceActivity {
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/QuickContactsDemo.java b/samples/ApiDemos/src/com/example/android/apis/app/QuickContactsDemo.java
index 1ee5742..004e568 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/QuickContactsDemo.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/QuickContactsDemo.java
@@ -75,8 +75,6 @@
@Override
public void bindView(View view, Context context, Cursor cursor) {
final ContactListItemCache cache = (ContactListItemCache) view.getTag();
- TextView nameView = cache.nameView;
- QuickContactBadge photoView = cache.photoView;
// Set the name
cursor.copyStringToBuffer(SUMMARY_NAME_COLUMN_INDEX, cache.nameBuffer);
int size = cache.nameBuffer.sizeCopied;
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java b/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java
index 4e248b9..22ae7f4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java
@@ -18,8 +18,6 @@
// Need the following import to get access to the app resources, since this
// class is in a sub-package.
-import java.util.Map;
-
import com.example.android.apis.R;
import android.app.Activity;
@@ -31,8 +29,6 @@
import android.widget.Button;
import android.widget.TextView;
-import java.util.Map;
-
/**
* Shows how an activity can send data to its launching activity when done.y.
* <p>This can be used, for example, to implement a dialog alowing the user to
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java b/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java
index 982317c..c96e1bb 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java
@@ -32,8 +32,11 @@
*/
public class RedirectGetter extends Activity
{
+ private String mTextPref;
+ private TextView mText;
+
@Override
- protected void onCreate(Bundle savedInstanceState)
+ protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
@@ -45,9 +48,12 @@
// The text being set.
mText = (TextView)findViewById(R.id.text);
+
+ // Display the stored values, or if not stored initialize with an empty String
+ loadPrefs();
}
- private final boolean loadPrefs()
+ private final void loadPrefs()
{
// Retrieve the current redirect values.
// NOTE: because this preference is shared between multiple
@@ -58,10 +64,9 @@
mTextPref = preferences.getString("text", null);
if (mTextPref != null) {
mText.setText(mTextPref);
- return true;
+ } else {
+ mText.setText("");
}
-
- return false;
}
private OnClickListener mApplyListener = new OnClickListener()
@@ -79,8 +84,4 @@
finish();
}
};
-
- private String mTextPref;
- TextView mText;
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/SetWallpaperActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/SetWallpaperActivity.java
index 8630b1c..f3d4ffb 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/SetWallpaperActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/SetWallpaperActivity.java
@@ -29,7 +29,6 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
-import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/WallpaperActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/WallpaperActivity.java
index 8d7f5a1..7b5eea2 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/WallpaperActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/WallpaperActivity.java
@@ -22,7 +22,6 @@
import android.app.Activity;
import android.os.Bundle;
-import android.view.WindowManager;
/**
* <h3>Wallpaper Activity</h3>
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java b/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java
index 8fff231..90d3450 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java
@@ -18,15 +18,12 @@
import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
import java.io.InputStream;
-import java.io.ByteArrayOutputStream;
public class AlphaBitmap extends GraphicsActivity {
@@ -35,23 +32,23 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Bitmap mBitmap;
private Bitmap mBitmap2;
private Bitmap mBitmap3;
private Shader mShader;
-
+
private static void drawIntoBitmap(Bitmap bm) {
float x = bm.getWidth();
float y = bm.getHeight();
Canvas c = new Canvas(bm);
Paint p = new Paint();
p.setAntiAlias(true);
-
+
p.setAlpha(0x80);
c.drawCircle(x/2, y/2, x/2, p);
-
+
p.setAlpha(0x30);
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
p.setTextSize(60);
@@ -59,28 +56,28 @@
Paint.FontMetrics fm = p.getFontMetrics();
c.drawText("Alpha", x/2, (y-fm.ascent)/2, p);
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
InputStream is = context.getResources().openRawResource(R.drawable.app_sample_code);
mBitmap = BitmapFactory.decodeStream(is);
mBitmap2 = mBitmap.extractAlpha();
mBitmap3 = Bitmap.createBitmap(200, 200, Bitmap.Config.ALPHA_8);
drawIntoBitmap(mBitmap3);
-
+
mShader = new LinearGradient(0, 0, 100, 70, new int[] {
Color.RED, Color.GREEN, Color.BLUE },
null, Shader.TileMode.MIRROR);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
Paint p = new Paint();
float y = 10;
-
+
p.setColor(Color.RED);
canvas.drawBitmap(mBitmap, 10, y, p);
y += mBitmap.getHeight() + 10;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java
index 279b588..330924e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java
@@ -23,23 +23,23 @@
import android.view.animation.Transformation;
public class AnimateDrawable extends ProxyDrawable {
-
+
private Animation mAnimation;
private Transformation mTransformation = new Transformation();
public AnimateDrawable(Drawable target) {
super(target);
}
-
+
public AnimateDrawable(Drawable target, Animation animation) {
super(target);
mAnimation = animation;
}
-
+
public Animation getAnimation() {
return mAnimation;
}
-
+
public void setAnimation(Animation anim) {
mAnimation = anim;
}
@@ -47,11 +47,11 @@
public boolean hasStarted() {
return mAnimation != null && mAnimation.hasStarted();
}
-
+
public boolean hasEnded() {
return mAnimation == null || mAnimation.hasEnded();
}
-
+
@Override
public void draw(Canvas canvas) {
Drawable dr = getProxy();
@@ -69,4 +69,4 @@
}
}
}
-
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java
index 7c9473d..0398fbf 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java
@@ -18,14 +18,14 @@
import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
-import android.graphics.*;
-import android.graphics.drawable.*;
-import android.view.animation.*;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
public class AnimateDrawables extends GraphicsActivity {
@@ -34,7 +34,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private AnimateDrawable mDrawable;
@@ -45,17 +45,18 @@
Drawable dr = context.getResources().getDrawable(R.drawable.beach);
dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
-
+
Animation an = new TranslateAnimation(0, 100, 0, 200);
an.setDuration(2000);
an.setRepeatCount(-1);
an.initialize(10, 10, 10, 10);
-
+
mDrawable = new AnimateDrawable(dr, an);
an.startNow();
}
-
- @Override protected void onDraw(Canvas canvas) {
+
+ @Override
+ protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
mDrawable.draw(canvas);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java
index ff8b38b..1bd07f9 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java
@@ -20,7 +20,6 @@
// class is in a sub-package.
//import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -33,7 +32,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint[] mPaints;
private Paint mFramePaint;
@@ -43,27 +42,27 @@
private float mStart;
private float mSweep;
private int mBigIndex;
-
+
private static final float SWEEP_INC = 2;
private static final float START_INC = 15;
-
+
public SampleView(Context context) {
super(context);
-
+
mPaints = new Paint[4];
mUseCenters = new boolean[4];
mOvals = new RectF[4];
-
+
mPaints[0] = new Paint();
mPaints[0].setAntiAlias(true);
mPaints[0].setStyle(Paint.Style.FILL);
mPaints[0].setColor(0x88FF0000);
mUseCenters[0] = false;
-
+
mPaints[1] = new Paint(mPaints[0]);
mPaints[1].setColor(0x8800FF00);
mUseCenters[1] = true;
-
+
mPaints[2] = new Paint(mPaints[0]);
mPaints[2].setStyle(Paint.Style.STROKE);
mPaints[2].setStrokeWidth(4);
@@ -73,36 +72,36 @@
mPaints[3] = new Paint(mPaints[2]);
mPaints[3].setColor(0x88888888);
mUseCenters[3] = true;
-
+
mBigOval = new RectF(40, 10, 280, 250);
-
+
mOvals[0] = new RectF( 10, 270, 70, 330);
mOvals[1] = new RectF( 90, 270, 150, 330);
mOvals[2] = new RectF(170, 270, 230, 330);
mOvals[3] = new RectF(250, 270, 310, 330);
-
+
mFramePaint = new Paint();
mFramePaint.setAntiAlias(true);
mFramePaint.setStyle(Paint.Style.STROKE);
mFramePaint.setStrokeWidth(0);
}
-
+
private void drawArcs(Canvas canvas, RectF oval, boolean useCenter,
Paint paint) {
canvas.drawRect(oval, mFramePaint);
canvas.drawArc(oval, mStart, mSweep, useCenter, paint);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
-
+
drawArcs(canvas, mBigOval, mUseCenters[mBigIndex],
mPaints[mBigIndex]);
-
+
for (int i = 0; i < 4; i++) {
drawArcs(canvas, mOvals[i], mUseCenters[i], mPaints[i]);
}
-
+
mSweep += SWEEP_INC;
if (mSweep > 360) {
mSweep -= 360;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java
index 88f0c1d..6a8b542 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java
@@ -18,36 +18,36 @@
import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
-import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
public class BitmapDecode extends GraphicsActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Bitmap mBitmap;
private Bitmap mBitmap2;
private Bitmap mBitmap3;
private Bitmap mBitmap4;
private Drawable mDrawable;
-
+
private Movie mMovie;
private long mMovieStart;
-
+
+ //Set to false to use decodeByteArray
+ private static final boolean DECODE_STREAM = true;
+
private static byte[] streamToBytes(InputStream is) {
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
@@ -60,33 +60,33 @@
}
return os.toByteArray();
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
java.io.InputStream is;
is = context.getResources().openRawResource(R.drawable.beach);
-
+
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm;
-
+
opts.inJustDecodeBounds = true;
bm = BitmapFactory.decodeStream(is, null, opts);
-
+
// now opts.outWidth and opts.outHeight are the dimension of the
// bitmap, even though bm is null
-
+
opts.inJustDecodeBounds = false; // this will request the bm
opts.inSampleSize = 4; // scaled down by 4
bm = BitmapFactory.decodeStream(is, null, opts);
-
+
mBitmap = bm;
-
+
// decode an image with transparency
is = context.getResources().openRawResource(R.drawable.frog);
mBitmap2 = BitmapFactory.decodeStream(is);
-
+
// create a deep copy of it using getPixels() into different configs
int w = mBitmap2.getWidth();
int h = mBitmap2.getHeight();
@@ -96,32 +96,34 @@
Bitmap.Config.ARGB_8888);
mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
Bitmap.Config.ARGB_4444);
-
+
mDrawable = context.getResources().getDrawable(R.drawable.button);
mDrawable.setBounds(150, 20, 300, 100);
-
+
is = context.getResources().openRawResource(R.drawable.animated_gif);
- if (true) {
+
+ if (DECODE_STREAM) {
mMovie = Movie.decodeStream(is);
} else {
byte[] array = streamToBytes(is);
mMovie = Movie.decodeByteArray(array, 0, array.length);
}
}
-
- @Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(0xFFCCCCCC);
-
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawColor(0xFFCCCCCC);
+
Paint p = new Paint();
p.setAntiAlias(true);
-
+
canvas.drawBitmap(mBitmap, 10, 10, null);
canvas.drawBitmap(mBitmap2, 10, 170, null);
canvas.drawBitmap(mBitmap3, 110, 170, null);
canvas.drawBitmap(mBitmap4, 210, 170, null);
-
+
mDrawable.draw(canvas);
-
+
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
@@ -140,4 +142,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java
index 4d48a1e..12c79ca 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java
@@ -31,16 +31,16 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private static final int WIDTH = 20;
private static final int HEIGHT = 20;
private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1);
-
+
private final Bitmap mBitmap;
private final float[] mVerts = new float[COUNT*2];
private final float[] mOrig = new float[COUNT*2];
-
+
private final Matrix mMatrix = new Matrix();
private final Matrix mInverse = new Matrix();
@@ -55,7 +55,7 @@
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.beach);
-
+
float w = mBitmap.getWidth();
float h = mBitmap.getHeight();
// construct our mesh
@@ -63,17 +63,17 @@
for (int y = 0; y <= HEIGHT; y++) {
float fy = h * y / HEIGHT;
for (int x = 0; x <= WIDTH; x++) {
- float fx = w * x / WIDTH;
+ float fx = w * x / WIDTH;
setXY(mVerts, index, fx, fy);
setXY(mOrig, index, fx, fy);
index += 1;
}
}
-
+
mMatrix.setTranslate(10, 10);
mMatrix.invert(mInverse);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFCCCCCC);
@@ -81,7 +81,7 @@
canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0,
null, 0, null);
}
-
+
private void warp(float cx, float cy) {
final float K = 10000;
float[] src = mOrig;
@@ -94,7 +94,7 @@
float dd = dx*dx + dy*dy;
float d = FloatMath.sqrt(dd);
float pull = K / (dd + 0.000001f);
-
+
pull /= (d + 0.000001f);
// android.util.Log.d("skia", "index " + i + " dist=" + d + " pull=" + pull);
@@ -114,7 +114,7 @@
@Override public boolean onTouchEvent(MotionEvent event) {
float[] pt = { event.getX(), event.getY() };
mInverse.mapPoints(pt);
-
+
int x = (int)pt[0];
int y = (int)pt[1];
if (mLastWarpX != x || mLastWarpY != y) {
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java
index 88717bc..e9b2167 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java
@@ -16,32 +16,26 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
-import android.graphics.drawable.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
public class BitmapPixels extends GraphicsActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Bitmap mBitmap1;
private Bitmap mBitmap2;
private Bitmap mBitmap3;
- private Bitmap mBitmap4;
// access the red component from a premultiplied color
private static int getR32(int c) { return (c >> 0) & 0xFF; }
@@ -67,7 +61,7 @@
private static short pack4444(int r, int g, int b, int a) {
return (short)((a << 0) | ( b << 4) | (g << 8) | (r << 12));
}
-
+
private static int mul255(int c, int a) {
int prod = c * a + 128;
return (prod + (prod >> 8)) >> 8;
@@ -88,7 +82,7 @@
// now pack it in the correct order
return pack8888(r, g, b, a);
}
-
+
private static void makeRamp(int from, int to, int n,
int[] ramp8888, short[] ramp565,
short[] ramp4444) {
@@ -113,7 +107,7 @@
a += da;
}
}
-
+
private static IntBuffer makeBuffer(int[] src, int n) {
IntBuffer dst = IntBuffer.allocate(n*n);
for (int i = 0; i < n; i++) {
@@ -122,7 +116,7 @@
dst.rewind();
return dst;
}
-
+
private static ShortBuffer makeBuffer(short[] src, int n) {
ShortBuffer dst = ShortBuffer.allocate(n*n);
for (int i = 0; i < n; i++) {
@@ -131,31 +125,31 @@
dst.rewind();
return dst;
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
final int N = 100;
int[] data8888 = new int[N];
short[] data565 = new short[N];
short[] data4444 = new short[N];
-
+
makeRamp(premultiplyColor(Color.RED), premultiplyColor(Color.GREEN),
N, data8888, data565, data4444);
-
+
mBitmap1 = Bitmap.createBitmap(N, N, Bitmap.Config.ARGB_8888);
mBitmap2 = Bitmap.createBitmap(N, N, Bitmap.Config.RGB_565);
mBitmap3 = Bitmap.createBitmap(N, N, Bitmap.Config.ARGB_4444);
-
+
mBitmap1.copyPixelsFromBuffer(makeBuffer(data8888, N));
mBitmap2.copyPixelsFromBuffer(makeBuffer(data565, N));
mBitmap3.copyPixelsFromBuffer(makeBuffer(data4444, N));
}
-
+
@Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(0xFFCCCCCC);
-
+ canvas.drawColor(0xFFCCCCCC);
+
int y = 10;
canvas.drawBitmap(mBitmap1, 10, y, null);
y += mBitmap1.getHeight() + 10;
@@ -165,4 +159,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java
index cf83597..42f8be3 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,7 +28,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint;
private Path mPath;
@@ -37,46 +36,46 @@
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(6);
mPaint.setTextSize(16);
mPaint.setTextAlign(Paint.Align.RIGHT);
-
+
mPath = new Path();
}
-
+
private void drawScene(Canvas canvas) {
canvas.clipRect(0, 0, 100, 100);
-
+
canvas.drawColor(Color.WHITE);
-
+
mPaint.setColor(Color.RED);
canvas.drawLine(0, 0, 100, 100, mPaint);
-
+
mPaint.setColor(Color.GREEN);
canvas.drawCircle(30, 70, 30, mPaint);
-
+
mPaint.setColor(Color.BLUE);
canvas.drawText("Clipping", 100, 30, mPaint);
}
-
+
@Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(Color.GRAY);
+ canvas.drawColor(Color.GRAY);
canvas.save();
canvas.translate(10, 10);
drawScene(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 10);
canvas.clipRect(10, 10, 90, 90);
canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE);
drawScene(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(10, 160);
mPath.reset();
@@ -85,21 +84,21 @@
canvas.clipPath(mPath, Region.Op.REPLACE);
drawScene(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 160);
canvas.clipRect(0, 0, 60, 60);
canvas.clipRect(40, 40, 100, 100, Region.Op.UNION);
drawScene(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(10, 310);
canvas.clipRect(0, 0, 60, 60);
canvas.clipRect(40, 40, 100, 100, Region.Op.XOR);
drawScene(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 310);
canvas.clipRect(0, 0, 60, 60);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorFilters.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorFilters.java
index 92d18ba..8eb60b5 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorFilters.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorFilters.java
@@ -23,18 +23,17 @@
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
public class ColorFilters extends GraphicsActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
-
+
}
-
+
private static class SampleView extends View {
private Activity mActivity;
private Drawable mDrawable;
@@ -52,7 +51,7 @@
int center = (r.top + r.bottom) >> 1;
int h = curr.getIntrinsicHeight();
int y = center - (h >> 1);
-
+
curr.setBounds(x, y, x + curr.getIntrinsicWidth(), y + h);
}
@@ -61,7 +60,7 @@
mActivity = activity;
Context context = activity;
setFocusable(true);
-
+
mDrawable = context.getResources().getDrawable(R.drawable.btn_default_normal);
mDrawable.setBounds(0, 0, 150, 48);
mDrawable.setDither(true);
@@ -84,13 +83,13 @@
mPaint.setAntiAlias(true);
mPaint.setTextSize(16);
mPaint.setTextAlign(Paint.Align.CENTER);
-
+
mPaint2 = new Paint(mPaint);
mPaint2.setAlpha(64);
-
+
Paint.FontMetrics fm = mPaint.getFontMetrics();
mPaintTextOffset = (fm.descent + fm.ascent) * 0.5f;
-
+
mColors = new int[] {
0,
0xCC0000FF,
@@ -106,10 +105,10 @@
PorterDuff.Mode.MULTIPLY,
};
mModeIndex = 0;
-
+
updateTitle();
}
-
+
private void swapPaintColors() {
if (mPaint.getColor() == 0xFF000000) {
mPaint.setColor(0xFFFFFFFF);
@@ -120,11 +119,11 @@
}
mPaint2.setAlpha(64);
}
-
+
private void updateTitle() {
mActivity.setTitle(mModes[mModeIndex].toString());
}
-
+
private void drawSample(Canvas canvas, ColorFilter filter) {
Rect r = mDrawable.getBounds();
float x = (r.left + r.right) * 0.5f;
@@ -134,15 +133,15 @@
mDrawable.draw(canvas);
canvas.drawText("Label", x+1, y+1, mPaint2);
canvas.drawText("Label", x, y, mPaint);
-
+
for (Drawable dr : mDrawables) {
dr.setColorFilter(filter);
dr.draw(canvas);
}
}
-
+
@Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(0xFFCCCCCC);
+ canvas.drawColor(0xFFCCCCCC);
canvas.translate(8, 12);
for (int color : mColors) {
@@ -160,8 +159,6 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
- float x = event.getX();
- float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
@@ -181,4 +178,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java
index 19a0f7f..f438e73 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java
@@ -18,35 +18,31 @@
import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.View;
public class ColorMatrixSample extends GraphicsActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- private ColorMatrix mCM = new ColorMatrix();
private Bitmap mBitmap;
- private float mSaturation;
private float mAngle;
-
+
public SampleView(Context context) {
super(context);
-
+
mBitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.balloons);
}
-
+
private static void setTranslate(ColorMatrix cm, float dr, float dg,
float db, float da) {
cm.set(new float[] {
@@ -55,7 +51,7 @@
0, 0, 2, 0, db,
0, 0, 0, 1, da });
}
-
+
private static void setContrast(ColorMatrix cm, float contrast) {
float scale = contrast + 1.f;
float translate = (-.5f * scale + .5f) * 255.f;
@@ -65,7 +61,7 @@
0, 0, scale, 0, translate,
0, 0, 0, 1, 0 });
}
-
+
private static void setContrastTranslateOnly(ColorMatrix cm, float contrast) {
float scale = contrast + 1.f;
float translate = (-.5f * scale + .5f) * 255.f;
@@ -75,7 +71,7 @@
0, 0, 1, 0, translate,
0, 0, 0, 1, 0 });
}
-
+
private static void setContrastScaleOnly(ColorMatrix cm, float contrast) {
float scale = contrast + 1.f;
float translate = (-.5f * scale + .5f) * 255.f;
@@ -85,40 +81,40 @@
0, 0, scale, 0, 0,
0, 0, 0, 1, 0 });
}
-
+
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
float x = 20;
float y = 20;
-
+
canvas.drawColor(Color.WHITE);
-
+
paint.setColorFilter(null);
canvas.drawBitmap(mBitmap, x, y, paint);
-
+
ColorMatrix cm = new ColorMatrix();
-
+
mAngle += 2;
if (mAngle > 180) {
mAngle = 0;
}
-
+
//convert our animated angle [-180...180] to a contrast value of [-1..1]
float contrast = mAngle / 180.f;
-
+
setContrast(cm, contrast);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(mBitmap, x + mBitmap.getWidth() + 10, y, paint);
-
+
setContrastScaleOnly(cm, contrast);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(mBitmap, x, y + mBitmap.getHeight() + 10, paint);
-
+
setContrastTranslateOnly(cm, contrast);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(mBitmap, x, y + 2*(mBitmap.getHeight() + 10),
paint);
-
+
invalidate();
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java
index 7588180..1c7125f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java
@@ -37,7 +37,7 @@
private Paint mCenterPaint;
private final int[] mColors;
private OnColorChangedListener mListener;
-
+
ColorPickerView(Context c, OnColorChangedListener l, int color) {
super(c);
mListener = l;
@@ -46,33 +46,33 @@
0xFFFFFF00, 0xFFFF0000
};
Shader s = new SweepGradient(0, 0, mColors, null);
-
+
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setShader(s);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(32);
-
+
mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCenterPaint.setColor(color);
mCenterPaint.setStrokeWidth(5);
}
-
+
private boolean mTrackingCenter;
private boolean mHighlightCenter;
- @Override
+ @Override
protected void onDraw(Canvas canvas) {
float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;
-
+
canvas.translate(CENTER_X, CENTER_X);
-
- canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
+
+ canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
-
+
if (mTrackingCenter) {
int c = mCenterPaint.getColor();
mCenterPaint.setStyle(Paint.Style.STROKE);
-
+
if (mHighlightCenter) {
mCenterPaint.setAlpha(0xFF);
} else {
@@ -81,17 +81,17 @@
canvas.drawCircle(0, 0,
CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
mCenterPaint);
-
+
mCenterPaint.setStyle(Paint.Style.FILL);
mCenterPaint.setColor(c);
}
}
-
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
}
-
+
private static final int CENTER_X = 100;
private static final int CENTER_Y = 100;
private static final int CENTER_RADIUS = 32;
@@ -108,11 +108,11 @@
}
return n;
}
-
+
private int ave(int s, int d, float p) {
return s + java.lang.Math.round(p * (d - s));
}
-
+
private int interpColor(int colors[], float unit) {
if (unit <= 0) {
return colors[0];
@@ -120,7 +120,7 @@
if (unit >= 1) {
return colors[colors.length - 1];
}
-
+
float p = unit * (colors.length - 1);
int i = (int)p;
p -= i;
@@ -132,16 +132,16 @@
int r = ave(Color.red(c0), Color.red(c1), p);
int g = ave(Color.green(c0), Color.green(c1), p);
int b = ave(Color.blue(c0), Color.blue(c1), p);
-
+
return Color.argb(a, r, g, b);
}
-
+
private int rotateColor(int color, float rad) {
float deg = rad * 180 / 3.1415927f;
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
-
+
ColorMatrix cm = new ColorMatrix();
ColorMatrix tmp = new ColorMatrix();
@@ -150,17 +150,17 @@
cm.postConcat(tmp);
tmp.setYUV2RGB();
cm.postConcat(tmp);
-
+
final float[] a = cm.getArray();
int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);
int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);
int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);
-
+
return Color.argb(Color.alpha(color), pinToByte(ir),
pinToByte(ig), pinToByte(ib));
}
-
+
private static final float PI = 3.1415926f;
@Override
@@ -168,7 +168,7 @@
float x = event.getX() - CENTER_X;
float y = event.getY() - CENTER_Y;
boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;
-
+
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mTrackingCenter = inCenter;
@@ -212,7 +212,7 @@
OnColorChangedListener listener,
int initialColor) {
super(context);
-
+
mListener = listener;
mInitialColor = initialColor;
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java
index d3b0981..85471d9 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java
@@ -35,10 +35,10 @@
private Sensor mSensor;
private SampleView mView;
private float[] mValues;
-
+
private final SensorEventListener mListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent event) {
- if (Config.LOGD) Log.d(TAG,
+ if (Config.DEBUG) Log.d(TAG,
"sensorChanged (" + event.values[0] + ", " + event.values[1] + ", " + event.values[2] + ")");
mValues = event.values;
if (mView != null) {
@@ -62,17 +62,17 @@
@Override
protected void onResume()
{
- if (Config.LOGD) Log.d(TAG, "onResume");
+ if (Config.DEBUG) Log.d(TAG, "onResume");
super.onResume();
mSensorManager.registerListener(mListener, mSensor,
SensorManager.SENSOR_DELAY_GAME);
}
-
+
@Override
protected void onStop()
{
- if (Config.LOGD) Log.d(TAG, "onStop");
+ if (Config.DEBUG) Log.d(TAG, "onStop");
mSensorManager.unregisterListener(mListener);
super.onStop();
}
@@ -81,7 +81,6 @@
private Paint mPaint = new Paint();
private Path mPath = new Path();
private boolean mAnimate;
- private long mNextTime;
public SampleView(Context context) {
super(context);
@@ -93,12 +92,12 @@
mPath.lineTo(20, 60);
mPath.close();
}
-
+
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
canvas.drawColor(Color.WHITE);
-
+
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
@@ -109,23 +108,24 @@
int cy = h / 2;
canvas.translate(cx, cy);
- if (mValues != null) {
+ if (mValues != null) {
canvas.rotate(-mValues[0]);
}
canvas.drawPath(mPath, mPaint);
}
-
+
@Override
protected void onAttachedToWindow() {
mAnimate = true;
+ if (Config.DEBUG) Log.d(TAG, "onAttachedToWindow. mAnimate=" + mAnimate);
super.onAttachedToWindow();
}
-
+
@Override
protected void onDetachedFromWindow() {
mAnimate = false;
+ if (Config.DEBUG) Log.d(TAG, "onDetachedFromWindow. mAnimate=" + mAnimate);
super.onDetachedFromWindow();
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java b/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java
index e3e5d9a..61fe9d5 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java
@@ -16,13 +16,9 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
import java.io.ByteArrayOutputStream;
@@ -34,11 +30,11 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static final int WIDTH = 50;
private static final int HEIGHT = 50;
private static final int STRIDE = 64; // must be >= WIDTH
-
+
private static int[] createColors() {
int[] colors = new int[STRIDE * HEIGHT];
for (int y = 0; y < HEIGHT; y++) {
@@ -52,18 +48,18 @@
}
return colors;
}
-
+
private static class SampleView extends View {
private Bitmap[] mBitmaps;
private Bitmap[] mJPEG;
private Bitmap[] mPNG;
private int[] mColors;
private Paint mPaint;
-
+
private static Bitmap codec(Bitmap src, Bitmap.CompressFormat format,
int quality) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
- src.compress(format, quality, os);
+ src.compress(format, quality, os);
byte[] array = os.toByteArray();
return BitmapFactory.decodeByteArray(array, 0, array.length);
@@ -72,7 +68,7 @@
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mColors = createColors();
int[] colors = mColors;
@@ -84,7 +80,7 @@
Bitmap.Config.RGB_565);
mBitmaps[2] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
Bitmap.Config.ARGB_4444);
-
+
// these three will have their colors set later
mBitmaps[3] = Bitmap.createBitmap(WIDTH, HEIGHT,
Bitmap.Config.ARGB_8888);
@@ -95,10 +91,10 @@
for (int i = 3; i <= 5; i++) {
mBitmaps[i].setPixels(colors, 0, STRIDE, 0, 0, WIDTH, HEIGHT);
}
-
+
mPaint = new Paint();
mPaint.setDither(true);
-
+
// now encode/decode using JPEG and PNG
mJPEG = new Bitmap[mBitmaps.length];
mPNG = new Bitmap[mBitmaps.length];
@@ -107,7 +103,7 @@
mPNG[i] = codec(mBitmaps[i], Bitmap.CompressFormat.PNG, 0);
}
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
@@ -117,7 +113,7 @@
canvas.drawBitmap(mPNG[i], 160, 0, null);
canvas.translate(0, mBitmaps[i].getHeight());
}
-
+
// draw the color array directly, w/o craeting a bitmap object
canvas.drawBitmap(mColors, 0, STRIDE, 0, 0, WIDTH, HEIGHT,
true, null);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java
index bb154eb..715e175 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java
@@ -88,10 +88,10 @@
public void draw(GL10 gl)
{
- gl.glFrontFace(gl.GL_CW);
- gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
- gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
- gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
+ gl.glFrontFace(GL10.GL_CW);
+ gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
+ gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
+ gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
}
private IntBuffer mVertexBuffer;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java
index 0f15f91..ac0ae27 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.java
index 8c5c93a..0288ad1 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.java
@@ -47,7 +47,7 @@
final LayoutInflater li = (LayoutInflater)getSystemService(
LAYOUT_INFLATER_SERVICE);
-
+
this.setTitle(R.string.density_title);
LinearLayout root = new LinearLayout(this);
root.setOrientation(LinearLayout.VERTICAL);
@@ -76,11 +76,11 @@
layout = (LinearLayout)li.inflate(R.layout.density_image_views, null);
addLabelToRoot(root, "Inflated layout");
addChildToRoot(root, layout);
-
+
layout = (LinearLayout)li.inflate(R.layout.density_styled_image_views, null);
addLabelToRoot(root, "Inflated styled layout");
addChildToRoot(root, layout);
-
+
layout = new LinearLayout(this);
addCanvasBitmap(layout, R.drawable.logo120dpi, true);
addCanvasBitmap(layout, R.drawable.logo160dpi, true);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java b/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java
index cbe6373..21eba0d 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,7 +28,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint();
private float[] mPts;
@@ -38,11 +37,11 @@
private static final int SEGS = 32;
private static final int X = 0;
private static final int Y = 1;
-
+
private void buildPoints() {
final int ptCount = (SEGS + 1) * 2;
mPts = new float[ptCount * 2];
-
+
float value = 0;
final float delta = SIZE / SEGS;
for (int i = 0; i <= SEGS; i++) {
@@ -53,16 +52,16 @@
value += delta;
}
}
-
+
public SampleView(Context context) {
super(context);
-
+
buildPoints();
}
-
+
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
-
+
canvas.translate(10, 10);
canvas.drawColor(Color.WHITE);
@@ -70,7 +69,7 @@
paint.setColor(Color.RED);
paint.setStrokeWidth(0);
canvas.drawLines(mPts, paint);
-
+
paint.setColor(Color.BLUE);
paint.setStrokeWidth(3);
canvas.drawPoints(mPts, paint);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java b/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
index 867da4c..fcfd28f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -26,7 +25,7 @@
import android.view.View;
public class FingerPaint extends GraphicsActivity
- implements ColorPickerDialog.OnColorChangedListener {
+ implements ColorPickerDialog.OnColorChangedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -41,34 +40,34 @@
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
-
+
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}
-
+
private Paint mPaint;
private MaskFilter mEmboss;
private MaskFilter mBlur;
-
+
public void colorChanged(int color) {
mPaint.setColor(color);
}
public class MyView extends View {
-
+
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
-
+
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
-
+
public MyView(Context c) {
super(c);
-
+
mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
@@ -79,19 +78,19 @@
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
-
+
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFAAAAAA);
-
+
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
-
+
canvas.drawPath(mPath, mPaint);
}
-
+
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
-
+
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
@@ -114,12 +113,12 @@
// kill this so we don't double draw
mPath.reset();
}
-
+
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
-
+
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
@@ -137,7 +136,7 @@
return true;
}
}
-
+
private static final int COLOR_MENU_ID = Menu.FIRST;
private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
private static final int BLUR_MENU_ID = Menu.FIRST + 2;
@@ -147,7 +146,7 @@
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
-
+
menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
@@ -164,13 +163,13 @@
*****/
return true;
}
-
+
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return true;
}
-
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
mPaint.setXfermode(null);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java b/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java
index eb6d47d..fa7a6b7 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java
@@ -20,7 +20,6 @@
// class is in a sub-package.
import com.example.android.apis.R;
-import android.app.Activity;
import android.os.Bundle;
public class GradientDrawable1 extends GraphicsActivity {
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java
index 023c0d7..69682d4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java
@@ -20,9 +20,11 @@
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.Window;
class GraphicsActivity extends Activity {
+ // set to true to test Picture
+ private static final boolean TEST_PICTURE = false;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -30,13 +32,12 @@
@Override
public void setContentView(View view) {
- if (false) { // set to true to test Picture
+ if (TEST_PICTURE) {
ViewGroup vg = new PictureLayout(this);
vg.addView(view);
view = vg;
}
-
+
super.setContentView(view);
}
-}
-
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java
index d9f5db0..7e2a694 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,7 +28,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private static final int LAYER_FLAGS = Canvas.MATRIX_SAVE_FLAG |
Canvas.CLIP_SAVE_FLAG |
@@ -42,23 +41,23 @@
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
-
+
@Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(Color.WHITE);
-
+ canvas.drawColor(Color.WHITE);
+
canvas.translate(10, 10);
-
+
canvas.saveLayerAlpha(0, 0, 200, 200, 0x88, LAYER_FLAGS);
-
+
mPaint.setColor(Color.RED);
canvas.drawCircle(75, 75, 75, mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawCircle(125, 125, 75, mPaint);
-
+
canvas.restore();
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java b/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java
index e159efe..c2d433e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java
@@ -16,13 +16,9 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
public class MeasureText extends GraphicsActivity {
@@ -32,11 +28,11 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static final int WIDTH = 50;
private static final int HEIGHT = 50;
private static final int STRIDE = 64; // must be >= WIDTH
-
+
private static int[] createColors() {
int[] colors = new int[STRIDE * HEIGHT];
for (int y = 0; y < HEIGHT; y++) {
@@ -50,16 +46,16 @@
}
return colors;
}
-
+
private static class SampleView extends View {
private Paint mPaint;
private float mOriginX = 10;
private float mOriginY = 80;
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(5);
@@ -68,22 +64,22 @@
mPaint.setTypeface(Typeface.create(Typeface.SERIF,
Typeface.ITALIC));
}
-
+
private void showText(Canvas canvas, String text, Paint.Align align) {
// mPaint.setTextAlign(align);
-
+
Rect bounds = new Rect();
float[] widths = new float[text.length()];
int count = mPaint.getTextWidths(text, 0, text.length(), widths);
float w = mPaint.measureText(text, 0, text.length());
mPaint.getTextBounds(text, 0, text.length(), bounds);
-
+
mPaint.setColor(0xFF88FF88);
canvas.drawRect(bounds, mPaint);
mPaint.setColor(Color.BLACK);
canvas.drawText(text, 0, 0, mPaint);
-
+
float[] pts = new float[2 + count*2];
float x = 0;
float y = 0;
@@ -100,12 +96,12 @@
mPaint.setStrokeWidth(5);
canvas.drawPoints(pts, 0, (count + 1) << 1, mPaint);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
-
+
canvas.translate(mOriginX, mOriginY);
-
+
showText(canvas, "Measure", Paint.Align.LEFT);
canvas.translate(0, 80);
showText(canvas, "wiggy!", Paint.Align.CENTER);
@@ -114,4 +110,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java
index 80ddf38..2894fa9 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -30,7 +29,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint;
private Path mPath;
@@ -41,7 +40,7 @@
private static PathEffect makeDash(float phase) {
return new DashPathEffect(new float[] { 15, 5, 8, 5 }, phase);
}
-
+
private static void makeEffects(PathEffect[] e, float phase) {
e[0] = null; // no effect
e[1] = new CornerPathEffect(10);
@@ -51,7 +50,7 @@
e[4] = new ComposePathEffect(e[2], e[1]);
e[5] = new ComposePathEffect(e[3], e[1]);
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
@@ -60,23 +59,23 @@
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(6);
-
+
mPath = makeFollowPath();
-
+
mEffects = new PathEffect[6];
-
+
mColors = new int[] { Color.BLACK, Color.RED, Color.BLUE,
Color.GREEN, Color.MAGENTA, Color.BLACK
};
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
-
+
RectF bounds = new RectF();
mPath.computeBounds(bounds, false);
canvas.translate(10 - bounds.left, 10 - bounds.top);
-
+
makeEffects(mEffects, mPhase);
mPhase += 1;
invalidate();
@@ -88,7 +87,7 @@
canvas.translate(0, 28);
}
}
-
+
@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
@@ -106,7 +105,7 @@
}
return p;
}
-
+
private static Path makePathDash() {
Path p = new Path();
p.moveTo(4, 0);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java
index 78dba26..10cfc49 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java
@@ -20,11 +20,9 @@
// class is in a sub-package.
//import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.View;
public class PathFillTypes extends GraphicsActivity {
@@ -34,7 +32,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path mPath;
@@ -48,7 +46,7 @@
mPath.addCircle(40, 40, 45, Path.Direction.CCW);
mPath.addCircle(80, 80, 45, Path.Direction.CCW);
}
-
+
private void showPath(Canvas canvas, int x, int y, Path.FillType ft,
Paint paint) {
canvas.save();
@@ -59,14 +57,14 @@
canvas.drawPath(mPath, paint);
canvas.restore();
}
-
+
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
canvas.drawColor(0xFFCCCCCC);
-
+
canvas.translate(20, 20);
-
+
paint.setAntiAlias(true);
showPath(canvas, 0, 0, Path.FillType.WINDING, paint);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java
index d2a51ff..6b6d8e1 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java
@@ -16,11 +16,9 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.*;
@@ -31,7 +29,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static Bitmap makeBitmap1() {
Bitmap bm = Bitmap.createBitmap(40, 40, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bm);
@@ -41,7 +39,7 @@
c.drawRect(5, 5, 35, 35, p);
return bm;
}
-
+
private static Bitmap makeBitmap2() {
Bitmap bm = Bitmap.createBitmap(64, 64, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
@@ -51,13 +49,13 @@
c.drawCircle(32, 32, 27, p);
return bm;
}
-
+
private static class SampleView extends View {
private final Shader mShader1;
private final Shader mShader2;
private final Paint mPaint;
private final DrawFilter mFastDF;
-
+
private float mTouchStartX;
private float mTouchStartY;
private float mTouchCurrX;
@@ -72,25 +70,25 @@
mFastDF = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG |
Paint.DITHER_FLAG,
0);
-
+
mShader1 = new BitmapShader(makeBitmap1(), Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
mShader2 = new BitmapShader(makeBitmap2(), Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
-
+
Matrix m = new Matrix();
m.setRotate(30);
mShader2.setLocalMatrix(m);
-
+
mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.setDrawFilter(mDF);
mPaint.setShader(mShader1);
canvas.drawPaint(mPaint);
-
+
canvas.translate(mTouchCurrX - mTouchStartX,
mTouchCurrY - mTouchStartY);
@@ -102,7 +100,7 @@
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
-
+
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mTouchStartX = mTouchCurrX = x;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java
index cfa3c29..c1d22a8 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java
@@ -26,7 +26,6 @@
import android.view.ViewGroup;
import android.view.ViewParent;
-
public class PictureLayout extends ViewGroup {
private final Picture mPicture = new Picture();
@@ -36,7 +35,7 @@
public PictureLayout(Context context, AttributeSet attrs) {
super(context, attrs);
- }
+ }
@Override
public void addView(View child) {
@@ -105,7 +104,7 @@
setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
resolveSize(maxHeight, heightMeasureSpec));
}
-
+
private void drawPict(Canvas canvas, int x, int y, int w, int h,
float sx, float sy) {
canvas.save();
@@ -121,10 +120,10 @@
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
mPicture.endRecording();
-
+
int x = getWidth()/2;
int y = getHeight()/2;
-
+
if (false) {
canvas.drawPicture(mPicture);
} else {
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java
index 1bd0a8c..61842dd 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java
@@ -16,13 +16,11 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PictureDrawable;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.View;
import java.io.*;
@@ -34,17 +32,17 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Picture mPicture;
private Drawable mDrawable;
static void drawSomething(Canvas canvas) {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-
+
p.setColor(0x88FF0000);
canvas.drawCircle(50, 50, 40, p);
-
+
p.setColor(Color.GREEN);
p.setTextSize(30);
canvas.drawText("Pictures", 60, 60, p);
@@ -58,20 +56,20 @@
mPicture = new Picture();
drawSomething(mPicture.beginRecording(200, 100));
mPicture.endRecording();
-
+
mDrawable = new PictureDrawable(mPicture);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.drawPicture(mPicture);
-
+
canvas.drawPicture(mPicture, new RectF(0, 100, getWidth(), 200));
-
+
mDrawable.setBounds(0, 200, getWidth(), 300);
mDrawable.draw(canvas);
-
+
ByteArrayOutputStream os = new ByteArrayOutputStream();
mPicture.writeToStream(os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java
index 15d92de..a1f1ed4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java
@@ -20,7 +20,6 @@
// class is in a sub-package.
//import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -33,7 +32,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Matrix mMatrix = new Matrix();
@@ -43,13 +42,13 @@
canvas.save();
mMatrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
canvas.concat(mMatrix);
-
+
mPaint.setColor(Color.GRAY);
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawRect(0, 0, 64, 64, mPaint);
canvas.drawLine(0, 0, 64, 64, mPaint);
canvas.drawLine(0, 64, 64, 0, mPaint);
-
+
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL);
// how to draw the text center on our square
@@ -58,7 +57,7 @@
// centering in Y, we need to measure ascent/descent first
float y = 64/2 - (mFontMetrics.ascent + mFontMetrics.descent)/2;
canvas.drawText(src.length/2 + "", x, y, mPaint);
-
+
canvas.restore();
}
@@ -72,10 +71,9 @@
mPaint.setTextAlign(Paint.Align.CENTER);
mFontMetrics = mPaint.getFontMetrics();
}
-
- @Override protected void onDraw(Canvas canvas) {
- Paint paint = mPaint;
+ @Override
+ protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.save();
@@ -83,7 +81,7 @@
// translate (1 point)
doDraw(canvas, new float[] { 0, 0 }, new float[] { 5, 5 });
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 10);
// rotate/uniform-scale (2 points)
@@ -107,4 +105,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java
index d264134..635132e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java
@@ -22,18 +22,18 @@
import android.graphics.drawable.Drawable;
public class ProxyDrawable extends Drawable {
-
+
private Drawable mProxy;
private boolean mMutated;
public ProxyDrawable(Drawable target) {
mProxy = target;
}
-
+
public Drawable getProxy() {
return mProxy;
}
-
+
public void setProxy(Drawable proxy) {
if (proxy != this) {
mProxy = proxy;
@@ -46,43 +46,43 @@
mProxy.draw(canvas);
}
}
-
+
@Override
public int getIntrinsicWidth() {
return mProxy != null ? mProxy.getIntrinsicWidth() : -1;
}
-
+
@Override
public int getIntrinsicHeight() {
return mProxy != null ? mProxy.getIntrinsicHeight() : -1;
}
-
+
@Override
public int getOpacity() {
return mProxy != null ? mProxy.getOpacity() : PixelFormat.TRANSPARENT;
}
-
+
@Override
public void setFilterBitmap(boolean filter) {
if (mProxy != null) {
mProxy.setFilterBitmap(filter);
}
}
-
+
@Override
public void setDither(boolean dither) {
if (mProxy != null) {
mProxy.setDither(dither);
}
}
-
+
@Override
public void setColorFilter(ColorFilter colorFilter) {
if (mProxy != null) {
mProxy.setColorFilter(colorFilter);
}
}
-
+
@Override
public void setAlpha(int alpha) {
if (mProxy != null) {
@@ -99,4 +99,4 @@
return this;
}
}
-
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java
index 833274b..fc0aa08 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,7 +28,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private final Paint mPaint = new Paint();
private final Rect mRect1 = new Rect();
@@ -38,11 +37,11 @@
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mPaint.setAntiAlias(true);
mPaint.setTextSize(16);
mPaint.setTextAlign(Paint.Align.CENTER);
-
+
mRect1.set(10, 10, 100, 80);
mRect2.set(50, 50, 130, 110);
}
@@ -55,25 +54,25 @@
mPaint.setColor(Color.BLUE);
mPaint.setAlpha(alpha);
drawCentered(canvas, mRect2, mPaint);
-
+
// restore style
mPaint.setStyle(Paint.Style.FILL);
}
-
+
private void drawRgn(Canvas canvas, int color, String str, Region.Op op) {
if (str != null) {
mPaint.setColor(Color.BLACK);
canvas.drawText(str, 80, 24, mPaint);
}
-
+
Region rgn = new Region();
rgn.set(mRect1);
rgn.op(mRect2, op);
-
+
mPaint.setColor(color);
RegionIterator iter = new RegionIterator(rgn);
Rect r = new Rect();
-
+
canvas.translate(0, 30);
mPaint.setColor(color);
while (iter.next(r)) {
@@ -81,7 +80,7 @@
}
drawOriginalRects(canvas, 0x80);
}
-
+
private static void drawCentered(Canvas c, Rect r, Paint p) {
float inset = p.getStrokeWidth() * 0.5f;
if (inset == 0) { // catch hairlines
@@ -90,32 +89,33 @@
c.drawRect(r.left + inset, r.top + inset,
r.right - inset, r.bottom - inset, p);
}
-
- @Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(Color.GRAY);
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawColor(Color.GRAY);
canvas.save();
canvas.translate(80, 5);
drawOriginalRects(canvas, 0xFF);
canvas.restore();
-
+
mPaint.setStyle(Paint.Style.FILL);
-
+
canvas.save();
canvas.translate(0, 140);
drawRgn(canvas, Color.RED, "Union", Region.Op.UNION);
canvas.restore();
-
+
canvas.save();
canvas.translate(0, 280);
drawRgn(canvas, Color.BLUE, "Xor", Region.Op.XOR);
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 140);
drawRgn(canvas, Color.GREEN, "Difference", Region.Op.DIFFERENCE);
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 280);
drawRgn(canvas, Color.WHITE, "Intersect", Region.Op.INTERSECT);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java b/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java
index b0ff0359..74c2406 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java
@@ -16,14 +16,10 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
public class RoundRects extends GraphicsActivity {
@@ -33,7 +29,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Path mPath;
private Paint mPaint;
@@ -47,73 +43,71 @@
mPath = new Path();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mRect = new Rect(0, 0, 120, 120);
-
+
mDrawable = new GradientDrawable(GradientDrawable.Orientation.TL_BR,
new int[] { 0xFFFF0000, 0xFF00FF00,
0xFF0000FF });
mDrawable.setShape(GradientDrawable.RECTANGLE);
mDrawable.setGradientRadius((float)(Math.sqrt(2) * 60));
}
-
+
static void setCornerRadii(GradientDrawable drawable, float r0,
float r1, float r2, float r3) {
drawable.setCornerRadii(new float[] { r0, r0, r1, r1,
r2, r2, r3, r3 });
}
-
+
@Override protected void onDraw(Canvas canvas) {
-
+
mDrawable.setBounds(mRect);
float r = 16;
-
+
canvas.save();
canvas.translate(10, 10);
mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
setCornerRadii(mDrawable, r, r, 0, 0);
mDrawable.draw(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(10 + mRect.width() + 10, 10);
mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
setCornerRadii(mDrawable, 0, 0, r, r);
mDrawable.draw(canvas);
canvas.restore();
-
+
canvas.translate(0, mRect.height() + 10);
-
+
canvas.save();
canvas.translate(10, 10);
mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
setCornerRadii(mDrawable, 0, r, r, 0);
mDrawable.draw(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(10 + mRect.width() + 10, 10);
mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
setCornerRadii(mDrawable, r, 0, 0, r);
mDrawable.draw(canvas);
canvas.restore();
-
+
canvas.translate(0, mRect.height() + 10);
-
+
canvas.save();
canvas.translate(10, 10);
mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
setCornerRadii(mDrawable, r, 0, r, 0);
mDrawable.draw(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(10 + mRect.width() + 10, 10);
mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
setCornerRadii(mDrawable, 0, r, 0, r);
mDrawable.draw(canvas);
canvas.restore();
-
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java
index f55e55b..6ffdb5b 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,14 +28,14 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mHairPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Matrix mMatrix = new Matrix();
private final RectF mSrcR = new RectF();
-
+
private static final Matrix.ScaleToFit[] sFits =
new Matrix.ScaleToFit[] {
Matrix.ScaleToFit.FILL,
@@ -44,11 +43,11 @@
Matrix.ScaleToFit.CENTER,
Matrix.ScaleToFit.END
};
-
+
private static final String[] sFitLabels = new String[] {
"FILL", "START", "CENTER", "END"
};
-
+
private static final int[] sSrcData = new int[] {
80, 40, Color.RED,
40, 80, Color.GREEN,
@@ -56,7 +55,7 @@
80, 80, Color.BLACK
};
private static final int N = 4;
-
+
private static final int WIDTH = 52;
private static final int HEIGHT = 52;
private final RectF mDstR = new RectF(0, 0, WIDTH, HEIGHT);
@@ -67,34 +66,33 @@
mHairPaint.setStyle(Paint.Style.STROKE);
mLabelPaint.setTextSize(16);
}
-
+
private void setSrcR(int index) {
int w = sSrcData[index*3 + 0];
int h = sSrcData[index*3 + 1];
mSrcR.set(0, 0, w, h);
}
-
+
private void drawSrcR(Canvas canvas, int index) {
mPaint.setColor(sSrcData[index*3 + 2]);
canvas.drawOval(mSrcR, mPaint);
}
-
+
private void drawFit(Canvas canvas, int index, Matrix.ScaleToFit stf) {
canvas.save();
-
+
setSrcR(index);
mMatrix.setRectToRect(mSrcR, mDstR, stf);
canvas.concat(mMatrix);
drawSrcR(canvas, index);
-
+
canvas.restore();
-
+
canvas.drawRect(mDstR, mHairPaint);
}
- @Override protected void onDraw(Canvas canvas) {
- Paint paint = mPaint;
-
+ @Override
+ protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.translate(10, 10);
@@ -106,7 +104,7 @@
canvas.translate(mSrcR.width() + 15, 0);
}
canvas.restore();
-
+
canvas.translate(0, 100);
for (int j = 0; j < sFits.length; j++) {
canvas.save();
@@ -121,4 +119,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java b/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java
index 87e0461..dc07a27 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java
@@ -24,6 +24,7 @@
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Config;
+import android.util.Log;
import android.view.View;
public class SensorTest extends GraphicsActivity {
@@ -33,7 +34,7 @@
private Sensor mSensor;
private SampleView mView;
private float[] mValues;
-
+
private static class RunAve {
private final float[] mWeights;
private final float mWeightScale;
@@ -43,7 +44,7 @@
public RunAve(float[] weights) {
mWeights = weights;
-
+
float sum = 0;
for (int i = 0; i < weights.length; i++) {
sum += weights[i];
@@ -54,12 +55,12 @@
mSamples = new float[mDepth];
mCurr = 0;
}
-
+
public void addSample(float value) {
mSamples[mCurr] = value;
mCurr = (mCurr + 1) % mDepth;
}
-
+
public float computeAve() {
final int depth = mDepth;
int index = mCurr;
@@ -92,20 +93,20 @@
}
mPrev[i] = event.values[i];
}
-
+
if (show) {
// only shows if we think the delta is big enough, in an attempt
// to detect "serious" moves left/right or up/down
- android.util.Log.e(TAG, "sensorChanged " + event.sensor.getName() +
+ Log.e(TAG, "sensorChanged " + event.sensor.getName() +
" (" + event.values[0] + ", " + event.values[1] + ", " +
event.values[2] + ")" + " diff(" + diff[0] +
" " + diff[1] + " " + diff[2] + ")");
}
-
+
long now = android.os.SystemClock.uptimeMillis();
if (now - mLastGestureTime > 1000) {
mLastGestureTime = 0;
-
+
float x = diff[0];
float y = diff[1];
boolean gestX = Math.abs(x) > 3;
@@ -114,15 +115,15 @@
if ((gestX || gestY) && !(gestX && gestY)) {
if (gestX) {
if (x < 0) {
- android.util.Log.e("test", "<<<<<<<< LEFT <<<<<<<<<<<<");
+ Log.e("test", "<<<<<<<< LEFT <<<<<<<<<<<<");
} else {
- android.util.Log.e("test", ">>>>>>>>> RITE >>>>>>>>>>>");
+ Log.e("test", ">>>>>>>>> RITE >>>>>>>>>>>");
}
} else {
if (y < -2) {
- android.util.Log.e("test", "<<<<<<<< UP <<<<<<<<<<<<");
+ Log.e("test", "<<<<<<<< UP <<<<<<<<<<<<");
} else {
- android.util.Log.e("test", ">>>>>>>>> DOWN >>>>>>>>>>>");
+ Log.e("test", ">>>>>>>>> DOWN >>>>>>>>>>>");
}
}
mLastGestureTime = now;
@@ -141,28 +142,27 @@
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mView = new SampleView(this);
setContentView(mView);
- if (Config.LOGD) android.util.Log.d(TAG, "create " + mSensorManager);
+ if (Config.DEBUG) Log.d(TAG, "create " + mSensorManager);
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mListener, mSensor, SensorManager.SENSOR_DELAY_FASTEST);
- if (Config.LOGD) android.util.Log.d(TAG, "resume " + mSensorManager);
+ if (Config.DEBUG) Log.d(TAG, "resume " + mSensorManager);
}
-
+
@Override
protected void onStop() {
mSensorManager.unregisterListener(mListener);
super.onStop();
- if (Config.LOGD) android.util.Log.d(TAG, "stop " + mSensorManager);
+ if (Config.DEBUG) Log.d(TAG, "stop " + mSensorManager);
}
private class SampleView extends View {
private Paint mPaint = new Paint();
private Path mPath = new Path();
private boolean mAnimate;
- private long mNextTime;
public SampleView(Context context) {
super(context);
@@ -174,13 +174,13 @@
mPath.lineTo(20, 60);
mPath.close();
}
-
+
@Override
protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
canvas.drawColor(Color.WHITE);
-
+
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
@@ -191,21 +191,23 @@
int cy = h / 2;
canvas.translate(cx, cy);
- if (mValues != null) {
+ if (mValues != null) {
canvas.rotate(-mValues[0]);
}
canvas.drawPath(mPath, mPaint);
}
-
+
@Override
protected void onAttachedToWindow() {
mAnimate = true;
+ if (Config.DEBUG) Log.d(TAG, "onAttachedToWindow. mAnimate="+mAnimate);
super.onAttachedToWindow();
}
-
+
@Override
protected void onDetachedFromWindow() {
mAnimate = false;
+ if (Config.DEBUG) Log.d(TAG, "onAttachedToWindow. mAnimate="+mAnimate);
super.onDetachedFromWindow();
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java
index 6d450bb..236f4fc 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java
@@ -16,16 +16,12 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
public class ShapeDrawable1 extends GraphicsActivity {
@@ -35,49 +31,49 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private ShapeDrawable[] mDrawables;
-
+
private static Shader makeSweep() {
return new SweepGradient(150, 25,
new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000 },
null);
}
-
+
private static Shader makeLinear() {
return new LinearGradient(0, 0, 50, 50,
new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF },
null, Shader.TileMode.MIRROR);
}
-
+
private static Shader makeTiling() {
int[] pixels = new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0};
Bitmap bm = Bitmap.createBitmap(pixels, 2, 2,
Bitmap.Config.ARGB_8888);
-
+
return new BitmapShader(bm, Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
}
-
+
private static class MyShapeDrawable extends ShapeDrawable {
private Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
+
public MyShapeDrawable(Shape s) {
super(s);
mStrokePaint.setStyle(Paint.Style.STROKE);
}
-
+
public Paint getStrokePaint() {
return mStrokePaint;
}
-
+
@Override protected void onDraw(Shape s, Canvas c, Paint p) {
s.draw(c, p);
s.draw(c, mStrokePaint);
}
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
@@ -85,14 +81,14 @@
float[] outerR = new float[] { 12, 12, 12, 12, 0, 0, 0, 0 };
RectF inset = new RectF(6, 6, 6, 6);
float[] innerR = new float[] { 12, 12, 0, 0, 12, 12, 0, 0 };
-
+
Path path = new Path();
path.moveTo(50, 0);
path.lineTo(0, 50);
path.lineTo(50, 100);
path.lineTo(100, 50);
path.close();
-
+
mDrawables = new ShapeDrawable[7];
mDrawables[0] = new ShapeDrawable(new RectShape());
mDrawables[1] = new ShapeDrawable(new OvalShape());
@@ -104,7 +100,7 @@
innerR));
mDrawables[5] = new ShapeDrawable(new PathShape(path, 100, 100));
mDrawables[6] = new MyShapeDrawable(new ArcShape(45, -270));
-
+
mDrawables[0].getPaint().setColor(0xFFFF0000);
mDrawables[1].getPaint().setColor(0xFF00FF00);
mDrawables[2].getPaint().setColor(0xFF0000FF);
@@ -112,26 +108,26 @@
mDrawables[4].getPaint().setShader(makeLinear());
mDrawables[5].getPaint().setShader(makeTiling());
mDrawables[6].getPaint().setColor(0x88FF8844);
-
+
PathEffect pe = new DiscretePathEffect(10, 4);
PathEffect pe2 = new CornerPathEffect(4);
mDrawables[3].getPaint().setPathEffect(
new ComposePathEffect(pe2, pe));
-
+
MyShapeDrawable msd = (MyShapeDrawable)mDrawables[6];
msd.getStrokePaint().setStrokeWidth(4);
}
-
+
@Override protected void onDraw(Canvas canvas) {
-
+
int x = 10;
int y = 10;
int width = 300;
int height = 50;
-
+
for (Drawable dr : mDrawables) {
dr.setBounds(x, y, x + width, y + height);
- dr.draw(canvas);
+ dr.draw(canvas);
y += height + 5;
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java
index dc127fd..5da10cf 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java
@@ -16,11 +16,6 @@
package com.example.android.apis.graphics;
-// Need the following import to get access to the app resources, since this
-// class is in a sub-package.
-//import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -34,7 +29,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float mRotate;
@@ -55,7 +50,7 @@
Color.GREEN }, null);
mPaint.setShader(mShader);
}
-
+
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
float x = 160;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java
index 0576a7c..0ecba16 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java
@@ -16,13 +16,9 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
public class TextAlign extends GraphicsActivity {
@@ -32,27 +28,27 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint;
private float mX;
private float[] mPos;
-
+
private Path mPath;
private Paint mPathPaint;
-
+
private static final int DY = 30;
private static final String TEXT_L = "Left";
private static final String TEXT_C = "Center";
private static final String TEXT_R = "Right";
private static final String POSTEXT = "Positioned";
private static final String TEXTONPATH = "Along a path";
-
+
private static void makePath(Path p) {
p.moveTo(10, 0);
p.cubicTo(100, -50, 200, 50, 300, 0);
}
-
+
private float[] buildTextPositions(String text, float y, Paint paint) {
float[] widths = new float[text.length()];
// initially get the widths for each char
@@ -67,18 +63,18 @@
}
return pos;
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(30);
mPaint.setTypeface(Typeface.SERIF);
-
+
mPos = buildTextPositions(POSTEXT, 0, mPaint);
-
+
mPath = new Path();
makePath(mPath);
@@ -87,7 +83,7 @@
mPathPaint.setColor(0x800000FF);
mPathPaint.setStyle(Paint.Style.STROKE);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
@@ -95,13 +91,13 @@
float x = mX;
float y = 0;
float[] pos = mPos;
-
+
// draw the normal strings
p.setColor(0x80FF0000);
canvas.drawLine(x, y, x, y+DY*3, p);
p.setColor(Color.BLACK);
-
+
canvas.translate(0, DY);
p.setTextAlign(Paint.Align.LEFT);
canvas.drawText(TEXT_L, x, y, p);
@@ -113,11 +109,11 @@
canvas.translate(0, DY);
p.setTextAlign(Paint.Align.RIGHT);
canvas.drawText(TEXT_R, x, y, p);
-
+
canvas.translate(100, DY*2);
// now draw the positioned strings
-
+
p.setColor(0xBB00FF00);
for (int i = 0; i < pos.length/2; i++) {
canvas.drawLine(pos[i*2+0], pos[i*2+1]-DY,
@@ -127,17 +123,17 @@
p.setTextAlign(Paint.Align.LEFT);
canvas.drawPosText(POSTEXT, pos, p);
-
+
canvas.translate(0, DY);
p.setTextAlign(Paint.Align.CENTER);
canvas.drawPosText(POSTEXT, pos, p);
-
+
canvas.translate(0, DY);
p.setTextAlign(Paint.Align.RIGHT);
canvas.drawPosText(POSTEXT, pos, p);
-
+
// now draw the text on path
-
+
canvas.translate(-100, DY*2);
canvas.drawPath(mPath, mPathPaint);
@@ -148,7 +144,7 @@
canvas.drawPath(mPath, mPathPaint);
p.setTextAlign(Paint.Align.CENTER);
canvas.drawTextOnPath(TEXTONPATH, mPath, 0, 0, p);
-
+
canvas.translate(0, DY*1.5f);
canvas.drawPath(mPath, mPathPaint);
p.setTextAlign(Paint.Align.RIGHT);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java
index 14e6c4f..9a3eb65 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -41,34 +40,34 @@
public class TouchPaint extends GraphicsActivity {
/** Used as a pulse to gradually fade the contents of the window. */
private static final int FADE_MSG = 1;
-
+
/** Menu ID for the command to clear the window. */
private static final int CLEAR_ID = Menu.FIRST;
/** Menu ID for the command to toggle fading. */
private static final int FADE_ID = Menu.FIRST+1;
-
+
/** How often to fade the contents of the window (in ms). */
private static final int FADE_DELAY = 100;
-
+
/** The view responsible for drawing the window. */
MyView mView;
/** Is fading mode enabled? */
boolean mFading;
-
+
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
+
// Create and attach the view that is responsible for painting.
mView = new MyView(this);
setContentView(mView);
mView.requestFocus();
-
+
// Restore the fading option if we are being thawed from a
// previously saved state. Note that we are not currently remembering
// the contents of the bitmap.
mFading = savedInstanceState != null ? savedInstanceState.getBoolean("fading", true) : true;
}
-
+
@Override public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, CLEAR_ID, 0, "Clear");
menu.add(0, FADE_ID, 0, "Fade").setCheckable(true);
@@ -130,14 +129,14 @@
mHandler.sendMessageDelayed(
mHandler.obtainMessage(FADE_MSG), FADE_DELAY);
}
-
+
/**
* Stop the pulse to fade the screen.
*/
void stopFading() {
mHandler.removeMessages(FADE_MSG);
}
-
+
private Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
switch (msg.what) {
@@ -155,7 +154,7 @@
}
}
};
-
+
public class MyView extends View {
private static final int FADE_ALPHA = 0x06;
private static final int MAX_FADE_STEPS = 256/FADE_ALPHA + 4;
@@ -169,7 +168,7 @@
private float mCurX;
private float mCurY;
private int mFadeSteps = MAX_FADE_STEPS;
-
+
public MyView(Context c) {
super(c);
setFocusable(true);
@@ -189,7 +188,7 @@
mFadeSteps = MAX_FADE_STEPS;
}
}
-
+
public void fade() {
if (mCanvas != null && mFadeSteps < MAX_FADE_STEPS) {
mCanvas.drawPaint(mFadePaint);
@@ -197,7 +196,7 @@
mFadeSteps++;
}
}
-
+
@Override protected void onSizeChanged(int w, int h, int oldw,
int oldh) {
int curW = mBitmap != null ? mBitmap.getWidth() : 0;
@@ -205,10 +204,10 @@
if (curW >= w && curH >= h) {
return;
}
-
+
if (curW < w) curW = w;
if (curH < h) curH = h;
-
+
Bitmap newBitmap = Bitmap.createBitmap(curW, curH,
Bitmap.Config.RGB_565);
Canvas newCanvas = new Canvas();
@@ -220,7 +219,7 @@
mCanvas = newCanvas;
mFadeSteps = MAX_FADE_STEPS;
}
-
+
@Override protected void onDraw(Canvas canvas) {
if (mBitmap != null) {
canvas.drawBitmap(mBitmap, 0, 0, null);
@@ -246,7 +245,7 @@
drawPoint(mCurX, mCurY, 1.0f, 16.0f);
return true;
}
-
+
@Override public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
if (action != MotionEvent.ACTION_UP && action != MotionEvent.ACTION_CANCEL) {
@@ -269,7 +268,7 @@
}
return true;
}
-
+
private void drawPoint(float x, float y, float pressure, float width) {
//Log.i("TouchPaint", "Drawing: " + x + "x" + y + " p="
// + pressure + " width=" + width);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java
index c0f32a7..4133c04 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
index ede6ef5..c41d173 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
@@ -23,7 +23,6 @@
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
-import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java
index aefc311..08facaa 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,20 +28,20 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Typeface mFace;
-
+
public SampleView(Context context) {
super(context);
mFace = Typeface.createFromAsset(getContext().getAssets(),
"fonts/samplefont.ttf");
-
+
mPaint.setTextSize(64);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java b/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java
index 7ee99d0..0a2f630 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,20 +28,20 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
+
requestWindowFeature(Window.FEATURE_NO_TITLE);
-
+
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mBigCharPaint;
private Paint mLabelPaint;
private final char[] mChars = new char[256];
private final float[] mPos = new float[512];
-
+
private int mBase;
-
+
private static final int XMUL = 20;
private static final int YMUL = 28;
private static final int YBASE = 18;
@@ -51,49 +50,49 @@
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
-
+
mBigCharPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBigCharPaint.setTextSize(15);
mBigCharPaint.setTextAlign(Paint.Align.CENTER);
-
+
mLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLabelPaint.setTextSize(8);
mLabelPaint.setTextAlign(Paint.Align.CENTER);
-
+
// the position array is the same for all charts
float[] pos = mPos;
int index = 0;
for (int col = 0; col < 16; col++) {
- final float x = col * 20 + 10;
+ final float x = col * XMUL + 10;
for (int row = 0; row < 16; row++) {
pos[index++] = x;
pos[index++] = row * YMUL + YBASE;
}
}
}
-
+
private float computeX(int index) {
- return (index >> 4) * 20 + 10;
+ return (index >> 4) * XMUL + 10;
}
private float computeY(int index) {
return (index & 0xF) * YMUL + YMUL;
}
-
+
private void drawChart(Canvas canvas, int base) {
char[] chars = mChars;
for (int i = 0; i < 256; i++) {
int unichar = base + i;
chars[i] = (char)unichar;
-
+
canvas.drawText(Integer.toHexString(unichar),
computeX(i), computeY(i), mLabelPaint);
}
canvas.drawPosText(chars, 0, 256, mPos, mBigCharPaint);
}
-
+
@Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(Color.WHITE);
+ canvas.drawColor(Color.WHITE);
canvas.translate(0, 1);
drawChart(canvas, mBase * 256);
@@ -118,4 +117,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java
index 1e61906..ac1ab8a 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java
@@ -18,17 +18,11 @@
import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
-import android.graphics.drawable.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
-import java.io.IOException;
-import java.io.InputStream;
-
public class Vertices extends GraphicsActivity {
@Override
@@ -36,14 +30,13 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private final Paint mPaint = new Paint();
private final float[] mVerts = new float[10];
private final float[] mTexs = new float[10];
- private final int[] mColors = new int[10];
private final short[] mIndices = { 0, 1, 2, 3, 4, 1 };
-
+
private final Matrix mMatrix = new Matrix();
private final Matrix mInverse = new Matrix();
@@ -61,7 +54,7 @@
Shader s = new BitmapShader(bm, Shader.TileMode.CLAMP,
Shader.TileMode.CLAMP);
mPaint.setShader(s);
-
+
float w = bm.getWidth();
float h = bm.getHeight();
// construct our mesh
@@ -70,18 +63,18 @@
setXY(mTexs, 2, w, 0);
setXY(mTexs, 3, w, h);
setXY(mTexs, 4, 0, h);
-
+
setXY(mVerts, 0, w/2, h/2);
setXY(mVerts, 1, 0, 0);
setXY(mVerts, 2, w, 0);
setXY(mVerts, 3, w, h);
setXY(mVerts, 4, 0, h);
-
+
mMatrix.setScale(0.8f, 0.8f);
mMatrix.preTranslate(20, 20);
mMatrix.invert(mInverse);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFCCCCCC);
canvas.save();
@@ -104,7 +97,7 @@
invalidate();
return true;
}
-
+
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java
index b9f8424..54e15e3 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
@@ -33,35 +32,35 @@
import android.view.View;
public class Xfermodes extends GraphicsActivity {
-
+
// create a bitmap with a circle, used for the "dst" image
static Bitmap makeDst(int w, int h) {
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-
- p.setColor(0xFFFFCC44);
+
+ p.setColor(0xFFFFCC44);
c.drawOval(new RectF(0, 0, w*3/4, h*3/4), p);
return bm;
}
-
+
// create a bitmap with a rect, used for the "src" image
static Bitmap makeSrc(int w, int h) {
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-
+
p.setColor(0xFF66AAFF);
c.drawRect(w/3, h/3, w*19/20, h*19/20, p);
return bm;
}
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private static final int W = 64;
private static final int H = 64;
@@ -70,7 +69,7 @@
private Bitmap mSrcB;
private Bitmap mDstB;
private Shader mBG; // background checker-board pattern
-
+
private static final Xfermode[] sModes = {
new PorterDuffXfermode(PorterDuff.Mode.CLEAR),
new PorterDuffXfermode(PorterDuff.Mode.SRC),
@@ -89,20 +88,20 @@
new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),
new PorterDuffXfermode(PorterDuff.Mode.SCREEN)
};
-
+
private static final String[] sLabels = {
"Clear", "Src", "Dst", "SrcOver",
"DstOver", "SrcIn", "DstIn", "SrcOut",
"DstOut", "SrcATop", "DstATop", "Xor",
"Darken", "Lighten", "Multiply", "Screen"
};
-
+
public SampleView(Context context) {
super(context);
-
+
mSrcB = makeSrc(W, H);
mDstB = makeDst(W, H);
-
+
// make a ckeckerboard pattern
Bitmap bm = Bitmap.createBitmap(new int[] { 0xFFFFFFFF, 0xFFCCCCCC,
0xFFCCCCCC, 0xFFFFFFFF }, 2, 2,
@@ -114,18 +113,18 @@
m.setScale(6, 6);
mBG.setLocalMatrix(m);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
-
+
Paint labelP = new Paint(Paint.ANTI_ALIAS_FLAG);
labelP.setTextAlign(Paint.Align.CENTER);
-
+
Paint paint = new Paint();
paint.setFilterBitmap(false);
-
+
canvas.translate(15, 35);
-
+
int x = 0;
int y = 0;
for (int i = 0; i < sModes.length; i++) {
@@ -134,12 +133,12 @@
paint.setShader(null);
canvas.drawRect(x - 0.5f, y - 0.5f,
x + W + 0.5f, y + H + 0.5f, paint);
-
+
// draw the checker-board pattern
paint.setStyle(Paint.Style.FILL);
paint.setShader(mBG);
canvas.drawRect(x, y, x + W, y + H, paint);
-
+
// draw the src/dst example into our offscreen bitmap
int sc = canvas.saveLayer(x, y, x + W, y + H, null,
Canvas.MATRIX_SAVE_FLAG |
@@ -153,13 +152,13 @@
canvas.drawBitmap(mSrcB, 0, 0, paint);
paint.setXfermode(null);
canvas.restoreToCount(sc);
-
+
// draw the label
canvas.drawText(sLabels[i],
x + W/2, y - labelP.getTextSize()/2, labelP);
-
+
x += W + 10;
-
+
// wrap around when we've drawn enough for one row
if ((i % ROW_MAX) == ROW_MAX - 1) {
x = 0;
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java b/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java
index b2236aa..041794e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java
@@ -49,7 +49,7 @@
s.setOnItemSelectedListener(this);
}
- public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
switch (position) {
case 0:
@@ -79,7 +79,7 @@
}
}
- public void onNothingSelected(AdapterView parent) {
+ public void onNothingSelected(AdapterView<?> parent) {
}
private String[] mStrings = {
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java b/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java
index 11fc9ed..2cd7605 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java
@@ -50,7 +50,7 @@
s.setOnItemSelectedListener(this);
}
- public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
final View target = findViewById(R.id.target);
final View targetParent = (View) target.getParent();
@@ -96,6 +96,6 @@
target.startAnimation(a);
}
- public void onNothingSelected(AdapterView parent) {
+ public void onNothingSelected(AdapterView<?> parent) {
}
}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java
index f4274e5..bec4a5d 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java
@@ -19,12 +19,9 @@
import com.example.android.apis.R;
import android.app.Activity;
-import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.os.Bundle;
-import android.view.View;
-
public class AutoComplete1 extends Activity {
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java
index c6fa08b..3d63a91 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java
@@ -22,13 +22,15 @@
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
-import android.provider.Contacts;
+import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AutoCompleteTextView;
import android.widget.CursorAdapter;
+import android.widget.FilterQueryProvider;
import android.widget.Filterable;
import android.widget.TextView;
@@ -39,8 +41,9 @@
setContentView(R.layout.autocomplete_4);
ContentResolver content = getContentResolver();
- Cursor cursor = content.query(Contacts.People.CONTENT_URI,
- PEOPLE_PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER);
+ Cursor cursor = content.query(Contacts.CONTENT_URI,
+ CONTACT_PROJECTION, null, null, null);
+
ContactListAdapter adapter = new ContactListAdapter(this, cursor);
AutoCompleteTextView textView = (AutoCompleteTextView)
@@ -61,50 +64,40 @@
final LayoutInflater inflater = LayoutInflater.from(context);
final TextView view = (TextView) inflater.inflate(
android.R.layout.simple_dropdown_item_1line, parent, false);
- view.setText(cursor.getString(5));
+ view.setText(cursor.getString(COLUMN_DISPLAY_NAME));
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
- ((TextView) view).setText(cursor.getString(5));
+ ((TextView) view).setText(cursor.getString(COLUMN_DISPLAY_NAME));
}
@Override
public String convertToString(Cursor cursor) {
- return cursor.getString(5);
+ return cursor.getString(COLUMN_DISPLAY_NAME);
}
@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
- if (getFilterQueryProvider() != null) {
- return getFilterQueryProvider().runQuery(constraint);
+ FilterQueryProvider filter = getFilterQueryProvider();
+ if (filter != null) {
+ return filter.runQuery(constraint);
}
- StringBuilder buffer = null;
- String[] args = null;
- if (constraint != null) {
- buffer = new StringBuilder();
- buffer.append("UPPER(");
- buffer.append(Contacts.ContactMethods.NAME);
- buffer.append(") GLOB ?");
- args = new String[] { constraint.toString().toUpperCase() + "*" };
- }
-
- return mContent.query(Contacts.People.CONTENT_URI, PEOPLE_PROJECTION,
- buffer == null ? null : buffer.toString(), args,
- Contacts.People.DEFAULT_SORT_ORDER);
+ Uri uri = Uri.withAppendedPath(
+ Contacts.CONTENT_FILTER_URI,
+ Uri.encode(constraint.toString()));
+ return mContent.query(uri, CONTACT_PROJECTION, null, null, null);
}
- private ContentResolver mContent;
+ private ContentResolver mContent;
}
- private static final String[] PEOPLE_PROJECTION = new String[] {
- Contacts.People._ID,
- Contacts.People.PRIMARY_PHONE_ID,
- Contacts.People.TYPE,
- Contacts.People.NUMBER,
- Contacts.People.LABEL,
- Contacts.People.NAME,
+ public static final String[] CONTACT_PROJECTION = new String[] {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME
};
-}
+
+ private static final int COLUMN_DISPLAY_NAME = 1;
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java
index 7406da4..2009d8a2 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java
@@ -22,7 +22,7 @@
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
-import android.provider.Contacts;
+import android.provider.ContactsContract.Contacts;
import android.widget.AutoCompleteTextView;
public class AutoComplete5 extends Activity {
@@ -32,8 +32,8 @@
setContentView(R.layout.autocomplete_5);
ContentResolver content = getContentResolver();
- Cursor cursor = content.query(Contacts.People.CONTENT_URI,
- PEOPLE_PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER);
+ Cursor cursor = content.query(Contacts.CONTENT_URI,
+ AutoComplete4.CONTACT_PROJECTION, null, null, null);
AutoComplete4.ContactListAdapter adapter =
new AutoComplete4.ContactListAdapter(this, cursor);
@@ -41,13 +41,4 @@
findViewById(R.id.edit);
textView.setAdapter(adapter);
}
-
- private static final String[] PEOPLE_PROJECTION = new String[] {
- Contacts.People._ID,
- Contacts.People.PRIMARY_PHONE_ID,
- Contacts.People.TYPE,
- Contacts.People.NUMBER,
- Contacts.People.LABEL,
- Contacts.People.NAME
- };
-}
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java
index 3573bfb..2c28d65 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java
@@ -19,12 +19,9 @@
import com.example.android.apis.R;
import android.app.Activity;
-import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.MultiAutoCompleteTextView;
import android.os.Bundle;
-import android.view.View;
-
public class AutoComplete6 extends Activity {
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java b/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java
index e2f8cc8..a88ee30 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java
@@ -22,9 +22,6 @@
import android.app.Activity;
import android.os.Bundle;
-import android.widget.Spinner;
-import android.widget.ArrayAdapter;
-
/**
* A gallery of the different styles of buttons.
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
index 5784122..b6cce29 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
@@ -17,49 +17,49 @@
package com.example.android.apis.view;
import android.app.ExpandableListActivity;
-import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
-import android.net.Uri;
import android.os.Bundle;
-import android.provider.Contacts.People;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.widget.ExpandableListAdapter;
import android.widget.SimpleCursorTreeAdapter;
-
/**
* Demonstrates expandable lists backed by Cursors
*/
public class ExpandableList2 extends ExpandableListActivity {
- private int mGroupIdColumnIndex;
-
- private String mPhoneNumberProjection[] = new String[] {
- People.Phones._ID, People.Phones.NUMBER
+ private static final int COLUMN_CONTACT_ID = 0;
+
+ private static final String[] CONTACT_PROJECTION = new String[] {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME
};
-
+ private static final String[] PHONE_PROJECTION = new String[] {
+ Phone._ID,
+ Phone.CONTACT_ID,
+ Phone.NUMBER
+ };
+
private ExpandableListAdapter mAdapter;
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Query for people
- Cursor groupCursor = managedQuery(People.CONTENT_URI,
- new String[] {People._ID, People.NAME}, null, null, null);
-
- // Cache the ID column index
- mGroupIdColumnIndex = groupCursor.getColumnIndexOrThrow(People._ID);
+ Cursor groupCursor = managedQuery(Contacts.CONTENT_URI,
+ CONTACT_PROJECTION, null, null, null);
// Set up our adapter
mAdapter = new MyExpandableListAdapter(groupCursor,
this,
android.R.layout.simple_expandable_list_item_1,
android.R.layout.simple_expandable_list_item_1,
- new String[] {People.NAME}, // Name for group layouts
+ new String[] {Contacts.DISPLAY_NAME}, // Name for group layouts
new int[] {android.R.id.text1},
- new String[] {People.NUMBER}, // Number for child layouts
+ new String[] {Phone.NUMBER}, // Number for child layouts
new int[] {android.R.id.text1});
setListAdapter(mAdapter);
}
@@ -75,18 +75,13 @@
@Override
protected Cursor getChildrenCursor(Cursor groupCursor) {
- // Given the group, we return a cursor for all the children within that group
-
- // Return a cursor that points to this contact's phone numbers
- Uri.Builder builder = People.CONTENT_URI.buildUpon();
- ContentUris.appendId(builder, groupCursor.getLong(mGroupIdColumnIndex));
- builder.appendEncodedPath(People.Phones.CONTENT_DIRECTORY);
- Uri phoneNumbersUri = builder.build();
-
+ int contactId = groupCursor.getInt(COLUMN_CONTACT_ID);
// The returned Cursor MUST be managed by us, so we use Activity's helper
// functionality to manage it for us.
- return managedQuery(phoneNumbersUri, mPhoneNumberProjection, null, null, null);
+ return managedQuery(Phone.CONTENT_URI,
+ PHONE_PROJECTION,
+ Phone.CONTACT_ID + " = " + contactId,
+ null, null);
}
-
}
-}
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java b/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java
index 86f6ee7..c816b31 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java
@@ -20,12 +20,10 @@
import android.app.Activity;
import android.os.Bundle;
-import android.view.View;
import android.webkit.WebView;
import android.widget.ListView;
import android.widget.ArrayAdapter;
-
/**
* Demonstrates the use of non-focusable views.
*/
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java b/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
index a539a5b..7aaaaef 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
@@ -49,7 +49,7 @@
// Set a item click listener, and just Toast the clicked position
g.setOnItemClickListener(new OnItemClickListener() {
- public void onItemClick(AdapterView parent, View v, int position, long id) {
+ public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(Gallery1.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java b/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java
index 2eea1ff..ed33451 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java
@@ -17,9 +17,8 @@
package com.example.android.apis.view;
import android.app.Activity;
-import android.content.Context;
import android.database.Cursor;
-import android.provider.Contacts.People;
+import android.provider.ContactsContract.Contacts;
import android.os.Bundle;
import android.widget.Gallery;
import android.widget.SimpleCursorAdapter;
@@ -37,16 +36,17 @@
setContentView(R.layout.gallery_2);
// Get a cursor with all people
- Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
+ Cursor c = getContentResolver().query(Contacts.CONTENT_URI,
+ CONTACT_PROJECTION, null, null, null);
startManagingCursor(c);
-
+
SpinnerAdapter adapter = new SimpleCursorAdapter(this,
// Use a template that displays a text view
android.R.layout.simple_gallery_item,
// Give the cursor to the list adatper
c,
// Map the NAME column in the people database to...
- new String[] {People.NAME},
+ new String[] {Contacts.DISPLAY_NAME},
// The "text1" view defined in the XML template
new int[] { android.R.id.text1 });
@@ -54,4 +54,8 @@
g.setAdapter(adapter);
}
-}
+ private static final String[] CONTACT_PROJECTION = new String[] {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME
+ };
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java b/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java
index 66ef282..7f17c82 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java
@@ -56,11 +56,11 @@
g.setOnItemSelectedListener(this);
}
- public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
mSwitcher.setImageResource(mImageIds[position]);
}
- public void onNothingSelected(AdapterView parent) {
+ public void onNothingSelected(AdapterView<?> parent) {
}
public View makeView() {
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List13.java b/samples/ApiDemos/src/com/example/android/apis/view/List13.java
index b3087be..68179ed 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List13.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List13.java
@@ -52,7 +52,6 @@
private LayoutInflater mInflater;
public SlowAdapter(Context context) {
- mContext = context;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@@ -114,11 +113,6 @@
return text;
}
-
- /**
- * Remember our context so we can use it when constructing views.
- */
- private Context mContext;
}
@Override
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List2.java b/samples/ApiDemos/src/com/example/android/apis/view/List2.java
index 4f37dd8..4dca2a7 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List2.java
@@ -18,34 +18,40 @@
import android.app.ListActivity;
import android.database.Cursor;
-import android.provider.Contacts.People;
+import android.provider.ContactsContract.Contacts;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;
/**
- * A list view example where the
+ * A list view example where the
* data comes from a cursor.
*/
public class List2 extends ListActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get a cursor with all people
- Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
+ Cursor c = getContentResolver().query(Contacts.CONTENT_URI,
+ CONTACT_PROJECTION, null, null, null);
startManagingCursor(c);
- ListAdapter adapter = new SimpleCursorAdapter(this,
+ ListAdapter adapter = new SimpleCursorAdapter(this,
// Use a template that displays a text view
- android.R.layout.simple_list_item_1,
+ android.R.layout.simple_list_item_1,
// Give the cursor to the list adatper
- c,
+ c,
// Map the NAME column in the people database to...
- new String[] {People.NAME} ,
+ new String[] {Contacts.DISPLAY_NAME},
// The "text1" view defined in the XML template
- new int[] {android.R.id.text1});
+ new int[] {android.R.id.text1});
setListAdapter(adapter);
}
-}
+
+ private static final String[] CONTACT_PROJECTION = new String[] {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME
+ };
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List3.java b/samples/ApiDemos/src/com/example/android/apis/view/List3.java
index 17e59f1..9c3b4b4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List3.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List3.java
@@ -16,36 +16,69 @@
package com.example.android.apis.view;
-
import android.app.ListActivity;
import android.database.Cursor;
import android.os.Bundle;
-import android.provider.Contacts.Phones;
-import android.widget.ListAdapter;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.view.View;
import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
/**
- * A list view example where the
+ * A list view example where the
* data comes from a cursor, and a
* SimpleCursorListAdapter is used to map each item to a two-line
* display.
*/
public class List3 extends ListActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get a cursor with all phones
- Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);
+ Cursor c = getContentResolver().query(Phone.CONTENT_URI,
+ PHONE_PROJECTION, null, null, null);
startManagingCursor(c);
-
+
// Map Cursor columns to views defined in simple_list_item_2.xml
- ListAdapter adapter = new SimpleCursorAdapter(this,
- android.R.layout.simple_list_item_2, c,
- new String[] { Phones.NAME, Phones.NUMBER },
+ SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
+ android.R.layout.simple_list_item_2, c,
+ new String[] {
+ Phone.TYPE,
+ Phone.NUMBER
+ },
new int[] { android.R.id.text1, android.R.id.text2 });
+ //Used to display a readable string for the phone type
+ adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
+ public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
+ //Let the adapter handle the binding if the column is not TYPE
+ if (columnIndex != COLUMN_TYPE) {
+ return false;
+ }
+ int type = cursor.getInt(COLUMN_TYPE);
+ String label = null;
+ //Custom type? Then get the custom label
+ if (type == Phone.TYPE_CUSTOM) {
+ label = cursor.getString(COLUMN_LABEL);
+ }
+ //Get the readable string
+ String text = (String) Phone.getTypeLabel(getResources(), type, label);
+ //Set text
+ ((TextView) view).setText(text);
+ return true;
+ }
+ });
setListAdapter(adapter);
}
-
-}
+
+ private static final String[] PHONE_PROJECTION = new String[] {
+ Phone._ID,
+ Phone.TYPE,
+ Phone.LABEL,
+ Phone.NUMBER
+ };
+
+ private static final int COLUMN_TYPE = 1;;
+ private static final int COLUMN_LABEL = 2;
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List7.java b/samples/ApiDemos/src/com/example/android/apis/view/List7.java
index e773db6..ff5406f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List7.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List7.java
@@ -16,12 +16,15 @@
package com.example.android.apis.view;
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
import com.example.android.apis.R;
+
import android.app.ListActivity;
import android.database.Cursor;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.os.Bundle;
-import android.provider.ContactsContract;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
@@ -33,69 +36,64 @@
* A list view example where the data comes from a cursor.
*/
public class List7 extends ListActivity implements OnItemSelectedListener {
- private static final String[] PROJECTION = new String[] {
- ContactsContract.Contacts._ID,
- ContactsContract.Contacts.DISPLAY_NAME,
- ContactsContract.Contacts.HAS_PHONE_NUMBER,
- ContactsContract.Contacts.LOOKUP_KEY
- };
-
- private int mIdColumnIndex;
- private int mHasPhoneColumnIndex;
private TextView mPhone;
+ private static final String[] PHONE_PROJECTION = new String[] {
+ Phone._ID,
+ Phone.TYPE,
+ Phone.LABEL,
+ Phone.NUMBER,
+ Phone.DISPLAY_NAME
+ };
+
+ private static final int COLUMN_PHONE_TYPE = 1;
+ private static final int COLUMN_PHONE_LABEL = 2;
+ private static final int COLUMN_PHONE_NUMBER = 3;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
setContentView(R.layout.list_7);
-
mPhone = (TextView) findViewById(R.id.phone);
getListView().setOnItemSelectedListener(this);
- // Get a cursor with all people
- Cursor c = managedQuery(ContactsContract.Contacts.CONTENT_URI,
- PROJECTION, null, null, null);
- mIdColumnIndex = c.getColumnIndex(ContactsContract.Contacts._ID);
- mHasPhoneColumnIndex = c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
+ // Get a cursor with all numbers.
+ // This query will only return contacts with phone numbers
+ Cursor c = getContentResolver().query(Phone.CONTENT_URI,
+ PHONE_PROJECTION, Phone.NUMBER + " NOT NULL", null, null);
+ startManagingCursor(c);
ListAdapter adapter = new SimpleCursorAdapter(this,
- android.R.layout.simple_list_item_1, // Use a template
- // that displays a
- // text view
- c, // Give the cursor to the list adapter
- new String[] { ContactsContract.Contacts.DISPLAY_NAME }, // Map the NAME column in the
- // people database to...
- new int[] { android.R.id.text1 }); // The "text1" view defined in
- // the XML template
+ // Use a template that displays a text view
+ android.R.layout.simple_list_item_1,
+ // Give the cursor to the list adapter
+ c,
+ // Map the DISPLAY_NAME column to...
+ new String[] {Phone.DISPLAY_NAME},
+ // The "text1" view defined in the XML template
+ new int[] {android.R.id.text1});
setListAdapter(adapter);
}
- public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
if (position >= 0) {
- final Cursor c = (Cursor) parent.getItemAtPosition(position);
- if (c.getInt(mHasPhoneColumnIndex) > 0) {
- final long contactId = c.getLong(mIdColumnIndex);
- final Cursor phones = getContentResolver().query(
- ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
- new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER },
- ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null,
- ContactsContract.CommonDataKinds.Phone.IS_SUPER_PRIMARY + " DESC");
-
- try {
- phones.moveToFirst();
- mPhone.setText(phones.getString(0));
- } finally {
- phones.close();
- }
- } else {
- mPhone.setText(R.string.list_7_nothing);
+ //Get current cursor
+ Cursor c = (Cursor) parent.getItemAtPosition(position);
+ int type = c.getInt(COLUMN_PHONE_TYPE);
+ String phone = c.getString(COLUMN_PHONE_NUMBER);
+ String label = null;
+ //Custom type? Then get the custom label
+ if (type == Phone.TYPE_CUSTOM) {
+ label = c.getString(COLUMN_PHONE_LABEL);
}
+ //Get the readable string
+ String numberType = (String) Phone.getTypeLabel(getResources(), type, label);
+ String text = numberType + ": " + phone;
+ mPhone.setText(text);
}
}
- public void onNothingSelected(AdapterView parent) {
- mPhone.setText(R.string.list_7_nothing);
+ public void onNothingSelected(AdapterView<?> parent) {
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List9.java b/samples/ApiDemos/src/com/example/android/apis/view/List9.java
index 15b3cc1..b2aea05 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List9.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List9.java
@@ -111,8 +111,8 @@
- public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
- int lastItem = firstVisibleItem + visibleItemCount - 1;
+ public void onScroll(AbsListView view, int firstVisibleItem,
+ int visibleItemCount, int totalItemCount) {
if (mReady) {
char firstLetter = mStrings[firstVisibleItem].charAt(0);
@@ -120,8 +120,6 @@
mShowing = true;
mDialogText.setVisibility(View.VISIBLE);
-
-
}
mDialogText.setText(((Character)firstLetter).toString());
mHandler.removeCallbacks(mRemoveWindow);
@@ -316,5 +314,4 @@
"Woodside Cabecou", "Xanadu", "Xynotyro", "Yarg Cornish",
"Yarra Valley Pyramid", "Yorkshire Blue", "Zamorano",
"Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
-
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java b/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java
index 97416d4..5fbf6dd 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java
@@ -19,7 +19,6 @@
import android.app.Activity;
import android.os.Bundle;
import android.widget.RatingBar;
-import android.widget.SeekBar;
import android.widget.TextView;
import com.example.android.apis.R;
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java b/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java
index 1af3c81..02fcd0e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java
@@ -24,7 +24,6 @@
import android.widget.TextView;
import android.widget.Button;
-
/**
* Demonstrates wrapping a layout in a ScrollView.
*
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java
index f1f8f24..f904f84 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java
@@ -19,15 +19,9 @@
import com.example.android.apis.R;
import android.app.Activity;
-import android.widget.TableLayout;
-import android.widget.Button;
import android.os.Bundle;
-import android.view.View;
-
public class TableLayout10 extends Activity {
- private boolean mShrink;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java
index 770238f..09b19a2 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java
@@ -25,8 +25,6 @@
* <p>This example shows how to use horizontal gravity in a table layout.</p>
*/
public class TableLayout11 extends Activity {
- private boolean mShrink;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java
index 14cbd0d..f3fe850 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java
@@ -25,8 +25,6 @@
* <p>This example shows how to use cell spanning in a table layout.</p>
*/
public class TableLayout12 extends Activity {
- private boolean mShrink;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java b/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java
index 455969e..39f7e9b 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java
@@ -21,7 +21,6 @@
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.view.LayoutInflater;
-import android.view.View;
import com.example.android.apis.R;
diff --git a/samples/ContactManager/AndroidManifest.xml b/samples/ContactManager/AndroidManifest.xml
index abf5669..60fca32 100644
--- a/samples/ContactManager/AndroidManifest.xml
+++ b/samples/ContactManager/AndroidManifest.xml
@@ -17,6 +17,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.contactmanager"
android:versionCode="1" android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="5" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+ <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+
<application android:label="@string/app_name" android:icon="@drawable/icon">
<activity android:name=".ContactManager" android:label="@string/app_name">
<intent-filter>
@@ -26,10 +32,5 @@
</activity>
<activity android:name="ContactAdder" android:label="@string/addContactTitle">
</activity>
-
</application>
- <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="5" />
- <uses-permission android:name="android.permission.GET_ACCOUNTS" />
- <uses-permission android:name="android.permission.READ_CONTACTS" />
- <uses-permission android:name="android.permission.WRITE_CONTACTS" />
</manifest>
diff --git a/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java b/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java
index d96b644..e27ee56 100644
--- a/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java
+++ b/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java
@@ -898,7 +898,7 @@
// The '2' key zooms out
case KeyEvent.KEYCODE_2:
- if (!mAlphaKeySet && !mDisplayWorldFlat) {
+ if (!mAlphaKeySet && !mDisplayWorldFlat && mInitialized) {
mGLView.zoom(-2);
handled = true;
}
@@ -906,7 +906,7 @@
// The '8' key zooms in
case KeyEvent.KEYCODE_8:
- if (!mAlphaKeySet && !mDisplayWorldFlat) {
+ if (!mAlphaKeySet && !mDisplayWorldFlat && mInitialized) {
mGLView.zoom(2);
handled = true;
}
diff --git a/samples/JetBoy/AndroidManifest.xml b/samples/JetBoy/AndroidManifest.xml
index bba069d..d0d4173 100755
--- a/samples/JetBoy/AndroidManifest.xml
+++ b/samples/JetBoy/AndroidManifest.xml
@@ -20,6 +20,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.jetboy" android:versionCode="1"
android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3"></uses-sdk>
+
<application android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
@@ -33,5 +36,4 @@
</intent-filter>
</activity>
</application>
- <uses-sdk android:minSdkVersion="3"></uses-sdk>
</manifest>
diff --git a/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java b/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java
index a4ffef5..15c5923 100644
--- a/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java
+++ b/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java
@@ -21,7 +21,6 @@
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.Window;
import android.widget.TextView;
import com.example.android.lunarlander.LunarView.LunarThread;
@@ -58,7 +57,7 @@
/**
* Invoked during init to give the Activity a chance to set up its Menu.
- *
+ *
* @param menu the Menu to which entries may be added
* @return true
*/
@@ -79,7 +78,7 @@
/**
* Invoked when the user selects an item from the Menu.
- *
+ *
* @param item the Menu entry which was selected
* @return true if the Menu item was legit (and we consumed it), false
* otherwise
@@ -116,7 +115,7 @@
/**
* Invoked when the Activity is created.
- *
+ *
* @param savedInstanceState a Bundle containing state saved from a previous
* execution, or null if this is a new execution
*/
@@ -157,7 +156,7 @@
/**
* Notification that something is about to happen, to give the Activity a
* chance to save state.
- *
+ *
* @param outState a Bundle into which this Activity should save its state
*/
@Override
diff --git a/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java b/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java
index c52c7ab..2a46147 100644
--- a/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java
+++ b/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java
@@ -37,7 +37,7 @@
/**
* View that draws, takes keystrokes, etc. for a simple LunarLander game.
- *
+ *
* Has a mode which RUNNING, PAUSED, etc. Has a x, y, dx, dy, ... capturing the
* current ship physics. All x/y etc. are measured with (0,0) at the lower left.
* updatePhysics() advances the physics based on realtime. draw() renders the
@@ -112,14 +112,14 @@
/**
* Current height of the surface/canvas.
- *
+ *
* @see #setSurfaceSize
*/
private int mCanvasHeight = 1;
/**
* Current width of the surface/canvas.
- *
+ *
* @see #setSurfaceSize
*/
private int mCanvasWidth = 1;
@@ -321,7 +321,7 @@
* Restores game state from the indicated Bundle. Typically called when
* the Activity is being restored after having been previously
* destroyed.
- *
+ *
* @param savedState Bundle containing the game state
*/
public synchronized void restoreState(Bundle savedState) {
@@ -372,7 +372,7 @@
/**
* Dump game state to the provided Bundle. Typically called when the
* Activity is being suspended.
- *
+ *
* @return Bundle with this view's state
*/
public Bundle saveState(Bundle map) {
@@ -400,7 +400,7 @@
/**
* Sets the current difficulty.
- *
+ *
* @param difficulty
*/
public void setDifficulty(int difficulty) {
@@ -423,7 +423,7 @@
* Passing true allows the thread to run; passing false will shut it
* down if it's already running. Calling start() after this was most
* recently called with false will result in an immediate shutdown.
- *
+ *
* @param b true to run, false to shut down
*/
public void setRunning(boolean b) {
@@ -433,7 +433,7 @@
/**
* Sets the game mode. That is, whether we are running, paused, in the
* failure state, in the victory state, etc.
- *
+ *
* @see #setState(int, CharSequence)
* @param mode one of the STATE_* constants
*/
@@ -446,7 +446,7 @@
/**
* Sets the game mode. That is, whether we are running, paused, in the
* failure state, in the victory state, etc.
- *
+ *
* @param mode one of the STATE_* constants
* @param message string to add to screen or null
*/
@@ -509,7 +509,7 @@
mCanvasHeight = height;
// don't forget to resize the background image
- mBackgroundImage = mBackgroundImage.createScaledBitmap(
+ mBackgroundImage = Bitmap.createScaledBitmap(
mBackgroundImage, width, height, true);
}
}
@@ -527,7 +527,7 @@
/**
* Handles a key-down event.
- *
+ *
* @param keyCode the key that was pressed
* @param msg the original event object
* @return true
@@ -539,8 +539,6 @@
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) okStart = true;
if (keyCode == KeyEvent.KEYCODE_S) okStart = true;
- boolean center = (keyCode == KeyEvent.KEYCODE_DPAD_UP);
-
if (okStart
&& (mMode == STATE_READY || mMode == STATE_LOSE || mMode == STATE_WIN)) {
// ready-to-start -> start
@@ -579,7 +577,7 @@
/**
* Handles a key-up event.
- *
+ *
* @param keyCode the key that was pressed
* @param msg the original event object
* @return true if the key was handled and consumed, or else false
@@ -807,7 +805,7 @@
/**
* Fetches the animation thread corresponding to this LunarView.
- *
+ *
* @return the animation thread
*/
public LunarThread getThread() {
diff --git a/samples/MultiResolution/AndroidManifest.xml b/samples/MultiResolution/AndroidManifest.xml
index 4719069..0ebb55c 100644
--- a/samples/MultiResolution/AndroidManifest.xml
+++ b/samples/MultiResolution/AndroidManifest.xml
@@ -23,6 +23,10 @@
<uses-permission
android:name="android.permission.INTERNET"/>
+ <uses-sdk
+ android:minSdkVersion="3"
+ android:targetSdkVersion="4"/>
+
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
@@ -42,8 +46,4 @@
</application>
- <uses-sdk
- android:minSdkVersion="3"
- android:targetSdkVersion="4"/>
-
</manifest>
diff --git a/samples/NotePad/AndroidManifest.xml b/samples/NotePad/AndroidManifest.xml
index b87dfe3..83e5732 100644
--- a/samples/NotePad/AndroidManifest.xml
+++ b/samples/NotePad/AndroidManifest.xml
@@ -22,6 +22,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.notepad" >
+ <uses-sdk android:targetSdkVersion="4" android:minSdkVersion="3"/>
+
<application android:icon="@drawable/app_notes"
android:label="@string/app_name" >
<provider android:name="NotePadProvider"
@@ -107,6 +109,4 @@
</application>
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4"/>
</manifest>
-
diff --git a/samples/SampleSyncAdapter/AndroidManifest.xml b/samples/SampleSyncAdapter/AndroidManifest.xml
index 7f9f83b..202ed0e 100644
--- a/samples/SampleSyncAdapter/AndroidManifest.xml
+++ b/samples/SampleSyncAdapter/AndroidManifest.xml
@@ -45,7 +45,9 @@
android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission
android:name="android.permission.WRITE_SYNC_SETTINGS" />
-
+
+ <uses-sdk android:minSdkVersion="5" />
+
<application
android:icon="@drawable/icon"
android:label="@string/label">
@@ -87,6 +89,4 @@
-->
</activity>
</application>
- <uses-sdk
- android:minSdkVersion="5" />
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/samples/Spinner/AndroidManifest.xml b/samples/Spinner/AndroidManifest.xml
index f1accf8..719a022 100644
--- a/samples/Spinner/AndroidManifest.xml
+++ b/samples/Spinner/AndroidManifest.xml
@@ -26,6 +26,12 @@
package="com.android.example.spinner"
android:versionCode="1"
android:versionName="1.0">
+
+ <!--
+ Requires a minimum platform version of Android-3 (SDK 1.5) to run
+ -->
+ <uses-sdk android:minSdkVersion="3"/>
+
<!--
Sets the application's user-readable label
-->
@@ -45,9 +51,5 @@
</activity>
</application>
- <!--
- Requires a minimum platform version of Android-3 (SDK 1.5) to run
- -->
- <uses-sdk android:minSdkVersion="3"/>
</manifest>
diff --git a/samples/TicTacToeMain/AndroidManifest.xml b/samples/TicTacToeMain/AndroidManifest.xml
index 54654f9..077eaa7 100755
--- a/samples/TicTacToeMain/AndroidManifest.xml
+++ b/samples/TicTacToeMain/AndroidManifest.xml
@@ -19,6 +19,9 @@
package="com.example.android.tictactoe"
android:versionCode="1"
android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="8" />
+
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
@@ -34,6 +37,4 @@
</application>
- <uses-sdk android:minSdkVersion="8" />
-
</manifest>
diff --git a/samples/Wiktionary/AndroidManifest.xml b/samples/Wiktionary/AndroidManifest.xml
index 1641a8b..741874b 100644
--- a/samples/Wiktionary/AndroidManifest.xml
+++ b/samples/Wiktionary/AndroidManifest.xml
@@ -18,6 +18,12 @@
package="com.example.android.wiktionary"
android:versionCode="1"
android:versionName="1.0">
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" />
+
+ <meta-data android:name="android.app.default_searchable" android:value=".LookupActivity" />
+
<application android:icon="@drawable/app_icon" android:label="@string/app_name"
android:description="@string/app_descrip">
@@ -62,9 +68,4 @@
</application>
- <meta-data android:name="android.app.default_searchable" android:value=".LookupActivity" />
-
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" />
-
</manifest>
diff --git a/samples/WiktionarySimple/AndroidManifest.xml b/samples/WiktionarySimple/AndroidManifest.xml
index c6b8724..b9935f4 100644
--- a/samples/WiktionarySimple/AndroidManifest.xml
+++ b/samples/WiktionarySimple/AndroidManifest.xml
@@ -19,6 +19,9 @@
android:versionCode="1"
android:versionName="1.0">
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" />
+
<application android:icon="@drawable/app_icon" android:label="@string/app_name">
<!-- Broadcast Receiver that will process AppWidget updates -->
@@ -35,7 +38,4 @@
</application>
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" />
-
</manifest>
diff --git a/testrunner/adb_interface.py b/testrunner/adb_interface.py
index 451d046..1928c73 100755
--- a/testrunner/adb_interface.py
+++ b/testrunner/adb_interface.py
@@ -315,19 +315,10 @@
self.SendCommand("wait-for-device")
# Now the device is there, but may not be running.
# Query the package manager with a basic command
- pm_found = False
- attempts = 0
- wait_period = 5
- while not pm_found and (attempts*wait_period) < wait_time:
- # assume the 'adb shell pm path android' command will always
- # return 'package: something' in the success case
- output = self.SendShellCommand("pm path android", retry_count=1)
- if "package:" in output:
- pm_found = True
- else:
- time.sleep(wait_period)
- attempts += 1
- if not pm_found:
+ try:
+ self._WaitForShellCommandContents("pm path android", "package:",
+ wait_time)
+ except errors.WaitForResponseTimedOutError:
raise errors.WaitForResponseTimedOutError(
"Package manager did not respond after %s seconds" % wait_time)
@@ -344,28 +335,88 @@
instrumentation_path = "%s/%s" % (package_name, runner_name)
logger.Log("Waiting for instrumentation to be present")
# Query the package manager
- inst_found = False
- attempts = 0
- wait_period = 5
- while not inst_found and (attempts*wait_period) < wait_time:
- # assume the 'adb shell pm list instrumentation'
- # return 'instrumentation: something' in the success case
- try:
- output = self.SendShellCommand("pm list instrumentation | grep %s"
- % instrumentation_path, retry_count=1)
- if "instrumentation:" in output:
- inst_found = True
- except errors.AbortError, e:
- # ignore
- pass
- if not inst_found:
- time.sleep(wait_period)
- attempts += 1
- if not inst_found:
+ try:
+ command = "pm list instrumentation | grep %s" % instrumentation_path
+ self._WaitForShellCommandContents(command, "instrumentation:", wait_time,
+ raise_abort=False)
+ except errors.WaitForResponseTimedOutError :
logger.Log(
"Could not find instrumentation %s on device. Does the "
"instrumentation in test's AndroidManifest.xml match definition"
"in test_defs.xml?" % instrumentation_path)
+ raise
+
+ def WaitForProcess(self, name, wait_time=120):
+ """Wait until a process is running on the device.
+
+ Args:
+ name: the process name as it appears in `ps`
+ wait_time: time in seconds to wait
+
+ Raises:
+ WaitForResponseTimedOutError if wait_time elapses and the process is
+ still not running
+ """
+ logger.Log("Waiting for process %s" % name)
+ self.SendCommand("wait-for-device")
+ self._WaitForShellCommandContents("ps", name, wait_time)
+
+ def WaitForProcessEnd(self, name, wait_time=120):
+ """Wait until a process is no longer running on the device.
+
+ Args:
+ name: the process name as it appears in `ps`
+ wait_time: time in seconds to wait
+
+ Raises:
+ WaitForResponseTimedOutError if wait_time elapses and the process is
+ still running
+ """
+ logger.Log("Waiting for process %s to end" % name)
+ self._WaitForShellCommandContents("ps", name, wait_time, invert=True)
+
+ def _WaitForShellCommandContents(self, command, expected, wait_time,
+ raise_abort=True, invert=False):
+ """Wait until the response to a command contains a given output.
+
+ Assumes that a only successful execution of "adb shell <command>" contains
+ the substring expected. Assumes that a device is present.
+
+ Args:
+ command: adb shell command to execute
+ expected: the string that should appear to consider the
+ command successful.
+ wait_time: time in seconds to wait
+ raise_abort: if False, retry when executing the command raises an
+ AbortError, rather than failing.
+ invert: if True, wait until the command output no longer contains the
+ expected contents.
+
+ Raises:
+ WaitForResponseTimedOutError: If wait_time elapses and the command has not
+ returned an output containing expected yet.
+ """
+ # Query the device with the command
+ success = False
+ attempts = 0
+ wait_period = 5
+ while not success and (attempts*wait_period) < wait_time:
+ # assume the command will always contain expected in the success case
+ try:
+ output = self.SendShellCommand(command, retry_count=1)
+ if ((not invert and expected in output)
+ or (invert and expected not in output)):
+ success = True
+ except errors.AbortError, e:
+ if raise_abort:
+ raise
+ # ignore otherwise
+
+ if not success:
+ time.sleep(wait_period)
+ attempts += 1
+
+ if not success:
raise errors.WaitForResponseTimedOutError()
def WaitForBootComplete(self, wait_time=120):
diff --git a/testrunner/test_defs/test_walker.py b/testrunner/test_defs/test_walker.py
index 06c4e6d..4ef6923 100755
--- a/testrunner/test_defs/test_walker.py
+++ b/testrunner/test_defs/test_walker.py
@@ -116,7 +116,8 @@
Args:
path: absolute file system path to check
tests: current list of found tests
- build_path: the parent directory where Android.mk was found
+ build_path: the parent directory where Android.mk that builds sub-folders
+ was found
Returns:
updated list of tests
@@ -124,17 +125,31 @@
if not os.path.isdir(path):
return tests
filenames = os.listdir(path)
- # Try to build as much of original path as possible, so
- # keep track of upper-most parent directory where Android.mk was found
- # this is also necessary in case of overlapping tests
- # ie if a test exists at 'foo' directory and 'foo/sub', attempting to
- # build both 'foo' and 'foo/sub' will fail.
- if not build_path and filenames.count(android_mk.AndroidMK.FILENAME):
- build_path = self._MakePathRelativeToBuild(path)
if filenames.count(android_manifest.AndroidManifest.FILENAME):
# found a manifest! now parse it to find the test definition(s)
manifest = android_manifest.AndroidManifest(app_path=path)
- tests.extend(self._CreateSuitesFromManifest(manifest, build_path))
+ if not build_path:
+ # haven't found a parent makefile which builds this dir. Use current
+ # dir as build path
+ tests.extend(self._CreateSuitesFromManifest(
+ manifest, self._MakePathRelativeToBuild(path)))
+ else:
+ tests.extend(self._CreateSuitesFromManifest(manifest, build_path))
+ # Try to build as much of original path as possible, so
+ # keep track of upper-most parent directory where Android.mk was found that
+ # has rule to build sub-directory makefiles
+ # this is also necessary in case of overlapping tests
+ # ie if a test exists at 'foo' directory and 'foo/sub', attempting to
+ # build both 'foo' and 'foo/sub' will fail.
+ if filenames.count(android_mk.AndroidMK.FILENAME):
+ android_mk_parser = android_mk.AndroidMK(app_path=path)
+ if android_mk_parser.HasInclude('call all-makefiles-under,$(LOCAL_PATH)'):
+ # found rule to build sub-directories. The parent path can be used,
+ # or if not set, use current path
+ if not build_path:
+ build_path = self._MakePathRelativeToBuild(path)
+ else:
+ build_path = None
for filename in filenames:
self._FindSubTests(os.path.join(path, filename), tests, build_path)
return tests
diff --git a/tools/monkeyrunner/Android.mk b/tools/monkeyrunner/Android.mk
deleted file mode 100644
index d15c67e..0000000
--- a/tools/monkeyrunner/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# 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.
-#
-MONKEYRUNNER_LOCAL_DIR := $(call my-dir)
-include $(MONKEYRUNNER_LOCAL_DIR)/etc/Android.mk
-include $(MONKEYRUNNER_LOCAL_DIR)/src/Android.mk
diff --git a/tools/monkeyrunner/MODULE_LICENSE_APACHE2 b/tools/monkeyrunner/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/tools/monkeyrunner/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/tools/monkeyrunner/NOTICE b/tools/monkeyrunner/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/tools/monkeyrunner/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/tools/monkeyrunner/etc/manifest.txt b/tools/monkeyrunner/etc/manifest.txt
deleted file mode 100644
index 288be5f..0000000
--- a/tools/monkeyrunner/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.monkeyrunner.MonkeyRunner
diff --git a/tools/monkeyrunner/etc/monkeyrunner b/tools/monkeyrunner/etc/monkeyrunner
deleted file mode 100755
index 364be2a..0000000
--- a/tools/monkeyrunner/etc/monkeyrunner
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/sh
-# Copyright 2005-2007, The Android Open Source Project
-#
-# 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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=monkeyrunner.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/tools/lib
- libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/framework
- libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- echo `basename "$prog"`": can't find $jarfile"
- exit 1
-fi
-
-
-# Check args.
-if [ debug = "$1" ]; then
- # add this in for debugging
- java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
- shift 1
-else
- java_debug=
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
- jarpath=`cygpath -w "$frameworkdir/$jarfile"`
- progdir=`cygpath -w "$progdir"`
-else
- jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -Dcom.android.monkeyrunner.bindir="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/monkeyrunner/src/Android.mk b/tools/monkeyrunner/src/Android.mk
deleted file mode 100644
index fb6b9c1..0000000
--- a/tools/monkeyrunner/src/Android.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# Copyright (C) 2009 The Android Open Source Project
-#
-# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
- ddmlib \
- jython \
- xmlwriter
-
-
-LOCAL_MODULE := monkeyrunner
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build ext.jar
-# ============================================================
-
-ext_dirs := ../../../../external/xmlwriter/src
-
-ext_src_files := $(call all-java-files-under,$(ext_dirs))
-
-# ==== the library =========================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(ext_src_files)
-
-LOCAL_NO_STANDARD_LIBRARIES := true
-#LOCAL_JAVA_LIBRARIES := core
-#LOCAL_STATIC_JAVA_LIBRARIES := libgoogleclient
-
-LOCAL_MODULE := xmlwriter
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRecorder.java b/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRecorder.java
deleted file mode 100644
index f06eafd..0000000
--- a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRecorder.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * 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 com.android.monkeyrunner;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-import org.jheer.XMLWriter;
-
-/**
- * MonkeyRecorder is a host side class that records the output of scripts that are run.
- * It creates a unique directory, puts in an xml file that records each cmd and result.
- * It stores every screenshot in this directory.
- * When finished, it zips this all up.
- *
- * Calling Sequence:
- * mr = new MonkeyRecorder(scriptName);
- * mr.startCommand();
- * [mr.addAttribute(name, value);]
- * ...
- * [mr.addInput(cmd);]
- * [mr.addResults(result, filename);] // filename = "" if no screenshot
- * mr.endCommand();
- * mr.addComment(comment);
- * mr.startCommand();
- * ...
- * mr.endCommand();
- * ...
- * mr.close();
- *
- * With MonkeyRunner this should output an xml file, <script_name>-yyyyMMdd-HH:mm:ss.xml, into the
- * directory out/<script_name>-yyyyMMdd-HH:mm:ss with the contents like:
- *
- * <?xml version="1.0" encoding='UTF-8'?>
- * <!-- Monkey Script Results -->
- * <script_run script_name="filename" monkeyRunnerVersion="0.2">
- * <!-- Device specific variables -->
- * <device_var var_name="name" var_value="value" />
- * <device_var name="build.display" value="opal-userdebug 1.6 DRC79 14207 test-keys"/>
- * ...
- * <!-- Script commands -->
- * <command>
- * dateTime="20090921-17:08:43"
- * <input cmd="Pressing: menu"/>
- * <response result="OK" dateTime="20090921-17:08:43"/>
- * </command>
- * ...
- * <command>
- * dateTime="20090921-17:09:44"
- * <input cmd="grabscreen"/>
- * <response result="OK" dateTime="20090921-17:09:45" screenshot="home_screen-20090921-17:09:45.png"/>
- * </command>
- * ...
- * </script_run>
- *
- * And then zip it up with all the screenshots in the file: <script_name>-yyyyMMdd-HH:mm:ss.zip.
- */
-
-public class MonkeyRecorder {
-
- // xml file to store output results in
- private static String mXmlFilename;
- private static FileWriter mXmlFile;
- private static XMLWriter mXmlWriter;
-
- // unique subdirectory to put results in (screenshots and xml file)
- private static String mDirname;
- private static List<String> mScreenShotNames = new ArrayList<String>();
-
- // where we store all the results for all the script runs
- private static final String ROOT_DIR = "out";
-
- // for getting the date and time in now()
- private static final SimpleDateFormat SIMPLE_DATE_TIME_FORMAT =
- new SimpleDateFormat("yyyyMMdd-HH:mm:ss");
-
- /**
- * Create a new MonkeyRecorder that records commands and zips up screenshots for submittal
- *
- * @param scriptName filepath of the monkey script we are running
- */
- public MonkeyRecorder(String scriptName, String version) throws IOException {
- // Create directory structure to store xml file, images and zips
- File scriptFile = new File(scriptName);
- scriptName = scriptFile.getName(); // Get rid of path
- mDirname = ROOT_DIR + "/" + stripType(scriptName) + "-" + now();
- new File(mDirname).mkdirs();
-
- // Initialize xml file
- mXmlFilename = stampFilename(stripType(scriptName) + ".xml");
- initXmlFile(scriptName, version);
- }
-
- // Get the current date and time in a simple string format (used for timestamping filenames)
- private static String now() {
- return SIMPLE_DATE_TIME_FORMAT.format(Calendar.getInstance().getTime());
- }
-
- /**
- * Initialize the xml file writer
- *
- * @param scriptName filename (not path) of the monkey script, stored as attribute in the xml file
- * @param version of the monkey runner test system
- */
- private static void initXmlFile(String scriptName, String version) throws IOException {
- String[] names = new String[] { "script_name", "monkeyRunnerVersion" };
- String[] values = new String[] { scriptName, version };
- mXmlFile = new FileWriter(mDirname + "/" + mXmlFilename);
- mXmlWriter = new XMLWriter(mXmlFile);
- mXmlWriter.begin();
- mXmlWriter.comment("Monkey Script Results");
- mXmlWriter.start("script_run", names, values, names.length);
- }
-
- /**
- * Add a comment to the xml file.
- *
- * @param comment comment to add to the xml file
- */
- public static void addComment(String comment) throws IOException {
- mXmlWriter.comment(comment);
- }
-
- /**
- * Begin writing a command xml element
- */
- public static void startCommand() throws IOException {
- mXmlWriter.start("command", "dateTime", now());
- }
-
- /**
- * Write a command name attribute in a command xml element.
- * It's add as a sinlge script command could be multiple monkey commands.
- *
- * @param cmd command sent to the monkey
- */
- public static void addInput(String cmd) throws IOException {
- String name = "cmd";
- String value = cmd;
- mXmlWriter.tag("input", name, value);
- }
-
- /**
- * Write a response xml element in a command.
- * Attributes include the monkey result, datetime, and possibly screenshot filename
- *
- * @param result response of the monkey to the command
- * @param filename filename of the screen shot (or other file to be included)
- */
- public static void addResult(String result, String filename) throws IOException {
- int num_args = 2;
- String[] names = new String[3];
- String[] values = new String[3];
- names[0] = "result";
- values[0] = result;
- names[1] = "dateTime";
- values[1] = now();
- if (filename.length() != 0) {
- names[2] = "screenshot";
- values[2] = stampFilename(filename);
- addScreenShot(filename);
- num_args = 3;
- }
- mXmlWriter.tag("response", names, values, num_args);
- }
-
- /**
- * Add an attribut to an open xml element. name="escaped_value"
- *
- * @param name name of the attribute
- * @param value value of the attribute
- */
- public static void addAttribute(String name, String value) throws IOException {
- mXmlWriter.addAttribute(name, value);
- }
-
- /**
- * Add an xml device variable element. name="escaped_value"
- *
- * @param name name of the variable
- * @param value value of the variable
- */
- public static void addDeviceVar(String name, String value) throws IOException {
- String[] names = {"name", "value"};
- String[] values = {name, value};
- mXmlWriter.tag("device_var", names, values, names.length);
- }
-
- /**
- * Move the screenshot to storage and remember you did it so it can be zipped up later.
- *
- * @param filename file name of the screenshot to be stored (Not path name)
- */
- private static void addScreenShot(String filename) {
- File file = new File(filename);
- String screenShotName = stampFilename(filename);
- file.renameTo(new File(mDirname, screenShotName));
- mScreenShotNames.add(screenShotName);
- }
-
- /**
- * Finish writing a command xml element
- */
- public static void endCommand() throws IOException {
- mXmlWriter.end();
- }
-
- /**
- * Add datetime in front of filetype (the stuff after and including the last infamous '.')
- *
- * @param filename path of file to be stamped
- */
- private static String stampFilename(String filename) {
- //
- int typeIndex = filename.lastIndexOf('.');
- if (typeIndex == -1) {
- return filename + "-" + now();
- }
- return filename.substring(0, typeIndex) + "-" + now() + filename.substring(typeIndex);
- }
-
- /**
- * Strip out the file type (the stuff after and including the last infamous '.')
- *
- * @param filename path of file to be stripped of type information
- */
- private static String stripType(String filename) {
- //
- int typeIndex = filename.lastIndexOf('.');
- if (typeIndex == -1)
- return filename;
- return filename.substring(0, typeIndex);
- }
-
- /**
- * Close the monkeyRecorder by closing the xml file and zipping it up with the screenshots.
- *
- * @param filename path of file to be stripped of type information
- */
- public static void close() throws IOException {
- // zip up xml file and screenshots into ROOT_DIR.
- byte[] buf = new byte[1024];
- String zipFileName = mXmlFilename + ".zip";
- endCommand();
- mXmlFile.close();
- FileOutputStream zipFile = new FileOutputStream(ROOT_DIR + "/" + zipFileName);
- ZipOutputStream out = new ZipOutputStream(zipFile);
-
- // add the xml file
- addFileToZip(out, mDirname + "/" + mXmlFilename, buf);
-
- // Add the screenshots
- for (String filename : mScreenShotNames) {
- addFileToZip(out, mDirname + "/" + filename, buf);
- }
- out.close();
- }
-
- /**
- * Helper function to zip up a file into an open zip archive.
- *
- * @param zip the stream of the zip archive
- * @param filepath the filepath of the file to be added to the zip archive
- * @param buf storage place to stage reads of file before zipping
- */
- private static void addFileToZip(ZipOutputStream zip, String filepath, byte[] buf) throws IOException {
- FileInputStream in = new FileInputStream(filepath);
- zip.putNextEntry(new ZipEntry(filepath));
- int len;
- while ((len = in.read(buf)) > 0) {
- zip.write(buf, 0, len);
- }
- zip.closeEntry();
- in.close();
- }
-}
diff --git a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunner.java b/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunner.java
deleted file mode 100644
index 4734ba1..0000000
--- a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunner.java
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * 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 com.android.monkeyrunner;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.NullOutputReceiver;
-import com.android.ddmlib.RawImage;
-import com.android.ddmlib.Log.ILogOutput;
-import com.android.ddmlib.Log.LogLevel;
-
-import java.awt.image.BufferedImage;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.imageio.ImageIO;
-
-/**
- * MonkeyRunner is a host side application to control a monkey instance on a
- * device. MonkeyRunner provides some useful helper functions to control the
- * device as well as various other methods to help script tests.
- */
-public class MonkeyRunner {
-
- static String monkeyServer = "127.0.0.1";
- static int monkeyPort = 1080;
- static Socket monkeySocket = null;
-
- static IDevice monkeyDevice;
-
- static BufferedReader monkeyReader;
- static BufferedWriter monkeyWriter;
- static String monkeyResponse;
-
- static MonkeyRecorder monkeyRecorder;
-
- static String scriptName = null;
-
- // Obtain a suitable logger.
- private static Logger logger = Logger.getLogger("com.android.monkeyrunner");
-
- // delay between key events
- final static int KEY_INPUT_DELAY = 1000;
-
- // version of monkey runner
- final static String monkeyRunnerVersion = "0.4";
-
- // TODO: interface cmd; class xml tags; fix logger; test class/script
-
- public static void main(String[] args) throws IOException {
-
- // haven't figure out how to get below INFO...bad parent. Pass -v INFO to turn on logging
- logger.setLevel(Level.parse("WARNING"));
- processOptions(args);
-
- logger.info("initAdb");
- initAdbConnection();
- logger.info("openMonkeyConnection");
- openMonkeyConnection();
-
- logger.info("start_script");
- start_script();
-
- logger.info("ScriptRunner.run");
- ScriptRunner.run(scriptName);
-
- logger.info("end_script");
- end_script();
- logger.info("closeMonkeyConnection");
- closeMonkeyConnection();
- }
-
- /**
- * Initialize an adb session with a device connected to the host
- *
- */
- public static void initAdbConnection() {
- String adbLocation = "adb";
- boolean device = false;
- boolean emulator = false;
- String serial = null;
-
- AndroidDebugBridge.init(false /* debugger support */);
-
- try {
- AndroidDebugBridge bridge = AndroidDebugBridge.createBridge(
- adbLocation, true /* forceNewBridge */);
-
- // we can't just ask for the device list right away, as the internal thread getting
- // them from ADB may not be done getting the first list.
- // Since we don't really want getDevices() to be blocking, we wait here manually.
- int count = 0;
- while (bridge.hasInitialDeviceList() == false) {
- try {
- Thread.sleep(100);
- count++;
- } catch (InterruptedException e) {
- // pass
- }
-
- // let's not wait > 10 sec.
- if (count > 100) {
- System.err.println("Timeout getting device list!");
- return;
- }
- }
-
- // now get the devices
- IDevice[] devices = bridge.getDevices();
-
- if (devices.length == 0) {
- printAndExit("No devices found!", true /* terminate */);
- }
-
- monkeyDevice = null;
-
- if (emulator || device) {
- for (IDevice d : devices) {
- // this test works because emulator and device can't both be true at the same
- // time.
- if (d.isEmulator() == emulator) {
- // if we already found a valid target, we print an error and return.
- if (monkeyDevice != null) {
- if (emulator) {
- printAndExit("Error: more than one emulator launched!",
- true /* terminate */);
- } else {
- printAndExit("Error: more than one device connected!",true /* terminate */);
- }
- }
- monkeyDevice = d;
- }
- }
- } else if (serial != null) {
- for (IDevice d : devices) {
- if (serial.equals(d.getSerialNumber())) {
- monkeyDevice = d;
- break;
- }
- }
- } else {
- if (devices.length > 1) {
- printAndExit("Error: more than one emulator or device available!",
- true /* terminate */);
- }
- monkeyDevice = devices[0];
- }
-
- monkeyDevice.createForward(monkeyPort, monkeyPort);
- String command = "monkey --port " + monkeyPort;
- monkeyDevice.executeShellCommand(command, new NullOutputReceiver());
-
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Open a tcp session over adb with the device to communicate monkey commands
- */
- public static void openMonkeyConnection() {
- try {
- InetAddress addr = InetAddress.getByName(monkeyServer);
- monkeySocket = new Socket(addr, monkeyPort);
- monkeyWriter = new BufferedWriter(new OutputStreamWriter(monkeySocket.getOutputStream()));
- monkeyReader = new BufferedReader(new InputStreamReader(monkeySocket.getInputStream()));
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Close tcp session with the monkey on the device
- *
- */
- public static void closeMonkeyConnection() {
- try {
- monkeyReader.close();
- monkeyWriter.close();
- monkeySocket.close();
- AndroidDebugBridge.terminate();
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * This is a house cleaning routine to run before starting a script. Puts
- * the device in a known state and starts recording interesting info.
- */
- public static void start_script() throws IOException {
- press("menu", false);
- press("menu", false);
- press("home", false);
-
- // Start recording the script output, might want md5 signature of file for completeness
- monkeyRecorder = new MonkeyRecorder(scriptName, monkeyRunnerVersion);
-
- // Record what device we are running on
- addDeviceVars();
- monkeyRecorder.addComment("Script commands");
- }
-
- /**
- * This is a house cleaning routine to run after finishing a script.
- * Puts the monkey server in a known state and closes the recording.
- */
- public static void end_script() throws IOException {
- String command = "done";
- sendMonkeyEvent(command, false, false);
-
- // Stop the recording and zip up the results
- monkeyRecorder.close();
- }
-
- /** This is a method for scripts to launch an activity on the device
- *
- * @param name The name of the activity to launch
- */
- public static void launch_activity(String name) throws IOException {
- System.out.println("Launching: " + name);
- recordCommand("Launching: " + name);
- monkeyDevice.executeShellCommand("am start -a android.intent.action.MAIN -n "
- + name, new NullOutputReceiver());
- // void return, so no response given, just close the command element in the xml file.
- monkeyRecorder.endCommand();
- }
-
- /**
- * Grabs the current state of the screen stores it as a png
- *
- * @param tag filename or tag descriptor of the screenshot
- */
- public static void grabscreen(String tag) throws IOException {
- tag += ".png";
-
- try {
- Thread.sleep(1000);
- getDeviceImage(monkeyDevice, tag, false);
- } catch (InterruptedException e) {
- }
- }
-
- /**
- * Sleeper method for script to call
- *
- * @param msec msecs to sleep for
- */
- public static void sleep(int msec) throws IOException {
- try {
- recordCommand("sleep: " + msec);
- Thread.sleep(msec);
- recordResponse("OK");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Tap function for scripts to call at a particular x and y location
- *
- * @param x x-coordinate
- * @param y y-coordinate
- */
- public static boolean tap(int x, int y) throws IOException {
- String command = "tap " + x + " " + y;
- boolean result = sendMonkeyEvent(command);
- return result;
- }
-
- /**
- * Press function for scripts to call on a particular button or key
- *
- * @param key key to press
- */
- public static boolean press(String key) throws IOException {
- return press(key, true);
- }
-
- /**
- * Press function for scripts to call on a particular button or key
- *
- * @param key key to press
- * @param print whether to send output to user
- */
- private static boolean press(String key, boolean print) throws IOException {
- String command = "press " + key;
- boolean result = sendMonkeyEvent(command, print, true);
- return result;
- }
-
- /**
- * dpad down function
- */
- public static boolean down() throws IOException {
- return press("dpad_down");
- }
-
- /**
- * dpad up function
- */
- public static boolean up() throws IOException {
- return press("dpad_up");
- }
-
- /**
- * Function to type text on the device
- *
- * @param text text to type
- */
- public static boolean type(String text) throws IOException {
- boolean result = false;
- // text might have line ends, which signal new monkey command, so we have to eat and reissue
- String[] lines = text.split("[\\r\\n]+");
- for (String line: lines) {
- result = sendMonkeyEvent("type " + line + "\n");
- }
- // return last result. Should never fail..?
- return result;
- }
-
- /**
- * Function to get a static variable from the device
- *
- * @param name name of static variable to get
- */
- public static boolean getvar(String name) throws IOException {
- return sendMonkeyEvent("getvar " + name + "\n");
- }
-
- /**
- * Function to get the list of static variables from the device
- */
- public static boolean listvar() throws IOException {
- return sendMonkeyEvent("listvar \n");
- }
-
- /**
- * This function is the communication bridge between the host and the device.
- * It sends monkey events and waits for responses over the adb tcp socket.
- * This version if for all scripted events so that they get recorded and reported to user.
- *
- * @param command the monkey command to send to the device
- */
- private static boolean sendMonkeyEvent(String command) throws IOException {
- return sendMonkeyEvent(command, true, true);
- }
-
- /**
- * This function allows the communication bridge between the host and the device
- * to be invisible to the script for internal needs.
- * It splits a command into monkey events and waits for responses for each over an adb tcp socket.
- * Returns on an error, else continues and sets up last response.
- *
- * @param command the monkey command to send to the device
- * @param print whether to print out the responses to the user
- * @param record whether to put the command in the xml file that stores test outputs
- */
- private static boolean sendMonkeyEvent(String command, Boolean print, Boolean record) throws IOException {
- command = command.trim();
- if (print)
- System.out.println("MonkeyCommand: " + command);
- if (record)
- recordCommand(command);
- logger.info("Monkey Command: " + command + ".");
-
- // send a single command and get the response
- monkeyWriter.write(command + "\n");
- monkeyWriter.flush();
- monkeyResponse = monkeyReader.readLine();
-
- if(monkeyResponse != null) {
- // if a command returns with a response
- if (print)
- System.out.println("MonkeyServer: " + monkeyResponse);
- if (record)
- recordResponse(monkeyResponse);
- logger.info("Monkey Response: " + monkeyResponse + ".");
-
- // return on error
- if (monkeyResponse.startsWith("ERROR"))
- return false;
-
- // return on ok
- if(monkeyResponse.startsWith("OK"))
- return true;
-
- // return on something else?
- return false;
- }
- // didn't get a response...
- if (print)
- System.out.println("MonkeyServer: ??no response");
- if (record)
- recordResponse("??no response");
- logger.info("Monkey Response: ??no response.");
-
- //return on no response
- return false;
- }
-
- /**
- * Record the command in the xml file
- *
- * @param command the command sent to the monkey server
- */
- private static void recordCommand(String command) throws IOException {
- if (monkeyRecorder != null) { // don't record setup junk
- monkeyRecorder.startCommand();
- monkeyRecorder.addInput(command);
- }
- }
-
- /**
- * Record the response in the xml file
- *
- * @param response the response sent by the monkey server
- */
- private static void recordResponse(String response) throws IOException {
- recordResponse(response, "");
- }
-
- /**
- * Record the response and the filename in the xml file, store the file (to be zipped up later)
- *
- * @param response the response sent by the monkey server
- * @param filename the filename of a file to be time stamped, recorded in the xml file and stored
- */
- private static void recordResponse(String response, String filename) throws IOException {
- if (monkeyRecorder != null) { // don't record setup junk
- monkeyRecorder.addResult(response, filename); // ignores file if filename empty
- monkeyRecorder.endCommand();
- }
- }
-
- /**
- * Add the device variables to the xml file in monkeyRecorder.
- * The results get added as device_var tags in the script_run tag
- */
- private static void addDeviceVars() throws IOException {
- monkeyRecorder.addComment("Device specific variables");
- sendMonkeyEvent("listvar \n", false, false);
- if (monkeyResponse.startsWith("OK:")) {
- // peel off "OK:" string and get the individual var names
- String[] varNames = monkeyResponse.substring(3).split("\\s+");
- // grab all the individual var values
- for (String name: varNames) {
- sendMonkeyEvent("getvar " + name, false, false);
- if(monkeyResponse != null) {
- if (monkeyResponse.startsWith("OK") ) {
- if (monkeyResponse.length() > 2) {
- monkeyRecorder.addDeviceVar(name, monkeyResponse.substring(3));
- } else {
- // only got OK - good variable but no value
- monkeyRecorder.addDeviceVar(name, "null");
- }
- } else {
- // error returned - couldn't get var value for name... include error return
- monkeyRecorder.addDeviceVar(name, monkeyResponse);
- }
- } else {
- // no monkeyResponse - bad variable with no value
- monkeyRecorder.addDeviceVar(name, "null");
- }
- }
- } else {
- // it's an error, can't find variable names...
- monkeyRecorder.addAttribute("listvar", monkeyResponse);
- }
- }
-
- /**
- * Process the command-line options
- *
- * @return Returns true if options were parsed with no apparent errors.
- */
- private static void processOptions(String[] args) {
- // parse command line parameters.
- int index = 0;
-
- do {
- String argument = args[index++];
-
- if ("-s".equals(argument)) {
- if(index == args.length) {
- printUsageAndQuit("Missing Server after -s");
- }
-
- monkeyServer = args[index++];
-
- } else if ("-p".equals(argument)) {
- // quick check on the next argument.
- if (index == args.length) {
- printUsageAndQuit("Missing Server port after -p");
- }
-
- monkeyPort = Integer.parseInt(args[index++]);
-
- } else if ("-v".equals(argument)) {
- // quick check on the next argument.
- if (index == args.length) {
- printUsageAndQuit("Missing Log Level after -v");
- }
-
- Level level = Level.parse(args[index++]);
- logger.setLevel(level);
- level = logger.getLevel();
- System.out.println("Log level set to: " + level + "(" + level.intValue() + ").");
- System.out.println("Warning: Log levels below INFO(800) not working currently... parent issues");
-
- } else if (argument.startsWith("-")) {
- // we have an unrecognized argument.
- printUsageAndQuit("Unrecognized argument: " + argument + ".");
-
- monkeyPort = Integer.parseInt(args[index++]);
-
- } else {
- // get the filepath of the script to run. This will be the last undashed argument.
- scriptName = argument;
- }
- } while (index < args.length);
- }
-
- /*
- * Grab an image from an ADB-connected device.
- */
- private static void getDeviceImage(IDevice device, String filepath, boolean landscape)
- throws IOException {
- RawImage rawImage;
- recordCommand("grabscreen");
- System.out.println("Grabbing Screeshot: " + filepath + ".");
-
- try {
- rawImage = device.getScreenshot();
- }
- catch (IOException ioe) {
- recordResponse("No frame buffer", "");
- printAndExit("Unable to get frame buffer: " + ioe.getMessage(), true /* terminate */);
- return;
- }
-
- // device/adb not available?
- if (rawImage == null) {
- recordResponse("No image", "");
- return;
- }
-
- assert rawImage.bpp == 16;
-
- BufferedImage image;
-
- logger.info("Raw Image - height: " + rawImage.height + ", width: " + rawImage.width);
-
- if (landscape) {
- // convert raw data to an Image
- image = new BufferedImage(rawImage.height, rawImage.width,
- BufferedImage.TYPE_INT_ARGB);
-
- byte[] buffer = rawImage.data;
- int index = 0;
- for (int y = 0 ; y < rawImage.height ; y++) {
- for (int x = 0 ; x < rawImage.width ; x++) {
-
- int value = buffer[index++] & 0x00FF;
- value |= (buffer[index++] << 8) & 0x0FF00;
-
- int r = ((value >> 11) & 0x01F) << 3;
- int g = ((value >> 5) & 0x03F) << 2;
- int b = ((value >> 0) & 0x01F) << 3;
-
- value = 0xFF << 24 | r << 16 | g << 8 | b;
-
- image.setRGB(y, rawImage.width - x - 1, value);
- }
- }
- } else {
- // convert raw data to an Image
- image = new BufferedImage(rawImage.width, rawImage.height,
- BufferedImage.TYPE_INT_ARGB);
-
- byte[] buffer = rawImage.data;
- int index = 0;
- for (int y = 0 ; y < rawImage.height ; y++) {
- for (int x = 0 ; x < rawImage.width ; x++) {
-
- int value = buffer[index++] & 0x00FF;
- value |= (buffer[index++] << 8) & 0x0FF00;
-
- int r = ((value >> 11) & 0x01F) << 3;
- int g = ((value >> 5) & 0x03F) << 2;
- int b = ((value >> 0) & 0x01F) << 3;
-
- value = 0xFF << 24 | r << 16 | g << 8 | b;
-
- image.setRGB(x, y, value);
- }
- }
- }
-
- if (!ImageIO.write(image, "png", new File(filepath))) {
- recordResponse("No png writer", "");
- throw new IOException("Failed to find png writer");
- }
- recordResponse("OK", filepath);
- }
-
- private static void printUsageAndQuit(String message) {
- // 80 cols marker: 01234567890123456789012345678901234567890123456789012345678901234567890123456789
- System.out.println(message);
- System.out.println("Usage: monkeyrunner [options] SCRIPT_FILE");
- System.out.println("");
- System.out.println(" -s MonkeyServer IP Address.");
- System.out.println(" -p MonkeyServer TCP Port.");
- System.out.println(" -v MonkeyServer Logging level (ALL, FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE, OFF)");
- System.out.println("");
- System.out.println("");
-
- System.exit(1);
- }
-
- private static void printAndExit(String message, boolean terminate) {
- System.out.println(message);
- if (terminate) {
- AndroidDebugBridge.terminate();
- }
- System.exit(1);
- }
-}
diff --git a/tools/monkeyrunner/src/com/android/monkeyrunner/ScriptRunner.java b/tools/monkeyrunner/src/com/android/monkeyrunner/ScriptRunner.java
deleted file mode 100644
index 6a4405b..0000000
--- a/tools/monkeyrunner/src/com/android/monkeyrunner/ScriptRunner.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.android.monkeyrunner;
-
-import org.python.core.Py;
-import org.python.core.PyObject;
-import org.python.util.PythonInterpreter;
-import org.python.util.InteractiveConsole;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.lang.RuntimeException;
-import java.util.Properties;
-
-
-/**
- * Runs Jython based scripts.
- */
-public class ScriptRunner {
-
- /** The "this" scope object for scripts. */
- private final Object scope;
- private final String variable;
-
- /** Private constructor. */
- private ScriptRunner(Object scope, String variable) {
- this.scope = scope;
- this.variable = variable;
- }
-
- /** Creates a new instance for the given scope object. */
- public static ScriptRunner newInstance(Object scope, String variable) {
- return new ScriptRunner(scope, variable);
- }
-
- /**
- * Runs the specified Jython script. First runs the initialization script to
- * preload the appropriate client library version.
- */
- public static void run(String scriptfilename) {
- try {
- initPython();
- PythonInterpreter python = new PythonInterpreter();
-
- python.execfile(scriptfilename);
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
-
-
- /** Initialize the python interpreter. */
- private static void initPython() {
- Properties props = new Properties();
- // Default is 'message' which displays sys-package-mgr bloat
- // Choose one of error,warning,message,comment,debug
- props.setProperty("python.verbose", "error");
- props.setProperty("python.path", System.getProperty("java.class.path"));
- PythonInterpreter.initialize(System.getProperties(), props, new String[] {""});
- }
-
- /**
- * Create and run a console using a new python interpreter for the test
- * associated with this instance.
- */
- public void console() throws IOException {
- initPython();
- InteractiveConsole python = new InteractiveConsole();
- initInterpreter(python, scope, variable);
- python.interact();
- }
-
- /**
- * Start an interactive python interpreter using the specified set of local
- * variables. Use this to interrupt a running test script with a prompt:
- *
- * @param locals
- */
- public static void console(PyObject locals) {
- initPython();
- InteractiveConsole python = new InteractiveConsole(locals);
- python.interact();
- }
-
- /**
- * Initialize a python interpreter.
- *
- * @param python
- * @param scope
- * @throws IOException
- */
- public static void initInterpreter(PythonInterpreter python, Object scope, String variable)
- throws IOException {
- // Store the current test case as the this variable
- python.set(variable, scope);
- }
-}