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

善用商業數據分析的工具和技巧,光靠一份最簡單的交易紀錄(只有顧客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)
package 'ROCR' was built under R version 3.5.1Loading required package: gplots
package 'gplots' was built under R version 3.5.1
Attaching package: 'gplots'

The following object is masked from 'package:stats':

    lowess
library(googleVis)
package 'googleVis' was built under R version 3.5.1Creating a generic function for 'toJSON' from package 'jsonlite' in package 'googleVis'

Welcome to googleVis version 0.6.2

Please read Google's Terms of Use
before you start using the package:
https://developers.google.com/terms/

Note, the plot method of googleVis will by default use
the standard browser to display its output.

See the googleVis package vignettes for more details,
or visit http://github.com/mages/googleVis.

To suppress this message use:
suppressPackageStartupMessages(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  
par(cex=0.8)
hist(X$date, "years", las=2, freq=T, xlab="", main="No. Transaction by Year")

有多少不一樣的cid

n_distinct(X$cid)           # 顧客數 18417
[1] 18417
1.2 顧客資料 (A)
  • mutate(): 長一個新欄位
  • days: recency: 整筆資料的最後一天-date
    money = mean(amount),   # 平均購買金額
    senior = max(days),     # 第一次購買距今天數"
0,    since = min(date)       # 第一次購買日期"
  ) %>% data.frame
1.4 顧客資料摘要
summary(A)
      cid             recent          freq           money          senior         since           
 Min.   :    10   Min.   :   1   Min.   : 1.00   Min.   :   5   Min.   :   1   Min.   :2005-01-02  
 1st Qu.: 81990   1st Qu.: 244   1st Qu.: 1.00   1st Qu.:  22   1st Qu.: 988   1st Qu.:2007-10-23  
 Median :136430   Median :1070   Median : 2.00   Median :  30   Median :2087   Median :2010-04-15  
 Mean   :137574   Mean   :1253   Mean   : 2.78   Mean   :  58   Mean   :1984   Mean   :2010-07-26  
 3rd Qu.:195100   3rd Qu.:2130   3rd Qu.: 3.00   3rd Qu.:  50   3rd Qu.:2992   3rd Qu.:2013-04-18  
 Max.   :264200   Max.   :4014   Max.   :45.00   Max.   :4500   Max.   :4016   Max.   :2015-12-31  
1.5 變數的分布狀況

frequency : decrete variable pmin() : 設一個上限,超過上限的都算在最後一個區間

p0 = par(cex=0.8, mfrow=c(2,2), mar=c(3,3,4,2))
hist(A$recent,20,main="recency",ylab="",xlab="")
hist(pmin(A$freq, 10),0:10,main="frequency",ylab="",xlab="")
hist(A$senior,20,main="seniority",ylab="",xlab="")
hist(log(A$money,10),,main="log(money)",ylab="",xlab="")



2. 層級式集群分析

2.1 RFM顧客分群
12345678910NA107322661296223732071942178123922096127NA
2.2 顧客群組屬性

看看每一群裡面平均的RFM為多少

每個泡泡為一個群

  • x y 軸放最重要的變數: frequency,
  • 大小: 這個族群的營收貢獻
  • 顏色: 多久沒來買
  • text: 族群大小

127那群: 是最重要的顧客,較常來買,每次買的金額也高。對他們要想盡辦法保留 2266那群: 常買但買的東西不多。可以看他喜好,盡量刺激他買多一點

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



3. 規則分群

用kmeans分群算是一種“統計”的分群 用階層式的“規則”分群,可以每年都用同樣的規則做分群,就可以比較每年的變化狀況 藉此可以比較顧客在行銷滑水道裡面滑去哪裡了 ##### 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)}

圖三、顧客分群規則

3.2 平均購買週期

K、R、F、M都很重要

計算freq>1,找買超過一次的顧客(有回購的人) \[ 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 \] \[ \frac{\sum_{t=1}^N (\frac{S_i}{F_i})}{N} \] \[ \frac{ \sum_{t=1}^N }{} \]

K = as.integer(sum(A$senior[A$freq>1]) / sum(A$freq[A$freq>1])); K

sum(A$senior[A$freq>1] / A$freq[A$freq>1]) / nrow(A)

回購顧客的平均購買週期 K = 521 days

3.3 滑動資料窗格

每個年底都會彙整資料 用一個大Y變數把每個年份的資料框都存起來 status: 他屬於哪一群顧客(沉睡? 主力?….)

Y = list()              # 建立一個空的LIST
for(y in 2010:2015) {   # 每年年底將顧客資料彙整成一個資料框
  D = as.Date(paste0(c(y, y-1),"-12-31")) # 當期、前期的期末日期 
  Y[[paste0("Y",y)]] = X %>%        # 從交易資料做起,命名list的elements為Y+年份
      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)
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)

chrome的設定 > 進階 > 隱私權及安全性 > 內容設定 > Flash > [新增] > 127.0.0.1

plot( gvisMotionChart(
  CustSegments, "status", "year",
  options=list(width=900, height=600) ) )

圖四、顧客分群規則

R2頻率增加 N2購買金額應加

3.7 族群屬性動態分析

看看水缸中的顧客如何流動

  • 381個顧客本來2014年在N1,2015年變成了N2
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    # 流量矩陣
tx %>% prop.table(1) %>% round(3)   # 流量矩陣(%)
3.8 互動式流量分析

柱子: 粗的流動到細的地方 小山丘: 留在原水缸

S1的人一部分繼續睡,一部份跑到S2(睡更深)

chorddiag(tx, groupColors=cols)


4. 建立模型

在這個案例裡面,我們的資料是收到Y2015年底,所以我們可以假設現在的時間是Y2015年底,我們想要用現有的資料建立模型,來預測每一位顧客:

但是,我們並沒有Y2016的資料,為了要建立模型,我們需要先把時間回推一期,也就是說:

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

4.1 準備資料

我們用Y2014年底的資料做自變數,Y2015年的資料做應變數 當期購買次數&金額為第8,9欄 第1欄為cId,拿來當join時的key

left_join: 如果兩邊沒有match的資料,保留左邊的資料右邊填na或null merge: 如果兩邊沒有match的資料,就直接砍了不會保留

欄位名稱中的.x和.y是R自動加進去的

CX = left_join(Y$Y2014, Y$Y2015[,c(1,8,9)], by="cid")
head(CX)
  • y_freq.y欄位: 2015年會不會來買(Retain)
  • y_revenue.y欄位: 2015年會來買多少錢
names(CX)[8:11] = c("freq0","revenue0","Retain", "Revenue")
CX$Retain = CX$Retain > 0
head(CX)
table(CX$Retain) %>% prop.table()  # 平均保留機率 = 22.54%
4.2 建立類別模型
mRet = glm(Retain ~ ., CX[,c(2:3,6,8:10)], family=binomial())
summary(mRet)
4.3 估計類別模型的準確性
pred = predict(mRet,type="response")
table(pred>0.5,CX$Retain) 
# 混淆矩陣 (Confusion Matrix)  
table(pred>0.5,CX$Retain) %>% 
  {sum(diag(.))/sum(.)}            # 正確率(ACC): 85.19% 
colAUC(pred,CX$Retain)             # 辯識率(AUC): 87.92%
prediction(pred, CX$Retain) %>%    # ROC CURVE 
  performance("tpr", "fpr") %>% 
  plot(print.cutoffs.at=seq(0,1,0.1))
4.4 建立數量模型

subset : 對會來買的人做回歸模型 log : 應變數取log後再看R-squared

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
  • 紅線為預測值 * 粉紅圈為實際值
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)

所有人的CLV

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

S3族群

par(mfrow=c(1,2), mar=c(4,3,3,2), cex=0.8)
hist(CX$ProbRetain[CX$status=="S3"],main="ProbRetain",xlab="")
hist(log(CX$PredRevenue[CX$status=="S3"],10),main="PredRevenue",xlab="")
7.2 估計預期報酬

可以依據之前使用行銷工具的經驗來推出effect和cost, 這裡假設行銷工具的成本和預期效益為

cost = 10        # 成本
effect = 0.75    # 效益:下一期的購買機率

估計這項行銷工具對每一位R2顧客的預期報酬

Target = subset(CX, status=="R2")
Target$ExpReturn = (effect - Target$ProbRetain) * Target$PredRevenue - cost
summary(Target$ExpReturn)

這一項工具對R2顧客的預期報酬是負的

這項工具對於Retain大於0.75的人其實沒甚麼用 他們算出來的ExpReturn會是負的

7.3 選擇行銷對象

但是,我們還是可以挑出許多預期報酬很大的行銷對象

Target %>% arrange(desc(ExpReturn)) %>% select(cid, ExpReturn) %>% head(15)

找出預期報償為正的顧客 可以對他們實施這項行銷工具

sum(Target$ExpReturn > 0)                 # 可實施對象:258

在R2之中,有258人的預期報酬大於零,如果對這258人使用這項工具,我們的期望報酬是:

sum(Target$ExpReturn[Target$ExpReturn > 0])   # 預期報酬: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

這個結果是合理的嗎? 你想要怎麼修正這項分析的程序呢?

  • 因為每個群算出來的probRetain不一樣,而且同一套行銷工具應用到不同族群的顧客產生出來的cost和effect也不一樣,所以無法直接用相同的算法套運到所有族群。



8. 結論

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

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







LS0tDQp0aXRsZTogIkNWTe+8mumhp+WuouWDueWAvOeuoeeQhiAiDQphdXRob3I6ICLorJ3pm6jpnZwgTTA3NDAyMDAwNiwgMjAxOC8wNy8yOSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCjxicj4NCg0KIyMjIOWJjeiogO+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+PGhyPg0KDQojIyMjIyBTZXR1cCANCmBgYHtyfQ0KU3lzLnNldGxvY2FsZSgiTENfQUxMIiwiQyIpDQpwYWNrYWdlcyA9IGMoDQogICJkcGx5ciIsImdncGxvdDIiLCJnb29nbGVWaXMiLCJkZXZ0b29scyIsIm1hZ3JpdHRyIiwiY2FUb29scyIsIlJPQ1IiLCJjYVRvb2xzIikNCmV4aXN0aW5nID0gYXMuY2hhcmFjdGVyKGluc3RhbGxlZC5wYWNrYWdlcygpWywxXSkNCmZvcihwa2cgaW4gcGFja2FnZXNbIShwYWNrYWdlcyAlaW4lIGV4aXN0aW5nKV0pIGluc3RhbGwucGFja2FnZXMocGtnKQ0KDQppZighaXMuZWxlbWVudCgiY2hvcmRkaWFnIiwgZXhpc3RpbmcpKQ0KICBkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoIm1hdHRmbG9yL2Nob3JkZGlhZyIpDQpgYGANCg0KIyMjIyMgTGlicmFyeQ0KYGBge3IgZWNobz1ULCBtZXNzYWdlPUYsIGNhY2hlPUYsIHdhcm5pbmc9Rn0NCnJtKGxpc3Q9bHMoYWxsPVQpKQ0Kb3B0aW9ucyhkaWdpdHM9NCwgc2NpcGVuPTEyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoY2FUb29scykNCmxpYnJhcnkoUk9DUikNCmxpYnJhcnkoZ29vZ2xlVmlzKQ0KbGlicmFyeShjaG9yZGRpYWcpDQpgYGANCjxicj48aHI+DQoNCiMjIyDln7rmnKzmlbTnkIblh73mlbgNCg0KKiBhcnJhbmdlOiDmoLnmk5rkvaDpgbjlrprnmoTorormlbjlgZrmjpLliJcgKOWPr+S7peaYr+WkmuWAi+iuiuaVuCkNCg0KKiBmaWx0ZXI6IOagueaTmuS9oOioreWumueahOaineS7tuWBmnJvdyDnr6npgbgob3Igc2VsZWN0aW9uKQ0KDQoqIG11dGF0ZTog5qC55pOa5L2g57Wm5a6a55qE5YC86LOm5LqI5paw6K6K5pW477yM5oiW5piv6K6K5pu06IiK6K6K5pW4DQoNCiogc2VsZWN0OiDmoLnmk5rntablrprnmoTorormlbjlkI3nqLHlgZrpgbjmk4fvvIzkuZ/lj6/ku6XlgZrliKrpmaTorormlbgNCg0KKiBncm91cF9ieTog5qC55pOa57Wm5a6a6K6K5pW45YGaZ3JvdXDvvIzku6XpipzmjqVzdW1tYXJpc2UNCg0KKiBzdW1tYXJpc2U6IOizh+aWmeaVtOS9tQ0KDQoNCg0KIyMjIDEgMS4g6LOH5paZ5pW055CGDQoNCiMjIyMjIDEuMSDkuqTmmJPos4fmlpkgKFgpDQpgYGB7cn0NClggPSByZWFkLnRhYmxlKA0KICAncHVyY2hhc2VzLnR4dCcsIGhlYWRlcj1GQUxTRSwgc2VwPSdcdCcsIHN0cmluZ3NBc0ZhY3RvcnM9RikNCm5hbWVzKFgpID0gYygnY2lkJywnYW1vdW50JywnZGF0ZScpDQpYJGRhdGUgPSBhcy5EYXRlKFgkZGF0ZSkNCnN1bW1hcnkoWCkgICAgICAgICAgICAgICAgICAjIOS6pOaYk+asoeaVuCA1MTI0Mw0KYGBgDQoNCg0KYGBge3IgZmlnLmhlaWdodD0zLCBmaWcud2lkdGg9Ny4yfQ0KcGFyKGNleD0wLjgpDQpoaXN0KFgkZGF0ZSwgInllYXJzIiwgbGFzPTIsIGZyZXE9VCwgeGxhYj0iIiwgbWFpbj0iTm8uIFRyYW5zYWN0aW9uIGJ5IFllYXIiKQ0KIyB5ZWFyc+WPr+S7peaPm+aIkHdlZWtz5LmL6aGe55qEDQpgYGANCg0K5pyJ5aSa5bCR5LiN5LiA5qij55qEY2lkDQpgYGB7cn0NCm5fZGlzdGluY3QoWCRjaWQpICAgICAgICAgICAjIOmhp+WuouaVuCAxODQxNw0KYGBgDQoNCiMjIyMjIDEuMiDpoaflrqLos4fmlpkgKEEpDQoNCiogbXV0YXRlKCk6IOmVt+S4gOWAi+aWsOashOS9jQ0KKiBkYXlzOiByZWNlbmN5OiDmlbTnrYbos4fmlpnnmoTmnIDlvozkuIDlpKktZGF0ZQ0KYGBge3J9DQpBID0gWCAlPiUgDQogIG11dGF0ZShkYXlzID0gYXMuaW50ZWdlcihhcy5EYXRlKCIyMDE2LTAxLTAxIikgLSBkYXRlKSkgJT4lIA0KICBncm91cF9ieShjaWQpICU+JSBzdW1tYXJpc2UoDQogICAgcmVjZW50ID0gbWluKGRheXMpLCAgICAgIyDmnIDov5Hos7zosrfot53ku4rlpKnmlbgNCiAgICBmcmVxID0gbigpLCAgICAgICAgICAgICAjIOizvOiyt+asoeaVuA0KICAgIG1vbmV5ID0gbWVhbihhbW91bnQpLCAgICMg5bmz5Z2H6LO86LK36YeR6aGNDQogICAgc2VuaW9yID0gbWF4KGRheXMpLCAgICAgIyDnrKzkuIDmrKHos7zosrfot53ku4rlpKnmlbgNCiAgICBzaW5jZSA9IG1pbihkYXRlKSAgICAgICAjIOesrOS4gOasoeizvOiyt+aXpeacnw0KICApICU+JSBkYXRhLmZyYW1lDQpgYGANCg0KIyMjIyMgMS40IOmhp+Wuouizh+aWmeaRmOimgQ0KYGBge3J9DQpzdW1tYXJ5KEEpDQpgYGANCg0KIyMjIyMgMS41IOiuiuaVuOeahOWIhuW4g+eLgOazgQ0KDQpmcmVxdWVuY3kgOiBkZWNyZXRlIHZhcmlhYmxlIA0KcG1pbigpIDog6Kit5LiA5YCL5LiK6ZmQ77yM6LaF6YGO5LiK6ZmQ55qE6YO9566X5Zyo5pyA5b6M5LiA5YCL5Y2A6ZaTDQpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04fQ0KcDAgPSBwYXIoY2V4PTAuOCwgbWZyb3c9YygyLDIpLCBtYXI9YygzLDMsNCwyKSkNCmhpc3QoQSRyZWNlbnQsMjAsbWFpbj0icmVjZW5jeSIseWxhYj0iIix4bGFiPSIiKQ0KaGlzdChwbWluKEEkZnJlcSwgMTApLDA6MTAsbWFpbj0iZnJlcXVlbmN5Iix5bGFiPSIiLHhsYWI9IiIpDQpoaXN0KEEkc2VuaW9yLDIwLG1haW49InNlbmlvcml0eSIseWxhYj0iIix4bGFiPSIiKQ0KaGlzdChsb2coQSRtb25leSwxMCksLG1haW49ImxvZyhtb25leSkiLHlsYWI9IiIseGxhYj0iIikNCmBgYA0KPGJyPjxocj4NCg0KIyMjIDIuIOWxpOe0muW8j+mbhue+pOWIhuaekA0KDQojIyMjIyAyLjEgUkZN6aGn5a6i5YiG576kDQpgYGB7cn0NCnNldC5zZWVkKDExMSkNCkEkZ3JwID0ga21lYW5zKHNjYWxlKEFbLDI6NF0pLDEwKSRjbHVzdGVyICPlj6rnlKhSLCBGLCBN5LiJ5YCL5qyE5L2NDQp0YWJsZShBJGdycCkgICMg5peP576k5aSn5bCPDQpgYGANCg0KIyMjIyMgMi4yIOmhp+Wuoue+pOe1hOWxrOaApw0KDQrnnIvnnIvmr4/kuIDnvqToo6HpnaLlubPlnYfnmoRSRk3ngrrlpJrlsJENCg0K5q+P5YCL5rOh5rOh54K65LiA5YCL576kDQoNCiogeCB5IOi7uOaUvuacgOmHjeimgeeahOiuiuaVuDogZnJlcXVlbmN5LA0KKiDlpKflsI86IOmAmeWAi+aXj+e+pOeahOeHn+aUtuiyoueNuw0KKiDpoY/oibI6IOWkmuS5heaykuS+huiytw0KKiB0ZXh0OiDml4/nvqTlpKflsI8NCg0KDQoxMjfpgqPnvqQ6IOaYr+acgOmHjeimgeeahOmhp+Wuou+8jOi8g+W4uOS+huiyt++8jOavj+asoeiyt+eahOmHkemhjeS5n+mrmOOAguWwjeS7luWAkeimgeaDs+eboei+puazleS/neeVmQ0KMjI2NumCo+e+pDog5bi46LK35L2G6LK355qE5p2x6KW/5LiN5aSa44CC5Y+v5Lul55yL5LuW5Zac5aW977yM55uh6YeP5Yi65r+A5LuW6LK35aSa5LiA6bueDQoNCmBgYHtyIGZpZy5oZWlnaHQ9NC41LCBmaWcud2lkdGg9OH0NCmdyb3VwX2J5KEEsIGdycCkgJT4lIHN1bW1hcmlzZSgNCiAgcmVjZW50PW1lYW4ocmVjZW50KSwgDQogIGZyZXE9bWVhbihmcmVxKSwgDQogIG1vbmV5PW1lYW4obW9uZXkpLCANCiAgc2l6ZT1uKCkgKSAlPiUgDQogIG11dGF0ZSggcmV2ZW51ZSA9IHNpemUqbW9uZXkvMTAwMCApICAlPiUgDQogIGZpbHRlcihzaXplID4gMSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHg9ZnJlcSwgeT1tb25leSkpICsNCiAgZ2VvbV9wb2ludChhZXMoc2l6ZT1yZXZlbnVlLCBjb2w9cmVjZW50KSxhbHBoYT0wLjUpICsNCiAgc2NhbGVfc2l6ZShyYW5nZT1jKDQsMzApKSArDQogIHNjYWxlX2NvbG9yX2dyYWRpZW50KGxvdz0iZ3JlZW4iLGhpZ2g9InJlZCIpICsNCiAgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMChsaW1pdHM9YygzMCwzMDAwKSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNpemUgKSxzaXplPTMpICsNCiAgdGhlbWVfYncoKSArIGd1aWRlcyhzaXplPUYpICsNCiAgbGFicyh0aXRsZT0iQ3VzdG9tZXIgU2VnZW1lbnRzIiwNCiAgICAgICBzdWJ0aXRsZT0iKGJ1YmJsZV9zaXplOnJldmVudWVfY29udHJpYnV0aW9uOyB0ZXh0Omdyb3VwX3NpemUpIiwNCiAgICAgICBjb2xvcj0iUmVjZW5jeSIpICsNCiAgeGxhYigiRnJlcXVlbmN5IChsb2cpIikgKyB5bGFiKCJBdmVyYWdlIFRyYW5zYWN0aW9uIEFtb3VudCAobG9nKSIpDQpgYGANCjxicj48aHI+DQoNCiMjIyAzLiDopo/liYfliIbnvqQNCueUqGttZWFuc+WIhue+pOeul+aYr+S4gOeoriLntbHoqIgi55qE5YiG576kDQrnlKjpmo7lsaTlvI/nmoQi6KaP5YmHIuWIhue+pO+8jOWPr+S7peavj+W5tOmDveeUqOWQjOaoo+eahOimj+WJh+WBmuWIhue+pO+8jOWwseWPr+S7peavlOi8g+avj+W5tOeahOiuiuWMlueLgOazgQ0K6JeJ5q2k5Y+v5Lul5q+U6LyD6aGn5a6i5Zyo6KGM6Yq35ruR5rC06YGT6KOh6Z2i5ruR5Y675ZOq6KOh5LqGDQojIyMjIyAzLjEg6aGn5a6i5YiG576k6KaP5YmHDQpgYGB7cn0NClNUUyA9IGMoIk4xIiwiTjIiLCJSMSIsIlIyIiwiUzEiLCJTMiIsIlMzIikNClN0YXR1cyA9IGZ1bmN0aW9uKHJ4LGZ4LG14LHN4LEspIHtmYWN0b3IoDQogIGlmZWxzZShzeCA8IDIqSywNCiAgICAgICAgIGlmZWxzZShmeCpteCA+IDUwLCAiTjIiLCAiTjEiKSwNCiAgICAgICAgIGlmZWxzZShyeCA8IDIqSywNCiAgICAgICAgICAgICAgICBpZmVsc2Uoc3gvZnggPCAwLjc1KkssIlIyIiwiUjEiKSwNCiAgICAgICAgICAgICAgICBpZmVsc2UocnggPCAzKkssIlMxIiwNCiAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHJ4IDwgNCpLLCJTMiIsIlMzIikpKSksIFNUUyl9DQpgYGANCg0KPGNlbnRlcj4NCg0KIVvlnJbkuInjgIHpoaflrqLliIbnvqTopo/liYddKGZpZy9maWczLmpmaWYpDQoNCjwvY2VudGVyPg0KDQojIyMjIyAzLjIg5bmz5Z2H6LO86LK36YCx5pyfDQoNCkvjgIFS44CBRuOAgU3pg73lvojph43opoENCg0K6KiI566XZnJlcT4x77yM5om+6LK36LaF6YGO5LiA5qyh55qE6aGn5a6iKOacieWbnuizvOeahOS6uikNCiQkIFZfaSA9IFxzdW1fe3Q9MH1eTiBnIFx0aW1lcyBtX2kgXGZyYWN7cl9pXnR9eygxK2QpXnR9ID0gZyBcdGltZXMgbV9pIFxzdW1fe3Q9MH1eTiAoXGZyYWN7cl9pfXsxK2R9KV50ICAkJA0KJCQgXGZyYWN7XHN1bV97dD0xfV5OIChcZnJhY3tTX2l9e0ZfaX0pfXtOfSAkJA0KJCQgXGZyYWN7IFxzdW1fe3Q9MX1eTiAgIH17fSAkJA0KYGBge3J9DQpLID0gYXMuaW50ZWdlcihzdW0oQSRzZW5pb3JbQSRmcmVxPjFdKSAvIHN1bShBJGZyZXFbQSRmcmVxPjFdKSk7IEsNCg0Kc3VtKEEkc2VuaW9yW0EkZnJlcT4xXSAvIEEkZnJlcVtBJGZyZXE+MV0pIC8gbnJvdyhBKQ0KYGBgDQrlm57os7zpoaflrqLnmoTlubPlnYfos7zosrfpgLHmnJ8gYEsgPSA1MjEgZGF5c2ANCg0KIyMjIyMgMy4zIOa7keWLleizh+aWmeeql+agvA0KDQrmr4/lgIvlubTlupXpg73mnIPlvZnmlbTos4fmlpkNCueUqOS4gOWAi+Wkp1norormlbjmiormr4/lgIvlubTku73nmoTos4fmlpnmoYbpg73lrZjotbfkvoYNCnN0YXR1czog5LuW5bGs5pa85ZOq5LiA576k6aGn5a6iKOayieedoT8g5Li75YqbPy4uLi4pDQpgYGB7cn0NClkgPSBsaXN0KCkgICAgICAgICAgICAgICMg5bu656uL5LiA5YCL56m655qETElTVA0KZm9yKHkgaW4gMjAxMDoyMDE1KSB7ICAgIyDmr4/lubTlubTlupXlsIfpoaflrqLos4fmlpnlvZnmlbTmiJDkuIDlgIvos4fmlpnmoYYNCiAgRCA9IGFzLkRhdGUocGFzdGUwKGMoeSwgeS0xKSwiLTEyLTMxIikpICMg55W25pyf44CB5YmN5pyf55qE5pyf5pyr5pel5pyfIA0KICBZW1twYXN0ZTAoIlkiLHkpXV0gPSBYICU+JSAgICAgICAgIyDlvp7kuqTmmJPos4fmlpnlgZrotbfvvIzlkb3lkI1saXN055qEZWxlbWVudHPngrpZK+W5tOS7vQ0KICAgICAgZmlsdGVyKGRhdGUgPD0gRFsxXSkgJT4lICAgICAgICAjIOWwh+izh+aWmeWIh+m9iuWIsOacn+acq+aXpeacnw0KICAgICAgbXV0YXRlKGRheXMgPSAxICsgYXMuaW50ZWdlcihEWzFdIC0gZGF0ZSkpICU+JSAgICMg5Lqk5piT6Led5pyf5pyr5aSp5pW4DQogICAgICBncm91cF9ieShjaWQpICU+JSBzdW1tYXJpc2UoICAgICMg5L6d6aGn5a6i5b2Z57i9IC4uLg0KICAgICAgICAgIHJlY2VudCA9IG1pbihkYXlzKSwgICAgICAgICAgICMgICDmnIDlvozkuIDmrKHos7zosrfot53mnJ/mnKvlpKnmlbggICANCiAgICAgICAgICBmcmVxID0gbigpLCAgICAgICAgICAgICAgICAgICAjICAg6LO86LK35qyh5pW4ICjoh7PmnJ/mnKvngrrmraIpICAgDQogICAgICAgICAgbW9uZXkgPSBtZWFuKGFtb3VudCksICAgICAgICAgIyAgIOW5s+Wdh+izvOiyt+mHkemhjSAo6Iez5pyf5pyr54K65q2iKQ0KICAgICAgICAgIHNlbmlvciA9IG1heChkYXlzKSwgICAgICAgICAgICMgICDnrKzkuIDmrKHos7zosrfot53mnJ/mnKvlpKnmlbgNCiAgICAgICAgICBzdGF0dXMgPSBTdGF0dXMocmVjZW50LGZyZXEsbW9uZXksc2VuaW9yLEspLCAgIyDmnJ/mnKvni4DmhYsNCiAgICAgICAgICBzaW5jZSA9IG1pbihkYXRlKSwgICAgICAgICAgICAgICAgICAgICAgIyDnrKzkuIDmrKHos7zosrfml6XmnJ8NCiAgICAgICAgICB5X2ZyZXEgPSBzdW0oZGF0ZSA+IERbMl0pLCAgICAgICAgICAgICAgIyDnlbbmnJ/os7zosrfmrKHmlbgNCiAgICAgICAgICB5X3JldmVudWUgPSBzdW0oYW1vdW50W2RhdGUgPiBEWzJdXSkgICAgIyDnlbbmnJ/os7zosrfph5HpoY0NCiAgICAgICkgJT4lIGRhdGEuZnJhbWUgfQ0KYGBgDQoNCmBgYHtyfQ0KaGVhZChZJFkyMDE1KQ0KYGBgDQoNCiMjIyMjIDMuNCDmr4/lubTlubTlupXnmoTntK/oqIjpoaflrqLkurrmlbgNCmBgYHtyfQ0Kc2FwcGx5KFksIG5yb3cpDQpgYGANCg0KIyMjIyMgMy41IOaXj+e+pOWkp+Wwj+iuiuWMlui2qOWLog0KDQrnnaHokZfnmoTkurrmnIPotorkvobotorlpJrvvIzmiYDku6XkurrotorkvobotorlpJoNCuacieS6m+a8lOeul+azleacg+aKiuayieedoeWkquS5heeahOmhp+WuouWIquaOiQ0K55So6YCZ5YCL5ZyW5Y+v5Lul55yL5LiA5LiL5q+P5LiA5YCL5peP576k55qE6aGn5a6i6K6K5YyW54uA5rOBDQpgYGB7ciBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD04fQ0KY29scyA9IGMoImdvbGQiLCJvcmFuZ2UiLCJibHVlIiwiZ3JlZW4iLCJwaW5rIiwibWFnZW50YSIsImRhcmtyZWQiKSAjIOioreWumumhj+iJsg0Kc2FwcGx5KFksIGZ1bmN0aW9uKGRmKSB0YWJsZShkZiRzdGF0dXMpKSAlPiUgYmFycGxvdChjb2w9Y29scykNCmxlZ2VuZCgidG9wbGVmdCIscmV2KFNUUyksZmlsbD1yZXYoY29scykpDQpgYGANCg0KIyMjIyMgMy42IOaXj+e+pOWxrOaAp+WLleaFi+WIhuaekA0KYGBge3J9DQpDdXN0U2VnbWVudHMgPSBkby5jYWxsKHJiaW5kLCBsYXBwbHkoWSwgZnVuY3Rpb24oZCkgew0KICBncm91cF9ieShkLCBzdGF0dXMpICU+JSBzdW1tYXJpc2UoDQogICAgYXZlcmFnZV9mcmVxdWVuY3kgPSBtZWFuKGZyZXEpLA0KICAgIGF2ZXJhZ2VfYW1vdW50ID0gbWVhbihtb25leSksDQogICAgdG90YWxfcmV2ZW51ZSA9IHN1bSh5X3JldmVudWUpLA0KICAgIHRvdGFsX25vX29yZGVycyA9IHN1bSh5X2ZyZXEpLA0KICAgIGF2ZXJhZ2VfcmVjZW5jeSA9IG1lYW4ocmVjZW50KSwNCiAgICBhdmVyYWdlX3Nlbmlvcml0eSA9IG1lYW4oc2VuaW9yKSwNCiAgICBncm91cF9zaXplID0gbigpDQogICl9KSkgJT4lIHVuZ3JvdXAgJT4lIA0KICBtdXRhdGUoeWVhcj1yZXAoMjAxMDoyMDE1LCBlYWNoPTcpKSAlPiUgZGF0YS5mcmFtZQ0KaGVhZChDdXN0U2VnbWVudHMpDQpgYGANCg0KY2hyb21l55qE6Kit5a6aID4g6YCy6ZqOID4g6Zqx56eB5qyK5Y+K5a6J5YWo5oCnID4g5YWn5a656Kit5a6aID4gRmxhc2ggPiBb5paw5aKeXSA+IDEyNy4wLjAuMQ0KYGBge3IgZXZhbD1GfQ0KcGxvdCggZ3Zpc01vdGlvbkNoYXJ0KA0KICBDdXN0U2VnbWVudHMsICJzdGF0dXMiLCAieWVhciIsDQogIG9wdGlvbnM9bGlzdCh3aWR0aD05MDAsIGhlaWdodD02MDApICkgKQ0KYGBgDQoNCjxjZW50ZXI+DQoNCiFb5ZyW5Zub44CB6aGn5a6i5YiG576k6KaP5YmHXShmaWcvZmlnNC5qZmlmKQ0KDQo8L2NlbnRlcj4NCg0KUjLpoLvnjoflop7liqANCk4y6LO86LK36YeR6aGN5oeJ5YqgDQoNCg0KIyMjIyMgMy43IOaXj+e+pOWxrOaAp+WLleaFi+WIhuaekA0KDQrnnIvnnIvmsLTnvLjkuK3nmoTpoaflrqLlpoLkvZXmtYHli5UNCg0KKiAzODHlgIvpoaflrqLmnKzkvoYyMDE05bm05ZyoTjHvvIwyMDE15bm06K6K5oiQ5LqGTjINCg0KYGBge3J9DQpkZiA9IG1lcmdlKFkkWTIwMTRbLGMoMSw2KV0sIFkkWTIwMTVbLGMoMSw2KV0sDQogICAgICAgICAgIGJ5PSJjaWQiLCBhbGwueD1UKQ0KdHggPSB0YWJsZShkZiRzdGF0dXMueCwgZGYkc3RhdHVzLnkpICU+JSANCiAgYXMuZGF0YS5mcmFtZS5tYXRyaXgoKSAlPiUgYXMubWF0cml4KCkNCnR4ICAgICMg5rWB6YeP55+p6ZmjDQpgYGANCg0KYGBge3J9DQp0eCAlPiUgcHJvcC50YWJsZSgxKSAlPiUgcm91bmQoMykgICAjIOa1gemHj+efqemZoyglKQ0KYGBgDQoNCiMjIyMjIDMuOCDkupLli5XlvI/mtYHph4/liIbmnpANCg0K5p+x5a2QOiDnspfnmoTmtYHli5XliLDntLDnmoTlnLDmlrkNCuWwj+WxseS4mDog55WZ5Zyo5Y6f5rC057y4DQoNClMx55qE5Lq65LiA6YOo5YiG57m857qM552h77yM5LiA6YOo5Lu96LeR5YiwUzIo552h5pu05rexKQ0KYGBge3J9DQpjaG9yZGRpYWcodHgsIGdyb3VwQ29sb3JzPWNvbHMpDQpgYGANCg0KIVtdKGZpZy9jaG9yZC5qcGcpDQoNCjxicj48aHI+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+aWmQ0KDQrmiJHlgJHnlKhZMjAxNOW5tOW6leeahOizh+aWmeWBmuiHquiuiuaVuO+8jFkyMDE15bm055qE6LOH5paZ5YGa5oeJ6K6K5pW4DQrnlbbmnJ/os7zosrfmrKHmlbgm6YeR6aGN54K656ysOCw55qyEDQrnrKwx5qyE54K6Y0lk77yM5ou/5L6G55W2am9pbuaZgueahGtleQ0KDQpsZWZ0X2pvaW46IOWmguaenOWFqemCiuaykuaciW1hdGNo55qE6LOH5paZ77yM5L+d55WZ5bem6YKK55qE6LOH5paZ5Y+z6YKK5aGrbmHmiJZudWxsDQptZXJnZTog5aaC5p6c5YWp6YKK5rKS5pyJbWF0Y2jnmoTos4fmlpnvvIzlsLHnm7TmjqXnoI3kuobkuI3mnIPkv53nlZkNCg0K5qyE5L2N5ZCN56ix5Lit55qELnjlkowueeaYr1Loh6rli5XliqDpgLLljrvnmoQNCg0KDQoNCmBgYHtyfQ0KQ1ggPSBsZWZ0X2pvaW4oWSRZMjAxNCwgWSRZMjAxNVssYygxLDgsOSldLCBieT0iY2lkIikNCmhlYWQoQ1gpDQpgYGANCg0KKiB5X2ZyZXEueeashOS9jTogMjAxNeW5tOacg+S4jeacg+S+huiytyhSZXRhaW4pDQoqIHlfcmV2ZW51ZS555qyE5L2NOiAyMDE15bm05pyD5L6G6LK35aSa5bCR6YyiDQoNCmBgYHtyfQ0KbmFtZXMoQ1gpWzg6MTFdID0gYygiZnJlcTAiLCJyZXZlbnVlMCIsIlJldGFpbiIsICJSZXZlbnVlIikNCkNYJFJldGFpbiA9IENYJFJldGFpbiA+IDANCmhlYWQoQ1gpDQpgYGANCg0KYGBge3J9DQp0YWJsZShDWCRSZXRhaW4pICU+JSBwcm9wLnRhYmxlKCkgICMg5bmz5Z2H5L+d55WZ5qmf546HID0gMjIuNTQlDQpgYGANCg0KIyMjIyMgNC4yIOW7uueri+mhnuWIpeaooeWeiw0KYGBge3J9DQptUmV0ID0gZ2xtKFJldGFpbiB+IC4sIENYWyxjKDI6Myw2LDg6MTApXSwgZmFtaWx5PWJpbm9taWFsKCkpDQpzdW1tYXJ5KG1SZXQpDQpgYGANCg0KIyMjIyMgNC4zIOS8sOioiOmhnuWIpeaooeWei+eahOa6lueiuuaApw0KYGBge3J9DQpwcmVkID0gcHJlZGljdChtUmV0LHR5cGU9InJlc3BvbnNlIikNCnRhYmxlKHByZWQ+MC41LENYJFJldGFpbikgDQojIOa3t+a3huefqemZoyAoQ29uZnVzaW9uIE1hdHJpeCkgIA0KYGBgDQpgYGB7cn0NCnRhYmxlKHByZWQ+MC41LENYJFJldGFpbikgJT4lIA0KICB7c3VtKGRpYWcoLikpL3N1bSguKX0gICAgICAgICAgICAjIOato+eiuueOhyhBQ0MpOiA4NS4xOSUgDQpgYGANCmBgYHtyfQ0KY29sQVVDKHByZWQsQ1gkUmV0YWluKSAgICAgICAgICAgICAjIOi+r+itmOeOhyhBVUMpOiA4Ny45MiUNCmBgYA0KYGBge3IgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NH0NCnByZWRpY3Rpb24ocHJlZCwgQ1gkUmV0YWluKSAlPiUgICAgIyBST0MgQ1VSVkUgDQogIHBlcmZvcm1hbmNlKCJ0cHIiLCAiZnByIikgJT4lIA0KICBwbG90KHByaW50LmN1dG9mZnMuYXQ9c2VxKDAsMSwwLjEpKQ0KYGBgDQoNCiMjIyMjIDQuNCDlu7rnq4vmlbjph4/mqKHlnosNCg0Kc3Vic2V0IDog5bCN5pyD5L6G6LK355qE5Lq65YGa5Zue5q245qih5Z6LDQpsb2cgOiDmh4norormlbjlj5Zsb2flvozlho3nnItSLXNxdWFyZWQNCg0KYGBge3J9DQpkeCA9IHN1YnNldChDWCwgUmV2ZW51ZSA+IDApICAjIOWPquWwjeacieS+huizvOiyt+eahOS6uuWBmuaooeWeiw0KbVJldiA9IGxtKGxvZyhSZXZlbnVlKSB+IHJlY2VudCArIGZyZXEgKyBsb2coMSttb25leSkgKyBzZW5pb3IgKw0KICAgICAgICAgIHN0YXR1cyArIGZyZXEwICsgbG9nKDErcmV2ZW51ZTApLCBkeCkgIA0Kc3VtbWFyeShtUmV2KSAgICAgICAgICAgICAgICAgIyDliKTlrprkv4Ig5pW477yaUjIgPSAwLjcxMw0KYGBgDQoNCiog57SF57ea54K66aCQ5ris5YC8DQoq44CA57KJ57SF5ZyI54K65a+m6Zqb5YC8DQoNCmBgYHtyIGZpZy5oZWlnaHQ9NC41LCBmaWcud2lkdGg9NC41fQ0KcGxvdChsb2coZHgkUmV2ZW51ZSksIHByZWRpY3QobVJldiksIGNvbD0ncGluaycsIGNleD0wLjY1KQ0KYWJsaW5lKDAsMSxjb2w9J3JlZCcpIA0KYGBgDQo8YnI+PGhyPg0KDQojIyMgNS4g5Lyw6KiI6aGn5a6i57WC55Sf5YO55YC8DQoNCiMjIyMjIDUuMSBZMjAxNueahOmgkOa4rOWAvA0K5L2/55So5qih5Z6L5bCNWTIwMTXlubTlupXnmoTos4fmlpnlgZrpoJDmuKzvvIzlsI3os4fmlpnkuK3nmoTmr4/kuIDkvY3poaflrqLvvIzpoJDmuKzlpbnlgJHlnKhZMjAxNueahOS/neeVmeeOh+WSjOizvOiyt+mHkemhjeOAgg0KYGBge3J9DQpDWCA9IFkkWTIwMTUNCm5hbWVzKENYKVs4OjldID0gYygiZnJlcTAiLCJyZXZlbnVlMCIpDQoNCiMg6aCQ5risWTIwMTbkv53nlZnnjocNCkNYJFByb2JSZXRhaW4gPSBwcmVkaWN0KG1SZXQsQ1gsdHlwZT0ncmVzcG9uc2UnKQ0KDQojIOmgkOa4rFkyMDE26LO86LK36YeR6aGNDQpDWCRQcmVkUmV2ZW51ZSA9IGV4cChwcmVkaWN0KG1SZXYsQ1gpKQ0KYGBgDQoNCmBgYHtyIGZpZy5oZWlnaHQ9Mi41LCBmaWcud2lkdGg9OH0NCnBhcihtZnJvdz1jKDEsMiksIG1hcj1jKDQsMywzLDIpLCBjZXg9MC44KQ0KaGlzdChDWCRQcm9iUmV0YWluLG1haW49IlByb2JSZXRhaW4iLCB5bGFiPSIiKQ0KaGlzdChsb2coQ1gkUHJlZFJldmVudWUsMTApLG1haW49ImxvZyhQcmVkUmV2ZW51ZSkiLCB5bGFiPSIiKQ0KYGBgDQo8YnI+DQoNCiMjIyMjIDUuMiDkvLDoqIjpoaflrqLntYLnlJ/lg7nlgLwoQ0xWKQ0KDQo8Y2VudGVyPumhp+WuoiRpJOeahOe1gueUn+WDueWAvDwvY2VudGVyPg0KDQokJCBWX2kgPSBcc3VtX3t0PTB9Xk4gZyBcdGltZXMgbV9pIFxmcmFje3JfaV50fXsoMStkKV50fSA9IGcgXHRpbWVzIG1faSBcc3VtX3t0PTB9Xk4gKFxmcmFje3JfaX17MStkfSledCAgJCQNCg0KPGNlbnRlcj4kbV9pJOOAgSRyX2kk77ya6aGn5a6iJGkk55qE6aCQ5pyfKOavj+acnynnh5/mlLbosqLnjbvjgIHkv53nlZnmqZ/njoc8L2NlbnRlcj4NCg0KPGNlbnRlcj4kZyTjgIEkZCTvvJrlhazlj7jnmoQo56iF5YmNKeeHn+alreWIqea9pOWIqeeOh+OAgeizh+mHkeaIkOacrDwvY2VudGVyPg0KDQoNCg0KYGBge3J9DQpnID0gMC41ICAgIyAo56iF5YmNKeeNsuWIqeeOhw0KTiA9IDUgICAgICMg5pyf5pW4ID0gNQ0KZCA9IDAuMSAgICMg5Yip546HID0gMTAlDQpDWCRDTFYgPSBnICogQ1gkUHJlZFJldmVudWUgKiByb3dTdW1zKHNhcHBseSgNCiAgMDpOLCBmdW5jdGlvbihpKSAoQ1gkUHJvYlJldGFpbi8oMStkKSleaSApICkNCg0Kc3VtbWFyeShDWCRDTFYpDQpgYGANCg0K5omA5pyJ5Lq655qEQ0xWDQpgYGB7ciBmaWcuaGVpZ2h0PTIuNSwgZmlnLndpZHRoPTcuMn0NCnBhcihtYXI9YygyLDIsMywxKSwgY2V4PTAuOCkNCmhpc3QobG9nKENYJENMViwxMCksIHhsYWI9IiIsIHlsYWI9IiIpDQpgYGANCg0KIyMjIyMgNS4zIOavlOi8g+WQhOaXj+e+pOeahOWDueWAvA0KDQpgYGB7cn0NCiMg5ZCE5peP576k55qE5bmz5Z2H54ef5pS26LKi542744CB5L+d55WZ5qmf546H44CB57WC55Sf5YO55YC8DQpzYXBwbHkoQ1hbLDEwOjEyXSwgdGFwcGx5LCBDWCRzdGF0dXMsIG1lYW4pDQpgYGANCg0KDQoNCmBgYHtyfQ0KcGFyKG1hcj1jKDMsMyw0LDIpLCBjZXg9MC44KQ0KYm94cGxvdChsb2coQ0xWKX5zdGF0dXMsIENYLCBtYWluPSJDTFYgYnkgR3JvdXBzIikNCg0KYGBgDQo8YnI+PGhyPg0KDQojIyMgNi4g6Kit5a6a6KGM6Yq3562W55Wl44CB6KaP5YqD6KGM6Yq35bel5YW3DQoNCjxicj48aHI+DQoNCiMjIyA3LiDpgbjmk4fooYzpirflsI3osaENCg0K57Wm5a6a5p+Q5LiA6KGM6Yq35bel5YW355qE5oiQ5pys5ZKM6aCQ5pyf5pWI55uK77yM6YG45pOH5Y+v5Lul5pa96KGM6YCZ6aCF5bel5YW355qE5bCN6LGh44CCIA0KDQojIyMjIyA3LjEg5bCNUjLml4/nvqTpgLLooYzkv53nlZkNClIy5peP576k55qE6aCQ5ris5L+d55WZ546H5ZKM6LO86LK36YeR6aGNDQpgYGB7ciBmaWcuaGVpZ2h0PTIuNSwgZmlnLndpZHRoPTh9DQpwYXIobWZyb3c9YygxLDIpLCBtYXI9Yyg0LDMsMywyKSwgY2V4PTAuOCkNCmhpc3QoQ1gkUHJvYlJldGFpbltDWCRzdGF0dXM9PSJSMiJdLG1haW49IlByb2JSZXRhaW4iLHhsYWI9IiIpDQpoaXN0KGxvZyhDWCRQcmVkUmV2ZW51ZVtDWCRzdGF0dXM9PSJSMiJdLDEwKSxtYWluPSJQcmVkUmV2ZW51ZSIseGxhYj0iIikNCmBgYA0KDQpTM+aXj+e+pA0KYGBge3IgZmlnLmhlaWdodD0yLjUsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93PWMoMSwyKSwgbWFyPWMoNCwzLDMsMiksIGNleD0wLjgpDQpoaXN0KENYJFByb2JSZXRhaW5bQ1gkc3RhdHVzPT0iUzMiXSxtYWluPSJQcm9iUmV0YWluIix4bGFiPSIiKQ0KaGlzdChsb2coQ1gkUHJlZFJldmVudWVbQ1gkc3RhdHVzPT0iUzMiXSwxMCksbWFpbj0iUHJlZFJldmVudWUiLHhsYWI9IiIpDQpgYGANCg0KDQoNCiMjIyMjIDcuMiDkvLDoqIjpoJDmnJ/loLHphawNCg0K5Y+v5Lul5L6d5pOa5LmL5YmN5L2/55So6KGM6Yq35bel5YW355qE57aT6amX5L6G5o6o5Ye6ZWZmZWN05ZKMY29zdO+8jA0K6YCZ6KOh5YGH6Kit6KGM6Yq35bel5YW355qE5oiQ5pys5ZKM6aCQ5pyf5pWI55uK54K6DQpgYGB7cn0NCmNvc3QgPSAxMCAgICAgICAgIyDmiJDmnKwNCmVmZmVjdCA9IDAuNzUgICAgIyDmlYjnm4rvvJrkuIvkuIDmnJ/nmoTos7zosrfmqZ/njocNCmBgYA0KDQrkvLDoqIjpgJnpoIXooYzpirflt6XlhbflsI3mr4/kuIDkvY1SMumhp+WuoueahOmgkOacn+WgsemFrA0KYGBge3J9DQpUYXJnZXQgPSBzdWJzZXQoQ1gsIHN0YXR1cz09IlIyIikNClRhcmdldCRFeHBSZXR1cm4gPSAoZWZmZWN0IC0gVGFyZ2V0JFByb2JSZXRhaW4pICogVGFyZ2V0JFByZWRSZXZlbnVlIC0gY29zdA0Kc3VtbWFyeShUYXJnZXQkRXhwUmV0dXJuKQ0KYGBgDQrpgJnkuIDpoIXlt6XlhbflsI1SMumhp+WuoueahOmgkOacn+WgsemFrOaYr+iyoOeahA0KDQrpgJnpoIXlt6XlhbflsI3mlrxSZXRhaW7lpKfmlrwwLjc155qE5Lq65YW25a+m5rKS55Sa6bq855SoDQrku5blgJHnrpflh7rkvobnmoRFeHBSZXR1cm7mnIPmmK/osqDnmoQNCg0KIyMjIyMgNy4zIOmBuOaTh+ihjOmKt+WwjeixoQ0KDQrkvYbmmK/vvIzmiJHlgJHpgoTmmK/lj6/ku6XmjJHlh7roqLHlpJrpoJDmnJ/loLHphazlvojlpKfnmoTooYzpirflsI3osaENCmBgYHtyfQ0KVGFyZ2V0ICU+JSBhcnJhbmdlKGRlc2MoRXhwUmV0dXJuKSkgJT4lIHNlbGVjdChjaWQsIEV4cFJldHVybikgJT4lIGhlYWQoMTUpDQpgYGANCg0K5om+5Ye66aCQ5pyf5aCx5YSf54K65q2j55qE6aGn5a6iDQrlj6/ku6XlsI3ku5blgJHlr6bmlr3pgJnpoIXooYzpirflt6XlhbcNCg0KYGBge3J9DQpzdW0oVGFyZ2V0JEV4cFJldHVybiA+IDApICAgICAgICAgICAgICAgICAjIOWPr+WvpuaWveWwjeixoe+8mjI1OA0KYGBgDQrlnKhSMuS5i+S4re+8jOaciTI1OOS6uueahOmgkOacn+WgsemFrOWkp+aWvOmbtu+8jOWmguaenOWwjemAmTI1OOS6uuS9v+eUqOmAmemgheW3peWFt++8jOaIkeWAkeeahOacn+acm+WgsemFrOaYr++8mg0KYGBge3J9DQpzdW0oVGFyZ2V0JEV4cFJldHVybltUYXJnZXQkRXhwUmV0dXJuID4gMF0pICAgIyDpoJDmnJ/loLHphazvvJo2NDY0DQpgYGANCg0KIyMjIyMgUVVJWjoNCuaIkeWAkeWPr+S7peeul+WHuuWwjeaJgOacieeahOaXj+e+pOWvpuaWvemAmemgheW3peWFt+eahOacn+acm+WgsemFrCAuLi4NCmBgYHtyfQ0KVGFyZ2V0ID0gQ1gNClRhcmdldCRFeHBSZXR1cm4gPSAoZWZmZWN0IC0gVGFyZ2V0JFByb2JSZXRhaW4pICogVGFyZ2V0JFByZWRSZXZlbnVlIC0gY29zdA0KZmlsdGVyKFRhcmdldCwgVGFyZ2V0JEV4cFJldHVybiA+IDApICU+JQ0KICBncm91cF9ieShzdGF0dXMpICU+JSBzdW1tYXJpc2UoDQogICAgTm8uVGFyZ2V0ID0gbigpLA0KICAgIEF2Z1JPSSA9IG1lYW4oRXhwUmV0dXJuKSwNCiAgICBUb3RhbFJPSSA9IHN1bShFeHBSZXR1cm4pICkgJT4lIGRhdGEuZnJhbWUNCmBgYA0K6YCZ5YCL57WQ5p6c5piv5ZCI55CG55qE5ZeO77yfIOS9oOaDs+imgeaAjum6vOS/ruato+mAmemgheWIhuaekOeahOeoi+W6j+WRou+8nw0KDQorIOWboOeCuuavj+WAi+e+pOeul+WHuuS+hueahHByb2JSZXRhaW7kuI3kuIDmqKPvvIzogIzkuJTlkIzkuIDlpZfooYzpirflt6Xlhbfmh4nnlKjliLDkuI3lkIzml4/nvqTnmoTpoaflrqLnlKLnlJ/lh7rkvobnmoRjb3N05ZKMZWZmZWN05Lmf5LiN5LiA5qij77yM5omA5Lul54Sh5rOV55u05o6l55So55u45ZCM55qE566X5rOV5aWX6YGL5Yiw5omA5pyJ5peP576k44CCDQorDQoNCjxicj48YnI+PGhyPg0KDQojIyMgOC4g57WQ6KuWDQoNCuWmguaenOS9oOWPquaciemhp+WuoklE44CB5Lqk5piT5pel5pyf44CB5Lqk5piT6YeR6aGN5LiJ5YCL5qyE5L2N55qE6Kmx77yM5L2g5Y+v5Lul5YGa55qE5YiG5p6Q5YyF5ous77yaDQoNCisg5YWo6auU6aGn5a6i5ZKM5q+P5LiA5YCL6aGn5a6i5YiG576k55qE77yaDQogICAgKyDml4/nvqTlpKflsI/oiIfmiJDplbfotqjli6INCiAgICArIOaXj+e+pOWxrOaAp+WIhuaekO+8muWmguW5s+Wdh0NMVuOAgeW5s+Wdh+eHn+aUtuiyoueNu+OAgeaIkOmVt+eOh+OAgeavm+WIqeeOhyjpnIDopoHmnInmiJDmnKzos4fmlpkp562J562JDQogICAgKyDntYTplpPmtYHph4/lkozlubPlnYfmtYHli5XmqZ/njocNCg0KKyDmr4/kuIDlgIvpoaflrqLnmoTvvJoNCiAgICArIOS/neeVmeeOh+OAgemgkOacn+izvOiyt+mHkemhjeOAgee1gui6q+WDueWAvA0KICAgICsg55uu5YmN5omA5Zyo576k57WE77yM5Lul5Y+K5LiL5LiA5pyf5pyD6L2J5Yiw5YCL576k57WE55qE5qmf546HDQogICAgKyDlpoLmnpzmnInooYzpirflt6XlhbfnmoTkvb/nlKjntIDpjITnmoToqbHvvIzmiJHlgJHkuZ/lj6/ku6XkvLDoqIjmr4/kuIDmqKPooYzpirflt6XlhbfjgIHlsI3mr4/kuIDkvY3poaflrqLnmoTmiJDlip/mqZ/njocNCg0K5LiA6Iis6ICM6KiA77yM6YCZ5LiA5Lqb5YiG5p6Q55qE57WQ5p6c77yM6Laz5aSg6K6T5oiR5YCR5Yi25a6a6aGn5a6i55m85bGV5ZKM6aGn5a6i5L+d55WZ562W55Wl77yb6Iez5pa86aGn5a6i5ZC45pS2562W55Wl77yM5oiR5YCR6YCa5bi46YKE6ZyA6KaB5b6eQ1JN5pKI5Ye66aGn5a6i5YCL5Lq65bGs5oCn6LOH5paZ5omN6IO95YGa5Yiw44CCIA0KDQoNCjxicj48YnI+PGhyPjxicj48YnI+PGJyPg0KDQo8c3R5bGU+DQouY2FwdGlvbiB7DQogIGNvbG9yOiAjNzc3Ow0KICBtYXJnaW4tdG9wOiAxMHB4Ow0KfQ0KcCBjb2RlIHsNCiAgd2hpdGUtc3BhY2U6IGluaGVyaXQ7DQp9DQpwcmUgew0KICB3b3JkLWJyZWFrOiBub3JtYWw7DQogIHdvcmQtd3JhcDogbm9ybWFsOw0KICBsaW5lLWhlaWdodDogMTsNCn0NCnByZSBjb2RlIHsNCiAgd2hpdGUtc3BhY2U6IGluaGVyaXQ7DQp9DQpwLGxpIHsNCiAgZm9udC1mYW1pbHk6ICJUcmVidWNoZXQgTVMiLCAi5b6u6Luf5q2j6buR6auUIiwgIk1pY3Jvc29mdCBKaGVuZ0hlaSI7DQp9DQoNCi5yew0KICBsaW5lLWhlaWdodDogMS4yOw0KfQ0KDQp0aXRsZXsNCiAgY29sb3I6ICNjYzAwMDA7DQogIGZvbnQtZmFtaWx5OiAiVHJlYnVjaGV0IE1TIiwgIuW+rui7n+ato+m7kemrlCIsICJNaWNyb3NvZnQgSmhlbmdIZWkiOw0KfQ0KDQpib2R5ew0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KaDEsaDIsaDMsaDQsaDV7DQogIGNvbG9yOiAjMDA4ODAwOw0KICBmb250LWZhbWlseTogIlRyZWJ1Y2hldCBNUyIsICLlvq7ou5/mraPpu5Hpq5QiLCAiTWljcm9zb2Z0IEpoZW5nSGVpIjsNCn0NCg0KaDN7DQogIGNvbG9yOiAjMDA4ODAwOw0KICBiYWNrZ3JvdW5kOiAjZTZmZmU2Ow0KICBsaW5lLWhlaWdodDogMjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQp9DQoNCmg1ew0KICBjb2xvcjogIzAwNjAwMDsNCiAgYmFja2dyb3VuZDogI2Y4ZjhmODsNCiAgbGluZS1oZWlnaHQ6IDEuNTsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQp9DQoNCmVtew0KICBjb2xvcjogIzAwMDBjMDsNCiAgYmFja2dyb3VuZDogI2YwZjBmMDsNCiAgfQ0KPC9zdHlsZT4NCg0K