Portfolios with Three Risky Assets

Xét một danh mục đầu tư (Portfolio) gồm ba tài sản là A, B và C. Kí hiệu \(R_i\) (\(i = A, B, C\)) là lợi tức tương ứng của ba tài sản và giả định rằng các lợi tức là biến ngẫu nhiên (Random Variable) thỏa mãn:

\[R_{i}\sim N(\mu_i,\sigma_i^2)\]

Ngoài ra với \(i \ne j\) thì covariance của gặp tài sản bất kì \(i\)\(j\):

\[\mathrm{cov}\left(R_i, R_j \right) = \sigma_{ij}\]

Nếu tỉ trọng của ba tài sản này trong danh mục đầu tư là \(x_A\), \(x_B\)\(x_C\) (lưu ý rằng \(x_A + x_B + x_C = 1\)) thì lợi tức của danh mục, kí hiệu là \(R_p,_x\) cũng sẽ là một biến ngẫu nhiên:

\[\begin{equation} \tag{1} R_p = x_AR_A + x_BR_B + x_CR_C \end{equation}\]

Và lợi tức kì vọng của danh mục \(\mu_p,_x\), nếu kí hiệu \(\mu_A\), \(\mu_B\)\(\mu_C\) lần lượt là lợi tức kì vọng của ba tài sản A, B và C sẽ được tính theo công thức:

\[\begin{equation} \tag{2} \mu_p = E[R_p] = x_A\mu_A + x_B\mu_B + x_C\mu_C \end{equation}\]

Còn rủi ro của danh mục, kí hiệu là \(\sigma_p\) sẽ là:

\[\begin{equation} \tag{3} \sigma^2_p = \mathrm{var(R_p) = x^2_A\sigma^2_A + x^2_B\sigma^2_B + x^2_C\sigma^2_C + 2x_Ax_B\sigma_{AB} + 2x_Bx_C\sigma_{BC} + 2x_Ax_C\sigma_{AC}} \end{equation}\]

Các công thức được mô tả bằng các phương trình đại số ở trên bạn đọc có thể tìm thất ở bất kì cuốn sách nào về Investment và Portfolio Theory. Còn theo ngôn ngữ của ma trận và tính toán ma trận (Matrix Calculation) thì lợi tức của danh mục tính theo công thức (2) sẽ được biểu diễn là:

\[\mu_p = X\mu\]

Còn rủi ro của danh mục theo công thức (3), với chú ý rằng \(X'\) là ma trận chuyển vị của ma trận \(X\), sẽ là:

\[\sigma^2_p = X'\Sigma X\]

Trong đó \(X\), \(\mu\)\(\Sigma\) được định nghĩa và mô tả dưới đây:

  • \(\mu\) là ma trận lợi tức của ba tài sản A, B và C. Đây là ma trận có kích thước 3×1:

\[\mu = \begin{pmatrix} \mu_A \\ \mu_B \\ \mu_C \end{pmatrix}\]

  • \(X\) là ma trận tỉ trọng của ba tài sản A, B và C (kích thước 3×1):

\[X = \begin{pmatrix} x_A & x_B & x_C \end{pmatrix}\]

  • \(\Sigma\) là ma trận hiệp phương sai (Covariance Matrix) của ba tài sản trong danh mục đầu tư. Đây là một ma trận đối xứng (symmetric) kích thước 3×3 vì rằng \(\mathrm{cov}\left(R_i, R_j \right) = \mathrm{cov}\left(R_j, R_i \right)\):

\[\begin{equation*} \Sigma = \begin{pmatrix} \sigma^2_A & \sigma_{AB} & \sigma_{AC} \\ \sigma_{AB} & \sigma^2_B & \sigma_{BC} \\ \sigma_{AC} & \sigma_{BC} & \sigma^2_C \end{pmatrix} \end{equation*}\]

Những mục dưới đây chúng ta sẽ triển khai tính toán lợi tức - rủi ro của danh mục đầu tư và những bài toán cơ bản của Portfolio Theory bằng tính toán ma trận với ngôn ngữ R.

A Simple Example

Xét một danh mục đầu tư gồm ba cổ phiếu A, B và C với lợi tức (kí hiệu \(\mu_i\)), rủi ro (kí hiệu \(\sigma_i\)) và covariance theo từng cặp (kí hiệu \(\sigma_{ij}\)) được cho ở Table 1 dưới đây:

Table 1: A Real-world example data
Stock \(i\) \(\mu_i\) \(\sigma_i\) Pair \((i,j)\) \(\sigma_{ij}\)
A 0.0013128 0.0203511 (A,B) 0.0002519
B 0.0008900 0.0199235 (A,C) 0.0002366
C -0.0005860 0.0002720 (B,C) 0.0002720

Xét một danh mục đầu tư mà tỉ trọng của các tài sản A, B, C là như nhau (equally weighted portfolio). Dưới đây là R codes cho tính toán lợi tức và rủi ro của danh mục đầu tư này. Trước hết là nhập số liệu cho các ma trận \(X\), \(\mu\)\(\Sigma\) dựa trên Table 1:

Ma trận hiệp phương sai:

Table 2: Covariance matrix
A B C
A 0.0004142 0.0002519 0.0002366
B 0.0002519 0.0003969 0.0002720
C 0.0002366 0.0002720 0.0009598

Tính toán lợi tức và rủi ro cho danh mục đầu tư:

## [1] 0.0005389225
## [1] 0.01912497

Danh mục đầu tư này tuy lợi tức chỉ bằng 41% so với tài sản B nhưng rủi ro lại gần bằng. Một nhà đầu tư duy lí đương nhiên sẽ ưa thích đầu tư toàn bộ tài sản của mình vào B hơn là phân bổ đều vào ba tài sản. Do vậy mà trọng tâm của lí thuyết danh mục (Portfolio Theory) và lựa chọn danh mục đầu tư (Portfolio Selection) là trả lời câu hỏi kiểu như sau:

  1. Có hay không một sự kết hợp cụ thể nào đó của các tài sản mà cùng với mức lợi tức như tài sản A - tài sản có lợi tức cao nhất trong số ba tài sản nhưng có rủi ro thấp hơn?

  2. Có hay không một sự kết hợp cụ thể nào đó của các tài sản mà cùng với mức lợi tức như tài sản B nhưng rủi ro lại thấp hơn 0.0199235?

  3. Có hay không một sự kết hợp cụ thể nào đó của các tài sản mà với một mức lợi tức mục tiêu định trước là, ví dụ, 1% nhưng rủi ro là thấp nhất có thể được, thậm chí là thấp hơn cả rủi ro của tài sản C - là tài sản có rủi ro thấp nhất trong số ba tài sản?

Những câu hỏi này sẽ dần được sáng tỏ trong các mục kế tiếp.

A Real-world Application

Trong thế giới thực chúng ta cần tính được Table 1 từ dữ liệu thô (raw data). Để minh họa chúng ta chọn ba công ti là Microsoft, Starbucks và General Motor (tức là một công ti công nghệ, một công ti hàng tiêu dùng nhanh và một công ti công nghiệp nặng) và lấy dữ liệu lịch sử về giá cổ phiếu của ba công ti này bằng hàm tq_get() của thư viện tidyquant từ 2018-01-01 đến 2020-12-31:

Chúng ta có thể xem giá của ba cổ phiếu tại ngày cuối cùng trong mẫu dữ liệu đã lấy:

Table 3: Some Observations
symbol date open high low close volume adjusted
GE 2020-12-30 10.58 10.85 10.55 10.71 50621000 10.71
MSFT 2020-12-30 225.23 225.63 221.47 221.68 20272300 221.68
SBUX 2020-12-30 105.99 106.62 105.78 105.97 3654100 105.97

Xu hướng biến động về giá hiệu chỉnh (adjusted) của ba cổ phiếu này (Figure 1):

Tính toán lợi tức của các tài sản được đo bằng log return theo công thức sau:

\[R_t=\ln\left(\frac{P_{t}} {P_{t-1}}\right)\]

Trong đó \(P_t\) là giá của tài sản ở thời điểm t và \(P_{t-1}\) là giá của tài sản tại thời điểm trước đó 1 ngày (còn gọi là trễ 1, kí hiệu là \(lag_1\)).

Phân phối của lợi tức có vẻ là phân phối chuẩn như ta có thể thấy ở Figure 2 dưới đây:

Để có kết luận chính xác phân phối có phải là phân phối chuẩn hay không chúng ta có thể dựa vào một test thống kê là Jarque–Bera (JB) test. Trước hết viết hàm tính toán thống kê này cùng p-value tương ứng:

Hàm tính toán ba tiêu chí quan trọng khác là Skewness, Kurtosis và CV (Coefficient of variation):

Table 4 liệt kê các thống kê quan trọng cùng với kiểm định JB Test cho lợi tức của ba tài sản:

Table 4: Main Statistics for Symbol
symbol Skewness Kurtosis CV JB_test p_value Mean Min Max SD N
GE -0.043 3.531 -52.867 395.857 0 -0.001 -0.164 0.137 0.031 754
MSFT -0.385 9.398 15.502 2812.889 0 0.001 -0.159 0.133 0.020 754
SBUX -0.381 15.961 22.386 8071.986 0 0.001 -0.177 0.137 0.020 754

Các giá trị p_value này rất thấp do vậy có thể chấp nhận giả thuyết rằng các lợi tức có phân phối chuẩn. Dưới đây là R codes để tính toán lợi tức và rủi ro cho ba cổ phiếu:

##          MSFT          SBUX            GE 
##  0.0013127958  0.0008899841 -0.0005860124

Tính Covariance Matrix của ba tài sản:

##              MSFT         SBUX           GE
## MSFT 0.0004141659 0.0002518696 0.0002366285
## SBUX 0.0002518696 0.0003969449 0.0002719917
## GE   0.0002366285 0.0002719917 0.0009597900

Xét một danh mục đầu tư mà các trọng số của các tài sản là như nhau (Equal-weight portfolio). Dưới đây là R codes tính toán lợi tức và rủi ro của danh mục đầu tư này theo ngôn ngữ ma trận:

## [1] 0.0005389225
## [1] 0.01912497

Xét một danh mục đầu tư có các trọng số (weights) của các tài sản là 40%, 80% và -20%. Trọng số âm có nghĩa là nguồn tài chính để đầu tư vào cổ phiếu của GE bằng cách “mượn” (thuật ngữ tiếng Anh là Short Sell). Loại danh mục đầu tư có trọng số âm này được gọi là Long-Short portfolio. Tương tự như ở trên, trước hết chúng ta tạo X là vector các trọng số:

Dễ dàng thấy rằng tổng các trọng số luôn bằng 1. Lợi tức và rủi ro của danh mục đầu tư này:

Chúng ta nên lưu lại các kết quả đã có:

Table 5: Risk-return trade-off
symbol risk return
GE 0.0310 -0.0006
MSFT 0.0204 0.0013
SBUX 0.0199 0.0009
EQUA 0.0191 0.0005
SHORT 0.0199 0.0014

Table 5 chỉ ra rằng Long-Short portfolio (kí hiệu SHORT) có lợi tức lớn nhất và cao hơn lợi tức của mã MSFT - cổ phiếu có lợi tức cao nhất trong số ba tài sản nhưng rủi ro của danh mục này lại thấp hơn rủi ro của MSFT. Liệu rằng việc đa dạng hóa bằng cách đầu tư vào ba tài sản trên với trọng số lần lượt là 40% cho MSFT, 80% cho SBUX và -20% cho GE có phải là lựa chọn tối ưu hay chí ít là hiệu quả? Chúng ta sẽ trả lời câu hỏi này ở mục kế tiếp ngay sau đây.

Efficient Portfolios by Simulation

Như ở trên đã phân tích, bằng cách thay đổi các trọng số chúng ta có hai danh mục đầu tư. Danh mục đầu tư thứ nhất (kí hiệu EQUA) có các trọng số bằng nhau (và đều bằng 33.33%) còn danh mục thứ hai (kí hiệu SHORT) có các trọng số lần lượt là 40%, 80% và -20%. Để tìm được danh mục đầu tư hiệu quả một trong những cách mà chúng ta có thể sử dụng là bằng mô phỏng (Simulation). Theo cách tiếp cận này chúng ta sẽ khảo sát cặp risk-return của, chẳng hạn, 10000 danh mục đầu tư khác nhau tương ứng với 10000 bộ trọng số khác nhau cho các tài sản cấu thành nên danh mục. Dựa trên khảo sát về cặp risk-return của 10000 danh mục đầu tư này chúng ta có thể trả lời một số câu hỏi như phải chăng còn tồn tại một danh mục với bộ trọng số nào đó mà lợi tức thì còn cao hơn lợi tức của SHORT nhưng rủi ro còn thấp hơn cả rủi ro của SHORT?.

Lưu ý rằng cho đến hiện tại, từ Table 5 thì SHORT chính là danh mục đầu tư “tốt nhất” căn cứ vào return còn EQUA là danh mục đầu tư có rủi ro thấp nhất căn cứ vào risk.

Để thực hiện simulation trước hết chúng ta viết một hàm có tên là portfolio_risk_return() tính toán cặp risk-return của một danh mục đầu tư nếu cho trước các trọng số tương ứng với ba tài sản MSFT, SBUX và GE:

Các trọng số sử dụng trong tính toán của hàm trên được tạo ra từ hàm random.bounded() của thư viện rportfolios. Lưu ý rằng: (1) tổng các trọng số luôn là 1, và (2) trọng số có thể là âm như có thể thấy:

## [1] -0.1699776  0.1699776  1.0000000

Sử dụng hàm này tính toán cặp risk-return của 10000 danh mục đầu tư và lưu lại kết quả dưới dạng một Data Frame có tên df_return_mini_10000 như dưới đây:

##    user  system elapsed 
##   28.12    0.43   28.61

Lấy ra danh mục đầu tư có rủi ro thấp nhất và danh mục đầu tư có lợi tức cao nhất:

Figure 3 dưới đây chỉ ra cặp risk-return cho 10002 danh mục (10000 danh mục + hai danh mục EQUA và SHORT):

Ba tài sản đơn lẻ (có thể coi là ba danh mục đầu tư mà trong đó các trọng số của hai tài sản là 0% còn tài sản thứ ba có trọng số 100%) được biểu diễn bằng ba điểm màu xanh. Hai danh mục EQUA và SHORT là hai điểm màu vàng còn màu đỏ và tím lần lượt là hai danh mục có rủi ro thấp nhất và lợi tức cao nhất.

Figure 3 chỉ ra rằng:

  1. Vẫn tồn tại rất nhiều danh mục đầu tư mà so với SHORT thì: (1) lợi tức cao hơn, và (2) rủi ro thấp hơn.
  2. Vẫn còn tại rất nhiều danh mục đầu tư mà so với EQUA thì: (1) lợi tức cao hơn, và (2) rủi ro thấp hơn.

Chúng ta có thể xem tỉ trọng các tài sản có rủi ro thấp nhất trong số 10002 danh mục đầu tư (điểm màu đỏ):

Table 5: Minimum-variance Portfolio
symbol weight return risk
MSFT 45.01% 0.001 0.018
SBUX 45.88% 0.001 0.018
GE 9.11% 0.001 0.018

Và danh mục đầu tư có lợi tức cao nhất (điểm màu tím):

Table 6: Maximun-return Portfolio
symbol weight return risk
MSFT 99.97% 0.003 0.035
SBUX 100% 0.003 0.035
GE -99.97% 0.003 0.035

Summary

Đa dạng hóa đầu tư nhằm giảm thiểu rủi ro là một trong những hệ quả quan trọng của lí thuyết danh mục đầu tư (Portfolio Theory). Phần 1 của trước hết điểm lại những điểm cốt lõi của lí thuyết danh mục đầu tư và việc tính toán theo ngôn ngữ ma trận với R cũng như cách tiếp cận trực quan để tìm ra danh mục đầu tư hiệu quả (Efficient Portfolio) bằng phương pháp mô phỏng. Trong trường hợp danh mục đầu tư có n tài sản khác nhau thì việc áp dụng và tính toán vẫn không có gì thay đổi.

Đối với các khía cạnh như lí thuyết về Portfolio Theory, cơ sở Toán - Thống Kê/tính toán ma trận (Matrix Calculation) với ngôn ngữ R là những mảng kiến thức/kĩ năng mà người viết bài này mặc định bạn đọc đã nắm được. Bạn đọc quan tâm có thể tham khảo các tài liệu liệt kê ở mục References.

LS0tDQp0aXRsZTogJ1F1YW50aXRhdGl2ZSBGaW5hbmNlOiBQb3J0Zm9saW8gVGhlb3J5IChQMSknDQphdXRob3I6ICdBdXRob3I6IE5ndXllbiBDaGkgRHVuZycNCnN1YnRpdGxlOiAiUiBGaW5hbmNlIFNlcmllcyINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgICMgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgaGlnaGxpZ2h0OiB6ZW5idXJuDQogICAgIyBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRoZW1lOiAiZmxhdGx5Ig0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KLS0tDQoNCmBgYHtyIHNldHVwLGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCBjYWNoZSA9IFRSVUUpDQoNCmBgYA0KDQohW10oQzovVXNlcnMvQURNSU4vRG9jdW1lbnRzL2ludjIuanBnKQ0KDQoNCiMgUG9ydGZvbGlvcyB3aXRoIFRocmVlIFJpc2t5IEFzc2V0cw0KDQpYw6l0IG3hu5l0IGRhbmggbeG7pWMgxJHhuqd1IHTGsCAoUG9ydGZvbGlvKSBn4buTbSBiYSB0w6BpIHPhuqNuIGzDoCBBLCBCIHbDoCBDLiBLw60gaGnhu4d1ICRSX2kkICgkaSA9IEEsIEIsIEMkKSBsw6AgbOG7o2kgdOG7qWMgdMawxqFuZyDhu6luZyBj4bunYSBiYSB0w6BpIHPhuqNuIHbDoCBnaeG6oyDEkeG7i25oIHLhurFuZyBjw6FjIGzhu6NpIHThu6ljIGzDoCBiaeG6v24gbmfhuqt1IG5oacOqbiAoUmFuZG9tIFZhcmlhYmxlKSB0aOG7j2EgbcOjbjogDQoNCg0KDQokJFJfe2l9XHNpbSBOKFxtdV9pLFxzaWdtYV9pXjIpJCQNCg0KTmdvw6BpIHJhIHbhu5tpICRpIFxuZSBqJCB0aMOsIGNvdmFyaWFuY2UgY+G7p2EgZ+G6t3AgdMOgaSBz4bqjbiBi4bqldCBrw6wgJGkkIHbDoCAkaiQ6IA0KDQokJFxtYXRocm17Y292fVxsZWZ0KFJfaSwgUl9qIFxyaWdodCkgPSBcc2lnbWFfe2lqfSQkDQoNCk7hur91IHThu4kgdHLhu41uZyBj4bunYSBiYSB0w6BpIHPhuqNuIG7DoHkgdHJvbmcgZGFuaCBt4bulYyDEkeG6p3UgdMawIGzDoCAkeF9BJCwgJHhfQiQgdsOgICR4X0MkIChsxrB1IMO9IHLhurFuZyAkeF9BICsgeF9CICsgeF9DID0gMSQpIHRow6wgbOG7o2kgdOG7qWMgY+G7p2EgZGFuaCBt4bulYywga8OtIGhp4buHdSBsw6AgJFJfcCxfeCQgY8Wpbmcgc+G6vSBsw6AgbeG7mXQgYmnhur9uIG5n4bqrdSBuaGnDqm46IA0KDQokJFxiZWdpbntlcXVhdGlvbn0NClx0YWd7MX0NClJfcCA9IHhfQVJfQSArIHhfQlJfQiArIHhfQ1JfQw0KXGVuZHtlcXVhdGlvbn0kJA0KDQoNCg0KVsOgIGzhu6NpIHThu6ljIGvDrCB24buNbmcgY+G7p2EgZGFuaCBt4bulYyAkXG11X3AsX3gkLCBu4bq/dSBrw60gaGnhu4d1ICRcbXVfQSQsICRcbXVfQiQgdsOgICRcbXVfQyQgbOG6p24gbMaw4bujdCBsw6AgbOG7o2kgdOG7qWMga8OsIHbhu41uZyBj4bunYSBiYSB0w6BpIHPhuqNuIEEsIEIgdsOgIEMgc+G6vSDEkcaw4bujYyB0w61uaCB0aGVvIGPDtG5nIHRo4bupYzogDQoNCiQkXGJlZ2lue2VxdWF0aW9ufQ0KXHRhZ3syfQ0KXG11X3AgPSBFW1JfcF0gPSB4X0FcbXVfQSArIHhfQlxtdV9CICsgeF9DXG11X0MNClxlbmR7ZXF1YXRpb259JCQgDQoNCg0KDQpDw7JuIHLhu6dpIHJvIGPhu6dhIGRhbmggbeG7pWMsIGvDrSBoaeG7h3UgbMOgICRcc2lnbWFfcCQgc+G6vSBsw6A6ICANCg0KJCRcYmVnaW57ZXF1YXRpb259DQpcdGFnezN9DQpcc2lnbWFeMl9wID0gXG1hdGhybXt2YXIoUl9wKSA9IHheMl9BXHNpZ21hXjJfQSArIHheMl9CXHNpZ21hXjJfQiArIHheMl9DXHNpZ21hXjJfQyArIDJ4X0F4X0Jcc2lnbWFfe0FCfSArIDJ4X0J4X0Ncc2lnbWFfe0JDfSArIDJ4X0F4X0Ncc2lnbWFfe0FDfX0NClxlbmR7ZXF1YXRpb259JCQNCg0KDQpDw6FjIGPDtG5nIHRo4bupYyDEkcaw4bujYyBtw7QgdOG6oyBi4bqxbmcgY8OhYyBwaMawxqFuZyB0csOsbmggxJHhuqFpIHPhu5Eg4bufIHRyw6puIGLhuqFuIMSR4buNYyBjw7MgdGjhu4MgdMOsbSB0aOG6pXQg4bufIGLhuqV0IGvDrCBjdeG7kW4gc8OhY2ggbsOgbyB24buBIEludmVzdG1lbnQgdsOgIFBvcnRmb2xpbyBUaGVvcnkuIEPDsm4gdGhlbyBuZ8O0biBuZ+G7ryBj4bunYSBtYSB0cuG6rW4gdsOgIHTDrW5oIHRvw6FuIG1hIHRy4bqtbiAoTWF0cml4IENhbGN1bGF0aW9uKSB0aMOsIGzhu6NpIHThu6ljIGPhu6dhIGRhbmggbeG7pWMgdMOtbmggdGhlbyBjw7RuZyB0aOG7qWMgKDIpIHPhur0gxJHGsOG7o2MgYmnhu4N1IGRp4buFbiBsw6A6IA0KDQokJFxtdV9wID0gWFxtdSQkDQoNCkPDsm4gcuG7p2kgcm8gY+G7p2EgZGFuaCBt4bulYyB0aGVvIGPDtG5nIHRo4bupYyAoMyksIHbhu5tpIGNow7ogw70gcuG6sW5nICRYJyQgbMOgIG1hIHRy4bqtbiBjaHV54buDbiB24buLIGPhu6dhIG1hIHRy4bqtbiAkWCQsIHPhur0gbMOgOiANCg0KDQokJFxzaWdtYV4yX3AgPSBYJ1xTaWdtYSBYJCQNCg0KVHJvbmcgxJHDsyAkWCQsICRcbXUkIHbDoCAkXFNpZ21hJCDEkcaw4bujYyDEkeG7i25oIG5naMSpYSB2w6AgbcO0IHThuqMgZMaw4bubaSDEkcOieTogDQoNCi0gJFxtdSQgbMOgIG1hIHRy4bqtbiBs4bujaSB04bupYyBj4bunYSBiYSB0w6BpIHPhuqNuIEEsIEIgdsOgIEMuIMSQw6J5IGzDoCBtYSB0cuG6rW4gY8OzIGvDrWNoIHRoxrDhu5tjIDPDlzE6IA0KDQokJFxtdSA9IA0KXGJlZ2lue3BtYXRyaXh9DQpcbXVfQSBcXA0KXG11X0IgXFwNClxtdV9DDQpcZW5ke3BtYXRyaXh9JCQgIA0KDQotICRYJCBsw6AgbWEgdHLhuq1uIHThu4kgdHLhu41uZyBj4bunYSBiYSB0w6BpIHPhuqNuIEEsIEIgdsOgIEMgKGvDrWNoIHRoxrDhu5tjIDPDlzEpOiANCg0KJCRYID0gDQpcYmVnaW57cG1hdHJpeH0NCnhfQSAmIHhfQiAmIHhfQw0KXGVuZHtwbWF0cml4fSQkICANCg0KLSAkXFNpZ21hJCBsw6AgbWEgdHLhuq1uIGhp4buHcCBwaMawxqFuZyBzYWkgKENvdmFyaWFuY2UgTWF0cml4KSBj4bunYSBiYSB0w6BpIHPhuqNuIHRyb25nIGRhbmggbeG7pWMgxJHhuqd1IHTGsC4gxJDDonkgbMOgIG3hu5l0IG1hIHRy4bqtbiDEkeG7kWkgeOG7qW5nIChzeW1tZXRyaWMpIGvDrWNoIHRoxrDhu5tjIDPDlzMgdsOsIHLhurFuZyAkXG1hdGhybXtjb3Z9XGxlZnQoUl9pLCBSX2ogXHJpZ2h0KSA9IFxtYXRocm17Y292fVxsZWZ0KFJfaiwgUl9pIFxyaWdodCkkOiANCg0KJCRcYmVnaW57ZXF1YXRpb24qfQ0KXFNpZ21hID0gDQpcYmVnaW57cG1hdHJpeH0NClxzaWdtYV4yX0EgJiBcc2lnbWFfe0FCfSAmIFxzaWdtYV97QUN9IFxcDQpcc2lnbWFfe0FCfSAmIFxzaWdtYV4yX0IgJiBcc2lnbWFfe0JDfSBcXA0KXHNpZ21hX3tBQ30gJiBcc2lnbWFfe0JDfSAmIFxzaWdtYV4yX0MNClxlbmR7cG1hdHJpeH0NClxlbmR7ZXF1YXRpb24qfSQkIA0KDQpOaOG7r25nIG3hu6VjIGTGsOG7m2kgxJHDonkgY2jDum5nIHRhIHPhur0gdHJp4buDbiBraGFpIHTDrW5oIHRvw6FuIGzhu6NpIHThu6ljIC0gcuG7p2kgcm8gY+G7p2EgZGFuaCBt4bulYyDEkeG6p3UgdMawIHbDoCBuaOG7r25nIGLDoGkgdG/DoW4gY8ahIGLhuqNuIGPhu6dhIFBvcnRmb2xpbyBUaGVvcnkgYuG6sW5nIHTDrW5oIHRvw6FuIG1hIHRy4bqtbiB24bubaSBuZ8O0biBuZ+G7ryBSLiANCg0KIyBBIFNpbXBsZSBFeGFtcGxlDQoNCljDqXQgbeG7mXQgZGFuaCBt4bulYyDEkeG6p3UgdMawIGfhu5NtIGJhIGPhu5UgcGhp4bq/dSBBLCBCIHbDoCBDIHbhu5tpIGzhu6NpIHThu6ljIChrw60gaGnhu4d1ICRcbXVfaSQpLCBy4bunaSBybyAoa8OtIGhp4buHdSAkXHNpZ21hX2kkKSB2w6AgY292YXJpYW5jZSB0aGVvIHThu6tuZyBj4bq3cCAoa8OtIGhp4buHdSAkXHNpZ21hX3tpan0kKSDEkcaw4bujYyBjaG8g4bufIFRhYmxlIDEgZMaw4bubaSDEkcOieTogDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KDQpybShsaXN0ID0gbHMoKSkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KDQpjb2xfbmFtZXMgPC0gYygiU3RvY2sgJGkkIiwgIiRcXG11X2kkIiwgIiRcXHNpZ21hX2kkIiwgIlBhaXIgJChpLGopJCIsICIkXFxzaWdtYV97aWp9JCIpDQoNCnN5bWJvbCA8LSBjKExFVFRFUlNbMTozXSkNCg0KbXUgPC0gYygwLjAwMTMxMjc5NTgsIDAuMDAwODg5OTg0MSwgLTAuMDAwNTg2MDEyNCkNCg0Kc2lnbWFfaSA8LSBjKDAuMDIwMzUxMDcsIDAuMDE5OTIzNDgsIDAuMDAwMjcxOTkxNykNCg0KcGFpciA8LSBjKCIoQSxCKSIsICIoQSxDKSIsICIoQixDKSIpDQoNCnNpZ21hX2lqIDwtIGMoMC4wMDAyNTE4Njk2LCAwLjAwMDIzNjYyODUsIDAuMDAwMjcxOTkxNykNCg0KdGhyZWVfZXhhbXBsZSA8LSB0aWJibGUoc3ltYm9sID0gc3ltYm9sLCBtdSA9IG11LCBteV9zaWdtYSA9IHNpZ21hX2ksIHBhaXIgPSBwYWlyLCBzaWdtYV9paiA9IHNpZ21hX2lqKQ0KDQpuYW1lcyh0aHJlZV9leGFtcGxlKSA8LSBjb2xfbmFtZXMNCg0KdGhyZWVfZXhhbXBsZSAlPiUNCiAgaGVhZCgpICU+JSANCiAga2JsKGNhcHRpb24gPSAiVGFibGUgMTogQSBSZWFsLXdvcmxkIGV4YW1wbGUgZGF0YSIsIA0KICAgICAgY29sLm5hbWVzID0gY29sX25hbWVzLCANCiAgICAgIGVzY2FwZSA9IFRSVUUpICU+JQ0KICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBGQUxTRSwgaHRtbF9mb250ID0gIkNhbWJyaWEiKQ0KDQpgYGANCg0KWMOpdCBt4buZdCBkYW5oIG3hu6VjIMSR4bqndSB0xrAgbcOgIHThu4kgdHLhu41uZyBj4bunYSBjw6FjIHTDoGkgc+G6o24gQSwgQiwgQyBsw6AgbmjGsCBuaGF1IChlcXVhbGx5IHdlaWdodGVkIHBvcnRmb2xpbykuIETGsOG7m2kgxJHDonkgbMOgIFIgY29kZXMgY2hvIHTDrW5oIHRvw6FuIGzhu6NpIHThu6ljIHbDoCBy4bunaSBybyBj4bunYSBkYW5oIG3hu6VjIMSR4bqndSB0xrAgbsOgeS4gVHLGsOG7m2MgaOG6v3QgbMOgIG5o4bqtcCBz4buRIGxp4buHdSBjaG8gY8OhYyBtYSB0cuG6rW4gJFgkLCAkXG11JCB2w6AgJFxTaWdtYSQgZOG7sWEgdHLDqm4gVGFibGUgMToNCg0KYGBge3J9DQoNCiMgQ2xlYXIgd29ya3NwYWNlOiANCnJtKGxpc3QgPSBscygpKQ0KDQojIFN5bWJvbDogDQpteV9zeW1ib2xzIDwtIExFVFRFUlNbMTozXQ0KDQojIEFzc2V0IFdlaWdodHM6IA0KWCA8LSByZXAoMSAvIDMsIDMpDQoNCiMgQXNzZXQgcmV0dXJuczogDQptdSA8LSBjKDAuMDAxMzEyNzk1OCwgMC4wMDA4ODk5ODQxLCAtMC4wMDA1ODYwMTI0KQ0KDQojIEFzc2V0IHJpc2tzOiANCnNpZ21hX2kgPC0gYygwLjAyMDM1MTA3LCAwLjAxOTkyMzQ4LCAwLjAzMDk4MDQ4KQ0KDQojIENvdmFyaWFuY2U6IA0Kc2lnbWFfaWogPC0gYygwLjAwMDI1MTg2OTYsIDAuMDAwMjM2NjI4NSwgMC4wMDAyNzE5OTE3KQ0KDQojIENyZWF0ZSBjb3ZhcmlhbmNlIG1hdHJpeDogDQpzaWdtYV9tYXRyaXhfMyA8LSBtYXRyaXgoYyhzaWdtYV9pWzFdKnNpZ21hX2lbMV0sIHNpZ21hX2lqWzFdLCBzaWdtYV9palsyXSwgDQogICAgICAgICAgICAgICAgICAgICAgICBzaWdtYV9palsxXSwgc2lnbWFfaVsyXSpzaWdtYV9pWzJdLCBzaWdtYV9palszXSwgDQogICAgICAgICAgICAgICAgICAgICAgICBzaWdtYV9palsyXSwgc2lnbWFfaWpbM10sIHNpZ21hX2lbM10qc2lnbWFfaVszXSksDQogICAgICAgICAgICAgICAgICAgICAgICBucm93ID0gMywgYnlyb3cgPSBUUlVFKQ0KDQojIFNldCBuYW1lIGZvciBjb3ZhcmlhbmNlIG1hdHJpeDoNCmRpbW5hbWVzKHNpZ21hX21hdHJpeF8zKSA8LSBsaXN0KG15X3N5bWJvbHMsIG15X3N5bWJvbHMpDQoNCmBgYA0KDQpNYSB0cuG6rW4gaGnhu4dwIHBoxrDGoW5nIHNhaTogDQoNCmBgYHtyfQ0KbGlicmFyeShtYWdyaXR0cikgIyBGb3IgdXNpbmcgUGlwZSBvcGVyYXRvci4gDQpsaWJyYXJ5KGthYmxlRXh0cmEpICMgRm9yIHByZXNlbnRpbmcgdGFibGUuIA0KDQpzaWdtYV9tYXRyaXhfMyAlPiUgDQogIGtibChjYXB0aW9uID0gIlRhYmxlIDI6IENvdmFyaWFuY2UgbWF0cml4IiwgZXNjYXBlID0gVFJVRSkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IEZBTFNFLCBodG1sX2ZvbnQgPSAiQ2FtYnJpYSIpDQogIA0KICANCmBgYA0KDQpUw61uaCB0b8OhbiBs4bujaSB04bupYyB2w6AgcuG7p2kgcm8gY2hvIGRhbmggbeG7pWMgxJHhuqd1IHTGsDogDQoNCmBgYHtyfQ0KIyBQb3J0Zm9saW8gcmV0dXJuOiANCm11X3BvcnQgPSBjcm9zc3Byb2QoWCwgbXUpDQoNCm11X3BvcnQgPC0gbXVfcG9ydCAlPiUgYXMubnVtZXJpYygpDQoNCiMgUG9ydGZvbGlvIHJpc2s6IA0KDQpzaWcyX3BvcnQgPC0gdChYKSAlKiUgc2lnbWFfbWF0cml4XzMgJSolIFgNCg0Kc2lnX3BvcnQgPC0gc2lnMl9wb3J0ICU+JSBhcy5udW1lcmljKCkgJT4lIHNxcnQoKQ0KDQojIFByaW50IHJlc3VsdHM6IA0KDQpwcmludChtdV9wb3J0KSAjIFJldHVybg0KcHJpbnQoc2lnX3BvcnQpICMgUmlzaw0KYGBgDQoNCkRhbmggbeG7pWMgxJHhuqd1IHTGsCBuw6B5IHR1eSBs4bujaSB04bupYyBjaOG7iSBi4bqxbmcgNDElIHNvIHbhu5tpIHTDoGkgc+G6o24gQiBuaMawbmcgcuG7p2kgcm8gbOG6oWkgZ+G6p24gYuG6sW5nLiBN4buZdCBuaMOgIMSR4bqndSB0xrAgZHV5IGzDrSDEkcawxqFuZyBuaGnDqm4gc+G6vSDGsGEgdGjDrWNoIMSR4bqndSB0xrAgdG/DoG4gYuG7mSB0w6BpIHPhuqNuIGPhu6dhIG3DrG5oIHbDoG8gQiBoxqFuIGzDoCBwaMOibiBi4buVIMSR4buBdSB2w6BvIGJhIHTDoGkgc+G6o24uIERvIHbhuq15IG3DoCB0cuG7jW5nIHTDom0gY+G7p2EgbMOtIHRodXnhur90IGRhbmggbeG7pWMgKFBvcnRmb2xpbyBUaGVvcnkpIHbDoCBs4buxYSBjaOG7jW4gZGFuaCBt4bulYyDEkeG6p3UgdMawIChQb3J0Zm9saW8gU2VsZWN0aW9uKSBsw6AgdHLhuqMgbOG7nWkgY8OidSBo4buPaSBraeG7g3UgbmjGsCBzYXU6IA0KDQoxLiBDw7MgaGF5IGtow7RuZyBt4buZdCBz4buxIGvhur90IGjhu6NwIGPhu6UgdGjhu4MgbsOgbyDEkcOzIGPhu6dhIGPDoWMgdMOgaSBz4bqjbiBtw6AgY8O5bmcgduG7m2kgbeG7qWMgbOG7o2kgdOG7qWMgbmjGsCB0w6BpIHPhuqNuIEEgLSB0w6BpIHPhuqNuIGPDsyBs4bujaSB04bupYyBjYW8gbmjhuqV0IHRyb25nIHPhu5EgYmEgdMOgaSBz4bqjbiBuaMawbmcgY8OzIHLhu6dpIHJvIHRo4bqlcCBoxqFuPyANCg0KMi4gQ8OzIGhheSBraMO0bmcgbeG7mXQgc+G7sSBr4bq/dCBo4bujcCBj4bulIHRo4buDIG7DoG8gxJHDsyBj4bunYSBjw6FjIHTDoGkgc+G6o24gbcOgIGPDuW5nIHbhu5tpIG3hu6ljIGzhu6NpIHThu6ljIG5oxrAgdMOgaSBz4bqjbiBCIG5oxrBuZyBy4bunaSBybyBs4bqhaSB0aOG6pXAgaMahbiAwLjAxOTkyMzU/IA0KDQozLiBDw7MgaGF5IGtow7RuZyBt4buZdCBz4buxIGvhur90IGjhu6NwIGPhu6UgdGjhu4MgbsOgbyDEkcOzIGPhu6dhIGPDoWMgdMOgaSBz4bqjbiBtw6AgduG7m2kgbeG7mXQgbeG7qWMgbOG7o2kgdOG7qWMgbeG7pWMgdGnDqnUgxJHhu4tuaCB0csaw4bubYyBsw6AsIHbDrSBk4bulLCAxJSBuaMawbmcgcuG7p2kgcm8gbMOgIHRo4bqlcCBuaOG6pXQgY8OzIHRo4buDIMSRxrDhu6NjLCB0aOG6rW0gY2jDrSBsw6AgdGjhuqVwIGjGoW4gY+G6oyBy4bunaSBybyBj4bunYSB0w6BpIHPhuqNuIEMgLSBsw6AgdMOgaSBz4bqjbiBjw7MgcuG7p2kgcm8gdGjhuqVwIG5o4bqldCB0cm9uZyBz4buRIGJhIHTDoGkgc+G6o24/DQoNCk5o4buvbmcgY8OidSBo4buPaSBuw6B5IHPhur0gZOG6p24gxJHGsOG7o2Mgc8OhbmcgdOG7jyB0cm9uZyBjw6FjIG3hu6VjIGvhur8gdGnhur9wLiANCg0KIyBBIFJlYWwtd29ybGQgQXBwbGljYXRpb24NCg0KVHJvbmcgdGjhur8gZ2nhu5tpIHRo4buxYyBjaMO6bmcgdGEgY+G6p24gdMOtbmggxJHGsOG7o2MgVGFibGUgMSB04burIGThu68gbGnhu4d1IHRow7QgKHJhdyBkYXRhKS4gxJDhu4MgbWluaCBo4buNYSBjaMO6bmcgdGEgY2jhu41uIGJhIGPDtG5nIHRpIGzDoCBNaWNyb3NvZnQsIFN0YXJidWNrcyB2w6AgR2VuZXJhbCBNb3RvciAodOG7qWMgbMOgIG3hu5l0IGPDtG5nIHRpIGPDtG5nIG5naOG7hywgbeG7mXQgY8O0bmcgdGkgaMOgbmcgdGnDqnUgZMO5bmcgbmhhbmggdsOgIG3hu5l0IGPDtG5nIHRpIGPDtG5nIG5naGnhu4dwIG7hurduZykgdsOgIGzhuqV5IGThu68gbGnhu4d1IGzhu4tjaCBz4butIHbhu4EgZ2nDoSBj4buVIHBoaeG6v3UgY+G7p2EgYmEgY8O0bmcgdGkgbsOgeSBi4bqxbmcgaMOgbSBgdHFfZ2V0KClgIGPhu6dhIHRoxrAgdmnhu4duICoqdGlkeXF1YW50KiogdOG7qyAyMDE4LTAxLTAxIMSR4bq/biAyMDIwLTEyLTMxOiANCg0KYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD00fQ0KIyBDbGVhciB3b3Jrc3BhY2U6IA0Kcm0obGlzdCA9IGxzKCkpDQoNCiMgU29tZSBzdG9ja3Mgc2VsZWN0ZWQgKE1pY3Jvc29mdCwgU3RhcmJ1Y2tzIGFuZCBBcHBsZSk6IA0KDQpteV9zeW1ib2xzIDwtIGMoIk1TRlQiLCAiU0JVWCIsICJHRSIpDQoNCiMgTnVtYmVyIG9mIHN0b2NrczogDQoNCm4gPC0gbGVuZ3RoKG15X3N5bWJvbHMpDQoNCiMgQ29sbGVjdCBkYXRhOiANCg0KbGlicmFyeSh0aWR5cXVhbnQpDQpwcmljZV9kYXRhIDwtIHRxX2dldChteV9zeW1ib2xzLA0KICAgICAgICAgICAgICAgICAgICAgZnJvbSA9ICIyMDE4LTAxLTAxIiwNCiAgICAgICAgICAgICAgICAgICAgIHRvID0gIjIwMjAtMTItMzEiLA0KICAgICAgICAgICAgICAgICAgICAgZ2V0ID0gInN0b2NrLnByaWNlcyIpDQpgYGANCg0KQ2jDum5nIHRhIGPDsyB0aOG7gyB4ZW0gZ2nDoSBj4bunYSBiYSBj4buVIHBoaeG6v3UgdOG6oWkgbmfDoHkgY3Xhu5FpIGPDuW5nIHRyb25nIG3huqt1IGThu68gbGnhu4d1IMSRw6MgbOG6pXk6IA0KDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9DQoNCiMgU2hvdyBzb21lIG9ic2VydmF0aW9uczogDQoNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCg0KcHJpY2VfZGF0YSAlPiUgDQogIGdyb3VwX2J5KHN5bWJvbCkgJT4lIA0KICBzbGljZSh3aGljaC5tYXgoZGF0ZSkpICU+JSANCiAga2JsKGNhcHRpb24gPSAiVGFibGUgMzogU29tZSBPYnNlcnZhdGlvbnMiLCBlc2NhcGUgPSBUUlVFKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRkFMU0UsIGh0bWxfZm9udCA9ICJDYW1icmlhIikNCg0KYGBgDQoNClh1IGjGsOG7m25nIGJp4bq/biDEkeG7mW5nIHbhu4EgZ2nDoSBoaeG7h3UgY2jhu4luaCAoYWRqdXN0ZWQpIGPhu6dhIGJhIGPhu5UgcGhp4bq/dSBuw6B5IChGaWd1cmUgMSk6IA0KDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9DQoNCiMgUHJpY2UgdHJlbmQ6IA0KDQpwcmljZV9kYXRhICU+JSANCiAgZ2dwbG90KGFlcyhkYXRlLCBhZGp1c3RlZCwgY29sb3IgPSBzeW1ib2wpKSArDQogIGdlb21fbGluZShzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICBmYWNldF93cmFwKH4gc3ltYm9sLCBzY2FsZXMgPSAiZnJlZSIpICsgDQogIGxhYnMoeCA9IE5VTEwsIHkgPSBOVUxMLCANCiAgICAgICB0aXRsZSA9ICJGaWd1cmUgMTogU3RvY2sgUHJpY2UiKQ0KDQpgYGANCg0KVMOtbmggdG/DoW4gbOG7o2kgdOG7qWMgY+G7p2EgY8OhYyB0w6BpIHPhuqNuIMSRxrDhu6NjIMSRbyBi4bqxbmcgbG9nIHJldHVybiB0aGVvIGPDtG5nIHRo4bupYyBzYXU6IA0KDQoNCiQkUl90PVxsblxsZWZ0KFxmcmFje1Bfe3R9fSB7UF97dC0xfX1ccmlnaHQpJCQgDQoNClRyb25nIMSRw7MgJFBfdCQgbMOgIGdpw6EgY+G7p2EgdMOgaSBz4bqjbiDhu58gdGjhu51pIMSRaeG7g20gdCB2w6AgJFBfe3QtMX0kIGzDoCBnacOhIGPhu6dhIHTDoGkgc+G6o24gdOG6oWkgdGjhu51pIMSRaeG7g20gdHLGsOG7m2MgxJHDsyAxIG5nw6B5IChjw7JuIGfhu41pIGzDoCB0cuG7hSAxLCBrw60gaGnhu4d1IGzDoCAkbGFnXzEkKS4gDQoNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NH0NCg0KIyBDYWxjdWxhdGUgZGFpbHkgcmV0dXJuIGJhc2VkIG9uIGFkanVzdGVkIHByaWNlOiANCg0KcHJpY2VfZGF0YSAlPiUNCiAgZ3JvdXBfYnkoc3ltYm9sKSAlPiUgDQogIG11dGF0ZShsYWcxID0gbGFnKGFkanVzdGVkLCBuID0gMUwpKSAlPiUgDQogIGZpbHRlcighaXMubmEobGFnMSkpICU+JSANCiAgbXV0YXRlKGRhaWx5X3JldHVybiA9IGxvZyhhZGp1c3RlZCAvIGxhZzEpKSAlPiUgDQogIHVuZ3JvdXAoKSAlPiUgDQogIHNlbGVjdChzeW1ib2wsIGRhdGUsIGRhaWx5X3JldHVybikgLT4gZGFpbHlfcmV0dXJucw0KYGBgDQoNClBow6JuIHBo4buRaSBj4bunYSBs4bujaSB04bupYyBjw7MgduG6uyBsw6AgcGjDom4gcGjhu5FpIGNodeG6qW4gbmjGsCB0YSBjw7MgdGjhu4MgdGjhuqV5IOG7nyBGaWd1cmUgMiBkxrDhu5tpIMSRw6J5OiANCg0KYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD00fSAgDQojIFJldHVybiBkaXN0cmlidXRpb246IA0KDQpkYWlseV9yZXR1cm5zICU+JSANCiAgZ2dwbG90KGFlcyhkYWlseV9yZXR1cm4sIGZpbGwgPSBzeW1ib2wsIGNvbG9yID0gc3ltYm9sKSkgKyANCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC4xLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSwgYWxwaGEgPSAwLjEsIGJpbndpZHRoID0gMC4wMSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyANCiAgZmFjZXRfd3JhcCh+IHN5bWJvbCwgc2NhbGVzID0gImZyZWUiKSArIA0KICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgDQogICAgICAgdGl0bGUgPSAiRmlndXJlIDI6IERhaWx5IFJldHVybiBEaXN0cmlidXRpb24iKQ0KDQpgYGANCg0KxJDhu4MgY8OzIGvhur90IGx14bqtbiBjaMOtbmggeMOhYyBwaMOibiBwaOG7kWkgY8OzIHBo4bqjaSBsw6AgcGjDom4gcGjhu5FpIGNodeG6qW4gaGF5IGtow7RuZyBjaMO6bmcgdGEgY8OzIHRo4buDIGThu7FhIHbDoG8gbeG7mXQgdGVzdCB0aOG7kW5nIGvDqiBsw6AgSmFycXVl4oCTQmVyYSAoSkIpIHRlc3QuIFRyxrDhu5tjIGjhur90IHZp4bq/dCBow6BtIHTDrW5oIHRvw6FuIHRo4buRbmcga8OqIG7DoHkgY8O5bmcgcC12YWx1ZSB0xrDGoW5nIOG7qW5nOiANCg0KYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD00fSANCiMgRnVuY3Rpb24gY2FsY3VsYXRlcyBKYXJxdWXigJNCZXJhIChKQikgdGVzdDogDQpteV9KQiA8LSBmdW5jdGlvbih4KSB7DQogIG4gPC0gbGVuZ3RoKHgpDQogIG0xIDwtIHN1bSh4KS9uDQogIG0yIDwtIHN1bSgoeCAtIG0xKV4yKS9uDQogIG0zIDwtIHN1bSgoeCAtIG0xKV4zKS9uDQogIG00IDwtIHN1bSgoeCAtIG0xKV40KS9uDQogIGIxIDwtIChtMy9tMl4oMy8yKSleMg0KICBiMiA8LSAobTQvbTJeMikNCiAgSkIgPC0gbiAqIGIxLzYgKyBuICogKGIyIC0gMyleMi8yNA0KICByZXR1cm4oSkIpDQp9DQoNCiMgQ2FsY3VsYXRlcyBwLXZhbHVlIGZvciBKQiB0ZXN0OiANCm15X3N0YXMgPC0gZnVuY3Rpb24oeCkgew0KICBuIDwtIGxlbmd0aCh4KQ0KICBtMSA8LSBzdW0oeCkvbg0KICBtMiA8LSBzdW0oKHggLSBtMSleMikvbg0KICBtMyA8LSBzdW0oKHggLSBtMSleMykvbg0KICBtNCA8LSBzdW0oKHggLSBtMSleNCkvbg0KICBiMSA8LSAobTMvbTJeKDMvMikpXjINCiAgYjIgPC0gKG00L20yXjIpDQogIEpCIDwtIG4gKiBiMS82ICsgbiAqIChiMiAtIDMpXjIvMjQNCiAgcF92YWx1ZSA9IDEgLSBwY2hpc3EoSkIsIGRmID0gMikNCiAgcmV0dXJuKHBfdmFsdWUpDQp9DQpgYGANCg0KSMOgbSB0w61uaCB0b8OhbiBiYSB0acOqdSBjaMOtIHF1YW4gdHLhu41uZyBraMOhYyBsw6AgU2tld25lc3MsIEt1cnRvc2lzIHbDoCBDViAoQ29lZmZpY2llbnQgb2YgdmFyaWF0aW9uKTogDQoNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NH0gDQoNCiMgRnVudGlvbnMgY2FsY3VsYXRlcyBTa2V3bmVzczogDQpteV9zIDwtIGZ1bmN0aW9uKHgpIHsNCiAgbiA8LSBsZW5ndGgoeCkNCiAgeCA8LSB4IC0gbWVhbih4KQ0KICB5IDwtIHNxcnQobikgKiBzdW0oeF4zKS8oc3VtKHheMileKDMvMikpDQogIHkgPC0geSAqICgoMSAtIDEvbikpXigzLzIpDQogIHJldHVybih5KQ0KfQ0KDQojIEZ1bnRpb25zIGNhbGN1bGF0ZXMga3VydG9zaXM6IA0KbXlfayA8LSBmdW5jdGlvbih4KSB7DQogIG4gPC0gbGVuZ3RoKHgpDQogIHggPC0geCAtIG1lYW4oeCkNCiAgciA8LSBuICogc3VtKHheNCkvKHN1bSh4XjIpXjIpDQogIHkgPC0gIHIgKiAoMSAtIDEvbileMiAtIDMNCiAgcmV0dXJuKHkpDQp9DQoNCiMgRnVuY3Rpb24gY2FsY3VsYXRlcyBDViAoQ29lZmZpY2llbnQgb2YgdmFyaWF0aW9uKTogDQpteV9jdiA8LSBmdW5jdGlvbih4KSB7DQogIGN2IDwtIHNkKHgpIC8gbWVhbih4KQ0KICByZXR1cm4oY3YpDQp9DQpgYGANCg0KVGFibGUgNCBsaeG7h3Qga8OqIGPDoWMgdGjhu5FuZyBrw6ogcXVhbiB0cuG7jW5nIGPDuW5nIHbhu5tpIGtp4buDbSDEkeG7i25oIEpCIFRlc3QgY2hvIGzhu6NpIHThu6ljIGPhu6dhIGJhIHTDoGkgc+G6o246IA0KDQpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTR9IA0KIyBBcHBseSBmdW50aW9ucyBmb3Igb3VyIHN0b2NrOiANCg0KZGFpbHlfcmV0dXJucyAlPiUgDQogIGdyb3VwX2J5KHN5bWJvbCkgJT4lIA0KICBzdW1tYXJpc2UoU2tld25lc3MgPSBteV9zKGRhaWx5X3JldHVybiksIA0KICAgICAgICAgICAgS3VydG9zaXMgPSBteV9rKGRhaWx5X3JldHVybiksIA0KICAgICAgICAgICAgQ1YgPSBteV9jdihkYWlseV9yZXR1cm4pLCANCiAgICAgICAgICAgIEpCX3Rlc3QgPSBteV9KQihkYWlseV9yZXR1cm4pLCANCiAgICAgICAgICAgIHBfdmFsdWUgPSBteV9zdGFzKGRhaWx5X3JldHVybiksIA0KICAgICAgICAgICAgTWVhbiA9IG1lYW4oZGFpbHlfcmV0dXJuKSwgDQogICAgICAgICAgICBNaW4gPSBtaW4oZGFpbHlfcmV0dXJuKSwgDQogICAgICAgICAgICBNYXggPSBtYXgoZGFpbHlfcmV0dXJuKSwgDQogICAgICAgICAgICBTRCA9IHNkKGRhaWx5X3JldHVybiksIA0KICAgICAgICAgICAgTiA9IG4oKSkgLT4gZGZfc3RhdGlzdGljcw0KDQojIFNvbWUgbWFpbiBzdGF0aXN0aWNzIGZvciBzdG9ja3M6IA0KDQpkZl9zdGF0aXN0aWNzICU+JSANCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIGZ1bmN0aW9uKHgpIHtyb3VuZCh4LCAzKX0pICU+JSANCiAga2JsKGNhcHRpb24gPSAiVGFibGUgNDogTWFpbiBTdGF0aXN0aWNzIGZvciBTeW1ib2wiLCBlc2NhcGUgPSBUUlVFKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRkFMU0UsIGh0bWxfZm9udCA9ICJDYW1icmlhIikNCg0KYGBgDQoNCkPDoWMgZ2nDoSB0cuG7iyBwX3ZhbHVlIG7DoHkgcuG6pXQgdGjhuqVwIGRvIHbhuq15IGPDsyB0aOG7gyBjaOG6pXAgbmjhuq1uIGdp4bqjIHRodXnhur90IHLhurFuZyBjw6FjIGzhu6NpIHThu6ljIGPDsyBwaMOibiBwaOG7kWkgY2h14bqpbi4gRMaw4bubaSDEkcOieSBsw6AgUiBjb2RlcyDEkeG7gyB0w61uaCB0b8OhbiBs4bujaSB04bupYyB2w6AgcuG7p2kgcm8gY2hvIGJhIGPhu5UgcGhp4bq/dTogDQoNCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NH0gDQojIENhbGN1bGF0ZSByaXNrIGFuZCByZXR1cm4gZm9yIGFzc2V0czoNCiAgDQpkYWlseV9yZXR1cm5zICU+JSANCiAgZ3JvdXBfYnkoc3ltYm9sKSAlPiUgDQogIHN1bW1hcmlzZShyaXNrID0gc2QoZGFpbHlfcmV0dXJuKSwgcmV0dXJuID0gbWVhbihkYWlseV9yZXR1cm4pKSAtPiBkZl9yaXNrX3JldHVybg0KDQojIENvbnZlcnQgdG8gd2lkZSBmb3JtOiANCg0KZGFpbHlfcmV0dXJucyAlPiUgDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzeW1ib2wsIHZhbHVlc19mcm9tID0gZGFpbHlfcmV0dXJuKSAlPiUgDQogIHNlbGVjdCgtZGF0ZSkgLT4gcmV0dXJuc193aWRlDQoNCiMgQXNzZXQgbWVhbiByZXR1cm46IA0KDQptdSA8LSBjb2xNZWFucyhyZXR1cm5zX3dpZGUpIA0KDQpwcmludChtdSkNCmBgYA0KDQpUw61uaCBDb3ZhcmlhbmNlIE1hdHJpeCBj4bunYSBiYSB0w6BpIHPhuqNuOiANCg0KYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD00fSANCiMgQ292YXJpYW5jZSBtYXRyaXg6IA0KDQpzaWdtYV9tYXRyaXggPC0gY292KHJldHVybnNfd2lkZSkNCg0KcHJpbnQoc2lnbWFfbWF0cml4KQ0KDQpgYGANCg0KWMOpdCBt4buZdCBkYW5oIG3hu6VjIMSR4bqndSB0xrAgbcOgIGPDoWMgdHLhu41uZyBz4buRIGPhu6dhIGPDoWMgdMOgaSBz4bqjbiBsw6AgbmjGsCBuaGF1IChFcXVhbC13ZWlnaHQgcG9ydGZvbGlvKS4gRMaw4bubaSDEkcOieSBsw6AgUiBjb2RlcyB0w61uaCB0b8OhbiBs4bujaSB04bupYyB2w6AgcuG7p2kgcm8gY+G7p2EgZGFuaCBt4bulYyDEkeG6p3UgdMawIG7DoHkgdGhlbyBuZ8O0biBuZ+G7ryBtYSB0cuG6rW46IA0KDQpgYGB7cn0NCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAgRXF1YWwtd2VpZ2h0IHBvcnRmb2xpbw0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNClggPC0gcmVwKDEgLyBuLCBuKQ0KDQojIFBvcnRmb2xpbyByZXR1cm46IA0KbXVfcG9ydCA9IGNyb3NzcHJvZChYLCBtdSkNCg0KbXVfcG9ydF9lcXUgPC0gbXVfcG9ydCAlPiUgYXMubnVtZXJpYygpDQoNCiMgUG9ydGZvbGlvIHJpc2s6IA0KDQpzaWcyX3BvcnRfZXF1IDwtIHQoWCkgJSolIHNpZ21hX21hdHJpeCAlKiUgWA0KDQpzaWdfcG9ydF9lcXUgPC0gc2lnMl9wb3J0X2VxdSAlPiUgYXMubnVtZXJpYygpICU+JSBzcXJ0KCkNCg0KIyBQcmludCByZXN1bHRzOiANCg0KcHJpbnQobXVfcG9ydF9lcXUpICMgUmV0dXJuDQpwcmludChzaWdfcG9ydF9lcXUpICMgUmlzaw0KYGBgDQoNCljDqXQgbeG7mXQgZGFuaCBt4bulYyDEkeG6p3UgdMawIGPDsyBjw6FjIHRy4buNbmcgc+G7kSAod2VpZ2h0cykgY+G7p2EgY8OhYyB0w6BpIHPhuqNuIGzDoCA0MCUsIDgwJSB2w6AgLTIwJS4gVHLhu41uZyBz4buRIMOibSBjw7MgbmdoxKlhIGzDoCBuZ3Xhu5NuIHTDoGkgY2jDrW5oIMSR4buDIMSR4bqndSB0xrAgdsOgbyBj4buVIHBoaeG6v3UgY+G7p2EgR0UgYuG6sW5nIGPDoWNoICJtxrDhu6NuIiAodGh14bqtdCBuZ+G7ryB0aeG6v25nIEFuaCBsw6AgU2hvcnQgU2VsbCkuIExv4bqhaSBkYW5oIG3hu6VjIMSR4bqndSB0xrAgY8OzIHRy4buNbmcgc+G7kSDDom0gbsOgeSDEkcaw4bujYyBn4buNaSBsw6AgTG9uZy1TaG9ydCBwb3J0Zm9saW8uIFTGsMahbmcgdOG7sSBuaMawIOG7nyB0csOqbiwgdHLGsOG7m2MgaOG6v3QgY2jDum5nIHRhIHThuqFvIFggbMOgIHZlY3RvciBjw6FjIHRy4buNbmcgc+G7kTogDQoNCmBgYHtyfQ0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIExvbmctU2hvcnQgcG9ydGZvbGlvDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpYIDwtIGMoMC40LCAwLjgsIC0wLjIpDQpgYGANCg0KROG7hSBkw6BuZyB0aOG6pXkgcuG6sW5nIHThu5VuZyBjw6FjIHRy4buNbmcgc+G7kSBsdcO0biBi4bqxbmcgMS4gTOG7o2kgdOG7qWMgdsOgIHLhu6dpIHJvIGPhu6dhIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBuw6B5OiANCg0KYGBge3J9DQojIFBvcnRmb2xpbyByZXR1cm46IA0KbXVfcG9ydF9zaG8gPSBjcm9zc3Byb2QoWCwgbXUpDQoNCm11X3BvcnRfc2hvIDwtIG11X3BvcnRfc2hvICU+JSBhcy5udW1lcmljKCkNCg0KIyBQb3J0Zm9saW8gcmlzazogDQoNCnNpZzJfcG9ydF9zaG8gPC0gdChYKSAlKiUgc2lnbWFfbWF0cml4ICUqJSBYDQoNCnNpZ19wb3J0X3NobyA8LSBzaWcyX3BvcnRfc2hvICU+JSBhcy5udW1lcmljKCkgJT4lIHNxcnQoKQ0KYGBgDQoNCkNow7puZyB0YSBuw6puIGzGsHUgbOG6oWkgY8OhYyBr4bq/dCBxdeG6oyDEkcOjIGPDszogDQoNCmBgYHtyfQ0KDQp0d29fcG9ydCA8LSB0aWJibGUoc3ltYm9sID0gYygiRVFVQSIsICJTSE9SVCIpLCANCiAgICAgICAgICAgICAgICAgICByaXNrID0gYyhzaWdfcG9ydF9lcXUsIHNpZ19wb3J0X3NobyksIA0KICAgICAgICAgICAgICAgICAgIHJldHVybiA9IGMobXVfcG9ydF9lcXUsIG11X3BvcnRfc2hvKSkNCg0KZGZfcmlza19yZXR1cm4gJT4lIGJpbmRfcm93cyh0d29fcG9ydCkgLT4gZGZfdG90YWwNCg0KZGZfdG90YWwgJT4lIA0KICBtdXRhdGVfaWYoaXMubnVtZXJpYywgZnVuY3Rpb24oeCkge3JvdW5kKHgsIDQpfSkgJT4lIA0KICBrYmwoY2FwdGlvbiA9ICJUYWJsZSA1OiBSaXNrLXJldHVybiB0cmFkZS1vZmYiLCBlc2NhcGUgPSBUUlVFKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRkFMU0UsIGh0bWxfZm9udCA9ICJDYW1icmlhIikNCiAgDQoNCmBgYA0KDQpUYWJsZSA1IGNo4buJIHJhIHLhurFuZyBMb25nLVNob3J0IHBvcnRmb2xpbyAoa8OtIGhp4buHdSBTSE9SVCkgY8OzIGzhu6NpIHThu6ljIGzhu5tuIG5o4bqldCB2w6AgY2FvIGjGoW4gbOG7o2kgdOG7qWMgY+G7p2EgbcOjIE1TRlQgLSBj4buVIHBoaeG6v3UgY8OzIGzhu6NpIHThu6ljIGNhbyBuaOG6pXQgdHJvbmcgc+G7kSBiYSB0w6BpIHPhuqNuIG5oxrBuZyBy4bunaSBybyBj4bunYSBkYW5oIG3hu6VjIG7DoHkgbOG6oWkgdGjhuqVwIGjGoW4gcuG7p2kgcm8gY+G7p2EgTVNGVC4gTGnhu4d1IHLhurFuZyB2aeG7h2MgxJFhIGThuqFuZyBow7NhIGLhurFuZyBjw6FjaCDEkeG6p3UgdMawIHbDoG8gYmEgdMOgaSBz4bqjbiB0csOqbiB24bubaSB0cuG7jW5nIHPhu5EgbOG6p24gbMaw4bujdCBsw6AgNDAlIGNobyBNU0ZULCA4MCUgY2hvIFNCVVggdsOgIC0yMCUgY2hvIEdFIGPDsyBwaOG6o2kgbMOgIGzhu7FhIGNo4buNbiB04buRaSDGsHUgaGF5IGNow60gw610IGzDoCBoaeG7h3UgcXXhuqM/IENow7puZyB0YSBz4bq9IHRy4bqjIGzhu51pIGPDonUgaOG7j2kgbsOgeSDhu58gbeG7pWMga+G6vyB0aeG6v3AgbmdheSBzYXUgxJHDonkuIA0KDQojIEVmZmljaWVudCBQb3J0Zm9saW9zIGJ5IFNpbXVsYXRpb24NCg0KTmjGsCDhu58gdHLDqm4gxJHDoyBwaMOibiB0w61jaCwgYuG6sW5nIGPDoWNoIHRoYXkgxJHhu5VpIGPDoWMgdHLhu41uZyBz4buRIGNow7puZyB0YSBjw7MgaGFpIGRhbmggbeG7pWMgxJHhuqd1IHTGsC4gRGFuaCBt4bulYyDEkeG6p3UgdMawIHRo4bupIG5o4bqldCAoa8OtIGhp4buHdSBFUVVBKSBjw7MgY8OhYyB0cuG7jW5nIHPhu5EgYuG6sW5nIG5oYXUgKHbDoCDEkeG7gXUgYuG6sW5nIDMzLjMzJSkgY8OybiBkYW5oIG3hu6VjIHRo4bupIGhhaSAoa8OtIGhp4buHdSBTSE9SVCkgY8OzIGPDoWMgdHLhu41uZyBz4buRIGzhuqduIGzGsOG7o3QgbMOgIDQwJSwgODAlIHbDoCAtMjAlLiDEkOG7gyB0w6xtIMSRxrDhu6NjIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBoaeG7h3UgcXXhuqMgbeG7mXQgdHJvbmcgbmjhu69uZyBjw6FjaCBtw6AgY2jDum5nIHRhIGPDsyB0aOG7gyBz4butIGThu6VuZyBsw6AgYuG6sW5nIG3DtCBwaOG7j25nIChTaW11bGF0aW9uKS4gVGhlbyBjw6FjaCB0aeG6v3AgY+G6rW4gIG7DoHkgY2jDum5nIHRhIHPhur0ga2jhuqNvIHPDoXQgY+G6t3Agcmlzay1yZXR1cm4gY+G7p2EsIGNo4bqzbmcgaOG6oW4sIDEwMDAwIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBraMOhYyBuaGF1IHTGsMahbmcg4bupbmcgduG7m2kgMTAwMDAgYuG7mSB0cuG7jW5nIHPhu5Ega2jDoWMgbmhhdSBjaG8gY8OhYyB0w6BpIHPhuqNuIGPhuqV1IHRow6BuaCBuw6puIGRhbmggbeG7pWMuIEThu7FhIHRyw6puIGto4bqjbyBzw6F0IHbhu4EgY+G6t3Agcmlzay1yZXR1cm4gY+G7p2EgMTAwMDAgZGFuaCBt4bulYyDEkeG6p3UgdMawIG7DoHkgY2jDum5nIHRhIGPDsyB0aOG7gyB0cuG6oyBs4budaSBt4buZdCBz4buRIGPDonUgaOG7j2kgbmjGsCAqKnBo4bqjaSBjaMSDbmcgY8OybiB04buTbiB04bqhaSBt4buZdCBkYW5oICBt4bulYyB24bubaSBi4buZIHRy4buNbmcgc+G7kSBuw6BvIMSRw7MgbcOgIGzhu6NpIHThu6ljIHRow6wgY8OybiBjYW8gaMahbiBs4bujaSB04bupYyBj4bunYSBTSE9SVCBuaMawbmcgcuG7p2kgcm8gY8OybiB0aOG6pXAgaMahbiBj4bqjIHLhu6dpIHJvIGPhu6dhIFNIT1JUPyoqLiANCg0KTMawdSDDvSBy4bqxbmcgY2hvIMSR4bq/biBoaeG7h24gdOG6oWksIHThu6sgVGFibGUgNSB0aMOsIFNIT1JUIGNow61uaCBsw6AgZGFuaCBt4bulYyDEkeG6p3UgdMawICJ04buRdCBuaOG6pXQiIGPEg24gY+G7qSB2w6BvIHJldHVybiBjw7JuIEVRVUEgbMOgIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBjw7MgcuG7p2kgcm8gdGjhuqVwIG5o4bqldCBjxINuIGPhu6kgdsOgbyByaXNrLiANCg0KDQrEkOG7gyB0aOG7sWMgaGnhu4duIHNpbXVsYXRpb24gdHLGsOG7m2MgaOG6v3QgY2jDum5nIHRhIHZp4bq/dCBt4buZdCBow6BtIGPDsyB0w6puIGzDoCBgcG9ydGZvbGlvX3Jpc2tfcmV0dXJuKClgIHTDrW5oIHRvw6FuIGPhurdwIHJpc2stcmV0dXJuIGPhu6dhIG3hu5l0IGRhbmggbeG7pWMgxJHhuqd1IHTGsCBu4bq/dSBjaG8gdHLGsOG7m2MgY8OhYyB0cuG7jW5nIHPhu5EgdMawxqFuZyDhu6luZyB24bubaSBiYSB0w6BpIHPhuqNuIE1TRlQsIFNCVVggdsOgIEdFOiAgDQoNCg0KYGBge3J9DQoNCmxpYnJhcnkocnBvcnRmb2xpb3MpDQoNCnBvcnRmb2xpb19yaXNrX3JldHVybiA8LSBmdW5jdGlvbihqKSB7DQogIA0KICAjIENyZWF0ZSByYW5kb20gd2VpZ2h0czogDQogIA0KICBzZXQuc2VlZChqKQ0KICANCiAgWCA8LSByYW5kb20uYm91bmRlZChuID0gbiwgeC50ID0gMSwgeC5sID0gcmVwKC0xLCBuKSwgeC51ID0gcmVwKDEsIG4pKQ0KDQogICMgUG9ydGZvbGlvIHJldHVybjogDQogIG11X3BvcnRfcmFuZCA9IGNyb3NzcHJvZChYLCBtdSkgJT4lIGFzLm51bWVyaWMoKQ0KDQogICMgUG9ydGZvbGlvIHJpc2s6IA0KICBzaWdfcG9ydF9yYW5kIDwtIHQoWCkgJSolIHNpZ21hX21hdHJpeCAlKiUgWCAlPiUgYXMubnVtZXJpYygpICU+JSBzcXJ0KCkNCiAgDQogICMgQ3JlYXRlIGEgZGF0YSBmcmFtZSBvZiByZXN1bHRzOiANCiAgZGZfcG9mdCA8LSB0aWJibGUoc3ltYm9sID0gbXlfc3ltYm9scywgDQogICAgICAgICAgICAgICAgICAgIHdlaWdodCA9IFgsIA0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gPSBtdV9wb3J0X3JhbmQsIA0KICAgICAgICAgICAgICAgICAgICByaXNrID0gc2lnX3BvcnRfcmFuZCwNCiAgICAgICAgICAgICAgICAgICAgcG9ydF9pbmRleCA9IGopDQogIA0KICByZXR1cm4oZGZfcG9mdCkNCg0KfQ0KYGBgDQoNCkPDoWMgdHLhu41uZyBz4buRIHPhu60gZOG7pW5nIHRyb25nIHTDrW5oIHRvw6FuIGPhu6dhIGjDoG0gdHLDqm4gxJHGsOG7o2MgdOG6oW8gcmEgdOG7qyBow6BtIGByYW5kb20uYm91bmRlZCgpYCBj4bunYSB0aMawIHZp4buHbiAqKnJwb3J0Zm9saW9zKiouIEzGsHUgw70gcuG6sW5nOiAoMSkgdOG7lW5nIGPDoWMgdHLhu41uZyBz4buRIGx1w7RuIGzDoCAxLCB2w6AgKDIpIHRy4buNbmcgc+G7kSBjw7MgdGjhu4MgbMOgIMOibSBuaMawIGPDsyB0aOG7gyB0aOG6pXk6IA0KDQpgYGB7cn0NCnNldC5zZWVkKDI5KQ0KcmFuZG9tLmJvdW5kZWQobiA9IG4sIHgudCA9IDEsIHgubCA9IHJlcCgtMSwgbiksIHgudSA9IHJlcCgxLCBuKSkNCmBgYA0KDQpT4butIGThu6VuZyBow6BtIG7DoHkgdMOtbmggdG/DoW4gY+G6t3Agcmlzay1yZXR1cm4gY+G7p2EgMTAwMDAgZGFuaCBt4bulYyDEkeG6p3UgdMawIHbDoCBsxrB1IGzhuqFpIGvhur90IHF14bqjIGTGsOG7m2kgZOG6oW5nIG3hu5l0IERhdGEgRnJhbWUgY8OzIHTDqm4gKipkZl9yZXR1cm5fbWluaV8xMDAwMCoqIG5oxrAgZMaw4bubaSDEkcOieTogIA0KDQpgYGB7cn0NCnN5c3RlbS50aW1lKGxhcHBseSgxOjEwMDAwLCBwb3J0Zm9saW9fcmlza19yZXR1cm4pIC0+IGFsbF9yZXR1cm5fcG9ydCkNCg0KZG8uY2FsbCgiYmluZF9yb3dzIiwgYWxsX3JldHVybl9wb3J0KSAtPiBkZl9yZXR1cm5fMTAwMDANCg0KZGZfcmV0dXJuXzEwMDAwICU+JSANCiAgZmlsdGVyKCFkdXBsaWNhdGVkKHBvcnRfaW5kZXgpKSAtPiBkZl9yZXR1cm5fbWluaV8xMDAwMA0KYGBgDQoNCkzhuqV5IHJhIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBjw7MgcuG7p2kgcm8gdGjhuqVwIG5o4bqldCB2w6AgZGFuaCBt4bulYyDEkeG6p3UgdMawIGPDsyBs4bujaSB04bupYyBjYW8gbmjhuqV0OiAgDQoNCmBgYHtyfQ0KIyBNaW5pbXVtIHJpc2sgcG9ydGZvbGlvOiANCm1pbl9yaXNrIDwtIGRmX3JldHVybl9taW5pXzEwMDAwICU+JSBzbGljZSh3aGljaC5taW4ocmlzaykpIA0KDQojIE1heGltdW0gcmV0dXJuIHBvcnRmb2xpbzogDQptYXhfcmV0dXJuIDwtIGRmX3JldHVybl9taW5pXzEwMDAwICU+JSBzbGljZSh3aGljaC5tYXgocmV0dXJuKSkgDQpgYGANCg0KRmlndXJlIDMgZMaw4bubaSDEkcOieSBjaOG7iSByYSBj4bq3cCByaXNrLXJldHVybiBjaG8gMTAwMDIgZGFuaCBt4bulYyAoMTAwMDAgZGFuaCBt4bulYyArIGhhaSBkYW5oIG3hu6VjIEVRVUEgdsOgIFNIT1JUKTogDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3JlcGVsKQ0KbGlicmFyeShzY2FsZXMpDQoNCmRmX3JldHVybl9taW5pXzEwMDAwICU+JSANCiAgZ2dwbG90KGFlcyhyaXNrLCByZXR1cm4pKSArIA0KICBnZW9tX3BvaW50KGFscGhhID0gMC4wNSwgY29sb3IgPSAiYmx1ZSIpICsgDQogIGdlb21fcG9pbnQoZGF0YSA9IG1pbl9yaXNrLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMywgc2hhcGUgPSAxNykgKyANCiAgZ2VvbV90ZXh0X3JlcGVsKGRhdGEgPSBtaW5fcmlzaywgYWVzKGxhYmVsID0gIk1pbiBSaXNrIikpICsgDQogIGdlb21fcG9pbnQoZGF0YSA9IG1heF9yZXR1cm4sIGNvbG9yID0gInB1cnBsZSIsIHNpemUgPSAzLCBzaGFwZSA9IDE4KSArIA0KICBnZW9tX3RleHRfcmVwZWwoZGF0YSA9IG1heF9yZXR1cm4sIGFlcyhsYWJlbCA9ICJNYXggUmV0dXJuIikpICsgDQogIGdlb21fcG9pbnQoZGF0YSA9IGRmX3RvdGFsICU+JSBmaWx0ZXIoIXN5bWJvbCAlaW4lIGMoIkVRVUEiLCAiU0hPUlQiKSksIGNvbG9yID0gImdyZWVuIiwgc2l6ZSA9IDIpICsgDQogIGdlb21fcG9pbnQoZGF0YSA9IGRmX3RvdGFsICU+JSBmaWx0ZXIoc3ltYm9sICVpbiUgYygiRVFVQSIsICJTSE9SVCIpKSwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZSA9IDIpICsgDQogIGdlb21fdGV4dF9yZXBlbChkYXRhID0gZGZfdG90YWwsIGFlcyhsYWJlbCA9IHN5bWJvbCkpICsgDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50KSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCkgKyANCiAgbGFicyh4ID0gZXhwcmVzc2lvbigiUmlzayIgfiAoc2lnbWEpKSwgDQogICAgICAgeSA9IGV4cHJlc3Npb24oIlJldHVybiIgfiAobXUpKSwgDQogICAgICAgdGl0bGUgPSAiRmlndXJlIDM6IFBvcnRmb2xpbyBPcHRpbWl6YXRpb24gJiBFZmZpY2llbnQgRnJvbnRpZXIiKSANCmBgYA0KDQpCYSB0w6BpIHPhuqNuIMSRxqFuIGzhursgKGPDsyB0aOG7gyBjb2kgbMOgIGJhIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBtw6AgdHJvbmcgxJHDsyBjw6FjIHRy4buNbmcgc+G7kSBj4bunYSBoYWkgdMOgaSBz4bqjbiBsw6AgMCUgY8OybiB0w6BpIHPhuqNuIHRo4bupIGJhIGPDsyB0cuG7jW5nIHPhu5EgMTAwJSkgxJHGsOG7o2MgYmnhu4N1IGRp4buFbiBi4bqxbmcgYmEgxJFp4buDbSBtw6B1IHhhbmguIEhhaSBkYW5oIG3hu6VjIEVRVUEgdsOgIFNIT1JUIGzDoCBoYWkgxJFp4buDbSBtw6B1IHbDoG5nIGPDsm4gbcOgdSDEkeG7jyB2w6AgdMOtbSBs4bqnbiBsxrDhu6N0IGzDoCBoYWkgZGFuaCBt4bulYyBjw7MgcuG7p2kgcm8gdGjhuqVwIG5o4bqldCB2w6AgbOG7o2kgdOG7qWMgY2FvIG5o4bqldC4gDQoNCkZpZ3VyZSAzIGNo4buJIHJhIHLhurFuZzogDQoNCjEuIFbhuqtuIHThu5NuIHThuqFpIHLhuqV0IG5oaeG7gXUgZGFuaCBt4bulYyDEkeG6p3UgdMawIG3DoCBzbyB24bubaSBTSE9SVCB0aMOsOiAoMSkgbOG7o2kgdOG7qWMgY2FvIGjGoW4sIHbDoCAoMikgcuG7p2kgcm8gdGjhuqVwIGjGoW4uDQoyLiBW4bqrbiBjw7JuIHThuqFpIHLhuqV0IG5oaeG7gXUgZGFuaCBt4bulYyDEkeG6p3UgdMawIG3DoCBzbyB24bubaSBFUVVBIHRow6w6ICgxKSBs4bujaSB04bupYyBjYW8gaMahbiwgdsOgICgyKSBy4bunaSBybyB0aOG6pXAgaMahbi4gDQoNCg0KQ2jDum5nIHRhIGPDsyB0aOG7gyB4ZW0gdOG7iSB0cuG7jW5nIGPDoWMgdMOgaSBz4bqjbiBjw7MgcuG7p2kgcm8gdGjhuqVwIG5o4bqldCB0cm9uZyBz4buRIDEwMDAyIGRhbmggbeG7pWMgxJHhuqd1IHTGsCAoxJFp4buDbSBtw6B1IMSR4buPKTogDQoNCg0KYGBge3J9DQoNCmRmX3JldHVybl8xMDAwMCAlPiUgDQogIGZpbHRlcihwb3J0X2luZGV4ID09IG1pbl9yaXNrJHBvcnRfaW5kZXgpICU+JSANCiAgbXV0YXRlKHdlaWdodCA9IHJvdW5kKHdlaWdodCoxMDAsIDIpKSAlPiUgDQogIG11dGF0ZSh3ZWlnaHQgPSBhcy5jaGFyYWN0ZXIod2VpZ2h0KSkgJT4lIA0KICBtdXRhdGUod2VpZ2h0ID0gcGFzdGUwKHdlaWdodCwgIiUiKSkgJT4lIA0KICBzZWxlY3QoLXBvcnRfaW5kZXgpICU+JSANCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIGZ1bmN0aW9uKHgpIHtyb3VuZCh4LCAzKX0pICU+JSANCiAga2JsKGNhcHRpb24gPSAiVGFibGUgNTogTWluaW11bS12YXJpYW5jZSBQb3J0Zm9saW8iLCBlc2NhcGUgPSBUUlVFKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRkFMU0UsIGh0bWxfZm9udCA9ICJDYW1icmlhIikNCiAgDQpgYGANCg0KVsOgIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBjw7MgbOG7o2kgdOG7qWMgY2FvIG5o4bqldCAoxJFp4buDbSBtw6B1IHTDrW0pOiANCg0KYGBge3J9DQpkZl9yZXR1cm5fMTAwMDAgJT4lIA0KICBmaWx0ZXIocG9ydF9pbmRleCA9PSBtYXhfcmV0dXJuJHBvcnRfaW5kZXgpICU+JSANCiAgbXV0YXRlKHdlaWdodCA9IHJvdW5kKHdlaWdodCoxMDAsIDIpKSAlPiUgDQogIG11dGF0ZSh3ZWlnaHQgPSBhcy5jaGFyYWN0ZXIod2VpZ2h0KSkgJT4lIA0KICBtdXRhdGUod2VpZ2h0ID0gcGFzdGUwKHdlaWdodCwgIiUiKSkgJT4lIA0KICBzZWxlY3QoLXBvcnRfaW5kZXgpICU+JSANCiAgbXV0YXRlX2lmKGlzLm51bWVyaWMsIGZ1bmN0aW9uKHgpIHtyb3VuZCh4LCAzKX0pICU+JSANCiAga2JsKGNhcHRpb24gPSAiVGFibGUgNjogTWF4aW11bi1yZXR1cm4gUG9ydGZvbGlvIiwgZXNjYXBlID0gVFJVRSkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IEZBTFNFLCBodG1sX2ZvbnQgPSAiQ2FtYnJpYSIpDQoNCg0KYGBgDQoNCiMgU3VtbWFyeQ0KDQrEkGEgZOG6oW5nIGjDs2EgxJHhuqd1IHTGsCBuaOG6sW0gZ2nhuqNtIHRoaeG7g3UgcuG7p2kgcm8gbMOgIG3hu5l0IHRyb25nIG5o4buvbmcgaOG7hyBxdeG6oyBxdWFuIHRy4buNbmcgY+G7p2EgbMOtIHRodXnhur90IGRhbmggbeG7pWMgxJHhuqd1IHTGsCAoUG9ydGZvbGlvIFRoZW9yeSkuIFBo4bqnbiAxIGPhu6dhICB0csaw4bubYyBo4bq/dCDEkWnhu4NtIGzhuqFpIG5o4buvbmcgxJFp4buDbSBj4buRdCBsw7VpIGPhu6dhIGzDrSB0aHV54bq/dCBkYW5oIG3hu6VjIMSR4bqndSB0xrAgdsOgIHZp4buHYyB0w61uaCB0b8OhbiB0aGVvIG5nw7RuIG5n4buvIG1hIHRy4bqtbiB24bubaSBSIGPFqW5nIG5oxrAgY8OhY2ggdGnhur9wIGPhuq1uIHRy4buxYyBxdWFuIMSR4buDIHTDrG0gcmEgZGFuaCBt4bulYyDEkeG6p3UgdMawIGhp4buHdSBxdeG6oyAoRWZmaWNpZW50IFBvcnRmb2xpbykgYuG6sW5nIHBoxrDGoW5nIHBow6FwIG3DtCBwaOG7j25nLiBUcm9uZyB0csaw4budbmcgaOG7o3AgZGFuaCBt4bulYyDEkeG6p3UgdMawIGPDsyBuIHTDoGkgc+G6o24ga2jDoWMgbmhhdSB0aMOsIHZp4buHYyDDoXAgZOG7pW5nIHbDoCB0w61uaCB0b8OhbiB24bqrbiBraMO0bmcgY8OzIGfDrCB0aGF5IMSR4buVaS4gDQoNCsSQ4buRaSB24bubaSBjw6FjIGtow61hIGPhuqFuaCBuaMawIGzDrSB0aHV54bq/dCB24buBIFBvcnRmb2xpbyBUaGVvcnksIGPGoSBz4bufIFRvw6FuIC0gVGjhu5FuZyBLw6ovdMOtbmggdG/DoW4gbWEgdHLhuq1uIChNYXRyaXggQ2FsY3VsYXRpb24pIHbhu5tpIG5nw7RuIG5n4buvIFIgbMOgIG5o4buvbmcgbeG6o25nIGtp4bq/biB0aOG7qWMva8SpIG7Eg25nIG3DoCBuZ8aw4budaSB2aeG6v3QgYsOgaSBuw6B5IG3hurdjIMSR4buLbmggYuG6oW4gxJHhu41jIMSRw6MgbuG6r20gxJHGsOG7o2MuIELhuqFuIMSR4buNYyBxdWFuIHTDom0gY8OzIHRo4buDIHRoYW0ga2jhuqNvIGPDoWMgdMOgaSBsaeG7h3UgbGnhu4d0IGvDqiDhu58gbeG7pWMgUmVmZXJlbmNlcy4gDQoNCiMgUmVmZXJlbmNlcw0KDQoxLiBbSW52ZXN0bWVudHMgMTB0aCBFZGl0aW9uIGJ5IFp2aSBCb2RpZSwgQWxleCBLYW5lIChBdXRob3IpLCBBbGFuIEouIE1hcmN1c10oaHR0cHM6Ly93d3cuYW1hem9uLmNvbS9JbnZlc3RtZW50cy0xMHRoLVp2aS1Cb2RpZS9kcC8wMDc3ODYxNjcxKS4gDQoyLiBbTW9kZXJuIFBvcnRmb2xpbyBUaGVvcnkgYW5kIEludmVzdG1lbnQgQW5hbHlzaXMsIDl0aCBFZGl0aW9uIGJ5IEVsdG9uIGV0IGFsLl0oaHR0cHM6Ly93d3cud2lsZXkuY29tL2VuLXVzL01vZGVybitQb3J0Zm9saW8rVGhlb3J5K2FuZCtJbnZlc3RtZW50K0FuYWx5c2lzJTJDKzl0aCtFZGl0aW9uLXAtOTc4MTExODQ2OTk0MSkuIA0KMy4gW0Jhc2ljcyBvZiBNYXRyaXggQWxnZWJyYSBmb3IgU3RhdGlzdGljcyB3aXRoIFIgYnkgTmljayBGaWVsbGVyXShodHRwczovL3d3dy5hbWF6b24uY29tL0Jhc2ljcy1NYXRyaXgtQWxnZWJyYS1TdGF0aXN0aWNzLUNoYXBtYW4tZWJvb2svZHAvQjAxMTZSNDZUUS9yZWY9c3JfMV8xP2RjaGlsZD0xJmtleXdvcmRzPW1hdHJpeCtjYWxjdWxhdGlvbitpbityJnFpZD0xNjExNDkxOTY5JnM9Ym9va3Mmc3I9MS0xKQ0KDQoNCg0KDQo=