Update from latest

pull/124/head
Baohua Yang 2018-08-29 14:52:32 +08:00
parent beb7610d52
commit a666b44664
23 changed files with 25329 additions and 24899 deletions

View File

@ -42,6 +42,7 @@ ready: # create/join channel, install/instantiate cc
make stop
# make clean_config # Remove existing crypto-config and channel artifacts.
make gen_config # Will ignore if local config path exists
make start
if [ "$(HLF_MODE)" = "dev" ]; then \
@ -75,8 +76,10 @@ ready: # create/join channel, install/instantiate cc
# channel related operations
channel_test: test_channel_create test_channel_join test_channel_list test_channel_getinfo
# chaincode related operations
cc_test: test_cc_install test_cc_instantiate test_cc_invoke_query
restart: stop start
start: # bootup the fabric network
@ -86,14 +89,16 @@ start: # bootup the fabric network
stop: # stop the fabric network
@echo "Stop the fabric network with ${COMPOSE_FILE}..."
@docker-compose -f ${COMPOSE_FILE} down >& /tmp/docker-compose.log # Stop a fabric network
@docker-compose -f ${COMPOSE_FILE} down >& /tmp/docker-compose.log
chaincode_dev: restart chaincode_init test_cc_peer0 stop
################## Channel testing operations ################
test_channel_list: # List the channel that peer joined
@echo "List the joined channels"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_list.sh"
test_channel_getinfo: # Get info of a channel
@echo "Get info of the app channel"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_channel_getinfo.sh"
@ -166,11 +171,14 @@ test_fetch_blocks: # test fetching channel blocks fetch
@echo "Test fetching block files"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_fetch_blocks.sh"
temp: # test temp instructions, used for experiment
@echo "Test experimental instructions"
@docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_temp.sh"
################## Env setup related, no need to see usually ################
setup: # setup the environment
bash scripts/env_setup.sh # Installing Docker and Docker-Compose
bash scripts/download_images.sh # Pull required Docker images
check: # Check shell scripts grammar
@echo "Check shell scripts grammar"
@ -182,6 +190,7 @@ clean: # clean up containers
@-docker ps -a | awk '$$2 ~ /dev-peer/ { print $$1 }' | xargs -r -I {} docker rm -f {}
@-docker images | awk '$$1 ~ /dev-peer/ { print $$3 }' | xargs -r -I {} docker rmi -f {}
echo "May manually clean the crypto-config and $(MODE)/channel-artifacts"
clean_config: clean_channel_artifacts clean_crypto_config
env_clean: # clean up environment
@ -231,6 +240,7 @@ clean_channel_artifacts: # clean channel related artifacts
clean_crypto_config: # clean config artifacts
rm -rf crypto-config
rm -rf org3/crypto-config
download: # download required images
@echo "Download Docker images"
bash scripts/download_images.sh

View File

@ -178,6 +178,7 @@ services:
- ./solo/channel-artifacts:/tmp/channel-artifacts
- ./examples:/opt/gopath/src/examples
#deprecated
event-listener:
extends:
file: base.yaml
@ -190,13 +191,13 @@ services:
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.Org1.example.com/msp
volumes:
- ./scripts:/tmp/scripts
- ./crypto-config.yaml:/etc/hyperledger/fabric/crypto-config.yaml
- ./crypto-config:/etc/hyperledger/fabric/crypto-config
- ./solo/channel-artifacts:/tmp/channel-artifacts
- ./solo/configtx.yaml:/etc/hyperledger/fabric/configtx.yaml
- ./examples:/opt/gopath/src/github.com/hyperledger/fabric/examples
- ./solo/channel-artifacts:/tmp/channel-artifacts
- ./examples:/opt/gopath/src/examples
command: bash -c 'while true; do sleep 1; block-listener -events-address=peer0.org1.example.com:7053 -events-mspdir=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/ -events-mspid=Org1MSP; done'
#command: bash -c 'while true; do sleep 20170504; done'

View File

@ -46,12 +46,14 @@ setOrdererEnvs () {
# Set global env variables for fabric cli, after setting:
# client is the admin as given org
# TLS root cert is configured to given peer's
# TLS root cert is configured to given peer's tls ca
# remote peer address is configured to given peer's
# CORE_PEER_LOCALMSPID=Org1MSP
# CORE_PEER_ADDRESS=peer0.org1.example.com:7051
# CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
# CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
# CORE_PEER_LOCALMSPID=Org1MSP # local msp id to use
# CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp # local msp path to use
# CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt # local trusted tls ca cert
# CORE_PEER_ADDRESS=peer0.org1.example.com:7051 # remote peer to send proposal to
# Usage: setEnvs org peer
setEnvs () {
local org=$1 # 1 or 2
@ -65,7 +67,7 @@ setEnvs () {
t="\${ORG${org}_ADMIN_MSP}" && export CORE_PEER_MSPCONFIGPATH=`eval echo $t`
t="\${ORG${org}_PEER${peer}_TLS_ROOTCERT}" && export CORE_PEER_TLS_ROOTCERT_FILE=`eval echo $t`
env |grep CORE_PEER
#env |grep CORE
}
checkOSNAvailability() {
@ -191,6 +193,10 @@ getShasum () {
[ ! $# -eq 1 ] && exit 1
shasum ${1} | awk '{print $1}'
}
# List the channel that the peer joined
# E.g., for peer 0 at org 1, will do
# channelList 1 0
channelList () {
local org=$1
local peer=$2
@ -205,12 +211,18 @@ channelList () {
echo "=== Done to list the channels that org${org}/peer${peer} joined === "
fi
}
# Get the info of specific channel, including {height, currentBlockHash, previousBlockHash}.
# E.g., for peer 0 at org 1, get info of business channel will do
# channelGetInfo businesschannel 1 0
channelGetInfo () {
local channel=$1
local org=$2
local peer=$3
echo "=== Get channel info of ${channel} with id of org${org}/peer${peer} === "
setEnvs $org $peer
peer channel getinfo -c ${channel} >&log.txt
rc=$?
[ $rc -ne 0 ] && cat log.txt
@ -354,7 +366,8 @@ chaincodeInstall () {
local version=$4
local path=$5
[ -z $org ] && [ -z $peer ] && [ -z $name ] && [ -z $version ] && [ -z $path ] && echo_r "input param invalid" && exit -1
echo "=== Install Chaincode $name:$version ($path) on org ${org}/peer $peer === "
echo "=== Install Chaincode on org ${org}/peer ${peer} === "
echo "name=${name}, version=${version}, path=${path}"
setEnvs $org $peer
peer chaincode install \
-n ${name} \
@ -371,7 +384,7 @@ chaincodeInstall () {
# chaincodeInstantiate channel org peer name version args
chaincodeInstantiate () {
if [ "$#" -gt 8 -a "$#" -lt 6 ]; then
echo "Wrong param number for chaincode instantaite"
echo_r "Wrong param number for chaincode instantaite"
exit -1
fi
local channel=$1
@ -380,9 +393,20 @@ chaincodeInstantiate () {
local name=$4
local version=$5
local args=$6
local collection_config="" # collection config file path for sideDB
local policy="OR ('Org1MSP.member','Org2MSP.member')" # endorsement policy
if [ ! -z "$7" ]; then
collection_config=$7
fi
if [ ! -z "$8" ]; then
policy=$8
fi
setEnvs $org $peer
echo "=== chaincodeInstantiate for channel ${channel} by org $org/peer $peer ===="
echo "=== chaincodeInstantiate for channel ${channel} on org $org/peer $peer ===="
echo "name=${name}, version=${version}, args=${args}, collection_config=${collection_config}, policy=${policy}"
# while 'peer chaincode' command can get the orderer endpoint from the peer (if join was successful),
# lets supply it directly as we know it using the "-o" option
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
@ -392,6 +416,8 @@ chaincodeInstantiate () {
-n ${name} \
-v ${version} \
-c ${args} \
-P "${policy}" \
--collections-config "${collection_config}" \
>&log.txt
else
peer chaincode instantiate \
@ -400,8 +426,8 @@ chaincodeInstantiate () {
-n ${name} \
-v ${version} \
-c ${args} \
-P ${policy} \
--collections-config ${collection_config} \
-P "${policy}" \
--collections-config "${collection_config}" \
--tls \
--cafile ${ORDERER_TLS_CA} \
>&log.txt
@ -421,7 +447,8 @@ chaincodeInvoke () {
local name=$4
local args=$5
[ -z $channel ] && [ -z $org ] && [ -z $peer ] && [ -z $name ] && [ -z $args ] && echo_r "input param invalid" && exit -1
echo "=== Invoke transaction on peer$peer in channel ${channel} === "
echo "=== chaincodeInvoke to orderer by id of org${org}/peer${peer} === "
echo "channel=${channel}, name=${name}, args=${args}"
setEnvs $org $peer
# while 'peer chaincode' command can get the orderer endpoint from the peer (if join was successful),
# lets supply it directly as we know it using the "-o" option
@ -457,7 +484,8 @@ chaincodeQuery () {
local args=$5
[ -z $channel ] && [ -z $org ] && [ -z $peer ] && [ -z $name ] && [ -z $args ] && echo_r "input param invalid" && exit -1
[ $# -gt 5 ] && local expected_result=$6
echo "=== Querying on org $org/peer $peer in channel ${channel}... === "
echo "=== chaincodeQuery to org $org/peer $peer === "
echo "channel=${channel}, name=${name}, args=${args}"
local rc=1
local starttime=$(date +%s)
@ -479,18 +507,20 @@ chaincodeQuery () {
let rc=1
echo_b "$VALUE != ${expected_result}, will retry"
fi
fi
if [ $rc -ne 0 ]; then
else
cat log.txt
fi
if [ $rc -ne 0 ]; then
cat log.txt
sleep 2
fi
fi
done
# rc==0, or timeout
if [ $rc -eq 0 ]; then
echo "=== Query on peer$peer in channel ${channel} is successful === "
echo "=== Query on org $org/peer$peer in channel ${channel} is successful === "
else
echo_r "=== Query result on peer$peer is INVALID, run `make stop clean` to clean ==="
echo_r "=== Query on org $org/peer$peer is INVALID, run `make stop clean` to clean ==="
exit 1
fi
}

View File

@ -0,0 +1,41 @@
#!/bin/bash
# Importing useful functions for cc testing
if [ -f ./func.sh ]; then
source ./func.sh
elif [ -f scripts/func.sh ]; then
source scripts/func.sh
fi
## Install chaincode on all peers
CC_NAME="chaincode01"
CC_PATH="examples/chaincode/go/chaincode01"
CC_INIT_ARGS='{"Args":["init",""]}'
CC_INVOKE_ARGS='{"Args":["createOrder","OD502","OD501","Order_Created"]}'
CC_QUERY_ARGS='{"Args":["queryByParentOrder","OD501"]}'
echo_b "=== Installing chaincode ${CC_NAME} on all 4 peers... ==="
echo before comment
: <<'END'
for org in "${ORGS[@]}"
do
for peer in "${PEERS[@]}"
do
chaincodeInstall $org $peer ${CC_NAME} ${CC_INIT_VERSION} ${CC_PATH}
done
done
echo_g "=== Install chaincode done ==="
echo_b "Instantiate chaincode"
chaincodeInstantiate "${APP_CHANNEL}" 1 0 ${CC_NAME} ${CC_INIT_VERSION} ${CC_INIT_ARGS}
END
echo_b "Invoke chaincode"
chaincodeInvoke ${APP_CHANNEL} 1 0 ${CC_NAME} ${CC_INVOKE_ARGS}
echo_b "Query chaincode"
chaincodeInvoke ${APP_CHANNEL} 1 0 ${CC_NAME} ${CC_QUERY_ARGS}

View File

@ -698,13 +698,13 @@
},
"signatures": [
{
"signature": "MEQCIDOl61CxmZnjAjnHz4fmYes8TcojZuX2+XtzdEfOhf4eAiBKlJwk/AtukeV8pEgq/2JcCnnSSz3ZNXxkVm7dSjB5AQ==",
"signature": "MEQCIBp8nm8jwJd/BQWNbFm+F4op9vuiZkMUno0bITzoAjhmAiBX06T3r/Gpy0hVIrPjxxPKKrYBZi66uzmm+geKafEDxQ==",
"signature_header": {
"creator": {
"id_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNHakNDQWNDZ0F3SUJBZ0lSQUlGd0tEeURCdXh6ZWg4NGljSmh0ejh3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpJdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekl1WlhoaGJYQnNaUzVqYjIwd0hoY05NVGd3TkRBeU1ESXpNRE0zV2hjTk1qZ3dNek13TURJek1ETTMKV2pCYk1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFZk1CMEdBMVVFQXd3V1FXUnRhVzVBYjNKbk1pNWxlR0Z0Y0d4bExtTnZiVEJaCk1CTUdCeXFHU000OUFnRUdDQ3FHU000OUF3RUhBMElBQk1SQ2lBVEQwNHI3WEE1MlR1d21rbVFpb1BNNDNrWjAKR29mVUVwazZMM3BLc0lXZDRyOEVyY1l2aGpKOUZ3TC9aa1FwamJmVWczTDVOTXZQVVlzRUJOcWpUVEJMTUE0RwpBMVVkRHdFQi93UUVBd0lIZ0RBTUJnTlZIUk1CQWY4RUFqQUFNQ3NHQTFVZEl3UWtNQ0tBSU14bWdiWEIySDQyClpaSElxZk1yUm1ZTXJGTlFjRVFMWkRNQXpSNllTT25oTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFESXFIbkYKTVRueENhY3VqWFExSWRNYjRQM1dQNkFwRzJvNDFmODlzWHQ0RGdJZ1pHR2lIckQ2eG5nMEdIQ1R6dVpjay9keApEVTRteGhRT3piQmxOOUJSaXRVPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==",
"mspid": "Org2MSP"
},
"nonce": "2yjv89nxowCrMWBDCN7CyFkQN9448JVC"
"nonce": "eFwruX1hTPSqznJutSpLxT4rhgUrBYH4"
}
}
]
@ -713,7 +713,7 @@
"channel_header": {
"channel_id": "businesschannel",
"epoch": "0",
"timestamp": "2018-08-20T06:36:06.000Z",
"timestamp": "2018-08-28T03:24:38.000Z",
"tx_id": "",
"type": 2,
"version": 0
@ -723,18 +723,18 @@
"id_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNHakNDQWNDZ0F3SUJBZ0lSQUlGd0tEeURCdXh6ZWg4NGljSmh0ejh3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpJdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekl1WlhoaGJYQnNaUzVqYjIwd0hoY05NVGd3TkRBeU1ESXpNRE0zV2hjTk1qZ3dNek13TURJek1ETTMKV2pCYk1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFZk1CMEdBMVVFQXd3V1FXUnRhVzVBYjNKbk1pNWxlR0Z0Y0d4bExtTnZiVEJaCk1CTUdCeXFHU000OUFnRUdDQ3FHU000OUF3RUhBMElBQk1SQ2lBVEQwNHI3WEE1MlR1d21rbVFpb1BNNDNrWjAKR29mVUVwazZMM3BLc0lXZDRyOEVyY1l2aGpKOUZ3TC9aa1FwamJmVWczTDVOTXZQVVlzRUJOcWpUVEJMTUE0RwpBMVVkRHdFQi93UUVBd0lIZ0RBTUJnTlZIUk1CQWY4RUFqQUFNQ3NHQTFVZEl3UWtNQ0tBSU14bWdiWEIySDQyClpaSElxZk1yUm1ZTXJGTlFjRVFMWkRNQXpSNllTT25oTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFESXFIbkYKTVRueENhY3VqWFExSWRNYjRQM1dQNkFwRzJvNDFmODlzWHQ0RGdJZ1pHR2lIckQ2eG5nMEdIQ1R6dVpjay9keApEVTRteGhRT3piQmxOOUJSaXRVPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==",
"mspid": "Org2MSP"
},
"nonce": "CQuP6iJ1BJvmoPMOqs3w8IeJZGNUrG0Z"
"nonce": "0cLj8FDGj/WY42Y5Vm7bkToJ7Rwppc8G"
}
}
},
"signature": "MEQCICbIgDycvMnP08dY204A7tYc3yVjAGKPga523EA/xJQpAiAFfIVABnvurPjn/qDPJRbPsvYIvpJNqOmA5TRumeHo4Q=="
"signature": "MEQCIAaNHEjsFJ+MGKQ8N4lIX0ITQsIVMgc8DhVChwY/ulYgAiAbafEEDmMHD+tBx4vCU2vFVv+GWhPXxciQbVyDCzLlxg=="
}
},
"header": {
"channel_header": {
"channel_id": "businesschannel",
"epoch": "0",
"timestamp": "2018-08-20T06:36:06.000Z",
"timestamp": "2018-08-28T03:24:38.000Z",
"tx_id": "",
"type": 1,
"version": 0
@ -744,23 +744,23 @@
"id_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNERENDQWJLZ0F3SUJBZ0lRUysyUitKSWo5WnBKTHhOSWk1MmtHREFLQmdncWhrak9QUVFEQWpCcE1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVVNQklHQTFVRUNoTUxaWGhoYlhCc1pTNWpiMjB4RnpBVkJnTlZCQU1URG1OaExtVjRZVzF3CmJHVXVZMjl0TUI0WERURTRNRFF3TWpBeU16QXpOMW9YRFRJNE1ETXpNREF5TXpBek4xb3dXREVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RmpBVUJnTlZCQWNURFZOaGJpQkdjbUZ1WTJsegpZMjh4SERBYUJnTlZCQU1URTI5eVpHVnlaWEl1WlhoaGJYQnNaUzVqYjIwd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxCmhrak9QUU1CQndOQ0FBUWlJMzQ2VitObUJNM2xVcGxoODVpTFYzbmF1aVNLRzRjZjE4NWVQTXgxWWp4RG53RlkKaUx5aEFzMmtxSTA3Ly9COXFCOFZwOVh4TVlBeVU3UXVGZGhNbzAwd1N6QU9CZ05WSFE4QkFmOEVCQU1DQjRBdwpEQVlEVlIwVEFRSC9CQUl3QURBckJnTlZIU01FSkRBaWdDQ1BhWDVvUEsyVk5lN2NxU2g2KzRmQVVPRSszQk9FCnJjbGtRSE0xSlpORFFqQUtCZ2dxaGtqT1BRUURBZ05JQURCRkFpRUF0N283UGkzZWVweGpWd24zRTB6Y2ptd2sKQTBIVDh4MnpSYXMwTjlqZ0E0OENJQ1kzUTRjMXM3QlJHcXRsSkF2VU9vMUo0SitXbkRhTGVlS01ZWmRWUWl6TgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==",
"mspid": "OrdererMSP"
},
"nonce": "W6NRj5ATK906KzyY/FHCHP9ZYH9T9yw5"
"nonce": "uhiXA2T9Mb6PHVbdJiisYltRa12ueB+v"
}
}
},
"signature": "MEQCIFfRKhiHGzqXG+4ZIa3NQV0k7p7JKoe+r6yTf6yZnMwsAiBX+o8RxvZMAAiK4Jxkd8nm2KTfhz/YC18qc2HXly017A=="
"signature": "MEQCIFcRqBIXQ3NJy1o3GGHQ8eG67TRGXexqyDmaj+QpwMK6AiA413Zoa5IkPj3Bl+Fr3gBisAFZR5gkr+5AAO8i6E3vdQ=="
}
]
},
"header": {
"data_hash": "Rk8BCGQmhNJTKP7CmGijc3Ub/WEjizb6cbYhmQvVeWk=",
"data_hash": "2521uHhHVsA7XgMoLQB5LfuvZcDyCfL2jC+bLu5N9gM=",
"number": "2",
"previous_hash": "e1zZVoSuT5rHiJXe9o7fZWmoYM1ZhxdLk4Pc2qtWoSE="
"previous_hash": "bmipkC6uriyoeKQ1MwSBnnr0wtb7MrCCYnlN/ROx9nY="
},
"metadata": {
"metadata": [
"EvgGCq0GCpAGCgpPcmRlcmVyTVNQEoEGLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNERENDQWJLZ0F3SUJBZ0lRUysyUitKSWo5WnBKTHhOSWk1MmtHREFLQmdncWhrak9QUVFEQWpCcE1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVVNQklHQTFVRUNoTUxaWGhoYlhCc1pTNWpiMjB4RnpBVkJnTlZCQU1URG1OaExtVjRZVzF3CmJHVXVZMjl0TUI0WERURTRNRFF3TWpBeU16QXpOMW9YRFRJNE1ETXpNREF5TXpBek4xb3dXREVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RmpBVUJnTlZCQWNURFZOaGJpQkdjbUZ1WTJsegpZMjh4SERBYUJnTlZCQU1URTI5eVpHVnlaWEl1WlhoaGJYQnNaUzVqYjIwd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxCmhrak9QUU1CQndOQ0FBUWlJMzQ2VitObUJNM2xVcGxoODVpTFYzbmF1aVNLRzRjZjE4NWVQTXgxWWp4RG53RlkKaUx5aEFzMmtxSTA3Ly9COXFCOFZwOVh4TVlBeVU3UXVGZGhNbzAwd1N6QU9CZ05WSFE4QkFmOEVCQU1DQjRBdwpEQVlEVlIwVEFRSC9CQUl3QURBckJnTlZIU01FSkRBaWdDQ1BhWDVvUEsyVk5lN2NxU2g2KzRmQVVPRSszQk9FCnJjbGtRSE0xSlpORFFqQUtCZ2dxaGtqT1BRUURBZ05JQURCRkFpRUF0N283UGkzZWVweGpWd24zRTB6Y2ptd2sKQTBIVDh4MnpSYXMwTjlqZ0E0OENJQ1kzUTRjMXM3QlJHcXRsSkF2VU9vMUo0SitXbkRhTGVlS01ZWmRWUWl6TgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tChIYs5vW1Pt8B5Q1YgRvFqRChLudVG5USvi2EkYwRAIgM6aenJP2Z7qd59MkWH6r60cj63UYRdQIrFZRQN5XWw4CIDi+pO1sDD+67/zPZdbyyEsnJbWPpWinc61SE2eEvI28",
"CgIIAhL5BgqtBgqQBgoKT3JkZXJlck1TUBKBBi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDRERDQ0FiS2dBd0lCQWdJUVMrMlIrSklqOVpwSkx4TklpNTJrR0RBS0JnZ3Foa2pPUFFRREFqQnBNUXN3CkNRWURWUVFHRXdKVlV6RVRNQkVHQTFVRUNCTUtRMkZzYVdadmNtNXBZVEVXTUJRR0ExVUVCeE1OVTJGdUlFWnkKWVc1amFYTmpiekVVTUJJR0ExVUVDaE1MWlhoaGJYQnNaUzVqYjIweEZ6QVZCZ05WQkFNVERtTmhMbVY0WVcxdwpiR1V1WTI5dE1CNFhEVEU0TURRd01qQXlNekF6TjFvWERUSTRNRE16TURBeU16QXpOMW93V0RFTE1Ba0dBMVVFCkJoTUNWVk14RXpBUkJnTlZCQWdUQ2tOaGJHbG1iM0p1YVdFeEZqQVVCZ05WQkFjVERWTmhiaUJHY21GdVkybHoKWTI4eEhEQWFCZ05WQkFNVEUyOXlaR1Z5WlhJdVpYaGhiWEJzWlM1amIyMHdXVEFUQmdjcWhrak9QUUlCQmdncQpoa2pPUFFNQkJ3TkNBQVFpSTM0NlYrTm1CTTNsVXBsaDg1aUxWM25hdWlTS0c0Y2YxODVlUE14MVlqeERud0ZZCmlMeWhBczJrcUkwNy8vQjlxQjhWcDlYeE1ZQXlVN1F1RmRoTW8wMHdTekFPQmdOVkhROEJBZjhFQkFNQ0I0QXcKREFZRFZSMFRBUUgvQkFJd0FEQXJCZ05WSFNNRUpEQWlnQ0NQYVg1b1BLMlZOZTdjcVNoNis0ZkFVT0UrM0JPRQpyY2xrUUhNMUpaTkRRakFLQmdncWhrak9QUVFEQWdOSUFEQkZBaUVBdDdvN1BpM2VlcHhqVnduM0UwemNqbXdrCkEwSFQ4eDJ6UmFzME45amdBNDhDSUNZM1E0YzFzN0JSR3F0bEpBdlVPbzFKNEorV25EYUxlZUtNWVpkVlFpek4KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoSGDu30JMFWD39LZTNVBhZ4CNfaclF+QRYgRJHMEUCIQCdmm7RIM1/KhcHij7PuOC7s9/v7WUEUerzeBp/vurlmAIgFqFW/LSYboRI/5FSWU1NpBl6leE8qQKxDQk/7Lm6MNw=",
"EvkGCq0GCpAGCgpPcmRlcmVyTVNQEoEGLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNERENDQWJLZ0F3SUJBZ0lRUysyUitKSWo5WnBKTHhOSWk1MmtHREFLQmdncWhrak9QUVFEQWpCcE1Rc3cKQ1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRUJ4TU5VMkZ1SUVaeQpZVzVqYVhOamJ6RVVNQklHQTFVRUNoTUxaWGhoYlhCc1pTNWpiMjB4RnpBVkJnTlZCQU1URG1OaExtVjRZVzF3CmJHVXVZMjl0TUI0WERURTRNRFF3TWpBeU16QXpOMW9YRFRJNE1ETXpNREF5TXpBek4xb3dXREVMTUFrR0ExVUUKQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RmpBVUJnTlZCQWNURFZOaGJpQkdjbUZ1WTJsegpZMjh4SERBYUJnTlZCQU1URTI5eVpHVnlaWEl1WlhoaGJYQnNaUzVqYjIwd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxCmhrak9QUU1CQndOQ0FBUWlJMzQ2VitObUJNM2xVcGxoODVpTFYzbmF1aVNLRzRjZjE4NWVQTXgxWWp4RG53RlkKaUx5aEFzMmtxSTA3Ly9COXFCOFZwOVh4TVlBeVU3UXVGZGhNbzAwd1N6QU9CZ05WSFE4QkFmOEVCQU1DQjRBdwpEQVlEVlIwVEFRSC9CQUl3QURBckJnTlZIU01FSkRBaWdDQ1BhWDVvUEsyVk5lN2NxU2g2KzRmQVVPRSszQk9FCnJjbGtRSE0xSlpORFFqQUtCZ2dxaGtqT1BRUURBZ05JQURCRkFpRUF0N283UGkzZWVweGpWd24zRTB6Y2ptd2sKQTBIVDh4MnpSYXMwTjlqZ0E0OENJQ1kzUTRjMXM3QlJHcXRsSkF2VU9vMUo0SitXbkRhTGVlS01ZWmRWUWl6TgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tChIYtWxsfO3RnJmTYIiZaodCprEjO3RaameqEkcwRQIhAP2wMJNCjiXK8sV/6WvDsydUNCUH/J39sieIXkHzFICAAiAqIVUmhK5A20CnXFCyRZoWpENefzUiRBYvUeJesrU0eQ==",
"CgIIAhL5BgqtBgqQBgoKT3JkZXJlck1TUBKBBi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlDRERDQ0FiS2dBd0lCQWdJUVMrMlIrSklqOVpwSkx4TklpNTJrR0RBS0JnZ3Foa2pPUFFRREFqQnBNUXN3CkNRWURWUVFHRXdKVlV6RVRNQkVHQTFVRUNCTUtRMkZzYVdadmNtNXBZVEVXTUJRR0ExVUVCeE1OVTJGdUlFWnkKWVc1amFYTmpiekVVTUJJR0ExVUVDaE1MWlhoaGJYQnNaUzVqYjIweEZ6QVZCZ05WQkFNVERtTmhMbVY0WVcxdwpiR1V1WTI5dE1CNFhEVEU0TURRd01qQXlNekF6TjFvWERUSTRNRE16TURBeU16QXpOMW93V0RFTE1Ba0dBMVVFCkJoTUNWVk14RXpBUkJnTlZCQWdUQ2tOaGJHbG1iM0p1YVdFeEZqQVVCZ05WQkFjVERWTmhiaUJHY21GdVkybHoKWTI4eEhEQWFCZ05WQkFNVEUyOXlaR1Z5WlhJdVpYaGhiWEJzWlM1amIyMHdXVEFUQmdjcWhrak9QUUlCQmdncQpoa2pPUFFNQkJ3TkNBQVFpSTM0NlYrTm1CTTNsVXBsaDg1aUxWM25hdWlTS0c0Y2YxODVlUE14MVlqeERud0ZZCmlMeWhBczJrcUkwNy8vQjlxQjhWcDlYeE1ZQXlVN1F1RmRoTW8wMHdTekFPQmdOVkhROEJBZjhFQkFNQ0I0QXcKREFZRFZSMFRBUUgvQkFJd0FEQXJCZ05WSFNNRUpEQWlnQ0NQYVg1b1BLMlZOZTdjcVNoNis0ZkFVT0UrM0JPRQpyY2xrUUhNMUpaTkRRakFLQmdncWhrak9QUVFEQWdOSUFEQkZBaUVBdDdvN1BpM2VlcHhqVnduM0UwemNqbXdrCkEwSFQ4eDJ6UmFzME45amdBNDhDSUNZM1E0YzFzN0JSR3F0bEpBdlVPbzFKNEorV25EYUxlZUtNWVpkVlFpek4KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoSGNMsND2/7I5BTSSmA14lr65Yh89RbLspLxJHMEUCIQCo4R+5xncJYL5Kt/tcdAeeNVI1H/XCjByMvQB0u4VAZwIgWNBzmK6sb6MQi96jvzwyjDicPHMfpnPHe4KpGwvuEeQ=",
"",
""
]

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long