Uploaded by Linkel Rae Lee

code

advertisement
AdIntegrator.java
package com.buildbox;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
import
java.lang.ref.WeakReference;
public class AdIntegrator {
public static native
boolean
rewardedVideoDidEnd();
private static
WeakReference<Cocos2dxAc
tivity> activity;
public static void
initBridge(Cocos2dxActivity
act){
activity = new
WeakReference<Cocos2dxAc
tivity>(act);
}
public static void initAds(){
}
public static void
showBanner(){
}
public static void
hideBanner(){
}
public static boolean
isBannerVisible(){
return true;
}
public static boolean
isRewardedVideoAvialable(){
return true;
}
public static void
showInterstitial(){
}
public static void
showRewardedVideo(){
}
}
PTPlayer.java
package com.hhhhhhhh.hhh;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
import
org.cocos2dx.lib.Cocos2dxGL
SurfaceView;
import
org.cocos2dx.lib.Cocos2dxRe
flectionHelper;
import android.os.Build;
import android.view.View;
import
android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import
android.view.WindowManag
er;
import android.widget.Toast;
import
com.buildbox.AdIntegrator;
import
com.secrethq.store.PTStoreB
ridge;
import
com.google.android.gms.ga
mes.GamesActivityResultCod
es;
import com.secrethq.ads.*;
import com.secrethq.utils.*;
import
android.content.SharedPrefe
rences;
import
android.content.Context;
public class PTPlayer extends
Cocos2dxActivity {
protected void
onActivityResult(int
requestCode, int resultCode,
Intent data) {
super.onActivityResult(reque
stCode, resultCode, data);
try {
Log.v("---------","onActivityResult: request:
" + requestCode + " result: "+
resultCode);
if(PTStoreBridge.iabHelper().
handleActivityResult(request
Code, resultCode, data)
Log.v("----------", "handled by
IABHelper");
}
else
if(requestCode ==
PTServicesBridge.RC_SIGN_I
N){
SharedPreferences
sharedPref =
this.getPreferences(Context.
MODE_PRIVATE);
SharedPreferences.E
ditor editor =
sharedPref.edit();
if(resultCode ==
RESULT_OK){
PTServicesBridge.inst
ance().onActivityResult(requ
estCode, resultCode, data);
editor.putBoolean("
GooglePlayServiceSignInError
", false);
editor.commit();
}
else
if(resultCode ==
GamesActivityResultCodes.R
ESULT_SIGN_IN_FAILED){
int duration =
Toast.LENGTH_SHORT;
Toast toast =
Toast.makeText(this, "Google
Play Services: Sign in error",
duration);
toast.show();
editor.putBoolean("
GooglePlayServiceSignInError
", true);
editor.commit();
}
else
if(resultCode ==
GamesActivityResultCodes.R
ESULT_APP_MISCONFIGURE
D){
getWindow().addFla
gs(WindowManager.LayoutP
arams.FLAG_KEEP_SCREEN_
ON);
}
@Override
public void
onNativeInit(){
initBridges();
int duration =
Toast.LENGTH_SHORT;
private void
initBridges(){
AdIntegrator.initBridge(
this );
toast.show();
PTStoreBridge.initBri
dge( this );
e) {
Log.v("-----------",
"onActivityResult FAIL on
iabHelper : " + e.toString());
}
}
protected void
onCreate(Bundle
savedInstanceState) {
super.onCreate(save
dInstanceState);
this.hideVirtualButto
n();
PTServicesBridge.init
Bridge(this, getString(
R.string.app_id ));
PTAdAdMobBridge.i
nitBridge(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kAppLovin")) {
}
Toast toast =
Toast.makeText(this, "Google
Play Services: App
misconfigured", duration);
}
}
} catch (Exception
if
(PTJniHelper.isAdNetworkAct
ive("kAdMob") ||
PTJniHelper.isAdNetworkActi
ve("kFacebook")) {
if
(PTJniHelper.isAdNetworkAct
ive("kChartboost")) {
PTAdChartboostBrid
ge.initBridge(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kRevMob")) {
PTAdRevMobBridge.i
nitBridge(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kInMobi")) {
PTAdInMobiBridge.initBridge
(this);
}
PTAdAppLovinBridge
.initBridge(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kLeadBolt")) {
PTAdLeadBoltBridge.
initBridge(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kFacebook")) {
PTAdFacebookBridge
.initBridge(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kHeyzap")) {
PTAdHeyzapBridge.in
itBridge(this);
}
}
@Override
public
Cocos2dxGLSurfaceView
onCreateView() {
}
Cocos2dxGLSurfaceV
iew glSurfaceView = new
Cocos2dxGLSurfaceView(this
);
glSurfaceView.setEG
LConfigChooser(8, 8, 8, 0, 0,
0);
return
glSurfaceView;
}
static {
System.loadLibrary("
player");
}
@Override
protected void
onResume() {
}
@Override
protected void
onStart() {
final
int
SYSTEM_UI_FLAG_LAYOUT_
HIDE_NAVIGATION =
Cocos2dxReflectionHelper
super.onStart();
if
(PTJniHelper.isAdNetworkAct
ive("kChartboost")) {
.<Integer>
getConstantValue(viewClass,
PTAdChartboostBrid
ge.onStart( this );
}
}
@Override
protected void
onStop() {
n();
super.onStop();
if
(PTJniHelper.isAdNetworkAct
ive("kChartboost")) {
super.onResume();
if
(PTJniHelper.isAdNetworkAct
ive("kChartboost")) {
PTAdChartboostBrid
ge.onStop( this );
}
}
PTAdChartboostBrid
ge.onResume( this );
}
}
@Override
protected void
onDestroy() {
this.hideVirtualButto
@Override
public void
onWindowFocusChanged(bo
olean hasFocus) {
super.onWindowFoc
usChanged(hasFocus);
if (hasFocus)
{
this.hideVirtualButto
n();
Class
viewClass = View.class;
"SYSTEM_UI_FLAG_L
AYOUT_HIDE_NAVIGATION")
;
final
int
SYSTEM_UI_FLAG_LAYOUT_F
ULLSCREEN =
Cocos2dxReflectionHelper
.<Integer>
getConstantValue(viewClass,
"SYSTEM_UI_FLAG_L
AYOUT_FULLSCREEN");
final
int
SYSTEM_UI_FLAG_HIDE_NAV
IGATION =
Cocos2dxReflectionHelper
.<Integer>
getConstantValue(viewClass,
super.onDestroy();
}
protected void
hideVirtualButton() {
if
(Build.VERSION.SDK_INT >=
19) {
//
use reflection to remove
dependence of API level
"SYSTEM_UI_FLAG_
HIDE_NAVIGATION");
final
int
SYSTEM_UI_FLAG_FULLSCRE
EN =
Cocos2dxReflectionHelper
.<Integer>
getConstantValue(viewClass,
SYSTEM_UI_FLAG_HIDE_NAV
IGATION // hide nav bar
"SYSTEM_UI_FLAG_F
ULLSCREEN");
final
int
SYSTEM_UI_FLAG_IMMERSIV
E_STICKY =
Cocos2dxReflectionHelper
.<Integer>
getConstantValue(viewClass,
"SYSTEM_UI_FLAG_I
MMERSIVE_STICKY");
final
int
SYSTEM_UI_FLAG_LAYOUT_S
TABLE =
Cocos2dxReflectionHelper
.<Integer>
getConstantValue(viewClass,
"SYSTEM_UI_FLAG_L
AYOUT_STABLE");
//
getWindow().getDecorView()
.setSystemUiVisibility();
final
Object[] parameters = new
Object[] {
SYSTEM_UI_FLAG_LAYOUT_S
TABLE
|
SYSTEM_UI_FLAG_LAYOUT_
HIDE_NAVIGATION
|
SYSTEM_UI_FLAG_LAYOUT_F
ULLSCREEN
|
|
SYSTEM_UI_FLAG_FULLSCRE
EN // hide status bar
|
SYSTEM_UI_FLAG_IMMERSIV
E_STICKY };
Cocos2dxReflectionH
elper.<Void>
invokeInstanceMethod(getW
indow()
.getDecorView(),
"setSystemUiVisibility",
new Class[] {
Integer.TYPE }, parameters);
}
}
}
PTAdAdMobBridge.java
package com.hhhhhhhh.hhh;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
import
org.cocos2dx.lib.Cocos2dxGL
SurfaceView;
import
org.cocos2dx.lib.Cocos2dxRe
flectionHelper;
import android.os.Build;
import android.view.View;
import
android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import
android.view.WindowManag
er;
import android.widget.Toast;
import
com.buildbox.AdIntegrator;
import
com.secrethq.store.PTStoreB
ridge;
import
com.google.android.gms.ga
mes.GamesActivityResultCod
es;
import com.secrethq.ads.*;
import com.secrethq.utils.*;
import
android.content.SharedPrefe
rences;
import
android.content.Context;
public class PTPlayer extends
Cocos2dxActivity {
protected void
onActivityResult(int
requestCode, int resultCode,
Intent data) {
super.onActivityResult(reque
stCode, resultCode, data);
try {
Log.v("---------","onActivityResult:
request: " + requestCode + "
result: "+ resultCode);
if(PTStoreBridge.iabHelper().
handleActivityResult(request
Code, resultCode, data)){
Log.v("-----------",
"handled by IABHelper");
}
else
if(requestCode ==
PTServicesBridge.RC_SIGN_I
N){
SharedPreferences
sharedPref =
this.getPreferences(Context.
MODE_PRIVATE);
else
if(resultCode ==
GamesActivityResultCodes.R
ESULT_APP_MISCONFIGURE
D){
@Override
public void
onNativeInit(){
initBridges();
SharedPreferences.E
ditor editor =
sharedPref.edit();
if(resultCode ==
RESULT_OK){
int duration =
Toast.LENGTH_SHORT;
Toast toast =
Toast.makeText(this, "Google
Play Services: App
misconfigured", duration);
private void
initBridges(){
AdIntegrator.initBridge(
this );
toast.show();
PTStoreBridge.initBri
dge( this );
PTServicesBridge.inst
ance().onActivityResult(requ
estCode, resultCode, data);
editor.putBoolean("
GooglePlayServiceSignInError
", false);
editor.commit();
}
else
if(resultCode ==
GamesActivityResultCodes.R
ESULT_SIGN_IN_FAILED){
int duration =
Toast.LENGTH_SHORT;
Toast toast =
Toast.makeText(this, "Google
Play Services: Sign in error",
duration);
}
}
} catch (Exception
e) {
if
(PTJniHelper.isAdNetworkAct
ive("kChartboost")) {
Log.v("-----------",
"onActivityResult FAIL on
iabHelper : " + e.toString());
}
}
PTAdChartboostBrid
ge.initBridge(this);
}
protected void
onCreate(Bundle
savedInstanceState) {
super.onCreate(save
dInstanceState);
this.hideVirtualButto
n();
toast.show();
editor.putBoolean("
GooglePlayServiceSignInError
", true);
editor.commit();
}
}
PTServicesBridge.init
Bridge(this, getString(
R.string.app_id ));
getWindow().addFla
gs(WindowManager.LayoutP
arams.FLAG_KEEP_SCREEN_
ON);
}
if
(PTJniHelper.isAdNetworkAct
ive("kRevMob")) {
PTAdRevMobBridge.i
nitBridge(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kInMobi")) {
PTAdInMobiBridge.initBridge
(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kAdMob") ||
PTJniHelper.isAdNetworkActi
ve("kFacebook")) {
PTAdAdMobBridge.i
nitBridge(this);
}
glSurfaceView.setEG
LConfigChooser(8, 8, 8, 0, 0,
0);
if
(PTJniHelper.isAdNetworkAct
ive("kAppLovin")) {
glSurfaceView;
}
PTAdAppLovinBridge
.initBridge(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kLeadBolt")) {
PTAdLeadBoltBridge.
initBridge(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kFacebook")) {
PTAdFacebookBridge
.initBridge(this);
}
if
(PTJniHelper.isAdNetworkAct
ive("kHeyzap")) {
PTAdHeyzapBridge.in
itBridge(this);
}
}
@Override
public
Cocos2dxGLSurfaceView
onCreateView() {
return
static {
System.loadLibrary("
player");
}
@Override
protected void
onResume() {
protected void
onStart() {
super.onStart();
if
(PTJniHelper.isAdNetworkAct
ive("kChartboost")) {
PTAdChartboostBrid
ge.onStart( this );
}
}
@Override
protected void
onStop() {
n();
super.onStop();
if
(PTJniHelper.isAdNetworkAct
ive("kChartboost")) {
super.onResume();
if
(PTJniHelper.isAdNetworkAct
ive("kChartboost")) {
PTAdChartboostBrid
ge.onStop( this );
}
}
PTAdChartboostBrid
ge.onResume( this );
}
}
@Override
protected void
onDestroy() {
this.hideVirtualButto
@Override
public void
onWindowFocusChanged(bo
olean hasFocus) {
super.onWindowFoc
usChanged(hasFocus);
if (hasFocus)
{
super.onDestroy();
}
protected void
hideVirtualButton() {
if
(Build.VERSION.SDK_INT >=
19) {
//
use reflection to remove
dependence of API level
this.hideVirtualButto
Cocos2dxGLSurfaceV
iew glSurfaceView = new
Cocos2dxGLSurfaceView(this
);
n();
Class
}
}
@Override
viewClass = View.class;
final
int
SYSTEM_UI_FLAG_LAYOUT_
HIDE_NAVIGATION =
Cocos2dxReflectionHelper
.<Integer>
getConstantValue(viewClass,
SYSTEM_UI_FLAG_IMMERSIV
E_STICKY =
Cocos2dxReflectionHelper
.<Integer>
getConstantValue(viewClass,
"SYSTEM_UI_FLAG_L
AYOUT_HIDE_NAVIGATION")
;
final
int
SYSTEM_UI_FLAG_LAYOUT_F
ULLSCREEN =
Cocos2dxReflectionHelper
"SYSTEM_UI_FLAG_I
MMERSIVE_STICKY");
final
int
SYSTEM_UI_FLAG_LAYOUT_S
TABLE =
Cocos2dxReflectionHelper
.<Integer>
getConstantValue(viewClass,
.<Integer>
getConstantValue(viewClass,
"SYSTEM_UI_FLAG_L
AYOUT_FULLSCREEN");
final
int
SYSTEM_UI_FLAG_HIDE_NAV
IGATION =
Cocos2dxReflectionHelper
"SYSTEM_UI_FLAG_L
AYOUT_STABLE");
.<Integer>
getConstantValue(viewClass,
//
getWindow().getDecorView()
.setSystemUiVisibility();
final
Object[] parameters = new
Object[] {
SYSTEM_UI_FLAG_LAYOUT_S
TABLE
"SYSTEM_UI_FLAG_
HIDE_NAVIGATION");
final
int
SYSTEM_UI_FLAG_FULLSCRE
EN =
Cocos2dxReflectionHelper
|
SYSTEM_UI_FLAG_LAYOUT_
HIDE_NAVIGATION
.<Integer>
getConstantValue(viewClass,
|
SYSTEM_UI_FLAG_HIDE_NAV
IGATION // hide nav bar
"SYSTEM_UI_FLAG_F
ULLSCREEN");
final
int
|
SYSTEM_UI_FLAG_FULLSCRE
EN // hide status bar
|
SYSTEM_UI_FLAG_LAYOUT_F
ULLSCREEN
|
SYSTEM_UI_FLAG_IMMERSIV
E_STICKY };
Cocos2dxReflectionH
elper.<Void>
invokeInstanceMethod(getW
indow()
.getDecorView(),
"setSystemUiVisibility",
new Class[] {
Integer.TYPE }, parameters);
}
}
}
PTAdAppLovinBridge.java
package com.secrethq.ads;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
public class
PTAdAppLovinBridge {
public static void
initBridge(Cocos2dxActivity
activity){
}
public static void
startSession( String sdkKey ){
}
public static void
showFullScreen() {
}
public static void
showPopup() {
}
public static void
showBannerAd(){
}
public static void
hideBannerAd(){
}
}
PTAdChartboostBridge.java
package com.secrethq.ads;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
import android.app.Activity;
public class
PTAdChartboostBridge {
public static void
initBridge(Cocos2dxActivity
activity){
}
public static void
cacheInterstitial(final String
location) {
}
public static void
showInterstitial() {
}
public static void
showInterstitial(final String
location) {
}
public static void
onResume( Activity act){
}
public static void
onStart( Activity act){
}
public static void
onStop( Activity act){
}
}
PTAdFacebookBridge
package com.secrethq.ads;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
public class
PTAdFacebookBridge {
public static void
initBridge(Cocos2dxActivity
activity){
}
public static void
initBanner(){
}
public static void
initInterstitial(){
}
public static void
showFullScreen(){
}
public static void
showBannerAd(){
}
public static void
hideBannerAd(){
}
public static boolean
isBannerVisisble() {
return false;
}
}
PTAdHeyzapBridge.java
package com.secrethq.ads;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
public class
PTAdHeyzapBridge {
public static void
initBridge(Cocos2dxActivity
activity){
}
public static void
initBanner(){
}
public static void
initInterstitial(){
}
public static void
initVideo() {
}
public static void
startSession( String sdkKey ){
}
public static void
showFullScreen(){
}
public static void
showBannerAd(){
}
public static void
showRewardedVideo(){
}
public static void
hideBannerAd(){
}
public static boolean
isBannerVisisble() {
return false;
}
public static boolean
isRewardedVideoAvialable(){
return false;
}
}
PTAdInMobiBridge.java
package com.secrethq.ads;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
import android.app.Activity;
public class
PTAdInMobiBridge {
public static void
initBridge(Cocos2dxActivity
activity){
}
public static void
showBanner() {
}
public static void
hideBanner() {
}
public static void
showInterstitial() {
}
}
PTAdLeadBoltBridge.java
package com.secrethq.ads;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
public class
PTAdLeadBoltBridge {
public static void
hideBannerAd(){
}
}
PTAdRevMobBridge.java
package com.secrethq.ads;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
public class
PTAdRevMobBridge {
public static void
initBridge(Cocos2dxActivity
activity){
}
public static void
startSession( String appid ){
}
public static void
showFullScreen(){
}
public static void
initBridge(Cocos2dxActivity
activity){
}
public static void
showPopup(){
}
public static void
startSession( String sdkKey ){
}
public static void
showBannerAd(){
}
public static void
showFullScreen() {
}
public static void
hideBannerAd(){
}
public static void
showPopup() {
}
}
Base64.java
package com.secrethq.ads;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
public static void
showBannerAd(){
}
public class
PTAdRevMobBridge {
public static void
initBridge(Cocos2dxActivity
activity){
}
public static void
startSession( String appid ){
}
public static void
showFullScreen(){
}
public static void
showPopup(){
}
public static void
showBannerAd(){
}
public static void
hideBannerAd(){
}
}
Base64DecoderException.ja
va
// Copyright 2002, Google,
Inc.
//
// 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/licen
ses/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.secrethq.store.util;
/**
* Exception thrown when
encountering an invalid
Base64 input character.
*
* @author nelson
*/
public class
Base64DecoderException
extends Exception {
public
Base64DecoderException() {
super();
}
public
Base64DecoderException(Str
ing s) {
super(s);
}
private static final long
serialVersionUID = 1L;
}
IabException.java
/* Copyright (c) 2012 Google
Inc.
*
* 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/licen
ses/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.secrethq.store.util;
/**
* Exception thrown when
something went wrong with
in-app billing.
* An IabException has an
associated IabResult (an
error).
* To get the IAB result that
caused this exception to be
thrown,
* call {@link #getResult()}.
*/
public class IabException
extends Exception {
IabResult mResult;
public
IabException(IabResult r) {
this(r, null);
}
public IabException(int
response, String message) {
this(new
IabResult(response,
message));
}
public
IabException(IabResult r,
Exception cause) {
super(r.getMessage(),
cause);
mResult = r;
}
public IabException(int
response, String message,
Exception cause) {
this(new
IabResult(response,
message), cause);
}
/** Returns the IAB result
(error) that this exception
signals. */
public IabResult
getResult() { return mResult;
}
}
IabHelper.java
/* Copyright (c) 2012 Google
Inc.
*
* 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/licen
ses/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.secrethq.store.util;
import android.app.Activity;
import
android.app.PendingIntent;
import
android.content.Component
Name;
import
android.content.Context;
import
android.content.Intent;
import
android.content.IntentSende
r.SendIntentException;
import
android.content.ServiceConn
ection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import
android.os.RemoteException
;
import
android.text.TextUtils;
import android.util.Log;
import
com.android.vending.billing.I
InAppBillingService;
import
org.json.JSONException;
import java.util.ArrayList;
import java.util.List;
/**
* Provides convenience
methods for in-app billing.
You can create one instance
of this
* class for your application
and use it to process in-app
billing operations.
* It provides synchronous
(blocking) and asynchronous
(non-blocking) methods for
* many common in-app
billing operations, as well as
automatic signature
* verification.
*
* After instantiating, you
must perform setup in order
to start using the object.
* To perform setup, call the
{@link #startSetup} method
and provide a listener;
* that listener will be
notified when setup is
complete, after which (and
not before)
* you may call other
methods.
*
* After setup is complete,
you will typically want to
request an inventory of
owned
* items and subscriptions.
See {@link #queryInventory},
{@link
#queryInventoryAsync}
* and related methods.
*
* When you are done with
this object, don't forget to
call {@link #dispose}
* to ensure proper cleanup.
This object holds a binding to
the in-app billing
* service, which will leak
unless you dispose of it
correctly. If you created
* the object on an Activity's
onCreate method, then the
recommended
* place to dispose of it is the
Activity's onDestroy method.
*
* A note about threading:
When using this object from
a background thread, you
may
* call the blocking versions
of methods; when using from
a UI thread, call
* only the asynchronous
versions and handle the
results via callbacks.
* Also, notice that you can
only call one asynchronous
operation at a time;
* attempting to start a
second asynchronous
operation while the first one
* has not yet completed will
result in an exception being
thrown.
*
* @author Bruno Oliveira
(Google)
*
*/
public class IabHelper {
// Is debug logging
enabled?
boolean mDebugLog =
false;
String mDebugTag =
"IabHelper";
// Is setup done?
boolean mSetupDone =
false;
// Has this object been
disposed of? (If so, we
should ignore callbacks, etc)
boolean mDisposed =
false;
// Are subscriptions
supported?
boolean
mSubscriptionsSupported =
false;
// Is an asynchronous
operation in progress?
// (only one at a time can
be in progress)
boolean mAsyncInProgress
= false;
// (for logging/debugging)
// if mAsyncInProgress ==
true, what asynchronous
operation is in progress?
String mAsyncOperation =
"";
// Context we were passed
during initialization
Context mContext;
// Connection to the
service
IInAppBillingService
mService;
ServiceConnection
mServiceConn;
// The request code used
to launch purchase flow
int mRequestCode;
// The item type of the
current purchase flow
String
mPurchasingItemType;
// Public key for verifying
signature, in base64
encoding
String mSignatureBase64 =
null;
// Billing response codes
public static final int
BILLING_RESPONSE_RESULT_
OK = 0;
public static final int
BILLING_RESPONSE_RESULT_
USER_CANCELED = 1;
public static final int
BILLING_RESPONSE_RESULT_
BILLING_UNAVAILABLE = 3;
public static final int
BILLING_RESPONSE_RESULT_
ITEM_UNAVAILABLE = 4;
public static final int
BILLING_RESPONSE_RESULT_
DEVELOPER_ERROR = 5;
public static final int
BILLING_RESPONSE_RESULT_
ERROR = 6;
public static final int
BILLING_RESPONSE_RESULT_
ITEM_ALREADY_OWNED = 7;
public static final int
BILLING_RESPONSE_RESULT_
ITEM_NOT_OWNED = 8;
// IAB Helper error codes
public static final int
IABHELPER_ERROR_BASE = 1000;
public static final int
IABHELPER_REMOTE_EXCEP
TION = -1001;
public static final int
IABHELPER_BAD_RESPONSE
= -1002;
public static final int
IABHELPER_VERIFICATION_F
AILED = -1003;
public static final int
IABHELPER_SEND_INTENT_F
AILED = -1004;
public static final int
IABHELPER_USER_CANCELLE
D = -1005;
public static final int
IABHELPER_UNKNOWN_PUR
CHASE_RESPONSE = -1006;
public static final int
IABHELPER_MISSING_TOKEN
= -1007;
public static final int
IABHELPER_UNKNOWN_ERR
OR = -1008;
public static final int
IABHELPER_SUBSCRIPTIONS_
NOT_AVAILABLE = -1009;
public static final int
IABHELPER_INVALID_CONSU
MPTION = -1010;
// Keys for the responses
from InAppBillingService
public static final String
RESPONSE_CODE =
"RESPONSE_CODE";
public static final String
RESPONSE_GET_SKU_DETAIL
S_LIST = "DETAILS_LIST";
public static final String
RESPONSE_BUY_INTENT =
"BUY_INTENT";
public static final String
RESPONSE_INAPP_PURCHAS
E_DATA =
"INAPP_PURCHASE_DATA";
public static final String
RESPONSE_INAPP_SIGNATU
RE =
"INAPP_DATA_SIGNATURE";
public static final String
RESPONSE_INAPP_ITEM_LIST
=
"INAPP_PURCHASE_ITEM_LI
ST";
public static final String
RESPONSE_INAPP_PURCHAS
E_DATA_LIST =
"INAPP_PURCHASE_DATA_LI
ST";
public static final String
RESPONSE_INAPP_SIGNATU
RE_LIST =
"INAPP_DATA_SIGNATURE_L
IST";
public static final String
INAPP_CONTINUATION_TOK
EN =
"INAPP_CONTINUATION_TO
KEN";
// Item types
public static final String
ITEM_TYPE_INAPP = "inapp";
public static final String
ITEM_TYPE_SUBS = "subs";
// some fields on the
getSkuDetails response
bundle
public static final String
GET_SKU_DETAILS_ITEM_LIS
T = "ITEM_ID_LIST";
public static final String
GET_SKU_DETAILS_ITEM_TY
PE_LIST = "ITEM_TYPE_LIST";
/**
* Creates an instance.
After creation, it will not yet
be ready to use. You must
perform
* setup by calling {@link
#startSetup} and wait for
setup to complete. This
constructor does not
* block and is safe to call
from a UI thread.
*
* @param ctx Your
application or Activity
context. Needed to bind to
the in-app billing service.
* @param
base64PublicKey Your
application's public key,
encoded in base64.
* This is used for
verification of purchase
signatures. You can find your
app's base64-encoded
* public key in your
application's page on Google
Play Developer Console.
Note that this
* is NOT your
"developer public key".
*/
public IabHelper(Context
ctx, String base64PublicKey) {
mContext =
ctx.getApplicationContext();
mSignatureBase64 =
base64PublicKey;
logDebug("IAB helper
created.");
}
/**
* Enables or disable debug
logging through LogCat.
*/
public void
enableDebugLogging(boolea
n enable, String tag) {
checkNotDisposed();
mDebugLog = enable;
mDebugTag = tag;
}
public void
enableDebugLogging(boolea
n enable) {
checkNotDisposed();
mDebugLog = enable;
}
/**
* Callback for setup
process. This listener's {@link
#onIabSetupFinished}
method is called
* when the setup process
is complete.
*/
public interface
OnIabSetupFinishedListener {
/**
* Called to notify that
setup is complete.
*
* @param result The
result of the setup process.
*/
public void
onIabSetupFinished(IabResul
t result);
}
/**
* Starts the setup process.
This will start up the setup
process asynchronously.
* You will be notified
through the listener when
the setup process is
complete.
* This method is safe to
call from a UI thread.
*
* @param listener The
listener to notify when the
setup process is complete.
*/
public void startSetup(final
OnIabSetupFinishedListener
listener) {
// If already set up, can't
do it again.
checkNotDisposed();
if (mSetupDone) throw
new
IllegalStateException("IAB
helper is already set up.");
// Connection to IAB
service
logDebug("Starting inapp billing setup.");
mServiceConn = new
ServiceConnection() {
@Override
public void
onServiceDisconnected(Com
ponentName name) {
logDebug("Billing
service disconnected.");
mService = null;
}
@Override
public void
onServiceConnected(Compo
nentName name, IBinder
service) {
if (mDisposed)
return;
logDebug("Billing
service connected.");
mService =
IInAppBillingService.Stub.asI
nterface(service);
String packageName
=
mContext.getPackageName()
;
try {
logDebug("Checking for inapp billing 3 support.");
// check for inapp billing v3 support
int response =
mService.isBillingSupported(
3, packageName,
ITEM_TYPE_INAPP);
if (response !=
BILLING_RESPONSE_RESULT_
OK) {
if (listener !=
null)
listener.onIabSetupFinished(
new IabResult(response,
"Error
checking for billing v3
support."));
// if in-app
purchases aren't supported,
neither are subscriptions.
"RemoteException while
setting up in-app billing."));
}
mSubscriptionsSupported =
false;
return;
}
logDebug("In-app
billing version 3 supported
for " + packageName);
e.printStackTrace();
return;
}
// check for v3
subscriptions support
response =
mService.isBillingSupported(
3, packageName,
ITEM_TYPE_SUBS);
if (response ==
BILLING_RESPONSE_RESULT_
OK) {
logDebug("Subscriptions
AVAILABLE.");
mSubscriptionsSupported =
true;
}
else {
logDebug("Subscriptions
NOT AVAILABLE. Response: "
+ response);
}
mSetupDone =
true;
}
catch
(RemoteException e) {
if (listener != null)
{
listener.onIabSetupFinished(
new
IabResult(IABHELPER_REMO
TE_EXCEPTION,
if (listener != null) {
listener.onIabSetupFinished(
new
IabResult(BILLING_RESPONS
E_RESULT_OK, "Setup
successful."));
}
}
};
Intent serviceIntent =
new
Intent("com.android.vending
.billing.InAppBillingService.BI
ND");
serviceIntent.setPackage("co
m.android.vending");
if
(!mContext.getPackageMana
ger().queryIntentServices(ser
viceIntent, 0).isEmpty()) {
// service available to
handle that Intent
mContext.bindService(servic
eIntent, mServiceConn,
Context.BIND_AUTO_CREATE
);
}
else {
// no service available
to handle that Intent
if (listener != null) {
listener.onIabSetupFinished(
new
IabResult(BILLING_RESPONS
E_RESULT_BILLING_UNAVAIL
ABLE,
"Billing service
unavailable on device."));
}
}
}
/**
* Dispose of object,
releasing resources. It's very
important to call this
* method when you are
done with this object. It will
release any resources
* used by it such as
service connections.
Naturally, once the object is
* disposed of, it can't be
used again.
*/
public void dispose() {
logDebug("Disposing.");
mSetupDone = false;
if (mServiceConn != null)
{
logDebug("Unbinding
from service.");
if (mContext != null)
mContext.unbindService(mS
erviceConn);
}
mDisposed = true;
mContext = null;
mServiceConn = null;
mService = null;
mPurchaseListener =
null;
}
private void
checkNotDisposed() {
if (mDisposed) throw
new
IllegalStateException("IabHel
per was disposed of, so it
cannot be used.");
}
/** Returns whether
subscriptions are supported.
*/
public boolean
subscriptionsSupported() {
checkNotDisposed();
return
mSubscriptionsSupported;
}
/**
* Callback that notifies
when a purchase is finished.
*/
public interface
OnIabPurchaseFinishedListen
er {
/**
* Called to notify that
an in-app purchase finished.
If the purchase was
successful,
* then the sku
parameter specifies which
item was purchased. If the
purchase failed,
* the sku and extraData
parameters may or may not
be null, depending on how
far the purchase
* process went.
*
* @param result The
result of the purchase.
* @param info The
purchase information (null if
purchase failed)
*/
public void
onIabPurchaseFinished(IabRe
sult result, Purchase info);
}
// The listener registered
on launchPurchaseFlow,
which we have to call back
when
// the purchase finishes
OnIabPurchaseFinishedListen
er mPurchaseListener;
public void
launchPurchaseFlow(Activity
act, String sku, int
requestCode,
OnIabPurchaseFinishedListen
er listener) {
launchPurchaseFlow(act,
sku, requestCode, listener,
"");
}
public void
launchPurchaseFlow(Activity
act, String sku, int
requestCode,
OnIabPurchaseFinishedListen
er listener, String extraData)
{
launchPurchaseFlow(act,
sku, ITEM_TYPE_INAPP,
requestCode, listener,
extraData);
}
public void
launchSubscriptionPurchaseF
low(Activity act, String sku,
int requestCode,
OnIabPurchaseFinishedListen
er listener) {
launchSubscriptionPurchaseF
low(act, sku, requestCode,
listener, "");
}
public void
launchSubscriptionPurchaseF
low(Activity act, String sku,
int requestCode,
OnIabPurchaseFinishedListen
er listener, String extraData)
{
launchPurchaseFlow(act,
sku, ITEM_TYPE_SUBS,
requestCode, listener,
extraData);
}
/**
* Initiate the UI flow for
an in-app purchase. Call this
method to initiate an in-app
purchase,
* which will involve
bringing up the Google Play
screen. The calling activity
will be paused while
* the user interacts with
Google Play, and the result
will be delivered via the
activity's
* {@link
android.app.Activity#onActiv
ityResult} method, at which
point you must call
* this object's {@link
#handleActivityResult}
method to continue the
purchase flow. This method
* MUST be called from the
UI thread of the Activity.
*
* @param act The calling
activity.
* @param sku The sku of
the item to purchase.
* @param itemType
indicates if it's a product or a
subscription
(ITEM_TYPE_INAPP or
ITEM_TYPE_SUBS)
* @param requestCode A
request code (to
differentiate from other
responses -* as in {@link
android.app.Activity#startAct
ivityForResult}).
* @param listener The
listener to notify when the
purchase process finishes
* @param extraData Extra
data (developer payload),
which will be returned with
the purchase data
* when the purchase
completes. This extra data
will be permanently bound
to that purchase
* and will always be
returned when the purchase
is queried.
*/
public void
launchPurchaseFlow(Activity
act, String sku, String
itemType, int requestCode,
OnIabPurchaseFinishedListen
er listener, String extraData)
{
checkNotDisposed();
checkSetupDone("launchPur
chaseFlow");
flagStartAsync("launchPurch
aseFlow");
IabResult result;
if
(itemType.equals(ITEM_TYPE
_SUBS) &&
!mSubscriptionsSupported) {
IabResult r = new
IabResult(IABHELPER_SUBSC
RIPTIONS_NOT_AVAILABLE,
"Subscriptions are
not available.");
flagEndAsync();
if (listener != null)
listener.onIabPurchaseFinish
ed(r, null);
return;
}
try {
logDebug("Constructing buy
intent for " + sku + ", item
type: " + itemType);
Bundle
buyIntentBundle =
mService.getBuyIntent(3,
mContext.getPackageName()
, sku, itemType, extraData);
int response =
getResponseCodeFromBundl
e(buyIntentBundle);
if (response !=
BILLING_RESPONSE_RESULT_
OK) {
logError("Unable to
buy item, Error response: " +
getResponseDesc(response))
;
flagEndAsync();
result = new
IabResult(response, "Unable
to buy item");
if (listener != null)
listener.onIabPurchaseFinish
ed(result, null);
return;
}
PendingIntent
pendingIntent =
buyIntentBundle.getParcelab
le(RESPONSE_BUY_INTENT);
logDebug("Launching
buy intent for " + sku + ".
Request code: " +
requestCode);
mRequestCode =
requestCode;
mPurchaseListener =
listener;
mPurchasingItemType
= itemType;
act.startIntentSenderForResu
lt(pendingIntent.getIntentSe
nder(),
requestCode, new Intent(),
Integer.valueOf(0),
Integer.valueOf(0),
Integer.valueOf(0));
}
catch
(SendIntentException e) {
logError("SendIntentExceptio
n while launching purchase
flow for sku " + sku);
e.printStackTrace();
flagEndAsync();
result = new
IabResult(IABHELPER_SEND_I
NTENT_FAILED, "Failed to
send intent.");
if (listener != null)
listener.onIabPurchaseFinish
ed(result, null);
}
catch (RemoteException
e) {
logError("RemoteException
while launching purchase
flow for sku " + sku);
e.printStackTrace();
flagEndAsync();
result = new
IabResult(IABHELPER_REMO
TE_EXCEPTION, "Remote
exception while starting
purchase flow");
if (listener != null)
listener.onIabPurchaseFinish
ed(result, null);
}
}
/**
* Handles an activity
result that's part of the
purchase flow in in-app
billing. If you
* are calling {@link
#launchPurchaseFlow}, then
you must call this method
from your
* Activity's {@link
android.app.Activity@onActi
vityResult} method. This
method
* MUST be called from the
UI thread of the Activity.
*
* @param requestCode
The requestCode as you
received it.
* @param resultCode The
resultCode as you received it.
* @param data The data
(Intent) as you received it.
* @return Returns true if
the result was related to a
purchase flow and was
handled;
* false if the result was
not related to a purchase, in
which case you should
* handle it normally.
*/
public boolean
handleActivityResult(int
requestCode, int resultCode,
Intent data) {
IabResult result;
if (requestCode !=
mRequestCode) return false;
checkNotDisposed();
checkSetupDone("handleActi
vityResult");
// end of async purchase
operation that started on
launchPurchaseFlow
flagEndAsync();
if (data == null) {
logError("Null data in
IAB activity result.");
result = new
IabResult(IABHELPER_BAD_R
ESPONSE, "Null data in IAB
result");
if (mPurchaseListener
!= null)
mPurchaseListener.onIabPur
chaseFinished(result, null);
return true;
}
int responseCode =
getResponseCodeFromIntent
(data);
String purchaseData =
data.getStringExtra(RESPONS
E_INAPP_PURCHASE_DATA);
String dataSignature =
data.getStringExtra(RESPONS
E_INAPP_SIGNATURE);
if (resultCode ==
Activity.RESULT_OK &&
responseCode ==
BILLING_RESPONSE_RESULT_
OK) {
logDebug("Successful
resultcode from purchase
activity.");
logDebug("Purchase
data: " + purchaseData);
logDebug("Data
signature: " + dataSignature);
logDebug("Extras: " +
data.getExtras());
logDebug("Expected
item type: " +
mPurchasingItemType);
if (purchaseData ==
null || dataSignature == null)
{
logError("BUG:
either purchaseData or
dataSignature is null.");
logDebug("Extras: "
+ data.getExtras().toString());
result = new
IabResult(IABHELPER_UNKN
OWN_ERROR, "IAB returned
null purchaseData or
dataSignature");
if
(mPurchaseListener != null)
mPurchaseListener.onIabPur
chaseFinished(result, null);
return true;
}
Purchase purchase =
null;
try {
purchase = new
Purchase(mPurchasingItemT
ype, purchaseData,
dataSignature);
String sku =
purchase.getSku();
// Verify signature
if
(!Security.verifyPurchase(mSi
gnatureBase64,
purchaseData,
dataSignature)) {
logError("Purchase signature
verification FAILED for sku " +
sku);
result = new
IabResult(IABHELPER_VERIFI
CATION_FAILED, "Signature
verification failed for sku " +
sku);
if
(mPurchaseListener != null)
mPurchaseListener.onIabPur
chaseFinished(result,
purchase);
return true;
}
logDebug("Purchase
signature successfully
verified.");
}
catch (JSONException
e) {
logError("Failed to
parse purchase data.");
e.printStackTrace();
result = new
IabResult(IABHELPER_BAD_R
ESPONSE, "Failed to parse
purchase data.");
if
(mPurchaseListener != null)
mPurchaseListener.onIabPur
chaseFinished(result, null);
return true;
}
if (mPurchaseListener
!= null) {
mPurchaseListener.onIabPur
chaseFinished(new
IabResult(BILLING_RESPONS
E_RESULT_OK, "Success"),
purchase);
}
}
else if (resultCode ==
Activity.RESULT_OK) {
// result code was OK,
but in-app billing response
was not OK.
logDebug("Result code
was OK but in-app billing
response was not OK: " +
getResponseDesc(responseC
ode));
if (mPurchaseListener
!= null) {
result = new
IabResult(responseCode,
"Problem purchashing
item.");
mPurchaseListener.onIabPur
chaseFinished(result, null);
}
}
else if (resultCode ==
Activity.RESULT_CANCELED) {
logDebug("Purchase
canceled - Response: " +
getResponseDesc(responseC
ode));
result = new
IabResult(IABHELPER_USER_
CANCELLED, "User
canceled.");
if (mPurchaseListener
!= null)
mPurchaseListener.onIabPur
chaseFinished(result, null);
}
else {
logError("Purchase
failed. Result code: " +
Integer.toString(resultCode)
+ ". Response: " +
getResponseDesc(responseC
ode));
result = new
IabResult(IABHELPER_UNKN
OWN_PURCHASE_RESPONSE
, "Unknown purchase
response.");
if (mPurchaseListener
!= null)
mPurchaseListener.onIabPur
chaseFinished(result, null);
}
return true;
}
public Inventory
queryInventory(boolean
querySkuDetails, List<String>
moreSkus) throws
IabException {
return
queryInventory(querySkuDet
ails, moreSkus, null);
}
/**
* Queries the inventory.
This will query all owned
items from the server, as
well as
* information on
additional skus, if specified.
This method may block or
take long to execute.
* Do not call from a UI
thread. For that, use the
non-blocking version {@link
#refreshInventoryAsync}.
*
* @param
querySkuDetails if true, SKU
details (price, description,
etc) will be queried as well
* as purchase
information.
* @param moreItemSkus
additional PRODUCT skus to
query information on,
regardless of ownership.
* Ignored if null or if
querySkuDetails is false.
* @param moreSubsSkus
additional SUBSCRIPTIONS
skus to query information
on, regardless of ownership.
* Ignored if null or if
querySkuDetails is false.
* @throws IabException if
a problem occurs while
refreshing the inventory.
*/
public Inventory
queryInventory(boolean
querySkuDetails, List<String>
moreItemSkus,
List<String> moreSubsSkus)
throws IabException {
checkNotDisposed();
checkSetupDone("queryInve
ntory");
try {
Inventory inv = new
Inventory();
int r =
queryPurchases(inv,
ITEM_TYPE_INAPP);
if (r !=
BILLING_RESPONSE_RESULT_
OK) {
throw new
IabException(r, "Error
refreshing inventory
(querying owned items).");
}
if (querySkuDetails) {
r=
querySkuDetails(ITEM_TYPE_
INAPP, inv, moreItemSkus);
if (r !=
BILLING_RESPONSE_RESULT_
OK) {
throw new
IabException(r, "Error
refreshing inventory
(querying prices of items).");
}
}
// if subscriptions are
supported, then also query
for subscriptions
if
(mSubscriptionsSupported) {
r=
queryPurchases(inv,
ITEM_TYPE_SUBS);
if (r !=
BILLING_RESPONSE_RESULT_
OK) {
throw new
IabException(r, "Error
refreshing inventory
(querying owned
subscriptions).");
}
if (querySkuDetails)
{
r=
querySkuDetails(ITEM_TYPE_
SUBS, inv, moreItemSkus);
if (r !=
BILLING_RESPONSE_RESULT_
OK) {
throw new
IabException(r, "Error
refreshing inventory
(querying prices of
subscriptions).");
}
}
}
return inv;
}
catch (RemoteException
e) {
throw new
IabException(IABHELPER_RE
MOTE_EXCEPTION, "Remote
exception while refreshing
inventory.", e);
}
catch (JSONException e)
{
throw new
IabException(IABHELPER_BA
D_RESPONSE, "Error parsing
JSON response while
refreshing inventory.", e);
}
}
/**
* Listener that notifies
when an inventory query
operation completes.
*/
public interface
QueryInventoryFinishedListe
ner {
/**
* Called to notify that
an inventory query operation
completed.
*
* @param result The
result of the operation.
* @param inv The
inventory.
*/
public void
onQueryInventoryFinished(Ia
bResult result, Inventory inv);
}
/**
* Asynchronous wrapper
for inventory query. This will
perform an inventory
* query as described in
{@link #queryInventory}, but
will do so asynchronously
* and call back the
specified listener upon
completion. This method is
safe to
* call from a UI thread.
*
* @param
querySkuDetails as in {@link
#queryInventory}
* @param moreSkus as in
{@link #queryInventory}
* @param listener The
listener to notify when the
refresh operation completes.
*/
public void
queryInventoryAsync(final
boolean querySkuDetails,
final
List<String> moreSkus,
final
QueryInventoryFinishedListe
ner listener) {
final Handler handler =
new Handler();
checkNotDisposed();
checkSetupDone("queryInve
ntory");
flagStartAsync("refresh
inventory");
(new Thread(new
Runnable() {
public void run() {
IabResult result =
new
IabResult(BILLING_RESPONS
E_RESULT_OK, "Inventory
refresh successful.");
Inventory inv = null;
try {
inv =
queryInventory(querySkuDet
ails, moreSkus);
}
catch (IabException
ex) {
result =
ex.getResult();
}
flagEndAsync();
final IabResult
result_f = result;
final Inventory inv_f
= inv;
if (!mDisposed &&
listener != null) {
handler.post(new
Runnable() {
public void
run() {
listener.onQueryInventoryFin
ished(result_f, inv_f);
}
});
}
}
})).start();
}
public void
queryInventoryAsync(QueryI
nventoryFinishedListener
listener) {
queryInventoryAsync(true,
null, listener);
}
public void
queryInventoryAsync(boolea
n querySkuDetails,
QueryInventoryFinishedListe
ner listener) {
queryInventoryAsync(queryS
kuDetails, null, listener);
}
/**
* Consumes a given in-app
product. Consuming can only
be done on an item
* that's owned, and as a
result of consumption, the
user will no longer own it.
* This method may block
or take long to return. Do not
call from the UI thread.
* For that, see {@link
#consumeAsync}.
*
* @param itemInfo The
PurchaseInfo that represents
the item to consume.
* @throws IabException if
there is a problem during
consumption.
*/
void consume(Purchase
itemInfo) throws
IabException {
checkNotDisposed();
checkSetupDone("consume")
;
if
(!itemInfo.mItemType.equals
(ITEM_TYPE_INAPP)) {
throw new
IabException(IABHELPER_INV
ALID_CONSUMPTION,
"Items of type '" +
itemInfo.mItemType + "'
can't be consumed.");
}
try {
String token =
itemInfo.getToken();
String sku =
itemInfo.getSku();
if (token == null ||
token.equals("")) {
logError("Can't
consume "+ sku + ". No
token.");
throw new
IabException(IABHELPER_MI
SSING_TOKEN, "PurchaseInfo
is missing token for sku: "
+ sku + " " +
itemInfo);
}
logDebug("Consuming
sku: " + sku + ", token: " +
token);
int response =
mService.consumePurchase(
3,
mContext.getPackageName()
, token);
if (response ==
BILLING_RESPONSE_RESULT_
OK) {
logDebug("Successfully
consumed sku: " + sku);
}
else {
logDebug("Error
consuming consuming sku "
+ sku + ". " +
getResponseDesc(response))
;
throw new
IabException(response,
"Error consuming sku " +
sku);
}
}
catch (RemoteException
e) {
throw new
IabException(IABHELPER_RE
MOTE_EXCEPTION, "Remote
exception while consuming.
PurchaseInfo: " + itemInfo,
e);
}
}
/**
* Callback that notifies
when a consumption
operation finishes.
*/
public interface
OnConsumeFinishedListener
{
/**
* Called to notify that a
consumption has finished.
*
* @param purchase The
purchase that was (or was to
be) consumed.
* @param result The
result of the consumption
operation.
*/
public void
onConsumeFinished(Purchas
e purchase, IabResult result);
}
/**
* Callback that notifies
when a multi-item
consumption operation
finishes.
*/
public interface
OnConsumeMultiFinishedList
ener {
/**
* Called to notify that a
consumption of multiple
items has finished.
*
* @param purchases
The purchases that were (or
were to be) consumed.
* @param results The
results of each consumption
operation, corresponding to
each
* sku.
*/
public void
onConsumeMultiFinished(Lis
t<Purchase> purchases,
List<IabResult> results);
}
/**
* Asynchronous wrapper
to item consumption. Works
like {@link #consume}, but
* performs the
consumption in the
background and notifies
completion through
* the provided listener.
This method is safe to call
from a UI thread.
*
* @param purchase The
purchase to be consumed.
* @param listener The
listener to notify when the
consumption operation
finishes.
*/
public void
consumeAsync(Purchase
purchase,
OnConsumeFinishedListener
listener) {
checkNotDisposed();
checkSetupDone("consume")
;
List<Purchase>
purchases = new
ArrayList<Purchase>();
purchases.add(purchase);
consumeAsyncInternal(purch
ases, listener, null);
}
/**
* Same as {@link
consumeAsync}, but for
multiple items at once.
* @param purchases The
list of PurchaseInfo objects
representing the purchases
to consume.
* @param listener The
listener to notify when the
consumption operation
finishes.
*/
public void
consumeAsync(List<Purchase
> purchases,
OnConsumeMultiFinishedList
ener listener) {
checkNotDisposed();
checkSetupDone("consume")
;
consumeAsyncInternal(purch
ases, null, listener);
}
/**
* Returns a humanreadable description for the
given response code.
*
* @param code The
response code
* @return A humanreadable string explaining
the result code.
* It also includes the
result code numerically.
*/
public static String
getResponseDesc(int code) {
String[] iab_msgs =
("0:OK/1:User
Canceled/2:Unknown/" +
"3:Billing
Unavailable/4:Item
unavailable/" +
"5:Developer
Error/6:Error/7:Item Already
Owned/" +
"8:Item not
owned").split("/");
String[] iabhelper_msgs
= ("0:OK/-1001:Remote
exception during
initialization/" +
"1002:Bad response
received/" +
"1003:Purchase signature
verification failed/" +
"1004:Send intent failed/" +
"1005:User cancelled/" +
"1006:Unknown purchase
response/" +
"1007:Missing token/" +
"1008:Unknown error/" +
"1009:Subscriptions not
available/" +
"1010:Invalid consumption
attempt").split("/");
if (code <=
IABHELPER_ERROR_BASE) {
int index =
IABHELPER_ERROR_BASE code;
if (index >= 0 && index
< iabhelper_msgs.length)
return
iabhelper_msgs[index];
else return
String.valueOf(code) +
":Unknown IAB Helper
Error";
}
else if (code < 0 || code
>= iab_msgs.length)
return
String.valueOf(code) +
":Unknown";
else
return
iab_msgs[code];
}
// Checks that setup was
done; if not, throws an
exception.
void
checkSetupDone(String
operation) {
if (!mSetupDone) {
logError("Illegal state
for operation (" + operation
+ "): IAB helper is not set
up.");
throw new
IllegalStateException("IAB
helper is not set up. Can't
perform operation: " +
operation);
}
}
// Workaround to bug
where sometimes response
codes come as Long instead
of Integer
int
getResponseCodeFromBundl
e(Bundle b) {
Object o =
b.get(RESPONSE_CODE);
if (o == null) {
logDebug("Bundle
with null response code,
assuming OK (known
issue)");
return
BILLING_RESPONSE_RESULT_
OK;
}
else if (o instanceof
Integer) return
((Integer)o).intValue();
else if (o instanceof
Long) return
(int)((Long)o).longValue();
else {
logError("Unexpected
type for bundle response
code.");
logError(o.getClass().getNam
e());
throw new
RuntimeException("Unexpec
ted type for bundle response
code: " +
o.getClass().getName());
}
}
// Workaround to bug
where sometimes response
codes come as Long instead
of Integer
int
getResponseCodeFromIntent
(Intent i) {
Object o =
i.getExtras().get(RESPONSE_
CODE);
if (o == null) {
logError("Intent with
no response code, assuming
OK (known issue)");
return
BILLING_RESPONSE_RESULT_
OK;
}
else if (o instanceof
Integer) return
((Integer)o).intValue();
else if (o instanceof
Long) return
(int)((Long)o).longValue();
else {
logError("Unexpected
type for intent response
code.");
logError(o.getClass().getNam
e());
throw new
RuntimeException("Unexpec
ted type for intent response
code: " +
o.getClass().getName());
}
}
void flagStartAsync(String
operation) {
if (mAsyncInProgress)
throw new
IllegalStateException("Can't
start async operation (" +
operation + ")
because another async
operation(" +
mAsyncOperation + ") is in
progress.");
mAsyncOperation =
operation;
mAsyncInProgress =
true;
logDebug("Starting
async operation: " +
operation);
}
void flagEndAsync() {
logDebug("Ending async
operation: " +
mAsyncOperation);
mAsyncOperation = "";
mAsyncInProgress =
false;
}
int
queryPurchases(Inventory
inv, String itemType) throws
JSONException,
RemoteException {
// Query purchases
logDebug("Querying
owned items, item type: " +
itemType);
logDebug("Package
name: " +
mContext.getPackageName()
);
boolean
verificationFailed = false;
String continueToken =
null;
do {
logDebug("Calling
getPurchases with
continuation token: " +
continueToken);
Bundle ownedItems =
mService.getPurchases(3,
mContext.getPackageName()
,
itemType,
continueToken);
int response =
getResponseCodeFromBundl
e(ownedItems);
logDebug("Owned
items response: " +
String.valueOf(response));
if (response !=
BILLING_RESPONSE_RESULT_
OK) {
logDebug("getPurchases()
failed: " +
getResponseDesc(response))
;
return response;
}
if
(!ownedItems.containsKey(R
ESPONSE_INAPP_ITEM_LIST)
||
!ownedItems.containsKey(RE
SPONSE_INAPP_PURCHASE_
DATA_LIST)
||
!ownedItems.containsKey(RE
SPONSE_INAPP_SIGNATURE_
LIST)) {
logError("Bundle
returned from
getPurchases() doesn't
contain required fields.");
return
IABHELPER_BAD_RESPONSE;
}
ArrayList<String>
ownedSkus =
ownedItems.getStringArrayLi
st(
RESPONSE_INAPP_ITEM_LIST
);
ArrayList<String>
purchaseDataList =
ownedItems.getStringArrayLi
st(
RESPONSE_INAPP_PURCHAS
E_DATA_LIST);
ArrayList<String>
signatureList =
ownedItems.getStringArrayLi
st(
RESPONSE_INAPP_SIGNATU
RE_LIST);
for (int i = 0; i <
purchaseDataList.size(); ++i) {
String purchaseData
= purchaseDataList.get(i);
String signature =
signatureList.get(i);
String sku =
ownedSkus.get(i);
if
(Security.verifyPurchase(mSi
gnatureBase64,
purchaseData, signature)) {
logDebug("Sku is
owned: " + sku);
Purchase
purchase = new
Purchase(itemType,
purchaseData, signature);
if
(TextUtils.isEmpty(purchase.
getToken())) {
logWarn("BUG:
empty/null token!");
logDebug("Purchase data: " +
purchaseData);
}
// Record
ownership and token
inv.addPurchase(purchase);
}
else {
logWarn("Purchase signature
verification **FAILED**. Not
adding item.");
logDebug("
Purchase data: " +
purchaseData);
logDebug("
Signature: " + signature);
verificationFailed
= true;
}
}
continueToken =
ownedItems.getString(INAPP
_CONTINUATION_TOKEN);
logDebug("Continuation
token: " + continueToken);
} while
(!TextUtils.isEmpty(continue
Token));
return verificationFailed
?
IABHELPER_VERIFICATION_F
AILED :
BILLING_RESPONSE_RESULT_
OK;
}
int querySkuDetails(String
itemType, Inventory inv,
List<String> moreSkus)
throws
RemoteException,
JSONException {
logDebug("Querying SKU
details.");
ArrayList<String> skuList
= new ArrayList<String>();
skuList.addAll(inv.getAllOwn
edSkus(itemType));
if (moreSkus != null) {
for (String sku :
moreSkus) {
if
(!skuList.contains(sku)) {
skuList.add(sku);
}
}
}
if (skuList.size() == 0) {
logDebug("queryPrices:
nothing to do because there
are no SKUs.");
return
BILLING_RESPONSE_RESULT_
OK;
}
Bundle querySkus = new
Bundle();
querySkus.putStringArrayList
(GET_SKU_DETAILS_ITEM_LI
ST, skuList);
Bundle skuDetails =
mService.getSkuDetails(3,
mContext.getPackageName()
,
itemType,
querySkus);
if
(!skuDetails.containsKey(RES
PONSE_GET_SKU_DETAILS_LI
ST)) {
int response =
getResponseCodeFromBundl
e(skuDetails);
if (response !=
BILLING_RESPONSE_RESULT_
OK) {
logDebug("getSkuDetails()
failed: " +
getResponseDesc(response))
;
return response;
}
else {
logError("getSkuDetails()
returned a bundle with
neither an error nor a detail
list.");
return
IABHELPER_BAD_RESPONSE;
}
}
ArrayList<String>
responseList =
skuDetails.getStringArrayList(
RESPONSE_GET_SKU_DETAIL
S_LIST);
for (String thisResponse :
responseList) {
SkuDetails d = new
SkuDetails(itemType,
thisResponse);
logDebug("Got sku
details: " + d);
inv.addSkuDetails(d);
}
return
BILLING_RESPONSE_RESULT_
OK;
}
void
consumeAsyncInternal(final
List<Purchase> purchases,
final
OnConsumeFinishedListener
singleListener,
final
OnConsumeMultiFinishedList
ener multiListener) {
final Handler handler =
new Handler();
flagStartAsync("consume");
(new Thread(new
Runnable() {
public void run() {
final List<IabResult>
results = new
ArrayList<IabResult>();
for (Purchase
purchase : purchases) {
try {
consume(purchase);
results.add(new
IabResult(BILLING_RESPONS
E_RESULT_OK, "Successful
consume of sku " +
purchase.getSku()));
}
catch
(IabException ex) {
results.add(ex.getResult());
}
}
flagEndAsync();
if (!mDisposed &&
singleListener != null) {
handler.post(new
Runnable() {
public void
run() {
singleListener.onConsumeFin
ished(purchases.get(0),
results.get(0));
}
});
}
if (!mDisposed &&
multiListener != null) {
handler.post(new
Runnable() {
public void
run() {
multiListener.onConsumeMu
ltiFinished(purchases,
results);
}
});
}
}
})).start();
{
* See the License for the
specific language governing
permissions and
* limitations under the
License.
*/
if (mDebugLog)
Log.d(mDebugTag, msg);
}
package
com.secrethq.store.util;
}
void logDebug(String msg)
void logError(String msg) {
Log.e(mDebugTag, "Inapp billing error: " + msg);
}
void logWarn(String msg) {
Log.w(mDebugTag, "Inapp billing warning: " + msg);
}
}
IabResult.java
/* Copyright (c) 2012 Google
Inc.
*
* 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/licen
ses/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.
import android.app.Activity;
import
android.app.PendingIntent;
import
android.content.Component
Name;
import
android.content.Context;
import
android.content.Intent;
import
android.content.IntentSende
r.SendIntentException;
import
android.content.ServiceConn
ection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import
android.os.RemoteException
;
import
android.text.TextUtils;
import android.util.Log;
import
com.android.vending.billing.I
InAppBillingService;
import
org.json.JSONException;
import java.util.ArrayList;
import java.util.List;
/**
* Provides convenience
methods for in-app billing.
You can create one instance
of this
* class for your application
and use it to process in-app
billing operations.
* It provides synchronous
(blocking) and asynchronous
(non-blocking) methods for
* many common in-app
billing operations, as well as
automatic signature
* verification.
*
* After instantiating, you
must perform setup in order
to start using the object.
* To perform setup, call the
{@link #startSetup} method
and provide a listener;
* that listener will be
notified when setup is
complete, after which (and
not before)
* you may call other
methods.
*
* After setup is complete,
you will typically want to
request an inventory of
owned
* items and subscriptions.
See {@link #queryInventory},
{@link
#queryInventoryAsync}
* and related methods.
*
* When you are done with
this object, don't forget to
call {@link #dispose}
* to ensure proper cleanup.
This object holds a binding to
the in-app billing
* service, which will leak
unless you dispose of it
correctly. If you created
* the object on an Activity's
onCreate method, then the
recommended
* place to dispose of it is the
Activity's onDestroy method.
*
* A note about threading:
When using this object from
a background thread, you
may
* call the blocking versions
of methods; when using from
a UI thread, call
* only the asynchronous
versions and handle the
results via callbacks.
* Also, notice that you can
only call one asynchronous
operation at a time;
* attempting to start a
second asynchronous
operation while the first one
* has not yet completed will
result in an exception being
thrown.
*
* @author Bruno Oliveira
(Google)
*
*/
public class IabHelper {
// Is debug logging
enabled?
boolean mDebugLog =
false;
String mDebugTag =
"IabHelper";
// Is setup done?
boolean mSetupDone =
false;
// Has this object been
disposed of? (If so, we
should ignore callbacks, etc)
boolean mDisposed =
false;
// Are subscriptions
supported?
boolean
mSubscriptionsSupported =
false;
// Is an asynchronous
operation in progress?
// (only one at a time can
be in progress)
boolean mAsyncInProgress
= false;
// (for logging/debugging)
// if mAsyncInProgress ==
true, what asynchronous
operation is in progress?
String mAsyncOperation =
"";
// Context we were passed
during initialization
Context mContext;
// Connection to the
service
IInAppBillingService
mService;
ServiceConnection
mServiceConn;
// The request code used
to launch purchase flow
int mRequestCode;
// The item type of the
current purchase flow
String
mPurchasingItemType;
// Public key for verifying
signature, in base64
encoding
String mSignatureBase64 =
null;
// Billing response codes
public static final int
BILLING_RESPONSE_RESULT_
OK = 0;
public static final int
BILLING_RESPONSE_RESULT_
USER_CANCELED = 1;
public static final int
BILLING_RESPONSE_RESULT_
BILLING_UNAVAILABLE = 3;
public static final int
BILLING_RESPONSE_RESULT_
ITEM_UNAVAILABLE = 4;
public static final int
BILLING_RESPONSE_RESULT_
DEVELOPER_ERROR = 5;
public static final int
BILLING_RESPONSE_RESULT_
ERROR = 6;
public static final int
BILLING_RESPONSE_RESULT_
ITEM_ALREADY_OWNED = 7;
public static final int
BILLING_RESPONSE_RESULT_
ITEM_NOT_OWNED = 8;
// IAB Helper error codes
public static final int
IABHELPER_ERROR_BASE = 1000;
public static final int
IABHELPER_REMOTE_EXCEP
TION = -1001;
public static final int
IABHELPER_BAD_RESPONSE
= -1002;
public static final int
IABHELPER_VERIFICATION_F
AILED = -1003;
public static final int
IABHELPER_SEND_INTENT_F
AILED = -1004;
public static final int
IABHELPER_USER_CANCELLE
D = -1005;
public static final int
IABHELPER_UNKNOWN_PUR
CHASE_RESPONSE = -1006;
public static final int
IABHELPER_MISSING_TOKEN
= -1007;
public static final int
IABHELPER_UNKNOWN_ERR
OR = -1008;
public static final int
IABHELPER_SUBSCRIPTIONS_
NOT_AVAILABLE = -1009;
public static final int
IABHELPER_INVALID_CONSU
MPTION = -1010;
// Keys for the responses
from InAppBillingService
public static final String
RESPONSE_CODE =
"RESPONSE_CODE";
public static final String
RESPONSE_GET_SKU_DETAIL
S_LIST = "DETAILS_LIST";
public static final String
RESPONSE_BUY_INTENT =
"BUY_INTENT";
public static final String
RESPONSE_INAPP_PURCHAS
E_DATA =
"INAPP_PURCHASE_DATA";
public static final String
RESPONSE_INAPP_SIGNATU
RE =
"INAPP_DATA_SIGNATURE";
public static final String
RESPONSE_INAPP_ITEM_LIST
=
"INAPP_PURCHASE_ITEM_LI
ST";
public static final String
RESPONSE_INAPP_PURCHAS
E_DATA_LIST =
"INAPP_PURCHASE_DATA_LI
ST";
public static final String
RESPONSE_INAPP_SIGNATU
RE_LIST =
"INAPP_DATA_SIGNATURE_L
IST";
public static final String
INAPP_CONTINUATION_TOK
EN =
"INAPP_CONTINUATION_TO
KEN";
// Item types
public static final String
ITEM_TYPE_INAPP = "inapp";
public static final String
ITEM_TYPE_SUBS = "subs";
// some fields on the
getSkuDetails response
bundle
public static final String
GET_SKU_DETAILS_ITEM_LIS
T = "ITEM_ID_LIST";
public static final String
GET_SKU_DETAILS_ITEM_TY
PE_LIST = "ITEM_TYPE_LIST";
/**
* Creates an instance.
After creation, it will not yet
be ready to use. You must
perform
* setup by calling {@link
#startSetup} and wait for
setup to complete. This
constructor does not
* block and is safe to call
from a UI thread.
*
* @param ctx Your
application or Activity
context. Needed to bind to
the in-app billing service.
* @param
base64PublicKey Your
application's public key,
encoded in base64.
* This is used for
verification of purchase
signatures. You can find your
app's base64-encoded
* public key in your
application's page on Google
Play Developer Console.
Note that this
* is NOT your
"developer public key".
*/
public IabHelper(Context
ctx, String base64PublicKey) {
mContext =
ctx.getApplicationContext();
mSignatureBase64 =
base64PublicKey;
logDebug("IAB helper
created.");
}
/**
* Enables or disable debug
logging through LogCat.
*/
public void
enableDebugLogging(boolea
n enable, String tag) {
checkNotDisposed();
mDebugLog = enable;
mDebugTag = tag;
}
public void
enableDebugLogging(boolea
n enable) {
checkNotDisposed();
mDebugLog = enable;
}
/**
* Callback for setup
process. This listener's {@link
#onIabSetupFinished}
method is called
* when the setup process
is complete.
*/
public interface
OnIabSetupFinishedListener {
/**
* Called to notify that
setup is complete.
*
* @param result The
result of the setup process.
*/
public void
onIabSetupFinished(IabResul
t result);
}
/**
* Starts the setup process.
This will start up the setup
process asynchronously.
* You will be notified
through the listener when
the setup process is
complete.
* This method is safe to
call from a UI thread.
*
* @param listener The
listener to notify when the
setup process is complete.
*/
public void startSetup(final
OnIabSetupFinishedListener
listener) {
// If already set up, can't
do it again.
checkNotDisposed();
if (mSetupDone) throw
new
IllegalStateException("IAB
helper is already set up.");
// Connection to IAB
service
logDebug("Starting inapp billing setup.");
mServiceConn = new
ServiceConnection() {
@Override
public void
onServiceDisconnected(Com
ponentName name) {
logDebug("Billing
service disconnected.");
mService = null;
}
@Override
public void
onServiceConnected(Compo
nentName name, IBinder
service) {
if (mDisposed)
return;
logDebug("Billing
service connected.");
mService =
IInAppBillingService.Stub.asI
nterface(service);
String packageName
=
mContext.getPackageName()
;
try {
logDebug("Checking for inapp billing 3 support.");
// check for inapp billing v3 support
int response =
mService.isBillingSupported(
3, packageName,
ITEM_TYPE_INAPP);
if (response !=
BILLING_RESPONSE_RESULT_
OK) {
if (listener !=
null)
listener.onIabSetupFinished(
new IabResult(response,
"Error
checking for billing v3
support."));
// if in-app
purchases aren't supported,
neither are subscriptions.
mSubscriptionsSupported =
false;
return;
}
logDebug("In-app
billing version 3 supported
for " + packageName);
// check for v3
subscriptions support
response =
mService.isBillingSupported(
3, packageName,
ITEM_TYPE_SUBS);
if (response ==
BILLING_RESPONSE_RESULT_
OK) {
logDebug("Subscriptions
AVAILABLE.");
mSubscriptionsSupported =
true;
}
else {
logDebug("Subscriptions
NOT AVAILABLE. Response: "
+ response);
}
mSetupDone =
true;
}
catch
(RemoteException e) {
if (listener != null)
{
listener.onIabSetupFinished(
new
IabResult(IABHELPER_REMO
TE_EXCEPTION,
"RemoteException while
setting up in-app billing."));
}
e.printStackTrace();
return;
}
if (listener != null) {
listener.onIabSetupFinished(
new
IabResult(BILLING_RESPONS
E_RESULT_OK, "Setup
successful."));
}
}
};
Intent serviceIntent =
new
Intent("com.android.vending
.billing.InAppBillingService.BI
ND");
serviceIntent.setPackage("co
m.android.vending");
if
(!mContext.getPackageMana
ger().queryIntentServices(ser
viceIntent, 0).isEmpty()) {
// service available to
handle that Intent
mContext.bindService(servic
eIntent, mServiceConn,
Context.BIND_AUTO_CREATE
);
}
else {
// no service available
to handle that Intent
if (listener != null) {
listener.onIabSetupFinished(
new
IabResult(BILLING_RESPONS
E_RESULT_BILLING_UNAVAIL
ABLE,
"Billing service
unavailable on device."));
}
}
}
/**
* Dispose of object,
releasing resources. It's very
important to call this
* method when you are
done with this object. It will
release any resources
* used by it such as
service connections.
Naturally, once the object is
* disposed of, it can't be
used again.
*/
public void dispose() {
logDebug("Disposing.");
mSetupDone = false;
if (mServiceConn != null)
{
logDebug("Unbinding
from service.");
if (mContext != null)
mContext.unbindService(mS
erviceConn);
}
mDisposed = true;
mContext = null;
mServiceConn = null;
mService = null;
mPurchaseListener =
null;
}
private void
checkNotDisposed() {
if (mDisposed) throw
new
IllegalStateException("IabHel
per was disposed of, so it
cannot be used.");
}
/** Returns whether
subscriptions are supported.
*/
public boolean
subscriptionsSupported() {
checkNotDisposed();
return
mSubscriptionsSupported;
}
/**
* Callback that notifies
when a purchase is finished.
*/
public interface
OnIabPurchaseFinishedListen
er {
/**
* Called to notify that
an in-app purchase finished.
If the purchase was
successful,
* then the sku
parameter specifies which
item was purchased. If the
purchase failed,
* the sku and extraData
parameters may or may not
be null, depending on how
far the purchase
* process went.
*
* @param result The
result of the purchase.
* @param info The
purchase information (null if
purchase failed)
*/
public void
onIabPurchaseFinished(IabRe
sult result, Purchase info);
}
// The listener registered
on launchPurchaseFlow,
which we have to call back
when
// the purchase finishes
OnIabPurchaseFinishedListen
er mPurchaseListener;
public void
launchPurchaseFlow(Activity
act, String sku, int
requestCode,
OnIabPurchaseFinishedListen
er listener) {
launchPurchaseFlow(act,
sku, requestCode, listener,
"");
}
public void
launchPurchaseFlow(Activity
act, String sku, int
requestCode,
OnIabPurchaseFinishedListen
er listener, String extraData)
{
launchPurchaseFlow(act,
sku, ITEM_TYPE_INAPP,
requestCode, listener,
extraData);
}
public void
launchSubscriptionPurchaseF
low(Activity act, String sku,
int requestCode,
OnIabPurchaseFinishedListen
er listener) {
launchSubscriptionPurchaseF
low(act, sku, requestCode,
listener, "");
}
public void
launchSubscriptionPurchaseF
low(Activity act, String sku,
int requestCode,
OnIabPurchaseFinishedListen
er listener, String extraData)
{
launchPurchaseFlow(act,
sku, ITEM_TYPE_SUBS,
requestCode, listener,
extraData);
}
/**
* Initiate the UI flow for
an in-app purchase. Call this
method to initiate an in-app
purchase,
* which will involve
bringing up the Google Play
screen. The calling activity
will be paused while
* the user interacts with
Google Play, and the result
will be delivered via the
activity's
* {@link
android.app.Activity#onActiv
ityResult} method, at which
point you must call
* this object's {@link
#handleActivityResult}
method to continue the
purchase flow. This method
* MUST be called from the
UI thread of the Activity.
*
* @param act The calling
activity.
* @param sku The sku of
the item to purchase.
* @param itemType
indicates if it's a product or a
subscription
(ITEM_TYPE_INAPP or
ITEM_TYPE_SUBS)
* @param requestCode A
request code (to
differentiate from other
responses -* as in {@link
android.app.Activity#startAct
ivityForResult}).
* @param listener The
listener to notify when the
purchase process finishes
* @param extraData Extra
data (developer payload),
which will be returned with
the purchase data
* when the purchase
completes. This extra data
will be permanently bound
to that purchase
* and will always be
returned when the purchase
is queried.
*/
public void
launchPurchaseFlow(Activity
act, String sku, String
itemType, int requestCode,
OnIabPurchaseFinishedListen
er listener, String extraData)
{
checkNotDisposed();
checkSetupDone("launchPur
chaseFlow");
flagStartAsync("launchPurch
aseFlow");
IabResult result;
if
(itemType.equals(ITEM_TYPE
_SUBS) &&
!mSubscriptionsSupported) {
IabResult r = new
IabResult(IABHELPER_SUBSC
RIPTIONS_NOT_AVAILABLE,
"Subscriptions are
not available.");
flagEndAsync();
if (listener != null)
listener.onIabPurchaseFinish
ed(r, null);
return;
}
try {
logDebug("Constructing buy
intent for " + sku + ", item
type: " + itemType);
Bundle
buyIntentBundle =
mService.getBuyIntent(3,
mContext.getPackageName()
, sku, itemType, extraData);
int response =
getResponseCodeFromBundl
e(buyIntentBundle);
if (response !=
BILLING_RESPONSE_RESULT_
OK) {
logError("Unable to
buy item, Error response: " +
getResponseDesc(response))
;
flagEndAsync();
result = new
IabResult(response, "Unable
to buy item");
if (listener != null)
listener.onIabPurchaseFinish
ed(result, null);
return;
}
PendingIntent
pendingIntent =
buyIntentBundle.getParcelab
le(RESPONSE_BUY_INTENT);
logDebug("Launching
buy intent for " + sku + ".
Request code: " +
requestCode);
mRequestCode =
requestCode;
mPurchaseListener =
listener;
mPurchasingItemType
= itemType;
act.startIntentSenderForResu
lt(pendingIntent.getIntentSe
nder(),
requestCode, new Intent(),
Integer.valueOf(0),
Integer.valueOf(0),
Integer.valueOf(0));
}
catch
(SendIntentException e) {
logError("SendIntentExceptio
n while launching purchase
flow for sku " + sku);
e.printStackTrace();
flagEndAsync();
result = new
IabResult(IABHELPER_SEND_I
NTENT_FAILED, "Failed to
send intent.");
if (listener != null)
listener.onIabPurchaseFinish
ed(result, null);
}
catch (RemoteException
e) {
logError("RemoteException
while launching purchase
flow for sku " + sku);
e.printStackTrace();
flagEndAsync();
result = new
IabResult(IABHELPER_REMO
TE_EXCEPTION, "Remote
exception while starting
purchase flow");
if (listener != null)
listener.onIabPurchaseFinish
ed(result, null);
}
}
/**
* Handles an activity
result that's part of the
purchase flow in in-app
billing. If you
* are calling {@link
#launchPurchaseFlow}, then
you must call this method
from your
* Activity's {@link
android.app.Activity@onActi
vityResult} method. This
method
* MUST be called from the
UI thread of the Activity.
*
* @param requestCode
The requestCode as you
received it.
* @param resultCode The
resultCode as you received it.
* @param data The data
(Intent) as you received it.
* @return Returns true if
the result was related to a
purchase flow and was
handled;
* false if the result was
not related to a purchase, in
which case you should
* handle it normally.
*/
public boolean
handleActivityResult(int
requestCode, int resultCode,
Intent data) {
IabResult result;
if (requestCode !=
mRequestCode) return false;
checkNotDisposed();
checkSetupDone("handleActi
vityResult");
// end of async purchase
operation that started on
launchPurchaseFlow
flagEndAsync();
if (data == null) {
logError("Null data in
IAB activity result.");
result = new
IabResult(IABHELPER_BAD_R
ESPONSE, "Null data in IAB
result");
if (mPurchaseListener
!= null)
mPurchaseListener.onIabPur
chaseFinished(result, null);
return true;
}
int responseCode =
getResponseCodeFromIntent
(data);
String purchaseData =
data.getStringExtra(RESPONS
E_INAPP_PURCHASE_DATA);
String dataSignature =
data.getStringExtra(RESPONS
E_INAPP_SIGNATURE);
if (resultCode ==
Activity.RESULT_OK &&
responseCode ==
BILLING_RESPONSE_RESULT_
OK) {
logDebug("Successful
resultcode from purchase
activity.");
logDebug("Purchase
data: " + purchaseData);
logDebug("Data
signature: " + dataSignature);
logDebug("Extras: " +
data.getExtras());
logDebug("Expected
item type: " +
mPurchasingItemType);
if (purchaseData ==
null || dataSignature == null)
{
logError("BUG:
either purchaseData or
dataSignature is null.");
logDebug("Extras: "
+ data.getExtras().toString());
result = new
IabResult(IABHELPER_UNKN
OWN_ERROR, "IAB returned
null purchaseData or
dataSignature");
if
(mPurchaseListener != null)
mPurchaseListener.onIabPur
chaseFinished(result, null);
return true;
}
Purchase purchase =
null;
try {
purchase = new
Purchase(mPurchasingItemT
ype, purchaseData,
dataSignature);
String sku =
purchase.getSku();
// Verify signature
if
(!Security.verifyPurchase(mSi
gnatureBase64,
purchaseData,
dataSignature)) {
logError("Purchase signature
verification FAILED for sku " +
sku);
result = new
IabResult(IABHELPER_VERIFI
CATION_FAILED, "Signature
verification failed for sku " +
sku);
if
(mPurchaseListener != null)
mPurchaseListener.onIabPur
chaseFinished(result,
purchase);
return true;
}
logDebug("Purchase
signature successfully
verified.");
}
catch (JSONException
e) {
logError("Failed to
parse purchase data.");
e.printStackTrace();
result = new
IabResult(IABHELPER_BAD_R
ESPONSE, "Failed to parse
purchase data.");
if
(mPurchaseListener != null)
mPurchaseListener.onIabPur
chaseFinished(result, null);
return true;
}
if (mPurchaseListener
!= null) {
mPurchaseListener.onIabPur
chaseFinished(new
IabResult(BILLING_RESPONS
E_RESULT_OK, "Success"),
purchase);
}
}
else if (resultCode ==
Activity.RESULT_OK) {
// result code was OK,
but in-app billing response
was not OK.
logDebug("Result code
was OK but in-app billing
response was not OK: " +
getResponseDesc(responseC
ode));
if (mPurchaseListener
!= null) {
result = new
IabResult(responseCode,
"Problem purchashing
item.");
mPurchaseListener.onIabPur
chaseFinished(result, null);
}
}
else if (resultCode ==
Activity.RESULT_CANCELED) {
logDebug("Purchase
canceled - Response: " +
getResponseDesc(responseC
ode));
result = new
IabResult(IABHELPER_USER_
CANCELLED, "User
canceled.");
if (mPurchaseListener
!= null)
mPurchaseListener.onIabPur
chaseFinished(result, null);
}
else {
logError("Purchase
failed. Result code: " +
Integer.toString(resultCode)
+ ". Response: " +
getResponseDesc(responseC
ode));
result = new
IabResult(IABHELPER_UNKN
OWN_PURCHASE_RESPONSE
, "Unknown purchase
response.");
if (mPurchaseListener
!= null)
mPurchaseListener.onIabPur
chaseFinished(result, null);
}
return true;
}
public Inventory
queryInventory(boolean
querySkuDetails, List<String>
moreSkus) throws
IabException {
return
queryInventory(querySkuDet
ails, moreSkus, null);
}
/**
* Queries the inventory.
This will query all owned
items from the server, as
well as
* information on
additional skus, if specified.
This method may block or
take long to execute.
* Do not call from a UI
thread. For that, use the
non-blocking version {@link
#refreshInventoryAsync}.
*
* @param
querySkuDetails if true, SKU
details (price, description,
etc) will be queried as well
* as purchase
information.
* @param moreItemSkus
additional PRODUCT skus to
query information on,
regardless of ownership.
* Ignored if null or if
querySkuDetails is false.
* @param moreSubsSkus
additional SUBSCRIPTIONS
skus to query information
on, regardless of ownership.
* Ignored if null or if
querySkuDetails is false.
* @throws IabException if
a problem occurs while
refreshing the inventory.
*/
public Inventory
queryInventory(boolean
querySkuDetails, List<String>
moreItemSkus,
List<String> moreSubsSkus)
throws IabException {
checkNotDisposed();
checkSetupDone("queryInve
ntory");
try {
Inventory inv = new
Inventory();
int r =
queryPurchases(inv,
ITEM_TYPE_INAPP);
if (r !=
BILLING_RESPONSE_RESULT_
OK) {
throw new
IabException(r, "Error
refreshing inventory
(querying owned items).");
}
if (querySkuDetails) {
r=
querySkuDetails(ITEM_TYPE_
INAPP, inv, moreItemSkus);
if (r !=
BILLING_RESPONSE_RESULT_
OK) {
throw new
IabException(r, "Error
refreshing inventory
(querying prices of items).");
}
}
// if subscriptions are
supported, then also query
for subscriptions
if
(mSubscriptionsSupported) {
r=
queryPurchases(inv,
ITEM_TYPE_SUBS);
if (r !=
BILLING_RESPONSE_RESULT_
OK) {
throw new
IabException(r, "Error
refreshing inventory
(querying owned
subscriptions).");
}
if (querySkuDetails)
{
r=
querySkuDetails(ITEM_TYPE_
SUBS, inv, moreItemSkus);
if (r !=
BILLING_RESPONSE_RESULT_
OK) {
throw new
IabException(r, "Error
refreshing inventory
(querying prices of
subscriptions).");
}
}
}
return inv;
}
catch (RemoteException
e) {
throw new
IabException(IABHELPER_RE
MOTE_EXCEPTION, "Remote
exception while refreshing
inventory.", e);
}
catch (JSONException e)
{
throw new
IabException(IABHELPER_BA
D_RESPONSE, "Error parsing
JSON response while
refreshing inventory.", e);
}
}
/**
* Listener that notifies
when an inventory query
operation completes.
*/
public interface
QueryInventoryFinishedListe
ner {
/**
* Called to notify that
an inventory query operation
completed.
*
* @param result The
result of the operation.
* @param inv The
inventory.
*/
public void
onQueryInventoryFinished(Ia
bResult result, Inventory inv);
}
/**
* Asynchronous wrapper
for inventory query. This will
perform an inventory
* query as described in
{@link #queryInventory}, but
will do so asynchronously
* and call back the
specified listener upon
completion. This method is
safe to
* call from a UI thread.
*
* @param
querySkuDetails as in {@link
#queryInventory}
* @param moreSkus as in
{@link #queryInventory}
* @param listener The
listener to notify when the
refresh operation completes.
*/
public void
queryInventoryAsync(final
boolean querySkuDetails,
final
List<String> moreSkus,
final
QueryInventoryFinishedListe
ner listener) {
final Handler handler =
new Handler();
checkNotDisposed();
checkSetupDone("queryInve
ntory");
flagStartAsync("refresh
inventory");
(new Thread(new
Runnable() {
public void run() {
IabResult result =
new
IabResult(BILLING_RESPONS
E_RESULT_OK, "Inventory
refresh successful.");
Inventory inv = null;
try {
inv =
queryInventory(querySkuDet
ails, moreSkus);
}
catch (IabException
ex) {
result =
ex.getResult();
}
flagEndAsync();
final IabResult
result_f = result;
final Inventory inv_f
= inv;
if (!mDisposed &&
listener != null) {
handler.post(new
Runnable() {
public void
run() {
listener.onQueryInventoryFin
ished(result_f, inv_f);
}
});
}
}
})).start();
}
public void
queryInventoryAsync(QueryI
nventoryFinishedListener
listener) {
queryInventoryAsync(true,
null, listener);
}
public void
queryInventoryAsync(boolea
n querySkuDetails,
QueryInventoryFinishedListe
ner listener) {
queryInventoryAsync(queryS
kuDetails, null, listener);
}
/**
* Consumes a given in-app
product. Consuming can only
be done on an item
* that's owned, and as a
result of consumption, the
user will no longer own it.
* This method may block
or take long to return. Do not
call from the UI thread.
* For that, see {@link
#consumeAsync}.
*
* @param itemInfo The
PurchaseInfo that represents
the item to consume.
* @throws IabException if
there is a problem during
consumption.
*/
void consume(Purchase
itemInfo) throws
IabException {
checkNotDisposed();
checkSetupDone("consume")
;
if
(!itemInfo.mItemType.equals
(ITEM_TYPE_INAPP)) {
throw new
IabException(IABHELPER_INV
ALID_CONSUMPTION,
"Items of type '" +
itemInfo.mItemType + "'
can't be consumed.");
}
try {
String token =
itemInfo.getToken();
String sku =
itemInfo.getSku();
if (token == null ||
token.equals("")) {
logError("Can't
consume "+ sku + ". No
token.");
throw new
IabException(IABHELPER_MI
SSING_TOKEN, "PurchaseInfo
is missing token for sku: "
+ sku + " " +
itemInfo);
}
logDebug("Consuming
sku: " + sku + ", token: " +
token);
int response =
mService.consumePurchase(
3,
mContext.getPackageName()
, token);
if (response ==
BILLING_RESPONSE_RESULT_
OK) {
logDebug("Successfully
consumed sku: " + sku);
}
else {
logDebug("Error
consuming consuming sku "
+ sku + ". " +
getResponseDesc(response))
;
throw new
IabException(response,
"Error consuming sku " +
sku);
}
}
catch (RemoteException
e) {
throw new
IabException(IABHELPER_RE
MOTE_EXCEPTION, "Remote
exception while consuming.
PurchaseInfo: " + itemInfo,
e);
}
}
/**
* Callback that notifies
when a consumption
operation finishes.
*/
public interface
OnConsumeFinishedListener
{
/**
* Called to notify that a
consumption has finished.
*
* @param purchase The
purchase that was (or was to
be) consumed.
* @param result The
result of the consumption
operation.
*/
public void
onConsumeFinished(Purchas
e purchase, IabResult result);
}
/**
* Callback that notifies
when a multi-item
consumption operation
finishes.
*/
public interface
OnConsumeMultiFinishedList
ener {
/**
* Called to notify that a
consumption of multiple
items has finished.
*
* @param purchases
The purchases that were (or
were to be) consumed.
* @param results The
results of each consumption
operation, corresponding to
each
* sku.
*/
public void
onConsumeMultiFinished(Lis
t<Purchase> purchases,
List<IabResult> results);
}
/**
* Asynchronous wrapper
to item consumption. Works
like {@link #consume}, but
* performs the
consumption in the
background and notifies
completion through
* the provided listener.
This method is safe to call
from a UI thread.
*
* @param purchase The
purchase to be consumed.
* @param listener The
listener to notify when the
consumption operation
finishes.
*/
public void
consumeAsync(Purchase
purchase,
OnConsumeFinishedListener
listener) {
checkNotDisposed();
checkSetupDone("consume")
;
List<Purchase>
purchases = new
ArrayList<Purchase>();
purchases.add(purchase);
consumeAsyncInternal(purch
ases, listener, null);
}
/**
* Same as {@link
consumeAsync}, but for
multiple items at once.
* @param purchases The
list of PurchaseInfo objects
representing the purchases
to consume.
* @param listener The
listener to notify when the
consumption operation
finishes.
*/
public void
consumeAsync(List<Purchase
> purchases,
OnConsumeMultiFinishedList
ener listener) {
checkNotDisposed();
checkSetupDone("consume")
;
consumeAsyncInternal(purch
ases, null, listener);
}
/**
* Returns a humanreadable description for the
given response code.
*
* @param code The
response code
* @return A humanreadable string explaining
the result code.
* It also includes the
result code numerically.
*/
public static String
getResponseDesc(int code) {
String[] iab_msgs =
("0:OK/1:User
Canceled/2:Unknown/" +
"3:Billing
Unavailable/4:Item
unavailable/" +
"5:Developer
Error/6:Error/7:Item Already
Owned/" +
"8:Item not
owned").split("/");
String[] iabhelper_msgs
= ("0:OK/-1001:Remote
exception during
initialization/" +
"1002:Bad response
received/" +
"1003:Purchase signature
verification failed/" +
"1004:Send intent failed/" +
"1005:User cancelled/" +
"1006:Unknown purchase
response/" +
"1007:Missing token/" +
"1008:Unknown error/" +
"1009:Subscriptions not
available/" +
"1010:Invalid consumption
attempt").split("/");
if (code <=
IABHELPER_ERROR_BASE) {
int index =
IABHELPER_ERROR_BASE code;
if (index >= 0 && index
< iabhelper_msgs.length)
return
iabhelper_msgs[index];
else return
String.valueOf(code) +
":Unknown IAB Helper
Error";
}
else if (code < 0 || code
>= iab_msgs.length)
return
String.valueOf(code) +
":Unknown";
else
return
iab_msgs[code];
}
// Checks that setup was
done; if not, throws an
exception.
void
checkSetupDone(String
operation) {
if (!mSetupDone) {
logError("Illegal state
for operation (" + operation
+ "): IAB helper is not set
up.");
throw new
IllegalStateException("IAB
helper is not set up. Can't
perform operation: " +
operation);
}
}
// Workaround to bug
where sometimes response
codes come as Long instead
of Integer
int
getResponseCodeFromBundl
e(Bundle b) {
Object o =
b.get(RESPONSE_CODE);
if (o == null) {
logDebug("Bundle
with null response code,
assuming OK (known
issue)");
return
BILLING_RESPONSE_RESULT_
OK;
}
else if (o instanceof
Integer) return
((Integer)o).intValue();
else if (o instanceof
Long) return
(int)((Long)o).longValue();
else {
logError("Unexpected
type for bundle response
code.");
logError(o.getClass().getNam
e());
throw new
RuntimeException("Unexpec
ted type for bundle response
code: " +
o.getClass().getName());
}
}
// Workaround to bug
where sometimes response
codes come as Long instead
of Integer
int
getResponseCodeFromIntent
(Intent i) {
Object o =
i.getExtras().get(RESPONSE_
CODE);
if (o == null) {
logError("Intent with
no response code, assuming
OK (known issue)");
return
BILLING_RESPONSE_RESULT_
OK;
}
else if (o instanceof
Integer) return
((Integer)o).intValue();
else if (o instanceof
Long) return
(int)((Long)o).longValue();
else {
logError("Unexpected
type for intent response
code.");
logError(o.getClass().getNam
e());
throw new
RuntimeException("Unexpec
ted type for intent response
code: " +
o.getClass().getName());
}
}
void flagStartAsync(String
operation) {
if (mAsyncInProgress)
throw new
IllegalStateException("Can't
start async operation (" +
operation + ")
because another async
operation(" +
mAsyncOperation + ") is in
progress.");
mAsyncOperation =
operation;
mAsyncInProgress =
true;
logDebug("Starting
async operation: " +
operation);
}
void flagEndAsync() {
logDebug("Ending async
operation: " +
mAsyncOperation);
mAsyncOperation = "";
mAsyncInProgress =
false;
}
int
queryPurchases(Inventory
inv, String itemType) throws
JSONException,
RemoteException {
// Query purchases
logDebug("Querying
owned items, item type: " +
itemType);
logDebug("Package
name: " +
mContext.getPackageName()
);
boolean
verificationFailed = false;
String continueToken =
null;
do {
logDebug("Calling
getPurchases with
continuation token: " +
continueToken);
Bundle ownedItems =
mService.getPurchases(3,
mContext.getPackageName()
,
itemType,
continueToken);
int response =
getResponseCodeFromBundl
e(ownedItems);
logDebug("Owned
items response: " +
String.valueOf(response));
if (response !=
BILLING_RESPONSE_RESULT_
OK) {
logDebug("getPurchases()
failed: " +
getResponseDesc(response))
;
return response;
}
if
(!ownedItems.containsKey(R
ESPONSE_INAPP_ITEM_LIST)
||
!ownedItems.containsKey(RE
SPONSE_INAPP_PURCHASE_
DATA_LIST)
||
!ownedItems.containsKey(RE
SPONSE_INAPP_SIGNATURE_
LIST)) {
logError("Bundle
returned from
getPurchases() doesn't
contain required fields.");
return
IABHELPER_BAD_RESPONSE;
}
String sku =
ownedSkus.get(i);
if
(Security.verifyPurchase(mSi
gnatureBase64,
purchaseData, signature)) {
logDebug("Sku is
owned: " + sku);
Purchase
purchase = new
Purchase(itemType,
purchaseData, signature);
ArrayList<String>
ownedSkus =
ownedItems.getStringArrayLi
st(
logDebug("Purchase data: " +
purchaseData);
}
RESPONSE_INAPP_ITEM_LIST
);
ArrayList<String>
purchaseDataList =
ownedItems.getStringArrayLi
st(
RESPONSE_INAPP_PURCHAS
E_DATA_LIST);
ArrayList<String>
signatureList =
ownedItems.getStringArrayLi
st(
RESPONSE_INAPP_SIGNATU
RE_LIST);
for (int i = 0; i <
purchaseDataList.size(); ++i) {
String purchaseData
= purchaseDataList.get(i);
String signature =
signatureList.get(i);
if
(TextUtils.isEmpty(purchase.
getToken())) {
logWarn("BUG:
empty/null token!");
// Record
ownership and token
inv.addPurchase(purchase);
}
else {
logWarn("Purchase signature
verification **FAILED**. Not
adding item.");
logDebug("
Purchase data: " +
purchaseData);
logDebug("
Signature: " + signature);
verificationFailed
= true;
}
}
continueToken =
ownedItems.getString(INAPP
_CONTINUATION_TOKEN);
logDebug("Continuation
token: " + continueToken);
} while
(!TextUtils.isEmpty(continue
Token));
return verificationFailed
?
IABHELPER_VERIFICATION_F
AILED :
BILLING_RESPONSE_RESULT_
OK;
}
int querySkuDetails(String
itemType, Inventory inv,
List<String> moreSkus)
throws
RemoteException,
JSONException {
logDebug("Querying SKU
details.");
ArrayList<String> skuList
= new ArrayList<String>();
skuList.addAll(inv.getAllOwn
edSkus(itemType));
if (moreSkus != null) {
for (String sku :
moreSkus) {
if
(!skuList.contains(sku)) {
skuList.add(sku);
}
}
}
if (skuList.size() == 0) {
logDebug("queryPrices:
nothing to do because there
are no SKUs.");
return
BILLING_RESPONSE_RESULT_
OK;
}
Bundle querySkus = new
Bundle();
querySkus.putStringArrayList
(GET_SKU_DETAILS_ITEM_LI
ST, skuList);
Bundle skuDetails =
mService.getSkuDetails(3,
mContext.getPackageName()
,
itemType,
querySkus);
if
(!skuDetails.containsKey(RES
PONSE_GET_SKU_DETAILS_LI
ST)) {
int response =
getResponseCodeFromBundl
e(skuDetails);
if (response !=
BILLING_RESPONSE_RESULT_
OK) {
logDebug("getSkuDetails()
failed: " +
getResponseDesc(response))
;
return response;
}
else {
logError("getSkuDetails()
returned a bundle with
neither an error nor a detail
list.");
return
IABHELPER_BAD_RESPONSE;
}
}
ArrayList<String>
responseList =
skuDetails.getStringArrayList(
RESPONSE_GET_SKU_DETAIL
S_LIST);
for (String thisResponse :
responseList) {
SkuDetails d = new
SkuDetails(itemType,
thisResponse);
logDebug("Got sku
details: " + d);
inv.addSkuDetails(d);
}
return
BILLING_RESPONSE_RESULT_
OK;
}
void
consumeAsyncInternal(final
List<Purchase> purchases,
final
OnConsumeFinishedListener
singleListener,
final
OnConsumeMultiFinishedList
ener multiListener) {
final Handler handler =
new Handler();
flagStartAsync("consume");
(new Thread(new
Runnable() {
public void run() {
final List<IabResult>
results = new
ArrayList<IabResult>();
for (Purchase
purchase : purchases) {
try {
consume(purchase);
results.add(new
IabResult(BILLING_RESPONS
E_RESULT_OK, "Successful
consume of sku " +
purchase.getSku()));
}
catch
(IabException ex) {
results.add(ex.getResult());
}
}
flagEndAsync();
if (!mDisposed &&
singleListener != null) {
handler.post(new
Runnable() {
public void
run() {
singleListener.onConsumeFin
ished(purchases.get(0),
results.get(0));
}
});
}
if (!mDisposed &&
multiListener != null) {
handler.post(new
Runnable() {
public void
run() {
multiListener.onConsumeMu
ltiFinished(purchases,
results);
}
});
}
}
})).start();
}
void logDebug(String msg)
Log.w(mDebugTag, "Inapp billing warning: " + msg);
}
}
IabResult.java
/* Copyright (c) 2012 Google
Inc.
*
* 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/licen
ses/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.
*/
{
if (mDebugLog)
Log.d(mDebugTag, msg);
}
void logError(String msg) {
Log.e(mDebugTag, "Inapp billing error: " + msg);
}
void logWarn(String msg) {
package
com.secrethq.store.util;
/**
* Represents the result of an
in-app billing operation.
* A result is composed of a
response code (an integer)
and possibly a
* message (String). You can
get those by calling
* {@link #getResponse} and
{@link #getMessage()},
respectively. You
* can also inquire whether a
result is a success or a failure
by
* calling {@link #isSuccess()}
and {@link #isFailure()}.
*/
public class IabResult {
int mResponse;
String mMessage;
public IabResult(int
response, String message) {
mResponse = response;
if (message == null ||
message.trim().length() == 0)
{
mMessage =
IabHelper.getResponseDesc(
response);
}
else {
mMessage = message
+ " (response: " +
IabHelper.getResponseDesc(
response) + ")";
}
}
public int getResponse() {
return mResponse; }
public String getMessage()
{ return mMessage; }
public boolean isSuccess()
{ return mResponse ==
IabHelper.BILLING_RESPONS
E_RESULT_OK; }
public boolean isFailure() {
return !isSuccess(); }
public String toString() {
return "IabResult: " +
getMessage(); }
}
Inventory.java
/* Copyright (c) 2012 Google
Inc.
*
* 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/licen
ses/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.secrethq.store.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Represents a block of
information about in-app
items.
* An Inventory is returned
by such methods as {@link
IabHelper#queryInventory}.
*/
public class Inventory {
Map<String,SkuDetails>
mSkuMap = new
HashMap<String,SkuDetails>
();
Map<String,Purchase>
mPurchaseMap = new
HashMap<String,Purchase>()
;
Inventory() { }
/** Returns the listing
details for an in-app product.
*/
public SkuDetails
getSkuDetails(String sku) {
return
mSkuMap.get(sku);
}
/** Returns purchase
information for a given
product, or null if there is no
purchase. */
public Purchase
getPurchase(String sku) {
return
mPurchaseMap.get(sku);
}
/** Returns whether or
not there exists a purchase
of the given product. */
public boolean
hasPurchase(String sku) {
return
mPurchaseMap.containsKey(
sku);
}
/** Return whether or not
details about the given
product are available. */
public boolean
hasDetails(String sku) {
return
mSkuMap.containsKey(sku);
}
/**
* Erase a purchase
(locally) from the inventory,
given its product ID. This just
* modifies the Inventory
object locally and has no
effect on the server! This is
* useful when you have an
existing Inventory object
which you know to be up to
date,
* and you have just
consumed an item
successfully, which means
that erasing its
* purchase data from the
Inventory you already have is
quicker than querying for
* a new Inventory.
*/
public void
erasePurchase(String sku) {
if
(mPurchaseMap.containsKey
(sku))
mPurchaseMap.remove(sku);
}
/** Returns a list of all
owned product IDs. */
List<String>
getAllOwnedSkus() {
return new
ArrayList<String>(mPurchase
Map.keySet());
}
/** Returns a list of all
owned product IDs of a given
type */
List<String>
getAllOwnedSkus(String
itemType) {
List<String> result = new
ArrayList<String>();
for (Purchase p :
mPurchaseMap.values()) {
if
(p.getItemType().equals(item
Type)) result.add(p.getSku());
}
return result;
}
/** Returns a list of all
purchases. */
public List<Purchase>
getAllPurchases() {
return new
ArrayList<Purchase>(mPurch
aseMap.values());
}
void
addSkuDetails(SkuDetails d) {
mSkuMap.put(d.getSku(), d);
}
void
addPurchase(Purchase p) {
mPurchaseMap.put(p.getSku
(), p);
}
}
Purchase.java
* Copyright (c) 2012 Google
Inc.
*
* 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/licen
ses/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.secrethq.store.util;
import
org.json.JSONException;
import org.json.JSONObject;
/**
* Represents an in-app
billing purchase.
*/
public class Purchase {
String mItemType; //
ITEM_TYPE_INAPP or
ITEM_TYPE_SUBS
String mOrderId;
String mPackageName;
String mSku;
long mPurchaseTime;
int mPurchaseState;
String mDeveloperPayload;
String mToken;
String mOriginalJson;
String mSignature;
public Purchase(String
itemType, String
jsonPurchaseInfo, String
signature) throws
JSONException {
mItemType = itemType;
mOriginalJson =
jsonPurchaseInfo;
JSONObject o = new
JSONObject(mOriginalJson);
mOrderId =
o.optString("orderId");
mPackageName =
o.optString("packageName");
mSku =
o.optString("productId");
mPurchaseTime =
o.optLong("purchaseTime");
mPurchaseState =
o.optInt("purchaseState");
mDeveloperPayload =
o.optString("developerPaylo
ad");
mToken =
o.optString("token",
o.optString("purchaseToken"
));
mSignature = signature;
}
public String getItemType()
{ return mItemType; }
public String getOrderId() {
return mOrderId; }
public String
getPackageName() { return
mPackageName; }
public String getSku() {
return mSku; }
public long
getPurchaseTime() { return
mPurchaseTime; }
public int
getPurchaseState() { return
mPurchaseState; }
public String
getDeveloperPayload() {
return mDeveloperPayload; }
public String getToken() {
return mToken; }
public String
getOriginalJson() { return
mOriginalJson; }
public String getSignature()
{ return mSignature; }
@Override
public String toString() {
return "PurchaseInfo(type:"
+ mItemType + "):" +
mOriginalJson; }
}
Security.java
/* Copyright (c) 2012 Google
Inc.
*
* 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/licen
ses/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.secrethq.store.util;
import
android.text.TextUtils;
import android.util.Log;
import
org.json.JSONException;
import org.json.JSONObject;
import
java.security.InvalidKeyExcep
tion;
import
java.security.KeyFactory;
import
java.security.NoSuchAlgorith
mException;
import
java.security.PublicKey;
import
java.security.Signature;
import
java.security.SignatureExcept
ion;
import
java.security.spec.InvalidKey
SpecException;
import
java.security.spec.X509Encod
edKeySpec;
/**
* Security-related methods.
For a secure implementation,
all of this code
* should be implemented on
a server that communicates
with the
* application on the device.
For the sake of simplicity and
clarity of this
* example, this code is
included here and is
executed on the device. If
you
* must verify the purchases
on the phone, you should
obfuscate this code to
* make it harder for an
attacker to replace the code
with stubs that treat all
* purchases as verified.
*/
public class Security {
private static final String
TAG = "IABUtil/Security";
private static final String
KEY_FACTORY_ALGORITHM
= "RSA";
private static final String
SIGNATURE_ALGORITHM =
"SHA1withRSA";
/**
* Verifies that the data
was signed with the given
signature, and returns
* the verified purchase.
The data is in JSON format
and signed
* with a private key. The
data also contains the {@link
PurchaseState}
* and product ID of the
purchase.
* @param
base64PublicKey the base64encoded public key to use for
verifying.
* @param signedData the
signed JSON string (signed,
not encrypted)
* @param signature the
signature for the data, signed
with the private key
*/
public static boolean
verifyPurchase(String
base64PublicKey, String
signedData, String signature)
{
if
(TextUtils.isEmpty(signedDat
a) ||
TextUtils.isEmpty(base64Pub
licKey) ||
TextUtils.isEmpty(signature))
{
Log.e(TAG, "Purchase
verification failed: missing
data.");
return false;
}
PublicKey key =
Security.generatePublicKey(b
ase64PublicKey);
return
Security.verify(key,
signedData, signature);
}
/**
* Generates a PublicKey
instance from a string
containing the
* Base64-encoded public
key.
*
* @param
encodedPublicKey Base64encoded public key
* @throws
IllegalArgumentException if
encodedPublicKey is invalid
*/
public static PublicKey
generatePublicKey(String
encodedPublicKey) {
try {
byte[] decodedKey =
Base64.decode(encodedPubl
icKey);
KeyFactory keyFactory
=
KeyFactory.getInstance(KEY_
FACTORY_ALGORITHM);
return
keyFactory.generatePublic(n
ew
X509EncodedKeySpec(decod
edKey));
} catch
(NoSuchAlgorithmException
e) {
throw new
RuntimeException(e);
} catch
(InvalidKeySpecException e) {
Log.e(TAG, "Invalid
key specification.");
throw new
IllegalArgumentException(e);
} catch
(Base64DecoderException e)
{
Log.e(TAG, "Base64
decoding failed.");
throw new
IllegalArgumentException(e);
}
}
/**
* Verifies that the
signature from the server
matches the computed
* signature on the data.
Returns true if the data is
correctly signed.
*
* @param publicKey
public key associated with
the developer account
* @param signedData
signed data from server
* @param signature
server signature
* @return true if the data
and signature match
*/
public static boolean
verify(PublicKey publicKey,
String signedData, String
signature) {
Signature sig;
try {
sig =
Signature.getInstance(SIGNA
TURE_ALGORITHM);
sig.initVerify(publicKey);
sig.update(signedData.getByt
es());
if
(!sig.verify(Base64.decode(si
gnature))) {
Log.e(TAG,
"Signature verification
failed.");
return false;
}
return true;
} catch
(NoSuchAlgorithmException
e) {
Log.e(TAG,
"NoSuchAlgorithmException.
");
} catch
(InvalidKeyException e) {
Log.e(TAG, "Invalid
key specification.");
} catch
(SignatureException e) {
Log.e(TAG, "Signature
exception.");
} catch
(Base64DecoderException e)
{
Log.e(TAG, "Base64
decoding failed.");
}
return false;
}
}
SkuDetails.java
/* Copyright (c) 2012 Google
Inc.
*
* 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/licen
ses/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.secrethq.store.util;
import
org.json.JSONException;
import org.json.JSONObject;
/**
* Represents an in-app
product's listing details.
*/
public class SkuDetails {
String mItemType;
String mSku;
String mType;
String mPrice;
String mTitle;
String mDescription;
String mJson;
public SkuDetails(String
jsonSkuDetails) throws
JSONException {
this(IabHelper.ITEM_TYPE_IN
APP, jsonSkuDetails);
}
public SkuDetails(String
itemType, String
jsonSkuDetails) throws
JSONException {
mItemType = itemType;
mJson = jsonSkuDetails;
JSONObject o = new
JSONObject(mJson);
mSku =
o.optString("productId");
mType =
o.optString("type");
mPrice =
o.optString("price");
mTitle =
o.optString("title");
mDescription =
o.optString("description");
}
public String getSku() {
return mSku; }
public String getType() {
return mType; }
public String getPrice() {
return mPrice; }
public String getTitle() {
return mTitle; }
public String
getDescription() { return
mDescription; }
@Override
public String toString() {
return "SkuDetails:" +
mJson;
}
}
PTStoreBridge.java
package com.secrethq.store;
import
java.lang.ref.WeakReference;
import java.util.List;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
import
android.app.AlertDialog;
import
android.app.ProgressDialog;
import
android.content.DialogInterf
ace;
import android.util.Log;
import
com.secrethq.store.util.*;
import
com.secrethq.utils.PTService
sBridge;
public class PTStoreBridge {
private static
boolean readyToPurchase =
false;
private static
IabHelper mHelper;
private static
Cocos2dxActivity activity;
private static
WeakReference<Cocos2dxAc
tivity> s_activity;
private static
Inventory inventory;
private static final
String TAG =
"PTStoreBridge";
private static native String
licenseKey();
public static native void
purchaseDidComplete( String
productId );
public static native void
purchaseDidCompleteRestori
ng(String productId);
public static native
boolean
isProductConsumible( String
productId );
static public void
initBridge(Cocos2dxActivity
_activity){
activity =
_activity;
s_activity =
new
WeakReference<Cocos2dxAc
tivity>(activity);
mHelper =
new IabHelper(activity,
licenseKey());
readyToPurchase = true;
}
}
});
} catch
(Exception e) {
Log.v(TAG,
"IabHelper.startSetup :
FAILED : " + e.getMessage());
}
}
s_activity.get().runO
nUiThread( new Runnable() {
public void run() {
IabHelper.OnIabPurc
haseFinishedListener
mPurchaseFinishedListener
= new
IabHelper.OnIabPurchaseFini
shedListener() {
public void
onIabPurchaseFinished(IabRe
sult result, Purchase
purchase)
{
if
(result.isFailure()) {
Log.d(TAG, "Error
purchasing: " + result);
public static IabHelper
iabHelper() {
return
mHelper;
}
if(result.getResponse() ==
IabHelper.BILLING_RESPONS
E_RESULT_ITEM_ALREADY_O
WNED){
try {
mHelper.startSetup(
new
IabHelper.OnIabSetupFinishe
dListener() {
public static void
setInventory( Inventory
_inventory){
inventory =
_inventory;
}
public void
onIabSetupFinished(IabResul
t result) {
if
(!result.isSuccess()) {
Log.d(TAG,
"Problem setting up In-app
Billing: " + result);
readyToPurchase = false;
static public void
purchase( final String storeId
){
if (
!readyToPurchase ) {
Log.e(TAG, "In-app
Billing not Ready");
return;
}
} else {
if(!isProductConsumible(
storeId )){
Log.v(TAG, "Product
alreasdy ownded - restored:"
+ storeId);
purchaseDidComplete(
storeId );
}
else{
Log.v(TAG, "Product
alreasdy ownded consuming:" + storeId);
consumeStoreId(
storeId );
}
}
return;
}
if(
isProductConsumible(
purchase.getSku() ) ){
Log.v(TAG, "Consuming
product: " +
purchase.getSku());
consumePurchase( purchase
);
}
else{
Log.v(TAG, "Purchase did
completed:" +
purchase.getSku());
purchaseDidComplete(
purchase.getSku() );
}
Log.e(TAG,
"Consuming by StoreID " +
storeId);
"Inventory: " +
purchase.getSku());
inventory
// request
if(storeId.equals(
purchase.getSku() )){
s_activity.get().runO
nUiThread( new Runnable() {
public void run() {
consumePurchase( purchase
);
}
IabHelper.QueryInve
ntoryFinishedListener
mGotInventoryListener
=
new
IabHelper.QueryInventoryFin
ishedListener() {
public void
onQueryInventoryFinished(Ia
bResult result,
}
};
Inventory inventory) {
try {
(result.isFailure()) {
if
mHelper.launchPurc
haseFlow(activity, storeId,
10001,
mPurchaseFinishedListener,
null);
} catch
(Exception e) {
Log.v(TAG,
"launchPurchaseFlow :
FAILED : " + e.getMessage());
}
}
});
}
static void
consumeStoreId(final String
storeId){
Log.v(TAG,
"INVENTORY FAILURE: " +
result);
}
else {
setInventory(
inventory );
List<Purchase>
purchases =
inventory.getAllPurchases();
for (Purchase
purchase : purchases){
Log.v(TAG,
}
}
}
};
try {
mHelper.queryInvent
oryAsync(mGotInventoryList
ener);
}
catch (Exception e) {
Log.v(TAG,
"queryInventoryAsync :
FAILED : " + e.getMessage());
}
}
});
}
static public void
restorePurchases(){
if (
!readyToPurchase ) {
Log.e(TAG, "In-app
Billing not Ready");
return;
}
s_activity.get().runO
nUiThread( new Runnable() {
public void run() {
final
ProgressDialog progress;
progress =
ProgressDialog.show(activity,
null,
"Restoring
purchases...", true);
IabHelper.QueryInve
ntoryFinishedListener
mGotInventoryListener
=
new
IabHelper.QueryInventoryFin
ishedListener() {
"Inventory: " +
purchase.getSku());
Log.v(TAG,
"queryInventoryAsync :
FAILED : " + e.getMessage());
}
}
});
}
if( !
isProductConsumible(
purchase.getSku() )){
purchaseDidComplet
eRestoring(
purchase.getSku() );
if (
!readyToPurchase ) {
}
}
}
public void
onQueryInventoryFinished(Ia
bResult result,
progress.dismiss();
Inventory inventory) {
(result.isFailure()) {
AlertDialog.Builder dlgAlert
= new AlertDialog.Builder(
activity );
Log.v(TAG,
"INVENTORY FAILURE: " +
result);
dlgAlert.setMessage(
"Restore purchases
complete");
if
static public void
consumePurchase( final
Purchase purchase ){
Log.e(TAG, "In-app
Billing not Ready");
return;
}
}
else {
dlgAlert.setPositiveB
utton("OK", null);
setInventory(
inventory );
w();
dlgAlert.create().sho
s_activity.get().runO
nUiThread( new Runnable() {
public void run() {
Log.v(TAG, "Start
Consuming");
final ProgressDialog
progress;
progress =
ProgressDialog.show(activity,
null,
"Finalizing Purchase ...",
true);
}
};
List<Purchase>
purchases =
inventory.getAllPurchases();
for (Purchase
purchase : purchases){
Log.v(TAG,
try {
mHelper.queryInvent
oryAsync(mGotInventoryList
ener);
}
catch (Exception e) {
IabHelper.OnConsum
eFinishedListener
mConsumeFinishedListener =
new
IabHelper.OnConsumeFinish
edListener() {
"consumeAsync : FAILED : " +
e.getMessage());
public void
onConsumeFinished(Purchas
e purchase, IabResult result)
{
}
}
}
if
(result.isSuccess()) {
});
}
}
PTServicesBridge.java
package com.secrethq.utils;
purchaseDidComplete(
purchase.getSku() );
}
else {
Log.v(TAG, "Error
consume: " + result);
}
progress.dismiss();
}
};
if(purchase != null){
try {
mHelper.consumeAs
ync(purchase,
mConsumeFinishedListener);
} catch (Exception e)
{
Log.v(TAG,
import
java.lang.ref.WeakReference;
import java.io.File;
import java.io.FileFilter;
import
java.io.UnsupportedEncoding
Exception;
import
java.security.MessageDigest;
import
java.security.NoSuchAlgorith
mException;
import
java.util.regex.Pattern;
import java.nio.IntBuffer;
import
org.cocos2dx.lib.Cocos2dxAc
tivity;
import
com.google.android.gms.R;
import
com.google.android.gms.ads.
AdRequest;
import
com.google.android.gms.co
mmon.ConnectionResult;
import
com.google.android.gms.co
mmon.GooglePlayServicesUti
l;
import
com.google.android.gms.co
mmon.api.GoogleApiClient;
import
com.google.android.gms.ga
mes.Games;
import
com.google.android.gms.ga
mes.Player;
import
com.google.android.gms.plus
.Plus;
import
android.app.AlertDialog;
import
android.os.StrictMode;
import android.content.*;
import
android.content.IntentSende
r.SendIntentException;
import android.net.Uri;
import
android.opengl.GLSurfaceVie
w;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import
android.graphics.Bitmap;
import
android.os.Environment;
import
java.io.FileOutputStream;
import android.net.Uri;
import
javax.microedition.khronos.e
gl.EGLContext;
import
javax.microedition.khronos.e
gl.EGL10;
import
javax.microedition.khronos.o
pengles.GL10;
import
android.app.UiModeManage
r;
import
android.content.res.Configur
ation;
import
android.view.ViewGroup;
import
android.widget.FrameLayout
;
public class PTServicesBridge
implements
GoogleApiClient.Connection
Callbacks,
GoogleApiClient.OnConnecti
onFailedListener{
private static
PTServicesBridge sInstance;
private static final
String TAG =
"PTServicesBridge";
private static native
String getLeaderboardId();
private static native
void
warningMessageClicked(bool
ean accepted);
public static native
boolean removeAds();
private static
Cocos2dxActivity activity;
private static
WeakReference<Cocos2dxAc
tivity> s_activity;
private static final int
REQUEST_LEADERBOARD =
5000;
public static
PTServicesBridge instance() {
if (sInstance
== null)
sInstance = new
PTServicesBridge();
return
sInstance;
}
public static void
initBridge(Cocos2dxActivity
activity, String appId){
Log.v(TAG,
"PTServicesBridge -- INIT");
PTServicesBridge.s_a
ctivity = new
WeakReference<Cocos2dxAc
tivity>(activity);
PTServicesBridge.acti
vity = activity;
if(appId ==
null || appId.length() == 0 ||
appId.matches("[0-9]+") ==
false){
return;
}
private static
GoogleApiClient
mGoogleApiClient;
private static String
urlString;
private static int
scoreValue;
public static final int
RC_SIGN_IN = 9001;
SharedPreferences
sharedPref =
activity.getPreferences(Cont
ext.MODE_PRIVATE);
if(sharedPref.getBool
ean("GooglePlayServiceSignI
nError", false) == true){
Log.v(TAG, "Skipping
logging in Google Play
services");
return;
}
// Create a
GoogleApiClient instance
PTServicesBridge.mG
oogleApiClient = new
GoogleApiClient.Builder(PTSe
rvicesBridge.activity)
.addApi(Plus.API).ad
dScope(Plus.SCOPE_PLUS_LO
GIN)
.addApi(Games.API).
addScope(Games.SCOPE_GA
MES)
.addConnectionCallb
acks(instance())
.addOnConnectionFa
iledListener(instance())
.build();
}
public static void
openShareWidget( final
String message ){
View content
=
activity.findViewById(androi
d.R.id.content);
GLSurfaceView
glView = null;
if(content
instanceof ViewGroup){
//
Diving one more level deeper
to find a proper FrameLayout
ViewGroup
viewGroup =
(ViewGroup)((ViewGroup)co
ntent).getChildAt(0);
for
(int i = 0; i <
viewGroup.getChildCount();
i++) {
StrictMode.VmPolicy.Builder(
);
Bitmap
screenshot =
createBitmapFromGLSurface
(0, 0, width, height, gl);
try {
File
View child =
viewGroup.getChildAt(i);
if(child instanceof
GLSurfaceView){
glView =
(GLSurfaceView)child;
StrictMode.setVmPolicy(buil
der.build());
outputDir =
activity.getExternalCacheDir(
);
final
File file =
File.createTempFile("screens
hot", ".png", outputDir);
// now finally
we have screenshot so we
need to call Intent and
submit message and
screenshot together
Log.v(TAG,
"PTServicesBridge -openShareWidget with text:"
+ message);
break;
}
}
}
final int
width = glView.getWidth();
final int
height = glView.getHeight();
if(glView !=
null) {
//We
have to grab GL buffer right
after we done rendering
FileOutputStream
stream = new
FileOutputStream(file);
screenshot.compress
(Bitmap.CompressFormat.PN
G, 85, stream);
sharingIntent.setTyp
e("image/*");
stream.flush();
stream.close();
glView.queueEvent(n
ew Runnable() {
@Override
Intent
sharingIntent = new
Intent(android.content.Inten
t.ACTION_SEND);
sharingIntent.putExtr
a(android.content.Intent.EXT
RA_TEXT, message);
activity.runOnUiThre
ad(new Runnable() {
public void run() {
EGL10 egl =
(EGL10)EGLContext.getEGL();
@Override
GL10 gl =
(GL10)egl.eglGetCurrentCont
ext().getGL();
public void run() {
StrictMode.VmPolicy.Builder
builder = new
sharingIntent.putExtr
a(Intent.EXTRA_STREAM,
Uri.fromFile(file));
activity.startActivity(I
ntent.createChooser(sharingI
ntent, "Share" ));
}
w, h, GL10.GL_RGBA,
GL10.GL_UNSIGNED_BYTE,
intBuffer);
int
offset1, offset2;
for
(int i = 0; i < h; i++) {
});
offset1 = i * w;
}
offset2 = (h - i - 1) *
w;
catch
(Exception e) {
for (int j = 0; j < w;
j++) {
Log.d(TAG,
"Screenshot writing Error");
int
texturePixel =
bitmapBuffer[offset1 + j];
}
int blue =
(texturePixel >> 16) & 0xff;
}
});
}
}
int red =
(texturePixel << 16) &
0x00ff0000;
private static Bitmap
createBitmapFromGLSurface
(int x, int y, int w, int h, GL10
gl) {
int pixel =
(texturePixel & 0xff00ff00) |
red | blue;
int
bitmapBuffer[] = new int[w *
h];
int
bitmapSource[] = new int[w
* h];
IntBuffer
intBuffer =
IntBuffer.wrap(bitmapBuffer)
;
bitmapSource[offset
2 + j] = pixel;
}
}
} catch
gl.glReadPixels(x, y,
public static int
availableProcessors() {
int
processorsNum =
Runtime.getRuntime().availa
bleProcessors();
Log.d(TAG,
"availableProcessors: " +
processorsNum);
return
processorsNum;
}
public static int
getCoresNumber() {
class
CpuFilter implements
FileFilter {
@Override
public boolean
accept(File pathname) {
//Check if
filename is "cpu", followed
by a single digit number
if(Pattern.matches("cpu[09]+", pathname.getName()))
{
return true;
}
(Exception e) {
return false;
Log.e(TAG,
"createBitmapFromGLSurfac
e: " + e.getMessage(), e);
intBuffer.position(0);
try {
return
Bitmap.createBitmap(bitmap
Source, w, h,
Bitmap.Config.ARGB_8888);
}
return null;
}
}
}
try {
//Get directory
containing CPU info
File dir = new
File("/sys/devices/system/cp
u/");
public void run() {
PTServicesBridge.s_a
ctivity.get().runOnUiThread(
new Runnable() {
try {
//Filter to only
list the devices we care
about
File[] files =
dir.listFiles(new CpuFilter());
Log.d(TAG, "CPU
Count: "+files.length);
//Return the
number of cores (virtual CPU
devices)
return
files.length;
final Intent
intent = new
Intent(Intent.ACTION_VIEW).
setData(Uri.parse(PTServices
Bridge.urlString));
PTServicesBridge.acti
vity.startActivity(intent);
} catch(Exception e) {
public void run() {
String leaderboardId
=
PTServicesBridge.getLeaderb
oardId();
if(leaderboardId ==
null ||
leaderboardId.isEmpty()){
//Print exception
return;
} catch(Exception
e) {
//Print
Log.d(TAG, "OpenURL:
Failed.");
}
exception
Log.d(TAG, "CPU
Count: Failed.");
e.printStackTrace();
}
}
e.printStackTrace();
});
PTServicesBridge.acti
vity.startActivityForResult(Ga
mes.Leaderboards.getLeader
boardIntent(PTServicesBridg
e.mGoogleApiClient,
}
//Default to
return 1 core
return 1;
}
}
public static void
openUrl( String url ){
Log.v(TAG,
"PTServicesBridge -- Open
URL " + url);
PTServicesBridge.url
String = url;
PTServicesBridge.s_a
ctivity.get().runOnUiThread(
new Runnable() {
public static void
showLeaderboard( ){
Log.v(TAG,
"PTServicesBridge -- Show
Leaderboard ");
if(PTServicesBridge.
mGoogleApiClient == null ||
PTServicesBridge.mGoogleAp
iClient.isConnected() ==
false){
Log.e(TAG, "Google
play Servioces is not
sigend");
return;
}
leaderboardId),
REQUEST_LEADERBOARD);
}
});
}
public static void
showCustomFullScreenAd() {
Log.e(TAG,
"PTServicesBridge -showCustomFullScreenAd");
}
public static void
screenOnEnter(String name){
Log.e(TAG,
"PTServicesBridge -screenOnEnter");
}
public static void
screenOnExit(String name){
Log.e(TAG,
"PTServicesBridge -screenOnExit");
}
public static void
loadingDidComplete() {
Log.e(TAG,
"PTServicesBridge -loadingDidComplete");
}
public static void
submitScrore( int score ){
Log.v(TAG,
"PTServicesBridge -- Submit
Score " + score);
if(PTServicesBridge.
mGoogleApiClient == null ||
PTServicesBridge.mGoogleAp
iClient.isConnected() ==
false){
Log.e(TAG, "Google
play Servioces is not
sigend");
return;
}
String
if (
PTServicesBridge.mGoogleAp
iClient.isConnected() ) {
Games.Leaderboards
.submitScore(PTServicesBrid
ge.mGoogleApiClient,
leaderboardId,
PTServicesBridge.scoreValue)
;
}
}
public static boolean
isRunningOnTV(){
null ||
leaderboardId.isEmpty()){
PTServicesBridge.s_a
ctivity.get().runOnUiThread(
new Runnable() {
public void run() {
try {
UiModeManager
uiModeManager =
(UiModeManager)PTServices
Bridge.activity.getSystemSer
vice(
Context.UI_MODE_SERVICE
);
if
(uiModeManager.getCurrent
ModeType() ==
Configuration.UI_MODE_TYP
E_TELEVISION) {
Log.d("DeviceTypeRu
ntimeCheck", "Running on a
TV Device");
return true;
leaderboardId =
PTServicesBridge.getLeaderb
oardId();
if(leaderboardId ==
public static void
showFacebookPage( final
String facebookURL, final
String facebookID){
Log.v(TAG,
"Show facebook page for
URL: " + facebookURL + " ID:
" + facebookID);
} else {
Log.d("DeviceTypeRu
ntimeCheck", "Running on a
non-TV Device");
Intent intent
= new
Intent(Intent.ACTION_VIEW,
Uri.parse("fb://page/" +
facebookID));
PTServicesBridge.acti
vity.startActivity(intent);
}
catch(Exception e) {
Log.v(TAG, "Show
facebook FAILED going to
exception handler : " +
e.getMessage());
try {
PTServicesBridge.acti
vity.startActivity(new
Intent(Intent.ACTION_VIEW,
Uri.parse( facebookURL )));
} catch
(Exception e2) {
return false;
return;
}
}
}
PTServicesBridge.sco
reValue = score;
Log.v(TAG, "Show
facebook exception handle
FAILED : " +
e2.getMessage());
DialogInterface.OnClickListen
er() {
}
}
}
});
public void
onClick(DialogInterface
dialog, int which) {
}
public static void
showWarningMessage(final
String message){
Log.v(TAG,
"Show warning with
message: " + message);
PTServicesBridge.war
ningMessageClicked( true );
}
});
dlgAlert.setCancelabl
PTServicesBridge.s_a
ctivity.get().runOnUiThread(
new Runnable() {
e(true);
dlgAlert.create().sho
w();
public void run() {
}
});
AlertDialog.Builder
dlgAlert = new
AlertDialog.Builder(
PTServicesBridge.activity );
dlgAlert.setMessage(
message);
dlgAlert.setNegative
Button("Cancel", new
DialogInterface.OnClickListen
er() {
public void
onClick(DialogInterface
dialog, int which) {
PTServicesBridge.warningMe
ssageClicked( false );
}
});
}
public static void
loginGameServices( ){
Log.v(TAG,
"PTServicesBridge -- Login
Game Services ");
if(PTServicesBridge.
mGoogleApiClient != null){
PTServicesBridge.mG
oogleApiClient.connect();
}
}
public static boolean
isGameServiceAvialable( ){
Log.v(TAG,
"PTServicesBridge -- Is Game
Service Avialable ");
piClient != null &&
PTServicesBridge.mGoogleAp
iClient.isConnected());
}
@Override
public void
onConnected(Bundle arg0) {
Log.v(TAG,
"PTServicesBridge -- API
Client Connected bundle:" +
arg0);
}
@Override
public void
onConnectionSuspended(int
arg0) {
Log.v(TAG,
"PTServicesBridge -- API
Client Connection Suspended
");
}
@Override
public void
onConnectionFailed(Connect
ionResult connectionResult) {
Log.v(TAG,
"PTServicesBridge -- API
Client Connection FAILED:" +
connectionResult);
if(connectionResult.h
asResolution()){
try {
connectionResult.sta
rtResolutionForResult(activit
y, RC_SIGN_IN);
}
catch (SendIntentException
e) {
mGoogleApiClient.co
dlgAlert.setPositiveB
utton("OK", new
return
(PTServicesBridge.mGoogleA
nnect();
}
}
}
public static void
backButtonPressed( ){
Log.v(TAG,
"PTServicesBridge -backButtonPressed");
PTServicesBridge.s_a
ctivity.get().runOnUiThread(
new Runnable() {
public void run() {
PTServicesBridge.acti
vity.moveTaskToBack(true);
}
});
}
public void
onActivityResult(int
requestCode, int
responseCode, Intent
intent){
if(requestCode ==
RC_SIGN_IN &&
responseCode == -1){
mGoogleApiClient.co
nnect();
byte[] sha1hash =
md.digest();
return
convertToHex(sha1hash);
}
sb.append(String.for
mat("%02x", b));
}
public static Object
sha1Init() {
sb.toString();
}
MessageDigest
digest = null;
try{
private static String
convertToHex(byte[] data) {
StringBuilder buf = new
StringBuilder();
for (byte b : data) {
int halfbyte = (b >>> 4)
& 0x0F;
int two_halfs = 0;
do {
buf.append((0 <=
halfbyte) && (halfbyte <= 9)
? (char) ('0' + halfbyte) :
(char) ('a' + (halfbyte - 10)));
halfbyte = b & 0x0F;
} while (two_halfs++ <
1);
}
return buf.toString();
}
return
digest =
MessageDigest.getInstance("
SHA-1");
}
catch
(NoSuchAlgorithmException
e){
Log.e(TAG,
"PTServicesBridge -NoSuchAlgorithmException")
;
}
return
digest;
}
public static void
sha1Update(Object digest,
byte[] data, int length) {
}
PTJniHelper.java
ackage com.secrethq.utils;
((MessageDigest)dig
est).update(data, 0, length);
}
public class PTJniHelper {
public static String
password() {
return
"F3f+dc2uslwWfawkmKjjWU
p2/XDJ/uBQTCzxIZ+psAgeL/8
nzvyxUBp3/XTOq+RcG3//L5q
osQgbefovzqbhCw==";
}
public static native
boolean isAdNetworkActive(
String name );
}
}
}
public static String
sha1( byte[] data, int length)
throws
NoSuchAlgorithmException,
UnsupportedEncodingExcept
ion {
MessageDigest md =
MessageDigest.getInstance("
SHA-1");
md.update(data, 0,
length);
public static String
sha1Finish(Object digest) {
byte[] hash =
((MessageDigest)digest).dige
st();
StringBuilder
sb = new StringBuilder();
for (byte b:
hash) {
Cocos2dxAccelerometer.jav
a
package org.cocos2dx.lib;
import
android.content.Context;
import
android.content.res.Configur
ation;
import
android.hardware.Sensor;
import
android.hardware.SensorEve
nt;
import
android.hardware.SensorEve
ntListener;
import
android.hardware.SensorMa
nager;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import
android.view.WindowManag
er;
import android.os.Build.*;
public class
Cocos2dxAccelerometer
implements
SensorEventListener {
//
========================
========================
===========
// Constants
//
========================
========================
===========
private static final
String TAG =
Cocos2dxAccelerometer.clas
s.getSimpleName();
//
========================
========================
===========
// Fields
//
========================
========================
===========
aultSensor(Sensor.TYPE_ACC
ELEROMETER);
final Display
display = ((WindowManager)
this.mContext.getSystemServ
ice(Context.WINDOW_SERVI
CE)).getDefaultDisplay();
this.mNaturalOrienta
private final Context
mContext;
private final
SensorManager
mSensorManager;
private final Sensor
mAccelerometer;
private final int
mNaturalOrientation;
//
========================
========================
===========
// Constructors
//
========================
========================
===========
public
Cocos2dxAccelerometer(final
Context pContext) {
this.mContext =
pContext;
this.mSensorManage
r = (SensorManager)
this.mContext.getSystemServ
ice(Context.SENSOR_SERVICE
);
this.mAccelerometer
=
this.mSensorManager.getDef
tion =
display.getOrientation();
}
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
public void enable() {
this.mSensorManage
r.registerListener(this,
this.mAccelerometer,
SensorManager.SENSOR_DEL
AY_GAME);
}
public void
setInterval(float interval) {
// Honeycomb
version is 11
if(android.os.Build.VERSION.
SDK_INT < 11) {
this.mSensorManager.registe
rListener(this,
this.mAccelerometer,
SensorManager.SENSOR_DEL
AY_GAME);
} else {
//convert
seconds to microseconds
this.mSensorManager.registe
rListener(this,
this.mAccelerometer,
(int)(interval*100000));
}
}
public void disable() {
this.mSensorManage
r.unregisterListener(this);
}
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
@Override
public void
onSensorChanged(final
SensorEvent pSensorEvent) {
if
(pSensorEvent.sensor.getTyp
e() !=
Sensor.TYPE_ACCELEROMET
ER) {
return;
}
float x =
pSensorEvent.values[0];
float y =
pSensorEvent.values[1];
final float z =
pSensorEvent.values[2];
/*
* Because
the axes are not swapped
when the device's screen
orientation
* changes.
So we should swap it here. In
tablets such as Motorola
Xoom,
* the default
orientation is landscape, so
should consider this.
*/
final int
orientation =
this.mContext.getResources(
).getConfiguration().orientati
on;
if
((orientation ==
Configuration.ORIENTATION
_LANDSCAPE) &&
(this.mNaturalOrientation !=
Surface.ROTATION_0)) {
final
float tmp = x;
x=y;
y=
tmp;
} else if
((orientation ==
Configuration.ORIENTATION
_PORTRAIT) &&
(this.mNaturalOrientation !=
Surface.ROTATION_0)) {
final
float tmp = x;
x = y;
y=tmp;
}
Cocos2dxGLSurfaceV
iew.queueAccelerometer(x,y,
z,pSensorEvent.timestamp);
/*
if(BuildConfig.DEBUG
){
Log.d(TAG, "x = " +
pSensorEvent.values[0] + " y
= " + pSensorEvent.values[1]
+"z="+
pSensorEvent.values[2]);
}
*/
}
@Override
public void
onAccuracyChanged(final
Sensor pSensor, final int
pAccuracy) {
}
//
========================
========================
===========
// Methods
// Native method called
from
Cocos2dxGLSurfaceView (To
be in the same thread)
//
========================
========================
===========
public static native
void onSensorChanged(final
float pX, final float pY, final
float pZ, final long
pTimestamp);
//
========================
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
}
Cocos2dxActivity.java
package org.cocos2dx.lib;
import
org.cocos2dx.lib.Cocos2dxHe
lper.Cocos2dxHelperListener;
import android.app.Activity;
import
android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import
android.view.ViewGroup;
import android.util.Log;
import
android.widget.FrameLayout
;
public abstract class
Cocos2dxActivity extends
Activity implements
Cocos2dxHelperListener {
//
========================
========================
===========
// Constants
//
========================
========================
===========
private static final
String TAG =
Cocos2dxActivity.class.getSi
mpleName();
// Fields
//
========================
========================
===========
private
Cocos2dxGLSurfaceView
mGLSurfaceView;
private
Cocos2dxHandler mHandler;
private static Context
sContext = null;
public static Context
getContext() {
return
sContext;
}
//
========================
========================
===========
// Constructors
//
========================
========================
===========
@Override
protected void
onCreate(final Bundle
savedInstanceState) {
super.onCreate(save
dInstanceState);
sContext =
this;
this.mHandler = new
Cocos2dxHandler(this);
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
@Override
protected void
onResume() {
super.onResume();
Cocos2dxHelper.onR
esume();
this.mGLSurfaceView
.onResume();
}
@Override
protected void
onPause() {
super.onPause();
this.init();
Cocos2dxHelper.onP
//
========================
========================
===========
ause();
Cocos2dxHelper.init(
this, this);
}
this.mGLSurfaceView
.onPause();
}
@Override
public void
showDialog(final String
pTitle, final String pMessage)
{
Message
msg = new Message();
msg.what =
Cocos2dxHandler.HANDLER_
SHOW_DIALOG;
msg.obj =
new
Cocos2dxHandler.DialogMes
sage(pTitle, pMessage);
this.mHandler.send
Message(msg);
}
public void
runOnGLThread(final
Runnable pRunnable) {
this.mGLSurfaceView
.queueEvent(pRunnable);
}
//
========================
========================
===========
// Methods
//
========================
========================
===========
public void init() {
ViewGroup.LayoutParams.W
RAP_CONTENT);
Cocos2dxEditText
edittext = new
Cocos2dxEditText(this);
edittext.setLayoutParams(edi
ttext_layout_params);
// ...add to FrameLayout
framelayout.addView(edittex
t);
//
Cocos2dxGLSurfaceView
this.mGLSurfaceView =
this.onCreateView();
// FrameLayout
// ...add to FrameLayout
@Override
public void
showEditTextDialog(final
String pTitle, final String
pContent, final int
pInputMode, final int
pInputFlag, final int
pReturnType, final int
pMaxLength) {
Message
msg = new Message();
msg.what =
Cocos2dxHandler.HANDLER_
SHOW_EDITBOX_DIALOG;
msg.obj =
new
Cocos2dxHandler.EditBoxMe
ssage(pTitle, pContent,
pInputMode, pInputFlag,
pReturnType, pMaxLength);
this.mHandler.send
Message(msg);
}
@Override
ViewGroup.LayoutParams
framelayout_params =
new
ViewGroup.LayoutParams(Vi
ewGroup.LayoutParams.FILL
_PARENT,
ViewGroup.LayoutParams.FIL
L_PARENT);
FrameLayout
framelayout = new
FrameLayout(this);
framelayout.setLayoutParam
s(framelayout_params);
// Cocos2dxEditText
layout
ViewGroup.LayoutParams
edittext_layout_params =
new
ViewGroup.LayoutParams(Vi
ewGroup.LayoutParams.FILL
_PARENT,
framelayout.addView(this.m
GLSurfaceView);
// Switch to supported
OpenGL (ARGB888) mode on
emulator
if (isAndroidEmulator())
this.mGLSurfaceView.setEGL
ConfigChooser(8 , 8, 8, 8, 16,
0);
this.mGLSurfaceView.setCoc
os2dxRenderer(new
Cocos2dxRenderer());
this.mGLSurfaceView.setCoc
os2dxEditText(edittext);
// Set framelayout as the
content view
setContentView(fra
melayout);
}
import java.util.LinkedList;
public
Cocos2dxGLSurfaceView
onCreateView() {
return new
Cocos2dxGLSurfaceView(this
);
}
private final static boolean
isAndroidEmulator() {
String model =
Build.MODEL;
Log.d(TAG, "model=" +
model);
String product =
Build.PRODUCT;
Log.d(TAG, "product=" +
product);
boolean isEmulator =
false;
if (product != null) {
isEmulator =
product.equals("sdk") ||
product.contains("_sdk") ||
product.contains("sdk_");
}
Log.d(TAG, "isEmulator="
+ isEmulator);
return isEmulator;
}
//
========================
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
}
Cocos2dxBitmap.java
package org.cocos2dx.lib;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import
android.content.Context;
import
android.graphics.Bitmap;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Paint;
import
android.graphics.Paint.Align;
import
android.graphics.Paint.Font
MetricsInt;
import
android.graphics.Rect;
import
android.graphics.Typeface;
import
android.text.TextPaint;
import
android.text.TextUtils;
import android.util.Log;
public class Cocos2dxBitmap
{
//
========================
========================
===========
// Constants
//
========================
========================
===========
/* The values are the
same as
cocos2dx/platform/CCImage.
h. */
private static final int
HORIZONTALALIGN_LEFT = 1;
private static final int
HORIZONTALALIGN_RIGHT =
2;
private static final int
HORIZONTALALIGN_CENTER
= 3;
private static final int
VERTICALALIGN_TOP = 1;
private static final int
VERTICALALIGN_BOTTOM =
2;
private static final int
VERTICALALIGN_CENTER = 3;
//
========================
========================
===========
// Fields
//
========================
========================
===========
private static Context
sContext;
//
========================
========================
===========
// Constructors
//
========================
========================
===========
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
public static void
setContext(final Context
pContext) {
final
Cocos2dxBitmap.sCo
ntext = pContext;
}
int pHeight) {
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
createTextBitmapSha
dowStroke( pString,
pFontName, pFontSize, 1.0f,
1.0f, 1.0f,
// text font
and color
//
========================
========================
===========
// Methods
//
========================
========================
===========
private static native
void nativeInitBitmapDC(final
int pWidth,
final
int pHeight, final byte[]
pPixels);
/**
* @param pWidth
*
the width to
draw, it can be 0
* @param pHeight
*
the height to
draw, it can be 0
*/
public static void
createTextBitmap(String
pString, final String
pFontName,
final
int pFontSize, final int
pAlignment, final int pWidth,
final float fontTintG, final
float fontTintB,
//
pAlignment, pWidth,
pHeight,
// alignment
and size
final int pAlignment,
final int pWidth, final int
pHeight, final boolean
shadow,
final float shadowDX,
final float shadowDY, final
float shadowBlur, final
boolean stroke,
false, 0.0f, 0.0f, 0.0f,
final float strokeR,
final float strokeG, final float
strokeB, final float
strokeSize) {
// no shadow
false, 1.0f, 1.0f, 1.0f, 1.0f);
// no
stroke
}
public static void
createTextBitmapShadowStr
oke(String pString, final
String pFontName, final int
pFontSize,
final int
horizontalAlignment =
pAlignment & 0x0F;
final int
verticalAlignment =
(pAlignment >> 4) & 0x0F;
pString =
Cocos2dxBitmap.refactorStri
ng(pString);
final Paint
paint =
Cocos2dxBitmap.newPaint(p
FontName, pFontSize,
horizontalAlignment);
// set the
paint color
final float fontTintR,
paint.setARGB(255,
(int)(255.0 * fontTintR),
(int)(255.0 * fontTintG),
(int)(255.0 * fontTintB));
final
TextProperty textProperty =
Cocos2dxBitmap.computeTe
xtProperty(pString, pWidth,
pHeight, paint);
final int
bitmapTotalHeight =
(pHeight == 0 ?
textProperty.mTotalHeight:
pHeight);
renderTextDeltaX =
bitmapPaddingX;
}
x=
Cocos2dxBitmap.computeX(li
ne,
textProperty.mMaxWidth,
horizontalAlignment);
if (
shadowDY < 0.0 )
{
renderTextDeltaY =
bitmapPaddingY;
}
}
canvas.drawText(line
, x + renderTextDeltaX, y +
renderTextDeltaY, paint);
y +=
textProperty.mHeightPerLine
;
}
final Bitmap
// padding
needed when using shadows
(not used otherwise)
float
bitmapPaddingX = 0.0f;
float
bitmapPaddingY = 0.0f;
float
renderTextDeltaX = 0.0f;
float
renderTextDeltaY = 0.0f;
bitmap =
Bitmap.createBitmap(textPro
perty.mMaxWidth +
(int)bitmapPaddingX,
bitmapTotalHeight +
(int)bitmapPaddingY,
Bitmap.Config.ARGB_8888);
final Canvas
canvas = new
Canvas(bitmap);
if ( shadow )
{
// draw
again with stroke on if
needed
if ( stroke ) {
final
Paint paintStroke =
Cocos2dxBitmap.newPaint(p
FontName, pFontSize,
horizontalAlignment);
paintStroke.setStyle(
Paint.Style.STROKE);
/* Draw
string. */
int
shadowColor = 0xff7d7d7d;
paint.setShadowLaye
r(shadowBlur, shadowDX,
shadowDY, shadowColor);
bitmapPaddingX =
Math.abs(shadowDX);
bitmapPaddingY =
Math.abs(shadowDY);
if (
shadowDX < 0.0 )
{
final
FontMetricsInt
fontMetricsInt =
paint.getFontMetricsInt();
int x = 0;
int y =
Cocos2dxBitmap.computeY(f
ontMetricsInt, pHeight,
textProperty.mTotalHeight,
verticalAlignment);
final String[]
lines = textProperty.mLines;
for (final
String line : lines) {
paintStroke.setStrok
eWidth(strokeSize * 0.5f);
paintStroke.setARGB
(255, (int)strokeR * 255,
(int)strokeG * 255,
(int)strokeB * 255);
x = 0;
y=
Cocos2dxBitmap.computeY(f
ontMetricsInt, pHeight,
textProperty.mTotalHeight,
verticalAlignment);
final
String[] lines2 =
textProperty.mLines;
for
(final String line : lines2) {
x=
Cocos2dxBitmap.computeX(li
ne,
textProperty.mMaxWidth,
horizontalAlignment);
canvas.drawText(line
, x + renderTextDeltaX, y +
renderTextDeltaY,
paintStroke);
y +=
textProperty.mHeightPerLine
;
/* Set type
face for paint, now it support
.ttf file. */
if
(pFontName.endsWith(".ttf")
){
try {
final Typeface
typeFace =
Cocos2dxTypefaces.get(
paint.setTextAlign(Ali
gn.CENTER);
break;
case
HORIZONTALALIGN_RIGHT:
paint.setTextAlign(Ali
gn.RIGHT);
break;
Cocos2dxBitmap.sCo
ntext, pFontName);
paint.setTypeface(ty
peFace);
}
catch (final Exception e) {
case
HORIZONTALALIGN_LEFT:
default:
paint.setTextAlign(Ali
gn.LEFT);
break;
}
}
}
Log.e("Cocos2dxBitm
ap", "error to create ttf type
face: "
+
Cocos2dxBitmap.init
NativeObject(bitmap);
}
private static Paint
newPaint(final String
pFontName, final int
pFontSize,
final
int pHorizontalAlignment) {
final Paint
paint = new Paint();
paint.setColor(Color.
WHITE);
pFontName);
/* The file may not
find, use system font. */
paint.setTypeface(Ty
peface.create(pFontName,
Typeface.NORMAL));
}
} else {
paint.setTypeface(Ty
peface.create(pFontName,
Typeface.NORMAL));
}
paint.setTextSize(pFo
ntSize);
paint.setAntiAlias(tru
e);
switch
(pHorizontalAlignment) {
case
HORIZONTALALIGN_CENTER:
return paint;
}
private static
TextProperty
computeTextProperty(final
String pString,
final
int pWidth, final int pHeight,
final Paint pPaint) {
final
FontMetricsInt fm =
pPaint.getFontMetricsInt();
final int h =
(int) Math.ceil(fm.bottom fm.top);
int
maxContentWidth = 0;
final String[]
lines =
Cocos2dxBitmap.splitString(p
String, pWidth,
pHeight, pPaint);
if (pWidth !=
0) {
ret =
pMaxWidth / 2;
maxContentWidth =
pWidth;
} else {
/*
Compute the max width. */
int
temp = 0;
for
(final String line : lines) {
temp = (int)
Math.ceil(pPaint.measureTex
t(line, 0,
break;
case
HORIZONTALALIGN_RIGHT:
ret =
pMaxWidth;
/ 2;
break;
break;
case
HORIZONTALALIGN_LEFT:
default:
break;
}
return ret;
line.length()));
y=pFontMetricsInt.top +
(pConstrainHeight pTotalHeight)
case
VERTICALALIGN_BOTTOM:
y=pFontMetricsInt.top +
(pConstrainHeight pTotalHeight);
break;
}
default:
if (temp >
maxContentWidth) {
maxContentWidth =
temp;
}
}
}
return new
TextProperty(maxContentWi
dth, h, lines);
}
private static int
computeX(final String pText,
final int pMaxWidth,
final
int pHorizontalAlignment) {
int ret = 0;
switch
(pHorizontalAlignment) {
case
HORIZONTALALIGN_CENTER:
private static int
computeY(final
FontMetricsInt
pFontMetricsInt,
final
int pConstrainHeight, final int
pTotalHeight,
final
int pVerticalAlignment) {
int y = pFontMetricsInt.top;
if
(pConstrainHeight >
pTotalHeight) {
switch
(pVerticalAlignment) {
case
VERTICALALIGN_TOP:
y=pFontMetricsInt.top;
break;
case
VERTICALALIGN_CENTER:
break;
}
}
return y;
}
/*
* If maxWidth or
maxHeight is not 0, split the
string to fix the maxWidth
* and maxHeight.
*/
private static String[]
splitString(final String
pString,
final
int pMaxWidth, final int
pMaxHeight, final Paint
pPaint) {
final String[]
lines = pString.split("\\n");
String[] ret =
null;
final
FontMetricsInt fm =
pPaint.getFontMetricsInt();
final int
heightPerLine = (int)
Math.ceil(fm.bottom fm.top);
final int
maxLines = pMaxHeight /
heightPerLine;
if
(pMaxWidth != 0) {
final
LinkedList<String> strList =
new LinkedList<String>();
for
(final String line : lines) {
/*
* The width of line is
exceed maxWidth, should
divide it into
* two or more lines.
ret =
new String[strList.size()];
}
/* Should not exceed
the max height. */
lines;
if (maxLines > 0 &&
strList.size() >= maxLines) {
}
return ret;
break;
}
}
}
/*
Remove exceeding lines. */
if
(maxLines > 0 &&
strList.size() > maxLines) {
while (strList.size() >
maxLines) {
*/
strList.removeLast();
final int lineWidth =
(int) Math.ceil(pPaint
strList.toArray(ret);
} else {
ret =
}
private static
LinkedList<String>
divideStringWithMaxWidth(
final
String pString, final int
pMaxWidth, final Paint
pPaint) {
final int
charLength =
pString.length();
int start = 0;
int
tempWidth = 0;
final
LinkedList<String> strList =
new LinkedList<String>();
}
.measureText(line));
if (lineWidth >
pMaxWidth) {
strList.addAll(Cocos2
dxBitmap.divideStringWithM
axWidth(
line, pMaxWidth,
pPaint));
ret =
new String[strList.size()];
strList.toArray(ret);
} else if
(pMaxHeight != 0 &&
lines.length > maxLines) {
/*
Remove exceeding lines. */
final
LinkedList<String> strList =
new LinkedList<String>();
for
(int i = 0; i < maxLines; i++) {
/* Break a
String into String[] by the
width & should wrap the
word. */
for (int i = 1; i
<= charLength; ++i) {
tempWidth = (int)
Math.ceil(pPaint.measureTex
t(pString, start,
i));
if
(tempWidth >= pMaxWidth)
{
} else {
strList.add(lines[i]);
}
strList.add(line);
final int
lastIndexOfSpace =
pString.substring(0, i)
.lastIndexOf(" ");
if (lastIndexOfSpace
!= -1 && lastIndexOfSpace >
start) {
/* Remove spaces at
the beginning of a new line.
*/
while (i < charLength
&& pString.charAt(i) == ' ') {
/* Should
wrap the word. */
++i;
}
strList.add(pString.su
bstring(start,
lastIndexOfSpace));
start = i;
}
* example:
"\nabc" -> " \nabc"
"\nabc\n\n" -> " \nabc\n \n".
*/
final
StringBuilder strBuilder =
new StringBuilder(pString);
int start = 0;
int index =
strBuilder.indexOf("\n");
while (index
!= -1) {
if
(index == 0 ||
strBuilder.charAt(index - 1)
== '\n') {
}
i=
lastIndexOfSpace + 1; // skip
space
strBuilder.insert(star
/* Add the
t, " ");
last chars. */
if (start <
} else {
start = index + 2;
} else
charLength) {
{
/* Should
not exceed the width. */
strList.add(pString.su
bstring(start));
}
if
(tempWidth > pMaxWidth) {
return
strList;
}
strList.add(pString.su
bstring(start, i - 1));
/*
Compute from previous char.
*/
--i;
private static String
refactorString(final String
pString) {
/* Avoid
error when content is "". */
if
(pString.compareTo("") == 0)
{
start = index + 1;
}
if
(start > strBuilder.length() ||
index == strBuilder.length()) {
break;
}
index =
strBuilder.indexOf("\n",
start);
}
} else {
return " ";
}
strList.add(pString.su
bstring(start, i));
}
}
/*
* If the font
of "\n" is "" or "\n", insert " "
in front of it. For
return
strBuilder.toString();
}
private static void
initNativeObject(final Bitmap
pBitmap) {
final byte[]
pixels =
Cocos2dxBitmap.getPixels(p
Bitmap);
if (pixels ==
null) {
private static int
getFontSizeAccordingHeight(i
nt height) {
Paint paint =
new Paint();
Rect bounds
= new Rect();
private static String
getStringWithEllipsis(String
pString, float width,
float
fontSize) {
if
(TextUtils.isEmpty(pString)) {
return;
}
Cocos2dxBitmap.nati
veInitBitmapDC(pBitmap.get
Width(),
paint.setTypeface(Ty
peface.DEFAULT);
int
incr_text_size = 1;
boolean
found_desired_size = false;
pBitmap.getHeight(),
pixels);
return "";
}
TextPaint
paint = new TextPaint();
paint.setTypeface(Ty
peface.DEFAULT);
while
(!found_desired_size) {
}
paint.setTextSize(fon
tSize);
private static byte[]
getPixels(final Bitmap
pBitmap) {
if (pBitmap
!= null) {
final
byte[] pixels = new
byte[pBitmap.getWidth()
*
pBitmap.getHeight() * 4];
final
ByteBuffer buf =
ByteBuffer.wrap(pixels);
buf.order(ByteOrder.
nativeOrder());
pBitmap.copyPixelsT
oBuffer(buf);
paint.setTextSize(inc
r_text_size);
String text =
"SghMNy";
paint.getTextBounds
(text, 0, text.length(),
bounds);
incr_text_size++;
if
(height - bounds.height() <=
2) {
found_desired_size =
return null;
}
TextUtils.TruncateAt.
END).toString();
}
//
========================
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
true;
}
return pixels;
}
return
TextUtils.ellipsize(pString,
paint, width,
Log.d("font size",
"incr size:" + incr_text_size);
}
return
incr_text_size;
}
private static class
TextProperty {
/** The max
width of lines. */
private final
int mMaxWidth;
/** The
height of all lines. */
private final
int mTotalHeight;
private final
int mHeightPerLine;
private final
String[] mLines;
TextProperty(final int
pMaxWidth, final int
pHeightPerLine,
final String[] pLines) {
this.mMaxWidth =
pMaxWidth;
this.mHeightPerLine
= pHeightPerLine;
this.mTotalHeight =
pHeightPerLine *
pLines.length;
this.mLines = pLines;
}
}
}
Cocos2dxEditBoxDialog.java
package org.cocos2dx.lib;
import android.app.Dialog;
import
android.content.Context;
import
android.graphics.drawable.C
olorDrawable;
import android.os.Bundle;
import android.os.Handler;
import
android.text.InputFilter;
import
android.text.InputType;
import
android.util.TypedValue;
import
android.view.KeyEvent;
import
android.view.ViewGroup;
import
android.view.WindowManag
er;
import
android.view.inputmethod.E
ditorInfo;
import
android.view.inputmethod.In
putMethodManager;
import
android.widget.EditText;
import
android.widget.LinearLayout;
import
android.widget.TextView;
import
android.widget.TextView.On
EditorActionListener;
public class
Cocos2dxEditBoxDialog
extends Dialog {
//
========================
========================
===========
// Constants
//
========================
========================
===========
/**
* The user is allowed
to enter any text, including
line breaks.
*/
private final int
kEditBoxInputModeAny = 0;
/**
* The user is allowed
to enter an e-mail address.
*/
private final int
kEditBoxInputModeEmailAdd
r = 1;
/**
* The user is allowed
to enter an integer value.
*/
private final int
kEditBoxInputModeNumeric
= 2;
/**
* The user is allowed
to enter a phone number.
*/
private final int
kEditBoxInputModePhoneNu
mber = 3;
/**
* The user is allowed
to enter a URL.
*/
private final int
kEditBoxInputModeUrl = 4;
/**
* The user is allowed
to enter a real number value.
This extends
kEditBoxInputModeNumeric
by allowing a decimal point.
*/
private final int
kEditBoxInputModeDecimal
= 5;
/**
* The user is allowed
to enter any text, except for
line breaks.
*/
private final int
kEditBoxInputModeSingleLin
e = 6;
/**
* Indicates that the
text entered is confidential
data that should be obscured
whenever possible. This
implies
EDIT_BOX_INPUT_FLAG_SEN
SITIVE.
*/
private final int
kEditBoxInputFlagPassword =
0;
private final int
kEditBoxInputFlagInitialCaps
Sentence = 3;
/**
* Indicates that the
text entered is sensitive data
that the implementation
must never store into a
dictionary or table for use in
predictive, auto-completing,
or other accelerated input
schemes. A credit card
number is an example of
sensitive data.
*/
private final int
kEditBoxInputFlagSensitive =
1;
private final int
kKeyboardReturnTypeDefaul
t = 0;
private final int
kKeyboardReturnTypeDone =
1;
private final int
kKeyboardReturnTypeSend =
2;
private final int
kKeyboardReturnTypeSearch
= 3;
private final int
kKeyboardReturnTypeGo = 4;
/**
* This flag is a hint
to the implementation that
during text editing, the initial
letter of each word should be
capitalized.
*/
private final int
kEditBoxInputFlagInitialCaps
Word = 2;
/**
* This flag is a hint
to the implementation that
during text editing, the initial
letter of each sentence
should be capitalized.
*/
/**
* Capitalize all
characters automatically.
*/
private final int
kEditBoxInputFlagInitialCaps
AllCharacters = 4;
//
========================
========================
===========
// Fields
//
========================
========================
===========
private EditText
mInputEditText;
private TextView
mTextViewTitle;
private final int
mInputFlag;
private final int
mReturnType;
private final int
mMaxLength;
private int
mInputFlagConstraints;
private int
mInputModeContraints;
private boolean
mIsMultiline;
//
========================
========================
===========
// Constructors
//
========================
========================
===========
public
Cocos2dxEditBoxDialog(final
Context pContext, final String
pTitle, final String pMessage,
final int pInputMode, final int
pInputFlag, final int
pReturnType, final int
pMaxLength) {
super(pContext,
android.R.style.Theme_Trans
lucent_NoTitleBar_Fullscreen
);
//
super(context,
R.style.Theme_Translucent);
this.mTitle =
private final String
pTitle;
mTitle;
private final String
mMessage;
private final int
mInputMode;
this.mMessage =
pMessage;
this.mInputMode =
pInputMode;
this.mInputFlag =
pInputFlag;
this.mReturnType =
pReturnType;
this.mMaxLength =
pMaxLength;
}
@Override
protected void
onCreate(final Bundle
pSavedInstanceState) {
super.onCreate(pSav
edInstanceState);
this.getWindow().set
BackgroundDrawable(new
ColorDrawable(0x80000000))
;
final
LinearLayout layout = new
LinearLayout(this.getContext
());
layout.setOrientation
(LinearLayout.VERTICAL);
final
LinearLayout.LayoutParams
layoutParams = new
LinearLayout.LayoutParams(
ViewGroup.LayoutParams.FIL
L_PARENT,
ViewGroup.LayoutParams.FIL
L_PARENT);
this.mTextViewTitle
= new
TextView(this.getContext());
final
LinearLayout.LayoutParams
textviewParams = new
LinearLayout.LayoutParams(
ViewGroup.LayoutParams.W
RAP_CONTENT,
ViewGroup.LayoutParams.W
RAP_CONTENT);
textviewParams.left
Margin =
textviewParams.rightMargin
=
this.convertDipsToPixels(10);
this.mTextViewTitle.s
etTextSize(TypedValue.COM
PLEX_UNIT_DIP, 20);
layout.addView(this.
mTextViewTitle,
textviewParams);
this.mInputEditText
= new
EditText(this.getContext());
final
LinearLayout.LayoutParams
editTextParams = new
LinearLayout.LayoutParams(
ViewGroup.LayoutParams.FIL
L_PARENT,
ViewGroup.LayoutParams.W
RAP_CONTENT);
editTextParams.left
Margin =
editTextParams.rightMargin
=
this.convertDipsToPixels(10);
layout.addView(this.
mInputEditText,
editTextParams);
this.setContentView(
layout, layoutParams);
this.getWindow().ad
dFlags(WindowManager.Lay
outParams.FLAG_FULLSCREE
N);
this.mTextViewTitle.s
etText(this.mTitle);
this.mInputEditText.s
etText(this.mMessage);
int
oldImeOptions =
this.mInputEditText.getImeO
ptions();
this.mInputEditText.s
etImeOptions(oldImeOptions
|
EditorInfo.IME_FLAG_NO_EX
TRACT_UI);
oldImeOptions =
this.mInputEditText.getImeO
ptions();
switch
(this.mInputMode) {
case
kEditBoxInputModeAny:
this.mInputModeCon
traints =
InputType.TYPE_CLASS_TEXT
|
InputType.TYPE_TEXT_FLAG_
MULTI_LINE;
break;
case
kEditBoxInputModeEmailAdd
r:
this.mInputModeCon
traints =
InputType.TYPE_CLASS_TEXT
|
InputType.TYPE_TEXT_VARIA
TION_EMAIL_ADDRESS;
break;
case
kEditBoxInputModeNumeric:
this.mInputModeCon
traints =
InputType.TYPE_CLASS_NUM
BER |
InputType.TYPE_NUMBER_FL
AG_SIGNED;
traints =
InputType.TYPE_CLASS_NUM
BER |
InputType.TYPE_NUMBER_FL
AG_DECIMAL |
InputType.TYPE_NUMBER_FL
AG_SIGNED;
case
kEditBoxInputModeSingleLin
e:
this.mInputModeCon
traints =
InputType.TYPE_CLASS_TEXT
;
case
break;
case
kEditBoxInputModeDecimal:
raints =
InputType.TYPE_TEXT_FLAG_
NO_SUGGESTIONS;
break;
case
kEditBoxInputFlagInitialCaps
Word:
break;
}
if
(this.mIsMultiline) {
this.mInputModeCon
traints |=
InputType.TYPE_TEXT_FLAG_
MULTI_LINE;
}
break;
case
kEditBoxInputFlagInitialCaps
Sentence:
this.mInputFlagConst
raints =
InputType.TYPE_TEXT_FLAG_
CAP_SENTENCES;
break;
this.mInputEditText.s
etInputType(this.mInputMod
eContraints |
this.mInputFlagConstraints);
switch
(this.mInputFlag) {
case
kEditBoxInputFlagPassword:
this.mInputFlagConst
this.mInputModeCon
this.mInputFlagConst
this.mInputFlagConst
raints =
InputType.TYPE_TEXT_FLAG_
CAP_WORDS;
default:
kEditBoxInputModeUrl:
this.mInputModeCon
traints =
InputType.TYPE_CLASS_TEXT
|
InputType.TYPE_TEXT_VARIA
TION_URI;
case
kEditBoxInputFlagSensitive:
break;
case
kEditBoxInputModePhoneNu
mber:
break;
break;
break;
break;
this.mInputModeCon
traints =
InputType.TYPE_CLASS_PHO
NE;
InputType.TYPE_CLASS_TEXT
|
InputType.TYPE_TEXT_VARIA
TION_PASSWORD;
raints =
case
kEditBoxInputFlagInitialCaps
AllCharacters:
this.mInputFlagConst
raints =
InputType.TYPE_TEXT_FLAG_
CAP_CHARACTERS;
break;
default:
break;
}
etImeOptions(oldImeOptions
|
EditorInfo.IME_ACTION_SEA
RCH);
og.this.mInputEditText.reque
stFocus();
this.mInputEditText.s
etInputType(this.mInputFlag
Constraints |
this.mInputModeContraints);
case
kKeyboardReturnTypeGo:
Cocos2dxEditBoxDial
og.this.mInputEditText.setSel
ection(Cocos2dxEditBoxDialo
g.this.mInputEditText.length(
));
switch
(this.mReturnType) {
this.mInputEditText.s
etImeOptions(oldImeOptions
|
EditorInfo.IME_ACTION_GO);
Cocos2dxEditBoxDial
og.this.openKeyboard();
}
}, 200);
case
kKeyboardReturnTypeDefaul
t:
this.mInputEditText.s
etImeOptions(oldImeOptions
|
EditorInfo.IME_ACTION_NO
NE);
break;
case
kKeyboardReturnTypeDone:
break;
break;
this.mInputEditText.s
etOnEditorActionListener(ne
w OnEditorActionListener() {
default:
this.mInputEditText.s
etImeOptions(oldImeOptions
|
EditorInfo.IME_ACTION_NO
NE);
break;
@Override
public boolean
onEditorAction(final
TextView v, final int actionId,
final KeyEvent event) {
}
this.mInputEditText.s
etImeOptions(oldImeOptions
|
EditorInfo.IME_ACTION_DON
E);
break;
case
kKeyboardReturnTypeSend:
this.mInputEditText.s
etImeOptions(oldImeOptions
|
EditorInfo.IME_ACTION_SEN
D);
if
(this.mMaxLength > 0) {
this.mInputEditText.s
etFilters(new InputFilter[] {
new
InputFilter.LengthFilter(this.
mMaxLength) });
}
final Handler
initHandler = new Handler();
this.mInputEditText.s
if (actionId !=
EditorInfo.IME_NULL ||
(actionId ==
EditorInfo.IME_NULL &&
event != null &&
event.getAction() ==
KeyEvent.ACTION_DOWN)) {
initHandler.postDela
yed(new Runnable() {
break;
case
kKeyboardReturnTypeSearch
:
/* If user didn't set
keyboard type, this callback
will be invoked twice with
'KeyEvent.ACTION_DOWN'
and 'KeyEvent.ACTION_UP'.
*/
@Override
public void run() {
Cocos2dxEditBoxDial
Cocos2dxHelper.setE
ditTextDialogResult(Cocos2d
xEditBoxDialog.this.mInputE
ditText.getText().toString());
Cocos2dxEditBoxDial
og.this.closeKeyboard();
Cocos2dxEditBoxDial
og.this.dismiss();
return true;
}
private int
convertDipsToPixels(final
float pDIPs) {
final float
scale =
this.getContext().getResourc
es().getDisplayMetrics().dens
ity;
return
Math.round(pDIPs * scale);
}
return false;
}
});
}
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
//
========================
========================
===========
// Methods
//
========================
========================
===========
private void
openKeyboard() {
final
InputMethodManager imm =
(InputMethodManager)
this.getContext().getSystemS
ervice(Context.INPUT_METH
OD_SERVICE);
imm.showSoftInput(t
his.mInputEditText, 0);
}
private void
closeKeyboard() {
final
InputMethodManager imm =
(InputMethodManager)
this.getContext().getSystemS
ervice(Context.INPUT_METH
OD_SERVICE);
imm.hideSoftInputFr
omWindow(this.mInputEditT
ext.getWindowToken(), 0);
}
//
========================
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
}
Cocos2dxEditText.java
package org.cocos2dx.lib;
import
android.content.Context;
import
android.util.AttributeSet;
import
android.view.KeyEvent;
import
android.widget.EditText;
public class
Cocos2dxEditText extends
EditText {
//
========================
========================
===========
// Constants
//
========================
========================
===========
//
========================
========================
===========
// Fields
//
========================
========================
===========
private
Cocos2dxGLSurfaceView
mCocos2dxGLSurfaceView;
//
========================
========================
===========
// Constructors
//
========================
========================
===========
public
Cocos2dxEditText(final
Context context) {
super(context);
}
public
Cocos2dxEditText(final
Context context, final
AttributeSet attrs) {
super(context, attrs);
}
public
Cocos2dxEditText(final
Context context, final
AttributeSet attrs, final int
defStyle) {
super(context, attrs,
defStyle);
}
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
public void
setCocos2dxGLSurfaceView(f
inal Cocos2dxGLSurfaceView
pCocos2dxGLSurfaceView) {
this.mCocos2dxGLSu
rfaceView =
pCocos2dxGLSurfaceView;
}
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
}
Cocos2dxETCLoader.java
package org.cocos2dx.lib;
@Override
public boolean
onKeyDown(final int
pKeyCode, final KeyEvent
pKeyEvent) {
import
java.io.FileInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
super.onKeyDown(p
KeyCode, pKeyEvent);
import
android.content.Context;
import
android.content.res.AssetMa
nager;
import
android.opengl.ETC1Util;
import android.util.Log;
/* Let
GlSurfaceView get focus if
back key is input. */
if (pKeyCode
==
KeyEvent.KEYCODE_BACK) {
this.mCocos2dxGLSu
rfaceView.requestFocus();
}
return true;
}
//
========================
========================
===========
// Methods
//
========================
========================
===========
//
========================
public class
Cocos2dxETCLoader {
private static final
String ASSETS_PATH =
"assets/";
private static Context
context;
public static boolean
loadTexture(String filePath) {
if (!
ETC1Util.isETC1Supported())
{
return false;
}
if
(filePath.length() == 0) {
return false;
}
// Create
ETC1Texture
InputStream
inputStream = null;
ETC1Util.ETC1Textur
e texture = null;
ETC1Util.createTexture(input
Stream);
inputStream.close();
} catch
(Exception e) {
data,
length);
}
Log.d("Cocos2dx",
"Unable to create texture for
" + filePath);
catch (Exception e)
{
Log.d("invoke native
function error", e.toString());
AssetManager
assetManager = null;
try {
if
(filePath.charAt(0) == '/') {
height,
texture = null;
}
ret = false;
}
if (texture !=
null) {
// absolute path
boolean ret = true;
inputStream = new
FileInputStream(filePath);
} else
{
final int width =
texture.getWidth();
// remove prefix:
"assets/"
final int height =
texture.getHeight();
public static void
setContext(Context context)
{
if
(filePath.startsWith(ASSETS_
PATH)) {
final int length =
texture.getData().remaining(
);
Cocos2dxETCLoader.
context = context;
}
filePath =
filePath.substring(ASSETS_PA
TH.length());
final byte[] data = new
byte[length];
}
assetManager =
context.getAssets();
inputStream =
assetManager.open(filePath)
;
}
try {
return ret;
} else {
final ByteBuffer buf =
ByteBuffer.wrap(data);
buf.order(ByteOrder.nativeO
rder());
buf.put(texture.getData());
nativeSetTextureInfo
(width,
texture =
return false;
}
}
private static native
void
nativeSetTextureInfo(final int
width, final int height, final
byte[] data,
final
int dataLength);
}
Cocos2dxGLSurfaceView.jav
a
package org.cocos2dx.lib;
import
android.content.Context;
import
android.opengl.GLSurfaceVie
w;
import android.os.Handler;
import android.os.Message;
import
android.util.AttributeSet;
import android.util.Log;
import
android.view.KeyEvent;
import
android.view.MotionEvent;
import
android.view.inputmethod.In
putMethodManager;
public class
Cocos2dxGLSurfaceView
extends GLSurfaceView {
//
========================
========================
===========
// Constants
//
========================
========================
===========
private static final
String TAG =
Cocos2dxGLSurfaceView.clas
s.getSimpleName();
private final static int
HANDLER_OPEN_IME_KEYB
OARD = 2;
private final static int
HANDLER_CLOSE_IME_KEYB
OARD = 3;
//
========================
========================
===========
// Fields
//
========================
========================
===========
// TODO Static
handler -> Potential leak!
private static
Handler sHandler;
this.initView();
}
protected void
initView() {
private static
Cocos2dxGLSurfaceView
mCocos2dxGLSurfaceView;
private static
Cocos2dxTextInputWraper
sCocos2dxTextInputWraper;
this.setEGLContextCli
entVersion(2);
private
Cocos2dxRenderer
mCocos2dxRenderer;
private
Cocos2dxEditText
mCocos2dxEditText;
Cocos2dxGLSurfaceV
iew.mCocos2dxGLSurfaceVie
w = this;
//
========================
========================
===========
// Constructors
//
========================
========================
===========
public
Cocos2dxGLSurfaceView(fina
l Context context) {
super(context);
this.initView();
}
public
Cocos2dxGLSurfaceView(fina
l Context context, final
AttributeSet attrs) {
super(context, attrs);
this.setFocusableInT
ouchMode(true);
Cocos2dxGLSurfaceV
iew.sCocos2dxTextInputWra
per = new
Cocos2dxTextInputWraper(t
his);
Cocos2dxGLSurfaceV
iew.sHandler = new
Handler() {
@Override
public void
handleMessage(final
Message msg) {
switch (msg.what) {
case
HANDLER_OPEN_IME_KEYB
OARD:
if
(null !=
Cocos2dxGLSurfaceView.this.
mCocos2dxEditText &&
Cocos2dxGLSurfaceView.this.
mCocos2dxEditText.requestF
ocus()) {
Cocos2dxGLSurfaceView.this.
mCocos2dxEditText, 0);
Log.d("GLSurfaceVie
w", "HideSoftInput");
Cocos2dxGLSurfaceV
iew.this.mCocos2dxEditText.
removeTextChangedListener(
Cocos2dxGLSurfaceView.sCo
cos2dxTextInputWraper);
Log.d("GLSurfaceVie
w", "showSoftInput");
}
break;
break;
Cocos2dxGLSurfaceV
iew.this.mCocos2dxEditText.
setText("");
final String text =
(String) msg.obj;
Cocos2dxGLSurfaceV
iew.this.mCocos2dxEditText.
append(text);
Cocos2dxGLSurfaceV
iew.sCocos2dxTextInputWra
per.setOriginText(text);
Cocos2dxGLSurfaceV
iew.this.mCocos2dxEditText.
addTextChangedListener(Coc
os2dxGLSurfaceView.sCocos
2dxTextInputWraper);
final
InputMethodManager imm =
(InputMethodManager)
Cocos2dxGLSurfaceView.mC
ocos2dxGLSurfaceView.getC
ontext().getSystemService(C
ontext.INPUT_METHOD_SER
VICE);
imm.showSoftInput(
}
}
}
};
case
HANDLER_CLOSE_IME_KEYB
OARD:
if
(null !=
Cocos2dxGLSurfaceView.this.
mCocos2dxEditText) {
Cocos2dxGLSurfaceV
iew.this.mCocos2dxEditText.
removeTextChangedListener(
Cocos2dxGLSurfaceView.sCo
cos2dxTextInputWraper);
final
InputMethodManager imm =
(InputMethodManager)
Cocos2dxGLSurfaceView.mC
ocos2dxGLSurfaceView.getC
ontext().getSystemService(C
ontext.INPUT_METHOD_SER
VICE);
}
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
public static
Cocos2dxGLSurfaceView
getInstance() {
return
mCocos2dxGLSurfaceView;
}
public static void
queueAccelerometer(final
float x, final float y, final float
z, final long timestamp) {
imm.hideSoftInputFr
omWindow(Cocos2dxGLSurf
aceView.this.mCocos2dxEdit
Text.getWindowToken(), 0);
mCocos2dxGLSurfaceView.q
ueueEvent(new Runnable() {
@Override
public void
run() {
Cocos2dxGLSurfaceV
iew.this.requestFocus();
Cocos2dxAccelerometer.onS
ensorChanged(x, y, z,
timestamp);
}
});
}
public void
setCocos2dxRenderer(final
Cocos2dxRenderer renderer)
{
public void onPause()
this.mCocos2dxEditT
ext.setCocos2dxGLSurfaceVie
w(this);
this.requestFocus();
}
}
{
this.queueEvent(new
Runnable() {
@Override
public void run() {
this.mCocos2dxRend
erer = renderer;
this.setRenderer(this
.mCocos2dxRenderer);
}
private String
getContentText() {
return
this.mCocos2dxRenderer.get
ContentText();
}
public
Cocos2dxEditText
getCocos2dxEditText() {
return
this.mCocos2dxEditText;
}
public void
setCocos2dxEditText(final
Cocos2dxEditText
pCocos2dxEditText) {
this.mCocos2dxEditT
ext = pCocos2dxEditText;
if (null !=
this.mCocos2dxEditText &&
null !=
Cocos2dxGLSurfaceView.sCo
cos2dxTextInputWraper) {
this.mCocos2dxEditT
ext.setOnEditorActionListene
r(Cocos2dxGLSurfaceView.sC
ocos2dxTextInputWraper);
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
@Override
public void
onResume() {
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleOnPause();
}
});
this.setRenderMode(
RENDERMODE_WHEN_DIRTY
);
//super.onPause();
}
super.onResume();
this.setRenderMode(
RENDERMODE_CONTINUOU
SLY);
this.queueEvent(new
Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleOnResume();
}
});
}
@Override
@Override
public boolean
onTouchEvent(final
MotionEvent pMotionEvent)
{
// these data
are used in ACTION_MOVE
and ACTION_CANCEL
final int
pointerNumber =
pMotionEvent.getPointerCou
nt();
final int[] ids
= new int[pointerNumber];
final float[]
xs = new
float[pointerNumber];
final float[]
ys = new
float[pointerNumber];
for (int i = 0; i
< pointerNumber; i++) {
ids[i]
=
pMotionEvent.getPointerId(i)
;
xs[i]
= pMotionEvent.getX(i);
ys[i]
= pMotionEvent.getY(i);
}
switch
(pMotionEvent.getAction() &
MotionEvent.ACTION_MASK)
{
case
MotionEvent.ACTION_POINT
ER_DOWN:
final int
indexPointerDown =
pMotionEvent.getAction() >>
MotionEvent.ACTION_POINT
ER_ID_SHIFT;
final int
idPointerDown =
pMotionEvent.getPointerId(i
ndexPointerDown);
});
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleActionDown(idPointe
rDown, xPointerDown,
yPointerDown);
break;
case
MotionEvent.ACTION_MOVE
:
}
this.queueEvent(new
Runnable() {
});
break;
@Override
case
MotionEvent.ACTION_DOW
N:
// there are only one
finger on the screen
final int idDown =
pMotionEvent.getPointerId(0
);
final float xDown =
public void
run() {
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleActionMove(ids, xs,
ys);
}
});
xs[0];
break;
final float yDown =
final float
xPointerDown =
pMotionEvent.getX(indexPoi
nterDown);
ys[0];
case
MotionEvent.ACTION_POINT
ER_UP:
this.queueEvent(new
Runnable() {
final float
yPointerDown =
pMotionEvent.getY(indexPoi
nterDown);
@Override
public void
final int
indexPointUp =
pMotionEvent.getAction() >>
MotionEvent.ACTION_POINT
ER_ID_SHIFT;
run() {
this.queueEvent(new
Runnable() {
@Override
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleActionDown(idDown,
xDown, yDown);
public void
run() {
}
final int idPointerUp
=
pMotionEvent.getPointerId(i
ndexPointUp);
final float xPointerUp
=
pMotionEvent.getX(indexPoi
ntUp);
final float yPointerUp
=
pMotionEvent.getY(indexPoi
ntUp);
this.queueEvent(new
Runnable() {
run() {
}
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleActionUp(idUp, xUp,
yUp);
@Override
}
public void
});
run() {
break;
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleActionUp(idPointerU
p, xPointerUp, yPointerUp);
}
}
*/
return true;
public void
case
MotionEvent.ACTION_CANCE
L:
/*
* This function is
called before
Cocos2dxRenderer.nativeInit
(), so the
* width and height is
correct.
*/
@Override
protected void
onSizeChanged(final int
pNewSurfaceWidth, final int
pNewSurfaceHeight, final int
pOldSurfaceWidth, final int
pOldSurfaceHeight) {
this.queueEvent(new
Runnable() {
if(!this.isInEditMode(
)) {
});
@Override
break;
public void
run() {
case
MotionEvent.ACTION_UP:
// there are only one
finger on the screen
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleActionCancel(ids, xs,
ys);
final int idUp =
pMotionEvent.getPointerId(0
);
}
});
this.mCocos2dxRend
erer.setScreenWidthAndHeig
ht(pNewSurfaceWidth,
pNewSurfaceHeight);
}
}
@Override
public boolean
onKeyDown(final int
pKeyCode, final KeyEvent
pKeyEvent) {
final float xUp =
xs[0];
break;
}
if(pKeyEvent.getRep
eatCount() > 0){
final float yUp =
ys[0];
/*
if
(BuildConfig.DEBUG) {
this.queueEvent(new
Runnable() {
@Override
Cocos2dxGLSurfaceV
iew.dumpMotionEvent(pMot
ionEvent);
return false;
}
switch
(pKeyCode) {
case
KeyEvent.KEYCODE_BACK:
case
KeyEvent.KEYCODE_MENU:
case
KeyEvent.KEYCODE_DPAD_L
EFT:
case
KeyEvent.KEYCODE_DPAD_C
ENTER:
case
KeyEvent.KEYCODE_DPAD_RI
GHT:
case
KeyEvent.KEYCODE_DPAD_U
P:
case
KeyEvent.KEYCODE_DPAD_D
OWN:
case
KeyEvent.KEYCODE_BUTTON
_A:
case
KeyEvent.KEYCODE_BUTTON
_B:
case
KeyEvent.KEYCODE_BUTTON
_X:
case
KeyEvent.KEYCODE_BUTTON
_Y:
this.queueEvent(new
Runnable() {
@Override
public void
run() {
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleKeyDown(pKeyCode);
Log.v("PTPLAYER",
"KEY DOWN" + pKeyCode);
}
case
KeyEvent.KEYCODE_BUTTON
_Y:
});
return true;
this.queueEvent(new
Runnable() {
default:
return
super.onKeyDown(pKeyCode
, pKeyEvent);
}
}
public boolean
onKeyUp(final int pKeyCode,
final KeyEvent pKeyEvent){
@Override
public void
run() {
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleKeyUp(pKeyCode);
switch
(pKeyCode) {
case
KeyEvent.KEYCODE_BACK:
case
KeyEvent.KEYCODE_MENU:
case
KeyEvent.KEYCODE_DPAD_C
ENTER:
case
KeyEvent.KEYCODE_DPAD_L
EFT:
case
KeyEvent.KEYCODE_DPAD_RI
GHT:
case
KeyEvent.KEYCODE_DPAD_U
P:
case
KeyEvent.KEYCODE_DPAD_D
OWN:
case
KeyEvent.KEYCODE_BUTTON
_A:
case
KeyEvent.KEYCODE_BUTTON
_B:
case
KeyEvent.KEYCODE_BUTTON
_X:
Log.v("PTPLAYER",
"KEY UP" + pKeyCode);
}
});
return true;
default:
return
super.onKeyDown(pKeyCode
, pKeyEvent);
}
}
//
========================
========================
===========
// Methods
//
========================
========================
===========
//
========================
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
public static void
openIMEKeyboard() {
final
Message msg = new
Message();
msg.what =
Cocos2dxGLSurfaceView.HA
NDLER_OPEN_IME_KEYBOAR
D;
msg.obj =
Cocos2dxGLSurfaceView.mC
ocos2dxGLSurfaceView.getC
ontentText();
Cocos2dxGLSurfaceV
iew.sHandler.sendMessage(
msg);
}
public static void
closeIMEKeyboard() {
final
Message msg = new
Message();
msg.what =
Cocos2dxGLSurfaceView.HA
NDLER_CLOSE_IME_KEYBOA
RD;
Cocos2dxGLSurfaceV
iew.sHandler.sendMessage(
msg);
}
public void
insertText(final String pText)
{
this.queueEvent(new
Runnable() {
@Override
public void run() {
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleInsertText(pText);
}
});
}
public void
deleteBackward() {
final int
actionCode = action &
MotionEvent.ACTION_MASK;
sb.append("event
ACTION_").append(names[ac
tionCode]);
if
(actionCode ==
MotionEvent.ACTION_POINT
ER_DOWN || actionCode ==
MotionEvent.ACTION_POINT
ER_UP) {
sb.append("(pid
").append(action >>
MotionEvent.ACTION_POINT
ER_ID_SHIFT);
this.queueEvent(new
Runnable() {
sb.append(")");
}
@Override
public void run() {
Cocos2dxGLSurfaceV
iew.this.mCocos2dxRenderer
.handleDeleteBackward();
}
});
}
private static void
dumpMotionEvent(final
MotionEvent event) {
final String
names[] = { "DOWN", "UP",
"MOVE", "CANCEL",
"OUTSIDE",
"POINTER_DOWN",
"POINTER_UP", "7?", "8?",
"9?" };
final
StringBuilder sb = new
StringBuilder();
final int
action = event.getAction();
sb.append("[");
for (int i = 0; i
< event.getPointerCount();
i++) {
sb.append("#").appe
nd(i);
sb.append("(pid
").append(event.getPointerId
(i));
sb.append(")=").app
end((int) event.getX(i));
sb.append(",").appen
d((int) event.getY(i));
if (i +
1 < event.getPointerCount())
{
sb.append(";");
}
}
sb.append("]");
Log.d(Cocos2dxGLSu
rfaceView.TAG,
sb.toString());
}
}
Cocos2dxHandler.java
package org.cocos2dx.lib;
import
java.lang.ref.WeakReference;
import
android.app.AlertDialog;
import
android.content.DialogInterf
ace;
import android.os.Handler;
import android.os.Message;
public class Cocos2dxHandler
extends Handler {
//
========================
========================
===========
// Constants
//
========================
========================
===========
public final static int
HANDLER_SHOW_DIALOG =
1;
public final static int
HANDLER_SHOW_EDITBOX_
DIALOG = 2;
//
========================
========================
===========
// Fields
//
========================
========================
===========
private
WeakReference<Cocos2dxAc
tivity> mActivity;
//
========================
========================
===========
// Constructors
//
========================
========================
===========
public
Cocos2dxHandler(Cocos2dxA
ctivity activity) {
//
========================
========================
===========
public void
handleMessage(Message
msg) {
switch
(msg.what) {
case
Cocos2dxHandler.HANDLER_
SHOW_DIALOG:
showDialog(msg);
break;
this.mActivity = new
WeakReference<Cocos2dxAc
tivity>(activity);
}
case
Cocos2dxHandler.HANDLER_
SHOW_EDITBOX_DIALOG:
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
msg);
showEditBoxDialog(
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
//
========================
========================
===========
// Methods
break;
}
}
private void
showDialog(Message msg) {
Cocos2dxActivity
theActivity =
this.mActivity.get();
DialogMessage
dialogMessage =
(DialogMessage)msg.obj;
new
AlertDialog.Builder(theActivit
y)
.setTitle(dialogMessa
ge.titile)
.setMessage(dialogM
essage.message)
public int
.setPositiveButton("
Ok",
editBoxMessage.inp
inputFlag;
utFlag,
public int
returnType;
new
DialogInterface.OnClickListen
er() {
editBoxMessage.retu
maxLength;
editBoxMessage.max
Length).show();
}
public
EditBoxMessage(String title,
String content, int
inputMode, int inputFlag, int
returnType, int maxLength){
@Override
public void
onClick(DialogInterface
dialog, int which) {
//
TODO Auto-generated
method stub
}
}).create().show();
}
private void
showEditBoxDialog(Message
msg) {
EditBoxMessage
editBoxMessage =
(EditBoxMessage)msg.obj;
new
Cocos2dxEditBoxDialog(this.
mActivity.get(),
editBoxMessage.title
public int
rnType,
//
========================
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
public static class
DialogMessage {
public String
titile;
public String
message;
public
DialogMessage(String title,
String message) {
this.titile = title;
this.content =
content;
this.title = title;
this.inputMode =
inputMode;
this.inputFlag =
inputFlag;
this.returnType =
returnType;
this.maxLength =
maxLength;
}
}
}
Cocos2dxHelper.java
package org.cocos2dx.lib;
this.message =
message;
}
}
import
java.io.UnsupportedEncoding
Exception;
import java.util.Locale;
public static class
EditBoxMessage {
public String
title;
public String
content;
public int
inputMode;
import android.app.Activity;
import
android.content.Context;
import
android.content.SharedPrefe
rences;
,
editBoxMessage.con
tent,
editBoxMessage.inp
utMode,
import
android.content.pm.Applicati
onInfo;
import
android.content.res.AssetMa
nager;
import android.os.Build;
import
android.util.DisplayMetrics;
import android.view.Display;
import
android.view.WindowManag
er;
public class Cocos2dxHelper {
//
========================
========================
===========
// Constants
//
========================
========================
===========
private static final
String PREFS_NAME =
"Cocos2dxPrefsFile";
//
========================
========================
===========
// Fields
//
========================
========================
===========
private static
Cocos2dxMusic
sCocos2dMusic;
private static
Cocos2dxSound
sCocos2dSound;
private static
AssetManager
sAssetManager;
private static
Cocos2dxAccelerometer
sCocos2dxAccelerometer;
private static
boolean
sAccelerometerEnabled;
private static String
sPackageName;
private static String
sFileDirectory;
private static Context
sContext = null;
private static
Cocos2dxHelperListener
sCocos2dxHelperListener;
//
========================
========================
===========
// Constructors
//
========================
========================
===========
applicationInfo.packageNam
e;
Cocos2dxHelper.sFile
Directory =
pContext.getFilesDir().getAbs
olutePath();
Cocos2dxHelper.nati
veSetApkPath(applicationInf
o.sourceDir);
Cocos2dxHelper.sCoc
os2dxAccelerometer = new
Cocos2dxAccelerometer(pCo
ntext);
Cocos2dxHelper.sCoc
os2dMusic = new
Cocos2dxMusic(pContext);
Cocos2dxHelper.sCoc
os2dSound = new
Cocos2dxSound(pContext);
public static void
init(final Context pContext,
final Cocos2dxHelperListener
pCocos2dxHelperListener) {
final
ApplicationInfo
applicationInfo =
pContext.getApplicationInfo(
);
Cocos2dxHelper.sAss
etManager =
pContext.getAssets();
Cocos2dxHelper.sCo
ntext = pContext;
Cocos2dxBitmap.set
Context(pContext);
Cocos2dxHelper.sCoc
os2dxHelperListener =
pCocos2dxHelperListener;
Cocos2dxETCLoader.
setContext(pContext);
}
Cocos2dxHelper.sPac
kageName =
//
========================
========================
===========
Cocos2dxHelper.nati
veSetContext((Context)pCont
ext,
Cocos2dxHelper.sAssetMana
ger);
// Getter & Setter
//
========================
========================
===========
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
//
========================
========================
===========
// Methods
//
========================
========================
===========
private static native
void nativeSetApkPath(final
String pApkPath);
private static native
void
nativeSetEditTextDialogResul
t(final byte[] pBytes);
private static native
void nativeSetContext(final
Context pContext, final
AssetManager
pAssetManager);
public static String
getCocos2dxPackageName()
{
return
Cocos2dxHelper.sPackageNa
me;
}
public static void
onNativeInitStatic(){
Cocos2dxHelper.sCoc
os2dxHelperListener.onNativ
eInit();
}
public static String
getCocos2dxWritablePath() {
return
Cocos2dxHelper.sFileDirector
y;
}
public static String
getCurrentLanguage() {
return
Locale.getDefault().getLangu
age();
}
public static String
getDeviceModel(){
return
Build.MODEL;
}
public static
AssetManager
getAssetManager() {
return
Cocos2dxHelper.sAssetMana
ger;
}
public static void
setAccelerometerInterval(flo
at interval) {
Cocos2dxHelper.sCoc
os2dxAccelerometer.setInter
val(interval);
}
public static void
disableAccelerometer() {
Cocos2dxHelper.sAcc
elerometerEnabled = false;
Cocos2dxHelper.sCoc
os2dxAccelerometer.disable(
);
}
public static void
preloadBackgroundMusic(fin
al String pPath) {
Cocos2dxHelper.sCoc
os2dMusic.preloadBackgrou
ndMusic(pPath);
}
public static void
playBackgroundMusic(final
String pPath, final boolean
isLoop) {
public static void
enableAccelerometer() {
Cocos2dxHelper.sCoc
os2dMusic.playBackgroundM
usic(pPath, isLoop);
}
Cocos2dxHelper.sAcc
elerometerEnabled = true;
public static void
resumeBackgroundMusic() {
Cocos2dxHelper.sCoc
os2dxAccelerometer.enable()
;
}
Cocos2dxHelper.sCoc
os2dMusic.resumeBackgroun
dMusic();
}
}
public static void
pauseBackgroundMusic() {
Cocos2dxHelper.sCoc
os2dMusic.pauseBackground
Music();
}
public static void
stopBackgroundMusic() {
Cocos2dxHelper.sCoc
os2dMusic.stopBackground
Music();
}
public static void
rewindBackgroundMusic() {
Cocos2dxHelper.sCoc
os2dMusic.rewindBackgroun
dMusic();
}
public static boolean
isBackgroundMusicPlaying() {
return
Cocos2dxHelper.sCocos2dM
usic.isBackgroundMusicPlayi
ng();
}
public static void
preloadEffect(final String
path) {
Cocos2dxHelper.sCoc
os2dSound.preloadEffect(pat
h);
}
public static int
playEffect(final String path,
final boolean isLoop) {
return
Cocos2dxHelper.sCocos2dSo
und.playEffect(path, isLoop,
1, 0, 1);
}
public static void
resumeEffect(final int
soundId) {
Cocos2dxHelper.sCoc
os2dSound.resumeEffect(sou
ndId);
}
return
Cocos2dxHelper.sCocos2dSo
und.getEffectsVolume();
}
public static void
setEffectsVolume(final float
volume) {
Cocos2dxHelper.sCoc
os2dSound.setEffectsVolume
(volume);
}
public static void
unloadEffect(final String
path) {
Cocos2dxHelper.sCoc
os2dSound.unloadEffect(pat
h);
}
public static void
pauseAllEffects() {
Cocos2dxHelper.sCoc
os2dSound.pauseAllEffects();
}
public static void
pauseEffect(final int soundId)
{
public static void
resumeAllEffects() {
public static float
getBackgroundMusicVolume(
){
return
Cocos2dxHelper.sCocos2dM
usic.getBackgroundVolume();
}
Cocos2dxHelper.sCoc
os2dSound.pauseEffect(soun
dId);
}
Cocos2dxHelper.sCoc
os2dSound.resumeAllEffects(
);
}
public static void
stopEffect(final int soundId) {
public static void
stopAllEffects() {
public static void
setBackgroundMusicVolume(
final float volume) {
Cocos2dxHelper.sCoc
os2dSound.stopEffect(soundI
d);
}
Cocos2dxHelper.sCoc
os2dSound.stopAllEffects();
}
Cocos2dxHelper.sCoc
os2dMusic.setBackgroundVol
ume(volume);
public static void
public static float
getEffectsVolume() {
end() {
}
Cocos2dxHelper.sCoc
os2dMusic.end();
Cocos2dxHelper.sCoc
os2dSound.end();
}
public static void
onResume() {
if
(Cocos2dxHelper.sAccelerom
eterEnabled) {
Cocos2dxHelper.sCoc
os2dxAccelerometer.enable()
;
}
}
public static void
onPause() {
if
(Cocos2dxHelper.sAccelerom
eterEnabled) {
Cocos2dxHelper.sCoc
os2dxAccelerometer.disable(
);
}
}
/*
Nothing. */
private static void
showEditTextDialog(final
String pTitle, final String
pMessage, final int
pInputMode, final int
pInputFlag, final int
pReturnType, final int
pMaxLength) {
Cocos2dxHelper.sCoc
os2dxHelperListener.showEd
itTextDialog(pTitle,
pMessage, pInputMode,
pInputFlag, pReturnType,
pMaxLength);
}
public static void
setEditTextDialogResult(final
String pResult) {
try {
final
byte[] bytesUTF8 =
pResult.getBytes("UTF8");
}
}
public static int getDPI()
{
if (sContext
!= null)
{
DisplayMetrics
metrics = new
DisplayMetrics();
WindowManager
wm =
((Activity)sContext).getWind
owManager();
if
(wm != null)
{
Display d =
wm.getDefaultDisplay();
if (d != null)
Cocos2dxHelper.sCoc
os2dxHelperListener.runOnG
LThread(new Runnable() {
{
d.getMetrics(metrics
public static void
terminateProcess() {
android.os.Process.ki
llProcess(android.os.Process.
myPid());
}
private static void
showDialog(final String
pTitle, final String pMessage)
{
Cocos2dxHelper.sCoc
os2dxHelperListener.showDi
alog(pTitle, pMessage);
@Override
);
public void run() {
return
(int)(metrics.density*160.0f);
Cocos2dxHelper.nati
veSetEditTextDialogResult(by
tesUTF8);
}
}
}
}
return -1;
}
});
} catch
(UnsupportedEncodingExcep
tion
pUnsupportedEncodingExcep
tion) {
//
========================
========================
===========
// Functions for
CCUserDefault
//
========================
========================
===========
public static boolean
getBoolForKey(String key,
boolean defaultValue) {
SharedPreferences
settings =
((Activity)sContext).getShare
dPreferences(Cocos2dxHelpe
r.PREFS_NAME, 0);
return
settings.getBoolean(key,
defaultValue);
}
public static int
getIntegerForKey(String key,
int defaultValue) {
SharedPreferences
settings =
((Activity)sContext).getShare
dPreferences(Cocos2dxHelpe
r.PREFS_NAME, 0);
return
settings.getInt(key,
defaultValue);
}
public static float
getFloatForKey(String key,
float defaultValue) {
SharedPreferences
settings =
((Activity)sContext).getShare
dPreferences(Cocos2dxHelpe
r.PREFS_NAME, 0);
return
settings.getFloat(key,
defaultValue);
}
public static double
getDoubleForKey(String key,
double defaultValue) {
// SharedPreferences
doesn't support saving
double value
SharedPreferences
settings =
((Activity)sContext).getShare
dPreferences(Cocos2dxHelpe
r.PREFS_NAME, 0);
return
settings.getFloat(key,
(float)defaultValue);
}
public static void
setIntegerForKey(String key,
int value) {
SharedPreferences
settings =
((Activity)sContext).getShare
dPreferences(Cocos2dxHelpe
r.PREFS_NAME, 0);
public static String
getStringForKey(String key,
String defaultValue) {
SharedPreferences
settings =
((Activity)sContext).getShare
dPreferences(Cocos2dxHelpe
r.PREFS_NAME, 0);
return
settings.getString(key,
defaultValue);
}
public static void
setFloatForKey(String key,
float value) {
SharedPreferences
settings =
((Activity)sContext).getShare
dPreferences(Cocos2dxHelpe
r.PREFS_NAME, 0);
public static void
setBoolForKey(String key,
boolean value) {
SharedPreferences
settings =
((Activity)sContext).getShare
dPreferences(Cocos2dxHelpe
r.PREFS_NAME, 0);
SharedPreferences.E
ditor editor = settings.edit();
editor.putBoolean(ke
y, value);
editor.commit();
}
SharedPreferences.E
ditor editor = settings.edit();
editor.putInt(key,
value);
editor.commit();
}
SharedPreferences.E
ditor editor = settings.edit();
editor.putFloat(key,
value);
editor.commit();
}
public static void
setDoubleForKey(String key,
double value) {
// SharedPreferences
doesn't support recording
double value
SharedPreferences
settings =
((Activity)sContext).getShare
dPreferences(Cocos2dxHelpe
r.PREFS_NAME, 0);
SharedPreferences.E
ditor editor = settings.edit();
editor.putFloat(key,
(float)value);
editor.commit();
}
public static void
setStringForKey(String key,
String value) {
SharedPreferences
settings =
((Activity)sContext).getShare
dPreferences(Cocos2dxHelpe
r.PREFS_NAME, 0);
SharedPreferences.E
ditor editor = settings.edit();
editor.putString(key,
value);
editor.commit();
}
//
========================
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
public static
interface
Cocos2dxHelperListener {
public void
showDialog(final String
pTitle, final String
pMessage);
public void
showEditTextDialog(final
String pTitle, final String
pMessage, final int
pInputMode, final int
pInputFlag, final int
pReturnType, final int
pMaxLength);
public void
onNativeInit();
public void
runOnGLThread(final
Runnable pRunnable);
}
}
Cocos2dxLocalStorage.java
package org.cocos2dx.lib;
import
android.content.Context;
import
android.database.Cursor;
import
android.database.sqlite.SQLit
eDatabase;
import
android.database.sqlite.SQLit
eOpenHelper;
import android.util.Log;
public class
Cocos2dxLocalStorage {
private static final String
TAG =
"Cocos2dxLocalStorage";
* @return
*/
public static boolean
init(String dbName, String
tableName) {
if
(Cocos2dxActivity.getContext
() != null) {
DATABASE_NAME =
dbName;
TABLE_NAME =
tableName;
mDatabaseOpenHelp
er = new
DBOpenHelper(Cocos2dxActi
vity.getContext());
mDatabase =
mDatabaseOpenHelper.getW
ritableDatabase();
return true;
}
return false;
}
public static void destory()
private static String
DATABASE_NAME =
"jsb.sqlite";
private static String
TABLE_NAME = "data";
private static final int
DATABASE_VERSION = 1;
{
private static
DBOpenHelper
mDatabaseOpenHelper =
null;
private static
SQLiteDatabase mDatabase =
null;
/**
* Constructor
* @param context The
Context within which to
work, used to create the DB
public static void
setItem(String key, String
value) {
try {
String sql =
"replace into
"+TABLE_NAME+"(key,value)
values(?,?)";
if (mDatabase !=
null) {
mDatabase.close();
}
}
mDatabase.execSQL(
sql, new Object[] { key, value
});
} catch (Exception e)
{
e.printStackTrace();
}
mDatabase.execSQL(
sql, new Object[] {key});
} catch (Exception e)
{
}
public static String
getItem(String key) {
String ret = null;
try {
String sql = "select
value from "+TABLE_NAME+"
where key=?";
Cursor c =
mDatabase.rawQuery(sql,
new String[]{key});
while (c.moveToNext()) {
// only return the
first value
if (ret != null)
{
Log.e(TAG,
"The key contains more than
one value.");
break;
}
ret =
c.getString(c.getColumnInde
x("value"));
}
c.close();
} catch (Exception e)
{
e.printStackTrace();
}
return ret == null ? ""
: ret;
}
public static void
removeItem(String key) {
try {
String sql =
"delete from
"+TABLE_NAME+" where
key=?";
e.printStackTrace();
}
}
/**
* This creates/opens the
database.
*/
private static class
DBOpenHelper extends
SQLiteOpenHelper {
DBOpenHelper(Context
context) {
super(context,
DATABASE_NAME, null,
DATABASE_VERSION);
}
@Override
public void
onCreate(SQLiteDatabase
db) {
db.execSQL("CREATE
TABLE IF NOT EXISTS
"+TABLE_NAME+"(key TEXT
PRIMARY KEY,value TEXT);");
}
@Override
public void
onUpgrade(SQLiteDatabase
db, int oldVersion, int
newVersion) {
Log.w(TAG,
"Upgrading database from
version " + oldVersion + " to "
+ newVersion + ",
which will destroy all old
data");
//db.execSQL("DROP
TABLE IF EXISTS " +
VIRTUAL_TABLE);
//onCreate(db);
}
}
}
Cocos2dxMusic.java
package org.cocos2dx.lib;
import
java.io.FileInputStream;
import
android.content.Context;
import
android.content.res.AssetFile
Descriptor;
import
android.media.MediaPlayer;
import android.util.Log;
public class Cocos2dxMusic {
//
========================
========================
===========
// Constants
//
========================
========================
===========
private static final String
TAG =
Cocos2dxMusic.class.getSim
pleName();
//
========================
========================
===========
// Fields
//
========================
========================
===========
private final Context
mContext;
private MediaPlayer
mBackgroundMediaPlayer;
private float mLeftVolume;
private float
mRightVolume;
private boolean mPaused;
// whether music is paused
state.
private boolean mIsLoop =
false;
private boolean
mManualPaused = false; //
whether music is paused
manually before the program
is switched to the
background.
private String
mCurrentPath;
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
//
========================
========================
===========
// Constructors
//
========================
========================
===========
public void
preloadBackgroundMusic(fin
al String path) {
if ((this.mCurrentPath ==
null) ||
(!this.mCurrentPath.equals(p
ath))) {
// preload new
background music
public Cocos2dxMusic(final
Context context) {
this.mContext = context;
// release old resource
and create a new one
if
(this.mBackgroundMediaPlay
er != null) {
this.initData();
//
========================
========================
===========
// Methods
//
========================
========================
===========
}
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
this.mBackgroundMediaPlay
er.release();
}
this.mCurrentPath =
path;
}
}
public void
playBackgroundMusic(final
String path, final boolean
isLoop) {
if (mCurrentPath == null)
{
// it is the first time to
play background music or
end() was called
mBackgroundMediaPlayer =
createMediaplayer(path);
mCurrentPath = path;
} else {
if
(!mCurrentPath.equals(path)
){
// play new
background music
// release old
resource and create a new
one
if
(mBackgroundMediaPlayer
!= null) {
mBackgroundMediaPlayer.re
lease();
}
mBackgroundMediaPlayer =
createMediaplayer(path);
// record the path
mCurrentPath =
path;
this.mBackgroundMediaPlay
er =
this.createMediaplayer(path)
;
// record the path
}
}
if
(mBackgroundMediaPlayer
== null) {
}
Log.e(Cocos2dxMusic.TAG,
"playBackgroundMusic:
background media player is
null");
} else {
try {
// if the music is
playing or paused, stop it
if (mPaused) {
mBackgroundMediaPlayer.se
ekTo(0);
mBackgroundMediaPlayer.st
art();
} else if
(mBackgroundMediaPlayer.is
Playing()) {
mBackgroundMediaPlayer.se
ekTo(0);
} else {
mBackgroundMediaPlayer.st
art();
}
mBackgroundMediaP
layer.release();
mBackgroundMediaP
layer =
createMediaplayer(mCurrent
Path);
/**
* should set the state,
if not, the following
sequence will be error
* play -> pause ->
stop -> resume
*/
this.mPaused = false;
}
}
public void
pauseBackgroundMusic() {
if
(this.mBackgroundMediaPlay
er != null &&
this.mBackgroundMediaPlay
er.isPlaying()) {
public void
rewindBackgroundMusic() {
if
(this.mBackgroundMediaPlay
er != null) {
playBackgroundMusi
c(mCurrentPath, mIsLoop);
}
}
public boolean
isBackgroundMusicPlaying() {
boolean ret = false;
if
(this.mBackgroundMediaPlay
er == null) {
ret = false;
} else {
ret =
this.mBackgroundMediaPlay
er.isPlaying();
}
return ret;
mBackgroundMediaPlayer.se
tLooping(isLoop);
mPaused = false;
mIsLoop = isLoop;
} catch (final Exception
e) {
Log.e(Cocos2dxMusic.TAG,
"playBackgroundMusic: error
state");
}
}
}
public void
stopBackgroundMusic() {
if
(this.mBackgroundMediaPlay
er != null) {
this.mBackgroundMediaPlay
er.pause();
this.mPaused = true;
this.mManualPaused =
true;
}
}
public void
resumeBackgroundMusic() {
if
(this.mBackgroundMediaPlay
er != null && this.mPaused) {
this.mBackgroundMediaPlay
er.start();
this.mPaused = false;
this.mManualPaused =
false;
}
}
public void end() {
if
(this.mBackgroundMediaPlay
er != null) {
this.mBackgroundMediaPlay
er.release();
}
this.initData();
}
public float
getBackgroundVolume() {
if
(this.mBackgroundMediaPlay
er != null) {
return
(this.mLeftVolume +
this.mRightVolume) / 2;
} else {
return 0.0f;
}
}
public void
setBackgroundVolume(float
volume) {
if (volume < 0.0f) {
volume = 0.0f;
}
if (volume > 1.0f) {
volume = 1.0f;
}
if(!this.mManualPaused){
if
(this.mBackgroundMediaPlay
er != null && this.mPaused) {
this.mBackgroundMediaPlay
er.start();
this.mPaused =
false;
}
}
}
private void initData() {
this.mLeftVolume = 0.5f;
this.mRightVolume =
0.5f;
this.mLeftVolume =
this.mRightVolume =
volume;
if
(this.mBackgroundMediaPlay
er != null) {
this.mBackgroundMediaPlay
er = null;
this.mPaused = false;
this.mCurrentPath =
null;
}
this.mBackgroundMediaPlay
er.setVolume(this.mLeftVolu
me, this.mRightVolume);
}
}
/**
* create mediaplayer for
music
*
* @param pPath
*
the pPath relative
to assets
* @return
*/
private MediaPlayer
createMediaplayer(final
String path) {
MediaPlayer
mediaPlayer = new
MediaPlayer();
public void
onEnterBackground(){
if
(this.mBackgroundMediaPlay
er != null &&
this.mBackgroundMediaPlay
er.isPlaying()) {
this.mBackgroundMediaPlay
er.pause();
this.mPaused = true;
}
}
public void
onEnterForeground(){
try {
if
(path.startsWith("/")) {
final
FileInputStream fis = new
FileInputStream(path);
mediaPlayer.setDataSource(f
is.getFD());
fis.close();
} else {
final
AssetFileDescriptor
assetFileDescritor =
this.mContext.getAssets().op
enFd(path);
mediaPlayer.setDataSource(
assetFileDescritor.getFileDes
criptor(),
assetFileDescritor.getStartOf
fset(),
assetFileDescritor.getLength(
));
}
mediaPlayer.prepare();
mediaPlayer.setVolume(this.
mLeftVolume,
this.mRightVolume);
} catch (final Exception
e) {
mediaPlayer = null;
Log.e(Cocos2dxMusic.TAG,
"error: " + e.getMessage(),
e);
}
return mediaPlayer;
}
//
========================
========================
===========
// Inner and Anonymous
Classes
//
========================
========================
===========
}
Cocos2dxReflectionHelper.ja
va
Log.e("error", "can not
get constant" +
constantName);
}
return null;
package org.cocos2dx.lib;
import android.util.Log;
import
java.lang.reflect.InvocationTa
rgetException;
import
java.lang.reflect.Method;
}
public static <T> T
invokeInstanceMethod(final
Object instance, final String
methodName,
final
Class[] parameterTypes, final
Object[] parameters) {
catch
(InvocationTargetException
e) {
Log.e("error", "an
exception was thrown by the
invoked method when
invoking " + methodName);
}
return null;
}
}
Cocos2dxRenderer.java
package org.cocos2dx.lib;
import android.util.Log;
public class
Cocos2dxReflectionHelper {
public static <T> T
getConstantValue(final Class
aClass, final String
constantName) {
try {
return
(T)aClass.getDeclaredField(co
nstantName).get(null);
} catch
(NoSuchFieldException e) {
Log.e("error", "can not
find " + constantName + " in
" + aClass.getName());
}
catch
(IllegalAccessException e) {
Log.e("error",
constantName + " is not
accessable");
}
catch
(IllegalArgumentException e)
{
Log.e("error",
"arguments error when get "
+ constantName);
}
catch (Exception e) {
final Class aClass =
instance.getClass();
try {
final Method method
=
aClass.getMethod(methodNa
me, parameterTypes);
return
(T)method.invoke(instance,
parameters);
} catch
(NoSuchMethodException e)
{
Log.e("error", "can not
find " + methodName + " in "
+ aClass.getName());
}
catch
(IllegalAccessException e) {
Log.e("error",
methodName + " is not
accessible");
}
catch
(IllegalArgumentException e)
{
Log.e("error",
"arguments are error when
invoking " + methodName);
}
import
javax.microedition.khronos.e
gl.EGLConfig;
import
javax.microedition.khronos.o
pengles.GL10;
import
android.opengl.GLSurfaceVie
w;
public class
Cocos2dxRenderer
implements
GLSurfaceView.Renderer {
//
========================
========================
===========
// Constants
//
========================
========================
===========
private final static
long
NANOSECONDSPERSECOND
= 1000000000L;
private final static
long
NANOSECONDSPERMICROSE
COND = 1000000;
private static long
sAnimationInterval = (long)
(1.0 / 60 *
Cocos2dxRenderer.NANOSEC
ONDSPERSECOND);
//
========================
========================
===========
// Fields
//
========================
========================
===========
private long
mLastTickInNanoSeconds;
private int
mScreenWidth;
private int
mScreenHeight;
//
========================
========================
===========
// Constructors
//
========================
========================
===========
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
public static void
setAnimationInterval(final
double pAnimationInterval) {
Cocos2dxRenderer.s
AnimationInterval = (long)
(pAnimationInterval *
Cocos2dxRenderer.NANOSEC
ONDSPERSECOND);
}
public void
setScreenWidthAndHeight(fi
nal int pSurfaceWidth, final
int pSurfaceHeight) {
this.mScreenWidth =
pSurfaceWidth;
this.mScreenHeight =
pSurfaceHeight;
}
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
@Override
public void
onSurfaceCreated(final GL10
pGL10, final EGLConfig
pEGLConfig) {
Cocos2dxRenderer.n
ativeInit(this.mScreenWidth,
this.mScreenHeight);
this.mLastTickInNano
Seconds =
System.nanoTime();
}
@Override
public void
onSurfaceChanged(final
GL10 pGL10, final int pWidth,
final int pHeight) {
Log.d("RENDERER",
"Surface changed: " + pWidth
+ " " + pHeight);
Cocos2dxRenderer.n
ativeOnSurfaceChanged(pWi
dth, pHeight);
}
@Override
public void
onDrawFrame(final GL10 gl) {
/*
* FPS
controlling algorithm is not
accurate, and it will slow
down FPS
* on some
devices. So comment FPS
controlling code.
*/
/*
final long
nowInNanoSeconds =
System.nanoTime();
final long
interval =
nowInNanoSeconds this.mLastTickInNanoSecond
s;
*/
// should
render a frame when
onDrawFrame() is called or
there is a
// "ghost"
Cocos2dxRenderer.n
ativeRender();
/*
// fps
controlling
if (interval <
Cocos2dxRenderer.sAnimatio
nInterval) {
try {
// because we
render it before, so we
should sleep twice time
interval
Thread.sleep((Cocos
2dxRenderer.sAnimationInte
rval - interval) /
Cocos2dxRenderer.NANOSEC
ONDSPERMICROSECOND);
}
catch (final Exception e) {
}
}
this.mLastTickInNano
Seconds =
nowInNanoSeconds;
*/
}
//
========================
========================
===========
// Methods
//
========================
========================
===========
private static native
void
nativeTouchesBegin(final int
pID, final float pX, final float
pY);
private static native
void nativeTouchesEnd(final
int pID, final float pX, final
float pY);
private static native
void
nativeTouchesMove(final
int[] pIDs, final float[] pXs,
final float[] pYs);
private static native
void
nativeTouchesCancel(final
int[] pIDs, final float[] pXs,
final float[] pYs);
private static native
boolean nativeKeyDown(final
int pKeyCode);
private static native
boolean nativeKeyUp(final
int pKeyCode);
private static native
void nativeRender();
private static native
void nativeInit(final int
pWidth, final int pHeight);
private static native
void
nativeOnSurfaceChanged(fin
al int width, final int height);
private static native
void nativeOnPause();
private static native
void nativeOnResume();
public void
handleActionDown(final int
pID, final float pX, final float
pY) {
Cocos2dxRenderer.n
ativeTouchesBegin(pID, pX,
pY);
}
public void
handleActionUp(final int pID,
final float pX, final float pY) {
Cocos2dxRenderer.n
ativeTouchesEnd(pID, pX,
pY);
}
public void
handleActionCancel(final
int[] pIDs, final float[] pXs,
final float[] pYs) {
Cocos2dxRenderer.n
ativeTouchesCancel(pIDs,
pXs, pYs);
}
public void
handleActionMove(final int[]
pIDs, final float[] pXs, final
float[] pYs) {
Cocos2dxRenderer.n
ativeTouchesMove(pIDs, pXs,
pYs);
}
public void
handleKeyDown(final int
pKeyCode) {
Cocos2dxRenderer.n
ativeKeyDown(pKeyCode);
}
public void
handleKeyUp(final int
pKeyCode) {
Cocos2dxRenderer.n
ativeKeyUp(pKeyCode);
}
public void
handleOnPause() {
Cocos2dxRenderer.n
ativeOnPause();
}
public void
handleOnResume() {
Cocos2dxRenderer.n
ativeOnResume();
}
private static native
void nativeInsertText(final
String pText);
private static native
void nativeDeleteBackward();
private static native
String
nativeGetContentText();
public void
handleInsertText(final String
pText) {
Cocos2dxRenderer.n
ativeInsertText(pText);
}
public void
handleDeleteBackward() {
Cocos2dxRenderer.n
ativeDeleteBackward();
}
public String
getContentText() {
return
Cocos2dxRenderer.nativeGet
ContentText();
}
//
========================
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
}
Cocos2dxSound.java
package org.cocos2dx.lib;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import
java.util.concurrent.Concurre
ntHashMap;
import
android.content.Context;
import
android.media.AudioManage
r;
import
android.media.SoundPool;
import android.util.Log;
public class Cocos2dxSound {
//
========================
========================
===========
// Constants
//
========================
========================
===========
private static final String
TAG = "Cocos2dxSound";
//
========================
========================
===========
// Fields
//
========================
========================
===========
private final Context
mContext;
private SoundPool
mSoundPool;
private float mLeftVolume;
private float
mRightVolume;
// sound path and stream
ids map
// a file may be played
many times at the same time
// so there is an array map
to a file path
private final
HashMap<String,
ArrayList<Integer>>
mPathStreamIDsMap = new
HashMap<String,
ArrayList<Integer>>();
private final
HashMap<String, Integer>
mPathSoundIDMap = new
HashMap<String, Integer>();
private
ConcurrentHashMap<Integer
,
SoundInfoForLoadedComplet
ed>
mPlayWhenLoadedEffects =
new
ConcurrentHashMap<Integer
,
SoundInfoForLoadedComplet
ed>();
private static final int
MAX_SIMULTANEOUS_STRE
AMS_DEFAULT = 5;
private static final int
MAX_SIMULTANEOUS_STRE
AMS_I9100 = 3;
private static final float
SOUND_RATE = 1.0f;
private static final int
SOUND_PRIORITY = 1;
private static final int
SOUND_QUALITY = 5;
private final static int
INVALID_SOUND_ID = -1;
private final static int
INVALID_STREAM_ID = -1;
//
========================
========================
===========
// Constructors
//
========================
========================
===========
public
Cocos2dxSound(final Context
context) {
this.mContext = context;
this.initData();
}
private void initData() {
if
(Cocos2dxHelper.getDevice
Model().contains("GTI9100")) {
this.mSoundPool =
new
SoundPool(Cocos2dxSound.
MAX_SIMULTANEOUS_STRE
AMS_I9100,
AudioManager.STREAM_MU
SIC,
Cocos2dxSound.SOUND_QU
ALITY);
}
else {
this.mSoundPool =
new
SoundPool(Cocos2dxSound.
MAX_SIMULTANEOUS_STRE
AMS_DEFAULT,
AudioManager.STREAM_MU
SIC,
Cocos2dxSound.SOUND_QU
ALITY);
}
this.mSoundPool.setOnLoad
CompleteListener(new
OnLoadCompletedListener())
;
this.mLeftVolume = 0.5f;
this.mRightVolume =
0.5f;
}
public int
preloadEffect(final String
path) {
Integer soundID =
this.mPathSoundIDMap.get(
path);
if (soundID == null) {
soundID =
this.createSoundIDFromAsse
t(path);
// save value just in
case if file is really loaded
if (soundID !=
Cocos2dxSound.INVALID_SO
UND_ID) {
this.mPathSoundIDMap.put(
path, soundID);
}
}
return soundID;
}
public void
unloadEffect(final String
path) {
// stop effects
final ArrayList<Integer>
streamIDs =
this.mPathStreamIDsMap.get
(path);
if (streamIDs != null) {
for (final Integer
steamID : streamIDs) {
this.mSoundPool.stop(steamI
D);
}
}
this.mPathStreamIDsMap.re
move(path);
// unload effect
final Integer soundID =
this.mPathSoundIDMap.get(
path);
if(soundID != null){
this.mSoundPool.unload(sou
ndID);
this.mPathSoundIDMap.rem
ove(path);
}
}
private static int
LOAD_TIME_OUT = 500;
public int playEffect(final
String path, final boolean
loop, float pitch, float pan,
float gain){
Integer soundID =
this.mPathSoundIDMap.get(
path);
int streamID =
Cocos2dxSound.INVALID_ST
REAM_ID;
if (soundID != null) {
// parameters; pan = 1 for left channel, 1 for right
channel, 0 for both channels
// play sound
streamID =
this.doPlayEffect(path,
soundID, loop, pitch, pan,
gain);
} else {
// the effect is not
prepared
soundID =
this.preloadEffect(path);
if (soundID ==
Cocos2dxSound.INVALID_SO
UND_ID) {
// can not preload
effect
return
Cocos2dxSound.INVALID_SO
UND_ID;
}
SoundInfoForLoadedComplet
ed info = new
SoundInfoForLoadedComplet
ed(path, loop, pitch, pan,
gain);
mPlayWhenLoadedEffects.pu
tIfAbsent(soundID, info);
synchronized(info) {
try {
info.wait(LOAD_TIME_OUT);
} catch(Exception e)
{
e.printStackTrace();
}
}
streamID =
info.effectID;
mPlayWhenLoadedEffects.re
move(soundID);
}
return streamID;
}
public void stopEffect(final
int steamID) {
this.mSoundPool.stop(steamI
D);
// remove record
for (final String pPath :
this.mPathStreamIDsMap.ke
ySet()) {
if
(this.mPathStreamIDsMap.ge
t(pPath).contains(steamID)) {
this.mPathStreamIDsMap.get
(pPath).remove(this.mPathSt
reamIDsMap.get(pPath).inde
xOf(steamID));
break;
}
}
}
public void
pauseEffect(final int
steamID) {
this.mSoundPool.pause(stea
mID);
}
public void
resumeEffect(final int
steamID) {
this.mSoundPool.resume(ste
amID);
}
public void
pauseAllEffects() {
if
(!this.mPathStreamIDsMap.is
Empty()) {
final
Iterator<Entry<String,
ArrayList<Integer>>> iter =
this.mPathStreamIDsMap.en
trySet().iterator();
while (iter.hasNext()) {
final Entry<String,
ArrayList<Integer>> entry =
iter.next();
for (final int
steamID : entry.getValue()) {
this.mSoundPool.pause(stea
mID);
}
}
}
}
public void
resumeAllEffects() {
// can not only invoke
SoundPool.autoResume()
here, because
// it only resumes all
effects paused by
pauseAllEffects()
if
(!this.mPathStreamIDsMap.is
Empty()) {
final
Iterator<Entry<String,
ArrayList<Integer>>> iter =
this.mPathStreamIDsMap.en
trySet().iterator();
while (iter.hasNext()) {
final Entry<String,
ArrayList<Integer>> entry =
iter.next();
for (final int
steamID : entry.getValue()) {
this.mSoundPool.resume(ste
amID);
}
}
}
}
@SuppressWarnings("unche
cked")
public void stopAllEffects()
{
// stop effects
if
(!this.mPathStreamIDsMap.is
Empty()) {
final Iterator<?> iter =
this.mPathStreamIDsMap.en
trySet().iterator();
while (iter.hasNext()) {
final
Map.Entry<String,
ArrayList<Integer>> entry =
(Map.Entry<String,
ArrayList<Integer>>)
iter.next();
for (final int
steamID : entry.getValue()) {
this.mSoundPool.stop(steamI
D);
}
}
}
// remove records
this.mPathStreamIDsMap.cle
ar();
}
public float
getEffectsVolume() {
return
(this.mLeftVolume +
this.mRightVolume) / 2;
}
public void
setEffectsVolume(float
volume) {
// volume should be in
[0, 1.0]
if (volume < 0) {
volume = 0;
}
if (volume > 1) {
volume = 1;
}
this.mPathSoundIDMap.clear
();
this.mPlayWhenLoadedEffect
s.clear();
this.mLeftVolume = 0.5f;
this.mRightVolume =
0.5f;
this.initData();
}
this.mLeftVolume =
this.mRightVolume =
volume;
// change the volume of
playing sounds
if
(!this.mPathStreamIDsMap.is
Empty()) {
final
Iterator<Entry<String,
ArrayList<Integer>>> iter =
this.mPathStreamIDsMap.en
trySet().iterator();
while (iter.hasNext()) {
final Entry<String,
ArrayList<Integer>> entry =
iter.next();
for (final int
steamID : entry.getValue()) {
this.mSoundPool.setVolume(
steamID, this.mLeftVolume,
this.mRightVolume);
}
}
}
}
public void end() {
this.mSoundPool.release();
this.mPathStreamIDsMap.cle
ar();
public int
createSoundIDFromAsset(fin
al String path) {
int soundID =
Cocos2dxSound.INVALID_SO
UND_ID;
try {
if
(path.startsWith("/")) {
soundID =
this.mSoundPool.load(path,
0);
} else {
soundID =
this.mSoundPool.load(this.m
Context.getAssets().openFd(
path), 0);
}
} catch (final Exception
e) {
soundID =
Cocos2dxSound.INVALID_SO
UND_ID;
Log.e(Cocos2dxSound.TAG,
"error: " + e.getMessage(),
e);
}
// mSoundPool.load
returns 0 if something goes
wrong, for example a file
does not exist
if (soundID == 0) {
soundID =
Cocos2dxSound.INVALID_SO
UND_ID;
}
return soundID;
if (streamIDs == null) {
streamIDs = new
ArrayList<Integer>();
this.mPathStreamIDsMap.pu
t(path, streamIDs);
}
}
streamIDs.add(streamID);
private float clamp(float
value, float min, float max) {
return Math.max(min,
(Math.min(value, max)));
}
private int
doPlayEffect(final String
path, final int soundId, final
boolean loop, float pitch,
float pan, float gain) {
float leftVolume =
this.mLeftVolume * gain *
(1.0f - this.clamp(pan, 0.0f,
1.0f));
float rightVolume =
this.mRightVolume * gain *
(1.0f - this.clamp(-pan, 0.0f,
1.0f));
float soundRate =
this.clamp(SOUND_RATE *
pitch, 0.5f, 2.0f);
// play sound
int streamID =
this.mSoundPool.play(soundI
d, this.clamp(leftVolume,
0.0f, 1.0f),
this.clamp(rightVolume, 0.0f,
1.0f),
Cocos2dxSound.SOUND_PRI
ORITY, loop ? -1 : 0,
soundRate);
// record stream id
ArrayList<Integer>
streamIDs =
this.mPathStreamIDsMap.get
(path);
return streamID;
}
public void
onEnterBackground(){
this.mSoundPool.autoPause(
);
}
public void
onEnterForeground(){
this.mSoundPool.autoResum
e();
}
//
========================
========================
===========
// Inner and Anonymous
Classes
//
========================
========================
===========
public class
SoundInfoForLoadedComplet
ed {
public int effectID;
public boolean isLoop;
public float pitch;
public float pan;
public float gain;
public String path;
public
SoundInfoForLoadedComplet
ed(String path, boolean
isLoop, float pitch, float pan,
float gain) {
this.path = path;
this.isLoop = isLoop;
this.pitch = pitch;
this.pan = pan;
this.gain = gain;
effectID =
Cocos2dxSound.INVALID_SO
UND_ID;
}
}
public class
OnLoadCompletedListener
implements
SoundPool.OnLoadComplete
Listener {
@Override
public void
onLoadComplete(SoundPool
soundPool, int sampleId, int
status) {
if (status == 0)
{
SoundInfoForLoadedComplet
ed info =
mPlayWhenLoadedEffects.ge
t(sampleId);
if (info != null) {
info.effectID =
doPlayEffect(info.path,
sampleId, info.isLoop,
info.pitch, info.pan,
info.gain);
synchronized
(info) {
info.notifyAll();
}
}
}
}
}
}
Cocos2dxTextInputWraper.j
ava
package org.cocos2dx.lib;
import
android.content.Context;
import android.text.Editable;
import
android.text.TextWatcher;
import android.util.Log;
import
android.view.KeyEvent;
import
android.view.inputmethod.E
ditorInfo;
import
android.view.inputmethod.In
putMethodManager;
import
android.widget.TextView;
import
android.widget.TextView.On
EditorActionListener;
public class
Cocos2dxTextInputWraper
implements TextWatcher,
OnEditorActionListener {
//
========================
========================
===========
// Constants
//
========================
========================
===========
private static final
String TAG =
Cocos2dxTextInputWraper.cl
ass.getSimpleName();
//
========================
========================
===========
// Fields
//
========================
========================
===========
private final
Cocos2dxGLSurfaceView
mCocos2dxGLSurfaceView;
private String mText;
private String
mOriginText;
//
========================
========================
===========
// Constructors
//
========================
========================
===========
public
Cocos2dxTextInputWraper(fi
nal Cocos2dxGLSurfaceView
pCocos2dxGLSurfaceView) {
this.mCocos2dxGLSu
rfaceView =
pCocos2dxGLSurfaceView;
}
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
private boolean
isFullScreenEdit() {
final
TextView textField =
this.mCocos2dxGLSurfaceVie
w.getCocos2dxEditText();
final
InputMethodManager imm =
(InputMethodManager)
textField.getContext().getSys
temService(Context.INPUT_
METHOD_SERVICE);
return
imm.isFullscreenMode();
}
public void
setOriginText(final String
pOriginText) {
this.mOriginText =
pOriginText;
}
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
@Override
public void
afterTextChanged(final
Editable s) {
if
(this.isFullScreenEdit()) {
return;
}
//if
(BuildConfig.DEBUG) {
//Log.d(TAG,
"afterTextChanged: " + s);
//}
int
nModified = s.length() this.mText.length();
if (nModified
> 0) {
final
String insertText =
s.subSequence(this.mText.le
ngth(), s.length()).toString();
public void
beforeTextChanged(final
CharSequence
pCharSequence, final int
start, final int count, final int
after) {
/*
if
(BuildConfig.DEBUG) {
this.mCocos2dxGLSu
rfaceView.insertText(insertT
ext);
/*
if
(BuildConfig.DEBUG) {
Log.d(TAG,
"beforeTextChanged(" +
pCharSequence + ")start: " +
start + ",count: " + count +
",after: " + after);
}
*/
this.mText =
pCharSequence.toString();
}
Log.d(TAG,
"insertText(" + insertText +
")");
}
*/
} else {
for (;
nModified < 0; ++nModified)
{
this.mCocos2dxGLSu
rfaceView.deleteBackward();
@Override
public void
onTextChanged(final
CharSequence
pCharSequence, final int
start, final int before, final int
count) {
}
this.mOriginText.length(); i >
0; i--) {
this.mCocos2dxGLSu
rfaceView.deleteBackward();
/*
if
(BuildConfig.DEBUG) {
Log.d(TAG,
"deleteBackward");
}
*/
}
String text =
pTextView.getText().toString(
);
/* If
user input nothing, translate
"\n" to engine. */
if
(text.compareTo("") == 0) {
text = "\n";
/*
}
if
(BuildConfig.DEBUG) {
Log.d(TAG,
"deleteBackward");
}
*/
}
}
this.mText =
s.toString();
}
@Override
@Override
public boolean
onEditorAction(final
TextView pTextView, final int
pActionID, final KeyEvent
pKeyEvent) {
if
(this.mCocos2dxGLSurfaceVi
ew.getCocos2dxEditText() ==
pTextView &&
this.isFullScreenEdit()) {
//
user press the action button,
delete all old text and insert
new text
for
(int i =
if
('\n' !=
text.charAt(text.length() - 1))
{
text += '\n';
}
final
String insertText = text;
this.mCocos2dxGLSu
rfaceView.insertText(insertT
ext);
/*
if
(BuildConfig.DEBUG) {
Log.d(TAG,
"insertText(" + insertText +
")");
}
*/
}
if (pActionID
==
EditorInfo.IME_ACTION_DON
E) {
this.mCocos2dxGLSu
rfaceView.requestFocus();
}
return false;
}
//
========================
========================
===========
// Methods
//
========================
========================
===========
//
========================
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
}
Cocos2dxTypefaces.java
package org.cocos2dx.lib;
import java.util.HashMap;
import
android.content.Context;
import
android.graphics.Typeface;
//
========================
========================
===========
public class
Cocos2dxTypefaces {
//
========================
========================
===========
// Constants
//
========================
========================
===========
//
========================
========================
===========
// Methods for/from
SuperClass/Interfaces
//
========================
========================
===========
//
========================
========================
===========
// Fields
//
========================
========================
===========
private static final
HashMap<String, Typeface>
sTypefaceCache = new
HashMap<String,
Typeface>();
//
========================
========================
===========
// Constructors
//
========================
========================
===========
//
========================
========================
===========
// Getter & Setter
//
========================
========================
===========
// Methods
//
========================
========================
===========
public static
synchronized Typeface
get(final Context pContext,
final String pAssetName) {
if
(!Cocos2dxTypefaces.sTypefa
ceCache.containsKey(pAsset
Name)) {
Typeface typeface =
null;
if
(pAssetName.startsWith("/")
)
{
typeface =
Typeface.createFromFile(pAs
setName);
}
else
{
typeface =
Typeface.createFromAsset(p
Context.getAssets(),
pAssetName);
}
Cocos2dxTypefaces.s
TypefaceCache.put(pAssetNa
me, typeface);
}
return
Cocos2dxTypefaces.sTypefac
eCache.get(pAssetName);
}
//
========================
========================
===========
// Inner and
Anonymous Classes
//
========================
========================
===========
}
Main.xml
<?xml version="1.0"
encoding="utf-8"?>
<FrameLayout
xmlns:android="http://sche
mas.android.com/apk/res/an
droid"
android:id="@+id/main"
android:layout_width="fill_p
arent"
android:layout_height="fill_p
arent"
android:orientation="vertical
">
<org.cocos2dx.lib.Cocos2dxE
ditText
android:orientation="vertical
"
android:id="@+id/textField"
android:layout_width="matc
h_parent"
android:layout_height="wra
p_content"
android:layout_height="matc
h_parent">
android:layout_width="fill_p
arent"
android:background="@null"
/>
<com.google.android.gms.ad
s.adMobView
android:id="@+id/ad
View"
<org.cocos2dx.lib.Cocos2dxG
LSurfaceView
android:id="@+id/game_gl_s
urfaceview"
android:layout_width="fill_p
arent"
android:layout_height="fill_p
arent"/>
<LinearLayout
android:id="@+id/revMobBa
nner"
android:layout_width="wrap
_content"
android:layout_height="wra
p_content"
android:layout_gravity="bott
om"
android:orientation="horizon
tal" >
android:layout_width="matc
h_parent"
android:layout_height="wra
p_content"
/>
</LinearLayout>
<!-<com.mopub.mobileads.Mo
PubView
android:id="@+id/adview"
android:layout_width="fill_p
arent"
android:layout_height="50d
p"
android:layout_gravity="bott
om" >
</com.mopub.mobileads.Mo
PubView>
<com.applovin.adview.AppLo
vinAdView
</LinearLayout>
xmlns:applovin="http://sche
<LinearLayout
mas.applovin.com/android/1
.0"
android:icon="@drawable/ic
on"
android:id="@+id/ALadview"
android:allowBackup="true"
android:layout_width="wrap
_content"
android:layout_height="wra
p_content"
android:layout_gravity="bott
om"
android:visibility="visible"
applovin:loadAdOnCreate="t
rue" /> -->
</FrameLayout>
Strings.xml
<?xml version="1.0"
encoding="utf-8"?>
<resources>
<string
name="app_name">Dawn
Woods</string>
<string
name="app_id"></string>
</resources>
AndroidManifest.xml
<?xml version="1.0"
encoding="utf-8"?>
<manifest
xmlns:android="http://sche
mas.android.com/apk/res/an
droid"
package="com.hhhhhhhh.hh
h"
android:versionCode="1"
android:versionName="1.0">
<application
android:label="@string/app_
name"
android:name="android.sup
port.multidex.MultiDexAppli
cation">
<meta-data
android:name="com.google.
android.gms.version"
android:value="@integer/go
ogle_play_services_version"
/>
<meta-data
android:name="com.google.
android.gms.games.APP_ID"
android:value="@string/app
_id" />
<activity
android:name=".PTPlayer"
android:label="@string/app_
name"
android:screenOrientation="l
andscape"
android:theme="@android:s
tyle/Theme.NoTitleBar.Fullsc
reen"
android:configChanges="orie
ntation">
<intent-filter>
<action
android:name="android.inte
nt.action.MAIN" />
<category
android:name="android.inte
nt.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- FACEBOOK SDK --><!-<activity
android:name="com.faceboo
k.ads.InterstitialAdActivity"
android:configChanges="key
boardHidden|orientation"
android:screenOrientation="
portrait"/>
--><!-- FACEBOOK SDK -->
<!-- ADMOB --><!-<activity
android:name="com.google.
android.gms.ads.AdActivity"
android:configChanges="key
board|keyboardHidden|orie
ntation|screenLayout|uiMod
e|screenSize|smallestScreen
Size"
android:theme="@android:s
tyle/Theme.Translucent" />
--><!-- ADMOB -->
<!-- VUNGLE --><!-<activity
android:name="com.vungle.
publisher.FullScreenAdActivit
y"
android:configChanges="key
boardHidden|orientation|scr
eenSize"
android:theme="@android:s
tyle/Theme.NoTitleBar.Fullsc
reen"/>
--><!-- VUNGLE -->
<!-- HEYZAP --><!-<activity
android:name="com.heyzap.
sdk.ads.HeyzapInterstitialActi
vity"
android:configChanges="key
boardHidden|orientation|scr
eenSize|smallestScreenSize"
/>
<activity
android:name="com.heyzap.
sdk.ads.HeyzapVideoActivity
"
android:configChanges="key
boardHidden|orientation|scr
eenSize|smallestScreenSize"
/>
<activity
android:name="com.heyzap.
sdk.ads.HeyzapProxyActivity"
/>
<activity
android:name="com.heyzap.
sdk.ads.VASTActivity"
android:configChanges="key
boardHidden|orientation|scr
eenSize|smallestScreenSize"
/>
<activity
android:name="com.heyzap.
sdk.ads.MediationTestActivit
y" />
<receiver
android:name="com.heyzap.
sdk.ads.PackageAddedReceiv
er">
<intent-filter>
<data
android:scheme="package"/
>
<action
android:name="android.inte
nt.action.PACKAGE_ADDED"/
>
</intent-filter>
</receiver>
--><!-- HEYZAP -->
<!-- APPLOVIN SDK --><!-<activity
android:name="com.applovi
n.adview.AppLovinInterstitial
Activity" />
<activity
android:name="com.applovi
n.adview.AppLovinConfirmat
ionActivity" />
<meta-data
android:name="applovin.sdk.
key"
android:value="{{AppLovin_S
DK_key}}" />
--><!-- APPLOVIN SDK -->
<!-- REVMOB --><!-<activity
android:name="com.revmob
.FullscreenActivity"
android:theme="@android:s
tyle/Theme.Translucent"
android:configChanges="key
boardHidden|orientation">
</activity>
<meta-data
android:name="com.revmob
.app.id"
android:value="{{RevMobMe
diaID}}"/>
--><!-- REVMOB -->
android:hardwareAccelerate
d="true" />
--><!-- INMOBI -->
<!-- CHARTBOOST -><!-<activity
android:name="com.chartbo
ost.sdk.CBImpressionActivity
"
android:excludeFromRecents
="true"
android:theme="@android:s
tyle/Theme.Translucent.NoTi
tleBar.Fullscreen"
android:configChanges="key
boardHidden|orientation|scr
eenSize"/>
--><!-- CHARTBOOST
-->
</application>
<supports-screens
android:largeScreens="true"
android:smallScreens="true"
android:anyDensity="true"
<!-- INMOBI --><!-<activity
android:name="com.inmobi.
rendering.InMobiAdActivity"
android:configChanges="key
boardHidden|orientation|ke
yboard|smallestScreenSize|s
creenSize"
android:theme="@android:s
tyle/Theme.Translucent.NoTi
tleBar"
android:normalScreens="tru
e"/>
<!-- INMOBI --><!-<uses-permission
android:name="android.per
mission.READ_LOGS" />
<uses-permission
android:name="android.per
mission.VIBRATE"/>
<uses-permission
android:name="android.per
mission.CALL_PHONE" />
<uses-permission
android:name="android.per
mission.READ_CALENDAR"/>
<uses-permission
android:name="android.per
mission.WRITE_CALENDAR"/
>
<uses-permission
android:name="android.per
mission.RECORD_AUDIO"/>
<uses-permission
android:name="android.per
mission.GET_TASKS" />
<uses-permission
android:name="android.per
mission.ACCESS_FINE_LOCAT
ION" />
<uses-permission
android:name="com.google.
android.gms.permission.ACTI
VITY_RECOGNITION"/>
--><!-- INMOBI -->
<uses-permission
android:name="android.per
mission.INTERNET" />
<uses-permission
android:name="com.android
.vending.BILLING" />
<uses-permission
android:name="android.per
mission.ACCESS_NETWORK_
STATE" />
<uses-permission
android:name="android.per
mission.ACCESS_WIFI_STATE
"/>
<uses-permission
android:name="android.per
mission.ACCESS_COARSE_LO
CATION" />
<uses-permission
android:name="android.per
mission.WRITE_EXTERNAL_S
TORAGE" />
<uses-permission
android:name="android.per
mission.READ_PHONE_STAT
E"/>
</manifest>
Build.gradle
apply plugin:
'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "28.0.3"
defaultConfig {
applicationId
"com.hhhhhhhh.hhh"
minSdkVersion 16
targetSdkVersion 26
multiDexEnabled true
ndk {
moduleName
"player_shared"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles
getDefaultProguardFile('prog
uard-android.txt'), 'proguardrules.txt'
}
}
dexOptions {
javaMaxHeapSize "4g"
}
}
dependencies {
implementation
'com.google.android.gms:pla
y-services:+'
implementation
'com.android.support:multid
ex:1.0.3'
implementation
fileTree(dir: 'libs', include:
['*.jar'])
// More deps here //
}
Lint.xml
<?xml version="1.0"
encoding="utf-8"?>
<lint>
</lint>
gradle-wrapper.properties
#Mon Nov 19 22:22:06 PST
2018
distributionBase=GRADLE_U
SER_HOME
distributionPath=wrapper/di
sts
zipStoreBase=GRADLE_USER
_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://servi
ces.gradle.org/distributions/
gradle-4.6-all.zip
main.ccp
#include
"PTPAppDelegate.h"
#include "cocos2d.h"
#include "PTPConfig.h"
#include
"models/PTModelController.
h"
#include
"PTPSettingsController.h"
#include
"platform/android/jni/JniHel
per.h"
#include <jni.h>
#include <android/log.h>
#include
"models/screens/PTModelSc
reen.h"
#include
"models/PTModelAtlas.h"
#include
"models/PTModelGeneralSet
tings.h"
#include
"models/objects/PTModelAs
setCharacter.h"
#include
"models/objects/PTModelOb
jectButtonPurchase.h"
#define LOG_TAG "main"
#define LOGD(...)
__android_log_print(ANDROI
D_LOG_DEBUG,LOG_TAG,__
VA_ARGS__)
#define
ARCHIVE_PASSWORD
PTJniHelper_passwordJNI()
using namespace cocos2d;
extern "C"
{
jint JNI_OnLoad(JavaVM
*vm, void *reserved){
JniHelper::setJavaVM(vm);
return JNI_VERSION_1_4;
}
std::string
PTJniHelper_passwordJNI(){
JniMethodInfo
methodInfo;
if (!
JniHelper::getStaticMethodIn
fo(methodInfo,
"com/secrethq/utils/PTJniHel
per", "password",
"()Ljava/lang/String;")){
return "";
}
jstring returnString =
(jstring) methodInfo.env>CallStaticObjectMethod(me
thodInfo.classID,
methodInfo.methodID);
methodInfo.env>DeleteLocalRef(methodInfo.
classID);
const char *out =
methodInfo.env-
>GetStringUTFChars(returnSt
ring, NULL);
methodInfo.env>DeleteLocalRef(returnString
);
std::string outString(out);
return outString;
}
void
Java_com_secrethq_utils_PT
JniHelper_updateScreenGeo
metry(JNIEnv* env, jobject
thiz, jstring
adNetworkNameString ){
PTPAppDelegate::updateScre
enGeometry();
}
jboolean
Java_com_secrethq_utils_PT
JniHelper_isAdNetworkActiv
e(JNIEnv* env, jobject thiz,
jstring
adNetworkNameString ){
const char*
adNetworkName = env>GetStringUTFChars(adNetw
orkNameString, 0);
std::string platformName =
"Google Play Store";
PTModelController *mc =
PTModelController::shared();
PTPSettingsController* sc
=
PTPSettingsController::share
d();
std::vector<PTModelScreenP
tr> screensArray = mc>getModels<PTModelScreen
>();
if(screensArray.empty() ||
sc->removeAds()){
return false;
}
for(int i=0; i <
screensArray.size(); i++){
PTModelScreenPtr
model = screensArray.at( i );
if(model>adNetworkFullscreen() ==
adNetworkName){
return true;
}
if(model>adNetworkBanner() ==
adNetworkName){
return true;
}
}
// check if this network in
backup list
// banner
std::list<std::string>
bannerList =
PTModelGeneralSettings::sh
ared()->adBannersList(
platformName );
std::list<std::string>::const_it
erator bannerIterator;
for (bannerIterator =
bannerList.begin();
bannerIterator !=
bannerList.end();
++bannerIterator) {
if(strcmp((*bannerIterator).c
_str(), adNetworkName) ==
0){
PTLog("ad Network
(%s) in backup list (banner)",
adNetworkName);
return true;
}
}
// interstitials
std::list<std::string>
interstitialList =
PTModelGeneralSettings::sh
ared()->adInterstitialsList(
platformName );
std::list<std::string>::const_it
erator interstittialsIterator;
for (interstittialsIterator =
interstitialList.begin();
interstittialsIterator !=
interstitialList.end();
++interstittialsIterator) {
if(strcmp((*interstittialsIterat
or).c_str(), adNetworkName)
== 0){
PTLog("ad Network
(%s) in backup list
(interstitials)",
adNetworkName);
return true;
}
}
// check if network is used
as reward video
std::vector<PTModelObjectB
uttonPurchasePtr>
buttonsArray = mc>getModels<PTModelObject
ButtonPurchase>();
if ( !buttonsArray.empty()
){
for(int i=0; i <
buttonsArray.size(); i++){
PTModelObjectButtonPurcha
sePtr model =
buttonsArray.at( i );
if ( model>purchaseMethod() ==
"kRewardedVideos"
&& model>rewardedVideoAdNetwork(
) == adNetworkName) {
return true;
}
}
}
// check if network is used
as reward video
std::vector<PTModelAssetCh
aracterPtr> charsArray = mc>getModels<PTModelAssetC
haracter>();
if ( !charsArray.empty() ){
for(int i=0; i <
charsArray.size(); i++){
PTModelAssetCharacterPtr
model = charsArray.at( i );
if ( model>purchaseMethod() ==
"kRewardedVideos"
&& model>rewardedVideoAdNetwork(
) == adNetworkName) {
return true;
}
}
}
return false;
}
void
Java_org_cocos2dx_lib_Coco
s2dxRenderer_nativeInit(JNI
Env* env, jobject thiz, jint w,
jint h){
PTModelController *mc =
PTModelController::shared();
if
(!CCDirector::sharedDirector(
)->getOpenGLView()){
CCEGLView *view =
CCEGLView::sharedOpenGLVi
ew();
view->setFrameSize(w,
h);
///////////////////////////////
//////
bool bRet = false;
unsigned long size = 0;
char* pBuffer =
(char*)CCFileUtils::sharedFile
Utils()>getFileData("data/data.pkg"
, "rb", &size);
if (pBuffer != NULL &&
size > 0){
PTLog("data.pkg size:
(%lu)", size);
mc>setUsingDataEncryption(
true );
}
std::string path =
CCFileUtils::sharedFileUtils()>getWritablePath();
std::string filePath =
path +
std::string("data.pkg");
FILE *fp =
fopen(filePath.c_str(), "wb");
if (! fp){
PTLog("can not create
file %s", path.c_str());
return;
}
fwrite(pBuffer, 1, size,
fp);
fclose(fp);
if (
CCFileUtils::sharedFileUtils()>isFileExist(filePath) ) {
PTLog("pkg file is
good");
}
//loading general info
mc->clean();
mc>loadDataForSplashScreen(fil
ePath,
ARCHIVE_PASSWORD.c_str())
;
PTPAppDelegate
*pAppDelegate = new
PTPAppDelegate();
pAppDelegate>setDataArchiveProcessor(A
RCHIVE_PASSWORD);
CCApplication::sharedApplica
tion()->run();
//clean up main model
controller before starting
loading Objects form XML
files
mc->clean();
}
else {
PTLog("NATIVE RE
INIT");
ccGLInvalidateStateCache();
CCShaderCache::sharedShad
erCache()>reloadDefaultShaders();
ccDrawInit();
s2dxRenderer_nativeOnSurfa
ceChanged(JNIEnv* env,
jobject thiz, jint w, jint h){
auto models =
PTModelController::shared()>getModels(PTModelGeneral
Settings::staticType());
if(models.size() != 0){
//Checking if there is no
PTModelGeneralSettings
then we are not ready for
reshape (meains we are in
the middle of loading
process)
CCEGLView *glView =
CCEGLView::sharedOpenGLVi
ew();
CCDirector::sharedDirector()>reshapeProjection(CCSizeM
ake(w,h));
glView->setFrameSize(w,
h);
PTPAppDelegate::updateScre
enGeometry();
}
}
}
Android.mk
LOCAL_PATH := $(call my-dir)
CCTextureCache::reloadAllTe
xtures();
include $(CLEAR_VARS)
CCNotificationCenter::shared
NotificationCenter()>postNotification(EVNET_CO
ME_TO_FOREGROUND,
NULL);
LOCAL_MODULE :=
player_shared
CCDirector::sharedDirector()>setGLDefaultValues();
LOCAL_SRC_FILES :=
main.cpp
}
}
void
Java_org_cocos2dx_lib_Coco
LOCAL_WHOLE_STATIC_LIBR
ARIES := core_static
cocos2dx_static box2d_static
LOCAL_MODULE_FILENAME
:= libplayer
GOOGLE_PLAY_STORE :=
true
include
$(BUILD_SHARED_LIBRARY)
$(call import-module, box2D)
$(call import-module, core)
$(call import-module,
cocos2dx)
Application.mk
APP_OPTIM := release
NDK_TOOLCHAIN_VERSION
:= clang
APP_STL := c++_static
APP_CPPFLAGS := -frtti fexceptions -Wformat=0 std=c++11 DGOOGLE_PLAY_STORE fsigned-char -Wnononportable-include-path
APP_LDFLAGS := -latomic
APP_ABI := armeabi armeabiv7a
APP_PLATFORM := android14
dagger-2.7.jar
0000 0000 0000 0000 0000
0900 0000 4d45
5441 2d49 4e46 2f50 4b03
0414 0008 0008
006d 572d 4900 0000 0000
0000 0000 0000
0014 0000 004d 4554 412d
494e 462f 4d41
4e49 4645 5354 2e4d 4645
cdb1 0ac2 3010
80e1 3d90 77b8 1748 8888
28dd 5ab7 42c1
c9fd 68ce 2618 72e5 9206
7d7b 5111 d7ff
1bfe 0973 bc51 a9e6 4a52
22e7 0e76 d669
d5cb 1c62 23f9 e74b a2c7
56e0 075a 9d85
b092 37c3 b383 7ec5 3910
4cd8 28c3 de3a
7bd0 6ad8 62aa 1f15 ce25
e01a 85bf d59b
d1df dfa3 9375 6661 5e12
9976 d44a ab17
504b 0708 92ab 04aa 7700
0000 8e00 0000
504b 0304 0a00 0000 0000
6d57 2d49 0000
0000 0000 0000 0000 0000
0700 0000 6461
6767 6572 2f50 4b03 040a
0000 0000 006d
572d 4900 0000 0000 0000
0000 0000 0010
0000 0064 6167 6765 722f
696e 7465 726e
616c 2f50 4b03 040a 0000
0000 006d 572d
4900 0000 0000 0000 0000
0000 0015 0000
0064 6167 6765 722f 6d75
6c74 6962 696e
6469 6e67 732f 504b 0304
1400 0800 0800
6d57 2d49 0000 0000 0000
0000 0000 0000
1500 0000 6461 6767 6572
2f52 6575 7361
626c 652e 636c 6173 7385
8fcd 4a43 410c
854f 5adb a9d5 da2e 74e1
4add 74e9 805b
5782 1604 ffb8 55f7 d369
b84c 99ce 48ef
4cd1 5773 e103 f850 626e
41bb 2934 909c
907c 49c8 f7cf e717 800b
0c14 7a0a 070a
7d42 771c f3c2 f2c8 7926
f40a ce95 9978
3e9f 99a5 211c 1739 2437
e757 5739 a95e
8510 9349 2e86 8a70 7657
33da 9b50 6af3
dfd0 d7d1 e639 87c4 d34b
c2e9 66a6 e024
8464 82b4 96c6 6739 3ddc
823e 45ef ec87
0ca8 e2e5 e1f9 f6fe 8670
b81a 79d7 2ecc
d826 3db6 f18d 05e8 4f4d
59f2 42ff fd42
18ac 573f 4e6a 9670 b2f1
dafa c121 81d0
106f a2b6 0676 56b1 85b6
e891 5495 6847
fabb 8c2e f6b0 0ffc 0250
4b07 08a7 93c4
0ee0 0000 005f 0100 0050
4b03 0414 0008
0008 006d 572d 4900 0000
0000 0000 0000
0000 0016 0000 0064 6167
6765 722f 436f
6d70 6f6e 656e 742e 636c
6173 7385 925d
4b02 4114 86cf a4b6 6966
5a96 da07 5684
5417 2d74 5b04 a506 421f
a25b 105e 8dbb
a765 6476 5676 7704 ff5a
17fd 807e 5474
5642 2316 ba98 d9f3 f13e
ef30 67f6 f3eb
fd03 002e 60cf 80aa 0135
0376 0cd8 6560
dc6a 211d 0c18 e43b 4a61
d094 3c0c 31a4
86e7 3b5a c651 f9e4 7470
3fe2 136e 4aae
5c73 a6b8 6450 ba51 ca8f
7824 7cd5 c237
ae65 c420 db17 aee2 910e
9041 2501 bb3a
bb26 32ef e018 9583 ca16
b17f aeef ebc0
c63b 2189 2a34 7d6f ec2b
54d1 79cc 32a8
f5b4 8a84 872f 2214 4389
8b43 893c f8e5
cfe7 0db3 8711 f114 d159
9909 979a 7c1b
ff48 bbbe 14f6 9400 a3f7
fc68 751e da0c
f693 118b 072e 46a4 3c4a
eeb7 257a e469
4dc7 48a2 b4f5 da25 afc3
646d cbb7 752c
4687 a445 87bb 2e06 e67c
0254 5a50 4fc3
11da 54aa 271a 2dc6 c2a0
fad7 e7f8 e78d
1b0c 182c d14a d19f b094
a6bb c20a e559
ca52 03da 7271 1956 a991
4f6c 10b7 368b
0ab0 4edf 3ae5 4572 2b21
6cc0 2694 e370
000c 610b b6a1 4282 e519
4a33 a095 6964
bf01 504b 0708 20bb 6ac8
6501 0000 8302
0000 504b 0304 1400 0800
0800 6d57 2d49
0000 0000 0000 0000 0000
0000 1500 0000
6461 6767 6572 2f50 726f
7669 6465 732e
636c 6173 7385 91df 4a02
5110 c6bf 63ea
9669 6a99 6911 5684 d44d
0bdd 7653 a491
e0bf 6ced a6ab a34e cbca
7a36 76cf 0abe
5a17 3d40 0f15 cd06 26c4
4617 c39c 6fe6
c7cc f09d 8fcf b777 0097
3830 b067 a062
a06a 605f 2069 2d5e 4920
db52 8afc 5b57
0601 055c d5df d5ca d979
7b22 6d9b 7cb3
ef7b 7367 42c1 69c4 5f09
146f 94f2 b4d4
8ea7 1af4 2243 570b 94ff
82d3 c36e eb61
d814 c83c 7aa1 3fa6 3bc7
e5e9 b925 7631
9573 2950 1d84 4a3b 337a
7202 67e4 d26a
011f 74dc 8e18 d395 ca36
e54f c36c 78e3
7046 4ad3 84b7 1cc6 3396
f46d d2dc 4fcd
a51b f2de 9378 aee9 5234
6a79 72a7 69dd
f71a 0247 f1f4 8034 c3fc
62b6 fe0f d2f7
5c67 bc60 d018 0cbb 56ab
c346 e47f 3925
5058 cde8 8da6 3466 3f6b
b163 57be 0894
e20c af0b 0824 38d6 f8c3
4592 d762 9dd5
06ab 1421 834d 6e64 5924
90c3 16e7 1aeb
3ce7 0243 c567 08c2 3676
508a 1461 1765
a4b9 9961 99e4 485d 57bf
0050 4b07 08af
188f 3446 0100 004b 0200
0050 4b03 0414
0008 0008 006d 572d 4900
0000 0000 0000
0000 0000 001c 0000 0064
6167 6765 722f
4d65 6d62 6572 7349 6e6a
6563 746f 722e
636c 6173 733b f56f d73e
0606 0623 061e
7606 2e76 066e 4606 decc
bcac d4e4 12df
d4dc a4d4 a262 4606 510d
9fac c4b2 44fd
9cc4 bc74 7dff 2490 9cb5
6618 2303 6770
667a 5e62 4969 512a 2303
9b46 4808 5850
c326 c40a 53b9 1da6 1023
0357 707e 6951
72aa 5b66 0ed0 0011 a875
9e60 bbf3 8bf4
401a 1819 c452 12d3 d353
8bf4 d164 1919
04d0 0d64 6364 6064 6062
0001 4616 4606
6606 1620 9f15 c863 6260
0362 088b 9d81
034c 7302 0050 4b07 08e1
7cd9 60a0 0000
00f6 0000 0050 4b03 0414
0008 0008 006d
572d 4900 0000 0000 0000
0000 0000 001e
0000 0064 6167 6765 722f
436f 6d70 6f6e
656e 7424 4275 696c 6465
722e 636c 6173
736d 8f4d 4bc3 4010 86df
e987 6b63 adf5
e3a0 0711 457a 34e0 b527
ad15 0441 d120
88a7 6d32 8494 cd6e 4936
05ff 9a07 7f80
3f4a 9c5c 5290 2ccc 0733
cfcc 3bfb f3fb
f50d e01a 870a bb0a 6385
7d42 f0ea aa22
e6fb cc30 6134 73f9 ca59
b6fe 6aa9 d79a
70f2 5259 9fe5 fc96 95d9
c2f0 8db5 ce6b
9f39 5b12 4e1f 6b26 34da
a6a1 6e1a 61a4
8b94 fd94 d05f 6b53 c9d2
8b76 6e6e 3817
a1e8 73c5 02f7 a2f7 e739
e1bc 9dbd 7371
55c3 9c4c 150e 08c7 894e
532e c2e6 dccb
db2a 3309 1704 d564 c307
6bb9 9819 5d96
2ce7 8e37 9b9f 164b 8e3d
e1ac 556c f349
19fa 2f34 2110 3a62 5dd4
af8b 9ef8 0efa
d892 7824 9992 def6 0788
3140 801d a9ee
8905 a8e7 8618 4d06 7f50
4b07 08aa ea05
89f8 0000 0086 0100 0050
4b03 0414 0008
0008 006d 572d 4900 0000
0000 0000 0000
0000 0021 0000 0064 6167
6765 722f 5375
6263 6f6d 706f 6e65 6e74
2442 7569 6c64
6572 2e63 6c61 7373 6d8f
4d4b 0331 1086
dfe9 87b1 6bd5 d67a 1111
51a4 4717 7aed
c98f 0a82 a0d8 4510 4fd9
dd61 4949 93b2
9b14 fc6b 1efc 01fe 2831
7b69 3dec c09b
0c99 27f3 cefc fc7e 7d03
9860 24b0 2f30
1018 12a2 b9f5 65c6 0f4a
3361 38f7 6966
972b 6bd8 b8eb 855c 4bc2
c9ab 374e 2df9
4d55 2ad5 7c63 8c75 d229
6b2a c2d9 53cd
c45a 9a22 969b 429c c8b2
6037 2574 d752
fbd0 f7b2 999b 695e 06a3
e473 c501 ee24
ef2f 33c2 4533 7b6f 335f
c39c 4f05 8e08
a7b9 2c0a 2ee3 ff13 5fdd
7aa5 732e 0962
93f5 1f8d e1f2 4ecb aae2
30f1 60db fc39
5d70 e608 e78d 7edb 3d09
a306 af31 81d0
0a6a a38e 363a e16c a18b
9d70 1f87 4c84
daee 0788 d143 84bd f07a
1814 a1fe d7c7
c1b8 f707 504b 0708 d9cb
77cd fc00 0000
8f01 0000 504b 0304 1400
0800 0800 6d57
2d49 0000 0000 0000 0000
0000 0000 1100
0000 6461 6767 6572 2f4c
617a 792e 636c
6173 733b f56f d73e 0606
0623 061e 7606
2e76 066e 4606 e6f4 d412
4606 110d 4d9f
acc4 b244 fd9c c4bc 747d
ffa4 acd4 e412
6b46 06ce e0cc f4bc c492
d2a2 5446 0656
0dcd 9010 a098 864d 8815
a65a 3b6c dab9
82f3 4b8b 9253 dd32 7380
fa39 7d12 ab2a
f540 aa18 19b8 5312 d3d3
538b f441 428c
0c02 e85a d918 1918 1998
1840 8091 05e8
4406 1620 9f15 c863 6260
0362 088b 9d81
034c 7302 0050 4b07 08e5
eb58 8392 0000
00d4 0000 0050 4b03 0414
0008 0008 006d
572d 4900 0000 0000 0000
0000 0000 0013
0000 0064 6167 6765 722f
4d61 704b 6579
2e63 6c61 7373 8590 4f4b
0251 14c5 cff5
4f53 9aa9 fd83 1661 b590
da34 d0b6 95a0
8194 a3d8 2464 8b78 8eb7
6164 7c23 e31b
c3af d6a2 0fd0 878a ae09
b919 68f1 b8f7
727e e7f0 385f df1f 9f00
6e70 6ce1 c0c2
a185 2342 31d1 efb1 9a0d
5498 3021 7b79
3524 541b 5a47 4699 20d2
4d7e 5349 68b2
e223 42e1 314a 628f ef82
50d8 6247 cdee
7979 3d51 0b45 38e9 27da
0453 1e04 f360
14f2 2661 4e38 7f58 3176
a8b4 6fab 3fc1
6e46 5e32 656d 787c 4b38
4d67 5c15 fb6c
44cf 2fd6 3fbc 48e7 5a21
afa2 dce5 8c05
2e37 1ca7 eb36 dc76 d779
759f 7b2d c259
baad cf46 5cb2 89a9 fe0f
d28b c2c0 5b0a
68f5 9f1c b7dd 91d4 d258
f93e c7f6 ba09
4265 93d0 1d4d d833 845a
6ae8 a69e 3a81
9091 f75b 718e 9043 5eae
2db9 b243 5822
6dcb 9ac1 0e0a 326b 8215
65ee 0a52 7a01
31f6 5046 6575 31aa d8ff
0150 4b07 084c
14e3 b025 0100 00e3 0100
0050 4b03 0414
0008 0008 006d 572d 4900
0000 0000 0000
0000 0000 0019 0000 0064
6167 6765 722f
5375 6263 6f6d 706f 6e65
6e74 2e63 6c61
7373 8592 4d4f c240 1086
67f9 b082 a820
2822 31a8 3144 3dd8 c4ab
c644 0513 123f
08a0 89e1 b4b4 6353 b2dd
25ed 2e09 7fcd
833f c01f 659c 1223 1c9a
7898 ee4c e779
df76 76f7 ebfb e313 002e
a06e 41d5 825d
0b6a 16ec 31b0 6e8d 2f5c
0c19 143a 5262
7827 7814 6144 8d40 b946
c459 e5e4 74f8
30e6 536e 0b2e 3d7b 4e5c
3228 dd48 a934
d7be 922d 7ce7 4668 06b9
beef 49ae 4d88
0caa 09b2 abb3 6b52 e6fb
ca84 0ede fb82
b052 df8c 1c15 4c94 44a9
cf63 9e41 ad67
a4f6 037c f523 7f24 70f1
21fa 9b83 254f
fed7 b07b a849 4f19 f967
a75c 18b2 6efe
8376 95f0 9d19 09ac decb
d3a0 f3d8 66b0
9f2c 19f0 d043 4de4 5172
bf2d 3020 cfc1
6c82 0465 066f 5df2 3a4c
665b ca31 318c
2ea1 6597 7b1e 86f6 f226
3028 2e84 cfa3
313a f4aa 91e8 b5d8 1906
f504 abe3 dfd3
6d32 6090 a248 d31d 6019
9a18 56a9 ce51
951e d223 4f91 8235 6a17
e6d9 3a6c d0da
a07a 9344 4584 126c 4139
4e87 c010 2ab0
0d3b 04ac cca5 3430 45b6
99fb 0150 4b07
08f2 ed6e 4d5b 0100 0064
0200 0050 4b03
0414 0008 0008 006d 572d
4900 0000 0000
0000 0000 0000 001a 0000
0064 6167 6765
722f 5072 6f76 6964 6573
2454 7970 652e
636c 6173 737d 526b 4f13
5110 3d97 6ebb
db65 4ba1 f661 11f1 85da
16a5 5241 d436
0424 3521 a980 d982 69fc
6096 76ad 4b96
add9 b624 26fe 2829 8918
8d86 cffe 28e3
cca5 18aa c5bb c94c ce9d
3333 6766 efcf
5f5f 7f00 28a0 1486 827b
3aee 634e 455a
c503 1de3 9867 53d0 30a1
53b0 c08c 871a
12ec 1734 24d9 2f6a 48b1
7fa4 6249 20b4
bdb1 fe72 bb2c a054 3fbc
b705 8c75 cfb3
fd35 d76a b7ed b640 b2d2
b09a 4ddb cf6f
f9ad 03a7 61b7 6798 5614
0898 e5aa 804e
f6cd ce6a 65bb 6cd2 d58b
d52d 0175 e60c
a75e 5f94 1c3a b0dc 2e97
4f67 b217 9294
b556 8304 452b 8e67 6f74
f777 6dbf 6aed
ba74 a3ca eccd b702 b94c
65cf 3ab0 f2ae
e535 f366 c777 bc66 317b
51bd 58a5 55b7
dc1d cb77 b84c bf96 e259
fb36 c7fe a943
2a4b 8ee7 7496 6909 43da
ac67 7728 bbf3
cea1 29c2 a6d3 f4ac 4ed7
a74a 810c 07b4
52dd ed27 9fcf 2d7b ddfd
d270 7dcb 45de
66ab ebd7 ede7 0e2b 8b9c
c5e7 38df c065
fec5 6903 8ff1 44c5 5381
f8b0 3206 a651
3470 0b33 0626 1037 9060
9364 9342 5c60
6c50 8b40 b0ee b63c ea16
cf64 cfe9 dcdc
ddb3 eb1d 5214 fdab 89c0
e2f9 79e4 3329
0efb 0783 7d8a 2bf3 f4e0
c6e9 d506 57d2
2c0c 209f e8fb 64df a7d8
8f4f f2a4 c454
10c6 24ae 4060 8ad0 4df2
7cf4 1ec4 678c
9c20 f089 90c0 55b2 2119
2b10 7f1a d7fa
fc05 8cc8 5b3d a6e4 be20
7802 85f9 2303
fceb 648d 5316 6e50 078e
d3e6 c872 8579
04e8 03d4 dcec d431 4287
ff49 5771 9ba5
e38e e4dc 8586 0cd9 5321
1f69 103e d56f
506a 3135 700c ed08 6109
7445 8251 098c
a004 1109 c642 1244 d5ef
8402 3d7a 6035
a587 51b3 16ec 2162 d642
3d44 cd23 88c3
3f2b 4822 4876 0911 3ca3
a555 a8fb 2b5a
4181 0638 d594 454e fa59
5c92 e3d2 d345
1eb1 95f4 6f50 4b07 0812
ab33 3460 0200
004d 0400 0050 4b03 0414
0008 0008 006d
572d 4900 0000 0000 0000
0000 0000 0013
0000 0064 6167 6765 722f
4d6f 6475 6c65
2e63 6c61 7373 8591 4d4b
0331 1086 27fd
70fb 61b5 d56a 1111 c543
510f 2e78 5504
d10a 82d5 b25d 05d9 53ba
1d97 946c 5276
9342 ff9a 077f 803f 4a9c
5570 3d2c 7848
f24e 66de 6798 e4e3 f3ed
1d00 cea0 e740
d781 2d07 b619 d484 0aa5
9d62 caa0 7b74
1cdc cff8 82bb 92ab c8bd
963c 4dcf 1974
ae94 d286 1ba1 d50d be72
2b0d 83fa 5844
8a1b 9b20 835e 81ed e2e4
929c add4 4e42
1dcf b542 65a8 4163 ac6d
12e2 ad90 646b
0ef5 d44a 3ccd 9c0c 763c
ab8c 88f1 59a4
6222 316f 49b6 833f 74fe
9b70 3d34 8425
459d aa0b 2e2d 41fb ff94
8eb4 14e1 920c
8ef7 f4e0 df0d 070c f68a
2d3e 4f22 3454
7958 9c1f 488c 89e9 2fe7
4845 15ff 6544
acd6 9447 1126 eecf 680c
dab9 f571 32c3
905e 6ebf 9096 cfdb 67c0
a044 ab4c 5f55
aa10 1aaa 14af 5054 0e68
73b2 6ba8 51a2
5e98 a0d5 f856 4d58 a573
9754 8b68 6b08
ebd0 864e 2603 6008 1bb0
f905 504b 0708
09f5 1b5c 3601 0000 1002
0000 504b 0304
1400 0800 0800 6d57 2d49
0000 0000 0000
0000 0000 0000 1a00 0000
6461 6767 6572
2f69 6e74 6572 6e61 6c2f
4265 7461 2e63
6c61 7373 858f bb6a 0251
1086 fff1 b66a
6e06 6c52 a98d 650e a44d
a531 a904 c38a
e9c7 7558 8e1c cf81 f5ac
e0ab a5f0 01f2
5021 b329 6223 6460 e61f
986f 6e5f df9f
2700 4fb8 4b70 9de0 26c1
2da1 bb0c 6591
c99b 7542 e84c 25f2 e396
0f4c 7848 4b1f
ed4e 3eec deae 9d4c bc0f
91a3 0d7e 4f18
cd2b c638 f6b9 e1bf 8299
85ac dc89 8fb2
7926 0c2f 33a9 4425 3453
a479 6057 eada
f13f e87b 7036 3b6a 436b
b958 a52f af84
fe86 f35c 0a63 7559 e1d9
99ea 7042 ef3c
67b1 de4a 1609 838b a3cf
df8c 0984 9a7a
1d95 d5d0 f88d 4db4 54ef
354b 54db 5aef
08ba b8fa 0150 4b07 08da
e884 49d1 0000
0044 0100 0050 4b03 0414
0008 0008 006d
572d 4900 0000 0000 0000
0000 0000 0022
0000 0064 6167 6765 722f
696e 7465 726e
616c 2f53 6574 4661 6374
6f72 7924 312e
636c 6173 738d 52db 4ac3
4010 3d6b 5353
63b4 555b eff7 0bb4 828d
fada 2248 5110
ea05 2abe 6fd3 255d 891b
49b7 827f a52f
2a3e f801 7e94 3889 11a5
5531 b033 3b67
cedc b2f3 faf6 fc02 6017
6b16 d298 b130
8b39 0b06 e64d 2c98 5834
b1c4 3058 954a
ea3d 8654 b174 c160 d482
9660 c8d6 a512
27dd aba6 08cf 79d3 2764
bc1e b8dc bfe0
a18c ec04 3474 5b76 18ec
23a5 4458 f379
a723 c85c acb7 b8e7 89d0
914a 8b50 71df
6908 7dc8 5d1d 84b7 eb3b
152a e509 cd30
562c d52f f90d 77ba 5ac6
14f2 0c35 a4a7
b8ee 8694 7ca3 d75f fd30
7dae 3ce7 b479
295c 5dd9 a398 fc27 efbb
83e1 ac1f eceb
2b69 aafa 8f3a 5125 ab11
7443 571c ca68
f6ec d750 e588 4fc8 8172
fda0 2395 772c
743b 6899 58b6 6122 6362
c5c6 2a72 36b2
c831 ccff f577 1872 bdc5
19a6 7ee9 9b61
f6f7 5c0c 85af a96a 81ef
532a 1928 7a9f
8cb8 bad6 b7c4 c436 2d43
1ab4 04b4 2529
3ad4 2c59 4374 7348 33d2
e9cd 47b0 7bba
0cc0 2239 1883 9b18 2669
7f10 488f 9266
d170 c48a 82cb 49b0 f184
81bb 9ed8 ad6f
b146 123b 1673 c673 fb94
63a2 af81 07a4
7a93 fcd4 8091 a4c9 a310
eb49 4cc5 e834
c911 3a16 b10d 445f e61d
504b 0708 c05b
0eeb 9501 0000 1803 0000
504b 0304 1400
0800 0800 6d57 2d49 0000
0000 0000 0000
0000 0000 2400 0000 6461
6767 6572 2f69
6e74 6572 6e61 6c2f 5072
6f76 6964 6572
4f66 4c61 7a79 2e63 6c61
7373 9554 d952
1351 103d 37db 8461 3021
ac92 208b 8049
5082 881b c448 4cf0 c508
5625 4515 bc58
c364 0c03 6386 9a4c 28f1
1ffc 017e c057
7101 4aaa d437 abfc 28b5
6732 0959 b17c
b94b 77df 734e 77df 7b7f
fdfe fa0d c002
5679 f4e0 5617 38cc 7188
f170 5636 f33c
6e63 81c3 1d1e 8bb8 cbe1
1e4f c6fb e6f0
80c7 432c 7158 66f0 eeeb
da81 9297 7586
a1cc ae78 20be 8929 c55d
5932 622f 6c07
0575 6595 4251 34ca bacc
106a 1f15 cfe5
9613 14da 3725 964a b26e
285a b194 564a
e2b6 2ae7 19d8 1683 27ae
1415 23c1 3012
ee40 14d9 6070 a5b4 3cb1
f832 4a51 5e2b
bfde 96f5 9c89 c110 c868
92a8 6e88 ba62
ee6d a3cb d851 4a0c e399
bc58 28c8 3a21
1ab2 5e14 d51a e6fa ab8c
f8f6 9074 0d36
1e3f dcaf 424c ffe3 6c35
b19e ac21 4a7b
cfc5 7deb 1c55 950a ca30
d621 97ca 2933
2167 4136 289f 70a4 ca63
0bea 6fb4 5469
3c92 2e8b 06e9 9aef 58a5
8e6d 7a19 cf2d
59ce 982a 160b b1f5 6d33
6039 71b9 c40e
ce56 6d09 5b74 0b01 5da2
b8a4 dacd 7586
cda4 b3ed 95b4 9afe 8b9d
cf6a 655d 929f
2a66 dffa 1adb 3467 0209
e847 4440 007d
0cc3 175c c9ea 8d5c d575
4d17 7005 3e0e
7101 8f40 82af 5dde 7e0e
8f05 ac20 c930
d056 aa49 3920 6002 931c
9e08 4821 cde0
6f4e 9321 d8cc 92d6 ca74
8d52 3bb2 b447
d758 2526 8699 ce2d 6fbc
3ba3 ad9a 6549
2be6 15eb d931 0892 89bb
a619 6b65 55ad
e136 14be 6d1f 7d17 b694
4aef 989e 4d5e
2e29 ba9c af95 905e 8151
2e59 7dde a2ef
85a3 9f87 fe07 38a8 e854
565a fbe9 4b72
a0d7 3f6c b681 d66e da51
8968 1ca4 dd3b
9a1d 3487 a2a7 601f e138
826f f627 bacf
e1dc 3c85 eb7b 74f6 0bdc
c7e4 7761 88c6
00cd c018 8de3 747a 0241
4c62 982c 8315
0c5c c508 60ad 2adc c106
5fa8 e6eb 25df
28ad 29e6 8f19 c0e1 1a47
b0b0 c58e 939b
1a68 4b4c d38e d1ec 8d7e
86fb 0c9e 0fb4
765a 723c 963d 6a49 102a
31b6 8460 8325
5443 be4e a599 c2b4 8dfc
8c70 cc18 df39
b8cd e819 bc3f d075 0abe
9960 b18e c067
6556 4fe0 b3f2 a912 ccf8
9324 fd06 794c
82a4 2ddd 1d3d 4177 336c
b00e d6dd a2db
6deb f622 8c88 0db7 6879
80de 0077 02e1
089c eb3d 5cce 4f70 1c5b
dcf5 d0a3 954e
0b2b 8c1c 1569 51cc 5af3
cdbf 504b 0708
313f d9d1 0003 0000 a806
0000 504b 0304
1400 0800 0800 6d57 2d49
0000 0000 0000
0000 0000 0000 1d00 0000
6461 6767 6572
2f69 6e74 6572 6e61 6c2f
4661 6374 6f72
792e 636c 6173 733b f56f
d73e 0606 0623
066e 7606 0e76 064e 7606
2e46 06ce e0cc
f4bc c492 d2a2 5446 0617
9b10 2b9f acc4
b244 fd9c c4bc 747d ffa4
acd4 e412 6b3b
4c21 b048 857e 661e 88a7
1f50 945f 9699
925a 6413 1262 6d67 cdc8
c015 9c5f 5a94
9cea 9699 0334 93c7 2d31
b924 bfa8 520f
a485 9141 3c25 313d 3db5
08a8 b524 b528
2f31 471f 2acd c820 806e
0b23 8328 566b
d818 1918 1998 8098 9901
0498 1858 c024
2b03 1b98 6607 0050 4b07
0835 13b6 5ba0
0000 00e7 0000 0050 4b03
0414 0008 0008
006d 572d 4900 0000 0000
0000 0000 0000
0020 0000 0064 6167 6765
722f 696e 7465
726e 616c 2f53 6574 4661
6374 6f72 792e
636c 6173 73ad 57db 5354
751c fffc f6c2
81dd a320 b828 ac98 575c
5610 41a5 c495
4404 5de3 9610 8495 7ad8
3dc2 91c3 593c
7b56 c1ca 7ba6 99dd 7b68
9ae9 c187 7c6a
462b 4372 a669 7a6c a687
7aeb a519 7be9
a57f c0a6 b4ef ef9c b307
f602 d84c 30fb
3bbf dff7 f2f9 7def 7bf6 c747
df7e 07a0
111f f910 c42b 45b4 1c11
70d4 0737 8ef9
b00a 12a7 0cf3 25e6 471c
b280 e33e 1461
841f 4605 287e 8838 2160
cc8f a590 3951
f561 1c9a 0f09 4cf8 7112
2a67 e87e 2461
f025 e5c3 299c e657 4d0a
98f2 a102 9280
3302 5e15 f01a 83b0 37a5
a871 5967 10a3
9a26 eb6d aa94 4cca 4986
25ed 5dbd fd43
473b 5adb fa7b 0e0d 3154
74c6 a591 1159
af57 3443 d635 49ad ef90
6246 429f dac5
50d4 a78c 6892 91d2 6586
96f9 e422 9d27
a453 527d ca50 d4fa 3ed9
b08f aaa4 8dd4
f70c 9f90 63c6 ae16 fa67
2853 b4b8 724a
89a7 24b5 574f d046 d6c9
9c92 39da 9d4a
d220 c12d 5924 0b71 922e
e668 f569 e548
7f7f 1a39 9650 5562 2909
6d0e 72c7 13c2
cc11 6b73 70d2 e01c de2b
8f4f 1853 0cc1
50cd 02b1 f2b4 25e2 14a6
e24e 4593 bb53
e3c3 b2de 2f0d ab44 d91f
e96f ce13 93f9
c1b2 03ea f829 0ca7 731a
0a45 a3b9 fa24
6c43 6cb0 b34f 4aa5 9d89
98a4 0e48 bac2
cdb1 6d2a cfcd 459f 7286
182c 4acc dc70
5acc b679 3c79 325b 2c3f
180a 228a a618
2d0c eb43 d9b9 cf3e d70c
505c 8d51 85b2
b96a 811b 08b4 3cd3 cba9
89b4 a76b 17d0
4b5b 743a db90 452a eeff
292c ee9c 7b44
3618 9651 2d64 a49c a76d
c282 89cf aa72
2ff3 4192 3453 e813 a30a
9155 795c d60c
9ef6 9c44 512c 9366 1ecb
72b1 29c2 4bd3
d401 494d f149 519c 6354
7001 97c8 197a
32d4 e58d ce7c 6160 589e
afda 694c f519
526c ac4b 9a30 f368 0eb6
d705 9c15 708e
c290 1daf b4d2 f234 23d3
edd6 450b 6da1
f26d 3033 e59a dcca 9706
be34 32ac 5e58
83a1 3012 53ed 3a77 8738
c060 fee6 c925
fde7 b1e0 eb4b a4f4 98dc
a1f0 7a2f 9eb5
630b 9717 b103 4d22 d660
2dc3 bac5 9b94
8b9f e7cb 9088 0dd8 2862
1336 52e4 45ec
c305 2a9c 590b 5a75 5d9a
e2b1 e3c2 1745
4470 8921 90b7 1138 f310
2527 5f1d 88b8
8c37 045c 11f1 26ae 0ab8
26e2 2d5c a73c
8b78 1b37 28d9 22de c1bb
22de c321 01ef
8bf8 001f 72b4 dd34 0f16
8a3f 43e5 fc6c
face c98e 39c3 8a79 824e
6d91 592a 5499
1969 a04e 9b3d 4749 5922
353e dba2 d1c5
8b8a 2a83 e6ad 2714 e587
003d f255 af5b
8ac7 3937 9757 7398 e65b
f625 fbcc 7346
6757 6af2 e903 5272 94ee
1f54 8cd1 f6c9
0962 c971 6ba8 973b d79a
2ed8 7274 6f55
3672 af2e c712 f4bd 61a3
8ab1 5139 36d6
9d30 ba53 aaca 509d cfc0
7cfe 142a 4e94
321b 391d 3dfe 4d37 2a25
bbe5 49c3 0c11
79e9 d1cc 4320 5f09 f149
95d2 c613 71e5
b839 fccd a4ac 0965 0daf
ec09 8b06 7a71
5a05 7293 5ecf 2a79 7fd0
7e1d bdbe b9b0
1ea5 bcf6 9d73 359d 37cd
3987 20d0 6b5b
0dc2 b4df 4c14 8ec2 ff3c
5fc2 759b 9e0c
b5b4 1698 d46d b64e 1d69
6c41 bdad f12c
bcb4 03fc f7e1 1eaa 0cb2
6978 6e9b 62b3
8a11 6ca5 b5dc 1223 631b
cd2b fc04 d8e8
18b2 9d3e d4dd 36e8 397a
bae9 591c 9e86
37bc f92e 0ac2 b577 21dc
2192 db04 2e85
87d6 315a 55b2 669c 5e26
35f3 9235 961a
9ec6 33e6 25c5 b6f7 7cc7
fd76 6167 8654
b323 55ed 4885 48ca 326a
17d1 a843 2da3
5c3b 49ab 90e8 7f86 bf46
c10c 0a89 771f
4543 7412 ccd3 347c 5dee
16e7 d8e4 a90a
786e 621b 2754 cdc0 efc2
f710 67b0 84d1
7369 b337 58e1 9d41 31c3
b148 2ddf 95b8
3078 d9cd 6e3d fe29 780f
cbba dd4d 1ee7
9626 6fc0 13f0 de44 751d
2705 3c19 58f7
503a 8332 aeec 21e5 5f49
af36 4369 77ad
a3b0 7406 cb19 9a0b 2a08
36c0 f009 827c
574e 24a1 ae42 7080 6e3d
7e60 62fd 5077
0f2b 782a 3d66 c40f 52cc
8129 f870 9676
e7a8 e2ce 5315 5c40 3b2e
a207 97f0 229d
8fe0 0a62 34fd 2671 151f
d3f3 539a 805f
e03a 7ea1 09f8 1b6e e001
9dff a001 c833
7586 7e21 b4a3 0c2d 6605
55a1 157b a81c
dc14 fd26 da37 d2ad c7a9
20f6 98bb 9354
9f9c e625 2411 7bd1 4655
fb19 a236 f773
e259 5cca 8d9d 791f 7ea7
31cf cb2b 889f
e91e 9ef9 18ae a103 fbe9
0e5e 03db 49de
baff 8083 1b25 5c0b 83d7
85a5 79d0 d17c
8e34 3b89 de80 c2c7 64a6
5740 1713 d0cd
a86e 1e62 c723 940a e861
ec21 6afe 818f
b1bf b152 40ef 5f58 fb90
e0ad 727a bea4
957f 7d90 51bc c65b e9c9
4bce 1bfe 062b
6f3b 956d b54c c88c 9168
09d8 3eed cca0
9085 25a0 08f5 d970 12e9
f39e 10c2 9b6b
a7c1 eee4 050c 5b22 4e7b
08e8 b7db 43c0
0b66 90f8 6e00 8376 9044
9b67 05a4 9092
3c64 5fb7 de94 35db be62
681a 955f c175
276b 5ed4 1088 e5f8 61bc
643e 5fc6 5366
eff2 e60e 6235 fdcc ab30
410a ff05 504b
0708 f2ad fb42 4906 0000
6f0e 0000 504b
0304 1400 0800 0800 6d57
2d49 0000 0000
0000 0000 0000 0000 2700
0000 6461 6767
6572 2f69 6e74 6572 6e61
6c2f 4461 6767
6572 436f 6c6c 6563 7469
6f6e 732e 636c
6173 738d 544d 531b 4710
7d8b 8416 2dcb
9730 b22d ec04 9b7c 20d9
41c1 4970 8c14
0116 10cb 08e4 448a 8873
2183 b405 6baf
57aa d52a 09b9 e496 4b7e
40aa 7249 1517
5f74 c027 ecb8 2a3f 20bf
2915 fc66 25ac
2f5c 71a9 6a5b d3dd f35e
cfeb 9ef9 e7bf
bffe 0670 0b0f 54dc d110
c292 8604 922a
bed0 e047 6a18 cb58 51b1
aa41 c5dd 61a4
b1a2 6114 6b72 9952 b1ae
4197 76c3 b742
0cff 32bf be5f 4e4f 4f55 7ca9
607c 6bf5
dbdd 07b9 9df5 af77 731b
bb85 9d9c 0225
a360 245d b16b aeb0 dda2
b0ea 8682 40d2
b44d 37a5 c037 172d 2af0
a72b 657a c7b2
a66d 6cd7 9fec 194e 41ec
59f4 84b2 9592
b08a c231 e5ba e5f4 bb07
664d c16c b62c
f6f7 0d27 6eda aee1 d8c2
8aaf 79eb 74c5
b28c 926b 9231 a140 af3a
46cd fcd9 2867
cd9a ab60 722e 13cd 3e12
3f88 78dd 35ad
b874 32c9 2f33 5865 de15
a5c7 5ba2 da22
0ae6 cd7d 5bb8 7587 ffe7
9385 a5e6 464b
d8fb f1dc de23 7224 52fd
70c9 4221 9122
e6c8 81a8 add5 ab96 5912
ae51 93cc bdbc
d1ef c86c 7965 8df7 d734
286a 79c3 95a2
b443 7430 12ee 16e5 b07a
26cc 646f 2931
59c8 6c37 40f2 9c53 2454
dc23 6e6f 8572
bf2c 3262 1b3f de13 b503
eede 31dd 83f5
9faa dc65 94f3 9e68 e16e
095a 7952 79a3
2b6f e16d 046c ed3e d370
86c4 9c89 c746
5906 d898 7efa 2bbd 1de8
c826 c276 72f3
1cd6 e2db b4b2 0328 59d8
4c14 8a5e 4997
287d a96e b1a7 194e b029
acb4 a88a 92e9
1eb2 9744 e0ac 6bf9 4add
2919 1ba6 6c49
b86f 26e7 2587 8289 7601
19ce 2f73 7484
7151 4546 c77d 6cb2 99ed
5a56 1d47 1cca
86c8 94ac 8a2d 1def 62fb
0ca3 5338 9990
6333 757c 8645 0517 df70
1e05 d7fe f7ee
7028 7b35 e250 778d 9282
a9f6 ba6b 6bd0
7852 750f 9b57 2e34 77de
8da3 56bc f8a3
dd01 ef3d a084 973b 27b1
0d9c 8816 b1c0
9728 c477 8753 8949 5ca0
9de2 6a00 6308
f04b 05e9 b944 4f9c 56a1
1d8c 9d60 e099
9772 99df 80e7 7c8f 9bc1
57cc 4bc0 34ae
d006 7115 ef30 4b6e cec2
e7c5 2622 7f40
7d0e dff1 4bf8 1f46 4e30
784c a7cf 031a
a505 6ef2 b9fc 0843 646b
034e b039 1768
67bc 5c65 08d7 3cf6 eb64
9825 7393 e177
8606 6863 b117 08f0 b21f
61d0 d778 09f5
21cb 1dca 369d 375e 20a8
e04f a8fe a7f0
fb1a f2b1 f5a8 43b4 c022
34dc 26e5 1d0a
b0e4 d187 9b88 781f 1fd0
4ef1 f721 e658
52b4 2b16 7b1d bbc1 982c
7218 3efd 5f4c
abb8 b9a2 b48a 9567 9ae7
a99a c52e b6e4
d065 8191 e7d0 4e30 7cdc
23e9 dd0e 0574
7cec 29d0 c45a 20d6 2d7c
d28f a5b7 b046
7ab1 eebf 11eb 531e 9a93
ddea f12e 3d32
673a 1238 821a f17f df88
84c6 8ea0 477e
0d8d dbfa de6f 8dd0 44e3
75c3 c2ec 34b0
cd6f 8e9d f88a 03f3 0d41
763a a8a6 5b54
339e d203 c151 7a6f 7bb4
9fbf 0250 4b07
08c6 1067 7faa 0300 0031
0700 0050 4b03
0414 0008 0008 006d 572d
4900 0000 0000
0000 0000 0000 0026 0000
0064 6167 6765
722f 696e 7465 726e 616c
2f4d 656d 6265
7273 496e 6a65 6374 6f72
732e 636c 6173
7395 545d 4f13 4114 3dd3
16fa c162 1168
c50a 8808 b51f 42a5 020f
9634 1a84 a449
5d4c daf0 e6c3 763b 2983
cb2c d96e 4dfc
57ea 8b1f 0fc6 677f 94f1
ee74 2bf6 636d
6cd2 999d 7bef 39e7 ce99
d9fd f9eb db77
0065 1cce 2182 4771 c490
4b20 8f42 14c5
04a2 781c c54e 14bb 5194
1896 74fb ecfa
15bf 6a71 a75b 9397 dc74
6d87 41ab 49c9
9d63 cbe8 7679 9761 5ea8
8c5f c650 cdd5
db46 a7c3 9dd2 08b2 52bf
34de 1925 cb90
9dd2 59cb 8b55 f2e3 2186
c8b1 dde6 0cc9
ba90 5cef 7914 4da3 6551
64b1 6e9b 8675
6e38 c25b fbc1 e4d5 687f
2b41 fa0c 3121
bbae 214d 4536 413a 3dac
f0fe 7aa0 b216
c079 d46c 56aa 040c d3cc
106f 888e 34dc
9e43 88ca 51f3 d9b8 44a0
397d 221a f28a
2922 c979 864c 2e1f bc99
8300 8520 c8a0
57ad cd2d de31 5c21 3b4d
9ba1 1c78 5eff
d08e f91c b4d1 f520 b91d
5faf f19f 4ef4
71d3 7631 7b24 a470 ab64
7d2e 7f4e 86b9
1782 2edf e600 25a4 cb1d
6958 a3f0 2e41
130d bbe7 98fc 5478 279b
1a2d d8f5 5ad5
3087 271a f650 8ee2 a986
7d1c d0e5 98dc
9086 07d8 64d8 9826 ccb0
306a 02c3 fe34
d4d6 c457 3095 9bf0 2e91
0bb1 9ade 68be
d08f 4f18 0ea7 3a31 899a
dc59 1bc5 bd76
b869 cbb6 7085 2d69 179a
79c1 cdb7 baed
ea3d cb62 c84e 6a65 3c44
56ce d2d7 c5fb
4510 2777 3584 304f ab37
3487 688e 178a
5fc1 4228 7ea0 4518 b768
4ca8 c436 c1b2
48d2 53ba 5f88 05dc 5644
712c 6209 0ccb
43b9 d49f 5c9a 7277 e839
8415 5adf 45c6
975c a5b8 6ae4 1342 9e1a
536a b32a bae7
23ee 1162 156b 3ee2 25e5
bc6c acf0 05e1
1f88 dcf4 d847 9daa feb4
7e0d d655 7fcb
4391 fb34 f799 37e8 4f37
8632 1e73 c967
9e29 7cc6 cc47 5570 435b
fb8b 7606 0fb1
a5f2 db6a cc92 3d9e 4574
e854 1d7f 9ef9
0d50 4b07 0811 b043 bc60
0200 00d9 0500
0050 4b03 0414 0008 0008
006d 572d 4900
0000 0000 0000 0000 0000
0025 0000 0064
6167 6765 722f 696e 7465
726e 616c 2f47
7774 496e 636f 6d70 6174
6962 6c65 2e63
6c61 7373 3bf5 6fd7 3e06
0606 2306 4e76
0636 7606 7676 060e 4606
aee0 fcd2 a2e4
54b7 cc9c 5446 0611 f7f2
12cf bce4 fcdc
82c4 92cc a49c 54bd acc4
b244 4606 f994
c4f4 f4d4 22fd ccbc 92d4
a2bc c41c 7d34
658c 0c02 2085 fa39 8979
e9fa fe49 59a9
c925 404d 08a1 c4bc bcfc
12a0 d2fc 3c7d
4738 538d 9181 9181 0988
9919 4080 9181
0548 3231 b002 0050 4b07
0876 1346 0883
0000 00a6 0000 0050 4b03
0414 0008 0008
006d 572d 4900 0000 0000
0000 0000 0000
0020 0000 0064 6167 6765
722f 696e 7465
726e 616c 2f4d 6170 4661
6374 6f72 792e
636c 6173 739d 566b 531b
5518 7e0e b92c
4996 5b80 2015 9502 d690
14d2 8b6d 6913
514a c146 02ad 0483 add7
4d72 9a2c 2cbb
cc66 53a9 ffc4 5fe0 579d
b1b6 d199 8e9f
fde8 477f 8a33 5ede 7372
5d92 30ad c370
de73 deeb f35e cec9 fefe
cf2f 2f00 5cc1
6110 1348 05f1 1e56 03f0
e3fd 10c6 f081
8235 05b7 8374 5e0f c187
3b41 6c60 53ec
3e0c e12e d221 7c84 2db1
6414 6c87 308c
1db1 dc53 705f e87c 2cec
7615 6415 ec31
8c14 2cd3 b1f5 7cd5 d1cd
d2b6 764c 9ccc
81f6 584b 10c3 4810 23c9
10c8 ea25 5373
aa36 67b8 e496 a6f6 b692
9273 92d0 cd03
5e70 12f7 6deb b15e e476
6a2f 975c a53f
067f 4a37 7567 9521 1c3d
e57a 31c7 e05d
b78a 5c44 d54d be53 3dca
737b 4fcb 1bc4
0967 ac82 66e4 345b 17e7
06d3 eb94 f50a
c34c a6a8 954a dca6 a00e
b74d 4dba dbd4
0a8e 653f a188 9e23 9148
c4ed e0c9 71d3
c9c2 19d6 2221 899c e16a
f455 7315 f9f8
0b36 d71c 8a72 2dda 5b39
b978 36f8 3081
6fea 36b8 0c53 7d7c 31a4
fb40 7a55 ec22
e3ef 525b b7ea 7686 6696
12f7 f242 3399
ebc1 5bed 93dc ff08 7b56
393a bae1 2971
8761 2cba d835 9e3e 4e13
4c35 f26d d4a9
9a36 4d6e af1b 5aa5 c269
5626 dd06 0b52
4b8c a5cd 2b55 837c 5eef
a5f0 3283 3dd5
9d6c 03ec 50d6 d10a 87c4
9313 27af eb27
0cd3 a7c1 7758 4c34 659d
5566 305f be23
ddac aec2 36ab da07 85c0
11cc 5a55 bbc0
3775 7151 46da 9d58 1626
2ace 21a7 605f
c5a7 78a0 2282 2915 71ac
50be 2e87 0ce7
fab7 54f8 785d c543 7ca6
e073 155f e04b
155f e16b 05e4 3d8f 0215
4a45 115c c523
e178 bc47 6b54 94b0 a2a2
2ce4 933d 5ba4
42c7 8180 7691 61f4 7459
a86f 7dea 4277
af1d 2e4d 328d b834 7951
71af 27db a275
cb30 c891 6e99 345e 2355
f3c8 2aea 8fe4
2323 939f ed7a e6ba 46d6
5bd1 bfe5 d273
9ae1 fc69 3877 e4d9 1565
d6e4 dfd0 0b79
c88b 77b5 4a99 9cec eb4e
79e3 e498 1478
312b 9dcd 44d3 9d81 5cda
1472 50de 926c
f725 2256 d2d5 41a9 33a8
b7f2 8fb8 d49b
7521 1ba5 ac55 76f8 8923
1379 4859 99f2
e0a7 9bba c5a9 9a83 b4c9
6946 5564 7a5c
25c9 4ab4 c790 7671 7a5c
045c a6df ac09
5017 e83f 2c06 8fe8 6bf4
0339 8069 7869
a599 a275 8638 9ce8 00d1
a1d8 33b0 58fc
3906 9ec2 f323 313c 7883
d661 a2c0 db64
7401 2ade c19b 748a d40d
f016 6601 b93b
2f03 ccb9 64f3 2dd9 742b
f802 02e4 eb42
2374 897c 0bed f158 0d5e
86df e0cb fc0a
ff83 f833 283f b400 04a5
ca12 d1e5 8ee0
e304 252a a581 aee0 42b6
d892 b583 c768
4723 de08 fe27 f9f7 12dd
8dfd 044f 0d83
0ccf 11c8 d40f 4186 1a42
0cdb 176b 50e9
9947 9c36 4302 e1f0 4e7c
a986 1106 5a47
0563 4c42 af21 ecc1 fef7 fffe
21ea 27b0
7b25 f608 7d3e 0037 a808
2b48 e026 7d61
dcc2 3692 328f 598a 9fa0
2e2c e192 2cf1
6ea3 9c43 f46d 72b9 9551
5beb 4a4b 6bbe
a575 95b4 de95 4d1a f81b
330a ae29 b8fe
17f9 abe7 7b63 744d bc36
a423 f25d 23ca
88fa 623f 63bc 5d5e bf64
ce49 486a 5da1
0164 cec5 9997 1675 c737
290d 4193 044d
9499 1100 1f96 fd81 ff00
504b 0708 f24b
808a 1504 0000 8609 0000
504b 0304 1400
0800 0800 6d57 2d49 0000
0000 0000 0000
0000 0000 2500 0000 6461
6767 6572 2f69
6e74 6572 6e61 6c2f 4465
6c65 6761 7465
4661 6374 6f72 792e 636c
6173 7385 525b
6f12 4114 fe86 db16 d896
5a29 0856 1154
caa5 4af4 d112 9246 2531
c14b 0269 e2e3
b08c ebd6 ed2e d90e 4dfb
2bfc 2b36 d134
6aa2 6f9a f8a3 8c67 9605
0b94 f461 e6cc
9c73 e6bb 9ccc 9fbf df7e
0078 8c9d 04e2
28c5 b182 bb1a ee25 1046
2989 fb28 6bd8
4e20 8692 868a 86aa 861a
c3ca 40d8 c2e4
5230 643b 07fc 989f 342c
e740 18b2 f1c6
738f ad81 f076 19e2 5dcb
74b8 1c79 d4b5
7579 57b3 d7db 6d51 6bac
6939 966c 3184
2bd5 7d86 c853 7740 8f52
1dcb 11af 4687
7de1 f578 dfa6 cc46 c735
b8bd cf3d 4bdd
8364 44be b78e 188a 9d01
374d e111 8714
9ec3 edc6 b340 649b 1bd2
f54e 8927 33fb
fe74 38c1 285f f578 a234
6c0a c990 ae54
7d43 0d9b 3b66 e375 5f99
a2e2 6a57 72e3
c34b 3e0c 50a3 952a 3da3
f623 2127 7883
8977 867c 65c9 ecd4 0c0a
4b8a 6321 aaa3
ddec 3d59 54d1 5a4c 2d78
9bf3 94e8 ba23
cf10 6d4b 694e cf19 7fa8
e074 a4b0 ae23
099d 84fd c77f 61ab 569b
5c4b f1fc c410
4369 b98e 86ba 8e1b c831
9416 3af7 3c73
7428 1c39 6d26 b82b 06cf
b03e 6f88 3edd
1247 0c9b 970e 0d8f e857
c741 5669 8594
0f8a abf4 eb43 58a3 7fce
943d daaf 5166
8f22 a318 ad9d 839d d121
8c0d da63 7e32
8feb b4eb e306 a4b1 4931
3393 c952 64ca
3e41 2bb8 7714 552d 57fb
8cd0 6f24 bf23
fcf6 1c91 9fea fa15 5186
4f54 8cf8 144a
0950 8086 3ba4 a774 812a
b740 950b a8f2
be40 960a ccdc a4e2 166e
05dc 1f29 8628
16eb 3e71 8c88 359f f8d7
051d f52f 089d
4d35 e4c9 2850 a6db 3631
5549 438d 4077
48d1 035f 4f66 0c18 e851
a7f1 2c33 33b5
ecb4 b646 b5bc 8f1e d2d7
0291 b769 8d4f
05c2 55b1 f80f 504b 0708
3aae 138a 3902
0000 8404 0000 504b 0304
1400 0800 0800
6d57 2d49 0000 0000 0000
0000 0000 0000
2800 0000 6461 6767 6572
2f69 6e74 6572
6e61 6c2f 4d61 7050 726f
7669 6465 7246
6163 746f 7279 2e63 6c61
7373 9555 eb4e
1341 14fe a6b7 6d6b 9582
828a a8c8 cd52
9452 4445 a828 5650 1495
44d2 c8cf 6d59
eb9a 6597 6cb7 067c 015f
07bc 6134 f101
7c28 e337 bb4b ed05 e3d2
a43b 3367 cef9
ce39 df39 33f3 ebf7 f79f
00a6 f138 8904
6e2a b895 4408 b713 5ccc
2671 0277 9298
c3bc 5c16 a4c2 5d05 0b52
724f c17d 058b
0a1e 08a4 564c 53b3 8b86
5aab 6935 01e5
415d 3736 355b 20ba f46c
6d7d 4360 6475
53ad 5635 3ba7 9b8e 669b
aa91 7ba6 6eaf
d9d6 3b9d 6acb 6ac5 b1ec
dd79 81c4 4bbd
6aaa 4edd d604 9e04 3029
acbe 55df a939
4335 abb9 17e5 b75a c599
ef94 2c10 b8ab
6299 8ead 97eb 8e6e 5689
4389 a748 810b
4c9d a956 4961 fda9 07b6
c308 2450 eed0
7961 bd44 5009 ab94 0f13
cd65 56c6 0304
3ce2 3343 db48 d1da d464
1cba a93d af6f
9535 7b5d 2d1b 94f4 ac5a
15d5 28a9 b62e
d7be 3052 d3df 7310 2b02
6ae1 e95c 6796
a523 640b c70b 4a66 eca6
c6ba 695b dbce
aec0 5826 0800 0d5e 1d23
a820 904d b1c4
0aba a93b 0b24 26d3 56b3
f112 8971 dee8
6cb9 be56 d276 b70f 89bb
763c 6737 32c7
ed02 1944 b8aa 3902 ddcc
acbd a9a6 db65
41da eacc a151 336f 02b3
edf9 07a9 6dde
0d30 b433 253f 7956 3498
9140 bc50 317c
e2c3 1989 f121 7889 8f38
96ed 5e5b 4f70
7076 243f c997 56dd ae68
cbba 2cf0 d9ce
f827 2542 0a43 1816 c806
ef7f 6951 4c21
8d6e 39cb 2b78 98c2 1296
5338 83de 1432
1817 18fa 3f5a 0a8f a466
ba9d 0246 fa0f
0e78 3d06 a909 73c9 ac04
2f79 ef5f 628b
9661 3002 dd32 7952 baea
e696 b5a9 bf76
0f8a 7b15 0e76 9cab 8e36
8ebb f701 e7c8
f309 3801 5ef9 7c23 fa25
579c f7f0 f908
e134 4732 d558 f741 a1ee
599c e3fc 3c25
3388 700f 48fe 4068 a35f
1c20 bce7 eaf5
f31b 7377 aee3 02bf 294f
0b03 b8c8 d1c3
ba44 a4cb 18f4 9106 5c0d
20f2 1111 8921
9a30 6efa 1657 f867 03f8
161a c710 c793
d903 44b3 13df 10fb 0265
9f82 b06b 7a8a
2330 cb00 efd0 fd9c 1b46
9f67 8011 a608
77e6 2537 dab2 37d6 d8eb
6b24 7e95 3376
8bef 7a91 2b19 5834 fb19
ca5e c3a5 176d
b129 e3a8 ef6a b445 32d6
e020 9b5e 24ec
0477 5a61 bf22 de0e 3b1c
0436 0d12 74cd
872b d181 e420 969d 3880
d83f 126f d0d3
6830 1263 c17a ddfd 1826
9123 c25f 1f31
3ff4 38a6 d832 9e8f 49d7
9e6c ff40 62e3
1b92 74f4 0991 fd46 01bd
2a8c b00a a32e
b761 3ff1 69dc 70c7 196a
4832 42dc e52f
1de7 2c81 2e9c ff03 504b
0708 a0a4 4ef7
3c03 0000 c208 0000 504b
0304 1400 0800
0800 6d57 2d49 0000 0000
0000 0000 0000
0000 2800 0000 6461 6767
6572 2f69 6e74
6572 6e61 6c2f 5365 7446
6163 746f 7279
2442 7569 6c64 6572 2e63
6c61 7373 9555
6d77 1257 107e 2e01 9690
252f c490 5795
681a 09d4 90a4 d6b6 42a2
1192 06c5 4485
4693 b6d6 05f6 90b5 db85
2e8b 47fb b17f
a19f ea1f e8d7 6a5f 62eb
39fa b1e7 f447
f574 ee65 8184 158c 8773
eede b933 f3cc
3373 e70e fffe f7f7 6b00
2b28 fa31 8c75
3f46 70dd 8f14 d2fd 246e
f065 932f 9f4b
d8f2 21e3 8784 1b03 b889
2cb7 b9e5 c3b6
841d 3f02 b8ed c71d dc95
9093 9067 18d5
8c92 f658 2bd5 15fd b659
a18d 6ad6 1886
b38f 94c7 4abc 6e69 7a3c
abd5 ac04 437f
4e2b 1b8a 5537 5586 c50e
7552 c84f e29a
f148 2d5a f126 5032 9f4f
acd1 8fa2 142b
ba4e 2aad 621c 89b2 7942
9823 66a9 164e
135c c0cf 29b5 9a6a f2e3
5a5a ab29 055d
2d31 b07d 066f 5233 346b
8dc1 13c9 6416
7619 dca9 4a89 3218 ca6a
86ba 5dff aea0
9a79 6ece 10cc 568a 8abe
ab98 1a97 ed43
b775 a011 51e9 7a5d d389
0983 9c31 0cd5
4ce9 3c1e 29e6 b225 a55c
564d a26c a9a6
a1e8 f19c 6a6d 2a45 ab62
3e9d b39d 885f
c859 e49c f603 e1b3 0c29
9db5 6928 43c7
193d ad36 592d 9c20 6aa3
3c0c 034a a9d4
8465 588d bcbd c489 9340
125a d099 08c3
7817 4c86 d35d 2e34 6693
0be4 2ca5 f8ed
2da5 6a27 b6d5 859e edf0
3e79 8f51 de29
4761 2903 67b5 192e 770b
fbf6 ce8b b5fa
5ae9 4ab8 b7e7 fb64 e229
7099 e14c a497
1719 9eef 69d0 8093 f005
37cc 647a 1158
4ef0 97e2 7ab2 c497 65be
ac50 f8de 1e0c
be64 51b7 1f5b 5f84 0344
92f9 2b8d 32e8
8a51 8eef 1478 8912 6bce
2306 7fae 5237
8bea a6c6 bb60 a80d bcc8
6d65 4c61 9a2f
ab12 7665 dcc3 7d19 418c
ca08 f165 0293
0c13 6dcc f5e6 24d8 30cd
0add ed0c 7ff0
65d5 08ab 5cbe 1ade aeeb
7ab8 6adf 1347
dd93 b02f e34b 7c25 e36b
3c60 8877 3884
d3f5 aaae 1515 4bad 8535
236c 1da8 2df7
b04e 538b 61aa 7b65 7880
6f24 3c94 a1a0
c070 eedd d74e c3b7 b340
9444 afda 33cc
76aa d342 6e37 1e8d 2ab9
6aaa 359a 2ba5
ace0 3c1a c92c 3887 fc58
c479 3bfc 2a07
8f5b d20d d3f3 ea62 4e53
3770 a0d4 da55
e3c1 3a43 71ab 75c7 a943
7e67 930e b5e3
8ba1 4c53 b344 699a 6aa9
d507 3463 ac7a
4d34 e53e 96e9 0f72 84fe
44fb a883 a887
c070 8a24 17c6 480a 1d91
c787 2778 67d1
de4b 12f5 1f69 6648 fa9e
a43e fa8e 450f
e18a 4ebf 44df 1f70 4767
c4d7 f35c 009f
a635 0837 ad5b b466 20e3
0681 dec4 193a
0937 9c71 16e7 00b1 3b8f
3982 e6bb 0f68
e7c2 3ced 65fb e42c 2ed0
971e 1216 48c3
c3ff 48fe 2efa cebe 80f7
1946 62ff 20f0
0ad2 5ed0 7788 fe37 d1df
e18e fd05 bf0b
f7a2 bf92 915b 5019 1421
7788 c21d 02bc
2b68 841a 202d 1ab3 8822
4681 e68f e92e
b474 1f92 eea2 488e 9db2
0bb4 4847 f113
f3f2 74e3 759f e0f6 28d6
7e17 5e4b 3d78
2dd1 6d3a 78ad d0d1 47b8
64f3 fa09 1e51
cb0d c16b 9c57 e825 067e
b6d9 c99c 5d4b
e3e9 d4bc 4260 8f7b 701d
3bc4 6027 f707
d417 0f29 5451 706f 5cda
86cd 7dfe d809
677c 5178 bba6 266d a21f
0f83 fc3f b1fb
4a21 44de 3252 747a e610
acdd 495e 0192
1621 a20d 9356 7924 7c6a
778f 84cf 44f7
f0dd 1524 c8b7 4d40 b209
f890 c4aa 1dee
92d0 0023 c1c0 9f18 7a06
c9fd 0bdc 7dbf
c1fb 5c70 3b1a 98f3 f6c0
255f a317 6453
5fc3 55f1 bd46 97c0 7bdd
458f 2a40 bd3d
89cb 02d5 f73f 504b 0708
9e2b ca13 5804
0000 aa0a 0000 504b 0304
1400 0800 0800
6d57 2d49 0000 0000 0000
0000 0000 0000
2100 0000 6461 6767 6572
2f69 6e74 6572
6e61 6c2f 5369 6e67 6c65
4368 6563 6b2e
636c 6173 7385 55db 5213
4110 3d93 8b4b
360b 41c0 8002 a280 1816
25de 6fc4 c855
4d55 8c94 44aa e06d d98c
6175 dda5 361b
4bfd 0bdf 940f d057 efa8
5479 79b2 ca6f
b2d4 9e49 c235 c197 9e9d
3ed3 dda7 fb4c
26bf fe7c f90a e00c 322a
6238 1341 0467
8539 27cc 7905 1754 842b
ee8b 5168 b8a4
e0b2 822b 2ac6 9052 7055
257f 5ac5 358c
2b98 5030 c9d0 7c37 97c9
65f2 9989 6c66
7166 9aa1 2d7b df78 6424
6dc3 2926 6f2f
dde7 a63f c6d0 b4e2 b98f
ac02 f718 3a25
fe38 6939 024b ce56 013a
1499 b38a 8ee1
973d ced0 53ff 542a 9f1f
4b8b 7c96 53f2
0dc7 a493 ed83 46a9 c43d
df72 9dd2 b455
3296 6c5e 6060 8b0c fb52
9663 f969 8643
8906 3587 e719 4253 6e81
d2c4 b296 c373
e587 4bdc cb8b 1ca2 11d7
34ec 79c3 b3c4
beea 0cf9 cb56 89a1 375b
308a 45ee 5146
9f7b 8e61 27e7 2ca7 68f3
a965 6e3e 207e
f1ed b14f 566a f1fd 7b05
d6ba 6b9e f30d
f3c1 2d63 4506 4901 ae32
f435 e8a2 1225
5a09 16b9 cfd0 9118 ae27
c1fe 9a04 77f8
3dee 7139 bb70 6298 8219
4e35 1c50 43b1
6653 f92b bbcb a4f7 e6f8
1f51 53a6 5d55
2c98 10fd ccd7 afb1 dbb5
57de dac0 b3c6
d327 b54a ea9c 5bf6 4c7e
dd12 92b4 6e51
6054 24d2 7008 a31a f6a3
4d43 a730 5d38
c8d0 b559 75a2 76e1 663c
cff5 34b4 a343
c371 2418 baf7 50b7 0e3a
ed96 97aa a882
290d d398 6138 50b7 1941
aa5b c175 0d37
7093 48ef 9c01 4374 4ba3
7443 77d6 9af5
b8e9 3a05 4bfe 5018 3453
54cd b97e ae6c
db0c 4389 dd53 ad7b 8d62
9bbe 299b 7e79
74d7 0bbc 6479 bcb0 3115
babd 7eb9 2445
5cc4 697a 3062 08d0 4bd2
8a10 f540 53a5
d767 52cc 0cd4 2b7d 0710
a77d a7f0 b776
8959 932f 445e ea97 6c0f
ed9e d31a a075
405f 03d3 df22 f001 c1b7
08ad 2236 f213
d175 8417 d6b0 ef9b 3ef2
01ca 1b19 dc4b
364e cf18 d04f bb23 8862
807c 83b4 3b86
c312 93e9 d047 18e4 5785
ced1 6d58 ff06
1627 6c80 be63 607f 2951
40c1 a042 a950
e53f 4430 c95f 65fb 6c83
ed7b 2859 32c4
35f0 126d fac8 6734 3110
779d 1153 01bc
dec1 7694 6c92 aa9c a221
9c25 a6e7 ebb0
0d93 6fb8 01db 0a56 63db
04f6 1b87 05d1
0a4d 9da4 68c7 4895 e643
04e9 1cd0 a7ff
4064 152a 2dea 0b84 f5d7
eb88 2ce8 9f10
fd0e 6d0d cd9b 145b 2800
f437 d082 1469
9996 d4b4 4a0a 393e 4842
9b9e b824 26b5
6ca9 297d 8248 9da4 3699
a430 29c9 03dd
6d91 8f68 5985 127a 8550
f01d 42eb 8891
a4ec 1d02 6f64 9828 afca
c33d 54ba 57a6
0d23 a08d 3372 5632 2769
6862 3dfd 0f50
4b07 08cb cfd5 135a 0300
00e0 0600 0050
4b03 0414 0008 0008 006d
572d 4900 0000
0000 0000 0000 0000 0030
0000 0064 6167
6765 722f 696e 7465 726e
616c 2f4d 6170
5072 6f76 6964 6572 4661
6374 6f72 7924
4275 696c 6465 722e 636c
6173 7395 566d
4f13 5914 7e6e 5b3a 30db
22a2 c22a 8885
451d 0a52 f15d dac5 5d11
d64a 0593 6289
51a3 433b 9691 71a6 994e
11fc 497e d2c4
5d36 9aec 7e34 d91f 65f6
b9d3 6929 54b4
86e4 de39 e79e f33c e7ed
def2 df97 8fff
00b8 849c 8a18 aea8 88e3
aa8a 6bb8 de43
f186 829b 2aba 30ab 20dd
8d8c 0a05 bf76
634e c52d fca6 e077 05b7
05d4 577a e576
cdb4 4a86 2b70 32f7 52df
d253 35cf b452
39d3 de34 4a77 f5ea c67d
bd92 16e8 c99b
655b f76a ae21 307b 985d
6675 29ed 9f6d
a74c fba5 51f4 520f 5c67
cb24 7866 b590
9ee3 9f40 3463 daa6 3727
10d1 b213 056e
f34e 8998 4708 642c d75e
ad1b eeaa be6e
51d3 9f73 8aba 55d0 5d53
ca81 32e2 6d98
5501 a519 732c 6bdb 863b
6fe9 d5aa c183
a95c 492f 970d 97fc 9ee1
daba 9562 588d
2016 f5a2 e7b8 3be3 8133
8389 54cd 3744
1559 8181 fd74 3b95 06e5
951f 8094 05f0
3315 e85a 972a 8173 da44
0700 7498 eec8
b085 215c a979 026b 5abd
1b96 6e97 532b
ebb2 ea87 f420 dd09 7e4b
71c2 9bc6 8e6c
431b 3cbb 5509 bc56 5e14
74ab c62a 0d1e
c249 1846 2c30 fcad b910
88e7 3dbd b8c9
7082 a23f d4be 334a 3f92
4bb3 660a e605
925a b613 df99 b49c ced0
f645 b9cc b08f
9d39 0964 324b b3ed 352b
7c45 37f7 b5d2
aa79 a7e6 168d 4553 9661
b09d 635a fac4
d08f 6372 b9a3 6021 8645
fc11 432f 8e08
8c7d 3f48 e976 5760 648f
7bb9 6659 0f1c
df65 61bb 6854 3cd3 b1d9
e3d5 0d23 c111
4898 d584 4d0b e9c7 7b32
2ad5 8df6 279c
1709 8ff2 961c 8286 a182
7b31 8c61 89a5
eebc 4702 7d07 8b21 30de
49c9 3961 9a6c
d5e8 41e3 3bbe 3cef 5816
c198 129f 8784
6dbc def7 62ad 99de c6c2
7685 0646 29ef
bf05 c37c 96be f10e ded0
5a0e a5aa f359
3ad1 7a53 f39e 6bda 655f
3f78 08db 1e59
dbdd dea7 9968 5761 86ef
7f9c bf0c bcbf
7230 b8f7 510a e128 225c
393c d41c a7e6
31a5 10f7 7872 17a1 e4d0
df08 ff89 c87b
2ac2 38c1 b597 3b90 a3d3
3201 5730 4069
a0ee 8041 9c02 fcaf 210c
13ee 34bf 63dc
eb67 233e f919 2468 2d89
b2c4 f0cf 3ea1
eb51 f203 2262 17d1 774d
a2a8 7ff8 d027
d803 9104 edb0 f54c 46a9
1bc3 2f01 fc5b
e2c8 50b5 c9cf 9242 79d4
dfbd 8b9e 7fa7
1a92 2a25 493b 39f5 177e
5a4b 4ae6 88cf
7c8a dcc0 134a 4f99 ee33
d6e6 39d3 29e2
1c4a 7e34 893a 6e33 5d0d
e338 ebc7 a3d1
e63c f94f efb3 1a69 5a69
4dab 095a 257d
c650 6f3c 887f 925b 3f2e
047d 2850 2311
a2c9 a15d 88f7 07ea 926d
8924 da8c 248a
69bf f0f2 2b85 8b41 24b1
4053 8f24 1cb0
cdf0 7f04 b95f c649 48de
10ed baf0 33a5
2909 d5d7 fd3f 504b 0708
afd7 a3c4 7903
0000 4a08 0000 504b 0304
1400 0800 0800
6d57 2d49 0000 0000 0000
0000 0000 0000
2100 0000 6461 6767 6572
2f69 6e74 6572
6e61 6c2f 446f 7562 6c65
4368 6563 6b2e
636c 6173 739d 565b 5713
5714 fe0e 094c
0883 d020 17b9 68bc 5421
0163 bdb4 0a88
cac5 1a1b 2396 8845 7b71
488e 6170 3a49
2713 d43e f657 54df d557
2f15 dbb2 56b5
f5a1 6bf5 27f9 60fb 9d99
9020 061e ba96
9ecb defb ecfd ed6f ef3d
e19f 77bf ff01
e028 96c2 e8c1 5433 3a30
ad96 19b5 9cd7
f079 188d bef8 420b ba90
d470 51c3 1761
8431 1542 4aed 97d4 920e
e1b2 da67 c368
c695 30be c49c 864c 98cf
ae6a 98d7 702d
8caf b0a0 e1ba 40eb d574
329d cc24 cfa5
92d7 67a6 0522 a965 63c5
4858 869d 4f5c
5e5c 9659 774c 2054 740a
2b66 4e3a 02dd
9efe 6ec2 b495 2e31 5b51
d0a8 79ce ccdb
865b 76a4 407f 7dab f14c
666c 42f9 33ed
926b d859 5a76 1c30 4a25
e9b8 66c1 2e4d
9b25 63d1 9239 0141 644d
e3a6 6dba 1302
bd83 5bc4 1c9a 1708 4e15
7274 d396 326d
992e 7fbf 289d 8cf2 a112
2964 0d6b de70
4c75 af08 83ee 9259 1218
48e5 8c7c 5e3a
f4e8 4ac7 36ac c474 a14c
83a9 2599 bd4d
7c5d efbf bd57 5c7f bf6f
bb87 ebd9 b5ce
b946 f6f6 25a3 e83d 22f1
245c 60cf 1659
f8af 542a 81bc 7405 760e
0ed5 2b41 5bb6
ec38 d276 9355 e69a 1c59
2a5b 2eab a8e1
8640 e3e0 103d 091c d992
ad2d 2b17 ca49
4be6 0d97 4e67 c733 a31f
869f d81e fbf6
c50e 5ac6 8ff7 040e 6e8d
abc2 698a 768a
be4d f7c8 c6fb bad3 f3ff
0b67 1d47 a1f1
ac55 e9b3 c0a0 aac2 7c7d
cf1f 8ab6 0b55
2f52 78ae 5076 b2f2 bca9
1aa9 7d43 df1c
568e 74ec c319 1dbb d0ab
638f 5aa2 d82b
d053 8b7a 6e7d 4c66 1ca7
e0e8 e843 bf8e
048e b0b3 6a46 494b 15d2
6203 ba72 e66e
5616 d503 0e6d cd62 ce75
4c3b 3f59 362d
6f9c 67e6 b285 a2cc 45d7
073c 7ac7 2845
4d7b a570 9b42 47b2 e94a
e68a b4ee f1cc
c9b6 f934 9a33 6fdd 92aa
15a3 7e03 9646
a33a bec6 376a f996 2c46
0ff2 fe1d 6eaa
8c0c 0d8b 3ab2 e048 f76d
3339 ca74 bf40
cb06 d604 3aeb f2ab 41ea
b885 3c29 dc5c
117e 4c6a a2cc 9253 b8e3
0f6d 9351 2c4a
9b10 4606 539b 8918 1bfa
4054 e166 6c93
7da5 eadb d987 dc82 2fda
3cc5 9558 cca9
1e02 36dd c066 7266 c97d
c1ce 99de 7751
40cf 2a9a d205 375d b6ac
ea2c 6d09 acf6
d5a8 c9a6 2c7e 68f9 69cb
c992 e9c8 5cb5
9d54 af94 4b5e f75f c727
fc89 e841 037f
5a3a 1144 af6a 47fe 1c4d
aa66 0351 f2dc
80dd bcef 51f2 f61e d5a4
9435 52ca 0272
3dc0 dbcf dc1b b8ef 8fbd
8488 3d43 c30b
049e 21f8 006d f1bf d1b2
86c6 8597 687a
158b bf80 f694 6641 7ccc
b58b 4e40 2741
ba6c a1ab 01ba da47 cd41
4fe7 b9c3 210c
02de c987 33f4 9e2e 56d5
eda6 2ece 731b
c4bf 74d4 a061 58c3 0805
3efe c354 736e
7cb4 622f 43aa d0a5 d82f
08a4 e284 fb08
4bb1 854b 7f6d b8a7 78d6
7e43 4878 a740
7a84 d287 181e 893f c4a1
3534 2fac 21cc
9c5a 22fa 2a5a 4756 b123
d2c6 439c 8755
b4bf c447 5eae 8198 60c2
c36f 1e23 3c1a
1c7e b32b f82a fe84 10da
91c7 32c3 2fc3
f676 9f8d 4fd1 ca35 4660
71e8 18a6 d508
0b72 9859 27c8 c831 4a8f
e333 9cc0 0d9c
c44d 8c41 e234 7ec0 198f
ad28 02d4 8fb2
94bd 3c31 b10a 6f8d 8c70
9432 9f37 9dbb
af53 bc29 b67a 107c 871b
1a8e f9ff dea2
795a c3f1 b768 aad0 7682
7f4a f411 995f
e425 fa56 1eba 63bf 2272
2df6 273a eea3
31f6 640d 1d0b 2cfb ce27
d554 22dc 8169
869f 61d0 0bd8 818b 1e4c
1f40 37d3 e8e7
3ef4 9e64 7705 1243 eca8
443f c9e8 a798
951f fd27 aa54 dd07 18b8
f33e c2b1 d7e8
4cc5 fde8 c4f3 1a5d 7530
5c86 862b 8c72
8d18 16aa 8da5 f3ff 2952
28bc fee8 aba2
a9e9 c6ab ba3a b84e 2384
0932 2f3c 5c93
1e2a a02f d2b1 8aee 07d0
828f 110c 3c47
700d 3dec 10f1 1c0d 4fbd
670a 55d8 33ee
6771 073c af9c 22fd aca0
d0f7 7c16 e7bc
7df2 3f50 4b07 08a1 b6d4
3fee 0400 0014
0a00 0050 4b03 0414 0008
0008 006d 572d
4900 0000 0000 0000 0000
0000 0023 0000
0064 6167 6765 722f 696e
7465 726e 616c
2f50 7265 636f 6e64 6974
696f 6e73 2e63
6c61 7373 7d92 df4f 1341
10c7 bfdb 9fb4
5c2d 20e0 4f2a 4862 da92
7848 6262 94f0
62f4 a954 9236 4d88 4fdb
ed72 2c1c 7bcd
f66a e4bf d2a7 269a e8a3
897f 9471 7639
424b 4fef 6167 6776 bef3
d999 bddf 7fbe
fd00 b087 ed22 36ca 60a8
d9e5 4919 05d4
8ad8 2c62 8bc1 13a7 529c
b7a3 b83d 0e43
8667 f5d6 19ff c4fd 90eb c0ff
d03f 9322
7ed3 980f 31e4 de46 03c9
506d 292d dbe3
8bbe 345d de0f 29b2 d28a
040f 7bdc 28eb
27c1 9291 27d2 482d 5c42
4ab9 f559 d5e5
f05a 99ed 76e9 b8d2 89b9
383f e4c3 eb7a
1d15 681e 8f0d ed6b fbdd
d7f3 250f ea24
6c38 f1ab 949e a622 9dd8
281d a477 e949
6322 7328 4723 1edc ba7a
2263 d8fd 373f
85e2 6e54 d857 5ac5 07d4
5dbd d1a3 59c6
a76a 440f d31a f020 90c6
573a 9646 f3d0
3f32 5244 7aa0 6215 e911
e9ca 9d68 6c84
7caf dca0 674e 9f5b 140d
e386 681f f428
72b5 de7d 1672 68d3 3cdc
c37d bb3c 65d8
f82f 8d61 e976 4f0c 6bf5
948e 7a78 813c
fd52 f6cb a284 2216 9021
0b7c 24cb c8de
69fe c2e2 77b0 e309 323f
9b5f 2892 43d9
c629 1fd8 246f 0b1e b6b1
489e 77a5 205b
7176 3a52 25bb e428 ccc3
326d 3258 71c0
bb09 f084 8e32 64ab 04f4
2c70 6782 ec3c
d127 6f97 eaef 39e2 fa95
2421 dadd 2ad6
8879 c3ae ceb2 2b09 db0a
699c 9452 7245
994b ce37 27c8 7d75 0996
5870 c197 53bd
e5f1 000f c932 3c72 598f
ff02 504b 0708
2348 6b25 d801 0000 a703
0000 504b 0304
1400 0800 0800 6d57 2d49
0000 0000 0000
0000 0000 0000 2a00 0000
6461 6767 6572
2f69 6e74 6572 6e61 6c2f
4d61 7050 726f
7669 6465 7246 6163 746f
7279 2431 2e63
6c61 7373 858c 410a c230
1045 ff68 b5b5
0a76 e756 a46b 835e 412c
b810 054f 10db
a1a6 8444 d25a f06a 2e3c
8087 1253 5cba
7086 f9c3 87f7 ffeb fd78
0258 631c 220c
3122 c427 7b73 3967 4a33
61b6 97d7 a3b3
ad2a d865 326f acbb 2f2b
d94a c274 6b72
6d6b 65ca 3d37 175b 8488
0969 21cb 929d
50a6 6167 a416 bff1 7445
98ec 8c61 b7d1
b2ae b926 245d a3d0 d294
e270 ae38 6f08
8bff 45c9 1c84 1ebe d3f7
0bef 020c fc0f
30f4 1af9 8b3d 431d 9044
1f50 4b07 087b
4aae f7a7 0000 00ea 0000
0050 4b03 0414
0008 0008 006d 572d 4900
0000 0000 0000
0000 0000 0025 0000 0064
6167 6765 722f
696e 7465 726e 616c 2f49
6e73 7461 6e63
6546 6163 746f 7279 2e63
6c61 7373 8552
6b6b d350 187e 4e6f 59b3
ec62 6d3b af9b
ad73 261d 5af4 9b5a 0a22
0e84 3a85 96c2
3e9e 66a1 66c6 a464 a7e2
fed5 0465 e040
3f0a fe28 f149 1adb 75ed
28e1 e4bc b7f3
5c0e e7cf df1f 3f01 3c85
a5a1 a243 a0aa
e1be 8e34 b675 68a8 e619
3dd0 b0a3 e1a1
c092 eb1f 2be9 db8e 40a1
7524 3fcb ba27
fd7e fd5d efc8 b1d5 0b81
7cdb edfb 520d
430e a43b 1d56 7276 e848
c5f4 9139 7bc0
6a1d ca7e df09 ebae af9c
d097 5e7d 4fda
2a08 4f78 30f3 2a38 e4b1
b596 eb3b fbc3
4f3d 27ec c89e 1713 07b6
f4ba 3274 a33c
2996 a78b 2783 ff8d 95b6
92f6 c7b7 7290
e4cf 1a9d e7b3 429a 26c5
5ea9 a6c1 6633
f2d2 707d 5735 054a f3bc
74a9 597d 708f
052a 3340 6f92 6b9b d8db
5934 3326 8da5
113c dd77 9440 d1b4 e65d
7cd6 b4e2 ebde
9b6f 6fb6 b4c8 abde 0e86
21c5 b8d1 a515
2f69 7b1c c109 6c4e 50f7
879e f73e 88c1
5e7f b19d 8172 03df 4009
a6c0 d602 a3d1
58d9 401e bac0 fa65 9d02
1b57 08e5 8598
5617 4ff8 3c35 3eda 25ae
4204 c27d 99cf
3905 839d 3c56 b0ca 788d
951e 73c1 bd54
fb8d e573 8883 33a4 7e9d
237d 503b 43e6
948d 0cd6 f95f e518 5061
5625 c436 ae31
3346 0763 7890 e662 c5e0
7e9d 8be0 46c2
5ce4 a2a7 316f 8a1f a093
275b dbfd 8edc
d778 7c42 6691 ac46 a8dd
98ac 3c9a c606
6e00 7134 7255 98ea dd1c
f78c b1e3 5b8c
6ee3 4ec2 fb92 5924 325b
fb86 dce9 9832
1717 eb17 7c65 13aa c254
2522 18c1 dee5
1a45 9bd8 8af7 7bff 0050
4b07 08af cce0
d2fb 0100 0034 0400 0050
4b03 0414 0008
0008 006d 572d 4900 0000
0000 0000 0000
0000 003a 0000 0064 6167
6765 722f 696e
7465 726e 616c 2f4d 656d
6265 7273 496e
6a65 6374 6f72 7324 4e6f
4f70 4d65 6d62
6572 7349 6e6a 6563 746f
722e 636c 6173
739d 546b 4f13 4114 3dd3
2e6c bb2c 0fcb
4b5e 8a8a d882 52c0 f2b2
4d03 2198 d4d4
6252 c418 3f0d cb5a 0697
59b3 ddf2 bb04
1221 1a0d 9ffd 51c6 3bd3
aa50 1a4d ba4d
663a 73ce 3df7 dc3b b3fb
e3e7 97ef 0016
918b c340 cac2 0c66 4d24
4c3c b1d0 8539
35a4 2dcc 6321 866e 8b18
6945 5b34 f1d4
4486 2156 2895 7736 4a9b
5b0c fd25 7ffb
e34b f768 cf0d aa05 79e8
3aa1 1f30 d805
29dd 60d3 e3d5 aa5b 6558
2eee f34a c50d
d242 866e 20b9 976e 8aa8
4eb5 90c9 3298
53bb 1bc5 d75b 6586 9577
ed6a 741e 73af
a65c ac25 536d 8b18 9bfe
becb d05b 14d2
2dd5 14ba c3f7 3cda 31b5
faf6 7b86 17c9
e221 3fe6 698f cb4a ba1c
0642 56b2 a976
f325 8abe c3bd 5d1e 0895
a691 cb90 fcc8
55d8 8d3c 5465 4e48 11e6
1986 5ad8 28a4
7629 3a3c 10d4 8578 5954
240f 6b01 2945
930a e816 3a6f c304 c3e0
5585 ed3d 8565
152f 2664 35e4 d269 b2d0
6010 9e73 bc86
89f0 0abe 256b 47b9 f6fa
90cf fe8e 6b42
7237 f3e7 c981 55f6 6b81
e33e 17aa 5b83
cd29 e654 8c8d 5bea 9a27
6c2c 61d9 c40a
43a6 1d6b 3686 b16a 631c
1326 d66c 3c43
d646 37fa 187a ae17 4ee7
d1ba 0286 0ec7
f325 f91c 48a6 5a75 73f2
7fb6 1896 ae1e
947e d9b2 adae e075 4724
3dd1 2cfd 2a70
1d5f ee8b 50f8 9274 6de7
c075 3e94 fcb0
54f3 3c86 e956 f7e1 e6d6
fa3c 7d22 ba40
e188 ac8f a86e 007d a3aa
ddf4 a1e9 401c
fd18 2074 9056 f769 568f
750a f619 914b
443f d18a 7a45 63a7 c632
c41f c6ed 063f
8388 deb5 12c6 cc05 3a2e
6128 7ee4 1a7f
8446 bbce c228 c634 4ec7
43a3 5258 4094
7e80 3933 3b7e 8ece 937f
849b b8a3 ace3
aee6 4cd2 de3d 6d58 c9e4
698e a8a8 d90b
986f feaa 587a 7795 ca5c
d34a 4375 5643
49fd 7b80 298a 8de1 a156
545a 2bd4 2ef5
8c7d 85f1 3611 8b9e 237e
06cb f846 abe8
295d e533 b093 3f5d a927
58a2 ae66 a88e
bab5 693c d273 12bd 9a41
af38 1ea3 677d
f417 504b 0708 5822 97d3
9102 0000 dd05
0000 504b 0304 1400 0800
0800 6d57 2d49
0000 0000 0000 0000 0000
0000 1200 0000
6461 6767 6572 2f42 696e
6473 2e63 6c61
7373 8590 bf4e c330 10c6
bf2b b486 52a0
b031 a002 4347 22b1 3281
9a0a 244a 5108
2c4c 6e72 8a5c b90e 4a9c
4a7d 3506 1e80
87aa b874 a04b 242c 9def
ecef f79d fffc
acbf be01 dce0 54e1 58a1
af70 42e8 bee6
5591 f0d8 5896 c5bd 7169
793d d74b 4d38
8b2a e7cd 82df 4d69 6696
ef9c cbbd f626
7725 e1f2 a966 02ab 5d16
e83f 2118 e549
b560 e739 bd25 5c34 3311
7b21 a412 a4bd
d4b6 9273 87ff a02f b935
c94a 0c2a 7a7b
8e1f 2721 e1bc d912 eb22
632f e455 b31e
5aae 2f18 af3e 59a0 ce24
8c1f a623 422f
d559 c645 b079 3fa1 bff5
4e67 734e 3c61
d0d8 6efb 2943 02a1 25b1
837a b4b0 bb99
dbe8 481e c8ae 92bc 27fa
3ea3 8b03 f4ea
f203 c438 c4d1 2f50 4b07
08bd ac58 36f5
0000 009a 0100 0050 4b03
0414 0008 0008
006d 572d 4900 0000 0000
0000 0000 0000
001a 0000 0064 6167 6765
722f 4d75 6c74
6962 696e 6469 6e67 732e
636c 6173 736d
8f4d 6bc2 4010 86df f12b
6a5b 95e2 c583
94f6 e0b1 815e 3d15 d493
c5a2 4128 3d6d
9261 5959 3725 d915 fad7
7ae8 0ff0 4749
371e 2a42 06e6 03de 8777
668e a79f 5f00
2fe8 07b8 0d70 17a0 47e8
6e32 9727 bc50
9a09 f76f 4e5b 152b 932a
238b e79d 3808
c268 ed8c 557b deaa 42c5
9a5f 8dc9 acb0
2a33 05e1 7159 32a1 1646
86e2 5f08 6759
e2f6 6c2c a753 c2b8 9a89
442e d97a bd79
10da f9e5 4fd5 dc5c 7369
157d 7fb1 871b
d1c7 fb9c 304c 8594 9c87
57f7 1206 1787
55bc e3c4 121e 2a4d 2f4f
4c08 849a cf3a
caa8 a171 ae4d b47c 1ffa
29f0 bded f5ce
2788 d1c5 cd1f 504b 0708
60bf 608d d700
0000 4701 0000 504b 0304
1400 0800 0800
6d57 2d49 0000 0000 0000
0000 0000 0000
2200 0000 6461 6767 6572
2f6d 756c 7469
6269 6e64 696e 6773 2f4c
6f6e 674b 6579
2e63 6c61 7373 6d90 4d4b
c340 1086 df69
d346 6bb5 f5a6 a088 1e44
2f06 bcf6 24b4
229a 52d0 e0c5 d326 1996
2d9b 4d69 3685
fe35 0ffe 007f 9438 9562
2f39 cc07 f3bc
ccd7 f7cf e717 807b 1c87
380a 3108 3124
7456 cad6 4c68 dfdc 3e13
7a6f 65bd ccf8
d158 29f5 e3d2 e917 5edf
cdd5 4a11 4e5f
6be7 4dc1 efa6 32a9 e507
e74a afbc 295d
45b8 8c37 9ac8 2aa7 23f5
0fa2 7199 d505
3bcf f988 70de ac49 d452
b317 7ed5 cc27
9637 2d92 f582 45d4 9d4e
92a7 d998 3088
73a5 352f a3a9 5ac8 8e82
ceb6 85a2 b6de
a4c6 e5c6 e92a dade 4018
eeba cfd2 3967
9e70 d138 7077 d835 81d0
126b cbdb 2820
04e8 48d6 42f7 cf87 d893
7822 745f 624f
74c1 0788 7180 3e0e 815f
504b 0708 37e5
6ca0 f400 0000 6f01 0000
504b 0304 1400
0800 0800 6d57 2d49 0000
0000 0000 0000
0000 0000 2300 0000 6461
6767 6572 2f6d
756c 7469 6269 6e64 696e
6773 2f43 6c61
7373 4b65 792e 636c 6173
736d 9041 4b02
5110 c7ff 63ea a665 5a42
d421 a20e 511d
5ce8 5a04 9146 9022 e4d2
a5d3 d31d 9627
6fdf caee 5bc1 afd6 a10f
d087 8a46 a90c
dac3 3033 efff e33f 6fe6 e3f3
ed1d c015
da1e 5a1e 763d ec11 2a73
6572 26b4 cf2f
fa53 3557 be51 36f2 ef8d
cab2 6b42 6da4
23ab 5c9e 0ab1 ff9f b8b9
bc15 a83e 4af2
74c2 0fda 08d5 5809 4fbc
e82c 59c2 e173
6e9d 8ef9 4567 7a6c f8ce
dac4 29a7 139b
114e fef8 a95f c1ef 2693
3c66 eb38 14f3
a362 2650 69c4 4ef4 d362
bd67 7869 112c
662c 5075 d00b 1e87 5d42
b31f aa28 e2d4
1fa8 99fc 71e9 fffd 10e7
c6e9 b1b6 a1b6
51e6 ff2c 4168 aded 87e3
294f 1ce1 b870
e27a b333 02a1 24b1 21d7
a632 a18c 8a74
55e9 4af0 2436 5755 0d75
c907 426d 49de
16a2 fc0a 6234 b083 26f0
0550 4b07 08ab
aa9a 8010 0100 00ae 0100
0050 4b03 0414
0008 0008 006d 572d 4900
0000 0000 0000
0000 0000 0025 0000 0064
6167 6765 722f
6d75 6c74 6962 696e 6469
6e67 732f 4d75
6c74 6962 696e 6473 2e63
6c61 7373 6d4f
3d4b 0341 107d 134d 4ea3
3116 3616 225a
58ba 606b 2524 c1c2 10d0
234d aabd bb61
d9b0 b727 77bb 81fc 350b
7f80 3f4a 9c13
f49a 1b98 0f78 6fe6 bdf9
fafe f804 f080
6982 d304 9304 6784 f15b
15eb 9c17 d631
61ba 8c2e d8cc faa2 b9df
ea9d 265c be46
1f6c c96b dbd8 ccf1 93f7
55d0 c156 be21
dcbc b41c e5b4 374a ff03
6a56 e5b1 641f
b878 245c f573 525d 1b0e
820f 77da 4551
beed e7cd 1db7 a7d2 fd3b
0b79 b49c a7cf
ab19 e1ba d0c6 70ad ca3f
bbd6 9b46 75e6
09e7 ddb9 55b6 e53c c852
af42 f7d1 1d81
3090 3c40 1b03 1cfe d621
46d2 2f64 4aa4
1f09 7ebc 0131 c638 f901
504b 0708 09d7
9236 dc00 0000 5101 0000
504b 0304 1400
0800 0800 6d57 2d49 0000
0000 0000 0000
0000 0000 2a00 0000 6461
6767 6572 2f6d
756c 7469 6269 6e64 696e
6773 2f45 6c65
6d65 6e74 7349 6e74 6f53
6574 2e63 6c61
7373 8590 4d4b c340 1086
dfad b6d1 fa55
c58b 07a9 8af4 68c0 6b4f
4253 2c58 2b69
f4e2 6993 0c61 cb66 5792
4da1 7fcd 833f
a03f 4a9c 8858 9080 03f3
b1f3 3ecc 2cb3
fe7c ff00 708b 130f 471e
7a1e 8e05 ba73
5b15 098d 9526 81d3 4053
4ec6 9513 e3ec
9cdc cd42 2ea5 c059 5819
a772 7a51 a58a
35dd 1963 9d74 ca9a 52e0
f2a1 667c 2d4d
e6cb 5fc1 1fd9 a4aa 2751
3a14 386f 6622
5964 e458 6f2f a5ae 78fd
5533 f7f3 a968
f546 0c77 a641 743f 1b09
5c34 d321 3986
b962 76f0 0ff2 64b5 4a56
0c7a e1f3 6334
9906 02d7 a9cc 322a fcbc
d24e c5ca a4ca
64a5 ffe7 2e02 bdcd e059
bca0 845b fdc6
5d9b 630d 0404 5aec 5ba8
ad85 edef d846
8773 9fbb 1ee7 1dd6 775f
2108 5dec 61bf
7e11 0e70 f805 504b 0708
3151 0df1 0401
0000 bc01 0000 504b 0304
1400 0800 0800
6d57 2d49 0000 0000 0000
0000 0000 0000
2200 0000 6461 6767 6572
2f6d 756c 7469
6269 6e64 696e 6773 2f49
6e74 6f53 6574
2e63 6c61 7373 8590 cf4a
c340 10c6 bfad
b6d1 5ab5 7a13 94aa 871e
0d78 f524 3462
c15a 49a3 174f 9b64 085b
36bb 92ec 16fa
6a1e 7c00 1f4a 9c88 d84b
c081 f9fb fd98
81f9 fc7a ff00 708d e300
8701 8601 8e04
fa0b ebab 8cee 9426 81c1
d438 bb20 77b5
942b 2970 127b e354 492f
aa56 a9a6 5b63
ac93 4e59 530b 5c3c 344c
a8a5 2942 f927
8413 9bf9 928c a3fc 46e0
ac9d 4964 5590
63bd bb92 daf3 d9cb 762e
d2d4 ac4a d66f
c470 6f16 25f7 f389 c079
3b1d 9363 982b
66c7 ff20 4f56 ab6c cd60
103f 3f26 d359
2470 9acb a2a0 2a2c bd76
2a55 2657 a6a8
c3df 7f08 0c37 0be7 e992
321e 8d5a 6f6c
9e34 1610 e8b0 6fa1 b10e
b67f 6217 3dce
239e 069c 7758 df7d 8520
f4b1 8741 d311
f671 f00d 504b 0708 9783
6961 fe00 0000
ac01 0000 504b 0304 1400
0800 0800 6d57
2d49 0000 0000 0000 0000
0000 0000 2100
0000 6461 6767 6572 2f6d
756c 7469 6269
6e64 696e 6773 2f49 6e74
4b65 792e 636c
6173 736d 904d 4bc3 4010
86df 69d3 465b
b5f5 a688 881e 442f 06bc
7a12 5ab1 d852
d0e0 c5d3 2619 c296 cda6
24bb 85fe 350f
fe00 7f94 3855 b197 1ce6
8379 5ee6 ebf3
ebfd 03c0 2d0e 431c 8418
8418 123a 2b65
3c13 da57 d713 42ef a5f4
55ca 0fda 48a9
3fb1 ee89 d737 0bb5 5284
e367 6f9d 2ef8
55d7 3a31 7c6f 6de9 94d3
a5ad 09e7 d38d
2632 cae6 91fa 07d1 a84c
7dc1 d671 7647
386d d6c4 aaca d909 bf68
e663 c39b 16f1
7ac9 22ea cec6 f1e3 7c44
184c 3395 e75c
4533 b594 1d05 9dfc 150a
6f9c 4eb4 cdb4
cdeb e8f7 04c2 70db 7c9e
2c38 7584 b3c6
79db bb2e 0984 9658 5b9e
4601 2140 47b2
16ba 3f3e c48e c423 a1bb
127b a20b de40
8c3e f6b0 0f7c 0350 4b07
0832 5a85 a4f4
0000 006d 0100 0050 4b03
0414 0008 0008
006d 572d 4900 0000 0000
0000 0000 0000
0022 0000 0064 6167 6765
722f 6d75 6c74
6962 696e 6469 6e67 732f
496e 746f 4d61
702e 636c 6173 7385 90cf
4ac3 4010 c6bf
a9b6 d15a b57a 1394 aa87
1e0d 78f5 2434
62c1 5889 d18b a74d 3284
2d9b 4d49 3785
be9a 071f c087 1227 22f6
1270 60fe 7e3f
6660 3ebf de3f 005c e3d8
c3a1 87a1 8723
42ff b9ac ab94 efb4 61c2
606a 5d19 aac5
d55c ad14 e124 aaad d305
bfea a54e 0cdf
5a5b 3ae5 7469 9784 8b87
86f1 8db2 b9af
fe04 7f52 a675 c1d6 7176
4338 6b67 6255
e5ec 44ef ae94 a9e5 ec65
3b17 186e 56c5
eb05 0bdc 0b83 f87e 3621
9cb7 d311 3b81
a512 76fc 0ff2 541a 9dae
05f4 a297 c778
1a06 84d3 4ce5 3957 7e51
1ba7 136d 336d
f3a5 fffb 0fc2 70b3 7096
cc39 7584 51eb
8dcd 93c6 0442 477c 0b8d
75b0 fd13 bbe8
491e c9d4 93bc 23fa ee1b
88d1 c71e 064d
c7d8 c7c1 3750 4b07 0871
fcd5 47fe 0000
00ac 0100 0050 4b03 0414
0008 0008 006d
572d 4900 0000 0000 0000
0000 0000 0024
0000 0064 6167 6765 722f
6d75 6c74 6962
696e 6469 6e67 732f 5374
7269 6e67 4b65
792e 636c 6173 736d 90cf
4ac3 4010 c6bf
a969 a355 db0a 1ef4 a0a2
07d1 8b81 5e3d
096d 116c 29d8 e0c5 d326
19c2 96cd a624
9b42 5fcd 830f e043 49a7
2aad 871c 6667
99ef c737 7fbe be3f 3e01
f471 e2a3 e3a3
eba3 4768 2e95 a998 707a
773f 9eab a50a
8cb2 6930 7385 b6e9 23a1
3dcb ab22 e691
36c2 747e cb2f bc7a d8a0
84f3 d7ca 3a9d
f19b 2e75 64f8 c9da dc29
a773 5b12 aeff
d9a9 ad10 0cf2 b8ca d83a
4ec4 fda2 9e09
5591 b213 fda6 5e1f 1ade
5884 ab05 0bd4
9a0c c3e7 e980 d01d 272a
4db9 0826 6a21
338a 74f9 57c8 2ae3 74a4
6d22 d397 c176
0b42 6fe7 3f8d e61c 3bc2
556d cbdd 6ab7
0442 4362 4f6e 491e c143
537e 0db4 7e5e
1ffb 92cf 443d 90dc 16ce
7b07 310e 7184
6360 0d50 4b07 086d a4a0
7efc 0000 0084
0100 0050 4b03 0414 0008
0008 006d 572d
4900 0000 0000 0000 0000
0000 001c 0000
0064 6167 6765 722f 4269
6e64 734f 7074
696f 6e61 6c4f 662e 636c
6173 736d 8fcd
6ac2 5010 85cf 6835 6aeb
cf42 0417 a5b4
8b2e 1be8 d695 a2d2 8525
a0a1 9bae c664
1aae 5c6f 24b9 117c b52e
fa00 3e54 e94d
1715 4a06 e607 cec7 9999
f3f7 e717 8067
f43d dc78 e87a e811 3a9b
b4c8 2259 2a2d
84e1 4c99 380f 0e56 a586
75f0 f1b4 e323
13c6 ebc2 58b5 9737 95ab
ad96 a931 a9e5
92c9 09f7 ab92 f135 9bc4
e73f c19f a751
b117 6325 9e10 6eab 9990
b344 acd3 1b47
d685 5bff 50cd 2db4 9456
e1e9 200e 6ebe
2ec2 9760 4e18 c59c 2492
f9ff 6e26 0c2e
2ec1 7627 9125 dc55 1a5f
1e79 2410 6a2e
eb28 a386 abdf da40 d3f5
a19b 3cd7 5b4e
6fbf 8304 1d5c ff00 504b
0708 2615 5f0f
db00 0000 4d01 0000 504b
0304 0a00 0000
0000 6e57 2d49 0000 0000
0000 0000 0000
0000 0f00 0000 4d45 5441
2d49 4e46 2f6d
6176 656e 2f50 4b03 040a
0000 0000 006e
572d 4900 0000 0000 0000
0000 0000 0021
0000 004d 4554 412d 494e
462f 6d61 7665
6e2f 636f 6d2e 676f 6f67
6c65 2e64 6167
6765 722f 504b 0304 0a00
0000 0000 6e57
2d49 0000 0000 0000 0000
0000 0000 2800
0000 4d45 5441 2d49 4e46
2f6d 6176 656e
2f63 6f6d 2e67 6f6f 676c
652e 6461 6767
6572 2f64 6167 6765 722f
504b 0304 1400
0800 0800 5257 2d49 0000
0000 0000 0000
0000 0000 2f00 0000 4d45
5441 2d49 4e46
2f6d 6176 656e 2f63 6f6d
2e67 6f6f 676c
652e 6461 6767 6572 2f64
6167 6765 722f
706f 6d2e 786d 6cb5 565d
77db 360c 7df7
afc0 fcd4 6e11 65a7 3d69
9729 eaf1 92f4
cc6d eaf4 c4c9 ba3e f530
122c 3395 4895
a46c e7df 0fd4 8723 d94e
d276 8b5f 6c80
2070 015c 800e deac b214
16a8 8d50 f2a8
3f64 833e a08c 542c 6472
d4bf ba7c ebbd
eebf 097b c12f 9ed7 8363
95df 6a91 cc2d
3c3b 7e0e fb83 e13e 4cbf
155c e31e 8c65
c47a 3d80 3311 a134 1843
2163 d460 e708
a39c 47f4 559f ecc1 df55
30d8 6703 78e6
0cfa f551 fff9 1fe4 e156 1590
f15b 90ca
4261 905c 0803 3391 22e0
2ac2 dc82 9010
a92c 4f05 9711 c252 d879
19a6 76c2 c8c5
e7da 85ba b69c ac39 d9e7
24cd da76 c0ad
c35b 7ee6 d6e6 87be bf5c
2e19 2fc1 32a5
133f ad0c 8d7f 363e 3e9d
4c4f 3d02 ecae
5cc9 148d 018d df0a a129
d3eb 5be0 39c1
89f8 3581 4cf9 1294 069e
68a4 33ab 1cdc
a516 96ea b907 46cd ec92
ea45 5e62 61ac
16d7 85ed d4aa 0147 29b7
0da8 5a5c 427f
3485 f1b4 0f7f 8ea6 e3e9
1ef9 f834 befc
ebfc ea12 3e8d 2e2e 4693
cbf1 e914 ce2f
e0f8 7c72 32be 1c9f 4f48
7a0b a3c9 6778
3f9e 9cec 0152 a528 0cae
72ed f013 48e1
aa88 b12b d914 b103 60a6
2a40 26c7 48cc
4444 79c9 a4e0 0942 a288
2d92 d281 1c75
268c eba5 2178 3179 4945
262c b7a5 662b
29d6 f33c 6252 aed5 0d46
1688 77d2 1cf5
ebda 677c 81b2 5dfd 8fe7
1ffc 976c e0f8
585a 1eae 8c58 5bbb 4e2d
5f94 76fb 83c1
d0ff e7c3 d994 2e66 dc13
d258 c70b ba65
c4a1 2995 672a 2a31 7d47
30b8 cfa2 5478
8b97 5f06 5f06 6c65 e27e
48e9 0699 8a31
adf9 1c96 0e02 bfa3 737c
0972 eab8 b461
c9b6 20d1 aac8 c771 4814
6689 5249 8a2c
e649 823a f09b a3ca 906b
2b66 3cb2 a4a8
0cbc ca4f e0b7 4e2a d37a
7cc3 7df6 2af0
1bc1 45f6 9bd0 bd5d 0e37
3d05 9267 189e
d467 a550 e1d7 8a5a 6d05
9a3a 1e2d 03b8
28a4 1519 4256 184b b390
b941 7bc7 17fc
c071 de14 79ae b475 acd0
4ac4 0c5c e7cb
ab37 64c2 1a88 4376 10f8
1d4d 05ba 15cf
2962 cc91 c824 a33b 046b
d56d 580f f1ba
b0ce df8a 09e9 48b6 51d3
6e11 ba86 5b45
f5db 311e 8dda 6a27 8dc9
823f 18b9 b6d8
0c49 4686 3615 8616 0d21
aa7e ef00 f368
050a 291e 49bd b278 2a00
ad62 585d d8f9
8358 6a8b 9fc7 d292 d794
b92e 44da 3432
4f8b 84d6 c2da 6d25 3762
0b36 cd39 a397
0fe7 bc30 2c53 376a 0b77
1739 9722 e3a9
67a4 98cd 683c ab15 5179
df95 4f6b 5087
ecf5 dda0 96e3 3464 bfff
d63c 2906 de9d
bc7f e596 bedb 9e65 2af4
9c45 7321 713d
48a5 3b5c 6154 94db f64e
d956 b7b5 a417
7158 62f5 782e 025f c41b
c789 e2a9 09cb
af90 d65e f495 d277 bfab
af6e 087f 478c
96b2 651c 444a ce44 5268
be89 2830 2291
dc16 1a37 81dc d70f b6be
b1a3 335b 1ca7
191b 1eec 6ec4 4633 069d
ad79 97cf 0e80
81bf 331f 5a5a 1d56 6d93
ac05 a322 8ac3
17ab e861 c2dc 5f3c fa33
9416 317e e4d1
577a 9527 b4ac 4dbd d669
a559 7aa1 797a
b821 b35f 5d8b b6af 3d41
7246 153a c287
73fb 71f6 726b 690c 6ae7
6607 85f3 3937
1826 2891 3240 8f46 a931
ad4e 7611 bea3
abb5 441e ed49 e5d1 bfa0
660a ba57 ffc3
48fc 1455 f4ff 5aca 0712
77db d6c5 7bda
ac1b c954 fbbb ded6 e5cb
ef5e e3b0 f72f
504b 0708 57e6 18dc 3904
0000 970c 0000
504b 0304 1400 0800 0800
6d57 2d49 0000
0000 0000 0000 0000 0000
3600 0000 4d45
5441 2d49 4e46 2f6d 6176
656e 2f63 6f6d
2e67 6f6f 676c 652e 6461
6767 6572 2f64
6167 6765 722f 706f 6d2e
7072 6f70 6572
7469 6573 5376 4fcd 4b2d
4a2c 494d 5148
aa54 f04d 2c4b cde3 520e
294d 5508 4e2d
5030 3456 3034 b032 b5b4
3232 5370 7509
5130 3230 34e3 2a4b 2d2a
cecc cfb3 35d2
33e7 4a2f ca2f 2df0 4cb1
4dce cfd5 4bcf
cf4f cf49 d54b 494c 4f4f
2de2 4a2c 2ac9
4c4b 4c2e 014a 4245 0050
4b07 0837 c687
4b65 0000 006a 0000 0050
4b01 0214 030a
0000 0000 006e 572d 4900
0000 0000 0000
0000 0000 0009 0000 0000
0000 0000 0010
00ed 4100 0000 004d 4554
412d 494e 462f
504b 0102 1403 1400 0800
0800 6d57 2d49
92ab 04aa 7700 0000 8e00
0000 1400 0000
0000 0000 0000 0000 a481
2700 0000 4d45
5441 2d49 4e46 2f4d 414e
4946 4553 542e
4d46 504b 0102 1403 0a00
0000 0000 6d57
2d49 0000 0000 0000 0000
0000 0000 0700
0000 0000 0000 0000 1000
e841 e000 0000
6461 6767 6572 2f50 4b01
0214 030a 0000
0000 006d 572d 4900 0000
0000 0000 0000
0000 0010 0000 0000 0000
0000 0010 00e8
4105 0100 0064 6167 6765
722f 696e 7465
726e 616c 2f50 4b01 0214
030a 0000 0000
006d 572d 4900 0000 0000
0000 0000 0000
0015 0000 0000 0000 0000
0010 00e8 4133
0100 0064 6167 6765 722f
6d75 6c74 6962
696e 6469 6e67 732f 504b
0102 1403 1400
0800 0800 6d57 2d49 a793
c40e e000 0000
5f01 0000 1500 0000 0000
0000 0000 0000
a081 6601 0000 6461 6767
6572 2f52 6575
7361 626c 652e 636c 6173
7350 4b01 0214
0314 0008 0008 006d 572d
4920 bb6a c865
0100 0083 0200 0016 0000
0000 0000 0000
0000 00a0 8189 0200 0064
6167 6765 722f
436f 6d70 6f6e 656e 742e
636c 6173 7350
4b01 0214 0314 0008 0008
006d 572d 49af
188f 3446 0100 004b 0200
0015 0000 0000
0000 0000 0000 00a0 8132
0400 0064 6167
6765 722f 5072 6f76 6964
6573 2e63 6c61
7373 504b 0102 1403 1400
0800 0800 6d57
2d49 e17c d960 a000 0000
f600 0000 1c00
0000 0000 0000 0000 0000
a081 bb05 0000
6461 6767 6572 2f4d 656d
6265 7273 496e
6a65 6374 6f72 2e63 6c61
7373 504b 0102
1403 1400 0800 0800 6d57
2d49 aaea 0589
f800 0000 8601 0000 1e00
0000 0000 0000
0000 0000 a081 a506 0000
6461 6767 6572
2f43 6f6d 706f 6e65 6e74
2442 7569 6c64
6572 2e63 6c61 7373 504b
0102 1403 1400
0800 0800 6d57 2d49 d9cb
77cd fc00 0000
8f01 0000 2100 0000 0000
0000 0000 0000
a081 e907 0000 6461 6767
6572 2f53 7562
636f 6d70 6f6e 656e 7424
4275 696c 6465
722e 636c 6173 7350 4b01
0214 0314 0008
0008 006d 572d 49e5 eb58
8392 0000 00d4
0000 0011 0000 0000 0000
0000 0000 00a0
8134 0900 0064 6167 6765
722f 4c61 7a79
2e63 6c61 7373 504b 0102
1403 1400 0800
0800 6d57 2d49 4c14 e3b0
2501 0000 e301
0000 1300 0000 0000 0000
0000 0000 a081
050a 0000 6461 6767 6572
2f4d 6170 4b65
792e 636c 6173 7350 4b01
0214 0314 0008
0008 006d 572d 49f2 ed6e
4d5b 0100 0064
0200 0019 0000 0000 0000
0000 0000 00a0
816b 0b00 0064 6167 6765
722f 5375 6263
6f6d 706f 6e65 6e74 2e63
6c61 7373 504b
0102 1403 1400 0800 0800
6d57 2d49 12ab
3334 6002 0000 4d04 0000
1a00 0000 0000
0000 0000 0000 a081 0d0d
0000 6461 6767
6572 2f50 726f 7669 6465
7324 5479 7065
2e63 6c61 7373 504b 0102
1403 1400 0800
0800 6d57 2d49 09f5 1b5c
3601 0000 1002
0000 1300 0000 0000 0000
0000 0000 a081
b50f 0000 6461 6767 6572
2f4d 6f64 756c
652e 636c 6173 7350 4b01
0214 0314 0008
0008 006d 572d 49da e884
49d1 0000 0044
0100 001a 0000 0000 0000
0000 0000 00a0
812c 1100 0064 6167 6765
722f 696e 7465
726e 616c 2f42 6574 612e
636c 6173 7350
4b01 0214 0314 0008 0008
006d 572d 49c0
5b0e eb95 0100 0018 0300
0022 0000 0000
0000 0000 0000 00a0 8145
1200 0064 6167
6765 722f 696e 7465 726e
616c 2f53 6574
4661 6374 6f72 7924 312e
636c 6173 7350
4b01 0214 0314 0008 0008
006d 572d 4931
3fd9 d100 0300 00a8 0600
0024 0000 0000
0000 0000 0000 00a0 812a
1400 0064 6167
6765 722f 696e 7465 726e
616c 2f50 726f
7669 6465 724f 664c 617a
792e 636c 6173
7350 4b01 0214 0314 0008
0008 006d 572d
4935 13b6 5ba0 0000 00e7
0000 001d 0000
0000 0000 0000 0000 00a0
817c 1700 0064
6167 6765 722f 696e 7465
726e 616c 2f46
6163 746f 7279 2e63 6c61
7373 504b 0102
1403 1400 0800 0800 6d57
2d49 f2ad fb42
4906 0000 6f0e 0000 2000
0000 0000 0000
0000 0000 a081 6718 0000
6461 6767 6572
2f69 6e74 6572 6e61 6c2f
5365 7446 6163
746f 7279 2e63 6c61 7373
504b 0102 1403
1400 0800 0800 6d57 2d49
c610 677f aa03
0000 3107 0000 2700 0000
0000 0000 0000
0000 a081 fe1e 0000 6461
6767 6572 2f69
6e74 6572 6e61 6c2f 4461
6767 6572 436f
6c6c 6563 7469 6f6e 732e
636c 6173 7350
4b01 0214 0314 0008 0008
006d 572d 4911
b043 bc60 0200 00d9 0500
0026 0000 0000
0000 0000 0000 00a0 81fd
2200 0064 6167
6765 722f 696e 7465 726e
616c 2f4d 656d
6265 7273 496e 6a65 6374
6f72 732e 636c
6173 7350 4b01 0214 0314
0008 0008 006d
572d 4976 1346 0883 0000
00a6 0000 0025
0000 0000 0000 0000 0000
00a0 81b1 2500
0064 6167 6765 722f 696e
7465 726e 616c
2f47 7774 496e 636f 6d70
6174 6962 6c65
2e63 6c61 7373 504b 0102
1403 1400 0800
0800 6d57 2d49 f24b 808a
1504 0000 8609
0000 2000 0000 0000 0000
0000 0000 a081
8726 0000 6461 6767 6572
2f69 6e74 6572
6e61 6c2f 4d61 7046 6163
746f 7279 2e63
6c61 7373 504b 0102 1403
1400 0800 0800
6d57 2d49 3aae 138a 3902
0000 8404 0000
2500 0000 0000 0000 0000
0000 a081 ea2a
0000 6461 6767 6572 2f69
6e74 6572 6e61
6c2f 4465 6c65 6761 7465
4661 6374 6f72
792e 636c 6173 7350 4b01
0214 0314 0008
0008 006d 572d 49a0 a44e
f73c 0300 00c2
0800 0028 0000 0000 0000
0000 0000 00a0
8176 2d00 0064 6167 6765
722f 696e 7465
726e 616c 2f4d 6170 5072
6f76 6964 6572
4661 6374 6f72 792e 636c
6173 7350 4b01
0214 0314 0008 0008 006d
572d 499e 2bca
1358 0400 00aa 0a00 0028
0000 0000 0000
0000 0000 00a0 8108 3100
0064 6167 6765
722f 696e 7465 726e 616c
2f53 6574 4661
6374 6f72 7924 4275 696c
6465 722e 636c
6173 7350 4b01 0214 0314
0008 0008 006d
572d 49cb cfd5 135a 0300
00e0 0600 0021
0000 0000 0000 0000 0000
00a0 81b6 3500
0064 6167 6765 722f 696e
7465 726e 616c
2f53 696e 676c 6543 6865
636b 2e63 6c61
7373 504b 0102 1403 1400
0800 0800 6d57
2d49 afd7 a3c4 7903 0000
4a08 0000 3000
0000 0000 0000 0000 0000
a081 5f39 0000
6461 6767 6572 2f69 6e74
6572 6e61 6c2f
4d61 7050 726f 7669 6465
7246 6163 746f
7279 2442 7569 6c64 6572
2e63 6c61 7373
504b 0102 1403 1400 0800
0800 6d57 2d49
a1b6 d43f ee04 0000 140a
0000 2100 0000
0000 0000 0000 0000 a081
363d 0000 6461
6767 6572 2f69 6e74 6572
6e61 6c2f 446f
7562 6c65 4368 6563 6b2e
636c 6173 7350
4b01 0214 0314 0008 0008
006d 572d 4923
486b 25d8 0100 00a7 0300
0023 0000 0000
0000 0000 0000 00a0 8173
4200 0064 6167
6765 722f 696e 7465 726e
616c 2f50 7265
636f 6e64 6974 696f 6e73
2e63 6c61 7373
504b 0102 1403 1400 0800
0800 6d57 2d49
7b4a aef7 a700 0000 ea00
0000 2a00 0000
0000 0000 0000 0000 a081
9c44 0000 6461
6767 6572 2f69 6e74 6572
6e61 6c2f 4d61
7050 726f 7669 6465 7246
6163 746f 7279
2431 2e63 6c61 7373 504b
0102 1403 1400
0800 0800 6d57 2d49 afcc
e0d2 fb01 0000
3404 0000 2500 0000 0000
0000 0000 0000
a081 9b45 0000 6461 6767
6572 2f69 6e74
6572 6e61 6c2f 496e 7374
616e 6365 4661
6374 6f72 792e 636c 6173
7350 4b01 0214
0314 0008 0008 006d 572d
4958 2297 d391
0200 00dd 0500 003a 0000
0000 0000 0000
0000 00a0 81e9 4700 0064
6167 6765 722f
696e 7465 726e 616c 2f4d
656d 6265 7273
496e 6a65 6374 6f72 7324
4e6f 4f70 4d65
6d62 6572 7349 6e6a 6563
746f 722e 636c
6173 7350 4b01 0214 0314
0008 0008 006d
572d 49bd ac58 36f5 0000
009a 0100 0012
0000 0000 0000 0000 0000
00a0 81e2 4a00
0064 6167 6765 722f 4269
6e64 732e 636c
6173 7350 4b01 0214 0314
0008 0008 006d
572d 4960 bf60 8dd7 0000
0047 0100 001a
0000 0000 0000 0000 0000
00a0 8117 4c00
0064 6167 6765 722f 4d75
6c74 6962 696e
6469 6e67 732e 636c 6173
7350 4b01 0214
0314 0008 0008 006d 572d
4937 e56c a0f4
0000 006f 0100 0022 0000
0000 0000 0000
0000 00a0 8136 4d00 0064
6167 6765 722f
6d75 6c74 6962 696e 6469
6e67 732f 4c6f
6e67 4b65 792e 636c 6173
7350 4b01 0214
0314 0008 0008 006d 572d
49ab aa9a 8010
0100 00ae 0100 0023 0000
0000 0000 0000
0000 00a0 817a 4e00 0064
6167 6765 722f
6d75 6c74 6962 696e 6469
6e67 732f 436c
6173 734b 6579 2e63 6c61
7373 504b 0102
1403 1400 0800 0800 6d57
2d49 09d7 9236
dc00 0000 5101 0000 2500
0000 0000 0000
0000 0000 a081 db4f 0000
6461 6767 6572
2f6d 756c 7469 6269 6e64
696e 6773 2f4d
756c 7469 6269 6e64 732e
636c 6173 7350
4b01 0214 0314 0008 0008
006d 572d 4931
510d f104 0100 00bc 0100
002a 0000 0000
0000 0000 0000 00a0 810a
5100 0064 6167
6765 722f 6d75 6c74 6962
696e 6469 6e67
732f 456c 656d 656e 7473
496e 746f 5365
742e 636c 6173 7350 4b01
0214 0314 0008
0008 006d 572d 4997 8369
61fe 0000 00ac
0100 0022 0000 0000 0000
0000 0000 00a0
8166 5200 0064 6167 6765
722f 6d75 6c74
6962 696e 6469 6e67 732f
496e 746f 5365
742e 636c 6173 7350 4b01
0214 0314 0008
0008 006d 572d 4932 5a85
a4f4 0000 006d
0100 0021 0000 0000 0000
0000 0000 00a0
81b4 5300 0064 6167 6765
722f 6d75 6c74
6962 696e 6469 6e67 732f
496e 744b 6579
2e63 6c61 7373 504b 0102
1403 1400 0800
0800 6d57 2d49 71fc d547
fe00 0000 ac01
0000 2200 0000 0000 0000
0000 0000 a081
f754 0000 6461 6767 6572
2f6d 756c 7469
6269 6e64 696e 6773 2f49
6e74 6f4d 6170
2e63 6c61 7373 504b 0102
1403 1400 0800
0800 6d57 2d49 6da4 a07e
fc00 0000 8401
0000 2400 0000 0000 0000
0000 0000 a081
4556 0000 6461 6767 6572
2f6d 756c 7469
6269 6e64 696e 6773 2f53
7472 696e 674b
6579 2e63 6c61 7373 504b
0102 1403 1400
0800 0800 6d57 2d49 2615
5f0f db00 0000
4d01 0000 1c00 0000 0000
0000 0000 0000
a081 9357 0000 6461 6767
6572 2f42 696e
6473 4f70 7469 6f6e 616c
4f66 2e63 6c61
7373 504b 0102 1403 0a00
0000 0000 6e57
2d49 0000 0000 0000 0000
0000 0000 0f00
0000 0000 0000 0000 1000
ed41 b858 0000
4d45 5441 2d49 4e46 2f6d
6176 656e 2f50
4b01 0214 030a 0000 0000
006e 572d 4900
0000 0000 0000 0000 0000
0021 0000 0000
0000 0000 0010 00ed 41e5
5800 004d 4554
412d 494e 462f 6d61 7665
6e2f 636f 6d2e
676f 6f67 6c65 2e64 6167
6765 722f 504b
0102 1403 0a00 0000 0000
6e57 2d49 0000
0000 0000 0000 0000 0000
2800 0000 0000
0000 0000 1000 ed41 2459
0000 4d45 5441
2d49 4e46 2f6d 6176 656e
2f63 6f6d 2e67
6f6f 676c 652e 6461 6767
6572 2f64 6167
6765 722f 504b 0102 1403
1400 0800 0800
5257 2d49 57e6 18dc 3904
0000 970c 0000
2f00 0000 0000 0000 0000
0000 a081 6a59
0000 4d45 5441 2d49 4e46
2f6d 6176 656e
2f63 6f6d 2e67 6f6f 676c
652e 6461 6767
6572 2f64 6167 6765 722f
706f 6d2e 786d
6c50 4b01 0214 0314 0008
0008 006d 572d
4937 c687 4b65 0000 006a
0000 0036 0000
0000 0000 0000 0000 00a0
8100 5e00 004d
4554 412d 494e 462f 6d61
7665 6e2f 636f
6d2e 676f 6f67 6c65 2e64
6167 6765 722f
6461 6767 6572 2f70 6f6d
2e70 726f 7065
7274 6965 7350 4b05 0600
0000 0033 0033
005c 0f00 00c9 5e00 0000 00
javax.inject-1.jar
504b 0304 0a00 0000 0000
e280 4d3b 0000
0000 0000 0000 0000 0000
0600 0400 6a61
7661 782f feca 0000 504b
0304 0a00 0000
0000 e280 4d3b 0000 0000
0000 0000 0000
0000 0d00 0000 6a61 7661
782f 696e 6a65
6374 2f50 4b03 0414 0008
0008 00e2 804d
3b00 0000 0000 0000 0000
0000 0019 0000
006a 6176 6178 2f69 6e6a
6563 742f 496e
6a65 6374 2e63 6c61 7373
8590 cd4e 0231
1485 4f41 1805 7f50 dcb8
30fe 2c48 dc38
71ed cac0 1027 01c6 0c83
1b57 65bc 2125
a543 a043 e4d5 5cf8 003e
94f1 1612 d94c
6293 9e36 e77e f7b4 b9df
3f9f 5f00 1e70
eee1 d4c3 9987 a640 6d98
e58b 94ba 4a93
403d 3453 4aed fd54 aea4
c045 9c1b ab66
f4aa 966a ace9 c998 cc4a
ab32 b314 b8ec
39c6 d7d2 4c7c f957 f013
b998 907d 14a8
aca4 ce39 f1b6 980b 34cd
c8d8 643d 2786
abfd 2079 8e3a fc7e 3b1a
0c93 78d4 4ea2
9833 ba61 d063 f7ba 3823
26cb 117c e384
d63f c84b a655 ba66 d08b
4783 24ec 0702
37c5 2d9d 2ccd ddd7 e89d
e9a6 433e 7cb5
998a bf1d 8e40 63d7 188d
b7d6 5561 d66e
622d 0181 12ef 32dc 2a61
6fa3 1554 f9bc
63d7 e3da fe1b ca84 03d4
9cd4 9d1c e2c8
f984 639c a001 fc02 504b
0708 b535 3b38
0e01 0000 c201 0000 504b
0304 1400 0800
0800 e280 4d3b 0000 0000
0000 0000 0000
0000 1800 0000 6a61 7661
782f 696e 6a65
6374 2f4e 616d 6564 2e63
6c61 7373 8590
4d4b c340 1086 df69 53a3
f1ab ad0a 7a52
2f45 2f06 cf9e 0a55 10b4
6aaa deb7 e9b4
6cd9 6c20 d92d fad7 7af0
07f8 a3c4 690f
46a1 e061 9819 e679 e7eb
f36b fe01 e012
7b21 9a21 5a21 da84 c64c
19cf 84fd b3f3
bba9 9aa9 d828 3b89 07ae
d076 7245 6875
adcd 9d72 3ab7 3d1e 2b6f
1c01 8468 90fb
22e5 1b6d 441a f555 c6a3
8b85 9a70 9478
eb74 c6af bad4 43c3 95bc
241c 2e27 bcc5
da4e 3975 f193 5746 8f35
1732 e7f4 d770
f5a3 897b 79ea 33b6 8e47
c29c ac66 1276
4248 2448 e71f e431 373a
7d17 304c 5efa
cfb7 f7d7 84f6 9f9d 96a7
109a 559b 87e1
a240 385e d9b9 baaf 43f2
979a 585d 7e4c
0121 4043 b235 c9ea 2542
29ad 4b58 c306
22f1 0782 6d8a df12 db16
2c60 ec60 f71b
504b 0708 0129 6a2f 0201
0000 a201 0000
504b 0304 1400 0800 0800
e280 4d3b 0000
0000 0000 0000 0000 0000
1b00 0000 6a61
7661 782f 696e 6a65 6374
2f50 726f 7669
6465 722e 636c 6173 733b
f56f d73e 0606
0643 061e 7606 2e76 066e
4606 e6f4 d412
4606 110d 4d9f acc4 b244
fd9c c4bc 747d
ffa4 acd4 e412 6b46 06ce
e0cc f4bc c492
d2a2 5446 0656 0dcd 9010
a098 864d 8815
a65a 3b6c dab9 82f3 4b8b
9253 dd32 7380
fa79 038a f2cb 3253 528b
f440 2a19 1944
4154 857e 661e 48b1 3e4c
9291 4100 dd20
3646 0646 0626 0610 6064
013a 9881 05c8
6705 f298 18d8 8018 c262
67e0 00d3 9c00
504b 0708 c544 1750 9700
0000 e200 0000
504b 0304 1400 0800 0800
e280 4d3b 0000
0000 0000 0000 0000 0000
1c00 0000 6a61
7661 782f 696e 6a65 6374
2f51 7561 6c69
6669 6572 2e63 6c61 7373
8590 cd4a c340
1485 cf54 6bb4 6a7f 5c08
2ea4 eaa2 4b83
6b57 012b 146a 52e3 2888
0b99 c66b 9932
9d94 7452 ecab b9f0 017c
28f1 8e8b 7613
70e0 cedf f9ce e172 bf7f
3ebf 005c e128
402b 403b 4047 a0f1 9097
4546 b7da 9040
f3be 5446 bf6b 2a2e a76a
a904 4ed2 d23a
3da3 27bd d063 4391 b5b9
534e e776 2170
3af4 4c68 949d 846a 2d84
5215 1372 d702
f5a5 3225 875e 5473 7d43
33b2 4eae e6c4
702b 8ae3 4446 7290 c4af
f279 d417 38ab
b6a5 e4d8 c537 36f5 fe41
46b9 d1d9 8ac1
207d 8ce5 e08e 53cf ab2d
3779 56fa 6ee8
8de9 638f 7c84 da4e 2973
e17a 2402 ed8d
3719 7b51 a05b 19b7 9953
4f40 a0c6 b505
bf6a d8fe dbeb d8e1 b3cb
bf01 6bbb 2f10
843d 34b0 ef5f 8403 1ca2
09fc 0250 4b07
081f c5b9 9903 0100 00b1
0100 0050 4b03
0414 0008 0008 00e2 804d
3b00 0000 0000
0000 0000 0000 0018 0000
006a 6176 6178
2f69 6e6a 6563 742f 5363
6f70 652e 636c
6173 7385 90cd 4e02 3114
854f 511c c51f
909d 0b83 ba60 e9c4 b5ab
49c0 8404 66c8
584d 8c0b 53c6 1b52 525a
021d 22af e6c2
07f0 a18c b72c 6433 894d
dadb dbf3 9d93
e67e ff7c 7e01 b843 3b42
3342 2bc2 b940
e3d1 95cb 821e b4a1 d014
6e41 b733 b556
0217 7969 bd9e d3b3 5ee9
89a1 c45a e795
d7ce ae04 2e87 8189 8db2
d358 fd09 b154
cb29 f97b 81fa 5a99 9203
6faa b9be a139
592f 370b 62b8 99a4 6926
1339 c8d2 37f9
32ee 0b5c 55db 72f2 ece2
1b9b baff 2063
6774 b161 30ca 9f52 3918
71ea 75b5 a5e7
8a32 fc86 de99 6e07 e423
d676 4685 8fb7
e310 68ed 7cd9 2408 029d
caa8 dd8c ba02
0235 de7b 08ab 86fd ed59
c701 d70e bf46
ac1d be42 108e d0c0 71e8
0827 38c5 19f0
0b50 4b07 085a 8dc7 16fe
0000 00a9 0100
0050 4b03 0414 0008 0008
00e2 804d 3b00
0000 0000 0000 0000 0000
001c 0000 006a
6176 6178 2f69 6e6a 6563
742f 5369 6e67
6c65 746f 6e2e 636c 6173
7385 8fcb 4a43
410c 86ff 54eb 68d5 da85
0aae d44d 970e
ae5d 15aa 2078 e31c 753f
1d43 9932 cd88
9d53 eaab b9f0 017c 2831
a7a0 a550 3090
0bc9 97f0 e7eb fbe3 13c0
393a 06bb 066d
833d 42ab 4cd5 9be7 ab10
99d0 2e83 0c23
e724 6723 3775 84a3 a292
1cc6 fc1c 2661
10b9 2792 b2cb 21c9 84b0
7f53 3333 1b64
c43e dbd2 a757 be20 9cce
db36 3a19 5af7
c7db 7ef2 d598 25f3 8b32
27ab 9982 b312
5a29 d29c ba58 a9a4 ee3f
e843 8ac1 bfeb
8229 9eee 1eaf 6f2f 0987
cbba 7e5f 2274
16a7 ee07 f590 70bc f2fa
e2cf 2e81 d050
5f43 6d0d accf 6313 1b9a
0fb4 6b34 6faa
6f29 d362 6c63 e707 504b
0708 59b1 1c4b
dd00 0000 6701 0000 504b
0102 0a00 0a00
0000 0000 e280 4d3b 0000
0000 0000 0000
0000 0000 0600 0400 0000
0000 0000 0000
0000 0000 0000 6a61 7661
782f feca 0000
504b 0102 0a00 0a00 0000
0000 e280 4d3b
0000 0000 0000 0000 0000
0000 0d00 0000
0000 0000 0000 0000 0000
2800 0000 6a61
7661 782f 696e 6a65 6374
2f50 4b01 0214
0014 0008 0008 00e2 804d
3bb5 353b 380e
0100 00c2 0100 0019 0000
0000 0000 0000
0000 0000 0053 0000 006a
6176 6178 2f69
6e6a 6563 742f 496e 6a65
6374 2e63 6c61
7373 504b 0102 1400 1400
0800 0800 e280
4d3b 0129 6a2f 0201 0000
a201 0000 1800
0000 0000 0000 0000 0000
0000 a801 0000
6a61 7661 782f 696e 6a65
6374 2f4e 616d
6564 2e63 6c61 7373 504b
0102 1400 1400
0800 0800 e280 4d3b c544
1750 9700 0000
e200 0000 1b00 0000 0000
0000 0000 0000
0000 f002 0000 6a61 7661
782f 696e 6a65
6374 2f50 726f 7669 6465
722e 636c 6173
7350 4b01 0214 0014 0008
0008 00e2 804d
3b1f c5b9 9903 0100 00b1
0100 001c 0000
0000 0000 0000 0000 0000
00d0 0300 006a
6176 6178 2f69 6e6a 6563
742f 5175 616c
6966 6965 722e 636c 6173
7350 4b01 0214
0014 0008 0008 00e2 804d
3b5a 8dc7 16fe
0000 00a9 0100 0018 0000
0000 0000 0000
0000 0000 001d 0500 006a
6176 6178 2f69
6e6a 6563 742f 5363 6f70
652e 636c 6173
7350 4b01 0214 0014 0008
0008 00e2 804d
3b59 b11c 4bdd 0000 0067
0100 001c 0000
0000 0000 0000 0000 0000
0061 0600 006a
6176 6178 2f69 6e6a 6563
742f 5369 6e67
6c65 746f 6e2e 636c 6173
7350 4b05 0600
0000 0008 0008 0023 0200
0088 0700 0000
00
nineoldandroids-2.4.0.jar
504b 0304 0a00 0000 0000
e280 4d3b 0000
0000 0000 0000 0000 0000
0600 0400 6a61
7661 782f feca 0000 504b
0304 0a00 0000
0000 e280 4d3b 0000 0000
0000 0000 0000
0000 0d00 0000 6a61 7661
782f 696e 6a65
6374 2f50 4b03 0414 0008
0008 00e2 804d
3b00 0000 0000 0000 0000
0000 0019 0000
006a 6176 6178 2f69 6e6a
6563 742f 496e
6a65 6374 2e63 6c61 7373
8590 cd4e 0231
1485 4f41 1805 7f50 dcb8
30fe 2c48 dc38
71ed cac0 1027 01c6 0c83
1b57 65bc 2125
a543 a043 e4d5 5cf8 003e
94f1 1612 d94c
6293 9e36 e77e f7b4 b9df
3f9f 5f00 1e70
eee1 d4c3 9987 a640 6d98
e58b 94ba 4a93
403d 3453 4aed fd54 aea4
c045 9c1b ab66
f4aa 966a ace9 c998 cc4a
ab32 b314 b8ec
39c6 d7d2 4c7c f957 f013
b998 907d 14a8
aca4 ce39 f1b6 980b 34cd
c8d8 643d 2786
abfd 2079 8e3a fc7e 3b1a
0c93 78d4 4ea2
9833 ba61 d063 f7ba 3823
26cb 117c e384
d63f c84b a655 ba66 d08b
4783 24ec 0702
37c5 2d9d 2ccd ddd7 e89d
e9a6 433e 7cb5
998a bf1d 8e40 63d7 188d
b7d6 5561 d66e
622d 0181 12ef 32dc 2a61
6fa3 1554 f9bc
63d7 e3da fe1b ca84 03d4
9cd4 9d1c e2c8
f984 639c a001 fc02 504b
0708 b535 3b38
0e01 0000 c201 0000 504b
0304 1400 0800
0800 e280 4d3b 0000 0000
0000 0000 0000
0000 1800 0000 6a61 7661
782f 696e 6a65
6374 2f4e 616d 6564 2e63
6c61 7373 8590
4d4b c340 1086 df69 53a3
f1ab ad0a 7a52
2f45 2f06 cf9e 0a55 10b4
6aaa deb7 e9b4
6cd9 6c20 d92d fad7 7af0
07f8 a3c4 690f
46a1 e061 9819 e679 e7eb
f36b fe01 e012
7b21 9a21 5a21 da84 c64c
19cf 84fd b3f3
bba9 9aa9 d828 3b89 07ae
d076 7245 6875
adcd 9d72 3ab7 3d1e 2b6f
1c01 8468 90fb
22e5 1b6d 441a f555 c6a3
8b85 9a70 9478
eb74 c6af bad4 43c3 95bc
241c 2e27 bcc5
da4e 3975 f193 5746 8f35
1732 e7f4 d770
f5a3 897b 79ea 33b6 8e47
c29c ac66 1276
4248 2448 e71f e431 373a
7d17 304c 5efa
cfb7 f7d7 84f6 9f9d 96a7
109a 559b 87e1
a240 385e d9b9 baaf 43f2
979a 585d 7e4c
0121 4043 b235 c9ea 2542
29ad 4b58 c306
22f1 0782 6d8a df12 db16
2c60 ec60 f71b
504b 0708 0129 6a2f 0201
0000 a201 0000
504b 0304 1400 0800 0800
e280 4d3b 0000
0000 0000 0000 0000 0000
1b00 0000 6a61
7661 782f 696e 6a65 6374
2f50 726f 7669
6465 722e 636c 6173 733b
f56f d73e 0606
0643 061e 7606 2e76 066e
4606 e6f4 d412
4606 110d 4d9f acc4 b244
fd9c c4bc 747d
ffa4 acd4 e412 6b46 06ce
e0cc f4bc c492
d2a2 5446 0656 0dcd 9010
a098 864d 8815
a65a 3b6c dab9 82f3 4b8b
9253 dd32 7380
fa79 038a f2cb 3253 528b
f440 2a19 1944
4154 857e 661e 48b1 3e4c
9291 4100 dd20
3646 0646 0626 0610 6064
013a 9881 05c8
6705 f298 18d8 8018 c262
67e0 00d3 9c00
504b 0708 c544 1750 9700
0000 e200 0000
504b 0304 1400 0800 0800
e280 4d3b 0000
0000 0000 0000 0000 0000
1c00 0000 6a61
7661 782f 696e 6a65 6374
2f51 7561 6c69
6669 6572 2e63 6c61 7373
8590 cd4a c340
1485 cf54 6bb4 6a7f 5c08
2ea4 eaa2 4b83
6b57 012b 146a 52e3 2888
0b99 c66b 9932
9d94 7452 ecab b9f0 017c
28f1 8e8b 7613
70e0 cedf f9ce e172 bf7f
3ebf 005c e128
402b 403b 4047 a0f1 9097
4546 b7da 9040
f3be 5446 bf6b 2a2e a76a
a904 4ed2 d23a
3da3 27bd d063 4391 b5b9
534e e776 2170
3af4 4c68 949d 846a 2d84
5215 1372 d702
f5a5 3225 875e 5473 7d43
33b2 4eae e6c4
702b 8ae3 4446 7290 c4af
f279 d417 38ab
b6a5 e4d8 c537 36f5 fe41
46b9 d1d9 8ac1
207d 8ce5 e08e 53cf ab2d
3779 56fa 6ee8
8de9 638f 7c84 da4e 2973
e17a 2402 ed8d
3719 7b51 a05b 19b7 9953
4f40 a0c6 b505
bf6a d8fe dbeb d8e1 b3cb
bf01 6bbb 2f10
843d 34b0 ef5f 8403 1ca2
09fc 0250 4b07
081f c5b9 9903 0100 00b1
0100 0050 4b03
0414 0008 0008 00e2 804d
3b00 0000 0000
0000 0000 0000 0018 0000
006a 6176 6178
2f69 6e6a 6563 742f 5363
6f70 652e 636c
6173 7385 90cd 4e02 3114
854f 511c c51f
909d 0b83 ba60 e9c4 b5ab
49c0 8404 66c8
584d 8c0b 53c6 1b52 525a
021d 22af e6c2
07f0 a18c b72c 6433 894d
dadb dbf3 9d93
e67e ff7c 7e01 b843 3b42
3342 2bc2 b940
e3d1 95cb 821e b4a1 d014
6e41 b733 b556
0217 7969 bd9e d3b3 5ee9
89a1 c45a e795
d7ce ae04 2e87 8189 8db2
d358 fd09 b154
cb29 f97b 81fa 5a99 9203
6faa b9be a139
592f 370b 62b8 99a4 6926
1339 c8d2 37f9
32ee 0b5c 55db 72f2 ece2
1b9b baff 2063
6774 b161 30ca 9f52 3918
71ea 75b5 a5e7
8a32 fc86 de99 6e07 e423
d676 4685 8fb7
e310 68ed 7cd9 2408 029d
caa8 dd8c ba02
0235 de7b 08ab 86fd ed59
c701 d70e bf46
ac1d be42 108e d0c0 71e8
0827 38c5 19f0
0b50 4b07 085a 8dc7 16fe
0000 00a9 0100
0050 4b03 0414 0008 0008
00e2 804d 3b00
0000 0000 0000 0000 0000
001c 0000 006a
6176 6178 2f69 6e6a 6563
742f 5369 6e67
6c65 746f 6e2e 636c 6173
7385 8fcb 4a43
410c 86ff 54eb 68d5 da85
0aae d44d 970e
ae5d 15aa 2078 e31c 753f
1d43 9932 cd88
9d53 eaab b9f0 017c 2831
a7a0 a550 3090
0bc9 97f0 e7eb fbe3 13c0
393a 06bb 066d
833d 42ab 4cd5 9be7 ab10
99d0 2e83 0c23
e724 6723 3775 84a3 a292
1cc6 fc1c 2661
10b9 2792 b2cb 21c9 84b0
7f53 3333 1b64
c43e dbd2 a757 be20 9cce
db36 3a19 5af7
c7db 7ef2 d598 25f3 8b32
27ab 9982 b312
5a29 d29c ba58 a9a4 ee3f
e843 8ac1 bfeb
8229 9eee 1eaf 6f2f 0987
cbba 7e5f 2274
16a7 ee07 f590 70bc f2fa
e2cf 2e81 d050
5f43 6d0d accf 6313 1b9a
0fb4 6b34 6faa
6f29 d362 6c63 e707 504b
0708 59b1 1c4b
dd00 0000 6701 0000 504b
0102 0a00 0a00
0000 0000 e280 4d3b 0000
0000 0000 0000
0000 0000 0600 0400 0000
0000 0000 0000
0000 0000 0000 6a61 7661
782f feca 0000
504b 0102 0a00 0a00 0000
0000 e280 4d3b
0000 0000 0000 0000 0000
0000 0d00 0000
0000 0000 0000 0000 0000
2800 0000 6a61
7661 782f 696e 6a65 6374
2f50 4b01 0214
0014 0008 0008 00e2 804d
3bb5 353b 380e
0100 00c2 0100 0019 0000
0000 0000 0000
0000 0000 0053 0000 006a
6176 6178 2f69
6e6a 6563 742f 496e 6a65
6374 2e63 6c61
7373 504b 0102 1400 1400
0800 0800 e280
4d3b 0129 6a2f 0201 0000
a201 0000 1800
0000 0000 0000 0000 0000
0000 a801 0000
6a61 7661 782f 696e 6a65
6374 2f4e 616d
6564 2e63 6c61 7373 504b
0102 1400 1400
0800 0800 e280 4d3b c544
1750 9700 0000
e200 0000 1b00 0000 0000
0000 0000 0000
0000 f002 0000 6a61 7661
782f 696e 6a65
6374 2f50 726f 7669 6465
722e 636c 6173
7350 4b01 0214 0014 0008
0008 00e2 804d
3b1f c5b9 9903 0100 00b1
0100 001c 0000
0000 0000 0000 0000 0000
00d0 0300 006a
6176 6178 2f69 6e6a 6563
742f 5175 616c
6966 6965 722e 636c 6173
7350 4b01 0214
0014 0008 0008 00e2 804d
3b5a 8dc7 16fe
0000 00a9 0100 0018 0000
0000 0000 0000
0000 0000 001d 0500 006a
6176 6178 2f69
6e6a 6563 742f 5363 6f70
652e 636c 6173
7350 4b01 0214 0014 0008
0008 00e2 804d
3b59 b11c 4bdd 0000 0067
0100 001c 0000
0000 0000 0000 0000 0000
0061 0600 006a
6176 6178 2f69 6e6a 6563
742f 5369 6e67
6c65 746f 6e2e 636c 6173
7350 4b05 0600
0000 0008 0008 0023 0200
0088 0700 0000
00
IInAppBillingService.aidl
/*
* Copyright (C) 2012 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/licen
ses/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.vending.billing;
import android.os.Bundle;
/**
* InAppBillingService is the
service that provides in-app
billing version 3 and beyond.
* This service provides the
following features:
* 1. Provides a new API to
get details of in-app items
published for the app
including
* price, type, title and
description.
* 2. The purchase flow is
synchronous and purchase
information is available
immediately
* after it completes.
* 3. Purchase information of
in-app purchases is
maintained within the
Google Play system
* till the purchase is
consumed.
* 4. An API to consume a
purchase of an inapp item.
All purchases of one-time
* in-app items are
consumable and thereafter
can be purchased again.
* 5. An API to get current
purchases of the user
immediately. This will not
contain any
* consumed purchases.
*
* All calls will give a
response code with the
following possible values
* RESULT_OK = 0 - success
* RESULT_USER_CANCELED
= 1 - user pressed back or
canceled a dialog
*
RESULT_BILLING_UNAVAILA
BLE = 3 - this billing API
version is not supported for
the type requested
*
RESULT_ITEM_UNAVAILABLE
= 4 - requested SKU is not
available for purchase
*
RESULT_DEVELOPER_ERROR
= 5 - invalid arguments
provided to the API
* RESULT_ERROR = 6 - Fatal
error during the API action
*
RESULT_ITEM_ALREADY_OW
NED = 7 - Failure to purchase
since item is already owned
*
RESULT_ITEM_NOT_OWNED
= 8 - Failure to consume
since item is not owned
*/
interface IInAppBillingService
{
/**
* Checks support for the
requested billing API version,
package and in-app type.
* Minimum API version
supported by this interface is
3.
* @param apiVersion the
billing version which the app
is using
* @param packageName
the package name of the
calling app
* @param type type of
the in-app item being
purchased "inapp" for onetime purchases
*
and "subs" for
subscription.
* @return RESULT_OK(0)
on success, corresponding
result code on failures
*/
int isBillingSupported(int
apiVersion, String
packageName, String type);
* Provides details of a list
of SKUs
* Given a list of SKUs of a
valid type in the skusBundle,
this returns a bundle
* with a list JSON strings
containing the productId,
price, title and description.
* This API can be called
with a maximum of 20 SKUs.
* @param apiVersion
billing API version that the
Third-party is using
* @param packageName
the package name of the
calling app
* @param skusBundle
bundle containing a
StringArrayList of SKUs with
key "ITEM_ID_LIST"
* @return Bundle
containing the following keyvalue pairs
*
"RESPONSE_CODE"
with int value, RESULT_OK(0)
if success, other response
codes on
*
failure as listed
above.
*
"DETAILS_LIST" with
a StringArrayList containing
purchase information
*
in JSON format
similar to:
*
'{ "productId" :
"exampleSku", "type" :
"inapp", "price" : "$5.00",
*
"title :
"Example Title",
"description" : "This is an
example description" }'
*/
Bundle getSkuDetails(int
apiVersion, String
packageName, String type, in
Bundle skusBundle);
/**
/**
* Returns a pending intent
to launch the purchase flow
for an in-app item by
providing a SKU,
* the type, a unique
purchase token and an
optional developer payload.
* @param apiVersion
billing API version that the
app is using
* @param packageName
package name of the calling
app
* @param sku the SKU of
the in-app item as published
in the developer console
* @param type the type
of the in-app item ("inapp"
for one-time purchases
*
and "subs" for
subscription).
* @param
developerPayload optional
argument to be sent back
with the purchase
information
* @return Bundle
containing the following keyvalue pairs
*
"RESPONSE_CODE"
with int value, RESULT_OK(0)
if success, other response
codes on
*
failure as listed
above.
*
"BUY_INTENT" PendingIntent to start the
purchase flow
*
* The Pending intent
should be launched with
startIntentSenderForResult.
When purchase flow
* has completed, the
onActivityResult() will give a
resultCode of OK or
CANCELED.
* If the purchase is
successful, the result data
will contain the following
key-value pairs
*
"RESPONSE_CODE"
with int value, RESULT_OK(0)
if success, other response
codes on
*
failure as listed
above.
*
"INAPP_PURCHASE_DATA" String in JSON format similar
to
*
'{"orderId":"1299976316905
4705758.1371079406387615
",
*
"packageName":"com.examp
le.app",
*
"productId":"exampleSku",
*
"purchaseTime":1345678900
000,
*
"purchaseToken" :
"122333444455555",
*
"developerPayload":"exampl
e developer payload" }'
*
"INAPP_DATA_SIGNATURE" String containing the
signature of the purchase
data that
*
was
signed with the private key
of the developer
*
TODO: change this to appspecific keys.
*/
Bundle getBuyIntent(int
apiVersion, String
packageName, String sku,
String type,
String
developerPayload);
/**
* Returns the current
SKUs owned by the user of
the type and package name
specified along with
* purchase information
and a signature of the data
to be validated.
* This will return all SKUs
that have been purchased in
V3 and managed items
purchased using
* V1 and V2 that have not
been consumed.
* @param apiVersion
billing API version that the
app is using
* @param packageName
package name of the calling
app
* @param type the type
of the in-app items being
requested
*
("inapp" for onetime purchases and "subs"
for subscription).
* @param
continuationToken to be set
as null for the first call, if the
number of owned
*
skus are too many, a
continuationToken is
returned in the response
bundle.
*
This method can be
called again with the
continuation token to get the
next set of
*
owned skus.
* @return Bundle
containing the following keyvalue pairs
*
"RESPONSE_CODE"
with int value, RESULT_OK(0)
if success, other response
codes on
*
failure as listed
above.
*
"INAPP_PURCHASE_ITEM_LI
ST" - StringArrayList
containing the list of SKUs
*
"INAPP_PURCHASE_DATA_LI
ST" - StringArrayList
containing the purchase
information
*
"INAPP_DATA_SIGNATURE_L
IST"- StringArrayList
containing the signatures
*
of
the purchase information
*
"INAPP_CONTINUATION_TO
KEN" - String containing a
continuation token for the
*
next set of in-app purchases.
Only set if the
*
user
has more owned skus than
the current list.
*/
Bundle getPurchases(int
apiVersion, String
packageName, String type,
String continuationToken);
/**
* Consume the last
purchase of the given SKU.
This will result in this item
being removed
* from all subsequent
responses to getPurchases()
and allow re-purchase of this
item.
* @param apiVersion
billing API version that the
app is using
* @param packageName
package name of the calling
app
* @param purchaseToken
token in the purchase
information JSON that
identifies the purchase
*
to be consumed
* @return 0 if
consumption succeeded.
Appropriate error values for
failures.
*/
int consumePurchase(int
apiVersion, String
packageName, String
purchaseToken);
}
Keys.pack
e8d0 04aa 2127 df52 e4c5
3a66 509d 5695
7ffa 0270 cc1c 4395 bf8a
c457 1c0b 45dc
3675 10c5 1789 beee cb09
da83 19f9 bf83
6fb6 b472 50ef 5d2c b678
9ab8 cef3 0488
84f1 0da9 6f4b f156 f3ef
3060 4c95 56f3
14d8 0273 c809 58da 879c
a276 1e0f 54af
5340 16d5 5ea0 b9e7 c009
de98 13e2 a5d7
3186 8637 0cfc 4e33 aa72
feff ecea 17cd
e8d0 04aa 2120 df4a 80ac
1f66 4cf4 72ef
6ef8 0e3d e009 49da 9089
be39 2e12 4fa4
1607 3bd0 54ad f0d6 dd09
c89a 17fe a5d7
2491 9f3f 67fe 4630 b11d
b8dd e0f7 1789
84fc 0fbf 660e 9a60 ef89
196a 569b 5795
58e6 047e c848 6793 bff3
9d71 1211 00a6
1c64 17c5 44e6 a2e7 c562
e98a 7cd6 f1b3
008f 823a 0ce9 4031 b172
97c6 e6f8 3f82
c0d0 0e97 6561 f756 e490
5c43 5793 4395
5ce1 1f69 c206 0abb b28d
a76f 1c12 45b2
7945 10d6 5fe6 83e1 dd71
fee4 25f8 b085
11df a53d 73e4 4b55 9e7b
9dd5 edf1 1783
d0bf 31ae 640e de13 c38b
1f7b 479f 40fa
14d8 0273 c809 58da 879c
a276 1e0f 54af
795f 10c7 52b4 b4e3 de66
91bd 15e9 bf92
6fbd 9731 6daa 7b30 ff40
9bc0 eff8 78bd
d6dc 01bb 0b27 db4a ef97
1567 45f4 70f3
7fe7 183d e309 479f dbbe
bc78 0b0f 54af
795e 11de 58b2 f0d1 dd76
f58a 7cdf b083
108d 9726 6fe5 4155 9e73
d4fb ede8 179f
d7c1 0baa 680a d640 aaa3
0e6c 53d0 39d8
7ff9 0e3d e21e 4f88 dbba
a174 1003 4ea2
0007 0ad9 56b4 b5cf d770
e88f 11e9 8592
088f 9a33 72ef 253a b162
99b8 eaf8 78be
ccda 15fe 5603 df5d aab6
1965 479d 47fa
7a9e 2a7b cb0d 498e b49d
ee78 0e15 45a2
7948 1dd6 52e6 e088 f365
fd8b 15f8 f198
159a 8433 72e3 4031 d550
95df e6f3 0488
d6bf 31ab 731d d345 eb89
7646 4094 56fc
6ab4 2917 f81b 4f88 f1b0
8a13 3513 45dc
3a60 18d6 52e6 84f0 d36d
e887 02e5 be99
6fab 9920 77ff 4a55 9a79
95d0 eff9 16e7
d3dc 06aa 6961 ca52 ee81
1567 45f4 60f7
71fb 1f74 c30f 0abb bf90
a378 090f 4fb8
7947 0cdc 47e6 83ed c76d
ffe4 17f8 a585
0c9d 8326 63f9 6c30 aa79
80b8 c2ec 0281
c195 3688 212a ca43 aab6
0866 509b 39cf
7fe1 1878 a729 5f8e be91
a77d 186c 73ba
1668 0991 73af a3f6 d36d
f88b 7cc8 b496
1197 d616 63e6 4e26 d57b
bbf1 c896 3988
ddbf 20ac 680c d247 e480
0f7a 28b7 5efe
79f1 4b59 c41a 4f99 a590
a177 7735 50b7
0463 59e3 56b2 b588 e276
e98d 1eed a292
45bc 993f 76e6 4a2b ba1d
a4c7 f1ff 1a8c
d7d0 4293 641f d25c eeef
2b6c 40de 7ff6
70ff 615e c204 4693 a290
a177 5d32 59a6
1607 2cc2 52e6 95ec d171
e29e 02e5 be99
6fbd 9a3d 65e1 0f0b b062
97da 89cb 1386
c1e0 12fe 5204 cf5d eeef
3066 4195 56fb
14c5 1e7c c31c 438e a8f3
807c 0512 2a9b
0679 1cd5 3d92 a9f2 d709
d480 13ac 859e
089a d602 73f8 4c37 be64
91b8 caf1 138a
c1bf 2bb0 750e c845 eb89
765a 529b 56fb
14d5 1b6d c809 589b bf9a
ab39 3e0e 41b8
1068 73fc 58b2 bff0 9240
ccce 3de9 a8fd
3590 853b 72e3 4031 ff5a
9bd6 eafa 1b88
d6bf 23b3 6011 d55d aaa4
0c79 02ad 47f0
6cf1 615c c301 479b a590
a177 5d36 4cb7
1068 14d4 59b2 dacf d36a
f5ce 35e3 bd98
17f5 bf36 6aef 0f1e b17e
99d3 f7f5 1d83
84f9 0db1 7161 fe56 ec80
1d7d 479a 13cc
71e1 0579 a738 7ea5 96ab
814c 2d39 749f
2741 3cee 63b4 b1ec c165
f49c 1b86 9398
1091 9537 26cc 402d bc72
fee0 eafb 1a99
84f9 07bf 6f4b fc5c f886
1903 648b 5dfc
6afd 0473 a722 5f97 a1d9
8d76 0808 54b3
0107 35de 58b6 dae3 dc6a
f68f 02e5 be99
6fac 9927 74e9 4a7f 8d72
97c6 89f5 01b4
e1d8 12aa 7861 f551 e080
1f7d 02b8 41fe
73f1 4b4e d909 5e9f f1c8
c44a 1509 57f6
1062 10df 17b4 b5f5 d371
ffe4 30ed bd9b
45be 8226 74e3 4d2a ab72
fefd e1f6 178e
d095 23ad 720e ce39 dc80
0e7a 4b91 5dbf
50e1 067f c81a 20a9 bd9c
ab69 772b 41b1
1a6e 73e3 58b2 b1f6 d723
d78b 10f8 f1bc
0086 fc11 67e7 4a2d be37
a7da e2f7 17e7
f4da 15bb 731e ca13 d980
106c 418a 5af0
709e 3f6f c409 46f0 9e9b
a47c 1e12 0090
016c 14d4 3d96 84dd f551
d4bb 26d3 85be
31b3 b30d 41eb 423a af7b
95cb a3d9 148b
c1d6 16ad 0b02 c96b cf88
0c7d 5bf4 72ea
6afb 4b5b c204 4695 a6f3
8978 1003 0092
1a7f 1cd2 43af bfec b848
fe97 14e3 b085
01df bd37 7f80 6230 a972
99d7 ede8 52b9
ddc5 07d4 480f d656 aaa4
1260 4f9f 47f6
71fa 615b c21a 499f f1b8
ad6d 1409 4ef6
1c63 59e1 45a3 a3f1 b84e
f49a 19fe f1b4
26a8 d619 63f3 251c be64
8092 d0f4 1389
cbc2 689d 690a ca47 ef97
5c38 28ad 50f0
6cf1 4b50 d804 5e93 a195
a77c 0f6c 41b8
1a60 18c5 5ea9 bef1 eb09
c89a 19fc f1b5
22b2 d63d 68aa 6b3a be63
9cb8 c7fd 1f8c
c3d0 6898 6e19 d956 eec5
3166 549b 5efa
70e0 6154 cb07 5897 b08d
a776 136c 73b5
0168 1cdf 1787 b4e8 c770
ef83 13e2 a5fd
219a 8526 74e5 567f 8b6e
84d7 89da 1d83
d095 0cbf 6c0e b076 f286
107c 469b 57bf
58e6 0470 8d29 5e96 b08a
c44a 0903 41bb
535e 0dde 45a3 dac7 d664
fece 4586 9298
0b8b 8433 75fe 250a b17b
9bd1 e8bc 2694
d4d0 689b 6f0f 9a60 e590
126d 28bc 46e6
3ed5 0579 8d3d 599f dbad
bb6d 1214 49b7
1f07 2cdf 5ba9 b3e9 b851
fe99 17fe b5d7
3590 9f3c 72f9 250f b376
8d92 cef3 1688
aefa 00b4 6408 ce39 d991
1d7b 56de 77f6
6de0 0a73 ce0d 20b5 b393
ab7a 0946 66a4
1260 1c91 64b2 b1f6 d723
a8e4 3cf9 bc87
45b9 843d 6baa 682d b062
9ad6 89d8 178b
c5c0 0eaa 212a d45a e784
0860 4d90 39cc
6af5 1969 a722 5f97 a1d9
8f77 140b 41a2
1a62 17bb 76af a2a2 f671
fa89 7cde b491
0c93 9a58 74ef 5936 ba60
b8db edf7 78af
f1ec 2191 4825 b063 deba
3b5b 6dab 63c0
4add 3f51 e837 7d95 a395
aa13 2d32 7f91
2142 2ce1 6892 99d6 fe46
c4bb 18e0 be94
0ef5 a13b 68ee 4028 ac37
a7c6 ecee 17e7
e7da 0eb2 6818 d35c e4c5
2f61 438e 5695
6ef8 0a69 cb07 5897 8289
ab7a 1400 49b5
256c 15c4 52b5 dad6 db6f
f280 11ac 9e91
038c 9326 0cce 5a2d be63
9ddd ed96 2282
d3d0 10ab 714b ee4a fa80
765d 4d8b 50f7
3ed1 0668 c109 5e93 be97
c45e 1c0b 45f6
207d 1cd4 53e6 9deb dc09
d49e 17ef b883
1cf5 a437 60e3 4333 ff43
9ddf e6f3 0799
aeff 17b3 714b fc5c f886
1903 0fd3 1e95
5df5 0678 df09 0abc bd98
bd71 772a 4fb7
1707 29c3 52b5 b5f6 b853
fa8a 12e5 bf90
6fad 9321 63fe 0f2b ba6f
80b8 d0f4 1389
cbc2 4291 670d c956 feef
0c7b 478d 56eb
14d9 027e df07 5995 b78d
ee4e 1408 44b9
047e 59fc 56b4 bbe7 c673
f78f 15e9 dbb1
0a91 8272 75e3 553a d545
9bc6 e2e8 17cd
f6dc 05b6 754b f156 f3ef
2c65 4387 13dc
71fb 0779 c21f 44f0 9796
bc7a 1846 6db7
0b07 3dc3 56b1 f0d1 da62
ff81 0186 9396
0694 d616 63e6 4a2b b678
9a92 d7f4 0088
d7dd 0db2 6561 e95b eb81
137e 02bd 5cf3
71e6 615c c11b 5d9f bd95
c46f 1814 53bf
1c63 3ade 53a3 dac8 c76e
ebce 22e5 bc92
0a8a 8258 43ee 483a ff26
fef3 edf5 1f8c
d0dc 0db0 2138 ca56 ef81
7644 4d88 56bf
5ffa 0270 cc1c 4395 bff3
9e4d 2221 7299
265d 26e5 7e92 9cc7 ed44
e987 1286 8596
0e96 9835 26ce 4e32 be70
9192 d0f3 0783
c0bf 30bb 6702 d65f aaa4
0829 718a 52ed
6a9e 2c6f cc0c 439f bf8d
ee5a 120a 4fa4
794c 0cc5 58e6 84eb de77
91ac 19f9 bf94
00f5 ba33 75fe 0f16 9b1d
a7d1 e2f0 17e7
e7d9 0dad 644b fb5d e388
1d7d 4b91 5dbf
58e6 0a70 c81b 20bc b881
ab7d 5d34 4fa2
1279 10de 59cc 80d6 ed44
c9a1 23dc 8ea3
2cab ba17 59cc 5a31 bc63
9ddd ed96 339e
d7d0 16d4 5104 c95a fe8c
1367 28b9 41f0
6be4 4b54 e962 7999 b095
ab39 3009 44bf
1564 1cc3 3d81 a2ed c76d
ffce 35e3 bd9b
0c8c 9f3d 6880 7f0b 8050
a6fd d6cc 2db9
ede1 2e9b 5e38 d546 e481
7648 46de 71fe
70fa 0e6f 8d2e 589f a0d7
c45b 080f 4cb2
5349 18c5 52cc 9ce3 d066
f7ce 25ef b09b
00f5 b73c 6fe7 4e2b b678
9a92 c1f9 1a8c
d2dc 0dab 7361 e95a ee80
0f29 669b 5ffa
6afd 0473 8d3c 4288 b48a
a676 1102 2a86
1278 0ad4 1785 a5f0 c066
f59a 56db be85
099b fc14 69f8 4c3a ff5e
9ad1 f1f9 139e
c1bf 2eb7 770e c939 cd97
156d 02ad 5ae5
7b9e 287c c31e 4b89 f18a
a763 186c 64b7
1e6c 1ed4 17a2 b5ee d37a
91b9 13ed a198
0bf5 a53d 73f8 4c3a 8c7e
8ed7 89df 1380
c1c7 03fe 5206 d55c fe8d
764b 439d 58f8
6cfb 1e73 c948 7999 b497
ab13 3c02 0094
1263 17d4 45cc 9af7 df73
bba5 13f5 dbb6
0b98 833e 67f8 0f09 ba7b
9bd1 eae8 0be7
f7dc 18bb 0b38 ce5a e98e
5c5d 4dde 76fb
79f1 614d c109 5e9c be8b
a339 3b14 49b5
0764 16df 3d87 bceb d56d
bbad 17e1 b485
04df b43d 74ee 4a2d ac1d
98dd e0f7 78ac
d4c5 0ebb 2102 f560 aaa4
0c79 02ad 47f0
6cf1 6151 c20b 41f0 9c98
b639 2f03 46bf
1f61 73f2 45a3 b1f6 db6c
f5ce 3fe2 b592
1df5 a037 6ae5 4c36 ab6e
d4f6 f1fd 15e7
ead4 14b7 660a ce5a e58b
5c4b 578a 47f0
709e 3b49 f22f 78b5 84a9
914d 3432 6c93
2c4a 18dc 52b6 bce3 cb23
eb9c 19fc b485
1196 9321 0cda 7b00 9845
bbe7 d3c3 26a4
f0f9 2781 5119 d543 ef97
0860 478d 39d9
71fa 1f17 ee09 4699 a495
af6d 1802 0085
1a77 1cbb 70a7 bde7 924a
dfe4 21ed ba92
108f d616 6ff9 5b3e b174
91b8 c7f3 5283
d1c1 42aa 6904 cf50 e2ef
2c5d 7db9 61d0
4bc4 3449 e43c 66bf 8ebe
af74 1846 6fa0
167f 59f4 51a0 b5e1 c670
91a2 17ee b49b
45b0 9034 75ef 5b55 be63
80c0 eafe 0799
c1fb 03b3 6461 fe41 eb92
5c5a 568c 5cf4
7b9e 2270 cc0f 4fda 829c
a27c 1e12 45b2
7949 0bd0 40e6 97f0 d367
f28b 18f8 dba7
31a0 b100 49df 7f00 8b5e
a0fe c6c3 3e8c
c6d0 0ead 0b2a de13 c38b
086c 508d 47f6
6afd 0a71 a738 7ea5 96ab
814c 2d39 749f
2741 3cee 7eab b1e5 d709
d488 10ff b483
6fad 9325 67f8 4b7f 9c78
9ddc f096 3181
cdd6 09fe 5204 cf5d eeef
356d 4e9b 13de
70fd 067c d901 4594 f1bf
bc78 1003 53dc
1263 10dc 56b2 b9ed dc70
c3e4 39fe b892
0b8b 9726 6fe5 4155 8c74
9bc0 e6bc 2694
d4d0 688a 730a d958 e38b
1b03 7195 5aef
14c7 037c df0d 0aa9 b28b
ab7c 136c 75b8
1f64 14d8 43a3 b4a2 e770
fee4 26d8 8eb0
37b0 a302 59de 660b 9352
abf3 edf5 1f8c
d0dc 0db0 0b24 d859 ef86
0829 63f4 60fa
7fe6 0875 8d3a 4b9e b88c
bd13 2e09 4cb9
7948 1dd6 52e6 e288 f16b
fa9c 17ef a592
17f5 b736 26c4 4a2b a878
86d9 89db 1380
c195 31ae 640e de13 c784
0403 658c 5cea
70f0 4b49 c51a 4f89 b996
a27d 7705 48bf
1f69 0bd4 59cc 91ec d576
f78f 04ac 8792
0990 953b 72f3 0f12 b073
9dd4 eaf9 00e7
f6da 16bf 7502 d55d aaa1
0e68 45f4 74ed
77f0 4b4f c21c 4b8e b896
a013 2b0f 53bf
1164 15d8 43bf f0d6 da71
fe9d 1ee3 bd93
6fac 823d 74ef 0f16 bb72
9ac6 eafa 1b88
d6bf 36bb 791f b060 e38b
1b65 47de 66ec
7b9e 3875 c207 5eda 9a9c
b713 350f 44b2
1663 73d9 52af b7ea c609
f480 13db b08e
2690 9a3e 6ff9 4630 b141
91d1 f7f3 00e7
f3d4 09bb 213e ca39 d995
1d7e 4cde 72fc
6afd 0473 a72a 5f96 bd9c
ba39 3c08 49bb
1279 10de 59cc 84eb df66
91ba 17e7 b899
02df b233 6beb 483a ff56
9adb eeb2 78a9
c1c6 0bb9 6f4b e95a f080
7645 4d91 43bf
53e1 1874 ce62 658a b497
ee58 130f 4db7
0764 16df 1780 a2e3 df66
e8e4 37ea b792
068b 9336 26cb 5c2c ba63
fef3 e0e8 1b82
cabf 32b2 6012 c913 c880
1a66 509b 13cd
7bf0 026f c80b 5ef0 959c
a27c 0903 009f
1d7d 0cc5 1789 b2e8 d760
efe4 3ae3 b29c
009b d61b 6beb 483a d556
81c6 ecbc 3e82
c7de 6893 7418 d350 80a2
1d64 47de 72f1
79f8 0e3d e901 589f b28d
a776 136c 6db7
0b2d 2ac1 52a3 b488 e56c
e982 1286 8185
008c 823b 67e4 250a 961d
bfd7 e6ec 52bb
c1d9 0dbd 681f c339 dd8c
187d 4af4 72ef
6ef8 027e cc1c 4395 bfd9
8078 1003 2a84
1661 1cd0 44a3 f0d1 dd76
f58a 7cc1 b090
0c9c d601 72eb 5b3a d551
86db e0e8 1b82
cabf 2bb0 681f 9a60 ef86
0860 4d90 39cf
4acb 2c4f e23d 7aa5 85b0
9a55 3839 72b3
1564 15dd 3d8a b9ef db77
bba0 03e1 b392
17f5 b930 6cef 4c2b ff51
86d3 eef9 52bf
c1d6 16d4 450e dc56 eb91
196d 02bf 5df6
73f5 1f74 c206 208a be90
a06d 0e6c 64bf
0168 1ac5 178b bff4 d76e
fe80 0286 8283
1790 9d37 26c9 4033 b065
feff ecea 17cd
f1c5 4295 6412 b07e e593
1929 7097 54f7
6ab4 2078 d462 639e bd9c
ee4a 1213 4eb2
794c 0dc5 45a7 b3f6 db6c
f5ce 30e3 a394
00f5 b237 75fe 4631 be63
9ddd ed96 3185
c5c5 16bb 734b 8839 c587
166c 418a 13cb
67e4 0e17 e806 4eda 9590
bd6d 1c08 43b3
7945 1cd0 5bb2 b888 e06c
ef8f 02e5 be99
6fab 9f3f 63aa 783e ad67
fef6 e6fd 0685
84e6 0dab 6f0f b061 e591
1d7d 4b91 5dbf
53fb 0f74 cb01 4f88 dbb6
ac73 1805 54f6
357f 18dc 52e6 83f6 d377
fece 4486 81a3
3ab8 a41d 53da 700b 9643
b8f7 dcd1 1d83
c1c1 0ba4 601f d35c e4ef
2c5d 7db9 61d0
4bc4 3449 e43c 66bf 8eb4
a16f 180b 45b8
0707 37de 43e6 95ec dd76
fc86 56cf a485
179a 9831 7faa 7b3a a763
fefe e2fe 1781
84e3 07ac 7502 d952 e6c5
2f79 439d 5af1
799e 3869 df07 419f f1ae
a77d 090e 2ab8
1260 1cfe 5982 b5f4 db60
fee4 31ed bc92
45b0 8037 74aa 6b3a b376
8db8 f5fd 0084
c5d7 0ebb 570a d646 efef
157a 6793 43eb
679e 247f c70d 498e f1bf
bc78 1003 0085
076c 0dd4 17f2 dae0 c76d
ff82 13c5 95fd
168b 9726 6380 6830 b070
98d7 a3cc 1e8c
dd95 31aa 6e19 df3
PTModelAnimation.0.attribu
tes.pack
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a 4821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a 5e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a 6d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a 7921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a a721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a db21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
9999 9acd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3ecc cccd cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a f821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0b e021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0b e921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0c 3c21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0f a121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0f ac21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0f b521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd10 1721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd10 2621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd10 4021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd12 4121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd13 d821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd14 f721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd15 1e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3d
cccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d88 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd15 3221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3d
cccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d88 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd17 9921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd17 a221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd18 fe21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 1121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 2321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 4e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 6d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
4ccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3f08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 d221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 e421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1a 1d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1a 4121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e6e eeef cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1a cd21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1b 6221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 2421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 3021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 3921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 4821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 5121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 6a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 8b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 9621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c d021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c ea21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c f321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1d 3f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1f 0621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1f 5d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3fcc cccd cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1f 6a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1f 7621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd20 2c21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd20 a121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
4ccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd20 b321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd20 bc21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd25 3f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd25 6921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd25 8221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
4ccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c2cd 0155 c2cd 0156
c2cc a383 0aca
3e88 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd26 5621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3ecc cccd cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd27 6921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3ebb bbbc cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd2b 7d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd2e 4d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd2e 8a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
9999 9acd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e88 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd30 5e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd36 2f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd38 7321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd39 2f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd40 7021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd40 a321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd43 e721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
9999 9acd 0155 ca00 0000
00cd 0156 c263
830a c2cd 0155 c2cd 0156
c2cc a383 0aca
4040 0000 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd44 8a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd44 9e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd44 dc21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd52 7121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3ebb bbbc cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5b 2e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5b 4a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5b 5721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5b c421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5b ed21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5c 2a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3ebb bbbc cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd63 af21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6a f421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6a fd21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 1021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 2621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
cccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 2f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 4121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c2cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 6f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 7b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 8721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 9321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b a321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b b621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b c421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b d221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b de21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b ea21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b fc21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6c 0821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 db21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e a221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e ab21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e ce21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3f19 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e dd21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e e621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e f221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e fb21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 0721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 1021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 4a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 5321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 5f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 6b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f b721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f c021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f ca21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f d321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f dd21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f e621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f ef21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd70 0c21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd71 3c21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd71 4821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 3521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 3f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 4b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 5f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 8721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 9121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 9b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 a921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 b721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 c721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 d121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 e221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 f921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 1421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 1e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 2821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 3221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 4021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 4f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 5921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 b921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 c721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 d521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 e121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 f521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 ff21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 0b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 1521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 1f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 2921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 3721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 4121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 4b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 5b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 7f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 9b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7d 6e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3eaa aaab cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e 6821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e 8121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e 9321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e 9c21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e a521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e ae21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e bb21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e ca21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e f521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7f 7521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7f 7e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7f 8721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7f 9021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7f 9921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd80 9521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd80 b021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd81 0221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd81 bc21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
9999 9acd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e88 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd81 ff21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
PTModelAnimation.0.conne
ctions.pack
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a 4821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a 5e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a 6d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a 7921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a a721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a db21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
9999 9acd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3ecc cccd cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0a f821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0b e021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0b e921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0c 3c21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0f a121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0f ac21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd0f b521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd10 1721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd10 2621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd10 4021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd12 4121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd13 d821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd14 f721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd15 1e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3d
cccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d88 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd15 3221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3d
cccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d88 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd17 9921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd17 a221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd18 fe21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 1121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 2321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 4e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 6d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
4ccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3f08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 d221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 e421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1a 1d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1a 4121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e6e eeef cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1a cd21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1b 6221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 2421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 3021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 3921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 4821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 5121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 6a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 8b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c 9621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c d021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c ea21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1c f321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1d 3f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1f 0621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1f 5d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3fcc cccd cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1f 6a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd1f 7621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd20 2c21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd20 a121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
4ccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd20 b321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd20 bc21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd25 3f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd25 6921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd25 8221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
4ccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c2cd 0155 c2cd 0156
c2cc a383 0aca
3e88 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd26 5621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3ecc cccd cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd27 6921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3ebb bbbc cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd2b 7d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd2e 4d21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd2e 8a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
9999 9acd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e88 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd30 5e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd36 2f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd38 7321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd39 2f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd40 7021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd40 a321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd43 e721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
9999 9acd 0155 ca00 0000
00cd 0156 c263
830a c2cd 0155 c2cd 0156
c2cc a383 0aca
4040 0000 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd44 8a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd44 9e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd44 dc21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd52 7121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3ebb bbbc cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5b 2e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5b 4a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5b 5721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5b c421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5b ed21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd5c 2a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3ebb bbbc cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd63 af21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6a f421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6a fd21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 1021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 2621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
cccc cdcd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 2f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 4121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c2cd 0155 c2cd 0156
c2cc a383 0aca
3e99 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 6f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 7b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 8721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b 9321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b a321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b b621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b c421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b d221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b de21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b ea21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6b fc21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6c 0821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd19 db21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e a221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e ab21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e ce21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3f19 999a cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e dd21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e e621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e f221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6e fb21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 0721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 1021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 4a21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 5321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 5f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f 6b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f b721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f c021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f ca21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f d321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f dd21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f e621
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd6f ef21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd70 0c21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd71 3c21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd71 4821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 3521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 3f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 4b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 5f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 8721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 9121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 9b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 a921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 b721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 c721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 d121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 e221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd75 f921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 1421
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 1e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 2821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 3221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 4021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 4f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 5921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 b921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 c721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 d521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 e121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 f521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd76 ff21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 0b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 1521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 1f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 2921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 3721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 4121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 4b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 5b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 7f21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd77 9b21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7d 6e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
0000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3eaa aaab cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e 6821
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e 8121
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e 9321
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e 9c21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e a521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e ae21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e bb21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e ca21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7e f521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7f 7521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7f 7e21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7f 8721
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7f 9021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd7f 9921
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd80 9521
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd80 b021
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd81 0221
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd81 bc21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3e
9999 9acd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3e88 8889 cd01 55ca 0000
0000 cd01 56c2
8602 810a a02a cd81 ff21
b050 544d 6f64
656c 416e 696d 6174 696f
6e55 830a ca3f
8000 00cd 0155 ca00 0000
00cd 0156 c263
830a c3cd 0155 c2cd 0156
c2cc a383 0aca
3d08 8889 cd01 55ca 0000
0000 cd01 56c2
PTModelAssetCharacter.0.c
onnections.pack
ƒ
Ù-kisspng-pixel-art-spriterocks-5abdc79be055b5*Í
l!´PTModelAssetObstacleƒ
¤tree*Í
à!´PTModelAssetObs
tacleƒ
£car*Í
G!´PTModelAssetObstacleƒ
¶drawing-bushes-pixel-4*Í
]!´PTModelAssetObstacleƒ
³pine-tree-pixel-png*Í
x!´PTModelAssetObstacleƒ
²Layer_1 - Copy (2)*Í
¦!´PTModelAssetObstacleƒ
¡1*Í
Ú!´PTModelAssetObstacleƒ
ÙJkisscc0-hardwood-woodstain-lumber-pixel-art-pixellog-side5b713829061797*Í !´PTMod
elAssetObstacleƒ
¯2e29f43a603936d*Í
÷!´PTModelAssetObstacleƒ
¯8fd9223acb89db4*Í
ß!´PTModelAssetObstacleƒ
ªssssssssss*Í
è!´PTModelAssetObstacleƒ
¯8fd9223acb89db4*Í;!´PTMo
delAssetObstacleƒ
³d2081b1f1b727a5
(1)*Í«!´PTModelAssetObstacl
eƒ
¦middle*Í´!´PTModelAssetOb
stacleƒ
¨Platform*Ì€!´PTModelAsset
Obstacleƒ
¥back3*Í!´PTModelAssetObs
tacleƒ
¯dca2574a41f6294*Í%!´PTM
odelAssetObstacleƒ
¥spike*Í?!´PTModelAssetObs
tacleƒ
§Layer_1*Í×!´PTModelAsset
Obstacleƒ
¯bda95fab1079226*Íö!´PTM
odelAssetObstacleƒ
§unnamed*Í@!´PTModelAss
etObstacleƒ
£123*Í!´PTModelAssetObsta
cleƒ
¤1234*Í1!´PTModelAssetObs
tacleƒ
¤door*Í¡!´PTModelAssetObst
acleƒ
¡6*Íý!´PTModelAssetObstacl
eƒ
¡5*Í!´PTModelAssetObstacleƒ

¤ffff*Í"!´PTModelAssetObsta
cleƒ
¯24d7d2439776568*ÍM!´PT
ModelAssetObstacleƒ
®Layer_1 Copy*Íl!´PTModelAssetObsta
cleƒ
ªUntitled3*ÍÑ!´PTModelAssetObstacle
ƒ
¯c95d720d1b66c9c*ÍÚ!´PTM
odelAssetObstacleƒ
¡4*Í!´PTModelAssetObstacleƒ

¥spear*ÍÌ!´PTModelAssetObs
tacleƒ
¡5*Ía!´PTModelAssetObstacl
eƒ
§UPPLONG*ÍG!´PTModelAss
etObstacleƒ
ªLong
stick*Í#!´PTModelAssetObsta
cleƒ
¤4log*Í8!´PTModelAssetObst
acleƒ
¤2log*Í/!´PTModelAssetObst
acleƒ
¨UPPLONG3*ÍP!´PTModelAss
etObstacleƒ
§SPIKE
6*Íi!´PTModelAssetObstacleƒ

ªLONGSIDLOG*ÍŠ!´PTModelA
ssetObstacleƒ
¦4SPIKE*Í•!´PTModelAssetO
bstacleƒ
§4UPLONG*ÍÏ!´PTModelAsset
Obstacleƒ
¥LOGUP*Íé!´PTModelAssetO
bstacleƒ
§2LOGUP1*Íò!´PTModelAsse
tObstacleƒ
§3STICKS*Í>!´PTModelAsset
Obstacleƒ
¯aecbd57c437156e*Í!´PTModelAssetObstacleƒ
§Layer_0*Í\!´PTModelAssetObstacleƒ
¥water*Íi!´PTModelAssetObstacleƒ
¤raft*Íu!´PTModelAssetObstacleƒ
¥hole1*Í
+!´PTModelAssetObstacleƒ
¥check*Í !´PTModelAssetOb
stacleƒ
ªssssssssss*Í%>!´PTModelAss
etObstacleƒ
²Layer_1 - Copy
(2)*Í.L!´PTModelAssetO
bstacleƒ
¤eart*Í0]!´PTModelAssetObs
tacleƒ
£Saw*Í6.!´PTModelAssetObs
tacleƒ
¬1 - Copy
(2)*Í8r!´PTModelAssetObstac
leƒ
¡1*Í9.!´PTModelAssetObstacl
eƒ
¬Wooden
Crate*Í@o!´PTModelAssetO
bstacleƒ
­ssssssssss123*Í@¢!´PTMode
lAssetObstacleƒ
¡1*ÍCæ!´PTModelAssetObsta
cleƒ
¥eart1*Í[!´PTModelAssetObstacleƒ
¢10*ÍD‰!´PTModelAssetObs
tacleƒ
§Layer15*ÍD!´PTModelAsse
tObstacleƒ
©standwell*ÍDÛ!´PTModelAs
setObstacleƒ
§Graph1
*Í[I!´PTModelAssetObstacleƒ

³graph-papertexture*Í[V!´PTModelAssetO
bstacleƒ
§Layer_1*Í
!´PTModelAssetObstacleƒ
¢up*Í[Ã!´PTModelAssetObst
acleƒ
®LEFT AND
RIGHT*Í[ì!´PTModelAssetObs
tacleƒ
§Sailing*Íc®!´PTModelAssetO
bstacleƒ
¦target*Íjê!´PTModelAssetO
bstacleƒ
«targetarrow*Íjó!´PTModelA
ssetObstacleƒ
¤Rope*Íp!´PTModelAssetObs
tacleƒ
¥arrow*Íwš!´PTModelAssetO
bstacleƒ
§Layer_1*Í}m!´PTModelAsse
tObstacleƒ
¨texture1*Í~F!´PTModelAsse
tObstacleƒ
¦Sprite*Í~€!´PTModelAssetO
bstacleƒ
¯5b779b2bfe422c2*Í~’!´PTM
odelAssetObstacleƒ
°5b779b2bfe422c22*Í~›!´PT
ModelAssetObstacleƒ
°5b779b2bfe422c21*Í~¤!´PT
ModelAssetObstacleƒ
¯CHAv_J5W8AEOUw*Í~­!´PTModelAssetObstacleƒ

¯CHAv_J5W8AEOUw*Í~º!´PTModelAssetObstacleƒ

¦latern*Í~É!´PTModelAssetO
bstacleƒ
¨TiedROpe*Í~Ü!´PTModelAss
etObstacleƒ
¦botton*Í•t!´PTModelAssetO
bstacleƒ
¦handle*Í•}!´PTModelAssetO
bstacleƒ
«BorderRight*Í•†!´PTModelA
ssetObstacleƒ
ªBorderLeft*Í•!´PTModelAs
setObstacleƒ
°CageDesignthorug*Í•˜!´PTM
odelAssetObstacleƒ
¤DAGE*Í€”!´PTModelAssetO
bstacleƒ
¥DAGE1*Í€¯!´PTModelAsset
Obstacleƒ
¥Stand*́!´PTModelAssetOb
stacleƒ
§Layer_1*́»!´PTModelAsset
Obstacleƒ
¦Stand1*́þ!´PTModelAsset
Obstacle
Download