前言:從交易記錄到顧客價值
善用商業數據分析的工具和技巧,光靠一份最簡單的交易紀錄(只有顧客ID、交易日期和交易金額三個欄位),我們就可以做一系列很深入、很有價值的顧客價值分析和行銷策略規劃,包括:
- 交易記錄分析:
- 顧客群組與標籤:
- 集群分析
- 群組屬性分析
- 組間流動機率
- 顧客(個人)流動機率
從這一些分析我們可以看到公司主要的營收和獲利的重要來源,我們也可以看到這一些產生獲利的群組是不是有成長或者衰退的趨勢;據此我們可以設定行銷的重點,決定行銷的策略,和規劃行銷的工具。除了上述的敘述統計、集群分析、和資料視覺化之外,我們還可以利用這些簡單的交易紀錄:
- 建立預測性模型,預測每一位顧客的:
- 保留機率
- 預期營收
- 組間變換機率
- 下次可能購買時間
利用這一些預測我們就可以進行全面客製化的:
- 顧客價值管理:
- 顧客終生價值
- 顧客吸收策略
- 顧客發展策略
- 顧客保留策略
- 針對性行銷:
Setup
Sys.setlocale("LC_ALL","C")
[1] "C"
packages = c(
"dplyr","ggplot2","googleVis","devtools","magrittr","caTools","ROCR","caTools")
existing = as.character(installed.packages()[,1])
for(pkg in packages[!(packages %in% existing)]) install.packages(pkg)
if(!is.element("chorddiag", existing))
devtools::install_github("mattflor/chorddiag")
Library
rm(list=ls(all=T))
options(digits=4, scipen=12)
library(dplyr)
library(ggplot2)
library(caTools)
library(ROCR)
library(googleVis)
library(chorddiag)
1 1. 資料整理
1.1 交易資料 (X)
X = read.table(
'purchases.txt', header=FALSE, sep='\t', stringsAsFactors=F)
names(X) = c('cid','amount','date')
X$date = as.Date(X$date)
summary(X) # 交易次數 51243
cid amount date
Min. : 10 Min. : 5 Min. :2005-01-02
1st Qu.: 57720 1st Qu.: 25 1st Qu.:2009-01-17
Median :102440 Median : 30 Median :2011-11-23
Mean :108935 Mean : 62 Mean :2011-07-14
3rd Qu.:160525 3rd Qu.: 60 3rd Qu.:2013-12-29
Max. :264200 Max. :4500 Max. :2015-12-31
程式碼說明
- 將檔案讀進table,header=FALSE,代表檔案沒有變數名稱,sep=‘’,代表依照,stringsAsFactors=F,代表不用變成類別。
- names(X) = c(‘cid’,‘amount’,‘date’),將變數取名
- X\(date = as.Date(X\)date)將檔案中日期轉成r中的日期格式
執行意涵
- 讀取檔案是第一步也是最重要的一步,在一開始將檔案格式整理切分後,可以有利後面資料分析進行,是簡單但重要的一個步驟。
par(cex=0.8)
hist(X$date, "years", las=2, freq=T, xlab="", main="No. Transaction by Year")

程式碼說明
- par(cex=0.8),設定文字和符號的字體大小
- hist(X\(date, "years", las=2, freq=T, xlab="", main="No. Transaction by Year"),用X\)date作為x軸,freq=T,以頻率來計算,並用每一年作為切分,las=2,顯示y軸的呈現方法,xlab=“”,xlab不取名,main=“No. Transaction by Year”,這張圖的名稱。
執行意涵
- 視覺化資料幫助我們更加快速觀察資料提供給我們的訊息,從圖中我們可以看出,交易次數逐年攀升。
n_distinct(X$cid) # 顧客數 18417
[1] 18417
程式碼說明
- n_distinct(X$cid),n_distinct()這個function會找出不重複的項目,在這筆資料中有許多顧客編碼是重複的,透過這個步驟我們可以算出顧客數。
執行意涵
1.2 顧客資料 (A)
A = X %>%
mutate(days = as.integer(as.Date("2016-01-01") - date)) %>%
group_by(cid) %>% summarise(
recent = min(days), # 最近購買距今天數
freq = n(), # 購買次數
money = mean(amount), # 平均購買金額
senior = max(days), # 第一次購買距今天數
since = min(date) # 第一次購買日期
) %>% data.frame
程式碼說明
- mutate(days = as.integer(as.Date(“2016-01-01”) - date))創造一個新的變數days,內容為2016-01-01 - 交易發生的日期,先用日期格式來計算,再使用as.integer轉成數字格式。
- group_by(cid)綁住顧客編碼
- 將新增的變數一起轉成data.frame A
執行意涵
- 觀察個別顧客的消費行為,透過新增許多變數,能幫助我們後面的分析。
1.4 顧客資料摘要
summary(A)
cid recent freq money
Min. : 10 Min. : 1 Min. : 1.00 Min. : 5
1st Qu.: 81990 1st Qu.: 244 1st Qu.: 1.00 1st Qu.: 22
Median :136430 Median :1070 Median : 2.00 Median : 30
Mean :137574 Mean :1253 Mean : 2.78 Mean : 58
3rd Qu.:195100 3rd Qu.:2130 3rd Qu.: 3.00 3rd Qu.: 50
Max. :264200 Max. :4014 Max. :45.00 Max. :4500
senior since
Min. : 1 Min. :2005-01-02
1st Qu.: 988 1st Qu.:2007-10-23
Median :2087 Median :2010-04-15
Mean :1984 Mean :2010-07-26
3rd Qu.:2992 3rd Qu.:2013-04-18
Max. :4016 Max. :2015-12-31
1.5 變數的分布狀況
group_by(A, grp) %>% summarise(
recent=mean(recent),
freq=mean(freq),
money=mean(money),
size=n() ) %>%
mutate( revenue = size*money/1000 ) %>%
filter(size > 1) %>%
ggplot(aes(x=freq, y=money)) +
geom_point(aes(size=revenue, col=recent),alpha=0.5) + #泡泡大小→營收貢獻 泡泡內文字→佔多少人
scale_size(range=c(4,30)) +
scale_color_gradient(low="green",high="red") +
scale_x_log10() + scale_y_log10(limits=c(30,3000)) +
geom_text(aes(label = size ),size=3) +
theme_bw() + guides(size=F) +
labs(title="Customer Segements",
subtitle="(bubble_size:revenue_contribution; text:group_size)",
color="Recency") +
xlab("Frequency (log)") + ylab("Average Transaction Amount (log)")

程式碼說明
- p0 = par(cex=0.8, mfrow=c(2,2), mar=c(3,3,4,2)),cex設定字體大小,mfrow設定圖的排列方式,mar設定圖的邊框大小。
- hist(A$recent,20,main=“recency”,ylab=“”,xlab=“”),繪製顧客最近購買據今天數的柱狀圖,20根柱子,標題為recency,x和y軸都不取名子。
- hist(pmin(A\(freq, 10),0:10,main="frequency",ylab="",xlab=""),繪製顧客購買次數的柱狀圖,pmin(A\)freq, 10)將freq取pmin10,高於10次都以10次計算,0:10,設定x軸值,標題為frequency,x和y軸都不取名。
- hist(A$senior,20,main=“seniority”,ylab=“”,xlab=“”),繪製顧客第一次購買據今天數的柱狀圖,20根柱子,標題為seniority,x和y軸都不取名子。
- hist(log(A$money,10),,main=“log(money)”,ylab=“”,xlab=“”),繪製顧客平均購買金額柱狀圖,將money取log,標題為log(money),x和y軸都不取名子。
執行意涵
- 將四項變數資料視覺化,可以觀察出各變數的分布狀況。
2. 層級式集群分析
2.1 RFM顧客分群
set.seed(111)
A$grp = kmeans(scale(A[,2:4]),10)$cluster
table(A$grp) # 族群大小
1 2 3 4 5 6 7 8 9 10
1073 2266 1296 2237 3207 1942 1781 2392 2096 127
程式碼說明
- A\(grp = kmeans(scale(A[,2:4]),10)\)cluster,將A中變數2到4取常態分佈,接著使用kmeans將它分成10群,接著將他cluster的分布存進新的變數grp
- table(A$grp),將每一群數量分佈印出來。
執行意涵
2.2 顧客群組屬性
Y = list() # 建立一個空的LIST
for(y in 2010:2015) { # 每年年底將顧客資料彙整成一個資料框
D = as.Date(paste0(c(y, y-1),"-12-31")) # 當期、前期的期末日期
Y[[paste0("Y",y)]] = X %>% # 從交易資料做起
filter(date <= D[1]) %>% # 將資料切齊到期末日期
mutate(days = 1 + as.integer(D[1] - date)) %>% # 交易距期末天數
group_by(cid) %>% summarise( # 依顧客彙總 ...
recent = min(days), # 最後一次購買距期末天數
freq = n(), # 購買次數 (至期末為止)
money = mean(amount), # 平均購買金額 (至期末為止)
senior = max(days), # 第一次購買距期末天數
status = Status(recent,freq,money,senior,K), # 期末狀態
since = min(date), # 第一次購買日期
y_freq = sum(date > D[2]), # 當期購買次數
y_revenue = sum(amount[date > D[2]]) # 當期購買金額
) %>% data.frame }
程式碼說明
- group_by(A, grp) %>% summarise(recent=mean(recent), freq=mean(freq),money=mean(money), size=n(),先將A資料格式group by grp,代表後面summarise時以group來計算,後面將最近購買距今天數、 購買次數、金額三樣數據取平均,size=n()算出每群的大小。
- mutate( revenue = size*money/1000 )%>% filter(size > 1)新增一個變數為revenue,並將計算出來size > 1的塞出來
- ggplot(aes(x=freq, y=money)) + geom_point(aes(size=revenue, col=recent),alpha=0.5) + scale_size(range=c(4,30)) + scale_color_gradient(low=“green”,high=“red”) + scale_x_log10() + scale_y_log10(limits=c(30,3000)) + geom_text(aes(label = size ),size=3) + theme_bw() + guides(size=F) + labs(title=“Customer Segements”, subtitle=“(bubble_size:revenue_contribution; text:group_size)”, color=“Recency”) + xlab(“Frequency (log)”) + ylab(“Average Transaction Amount (log)”) 用ggplot來繪製,x軸放平均購買次數,y放平均購買金額,圖形上的點,大小為利潤貢獻,顏色為平均最近購買據今天數,透明度0.5,圓圈大小為430,調色為數值越低為綠色,越高為紅色,x和y軸的值取log10,y的原本值設定在303000間,篩掉離群值,字體大小設定為3,主題設定為bw,最後再幫圖檔取名,X軸Y軸取名。
執行意涵
- 透過將不同群顧客的消費習性透過視覺化分類出來,可以讓我們快速發現他們差異,並有利我們之後針對不同群顧客執行不同行銷策略。
3. 規則分群
3.1 顧客分群規則
r{r eval=F}
<!-- rnb-source-end -->
<!-- rnb-output-begin eyJkYXRhIjoiRXJyb3I6IGF0dGVtcHQgdG8gdXNlIHplcm8tbGVuZ3RoIHZhcmlhYmxlIG5hbWVcbiJ9 -->
Error: attempt to use zero-length variable name ```
程式碼說明
- STS = c(“N1”,“N2”,“R1”,“R2”,“S1”,“S2”,“S3”),建立一個向量
- 建立Statusfunction,sx<2k成立前提下,且fx*mx成立,為N2,不是則為N1,若sx<2*k不成立前提下,rx<2*K成立,且sx/fx<0.75成立,為R2,不是則為R1,若rx<2*K不成立且rx<3*K,為S1,若上述皆不成立,rx<4*K為S2,不成立則為S3
執行意涵
3.2 平均購買週期
K = as.integer(sum(A$senior[A$freq>1]) / sum(A$freq[A$freq>1])); K
[1] 521
回購顧客的平均購買週期 K = 521 days
程式碼說明
- 將購買次數大於一顧客的第一次距今購買天數/購買次數大於一顧客的總來店次數。
執行意涵
3.3 滑動資料窗格
Y = list() # 建立一個空的LIST
for(y in 2010:2015) { # 每年年底將顧客資料彙整成一個資料框
D = as.Date(paste0(c(y, y-1),"-12-31")) # 當期、前期的期末日期
Y[[paste0("Y",y)]] = X %>% # 從交易資料做起
filter(date <= D[1]) %>% # 將資料切齊到期末日期
mutate(days = 1 + as.integer(D[1] - date)) %>% # 交易距期末天數
group_by(cid) %>% summarise( # 依顧客彙總 ...
recent = min(days), # 最後一次購買距期末天數
freq = n(), # 購買次數 (至期末為止)
money = mean(amount), # 平均購買金額 (至期末為止)
senior = max(days), # 第一次購買距期末天數
status = Status(recent,freq,money,senior,K), # 期末狀態
since = min(date), # 第一次購買日期
y_freq = sum(date > D[2]), # 當期購買次數
y_revenue = sum(amount[date > D[2]]) # 當期購買金額
) %>% data.frame }
程式碼說明
- for(y in 2010:2015)建立一個迴圈,y會從2010到2015執行下面那段程式碼。
- D = as.Date(paste0(c(y, y-1),“-12-31”)),paste0會消除年份接月份時sep=“”那個空白,印出來的日期會有兩個,分別是前一年和今年的12月31日,ex:“2015-12-31” “2014-12-31”,再轉成日期格式。
- 建立一個空的LIST,每年年底將顧客資料彙整成一個資料框,當期、前期的期末日期 ,從交易資料做起,將資料切齊到期末日期,交易距期末天數,依顧客彙總 …,最後一次購買距期末天數,購買次數 (至期末為止),平均購買金額 (至期末為止),第一次購買距期末天數,期末狀態,第一次購買日期,當期購買次數,當期購買金額。
執行意涵
- 將資料按年份切割,可以做出來每一年個別的分析,方便之後預測下一年的顧客消費行為。
head(Y$Y2015)
程式碼說明
執行意涵
- 觀察2015年前五筆資料 ##### 3.4 每年年底的累計顧客人數
pred = predict(mRet,type="response")
table(pred>0.5,CX$Retain)
FALSE TRUE
FALSE 12045 1530
TRUE 974 2356
# 混淆矩陣 (Confusion Matrix)
程式碼說明
- 使用sapply將Y lsit中六個data frame 的row數量印出來。
執行意涵
3.5 族群大小變化趨勢
prediction(pred, CX$Retain) %>% # ROC CURVE
performance("tpr", "fpr") %>%
plot(print.cutoffs.at=seq(0,1,0.1))

程式碼說明
- 先設定一個顏色的向量,將每個Y裡的data frame的status數量視覺化,顏色為向量設定的顏色,接著加入旁篇的調色條,將STS和cols都倒過來。
執行意涵
3.6 族群屬性動態分析
CustSegments = do.call(rbind, lapply(Y, function(d) {
group_by(d, status) %>% summarise(
average_frequency = mean(freq),
average_amount = mean(money),
total_revenue = sum(y_revenue),
total_no_orders = sum(y_freq),
average_recency = mean(recent),
average_seniority = mean(senior),
group_size = n()
)})) %>% ungroup %>%
mutate(year=rep(2010:2015, each=7)) %>% data.frame
head(CustSegments)
程式碼說明
- 將y裡的data frame 依照status囊總,算出平均來店次數、平均購買金額、平均當期利潤、當期購買總次數、平均最近距今購買天數、平均第一次到店距今天數和每一群人數,接著再將群組打散,將2010到2015重複6次對應7個不同status,把格式存成data.frame,然後印出前6行
執行意涵
- 將6年每個status的變化做成data.frame,以利在後面視覺化分析。
plot( gvisMotionChart(
CustSegments, "status", "year",
options=list(width=900, height=600) ) )
程式碼說明
- 用剛剛status資料繪製互動泡泡圖,status依照年做變化,設定長900D、寬600。
執行意涵
3.7 族群屬性動態分析
g = 0.5 # (稅前)獲利率
N = 5 # 期數 = 5
d = 0.1 # 利率 = 10%
CX$CLV = g * CX$PredRevenue * rowSums(sapply(
0:N, function(i) (CX$ProbRetain/(1+d))^i ) )
summary(CX$CLV)
Min. 1st Qu. Median Mean 3rd Qu. Max.
3 16 24 51 45 5094
程式碼說明
- 將Y list中2014和2015年的cid和status,用cid囊括
- 接著將他們兩個擺進table分析,2014到2015年status的轉變,並把他存進data.frame中
執行意涵
tx %>% prop.table(1) %>% round(3) # 流量矩陣(%)
N1 N2 R1 R2 S1 S2 S3
N1 0.549 0.123 0.046 0.014 0.268 0.000 0.000
N2 0.000 0.541 0.128 0.206 0.126 0.000 0.000
R1 0.000 0.000 0.590 0.020 0.390 0.000 0.000
R2 0.000 0.000 0.099 0.864 0.037 0.000 0.000
S1 0.000 0.000 0.059 0.002 0.417 0.523 0.000
S2 0.000 0.000 0.037 0.000 0.000 0.328 0.635
S3 0.000 0.000 0.028 0.000 0.000 0.000 0.972
程式碼說明
- 將流量矩陣丟進prob.table,採機率形式表現,取到小數點後三位
執行意涵
- 以機率形式表示2014到2015年,status的機率轉變。
3.8 互動式流量分析
chorddiag(tx, groupColors=cols)
程式碼說明
- 將流量矩陣丟進互動式流量分析,顏色使用剛剛設定的顏色向量
執行意涵
- 用互動式流量分析圖,能將流量矩陣用視覺化呈現,以利分析。
4. 建立模型
在這個案例裡面,我們的資料是收到Y2015年底,所以我們可以假設現在的時間是Y2015年底,我們想要用現有的資料建立模型,來預測每一位顧客:
- 在Y2016年是否會來購買 (保留率:Retain)
- 她來購買的話,會買多少錢 (購買金額:Revenue)
但是,我們並沒有Y2016的資料,為了要建立模型,我們需要先把時間回推一期,也就是說:
- 用Y2014年底以前的資料整理出預測變數(X)
- 用Y2015年的資料整理出目標變數(Y)
假如Y2016的情況(跟Y2015比)沒有太大的變化的話,接下來我們就可以
- 使用該模型,以Y2015年底的資料,預測Y2016的狀況
4.1 準備資料
我們用Y2014年底的資料做自變數,Y2015年的資料做應變數
sum(Target$ExpReturn > 0) # 可實施對象:258
[1] 258
程式碼說明
- CX = left_join(Y\(Y2014, Y\)Y2015[,c(1,8,9)], by=“cid”)
- 將 2014 年消費者全部的資料與 2015 年消費者僅消費頻率及消費額的資料,以 cid 作為對照合併
執行意涵
- 將建立模型時所需要的自變數 ( 2014 資料 ) 以及應變數 ( 2015 資料 ) 合併為一個 data.frame 以利後續建模使用。
Target = CX
Target$ExpReturn = (effect - Target$ProbRetain) * Target$PredRevenue - cost
filter(Target, Target$ExpReturn > 0) %>%
group_by(status) %>% summarise(
No.Target = n(),
AvgROI = mean(ExpReturn),
TotalROI = sum(ExpReturn) ) %>% data.frame
程式碼說明
- names(CX)[8:11] = c(“freq0”,“revenue0”,“Retain”, “Revenue”)
- 重新命名合併過後被系統自動命名的變數。
- CX\(Retain = CX\)Retain > 0
- 將第二年消費次數非 0 次的顧客判定為 Retain = TRUE。
執行意涵
- 將 CX 資料框內的資料處理成接下來建模所需要的格式。
table(CX$Retain) %>% prop.table() # 平均保留機率 = 22.54%
FALSE TRUE
0.7701 0.2299
程式碼說明
- table(CX$Retain) %>% prop.table()
- 將 CX 中的 Retain 變數中的 T/F 比例計算出來。
執行意涵
4.2 建立類別模型
mRet = glm(Retain ~ ., CX[,c(2:3,6,8:10)], family=binomial())
summary(mRet)
Call:
glm(formula = Retain ~ ., family = binomial(), data = CX[, c(2:3,
6, 8:10)])
Deviance Residuals:
Min 1Q Median 3Q Max
-3.689 -0.473 -0.298 -0.142 3.386
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -1.074007 0.089431 -12.01 < 2e-16 ***
recent -0.002067 0.000131 -15.73 < 2e-16 ***
freq 0.095217 0.013882 6.86 0.0000000000069 ***
statusN2 0.669429 0.070234 9.53 < 2e-16 ***
statusR1 0.488321 0.084389 5.79 0.0000000071864 ***
statusR2 1.290002 0.110841 11.64 < 2e-16 ***
statusS1 0.670604 0.146532 4.58 0.0000047279944 ***
statusS2 1.353554 0.208210 6.50 0.0000000000798 ***
statusS3 2.573689 0.275786 9.33 < 2e-16 ***
freq0 0.566557 0.065532 8.65 < 2e-16 ***
revenue0 -0.000132 0.000135 -0.98 0.33
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 18228 on 16904 degrees of freedom
Residual deviance: 11766 on 16894 degrees of freedom
AIC: 11788
Number of Fisher Scoring iterations: 6
程式碼說明
- mRet = glm(Retain ~ ., CX[,c(2:3,6,8:10)], family=binomial())
- 建立羅吉斯模型。自變數為 recent、freq、status、freq0、revenue0,應變數為 Retain。
執行意涵
- 建立一個以 2014 年顧客資料來預測 2015 年該顧客是否會來消費的羅吉斯模型。
4.3 估計類別模型的準確性
pred = predict(mRet,type="response")
table(pred>0.5,CX$Retain)
FALSE TRUE
FALSE 12045 1530
TRUE 974 2356
# 混淆矩陣 (Confusion Matrix)
程式碼說明
- pred = predict(mRet,type=“response”)
- 將前述步驟所建立的模型其觀察值的預測值全部存到變數 pred 中。
- table(pred>0.5,CX$Retain)
- 將類別預測值與實際發生值轉換為混淆矩陣。
執行意涵
table(pred>0.5,CX$Retain) %>%
{sum(diag(.))/sum(.)} # 正確率(ACC): 85.19%
[1] 0.8519
colAUC(pred,CX$Retain) # 辯識率(AUC): 87.92%
[,1]
FALSE vs. TRUE 0.8792
程式碼說明
- table(pred>0.5,CX$Retain) %>% {sum(diag(.))/sum(.)}
- 將類別預測值與實際發生值轉換為混淆矩陣,並計算 ACC ( 正確率 )。
- colAUC(pred,CX$Retain)
- 將類別預測值與實際發生值轉換為 AUC ( 辨識率 )。
執行意涵
- 計算 ACC 及 AUC 能讓我們直觀地了解此模型的預測表現,並能夠與其他模型作比較。
prediction(pred, CX$Retain) %>% # ROC CURVE
performance("tpr", "fpr") %>%
plot(print.cutoffs.at=seq(0,1,0.1))

程式碼說明
- prediction(pred, CX$Retain) %>% performance(“tpr”, “fpr”) %>% plot(print.cutoffs.at=seq(0,1,0.1))
- 將類別預測值與實際發生值其 TPR、FPR 繪製成圖,threshold 從 0 ~ 1 之間每 0.1 繪製一個點,再連成如上圖之 ROC 曲線。
執行意涵
- 繪製 ROC 曲線。此舉能夠幫助模型使用者了解模型的預測表現,並能夠使模型使用者依 TPR、FPR 挑出能夠接受之 threshold 值。
4.4 建立數量模型
dx = subset(CX, Revenue > 0) # 只對有來購買的人做模型
mRev = lm(log(Revenue) ~ recent + freq + log(1+money) + senior +
status + freq0 + log(1+revenue0), dx)
summary(mRev) # 判定係數:R2 = 0.713
Call:
lm(formula = log(Revenue) ~ recent + freq + log(1 + money) +
senior + status + freq0 + log(1 + revenue0), data = dx)
Residuals:
Min 1Q Median 3Q Max
-3.245 -0.209 -0.067 0.205 3.435
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.0587930 0.0458344 1.28 0.1997
recent 0.0003541 0.0000507 6.98 0.00000000000337 ***
freq 0.0526850 0.0046504 11.33 < 2e-16 ***
log(1 + money) 0.9320818 0.0135203 68.94 < 2e-16 ***
senior -0.0001369 0.0000182 -7.52 0.00000000000007 ***
statusN2 0.0127716 0.0262656 0.49 0.6268
statusR1 0.1927532 0.0407579 4.73 0.00000233405019 ***
statusR2 0.0297685 0.0352479 0.84 0.3984
statusS1 0.0082406 0.0630355 0.13 0.8960
statusS2 -0.2406398 0.0865731 -2.78 0.0055 **
statusS3 -0.3667341 0.1181061 -3.11 0.0019 **
freq0 0.0103133 0.0172551 0.60 0.5501
log(1 + revenue0) 0.0632756 0.0094003 6.73 0.00000000001930 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.463 on 3873 degrees of freedom
Multiple R-squared: 0.713, Adjusted R-squared: 0.712
F-statistic: 802 on 12 and 3873 DF, p-value: <2e-16
程式碼說明
- dx = subset(CX, Revenue > 0)
- 將原先的資料框 CX 取子集,只要 2015 有來消費的顧客觀察值即可。
- mRev = lm(log(Revenue) ~ recent + freq + log(1+money) + senior + status + freq0 + log(1+revenue0), dx)
- 建立一般線性模型,自變數為 recent、freq、log(1+money)、senior、status、freq0、log(1+revenue0),應變數為 log(Revenue)。money 及 revenue0 兩個變數額外 + 1 是為了避免該值 < 1 會造成取對數後數值為負。
執行意涵
- 對 2015 年仍然有來消費的顧客建立「會花費多少金額」的一般線性數量預測模型。
plot(log(dx$Revenue), predict(mRev), col='pink', cex=0.65)
abline(0,1,col='red')

程式碼說明
- plot(log(dx$Revenue), predict(mRev), col=‘pink’, cex=0.65)
- 將預測值對實際發生值繪製散佈圖,顏色設定為 pink,大小調整為 0.65
- abline(0,1,col=‘red’)
- 繪製一條紅色的 45 度線做為對照。
執行意涵
- 繪製一張散佈圖來觀察此模型的預測結果與實際觀測值的差距。
5. 估計顧客終生價值
5.1 Y2016的預測值
使用模型對Y2015年底的資料做預測,對資料中的每一位顧客,預測她們在Y2016的保留率和購買金額。
CX = Y$Y2015
names(CX)[8:9] = c("freq0","revenue0")
# 預測Y2016保留率
CX$ProbRetain = predict(mRet,CX,type='response')
# 預測Y2016購買金額
CX$PredRevenue = exp(predict(mRev,CX))
程式碼說明
- CX = Y$Y2015 ; names(CX)[8:9] = c(“freq0”,“revenue0”)
- 將資料框 CX 的資料更改為 2015 年的資料,並將變數欄位 8、9 更改為模型可以認知的名稱 freq0 及 revenue0。
- CX$ProbRetain = predict(mRet,CX,type=‘response’)
- 將類別預測模型 ( 2016 年是否會來消費 ) 預測的結果存為 CX 中的 ProbRetain。
- CX$PredRevenue = exp(predict(mRev,CX))
- 將數量預測模型 ( 2016 年會消費多少金額 ) 預測的結果存為 CX 中的 PredRevenue。
執行意涵
- 將 2015 年的顧客資料丟入我們於第四部分所建立的兩個預測模型,分別預測顧客於 2016 年是否會來消費,以及如果會來消費,其消費金額是多少。
par(mfrow=c(1,2), mar=c(4,3,3,2), cex=0.8)
hist(CX$ProbRetain,main="ProbRetain", ylab="")
hist(log(CX$PredRevenue,10),main="log(PredRevenue)", ylab="")

程式碼說明
- par(mfrow=c(1,2), mar=c(4,3,3,2), cex=0.8)
- 基礎繪圖設定,接下來的圖為一列兩行併為一張圖,邊界為 4,3,3,2,整體大小為 0.8。
- hist(CX$ProbRetain,main=“ProbRetain”, ylab=“”)
- 繪製第一個模型的預測結果柱狀圖。
- hist(log(CX$PredRevenue,10),main=“log(PredRevenue)”, ylab=“”)
- 繪製第二個模型的預測結果柱狀圖。注意金額的數字有取 log10。
執行意涵
- 將預測結果以柱狀圖表示,能夠觀察兩個模型預測出來的結果分佈。如第一個模型預測今年的這些顧客於明年會來消費的機率大部分趨近於 0;而消費金額大部分落於 1.5 ( 也就是原始數值 31.62 ) 左右。
5.2 估計顧客終生價值(CLV)
顧客\(i\)的終生價值
\[ V_i = \sum_{t=0}^N g \times m_i \frac{r_i^t}{(1+d)^t} = g \times m_i \sum_{t=0}^N (\frac{r_i}{1+d})^t \]
\(m_i\)、\(r_i\):顧客\(i\)的預期(每期)營收貢獻、保留機率
\(g\)、\(d\):公司的(稅前)營業利潤利率、資金成本
g = 0.5 # (稅前)獲利率
N = 5 # 期數 = 5
d = 0.1 # 利率 = 10%
CX$CLV = g * CX$PredRevenue * rowSums(sapply(
0:N, function(i) (CX$ProbRetain/(1+d))^i ) )
summary(CX$CLV)
Min. 1st Qu. Median Mean 3rd Qu. Max.
3 16 24 51 45 5094
程式碼說明
- CX\(CLV = g * CX\)PredRevenue * rowSums(sapply(0:N, function(i) (CX$ProbRetain/(1+d))^i ) )
- 計算顧客終生價值 : 將獲利率乘上預期獲利,再乘上未來五年預期保留率的現值總和。
執行意涵
- 計算顧客終生價值能夠讓我們了解每一個顧客的潛在價值有多大 ( 在這個題目我們計算了五年 )。
par(mar=c(2,2,3,1), cex=0.8)
hist(log(CX$CLV,10), xlab="", ylab="")

程式碼說明
- par(mar=c(2,2,3,1), cex=0.8)
- 基礎繪圖設定,接下來的圖邊界為 2,2,3,1,整體大小為 0.8。
- hist(log(CX$CLV,10), xlab=“”, ylab=“”)
- 繪製顧客終生價值的柱狀圖。注意這邊的「價值」也有取 log10。
執行意涵
- 將顧客終生價值繪製成柱狀圖,能夠更直觀地看到顧客普遍帶給公司的價值在哪些區段。
5.3 比較各族群的價值
# 各族群的平均營收貢獻、保留機率、終生價值
sapply(CX[,10:12], tapply, CX$status, mean)
ProbRetain PredRevenue CLV
N1 0.20269 31.98 20.17
N2 0.44075 131.23 110.89
R1 0.34150 69.85 54.60
R2 0.74925 91.27 136.31
S1 0.05724 56.10 29.66
S2 0.03475 49.48 25.58
S3 0.02326 49.36 25.17
程式碼說明
- sapply(CX[,10:12], tapply, CX$status, mean)
- 將變數 10 ~ 12 ( 兩個預測結果與顧客終生價值 ) 根據不同的消費者狀態分組,計算其平均值。
執行意涵
- 透過彙整成表格,能夠直接地看到每一個狀態下的消費者其平均保留機率、預計花費以及終生價值,有助於了解每個消費者狀態的性質與對其進行策略擬定。
par(mar=c(3,3,4,2), cex=0.8)
boxplot(log(CLV)~status, CX, main="CLV by Groups")

程式碼說明
- par(mar=c(3,3,4,2), cex=0.8)
- 基礎繪圖設定,接下來的圖邊界為 3,3,4,2,整體大小為 0.8。
- boxplot(log(CLV)~status, CX, main=“CLV by Groups”)
- 繪製顧客終生價值對顧客狀態分群的盒狀圖。
執行意涵
- 從盒狀圖中可以看到不同的顧客狀態,其終生價值的分佈狀況。
7. 選擇行銷對象
給定某一行銷工具的成本和預期效益,選擇可以施行這項工具的對象。
7.1 對R2族群進行保留
R2族群的預測保留率和購買金額
par(mfrow=c(1,2), mar=c(4,3,3,2), cex=0.8)
hist(CX$ProbRetain[CX$status=="R2"],main="ProbRetain",xlab="")
hist(log(CX$PredRevenue[CX$status=="R2"],10),main="PredRevenue",xlab="")

程式碼說明
- 首先先用par(),對於圖表的格式進行調整,方便觀察。
- 接著hist()畫出長條圖,觀察R2族群的預測保留率以及預測消費金額,對於消費金額取log使其呈現常態分佈,驗證結果正確性。
- 在ProbRetain當中x軸為機率,y軸為顧客數量,在PredRevenue中x軸為消費金額,y軸為顧客數量。
執行意涵
- 透過視覺化的動作將目標族群R2的預測保留率以及預測消費金額更加容易觀察。
7.2 估計預期報酬
假設行銷工具的成本和預期效益為
cost = 10 # 成本
effect = 0.75 # 效益:下一期的購買機率
估計這項行銷工具對每一位R2顧客的預期報酬
Target = subset(CX, status=="R2")
Target$ExpReturn = (effect - Target$ProbRetain) * Target$PredRevenue - cost
summary(Target$ExpReturn)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-515.8 -15.4 -11.5 -10.3 -8.1 646.9
這一項工具對R2顧客的預期報酬是負的
程式碼說明
- 先設定我們的預期效益、執行成本為多少。
- subset出一個新的子集(關於R2群顧客的消費資料),建立成Target。
- 建立ExpReturn預期報酬,也就是報酬扣掉cost成本,接著summary出結果。
執行意涵
- 估計使用此行銷工具對每一位R2顧客能給店裡帶來的預期報酬是否是好的,若不好則再選擇其他更適合的行銷工具。
7.3 選擇行銷對象
但是,我們還是可以挑出許多預期報酬很大的行銷對象
Target %>% arrange(desc(ExpReturn)) %>% select(cid, ExpReturn) %>% head(15)
sum(Target$ExpReturn > 0) # 可實施對象:258
[1] 258
在R2之中,有258人的預期報酬大於零,如果對這258人使用這項工具,我們的期望報酬是:
sum(Target$ExpReturn[Target$ExpReturn > 0]) # 預期報酬:6464
[1] 6464
程式碼說明
- 從Target中依照降冪排列的方式選擇最前面的15筆資料(資料中是含有顧客以及預期報酬的)。
- 接著加總所有預期報酬為正值的顧客數量。
- 最後加總所有預期報酬為正值的顧客之預期報酬,得到使用此項工具的總最大預期報酬。
執行意涵
- 雖然我們得到了平均為負值的結果,但我們可以透過“選擇”的方式去找出預期報酬為正值的R2顧客,並且針對這些報酬為正的顧客使用此項行銷工具,得到最好的預期報酬總值。
QUIZ:
我們可以算出對所有的族群實施這項工具的期望報酬 …
Target = CX
Target$ExpReturn = (effect - Target$ProbRetain) * Target$PredRevenue - cost
filter(Target, Target$ExpReturn > 0) %>%
group_by(status) %>% summarise(
No.Target = n(),
AvgROI = mean(ExpReturn),
TotalROI = sum(ExpReturn) ) %>% data.frame
這個結果是合理的嗎? 你想要怎麼修正這項分析的程序呢?
不合理
- 其效益(加成方法)為定值0.75,但因為族群不同,貢獻效益也不同,故算出來的數值會有落差,應採用比率的方式較為客觀。
- 若行銷的邊際成本低(像是電子檔DM),則應可以全部的顧客都發,其成本會隨著數量增加而降低,此結果應不符合現實。
LS0tDQp0aXRsZTogIkNWTe+8mumhp+WuouWDueWAvOeuoeeQhiAiDQphdXRob3I6ICJHcm91cCAyICwgMjAxOC8wOC8xNSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCjxicj4NCg0KIyMjIOWJjeiogO+8muW+nuS6pOaYk+iomOmMhOWIsOmhp+WuouWDueWAvA0KDQrlloTnlKjllYbmpa3mlbjmk5rliIbmnpDnmoTlt6XlhbflkozmioDlt6fvvIzlhYnpnaDkuIDku73mnIDnsKHllq7nmoTkuqTmmJPntIDpjIQo5Y+q5pyJ6aGn5a6iSUTjgIHkuqTmmJPml6XmnJ/lkozkuqTmmJPph5HpoY3kuInlgIvmrITkvY0p77yM5oiR5YCR5bCx5Y+v5Lul5YGa5LiA57O75YiX5b6I5rex5YWl44CB5b6I5pyJ5YO55YC855qE6aGn5a6i5YO55YC85YiG5p6Q5ZKM6KGM6Yq3562W55Wl6KaP5YqD77yM5YyF5ous77yaDQoNCisgKirkuqTmmJPoqJjpjITliIbmnpAqKu+8mg0KICAgICsg5pWY6L+w57Wx6KiIDQogICAgKyDotqjli6LjgIHkuqTlj4nliIbmnpANCiAgICArIOizh+aWmeimluimuuWMlg0KDQorICoq6aGn5a6i576k57WE6IiH5qiZ57GkKirvvJoNCiAgICArIOmbhue+pOWIhuaekA0KICAgICsg576k57WE5bGs5oCn5YiG5p6QDQogICAgKyDntYTplpPmtYHli5XmqZ/njocNCiAgICArIOmhp+WuoijlgIvkurop5rWB5YuV5qmf546HDQoNCg0KPGNlbnRlcj4NCg0KIVvlnJbkuIDjgIHpoaflrqLlg7nlgLznrqHnkIbnmoTlsaTmrKFdKGZpZy9maWcxLnBuZykNCg0KPC9jZW50ZXI+DQoNCjxicj7lvp7pgJnkuIDkupvliIbmnpDmiJHlgJHlj6/ku6XnnIvliLDlhazlj7jkuLvopoHnmoTnh5/mlLblkoznjbLliKnnmoTph43opoHkvobmupDvvIzmiJHlgJHkuZ/lj6/ku6XnnIvliLDpgJnkuIDkupvnlKLnlJ/njbLliKnnmoTnvqTntYTmmK/kuI3mmK/mnInmiJDplbfmiJbogIXoobDpgIDnmoTotqjli6LvvJvmk5rmraTmiJHlgJHlj6/ku6XoqK3lrprooYzpirfnmoTph43pu57vvIzmsbrlrprooYzpirfnmoTnrZbnlaXvvIzlkozopo/lioPooYzpirfnmoTlt6XlhbfjgILpmaTkuobkuIrov7DnmoTmlZjov7DntbHoqIjjgIHpm4bnvqTliIbmnpDjgIHlkozos4fmlpnoppboprrljJbkuYvlpJbvvIzmiJHlgJHpgoTlj6/ku6XliKnnlKjpgJnkupvnsKHllq7nmoTkuqTmmJPntIDpjITvvJoNCg0KKyAqKuW7uueri+mgkOa4rOaAp+aooeWeiyoq77yM6aCQ5ris5q+P5LiA5L2N6aGn5a6i55qE77yaDQogICAgKyDkv53nlZnmqZ/njocNCiAgICArIOmgkOacn+eHn+aUtg0KICAgICsg57WE6ZaT6K6K5o+b5qmf546HDQogICAgKyDkuIvmrKHlj6/og73os7zosrfmmYLplpMNCg0KPGJyPuWIqeeUqOmAmeS4gOS6m+mgkOa4rOaIkeWAkeWwseWPr+S7pemAsuihjOWFqOmdouWuouijveWMlueahO+8miANCg0KKyAqKumhp+WuouWDueWAvOeuoeeQhioq77yaDQogICAgKyDpoaflrqLntYLnlJ/lg7nlgLwNCiAgICArIOmhp+WuouWQuOaUtuetlueVpQ0KICAgICsg6aGn5a6i55m85bGV562W55WlDQogICAgKyDpoaflrqLkv53nlZnnrZbnlaUNCg0KKyAqKumHneWwjeaAp+ihjOmKtyoq77yaDQogICAgKyDoqK3oqIjooYzpirfmlrnmoYgNCiAgICArIOmBuOaTh+ihjOmKt+aWueahiA0KICAgICsg6YG45pOH6KGM6Yq35bCN6LGhDQoNCg0KPGNlbnRlcj4NCg0KIVvlnJbkuozjgIHpoaflrqLlg7nlgLznrqHnkIbmtYHnqItdKGZpZy9maWcyLnBuZykNCg0KPC9jZW50ZXI+DQoNCg0KDQo8YnI+PGhyPg0KDQojIyMjIyBTZXR1cCANCmBgYHtyfQ0KU3lzLnNldGxvY2FsZSgiTENfQUxMIiwiQyIpDQpwYWNrYWdlcyA9IGMoDQogICJkcGx5ciIsImdncGxvdDIiLCJnb29nbGVWaXMiLCJkZXZ0b29scyIsIm1hZ3JpdHRyIiwiY2FUb29scyIsIlJPQ1IiLCJjYVRvb2xzIikNCmV4aXN0aW5nID0gYXMuY2hhcmFjdGVyKGluc3RhbGxlZC5wYWNrYWdlcygpWywxXSkNCmZvcihwa2cgaW4gcGFja2FnZXNbIShwYWNrYWdlcyAlaW4lIGV4aXN0aW5nKV0pIGluc3RhbGwucGFja2FnZXMocGtnKQ0KDQppZighaXMuZWxlbWVudCgiY2hvcmRkaWFnIiwgZXhpc3RpbmcpKQ0KICBkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoIm1hdHRmbG9yL2Nob3JkZGlhZyIpDQpgYGANCg0KKw0KDQojIyMjIyBMaWJyYXJ5DQpgYGB7ciBlY2hvPVQsIG1lc3NhZ2U9RiwgY2FjaGU9Riwgd2FybmluZz1GfQ0Kcm0obGlzdD1scyhhbGw9VCkpDQpvcHRpb25zKGRpZ2l0cz00LCBzY2lwZW49MTIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShjYVRvb2xzKQ0KbGlicmFyeShST0NSKQ0KbGlicmFyeShnb29nbGVWaXMpDQpsaWJyYXJ5KGNob3JkZGlhZykNCmBgYA0KPGJyPjxocj4NCg0KIyMjIDEgMS4g6LOH5paZ5pW055CGDQoNCiMjIyMjIDEuMSDkuqTmmJPos4fmlpkgKFgpDQpgYGB7cn0NClggPSByZWFkLnRhYmxlKA0KICAncHVyY2hhc2VzLnR4dCcsIGhlYWRlcj1GQUxTRSwgc2VwPSdcdCcsIHN0cmluZ3NBc0ZhY3RvcnM9RikNCm5hbWVzKFgpID0gYygnY2lkJywnYW1vdW50JywnZGF0ZScpDQpYJGRhdGUgPSBhcy5EYXRlKFgkZGF0ZSkNCnN1bW1hcnkoWCkgICAgICAgICAgICAgICAgICAjIOS6pOaYk+asoeaVuCA1MTI0Mw0KYGBgDQogKirnqIvlvI/norzoqqrmmI4qKg0KIA0KKyDlsIfmqpTmoYjoroDpgLJ0YWJsZSxoZWFkZXI9RkFMU0XvvIzku6PooajmqpTmoYjmspLmnInorormlbjlkI3nqLHvvIxzZXA9J1x0J++8jOS7o+ihqOS+neeFp1x05L6G5YiH5YiG5qqU5qGI77yMc3RyaW5nc0FzRmFjdG9ycz1G77yM5Luj6KGo5LiN55So6K6K5oiQ6aGe5Yil44CCDQorIG5hbWVzKFgpID0gYygnY2lkJywnYW1vdW50JywnZGF0ZScp77yM5bCH6K6K5pW45Y+W5ZCNDQorIFgkZGF0ZSA9IGFzLkRhdGUoWCRkYXRlKeWwh+aqlOahiOS4reaXpeacn+i9ieaIkHLkuK3nmoTml6XmnJ/moLzlvI8NCg0KICoq5Z+36KGM5oSP5ra1KioNCiANCisg6K6A5Y+W5qqU5qGI5piv56ys5LiA5q2l5Lmf5piv5pyA6YeN6KaB55qE5LiA5q2l77yM5Zyo5LiA6ZaL5aeL5bCH5qqU5qGI5qC85byP5pW055CG5YiH5YiG5b6M77yM5Y+v5Lul5pyJ5Yip5b6M6Z2i6LOH5paZ5YiG5p6Q6YCy6KGM77yM5piv57Ch5Zau5L2G6YeN6KaB55qE5LiA5YCL5q2l6amf44CCDQoNCmBgYHtyIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTcuMn0NCnBhcihjZXg9MC44KQ0KaGlzdChYJGRhdGUsICJ5ZWFycyIsIGxhcz0yLCBmcmVxPVQsIHhsYWI9IiIsIG1haW49Ik5vLiBUcmFuc2FjdGlvbiBieSBZZWFyIikNCmBgYA0KICoq56iL5byP56K86Kqq5piOKioNCiANCisgcGFyKGNleD0wLjgp77yM6Kit5a6a5paH5a2X5ZKM56ym6Jmf55qE5a2X6auU5aSn5bCPDQorIGhpc3QoWCRkYXRlLCAieWVhcnMiLCBsYXM9MiwgZnJlcT1ULCB4bGFiPSIiLCBtYWluPSJOby4gVHJhbnNhY3Rpb24gYnkgWWVhciIp77yM55SoWCRkYXRl5L2c54K6eOi7uCxmcmVxPVQs5Lul6aC7546H5L6G6KiI566X77yM5Lim55So5q+P5LiA5bm05L2c54K65YiH5YiG77yMbGFzPTLvvIzpoa/npLp56Lu455qE5ZGI54++5pa55rOV77yMeGxhYj0iIu+8jHhsYWLkuI3lj5blkI3vvIxtYWluPSJOby4gVHJhbnNhY3Rpb24gYnkgWWVhciLvvIzpgJnlvLXlnJbnmoTlkI3nqLHjgIINCiANCiAqKuWft+ihjOaEj+a2tSoqDQogDQorIOimluimuuWMluizh+aWmeW5q+WKqeaIkeWAkeabtOWKoOW/q+mAn+ingOWvn+izh+aWmeaPkOS+m+e1puaIkeWAkeeahOioiuaBr++8jOW+nuWcluS4reaIkeWAkeWPr+S7peeci+WHuu+8jOS6pOaYk+asoeaVuOmAkOW5tOaUgOWNh+OAgg0KYGBge3J9DQpuX2Rpc3RpbmN0KFgkY2lkKSAgICAgICAgICAgIyDpoaflrqLmlbggMTg0MTcNCmBgYA0KICoq56iL5byP56K86Kqq5piOKioNCg0KKyBuX2Rpc3RpbmN0KFgkY2lkKe+8jG5fZGlzdGluY3QoKemAmeWAi2Z1bmN0aW9u5pyD5om+5Ye65LiN6YeN6KSH55qE6aCF55uu77yM5Zyo6YCZ562G6LOH5paZ5Lit5pyJ6Kix5aSa6aGn5a6i57eo56K85piv6YeN6KSH55qE77yM6YCP6YGO6YCZ5YCL5q2l6amf5oiR5YCR5Y+v5Lul566X5Ye66aGn5a6i5pW444CCDQoNCiAqKuWft+ihjOaEj+a2tSoqDQogDQorIOingOWvn+mhp+Wuoue4veaVuA0KDQojIyMjIyAxLjIg6aGn5a6i6LOH5paZIChBKQ0KYGBge3J9DQpBID0gWCAlPiUgDQogIG11dGF0ZShkYXlzID0gYXMuaW50ZWdlcihhcy5EYXRlKCIyMDE2LTAxLTAxIikgLSBkYXRlKSkgJT4lIA0KICBncm91cF9ieShjaWQpICU+JSBzdW1tYXJpc2UoDQogICAgcmVjZW50ID0gbWluKGRheXMpLCAgICAgIyDmnIDov5Hos7zosrfot53ku4rlpKnmlbgNCiAgICBmcmVxID0gbigpLCAgICAgICAgICAgICAjIOizvOiyt+asoeaVuA0KICAgIG1vbmV5ID0gbWVhbihhbW91bnQpLCAgICMg5bmz5Z2H6LO86LK36YeR6aGNDQogICAgc2VuaW9yID0gbWF4KGRheXMpLCAgICAgIyDnrKzkuIDmrKHos7zosrfot53ku4rlpKnmlbgNCiAgICBzaW5jZSA9IG1pbihkYXRlKSAgICAgICAjIOesrOS4gOasoeizvOiyt+aXpeacnw0KICApICU+JSBkYXRhLmZyYW1lDQpgYGANCiAqKueoi+W8j+eivOiqquaYjioqDQogDQogKyBtdXRhdGUoZGF5cyA9IGFzLmludGVnZXIoYXMuRGF0ZSgiMjAxNi0wMS0wMSIpIC0gZGF0ZSkp5Ym16YCg5LiA5YCL5paw55qE6K6K5pW4ZGF5c++8jOWFp+WuueeCujIwMTYtMDEtMDEgLSDkuqTmmJPnmbznlJ/nmoTml6XmnJ/vvIzlhYjnlKjml6XmnJ/moLzlvI/kvoboqIjnrpfvvIzlho3kvb/nlKhhcy5pbnRlZ2Vy6L2J5oiQ5pW45a2X5qC85byP44CCDQogKyBncm91cF9ieShjaWQp57aB5L2P6aGn5a6i57eo56K8DQogKyDlsIfmlrDlop7nmoTorormlbjkuIDotbfovYnmiJBkYXRhLmZyYW1lIEEgDQogDQogKirln7fooYzmhI/mtrUqKg0KIA0KICsg6KeA5a+f5YCL5Yil6aGn5a6i55qE5raI6LK76KGM54K677yM6YCP6YGO5paw5aKe6Kix5aSa6K6K5pW477yM6IO95bmr5Yqp5oiR5YCR5b6M6Z2i55qE5YiG5p6Q44CCDQogDQojIyMjIyAxLjQg6aGn5a6i6LOH5paZ5pGY6KaBDQpgYGB7cn0NCnN1bW1hcnkoQSkNCmBgYA0KDQojIyMjIyAxLjUg6K6K5pW455qE5YiG5biD54uA5rOBDQpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04fQ0KcDAgPSBwYXIoY2V4PTAuOCwgbWZyb3c9YygyLDIpLCBtYXI9YygzLDMsNCwyKSkNCmhpc3QoQSRyZWNlbnQsMjAsbWFpbj0icmVjZW5jeSIseWxhYj0iIix4bGFiPSIiKQ0KaGlzdChwbWluKEEkZnJlcSwgMTApLDA6MTAsbWFpbj0iZnJlcXVlbmN5Iix5bGFiPSIiLHhsYWI9IiIpDQpoaXN0KEEkc2VuaW9yLDIwLG1haW49InNlbmlvcml0eSIseWxhYj0iIix4bGFiPSIiKQ0KaGlzdChsb2coQSRtb25leSwxMCksLG1haW49ImxvZyhtb25leSkiLHlsYWI9IiIseGxhYj0iIikNCmBgYA0KICoq56iL5byP56K86Kqq5piOKioNCiANCisgcDAgPSBwYXIoY2V4PTAuOCwgbWZyb3c9YygyLDIpLCBtYXI9YygzLDMsNCwyKSnvvIxjZXjoqK3lrprlrZfpq5TlpKflsI/vvIxtZnJvd+ioreWumuWclueahOaOkuWIl+aWueW8j++8jG1hcuioreWumuWclueahOmCiuahhuWkp+Wwj+OAgg0KKyBoaXN0KEEkcmVjZW50LDIwLG1haW49InJlY2VuY3kiLHlsYWI9IiIseGxhYj0iIinvvIznuaroo73poaflrqLmnIDov5Hos7zosrfmk5rku4rlpKnmlbjnmoTmn7Hni4DlnJbvvIwyMOagueafseWtkO+8jOaomemhjOeCunJlY2VuY3nvvIx45ZKMeei7uOmDveS4jeWPluWQjeWtkOOAgg0KKyBoaXN0KHBtaW4oQSRmcmVxLCAxMCksMDoxMCxtYWluPSJmcmVxdWVuY3kiLHlsYWI9IiIseGxhYj0iIinvvIznuaroo73poaflrqLos7zosrfmrKHmlbjnmoTmn7Hni4DlnJbvvIxwbWluKEEkZnJlcSwgMTAp5bCHZnJlceWPlnBtaW4xMO+8jOmrmOaWvDEw5qyh6YO95LulMTDmrKHoqIjnrpfvvIwwOjEw77yM6Kit5a6aeOi7uOWAvO+8jOaomemhjOeCumZyZXF1ZW5jee+8jHjlkox56Lu46YO95LiN5Y+W5ZCN44CCDQorIGhpc3QoQSRzZW5pb3IsMjAsbWFpbj0ic2VuaW9yaXR5Iix5bGFiPSIiLHhsYWI9IiIp77yM57mq6KO96aGn5a6i56ys5LiA5qyh6LO86LK35pOa5LuK5aSp5pW455qE5p+x54uA5ZyW77yMMjDmoLnmn7HlrZDvvIzmqJnpoYzngrpzZW5pb3JpdHnvvIx45ZKMeei7uOmDveS4jeWPluWQjeWtkOOAgg0KKyBoaXN0KGxvZyhBJG1vbmV5LDEwKSwsbWFpbj0ibG9nKG1vbmV5KSIseWxhYj0iIix4bGFiPSIiKe+8jOe5quijvemhp+WuouW5s+Wdh+izvOiyt+mHkemhjeafseeLgOWclu+8jOWwh21vbmV55Y+WbG9n77yM5qiZ6aGM54K6bG9nKG1vbmV5Ke+8jHjlkox56Lu46YO95LiN5Y+W5ZCN5a2Q44CCDQoNCiAqKuWft+ihjOaEj+a2tSoqDQoNCisg5bCH5Zub6aCF6K6K5pW46LOH5paZ6KaW6Ka65YyW77yM5Y+v5Lul6KeA5a+f5Ye65ZCE6K6K5pW455qE5YiG5biD54uA5rOB44CCDQoNCjxicj48aHI+DQoNCg0KIyMjIDIuIOWxpOe0muW8j+mbhue+pOWIhuaekA0KDQojIyMjIyAyLjEgUkZN6aGn5a6i5YiG576kDQpgYGB7cn0NCnNldC5zZWVkKDExMSkNCkEkZ3JwID0ga21lYW5zKHNjYWxlKEFbLDI6NF0pLDEwKSRjbHVzdGVyDQp0YWJsZShBJGdycCkgICMg5peP576k5aSn5bCPDQpgYGANCiAqKueoi+W8j+eivOiqquaYjioqDQogDQorIEEkZ3JwID0ga21lYW5zKHNjYWxlKEFbLDI6NF0pLDEwKSRjbHVzdGVy77yM5bCHQeS4reiuiuaVuDLliLA05Y+W5bi45oWL5YiG5L2I77yM5o6l6JGX5L2/55Soa21lYW5z5bCH5a6D5YiG5oiQMTDnvqTvvIzmjqXokZflsIfku5ZjbHVzdGVy55qE5YiG5biD5a2Y6YCy5paw55qE6K6K5pW4Z3JwDQorIHRhYmxlKEEkZ3JwKe+8jOWwh+avj+S4gOe+pOaVuOmHj+WIhuS9iOWNsOWHuuS+huOAgg0KDQogKirln7fooYzmhI/mtrUqKg0KDQorIOWIhue+pOW+jOaWueS+v+W+jOmdoumgkOa4rA0KDQojIyMjIyAyLjIg6aGn5a6i576k57WE5bGs5oCnDQpgYGB7ciBmaWcuaGVpZ2h0PTQuNSwgZmlnLndpZHRoPTh9DQpncm91cF9ieShBLCBncnApICU+JSBzdW1tYXJpc2UoDQogIHJlY2VudD1tZWFuKHJlY2VudCksIA0KICBmcmVxPW1lYW4oZnJlcSksIA0KICBtb25leT1tZWFuKG1vbmV5KSwgDQogIHNpemU9bigpICkgJT4lIA0KICBtdXRhdGUoIHJldmVudWUgPSBzaXplKm1vbmV5LzEwMDAgKSAgJT4lIA0KICBmaWx0ZXIoc2l6ZSA+IDEpICU+JSANCiAgZ2dwbG90KGFlcyh4PWZyZXEsIHk9bW9uZXkpKSArDQogIGdlb21fcG9pbnQoYWVzKHNpemU9cmV2ZW51ZSwgY29sPXJlY2VudCksYWxwaGE9MC41KSArDQogIHNjYWxlX3NpemUocmFuZ2U9Yyg0LDMwKSkgKw0KICBzY2FsZV9jb2xvcl9ncmFkaWVudChsb3c9ImdyZWVuIixoaWdoPSJyZWQiKSArDQogIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAobGltaXRzPWMoMzAsMzAwMCkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzaXplICksc2l6ZT0zKSArDQogIHRoZW1lX2J3KCkgKyBndWlkZXMoc2l6ZT1GKSArDQogIGxhYnModGl0bGU9IkN1c3RvbWVyIFNlZ2VtZW50cyIsDQogICAgICAgc3VidGl0bGU9IihidWJibGVfc2l6ZTpyZXZlbnVlX2NvbnRyaWJ1dGlvbjsgdGV4dDpncm91cF9zaXplKSIsDQogICAgICAgY29sb3I9IlJlY2VuY3kiKSArDQogIHhsYWIoIkZyZXF1ZW5jeSAobG9nKSIpICsgeWxhYigiQXZlcmFnZSBUcmFuc2FjdGlvbiBBbW91bnQgKGxvZykiKQ0KYGBgDQoNCiAqKueoi+W8j+eivOiqquaYjioqDQogDQorIGdyb3VwX2J5KEEsIGdycCkgJT4lIHN1bW1hcmlzZShyZWNlbnQ9bWVhbihyZWNlbnQpLCBmcmVxPW1lYW4oZnJlcSksbW9uZXk9bWVhbihtb25leSksIHNpemU9bigpLOWFiOWwh0Hos4fmlpnmoLzlvI9ncm91cCBieSBncnAs5Luj6KGo5b6M6Z2ic3VtbWFyaXNl5pmC5LulZ3JvdXDkvoboqIjnrpfvvIzlvozpnaLlsIfmnIDov5Hos7zosrfot53ku4rlpKnmlbjjgIEg6LO86LK35qyh5pW444CB6YeR6aGN5LiJ5qij5pW45pOa5Y+W5bmz5Z2H77yMc2l6ZT1uKCnnrpflh7rmr4/nvqTnmoTlpKflsI/jgIINCisgbXV0YXRlKCByZXZlbnVlID0gc2l6ZSptb25leS8xMDAwICklPiUgZmlsdGVyKHNpemUgPiAxKeaWsOWinuS4gOWAi+iuiuaVuOeCunJldmVudWXvvIzkuKblsIfoqIjnrpflh7rkvoZzaXplID4gMeeahOWhnuWHuuS+hg0KKyBnZ3Bsb3QoYWVzKHg9ZnJlcSwgeT1tb25leSkpICsNCiAgZ2VvbV9wb2ludChhZXMoc2l6ZT1yZXZlbnVlLCBjb2w9cmVjZW50KSxhbHBoYT0wLjUpICsNCiAgc2NhbGVfc2l6ZShyYW5nZT1jKDQsMzApKSArDQogIHNjYWxlX2NvbG9yX2dyYWRpZW50KGxvdz0iZ3JlZW4iLGhpZ2g9InJlZCIpICsNCiAgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMChsaW1pdHM9YygzMCwzMDAwKSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNpemUgKSxzaXplPTMpICsNCiAgdGhlbWVfYncoKSArIGd1aWRlcyhzaXplPUYpICsNCiAgbGFicyh0aXRsZT0iQ3VzdG9tZXIgU2VnZW1lbnRzIiwNCiAgICAgICBzdWJ0aXRsZT0iKGJ1YmJsZV9zaXplOnJldmVudWVfY29udHJpYnV0aW9uOyB0ZXh0Omdyb3VwX3NpemUpIiwNCiAgICAgICBjb2xvcj0iUmVjZW5jeSIpICsNCiAgeGxhYigiRnJlcXVlbmN5IChsb2cpIikgKyB5bGFiKCJBdmVyYWdlIFRyYW5zYWN0aW9uIEFtb3VudCAobG9nKSIpDQogIOeUqGdncGxvdOS+hue5quijve+8jHjou7jmlL7lubPlnYfos7zosrfmrKHmlbjvvIx55pS+5bmz5Z2H6LO86LK36YeR6aGN77yM5ZyW5b2i5LiK55qE6bue77yM5aSn5bCP54K65Yip5r2k6LKi542777yM6aGP6Imy54K65bmz5Z2H5pyA6L+R6LO86LK35pOa5LuK5aSp5pW477yM6YCP5piO5bqmMC4177yM5ZyT5ZyI5aSn5bCP54K6NH4zMO+8jOiqv+iJsueCuuaVuOWAvOi2iuS9jueCuue2oOiJsu+8jOi2iumrmOeCuue0heiJsu+8jHjlkox56Lu455qE5YC85Y+WbG9nMTDvvIx555qE5Y6f5pys5YC86Kit5a6a5ZyoMzB+MzAwMOmWk++8jOevqeaOiemboue+pOWAvO+8jOWtl+mrlOWkp+Wwj+ioreWumueCujPvvIzkuLvpoYzoqK3lrprngrpid++8jOacgOW+jOWGjeW5q+WcluaqlOWPluWQje+8jFjou7hZ6Lu45Y+W5ZCN44CCDQogDQogKirln7fooYzmhI/mtrUqKg0KDQorIOmAj+mBjuWwh+S4jeWQjOe+pOmhp+WuoueahOa2iOiyu+e/kuaAp+mAj+mBjuimluimuuWMluWIhumhnuWHuuS+hu+8jOWPr+S7peiuk+aIkeWAkeW/q+mAn+eZvOePvuS7luWAkeW3rueVsO+8jOS4puacieWIqeaIkeWAkeS5i+W+jOmHneWwjeS4jeWQjOe+pOmhp+WuouWft+ihjOS4jeWQjOihjOmKt+etlueVpeOAgg0KPGJyPjxocj4NCg0KIyMjIDMuIOimj+WJh+WIhue+pA0KDQojIyMjIyAzLjEg6aGn5a6i5YiG576k6KaP5YmHDQpgYGB7cn0NClNUUyA9IGMoIk4xIiwiTjIiLCJSMSIsIlIyIiwiUzEiLCJTMiIsIlMzIikNClN0YXR1cyA9IGZ1bmN0aW9uKHJ4LGZ4LG14LHN4LEspIHtmYWN0b3IoDQogIGlmZWxzZShzeCA8IDIqSywNCiAgICAgICAgIGlmZWxzZShmeCpteCA+IDUwLCAiTjIiLCAiTjEiKSwNCiAgICAgICAgIGlmZWxzZShyeCA8IDIqSywNCiAgICAgICAgICAgICAgICBpZmVsc2Uoc3gvZnggPCAwLjc1KkssIlIyIiwiUjEiKSwNCiAgICAgICAgICAgICAgICBpZmVsc2UocnggPCAzKkssIlMxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHJ4IDwgNCpLLCJTMiIsIlMzIikpKSksIFNUUyl9DQpgYGANCiAqKueoi+W8j+eivOiqquaYjioqDQogDQorIFNUUyA9IGMoIk4xIiwiTjIiLCJSMSIsIlIyIiwiUzEiLCJTMiIsIlMzIinvvIzlu7rnq4vkuIDlgIvlkJHph48NCisg5bu656uLU3RhdHVzZnVuY3Rpb27vvIxzeDwya+aIkOeri+WJjeaPkOS4i++8jOS4lGZ4XCpteOaIkOeri++8jOeCuk4y77yM5LiN5piv5YmH54K6TjHvvIzoi6VzeDwyXCpr5LiN5oiQ56uL5YmN5o+Q5LiL77yMcng8MlwqS+aIkOeri++8jOS4lHN4L2Z4PDAuNzXmiJDnq4vvvIzngrpSMu+8jOS4jeaYr+WJh+eCulIx77yM6Iulcng8MlwqS+S4jeaIkOeri+S4lHJ4PDNcKkvvvIzngrpTMe+8jOiLpeS4iui/sOeahuS4jeaIkOeri++8jHJ4PDRcKkvngrpTMu+8jOS4jeaIkOeri+WJh+eCulMzDQoNCiAqKuWft+ihjOaEj+a2tSoqDQogDQorIOWFiOWwh+mhp+WuouWIhue+pOaineS7tuioreWumuWlve+8jOacieWIqeW+jOmdoumhp+WuouWIhuaekOOAgg0KDQo8Y2VudGVyPg0KDQohW+WcluS4ieOAgemhp+WuouWIhue+pOimj+WJh10oZmlnL2ZpZzMuamZpZikNCg0KPC9jZW50ZXI+DQoNCiMjIyMjIDMuMiDlubPlnYfos7zosrfpgLHmnJ8NCmBgYHtyfQ0KSyA9IGFzLmludGVnZXIoc3VtKEEkc2VuaW9yW0EkZnJlcT4xXSkgLyBzdW0oQSRmcmVxW0EkZnJlcT4xXSkpOyBLDQpgYGANCuWbnuizvOmhp+WuoueahOW5s+Wdh+izvOiyt+mAseacnyBgSyA9IDUyMSBkYXlzYA0KDQogKirnqIvlvI/norzoqqrmmI4qKg0KDQorIOWwh+izvOiyt+asoeaVuOWkp+aWvOS4gOmhp+WuoueahOesrOS4gOasoei3neS7iuizvOiyt+WkqeaVuC/os7zosrfmrKHmlbjlpKfmlrzkuIDpoaflrqLnmoTnuL3kvoblupfmrKHmlbjjgIINCg0KICoq5Z+36KGM5oSP5ra1KioNCiANCisg6KiI566X5Ye65Zue6LO86aGn5a6i55qE5bmz5Z2H6LO86LK36YCx5pyf44CCDQoNCg0KIyMjIyMgMy4zIOa7keWLleizh+aWmeeql+agvA0KYGBge3J9DQpZID0gbGlzdCgpICAgICAgICAgICAgICAjIOW7uueri+S4gOWAi+epuueahExJU1QNCmZvcih5IGluIDIwMTA6MjAxNSkgeyAgICMg5q+P5bm05bm05bqV5bCH6aGn5a6i6LOH5paZ5b2Z5pW05oiQ5LiA5YCL6LOH5paZ5qGGDQogIEQgPSBhcy5EYXRlKHBhc3RlMChjKHksIHktMSksIi0xMi0zMSIpKSAjIOeVtuacn+OAgeWJjeacn+eahOacn+acq+aXpeacnyANCiAgWVtbcGFzdGUwKCJZIix5KV1dID0gWCAlPiUgICAgICAgICMg5b6e5Lqk5piT6LOH5paZ5YGa6LW3DQogICAgZmlsdGVyKGRhdGUgPD0gRFsxXSkgJT4lICAgICAgICAjIOWwh+izh+aWmeWIh+m9iuWIsOacn+acq+aXpeacnw0KICAgIG11dGF0ZShkYXlzID0gMSArIGFzLmludGVnZXIoRFsxXSAtIGRhdGUpKSAlPiUgICAjIOS6pOaYk+i3neacn+acq+WkqeaVuA0KICAgIGdyb3VwX2J5KGNpZCkgJT4lIHN1bW1hcmlzZSggICAgIyDkvp3poaflrqLlvZnnuL0gLi4uDQogICAgICByZWNlbnQgPSBtaW4oZGF5cyksICAgICAgICAgICAjICAg5pyA5b6M5LiA5qyh6LO86LK36Led5pyf5pyr5aSp5pW4ICAgDQogICAgICBmcmVxID0gbigpLCAgICAgICAgICAgICAgICAgICAjICAg6LO86LK35qyh5pW4ICjoh7PmnJ/mnKvngrrmraIpICAgDQogICAgICBtb25leSA9IG1lYW4oYW1vdW50KSwgICAgICAgICAjICAg5bmz5Z2H6LO86LK36YeR6aGNICjoh7PmnJ/mnKvngrrmraIpDQogICAgICBzZW5pb3IgPSBtYXgoZGF5cyksICAgICAgICAgICAjICAg56ys5LiA5qyh6LO86LK36Led5pyf5pyr5aSp5pW4DQogICAgICBzdGF0dXMgPSBTdGF0dXMocmVjZW50LGZyZXEsbW9uZXksc2VuaW9yLEspLCAgIyDmnJ/mnKvni4DmhYsNCiAgICAgIHNpbmNlID0gbWluKGRhdGUpLCAgICAgICAgICAgICAgICAgICAgICAjIOesrOS4gOasoeizvOiyt+aXpeacnw0KICAgICAgeV9mcmVxID0gc3VtKGRhdGUgPiBEWzJdKSwgICAgICAgICAgICAgICMg55W25pyf6LO86LK35qyh5pW4DQogICAgICB5X3JldmVudWUgPSBzdW0oYW1vdW50W2RhdGUgPiBEWzJdXSkgICAgIyDnlbbmnJ/os7zosrfph5HpoY0NCiAgICApICU+JSBkYXRhLmZyYW1lIH0NCmBgYA0KICoq56iL5byP56K86Kqq5piOKioNCiANCisgZm9yKHkgaW4gMjAxMDoyMDE1KeW7uueri+S4gOWAi+i/tOWciO+8jHnmnIPlvp4yMDEw5YiwMjAxNeWft+ihjOS4i+mdoumCo+auteeoi+W8j+eivOOAgg0KKyBEID0gYXMuRGF0ZShwYXN0ZTAoYyh5LCB5LTEpLCItMTItMzEiKSnvvIxwYXN0ZTDmnIPmtojpmaTlubTku73mjqXmnIjku73mmYJzZXA9IiLpgqPlgIvnqbrnmb3vvIzljbDlh7rkvobnmoTml6XmnJ/mnIPmnInlhanlgIvvvIzliIbliKXmmK/liY3kuIDlubTlkozku4rlubTnmoQxMuaciDMx5pel77yMZXg6IjIwMTUtMTItMzEiICIyMDE0LTEyLTMxIu+8jOWGjei9ieaIkOaXpeacn+agvOW8j+OAgg0KKyDlu7rnq4vkuIDlgIvnqbrnmoRMSVNU77yM5q+P5bm05bm05bqV5bCH6aGn5a6i6LOH5paZ5b2Z5pW05oiQ5LiA5YCL6LOH5paZ5qGG77yM55W25pyf44CB5YmN5pyf55qE5pyf5pyr5pel5pyfIO+8jOW+nuS6pOaYk+izh+aWmeWBmui1t++8jOWwh+izh+aWmeWIh+m9iuWIsOacn+acq+aXpeacn++8jOS6pOaYk+i3neacn+acq+WkqeaVuO+8jOS+nemhp+WuouW9mee4vSAuLi7vvIzmnIDlvozkuIDmrKHos7zosrfot53mnJ/mnKvlpKnmlbjvvIzos7zosrfmrKHmlbggKOiHs+acn+acq+eCuuatoinvvIzlubPlnYfos7zosrfph5HpoY0gKOiHs+acn+acq+eCuuatoinvvIznrKzkuIDmrKHos7zosrfot53mnJ/mnKvlpKnmlbjvvIzmnJ/mnKvni4DmhYvvvIznrKzkuIDmrKHos7zosrfml6XmnJ/vvIznlbbmnJ/os7zosrfmrKHmlbjvvIznlbbmnJ/os7zosrfph5HpoY3jgIINCg0KICoq5Z+36KGM5oSP5ra1KioNCg0KKyDlsIfos4fmlpnmjInlubTku73liIflibLvvIzlj6/ku6XlgZrlh7rkvobmr4/kuIDlubTlgIvliKXnmoTliIbmnpDvvIzmlrnkvr/kuYvlvozpoJDmuKzkuIvkuIDlubTnmoTpoaflrqLmtojosrvooYzngrrjgIINCg0KYGBge3J9DQpoZWFkKFkkWTIwMTUpDQpgYGANCiAqKueoi+W8j+eivOiqquaYjioqDQogDQorIOWNsOWHujIwMTXlubTliY3kupTnrYbos4fmlpkNCg0KICoq5Z+36KGM5oSP5ra1KioNCiANCisg6KeA5a+fMjAxNeW5tOWJjeS6lOethuizh+aWmQ0KIyMjIyMgMy40IOavj+W5tOW5tOW6leeahOe0r+ioiOmhp+WuouS6uuaVuA0KYGBge3J9DQpzYXBwbHkoWSwgbnJvdykNCmBgYA0KICoq56iL5byP56K86Kqq5piOKioNCg0KKyDkvb/nlKhzYXBwbHnlsIdZIGxzaXTkuK3lha3lgItkYXRhIGZyYW1lIOeahHJvd+aVuOmHj+WNsOWHuuS+huOAgg0KDQogKirln7fooYzmhI/mtrUqKg0KDQorIOingOWvnzblubTkvobnmoTpoaflrqLnuL3mlbjph48NCg0KIyMjIyMgMy41IOaXj+e+pOWkp+Wwj+iuiuWMlui2qOWLog0KYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OH0NCmNvbHMgPSBjKCJnb2xkIiwib3JhbmdlIiwiYmx1ZSIsImdyZWVuIiwicGluayIsIm1hZ2VudGEiLCJkYXJrcmVkIikNCnNhcHBseShZLCBmdW5jdGlvbihkZikgdGFibGUoZGYkc3RhdHVzKSkgJT4lIGJhcnBsb3QoY29sPWNvbHMpDQpsZWdlbmQoInRvcGxlZnQiLHJldihTVFMpLGZpbGw9cmV2KGNvbHMpKQ0KYGBgDQogKirnqIvlvI/norzoqqrmmI4qKg0KIA0KKyDlhYjoqK3lrprkuIDlgIvpoY/oibLnmoTlkJHph4/vvIzlsIfmr4/lgItZ6KOh55qEZGF0YSBmcmFtZeeahHN0YXR1c+aVuOmHj+imluimuuWMlu+8jOmhj+iJsueCuuWQkemHj+ioreWumueahOmhj+iJsu+8jOaOpeiRl+WKoOWFpeaXgeevh+eahOiqv+iJsuaine+8jOWwh1NUU+WSjGNvbHPpg73lgJLpgY7kvobjgIINCg0KICoq5Z+36KGM5oSP5ra1KioNCg0KKyDoppboprrljJbmr4/kuIDlubTku73kuI3lkIxzdGF0dXPnmoTmlbjph48NCg0KIyMjIyMgMy42IOaXj+e+pOWxrOaAp+WLleaFi+WIhuaekA0KYGBge3J9DQpDdXN0U2VnbWVudHMgPSBkby5jYWxsKHJiaW5kLCBsYXBwbHkoWSwgZnVuY3Rpb24oZCkgew0KICBncm91cF9ieShkLCBzdGF0dXMpICU+JSBzdW1tYXJpc2UoDQogICAgYXZlcmFnZV9mcmVxdWVuY3kgPSBtZWFuKGZyZXEpLA0KICAgIGF2ZXJhZ2VfYW1vdW50ID0gbWVhbihtb25leSksDQogICAgdG90YWxfcmV2ZW51ZSA9IHN1bSh5X3JldmVudWUpLA0KICAgIHRvdGFsX25vX29yZGVycyA9IHN1bSh5X2ZyZXEpLA0KICAgIGF2ZXJhZ2VfcmVjZW5jeSA9IG1lYW4ocmVjZW50KSwNCiAgICBhdmVyYWdlX3Nlbmlvcml0eSA9IG1lYW4oc2VuaW9yKSwNCiAgICBncm91cF9zaXplID0gbigpDQogICl9KSkgJT4lIHVuZ3JvdXAgJT4lIA0KICBtdXRhdGUoeWVhcj1yZXAoMjAxMDoyMDE1LCBlYWNoPTcpKSAlPiUgZGF0YS5mcmFtZQ0KaGVhZChDdXN0U2VnbWVudHMpDQpgYGANCiAqKueoi+W8j+eivOiqquaYjioqDQogDQorIOWwh3noo6HnmoRkYXRhIGZyYW1lIOS+neeFp3N0YXR1c+Wbiue4ve+8jOeul+WHuuW5s+Wdh+S+huW6l+asoeaVuOOAgeW5s+Wdh+izvOiyt+mHkemhjeOAgeW5s+Wdh+eVtuacn+WIqea9pOOAgeeVtuacn+izvOiyt+e4veasoeaVuOOAgeW5s+Wdh+acgOi/kei3neS7iuizvOiyt+WkqeaVuOOAgeW5s+Wdh+esrOS4gOasoeWIsOW6l+i3neS7iuWkqeaVuOWSjOavj+S4gOe+pOS6uuaVuO+8jOaOpeiRl+WGjeWwh+e+pOe1hOaJk+aVo++8jOWwhzIwMTDliLAyMDE16YeN6KSHNuasoeWwjeaHiTflgIvkuI3lkIxzdGF0dXPvvIzmiormoLzlvI/lrZjmiJBkYXRhLmZyYW1l77yM54S25b6M5Y2w5Ye65YmNNuihjA0KDQogKirln7fooYzmhI/mtrUqKg0KIA0KKyDlsIc25bm05q+P5YCLc3RhdHVz55qE6K6K5YyW5YGa5oiQZGF0YS5mcmFtZe+8jOS7peWIqeWcqOW+jOmdouimluimuuWMluWIhuaekOOAgg0KYGBge3IgZXZhbD1GfQ0KcGxvdCggZ3Zpc01vdGlvbkNoYXJ0KA0KICBDdXN0U2VnbWVudHMsICJzdGF0dXMiLCAieWVhciIsDQogIG9wdGlvbnM9bGlzdCh3aWR0aD05MDAsIGhlaWdodD02MDApICkgKQ0KYGBgDQogKirnqIvlvI/norzoqqrmmI4qKg0KDQorIOeUqOWJm+WJm3N0YXR1c+izh+aWmee5quijveS6kuWLleazoeazoeWclu+8jHN0YXR1c+S+neeFp+W5tOWBmuiuiuWMlu+8jOioreWumumVtzkwMETjgIHlr6w2MDDjgIINCg0KICoq5Z+36KGM5oSP5ra1KioNCiANCisg6KaW6Ka65YyW6KeA5a+f5q+P5LiA5bm05LiN5ZCMc3RhdHVz55qE6K6K5YyW44CCDQo8Y2VudGVyPg0KIVvlnJblm5vjgIHpoaflrqLliIbnvqTopo/liYddKGZpZy9maWc0LmpmaWYpDQoNCjwvY2VudGVyPg0KDQoNCiMjIyMjIDMuNyDml4/nvqTlsazmgKfli5XmhYvliIbmnpANCmBgYHtyfQ0KZGYgPSBtZXJnZShZJFkyMDE0WyxjKDEsNildLCBZJFkyMDE1WyxjKDEsNildLA0KICAgICAgICAgICBieT0iY2lkIiwgYWxsLng9VCkNCnR4ID0gdGFibGUoZGYkc3RhdHVzLngsIGRmJHN0YXR1cy55KSAlPiUgDQogIGFzLmRhdGEuZnJhbWUubWF0cml4KCkgJT4lIGFzLm1hdHJpeCgpDQp0eCAgICAjIOa1gemHj+efqemZow0KYGBgDQogKirnqIvlvI/norzoqqrmmI4qKg0KDQorIOWwh1kgbGlzdOS4rTIwMTTlkowyMDE15bm055qEY2lk5ZKMc3RhdHVz77yM55SoY2lk5ZuK5ousDQorIOaOpeiRl+Wwh+S7luWAkeWFqeWAi+aTuumAsnRhYmxl5YiG5p6Q77yMMjAxNOWIsDIwMTXlubRzdGF0dXPnmoTovYnororvvIzkuKbmiorku5blrZjpgLJkYXRhLmZyYW1l5LitDQoNCiAqKuWft+ihjOaEj+a2tSoqDQogDQorIOWwh+S7luiuiuaIkOa1gemHj+efqemZo++8jOS7peWIqeingOWvn3N0YXR1c+eahOiuiuWMluOAgg0KYGBge3J9DQp0eCAlPiUgcHJvcC50YWJsZSgxKSAlPiUgcm91bmQoMykgICAjIOa1gemHj+efqemZoyglKQ0KYGBgDQogKirnqIvlvI/norzoqqrmmI4qKg0KDQorIOWwh+a1gemHj+efqemZo+S4n+mAsnByb2IudGFibGXvvIzmjqHmqZ/njoflvaLlvI/ooajnj77vvIzlj5bliLDlsI/mlbjpu57lvozkuInkvY0NCg0KICoq5Z+36KGM5oSP5ra1KioNCg0KKyDku6XmqZ/njoflvaLlvI/ooajnpLoyMDE05YiwMjAxNeW5tO+8jHN0YXR1c+eahOapn+eOh+i9ieiuiuOAgg0KDQojIyMjIyAzLjgg5LqS5YuV5byP5rWB6YeP5YiG5p6QDQpgYGB7cn0NCmNob3JkZGlhZyh0eCwgZ3JvdXBDb2xvcnM9Y29scykNCmBgYA0KICoq56iL5byP56K86Kqq5piOKioNCg0KKyDlsIfmtYHph4/nn6npmaPkuJ/pgLLkupLli5XlvI/mtYHph4/liIbmnpDvvIzpoY/oibLkvb/nlKjliZvliZvoqK3lrprnmoTpoY/oibLlkJHph48NCg0KICoq5Z+36KGM5oSP5ra1KioNCg0KKyDnlKjkupLli5XlvI/mtYHph4/liIbmnpDlnJbvvIzog73lsIfmtYHph4/nn6npmaPnlKjoppboprrljJblkYjnj77vvIzku6XliKnliIbmnpDjgIINCg0KIVtdKGZpZy9jaG9yZC5qcGcpDQoNCjxicj48aHI+DQoNCiMjIyA0LiDlu7rnq4vmqKHlnosNCg0K5Zyo6YCZ5YCL5qGI5L6L6KOh6Z2i77yM5oiR5YCR55qE6LOH5paZ5piv5pS25YiwWTIwMTXlubTlupXvvIzmiYDku6XmiJHlgJHlj6/ku6XlgYfoqK3nj77lnKjnmoTmmYLplpPmmK9ZMjAxNeW5tOW6le+8jOaIkeWAkeaDs+imgeeUqOePvuacieeahOizh+aWmeW7uueri+aooeWei++8jOS+humgkOa4rOavj+S4gOS9jemhp+Wuou+8mg0KDQorIOWcqFkyMDE25bm05piv5ZCm5pyD5L6G6LO86LK3ICjkv53nlZnnjofvvJpSZXRhaW4pDQorIOWlueS+huizvOiyt+eahOipse+8jOacg+iyt+WkmuWwkemMoiAo6LO86LK36YeR6aGN77yaUmV2ZW51ZSkNCg0K5L2G5piv77yM5oiR5YCR5Lim5rKS5pyJWTIwMTbnmoTos4fmlpnvvIzngrrkuobopoHlu7rnq4vmqKHlnovvvIzmiJHlgJHpnIDopoHlhYjmiormmYLplpPlm57mjqjkuIDmnJ/vvIzkuZ/lsLHmmK/oqqrvvJoNCg0KKyDnlKhZMjAxNOW5tOW6leS7peWJjeeahOizh+aWmeaVtOeQhuWHuumgkOa4rOiuiuaVuChYKSANCisg55SoWTIwMTXlubTnmoTos4fmlpnmlbTnkIblh7rnm67mqJnorormlbgoWSkgDQoNCuWBh+WmglkyMDE255qE5oOF5rOBKOi3n1kyMDE15q+UKeaykuacieWkquWkp+eahOiuiuWMlueahOipse+8jOaOpeS4i+S+huaIkeWAkeWwseWPr+S7pQ0KDQorIOS9v+eUqOipsuaooeWei++8jOS7pVkyMDE15bm05bqV55qE6LOH5paZ77yM6aCQ5risWTIwMTbnmoTni4Dms4ENCg0KIyMjIyMgNC4xIOa6luWCmeizh+aWmQ0K5oiR5YCR55SoWTIwMTTlubTlupXnmoTos4fmlpnlgZroh6rorormlbjvvIxZMjAxNeW5tOeahOizh+aWmeWBmuaHieiuiuaVuA0KDQpgYGB7cn0NCkNYID0gbGVmdF9qb2luKFkkWTIwMTQsIFkkWTIwMTVbLGMoMSw4LDkpXSwgYnk9ImNpZCIpDQpoZWFkKENYKQ0KYGBgDQoNCiAqKueoi+W8j+eivOiqquaYjioqDQogDQorIENYID0gbGVmdF9qb2luKFkkWTIwMTQsIFkkWTIwMTVbLGMoMSw4LDkpXSwgYnk9ImNpZCIpDQorIOWwhyAyMDE0IOW5tOa2iOiyu+iAheWFqOmDqOeahOizh+aWmeiIhyAyMDE1IOW5tOa2iOiyu+iAheWDhea2iOiyu+mgu+eOh+WPiua2iOiyu+mhjeeahOizh+aWme+8jOS7pSBjaWQg5L2c54K65bCN54Wn5ZCI5L21DQogDQogKirln7fooYzmhI/mtrUqKg0KDQorIOWwh+W7uueri+aooeWei+aZguaJgOmcgOimgeeahOiHquiuiuaVuCAoIDIwMTQg6LOH5paZICkg5Lul5Y+K5oeJ6K6K5pW4ICggMjAxNSDos4fmlpkgKSDlkIjkvbXngrrkuIDlgIsgZGF0YS5mcmFtZSDku6XliKnlvoznuozlu7rmqKHkvb/nlKjjgIINCg0KDQpgYGB7cn0NCm5hbWVzKENYKVs4OjExXSA9IGMoImZyZXEwIiwicmV2ZW51ZTAiLCJSZXRhaW4iLCAiUmV2ZW51ZSIpDQpDWCRSZXRhaW4gPSBDWCRSZXRhaW4gPiAwDQpoZWFkKENYKQ0KYGBgDQoNCiAqKueoi+W8j+eivOiqquaYjioqDQogDQorIG5hbWVzKENYKVs4OjExXSA9IGMoImZyZXEwIiwicmV2ZW51ZTAiLCJSZXRhaW4iLCAiUmV2ZW51ZSIpDQorIOmHjeaWsOWRveWQjeWQiOS9temBjuW+jOiiq+ezu+e1seiHquWLleWRveWQjeeahOiuiuaVuOOAgg0KKyBDWCRSZXRhaW4gPSBDWCRSZXRhaW4gPiAwDQorIOWwh+esrOS6jOW5tOa2iOiyu+asoeaVuOmdniAwIOasoeeahOmhp+WuouWIpOWumueCuiBSZXRhaW4gPSBUUlVF44CCDQogDQogKirln7fooYzmhI/mtrUqKg0KDQorIOWwhyBDWCDos4fmlpnmoYblhafnmoTos4fmlpnomZXnkIbmiJDmjqXkuIvkvoblu7rmqKHmiYDpnIDopoHnmoTmoLzlvI/jgIINCg0KDQpgYGB7cn0NCnRhYmxlKENYJFJldGFpbikgJT4lIHByb3AudGFibGUoKSAgIyDlubPlnYfkv53nlZnmqZ/njocgPSAyMi41NCUNCmBgYA0KDQogKirnqIvlvI/norzoqqrmmI4qKg0KIA0KKyB0YWJsZShDWCRSZXRhaW4pICU+JSBwcm9wLnRhYmxlKCkNCisg5bCHIENYIOS4reeahCBSZXRhaW4g6K6K5pW45Lit55qEIFQvRiDmr5TkvovoqIjnrpflh7rkvobjgIINCiANCiAqKuWft+ihjOaEj+a2tSoqDQoNCisg5Yid5q2l5LqG6KejIDIwMTUg5bm06YKE5Ymp5LiL5aSa5bCR5q+U5L6L55qE6aGn5a6i44CCDQoNCg0KIyMjIyMgNC4yIOW7uueri+mhnuWIpeaooeWeiw0KYGBge3J9DQptUmV0ID0gZ2xtKFJldGFpbiB+IC4sIENYWyxjKDI6Myw2LDg6MTApXSwgZmFtaWx5PWJpbm9taWFsKCkpDQpzdW1tYXJ5KG1SZXQpDQpgYGANCg0KICoq56iL5byP56K86Kqq5piOKioNCiANCisgbVJldCA9IGdsbShSZXRhaW4gfiAuLCBDWFssYygyOjMsNiw4OjEwKV0sIGZhbWlseT1iaW5vbWlhbCgpKQ0KKyDlu7rnq4vnvoXlkInmlq/mqKHlnovjgILoh6rorormlbjngrogcmVjZW5044CBZnJlceOAgXN0YXR1c+OAgWZyZXEw44CBcmV2ZW51ZTDvvIzmh4norormlbjngrogUmV0YWlu44CCDQogDQogKirln7fooYzmhI/mtrUqKg0KDQorIOW7uueri+S4gOWAi+S7pSAyMDE0IOW5tOmhp+Wuouizh+aWmeS+humgkOa4rCAyMDE1IOW5tOipsumhp+WuouaYr+WQpuacg+S+hua2iOiyu+eahOe+heWQieaWr+aooeWei+OAgg0KDQojIyMjIyA0LjMg5Lyw6KiI6aGe5Yil5qih5Z6L55qE5rqW56K65oCnDQpgYGB7cn0NCnByZWQgPSBwcmVkaWN0KG1SZXQsdHlwZT0icmVzcG9uc2UiKQ0KdGFibGUocHJlZD4wLjUsQ1gkUmV0YWluKSANCiMg5re35reG55+p6ZmjIChDb25mdXNpb24gTWF0cml4KSAgDQpgYGANCg0KICoq56iL5byP56K86Kqq5piOKioNCiANCisgcHJlZCA9IHByZWRpY3QobVJldCx0eXBlPSJyZXNwb25zZSIpDQorIOWwh+WJjei/sOatpempn+aJgOW7uueri+eahOaooeWei+WFtuingOWvn+WAvOeahOmgkOa4rOWAvOWFqOmDqOWtmOWIsOiuiuaVuCBwcmVkIOS4reOAgg0KKyB0YWJsZShwcmVkPjAuNSxDWCRSZXRhaW4pIA0KKyDlsIfpoZ7liKXpoJDmuKzlgLzoiIflr6bpmpvnmbznlJ/lgLzovYnmj5vngrrmt7fmt4bnn6npmaPjgIINCiANCiAqKuWft+ihjOaEj+a2tSoqDQoNCisg6KiI566X5re35reG55+p6Zmj5Y+v5Lul5bmr5Yqp5oiR5YCR5LqG6Kej5qih5Z6L55qE6aCQ5ris6KGo54++5aaC5L2V44CCDQoNCmBgYHtyfQ0KdGFibGUocHJlZD4wLjUsQ1gkUmV0YWluKSAlPiUgDQogIHtzdW0oZGlhZyguKSkvc3VtKC4pfSAgICAgICAgICAgICMg5q2j56K6546HKEFDQyk6IDg1LjE5JSANCmBgYA0KYGBge3J9DQpjb2xBVUMocHJlZCxDWCRSZXRhaW4pICAgICAgICAgICAgICMg6L6v6K2Y546HKEFVQyk6IDg3LjkyJQ0KYGBgDQoNCiAqKueoi+W8j+eivOiqquaYjioqDQogDQorIHRhYmxlKHByZWQ+MC41LENYJFJldGFpbikgJT4lIHtzdW0oZGlhZyguKSkvc3VtKC4pfQ0KKyDlsIfpoZ7liKXpoJDmuKzlgLzoiIflr6bpmpvnmbznlJ/lgLzovYnmj5vngrrmt7fmt4bnn6npmaPvvIzkuKboqIjnrpcgQUNDICgg5q2j56K6546HICnjgIINCisgY29sQVVDKHByZWQsQ1gkUmV0YWluKQ0KKyDlsIfpoZ7liKXpoJDmuKzlgLzoiIflr6bpmpvnmbznlJ/lgLzovYnmj5vngrogQVVDICgg6L6o6K2Y546HICnjgIINCiANCiAqKuWft+ihjOaEj+a2tSoqDQoNCisg6KiI566XIEFDQyDlj4ogQVVDIOiDveiuk+aIkeWAkeebtOingOWcsOS6huino+atpOaooeWei+eahOmgkOa4rOihqOePvu+8jOS4puiDveWkoOiIh+WFtuS7luaooeWei+S9nOavlOi8g+OAgg0KDQoNCmBgYHtyIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTR9DQpwcmVkaWN0aW9uKHByZWQsIENYJFJldGFpbikgJT4lICAgICMgUk9DIENVUlZFIA0KICBwZXJmb3JtYW5jZSgidHByIiwgImZwciIpICU+JSANCiAgcGxvdChwcmludC5jdXRvZmZzLmF0PXNlcSgwLDEsMC4xKSkNCmBgYA0KDQogKirnqIvlvI/norzoqqrmmI4qKg0KIA0KKyBwcmVkaWN0aW9uKHByZWQsIENYJFJldGFpbikgJT4lIHBlcmZvcm1hbmNlKCJ0cHIiLCAiZnByIikgJT4lIHBsb3QocHJpbnQuY3V0b2Zmcy5hdD1zZXEoMCwxLDAuMSkpDQorIOWwh+mhnuWIpemgkOa4rOWAvOiIh+Wvpumam+eZvOeUn+WAvOWFtiBUUFLjgIFGUFIg57mq6KO95oiQ5ZyW77yMdGhyZXNob2xkIOW+niAwIH4gMSDkuYvplpPmr48gMC4xIOe5quijveS4gOWAi+m7nu+8jOWGjemAo+aIkOWmguS4iuWcluS5iyBST0Mg5puy57ea44CCDQogDQogKirln7fooYzmhI/mtrUqKg0KDQorIOe5quijvSBST0Mg5puy57ea44CC5q2k6IiJ6IO95aSg5bmr5Yqp5qih5Z6L5L2/55So6ICF5LqG6Kej5qih5Z6L55qE6aCQ5ris6KGo54++77yM5Lim6IO95aSg5L2/5qih5Z6L5L2/55So6ICF5L6dIFRQUuOAgUZQUiDmjJHlh7rog73lpKDmjqXlj5fkuYsgdGhyZXNob2xkIOWAvOOAgg0KDQojIyMjIyA0LjQg5bu656uL5pW46YeP5qih5Z6LDQpgYGB7cn0NCmR4ID0gc3Vic2V0KENYLCBSZXZlbnVlID4gMCkgICMg5Y+q5bCN5pyJ5L6G6LO86LK355qE5Lq65YGa5qih5Z6LDQptUmV2ID0gbG0obG9nKFJldmVudWUpIH4gcmVjZW50ICsgZnJlcSArIGxvZygxK21vbmV5KSArIHNlbmlvciArDQogICAgICAgICAgc3RhdHVzICsgZnJlcTAgKyBsb2coMStyZXZlbnVlMCksIGR4KSAgDQpzdW1tYXJ5KG1SZXYpICAgICAgICAgICAgICAgICAjIOWIpOWumuS/guaVuO+8mlIyID0gMC43MTMNCmBgYA0KDQogKirnqIvlvI/norzoqqrmmI4qKg0KIA0KKyBkeCA9IHN1YnNldChDWCwgUmV2ZW51ZSA+IDApDQorIOWwh+WOn+WFiOeahOizh+aWmeahhiBDWCDlj5blrZDpm4bvvIzlj6ropoEgMjAxNSDmnInkvobmtojosrvnmoTpoaflrqLop4Dlr5/lgLzljbPlj6/jgIINCisgbVJldiA9IGxtKGxvZyhSZXZlbnVlKSB+IHJlY2VudCArIGZyZXEgKyBsb2coMSttb25leSkgKyBzZW5pb3IgKyBzdGF0dXMgKyBmcmVxMCArIGxvZygxK3JldmVudWUwKSwgZHgpDQorIOW7uueri+S4gOiIrOe3muaAp+aooeWei++8jOiHquiuiuaVuOeCuiByZWNlbnTjgIFmcmVx44CBbG9nKDErbW9uZXkp44CBc2VuaW9y44CBc3RhdHVz44CBZnJlcTDjgIFsb2coMStyZXZlbnVlMCnvvIzmh4norormlbjngrogbG9nKFJldmVudWUp44CCbW9uZXkg5Y+KIHJldmVudWUwIOWFqeWAi+iuiuaVuOmhjeWkliArIDEg5piv54K65LqG6YG/5YWN6Kmy5YC8IDwgMSDmnIPpgKDmiJDlj5blsI3mlbjlvozmlbjlgLzngrrosqDjgIINCiANCiAqKuWft+ihjOaEj+a2tSoqDQoNCisg5bCNIDIwMTUg5bm05LuN54S25pyJ5L6G5raI6LK755qE6aGn5a6i5bu656uL44CM5pyD6Iqx6LK75aSa5bCR6YeR6aGN44CN55qE5LiA6Iis57ea5oCn5pW46YeP6aCQ5ris5qih5Z6L44CCDQoNCmBgYHtyIGZpZy5oZWlnaHQ9NC41LCBmaWcud2lkdGg9NC41fQ0KcGxvdChsb2coZHgkUmV2ZW51ZSksIHByZWRpY3QobVJldiksIGNvbD0ncGluaycsIGNleD0wLjY1KQ0KYWJsaW5lKDAsMSxjb2w9J3JlZCcpIA0KYGBgDQoNCiAqKueoi+W8j+eivOiqquaYjioqDQogDQorIHBsb3QobG9nKGR4JFJldmVudWUpLCBwcmVkaWN0KG1SZXYpLCBjb2w9J3BpbmsnLCBjZXg9MC42NSkNCisg5bCH6aCQ5ris5YC85bCN5a+m6Zqb55m855Sf5YC857mq6KO95pWj5L2I5ZyW77yM6aGP6Imy6Kit5a6a54K6IHBpbmvvvIzlpKflsI/oqr/mlbTngrogMC42NQ0KKyBhYmxpbmUoMCwxLGNvbD0ncmVkJykNCisg57mq6KO95LiA5qKd57SF6Imy55qEIDQ1IOW6pue3muWBmueCuuWwjeeFp+OAgg0KIA0KICoq5Z+36KGM5oSP5ra1KioNCg0KKyDnuaroo73kuIDlvLXmlaPkvYjlnJbkvobop4Dlr5/mraTmqKHlnovnmoTpoJDmuKzntZDmnpzoiIflr6bpmpvop4DmuKzlgLznmoTlt67ot53jgIINCg0KPGJyPjxocj4NCg0KIyMjIDUuIOS8sOioiOmhp+Wuoue1gueUn+WDueWAvA0KDQojIyMjIyA1LjEgWTIwMTbnmoTpoJDmuKzlgLwNCuS9v+eUqOaooeWei+WwjVkyMDE15bm05bqV55qE6LOH5paZ5YGa6aCQ5ris77yM5bCN6LOH5paZ5Lit55qE5q+P5LiA5L2N6aGn5a6i77yM6aCQ5ris5aW55YCR5ZyoWTIwMTbnmoTkv53nlZnnjoflkozos7zosrfph5HpoY3jgIINCmBgYHtyfQ0KQ1ggPSBZJFkyMDE1DQpuYW1lcyhDWClbODo5XSA9IGMoImZyZXEwIiwicmV2ZW51ZTAiKQ0KDQojIOmgkOa4rFkyMDE25L+d55WZ546HDQpDWCRQcm9iUmV0YWluID0gcHJlZGljdChtUmV0LENYLHR5cGU9J3Jlc3BvbnNlJykNCg0KIyDpoJDmuKxZMjAxNuizvOiyt+mHkemhjQ0KQ1gkUHJlZFJldmVudWUgPSBleHAocHJlZGljdChtUmV2LENYKSkNCmBgYA0KDQogKirnqIvlvI/norzoqqrmmI4qKg0KIA0KKyBDWCA9IFkkWTIwMTUgOyBuYW1lcyhDWClbODo5XSA9IGMoImZyZXEwIiwicmV2ZW51ZTAiKQ0KKyDlsIfos4fmlpnmoYYgQ1gg55qE6LOH5paZ5pu05pS554K6IDIwMTUg5bm055qE6LOH5paZ77yM5Lim5bCH6K6K5pW45qyE5L2NIDjjgIE5IOabtOaUueeCuuaooeWei+WPr+S7peiqjeefpeeahOWQjeeosSBmcmVxMCDlj4ogcmV2ZW51ZTDjgIINCisgQ1gkUHJvYlJldGFpbiA9IHByZWRpY3QobVJldCxDWCx0eXBlPSdyZXNwb25zZScpDQorIOWwh+mhnuWIpemgkOa4rOaooeWeiyAoIDIwMTYg5bm05piv5ZCm5pyD5L6G5raI6LK7ICkg6aCQ5ris55qE57WQ5p6c5a2Y54K6IENYIOS4reeahCBQcm9iUmV0YWlu44CCDQorIENYJFByZWRSZXZlbnVlID0gZXhwKHByZWRpY3QobVJldixDWCkpDQorIOWwh+aVuOmHj+mgkOa4rOaooeWeiyAoIDIwMTYg5bm05pyD5raI6LK75aSa5bCR6YeR6aGNICkg6aCQ5ris55qE57WQ5p6c5a2Y54K6IENYIOS4reeahCBQcmVkUmV2ZW51ZeOAgg0KIA0KICoq5Z+36KGM5oSP5ra1KioNCg0KKyDlsIcgMjAxNSDlubTnmoTpoaflrqLos4fmlpnkuJ/lhaXmiJHlgJHmlrznrKzlm5vpg6jliIbmiYDlu7rnq4vnmoTlhanlgIvpoJDmuKzmqKHlnovvvIzliIbliKXpoJDmuKzpoaflrqLmlrwgMjAxNiDlubTmmK/lkKbmnIPkvobmtojosrvvvIzku6Xlj4rlpoLmnpzmnIPkvobmtojosrvvvIzlhbbmtojosrvph5HpoY3mmK/lpJrlsJHjgIINCg0KYGBge3IgZmlnLmhlaWdodD0yLjUsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93PWMoMSwyKSwgbWFyPWMoNCwzLDMsMiksIGNleD0wLjgpDQpoaXN0KENYJFByb2JSZXRhaW4sbWFpbj0iUHJvYlJldGFpbiIsIHlsYWI9IiIpDQpoaXN0KGxvZyhDWCRQcmVkUmV2ZW51ZSwxMCksbWFpbj0ibG9nKFByZWRSZXZlbnVlKSIsIHlsYWI9IiIpDQpgYGANCg0KICoq56iL5byP56K86Kqq5piOKioNCiANCisgcGFyKG1mcm93PWMoMSwyKSwgbWFyPWMoNCwzLDMsMiksIGNleD0wLjgpDQorIOWfuuekjue5quWcluioreWumu+8jOaOpeS4i+S+hueahOWclueCuuS4gOWIl+WFqeihjOS9teeCuuS4gOW8teWclu+8jOmCiueVjOeCuiA0LDMsMywy77yM5pW06auU5aSn5bCP54K6IDAuOOOAgg0KKyBoaXN0KENYJFByb2JSZXRhaW4sbWFpbj0iUHJvYlJldGFpbiIsIHlsYWI9IiIpDQorIOe5quijveesrOS4gOWAi+aooeWei+eahOmgkOa4rOe1kOaenOafseeLgOWcluOAgg0KKyBoaXN0KGxvZyhDWCRQcmVkUmV2ZW51ZSwxMCksbWFpbj0ibG9nKFByZWRSZXZlbnVlKSIsIHlsYWI9IiIpDQorIOe5quijveesrOS6jOWAi+aooeWei+eahOmgkOa4rOe1kOaenOafseeLgOWcluOAguazqOaEj+mHkemhjeeahOaVuOWtl+acieWPliBsb2cxMOOAgg0KIA0KICoq5Z+36KGM5oSP5ra1KioNCg0KKyDlsIfpoJDmuKzntZDmnpzku6Xmn7Hni4DlnJbooajnpLrvvIzog73lpKDop4Dlr5/lhanlgIvmqKHlnovpoJDmuKzlh7rkvobnmoTntZDmnpzliIbkvYjjgILlpoLnrKzkuIDlgIvmqKHlnovpoJDmuKzku4rlubTnmoTpgJnkupvpoaflrqLmlrzmmI7lubTmnIPkvobmtojosrvnmoTmqZ/njoflpKfpg6jliIbotqjov5HmlrwgMO+8m+iAjOa2iOiyu+mHkemhjeWkp+mDqOWIhuiQveaWvCAxLjUgKCDkuZ/lsLHmmK/ljp/lp4vmlbjlgLwgMzEuNjIgKSDlt6blj7PjgIINCg0KPGJyPg0KDQojIyMjIyA1LjIg5Lyw6KiI6aGn5a6i57WC55Sf5YO55YC8KENMVikNCg0KPGNlbnRlcj7poaflrqIkaSTnmoTntYLnlJ/lg7nlgLw8L2NlbnRlcj4NCg0KJCQgVl9pID0gXHN1bV97dD0wfV5OIGcgXHRpbWVzIG1faSBcZnJhY3tyX2ledH17KDErZCledH0gPSBnIFx0aW1lcyBtX2kgXHN1bV97dD0wfV5OIChcZnJhY3tyX2l9ezErZH0pXnQgICQkDQoNCjxjZW50ZXI+JG1faSTjgIEkcl9pJO+8mumhp+WuoiRpJOeahOmgkOacnyjmr4/mnJ8p54ef5pS26LKi542744CB5L+d55WZ5qmf546HPC9jZW50ZXI+DQoNCjxjZW50ZXI+JGck44CBJGQk77ya5YWs5Y+455qEKOeoheWJjSnnh5/mpa3liKnmvaTliKnnjofjgIHos4fph5HmiJDmnKw8L2NlbnRlcj4NCg0KYGBge3J9DQpnID0gMC41ICAgIyAo56iF5YmNKeeNsuWIqeeOhw0KTiA9IDUgICAgICMg5pyf5pW4ID0gNQ0KZCA9IDAuMSAgICMg5Yip546HID0gMTAlDQpDWCRDTFYgPSBnICogQ1gkUHJlZFJldmVudWUgKiByb3dTdW1zKHNhcHBseSgNCiAgMDpOLCBmdW5jdGlvbihpKSAoQ1gkUHJvYlJldGFpbi8oMStkKSleaSApICkNCg0Kc3VtbWFyeShDWCRDTFYpDQpgYGANCg0KICoq56iL5byP56K86Kqq5piOKioNCiANCisgQ1gkQ0xWID0gZyAqIENYJFByZWRSZXZlbnVlICogcm93U3VtcyhzYXBwbHkoMDpOLCBmdW5jdGlvbihpKSAoQ1gkUHJvYlJldGFpbi8oMStkKSleaSApICkNCisg6KiI566X6aGn5a6i57WC55Sf5YO55YC8IDog5bCH542y5Yip546H5LmY5LiK6aCQ5pyf542y5Yip77yM5YaN5LmY5LiK5pyq5L6G5LqU5bm06aCQ5pyf5L+d55WZ546H55qE54++5YC857i95ZKM44CCDQogDQogKirln7fooYzmhI/mtrUqKg0KDQorIOioiOeul+mhp+Wuoue1gueUn+WDueWAvOiDveWkoOiuk+aIkeWAkeS6huino+avj+S4gOWAi+mhp+WuoueahOa9m+WcqOWDueWAvOacieWkmuWkpyAoIOWcqOmAmeWAi+mhjOebruaIkeWAkeioiOeul+S6huS6lOW5tCAp44CCDQoNCmBgYHtyIGZpZy5oZWlnaHQ9Mi41LCBmaWcud2lkdGg9Ny4yfQ0KcGFyKG1hcj1jKDIsMiwzLDEpLCBjZXg9MC44KQ0KaGlzdChsb2coQ1gkQ0xWLDEwKSwgeGxhYj0iIiwgeWxhYj0iIikNCmBgYA0KDQogKirnqIvlvI/norzoqqrmmI4qKg0KIA0KKyBwYXIobWFyPWMoMiwyLDMsMSksIGNleD0wLjgpDQorIOWfuuekjue5quWcluioreWumu+8jOaOpeS4i+S+hueahOWclumCiueVjOeCuiAyLDIsMywx77yM5pW06auU5aSn5bCP54K6IDAuOOOAgg0KKyBoaXN0KGxvZyhDWCRDTFYsMTApLCB4bGFiPSIiLCB5bGFiPSIiKQ0KKyDnuaroo73poaflrqLntYLnlJ/lg7nlgLznmoTmn7Hni4DlnJbjgILms6jmhI/pgJnpgornmoTjgIzlg7nlgLzjgI3kuZ/mnInlj5YgbG9nMTDjgIINCiANCiAqKuWft+ihjOaEj+a2tSoqDQoNCisg5bCH6aGn5a6i57WC55Sf5YO55YC857mq6KO95oiQ5p+x54uA5ZyW77yM6IO95aSg5pu055u06KeA5Zyw55yL5Yiw6aGn5a6i5pmu6YGN5bi257Wm5YWs5Y+455qE5YO55YC85Zyo5ZOq5Lqb5Y2A5q6144CCDQoNCiMjIyMjIDUuMyDmr5TovIPlkITml4/nvqTnmoTlg7nlgLwNCg0KYGBge3J9DQojIOWQhOaXj+e+pOeahOW5s+Wdh+eHn+aUtuiyoueNu+OAgeS/neeVmeapn+eOh+OAgee1gueUn+WDueWAvA0Kc2FwcGx5KENYWywxMDoxMl0sIHRhcHBseSwgQ1gkc3RhdHVzLCBtZWFuKQ0KYGBgDQoNCiAqKueoi+W8j+eivOiqquaYjioqDQogDQorIHNhcHBseShDWFssMTA6MTJdLCB0YXBwbHksIENYJHN0YXR1cywgbWVhbikNCisg5bCH6K6K5pW4IDEwIH4gMTIgKCDlhanlgIvpoJDmuKzntZDmnpzoiIfpoaflrqLntYLnlJ/lg7nlgLwgKSDmoLnmk5rkuI3lkIznmoTmtojosrvogIXni4DmhYvliIbntYTvvIzoqIjnrpflhbblubPlnYflgLzjgIINCg0KICoq5Z+36KGM5oSP5ra1KioNCg0KKyDpgI/pgY7lvZnmlbTmiJDooajmoLzvvIzog73lpKDnm7TmjqXlnLDnnIvliLDmr4/kuIDlgIvni4DmhYvkuIvnmoTmtojosrvogIXlhbblubPlnYfkv53nlZnmqZ/njofjgIHpoJDoqIjoirHosrvku6Xlj4rntYLnlJ/lg7nlgLzvvIzmnInliqnmlrzkuobop6Pmr4/lgIvmtojosrvogIXni4DmhYvnmoTmgKfos6roiIflsI3lhbbpgLLooYznrZbnlaXmk6zlrprjgIINCg0KYGBge3J9DQpwYXIobWFyPWMoMywzLDQsMiksIGNleD0wLjgpDQpib3hwbG90KGxvZyhDTFYpfnN0YXR1cywgQ1gsIG1haW49IkNMViBieSBHcm91cHMiKQ0KDQpgYGANCg0KICoq56iL5byP56K86Kqq5piOKioNCiANCisgcGFyKG1hcj1jKDMsMyw0LDIpLCBjZXg9MC44KQ0KKyDln7rnpI7nuarlnJboqK3lrprvvIzmjqXkuIvkvobnmoTlnJbpgornlYzngrogMywzLDQsMu+8jOaVtOmrlOWkp+Wwj+eCuiAwLjjjgIINCisgYm94cGxvdChsb2coQ0xWKX5zdGF0dXMsIENYLCBtYWluPSJDTFYgYnkgR3JvdXBzIikNCisg57mq6KO96aGn5a6i57WC55Sf5YO55YC85bCN6aGn5a6i54uA5oWL5YiG576k55qE55uS54uA5ZyW44CCDQogDQogKirln7fooYzmhI/mtrUqKg0KDQorIOW+nuebkueLgOWcluS4reWPr+S7peeci+WIsOS4jeWQjOeahOmhp+WuoueLgOaFi++8jOWFtue1gueUn+WDueWAvOeahOWIhuS9iOeLgOazgeOAgg0KDQoNCjxicj48aHI+DQoNCiMjIyA2LiDoqK3lrprooYzpirfnrZbnlaXjgIHopo/lioPooYzpirflt6XlhbcNCg0KKirooYzpirfnrZbnlaXoqK3lrpoqKg0KDQorIOW+nuS6kuWLleW8j+a1gemHj+WIhuaekOS7peWPiuWIhue+pOimj+WJh+S+hueci++8jOaIkeWAkeWPr+S7peefpemBk+WQhOe+pOmhp+WuoueahOenu+i9ieeoi+W6puS7peWPiua2iOiyu+eJueaAp+eCuuS9le+8jOWGjeagueaTmumAmeS6m+izh+aWmemAsuihjOWIhuaekOWItuWumuWuouijveWMlueahOihjOmKt+etlueVpe+8jOatpOWkluaIkeWAkeW/hemgiOagueaTmumhp+Wuoue1gueUn+WDueWAvOWOu+WIpOaWt+WTquS6m+e+pOeahOmhp+WuouaYr+aIkeWAkeacgOmcgOimgeWBmumhp+WuouS/neeVmeeahOOAgg0KDQorICoqU+aXj+e+pCoq77ya5o6h55So5q+U6LyD5Yi65r+A55qE6KGM6Yq3562W55Wl5Zaa6YaS5q2k576k6aGn5a6i77yM5L2G6KGM6Yq35Li75Yqb5Lim5LiN5Zyo5q2k44CCDQorIFMx77ya556M552h6aGn5a6i77yM556M552h6aGn5a6i5bCN5pa86YCZ5a625bqX55qE6KqN6K2Y5pyJ5LiA5a6a5pmC6ZaT77yM5pyJ5LiA5Y2K55qE5qmf5pyD5oiQ54K65Li75Yqb6aGn5a6i77yM5L2G5Lmf5pyJ5Y+m5LiA5Y2K55qE5qmf5pyD5oiQ54K65Y2K552h6aGn5a6i77yM5LiU5qW15bCR5pW45pyD5LuN5L+d55WZ5pa85q2k54uA5oWL5Lit77yM6ZuW54S2Q0xW5YGP5L2O77yM5L2G6Iul5oiQ5rWB6L2J5oiQ54K65Li75Yqb6aGn5a6i5LuN5pyJ5LiA5a6a5r2b5Yqb5a2Y5Zyo77yM54K65LqG5aKe5Yqg5oiQ54K65Li75Yqb6aGn5a6i55qE5qmf5pyD77yM5oiR5YCR5Yip55SoZS1tYWls6KGM6Yq377yM6Yed5bCN5q2k576k6aGn5a6i5a+E5Ye66ICB6aGn5a6i55qE6ZmQ5pmC54m55oOg5ZWG5ZOB5oiW5piv5oqY5YO55Yi477yM5ZC45byV556M552h6aGn5a6i6YeN5paw5Zue5Yiw5bqX6KOh5raI6LK777yM5YaN5Yqg5Lul5Yip55So5pyD5ZOh5Yi25bqm6K6T6aGn5a6i55WZ5L2P5Zyo5bqX5Lit44CCDQorIFMy77ya5Y2K552h6aGn5a6i77yM5q2k576k6aGn5a6i55qEQ0xW5YC85L2O77yM5LiU5aSa5pW45pyD5rWB6L2J5oiQ54K65rKI552h6aGn5a6i77yM5bCR5pW45pyD6K6K5oiQ556M552h6aGn5a6i77yM55Sx5pa86aGn5a6i5L+d55WZ5YO55YC85L2O77yM5pWF5bCN5pa85q2k576k6aGn5a6i5oiR5YCR5o6h55So5LiN5YiG576k55qE6KGM6Yq3562W55Wl5qih5byP77yM5Yip55So54m55oOg44CB6YCx5bm05oW244CB54m56LOj55qE5pa55byP5ZC45byV6aGn5a6i5LiK6ZaA44CCDQorIFMz77ya5rKI552h6aGn5a6i77yM5q2k6aGe6aGn5a6i5qW16Zuj5YaN6L2J54K65YW25LuW56iu6aGe6aGn5a6i77yM5q2k576k6aGn5a6i5YO55YC85L2O77yM5L+d55WZ5omA6YCg5oiQ55qE5pWI5p6c5Lmf5LiN5piO6aGv77yM5pWF5o6h55So6IiHUzLkuIDmqKPnmoTkuI3ph53lsI3mgKflgZrms5XvvIzmjqHnlKjovIPmtojmpbXnmoTooYzpirfmlrnlvI/jgIINCg0KKyAqKlLml4/nvqQqKu+8muaOoeeUqOaPkOmrmOW/oOiqoOW6pueahOihjOmKt+aWueW8j+S/neeVmeatpOe+pOmhp+Wuou+8jOWFtueCuuaIkeWAkeeahOihjOmKt+S4u+WKm+WwjeixoeOAgg0KKyBSMe+8muS4u+WKm+mhp+Wuou+8muS4u+WKm+mhp+WuoueahENMVueCuuesrOS4iemrmO+8jOWFtuavlOi8g+WuueaYk+a1gei9ieaIkOeejOedoemhp+Wuou+8jOeCuuS6humBv+WFjeiuiuaIkOeejOedoemhp+WuouaIkeWAkeW/hemgiOWinuW8t+atpOe+pOeahOW/oOiqoOW6pu+8jOWDj+aYr+ioreeri+S4gOS6m+acg+WToeWIhue0mueNjuWLteWItuW6pu+8jOi2iumrmOetiee0mueahOmhp+WuouWwseiDveS6q+aciei2iuWkmueahOWwiueIteacg+WToeWEquaDoO+8jOS4puS4lOavj+W5tOi0iOmAgeeUn+aXpeemruetieetieOAguiXieatpOWQuOW8leS4u+WKm+mhp+WuouaMgee6jOWcqOW6l+a2iOiyu++8jOmZjeS9juaIkOeCuueejOedoemhp+WuoueahOapn+acg+OAgg0KKyBSMu+8muaguOW/g+mhp+Wuou+8muaguOW/g+mhp+WuoueahENMVueCuuacgOmrmO+8jOWFtuS5n+S4jeWkquWuueaYk+i9ieaIkOWFtuS7lue+pOmhp+Wuou+8jOWcqOacg+WToeiHs+eVtuS4reatpOe+pOmhp+WuouacgOe1guacg+aIkOeCuuacgOmrmOetiee0muacg+WToe+8jOS7peacgOmrmOetiee0mueahOacg+WToeWEquaDoOOAgeeEoeW+ruS4jeiHs+eahOeJueWIpeacjeWLme+8jOiuk+aguOW/g+mhp+Wuouaciee+juWlveeahOa2iOiyu+mrlOmpl++8jOaMgee6jOS/neeVmeaguOW/g+mhp+WuouOAgg0KDQorICoqTuaXj+e+pCoq77ya5o6h55So5oyB57qM5ZC45byV55qE5pa55byP5bCH5paw6aGn5a6i5Yiw5bqX5raI6LK75oiQ54K657+S5oWj77yM5oiQ54K65paw55qEUuaXj+e+pOmhp+Wuou+8jOeCuuihjOmKt+S4u+WKm+WwjeixoeOAgg0KKyBOMe+8muaWsOmhp+Wuou+8muaWsOmhp+WuouWxrOaWvOmChOWcqOingOWvn+OAgeingOacm+eahOS4gOaXj+e+pO+8jOWFtua2iOiyu+iyoueNu+S4jemrmO+8jENMVualteS9ju+8jOa1gei9ieeCuua9m+WKm+mhp+WuoueahOapn+acg+S5n+S4jemrmO+8jOS9huW/hemgiOaMgee6jOWfuemkiuaWsOmhp+WuouaIkOeCuuW/oOiqoOmhp+Wuou+8jOWinuWKoOW6l+eahOalree4vuaIkOmVt++8jOaVheWNs+S9v+aViOebiueci+S8vOS4jemrmOS5n+W/hemgiOWBmuS4gOS6m+S/neeVmeeahOihjOmKt+etlueVpe+8jOWPr+S7peWIqeeUqOS4gOS6m+WFhea7v+aWsOmuruaEn+eahOihjOmKt+aWueW8j+WDj+aYr+mbhum7nuWlveemruOAgeePvumHkeWbnumli+OAgeaWsOWuouWlveemruemruWMheWIhumajuautei0iOmAgeeahOaWueW8j+WQuOW8leWFtuaMgee6jOWIsOW6l+a2iOiyu+OAgg0KKyBOMu+8muaWsOa9m+WKm+mhp+Wuou+8muatpOe+pOmhp+WuouWwjeW6l+eahOaUtuebiuiyoueNu+ebuOeVtumrmO+8jENMVualtemrmO+8jOacieS4gOWumuapn+acg+aIkOeCulIy6aGn5a6i77yM5LiU5pyJ5b6I5aSn5qmf5pyD6KKr5L+d55WZ5pa85Y6f5L6G54uA5oWL77yM5pWF6KaB5bCN5q2k576k6aGn5a6i6YCy6KGM56mN5qW155qE6aGn5a6i5L+d55WZ6KGM6Yq35pa55byP77yM5Y+v6YCy6KGM5paw5pyD5ZOh5YWl5pyD5aW956au77yM5bCH5paw5r2b5Yqb6aGn5a6i6K6K5oiQ5pyD5ZOh77yM5bCN5pyD5ZOh5a6a5pyf5o6o5Ye65pyJ6Laj44CB5YSq5oOg55qE6KGM6Yq35rS75YuV77yM6K6T5YW25pu057+S5oWj5pa85Zyo6YCZ6KOh5raI6LK777yM5Lmf5Y+v5Lul6YCP6YGO5a+E6YCBZS1tYWls55qE5pa55byP5a+E6YCB5paw6aGn5a6i55qE5bCI5bGs5YSq5oOg44CCDQoNCioq6KGM6Yq35bel5YW36KaP5YqDKioNCg0KKyAqKmUtbWFpbOihjOmKtyoq77ya5YGa5pyJ6Yed5bCN5oCn55qE6KGM6Yq35rS75YuV77yM5qC55pOa5LiN5ZCM55qE5peP576k5a+E6YCB55u46Zec6KiK5oGv77yM5L6L5aaC5bCN5pa8U+aXj+e+pOaOoeeUqOiAgemhp+WuouWbnuWomOWutua0u+WLle+8jE7ml4/nvqTmjqHnlKjmlrDpoaflrqLmraHov47lhKrmg6DmtLvli5XvvIzlsI3poaflrqLnmoTni4DmhYvmipXlhbbmiYDlpb3jgIINCisgKirnsKHoqIrooYzpircqKu+8muaOoeeUqOi3n2UtbWFpbOihjOmKt+ebuOWQjOeahOaJi+azle+8jOmAmuefpemhp+WuouaciemAmeS6m+WEquaDoOioiuaBr+OAgg0KKyAqKuWwiOWxrEFQUCoq77ya5bCN5pa85oCl6ZyA5L+d55WZ55qE6aGn5a6i5YGa56mN5qW155qE6aGn5a6i5L+d55WZ55qE5YuV5L2c77yM6YCP6YGO5pyD5ZOh5YiG57Sa5Yi25bqm77yM5bCHQ0xW6auY55qE5peP576k77yMUjHjgIFSMuOAgU4y576k6aGn5a6i5Z+56aSK5oiQ5b+g6Kqg6aGn5a6i44CCDQorICoq56S+576k6KGM6Yq3KirvvJrlgZrkuI3ph53lsI3mgKflnLDooYzpirfvvIzorpPmm7TlpJrkurrnn6XpgZPlupfoiInovqbnmoTmtLvli5XvvIzmk7TlpKflhbbntrLot6/ogbLph4/vvIzlkLjlvJXlkITml4/nvqTkvobliLDlupfkuK3mtojosrvjgIINCjxicj48aHI+DQoNCiMjIyA3LiDpgbjmk4fooYzpirflsI3osaENCg0K57Wm5a6a5p+Q5LiA6KGM6Yq35bel5YW355qE5oiQ5pys5ZKM6aCQ5pyf5pWI55uK77yM6YG45pOH5Y+v5Lul5pa96KGM6YCZ6aCF5bel5YW355qE5bCN6LGh44CCIA0KDQojIyMjIyA3LjEg5bCNUjLml4/nvqTpgLLooYzkv53nlZkNClIy5peP576k55qE6aCQ5ris5L+d55WZ546H5ZKM6LO86LK36YeR6aGNDQpgYGB7ciBmaWcuaGVpZ2h0PTIuNSwgZmlnLndpZHRoPTh9DQpwYXIobWZyb3c9YygxLDIpLCBtYXI9Yyg0LDMsMywyKSwgY2V4PTAuOCkNCmhpc3QoQ1gkUHJvYlJldGFpbltDWCRzdGF0dXM9PSJSMiJdLG1haW49IlByb2JSZXRhaW4iLHhsYWI9IiIpDQpoaXN0KGxvZyhDWCRQcmVkUmV2ZW51ZVtDWCRzdGF0dXM9PSJSMiJdLDEwKSxtYWluPSJQcmVkUmV2ZW51ZSIseGxhYj0iIikNCmBgYA0KKirnqIvlvI/norzoqqrmmI4qKg0KDQorIOmmluWFiOWFiOeUqHBhcigp77yM5bCN5pa85ZyW6KGo55qE5qC85byP6YCy6KGM6Kq/5pW077yM5pa55L6/6KeA5a+f44CCDQorIOaOpeiRl2hpc3QoKeeVq+WHuumVt+aineWclu+8jOingOWvn1Iy5peP576k55qE6aCQ5ris5L+d55WZ546H5Lul5Y+K6aCQ5ris5raI6LK76YeR6aGN77yM5bCN5pa85raI6LK76YeR6aGN5Y+WbG9n5L2/5YW25ZGI54++5bi45oWL5YiG5L2I77yM6amX6K2J57WQ5p6c5q2j56K65oCn44CCDQorIOWcqFByb2JSZXRhaW7nlbbkuK146Lu454K65qmf546H77yMeei7uOeCuumhp+WuouaVuOmHj++8jOWcqFByZWRSZXZlbnVl5LiteOi7uOeCuua2iOiyu+mHkemhje+8jHnou7jngrrpoaflrqLmlbjph4/jgIINCg0KKirln7fooYzmhI/mtrUqKg0KDQorIOmAj+mBjuimluimuuWMlueahOWLleS9nOWwh+ebruaomeaXj+e+pFIy55qE6aCQ5ris5L+d55WZ546H5Lul5Y+K6aCQ5ris5raI6LK76YeR6aGN5pu05Yqg5a655piT6KeA5a+f44CCDQoNCiMjIyMjIDcuMiDkvLDoqIjpoJDmnJ/loLHphawNCuWBh+ioreihjOmKt+W3peWFt+eahOaIkOacrOWSjOmgkOacn+aViOebiueCug0KYGBge3J9DQpjb3N0ID0gMTAgICAgICAgICMg5oiQ5pysDQplZmZlY3QgPSAwLjc1ICAgICMg5pWI55uK77ya5LiL5LiA5pyf55qE6LO86LK35qmf546HDQpgYGANCg0K5Lyw6KiI6YCZ6aCF6KGM6Yq35bel5YW35bCN5q+P5LiA5L2NUjLpoaflrqLnmoTpoJDmnJ/loLHphawNCmBgYHtyfQ0KVGFyZ2V0ID0gc3Vic2V0KENYLCBzdGF0dXM9PSJSMiIpDQpUYXJnZXQkRXhwUmV0dXJuID0gKGVmZmVjdCAtIFRhcmdldCRQcm9iUmV0YWluKSAqIFRhcmdldCRQcmVkUmV2ZW51ZSAtIGNvc3QNCnN1bW1hcnkoVGFyZ2V0JEV4cFJldHVybikNCmBgYA0K6YCZ5LiA6aCF5bel5YW35bCNUjLpoaflrqLnmoTpoJDmnJ/loLHphazmmK/osqDnmoQNCg0KKirnqIvlvI/norzoqqrmmI4qKg0KDQorIOWFiOioreWumuaIkeWAkeeahOmgkOacn+aViOebiuOAgeWft+ihjOaIkOacrOeCuuWkmuWwkeOAgg0KKyBzdWJzZXTlh7rkuIDlgIvmlrDnmoTlrZDpm4bvvIjpl5zmlrxSMue+pOmhp+WuoueahOa2iOiyu+izh+aWme+8ie+8jOW7uueri+aIkFRhcmdldOOAgg0KKyDlu7rnq4tFeHBSZXR1cm7poJDmnJ/loLHphazvvIzkuZ/lsLHmmK/loLHphazmiaPmjoljb3N05oiQ5pys77yM5o6l6JGXc3VtbWFyeeWHuue1kOaenOOAgg0KDQoqKuWft+ihjOaEj+a2tSoqDQoNCisg5Lyw6KiI5L2/55So5q2k6KGM6Yq35bel5YW35bCN5q+P5LiA5L2NUjLpoaflrqLog73ntablupfoo6HluLbkvobnmoTpoJDmnJ/loLHphazmmK/lkKbmmK/lpb3nmoTvvIzoi6XkuI3lpb3liYflho3pgbjmk4flhbbku5bmm7TpganlkIjnmoTooYzpirflt6XlhbfjgIINCg0KIyMjIyMgNy4zIOmBuOaTh+ihjOmKt+WwjeixoQ0K5L2G5piv77yM5oiR5YCR6YKE5piv5Y+v5Lul5oyR5Ye66Kix5aSa6aCQ5pyf5aCx6YWs5b6I5aSn55qE6KGM6Yq35bCN6LGhDQpgYGB7cn0NClRhcmdldCAlPiUgYXJyYW5nZShkZXNjKEV4cFJldHVybikpICU+JSBzZWxlY3QoY2lkLCBFeHBSZXR1cm4pICU+JSBoZWFkKDE1KQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtKFRhcmdldCRFeHBSZXR1cm4gPiAwKSAgICAgICAgICAgICAgICAgIyDlj6/lr6bmlr3lsI3osaHvvJoyNTgNCmBgYA0K5ZyoUjLkuYvkuK3vvIzmnIkyNTjkurrnmoTpoJDmnJ/loLHphazlpKfmlrzpm7bvvIzlpoLmnpzlsI3pgJkyNTjkurrkvb/nlKjpgJnpoIXlt6XlhbfvvIzmiJHlgJHnmoTmnJ/mnJvloLHphazmmK/vvJoNCmBgYHtyfQ0Kc3VtKFRhcmdldCRFeHBSZXR1cm5bVGFyZ2V0JEV4cFJldHVybiA+IDBdKSAgICMg6aCQ5pyf5aCx6YWs77yaNjQ2NA0KYGBgDQoqKueoi+W8j+eivOiqquaYjioqDQoNCisg5b6eVGFyZ2V05Lit5L6d54Wn6ZmN5Yaq5o6S5YiX55qE5pa55byP6YG45pOH5pyA5YmN6Z2i55qEMTXnrYbos4fmlpnvvIjos4fmlpnkuK3mmK/lkKvmnInpoaflrqLku6Xlj4rpoJDmnJ/loLHphaznmoTvvInjgIINCisg5o6l6JGX5Yqg57i95omA5pyJ6aCQ5pyf5aCx6YWs54K65q2j5YC855qE6aGn5a6i5pW46YeP44CCDQorIOacgOW+jOWKoOe4veaJgOaciemgkOacn+WgsemFrOeCuuato+WAvOeahOmhp+WuouS5i+mgkOacn+WgsemFrO+8jOW+l+WIsOS9v+eUqOatpOmgheW3peWFt+eahOe4veacgOWkp+mgkOacn+WgsemFrOOAgg0KDQoqKuWft+ihjOaEj+a2tSoqDQoNCisg6ZuW54S25oiR5YCR5b6X5Yiw5LqG5bmz5Z2H54K66LKg5YC855qE57WQ5p6c77yM5L2G5oiR5YCR5Y+v5Lul6YCP6YGO4oCc6YG45pOH4oCd55qE5pa55byP5Y675om+5Ye66aCQ5pyf5aCx6YWs54K65q2j5YC855qEUjLpoaflrqLvvIzkuKbkuJTph53lsI3pgJnkupvloLHphazngrrmraPnmoTpoaflrqLkvb/nlKjmraTpoIXooYzpirflt6XlhbfvvIzlvpfliLDmnIDlpb3nmoTpoJDmnJ/loLHphaznuL3lgLzjgIINCg0KPGJyPjxicj48aHI+DQoNCiMjIyMjIFFVSVo6DQoNCuaIkeWAkeWPr+S7peeul+WHuuWwjeaJgOacieeahOaXj+e+pOWvpuaWvemAmemgheW3peWFt+eahOacn+acm+WgsemFrCAuLi4NCmBgYHtyfQ0KVGFyZ2V0ID0gQ1gNClRhcmdldCRFeHBSZXR1cm4gPSAoZWZmZWN0IC0gVGFyZ2V0JFByb2JSZXRhaW4pICogVGFyZ2V0JFByZWRSZXZlbnVlIC0gY29zdA0KZmlsdGVyKFRhcmdldCwgVGFyZ2V0JEV4cFJldHVybiA+IDApICU+JQ0KICBncm91cF9ieShzdGF0dXMpICU+JSBzdW1tYXJpc2UoDQogICAgTm8uVGFyZ2V0ID0gbigpLA0KICAgIEF2Z1JPSSA9IG1lYW4oRXhwUmV0dXJuKSwNCiAgICBUb3RhbFJPSSA9IHN1bShFeHBSZXR1cm4pICkgJT4lIGRhdGEuZnJhbWUNCmBgYA0KKirpgJnlgIvntZDmnpzmmK/lkIjnkIbnmoTll47vvJ8g5L2g5oOz6KaB5oCO6bq85L+u5q2j6YCZ6aCF5YiG5p6Q55qE56iL5bqP5ZGi77yfKioNCg0KKirkuI3lkIjnkIYqKg0KDQorIOWFtuaViOebiu+8iOWKoOaIkOaWueazle+8ieeCuuWumuWAvDAuNzXvvIzkvYblm6Dngrrml4/nvqTkuI3lkIzvvIzosqLnjbvmlYjnm4rkuZ/kuI3lkIzvvIzmlYXnrpflh7rkvobnmoTmlbjlgLzmnIPmnInokL3lt67vvIzmh4nmjqHnlKjmr5TnjofnmoTmlrnlvI/ovIPngrrlrqLop4DjgIINCisg6Iul6KGM6Yq355qE6YKK6Zqb5oiQ5pys5L2O77yI5YOP5piv6Zu75a2Q5qqURE3vvInvvIzliYfmh4nlj6/ku6Xlhajpg6jnmoTpoaflrqLpg73nmbzvvIzlhbbmiJDmnKzmnIPpmqjokZfmlbjph4/lop7liqDogIzpmY3kvY7vvIzmraTntZDmnpzmh4nkuI3nrKblkIjnj77lr6bjgIINCg0KPGJyPjxicj48aHI+DQoNCiMjIyA4LiDntZDoq5YNCg0K5aaC5p6c5L2g5Y+q5pyJ6aGn5a6iSUTjgIHkuqTmmJPml6XmnJ/jgIHkuqTmmJPph5HpoY3kuInlgIvmrITkvY3nmoToqbHvvIzkvaDlj6/ku6XlgZrnmoTliIbmnpDljIXmi6zvvJoNCg0KKyDlhajpq5TpoaflrqLlkozmr4/kuIDlgIvpoaflrqLliIbnvqTnmoTvvJoNCiAgICArIOaXj+e+pOWkp+Wwj+iIh+aIkOmVt+i2qOWLog0KICAgICsg5peP576k5bGs5oCn5YiG5p6Q77ya5aaC5bmz5Z2HQ0xW44CB5bmz5Z2H54ef5pS26LKi542744CB5oiQ6ZW3546H44CB5q+b5Yip546HKOmcgOimgeacieaIkOacrOizh+aWmSnnrYnnrYkNCiAgICArIOe1hOmWk+a1gemHj+WSjOW5s+Wdh+a1geWLleapn+eOhw0KDQorIOavj+S4gOWAi+mhp+WuoueahO+8mg0KICAgICsg5L+d55WZ546H44CB6aCQ5pyf6LO86LK36YeR6aGN44CB57WC6Lqr5YO55YC8DQogICAgKyDnm67liY3miYDlnKjnvqTntYTvvIzku6Xlj4rkuIvkuIDmnJ/mnIPovYnliLDlgIvnvqTntYTnmoTmqZ/njocNCiAgICArIOWmguaenOacieihjOmKt+W3peWFt+eahOS9v+eUqOe0gOmMhOeahOipse+8jOaIkeWAkeS5n+WPr+S7peS8sOioiOavj+S4gOaoo+ihjOmKt+W3peWFt+OAgeWwjeavj+S4gOS9jemhp+WuoueahOaIkOWKn+apn+eOhw0KDQrkuIDoiKzogIzoqIDvvIzpgJnkuIDkupvliIbmnpDnmoTntZDmnpzvvIzotrPlpKDorpPmiJHlgJHliLblrprpoaflrqLnmbzlsZXlkozpoaflrqLkv53nlZnnrZbnlaXvvJvoh7PmlrzpoaflrqLlkLjmlLbnrZbnlaXvvIzmiJHlgJHpgJrluLjpgoTpnIDopoHlvp5DUk3mkojlh7rpoaflrqLlgIvkurrlsazmgKfos4fmlpnmiY3og73lgZrliLDjgIIgDQoNCg0KPGJyPjxicj48aHI+PGJyPjxicj48YnI+DQoNCjxzdHlsZT4NCi5jYXB0aW9uIHsNCiAgY29sb3I6ICM3Nzc7DQogIG1hcmdpbi10b3A6IDEwcHg7DQp9DQpwIGNvZGUgew0KICB3aGl0ZS1zcGFjZTogaW5oZXJpdDsNCn0NCnByZSB7DQogIHdvcmQtYnJlYWs6IG5vcm1hbDsNCiAgd29yZC13cmFwOiBub3JtYWw7DQogIGxpbmUtaGVpZ2h0OiAxOw0KfQ0KcHJlIGNvZGUgew0KICB3aGl0ZS1zcGFjZTogaW5oZXJpdDsNCn0NCnAsbGkgew0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KLnJ7DQogIGxpbmUtaGVpZ2h0OiAxLjI7DQp9DQoNCnRpdGxlew0KICBjb2xvcjogI2NjMDAwMDsNCiAgZm9udC1mYW1pbHk6ICJUcmVidWNoZXQgTVMiLCAi5b6u6Luf5q2j6buR6auUIiwgIk1pY3Jvc29mdCBKaGVuZ0hlaSI7DQp9DQoNCmJvZHl7DQogIGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgIuW+rui7n+ato+m7kemrlCIsICJNaWNyb3NvZnQgSmhlbmdIZWkiOw0KfQ0KDQpoMSxoMixoMyxoNCxoNXsNCiAgY29sb3I6ICMwMDg4MDA7DQogIGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgIuW+rui7n+ato+m7kemrlCIsICJNaWNyb3NvZnQgSmhlbmdIZWkiOw0KfQ0KDQpoM3sNCiAgY29sb3I6ICMwMDg4MDA7DQogIGJhY2tncm91bmQ6ICNlNmZmZTY7DQogIGxpbmUtaGVpZ2h0OiAyOw0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KaDV7DQogIGNvbG9yOiAjMDA2MDAwOw0KICBiYWNrZ3JvdW5kOiAjZjhmOGY4Ow0KICBsaW5lLWhlaWdodDogMS41Ow0KICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KZW17DQogIGNvbG9yOiAjMDAwMGMwOw0KICBiYWNrZ3JvdW5kOiAjZjBmMGYwOw0KICB9DQo8L3N0eWxlPg0KDQo=