Tên: Mai Huy

MSSV: 43.01.104.065

Số thứ tự: 08

Câu a)

# Load thư viện ISLR chứa tập dữ liệu Weekly
library(ISLR)
#
summary(Weekly)
      Year           Lag1               Lag2               Lag3               Lag4               Lag5              Volume       
 Min.   :1990   Min.   :-18.1950   Min.   :-18.1950   Min.   :-18.1950   Min.   :-18.1950   Min.   :-18.1950   Min.   :0.08747  
 1st Qu.:1995   1st Qu.: -1.1540   1st Qu.: -1.1540   1st Qu.: -1.1580   1st Qu.: -1.1580   1st Qu.: -1.1660   1st Qu.:0.33202  
 Median :2000   Median :  0.2410   Median :  0.2410   Median :  0.2410   Median :  0.2380   Median :  0.2340   Median :1.00268  
 Mean   :2000   Mean   :  0.1506   Mean   :  0.1511   Mean   :  0.1472   Mean   :  0.1458   Mean   :  0.1399   Mean   :1.57462  
 3rd Qu.:2005   3rd Qu.:  1.4050   3rd Qu.:  1.4090   3rd Qu.:  1.4090   3rd Qu.:  1.4090   3rd Qu.:  1.4050   3rd Qu.:2.05373  
 Max.   :2010   Max.   : 12.0260   Max.   : 12.0260   Max.   : 12.0260   Max.   : 12.0260   Max.   : 12.0260   Max.   :9.32821  
     Today          Direction 
 Min.   :-18.1950   Down:484  
 1st Qu.: -1.1540   Up  :605  
 Median :  0.2410             
 Mean   :  0.1499             
 3rd Qu.:  1.4050             
 Max.   : 12.0260             

Hàm summary() cho biết thông tin về giá trị cao nhất, thấp nhất, giá trị trung bình, trung vị, giá trị ở khoảng 25, 75 % của các biến trong dữ liệu Weekly.

# Ma trận tương quan giữa các biến khi bỏ đi biến định tính Direction
cor(Weekly[, -9])
              Year         Lag1        Lag2        Lag3         Lag4         Lag5      Volume        Today
Year    1.00000000 -0.032289274 -0.03339001 -0.03000649 -0.031127923 -0.030519101  0.84194162 -0.032459894
Lag1   -0.03228927  1.000000000 -0.07485305  0.05863568 -0.071273876 -0.008183096 -0.06495131 -0.075031842
Lag2   -0.03339001 -0.074853051  1.00000000 -0.07572091  0.058381535 -0.072499482 -0.08551314  0.059166717
Lag3   -0.03000649  0.058635682 -0.07572091  1.00000000 -0.075395865  0.060657175 -0.06928771 -0.071243639
Lag4   -0.03112792 -0.071273876  0.05838153 -0.07539587  1.000000000 -0.075675027 -0.06107462 -0.007825873
Lag5   -0.03051910 -0.008183096 -0.07249948  0.06065717 -0.075675027  1.000000000 -0.05851741  0.011012698
Volume  0.84194162 -0.064951313 -0.08551314 -0.06928771 -0.061074617 -0.058517414  1.00000000 -0.033077783
Today  -0.03245989 -0.075031842  0.05916672 -0.07124364 -0.007825873  0.011012698 -0.03307778  1.000000000

Mối tương quan giữa các biến Tag và biến TOday gần bằng 0. Mối tương quan đáng kể duy nhất là giữa biến Year và volume.

# attach dùng để khiến cho những biến feature trong dữ liệu có sẵn trong Rstudio theo tên
attach(Weekly)
plot(Volume)

Chúng ta thấy rằng giá trị Volume tăng theo thời gian do mối tương quan giữa Year và Volume là khá lớn

Câu b)

Chúng ta sẽ fit mô hình logistic Regression để dự đoán biến đầu ra Direction và sử dụng các biến đầu vào là Lag1 -> Lag5 và Volume. Hàm glm() và đưa vào biến family =binomial dùng để chạy 1 mô hình Logistic Regression.

# Fit mô hình Logistic Regresion để dự đoán biến đầu ra Direction trong dữ liệu Weekly
fit.glm <- glm(Direction ~ Lag1 + Lag2 + Lag3 + Lag4 + Lag5 + Volume, data = Weekly, family = binomial)
# Hàm summary() sẽ cho chúng ta biết thông tin p-values, Z-value, độ lệch chuẩn cho những hệ số của các biến đầu vào
summary(fit.glm)

Call:
glm(formula = Direction ~ Lag1 + Lag2 + Lag3 + Lag4 + Lag5 + 
    Volume, family = binomial, data = Weekly)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-1.6949  -1.2565   0.9913   1.0849   1.4579  

Coefficients:
            Estimate Std. Error z value Pr(>|z|)   
(Intercept)  0.26686    0.08593   3.106   0.0019 **
Lag1        -0.04127    0.02641  -1.563   0.1181   
Lag2         0.05844    0.02686   2.175   0.0296 * 
Lag3        -0.01606    0.02666  -0.602   0.5469   
Lag4        -0.02779    0.02646  -1.050   0.2937   
Lag5        -0.01447    0.02638  -0.549   0.5833   
Volume      -0.02274    0.03690  -0.616   0.5377   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 1496.2  on 1088  degrees of freedom
Residual deviance: 1486.4  on 1082  degrees of freedom
AIC: 1500.4

Number of Fisher Scoring iterations: 4

Hàm summray cho biết thông tin về giá trị các hệ số của mô hình (B0->B6), thấy rằng Lag2 có hệ số nhỏ nhất = 0.0296, hệ số của Lag tương đối nhỏ vì thế có bằng chứng thống kê cho thấy rằng có mối quan hệ giữa Lag2 và biến đầu ra Direction.

Câu c)

# Có 1089 quan sát trong dữ liệu Weekly
dim(Weekly)
[1] 1089    9
# Hàm predict dùng để dự đoán xác suất xu hướng thị trường sẽ đi lên (Directtion = Up), type = "response" để xuất ra xác xuất theo dạng P(Y = 1|X)
probs <- predict(fit.glm, type = "response")
# Tạo một vecto gom 1089 thành phần down
pred.glm = rep ("Down", length(probs))
#Chuyển các thành phần sang Up khi xác suất lớn hơn 0.5
pred.glm[probs > 0.5] <- "Up"
# Dùng hàm table() để tạo ra một ma trận để quyết định xem có bao nhiêu quan sát được phân loại đúng, bao nhiêu bị phân loại sai
table(pred.glm, Direction)
        Direction
pred.glm Down  Up
    Down   54  48
    Up    430 557

Tỉ lệ số ngày dự đoán đúng = (54+557)/1089 = 0.56. Hàm logistic dự đoán đúng 56% số ngày, nói cách khác tỉ lệ dự đoán lỗi là khoảng 44%. Chúng ta cũng có thể nói rằng tính theo tuần, tỉ lệ dự đoán đúng thị trường đi lên là 557/(48+557) = 92%, tỉ lệ dự đoán đúng thị trường đi xuống là 54/(54+430) = 11.15%

Câu d)

#Vecto train gồm 1089 phần từ tương ướng với tập dữ liệu quan sát, dòng nào trong data có year <2009 sẽ trả về true, còn lại trả về false
train <- (Year < 2009)
# Tạo ra ma trận con của tập dữ liệu tương đương những giá trị từ năm 2009 đến 2010
Weekly.20092010 <- Weekly[!train, ]
# Bao gồm 104 số quan sát từ năm 2009 đến 2010
dim(Weekly.20092010)
[1] 104   9
# Tạo ra một vector gồm 104 giá trị Direction = Up hoặc Down từ năm 2009 đến 2010
Direction.20092010 <- Direction[!train]
# Thực hiện lại hồi qui logistic dựa trên tập huấn luyện (dữ liệu trước 2009) với subset =train (Year < 2009), chỉ bao gồm 1 giá trị đầu vào là Lag2
fit.glm2 <- glm(Direction ~ Lag2, data = Weekly, family = binomial, subset = train)
# Hàm predict dùng để dự đoán xác suất xu hướng thị trường sẽ đi lên (Directtion = Up), type = "response" để xuất ra xác xuất theo dạng P(Y = 1|X)
probs2 <- predict(fit.glm2, Weekly.20092010, type = "response")
# Tạo một vecto gom 104 thành phần down tương ứng với số quan sát từ năm 2009 đến 2010
pred.glm2 <- rep("Down", length(probs2))
#Chuyển các thành phần sang Up khi xác suất lớn hơn 0.5
pred.glm2[probs2 > 0.5] <- "Up"
# Dùng hàm table() để tạo ra một ma trận để quyết định xem có bao nhiêu quan sát được phân loại đúng, bao nhiêu bị phân loại sai
table(pred.glm2, Direction.20092010)
         Direction.20092010
pred.glm2 Down Up
     Down    9  5
     Up     34 56

Có 9 + 56 = 65 quan sát được phân loại đúng

Tỉ lệ số ngày dự đoán đúng = (9+56)/104 = 0.625, nói cách tỉ lệ dự đoán sai là 0.375

Câu e) Sử dụng LDA

# Load thư viện MASS
library(MASS)
# Phân tích khác biệt tuyến tính với chỉ có 1 biến đầu là lag2 trong tập dữ liệu trước năm 2009
fit.lda <- lda(Direction ~ Lag2, data = Weekly, subset = train)
# Thông tin khác biệt tuyến tính
fit.lda
Call:
lda(Direction ~ Lag2, data = Weekly, subset = train)

Prior probabilities of groups:
     Down        Up 
0.4477157 0.5522843 

Group means:
            Lag2
Down -0.03568254
Up    0.26036581

Coefficients of linear discriminants:
           LD1
Lag2 0.4414162

Kết quả hàm lda() chỉ ra rẳng 44.8% dữ liệu huấn luyện có direction: down

Đồng thời cho biết giá trị trung bình của mỗi nhóm biến đầu (Lag1 và Lag2) vào tương ứng với mỗi phân loại Down và Up

Hàm lda() cũng cung cấp hệ số phân biệt Lag2= 0.4414162, nếu 0.4414162 x Lag2 lớn thì LDA sẽ dự đoán phân loại thị trường tăng. Nếu nhỏ thì sẽ dự đoán thị trường giảm

# Hàm predict dùng để dự đoán xác suất xu hướng thị trường sẽ đi lên (Direction = Up) với tập data từ năm 2009 đến 2010
pred.lda <- predict(fit.lda, Weekly.20092010)
# Dùng hàm table() để tạo ra một ma trận để quyết định xem có bao nhiêu quan sát được phân loại đúng, bao nhiêu bị phân loại sai
table(pred.lda$class, Direction.20092010)
      Direction.20092010
       Down Up
  Down    9  5
  Up     34 56

Có 9 + 56 = 65 quan sát được phân loại đúng

Tỉ lệ số ngày dự đoán đúng = (9+56)/104 = 0.625, nói cách tỉ lệ dự đoán sai là 0.375. Kết quả đạt được rất giống với mô hình Logistic Regression.

Câu f) Sử dụng QDA

# Phân tích khác biệt bình phương với chỉ có 2 biến đầu vào Lag1 và lag2 trong tập dữ liệu trước năm 2009
fit.qda <- qda(Direction ~ Lag2, data = Weekly, subset = train)
# Thông tin khác biệt bình phương
fit.qda
Call:
qda(Direction ~ Lag2, data = Weekly, subset = train)

Prior probabilities of groups:
     Down        Up 
0.4477157 0.5522843 

Group means:
            Lag2
Down -0.03568254
Up    0.26036581
# Hàm predict dùng để dự đoán xác suất xu hướng thị trường sẽ đi lên (Direction = Up) với tập data từ năm 2009 đến 2010
pred.qda <- predict(fit.qda, Weekly.20092010)
# Dùng hàm table() để tạo ra một ma trận để quyết định xem có bao nhiêu quan sát được phân loại đúng, bao nhiêu bị phân loại sai
table(pred.qda$class, Direction.20092010)
      Direction.20092010
       Down Up
  Down    0  0
  Up     43 61

Có 0 + 61 = 61 quan sát được phân loại đúng

Tỉ lệ số ngày dự đoán đúng = (0+61)/104 = 0.5865, nói cách tỉ lệ dự đoán sai là 0.4134. Tỉ lệ dự đoán đúng thị trường tăng là 100 % và 0 % cho thị trường giảm. QDA đạt được độ chính xác 58.65% mặc dù mô hình dự đoán “Up” toàn bộ các dòng.

LS0tDQp0aXRsZTogIkLDoGkgdOG6rXAgMV9UdeG6p24gNSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMjIyBUw6puOiBNYWkgSHV5DQojIyMgTVNTVjogNDMuMDEuMTA0LjA2NQ0KIyMjIFPhu5EgdGjhu6kgdOG7sTogMDgNCg0KIyBDw6J1IGEpDQoNCmBgYHtyfQ0KIyBMb2FkIHRoxrAgdmnhu4duIElTTFIgY2jhu6lhIHThuq1wIGThu68gbGnhu4d1IFdlZWtseQ0KbGlicmFyeShJU0xSKQ0KIyBQaMOibiB0w61jaCB04buVbmcgcXVhbiB04bqtcCBk4buvIGxp4buHdSBXZWVrbHkNCnN1bW1hcnkoV2Vla2x5KQ0KYGBgDQoNCkjDoG0gc3VtbWFyeSgpIGNobyBiaeG6v3QgdGjDtG5nIHRpbiB24buBIGdpw6EgdHLhu4sgY2FvIG5o4bqldCwgdGjhuqVwIG5o4bqldCwgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCwgdHJ1bmcgduG7iywgZ2nDoSB0cuG7iyDhu58ga2hv4bqjbmcgMjUsIDc1ICUgY+G7p2EgY8OhYyBiaeG6v24gdHJvbmcgZOG7ryBsaeG7h3UgV2Vla2x5Lg0KDQpgYGB7cn0NCiMgTWEgdHLhuq1uIHTGsMahbmcgcXVhbiBnaeG7r2EgY8OhYyBiaeG6v24ga2hpIGLhu48gxJFpIGJp4bq/biDEkeG7i25oIHTDrW5oIERpcmVjdGlvbg0KY29yKFdlZWtseVssIC05XSkNCmBgYA0KDQpN4buRaSB0xrDGoW5nIHF1YW4gZ2nhu69hIGPDoWMgYmnhur9uIFRhZyB2w6AgYmnhur9uIFRPZGF5IGfhuqduIGLhurFuZyAwLiBN4buRaSB0xrDGoW5nIHF1YW4gxJHDoW5nIGvhu4MgZHV5IG5o4bqldCBsw6AgZ2nhu69hIGJp4bq/biBZZWFyIHbDoCB2b2x1bWUuDQoNCmBgYHtyfQ0KIyBhdHRhY2ggZMO5bmcgxJHhu4Mga2hp4bq/biBjaG8gbmjhu69uZyBiaeG6v24gZmVhdHVyZSB0cm9uZyBk4buvIGxp4buHdSBjw7Mgc+G6tW4gdHJvbmcgUnN0dWRpbyB0aGVvIHTDqm4NCmF0dGFjaChXZWVrbHkpDQpgYGANCg0KYGBge3J9DQojIEJp4buDdSDEkeG7kyBwaMOibiB0w6FuIGJp4bq/biB2b2x1bWUNCnBsb3QoVm9sdW1lKQ0KYGBgDQoNCkNow7puZyB0YSB0aOG6pXkgcuG6sW5nIGdpw6EgdHLhu4sgVm9sdW1lIHTEg25nIHRoZW8gdGjhu51pIGdpYW4gZG8gbeG7kWkgdMawxqFuZyBxdWFuIGdp4buvYSBZZWFyIHbDoCBWb2x1bWUgbMOgIGtow6EgbOG7m24NCg0KIyBDw6J1IGIpDQoNCkNow7puZyB0YSBz4bq9IGZpdCBtw7QgaMOsbmggbG9naXN0aWMgUmVncmVzc2lvbiDEkeG7gyBk4buxIMSRb8OhbiBiaeG6v24gxJHhuqd1IHJhIERpcmVjdGlvbiB2w6Agc+G7rSBk4bulbmcgY8OhYyBiaeG6v24gxJHhuqd1IHbDoG8gbMOgIExhZzEgLT4gTGFnNSB2w6AgVm9sdW1lLiBIw6BtIGdsbSgpIHbDoCDEkcawYSB2w6BvIGJp4bq/biBmYW1pbHkgPWJpbm9taWFsIGTDuW5nIMSR4buDIGNo4bqheSAxIG3DtCBow6xuaCBMb2dpc3RpYyBSZWdyZXNzaW9uLg0KDQpgYGB7cn0NCiMgRml0IG3DtCBow6xuaCBMb2dpc3RpYyBSZWdyZXNpb24gxJHhu4MgZOG7sSDEkW/DoW4gYmnhur9uIMSR4bqndSByYSBEaXJlY3Rpb24gdHJvbmcgZOG7ryBsaeG7h3UgV2Vla2x5DQpmaXQuZ2xtIDwtIGdsbShEaXJlY3Rpb24gfiBMYWcxICsgTGFnMiArIExhZzMgKyBMYWc0ICsgTGFnNSArIFZvbHVtZSwgZGF0YSA9IFdlZWtseSwgZmFtaWx5ID0gYmlub21pYWwpDQpgYGANCg0KDQpgYGB7cn0NCiMgSMOgbSBzdW1tYXJ5KCkgc+G6vSBjaG8gY2jDum5nIHRhIGJp4bq/dCB0aMO0bmcgdGluIHAtdmFsdWVzLCBaLXZhbHVlLCDEkeG7mSBs4buHY2ggY2h14bqpbiBjaG8gbmjhu69uZyBo4buHIHPhu5EgY+G7p2EgY8OhYyBiaeG6v24gxJHhuqd1IHbDoG8NCnN1bW1hcnkoZml0LmdsbSkNCmBgYA0KDQpIw6BtIHN1bW1yYXkgY2hvIGJp4bq/dCB0aMO0bmcgdGluIHbhu4EgZ2nDoSB0cuG7iyBjw6FjIGjhu4cgc+G7kSBj4bunYSBtw7QgaMOsbmggKEIwLT5CNiksIHRo4bqleSBy4bqxbmcgTGFnMiBjw7MgaOG7hyBz4buRIG5o4buPIG5o4bqldCA9IDAuMDI5NiwgaOG7hyBz4buRIGPhu6dhIExhZyB0xrDGoW5nIMSR4buRaSBuaOG7jyB2w6wgdGjhur8gY8OzIGLhurFuZyBjaOG7qW5nIHRo4buRbmcga8OqIGNobyB0aOG6pXkgcuG6sW5nIGPDsyBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIExhZzIgdsOgIGJp4bq/biDEkeG6p3UgcmEgRGlyZWN0aW9uLg0KDQojIEPDonUgYykNCg0KYGBge3J9DQojIEPDsyAxMDg5IHF1YW4gc8OhdCB0cm9uZyBk4buvIGxp4buHdSBXZWVrbHkNCmRpbShXZWVrbHkpDQojIEjDoG0gcHJlZGljdCBkw7luZyDEkeG7gyBk4buxIMSRb8OhbiB4w6FjIHN14bqldCB4dSBoxrDhu5tuZyB0aOG7iyB0csaw4budbmcgc+G6vSDEkWkgbMOqbiAoRGlyZWN0dGlvbiA9IFVwKSwgdHlwZSA9ICJyZXNwb25zZSIgxJHhu4MgeHXhuqV0IHJhIHjDoWMgeHXhuqV0IHRoZW8gZOG6oW5nIFAoWSA9IDF8WCkNCnByb2JzIDwtIHByZWRpY3QoZml0LmdsbSwgdHlwZSA9ICJyZXNwb25zZSIpDQojIFThuqFvIG3hu5l0IHZlY3RvIGdvbSAxMDg5IHRow6BuaCBwaOG6p24gZG93bg0KcHJlZC5nbG0gPSByZXAgKCJEb3duIiwgbGVuZ3RoKHByb2JzKSkNCiNDaHV54buDbiBjw6FjIHRow6BuaCBwaOG6p24gc2FuZyBVcCBraGkgeMOhYyBzdeG6pXQgbOG7m24gaMahbiAwLjUNCnByZWQuZ2xtW3Byb2JzID4gMC41XSA8LSAiVXAiDQpgYGANCg0KYGBge3J9DQojIETDuW5nIGjDoG0gdGFibGUoKSDEkeG7gyB04bqhbyByYSBt4buZdCBtYSB0cuG6rW4gxJHhu4MgcXV54bq/dCDEkeG7i25oIHhlbSBjw7MgYmFvIG5oacOqdSBxdWFuIHPDoXQgxJHGsOG7o2MgcGjDom4gbG/huqFpIMSRw7puZywgYmFvIG5oacOqdSBi4buLIHBow6JuIGxv4bqhaSBzYWkNCnRhYmxlKHByZWQuZ2xtLCBEaXJlY3Rpb24pDQpgYGANCg0KVOG7iSBs4buHIHPhu5EgbmfDoHkgZOG7sSDEkW/DoW4gxJHDum5nID0gKDU0KzU1NykvMTA4OSA9IDAuNTYuIEjDoG0gbG9naXN0aWMgZOG7sSDEkW/DoW4gxJHDum5nIDU2JSBz4buRIG5nw6B5LCBuw7NpIGPDoWNoIGtow6FjIHThu4kgbOG7hyBk4buxIMSRb8OhbiBs4buXaSBsw6Aga2hv4bqjbmcgNDQlLiBDaMO6bmcgdGEgY8WpbmcgY8OzIHRo4buDIG7Ds2kgcuG6sW5nIHTDrW5oIHRoZW8gdHXhuqduLCB04buJIGzhu4cgZOG7sSDEkW/DoW4gxJHDum5nIHRo4buLIHRyxrDhu51uZyDEkWkgbMOqbiBsw6AgNTU3Lyg0OCs1NTcpID0gOTIlLCB04buJIGzhu4cgZOG7sSDEkW/DoW4gxJHDum5nIHRo4buLIHRyxrDhu51uZyDEkWkgeHXhu5FuZyBsw6AgNTQvKDU0KzQzMCkgPSAgMTEuMTUlDQoNCiMgQ8OidSBkKQ0KDQpgYGB7cn0NCiNWZWN0byB0cmFpbiBn4buTbSAxMDg5IHBo4bqnbiB04burIHTGsMahbmcgxrDhu5tuZyB24bubaSB04bqtcCBk4buvIGxp4buHdSBxdWFuIHPDoXQsIGTDsm5nIG7DoG8gdHJvbmcgZGF0YSBjw7MgeWVhciA8MjAwOSBz4bq9IHRy4bqjIHbhu4EgdHJ1ZSwgY8OybiBs4bqhaSB0cuG6oyB24buBIGZhbHNlDQp0cmFpbiA8LSAoWWVhciA8IDIwMDkpDQpgYGANCg0KYGBge3J9DQojIFThuqFvIHJhIG1hIHRy4bqtbiBjb24gY+G7p2EgdOG6rXAgZOG7ryBsaeG7h3UgdMawxqFuZyDEkcawxqFuZyBuaOG7r25nIGdpw6EgdHLhu4sgdOG7qyBuxINtIDIwMDkgxJHhur9uIDIwMTANCldlZWtseS4yMDA5MjAxMCA8LSBXZWVrbHlbIXRyYWluLCBdDQpgYGANCg0KYGBge3J9DQojIEJhbyBn4buTbSAxMDQgc+G7kSBxdWFuIHPDoXQgdOG7qyBuxINtIDIwMDkgxJHhur9uIDIwMTANCmRpbShXZWVrbHkuMjAwOTIwMTApDQpgYGANCg0KDQpgYGB7cn0NCiMgVOG6oW8gcmEgbeG7mXQgdmVjdG9yIGfhu5NtIDEwNCBnacOhIHRy4buLIERpcmVjdGlvbiA9IFVwIGhv4bq3YyBEb3duIHThu6sgbsSDbSAyMDA5IMSR4bq/biAyMDEwDQpEaXJlY3Rpb24uMjAwOTIwMTAgPC0gRGlyZWN0aW9uWyF0cmFpbl0NCmBgYA0KDQoNCmBgYHtyfQ0KIyBUaOG7sWMgaGnhu4duIGzhuqFpIGjhu5NpIHF1aSBsb2dpc3RpYyBk4buxYSB0csOqbiB04bqtcCBodeG6pW4gbHV54buHbiAoZOG7ryBsaeG7h3UgdHLGsOG7m2MgMjAwOSkgduG7m2kgc3Vic2V0ID10cmFpbiAoWWVhciA8IDIwMDkpLCBjaOG7iSBiYW8gZ+G7k20gMSBnacOhIHRy4buLIMSR4bqndSB2w6BvIGzDoCBMYWcyDQpmaXQuZ2xtMiA8LSBnbG0oRGlyZWN0aW9uIH4gTGFnMiwgZGF0YSA9IFdlZWtseSwgZmFtaWx5ID0gYmlub21pYWwsIHN1YnNldCA9IHRyYWluKQ0KYGBgDQoNCg0KYGBge3J9DQojIEjDoG0gcHJlZGljdCBkw7luZyDEkeG7gyBk4buxIMSRb8OhbiB4w6FjIHN14bqldCB4dSBoxrDhu5tuZyB0aOG7iyB0csaw4budbmcgc+G6vSDEkWkgbMOqbiAoRGlyZWN0dGlvbiA9IFVwKSwgdHlwZSA9ICJyZXNwb25zZSIgxJHhu4MgeHXhuqV0IHJhIHjDoWMgeHXhuqV0IHRoZW8gZOG6oW5nIFAoWSA9IDF8WCkNCnByb2JzMiA8LSBwcmVkaWN0KGZpdC5nbG0yLCBXZWVrbHkuMjAwOTIwMTAsIHR5cGUgPSAicmVzcG9uc2UiKQ0KYGBgDQoNCg0KYGBge3J9DQojIFThuqFvIG3hu5l0IHZlY3RvIGdvbSAxMDQgdGjDoG5oIHBo4bqnbiBkb3duIHTGsMahbmcg4bupbmcgduG7m2kgc+G7kSBxdWFuIHPDoXQgdOG7qyBuxINtIDIwMDkgxJHhur9uIDIwMTANCnByZWQuZ2xtMiA8LSByZXAoIkRvd24iLCBsZW5ndGgocHJvYnMyKSkNCmBgYA0KDQoNCmBgYHtyfQ0KI0NodXnhu4NuIGPDoWMgdGjDoG5oIHBo4bqnbiBzYW5nIFVwIGtoaSB4w6FjIHN14bqldCBs4bubbiBoxqFuIDAuNQ0KcHJlZC5nbG0yW3Byb2JzMiA+IDAuNV0gPC0gIlVwIg0KYGBgDQoNCg0KYGBge3J9DQojIETDuW5nIGjDoG0gdGFibGUoKSDEkeG7gyB04bqhbyByYSBt4buZdCBtYSB0cuG6rW4gxJHhu4MgcXV54bq/dCDEkeG7i25oIHhlbSBjw7MgYmFvIG5oacOqdSBxdWFuIHPDoXQgxJHGsOG7o2MgcGjDom4gbG/huqFpIMSRw7puZywgYmFvIG5oacOqdSBi4buLIHBow6JuIGxv4bqhaSBzYWkNCnRhYmxlKHByZWQuZ2xtMiwgRGlyZWN0aW9uLjIwMDkyMDEwKQ0KYGBgDQoNCkPDsyA5ICsgNTYgPSA2NSBxdWFuIHPDoXQgxJHGsOG7o2MgcGjDom4gbG/huqFpIMSRw7puZw0KDQpU4buJIGzhu4cgc+G7kSBuZ8OgeSBk4buxIMSRb8OhbiDEkcO6bmcgPSAoOSs1NikvMTA0ID0gMC42MjUsIG7Ds2kgY8OhY2ggdOG7iSBs4buHIGThu7EgxJFvw6FuIHNhaSBsw6AgMC4zNzUNCg0KIyBDw6J1IGUpIFPhu60gZOG7pW5nIExEQQ0KDQpgYGB7cn0NCiMgTG9hZCB0aMawIHZp4buHbiBNQVNTDQpsaWJyYXJ5KE1BU1MpDQpgYGANCg0KYGBge3J9DQojIFBow6JuIHTDrWNoIGtow6FjIGJp4buHdCB0dXnhur9uIHTDrW5oIHbhu5tpIGNo4buJIGPDsyAxIGJp4bq/biDEkeG6p3UgbMOgIGxhZzIgdHJvbmcgdOG6rXAgZOG7ryBsaeG7h3UgdHLGsOG7m2MgbsSDbSAyMDA5DQpmaXQubGRhIDwtIGxkYShEaXJlY3Rpb24gfiBMYWcyLCBkYXRhID0gV2Vla2x5LCBzdWJzZXQgPSB0cmFpbikNCmBgYA0KDQoNCg0KYGBge3J9DQojIFRow7RuZyB0aW4ga2jDoWMgYmnhu4d0IHR1eeG6v24gdMOtbmgNCmZpdC5sZGENCmBgYA0KDQpL4bq/dCBxdeG6oyBow6BtIGxkYSgpIGNo4buJIHJhIHLhurNuZyA0NC44JSBk4buvIGxp4buHdSBodeG6pW4gbHV54buHbiBjw7MgZGlyZWN0aW9uOiBkb3duDQoNCsSQ4buTbmcgdGjhu51pIGNobyBiaeG6v3QgZ2nDoSB0cuG7iyB0cnVuZyBiw6xuaCBj4bunYSBt4buXaSBuaMOzbSBiaeG6v24gxJHhuqd1IChMYWcxIHbDoCBMYWcyKSB2w6BvIHTGsMahbmcg4bupbmcgduG7m2kgbeG7l2kgcGjDom4gbG/huqFpIERvd24gdsOgIFVwDQoNCkjDoG0gbGRhKCkgY8WpbmcgY3VuZyBj4bqlcCBo4buHIHPhu5EgcGjDom4gYmnhu4d0IExhZzI9IDAuNDQxNDE2MiwgbuG6v3UgMC40NDE0MTYyIHggTGFnMiBs4bubbiB0aMOsIExEQSBz4bq9IGThu7EgxJFvw6FuIHBow6JuIGxv4bqhaSB0aOG7iyB0csaw4budbmcgdMSDbmcuIE7hur91IG5o4buPIHRow6wgc+G6vSBk4buxIMSRb8OhbiB0aOG7iyB0csaw4budbmcgZ2nhuqNtDQoNCmBgYHtyfQ0KIyBIw6BtIHByZWRpY3QgZMO5bmcgxJHhu4MgZOG7sSDEkW/DoW4geMOhYyBzdeG6pXQgeHUgaMaw4bubbmcgdGjhu4sgdHLGsOG7nW5nIHPhur0gxJFpIGzDqm4gKERpcmVjdGlvbiA9IFVwKSB24bubaSB04bqtcCBkYXRhIHThu6sgbsSDbSAyMDA5IMSR4bq/biAyMDEwDQpwcmVkLmxkYSA8LSBwcmVkaWN0KGZpdC5sZGEsIFdlZWtseS4yMDA5MjAxMCkNCmBgYA0KDQpgYGB7cn0NCiMgRMO5bmcgaMOgbSB0YWJsZSgpIMSR4buDIHThuqFvIHJhIG3hu5l0IG1hIHRy4bqtbiDEkeG7gyBxdXnhur90IMSR4buLbmggeGVtIGPDsyBiYW8gbmhpw6p1IHF1YW4gc8OhdCDEkcaw4bujYyBwaMOibiBsb+G6oWkgxJHDum5nLCBiYW8gbmhpw6p1IGLhu4sgcGjDom4gbG/huqFpIHNhaQ0KdGFibGUocHJlZC5sZGEkY2xhc3MsIERpcmVjdGlvbi4yMDA5MjAxMCkNCmBgYA0KDQpDw7MgOSArIDU2ID0gNjUgcXVhbiBzw6F0IMSRxrDhu6NjIHBow6JuIGxv4bqhaSDEkcO6bmcNCg0KVOG7iSBs4buHIHPhu5EgbmfDoHkgZOG7sSDEkW/DoW4gxJHDum5nID0gKDkrNTYpLzEwNCA9IDAuNjI1LCBuw7NpIGPDoWNoIHThu4kgbOG7hyBk4buxIMSRb8OhbiBzYWkgbMOgIDAuMzc1LiBL4bq/dCBxdeG6oyDEkeG6oXQgxJHGsOG7o2MgcuG6pXQgZ2nhu5FuZyB24bubaSBtw7QgaMOsbmggTG9naXN0aWMgUmVncmVzc2lvbi4NCg0KIyBDw6J1IGYpIFPhu60gZOG7pW5nIFFEQQ0KDQpgYGB7cn0NCiMgUGjDom4gdMOtY2gga2jDoWMgYmnhu4d0IGLDrG5oIHBoxrDGoW5nIHbhu5tpIGNo4buJIGPDsyAyIGJp4bq/biDEkeG6p3UgdsOgbyBMYWcxIHbDoCBsYWcyIHRyb25nIHThuq1wIGThu68gbGnhu4d1IHRyxrDhu5tjIG7Eg20gMjAwOQ0KZml0LnFkYSA8LSBxZGEoRGlyZWN0aW9uIH4gTGFnMiwgZGF0YSA9IFdlZWtseSwgc3Vic2V0ID0gdHJhaW4pDQpgYGANCg0KYGBge3J9DQojIFRow7RuZyB0aW4ga2jDoWMgYmnhu4d0IGLDrG5oIHBoxrDGoW5nDQpmaXQucWRhDQpgYGANCg0KYGBge3J9DQojIEjDoG0gcHJlZGljdCBkw7luZyDEkeG7gyBk4buxIMSRb8OhbiB4w6FjIHN14bqldCB4dSBoxrDhu5tuZyB0aOG7iyB0csaw4budbmcgc+G6vSDEkWkgbMOqbiAoRGlyZWN0aW9uID0gVXApIHbhu5tpIHThuq1wIGRhdGEgdOG7qyBuxINtIDIwMDkgxJHhur9uIDIwMTANCnByZWQucWRhIDwtIHByZWRpY3QoZml0LnFkYSwgV2Vla2x5LjIwMDkyMDEwKQ0KYGBgDQoNCmBgYHtyfQ0KIyBEw7luZyBow6BtIHRhYmxlKCkgxJHhu4MgdOG6oW8gcmEgbeG7mXQgbWEgdHLhuq1uIMSR4buDIHF1eeG6v3QgxJHhu4tuaCB4ZW0gY8OzIGJhbyBuaGnDqnUgcXVhbiBzw6F0IMSRxrDhu6NjIHBow6JuIGxv4bqhaSDEkcO6bmcsIGJhbyBuaGnDqnUgYuG7iyBwaMOibiBsb+G6oWkgc2FpDQp0YWJsZShwcmVkLnFkYSRjbGFzcywgRGlyZWN0aW9uLjIwMDkyMDEwKQ0KYGBgDQoNCkPDsyAwICsgNjEgPSA2MSBxdWFuIHPDoXQgxJHGsOG7o2MgcGjDom4gbG/huqFpIMSRw7puZw0KDQpU4buJIGzhu4cgc+G7kSBuZ8OgeSBk4buxIMSRb8OhbiDEkcO6bmcgPSAoMCs2MSkvMTA0ID0gMC41ODY1LCBuw7NpIGPDoWNoIHThu4kgbOG7hyBk4buxIMSRb8OhbiBzYWkgbMOgIDAuNDEzNC4gVOG7iSBs4buHIGThu7EgxJFvw6FuIMSRw7puZyB0aOG7iyB0csaw4budbmcgdMSDbmcgbMOgIDEwMCAlIHbDoCAwICUgY2hvIHRo4buLIHRyxrDhu51uZyBnaeG6o20uIFFEQSDEkeG6oXQgxJHGsOG7o2MgxJHhu5kgY2jDrW5oIHjDoWMgNTguNjUlIG3hurdjIGTDuSBtw7QgaMOsbmggZOG7sSDEkW/DoW4gIlVwIiB0b8OgbiBi4buZIGPDoWMgZMOybmcuDQoNCg==