
Motivations
Dear M,
Econometrics là môn học quan trọng (ít nhất là cho những ai định
hướng theo đuổi bậc học sau đại học). Đối với hầu hết sinh viên, kể cả
theo học ngành kinh tế, thì đây vẫn được coi là môn học khó. Textbook về
môn học này thì nhiều. Ở Việt Nam có thể dễ dàng tìm được những
textbooks nổi tiếng (chỉ nêu tên một số sách) của Gurajati,
Woodbridge,
Green,
và Hill.
Trong số các textbooks này thì cuốn của Green dành cho bậc sau đại
học nên nặng về phần toán. Sách của Gurajati và Woodbridge dành cho bậc
đại học (Undergraduate) nhưng rất dày (đều trên 900 trang) và còn cả
những mảng chuyên sâu về Panel Data và Time Series - những phần thường
không được lựa chọn để giảng dạy môn học này cho bậc đại học khối ngành
kinh tế ở hầu hết các đại học Việt Nam. Do vậy cuốn sách của Hill (chỉ
380 trang) tỏ ra là phù hợp hơn cả: không quá dài, trực quan dễ hình
dung, và còn giải thích chi tiết cái gốc Thống Kê của môn học này.
Post này được viết để bạn có thể sử dụng textbook này một cách nhanh
chóng.
Graph Section
Trước hết bạn nên load toàn bộ data của textbook này tại đây.
Graph là một phần quan trọng của môn học này. Chúng ta có thể tái lập
lại Figure 3.6 được trình bày tại trang 51 của giáo trình này với ngôn
ngữ R như sau:
# Clear R our environment:
rm(list = ls())
# Load data (from http://www.econometrics.com/comdata/hill/data.html):
read.table("http://www.econometrics.com/comdata/hill/TAB3-1.shd", header = TRUE) -> exp_income_data
# Load some R packages:
library(dplyr) # For data processing.
library(ggplot2) # For data visualization.
# Replicate figure 3.6 (page 51):
exp_income_data %>%
ggplot(aes(x = x, y = y)) +
geom_point() +
labs(x = "Income", y = "Expenditure",
title = "Figure 3.6: Expenditure-Income Relationship",
subtitle = "Note: Replicate graph created by Hill et all. (2001)",
caption = "Source: http://principlesofeconometrics.com/ue2/ue2.htm")

Econometric Model
Giả sử chúng ta đề xuất mô hình kinh tế lượng dưới đây nhằm đánh giá
mối quan hệ giữa thu nhập và chi tiêu:
\[Expenditure_i = \beta_0 + \beta_1
Income_{i} + u_i \ , \ i=1,\dots,n.\] Dưới đây là R codes ước
lượng các hệ số hồi quy của mô hình trên:
# Estimate coefficients:
lm(data = exp_income_data, y ~ x) -> ols_model
# Present results:
library(stargazer)
stargazer(ols_model,
title = "Table 3.6: Regression Results",
type = "text",
align = TRUE)
##
## Table 3.6: Regression Results
## ===============================================
## Dependent variable:
## ---------------------------
## y
## -----------------------------------------------
## x 0.128***
## (0.031)
##
## Constant 40.768*
## (22.139)
##
## -----------------------------------------------
## Observations 40
## R2 0.317
## Adjusted R2 0.299
## Residual Std. Error 37.805 (df = 38)
## F Statistic 17.647*** (df = 1; 38)
## ===============================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Đây chính là kết quả được trình bày trong textbook bằng phần mềm SAS
tại trang 57.
Đương nhiên chúng ta có thể bổ sung thêm cả Regression Line màu đỏ
với khoảng tin cậy 95% như sau:
# Add regression line:
exp_income_data %>%
ggplot(aes(x = x, y = y)) +
geom_point() +
geom_smooth(method = "lm", color = "red") +
labs(x = "Income", y = "Expenditure",
title = "Figure 3.6: Expenditure-Income Relationship",
subtitle = "Note: Replicate graph created by Hill et all. (2001)",
caption = "Source: http://principlesofeconometrics.com/ue2/ue2.htm")

Basic Econometrics
Đây cũng là một textbook nhập môn rất hay (và rất dày) của Gujarati.
Sách này có thể download tại
đây. Data của textbook có thể download tại
đây. Theo truyền thống tì textbook này sử dụng phần mềm Eviews (với
các file dữ liệu có đuôi là .wf1). Dưới đây là một bộ số liệu được trình
bày ở trang 24:

Load bộ dữ liệu Eviews này vào R:
# Load hexView packege for importing Eviews files:
library(hexView)
# Load data:
readEViews("table1-1.wf1") -> table1_1_p24
# Show some observations:
head(table1_1_p24)
## Date Y1 Y2 Y3 Y4 GROUP01 TABLE01
## 1 0001-01-01 2206.0 2186.0 92.7 91.4 1.807873e-308 6.953356e-309
## 2 0002-01-01 0.7 0.7 151.0 149.0 3.013522e-315 0.000000e+00
## 3 0003-01-01 73.0 74.0 61.0 56.0 2.215260e+214 1.244442e-309
## 4 0004-01-01 3620.0 3737.0 86.3 91.8 8.165349e+141 3.204296e-306
## 5 0005-01-01 7472.0 7444.0 63.4 58.4 9.780788e+24 2.758637e-312
## 6 0006-01-01 788.0 873.0 77.8 73.0 3.068373e+257 0.000000e+00
Giáo trình này còn cung cấp dữ liệu ở dạng .txt. Chúng ta cũng có thể
load bộ dữ liệu trên ở định dạng này vào R như sau:
# Load data from .txt files:
read.table("Table 1.1.txt", header = TRUE, skip = 7) -> table1_1_p24_from_txt
# Show some observations:
head(table1_1_p24_from_txt)
## STATE Y1 Y2 X1 X2
## 1 AL 2206.0 2186.0 92.7 91.4
## 2 AK 0.7 0.7 151.0 149.0
## 3 AZ 73.0 74.0 61.0 56.0
## 4 AR 3620.0 3737.0 86.3 91.8
## 5 CA 7472.0 7444.0 63.4 58.4
## 6 CO 788.0 873.0 77.8 73.0
Cách khác là chúng ta load bất kì bộ số liệu nào
(được giáo trình này sử dụng) từ package gujarati. Trước hết
cài đặt package này như sau:
# Install remotes package for using install_github() command:
install.packages("remotes")
# Install gujarati package:
remotes::install_github("brunoruas2/gujarati")
Đến đây chúng ta có thể sử dụng bất bì bộ dữ liệu nào được nhắc đến
trong giáo trình này, ví dụ:
# Load gujarati package:
library(gujarati)
# Load data from gujatati package:
data("Table1_1")
# Show some observations:
head(Table1_1)
## STATE Y1 Y2 X1 X2
## 1 AL 2206 2186 92.7 91.4
## 2 AK 0.7 0.7 151 149
## 3 AZ 73 74 61 56
## 4 AR 3620 3737 86.3 91.8
## 5 CA 7472 7444 63.4 58.4
## 6 CO 788 873 77.8 73
Cái hay là những dữ liệu load từ package này có mô tả đầy đủ. R codes
để có thông tin về bộ dữ liệu như sau:

Dưới đây là Example 3.1 được trình bày tại trang 81:

Chúng ta có thể tái lập lại kết quả ở Example 3.1 như sau:
# Load data:
data("TableI_1")
Tác giả của gói gujarati có lẽ gặp lỗi nào đó khi viết package này
khiến cho những variables của bộ dữ liệu này đang là factor. Do vậy cần
convert về numeric cho phù hợp với bản chất của các biến:
TableI_1 %>%
mutate(PCE = as.numeric(as.character(PCE.Y.)),
GDP = as.numeric(as.character(GDP.X.)),
time = as.numeric(as.character(Year))) -> TableI_1
Với data đã được xử lí chúng ta có thể thực hiện ước lượng cho mô
hình và trình bày kết quả:
# Estimate coefficients:
lm(data = TableI_1, PCE ~ GDP) -> my_ols
# Present results:
stargazer(my_ols,
title = "Example 3.1 (Gujarati Textbook): Regression Results",
type = "text",
align = TRUE)
##
## Example 3.1 (Gujarati Textbook): Regression Results
## ===============================================
## Dependent variable:
## ---------------------------
## PCE
## -----------------------------------------------
## GDP 0.722***
## (0.004)
##
## Constant -299.591***
## (28.765)
##
## -----------------------------------------------
## Observations 46
## R2 0.998
## Adjusted R2 0.998
## Residual Std. Error 73.567 (df = 44)
## F Statistic 26,630.330*** (df = 1; 44)
## ===============================================
## Note: *p<0.1; **p<0.05; ***p<0.01
Hoặc trình bày kết quả theo một cách khác:
##
## Call:
## lm(formula = PCE ~ GDP, data = TableI_1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -151.094 -50.358 -6.161 37.199 165.532
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -2.996e+02 2.876e+01 -10.41 1.88e-13 ***
## GDP 7.218e-01 4.423e-03 163.19 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 73.57 on 44 degrees of freedom
## Multiple R-squared: 0.9984, Adjusted R-squared: 0.9983
## F-statistic: 2.663e+04 on 1 and 44 DF, p-value: < 2.2e-16
Final Notes
Sử dụng R cho mục đích khiêm tốn là giảng dạy Econometrics không quá
khó khăn như hình dung ban đầu. Lại có nhiều lợi thế khác. Chẳng hạn như
có thể tạo ra bài giảng, slide luôn.
LS0tDQp0aXRsZTogIlVuZGVyZ3JhZHVhdGUgRWNvbm9tZXRyaWNzIChSIFZlcnNpb24pIg0KYXV0aG9yOiAiQXV0aG9yOiBOZ3V5ZW4gQ2hpIER1bmciDQpzdWJ0aXRsZTogIkVjb25vbWV0cmljcyBTZXJpZXMiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgaGlnaGxpZ2h0OiB6ZW5idXJuDQogICAgdGhlbWU6IGZsYXRseQ0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgd29yZF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCi0tLQ0KDQpgYGB7ciBzZXR1cCxpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBUUlVFKQ0KDQpgYGANCg0KIVtdKGVjb25faGlsbC5qcGcpDQoNCiMgTW90aXZhdGlvbnMNCg0KRGVhciBNLCANCg0KRWNvbm9tZXRyaWNzIGzDoCBtw7RuIGjhu41jIHF1YW4gdHLhu41uZyAow610IG5o4bqldCBsw6AgY2hvIG5o4buvbmcgYWkgxJHhu4tuaCBoxrDhu5tuZyB0aGVvIMSRdeG7lWkgYuG6rWMgaOG7jWMgc2F1IMSR4bqhaSBo4buNYykuIMSQ4buRaSB24bubaSBo4bqndSBo4bq/dCBzaW5oIHZpw6puLCBr4buDIGPhuqMgdGhlbyBo4buNYyBuZ8Ogbmgga2luaCB04bq/LCB0aMOsIMSRw6J5IHbhuqtuIMSRxrDhu6NjIGNvaSBsw6AgbcO0biBo4buNYyBraMOzLiBUZXh0Ym9vayB24buBIG3DtG4gaOG7jWMgbsOgeSB0aMOsIG5oaeG7gXUuIOG7niBWaeG7h3QgTmFtIGPDsyB0aOG7gyBk4buFIGTDoG5nIHTDrG0gxJHGsOG7o2Mgbmjhu69uZyB0ZXh0Ym9va3MgbuG7lWkgdGnhur9uZyAoY2jhu4kgbsOqdSB0w6puIG3hu5l0IHPhu5Egc8OhY2gpIGPhu6dhIFtHdXJhamF0aV0oaHR0cHM6Ly93d3cuYW1hem9uLmNvbS9CYXNpYy1FY29ub21ldHJpY3MtRGFtb2Rhci1OLUd1amFyYXRpL2RwLzAwNzMzNzU3NzIpLCBbV29vZGJyaWRnZV0oaHR0cHM6Ly93d3cuYW1hem9uLmNvbS9JbnRyb2R1Y3RvcnktRWNvbm9tZXRyaWNzLU1vZGVybi1BcHByb2FjaC1NaW5kVGFwL2RwLzEzMzc1NTg4NjkvcmVmPXNyXzFfMT9jcmlkPTFCRDMwSFBFTU8zODcma2V5d29yZHM9SW50cm9kdWN0b3J5K0Vjb25vbWV0cmljcyUzQStBK01vZGVybitBcHByb2FjaCZxaWQ9MTY3ODMzNjM1OSZzPWJvb2tzJnNwcmVmaXg9aW50cm9kdWN0b3J5K2Vjb25vbWV0cmljcythK21vZGVybithcHByb2FjaCUyQ3N0cmlwYm9va3MtaW50bC1zaGlwJTJDMjkzJnNyPTEtMSksIFtHcmVlbl0oaHR0cHM6Ly93d3cuYW1hem9uLmNvbS9FY29ub21ldHJpYy1BbmFseXNpcy1HcmVlbmUvZHAvOTM1MzA2MTA3NS9yZWY9c3JfMV8xP2NyaWQ9VkFHNzE2MTcyMFlUJmtleXdvcmRzPUdyZWVuK2Vjb25vbWV0cmljcyZxaWQ9MTY3ODMzNjQxNyZzPWJvb2tzJnNwcmVmaXg9Z3JlZW4rZWNvbm9tZXRyaWNzJTJDc3RyaXBib29rcy1pbnRsLXNoaXAlMkMyOTUmc3I9MS0xKSwgdsOgIFtIaWxsXShodHRwczovL3d3dy5hbWF6b24uY29tL1VuZGVyZ3JhZHVhdGUtRWNvbm9tZXRyaWNzLVItQ2FydGVyLUhpbGwvZHAvMDQ3MTMzMTg0OC9yZWY9c3JfMV8xP2NyaWQ9MldLNlZFRVlUTDY5WCZrZXl3b3Jkcz1oaWxsK3VuZGVyZ3JhZHVhdGUrZWNvbm9tZXRyaWNzJnFpZD0xNjc4MzM2NTA3JnM9Ym9va3Mmc3ByZWZpeD1oaWxsK3VuZGVyZ3JhZHVhdGUrZWNvbm9tZXRyaWNzJTJDc3RyaXBib29rcy1pbnRsLXNoaXAlMkMzNDgmc3I9MS0xKS4gDQoNCg0KVHJvbmcgc+G7kSBjw6FjIHRleHRib29rcyBuw6B5IHRow6wgY3Xhu5FuIGPhu6dhIEdyZWVuIGTDoG5oIGNobyBi4bqtYyBzYXUgxJHhuqFpIGjhu41jIG7Dqm4gbuG6t25nIHbhu4EgcGjhuqduIHRvw6FuLiBTw6FjaCBj4bunYSBHdXJhamF0aSB2w6AgV29vZGJyaWRnZSBkw6BuaCBjaG8gYuG6rWMgxJHhuqFpIGjhu41jIChVbmRlcmdyYWR1YXRlKSBuaMawbmcgcuG6pXQgZMOgeSAoxJHhu4F1IHRyw6puIDkwMCB0cmFuZykgdsOgIGPDsm4gY+G6oyBuaOG7r25nIG3huqNuZyBjaHV5w6puIHPDonUgduG7gSBQYW5lbCBEYXRhIHbDoCBUaW1lIFNlcmllcyAtIG5o4buvbmcgcGjhuqduIHRoxrDhu51uZyBraMO0bmcgxJHGsOG7o2MgbOG7sWEgY2jhu41uIMSR4buDIGdp4bqjbmcgZOG6oXkgbcO0biBo4buNYyBuw6B5IGNobyBi4bqtYyDEkeG6oWkgaOG7jWMga2jhu5FpIG5nw6BuaCBraW5oIHThur8g4bufIGjhuqd1IGjhur90IGPDoWMgxJHhuqFpIGjhu41jIFZp4buHdCBOYW0uIERvIHbhuq15IGN14buRbiBzw6FjaCBj4bunYSBIaWxsIChjaOG7iSAzODAgdHJhbmcpIHThu48gcmEgbMOgIHBow7kgaOG7o3AgaMahbiBj4bqjOiBraMO0bmcgcXXDoSBkw6BpLCB0cuG7sWMgcXVhbiBk4buFIGjDrG5oIGR1bmcsIHbDoCBjw7JuIGdp4bqjaSB0aMOtY2ggY2hpIHRp4bq/dCBjw6FpIGfhu5FjIFRo4buRbmcgS8OqIGPhu6dhIG3DtG4gaOG7jWMgbsOgeS4gDQoNClBvc3QgbsOgeSDEkcaw4bujYyB2aeG6v3QgxJHhu4MgYuG6oW4gY8OzIHRo4buDIHPhu60gZOG7pW5nIHRleHRib29rIG7DoHkgbeG7mXQgY8OhY2ggbmhhbmggY2jDs25nLiANCg0KDQojIEdyYXBoIFNlY3Rpb24NCg0KVHLGsOG7m2MgaOG6v3QgYuG6oW4gbsOqbiBsb2FkIHRvw6BuIGLhu5kgZGF0YSBj4bunYSB0ZXh0Ym9vayBuw6B5IFt04bqhaSDEkcOieV0oaHR0cDovL3ByaW5jaXBsZXNvZmVjb25vbWV0cmljcy5jb20vdWUyL3VlMi5odG0pLiBHcmFwaCBsw6AgbeG7mXQgcGjhuqduIHF1YW4gdHLhu41uZyBj4bunYSBtw7RuIGjhu41jIG7DoHkuIENow7puZyB0YSBjw7MgdGjhu4MgdMOhaSBs4bqtcCBs4bqhaSBGaWd1cmUgMy42IMSRxrDhu6NjIHRyw6xuaCBiw6B5IHThuqFpIHRyYW5nIDUxIGPhu6dhIGdpw6FvIHRyw6xuaCBuw6B5IHbhu5tpIG5nw7RuIG5n4buvIFIgbmjGsCBzYXU6IA0KDQoNCmBgYHtyfQ0KDQojIENsZWFyIFIgb3VyIGVudmlyb25tZW50OiANCg0Kcm0obGlzdCA9IGxzKCkpDQoNCiMgTG9hZCBkYXRhIChmcm9tIGh0dHA6Ly93d3cuZWNvbm9tZXRyaWNzLmNvbS9jb21kYXRhL2hpbGwvZGF0YS5odG1sKTogDQoNCnJlYWQudGFibGUoImh0dHA6Ly93d3cuZWNvbm9tZXRyaWNzLmNvbS9jb21kYXRhL2hpbGwvVEFCMy0xLnNoZCIsIGhlYWRlciA9IFRSVUUpIC0+IGV4cF9pbmNvbWVfZGF0YQ0KDQojIExvYWQgc29tZSBSIHBhY2thZ2VzOiANCg0KbGlicmFyeShkcGx5cikgIyBGb3IgZGF0YSBwcm9jZXNzaW5nLiANCmxpYnJhcnkoZ2dwbG90MikgIyBGb3IgZGF0YSB2aXN1YWxpemF0aW9uLiANCg0KIyBSZXBsaWNhdGUgZmlndXJlIDMuNiAocGFnZSA1MSk6IA0KDQpleHBfaW5jb21lX2RhdGEgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSB4LCB5ID0geSkpICsgDQogIGdlb21fcG9pbnQoKSArIA0KICBsYWJzKHggPSAiSW5jb21lIiwgeSA9ICJFeHBlbmRpdHVyZSIsIA0KICAgICAgIHRpdGxlID0gIkZpZ3VyZSAzLjY6IEV4cGVuZGl0dXJlLUluY29tZSBSZWxhdGlvbnNoaXAiLCANCiAgICAgICBzdWJ0aXRsZSA9ICJOb3RlOiBSZXBsaWNhdGUgZ3JhcGggY3JlYXRlZCBieSBIaWxsIGV0IGFsbC4gKDIwMDEpIiwgDQogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IGh0dHA6Ly9wcmluY2lwbGVzb2ZlY29ub21ldHJpY3MuY29tL3VlMi91ZTIuaHRtIikNCg0KYGBgDQoNCiMgRWNvbm9tZXRyaWMgTW9kZWwNCg0KR2nhuqMgc+G7rSBjaMO6bmcgdGEgxJHhu4EgeHXhuqV0IG3DtCBow6xuaCBraW5oIHThur8gbMaw4bujbmcgZMaw4bubaSDEkcOieSBuaOG6sW0gxJHDoW5oIGdpw6EgbeG7kWkgcXVhbiBo4buHIGdp4buvYSB0aHUgbmjhuq1wIHbDoCBjaGkgdGnDqnU6IA0KDQoNCiQkRXhwZW5kaXR1cmVfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIEluY29tZV97aX0gKyB1X2kgXCAsIFwgaT0xLFxkb3RzLG4uJCQNCkTGsOG7m2kgxJHDonkgbMOgIFIgY29kZXMgxrDhu5tjIGzGsOG7o25nIGPDoWMgaOG7hyBz4buRIGjhu5NpIHF1eSBj4bunYSBtw7QgaMOsbmggdHLDqm46DQoNCg0KYGBge3J9DQojIEVzdGltYXRlIGNvZWZmaWNpZW50czogDQoNCmxtKGRhdGEgPSBleHBfaW5jb21lX2RhdGEsIHkgfiB4KSAtPiBvbHNfbW9kZWwNCg0KIyBQcmVzZW50IHJlc3VsdHM6IA0KDQpsaWJyYXJ5KHN0YXJnYXplcikNCg0Kc3RhcmdhemVyKG9sc19tb2RlbCwgIA0KICAgICAgICAgIHRpdGxlID0gIlRhYmxlIDMuNjogUmVncmVzc2lvbiBSZXN1bHRzIiwNCiAgICAgICAgICB0eXBlID0gInRleHQiLCANCiAgICAgICAgICBhbGlnbiA9IFRSVUUpDQpgYGANCg0KxJDDonkgY2jDrW5oIGzDoCBr4bq/dCBxdeG6oyDEkcaw4bujYyB0csOsbmggYsOgeSB0cm9uZyB0ZXh0Ym9vayBi4bqxbmcgcGjhuqduIG3hu4FtIFNBUyB04bqhaSB0cmFuZyA1Ny4gDQoNCsSQxrDGoW5nIG5oacOqbiBjaMO6bmcgdGEgY8OzIHRo4buDIGLhu5Ugc3VuZyB0aMOqbSBj4bqjIFJlZ3Jlc3Npb24gTGluZSBtw6B1IMSR4buPIHbhu5tpIGtob+G6o25nIHRpbiBj4bqteSA5NSUgbmjGsCBzYXU6IA0KDQpgYGB7cn0NCiMgQWRkIHJlZ3Jlc3Npb24gbGluZTogDQoNCmV4cF9pbmNvbWVfZGF0YSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHgsIHkgPSB5KSkgKyANCiAgZ2VvbV9wb2ludCgpICsgDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gInJlZCIpICsgDQogIGxhYnMoeCA9ICJJbmNvbWUiLCB5ID0gIkV4cGVuZGl0dXJlIiwgDQogICAgICAgdGl0bGUgPSAiRmlndXJlIDMuNjogRXhwZW5kaXR1cmUtSW5jb21lIFJlbGF0aW9uc2hpcCIsIA0KICAgICAgIHN1YnRpdGxlID0gIk5vdGU6IFJlcGxpY2F0ZSBncmFwaCBjcmVhdGVkIGJ5IEhpbGwgZXQgYWxsLiAoMjAwMSkiLCANCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogaHR0cDovL3ByaW5jaXBsZXNvZmVjb25vbWV0cmljcy5jb20vdWUyL3VlMi5odG0iKQ0KDQpgYGANCg0KIyBCYXNpYyBFY29ub21ldHJpY3MNCg0KxJDDonkgY8WpbmcgbMOgIG3hu5l0IHRleHRib29rIG5o4bqtcCBtw7RuIHLhuqV0IGhheSAodsOgIHLhuqV0IGTDoHkpIGPhu6dhIEd1amFyYXRpLiBTw6FjaCBuw6B5IGPDsyB0aOG7gyBkb3dubG9hZCBbdOG6oWkgxJHDonldKGh0dHBzOi8vd3d3LmNicGJ1LmFjLmluL3VzZXJmaWxlcy9maWxlLzIwMjAvU1RVRFlfTUFUL0VDTy8xLnBkZikuIERhdGEgY+G7p2EgdGV4dGJvb2sgY8OzIHRo4buDIGRvd25sb2FkIFt04bqhaSDEkcOieV0oaHR0cHM6Ly9oaWdoZXJlZC5taGVkdWNhdGlvbi5jb20vc2l0ZXMvMDA3MDY2MDA1MC9zdHVkZW50X3ZpZXcwL2RhdGFfc2V0cy5odG1sKS4gVGhlbyB0cnV54buBbiB0aOG7kW5nIHTDrCB0ZXh0Ym9vayBuw6B5IHPhu60gZOG7pW5nIHBo4bqnbiBt4buBbSBFdmlld3MgKHbhu5tpIGPDoWMgZmlsZSBk4buvIGxp4buHdSBjw7MgxJF1w7RpIGzDoCAud2YxKS4gRMaw4bubaSDEkcOieSBsw6AgbeG7mXQgYuG7mSBz4buRIGxp4buHdSDEkcaw4bujYyB0csOsbmggYsOgeSDhu58gdHJhbmcgMjQ6IA0KDQohW10odGFibGUxXzFfcDI0LmpwZykNCg0KTG9hZCBi4buZIGThu68gbGnhu4d1IEV2aWV3cyBuw6B5IHbDoG8gUjogDQoNCmBgYHtyfQ0KIyBMb2FkIGhleFZpZXcgcGFja2VnZSBmb3IgaW1wb3J0aW5nIEV2aWV3cyBmaWxlczogDQoNCmxpYnJhcnkoaGV4VmlldykNCg0KIyBMb2FkIGRhdGE6IA0KDQpyZWFkRVZpZXdzKCJ0YWJsZTEtMS53ZjEiKSAtPiB0YWJsZTFfMV9wMjQNCg0KIyBTaG93IHNvbWUgb2JzZXJ2YXRpb25zOiANCg0KaGVhZCh0YWJsZTFfMV9wMjQpDQoNCmBgYA0KDQpHacOhbyB0csOsbmggbsOgeSBjw7JuIGN1bmcgY+G6pXAgZOG7ryBsaeG7h3Ug4bufIGThuqFuZyAudHh0LiBDaMO6bmcgdGEgY8WpbmcgY8OzIHRo4buDIGxvYWQgYuG7mSBk4buvIGxp4buHdSB0csOqbiDhu58gxJHhu4tuaCBk4bqhbmcgbsOgeSB2w6BvIFIgbmjGsCBzYXU6IA0KDQpgYGB7cn0NCiMgTG9hZCBkYXRhIGZyb20gLnR4dCBmaWxlczogDQoNCnJlYWQudGFibGUoIlRhYmxlIDEuMS50eHQiLCBoZWFkZXIgPSBUUlVFLCBza2lwID0gNykgLT4gdGFibGUxXzFfcDI0X2Zyb21fdHh0DQoNCiMgU2hvdyBzb21lIG9ic2VydmF0aW9uczogDQoNCmhlYWQodGFibGUxXzFfcDI0X2Zyb21fdHh0KQ0KYGBgDQoNCkPDoWNoIGtow6FjIGzDoCBjaMO6bmcgdGEgbG9hZCAqKmLhuqV0IGvDrCoqIGLhu5kgc+G7kSBsaeG7h3UgbsOgbyAoxJHGsOG7o2MgZ2nDoW8gdHLDrG5oIG7DoHkgc+G7rSBk4bulbmcpIHThu6sgcGFja2FnZSAqZ3VqYXJhdGkqLiBUcsaw4bubYyBo4bq/dCBjw6BpIMSR4bq3dCBwYWNrYWdlIG7DoHkgbmjGsCBzYXU6IA0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiMgSW5zdGFsbCByZW1vdGVzIHBhY2thZ2UgZm9yIHVzaW5nIGluc3RhbGxfZ2l0aHViKCkgY29tbWFuZDogDQppbnN0YWxsLnBhY2thZ2VzKCJyZW1vdGVzIikNCg0KIyBJbnN0YWxsIGd1amFyYXRpIHBhY2thZ2U6IA0KcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoImJydW5vcnVhczIvZ3VqYXJhdGkiKQ0KYGBgDQoNCsSQ4bq/biDEkcOieSBjaMO6bmcgdGEgY8OzIHRo4buDIHPhu60gZOG7pW5nIGLhuqV0IGLDrCBi4buZIGThu68gbGnhu4d1IG7DoG8gxJHGsOG7o2Mgbmjhuq9jIMSR4bq/biB0cm9uZyBnacOhbyB0csOsbmggbsOgeSwgdsOtIGThu6U6DQoNCg0KYGBge3J9DQojIExvYWQgZ3VqYXJhdGkgcGFja2FnZTogDQoNCmxpYnJhcnkoZ3VqYXJhdGkpDQoNCiMgTG9hZCBkYXRhIGZyb20gZ3VqYXRhdGkgcGFja2FnZTogDQpkYXRhKCJUYWJsZTFfMSIpDQoNCiMgU2hvdyBzb21lIG9ic2VydmF0aW9uczogDQoNCmhlYWQoVGFibGUxXzEpDQoNCmBgYA0KDQpDw6FpIGhheSBsw6Agbmjhu69uZyBk4buvIGxp4buHdSBsb2FkIHThu6sgcGFja2FnZSBuw6B5IGPDsyBtw7QgdOG6oyDEkeG6p3kgxJHhu6cuIFIgY29kZXMgxJHhu4MgY8OzIHRow7RuZyB0aW4gduG7gSBi4buZIGThu68gbGnhu4d1IG5oxrAgc2F1OiANCg0KYGBge3J9DQo/VGFibGUxXzENCmBgYA0KDQohW10oZGVzLmpwZykNCg0KDQpExrDhu5tpIMSRw6J5IGzDoCBFeGFtcGxlIDMuMSDEkcaw4bujYyB0csOsbmggYsOgeSB04bqhaSB0cmFuZyA4MToNCg0KDQohW10oZXgzLjEuanBnKQ0KDQoNCg0KDQpDaMO6bmcgdGEgY8OzIHRo4buDIHTDoWkgbOG6rXAgbOG6oWkga+G6v3QgcXXhuqMg4bufIEV4YW1wbGUgMy4xIG5oxrAgc2F1OiANCg0KYGBge3J9DQojIExvYWQgZGF0YTogDQoNCmRhdGEoIlRhYmxlSV8xIikNCmBgYA0KDQpUw6FjIGdp4bqjIGPhu6dhIGfDs2kgZ3VqYXJhdGkgY8OzIGzhur0gZ+G6t3AgbOG7l2kgbsOgbyDEkcOzIGtoaSB2aeG6v3QgcGFja2FnZSBuw6B5IGtoaeG6v24gY2hvIG5o4buvbmcgdmFyaWFibGVzIGPhu6dhIGLhu5kgZOG7ryBsaeG7h3UgbsOgeSDEkWFuZyBsw6AgZmFjdG9yLiBEbyB24bqteSBj4bqnbiBjb252ZXJ0IHbhu4EgbnVtZXJpYyBjaG8gcGjDuSBo4bujcCB24bubaSBi4bqjbiBjaOG6pXQgY+G7p2EgY8OhYyBiaeG6v246IA0KDQpgYGB7cn0NClRhYmxlSV8xICU+JSANCiAgbXV0YXRlKFBDRSA9IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKFBDRS5ZLikpLCANCiAgICAgICAgIEdEUCA9IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKEdEUC5YLikpLCANCiAgICAgICAgIHRpbWUgPSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihZZWFyKSkpIC0+IFRhYmxlSV8xDQpgYGANCg0KVuG7m2kgZGF0YSDEkcOjIMSRxrDhu6NjIHjhu60gbMOtIGNow7puZyB0YSBjw7MgdGjhu4MgdGjhu7FjIGhp4buHbiDGsOG7m2MgbMaw4bujbmcgY2hvIG3DtCBow6xuaCB2w6AgdHLDrG5oIGLDoHkga+G6v3QgcXXhuqM6IA0KDQpgYGB7cn0NCiMgRXN0aW1hdGUgY29lZmZpY2llbnRzOiANCg0KbG0oZGF0YSA9IFRhYmxlSV8xLCBQQ0UgfiBHRFApIC0+IG15X29scw0KDQojIFByZXNlbnQgcmVzdWx0czogDQoNCnN0YXJnYXplcihteV9vbHMsICANCiAgICAgICAgICB0aXRsZSA9ICJFeGFtcGxlIDMuMSAoR3VqYXJhdGkgVGV4dGJvb2spOiBSZWdyZXNzaW9uIFJlc3VsdHMiLA0KICAgICAgICAgIHR5cGUgPSAidGV4dCIsIA0KICAgICAgICAgIGFsaWduID0gVFJVRSkNCg0KDQpgYGANCg0KSG/hurdjIHRyw6xuaCBiw6B5IGvhur90IHF14bqjIHRoZW8gbeG7mXQgY8OhY2gga2jDoWM6IA0KDQpgYGB7cn0NCnN1bW1hcnkobXlfb2xzKQ0KYGBgDQoNCg0KDQojIEZpbmFsIE5vdGVzDQoNClPhu60gZOG7pW5nIFIgY2hvIG3hu6VjIMSRw61jaCBraGnDqm0gdOG7kW4gbMOgIGdp4bqjbmcgZOG6oXkgRWNvbm9tZXRyaWNzIGtow7RuZyBxdcOhIGtow7Mga2jEg24gbmjGsCBow6xuaCBkdW5nIGJhbiDEkeG6p3UuIEzhuqFpIGPDsyBuaGnhu4F1IGzhu6NpIHRo4bq/IGtow6FjLiBDaOG6s25nIGjhuqFuIG5oxrAgY8OzIHRo4buDIHThuqFvIHJhIGLDoGkgZ2nhuqNuZywgc2xpZGUgbHXDtG4uIA0KDQoNCg0K