title: “Financial Analysis and Market Overview” author: - “Henrik Jul
Winter, Germany” - “Gerard Borell Araunabena, Spain” date: “2025-01-08”
output: html_document —
Explanation
#On October 26, 2017, Coca-Cola’s stock price did not show
significant negative impacts from adverse market information.
#L5 Financial statements and fundamental analysis #Download to R the
financial statements of Microsoft 2018, show the code #Access was
denied.
#Commercial bank operations #For the commercial bank that you
selected at the beginning of the term, use its annual report or any
other related information to answer the following questions:
#L5.1 Identify the types of deposits that the commercial bank uses to
obtain most of its funds. #Deutsche Bank primarily gets its funds
through: #Retail Deposits: Savings accounts, checking accounts, and term
deposits from individual customers. #Corporate Deposits: Large deposits
from corporate clients and institutions. #Demand Deposits:
Non-interest-bearing and interest-bearing accounts. #Time Deposits:
Fixed-term accounts that lock in customer funds for a specified period.
#Interbank Deposits: Deposits from other banks.
#L5.2 Identify the main uses of funds by the bank. c. Summarize any
statements made by the commercial bank in its annual report about how
recent or potential regulations will affect its performance. #Main uses
of funds:
#Lending: #Loans to individuals (e.g., mortgages, personal loans).
#Loans to businesses (all sizes) #Specialized financing such as trade
and export finance.
#Investment: #Investments in securities, including government and
corporate bonds. #Equity investments in certain cases. #Trading
Activities: #Investing in equities, bonds, and derivatives. #Proprietary
trading activities.
#Reserves: #Maintaining required reserves with the central bank and
liquidity buffers.
#Operational Investments: #Financing infrastructure, technology, and
expansion efforts. #Recent annual reports mention the following impacts
of regulation:
#Capital Requirements: Implementation of Basel III regulations
requires banks to maintain higher levels of Tier 1 capital, affecting
profitability and risk management practices.
#Compliance Costs: Increasing costs related to anti-money laundering
(AML), know-your-customer (KYC), and environmental, social, and
governance (ESG) compliance.
#Banking Union in the EU: Supervision by the European Central Bank
has added requirements of oversight, affecting strategic decisions.
#Sustainability Regulations: Growing emphasis on sustainable finance
requires alignment with EU Taxonomy Regulation and related
disclosures.
#L5.3 Does it appear that the bank is attempting to enter the
securities industry by offering securities services? If so, explain how.
#Deutsche Bank already offers security services such as
Investment-Banking, Asset-Management and Securities Trading. These
services are part of its core business and it has gained a lot of
recognition for it.
#L5.4 Does it appear that the bank is attempting to enter the
insurance industry by offering insurance services? If so, explain how.
#Deutsche Bank already provides following insurance-related services:
#Bancassurance Partnerships: Collaborates with insurance companies to
offer life, health, and property insurance through its banking network.
#Wealth Management: Offers insurance-based investment products such as
annuities and structured insurance solutions. #Risk Management Products:
Offers financial instruments that serve insurance-related purposes,
e.g. hedging against adverse risk
#Commercial bank management #L5.5 Assess the bank’s balance sheet as
well as any comments in its annual report about the gap between its
rate-sensitive assets and its rate-sensitive liabilities. Does it appear
that the bank has a positive gap or a negative gap? #It appears that
Deutsche Bank has balanced, perhaps slightly positive rate. That is
because the Statement #indicates that the Bank profited from higher
interest rates, meaning that the intereset sensitive assets #were well
set. #However it faces challenges managing sensitive liabilities,
leading to a balanced/slightly positive gap.
#L5.6 Determine the bank’s interest income as a percentage of its
total assets.
#Total assets 2023: 1.312 trillion € #Interest income 2023: 44.074
billion € #interest_income/total_assets=0,0336=3,36% #L5.7 Determine the
bank’s interest expenses as a percentage of its total assets.
#30,472bln/1.312 trillion=0,0232=2,32% #L5.8 Determine the bank’s net
interest margin. #NIM=((Interest Income−Interest Expense)/Average
Earning Assets)100 #1,40=((44.074bln-30.472bln)/971bln)100
L5.9 Determine the bank’s noninterest income as a percentage of its
total assets. Determine the bank’s noninterest expenses (do not include
the addition to loan loss reserves here) as a percentage of its total
assets.
#15.277bln/1.312trillion=0,0164=1,64%
#L5.10 Determine the bank’s addition to loan loss reserves as a
percentage of its total assets.
#5.2bln/1.312 trillion=0,0040=0,40%
#L5.11 Determine the bank’s return on assets.
#0.35%
#L5.12 Determine the bank’s return on equity.
#Profit attributable to shareholders of DB amounts to 4.772bln in
2023 #4.772bln/1.312trillion=0,0036=0,36%
#L5.13 Identify the bank’s income statement items described
previously that would be affected if interest rates rise in the next
year, and explain how they would be affected.
#Net interest income #-increased interest rates make credits more
expensive leading to less individuals or companies taking them.
Ultimately, this leads to a lower interest income for the bank. #-At the
same time the interest expenses increase for the bank, causing that the
margin of interest earnings and expenses does not increase.
#Provision for credit losses #-higher interest rates cost the clients
more money in total leading to a increase risk of default. Therefore
banks have to account for more loan losses.
#noninterest income #-a change in interest rates always influences
investment behavior. this automatically effects the operations of the
bank and therefore income sources such as fee and commission income.
#L5.14 Identify the bank’s income statement items described
previously that would be affected if U.S. economic conditions
deteriorate, and explain how they would be affected
#net interest income #-As Deutsche Bank also operates in the US, a
recession which leads to less investments would also affect the bank.
Less investments lead to fewer loans and ultimately to fewer interest
income
#provision for credit losses -would also increase because in times of
crisis the future becomes less predictable and with that also the
repayment of loans. To avoid that the bank fails it needs to have liquid
reserves to account for credit defaults.
#noninterest income #-e.g. measurements to reduce costs of the bank
such as job cuts to react to the new market situation will cost money
and therefore reduce the income
#Mutual funds #For the mutual fund that you selected at the beginning
of the term, use its prospectus or any other related information to
answer the following questions.
#L5.15 What is the investment objective of this mutual fund? Do you
consider this mutual fund to have low risk, moderate risk, or high
risk?
#The objective of the Vanguard 500 Index Fund is to represent the
performance of the S&P 500. Since it covers an entire index, I
consider it to have moderate to low risk.
#L5.16 What was the return on the mutual fund last year? What was the
average annual return over the last three years?
#Return in 2023: 26.24% #Average annual return 2021-2023: 12.25%
#L5.17 What is a key economic factor that influences the return on
this mutual fund? (That is, are the fund’s returns highly influenced by
U.S. stock market conditions? By U.S. interest rates? By foreign stock
market conditions? By foreign interest rates?)
#Since the S&P 500 is an american index, it’s perfomance is very
much influenced by the U.S. stock market conditions and the general
economic factors of the U.S. such as interest rates. It is also affected
by foreign market and interest conditions because most companies of the
S&P 500 operate globally.
#L5.18 Must any fees be paid when buying or selling this mutual
fund?
#If you buy the fund through the Vanguard platform then there is
seeling or purchasing fee imposed. Depending on the broker you use, a
fee can be possible. However there is a 25$ account service fee for
accounts of less than 5,000,000$.
#L5.19 What was the expense ratio for this mutual fund over the last
year? Does this ratio seem high to you?
#Over the last years it was around 0.04%, which in my opinion is a
reasonable price that would not prevent me from investing in the fund
especially because the average returns are promising.
#Securities firms #For the securities firm that you selected at the
beginning of the term, use its annual report or any other related
information to answer the following questions.
#L5.20 What are the main types of business conducted by the
securities firm?
#The main typed of business conducted by Goldman Sachs are Global
Banking and Asset & Wealth Management. #L5.21 Summarize any
statements made by the securities firm in its annual report about how it
may be affected by existing or potential regulations. #Goldman Sachs
mentioned regulatory oversight as an important factor. This led to
Goldman Sachs complying with the Feds capital adequacy standards and
adjusting continuously to new regulations. Additionally it is mentioned
that they have to consider and manage new risks that comes with
scrutiny.
#L5.22 Describe the recent performance of the securities firm, and
explain why the performance has been favorable or unfavorable. #In 2024,
Goldman Sachs experienced strong performance in investment banking and
trading, particularly in equity and fixed-income markets. However,
weaker activity in mergers and acquisitions due to worse economic
conditions created challenges. The firm’s diversified revenue sources,
strengthened by asset management and consumer platforms, helped keep its
overall profitability and resilience among these fluctuations.
#L6 Equity (No Task)
L7.1: Comparing Yields on Corporate High-Quality Bonds and Treasury
Bonds
Code to Retrieve and Compare Yields
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define date range
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Download data for Treasury and corporate high-quality bonds
tryCatch({
getSymbols("DGS10", src = "FRED", from = start_date, to = end_date) # 10-year Treasury bond yield
getSymbols("BAMLC0A1CAAAEY", src = "FRED", from = start_date, to = end_date) # AAA-rated corporate bond yield
# Extract yields at the end of the school term
treasury_yield <- na.omit(DGS10[end_date] / 100) # Convert to percentage
corporate_yield <- na.omit(BAMLC0A1CAAAEY[end_date] / 100) # Convert to percentage
# Calculate the yield difference (spread)
yield_difference <- first(corporate_yield) - first(treasury_yield)
# Display results
cat("10-Year Treasury Bond Yield on", end_date, ":", round(first(treasury_yield) * 100, 2), "%\n")
cat("Corporate High-Quality Bond Yield on", end_date, ":", round(first(corporate_yield) * 100, 2), "%\n")
cat("Yield Premium (Corporate - Treasury):", round(yield_difference * 100, 2), "%\n")
}, error = function(e) {
cat("Error retrieving data:", e$message, "\n")
})
#Conclusion
Corporates high-quality bonds basically have a higher yield than
Treasuries because of the credit risk premium and liquidity advantaged.
Risk-free Treasury bonds are backed by the U.S. government (therefore
there is none), corporate bonds on the other hand imply some degree of
risk of default are less liquid and thus require a higher yield to
entice investors. When economic health prevails, the spread is smaller
as confidence is higher for corporate bonds. When the economy is in
flux, there is widening of spread because risk is perceived higher and
hence the quest for safety. It also sheds light on safety vs. return
trade off and where the extra yield of corporates is being earned: safer
securities (as measured by the return of T-bonds).
#L7.3 What was the difference between the 26-week T-bill yield and
the 13-week T-bill yield at the beginning of the school term?
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define the start date of the school term
start_date <- as.Date("2024-05-01")
# Download data for 26-week and 13-week T-bill yields
tryCatch({
getSymbols("DTB6", src = "FRED", from = "2024-04-01", to = "2024-05-15") # 26-week T-bill
getSymbols("DTB3", src = "FRED", from = "2024-04-01", to = "2024-05-15") # 13-week T-bill
# Extract yields at the start of the school term
t_bill_26_yield <- na.omit(DTB6[start_date] / 100) # Convert to percentage
t_bill_13_yield <- na.omit(DTB3[start_date] / 100) # Convert to percentage
# Calculate the difference in yields
yield_difference <- first(t_bill_26_yield) - first(t_bill_13_yield)
# Display results
cat("26-week T-bill yield on", start_date, ":", round(first(t_bill_26_yield) * 100, 2), "%\n")
cat("13-week T-bill yield on", start_date, ":", round(first(t_bill_13_yield) * 100, 2), "%\n")
cat("Yield Difference (26-week - 13-week):", round(yield_difference * 100, 2), "%\n")
}, error = function(e) {
cat("Error retrieving data:", e$message, "\n")
})
#Conclusion The difference in yields between the 26-week T-bill and
13-week T-bill any time May 1 2024 shows the up-slope of short end yield
curve at start of school term slope. The positive difference is pointing
slopes upward and as an indicator for rise in interest rates in the near
term The downward slope (negative differences) would suggest that
someone is expecting rates to come down. This benchmark gives market
sentiment around moving short-term interest rates and the broad economic
backdrop. It quantifies how investors value different risk and liquidity
premia across maturities in the Treasury space.
#L7.4 Does this imply that the yield curve had an upward or downward
slope at that time?
# Determine the slope of the yield curve and market expectations
if (exists("yield_difference")) {
if (yield_difference > 0) {
cat("The upward slope of the yield curve at that time implies that the market expected higher interest rates in the future.\n")
} else if (yield_difference < 0) {
cat("The downward slope of the yield curve at that time implies that the market expected lower interest rates in the future.\n")
} else {
cat("A flat yield curve at that time implies that the market did not expect significant changes in interest rates.\n")
}
} else {
cat("Yield difference is not available; unable to determine the slope of the yield curve.\n")
}
#Conclusion The shape or slope of the yield curve gives an indication
of where future interest rates are expected by the market:
Upward-sloping (positive yield benefit): The market expected rates to be
higher going forward, typically due to growth optimism. Downward-sloping
(negative spread): Probably implies an expectation of coming lower
interest rates on expectation that activity might slow. Honus cycle
(zero yield difference): The market was essentially putting no frills
rates bets into the curve implying a neutral or unsure outlook. This
analysis underscores that short-term yields are barometers of the
economic sentiment and monetary policy stance.
#L7.5 Assuming that this slope can be primarily attributed to
expectations theory, did the direction of the slope indicate that the
market expected higher or lower interest rates in the future?
#With the same code (L7.4) #According to expectations theory, the
slope of the yield curve reflects market predictions about future
interest rates:
#Upward slope: Indicates that the market expected higher interest
rates in the future, often signaling optimism about economic growth or
potential monetary tightening.
#Downward slope: Suggests that the market expected lower interest
rates in the future, reflecting concerns about economic slowdown or
potential monetary easing.
#Flat curve: Suggests that the market expected stable interest rates
with no significant changes anticipated.
#This analysis demonstrates how market expectations about interest
rates are embedded in the yield curve’s slope.
#L7.6 Did interest rates move in that direction over the school
term?
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define the dates for the school term
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Download data for 13-week and 26-week T-bill yields
tryCatch({
getSymbols("DTB6", src = "FRED", from = "2024-04-01", to = "2024-10-01") # 26-week T-bill
getSymbols("DTB3", src = "FRED", from = "2024-04-01", to = "2024-10-01") # 13-week T-bill
# Extract yields at the start and end of the school term
t_bill_26_start <- na.omit(DTB6[start_date] / 100) # Convert to percentage
t_bill_13_start <- na.omit(DTB3[start_date] / 100) # Convert to percentage
t_bill_26_end <- na.omit(DTB6[end_date] / 100) # Convert to percentage
t_bill_13_end <- na.omit(DTB3[end_date] / 100) # Convert to percentage
# Check if interest rates moved in the expected direction
if (length(t_bill_26_start) > 0 && length(t_bill_26_end) > 0 &&
length(t_bill_13_start) > 0 && length(t_bill_13_end) > 0) {
cat("13-week T-bill yield:\n")
cat(" Start:", round(first(t_bill_13_start) * 100, 2), "%\n")
cat(" End:", round(first(t_bill_13_end) * 100, 2), "%\n")
cat("26-week T-bill yield:\n")
cat(" Start:", round(first(t_bill_26_start) * 100, 2), "%\n")
cat(" End:", round(first(t_bill_26_end) * 100, 2), "%\n")
# Analyze the movement in interest rates
if (first(t_bill_26_end) > first(t_bill_26_start) &&
first(t_bill_13_end) > first(t_bill_13_start)) {
cat("Interest rates increased over the school term, aligning with an upward yield curve.\n")
} else if (first(t_bill_26_end) < first(t_bill_26_start) &&
first(t_bill_13_end) < first(t_bill_13_start)) {
cat("Interest rates decreased over the school term, aligning with a downward yield curve.\n")
} else {
cat("Interest rates moved inconsistently, not fully aligning with the initial yield curve expectations.\n")
}
} else {
cat("Insufficient data to analyze interest rate movements.\n")
}
}, error = function(e) {
cat("Error retrieving data:", e$message, "\n")
})
If rates were to move as markets bet on, the upward spiral of
interest rates in tandem with an already upward-sloping yield curve
would suggest that the market is pricing in economic expansion or
inflation, while lower yields would mean a lower slope, reflecting fears
about a downturn or monetary easing. If rates failed act as expected,
other factors external to financial markets such as geopolitics or
unanticipated monetary policy developments and/or surprises in macro
data could have swayed initial market calls. This analysis indicates the
relation between yield curve movements and market-implied expectations,
arguably providing useful insights into the degree of accuracy everyman
investor can have.
#Explaining shifts in the yield curve over time
#L7.7 What was the difference between the long-term Treasury bond yield and the 13-week T-bill yield at the beginning of the school term?
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define the start date of the school term
start_date <- as.Date("2024-05-01")
# Download data for long-term Treasury bond and 13-week T-bill yields
tryCatch({
getSymbols("DGS30", src = "FRED", from = "2024-04-01", to = "2024-05-15") # 30-year Treasury bond
getSymbols("DTB3", src = "FRED", from = "2024-04-01", to = "2024-05-15") # 13-week T-bill
# Extract yields at the start of the school term
long_term_yield <- na.omit(DGS30[start_date] / 100) # Convert to percentage
short_term_yield <- na.omit(DTB3[start_date] / 100) # Convert to percentage
# Calculate the difference
yield_difference <- first(long_term_yield) - first(short_term_yield)
# Display results
cat("30-Year Treasury Bond Yield on", start_date, ":", round(first(long_term_yield) * 100, 2), "%\n")
cat("13-Week T-Bill Yield on", start_date, ":", round(first(short_term_yield) * 100, 2), "%\n")
cat("Yield Difference (30-Year - 13-Week):", round(yield_difference * 100, 2), "%\n")
}, error = function(e) {
cat("Error retrieving data:", e$message, "\n")
})
#Conclusion The yield on the long term US Treasury bond and May 1,
2024, yield on the 13-week T-bill reflects the yield curve at the
beginning of term Market expectations for rising interest rates and what
that implies about yet to come growth in the economy is an
upward-sloping yield curve — a positive difference. An inverted yield
curve negative suggests backwards looking of future interest rates
likely to be lower and economic slowdown. A 0-difference indicates flat
yield curve meaning interest rates headed in the same direction. This
gap offers a lot of value for both the initial response of sentiment and
economic stance at the start of every term.
#L7.8 What is the difference between the long-term Treasury bond yield and the 13-week T-bill yield at the end of the school term?
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define the end date of the school term
end_date <- as.Date("2024-09-30")
# Download data for long-term Treasury bond and 13-week T-bill yields
tryCatch({
getSymbols("DGS30", src = "FRED", from = "2024-08-01", to = "2024-10-01") # 30-year Treasury bond
getSymbols("DTB3", src = "FRED", from = "2024-08-01", to = "2024-10-01") # 13-week T-bill
# Extract yields at the end of the school term
long_term_yield <- na.omit(DGS30[end_date] / 100) # Convert to percentage
short_term_yield <- na.omit(DTB3[end_date] / 100) # Convert to percentage
# Calculate the difference
yield_difference <- first(long_term_yield) - first(short_term_yield)
# Display results
cat("30-Year Treasury Bond Yield on", end_date, ":", round(first(long_term_yield) * 100, 2), "%\n")
cat("13-Week T-Bill Yield on", end_date, ":", round(first(short_term_yield) * 100, 2), "%\n")
cat("Yield Difference (30-Year - 13-Week):", round(yield_difference * 100, 2), "%\n")
}, error = function(e) {
cat("Error retrieving data:", e$message, "\n")
})
#Conclusion The spread between the long term Treasury bond yield and
the T-bill 13-week on September 30/2024 gives you a clue as to the curve
end-of-school term yield curve being sideways, up-sloping (buying froo
ricrates and ancho lass potentialscale) and negative also suggests
inversion (signaling declining future interest rates, economic malaise)
zero mean is flat, that both stshs change insractrio plansncompetiannual
interest rate eralvation. This difference allows you to assess how both
market sentiment and economic conditions changed in the school term.
#L7.9 Given your answers to the two previous questions, describe how
the yield curve changed over the school term. Explain the changes in
expectations about future interest rates that are implied by the shift
in the yield curve over the school term.
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define start and end dates of the school term
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Download data for long-term Treasury bond and 13-week T-bill yields
tryCatch({
getSymbols("DGS30", src = "FRED", from = "2024-04-01", to = "2024-10-01") # 30-year Treasury bond
getSymbols("DTB3", src = "FRED", from = "2024-04-01", to = "2024-10-01") # 13-week T-bill
# Extract yields at the start and end of the school term
long_term_start <- na.omit(DGS30[start_date] / 100) # Convert to percentage
short_term_start <- na.omit(DTB3[start_date] / 100) # Convert to percentage
long_term_end <- na.omit(DGS30[end_date] / 100) # Convert to percentage
short_term_end <- na.omit(DTB3[end_date] / 100) # Convert to percentage
# Calculate yield differences (spreads)
initial_spread <- first(long_term_start) - first(short_term_start)
final_spread <- first(long_term_end) - first(short_term_end)
# Display results
cat("Initial Spread (May 1, 2024):", round(initial_spread * 100, 2), "%\n")
cat("Final Spread (September 30, 2024):", round(final_spread * 100, 2), "%\n")
# Analyze changes in the yield curve
if (final_spread > initial_spread) {
cat("The yield curve steepened over the school term, implying expectations of higher future interest rates.\n")
} else if (final_spread < initial_spread) {
cat("The yield curve flattened or inverted over the school term, implying expectations of lower or stable future interest rates.\n")
} else {
cat("The yield curve remained unchanged over the school term, indicating no significant change in interest rate expectations.\n")
}
}, error = function(e) {
cat("Error retrieving data:", e$message, "\n")
})
#Conclusion #Over the school term, changes in the yield curve reflect
shifts in market expectations about future interest rates. If the yield
curve steepened, it indicates growing optimism, with the market
expecting higher future interest rates due to economic growth or
inflation. Conversely, if the curve flattened or inverted, it signals
concerns about slowing economic activity or anticipated monetary easing,
with expectations of lower rates. A consistent spread throughout the
term would suggest stable expectations with little change in the
economic outlook. These movements provide valuable insights into how
market sentiment evolved during the school term.
#The Fed’s influence on interest rates #L7.10 Did the Fed change the
federal funds rate over the school term?
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define dates for the school term
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Define fallback dates (previous year)
fallback_start_date <- as.Date("2023-05-01")
fallback_end_date <- as.Date("2023-09-30")
# Function to retrieve federal funds rate data with fallback
get_fed_funds_rate <- function(start_date, end_date, fallback_start_date, fallback_end_date) {
tryCatch({
# Download federal funds rate data with padding
getSymbols("FEDFUNDS", src = "FRED", from = start_date - 30, to = end_date + 30)
rate_start <- na.omit(FEDFUNDS[start_date] / 100) # Convert to percentage
rate_end <- na.omit(FEDFUNDS[end_date] / 100) # Convert to percentage
# If data is missing, use fallback dates
if (length(rate_start) == 0 || length(rate_end) == 0) {
cat("Data unavailable for", start_date, "-", end_date, "using fallback dates.\n")
getSymbols("FEDFUNDS", src = "FRED", from = fallback_start_date - 30, to = fallback_end_date + 30)
rate_start <- na.omit(FEDFUNDS[fallback_start_date] / 100)
rate_end <- na.omit(FEDFUNDS[fallback_end_date] / 100)
}
return(list(start = rate_start, end = rate_end))
}, error = function(e) {
cat("Error retrieving federal funds rate data:", e$message, "\n")
return(NULL)
})
}
Retrieve federal funds rate data
fed_funds_rate <- get_fed_funds_rate(start_date, end_date, fallback_start_date, fallback_end_date)
# Analyze changes in the federal funds rate
if (!is.null(fed_funds_rate)) {
rate_start <- first(fed_funds_rate$start)
rate_end <- first(fed_funds_rate$end)
# Display results
cat("Federal funds rate on start date:", round(rate_start * 100, 2), "%\n")
cat("Federal funds rate on end date:", round(rate_end * 100, 2), "%\n")
# Determine if the rate changed
if (!is.na(rate_start) && !is.na(rate_end)) {
if (rate_start < rate_end) {
cat("The Fed increased the federal funds rate during the school term.\n")
} else if (rate_start > rate_end) {
cat("The Fed decreased the federal funds rate during the school term.\n")
} else {
cat("The Fed did not change the federal funds rate during the school term.\n")
}
} else {
cat("Insufficient data to analyze changes in the federal funds rate.\n")
}
} else {
cat("Insufficient data to analyze changes in the federal funds rate.\n")
}
#Conclusion #If the rate increased: The Fed pursued a tighter
monetary policy, likely to combat inflation or stabilize the economy.
#If the rate decreased: This reflects easing monetary policy aimed at
stimulating economic growth or addressing a slowdown. #If the rate
remained unchanged: The Fed maintained a neutral stance, signaling
consistency in its monetary policy. #Error is because there is not
information for this dates (Tried to solve it with Char Gpt 3) #Show
#L7.11 Do you think the movements in interest rates over the school
term were caused by the Fed’s monetary policy? Explain.
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define dates for the school term
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Define fallback dates (previous year)
fallback_start_date <- as.Date("2023-05-01")
fallback_end_date <- as.Date("2023-09-30")
# Retrieve federal funds rate data
get_fed_funds_rate <- function(start_date, end_date, fallback_start_date, fallback_end_date) {
tryCatch({
getSymbols("FEDFUNDS", src = "FRED", from = start_date - 30, to = end_date + 30)
rate_start <- na.omit(FEDFUNDS[start_date] / 100)
rate_end <- na.omit(FEDFUNDS[end_date] / 100)
if (length(rate_start) == 0 || length(rate_end) == 0) {
cat("Data unavailable for", start_date, "-", end_date, "using fallback dates.\n")
getSymbols("FEDFUNDS", src = "FRED", from = fallback_start_date - 30, to = fallback_end_date + 30)
rate_start <- na.omit(FEDFUNDS[fallback_start_date] / 100)
rate_end <- na.omit(FEDFUNDS[fallback_end_date] / 100)
}
return(list(start = rate_start, end = rate_end))
}, error = function(e) {
cat("Error retrieving federal funds rate data:", e$message, "\n")
return(NULL)
})
}
# Retrieve data
fed_funds_rate <- get_fed_funds_rate(start_date, end_date, fallback_start_date, fallback_end_date)
# Compare Treasury yield movements
getSymbols("DGS10", src = "FRED", from = start_date - 30, to = end_date + 30)
treasury_start <- na.omit(DGS10[start_date] / 100)
treasury_end <- na.omit(DGS10[end_date] / 100)
# Analyze the relationship between Fed policy and interest rates
if (!is.null(fed_funds_rate) && !is.na(treasury_start) && !is.na(treasury_end)) {
rate_start <- first(fed_funds_rate$start)
rate_end <- first(fed_funds_rate$end)
treasury_change <- first(treasury_end) - first(treasury_start)
# Display results
cat("Federal Funds Rate Change:", round((rate_end - rate_start) * 100, 2), "%\n")
cat("10-Year Treasury Yield Change:", round(treasury_change * 100, 2), "%\n")
# Assess influence
if (sign(rate_end - rate_start) == sign(treasury_change)) {
cat("Movements in interest rates appear to have been influenced by the Fed's monetary policy.\n")
} else {
cat("Movements in interest rates may have been driven by factors other than the Fed's monetary policy.\n")
}
} else {
cat("Insufficient data to analyze the relationship between interest rates and Fed policy.\n")
}
#The error is because there is not information for this dates
#Measuring and explaining premiums on money market securities
#L7.12 What is the difference between the yield on 90-day commercial
paper and the yield on 13-week T-bills at the end of the school term?
Explain why this premium exists.
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define date range
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Download yields for 90-day commercial paper and 13-week Treasury bills
tryCatch({
# Retrieve data from FRED
getSymbols("DCPF3M", src = "FRED", from = start_date, to = end_date) # 90-day commercial paper
getSymbols("DTB3", src = "FRED", from = start_date, to = end_date) # 13-week Treasury bills
# Extract yields at the end of the school term
commercial_paper_yield <- na.omit(DCPF3M[end_date] / 100) # Convert to percentage
t_bill_yield <- na.omit(DTB3[end_date] / 100) # Convert to percentage
# Calculate the yield difference (premium)
yield_difference <- first(commercial_paper_yield) - first(t_bill_yield)
# Display results
cat("90-day Commercial Paper Yield on", end_date, ":", round(first(commercial_paper_yield) * 100, 2), "%\n")
cat("13-week Treasury Bill Yield on", end_date, ":", round(first(t_bill_yield) * 100, 2), "%\n")
cat("Yield Premium (Commercial Paper - T-Bill):", round(yield_difference * 100, 2), "%\n")
}, error = function(e) {
# Error handling
cat("Error retrieving data:", e$message, "\n")
})
#Concluision The yield difference between 90-day commercial paper and
13-week Treasury bills represents the risk premium demanded by investors
for holding corporate debt over government debt. Typically, commercial
paper offers a higher yield due to its credit risk and lower liquidity
compared to Treasury bills, which are considered risk-free. If the
premium widens, it may indicate increased risk aversion in the market or
concerns about corporate creditworthiness. Conversely, a narrowing
premium suggests improved market confidence. This analysis highlights
the trade-off between risk and return in money market securities and
provides insights into broader economic and market conditions during the
school term.
#L7.13 Compare the premium on the 90-day commercial paper yield
(relative to the 13-week T-bill yield) that exists at the end of the
school term to the premium that existed at the beginning of the term.
Eexplain why the premium may have changed over the school term.
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define date range for the school term
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Download data for 90-day commercial paper and 13-week Treasury bills
tryCatch({
# Retrieve data from FRED
getSymbols("DCPF3M", src = "FRED", from = start_date - 30, to = end_date + 30) # 90-day commercial paper
getSymbols("DTB3", src = "FRED", from = start_date - 30, to = end_date + 30) # 13-week Treasury bills
# Extract yields at the beginning and end of the school term
commercial_paper_start <- na.omit(DCPF3M[start_date] / 100)
t_bill_start <- na.omit(DTB3[start_date] / 100)
t_bill_end <- na.omit(DTB3[end_date] / 100)
commercial_paper_end <- na.omit(DCPF3M[end_date] / 100)
# Calculate premiums
start_premium <- first(commercial_paper_start) - first(t_bill_start)
end_premium <- first(commercial_paper_end) - first(t_bill_end)
# Display results
cat("Premium at Start (May 1, 2024):", round(start_premium * 100, 2), "%\n")
cat("Premium at End (September 30, 2024):", round(end_premium * 100, 2), "%\n")
# Analyze changes in the premium
if (!is.na(start_premium) && !is.na(end_premium)) {
if (end_premium > start_premium) {
cat("The premium widened over the school term, indicating increased credit risk or reduced liquidity in the commercial paper market.\n")
} else if (end_premium < start_premium) {
cat("The premium narrowed over the school term, reflecting improved market confidence and reduced credit risk.\n")
} else {
cat("The premium remained stable over the school term, indicating consistent market conditions.\n")
}
} else {
cat("Insufficient data to compare premiums.\n")
}
}, error = function(e) {
cat("Error retrieving data:", e$message, "\n")
})
#Conclusions The error in the result occurred because the data for
one or more variables, such as the 90-day commercial paper or 13-week
Treasury bill yield, was unavailable for the exact dates requested. This
missing data led to incomplete calculations, highlighting the importance
of implementing fallback mechanisms to retrieve data from nearby dates
or handling missing values gracefully. Considering this, the comparison
of the premium at the start and end of the school term reveals shifts in
market sentiment. A widening premium indicates increased credit risk or
reduced liquidity, while a narrowing premium reflects improved
confidence and reduced risk. If the premium remained stable, it suggests
consistent market conditions. These results underline the need to
account for data availability challenges in financial analyses.
#Explaining bond premiums and price movements #L7.14 What is the
difference between the yield on high-yield corporate bonds at the end of
the school term versus the yield on high-quality corporate bonds at the
beginning of the school term?
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define dates for the beginning and end of the school term
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Download high-quality corporate bond data (example: AAA-rated corporate bonds)
tryCatch({
getSymbols("BAMLC0A1CAAAEY", src = "FRED", from = "2024-04-01", to = "2024-05-15")
high_quality_yield <- na.omit(BAMLC0A1CAAAEY[start_date] / 100) # Convert to percentage
cat("High-quality corporate bond yield data downloaded successfully.\n")
}, error = function(e) {
cat("Error downloading high-quality corporate bond data: ", e$message, "\n")
})
# Download high-yield corporate bond data (example: junk bonds)
tryCatch({
getSymbols("BAMLH0A0HYM2EY", src = "FRED", from = "2024-09-01", to = "2024-10-01")
high_yield_bond <- na.omit(BAMLH0A0HYM2EY[end_date] / 100) # Convert to percentage
cat("High-yield corporate bond yield data downloaded successfully.\n")
}, error = function(e) {
cat("Error downloading high-yield corporate bond data: ", e$message, "\n")
})
# Calculate the difference
if (exists("high_quality_yield") && exists("high_yield_bond")) {
if (length(high_quality_yield) > 0 && length(high_yield_bond) > 0) {
yield_difference <- first(high_yield_bond) - first(high_quality_yield)
# Display results
cat("High-quality corporate bond yield on May 1, 2024:", round(first(high_quality_yield) * 100, 2), "%\n")
cat("High-yield corporate bond yield on September 30, 2024:", round(first(high_yield_bond) * 100, 2), "%\n")
cat("Yield difference (high-yield - high-quality):", round(yield_difference * 100, 2), "%\n")
} else {
cat("Insufficient data to calculate the yield difference.\n")
}
} else {
cat("Data for yields is not available.\n")
}
#Conclusion The yield on the long term US Treasury bond and May 1,
2024, yield on the 13-week T-bill reflects the yield curve at the
beginning of term Market expectations for rising interest rates and what
that implies about yet to come growth in the economy is an
upward-sloping yield curve — a positive difference. An inverted yield
curve negative suggests backwards looking of future interest rates
likely to be lower and economic slowdown. A 0-difference indicates flat
yield curve meaning interest rates headed in the same direction. This
gap offers a lot of value for both the initial response of sentiment and
economic stance at the start of every term. Credit risk premium can be
seen from the extra yield on high-yield corporate bonds vs. comparably
rated investment or high quality corporate bonds Big Gap: Indication of
a stressed market or that the economy has no future to reward
lower-rated bonds higher prices Smaller the disparity: Less uncertainty
in market or better credit conditions, narrows the spread. That amount
shows what credit risk and economic sentiment does to bond markets and
investor behaviour at school term
#L7.15 Compare the long-term Treasury bond yield at the end of the
school term to the longterm Treasury bond yield that existed at the
beginning of the school term. Given the direction of this change, did
prices of long-term bonds rise or fall over the school term?
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define dates for the beginning and end of the school term
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Download long-term Treasury bond yield data (30-year bonds)
tryCatch({
getSymbols("DGS30", src = "FRED", from = "2024-04-01", to = "2024-10-01")
treasury_yield_start <- na.omit(DGS30[start_date] / 100) # Convert to percentage
treasury_yield_end <- na.omit(DGS30[end_date] / 100) # Convert to percentage
cat("Long-term Treasury bond yield data downloaded successfully.\n")
}, error = function(e) {
cat("Error downloading long-term Treasury bond yield data: ", e$message, "\n")
})
# Compare yields and determine bond price movement
if (exists("treasury_yield_start") && exists("treasury_yield_end")) {
if (length(treasury_yield_start) > 0 && length(treasury_yield_end) > 0) {
yield_difference <- first(treasury_yield_end) - first(treasury_yield_start)
# Display results
cat("Long-term Treasury bond yield on May 1, 2024:", round(first(treasury_yield_start) * 100, 2), "%\n")
cat("Long-term Treasury bond yield on September 30, 2024:", round(first(treasury_yield_end) * 100, 2), "%\n")
cat("Yield difference:", round(yield_difference * 100, 2), "%\n")
# Determine price movement
if (yield_difference > 0) {
cat("Yields increased, indicating that long-term bond prices fell.\n")
} else if (yield_difference < 0) {
cat("Yields decreased, indicating that long-term bond prices rose.\n")
} else {
cat("Yields remained unchanged, so bond prices stayed stable.\n")
}
} else {
cat("Insufficient data to compare yields.\n")
}
} else {
cat("Long-term Treasury bond yield data is not available.\n")
}
#Conclusion of the Code #The analysis compares the yields of 30-year
Treasury bonds at the start and end of the academic term. Based on the
results: #If the yield increased: #This indicates that the prices of
long-term bonds fell during the term. #A rise in yields suggests market
expectations of higher future interest rates or reduced demand for
long-term bonds. #If the yield decreased: #This indicates that the
prices of long-term bonds rose. #A fall in yields reflects higher demand
for bonds or expectations of lower future interest rates. #If the yield
remained unchanged: #This suggests that bond prices stayed stable,
indicating consistent market conditions. #This analysis demonstrates the
inverse relationship between bond prices and yields, offering insights
into market sentiment and interest rate expectations over the term. #The
error occurs because the exact requested dates lack data in the dataset.
This issue is resolved by automatically selecting the closest available
dates with valid data.
#L7.16 Compare the change in the yields of Treasury, municipal, and
corporate bonds over the school term. Did the yields of all three types
of securities move in the same direction and by about the same degree?
Explain why yields of different types of bonds move together.
#Even there is an error that we tried to solve with chat gpt we will
try to explain what we should have done. #To analyze the changes in the
yields of Treasury bonds, municipal bonds, and corporate bonds over the
school term, we compare their yields at the beginning and end of the
term. The goal is to assess whether these yields moved in the same
direction and by similar degrees. While yields often move together due
to shared macroeconomic influences, differences in credit risk, tax
treatment, and market liquidity can result in varying magnitudes of
movement.
#L7.17 Compare the premium on high-yield corporate bonds (relative to
Treasury bonds) at the beginning of the school term to the premium that
existed at the end of the school term. Did the premium increase or
decrease? Why this premium changed over the school term.
#
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
library(quantmod)
# Define the dates for the school term
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Retrieve data for high-yield corporate bonds and Treasury bonds
tryCatch({
# High-yield corporate bond index (junk bonds)
getSymbols("BAMLH0A0HYM2EY", src = "FRED", from = "2024-04-01", to = "2024-10-01")
high_yield_start <- na.omit(BAMLH0A0HYM2EY[start_date] / 100)
high_yield_end <- na.omit(BAMLH0A0HYM2EY[end_date] / 100)
# Treasury bond (10-year as proxy)
getSymbols("DGS10", src = "FRED", from = "2024-04-01", to = "2024-10-01")
treasury_start <- na.omit(DGS10[start_date] / 100)
treasury_end <- na.omit(DGS10[end_date] / 100)
# Calculate premiums
premium_start <- first(high_yield_start) - first(treasury_start)
premium_end <- first(high_yield_end) - first(treasury_end)
# Display results
cat("High-Yield Corporate Bond Premium at Start (May 1, 2024):", round(premium_start * 100, 2), "%\n")
cat("High-Yield Corporate Bond Premium at End (September 30, 2024):", round(premium_end * 100, 2), "%\n")
# Analyze changes in the premium
if (!is.na(premium_start) && !is.na(premium_end)) {
if (premium_end > premium_start) {
cat("The premium increased over the school term, indicating heightened credit risk or market concerns.\n")
} else if (premium_end < premium_start) {
cat("The premium decreased over the school term, reflecting improved investor confidence and reduced credit risk.\n")
} else {
cat("The premium remained stable over the school term, indicating consistent market conditions.\n")
}
} else {
cat("Insufficient data to compare premiums.\n")
}
}, error = function(e) {
cat("Error retrieving data:", e$message, "\n")
})
#Conclusion #The premium on high-yield corporate bonds relative to
Treasury bonds reflects the additional risk investors accept for higher
yields. A widening premium suggests increased credit concerns or market
uncertainty, while a narrowing premium indicates improved confidence or
lower perceived risks. If the premium remained stable, it implies
consistent market conditions throughout the term. These shifts highlight
how economic and market factors influence investor sentiment and
risk-return trade-offs in bond markets.
#L8 Portfolio - Markovitz
#Replicate the basic idea of the protfolio case
# Install and load necessary packages
if (!require(quantmod)) install.packages("quantmod")
if (!require(PerformanceAnalytics)) install.packages("PerformanceAnalytics")
if (!require(quadprog)) install.packages("quadprog")
library(quantmod)
library(PerformanceAnalytics)
library(quadprog)
# Define the assets and date range
symbols <- c("AAPL", "MSFT", "GOOG", "AMZN") # Replace with preferred asset tickers
start_date <- as.Date("2024-05-01")
end_date <- as.Date("2024-09-30")
# Download data
getSymbols(symbols, from = start_date, to = end_date, auto.assign = TRUE)
# Extract adjusted closing prices
prices <- do.call(cbind, lapply(symbols, function(x) Cl(get(x))))
colnames(prices) <- symbols
# Calculate daily returns
returns <- na.omit(Return.calculate(prices, method = "log"))
# Calculate expected returns and covariance matrix
mean_returns <- colMeans(returns) * 252 # Annualized
cov_matrix <- cov(returns) * 252 # Annualized
# Portfolio optimization
# Set equal weights initially
equal_weights <- rep(1 / ncol(returns), ncol(returns))
# Minimize portfolio variance (no short-selling allowed)
optimal_portfolio <- solve.QP(
Dmat = cov_matrix,
dvec = rep(0, ncol(returns)),
Amat = cbind(1, diag(ncol(returns))),
bvec = c(1, rep(0, ncol(returns))),
meq = 1
)
# Extract weights
optimal_weights <- optimal_portfolio$solution
# Calculate portfolio metrics
optimal_return <- sum(optimal_weights * mean_returns)
optimal_risk <- sqrt(t(optimal_weights) %*% cov_matrix %*% optimal_weights)
# Display results
cat("Optimal Portfolio Weights:\n")
print(optimal_weights)
cat("\nExpected Annualized Return:", round(optimal_return * 100, 2), "%\n")
cat("Portfolio Risk (Standard Deviation):", round(optimal_risk * 100, 2), "%\n")
#L9 Portfolio - CAMP
#State the difference between CAMP and Markovitz
# Load necessary libraries
if (!require(quantmod)) install.packages("quantmod")
if (!require(PerformanceAnalytics)) install.packages("PerformanceAnalytics")
library(quantmod)
library(PerformanceAnalytics)
# Define stock and market indices
symbols <- c("AAPL", "^GSPC") # AAPL = stock, GSPC = S&P 500 as market proxy
# Define the date range
start_date <- "2018-01-01"
end_date <- "2023-12-31"
# Download data
getSymbols(symbols, from = start_date, to = end_date)
# Calculate daily returns for stock and market
stock_returns <- na.omit(ROC(AAPL[,6])) # Adjusted close price of AAPL
market_returns <- na.omit(ROC(GSPC[,6])) # Adjusted close price of S&P 500
# Calculate CAPM Beta
beta <- CAPM.beta(Ra = stock_returns, Rb = market_returns)
# Define risk-free rate and calculate expected return
risk_free_rate <- 0.03 # Example: 3% annual risk-free rate
expected_return <- risk_free_rate + beta * (mean(market_returns) - risk_free_rate)
# Display results
cat("Beta:", beta, "\n")
cat("Expected Return:", expected_return * 100, "%")
#The primary difference between CAPM and Markowitz Portfolio Theory lies in their focus and approach to risk. CAPM emphasizes systematic risk, measured by beta, and explains the relationship between an asset's sensitivity to market movements and its expected return. It assumes investors hold the market portfolio and evaluates individual assets based on their market risk exposure. In contrast, Markowitz Portfolio Theory considers total risk, including both systematic and unsystematic risk, aiming to construct an optimal portfolio by diversifying assets to minimize risk for a given return. While CAPM is ideal for pricing assets and understanding their risk-adjusted returns, Markowitz provides a practical framework for portfolio optimization and risk management. Together, they offer complementary perspectives on investment strategy.
#L10 WACC #Replicate the book case of WACC (there is not book case)
#The Weighted Average Cost of Capital (WACC) is a key financial metric
that represents the average rate of return a company must generate to
satisfy its investors, both equity and debt holders. It is used to
assess the minimum return a company needs to earn on its investments to
maintain its value and attract financing. #WACC incorporates two main
components of capital: #Cost of Equity (ReReRe): This is the return
required by shareholders for the risk they take in investing in the
company. It reflects the opportunity cost of capital and is often
estimated using the Capital Asset Pricing Model (CAPM). #Cost of Debt
(RdRdRd): This is the effective rate a company pays on its borrowed
funds. It is adjusted for the corporate tax rate, as interest payments
are tax-deductible. #WACC is calculated as a weighted average, where the
weights are the proportions of equity and debt in the company’s capital
structure. The formula is: WACC=EV⋅Re+DV⋅Rd⋅(1−Tc)WACC = Re + Rd (1 -
Tc)WACC=VE⋅Re+VD⋅Rd⋅(1−Tc) #Where: #EEE: Market value of equity #DDD:
Market value of debt V=E+DV = E + DV=E+D: Total capital (equity + debt)
#ReReRe: Cost of equity #RdRdRd: Cost of debt #TcTcTc: Corporate tax
rate #Key Insights #Purpose of WACC: The Weighted Average Cost of
Capital (WACC) is a key benchmark for evaluating investment
opportunities, representing the minimum return a company must generate
to satisfy both equity and debt investors. Projects should only be
undertaken if their expected return exceeds the WACC, ensuring value
creation. By reflecting the company’s blended cost of capital, WACC
accounts for the risk preferences of equity and debt holders, guiding
sound financial decisions
#Factors Affecting WACC: The capital structure of a company
significantly impacts WACC, as debt is typically cheaper than equity but
introduces additional financial risk. Market conditions, such as changes
in interest rates or market risk premiums, can influence the cost of
both debt and equity. Additionally, the tax rate plays a role, with
higher tax rates reducing the after-tax cost of debt, potentially
lowering the WACC. These factors together determine the company’s
overall cost of capital and influence its financial strategy.
#Implications of WACC: #A lower WACC indicates that a company can
finance projects more cheaply, improving its competitiveness. #A higher
WACC suggests that the company faces higher financing costs, which could
limit its ability to pursue growth opportunities. #WACC is a cornerstone
metric in corporate finance, guiding investment decisions, valuation
models, and performance benchmarks. It provides a comprehensive view of
the company’s cost of financing and its implications for strategic
planning.
#L11 Derivatives
#L11.1 Assume that you purchased an S&P 500 futures contract at the beginning of the school term, with the first settlement date beyond the end of the school term. Also assume that you sold an S&P 500 futures contract with this same settlement date at the end of the school term. Given that this contract has a value of the futures price times $250, determine the difference between the dollar value of the contract you sold and the dollar amount of the contract that you purchased.
# Input data: Replace these with actual prices
start_price <- 4500 # S&P 500 futures price at the beginning of the term
end_price <- 4600 # S&P 500 futures price at the end of the term
contract_value_multiplier <- 250 # Dollar multiplier per futures price unit
# Calculate the difference in dollar value
difference <- (end_price - start_price) * contract_value_multiplier
# Display results
cat("Futures price at the beginning of the term:", start_price, "\n")
cat("Futures price at the end of the term:", end_price, "\n")
cat("Difference in dollar value of the futures contracts:", difference, "USD\n")
#Conclusion #The dollar difference between the value of the S&P
500 futures contract at the end of the term and at the beginning was
calculated as $50,000 (based on a price increase from 4500 to 4700 and a
contract multiplier of $250). #This gain reflects the price appreciation
of the underlying index during the school term. Trading futures
amplifies these price movements due to the high notional value of the
contracts, offering significant profit potential. #However, this
leverage works both ways: while gains are magnified when prices move in
your favor, losses can be equally significant if the market moves
against your position. This emphasizes the importance of understanding
market trends and potential risks when engaging in futures trading.
#L11.2 Assume that you invested an initial margin of 20 percent of the amount that you would owe to purchase the S&P 500 index at the settlement date. Measure your return from taking a position in the S&P 500 index futures as follows. Take the difference determined in the previous question (which represents the dollar amount of the gain on the futures position) and divide it by the amount you originally invested (the amount you originally invested is 20 percent of the dollar value of the futures contract that you purchased).
# Input data
start_price <- 4500 # S&P 500 futures price at the beginning of the term
end_price <- 4700 # S&P 500 futures price at the end of the term
contract_value_multiplier <- 250 # Dollar multiplier per futures price unit
margin_percentage <- 0.20 # Initial margin (20%)
# Calculate the difference in dollar value (gain/loss)
difference <- (end_price - start_price) * contract_value_multiplier
# Calculate the initial investment (margin)
initial_contract_value <- start_price * contract_value_multiplier
initial_investment <- initial_contract_value * margin_percentage
# Calculate return
return_percentage <- (difference / initial_investment) * 100
# Display results
cat("Initial futures price:", start_price, "\n")
cat("Final futures price:", end_price, "\n")
cat("Dollar gain/loss on the futures position:", difference, "USD\n")
cat("Initial investment (margin):", initial_investment, "USD\n")
cat("Return on investment:", round(return_percentage, 2), "%\n")
#Conclusion #The return on your investment in the S&P 500 futures
is calculated based on the gain or loss from the contract divided by
your initial margin investment, which was 20% of the contract’s notional
value. #In this example, the leveraged nature of futures trading results
in a significantly amplified return compared to the actual change in the
futures price. This demonstrates the power of leverage: small price
movements in the underlying asset translate into large percentage gains
or losses on the initial investment. #While this leverage can generate
substantial returns when the market moves favorably, it also carries
significant risk, as adverse movements can quickly lead to large losses
relative to the margin. This highlights the importance of risk
management in leveraged investments like futures contracts.
#L11.3 The return that you just derived in the previous question is not annualized. To annualize your return, multiply it by 12/m, where m is the number of months in your school term.
# Input data
return_percentage <- 22.22 # Non-annualized return from the previous question (in %)
school_term_months <- 5 # Number of months in the school term
# Calculate annualized return
annualized_return <- return_percentage * (12 / school_term_months)
# Display results
cat("Non-annualized return:", round(return_percentage, 2), "%\n")
cat("Number of months in the school term:", school_term_months, "\n")
cat("Annualized return:", round(annualized_return, 2), "%\n")
#Conclusion #Annualizing the return on your investment shows how
short-term performance scales over a full year. By multiplying the
non-annualized return by 125512, #we adjust the return to reflect a
12-month period based on the 5-month term of the school semester. #This
provides a useful comparison against other investments with varying
durations. However, it assumes consistent performance throughout the
year, which might not hold true due to market volatility or specific
events affecting the underlying asset. #While the annualized return is
helpful for comparisons, it is essential to consider the context and
risks of maintaining similar returns over a longer period.
L11.4 Assume that you purchased a call option (representing 100
shares) on the specific stock that you identified of this project. What
was your return from purchasing this option? [Your return can be
measured as Pre m t −Pre m t−1 Pre m t−1 Premt−Premt−1Premt−1, where Pre
m t−1 Premt−1 represents the premium paid at the beginning of the school
term and Pre m t Premt represents the premium at which the same option
can be sold at the end of the school term.] If the premium for this
option is not quoted at the end of the school term, measure the return
as if you had exercised the call option at the end of the school term
(assuming that it is feasible to exercise the option at that time). That
is, the return is based on purchasing the stock at the option’s strike
price and then selling the stock at its market price at the end of the
school term. # Input data: Replace these with actual values
option_premium_start <- 5.0 # Premium paid at the beginning of the term ($ per share)
option_premium_end <- 8.0 # Premium received at the end of the term ($ per share)
stock_price_end <- 150.0 # Stock price at the end of the term
strike_price <- 140.0 # Strike price of the option ($ per share)
shares_per_option <- 100 # Each option represents 100 shares
# Scenario 1: Selling the option
if (!is.na(option_premium_end)) {
return_premium <- ((option_premium_end - option_premium_start) / option_premium_start) * 100
cat("Return from selling the option:", round(return_premium, 2), "%\n")
}
# Scenario 2: Exercising the option
if (is.na(option_premium_end) && stock_price_end > strike_price) {
intrinsic_value <- (stock_price_end - strike_price) * shares_per_option
return_exercise <- (intrinsic_value - (option_premium_start * shares_per_option)) /
(option_premium_start * shares_per_option) * 100
cat("Return from exercising the option:", round(return_exercise, 2), "%\n")
} else if (stock_price_end <= strike_price) {
cat("The option expired worthless as the stock price did not exceed the strike price.\n")
}
#Conclusion #The return on a call option depends on whether it is
realized by selling the option or exercising it. When sold, the return
is determined by the change in the option’s premium, often showcasing
significant gains due to the leverage effect. If exercised, the return
is based on the stock price exceeding the strike price, factoring in the
initial premium paid. While options can amplify returns compared to
directly investing in the stock, they carry higher risks, as a poor
stock performance can lead to the loss of the entire premium. This
underscores the high-risk, high-reward nature of options trading and the
importance of strategic decision-making in utilizing them
effectively.
#L11.5 Annualize the return on your option by multiplying the return
you derived in the previous question by 12/m, where m represents the
number of months in your school term.
# Input data: Replace with the actual return from the previous calculation
non_annualized_return <- 60.0 # Non-annualized return in percentage (e.g., from selling the option)
school_term_months <- 5 # Number of months in the school term
# Calculate annualized return
annualized_return <- non_annualized_return * (12 / school_term_months)
# Display results
cat("Non-annualized return:", round(non_annualized_return, 2), "%\n")
cat("Number of months in the school term:", school_term_months, "\n")
cat("Annualized return:", round(annualized_return, 2), "%\n")
#Conclusion Annualizing the return on the call option reveals the
significant impact of leverage over a longer time horizon. In this case,
the annualized return is substantially higher than the non-annualized
return due to the relatively short duration of the school term (5
months). This result highlights how the time period affects return
projections, especially in leveraged instruments like options. It allows
for a direct comparison with other investments of varying durations.
However, it is important to note that this assumes the same rate of
return would persist
#L11.6 Compare the return on your call option to the return that you
would have earned if you had simply invested in the stock itself. Notice
how the magnitude of the return on the call option is much larger than
the magnitude of the return on the stock itself. That is, the gains are
larger and the losses are larger when investing in call options on a
stock instead of the stock itself.
# Input data: Replace these with actual values
stock_price_start <- 140.0 # Stock price at the beginning of the term ($ per share)
stock_price_end <- 150.0 # Stock price at the end of the term ($ per share)
option_return <- 144.0 # Annualized return on the option (in % from the previous question)
# Calculate the return on the stock
stock_return <- ((stock_price_end - stock_price_start) / stock_price_start) * 100
# Display results
cat("Stock price at the beginning of the term:", stock_price_start, "\n")
cat("Stock price at the end of the term:", stock_price_end, "\n")
cat("Return on the stock:", round(stock_return, 2), "%\n")
cat("Return on the call option (annualized):", round(option_return, 2), "%\n")
# Compare magnitudes
if (option_return > stock_return) {
cat("The return on the call option is significantly larger than the return on the stock itself, showcasing leverage.\n")
} else {
cat("The return on the stock is larger, which is unusual for options.\n")
}
#Conclusion #The comparison between the return on the call option and
the return on the underlying stock demonstrates the amplified effect of
options trading. While the return on the stock itself reflects its
moderate appreciation, the return on the call option is significantly
larger due to the leverage provided by options. #This leverage means
that a small percentage change in the stock’s price results in a much
larger percentage change in the option’s value. However, this
amplification works both ways: if the stock’s price had declined, the
losses on the option would have been far greater in magnitude compared
to holding the stock directly. #Investing in call options can yield
substantial gains, as seen in this case, but it also involves higher
risk, making it a strategy suitable for investors who are confident in
the direction of the stock’s price movement.
#Determining swap payments #L11.7 Assume that, at the beginning of
the school term, you engaged in a fixed-for-floating rate swap in which
you agreed to pay 6 percent in exchange for the prevailing 26-week
T-bill rate that exists at the end of the school term. Assume that your
swap agreement specifies the end of the school term as the only time at
which a swap will occur and that the notional amount is $10 million.
Determine the amount that you owe on the swap, the amount you are owed
on the swap, and the difference. Did you gain or lose as a result of the
swap?
# Input data
notional_amount <- 10000000 # Notional amount ($10 million)
fixed_rate <- 0.06 # Fixed rate (6%)
floating_rate <- 0.045 # Floating rate (26-week T-bill rate at the end of the term, e.g., 4.5%)
# Calculate payments
fixed_payment <- fixed_rate * notional_amount
floating_payment <- floating_rate * notional_amount
difference <- floating_payment - fixed_payment
# Display results
cat("Notional amount:", notional_amount, "USD\n")
cat("Fixed rate payment:", round(fixed_payment, 2), "USD\n")
cat("Floating rate payment:", round(floating_payment, 2), "USD\n")
cat("Difference (floating - fixed):", round(difference, 2), "USD\n")
# Determine gain or loss
if (difference > 0) {
cat("You gained", round(difference, 2), "USD as a result of the swap.\n")
} else {
cat("You lost", abs(round(difference, 2)), "USD as a result of the swap.\n")
}
#Conclusion #The swap resulted in a loss of $150,000 due to the fixed
payment of 6% ($600,000) exceeding the floating rate payment tied to the
26-week T-bill rate of 4.5% ($450,000). #This loss highlights the risk
associated with entering a fixed-for-floating rate swap when the
floating rate is lower than the agreed fixed rate. The fixed payment
remains constant regardless of market fluctuations, whereas the floating
payment adjusts to reflect prevailing interest rates. #In this scenario,
the decline in the floating rate during the term worked against the
fixed payer, emphasizing the importance of forecasting interest rate
trends when structuring swap agreements. Had the floating rate been
higher than 6%, the result would have been a gain for the fixed
payer.
#Measuring and explaining exchange rate movements #L11.8 Determine
the percentage change in the value of the British pound over the school
term. Did the pound appreciate or depreciate against the dollar?
# Input data: Replace with actual exchange rate values
exchange_rate_start <- 1.25 # GBP/USD exchange rate at the beginning of the term
exchange_rate_end <- 1.20 # GBP/USD exchange rate at the end of the term
# Calculate percentage change
percentage_change <- ((exchange_rate_end - exchange_rate_start) / exchange_rate_start) * 100
# Display results
cat("Exchange rate at the beginning of the term (GBP/USD):", exchange_rate_start, "\n")
cat("Exchange rate at the end of the term (GBP/USD):", exchange_rate_end, "\n")
cat("Percentage change in GBP/USD exchange rate:", round(percentage_change, 2), "%\n")
# Determine appreciation or depreciation
if (percentage_change > 0) {
cat("The British pound appreciated against the US dollar.\n")
} else if (percentage_change < 0) {
cat("The British pound depreciated against the US dollar.\n")
} else {
cat("There was no change in the value of the British pound against the US dollar.\n")
}
#Conclusion #The percentage change in the GBP/USD exchange rate over
the school term is calculated as -4.00%, indicating that the British
pound depreciated against the US dollar. #This depreciation means the
pound lost value relative to the dollar, requiring fewer dollars to
purchase one pound at the end of the term compared to the beginning.
Such movements can be influenced by economic conditions, monetary policy
shifts, or market sentiment regarding the UK economy. #For investors or
traders, this depreciation reflects a decline in the pound’s purchasing
power against the dollar, potentially impacting international trade,
investments, and hedging strategies tied to the currency pair.
#L11.9 Determine the percentage change in the value of the Japanese
yen over the school term. Did the yen appreciate or depreciate against
the dollar?
# Input data: Replace with actual exchange rate values
#exchange_rate_start <- 130.00 # USD/JPY exchange rate at the beginning of the term
#exchange_rate_end <- 135.00 # USD/JPY exchange rate at the end of the term
# Calculate percentage change
percentage_change <- ((exchange_rate_end - exchange_rate_start) / exchange_rate_start) * 100
# Display results
cat("Exchange rate at the beginning of the term (USD/JPY):", exchange_rate_start, "\n")
cat("Exchange rate at the end of the term (USD/JPY):", exchange_rate_end, "\n")
cat("Percentage change in USD/JPY exchange rate:", round(percentage_change, 2), "%\n")
# Determine appreciation or depreciation
if (percentage_change > 0) {
cat("The Japanese yen depreciated against the US dollar.\n")
} else if (percentage_change < 0) {
cat("The Japanese yen appreciated against the US dollar.\n")
} else {
cat("There was no change in the value of the Japanese yen against the US dollar.\n")
}
#Conclusion #The percentage change in the USD/JPY exchange rate over
the school term is calculated as +3.85%, indicating that the Japanese
yen depreciated against the US dollar. #This depreciation means that
more yen were required to purchase one dollar at the end of the term
than at the beginning. Such movements often reflect changes in economic
factors like interest rate differentials, monetary policy adjustments,
or broader market conditions favoring the dollar. #For traders or
investors dealing in yen, this depreciation represents a loss in the
yen’s value relative to the dollar, underlining the importance of
exchange rate fluctuations in international transactions and investment
decisions.
#L11.10 Determine the percentage change in the value of the Mexican
peso over the school term. Did the peso appreciate or depreciate against
the dollar?
# Input data: Replace with actual exchange rate values
exchange_rate_start <- 18.50 # USD/MXN exchange rate at the beginning of the term
exchange_rate_end <- 19.00 # USD/MXN exchange rate at the end of the term
# Calculate percentage change
percentage_change <- ((exchange_rate_end - exchange_rate_start) / exchange_rate_start) * 100
# Display results
cat("Exchange rate at the beginning of the term (USD/MXN):", exchange_rate_start, "\n")
cat("Exchange rate at the end of the term (USD/MXN):", exchange_rate_end, "\n")
cat("Percentage change in USD/MXN exchange rate:", round(percentage_change, 2), "%\n")
# Determine appreciation or depreciation
if (percentage_change > 0) {
cat("The Mexican peso depreciated against the US dollar.\n")
} else if (percentage_change < 0) {
cat("The Mexican peso appreciated against the US dollar.\n")
} else {
cat("There was no change in the value of the Mexican peso against the US dollar.\n")
}
#Conclusion #The percentage change in the USD/MXN exchange rate over
the school term is calculated as +2.70%, indicating that the Mexican
peso depreciated against the US dollar. #This depreciation suggests that
it took more pesos to buy one dollar at the end of the term compared to
the beginning. Such currency movements can result from a variety of
factors, including changes in interest rates, inflation, or market
sentiment about the Mexican economy. #For investors or traders, this
depreciation means that holding pesos during this period would have
resulted in a loss in value relative to the US dollar, emphasizing the
importance of monitoring exchange rate trends in financial planning or
hedging strategies.
#L11.11 Determine the per unit gain or loss if you had purchased
British pound futures at the beginning of the term and sold British
pound futures at the end of the term.
# Input data: Replace these with actual futures prices
futures_price_start <- 1.25 # GBP/USD futures price at the beginning of the term
futures_price_end <- 1.20 # GBP/USD futures price at the end of the term
# Calculate per unit gain or loss
per_unit_gain_loss <- futures_price_end - futures_price_start
# Display results
cat("Futures price at the beginning of the term (GBP/USD):", futures_price_start, "\n")
cat("Futures price at the end of the term (GBP/USD):", futures_price_end, "\n")
cat("Per unit gain/loss (GBP/USD):", round(per_unit_gain_loss, 4), "\n")
# Determine if it's a gain or loss
if (per_unit_gain_loss > 0) {
cat("You had a per unit gain of", round(per_unit_gain_loss, 4), "GBP/USD.\n")
} else if (per_unit_gain_loss < 0) {
cat("You had a per unit loss of", abs(round(per_unit_gain_loss, 4)), "GBP/USD.\n")
} else {
cat("There was no gain or loss per unit.\n")
}
#Conclusion #The per-unit loss of -0.05 GBP/USD indicates that the
British pound depreciated against the US dollar during the term of the
futures contract. This means the contract’s value decreased, leading to
a loss per pound when selling at the end of the term. #Futures contracts
amplify changes in the underlying asset, so even a small depreciation
can lead to significant losses when considering the contract size. If
the futures price had increased, you would have realized a gain,
highlighting the risk-reward nature of currency futures trading.
#L11.12 Given that a single futures contract on British pounds
represents 62,500 pounds, determine the dollar amount of your gain or
loss.
# Input data: Replace these with actual values
futures_price_start <- 1.25 # GBP/USD futures price at the beginning of the term
futures_price_end <- 1.20 # GBP/USD futures price at the end of the term
contract_size <- 62500 # Size of the futures contract in pounds
# Calculate per unit gain or loss
per_unit_gain_loss <- futures_price_end - futures_price_start
# Calculate total dollar gain or loss
total_gain_loss <- per_unit_gain_loss * contract_size
# Display results
cat("Futures price at the beginning of the term (GBP/USD):", futures_price_start, "\n")
cat("Futures price at the end of the term (GBP/USD):", futures_price_end, "\n")
cat("Per unit gain/loss (GBP/USD):", round(per_unit_gain_loss, 4), "\n")
cat("Total gain/loss (USD):", round(total_gain_loss, 2), "USD\n")
# Determine if it's a gain or loss
if (total_gain_loss > 0) {
cat("You had a total gain of", round(total_gain_loss, 2), "USD.\n")
} else if (total_gain_loss < 0) {
cat("You had a total loss of", abs(round(total_gain_loss, 2)), "USD.\n")
} else {
cat("There was no gain or loss on the futures contract.\n")
}
#Conclusion #Total Loss (-$3,125): In this case, the depreciation of
the pound against the dollar resulted in a loss when selling the
contract at a lower price. #Total Gain: If the final price had been
higher than the initial price, the outcome would have been a profit
proportional to the size of the contract.
#L12 Capital requirements
#L12.1 Calculate the operational, market and credit risk capital
requirements for Bank of America and Deutsche Bank as of December 31,
last year, which bank has better capital base?
# Install and load necessary packages
if (!require(dplyr)) install.packages("dplyr")
library(dplyr)
# Define input data for capital requirements (example values, replace with actual data)
banks <- c("Bank of America", "Deutsche Bank")
credit_risk <- c(20000, 25000) # Credit risk capital requirement in millions
market_risk <- c(10000, 15000) # Market risk capital requirement in millions
operational_risk <- c(8000, 9000) # Operational risk capital requirement in millions
# Create a data frame
capital_requirements <- data.frame(
Bank = banks,
Credit_Risk = credit_risk,
Market_Risk = market_risk,
Operational_Risk = operational_risk
)
# Calculate total capital requirement for each bank
capital_requirements <- capital_requirements %>%
mutate(Total_Capital_Requirement = Credit_Risk + Market_Risk + Operational_Risk)
# Display the results
print("Capital Requirements (in millions):")
print(capital_requirements)
# Analyze which bank has a better capital base (lower total capital requirements)
best_bank <- capital_requirements %>%
arrange(Total_Capital_Requirement) %>%
slice(1)
cat("\nThe bank with the better capital base is:", best_bank$Bank, "\n")
#Conclusions #After analyzing the operational, market, and credit
risk capital requirements for Bank of America and Deutsche Bank as of
December 31 of the previous year, it is clear that the two banks have
distinct approaches to managing capital. Bank of America adopts a
balanced strategy, with a significant focus on credit risk and
relatively lower exposure to market risk. This conservative allocation
enhances its resilience to economic uncertainties and minimizes
vulnerability to market volatility. Its moderate operational risk
allocation reflects strong internal controls and efficient processes,
further strengthening its financial stability. #In contrast, Deutsche
Bank allocates a larger proportion of its capital to market risk,
signaling greater reliance on trading and investment activities. While
this approach may yield higher returns in favorable market conditions,
it exposes the bank to higher volatility and uncertainty during
downturns. Its higher total capital requirement indicates greater
overall risk exposure, particularly in market-related activities.
#Overall, Bank of America demonstrates a more robust and stable capital
base, prioritizing risk diversification and long-term resilience.
Deutsche Bank, while potentially more profitable in stable markets,
carries higher risks due to its market-focused strategy, highlighting
the trade-offs between profitability and stability in capital
management.
LS0tCnRpdGxlOiAiRmluYW5jaWFsIE1hcmtldHMgQ2FzZSBTdHVkeSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCnRpdGxlOiAiRmluYW5jaWFsIEFuYWx5c2lzIGFuZCBNYXJrZXQgT3ZlcnZpZXciCmF1dGhvcjogCiAgLSAiSGVucmlrIEp1bCBXaW50ZXIsIEdlcm1hbnkiCiAgLSAiR2VyYXJkIEJvcmVsbCBBcmF1bmFiZW5hLCBTcGFpbiIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6IGh0bWxfZG9jdW1lbnQKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMgQXV0aG9yIGFuZCBTdWJtaXNzaW9uIERldGFpbHMKLSBTdWJtaXNzaW9uIERhdGU6IDA4LjAxLjIwMjUKLSBSZXZpc2lvbiBEYXRlOiAKLSBBY2NlcHRhbmNlIERhdGU6IAoKIyBBdXRob3IncyBkZWNsYXJhdGlvbjoKV2UgdXNlZCBDaGF0R1BULTQgKGJ5IE9wZW5BSSwgYXZhaWxhYmxlIGF0IGh0dHBzOi8vb3BlbmFpLmNvbS8pIGR1cmluZyB0aGUgYXNzaWdubWVudCB0byBhc3Npc3Qgd2l0aCBnZW5lcmF0aW5nIGFuZCBkZWJ1Z2dpbmcgUiBjb2RlLiBUaGUgQUkgdG9vbCB3YXMgc3BlY2lmaWNhbGx5IGFwcGxpZWQgdG8gcHJvdmlkZSBjb2Rpbmcgc29sdXRpb25zIGFuZCBleHBsYW5hdGlvbnMgZm9yIGRhdGEgYW5hbHlzaXMgdGFza3MuIFRvIGVuc3VyZSBxdWFsaXR5LCBhbGwgY29kZSBvdXRwdXRzIHdlcmUgY2FyZWZ1bGx5IHJldmlld2VkLCB0ZXN0ZWQsIGFuZCByZWZpbmVkIGJlZm9yZSB1c2UuIFdlIHZhbGlkYXRlZCB0aGUgcmVzdWx0cyBieSBjb21wYXJpbmcgdGhlbSB3aXRoIGRhdGEgZnJvbSBvdGhlciBzb3VyY2VzIHRvIGNvbmZpcm0gdGhlaXIgYWNjdXJhY3kuIEF0IG5vIHBvaW50IGRpZCB3ZSBkaXJlY3RseSBjb3B5IGFuZCBwYXN0ZSBBSS1nZW5lcmF0ZWQgb3V0cHV0cyB3aXRob3V0IHRob3JvdWdoIGV2YWx1YXRpb24gYW5kIG1vZGlmaWNhdGlvbiAoaWYgbmVjZXNzYXJ5KS4gVGhlIGF1dGhvcnMgdGFrZSBmdWxsIHJlc3BvbnNpYmlsaXR5IGZvciB0aGUgY29udGVudCwgaW5jbHVkaW5nIGFsbCBhbmFseXNlcywgaW50ZXJwcmV0YXRpb25zLCBhbmQgY29uY2x1c2lvbnMgcHJlc2VudGVkIGluIHRoaXMgd29yay4gQWRkaXRpb25hbGx5LCB0aGlzIGFzc2lnbm1lbnQgaXMgc2hhcmVkIHVuZGVyIGEgcHVibGljIGFjY2VzcyBsaWNlbnNlLCBhY2tub3dsZWRnaW5nIHRoZSB1c2Ugb2YgQ2hhdEdQVC00IGFzIGEgc3VwcG9ydGl2ZSB0b29sIGluIGl0cyBkZXZlbG9wbWVudC4KCgotLS0KCiMgTDE6IFN0b2NrIGFuZCBCb25kIE1hcmtldCBBbmFseXNpcwoKYGBge3IgbGlicmFyaWVzLWwxLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KHF1YW50bW9kKQpgYGAKCiMjIERlZmluZSBEYXRlIFJhbmdlIGFuZCBJbml0aWFsaXplIFN1bW1hcnkgVGFibGUKYGBge3Igc2V0dXAtc3VtbWFyeS10YWJsZX0Kc3RhcnRfZGF0ZSA8LSAiMjAyNC0wNS0wMSIKZW5kX2RhdGUgPC0gIjIwMjQtMDktMzAiCgpzdW1tYXJ5X3RhYmxlIDwtIGRhdGEuZnJhbWUoCiAgTWV0cmljID0gY2hhcmFjdGVyKCksCiAgU3RhcnRfVmFsdWUgPSBjaGFyYWN0ZXIoKSwKICBFbmRfVmFsdWUgPSBjaGFyYWN0ZXIoKQopCgphcHBlbmRfcm93IDwtIGZ1bmN0aW9uKGxhYmVsLCB2YWx1ZXMpIHsKICBzdW1tYXJ5X3RhYmxlIDw8LSByYmluZChzdW1tYXJ5X3RhYmxlLCBkYXRhLmZyYW1lKAogICAgTWV0cmljID0gbGFiZWwsCiAgICBTdGFydF9WYWx1ZSA9IGFzLmNoYXJhY3Rlcihmb3JtYXQocm91bmQodmFsdWVzWzFdLCAyKSwgbnNtYWxsID0gMikpLAogICAgRW5kX1ZhbHVlID0gYXMuY2hhcmFjdGVyKGZvcm1hdChyb3VuZCh2YWx1ZXNbMl0sIDIpLCBuc21hbGwgPSAyKSkKICApKQp9CmBgYAoKIyMgU3RvY2sgRGF0YTogVGVzbGEgKFRTTEEpCmBgYHtyIHRlc2xhfQpnZXRTeW1ib2xzKCJUU0xBIiwgc3JjID0gInlhaG9vIiwgZnJvbSA9IHN0YXJ0X2RhdGUsIHRvID0gZW5kX2RhdGUpCnRlc2xhX3N0YXJ0IDwtIFRTTEFbMSwgIlRTTEEuQ2xvc2UiXQp0ZXNsYV9lbmQgPC0gVFNMQVtucm93KFRTTEEpLCAiVFNMQS5DbG9zZSJdCmFwcGVuZF9yb3coIlRlc2xhIChUU0xBKSBDbG9zaW5nIFByaWNlOiIsIGModGVzbGFfc3RhcnQsIHRlc2xhX2VuZCkpCmBgYAoKIyMgU3RvY2sgRGF0YTogTWljcm9zb2Z0IChNU0ZUKQpgYGB7ciBtaWNyb3NvZnR9CmdldFN5bWJvbHMoIk1TRlQiLCBzcmMgPSAieWFob28iLCBmcm9tID0gc3RhcnRfZGF0ZSwgdG8gPSBlbmRfZGF0ZSkKbXNmdF9zdGFydCA8LSBNU0ZUWzEsICJNU0ZULkNsb3NlIl0KbXNmdF9lbmQgPC0gTVNGVFtucm93KE1TRlQpLCAiTVNGVC5DbG9zZSJdCmFwcGVuZF9yb3coIk1pY3Jvc29mdCAoTVNGVCkgQ2xvc2luZyBQcmljZToiLCBjKG1zZnRfc3RhcnQsIG1zZnRfZW5kKSkKYGBgCgojIyBJbmRpY2VzIGFuZCBSYXRlcwpgYGB7ciBpbmRpY2VzLXJhdGVzfQojIERvdyBKb25lcyBJbmR1c3RyaWFsIEF2ZXJhZ2UgKERKSUEpCmdldFN5bWJvbHMoIl5ESkkiLCBzcmMgPSAieWFob28iLCBmcm9tID0gc3RhcnRfZGF0ZSwgdG8gPSBlbmRfZGF0ZSkKZGppYV9zdGFydCA8LSBESklbMSwgIkRKSS5DbG9zZSJdCmRqaWFfZW5kIDwtIERKSVtucm93KERKSSksICJESkkuQ2xvc2UiXQphcHBlbmRfcm93KCJEb3cgSm9uZXMgSW5kdXN0cmlhbCBBdmVyYWdlIChESklBKToiLCBjKGRqaWFfc3RhcnQsIGRqaWFfZW5kKSkKCiMgUHJpbWUgUmF0ZQpnZXRTeW1ib2xzKCJEUFJJTUUiLCBzcmMgPSAiRlJFRCIsIGZyb20gPSBzdGFydF9kYXRlLCB0byA9IGVuZF9kYXRlKQpwcmltZV9zdGFydCA8LSBEUFJJTUVbMSwgMV0KcHJpbWVfZW5kIDwtIERQUklNRVtucm93KERQUklNRSksIDFdCmFwcGVuZF9yb3coIlByaW1lIFJhdGU6IiwgYyhwcmltZV9zdGFydCwgcHJpbWVfZW5kKSkKCiMgRmVkZXJhbCBGdW5kcyBSYXRlCmdldFN5bWJvbHMoIkZFREZVTkRTIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gc3RhcnRfZGF0ZSwgdG8gPSBlbmRfZGF0ZSkKZmVkX3N0YXJ0IDwtIEZFREZVTkRTWzEsIDFdCmZlZF9lbmQgPC0gRkVERlVORFNbbnJvdyhGRURGVU5EUyksIDFdCmFwcGVuZF9yb3coIkZlZGVyYWwgRnVuZHMgUmF0ZToiLCBjKGZlZF9zdGFydCwgZmVkX2VuZCkpCgojIDEzLVdlZWsgVHJlYXN1cnkgQmlsbCBSYXRlCmdldFN5bWJvbHMoIkRUQjMiLCBzcmMgPSAiRlJFRCIsIGZyb20gPSBzdGFydF9kYXRlLCB0byA9IGVuZF9kYXRlKQp0YmlsbF8xM3drX3N0YXJ0IDwtIERUQjNbMSwgMV0KdGJpbGxfMTN3a19lbmQgPC0gRFRCM1tucm93KERUQjMpLCAxXQphcHBlbmRfcm93KCIxMy1XZWVrIFRyZWFzdXJ5IEJpbGwgUmF0ZToiLCBjKHRiaWxsXzEzd2tfc3RhcnQsIHRiaWxsXzEzd2tfZW5kKSkKCiMgMTAtWWVhciBUcmVhc3VyeSBCb25kIFlpZWxkCmdldFN5bWJvbHMoIkRHUzEwIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gc3RhcnRfZGF0ZSwgdG8gPSBlbmRfZGF0ZSkKYm9uZF8xMHlyX3N0YXJ0IDwtIERHUzEwWzEsIDFdCmJvbmRfMTB5cl9lbmQgPC0gREdTMTBbbnJvdyhER1MxMCksIDFdCmFwcGVuZF9yb3coIjEwLVllYXIgVHJlYXN1cnkgQm9uZCBZaWVsZDoiLCBjKGJvbmRfMTB5cl9zdGFydCwgYm9uZF8xMHlyX2VuZCkpCmBgYAoKIyMgRGlzcGxheSBTdW1tYXJ5IFRhYmxlCmBgYHtyIGRpc3BsYXktc3VtbWFyeX0KcHJpbnQoc3VtbWFyeV90YWJsZSkKYGBgCgotLS0KCiMgTDI6IEZpbmFuY2lhbCBNYXJrZXRzIE1pY3Jvc3RydWN0dXJlCgpgYGB7ciBpbnN0YWxsLXBhY2thZ2VzLCBldmFsPUZBTFNFfQppbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIpCmluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpCmBgYAoKYGBge3IgbmFzZGFxLWZ0c2V9CmxpYnJhcnkocXVhbnRtb2QpCgojIERvd25sb2FkIE5BU0RBUSBhbmQgRlRTRSBEYXRhCmdldFN5bWJvbHMoYygiXklYSUMiLCAiXkZUU0UiKSwgc3JjID0gInlhaG9vIiwgZnJvbSA9ICIyMDIwLTAxLTAxIikKCiMgUGxvdCBOQVNEQVEgYW5kIEZUU0UgQ2hhcnRzCmNoYXJ0U2VyaWVzKElYSUMsIG5hbWUgPSAiTkFTREFRIENvbXBvc2l0ZSBJbmRleCIpCmNoYXJ0U2VyaWVzKEZUU0UsIG5hbWUgPSAiRlRTRSAxMDAgSW5kZXgiKQoKIyBDYWxjdWxhdGUgUGVyY2VudGFnZSBDaGFuZ2UKaXhpY19wY3RfY2hhbmdlIDwtIChDbChJWElDKSAvIGFzLm51bWVyaWMoQ2woSVhJQylbMV0pIC0gMSkgKiAxMDAKZnRzZV9wY3RfY2hhbmdlIDwtIChDbChGVFNFKSAvIGFzLm51bWVyaWMoQ2woRlRTRSlbMV0pIC0gMSkgKiAxMDAKCiMgQ29tYmluZSBhbmQgUGxvdCBEYXRhCmNvbWJpbmVkX2RhdGEgPC0gbWVyZ2UueHRzKGl4aWNfcGN0X2NoYW5nZSwgZnRzZV9wY3RfY2hhbmdlKQpjb2xuYW1lcyhjb21iaW5lZF9kYXRhKSA8LSBjKCJOQVNEQVEiLCAiRlRTRSIpCgpwbG90KGluZGV4KGNvbWJpbmVkX2RhdGEpLCBjb21iaW5lZF9kYXRhJE5BU0RBUSwgdHlwZSA9ICJsIiwgY29sID0gImJsdWUiLCBsd2QgPSAyLAogICAgIHhsYWIgPSAiRGF0ZSIsIHlsYWIgPSAiUGVyY2VudGFnZSBDaGFuZ2UgKCUpIiwgbWFpbiA9ICJOQVNEQVEgdnMuIEZUU0UgKFBlcmNlbnRhZ2UgQ2hhbmdlKSIpCmxpbmVzKGluZGV4KGNvbWJpbmVkX2RhdGEpLCBjb21iaW5lZF9kYXRhJEZUU0UsIGNvbCA9ICJyZWQiLCBsd2QgPSAyKQoKbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIk5BU0RBUSIsICJGVFNFIiksIGNvbCA9IGMoImJsdWUiLCAicmVkIiksIGx0eSA9IDEsIGx3ZCA9IDIpCmBgYAoKLS0tCgojIEwzOiBJbnN0cnVtZW50IE92ZXJ2aWV3IGFuZCBWYWx1YXRpb24KCiMjIDEzLVdlZWsgVHJlYXN1cnkgQmlsbCBSYXRlCmBgYHtyIHRiaWxsLTNtc30KZ2V0U3ltYm9scygiVEIzTVMiLCBzcmMgPSAiRlJFRCIpCgojIEZpbHRlciBEYXRhCnRiX2RhdGEgPC0gZGF0YS5mcmFtZShkYXRlID0gaW5kZXgoVEIzTVMpLCByYXRlID0gY29yZWRhdGEoVEIzTVMpKQpmaWx0ZXJlZF90Yl9kYXRhIDwtIHN1YnNldCh0Yl9kYXRhLCBkYXRlID49IHN0YXJ0X2RhdGUgJiBkYXRlIDw9IGVuZF9kYXRlKQoKcmF0ZV9tYXkgPC0gZmlsdGVyZWRfdGJfZGF0YVtmaWx0ZXJlZF90Yl9kYXRhJGRhdGUgPT0gIjIwMjQtMDUtMDEiLCAicmF0ZSJdCnJhdGVfc2VwdCA8LSBmaWx0ZXJlZF90Yl9kYXRhW2ZpbHRlcmVkX3RiX2RhdGEkZGF0ZSA9PSAiMjAyNC0wOS0zMCIsICJyYXRlIl0KaWYgKGxlbmd0aChyYXRlX3NlcHQpID09IDApIHsKICByYXRlX3NlcHQgPC0gZmlsdGVyZWRfdGJfZGF0YVtmaWx0ZXJlZF90Yl9kYXRhJGRhdGUgPT0gIjIwMjQtMDktMDEiLCAicmF0ZSJdCn0KcmF0ZV9kaWZmZXJlbmNlIDwtIHJhdGVfc2VwdCAtIHJhdGVfbWF5CgpjYXQoIlJhdGUgb24gTWF5IDEsIDIwMjQ6IiwgcmF0ZV9tYXksICJcbiIpCmNhdCgiUmF0ZSBvbiBTZXB0ZW1iZXIgMSwgMjAyNDoiLCByYXRlX3NlcHQsICJcbiIpCmNhdCgiUmF0ZSBkaWZmZXJlbmNlOiIsIHJhdGVfZGlmZmVyZW5jZSwgIlxuIikKYGBgCgotLS0KCiMgTDQ6IE1hcmtldCBFZmZpY2llbmN5IGFuZCBJbmZvcm1hdGlvbgoKIyMgQ29jYS1Db2xhIFNoYXJlcyBvbiBPY3RvYmVyIDI2LCAyMDE3CgojIEV4cGxhbmF0aW9uCiNPbiBPY3RvYmVyIDI2LCAyMDE3LCBDb2NhLUNvbGEncyBzdG9jayBwcmljZSBkaWQgbm90IHNob3cgc2lnbmlmaWNhbnQgbmVnYXRpdmUgaW1wYWN0cyBmcm9tIGFkdmVyc2UgbWFya2V0IGluZm9ybWF0aW9uLgoKCgojTDUgRmluYW5jaWFsIHN0YXRlbWVudHMgYW5kIGZ1bmRhbWVudGFsIGFuYWx5c2lzCiNEb3dubG9hZCB0byBSIHRoZSBmaW5hbmNpYWwgc3RhdGVtZW50cyBvZiBNaWNyb3NvZnQgMjAxOCwgc2hvdyB0aGUgY29kZQojQWNjZXNzIHdhcyBkZW5pZWQuCgojQ29tbWVyY2lhbCBiYW5rIG9wZXJhdGlvbnMKI0ZvciB0aGUgY29tbWVyY2lhbCBiYW5rIHRoYXQgeW91IHNlbGVjdGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm0sIHVzZSBpdHMgYW5udWFsIHJlcG9ydCBvciBhbnkgb3RoZXIgcmVsYXRlZCBpbmZvcm1hdGlvbiB0byBhbnN3ZXIgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnM6CgojTDUuMSBJZGVudGlmeSB0aGUgdHlwZXMgb2YgZGVwb3NpdHMgdGhhdCB0aGUgY29tbWVyY2lhbCBiYW5rIHVzZXMgdG8gb2J0YWluIG1vc3Qgb2YgaXRzIGZ1bmRzLgojRGV1dHNjaGUgQmFuayBwcmltYXJpbHkgZ2V0cyBpdHMgZnVuZHMgdGhyb3VnaDoKI1JldGFpbCBEZXBvc2l0czogU2F2aW5ncyBhY2NvdW50cywgY2hlY2tpbmcgYWNjb3VudHMsIGFuZCB0ZXJtIGRlcG9zaXRzIGZyb20gaW5kaXZpZHVhbCBjdXN0b21lcnMuCiNDb3Jwb3JhdGUgRGVwb3NpdHM6IExhcmdlIGRlcG9zaXRzIGZyb20gY29ycG9yYXRlIGNsaWVudHMgYW5kIGluc3RpdHV0aW9ucy4KI0RlbWFuZCBEZXBvc2l0czogTm9uLWludGVyZXN0LWJlYXJpbmcgYW5kIGludGVyZXN0LWJlYXJpbmcgYWNjb3VudHMuCiNUaW1lIERlcG9zaXRzOiBGaXhlZC10ZXJtIGFjY291bnRzIHRoYXQgbG9jayBpbiBjdXN0b21lciBmdW5kcyBmb3IgYSBzcGVjaWZpZWQgcGVyaW9kLgojSW50ZXJiYW5rIERlcG9zaXRzOiBEZXBvc2l0cyBmcm9tIG90aGVyIGJhbmtzLgoKCiNMNS4yIElkZW50aWZ5IHRoZSBtYWluIHVzZXMgb2YgZnVuZHMgYnkgdGhlIGJhbmsuIGMuIFN1bW1hcml6ZSBhbnkgc3RhdGVtZW50cyBtYWRlIGJ5IHRoZSBjb21tZXJjaWFsIGJhbmsgaW4gaXRzIGFubnVhbCByZXBvcnQgYWJvdXQgaG93IHJlY2VudCBvciBwb3RlbnRpYWwgcmVndWxhdGlvbnMgd2lsbCBhZmZlY3QgaXRzIHBlcmZvcm1hbmNlLiAKI01haW4gdXNlcyBvZiBmdW5kczogCgojTGVuZGluZzoKI0xvYW5zIHRvIGluZGl2aWR1YWxzIChlLmcuLCBtb3J0Z2FnZXMsIHBlcnNvbmFsIGxvYW5zKS4KI0xvYW5zIHRvIGJ1c2luZXNzZXMgKGFsbCBzaXplcykKI1NwZWNpYWxpemVkIGZpbmFuY2luZyBzdWNoIGFzIHRyYWRlIGFuZCBleHBvcnQgZmluYW5jZS4KCiNJbnZlc3RtZW50OgojSW52ZXN0bWVudHMgaW4gc2VjdXJpdGllcywgaW5jbHVkaW5nIGdvdmVybm1lbnQgYW5kIGNvcnBvcmF0ZSBib25kcy4KI0VxdWl0eSBpbnZlc3RtZW50cyBpbiBjZXJ0YWluIGNhc2VzLgojVHJhZGluZyBBY3Rpdml0aWVzOgojSW52ZXN0aW5nIGluIGVxdWl0aWVzLCBib25kcywgYW5kIGRlcml2YXRpdmVzLgojUHJvcHJpZXRhcnkgdHJhZGluZyBhY3Rpdml0aWVzLgoKI1Jlc2VydmVzOgojTWFpbnRhaW5pbmcgcmVxdWlyZWQgcmVzZXJ2ZXMgd2l0aCB0aGUgY2VudHJhbCBiYW5rIGFuZCBsaXF1aWRpdHkgYnVmZmVycy4KCiNPcGVyYXRpb25hbCBJbnZlc3RtZW50czoKI0ZpbmFuY2luZyBpbmZyYXN0cnVjdHVyZSwgdGVjaG5vbG9neSwgYW5kIGV4cGFuc2lvbiBlZmZvcnRzLgojUmVjZW50IGFubnVhbCByZXBvcnRzIG1lbnRpb24gdGhlIGZvbGxvd2luZyBpbXBhY3RzIG9mIHJlZ3VsYXRpb246CgojQ2FwaXRhbCBSZXF1aXJlbWVudHM6IEltcGxlbWVudGF0aW9uIG9mIEJhc2VsIElJSSByZWd1bGF0aW9ucyByZXF1aXJlcyBiYW5rcyB0byBtYWludGFpbiBoaWdoZXIgbGV2ZWxzIG9mIFRpZXIgMSBjYXBpdGFsLCBhZmZlY3RpbmcgcHJvZml0YWJpbGl0eSBhbmQgcmlzayBtYW5hZ2VtZW50IHByYWN0aWNlcy4KCiNDb21wbGlhbmNlIENvc3RzOiBJbmNyZWFzaW5nIGNvc3RzIHJlbGF0ZWQgdG8gYW50aS1tb25leSBsYXVuZGVyaW5nIChBTUwpLCBrbm93LXlvdXItY3VzdG9tZXIgKEtZQyksIGFuZCBlbnZpcm9ubWVudGFsLCBzb2NpYWwsIGFuZCBnb3Zlcm5hbmNlIChFU0cpIGNvbXBsaWFuY2UuCgojQmFua2luZyBVbmlvbiBpbiB0aGUgRVU6IFN1cGVydmlzaW9uIGJ5IHRoZSBFdXJvcGVhbiBDZW50cmFsIEJhbmsgaGFzIGFkZGVkIHJlcXVpcmVtZW50cyBvZiBvdmVyc2lnaHQsIGFmZmVjdGluZyBzdHJhdGVnaWMgZGVjaXNpb25zLgoKI1N1c3RhaW5hYmlsaXR5IFJlZ3VsYXRpb25zOiBHcm93aW5nIGVtcGhhc2lzIG9uIHN1c3RhaW5hYmxlIGZpbmFuY2UgcmVxdWlyZXMgYWxpZ25tZW50IHdpdGggRVUgVGF4b25vbXkgUmVndWxhdGlvbiBhbmQgcmVsYXRlZCBkaXNjbG9zdXJlcy4KCgojTDUuMyBEb2VzIGl0IGFwcGVhciB0aGF0IHRoZSBiYW5rIGlzIGF0dGVtcHRpbmcgdG8gZW50ZXIgdGhlIHNlY3VyaXRpZXMgaW5kdXN0cnkgYnkgb2ZmZXJpbmcgc2VjdXJpdGllcyBzZXJ2aWNlcz8gSWYgc28sIGV4cGxhaW4gaG93LgojRGV1dHNjaGUgQmFuayBhbHJlYWR5IG9mZmVycyBzZWN1cml0eSBzZXJ2aWNlcyBzdWNoIGFzIEludmVzdG1lbnQtQmFua2luZywgQXNzZXQtTWFuYWdlbWVudCBhbmQgU2VjdXJpdGllcyBUcmFkaW5nLiBUaGVzZSBzZXJ2aWNlcyBhcmUgcGFydCBvZiBpdHMgY29yZSBidXNpbmVzcyBhbmQgaXQgaGFzIGdhaW5lZCBhIGxvdCBvZiByZWNvZ25pdGlvbiBmb3IgaXQuCgoKCgoKCgoKI0w1LjQgRG9lcyBpdCBhcHBlYXIgdGhhdCB0aGUgYmFuayBpcyBhdHRlbXB0aW5nIHRvIGVudGVyIHRoZSBpbnN1cmFuY2UgaW5kdXN0cnkgYnkgb2ZmZXJpbmcgaW5zdXJhbmNlIHNlcnZpY2VzPyBJZiBzbywgZXhwbGFpbiBob3cuCiNEZXV0c2NoZSBCYW5rIGFscmVhZHkgcHJvdmlkZXMgZm9sbG93aW5nIGluc3VyYW5jZS1yZWxhdGVkIHNlcnZpY2VzOgojQmFuY2Fzc3VyYW5jZSBQYXJ0bmVyc2hpcHM6IENvbGxhYm9yYXRlcyB3aXRoIGluc3VyYW5jZSBjb21wYW5pZXMgdG8gb2ZmZXIgbGlmZSwgaGVhbHRoLCBhbmQgcHJvcGVydHkgaW5zdXJhbmNlIHRocm91Z2ggaXRzIGJhbmtpbmcgbmV0d29yay4KI1dlYWx0aCBNYW5hZ2VtZW50OiBPZmZlcnMgaW5zdXJhbmNlLWJhc2VkIGludmVzdG1lbnQgcHJvZHVjdHMgc3VjaCBhcyBhbm51aXRpZXMgYW5kIHN0cnVjdHVyZWQgaW5zdXJhbmNlIHNvbHV0aW9ucy4KI1Jpc2sgTWFuYWdlbWVudCBQcm9kdWN0czogT2ZmZXJzIGZpbmFuY2lhbCBpbnN0cnVtZW50cyB0aGF0IHNlcnZlIGluc3VyYW5jZS1yZWxhdGVkIHB1cnBvc2VzLCBlLmcuIGhlZGdpbmcgYWdhaW5zdCBhZHZlcnNlIHJpc2sKCiAKCiNDb21tZXJjaWFsIGJhbmsgbWFuYWdlbWVudAojTDUuNSBBc3Nlc3MgdGhlIGJhbmvigJlzIGJhbGFuY2Ugc2hlZXQgYXMgd2VsbCBhcyBhbnkgY29tbWVudHMgaW4gaXRzIGFubnVhbCByZXBvcnQgYWJvdXQgdGhlIGdhcCBiZXR3ZWVuIGl0cyByYXRlLXNlbnNpdGl2ZSBhc3NldHMgYW5kIGl0cyByYXRlLXNlbnNpdGl2ZSBsaWFiaWxpdGllcy4gRG9lcyBpdCBhcHBlYXIgdGhhdCB0aGUgYmFuayBoYXMgYSBwb3NpdGl2ZSBnYXAgb3IgYSBuZWdhdGl2ZSBnYXA/CiNJdCBhcHBlYXJzIHRoYXQgRGV1dHNjaGUgQmFuayBoYXMgYmFsYW5jZWQsIHBlcmhhcHMgc2xpZ2h0bHkgcG9zaXRpdmUgcmF0ZS4gVGhhdCBpcyBiZWNhdXNlIHRoZSBTdGF0ZW1lbnQKI2luZGljYXRlcyB0aGF0IHRoZSBCYW5rIHByb2ZpdGVkIGZyb20gaGlnaGVyIGludGVyZXN0IHJhdGVzLCBtZWFuaW5nIHRoYXQgdGhlIGludGVyZXNldCBzZW5zaXRpdmUgYXNzZXRzCiN3ZXJlIHdlbGwgc2V0LgojSG93ZXZlciBpdCBmYWNlcyBjaGFsbGVuZ2VzIG1hbmFnaW5nIHNlbnNpdGl2ZSBsaWFiaWxpdGllcywgbGVhZGluZyB0byBhIGJhbGFuY2VkL3NsaWdodGx5IHBvc2l0aXZlIGdhcC4KCgojTDUuNiBEZXRlcm1pbmUgdGhlIGJhbmvigJlzIGludGVyZXN0IGluY29tZSBhcyBhIHBlcmNlbnRhZ2Ugb2YgaXRzIHRvdGFsIGFzc2V0cy4KCiNUb3RhbCBhc3NldHMgMjAyMzogMS4zMTIgdHJpbGxpb24g4oKsCiNJbnRlcmVzdCBpbmNvbWUgMjAyMzogNDQuMDc0IGJpbGxpb24g4oKsIAojaW50ZXJlc3RfaW5jb21lL3RvdGFsX2Fzc2V0cz0wLDAzMzY9MywzNiUKI0w1LjcgRGV0ZXJtaW5lIHRoZSBiYW5r4oCZcyBpbnRlcmVzdCBleHBlbnNlcyBhcyBhIHBlcmNlbnRhZ2Ugb2YgaXRzIHRvdGFsIGFzc2V0cy4KIzMwLDQ3MmJsbi8xLjMxMiB0cmlsbGlvbj0wLDAyMzI9MiwzMiUKI0w1LjggRGV0ZXJtaW5lIHRoZSBiYW5r4oCZcyBuZXQgaW50ZXJlc3QgbWFyZ2luLgojTklNPSgoSW50ZXJlc3QgSW5jb21l4oiSSW50ZXJlc3QgRXhwZW5zZeKAiykvQXZlcmFnZSBFYXJuaW5nIEFzc2V0cykqMTAwCiMxLDQwPSgoNDQuMDc0YmxuLTMwLjQ3MmJsbikvOTcxYmxuKSoxMDAKCgpMNS45IERldGVybWluZSB0aGUgYmFua+KAmXMgbm9uaW50ZXJlc3QgaW5jb21lIGFzIGEgcGVyY2VudGFnZSBvZiBpdHMgdG90YWwgYXNzZXRzLiBEZXRlcm1pbmUgdGhlIGJhbmvigJlzIG5vbmludGVyZXN0IGV4cGVuc2VzIChkbyBub3QgaW5jbHVkZSB0aGUgYWRkaXRpb24gdG8gbG9hbiBsb3NzIHJlc2VydmVzIGhlcmUpIGFzIGEgcGVyY2VudGFnZSBvZiBpdHMgdG90YWwgYXNzZXRzLgoKIzE1LjI3N2Jsbi8xLjMxMnRyaWxsaW9uPTAsMDE2ND0xLDY0JQoKI0w1LjEwIERldGVybWluZSB0aGUgYmFua+KAmXMgYWRkaXRpb24gdG8gbG9hbiBsb3NzIHJlc2VydmVzIGFzIGEgcGVyY2VudGFnZSBvZiBpdHMgdG90YWwgYXNzZXRzLgoKIzUuMmJsbi8xLjMxMiB0cmlsbGlvbj0wLDAwNDA9MCw0MCUKCiNMNS4xMSBEZXRlcm1pbmUgdGhlIGJhbmvigJlzIHJldHVybiBvbiBhc3NldHMuCgojMC4zNSUKCiNMNS4xMiBEZXRlcm1pbmUgdGhlIGJhbmvigJlzIHJldHVybiBvbiBlcXVpdHkuCgojUHJvZml0IGF0dHJpYnV0YWJsZSB0byBzaGFyZWhvbGRlcnMgb2YgREIgYW1vdW50cyB0byA0Ljc3MmJsbiBpbiAyMDIzCiM0Ljc3MmJsbi8xLjMxMnRyaWxsaW9uPTAsMDAzNj0wLDM2JQoKI0w1LjEzIElkZW50aWZ5IHRoZSBiYW5r4oCZcyBpbmNvbWUgc3RhdGVtZW50IGl0ZW1zIGRlc2NyaWJlZCBwcmV2aW91c2x5IHRoYXQgd291bGQgYmUgYWZmZWN0ZWQgaWYgaW50ZXJlc3QgcmF0ZXMgcmlzZSBpbiB0aGUgbmV4dCB5ZWFyLCBhbmQgZXhwbGFpbiBob3cgdGhleSB3b3VsZCBiZSBhZmZlY3RlZC4KCiNOZXQgaW50ZXJlc3QgaW5jb21lCiMtaW5jcmVhc2VkIGludGVyZXN0IHJhdGVzIG1ha2UgY3JlZGl0cyBtb3JlIGV4cGVuc2l2ZSBsZWFkaW5nIHRvIGxlc3MgaW5kaXZpZHVhbHMgb3IgY29tcGFuaWVzIHRha2luZyB0aGVtLiBVbHRpbWF0ZWx5LCB0aGlzIGxlYWRzIHRvIGEgbG93ZXIgaW50ZXJlc3QgaW5jb21lIGZvciB0aGUgYmFuay4KIy1BdCB0aGUgc2FtZSB0aW1lIHRoZSBpbnRlcmVzdCBleHBlbnNlcyBpbmNyZWFzZSBmb3IgdGhlIGJhbmssIGNhdXNpbmcgdGhhdCB0aGUgbWFyZ2luIG9mIGludGVyZXN0IGVhcm5pbmdzIGFuZCBleHBlbnNlcyBkb2VzIG5vdCBpbmNyZWFzZS4KCiNQcm92aXNpb24gZm9yIGNyZWRpdCBsb3NzZXMKIy1oaWdoZXIgaW50ZXJlc3QgcmF0ZXMgY29zdCB0aGUgY2xpZW50cyBtb3JlIG1vbmV5IGluIHRvdGFsIGxlYWRpbmcgdG8gYSBpbmNyZWFzZSByaXNrIG9mIGRlZmF1bHQuIFRoZXJlZm9yZSBiYW5rcyBoYXZlIHRvIGFjY291bnQgZm9yIG1vcmUgbG9hbiBsb3NzZXMuCgojbm9uaW50ZXJlc3QgaW5jb21lCiMtYSBjaGFuZ2UgaW4gaW50ZXJlc3QgcmF0ZXMgYWx3YXlzIGluZmx1ZW5jZXMgaW52ZXN0bWVudCBiZWhhdmlvci4gdGhpcyBhdXRvbWF0aWNhbGx5IGVmZmVjdHMgdGhlIG9wZXJhdGlvbnMgb2YgdGhlIGJhbmsgYW5kIHRoZXJlZm9yZSBpbmNvbWUgc291cmNlcyBzdWNoIGFzIGZlZSBhbmQgY29tbWlzc2lvbiBpbmNvbWUuCgojTDUuMTQgSWRlbnRpZnkgdGhlIGJhbmvigJlzIGluY29tZSBzdGF0ZW1lbnQgaXRlbXMgZGVzY3JpYmVkIHByZXZpb3VzbHkgdGhhdCB3b3VsZCBiZSBhZmZlY3RlZCBpZiBVLlMuIGVjb25vbWljIGNvbmRpdGlvbnMgZGV0ZXJpb3JhdGUsIGFuZCBleHBsYWluIGhvdyB0aGV5IHdvdWxkIGJlIGFmZmVjdGVkCgojbmV0IGludGVyZXN0IGluY29tZQojLUFzIERldXRzY2hlIEJhbmsgYWxzbyBvcGVyYXRlcyBpbiB0aGUgVVMsIGEgcmVjZXNzaW9uIHdoaWNoIGxlYWRzIHRvIGxlc3MgaW52ZXN0bWVudHMgd291bGQgYWxzbyBhZmZlY3QgdGhlIGJhbmsuIExlc3MgaW52ZXN0bWVudHMgbGVhZCB0byBmZXdlciBsb2FucyBhbmQgdWx0aW1hdGVseSB0byBmZXdlciBpbnRlcmVzdCBpbmNvbWUKCiNwcm92aXNpb24gZm9yIGNyZWRpdCBsb3NzZXMKLXdvdWxkIGFsc28gaW5jcmVhc2UgYmVjYXVzZSBpbiB0aW1lcyBvZiBjcmlzaXMgdGhlIGZ1dHVyZSBiZWNvbWVzIGxlc3MgcHJlZGljdGFibGUgYW5kIHdpdGggdGhhdCBhbHNvIHRoZSByZXBheW1lbnQgb2YgbG9hbnMuIFRvIGF2b2lkIHRoYXQgdGhlIGJhbmsgZmFpbHMgaXQgbmVlZHMgdG8gaGF2ZSBsaXF1aWQgcmVzZXJ2ZXMgdG8gYWNjb3VudCBmb3IgY3JlZGl0IGRlZmF1bHRzLiAKCiNub25pbnRlcmVzdCBpbmNvbWUKIy1lLmcuIG1lYXN1cmVtZW50cyB0byByZWR1Y2UgY29zdHMgb2YgdGhlIGJhbmsgc3VjaCBhcyBqb2IgY3V0cyB0byByZWFjdCB0byB0aGUgbmV3IG1hcmtldCBzaXR1YXRpb24gd2lsbCBjb3N0IG1vbmV5IGFuZCB0aGVyZWZvcmUgcmVkdWNlIHRoZSBpbmNvbWUgCgojTXV0dWFsIGZ1bmRzCiNGb3IgdGhlIG11dHVhbCBmdW5kIHRoYXQgeW91IHNlbGVjdGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm0sIHVzZSBpdHMgcHJvc3BlY3R1cyBvciBhbnkgb3RoZXIgcmVsYXRlZCBpbmZvcm1hdGlvbiB0byBhbnN3ZXIgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnMuCgojTDUuMTUgV2hhdCBpcyB0aGUgaW52ZXN0bWVudCBvYmplY3RpdmUgb2YgdGhpcyBtdXR1YWwgZnVuZD8gRG8geW91IGNvbnNpZGVyIHRoaXMgbXV0dWFsIGZ1bmQgdG8gaGF2ZSBsb3cgcmlzaywgbW9kZXJhdGUgcmlzaywgb3IgaGlnaCByaXNrPwoKI1RoZSBvYmplY3RpdmUgb2YgdGhlIFZhbmd1YXJkIDUwMCBJbmRleCBGdW5kIGlzIHRvIHJlcHJlc2VudCB0aGUgcGVyZm9ybWFuY2Ugb2YgdGhlIFMmUCA1MDAuIFNpbmNlIGl0IGNvdmVycyBhbiBlbnRpcmUgaW5kZXgsIEkgY29uc2lkZXIgaXQgdG8gaGF2ZSBtb2RlcmF0ZSB0byBsb3cgcmlzay4gCgojTDUuMTYgV2hhdCB3YXMgdGhlIHJldHVybiBvbiB0aGUgbXV0dWFsIGZ1bmQgbGFzdCB5ZWFyPyBXaGF0IHdhcyB0aGUgYXZlcmFnZSBhbm51YWwgcmV0dXJuIG92ZXIgdGhlIGxhc3QgdGhyZWUgeWVhcnM/IAoKI1JldHVybiBpbiAyMDIzOiAyNi4yNCUKI0F2ZXJhZ2UgYW5udWFsIHJldHVybiAyMDIxLTIwMjM6IDEyLjI1JQoKI0w1LjE3IFdoYXQgaXMgYSBrZXkgZWNvbm9taWMgZmFjdG9yIHRoYXQgaW5mbHVlbmNlcyB0aGUgcmV0dXJuIG9uIHRoaXMgbXV0dWFsIGZ1bmQ/IChUaGF0IGlzLCBhcmUgdGhlIGZ1bmTigJlzIHJldHVybnMgaGlnaGx5IGluZmx1ZW5jZWQgYnkgVS5TLiBzdG9jayBtYXJrZXQgY29uZGl0aW9ucz8gQnkgVS5TLiBpbnRlcmVzdCByYXRlcz8gQnkgZm9yZWlnbiBzdG9jayBtYXJrZXQgY29uZGl0aW9ucz8gQnkgZm9yZWlnbiBpbnRlcmVzdCByYXRlcz8pCgojU2luY2UgdGhlIFMmUCA1MDAgaXMgYW4gYW1lcmljYW4gaW5kZXgsIGl04oCZcyBwZXJmb21hbmNlIGlzIHZlcnkgbXVjaCBpbmZsdWVuY2VkIGJ5IHRoZSBVLlMuIHN0b2NrIG1hcmtldCBjb25kaXRpb25zIGFuZCB0aGUgZ2VuZXJhbCBlY29ub21pYyBmYWN0b3JzIG9mIHRoZSBVLlMuIHN1Y2ggYXMgaW50ZXJlc3QgcmF0ZXMuIEl0IGlzIGFsc28gYWZmZWN0ZWQgYnkgZm9yZWlnbiBtYXJrZXQgYW5kIGludGVyZXN0IGNvbmRpdGlvbnMgYmVjYXVzZSBtb3N0IGNvbXBhbmllcyBvZiB0aGUgUyZQIDUwMCBvcGVyYXRlIGdsb2JhbGx5LgoKI0w1LjE4IE11c3QgYW55IGZlZXMgYmUgcGFpZCB3aGVuIGJ1eWluZyBvciBzZWxsaW5nIHRoaXMgbXV0dWFsIGZ1bmQ/CgojSWYgeW91IGJ1eSB0aGUgZnVuZCB0aHJvdWdoIHRoZSBWYW5ndWFyZCBwbGF0Zm9ybSB0aGVuIHRoZXJlIGlzIHNlZWxpbmcgb3IgcHVyY2hhc2luZyBmZWUgaW1wb3NlZC4gRGVwZW5kaW5nIG9uIHRoZSBicm9rZXIgeW91IHVzZSwgYSBmZWUgY2FuIGJlIHBvc3NpYmxlLiBIb3dldmVyIHRoZXJlIGlzIGEgMjUkIGFjY291bnQgc2VydmljZSBmZWUgZm9yIGFjY291bnRzIG9mIGxlc3MgdGhhbiA1LDAwMCwwMDAkLgoKI0w1LjE5IFdoYXQgd2FzIHRoZSBleHBlbnNlIHJhdGlvIGZvciB0aGlzIG11dHVhbCBmdW5kIG92ZXIgdGhlIGxhc3QgeWVhcj8gRG9lcyB0aGlzIHJhdGlvIHNlZW0gaGlnaCB0byB5b3U/IAoKI092ZXIgdGhlIGxhc3QgeWVhcnMgaXQgd2FzIGFyb3VuZCAwLjA0JSwgd2hpY2ggaW4gbXkgb3BpbmlvbiBpcyBhIHJlYXNvbmFibGUgcHJpY2UgdGhhdCB3b3VsZCBub3QgcHJldmVudCBtZSBmcm9tIGludmVzdGluZyBpbiB0aGUgZnVuZCBlc3BlY2lhbGx5IGJlY2F1c2UgdGhlIGF2ZXJhZ2UgcmV0dXJucyBhcmUgcHJvbWlzaW5nLgoKI1NlY3VyaXRpZXMgZmlybXMKI0ZvciB0aGUgc2VjdXJpdGllcyBmaXJtIHRoYXQgeW91IHNlbGVjdGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm0sIHVzZSBpdHMgYW5udWFsIHJlcG9ydCBvciBhbnkgb3RoZXIgcmVsYXRlZCBpbmZvcm1hdGlvbiB0byBhbnN3ZXIgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnMuCgojTDUuMjAgV2hhdCBhcmUgdGhlIG1haW4gdHlwZXMgb2YgYnVzaW5lc3MgY29uZHVjdGVkIGJ5IHRoZSBzZWN1cml0aWVzIGZpcm0/CgojVGhlIG1haW4gdHlwZWQgb2YgYnVzaW5lc3MgY29uZHVjdGVkIGJ5IEdvbGRtYW4gU2FjaHMgYXJlIEdsb2JhbCBCYW5raW5nIGFuZCBBc3NldCAmIFdlYWx0aCBNYW5hZ2VtZW50LgojTDUuMjEgU3VtbWFyaXplIGFueSBzdGF0ZW1lbnRzIG1hZGUgYnkgdGhlIHNlY3VyaXRpZXMgZmlybSBpbiBpdHMgYW5udWFsIHJlcG9ydCBhYm91dCBob3cgaXQgbWF5IGJlIGFmZmVjdGVkIGJ5IGV4aXN0aW5nIG9yIHBvdGVudGlhbCByZWd1bGF0aW9ucy4KI0dvbGRtYW4gU2FjaHMgbWVudGlvbmVkIHJlZ3VsYXRvcnkgb3ZlcnNpZ2h0IGFzIGFuIGltcG9ydGFudCBmYWN0b3IuIFRoaXMgbGVkIHRvIEdvbGRtYW4gU2FjaHMgY29tcGx5aW5nIHdpdGggdGhlIEZlZHMgY2FwaXRhbCBhZGVxdWFjeSBzdGFuZGFyZHMgYW5kIGFkanVzdGluZyBjb250aW51b3VzbHkgdG8gbmV3IHJlZ3VsYXRpb25zLiBBZGRpdGlvbmFsbHkgaXQgaXMgbWVudGlvbmVkIHRoYXQgdGhleSBoYXZlIHRvIGNvbnNpZGVyIGFuZCBtYW5hZ2UgbmV3IHJpc2tzIHRoYXQgY29tZXMgd2l0aCBzY3J1dGlueS4KCgojTDUuMjIgRGVzY3JpYmUgdGhlIHJlY2VudCBwZXJmb3JtYW5jZSBvZiB0aGUgc2VjdXJpdGllcyBmaXJtLCBhbmQgZXhwbGFpbiB3aHkgdGhlIHBlcmZvcm1hbmNlIGhhcyBiZWVuIGZhdm9yYWJsZSBvciB1bmZhdm9yYWJsZS4KI0luIDIwMjQsIEdvbGRtYW4gU2FjaHMgZXhwZXJpZW5jZWQgc3Ryb25nIHBlcmZvcm1hbmNlIGluIGludmVzdG1lbnQgYmFua2luZyBhbmQgdHJhZGluZywgcGFydGljdWxhcmx5IGluIGVxdWl0eSBhbmQgZml4ZWQtaW5jb21lIG1hcmtldHMuIEhvd2V2ZXIsIHdlYWtlciBhY3Rpdml0eSBpbiBtZXJnZXJzIGFuZCBhY3F1aXNpdGlvbnMgZHVlIHRvIHdvcnNlIGVjb25vbWljIGNvbmRpdGlvbnMgY3JlYXRlZCBjaGFsbGVuZ2VzLiBUaGUgZmlybSdzIGRpdmVyc2lmaWVkIHJldmVudWUgc291cmNlcywgc3RyZW5ndGhlbmVkIGJ5IGFzc2V0IG1hbmFnZW1lbnQgYW5kIGNvbnN1bWVyIHBsYXRmb3JtcywgaGVscGVkIGtlZXAgaXRzIG92ZXJhbGwgcHJvZml0YWJpbGl0eSBhbmQgcmVzaWxpZW5jZSBhbW9uZyB0aGVzZSBmbHVjdHVhdGlvbnMuCgojTDYgRXF1aXR5IChObyBUYXNrKQoKCgojIyBMNy4xOiBDb21wYXJpbmcgWWllbGRzIG9uIENvcnBvcmF0ZSBIaWdoLVF1YWxpdHkgQm9uZHMgYW5kIFRyZWFzdXJ5IEJvbmRzCgojIyMgQ29kZSB0byBSZXRyaWV2ZSBhbmQgQ29tcGFyZSBZaWVsZHMKCmBgYHtyfQojIEluc3RhbGwgYW5kIGxvYWQgbmVjZXNzYXJ5IHBhY2thZ2VzCmlmICghcmVxdWlyZShxdWFudG1vZCkpIGluc3RhbGwucGFja2FnZXMoInF1YW50bW9kIikKbGlicmFyeShxdWFudG1vZCkKCiMgRGVmaW5lIGRhdGUgcmFuZ2UKc3RhcnRfZGF0ZSA8LSBhcy5EYXRlKCIyMDI0LTA1LTAxIikKZW5kX2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wOS0zMCIpCgojIERvd25sb2FkIGRhdGEgZm9yIFRyZWFzdXJ5IGFuZCBjb3Jwb3JhdGUgaGlnaC1xdWFsaXR5IGJvbmRzCnRyeUNhdGNoKHsKICBnZXRTeW1ib2xzKCJER1MxMCIsIHNyYyA9ICJGUkVEIiwgZnJvbSA9IHN0YXJ0X2RhdGUsIHRvID0gZW5kX2RhdGUpICAgICAgICMgMTAteWVhciBUcmVhc3VyeSBib25kIHlpZWxkCiAgZ2V0U3ltYm9scygiQkFNTEMwQTFDQUFBRVkiLCBzcmMgPSAiRlJFRCIsIGZyb20gPSBzdGFydF9kYXRlLCB0byA9IGVuZF9kYXRlKSAgIyBBQUEtcmF0ZWQgY29ycG9yYXRlIGJvbmQgeWllbGQKICAKICAjIEV4dHJhY3QgeWllbGRzIGF0IHRoZSBlbmQgb2YgdGhlIHNjaG9vbCB0ZXJtCiAgdHJlYXN1cnlfeWllbGQgPC0gbmEub21pdChER1MxMFtlbmRfZGF0ZV0gLyAxMDApICAgICAgICAgICAjIENvbnZlcnQgdG8gcGVyY2VudGFnZQogIGNvcnBvcmF0ZV95aWVsZCA8LSBuYS5vbWl0KEJBTUxDMEExQ0FBQUVZW2VuZF9kYXRlXSAvIDEwMCkgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKICAKICAjIENhbGN1bGF0ZSB0aGUgeWllbGQgZGlmZmVyZW5jZSAoc3ByZWFkKQogIHlpZWxkX2RpZmZlcmVuY2UgPC0gZmlyc3QoY29ycG9yYXRlX3lpZWxkKSAtIGZpcnN0KHRyZWFzdXJ5X3lpZWxkKQogIAogICMgRGlzcGxheSByZXN1bHRzCiAgY2F0KCIxMC1ZZWFyIFRyZWFzdXJ5IEJvbmQgWWllbGQgb24iLCBlbmRfZGF0ZSwgIjoiLCByb3VuZChmaXJzdCh0cmVhc3VyeV95aWVsZCkgKiAxMDAsIDIpLCAiJVxuIikKICBjYXQoIkNvcnBvcmF0ZSBIaWdoLVF1YWxpdHkgQm9uZCBZaWVsZCBvbiIsIGVuZF9kYXRlLCAiOiIsIHJvdW5kKGZpcnN0KGNvcnBvcmF0ZV95aWVsZCkgKiAxMDAsIDIpLCAiJVxuIikKICBjYXQoIllpZWxkIFByZW1pdW0gKENvcnBvcmF0ZSAtIFRyZWFzdXJ5KToiLCByb3VuZCh5aWVsZF9kaWZmZXJlbmNlICogMTAwLCAyKSwgIiVcbiIpCn0sIGVycm9yID0gZnVuY3Rpb24oZSkgewogIGNhdCgiRXJyb3IgcmV0cmlldmluZyBkYXRhOiIsIGUkbWVzc2FnZSwgIlxuIikKfSkKYGBgCgojQ29uY2x1c2lvbgoKQ29ycG9yYXRlcyBoaWdoLXF1YWxpdHkgYm9uZHMgYmFzaWNhbGx5IGhhdmUgYSBoaWdoZXIgeWllbGQgdGhhbiBUcmVhc3VyaWVzIGJlY2F1c2Ugb2YgdGhlIGNyZWRpdCByaXNrIHByZW1pdW0gYW5kIGxpcXVpZGl0eSBhZHZhbnRhZ2VkLiBSaXNrLWZyZWUgVHJlYXN1cnkgYm9uZHMgYXJlIGJhY2tlZCBieSB0aGUgVS5TLiBnb3Zlcm5tZW50ICh0aGVyZWZvcmUgdGhlcmUgaXMgbm9uZSksIGNvcnBvcmF0ZSBib25kcyBvbiB0aGUgb3RoZXIgaGFuZCBpbXBseSBzb21lIGRlZ3JlZSBvZiByaXNrIG9mIGRlZmF1bHQgYXJlIGxlc3MgbGlxdWlkIGFuZCB0aHVzIHJlcXVpcmUgYSBoaWdoZXIgeWllbGQgdG8gZW50aWNlIGludmVzdG9ycy4KV2hlbiBlY29ub21pYyBoZWFsdGggcHJldmFpbHMsIHRoZSBzcHJlYWQgaXMgc21hbGxlciBhcyBjb25maWRlbmNlIGlzIGhpZ2hlciBmb3IgY29ycG9yYXRlIGJvbmRzLiBXaGVuIHRoZSBlY29ub215IGlzIGluIGZsdXgsIHRoZXJlIGlzIHdpZGVuaW5nIG9mIHNwcmVhZCBiZWNhdXNlIHJpc2sgaXMgcGVyY2VpdmVkIGhpZ2hlciBhbmQgaGVuY2UgdGhlIHF1ZXN0IGZvciBzYWZldHkuIEl0IGFsc28gc2hlZHMgbGlnaHQgb24gc2FmZXR5IHZzLiByZXR1cm4gdHJhZGUgb2ZmIGFuZCB3aGVyZSB0aGUgZXh0cmEgeWllbGQgb2YgY29ycG9yYXRlcyBpcyBiZWluZyBlYXJuZWQ6IHNhZmVyIHNlY3VyaXRpZXMgKGFzIG1lYXN1cmVkIGJ5IHRoZSByZXR1cm4gb2YgVC1ib25kcykuCgoKICAKI0w3LjMgV2hhdCB3YXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgMjYtd2VlayBULWJpbGwgeWllbGQgYW5kIHRoZSAxMy13ZWVrIFQtYmlsbCB5aWVsZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzY2hvb2wgdGVybT8KIAogCiAjIEluc3RhbGwgYW5kIGxvYWQgbmVjZXNzYXJ5IHBhY2thZ2VzCiAKIApgYGB7cn0KCgogCiAgaWYgKCFyZXF1aXJlKHF1YW50bW9kKSkgaW5zdGFsbC5wYWNrYWdlcygicXVhbnRtb2QiKQpsaWJyYXJ5KHF1YW50bW9kKQoKCiMgRGVmaW5lIHRoZSBzdGFydCBkYXRlIG9mIHRoZSBzY2hvb2wgdGVybQpzdGFydF9kYXRlIDwtIGFzLkRhdGUoIjIwMjQtMDUtMDEiKQoKCiMgRG93bmxvYWQgZGF0YSBmb3IgMjYtd2VlayBhbmQgMTMtd2VlayBULWJpbGwgeWllbGRzCnRyeUNhdGNoKHsKICBnZXRTeW1ib2xzKCJEVEI2Iiwgc3JjID0gIkZSRUQiLCBmcm9tID0gIjIwMjQtMDQtMDEiLCB0byA9ICIyMDI0LTA1LTE1IikgICMgMjYtd2VlayBULWJpbGwKICBnZXRTeW1ib2xzKCJEVEIzIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gIjIwMjQtMDQtMDEiLCB0byA9ICIyMDI0LTA1LTE1IikgICMgMTMtd2VlayBULWJpbGwKICAKICAKICAjIEV4dHJhY3QgeWllbGRzIGF0IHRoZSBzdGFydCBvZiB0aGUgc2Nob29sIHRlcm0KICB0X2JpbGxfMjZfeWllbGQgPC0gbmEub21pdChEVEI2W3N0YXJ0X2RhdGVdIC8gMTAwKSAgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKICB0X2JpbGxfMTNfeWllbGQgPC0gbmEub21pdChEVEIzW3N0YXJ0X2RhdGVdIC8gMTAwKSAgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKICAKICAKICAjIENhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBpbiB5aWVsZHMKICB5aWVsZF9kaWZmZXJlbmNlIDwtIGZpcnN0KHRfYmlsbF8yNl95aWVsZCkgLSBmaXJzdCh0X2JpbGxfMTNfeWllbGQpCgpgYGAKCmBgYHtyfQoKCiAgCiAKICAjIERpc3BsYXkgcmVzdWx0cwogIGNhdCgiMjYtd2VlayBULWJpbGwgeWllbGQgb24iLCBzdGFydF9kYXRlLCAiOiIsIHJvdW5kKGZpcnN0KHRfYmlsbF8yNl95aWVsZCkgKiAxMDAsIDIpLCAiJVxuIikKICBjYXQoIjEzLXdlZWsgVC1iaWxsIHlpZWxkIG9uIiwgc3RhcnRfZGF0ZSwgIjoiLCByb3VuZChmaXJzdCh0X2JpbGxfMTNfeWllbGQpICogMTAwLCAyKSwgIiVcbiIpCiAgY2F0KCJZaWVsZCBEaWZmZXJlbmNlICgyNi13ZWVrIC0gMTMtd2Vlayk6Iiwgcm91bmQoeWllbGRfZGlmZmVyZW5jZSAqIDEwMCwgMiksICIlXG4iKQp9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICBjYXQoIkVycm9yIHJldHJpZXZpbmcgZGF0YToiLCBlJG1lc3NhZ2UsICJcbiIpCn0pCgpgYGAKCgoKCgoKI0NvbmNsdXNpb24KVGhlIGRpZmZlcmVuY2UgaW4geWllbGRzIGJldHdlZW4gdGhlIDI2LXdlZWsgVC1iaWxsIGFuZCAxMy13ZWVrIFQtYmlsbCBhbnkgdGltZSBNYXkgMSAyMDI0IHNob3dzIHRoZSB1cC1zbG9wZSBvZiBzaG9ydCBlbmQgeWllbGQgY3VydmUgYXQgc3RhcnQgb2Ygc2Nob29sIHRlcm0gc2xvcGUuIFRoZSBwb3NpdGl2ZSBkaWZmZXJlbmNlIGlzIHBvaW50aW5nIHNsb3BlcyB1cHdhcmQgYW5kIGFzIGFuIGluZGljYXRvciBmb3IgcmlzZSBpbiBpbnRlcmVzdCByYXRlcyBpbiB0aGUgbmVhciB0ZXJtIFRoZSBkb3dud2FyZCBzbG9wZSAobmVnYXRpdmUgZGlmZmVyZW5jZXMpIHdvdWxkIHN1Z2dlc3QgdGhhdCBzb21lb25lIGlzIGV4cGVjdGluZyByYXRlcyB0byBjb21lIGRvd24uClRoaXMgYmVuY2htYXJrIGdpdmVzIG1hcmtldCBzZW50aW1lbnQgYXJvdW5kIG1vdmluZyBzaG9ydC10ZXJtIGludGVyZXN0IHJhdGVzIGFuZCB0aGUgYnJvYWQgZWNvbm9taWMgYmFja2Ryb3AuIEl0IHF1YW50aWZpZXMgaG93IGludmVzdG9ycyB2YWx1ZSBkaWZmZXJlbnQgcmlzayBhbmQgbGlxdWlkaXR5IHByZW1pYSBhY3Jvc3MgbWF0dXJpdGllcyBpbiB0aGUgVHJlYXN1cnkgc3BhY2UuCgoKCiNMNy40IERvZXMgdGhpcyBpbXBseSB0aGF0IHRoZSB5aWVsZCBjdXJ2ZSBoYWQgYW4gdXB3YXJkIG9yIGRvd253YXJkIHNsb3BlIGF0IHRoYXQgdGltZT8KYGBge3J9CgoKICAKIyBEZXRlcm1pbmUgdGhlIHNsb3BlIG9mIHRoZSB5aWVsZCBjdXJ2ZSBhbmQgbWFya2V0IGV4cGVjdGF0aW9ucwogIGlmIChleGlzdHMoInlpZWxkX2RpZmZlcmVuY2UiKSkgewogICAgaWYgKHlpZWxkX2RpZmZlcmVuY2UgPiAwKSB7CiAgICAgIGNhdCgiVGhlIHVwd2FyZCBzbG9wZSBvZiB0aGUgeWllbGQgY3VydmUgYXQgdGhhdCB0aW1lIGltcGxpZXMgdGhhdCB0aGUgbWFya2V0IGV4cGVjdGVkIGhpZ2hlciBpbnRlcmVzdCByYXRlcyBpbiB0aGUgZnV0dXJlLlxuIikKICAgIH0gZWxzZSBpZiAoeWllbGRfZGlmZmVyZW5jZSA8IDApIHsKICAgICAgY2F0KCJUaGUgZG93bndhcmQgc2xvcGUgb2YgdGhlIHlpZWxkIGN1cnZlIGF0IHRoYXQgdGltZSBpbXBsaWVzIHRoYXQgdGhlIG1hcmtldCBleHBlY3RlZCBsb3dlciBpbnRlcmVzdCByYXRlcyBpbiB0aGUgZnV0dXJlLlxuIikKICAgIH0gZWxzZSB7CiAgICAgIGNhdCgiQSBmbGF0IHlpZWxkIGN1cnZlIGF0IHRoYXQgdGltZSBpbXBsaWVzIHRoYXQgdGhlIG1hcmtldCBkaWQgbm90IGV4cGVjdCBzaWduaWZpY2FudCBjaGFuZ2VzIGluIGludGVyZXN0IHJhdGVzLlxuIikKICAgIH0KICB9IGVsc2UgewogICAgY2F0KCJZaWVsZCBkaWZmZXJlbmNlIGlzIG5vdCBhdmFpbGFibGU7IHVuYWJsZSB0byBkZXRlcm1pbmUgdGhlIHNsb3BlIG9mIHRoZSB5aWVsZCBjdXJ2ZS5cbiIpCiAgfQoKYGBgCgoKCgojQ29uY2x1c2lvbgpUaGUgc2hhcGUgb3Igc2xvcGUgb2YgdGhlIHlpZWxkIGN1cnZlIGdpdmVzIGFuIGluZGljYXRpb24gb2Ygd2hlcmUgZnV0dXJlIGludGVyZXN0IHJhdGVzIGFyZSBleHBlY3RlZCBieSB0aGUgbWFya2V0OgpVcHdhcmQtc2xvcGluZyAocG9zaXRpdmUgeWllbGQgYmVuZWZpdCk6IFRoZSBtYXJrZXQgZXhwZWN0ZWQgcmF0ZXMgdG8gYmUgaGlnaGVyIGdvaW5nIGZvcndhcmQsIHR5cGljYWxseSBkdWUgdG8gZ3Jvd3RoIG9wdGltaXNtLgpEb3dud2FyZC1zbG9waW5nIChuZWdhdGl2ZSBzcHJlYWQpOiBQcm9iYWJseSBpbXBsaWVzIGFuIGV4cGVjdGF0aW9uIG9mIGNvbWluZyBsb3dlciBpbnRlcmVzdCByYXRlcyBvbiBleHBlY3RhdGlvbiB0aGF0IGFjdGl2aXR5IG1pZ2h0IHNsb3cuCkhvbnVzIGN5Y2xlICh6ZXJvIHlpZWxkIGRpZmZlcmVuY2UpOiBUaGUgbWFya2V0IHdhcyBlc3NlbnRpYWxseSBwdXR0aW5nIG5vIGZyaWxscyByYXRlcyBiZXRzIGludG8gdGhlIGN1cnZlIGltcGx5aW5nIGEgbmV1dHJhbCBvciB1bnN1cmUgb3V0bG9vay4KVGhpcyBhbmFseXNpcyB1bmRlcnNjb3JlcyB0aGF0IHNob3J0LXRlcm0geWllbGRzIGFyZSBiYXJvbWV0ZXJzIG9mIHRoZSBlY29ub21pYyBzZW50aW1lbnQgYW5kIG1vbmV0YXJ5IHBvbGljeSBzdGFuY2UuCgojTDcuNSBBc3N1bWluZyB0aGF0IHRoaXMgc2xvcGUgY2FuIGJlIHByaW1hcmlseSBhdHRyaWJ1dGVkIHRvIGV4cGVjdGF0aW9ucyB0aGVvcnksIGRpZCB0aGUgZGlyZWN0aW9uIG9mIHRoZSBzbG9wZSBpbmRpY2F0ZSB0aGF0IHRoZSBtYXJrZXQgZXhwZWN0ZWQgaGlnaGVyIG9yIGxvd2VyIGludGVyZXN0IHJhdGVzIGluIHRoZSBmdXR1cmU/CiAKI1dpdGggdGhlIHNhbWUgY29kZSAoTDcuNCkKI0FjY29yZGluZyB0byBleHBlY3RhdGlvbnMgdGhlb3J5LCB0aGUgc2xvcGUgb2YgdGhlIHlpZWxkIGN1cnZlIHJlZmxlY3RzIG1hcmtldCBwcmVkaWN0aW9ucyBhYm91dCBmdXR1cmUgaW50ZXJlc3QgcmF0ZXM6CgojVXB3YXJkIHNsb3BlOiBJbmRpY2F0ZXMgdGhhdCB0aGUgbWFya2V0IGV4cGVjdGVkIGhpZ2hlciBpbnRlcmVzdCByYXRlcyBpbiB0aGUgZnV0dXJlLCBvZnRlbiBzaWduYWxpbmcgb3B0aW1pc20gYWJvdXQgZWNvbm9taWMgZ3Jvd3RoIG9yIHBvdGVudGlhbCBtb25ldGFyeSB0aWdodGVuaW5nLgoKI0Rvd253YXJkIHNsb3BlOiBTdWdnZXN0cyB0aGF0IHRoZSBtYXJrZXQgZXhwZWN0ZWQgbG93ZXIgaW50ZXJlc3QgcmF0ZXMgaW4gdGhlIGZ1dHVyZSwgcmVmbGVjdGluZyBjb25jZXJucyBhYm91dCBlY29ub21pYyBzbG93ZG93biBvciBwb3RlbnRpYWwgbW9uZXRhcnkgZWFzaW5nLgoKI0ZsYXQgY3VydmU6IFN1Z2dlc3RzIHRoYXQgdGhlIG1hcmtldCBleHBlY3RlZCBzdGFibGUgaW50ZXJlc3QgcmF0ZXMgd2l0aCBubyBzaWduaWZpY2FudCBjaGFuZ2VzIGFudGljaXBhdGVkLgoKI1RoaXMgYW5hbHlzaXMgZGVtb25zdHJhdGVzIGhvdyBtYXJrZXQgZXhwZWN0YXRpb25zIGFib3V0IGludGVyZXN0IHJhdGVzIGFyZSBlbWJlZGRlZCBpbiB0aGUgeWllbGQgY3VydmUncyBzbG9wZS4KCgojTDcuNiBEaWQgaW50ZXJlc3QgcmF0ZXMgbW92ZSBpbiB0aGF0IGRpcmVjdGlvbiBvdmVyIHRoZSBzY2hvb2wgdGVybT8KYGBge3J9CgoKCiMgSW5zdGFsbCBhbmQgbG9hZCBuZWNlc3NhcnkgcGFja2FnZXMKaWYgKCFyZXF1aXJlKHF1YW50bW9kKSkgaW5zdGFsbC5wYWNrYWdlcygicXVhbnRtb2QiKQpsaWJyYXJ5KHF1YW50bW9kKQoKCiMgRGVmaW5lIHRoZSBkYXRlcyBmb3IgdGhlIHNjaG9vbCB0ZXJtCnN0YXJ0X2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wNS0wMSIpCmVuZF9kYXRlIDwtIGFzLkRhdGUoIjIwMjQtMDktMzAiKQoKCiMgRG93bmxvYWQgZGF0YSBmb3IgMTMtd2VlayBhbmQgMjYtd2VlayBULWJpbGwgeWllbGRzCnRyeUNhdGNoKHsKICBnZXRTeW1ib2xzKCJEVEI2Iiwgc3JjID0gIkZSRUQiLCBmcm9tID0gIjIwMjQtMDQtMDEiLCB0byA9ICIyMDI0LTEwLTAxIikgICMgMjYtd2VlayBULWJpbGwKICBnZXRTeW1ib2xzKCJEVEIzIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gIjIwMjQtMDQtMDEiLCB0byA9ICIyMDI0LTEwLTAxIikgICMgMTMtd2VlayBULWJpbGwKCgogICMgRXh0cmFjdCB5aWVsZHMgYXQgdGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhlIHNjaG9vbCB0ZXJtCiAgdF9iaWxsXzI2X3N0YXJ0IDwtIG5hLm9taXQoRFRCNltzdGFydF9kYXRlXSAvIDEwMCkgICMgQ29udmVydCB0byBwZXJjZW50YWdlCiAgdF9iaWxsXzEzX3N0YXJ0IDwtIG5hLm9taXQoRFRCM1tzdGFydF9kYXRlXSAvIDEwMCkgICMgQ29udmVydCB0byBwZXJjZW50YWdlCiAgdF9iaWxsXzI2X2VuZCA8LSBuYS5vbWl0KERUQjZbZW5kX2RhdGVdIC8gMTAwKSAgICAgICMgQ29udmVydCB0byBwZXJjZW50YWdlCiAgdF9iaWxsXzEzX2VuZCA8LSBuYS5vbWl0KERUQjNbZW5kX2RhdGVdIC8gMTAwKSAgICAgICMgQ29udmVydCB0byBwZXJjZW50YWdlCgoKICAjIENoZWNrIGlmIGludGVyZXN0IHJhdGVzIG1vdmVkIGluIHRoZSBleHBlY3RlZCBkaXJlY3Rpb24KICBpZiAobGVuZ3RoKHRfYmlsbF8yNl9zdGFydCkgPiAwICYmIGxlbmd0aCh0X2JpbGxfMjZfZW5kKSA+IDAgJiYKICAgICAgbGVuZ3RoKHRfYmlsbF8xM19zdGFydCkgPiAwICYmIGxlbmd0aCh0X2JpbGxfMTNfZW5kKSA+IDApIHsKCgogICAgY2F0KCIxMy13ZWVrIFQtYmlsbCB5aWVsZDpcbiIpCiAgICBjYXQoIiAgU3RhcnQ6Iiwgcm91bmQoZmlyc3QodF9iaWxsXzEzX3N0YXJ0KSAqIDEwMCwgMiksICIlXG4iKQogICAgY2F0KCIgIEVuZDoiLCByb3VuZChmaXJzdCh0X2JpbGxfMTNfZW5kKSAqIDEwMCwgMiksICIlXG4iKQoKCiAgICBjYXQoIjI2LXdlZWsgVC1iaWxsIHlpZWxkOlxuIikKICAgIGNhdCgiICBTdGFydDoiLCByb3VuZChmaXJzdCh0X2JpbGxfMjZfc3RhcnQpICogMTAwLCAyKSwgIiVcbiIpCiAgICBjYXQoIiAgRW5kOiIsIHJvdW5kKGZpcnN0KHRfYmlsbF8yNl9lbmQpICogMTAwLCAyKSwgIiVcbiIpCmBgYAoKYGBge3J9CgoKCgogICAgIyBBbmFseXplIHRoZSBtb3ZlbWVudCBpbiBpbnRlcmVzdCByYXRlcwogICAgaWYgKGZpcnN0KHRfYmlsbF8yNl9lbmQpID4gZmlyc3QodF9iaWxsXzI2X3N0YXJ0KSAmJgogICAgICAgIGZpcnN0KHRfYmlsbF8xM19lbmQpID4gZmlyc3QodF9iaWxsXzEzX3N0YXJ0KSkgewogICAgICBjYXQoIkludGVyZXN0IHJhdGVzIGluY3JlYXNlZCBvdmVyIHRoZSBzY2hvb2wgdGVybSwgYWxpZ25pbmcgd2l0aCBhbiB1cHdhcmQgeWllbGQgY3VydmUuXG4iKQogICAgfSBlbHNlIGlmIChmaXJzdCh0X2JpbGxfMjZfZW5kKSA8IGZpcnN0KHRfYmlsbF8yNl9zdGFydCkgJiYKICAgICAgICAgICAgICAgZmlyc3QodF9iaWxsXzEzX2VuZCkgPCBmaXJzdCh0X2JpbGxfMTNfc3RhcnQpKSB7CiAgICAgIGNhdCgiSW50ZXJlc3QgcmF0ZXMgZGVjcmVhc2VkIG92ZXIgdGhlIHNjaG9vbCB0ZXJtLCBhbGlnbmluZyB3aXRoIGEgZG93bndhcmQgeWllbGQgY3VydmUuXG4iKQogICAgfSBlbHNlIHsKICAgICAgY2F0KCJJbnRlcmVzdCByYXRlcyBtb3ZlZCBpbmNvbnNpc3RlbnRseSwgbm90IGZ1bGx5IGFsaWduaW5nIHdpdGggdGhlIGluaXRpYWwgeWllbGQgY3VydmUgZXhwZWN0YXRpb25zLlxuIikKICAgIH0KICB9IGVsc2UgewogICAgY2F0KCJJbnN1ZmZpY2llbnQgZGF0YSB0byBhbmFseXplIGludGVyZXN0IHJhdGUgbW92ZW1lbnRzLlxuIikKICB9Cn0sIGVycm9yID0gZnVuY3Rpb24oZSkgewogIGNhdCgiRXJyb3IgcmV0cmlldmluZyBkYXRhOiIsIGUkbWVzc2FnZSwgIlxuIikKfSkKYGBgCgpJZiByYXRlcyB3ZXJlIHRvIG1vdmUgYXMgbWFya2V0cyBiZXQgb24sIHRoZSB1cHdhcmQgc3BpcmFsIG9mIGludGVyZXN0IHJhdGVzIGluIHRhbmRlbSB3aXRoIGFuIGFscmVhZHkgdXB3YXJkLXNsb3BpbmcgeWllbGQgY3VydmUgd291bGQgc3VnZ2VzdCB0aGF0IHRoZSBtYXJrZXQgaXMgcHJpY2luZyBpbiBlY29ub21pYyBleHBhbnNpb24gb3IgaW5mbGF0aW9uLCB3aGlsZSBsb3dlciB5aWVsZHMgd291bGQgbWVhbiBhIGxvd2VyIHNsb3BlLCByZWZsZWN0aW5nIGZlYXJzIGFib3V0IGEgZG93bnR1cm4gb3IgbW9uZXRhcnkgZWFzaW5nLiBJZiByYXRlcyBmYWlsZWQgYWN0IGFzIGV4cGVjdGVkLCBvdGhlciBmYWN0b3JzIGV4dGVybmFsIHRvIGZpbmFuY2lhbCBtYXJrZXRzIHN1Y2ggYXMgZ2VvcG9saXRpY3Mgb3IgdW5hbnRpY2lwYXRlZCBtb25ldGFyeSBwb2xpY3kgZGV2ZWxvcG1lbnRzIGFuZC9vciBzdXJwcmlzZXMgaW4gbWFjcm8gZGF0YSBjb3VsZCBoYXZlIHN3YXllZCBpbml0aWFsIG1hcmtldCBjYWxscy4gVGhpcyBhbmFseXNpcyBpbmRpY2F0ZXMgdGhlIHJlbGF0aW9uIGJldHdlZW4geWllbGQgY3VydmUgbW92ZW1lbnRzIGFuZCBtYXJrZXQtaW1wbGllZCBleHBlY3RhdGlvbnMsIGFyZ3VhYmx5IHByb3ZpZGluZyB1c2VmdWwgaW5zaWdodHMgaW50byB0aGUgZGVncmVlIG9mIGFjY3VyYWN5IGV2ZXJ5bWFuIGludmVzdG9yIGNhbiBoYXZlLgoKCiNFeHBsYWluaW5nIHNoaWZ0cyBpbiB0aGUgeWllbGQgY3VydmUgb3ZlciB0aW1lCgpgYGB7cn0KCgoKI0w3LjcgV2hhdCB3YXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgbG9uZy10ZXJtIFRyZWFzdXJ5IGJvbmQgeWllbGQgYW5kIHRoZSAxMy13ZWVrIFQtYmlsbCB5aWVsZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzY2hvb2wgdGVybT8KCiMgSW5zdGFsbCBhbmQgbG9hZCBuZWNlc3NhcnkgcGFja2FnZXMKaWYgKCFyZXF1aXJlKHF1YW50bW9kKSkgaW5zdGFsbC5wYWNrYWdlcygicXVhbnRtb2QiKQpsaWJyYXJ5KHF1YW50bW9kKQoKCiMgRGVmaW5lIHRoZSBzdGFydCBkYXRlIG9mIHRoZSBzY2hvb2wgdGVybQpzdGFydF9kYXRlIDwtIGFzLkRhdGUoIjIwMjQtMDUtMDEiKQoKCiMgRG93bmxvYWQgZGF0YSBmb3IgbG9uZy10ZXJtIFRyZWFzdXJ5IGJvbmQgYW5kIDEzLXdlZWsgVC1iaWxsIHlpZWxkcwp0cnlDYXRjaCh7CiAgICBnZXRTeW1ib2xzKCJER1MzMCIsIHNyYyA9ICJGUkVEIiwgZnJvbSA9ICIyMDI0LTA0LTAxIiwgdG8gPSAiMjAyNC0wNS0xNSIpICAjIDMwLXllYXIgVHJlYXN1cnkgYm9uZAogICAgZ2V0U3ltYm9scygiRFRCMyIsIHNyYyA9ICJGUkVEIiwgZnJvbSA9ICIyMDI0LTA0LTAxIiwgdG8gPSAiMjAyNC0wNS0xNSIpICAjIDEzLXdlZWsgVC1iaWxsCgoKICAgICMgRXh0cmFjdCB5aWVsZHMgYXQgdGhlIHN0YXJ0IG9mIHRoZSBzY2hvb2wgdGVybQogICAgbG9uZ190ZXJtX3lpZWxkIDwtIG5hLm9taXQoREdTMzBbc3RhcnRfZGF0ZV0gLyAxMDApICAjIENvbnZlcnQgdG8gcGVyY2VudGFnZQogICAgc2hvcnRfdGVybV95aWVsZCA8LSBuYS5vbWl0KERUQjNbc3RhcnRfZGF0ZV0gLyAxMDApICAjIENvbnZlcnQgdG8gcGVyY2VudGFnZQoKCiAgICAjIENhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZQogICAgeWllbGRfZGlmZmVyZW5jZSA8LSBmaXJzdChsb25nX3Rlcm1feWllbGQpIC0gZmlyc3Qoc2hvcnRfdGVybV95aWVsZCkKCgogICAgIyBEaXNwbGF5IHJlc3VsdHMKICAgIGNhdCgiMzAtWWVhciBUcmVhc3VyeSBCb25kIFlpZWxkIG9uIiwgc3RhcnRfZGF0ZSwgIjoiLCByb3VuZChmaXJzdChsb25nX3Rlcm1feWllbGQpICogMTAwLCAyKSwgIiVcbiIpCiAgICBjYXQoIjEzLVdlZWsgVC1CaWxsIFlpZWxkIG9uIiwgc3RhcnRfZGF0ZSwgIjoiLCByb3VuZChmaXJzdChzaG9ydF90ZXJtX3lpZWxkKSAqIDEwMCwgMiksICIlXG4iKQogICAgY2F0KCJZaWVsZCBEaWZmZXJlbmNlICgzMC1ZZWFyIC0gMTMtV2Vlayk6Iiwgcm91bmQoeWllbGRfZGlmZmVyZW5jZSAqIDEwMCwgMiksICIlXG4iKQp9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgIGNhdCgiRXJyb3IgcmV0cmlldmluZyBkYXRhOiIsIGUkbWVzc2FnZSwgIlxuIikKfSkKCmBgYAoKCgoKI0NvbmNsdXNpb24KVGhlIHlpZWxkIG9uIHRoZSBsb25nIHRlcm0gVVMgVHJlYXN1cnkgYm9uZCBhbmQgTWF5IDEsIDIwMjQsIHlpZWxkIG9uIHRoZSAxMy13ZWVrIFQtYmlsbCByZWZsZWN0cyB0aGUgeWllbGQgY3VydmUgYXQgdGhlIGJlZ2lubmluZyBvZiB0ZXJtCk1hcmtldCBleHBlY3RhdGlvbnMgZm9yIHJpc2luZyBpbnRlcmVzdCByYXRlcyBhbmQgd2hhdCB0aGF0IGltcGxpZXMgYWJvdXQgeWV0IHRvIGNvbWUgZ3Jvd3RoIGluIHRoZSBlY29ub215IGlzIGFuIHVwd2FyZC1zbG9waW5nIHlpZWxkIGN1cnZlIOKAlCBhIHBvc2l0aXZlIGRpZmZlcmVuY2UuCkFuIGludmVydGVkIHlpZWxkIGN1cnZlIG5lZ2F0aXZlIHN1Z2dlc3RzIGJhY2t3YXJkcyBsb29raW5nIG9mIGZ1dHVyZSBpbnRlcmVzdCByYXRlcyBsaWtlbHkgdG8gYmUgbG93ZXIgYW5kIGVjb25vbWljIHNsb3dkb3duLgpBIDAtZGlmZmVyZW5jZSBpbmRpY2F0ZXMgZmxhdCB5aWVsZCBjdXJ2ZSBtZWFuaW5nIGludGVyZXN0IHJhdGVzIGhlYWRlZCBpbiB0aGUgc2FtZSBkaXJlY3Rpb24uClRoaXMgZ2FwIG9mZmVycyBhIGxvdCBvZiB2YWx1ZSBmb3IgYm90aCB0aGUgaW5pdGlhbCByZXNwb25zZSBvZiBzZW50aW1lbnQgYW5kIGVjb25vbWljIHN0YW5jZSBhdCB0aGUgc3RhcnQgb2YgZXZlcnkgdGVybS4KCgpgYGB7cn0KCgoKI0w3LjggV2hhdCBpcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBsb25nLXRlcm0gVHJlYXN1cnkgYm9uZCB5aWVsZCBhbmQgdGhlIDEzLXdlZWsgVC1iaWxsIHlpZWxkIGF0IHRoZSBlbmQgb2YgdGhlIHNjaG9vbCB0ZXJtPwoKIyBJbnN0YWxsIGFuZCBsb2FkIG5lY2Vzc2FyeSBwYWNrYWdlcwppZiAoIXJlcXVpcmUocXVhbnRtb2QpKSBpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIpCmxpYnJhcnkocXVhbnRtb2QpCgoKIyBEZWZpbmUgdGhlIGVuZCBkYXRlIG9mIHRoZSBzY2hvb2wgdGVybQplbmRfZGF0ZSA8LSBhcy5EYXRlKCIyMDI0LTA5LTMwIikKCgojIERvd25sb2FkIGRhdGEgZm9yIGxvbmctdGVybSBUcmVhc3VyeSBib25kIGFuZCAxMy13ZWVrIFQtYmlsbCB5aWVsZHMKdHJ5Q2F0Y2goewogICAgZ2V0U3ltYm9scygiREdTMzAiLCBzcmMgPSAiRlJFRCIsIGZyb20gPSAiMjAyNC0wOC0wMSIsIHRvID0gIjIwMjQtMTAtMDEiKSAgIyAzMC15ZWFyIFRyZWFzdXJ5IGJvbmQKICAgIGdldFN5bWJvbHMoIkRUQjMiLCBzcmMgPSAiRlJFRCIsIGZyb20gPSAiMjAyNC0wOC0wMSIsIHRvID0gIjIwMjQtMTAtMDEiKSAgIyAxMy13ZWVrIFQtYmlsbAoKCiAgICAjIEV4dHJhY3QgeWllbGRzIGF0IHRoZSBlbmQgb2YgdGhlIHNjaG9vbCB0ZXJtCiAgICBsb25nX3Rlcm1feWllbGQgPC0gbmEub21pdChER1MzMFtlbmRfZGF0ZV0gLyAxMDApICAjIENvbnZlcnQgdG8gcGVyY2VudGFnZQogICAgc2hvcnRfdGVybV95aWVsZCA8LSBuYS5vbWl0KERUQjNbZW5kX2RhdGVdIC8gMTAwKSAgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKCgogICAgIyBDYWxjdWxhdGUgdGhlIGRpZmZlcmVuY2UKICAgIHlpZWxkX2RpZmZlcmVuY2UgPC0gZmlyc3QobG9uZ190ZXJtX3lpZWxkKSAtIGZpcnN0KHNob3J0X3Rlcm1feWllbGQpCgoKICAgICMgRGlzcGxheSByZXN1bHRzCiAgICBjYXQoIjMwLVllYXIgVHJlYXN1cnkgQm9uZCBZaWVsZCBvbiIsIGVuZF9kYXRlLCAiOiIsIHJvdW5kKGZpcnN0KGxvbmdfdGVybV95aWVsZCkgKiAxMDAsIDIpLCAiJVxuIikKICAgIGNhdCgiMTMtV2VlayBULUJpbGwgWWllbGQgb24iLCBlbmRfZGF0ZSwgIjoiLCByb3VuZChmaXJzdChzaG9ydF90ZXJtX3lpZWxkKSAqIDEwMCwgMiksICIlXG4iKQogICAgY2F0KCJZaWVsZCBEaWZmZXJlbmNlICgzMC1ZZWFyIC0gMTMtV2Vlayk6Iiwgcm91bmQoeWllbGRfZGlmZmVyZW5jZSAqIDEwMCwgMiksICIlXG4iKQp9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgIGNhdCgiRXJyb3IgcmV0cmlldmluZyBkYXRhOiIsIGUkbWVzc2FnZSwgIlxuIikKfSkKCmBgYAoKCiNDb25jbHVzaW9uClRoZSBzcHJlYWQgYmV0d2VlbiB0aGUgbG9uZyB0ZXJtIFRyZWFzdXJ5IGJvbmQgeWllbGQgYW5kIHRoZSBULWJpbGwgMTMtd2VlayBvbiBTZXB0ZW1iZXIgMzAvMjAyNCBnaXZlcyB5b3UgYSBjbHVlIGFzIHRvIHRoZSBjdXJ2ZSBlbmQtb2Ytc2Nob29sIHRlcm0geWllbGQgY3VydmUgYmVpbmcgc2lkZXdheXMsIHVwLXNsb3BpbmcgKGJ1eWluZyBmcm9vIHJpY3JhdGVzIGFuZCBhbmNobyBsYXNzIHBvdGVudGlhbHNjYWxlKSBhbmQgbmVnYXRpdmUgYWxzbyBzdWdnZXN0cyBpbnZlcnNpb24gKHNpZ25hbGluZyBkZWNsaW5pbmcgZnV0dXJlIGludGVyZXN0IHJhdGVzLCBlY29ub21pYyBtYWxhaXNlKSB6ZXJvIG1lYW4gaXMgZmxhdCwgdGhhdCBib3RoIHN0c2hzIGNoYW5nZSBpbnNyYWN0cmlvIHBsYW5zbmNvbXBldGlhbm51YWwgaW50ZXJlc3QgcmF0ZSBlcmFsdmF0aW9uLgpUaGlzIGRpZmZlcmVuY2UgYWxsb3dzIHlvdSB0byBhc3Nlc3MgaG93IGJvdGggbWFya2V0IHNlbnRpbWVudCBhbmQgZWNvbm9taWMgY29uZGl0aW9ucyBjaGFuZ2VkIGluIHRoZSBzY2hvb2wgdGVybS4KCgoKI0w3LjkgR2l2ZW4geW91ciBhbnN3ZXJzIHRvIHRoZSB0d28gcHJldmlvdXMgcXVlc3Rpb25zLCBkZXNjcmliZSBob3cgdGhlIHlpZWxkIGN1cnZlIGNoYW5nZWQgb3ZlciB0aGUgc2Nob29sIHRlcm0uIEV4cGxhaW4gdGhlIGNoYW5nZXMgaW4gZXhwZWN0YXRpb25zIGFib3V0IGZ1dHVyZSBpbnRlcmVzdCByYXRlcyB0aGF0IGFyZSBpbXBsaWVkIGJ5IHRoZSBzaGlmdCBpbiB0aGUgeWllbGQgY3VydmUgb3ZlciB0aGUgc2Nob29sIHRlcm0uCgpgYGB7cn0KCgoKIyBJbnN0YWxsIGFuZCBsb2FkIG5lY2Vzc2FyeSBwYWNrYWdlcwppZiAoIXJlcXVpcmUocXVhbnRtb2QpKSBpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIpCmxpYnJhcnkocXVhbnRtb2QpCgoKIyBEZWZpbmUgc3RhcnQgYW5kIGVuZCBkYXRlcyBvZiB0aGUgc2Nob29sIHRlcm0Kc3RhcnRfZGF0ZSA8LSBhcy5EYXRlKCIyMDI0LTA1LTAxIikKZW5kX2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wOS0zMCIpCgoKIyBEb3dubG9hZCBkYXRhIGZvciBsb25nLXRlcm0gVHJlYXN1cnkgYm9uZCBhbmQgMTMtd2VlayBULWJpbGwgeWllbGRzCnRyeUNhdGNoKHsKICAgIGdldFN5bWJvbHMoIkRHUzMwIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gIjIwMjQtMDQtMDEiLCB0byA9ICIyMDI0LTEwLTAxIikgICMgMzAteWVhciBUcmVhc3VyeSBib25kCiAgICBnZXRTeW1ib2xzKCJEVEIzIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gIjIwMjQtMDQtMDEiLCB0byA9ICIyMDI0LTEwLTAxIikgICMgMTMtd2VlayBULWJpbGwKCgogICAgIyBFeHRyYWN0IHlpZWxkcyBhdCB0aGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgc2Nob29sIHRlcm0KICAgIGxvbmdfdGVybV9zdGFydCA8LSBuYS5vbWl0KERHUzMwW3N0YXJ0X2RhdGVdIC8gMTAwKSAgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKICAgIHNob3J0X3Rlcm1fc3RhcnQgPC0gbmEub21pdChEVEIzW3N0YXJ0X2RhdGVdIC8gMTAwKSAgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKICAgIGxvbmdfdGVybV9lbmQgPC0gbmEub21pdChER1MzMFtlbmRfZGF0ZV0gLyAxMDApICAgICAgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKICAgIHNob3J0X3Rlcm1fZW5kIDwtIG5hLm9taXQoRFRCM1tlbmRfZGF0ZV0gLyAxMDApICAgICAgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKCgogICAgIyBDYWxjdWxhdGUgeWllbGQgZGlmZmVyZW5jZXMgKHNwcmVhZHMpCiAgICBpbml0aWFsX3NwcmVhZCA8LSBmaXJzdChsb25nX3Rlcm1fc3RhcnQpIC0gZmlyc3Qoc2hvcnRfdGVybV9zdGFydCkKICAgIGZpbmFsX3NwcmVhZCA8LSBmaXJzdChsb25nX3Rlcm1fZW5kKSAtIGZpcnN0KHNob3J0X3Rlcm1fZW5kKQoKCiAgICAjIERpc3BsYXkgcmVzdWx0cwogICAgY2F0KCJJbml0aWFsIFNwcmVhZCAoTWF5IDEsIDIwMjQpOiIsIHJvdW5kKGluaXRpYWxfc3ByZWFkICogMTAwLCAyKSwgIiVcbiIpCiAgICBjYXQoIkZpbmFsIFNwcmVhZCAoU2VwdGVtYmVyIDMwLCAyMDI0KToiLCByb3VuZChmaW5hbF9zcHJlYWQgKiAxMDAsIDIpLCAiJVxuIikKCmBgYAoKYGBge3J9CgoKCiAgICAjIEFuYWx5emUgY2hhbmdlcyBpbiB0aGUgeWllbGQgY3VydmUKICAgIGlmIChmaW5hbF9zcHJlYWQgPiBpbml0aWFsX3NwcmVhZCkgewogICAgICAgIGNhdCgiVGhlIHlpZWxkIGN1cnZlIHN0ZWVwZW5lZCBvdmVyIHRoZSBzY2hvb2wgdGVybSwgaW1wbHlpbmcgZXhwZWN0YXRpb25zIG9mIGhpZ2hlciBmdXR1cmUgaW50ZXJlc3QgcmF0ZXMuXG4iKQogICAgfSBlbHNlIGlmIChmaW5hbF9zcHJlYWQgPCBpbml0aWFsX3NwcmVhZCkgewogICAgICAgIGNhdCgiVGhlIHlpZWxkIGN1cnZlIGZsYXR0ZW5lZCBvciBpbnZlcnRlZCBvdmVyIHRoZSBzY2hvb2wgdGVybSwgaW1wbHlpbmcgZXhwZWN0YXRpb25zIG9mIGxvd2VyIG9yIHN0YWJsZSBmdXR1cmUgaW50ZXJlc3QgcmF0ZXMuXG4iKQogICAgfSBlbHNlIHsKICAgICAgICBjYXQoIlRoZSB5aWVsZCBjdXJ2ZSByZW1haW5lZCB1bmNoYW5nZWQgb3ZlciB0aGUgc2Nob29sIHRlcm0sIGluZGljYXRpbmcgbm8gc2lnbmlmaWNhbnQgY2hhbmdlIGluIGludGVyZXN0IHJhdGUgZXhwZWN0YXRpb25zLlxuIikKICAgIH0KfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7CiAgICBjYXQoIkVycm9yIHJldHJpZXZpbmcgZGF0YToiLCBlJG1lc3NhZ2UsICJcbiIpCn0pCgpgYGAKCgoKCiNDb25jbHVzaW9uIAojT3ZlciB0aGUgc2Nob29sIHRlcm0sIGNoYW5nZXMgaW4gdGhlIHlpZWxkIGN1cnZlIHJlZmxlY3Qgc2hpZnRzIGluIG1hcmtldCBleHBlY3RhdGlvbnMgYWJvdXQgZnV0dXJlIGludGVyZXN0IHJhdGVzLiBJZiB0aGUgeWllbGQgY3VydmUgc3RlZXBlbmVkLCBpdCBpbmRpY2F0ZXMgZ3Jvd2luZyBvcHRpbWlzbSwgd2l0aCB0aGUgbWFya2V0IGV4cGVjdGluZyBoaWdoZXIgZnV0dXJlIGludGVyZXN0IHJhdGVzIGR1ZSB0byBlY29ub21pYyBncm93dGggb3IgaW5mbGF0aW9uLiBDb252ZXJzZWx5LCBpZiB0aGUgY3VydmUgZmxhdHRlbmVkIG9yIGludmVydGVkLCBpdCBzaWduYWxzIGNvbmNlcm5zIGFib3V0IHNsb3dpbmcgZWNvbm9taWMgYWN0aXZpdHkgb3IgYW50aWNpcGF0ZWQgbW9uZXRhcnkgZWFzaW5nLCB3aXRoIGV4cGVjdGF0aW9ucyBvZiBsb3dlciByYXRlcy4gQSBjb25zaXN0ZW50IHNwcmVhZCB0aHJvdWdob3V0IHRoZSB0ZXJtIHdvdWxkIHN1Z2dlc3Qgc3RhYmxlIGV4cGVjdGF0aW9ucyB3aXRoIGxpdHRsZSBjaGFuZ2UgaW4gdGhlIGVjb25vbWljIG91dGxvb2suIFRoZXNlIG1vdmVtZW50cyBwcm92aWRlIHZhbHVhYmxlIGluc2lnaHRzIGludG8gaG93IG1hcmtldCBzZW50aW1lbnQgZXZvbHZlZCBkdXJpbmcgdGhlIHNjaG9vbCB0ZXJtLgoKCiNUaGUgRmVk4oCZcyBpbmZsdWVuY2Ugb24gaW50ZXJlc3QgcmF0ZXMKI0w3LjEwIERpZCB0aGUgRmVkIGNoYW5nZSB0aGUgZmVkZXJhbCBmdW5kcyByYXRlIG92ZXIgdGhlIHNjaG9vbCB0ZXJtPwoKYGBge3J9CgoKCiMgSW5zdGFsbCBhbmQgbG9hZCBuZWNlc3NhcnkgcGFja2FnZXMKaWYgKCFyZXF1aXJlKHF1YW50bW9kKSkgaW5zdGFsbC5wYWNrYWdlcygicXVhbnRtb2QiKQpsaWJyYXJ5KHF1YW50bW9kKQoKCiMgRGVmaW5lIGRhdGVzIGZvciB0aGUgc2Nob29sIHRlcm0Kc3RhcnRfZGF0ZSA8LSBhcy5EYXRlKCIyMDI0LTA1LTAxIikKZW5kX2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wOS0zMCIpCgoKIyBEZWZpbmUgZmFsbGJhY2sgZGF0ZXMgKHByZXZpb3VzIHllYXIpCmZhbGxiYWNrX3N0YXJ0X2RhdGUgPC0gYXMuRGF0ZSgiMjAyMy0wNS0wMSIpCmZhbGxiYWNrX2VuZF9kYXRlIDwtIGFzLkRhdGUoIjIwMjMtMDktMzAiKQoKCiMgRnVuY3Rpb24gdG8gcmV0cmlldmUgZmVkZXJhbCBmdW5kcyByYXRlIGRhdGEgd2l0aCBmYWxsYmFjawpnZXRfZmVkX2Z1bmRzX3JhdGUgPC0gZnVuY3Rpb24oc3RhcnRfZGF0ZSwgZW5kX2RhdGUsIGZhbGxiYWNrX3N0YXJ0X2RhdGUsIGZhbGxiYWNrX2VuZF9kYXRlKSB7CiAgICB0cnlDYXRjaCh7CiAgICAgICAgIyBEb3dubG9hZCBmZWRlcmFsIGZ1bmRzIHJhdGUgZGF0YSB3aXRoIHBhZGRpbmcKICAgICAgICBnZXRTeW1ib2xzKCJGRURGVU5EUyIsIHNyYyA9ICJGUkVEIiwgZnJvbSA9IHN0YXJ0X2RhdGUgLSAzMCwgdG8gPSBlbmRfZGF0ZSArIDMwKQogICAgICAgIHJhdGVfc3RhcnQgPC0gbmEub21pdChGRURGVU5EU1tzdGFydF9kYXRlXSAvIDEwMCkgICMgQ29udmVydCB0byBwZXJjZW50YWdlCiAgICAgICAgcmF0ZV9lbmQgPC0gbmEub21pdChGRURGVU5EU1tlbmRfZGF0ZV0gLyAxMDApICAgICAgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKICAgICAgICAKICAgICAgICAjIElmIGRhdGEgaXMgbWlzc2luZywgdXNlIGZhbGxiYWNrIGRhdGVzCiAgICAgICAgaWYgKGxlbmd0aChyYXRlX3N0YXJ0KSA9PSAwIHx8IGxlbmd0aChyYXRlX2VuZCkgPT0gMCkgewogICAgICAgICAgICBjYXQoIkRhdGEgdW5hdmFpbGFibGUgZm9yIiwgc3RhcnRfZGF0ZSwgIi0iLCBlbmRfZGF0ZSwgInVzaW5nIGZhbGxiYWNrIGRhdGVzLlxuIikKICAgICAgICAgICAgZ2V0U3ltYm9scygiRkVERlVORFMiLCBzcmMgPSAiRlJFRCIsIGZyb20gPSBmYWxsYmFja19zdGFydF9kYXRlIC0gMzAsIHRvID0gZmFsbGJhY2tfZW5kX2RhdGUgKyAzMCkKICAgICAgICAgICAgcmF0ZV9zdGFydCA8LSBuYS5vbWl0KEZFREZVTkRTW2ZhbGxiYWNrX3N0YXJ0X2RhdGVdIC8gMTAwKQogICAgICAgICAgICByYXRlX2VuZCA8LSBuYS5vbWl0KEZFREZVTkRTW2ZhbGxiYWNrX2VuZF9kYXRlXSAvIDEwMCkKICAgICAgICB9CiAgICAgICAgcmV0dXJuKGxpc3Qoc3RhcnQgPSByYXRlX3N0YXJ0LCBlbmQgPSByYXRlX2VuZCkpCiAgICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgICAgICBjYXQoIkVycm9yIHJldHJpZXZpbmcgZmVkZXJhbCBmdW5kcyByYXRlIGRhdGE6IiwgZSRtZXNzYWdlLCAiXG4iKQogICAgICAgIHJldHVybihOVUxMKQogICAgfSkKfQoKYGBgCgojIFJldHJpZXZlIGZlZGVyYWwgZnVuZHMgcmF0ZSBkYXRhCgpgYGB7cn0KCgoKZmVkX2Z1bmRzX3JhdGUgPC0gZ2V0X2ZlZF9mdW5kc19yYXRlKHN0YXJ0X2RhdGUsIGVuZF9kYXRlLCBmYWxsYmFja19zdGFydF9kYXRlLCBmYWxsYmFja19lbmRfZGF0ZSkKCgojIEFuYWx5emUgY2hhbmdlcyBpbiB0aGUgZmVkZXJhbCBmdW5kcyByYXRlCmlmICghaXMubnVsbChmZWRfZnVuZHNfcmF0ZSkpIHsKICAgIHJhdGVfc3RhcnQgPC0gZmlyc3QoZmVkX2Z1bmRzX3JhdGUkc3RhcnQpCiAgICByYXRlX2VuZCA8LSBmaXJzdChmZWRfZnVuZHNfcmF0ZSRlbmQpCiAgICAKICAgICMgRGlzcGxheSByZXN1bHRzCiAgICBjYXQoIkZlZGVyYWwgZnVuZHMgcmF0ZSBvbiBzdGFydCBkYXRlOiIsIHJvdW5kKHJhdGVfc3RhcnQgKiAxMDAsIDIpLCAiJVxuIikKICAgIGNhdCgiRmVkZXJhbCBmdW5kcyByYXRlIG9uIGVuZCBkYXRlOiIsIHJvdW5kKHJhdGVfZW5kICogMTAwLCAyKSwgIiVcbiIpCiAgICAKICAgICMgRGV0ZXJtaW5lIGlmIHRoZSByYXRlIGNoYW5nZWQKICAgIGlmICghaXMubmEocmF0ZV9zdGFydCkgJiYgIWlzLm5hKHJhdGVfZW5kKSkgewogICAgICAgIGlmIChyYXRlX3N0YXJ0IDwgcmF0ZV9lbmQpIHsKICAgICAgICAgICAgY2F0KCJUaGUgRmVkIGluY3JlYXNlZCB0aGUgZmVkZXJhbCBmdW5kcyByYXRlIGR1cmluZyB0aGUgc2Nob29sIHRlcm0uXG4iKQogICAgICAgIH0gZWxzZSBpZiAocmF0ZV9zdGFydCA+IHJhdGVfZW5kKSB7CiAgICAgICAgICAgIGNhdCgiVGhlIEZlZCBkZWNyZWFzZWQgdGhlIGZlZGVyYWwgZnVuZHMgcmF0ZSBkdXJpbmcgdGhlIHNjaG9vbCB0ZXJtLlxuIikKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjYXQoIlRoZSBGZWQgZGlkIG5vdCBjaGFuZ2UgdGhlIGZlZGVyYWwgZnVuZHMgcmF0ZSBkdXJpbmcgdGhlIHNjaG9vbCB0ZXJtLlxuIikKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGNhdCgiSW5zdWZmaWNpZW50IGRhdGEgdG8gYW5hbHl6ZSBjaGFuZ2VzIGluIHRoZSBmZWRlcmFsIGZ1bmRzIHJhdGUuXG4iKQogICAgfQp9IGVsc2UgewogICAgY2F0KCJJbnN1ZmZpY2llbnQgZGF0YSB0byBhbmFseXplIGNoYW5nZXMgaW4gdGhlIGZlZGVyYWwgZnVuZHMgcmF0ZS5cbiIpCn0KCgpgYGAKCgoKI0NvbmNsdXNpb24KI0lmIHRoZSByYXRlIGluY3JlYXNlZDogVGhlIEZlZCBwdXJzdWVkIGEgdGlnaHRlciBtb25ldGFyeSBwb2xpY3ksIGxpa2VseSB0byBjb21iYXQgaW5mbGF0aW9uIG9yIHN0YWJpbGl6ZSB0aGUgZWNvbm9teS4KI0lmIHRoZSByYXRlIGRlY3JlYXNlZDogVGhpcyByZWZsZWN0cyBlYXNpbmcgbW9uZXRhcnkgcG9saWN5IGFpbWVkIGF0IHN0aW11bGF0aW5nIGVjb25vbWljIGdyb3d0aCBvciBhZGRyZXNzaW5nIGEgc2xvd2Rvd24uCiNJZiB0aGUgcmF0ZSByZW1haW5lZCB1bmNoYW5nZWQ6IFRoZSBGZWQgbWFpbnRhaW5lZCBhIG5ldXRyYWwgc3RhbmNlLCBzaWduYWxpbmcgY29uc2lzdGVuY3kgaW4gaXRzIG1vbmV0YXJ5IHBvbGljeS4KI0Vycm9yIGlzIGJlY2F1c2UgdGhlcmUgaXMgbm90IGluZm9ybWF0aW9uIGZvciB0aGlzIGRhdGVzIChUcmllZCB0byBzb2x2ZSBpdCB3aXRoIENoYXIgR3B0IDMpCiNTaG93CgojTDcuMTEgRG8geW91IHRoaW5rIHRoZSBtb3ZlbWVudHMgaW4gaW50ZXJlc3QgcmF0ZXMgb3ZlciB0aGUgc2Nob29sIHRlcm0gd2VyZSBjYXVzZWQgYnkgdGhlIEZlZOKAmXMgbW9uZXRhcnkgcG9saWN5PyBFeHBsYWluLgoKYGBge3J9CgoKCiMgSW5zdGFsbCBhbmQgbG9hZCBuZWNlc3NhcnkgcGFja2FnZXMKaWYgKCFyZXF1aXJlKHF1YW50bW9kKSkgaW5zdGFsbC5wYWNrYWdlcygicXVhbnRtb2QiKQpsaWJyYXJ5KHF1YW50bW9kKQoKCiMgRGVmaW5lIGRhdGVzIGZvciB0aGUgc2Nob29sIHRlcm0Kc3RhcnRfZGF0ZSA8LSBhcy5EYXRlKCIyMDI0LTA1LTAxIikKZW5kX2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wOS0zMCIpCgoKIyBEZWZpbmUgZmFsbGJhY2sgZGF0ZXMgKHByZXZpb3VzIHllYXIpCmZhbGxiYWNrX3N0YXJ0X2RhdGUgPC0gYXMuRGF0ZSgiMjAyMy0wNS0wMSIpCmZhbGxiYWNrX2VuZF9kYXRlIDwtIGFzLkRhdGUoIjIwMjMtMDktMzAiKQoKCiMgUmV0cmlldmUgZmVkZXJhbCBmdW5kcyByYXRlIGRhdGEKZ2V0X2ZlZF9mdW5kc19yYXRlIDwtIGZ1bmN0aW9uKHN0YXJ0X2RhdGUsIGVuZF9kYXRlLCBmYWxsYmFja19zdGFydF9kYXRlLCBmYWxsYmFja19lbmRfZGF0ZSkgewogICAgdHJ5Q2F0Y2goewogICAgICAgIGdldFN5bWJvbHMoIkZFREZVTkRTIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gc3RhcnRfZGF0ZSAtIDMwLCB0byA9IGVuZF9kYXRlICsgMzApCiAgICAgICAgcmF0ZV9zdGFydCA8LSBuYS5vbWl0KEZFREZVTkRTW3N0YXJ0X2RhdGVdIC8gMTAwKQogICAgICAgIHJhdGVfZW5kIDwtIG5hLm9taXQoRkVERlVORFNbZW5kX2RhdGVdIC8gMTAwKQogICAgICAgIAogICAgICAgIGlmIChsZW5ndGgocmF0ZV9zdGFydCkgPT0gMCB8fCBsZW5ndGgocmF0ZV9lbmQpID09IDApIHsKICAgICAgICAgICAgY2F0KCJEYXRhIHVuYXZhaWxhYmxlIGZvciIsIHN0YXJ0X2RhdGUsICItIiwgZW5kX2RhdGUsICJ1c2luZyBmYWxsYmFjayBkYXRlcy5cbiIpCiAgICAgICAgICAgIGdldFN5bWJvbHMoIkZFREZVTkRTIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gZmFsbGJhY2tfc3RhcnRfZGF0ZSAtIDMwLCB0byA9IGZhbGxiYWNrX2VuZF9kYXRlICsgMzApCiAgICAgICAgICAgIHJhdGVfc3RhcnQgPC0gbmEub21pdChGRURGVU5EU1tmYWxsYmFja19zdGFydF9kYXRlXSAvIDEwMCkKICAgICAgICAgICAgcmF0ZV9lbmQgPC0gbmEub21pdChGRURGVU5EU1tmYWxsYmFja19lbmRfZGF0ZV0gLyAxMDApCiAgICAgICAgfQogICAgICAgIHJldHVybihsaXN0KHN0YXJ0ID0gcmF0ZV9zdGFydCwgZW5kID0gcmF0ZV9lbmQpKQogICAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7CiAgICAgICAgY2F0KCJFcnJvciByZXRyaWV2aW5nIGZlZGVyYWwgZnVuZHMgcmF0ZSBkYXRhOiIsIGUkbWVzc2FnZSwgIlxuIikKICAgICAgICByZXR1cm4oTlVMTCkKICAgIH0pCn0KYGBgCgpgYGB7cn0KCgoKCiMgUmV0cmlldmUgZGF0YQpmZWRfZnVuZHNfcmF0ZSA8LSBnZXRfZmVkX2Z1bmRzX3JhdGUoc3RhcnRfZGF0ZSwgZW5kX2RhdGUsIGZhbGxiYWNrX3N0YXJ0X2RhdGUsIGZhbGxiYWNrX2VuZF9kYXRlKQoKCiMgQ29tcGFyZSBUcmVhc3VyeSB5aWVsZCBtb3ZlbWVudHMKZ2V0U3ltYm9scygiREdTMTAiLCBzcmMgPSAiRlJFRCIsIGZyb20gPSBzdGFydF9kYXRlIC0gMzAsIHRvID0gZW5kX2RhdGUgKyAzMCkKdHJlYXN1cnlfc3RhcnQgPC0gbmEub21pdChER1MxMFtzdGFydF9kYXRlXSAvIDEwMCkKdHJlYXN1cnlfZW5kIDwtIG5hLm9taXQoREdTMTBbZW5kX2RhdGVdIC8gMTAwKQoKCiMgQW5hbHl6ZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gRmVkIHBvbGljeSBhbmQgaW50ZXJlc3QgcmF0ZXMKaWYgKCFpcy5udWxsKGZlZF9mdW5kc19yYXRlKSAmJiAhaXMubmEodHJlYXN1cnlfc3RhcnQpICYmICFpcy5uYSh0cmVhc3VyeV9lbmQpKSB7CiAgICByYXRlX3N0YXJ0IDwtIGZpcnN0KGZlZF9mdW5kc19yYXRlJHN0YXJ0KQogICAgcmF0ZV9lbmQgPC0gZmlyc3QoZmVkX2Z1bmRzX3JhdGUkZW5kKQogICAgdHJlYXN1cnlfY2hhbmdlIDwtIGZpcnN0KHRyZWFzdXJ5X2VuZCkgLSBmaXJzdCh0cmVhc3VyeV9zdGFydCkKCgogICAgIyBEaXNwbGF5IHJlc3VsdHMKICAgIGNhdCgiRmVkZXJhbCBGdW5kcyBSYXRlIENoYW5nZToiLCByb3VuZCgocmF0ZV9lbmQgLSByYXRlX3N0YXJ0KSAqIDEwMCwgMiksICIlXG4iKQogICAgY2F0KCIxMC1ZZWFyIFRyZWFzdXJ5IFlpZWxkIENoYW5nZToiLCByb3VuZCh0cmVhc3VyeV9jaGFuZ2UgKiAxMDAsIDIpLCAiJVxuIikKCgogICAgIyBBc3Nlc3MgaW5mbHVlbmNlCiAgICBpZiAoc2lnbihyYXRlX2VuZCAtIHJhdGVfc3RhcnQpID09IHNpZ24odHJlYXN1cnlfY2hhbmdlKSkgewogICAgICAgIGNhdCgiTW92ZW1lbnRzIGluIGludGVyZXN0IHJhdGVzIGFwcGVhciB0byBoYXZlIGJlZW4gaW5mbHVlbmNlZCBieSB0aGUgRmVkJ3MgbW9uZXRhcnkgcG9saWN5LlxuIikKICAgIH0gZWxzZSB7CiAgICAgICAgY2F0KCJNb3ZlbWVudHMgaW4gaW50ZXJlc3QgcmF0ZXMgbWF5IGhhdmUgYmVlbiBkcml2ZW4gYnkgZmFjdG9ycyBvdGhlciB0aGFuIHRoZSBGZWQncyBtb25ldGFyeSBwb2xpY3kuXG4iKQogICAgfQp9IGVsc2UgewogICAgY2F0KCJJbnN1ZmZpY2llbnQgZGF0YSB0byBhbmFseXplIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbnRlcmVzdCByYXRlcyBhbmQgRmVkIHBvbGljeS5cbiIpCn0KCmBgYAoKI1RoZSBlcnJvciBpcyBiZWNhdXNlIHRoZXJlIGlzIG5vdCBpbmZvcm1hdGlvbiBmb3IgdGhpcyBkYXRlcwojTWVhc3VyaW5nIGFuZCBleHBsYWluaW5nIHByZW1pdW1zIG9uIG1vbmV5IG1hcmtldCBzZWN1cml0aWVzCgojTDcuMTIgV2hhdCBpcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB5aWVsZCBvbiA5MC1kYXkgY29tbWVyY2lhbCBwYXBlciBhbmQgdGhlIHlpZWxkIG9uIDEzLXdlZWsgVC1iaWxscyBhdCB0aGUgZW5kIG9mIHRoZSBzY2hvb2wgdGVybT8gRXhwbGFpbiB3aHkgdGhpcyBwcmVtaXVtIGV4aXN0cy4KCmBgYHtyfQoKCgojIEluc3RhbGwgYW5kIGxvYWQgbmVjZXNzYXJ5IHBhY2thZ2VzCmlmICghcmVxdWlyZShxdWFudG1vZCkpIGluc3RhbGwucGFja2FnZXMoInF1YW50bW9kIikKbGlicmFyeShxdWFudG1vZCkKCgojIERlZmluZSBkYXRlIHJhbmdlCnN0YXJ0X2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wNS0wMSIpCmVuZF9kYXRlIDwtIGFzLkRhdGUoIjIwMjQtMDktMzAiKQoKCiMgRG93bmxvYWQgeWllbGRzIGZvciA5MC1kYXkgY29tbWVyY2lhbCBwYXBlciBhbmQgMTMtd2VlayBUcmVhc3VyeSBiaWxscwp0cnlDYXRjaCh7CiAgICAjIFJldHJpZXZlIGRhdGEgZnJvbSBGUkVECiAgICBnZXRTeW1ib2xzKCJEQ1BGM00iLCBzcmMgPSAiRlJFRCIsIGZyb20gPSBzdGFydF9kYXRlLCB0byA9IGVuZF9kYXRlKSAgIyA5MC1kYXkgY29tbWVyY2lhbCBwYXBlcgogICAgZ2V0U3ltYm9scygiRFRCMyIsIHNyYyA9ICJGUkVEIiwgZnJvbSA9IHN0YXJ0X2RhdGUsIHRvID0gZW5kX2RhdGUpICAgIyAxMy13ZWVrIFRyZWFzdXJ5IGJpbGxzCiAgICAKICAgICMgRXh0cmFjdCB5aWVsZHMgYXQgdGhlIGVuZCBvZiB0aGUgc2Nob29sIHRlcm0KICAgIGNvbW1lcmNpYWxfcGFwZXJfeWllbGQgPC0gbmEub21pdChEQ1BGM01bZW5kX2RhdGVdIC8gMTAwKSAgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKICAgIHRfYmlsbF95aWVsZCA8LSBuYS5vbWl0KERUQjNbZW5kX2RhdGVdIC8gMTAwKSAgICAgICAgICAgICAgIyBDb252ZXJ0IHRvIHBlcmNlbnRhZ2UKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIHlpZWxkIGRpZmZlcmVuY2UgKHByZW1pdW0pCiAgICB5aWVsZF9kaWZmZXJlbmNlIDwtIGZpcnN0KGNvbW1lcmNpYWxfcGFwZXJfeWllbGQpIC0gZmlyc3QodF9iaWxsX3lpZWxkKQogICAgCiAgICAjIERpc3BsYXkgcmVzdWx0cwogICAgY2F0KCI5MC1kYXkgQ29tbWVyY2lhbCBQYXBlciBZaWVsZCBvbiIsIGVuZF9kYXRlLCAiOiIsIHJvdW5kKGZpcnN0KGNvbW1lcmNpYWxfcGFwZXJfeWllbGQpICogMTAwLCAyKSwgIiVcbiIpCiAgICBjYXQoIjEzLXdlZWsgVHJlYXN1cnkgQmlsbCBZaWVsZCBvbiIsIGVuZF9kYXRlLCAiOiIsIHJvdW5kKGZpcnN0KHRfYmlsbF95aWVsZCkgKiAxMDAsIDIpLCAiJVxuIikKICAgIGNhdCgiWWllbGQgUHJlbWl1bSAoQ29tbWVyY2lhbCBQYXBlciAtIFQtQmlsbCk6Iiwgcm91bmQoeWllbGRfZGlmZmVyZW5jZSAqIDEwMCwgMiksICIlXG4iKQp9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgICMgRXJyb3IgaGFuZGxpbmcKICAgIGNhdCgiRXJyb3IgcmV0cmlldmluZyBkYXRhOiIsIGUkbWVzc2FnZSwgIlxuIikKfSkKCmBgYAojQ29uY2x1aXNpb24KVGhlIHlpZWxkIGRpZmZlcmVuY2UgYmV0d2VlbiA5MC1kYXkgY29tbWVyY2lhbCBwYXBlciBhbmQgMTMtd2VlayBUcmVhc3VyeSBiaWxscyByZXByZXNlbnRzIHRoZSByaXNrIHByZW1pdW0gZGVtYW5kZWQgYnkgaW52ZXN0b3JzIGZvciBob2xkaW5nIGNvcnBvcmF0ZSBkZWJ0IG92ZXIgZ292ZXJubWVudCBkZWJ0LiBUeXBpY2FsbHksIGNvbW1lcmNpYWwgcGFwZXIgb2ZmZXJzIGEgaGlnaGVyIHlpZWxkIGR1ZSB0byBpdHMgY3JlZGl0IHJpc2sgYW5kIGxvd2VyIGxpcXVpZGl0eSBjb21wYXJlZCB0byBUcmVhc3VyeSBiaWxscywgd2hpY2ggYXJlIGNvbnNpZGVyZWQgcmlzay1mcmVlLiBJZiB0aGUgcHJlbWl1bSB3aWRlbnMsIGl0IG1heSBpbmRpY2F0ZSBpbmNyZWFzZWQgcmlzayBhdmVyc2lvbiBpbiB0aGUgbWFya2V0IG9yIGNvbmNlcm5zIGFib3V0IGNvcnBvcmF0ZSBjcmVkaXR3b3J0aGluZXNzLiBDb252ZXJzZWx5LCBhIG5hcnJvd2luZyBwcmVtaXVtIHN1Z2dlc3RzIGltcHJvdmVkIG1hcmtldCBjb25maWRlbmNlLiBUaGlzIGFuYWx5c2lzIGhpZ2hsaWdodHMgdGhlIHRyYWRlLW9mZiBiZXR3ZWVuIHJpc2sgYW5kIHJldHVybiBpbiBtb25leSBtYXJrZXQgc2VjdXJpdGllcyBhbmQgcHJvdmlkZXMgaW5zaWdodHMgaW50byBicm9hZGVyIGVjb25vbWljIGFuZCBtYXJrZXQgY29uZGl0aW9ucyBkdXJpbmcgdGhlIHNjaG9vbCB0ZXJtLgoKCiNMNy4xMyBDb21wYXJlIHRoZSBwcmVtaXVtIG9uIHRoZSA5MC1kYXkgY29tbWVyY2lhbCBwYXBlciB5aWVsZCAocmVsYXRpdmUgdG8gdGhlIDEzLXdlZWsgVC1iaWxsIHlpZWxkKSB0aGF0IGV4aXN0cyBhdCB0aGUgZW5kIG9mIHRoZSBzY2hvb2wgdGVybSB0byB0aGUgcHJlbWl1bSB0aGF0IGV4aXN0ZWQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdGVybS4gRWV4cGxhaW4gd2h5IHRoZSBwcmVtaXVtIG1heSBoYXZlIGNoYW5nZWQgb3ZlciB0aGUgc2Nob29sIHRlcm0uCgpgYGB7cn0KCgoKIyBJbnN0YWxsIGFuZCBsb2FkIG5lY2Vzc2FyeSBwYWNrYWdlcwppZiAoIXJlcXVpcmUocXVhbnRtb2QpKSBpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIpCmxpYnJhcnkocXVhbnRtb2QpCgoKIyBEZWZpbmUgZGF0ZSByYW5nZSBmb3IgdGhlIHNjaG9vbCB0ZXJtCnN0YXJ0X2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wNS0wMSIpCmVuZF9kYXRlIDwtIGFzLkRhdGUoIjIwMjQtMDktMzAiKQoKCiMgRG93bmxvYWQgZGF0YSBmb3IgOTAtZGF5IGNvbW1lcmNpYWwgcGFwZXIgYW5kIDEzLXdlZWsgVHJlYXN1cnkgYmlsbHMKdHJ5Q2F0Y2goewogICAgIyBSZXRyaWV2ZSBkYXRhIGZyb20gRlJFRAogICAgZ2V0U3ltYm9scygiRENQRjNNIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gc3RhcnRfZGF0ZSAtIDMwLCB0byA9IGVuZF9kYXRlICsgMzApICAjIDkwLWRheSBjb21tZXJjaWFsIHBhcGVyCiAgICBnZXRTeW1ib2xzKCJEVEIzIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gc3RhcnRfZGF0ZSAtIDMwLCB0byA9IGVuZF9kYXRlICsgMzApICAgIyAxMy13ZWVrIFRyZWFzdXJ5IGJpbGxzCgoKICAgICMgRXh0cmFjdCB5aWVsZHMgYXQgdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mIHRoZSBzY2hvb2wgdGVybQogICAgY29tbWVyY2lhbF9wYXBlcl9zdGFydCA8LSBuYS5vbWl0KERDUEYzTVtzdGFydF9kYXRlXSAvIDEwMCkgIAogICAgdF9iaWxsX3N0YXJ0IDwtIG5hLm9taXQoRFRCM1tzdGFydF9kYXRlXSAvIDEwMCkgICAgICAgICAgICAgICAgICAgICAgICAKICAgIHRfYmlsbF9lbmQgPC0gbmEub21pdChEVEIzW2VuZF9kYXRlXSAvIDEwMCkgICAgICAgICAgICAgICAgICAKICAgIGNvbW1lcmNpYWxfcGFwZXJfZW5kIDwtIG5hLm9taXQoRENQRjNNW2VuZF9kYXRlXSAvIDEwMCkKCiAgICAjIENhbGN1bGF0ZSBwcmVtaXVtcwogICAgc3RhcnRfcHJlbWl1bSA8LSBmaXJzdChjb21tZXJjaWFsX3BhcGVyX3N0YXJ0KSAtIGZpcnN0KHRfYmlsbF9zdGFydCkKICAgIGVuZF9wcmVtaXVtIDwtIGZpcnN0KGNvbW1lcmNpYWxfcGFwZXJfZW5kKSAtIGZpcnN0KHRfYmlsbF9lbmQpCgoKICAgICMgRGlzcGxheSByZXN1bHRzCiAgICBjYXQoIlByZW1pdW0gYXQgU3RhcnQgKE1heSAxLCAyMDI0KToiLCByb3VuZChzdGFydF9wcmVtaXVtICogMTAwLCAyKSwgIiVcbiIpCiAgICBjYXQoIlByZW1pdW0gYXQgRW5kIChTZXB0ZW1iZXIgMzAsIDIwMjQpOiIsIHJvdW5kKGVuZF9wcmVtaXVtICogMTAwLCAyKSwgIiVcbiIpCgpgYGAKCmBgYHtyfQoKCiAKICAgICMgQW5hbHl6ZSBjaGFuZ2VzIGluIHRoZSBwcmVtaXVtCiAgICBpZiAoIWlzLm5hKHN0YXJ0X3ByZW1pdW0pICYmICFpcy5uYShlbmRfcHJlbWl1bSkpIHsKICAgICAgICBpZiAoZW5kX3ByZW1pdW0gPiBzdGFydF9wcmVtaXVtKSB7CiAgICAgICAgICAgIGNhdCgiVGhlIHByZW1pdW0gd2lkZW5lZCBvdmVyIHRoZSBzY2hvb2wgdGVybSwgaW5kaWNhdGluZyBpbmNyZWFzZWQgY3JlZGl0IHJpc2sgb3IgcmVkdWNlZCBsaXF1aWRpdHkgaW4gdGhlIGNvbW1lcmNpYWwgcGFwZXIgbWFya2V0LlxuIikKICAgICAgICB9IGVsc2UgaWYgKGVuZF9wcmVtaXVtIDwgc3RhcnRfcHJlbWl1bSkgewogICAgICAgICAgICBjYXQoIlRoZSBwcmVtaXVtIG5hcnJvd2VkIG92ZXIgdGhlIHNjaG9vbCB0ZXJtLCByZWZsZWN0aW5nIGltcHJvdmVkIG1hcmtldCBjb25maWRlbmNlIGFuZCByZWR1Y2VkIGNyZWRpdCByaXNrLlxuIikKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjYXQoIlRoZSBwcmVtaXVtIHJlbWFpbmVkIHN0YWJsZSBvdmVyIHRoZSBzY2hvb2wgdGVybSwgaW5kaWNhdGluZyBjb25zaXN0ZW50IG1hcmtldCBjb25kaXRpb25zLlxuIikKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGNhdCgiSW5zdWZmaWNpZW50IGRhdGEgdG8gY29tcGFyZSBwcmVtaXVtcy5cbiIpCiAgICB9Cn0sIGVycm9yID0gZnVuY3Rpb24oZSkgewogICAgY2F0KCJFcnJvciByZXRyaWV2aW5nIGRhdGE6IiwgZSRtZXNzYWdlLCAiXG4iKQp9KQoKYGBgCgojQ29uY2x1c2lvbnMKVGhlIGVycm9yIGluIHRoZSByZXN1bHQgb2NjdXJyZWQgYmVjYXVzZSB0aGUgZGF0YSBmb3Igb25lIG9yIG1vcmUgdmFyaWFibGVzLCBzdWNoIGFzIHRoZSA5MC1kYXkgY29tbWVyY2lhbCBwYXBlciBvciAxMy13ZWVrIFRyZWFzdXJ5IGJpbGwgeWllbGQsIHdhcyB1bmF2YWlsYWJsZSBmb3IgdGhlIGV4YWN0IGRhdGVzIHJlcXVlc3RlZC4gVGhpcyBtaXNzaW5nIGRhdGEgbGVkIHRvIGluY29tcGxldGUgY2FsY3VsYXRpb25zLCBoaWdobGlnaHRpbmcgdGhlIGltcG9ydGFuY2Ugb2YgaW1wbGVtZW50aW5nIGZhbGxiYWNrIG1lY2hhbmlzbXMgdG8gcmV0cmlldmUgZGF0YSBmcm9tIG5lYXJieSBkYXRlcyBvciBoYW5kbGluZyBtaXNzaW5nIHZhbHVlcyBncmFjZWZ1bGx5LiBDb25zaWRlcmluZyB0aGlzLCB0aGUgY29tcGFyaXNvbiBvZiB0aGUgcHJlbWl1bSBhdCB0aGUgc3RhcnQgYW5kIGVuZCBvZiB0aGUgc2Nob29sIHRlcm0gcmV2ZWFscyBzaGlmdHMgaW4gbWFya2V0IHNlbnRpbWVudC4gQSB3aWRlbmluZyBwcmVtaXVtIGluZGljYXRlcyBpbmNyZWFzZWQgY3JlZGl0IHJpc2sgb3IgcmVkdWNlZCBsaXF1aWRpdHksIHdoaWxlIGEgbmFycm93aW5nIHByZW1pdW0gcmVmbGVjdHMgaW1wcm92ZWQgY29uZmlkZW5jZSBhbmQgcmVkdWNlZCByaXNrLiBJZiB0aGUgcHJlbWl1bSByZW1haW5lZCBzdGFibGUsIGl0IHN1Z2dlc3RzIGNvbnNpc3RlbnQgbWFya2V0IGNvbmRpdGlvbnMuIFRoZXNlIHJlc3VsdHMgdW5kZXJsaW5lIHRoZSBuZWVkIHRvIGFjY291bnQgZm9yIGRhdGEgYXZhaWxhYmlsaXR5IGNoYWxsZW5nZXMgaW4gZmluYW5jaWFsIGFuYWx5c2VzLgoKI0V4cGxhaW5pbmcgYm9uZCBwcmVtaXVtcyBhbmQgcHJpY2UgbW92ZW1lbnRzCiNMNy4xNCBXaGF0IGlzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHlpZWxkIG9uIGhpZ2gteWllbGQgY29ycG9yYXRlIGJvbmRzIGF0IHRoZSBlbmQgb2YgdGhlIHNjaG9vbCB0ZXJtIHZlcnN1cyB0aGUgeWllbGQgb24gaGlnaC1xdWFsaXR5IGNvcnBvcmF0ZSBib25kcyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzY2hvb2wgdGVybT8KCmBgYHtyfQoKIyBJbnN0YWxsIGFuZCBsb2FkIG5lY2Vzc2FyeSBwYWNrYWdlcwppZiAoIXJlcXVpcmUocXVhbnRtb2QpKSBpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIpCmxpYnJhcnkocXVhbnRtb2QpCgoKIyBEZWZpbmUgZGF0ZXMgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiB0aGUgc2Nob29sIHRlcm0Kc3RhcnRfZGF0ZSA8LSBhcy5EYXRlKCIyMDI0LTA1LTAxIikKZW5kX2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wOS0zMCIpCgoKIyBEb3dubG9hZCBoaWdoLXF1YWxpdHkgY29ycG9yYXRlIGJvbmQgZGF0YSAoZXhhbXBsZTogQUFBLXJhdGVkIGNvcnBvcmF0ZSBib25kcykKdHJ5Q2F0Y2goewogICAgZ2V0U3ltYm9scygiQkFNTEMwQTFDQUFBRVkiLCBzcmMgPSAiRlJFRCIsIGZyb20gPSAiMjAyNC0wNC0wMSIsIHRvID0gIjIwMjQtMDUtMTUiKQogICAgaGlnaF9xdWFsaXR5X3lpZWxkIDwtIG5hLm9taXQoQkFNTEMwQTFDQUFBRVlbc3RhcnRfZGF0ZV0gLyAxMDApICAjIENvbnZlcnQgdG8gcGVyY2VudGFnZQogICAgY2F0KCJIaWdoLXF1YWxpdHkgY29ycG9yYXRlIGJvbmQgeWllbGQgZGF0YSBkb3dubG9hZGVkIHN1Y2Nlc3NmdWxseS5cbiIpCn0sIGVycm9yID0gZnVuY3Rpb24oZSkgewogICAgY2F0KCJFcnJvciBkb3dubG9hZGluZyBoaWdoLXF1YWxpdHkgY29ycG9yYXRlIGJvbmQgZGF0YTogIiwgZSRtZXNzYWdlLCAiXG4iKQp9KQoKCiMgRG93bmxvYWQgaGlnaC15aWVsZCBjb3Jwb3JhdGUgYm9uZCBkYXRhIChleGFtcGxlOiBqdW5rIGJvbmRzKQp0cnlDYXRjaCh7CiAgICBnZXRTeW1ib2xzKCJCQU1MSDBBMEhZTTJFWSIsIHNyYyA9ICJGUkVEIiwgZnJvbSA9ICIyMDI0LTA5LTAxIiwgdG8gPSAiMjAyNC0xMC0wMSIpCiAgICBoaWdoX3lpZWxkX2JvbmQgPC0gbmEub21pdChCQU1MSDBBMEhZTTJFWVtlbmRfZGF0ZV0gLyAxMDApICAjIENvbnZlcnQgdG8gcGVyY2VudGFnZQogICAgY2F0KCJIaWdoLXlpZWxkIGNvcnBvcmF0ZSBib25kIHlpZWxkIGRhdGEgZG93bmxvYWRlZCBzdWNjZXNzZnVsbHkuXG4iKQp9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgIGNhdCgiRXJyb3IgZG93bmxvYWRpbmcgaGlnaC15aWVsZCBjb3Jwb3JhdGUgYm9uZCBkYXRhOiAiLCBlJG1lc3NhZ2UsICJcbiIpCn0pCmBgYAoKYGBge3J9CgoKIyBDYWxjdWxhdGUgdGhlIGRpZmZlcmVuY2UKaWYgKGV4aXN0cygiaGlnaF9xdWFsaXR5X3lpZWxkIikgJiYgZXhpc3RzKCJoaWdoX3lpZWxkX2JvbmQiKSkgewogICAgaWYgKGxlbmd0aChoaWdoX3F1YWxpdHlfeWllbGQpID4gMCAmJiBsZW5ndGgoaGlnaF95aWVsZF9ib25kKSA+IDApIHsKICAgICAgICB5aWVsZF9kaWZmZXJlbmNlIDwtIGZpcnN0KGhpZ2hfeWllbGRfYm9uZCkgLSBmaXJzdChoaWdoX3F1YWxpdHlfeWllbGQpCiAgICAgICAgCiAgICAgICAgIyBEaXNwbGF5IHJlc3VsdHMKICAgICAgICBjYXQoIkhpZ2gtcXVhbGl0eSBjb3Jwb3JhdGUgYm9uZCB5aWVsZCBvbiBNYXkgMSwgMjAyNDoiLCByb3VuZChmaXJzdChoaWdoX3F1YWxpdHlfeWllbGQpICogMTAwLCAyKSwgIiVcbiIpCiAgICAgICAgY2F0KCJIaWdoLXlpZWxkIGNvcnBvcmF0ZSBib25kIHlpZWxkIG9uIFNlcHRlbWJlciAzMCwgMjAyNDoiLCByb3VuZChmaXJzdChoaWdoX3lpZWxkX2JvbmQpICogMTAwLCAyKSwgIiVcbiIpCiAgICAgICAgY2F0KCJZaWVsZCBkaWZmZXJlbmNlIChoaWdoLXlpZWxkIC0gaGlnaC1xdWFsaXR5KToiLCByb3VuZCh5aWVsZF9kaWZmZXJlbmNlICogMTAwLCAyKSwgIiVcbiIpCiAgICB9IGVsc2UgewogICAgICAgIGNhdCgiSW5zdWZmaWNpZW50IGRhdGEgdG8gY2FsY3VsYXRlIHRoZSB5aWVsZCBkaWZmZXJlbmNlLlxuIikKICAgIH0KfSBlbHNlIHsKICAgIGNhdCgiRGF0YSBmb3IgeWllbGRzIGlzIG5vdCBhdmFpbGFibGUuXG4iKQp9CmBgYAojQ29uY2x1c2lvbgpUaGUgeWllbGQgb24gdGhlIGxvbmcgdGVybSBVUyBUcmVhc3VyeSBib25kIGFuZCBNYXkgMSwgMjAyNCwgeWllbGQgb24gdGhlIDEzLXdlZWsgVC1iaWxsIHJlZmxlY3RzIHRoZSB5aWVsZCBjdXJ2ZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRlcm0KTWFya2V0IGV4cGVjdGF0aW9ucyBmb3IgcmlzaW5nIGludGVyZXN0IHJhdGVzIGFuZCB3aGF0IHRoYXQgaW1wbGllcyBhYm91dCB5ZXQgdG8gY29tZSBncm93dGggaW4gdGhlIGVjb25vbXkgaXMgYW4gdXB3YXJkLXNsb3BpbmcgeWllbGQgY3VydmUg4oCUIGEgcG9zaXRpdmUgZGlmZmVyZW5jZS4KQW4gaW52ZXJ0ZWQgeWllbGQgY3VydmUgbmVnYXRpdmUgc3VnZ2VzdHMgYmFja3dhcmRzIGxvb2tpbmcgb2YgZnV0dXJlIGludGVyZXN0IHJhdGVzIGxpa2VseSB0byBiZSBsb3dlciBhbmQgZWNvbm9taWMgc2xvd2Rvd24uCkEgMC1kaWZmZXJlbmNlIGluZGljYXRlcyBmbGF0IHlpZWxkIGN1cnZlIG1lYW5pbmcgaW50ZXJlc3QgcmF0ZXMgaGVhZGVkIGluIHRoZSBzYW1lIGRpcmVjdGlvbi4KVGhpcyBnYXAgb2ZmZXJzIGEgbG90IG9mIHZhbHVlIGZvciBib3RoIHRoZSBpbml0aWFsIHJlc3BvbnNlIG9mIHNlbnRpbWVudCBhbmQgZWNvbm9taWMgc3RhbmNlIGF0IHRoZSBzdGFydCBvZiBldmVyeSB0ZXJtLgpDcmVkaXQgcmlzayBwcmVtaXVtIGNhbiBiZSBzZWVuIGZyb20gdGhlIGV4dHJhIHlpZWxkIG9uIGhpZ2gteWllbGQgY29ycG9yYXRlIGJvbmRzIHZzLiBjb21wYXJhYmx5IHJhdGVkIGludmVzdG1lbnQgb3IgaGlnaCBxdWFsaXR5IGNvcnBvcmF0ZSBib25kcwpCaWcgR2FwOiBJbmRpY2F0aW9uIG9mIGEgc3RyZXNzZWQgbWFya2V0IG9yIHRoYXQgdGhlIGVjb25vbXkgaGFzIG5vIGZ1dHVyZSB0byByZXdhcmQgbG93ZXItcmF0ZWQgYm9uZHMgaGlnaGVyIHByaWNlcwpTbWFsbGVyIHRoZSBkaXNwYXJpdHk6IExlc3MgdW5jZXJ0YWludHkgaW4gbWFya2V0IG9yIGJldHRlciBjcmVkaXQgY29uZGl0aW9ucywgbmFycm93cyB0aGUgc3ByZWFkLgpUaGF0IGFtb3VudCBzaG93cyB3aGF0IGNyZWRpdCByaXNrIGFuZCBlY29ub21pYyBzZW50aW1lbnQgZG9lcyB0byBib25kIG1hcmtldHMgYW5kIGludmVzdG9yIGJlaGF2aW91ciBhdCBzY2hvb2wgdGVybQoKCgoKI0w3LjE1IENvbXBhcmUgdGhlIGxvbmctdGVybSBUcmVhc3VyeSBib25kIHlpZWxkIGF0IHRoZSBlbmQgb2YgdGhlIHNjaG9vbCB0ZXJtIHRvIHRoZSBsb25ndGVybSBUcmVhc3VyeSBib25kIHlpZWxkIHRoYXQgZXhpc3RlZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzY2hvb2wgdGVybS4gR2l2ZW4gdGhlIGRpcmVjdGlvbiBvZiB0aGlzIGNoYW5nZSwgZGlkIHByaWNlcyBvZiBsb25nLXRlcm0gYm9uZHMgcmlzZSBvciBmYWxsIG92ZXIgdGhlIHNjaG9vbCB0ZXJtPwoKYGBge3J9CiMgSW5zdGFsbCBhbmQgbG9hZCBuZWNlc3NhcnkgcGFja2FnZXMKaWYgKCFyZXF1aXJlKHF1YW50bW9kKSkgaW5zdGFsbC5wYWNrYWdlcygicXVhbnRtb2QiKQpsaWJyYXJ5KHF1YW50bW9kKQoKIyBEZWZpbmUgZGF0ZXMgZm9yIHRoZSBiZWdpbm5pbmcgYW5kIGVuZCBvZiB0aGUgc2Nob29sIHRlcm0Kc3RhcnRfZGF0ZSA8LSBhcy5EYXRlKCIyMDI0LTA1LTAxIikKZW5kX2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wOS0zMCIpCgojIERvd25sb2FkIGxvbmctdGVybSBUcmVhc3VyeSBib25kIHlpZWxkIGRhdGEgKDMwLXllYXIgYm9uZHMpCnRyeUNhdGNoKHsKICAgIGdldFN5bWJvbHMoIkRHUzMwIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gIjIwMjQtMDQtMDEiLCB0byA9ICIyMDI0LTEwLTAxIikKICAgIHRyZWFzdXJ5X3lpZWxkX3N0YXJ0IDwtIG5hLm9taXQoREdTMzBbc3RhcnRfZGF0ZV0gLyAxMDApICAjIENvbnZlcnQgdG8gcGVyY2VudGFnZQogICAgdHJlYXN1cnlfeWllbGRfZW5kIDwtIG5hLm9taXQoREdTMzBbZW5kX2RhdGVdIC8gMTAwKSAgICAgICMgQ29udmVydCB0byBwZXJjZW50YWdlCiAgICBjYXQoIkxvbmctdGVybSBUcmVhc3VyeSBib25kIHlpZWxkIGRhdGEgZG93bmxvYWRlZCBzdWNjZXNzZnVsbHkuXG4iKQp9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgIGNhdCgiRXJyb3IgZG93bmxvYWRpbmcgbG9uZy10ZXJtIFRyZWFzdXJ5IGJvbmQgeWllbGQgZGF0YTogIiwgZSRtZXNzYWdlLCAiXG4iKQp9KQoKIyBDb21wYXJlIHlpZWxkcyBhbmQgZGV0ZXJtaW5lIGJvbmQgcHJpY2UgbW92ZW1lbnQKaWYgKGV4aXN0cygidHJlYXN1cnlfeWllbGRfc3RhcnQiKSAmJiBleGlzdHMoInRyZWFzdXJ5X3lpZWxkX2VuZCIpKSB7CiAgICBpZiAobGVuZ3RoKHRyZWFzdXJ5X3lpZWxkX3N0YXJ0KSA+IDAgJiYgbGVuZ3RoKHRyZWFzdXJ5X3lpZWxkX2VuZCkgPiAwKSB7CiAgICAgICAgeWllbGRfZGlmZmVyZW5jZSA8LSBmaXJzdCh0cmVhc3VyeV95aWVsZF9lbmQpIC0gZmlyc3QodHJlYXN1cnlfeWllbGRfc3RhcnQpCiAgICAgICAgCiMgRGlzcGxheSByZXN1bHRzCiAgICAgICAgY2F0KCJMb25nLXRlcm0gVHJlYXN1cnkgYm9uZCB5aWVsZCBvbiBNYXkgMSwgMjAyNDoiLCByb3VuZChmaXJzdCh0cmVhc3VyeV95aWVsZF9zdGFydCkgKiAxMDAsIDIpLCAiJVxuIikKICAgICAgICBjYXQoIkxvbmctdGVybSBUcmVhc3VyeSBib25kIHlpZWxkIG9uIFNlcHRlbWJlciAzMCwgMjAyNDoiLCByb3VuZChmaXJzdCh0cmVhc3VyeV95aWVsZF9lbmQpICogMTAwLCAyKSwgIiVcbiIpCiAgICAgICAgY2F0KCJZaWVsZCBkaWZmZXJlbmNlOiIsIHJvdW5kKHlpZWxkX2RpZmZlcmVuY2UgKiAxMDAsIDIpLCAiJVxuIikKICAgICAgICAKICAgICAgICAjIERldGVybWluZSBwcmljZSBtb3ZlbWVudAogICAgICAgIGlmICh5aWVsZF9kaWZmZXJlbmNlID4gMCkgewogICAgICAgICAgICBjYXQoIllpZWxkcyBpbmNyZWFzZWQsIGluZGljYXRpbmcgdGhhdCBsb25nLXRlcm0gYm9uZCBwcmljZXMgZmVsbC5cbiIpCiAgICAgICAgfSBlbHNlIGlmICh5aWVsZF9kaWZmZXJlbmNlIDwgMCkgewogICAgICAgICAgICBjYXQoIllpZWxkcyBkZWNyZWFzZWQsIGluZGljYXRpbmcgdGhhdCBsb25nLXRlcm0gYm9uZCBwcmljZXMgcm9zZS5cbiIpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2F0KCJZaWVsZHMgcmVtYWluZWQgdW5jaGFuZ2VkLCBzbyBib25kIHByaWNlcyBzdGF5ZWQgc3RhYmxlLlxuIikKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGNhdCgiSW5zdWZmaWNpZW50IGRhdGEgdG8gY29tcGFyZSB5aWVsZHMuXG4iKQogICAgfQp9IGVsc2UgewogICAgY2F0KCJMb25nLXRlcm0gVHJlYXN1cnkgYm9uZCB5aWVsZCBkYXRhIGlzIG5vdCBhdmFpbGFibGUuXG4iKQp9CgpgYGAKCiNDb25jbHVzaW9uIG9mIHRoZSBDb2RlCiNUaGUgYW5hbHlzaXMgY29tcGFyZXMgdGhlIHlpZWxkcyBvZiAzMC15ZWFyIFRyZWFzdXJ5IGJvbmRzIGF0IHRoZSBzdGFydCBhbmQgZW5kIG9mIHRoZSBhY2FkZW1pYyB0ZXJtLiBCYXNlZCBvbiB0aGUgcmVzdWx0czoKI0lmIHRoZSB5aWVsZCBpbmNyZWFzZWQ6CiNUaGlzIGluZGljYXRlcyB0aGF0IHRoZSBwcmljZXMgb2YgbG9uZy10ZXJtIGJvbmRzIGZlbGwgZHVyaW5nIHRoZSB0ZXJtLgojQSByaXNlIGluIHlpZWxkcyBzdWdnZXN0cyBtYXJrZXQgZXhwZWN0YXRpb25zIG9mIGhpZ2hlciBmdXR1cmUgaW50ZXJlc3QgcmF0ZXMgb3IgcmVkdWNlZCBkZW1hbmQgZm9yIGxvbmctdGVybSBib25kcy4KI0lmIHRoZSB5aWVsZCBkZWNyZWFzZWQ6CiNUaGlzIGluZGljYXRlcyB0aGF0IHRoZSBwcmljZXMgb2YgbG9uZy10ZXJtIGJvbmRzIHJvc2UuCiNBIGZhbGwgaW4geWllbGRzIHJlZmxlY3RzIGhpZ2hlciBkZW1hbmQgZm9yIGJvbmRzIG9yIGV4cGVjdGF0aW9ucyBvZiBsb3dlciBmdXR1cmUgaW50ZXJlc3QgcmF0ZXMuCiNJZiB0aGUgeWllbGQgcmVtYWluZWQgdW5jaGFuZ2VkOgojVGhpcyBzdWdnZXN0cyB0aGF0IGJvbmQgcHJpY2VzIHN0YXllZCBzdGFibGUsIGluZGljYXRpbmcgY29uc2lzdGVudCBtYXJrZXQgY29uZGl0aW9ucy4KI1RoaXMgYW5hbHlzaXMgZGVtb25zdHJhdGVzIHRoZSBpbnZlcnNlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGJvbmQgcHJpY2VzIGFuZCB5aWVsZHMsIG9mZmVyaW5nIGluc2lnaHRzIGludG8gbWFya2V0IHNlbnRpbWVudCBhbmQgaW50ZXJlc3QgcmF0ZSBleHBlY3RhdGlvbnMgb3ZlciB0aGUgdGVybS4KI1RoZSBlcnJvciBvY2N1cnMgYmVjYXVzZSB0aGUgZXhhY3QgcmVxdWVzdGVkIGRhdGVzIGxhY2sgZGF0YSBpbiB0aGUgZGF0YXNldC4gVGhpcyBpc3N1ZSBpcyByZXNvbHZlZCBieSBhdXRvbWF0aWNhbGx5IHNlbGVjdGluZyB0aGUgY2xvc2VzdCBhdmFpbGFibGUgZGF0ZXMgd2l0aCB2YWxpZCBkYXRhLiAKCiNMNy4xNiBDb21wYXJlIHRoZSBjaGFuZ2UgaW4gdGhlIHlpZWxkcyBvZiBUcmVhc3VyeSwgbXVuaWNpcGFsLCBhbmQgY29ycG9yYXRlIGJvbmRzIG92ZXIgdGhlIHNjaG9vbCB0ZXJtLiBEaWQgdGhlIHlpZWxkcyBvZiBhbGwgdGhyZWUgdHlwZXMgb2Ygc2VjdXJpdGllcyBtb3ZlIGluIHRoZSBzYW1lIGRpcmVjdGlvbiBhbmQgYnkgYWJvdXQgdGhlIHNhbWUgZGVncmVlPyBFeHBsYWluIHdoeSB5aWVsZHMgb2YgZGlmZmVyZW50IHR5cGVzIG9mIGJvbmRzIG1vdmUgdG9nZXRoZXIuCgojRXZlbiB0aGVyZSBpcyBhbiBlcnJvciB0aGF0IHdlIHRyaWVkIHRvIHNvbHZlIHdpdGggY2hhdCBncHQgd2Ugd2lsbCB0cnkgdG8gZXhwbGFpbiB3aGF0IHdlIHNob3VsZCBoYXZlIGRvbmUuCiNUbyBhbmFseXplIHRoZSBjaGFuZ2VzIGluIHRoZSB5aWVsZHMgb2YgVHJlYXN1cnkgYm9uZHMsIG11bmljaXBhbCBib25kcywgYW5kIGNvcnBvcmF0ZSBib25kcyBvdmVyIHRoZSBzY2hvb2wgdGVybSwgd2UgY29tcGFyZSB0aGVpciB5aWVsZHMgYXQgdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mIHRoZSB0ZXJtLiBUaGUgZ29hbCBpcyB0byBhc3Nlc3Mgd2hldGhlciB0aGVzZSB5aWVsZHMgbW92ZWQgaW4gdGhlIHNhbWUgZGlyZWN0aW9uIGFuZCBieSBzaW1pbGFyIGRlZ3JlZXMuIFdoaWxlIHlpZWxkcyBvZnRlbiBtb3ZlIHRvZ2V0aGVyIGR1ZSB0byBzaGFyZWQgbWFjcm9lY29ub21pYyBpbmZsdWVuY2VzLCBkaWZmZXJlbmNlcyBpbiBjcmVkaXQgcmlzaywgdGF4IHRyZWF0bWVudCwgYW5kIG1hcmtldCBsaXF1aWRpdHkgY2FuIHJlc3VsdCBpbiB2YXJ5aW5nIG1hZ25pdHVkZXMgb2YgbW92ZW1lbnQuCgoKI0w3LjE3IENvbXBhcmUgdGhlIHByZW1pdW0gb24gaGlnaC15aWVsZCBjb3Jwb3JhdGUgYm9uZHMgKHJlbGF0aXZlIHRvIFRyZWFzdXJ5IGJvbmRzKSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzY2hvb2wgdGVybSB0byB0aGUgcHJlbWl1bSB0aGF0IGV4aXN0ZWQgYXQgdGhlIGVuZCBvZiB0aGUgc2Nob29sIHRlcm0uIERpZCB0aGUgcHJlbWl1bSBpbmNyZWFzZSBvciBkZWNyZWFzZT8gV2h5IHRoaXMgcHJlbWl1bSBjaGFuZ2VkIG92ZXIgdGhlIHNjaG9vbCB0ZXJtLgoKYGBge3J9CgoKCiMKIyBJbnN0YWxsIGFuZCBsb2FkIG5lY2Vzc2FyeSBwYWNrYWdlcwppZiAoIXJlcXVpcmUocXVhbnRtb2QpKSBpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIpCmxpYnJhcnkocXVhbnRtb2QpCgoKIyBEZWZpbmUgdGhlIGRhdGVzIGZvciB0aGUgc2Nob29sIHRlcm0Kc3RhcnRfZGF0ZSA8LSBhcy5EYXRlKCIyMDI0LTA1LTAxIikKZW5kX2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wOS0zMCIpCgoKIyBSZXRyaWV2ZSBkYXRhIGZvciBoaWdoLXlpZWxkIGNvcnBvcmF0ZSBib25kcyBhbmQgVHJlYXN1cnkgYm9uZHMKdHJ5Q2F0Y2goewogICAgIyBIaWdoLXlpZWxkIGNvcnBvcmF0ZSBib25kIGluZGV4IChqdW5rIGJvbmRzKQogICAgZ2V0U3ltYm9scygiQkFNTEgwQTBIWU0yRVkiLCBzcmMgPSAiRlJFRCIsIGZyb20gPSAiMjAyNC0wNC0wMSIsIHRvID0gIjIwMjQtMTAtMDEiKQogICAgaGlnaF95aWVsZF9zdGFydCA8LSBuYS5vbWl0KEJBTUxIMEEwSFlNMkVZW3N0YXJ0X2RhdGVdIC8gMTAwKQogICAgaGlnaF95aWVsZF9lbmQgPC0gbmEub21pdChCQU1MSDBBMEhZTTJFWVtlbmRfZGF0ZV0gLyAxMDApCgoKICAgICMgVHJlYXN1cnkgYm9uZCAoMTAteWVhciBhcyBwcm94eSkKICAgIGdldFN5bWJvbHMoIkRHUzEwIiwgc3JjID0gIkZSRUQiLCBmcm9tID0gIjIwMjQtMDQtMDEiLCB0byA9ICIyMDI0LTEwLTAxIikKICAgIHRyZWFzdXJ5X3N0YXJ0IDwtIG5hLm9taXQoREdTMTBbc3RhcnRfZGF0ZV0gLyAxMDApCiAgICB0cmVhc3VyeV9lbmQgPC0gbmEub21pdChER1MxMFtlbmRfZGF0ZV0gLyAxMDApCgoKICAgICMgQ2FsY3VsYXRlIHByZW1pdW1zCiAgICBwcmVtaXVtX3N0YXJ0IDwtIGZpcnN0KGhpZ2hfeWllbGRfc3RhcnQpIC0gZmlyc3QodHJlYXN1cnlfc3RhcnQpCiAgICBwcmVtaXVtX2VuZCA8LSBmaXJzdChoaWdoX3lpZWxkX2VuZCkgLSBmaXJzdCh0cmVhc3VyeV9lbmQpCgoKICAgICMgRGlzcGxheSByZXN1bHRzCiAgICBjYXQoIkhpZ2gtWWllbGQgQ29ycG9yYXRlIEJvbmQgUHJlbWl1bSBhdCBTdGFydCAoTWF5IDEsIDIwMjQpOiIsIHJvdW5kKHByZW1pdW1fc3RhcnQgKiAxMDAsIDIpLCAiJVxuIikKICAgIGNhdCgiSGlnaC1ZaWVsZCBDb3Jwb3JhdGUgQm9uZCBQcmVtaXVtIGF0IEVuZCAoU2VwdGVtYmVyIDMwLCAyMDI0KToiLCByb3VuZChwcmVtaXVtX2VuZCAqIDEwMCwgMiksICIlXG4iKQoKCiAgICAjIEFuYWx5emUgY2hhbmdlcyBpbiB0aGUgcHJlbWl1bQogICAgaWYgKCFpcy5uYShwcmVtaXVtX3N0YXJ0KSAmJiAhaXMubmEocHJlbWl1bV9lbmQpKSB7CiAgICAgICAgaWYgKHByZW1pdW1fZW5kID4gcHJlbWl1bV9zdGFydCkgewogICAgICAgICAgICBjYXQoIlRoZSBwcmVtaXVtIGluY3JlYXNlZCBvdmVyIHRoZSBzY2hvb2wgdGVybSwgaW5kaWNhdGluZyBoZWlnaHRlbmVkIGNyZWRpdCByaXNrIG9yIG1hcmtldCBjb25jZXJucy5cbiIpCiAgICAgICAgfSBlbHNlIGlmIChwcmVtaXVtX2VuZCA8IHByZW1pdW1fc3RhcnQpIHsKICAgICAgICAgICAgY2F0KCJUaGUgcHJlbWl1bSBkZWNyZWFzZWQgb3ZlciB0aGUgc2Nob29sIHRlcm0sIHJlZmxlY3RpbmcgaW1wcm92ZWQgaW52ZXN0b3IgY29uZmlkZW5jZSBhbmQgcmVkdWNlZCBjcmVkaXQgcmlzay5cbiIpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2F0KCJUaGUgcHJlbWl1bSByZW1haW5lZCBzdGFibGUgb3ZlciB0aGUgc2Nob29sIHRlcm0sIGluZGljYXRpbmcgY29uc2lzdGVudCBtYXJrZXQgY29uZGl0aW9ucy5cbiIpCiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBjYXQoIkluc3VmZmljaWVudCBkYXRhIHRvIGNvbXBhcmUgcHJlbWl1bXMuXG4iKQogICAgfQp9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsKICAgIGNhdCgiRXJyb3IgcmV0cmlldmluZyBkYXRhOiIsIGUkbWVzc2FnZSwgIlxuIikKfSkKYGBgCiNDb25jbHVzaW9uCiNUaGUgcHJlbWl1bSBvbiBoaWdoLXlpZWxkIGNvcnBvcmF0ZSBib25kcyByZWxhdGl2ZSB0byBUcmVhc3VyeSBib25kcyByZWZsZWN0cyB0aGUgYWRkaXRpb25hbCByaXNrIGludmVzdG9ycyBhY2NlcHQgZm9yIGhpZ2hlciB5aWVsZHMuIEEgd2lkZW5pbmcgcHJlbWl1bSBzdWdnZXN0cyBpbmNyZWFzZWQgY3JlZGl0IGNvbmNlcm5zIG9yIG1hcmtldCB1bmNlcnRhaW50eSwgd2hpbGUgYSBuYXJyb3dpbmcgcHJlbWl1bSBpbmRpY2F0ZXMgaW1wcm92ZWQgY29uZmlkZW5jZSBvciBsb3dlciBwZXJjZWl2ZWQgcmlza3MuIElmIHRoZSBwcmVtaXVtIHJlbWFpbmVkIHN0YWJsZSwgaXQgaW1wbGllcyBjb25zaXN0ZW50IG1hcmtldCBjb25kaXRpb25zIHRocm91Z2hvdXQgdGhlIHRlcm0uIFRoZXNlIHNoaWZ0cyBoaWdobGlnaHQgaG93IGVjb25vbWljIGFuZCBtYXJrZXQgZmFjdG9ycyBpbmZsdWVuY2UgaW52ZXN0b3Igc2VudGltZW50IGFuZCByaXNrLXJldHVybiB0cmFkZS1vZmZzIGluIGJvbmQgbWFya2V0cy4KCiNMOCBQb3J0Zm9saW8gLSBNYXJrb3ZpdHoKCiNSZXBsaWNhdGUgdGhlIGJhc2ljIGlkZWEgb2YgdGhlIHByb3Rmb2xpbyBjYXNlCgpgYGB7cn0KCgoKIyBJbnN0YWxsIGFuZCBsb2FkIG5lY2Vzc2FyeSBwYWNrYWdlcwppZiAoIXJlcXVpcmUocXVhbnRtb2QpKSBpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIpCmlmICghcmVxdWlyZShQZXJmb3JtYW5jZUFuYWx5dGljcykpIGluc3RhbGwucGFja2FnZXMoIlBlcmZvcm1hbmNlQW5hbHl0aWNzIikKaWYgKCFyZXF1aXJlKHF1YWRwcm9nKSkgaW5zdGFsbC5wYWNrYWdlcygicXVhZHByb2ciKQpsaWJyYXJ5KHF1YW50bW9kKQpsaWJyYXJ5KFBlcmZvcm1hbmNlQW5hbHl0aWNzKQpsaWJyYXJ5KHF1YWRwcm9nKQoKCiMgRGVmaW5lIHRoZSBhc3NldHMgYW5kIGRhdGUgcmFuZ2UKc3ltYm9scyA8LSBjKCJBQVBMIiwgIk1TRlQiLCAiR09PRyIsICJBTVpOIikgICMgUmVwbGFjZSB3aXRoIHByZWZlcnJlZCBhc3NldCB0aWNrZXJzCnN0YXJ0X2RhdGUgPC0gYXMuRGF0ZSgiMjAyNC0wNS0wMSIpCmVuZF9kYXRlIDwtIGFzLkRhdGUoIjIwMjQtMDktMzAiKQoKCiMgRG93bmxvYWQgZGF0YQpnZXRTeW1ib2xzKHN5bWJvbHMsIGZyb20gPSBzdGFydF9kYXRlLCB0byA9IGVuZF9kYXRlLCBhdXRvLmFzc2lnbiA9IFRSVUUpCgoKIyBFeHRyYWN0IGFkanVzdGVkIGNsb3NpbmcgcHJpY2VzCnByaWNlcyA8LSBkby5jYWxsKGNiaW5kLCBsYXBwbHkoc3ltYm9scywgZnVuY3Rpb24oeCkgQ2woZ2V0KHgpKSkpCmNvbG5hbWVzKHByaWNlcykgPC0gc3ltYm9scwoKCiMgQ2FsY3VsYXRlIGRhaWx5IHJldHVybnMKcmV0dXJucyA8LSBuYS5vbWl0KFJldHVybi5jYWxjdWxhdGUocHJpY2VzLCBtZXRob2QgPSAibG9nIikpCgoKIyBDYWxjdWxhdGUgZXhwZWN0ZWQgcmV0dXJucyBhbmQgY292YXJpYW5jZSBtYXRyaXgKbWVhbl9yZXR1cm5zIDwtIGNvbE1lYW5zKHJldHVybnMpICogMjUyICAjIEFubnVhbGl6ZWQKY292X21hdHJpeCA8LSBjb3YocmV0dXJucykgKiAyNTIgICAgICAgICAjIEFubnVhbGl6ZWQKCgojIFBvcnRmb2xpbyBvcHRpbWl6YXRpb24KIyBTZXQgZXF1YWwgd2VpZ2h0cyBpbml0aWFsbHkKZXF1YWxfd2VpZ2h0cyA8LSByZXAoMSAvIG5jb2wocmV0dXJucyksIG5jb2wocmV0dXJucykpCgoKIyBNaW5pbWl6ZSBwb3J0Zm9saW8gdmFyaWFuY2UgKG5vIHNob3J0LXNlbGxpbmcgYWxsb3dlZCkKb3B0aW1hbF9wb3J0Zm9saW8gPC0gc29sdmUuUVAoCiAgICBEbWF0ID0gY292X21hdHJpeCwKICAgIGR2ZWMgPSByZXAoMCwgbmNvbChyZXR1cm5zKSksCiAgICBBbWF0ID0gY2JpbmQoMSwgZGlhZyhuY29sKHJldHVybnMpKSksCiAgICBidmVjID0gYygxLCByZXAoMCwgbmNvbChyZXR1cm5zKSkpLAogICAgbWVxID0gMQopCgoKIyBFeHRyYWN0IHdlaWdodHMKb3B0aW1hbF93ZWlnaHRzIDwtIG9wdGltYWxfcG9ydGZvbGlvJHNvbHV0aW9uCgoKIyBDYWxjdWxhdGUgcG9ydGZvbGlvIG1ldHJpY3MKb3B0aW1hbF9yZXR1cm4gPC0gc3VtKG9wdGltYWxfd2VpZ2h0cyAqIG1lYW5fcmV0dXJucykKb3B0aW1hbF9yaXNrIDwtIHNxcnQodChvcHRpbWFsX3dlaWdodHMpICUqJSBjb3ZfbWF0cml4ICUqJSBvcHRpbWFsX3dlaWdodHMpCgoKIyBEaXNwbGF5IHJlc3VsdHMKY2F0KCJPcHRpbWFsIFBvcnRmb2xpbyBXZWlnaHRzOlxuIikKcHJpbnQob3B0aW1hbF93ZWlnaHRzKQpjYXQoIlxuRXhwZWN0ZWQgQW5udWFsaXplZCBSZXR1cm46Iiwgcm91bmQob3B0aW1hbF9yZXR1cm4gKiAxMDAsIDIpLCAiJVxuIikKY2F0KCJQb3J0Zm9saW8gUmlzayAoU3RhbmRhcmQgRGV2aWF0aW9uKToiLCByb3VuZChvcHRpbWFsX3Jpc2sgKiAxMDAsIDIpLCAiJVxuIikKCmBgYAoKCiNMOSBQb3J0Zm9saW8gLSBDQU1QCgpgYGB7cn0KCgoKCiNTdGF0ZSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIENBTVAgYW5kIE1hcmtvdml0egojIExvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcwppZiAoIXJlcXVpcmUocXVhbnRtb2QpKSBpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIpCmlmICghcmVxdWlyZShQZXJmb3JtYW5jZUFuYWx5dGljcykpIGluc3RhbGwucGFja2FnZXMoIlBlcmZvcm1hbmNlQW5hbHl0aWNzIikKbGlicmFyeShxdWFudG1vZCkKbGlicmFyeShQZXJmb3JtYW5jZUFuYWx5dGljcykKCgojIERlZmluZSBzdG9jayBhbmQgbWFya2V0IGluZGljZXMKc3ltYm9scyA8LSBjKCJBQVBMIiwgIl5HU1BDIikgICMgQUFQTCA9IHN0b2NrLCBHU1BDID0gUyZQIDUwMCBhcyBtYXJrZXQgcHJveHkKCgojIERlZmluZSB0aGUgZGF0ZSByYW5nZQpzdGFydF9kYXRlIDwtICIyMDE4LTAxLTAxIgplbmRfZGF0ZSA8LSAiMjAyMy0xMi0zMSIKCgojIERvd25sb2FkIGRhdGEKZ2V0U3ltYm9scyhzeW1ib2xzLCBmcm9tID0gc3RhcnRfZGF0ZSwgdG8gPSBlbmRfZGF0ZSkKCgojIENhbGN1bGF0ZSBkYWlseSByZXR1cm5zIGZvciBzdG9jayBhbmQgbWFya2V0CnN0b2NrX3JldHVybnMgPC0gbmEub21pdChST0MoQUFQTFssNl0pKSAgIyBBZGp1c3RlZCBjbG9zZSBwcmljZSBvZiBBQVBMCm1hcmtldF9yZXR1cm5zIDwtIG5hLm9taXQoUk9DKEdTUENbLDZdKSkgICMgQWRqdXN0ZWQgY2xvc2UgcHJpY2Ugb2YgUyZQIDUwMAoKCiMgQ2FsY3VsYXRlIENBUE0gQmV0YQpiZXRhIDwtIENBUE0uYmV0YShSYSA9IHN0b2NrX3JldHVybnMsIFJiID0gbWFya2V0X3JldHVybnMpCgoKIyBEZWZpbmUgcmlzay1mcmVlIHJhdGUgYW5kIGNhbGN1bGF0ZSBleHBlY3RlZCByZXR1cm4Kcmlza19mcmVlX3JhdGUgPC0gMC4wMyAgIyBFeGFtcGxlOiAzJSBhbm51YWwgcmlzay1mcmVlIHJhdGUKZXhwZWN0ZWRfcmV0dXJuIDwtIHJpc2tfZnJlZV9yYXRlICsgYmV0YSAqIChtZWFuKG1hcmtldF9yZXR1cm5zKSAtIHJpc2tfZnJlZV9yYXRlKQoKCiMgRGlzcGxheSByZXN1bHRzCmNhdCgiQmV0YToiLCBiZXRhLCAiXG4iKQpjYXQoIkV4cGVjdGVkIFJldHVybjoiLCBleHBlY3RlZF9yZXR1cm4gKiAxMDAsICIlIikKCgoKCgoKI1RoZSBwcmltYXJ5IGRpZmZlcmVuY2UgYmV0d2VlbiBDQVBNIGFuZCBNYXJrb3dpdHogUG9ydGZvbGlvIFRoZW9yeSBsaWVzIGluIHRoZWlyIGZvY3VzIGFuZCBhcHByb2FjaCB0byByaXNrLiBDQVBNIGVtcGhhc2l6ZXMgc3lzdGVtYXRpYyByaXNrLCBtZWFzdXJlZCBieSBiZXRhLCBhbmQgZXhwbGFpbnMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGFuIGFzc2V0J3Mgc2Vuc2l0aXZpdHkgdG8gbWFya2V0IG1vdmVtZW50cyBhbmQgaXRzIGV4cGVjdGVkIHJldHVybi4gSXQgYXNzdW1lcyBpbnZlc3RvcnMgaG9sZCB0aGUgbWFya2V0IHBvcnRmb2xpbyBhbmQgZXZhbHVhdGVzIGluZGl2aWR1YWwgYXNzZXRzIGJhc2VkIG9uIHRoZWlyIG1hcmtldCByaXNrIGV4cG9zdXJlLiBJbiBjb250cmFzdCwgTWFya293aXR6IFBvcnRmb2xpbyBUaGVvcnkgY29uc2lkZXJzIHRvdGFsIHJpc2ssIGluY2x1ZGluZyBib3RoIHN5c3RlbWF0aWMgYW5kIHVuc3lzdGVtYXRpYyByaXNrLCBhaW1pbmcgdG8gY29uc3RydWN0IGFuIG9wdGltYWwgcG9ydGZvbGlvIGJ5IGRpdmVyc2lmeWluZyBhc3NldHMgdG8gbWluaW1pemUgcmlzayBmb3IgYSBnaXZlbiByZXR1cm4uIFdoaWxlIENBUE0gaXMgaWRlYWwgZm9yIHByaWNpbmcgYXNzZXRzIGFuZCB1bmRlcnN0YW5kaW5nIHRoZWlyIHJpc2stYWRqdXN0ZWQgcmV0dXJucywgTWFya293aXR6IHByb3ZpZGVzIGEgcHJhY3RpY2FsIGZyYW1ld29yayBmb3IgcG9ydGZvbGlvIG9wdGltaXphdGlvbiBhbmQgcmlzayBtYW5hZ2VtZW50LiBUb2dldGhlciwgdGhleSBvZmZlciBjb21wbGVtZW50YXJ5IHBlcnNwZWN0aXZlcyBvbiBpbnZlc3RtZW50IHN0cmF0ZWd5LgoKYGBgCiNMMTAgV0FDQwojUmVwbGljYXRlIHRoZSBib29rIGNhc2Ugb2YgV0FDQyAodGhlcmUgaXMgbm90IGJvb2sgY2FzZSkKI1RoZSBXZWlnaHRlZCBBdmVyYWdlIENvc3Qgb2YgQ2FwaXRhbCAoV0FDQykgaXMgYSBrZXkgZmluYW5jaWFsIG1ldHJpYyB0aGF0IHJlcHJlc2VudHMgdGhlIGF2ZXJhZ2UgcmF0ZSBvZiByZXR1cm4gYSBjb21wYW55IG11c3QgZ2VuZXJhdGUgdG8gc2F0aXNmeSBpdHMgaW52ZXN0b3JzLCBib3RoIGVxdWl0eSBhbmQgZGVidCBob2xkZXJzLiBJdCBpcyB1c2VkIHRvIGFzc2VzcyB0aGUgbWluaW11bSByZXR1cm4gYSBjb21wYW55IG5lZWRzIHRvIGVhcm4gb24gaXRzIGludmVzdG1lbnRzIHRvIG1haW50YWluIGl0cyB2YWx1ZSBhbmQgYXR0cmFjdCBmaW5hbmNpbmcuCiNXQUNDIGluY29ycG9yYXRlcyB0d28gbWFpbiBjb21wb25lbnRzIG9mIGNhcGl0YWw6CiNDb3N0IG9mIEVxdWl0eSAoUmVSZVJlKTogVGhpcyBpcyB0aGUgcmV0dXJuIHJlcXVpcmVkIGJ5IHNoYXJlaG9sZGVycyBmb3IgdGhlIHJpc2sgdGhleSB0YWtlIGluIGludmVzdGluZyBpbiB0aGUgY29tcGFueS4gSXQgcmVmbGVjdHMgdGhlIG9wcG9ydHVuaXR5IGNvc3Qgb2YgY2FwaXRhbCBhbmQgaXMgb2Z0ZW4gZXN0aW1hdGVkIHVzaW5nIHRoZSBDYXBpdGFsIEFzc2V0IFByaWNpbmcgTW9kZWwgKENBUE0pLgojQ29zdCBvZiBEZWJ0IChSZFJkUmQpOiBUaGlzIGlzIHRoZSBlZmZlY3RpdmUgcmF0ZSBhIGNvbXBhbnkgcGF5cyBvbiBpdHMgYm9ycm93ZWQgZnVuZHMuIEl0IGlzIGFkanVzdGVkIGZvciB0aGUgY29ycG9yYXRlIHRheCByYXRlLCBhcyBpbnRlcmVzdCBwYXltZW50cyBhcmUgdGF4LWRlZHVjdGlibGUuCiNXQUNDIGlzIGNhbGN1bGF0ZWQgYXMgYSB3ZWlnaHRlZCBhdmVyYWdlLCB3aGVyZSB0aGUgd2VpZ2h0cyBhcmUgdGhlIHByb3BvcnRpb25zIG9mIGVxdWl0eSBhbmQgZGVidCBpbiB0aGUgY29tcGFueeKAmXMgY2FwaXRhbCBzdHJ1Y3R1cmUuIFRoZSBmb3JtdWxhIGlzOgogIFdBQ0M9RVbii4VSZStEVuKLhVJk4ouFKDHiiJJUYylXQUNDID0gXGZyYWN7RX17Vn0gXGNkb3QgUmUgKyBcZnJhY3tEfXtWfSBcY2RvdCBSZCBcY2RvdCAoMSAtIFRjKVdBQ0M9VkXigIvii4VSZStWROKAi+KLhVJk4ouFKDHiiJJUYykKI1doZXJlOgogICNFRUU6IE1hcmtldCB2YWx1ZSBvZiBlcXVpdHkKI0RERDogTWFya2V0IHZhbHVlIG9mIGRlYnQKVj1FK0RWID0gRSArIERWPUUrRDogVG90YWwgY2FwaXRhbCAoZXF1aXR5ICsgZGVidCkKI1JlUmVSZTogQ29zdCBvZiBlcXVpdHkKI1JkUmRSZDogQ29zdCBvZiBkZWJ0CiNUY1RjVGM6IENvcnBvcmF0ZSB0YXggcmF0ZQojS2V5IEluc2lnaHRzCiNQdXJwb3NlIG9mIFdBQ0M6IFRoZSBXZWlnaHRlZCBBdmVyYWdlIENvc3Qgb2YgQ2FwaXRhbCAoV0FDQykgaXMgYSBrZXkgYmVuY2htYXJrIGZvciBldmFsdWF0aW5nIGludmVzdG1lbnQgb3Bwb3J0dW5pdGllcywgcmVwcmVzZW50aW5nIHRoZSBtaW5pbXVtIHJldHVybiBhIGNvbXBhbnkgbXVzdCBnZW5lcmF0ZSB0byBzYXRpc2Z5IGJvdGggZXF1aXR5IGFuZCBkZWJ0IGludmVzdG9ycy4gUHJvamVjdHMgc2hvdWxkIG9ubHkgYmUgdW5kZXJ0YWtlbiBpZiB0aGVpciBleHBlY3RlZCByZXR1cm4gZXhjZWVkcyB0aGUgV0FDQywgZW5zdXJpbmcgdmFsdWUgY3JlYXRpb24uIEJ5IHJlZmxlY3RpbmcgdGhlIGNvbXBhbnnigJlzIGJsZW5kZWQgY29zdCBvZiBjYXBpdGFsLCBXQUNDIGFjY291bnRzIGZvciB0aGUgcmlzayBwcmVmZXJlbmNlcyBvZiBlcXVpdHkgYW5kIGRlYnQgaG9sZGVycywgZ3VpZGluZyBzb3VuZCBmaW5hbmNpYWwgZGVjaXNpb25zCgoKI0ZhY3RvcnMgQWZmZWN0aW5nIFdBQ0M6IFRoZSBjYXBpdGFsIHN0cnVjdHVyZSBvZiBhIGNvbXBhbnkgc2lnbmlmaWNhbnRseSBpbXBhY3RzIFdBQ0MsIGFzIGRlYnQgaXMgdHlwaWNhbGx5IGNoZWFwZXIgdGhhbiBlcXVpdHkgYnV0IGludHJvZHVjZXMgYWRkaXRpb25hbCBmaW5hbmNpYWwgcmlzay4gTWFya2V0IGNvbmRpdGlvbnMsIHN1Y2ggYXMgY2hhbmdlcyBpbiBpbnRlcmVzdCByYXRlcyBvciBtYXJrZXQgcmlzayBwcmVtaXVtcywgY2FuIGluZmx1ZW5jZSB0aGUgY29zdCBvZiBib3RoIGRlYnQgYW5kIGVxdWl0eS4gQWRkaXRpb25hbGx5LCB0aGUgdGF4IHJhdGUgcGxheXMgYSByb2xlLCB3aXRoIGhpZ2hlciB0YXggcmF0ZXMgcmVkdWNpbmcgdGhlIGFmdGVyLXRheCBjb3N0IG9mIGRlYnQsIHBvdGVudGlhbGx5IGxvd2VyaW5nIHRoZSBXQUNDLiBUaGVzZSBmYWN0b3JzIHRvZ2V0aGVyIGRldGVybWluZSB0aGUgY29tcGFueeKAmXMgb3ZlcmFsbCBjb3N0IG9mIGNhcGl0YWwgYW5kIGluZmx1ZW5jZSBpdHMgZmluYW5jaWFsIHN0cmF0ZWd5LgojSW1wbGljYXRpb25zIG9mIFdBQ0M6CiNBIGxvd2VyIFdBQ0MgaW5kaWNhdGVzIHRoYXQgYSBjb21wYW55IGNhbiBmaW5hbmNlIHByb2plY3RzIG1vcmUgY2hlYXBseSwgaW1wcm92aW5nIGl0cyBjb21wZXRpdGl2ZW5lc3MuCiNBIGhpZ2hlciBXQUNDIHN1Z2dlc3RzIHRoYXQgdGhlIGNvbXBhbnkgZmFjZXMgaGlnaGVyIGZpbmFuY2luZyBjb3N0cywgd2hpY2ggY291bGQgbGltaXQgaXRzIGFiaWxpdHkgdG8gcHVyc3VlIGdyb3d0aCBvcHBvcnR1bml0aWVzLgojV0FDQyBpcyBhIGNvcm5lcnN0b25lIG1ldHJpYyBpbiBjb3Jwb3JhdGUgZmluYW5jZSwgZ3VpZGluZyBpbnZlc3RtZW50IGRlY2lzaW9ucywgdmFsdWF0aW9uIG1vZGVscywgYW5kIHBlcmZvcm1hbmNlIGJlbmNobWFya3MuIEl0IHByb3ZpZGVzIGEgY29tcHJlaGVuc2l2ZSB2aWV3IG9mIHRoZSBjb21wYW554oCZcyBjb3N0IG9mIGZpbmFuY2luZyBhbmQgaXRzIGltcGxpY2F0aW9ucyBmb3Igc3RyYXRlZ2ljIHBsYW5uaW5nLgoKCgoKI0wxMSBEZXJpdmF0aXZlcwoKYGBge3J9CgoKCiNMMTEuMSBBc3N1bWUgdGhhdCB5b3UgcHVyY2hhc2VkIGFuIFMmUCA1MDAgZnV0dXJlcyBjb250cmFjdCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzY2hvb2wgdGVybSwgd2l0aCB0aGUgZmlyc3Qgc2V0dGxlbWVudCBkYXRlIGJleW9uZCB0aGUgZW5kIG9mIHRoZSBzY2hvb2wgdGVybS4gQWxzbyBhc3N1bWUgdGhhdCB5b3Ugc29sZCBhbiBTJlAgNTAwIGZ1dHVyZXMgY29udHJhY3Qgd2l0aCB0aGlzIHNhbWUgc2V0dGxlbWVudCBkYXRlIGF0IHRoZSBlbmQgb2YgdGhlIHNjaG9vbCB0ZXJtLiBHaXZlbiB0aGF0IHRoaXMgY29udHJhY3QgaGFzIGEgdmFsdWUgb2YgdGhlIGZ1dHVyZXMgcHJpY2UgdGltZXMgJDI1MCwgZGV0ZXJtaW5lIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGRvbGxhciB2YWx1ZSBvZiB0aGUgY29udHJhY3QgeW91IHNvbGQgYW5kIHRoZSBkb2xsYXIgYW1vdW50IG9mIHRoZSBjb250cmFjdCB0aGF0IHlvdSBwdXJjaGFzZWQuCiMgSW5wdXQgZGF0YTogUmVwbGFjZSB0aGVzZSB3aXRoIGFjdHVhbCBwcmljZXMKc3RhcnRfcHJpY2UgPC0gNDUwMCAgIyBTJlAgNTAwIGZ1dHVyZXMgcHJpY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdGVybQplbmRfcHJpY2UgPC0gNDYwMCAgICAjIFMmUCA1MDAgZnV0dXJlcyBwcmljZSBhdCB0aGUgZW5kIG9mIHRoZSB0ZXJtCmNvbnRyYWN0X3ZhbHVlX211bHRpcGxpZXIgPC0gMjUwICAjIERvbGxhciBtdWx0aXBsaWVyIHBlciBmdXR1cmVzIHByaWNlIHVuaXQKCgojIENhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBpbiBkb2xsYXIgdmFsdWUKZGlmZmVyZW5jZSA8LSAoZW5kX3ByaWNlIC0gc3RhcnRfcHJpY2UpICogY29udHJhY3RfdmFsdWVfbXVsdGlwbGllcgoKCiMgRGlzcGxheSByZXN1bHRzCmNhdCgiRnV0dXJlcyBwcmljZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0ZXJtOiIsIHN0YXJ0X3ByaWNlLCAiXG4iKQpjYXQoIkZ1dHVyZXMgcHJpY2UgYXQgdGhlIGVuZCBvZiB0aGUgdGVybToiLCBlbmRfcHJpY2UsICJcbiIpCmNhdCgiRGlmZmVyZW5jZSBpbiBkb2xsYXIgdmFsdWUgb2YgdGhlIGZ1dHVyZXMgY29udHJhY3RzOiIsIGRpZmZlcmVuY2UsICJVU0RcbiIpCgoKYGBgCgojQ29uY2x1c2lvbgojVGhlIGRvbGxhciBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHZhbHVlIG9mIHRoZSBTJlAgNTAwIGZ1dHVyZXMgY29udHJhY3QgYXQgdGhlIGVuZCBvZiB0aGUgdGVybSBhbmQgYXQgdGhlIGJlZ2lubmluZyB3YXMgY2FsY3VsYXRlZCBhcyAkNTAsMDAwIChiYXNlZCBvbiBhIHByaWNlIGluY3JlYXNlIGZyb20gNDUwMCB0byA0NzAwIGFuZCBhIGNvbnRyYWN0IG11bHRpcGxpZXIgb2YgJDI1MCkuCiNUaGlzIGdhaW4gcmVmbGVjdHMgdGhlIHByaWNlIGFwcHJlY2lhdGlvbiBvZiB0aGUgdW5kZXJseWluZyBpbmRleCBkdXJpbmcgdGhlIHNjaG9vbCB0ZXJtLiBUcmFkaW5nIGZ1dHVyZXMgYW1wbGlmaWVzIHRoZXNlIHByaWNlIG1vdmVtZW50cyBkdWUgdG8gdGhlIGhpZ2ggbm90aW9uYWwgdmFsdWUgb2YgdGhlIGNvbnRyYWN0cywgb2ZmZXJpbmcgc2lnbmlmaWNhbnQgcHJvZml0IHBvdGVudGlhbC4KI0hvd2V2ZXIsIHRoaXMgbGV2ZXJhZ2Ugd29ya3MgYm90aCB3YXlzOiB3aGlsZSBnYWlucyBhcmUgbWFnbmlmaWVkIHdoZW4gcHJpY2VzIG1vdmUgaW4geW91ciBmYXZvciwgbG9zc2VzIGNhbiBiZSBlcXVhbGx5IHNpZ25pZmljYW50IGlmIHRoZSBtYXJrZXQgbW92ZXMgYWdhaW5zdCB5b3VyIHBvc2l0aW9uLiBUaGlzIGVtcGhhc2l6ZXMgdGhlIGltcG9ydGFuY2Ugb2YgdW5kZXJzdGFuZGluZyBtYXJrZXQgdHJlbmRzIGFuZCBwb3RlbnRpYWwgcmlza3Mgd2hlbiBlbmdhZ2luZyBpbiBmdXR1cmVzIHRyYWRpbmcuCgpgYGB7cn0KCgoKI0wxMS4yIEFzc3VtZSB0aGF0IHlvdSBpbnZlc3RlZCBhbiBpbml0aWFsIG1hcmdpbiBvZiAyMCBwZXJjZW50IG9mIHRoZSBhbW91bnQgdGhhdCB5b3Ugd291bGQgb3dlIHRvIHB1cmNoYXNlIHRoZSBTJlAgNTAwIGluZGV4IGF0IHRoZSBzZXR0bGVtZW50IGRhdGUuIE1lYXN1cmUgeW91ciByZXR1cm4gZnJvbSB0YWtpbmcgYSBwb3NpdGlvbiBpbiB0aGUgUyZQIDUwMCBpbmRleCBmdXR1cmVzIGFzIGZvbGxvd3MuIFRha2UgdGhlIGRpZmZlcmVuY2UgZGV0ZXJtaW5lZCBpbiB0aGUgcHJldmlvdXMgcXVlc3Rpb24gKHdoaWNoIHJlcHJlc2VudHMgdGhlIGRvbGxhciBhbW91bnQgb2YgdGhlIGdhaW4gb24gdGhlIGZ1dHVyZXMgcG9zaXRpb24pIGFuZCBkaXZpZGUgaXQgYnkgdGhlIGFtb3VudCB5b3Ugb3JpZ2luYWxseSBpbnZlc3RlZCAodGhlIGFtb3VudCB5b3Ugb3JpZ2luYWxseSBpbnZlc3RlZCBpcyAyMCBwZXJjZW50IG9mIHRoZSBkb2xsYXIgdmFsdWUgb2YgdGhlIGZ1dHVyZXMgY29udHJhY3QgdGhhdCB5b3UgcHVyY2hhc2VkKS4KCgojIElucHV0IGRhdGEKc3RhcnRfcHJpY2UgPC0gNDUwMCAgIyBTJlAgNTAwIGZ1dHVyZXMgcHJpY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdGVybQplbmRfcHJpY2UgPC0gNDcwMCAgICAjIFMmUCA1MDAgZnV0dXJlcyBwcmljZSBhdCB0aGUgZW5kIG9mIHRoZSB0ZXJtCmNvbnRyYWN0X3ZhbHVlX211bHRpcGxpZXIgPC0gMjUwICAjIERvbGxhciBtdWx0aXBsaWVyIHBlciBmdXR1cmVzIHByaWNlIHVuaXQKbWFyZ2luX3BlcmNlbnRhZ2UgPC0gMC4yMCAgIyBJbml0aWFsIG1hcmdpbiAoMjAlKQoKCiMgQ2FsY3VsYXRlIHRoZSBkaWZmZXJlbmNlIGluIGRvbGxhciB2YWx1ZSAoZ2Fpbi9sb3NzKQpkaWZmZXJlbmNlIDwtIChlbmRfcHJpY2UgLSBzdGFydF9wcmljZSkgKiBjb250cmFjdF92YWx1ZV9tdWx0aXBsaWVyCgoKIyBDYWxjdWxhdGUgdGhlIGluaXRpYWwgaW52ZXN0bWVudCAobWFyZ2luKQppbml0aWFsX2NvbnRyYWN0X3ZhbHVlIDwtIHN0YXJ0X3ByaWNlICogY29udHJhY3RfdmFsdWVfbXVsdGlwbGllcgppbml0aWFsX2ludmVzdG1lbnQgPC0gaW5pdGlhbF9jb250cmFjdF92YWx1ZSAqIG1hcmdpbl9wZXJjZW50YWdlCgoKIyBDYWxjdWxhdGUgcmV0dXJuCnJldHVybl9wZXJjZW50YWdlIDwtIChkaWZmZXJlbmNlIC8gaW5pdGlhbF9pbnZlc3RtZW50KSAqIDEwMAoKCiMgRGlzcGxheSByZXN1bHRzCmNhdCgiSW5pdGlhbCBmdXR1cmVzIHByaWNlOiIsIHN0YXJ0X3ByaWNlLCAiXG4iKQpjYXQoIkZpbmFsIGZ1dHVyZXMgcHJpY2U6IiwgZW5kX3ByaWNlLCAiXG4iKQpjYXQoIkRvbGxhciBnYWluL2xvc3Mgb24gdGhlIGZ1dHVyZXMgcG9zaXRpb246IiwgZGlmZmVyZW5jZSwgIlVTRFxuIikKY2F0KCJJbml0aWFsIGludmVzdG1lbnQgKG1hcmdpbik6IiwgaW5pdGlhbF9pbnZlc3RtZW50LCAiVVNEXG4iKQpjYXQoIlJldHVybiBvbiBpbnZlc3RtZW50OiIsIHJvdW5kKHJldHVybl9wZXJjZW50YWdlLCAyKSwgIiVcbiIpCgoKCmBgYAoKCiNDb25jbHVzaW9uCiNUaGUgcmV0dXJuIG9uIHlvdXIgaW52ZXN0bWVudCBpbiB0aGUgUyZQIDUwMCBmdXR1cmVzIGlzIGNhbGN1bGF0ZWQgYmFzZWQgb24gdGhlIGdhaW4gb3IgbG9zcyBmcm9tIHRoZSBjb250cmFjdCBkaXZpZGVkIGJ5IHlvdXIgaW5pdGlhbCBtYXJnaW4gaW52ZXN0bWVudCwgd2hpY2ggd2FzIDIwJSBvZiB0aGUgY29udHJhY3QncyBub3Rpb25hbCB2YWx1ZS4KI0luIHRoaXMgZXhhbXBsZSwgdGhlIGxldmVyYWdlZCBuYXR1cmUgb2YgZnV0dXJlcyB0cmFkaW5nIHJlc3VsdHMgaW4gYSBzaWduaWZpY2FudGx5IGFtcGxpZmllZCByZXR1cm4gY29tcGFyZWQgdG8gdGhlIGFjdHVhbCBjaGFuZ2UgaW4gdGhlIGZ1dHVyZXMgcHJpY2UuIFRoaXMgZGVtb25zdHJhdGVzIHRoZSBwb3dlciBvZiBsZXZlcmFnZTogc21hbGwgcHJpY2UgbW92ZW1lbnRzIGluIHRoZSB1bmRlcmx5aW5nIGFzc2V0IHRyYW5zbGF0ZSBpbnRvIGxhcmdlIHBlcmNlbnRhZ2UgZ2FpbnMgb3IgbG9zc2VzIG9uIHRoZSBpbml0aWFsIGludmVzdG1lbnQuCiNXaGlsZSB0aGlzIGxldmVyYWdlIGNhbiBnZW5lcmF0ZSBzdWJzdGFudGlhbCByZXR1cm5zIHdoZW4gdGhlIG1hcmtldCBtb3ZlcyBmYXZvcmFibHksIGl0IGFsc28gY2FycmllcyBzaWduaWZpY2FudCByaXNrLCBhcyBhZHZlcnNlIG1vdmVtZW50cyBjYW4gcXVpY2tseSBsZWFkIHRvIGxhcmdlIGxvc3NlcyByZWxhdGl2ZSB0byB0aGUgbWFyZ2luLiBUaGlzIGhpZ2hsaWdodHMgdGhlIGltcG9ydGFuY2Ugb2YgcmlzayBtYW5hZ2VtZW50IGluIGxldmVyYWdlZCBpbnZlc3RtZW50cyBsaWtlIGZ1dHVyZXMgY29udHJhY3RzLgoKYGBge3J9CgoKCiNMMTEuMyBUaGUgcmV0dXJuIHRoYXQgeW91IGp1c3QgZGVyaXZlZCBpbiB0aGUgcHJldmlvdXMgcXVlc3Rpb24gaXMgbm90IGFubnVhbGl6ZWQuIFRvIGFubnVhbGl6ZSB5b3VyIHJldHVybiwgbXVsdGlwbHkgaXQgYnkgMTIvbSwgd2hlcmUgbSBpcyB0aGUgbnVtYmVyIG9mIG1vbnRocyBpbiB5b3VyIHNjaG9vbCB0ZXJtLgoKIyBJbnB1dCBkYXRhCnJldHVybl9wZXJjZW50YWdlIDwtIDIyLjIyICAjIE5vbi1hbm51YWxpemVkIHJldHVybiBmcm9tIHRoZSBwcmV2aW91cyBxdWVzdGlvbiAoaW4gJSkKc2Nob29sX3Rlcm1fbW9udGhzIDwtIDUgICAgICMgTnVtYmVyIG9mIG1vbnRocyBpbiB0aGUgc2Nob29sIHRlcm0KCgojIENhbGN1bGF0ZSBhbm51YWxpemVkIHJldHVybgphbm51YWxpemVkX3JldHVybiA8LSByZXR1cm5fcGVyY2VudGFnZSAqICgxMiAvIHNjaG9vbF90ZXJtX21vbnRocykKCgojIERpc3BsYXkgcmVzdWx0cwpjYXQoIk5vbi1hbm51YWxpemVkIHJldHVybjoiLCByb3VuZChyZXR1cm5fcGVyY2VudGFnZSwgMiksICIlXG4iKQpjYXQoIk51bWJlciBvZiBtb250aHMgaW4gdGhlIHNjaG9vbCB0ZXJtOiIsIHNjaG9vbF90ZXJtX21vbnRocywgIlxuIikKY2F0KCJBbm51YWxpemVkIHJldHVybjoiLCByb3VuZChhbm51YWxpemVkX3JldHVybiwgMiksICIlXG4iKQoKCmBgYAoKI0NvbmNsdXNpb24KI0FubnVhbGl6aW5nIHRoZSByZXR1cm4gb24geW91ciBpbnZlc3RtZW50IHNob3dzIGhvdyBzaG9ydC10ZXJtIHBlcmZvcm1hbmNlIHNjYWxlcyBvdmVyIGEgZnVsbCB5ZWFyLiBCeSBtdWx0aXBseWluZyB0aGUgbm9uLWFubnVhbGl6ZWQgcmV0dXJuIGJ5IDEyNVxmcmFjezEyfXs1fTUxMuKAiywgCiN3ZSBhZGp1c3QgdGhlIHJldHVybiB0byByZWZsZWN0IGEgMTItbW9udGggcGVyaW9kIGJhc2VkIG9uIHRoZSA1LW1vbnRoIHRlcm0gb2YgdGhlIHNjaG9vbCBzZW1lc3Rlci4KI1RoaXMgcHJvdmlkZXMgYSB1c2VmdWwgY29tcGFyaXNvbiBhZ2FpbnN0IG90aGVyIGludmVzdG1lbnRzIHdpdGggdmFyeWluZyBkdXJhdGlvbnMuIEhvd2V2ZXIsIGl0IGFzc3VtZXMgY29uc2lzdGVudCBwZXJmb3JtYW5jZSB0aHJvdWdob3V0IHRoZSB5ZWFyLCB3aGljaCBtaWdodCBub3QgaG9sZCB0cnVlIGR1ZSB0byBtYXJrZXQgdm9sYXRpbGl0eSBvciBzcGVjaWZpYyBldmVudHMgYWZmZWN0aW5nIHRoZSB1bmRlcmx5aW5nIGFzc2V0LiAKI1doaWxlIHRoZSBhbm51YWxpemVkIHJldHVybiBpcyBoZWxwZnVsIGZvciBjb21wYXJpc29ucywgaXQgaXMgZXNzZW50aWFsIHRvIGNvbnNpZGVyIHRoZSBjb250ZXh0IGFuZCByaXNrcyBvZiBtYWludGFpbmluZyBzaW1pbGFyIHJldHVybnMgb3ZlciBhIGxvbmdlciBwZXJpb2QuCgoKCgoKTDExLjQgQXNzdW1lIHRoYXQgeW91IHB1cmNoYXNlZCBhIGNhbGwgb3B0aW9uIChyZXByZXNlbnRpbmcgMTAwIHNoYXJlcykgb24gdGhlIHNwZWNpZmljIHN0b2NrIHRoYXQgeW91IGlkZW50aWZpZWQgb2YgdGhpcyBwcm9qZWN0LiBXaGF0IHdhcyB5b3VyIHJldHVybiBmcm9tIHB1cmNoYXNpbmcgdGhpcyBvcHRpb24/IFtZb3VyIHJldHVybiBjYW4gYmUgbWVhc3VyZWQgYXMgClByZQptCnQK4oiSUHJlCm0KdOKIkjEKUHJlCm0KdOKIkjEKUHJlbXTiiJJQcmVtdOKIkjFQcmVtdOKIkjEsIHdoZXJlIApQcmUKbQp04oiSMQpQcmVtdOKIkjEgcmVwcmVzZW50cyB0aGUgcHJlbWl1bSBwYWlkIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNjaG9vbCB0ZXJtIGFuZCAKUHJlCm0KdApQcmVtdCByZXByZXNlbnRzIHRoZSBwcmVtaXVtIGF0IHdoaWNoIHRoZSBzYW1lIG9wdGlvbiBjYW4gYmUgc29sZCBhdCB0aGUgZW5kIG9mIHRoZSBzY2hvb2wgdGVybS5dIElmIHRoZSBwcmVtaXVtIGZvciB0aGlzIG9wdGlvbiBpcyBub3QgcXVvdGVkIGF0IHRoZSBlbmQgb2YgdGhlIHNjaG9vbCB0ZXJtLCBtZWFzdXJlIHRoZSByZXR1cm4gYXMgaWYgeW91IGhhZCBleGVyY2lzZWQgdGhlIGNhbGwgb3B0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIHNjaG9vbCB0ZXJtIChhc3N1bWluZyB0aGF0IGl0IGlzIGZlYXNpYmxlIHRvIGV4ZXJjaXNlIHRoZSBvcHRpb24gYXQgdGhhdCB0aW1lKS4gVGhhdCBpcywgdGhlIHJldHVybiBpcyBiYXNlZCBvbiBwdXJjaGFzaW5nIHRoZSBzdG9jayBhdCB0aGUgb3B0aW9u4oCZcyBzdHJpa2UgcHJpY2UgYW5kIHRoZW4gc2VsbGluZyB0aGUgc3RvY2sgYXQgaXRzIG1hcmtldCBwcmljZSBhdCB0aGUgZW5kIG9mIHRoZSBzY2hvb2wgdGVybS4KIyBJbnB1dCBkYXRhOiBSZXBsYWNlIHRoZXNlIHdpdGggYWN0dWFsIHZhbHVlcwpgYGB7cn0KCgoKb3B0aW9uX3ByZW1pdW1fc3RhcnQgPC0gNS4wICAjIFByZW1pdW0gcGFpZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0ZXJtICgkIHBlciBzaGFyZSkKb3B0aW9uX3ByZW1pdW1fZW5kIDwtIDguMCAgICAjIFByZW1pdW0gcmVjZWl2ZWQgYXQgdGhlIGVuZCBvZiB0aGUgdGVybSAoJCBwZXIgc2hhcmUpCnN0b2NrX3ByaWNlX2VuZCA8LSAxNTAuMCAgICAgIyBTdG9jayBwcmljZSBhdCB0aGUgZW5kIG9mIHRoZSB0ZXJtCnN0cmlrZV9wcmljZSA8LSAxNDAuMCAgICAgICAgIyBTdHJpa2UgcHJpY2Ugb2YgdGhlIG9wdGlvbiAoJCBwZXIgc2hhcmUpCnNoYXJlc19wZXJfb3B0aW9uIDwtIDEwMCAgICAgIyBFYWNoIG9wdGlvbiByZXByZXNlbnRzIDEwMCBzaGFyZXMKCgojIFNjZW5hcmlvIDE6IFNlbGxpbmcgdGhlIG9wdGlvbgppZiAoIWlzLm5hKG9wdGlvbl9wcmVtaXVtX2VuZCkpIHsKICAgIHJldHVybl9wcmVtaXVtIDwtICgob3B0aW9uX3ByZW1pdW1fZW5kIC0gb3B0aW9uX3ByZW1pdW1fc3RhcnQpIC8gb3B0aW9uX3ByZW1pdW1fc3RhcnQpICogMTAwCiAgICBjYXQoIlJldHVybiBmcm9tIHNlbGxpbmcgdGhlIG9wdGlvbjoiLCByb3VuZChyZXR1cm5fcHJlbWl1bSwgMiksICIlXG4iKQp9CgoKIyBTY2VuYXJpbyAyOiBFeGVyY2lzaW5nIHRoZSBvcHRpb24KaWYgKGlzLm5hKG9wdGlvbl9wcmVtaXVtX2VuZCkgJiYgc3RvY2tfcHJpY2VfZW5kID4gc3RyaWtlX3ByaWNlKSB7CiAgICBpbnRyaW5zaWNfdmFsdWUgPC0gKHN0b2NrX3ByaWNlX2VuZCAtIHN0cmlrZV9wcmljZSkgKiBzaGFyZXNfcGVyX29wdGlvbgogICAgcmV0dXJuX2V4ZXJjaXNlIDwtIChpbnRyaW5zaWNfdmFsdWUgLSAob3B0aW9uX3ByZW1pdW1fc3RhcnQgKiBzaGFyZXNfcGVyX29wdGlvbikpIC8gCiAgICAgICAgKG9wdGlvbl9wcmVtaXVtX3N0YXJ0ICogc2hhcmVzX3Blcl9vcHRpb24pICogMTAwCiAgICBjYXQoIlJldHVybiBmcm9tIGV4ZXJjaXNpbmcgdGhlIG9wdGlvbjoiLCByb3VuZChyZXR1cm5fZXhlcmNpc2UsIDIpLCAiJVxuIikKfSBlbHNlIGlmIChzdG9ja19wcmljZV9lbmQgPD0gc3RyaWtlX3ByaWNlKSB7CiAgICBjYXQoIlRoZSBvcHRpb24gZXhwaXJlZCB3b3J0aGxlc3MgYXMgdGhlIHN0b2NrIHByaWNlIGRpZCBub3QgZXhjZWVkIHRoZSBzdHJpa2UgcHJpY2UuXG4iKQp9CgpgYGAKCgoKCiNDb25jbHVzaW9uCiNUaGUgcmV0dXJuIG9uIGEgY2FsbCBvcHRpb24gZGVwZW5kcyBvbiB3aGV0aGVyIGl0IGlzIHJlYWxpemVkIGJ5IHNlbGxpbmcgdGhlIG9wdGlvbiBvciBleGVyY2lzaW5nIGl0LiBXaGVuIHNvbGQsIHRoZSByZXR1cm4gaXMgZGV0ZXJtaW5lZCBieSB0aGUgY2hhbmdlIGluIHRoZSBvcHRpb27igJlzIHByZW1pdW0sIG9mdGVuIHNob3djYXNpbmcgc2lnbmlmaWNhbnQgZ2FpbnMgZHVlIHRvIHRoZSBsZXZlcmFnZSBlZmZlY3QuIElmIGV4ZXJjaXNlZCwgdGhlIHJldHVybiBpcyBiYXNlZCBvbiB0aGUgc3RvY2sgcHJpY2UgZXhjZWVkaW5nIHRoZSBzdHJpa2UgcHJpY2UsIGZhY3RvcmluZyBpbiB0aGUgaW5pdGlhbCBwcmVtaXVtIHBhaWQuIFdoaWxlIG9wdGlvbnMgY2FuIGFtcGxpZnkgcmV0dXJucyBjb21wYXJlZCB0byBkaXJlY3RseSBpbnZlc3RpbmcgaW4gdGhlIHN0b2NrLCB0aGV5IGNhcnJ5IGhpZ2hlciByaXNrcywgYXMgYSBwb29yIHN0b2NrIHBlcmZvcm1hbmNlIGNhbiBsZWFkIHRvIHRoZSBsb3NzIG9mIHRoZSBlbnRpcmUgcHJlbWl1bS4gVGhpcyB1bmRlcnNjb3JlcyB0aGUgaGlnaC1yaXNrLCBoaWdoLXJld2FyZCBuYXR1cmUgb2Ygb3B0aW9ucyB0cmFkaW5nIGFuZCB0aGUgaW1wb3J0YW5jZSBvZiBzdHJhdGVnaWMgZGVjaXNpb24tbWFraW5nIGluIHV0aWxpemluZyB0aGVtIGVmZmVjdGl2ZWx5LgoKCiNMMTEuNSBBbm51YWxpemUgdGhlIHJldHVybiBvbiB5b3VyIG9wdGlvbiBieSBtdWx0aXBseWluZyB0aGUgcmV0dXJuIHlvdSBkZXJpdmVkIGluIHRoZSBwcmV2aW91cyBxdWVzdGlvbiBieSAxMi9tLCB3aGVyZSBtIHJlcHJlc2VudHMgdGhlIG51bWJlciBvZiBtb250aHMgaW4geW91ciBzY2hvb2wgdGVybS4KCmBgYHtyfQoKCgojIElucHV0IGRhdGE6IFJlcGxhY2Ugd2l0aCB0aGUgYWN0dWFsIHJldHVybiBmcm9tIHRoZSBwcmV2aW91cyBjYWxjdWxhdGlvbgpub25fYW5udWFsaXplZF9yZXR1cm4gPC0gNjAuMCAgIyBOb24tYW5udWFsaXplZCByZXR1cm4gaW4gcGVyY2VudGFnZSAoZS5nLiwgZnJvbSBzZWxsaW5nIHRoZSBvcHRpb24pCnNjaG9vbF90ZXJtX21vbnRocyA8LSA1ICAgICAgICAjIE51bWJlciBvZiBtb250aHMgaW4gdGhlIHNjaG9vbCB0ZXJtCgoKIyBDYWxjdWxhdGUgYW5udWFsaXplZCByZXR1cm4KYW5udWFsaXplZF9yZXR1cm4gPC0gbm9uX2FubnVhbGl6ZWRfcmV0dXJuICogKDEyIC8gc2Nob29sX3Rlcm1fbW9udGhzKQoKCiMgRGlzcGxheSByZXN1bHRzCmNhdCgiTm9uLWFubnVhbGl6ZWQgcmV0dXJuOiIsIHJvdW5kKG5vbl9hbm51YWxpemVkX3JldHVybiwgMiksICIlXG4iKQpjYXQoIk51bWJlciBvZiBtb250aHMgaW4gdGhlIHNjaG9vbCB0ZXJtOiIsIHNjaG9vbF90ZXJtX21vbnRocywgIlxuIikKY2F0KCJBbm51YWxpemVkIHJldHVybjoiLCByb3VuZChhbm51YWxpemVkX3JldHVybiwgMiksICIlXG4iKQoKYGBgCgoKI0NvbmNsdXNpb24KQW5udWFsaXppbmcgdGhlIHJldHVybiBvbiB0aGUgY2FsbCBvcHRpb24gcmV2ZWFscyB0aGUgc2lnbmlmaWNhbnQgaW1wYWN0IG9mIGxldmVyYWdlIG92ZXIgYSBsb25nZXIgdGltZSBob3Jpem9uLiBJbiB0aGlzIGNhc2UsIHRoZSBhbm51YWxpemVkIHJldHVybiBpcyBzdWJzdGFudGlhbGx5IGhpZ2hlciB0aGFuIHRoZSBub24tYW5udWFsaXplZCByZXR1cm4gZHVlIHRvIHRoZSByZWxhdGl2ZWx5IHNob3J0IGR1cmF0aW9uIG9mIHRoZSBzY2hvb2wgdGVybSAoNSBtb250aHMpLgpUaGlzIHJlc3VsdCBoaWdobGlnaHRzIGhvdyB0aGUgdGltZSBwZXJpb2QgYWZmZWN0cyByZXR1cm4gcHJvamVjdGlvbnMsIGVzcGVjaWFsbHkgaW4gbGV2ZXJhZ2VkIGluc3RydW1lbnRzIGxpa2Ugb3B0aW9ucy4gSXQgYWxsb3dzIGZvciBhIGRpcmVjdCBjb21wYXJpc29uIHdpdGggb3RoZXIgaW52ZXN0bWVudHMgb2YgdmFyeWluZyBkdXJhdGlvbnMuIEhvd2V2ZXIsIGl0IGlzIGltcG9ydGFudCB0byBub3RlIHRoYXQgdGhpcyBhc3N1bWVzIHRoZSBzYW1lIHJhdGUgb2YgcmV0dXJuIHdvdWxkIHBlcnNpc3QgCgoKCgojTDExLjYgQ29tcGFyZSB0aGUgcmV0dXJuIG9uIHlvdXIgY2FsbCBvcHRpb24gdG8gdGhlIHJldHVybiB0aGF0IHlvdSB3b3VsZCBoYXZlIGVhcm5lZCBpZiB5b3UgaGFkIHNpbXBseSBpbnZlc3RlZCBpbiB0aGUgc3RvY2sgaXRzZWxmLiBOb3RpY2UgaG93IHRoZSBtYWduaXR1ZGUgb2YgdGhlIHJldHVybiBvbiB0aGUgY2FsbCBvcHRpb24gaXMgbXVjaCBsYXJnZXIgdGhhbiB0aGUgbWFnbml0dWRlIG9mIHRoZSByZXR1cm4gb24gdGhlIHN0b2NrIGl0c2VsZi4gVGhhdCBpcywgdGhlIGdhaW5zIGFyZSBsYXJnZXIgYW5kIHRoZSBsb3NzZXMgYXJlIGxhcmdlciB3aGVuIGludmVzdGluZyBpbiBjYWxsIG9wdGlvbnMgb24gYSBzdG9jayBpbnN0ZWFkIG9mIHRoZSBzdG9jayBpdHNlbGYuCmBgYHtyfQoKCgojIElucHV0IGRhdGE6IFJlcGxhY2UgdGhlc2Ugd2l0aCBhY3R1YWwgdmFsdWVzCnN0b2NrX3ByaWNlX3N0YXJ0IDwtIDE0MC4wICAgICMgU3RvY2sgcHJpY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdGVybSAoJCBwZXIgc2hhcmUpCnN0b2NrX3ByaWNlX2VuZCA8LSAxNTAuMCAgICAgICMgU3RvY2sgcHJpY2UgYXQgdGhlIGVuZCBvZiB0aGUgdGVybSAoJCBwZXIgc2hhcmUpCm9wdGlvbl9yZXR1cm4gPC0gMTQ0LjAgICAgICAgICMgQW5udWFsaXplZCByZXR1cm4gb24gdGhlIG9wdGlvbiAoaW4gJSBmcm9tIHRoZSBwcmV2aW91cyBxdWVzdGlvbikKCgojIENhbGN1bGF0ZSB0aGUgcmV0dXJuIG9uIHRoZSBzdG9jawpzdG9ja19yZXR1cm4gPC0gKChzdG9ja19wcmljZV9lbmQgLSBzdG9ja19wcmljZV9zdGFydCkgLyBzdG9ja19wcmljZV9zdGFydCkgKiAxMDAKCgojIERpc3BsYXkgcmVzdWx0cwpjYXQoIlN0b2NrIHByaWNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm06Iiwgc3RvY2tfcHJpY2Vfc3RhcnQsICJcbiIpCmNhdCgiU3RvY2sgcHJpY2UgYXQgdGhlIGVuZCBvZiB0aGUgdGVybToiLCBzdG9ja19wcmljZV9lbmQsICJcbiIpCmNhdCgiUmV0dXJuIG9uIHRoZSBzdG9jazoiLCByb3VuZChzdG9ja19yZXR1cm4sIDIpLCAiJVxuIikKY2F0KCJSZXR1cm4gb24gdGhlIGNhbGwgb3B0aW9uIChhbm51YWxpemVkKToiLCByb3VuZChvcHRpb25fcmV0dXJuLCAyKSwgIiVcbiIpCgoKIyBDb21wYXJlIG1hZ25pdHVkZXMKaWYgKG9wdGlvbl9yZXR1cm4gPiBzdG9ja19yZXR1cm4pIHsKICAgIGNhdCgiVGhlIHJldHVybiBvbiB0aGUgY2FsbCBvcHRpb24gaXMgc2lnbmlmaWNhbnRseSBsYXJnZXIgdGhhbiB0aGUgcmV0dXJuIG9uIHRoZSBzdG9jayBpdHNlbGYsIHNob3djYXNpbmcgbGV2ZXJhZ2UuXG4iKQp9IGVsc2UgewogICAgY2F0KCJUaGUgcmV0dXJuIG9uIHRoZSBzdG9jayBpcyBsYXJnZXIsIHdoaWNoIGlzIHVudXN1YWwgZm9yIG9wdGlvbnMuXG4iKQp9CgoKYGBgCgoKCiNDb25jbHVzaW9uCiNUaGUgY29tcGFyaXNvbiBiZXR3ZWVuIHRoZSByZXR1cm4gb24gdGhlIGNhbGwgb3B0aW9uIGFuZCB0aGUgcmV0dXJuIG9uIHRoZSB1bmRlcmx5aW5nIHN0b2NrIGRlbW9uc3RyYXRlcyB0aGUgYW1wbGlmaWVkIGVmZmVjdCBvZiBvcHRpb25zIHRyYWRpbmcuIFdoaWxlIHRoZSByZXR1cm4gb24gdGhlIHN0b2NrIGl0c2VsZiByZWZsZWN0cyBpdHMgbW9kZXJhdGUgYXBwcmVjaWF0aW9uLCB0aGUgcmV0dXJuIG9uIHRoZSBjYWxsIG9wdGlvbiBpcyBzaWduaWZpY2FudGx5IGxhcmdlciBkdWUgdG8gdGhlIGxldmVyYWdlIHByb3ZpZGVkIGJ5IG9wdGlvbnMuCiNUaGlzIGxldmVyYWdlIG1lYW5zIHRoYXQgYSBzbWFsbCBwZXJjZW50YWdlIGNoYW5nZSBpbiB0aGUgc3RvY2vigJlzIHByaWNlIHJlc3VsdHMgaW4gYSBtdWNoIGxhcmdlciBwZXJjZW50YWdlIGNoYW5nZSBpbiB0aGUgb3B0aW9u4oCZcyB2YWx1ZS4gSG93ZXZlciwgdGhpcyBhbXBsaWZpY2F0aW9uIHdvcmtzIGJvdGggd2F5czogaWYgdGhlIHN0b2Nr4oCZcyBwcmljZSBoYWQgZGVjbGluZWQsIHRoZSBsb3NzZXMgb24gdGhlIG9wdGlvbiB3b3VsZCBoYXZlIGJlZW4gZmFyIGdyZWF0ZXIgaW4gbWFnbml0dWRlIGNvbXBhcmVkIHRvIGhvbGRpbmcgdGhlIHN0b2NrIGRpcmVjdGx5LgojSW52ZXN0aW5nIGluIGNhbGwgb3B0aW9ucyBjYW4geWllbGQgc3Vic3RhbnRpYWwgZ2FpbnMsIGFzIHNlZW4gaW4gdGhpcyBjYXNlLCBidXQgaXQgYWxzbyBpbnZvbHZlcyBoaWdoZXIgcmlzaywgbWFraW5nIGl0IGEgc3RyYXRlZ3kgc3VpdGFibGUgZm9yIGludmVzdG9ycyB3aG8gYXJlIGNvbmZpZGVudCBpbiB0aGUgZGlyZWN0aW9uIG9mIHRoZSBzdG9ja+KAmXMgcHJpY2UgbW92ZW1lbnQuCgoKI0RldGVybWluaW5nIHN3YXAgcGF5bWVudHMKI0wxMS43IEFzc3VtZSB0aGF0LCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzY2hvb2wgdGVybSwgeW91IGVuZ2FnZWQgaW4gYSBmaXhlZC1mb3ItZmxvYXRpbmcgcmF0ZSBzd2FwIGluIHdoaWNoIHlvdSBhZ3JlZWQgdG8gcGF5IDYgcGVyY2VudCBpbiBleGNoYW5nZSBmb3IgdGhlIHByZXZhaWxpbmcgMjYtd2VlayBULWJpbGwgcmF0ZSB0aGF0IGV4aXN0cyBhdCB0aGUgZW5kIG9mIHRoZSBzY2hvb2wgdGVybS4gQXNzdW1lIHRoYXQgeW91ciBzd2FwIGFncmVlbWVudCBzcGVjaWZpZXMgdGhlIGVuZCBvZiB0aGUgc2Nob29sIHRlcm0gYXMgdGhlIG9ubHkgdGltZSBhdCB3aGljaCBhIHN3YXAgd2lsbCBvY2N1ciBhbmQgdGhhdCB0aGUgbm90aW9uYWwgYW1vdW50IGlzICQxMCBtaWxsaW9uLiBEZXRlcm1pbmUgdGhlIGFtb3VudCB0aGF0IHlvdSBvd2Ugb24gdGhlIHN3YXAsIHRoZSBhbW91bnQgeW91IGFyZSBvd2VkIG9uIHRoZSBzd2FwLCBhbmQgdGhlIGRpZmZlcmVuY2UuIERpZCB5b3UgZ2FpbiBvciBsb3NlIGFzIGEgcmVzdWx0IG9mIHRoZSBzd2FwPwpgYGB7cn0KCgoKIyBJbnB1dCBkYXRhCm5vdGlvbmFsX2Ftb3VudCA8LSAxMDAwMDAwMCAgICAgICAjIE5vdGlvbmFsIGFtb3VudCAoJDEwIG1pbGxpb24pCmZpeGVkX3JhdGUgPC0gMC4wNiAgICAgICAgICAgICAgICAjIEZpeGVkIHJhdGUgKDYlKQpmbG9hdGluZ19yYXRlIDwtIDAuMDQ1ICAgICAgICAgICAgIyBGbG9hdGluZyByYXRlICgyNi13ZWVrIFQtYmlsbCByYXRlIGF0IHRoZSBlbmQgb2YgdGhlIHRlcm0sIGUuZy4sIDQuNSUpCgoKIyBDYWxjdWxhdGUgcGF5bWVudHMKZml4ZWRfcGF5bWVudCA8LSBmaXhlZF9yYXRlICogbm90aW9uYWxfYW1vdW50CmZsb2F0aW5nX3BheW1lbnQgPC0gZmxvYXRpbmdfcmF0ZSAqIG5vdGlvbmFsX2Ftb3VudApkaWZmZXJlbmNlIDwtIGZsb2F0aW5nX3BheW1lbnQgLSBmaXhlZF9wYXltZW50CgoKIyBEaXNwbGF5IHJlc3VsdHMKY2F0KCJOb3Rpb25hbCBhbW91bnQ6Iiwgbm90aW9uYWxfYW1vdW50LCAiVVNEXG4iKQpjYXQoIkZpeGVkIHJhdGUgcGF5bWVudDoiLCByb3VuZChmaXhlZF9wYXltZW50LCAyKSwgIlVTRFxuIikKY2F0KCJGbG9hdGluZyByYXRlIHBheW1lbnQ6Iiwgcm91bmQoZmxvYXRpbmdfcGF5bWVudCwgMiksICJVU0RcbiIpCmNhdCgiRGlmZmVyZW5jZSAoZmxvYXRpbmcgLSBmaXhlZCk6Iiwgcm91bmQoZGlmZmVyZW5jZSwgMiksICJVU0RcbiIpCgoKIyBEZXRlcm1pbmUgZ2FpbiBvciBsb3NzCmlmIChkaWZmZXJlbmNlID4gMCkgewogICAgY2F0KCJZb3UgZ2FpbmVkIiwgcm91bmQoZGlmZmVyZW5jZSwgMiksICJVU0QgYXMgYSByZXN1bHQgb2YgdGhlIHN3YXAuXG4iKQp9IGVsc2UgewogICAgY2F0KCJZb3UgbG9zdCIsIGFicyhyb3VuZChkaWZmZXJlbmNlLCAyKSksICJVU0QgYXMgYSByZXN1bHQgb2YgdGhlIHN3YXAuXG4iKQp9CgoKCmBgYAojQ29uY2x1c2lvbgojVGhlIHN3YXAgcmVzdWx0ZWQgaW4gYSBsb3NzIG9mICQxNTAsMDAwIGR1ZSB0byB0aGUgZml4ZWQgcGF5bWVudCBvZiA2JSAoJDYwMCwwMDApIGV4Y2VlZGluZyB0aGUgZmxvYXRpbmcgcmF0ZSBwYXltZW50IHRpZWQgdG8gdGhlIDI2LXdlZWsgVC1iaWxsIHJhdGUgb2YgNC41JSAoJDQ1MCwwMDApLgojVGhpcyBsb3NzIGhpZ2hsaWdodHMgdGhlIHJpc2sgYXNzb2NpYXRlZCB3aXRoIGVudGVyaW5nIGEgZml4ZWQtZm9yLWZsb2F0aW5nIHJhdGUgc3dhcCB3aGVuIHRoZSBmbG9hdGluZyByYXRlIGlzIGxvd2VyIHRoYW4gdGhlIGFncmVlZCBmaXhlZCByYXRlLiBUaGUgZml4ZWQgcGF5bWVudCByZW1haW5zIGNvbnN0YW50IHJlZ2FyZGxlc3Mgb2YgbWFya2V0IGZsdWN0dWF0aW9ucywgd2hlcmVhcyB0aGUgZmxvYXRpbmcgcGF5bWVudCBhZGp1c3RzIHRvIHJlZmxlY3QgcHJldmFpbGluZyBpbnRlcmVzdCByYXRlcy4KI0luIHRoaXMgc2NlbmFyaW8sIHRoZSBkZWNsaW5lIGluIHRoZSBmbG9hdGluZyByYXRlIGR1cmluZyB0aGUgdGVybSB3b3JrZWQgYWdhaW5zdCB0aGUgZml4ZWQgcGF5ZXIsIGVtcGhhc2l6aW5nIHRoZSBpbXBvcnRhbmNlIG9mIGZvcmVjYXN0aW5nIGludGVyZXN0IHJhdGUgdHJlbmRzIHdoZW4gc3RydWN0dXJpbmcgc3dhcCBhZ3JlZW1lbnRzLiBIYWQgdGhlIGZsb2F0aW5nIHJhdGUgYmVlbiBoaWdoZXIgdGhhbiA2JSwgdGhlIHJlc3VsdCB3b3VsZCBoYXZlIGJlZW4gYSBnYWluIGZvciB0aGUgZml4ZWQgcGF5ZXIuCgoKI01lYXN1cmluZyBhbmQgZXhwbGFpbmluZyBleGNoYW5nZSByYXRlIG1vdmVtZW50cwojTDExLjggRGV0ZXJtaW5lIHRoZSBwZXJjZW50YWdlIGNoYW5nZSBpbiB0aGUgdmFsdWUgb2YgdGhlIEJyaXRpc2ggcG91bmQgb3ZlciB0aGUgc2Nob29sIHRlcm0uIERpZCB0aGUgcG91bmQgYXBwcmVjaWF0ZSBvciBkZXByZWNpYXRlIGFnYWluc3QgdGhlIGRvbGxhcj8KYGBge3J9CgoKCiMgSW5wdXQgZGF0YTogUmVwbGFjZSB3aXRoIGFjdHVhbCBleGNoYW5nZSByYXRlIHZhbHVlcwpleGNoYW5nZV9yYXRlX3N0YXJ0IDwtIDEuMjUgICMgR0JQL1VTRCBleGNoYW5nZSByYXRlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm0KZXhjaGFuZ2VfcmF0ZV9lbmQgPC0gMS4yMCAgICAjIEdCUC9VU0QgZXhjaGFuZ2UgcmF0ZSBhdCB0aGUgZW5kIG9mIHRoZSB0ZXJtCgoKIyBDYWxjdWxhdGUgcGVyY2VudGFnZSBjaGFuZ2UKcGVyY2VudGFnZV9jaGFuZ2UgPC0gKChleGNoYW5nZV9yYXRlX2VuZCAtIGV4Y2hhbmdlX3JhdGVfc3RhcnQpIC8gZXhjaGFuZ2VfcmF0ZV9zdGFydCkgKiAxMDAKCgojIERpc3BsYXkgcmVzdWx0cwpjYXQoIkV4Y2hhbmdlIHJhdGUgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdGVybSAoR0JQL1VTRCk6IiwgZXhjaGFuZ2VfcmF0ZV9zdGFydCwgIlxuIikKY2F0KCJFeGNoYW5nZSByYXRlIGF0IHRoZSBlbmQgb2YgdGhlIHRlcm0gKEdCUC9VU0QpOiIsIGV4Y2hhbmdlX3JhdGVfZW5kLCAiXG4iKQpjYXQoIlBlcmNlbnRhZ2UgY2hhbmdlIGluIEdCUC9VU0QgZXhjaGFuZ2UgcmF0ZToiLCByb3VuZChwZXJjZW50YWdlX2NoYW5nZSwgMiksICIlXG4iKQoKCiMgRGV0ZXJtaW5lIGFwcHJlY2lhdGlvbiBvciBkZXByZWNpYXRpb24KaWYgKHBlcmNlbnRhZ2VfY2hhbmdlID4gMCkgewogICAgY2F0KCJUaGUgQnJpdGlzaCBwb3VuZCBhcHByZWNpYXRlZCBhZ2FpbnN0IHRoZSBVUyBkb2xsYXIuXG4iKQp9IGVsc2UgaWYgKHBlcmNlbnRhZ2VfY2hhbmdlIDwgMCkgewogICAgY2F0KCJUaGUgQnJpdGlzaCBwb3VuZCBkZXByZWNpYXRlZCBhZ2FpbnN0IHRoZSBVUyBkb2xsYXIuXG4iKQp9IGVsc2UgewogICAgY2F0KCJUaGVyZSB3YXMgbm8gY2hhbmdlIGluIHRoZSB2YWx1ZSBvZiB0aGUgQnJpdGlzaCBwb3VuZCBhZ2FpbnN0IHRoZSBVUyBkb2xsYXIuXG4iKQp9CgpgYGAKCgojQ29uY2x1c2lvbgojVGhlIHBlcmNlbnRhZ2UgY2hhbmdlIGluIHRoZSBHQlAvVVNEIGV4Y2hhbmdlIHJhdGUgb3ZlciB0aGUgc2Nob29sIHRlcm0gaXMgY2FsY3VsYXRlZCBhcyAtNC4wMCUsIGluZGljYXRpbmcgdGhhdCB0aGUgQnJpdGlzaCBwb3VuZCBkZXByZWNpYXRlZCBhZ2FpbnN0IHRoZSBVUyBkb2xsYXIuCiNUaGlzIGRlcHJlY2lhdGlvbiBtZWFucyB0aGUgcG91bmQgbG9zdCB2YWx1ZSByZWxhdGl2ZSB0byB0aGUgZG9sbGFyLCByZXF1aXJpbmcgZmV3ZXIgZG9sbGFycyB0byBwdXJjaGFzZSBvbmUgcG91bmQgYXQgdGhlIGVuZCBvZiB0aGUgdGVybSBjb21wYXJlZCB0byB0aGUgYmVnaW5uaW5nLiBTdWNoIG1vdmVtZW50cyBjYW4gYmUgaW5mbHVlbmNlZCBieSBlY29ub21pYyBjb25kaXRpb25zLCBtb25ldGFyeSBwb2xpY3kgc2hpZnRzLCBvciBtYXJrZXQgc2VudGltZW50IHJlZ2FyZGluZyB0aGUgVUsgZWNvbm9teS4KI0ZvciBpbnZlc3RvcnMgb3IgdHJhZGVycywgdGhpcyBkZXByZWNpYXRpb24gcmVmbGVjdHMgYSBkZWNsaW5lIGluIHRoZSBwb3VuZCdzIHB1cmNoYXNpbmcgcG93ZXIgYWdhaW5zdCB0aGUgZG9sbGFyLCBwb3RlbnRpYWxseSBpbXBhY3RpbmcgaW50ZXJuYXRpb25hbCB0cmFkZSwgaW52ZXN0bWVudHMsIGFuZCBoZWRnaW5nIHN0cmF0ZWdpZXMgdGllZCB0byB0aGUgY3VycmVuY3kgcGFpci4KCgojTDExLjkgRGV0ZXJtaW5lIHRoZSBwZXJjZW50YWdlIGNoYW5nZSBpbiB0aGUgdmFsdWUgb2YgdGhlIEphcGFuZXNlIHllbiBvdmVyIHRoZSBzY2hvb2wgdGVybS4gRGlkIHRoZSB5ZW4gYXBwcmVjaWF0ZSBvciBkZXByZWNpYXRlIGFnYWluc3QgdGhlIGRvbGxhcj8KYGBge3J9CgoKCiAgCiMgSW5wdXQgZGF0YTogUmVwbGFjZSB3aXRoIGFjdHVhbCBleGNoYW5nZSByYXRlIHZhbHVlcwojZXhjaGFuZ2VfcmF0ZV9zdGFydCA8LSAxMzAuMDAgICMgVVNEL0pQWSBleGNoYW5nZSByYXRlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm0KI2V4Y2hhbmdlX3JhdGVfZW5kIDwtIDEzNS4wMCAgICAjIFVTRC9KUFkgZXhjaGFuZ2UgcmF0ZSBhdCB0aGUgZW5kIG9mIHRoZSB0ZXJtCgoKIyBDYWxjdWxhdGUgcGVyY2VudGFnZSBjaGFuZ2UKcGVyY2VudGFnZV9jaGFuZ2UgPC0gKChleGNoYW5nZV9yYXRlX2VuZCAtIGV4Y2hhbmdlX3JhdGVfc3RhcnQpIC8gZXhjaGFuZ2VfcmF0ZV9zdGFydCkgKiAxMDAKCgojIERpc3BsYXkgcmVzdWx0cwpjYXQoIkV4Y2hhbmdlIHJhdGUgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdGVybSAoVVNEL0pQWSk6IiwgZXhjaGFuZ2VfcmF0ZV9zdGFydCwgIlxuIikKY2F0KCJFeGNoYW5nZSByYXRlIGF0IHRoZSBlbmQgb2YgdGhlIHRlcm0gKFVTRC9KUFkpOiIsIGV4Y2hhbmdlX3JhdGVfZW5kLCAiXG4iKQpjYXQoIlBlcmNlbnRhZ2UgY2hhbmdlIGluIFVTRC9KUFkgZXhjaGFuZ2UgcmF0ZToiLCByb3VuZChwZXJjZW50YWdlX2NoYW5nZSwgMiksICIlXG4iKQoKCiMgRGV0ZXJtaW5lIGFwcHJlY2lhdGlvbiBvciBkZXByZWNpYXRpb24KaWYgKHBlcmNlbnRhZ2VfY2hhbmdlID4gMCkgewogIGNhdCgiVGhlIEphcGFuZXNlIHllbiBkZXByZWNpYXRlZCBhZ2FpbnN0IHRoZSBVUyBkb2xsYXIuXG4iKQp9IGVsc2UgaWYgKHBlcmNlbnRhZ2VfY2hhbmdlIDwgMCkgewogIGNhdCgiVGhlIEphcGFuZXNlIHllbiBhcHByZWNpYXRlZCBhZ2FpbnN0IHRoZSBVUyBkb2xsYXIuXG4iKQp9IGVsc2UgewogIGNhdCgiVGhlcmUgd2FzIG5vIGNoYW5nZSBpbiB0aGUgdmFsdWUgb2YgdGhlIEphcGFuZXNlIHllbiBhZ2FpbnN0IHRoZSBVUyBkb2xsYXIuXG4iKQp9CgoKYGBgCgoKCiNDb25jbHVzaW9uCiNUaGUgcGVyY2VudGFnZSBjaGFuZ2UgaW4gdGhlIFVTRC9KUFkgZXhjaGFuZ2UgcmF0ZSBvdmVyIHRoZSBzY2hvb2wgdGVybSBpcyBjYWxjdWxhdGVkIGFzICszLjg1JSwgaW5kaWNhdGluZyB0aGF0IHRoZSBKYXBhbmVzZSB5ZW4gZGVwcmVjaWF0ZWQgYWdhaW5zdCB0aGUgVVMgZG9sbGFyLgojVGhpcyBkZXByZWNpYXRpb24gbWVhbnMgdGhhdCBtb3JlIHllbiB3ZXJlIHJlcXVpcmVkIHRvIHB1cmNoYXNlIG9uZSBkb2xsYXIgYXQgdGhlIGVuZCBvZiB0aGUgdGVybSB0aGFuIGF0IHRoZSBiZWdpbm5pbmcuIFN1Y2ggbW92ZW1lbnRzIG9mdGVuIHJlZmxlY3QgY2hhbmdlcyBpbiBlY29ub21pYyBmYWN0b3JzIGxpa2UgaW50ZXJlc3QgcmF0ZSBkaWZmZXJlbnRpYWxzLCBtb25ldGFyeSBwb2xpY3kgYWRqdXN0bWVudHMsIG9yIGJyb2FkZXIgbWFya2V0IGNvbmRpdGlvbnMgZmF2b3JpbmcgdGhlIGRvbGxhci4KI0ZvciB0cmFkZXJzIG9yIGludmVzdG9ycyBkZWFsaW5nIGluIHllbiwgdGhpcyBkZXByZWNpYXRpb24gcmVwcmVzZW50cyBhIGxvc3MgaW4gdGhlIHllbidzIHZhbHVlIHJlbGF0aXZlIHRvIHRoZSBkb2xsYXIsIHVuZGVybGluaW5nIHRoZSBpbXBvcnRhbmNlIG9mIGV4Y2hhbmdlIHJhdGUgZmx1Y3R1YXRpb25zIGluIGludGVybmF0aW9uYWwgdHJhbnNhY3Rpb25zIGFuZCBpbnZlc3RtZW50IGRlY2lzaW9ucy4KCgojTDExLjEwIERldGVybWluZSB0aGUgcGVyY2VudGFnZSBjaGFuZ2UgaW4gdGhlIHZhbHVlIG9mIHRoZSBNZXhpY2FuIHBlc28gb3ZlciB0aGUgc2Nob29sIHRlcm0uIERpZCB0aGUgcGVzbyBhcHByZWNpYXRlIG9yIGRlcHJlY2lhdGUgYWdhaW5zdCB0aGUgZG9sbGFyPwpgYGB7cn0KCgoKIyBJbnB1dCBkYXRhOiBSZXBsYWNlIHdpdGggYWN0dWFsIGV4Y2hhbmdlIHJhdGUgdmFsdWVzCmV4Y2hhbmdlX3JhdGVfc3RhcnQgPC0gMTguNTAgICMgVVNEL01YTiBleGNoYW5nZSByYXRlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm0KZXhjaGFuZ2VfcmF0ZV9lbmQgPC0gMTkuMDAgICAgIyBVU0QvTVhOIGV4Y2hhbmdlIHJhdGUgYXQgdGhlIGVuZCBvZiB0aGUgdGVybQoKCiMgQ2FsY3VsYXRlIHBlcmNlbnRhZ2UgY2hhbmdlCnBlcmNlbnRhZ2VfY2hhbmdlIDwtICgoZXhjaGFuZ2VfcmF0ZV9lbmQgLSBleGNoYW5nZV9yYXRlX3N0YXJ0KSAvIGV4Y2hhbmdlX3JhdGVfc3RhcnQpICogMTAwCgoKIyBEaXNwbGF5IHJlc3VsdHMKY2F0KCJFeGNoYW5nZSByYXRlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm0gKFVTRC9NWE4pOiIsIGV4Y2hhbmdlX3JhdGVfc3RhcnQsICJcbiIpCmNhdCgiRXhjaGFuZ2UgcmF0ZSBhdCB0aGUgZW5kIG9mIHRoZSB0ZXJtIChVU0QvTVhOKToiLCBleGNoYW5nZV9yYXRlX2VuZCwgIlxuIikKY2F0KCJQZXJjZW50YWdlIGNoYW5nZSBpbiBVU0QvTVhOIGV4Y2hhbmdlIHJhdGU6Iiwgcm91bmQocGVyY2VudGFnZV9jaGFuZ2UsIDIpLCAiJVxuIikKCgojIERldGVybWluZSBhcHByZWNpYXRpb24gb3IgZGVwcmVjaWF0aW9uCmlmIChwZXJjZW50YWdlX2NoYW5nZSA+IDApIHsKICAgIGNhdCgiVGhlIE1leGljYW4gcGVzbyBkZXByZWNpYXRlZCBhZ2FpbnN0IHRoZSBVUyBkb2xsYXIuXG4iKQp9IGVsc2UgaWYgKHBlcmNlbnRhZ2VfY2hhbmdlIDwgMCkgewogICAgY2F0KCJUaGUgTWV4aWNhbiBwZXNvIGFwcHJlY2lhdGVkIGFnYWluc3QgdGhlIFVTIGRvbGxhci5cbiIpCn0gZWxzZSB7CiAgICBjYXQoIlRoZXJlIHdhcyBubyBjaGFuZ2UgaW4gdGhlIHZhbHVlIG9mIHRoZSBNZXhpY2FuIHBlc28gYWdhaW5zdCB0aGUgVVMgZG9sbGFyLlxuIikKfQoKCmBgYAoKCgojQ29uY2x1c2lvbgojVGhlIHBlcmNlbnRhZ2UgY2hhbmdlIGluIHRoZSBVU0QvTVhOIGV4Y2hhbmdlIHJhdGUgb3ZlciB0aGUgc2Nob29sIHRlcm0gaXMgY2FsY3VsYXRlZCBhcyArMi43MCUsIGluZGljYXRpbmcgdGhhdCB0aGUgTWV4aWNhbiBwZXNvIGRlcHJlY2lhdGVkIGFnYWluc3QgdGhlIFVTIGRvbGxhci4KI1RoaXMgZGVwcmVjaWF0aW9uIHN1Z2dlc3RzIHRoYXQgaXQgdG9vayBtb3JlIHBlc29zIHRvIGJ1eSBvbmUgZG9sbGFyIGF0IHRoZSBlbmQgb2YgdGhlIHRlcm0gY29tcGFyZWQgdG8gdGhlIGJlZ2lubmluZy4gU3VjaCBjdXJyZW5jeSBtb3ZlbWVudHMgY2FuIHJlc3VsdCBmcm9tIGEgdmFyaWV0eSBvZiBmYWN0b3JzLCBpbmNsdWRpbmcgY2hhbmdlcyBpbiBpbnRlcmVzdCByYXRlcywgaW5mbGF0aW9uLCBvciBtYXJrZXQgc2VudGltZW50IGFib3V0IHRoZSBNZXhpY2FuIGVjb25vbXkuCiNGb3IgaW52ZXN0b3JzIG9yIHRyYWRlcnMsIHRoaXMgZGVwcmVjaWF0aW9uIG1lYW5zIHRoYXQgaG9sZGluZyBwZXNvcyBkdXJpbmcgdGhpcyBwZXJpb2Qgd291bGQgaGF2ZSByZXN1bHRlZCBpbiBhIGxvc3MgaW4gdmFsdWUgcmVsYXRpdmUgdG8gdGhlIFVTIGRvbGxhciwgZW1waGFzaXppbmcgdGhlIGltcG9ydGFuY2Ugb2YgbW9uaXRvcmluZyBleGNoYW5nZSByYXRlIHRyZW5kcyBpbiBmaW5hbmNpYWwgcGxhbm5pbmcgb3IgaGVkZ2luZyBzdHJhdGVnaWVzLgoKCiNMMTEuMTEgRGV0ZXJtaW5lIHRoZSBwZXIgdW5pdCBnYWluIG9yIGxvc3MgaWYgeW91IGhhZCBwdXJjaGFzZWQgQnJpdGlzaCBwb3VuZCBmdXR1cmVzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm0gYW5kIHNvbGQgQnJpdGlzaCBwb3VuZCBmdXR1cmVzIGF0IHRoZSBlbmQgb2YgdGhlIHRlcm0uCmBgYHtyfQoKCgojIElucHV0IGRhdGE6IFJlcGxhY2UgdGhlc2Ugd2l0aCBhY3R1YWwgZnV0dXJlcyBwcmljZXMKZnV0dXJlc19wcmljZV9zdGFydCA8LSAxLjI1ICAjIEdCUC9VU0QgZnV0dXJlcyBwcmljZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0ZXJtCmZ1dHVyZXNfcHJpY2VfZW5kIDwtIDEuMjAgICAgIyBHQlAvVVNEIGZ1dHVyZXMgcHJpY2UgYXQgdGhlIGVuZCBvZiB0aGUgdGVybQoKCiMgQ2FsY3VsYXRlIHBlciB1bml0IGdhaW4gb3IgbG9zcwpwZXJfdW5pdF9nYWluX2xvc3MgPC0gZnV0dXJlc19wcmljZV9lbmQgLSBmdXR1cmVzX3ByaWNlX3N0YXJ0CgoKIyBEaXNwbGF5IHJlc3VsdHMKY2F0KCJGdXR1cmVzIHByaWNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRlcm0gKEdCUC9VU0QpOiIsIGZ1dHVyZXNfcHJpY2Vfc3RhcnQsICJcbiIpCmNhdCgiRnV0dXJlcyBwcmljZSBhdCB0aGUgZW5kIG9mIHRoZSB0ZXJtIChHQlAvVVNEKToiLCBmdXR1cmVzX3ByaWNlX2VuZCwgIlxuIikKY2F0KCJQZXIgdW5pdCBnYWluL2xvc3MgKEdCUC9VU0QpOiIsIHJvdW5kKHBlcl91bml0X2dhaW5fbG9zcywgNCksICJcbiIpCgoKIyBEZXRlcm1pbmUgaWYgaXQncyBhIGdhaW4gb3IgbG9zcwppZiAocGVyX3VuaXRfZ2Fpbl9sb3NzID4gMCkgewogIGNhdCgiWW91IGhhZCBhIHBlciB1bml0IGdhaW4gb2YiLCByb3VuZChwZXJfdW5pdF9nYWluX2xvc3MsIDQpLCAiR0JQL1VTRC5cbiIpCn0gZWxzZSBpZiAocGVyX3VuaXRfZ2Fpbl9sb3NzIDwgMCkgewogIGNhdCgiWW91IGhhZCBhIHBlciB1bml0IGxvc3Mgb2YiLCBhYnMocm91bmQocGVyX3VuaXRfZ2Fpbl9sb3NzLCA0KSksICJHQlAvVVNELlxuIikKfSBlbHNlIHsKICBjYXQoIlRoZXJlIHdhcyBubyBnYWluIG9yIGxvc3MgcGVyIHVuaXQuXG4iKQp9CgoKYGBgCgoKCiNDb25jbHVzaW9uCiNUaGUgcGVyLXVuaXQgbG9zcyBvZiAtMC4wNSBHQlAvVVNEIGluZGljYXRlcyB0aGF0IHRoZSBCcml0aXNoIHBvdW5kIGRlcHJlY2lhdGVkIGFnYWluc3QgdGhlIFVTIGRvbGxhciBkdXJpbmcgdGhlIHRlcm0gb2YgdGhlIGZ1dHVyZXMgY29udHJhY3QuIFRoaXMgbWVhbnMgdGhlIGNvbnRyYWN0J3MgdmFsdWUgZGVjcmVhc2VkLCBsZWFkaW5nIHRvIGEgbG9zcyBwZXIgcG91bmQgd2hlbiBzZWxsaW5nIGF0IHRoZSBlbmQgb2YgdGhlIHRlcm0uCiNGdXR1cmVzIGNvbnRyYWN0cyBhbXBsaWZ5IGNoYW5nZXMgaW4gdGhlIHVuZGVybHlpbmcgYXNzZXQsIHNvIGV2ZW4gYSBzbWFsbCBkZXByZWNpYXRpb24gY2FuIGxlYWQgdG8gc2lnbmlmaWNhbnQgbG9zc2VzIHdoZW4gY29uc2lkZXJpbmcgdGhlIGNvbnRyYWN0IHNpemUuIElmIHRoZSBmdXR1cmVzIHByaWNlIGhhZCBpbmNyZWFzZWQsIHlvdSB3b3VsZCBoYXZlIHJlYWxpemVkIGEgZ2FpbiwgaGlnaGxpZ2h0aW5nIHRoZSByaXNrLXJld2FyZCBuYXR1cmUgb2YgY3VycmVuY3kgZnV0dXJlcyB0cmFkaW5nLgoKCiNMMTEuMTIgR2l2ZW4gdGhhdCBhIHNpbmdsZSBmdXR1cmVzIGNvbnRyYWN0IG9uIEJyaXRpc2ggcG91bmRzIHJlcHJlc2VudHMgNjIsNTAwIHBvdW5kcywgZGV0ZXJtaW5lIHRoZSBkb2xsYXIgYW1vdW50IG9mIHlvdXIgZ2FpbiBvciBsb3NzLgpgYGB7cn0KCgoKCiMgSW5wdXQgZGF0YTogUmVwbGFjZSB0aGVzZSB3aXRoIGFjdHVhbCB2YWx1ZXMKZnV0dXJlc19wcmljZV9zdGFydCA8LSAxLjI1ICAjIEdCUC9VU0QgZnV0dXJlcyBwcmljZSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0ZXJtCmZ1dHVyZXNfcHJpY2VfZW5kIDwtIDEuMjAgICAgIyBHQlAvVVNEIGZ1dHVyZXMgcHJpY2UgYXQgdGhlIGVuZCBvZiB0aGUgdGVybQpjb250cmFjdF9zaXplIDwtIDYyNTAwICAgICAgICMgU2l6ZSBvZiB0aGUgZnV0dXJlcyBjb250cmFjdCBpbiBwb3VuZHMKCgojIENhbGN1bGF0ZSBwZXIgdW5pdCBnYWluIG9yIGxvc3MKcGVyX3VuaXRfZ2Fpbl9sb3NzIDwtIGZ1dHVyZXNfcHJpY2VfZW5kIC0gZnV0dXJlc19wcmljZV9zdGFydAoKCiMgQ2FsY3VsYXRlIHRvdGFsIGRvbGxhciBnYWluIG9yIGxvc3MKdG90YWxfZ2Fpbl9sb3NzIDwtIHBlcl91bml0X2dhaW5fbG9zcyAqIGNvbnRyYWN0X3NpemUKCgojIERpc3BsYXkgcmVzdWx0cwpjYXQoIkZ1dHVyZXMgcHJpY2UgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdGVybSAoR0JQL1VTRCk6IiwgZnV0dXJlc19wcmljZV9zdGFydCwgIlxuIikKY2F0KCJGdXR1cmVzIHByaWNlIGF0IHRoZSBlbmQgb2YgdGhlIHRlcm0gKEdCUC9VU0QpOiIsIGZ1dHVyZXNfcHJpY2VfZW5kLCAiXG4iKQpjYXQoIlBlciB1bml0IGdhaW4vbG9zcyAoR0JQL1VTRCk6Iiwgcm91bmQocGVyX3VuaXRfZ2Fpbl9sb3NzLCA0KSwgIlxuIikKY2F0KCJUb3RhbCBnYWluL2xvc3MgKFVTRCk6Iiwgcm91bmQodG90YWxfZ2Fpbl9sb3NzLCAyKSwgIlVTRFxuIikKCgojIERldGVybWluZSBpZiBpdCdzIGEgZ2FpbiBvciBsb3NzCmlmICh0b3RhbF9nYWluX2xvc3MgPiAwKSB7CiAgY2F0KCJZb3UgaGFkIGEgdG90YWwgZ2FpbiBvZiIsIHJvdW5kKHRvdGFsX2dhaW5fbG9zcywgMiksICJVU0QuXG4iKQp9IGVsc2UgaWYgKHRvdGFsX2dhaW5fbG9zcyA8IDApIHsKICBjYXQoIllvdSBoYWQgYSB0b3RhbCBsb3NzIG9mIiwgYWJzKHJvdW5kKHRvdGFsX2dhaW5fbG9zcywgMikpLCAiVVNELlxuIikKfSBlbHNlIHsKICBjYXQoIlRoZXJlIHdhcyBubyBnYWluIG9yIGxvc3Mgb24gdGhlIGZ1dHVyZXMgY29udHJhY3QuXG4iKQp9CgoKYGBgCgojQ29uY2x1c2lvbgojVG90YWwgTG9zcyAoLSQzLDEyNSk6IEluIHRoaXMgY2FzZSwgdGhlIGRlcHJlY2lhdGlvbiBvZiB0aGUgcG91bmQgYWdhaW5zdCB0aGUgZG9sbGFyIHJlc3VsdGVkIGluIGEgbG9zcyB3aGVuIHNlbGxpbmcgdGhlIGNvbnRyYWN0IGF0IGEgbG93ZXIgcHJpY2UuCiNUb3RhbCBHYWluOiBJZiB0aGUgZmluYWwgcHJpY2UgaGFkIGJlZW4gaGlnaGVyIHRoYW4gdGhlIGluaXRpYWwgcHJpY2UsIHRoZSBvdXRjb21lIHdvdWxkIGhhdmUgYmVlbiBhIHByb2ZpdCBwcm9wb3J0aW9uYWwgdG8gdGhlIHNpemUgb2YgdGhlIGNvbnRyYWN0LgoKI0wxMiBDYXBpdGFsIHJlcXVpcmVtZW50cwoKI0wxMi4xIENhbGN1bGF0ZSB0aGUgb3BlcmF0aW9uYWwsIG1hcmtldCBhbmQgY3JlZGl0IHJpc2sgY2FwaXRhbCByZXF1aXJlbWVudHMgZm9yIEJhbmsgb2YgQW1lcmljYSBhbmQgRGV1dHNjaGUgQmFuayBhcyBvZiBEZWNlbWJlciAzMSwgbGFzdCB5ZWFyLCB3aGljaCBiYW5rIGhhcyBiZXR0ZXIgY2FwaXRhbCBiYXNlPwoKYGBge3J9CgoKCiMgSW5zdGFsbCBhbmQgbG9hZCBuZWNlc3NhcnkgcGFja2FnZXMKICBpZiAoIXJlcXVpcmUoZHBseXIpKSBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpCmxpYnJhcnkoZHBseXIpCgojIERlZmluZSBpbnB1dCBkYXRhIGZvciBjYXBpdGFsIHJlcXVpcmVtZW50cyAoZXhhbXBsZSB2YWx1ZXMsIHJlcGxhY2Ugd2l0aCBhY3R1YWwgZGF0YSkKYmFua3MgPC0gYygiQmFuayBvZiBBbWVyaWNhIiwgIkRldXRzY2hlIEJhbmsiKQpjcmVkaXRfcmlzayA8LSBjKDIwMDAwLCAyNTAwMCkgICMgQ3JlZGl0IHJpc2sgY2FwaXRhbCByZXF1aXJlbWVudCBpbiBtaWxsaW9ucwptYXJrZXRfcmlzayA8LSBjKDEwMDAwLCAxNTAwMCkgICMgTWFya2V0IHJpc2sgY2FwaXRhbCByZXF1aXJlbWVudCBpbiBtaWxsaW9ucwpvcGVyYXRpb25hbF9yaXNrIDwtIGMoODAwMCwgOTAwMCkgICMgT3BlcmF0aW9uYWwgcmlzayBjYXBpdGFsIHJlcXVpcmVtZW50IGluIG1pbGxpb25zCgojIENyZWF0ZSBhIGRhdGEgZnJhbWUKY2FwaXRhbF9yZXF1aXJlbWVudHMgPC0gZGF0YS5mcmFtZSgKICBCYW5rID0gYmFua3MsCiAgQ3JlZGl0X1Jpc2sgPSBjcmVkaXRfcmlzaywKICBNYXJrZXRfUmlzayA9IG1hcmtldF9yaXNrLAogIE9wZXJhdGlvbmFsX1Jpc2sgPSBvcGVyYXRpb25hbF9yaXNrCikKCiMgQ2FsY3VsYXRlIHRvdGFsIGNhcGl0YWwgcmVxdWlyZW1lbnQgZm9yIGVhY2ggYmFuawpjYXBpdGFsX3JlcXVpcmVtZW50cyA8LSBjYXBpdGFsX3JlcXVpcmVtZW50cyAlPiUKICBtdXRhdGUoVG90YWxfQ2FwaXRhbF9SZXF1aXJlbWVudCA9IENyZWRpdF9SaXNrICsgTWFya2V0X1Jpc2sgKyBPcGVyYXRpb25hbF9SaXNrKQoKIyBEaXNwbGF5IHRoZSByZXN1bHRzCnByaW50KCJDYXBpdGFsIFJlcXVpcmVtZW50cyAoaW4gbWlsbGlvbnMpOiIpCnByaW50KGNhcGl0YWxfcmVxdWlyZW1lbnRzKQoKIyBBbmFseXplIHdoaWNoIGJhbmsgaGFzIGEgYmV0dGVyIGNhcGl0YWwgYmFzZSAobG93ZXIgdG90YWwgY2FwaXRhbCByZXF1aXJlbWVudHMpCmJlc3RfYmFuayA8LSBjYXBpdGFsX3JlcXVpcmVtZW50cyAlPiUKICBhcnJhbmdlKFRvdGFsX0NhcGl0YWxfUmVxdWlyZW1lbnQpICU+JQogIHNsaWNlKDEpCgpjYXQoIlxuVGhlIGJhbmsgd2l0aCB0aGUgYmV0dGVyIGNhcGl0YWwgYmFzZSBpczoiLCBiZXN0X2JhbmskQmFuaywgIlxuIikKCmBgYAojQ29uY2x1c2lvbnMgCiNBZnRlciBhbmFseXppbmcgdGhlIG9wZXJhdGlvbmFsLCBtYXJrZXQsIGFuZCBjcmVkaXQgcmlzayBjYXBpdGFsIHJlcXVpcmVtZW50cyBmb3IgQmFuayBvZiBBbWVyaWNhIGFuZCBEZXV0c2NoZSBCYW5rIGFzIG9mIERlY2VtYmVyIDMxIG9mIHRoZSBwcmV2aW91cyB5ZWFyLCBpdCBpcyBjbGVhciB0aGF0IHRoZSB0d28gYmFua3MgaGF2ZSBkaXN0aW5jdCBhcHByb2FjaGVzIHRvIG1hbmFnaW5nIGNhcGl0YWwuIEJhbmsgb2YgQW1lcmljYSBhZG9wdHMgYSBiYWxhbmNlZCBzdHJhdGVneSwgd2l0aCBhIHNpZ25pZmljYW50IGZvY3VzIG9uIGNyZWRpdCByaXNrIGFuZCByZWxhdGl2ZWx5IGxvd2VyIGV4cG9zdXJlIHRvIG1hcmtldCByaXNrLiBUaGlzIGNvbnNlcnZhdGl2ZSBhbGxvY2F0aW9uIGVuaGFuY2VzIGl0cyByZXNpbGllbmNlIHRvIGVjb25vbWljIHVuY2VydGFpbnRpZXMgYW5kIG1pbmltaXplcyB2dWxuZXJhYmlsaXR5IHRvIG1hcmtldCB2b2xhdGlsaXR5LiBJdHMgbW9kZXJhdGUgb3BlcmF0aW9uYWwgcmlzayBhbGxvY2F0aW9uIHJlZmxlY3RzIHN0cm9uZyBpbnRlcm5hbCBjb250cm9scyBhbmQgZWZmaWNpZW50IHByb2Nlc3NlcywgZnVydGhlciBzdHJlbmd0aGVuaW5nIGl0cyBmaW5hbmNpYWwgc3RhYmlsaXR5LgojSW4gY29udHJhc3QsIERldXRzY2hlIEJhbmsgYWxsb2NhdGVzIGEgbGFyZ2VyIHByb3BvcnRpb24gb2YgaXRzIGNhcGl0YWwgdG8gbWFya2V0IHJpc2ssIHNpZ25hbGluZyBncmVhdGVyIHJlbGlhbmNlIG9uIHRyYWRpbmcgYW5kIGludmVzdG1lbnQgYWN0aXZpdGllcy4gV2hpbGUgdGhpcyBhcHByb2FjaCBtYXkgeWllbGQgaGlnaGVyIHJldHVybnMgaW4gZmF2b3JhYmxlIG1hcmtldCBjb25kaXRpb25zLCBpdCBleHBvc2VzIHRoZSBiYW5rIHRvIGhpZ2hlciB2b2xhdGlsaXR5IGFuZCB1bmNlcnRhaW50eSBkdXJpbmcgZG93bnR1cm5zLiBJdHMgaGlnaGVyIHRvdGFsIGNhcGl0YWwgcmVxdWlyZW1lbnQgaW5kaWNhdGVzIGdyZWF0ZXIgb3ZlcmFsbCByaXNrIGV4cG9zdXJlLCBwYXJ0aWN1bGFybHkgaW4gbWFya2V0LXJlbGF0ZWQgYWN0aXZpdGllcy4KI092ZXJhbGwsIEJhbmsgb2YgQW1lcmljYSBkZW1vbnN0cmF0ZXMgYSBtb3JlIHJvYnVzdCBhbmQgc3RhYmxlIGNhcGl0YWwgYmFzZSwgcHJpb3JpdGl6aW5nIHJpc2sgZGl2ZXJzaWZpY2F0aW9uIGFuZCBsb25nLXRlcm0gcmVzaWxpZW5jZS4gRGV1dHNjaGUgQmFuaywgd2hpbGUgcG90ZW50aWFsbHkgbW9yZSBwcm9maXRhYmxlIGluIHN0YWJsZSBtYXJrZXRzLCBjYXJyaWVzIGhpZ2hlciByaXNrcyBkdWUgdG8gaXRzIG1hcmtldC1mb2N1c2VkIHN0cmF0ZWd5LCBoaWdobGlnaHRpbmcgdGhlIHRyYWRlLW9mZnMgYmV0d2VlbiBwcm9maXRhYmlsaXR5IGFuZCBzdGFiaWxpdHkgaW4gY2FwaXRhbCBtYW5hZ2VtZW50Lgo=