From 66a5c522ee05034b557749d1802d4a6f364f6f0b Mon Sep 17 00:00:00 2001 From: "Emnai: EmnaiDEV-admin @ EmnaiDEV" Date: Wed, 8 Jan 2025 17:22:03 -0500 Subject: [PATCH 1/2] Created using Colab --- .../aistudio_gemini_prompt_freeform.ipynb | 409 ++++++++++++++++++ 1 file changed, 409 insertions(+) create mode 100644 templates/aistudio_gemini_prompt_freeform.ipynb diff --git a/templates/aistudio_gemini_prompt_freeform.ipynb b/templates/aistudio_gemini_prompt_freeform.ipynb new file mode 100644 index 00000000000..95ee45d7339 --- /dev/null +++ b/templates/aistudio_gemini_prompt_freeform.ipynb @@ -0,0 +1,409 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Tce3stUlHN0L" + }, + "source": [ + "##### Copyright 2023 Google LLC" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "form", + "id": "tuOe1ymfHZPu" + }, + "outputs": [], + "source": [ + "# @title Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "# you may not use this file except in compliance with the License.\n", + "# You may obtain a copy of the License at\n", + "#\n", + "# https://www.apache.org/licenses/LICENSE-2.0\n", + "#\n", + "# Unless required by applicable law or agreed to in writing, software\n", + "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "# See the License for the specific language governing permissions and\n", + "# limitations under the License." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FKwyTRdwB8aW" + }, + "source": [ + "## Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "RXInneX6xx7c" + }, + "outputs": [], + "source": [ + "!pip install -U -q \"google-generativeai>=0.8.2\"" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "kWIuwKG2_oWE", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "d698c4ce-3a3b-4cb6-997c-991d8ce8e403" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[\n", + " {\n", + " \"role\": \"user\",\n", + " \"parts\": [\n", + " {\n", + " \"text\": \"You are an expert scientific researcher who has years of experience in conducting systematic literature surveys and meta-analyses of different topics. You pride yourself on incredible accuracy and attention to detail. You always stick to the facts in the sources provided, and never make up new facts. \\\\n\\\\nNow look at the research paper below, and answer the following questions in 1-2 sentences.\\\\n1. When was the paper published?\\\\n2. What is the sample size?\\\\n3. What is the study methodology? in particular, is it a randomized control trial? \\\\n4. How was the study funded? in particular, was the funding from commercial funders?\\\\n5. What was the key question being studied?\\\\n6. What were the key findings to the key question being studied?\\\\n\\\\n\\\\nResearch paper: \\\\nThe miracle of microfinance? Evidence from a randomized evaluation\\u2217\\\\nAbhijit Banerjee\\u2020 Esther Duflo\\u2021 Rachel Glennerster\\u00a7 Cynthia Kinnan\\u00b6\\\\nThis version: March, 2014\\\\nAbstract\\\\nThis paper reports results from the randomized evaluation of a group lending microcredit program in Hyderabad, India. A lender worked in 52 randomly selected neighborhoods, leading to an\\\\n8.4 percentage point increase in takeup of microcredit. Small business investment and profits of\\\\npre-existing businesses increased, but consumption did not significantly increase. Durable goods\\\\nexpenditure increased, while \\u201ctemptation goods\\u201d expenditure declined. We found no significant\\\\nchanges in health, education, or women\\u2019s empowerment. Two years later, after control areas had\\\\ngained access to microcredit but households in treatment area had borrowed for longer and in larger\\\\namounts, very few significant differences persist. JEL codes: O16, G21, D21\\\\n\\u2217This paper updates and supersedes the 2010 version, which reported results using one wave of endline surveys. Funding\\\\nfor the first wave of the survey was provided by The Vanguard Charitable Endowment Program and ICICI bank. Funding\\\\nfor the second wave was provided by Spandana and J-PAL. This draft was not reviewed by the The Vanguard Charitable\\\\nEndowment Program, ICICI Bank, or Spandana. The Centre for Micro Finance at the Institute for Financial Management\\\\nResearch (IFMR) (Chennai, India) set up and organized the experiment and the data collection, and made the anonymized\\\\ndata available first to the research team, and then publicly. At the time, IFMR did not have an IRB. Data analysis\\\\nand on-going data collection have received IRB approval from MIT COUHES (1203004973) and Northwestern University\\\\n(STU00063636). Adie Angrist, Leonardo Elias, Harris Eppsteiner, Shehla Imran, Seema Kacker, Tracy Li, Aditi Nagaraj\\\\nand Cecilia Peluffo provided excellent research assistance. Datasets for both waves of data used in this paper are available\\\\nat http://www.centre-for-microfinance.org/publications/data/. The authors wish to extend thanks to CMF and Spandana\\\\nfor organizing the experiment, to Padmaja Reddy (CEO of Spandana) whose commitment to understanding the impact of\\\\nmicrofinance made this project possible, to Annie Duflo (the executive director of CMF at the time of the study) for setting\\\\nup this project, and to numerous seminar audiences and colleagues for insightful suggestions.\\\\n\\u2020MIT Department of Economics , NBER and J-PAL. Email: banerjee@mit.edu\\\\n\\u2021MIT Department of Economics, NBER and J-PAL. Email: eduflo@mit.edu\\\\n\\u00a7\\\\nJ-PAL. Email: rglenner@mit.edu\\\\n\\u00b6Northwestern University Department of Economics and NBER. Email: c-kinnan@northwestern.edu\\\\n1\\\\n1 Introduction\\\\nMicrofinance institutions (MFIs) have expanded rapidly over the last 10 to 15 years: according\\\\nto the Microcredit Summit Campaign (2012), the number of very poor families with a microloan\\\\nhas grown more than 18-fold from 7.6 million in 1997 to 137.5 million in 2010. Microcredit has\\\\ngenerated considerable enthusiasm and hope for fast poverty alleviation, culminating in the\\\\nNobel Prize for Peace, awarded in 2006 to Mohammed Yunus and the Grameen Bank for their\\\\ncontribution to the reduction in world poverty. In the last several years, however, the enthusiasm\\\\nfor microcredit has been matched by an equally strong backlash. For instance, a November 2010\\\\narticle in The New York Times, appearing in the wake of a rash of reported suicides linked to\\\\nover-indebtedness, quotes Reddy Subrahmanyam, an official in Andhra Pradesh (the setting of\\\\nthis study), accusing MFIs of making \\u201chyperprofits off the poor.\\u201d He argues that \\u201cthe industry\\\\n[has] become no better than the widely despised village loan sharks it was intended to replace....\\\\nThe money lender lives in the community. At least you can burn down his house. With these\\\\ncompanies, it is loot and scoot\\u201d(Polgreen and Bajaj 2010).\\\\nWhat is striking about this debate is the relative paucity of evidence to inform it. Anecdotes\\\\nabout highly successful entrepreneurs or deeply indebted borrowers tell us nothing about the\\\\neffect of microfinance on the average borrower, much less the effect of having access to it on the\\\\naverage household. Even representative data about microfinance clients and non-clients cannot\\\\nidentify the causal effect of microfinance access, because clients are self-selected and therefore\\\\nnot comparable to non-clients. Microfinance organizations also purposely choose some villages\\\\nand not others. These issues make the evaluation of microcredit particularly difficult, and until\\\\nrecently there was little rigorous evidence to inform it.\\\\nThis has changed in the last few years, as several studies evaluating microfinance have been\\\\nconducted by different research teams with different partners in different settings: Morocco\\\\n(Cr\\u00e9pon et al., 2013), Bosnia-Herzegovina (Augsburg et al., 2013), Mexico (Angelucci et al.,\\\\n2013), Mongolia (Attanasio et al., 2013) and Ethiopia (Tarozzi et al., 2013). In this paper we\\\\nreport on the oldest of these, the first randomized evaluation of the effect of the canonical grouplending microcredit model, which targets women who may not necessarily be entrepreneurs. This\\\\nstudy also follows the households over the longest period of any evaluation (three to 3.5 years\\\\n1\\\\nafter the introduction of the program in their areas), which is necessary since many impacts\\\\nmay be expected to surface only over the medium run.\\\\nThe experiment, a collaborative project between the Center for Microfinance (CMF) at\\\\nthe Institute for Financial Management Research (IFMR) in Chennai and Spandana, one of\\\\nIndia\\u2019s fastest growing MFI at the time was conducted as follows. In 2005, 52 of 104 poor\\\\nneighborhoods in Hyderabad were randomly selected for the opening of a Spandana branch,\\\\nwhile the remainder were not.1 Hyderabad is the fifth largest city in India, and the capital of\\\\nAndhra Pradesh, the Indian state were microcredit has expanded the fastest and has recently\\\\nbeen most controversial. Fifteen to 18 months after the introduction of microfinance in each\\\\narea, a comprehensive household survey was conducted in an average of 65 households in each\\\\nneighborhood, for a total of about 6,850 households. In the meantime, other MFIs had also\\\\nstarted their operations in both treatment and comparison households, but the probability of\\\\nreceiving an MFI loan was still 8.4 percentage points (46%) higher in treatment areas than\\\\nin comparison areas (26.7% borrowers in treated areas versus 18.3% borrowers in comparison\\\\nareas). Two years after this first endline survey, the same households were surveyed once more.\\\\nBy that time, both Spandana and other organizations had started lending in the treatment and\\\\ncontrol groups, so the fraction of households borrowing from microcredit organizations was not\\\\ndramatically different (38.5% in treatment and 33% in control). But households in treatment\\\\ngroups had larger loans and had been borrowing for a longer time period. This second survey\\\\nthus gives us an opportunity to examine some of the longer-term impacts of microcredit access\\\\non households and businesses, although the setting is not perfect since we are comparing those\\\\nwho borrow for longer versus those who borrow for a shorter time, rather than those who do\\\\nand those who do not borrow at all.\\\\nSince it is entirely possible that there are spillover or general equilibrium effects (as analyzed\\\\nby Buera et al., 2011), and effects that operate through the expectation of being able to borrow\\\\nwhen needed (such as reductions in precautionary savings, as documented in Thailand by Ka1An alternative way to measure the impact of borrowing is to randomize microcredit offers among applicants.\\\\nThis approach was pioneered by Karlan and Zinman (2010), which uses individual randomization of the \\u201cmarginal\\u201d\\\\nclients in a credit scoring model to evaluate the impact of consumer lending in South Africa, and finds that access\\\\nto microcredit increases the probability of employment. The authors use the same approach to measure impact\\\\nof microcredit among small businesses in Manila (Karlan and Zinman, 2011). It should be noted, however, that\\\\nthese two studies evaluate slightly different programs: consumer lending in the South Africa study, and \\u201csecond\\\\ngeneration\\u201d individual-liability loans to existing entrepreneurs in Manila.\\\\n2\\\\nboski and Townsend, 2011, and in India by Fulford, 2011, or through general-equilibrium effects\\\\non prices or wages (Gin\\u00e9 and Townsend 2004)), we focus here on reduced-form/intent-to-treat\\\\nestimates.\\\\nWe examine the effect on borrowing from various sources, consumption, new business creation, business income, etc., as well as measures of other human development outcomes such as\\\\neducation, health and women\\u2019s empowerment. At the first endline, while households do borrow\\\\nmore from microcredit institutions, the overall take up is reasonably low (only 26.4% of the\\\\neligible households borrow, not the 80% that Spandana expected), and some of the loans are\\\\nsubstituting for informal loans. Informal borrowing declines, and we see no significant difference\\\\nin overall borrowed amount (though the point estimate is positive). This is itself was a surprising\\\\nresult at the time, though it has been replicated in other studies: the demand for microcredit\\\\nis less important than expected, and may not correspond to an important demand for extra\\\\ncredit. We see no significant difference in monthly per capita consumption and monthly nondurable consumption. We do see significant positive impacts on the purchase of durables. There\\\\nis evidence that this is financed partly by an increase in labor supply and partly by cutting\\\\nunnecessary consumption: households have reduced expenditures on what that they themselves\\\\ndescribe as \\u201ctemptation goods.\\u201d\\\\nThus, in our context, microfinance plays a role in helping some households make different\\\\nintertemporal choices in consumption. This is not the only impact that is traditionally expected\\\\nfrom microfinance, however. The primary engine of growth that it is supposed to fuel is business\\\\ncreation. This is typically true even for lenders that do not insist that households have a business\\\\nto take a first loan (Spandana is one of them), but still hope and expect that the ability to\\\\nborrow will eventually help households start or expand small businesses. (The description of\\\\nSpandana\\u2019s group-loan product is careful not to mention an automatic link between credit and\\\\nself-employment activity but does state that \\u201cLoans are used for cash flow smoothening (sic.),\\\\npredominantly for productive purposes.\\u201d2\\\\n) Fifteen to 18 months after gaining access, households\\\\nare no more likely to be entrepreneurs (that is, have at least one business), but they invest more\\\\nin the businesses they do have (or the ones they start). There is an increase in the average\\\\n2To give a sense of the prevalence of the purported link between microfinance and business creation, of the\\\\nroughly 3.1 million Google search results for \\u201cmicrofinance,\\u201d 1.35 million (44%) also contain the phrase \\u201cbusiness\\\\ncreation\\u201d or \\u201centrepreneurship\\u201d (retrieved November 2013).\\\\n3\\\\nprofits of the businesses that were already in existence before microcredit, which is entirely due\\\\nto very large increases in the upper tail of profitability. At every quantile between the 5th and\\\\nthe 95th percentile, there is no difference in the profits of the businesses. The median marginal\\\\nnew business is both less profitable and less likely to have even one employee in treatment than\\\\nin control areas.\\\\nAfter three years, when microcredit is available both in treatment and control groups but\\\\ntreatment group households have had the opportunity to borrow for a longer time, businesses\\\\nin the treatment groups have significantly more assets, and business profits are now larger for\\\\nbusinesses above the 85th percentile of profitability. However, the average business is still small\\\\nand not very profitable. In other words, perhaps contrary to most people\\u2019s belief, to the extent\\\\nmicrocredit helps businesses, it may help the most profitable businesses more. There is still no\\\\ndifference in average consumption.\\\\nWe do not find any effect on any of the women\\u2019s empowerment or human development\\\\noutcomes either after 18 or 36 months. Furthermore, almost 70% of eligible households do not\\\\nhave an MFI loan, preferring instead to borrow from other sources, if they borrow (and most\\\\ndo).\\\\nA number of caveats must be kept in mind when interpreting and generalizing these results.\\\\nFirst, the difference in microfinance take-up between treatment and control areas is low, even\\\\nby the first endline, which raises two issues: it lowers power and precision (though we have a\\\\nnumber of significant effects), and it means that the impact of microcredit we detect is driven\\\\nby the marginal borrowers\\u2013those who do not borrow when the cost of doing so is high (because\\\\nthey have fewer MFIs to choose from or do not want to change neighborhoods), but do borrow\\\\nwhen that cost is lower.\\\\nSecond, the evaluation was run in a context of very high economic growth, which could\\\\nhave either decreased or increased the impact of microfinance. Third, this is the evaluation of\\\\na for-profit microfinance model, and not-for-profit microfinance lenders may have larger positive effects if their interest rates are kept low. Fourth, as the MFI we study does not provide\\\\nany complementary services such as business training or sensitivity education, we are studying\\\\nthe pure impact of providing loans to women who may or may not use them for their own\\\\nbusinesses (though Spandana does believe that this is what the money will be used for eventu4\\\\nally), and we do find an expansion in women-owned businesses). Fifth, the study took place in\\\\n\\u201cmarginal\\u201d neighborhoods\\u2013those Spandana was indifferent about working with at the outset\\u2013\\\\nand the impacts may have been different in the neighborhoods they chose to exclude from the\\\\nrandomization (Heckman, 1992).\\\\nThus, it is an important reassurance that our results find a strong echo in the four other\\\\nstudies that look at similar programs in different contexts. This gives us confidence in the\\\\nrobustness and external validity of our findings. In short, microcredit is not for every household,\\\\nor even most households, and it does not lead to the miraculous social transformation some\\\\nproponents have claimed. Its principal impact seems to be, perhaps unsurprisingly, that it\\\\nallows some households to sacrifice some instantaneous utility (temptation goods or leisure)\\\\nin order to finance lumpy purchases, either for their home or in order to establish or expand\\\\na business. Prima facie, these marginal businesses do not appear to be highly productive or\\\\nprofitable, but more data and more time may be needed to fully establish their impacts on\\\\nindividuals, markets and communities.\\\\n2 The Spandana Microcredit product, and the context\\\\n2.1 Spandana and its microcredit product\\\\nUntil the major crisis in Indian microfinance in 2010, Spandana was one of the largest and\\\\nfastest-growing microfinance organizations in India, with 1.2 million active borrowers in March\\\\n2008, up from 520 borrowers in 1998-9, its first year of operation (MIX Market, 2009). It had\\\\nexpanded from its birthplace in Guntur, a dynamic city in Andhra Pradesh, across the state\\\\nand into several others.\\\\nThe basic Spandana product was the canonical group-loan product, first introduced by the\\\\nGrameen Bank. A group is comprised of six to ten women, and 25-45 groups form a \\u201ccenter.\\u201d\\\\nWomen are jointly responsible for the loans of their group. The first loan is Rs. 10,000, about\\\\n$200 at market exchange rates, or $1,000 at 2007 purchasing power parity (PPP)-adjusted\\\\nexchange rates (World Bank, 2007).3\\\\nIt takes 50 weeks to reimburse principal and interest; the\\\\n3\\\\nIn 2007 the PPP exchange rate was $1=Rs. 9.2, while the market exchange rate was $1'Rs. 50. All following\\\\nreferences to dollar amounts are in PPP terms unless noted otherwise.\\\\n5\\\\ninterest rate is 12% (non-declining balance; equivalent to a 24% APR). If all members of a group\\\\nrepay their loans, they are eligible for second loans of Rs. 10,000-12,000. Loan amounts increase\\\\nup to Rs. 20,000. During the course of the study, Spandana also introduced an individual\\\\nproduct, for clients who had been successful with one or two group-loan cycles. The individual\\\\nproduct was available in the treatment areas. Very few people in our sample ended up taking\\\\nthis loan, however, so the study is mainly an evaluation of a group-lending product.\\\\nEligibility is determined using the following criteria: clients must (a) be female (b) be aged\\\\n18 to 59, (c) have resided in the same area for at least one year, (d) have valid identification\\\\nand residential proof (ration card, voter card, or electricity bill), and (e) at least 80% of women\\\\nin a group must own their home.4 Groups are formed by women themselves, not by Spandana.\\\\nUnlike some other microfinance organizations, Spandana does not require its clients to start a\\\\nbusiness (or pretend to) in order to borrow: the organization recognizes that money is fungible,\\\\nand clients are left entirely free to choose the best use of the money, as long as they repay\\\\ntheir loan. Spandana does not determine loan eligibility by the expected productivity of the\\\\ninvestment, although selection into groups may screen out women who cannot convince fellow\\\\ngroup-members that they are likely to repay. Also unlike other microlenders, most notably\\\\nGrameen, Spandana does not explicitly insist on \\u201ctransformation\\u201d in the household. There is no\\\\nchanting of resolutions at group meetings, which are very short and focused on the repayment\\\\ntransaction. Spandana is primarily a lending organization, not directly involved in business\\\\ntraining, financial literacy promotion, etc. It is however the belief of the management that the\\\\nvery fact of borrowing will lead to such transformation, and to business creation. Spandana was\\\\nalso a for-profit operator, charging interest rates sufficient to make profits, though all the profits\\\\nwere re-invested in the organization in the period we study. The organization obtained private\\\\ncapital and would probably have launched an IPO if it had not been caught in the middle of\\\\nthe Andhra Pradesh crisis. This makes it different from Grameen Bank (Mohammed Yunus\\\\nhas explicitly and vigorously criticized for-profit MFIs after the IPO of Compartamos, a large\\\\nMexican MFI). All these features are important to keep in mind when interpreting the results of\\\\nthis study: it is possible that the Grameen product would have different impacts. However, from\\\\n4The home ownership requirement is not because the house is used as collateral, but because home owners are\\\\nmore stable and less likely to migrate. Spandana does not require a formal property title, just a general agreement\\\\nthat this house belongs to this household (something that tends to be clear even in informal settlement)\\\\n6\\\\nan evaluation point of view, there are clear advantages to this product: in particular, any impact\\\\non business expansion can be attributed to credit alone, rather than to other services. Moreover,\\\\nto the extent we find \\u201cpositive\\u201d results in the study, they are unlikely to be attributable to social\\\\ndesirability bias. It is also worth noting that, in the period we study, the interest rates charged\\\\nby Spandana were low by standard microfinance standards, even Grameen.\\\\n2.2 The context\\\\nTable 1A uses the baseline data to show a snapshot of households from the study area in\\\\n2005, before the Spandana product was launched. As we describe below, these numbers need\\\\nto be viewed with some caution, as the households sampled at baseline were not necessarily\\\\nrepresentative of the area as a whole, and were not purposely resurveyed at endline. At baseline,\\\\nthe average household was a family of five, with monthly expenditure of just under Rs. 5,000, or\\\\n$540 at PPP-adjusted exchange rates ($108 per capita) (World Bank, 2005).5 There was almost\\\\nno MFI borrowing in the sample areas at baseline. However, 68% of the households had at least\\\\none outstanding loan. The average amount outstanding was Rs. 38,000. Sixty-three percent\\\\nof households had a loan from an informal source (moneylenders, friends or neighbors, family\\\\nmembers or shopkeepers). Commercial bank loans were very rare (3.6%).\\\\nAlthough business investment was not commonly named as a motive for borrowing, businesses were common, with 32 businesses per 100 households, compared to an OECD-country\\\\naverage of 12% who say that they are self-employed. Less than half of all businesses were operated by women (14.5 woman-run businesses per 100 households.) Business owners and their\\\\nfamilies spent on average 58 hours per week working in the business.\\\\nGrowth between 2005 and 2010\\\\nTable 1B shows some of the same key statistics for the endline 1 and endline 2 (EL1 and EL2)\\\\nsamples in the control group.\\\\nComparing the control baseline sample (2005) with the control households in the EL1 (2008)\\\\nand EL2 (2010) samples reveal very rapid secular growth in Hyderabad over 2005-2010.6 Average\\\\n5Column 2 reports the control mean, and column 4 reports the treatment-control difference. None of these\\\\ndifferences are significant (column 5).\\\\n6While the comparison may not be perfect since the baseline survey was not conducted on the same sample as\\\\n7\\\\nhousehold consumption rose from Rs. 4,888 (2005) to Rs. 7,662 in 2007 and Rs. 11,497 in 2010\\\\n(all expressed in 2007 rupees). The fraction of households with at least one outstanding loan\\\\nrose from 68% at baseline to 89% in EL1 and 90% in EL2.\\\\nThe prevalence of businesses increased from 32 per hundred households at baseline to 44 at\\\\nEL1 and 56 at EL2. In endline 1 37.8% and in endline 2 40.3% of the business were operated by\\\\nwomen. However, the businesses remained very small, with on average .38 employees in EL1 and\\\\n.18 in EL2.7 As well as remaining very small in terms of employment, average sales remained\\\\nfairly steady: Rs. 14,800 at EL1 and 14,100 at EL2. However, looking across all households (not\\\\njust those with businesses), business revenues increased from around Rs. 4,800 to Rs. 5,800 (in\\\\nconstant 2007 rupees). At EL2, business owners reported business expenses (working capital)\\\\nplus investment in assets of almost Rs. 15,000, up from about Rs. 13,000 at EL1. (These\\\\nexpense estimates do not account for the cost of the proprietors\\u2019 time.)\\\\nThis context of rapid growth in urban Andhra Pradesh is another important feature to\\\\nkeep in mind, and may color the results of this study (of all the randomized evaluations on\\\\nmicrofinance, this is probably the most dynamic context). It is clearly an important example,\\\\nas microfinance clients in India represents roughly 30% of all microfinance clients worldwide,8\\\\nand microfinance has developed in many other rapidly growing environments (Bangladesh being\\\\nprobably the prime example). But the results may be different in contexts with much slower\\\\ngrowth, or in recessions. Fortunately, the other RCT studies cover a wide variety of contexts,\\\\nwhich will help to understand the extent to which results depend on context.\\\\n3 Experimental design\\\\n3.1 Experimental Design\\\\nAt the time this study was started, microfinance had already taken hold in several districts\\\\nin Andhra Pradesh, but most microfinance organizations had not yet started working in the\\\\nthe endline, the growth between EL1 and EL2 is for the same set of households, using the same survey instruments,\\\\nand thus gives us a good sense of the dynamism of this economy.\\\\n7The fall in average employment between EL1 and EL2 may reflect a compositional effect, with the marginal\\\\nbusinesses being smaller.\\\\n8MIX Market reported 94 million borrowers worldwide in 2011, of whom 28 million are located in India\\\\n(http://www.mixmarket.org/mfi/country/India).\\\\n8\\\\ncapital, Hyderabad. Spandana initially selected 120 areas (identifiable neighborhoods, or bastis)\\\\nin Hyderabad as places in which they were interested in opening branches but also willing not\\\\nto. These areas were selected based on having no preexisting microfinance presence, and having\\\\nresidents who were desirable potential borrowers: poor, but not \\u201cthe poorest of the poor.\\u201d Areas\\\\nwith high concentrations of construction workers were avoided because they move frequently,\\\\nwhich makes them undesirable as microfinance clients. While the selected areas are commonly\\\\nreferred to as \\u201cslums,\\u201d these are permanent settlements with concrete houses and some public\\\\namenities (electricity, water, etc.). Conversely, the largest ones were not selected for the study,\\\\nsince Spandana was keen to start operations there: the large population in these slums allowed\\\\nthem to benefit from economies of scale and reach quickly a number of clients that justified\\\\nexpansion in the city. The population in the neighborhoods selected for the study ranges from\\\\n46 to 555 households. The slums chosen to be part of the study were typically not continuous\\\\nto avoid spillovers across treatment and control slums.\\\\nIn each area, CMF first hired a market research company to conduct a small baseline neighborhood survey in 2005, collecting information on household composition, education, employment, asset ownership, expenditure, borrowing, saving, and any businesses currently operated\\\\nby the household or stopped within the last year. They surveyed a total of 2,800 households in\\\\norder to obtain a rapid assessment of the baseline conditions of the neighborhoods. However,\\\\nsince there was no existing census, and the baseline survey had to be conducted very rapidly to\\\\ngather some information necessary for stratification before Spandana began their operations, the\\\\nhouseholds were not selected randomly from a household list: instead field officers were asked\\\\nto map the area and select every n\\\\nth house, with n chosen to select 20 households per area.\\\\nUnfortunately, this procedure was not followed very rigorously by the market research company,\\\\nand we are not confident that the baseline is representative of the slum as a whole. Thus, the\\\\nbaseline survey was used solely as a basis for stratification, the descriptive analysis above, and\\\\nto collect area-level characteristics that are used as control variables.9 Beyond this, we do not\\\\nuse the baseline survey in the analysis that follows.\\\\nAfter the baseline survey, but prior to randomization, sixteen areas were dropped from\\\\nthe study because they were found to contain large numbers of migrant-worker households.\\\\n9However, omitting these controls makes no difference to the results.\\\\n9\\\\nSpandana (like other MFIs) has a rule that loans should only be made to households who\\\\nhave lived in the same community for at least one year because the organization believes that\\\\ndynamic incentives (the promise of more credit in the future) are more important in motivating\\\\nrepayment for these households.10 The remaining 104 areas were grouped into pairs of similar\\\\nneighborhoods, based on average per capita consumption and per-household debt, and one of\\\\neach pair was randomly assigned to the treatment group.11 Figure 5 shows a timeline of data\\\\ncollection and randomization.\\\\nTable 1 uses the baseline sample to show that treatment and comparison areas did not\\\\ndiffer in their baseline levels of demographic, financial, or entrepreneurship characteristics in the\\\\nbaseline survey. This is not surprising, since the sample was stratified according to per capita\\\\nconsumption and fraction of households with debt.\\\\nSpandana then progressively began operating in the 52 treatment areas between 2006 and\\\\n2007. The roll out happened at different date in different slums. Note that in the intervening\\\\nperiods, other MFIs also started their operations, both in treatment and comparison areas. We\\\\nwill show below that there is still a significant difference between MFI borrowing in treatment\\\\nand comparison groups. Spandana credit officers also started lending in very few of the control\\\\nslums, although this was stopped relatively rapidly. Furthermore, there was no rule against\\\\nborrowing in another slum (if one could find a group to join), and some people did do so.\\\\nOverall, 5% of households in control slums were borrowing from Spandana at the endline.\\\\nTo create a proper sampling frame for the endline, CMF staff undertook a comprehensive\\\\ncensus of each area in early 2007, and included a question on borrowing. The census revealed\\\\nlow rates of MFI borrowing even in treatment areas, so the endline sampling frame consisted\\\\nof households whose characteristics suggested high likelihood of having borrowed: those that\\\\nhad resided in the area for at least three years and contained at least one woman aged 18 to\\\\n55. Spandana borrowers identified in the census were oversampled, because we believed that\\\\n10We can compare baseline characteristics in the 16 areas dropped to those in the 104 areas included in the\\\\nrandomization. The differences are consistent with Spandana\\u2019s rationale for dropping the omitted areas: household\\\\nsize is smaller in these areas (due to migrant workers there without families or children); there is less business\\\\ncreation (presumably because migrants are unlikely to start a business) and there is less credit outstanding (likely\\\\nbecause informal lenders are also reluctant to lend to these very mobile households). (Results available upon\\\\nrequest.)\\\\n11Pairs were formed to minimize the sum across pairs A, B (area A avg loan balance \\u2013 area B avg loan balance)2\\\\n+ (area A per capita consumption \\u2013 area B per capita consumption)2\\\\n. Within each pair one neighborhood was\\\\nrandomly allocated into treatment.\\\\n10\\\\nheterogeneity in treatment effect would introduce more variance in outcomes among Spandana\\\\nborrowers than among non borrowers, and oversampling borrowers would therefore give higher\\\\npower. The results presented below weigh the observation to account for this oversampling so\\\\nthat the results are representative of the population as a whole. Since the sampling frame at\\\\nbaseline was not rigorous enough, baseline households were not purposely resurveyed in the\\\\nfollow-up. The first endline survey began in August 2007 and ended in April 2008, and the roll\\\\nout of the endline followed the roll out of the program. In each area, this first endline survey\\\\nwas conducted at least 12 months after Spandana began disbursing loans in this particular area,\\\\nand generally 15 to 18 months after (the survey followed the same calendar in the control slums,\\\\nin order to ensure comparability between treatment and control). The overall sample size was\\\\n6,864 households.\\\\nTwo years later, in 2009-2010, a second endline survey, following up on the same households,\\\\nwas undertaken. It included the same set of questions as in 2007-2008 to insure comparability.\\\\nThe re-contact rate was very high (90%). We discuss this attrition in more details below.\\\\n3.2 Potential threats to identification and caveats on interpretation\\\\n3.2.1 Attrition and selective migration\\\\nSince we don\\u2019t have a proper baseline sample that was systematically followed, a potential worry\\\\nis that the sample that is surveyed at endline may not be strictly comparable in treatment and\\\\ncontrol areas, if there was differential attrition in treatment and in control groups. For example,\\\\npeople could have moved into the area, or avoided moving out of the area, because Spandana\\\\nhad started their operations there. This does not seem highly likely, given that if someone really\\\\nwanted to borrow, they had options to do so either from another MFI (we will see that a fair\\\\nnumber of people did) or even from Spandana, by going to the next neighborhood. The treatment\\\\nonly made it marginally easier to borrow (as we will see in the next section). Nevertheless, in\\\\nretrospect, it was a clear mistake not to attempt to systematically re-survey at least a fraction\\\\nof the baseline sample, even though the baseline sampling frame was weak.\\\\nThat said, we have a number of ways to assess the extent to which attrition is a problem.\\\\nFirst of all, in Table A1, we verify that the households surveyed at endlines 1 and 2 are similar\\\\nin treatment and control groups, in terms of a number of characteristics which are fixed over\\\\n11\\\\ntime (the p-value on the joint difference of these characteristics across treatment arms is 0.980 at\\\\nEL1 and 0.534 at EL2). This is a first indication that we have a comparable sample at baseline\\\\nand at endline, even allowing for attrition.\\\\nSecond, the sample at EL1 was drawn from a census that was conducted fairly soon after\\\\nthe introduction of microcredit (on average less than a year). Moreover, the sampling frame for\\\\nEL1 was restricted to people who had lived in the area for at least three years before the census.\\\\nThis means that no one in the survey had migrated into the area because of Spandana: they\\\\nwere all residents of the area well before Spandana moved into the area (the vast majority had\\\\nbeen there for years). This removes the most plausible channel for differential selection into the\\\\nsample in treatment and control groups. There remains the possibility that fewer people (or\\\\ndifferent people) left the treatment areas between the launch of the product and the census due\\\\nto the option to borrow more easily, but in less than a year, the migration rate out of Hyderabad\\\\nis low, and given the ability to borrow if someone wants to, it seems far fetched that people\\\\nwould have been differentially likely to migrate out of the slums based on the ability to become\\\\na Spandana client.\\\\nWe can then study attrition between census and EL1, and between EL1 and EL2.\\\\nThere was some attrition between the census and EL1, especially since, as it customary in\\\\nthese types of surveys, census surveyors were given replacement lists in case they did not find\\\\nthe exact person they were looking for. However this attrition (roughly 25%) is almost exactly\\\\nthe same in treatment and in control areas: 27.6% in treatment and 25.2% in control (p-value\\\\nof difference: 0.165; see Table A2, Panel A). Moreover, the attrition is totally uncorrelated with\\\\nthe months elapsed since Spandana entered the slum (Table A2, Panel B), which is not what we\\\\nwould expect if it were somehow related to the program (it would have had more time to play\\\\nout if Spandana had entered a longer time before). The only characteristics that predict that\\\\nsomeone is more likely to be found is that they are a Spandana borrower (4.2pp lower attrition;\\\\nSE of 1.97pp), and living in a \\u201cnon-pucca\\u201d (lower-quality) house (2.7pp lower attrition; SE of\\\\n1.4pp). The most likely reason for the former is that the Spandana officers helped the CMF\\\\nfield team to locate their clients. For example, surveyors could attend weekly meetings to collect\\\\naddresses and find directions to people\\u2019s homes. The latter likely reflects greater mobility among\\\\nwealthier households. In all of the analysis that follows, we correct for this by adjusting the\\\\n12\\\\nsampling weights for the ratio between the probability to find a non-Spandana borrower and the\\\\nprobability to find a Spandana borrower (0.948).\\\\nAppendix Table 3, Panel A shows that the re-contact rate at endline 2 for households initially\\\\ninterviewed at endline 1 was very high (much higher than in most randomized controlled trials,\\\\nin the US or in developing countries). It was also similar in the treatment and the control\\\\ngroup, at 89.9% and 90.2%, respectively (the p-value of the difference is 0.248). Panel B shows\\\\naverage characteristics of the re-contacted versus attrited households. The samples do not differ\\\\nsignificantly along most dimensions. However, those who attrited had slightly higher per capita\\\\nexpenditure at endline 1, with a Rs. 1000 increase in expenditure associated with a 0.0098\\\\nincrease in likelihood of attrition (column 1: the standard error is 0.0032). Having a Spandana\\\\nloan at endline 1 was associated with 3.3 percentage points lower attrition (column 5: the\\\\nstandard error is 1pp); having any MFI loan is associated with 2.7 percentage points lower\\\\nattrition (column 6: the standard error is 0.8pp), driven by the effect of Spandana loans. Again,\\\\nthe explanation for this is that the credit officers helped the field team find the clients, if they\\\\nhad moved within their slum. Panel C of Table A3 shows shows that between treatment and\\\\ncontrol, attrition was not differentially correlated with characteristics.\\\\nThis data suggests that there is no evidence that migration or attrition patterns were driven\\\\nby the treatment, except through the mechanical effect that Spandana credit officers helped\\\\nsurveyors locate their clients, which we correct for.\\\\nNevertheless, to systematically address the concern that attrition may affect the results,\\\\nwe have re-estimated all the regressions below with a correction for sample selection inspired\\\\nby Dinardo, Fortin and Lemieux (2010), where we re-weight the data using the inverse of the\\\\npropensity to be observed at endline 2, so that the distribution of observable characteristics (at\\\\nendline 1) among households observed at endline 2 resembles that in the entire endline 1 sample.\\\\nWe then apply the same weights to endline 1 data (implicitly assuming a similar selection process\\\\nbetween the onset of microfinance and endline 1). The results, presented for key outcomes in\\\\nTable A5, are very similar to what we present here. (Full results available on request.) Note\\\\nthat this procedure only corrects for differential attrition by observables, not by unobservable\\\\nvariables.\\\\n13\\\\nInterpreting the results\\\\nThe experimental design and the implementation raise a number of issues worth keeping in mind\\\\nto interpret the results that follow.\\\\nFirst, given the sampling frame, ours will be an intent-to-treat (ITT) analysis on a sample of\\\\n\\u201clikely borrowers\\u201d. This is thus neither the effect on those who borrow nor the average effect on\\\\nthe neighborhood. Rather, it is the average effect of easier access to microfinance on those who\\\\nare primary targets. Second, microfinance was available in both treatment and control areas,\\\\nthough access was easier in treatment areas. Microfinance take-up is indeed higher in treatment\\\\nareas, which generates experimental variation, but the marginal clients may be different from\\\\nthe first clients to borrow in an area. This also affects power: the initial power calculations\\\\nwere performed when Spandana thought that 80% of eligible households would become clients\\\\nvery rapidly after the launch. In fact the data shows that the proportion reached only 18%\\\\nin 18 months (and this stayed at 18% after two and a half years). This is low, and also gave\\\\nother MFIs, which were behind Spandana in terms of penetration in Hyderabad, time to catch\\\\nup. Overall, take-up of microfinance from any organization was only 33% by EL2. This is an\\\\nimportant result in its own right, and very surprising at the time, but it implies that, with the\\\\nbenefits of hindsight, more areas would have been needed. This is not something that could be\\\\naddressed ex-post. Fortunately, subsequent evaluations of microfinance programs were able to\\\\ndo so, and find a very similar set of results (and non-results) suggesting that these outcomes are\\\\nnot the artifact of samples that are too small, or of a very non-representative set of clients.\\\\n4 Results\\\\nTo estimate the impact of microfinance becoming available in an area on likely clients, we focus\\\\non intent-to-treat (ITT) estimates; that is, simple comparisons of averages in treatment and\\\\ncomparison areas, averaged over borrowers and non-borrowers. We present ITT estimates of the\\\\neffect of microfinance on businesses operated by the household; for those who own businesses,\\\\nwe examine business profits, revenue, business inputs, and the number of workers employed by\\\\nthe business. (The construction of these variables is described in Appendix 1.) Each column of\\\\n14\\\\neach table reports the results of a regression of the form\\\\nyia = \\u03b1 + \\u03b2 \\u00d7 T reatia + X\\\\n0\\\\na\\u03b3 + \\u03b5ia\\\\nwhere yia is an outcome for household i in area a, T reatia is an indicator for living in a treated\\\\narea, and \\u03b2 is the intent-to-treat effect. X\\\\n0\\\\na\\\\nis a vector of control variables, calculated as arealevel baseline values: area population, total businesses, average per capita expenditure, fraction\\\\nof household heads who are literate, and fraction of all adults who are literate. Standard errors\\\\nare adjusted for clustering at the area level and all regressions are weighted to correct for\\\\noversampling of Spandana borrowers and for higher probability of tracking them. We estimated\\\\ntwo sets of regressions with a different specification: no control whatsoever, and control for\\\\nstrata rather than for the average characteristics in the control slums. The results (not reported\\\\nhere, but available on request) are qualitatively unchanged. Controlling for strata somewhat\\\\nincreases the precision in this case, so some results that are almost significant here become\\\\nsignificant with strata controls (this is particularly true for the grouped outcomes).\\\\nIn any study of this kind, where there are many possible outcomes without a single possible\\\\ncausal pathways, there is a danger of overinterpreting any single significant result (or even\\\\ndiscerning a pattern of results when there is none). We take a number of steps to avoid this\\\\nproblem. First, we report the outcome following the template that all papers in this issue follow,\\\\ninsuring no selection of outcomes based on what is significant or not. Second, for each table\\\\n(which corresponds to a \\u201cfamily\\u201d of outcomes) we report an index (a la Katz, Kling and Liebman\\\\n2007) of all the outcomes in the family taken together.12 Finally, for each of these outcomes,\\\\nwe report both the standard p-value and the p-value adjusted for multiple hypotheses testing\\\\nacross all the indices. The adjusted p-values are calculated using the step-down procedure of\\\\nHochberg (1988), which controls the family-wise error rate for all the indices. See Appendix A.4\\\\nfor details.\\\\n12The variables are signed such at that a positive treatment effect is a \\u201cgood\\u201d outcome. They are then normalized\\\\nby subtracting the mean in the control group and dividing by the standard deviation in the control group. The\\\\nindex is the simple average of the normalized variables.\\\\n15\\\\n4.1 Borrowing from Spandana and other MFIs\\\\nTreatment communities were randomly selected to receive Spandana branches, but other MFIs\\\\nalso started operating both in treatment and comparison areas. We are interested in testing the\\\\nimpact of access to microcredit, not only of borrowing from Spandana. Table 2 Panel A shows\\\\nthat, by the first endline, MFI borrowing was indeed higher in treatment than in control slums,\\\\nalthough borrowing from other MFIs made up for part of the difference in Spandana borrowing.\\\\nHouseholds in treatment areas are 12.7 percentage points more likely to report being Spandana\\\\nborrowers\\u201317.8% versus 5.1% (Table 2 Panel A, column 1). The difference in the percentage\\\\nof households saying that they borrow from any MFI is 8.4 points (Table 2 Panel A, column\\\\n3), so some households who ended up borrowing from Spandana in treatment areas would have\\\\nborrowed from another MFI in the absence of the intervention. While the absolute level of total\\\\nMFI borrowing is not very high, it is about 50% higher in treatment than in comparison areas.\\\\nColumns 1 and 3 show that treatment households also report significantly more borrowing from\\\\nMFIs (and from Spandana in particular) than comparison households. Averaged over borrowers\\\\nand non-borrowers, treatment households report Rs. 1,334 more borrowing from Spandana than\\\\ndo control households, and Rs. 1,286 more from all MFIs (both significant at the 1% level).\\\\nWhile both the absolute take-up rate and the implicit \\u201cfirst stage\\u201d are relatively small, this\\\\nappears to be similar to what was found in most other evaluations of the impact of access to\\\\nmicrofinance, despite the different contexts. In rural Morocco, Cr\\u00e9pon et al. (2013) find that\\\\nthe probability of having any loan from the MFI Al Amana in areas which got access to it is 10\\\\npercentage points, whereas it is essentially zero in control, and moreover, since there is no other\\\\nMFI, this represents the total increase in microfinance borrowing. In Mexico, Angelucci, Karlan\\\\nand Zinman (2013) find an increase of 10 percentage points in the probability of borrowing\\\\nfrom the MFI Compartamos in areas that got access to the lender, relative to a base of five\\\\npercentage points in the control. In Ethiopia, Tarozzi et al. (2013) find a larger impact of\\\\nmicrocredit introduction: 36%.\\\\nThe fairly low take-up rate in these different contexts is in itself a striking result, given the\\\\nhigh levels of informal borrowing in these communities and the purported benefits of microcredit\\\\nover these alternative forms of borrowing. In all cases, except when the randomization was\\\\namong those who had already expressed explicit interest in microcredit, only a minority of\\\\n16\\\\n\\u201clikely borrowers\\u201d end up borrowing.\\\\nTable 2 also displays the impact of microfinance access on other forms of borrowing. A\\\\nsizable fraction of the clients report repaying a more expensive debt as a reason to borrow from\\\\nSpandana, and we do indeed see some action on this margin. The share of households who have\\\\nsome informal borrowing\\u2013defined as borrowing from family, friends, moneylenders and goods\\\\npurchased on credit extended by the seller\\u2013goes down by 5.2 percentage points in treatment\\\\nareas (column 5), but bank borrowing is unaffected (column 4). The point estimate of the\\\\namount borrowed from informal sources is also negative, suggesting substitution of expensive\\\\nborrowing with cheaper MFI borrowing (an explicit objective of Spandana), and the point\\\\nestimate, though insignificant, is quite similar in absolute value to the increase in MFI borrowing\\\\n(column 5). However, given the high level of informal borrowing, this corresponds to a decline\\\\nof only 2.6%: When we examine the distribution of endline 1 informal borrowing, in Figure 1,\\\\ninformal borrowing is significantly lower in treatment areas from the 30th to 65th percentiles.\\\\nOverall, treatment affects the index of borrowing outcomes, and the p-value is small even when\\\\naccounting for multiple hypothesis testing across families (column 9).\\\\nAfter the end of the first endline, following our initial agreement with Spandana, Spandana\\\\nstarted to expand in these areas. Other MFIs also continued their expansion. However, two\\\\nyears later a significant difference still remained between Spandana slums and others: Table 2\\\\nPanel B shows that 17% of the households in the treatment slums borrowed from Spandana,\\\\nagainst 11% in the control slums. Other MFIs continued to expand both in the former treatment\\\\nand control slums, and MFI lending overall was almost the same in the treatment and the control\\\\ngroup. By the second endline survey, 33.1% of households had borrowed from an MFI in the\\\\nformer control slums, and 33.3% in the treatment slums. Since lending started later in the\\\\ncontrol group, however, households in the treatment group had on average been borrowing for\\\\nlonger than those in the control group, which is reflected in the fact that they had completed\\\\nmore loan cycles. On average, there was a difference of 0.085 loan cycles between the treatment\\\\nand the control households at endline 2 (column 8), which is almost unchanged from endline\\\\n1.13 The primary difference between treatment and control group at endline 2 is thus the length\\\\n13This difference is no longer significant at EL2, possibly owing to recall error and to the fact that we only collected information on the maximum number of cycles borrowed from any MFI, so this figure does not distinguish,\\\\ne.g., a household that borrowed three cycles each from two lenders versus three cycles from one lender.\\\\n17\\\\nof access to microfinance. Since microfinance loans grow with each cycle, treatment households\\\\nalso had larger loans. Among those who borrow, there was by endline 2 a significant difference\\\\nof about Rs. 2,300 (or 14%) in the size of the loans (not reported). Since about one third of\\\\nhouseholds borrow, this translates into an (insignificant) difference of about Rs. 800 in average\\\\nborrowing (column 3).\\\\n4.2 New businesses and business outcomes\\\\nPanel A in Table 3 presents the results from the first endline on business outcomes. Column\\\\n8 indicates that the probability that a household starts a business is in fact not significantly\\\\ndifferent in treatment and control areas. In comparison areas, 4.7% of households opened at\\\\nleast one business in the year prior to the survey, compared to 5.6% in treated areas (column\\\\n8). However, treatment households were somewhat more likely to have opened more than one\\\\nbusiness in the past year, and column 10 shows that more new businesses were created in\\\\ntreatment areas overall: 6.8 per 100 households, versus 5.3 per 100 households in control areas.\\\\nThe 90% confidence interval on new business creation ranges from an additional 0.3pp to 2.6pp\\\\nadditional new businesses. Overall treatment households are no more likely to have a business\\\\nand they don\\u2019t have significantly more businesses (columns 6 and 7).\\\\nConsistent with the fact that Spandana lends only to women, and with the stated goals\\\\nof microfinance institutions, the marginal businesses tend to be female-operated: column 11\\\\nshows that when we look at creation of businesses that are owned by women14 (column 11), we\\\\nfind that almost all of the differential business creation in treatment areas is in female-operated\\\\nbusinesses\\u2013there are 0.014 percentage points more female-owned businesses in treatment than\\\\nin control areas, an increase of 55%. Households in treated areas were no more likely to report\\\\nclosing a business, an event reported by 3.9% of households in treatment areas and 3.7% of the\\\\nhouseholds in comparison areas (column 9).15\\\\nTreatment households invest more in durables for their businesses. Since only a third of\\\\n14A business is classified as owned by a woman if the first person named in response to the question \\u201cWho is\\\\nthe owner of this business?\\u201d is female. Only 72 out of 2674 businesses have more than one owner. Classifying a\\\\nbusiness as owned by a woman if any person named as the owner is female does not change the result.\\\\n15It is possible that households not represented in our sample, such as households that had not lived in the area\\\\nfor three years, may have been differentially likely to close businesses in treated areas. However, the relatively\\\\nsmall amount of new business creation makes general-equilibrium effects on existing businesses rather unlikely.\\\\n18\\\\nhouseholds have a business, and most businesses use no assets whatsoever, the point estimate is\\\\nsmall in absolute value (Rs. 391 over the last year, or a bit less than a third of the increase in\\\\naverage MFI borrowing in treatment households) but the increment in treatment is more than\\\\nthe total value of business durables purchased in the last year by comparison households (Rs.\\\\n280), and is statistically significant.\\\\nThe rest of the columns in the Panel A of Table 3 report on current business status and last\\\\nmonth\\u2019s revenues, inputs costs, and profits (exclusive of interest payments). In these regressions,\\\\nwe assign a zero to those households that do not have a business, so these results give us the\\\\noverall impact of credit on business activities, including both the extensive and intensive margins.\\\\nTreatment households have more business assets (although the t-statistic on the asset stock is\\\\nonly 1.56). The treatment effects on revenues and inputs are both positive but insignificant.\\\\nFinally, there is an insignificant increase in business profits (column 5). Since this data\\\\nincludes zeros for households that do not have a business, this answers the question of whether\\\\nmicrocredit, as it is often believed, increases poor households\\u2019 income by expanding their business\\\\nopportunities. The point estimate, at Rs. 354 per month, corresponds to a roughly 50% increase\\\\nrelative to the profits received by the average comparison household. This is thus large in\\\\nproportion to profits, but it represents only a very small increase in disposable income for an\\\\naverage household\\u2013recall that the average total consumption of these households is about Rs.\\\\n7,000 per month and an increase of Rs. 354 per month in business revenues is certainly not\\\\ngoing to change the life of the average person who gets access to microcredit.\\\\nLooking at all businesses outcomes taken together, we find a 0.037 standard deviation increase in the standardized index of business outcomes, which is significant with conventional\\\\nstandard errors but not (p-value of 0.17) once the multiple hypothesis testing across different\\\\nfamilies of outcomes is taken into account.16\\\\nThis is the ITT estimate, and part of the reason it is low is that few households took\\\\nadvantage of microcredit in the treatment groups (and some did in the control as well). The\\\\nmarginal borrower in the treatment group may also have fewer opportunities than someone\\\\nwho was interested enough to borrow in the control group. This does not rule out that the\\\\nbusinesses of some specific groups could have benefited from the loan. To look at this in more\\\\n16It is significant even with this correction when we control for strata dummies\\\\n19\\\\ndetail, we focus on businesses that were already in existence before microcredit started. We do\\\\nthis in Table 3B.17 For businesses that existed before Spandana expanded, we find an expansion\\\\nin businesses (sales, inputs and investment), and the overall business index is significant and\\\\npositive, even after correcting for multiple inference (0.09 standard deviation, with a p value\\\\nof 0.057 after the correction). We find an average increase in profits of Rs. 2,206 in treatment\\\\nareas, which is statistically significant and represents more than doubling, relative to the control\\\\nmean of Rs. 2,000. This increase is not due to a few outliers; however, it is worth nothing it is\\\\nconcentrated in the upper tail (quantiles 95 and above), as shown in Figure 2. At every other\\\\nquantile, there is very little difference between the profits of existing businesses in treatment\\\\nand control areas. There are 75 businesses above the 95th percentiles, so it is not a handful,\\\\nbut the 95th percentile of monthly profit of existing businesses is Rs. 14,600 (or $1590 at PPP),\\\\nwhich makes them quite large and profitable businesses in this setting. The vast majority of\\\\nthe small businesses make very little profit to start with, and microcredit does nothing to help\\\\nthem. The finding that microcredit is most effective in helping already-profitable businesses is\\\\ncontrary both to much of the rhetoric of microcredit and the view of microcredit skeptics.\\\\nFinally, we have seen that the treatment led to some more business creation, particularly\\\\nfemale-owned businesses. In Figure 3, and Tables 3C and A4, we show more data on the characteristics of these new businesses. The quantile regressions in Figure 3 (profits for businesses\\\\nthat did not exist at baseline) show that all businesses between the 35th and 65th percentiles\\\\nhave significantly lower profits in treatment areas. Table 4, column 5 shows that the mean profit\\\\nis not significantly different across treatment and control due to the noisy data, but the median\\\\nnew business in treatment areas has Rs. 1,250 lower profits, significant at the 5% level (not\\\\nreported in tables, but shown in the figure). The average new business is also significantly less\\\\nlikely to have employees in the treatment areas: the number of employees per new business 0.29\\\\nto only 0.11 (column 6). For new businesses, the index across all outcomes is negative (0.081\\\\nstandard deviations) and significant with conventional levels but not after correcting for multiple\\\\ninference (p value, 0.028).\\\\nThese results could in principle be a combination of a treatment effect and a selection effect,\\\\n17In Table 3, we show that households are no more or less likely to close a business in the last year, thus there\\\\nis no sample selection induced by microfinance.\\\\n20\\\\nbut since the effect on existing businesses suggests a treatment effect which is close to zero\\\\nfor most businesses (and the point estimate is positive), the effect for new businesses is likely\\\\ndue to selection\\u2013the marginal business that gets started in treatment areas is less profitable\\\\nthan the marginal business in the control areas. The hypothesis that the marginal business\\\\nthat gets started is different in the treatment group gains some additional support in Appendix\\\\nTable 4, which shows a comparison of the industries of old businesses and new businesses, across\\\\ntreatment and comparison areas.18 Industry is a proxy for the average scale and capital intensity\\\\nof a business, which is likely to be measured with less error than actual scale or asset use. The\\\\nindustry composition of new businesses do differ. In particular, the fraction of food businesses\\\\n(tea/coffee stands, food vendors, kirana/small grocery stores, and agriculture) is 8.5 percentage\\\\npoints (about 45%) higher among new businesses in treatment areas than among new businesses\\\\nin comparison areas, and the fraction of rickshaw/driving businesses among new businesses in\\\\ntreatment areas is 5.4 (more than 50%) percentage points lower. Both these differences are\\\\nsignificant at the 10% level. Food businesses are the least capital-intensive businesses in these\\\\nareas, with assets worth an average of just Rs. 930 (mainly dosa tawas, pots and pans, etc.).\\\\nRickshaw/driving businesses, which require renting or owning a vehicle, are the most capitalintensive businesses, with assets worth an average of Rs. 12,697 (the bulk of which is the cost\\\\nof the vehicle).\\\\nMicrocredit would be expected to lower the profitability threshold to start a business, if\\\\ninterest rates are lower than those of other sources of lending available to the households. Another explanation for both results could be that, due to the fact that Spandana lends to women,\\\\nthe marginal businesses are more likely to be female owned, and are thus started in sectors in\\\\nwhich women are active. Furthermore, businesses operated by women generally tend to be less\\\\nprofitable, perhaps because of social constraints on what they can do and how much effort they\\\\ncan devote to an enterprise.19\\\\nPanel B of Table 3 shows the results for the business performance variables at the time of\\\\nthe second endline. As remarked already, by this time treatment and control households are\\\\nequally likely to have a microcredit loan, but the loan in treatment areas is bigger and borrowers\\\\n18Respondents could classify their businesses into 22 different types, which we grouped into the following: food,\\\\nclothing/sewing, rickshaw/driving, repair/construction, crafts vendor, and \\u201cother.\\u201d\\\\n19This is true in this data, and also found for example in Sri Lanka by de Mel et al. (2009).\\\\n21\\\\nhave been borrowing for a longer time. The results follow a clear pattern, consistent with the\\\\nidea that control households now borrow at the same rate. We find no significant difference in\\\\nbusiness creation in treatment and control areas: the point estimate is virtually zero (the 90%\\\\nconfidence interval ranges from 2pp fewer new businesses, to 2.5pp more). The new businesses\\\\nare in the same industries in treatment and control areas, and the negative effects for new\\\\nbusinesses at the median have disappeared (results omitted). For the contemporaneous flow\\\\ninvestment outcomes such as new business creation, business assets acquired in the previous\\\\nyear, etc. (columns 8 through 11) the point estimate is very close to zero (however the standard\\\\nerrors are large). On the other hand, businesses in treatment areas have significantly larger\\\\nasset stock (column 1), which reflects the cumulative effect of the past years during which they\\\\nhad a chance to borrow and expand. Despite this, their profits are still not significantly larger,\\\\nthough the point estimate is around 60% of the sample mean (with a t-statistic of around 1.5).\\\\nAs shown in Figure 4, the positive increase is once again concentrated in the top and bottom\\\\ntails, although it starts being positive a little earlier, at the 85th percentile.\\\\nOverall, microfinance is indeed associated with (some) business creation: in the first year, it\\\\ndoes lead to an increase in the number of new businesses created, particularly by women (though\\\\nnot in the number of households that start a business). However, these marginal businesses are\\\\neven smaller and less profitable than the average business in the area (the vast majority of\\\\nwhich are already small and unprofitable). It does also lead to a greater investment in existing\\\\nbusinesses, and an improvement in the profits for the most profitable of those businesses. For\\\\neveryone else, business profits do not increase, and on average microfinance does not help the\\\\nbusinesses to grow in any significant way. Even after three years, there is no increase in the\\\\nnumber of employees of businesses that existed before Spandana started its operation.\\\\n4.3 Labor supply\\\\nAccess to credit can lead to an increase in labor supply to finance an investment or the purchase\\\\nof durable goods which were out of reach before due to savings and borrowing constraints. This\\\\nis an area where different evaluations of microcredit have very different results, ranging from a\\\\nworrying increase in labor supply for teenagers in Augsburg et al. (2013) to steep decreases for\\\\neveryone in Cr\\u00e9pon et al. (2013). Table 5 shows the impact of the program on labor supply. In\\\\n22\\\\nendline 1, the household head and spouse in treatment households increase their overall labor\\\\nsupply by an average of 3.18 hours (90% CI: 0.84, 5.5). The increase occurs entirely in the\\\\nhouseholds\\u2019 own businesses, and there is no increase in number of hours worked for wages: those\\\\nhours may be much less elastic, if the households do not fully choose them. However, we do not\\\\nfind the increase in teenagers\\u2019 labor supply that is sometimes feared to be a potential downside\\\\nof microfinance and that was found in the Bosnia study (as the adolescents are drawn into the\\\\nbusiness by their parents); indeed teenage girls work about two hours less per week in treatment\\\\nthan control areas, and this difference is significant. Given that there is an increase among adults\\\\nand a decrease among teens, the overall index is, not surprisingly, close to zero and insignificant.\\\\nBy endline 2, as control households have started borrowing, the difference between treatment\\\\nand control disappears.\\\\n4.4 Consumption\\\\nTable 6 gives intent-to-treat estimates of the effect of microfinance on household spending.\\\\nColumns 1 and 3 of Panel A shows that there is no significant difference in total household\\\\nexpenditures\\u2013either total or non-durable\\u2013per adult equivalent, between treatment and comparison households. The point estimate is essentially zero in both cases and we can reject at the 5%\\\\nlevel the null hypothesis that there was a Rs. 85 per month increase in total consumption per\\\\nadult equivalent and Rs. 56 in non-durable consumption (about 6% of the average in control for\\\\nconsumption, and 4% for non-durable consumption) increase.20 Hence, enhanced microcredit\\\\naccess does not appear to be associated with any meaningful increase in consumption after 15\\\\nto 18 months. Of course, this may partly be due to the fact that relatively few people borrow,\\\\nand that some in the control group borrow from another MFI.21\\\\nWhile there are no significant impacts on average consumption and non-durable consumption,\\\\nthere are shifts in the composition of expenditure: column 2 shows that households in treatment\\\\nareas spent a statistically significant Rs. 17.08 more per capita per month22, or Rs. 205 per\\\\n20The 90% CIs are (-51, 71) for total consumption and (-59, 46) for non-durable consumption.\\\\n21For total consumption, the implied treatment on the treated (TOT) or IV estimate is a Rs. 119 (10/.084),\\\\nor 5%, increase, and for non-durable consumption it is a Rs. 75 (4%) decrease. However, the 90% confidence\\\\ninterval on the TOT estimate is wide, ranging from an increase of Rs 840 (or 60%) to a decrease of Rs. 600 (or\\\\n43%). The width of the TOT confidence intervals stems, of course, from the low first stage.\\\\n22The 90% CI is (1, 33).\\\\n23\\\\ncapita over the last year, on durables than did households in comparison areas. Note that this is\\\\nprobably an underestimate of the total effect of loans on durable purchases, since our measure\\\\nwould miss anyone who borrowed more than a year before the survey (the survey was 15 to 18\\\\nmonths after the centers opened) and immediately bought a durable with the loan. The most\\\\ncommonly purchased durables include gold and silver, motorcycles, sarees (purchased in bulk,\\\\npresumably mainly for weddings or as stock for a business), color TVs, refrigerators, rickshaws,\\\\ncomputers and cellphones.\\\\nColumns 7 and 8 show that while there was no detectable change in non-durable spending\\\\notherwise; the increase in durable spending by treatment households was essentially offset by\\\\nreduced spending on \\u201ctemptation goods\\u201d and festivals. Temptation goods are goods that households in our baseline survey said that they would like spend less on (this is thus the same list of\\\\ngoods for all households). They include in this case alcohol, tobacco, betel leaves, gambling, and\\\\nfood consumed outside the home. Spending on temptation goods is reduced by about Rs. 9 per\\\\ncapita per month (column 7). We also see in column 8 a large fall in festival spending per capita\\\\nin the previous year (Rs. 12 or 20% of the control level, significant at the 10% level). Together,\\\\nthe average drop in consumption in temptation goods and festivals is Rs. 21 per capita per\\\\nmonth. The decrease in festival expenditures does not come from large changes in large, very\\\\nexpensive ceremonies such as weddings (we see very few of them in the data) but rather appears\\\\nto come from declines at all levels of the distribution of spending on festivals.\\\\nThe absolute magnitude of these changes is relatively small: for instance, the Rs. 17 of\\\\nincreased durables spending per capita per month at endline 1 is approximately $1.75 at 2007\\\\nPPP exchange rates. However, this represents an increase of about 17% relative to total spending\\\\non durable goods in comparison areas. Furthermore, this figure averages over non-borrowers and\\\\nborrowers, and would be larger if it was attributed to borrowers alone.\\\\nPanel B of Table 6 reports on the impact effects at the time of the second endline, when\\\\nboth treatment and control households have access to the microfinance program. The effects on\\\\nboth total per capita spending and total per capita non-durable spending (columns 1 and 3) are\\\\nnegative with t-statistics around 1. Spending on temptation goods is still lower by about Rs.\\\\n10 per month (column 7), similar to endline 1, though the effect is now insignificant. The effect\\\\non festivals is now positive but insignificant. There is also no difference on average in durable\\\\n24\\\\ngoods spending in endline 2 (column 2). Given that the main difference between treatment and\\\\ncontrol households at endline 2 is that treatment households have been borrowing for longer,\\\\nthis suggests that, in the second cycle, households in the treatment seem to just repeat the first\\\\ncycle with another durable (of roughly the same size), while households in the control group\\\\nalso acquire a durable.\\\\n4.5 Microfinance as social revolution: education, child labor, and women\\u2019s\\\\nempowerment?\\\\nThe evidence so far suggests a different picture from the standard description of the role of\\\\nmicrofinance in the life of the poor: the pent-up demand for it is not overwhelming; many\\\\nhouseholds use their loan to acquire a household durable, reducing avoidable consumption to\\\\nfinance it; some invest in their businesses, but this does not lead to significant growth in the\\\\nprofitability of most businesses. Another staple of the microfinance literature is that because\\\\nthe loans are given to women and give them a chance to start their own businesses, this would\\\\nlead to a more general empowerment of women in the households, and this empowerment would\\\\nin turn translate in better outcomes for everyone, including education, health, etc. (e.g. CGAP,\\\\n2009). Indeed, we see a significant increase in the number of businesses managed by women in\\\\nendline 1 (Table 7, column 9).23 To examine whether this increase in women\\u2019s entrepreneurship\\\\ntranslates into increased bargaining power for women, Table 7 examines the effects of access\\\\nto microfinance on measures of women\\u2019s decision-making and children\\u2019s education and labor\\\\nsupply.\\\\nA finding of many studies of household decision-making is that an increase in women\\u2019s\\\\nbargaining power leads to an increase in investments in children\\u2019s human capital (see Thomas,\\\\n1990 and Duflo, 2003). However, we find that there is no change in the probability that children\\\\nor teenagers are enrolled in school (Table 7, columns 1, 2, 5 and 6), although we do see a\\\\nreduction in teenage girls\\u2019 labor supply (Table 5, column 5). There is no difference in private\\\\nschool fees, or in private school versus public school enrollment (results not reported to save\\\\nspace). There is also no difference in the number of hours worked by girls or boys aged 5 to 15\\\\n23There is no difference in the number of women-run businesses between treatment and control in endline 2,\\\\nwhich is unsurprising since all areas have access to microfinance at that point.\\\\n25\\\\n(columns 3 and 4).\\\\nBecause there are many possible proxies for women\\u2019s empowerment, and many \\u201csocial\\u201d\\\\noutcomes we use the approach of Kling et al. (2007) to test the null hypothesis of no effect\\\\nof microcredit on \\u201csocial outcomes\\u201d against the alternative that microcredit improves social\\\\noutcomes. We construct an equally weighted average of z-scores for the 16 social outcomes;\\\\nthis method gives us maximal power to detect an effect on social outcomes, if such an effect\\\\nis present.24 Column 7 shows that there is no effect on the index of social outcomes (point\\\\nestimate .007 standard deviations) and we can rule out an increase of more than one twentieth\\\\nof a standard deviation with 95% confidence.25\\\\nThis suggests that there is no prima facie evidence that microcredit leads to important\\\\nchanges in household decision-making or in social outcomes. Furthermore, this appears to be\\\\nnot only because we observe this only in the short run. Nothing major changes by endline 2:\\\\nthe effect of microfinance access on the index of women empowerment is still very small (indeed,\\\\nslightly negative) and insignificant, and anything but a small effect can still be ruled out. Recall\\\\nthat we are comparing households who, by EL2, are equally likely to borrow: the main difference\\\\nby EL2 is that households in the treatment group have had greater access to microfinance for\\\\nthe first 18 months; this may limit power to detect differences in the social outcomes at the\\\\ncommunity level.\\\\n5 Conclusion\\\\nThis study\\u2013the first and longest running evaluation of the standard group-lending loan product\\\\nthat has made microfinance known worldwide\\u2013yields a number of results that may prompt a\\\\nrethinking of the role of microfinance.\\\\nThe first result is that, in contrast to the claims sometimes made by MFIs and others\\\\n(including our partner), demand for microloans is far from universal. By the end of our three24The 16 outcomes we use are: indicators for women making decisions on each of food, clothing, health, home\\\\npurchase and repair, education, durable goods, gold and silver, investment; levels of spending on school tuition,\\\\nfees, and other education expenses; medical expenditure; teenage girls\\u2019 and teenage boys\\u2019 school enrollment; and\\\\ncounts of female children under one year and one to two years old. We selected these outcomes because they\\\\nwould likely be affected by changes in women\\u2019s bargaining power within the household.\\\\n25The 95% CI is (-.04, .05). The units are standard deviations.\\\\n26\\\\nyear study period, only 38% of households borrow from an MFI26, and this is among households\\\\nselected based on their relatively high propensity to take up microcredit. This does not appear\\\\nto be an anomaly: two other randomized interventions that have a similar design (in Morocco\\\\nand in Mexico) also find relatively low take-up, while another study in rural South India that\\\\nfocuses specifically on take-up of microfinance also finds it to be low (Banerjee et al. 2013).\\\\nPerhaps despite evidence of high marginal rates of return among microbusinesses, e.g. de Mel et\\\\nal. (2008), most households either do not have a project with a rate of return of at least 24%, the\\\\nAPR on a Spandana loan, or simply prefer to borrow from friends, relatives, or moneylenders\\\\ndue to the greater flexibility those sources provide, despite costs such as higher interest (from\\\\nmoneylenders) or embarrassment (when borrowing from friends or relatives) (Collins et. al\\\\n2009).\\\\nFor those who choose to borrow, while microcredit \\u201csucceeds\\u201d in leading some of them to\\\\nexpand their businesses (or choose to start a female-owned business), it does not appear to fuel\\\\nan escape from poverty based on those small businesses. Monthly consumption, a good indicator\\\\nof overall welfare, does not increase for those who had early access to microfinance, neither in\\\\nthe short run (when we may have foreseen that it would not increase, or perhaps even expected\\\\nit to decrease, as borrowers finance the acquisition of household or business durable goods), nor\\\\nin the longer run, after this crop of households have access to microcredit for a while, and those\\\\nin the former control group should be the ones tightening their belts. Business profit does not\\\\nincrease for the vast majority of businesses, although there are significant increases in the upper\\\\ntail of profitability. This study took place in a dynamic urban environment, in a context of very\\\\nhigh growth. Microcredit seems to have played very little part in it but may have had different\\\\nimpacts in other settings.\\\\nFurthermore, in the Hyderabadi context, we find that access to microcredit appears to have\\\\nno discernible effect on education, health, or women\\u2019s empowerment in the short run. In the\\\\nlonger run (when borrowing rates are the same, but households in the treatment groups have on\\\\naverage borrowed for longer), there is still no impact on women\\u2019s empowerment or other social\\\\noutcomes. The results differ from study to study on these outcomes, but as a whole they don\\u2019t\\\\npaint a picture of dramatic changes in basic development outcomes for poor families.\\\\n26The take-up rate is 42% in treatment areas and 33% percent in control areas.\\\\n27\\\\nMicrocredit therefore may not be the \\u201cmiracle\\u201d that it is sometimes claimed to be, although\\\\nit does allow some households to invest in their small businesses. One reason may be that the\\\\naverage business run by this target group is tiny (almost none of them have an employee), not\\\\nparticularly profitable, and difficult to expand, even in a high-growth context, given the skill\\\\nsets of the entrepreneurs and their life situations. And the marginal businesses that get created\\\\nthanks to microcredit are probably even less profitable and dynamic: we find that the average\\\\nnew business in a microcredit treatment area is less likely to have an employee than the new\\\\nbusiness in the control areas, and the median new business is even less profitable in treatment\\\\nversus control areas.\\\\nNevertheless, microcredit does affect the structure of household consumption. We see households invest in home durable goods and restrict their consumption of temptation goods and\\\\nexpenditures on festivals and parties. They continue to do so several years later, and this decrease is not due to a few particularly virtuous households, but seems to be spread across the\\\\nsample. Similar declines in these types of expenses are also found in all the other studies. Altered\\\\nconsumption thus does not seem to be tied to the ideology of a particular MFI.\\\\nMicrofinance affects labor supply choices as well: here we find that households that have\\\\naccess to loans seem to work harder on their own businesses; in other settings they are found to\\\\ncut arduous labor elsewhere. Thus, microcredit plays its role as a financial product in an environment where access is limited, not only to credit but also to saving opportunities. It expands\\\\nhouseholds\\u2019 abilities to make different intertemporal choices, including business investment. The\\\\nonly mistake that the microcredit enthusiasts may have made is to overestimate the potential\\\\nof businesses for the poor, both as a source of revenue and as a means of empowerment for their\\\\nfemale owners.\"\n", + " }\n", + " ]\n", + " }\n", + "]\n" + ] + } + ], + "source": [ + "# import necessary modules.\n", + "import base64\n", + "import copy\n", + "import json\n", + "import pathlib\n", + "import requests\n", + "\n", + "\n", + "import PIL.Image\n", + "import IPython.display\n", + "from IPython.display import Markdown\n", + "\n", + "try:\n", + " # The SDK will automatically read it from the GOOGLE_API_KEY environment variable.\n", + " # In Colab get the key from Colab-secrets (\"🔑\" in the left panel).\n", + " import os\n", + " from google.colab import userdata\n", + "\n", + " os.environ[\"GOOGLE_API_KEY\"] = userdata.get(\"GOOGLE_API_KEY\")\n", + "except ImportError:\n", + " pass\n", + "\n", + "import google.generativeai as genai\n", + "\n", + "# Parse the arguments\n", + "\n", + "model = 'gemini-1.5-pro' # @param {isTemplate: true}\n", + "contents_b64 = 'W3sicm9sZSI6InVzZXIiLCJwYXJ0cyI6W3sidGV4dCI6IllvdSBhcmUgYW4gZXhwZXJ0IHNjaWVudGlmaWMgcmVzZWFyY2hlciB3aG8gaGFzIHllYXJzIG9mIGV4cGVyaWVuY2UgaW4gY29uZHVjdGluZyBzeXN0ZW1hdGljIGxpdGVyYXR1cmUgc3VydmV5cyBhbmQgbWV0YS1hbmFseXNlcyBvZiBkaWZmZXJlbnQgdG9waWNzLiBZb3UgcHJpZGUgeW91cnNlbGYgb24gaW5jcmVkaWJsZSBhY2N1cmFjeSBhbmQgYXR0ZW50aW9uIHRvIGRldGFpbC4gWW91IGFsd2F5cyBzdGljayB0byB0aGUgZmFjdHMgaW4gdGhlIHNvdXJjZXMgcHJvdmlkZWQsIGFuZCBuZXZlciBtYWtlIHVwIG5ldyBmYWN0cy4gXFxuXFxuTm93IGxvb2sgYXQgdGhlIHJlc2VhcmNoIHBhcGVyIGJlbG93LCBhbmQgYW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zIGluIDEtMiBzZW50ZW5jZXMuXFxuMS4gV2hlbiB3YXMgdGhlIHBhcGVyIHB1Ymxpc2hlZD9cXG4yLiBXaGF0IGlzIHRoZSBzYW1wbGUgc2l6ZT9cXG4zLiBXaGF0IGlzIHRoZSBzdHVkeSBtZXRob2RvbG9neT8gaW4gcGFydGljdWxhciwgaXMgaXQgYSByYW5kb21pemVkIGNvbnRyb2wgdHJpYWw/IFxcbjQuIEhvdyB3YXMgdGhlIHN0dWR5IGZ1bmRlZD8gaW4gcGFydGljdWxhciwgd2FzIHRoZSBmdW5kaW5nIGZyb20gY29tbWVyY2lhbCBmdW5kZXJzP1xcbjUuIFdoYXQgd2FzIHRoZSBrZXkgcXVlc3Rpb24gYmVpbmcgc3R1ZGllZD9cXG42LiBXaGF0IHdlcmUgdGhlIGtleSBmaW5kaW5ncyB0byB0aGUga2V5IHF1ZXN0aW9uIGJlaW5nIHN0dWRpZWQ/XFxuXFxuXFxuUmVzZWFyY2ggcGFwZXI6IFxcblRoZSBtaXJhY2xlIG9mIG1pY3JvZmluYW5jZT8gRXZpZGVuY2UgZnJvbSBhIHJhbmRvbWl6ZWQgZXZhbHVhdGlvbuKIl1xcbkFiaGlqaXQgQmFuZXJqZWXigKAgRXN0aGVyIER1Zmxv4oChIFJhY2hlbCBHbGVubmVyc3RlcsKnIEN5bnRoaWEgS2lubmFuwrZcXG5UaGlzIHZlcnNpb246IE1hcmNoLCAyMDE0XFxuQWJzdHJhY3RcXG5UaGlzIHBhcGVyIHJlcG9ydHMgcmVzdWx0cyBmcm9tIHRoZSByYW5kb21pemVkIGV2YWx1YXRpb24gb2YgYSBncm91cCBsZW5kaW5nIG1pY3JvY3JlZGl0IHByb2dyYW0gaW4gSHlkZXJhYmFkLCBJbmRpYS4gQSBsZW5kZXIgd29ya2VkIGluIDUyIHJhbmRvbWx5IHNlbGVjdGVkIG5laWdoYm9yaG9vZHMsIGxlYWRpbmcgdG8gYW5cXG44LjQgcGVyY2VudGFnZSBwb2ludCBpbmNyZWFzZSBpbiB0YWtldXAgb2YgbWljcm9jcmVkaXQuIFNtYWxsIGJ1c2luZXNzIGludmVzdG1lbnQgYW5kIHByb2ZpdHMgb2ZcXG5wcmUtZXhpc3RpbmcgYnVzaW5lc3NlcyBpbmNyZWFzZWQsIGJ1dCBjb25zdW1wdGlvbiBkaWQgbm90IHNpZ25pZmljYW50bHkgaW5jcmVhc2UuIER1cmFibGUgZ29vZHNcXG5leHBlbmRpdHVyZSBpbmNyZWFzZWQsIHdoaWxlIOKAnHRlbXB0YXRpb24gZ29vZHPigJ0gZXhwZW5kaXR1cmUgZGVjbGluZWQuIFdlIGZvdW5kIG5vIHNpZ25pZmljYW50XFxuY2hhbmdlcyBpbiBoZWFsdGgsIGVkdWNhdGlvbiwgb3Igd29tZW7igJlzIGVtcG93ZXJtZW50LiBUd28geWVhcnMgbGF0ZXIsIGFmdGVyIGNvbnRyb2wgYXJlYXMgaGFkXFxuZ2FpbmVkIGFjY2VzcyB0byBtaWNyb2NyZWRpdCBidXQgaG91c2Vob2xkcyBpbiB0cmVhdG1lbnQgYXJlYSBoYWQgYm9ycm93ZWQgZm9yIGxvbmdlciBhbmQgaW4gbGFyZ2VyXFxuYW1vdW50cywgdmVyeSBmZXcgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgcGVyc2lzdC4gSkVMIGNvZGVzOiBPMTYsIEcyMSwgRDIxXFxu4oiXVGhpcyBwYXBlciB1cGRhdGVzIGFuZCBzdXBlcnNlZGVzIHRoZSAyMDEwIHZlcnNpb24sIHdoaWNoIHJlcG9ydGVkIHJlc3VsdHMgdXNpbmcgb25lIHdhdmUgb2YgZW5kbGluZSBzdXJ2ZXlzLiBGdW5kaW5nXFxuZm9yIHRoZSBmaXJzdCB3YXZlIG9mIHRoZSBzdXJ2ZXkgd2FzIHByb3ZpZGVkIGJ5IFRoZSBWYW5ndWFyZCBDaGFyaXRhYmxlIEVuZG93bWVudCBQcm9ncmFtIGFuZCBJQ0lDSSBiYW5rLiBGdW5kaW5nXFxuZm9yIHRoZSBzZWNvbmQgd2F2ZSB3YXMgcHJvdmlkZWQgYnkgU3BhbmRhbmEgYW5kIEotUEFMLiBUaGlzIGRyYWZ0IHdhcyBub3QgcmV2aWV3ZWQgYnkgdGhlIFRoZSBWYW5ndWFyZCBDaGFyaXRhYmxlXFxuRW5kb3dtZW50IFByb2dyYW0sIElDSUNJIEJhbmssIG9yIFNwYW5kYW5hLiBUaGUgQ2VudHJlIGZvciBNaWNybyBGaW5hbmNlIGF0IHRoZSBJbnN0aXR1dGUgZm9yIEZpbmFuY2lhbCBNYW5hZ2VtZW50XFxuUmVzZWFyY2ggKElGTVIpIChDaGVubmFpLCBJbmRpYSkgc2V0IHVwIGFuZCBvcmdhbml6ZWQgdGhlIGV4cGVyaW1lbnQgYW5kIHRoZSBkYXRhIGNvbGxlY3Rpb24sIGFuZCBtYWRlIHRoZSBhbm9ueW1pemVkXFxuZGF0YSBhdmFpbGFibGUgZmlyc3QgdG8gdGhlIHJlc2VhcmNoIHRlYW0sIGFuZCB0aGVuIHB1YmxpY2x5LiBBdCB0aGUgdGltZSwgSUZNUiBkaWQgbm90IGhhdmUgYW4gSVJCLiBEYXRhIGFuYWx5c2lzXFxuYW5kIG9uLWdvaW5nIGRhdGEgY29sbGVjdGlvbiBoYXZlIHJlY2VpdmVkIElSQiBhcHByb3ZhbCBmcm9tIE1JVCBDT1VIRVMgKDEyMDMwMDQ5NzMpIGFuZCBOb3J0aHdlc3Rlcm4gVW5pdmVyc2l0eVxcbihTVFUwMDA2MzYzNikuIEFkaWUgQW5ncmlzdCwgTGVvbmFyZG8gRWxpYXMsIEhhcnJpcyBFcHBzdGVpbmVyLCBTaGVobGEgSW1yYW4sIFNlZW1hIEthY2tlciwgVHJhY3kgTGksIEFkaXRpIE5hZ2FyYWpcXG5hbmQgQ2VjaWxpYSBQZWx1ZmZvIHByb3ZpZGVkIGV4Y2VsbGVudCByZXNlYXJjaCBhc3Npc3RhbmNlLiBEYXRhc2V0cyBmb3IgYm90aCB3YXZlcyBvZiBkYXRhIHVzZWQgaW4gdGhpcyBwYXBlciBhcmUgYXZhaWxhYmxlXFxuYXQgaHR0cDovL3d3dy5jZW50cmUtZm9yLW1pY3JvZmluYW5jZS5vcmcvcHVibGljYXRpb25zL2RhdGEvLiBUaGUgYXV0aG9ycyB3aXNoIHRvIGV4dGVuZCB0aGFua3MgdG8gQ01GIGFuZCBTcGFuZGFuYVxcbmZvciBvcmdhbml6aW5nIHRoZSBleHBlcmltZW50LCB0byBQYWRtYWphIFJlZGR5IChDRU8gb2YgU3BhbmRhbmEpIHdob3NlIGNvbW1pdG1lbnQgdG8gdW5kZXJzdGFuZGluZyB0aGUgaW1wYWN0IG9mXFxubWljcm9maW5hbmNlIG1hZGUgdGhpcyBwcm9qZWN0IHBvc3NpYmxlLCB0byBBbm5pZSBEdWZsbyAodGhlIGV4ZWN1dGl2ZSBkaXJlY3RvciBvZiBDTUYgYXQgdGhlIHRpbWUgb2YgdGhlIHN0dWR5KSBmb3Igc2V0dGluZ1xcbnVwIHRoaXMgcHJvamVjdCwgYW5kIHRvIG51bWVyb3VzIHNlbWluYXIgYXVkaWVuY2VzIGFuZCBjb2xsZWFndWVzIGZvciBpbnNpZ2h0ZnVsIHN1Z2dlc3Rpb25zLlxcbuKAoE1JVCBEZXBhcnRtZW50IG9mIEVjb25vbWljcyAsIE5CRVIgYW5kIEotUEFMLiBFbWFpbDogYmFuZXJqZWVAbWl0LmVkdVxcbuKAoU1JVCBEZXBhcnRtZW50IG9mIEVjb25vbWljcywgTkJFUiBhbmQgSi1QQUwuIEVtYWlsOiBlZHVmbG9AbWl0LmVkdVxcbsKnXFxuSi1QQUwuIEVtYWlsOiByZ2xlbm5lckBtaXQuZWR1XFxuwrZOb3J0aHdlc3Rlcm4gVW5pdmVyc2l0eSBEZXBhcnRtZW50IG9mIEVjb25vbWljcyBhbmQgTkJFUi4gRW1haWw6IGMta2lubmFuQG5vcnRod2VzdGVybi5lZHVcXG4xXFxuMSBJbnRyb2R1Y3Rpb25cXG5NaWNyb2ZpbmFuY2UgaW5zdGl0dXRpb25zIChNRklzKSBoYXZlIGV4cGFuZGVkIHJhcGlkbHkgb3ZlciB0aGUgbGFzdCAxMCB0byAxNSB5ZWFyczogYWNjb3JkaW5nXFxudG8gdGhlIE1pY3JvY3JlZGl0IFN1bW1pdCBDYW1wYWlnbiAoMjAxMiksIHRoZSBudW1iZXIgb2YgdmVyeSBwb29yIGZhbWlsaWVzIHdpdGggYSBtaWNyb2xvYW5cXG5oYXMgZ3Jvd24gbW9yZSB0aGFuIDE4LWZvbGQgZnJvbSA3LjYgbWlsbGlvbiBpbiAxOTk3IHRvIDEzNy41IG1pbGxpb24gaW4gMjAxMC4gTWljcm9jcmVkaXQgaGFzXFxuZ2VuZXJhdGVkIGNvbnNpZGVyYWJsZSBlbnRodXNpYXNtIGFuZCBob3BlIGZvciBmYXN0IHBvdmVydHkgYWxsZXZpYXRpb24sIGN1bG1pbmF0aW5nIGluIHRoZVxcbk5vYmVsIFByaXplIGZvciBQZWFjZSwgYXdhcmRlZCBpbiAyMDA2IHRvIE1vaGFtbWVkIFl1bnVzIGFuZCB0aGUgR3JhbWVlbiBCYW5rIGZvciB0aGVpclxcbmNvbnRyaWJ1dGlvbiB0byB0aGUgcmVkdWN0aW9uIGluIHdvcmxkIHBvdmVydHkuIEluIHRoZSBsYXN0IHNldmVyYWwgeWVhcnMsIGhvd2V2ZXIsIHRoZSBlbnRodXNpYXNtXFxuZm9yIG1pY3JvY3JlZGl0IGhhcyBiZWVuIG1hdGNoZWQgYnkgYW4gZXF1YWxseSBzdHJvbmcgYmFja2xhc2guIEZvciBpbnN0YW5jZSwgYSBOb3ZlbWJlciAyMDEwXFxuYXJ0aWNsZSBpbiBUaGUgTmV3IFlvcmsgVGltZXMsIGFwcGVhcmluZyBpbiB0aGUgd2FrZSBvZiBhIHJhc2ggb2YgcmVwb3J0ZWQgc3VpY2lkZXMgbGlua2VkIHRvXFxub3Zlci1pbmRlYnRlZG5lc3MsIHF1b3RlcyBSZWRkeSBTdWJyYWhtYW55YW0sIGFuIG9mZmljaWFsIGluIEFuZGhyYSBQcmFkZXNoICh0aGUgc2V0dGluZyBvZlxcbnRoaXMgc3R1ZHkpLCBhY2N1c2luZyBNRklzIG9mIG1ha2luZyDigJxoeXBlcnByb2ZpdHMgb2ZmIHRoZSBwb29yLuKAnSBIZSBhcmd1ZXMgdGhhdCDigJx0aGUgaW5kdXN0cnlcXG5baGFzXSBiZWNvbWUgbm8gYmV0dGVyIHRoYW4gdGhlIHdpZGVseSBkZXNwaXNlZCB2aWxsYWdlIGxvYW4gc2hhcmtzIGl0IHdhcyBpbnRlbmRlZCB0byByZXBsYWNlLi4uLlxcblRoZSBtb25leSBsZW5kZXIgbGl2ZXMgaW4gdGhlIGNvbW11bml0eS4gQXQgbGVhc3QgeW91IGNhbiBidXJuIGRvd24gaGlzIGhvdXNlLiBXaXRoIHRoZXNlXFxuY29tcGFuaWVzLCBpdCBpcyBsb290IGFuZCBzY29vdOKAnShQb2xncmVlbiBhbmQgQmFqYWogMjAxMCkuXFxuV2hhdCBpcyBzdHJpa2luZyBhYm91dCB0aGlzIGRlYmF0ZSBpcyB0aGUgcmVsYXRpdmUgcGF1Y2l0eSBvZiBldmlkZW5jZSB0byBpbmZvcm0gaXQuIEFuZWNkb3Rlc1xcbmFib3V0IGhpZ2hseSBzdWNjZXNzZnVsIGVudHJlcHJlbmV1cnMgb3IgZGVlcGx5IGluZGVidGVkIGJvcnJvd2VycyB0ZWxsIHVzIG5vdGhpbmcgYWJvdXQgdGhlXFxuZWZmZWN0IG9mIG1pY3JvZmluYW5jZSBvbiB0aGUgYXZlcmFnZSBib3Jyb3dlciwgbXVjaCBsZXNzIHRoZSBlZmZlY3Qgb2YgaGF2aW5nIGFjY2VzcyB0byBpdCBvbiB0aGVcXG5hdmVyYWdlIGhvdXNlaG9sZC4gRXZlbiByZXByZXNlbnRhdGl2ZSBkYXRhIGFib3V0IG1pY3JvZmluYW5jZSBjbGllbnRzIGFuZCBub24tY2xpZW50cyBjYW5ub3RcXG5pZGVudGlmeSB0aGUgY2F1c2FsIGVmZmVjdCBvZiBtaWNyb2ZpbmFuY2UgYWNjZXNzLCBiZWNhdXNlIGNsaWVudHMgYXJlIHNlbGYtc2VsZWN0ZWQgYW5kIHRoZXJlZm9yZVxcbm5vdCBjb21wYXJhYmxlIHRvIG5vbi1jbGllbnRzLiBNaWNyb2ZpbmFuY2Ugb3JnYW5pemF0aW9ucyBhbHNvIHB1cnBvc2VseSBjaG9vc2Ugc29tZSB2aWxsYWdlc1xcbmFuZCBub3Qgb3RoZXJzLiBUaGVzZSBpc3N1ZXMgbWFrZSB0aGUgZXZhbHVhdGlvbiBvZiBtaWNyb2NyZWRpdCBwYXJ0aWN1bGFybHkgZGlmZmljdWx0LCBhbmQgdW50aWxcXG5yZWNlbnRseSB0aGVyZSB3YXMgbGl0dGxlIHJpZ29yb3VzIGV2aWRlbmNlIHRvIGluZm9ybSBpdC5cXG5UaGlzIGhhcyBjaGFuZ2VkIGluIHRoZSBsYXN0IGZldyB5ZWFycywgYXMgc2V2ZXJhbCBzdHVkaWVzIGV2YWx1YXRpbmcgbWljcm9maW5hbmNlIGhhdmUgYmVlblxcbmNvbmR1Y3RlZCBieSBkaWZmZXJlbnQgcmVzZWFyY2ggdGVhbXMgd2l0aCBkaWZmZXJlbnQgcGFydG5lcnMgaW4gZGlmZmVyZW50IHNldHRpbmdzOiBNb3JvY2NvXFxuKENyw6lwb24gZXQgYWwuLCAyMDEzKSwgQm9zbmlhLUhlcnplZ292aW5hIChBdWdzYnVyZyBldCBhbC4sIDIwMTMpLCBNZXhpY28gKEFuZ2VsdWNjaSBldCBhbC4sXFxuMjAxMyksIE1vbmdvbGlhIChBdHRhbmFzaW8gZXQgYWwuLCAyMDEzKSBhbmQgRXRoaW9waWEgKFRhcm96emkgZXQgYWwuLCAyMDEzKS4gSW4gdGhpcyBwYXBlciB3ZVxcbnJlcG9ydCBvbiB0aGUgb2xkZXN0IG9mIHRoZXNlLCB0aGUgZmlyc3QgcmFuZG9taXplZCBldmFsdWF0aW9uIG9mIHRoZSBlZmZlY3Qgb2YgdGhlIGNhbm9uaWNhbCBncm91cGxlbmRpbmcgbWljcm9jcmVkaXQgbW9kZWwsIHdoaWNoIHRhcmdldHMgd29tZW4gd2hvIG1heSBub3QgbmVjZXNzYXJpbHkgYmUgZW50cmVwcmVuZXVycy4gVGhpc1xcbnN0dWR5IGFsc28gZm9sbG93cyB0aGUgaG91c2Vob2xkcyBvdmVyIHRoZSBsb25nZXN0IHBlcmlvZCBvZiBhbnkgZXZhbHVhdGlvbiAodGhyZWUgdG8gMy41IHllYXJzXFxuMVxcbmFmdGVyIHRoZSBpbnRyb2R1Y3Rpb24gb2YgdGhlIHByb2dyYW0gaW4gdGhlaXIgYXJlYXMpLCB3aGljaCBpcyBuZWNlc3Nhcnkgc2luY2UgbWFueSBpbXBhY3RzXFxubWF5IGJlIGV4cGVjdGVkIHRvIHN1cmZhY2Ugb25seSBvdmVyIHRoZSBtZWRpdW0gcnVuLlxcblRoZSBleHBlcmltZW50LCBhIGNvbGxhYm9yYXRpdmUgcHJvamVjdCBiZXR3ZWVuIHRoZSBDZW50ZXIgZm9yIE1pY3JvZmluYW5jZSAoQ01GKSBhdFxcbnRoZSBJbnN0aXR1dGUgZm9yIEZpbmFuY2lhbCBNYW5hZ2VtZW50IFJlc2VhcmNoIChJRk1SKSBpbiBDaGVubmFpIGFuZCBTcGFuZGFuYSwgb25lIG9mXFxuSW5kaWHigJlzIGZhc3Rlc3QgZ3Jvd2luZyBNRkkgYXQgdGhlIHRpbWUgd2FzIGNvbmR1Y3RlZCBhcyBmb2xsb3dzLiBJbiAyMDA1LCA1MiBvZiAxMDQgcG9vclxcbm5laWdoYm9yaG9vZHMgaW4gSHlkZXJhYmFkIHdlcmUgcmFuZG9tbHkgc2VsZWN0ZWQgZm9yIHRoZSBvcGVuaW5nIG9mIGEgU3BhbmRhbmEgYnJhbmNoLFxcbndoaWxlIHRoZSByZW1haW5kZXIgd2VyZSBub3QuMSBIeWRlcmFiYWQgaXMgdGhlIGZpZnRoIGxhcmdlc3QgY2l0eSBpbiBJbmRpYSwgYW5kIHRoZSBjYXBpdGFsIG9mXFxuQW5kaHJhIFByYWRlc2gsIHRoZSBJbmRpYW4gc3RhdGUgd2VyZSBtaWNyb2NyZWRpdCBoYXMgZXhwYW5kZWQgdGhlIGZhc3Rlc3QgYW5kIGhhcyByZWNlbnRseVxcbmJlZW4gbW9zdCBjb250cm92ZXJzaWFsLiBGaWZ0ZWVuIHRvIDE4IG1vbnRocyBhZnRlciB0aGUgaW50cm9kdWN0aW9uIG9mIG1pY3JvZmluYW5jZSBpbiBlYWNoXFxuYXJlYSwgYSBjb21wcmVoZW5zaXZlIGhvdXNlaG9sZCBzdXJ2ZXkgd2FzIGNvbmR1Y3RlZCBpbiBhbiBhdmVyYWdlIG9mIDY1IGhvdXNlaG9sZHMgaW4gZWFjaFxcbm5laWdoYm9yaG9vZCwgZm9yIGEgdG90YWwgb2YgYWJvdXQgNiw4NTAgaG91c2Vob2xkcy4gSW4gdGhlIG1lYW50aW1lLCBvdGhlciBNRklzIGhhZCBhbHNvXFxuc3RhcnRlZCB0aGVpciBvcGVyYXRpb25zIGluIGJvdGggdHJlYXRtZW50IGFuZCBjb21wYXJpc29uIGhvdXNlaG9sZHMsIGJ1dCB0aGUgcHJvYmFiaWxpdHkgb2ZcXG5yZWNlaXZpbmcgYW4gTUZJIGxvYW4gd2FzIHN0aWxsIDguNCBwZXJjZW50YWdlIHBvaW50cyAoNDYlKSBoaWdoZXIgaW4gdHJlYXRtZW50IGFyZWFzIHRoYW5cXG5pbiBjb21wYXJpc29uIGFyZWFzICgyNi43JSBib3Jyb3dlcnMgaW4gdHJlYXRlZCBhcmVhcyB2ZXJzdXMgMTguMyUgYm9ycm93ZXJzIGluIGNvbXBhcmlzb25cXG5hcmVhcykuIFR3byB5ZWFycyBhZnRlciB0aGlzIGZpcnN0IGVuZGxpbmUgc3VydmV5LCB0aGUgc2FtZSBob3VzZWhvbGRzIHdlcmUgc3VydmV5ZWQgb25jZSBtb3JlLlxcbkJ5IHRoYXQgdGltZSwgYm90aCBTcGFuZGFuYSBhbmQgb3RoZXIgb3JnYW5pemF0aW9ucyBoYWQgc3RhcnRlZCBsZW5kaW5nIGluIHRoZSB0cmVhdG1lbnQgYW5kXFxuY29udHJvbCBncm91cHMsIHNvIHRoZSBmcmFjdGlvbiBvZiBob3VzZWhvbGRzIGJvcnJvd2luZyBmcm9tIG1pY3JvY3JlZGl0IG9yZ2FuaXphdGlvbnMgd2FzIG5vdFxcbmRyYW1hdGljYWxseSBkaWZmZXJlbnQgKDM4LjUlIGluIHRyZWF0bWVudCBhbmQgMzMlIGluIGNvbnRyb2wpLiBCdXQgaG91c2Vob2xkcyBpbiB0cmVhdG1lbnRcXG5ncm91cHMgaGFkIGxhcmdlciBsb2FucyBhbmQgaGFkIGJlZW4gYm9ycm93aW5nIGZvciBhIGxvbmdlciB0aW1lIHBlcmlvZC4gVGhpcyBzZWNvbmQgc3VydmV5XFxudGh1cyBnaXZlcyB1cyBhbiBvcHBvcnR1bml0eSB0byBleGFtaW5lIHNvbWUgb2YgdGhlIGxvbmdlci10ZXJtIGltcGFjdHMgb2YgbWljcm9jcmVkaXQgYWNjZXNzXFxub24gaG91c2Vob2xkcyBhbmQgYnVzaW5lc3NlcywgYWx0aG91Z2ggdGhlIHNldHRpbmcgaXMgbm90IHBlcmZlY3Qgc2luY2Ugd2UgYXJlIGNvbXBhcmluZyB0aG9zZVxcbndobyBib3Jyb3cgZm9yIGxvbmdlciB2ZXJzdXMgdGhvc2Ugd2hvIGJvcnJvdyBmb3IgYSBzaG9ydGVyIHRpbWUsIHJhdGhlciB0aGFuIHRob3NlIHdobyBkb1xcbmFuZCB0aG9zZSB3aG8gZG8gbm90IGJvcnJvdyBhdCBhbGwuXFxuU2luY2UgaXQgaXMgZW50aXJlbHkgcG9zc2libGUgdGhhdCB0aGVyZSBhcmUgc3BpbGxvdmVyIG9yIGdlbmVyYWwgZXF1aWxpYnJpdW0gZWZmZWN0cyAoYXMgYW5hbHl6ZWRcXG5ieSBCdWVyYSBldCBhbC4sIDIwMTEpLCBhbmQgZWZmZWN0cyB0aGF0IG9wZXJhdGUgdGhyb3VnaCB0aGUgZXhwZWN0YXRpb24gb2YgYmVpbmcgYWJsZSB0byBib3Jyb3dcXG53aGVuIG5lZWRlZCAoc3VjaCBhcyByZWR1Y3Rpb25zIGluIHByZWNhdXRpb25hcnkgc2F2aW5ncywgYXMgZG9jdW1lbnRlZCBpbiBUaGFpbGFuZCBieSBLYTFBbiBhbHRlcm5hdGl2ZSB3YXkgdG8gbWVhc3VyZSB0aGUgaW1wYWN0IG9mIGJvcnJvd2luZyBpcyB0byByYW5kb21pemUgbWljcm9jcmVkaXQgb2ZmZXJzIGFtb25nIGFwcGxpY2FudHMuXFxuVGhpcyBhcHByb2FjaCB3YXMgcGlvbmVlcmVkIGJ5IEthcmxhbiBhbmQgWmlubWFuICgyMDEwKSwgd2hpY2ggdXNlcyBpbmRpdmlkdWFsIHJhbmRvbWl6YXRpb24gb2YgdGhlIOKAnG1hcmdpbmFs4oCdXFxuY2xpZW50cyBpbiBhIGNyZWRpdCBzY29yaW5nIG1vZGVsIHRvIGV2YWx1YXRlIHRoZSBpbXBhY3Qgb2YgY29uc3VtZXIgbGVuZGluZyBpbiBTb3V0aCBBZnJpY2EsIGFuZCBmaW5kcyB0aGF0IGFjY2Vzc1xcbnRvIG1pY3JvY3JlZGl0IGluY3JlYXNlcyB0aGUgcHJvYmFiaWxpdHkgb2YgZW1wbG95bWVudC4gVGhlIGF1dGhvcnMgdXNlIHRoZSBzYW1lIGFwcHJvYWNoIHRvIG1lYXN1cmUgaW1wYWN0XFxub2YgbWljcm9jcmVkaXQgYW1vbmcgc21hbGwgYnVzaW5lc3NlcyBpbiBNYW5pbGEgKEthcmxhbiBhbmQgWmlubWFuLCAyMDExKS4gSXQgc2hvdWxkIGJlIG5vdGVkLCBob3dldmVyLCB0aGF0XFxudGhlc2UgdHdvIHN0dWRpZXMgZXZhbHVhdGUgc2xpZ2h0bHkgZGlmZmVyZW50IHByb2dyYW1zOiBjb25zdW1lciBsZW5kaW5nIGluIHRoZSBTb3V0aCBBZnJpY2Egc3R1ZHksIGFuZCDigJxzZWNvbmRcXG5nZW5lcmF0aW9u4oCdIGluZGl2aWR1YWwtbGlhYmlsaXR5IGxvYW5zIHRvIGV4aXN0aW5nIGVudHJlcHJlbmV1cnMgaW4gTWFuaWxhLlxcbjJcXG5ib3NraSBhbmQgVG93bnNlbmQsIDIwMTEsIGFuZCBpbiBJbmRpYSBieSBGdWxmb3JkLCAyMDExLCBvciB0aHJvdWdoIGdlbmVyYWwtZXF1aWxpYnJpdW0gZWZmZWN0c1xcbm9uIHByaWNlcyBvciB3YWdlcyAoR2luw6kgYW5kIFRvd25zZW5kIDIwMDQpKSwgd2UgZm9jdXMgaGVyZSBvbiByZWR1Y2VkLWZvcm0vaW50ZW50LXRvLXRyZWF0XFxuZXN0aW1hdGVzLlxcbldlIGV4YW1pbmUgdGhlIGVmZmVjdCBvbiBib3Jyb3dpbmcgZnJvbSB2YXJpb3VzIHNvdXJjZXMsIGNvbnN1bXB0aW9uLCBuZXcgYnVzaW5lc3MgY3JlYXRpb24sIGJ1c2luZXNzIGluY29tZSwgZXRjLiwgYXMgd2VsbCBhcyBtZWFzdXJlcyBvZiBvdGhlciBodW1hbiBkZXZlbG9wbWVudCBvdXRjb21lcyBzdWNoIGFzXFxuZWR1Y2F0aW9uLCBoZWFsdGggYW5kIHdvbWVu4oCZcyBlbXBvd2VybWVudC4gQXQgdGhlIGZpcnN0IGVuZGxpbmUsIHdoaWxlIGhvdXNlaG9sZHMgZG8gYm9ycm93XFxubW9yZSBmcm9tIG1pY3JvY3JlZGl0IGluc3RpdHV0aW9ucywgdGhlIG92ZXJhbGwgdGFrZSB1cCBpcyByZWFzb25hYmx5IGxvdyAob25seSAyNi40JSBvZiB0aGVcXG5lbGlnaWJsZSBob3VzZWhvbGRzIGJvcnJvdywgbm90IHRoZSA4MCUgdGhhdCBTcGFuZGFuYSBleHBlY3RlZCksIGFuZCBzb21lIG9mIHRoZSBsb2FucyBhcmVcXG5zdWJzdGl0dXRpbmcgZm9yIGluZm9ybWFsIGxvYW5zLiBJbmZvcm1hbCBib3Jyb3dpbmcgZGVjbGluZXMsIGFuZCB3ZSBzZWUgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZVxcbmluIG92ZXJhbGwgYm9ycm93ZWQgYW1vdW50ICh0aG91Z2ggdGhlIHBvaW50IGVzdGltYXRlIGlzIHBvc2l0aXZlKS4gVGhpcyBpcyBpdHNlbGYgd2FzIGEgc3VycHJpc2luZ1xcbnJlc3VsdCBhdCB0aGUgdGltZSwgdGhvdWdoIGl0IGhhcyBiZWVuIHJlcGxpY2F0ZWQgaW4gb3RoZXIgc3R1ZGllczogdGhlIGRlbWFuZCBmb3IgbWljcm9jcmVkaXRcXG5pcyBsZXNzIGltcG9ydGFudCB0aGFuIGV4cGVjdGVkLCBhbmQgbWF5IG5vdCBjb3JyZXNwb25kIHRvIGFuIGltcG9ydGFudCBkZW1hbmQgZm9yIGV4dHJhXFxuY3JlZGl0LiBXZSBzZWUgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBtb250aGx5IHBlciBjYXBpdGEgY29uc3VtcHRpb24gYW5kIG1vbnRobHkgbm9uZHVyYWJsZSBjb25zdW1wdGlvbi4gV2UgZG8gc2VlIHNpZ25pZmljYW50IHBvc2l0aXZlIGltcGFjdHMgb24gdGhlIHB1cmNoYXNlIG9mIGR1cmFibGVzLiBUaGVyZVxcbmlzIGV2aWRlbmNlIHRoYXQgdGhpcyBpcyBmaW5hbmNlZCBwYXJ0bHkgYnkgYW4gaW5jcmVhc2UgaW4gbGFib3Igc3VwcGx5IGFuZCBwYXJ0bHkgYnkgY3V0dGluZ1xcbnVubmVjZXNzYXJ5IGNvbnN1bXB0aW9uOiBob3VzZWhvbGRzIGhhdmUgcmVkdWNlZCBleHBlbmRpdHVyZXMgb24gd2hhdCB0aGF0IHRoZXkgdGhlbXNlbHZlc1xcbmRlc2NyaWJlIGFzIOKAnHRlbXB0YXRpb24gZ29vZHMu4oCdXFxuVGh1cywgaW4gb3VyIGNvbnRleHQsIG1pY3JvZmluYW5jZSBwbGF5cyBhIHJvbGUgaW4gaGVscGluZyBzb21lIGhvdXNlaG9sZHMgbWFrZSBkaWZmZXJlbnRcXG5pbnRlcnRlbXBvcmFsIGNob2ljZXMgaW4gY29uc3VtcHRpb24uIFRoaXMgaXMgbm90IHRoZSBvbmx5IGltcGFjdCB0aGF0IGlzIHRyYWRpdGlvbmFsbHkgZXhwZWN0ZWRcXG5mcm9tIG1pY3JvZmluYW5jZSwgaG93ZXZlci4gVGhlIHByaW1hcnkgZW5naW5lIG9mIGdyb3d0aCB0aGF0IGl0IGlzIHN1cHBvc2VkIHRvIGZ1ZWwgaXMgYnVzaW5lc3NcXG5jcmVhdGlvbi4gVGhpcyBpcyB0eXBpY2FsbHkgdHJ1ZSBldmVuIGZvciBsZW5kZXJzIHRoYXQgZG8gbm90IGluc2lzdCB0aGF0IGhvdXNlaG9sZHMgaGF2ZSBhIGJ1c2luZXNzXFxudG8gdGFrZSBhIGZpcnN0IGxvYW4gKFNwYW5kYW5hIGlzIG9uZSBvZiB0aGVtKSwgYnV0IHN0aWxsIGhvcGUgYW5kIGV4cGVjdCB0aGF0IHRoZSBhYmlsaXR5IHRvXFxuYm9ycm93IHdpbGwgZXZlbnR1YWxseSBoZWxwIGhvdXNlaG9sZHMgc3RhcnQgb3IgZXhwYW5kIHNtYWxsIGJ1c2luZXNzZXMuIChUaGUgZGVzY3JpcHRpb24gb2ZcXG5TcGFuZGFuYeKAmXMgZ3JvdXAtbG9hbiBwcm9kdWN0IGlzIGNhcmVmdWwgbm90IHRvIG1lbnRpb24gYW4gYXV0b21hdGljIGxpbmsgYmV0d2VlbiBjcmVkaXQgYW5kXFxuc2VsZi1lbXBsb3ltZW50IGFjdGl2aXR5IGJ1dCBkb2VzIHN0YXRlIHRoYXQg4oCcTG9hbnMgYXJlIHVzZWQgZm9yIGNhc2ggZmxvdyBzbW9vdGhlbmluZyAoc2ljLiksXFxucHJlZG9taW5hbnRseSBmb3IgcHJvZHVjdGl2ZSBwdXJwb3Nlcy7igJ0yXFxuKSBGaWZ0ZWVuIHRvIDE4IG1vbnRocyBhZnRlciBnYWluaW5nIGFjY2VzcywgaG91c2Vob2xkc1xcbmFyZSBubyBtb3JlIGxpa2VseSB0byBiZSBlbnRyZXByZW5ldXJzICh0aGF0IGlzLCBoYXZlIGF0IGxlYXN0IG9uZSBidXNpbmVzcyksIGJ1dCB0aGV5IGludmVzdCBtb3JlXFxuaW4gdGhlIGJ1c2luZXNzZXMgdGhleSBkbyBoYXZlIChvciB0aGUgb25lcyB0aGV5IHN0YXJ0KS4gVGhlcmUgaXMgYW4gaW5jcmVhc2UgaW4gdGhlIGF2ZXJhZ2VcXG4yVG8gZ2l2ZSBhIHNlbnNlIG9mIHRoZSBwcmV2YWxlbmNlIG9mIHRoZSBwdXJwb3J0ZWQgbGluayBiZXR3ZWVuIG1pY3JvZmluYW5jZSBhbmQgYnVzaW5lc3MgY3JlYXRpb24sIG9mIHRoZVxcbnJvdWdobHkgMy4xIG1pbGxpb24gR29vZ2xlIHNlYXJjaCByZXN1bHRzIGZvciDigJxtaWNyb2ZpbmFuY2Us4oCdIDEuMzUgbWlsbGlvbiAoNDQlKSBhbHNvIGNvbnRhaW4gdGhlIHBocmFzZSDigJxidXNpbmVzc1xcbmNyZWF0aW9u4oCdIG9yIOKAnGVudHJlcHJlbmV1cnNoaXDigJ0gKHJldHJpZXZlZCBOb3ZlbWJlciAyMDEzKS5cXG4zXFxucHJvZml0cyBvZiB0aGUgYnVzaW5lc3NlcyB0aGF0IHdlcmUgYWxyZWFkeSBpbiBleGlzdGVuY2UgYmVmb3JlIG1pY3JvY3JlZGl0LCB3aGljaCBpcyBlbnRpcmVseSBkdWVcXG50byB2ZXJ5IGxhcmdlIGluY3JlYXNlcyBpbiB0aGUgdXBwZXIgdGFpbCBvZiBwcm9maXRhYmlsaXR5LiBBdCBldmVyeSBxdWFudGlsZSBiZXR3ZWVuIHRoZSA1dGggYW5kXFxudGhlIDk1dGggcGVyY2VudGlsZSwgdGhlcmUgaXMgbm8gZGlmZmVyZW5jZSBpbiB0aGUgcHJvZml0cyBvZiB0aGUgYnVzaW5lc3Nlcy4gVGhlIG1lZGlhbiBtYXJnaW5hbFxcbm5ldyBidXNpbmVzcyBpcyBib3RoIGxlc3MgcHJvZml0YWJsZSBhbmQgbGVzcyBsaWtlbHkgdG8gaGF2ZSBldmVuIG9uZSBlbXBsb3llZSBpbiB0cmVhdG1lbnQgdGhhblxcbmluIGNvbnRyb2wgYXJlYXMuXFxuQWZ0ZXIgdGhyZWUgeWVhcnMsIHdoZW4gbWljcm9jcmVkaXQgaXMgYXZhaWxhYmxlIGJvdGggaW4gdHJlYXRtZW50IGFuZCBjb250cm9sIGdyb3VwcyBidXRcXG50cmVhdG1lbnQgZ3JvdXAgaG91c2Vob2xkcyBoYXZlIGhhZCB0aGUgb3Bwb3J0dW5pdHkgdG8gYm9ycm93IGZvciBhIGxvbmdlciB0aW1lLCBidXNpbmVzc2VzXFxuaW4gdGhlIHRyZWF0bWVudCBncm91cHMgaGF2ZSBzaWduaWZpY2FudGx5IG1vcmUgYXNzZXRzLCBhbmQgYnVzaW5lc3MgcHJvZml0cyBhcmUgbm93IGxhcmdlciBmb3JcXG5idXNpbmVzc2VzIGFib3ZlIHRoZSA4NXRoIHBlcmNlbnRpbGUgb2YgcHJvZml0YWJpbGl0eS4gSG93ZXZlciwgdGhlIGF2ZXJhZ2UgYnVzaW5lc3MgaXMgc3RpbGwgc21hbGxcXG5hbmQgbm90IHZlcnkgcHJvZml0YWJsZS4gSW4gb3RoZXIgd29yZHMsIHBlcmhhcHMgY29udHJhcnkgdG8gbW9zdCBwZW9wbGXigJlzIGJlbGllZiwgdG8gdGhlIGV4dGVudFxcbm1pY3JvY3JlZGl0IGhlbHBzIGJ1c2luZXNzZXMsIGl0IG1heSBoZWxwIHRoZSBtb3N0IHByb2ZpdGFibGUgYnVzaW5lc3NlcyBtb3JlLiBUaGVyZSBpcyBzdGlsbCBub1xcbmRpZmZlcmVuY2UgaW4gYXZlcmFnZSBjb25zdW1wdGlvbi5cXG5XZSBkbyBub3QgZmluZCBhbnkgZWZmZWN0IG9uIGFueSBvZiB0aGUgd29tZW7igJlzIGVtcG93ZXJtZW50IG9yIGh1bWFuIGRldmVsb3BtZW50XFxub3V0Y29tZXMgZWl0aGVyIGFmdGVyIDE4IG9yIDM2IG1vbnRocy4gRnVydGhlcm1vcmUsIGFsbW9zdCA3MCUgb2YgZWxpZ2libGUgaG91c2Vob2xkcyBkbyBub3RcXG5oYXZlIGFuIE1GSSBsb2FuLCBwcmVmZXJyaW5nIGluc3RlYWQgdG8gYm9ycm93IGZyb20gb3RoZXIgc291cmNlcywgaWYgdGhleSBib3Jyb3cgKGFuZCBtb3N0XFxuZG8pLlxcbkEgbnVtYmVyIG9mIGNhdmVhdHMgbXVzdCBiZSBrZXB0IGluIG1pbmQgd2hlbiBpbnRlcnByZXRpbmcgYW5kIGdlbmVyYWxpemluZyB0aGVzZSByZXN1bHRzLlxcbkZpcnN0LCB0aGUgZGlmZmVyZW5jZSBpbiBtaWNyb2ZpbmFuY2UgdGFrZS11cCBiZXR3ZWVuIHRyZWF0bWVudCBhbmQgY29udHJvbCBhcmVhcyBpcyBsb3csIGV2ZW5cXG5ieSB0aGUgZmlyc3QgZW5kbGluZSwgd2hpY2ggcmFpc2VzIHR3byBpc3N1ZXM6IGl0IGxvd2VycyBwb3dlciBhbmQgcHJlY2lzaW9uICh0aG91Z2ggd2UgaGF2ZSBhXFxubnVtYmVyIG9mIHNpZ25pZmljYW50IGVmZmVjdHMpLCBhbmQgaXQgbWVhbnMgdGhhdCB0aGUgaW1wYWN0IG9mIG1pY3JvY3JlZGl0IHdlIGRldGVjdCBpcyBkcml2ZW5cXG5ieSB0aGUgbWFyZ2luYWwgYm9ycm93ZXJz4oCTdGhvc2Ugd2hvIGRvIG5vdCBib3Jyb3cgd2hlbiB0aGUgY29zdCBvZiBkb2luZyBzbyBpcyBoaWdoIChiZWNhdXNlXFxudGhleSBoYXZlIGZld2VyIE1GSXMgdG8gY2hvb3NlIGZyb20gb3IgZG8gbm90IHdhbnQgdG8gY2hhbmdlIG5laWdoYm9yaG9vZHMpLCBidXQgZG8gYm9ycm93XFxud2hlbiB0aGF0IGNvc3QgaXMgbG93ZXIuXFxuU2Vjb25kLCB0aGUgZXZhbHVhdGlvbiB3YXMgcnVuIGluIGEgY29udGV4dCBvZiB2ZXJ5IGhpZ2ggZWNvbm9taWMgZ3Jvd3RoLCB3aGljaCBjb3VsZFxcbmhhdmUgZWl0aGVyIGRlY3JlYXNlZCBvciBpbmNyZWFzZWQgdGhlIGltcGFjdCBvZiBtaWNyb2ZpbmFuY2UuIFRoaXJkLCB0aGlzIGlzIHRoZSBldmFsdWF0aW9uIG9mXFxuYSBmb3ItcHJvZml0IG1pY3JvZmluYW5jZSBtb2RlbCwgYW5kIG5vdC1mb3ItcHJvZml0IG1pY3JvZmluYW5jZSBsZW5kZXJzIG1heSBoYXZlIGxhcmdlciBwb3NpdGl2ZSBlZmZlY3RzIGlmIHRoZWlyIGludGVyZXN0IHJhdGVzIGFyZSBrZXB0IGxvdy4gRm91cnRoLCBhcyB0aGUgTUZJIHdlIHN0dWR5IGRvZXMgbm90IHByb3ZpZGVcXG5hbnkgY29tcGxlbWVudGFyeSBzZXJ2aWNlcyBzdWNoIGFzIGJ1c2luZXNzIHRyYWluaW5nIG9yIHNlbnNpdGl2aXR5IGVkdWNhdGlvbiwgd2UgYXJlIHN0dWR5aW5nXFxudGhlIHB1cmUgaW1wYWN0IG9mIHByb3ZpZGluZyBsb2FucyB0byB3b21lbiB3aG8gbWF5IG9yIG1heSBub3QgdXNlIHRoZW0gZm9yIHRoZWlyIG93blxcbmJ1c2luZXNzZXMgKHRob3VnaCBTcGFuZGFuYSBkb2VzIGJlbGlldmUgdGhhdCB0aGlzIGlzIHdoYXQgdGhlIG1vbmV5IHdpbGwgYmUgdXNlZCBmb3IgZXZlbnR1NFxcbmFsbHkpLCBhbmQgd2UgZG8gZmluZCBhbiBleHBhbnNpb24gaW4gd29tZW4tb3duZWQgYnVzaW5lc3NlcykuIEZpZnRoLCB0aGUgc3R1ZHkgdG9vayBwbGFjZSBpblxcbuKAnG1hcmdpbmFs4oCdIG5laWdoYm9yaG9vZHPigJN0aG9zZSBTcGFuZGFuYSB3YXMgaW5kaWZmZXJlbnQgYWJvdXQgd29ya2luZyB3aXRoIGF0IHRoZSBvdXRzZXTigJNcXG5hbmQgdGhlIGltcGFjdHMgbWF5IGhhdmUgYmVlbiBkaWZmZXJlbnQgaW4gdGhlIG5laWdoYm9yaG9vZHMgdGhleSBjaG9zZSB0byBleGNsdWRlIGZyb20gdGhlXFxucmFuZG9taXphdGlvbiAoSGVja21hbiwgMTk5MikuXFxuVGh1cywgaXQgaXMgYW4gaW1wb3J0YW50IHJlYXNzdXJhbmNlIHRoYXQgb3VyIHJlc3VsdHMgZmluZCBhIHN0cm9uZyBlY2hvIGluIHRoZSBmb3VyIG90aGVyXFxuc3R1ZGllcyB0aGF0IGxvb2sgYXQgc2ltaWxhciBwcm9ncmFtcyBpbiBkaWZmZXJlbnQgY29udGV4dHMuIFRoaXMgZ2l2ZXMgdXMgY29uZmlkZW5jZSBpbiB0aGVcXG5yb2J1c3RuZXNzIGFuZCBleHRlcm5hbCB2YWxpZGl0eSBvZiBvdXIgZmluZGluZ3MuIEluIHNob3J0LCBtaWNyb2NyZWRpdCBpcyBub3QgZm9yIGV2ZXJ5IGhvdXNlaG9sZCxcXG5vciBldmVuIG1vc3QgaG91c2Vob2xkcywgYW5kIGl0IGRvZXMgbm90IGxlYWQgdG8gdGhlIG1pcmFjdWxvdXMgc29jaWFsIHRyYW5zZm9ybWF0aW9uIHNvbWVcXG5wcm9wb25lbnRzIGhhdmUgY2xhaW1lZC4gSXRzIHByaW5jaXBhbCBpbXBhY3Qgc2VlbXMgdG8gYmUsIHBlcmhhcHMgdW5zdXJwcmlzaW5nbHksIHRoYXQgaXRcXG5hbGxvd3Mgc29tZSBob3VzZWhvbGRzIHRvIHNhY3JpZmljZSBzb21lIGluc3RhbnRhbmVvdXMgdXRpbGl0eSAodGVtcHRhdGlvbiBnb29kcyBvciBsZWlzdXJlKVxcbmluIG9yZGVyIHRvIGZpbmFuY2UgbHVtcHkgcHVyY2hhc2VzLCBlaXRoZXIgZm9yIHRoZWlyIGhvbWUgb3IgaW4gb3JkZXIgdG8gZXN0YWJsaXNoIG9yIGV4cGFuZFxcbmEgYnVzaW5lc3MuIFByaW1hIGZhY2llLCB0aGVzZSBtYXJnaW5hbCBidXNpbmVzc2VzIGRvIG5vdCBhcHBlYXIgdG8gYmUgaGlnaGx5IHByb2R1Y3RpdmUgb3JcXG5wcm9maXRhYmxlLCBidXQgbW9yZSBkYXRhIGFuZCBtb3JlIHRpbWUgbWF5IGJlIG5lZWRlZCB0byBmdWxseSBlc3RhYmxpc2ggdGhlaXIgaW1wYWN0cyBvblxcbmluZGl2aWR1YWxzLCBtYXJrZXRzIGFuZCBjb21tdW5pdGllcy5cXG4yIFRoZSBTcGFuZGFuYSBNaWNyb2NyZWRpdCBwcm9kdWN0LCBhbmQgdGhlIGNvbnRleHRcXG4yLjEgU3BhbmRhbmEgYW5kIGl0cyBtaWNyb2NyZWRpdCBwcm9kdWN0XFxuVW50aWwgdGhlIG1ham9yIGNyaXNpcyBpbiBJbmRpYW4gbWljcm9maW5hbmNlIGluIDIwMTAsIFNwYW5kYW5hIHdhcyBvbmUgb2YgdGhlIGxhcmdlc3QgYW5kXFxuZmFzdGVzdC1ncm93aW5nIG1pY3JvZmluYW5jZSBvcmdhbml6YXRpb25zIGluIEluZGlhLCB3aXRoIDEuMiBtaWxsaW9uIGFjdGl2ZSBib3Jyb3dlcnMgaW4gTWFyY2hcXG4yMDA4LCB1cCBmcm9tIDUyMCBib3Jyb3dlcnMgaW4gMTk5OC05LCBpdHMgZmlyc3QgeWVhciBvZiBvcGVyYXRpb24gKE1JWCBNYXJrZXQsIDIwMDkpLiBJdCBoYWRcXG5leHBhbmRlZCBmcm9tIGl0cyBiaXJ0aHBsYWNlIGluIEd1bnR1ciwgYSBkeW5hbWljIGNpdHkgaW4gQW5kaHJhIFByYWRlc2gsIGFjcm9zcyB0aGUgc3RhdGVcXG5hbmQgaW50byBzZXZlcmFsIG90aGVycy5cXG5UaGUgYmFzaWMgU3BhbmRhbmEgcHJvZHVjdCB3YXMgdGhlIGNhbm9uaWNhbCBncm91cC1sb2FuIHByb2R1Y3QsIGZpcnN0IGludHJvZHVjZWQgYnkgdGhlXFxuR3JhbWVlbiBCYW5rLiBBIGdyb3VwIGlzIGNvbXByaXNlZCBvZiBzaXggdG8gdGVuIHdvbWVuLCBhbmQgMjUtNDUgZ3JvdXBzIGZvcm0gYSDigJxjZW50ZXIu4oCdXFxuV29tZW4gYXJlIGpvaW50bHkgcmVzcG9uc2libGUgZm9yIHRoZSBsb2FucyBvZiB0aGVpciBncm91cC4gVGhlIGZpcnN0IGxvYW4gaXMgUnMuIDEwLDAwMCwgYWJvdXRcXG4kMjAwIGF0IG1hcmtldCBleGNoYW5nZSByYXRlcywgb3IgJDEsMDAwIGF0IDIwMDcgcHVyY2hhc2luZyBwb3dlciBwYXJpdHkgKFBQUCktYWRqdXN0ZWRcXG5leGNoYW5nZSByYXRlcyAoV29ybGQgQmFuaywgMjAwNykuM1xcbkl0IHRha2VzIDUwIHdlZWtzIHRvIHJlaW1idXJzZSBwcmluY2lwYWwgYW5kIGludGVyZXN0OyB0aGVcXG4zXFxuSW4gMjAwNyB0aGUgUFBQIGV4Y2hhbmdlIHJhdGUgd2FzICQxPVJzLiA5LjIsIHdoaWxlIHRoZSBtYXJrZXQgZXhjaGFuZ2UgcmF0ZSB3YXMgJDEmIzM5O1JzLiA1MC4gQWxsIGZvbGxvd2luZ1xcbnJlZmVyZW5jZXMgdG8gZG9sbGFyIGFtb3VudHMgYXJlIGluIFBQUCB0ZXJtcyB1bmxlc3Mgbm90ZWQgb3RoZXJ3aXNlLlxcbjVcXG5pbnRlcmVzdCByYXRlIGlzIDEyJSAobm9uLWRlY2xpbmluZyBiYWxhbmNlOyBlcXVpdmFsZW50IHRvIGEgMjQlIEFQUikuIElmIGFsbCBtZW1iZXJzIG9mIGEgZ3JvdXBcXG5yZXBheSB0aGVpciBsb2FucywgdGhleSBhcmUgZWxpZ2libGUgZm9yIHNlY29uZCBsb2FucyBvZiBScy4gMTAsMDAwLTEyLDAwMC4gTG9hbiBhbW91bnRzIGluY3JlYXNlXFxudXAgdG8gUnMuIDIwLDAwMC4gRHVyaW5nIHRoZSBjb3Vyc2Ugb2YgdGhlIHN0dWR5LCBTcGFuZGFuYSBhbHNvIGludHJvZHVjZWQgYW4gaW5kaXZpZHVhbFxcbnByb2R1Y3QsIGZvciBjbGllbnRzIHdobyBoYWQgYmVlbiBzdWNjZXNzZnVsIHdpdGggb25lIG9yIHR3byBncm91cC1sb2FuIGN5Y2xlcy4gVGhlIGluZGl2aWR1YWxcXG5wcm9kdWN0IHdhcyBhdmFpbGFibGUgaW4gdGhlIHRyZWF0bWVudCBhcmVhcy4gVmVyeSBmZXcgcGVvcGxlIGluIG91ciBzYW1wbGUgZW5kZWQgdXAgdGFraW5nXFxudGhpcyBsb2FuLCBob3dldmVyLCBzbyB0aGUgc3R1ZHkgaXMgbWFpbmx5IGFuIGV2YWx1YXRpb24gb2YgYSBncm91cC1sZW5kaW5nIHByb2R1Y3QuXFxuRWxpZ2liaWxpdHkgaXMgZGV0ZXJtaW5lZCB1c2luZyB0aGUgZm9sbG93aW5nIGNyaXRlcmlhOiBjbGllbnRzIG11c3QgKGEpIGJlIGZlbWFsZSAoYikgYmUgYWdlZFxcbjE4IHRvIDU5LCAoYykgaGF2ZSByZXNpZGVkIGluIHRoZSBzYW1lIGFyZWEgZm9yIGF0IGxlYXN0IG9uZSB5ZWFyLCAoZCkgaGF2ZSB2YWxpZCBpZGVudGlmaWNhdGlvblxcbmFuZCByZXNpZGVudGlhbCBwcm9vZiAocmF0aW9uIGNhcmQsIHZvdGVyIGNhcmQsIG9yIGVsZWN0cmljaXR5IGJpbGwpLCBhbmQgKGUpIGF0IGxlYXN0IDgwJSBvZiB3b21lblxcbmluIGEgZ3JvdXAgbXVzdCBvd24gdGhlaXIgaG9tZS40IEdyb3VwcyBhcmUgZm9ybWVkIGJ5IHdvbWVuIHRoZW1zZWx2ZXMsIG5vdCBieSBTcGFuZGFuYS5cXG5Vbmxpa2Ugc29tZSBvdGhlciBtaWNyb2ZpbmFuY2Ugb3JnYW5pemF0aW9ucywgU3BhbmRhbmEgZG9lcyBub3QgcmVxdWlyZSBpdHMgY2xpZW50cyB0byBzdGFydCBhXFxuYnVzaW5lc3MgKG9yIHByZXRlbmQgdG8pIGluIG9yZGVyIHRvIGJvcnJvdzogdGhlIG9yZ2FuaXphdGlvbiByZWNvZ25pemVzIHRoYXQgbW9uZXkgaXMgZnVuZ2libGUsXFxuYW5kIGNsaWVudHMgYXJlIGxlZnQgZW50aXJlbHkgZnJlZSB0byBjaG9vc2UgdGhlIGJlc3QgdXNlIG9mIHRoZSBtb25leSwgYXMgbG9uZyBhcyB0aGV5IHJlcGF5XFxudGhlaXIgbG9hbi4gU3BhbmRhbmEgZG9lcyBub3QgZGV0ZXJtaW5lIGxvYW4gZWxpZ2liaWxpdHkgYnkgdGhlIGV4cGVjdGVkIHByb2R1Y3Rpdml0eSBvZiB0aGVcXG5pbnZlc3RtZW50LCBhbHRob3VnaCBzZWxlY3Rpb24gaW50byBncm91cHMgbWF5IHNjcmVlbiBvdXQgd29tZW4gd2hvIGNhbm5vdCBjb252aW5jZSBmZWxsb3dcXG5ncm91cC1tZW1iZXJzIHRoYXQgdGhleSBhcmUgbGlrZWx5IHRvIHJlcGF5LiBBbHNvIHVubGlrZSBvdGhlciBtaWNyb2xlbmRlcnMsIG1vc3Qgbm90YWJseVxcbkdyYW1lZW4sIFNwYW5kYW5hIGRvZXMgbm90IGV4cGxpY2l0bHkgaW5zaXN0IG9uIOKAnHRyYW5zZm9ybWF0aW9u4oCdIGluIHRoZSBob3VzZWhvbGQuIFRoZXJlIGlzIG5vXFxuY2hhbnRpbmcgb2YgcmVzb2x1dGlvbnMgYXQgZ3JvdXAgbWVldGluZ3MsIHdoaWNoIGFyZSB2ZXJ5IHNob3J0IGFuZCBmb2N1c2VkIG9uIHRoZSByZXBheW1lbnRcXG50cmFuc2FjdGlvbi4gU3BhbmRhbmEgaXMgcHJpbWFyaWx5IGEgbGVuZGluZyBvcmdhbml6YXRpb24sIG5vdCBkaXJlY3RseSBpbnZvbHZlZCBpbiBidXNpbmVzc1xcbnRyYWluaW5nLCBmaW5hbmNpYWwgbGl0ZXJhY3kgcHJvbW90aW9uLCBldGMuIEl0IGlzIGhvd2V2ZXIgdGhlIGJlbGllZiBvZiB0aGUgbWFuYWdlbWVudCB0aGF0IHRoZVxcbnZlcnkgZmFjdCBvZiBib3Jyb3dpbmcgd2lsbCBsZWFkIHRvIHN1Y2ggdHJhbnNmb3JtYXRpb24sIGFuZCB0byBidXNpbmVzcyBjcmVhdGlvbi4gU3BhbmRhbmEgd2FzXFxuYWxzbyBhIGZvci1wcm9maXQgb3BlcmF0b3IsIGNoYXJnaW5nIGludGVyZXN0IHJhdGVzIHN1ZmZpY2llbnQgdG8gbWFrZSBwcm9maXRzLCB0aG91Z2ggYWxsIHRoZSBwcm9maXRzXFxud2VyZSByZS1pbnZlc3RlZCBpbiB0aGUgb3JnYW5pemF0aW9uIGluIHRoZSBwZXJpb2Qgd2Ugc3R1ZHkuIFRoZSBvcmdhbml6YXRpb24gb2J0YWluZWQgcHJpdmF0ZVxcbmNhcGl0YWwgYW5kIHdvdWxkIHByb2JhYmx5IGhhdmUgbGF1bmNoZWQgYW4gSVBPIGlmIGl0IGhhZCBub3QgYmVlbiBjYXVnaHQgaW4gdGhlIG1pZGRsZSBvZlxcbnRoZSBBbmRocmEgUHJhZGVzaCBjcmlzaXMuIFRoaXMgbWFrZXMgaXQgZGlmZmVyZW50IGZyb20gR3JhbWVlbiBCYW5rIChNb2hhbW1lZCBZdW51c1xcbmhhcyBleHBsaWNpdGx5IGFuZCB2aWdvcm91c2x5IGNyaXRpY2l6ZWQgZm9yLXByb2ZpdCBNRklzIGFmdGVyIHRoZSBJUE8gb2YgQ29tcGFydGFtb3MsIGEgbGFyZ2VcXG5NZXhpY2FuIE1GSSkuIEFsbCB0aGVzZSBmZWF0dXJlcyBhcmUgaW1wb3J0YW50IHRvIGtlZXAgaW4gbWluZCB3aGVuIGludGVycHJldGluZyB0aGUgcmVzdWx0cyBvZlxcbnRoaXMgc3R1ZHk6IGl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlIEdyYW1lZW4gcHJvZHVjdCB3b3VsZCBoYXZlIGRpZmZlcmVudCBpbXBhY3RzLiBIb3dldmVyLCBmcm9tXFxuNFRoZSBob21lIG93bmVyc2hpcCByZXF1aXJlbWVudCBpcyBub3QgYmVjYXVzZSB0aGUgaG91c2UgaXMgdXNlZCBhcyBjb2xsYXRlcmFsLCBidXQgYmVjYXVzZSBob21lIG93bmVycyBhcmVcXG5tb3JlIHN0YWJsZSBhbmQgbGVzcyBsaWtlbHkgdG8gbWlncmF0ZS4gU3BhbmRhbmEgZG9lcyBub3QgcmVxdWlyZSBhIGZvcm1hbCBwcm9wZXJ0eSB0aXRsZSwganVzdCBhIGdlbmVyYWwgYWdyZWVtZW50XFxudGhhdCB0aGlzIGhvdXNlIGJlbG9uZ3MgdG8gdGhpcyBob3VzZWhvbGQgKHNvbWV0aGluZyB0aGF0IHRlbmRzIHRvIGJlIGNsZWFyIGV2ZW4gaW4gaW5mb3JtYWwgc2V0dGxlbWVudClcXG42XFxuYW4gZXZhbHVhdGlvbiBwb2ludCBvZiB2aWV3LCB0aGVyZSBhcmUgY2xlYXIgYWR2YW50YWdlcyB0byB0aGlzIHByb2R1Y3Q6IGluIHBhcnRpY3VsYXIsIGFueSBpbXBhY3RcXG5vbiBidXNpbmVzcyBleHBhbnNpb24gY2FuIGJlIGF0dHJpYnV0ZWQgdG8gY3JlZGl0IGFsb25lLCByYXRoZXIgdGhhbiB0byBvdGhlciBzZXJ2aWNlcy4gTW9yZW92ZXIsXFxudG8gdGhlIGV4dGVudCB3ZSBmaW5kIOKAnHBvc2l0aXZl4oCdIHJlc3VsdHMgaW4gdGhlIHN0dWR5LCB0aGV5IGFyZSB1bmxpa2VseSB0byBiZSBhdHRyaWJ1dGFibGUgdG8gc29jaWFsXFxuZGVzaXJhYmlsaXR5IGJpYXMuIEl0IGlzIGFsc28gd29ydGggbm90aW5nIHRoYXQsIGluIHRoZSBwZXJpb2Qgd2Ugc3R1ZHksIHRoZSBpbnRlcmVzdCByYXRlcyBjaGFyZ2VkXFxuYnkgU3BhbmRhbmEgd2VyZSBsb3cgYnkgc3RhbmRhcmQgbWljcm9maW5hbmNlIHN0YW5kYXJkcywgZXZlbiBHcmFtZWVuLlxcbjIuMiBUaGUgY29udGV4dFxcblRhYmxlIDFBIHVzZXMgdGhlIGJhc2VsaW5lIGRhdGEgdG8gc2hvdyBhIHNuYXBzaG90IG9mIGhvdXNlaG9sZHMgZnJvbSB0aGUgc3R1ZHkgYXJlYSBpblxcbjIwMDUsIGJlZm9yZSB0aGUgU3BhbmRhbmEgcHJvZHVjdCB3YXMgbGF1bmNoZWQuIEFzIHdlIGRlc2NyaWJlIGJlbG93LCB0aGVzZSBudW1iZXJzIG5lZWRcXG50byBiZSB2aWV3ZWQgd2l0aCBzb21lIGNhdXRpb24sIGFzIHRoZSBob3VzZWhvbGRzIHNhbXBsZWQgYXQgYmFzZWxpbmUgd2VyZSBub3QgbmVjZXNzYXJpbHlcXG5yZXByZXNlbnRhdGl2ZSBvZiB0aGUgYXJlYSBhcyBhIHdob2xlLCBhbmQgd2VyZSBub3QgcHVycG9zZWx5IHJlc3VydmV5ZWQgYXQgZW5kbGluZS4gQXQgYmFzZWxpbmUsXFxudGhlIGF2ZXJhZ2UgaG91c2Vob2xkIHdhcyBhIGZhbWlseSBvZiBmaXZlLCB3aXRoIG1vbnRobHkgZXhwZW5kaXR1cmUgb2YganVzdCB1bmRlciBScy4gNSwwMDAsIG9yXFxuJDU0MCBhdCBQUFAtYWRqdXN0ZWQgZXhjaGFuZ2UgcmF0ZXMgKCQxMDggcGVyIGNhcGl0YSkgKFdvcmxkIEJhbmssIDIwMDUpLjUgVGhlcmUgd2FzIGFsbW9zdFxcbm5vIE1GSSBib3Jyb3dpbmcgaW4gdGhlIHNhbXBsZSBhcmVhcyBhdCBiYXNlbGluZS4gSG93ZXZlciwgNjglIG9mIHRoZSBob3VzZWhvbGRzIGhhZCBhdCBsZWFzdFxcbm9uZSBvdXRzdGFuZGluZyBsb2FuLiBUaGUgYXZlcmFnZSBhbW91bnQgb3V0c3RhbmRpbmcgd2FzIFJzLiAzOCwwMDAuIFNpeHR5LXRocmVlIHBlcmNlbnRcXG5vZiBob3VzZWhvbGRzIGhhZCBhIGxvYW4gZnJvbSBhbiBpbmZvcm1hbCBzb3VyY2UgKG1vbmV5bGVuZGVycywgZnJpZW5kcyBvciBuZWlnaGJvcnMsIGZhbWlseVxcbm1lbWJlcnMgb3Igc2hvcGtlZXBlcnMpLiBDb21tZXJjaWFsIGJhbmsgbG9hbnMgd2VyZSB2ZXJ5IHJhcmUgKDMuNiUpLlxcbkFsdGhvdWdoIGJ1c2luZXNzIGludmVzdG1lbnQgd2FzIG5vdCBjb21tb25seSBuYW1lZCBhcyBhIG1vdGl2ZSBmb3IgYm9ycm93aW5nLCBidXNpbmVzc2VzIHdlcmUgY29tbW9uLCB3aXRoIDMyIGJ1c2luZXNzZXMgcGVyIDEwMCBob3VzZWhvbGRzLCBjb21wYXJlZCB0byBhbiBPRUNELWNvdW50cnlcXG5hdmVyYWdlIG9mIDEyJSB3aG8gc2F5IHRoYXQgdGhleSBhcmUgc2VsZi1lbXBsb3llZC4gTGVzcyB0aGFuIGhhbGYgb2YgYWxsIGJ1c2luZXNzZXMgd2VyZSBvcGVyYXRlZCBieSB3b21lbiAoMTQuNSB3b21hbi1ydW4gYnVzaW5lc3NlcyBwZXIgMTAwIGhvdXNlaG9sZHMuKSBCdXNpbmVzcyBvd25lcnMgYW5kIHRoZWlyXFxuZmFtaWxpZXMgc3BlbnQgb24gYXZlcmFnZSA1OCBob3VycyBwZXIgd2VlayB3b3JraW5nIGluIHRoZSBidXNpbmVzcy5cXG5Hcm93dGggYmV0d2VlbiAyMDA1IGFuZCAyMDEwXFxuVGFibGUgMUIgc2hvd3Mgc29tZSBvZiB0aGUgc2FtZSBrZXkgc3RhdGlzdGljcyBmb3IgdGhlIGVuZGxpbmUgMSBhbmQgZW5kbGluZSAyIChFTDEgYW5kIEVMMilcXG5zYW1wbGVzIGluIHRoZSBjb250cm9sIGdyb3VwLlxcbkNvbXBhcmluZyB0aGUgY29udHJvbCBiYXNlbGluZSBzYW1wbGUgKDIwMDUpIHdpdGggdGhlIGNvbnRyb2wgaG91c2Vob2xkcyBpbiB0aGUgRUwxICgyMDA4KVxcbmFuZCBFTDIgKDIwMTApIHNhbXBsZXMgcmV2ZWFsIHZlcnkgcmFwaWQgc2VjdWxhciBncm93dGggaW4gSHlkZXJhYmFkIG92ZXIgMjAwNS0yMDEwLjYgQXZlcmFnZVxcbjVDb2x1bW4gMiByZXBvcnRzIHRoZSBjb250cm9sIG1lYW4sIGFuZCBjb2x1bW4gNCByZXBvcnRzIHRoZSB0cmVhdG1lbnQtY29udHJvbCBkaWZmZXJlbmNlLiBOb25lIG9mIHRoZXNlXFxuZGlmZmVyZW5jZXMgYXJlIHNpZ25pZmljYW50IChjb2x1bW4gNSkuXFxuNldoaWxlIHRoZSBjb21wYXJpc29uIG1heSBub3QgYmUgcGVyZmVjdCBzaW5jZSB0aGUgYmFzZWxpbmUgc3VydmV5IHdhcyBub3QgY29uZHVjdGVkIG9uIHRoZSBzYW1lIHNhbXBsZSBhc1xcbjdcXG5ob3VzZWhvbGQgY29uc3VtcHRpb24gcm9zZSBmcm9tIFJzLiA0LDg4OCAoMjAwNSkgdG8gUnMuIDcsNjYyIGluIDIwMDcgYW5kIFJzLiAxMSw0OTcgaW4gMjAxMFxcbihhbGwgZXhwcmVzc2VkIGluIDIwMDcgcnVwZWVzKS4gVGhlIGZyYWN0aW9uIG9mIGhvdXNlaG9sZHMgd2l0aCBhdCBsZWFzdCBvbmUgb3V0c3RhbmRpbmcgbG9hblxcbnJvc2UgZnJvbSA2OCUgYXQgYmFzZWxpbmUgdG8gODklIGluIEVMMSBhbmQgOTAlIGluIEVMMi5cXG5UaGUgcHJldmFsZW5jZSBvZiBidXNpbmVzc2VzIGluY3JlYXNlZCBmcm9tIDMyIHBlciBodW5kcmVkIGhvdXNlaG9sZHMgYXQgYmFzZWxpbmUgdG8gNDQgYXRcXG5FTDEgYW5kIDU2IGF0IEVMMi4gSW4gZW5kbGluZSAxIDM3LjglIGFuZCBpbiBlbmRsaW5lIDIgNDAuMyUgb2YgdGhlIGJ1c2luZXNzIHdlcmUgb3BlcmF0ZWQgYnlcXG53b21lbi4gSG93ZXZlciwgdGhlIGJ1c2luZXNzZXMgcmVtYWluZWQgdmVyeSBzbWFsbCwgd2l0aCBvbiBhdmVyYWdlIC4zOCBlbXBsb3llZXMgaW4gRUwxIGFuZFxcbi4xOCBpbiBFTDIuNyBBcyB3ZWxsIGFzIHJlbWFpbmluZyB2ZXJ5IHNtYWxsIGluIHRlcm1zIG9mIGVtcGxveW1lbnQsIGF2ZXJhZ2Ugc2FsZXMgcmVtYWluZWRcXG5mYWlybHkgc3RlYWR5OiBScy4gMTQsODAwIGF0IEVMMSBhbmQgMTQsMTAwIGF0IEVMMi4gSG93ZXZlciwgbG9va2luZyBhY3Jvc3MgYWxsIGhvdXNlaG9sZHMgKG5vdFxcbmp1c3QgdGhvc2Ugd2l0aCBidXNpbmVzc2VzKSwgYnVzaW5lc3MgcmV2ZW51ZXMgaW5jcmVhc2VkIGZyb20gYXJvdW5kIFJzLiA0LDgwMCB0byBScy4gNSw4MDAgKGluXFxuY29uc3RhbnQgMjAwNyBydXBlZXMpLiBBdCBFTDIsIGJ1c2luZXNzIG93bmVycyByZXBvcnRlZCBidXNpbmVzcyBleHBlbnNlcyAod29ya2luZyBjYXBpdGFsKVxcbnBsdXMgaW52ZXN0bWVudCBpbiBhc3NldHMgb2YgYWxtb3N0IFJzLiAxNSwwMDAsIHVwIGZyb20gYWJvdXQgUnMuIDEzLDAwMCBhdCBFTDEuIChUaGVzZVxcbmV4cGVuc2UgZXN0aW1hdGVzIGRvIG5vdCBhY2NvdW50IGZvciB0aGUgY29zdCBvZiB0aGUgcHJvcHJpZXRvcnPigJkgdGltZS4pXFxuVGhpcyBjb250ZXh0IG9mIHJhcGlkIGdyb3d0aCBpbiB1cmJhbiBBbmRocmEgUHJhZGVzaCBpcyBhbm90aGVyIGltcG9ydGFudCBmZWF0dXJlIHRvXFxua2VlcCBpbiBtaW5kLCBhbmQgbWF5IGNvbG9yIHRoZSByZXN1bHRzIG9mIHRoaXMgc3R1ZHkgKG9mIGFsbCB0aGUgcmFuZG9taXplZCBldmFsdWF0aW9ucyBvblxcbm1pY3JvZmluYW5jZSwgdGhpcyBpcyBwcm9iYWJseSB0aGUgbW9zdCBkeW5hbWljIGNvbnRleHQpLiBJdCBpcyBjbGVhcmx5IGFuIGltcG9ydGFudCBleGFtcGxlLFxcbmFzIG1pY3JvZmluYW5jZSBjbGllbnRzIGluIEluZGlhIHJlcHJlc2VudHMgcm91Z2hseSAzMCUgb2YgYWxsIG1pY3JvZmluYW5jZSBjbGllbnRzIHdvcmxkd2lkZSw4XFxuYW5kIG1pY3JvZmluYW5jZSBoYXMgZGV2ZWxvcGVkIGluIG1hbnkgb3RoZXIgcmFwaWRseSBncm93aW5nIGVudmlyb25tZW50cyAoQmFuZ2xhZGVzaCBiZWluZ1xcbnByb2JhYmx5IHRoZSBwcmltZSBleGFtcGxlKS4gQnV0IHRoZSByZXN1bHRzIG1heSBiZSBkaWZmZXJlbnQgaW4gY29udGV4dHMgd2l0aCBtdWNoIHNsb3dlclxcbmdyb3d0aCwgb3IgaW4gcmVjZXNzaW9ucy4gRm9ydHVuYXRlbHksIHRoZSBvdGhlciBSQ1Qgc3R1ZGllcyBjb3ZlciBhIHdpZGUgdmFyaWV0eSBvZiBjb250ZXh0cyxcXG53aGljaCB3aWxsIGhlbHAgdG8gdW5kZXJzdGFuZCB0aGUgZXh0ZW50IHRvIHdoaWNoIHJlc3VsdHMgZGVwZW5kIG9uIGNvbnRleHQuXFxuMyBFeHBlcmltZW50YWwgZGVzaWduXFxuMy4xIEV4cGVyaW1lbnRhbCBEZXNpZ25cXG5BdCB0aGUgdGltZSB0aGlzIHN0dWR5IHdhcyBzdGFydGVkLCBtaWNyb2ZpbmFuY2UgaGFkIGFscmVhZHkgdGFrZW4gaG9sZCBpbiBzZXZlcmFsIGRpc3RyaWN0c1xcbmluIEFuZGhyYSBQcmFkZXNoLCBidXQgbW9zdCBtaWNyb2ZpbmFuY2Ugb3JnYW5pemF0aW9ucyBoYWQgbm90IHlldCBzdGFydGVkIHdvcmtpbmcgaW4gdGhlXFxudGhlIGVuZGxpbmUsIHRoZSBncm93dGggYmV0d2VlbiBFTDEgYW5kIEVMMiBpcyBmb3IgdGhlIHNhbWUgc2V0IG9mIGhvdXNlaG9sZHMsIHVzaW5nIHRoZSBzYW1lIHN1cnZleSBpbnN0cnVtZW50cyxcXG5hbmQgdGh1cyBnaXZlcyB1cyBhIGdvb2Qgc2Vuc2Ugb2YgdGhlIGR5bmFtaXNtIG9mIHRoaXMgZWNvbm9teS5cXG43VGhlIGZhbGwgaW4gYXZlcmFnZSBlbXBsb3ltZW50IGJldHdlZW4gRUwxIGFuZCBFTDIgbWF5IHJlZmxlY3QgYSBjb21wb3NpdGlvbmFsIGVmZmVjdCwgd2l0aCB0aGUgbWFyZ2luYWxcXG5idXNpbmVzc2VzIGJlaW5nIHNtYWxsZXIuXFxuOE1JWCBNYXJrZXQgcmVwb3J0ZWQgOTQgbWlsbGlvbiBib3Jyb3dlcnMgd29ybGR3aWRlIGluIDIwMTEsIG9mIHdob20gMjggbWlsbGlvbiBhcmUgbG9jYXRlZCBpbiBJbmRpYVxcbihodHRwOi8vd3d3Lm1peG1hcmtldC5vcmcvbWZpL2NvdW50cnkvSW5kaWEpLlxcbjhcXG5jYXBpdGFsLCBIeWRlcmFiYWQuIFNwYW5kYW5hIGluaXRpYWxseSBzZWxlY3RlZCAxMjAgYXJlYXMgKGlkZW50aWZpYWJsZSBuZWlnaGJvcmhvb2RzLCBvciBiYXN0aXMpXFxuaW4gSHlkZXJhYmFkIGFzIHBsYWNlcyBpbiB3aGljaCB0aGV5IHdlcmUgaW50ZXJlc3RlZCBpbiBvcGVuaW5nIGJyYW5jaGVzIGJ1dCBhbHNvIHdpbGxpbmcgbm90XFxudG8uIFRoZXNlIGFyZWFzIHdlcmUgc2VsZWN0ZWQgYmFzZWQgb24gaGF2aW5nIG5vIHByZWV4aXN0aW5nIG1pY3JvZmluYW5jZSBwcmVzZW5jZSwgYW5kIGhhdmluZ1xcbnJlc2lkZW50cyB3aG8gd2VyZSBkZXNpcmFibGUgcG90ZW50aWFsIGJvcnJvd2VyczogcG9vciwgYnV0IG5vdCDigJx0aGUgcG9vcmVzdCBvZiB0aGUgcG9vci7igJ0gQXJlYXNcXG53aXRoIGhpZ2ggY29uY2VudHJhdGlvbnMgb2YgY29uc3RydWN0aW9uIHdvcmtlcnMgd2VyZSBhdm9pZGVkIGJlY2F1c2UgdGhleSBtb3ZlIGZyZXF1ZW50bHksXFxud2hpY2ggbWFrZXMgdGhlbSB1bmRlc2lyYWJsZSBhcyBtaWNyb2ZpbmFuY2UgY2xpZW50cy4gV2hpbGUgdGhlIHNlbGVjdGVkIGFyZWFzIGFyZSBjb21tb25seVxcbnJlZmVycmVkIHRvIGFzIOKAnHNsdW1zLOKAnSB0aGVzZSBhcmUgcGVybWFuZW50IHNldHRsZW1lbnRzIHdpdGggY29uY3JldGUgaG91c2VzIGFuZCBzb21lIHB1YmxpY1xcbmFtZW5pdGllcyAoZWxlY3RyaWNpdHksIHdhdGVyLCBldGMuKS4gQ29udmVyc2VseSwgdGhlIGxhcmdlc3Qgb25lcyB3ZXJlIG5vdCBzZWxlY3RlZCBmb3IgdGhlIHN0dWR5LFxcbnNpbmNlIFNwYW5kYW5hIHdhcyBrZWVuIHRvIHN0YXJ0IG9wZXJhdGlvbnMgdGhlcmU6IHRoZSBsYXJnZSBwb3B1bGF0aW9uIGluIHRoZXNlIHNsdW1zIGFsbG93ZWRcXG50aGVtIHRvIGJlbmVmaXQgZnJvbSBlY29ub21pZXMgb2Ygc2NhbGUgYW5kIHJlYWNoIHF1aWNrbHkgYSBudW1iZXIgb2YgY2xpZW50cyB0aGF0IGp1c3RpZmllZFxcbmV4cGFuc2lvbiBpbiB0aGUgY2l0eS4gVGhlIHBvcHVsYXRpb24gaW4gdGhlIG5laWdoYm9yaG9vZHMgc2VsZWN0ZWQgZm9yIHRoZSBzdHVkeSByYW5nZXMgZnJvbVxcbjQ2IHRvIDU1NSBob3VzZWhvbGRzLiBUaGUgc2x1bXMgY2hvc2VuIHRvIGJlIHBhcnQgb2YgdGhlIHN0dWR5IHdlcmUgdHlwaWNhbGx5IG5vdCBjb250aW51b3VzXFxudG8gYXZvaWQgc3BpbGxvdmVycyBhY3Jvc3MgdHJlYXRtZW50IGFuZCBjb250cm9sIHNsdW1zLlxcbkluIGVhY2ggYXJlYSwgQ01GIGZpcnN0IGhpcmVkIGEgbWFya2V0IHJlc2VhcmNoIGNvbXBhbnkgdG8gY29uZHVjdCBhIHNtYWxsIGJhc2VsaW5lIG5laWdoYm9yaG9vZCBzdXJ2ZXkgaW4gMjAwNSwgY29sbGVjdGluZyBpbmZvcm1hdGlvbiBvbiBob3VzZWhvbGQgY29tcG9zaXRpb24sIGVkdWNhdGlvbiwgZW1wbG95bWVudCwgYXNzZXQgb3duZXJzaGlwLCBleHBlbmRpdHVyZSwgYm9ycm93aW5nLCBzYXZpbmcsIGFuZCBhbnkgYnVzaW5lc3NlcyBjdXJyZW50bHkgb3BlcmF0ZWRcXG5ieSB0aGUgaG91c2Vob2xkIG9yIHN0b3BwZWQgd2l0aGluIHRoZSBsYXN0IHllYXIuIFRoZXkgc3VydmV5ZWQgYSB0b3RhbCBvZiAyLDgwMCBob3VzZWhvbGRzIGluXFxub3JkZXIgdG8gb2J0YWluIGEgcmFwaWQgYXNzZXNzbWVudCBvZiB0aGUgYmFzZWxpbmUgY29uZGl0aW9ucyBvZiB0aGUgbmVpZ2hib3Job29kcy4gSG93ZXZlcixcXG5zaW5jZSB0aGVyZSB3YXMgbm8gZXhpc3RpbmcgY2Vuc3VzLCBhbmQgdGhlIGJhc2VsaW5lIHN1cnZleSBoYWQgdG8gYmUgY29uZHVjdGVkIHZlcnkgcmFwaWRseSB0b1xcbmdhdGhlciBzb21lIGluZm9ybWF0aW9uIG5lY2Vzc2FyeSBmb3Igc3RyYXRpZmljYXRpb24gYmVmb3JlIFNwYW5kYW5hIGJlZ2FuIHRoZWlyIG9wZXJhdGlvbnMsIHRoZVxcbmhvdXNlaG9sZHMgd2VyZSBub3Qgc2VsZWN0ZWQgcmFuZG9tbHkgZnJvbSBhIGhvdXNlaG9sZCBsaXN0OiBpbnN0ZWFkIGZpZWxkIG9mZmljZXJzIHdlcmUgYXNrZWRcXG50byBtYXAgdGhlIGFyZWEgYW5kIHNlbGVjdCBldmVyeSBuXFxudGggaG91c2UsIHdpdGggbiBjaG9zZW4gdG8gc2VsZWN0IDIwIGhvdXNlaG9sZHMgcGVyIGFyZWEuXFxuVW5mb3J0dW5hdGVseSwgdGhpcyBwcm9jZWR1cmUgd2FzIG5vdCBmb2xsb3dlZCB2ZXJ5IHJpZ29yb3VzbHkgYnkgdGhlIG1hcmtldCByZXNlYXJjaCBjb21wYW55LFxcbmFuZCB3ZSBhcmUgbm90IGNvbmZpZGVudCB0aGF0IHRoZSBiYXNlbGluZSBpcyByZXByZXNlbnRhdGl2ZSBvZiB0aGUgc2x1bSBhcyBhIHdob2xlLiBUaHVzLCB0aGVcXG5iYXNlbGluZSBzdXJ2ZXkgd2FzIHVzZWQgc29sZWx5IGFzIGEgYmFzaXMgZm9yIHN0cmF0aWZpY2F0aW9uLCB0aGUgZGVzY3JpcHRpdmUgYW5hbHlzaXMgYWJvdmUsIGFuZFxcbnRvIGNvbGxlY3QgYXJlYS1sZXZlbCBjaGFyYWN0ZXJpc3RpY3MgdGhhdCBhcmUgdXNlZCBhcyBjb250cm9sIHZhcmlhYmxlcy45IEJleW9uZCB0aGlzLCB3ZSBkbyBub3RcXG51c2UgdGhlIGJhc2VsaW5lIHN1cnZleSBpbiB0aGUgYW5hbHlzaXMgdGhhdCBmb2xsb3dzLlxcbkFmdGVyIHRoZSBiYXNlbGluZSBzdXJ2ZXksIGJ1dCBwcmlvciB0byByYW5kb21pemF0aW9uLCBzaXh0ZWVuIGFyZWFzIHdlcmUgZHJvcHBlZCBmcm9tXFxudGhlIHN0dWR5IGJlY2F1c2UgdGhleSB3ZXJlIGZvdW5kIHRvIGNvbnRhaW4gbGFyZ2UgbnVtYmVycyBvZiBtaWdyYW50LXdvcmtlciBob3VzZWhvbGRzLlxcbjlIb3dldmVyLCBvbWl0dGluZyB0aGVzZSBjb250cm9scyBtYWtlcyBubyBkaWZmZXJlbmNlIHRvIHRoZSByZXN1bHRzLlxcbjlcXG5TcGFuZGFuYSAobGlrZSBvdGhlciBNRklzKSBoYXMgYSBydWxlIHRoYXQgbG9hbnMgc2hvdWxkIG9ubHkgYmUgbWFkZSB0byBob3VzZWhvbGRzIHdob1xcbmhhdmUgbGl2ZWQgaW4gdGhlIHNhbWUgY29tbXVuaXR5IGZvciBhdCBsZWFzdCBvbmUgeWVhciBiZWNhdXNlIHRoZSBvcmdhbml6YXRpb24gYmVsaWV2ZXMgdGhhdFxcbmR5bmFtaWMgaW5jZW50aXZlcyAodGhlIHByb21pc2Ugb2YgbW9yZSBjcmVkaXQgaW4gdGhlIGZ1dHVyZSkgYXJlIG1vcmUgaW1wb3J0YW50IGluIG1vdGl2YXRpbmdcXG5yZXBheW1lbnQgZm9yIHRoZXNlIGhvdXNlaG9sZHMuMTAgVGhlIHJlbWFpbmluZyAxMDQgYXJlYXMgd2VyZSBncm91cGVkIGludG8gcGFpcnMgb2Ygc2ltaWxhclxcbm5laWdoYm9yaG9vZHMsIGJhc2VkIG9uIGF2ZXJhZ2UgcGVyIGNhcGl0YSBjb25zdW1wdGlvbiBhbmQgcGVyLWhvdXNlaG9sZCBkZWJ0LCBhbmQgb25lIG9mXFxuZWFjaCBwYWlyIHdhcyByYW5kb21seSBhc3NpZ25lZCB0byB0aGUgdHJlYXRtZW50IGdyb3VwLjExIEZpZ3VyZSA1IHNob3dzIGEgdGltZWxpbmUgb2YgZGF0YVxcbmNvbGxlY3Rpb24gYW5kIHJhbmRvbWl6YXRpb24uXFxuVGFibGUgMSB1c2VzIHRoZSBiYXNlbGluZSBzYW1wbGUgdG8gc2hvdyB0aGF0IHRyZWF0bWVudCBhbmQgY29tcGFyaXNvbiBhcmVhcyBkaWQgbm90XFxuZGlmZmVyIGluIHRoZWlyIGJhc2VsaW5lIGxldmVscyBvZiBkZW1vZ3JhcGhpYywgZmluYW5jaWFsLCBvciBlbnRyZXByZW5ldXJzaGlwIGNoYXJhY3RlcmlzdGljcyBpbiB0aGVcXG5iYXNlbGluZSBzdXJ2ZXkuIFRoaXMgaXMgbm90IHN1cnByaXNpbmcsIHNpbmNlIHRoZSBzYW1wbGUgd2FzIHN0cmF0aWZpZWQgYWNjb3JkaW5nIHRvIHBlciBjYXBpdGFcXG5jb25zdW1wdGlvbiBhbmQgZnJhY3Rpb24gb2YgaG91c2Vob2xkcyB3aXRoIGRlYnQuXFxuU3BhbmRhbmEgdGhlbiBwcm9ncmVzc2l2ZWx5IGJlZ2FuIG9wZXJhdGluZyBpbiB0aGUgNTIgdHJlYXRtZW50IGFyZWFzIGJldHdlZW4gMjAwNiBhbmRcXG4yMDA3LiBUaGUgcm9sbCBvdXQgaGFwcGVuZWQgYXQgZGlmZmVyZW50IGRhdGUgaW4gZGlmZmVyZW50IHNsdW1zLiBOb3RlIHRoYXQgaW4gdGhlIGludGVydmVuaW5nXFxucGVyaW9kcywgb3RoZXIgTUZJcyBhbHNvIHN0YXJ0ZWQgdGhlaXIgb3BlcmF0aW9ucywgYm90aCBpbiB0cmVhdG1lbnQgYW5kIGNvbXBhcmlzb24gYXJlYXMuIFdlXFxud2lsbCBzaG93IGJlbG93IHRoYXQgdGhlcmUgaXMgc3RpbGwgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gTUZJIGJvcnJvd2luZyBpbiB0cmVhdG1lbnRcXG5hbmQgY29tcGFyaXNvbiBncm91cHMuIFNwYW5kYW5hIGNyZWRpdCBvZmZpY2VycyBhbHNvIHN0YXJ0ZWQgbGVuZGluZyBpbiB2ZXJ5IGZldyBvZiB0aGUgY29udHJvbFxcbnNsdW1zLCBhbHRob3VnaCB0aGlzIHdhcyBzdG9wcGVkIHJlbGF0aXZlbHkgcmFwaWRseS4gRnVydGhlcm1vcmUsIHRoZXJlIHdhcyBubyBydWxlIGFnYWluc3RcXG5ib3Jyb3dpbmcgaW4gYW5vdGhlciBzbHVtIChpZiBvbmUgY291bGQgZmluZCBhIGdyb3VwIHRvIGpvaW4pLCBhbmQgc29tZSBwZW9wbGUgZGlkIGRvIHNvLlxcbk92ZXJhbGwsIDUlIG9mIGhvdXNlaG9sZHMgaW4gY29udHJvbCBzbHVtcyB3ZXJlIGJvcnJvd2luZyBmcm9tIFNwYW5kYW5hIGF0IHRoZSBlbmRsaW5lLlxcblRvIGNyZWF0ZSBhIHByb3BlciBzYW1wbGluZyBmcmFtZSBmb3IgdGhlIGVuZGxpbmUsIENNRiBzdGFmZiB1bmRlcnRvb2sgYSBjb21wcmVoZW5zaXZlXFxuY2Vuc3VzIG9mIGVhY2ggYXJlYSBpbiBlYXJseSAyMDA3LCBhbmQgaW5jbHVkZWQgYSBxdWVzdGlvbiBvbiBib3Jyb3dpbmcuIFRoZSBjZW5zdXMgcmV2ZWFsZWRcXG5sb3cgcmF0ZXMgb2YgTUZJIGJvcnJvd2luZyBldmVuIGluIHRyZWF0bWVudCBhcmVhcywgc28gdGhlIGVuZGxpbmUgc2FtcGxpbmcgZnJhbWUgY29uc2lzdGVkXFxub2YgaG91c2Vob2xkcyB3aG9zZSBjaGFyYWN0ZXJpc3RpY3Mgc3VnZ2VzdGVkIGhpZ2ggbGlrZWxpaG9vZCBvZiBoYXZpbmcgYm9ycm93ZWQ6IHRob3NlIHRoYXRcXG5oYWQgcmVzaWRlZCBpbiB0aGUgYXJlYSBmb3IgYXQgbGVhc3QgdGhyZWUgeWVhcnMgYW5kIGNvbnRhaW5lZCBhdCBsZWFzdCBvbmUgd29tYW4gYWdlZCAxOCB0b1xcbjU1LiBTcGFuZGFuYSBib3Jyb3dlcnMgaWRlbnRpZmllZCBpbiB0aGUgY2Vuc3VzIHdlcmUgb3ZlcnNhbXBsZWQsIGJlY2F1c2Ugd2UgYmVsaWV2ZWQgdGhhdFxcbjEwV2UgY2FuIGNvbXBhcmUgYmFzZWxpbmUgY2hhcmFjdGVyaXN0aWNzIGluIHRoZSAxNiBhcmVhcyBkcm9wcGVkIHRvIHRob3NlIGluIHRoZSAxMDQgYXJlYXMgaW5jbHVkZWQgaW4gdGhlXFxucmFuZG9taXphdGlvbi4gVGhlIGRpZmZlcmVuY2VzIGFyZSBjb25zaXN0ZW50IHdpdGggU3BhbmRhbmHigJlzIHJhdGlvbmFsZSBmb3IgZHJvcHBpbmcgdGhlIG9taXR0ZWQgYXJlYXM6IGhvdXNlaG9sZFxcbnNpemUgaXMgc21hbGxlciBpbiB0aGVzZSBhcmVhcyAoZHVlIHRvIG1pZ3JhbnQgd29ya2VycyB0aGVyZSB3aXRob3V0IGZhbWlsaWVzIG9yIGNoaWxkcmVuKTsgdGhlcmUgaXMgbGVzcyBidXNpbmVzc1xcbmNyZWF0aW9uIChwcmVzdW1hYmx5IGJlY2F1c2UgbWlncmFudHMgYXJlIHVubGlrZWx5IHRvIHN0YXJ0IGEgYnVzaW5lc3MpIGFuZCB0aGVyZSBpcyBsZXNzIGNyZWRpdCBvdXRzdGFuZGluZyAobGlrZWx5XFxuYmVjYXVzZSBpbmZvcm1hbCBsZW5kZXJzIGFyZSBhbHNvIHJlbHVjdGFudCB0byBsZW5kIHRvIHRoZXNlIHZlcnkgbW9iaWxlIGhvdXNlaG9sZHMpLiAoUmVzdWx0cyBhdmFpbGFibGUgdXBvblxcbnJlcXVlc3QuKVxcbjExUGFpcnMgd2VyZSBmb3JtZWQgdG8gbWluaW1pemUgdGhlIHN1bSBhY3Jvc3MgcGFpcnMgQSwgQiAoYXJlYSBBIGF2ZyBsb2FuIGJhbGFuY2Ug4oCTIGFyZWEgQiBhdmcgbG9hbiBiYWxhbmNlKTJcXG4rIChhcmVhIEEgcGVyIGNhcGl0YSBjb25zdW1wdGlvbiDigJMgYXJlYSBCIHBlciBjYXBpdGEgY29uc3VtcHRpb24pMlxcbi4gV2l0aGluIGVhY2ggcGFpciBvbmUgbmVpZ2hib3Job29kIHdhc1xcbnJhbmRvbWx5IGFsbG9jYXRlZCBpbnRvIHRyZWF0bWVudC5cXG4xMFxcbmhldGVyb2dlbmVpdHkgaW4gdHJlYXRtZW50IGVmZmVjdCB3b3VsZCBpbnRyb2R1Y2UgbW9yZSB2YXJpYW5jZSBpbiBvdXRjb21lcyBhbW9uZyBTcGFuZGFuYVxcbmJvcnJvd2VycyB0aGFuIGFtb25nIG5vbiBib3Jyb3dlcnMsIGFuZCBvdmVyc2FtcGxpbmcgYm9ycm93ZXJzIHdvdWxkIHRoZXJlZm9yZSBnaXZlIGhpZ2hlclxcbnBvd2VyLiBUaGUgcmVzdWx0cyBwcmVzZW50ZWQgYmVsb3cgd2VpZ2ggdGhlIG9ic2VydmF0aW9uIHRvIGFjY291bnQgZm9yIHRoaXMgb3ZlcnNhbXBsaW5nIHNvXFxudGhhdCB0aGUgcmVzdWx0cyBhcmUgcmVwcmVzZW50YXRpdmUgb2YgdGhlIHBvcHVsYXRpb24gYXMgYSB3aG9sZS4gU2luY2UgdGhlIHNhbXBsaW5nIGZyYW1lIGF0XFxuYmFzZWxpbmUgd2FzIG5vdCByaWdvcm91cyBlbm91Z2gsIGJhc2VsaW5lIGhvdXNlaG9sZHMgd2VyZSBub3QgcHVycG9zZWx5IHJlc3VydmV5ZWQgaW4gdGhlXFxuZm9sbG93LXVwLiBUaGUgZmlyc3QgZW5kbGluZSBzdXJ2ZXkgYmVnYW4gaW4gQXVndXN0IDIwMDcgYW5kIGVuZGVkIGluIEFwcmlsIDIwMDgsIGFuZCB0aGUgcm9sbFxcbm91dCBvZiB0aGUgZW5kbGluZSBmb2xsb3dlZCB0aGUgcm9sbCBvdXQgb2YgdGhlIHByb2dyYW0uIEluIGVhY2ggYXJlYSwgdGhpcyBmaXJzdCBlbmRsaW5lIHN1cnZleVxcbndhcyBjb25kdWN0ZWQgYXQgbGVhc3QgMTIgbW9udGhzIGFmdGVyIFNwYW5kYW5hIGJlZ2FuIGRpc2J1cnNpbmcgbG9hbnMgaW4gdGhpcyBwYXJ0aWN1bGFyIGFyZWEsXFxuYW5kIGdlbmVyYWxseSAxNSB0byAxOCBtb250aHMgYWZ0ZXIgKHRoZSBzdXJ2ZXkgZm9sbG93ZWQgdGhlIHNhbWUgY2FsZW5kYXIgaW4gdGhlIGNvbnRyb2wgc2x1bXMsXFxuaW4gb3JkZXIgdG8gZW5zdXJlIGNvbXBhcmFiaWxpdHkgYmV0d2VlbiB0cmVhdG1lbnQgYW5kIGNvbnRyb2wpLiBUaGUgb3ZlcmFsbCBzYW1wbGUgc2l6ZSB3YXNcXG42LDg2NCBob3VzZWhvbGRzLlxcblR3byB5ZWFycyBsYXRlciwgaW4gMjAwOS0yMDEwLCBhIHNlY29uZCBlbmRsaW5lIHN1cnZleSwgZm9sbG93aW5nIHVwIG9uIHRoZSBzYW1lIGhvdXNlaG9sZHMsXFxud2FzIHVuZGVydGFrZW4uIEl0IGluY2x1ZGVkIHRoZSBzYW1lIHNldCBvZiBxdWVzdGlvbnMgYXMgaW4gMjAwNy0yMDA4IHRvIGluc3VyZSBjb21wYXJhYmlsaXR5LlxcblRoZSByZS1jb250YWN0IHJhdGUgd2FzIHZlcnkgaGlnaCAoOTAlKS4gV2UgZGlzY3VzcyB0aGlzIGF0dHJpdGlvbiBpbiBtb3JlIGRldGFpbHMgYmVsb3cuXFxuMy4yIFBvdGVudGlhbCB0aHJlYXRzIHRvIGlkZW50aWZpY2F0aW9uIGFuZCBjYXZlYXRzIG9uIGludGVycHJldGF0aW9uXFxuMy4yLjEgQXR0cml0aW9uIGFuZCBzZWxlY3RpdmUgbWlncmF0aW9uXFxuU2luY2Ugd2UgZG9u4oCZdCBoYXZlIGEgcHJvcGVyIGJhc2VsaW5lIHNhbXBsZSB0aGF0IHdhcyBzeXN0ZW1hdGljYWxseSBmb2xsb3dlZCwgYSBwb3RlbnRpYWwgd29ycnlcXG5pcyB0aGF0IHRoZSBzYW1wbGUgdGhhdCBpcyBzdXJ2ZXllZCBhdCBlbmRsaW5lIG1heSBub3QgYmUgc3RyaWN0bHkgY29tcGFyYWJsZSBpbiB0cmVhdG1lbnQgYW5kXFxuY29udHJvbCBhcmVhcywgaWYgdGhlcmUgd2FzIGRpZmZlcmVudGlhbCBhdHRyaXRpb24gaW4gdHJlYXRtZW50IGFuZCBpbiBjb250cm9sIGdyb3Vwcy4gRm9yIGV4YW1wbGUsXFxucGVvcGxlIGNvdWxkIGhhdmUgbW92ZWQgaW50byB0aGUgYXJlYSwgb3IgYXZvaWRlZCBtb3Zpbmcgb3V0IG9mIHRoZSBhcmVhLCBiZWNhdXNlIFNwYW5kYW5hXFxuaGFkIHN0YXJ0ZWQgdGhlaXIgb3BlcmF0aW9ucyB0aGVyZS4gVGhpcyBkb2VzIG5vdCBzZWVtIGhpZ2hseSBsaWtlbHksIGdpdmVuIHRoYXQgaWYgc29tZW9uZSByZWFsbHlcXG53YW50ZWQgdG8gYm9ycm93LCB0aGV5IGhhZCBvcHRpb25zIHRvIGRvIHNvIGVpdGhlciBmcm9tIGFub3RoZXIgTUZJICh3ZSB3aWxsIHNlZSB0aGF0IGEgZmFpclxcbm51bWJlciBvZiBwZW9wbGUgZGlkKSBvciBldmVuIGZyb20gU3BhbmRhbmEsIGJ5IGdvaW5nIHRvIHRoZSBuZXh0IG5laWdoYm9yaG9vZC4gVGhlIHRyZWF0bWVudFxcbm9ubHkgbWFkZSBpdCBtYXJnaW5hbGx5IGVhc2llciB0byBib3Jyb3cgKGFzIHdlIHdpbGwgc2VlIGluIHRoZSBuZXh0IHNlY3Rpb24pLiBOZXZlcnRoZWxlc3MsIGluXFxucmV0cm9zcGVjdCwgaXQgd2FzIGEgY2xlYXIgbWlzdGFrZSBub3QgdG8gYXR0ZW1wdCB0byBzeXN0ZW1hdGljYWxseSByZS1zdXJ2ZXkgYXQgbGVhc3QgYSBmcmFjdGlvblxcbm9mIHRoZSBiYXNlbGluZSBzYW1wbGUsIGV2ZW4gdGhvdWdoIHRoZSBiYXNlbGluZSBzYW1wbGluZyBmcmFtZSB3YXMgd2Vhay5cXG5UaGF0IHNhaWQsIHdlIGhhdmUgYSBudW1iZXIgb2Ygd2F5cyB0byBhc3Nlc3MgdGhlIGV4dGVudCB0byB3aGljaCBhdHRyaXRpb24gaXMgYSBwcm9ibGVtLlxcbkZpcnN0IG9mIGFsbCwgaW4gVGFibGUgQTEsIHdlIHZlcmlmeSB0aGF0IHRoZSBob3VzZWhvbGRzIHN1cnZleWVkIGF0IGVuZGxpbmVzIDEgYW5kIDIgYXJlIHNpbWlsYXJcXG5pbiB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgZ3JvdXBzLCBpbiB0ZXJtcyBvZiBhIG51bWJlciBvZiBjaGFyYWN0ZXJpc3RpY3Mgd2hpY2ggYXJlIGZpeGVkIG92ZXJcXG4xMVxcbnRpbWUgKHRoZSBwLXZhbHVlIG9uIHRoZSBqb2ludCBkaWZmZXJlbmNlIG9mIHRoZXNlIGNoYXJhY3RlcmlzdGljcyBhY3Jvc3MgdHJlYXRtZW50IGFybXMgaXMgMC45ODAgYXRcXG5FTDEgYW5kIDAuNTM0IGF0IEVMMikuIFRoaXMgaXMgYSBmaXJzdCBpbmRpY2F0aW9uIHRoYXQgd2UgaGF2ZSBhIGNvbXBhcmFibGUgc2FtcGxlIGF0IGJhc2VsaW5lXFxuYW5kIGF0IGVuZGxpbmUsIGV2ZW4gYWxsb3dpbmcgZm9yIGF0dHJpdGlvbi5cXG5TZWNvbmQsIHRoZSBzYW1wbGUgYXQgRUwxIHdhcyBkcmF3biBmcm9tIGEgY2Vuc3VzIHRoYXQgd2FzIGNvbmR1Y3RlZCBmYWlybHkgc29vbiBhZnRlclxcbnRoZSBpbnRyb2R1Y3Rpb24gb2YgbWljcm9jcmVkaXQgKG9uIGF2ZXJhZ2UgbGVzcyB0aGFuIGEgeWVhcikuIE1vcmVvdmVyLCB0aGUgc2FtcGxpbmcgZnJhbWUgZm9yXFxuRUwxIHdhcyByZXN0cmljdGVkIHRvIHBlb3BsZSB3aG8gaGFkIGxpdmVkIGluIHRoZSBhcmVhIGZvciBhdCBsZWFzdCB0aHJlZSB5ZWFycyBiZWZvcmUgdGhlIGNlbnN1cy5cXG5UaGlzIG1lYW5zIHRoYXQgbm8gb25lIGluIHRoZSBzdXJ2ZXkgaGFkIG1pZ3JhdGVkIGludG8gdGhlIGFyZWEgYmVjYXVzZSBvZiBTcGFuZGFuYTogdGhleVxcbndlcmUgYWxsIHJlc2lkZW50cyBvZiB0aGUgYXJlYSB3ZWxsIGJlZm9yZSBTcGFuZGFuYSBtb3ZlZCBpbnRvIHRoZSBhcmVhICh0aGUgdmFzdCBtYWpvcml0eSBoYWRcXG5iZWVuIHRoZXJlIGZvciB5ZWFycykuIFRoaXMgcmVtb3ZlcyB0aGUgbW9zdCBwbGF1c2libGUgY2hhbm5lbCBmb3IgZGlmZmVyZW50aWFsIHNlbGVjdGlvbiBpbnRvIHRoZVxcbnNhbXBsZSBpbiB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgZ3JvdXBzLiBUaGVyZSByZW1haW5zIHRoZSBwb3NzaWJpbGl0eSB0aGF0IGZld2VyIHBlb3BsZSAob3JcXG5kaWZmZXJlbnQgcGVvcGxlKSBsZWZ0IHRoZSB0cmVhdG1lbnQgYXJlYXMgYmV0d2VlbiB0aGUgbGF1bmNoIG9mIHRoZSBwcm9kdWN0IGFuZCB0aGUgY2Vuc3VzIGR1ZVxcbnRvIHRoZSBvcHRpb24gdG8gYm9ycm93IG1vcmUgZWFzaWx5LCBidXQgaW4gbGVzcyB0aGFuIGEgeWVhciwgdGhlIG1pZ3JhdGlvbiByYXRlIG91dCBvZiBIeWRlcmFiYWRcXG5pcyBsb3csIGFuZCBnaXZlbiB0aGUgYWJpbGl0eSB0byBib3Jyb3cgaWYgc29tZW9uZSB3YW50cyB0bywgaXQgc2VlbXMgZmFyIGZldGNoZWQgdGhhdCBwZW9wbGVcXG53b3VsZCBoYXZlIGJlZW4gZGlmZmVyZW50aWFsbHkgbGlrZWx5IHRvIG1pZ3JhdGUgb3V0IG9mIHRoZSBzbHVtcyBiYXNlZCBvbiB0aGUgYWJpbGl0eSB0byBiZWNvbWVcXG5hIFNwYW5kYW5hIGNsaWVudC5cXG5XZSBjYW4gdGhlbiBzdHVkeSBhdHRyaXRpb24gYmV0d2VlbiBjZW5zdXMgYW5kIEVMMSwgYW5kIGJldHdlZW4gRUwxIGFuZCBFTDIuXFxuVGhlcmUgd2FzIHNvbWUgYXR0cml0aW9uIGJldHdlZW4gdGhlIGNlbnN1cyBhbmQgRUwxLCBlc3BlY2lhbGx5IHNpbmNlLCBhcyBpdCBjdXN0b21hcnkgaW5cXG50aGVzZSB0eXBlcyBvZiBzdXJ2ZXlzLCBjZW5zdXMgc3VydmV5b3JzIHdlcmUgZ2l2ZW4gcmVwbGFjZW1lbnQgbGlzdHMgaW4gY2FzZSB0aGV5IGRpZCBub3QgZmluZFxcbnRoZSBleGFjdCBwZXJzb24gdGhleSB3ZXJlIGxvb2tpbmcgZm9yLiBIb3dldmVyIHRoaXMgYXR0cml0aW9uIChyb3VnaGx5IDI1JSkgaXMgYWxtb3N0IGV4YWN0bHlcXG50aGUgc2FtZSBpbiB0cmVhdG1lbnQgYW5kIGluIGNvbnRyb2wgYXJlYXM6IDI3LjYlIGluIHRyZWF0bWVudCBhbmQgMjUuMiUgaW4gY29udHJvbCAocC12YWx1ZVxcbm9mIGRpZmZlcmVuY2U6IDAuMTY1OyBzZWUgVGFibGUgQTIsIFBhbmVsIEEpLiBNb3Jlb3ZlciwgdGhlIGF0dHJpdGlvbiBpcyB0b3RhbGx5IHVuY29ycmVsYXRlZCB3aXRoXFxudGhlIG1vbnRocyBlbGFwc2VkIHNpbmNlIFNwYW5kYW5hIGVudGVyZWQgdGhlIHNsdW0gKFRhYmxlIEEyLCBQYW5lbCBCKSwgd2hpY2ggaXMgbm90IHdoYXQgd2VcXG53b3VsZCBleHBlY3QgaWYgaXQgd2VyZSBzb21laG93IHJlbGF0ZWQgdG8gdGhlIHByb2dyYW0gKGl0IHdvdWxkIGhhdmUgaGFkIG1vcmUgdGltZSB0byBwbGF5XFxub3V0IGlmIFNwYW5kYW5hIGhhZCBlbnRlcmVkIGEgbG9uZ2VyIHRpbWUgYmVmb3JlKS4gVGhlIG9ubHkgY2hhcmFjdGVyaXN0aWNzIHRoYXQgcHJlZGljdCB0aGF0XFxuc29tZW9uZSBpcyBtb3JlIGxpa2VseSB0byBiZSBmb3VuZCBpcyB0aGF0IHRoZXkgYXJlIGEgU3BhbmRhbmEgYm9ycm93ZXIgKDQuMnBwIGxvd2VyIGF0dHJpdGlvbjtcXG5TRSBvZiAxLjk3cHApLCBhbmQgbGl2aW5nIGluIGEg4oCcbm9uLXB1Y2Nh4oCdIChsb3dlci1xdWFsaXR5KSBob3VzZSAoMi43cHAgbG93ZXIgYXR0cml0aW9uOyBTRSBvZlxcbjEuNHBwKS4gVGhlIG1vc3QgbGlrZWx5IHJlYXNvbiBmb3IgdGhlIGZvcm1lciBpcyB0aGF0IHRoZSBTcGFuZGFuYSBvZmZpY2VycyBoZWxwZWQgdGhlIENNRlxcbmZpZWxkIHRlYW0gdG8gbG9jYXRlIHRoZWlyIGNsaWVudHMuIEZvciBleGFtcGxlLCBzdXJ2ZXlvcnMgY291bGQgYXR0ZW5kIHdlZWtseSBtZWV0aW5ncyB0byBjb2xsZWN0XFxuYWRkcmVzc2VzIGFuZCBmaW5kIGRpcmVjdGlvbnMgdG8gcGVvcGxl4oCZcyBob21lcy4gVGhlIGxhdHRlciBsaWtlbHkgcmVmbGVjdHMgZ3JlYXRlciBtb2JpbGl0eSBhbW9uZ1xcbndlYWx0aGllciBob3VzZWhvbGRzLiBJbiBhbGwgb2YgdGhlIGFuYWx5c2lzIHRoYXQgZm9sbG93cywgd2UgY29ycmVjdCBmb3IgdGhpcyBieSBhZGp1c3RpbmcgdGhlXFxuMTJcXG5zYW1wbGluZyB3ZWlnaHRzIGZvciB0aGUgcmF0aW8gYmV0d2VlbiB0aGUgcHJvYmFiaWxpdHkgdG8gZmluZCBhIG5vbi1TcGFuZGFuYSBib3Jyb3dlciBhbmQgdGhlXFxucHJvYmFiaWxpdHkgdG8gZmluZCBhIFNwYW5kYW5hIGJvcnJvd2VyICgwLjk0OCkuXFxuQXBwZW5kaXggVGFibGUgMywgUGFuZWwgQSBzaG93cyB0aGF0IHRoZSByZS1jb250YWN0IHJhdGUgYXQgZW5kbGluZSAyIGZvciBob3VzZWhvbGRzIGluaXRpYWxseVxcbmludGVydmlld2VkIGF0IGVuZGxpbmUgMSB3YXMgdmVyeSBoaWdoIChtdWNoIGhpZ2hlciB0aGFuIGluIG1vc3QgcmFuZG9taXplZCBjb250cm9sbGVkIHRyaWFscyxcXG5pbiB0aGUgVVMgb3IgaW4gZGV2ZWxvcGluZyBjb3VudHJpZXMpLiBJdCB3YXMgYWxzbyBzaW1pbGFyIGluIHRoZSB0cmVhdG1lbnQgYW5kIHRoZSBjb250cm9sXFxuZ3JvdXAsIGF0IDg5LjklIGFuZCA5MC4yJSwgcmVzcGVjdGl2ZWx5ICh0aGUgcC12YWx1ZSBvZiB0aGUgZGlmZmVyZW5jZSBpcyAwLjI0OCkuIFBhbmVsIEIgc2hvd3NcXG5hdmVyYWdlIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgcmUtY29udGFjdGVkIHZlcnN1cyBhdHRyaXRlZCBob3VzZWhvbGRzLiBUaGUgc2FtcGxlcyBkbyBub3QgZGlmZmVyXFxuc2lnbmlmaWNhbnRseSBhbG9uZyBtb3N0IGRpbWVuc2lvbnMuIEhvd2V2ZXIsIHRob3NlIHdobyBhdHRyaXRlZCBoYWQgc2xpZ2h0bHkgaGlnaGVyIHBlciBjYXBpdGFcXG5leHBlbmRpdHVyZSBhdCBlbmRsaW5lIDEsIHdpdGggYSBScy4gMTAwMCBpbmNyZWFzZSBpbiBleHBlbmRpdHVyZSBhc3NvY2lhdGVkIHdpdGggYSAwLjAwOThcXG5pbmNyZWFzZSBpbiBsaWtlbGlob29kIG9mIGF0dHJpdGlvbiAoY29sdW1uIDE6IHRoZSBzdGFuZGFyZCBlcnJvciBpcyAwLjAwMzIpLiBIYXZpbmcgYSBTcGFuZGFuYVxcbmxvYW4gYXQgZW5kbGluZSAxIHdhcyBhc3NvY2lhdGVkIHdpdGggMy4zIHBlcmNlbnRhZ2UgcG9pbnRzIGxvd2VyIGF0dHJpdGlvbiAoY29sdW1uIDU6IHRoZVxcbnN0YW5kYXJkIGVycm9yIGlzIDFwcCk7IGhhdmluZyBhbnkgTUZJIGxvYW4gaXMgYXNzb2NpYXRlZCB3aXRoIDIuNyBwZXJjZW50YWdlIHBvaW50cyBsb3dlclxcbmF0dHJpdGlvbiAoY29sdW1uIDY6IHRoZSBzdGFuZGFyZCBlcnJvciBpcyAwLjhwcCksIGRyaXZlbiBieSB0aGUgZWZmZWN0IG9mIFNwYW5kYW5hIGxvYW5zLiBBZ2FpbixcXG50aGUgZXhwbGFuYXRpb24gZm9yIHRoaXMgaXMgdGhhdCB0aGUgY3JlZGl0IG9mZmljZXJzIGhlbHBlZCB0aGUgZmllbGQgdGVhbSBmaW5kIHRoZSBjbGllbnRzLCBpZiB0aGV5XFxuaGFkIG1vdmVkIHdpdGhpbiB0aGVpciBzbHVtLiBQYW5lbCBDIG9mIFRhYmxlIEEzIHNob3dzIHNob3dzIHRoYXQgYmV0d2VlbiB0cmVhdG1lbnQgYW5kXFxuY29udHJvbCwgYXR0cml0aW9uIHdhcyBub3QgZGlmZmVyZW50aWFsbHkgY29ycmVsYXRlZCB3aXRoIGNoYXJhY3RlcmlzdGljcy5cXG5UaGlzIGRhdGEgc3VnZ2VzdHMgdGhhdCB0aGVyZSBpcyBubyBldmlkZW5jZSB0aGF0IG1pZ3JhdGlvbiBvciBhdHRyaXRpb24gcGF0dGVybnMgd2VyZSBkcml2ZW5cXG5ieSB0aGUgdHJlYXRtZW50LCBleGNlcHQgdGhyb3VnaCB0aGUgbWVjaGFuaWNhbCBlZmZlY3QgdGhhdCBTcGFuZGFuYSBjcmVkaXQgb2ZmaWNlcnMgaGVscGVkXFxuc3VydmV5b3JzIGxvY2F0ZSB0aGVpciBjbGllbnRzLCB3aGljaCB3ZSBjb3JyZWN0IGZvci5cXG5OZXZlcnRoZWxlc3MsIHRvIHN5c3RlbWF0aWNhbGx5IGFkZHJlc3MgdGhlIGNvbmNlcm4gdGhhdCBhdHRyaXRpb24gbWF5IGFmZmVjdCB0aGUgcmVzdWx0cyxcXG53ZSBoYXZlIHJlLWVzdGltYXRlZCBhbGwgdGhlIHJlZ3Jlc3Npb25zIGJlbG93IHdpdGggYSBjb3JyZWN0aW9uIGZvciBzYW1wbGUgc2VsZWN0aW9uIGluc3BpcmVkXFxuYnkgRGluYXJkbywgRm9ydGluIGFuZCBMZW1pZXV4ICgyMDEwKSwgd2hlcmUgd2UgcmUtd2VpZ2h0IHRoZSBkYXRhIHVzaW5nIHRoZSBpbnZlcnNlIG9mIHRoZVxcbnByb3BlbnNpdHkgdG8gYmUgb2JzZXJ2ZWQgYXQgZW5kbGluZSAyLCBzbyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2Ygb2JzZXJ2YWJsZSBjaGFyYWN0ZXJpc3RpY3MgKGF0XFxuZW5kbGluZSAxKSBhbW9uZyBob3VzZWhvbGRzIG9ic2VydmVkIGF0IGVuZGxpbmUgMiByZXNlbWJsZXMgdGhhdCBpbiB0aGUgZW50aXJlIGVuZGxpbmUgMSBzYW1wbGUuXFxuV2UgdGhlbiBhcHBseSB0aGUgc2FtZSB3ZWlnaHRzIHRvIGVuZGxpbmUgMSBkYXRhIChpbXBsaWNpdGx5IGFzc3VtaW5nIGEgc2ltaWxhciBzZWxlY3Rpb24gcHJvY2Vzc1xcbmJldHdlZW4gdGhlIG9uc2V0IG9mIG1pY3JvZmluYW5jZSBhbmQgZW5kbGluZSAxKS4gVGhlIHJlc3VsdHMsIHByZXNlbnRlZCBmb3Iga2V5IG91dGNvbWVzIGluXFxuVGFibGUgQTUsIGFyZSB2ZXJ5IHNpbWlsYXIgdG8gd2hhdCB3ZSBwcmVzZW50IGhlcmUuIChGdWxsIHJlc3VsdHMgYXZhaWxhYmxlIG9uIHJlcXVlc3QuKSBOb3RlXFxudGhhdCB0aGlzIHByb2NlZHVyZSBvbmx5IGNvcnJlY3RzIGZvciBkaWZmZXJlbnRpYWwgYXR0cml0aW9uIGJ5IG9ic2VydmFibGVzLCBub3QgYnkgdW5vYnNlcnZhYmxlXFxudmFyaWFibGVzLlxcbjEzXFxuSW50ZXJwcmV0aW5nIHRoZSByZXN1bHRzXFxuVGhlIGV4cGVyaW1lbnRhbCBkZXNpZ24gYW5kIHRoZSBpbXBsZW1lbnRhdGlvbiByYWlzZSBhIG51bWJlciBvZiBpc3N1ZXMgd29ydGgga2VlcGluZyBpbiBtaW5kXFxudG8gaW50ZXJwcmV0IHRoZSByZXN1bHRzIHRoYXQgZm9sbG93LlxcbkZpcnN0LCBnaXZlbiB0aGUgc2FtcGxpbmcgZnJhbWUsIG91cnMgd2lsbCBiZSBhbiBpbnRlbnQtdG8tdHJlYXQgKElUVCkgYW5hbHlzaXMgb24gYSBzYW1wbGUgb2ZcXG7igJxsaWtlbHkgYm9ycm93ZXJz4oCdLiBUaGlzIGlzIHRodXMgbmVpdGhlciB0aGUgZWZmZWN0IG9uIHRob3NlIHdobyBib3Jyb3cgbm9yIHRoZSBhdmVyYWdlIGVmZmVjdCBvblxcbnRoZSBuZWlnaGJvcmhvb2QuIFJhdGhlciwgaXQgaXMgdGhlIGF2ZXJhZ2UgZWZmZWN0IG9mIGVhc2llciBhY2Nlc3MgdG8gbWljcm9maW5hbmNlIG9uIHRob3NlIHdob1xcbmFyZSBwcmltYXJ5IHRhcmdldHMuIFNlY29uZCwgbWljcm9maW5hbmNlIHdhcyBhdmFpbGFibGUgaW4gYm90aCB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgYXJlYXMsXFxudGhvdWdoIGFjY2VzcyB3YXMgZWFzaWVyIGluIHRyZWF0bWVudCBhcmVhcy4gTWljcm9maW5hbmNlIHRha2UtdXAgaXMgaW5kZWVkIGhpZ2hlciBpbiB0cmVhdG1lbnRcXG5hcmVhcywgd2hpY2ggZ2VuZXJhdGVzIGV4cGVyaW1lbnRhbCB2YXJpYXRpb24sIGJ1dCB0aGUgbWFyZ2luYWwgY2xpZW50cyBtYXkgYmUgZGlmZmVyZW50IGZyb21cXG50aGUgZmlyc3QgY2xpZW50cyB0byBib3Jyb3cgaW4gYW4gYXJlYS4gVGhpcyBhbHNvIGFmZmVjdHMgcG93ZXI6IHRoZSBpbml0aWFsIHBvd2VyIGNhbGN1bGF0aW9uc1xcbndlcmUgcGVyZm9ybWVkIHdoZW4gU3BhbmRhbmEgdGhvdWdodCB0aGF0IDgwJSBvZiBlbGlnaWJsZSBob3VzZWhvbGRzIHdvdWxkIGJlY29tZSBjbGllbnRzXFxudmVyeSByYXBpZGx5IGFmdGVyIHRoZSBsYXVuY2guIEluIGZhY3QgdGhlIGRhdGEgc2hvd3MgdGhhdCB0aGUgcHJvcG9ydGlvbiByZWFjaGVkIG9ubHkgMTglXFxuaW4gMTggbW9udGhzIChhbmQgdGhpcyBzdGF5ZWQgYXQgMTglIGFmdGVyIHR3byBhbmQgYSBoYWxmIHllYXJzKS4gVGhpcyBpcyBsb3csIGFuZCBhbHNvIGdhdmVcXG5vdGhlciBNRklzLCB3aGljaCB3ZXJlIGJlaGluZCBTcGFuZGFuYSBpbiB0ZXJtcyBvZiBwZW5ldHJhdGlvbiBpbiBIeWRlcmFiYWQsIHRpbWUgdG8gY2F0Y2hcXG51cC4gT3ZlcmFsbCwgdGFrZS11cCBvZiBtaWNyb2ZpbmFuY2UgZnJvbSBhbnkgb3JnYW5pemF0aW9uIHdhcyBvbmx5IDMzJSBieSBFTDIuIFRoaXMgaXMgYW5cXG5pbXBvcnRhbnQgcmVzdWx0IGluIGl0cyBvd24gcmlnaHQsIGFuZCB2ZXJ5IHN1cnByaXNpbmcgYXQgdGhlIHRpbWUsIGJ1dCBpdCBpbXBsaWVzIHRoYXQsIHdpdGggdGhlXFxuYmVuZWZpdHMgb2YgaGluZHNpZ2h0LCBtb3JlIGFyZWFzIHdvdWxkIGhhdmUgYmVlbiBuZWVkZWQuIFRoaXMgaXMgbm90IHNvbWV0aGluZyB0aGF0IGNvdWxkIGJlXFxuYWRkcmVzc2VkIGV4LXBvc3QuIEZvcnR1bmF0ZWx5LCBzdWJzZXF1ZW50IGV2YWx1YXRpb25zIG9mIG1pY3JvZmluYW5jZSBwcm9ncmFtcyB3ZXJlIGFibGUgdG9cXG5kbyBzbywgYW5kIGZpbmQgYSB2ZXJ5IHNpbWlsYXIgc2V0IG9mIHJlc3VsdHMgKGFuZCBub24tcmVzdWx0cykgc3VnZ2VzdGluZyB0aGF0IHRoZXNlIG91dGNvbWVzIGFyZVxcbm5vdCB0aGUgYXJ0aWZhY3Qgb2Ygc2FtcGxlcyB0aGF0IGFyZSB0b28gc21hbGwsIG9yIG9mIGEgdmVyeSBub24tcmVwcmVzZW50YXRpdmUgc2V0IG9mIGNsaWVudHMuXFxuNCBSZXN1bHRzXFxuVG8gZXN0aW1hdGUgdGhlIGltcGFjdCBvZiBtaWNyb2ZpbmFuY2UgYmVjb21pbmcgYXZhaWxhYmxlIGluIGFuIGFyZWEgb24gbGlrZWx5IGNsaWVudHMsIHdlIGZvY3VzXFxub24gaW50ZW50LXRvLXRyZWF0IChJVFQpIGVzdGltYXRlczsgdGhhdCBpcywgc2ltcGxlIGNvbXBhcmlzb25zIG9mIGF2ZXJhZ2VzIGluIHRyZWF0bWVudCBhbmRcXG5jb21wYXJpc29uIGFyZWFzLCBhdmVyYWdlZCBvdmVyIGJvcnJvd2VycyBhbmQgbm9uLWJvcnJvd2Vycy4gV2UgcHJlc2VudCBJVFQgZXN0aW1hdGVzIG9mIHRoZVxcbmVmZmVjdCBvZiBtaWNyb2ZpbmFuY2Ugb24gYnVzaW5lc3NlcyBvcGVyYXRlZCBieSB0aGUgaG91c2Vob2xkOyBmb3IgdGhvc2Ugd2hvIG93biBidXNpbmVzc2VzLFxcbndlIGV4YW1pbmUgYnVzaW5lc3MgcHJvZml0cywgcmV2ZW51ZSwgYnVzaW5lc3MgaW5wdXRzLCBhbmQgdGhlIG51bWJlciBvZiB3b3JrZXJzIGVtcGxveWVkIGJ5XFxudGhlIGJ1c2luZXNzLiAoVGhlIGNvbnN0cnVjdGlvbiBvZiB0aGVzZSB2YXJpYWJsZXMgaXMgZGVzY3JpYmVkIGluIEFwcGVuZGl4IDEuKSBFYWNoIGNvbHVtbiBvZlxcbjE0XFxuZWFjaCB0YWJsZSByZXBvcnRzIHRoZSByZXN1bHRzIG9mIGEgcmVncmVzc2lvbiBvZiB0aGUgZm9ybVxcbnlpYSA9IM6xICsgzrIgw5cgVCByZWF0aWEgKyBYXFxuMFxcbmHOsyArIM61aWFcXG53aGVyZSB5aWEgaXMgYW4gb3V0Y29tZSBmb3IgaG91c2Vob2xkIGkgaW4gYXJlYSBhLCBUIHJlYXRpYSBpcyBhbiBpbmRpY2F0b3IgZm9yIGxpdmluZyBpbiBhIHRyZWF0ZWRcXG5hcmVhLCBhbmQgzrIgaXMgdGhlIGludGVudC10by10cmVhdCBlZmZlY3QuIFhcXG4wXFxuYVxcbmlzIGEgdmVjdG9yIG9mIGNvbnRyb2wgdmFyaWFibGVzLCBjYWxjdWxhdGVkIGFzIGFyZWFsZXZlbCBiYXNlbGluZSB2YWx1ZXM6IGFyZWEgcG9wdWxhdGlvbiwgdG90YWwgYnVzaW5lc3NlcywgYXZlcmFnZSBwZXIgY2FwaXRhIGV4cGVuZGl0dXJlLCBmcmFjdGlvblxcbm9mIGhvdXNlaG9sZCBoZWFkcyB3aG8gYXJlIGxpdGVyYXRlLCBhbmQgZnJhY3Rpb24gb2YgYWxsIGFkdWx0cyB3aG8gYXJlIGxpdGVyYXRlLiBTdGFuZGFyZCBlcnJvcnNcXG5hcmUgYWRqdXN0ZWQgZm9yIGNsdXN0ZXJpbmcgYXQgdGhlIGFyZWEgbGV2ZWwgYW5kIGFsbCByZWdyZXNzaW9ucyBhcmUgd2VpZ2h0ZWQgdG8gY29ycmVjdCBmb3JcXG5vdmVyc2FtcGxpbmcgb2YgU3BhbmRhbmEgYm9ycm93ZXJzIGFuZCBmb3IgaGlnaGVyIHByb2JhYmlsaXR5IG9mIHRyYWNraW5nIHRoZW0uIFdlIGVzdGltYXRlZFxcbnR3byBzZXRzIG9mIHJlZ3Jlc3Npb25zIHdpdGggYSBkaWZmZXJlbnQgc3BlY2lmaWNhdGlvbjogbm8gY29udHJvbCB3aGF0c29ldmVyLCBhbmQgY29udHJvbCBmb3JcXG5zdHJhdGEgcmF0aGVyIHRoYW4gZm9yIHRoZSBhdmVyYWdlIGNoYXJhY3RlcmlzdGljcyBpbiB0aGUgY29udHJvbCBzbHVtcy4gVGhlIHJlc3VsdHMgKG5vdCByZXBvcnRlZFxcbmhlcmUsIGJ1dCBhdmFpbGFibGUgb24gcmVxdWVzdCkgYXJlIHF1YWxpdGF0aXZlbHkgdW5jaGFuZ2VkLiBDb250cm9sbGluZyBmb3Igc3RyYXRhIHNvbWV3aGF0XFxuaW5jcmVhc2VzIHRoZSBwcmVjaXNpb24gaW4gdGhpcyBjYXNlLCBzbyBzb21lIHJlc3VsdHMgdGhhdCBhcmUgYWxtb3N0IHNpZ25pZmljYW50IGhlcmUgYmVjb21lXFxuc2lnbmlmaWNhbnQgd2l0aCBzdHJhdGEgY29udHJvbHMgKHRoaXMgaXMgcGFydGljdWxhcmx5IHRydWUgZm9yIHRoZSBncm91cGVkIG91dGNvbWVzKS5cXG5JbiBhbnkgc3R1ZHkgb2YgdGhpcyBraW5kLCB3aGVyZSB0aGVyZSBhcmUgbWFueSBwb3NzaWJsZSBvdXRjb21lcyB3aXRob3V0IGEgc2luZ2xlIHBvc3NpYmxlXFxuY2F1c2FsIHBhdGh3YXlzLCB0aGVyZSBpcyBhIGRhbmdlciBvZiBvdmVyaW50ZXJwcmV0aW5nIGFueSBzaW5nbGUgc2lnbmlmaWNhbnQgcmVzdWx0IChvciBldmVuXFxuZGlzY2VybmluZyBhIHBhdHRlcm4gb2YgcmVzdWx0cyB3aGVuIHRoZXJlIGlzIG5vbmUpLiBXZSB0YWtlIGEgbnVtYmVyIG9mIHN0ZXBzIHRvIGF2b2lkIHRoaXNcXG5wcm9ibGVtLiBGaXJzdCwgd2UgcmVwb3J0IHRoZSBvdXRjb21lIGZvbGxvd2luZyB0aGUgdGVtcGxhdGUgdGhhdCBhbGwgcGFwZXJzIGluIHRoaXMgaXNzdWUgZm9sbG93LFxcbmluc3VyaW5nIG5vIHNlbGVjdGlvbiBvZiBvdXRjb21lcyBiYXNlZCBvbiB3aGF0IGlzIHNpZ25pZmljYW50IG9yIG5vdC4gU2Vjb25kLCBmb3IgZWFjaCB0YWJsZVxcbih3aGljaCBjb3JyZXNwb25kcyB0byBhIOKAnGZhbWlseeKAnSBvZiBvdXRjb21lcykgd2UgcmVwb3J0IGFuIGluZGV4IChhIGxhIEthdHosIEtsaW5nIGFuZCBMaWVibWFuXFxuMjAwNykgb2YgYWxsIHRoZSBvdXRjb21lcyBpbiB0aGUgZmFtaWx5IHRha2VuIHRvZ2V0aGVyLjEyIEZpbmFsbHksIGZvciBlYWNoIG9mIHRoZXNlIG91dGNvbWVzLFxcbndlIHJlcG9ydCBib3RoIHRoZSBzdGFuZGFyZCBwLXZhbHVlIGFuZCB0aGUgcC12YWx1ZSBhZGp1c3RlZCBmb3IgbXVsdGlwbGUgaHlwb3RoZXNlcyB0ZXN0aW5nXFxuYWNyb3NzIGFsbCB0aGUgaW5kaWNlcy4gVGhlIGFkanVzdGVkIHAtdmFsdWVzIGFyZSBjYWxjdWxhdGVkIHVzaW5nIHRoZSBzdGVwLWRvd24gcHJvY2VkdXJlIG9mXFxuSG9jaGJlcmcgKDE5ODgpLCB3aGljaCBjb250cm9scyB0aGUgZmFtaWx5LXdpc2UgZXJyb3IgcmF0ZSBmb3IgYWxsIHRoZSBpbmRpY2VzLiBTZWUgQXBwZW5kaXggQS40XFxuZm9yIGRldGFpbHMuXFxuMTJUaGUgdmFyaWFibGVzIGFyZSBzaWduZWQgc3VjaCBhdCB0aGF0IGEgcG9zaXRpdmUgdHJlYXRtZW50IGVmZmVjdCBpcyBhIOKAnGdvb2TigJ0gb3V0Y29tZS4gVGhleSBhcmUgdGhlbiBub3JtYWxpemVkXFxuYnkgc3VidHJhY3RpbmcgdGhlIG1lYW4gaW4gdGhlIGNvbnRyb2wgZ3JvdXAgYW5kIGRpdmlkaW5nIGJ5IHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gaW4gdGhlIGNvbnRyb2wgZ3JvdXAuIFRoZVxcbmluZGV4IGlzIHRoZSBzaW1wbGUgYXZlcmFnZSBvZiB0aGUgbm9ybWFsaXplZCB2YXJpYWJsZXMuXFxuMTVcXG40LjEgQm9ycm93aW5nIGZyb20gU3BhbmRhbmEgYW5kIG90aGVyIE1GSXNcXG5UcmVhdG1lbnQgY29tbXVuaXRpZXMgd2VyZSByYW5kb21seSBzZWxlY3RlZCB0byByZWNlaXZlIFNwYW5kYW5hIGJyYW5jaGVzLCBidXQgb3RoZXIgTUZJc1xcbmFsc28gc3RhcnRlZCBvcGVyYXRpbmcgYm90aCBpbiB0cmVhdG1lbnQgYW5kIGNvbXBhcmlzb24gYXJlYXMuIFdlIGFyZSBpbnRlcmVzdGVkIGluIHRlc3RpbmcgdGhlXFxuaW1wYWN0IG9mIGFjY2VzcyB0byBtaWNyb2NyZWRpdCwgbm90IG9ubHkgb2YgYm9ycm93aW5nIGZyb20gU3BhbmRhbmEuIFRhYmxlIDIgUGFuZWwgQSBzaG93c1xcbnRoYXQsIGJ5IHRoZSBmaXJzdCBlbmRsaW5lLCBNRkkgYm9ycm93aW5nIHdhcyBpbmRlZWQgaGlnaGVyIGluIHRyZWF0bWVudCB0aGFuIGluIGNvbnRyb2wgc2x1bXMsXFxuYWx0aG91Z2ggYm9ycm93aW5nIGZyb20gb3RoZXIgTUZJcyBtYWRlIHVwIGZvciBwYXJ0IG9mIHRoZSBkaWZmZXJlbmNlIGluIFNwYW5kYW5hIGJvcnJvd2luZy5cXG5Ib3VzZWhvbGRzIGluIHRyZWF0bWVudCBhcmVhcyBhcmUgMTIuNyBwZXJjZW50YWdlIHBvaW50cyBtb3JlIGxpa2VseSB0byByZXBvcnQgYmVpbmcgU3BhbmRhbmFcXG5ib3Jyb3dlcnPigJMxNy44JSB2ZXJzdXMgNS4xJSAoVGFibGUgMiBQYW5lbCBBLCBjb2x1bW4gMSkuIFRoZSBkaWZmZXJlbmNlIGluIHRoZSBwZXJjZW50YWdlXFxub2YgaG91c2Vob2xkcyBzYXlpbmcgdGhhdCB0aGV5IGJvcnJvdyBmcm9tIGFueSBNRkkgaXMgOC40IHBvaW50cyAoVGFibGUgMiBQYW5lbCBBLCBjb2x1bW5cXG4zKSwgc28gc29tZSBob3VzZWhvbGRzIHdobyBlbmRlZCB1cCBib3Jyb3dpbmcgZnJvbSBTcGFuZGFuYSBpbiB0cmVhdG1lbnQgYXJlYXMgd291bGQgaGF2ZVxcbmJvcnJvd2VkIGZyb20gYW5vdGhlciBNRkkgaW4gdGhlIGFic2VuY2Ugb2YgdGhlIGludGVydmVudGlvbi4gV2hpbGUgdGhlIGFic29sdXRlIGxldmVsIG9mIHRvdGFsXFxuTUZJIGJvcnJvd2luZyBpcyBub3QgdmVyeSBoaWdoLCBpdCBpcyBhYm91dCA1MCUgaGlnaGVyIGluIHRyZWF0bWVudCB0aGFuIGluIGNvbXBhcmlzb24gYXJlYXMuXFxuQ29sdW1ucyAxIGFuZCAzIHNob3cgdGhhdCB0cmVhdG1lbnQgaG91c2Vob2xkcyBhbHNvIHJlcG9ydCBzaWduaWZpY2FudGx5IG1vcmUgYm9ycm93aW5nIGZyb21cXG5NRklzIChhbmQgZnJvbSBTcGFuZGFuYSBpbiBwYXJ0aWN1bGFyKSB0aGFuIGNvbXBhcmlzb24gaG91c2Vob2xkcy4gQXZlcmFnZWQgb3ZlciBib3Jyb3dlcnNcXG5hbmQgbm9uLWJvcnJvd2VycywgdHJlYXRtZW50IGhvdXNlaG9sZHMgcmVwb3J0IFJzLiAxLDMzNCBtb3JlIGJvcnJvd2luZyBmcm9tIFNwYW5kYW5hIHRoYW5cXG5kbyBjb250cm9sIGhvdXNlaG9sZHMsIGFuZCBScy4gMSwyODYgbW9yZSBmcm9tIGFsbCBNRklzIChib3RoIHNpZ25pZmljYW50IGF0IHRoZSAxJSBsZXZlbCkuXFxuV2hpbGUgYm90aCB0aGUgYWJzb2x1dGUgdGFrZS11cCByYXRlIGFuZCB0aGUgaW1wbGljaXQg4oCcZmlyc3Qgc3RhZ2XigJ0gYXJlIHJlbGF0aXZlbHkgc21hbGwsIHRoaXNcXG5hcHBlYXJzIHRvIGJlIHNpbWlsYXIgdG8gd2hhdCB3YXMgZm91bmQgaW4gbW9zdCBvdGhlciBldmFsdWF0aW9ucyBvZiB0aGUgaW1wYWN0IG9mIGFjY2VzcyB0b1xcbm1pY3JvZmluYW5jZSwgZGVzcGl0ZSB0aGUgZGlmZmVyZW50IGNvbnRleHRzLiBJbiBydXJhbCBNb3JvY2NvLCBDcsOpcG9uIGV0IGFsLiAoMjAxMykgZmluZCB0aGF0XFxudGhlIHByb2JhYmlsaXR5IG9mIGhhdmluZyBhbnkgbG9hbiBmcm9tIHRoZSBNRkkgQWwgQW1hbmEgaW4gYXJlYXMgd2hpY2ggZ290IGFjY2VzcyB0byBpdCBpcyAxMFxcbnBlcmNlbnRhZ2UgcG9pbnRzLCB3aGVyZWFzIGl0IGlzIGVzc2VudGlhbGx5IHplcm8gaW4gY29udHJvbCwgYW5kIG1vcmVvdmVyLCBzaW5jZSB0aGVyZSBpcyBubyBvdGhlclxcbk1GSSwgdGhpcyByZXByZXNlbnRzIHRoZSB0b3RhbCBpbmNyZWFzZSBpbiBtaWNyb2ZpbmFuY2UgYm9ycm93aW5nLiBJbiBNZXhpY28sIEFuZ2VsdWNjaSwgS2FybGFuXFxuYW5kIFppbm1hbiAoMjAxMykgZmluZCBhbiBpbmNyZWFzZSBvZiAxMCBwZXJjZW50YWdlIHBvaW50cyBpbiB0aGUgcHJvYmFiaWxpdHkgb2YgYm9ycm93aW5nXFxuZnJvbSB0aGUgTUZJIENvbXBhcnRhbW9zIGluIGFyZWFzIHRoYXQgZ290IGFjY2VzcyB0byB0aGUgbGVuZGVyLCByZWxhdGl2ZSB0byBhIGJhc2Ugb2YgZml2ZVxcbnBlcmNlbnRhZ2UgcG9pbnRzIGluIHRoZSBjb250cm9sLiBJbiBFdGhpb3BpYSwgVGFyb3p6aSBldCBhbC4gKDIwMTMpIGZpbmQgYSBsYXJnZXIgaW1wYWN0IG9mXFxubWljcm9jcmVkaXQgaW50cm9kdWN0aW9uOiAzNiUuXFxuVGhlIGZhaXJseSBsb3cgdGFrZS11cCByYXRlIGluIHRoZXNlIGRpZmZlcmVudCBjb250ZXh0cyBpcyBpbiBpdHNlbGYgYSBzdHJpa2luZyByZXN1bHQsIGdpdmVuIHRoZVxcbmhpZ2ggbGV2ZWxzIG9mIGluZm9ybWFsIGJvcnJvd2luZyBpbiB0aGVzZSBjb21tdW5pdGllcyBhbmQgdGhlIHB1cnBvcnRlZCBiZW5lZml0cyBvZiBtaWNyb2NyZWRpdFxcbm92ZXIgdGhlc2UgYWx0ZXJuYXRpdmUgZm9ybXMgb2YgYm9ycm93aW5nLiBJbiBhbGwgY2FzZXMsIGV4Y2VwdCB3aGVuIHRoZSByYW5kb21pemF0aW9uIHdhc1xcbmFtb25nIHRob3NlIHdobyBoYWQgYWxyZWFkeSBleHByZXNzZWQgZXhwbGljaXQgaW50ZXJlc3QgaW4gbWljcm9jcmVkaXQsIG9ubHkgYSBtaW5vcml0eSBvZlxcbjE2XFxu4oCcbGlrZWx5IGJvcnJvd2Vyc+KAnSBlbmQgdXAgYm9ycm93aW5nLlxcblRhYmxlIDIgYWxzbyBkaXNwbGF5cyB0aGUgaW1wYWN0IG9mIG1pY3JvZmluYW5jZSBhY2Nlc3Mgb24gb3RoZXIgZm9ybXMgb2YgYm9ycm93aW5nLiBBXFxuc2l6YWJsZSBmcmFjdGlvbiBvZiB0aGUgY2xpZW50cyByZXBvcnQgcmVwYXlpbmcgYSBtb3JlIGV4cGVuc2l2ZSBkZWJ0IGFzIGEgcmVhc29uIHRvIGJvcnJvdyBmcm9tXFxuU3BhbmRhbmEsIGFuZCB3ZSBkbyBpbmRlZWQgc2VlIHNvbWUgYWN0aW9uIG9uIHRoaXMgbWFyZ2luLiBUaGUgc2hhcmUgb2YgaG91c2Vob2xkcyB3aG8gaGF2ZVxcbnNvbWUgaW5mb3JtYWwgYm9ycm93aW5n4oCTZGVmaW5lZCBhcyBib3Jyb3dpbmcgZnJvbSBmYW1pbHksIGZyaWVuZHMsIG1vbmV5bGVuZGVycyBhbmQgZ29vZHNcXG5wdXJjaGFzZWQgb24gY3JlZGl0IGV4dGVuZGVkIGJ5IHRoZSBzZWxsZXLigJNnb2VzIGRvd24gYnkgNS4yIHBlcmNlbnRhZ2UgcG9pbnRzIGluIHRyZWF0bWVudFxcbmFyZWFzIChjb2x1bW4gNSksIGJ1dCBiYW5rIGJvcnJvd2luZyBpcyB1bmFmZmVjdGVkIChjb2x1bW4gNCkuIFRoZSBwb2ludCBlc3RpbWF0ZSBvZiB0aGVcXG5hbW91bnQgYm9ycm93ZWQgZnJvbSBpbmZvcm1hbCBzb3VyY2VzIGlzIGFsc28gbmVnYXRpdmUsIHN1Z2dlc3Rpbmcgc3Vic3RpdHV0aW9uIG9mIGV4cGVuc2l2ZVxcbmJvcnJvd2luZyB3aXRoIGNoZWFwZXIgTUZJIGJvcnJvd2luZyAoYW4gZXhwbGljaXQgb2JqZWN0aXZlIG9mIFNwYW5kYW5hKSwgYW5kIHRoZSBwb2ludFxcbmVzdGltYXRlLCB0aG91Z2ggaW5zaWduaWZpY2FudCwgaXMgcXVpdGUgc2ltaWxhciBpbiBhYnNvbHV0ZSB2YWx1ZSB0byB0aGUgaW5jcmVhc2UgaW4gTUZJIGJvcnJvd2luZ1xcbihjb2x1bW4gNSkuIEhvd2V2ZXIsIGdpdmVuIHRoZSBoaWdoIGxldmVsIG9mIGluZm9ybWFsIGJvcnJvd2luZywgdGhpcyBjb3JyZXNwb25kcyB0byBhIGRlY2xpbmVcXG5vZiBvbmx5IDIuNiU6IFdoZW4gd2UgZXhhbWluZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGVuZGxpbmUgMSBpbmZvcm1hbCBib3Jyb3dpbmcsIGluIEZpZ3VyZSAxLFxcbmluZm9ybWFsIGJvcnJvd2luZyBpcyBzaWduaWZpY2FudGx5IGxvd2VyIGluIHRyZWF0bWVudCBhcmVhcyBmcm9tIHRoZSAzMHRoIHRvIDY1dGggcGVyY2VudGlsZXMuXFxuT3ZlcmFsbCwgdHJlYXRtZW50IGFmZmVjdHMgdGhlIGluZGV4IG9mIGJvcnJvd2luZyBvdXRjb21lcywgYW5kIHRoZSBwLXZhbHVlIGlzIHNtYWxsIGV2ZW4gd2hlblxcbmFjY291bnRpbmcgZm9yIG11bHRpcGxlIGh5cG90aGVzaXMgdGVzdGluZyBhY3Jvc3MgZmFtaWxpZXMgKGNvbHVtbiA5KS5cXG5BZnRlciB0aGUgZW5kIG9mIHRoZSBmaXJzdCBlbmRsaW5lLCBmb2xsb3dpbmcgb3VyIGluaXRpYWwgYWdyZWVtZW50IHdpdGggU3BhbmRhbmEsIFNwYW5kYW5hXFxuc3RhcnRlZCB0byBleHBhbmQgaW4gdGhlc2UgYXJlYXMuIE90aGVyIE1GSXMgYWxzbyBjb250aW51ZWQgdGhlaXIgZXhwYW5zaW9uLiBIb3dldmVyLCB0d29cXG55ZWFycyBsYXRlciBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2Ugc3RpbGwgcmVtYWluZWQgYmV0d2VlbiBTcGFuZGFuYSBzbHVtcyBhbmQgb3RoZXJzOiBUYWJsZSAyXFxuUGFuZWwgQiBzaG93cyB0aGF0IDE3JSBvZiB0aGUgaG91c2Vob2xkcyBpbiB0aGUgdHJlYXRtZW50IHNsdW1zIGJvcnJvd2VkIGZyb20gU3BhbmRhbmEsXFxuYWdhaW5zdCAxMSUgaW4gdGhlIGNvbnRyb2wgc2x1bXMuIE90aGVyIE1GSXMgY29udGludWVkIHRvIGV4cGFuZCBib3RoIGluIHRoZSBmb3JtZXIgdHJlYXRtZW50XFxuYW5kIGNvbnRyb2wgc2x1bXMsIGFuZCBNRkkgbGVuZGluZyBvdmVyYWxsIHdhcyBhbG1vc3QgdGhlIHNhbWUgaW4gdGhlIHRyZWF0bWVudCBhbmQgdGhlIGNvbnRyb2xcXG5ncm91cC4gQnkgdGhlIHNlY29uZCBlbmRsaW5lIHN1cnZleSwgMzMuMSUgb2YgaG91c2Vob2xkcyBoYWQgYm9ycm93ZWQgZnJvbSBhbiBNRkkgaW4gdGhlXFxuZm9ybWVyIGNvbnRyb2wgc2x1bXMsIGFuZCAzMy4zJSBpbiB0aGUgdHJlYXRtZW50IHNsdW1zLiBTaW5jZSBsZW5kaW5nIHN0YXJ0ZWQgbGF0ZXIgaW4gdGhlXFxuY29udHJvbCBncm91cCwgaG93ZXZlciwgaG91c2Vob2xkcyBpbiB0aGUgdHJlYXRtZW50IGdyb3VwIGhhZCBvbiBhdmVyYWdlIGJlZW4gYm9ycm93aW5nIGZvclxcbmxvbmdlciB0aGFuIHRob3NlIGluIHRoZSBjb250cm9sIGdyb3VwLCB3aGljaCBpcyByZWZsZWN0ZWQgaW4gdGhlIGZhY3QgdGhhdCB0aGV5IGhhZCBjb21wbGV0ZWRcXG5tb3JlIGxvYW4gY3ljbGVzLiBPbiBhdmVyYWdlLCB0aGVyZSB3YXMgYSBkaWZmZXJlbmNlIG9mIDAuMDg1IGxvYW4gY3ljbGVzIGJldHdlZW4gdGhlIHRyZWF0bWVudFxcbmFuZCB0aGUgY29udHJvbCBob3VzZWhvbGRzIGF0IGVuZGxpbmUgMiAoY29sdW1uIDgpLCB3aGljaCBpcyBhbG1vc3QgdW5jaGFuZ2VkIGZyb20gZW5kbGluZVxcbjEuMTMgVGhlIHByaW1hcnkgZGlmZmVyZW5jZSBiZXR3ZWVuIHRyZWF0bWVudCBhbmQgY29udHJvbCBncm91cCBhdCBlbmRsaW5lIDIgaXMgdGh1cyB0aGUgbGVuZ3RoXFxuMTNUaGlzIGRpZmZlcmVuY2UgaXMgbm8gbG9uZ2VyIHNpZ25pZmljYW50IGF0IEVMMiwgcG9zc2libHkgb3dpbmcgdG8gcmVjYWxsIGVycm9yIGFuZCB0byB0aGUgZmFjdCB0aGF0IHdlIG9ubHkgY29sbGVjdGVkIGluZm9ybWF0aW9uIG9uIHRoZSBtYXhpbXVtIG51bWJlciBvZiBjeWNsZXMgYm9ycm93ZWQgZnJvbSBhbnkgTUZJLCBzbyB0aGlzIGZpZ3VyZSBkb2VzIG5vdCBkaXN0aW5ndWlzaCxcXG5lLmcuLCBhIGhvdXNlaG9sZCB0aGF0IGJvcnJvd2VkIHRocmVlIGN5Y2xlcyBlYWNoIGZyb20gdHdvIGxlbmRlcnMgdmVyc3VzIHRocmVlIGN5Y2xlcyBmcm9tIG9uZSBsZW5kZXIuXFxuMTdcXG5vZiBhY2Nlc3MgdG8gbWljcm9maW5hbmNlLiBTaW5jZSBtaWNyb2ZpbmFuY2UgbG9hbnMgZ3JvdyB3aXRoIGVhY2ggY3ljbGUsIHRyZWF0bWVudCBob3VzZWhvbGRzXFxuYWxzbyBoYWQgbGFyZ2VyIGxvYW5zLiBBbW9uZyB0aG9zZSB3aG8gYm9ycm93LCB0aGVyZSB3YXMgYnkgZW5kbGluZSAyIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZVxcbm9mIGFib3V0IFJzLiAyLDMwMCAob3IgMTQlKSBpbiB0aGUgc2l6ZSBvZiB0aGUgbG9hbnMgKG5vdCByZXBvcnRlZCkuIFNpbmNlIGFib3V0IG9uZSB0aGlyZCBvZlxcbmhvdXNlaG9sZHMgYm9ycm93LCB0aGlzIHRyYW5zbGF0ZXMgaW50byBhbiAoaW5zaWduaWZpY2FudCkgZGlmZmVyZW5jZSBvZiBhYm91dCBScy4gODAwIGluIGF2ZXJhZ2VcXG5ib3Jyb3dpbmcgKGNvbHVtbiAzKS5cXG40LjIgTmV3IGJ1c2luZXNzZXMgYW5kIGJ1c2luZXNzIG91dGNvbWVzXFxuUGFuZWwgQSBpbiBUYWJsZSAzIHByZXNlbnRzIHRoZSByZXN1bHRzIGZyb20gdGhlIGZpcnN0IGVuZGxpbmUgb24gYnVzaW5lc3Mgb3V0Y29tZXMuIENvbHVtblxcbjggaW5kaWNhdGVzIHRoYXQgdGhlIHByb2JhYmlsaXR5IHRoYXQgYSBob3VzZWhvbGQgc3RhcnRzIGEgYnVzaW5lc3MgaXMgaW4gZmFjdCBub3Qgc2lnbmlmaWNhbnRseVxcbmRpZmZlcmVudCBpbiB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgYXJlYXMuIEluIGNvbXBhcmlzb24gYXJlYXMsIDQuNyUgb2YgaG91c2Vob2xkcyBvcGVuZWQgYXRcXG5sZWFzdCBvbmUgYnVzaW5lc3MgaW4gdGhlIHllYXIgcHJpb3IgdG8gdGhlIHN1cnZleSwgY29tcGFyZWQgdG8gNS42JSBpbiB0cmVhdGVkIGFyZWFzIChjb2x1bW5cXG44KS4gSG93ZXZlciwgdHJlYXRtZW50IGhvdXNlaG9sZHMgd2VyZSBzb21ld2hhdCBtb3JlIGxpa2VseSB0byBoYXZlIG9wZW5lZCBtb3JlIHRoYW4gb25lXFxuYnVzaW5lc3MgaW4gdGhlIHBhc3QgeWVhciwgYW5kIGNvbHVtbiAxMCBzaG93cyB0aGF0IG1vcmUgbmV3IGJ1c2luZXNzZXMgd2VyZSBjcmVhdGVkIGluXFxudHJlYXRtZW50IGFyZWFzIG92ZXJhbGw6IDYuOCBwZXIgMTAwIGhvdXNlaG9sZHMsIHZlcnN1cyA1LjMgcGVyIDEwMCBob3VzZWhvbGRzIGluIGNvbnRyb2wgYXJlYXMuXFxuVGhlIDkwJSBjb25maWRlbmNlIGludGVydmFsIG9uIG5ldyBidXNpbmVzcyBjcmVhdGlvbiByYW5nZXMgZnJvbSBhbiBhZGRpdGlvbmFsIDAuM3BwIHRvIDIuNnBwXFxuYWRkaXRpb25hbCBuZXcgYnVzaW5lc3Nlcy4gT3ZlcmFsbCB0cmVhdG1lbnQgaG91c2Vob2xkcyBhcmUgbm8gbW9yZSBsaWtlbHkgdG8gaGF2ZSBhIGJ1c2luZXNzXFxuYW5kIHRoZXkgZG9u4oCZdCBoYXZlIHNpZ25pZmljYW50bHkgbW9yZSBidXNpbmVzc2VzIChjb2x1bW5zIDYgYW5kIDcpLlxcbkNvbnNpc3RlbnQgd2l0aCB0aGUgZmFjdCB0aGF0IFNwYW5kYW5hIGxlbmRzIG9ubHkgdG8gd29tZW4sIGFuZCB3aXRoIHRoZSBzdGF0ZWQgZ29hbHNcXG5vZiBtaWNyb2ZpbmFuY2UgaW5zdGl0dXRpb25zLCB0aGUgbWFyZ2luYWwgYnVzaW5lc3NlcyB0ZW5kIHRvIGJlIGZlbWFsZS1vcGVyYXRlZDogY29sdW1uIDExXFxuc2hvd3MgdGhhdCB3aGVuIHdlIGxvb2sgYXQgY3JlYXRpb24gb2YgYnVzaW5lc3NlcyB0aGF0IGFyZSBvd25lZCBieSB3b21lbjE0IChjb2x1bW4gMTEpLCB3ZVxcbmZpbmQgdGhhdCBhbG1vc3QgYWxsIG9mIHRoZSBkaWZmZXJlbnRpYWwgYnVzaW5lc3MgY3JlYXRpb24gaW4gdHJlYXRtZW50IGFyZWFzIGlzIGluIGZlbWFsZS1vcGVyYXRlZFxcbmJ1c2luZXNzZXPigJN0aGVyZSBhcmUgMC4wMTQgcGVyY2VudGFnZSBwb2ludHMgbW9yZSBmZW1hbGUtb3duZWQgYnVzaW5lc3NlcyBpbiB0cmVhdG1lbnQgdGhhblxcbmluIGNvbnRyb2wgYXJlYXMsIGFuIGluY3JlYXNlIG9mIDU1JS4gSG91c2Vob2xkcyBpbiB0cmVhdGVkIGFyZWFzIHdlcmUgbm8gbW9yZSBsaWtlbHkgdG8gcmVwb3J0XFxuY2xvc2luZyBhIGJ1c2luZXNzLCBhbiBldmVudCByZXBvcnRlZCBieSAzLjklIG9mIGhvdXNlaG9sZHMgaW4gdHJlYXRtZW50IGFyZWFzIGFuZCAzLjclIG9mIHRoZVxcbmhvdXNlaG9sZHMgaW4gY29tcGFyaXNvbiBhcmVhcyAoY29sdW1uIDkpLjE1XFxuVHJlYXRtZW50IGhvdXNlaG9sZHMgaW52ZXN0IG1vcmUgaW4gZHVyYWJsZXMgZm9yIHRoZWlyIGJ1c2luZXNzZXMuIFNpbmNlIG9ubHkgYSB0aGlyZCBvZlxcbjE0QSBidXNpbmVzcyBpcyBjbGFzc2lmaWVkIGFzIG93bmVkIGJ5IGEgd29tYW4gaWYgdGhlIGZpcnN0IHBlcnNvbiBuYW1lZCBpbiByZXNwb25zZSB0byB0aGUgcXVlc3Rpb24g4oCcV2hvIGlzXFxudGhlIG93bmVyIG9mIHRoaXMgYnVzaW5lc3M/4oCdIGlzIGZlbWFsZS4gT25seSA3MiBvdXQgb2YgMjY3NCBidXNpbmVzc2VzIGhhdmUgbW9yZSB0aGFuIG9uZSBvd25lci4gQ2xhc3NpZnlpbmcgYVxcbmJ1c2luZXNzIGFzIG93bmVkIGJ5IGEgd29tYW4gaWYgYW55IHBlcnNvbiBuYW1lZCBhcyB0aGUgb3duZXIgaXMgZmVtYWxlIGRvZXMgbm90IGNoYW5nZSB0aGUgcmVzdWx0LlxcbjE1SXQgaXMgcG9zc2libGUgdGhhdCBob3VzZWhvbGRzIG5vdCByZXByZXNlbnRlZCBpbiBvdXIgc2FtcGxlLCBzdWNoIGFzIGhvdXNlaG9sZHMgdGhhdCBoYWQgbm90IGxpdmVkIGluIHRoZSBhcmVhXFxuZm9yIHRocmVlIHllYXJzLCBtYXkgaGF2ZSBiZWVuIGRpZmZlcmVudGlhbGx5IGxpa2VseSB0byBjbG9zZSBidXNpbmVzc2VzIGluIHRyZWF0ZWQgYXJlYXMuIEhvd2V2ZXIsIHRoZSByZWxhdGl2ZWx5XFxuc21hbGwgYW1vdW50IG9mIG5ldyBidXNpbmVzcyBjcmVhdGlvbiBtYWtlcyBnZW5lcmFsLWVxdWlsaWJyaXVtIGVmZmVjdHMgb24gZXhpc3RpbmcgYnVzaW5lc3NlcyByYXRoZXIgdW5saWtlbHkuXFxuMThcXG5ob3VzZWhvbGRzIGhhdmUgYSBidXNpbmVzcywgYW5kIG1vc3QgYnVzaW5lc3NlcyB1c2Ugbm8gYXNzZXRzIHdoYXRzb2V2ZXIsIHRoZSBwb2ludCBlc3RpbWF0ZSBpc1xcbnNtYWxsIGluIGFic29sdXRlIHZhbHVlIChScy4gMzkxIG92ZXIgdGhlIGxhc3QgeWVhciwgb3IgYSBiaXQgbGVzcyB0aGFuIGEgdGhpcmQgb2YgdGhlIGluY3JlYXNlIGluXFxuYXZlcmFnZSBNRkkgYm9ycm93aW5nIGluIHRyZWF0bWVudCBob3VzZWhvbGRzKSBidXQgdGhlIGluY3JlbWVudCBpbiB0cmVhdG1lbnQgaXMgbW9yZSB0aGFuXFxudGhlIHRvdGFsIHZhbHVlIG9mIGJ1c2luZXNzIGR1cmFibGVzIHB1cmNoYXNlZCBpbiB0aGUgbGFzdCB5ZWFyIGJ5IGNvbXBhcmlzb24gaG91c2Vob2xkcyAoUnMuXFxuMjgwKSwgYW5kIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuXFxuVGhlIHJlc3Qgb2YgdGhlIGNvbHVtbnMgaW4gdGhlIFBhbmVsIEEgb2YgVGFibGUgMyByZXBvcnQgb24gY3VycmVudCBidXNpbmVzcyBzdGF0dXMgYW5kIGxhc3RcXG5tb250aOKAmXMgcmV2ZW51ZXMsIGlucHV0cyBjb3N0cywgYW5kIHByb2ZpdHMgKGV4Y2x1c2l2ZSBvZiBpbnRlcmVzdCBwYXltZW50cykuIEluIHRoZXNlIHJlZ3Jlc3Npb25zLFxcbndlIGFzc2lnbiBhIHplcm8gdG8gdGhvc2UgaG91c2Vob2xkcyB0aGF0IGRvIG5vdCBoYXZlIGEgYnVzaW5lc3MsIHNvIHRoZXNlIHJlc3VsdHMgZ2l2ZSB1cyB0aGVcXG5vdmVyYWxsIGltcGFjdCBvZiBjcmVkaXQgb24gYnVzaW5lc3MgYWN0aXZpdGllcywgaW5jbHVkaW5nIGJvdGggdGhlIGV4dGVuc2l2ZSBhbmQgaW50ZW5zaXZlIG1hcmdpbnMuXFxuVHJlYXRtZW50IGhvdXNlaG9sZHMgaGF2ZSBtb3JlIGJ1c2luZXNzIGFzc2V0cyAoYWx0aG91Z2ggdGhlIHQtc3RhdGlzdGljIG9uIHRoZSBhc3NldCBzdG9jayBpc1xcbm9ubHkgMS41NikuIFRoZSB0cmVhdG1lbnQgZWZmZWN0cyBvbiByZXZlbnVlcyBhbmQgaW5wdXRzIGFyZSBib3RoIHBvc2l0aXZlIGJ1dCBpbnNpZ25pZmljYW50LlxcbkZpbmFsbHksIHRoZXJlIGlzIGFuIGluc2lnbmlmaWNhbnQgaW5jcmVhc2UgaW4gYnVzaW5lc3MgcHJvZml0cyAoY29sdW1uIDUpLiBTaW5jZSB0aGlzIGRhdGFcXG5pbmNsdWRlcyB6ZXJvcyBmb3IgaG91c2Vob2xkcyB0aGF0IGRvIG5vdCBoYXZlIGEgYnVzaW5lc3MsIHRoaXMgYW5zd2VycyB0aGUgcXVlc3Rpb24gb2Ygd2hldGhlclxcbm1pY3JvY3JlZGl0LCBhcyBpdCBpcyBvZnRlbiBiZWxpZXZlZCwgaW5jcmVhc2VzIHBvb3IgaG91c2Vob2xkc+KAmSBpbmNvbWUgYnkgZXhwYW5kaW5nIHRoZWlyIGJ1c2luZXNzXFxub3Bwb3J0dW5pdGllcy4gVGhlIHBvaW50IGVzdGltYXRlLCBhdCBScy4gMzU0IHBlciBtb250aCwgY29ycmVzcG9uZHMgdG8gYSByb3VnaGx5IDUwJSBpbmNyZWFzZVxcbnJlbGF0aXZlIHRvIHRoZSBwcm9maXRzIHJlY2VpdmVkIGJ5IHRoZSBhdmVyYWdlIGNvbXBhcmlzb24gaG91c2Vob2xkLiBUaGlzIGlzIHRodXMgbGFyZ2UgaW5cXG5wcm9wb3J0aW9uIHRvIHByb2ZpdHMsIGJ1dCBpdCByZXByZXNlbnRzIG9ubHkgYSB2ZXJ5IHNtYWxsIGluY3JlYXNlIGluIGRpc3Bvc2FibGUgaW5jb21lIGZvciBhblxcbmF2ZXJhZ2UgaG91c2Vob2xk4oCTcmVjYWxsIHRoYXQgdGhlIGF2ZXJhZ2UgdG90YWwgY29uc3VtcHRpb24gb2YgdGhlc2UgaG91c2Vob2xkcyBpcyBhYm91dCBScy5cXG43LDAwMCBwZXIgbW9udGggYW5kIGFuIGluY3JlYXNlIG9mIFJzLiAzNTQgcGVyIG1vbnRoIGluIGJ1c2luZXNzIHJldmVudWVzIGlzIGNlcnRhaW5seSBub3RcXG5nb2luZyB0byBjaGFuZ2UgdGhlIGxpZmUgb2YgdGhlIGF2ZXJhZ2UgcGVyc29uIHdobyBnZXRzIGFjY2VzcyB0byBtaWNyb2NyZWRpdC5cXG5Mb29raW5nIGF0IGFsbCBidXNpbmVzc2VzIG91dGNvbWVzIHRha2VuIHRvZ2V0aGVyLCB3ZSBmaW5kIGEgMC4wMzcgc3RhbmRhcmQgZGV2aWF0aW9uIGluY3JlYXNlIGluIHRoZSBzdGFuZGFyZGl6ZWQgaW5kZXggb2YgYnVzaW5lc3Mgb3V0Y29tZXMsIHdoaWNoIGlzIHNpZ25pZmljYW50IHdpdGggY29udmVudGlvbmFsXFxuc3RhbmRhcmQgZXJyb3JzIGJ1dCBub3QgKHAtdmFsdWUgb2YgMC4xNykgb25jZSB0aGUgbXVsdGlwbGUgaHlwb3RoZXNpcyB0ZXN0aW5nIGFjcm9zcyBkaWZmZXJlbnRcXG5mYW1pbGllcyBvZiBvdXRjb21lcyBpcyB0YWtlbiBpbnRvIGFjY291bnQuMTZcXG5UaGlzIGlzIHRoZSBJVFQgZXN0aW1hdGUsIGFuZCBwYXJ0IG9mIHRoZSByZWFzb24gaXQgaXMgbG93IGlzIHRoYXQgZmV3IGhvdXNlaG9sZHMgdG9va1xcbmFkdmFudGFnZSBvZiBtaWNyb2NyZWRpdCBpbiB0aGUgdHJlYXRtZW50IGdyb3VwcyAoYW5kIHNvbWUgZGlkIGluIHRoZSBjb250cm9sIGFzIHdlbGwpLiBUaGVcXG5tYXJnaW5hbCBib3Jyb3dlciBpbiB0aGUgdHJlYXRtZW50IGdyb3VwIG1heSBhbHNvIGhhdmUgZmV3ZXIgb3Bwb3J0dW5pdGllcyB0aGFuIHNvbWVvbmVcXG53aG8gd2FzIGludGVyZXN0ZWQgZW5vdWdoIHRvIGJvcnJvdyBpbiB0aGUgY29udHJvbCBncm91cC4gVGhpcyBkb2VzIG5vdCBydWxlIG91dCB0aGF0IHRoZVxcbmJ1c2luZXNzZXMgb2Ygc29tZSBzcGVjaWZpYyBncm91cHMgY291bGQgaGF2ZSBiZW5lZml0ZWQgZnJvbSB0aGUgbG9hbi4gVG8gbG9vayBhdCB0aGlzIGluIG1vcmVcXG4xNkl0IGlzIHNpZ25pZmljYW50IGV2ZW4gd2l0aCB0aGlzIGNvcnJlY3Rpb24gd2hlbiB3ZSBjb250cm9sIGZvciBzdHJhdGEgZHVtbWllc1xcbjE5XFxuZGV0YWlsLCB3ZSBmb2N1cyBvbiBidXNpbmVzc2VzIHRoYXQgd2VyZSBhbHJlYWR5IGluIGV4aXN0ZW5jZSBiZWZvcmUgbWljcm9jcmVkaXQgc3RhcnRlZC4gV2UgZG9cXG50aGlzIGluIFRhYmxlIDNCLjE3IEZvciBidXNpbmVzc2VzIHRoYXQgZXhpc3RlZCBiZWZvcmUgU3BhbmRhbmEgZXhwYW5kZWQsIHdlIGZpbmQgYW4gZXhwYW5zaW9uXFxuaW4gYnVzaW5lc3NlcyAoc2FsZXMsIGlucHV0cyBhbmQgaW52ZXN0bWVudCksIGFuZCB0aGUgb3ZlcmFsbCBidXNpbmVzcyBpbmRleCBpcyBzaWduaWZpY2FudCBhbmRcXG5wb3NpdGl2ZSwgZXZlbiBhZnRlciBjb3JyZWN0aW5nIGZvciBtdWx0aXBsZSBpbmZlcmVuY2UgKDAuMDkgc3RhbmRhcmQgZGV2aWF0aW9uLCB3aXRoIGEgcCB2YWx1ZVxcbm9mIDAuMDU3IGFmdGVyIHRoZSBjb3JyZWN0aW9uKS4gV2UgZmluZCBhbiBhdmVyYWdlIGluY3JlYXNlIGluIHByb2ZpdHMgb2YgUnMuIDIsMjA2IGluIHRyZWF0bWVudFxcbmFyZWFzLCB3aGljaCBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGFuZCByZXByZXNlbnRzIG1vcmUgdGhhbiBkb3VibGluZywgcmVsYXRpdmUgdG8gdGhlIGNvbnRyb2xcXG5tZWFuIG9mIFJzLiAyLDAwMC4gVGhpcyBpbmNyZWFzZSBpcyBub3QgZHVlIHRvIGEgZmV3IG91dGxpZXJzOyBob3dldmVyLCBpdCBpcyB3b3J0aCBub3RoaW5nIGl0IGlzXFxuY29uY2VudHJhdGVkIGluIHRoZSB1cHBlciB0YWlsIChxdWFudGlsZXMgOTUgYW5kIGFib3ZlKSwgYXMgc2hvd24gaW4gRmlndXJlIDIuIEF0IGV2ZXJ5IG90aGVyXFxucXVhbnRpbGUsIHRoZXJlIGlzIHZlcnkgbGl0dGxlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgcHJvZml0cyBvZiBleGlzdGluZyBidXNpbmVzc2VzIGluIHRyZWF0bWVudFxcbmFuZCBjb250cm9sIGFyZWFzLiBUaGVyZSBhcmUgNzUgYnVzaW5lc3NlcyBhYm92ZSB0aGUgOTV0aCBwZXJjZW50aWxlcywgc28gaXQgaXMgbm90IGEgaGFuZGZ1bCxcXG5idXQgdGhlIDk1dGggcGVyY2VudGlsZSBvZiBtb250aGx5IHByb2ZpdCBvZiBleGlzdGluZyBidXNpbmVzc2VzIGlzIFJzLiAxNCw2MDAgKG9yICQxNTkwIGF0IFBQUCksXFxud2hpY2ggbWFrZXMgdGhlbSBxdWl0ZSBsYXJnZSBhbmQgcHJvZml0YWJsZSBidXNpbmVzc2VzIGluIHRoaXMgc2V0dGluZy4gVGhlIHZhc3QgbWFqb3JpdHkgb2ZcXG50aGUgc21hbGwgYnVzaW5lc3NlcyBtYWtlIHZlcnkgbGl0dGxlIHByb2ZpdCB0byBzdGFydCB3aXRoLCBhbmQgbWljcm9jcmVkaXQgZG9lcyBub3RoaW5nIHRvIGhlbHBcXG50aGVtLiBUaGUgZmluZGluZyB0aGF0IG1pY3JvY3JlZGl0IGlzIG1vc3QgZWZmZWN0aXZlIGluIGhlbHBpbmcgYWxyZWFkeS1wcm9maXRhYmxlIGJ1c2luZXNzZXMgaXNcXG5jb250cmFyeSBib3RoIHRvIG11Y2ggb2YgdGhlIHJoZXRvcmljIG9mIG1pY3JvY3JlZGl0IGFuZCB0aGUgdmlldyBvZiBtaWNyb2NyZWRpdCBza2VwdGljcy5cXG5GaW5hbGx5LCB3ZSBoYXZlIHNlZW4gdGhhdCB0aGUgdHJlYXRtZW50IGxlZCB0byBzb21lIG1vcmUgYnVzaW5lc3MgY3JlYXRpb24sIHBhcnRpY3VsYXJseVxcbmZlbWFsZS1vd25lZCBidXNpbmVzc2VzLiBJbiBGaWd1cmUgMywgYW5kIFRhYmxlcyAzQyBhbmQgQTQsIHdlIHNob3cgbW9yZSBkYXRhIG9uIHRoZSBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlc2UgbmV3IGJ1c2luZXNzZXMuIFRoZSBxdWFudGlsZSByZWdyZXNzaW9ucyBpbiBGaWd1cmUgMyAocHJvZml0cyBmb3IgYnVzaW5lc3Nlc1xcbnRoYXQgZGlkIG5vdCBleGlzdCBhdCBiYXNlbGluZSkgc2hvdyB0aGF0IGFsbCBidXNpbmVzc2VzIGJldHdlZW4gdGhlIDM1dGggYW5kIDY1dGggcGVyY2VudGlsZXNcXG5oYXZlIHNpZ25pZmljYW50bHkgbG93ZXIgcHJvZml0cyBpbiB0cmVhdG1lbnQgYXJlYXMuIFRhYmxlIDQsIGNvbHVtbiA1IHNob3dzIHRoYXQgdGhlIG1lYW4gcHJvZml0XFxuaXMgbm90IHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGFjcm9zcyB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgZHVlIHRvIHRoZSBub2lzeSBkYXRhLCBidXQgdGhlIG1lZGlhblxcbm5ldyBidXNpbmVzcyBpbiB0cmVhdG1lbnQgYXJlYXMgaGFzIFJzLiAxLDI1MCBsb3dlciBwcm9maXRzLCBzaWduaWZpY2FudCBhdCB0aGUgNSUgbGV2ZWwgKG5vdFxcbnJlcG9ydGVkIGluIHRhYmxlcywgYnV0IHNob3duIGluIHRoZSBmaWd1cmUpLiBUaGUgYXZlcmFnZSBuZXcgYnVzaW5lc3MgaXMgYWxzbyBzaWduaWZpY2FudGx5IGxlc3NcXG5saWtlbHkgdG8gaGF2ZSBlbXBsb3llZXMgaW4gdGhlIHRyZWF0bWVudCBhcmVhczogdGhlIG51bWJlciBvZiBlbXBsb3llZXMgcGVyIG5ldyBidXNpbmVzcyAwLjI5XFxudG8gb25seSAwLjExIChjb2x1bW4gNikuIEZvciBuZXcgYnVzaW5lc3NlcywgdGhlIGluZGV4IGFjcm9zcyBhbGwgb3V0Y29tZXMgaXMgbmVnYXRpdmUgKDAuMDgxXFxuc3RhbmRhcmQgZGV2aWF0aW9ucykgYW5kIHNpZ25pZmljYW50IHdpdGggY29udmVudGlvbmFsIGxldmVscyBidXQgbm90IGFmdGVyIGNvcnJlY3RpbmcgZm9yIG11bHRpcGxlXFxuaW5mZXJlbmNlIChwIHZhbHVlLCAwLjAyOCkuXFxuVGhlc2UgcmVzdWx0cyBjb3VsZCBpbiBwcmluY2lwbGUgYmUgYSBjb21iaW5hdGlvbiBvZiBhIHRyZWF0bWVudCBlZmZlY3QgYW5kIGEgc2VsZWN0aW9uIGVmZmVjdCxcXG4xN0luIFRhYmxlIDMsIHdlIHNob3cgdGhhdCBob3VzZWhvbGRzIGFyZSBubyBtb3JlIG9yIGxlc3MgbGlrZWx5IHRvIGNsb3NlIGEgYnVzaW5lc3MgaW4gdGhlIGxhc3QgeWVhciwgdGh1cyB0aGVyZVxcbmlzIG5vIHNhbXBsZSBzZWxlY3Rpb24gaW5kdWNlZCBieSBtaWNyb2ZpbmFuY2UuXFxuMjBcXG5idXQgc2luY2UgdGhlIGVmZmVjdCBvbiBleGlzdGluZyBidXNpbmVzc2VzIHN1Z2dlc3RzIGEgdHJlYXRtZW50IGVmZmVjdCB3aGljaCBpcyBjbG9zZSB0byB6ZXJvXFxuZm9yIG1vc3QgYnVzaW5lc3NlcyAoYW5kIHRoZSBwb2ludCBlc3RpbWF0ZSBpcyBwb3NpdGl2ZSksIHRoZSBlZmZlY3QgZm9yIG5ldyBidXNpbmVzc2VzIGlzIGxpa2VseVxcbmR1ZSB0byBzZWxlY3Rpb27igJN0aGUgbWFyZ2luYWwgYnVzaW5lc3MgdGhhdCBnZXRzIHN0YXJ0ZWQgaW4gdHJlYXRtZW50IGFyZWFzIGlzIGxlc3MgcHJvZml0YWJsZVxcbnRoYW4gdGhlIG1hcmdpbmFsIGJ1c2luZXNzIGluIHRoZSBjb250cm9sIGFyZWFzLiBUaGUgaHlwb3RoZXNpcyB0aGF0IHRoZSBtYXJnaW5hbCBidXNpbmVzc1xcbnRoYXQgZ2V0cyBzdGFydGVkIGlzIGRpZmZlcmVudCBpbiB0aGUgdHJlYXRtZW50IGdyb3VwIGdhaW5zIHNvbWUgYWRkaXRpb25hbCBzdXBwb3J0IGluIEFwcGVuZGl4XFxuVGFibGUgNCwgd2hpY2ggc2hvd3MgYSBjb21wYXJpc29uIG9mIHRoZSBpbmR1c3RyaWVzIG9mIG9sZCBidXNpbmVzc2VzIGFuZCBuZXcgYnVzaW5lc3NlcywgYWNyb3NzXFxudHJlYXRtZW50IGFuZCBjb21wYXJpc29uIGFyZWFzLjE4IEluZHVzdHJ5IGlzIGEgcHJveHkgZm9yIHRoZSBhdmVyYWdlIHNjYWxlIGFuZCBjYXBpdGFsIGludGVuc2l0eVxcbm9mIGEgYnVzaW5lc3MsIHdoaWNoIGlzIGxpa2VseSB0byBiZSBtZWFzdXJlZCB3aXRoIGxlc3MgZXJyb3IgdGhhbiBhY3R1YWwgc2NhbGUgb3IgYXNzZXQgdXNlLiBUaGVcXG5pbmR1c3RyeSBjb21wb3NpdGlvbiBvZiBuZXcgYnVzaW5lc3NlcyBkbyBkaWZmZXIuIEluIHBhcnRpY3VsYXIsIHRoZSBmcmFjdGlvbiBvZiBmb29kIGJ1c2luZXNzZXNcXG4odGVhL2NvZmZlZSBzdGFuZHMsIGZvb2QgdmVuZG9ycywga2lyYW5hL3NtYWxsIGdyb2Nlcnkgc3RvcmVzLCBhbmQgYWdyaWN1bHR1cmUpIGlzIDguNSBwZXJjZW50YWdlXFxucG9pbnRzIChhYm91dCA0NSUpIGhpZ2hlciBhbW9uZyBuZXcgYnVzaW5lc3NlcyBpbiB0cmVhdG1lbnQgYXJlYXMgdGhhbiBhbW9uZyBuZXcgYnVzaW5lc3Nlc1xcbmluIGNvbXBhcmlzb24gYXJlYXMsIGFuZCB0aGUgZnJhY3Rpb24gb2Ygcmlja3NoYXcvZHJpdmluZyBidXNpbmVzc2VzIGFtb25nIG5ldyBidXNpbmVzc2VzIGluXFxudHJlYXRtZW50IGFyZWFzIGlzIDUuNCAobW9yZSB0aGFuIDUwJSkgcGVyY2VudGFnZSBwb2ludHMgbG93ZXIuIEJvdGggdGhlc2UgZGlmZmVyZW5jZXMgYXJlXFxuc2lnbmlmaWNhbnQgYXQgdGhlIDEwJSBsZXZlbC4gRm9vZCBidXNpbmVzc2VzIGFyZSB0aGUgbGVhc3QgY2FwaXRhbC1pbnRlbnNpdmUgYnVzaW5lc3NlcyBpbiB0aGVzZVxcbmFyZWFzLCB3aXRoIGFzc2V0cyB3b3J0aCBhbiBhdmVyYWdlIG9mIGp1c3QgUnMuIDkzMCAobWFpbmx5IGRvc2EgdGF3YXMsIHBvdHMgYW5kIHBhbnMsIGV0Yy4pLlxcblJpY2tzaGF3L2RyaXZpbmcgYnVzaW5lc3Nlcywgd2hpY2ggcmVxdWlyZSByZW50aW5nIG9yIG93bmluZyBhIHZlaGljbGUsIGFyZSB0aGUgbW9zdCBjYXBpdGFsaW50ZW5zaXZlIGJ1c2luZXNzZXMsIHdpdGggYXNzZXRzIHdvcnRoIGFuIGF2ZXJhZ2Ugb2YgUnMuIDEyLDY5NyAodGhlIGJ1bGsgb2Ygd2hpY2ggaXMgdGhlIGNvc3RcXG5vZiB0aGUgdmVoaWNsZSkuXFxuTWljcm9jcmVkaXQgd291bGQgYmUgZXhwZWN0ZWQgdG8gbG93ZXIgdGhlIHByb2ZpdGFiaWxpdHkgdGhyZXNob2xkIHRvIHN0YXJ0IGEgYnVzaW5lc3MsIGlmXFxuaW50ZXJlc3QgcmF0ZXMgYXJlIGxvd2VyIHRoYW4gdGhvc2Ugb2Ygb3RoZXIgc291cmNlcyBvZiBsZW5kaW5nIGF2YWlsYWJsZSB0byB0aGUgaG91c2Vob2xkcy4gQW5vdGhlciBleHBsYW5hdGlvbiBmb3IgYm90aCByZXN1bHRzIGNvdWxkIGJlIHRoYXQsIGR1ZSB0byB0aGUgZmFjdCB0aGF0IFNwYW5kYW5hIGxlbmRzIHRvIHdvbWVuLFxcbnRoZSBtYXJnaW5hbCBidXNpbmVzc2VzIGFyZSBtb3JlIGxpa2VseSB0byBiZSBmZW1hbGUgb3duZWQsIGFuZCBhcmUgdGh1cyBzdGFydGVkIGluIHNlY3RvcnMgaW5cXG53aGljaCB3b21lbiBhcmUgYWN0aXZlLiBGdXJ0aGVybW9yZSwgYnVzaW5lc3NlcyBvcGVyYXRlZCBieSB3b21lbiBnZW5lcmFsbHkgdGVuZCB0byBiZSBsZXNzXFxucHJvZml0YWJsZSwgcGVyaGFwcyBiZWNhdXNlIG9mIHNvY2lhbCBjb25zdHJhaW50cyBvbiB3aGF0IHRoZXkgY2FuIGRvIGFuZCBob3cgbXVjaCBlZmZvcnQgdGhleVxcbmNhbiBkZXZvdGUgdG8gYW4gZW50ZXJwcmlzZS4xOVxcblBhbmVsIEIgb2YgVGFibGUgMyBzaG93cyB0aGUgcmVzdWx0cyBmb3IgdGhlIGJ1c2luZXNzIHBlcmZvcm1hbmNlIHZhcmlhYmxlcyBhdCB0aGUgdGltZSBvZlxcbnRoZSBzZWNvbmQgZW5kbGluZS4gQXMgcmVtYXJrZWQgYWxyZWFkeSwgYnkgdGhpcyB0aW1lIHRyZWF0bWVudCBhbmQgY29udHJvbCBob3VzZWhvbGRzIGFyZVxcbmVxdWFsbHkgbGlrZWx5IHRvIGhhdmUgYSBtaWNyb2NyZWRpdCBsb2FuLCBidXQgdGhlIGxvYW4gaW4gdHJlYXRtZW50IGFyZWFzIGlzIGJpZ2dlciBhbmQgYm9ycm93ZXJzXFxuMThSZXNwb25kZW50cyBjb3VsZCBjbGFzc2lmeSB0aGVpciBidXNpbmVzc2VzIGludG8gMjIgZGlmZmVyZW50IHR5cGVzLCB3aGljaCB3ZSBncm91cGVkIGludG8gdGhlIGZvbGxvd2luZzogZm9vZCxcXG5jbG90aGluZy9zZXdpbmcsIHJpY2tzaGF3L2RyaXZpbmcsIHJlcGFpci9jb25zdHJ1Y3Rpb24sIGNyYWZ0cyB2ZW5kb3IsIGFuZCDigJxvdGhlci7igJ1cXG4xOVRoaXMgaXMgdHJ1ZSBpbiB0aGlzIGRhdGEsIGFuZCBhbHNvIGZvdW5kIGZvciBleGFtcGxlIGluIFNyaSBMYW5rYSBieSBkZSBNZWwgZXQgYWwuICgyMDA5KS5cXG4yMVxcbmhhdmUgYmVlbiBib3Jyb3dpbmcgZm9yIGEgbG9uZ2VyIHRpbWUuIFRoZSByZXN1bHRzIGZvbGxvdyBhIGNsZWFyIHBhdHRlcm4sIGNvbnNpc3RlbnQgd2l0aCB0aGVcXG5pZGVhIHRoYXQgY29udHJvbCBob3VzZWhvbGRzIG5vdyBib3Jyb3cgYXQgdGhlIHNhbWUgcmF0ZS4gV2UgZmluZCBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluXFxuYnVzaW5lc3MgY3JlYXRpb24gaW4gdHJlYXRtZW50IGFuZCBjb250cm9sIGFyZWFzOiB0aGUgcG9pbnQgZXN0aW1hdGUgaXMgdmlydHVhbGx5IHplcm8gKHRoZSA5MCVcXG5jb25maWRlbmNlIGludGVydmFsIHJhbmdlcyBmcm9tIDJwcCBmZXdlciBuZXcgYnVzaW5lc3NlcywgdG8gMi41cHAgbW9yZSkuIFRoZSBuZXcgYnVzaW5lc3Nlc1xcbmFyZSBpbiB0aGUgc2FtZSBpbmR1c3RyaWVzIGluIHRyZWF0bWVudCBhbmQgY29udHJvbCBhcmVhcywgYW5kIHRoZSBuZWdhdGl2ZSBlZmZlY3RzIGZvciBuZXdcXG5idXNpbmVzc2VzIGF0IHRoZSBtZWRpYW4gaGF2ZSBkaXNhcHBlYXJlZCAocmVzdWx0cyBvbWl0dGVkKS4gRm9yIHRoZSBjb250ZW1wb3JhbmVvdXMgZmxvd1xcbmludmVzdG1lbnQgb3V0Y29tZXMgc3VjaCBhcyBuZXcgYnVzaW5lc3MgY3JlYXRpb24sIGJ1c2luZXNzIGFzc2V0cyBhY3F1aXJlZCBpbiB0aGUgcHJldmlvdXNcXG55ZWFyLCBldGMuIChjb2x1bW5zIDggdGhyb3VnaCAxMSkgdGhlIHBvaW50IGVzdGltYXRlIGlzIHZlcnkgY2xvc2UgdG8gemVybyAoaG93ZXZlciB0aGUgc3RhbmRhcmRcXG5lcnJvcnMgYXJlIGxhcmdlKS4gT24gdGhlIG90aGVyIGhhbmQsIGJ1c2luZXNzZXMgaW4gdHJlYXRtZW50IGFyZWFzIGhhdmUgc2lnbmlmaWNhbnRseSBsYXJnZXJcXG5hc3NldCBzdG9jayAoY29sdW1uIDEpLCB3aGljaCByZWZsZWN0cyB0aGUgY3VtdWxhdGl2ZSBlZmZlY3Qgb2YgdGhlIHBhc3QgeWVhcnMgZHVyaW5nIHdoaWNoIHRoZXlcXG5oYWQgYSBjaGFuY2UgdG8gYm9ycm93IGFuZCBleHBhbmQuIERlc3BpdGUgdGhpcywgdGhlaXIgcHJvZml0cyBhcmUgc3RpbGwgbm90IHNpZ25pZmljYW50bHkgbGFyZ2VyLFxcbnRob3VnaCB0aGUgcG9pbnQgZXN0aW1hdGUgaXMgYXJvdW5kIDYwJSBvZiB0aGUgc2FtcGxlIG1lYW4gKHdpdGggYSB0LXN0YXRpc3RpYyBvZiBhcm91bmQgMS41KS5cXG5BcyBzaG93biBpbiBGaWd1cmUgNCwgdGhlIHBvc2l0aXZlIGluY3JlYXNlIGlzIG9uY2UgYWdhaW4gY29uY2VudHJhdGVkIGluIHRoZSB0b3AgYW5kIGJvdHRvbVxcbnRhaWxzLCBhbHRob3VnaCBpdCBzdGFydHMgYmVpbmcgcG9zaXRpdmUgYSBsaXR0bGUgZWFybGllciwgYXQgdGhlIDg1dGggcGVyY2VudGlsZS5cXG5PdmVyYWxsLCBtaWNyb2ZpbmFuY2UgaXMgaW5kZWVkIGFzc29jaWF0ZWQgd2l0aCAoc29tZSkgYnVzaW5lc3MgY3JlYXRpb246IGluIHRoZSBmaXJzdCB5ZWFyLCBpdFxcbmRvZXMgbGVhZCB0byBhbiBpbmNyZWFzZSBpbiB0aGUgbnVtYmVyIG9mIG5ldyBidXNpbmVzc2VzIGNyZWF0ZWQsIHBhcnRpY3VsYXJseSBieSB3b21lbiAodGhvdWdoXFxubm90IGluIHRoZSBudW1iZXIgb2YgaG91c2Vob2xkcyB0aGF0IHN0YXJ0IGEgYnVzaW5lc3MpLiBIb3dldmVyLCB0aGVzZSBtYXJnaW5hbCBidXNpbmVzc2VzIGFyZVxcbmV2ZW4gc21hbGxlciBhbmQgbGVzcyBwcm9maXRhYmxlIHRoYW4gdGhlIGF2ZXJhZ2UgYnVzaW5lc3MgaW4gdGhlIGFyZWEgKHRoZSB2YXN0IG1ham9yaXR5IG9mXFxud2hpY2ggYXJlIGFscmVhZHkgc21hbGwgYW5kIHVucHJvZml0YWJsZSkuIEl0IGRvZXMgYWxzbyBsZWFkIHRvIGEgZ3JlYXRlciBpbnZlc3RtZW50IGluIGV4aXN0aW5nXFxuYnVzaW5lc3NlcywgYW5kIGFuIGltcHJvdmVtZW50IGluIHRoZSBwcm9maXRzIGZvciB0aGUgbW9zdCBwcm9maXRhYmxlIG9mIHRob3NlIGJ1c2luZXNzZXMuIEZvclxcbmV2ZXJ5b25lIGVsc2UsIGJ1c2luZXNzIHByb2ZpdHMgZG8gbm90IGluY3JlYXNlLCBhbmQgb24gYXZlcmFnZSBtaWNyb2ZpbmFuY2UgZG9lcyBub3QgaGVscCB0aGVcXG5idXNpbmVzc2VzIHRvIGdyb3cgaW4gYW55IHNpZ25pZmljYW50IHdheS4gRXZlbiBhZnRlciB0aHJlZSB5ZWFycywgdGhlcmUgaXMgbm8gaW5jcmVhc2UgaW4gdGhlXFxubnVtYmVyIG9mIGVtcGxveWVlcyBvZiBidXNpbmVzc2VzIHRoYXQgZXhpc3RlZCBiZWZvcmUgU3BhbmRhbmEgc3RhcnRlZCBpdHMgb3BlcmF0aW9uLlxcbjQuMyBMYWJvciBzdXBwbHlcXG5BY2Nlc3MgdG8gY3JlZGl0IGNhbiBsZWFkIHRvIGFuIGluY3JlYXNlIGluIGxhYm9yIHN1cHBseSB0byBmaW5hbmNlIGFuIGludmVzdG1lbnQgb3IgdGhlIHB1cmNoYXNlXFxub2YgZHVyYWJsZSBnb29kcyB3aGljaCB3ZXJlIG91dCBvZiByZWFjaCBiZWZvcmUgZHVlIHRvIHNhdmluZ3MgYW5kIGJvcnJvd2luZyBjb25zdHJhaW50cy4gVGhpc1xcbmlzIGFuIGFyZWEgd2hlcmUgZGlmZmVyZW50IGV2YWx1YXRpb25zIG9mIG1pY3JvY3JlZGl0IGhhdmUgdmVyeSBkaWZmZXJlbnQgcmVzdWx0cywgcmFuZ2luZyBmcm9tIGFcXG53b3JyeWluZyBpbmNyZWFzZSBpbiBsYWJvciBzdXBwbHkgZm9yIHRlZW5hZ2VycyBpbiBBdWdzYnVyZyBldCBhbC4gKDIwMTMpIHRvIHN0ZWVwIGRlY3JlYXNlcyBmb3JcXG5ldmVyeW9uZSBpbiBDcsOpcG9uIGV0IGFsLiAoMjAxMykuIFRhYmxlIDUgc2hvd3MgdGhlIGltcGFjdCBvZiB0aGUgcHJvZ3JhbSBvbiBsYWJvciBzdXBwbHkuIEluXFxuMjJcXG5lbmRsaW5lIDEsIHRoZSBob3VzZWhvbGQgaGVhZCBhbmQgc3BvdXNlIGluIHRyZWF0bWVudCBob3VzZWhvbGRzIGluY3JlYXNlIHRoZWlyIG92ZXJhbGwgbGFib3JcXG5zdXBwbHkgYnkgYW4gYXZlcmFnZSBvZiAzLjE4IGhvdXJzICg5MCUgQ0k6IDAuODQsIDUuNSkuIFRoZSBpbmNyZWFzZSBvY2N1cnMgZW50aXJlbHkgaW4gdGhlXFxuaG91c2Vob2xkc+KAmSBvd24gYnVzaW5lc3NlcywgYW5kIHRoZXJlIGlzIG5vIGluY3JlYXNlIGluIG51bWJlciBvZiBob3VycyB3b3JrZWQgZm9yIHdhZ2VzOiB0aG9zZVxcbmhvdXJzIG1heSBiZSBtdWNoIGxlc3MgZWxhc3RpYywgaWYgdGhlIGhvdXNlaG9sZHMgZG8gbm90IGZ1bGx5IGNob29zZSB0aGVtLiBIb3dldmVyLCB3ZSBkbyBub3RcXG5maW5kIHRoZSBpbmNyZWFzZSBpbiB0ZWVuYWdlcnPigJkgbGFib3Igc3VwcGx5IHRoYXQgaXMgc29tZXRpbWVzIGZlYXJlZCB0byBiZSBhIHBvdGVudGlhbCBkb3duc2lkZVxcbm9mIG1pY3JvZmluYW5jZSBhbmQgdGhhdCB3YXMgZm91bmQgaW4gdGhlIEJvc25pYSBzdHVkeSAoYXMgdGhlIGFkb2xlc2NlbnRzIGFyZSBkcmF3biBpbnRvIHRoZVxcbmJ1c2luZXNzIGJ5IHRoZWlyIHBhcmVudHMpOyBpbmRlZWQgdGVlbmFnZSBnaXJscyB3b3JrIGFib3V0IHR3byBob3VycyBsZXNzIHBlciB3ZWVrIGluIHRyZWF0bWVudFxcbnRoYW4gY29udHJvbCBhcmVhcywgYW5kIHRoaXMgZGlmZmVyZW5jZSBpcyBzaWduaWZpY2FudC4gR2l2ZW4gdGhhdCB0aGVyZSBpcyBhbiBpbmNyZWFzZSBhbW9uZyBhZHVsdHNcXG5hbmQgYSBkZWNyZWFzZSBhbW9uZyB0ZWVucywgdGhlIG92ZXJhbGwgaW5kZXggaXMsIG5vdCBzdXJwcmlzaW5nbHksIGNsb3NlIHRvIHplcm8gYW5kIGluc2lnbmlmaWNhbnQuXFxuQnkgZW5kbGluZSAyLCBhcyBjb250cm9sIGhvdXNlaG9sZHMgaGF2ZSBzdGFydGVkIGJvcnJvd2luZywgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0cmVhdG1lbnRcXG5hbmQgY29udHJvbCBkaXNhcHBlYXJzLlxcbjQuNCBDb25zdW1wdGlvblxcblRhYmxlIDYgZ2l2ZXMgaW50ZW50LXRvLXRyZWF0IGVzdGltYXRlcyBvZiB0aGUgZWZmZWN0IG9mIG1pY3JvZmluYW5jZSBvbiBob3VzZWhvbGQgc3BlbmRpbmcuXFxuQ29sdW1ucyAxIGFuZCAzIG9mIFBhbmVsIEEgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIHRvdGFsIGhvdXNlaG9sZFxcbmV4cGVuZGl0dXJlc+KAk2VpdGhlciB0b3RhbCBvciBub24tZHVyYWJsZeKAk3BlciBhZHVsdCBlcXVpdmFsZW50LCBiZXR3ZWVuIHRyZWF0bWVudCBhbmQgY29tcGFyaXNvbiBob3VzZWhvbGRzLiBUaGUgcG9pbnQgZXN0aW1hdGUgaXMgZXNzZW50aWFsbHkgemVybyBpbiBib3RoIGNhc2VzIGFuZCB3ZSBjYW4gcmVqZWN0IGF0IHRoZSA1JVxcbmxldmVsIHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGVyZSB3YXMgYSBScy4gODUgcGVyIG1vbnRoIGluY3JlYXNlIGluIHRvdGFsIGNvbnN1bXB0aW9uIHBlclxcbmFkdWx0IGVxdWl2YWxlbnQgYW5kIFJzLiA1NiBpbiBub24tZHVyYWJsZSBjb25zdW1wdGlvbiAoYWJvdXQgNiUgb2YgdGhlIGF2ZXJhZ2UgaW4gY29udHJvbCBmb3JcXG5jb25zdW1wdGlvbiwgYW5kIDQlIGZvciBub24tZHVyYWJsZSBjb25zdW1wdGlvbikgaW5jcmVhc2UuMjAgSGVuY2UsIGVuaGFuY2VkIG1pY3JvY3JlZGl0XFxuYWNjZXNzIGRvZXMgbm90IGFwcGVhciB0byBiZSBhc3NvY2lhdGVkIHdpdGggYW55IG1lYW5pbmdmdWwgaW5jcmVhc2UgaW4gY29uc3VtcHRpb24gYWZ0ZXIgMTVcXG50byAxOCBtb250aHMuIE9mIGNvdXJzZSwgdGhpcyBtYXkgcGFydGx5IGJlIGR1ZSB0byB0aGUgZmFjdCB0aGF0IHJlbGF0aXZlbHkgZmV3IHBlb3BsZSBib3Jyb3csXFxuYW5kIHRoYXQgc29tZSBpbiB0aGUgY29udHJvbCBncm91cCBib3Jyb3cgZnJvbSBhbm90aGVyIE1GSS4yMVxcbldoaWxlIHRoZXJlIGFyZSBubyBzaWduaWZpY2FudCBpbXBhY3RzIG9uIGF2ZXJhZ2UgY29uc3VtcHRpb24gYW5kIG5vbi1kdXJhYmxlIGNvbnN1bXB0aW9uLFxcbnRoZXJlIGFyZSBzaGlmdHMgaW4gdGhlIGNvbXBvc2l0aW9uIG9mIGV4cGVuZGl0dXJlOiBjb2x1bW4gMiBzaG93cyB0aGF0IGhvdXNlaG9sZHMgaW4gdHJlYXRtZW50XFxuYXJlYXMgc3BlbnQgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IFJzLiAxNy4wOCBtb3JlIHBlciBjYXBpdGEgcGVyIG1vbnRoMjIsIG9yIFJzLiAyMDUgcGVyXFxuMjBUaGUgOTAlIENJcyBhcmUgKC01MSwgNzEpIGZvciB0b3RhbCBjb25zdW1wdGlvbiBhbmQgKC01OSwgNDYpIGZvciBub24tZHVyYWJsZSBjb25zdW1wdGlvbi5cXG4yMUZvciB0b3RhbCBjb25zdW1wdGlvbiwgdGhlIGltcGxpZWQgdHJlYXRtZW50IG9uIHRoZSB0cmVhdGVkIChUT1QpIG9yIElWIGVzdGltYXRlIGlzIGEgUnMuIDExOSAoMTAvLjA4NCksXFxub3IgNSUsIGluY3JlYXNlLCBhbmQgZm9yIG5vbi1kdXJhYmxlIGNvbnN1bXB0aW9uIGl0IGlzIGEgUnMuIDc1ICg0JSkgZGVjcmVhc2UuIEhvd2V2ZXIsIHRoZSA5MCUgY29uZmlkZW5jZVxcbmludGVydmFsIG9uIHRoZSBUT1QgZXN0aW1hdGUgaXMgd2lkZSwgcmFuZ2luZyBmcm9tIGFuIGluY3JlYXNlIG9mIFJzIDg0MCAob3IgNjAlKSB0byBhIGRlY3JlYXNlIG9mIFJzLiA2MDAgKG9yXFxuNDMlKS4gVGhlIHdpZHRoIG9mIHRoZSBUT1QgY29uZmlkZW5jZSBpbnRlcnZhbHMgc3RlbXMsIG9mIGNvdXJzZSwgZnJvbSB0aGUgbG93IGZpcnN0IHN0YWdlLlxcbjIyVGhlIDkwJSBDSSBpcyAoMSwgMzMpLlxcbjIzXFxuY2FwaXRhIG92ZXIgdGhlIGxhc3QgeWVhciwgb24gZHVyYWJsZXMgdGhhbiBkaWQgaG91c2Vob2xkcyBpbiBjb21wYXJpc29uIGFyZWFzLiBOb3RlIHRoYXQgdGhpcyBpc1xcbnByb2JhYmx5IGFuIHVuZGVyZXN0aW1hdGUgb2YgdGhlIHRvdGFsIGVmZmVjdCBvZiBsb2FucyBvbiBkdXJhYmxlIHB1cmNoYXNlcywgc2luY2Ugb3VyIG1lYXN1cmVcXG53b3VsZCBtaXNzIGFueW9uZSB3aG8gYm9ycm93ZWQgbW9yZSB0aGFuIGEgeWVhciBiZWZvcmUgdGhlIHN1cnZleSAodGhlIHN1cnZleSB3YXMgMTUgdG8gMThcXG5tb250aHMgYWZ0ZXIgdGhlIGNlbnRlcnMgb3BlbmVkKSBhbmQgaW1tZWRpYXRlbHkgYm91Z2h0IGEgZHVyYWJsZSB3aXRoIHRoZSBsb2FuLiBUaGUgbW9zdFxcbmNvbW1vbmx5IHB1cmNoYXNlZCBkdXJhYmxlcyBpbmNsdWRlIGdvbGQgYW5kIHNpbHZlciwgbW90b3JjeWNsZXMsIHNhcmVlcyAocHVyY2hhc2VkIGluIGJ1bGssXFxucHJlc3VtYWJseSBtYWlubHkgZm9yIHdlZGRpbmdzIG9yIGFzIHN0b2NrIGZvciBhIGJ1c2luZXNzKSwgY29sb3IgVFZzLCByZWZyaWdlcmF0b3JzLCByaWNrc2hhd3MsXFxuY29tcHV0ZXJzIGFuZCBjZWxscGhvbmVzLlxcbkNvbHVtbnMgNyBhbmQgOCBzaG93IHRoYXQgd2hpbGUgdGhlcmUgd2FzIG5vIGRldGVjdGFibGUgY2hhbmdlIGluIG5vbi1kdXJhYmxlIHNwZW5kaW5nXFxub3RoZXJ3aXNlOyB0aGUgaW5jcmVhc2UgaW4gZHVyYWJsZSBzcGVuZGluZyBieSB0cmVhdG1lbnQgaG91c2Vob2xkcyB3YXMgZXNzZW50aWFsbHkgb2Zmc2V0IGJ5XFxucmVkdWNlZCBzcGVuZGluZyBvbiDigJx0ZW1wdGF0aW9uIGdvb2Rz4oCdIGFuZCBmZXN0aXZhbHMuIFRlbXB0YXRpb24gZ29vZHMgYXJlIGdvb2RzIHRoYXQgaG91c2Vob2xkcyBpbiBvdXIgYmFzZWxpbmUgc3VydmV5IHNhaWQgdGhhdCB0aGV5IHdvdWxkIGxpa2Ugc3BlbmQgbGVzcyBvbiAodGhpcyBpcyB0aHVzIHRoZSBzYW1lIGxpc3Qgb2ZcXG5nb29kcyBmb3IgYWxsIGhvdXNlaG9sZHMpLiBUaGV5IGluY2x1ZGUgaW4gdGhpcyBjYXNlIGFsY29ob2wsIHRvYmFjY28sIGJldGVsIGxlYXZlcywgZ2FtYmxpbmcsIGFuZFxcbmZvb2QgY29uc3VtZWQgb3V0c2lkZSB0aGUgaG9tZS4gU3BlbmRpbmcgb24gdGVtcHRhdGlvbiBnb29kcyBpcyByZWR1Y2VkIGJ5IGFib3V0IFJzLiA5IHBlclxcbmNhcGl0YSBwZXIgbW9udGggKGNvbHVtbiA3KS4gV2UgYWxzbyBzZWUgaW4gY29sdW1uIDggYSBsYXJnZSBmYWxsIGluIGZlc3RpdmFsIHNwZW5kaW5nIHBlciBjYXBpdGFcXG5pbiB0aGUgcHJldmlvdXMgeWVhciAoUnMuIDEyIG9yIDIwJSBvZiB0aGUgY29udHJvbCBsZXZlbCwgc2lnbmlmaWNhbnQgYXQgdGhlIDEwJSBsZXZlbCkuIFRvZ2V0aGVyLFxcbnRoZSBhdmVyYWdlIGRyb3AgaW4gY29uc3VtcHRpb24gaW4gdGVtcHRhdGlvbiBnb29kcyBhbmQgZmVzdGl2YWxzIGlzIFJzLiAyMSBwZXIgY2FwaXRhIHBlclxcbm1vbnRoLiBUaGUgZGVjcmVhc2UgaW4gZmVzdGl2YWwgZXhwZW5kaXR1cmVzIGRvZXMgbm90IGNvbWUgZnJvbSBsYXJnZSBjaGFuZ2VzIGluIGxhcmdlLCB2ZXJ5XFxuZXhwZW5zaXZlIGNlcmVtb25pZXMgc3VjaCBhcyB3ZWRkaW5ncyAod2Ugc2VlIHZlcnkgZmV3IG9mIHRoZW0gaW4gdGhlIGRhdGEpIGJ1dCByYXRoZXIgYXBwZWFyc1xcbnRvIGNvbWUgZnJvbSBkZWNsaW5lcyBhdCBhbGwgbGV2ZWxzIG9mIHRoZSBkaXN0cmlidXRpb24gb2Ygc3BlbmRpbmcgb24gZmVzdGl2YWxzLlxcblRoZSBhYnNvbHV0ZSBtYWduaXR1ZGUgb2YgdGhlc2UgY2hhbmdlcyBpcyByZWxhdGl2ZWx5IHNtYWxsOiBmb3IgaW5zdGFuY2UsIHRoZSBScy4gMTcgb2ZcXG5pbmNyZWFzZWQgZHVyYWJsZXMgc3BlbmRpbmcgcGVyIGNhcGl0YSBwZXIgbW9udGggYXQgZW5kbGluZSAxIGlzIGFwcHJveGltYXRlbHkgJDEuNzUgYXQgMjAwN1xcblBQUCBleGNoYW5nZSByYXRlcy4gSG93ZXZlciwgdGhpcyByZXByZXNlbnRzIGFuIGluY3JlYXNlIG9mIGFib3V0IDE3JSByZWxhdGl2ZSB0byB0b3RhbCBzcGVuZGluZ1xcbm9uIGR1cmFibGUgZ29vZHMgaW4gY29tcGFyaXNvbiBhcmVhcy4gRnVydGhlcm1vcmUsIHRoaXMgZmlndXJlIGF2ZXJhZ2VzIG92ZXIgbm9uLWJvcnJvd2VycyBhbmRcXG5ib3Jyb3dlcnMsIGFuZCB3b3VsZCBiZSBsYXJnZXIgaWYgaXQgd2FzIGF0dHJpYnV0ZWQgdG8gYm9ycm93ZXJzIGFsb25lLlxcblBhbmVsIEIgb2YgVGFibGUgNiByZXBvcnRzIG9uIHRoZSBpbXBhY3QgZWZmZWN0cyBhdCB0aGUgdGltZSBvZiB0aGUgc2Vjb25kIGVuZGxpbmUsIHdoZW5cXG5ib3RoIHRyZWF0bWVudCBhbmQgY29udHJvbCBob3VzZWhvbGRzIGhhdmUgYWNjZXNzIHRvIHRoZSBtaWNyb2ZpbmFuY2UgcHJvZ3JhbS4gVGhlIGVmZmVjdHMgb25cXG5ib3RoIHRvdGFsIHBlciBjYXBpdGEgc3BlbmRpbmcgYW5kIHRvdGFsIHBlciBjYXBpdGEgbm9uLWR1cmFibGUgc3BlbmRpbmcgKGNvbHVtbnMgMSBhbmQgMykgYXJlXFxubmVnYXRpdmUgd2l0aCB0LXN0YXRpc3RpY3MgYXJvdW5kIDEuIFNwZW5kaW5nIG9uIHRlbXB0YXRpb24gZ29vZHMgaXMgc3RpbGwgbG93ZXIgYnkgYWJvdXQgUnMuXFxuMTAgcGVyIG1vbnRoIChjb2x1bW4gNyksIHNpbWlsYXIgdG8gZW5kbGluZSAxLCB0aG91Z2ggdGhlIGVmZmVjdCBpcyBub3cgaW5zaWduaWZpY2FudC4gVGhlIGVmZmVjdFxcbm9uIGZlc3RpdmFscyBpcyBub3cgcG9zaXRpdmUgYnV0IGluc2lnbmlmaWNhbnQuIFRoZXJlIGlzIGFsc28gbm8gZGlmZmVyZW5jZSBvbiBhdmVyYWdlIGluIGR1cmFibGVcXG4yNFxcbmdvb2RzIHNwZW5kaW5nIGluIGVuZGxpbmUgMiAoY29sdW1uIDIpLiBHaXZlbiB0aGF0IHRoZSBtYWluIGRpZmZlcmVuY2UgYmV0d2VlbiB0cmVhdG1lbnQgYW5kXFxuY29udHJvbCBob3VzZWhvbGRzIGF0IGVuZGxpbmUgMiBpcyB0aGF0IHRyZWF0bWVudCBob3VzZWhvbGRzIGhhdmUgYmVlbiBib3Jyb3dpbmcgZm9yIGxvbmdlcixcXG50aGlzIHN1Z2dlc3RzIHRoYXQsIGluIHRoZSBzZWNvbmQgY3ljbGUsIGhvdXNlaG9sZHMgaW4gdGhlIHRyZWF0bWVudCBzZWVtIHRvIGp1c3QgcmVwZWF0IHRoZSBmaXJzdFxcbmN5Y2xlIHdpdGggYW5vdGhlciBkdXJhYmxlIChvZiByb3VnaGx5IHRoZSBzYW1lIHNpemUpLCB3aGlsZSBob3VzZWhvbGRzIGluIHRoZSBjb250cm9sIGdyb3VwXFxuYWxzbyBhY3F1aXJlIGEgZHVyYWJsZS5cXG40LjUgTWljcm9maW5hbmNlIGFzIHNvY2lhbCByZXZvbHV0aW9uOiBlZHVjYXRpb24sIGNoaWxkIGxhYm9yLCBhbmQgd29tZW7igJlzXFxuZW1wb3dlcm1lbnQ/XFxuVGhlIGV2aWRlbmNlIHNvIGZhciBzdWdnZXN0cyBhIGRpZmZlcmVudCBwaWN0dXJlIGZyb20gdGhlIHN0YW5kYXJkIGRlc2NyaXB0aW9uIG9mIHRoZSByb2xlIG9mXFxubWljcm9maW5hbmNlIGluIHRoZSBsaWZlIG9mIHRoZSBwb29yOiB0aGUgcGVudC11cCBkZW1hbmQgZm9yIGl0IGlzIG5vdCBvdmVyd2hlbG1pbmc7IG1hbnlcXG5ob3VzZWhvbGRzIHVzZSB0aGVpciBsb2FuIHRvIGFjcXVpcmUgYSBob3VzZWhvbGQgZHVyYWJsZSwgcmVkdWNpbmcgYXZvaWRhYmxlIGNvbnN1bXB0aW9uIHRvXFxuZmluYW5jZSBpdDsgc29tZSBpbnZlc3QgaW4gdGhlaXIgYnVzaW5lc3NlcywgYnV0IHRoaXMgZG9lcyBub3QgbGVhZCB0byBzaWduaWZpY2FudCBncm93dGggaW4gdGhlXFxucHJvZml0YWJpbGl0eSBvZiBtb3N0IGJ1c2luZXNzZXMuIEFub3RoZXIgc3RhcGxlIG9mIHRoZSBtaWNyb2ZpbmFuY2UgbGl0ZXJhdHVyZSBpcyB0aGF0IGJlY2F1c2VcXG50aGUgbG9hbnMgYXJlIGdpdmVuIHRvIHdvbWVuIGFuZCBnaXZlIHRoZW0gYSBjaGFuY2UgdG8gc3RhcnQgdGhlaXIgb3duIGJ1c2luZXNzZXMsIHRoaXMgd291bGRcXG5sZWFkIHRvIGEgbW9yZSBnZW5lcmFsIGVtcG93ZXJtZW50IG9mIHdvbWVuIGluIHRoZSBob3VzZWhvbGRzLCBhbmQgdGhpcyBlbXBvd2VybWVudCB3b3VsZFxcbmluIHR1cm4gdHJhbnNsYXRlIGluIGJldHRlciBvdXRjb21lcyBmb3IgZXZlcnlvbmUsIGluY2x1ZGluZyBlZHVjYXRpb24sIGhlYWx0aCwgZXRjLiAoZS5nLiBDR0FQLFxcbjIwMDkpLiBJbmRlZWQsIHdlIHNlZSBhIHNpZ25pZmljYW50IGluY3JlYXNlIGluIHRoZSBudW1iZXIgb2YgYnVzaW5lc3NlcyBtYW5hZ2VkIGJ5IHdvbWVuIGluXFxuZW5kbGluZSAxIChUYWJsZSA3LCBjb2x1bW4gOSkuMjMgVG8gZXhhbWluZSB3aGV0aGVyIHRoaXMgaW5jcmVhc2UgaW4gd29tZW7igJlzIGVudHJlcHJlbmV1cnNoaXBcXG50cmFuc2xhdGVzIGludG8gaW5jcmVhc2VkIGJhcmdhaW5pbmcgcG93ZXIgZm9yIHdvbWVuLCBUYWJsZSA3IGV4YW1pbmVzIHRoZSBlZmZlY3RzIG9mIGFjY2Vzc1xcbnRvIG1pY3JvZmluYW5jZSBvbiBtZWFzdXJlcyBvZiB3b21lbuKAmXMgZGVjaXNpb24tbWFraW5nIGFuZCBjaGlsZHJlbuKAmXMgZWR1Y2F0aW9uIGFuZCBsYWJvclxcbnN1cHBseS5cXG5BIGZpbmRpbmcgb2YgbWFueSBzdHVkaWVzIG9mIGhvdXNlaG9sZCBkZWNpc2lvbi1tYWtpbmcgaXMgdGhhdCBhbiBpbmNyZWFzZSBpbiB3b21lbuKAmXNcXG5iYXJnYWluaW5nIHBvd2VyIGxlYWRzIHRvIGFuIGluY3JlYXNlIGluIGludmVzdG1lbnRzIGluIGNoaWxkcmVu4oCZcyBodW1hbiBjYXBpdGFsIChzZWUgVGhvbWFzLFxcbjE5OTAgYW5kIER1ZmxvLCAyMDAzKS4gSG93ZXZlciwgd2UgZmluZCB0aGF0IHRoZXJlIGlzIG5vIGNoYW5nZSBpbiB0aGUgcHJvYmFiaWxpdHkgdGhhdCBjaGlsZHJlblxcbm9yIHRlZW5hZ2VycyBhcmUgZW5yb2xsZWQgaW4gc2Nob29sIChUYWJsZSA3LCBjb2x1bW5zIDEsIDIsIDUgYW5kIDYpLCBhbHRob3VnaCB3ZSBkbyBzZWUgYVxcbnJlZHVjdGlvbiBpbiB0ZWVuYWdlIGdpcmxz4oCZIGxhYm9yIHN1cHBseSAoVGFibGUgNSwgY29sdW1uIDUpLiBUaGVyZSBpcyBubyBkaWZmZXJlbmNlIGluIHByaXZhdGVcXG5zY2hvb2wgZmVlcywgb3IgaW4gcHJpdmF0ZSBzY2hvb2wgdmVyc3VzIHB1YmxpYyBzY2hvb2wgZW5yb2xsbWVudCAocmVzdWx0cyBub3QgcmVwb3J0ZWQgdG8gc2F2ZVxcbnNwYWNlKS4gVGhlcmUgaXMgYWxzbyBubyBkaWZmZXJlbmNlIGluIHRoZSBudW1iZXIgb2YgaG91cnMgd29ya2VkIGJ5IGdpcmxzIG9yIGJveXMgYWdlZCA1IHRvIDE1XFxuMjNUaGVyZSBpcyBubyBkaWZmZXJlbmNlIGluIHRoZSBudW1iZXIgb2Ygd29tZW4tcnVuIGJ1c2luZXNzZXMgYmV0d2VlbiB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgaW4gZW5kbGluZSAyLFxcbndoaWNoIGlzIHVuc3VycHJpc2luZyBzaW5jZSBhbGwgYXJlYXMgaGF2ZSBhY2Nlc3MgdG8gbWljcm9maW5hbmNlIGF0IHRoYXQgcG9pbnQuXFxuMjVcXG4oY29sdW1ucyAzIGFuZCA0KS5cXG5CZWNhdXNlIHRoZXJlIGFyZSBtYW55IHBvc3NpYmxlIHByb3hpZXMgZm9yIHdvbWVu4oCZcyBlbXBvd2VybWVudCwgYW5kIG1hbnkg4oCcc29jaWFs4oCdXFxub3V0Y29tZXMgd2UgdXNlIHRoZSBhcHByb2FjaCBvZiBLbGluZyBldCBhbC4gKDIwMDcpIHRvIHRlc3QgdGhlIG51bGwgaHlwb3RoZXNpcyBvZiBubyBlZmZlY3RcXG5vZiBtaWNyb2NyZWRpdCBvbiDigJxzb2NpYWwgb3V0Y29tZXPigJ0gYWdhaW5zdCB0aGUgYWx0ZXJuYXRpdmUgdGhhdCBtaWNyb2NyZWRpdCBpbXByb3ZlcyBzb2NpYWxcXG5vdXRjb21lcy4gV2UgY29uc3RydWN0IGFuIGVxdWFsbHkgd2VpZ2h0ZWQgYXZlcmFnZSBvZiB6LXNjb3JlcyBmb3IgdGhlIDE2IHNvY2lhbCBvdXRjb21lcztcXG50aGlzIG1ldGhvZCBnaXZlcyB1cyBtYXhpbWFsIHBvd2VyIHRvIGRldGVjdCBhbiBlZmZlY3Qgb24gc29jaWFsIG91dGNvbWVzLCBpZiBzdWNoIGFuIGVmZmVjdFxcbmlzIHByZXNlbnQuMjQgQ29sdW1uIDcgc2hvd3MgdGhhdCB0aGVyZSBpcyBubyBlZmZlY3Qgb24gdGhlIGluZGV4IG9mIHNvY2lhbCBvdXRjb21lcyAocG9pbnRcXG5lc3RpbWF0ZSAuMDA3IHN0YW5kYXJkIGRldmlhdGlvbnMpIGFuZCB3ZSBjYW4gcnVsZSBvdXQgYW4gaW5jcmVhc2Ugb2YgbW9yZSB0aGFuIG9uZSB0d2VudGlldGhcXG5vZiBhIHN0YW5kYXJkIGRldmlhdGlvbiB3aXRoIDk1JSBjb25maWRlbmNlLjI1XFxuVGhpcyBzdWdnZXN0cyB0aGF0IHRoZXJlIGlzIG5vIHByaW1hIGZhY2llIGV2aWRlbmNlIHRoYXQgbWljcm9jcmVkaXQgbGVhZHMgdG8gaW1wb3J0YW50XFxuY2hhbmdlcyBpbiBob3VzZWhvbGQgZGVjaXNpb24tbWFraW5nIG9yIGluIHNvY2lhbCBvdXRjb21lcy4gRnVydGhlcm1vcmUsIHRoaXMgYXBwZWFycyB0byBiZVxcbm5vdCBvbmx5IGJlY2F1c2Ugd2Ugb2JzZXJ2ZSB0aGlzIG9ubHkgaW4gdGhlIHNob3J0IHJ1bi4gTm90aGluZyBtYWpvciBjaGFuZ2VzIGJ5IGVuZGxpbmUgMjpcXG50aGUgZWZmZWN0IG9mIG1pY3JvZmluYW5jZSBhY2Nlc3Mgb24gdGhlIGluZGV4IG9mIHdvbWVuIGVtcG93ZXJtZW50IGlzIHN0aWxsIHZlcnkgc21hbGwgKGluZGVlZCxcXG5zbGlnaHRseSBuZWdhdGl2ZSkgYW5kIGluc2lnbmlmaWNhbnQsIGFuZCBhbnl0aGluZyBidXQgYSBzbWFsbCBlZmZlY3QgY2FuIHN0aWxsIGJlIHJ1bGVkIG91dC4gUmVjYWxsXFxudGhhdCB3ZSBhcmUgY29tcGFyaW5nIGhvdXNlaG9sZHMgd2hvLCBieSBFTDIsIGFyZSBlcXVhbGx5IGxpa2VseSB0byBib3Jyb3c6IHRoZSBtYWluIGRpZmZlcmVuY2VcXG5ieSBFTDIgaXMgdGhhdCBob3VzZWhvbGRzIGluIHRoZSB0cmVhdG1lbnQgZ3JvdXAgaGF2ZSBoYWQgZ3JlYXRlciBhY2Nlc3MgdG8gbWljcm9maW5hbmNlIGZvclxcbnRoZSBmaXJzdCAxOCBtb250aHM7IHRoaXMgbWF5IGxpbWl0IHBvd2VyIHRvIGRldGVjdCBkaWZmZXJlbmNlcyBpbiB0aGUgc29jaWFsIG91dGNvbWVzIGF0IHRoZVxcbmNvbW11bml0eSBsZXZlbC5cXG41IENvbmNsdXNpb25cXG5UaGlzIHN0dWR54oCTdGhlIGZpcnN0IGFuZCBsb25nZXN0IHJ1bm5pbmcgZXZhbHVhdGlvbiBvZiB0aGUgc3RhbmRhcmQgZ3JvdXAtbGVuZGluZyBsb2FuIHByb2R1Y3RcXG50aGF0IGhhcyBtYWRlIG1pY3JvZmluYW5jZSBrbm93biB3b3JsZHdpZGXigJN5aWVsZHMgYSBudW1iZXIgb2YgcmVzdWx0cyB0aGF0IG1heSBwcm9tcHQgYVxcbnJldGhpbmtpbmcgb2YgdGhlIHJvbGUgb2YgbWljcm9maW5hbmNlLlxcblRoZSBmaXJzdCByZXN1bHQgaXMgdGhhdCwgaW4gY29udHJhc3QgdG8gdGhlIGNsYWltcyBzb21ldGltZXMgbWFkZSBieSBNRklzIGFuZCBvdGhlcnNcXG4oaW5jbHVkaW5nIG91ciBwYXJ0bmVyKSwgZGVtYW5kIGZvciBtaWNyb2xvYW5zIGlzIGZhciBmcm9tIHVuaXZlcnNhbC4gQnkgdGhlIGVuZCBvZiBvdXIgdGhyZWUyNFRoZSAxNiBvdXRjb21lcyB3ZSB1c2UgYXJlOiBpbmRpY2F0b3JzIGZvciB3b21lbiBtYWtpbmcgZGVjaXNpb25zIG9uIGVhY2ggb2YgZm9vZCwgY2xvdGhpbmcsIGhlYWx0aCwgaG9tZVxcbnB1cmNoYXNlIGFuZCByZXBhaXIsIGVkdWNhdGlvbiwgZHVyYWJsZSBnb29kcywgZ29sZCBhbmQgc2lsdmVyLCBpbnZlc3RtZW50OyBsZXZlbHMgb2Ygc3BlbmRpbmcgb24gc2Nob29sIHR1aXRpb24sXFxuZmVlcywgYW5kIG90aGVyIGVkdWNhdGlvbiBleHBlbnNlczsgbWVkaWNhbCBleHBlbmRpdHVyZTsgdGVlbmFnZSBnaXJsc+KAmSBhbmQgdGVlbmFnZSBib3lz4oCZIHNjaG9vbCBlbnJvbGxtZW50OyBhbmRcXG5jb3VudHMgb2YgZmVtYWxlIGNoaWxkcmVuIHVuZGVyIG9uZSB5ZWFyIGFuZCBvbmUgdG8gdHdvIHllYXJzIG9sZC4gV2Ugc2VsZWN0ZWQgdGhlc2Ugb3V0Y29tZXMgYmVjYXVzZSB0aGV5XFxud291bGQgbGlrZWx5IGJlIGFmZmVjdGVkIGJ5IGNoYW5nZXMgaW4gd29tZW7igJlzIGJhcmdhaW5pbmcgcG93ZXIgd2l0aGluIHRoZSBob3VzZWhvbGQuXFxuMjVUaGUgOTUlIENJIGlzICgtLjA0LCAuMDUpLiBUaGUgdW5pdHMgYXJlIHN0YW5kYXJkIGRldmlhdGlvbnMuXFxuMjZcXG55ZWFyIHN0dWR5IHBlcmlvZCwgb25seSAzOCUgb2YgaG91c2Vob2xkcyBib3Jyb3cgZnJvbSBhbiBNRkkyNiwgYW5kIHRoaXMgaXMgYW1vbmcgaG91c2Vob2xkc1xcbnNlbGVjdGVkIGJhc2VkIG9uIHRoZWlyIHJlbGF0aXZlbHkgaGlnaCBwcm9wZW5zaXR5IHRvIHRha2UgdXAgbWljcm9jcmVkaXQuIFRoaXMgZG9lcyBub3QgYXBwZWFyXFxudG8gYmUgYW4gYW5vbWFseTogdHdvIG90aGVyIHJhbmRvbWl6ZWQgaW50ZXJ2ZW50aW9ucyB0aGF0IGhhdmUgYSBzaW1pbGFyIGRlc2lnbiAoaW4gTW9yb2Njb1xcbmFuZCBpbiBNZXhpY28pIGFsc28gZmluZCByZWxhdGl2ZWx5IGxvdyB0YWtlLXVwLCB3aGlsZSBhbm90aGVyIHN0dWR5IGluIHJ1cmFsIFNvdXRoIEluZGlhIHRoYXRcXG5mb2N1c2VzIHNwZWNpZmljYWxseSBvbiB0YWtlLXVwIG9mIG1pY3JvZmluYW5jZSBhbHNvIGZpbmRzIGl0IHRvIGJlIGxvdyAoQmFuZXJqZWUgZXQgYWwuIDIwMTMpLlxcblBlcmhhcHMgZGVzcGl0ZSBldmlkZW5jZSBvZiBoaWdoIG1hcmdpbmFsIHJhdGVzIG9mIHJldHVybiBhbW9uZyBtaWNyb2J1c2luZXNzZXMsIGUuZy4gZGUgTWVsIGV0XFxuYWwuICgyMDA4KSwgbW9zdCBob3VzZWhvbGRzIGVpdGhlciBkbyBub3QgaGF2ZSBhIHByb2plY3Qgd2l0aCBhIHJhdGUgb2YgcmV0dXJuIG9mIGF0IGxlYXN0IDI0JSwgdGhlXFxuQVBSIG9uIGEgU3BhbmRhbmEgbG9hbiwgb3Igc2ltcGx5IHByZWZlciB0byBib3Jyb3cgZnJvbSBmcmllbmRzLCByZWxhdGl2ZXMsIG9yIG1vbmV5bGVuZGVyc1xcbmR1ZSB0byB0aGUgZ3JlYXRlciBmbGV4aWJpbGl0eSB0aG9zZSBzb3VyY2VzIHByb3ZpZGUsIGRlc3BpdGUgY29zdHMgc3VjaCBhcyBoaWdoZXIgaW50ZXJlc3QgKGZyb21cXG5tb25leWxlbmRlcnMpIG9yIGVtYmFycmFzc21lbnQgKHdoZW4gYm9ycm93aW5nIGZyb20gZnJpZW5kcyBvciByZWxhdGl2ZXMpIChDb2xsaW5zIGV0LiBhbFxcbjIwMDkpLlxcbkZvciB0aG9zZSB3aG8gY2hvb3NlIHRvIGJvcnJvdywgd2hpbGUgbWljcm9jcmVkaXQg4oCcc3VjY2VlZHPigJ0gaW4gbGVhZGluZyBzb21lIG9mIHRoZW0gdG9cXG5leHBhbmQgdGhlaXIgYnVzaW5lc3NlcyAob3IgY2hvb3NlIHRvIHN0YXJ0IGEgZmVtYWxlLW93bmVkIGJ1c2luZXNzKSwgaXQgZG9lcyBub3QgYXBwZWFyIHRvIGZ1ZWxcXG5hbiBlc2NhcGUgZnJvbSBwb3ZlcnR5IGJhc2VkIG9uIHRob3NlIHNtYWxsIGJ1c2luZXNzZXMuIE1vbnRobHkgY29uc3VtcHRpb24sIGEgZ29vZCBpbmRpY2F0b3JcXG5vZiBvdmVyYWxsIHdlbGZhcmUsIGRvZXMgbm90IGluY3JlYXNlIGZvciB0aG9zZSB3aG8gaGFkIGVhcmx5IGFjY2VzcyB0byBtaWNyb2ZpbmFuY2UsIG5laXRoZXIgaW5cXG50aGUgc2hvcnQgcnVuICh3aGVuIHdlIG1heSBoYXZlIGZvcmVzZWVuIHRoYXQgaXQgd291bGQgbm90IGluY3JlYXNlLCBvciBwZXJoYXBzIGV2ZW4gZXhwZWN0ZWRcXG5pdCB0byBkZWNyZWFzZSwgYXMgYm9ycm93ZXJzIGZpbmFuY2UgdGhlIGFjcXVpc2l0aW9uIG9mIGhvdXNlaG9sZCBvciBidXNpbmVzcyBkdXJhYmxlIGdvb2RzKSwgbm9yXFxuaW4gdGhlIGxvbmdlciBydW4sIGFmdGVyIHRoaXMgY3JvcCBvZiBob3VzZWhvbGRzIGhhdmUgYWNjZXNzIHRvIG1pY3JvY3JlZGl0IGZvciBhIHdoaWxlLCBhbmQgdGhvc2VcXG5pbiB0aGUgZm9ybWVyIGNvbnRyb2wgZ3JvdXAgc2hvdWxkIGJlIHRoZSBvbmVzIHRpZ2h0ZW5pbmcgdGhlaXIgYmVsdHMuIEJ1c2luZXNzIHByb2ZpdCBkb2VzIG5vdFxcbmluY3JlYXNlIGZvciB0aGUgdmFzdCBtYWpvcml0eSBvZiBidXNpbmVzc2VzLCBhbHRob3VnaCB0aGVyZSBhcmUgc2lnbmlmaWNhbnQgaW5jcmVhc2VzIGluIHRoZSB1cHBlclxcbnRhaWwgb2YgcHJvZml0YWJpbGl0eS4gVGhpcyBzdHVkeSB0b29rIHBsYWNlIGluIGEgZHluYW1pYyB1cmJhbiBlbnZpcm9ubWVudCwgaW4gYSBjb250ZXh0IG9mIHZlcnlcXG5oaWdoIGdyb3d0aC4gTWljcm9jcmVkaXQgc2VlbXMgdG8gaGF2ZSBwbGF5ZWQgdmVyeSBsaXR0bGUgcGFydCBpbiBpdCBidXQgbWF5IGhhdmUgaGFkIGRpZmZlcmVudFxcbmltcGFjdHMgaW4gb3RoZXIgc2V0dGluZ3MuXFxuRnVydGhlcm1vcmUsIGluIHRoZSBIeWRlcmFiYWRpIGNvbnRleHQsIHdlIGZpbmQgdGhhdCBhY2Nlc3MgdG8gbWljcm9jcmVkaXQgYXBwZWFycyB0byBoYXZlXFxubm8gZGlzY2VybmlibGUgZWZmZWN0IG9uIGVkdWNhdGlvbiwgaGVhbHRoLCBvciB3b21lbuKAmXMgZW1wb3dlcm1lbnQgaW4gdGhlIHNob3J0IHJ1bi4gSW4gdGhlXFxubG9uZ2VyIHJ1biAod2hlbiBib3Jyb3dpbmcgcmF0ZXMgYXJlIHRoZSBzYW1lLCBidXQgaG91c2Vob2xkcyBpbiB0aGUgdHJlYXRtZW50IGdyb3VwcyBoYXZlIG9uXFxuYXZlcmFnZSBib3Jyb3dlZCBmb3IgbG9uZ2VyKSwgdGhlcmUgaXMgc3RpbGwgbm8gaW1wYWN0IG9uIHdvbWVu4oCZcyBlbXBvd2VybWVudCBvciBvdGhlciBzb2NpYWxcXG5vdXRjb21lcy4gVGhlIHJlc3VsdHMgZGlmZmVyIGZyb20gc3R1ZHkgdG8gc3R1ZHkgb24gdGhlc2Ugb3V0Y29tZXMsIGJ1dCBhcyBhIHdob2xlIHRoZXkgZG9u4oCZdFxcbnBhaW50IGEgcGljdHVyZSBvZiBkcmFtYXRpYyBjaGFuZ2VzIGluIGJhc2ljIGRldmVsb3BtZW50IG91dGNvbWVzIGZvciBwb29yIGZhbWlsaWVzLlxcbjI2VGhlIHRha2UtdXAgcmF0ZSBpcyA0MiUgaW4gdHJlYXRtZW50IGFyZWFzIGFuZCAzMyUgcGVyY2VudCBpbiBjb250cm9sIGFyZWFzLlxcbjI3XFxuTWljcm9jcmVkaXQgdGhlcmVmb3JlIG1heSBub3QgYmUgdGhlIOKAnG1pcmFjbGXigJ0gdGhhdCBpdCBpcyBzb21ldGltZXMgY2xhaW1lZCB0byBiZSwgYWx0aG91Z2hcXG5pdCBkb2VzIGFsbG93IHNvbWUgaG91c2Vob2xkcyB0byBpbnZlc3QgaW4gdGhlaXIgc21hbGwgYnVzaW5lc3Nlcy4gT25lIHJlYXNvbiBtYXkgYmUgdGhhdCB0aGVcXG5hdmVyYWdlIGJ1c2luZXNzIHJ1biBieSB0aGlzIHRhcmdldCBncm91cCBpcyB0aW55IChhbG1vc3Qgbm9uZSBvZiB0aGVtIGhhdmUgYW4gZW1wbG95ZWUpLCBub3RcXG5wYXJ0aWN1bGFybHkgcHJvZml0YWJsZSwgYW5kIGRpZmZpY3VsdCB0byBleHBhbmQsIGV2ZW4gaW4gYSBoaWdoLWdyb3d0aCBjb250ZXh0LCBnaXZlbiB0aGUgc2tpbGxcXG5zZXRzIG9mIHRoZSBlbnRyZXByZW5ldXJzIGFuZCB0aGVpciBsaWZlIHNpdHVhdGlvbnMuIEFuZCB0aGUgbWFyZ2luYWwgYnVzaW5lc3NlcyB0aGF0IGdldCBjcmVhdGVkXFxudGhhbmtzIHRvIG1pY3JvY3JlZGl0IGFyZSBwcm9iYWJseSBldmVuIGxlc3MgcHJvZml0YWJsZSBhbmQgZHluYW1pYzogd2UgZmluZCB0aGF0IHRoZSBhdmVyYWdlXFxubmV3IGJ1c2luZXNzIGluIGEgbWljcm9jcmVkaXQgdHJlYXRtZW50IGFyZWEgaXMgbGVzcyBsaWtlbHkgdG8gaGF2ZSBhbiBlbXBsb3llZSB0aGFuIHRoZSBuZXdcXG5idXNpbmVzcyBpbiB0aGUgY29udHJvbCBhcmVhcywgYW5kIHRoZSBtZWRpYW4gbmV3IGJ1c2luZXNzIGlzIGV2ZW4gbGVzcyBwcm9maXRhYmxlIGluIHRyZWF0bWVudFxcbnZlcnN1cyBjb250cm9sIGFyZWFzLlxcbk5ldmVydGhlbGVzcywgbWljcm9jcmVkaXQgZG9lcyBhZmZlY3QgdGhlIHN0cnVjdHVyZSBvZiBob3VzZWhvbGQgY29uc3VtcHRpb24uIFdlIHNlZSBob3VzZWhvbGRzIGludmVzdCBpbiBob21lIGR1cmFibGUgZ29vZHMgYW5kIHJlc3RyaWN0IHRoZWlyIGNvbnN1bXB0aW9uIG9mIHRlbXB0YXRpb24gZ29vZHMgYW5kXFxuZXhwZW5kaXR1cmVzIG9uIGZlc3RpdmFscyBhbmQgcGFydGllcy4gVGhleSBjb250aW51ZSB0byBkbyBzbyBzZXZlcmFsIHllYXJzIGxhdGVyLCBhbmQgdGhpcyBkZWNyZWFzZSBpcyBub3QgZHVlIHRvIGEgZmV3IHBhcnRpY3VsYXJseSB2aXJ0dW91cyBob3VzZWhvbGRzLCBidXQgc2VlbXMgdG8gYmUgc3ByZWFkIGFjcm9zcyB0aGVcXG5zYW1wbGUuIFNpbWlsYXIgZGVjbGluZXMgaW4gdGhlc2UgdHlwZXMgb2YgZXhwZW5zZXMgYXJlIGFsc28gZm91bmQgaW4gYWxsIHRoZSBvdGhlciBzdHVkaWVzLiBBbHRlcmVkXFxuY29uc3VtcHRpb24gdGh1cyBkb2VzIG5vdCBzZWVtIHRvIGJlIHRpZWQgdG8gdGhlIGlkZW9sb2d5IG9mIGEgcGFydGljdWxhciBNRkkuXFxuTWljcm9maW5hbmNlIGFmZmVjdHMgbGFib3Igc3VwcGx5IGNob2ljZXMgYXMgd2VsbDogaGVyZSB3ZSBmaW5kIHRoYXQgaG91c2Vob2xkcyB0aGF0IGhhdmVcXG5hY2Nlc3MgdG8gbG9hbnMgc2VlbSB0byB3b3JrIGhhcmRlciBvbiB0aGVpciBvd24gYnVzaW5lc3NlczsgaW4gb3RoZXIgc2V0dGluZ3MgdGhleSBhcmUgZm91bmQgdG9cXG5jdXQgYXJkdW91cyBsYWJvciBlbHNld2hlcmUuIFRodXMsIG1pY3JvY3JlZGl0IHBsYXlzIGl0cyByb2xlIGFzIGEgZmluYW5jaWFsIHByb2R1Y3QgaW4gYW4gZW52aXJvbm1lbnQgd2hlcmUgYWNjZXNzIGlzIGxpbWl0ZWQsIG5vdCBvbmx5IHRvIGNyZWRpdCBidXQgYWxzbyB0byBzYXZpbmcgb3Bwb3J0dW5pdGllcy4gSXQgZXhwYW5kc1xcbmhvdXNlaG9sZHPigJkgYWJpbGl0aWVzIHRvIG1ha2UgZGlmZmVyZW50IGludGVydGVtcG9yYWwgY2hvaWNlcywgaW5jbHVkaW5nIGJ1c2luZXNzIGludmVzdG1lbnQuIFRoZVxcbm9ubHkgbWlzdGFrZSB0aGF0IHRoZSBtaWNyb2NyZWRpdCBlbnRodXNpYXN0cyBtYXkgaGF2ZSBtYWRlIGlzIHRvIG92ZXJlc3RpbWF0ZSB0aGUgcG90ZW50aWFsXFxub2YgYnVzaW5lc3NlcyBmb3IgdGhlIHBvb3IsIGJvdGggYXMgYSBzb3VyY2Ugb2YgcmV2ZW51ZSBhbmQgYXMgYSBtZWFucyBvZiBlbXBvd2VybWVudCBmb3IgdGhlaXJcXG5mZW1hbGUgb3duZXJzLiJ9XX1d' # @param {isTemplate: true}\n", + "generation_config_b64 = 'eyJ0ZW1wZXJhdHVyZSI6MSwidG9wX3AiOjAuOTUsInRvcF9rIjo0MCwibWF4X291dHB1dF90b2tlbnMiOjgxOTJ9' # @param {isTemplate: true}\n", + "safety_settings_b64 = \"e30=\" # @param {isTemplate: true}\n", + "\n", + "gais_contents = json.loads(base64.b64decode(contents_b64))\n", + "\n", + "generation_config = json.loads(base64.b64decode(generation_config_b64))\n", + "safety_settings = json.loads(base64.b64decode(safety_settings_b64))\n", + "\n", + "stream = False\n", + "\n", + "# Convert and upload the files\n", + "\n", + "tempfiles = pathlib.Path(f\"tempfiles\")\n", + "tempfiles.mkdir(parents=True, exist_ok=True)\n", + "\n", + "\n", + "drive = None\n", + "def upload_file_data(file_data, index):\n", + " \"\"\"Upload files to the Files API.\n", + "\n", + " For each file, Google AI Studio either sent:\n", + " - a Google Drive ID,\n", + " - a URL,\n", + " - a file path, or\n", + " - The raw bytes (`inline_data`).\n", + "\n", + " The API only understands `inline_data` or it's Files API.\n", + " This code, uploads files to the files API where the API can access them.\n", + " \"\"\"\n", + "\n", + " mime_type = file_data[\"mime_type\"]\n", + " if drive_id := file_data.pop(\"drive_id\", None):\n", + " if drive is None:\n", + " from google.colab import drive\n", + " drive.mount(\"/gdrive\")\n", + "\n", + " path = next(\n", + " pathlib.Path(f\"/gdrive/.shortcut-targets-by-id/{drive_id}\").glob(\"*\")\n", + " )\n", + " print(\"Uploading:\", str(path))\n", + " file_info = genai.upload_file(path=path, mime_type=mime_type)\n", + " file_data[\"file_uri\"] = file_info.uri\n", + " return\n", + "\n", + " if url := file_data.pop(\"url\", None):\n", + " response = requests.get(url)\n", + " data = response.content\n", + " name = url.split(\"/\")[-1]\n", + " path = tempfiles / str(index)\n", + " path.write_bytes(data)\n", + " print(\"Uploading:\", url)\n", + " file_info = genai.upload_file(path, display_name=name, mime_type=mime_type)\n", + " file_data[\"file_uri\"] = file_info.uri\n", + " return\n", + "\n", + " if name := file_data.get(\"filename\", None):\n", + " if not pathlib.Path(name).exists():\n", + " raise IOError(\n", + " f\"local file: `{name}` does not exist. You can upload files \"\n", + " 'to Colab using the file manager (\"📁 Files\" in the left '\n", + " \"toolbar)\"\n", + " )\n", + " file_info = genai.upload_file(path, display_name=name, mime_type=mime_type)\n", + " file_data[\"file_uri\"] = file_info.uri\n", + " return\n", + "\n", + " if \"inline_data\" in file_data:\n", + " return\n", + "\n", + " raise ValueError(\"Either `drive_id`, `url` or `inline_data` must be provided.\")\n", + "\n", + "\n", + "contents = copy.deepcopy(gais_contents)\n", + "\n", + "index = 0\n", + "for content in contents:\n", + " for n, part in enumerate(content[\"parts\"]):\n", + " if file_data := part.get(\"file_data\", None):\n", + " upload_file_data(file_data, index)\n", + " index += 1\n", + "\n", + "import json\n", + "print(json.dumps(contents, indent=4))" + ] + }, + { + "cell_type": "code", + "source": [ + "sss" + ], + "metadata": { + "id": "d8oVuU4lAWfj", + "outputId": "49b0e6c8-5753-4625-f2db-0286e3dd118f", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 147 + } + }, + "execution_count": 6, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "name 'sss' is not defined", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msss\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'sss' is not defined" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "E7zAD69vE92b" + }, + "source": [ + "## Call `generate_content`" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "LB2LxPmAB95V", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 221 + }, + "outputId": "f2594d39-6b80-499d-ac79-dbf65e77a03c" + }, + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "name 'genai' is not defined", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# Call the model and print the response.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mgemini\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgenai\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mGenerativeModel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m response = gemini.generate_content(\n", + "\u001b[0;31mNameError\u001b[0m: name 'genai' is not defined" + ] + } + ], + "source": [ + "from IPython.display import display\n", + "from IPython.display import Markdown\n", + "\n", + "# Call the model and print the response.\n", + "gemini = genai.GenerativeModel(model_name=model)\n", + "\n", + "response = gemini.generate_content(\n", + " contents,\n", + " generation_config=generation_config,\n", + " safety_settings=safety_settings,\n", + " stream=stream,\n", + ")\n", + "\n", + "display(Markdown(response.text))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "9c9d345e9868" + }, + "source": [ + "\n", + " \n", + " \n", + "
\n", + " Docs on ai.google.dev\n", + " \n", + " More notebooks in the Cookbook\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "F91AeeGO1ncU" + }, + "source": [ + "## [optional] Show the conversation\n", + "\n", + "This section displays the conversation received from Google AI Studio." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "cellView": "form", + "id": "yoL3p3KPylFW" + }, + "outputs": [], + "source": [ + "# @title Show the conversation, in colab.\n", + "import mimetypes\n", + "\n", + "def show_file(file_data):\n", + " mime_type = file_data[\"mime_type\"]\n", + "\n", + " if drive_id := file_data.get(\"drive_id\", None):\n", + " path = next(\n", + " pathlib.Path(f\"/gdrive/.shortcut-targets-by-id/{drive_id}\").glob(\"*\")\n", + " )\n", + " name = path\n", + " # data = path.read_bytes()\n", + " kwargs = {\"filename\": path}\n", + " elif url := file_data.get(\"url\", None):\n", + " name = url\n", + " kwargs = {\"url\": url}\n", + " # response = requests.get(url)\n", + " # data = response.content\n", + " elif data := file_data.get(\"inline_data\", None):\n", + " name = None\n", + " kwargs = {\"data\": data}\n", + " elif name := file_data.get(\"filename\", None):\n", + " if not pathlib.Path(name).exists():\n", + " raise IOError(\n", + " f\"local file: `{name}` does not exist. You can upload files to \"\n", + " 'Colab using the file manager (\"📁 Files\"in the left toolbar)'\n", + " )\n", + " else:\n", + " raise ValueError(\"Either `drive_id`, `url` or `inline_data` must be provided.\")\n", + "\n", + " print(f\"File:\\n name: {name}\\n mime_type: {mime_type}\\n\")\n", + " return\n", + "\n", + " format = mimetypes.guess_extension(mime_type).strip(\".\")\n", + " if mime_type.startswith(\"image/\"):\n", + " image = IPython.display.Image(**kwargs, width=256)\n", + " IPython.display.display(image)\n", + " print()\n", + " return\n", + "\n", + " if mime_type.startswith(\"audio/\"):\n", + " if len(data) < 2**12:\n", + " audio = IPython.display.Audio(**kwargs)\n", + " IPython.display.display(audio)\n", + " print()\n", + " return\n", + "\n", + " if mime_type.startswith(\"video/\"):\n", + " if len(data) < 2**12:\n", + " audio = IPython.display.Video(**kwargs, mimetype=mime_type)\n", + " IPython.display.display(audio)\n", + " print()\n", + " return\n", + "\n", + " print(f\"File:\\n name: {name}\\n mime_type: {mime_type}\\n\")\n", + "\n", + "\n", + "for content in gais_contents:\n", + " if role := content.get(\"role\", None):\n", + " print(\"Role:\", role, \"\\n\")\n", + "\n", + " for n, part in enumerate(content[\"parts\"]):\n", + " if text := part.get(\"text\", None):\n", + " print(text, \"\\n\")\n", + "\n", + " elif file_data := part.get(\"file_data\", None):\n", + " show_file(file_data)\n", + "\n", + " print(\"-\" * 80, \"\\n\")" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [ + "Tce3stUlHN0L" + ], + "name": "aistudio_gemini_prompt_freeform.ipynb", + "toc_visible": true, + "provenance": [], + "include_colab_link": true + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file From 5f12bb1b36a13cb02f499611f95d4e5e5527bcd9 Mon Sep 17 00:00:00 2001 From: "Emnai: EmnaiDEV-admin @ EmnaiDEV" Date: Wed, 8 Jan 2025 17:23:17 -0500 Subject: [PATCH 2/2] Created using Colab --- .../aistudio_gemini_prompt_freeform.ipynb | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/templates/aistudio_gemini_prompt_freeform.ipynb b/templates/aistudio_gemini_prompt_freeform.ipynb index 95ee45d7339..200d13b4b6b 100644 --- a/templates/aistudio_gemini_prompt_freeform.ipynb +++ b/templates/aistudio_gemini_prompt_freeform.ipynb @@ -1,15 +1,5 @@ { "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "view-in-github", - "colab_type": "text" - }, - "source": [ - "\"Open" - ] - }, { "cell_type": "markdown", "metadata": { @@ -209,12 +199,12 @@ "sss" ], "metadata": { - "id": "d8oVuU4lAWfj", - "outputId": "49b0e6c8-5753-4625-f2db-0286e3dd118f", "colab": { "base_uri": "https://localhost:8080/", "height": 147 - } + }, + "id": "d8oVuU4lAWfj", + "outputId": "49b0e6c8-5753-4625-f2db-0286e3dd118f" }, "execution_count": 6, "outputs": [ @@ -396,8 +386,7 @@ ], "name": "aistudio_gemini_prompt_freeform.ipynb", "toc_visible": true, - "provenance": [], - "include_colab_link": true + "provenance": [] }, "kernelspec": { "display_name": "Python 3",