Core Functions in tidyquant - The Comprehensive R Archive Network followed by a non-number. using the quantmod function to.weekly A customized function called yf_convert_to_wide() can transform the long dataframe into a wide format (tickers as columns), much used in portfolio optimization. xts is a extensible time series package for time series data. Try These 2 Packages, Python List Print 7 Different Ways to Print a List You Must Know, How to get the most and least Volatile Cryptocurrencies, How to Get Cryptocurrency Data from Kraken API in Python, Click here to close (This popup will not appear again). > # in later model fitting. mutate(freq = 'yearly') img#wpstats{display:none} A third average called signal line; a 9 day exponential moving average of MACD signal, is also computed. Your data may not have an observation exactly at the market open and/or close. and a look at what's coming in mutate(freq = factor(freq, To learn more, see our tips on writing great answers. This returns stock price data from Yahoo Finance. I did an extensive amount of research a while ago on this and unfortunately didn't get anywhere. Remember that getSymbols() specifies the data source using the src argument and that Quandl() specifies it as part of the Quandl code (i.e.database/series). Recall endpoints() returns locations of the last observation in each period specified by the on argument. getSymbols.yahoo() always throws "Error in new.session()" #358 - GitHub tq_get function - RDocumentation getSymbols() will error if the data is not available for download. l_wide " /> An earlier exercise taught you how to use setSymbolLookup() to set a default data source for getSymbols(). You will use the same split-lapply-rbind paradigm from the Introduction to xts and zoo course. Spline interpolation is more appropriate for series without a strong trend, because it calculates a non-linear approximation using multiple data points. To subscribe to this RSS feed, copy and paste this URL into your RSS reader. Ask Question Asked 9 years, 11 months ago Modified 3 years, 8 months ago Viewed 2k times Part of R Language Collective 6 ## (3/3) Fetching data for ', Thanks for contributing an answer to Stack Overflow! ## - got 100% of valid prices -- Good job msperlin! Here we stick to the standard parameters. You will still use read.csv() find the column names of the date and time columns. We use cookies (necessary for website functioning) for analytics, to give you the its, zoo, xts, or timeSeries. For example, the argument for the first date of data importation in yfR::yf_get() is first_date, and not first.date as used in BatchGetSymbols::BatchGetSymbols. Value Syntactically valid names contain letters, numbers, ., and "_, and must start with a letter or a." Both getSymbols() and Quandl() provide access to the FRED database. It provides a rapid prototyping environment that makes modeling easier by removing the repetitive workflow issues surrounding data management and visualization. Meant to be called internally by getSymbols (see also). Modelling & Trading Framework for, > getSymbols("YHOO",src="google") # from google finance. + VXN=list(name='^VIX',src='yahoo')) The quantmod package provides functions to extract a single column, and also has functions to extract specific sets of columns. In this case, well-formatted means the file contains data for a single instrument with date, open, high, low, close, volume, and adjusted close columns, in that order. MACD is the function in quantmod that calculates the moving average convergence divergence, data is the closing price for NSE, nFast is the fast moving average, nSlow is the slow moving average, maType =SMA indicates we have chosen simple moving average, percent =FALSE implies we are calculating the difference between fast moving average and slow moving average. At present this is a nice tool to If Exp is missing, only the front month contract will be returned. A new feature called collection, which allows for easy download of a collection of tickers. Any Idea? For example, getSymbols(CP, src = yahoo) would load Canadian Pacific Railway data from the New York Stock Exchange. Is it appropriate to try to contact the referee of a paper after it has been accepted and published? Works..Thank you for your help, @Michael Kirchner. 'yearly'))) # make sure the order in plot is right These data sets often need to be aggregated before you can work with them. This exercise provides an example. > candleChart(AAPL,multi.col=TRUE,theme="white") For example, a 2-for-1 split would double the shares outstanding, and reduce the stock price by 1/2. a data object with all the columns prespecified, OR to use objects visible The london objects timezone is Europe/London and the chicago objects timezone is America/Chicago. You will use the split argument to import the data into an object that has both bid and ask prices for both instruments on one row. ts (time-series objects from the stats package). As an alternative somebody point to this script that could help you. You will often need to aggregate to a lower frequency to align multiple time series. This exercise will use to.period() to aggregate intraday data to an OHLC series. The difference between the fast moving average and the slow moving average is called MACD line. A replacement for anything statistical. You will use it to import QQQ data from Yahoo! Recall that xts objects store the time index as seconds since midnight, 1970-01-01 in the UTC timezone. setSymbolLookup merge() uses this underlying index and returns a result with the first objects timezone. How to extract all the ticker symbols of an exchange with Quantmod in R? of my visitors seem to appear), I will continue. You will learn more about the adjustment process in the next video. costly, data errors in trading can quickly lead to a new career. Remember, you are not supposed to call getSymbols.yahoo() directly! Description. Having the flexibility to return different data types is a great bonus and less work for you! specifyModel is the workhorse function a variety of sources, including Now that we have some data we may want to look at it. The Quandl() function allows you to specify common aggregations and transformations via the collapse and/or transform arguments. We will choose MACD (Moving Average Convergence Divergence) for this example. Yahoo Finance cover a large number of markets and assets, being used extensively for importing price datasets used in academic research and teaching. 3,167.75 -1.78 (-0.06%) At close: 03:00PM CST Stock chart is not supported by your current browser Yahoo Finance UK FTSE and Wall Street rise as UK government borrowing falls but debt still. You can use setSymbolLookup() to specify the default data source for an instrument. How about some examples of quantmod's data handling, This software is written and maintained by, Quantitative Financial Once again, you can use read.zoo(). You can supply your own end points to period.apply() (versus using endpoints()). The performance analytics package in R provides a consolidated platform to observe performance related parameters. Recently, Yahoo Finance - a popular source of free end-of-day price data - made some changes to their server which wreaked a little havoc on anyone relying on it for their algos or simulations. Is saying "dot com" a valid clue for Codenames? QQQ is an exchange-traded fund that tracks the Nasdaq 100 index, and Yahoo! along with the appropriate data object to search. So, you must adjust all pre-split prices in order to calculate historical returns correctly. document.documentElement.classList.add( - Stack Overflow How to get the list of all Yahoo Finance mutual funds in R? This time you will be using its split argument, which allows you to specify the name or number of the columns(s) that contain the variables that identify unique observations. This method is For example, collection SP500 represents the current composition of the SP500 index. ## - found cache file (2010-01-04 --> 2022-03-30) Maybe it's not possible within Quantmod, but perhaps another way of doing it? levels = c('daily', Enter the Are there any practical use cases for subtyping primitive types? This method is not to be called directly, instead a call to getSymbols(Symbols,src='yahooj') will in turn call this method. A call to getSymbols.yahoo will load into the specified ## Running yfR for 1 stocks | 2010-01-01 --> 2022-03-31 (4472 days) Most markets are usually closed at least part of the day. most appropriate way. In the past I have used function GetSymbols from the CRAN package quantmod in order to download end of day trade data for several stocks in the financial market. It can also extract columns for a specific instrument by using the symbol argument, which is useful when an object contains several instruments with the same price type. Setting a default source can be useful if you use that source often. Can consciousness simply be a brute fact connected to some physical processes that dont need explanation? If you steal opponent's Ring-bearer until end of turn, does it stop being Ring-bearer even at end of turn? within the user's environment. Much, Lets's take a look at an example of specifyModel: Stock splits can create large historical price changes even though they do not change the value of the company. as data handling is inherently error-prone. [1] "AAPL" Note there is So the close prices from the new data wont align closely with the adjusted close prices from the previous exercise (which are adjusted for both splits and dividends). 'jetpack-lazy-images-js-enabled' As of quantmod 0.4-9, getSymbols.yahoo has been patched to work with changes to Yahoo Finance, which also included the following changes to the raw data: The adjusted close column appears to no longer include dividend adjustments The close column appears to be adjusted for splits twice Description Retrieve current conversion rate between two currencies as well as historical rates. As of quantmod 0.4-9, getSymbols.yahoo has been patched to work with changes to Yahoo Finance, which also included the following changes to the raw data: The adjusted close column appears to no longer include dividend adjustments The close column appears to be adjusted for splits twice In this exercise, you will learn a general aggregation technique to aggregate daily data to weekly, but with weeks ending on Wednesdays. */ Automated Stock Trading with R - Towards Data Science You can also use setSymbolLookup() to create a mapping between the instrument symbol and the name of the R object. The xts class extends zoo, so you can easily convert the result of read.zoo() into an xts object by using as.xts(). Dividends do reduce the companys value by the amount of the dividend payment, but the investors return isnt affected because they receive the offsetting dividend payment. yfR is the second and backwards-incompatible version of BatchGetSymbols. fucntion of the current period open to close and the current close The Yahoo Finance symbol for the SSE Composite Index is 000001.SS. You can also use the getSymbolLookup() function to check per-symbol defaults before you try to load data using getSymbols(). Available as part of the Tidelift Subscription. Share Follow answered Mar 17, 2021 at 11:54 H.L. Its important to check your imported data is reasonable. Then you will use the series name to download the data directly from FRED using getSymbols(), and from the Quandl database using Quandl(). returns = ROC (data)*signal. A car dealership sent a 8300 form after I paid $10k in cash for a car. Intraday data can be huge, with hundreds of thousands of observations per day, millions per month, and hundreds of millions per year. Now you will create regular intra-day data from an irregular series. timeSeries (from the timeSeries package in the RMetrics suite). Am I in trouble. > getSymbols("AAPL",src="yahoo") I've found the end of day data from tiingo to be higher quality and the endpoint is more stable than Yahoo Finance. Does glide ratio improve with increase in scale? Downloads Symbols to specified env from 'finance.yahoo.co.jp'. The trading signal is applied to the closing price to obtain the returns of our strategy. In addition to this, you can check our blog for articles on different quantitative trading strategies. and data structure implying the next (Next) period's open to close new function chartSeries. Today Im releasing the first version of yfR (not yeat in CRAN). You use the Symbols argument to specify the instrument (i.e.the ticker symbol) you want to import. The command below creates chart for the NSE data. This exercise will teach you how to save and load symbol-based defaults by using saveSymbolLookup() and loadSymbolLookup(), respectively. We use the lag operator to eliminate look ahead bias. > You often need to specify both period and k arguments to aggregate intraday data. The call to modelData extracts the relevant data set, with transforms magically This exercise will show you how to fill missing values by trading day, without using the prior days final value. Also like lapply(), eapply() returns a list. simple wrapper to the underlying Yahoo! [1] "XPTUSD" Their website has documentation for it all! quantmod Share Follow edited Feb 27, 2021 at 0:53 asked Feb 26, 2021 at 18:02 user1357015 11.1k 22 66 109 Add a comment 1 Answer Sorted by: 0 Sadly quantmod can no longer access google's market information as per this issue. For example, you can download price data for all components of the SP500 by simply calling yfR::yf_collection_get("SP500"). The trading signal is applied to the closing price to obtain the returns of our strategy. 1 Answer Sorted by: 0 A fast way of doing this is using tidyquant. The getSymbols() function from the quantmod package provides a consistent interface to import data from various sources into your workspace. The data have already been loaded to your workspace in aapl_raw and aapl_split_adjusted, respectively. Occasionally this happens, and it is useful to set a single symbol to be pulled from a specific source. At its worst it can be dangerous The ROC function provides the percentage difference between the two closing prices. In this exercise, you will use the index.column argument to specify the date and time columns of the file. This in a major upgrade on BatchGetSymbols, with many backwards-incompatible changes. Presently this may be ts, Until that fix is released on CRAN, you can try installing the development version. To calculate the dividend ratio, you need to provide raw dividends and raw prices via the dividends and close arguments, respectively. quantmod (version 0.4.18) getSymbols.yahoo: Download OHLC Data From Yahoo Finance to specified from 'finance.yahoo.com'. aapl_prices <-tq_get ("AAPL", get = "stock.prices", from =" 1990-01-01") . LS0tCnRpdGxlOiAiSW1wb3J0aW5nIGFuZCBNYW5hZ2luZyBGaW5hbmNpYWwgRGF0YSBpbiBSIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfY29sbGFwc2VkOiBmYWxzZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICAKdG9jX2RlcHRoOiAzCi0tLQoKIyBJbnRyb2R1Y3Rpb24gYW5kIGRvd25sb2FkaW5nIGRhdGEKCiMjIEludHJvZHVjdGlvbiBhbmQgZG93bmxvYWRpbmcgZGF0YQoKIyMjIEludHJvZHVjaW5nIGdldFN5bWJvbHMoKQoKVGhlIGdldFN5bWJvbHMoKSBmdW5jdGlvbiBmcm9tIHRoZSBxdWFudG1vZCBwYWNrYWdlIHByb3ZpZGVzIGEgY29uc2lzdGVudCBpbnRlcmZhY2UgdG8gaW1wb3J0IGRhdGEgZnJvbSB2YXJpb3VzIHNvdXJjZXMgaW50byB5b3VyIHdvcmtzcGFjZS4gQnkgZGVmYXVsdCwgZ2V0U3ltYm9scygpIGltcG9ydHMgdGhlIGRhdGEgYXMgYSB4dHMgb2JqZWN0LgoKVGhpcyBleGVyY2lzZSB3aWxsIGludHJvZHVjZSB5b3UgdG8gZ2V0U3ltYm9scygpLiBZb3Ugd2lsbCB1c2UgaXQgdG8gaW1wb3J0IFFRUSBkYXRhIGZyb20gWWFob28hIEZpbmFuY2UuIFFRUSBpcyBhbiBleGNoYW5nZS10cmFkZWQgZnVuZCB0aGF0IHRyYWNrcyB0aGUgTmFzZGFxIDEwMCBpbmRleCwgYW5kIFlhaG9vISBGaW5hbmNlIGlzIHRoZSBkZWZhdWx0IGRhdGEgc291cmNlIGZvciBnZXRTeW1ib2xzKCkuCgpZb3UgdXNlIHRoZSBTeW1ib2xzIGFyZ3VtZW50IHRvIHNwZWNpZnkgdGhlIGluc3RydW1lbnQgKGkuZS4gdGhlIHRpY2tlciBzeW1ib2wpIHlvdSB3YW50IHRvIGltcG9ydC4gU2luY2UgU3ltYm9scyBpcyB0aGUgZmlyc3QgYXJndW1lbnQgdG8gZ2V0U3ltYm9scygpLCB5b3UgdXN1YWxseSBqdXN0IHR5cGUgdGhlIGluc3RydW1lbnQgbmFtZSBhbmQgb21pdCBTeW1ib2xzID0uCmBgYHtyfQojIExvYWQgdGhlIHF1YW50bW9kIHBhY2thZ2UKbGlicmFyeShxdWFudG1vZCkKCiMgSW1wb3J0IFFRUSBkYXRhIGZyb20gWWFob28hIEZpbmFuY2UKZ2V0U3ltYm9scyhTeW1ib2xzID0gIlFRUSIsIGF1dG8uYXNzaWduID0gVFJVRSkKCiMgTG9vayBhdCB0aGUgc3RydWN0dXJlIG9mIHRoZSBvYmplY3QgZ2V0U3ltYm9scyBjcmVhdGVkCnN0cihRUVEpCgojIExvb2sgYXQgdGhlIGZpcnN0IGZldyByb3dzIG9mIFFRUQpoZWFkKFFRUSkKYGBgCiMjIyBEYXRhIHNvdXJjZXMKCkluIHRoZSBsYXN0IGV4ZXJjaXNlLCB5b3UgaW1wb3J0ZWQgZGF0YSBmcm9tIFlhaG9vISBGaW5hbmNlLiBUaGUgc3JjIGFyZ3VtZW50IGFsbG93cyB5b3UgdG8gdGVsbCBnZXRTeW1ib2xzKCkgdG8gaW1wb3J0IGRhdGEgZnJvbSBhIGRpZmZlcmVudCBkYXRhIHNvdXJjZS4KCkluIHRoaXMgZXhlcmNpc2UsIHlvdSB3aWxsIGltcG9ydCBkYXRhIGZyb20gQWxwaGEgVmFudGFnZSBhbmQgRlJFRC4gQWxwaGEgVmFudGFnZSBpcyBhIHNvdXJjZSBzaW1pbGFyIHRvIFlhaG9vISBGaW5hbmNlLiBGUkVEIGlzIGFuIG9ubGluZSBkYXRhYmFzZSBvZiBlY29ub21pYyB0aW1lIHNlcmllcyBkYXRhIGNyZWF0ZWQgYW5kIG1haW50YWluZWQgYnkgdGhlIEZlZGVyYWwgUmVzZXJ2ZSBCYW5rIG9mIFN0LiBMb3Vpcy4KCmdldFN5bWJvbHMoKSBpbXBvcnRzIGRhdGEgZnJvbSBZYWhvbyEgRmluYW5jZSBieSBkZWZhdWx0IGJlY2F1c2Ugc3JjID0gInlhaG9vIiBieSBkZWZhdWx0LiBUaGUgc3JjIHZhbHVlcyBmb3IgQWxwaGEgVmFudGFnZSBhbmQgRlJFRCBhcmUgImF2IiBhbmQgIkZSRUQiLCByZXNwZWN0aXZlbHkuCmBgYHtyfQojIEltcG9ydCBRUVEgZGF0YSBmcm9tIEFscGhhIFZhbnRhZ2UKIyBnZXRTeW1ib2xzKFN5bWJvbHMgPSAiUVFRIiwgc3JjID0gImF2IikKIyBodHRwczovL3d3dy5hbHBoYXZhbnRhZ2UuY28vIHRvIGdldCBBUEkga2V5CiMgTG9vayBhdCB0aGUgc3RydWN0dXJlIG9mIFFRUQojIHN0cihRUVEpCgojIEltcG9ydCBHRFAgZGF0YSBmcm9tIEZSRUQKZ2V0U3ltYm9scyhTeW1ib2xzID0gIkdEUCIsIHNyYyA9ICJGUkVEIikKCiMgTG9vayBhdCB0aGUgc3RydWN0dXJlIG9mIEdEUApzdHIoR0RQKQpgYGAKIyMjIE1ha2UgZ2V0U3ltYm9scygpIHJldHVybiB0aGUgZGF0YSBpdCByZXRyaWV2ZXMKSW4gdGhlIGxhc3QgZXhlcmNpc2UsIGdldFN5bWJvbHMoKSBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQgYW4gb2JqZWN0IG5hbWVkIGxpa2UgdGhlIHN5bWJvbCB5b3UgcHJvdmlkZWQuIFRoaXMgZXhlcmNpc2Ugd2lsbCB0ZWFjaCB5b3UgdG8gbWFrZSBnZXRTeW1ib2xzKCkgcmV0dXJuIHRoZSBkYXRhLCBzbyB5b3UgY2FuIGFzc2lnbiB0aGUgb3V0cHV0IHlvdXJzZWxmLgoKVGhlcmUgYXJlIHR3byBhcmd1bWVudHMgdGhhdCB3aWxsIG1ha2UgZ2V0U3ltYm9scygpIHJldHVybiB0aGUgZGF0YToKCjEuIFNldCBhdXRvLmFzc2lnbiA9IEZBTFNFLgoyLiBTZXQgZW52ID0gTlVMTC4KClRoZSB0d28gbWV0aG9kcyBhcmUgZnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQsIGJ1dCBhdXRvLmFzc2lnbiA9IEZBTFNFIGRlc2NyaWJlcyB0aGUgYmVoYXZpb3IgYmV0dGVyLiBVc2UgaXQgYmVjYXVzZSB5b3Ugd2lsbCBiZSBtb3JlIGxpa2VseSB0byByZW1lbWJlciB3aGF0IGF1dG8uYXNzaWduID0gRkFMU0UgbWVhbnMgaW4gdGhlIGZ1dHVyZS4KYGBge3J9CiMgQXNzaWduIFNQWSBkYXRhIHRvICdzcHknIHVzaW5nIGF1dG8uYXNzaWduIGFyZ3VtZW50CnNweSA8LSBnZXRTeW1ib2xzKFN5bWJvbHMgPSAiU1BZIiwgYXV0by5hc3NpZ24gPSBGQUxTRSkKCiMgTG9vayBhdCB0aGUgc3RydWN0dXJlIG9mIHRoZSAnc3B5JyBvYmplY3QKc3RyKHNweSkKCiMgQXNzaWduIEpOSiBkYXRhIHRvICdqbmonIHVzaW5nIGVudiBhcmd1bWVudApqbmogPC0gZ2V0U3ltYm9scyhTeW1ib2xzID0gIkpOSiIsIGVudiA9IE5VTEwpCgojIExvb2sgYXQgdGhlIHN0cnVjdHVyZSBvZiB0aGUgJ2puaicgb2JqZWN0CnN0cihqbmopCmBgYApUdXJuaW5nIG9mZiBhdXRvLmFzc2lnbiBpcyB1c2VmdWwgaWYgeW91IHdhbnQgdG8gYXNzaWduIHRoZSBkYXRhIHRvIGFuIG9iamVjdCB5b3Vyc2VsZi4KCiMjIEludHJvZHVjdGlvbiB0byBRdWFuZGwKClNpbWlsYXIgdG8gaG93IHRoZSBxdWFudG1vZCBwYWNrYWdlIHByb3ZpZGVzIGdldFN5bWJvbHMoKSB0byBpbXBvcnQgZGF0YSBmcm9tIHZhcmlvdXMgc291cmNlcywgdGhlIFF1YW5kbCBwYWNrYWdlIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgUXVhbmRsIGRhdGFiYXNlcyB2aWEgb25lIHNpbXBsZSBmdW5jdGlvbjogUXVhbmRsKCkuCgpSZWNhbGwgdGhhdCBnZXRTeW1ib2xzKCkgdXNlcyB0aGUgU3ltYm9scyBhbmQgc3JjIGFyZ3VtZW50cyB0byBzcGVjaWZ5IHRoZSBpbnN0cnVtZW50IGFuZCBkYXRhIHNvdXJjZSwgcmVzcGVjdGl2ZWx5LiBUaGUgUXVhbmRsKCkgZnVuY3Rpb24gc3BlY2lmaWVzIGJvdGggdGhlIGRhdGEgc291cmNlIGFuZCB0aGUgaW5zdHJ1bWVudCB2aWEgaXRzIGNvZGUgYXJndW1lbnQsIGluIHRoZSBmb3JtICJEQVRBQkFTRS9EQVRBU0VUIi4KClR3byBvdGhlciB3YXlzIFF1YW5kbCgpIGRpZmZlcnMgZnJvbSBnZXRTeW1ib2xzKCkgYXJlOgoKMS4gUXVhbmRsKCkgcmV0dXJucyBhIGRhdGEuZnJhbWUgYnkgZGVmYXVsdC4KMi4gUXVhbmRsKCkgd2lsbCBub3QgYXV0b21hdGljYWxseSBhc3NpZ24gdGhlIGRhdGEgdG8gYW4gb2JqZWN0LgoKSWYgeW91IHBsYW4gb24gaW1wb3J0aW5nIGEgbG90IG9mIGRhdGEgdXNpbmcgUXVhbmRsKCksIHlvdSBtaWdodCBjb25zaWRlciBvcGVuaW5nIGEgZnJlZSBhY2NvdW50IHdpdGggdGhlbSBpbiBvcmRlciB0byBnZXQgYW4gQVBJIGtleS4KCmBgYHtyfQojIExvYWQgdGhlIFF1YW5kbCBwYWNrYWdlCmxpYnJhcnkoUXVhbmRsKQoKIyBJbXBvcnQgR0RQIGRhdGEgZnJvbSBGUkVECiMgZ2RwIDwtIFF1YW5kbChjb2RlID0gIkZSRUQvR0RQIikKCiMgTG9vayBhdCB0aGUgc3RydWN0dXJlIG9mIHRoZSBvYmplY3QgcmV0dXJuZWQgYnkgUXVhbmRsCiMgc3RyKGdkcCkKYGBgClF1YW5kbCBwcm92aWRlcyBhY2Nlc3MgdG8gYSBsYXJnZSBhbW91bnQgb2YgZGF0YSBzZXJpZXMuIFRoZWlyIHdlYnNpdGUgaGFzIGRvY3VtZW50YXRpb24gZm9yIGl0IGFsbCEKCiMjIyBSZXR1cm4gZGF0YSB0eXBlCgpUaGUgUXVhbmRsKCkgZnVuY3Rpb24gcmV0dXJucyBhIGRhdGEuZnJhbWUgYnkgZGVmYXVsdC4gSXQgY2FuIHJldHVybiBvdGhlciBjbGFzc2VzIHZpYSB0aGUgdHlwZSBhcmd1bWVudC4KClRoZSBwb3NzaWJsZSB2YWx1ZXMgZm9yIHR5cGUgYXJlOgoKMS4gInJhdyIgKGEgZGF0YS5mcmFtZSksCjIuICJ0cyIgKHRpbWUtc2VyaWVzIG9iamVjdHMgZnJvbSB0aGUgc3RhdHMgcGFja2FnZSksCjMuICJ6b28iLAo0LiAieHRzIiwgYW5kCjUuICJ0aW1lU2VyaWVzIiAoZnJvbSB0aGUgdGltZVNlcmllcyBwYWNrYWdlIGluIHRoZSBSTWV0cmljcyBzdWl0ZSkuCgpJbiB0aGlzIGV4ZXJjaXNlLCB5b3Ugd2lsbCBsZWFybiBob3cgdG8gdXNlIHRoZSB0eXBlIGFyZ3VtZW50IHRvIG1ha2UgUXVhbmRsKCkgcmV0dXJuIGFuIHh0cyBhbmQgYSB6b28gb2JqZWN0LgoKYGBge3J9CiMgSW1wb3J0IEdEUCBkYXRhIGZyb20gRlJFRCBhcyB4dHMKIyBnZHBfeHRzIDwtIFF1YW5kbChjb2RlID0gIkZSRUQvR0RQIiwgdHlwZSA9ICJ4dHMiKQoKIyBMb29rIGF0IHRoZSBzdHJ1Y3R1cmUgb2YgZ2RwX3h0cwojIHN0cihnZHBfeHRzKQogCiMgSW1wb3J0IEdEUCBkYXRhIGZyb20gRlJFRCBhcyB6b28KIyBnZHBfem9vIDwtIFF1YW5kbChjb2RlID0gIkZSRUQvR0RQIiwgdHlwZSA9ICJ6b28iKQoKIyBMb29rIGF0IHRoZSBzdHJ1Y3R1cmUgb2YgZ2RwX3pvbwojIHN0cihnZHBfem9vKQpgYGAKSGF2aW5nIHRoZSBmbGV4aWJpbGl0eSB0byByZXR1cm4gZGlmZmVyZW50IGRhdGEgdHlwZXMgaXMgYSBncmVhdCBib251cyBhbmQgbGVzcyB3b3JrIGZvciB5b3UhCgojIyBGaW5kaW5nIGRhdGEgZnJvbSBpbnRlcm5ldCBzb3VyY2VzCgojIyMgRmluZCBzdG9jayB0aWNrZXIgZnJvbSBZYWhvbyBGaW5hbmNlCgpZb3UgbmVlZCB0aGUgaW5zdHJ1bWVudCBpZGVudGlmaWVyIHRvIGltcG9ydCBkYXRhIGZyb20gYW4gaW50ZXJuZXQgZGF0YSBzb3VyY2UuIFRoZXkgY2FuIG9mdGVuIGJlIGZvdW5kIG9uIHRoZSBkYXRhIHNvdXJjZSB3ZWJzaXRlLiBJbiB0aGlzIGV4ZXJjaXNlLCB5b3Ugd2lsbCBzZWFyY2ggWWFob28gRmluYW5jZSBmb3IgdGhlIHRpY2tlciBzeW1ib2wgZm9yIFBmaXplciBzdG9jay4KCk5vdGUgdGhhdCBzb21lIHNvdXJjZXMgbWF5IG5vdCBwcm92aWRlIGRhdGEgZm9yIGNlcnRhaW4gc3ltYm9scywgZXZlbiBpZiB5b3UgY2FuIHNlZSB0aGUgZGF0YSBkaXNwbGF5ZWQgb24gdGhlaXIgd2Vic2l0ZSBpbiB0YWJsZXMgYW5kL29yIGNoYXJ0cy4gZ2V0U3ltYm9scygpIHdpbGwgZXJyb3IgaWYgdGhlIGRhdGEgaXMgbm90IGF2YWlsYWJsZSBmb3IgZG93bmxvYWQuCmBgYHtyfQojIENyZWF0ZSBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgUGZpemVyIHRpY2tlciBzeW1ib2wKc3ltYm9sIDwtICJQRkUiCgojIFVzZSBnZXRTeW1ib2xzIHRvIGltcG9ydCB0aGUgZGF0YQpnZXRTeW1ib2xzKCJQRkUiKQoKIyBMb29rIGF0IHRoZSBmaXJzdCBmZXcgcm93cyBvZiBkYXRhCmhlYWQoUEZFKQpgYGAKTG9va2luZyB1cCBpZGVudGlmaWVycyBvbmxpbmUgaXMgY29tbW9uIHdoZW4gc2Vla2luZyBkYXRhIGFib3V0IGEgbmV3IGluc3RydW1lbnQsIHNvIGl0J3MgZ29vZCB0byBnZXQgY29tZm9ydGFibGUgd2l0aCB0aGUgcHJvY2VzcyEKCiMjIyBEb3dubG9hZCBleGNoYW5nZSByYXRlIGRhdGEgZnJvbSBPYW5kYQoKT2FuZGEuY29tIHByb3ZpZGVzIGhpc3RvcmljYWwgZm9yZWlnbiBleGNoYW5nZSBkYXRhIGZvciBtYW55IGN1cnJlbmN5IHBhaXJzLiBDdXJyZW5jeSBwYWlycyBhcmUgZXhwcmVzc2VkIGFzIHR3byBjdXJyZW5jaWVzLCB0aGUgImJhc2UiIGFuZCB0aGUgInF1b3RlIiwgc2VwYXJhdGVkIGJ5IGEgIi8iLiBGb3IgZXhhbXBsZSwgdGhlIFUuUy4gRG9sbGFyIHRvIEV1cm8gZXhjaGFuZ2UgcmF0ZSB3b3VsZCBiZSAiVVNEL0VVUiIuCgpOb3RlIHRoYXQgZ2V0U3ltYm9scygpIHdpbGwgYXV0b21hdGljYWxseSBjb252ZXJ0ICJVU0QvRVVSIiB0byBhIHZhbGlkIG5hbWUgYnkgcmVtb3ZpbmcgdGhlICIvIi4gRm9yIGV4YW1wbGUsIGdldFN5bWJvbHMoIlVTRC9FVVIiKSB3b3VsZCBjcmVhdGUgYW4gb2JqZWN0IG5hbWVkIFVTREVVUi4KCkFsc28sIE9hbmRhLmNvbSBvbmx5IHByb3ZpZGVzIDE4MCBkYXlzIG9mIGhpc3RvcmljYWwgZGF0YS4gZ2V0U3ltYm9scygpIHdpbGwgd2FybiBhbmQgcmV0dXJuIGFzIG11Y2ggZGF0YSBhcyBwb3NzaWJsZSBpZiB5b3UgcmVxdWVzdCBkYXRhIGZyb20gbW9yZSB0aGFuIDE4MCBkYXlzIGFnby4gWW91IGNhbiB1c2UgdGhlIGZyb20gYW5kIHRvIGFyZ3VtZW50cyB0byBzZXQgYSBkYXRlIHJhbmdlOyBib3RoIHNob3VsZCBiZSBzdHJpbmdzIGluICIlWS0lbS0lZCIgZm9ybWF0IChlLmcuICIyMDE2LTAyLTA2IikuCgpxdWFudG1vZDo6b2FuZGEuY3VycmVuY2llcyBjb250YWlucyBhIGxpc3Qgb2YgY3VycmVuY2llcyBwcm92aWRlZCBieSBPYW5kYS5jb20uCmBgYHtyfQojIENyZWF0ZSBhIGN1cnJlbmN5X3BhaXIgb2JqZWN0CmN1cnJlbmN5X3BhaXIgPC0gIkdCUC9DQUQiCgojIExvYWQgQnJpdGlzaCBQb3VuZCB0byBDYW5hZGlhbiBEb2xsYXIgZXhjaGFuZ2UgcmF0ZSBkYXRhCmdldFN5bWJvbHMoY3VycmVuY3lfcGFpciwgc3JjID0gIm9hbmRhIikKCiMgRXhhbWluZSBvYmplY3QgdXNpbmcgc3RyKCkKc3RyKEdCUENBRCkKCiMgVHJ5IHRvIGxvYWQgZGF0YSBmcm9tIDE5MCBkYXlzIGFnbwpnZXRTeW1ib2xzKGN1cnJlbmN5X3BhaXIsIGZyb20gPSBTeXMuRGF0ZSgpIC0gMTkwLCB0byA9IFN5cy5EYXRlKCksIHNyYyA9ICJvYW5kYSIpCmBgYAojIyMgRmluZCBhbmQgaW1wb3J0IFVuZW1wbG95bWVudCBSYXRlIGRhdGEgZnJvbSBGUkVECgpCb3RoIGdldFN5bWJvbHMoKSBhbmQgUXVhbmRsKCkgcHJvdmlkZSBhY2Nlc3MgdG8gdGhlIEZSRUQgZGF0YWJhc2UuIEluIHRoaXMgZXhlcmNpc2UsIHlvdSB3aWxsIGZpbmQgdGhlIFtGUkVEXShodHRwczovL2ZyZWQuc3Rsb3Vpc2ZlZC5vcmcvKSBzeW1ib2wgZm9yIHRoZSBVbml0ZWQgU3RhdGVzIGNpdmlsaWFuIHVuZW1wbG95bWVudCByYXRlLiBUaGVuIHlvdSB3aWxsIHVzZSB0aGUgc2VyaWVzIG5hbWUgdG8gZG93bmxvYWQgdGhlIGRhdGEgZGlyZWN0bHkgZnJvbSBGUkVEIHVzaW5nIGdldFN5bWJvbHMoKSwgYW5kIGZyb20gdGhlIFF1YW5kbCBkYXRhYmFzZSB1c2luZyBRdWFuZGwoKS4KClJlbWVtYmVyIHRoYXQgZ2V0U3ltYm9scygpIHNwZWNpZmllcyB0aGUgZGF0YSBzb3VyY2UgdXNpbmcgdGhlIHNyYyBhcmd1bWVudCBhbmQgdGhhdCBRdWFuZGwoKSBzcGVjaWZpZXMgaXQgYXMgcGFydCBvZiB0aGUgUXVhbmRsIGNvZGUgKGkuZS4gZGF0YWJhc2Uvc2VyaWVzKS4KYGBge3J9CiMgQ3JlYXRlIGEgc2VyaWVzX25hbWUgb2JqZWN0CnNlcmllc19uYW1lIDwtICJVTlJBVEUiCgojIExvYWQgdGhlIGRhdGEgdXNpbmcgZ2V0U3ltYm9scwpnZXRTeW1ib2xzKHNlcmllc19uYW1lLCBzcmMgPSAiRlJFRCIpCgojIENyZWF0ZSBhIHF1YW5kbF9jb2RlIG9iamVjdAojIHF1YW5kbF9jb2RlIDwtICJGUkVEL1VOUkFURSIKCiMgTG9hZCB0aGUgZGF0YSB1c2luZyBRdWFuZGwjCiMgdW5lbXBsb3lfcmF0ZSA8LSBRdWFuZGwocXVhbmRsX2NvZGUpCmBgYAojIEV4dHJhY3RpbmcgYW5kIHRyYW5zZm9ybWluZyBkYXRhCgojIyBFeHRyYWN0IG9uZSBjb2x1bW4gZnJvbSBvbmUgaW5zdHJ1bWVudAoKVGhlIHF1YW50bW9kIHBhY2thZ2UgcHJvdmlkZXMgc2V2ZXJhbCBoZWxwZXIgZnVuY3Rpb25zIHRvIGV4dHJhY3Qgc3BlY2lmaWMgY29sdW1ucyBmcm9tIGFuIG9iamVjdCwgYmFzZWQgb24gdGhlIGNvbHVtbiBuYW1lLiBUaGUgT3AoKSwgSGkoKSwgTG8oKSwgQ2woKSwgVm8oKSwgYW5kIEFkKCkgZnVuY3Rpb25zIGNhbiBiZSB1c2VkIHRvIGV4dHJhY3QgdGhlIG9wZW4sIGhpZ2gsIGxvdywgY2xvc2UsIHZvbHVtZSwgYW5kIGFkanVzdGVkIGNsb3NlIGNvbHVtbiwgcmVzcGVjdGl2ZWx5LgoKSW4gdGhpcyBleGVyY2lzZSwgeW91IHdpbGwgdXNlIHR3byBvZiB0aGVzZSBmdW5jdGlvbnMgb24gYW4geHRzIG9iamVjdCBuYW1lZCBEQy4gVGhlIERDIG9iamVjdCBjb250YWlucyBmaWN0aXRpb3VzIERhdGFDYW1wIE9ITEMgKG9wZW4sIGhpZ2gsIGxvdywgY2xvc2UpIHN0b2NrIHByaWNlcyBjcmVhdGVkIGJ5IHJhbmRvbWl6aW5nIHNvbWUgcmVhbCBmaW5hbmNpYWwgbWFya2V0IGRhdGEuIERDIGlzIHNpbWlsYXIgdG8gdGhlIHh0cyBvYmplY3RzIGNyZWF0ZWQgYnkgZ2V0U3ltYm9scygpLgoKV2hpbGUgaXQncyBub3QgbmVjZXNzYXJ5IHRvIGNvbXBsZXRlIHRoZSBleGVyY2lzZSwgeW91IGNhbiBsZWFybiBtb3JlIGFib3V0IGFsbCB0aGUgZXh0cmFjdG9yIGZ1bmN0aW9ucyBmcm9tIGhlbHAoIk9ITEMuVHJhbnNmb3JtYXRpb25zIikuCiMjIEV4dHJhY3RpbmcgY29sdW1ucyBmcm9tIGZpbmFuY2lhbCB0aW1lIHNlcmllcwoKYGBge3J9CmxvYWQoZmlsZSA9ICJEQy5SRGF0YSIpCmBgYApgYGB7cn0KREMgPC0gRENbLGMoMSwyKV0KREMgPC0gdG8uaG91cmx5KERDLCBpbmRleEF0ID0gInN0YXJ0b2YiKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KHF1YW50bW9kKQojIEV4dHJhY3QgdGhlIGNsb3NlIGNvbHVtbgpkY19jbG9zZSA8LSBDbChEQykKCiMgTG9vayBhdCB0aGUgaGVhZCBvZiBkY19jbG9zZQpoZWFkKGRjX2Nsb3NlKQoKIyBFeHRyYWN0IHRoZSB2b2x1bWUgY29sdW1uCmRjX3ZvbHVtZSA8LSBWbyhEQykKCiMgTG9vayBhdCB0aGUgaGVhZCBvZiBkY192b2x1bWUKaGVhZChkY192b2x1bWUpCmBgYAojIyMgRXh0cmFjdCBtdWx0aXBsZSBjb2x1bW5zIGZyb20gb25lIGluc3RydW1lbnQKClRoZSBxdWFudG1vZCBwYWNrYWdlIHByb3ZpZGVzIGZ1bmN0aW9ucyB0byBleHRyYWN0IGEgc2luZ2xlIGNvbHVtbiwgYW5kIGFsc28gaGFzIGZ1bmN0aW9ucyB0byBleHRyYWN0IHNwZWNpZmljIHNldHMgb2YgY29sdW1ucy4KClJlY2FsbCBPSExDIHN0YW5kcyBmb3Igb3BlbiwgaGlnaCwgbG93LCBjbG9zZS4gTm93IHlvdSBjYW4gZ3Vlc3Mgd2hpY2ggY29sdW1ucyB0aGUgT0hMQygpIGFuZCBITEMoKSBmdW5jdGlvbnMgZXh0cmFjdC4gVGhlcmUncyBhbHNvIGFuIE9ITENWKCkgZnVuY3Rpb24sIHdoaWNoIGFkZHMgdGhlIHZvbHVtZSBjb2x1bW4uCgpUaGVzZSBmdW5jdGlvbnMgYXJlIGhlbHBmdWwgd2hlbiB5b3UgbmVlZCB0byBwYXNzIGEgc2V0IG9mIGNvbHVtbnMgdG8gYW5vdGhlciBmdW5jdGlvbi4gRm9yIGV4YW1wbGUsIHlvdSBtaWdodCBuZWVkIHRvIHBhc3MgdGhlIGhpZ2gsIGxvdywgYW5kIGNsb3NlIGNvbHVtbnMgKGluIHRoYXQgb3JkZXIpIHRvIGEgdGVjaG5pY2FsIGluZGljYXRvciBmdW5jdGlvbi4KYGBge3J9CiMgRXh0cmFjdCB0aGUgaGlnaCwgbG93LCBhbmQgY2xvc2UgY29sdW1ucwpkY19obGMgPSBITEMoREMpCgojIExvb2sgYXQgdGhlIGhlYWQgb2YgZGNfaGxjCmhlYWQoZGNfaGxjKQoKIyBFeHRyYWN0IHRoZSBvcGVuLCBoaWdoLCBsb3csIGNsb3NlLCBhbmQgdm9sdW1lIGNvbHVtbnMKZGNfb2hsY3YgPSBPSExDVihEQykKCiMgTG9vayBhdCB0aGUgaGVhZCBvZiBkY19vaGxjdgpoZWFkKGRjX29obGN2KQpgYGAKIyMjIFVzZSBnZXRQcmljZSB0byBleHRyYWN0IG90aGVyIGNvbHVtbnMKClRoZSBleHRyYWN0b3IgZnVuY3Rpb25zIHlvdSBsZWFybmVkIGluIHRoZSBwcmV2aW91cyB0d28gZXhlcmNpc2VzIGRvIG5vdCBjb3ZlciBhbGwgdXNlIGNhc2VzLiBTb21ldGltZXMgeW91IG1pZ2h0IGhhdmUgb25lIG9iamVjdCB0aGF0IGNvbnRhaW5zIHRoZSBzYW1lIHByaWNlIGNvbHVtbiBmb3IgbXVsdGlwbGUgaW5zdHJ1bWVudHMuIE90aGVyIHRpbWVzLCB5b3UgbWlnaHQgaGF2ZSBhbiBvYmplY3Qgd2l0aCBwcmljZSBkYXRhIChlLmcuIGJpZCwgYXNrLCB0cmFkZSkgdGhhdCBkbyBub3QgaGF2ZSBhbiBleHBsaWNpdCBleHRyYWN0b3IgZnVuY3Rpb24uCgpUaGUgZ2V0UHJpY2UoKSBmdW5jdGlvbiBpbiB0aGUgcXVhbnRtb2QgcGFja2FnZSBjYW4gZXh0cmFjdCBhbnkgY29sdW1uIGJ5IG5hbWUgYnkgdXNpbmcgdGhlIHByZWZlciBhcmd1bWVudC4gSXQgY2FuIGFsc28gZXh0cmFjdCBjb2x1bW5zIGZvciBhIHNwZWNpZmljIGluc3RydW1lbnQgYnkgdXNpbmcgdGhlIHN5bWJvbCBhcmd1bWVudCwgd2hpY2ggaXMgdXNlZnVsIHdoZW4gYW4gb2JqZWN0IGNvbnRhaW5zIHNldmVyYWwgaW5zdHJ1bWVudHMgd2l0aCB0aGUgc2FtZSBwcmljZSB0eXBlLgoKWW91IGNhbiB1c2UgcmVndWxhciBleHByZXNzaW9ucyBmb3IgYm90aCB0aGUgcHJlZmVyIGFuZCBzeW1ib2wgYXJndW1lbnRzLCBiZWNhdXNlIHRoZXkgYXJlIHBhc3NlZCB0byB0aGUgYmFzZTo6Z3JlcCgpIGZ1bmN0aW9uIGludGVybmFsbHkuCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQojYXBpClF1YW5kbC5hcGlfa2V5KCJYU1plUGljMTJqejlDTmYydVZoLSIpCmBgYApgYGB7cn0KIyBEb3dubG9hZCBDTUUgZGF0YSBmb3IgQ0wgYW5kIEJaIGFzIGFuIHh0cyBvYmplY3QKb2lsX2RhdGEgPC0gUXVhbmRsKGNvZGUgPSBjKCJDSFJJUy9DTUVfUVg3IiwgIkNGVEMvMDY3NjUzX0ZPX0xfQUxMX0NSIiksIHR5cGUgPSAieHRzIikKCiMgTG9vayBhdCB0aGUgY29sdW1uIG5hbWVzIG9mIHRoZSBvaWxfZGF0YSBvYmplY3QKY29sbmFtZXMob2lsX2RhdGEpCgojIEV4dHJhY3QgdGhlIE9wZW4gcHJpY2UgZm9yIENMSDIwMTYKY2xfb3BlbiA8LSBnZXRQcmljZShvaWxfZGF0YSwgc3ltYm9sID0gIkNNRV9RWDciLCBwcmVmZXIgPSAiT3BlbiQiKQoKIyBMb29rIGF0IEphbnVhcnksIDIwMTYgdXNpbmcgeHRzJyBJU08tODYwMSBzdWJzZXR0aW5nCmNsX29wZW5bIjIwMTYtMDEiXQpgYGAKZ2V0UHJpY2UoKSBpcyBhIHZlcnkgZmxleGlibGUgd2F5IHRvIHJldHJpZXZlIHRoZSBjb2x1bW5zIHlvdSBuZWVkLgoKIyMgSW1wb3J0aW5nIGFuZCB0cmFuc2Zvcm1pbmcgbXVsdGlwbGUgaW5zdHJ1bWVudHMKCgojIyMgVXNlIFF1YW5kbCB0byBkb3dubG9hZCB3ZWVrbHkgcmV0dXJucyBkYXRhCgpTb21ldGltZXMgeW91IG5lZWQgdG8gYWdncmVnYXRlIGFuZC9vciB0cmFuc2Zvcm0gcmF3IGRhdGEgYmVmb3JlIHlvdSBjYW4gY29udGludWUgeW91ciBhbmFseXNpcy4gVGhlIFF1YW5kbCgpIGZ1bmN0aW9uIGFsbG93cyB5b3UgdG8gc3BlY2lmeSBjb21tb24gYWdncmVnYXRpb25zIGFuZCB0cmFuc2Zvcm1hdGlvbnMgdmlhIHRoZSBjb2xsYXBzZSBhbmQvb3IgdHJhbnNmb3JtIGFyZ3VtZW50cy4gVGhlIFF1YW5kbCBBUEkgdGFrZXMgY2FyZSBvZiB0aGUgZGV0YWlscyBmb3IgeW91LgoKYGBge3J9CiMgRG93bmxvYWQgcXVhcnRlcmx5IENMIGFuZCBCWiBwcmljZXMKcXRyX3ByaWNlIDwtIFF1YW5kbChjb2RlID0gYygiQ0hSSVMvQ01FX1FNMSIsICJDSFJJUy9DTUVfUUcxIiksIGNvbGxhcHNlID0gInF1YXJ0ZXJseSIsdHlwZSA9ICJ4dHMiKQoKIyBWaWV3IHRoZSBoaWdoIHByaWNlcyBmb3IgYm90aCBzZXJpZXMKSGkocXRyX3ByaWNlKQoKIyBEb3dubG9hZCBxdWFydGVybHkgQ0wgYW5kIEJaIHJldHVybnMKcXRyX3JldHVybiA8LSBRdWFuZGwoY29kZSA9IGMoIkNIUklTL0NNRV9RTTEiLCAiQ0hSSVMvQ01FX1FHMSIpLCBjb2xsYXBzZSA9ICJxdWFydGVybHkiLHRyYW5zZm9ybSA9ICJyZGlmZiIsIHR5cGUgPSAieHRzIikKCiMgVmlldyB0aGUgc2V0dGxlIHByaWNlIHJldHVybnMgZm9yIGJvdGggc2VyaWVzCmdldFByaWNlKHF0cl9yZXR1cm4sIHByZWZlciA9ICJTZXR0bGUiKQpgYGAKIyMjIENvbWJpbmUgbWFueSBpbnN0cnVtZW50cyBpbnRvIG9uZSBvYmplY3QKCldoYXQgaWYgeW91IG5lZWQgdG8gYWdncmVnYXRlIG9yIHRyYW5zZm9ybSB5b3VyIGRhdGEgaW4gd2F5cyBRdWFuZGwoKSBkb2VzIG5vdCBzdXBwb3J0PyBJbiB0aG9zZSBjYXNlcywgeW91IGNhbiB1c2UgdGhlIGZsZXhpYmlsaXR5IG9mIFIuCgpPbmUgcGFyYWRpZ20gaW52b2x2ZXMgaW1wb3J0aW5nIGRhdGEgaW50byBhIG5ldyBlbnZpcm9ubWVudC4gVGhlbiB5b3UgY2FuIHVzZSBlYXBwbHkoKSB0byBjYWxsIGEgZnVuY3Rpb24gb24gZWFjaCBvYmplY3QgaW4gdGhlIGVudmlyb25tZW50LCBtdWNoIGxpa2Ugd2hhdCBsYXBwbHkoKSBkb2VzIGZvciBlYWNoIGVsZW1lbnQgb2YgYSBsaXN0LiBBbHNvIGxpa2UgbGFwcGx5KCksIGVhcHBseSgpIHJldHVybnMgYSBsaXN0LgoKVGhlbiB5b3UgY2FuIG1lcmdlIGFsbCB0aGUgZWxlbWVudHMgb2YgdGhlIGxpc3QgaW50byBvbmUgb2JqZWN0IGJ5IHVzaW5nIGRvLmNhbGwoKSwgd2hpY2ggaXMgbGlrZSBoYXZpbmcgUiBwcm9ncmFtbWF0aWNhbGx5IHR5cGUgYW5kIHJ1biBhIGNvbW1hbmQgZm9yIHlvdS4gSW5zdGVhZCBvZiB0eXBpbmcgbWVyZ2UobXlfbGlzdFtbMV1dLCBteV9saXN0W1syXV1dLCAuLi4pLCB5b3UgY2FuIHR5cGUgZG8uY2FsbChtZXJnZSwgbXlfbGlzdCkuCmBgYHtyfQojIENyZWF0ZSBuZXcgZW52aXJvbm1lbnQKZGF0YV9lbnYgPC0gbmV3LmVudigpCiMgVXNlIGdldFN5bWJvbHMgdG8gbG9hZCBkYXRhIGludG8gdGhlIGVudmlyb25tZW50CmdldFN5bWJvbHMoYygiU1BZIiwgIlFRUSIpLCBlbnYgPSBkYXRhX2VudiwgYXV0by5hc3NpZ24gPSBUUlVFKQpgYGAKYGBge3J9CiMgTG9vayBhdCBhIGZldyByb3dzIG9mIHRoZSBTUFkgZGF0YQpoZWFkKGRhdGFfZW52JFNQWSwgMykKYGBgCmBgYHtyfQojIExvb2sgYXQgYSBmZXcgcm93cyBvZiB0aGUgU1BZIGRhdGEKZWFwcGx5KGRhdGFfZW52LCBoZWFkKQpgYGAKYGBge3J9CiMgQ2FsbCBoZWFkIG9uIGVhY2ggb2JqZWN0IGluIGRhdGFfZW52IHVzaW5nIGVhcHBseQpkYXRhX2xpc3QgPC0gZWFwcGx5KGRhdGFfZW52LCBoZWFkKQoKIyBNZXJnZSBhbGwgdGhlIGxpc3QgZWxlbWVudHMgaW50byBvbmUgeHRzIG9iamVjdApkYXRhX21lcmdlZCA8LSBkby5jYWxsKG1lcmdlLCBkYXRhX2xpc3QpCgojIEVuc3VyZSB0aGUgY29sdW1ucyBhcmUgb3JkZXJlZDogb3BlbiwgaGlnaCwgbG93LCBjbG9zZQpkYXRhX29obGMgPC0gT0hMQyhkYXRhX21lcmdlZCkKZGF0YV9vaGxjCmBgYApgYGB7cn0KIyBFeHRyYWN0IHZvbHVtZSBjb2x1bW4gZnJvbSBlYWNoIG9iamVjdAphZGp1c3RlZF9saXN0IDwtIGxhcHBseShkYXRhX2VudiwgQWQpCiMgTWVyZ2UgZWFjaCBsaXN0IGVsZW1lbnQgaW50byBvbmUgb2JqZWN0CmFkanVzdGVkIDwtIGRvLmNhbGwobWVyZ2UsIGFkanVzdGVkX2xpc3QpCmhlYWQoYWRqdXN0ZWQpCmBgYAojIyMgRXh0cmFjdCB0aGUgQ2xvc2UgY29sdW1uIGZyb20gbWFueSBpbnN0cnVtZW50cwoKVGhlIHByZXZpb3VzIGV4ZXJjaXNlIHRhdWdodCB5b3UgaG93IHRvIHVzZSBkby5jYWxsKG1lcmdlLCBlYXBwbHkoZW52LCBmdW4pKSB0byBhcHBseSBhIGZ1bmN0aW9uIHRvIGVhY2ggb2JqZWN0IGluIGFuIGVudmlyb25tZW50IGFuZCB0aGVuIGNvbWJpbmUgYWxsIHRoZSByZXN1bHRzIGludG8gb25lIG9iamVjdC4KCkxldCdzIHVzZSB3aGF0IHlvdSBsZWFybmVkIHRvIHNvbHZlIGEgdmVyeSBjb21tb24gcHJvYmxlbS4gT2Z0ZW4geW91IHdpbGwgbmVlZCB0byBsb2FkIHNpbWlsYXIgZGF0YSBmb3IgbWFueSBpbnN0cnVtZW50cywgZXh0cmFjdCBhIGNvbHVtbiwgYW5kIGNyZWF0ZSBvbmUgb2JqZWN0IHRoYXQgY29udGFpbnMgdGhhdCBzcGVjaWZpYyBjb2x1bW4gZm9yIGV2ZXJ5IGluc3RydW1lbnQuCmBgYHtyfQojIFN5bWJvbHMKc3ltYm9scyA8LSBjKCJBQVBMIiwgIk1TRlQiLCAiSUJNIikKCiMgQ3JlYXRlIG5ldyBlbnZpcm9ubWVudApkYXRhX2VudiA8LSBuZXcuZW52KCkKCiMgTG9hZCBzeW1ib2xzIGludG8gZGF0YV9lbnYKZ2V0U3ltYm9scyhzeW1ib2xzLCBlbnYgPSBkYXRhX2VudikKCiMgRXh0cmFjdCB0aGUgY2xvc2UgY29sdW1uIGZyb20gZWFjaCBvYmplY3QgYW5kIGNvbWJpbmUgaW50byBvbmUgeHRzIG9iamVjdApjbG9zZV9kYXRhIDwtIGRvLmNhbGwobWVyZ2UsIGVhcHBseShkYXRhX2VudiwgQ2wpKQoKIyBWaWV3IHRoZSBoZWFkIG9mIGNsb3NlX2RhdGEKaGVhZChjbG9zZV9kYXRhKQpgYGAKCiMgTWFuYWdpbmcgZGF0YSBmcm9tIG11bHRpcGxlIHNvdXJjZXMKCiMjIFNldHRpbmcgZGVmYXVsdCBhcmd1bWVudHMgZm9yIGdldFN5bWJvbHMoKQoKIyMjIFNldCBhIGRlZmF1bHQgZGF0YSBzb3VyY2UKClJlY2FsbCB0aGF0IGdldFN5bWJvbHMoKSBpbXBvcnRzIGZyb20gWWFob28gRmluYW5jZSBieSBkZWZhdWx0LiBUaGlzIGV4ZXJjaXNlIHdpbGwgdGVhY2ggeW91IGhvdyB0byBjaGFuZ2UgdGhlIGRlZmF1bHQgZGF0YSBzb3VyY2Ugd2l0aCB0aGUgc2V0RGVmYXVsdHMoKSBmdW5jdGlvbi4KClRoZSBmaXJzdCBhcmd1bWVudCB0byBzZXREZWZhdWx0cygpIGlzIHRoZSBmdW5jdGlvbiB5b3Ugd2FudCB0byB1cGRhdGUsIGFuZCB0aGUgcmVtYWluaW5nIGFyZ3VtZW50cyBhcmUgbmFtZSA9IHZhbHVlIHBhaXJzIG9mIHRoZSBhcmd1bWVudHMgeW91IHdhbnQgdG8gdXBkYXRlIGFuZCB0aGUgbmV3IGRlZmF1bHQgdmFsdWUuCgpOb3RlIHRoYXQgdGhpcyBvbmx5IHdvcmtzIHdpdGggZ2V0U3ltYm9scygpIGJlY2F1c2UgZ2V0U3ltYm9scygpIGFjdGl2ZWx5IGNoZWNrcyB0byBzZWUgaWYgeW91IHdhbnQgdG8gdXNlIGEgZGlmZmVyZW50IGRlZmF1bHQgdmFsdWUuCmBgYHtyfQojIFNldCB0aGUgZGVmYXVsdCB0byBwdWxsIGRhdGEgZnJvbSBBbHBoYSBWYW50YWdlCnNldERlZmF1bHRzKGdldFN5bWJvbHMsIHNyYyA9ICJhdiIpCgojIEdldCBHT09HIGRhdGEKIyBnZXRTeW1ib2xzKCJHT09HIikKCiMgVmVyaWZ5IHRoZSBkYXRhIHdhcyBhY3R1YWxseSBwdWxsZWQgZnJvbSBBbHBoYSBWYW50YWdlCiMgc3RyKEdPT0cpCmBgYApTZXR0aW5nIGEgZGVmYXVsdCBzb3VyY2UgY2FuIGJlIHVzZWZ1bCBpZiB5b3UgdXNlIHRoYXQgc291cmNlIG9mdGVuLgoKIyMjIFNldCBkZWZhdWx0IGFyZ3VtZW50cyBmb3IgYSBnZXRTeW1ib2xzIHNvdXJjZQoKWW91IGNhbiBhbHNvIHVzZSBzZXREZWZhdWx0cygpIG9uIGluZGl2aWR1YWwgZ2V0U3ltYm9scygpIHNvdXJjZSBtZXRob2RzLiBUaGlzIGV4ZXJjaXNlIHdpbGwgdGVhY2ggeW91IGhvdyB0byBjaGFuZ2UgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoZSBmcm9tIGFyZ3VtZW50IHRvIGdldFN5bWJvbHMueWFob28oKS4KCllvdSBjYW4gZmluZCB0aGUgYXJndW1lbnRzIGZvciBhIHNwZWNpZmljIG1ldGhvZCBieSB1c2luZyBoZWxwKCkgKGUuZy4gaGVscCgiZ2V0U3ltYm9scy55YWhvbyIpIG9yIGJ5IGNhbGxpbmcgYXJncygpIHRvIHByaW50IHRoZW0gdG8gdGhlIGNvbnNvbGUgKGUuZy4gYXJncyhnZXRTeW1ib2xzLnlhaG9vKSkuIENhbGxpbmcgZ2V0RGVmYXVsdHMoKSB3aWxsIHNob3cgeW91IHRoZSBjdXJyZW50IGRlZmF1bHQgdmFsdWVzIChpZiB0aGVyZSBhcmUgYW55KS4KClJlbWVtYmVyLCB5b3UgYXJlIG5vdCBzdXBwb3NlZCB0byBjYWxsIGdldFN5bWJvbHMueWFob28oKSBkaXJlY3RseSEKYGBge3J9CiMgTG9vayBhdCBnZXRTeW1ib2xzLnlhaG9vIGFyZ3VtZW50cwphcmdzKGdldFN5bWJvbHMueWFob28pCgojIFNldCBkZWZhdWx0ICdmcm9tJyB2YWx1ZSBmb3IgZ2V0U3ltYm9scy55YWhvbwpzZXREZWZhdWx0cyhnZXRTeW1ib2xzLnlhaG9vLCBmcm9tID0gIjIwMDAtMDEtMDEiKQoKIyBDb25maXJtIGRlZmF1bHRzIHdlcmUgc2V0IGNvcnJlY3RseQpnZXREZWZhdWx0cygiZ2V0U3ltYm9scy55YWhvbyIpCmBgYAojIyBTZXR0aW5nIHBlci1pbnN0cnVtZW50IGRlZmF1bHQgYXJndW1lbnRzCgojIyMgU2V0IGRlZmF1bHQgZGF0YSBzb3VyY2UgZm9yIG9uZSBzeW1ib2wKCkNoYW5naW5nIHRoZSBkZWZhdWx0IHNvdXJjZSBmb3Igb25lIGluc3RydW1lbnQgaXMgdXNlZnVsIGlmIG11bHRpcGxlIHNvdXJjZXMgdXNlIHRoZSBzYW1lIHN5bWJvbCBmb3IgZGlmZmVyZW50IGluc3RydW1lbnRzLiBGb3IgZXhhbXBsZSwgZ2V0U3ltYm9scygiQ1AiLCBzcmMgPSAieWFob28iKSB3b3VsZCBsb2FkIENhbmFkaWFuIFBhY2lmaWMgUmFpbHdheSBkYXRhIGZyb20gdGhlIE5ldyBZb3JrIFN0b2NrIEV4Y2hhbmdlLiBCdXQgZ2V0U3ltYm9scygiQ1AiLCBzcmMgPSAiRlJFRCIpIHdvdWxkIGxvYWQgQ29ycG9yYXRlIFByb2ZpdHMgQWZ0ZXIgVGF4IGZyb20gdGhlIFUuUy4gQnVyZWF1IG9mIEVjb25vbWljIEFuYWx5c2lzLgoKWW91IGNhbiB1c2Ugc2V0U3ltYm9sTG9va3VwKCkgdG8gc3BlY2lmeSB0aGUgZGVmYXVsdCBkYXRhIHNvdXJjZSBmb3IgYW4gaW5zdHJ1bWVudC4gSW4gdGhpcyBleGVyY2lzZSwgeW91IHdpbGwgbGVhcm4gaG93IHRvIG1ha2UgZ2V0U3ltYm9scygiQ1AiKSBsb2FkIHRoZSBjb3Jwb3JhdGUgcHJvZml0IGRhdGEgZnJvbSBGUkVEIGluc3RlYWQgb2YgdGhlIHJhaWx3YXkgc3RvY2sgZGF0YSBmcm9tIFlhaG9vIEZpbmFuY2UuCgpzZXRTeW1ib2xMb29rdXAoKSBjYW4gdGFrZSBhbnkgbnVtYmVyIG9mIG5hbWUgPSB2YWx1ZSBwYWlycywgd2hlcmUgbmFtZSBpcyB0aGUgc3ltYm9sIGFuZCB2YWx1ZSBpcyBhIG5hbWVkIGxpc3Qgb2YgZ2V0U3ltYm9scygpIGFyZ3VtZW50cyBmb3IgdGhhdCBvbmUgc3ltYm9sLgpgYGB7cn0Kc2V0RGVmYXVsdHMoZ2V0U3ltYm9scywgc3JjID0gInlhaG9vIikKc2V0U3ltYm9sTG9va3VwKCJDUCIgPSAieWFob28iKQojIExvYWQgQ1AgZGF0YSBhZ2FpbgpnZXRTeW1ib2xzKCJDUCIpCiMgTG9vayBhdCB0aGUgZmlyc3QgZmV3IHJvd3Mgb2YgQ1AKaGVhZChDUCkKCnNldFN5bWJvbExvb2t1cCgiQ1AiID0gTlVMTCkKCiMgU2V0IHRoZSBzb3VyY2UgZm9yIENQIHRvIEZSRUQKc2V0U3ltYm9sTG9va3VwKCJDUCIgPSAiRlJFRCIpCgojIExvYWQgQ1AgZGF0YSBhZ2FpbgpnZXRTeW1ib2xzKCJDUCIpCgojIExvb2sgYXQgdGhlIGZpcnN0IGZldyByb3dzIG9mIENQCmhlYWQoQ1ApCmBgYApPY2Nhc2lvbmFsbHkgdGhpcyBoYXBwZW5zLCBhbmQgaXQgaXMgdXNlZnVsIHRvIHNldCBhIHNpbmdsZSBzeW1ib2wgdG8gYmUgcHVsbGVkIGZyb20gYSBzcGVjaWZpYyBzb3VyY2UuCgojIyMgU2F2ZSBhbmQgbG9hZCBzeW1ib2wgbG9va3VwIHRhYmxlCgpUaGUgcHJldmlvdXMgZXhlcmNpc2UgdGF1Z2h0IHlvdSBob3cgdG8gc2V0IGRlZmF1bHQgYXJndW1lbnRzIG9uIGEgcGVyLXN5bWJvbCBiYXNpcywgYnV0IHRob3NlIHNldHRpbmdzIG9ubHkgbGFzdCBmb3IgdGhlIGN1cnJlbnQgc2Vzc2lvbi4KClRoaXMgZXhlcmNpc2Ugd2lsbCB0ZWFjaCB5b3UgaG93IHRvIHNhdmUgYW5kIGxvYWQgc3ltYm9sLWJhc2VkIGRlZmF1bHRzIGJ5IHVzaW5nIHNhdmVTeW1ib2xMb29rdXAoKSBhbmQgbG9hZFN5bWJvbExvb2t1cCgpLCByZXNwZWN0aXZlbHkuIFlvdSBjYW4gdXNlIHRoZSBmaWxlIGFyZ3VtZW50cyB0byBzcGVjaWZ5IGEgZmlsZSB0byBzdG9yZSB5b3VyIGRlZmF1bHRzLgoKWW91IGNhbiBhbHNvIHVzZSB0aGUgZ2V0U3ltYm9sTG9va3VwKCkgZnVuY3Rpb24gdG8gY2hlY2sgcGVyLXN5bWJvbCBkZWZhdWx0cyBiZWZvcmUgeW91IHRyeSB0byBsb2FkIGRhdGEgdXNpbmcgZ2V0U3ltYm9scygpLgoKYGBge3J9CiMgU2F2ZSBzeW1ib2wgbG9va3VwIHRhYmxlCnNhdmVTeW1ib2xMb29rdXAoIm15X3N5bWJvbF9sb29rdXAucmRhIikKCiMgU2V0IGRlZmF1bHQgc291cmNlIGZvciBDUCB0byAieWFob28iCnNldFN5bWJvbExvb2t1cCgiQ1AiID0gInlhaG9vIikKCiMgVmVyaWZ5IHRoZSBkZWZhdWx0IHNvdXJjZSBpcyAieWFob28iCmdldFN5bWJvbExvb2t1cCgiQ1AiKQoKIyBMb2FkIHN5bWJvbCBsb29rdXAgdGFibGUKbG9hZFN5bWJvbExvb2t1cCgibXlfc3ltYm9sX2xvb2t1cC5yZGEiKQpnZXRTeW1ib2xMb29rdXAoIkNQIikKYGBgClRoaXMgd2lsbCBsZXQgeW91IGxvYWQgdGhlIHNhbWUgbG9va3VwIHRhYmxlIGV2ZW4gaWYgeW91IGNsb3NlIG91dCBvZiBSLgoKIyMgSGFuZGxpbmcgaW5zdHJ1bWVudCBzeW1ib2xzIHRoYXQgY2xhc2ggb3IgYXJlIG5vdCB2YWxpZCBSIG5hbWVzCgojIyMgQWNjZXNzIHRoZSBvYmplY3QgdXNpbmcgZ2V0KCkgb3IgYmFja3RpY2tzCgpBdCBzb21lIHBvaW50LCB5b3UgbWlnaHQgZG93bmxvYWQgZGF0YSBmb3IgYW4gaW5zdHJ1bWVudCB0aGF0IGRvZXMgbm90IGhhdmUgYSBzeW50YWN0aWNhbGx5IHZhbGlkIG5hbWUuIFN5bnRhY3RpY2FsbHkgdmFsaWQgbmFtZXMgY29udGFpbiBsZXR0ZXJzLCBudW1iZXJzLCAiLiIsIGFuZCAiXyIsIGFuZCBtdXN0IHN0YXJ0IHdpdGggYSBsZXR0ZXIgb3IgYSAiLiIgZm9sbG93ZWQgYnkgYSBub24tbnVtYmVyLgoKRm9yIGV4YW1wbGUsIHRoZSBzeW1ib2wgZm9yIEJlcmtzaGlyZSBIYXRoYXdheSBjbGFzcyBBIHNoYXJlcyBpcyAiQlJLLUEiLCB3aGljaCBpcyBub3QgYSBzeW50YWN0aWNhbGx5IHZhbGlkIG5hbWUgYmVjYXVzZSBpdCBjb250YWlucyBhICItIiBjaGFyYWN0ZXIuIEFub3RoZXIgZXhhbXBsZSBhcmUgQ2hpbmVzZSBzdG9ja3MsIHdoaWNoIGhhdmUgc3ltYm9scyBjb21wb3NlZCBvZiBudW1iZXJzLiBUaGUgWWFob28gRmluYW5jZSBzeW1ib2wgZm9yIHRoZSBTU0UgQ29tcG9zaXRlIEluZGV4IGlzICIwMDAwMDEuU1MiLgoKWW91IGNhbiB1c2UgdGhlIGdldCBmdW5jdGlvbiBvciBiYWNrdGlja3MgKGApIHRvIGFjY2VzcyBvYmplY3RzIHRoYXQgZG8gbm90IGhhdmUgc3ludGFjdGljYWxseSB2YWxpZCBuYW1lcy4KCmBgYHtyfQojIExvYWQgQlJLLUEgZGF0YQpnZXRTeW1ib2xzKCJCUkstQSIpCgojIFVzZSBiYWNrdGlja3MgYW5kIGhlYWQoKSB0byBsb29rIGF0IHRoZSBsb2FkZWQgZGF0YQpoZWFkKGBCUkstQWApCgojIFVzZSBnZXQoKSB0byBhc3NpZ24gdGhlIEJSSy1BIGRhdGEgdG8gYW4gb2JqZWN0IG5hbWVkIEJSSy5BCkJSSy5BIDwtIGdldCgiQlJLLUEiKQpgYGAKSnVzdCByZW1lbWJlciB0byB1c2UgYmFja3RpY2tzIG9yIGdldCgpIGlmIHlvdSBldmVyIHJ1biBpbnRvIGludmFsaWQgY2hhcmFjdGVycy4KCiMjIyBDcmVhdGUgdmFsaWQgbmFtZSBmb3Igb25lIGluc3RydW1lbnQKCklmIHlvdSBhcmUgb25seSBkb3dubG9hZGluZyBkYXRhIGZvciBhIHNpbmdsZSBzeW1ib2wgYW5kIHRoYXQgc3ltYm9sIGlzIG5vdCBhIHN5bnRhY3RpY2FsbHkgdmFsaWQgbmFtZSwgeW91IGNhbiBzZXQgYXV0by5hc3NpZ24gPSBGQUxTRSBpbiB5b3VyIGNhbGwgdG8gZ2V0U3ltYm9scygpLiBUaGF0IHdpbGwgYWxsb3cgeW91IHRvIGRpcmVjdGx5IGFzc2lnbiB0aGUgb3V0cHV0IHRvIGEgc3ludGFjdGljYWxseSB2YWxpZCBuYW1lLgoKWW91IG1heSBhbHNvIHdhbnQgdG8gY29udmVydCB0aGUgY29sdW1uIG5hbWVzIHRvIHN5bnRhY3RpY2FsbHkgdmFsaWQgbmFtZXMuIFRoYXQgaXMgYSBnb29kIGlkZWEgaWYgeW91IHBsYW4gdG8gdXNlIHRoZSBkYXRhIGluIGZ1bmN0aW9ucyB0aGF0IGV4cGVjdCBjb2x1bW4gbmFtZXMgdG8gYmUgc3ludGFjdGljYWxseSB2YWxpZCBuYW1lcyAoZS5nLiBsbSgpKS4KYGBge3J9CiMgQ3JlYXRlIEJSSy5BIG9iamVjdApCUksuQSA8LSBnZXRTeW1ib2xzKCJCUkstQSIsIGF1dG8uYXNzaWduID0gRkFMU0UpCgojIENyZWF0ZSBjb2xfbmFtZXMgb2JqZWN0IHdpdGggdGhlIGNvbHVtbiBuYW1lcyBvZiBCUksuQQpjb2xfbmFtZXMgPC0gY29sbmFtZXMoQlJLLkEpCgojIFNldCBCUksuQSBjb2x1bW4gbmFtZXMgdG8gc3ludGFjdGljYWxseSB2YWxpZCBuYW1lcwpjb2xuYW1lcyhCUksuQSkgPC0gbWFrZS5uYW1lcyhjb2xfbmFtZXMpCmBgYApOb3cgeW91IGNhbiBmaXggdHJpY2t5IHRpY2tlciBzeW1ib2xzIGluIHRoZSBjb2x1bW4gbmFtZXMgb2YgeW91ciBkYXRhLgoKIyMjIENyZWF0ZSB2YWxpZCBuYW1lcyBmb3IgbXVsdGlwbGUgaW5zdHJ1bWVudHMKCkFuIGVhcmxpZXIgZXhlcmNpc2UgdGF1Z2h0IHlvdSBob3cgdG8gdXNlIHNldFN5bWJvbExvb2t1cCgpIHRvIHNldCBhIGRlZmF1bHQgZGF0YSBzb3VyY2UgZm9yIGdldFN5bWJvbHMoKS4gWW91IGNhbiBhbHNvIHVzZSBzZXRTeW1ib2xMb29rdXAoKSB0byBjcmVhdGUgYSBtYXBwaW5nIGJldHdlZW4gdGhlIGluc3RydW1lbnQgc3ltYm9sIGFuZCB0aGUgbmFtZSBvZiB0aGUgUiBvYmplY3QuCgpUaGlzIGlzIHVzZWZ1bCBpZiB5b3Ugd2FudCB0byBkb3dubG9hZCBkYXRhIGZvciBhIGxvdCBzeW1ib2xzIHRoYXQgYXJlIG5vdCBzeW50YWN0aWNhbGx5IHZhbGlkIG5hbWVzLCBvciBzeW1ib2xzIHRoYXQgaGF2ZSBuYW1lcyB0aGF0IGNvbmZsaWN0IHdpdGggb3RoZXIgUiB2YXJpYWJsZSBuYW1lcy4KCkFuIGV4YW1wbGUgb2YgYSBuYW1lIHRoYXQgY29uZmxpY3RzIGlzIHRoZSBzeW1ib2wgZm9yIEFUJlQncyBzdG9jaywgVCwgd2hpY2ggaXMgb2Z0ZW4gdXNlZCBhcyBhIHNob3J0IGZvcm0gZm9yIHRoZSBsb2dpY2FsIHZhbHVlIFRSVUUuCgpUbyBjaGFuZ2UgdGhlIG5hbWUgb2YgYSBnaXZlbiBzeW1ib2wsIGFyZ3VtZW50cyBtdXN0IGJlIHBhc3NlZCB0byBzZXRTeW1ib2xMb29rdXAoKSBhcyBhIGxpc3QsIGxpa2Ugc286IHNldFN5bWJvbExvb2t1cChORVdfTkFNRSA9IGxpc3QobmFtZSA9ICJPTERfTkFNRSIpKS4KYGBge3J9CiMgU2V0IG5hbWUgZm9yIEJSSy1BIHRvIEJSSy5BCnNldFN5bWJvbExvb2t1cChCUksuQSA9IGxpc3QobmFtZSA9ICJCUkstQSIpKQoKIyBTZXQgbmFtZSBmb3IgVCAoQVQmVCkgdG8gQVRUCnNldFN5bWJvbExvb2t1cChBVFQgPSBsaXN0KG5hbWUgPSAiVCIpKQoKIyBMb2FkIEJSSy5BIGFuZCBBVFQgZGF0YQpnZXRTeW1ib2xzKGMoIkJSSy5BIiwgIkFUVCIpKQpgYGAKTm93IHlvdSBjYW4gbWFwIHRyb3VibGVzb21lIHRpY2tlcnMgdG8gbmV3IG5hbWVzIHdpdGggc2V0U3ltYm9sTG9va3VwKCkuCgojIEFsaWduaW5nIGRhdGEgd2l0aCBkaWZmZXJlbnQgcGVyaW9kaWNpdGllcwoKIyMgTWFraW5nIGlycmVndWxhciBkYXRhIHJlZ3VsYXIKCiMjIyBDcmVhdGUgYSB6ZXJvLXdpZHRoIGFuZCByZWd1bGFyIHh0cyBvYmplY3QKCkluIG9yZGVyIHRvIGNyZWF0ZSByZWd1bGFyIGRhdGEgZnJvbSBhbiBpcnJlZ3VsYXIgZGF0YSBzZXQsIHRoZSBmaXJzdCB0aGluZyB5b3UgbmVlZCBpcyBhIHJlZ3VsYXIgc2VxdWVuY2Ugb2YgZGF0ZS10aW1lcyB0aGF0IHNwYW4gdGhlIGRhdGVzIG9mIHlvdXIgaXJyZWd1bGFyIGRhdGEgc2V0LiBBICJyZWd1bGFyIiBzZXF1ZW5jZSBvZiBkYXRlLXRpbWVzIGhhcyBlcXVhbGx5LXNwYWNlZCB0aW1lIHBvaW50cy4KCkluIHRoaXMgZXhlcmNpc2UsIHlvdSB3aWxsIHVzZSB0aGUgaXJyZWd1bGFyX3h0cyBvYmplY3QgdG8gY3JlYXRlIGEgemVyby13aWR0aCB4dHMgb2JqZWN0IHRoYXQgaGFzIGEgcmVndWxhciBkYWlseSBpbmRleC4gQSB6ZXJvLXdpZHRoIHh0cyBvYmplY3QgaGFzIGFuIGluZGV4IG9mIGRhdGUtdGltZXMsIGJ1dCBubyBkYXRhIGNvbHVtbnMuCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQppcnJlZ3VsYXJfeHRzIDwtIHJiaW5kKHN0cnVjdHVyZShjKDRMLCAyMUwsIDFMLCAzNEwpLCAuRGltID0gYyg0TCwgMUwpLCBpbmRleCA9IHN0cnVjdHVyZShjKDE0NTE2OTI4MDAsIAoxNDUxOTUyMDAwLCAxNDUyMTI0ODAwLCAxNDUyNDcwNDAwKSwgdHpvbmUgPSAiVVRDIiwgdGNsYXNzID0gIkRhdGUiKSwgY2xhc3MgPSBjKCJ4dHMiLCAKInpvbyIpLCAuRGltbmFtZXMgPSBsaXN0KE5VTEwsICJkYXRhIikpKQpgYGAKCmBgYHtyfQojIEV4dHJhY3QgdGhlIHN0YXJ0IGRhdGUgb2YgdGhlIHNlcmllcwpzdGFydF9kYXRlIDwtIHN0YXJ0KGlycmVndWxhcl94dHMpCgojIEV4dHJhY3QgdGhlIGVuZCBkYXRlIG9mIHRoZSBzZXJpZXMKZW5kX2RhdGUgPC0gZW5kKGlycmVndWxhcl94dHMpCgojIENyZWF0ZSBhIHJlZ3VsYXIgZGF0ZSBzZXF1ZW5jZQpyZWd1bGFyX2luZGV4IDwtIHNlcShmcm9tID0gc3RhcnRfZGF0ZSwgdG8gPSBlbmRfZGF0ZSwgYnkgPSAiZGF5IikKCiMgQ3JlYXRlIGEgemVyby13aWR0aCB4dHMgb2JqZWN0CnJlZ3VsYXJfeHRzIDwtIHh0cyhzZXFfYWxvbmcocmVndWxhcl9pbmRleCksIG9yZGVyLmJ5ID0gcmVndWxhcl9pbmRleCkKYGBgCmBgYHtyfQpyZWd1bGFyX3h0cwpgYGAKIE1ha2luZyByZWd1bGFyIGRhdGUtdGltZSBzZXF1ZW5jZXMgaXMgdXNlZnVsIGluIG1hbnkgdGltZS1zZXJpZXMgYXBwbGljYXRpb25zLgoKIyMjIFVzZSBtZXJnZSB0byBtYWtlIGFuIGlycmVndWxhciBpbmRleCByZWd1bGFyCgpUaGUgcHJldmlvdXMgZXhlcmNpc2UgdGF1Z2h0IHlvdSBob3cgdG8gbWFrZSBhIHplcm8td2lkdGggeHRzIG9iamVjdCB3aXRoIGEgcmVndWxhciB0aW1lIGluZGV4LiBZb3UgY2FuIHVzZSB0aGUgemVyby13aWR0aCBvYmplY3QgdG8gcmVndWxhcml6ZSBhbiBpcnJlZ3VsYXIgeHRzIG9iamVjdC4KClRoZSByZWd1bGFyaXplZCBzZXJpZXMgdXN1YWxseSBoYXMgbWlzc2luZyB2YWx1ZXMgKE5BKSBiZWNhdXNlIHRoZSBpcnJlZ3VsYXIgZGF0YSBkb2VzIG5vdCBoYXZlIGEgdmFsdWUgZm9yIGFsbCBvYnNlcnZhdGlvbnMgaW4gdGhlIHJlZ3VsYXIgaW5kZXguIFRoaXMgZXhlcmNpc2Ugd2lsbCB0ZWFjaCB5b3UgaG93IHRvIGhhbmRsZSB0aGVzZSBtaXNzaW5nIHZhbHVlcyB3aGVuIHlvdSBtZXJnZSgpIHRoZSB0d28gc2VyaWVzLgoKYGBge3J9CiMgTWVyZ2UgaXJyZWd1bGFyX3h0cyBhbmQgcmVndWxhcl94dHMKbWVyZ2VkX3h0cyA8LSBtZXJnZShpcnJlZ3VsYXJfeHRzLCByZWd1bGFyX3h0cykKCiMgTG9vayBhdCB0aGUgZmlyc3QgZmV3IHJvd3Mgb2YgbWVyZ2VkX3h0cwpoZWFkKG1lcmdlZF94dHMpCgojIFVzZSB0aGUgZmlsbCBhcmd1bWVudCB0byBmaWxsIE5BIHdpdGggdGhlaXIgcHJldmlvdXMgdmFsdWUKbWVyZ2VkX2ZpbGxlZF94dHMgPC0gbWVyZ2UoaXJyZWd1bGFyX3h0cywgcmVndWxhcl94dHMsIGZpbGwgPSBuYS5sb2NmKQoKIyBMb29rIGF0IHRoZSBmaXJzdCBmZXcgcm93cyBvZiBtZXJnZWRfZmlsbGVkX3h0cwpoZWFkKG1lcmdlZF9maWxsZWRfeHRzKQpgYGAKRmlsbGluZyBmb3J3YXJkIGlzIGEgdXNlZnVsIG9wZXJhdGlvbiwgYnV0IGJlIGNhcmVmdWwgdG8gbWFrZSBzdXJlIGl0IGlzIHdoYXQgeW91IHdhbnQhCgojIyBBZ2dyZWdhdGluZyB0byBsb3dlciBmcmVxdWVuY3kKCiMjIyBBZ2dyZWdhdGUgZGFpbHkgZGF0YSBhbmQgbWVyZ2Ugd2l0aCBtb250aGx5IGRhdGEKClNvbWV0aW1lcyB0d28gc2VyaWVzIGhhdmUgdGhlIHNhbWUgcGVyaW9kaWN5LCBidXQgdXNlIGRpZmZlcmVudCBjb252ZW50aW9ucyB0byByZXByZXNlbnQgYSB0aW1lc3RhbXAuIEZvciBleGFtcGxlLCBtb250aGx5IHNlcmllcyBtYXkgYmUgdGltZXN0YW1wZWQgd2l0aCB0aGUgZmlyc3Qgb3IgbGFzdCBkYXRlIG9mIHRoZSBtb250aC4gVGhlIGRpZmZlcmVudCB0aW1lc3RhbXAgY29udmVudGlvbiBjYW4gY2F1c2UgbWFueSBOQSB3aGVuIHNlcmllcyBhcmUgbWVyZ2VkLiBUaGUgeWVhcm1vbiBjbGFzcyBmcm9tIHRoZSB6b28gcGFja2FnZSBoZWxwcyBzb2x2ZSB0aGlzIHByb2JsZW0uCgpJbiB0aGlzIGV4ZXJjaXNlLCB5b3Ugd2lsbCBhZ2dyZWdhdGUgdGhlIEZSRUQgZGFpbHkgRmVkIEZ1bmRzIHJhdGUgKERGRikgdG8gYSBtb250aGx5IHBlcmlvZGljeSBhbmQgbWVyZ2UgaXQgd2l0aCB0aGUgRlJFRCBtb250aGx5IEZlZCBGdW5kcyByYXRlIChGRURGVU5EUykuVGhlIERGRiBhZ2dyZWdhdGUgd2lsbCBiZSB0aW1lc3RhbXBlZCB3aXRoIHRoZSBsYXN0IHJvdyBvZiB0aGUgbW9udGgsIHdoaWxlIEZFREZVTkRTIGlzIHRpbWVzdGFtcGVkIHdpdGggdGhlIGZpcnN0IGRheSBvZiB0aGUgbW9udGguCmBgYHtyfQpnZXRTeW1ib2xzKGMoIkZFREZVTkRTIiwgIkRGRiIpLCBzcmMgPSAiRlJFRCIpCmBgYApgYGB7cn0KIyBBZ2dyZWdhdGUgREZGIHRvIG1vbnRobHkKbW9udGhseV9mZWRmdW5kcyA8LSBhcHBseS5tb250aGx5KERGRiwgbWVhbiwgbmEucm0gPSBUUlVFKQoKIyBDb252ZXJ0IGluZGV4IHRvIHllYXJtb24KaW5kZXgobW9udGhseV9mZWRmdW5kcykgPC0gYXMueWVhcm1vbihpbmRleChtb250aGx5X2ZlZGZ1bmRzKSkKCiMgTWVyZ2UgRkVERlVORFMgd2l0aCB0aGUgbW9udGhseSBhZ2dyZWdhdGUKbWVyZ2VkX2ZlZGZ1bmRzIDwtIG1lcmdlKEZFREZVTkRTLCBtb250aGx5X2ZlZGZ1bmRzKQoKIyBMb29rIGF0IHRoZSBmaXJzdCBmZXcgcm93cyBvZiB0aGUgbWVyZ2VkIG9iamVjdApoZWFkKG1lcmdlZF9mZWRmdW5kcykKYGBgCllvdSB3aWxsIG9mdGVuIG5lZWQgdG8gYWdncmVnYXRlIHRvIGEgbG93ZXIgZnJlcXVlbmN5IHRvIGFsaWduIG11bHRpcGxlIHRpbWUgc2VyaWVzLgoKIyMjIEFsaWduIHNlcmllcyB0byBmaXJzdCBhbmQgbGFzdCBkYXkgb2YgbW9udGgKClNvbWV0aW1lcyB5b3UgbWF5IG5vdCBiZSBhYmxlIHRvIHVzZSBjb252ZW5pZW5jZSBjbGFzc2VzIGxpa2UgeWVhcm1vbiB0byByZXByZXNlbnQgdGltZXN0YW1wcy4gVGhpcyBleGVyY2lzZSB3aWxsIHRlYWNoIHlvdSBob3cgdG8gbWFudWFsbHkgYWxpZ24gbWVyZ2VkIGRhdGEgdG8gdGhlIHRpbWVzdGFtcCByZXByZXNlbnRhdGlvbiB5b3UgcHJlZmVyLgoKRmlyc3QgeW91IG1lcmdlIHRoZSBsb3dlci1mcmVxdWVuY3kgZGF0YSB3aXRoIHRoZSBhZ2dyZWdhdGUgZGF0YSwgdGhlbiB1c2UgbmEubG9jZigpIHRvIGZpbGwgdGhlIE5BIGZvcndhcmQgKG9yIGJhY2t3YXJkLCB1c2luZyBmcm9tTGFzdCA9IFRSVUUpLiBUaGVuIHlvdSBjYW4gc3Vic2V0IHRoZSByZXN1bHQgdXNpbmcgdGhlIGluZGV4IG9mIHRoZSBvYmplY3Qgd2l0aCB0aGUgcmVwcmVzZW50YXRpb24geW91IHByZWZlci4KCmBgYHtyfQojIEFnZ3JlZ2F0ZSBERkYgdG8gbW9udGhseQptb250aGx5X2ZlZGZ1bmRzIDwtIGFwcGx5Lm1vbnRobHkoREZGLCBtZWFuLCBuYS5ybSA9IFRSVUUpCgojIE1lcmdlIEZFREZVTkRTIHdpdGggdGhlIG1vbnRobHkgYWdncmVnYXRlCm1lcmdlZF9mZWRmdW5kcyA8LSBtZXJnZShGRURGVU5EUywgbW9udGhseV9mZWRmdW5kcykKCiMgTG9vayBhdCB0aGUgZmlyc3QgZmV3IHJvd3Mgb2YgdGhlIG1lcmdlZCBvYmplY3QKaGVhZChtZXJnZWRfZmVkZnVuZHMpCmBgYApgYGB7cn0KIyBGaWxsIE5BIGZvcndhcmQKbWVyZ2VkX2ZlZGZ1bmRzX2xvY2YgPC0gbmEubG9jZihtZXJnZWRfZmVkZnVuZHMpCgojIEV4dHJhY3QgaW5kZXggdmFsdWVzIGNvbnRhaW5pbmcgbGFzdCBkYXkgb2YgbW9udGgKYWxpZ25lZF9sYXN0X2RheSA8LSBtZXJnZWRfZmVkZnVuZHNfbG9jZltpbmRleChtb250aGx5X2ZlZGZ1bmRzKV0KaGVhZChhbGlnbmVkX2xhc3RfZGF5KQojIEZpbGwgTkEgYmFja3dhcmQKbWVyZ2VkX2ZlZGZ1bmRzX2xvY2IgPC0gbmEubG9jZihtZXJnZWRfZmVkZnVuZHMsIGZyb21MYXN0ID0gVFJVRSkKCiMgRXh0cmFjdCBpbmRleCB2YWx1ZXMgY29udGFpbmluZyBmaXJzdCBkYXkgb2YgbW9udGgKYWxpZ25lZF9maXJzdF9kYXkgPC0gbWVyZ2VkX2ZlZGZ1bmRzX2xvY2JbaW5kZXgoRkVERlVORFMpXQpoZWFkKGFsaWduZWRfZmlyc3RfZGF5KQpgYGAKS25vd2luZyBob3cgdG8gbWFudWFsbHkgYWxpZ24gbWVyZ2VkIGRhdGEgd2lsbCBkZWZpbml0ZWx5IGNvbWUgaW4gaGFuZHkhCgojIyMgQWdncmVnYXRlIHRvIHdlZWtseSwgZW5kaW5nIG9uIFdlZG5lc2RheXMKCkluIHRoaXMgZXhlcmNpc2UsIHlvdSB3aWxsIGxlYXJuIGEgZ2VuZXJhbCBhZ2dyZWdhdGlvbiB0ZWNobmlxdWUgdG8gYWdncmVnYXRlIGRhaWx5IGRhdGEgdG8gd2Vla2x5LCBidXQgd2l0aCB3ZWVrcyBlbmRpbmcgb24gV2VkbmVzZGF5cy4gVGhpcyBpcyBvZnRlbiBkb25lIGluIHN0b2NrIG1hcmtldCByZXNlYXJjaCB0byBhdm9pZCBpbnRyYS13ZWVrIHNlYXNvbmFsaXR5LgoKWW91IGNhbiBzdXBwbHkgeW91ciBvd24gZW5kIHBvaW50cyB0byBwZXJpb2QuYXBwbHkoKSAodmVyc3VzIHVzaW5nIGVuZHBvaW50cygpKS4gUmVjYWxsIGVuZHBvaW50cygpIHJldHVybnMgbG9jYXRpb25zIG9mIHRoZSBsYXN0IG9ic2VydmF0aW9uIGluIGVhY2ggcGVyaW9kIHNwZWNpZmllZCBieSB0aGUgb24gYXJndW1lbnQuIFRoZSBmaXJzdCBhbmQgbGFzdCBlbGVtZW50cyBvZiB0aGUgcmVzdWx0IGFyZSBhbHdheXMgemVybyBhbmQgdGhlIHRvdGFsIG51bWJlciBvZiBvYnNlcnZhdGlvbnMsIHJlc3BlY3RpdmVseS4gVGhlIGVuZCBwb2ludHMgeW91IHBhc3MgdG8gcGVyaW9kLmFwcGx5KCkgbXVzdCBmb2xsb3cgdGhpcyBjb252ZW50aW9uLgoKYGBge3J9CiMgRXh0cmFjdCBpbmRleCB3ZWVrZGF5cwppbmRleF93ZWVrZGF5cyA8LSAuaW5kZXh3ZGF5KERGRikKCiMgRmluZCBsb2NhdGlvbnMgb2YgV2VkbmVzZGF5cwp3ZWRuZXNkYXlzIDwtIHdoaWNoKGluZGV4X3dlZWtkYXlzID09IDMpCgojIENyZWF0ZSBjdXN0b20gZW5kIHBvaW50cwplbmRfcG9pbnRzIDwtIGMoMCwgd2VkbmVzZGF5cywgbnJvdyhERkYpKQoKIyBDYWxjdWxhdGUgd2Vla2x5IG1lYW4gdXNpbmcgY3VzdG9tIGVuZCBwb2ludHMKd2Vla2x5X21lYW4gPC0gcGVyaW9kLmFwcGx5KERGRiwgZW5kX3BvaW50cywgbWVhbikKaGVhZCh3ZWVrbHlfbWVhbikKYGBgClRoZXJlIGFyZSBtYW55IHdheXMgdG8gY29udmVydCBhIHRpbWUgc2VyaWVzIHRvIGEgbG93ZXIgZnJlcXVlbmN5LgoKIyMgQWdncmVnYXRpbmcgYW5kIGNvbWJpbmluZyBpbnRyYWRheSBkYXRhCgojIyMgQ29tYmluZSBkYXRhIHRoYXQgaGF2ZSB0aW1lem9uZXMKClJlY2FsbCB0aGF0IHh0cyBvYmplY3RzIHN0b3JlIHRoZSB0aW1lIGluZGV4IGFzIHNlY29uZHMgc2luY2UgbWlkbmlnaHQsIDE5NzAtMDEtMDEgaW4gdGhlIFVUQyB0aW1lem9uZS4gbWVyZ2UoKSB1c2VzIHRoaXMgdW5kZXJseWluZyBpbmRleCBhbmQgcmV0dXJucyBhIHJlc3VsdCB3aXRoIHRoZSBmaXJzdCBvYmplY3QncyB0aW1lem9uZS4KClRoaXMgZXhlcmNpc2UgcHJvdmlkZXMgYW4gZXhhbXBsZS4gVGhlIHR3byBvYmplY3RzIGluIHlvdXIgd29ya3NwYWNlIGFyZSBpZGVudGljYWwgZXhjZXB0IGZvciB0aGUgaW5kZXggdGltZXpvbmUuIFRoZSBpbmRleCB2YWx1ZXMgYXJlIHRoZSBzYW1lIGluc3RhbmNlcyBpbiB0aW1lLCBidXQgbWVhc3VyZWQgaW4gZGlmZmVyZW50IGxvY2F0aW9ucy4gVGhlIGxvbmRvbiBvYmplY3QncyB0aW1lem9uZSBpcyBFdXJvcGUvTG9uZG9uIGFuZCB0aGUgY2hpY2FnbyBvYmplY3QncyB0aW1lem9uZSBpcyBBbWVyaWNhL0NoaWNhZ28uCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpsb25kb24gPC0gcmJpbmQoc3RydWN0dXJlKDE6NSwgLkRpbSA9IGMoNUwsIDFMKSwgaW5kZXggPSBzdHJ1Y3R1cmUoYygxMjYyNzU3NjAwLCAKMTI2MzIyNTYwMCwgMTI2MzIzNjQwMCwgMTI2MzI0MDAwMCwgMTI2MzQ1NjAwMCksIHR6b25lID0gIkV1cm9wZS9Mb25kb24iLCB0Y2xhc3MgPSBjKCJQT1NJWGN0IiwgCiJQT1NJWHQiKSksIGNsYXNzID0gYygieHRzIiwgInpvbyIpLCAuRGltbmFtZXMgPSBsaXN0KE5VTEwsICJMb25kb24iKSkpCgpjaGljYWdvIDwtIHJiaW5kKHN0cnVjdHVyZSgxOjUsIC5EaW0gPSBjKDVMLCAxTCksIGluZGV4ID0gc3RydWN0dXJlKGMoMTI2Mjc1NzYwMCwgCjEyNjMyMjU2MDAsIDEyNjMyMzY0MDAsIDEyNjMyNDAwMDAsIDEyNjM0NTYwMDApLCB0em9uZSA9ICJBbWVyaWNhL0NoaWNhZ28iLCB0Y2xhc3MgPSBjKCJQT1NJWGN0IiwgCiJQT1NJWHQiKSksIGNsYXNzID0gYygieHRzIiwgInpvbyIpLCAuRGltbmFtZXMgPSBsaXN0KE5VTEwsICJDaGljYWdvIikpKQpgYGAKYGBge3J9CiMgQ3JlYXRlIG1lcmdlZCBvYmplY3Qgd2l0aCBhIEV1cm9wZS9Mb25kb24gdGltZXpvbmUKdHpfbG9uZG9uIDwtIG1lcmdlKGxvbmRvbiwgY2hpY2FnbykKCiMgTG9vayBhdCB0el9sb25kb24gc3RydWN0dXJlCnN0cih0el9sb25kb24pCgojIENyZWF0ZSBtZXJnZWQgb2JqZWN0IHdpdGggYSBBbWVyaWNhL0NoaWNhZ28gdGltZXpvbmUKdHpfY2hpY2FnbyA8LSBtZXJnZShjaGljYWdvLCBsb25kb24pCgojIExvb2sgYXQgdHpfY2hpY2FnbyBzdHJ1Y3R1cmUKc3RyKHR6X2NoaWNhZ28pCmBgYAojIyMgTWFrZSBpcnJlZ3VsYXIgaW50cmFkYXktZGF5IGRhdGEgcmVndWxhcgoKRWFybGllciB5b3UgbGVhcm5lZCBob3cgdG8gY3JlYXRlIGEgcmVndWxhciBkYWlseSBzZXJpZXMgZnJvbSBpcnJlZ3VsYXIgZGFpbHkgZGF0YS4gTm93IHlvdSB3aWxsIGNyZWF0ZSByZWd1bGFyIGludHJhLWRheSBkYXRhIGZyb20gYW4gaXJyZWd1bGFyIHNlcmllcy4KCkludHJhLWRheSBmaW5hbmNpYWwgZGF0YSBvZnRlbiBkb2VzIG5vdCBzcGFuIGEgZnVsbCAyNCBob3VyIHBlcmlvZC4gTW9zdCBtYXJrZXRzIGFyZSB1c3VhbGx5IGNsb3NlZCBhdCBsZWFzdCBwYXJ0IG9mIHRoZSBkYXkuIFRoaXMgZXhlcmNpc2UgYXNzdW1lcyBtYXJrZXRzIG9wZW4gYXQgOUFNIGFuZCBjbG9zZSBhdCA0UE0gTW9uZGF5LUZyaWRheS4KCllvdXIgZGF0YSBtYXkgbm90IGhhdmUgYW4gb2JzZXJ2YXRpb24gZXhhY3RseSBhdCB0aGUgbWFya2V0IG9wZW4gYW5kL29yIGNsb3NlLiBTbywgeW91IHdvdWxkIG5vdCBiZSBhYmxlIHRvIHVzZSBzdGFydCgpIGFuZCBlbmQoKSBhcyB5b3UgY291bGQgd2l0aCB0aGUgZGFpbHkgZGF0YS4gWW91IG5lZWQgdG8gc3BlY2lmeSB0aGUgc3RhcnQgYW5kIGVuZCBkYXRlLXRpbWVzIHRvIGNyZWF0ZSB0aGlzIHJlZ3VsYXIgc2VxdWVuY2UuCgpUaGUgcmVndWxhciBkYXRlLXRpbWUgc2VxdWVuY2Ugd2lsbCBpbmNsdWRlIHBlcmlvZHMgd2hlbiBtYXJrZXRzIGFyZSBjbG9zZWQsIGJ1dCB5b3UgY2FuIHVzZSB4dHMnIHRpbWUtb2YtZGF5IHN1YnNldHRpbmcgdG8gZXh0cmFjdCBwZXJpb2RzIHRoZSBtYXJrZXQgaXMgb3Blbi4KYGBge3IgaW5jbHVkZT1GQUxTRX0KaXJyZWd1bGFyX3h0cyA8LSByYmluZChzdHJ1Y3R1cmUoMToyMCwgLkRpbSA9IGMoMjBMLCAxTCksIGluZGV4ID0gc3RydWN0dXJlKGMoMTI2MjYwNjQwMCwgCjEyNjI2MTM2MDAsIDEyNjI2MjgwMDAsIDEyNjI2NDk2MDAsIDEyNjI2NTMyMDAsIDEyNjI2NjA0MDAsIDEyNjI2ODIwMDAsIAoxMjYyNjg5MjAwLCAxMjYyNzQ2ODAwLCAxMjYyNzYxMjAwLCAxMjYyNzg2NDAwLCAxMjYyNzk3MjAwLCAxMjYyODE4ODAwLCAKMTI2Mjg1MTIwMCwgMTI2Mjg4MzYwMCwgMTI2Mjg4NzIwMCwgMTI2MjkwNTIwMCwgMTI2MjkxOTYwMCwgMTI2MjkzNDAwMCwgCjEyNjI5Mzc2MDApLCB0em9uZSA9ICIiLCB0Y2xhc3MgPSBjKCJQT1NJWGN0IiwgIlBPU0lYdCIpKSwgY2xhc3MgPSBjKCJ4dHMiLCAKInpvbyIpLCAuRGltbmFtZXMgPSBsaXN0KE5VTEwsICJkYXRhIikpKQpgYGAKCmBgYHtyfQojIENyZWF0ZSBhIHJlZ3VsYXIgZGF0ZS10aW1lIHNlcXVlbmNlCnJlZ3VsYXJfaW5kZXggPC0gc2VxKGFzLlBPU0lYY3QoIjIwMTAtMDEtMDQgMDk6MDAiKSwgYXMuUE9TSVhjdCgiMjAxMC0wMS0wOCAxNjowMCIpLCBieSA9ICIzMCBtaW4iKQoKIyBDcmVhdGUgYSB6ZXJvLXdpZHRoIHh0cyBvYmplY3QKcmVndWxhcl94dHMgPC0geHRzKHggPSBOVUxMLCBvcmRlci5ieSA9IHJlZ3VsYXJfaW5kZXgpCgojIE1lcmdlIGlycmVndWxhcl94dHMgYW5kIHJlZ3VsYXJfeHRzLCBmaWxsaW5nIE5BIHdpdGggdGhlaXIgcHJldmlvdXMgdmFsdWUKbWVyZ2VkX3h0cyA8LSBtZXJnZShpcnJlZ3VsYXJfeHRzLCByZWd1bGFyX3h0cywgZmlsbCA9IG5hLmxvY2YpCgojIFN1YnNldCB0byB0cmFkaW5nIGRheSAoOUFNIC0gNFBNKQp0cmFkZV9kYXkgPC0gbWVyZ2VkX3h0c1siVDA5OjAwL1QxNjowMCJdCnRyYWRlX2RheQpgYGAKTm93IHlvdSBrbm93IGhvdyB0byBzdWJzZXQgeW91ciBpbnRyYS1kYXkgZGF0YSB0byBvbmx5IGNvbnRhaW4gdGhlIHRyYWRpbmcgZGF5IQoKIyMjIEZpbGwgbWlzc2luZyB2YWx1ZXMgYnkgdHJhZGluZyBkYXkKClRoZSBwcmV2aW91cyBleGVyY2lzZSBjYXJyaWVkIHRoZSBsYXN0IG9ic2VydmF0aW9uIG9mIHRoZSBwcmlvciBkYXkgZm9yd2FyZCBpbnRvIHRoZSBmaXJzdCBvYnNlcnZhdGlvbiBvZiB0aGUgZm9sbG93aW5nIGRheS4gVGhpcyBleGVyY2lzZSB3aWxsIHNob3cgeW91IGhvdyB0byBmaWxsIG1pc3NpbmcgdmFsdWVzIGJ5IHRyYWRpbmcgZGF5LCB3aXRob3V0IHVzaW5nIHRoZSBwcmlvciBkYXkncyBmaW5hbCB2YWx1ZS4KCllvdSB3aWxsIHVzZSB0aGUgc2FtZSBzcGxpdC1sYXBwbHktcmJpbmQgcGFyYWRpZ20gZnJvbSB0aGUgSW50cm9kdWN0aW9uIHRvIHh0cyBhbmQgem9vIGNvdXJzZS4gRm9yIHJlZmVyZW5jZSwgdGhlIHBhdHRlcm4gaXMgYmVsb3cuCgogICAgeF9zcGxpdCA8LSBzcGxpdCh4LCBmID0gIm1vbnRocyIpCiAgICB4X2xpc3QgPC0gbGFwcGx5KHhfc3BsaXQsIGN1bW1heCkKICAgIHhfbGlzdF9yYmluZCA8LSBkby5jYWxsKHJiaW5kLCB4X2xpc3QpCgpSZWNhbGwgdGhhdCB0aGUgZG8uY2FsbChyYmluZCwgLi4uKSBzeW50YXggYWxsb3dzIHlvdSB0byBwYXNzIGEgbGlzdCBvZiBvYmplY3RzIHRvIHJiaW5kKCkgaW5zdGVhZCBvZiBoYXZpbmcgdG8gdHlwZSBhbGwgdGhlaXIgbmFtZXMuCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQp0cmFkZV9kYXkgPC0gcmJpbmQoc3RydWN0dXJlKGMoTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgMUwsIE5BLCBOQSwgTkEsIDJMLCBOQSwgTkEsIApOQSwgTkEsIDdMLCBOQSwgTkEsIE5BLCA4TCwgTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgCk5BLCBOQSwgTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgMTFMLCBOQSwgTkEsIE5BLCAKTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgTkEsIApOQSwgTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgTkEsIE5BLCBOQSwgTkEsIE5BKSwgY2xhc3MgPSBjKCJ4dHMiLCAKInpvbyIpLCBpbmRleCA9IHN0cnVjdHVyZShjKDEyNjI1OTU2MDAsIDEyNjI1OTc0MDAsIDEyNjI1OTkyMDAsIAoxMjYyNjAxMDAwLCAxMjYyNjAyODAwLCAxMjYyNjA0NjAwLCAxMjYyNjA2NDAwLCAxMjYyNjA4MjAwLCAxMjYyNjEwMDAwLCAKMTI2MjYxMTgwMCwgMTI2MjYxMzYwMCwgMTI2MjYxNTQwMCwgMTI2MjYxNzIwMCwgMTI2MjYxOTAwMCwgMTI2MjYyMDgwMCwgCjEyNjI2ODIwMDAsIDEyNjI2ODM4MDAsIDEyNjI2ODU2MDAsIDEyNjI2ODc0MDAsIDEyNjI2ODkyMDAsIDEyNjI2OTEwMDAsIAoxMjYyNjkyODAwLCAxMjYyNjk0NjAwLCAxMjYyNjk2NDAwLCAxMjYyNjk4MjAwLCAxMjYyNzAwMDAwLCAxMjYyNzAxODAwLCAKMTI2MjcwMzYwMCwgMTI2MjcwNTQwMCwgMTI2MjcwNzIwMCwgMTI2Mjc2ODQwMCwgMTI2Mjc3MDIwMCwgMTI2Mjc3MjAwMCwgCjEyNjI3NzM4MDAsIDEyNjI3NzU2MDAsIDEyNjI3Nzc0MDAsIDEyNjI3NzkyMDAsIDEyNjI3ODEwMDAsIDEyNjI3ODI4MDAsIAoxMjYyNzg0NjAwLCAxMjYyNzg2NDAwLCAxMjYyNzg4MjAwLCAxMjYyNzkwMDAwLCAxMjYyNzkxODAwLCAxMjYyNzkzNjAwLCAKMTI2Mjg1NDgwMCwgMTI2Mjg1NjYwMCwgMTI2Mjg1ODQwMCwgMTI2Mjg2MDIwMCwgMTI2Mjg2MjAwMCwgMTI2Mjg2MzgwMCwgCjEyNjI4NjU2MDAsIDEyNjI4Njc0MDAsIDEyNjI4NjkyMDAsIDEyNjI4NzEwMDAsIDEyNjI4NzI4MDAsIDEyNjI4NzQ2MDAsIAoxMjYyODc2NDAwLCAxMjYyODc4MjAwLCAxMjYyODgwMDAwLCAxMjYyOTQxMjAwLCAxMjYyOTQzMDAwLCAxMjYyOTQ0ODAwLCAKMTI2Mjk0NjYwMCwgMTI2Mjk0ODQwMCwgMTI2Mjk1MDIwMCwgMTI2Mjk1MjAwMCwgMTI2Mjk1MzgwMCwgMTI2Mjk1NTYwMCwgCjEyNjI5NTc0MDAsIDEyNjI5NTkyMDAsIDEyNjI5NjEwMDAsIDEyNjI5NjI4MDAsIDEyNjI5NjQ2MDAsIDEyNjI5NjY0MDAKKSwgdHpvbmUgPSAiIiwgdGNsYXNzID0gYygiUE9TSVhjdCIsICJQT1NJWHQiKSksIC5EaW0gPSBjKDc1TCwgCjFMKSwgLkRpbW5hbWVzID0gbGlzdChOVUxMLCAiZGF0YSIpKSkKYGBgCgpgYGB7cn0KIyBTcGxpdCB0cmFkZV9kYXkgaW50byBkYXlzCmRhaWx5X2xpc3QgPC0gc3BsaXQodHJhZGVfZGF5ICwgZiA9ICJkYXlzIikKCiMgVXNlIGxhcHBseSB0byBjYWxsIG5hLmxvY2YgZm9yIGVhY2ggZGF5IGluIGRhaWx5X2xpc3QKZGFpbHlfZmlsbGVkIDwtIGxhcHBseShkYWlseV9saXN0LCBGVU4gPSBuYS5sb2NmKQoKIyBVc2UgZG8uY2FsbCB0byByYmluZCB0aGUgcmVzdWx0cwpmaWxsZWRfYnlfdHJhZGVfZGF5IDwtIGRvLmNhbGwocmJpbmQsIGRhaWx5X2ZpbGxlZCkKZmlsbGVkX2J5X3RyYWRlX2RheQpgYGAKWW91IHVzZWQgYWR2YW5jZWQgZnVuY3Rpb25zIHRvIHRyYW5zZm9ybSBkYXRhIGZvciBlYWNoIHRyYWRpbmcgZGF5IQoKIyMjIEFnZ3JlZ2F0ZSBpcnJlZ3VsYXIgaW50cmFkYXktZGF5IGRhdGEKCkludHJhZGF5IGRhdGEgY2FuIGJlIGh1Z2UsIHdpdGggaHVuZHJlZHMgb2YgdGhvdXNhbmRzIG9mIG9ic2VydmF0aW9ucyBwZXIgZGF5LCBtaWxsaW9ucyBwZXIgbW9udGgsIGFuZCBodW5kcmVkcyBvZiBtaWxsaW9ucyBwZXIgeWVhci4gVGhlc2UgZGF0YSBzZXRzIG9mdGVuIG5lZWQgdG8gYmUgYWdncmVnYXRlZCBiZWZvcmUgeW91IGNhbiB3b3JrIHdpdGggdGhlbS4KCllvdSBsZWFybmVkIGhvdyB0byBhZ2dyZWdhdGUgZGFpbHkgZGF0YSBpbiB0aGUgSW50cm9kdWN0aW9uIHRvIHh0cyBhbmQgem9vIGNvdXJzZS4gVGhpcyBleGVyY2lzZSB3aWxsIHVzZSB0by5wZXJpb2QoKSB0byBhZ2dyZWdhdGUgaW50cmFkYXkgZGF0YSB0byBhbiBPSExDIHNlcmllcy4gWW91IG9mdGVuIG5lZWQgdG8gc3BlY2lmeSBib3RoIHBlcmlvZCBhbmQgayBhcmd1bWVudHMgdG8gYWdncmVnYXRlIGludHJhZGF5IGRhdGEuCgpgYGB7cn0KbG9hZCgiREMuUkRhdGEiKQoKZGNfaW50cmFkYXkgPC0gRENbLDFdCmBgYApgYGB7cn0KIyBDb252ZXJ0IHJhdyBwcmljZXMgdG8gNS1zZWNvbmQgcHJpY2VzCnh0c181c2VjIDwtIHRvLnBlcmlvZChkY19pbnRyYWRheSwgcGVyaW9kID0gInNlY29uZHMiLCBrID0gNSkKaGVhZCh4dHNfNXNlYykKIyBDb252ZXJ0IHJhdyBwcmljZXMgdG8gMTAtbWludXRlIHByaWNlcwp4dHNfMTBtaW4gPC0gdG8ucGVyaW9kKGRjX2ludHJhZGF5LCBwZXJpb2QgPSAibWludXRlcyIsIGsgPSAxMCkKaGVhZCh4dHNfMTBtaW4pCiMgQ29udmVydCByYXcgcHJpY2VzIHRvIDEtaG91ciBwcmljZXMKeHRzXzFob3VyIDwtIHRvLnBlcmlvZChkY19pbnRyYWRheSwgcGVyaW9kID0gImhvdXJzIiwgayA9IDEpCmhlYWQoeHRzXzFob3VyKQpgYGAKIyBJbXBvcnRpbmcgdGV4dCBkYXRhLCBhbmQgYWRqdXN0aW5nIGZvciBjb3Jwb3JhdGUgYWN0aW9ucwoKIyMgSW1wb3J0aW5nIHRleHQgZmlsZXMKCiMjIyBJbXBvcnQgd2VsbC1mb3JtYXR0ZWQgZGFpbHkgT0hMQyBkYXRhCgpZb3UgY2FuIHVzZSBnZXRTeW1ib2xzKCkgdG8gaW1wb3J0IGEgd2VsbC1mb3JtYXR0ZWQgQ1NWLiBJbiB0aGlzIGNhc2UsIHdlbGwtZm9ybWF0dGVkIG1lYW5zIHRoZSBmaWxlIGNvbnRhaW5zIGRhdGEgZm9yIGEgc2luZ2xlIGluc3RydW1lbnQgd2l0aCBkYXRlLCBvcGVuLCBoaWdoLCBsb3csIGNsb3NlLCB2b2x1bWUsIGFuZCBhZGp1c3RlZCBjbG9zZSBjb2x1bW5zLCBpbiB0aGF0IG9yZGVyLiBZb3UgbWlnaHQgaGF2ZSBub3RpY2VkIHRoYXQgdGhpcyBpcyB0aGUgc2FtZSBmb3JtYXQgYXMgZ2V0U3ltYm9scygpIHJldHVybnMgd2hlbiB5b3UgZG93bmxvYWQgZGF0YSBmcm9tIGludGVybmV0IHNvdXJjZXMuCgpnZXRTeW1ib2xzKCkgYWxsb3dzIHlvdSB0byB1c2UgYSBkaXJlY3Rvcnkgb2YgQ1NWIGZpbGVzIGFzIGEgc291cmNlIChsaWtlIFlhaG9vIEZpbmFuY2UgYW5kIEZSRUQpLiBJbiB0aGlzIGV4ZXJjaXNlLCB5b3Ugd2lsbCBiZSB1c2luZyBBTVpOLmNzdiBpbiB5b3VyIHdvcmtpbmcgZGlyZWN0b3J5LiBJdCBjb250YWlucyBzb21lIHJhbmRvbWl6ZWQgQW1hem9uLmNvbSBkYXRhIGZyb20gdGhlIGZpcnN0IGhhbGYgb2YgMjAwMi4gWW91IGNhbiB1c2UgZGlyKCkgdG8gc2VlIHRoZSBmaWxlIGluIHlvdXIgd29ya2luZyBkaXJlY3RvcnkuCmBgYHtyfQojIExvYWQgQU1aTi5jc3YKZ2V0U3ltYm9scygiQU1aTiIsIHNyYyA9ICJjc3YiKQoKIyBMb29rIGF0IEFNWk4gc3RydWN0dXJlCnN0cihBTVpOKQpgYGAKIyMjIEltcG9ydCB0ZXh0IGZpbGVzIGluIG90aGVyIGZvcm1hdHMKClRoZSBwcmV2aW91cyBleGVyY2lzZSB0YXVnaHQgeW91IGhvdyB0byBpbXBvcnQgd2VsbC1mb3JtYXR0ZWQgQ1NWIGRhdGEgdXNpbmcgZ2V0U3ltYm9scygpLiBVbmZvcnR1bmF0ZWx5LCBtb3N0IGRhdGEgYXJlIG5vdCB3ZWxsLWZvcm1hdHRlZC4KClRoZSB6b28gcGFja2FnZSBwcm92aWRlcyBzZXZlcmFsIGZ1bmN0aW9ucyB0byBpbXBvcnQgdGV4dCBmaWxlcyBhcyB6b28gb2JqZWN0cy4gVGhlIG1haW4gZnVuY3Rpb24gaXMgcmVhZC56b28oKSwgd2hpY2ggd3JhcHMgcmVhZC50YWJsZSgpLiBUaGUgeHRzIGNsYXNzIGV4dGVuZHMgem9vLCBzbyB5b3UgY2FuIGVhc2lseSBjb252ZXJ0IHRoZSByZXN1bHQgb2YgcmVhZC56b28oKSBpbnRvIGFuIHh0cyBvYmplY3QgYnkgdXNpbmcgYXMueHRzKCkuCgpgYGB7cn0KIyBJbXBvcnQgQU1aTi5jc3YgdXNpbmcgcmVhZC56b28KYW16bl96b28gPC0gcmVhZC56b28oIkFNWk4uY3N2Iiwgc2VwID0gIiwiLCBoZWFkZXIgPSBUUlVFKQoKIyBDb252ZXJ0IHRvIHh0cwphbXpuX3h0cyA8LSBhcy54dHMoYW16bl96b28pCgojIExvb2sgYXQgdGhlIGZpcnN0IGZldyByb3dzIG9mIGFtem5feHRzCmhlYWQoYW16bl94dHMpCmBgYApBcyB5b3Ugd2lsbCBzZWUsIHJlYWQuem9vKCkgaXMgYSB2ZXJ5IGZsZXhpYmxlIGltcG9ydCBmdW5jdGlvbiBmb3IgdGltZSBzZXJpZXMuCgojIyMgSGFuZGxlIGRhdGUgYW5kIHRpbWUgaW4gc2VwYXJhdGUgY29sdW1ucwoKcmVhZC56b28oKSBtYWtlcyBpdCBlYXN5IHRvIGltcG9ydCBkYXRhIHdoZW4gdGhlIGRhdGUgYW5kIHRpbWUgYXJlIGluIHNlcGFyYXRlIGNvbHVtbnMuIFRoZSBpbmRleC5jb2x1bW4gYXJndW1lbnQgYWxsb3dzIHlvdSB0byBzcGVjaWZ5IHRoZSBuYW1lIG9yIG51bWJlciBvZiB0aGUgY29sdW1uKHMpIGNvbnRhaW5pbmcgdGhlIGluZGV4IGRhdGEuIFRoYXQncyBhbGwgeW91IG5lZWQgdG8gZG8gaWYgdGhlIGRhdGUgYW5kIHRpbWUgYXJlIHNwZWNpZmllZCBpbiB0aGUgc3RhbmRhcmQgZm9ybWF0ICgiJVktJW0tJWQiIGZvciBkYXRlLCBhbmQgIiVIOiVNOiVTIiBmb3IgdGltZSkuCgpJbiB0aGlzIGV4ZXJjaXNlLCB5b3Ugd2lsbCB1c2UgdGhlIGluZGV4LmNvbHVtbiBhcmd1bWVudCB0byBzcGVjaWZ5IHRoZSBkYXRlIGFuZCB0aW1lIGNvbHVtbnMgb2YgdGhlIGZpbGUuIFlvdXIgd29ya2luZyBkaXJlY3RvcnkgaGFzIGEgZmlsZSBuYW1lZCBVTkUuY3N2IHRoYXQgY29udGFpbnMgc29tZSA1LW1pbnV0ZSBPSExDIGRhdGEgZm9yIHRoZSBlbmVyZ3kgY29tcGFueSwgVW5yb24uIFlvdSB3aWxsIHN0aWxsIHVzZSByZWFkLmNzdigpIGZpbmQgdGhlIGNvbHVtbiBuYW1lcyBvZiB0aGUgZGF0ZSBhbmQgdGltZSBjb2x1bW5zLgpgYGB7cn0KIyBSZWFkIGRhdGEgd2l0aCByZWFkLmNzdgp1bmVfZGF0YSA8LSByZWFkLmNzdigiVU5FLmNzdiIsIG5yb3dzID0gNSkKCiMgTG9vayBhdCB0aGUgc3RydWN0dXJlIG9mIHVuZV9kYXRhCnN0cih1bmVfZGF0YSkKYGBgCmBgYHtyfQojIFJlYWQgZGF0YSB3aXRoIHJlYWQuem9vLCBzcGVjaWZ5aW5nIGluZGV4IGNvbHVtbnMKdW5lX3pvbyA8LSByZWFkLnpvbygiVU5FLmNzdiIsIGluZGV4LmNvbHVtbiA9IGMoIkRhdGUiLCAiVGltZSIpLCBzZXAgPSAiLCIsIGhlYWRlciA9IFRSVUUpCgojIExvb2sgYXQgZmlyc3QgZmV3IHJvd3Mgb2YgZGF0YQpoZWFkKHVuZV96b28pCmBgYApUaGUgaW5kZXguY29sdW1uIGFyZ3VtZW50IGlzIGdyZWF0IGlmIHlvdXIgZGF0ZXMgYW5kIHRpbWVzIGFyZSBpbiBzZXBhcmF0ZSBjb2x1bW5zIQoKIyMjIFJlYWQgdGV4dCBmaWxlIGNvbnRhaW5pbmcgbXVsdGlwbGUgaW5zdHJ1bWVudHMKClRoZSBwcmV2aW91cyBleGVyY2lzZXMgd29yayBpZiBlYWNoIGZpbGUgY29udGFpbnMgb25seSBvbmUgaW5zdHJ1bWVudC4gU29tZSBzb2Z0d2FyZSBhbmQgZGF0YSB2ZW5kb3JzIG1heSBwcm92aWRlIGRhdGEgZm9yIGFsbCBpbnN0cnVtZW50cyBpbiBvbmUgZmlsZS4gVGhpcyBleGVyY2lzZSB3aWxsIHRlYWNoIHlvdSBob3cgdG8gaW1wb3J0IGEgZmlsZSB0aGF0IGNvbnRhaW5zIG11bHRpcGxlIGluc3RydW1lbnRzLgoKT25jZSBhZ2FpbiwgeW91IGNhbiB1c2UgcmVhZC56b28oKS4gVGhpcyB0aW1lIHlvdSB3aWxsIGJlIHVzaW5nIGl0cyBzcGxpdCBhcmd1bWVudCwgd2hpY2ggYWxsb3dzIHlvdSB0byBzcGVjaWZ5IHRoZSBuYW1lIG9yIG51bWJlciBvZiB0aGUgY29sdW1ucyhzKSB0aGF0IGNvbnRhaW4gdGhlIHZhcmlhYmxlcyB0aGF0IGlkZW50aWZ5IHVuaXF1ZSBvYnNlcnZhdGlvbnMuCgpUaGUgdHdvX3N5bWJvbHMuY3N2IGZpbGUgaW4geW91ciB3b3JraW5nIGRpcmVjdG9yeSBjb250YWlucyBiaWQvYXNrIGRhdGEgZm9yIHR3byBpbnN0cnVtZW50cywgd2hlcmUgZWFjaCByb3cgaGFzIG9uZSBiaWQgb3IgYXNrIG9ic2VydmF0aW9uIGZvciBvbmUgaW5zdHJ1bWVudC4gWW91IHdpbGwgdXNlIHRoZSBzcGxpdCBhcmd1bWVudCB0byBpbXBvcnQgdGhlIGRhdGEgaW50byBhbiBvYmplY3QgdGhhdCBoYXMgYm90aCBiaWQgYW5kIGFzayBwcmljZXMgZm9yIGJvdGggaW5zdHJ1bWVudHMgb24gb25lIHJvdy4KYGBge3J9CiMgUmVhZCBkYXRhIHdpdGggcmVhZC5jc3YKdHdvX3N5bWJvbHNfZGF0YSA8LSByZWFkLmNzdigidHdvX3N5bWJvbHMuY3N2IiwgbnJvd3MgPSA1KQoKIyBMb29rIGF0IHRoZSBzdHJ1Y3R1cmUgb2YgdHdvX3N5bWJvbHNfZGF0YQpzdHIodHdvX3N5bWJvbHNfZGF0YSkKYGBgCmBgYHtyfQojIFJlYWQgZGF0YSB3aXRoIHJlYWQuem9vLCBzcGVjaWZ5aW5nIGluZGV4IGNvbHVtbnMKdHdvX3N5bWJvbHNfem9vIDwtIHJlYWQuem9vKCJ0d29fc3ltYm9scy5jc3YiLCBzcGxpdCA9IGMoIlN5bWJvbCIsICJUeXBlIiksIHNlcCA9ICIsIiwgaGVhZGVyID0gVFJVRSkKCiMgTG9vayBhdCBmaXJzdCBmZXcgcm93cyBvZiBkYXRhCmhlYWQodHdvX3N5bWJvbHNfem9vKQpgYGAKIyMgQ2hlY2tpbmcgZm9yIHdlaXJkbmVzcwoKIyMjIEhhbmRsZSBtaXNzaW5nIHZhbHVlcwoKSW4gY2hhcHRlciAzLCB5b3UgdXNlZCBuYS5sb2NmKCkgdG8gZmlsbCBtaXNzaW5nIHZhbHVlcyB3aXRoIHRoZSBwcmV2aW91cyBub24tbWlzc2luZyB2YWx1ZS4gWW91IGNhbiB1c2UgaW50ZXJwb2xhdGlvbiB3aGVuIGNhcnJ5aW5nIHRoZSBwcmV2aW91cyB2YWx1ZSBmb3J3YXJkIGlzbid0IGFwcHJvcHJpYXRlLiBJbiB0aGlzIGV4ZXJjaXNlLCB5b3Ugd2lsbCBleHBsb3JlIHR3byBpbnRlcnBvbGF0aW9uIG1ldGhvZHM6IGxpbmVhciBhbmQgc3BsaW5lLgoKTGluZWFyIGludGVycG9sYXRpb24gY2FsY3VsYXRlcyB2YWx1ZXMgdGhhdCBsaWUgb24gYSBsaW5lIGJldHdlZW4gdHdvIGtub3duIGRhdGEgcG9pbnRzLiBUaGlzIGlzIGEgZ29vZCBjaG9pY2UgZm9yIGZhaXJseSBsaW5lYXIgZGF0YSwgbGlrZSBhIHNlcmllcyB3aXRoIGEgc3Ryb25nIHRyZW5kLiBTcGxpbmUgaW50ZXJwb2xhdGlvbiBpcyBtb3JlIGFwcHJvcHJpYXRlIGZvciBzZXJpZXMgd2l0aG91dCBhIHN0cm9uZyB0cmVuZCwgYmVjYXVzZSBpdCBjYWxjdWxhdGVzIGEgbm9uLWxpbmVhciBhcHByb3hpbWF0aW9uIHVzaW5nIG11bHRpcGxlIGRhdGEgcG9pbnRzLgoKVXNlIHRoZXNlIHR3byBtZXRob2RzIHRvIGludGVycG9sYXRlIHRoZSB0aHJlZSBtaXNzaW5nIHZhbHVlcyBmb3IgdGhlIDEwLXllYXIgVHJlYXN1cnkgcmF0ZSBpbiB0aGUgb2JqZWN0IERHUzEwLiBUaGVuIGNvbXBhcmUgdGhlIHJlc3VsdHMgd2l0aCB0aGUgb3V0cHV0IG9mIG5hLmxvY2YoKS4KCmBgYHtyIGluY2x1ZGU9RkFMU0V9CkRHUzEwIDwtIHJiaW5kKHN0cnVjdHVyZShjKDQuOTQsIDQuODUsIDQuNzgsIDQuNzksIDQuODUsIE5BLCA0Ljk5LCA0Ljk3LCA0Ljg2LCAKNC44LCA0Ljg0LCBOQSwgTkEsIDQuNjQsIDQuNTcsIDQuNjMpLCBjbGFzcyA9IGMoInh0cyIsICJ6b28iKSwgc3JjID0gIkZSRUQiLCB1cGRhdGVkID0gc3RydWN0dXJlKDE1OTU5NTk3ODkuMjk2NzgsIGNsYXNzID0gYygiUE9TSVhjdCIsIAoiUE9TSVh0IikpLCBpbmRleCA9IHN0cnVjdHVyZShjKDk5ODg3MDQwMCwgOTk4OTU2ODAwLCA5OTkwNDMyMDAsIAo5OTkxMjk2MDAsIDk5OTIxNjAwMCwgOTk5NDc1MjAwLCA5OTk1NjE2MDAsIDk5OTY0ODAwMCwgOTk5NzM0NDAwLCAKOTk5ODIwODAwLCAxMDAwMDgwMDAwLCAxMDAwMTY2NDAwLCAxMDAwMjUyODAwLCAxMDAwMzM5MjAwLCAxMDAwNDI1NjAwLCAKMTAwMDY4NDgwMCksIHR6b25lID0gIlVUQyIsIHRjbGFzcyA9ICJEYXRlIiksIC5EaW0gPSBjKDE2TCwgMUwKKSwgLkRpbW5hbWVzID0gbGlzdChOVUxMLCAiREdTMTAiKSkpCmBgYAoKYGBge3J9CiMgZmlsbCBOQSB1c2luZyBsYXN0IG9ic2VydmF0aW9uIGNhcnJpZWQgZm9yd2FyZApsb2NmIDwtIG5hLmxvY2YoREdTMTApCgojIGZpbGwgTkEgdXNpbmcgbGluZWFyIGludGVycG9sYXRpb24KYXBwcm94IDwtIG5hLmFwcHJveChER1MxMCkKCiMgZmlsbCBOQSB1c2luZyBzcGxpbmUgaW50ZXJwb2xhdGlvbgpzcGxpbmUgPC0gbmEuc3BsaW5lKERHUzEwKQoKIyBtZXJnZSBpbnRvIG9uZSBvYmplY3QKbmFfZmlsbGVkIDwtIG1lcmdlKGxvY2YsIGFwcHJveCwgc3BsaW5lKQoKIyBwbG90IGNvbWJpbmVkIG9iamVjdApwbG90KG5hX2ZpbGxlZCwgY29sID0gYygiYmxhY2siLCAicmVkIiwgImdyZWVuIikpCmBgYAojIyMgVmlzdWFsaXplIGltcG9ydGVkIGRhdGEKCkl0J3MgaW1wb3J0YW50IHRvIGNoZWNrIHlvdXIgaW1wb3J0ZWQgZGF0YSBpcyByZWFzb25hYmxlLiBBIHBsb3QgaXMgYSBxdWljayBhbmQgZWFzeSB3YXkgdG8gc3BvdCBvZGRpdGllcy4gSW4gdGhpcyBleGVyY2lzZSwgeW91IHdpbGwgdXNlIHRoZSBwbG90KCkgZnVuY3Rpb24gdG8gdmlzdWFsaXplIHNvbWUgQUFQTCBkYXRhIGZyb20gWWFob28gRmluYW5jZS4KCkEgc3RvY2sgc3BsaXQgY2F1c2VkIGEgaHVnZSBwcmljZSBjaGFuZ2UgaW4gSnVuZSAyMDE0LiBBcHBsZSBzaW11bHRhbmVvdXNseSBpbmNyZWFzZWQgdGhlIG51bWJlciBvZiBzaGFyZXMgb3V0c3RhbmRpbmcgYW5kIGRlY3JlYXNlZCBpdHMgc3RvY2sgcHJpY2UsIGxlYXZpbmcgdGhlIGNvbXBhbnkgdmFsdWUgdW5jaGFuZ2VkLiBGb3IgZXhhbXBsZSwgYSAyLWZvci0xIHNwbGl0IHdvdWxkIGRvdWJsZSB0aGUgc2hhcmVzIG91dHN0YW5kaW5nLCBhbmQgcmVkdWNlIHRoZSBzdG9jayBwcmljZSBieSAxLzIuCgpZb3Ugd2lsbCBhbHNvIHVzZSB0aGUgcXVhbnRtb2QgZXh0cmFjdG9yIGZ1bmN0aW9ucyBDbCgpIGFuZCBBZCgpIHRvIGFjY2VzcyB0aGUgY2xvc2UgYW5kIGFkanVzdGVkIGNsb3NlIGNvbHVtbnMsIHJlc3BlY3RpdmVseS4gWWFob28gRmluYW5jZSBwcm92aWRlcyB0aGUgc3BsaXQtIGFuZC9vciBkaXZpZGVuZC1hZGp1c3RlZCBjbG9zZSBjb2x1bW4uCmBgYHtyfQpnZXRTeW1ib2xzKCJBQVBMIiwgc3JjPSd5YWhvbycsIGZyb20gPSAiMjAwNy0wMS0wMSIsIHRvID0gIjIwMTctMDktMTciKQpgYGAKYGBge3J9CmhlYWQoQUFQTCkKYGBgCmBgYHtyfQojIExvb2sgYXQgdGhlIGxhc3QgZmV3IHJvd3Mgb2YgQUFQTCBkYXRhCnRhaWwoQUFQTCkKCiMgUGxvdCBjbG9zZSBwcmljZQpwbG90KEFBUEwkQUFQTC5DbG9zZSkKCiMgUGxvdCBhZGp1c3RlZCBjbG9zZSBwcmljZQpwbG90KEFBUEwkQUFQTC5BZGp1c3RlZCkKYGBgCiMjIyBDcm9zcyByZWZlcmVuY2Ugc291cmNlcwoKSW4gdGhpcyBleGVyY2lzZSwgeW91IHdpbGwgY3Jvc3MtcmVmZXJlbmNlIHRoZSBBQVBMIHJhdyBwcmljZSBkYXRhIGZyb20gdGhlIHByZXZpb3VzIGV4ZXJjaXNlIHdpdGggQUFQTCBkYXRhIGZyb20gYW5vdGhlciBzb3VyY2UuCgpUaGUgbmV3IGRhdGEgaXMgYWxyZWFkeSBhZGp1c3RlZCBmb3Igc3BsaXRzLCBidXQgbm90IGRpdmlkZW5kcy4gU28gdGhlIGNsb3NlIHByaWNlcyBmcm9tIHRoZSBuZXcgZGF0YSB3b24ndCBhbGlnbiBjbG9zZWx5IHdpdGggdGhlIGFkanVzdGVkIGNsb3NlIHByaWNlcyBmcm9tIHRoZSBwcmV2aW91cyBleGVyY2lzZSAod2hpY2ggYXJlIGFkanVzdGVkIGZvciBib3RoIHNwbGl0cyBhbmQgZGl2aWRlbmRzKS4gWW91IHdpbGwgbGVhcm4gbW9yZSBhYm91dCB0aGUgYWRqdXN0bWVudCBwcm9jZXNzIGluIHRoZSBuZXh0IHZpZGVvLgoKWW91IHdpbGwgY29tcGFyZSByYXcsIHVuYWRqdXN0ZWQgQUFQTCBkYXRhIHdpdGggc3BsaXQtYWRqdXN0ZWQgQUFQTCBkYXRhLiBUaGUgZGF0YSBoYXZlIGFscmVhZHkgYmVlbiBsb2FkZWQgdG8geW91ciB3b3Jrc3BhY2UgaW4gYWFwbF9yYXcgYW5kIGFhcGxfc3BsaXRfYWRqdXN0ZWQsIHJlc3BlY3RpdmVseS4KCiAgICAjIExvb2sgYXQgZmlyc3QgZmV3IHJvd3Mgb2YgYWFwbF9yYXcKICAgIGhlYWQoYWFwbF9yYXcpCiAgICAKICAgICMgTG9vayBhdCBmaXJzdCBmZXcgcm93cyBvZiBhYXBsX3NwbGl0X2FkanVzdGVkCiAgICBoZWFkKGFhcGxfc3BsaXRfYWRqdXN0ZWQpCiAgICAKICAgICMgUGxvdCBkaWZmZXJlbmNlIGJldHdlZW4gYWRqdXN0ZWQgY2xvc2UgYW5kIHNwbGl0LWFkanVzdGVkIGNsb3NlCiAgICBwbG90KEFkKGFhcGxfcmF3JEFBUEwuQWRqdXN0ZWQpIC0gQ2woYWFwbF9zcGxpdF9hZGp1c3RlZCRBQVBMLkNsb3NlKSkKICAgIAogICAgIyBQbG90IGRpZmZlcmVuY2UgYmV0d2VlbiB2b2x1bWUgZnJvbSB0aGUgcmF3IGFuZCBzcGxpdC1hZGp1c3RlZCBzb3VyY2VzCiAgICBwbG90KFZvKGFhcGxfcmF3JEFBUEwuVm9sdW1lKSAtIFZvKGFhcGxfc3BsaXRfYWRqdXN0ZWQkQUFQTC5Wb2x1bWUpKQoKVGhlIHZvbHVtZXMgYWdyZWUgb24gbW9zdCAoYnV0IG5vdCBhbGwpIGRheXMsIHdoZXJlYXMgdGhlIGNsb3NlIHByaWNlcyBhcmUgY29tcGxldGVseSBkaWZmZXJlbnQuCgojIyBBZGp1c3RpbmcgZm9yIGNvcnBvcmF0ZSBhY3Rpb25zCgojIyMgQWRqdXN0IGZvciBzdG9jayBzcGxpdHMgYW5kIGRpdmlkZW5kcwoKU3RvY2sgc3BsaXRzIGNhbiBjcmVhdGUgbGFyZ2UgaGlzdG9yaWNhbCBwcmljZSBjaGFuZ2VzIGV2ZW4gdGhvdWdoIHRoZXkgZG8gbm90IGNoYW5nZSB0aGUgdmFsdWUgb2YgdGhlIGNvbXBhbnkuIFNvLCB5b3UgbXVzdCBhZGp1c3QgYWxsIHByZS1zcGxpdCBwcmljZXMgaW4gb3JkZXIgdG8gY2FsY3VsYXRlIGhpc3RvcmljYWwgcmV0dXJucyBjb3JyZWN0bHkuCgpTaW1pbGFybHksIHlvdSBtdXN0IGFkanVzdCBhbGwgcHJlLWRpdmlkZW5kIHByaWNlcy4gRGl2aWRlbmRzIGRvIHJlZHVjZSB0aGUgY29tcGFueSdzIHZhbHVlIGJ5IHRoZSBhbW91bnQgb2YgdGhlIGRpdmlkZW5kIHBheW1lbnQsIGJ1dCB0aGUgaW52ZXN0b3IncyByZXR1cm4gaXNuJ3QgYWZmZWN0ZWQgYmVjYXVzZSB0aGV5IHJlY2VpdmUgdGhlIG9mZnNldHRpbmcgZGl2aWRlbmQgcGF5bWVudC4KCkluIHRoaXMgZXhlcmNpc2UsIHlvdSB3aWxsIGxlYXJuIGhvdyB0byB1c2UgdGhlIGFkanVzdE9ITEMoKSBmdW5jdGlvbiB0byBhZGp1c3QgcmF3IGhpc3RvcmljYWwgT0hMQyBwcmljZXMgZm9yIHNwbGl0cyBhbmQgZGl2aWRlbmRzLCBzbyBoaXN0b3JpY2FsIHJldHVybnMgY2FuIGJlIGNhbGN1bGF0ZWQgYWNjdXJhdGVseS4KCllhaG9vIEZpbmFuY2UgcHJvdmlkZXMgcmF3IHByaWNlcyBhbmQgYSBzcGxpdC0gYW5kIGRpdmlkZW5kLWFkanVzdGVkIGNsb3NlIGNvbHVtbi4gVGhlIG91dHB1dCBvZiBhZGp1c3RPSExDKCkgc2hvdWxkIG1hdGNoIFlhaG9vJ3MgYWRqdXN0ZWQgY2xvc2UgY29sdW1uLiBBQVBMIGRhdGEgZnJvbSBZYWhvbyBGaW5hbmNlIGlzIGFscmVhZHkgbG9hZGVkIGluIHlvdXIgd29ya3NwYWNlLgoKV2hpbGUgbm90IG5lY2Vzc2FyeSB0byBjb21wbGV0ZSB0aGlzIGV4ZXJjaXNlLCBZYWhvbyBGaW5hbmNlIHByb3ZpZGVzIGFuIFthY2Nlc3NpYmxlIGV4YW1wbGVdKGh0dHBzOi8vaGVscC55YWhvby5jb20va2IvZmluYW5jZS9TTE4yMzExLmh0bWwpIG9mIHRoZSBhZGp1c3RlZCBjbG9zZSBjYWxjdWxhdGlvbiwgaWYgeW91J3JlIGludGVyZXN0ZWQgaW4gbGVhcm5pbmcgbW9yZS4KCmBgYHtyfQojIExvb2sgYXQgZmlyc3QgZmV3IHJvd3Mgb2YgQUFQTApoZWFkKEFBUEwpCgojIEFkanVzdCBBQVBMIGZvciBzcGxpdHMgYW5kIGRpdmlkZW5kcwphYXBsX2FkanVzdGVkIDwtIGFkanVzdE9ITEMoQUFQTCkKCiMgTG9vayBhdCBmaXJzdCBmZXcgcm93cyBvZiBhYXBsX2FkanVzdGVkCmhlYWQoYWFwbF9hZGp1c3RlZCkKYGBgCiMjIyBEb3dubG9hZCBzcGxpdCBhbmQgZGl2aWRlbmQgZGF0YQpJbiB0aGUgcHJldmlvdXMgZXhlcmNpc2UsIHlvdSB1c2VkIGFkanVzdE9ITEMoKSB0byBhZGp1c3QgcmF3IGhpc3RvcmljYWwgT0hMQyBwcmljZXMgZm9yIHNwbGl0cyBhbmQgZGl2aWRlbmRzLCBidXQgaXQgb25seSB3b3JrcyBmb3IgT0hMQyBkYXRhLiBJdCB3aWxsIG5vdCB3b3JrIGlmIHlvdSBvbmx5IGhhdmUgY2xvc2UgcHJpY2VzLCBhbmQgaXQgZG9lcyBub3QgcmV0dXJuIGFueSBvZiB0aGUgc3BsaXQgb3IgZGl2aWRlbmQgZGF0YSBpdCB1c2VzLgoKWW91IG5lZWQgdGhlIGRhdGVzIGFuZCB2YWx1ZXMgZm9yIGVhY2ggc3BsaXQgYW5kIGRpdmlkZW5kIHRvIGFkanVzdCBhIG5vbi1PSExDIHByaWNlIHNlcmllcywgb3IgaWYgeW91IHNpbXBseSB3YW50IHRvIGFuYWx5emUgdGhlIHJhdyBzcGxpdCBhbmQgZGl2aWRlbmQgZGF0YS4KCllvdSBjYW4gZG93bmxvYWQgdGhlIHNwbGl0IGFuZCBkaXZpZGVuZCBkYXRhIGZyb20gWWFob28gRmluYW5jZSB1c2luZyB0aGUgcXVhbnRtb2QgZnVuY3Rpb25zIGdldFNwbGl0cygpIGFuZCBnZXREaXZpZGVuZHMoKSwgcmVzcGVjdGl2ZWx5LiBUaGUgaGlzdG9yaWNhbCBkaXZpZGVuZCBkYXRhIGZyb20gWWFob28gRmluYW5jZSBpcyBhZGp1c3RlZCBmb3Igc3BsaXRzLiBJZiB5b3Ugd2FudCB0byBkb3dubG9hZCB1bmFkanVzdGVkIGRpdmlkZW5kIGRhdGEsIHlvdSBuZWVkIHRvIHNldCBzcGxpdC5hZGp1c3QgPSBGQUxTRSBpbiB5b3VyIGNhbGwgdG8gZ2V0RGl2aWRlbmRzKCkuCgpgYGB7cn0KIyBEb3dubG9hZCBBQVBMIHNwbGl0IGRhdGEKc3BsaXRzIDwtIGdldFNwbGl0cygiQUFQTCIpCgojIERvd25sb2FkIEFBUEwgZGl2aWRlbmQgZGF0YQpkaXZpZGVuZHMgPC0gZ2V0RGl2aWRlbmRzKCJBQVBMIikKCiMgTG9vayBhdCB0aGUgZmlyc3QgZmV3IHJvd3Mgb2YgZGl2aWRlbmRzCmhlYWQoZGl2aWRlbmRzKQoKIyBEb3dubG9hZCB1bmFkanVzdGVkIEFBUEwgZGl2aWRlbmQgZGF0YQpyYXdfZGl2aWRlbmRzIDwtIGdldERpdmlkZW5kcygiQUFQTCIsIHNwbGl0LmFkanVzdCA9IEZBTFNFKQoKIyBMb29rIGF0IHRoZSBmaXJzdCBmZXcgcm93cyBvZiByYXdfZGl2aWRlbmRzCmhlYWQoZGl2aWRlbmRzKQpgYGAKSXQncyBpbXBvcnRhbnQgdG8gZ2V0IHNwbGl0cyBhbmQgZGl2aWRlbmRzIGNvcnJlY3Qgd2hlbiBjYWxjdWxhdGluZyBoaXN0b3JpY2FsIHJldHVybnMuCgojIyMgQWRqdXN0IHVuaXZhcmlhdGUgZGF0YSBmb3Igc3BsaXRzIGFuZCBkaXZpZGVuZHMKCklmIHlvdSBvbmx5IGhhdmUgY2xvc2UgcHJpY2VzLCB5b3UgY2FuIGFkanVzdCB0aGVtIHdpdGggYWRqUmF0aW9zKCkuIEl0IGhhcyAzIGFyZ3VtZW50czogc3BsaXRzLCBkaXZpZGVuZHMsIGFuZCBjbG9zZS4gSXQgcmV0dXJucyBhbiB4dHMgb2JqZWN0IHdpdGggc3BsaXQgYW5kIGRpdmlkZW5kIGFkanVzdG1lbnQgcmF0aW9zIGluIGNvbHVtbnMgIlNwbGl0IiBhbmQgIkRpdiIsIHJlc3BlY3RpdmVseS4KCllvdSBuZWVkIHRvIHByb3ZpZGUgc3BsaXQgZGF0YSB2aWEgdGhlIHNwbGl0cyBhcmd1bWVudCB0byBjYWxjdWxhdGUgdGhlIHNwbGl0IHJhdGlvLiBUbyBjYWxjdWxhdGUgdGhlIGRpdmlkZW5kIHJhdGlvLCB5b3UgbmVlZCB0byBwcm92aWRlIHJhdyBkaXZpZGVuZHMgYW5kIHJhdyBwcmljZXMgdmlhIHRoZSBkaXZpZGVuZHMgYW5kIGNsb3NlIGFyZ3VtZW50cywgcmVzcGVjdGl2ZWx5LgoKT25jZSB5b3UgaGF2ZSB0aGUgc3BsaXQgYW5kIGRpdmlkZW5kIGFkanVzdG1lbnQgcmF0aW9zLCB5b3UgY2FsY3VsYXRlIHRoZSBhZGp1c3RlZCBwcmljZSBtdWx0aXBseWluZyB0aGUgdW5hZGp1c3RlZCBwcmljZSBieSBib3RoIHRoZSBzcGxpdCBhbmQgZGl2aWRlbmQgYWRqdXN0bWVudCByYXRpb3MuCgpgYGB7cn0KIyBDYWxjdWxhdGUgc3BsaXQgYW5kIGRpdmlkZW5kIGFkanVzdG1lbnQgcmF0aW9zCnJhdGlvcyA8LSBhZGpSYXRpb3Moc3BsaXRzID0gc3BsaXRzLCBkaXZpZGVuZHMgPSByYXdfZGl2aWRlbmRzLCBjbG9zZSA9IENsKEFBUEwpKQoKIyBDYWxjdWxhdGUgYWRqdXN0ZWQgY2xvc2UgZm9yIEFBUEwKYWFwbF9hZGp1c3RlZCA8LSBDbChBQVBMKSAqIHJhdGlvc1ssICJTcGxpdCJdICogcmF0aW9zWywgIkRpdiJdCgojIExvb2sgYXQgZmlyc3QgZmV3IHJvd3Mgb2YgWWFob28gYWRqdXN0ZWQgY2xvc2UKaGVhZChBZChBQVBMKSkKCiMgTG9vayBhdCBmaXJzdCBmZXcgcm93cyBvZiBhYXBsX2FkanVzdGVkCmhlYWQoYWFwbF9hZGp1c3RlZCkKYGBgCgo=.