3.1 顧客分群規則
STS = c("N1","N2","R1","R2","S1","S2","S3")
Status = function(rx,fx,mx,sx,K) {factor(
ifelse(sx < 2*K,
ifelse(fx*mx > 50, "N2", "N1"),
ifelse(rx < 2*K,
ifelse(sx/fx < 0.75*K,"R2","R1"),
ifelse(rx < 3*K,"S1",
ifelse(rx < 4*K,"S2","S3")))), STS)}
#自己根據商業狀況制定分群規則
#K: 平均購買週期
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 %>% # 從交易資料做起 Y+y Y2010,Y2011...
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 }
head(Y$Y2015)
3.4 每年年底的累計顧客人數
sapply(Y, nrow)
Y2010 Y2011 Y2012 Y2013 Y2014 Y2015
10407 11674 13562 15468 16905 18417
3.5 族群大小變化趨勢
cols = c("gold","orange","blue","green","pink","magenta","darkred")
sapply(Y, function(df) table(df$status)) %>% barplot(col=cols)
legend("topleft",rev(STS),fill=rev(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)
plot( gvisMotionChart(
CustSegments, "status", "year",
options=list(width=900, height=600) ) )
3.7 族群屬性動態分析
df = merge(Y$Y2014[,c(1,6)], Y$Y2015[,c(1,6)],
by="cid", all.x=T)
tx = table(df$status.x, df$status.y) %>%
as.data.frame.matrix() %>% as.matrix()
tx # 流量矩陣
N1 N2 R1 R2 S1 S2 S3
N1 1705 381 144 45 831 0 0
N2 0 1131 267 430 263 0 0
R1 0 0 1240 43 819 0 0
R2 0 0 199 1742 75 0 0
S1 0 0 115 3 819 1026 0
S2 0 0 78 1 0 692 1339
S3 0 0 97 0 0 0 3420
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
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年的資料做應變數
CX = left_join(Y$Y2014, Y$Y2015[,c(1,8,9)], by="cid")
#left join 保留2014的,即使在2015找不到也要留下資料,2015的資料則填Null或NA
head(CX)
names(CX)[8:11] = c("freq0","revenue0","Retain", "Revenue")
CX$Retain = CX$Retain > 0 #2015會不會來買
head(CX)
table(CX$Retain) %>% prop.table() # 平均保留機率 = 22.54%
FALSE TRUE
0.7701 0.2299
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
4.3 估計類別模型的準確性
pred = predict(mRet,type="response")
table(pred>0.5,CX$Retain)
FALSE TRUE
FALSE 12045 1530
TRUE 974 2356
# 混淆矩陣 (Confusion Matrix)
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
prediction(pred, CX$Retain) %>% # ROC CURVE
performance("tpr", "fpr") %>%
plot(print.cutoffs.at=seq(0,1,0.1))

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
plot(log(dx$Revenue), predict(mRev), col='pink', cex=0.65)
abline(0,1,col='red')

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))
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="")

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
par(mar=c(2,2,3,1), cex=0.8)
hist(log(CX$CLV,10), xlab="", ylab="")

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
par(mar=c(3,3,4,2), cex=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="")

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顧客的預期報酬是負的
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
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
這個結果是合理的嗎? 你想要怎麼修正這項分析的程序呢?
8. 結論
如果你只有顧客ID、交易日期、交易金額三個欄位的話,你可以做的分析包括:
- 全體顧客和每一個顧客分群的:
- 族群大小與成長趨勢
- 族群屬性分析:如平均CLV、平均營收貢獻、成長率、毛利率(需要有成本資料)等等
- 組間流量和平均流動機率
- 每一個顧客的:
- 保留率、預期購買金額、終身價值
- 目前所在群組,以及下一期會轉到個群組的機率
- 如果有行銷工具的使用紀錄的話,我們也可以估計每一樣行銷工具、對每一位顧客的成功機率
一般而言,這一些分析的結果,足夠讓我們制定顧客發展和顧客保留策略;至於顧客吸收策略,我們通常還需要從CRM撈出顧客個人屬性資料才能做到。
LS0tDQp0aXRsZTogIkNWTe+8mumhp+WuouWDueWAvOeuoeeQhiAiDQphdXRob3I6ICJHcm91cDQgMjAxOC8wOC8xNSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KPHVsIGNsYXNzPSJuYXYiPg0KICA8bGk+PGEgaHJlZj0iI2ludHJvIj7liY3oqIA8L2E+PC9saT4NCiAgPGxpPjxhIGhyZWY9IiNhcnJhbmdlIj7os4fmlpnmlbTnkIY8L2E+PC9saT4NCiAgPGxpPjxhIGhyZWY9IiNoaWVyYXJjYWwiPuWxpOe0muW8j+mbhue+pOWIhuaekDwvYT48L2xpPg0KICA8bGk+PGEgaHJlZj0iI2NsdXN0ZXIiPuimj+WJh+WIhue+pDwvYT48L2xpPg0KICA8bGk+PGEgaHJlZj0iI21vZGVsIj7lu7rnq4vmqKHlnos8L2E+PC9saT4NCiAgPGxpPjxhIGhyZWY9IiNjdm0iPuS8sOioiOe1gueUn+WDueWAvDwvYT48L2xpPg0KICA8bGk+PGEgaHJlZj0iI3N0cmF0ZWd5Ij7oqK3lrprooYzpirfnrZbnlaXjgIHopo/lioPooYzpirflt6Xlhbc8L2E+PC9saT4NCiAgPGxpPjxhIGhyZWY9IiNtYXJrZXRpbmciPumBuOaTh+ihjOmKt+WwjeixoTwvYT48L2xpPg0KICA8bGk+PGEgaHJlZj0iI2NvbmNsdXNpb24iPue1kOirljwvYT48L2xpPg0KPC91bD4NCg0KDQo8ZGl2IGNsYXNzPSJjb21tZW50Ij4NCiAgR3JvdXA0Ojxicj4NCiAgQjAzNDAyMDAxMiDorJ3pm6jpnZw8YnI+DQogIEIwMzQwMjAwMjcg6Zmz6Z+75Y2JPGJyPg0KICBCMDQ0MDEyMDE1IOeOi+itr+iLkzxicj4NCiAgTTA2NDExMTAyNSDpu4PlqIHosao8YnI+DQogIE0wNjQxMTEwMzkg546LICDmrKM8YnI+DQogIOihjOWCs+aJgCAgICAg5a2f56Wl55GEPGJyPg0KPC9kaXY+DQoNCjxicj4NCg0KPGRpdiBpZD0iaW50cm8+DQojIyMg5YmN6KiA77ya5b6e5Lqk5piT6KiY6YyE5Yiw6aGn5a6i5YO55YC8DQo8L2Rpdj4NCg0K5ZaE55So5ZWG5qWt5pW45pOa5YiG5p6Q55qE5bel5YW35ZKM5oqA5ben77yM5YWJ6Z2g5LiA5Lu95pyA57Ch5Zau55qE5Lqk5piT57SA6YyEKOWPquaciemhp+WuoklE44CB5Lqk5piT5pel5pyf5ZKM5Lqk5piT6YeR6aGN5LiJ5YCL5qyE5L2NKe+8jOaIkeWAkeWwseWPr+S7peWBmuS4gOezu+WIl+W+iOa3seWFpeOAgeW+iOacieWDueWAvOeahOmhp+WuouWDueWAvOWIhuaekOWSjOihjOmKt+etlueVpeimj+WKg++8jOWMheaLrO+8mg0KDQorICoq5Lqk5piT6KiY6YyE5YiG5p6QKirvvJoNCiAgICArIOaVmOi/sOe1seioiA0KICAgICsg6Lao5Yui44CB5Lqk5Y+J5YiG5p6QDQogICAgKyDos4fmlpnoppboprrljJYNCg0KKyAqKumhp+Wuoue+pOe1hOiIh+aomeexpCoq77yaDQogICAgKyDpm4bnvqTliIbmnpANCiAgICArIOe+pOe1hOWxrOaAp+WIhuaekA0KICAgICsg57WE6ZaT5rWB5YuV5qmf546HDQogICAgKyDpoaflrqIo5YCL5Lq6Kea1geWLleapn+eOhw0KDQoNCjxjZW50ZXI+DQoNCiFb5ZyW5LiA44CB6aGn5a6i5YO55YC8566h55CG55qE5bGk5qyhXShmaWcvZmlnMS5wbmcpDQoNCjwvY2VudGVyPg0KDQo8YnI+5b6e6YCZ5LiA5Lqb5YiG5p6Q5oiR5YCR5Y+v5Lul55yL5Yiw5YWs5Y+45Li76KaB55qE54ef5pS25ZKM542y5Yip55qE6YeN6KaB5L6G5rqQ77yM5oiR5YCR5Lmf5Y+v5Lul55yL5Yiw6YCZ5LiA5Lqb55Si55Sf542y5Yip55qE576k57WE5piv5LiN5piv5pyJ5oiQ6ZW35oiW6ICF6KGw6YCA55qE6Lao5Yui77yb5pOa5q2k5oiR5YCR5Y+v5Lul6Kit5a6a6KGM6Yq355qE6YeN6bue77yM5rG65a6a6KGM6Yq355qE562W55Wl77yM5ZKM6KaP5YqD6KGM6Yq355qE5bel5YW344CC6Zmk5LqG5LiK6L+w55qE5pWY6L+w57Wx6KiI44CB6ZuG576k5YiG5p6Q44CB5ZKM6LOH5paZ6KaW6Ka65YyW5LmL5aSW77yM5oiR5YCR6YKE5Y+v5Lul5Yip55So6YCZ5Lqb57Ch5Zau55qE5Lqk5piT57SA6YyE77yaDQoNCisgKirlu7rnq4vpoJDmuKzmgKfmqKHlnosqKu+8jOmgkOa4rOavj+S4gOS9jemhp+WuoueahO+8mg0KICAgICsg5L+d55WZ5qmf546HDQogICAgKyDpoJDmnJ/nh5/mlLYNCiAgICArIOe1hOmWk+iuiuaPm+apn+eOhw0KICAgICsg5LiL5qyh5Y+v6IO96LO86LK35pmC6ZaTDQoNCjxicj7liKnnlKjpgJnkuIDkupvpoJDmuKzmiJHlgJHlsLHlj6/ku6XpgLLooYzlhajpnaLlrqLoo73ljJbnmoTvvJogDQoNCisgKirpoaflrqLlg7nlgLznrqHnkIYqKu+8mg0KDQogICAgKyDpoaflrqLntYLnlJ/lg7nlgLwNCiAgICArIOmhp+WuouWQuOaUtuetlueVpQ0KICAgICsg6aGn5a6i55m85bGV562W55WlDQogICAgKyDpoaflrqLkv53nlZnnrZbnlaUNCg0KKyAqKumHneWwjeaAp+ihjOmKtyoq77yaDQogICAgKyDoqK3oqIjooYzpirfmlrnmoYgNCiAgICArIOmBuOaTh+ihjOmKt+aWueahiA0KICAgICsg6YG45pOH6KGM6Yq35bCN6LGhDQoNCg0KPGNlbnRlcj4NCg0KIVvlnJbkuozjgIHpoaflrqLlg7nlgLznrqHnkIbmtYHnqItdKGZpZy9maWcyLnBuZykNCg0KPC9jZW50ZXI+DQoNCg0KDQo8YnI+PGhyPg0KDQojIyMjIyBTZXR1cCANCmBgYHtyfQ0KU3lzLnNldGxvY2FsZSgiTENfQUxMIiwiQyIpDQpwYWNrYWdlcyA9IGMoDQogICJkcGx5ciIsImdncGxvdDIiLCJnb29nbGVWaXMiLCJkZXZ0b29scyIsIm1hZ3JpdHRyIiwiY2FUb29scyIsIlJPQ1IiLCJjYVRvb2xzIikNCmV4aXN0aW5nID0gYXMuY2hhcmFjdGVyKGluc3RhbGxlZC5wYWNrYWdlcygpWywxXSkNCmZvcihwa2cgaW4gcGFja2FnZXNbIShwYWNrYWdlcyAlaW4lIGV4aXN0aW5nKV0pIGluc3RhbGwucGFja2FnZXMocGtnKQ0KDQppZighaXMuZWxlbWVudCgiY2hvcmRkaWFnIiwgZXhpc3RpbmcpKQ0KICBkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoIm1hdHRmbG9yL2Nob3JkZGlhZyIpDQpgYGANCg0KIyMjIyMgTGlicmFyeQ0KYGBge3IgZWNobz1ULCBtZXNzYWdlPUYsIGNhY2hlPUYsIHdhcm5pbmc9Rn0NCnJtKGxpc3Q9bHMoYWxsPVQpKQ0Kb3B0aW9ucyhkaWdpdHM9NCwgc2NpcGVuPTEyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoY2FUb29scykNCmxpYnJhcnkoUk9DUikNCmxpYnJhcnkoZ29vZ2xlVmlzKQ0KbGlicmFyeShjaG9yZGRpYWcpDQpgYGANCjxicj48aHI+DQoNCjxkaXYgaWQ9ImFycmFuZ2UiPg0KIyMjIDEgMS4g6LOH5paZ5pW055CGDQo8ZGl2Pg0KDQojIyMjIyAxLjEg5Lqk5piT6LOH5paZIChYKQ0KYGBge3J9DQpYID0gcmVhZC50YWJsZSgNCiAgJ3B1cmNoYXNlcy50eHQnLCBoZWFkZXI9RkFMU0UsIHNlcD0nXHQnLCBzdHJpbmdzQXNGYWN0b3JzPUYpDQpuYW1lcyhYKSA9IGMoJ2NpZCcsJ2Ftb3VudCcsJ2RhdGUnKQ0KWCRkYXRlID0gYXMuRGF0ZShYJGRhdGUpDQpzdW1tYXJ5KFgpICAgICAgICAgICAgICAgICAgIyDkuqTmmJPmrKHmlbggNTEyNDMNCmBgYA0KDQpgYGB7ciBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD03LjJ9DQpwYXIoY2V4PTAuOCkNCmhpc3QoWCRkYXRlLCAieWVhcnMiLCBsYXM9MiwgZnJlcT1ULCB4bGFiPSIiLCBtYWluPSJOby4gVHJhbnNhY3Rpb24gYnkgWWVhciIpDQpgYGANCg0KDQpgYGB7cn0NCm5fZGlzdGluY3QoWCRjaWQpICAgICAgICAgICAjIOmhp+WuouaVuCAxODQxNw0KI251bWJlciBvZiBkaXN0aWN0IChkeXBscikNCmBgYA0KDQojIyMjIyAxLjIg6aGn5a6i6LOH5paZIChBKQ0KPHAgY2xhc3M9ImNvbW1lbnQiPg0K5bCH5LiA5YCLcm935piv5LiA562G5Lqk5piT55qE6LOH5paZIOaVtOeQhuaIkOS4gOWAi3Jvd+aYr+S4gOWAi+mhp+WuoueahOW9meaVtOizh+aWmQ0KPC9wPg0KDQpgYGB7cn0NCkEgPSBYICU+JSANCiAgbXV0YXRlKGRheXMgPSBhcy5pbnRlZ2VyKGFzLkRhdGUoIjIwMTYtMDEtMDEiKSAtIGRhdGUpKSAlPiUgICNtdXRhdGUg5paw5aKe5qyE5L2NDQogIGdyb3VwX2J5KGNpZCkgJT4lIHN1bW1hcmlzZSgNCiAgICByZWNlbnQgPSBtaW4oZGF5cyksICAgICAjIOacgOi/keizvOiyt+i3neS7iuWkqeaVuA0KICAgIGZyZXEgPSBuKCksICAgICAgICAgICAgICMg6LO86LK35qyh5pW4IG4oKSA6c3VtbWFyaXNl55qE5YWn5bu65Ye95byPDQogICAgbW9uZXkgPSBtZWFuKGFtb3VudCksICAgIyDlubPlnYfos7zosrfph5HpoY0NCiAgICBzZW5pb3IgPSBtYXgoZGF5cyksICAgICAjIOesrOS4gOasoeizvOiyt+i3neS7iuWkqeaVuA0KICAgIHNpbmNlID0gbWluKGRhdGUpICAgICAgICMg56ys5LiA5qyh6LO86LK35pel5pyfDQogICkgJT4lIGRhdGEuZnJhbWUNCmBgYA0KDQojIyMjIyAxLjQg6aGn5a6i6LOH5paZ5pGY6KaBDQpgYGB7cn0NCnN1bW1hcnkoQSkNCmBgYA0KDQojIyMjIyAxLjUg6K6K5pW455qE5YiG5biD54uA5rOBDQpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04fQ0KcDAgPSBwYXIoY2V4PTAuOCwgbWZyb3c9YygyLDIpLG1hcj1jKDIsMiwyLDIpKQ0KaGlzdChBJHJlY2VudCwyMCxtYWluPSJyZWNlbmN5Iix5bGFiPSIiLHhsYWI9IiIpDQpoaXN0KHBtaW4oQSRmcmVxLCAxMCksMDoxMCxtYWluPSJmcmVxdWVuY3kiLHlsYWI9IiIseGxhYj0iIikNCmhpc3QoQSRzZW5pb3IsMjAsbWFpbj0ic2VuaW9yaXR5Iix5bGFiPSIiLHhsYWI9IiIpDQpoaXN0KGxvZyhBJG1vbmV5LDEwKSxtYWluPSJsb2cobW9uZXkpIix5bGFiPSIiLHhsYWI9IiIpDQpgYGANCjxicj48aHI+DQoNCg0KPGRpdiBpZD0iaGllcmFyY2FsIj4NCiMjIyAyLiDlsaTntJrlvI/pm4bnvqTliIbmnpANCjxkaXY+DQoNCg0KIyMjIyMgMi4xIFJGTemhp+WuouWIhue+pA0KYGBge3J9DQpzZXQuc2VlZCgxMTEpDQpBJGdycCA9IGttZWFucyhzY2FsZShBWywyOjRdKSwxMCkkY2x1c3Rlcg0KdGFibGUoQSRncnApICAjIOaXj+e+pOWkp+Wwjw0KYGBgDQoNCiMjIyMjIDIuMiDpoaflrqLnvqTntYTlsazmgKcNCmBgYHtyIGZpZy5oZWlnaHQ9NC41LCBmaWcud2lkdGg9OH0NCmdyb3VwX2J5KEEsIGdycCkgJT4lIHN1bW1hcmlzZSgNCiAgcmVjZW50PW1lYW4ocmVjZW50KSwgDQogIGZyZXE9bWVhbihmcmVxKSwgDQogIG1vbmV5PW1lYW4obW9uZXkpLCANCiAgc2l6ZT1uKCkgKSAlPiUgDQogIG11dGF0ZSggcmV2ZW51ZSA9IHNpemUqbW9uZXkvMTAwMCApICAlPiUgDQogIGZpbHRlcihzaXplID4gMSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHg9ZnJlcSwgeT1tb25leSkpICsNCiAgZ2VvbV9wb2ludChhZXMoc2l6ZT1yZXZlbnVlLCBjb2w9cmVjZW50KSxhbHBoYT0wLjUpICsNCiAgc2NhbGVfc2l6ZShyYW5nZT1jKDQsMzApKSArDQogIHNjYWxlX2NvbG9yX2dyYWRpZW50KGxvdz0iZ3JlZW4iLGhpZ2g9InJlZCIpICsNCiAgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMChsaW1pdHM9YygzMCwzMDAwKSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNpemUgKSxzaXplPTMpICsNCiAgdGhlbWVfYncoKSArIGd1aWRlcyhzaXplPUYpICsNCiAgbGFicyh0aXRsZT0iQ3VzdG9tZXIgU2VnZW1lbnRzIiwNCiAgICAgICBzdWJ0aXRsZT0iKGJ1YmJsZV9zaXplOnJldmVudWVfY29udHJpYnV0aW9uOyB0ZXh0Omdyb3VwX3NpemUpIiwNCiAgICAgICBjb2xvcj0iUmVjZW5jeSIpICsNCiAgeGxhYigiRnJlcXVlbmN5IChsb2cpIikgKyB5bGFiKCJBdmVyYWdlIFRyYW5zYWN0aW9uIEFtb3VudCAobG9nKSIpDQpgYGANCg0KPGRpdiBjbGFzcz0iY29tbWVudCI+DQrlnKjkvb/nlKhrLW1lYW5z5YiGMTDnvqTnmoTni4Dms4HkuIvvvIzlvp7kuIvlnJbmiJHlgJHpgbjlh7rnibnoibLmnIDnqoHlh7rnmoTlm5vnvqTpoaflrqLvvIzlpoLnrq3poK3mjIflkJHvvIzop4Dlr5/lhbbnibnmgKfvvJoNCg0KKyAxLuepjealteW4uOWuoijlj7PkuIvop5Ip77ya6auY6aC75L2G5bmz5Z2H6Iqx6LK75L2ODQorIDIu5LiA6Iis5bi45a6iKOS4reS4i+aWuSk6IOaZrumBjemhp+WuoueahOS7o+ihqOaXj+e+pO+8jOmgu+eOh+esrDLvvIzoirHosrvkuZ/kuI3pq5gNCisgMy7pkb3nn7PpoaflrqIo5pyA5LiK5pa5Ke+8muS4jeWkquW4uOS+hu+8jOS9huW5s+Wdh+iKseiyu+mdnuW4uOmrmO+8jOS4lOaXj+e+pOS6uuaVuOWwkQ0KKyA0LuaWsOmAsumhp+Wuoijlt6bkuIvmlrkp77ya6aC7546H5L2O77yM5LiU6Iqx6LK75LiN6auYDQoNCjwvZGl2Pg0KDQohW+WcluS4ieOAgemhp+WuouWIhue+pOimj+WJh10oZmlnL2NsdXN0ZXIyLnBuZykNCg0KDQoNCjxicj48aHI+DQoNCg0KPGRpdiBpZD0iY2x1c3RlciI+DQojIyMgMy4g6KaP5YmH5YiG576kDQo8ZGl2Pg0KDQoNCg0KIyMjIyMgMy4xIOmhp+WuouWIhue+pOimj+WJhw0KYGBge3J9DQpTVFMgPSBjKCJOMSIsIk4yIiwiUjEiLCJSMiIsIlMxIiwiUzIiLCJTMyIpDQpTdGF0dXMgPSBmdW5jdGlvbihyeCxmeCxteCxzeCxLKSB7ZmFjdG9yKA0KICBpZmVsc2Uoc3ggPCAyKkssDQogICAgICAgICBpZmVsc2UoZngqbXggPiA1MCwgIk4yIiwgIk4xIiksDQogICAgICAgICBpZmVsc2UocnggPCAyKkssDQogICAgICAgICAgICAgICAgaWZlbHNlKHN4L2Z4IDwgMC43NSpLLCJSMiIsIlIxIiksDQogICAgICAgICAgICAgICAgaWZlbHNlKHJ4IDwgMypLLCJTMSIsDQogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShyeCA8IDQqSywiUzIiLCJTMyIpKSkpLCBTVFMpfQ0KI+iHquW3seagueaTmuWVhualreeLgOazgeWItuWumuWIhue+pOimj+WJhw0KI0s6IOW5s+Wdh+izvOiyt+mAseacnw0KYGBgDQoNCjxjZW50ZXI+DQoNCiFb5ZyW5LiJ44CB6aGn5a6i5YiG576k6KaP5YmHXShmaWcvZmlnMy5qZmlmKQ0KDQo8L2NlbnRlcj4NCg0KIyMjIyMgMy4yIOW5s+Wdh+izvOiyt+mAseacnw0KDQpgYGB7cn0NCksgPSBhcy5pbnRlZ2VyKHN1bShBJHNlbmlvcltBJGZyZXE+MV0pIC8gc3VtKEEkZnJlcVtBJGZyZXE+MV0pKTsgSw0KI+ioiOeul+izvOiyt+asoeaVuOWkp+aWvOS4gOeahA0KYGBgDQrlm57os7zpoaflrqLnmoTlubPlnYfos7zosrfpgLHmnJ8gYEsgPSA1MjEgZGF5c2ANCg0KIyMjIyMgMy4zIOa7keWLleizh+aWmeeql+agvA0KYGBge3J9DQpZID0gbGlzdCgpICAgICAgICAgICAgICAjIOW7uueri+S4gOWAi+epuueahExJU1QNCmZvcih5IGluIDIwMTA6MjAxNSkgeyAgICMg5q+P5bm05bm05bqV5bCH6aGn5a6i6LOH5paZ5b2Z5pW05oiQ5LiA5YCL6LOH5paZ5qGGDQogIEQgPSBhcy5EYXRlKHBhc3RlMChjKHksIHktMSksIi0xMi0zMSIpKSAjIOeVtuacn+OAgeWJjeacn+eahOacn+acq+aXpeacnyANCiAgWVtbcGFzdGUwKCJZIix5KV1dID0gWCAlPiUgICAgICAgICMg5b6e5Lqk5piT6LOH5paZ5YGa6LW3IFkreSBZMjAxMCxZMjAxMS4uLg0KICAgIGZpbHRlcihkYXRlIDw9IERbMV0pICU+JSAgICAgICAgIyDlsIfos4fmlpnliIfpvYrliLDmnJ/mnKvml6XmnJ8NCiAgICBtdXRhdGUoZGF5cyA9IDEgKyBhcy5pbnRlZ2VyKERbMV0gLSBkYXRlKSkgJT4lICAgIyDkuqTmmJPot53mnJ/mnKvlpKnmlbgNCiAgICBncm91cF9ieShjaWQpICU+JSBzdW1tYXJpc2UoICAgICMg5L6d6aGn5a6i5b2Z57i9IC4uLg0KICAgICAgcmVjZW50ID0gbWluKGRheXMpLCAgICAgICAgICAgIyAgIOacgOW+jOS4gOasoeizvOiyt+i3neacn+acq+WkqeaVuCAgIA0KICAgICAgZnJlcSA9IG4oKSwgICAgICAgICAgICAgICAgICAgIyAgIOizvOiyt+asoeaVuCAo6Iez5pyf5pyr54K65q2iKSAgIA0KICAgICAgbW9uZXkgPSBtZWFuKGFtb3VudCksICAgICAgICAgIyAgIOW5s+Wdh+izvOiyt+mHkemhjSAo6Iez5pyf5pyr54K65q2iKQ0KICAgICAgc2VuaW9yID0gbWF4KGRheXMpLCAgICAgICAgICAgIyAgIOesrOS4gOasoeizvOiyt+i3neacn+acq+WkqeaVuA0KICAgICAgc3RhdHVzID0gU3RhdHVzKHJlY2VudCxmcmVxLG1vbmV5LHNlbmlvcixLKSwgICMg5pyf5pyr54uA5oWLDQogICAgICBzaW5jZSA9IG1pbihkYXRlKSwgICAgICAgICAgICAgICAgICAgICAgIyDnrKzkuIDmrKHos7zosrfml6XmnJ8NCiAgICAgIHlfZnJlcSA9IHN1bShkYXRlID4gRFsyXSksICAgICAgICAgICAgICAjIOeVtuacn+izvOiyt+asoeaVuA0KICAgICAgeV9yZXZlbnVlID0gc3VtKGFtb3VudFtkYXRlID4gRFsyXV0pICAgICMg55W25pyf6LO86LK36YeR6aGNDQogICAgKSAlPiUgZGF0YS5mcmFtZSB9DQpgYGANCg0KYGBge3J9DQpoZWFkKFkkWTIwMTUpDQpgYGANCg0KIyMjIyMgMy40IOavj+W5tOW5tOW6leeahOe0r+ioiOmhp+WuouS6uuaVuA0KYGBge3J9DQpzYXBwbHkoWSwgbnJvdykNCmBgYA0KDQojIyMjIyAzLjUg5peP576k5aSn5bCP6K6K5YyW6Lao5YuiDQpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04fQ0KY29scyA9IGMoImdvbGQiLCJvcmFuZ2UiLCJibHVlIiwiZ3JlZW4iLCJwaW5rIiwibWFnZW50YSIsImRhcmtyZWQiKQ0Kc2FwcGx5KFksIGZ1bmN0aW9uKGRmKSB0YWJsZShkZiRzdGF0dXMpKSAlPiUgYmFycGxvdChjb2w9Y29scykNCmxlZ2VuZCgidG9wbGVmdCIscmV2KFNUUyksZmlsbD1yZXYoY29scykpDQpgYGANCg0KIyMjIyMgMy42IOaXj+e+pOWxrOaAp+WLleaFi+WIhuaekA0KYGBge3J9DQpDdXN0U2VnbWVudHMgPSBkby5jYWxsKHJiaW5kLCBsYXBwbHkoWSwgZnVuY3Rpb24oZCkgew0KICBncm91cF9ieShkLCBzdGF0dXMpICU+JSBzdW1tYXJpc2UoDQogICAgYXZlcmFnZV9mcmVxdWVuY3kgPSBtZWFuKGZyZXEpLA0KICAgIGF2ZXJhZ2VfYW1vdW50ID0gbWVhbihtb25leSksDQogICAgdG90YWxfcmV2ZW51ZSA9IHN1bSh5X3JldmVudWUpLA0KICAgIHRvdGFsX25vX29yZGVycyA9IHN1bSh5X2ZyZXEpLA0KICAgIGF2ZXJhZ2VfcmVjZW5jeSA9IG1lYW4ocmVjZW50KSwNCiAgICBhdmVyYWdlX3Nlbmlvcml0eSA9IG1lYW4oc2VuaW9yKSwNCiAgICBncm91cF9zaXplID0gbigpDQogICl9KSkgJT4lIHVuZ3JvdXAgJT4lIA0KICBtdXRhdGUoeWVhcj1yZXAoMjAxMDoyMDE1LCBlYWNoPTcpKSAlPiUgZGF0YS5mcmFtZQ0KaGVhZChDdXN0U2VnbWVudHMpDQpgYGANCg0KYGBge3IgZXZhbD1GfQ0KcGxvdCggZ3Zpc01vdGlvbkNoYXJ0KA0KICBDdXN0U2VnbWVudHMsICJzdGF0dXMiLCAieWVhciIsDQogIG9wdGlvbnM9bGlzdCh3aWR0aD05MDAsIGhlaWdodD02MDApICkgKQ0KYGBgDQoNCjxjZW50ZXI+DQoNCiFb5ZyW5Zub44CB6aGn5a6i5YiG576k6KaP5YmHXShmaWcvZmlnNC5qZmlmKQ0KDQo8L2NlbnRlcj4NCg0KDQojIyMjIyAzLjcg5peP576k5bGs5oCn5YuV5oWL5YiG5p6QDQpgYGB7cn0NCmRmID0gbWVyZ2UoWSRZMjAxNFssYygxLDYpXSwgWSRZMjAxNVssYygxLDYpXSwNCiAgICAgICAgICAgYnk9ImNpZCIsIGFsbC54PVQpDQp0eCA9IHRhYmxlKGRmJHN0YXR1cy54LCBkZiRzdGF0dXMueSkgJT4lIA0KICBhcy5kYXRhLmZyYW1lLm1hdHJpeCgpICU+JSBhcy5tYXRyaXgoKQ0KdHggICAgIyDmtYHph4/nn6npmaMNCmBgYA0KDQpgYGB7cn0NCnR4ICU+JSBwcm9wLnRhYmxlKDEpICU+JSByb3VuZCgzKSAgICMg5rWB6YeP55+p6ZmjKCUpDQpgYGANCg0KIyMjIyMgMy44IOS6kuWLleW8j+a1gemHj+WIhuaekA0KYGBge3J9DQpjaG9yZGRpYWcodHgsIGdyb3VwQ29sb3JzPWNvbHMpDQpgYGANCg0KIVtdKGZpZy9jaG9yZC5qcGcpDQoNCjxicj48aHI+DQoNCjxkaXYgaWQ9Im1vZGVsIj4NCiMjIyA0LiDlu7rnq4vmqKHlnosNCjwvZGl2Pg0KDQrlnKjpgJnlgIvmoYjkvovoo6HpnaLvvIzmiJHlgJHnmoTos4fmlpnmmK/mlLbliLBZMjAxNeW5tOW6le+8jOaJgOS7peaIkeWAkeWPr+S7peWBh+ioreePvuWcqOeahOaZgumWk+aYr1kyMDE15bm05bqV77yM5oiR5YCR5oOz6KaB55So54++5pyJ55qE6LOH5paZ5bu656uL5qih5Z6L77yM5L6G6aCQ5ris5q+P5LiA5L2N6aGn5a6i77yaDQoNCisg5ZyoWTIwMTblubTmmK/lkKbmnIPkvobos7zosrcgKOS/neeVmeeOh++8mlJldGFpbikNCisg5aW55L6G6LO86LK355qE6Kmx77yM5pyD6LK35aSa5bCR6YyiICjos7zosrfph5HpoY3vvJpSZXZlbnVlKQ0KDQrkvYbmmK/vvIzmiJHlgJHkuKbmspLmnIlZMjAxNueahOizh+aWme+8jOeCuuS6huimgeW7uueri+aooeWei++8jOaIkeWAkemcgOimgeWFiOaKiuaZgumWk+WbnuaOqOS4gOacn++8jOS5n+WwseaYr+iqqu+8mg0KDQorIOeUqFkyMDE05bm05bqV5Lul5YmN55qE6LOH5paZ5pW055CG5Ye66aCQ5ris6K6K5pW4KFgpIA0KKyDnlKhZMjAxNeW5tOeahOizh+aWmeaVtOeQhuWHuuebruaomeiuiuaVuChZKSANCg0K5YGH5aaCWTIwMTbnmoTmg4Xms4Eo6LefWTIwMTXmr5Qp5rKS5pyJ5aSq5aSn55qE6K6K5YyW55qE6Kmx77yM5o6l5LiL5L6G5oiR5YCR5bCx5Y+v5LulDQoNCisg5L2/55So6Kmy5qih5Z6L77yM5LulWTIwMTXlubTlupXnmoTos4fmlpnvvIzpoJDmuKxZMjAxNueahOeLgOazgQ0KDQojIyMjIyA0LjEg5rqW5YKZ6LOH5paZDQrmiJHlgJHnlKhZMjAxNOW5tOW6leeahOizh+aWmeWBmuiHquiuiuaVuO+8jFkyMDE15bm055qE6LOH5paZ5YGa5oeJ6K6K5pW4DQoNCmBgYHtyfQ0KQ1ggPSBsZWZ0X2pvaW4oWSRZMjAxNCwgWSRZMjAxNVssYygxLDgsOSldLCBieT0iY2lkIikgDQojbGVmdCBqb2luIOS/neeVmTIwMTTnmoTvvIzljbPkvb/lnKgyMDE15om+5LiN5Yiw5Lmf6KaB55WZ5LiL6LOH5paZ77yMMjAxNeeahOizh+aWmeWJh+Whq051bGzmiJZOQQ0KaGVhZChDWCkNCmBgYA0KDQpgYGB7cn0NCm5hbWVzKENYKVs4OjExXSA9IGMoImZyZXEwIiwicmV2ZW51ZTAiLCJSZXRhaW4iLCAiUmV2ZW51ZSIpDQpDWCRSZXRhaW4gPSBDWCRSZXRhaW4gPiAwICMyMDE15pyD5LiN5pyD5L6G6LK3DQpoZWFkKENYKQ0KYGBgDQoNCmBgYHtyfQ0KdGFibGUoQ1gkUmV0YWluKSAlPiUgcHJvcC50YWJsZSgpICAjIOW5s+Wdh+S/neeVmeapn+eOhyA9IDIyLjU0JQ0KYGBgDQoNCiMjIyMjIDQuMiDlu7rnq4vpoZ7liKXmqKHlnosNCmBgYHtyfQ0KbVJldCA9IGdsbShSZXRhaW4gfiAuLCBDWFssYygyOjMsNiw4OjEwKV0sIGZhbWlseT1iaW5vbWlhbCgpKQ0Kc3VtbWFyeShtUmV0KQ0KYGBgDQoNCiMjIyMjIDQuMyDkvLDoqIjpoZ7liKXmqKHlnovnmoTmupbnorrmgKcNCmBgYHtyfQ0KcHJlZCA9IHByZWRpY3QobVJldCx0eXBlPSJyZXNwb25zZSIpDQp0YWJsZShwcmVkPjAuNSxDWCRSZXRhaW4pIA0KIyDmt7fmt4bnn6npmaMgKENvbmZ1c2lvbiBNYXRyaXgpICANCmBgYA0KYGBge3J9DQp0YWJsZShwcmVkPjAuNSxDWCRSZXRhaW4pICU+JSANCiAge3N1bShkaWFnKC4pKS9zdW0oLil9ICAgICAgICAgICAgIyDmraPnorrnjocoQUNDKTogODUuMTklIA0KYGBgDQpgYGB7cn0NCmNvbEFVQyhwcmVkLENYJFJldGFpbikgICAgICAgICAgICAgIyDovq/orZjnjocoQVVDKTogODcuOTIlDQpgYGANCmBgYHtyIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTR9DQpwcmVkaWN0aW9uKHByZWQsIENYJFJldGFpbikgJT4lICAgICMgUk9DIENVUlZFIA0KICBwZXJmb3JtYW5jZSgidHByIiwgImZwciIpICU+JSANCiAgcGxvdChwcmludC5jdXRvZmZzLmF0PXNlcSgwLDEsMC4xKSkNCmBgYA0KDQojIyMjIyA0LjQg5bu656uL5pW46YeP5qih5Z6LDQpgYGB7cn0NCmR4ID0gc3Vic2V0KENYLCBSZXZlbnVlID4gMCkgICMg5Y+q5bCN5pyJ5L6G6LO86LK355qE5Lq65YGa5qih5Z6LDQptUmV2ID0gbG0obG9nKFJldmVudWUpIH4gcmVjZW50ICsgZnJlcSArIGxvZygxK21vbmV5KSArIHNlbmlvciArDQogICAgICAgICAgc3RhdHVzICsgZnJlcTAgKyBsb2coMStyZXZlbnVlMCksIGR4KSAgDQpzdW1tYXJ5KG1SZXYpICAgICAgICAgICAgICAgICAjIOWIpOWumuS/guaVuO+8mlIyID0gMC43MTMNCmBgYA0KYGBge3IgZmlnLmhlaWdodD00LjUsIGZpZy53aWR0aD00LjV9DQpwbG90KGxvZyhkeCRSZXZlbnVlKSwgcHJlZGljdChtUmV2KSwgY29sPSdwaW5rJywgY2V4PTAuNjUpDQphYmxpbmUoMCwxLGNvbD0ncmVkJykgDQpgYGANCjxicj48aHI+DQoNCjxkaXYgaWQ9ImN2bSI+DQojIyMgNS4g5Lyw6KiI6aGn5a6i57WC55Sf5YO55YC8DQo8L2Rpdj4NCg0KIyMjIyMgNS4xIFkyMDE255qE6aCQ5ris5YC8DQrkvb/nlKjmqKHlnovlsI1ZMjAxNeW5tOW6leeahOizh+aWmeWBmumgkOa4rO+8jOWwjeizh+aWmeS4reeahOavj+S4gOS9jemhp+Wuou+8jOmgkOa4rOWlueWAkeWcqFkyMDE255qE5L+d55WZ546H5ZKM6LO86LK36YeR6aGN44CCDQpgYGB7cn0NCkNYID0gWSRZMjAxNQ0KbmFtZXMoQ1gpWzg6OV0gPSBjKCJmcmVxMCIsInJldmVudWUwIikNCg0KIyDpoJDmuKxZMjAxNuS/neeVmeeOhw0KQ1gkUHJvYlJldGFpbiA9IHByZWRpY3QobVJldCxDWCx0eXBlPSdyZXNwb25zZScpDQoNCiMg6aCQ5risWTIwMTbos7zosrfph5HpoY0NCkNYJFByZWRSZXZlbnVlID0gZXhwKHByZWRpY3QobVJldixDWCkpDQpgYGANCg0KYGBge3IgZmlnLmhlaWdodD0yLjUsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93PWMoMSwyKSwgbWFyPWMoNCwzLDMsMiksIGNleD0wLjgpDQpoaXN0KENYJFByb2JSZXRhaW4sbWFpbj0iUHJvYlJldGFpbiIsIHlsYWI9IiIpDQpoaXN0KGxvZyhDWCRQcmVkUmV2ZW51ZSwxMCksbWFpbj0ibG9nKFByZWRSZXZlbnVlKSIsIHlsYWI9IiIpDQpgYGANCjxicj4NCg0KIyMjIyMgNS4yIOS8sOioiOmhp+Wuoue1gueUn+WDueWAvChDTFYpDQoNCjxjZW50ZXI+6aGn5a6iJGkk55qE57WC55Sf5YO55YC8PC9jZW50ZXI+DQoNCiQkIFZfaSA9IFxzdW1fe3Q9MH1eTiBnIFx0aW1lcyBtX2kgXGZyYWN7cl9pXnR9eygxK2QpXnR9ID0gZyBcdGltZXMgbV9pIFxzdW1fe3Q9MH1eTiAoXGZyYWN7cl9pfXsxK2R9KV50ICAkJA0KDQo8Y2VudGVyPiRtX2kk44CBJHJfaSTvvJrpoaflrqIkaSTnmoTpoJDmnJ8o5q+P5pyfKeeHn+aUtuiyoueNu+OAgeS/neeVmeapn+eOhzwvY2VudGVyPg0KDQo8Y2VudGVyPiRnJOOAgSRkJO+8muWFrOWPuOeahCjnqIXliY0p54ef5qWt5Yip5r2k5Yip546H44CB6LOH6YeR5oiQ5pysPC9jZW50ZXI+DQoNCmBgYHtyfQ0KZyA9IDAuNSAgICMgKOeoheWJjSnnjbLliKnnjocNCk4gPSA1ICAgICAjIOacn+aVuCA9IDUNCmQgPSAwLjEgICAjIOWIqeeOhyA9IDEwJQ0KQ1gkQ0xWID0gZyAqIENYJFByZWRSZXZlbnVlICogcm93U3VtcyhzYXBwbHkoDQogIDA6TiwgZnVuY3Rpb24oaSkgKENYJFByb2JSZXRhaW4vKDErZCkpXmkgKSApDQoNCnN1bW1hcnkoQ1gkQ0xWKQ0KYGBgDQoNCmBgYHtyIGZpZy5oZWlnaHQ9Mi41LCBmaWcud2lkdGg9Ny4yfQ0KcGFyKG1hcj1jKDIsMiwzLDEpLCBjZXg9MC44KQ0KaGlzdChsb2coQ1gkQ0xWLDEwKSwgeGxhYj0iIiwgeWxhYj0iIikNCmBgYA0KDQojIyMjIyA1LjMg5q+U6LyD5ZCE5peP576k55qE5YO55YC8DQoNCmBgYHtyfQ0KIyDlkITml4/nvqTnmoTlubPlnYfnh5/mlLbosqLnjbvjgIHkv53nlZnmqZ/njofjgIHntYLnlJ/lg7nlgLwNCnNhcHBseShDWFssMTA6MTJdLCB0YXBwbHksIENYJHN0YXR1cywgbWVhbikNCmBgYA0KDQoNCmBgYHtyfQ0KcGFyKG1hcj1jKDMsMyw0LDIpLCBjZXg9MC44KQ0KYm94cGxvdChsb2coQ0xWKX5zdGF0dXMsIENYLCBtYWluPSJDTFYgYnkgR3JvdXBzIikNCg0KYGBgDQo8YnI+PGhyPg0KDQo8ZGl2IGlkPSJzdHJhdGVneSI+DQojIyMgNi4g6Kit5a6a6KGM6Yq3562W55Wl44CB6KaP5YqD6KGM6Yq35bel5YW3DQo8L2Rpdj4NCjxicj48aHI+DQoNCg0KPGRpdiBpZD0ibWFya2V0aW5nIj4NCiMjIyA3LiDpgbjmk4fooYzpirflsI3osaENCjwvZGl2Pg0KDQrntablrprmn5DkuIDooYzpirflt6XlhbfnmoTmiJDmnKzlkozpoJDmnJ/mlYjnm4rvvIzpgbjmk4flj6/ku6Xmlr3ooYzpgJnpoIXlt6XlhbfnmoTlsI3osaHjgIIgDQoNCiMjIyMjIDcuMSDlsI1SMuaXj+e+pOmAsuihjOS/neeVmQ0KUjLml4/nvqTnmoTpoJDmuKzkv53nlZnnjoflkozos7zosrfph5HpoY0NCmBgYHtyIGZpZy5oZWlnaHQ9Mi41LCBmaWcud2lkdGg9OH0NCnBhcihtZnJvdz1jKDEsMiksIG1hcj1jKDQsMywzLDIpLCBjZXg9MC44KQ0KaGlzdChDWCRQcm9iUmV0YWluW0NYJHN0YXR1cz09IlIyIl0sbWFpbj0iUHJvYlJldGFpbiIseGxhYj0iIikNCmhpc3QobG9nKENYJFByZWRSZXZlbnVlW0NYJHN0YXR1cz09IlIyIl0sMTApLG1haW49IlByZWRSZXZlbnVlIix4bGFiPSIiKQ0KYGBgDQoNCiMjIyMjIDcuMiDkvLDoqIjpoJDmnJ/loLHphawNCuWBh+ioreihjOmKt+W3peWFt+eahOaIkOacrOWSjOmgkOacn+aViOebiueCug0KYGBge3J9DQpjb3N0ID0gMTAgICAgICAgICMg5oiQ5pysDQplZmZlY3QgPSAwLjc1ICAgICMg5pWI55uK77ya5LiL5LiA5pyf55qE6LO86LK35qmf546HDQpgYGANCg0K5Lyw6KiI6YCZ6aCF6KGM6Yq35bel5YW35bCN5q+P5LiA5L2NUjLpoaflrqLnmoTpoJDmnJ/loLHphawNCmBgYHtyfQ0KVGFyZ2V0ID0gc3Vic2V0KENYLCBzdGF0dXM9PSJSMiIpDQpUYXJnZXQkRXhwUmV0dXJuID0gKGVmZmVjdCAtIFRhcmdldCRQcm9iUmV0YWluKSAqIFRhcmdldCRQcmVkUmV2ZW51ZSAtIGNvc3QNCnN1bW1hcnkoVGFyZ2V0JEV4cFJldHVybikNCmBgYA0K6YCZ5LiA6aCF5bel5YW35bCNUjLpoaflrqLnmoTpoJDmnJ/loLHphazmmK/osqDnmoQNCg0KIyMjIyMgNy4zIOmBuOaTh+ihjOmKt+WwjeixoQ0K5L2G5piv77yM5oiR5YCR6YKE5piv5Y+v5Lul5oyR5Ye66Kix5aSa6aCQ5pyf5aCx6YWs5b6I5aSn55qE6KGM6Yq35bCN6LGhDQpgYGB7cn0NClRhcmdldCAlPiUgYXJyYW5nZShkZXNjKEV4cFJldHVybikpICU+JSBzZWxlY3QoY2lkLCBFeHBSZXR1cm4pICU+JSBoZWFkKDE1KQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtKFRhcmdldCRFeHBSZXR1cm4gPiAwKSAgICAgICAgICAgICAgICAgIyDlj6/lr6bmlr3lsI3osaHvvJoyNTgNCmBgYA0K5ZyoUjLkuYvkuK3vvIzmnIkyNTjkurrnmoTpoJDmnJ/loLHphazlpKfmlrzpm7bvvIzlpoLmnpzlsI3pgJkyNTjkurrkvb/nlKjpgJnpoIXlt6XlhbfvvIzmiJHlgJHnmoTmnJ/mnJvloLHphazmmK/vvJoNCmBgYHtyfQ0Kc3VtKFRhcmdldCRFeHBSZXR1cm5bVGFyZ2V0JEV4cFJldHVybiA+IDBdKSAgICMg6aCQ5pyf5aCx6YWs77yaNjQ2NA0KYGBgDQoNCiMjIyMjIFFVSVo6DQrmiJHlgJHlj6/ku6Xnrpflh7rlsI3miYDmnInnmoTml4/nvqTlr6bmlr3pgJnpoIXlt6XlhbfnmoTmnJ/mnJvloLHphawgLi4uDQpgYGB7cn0NClRhcmdldCA9IENYDQpUYXJnZXQkRXhwUmV0dXJuID0gKGVmZmVjdCAtIFRhcmdldCRQcm9iUmV0YWluKSAqIFRhcmdldCRQcmVkUmV2ZW51ZSAtIGNvc3QNCmZpbHRlcihUYXJnZXQsIFRhcmdldCRFeHBSZXR1cm4gPiAwKSAlPiUNCiAgZ3JvdXBfYnkoc3RhdHVzKSAlPiUgc3VtbWFyaXNlKA0KICAgIE5vLlRhcmdldCA9IG4oKSwNCiAgICBBdmdST0kgPSBtZWFuKEV4cFJldHVybiksDQogICAgVG90YWxST0kgPSBzdW0oRXhwUmV0dXJuKSApICU+JSBkYXRhLmZyYW1lDQpgYGANCumAmeWAi+e1kOaenOaYr+WQiOeQhueahOWXju+8nyDkvaDmg7PopoHmgI7purzkv67mraPpgJnpoIXliIbmnpDnmoTnqIvluo/lkaLvvJ8NCg0KPGRpdiBjbGFzcz0iY29tbWVudCI+DQoNCisg5LiN5ZCI55CG44CC6YCZ5piv6Yed5bCNUjLml4/nvqTooYzpirflt6XlhbfnmoTmnJ/mnJvloLHphazntZDmnpzvvIzliY3pnaLoqK3lrprnmoRjb3N05oiQ5pys5ZKMZWZmZWN06LO86LK35qmf546HKOaViOebiinmh4noqbLmnIPmoLnmk5rpgY7lvoDntpPpqZflkozph53lsI3nmoTml4/nvqTogIzmnInmiYDkuI3lkIzvvIzkuI3lkIzml4/nvqTkuI3og73ntbHkuIDlpZfnlKjkuIDlgIvoqK3lrprjgIINCisg6Kit5q2k5Lu96LOH5paZ5oOF5aKD54K65om555m85qWt77yM5qC55pOa5oiR5YCR6Ieq5a6a55qE6KaP5YmH77yM5YiG5oiQ5Lul5LiL5peP576k77yaDQoNCiAgKyDmlrDpoaflrqLvvJrmiJHlgJHluIzmnJvorpPpgJnkupvmlrDpoaflrqLorormiJDmnKrkvobnmoTkuLvopoHpoaflrqLvvIzmk7TlpKfpirfllK7ph4/vvIzlm6DmraTmipXkuIvmr5RSMuaXj+e+pOabtOWkmueahOaIkOacrO+8jOiAjOaWsOa9m+WKm+mhp+WuouWPiOavlOaWsOmhp+WuoumHjeimge+8jOWboOatpOWFtmNvc3TovIPpq5jvvIznlJroh7Ppq5jmlrzkuLvopoHpoaflrqLvvIzlm6DngrrlnKjnq7bniK3mv4Dng4jnmoTmibnnmbzmpa3luILloLTkuIrvvIzopoHlkLjlvJXmlrDpoaflrqLjgIINCiAgDQogICAgKyBOMSDmlrDpoaflrqLjgIBjb3N0OjEzICBlZmZlY3Q6MC41DQogICAgKyBOMiDmlrDmvZvlipvpoaflrqIgY29zdDoxNSAgZWZmZWN0OjAuNg0KICANCiAgKyDkuLvopoHpoaflrqLvvJrlm6Dmibnnmbzmpa3poaflrqLovYnmj5vmiJDmnKzpnZ7luLjkvY7vvIznq7bniK3lsI3miYvnnL7lpJrvvIzlm6DmraTmrLLnlZnkuIvkuLvopoHpoaflrqLvvIzlv4XpoIjmj5DmkqXovIPlpJrooYzpirfmiJDmnKzvvIzpgb/lhY3mtYHlpLHkuLvopoHpoaflrqLjgILmoLjlv4PpoaflrqLnmoTlubPlnYfos7zosrfpgLHmnJ/ovIPkvY7vvIzmmK/mnIDluLjlhYnoh6jnmoTpoaflrqLvvIzngrrntq3mjIHlhbblv6DoqqDluqbvvIzlm6DmraTmiJHlgJHoqK3lrprlpoLkuIvvvJoNCiAgDQogICAgKyBSMSDkuLvlipvpoaflrqIgY29zdDo4ICBlZmZlY3Q6MC43DQogICAgKyBSMiDmoLjlv4PpoaflrqIgY29zdDoxMCAgZWZmZWN0OjAuNzUNCg0KICArIOayieedoeaXj+e+pO+8muaIkeWAkeiqjeeCuuS4jeWkqumcgOimgeWGjeWwjeayieedoeaXj+e+pOaKleS4i+WkquWkmuW/g+WKm++8jOWboOatpOS9v+eUqOeahOihjOmKt+W3peWFt+aIkOacrOimgeS9ju+8jOS4lOS8sOioiOmAmeS6m+mhp+WuouWbnuS+hueahOapn+eOh+S4jemrmO+8jOWboOatpOioreWumuWmguS4i++8mg0KICANCiAgICArIFMxIOeejOedoemhp+WuoiBjb3N0OjIgIGVmZmVjdDowLjMNCiAgICArIFMyIOWNiuedoemhp+WuoiBjb3N0OjIgIGVmZmVjdDowLjINCiAgICArIFMzIOayieedoemhp+WuoiBjb3N0OjIgIGVmZmVjdDowLjENCiAgDQoNCg0KPC9kaXY+DQoNCjxicj48YnI+PGhyPg0KDQo8ZGl2IGlkPSJjb25jbHVzaW9uIj4NCiMjIyA4LiDntZDoq5YNCjwvZGl2Pg0KDQrlpoLmnpzkvaDlj6rmnInpoaflrqJJROOAgeS6pOaYk+aXpeacn+OAgeS6pOaYk+mHkemhjeS4ieWAi+ashOS9jeeahOipse+8jOS9oOWPr+S7peWBmueahOWIhuaekOWMheaLrO+8mg0KDQorIOWFqOmrlOmhp+WuouWSjOavj+S4gOWAi+mhp+WuouWIhue+pOeahO+8mg0KICAgICsg5peP576k5aSn5bCP6IiH5oiQ6ZW36Lao5YuiDQogICAgKyDml4/nvqTlsazmgKfliIbmnpDvvJrlpoLlubPlnYdDTFbjgIHlubPlnYfnh5/mlLbosqLnjbvjgIHmiJDplbfnjofjgIHmr5vliKnnjoco6ZyA6KaB5pyJ5oiQ5pys6LOH5paZKeetieetiQ0KICAgICsg57WE6ZaT5rWB6YeP5ZKM5bmz5Z2H5rWB5YuV5qmf546HDQoNCisg5q+P5LiA5YCL6aGn5a6i55qE77yaDQogICAgKyDkv53nlZnnjofjgIHpoJDmnJ/os7zosrfph5HpoY3jgIHntYLouqvlg7nlgLwNCiAgICArIOebruWJjeaJgOWcqOe+pOe1hO+8jOS7peWPiuS4i+S4gOacn+acg+i9ieWIsOWAi+e+pOe1hOeahOapn+eOhw0KICAgICsg5aaC5p6c5pyJ6KGM6Yq35bel5YW355qE5L2/55So57SA6YyE55qE6Kmx77yM5oiR5YCR5Lmf5Y+v5Lul5Lyw6KiI5q+P5LiA5qij6KGM6Yq35bel5YW344CB5bCN5q+P5LiA5L2N6aGn5a6i55qE5oiQ5Yqf5qmf546HDQoNCuS4gOiIrOiAjOiogO+8jOmAmeS4gOS6m+WIhuaekOeahOe1kOaenO+8jOi2s+WkoOiuk+aIkeWAkeWItuWumumhp+WuoueZvOWxleWSjOmhp+WuouS/neeVmeetlueVpe+8m+iHs+aWvOmhp+WuouWQuOaUtuetlueVpe+8jOaIkeWAkemAmuW4uOmChOmcgOimgeW+nkNSTeaSiOWHuumhp+WuouWAi+S6uuWxrOaAp+izh+aWmeaJjeiDveWBmuWIsOOAgiANCg0KDQo8YnI+PGJyPjxocj48YnI+PGJyPjxicj4NCg0KPHN0eWxlPg0KLmNhcHRpb24gew0KICBjb2xvcjogIzc3NzsNCiAgbWFyZ2luLXRvcDogMTBweDsNCn0NCnAgY29kZSB7DQogIHdoaXRlLXNwYWNlOiBpbmhlcml0Ow0KfQ0KcHJlIHsNCiAgd29yZC1icmVhazogbm9ybWFsOw0KICB3b3JkLXdyYXA6IG5vcm1hbDsNCiAgbGluZS1oZWlnaHQ6IDE7DQp9DQpwcmUgY29kZSB7DQogIHdoaXRlLXNwYWNlOiBpbmhlcml0Ow0KfQ0KcCxsaSB7DQogIGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgIuW+rui7n+ato+m7kemrlCIsICJNaWNyb3NvZnQgSmhlbmdIZWkiOw0KfQ0KDQoucnsNCiAgbGluZS1oZWlnaHQ6IDEuMjsNCn0NCg0KdGl0bGV7DQogIGNvbG9yOiAjY2MwMDAwOw0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KYm9keXsNCiAgZm9udC1mYW1pbHk6ICJUcmVidWNoZXQgTVMiLCAi5b6u6Luf5q2j6buR6auUIiwgIk1pY3Jvc29mdCBKaGVuZ0hlaSI7DQp9DQoNCmgxLGgyLGgzLGg0LGg1ew0KICBjb2xvcjogIzAwODgwMDsNCiAgZm9udC1mYW1pbHk6ICJUcmVidWNoZXQgTVMiLCAi5b6u6Luf5q2j6buR6auUIiwgIk1pY3Jvc29mdCBKaGVuZ0hlaSI7DQp9DQoNCmgzew0KICBjb2xvcjogIzAwODgwMDsNCiAgYmFja2dyb3VuZDogI2U2ZmZlNjsNCiAgbGluZS1oZWlnaHQ6IDI7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KDQpoNXsNCiAgY29sb3I6ICMwMDYwMDA7DQogIGJhY2tncm91bmQ6ICNmOGY4Zjg7DQogIGxpbmUtaGVpZ2h0OiAxLjU7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KDQplbXsNCiAgY29sb3I6ICMwMDAwYzA7DQogIGJhY2tncm91bmQ6ICNmMGYwZjA7DQogIH0NCiAgDQoubmF2IHsNCiAgICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7DQogICAgbWFyZ2luOiAwOw0KICAgIHBhZGRpbmc6IDA7DQogICAgd2lkdGg6IDIwMHB4Ow0KICAgIGJhY2tncm91bmQtY29sb3I6ICNmMWYxZjE7DQogICAgcG9zaXRpb246IGZpeGVkOw0KICAgIGxlZnQ6IDVweDsNCn0NCg0KbGkgYSB7DQogICAgZGlzcGxheTogYmxvY2s7DQogICAgY29sb3I6ICMwMDA7DQogICAgcGFkZGluZzogOHB4IDE2cHg7DQogICAgdGV4dC1kZWNvcmF0aW9uOiBub25lOw0KfQ0KDQpsaSBhLmFjdGl2ZSB7DQogICAgYmFja2dyb3VuZC1jb2xvcjogIzRDQUY1MDsNCiAgICBjb2xvcjogd2hpdGU7DQp9DQoNCmxpIGE6aG92ZXI6bm90KC5hY3RpdmUpIHsNCiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjNTU1Ow0KICAgIGNvbG9yOiB3aGl0ZTsNCn0NCg0KLmNvbW1lbnQgew0KICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7DQogICAgYm9yZGVyOiAycHggc29saWQgI2NhOGVmZjsNCiAgICBwYWRkaW5nOiAyMHB4OyANCn0NCjwvc3R5bGU+DQoNCg==
Group4:
B034020012 謝雨靜
B034020027 陳韻卉
B044012015 王譯苓
M064111025 黃威豪
M064111039 王 欣
行傳所 孟祥瑄