前言:從交易記錄到顧客價值

善用商業數據分析的工具和技巧,光靠一份最簡單的交易紀錄(只有顧客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年前五筆資料

執行意涵

  • 觀察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數量印出來。

執行意涵

  • 觀察6年來的顧客總數量
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都倒過來。

執行意涵

  • 視覺化每一年份不同status的數量
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。

執行意涵

  • 視覺化觀察每一年不同status的變化。
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中

執行意涵

  • 將他變成流量矩陣,以利觀察status的變化。
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的資料,為了要建立模型,我們需要先把時間回推一期,也就是說:

假如Y2016的情況(跟Y2015比)沒有太大的變化的話,接下來我們就可以

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 比例計算出來。

執行意涵

  • 初步了解 2015 年還剩下多少比例的顧客。
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”)
  • 繪製顧客終生價值對顧客狀態分群的盒狀圖。

執行意涵

  • 從盒狀圖中可以看到不同的顧客狀態,其終生價值的分佈狀況。


6. 設定行銷策略、規劃行銷工具

行銷策略設定

行銷工具規劃

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),則應可以全部的顧客都發,其成本會隨著數量增加而降低,此結果應不符合現實。



8. 結論

如果你只有顧客ID、交易日期、交易金額三個欄位的話,你可以做的分析包括:

一般而言,這一些分析的結果,足夠讓我們制定顧客發展和顧客保留策略;至於顧客吸收策略,我們通常還需要從CRM撈出顧客個人屬性資料才能做到。







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=