Objectives

Upon completion of this lesson, you will be able to:

  • list the phases of CRISP-DM
  • understand the work products and activities of each phase

Introduction

CRISP-DM stands for Cross-Industry Standard Process for Data Mining and data mining in this context encompasses not only data mining but also data analytics and machine learning. It is a widely-used and well-established methodology for data mining that provides a structured approach to planning and executing data mining (and machine learning and data analytics) projects.

The CRISP-DM framework consists of six major phases:

  1. Business Understanding: In this phase, the project objectives and requirements are defined, and the data mining problem is formulated.

  2. Data Understanding: This phase involves collecting and analyzing the data that will be used for the project. This includes identifying the data sources, evaluating data quality, and exploring the data to gain insights.

  3. Data Preparation: In this phase, the data is cleaned, transformed, and formatted in a way that makes it suitable for data mining. This can involve selecting relevant variables, dealing with missing values, and encoding categorical variables.

  4. Modeling: In this phase, the data is analyzed using various modeling techniques, such as classification, clustering, or regression. The aim is to develop a model that can accurately predict or explain the target variable.

  5. Evaluation: The model is evaluated using various performance metrics to determine its effectiveness and suitability for the intended purpose.

  6. Deployment: In this final phase, the model is deployed in a real-world setting, and the results are monitored to ensure that the model is performing as expected.

The graphic below shows the iterative nature of the CRISP-DM framework1:

The short tutorial below by Dr. Soofastaei of Pearson Education summarizes the process. You might want to watch before reading more about CRISP-DM.

Why CRISP-DM?

The CRISP-DM framework provides a structured and iterative approach to data mining, allowing for continuous improvement and refinement throughout the project. It provides a standard blueprint to guide data projects. By using a standard framework, the data mining process becomes reliable and repeatable, particularly by analysts with few data mining skills. Furthermore, it reduces reliance on “heroes” and provides comfort for those new to data science and data mining.

In most data mining endeavors 60-80% of the effort is in data extraction, transformation, and loading, including – data understanding and data preparation. These phases are “standard” and should be done in a repeatable manner. CRISP-DM provides a framework to do so.

CRISP-DM Phases

This section takes a more detailed look at the various stages of the pipeline. The video below provides a summary, should you find a narrated tutorial helpful.

Stage 1: Business Understanding

At the initial stage of the CRISP-DM process, it is essential to define the business objectives of the data project and to understand any constraints. The objective of this phase is to reveal key factors that might impact the project’s outcome. Failing to undertake this step may lead to expending significant effort on generating correct answers to irrelevant queries.

Define Project Outcomes

  • Set Objectives: This involves defining your primary business objectives, which could be keeping current customers by predicting when they may switch to a competitor. You may also have other related questions to address, such as “Does the number of times a customer’s visits our website impact their decision to abandon their shopping cart?” or “Will reducing shipping fees significantly increase the number of customers we retain?”

  • Produce Project Plan: In this phase, the outcome is a detailed plan for attaining the data mining and business objectives. The plan should outline the steps to be executed throughout the remainder of the project, including the initial selection of tools and techniques. This is comparable to a project plan is software project management and commonly includes a timeline, task list, and perhaps critical path analysis, task assignments, and cost and time estimates.

  • Define Success Criteria: In the “Business success criteria” stage, we define the criteria that will be applied to evaluate the project’s success from a business perspective. Ideally, these should be precise and quantifiable, such as a specific decrease in customer churn by some point in time. Whenever possible, the success criteria must be SMART, i.e., specific, measurable, attainable, relevant, and time-based. However, in some cases, subjective criteria like “provide valuable insights into the relationships” may be necessary. If so, it is crucial to specify who will make the subjective assessment and when.

Assess Current Situation

This phase necessitates in-depth information gathering on all resources, restrictions/constraints, assumptions, and other variables that must be taken into account while establishing your data analysis objective and project plan.

  1. Inventory of Resources: Identify the resources available to the project including:
  • Personnel (e.g., subject matter experts, data scientists, data engineers, technical support)
  • Data (e.g., transactional and analytical databases, data files, third-party data)
  • Computing Resources (e.g., hardware platforms, cloud platforms)
  • Software (e.g., data mining tools, machine learning models, database management systems, visualization packages)
  1. Requirements, Assumptions and Constraints: Identify all current requirements including the schedule, use cases, quality of results, data security concerns, as well as any potential legal ramifications. Verify ownership of or license to use the data, along with any usage constraints. List any assumptions made by the project sponsors and stakeholders. These assumptions may pertain to the data, which can be confirmed during data mining, or they may relate to the business and cannot be verified. If the latter affects the results’ validity, it is crucial to enumerate them. Enumerate the project limitations, which could be restrictions on resource accessibility or technological constraints, such as the practicality of using a particular dataset size for modeling purposes.

  2. Risks and Mitigation: List any risks or adverse events that might delay the project or cause it to fail, or impact the deliverable or schedule. For each identified risks, define its likelihood of occurrence and its impact on the project. Create risks mitigation strategies for all high-impact or likely risks. Define what actions would need to be taken to reduce a risk or to deal with it should it occur.

  3. Terminology: Compile a glossary of terms relevant to the project and its stakeholders. The glossary should encompass a definition of all relevant business terms, which forms part of the business understanding available to the project. The glossary is generally a deliverable of the requirements gathering and elicitation efforts. Additionally, the project team must write a glossary of data mining terms to ensure that everyone has the same understanding of data mining techniques employed on the project.

  4. Costs and benefits: Create a cost-benefit analysis that contrasts the project expenses with the potential business benefits if the project is successful. This comparison is part of the business case and should be as precise as possible, utilizing financial measures.

Determine Data Mining Objectives

A business goal states objectives using measures that provide business value. The data mining objectives expresses the project’s technical aims. For instance, the business objective could be “Enhance e-mail marketing sales to current customers,” whereas the data mining objective might be “Forecast the order total for customers based on their previous three-year purchase history, demographic data (e.g., age, salary, zip code), and item pricing.” The data mining objectives are used to realize the business objectives. Data mining success criteria might include certain levels of precision, recall, accuracy, F1-score, among other technical data mining metrics.

Project Plan

The project plan defines how the project will be carried out, including which team members will do which activities and tasks, which tools are to be used, and when deliverables are due.

For the project tasks, define their duration, required resources and tools, inputs, outputs, and task dependencies. Where possible, try and make explicit the large-scale iterations in the data mining process, for example, repetitions of the modelling and evaluation phases. As part of the project plan, it is also important to analyze dependencies between time schedule and risks. Mark results of these analyses explicitly in the project plan, ideally with actions and recommendations if the risks are manifested. Decide at this point which evaluation strategy will be used in the evaluation phase. Your project plan will be a dynamic document.

At the end of each phase you’ll review progress and achievements and update the project plan accordingly. Specific review points for these updates should be part of the project plan. Initial assessment of tools and techniques – At the end of the first phase you should undertake an initial assessment of tools and techniques. Here, for example, you select a data mining tool that supports various methods for different stages of the process. It is important to assess tools and techniques early in the process since the selection of tools and techniques may influence the entire project.

Stage 2: Data Understanding

The second phase of the CRISP-DM process entails obtaining the data indicated in the project resources. This initial collection may involve data loading, especially if it aids in data comprehension. For instance, if a particular tool is utilized for data understanding, it is logical to upload the data into that tool. If there are multiple data sources, it is crucial to contemplate how and when they will be integrated.

A key deliverable is the data collection report which identifies the sources of data, their locations, and the methods necessary to retrieve the data, in addition to any data collection risks.

Describe Data

Among the first steps in understanding the data is to examine the data’s properties, i.e., how many instances, how many variables, what kinds of variables (categorical, numeric, textual), and the format of the data.

A key insight from this step is to know whether the right data is available to address the business objectives and whether there is sufficient data to build predictive models.

Examine the “gross” or “surface” properties of the acquired data and report on the results.

Explore Data

In this stage the data analysis team addresses initial, high-level data mining questions using data queries, descriptive statistics, and exploratory data visualizations. Exploratory analysis focuses chiefly on the distribution of target and predictor variables and correlations. Often, simple aggregations such as sums and means are explored, along with variance and co-variance.

A key project deliverable is the Data Exploration Report which contains the results of the exploratory data analysis, including key findings and initial hypothesis and whether those might impact the remainder of the project; or even if the project should be terminated at this point. To some extent, this step is a “gate keeping” act with a “go/no-go” decision.

It is common to include initial exploratory analysis results in the report, including exploratory visualizations, graphs and plots to show data characteristics, and possible future areas of more detailed examination of relevant and interesting subsets of the data.

Evaluate Data Quality

It is essential to conduct an evaluation of data quality, while considering pertinent issues such as:

  • Does the data encompass all the necessary cases, or is it incomplete?
  • Is the data accurate, or does it contain mistakes? If so, what is the extent of these errors?
  • Are there any omissions in the data? If present, how are they indicated, where do they arise, and how frequent are they?

Analysts generally enumerate the outcomes of the data quality validation in a report. In cases where quality issues are apparent, it is helpful to recommend applicable and appropriate remedies and imputation strategies. Addressing data quality problems ordinarily relies on a combination of expertise in data analytics and the business domain.

Stage 3: Data Preparation

Select Data

The data selection phase of a project involves making informed choices about the dataset to be analyzed, based on various factors including the pertinence of the data to the data mining objectives, the data quality, and technical constraints such as data size and format. It is important to note that data selection encompasses the choice of both attributes (columns) and records (rows) within a table.

To justify the inclusion or exclusion of data, it is necessary to provide a rationale for these decisions. This involves documenting the list of selected and omitted data, along with the reasons that informed these decisions.

Clean Data

The next task focuses on enhancing the quality of the data to meet the requirements of the selected analysis techniques and data mining algorithms. This may entail selecting clean subsets of the data, introducing appropriate default values, identifying corrupted data, or implementing more complex procedures such as modelling to impute missing data. The process must be reproducible.

To document the steps taken to address data quality issues, it is necessary to create a report outlining the decisions and actions taken in terms of data cleaning. This report should detail any transformations applied to the data for the purposes of cleaning and their potential impact on the results of the analysis.

Transform and Derive Data

Once the data has been clean, additional data preparation operations can be performed, including the creation of derived attributes, additional records, or transformed values for existing attributes.

Derived attributes refer to new variables constructed from one or more pre-existing attributes within the same record using some formula or rule. For instance, the variables of length and width might be used to derive a new attribute of area.

Generated records describe the process of creating entirely new records. For instance, it may be necessary to create records for customers who did not make any purchases in the past year, even though such records were not present in the raw data. Representing the fact that certain customers made zero purchases may be critical for modelling purposes and to ensure that data mining algorithms produce reasonable values.

Integrate Data

Data integration involves combining information from multiple data sources, files, tables, or external databases to create new values or records.

Merged data refers to the process of joining two or more sources that contain different information about the same objects. For instance, a retail chain may have separate databases containing information about each store’s characteristics, summarized sales data, and demographics of the surrounding area. These databases can be merged into a new database with one record for each store, combining relevant fields from the source databases.

Aggregations involve computing new values by summarizing information from multiple records and/or tables. For instance, a table of customer purchases with one record for each purchase can be transformed into a new table with one record for each customer, containing fields such as number of purchases, average purchase amount, percentage of orders charged to credit card, and percentage of items purchased during a promotion.

Stage 4: Model Selection

The initial stage of modeling involves selecting the specific technique that will be used for analysis, even if a tool was already selected in the Business Understanding phase. As an example, the analysis team may need to choose a proper classification technique and need to determine whether to use a decision-tree constructed with C5.0 or a classification model built from neural network generation with back propagation. It is important to perform this task separately for each modelling technique that will be applied.

The selected modelling techniques should be documented in detail and their training must be reproducible.

It is crucial to consider the assumptions made by the chosen modelling technique regarding the data. Many modelling techniques make specific assumptions about the data, such as requiring all attributes to have normal distributions, disallowing missing values, and requiring the class attribute to be categorical. All modelling assumptions made must be recorded.

Design Model Testing and Validation

Before constructing a model, it is necessary to develop a mechanism or procedure to evaluate its quality and validity. In supervised data mining tasks, such as classification, error rates are commonly used as quality measures for data mining models. As such, it is customary to split the dataset into training and testing sets, constructing the model on the training set, and assessing its quality on the separate testing set.

To train, test, and evaluate the models effectively, a comprehensive plan must be established. A key component of this plan is determining how to partition the available dataset into training, testing, and validation datasets. The plan should outline the specific methods and metrics that will be employed to assess the model’s accuracy and performance. It should also address any potential biases or limitations in the data and ensure that the models are evaluated in a fair and unbiased manner.

Construct Model

Running the modelling tool on the prepared dataset involves creating one or more models for analysis.

Parameter settings for the modelling tool should be documented, including the values chosen for each parameter and the reasoning behind their selection. The parameter settings will vary depending on the specific modelling tool and technique used.

The resulting models created by the modelling tool should be documented, including all relevant details about the models.

Model descriptions should be provided, including any interpretation of the models, difficulties encountered during their analysis, and potential limitations or biases. A comprehensive report should be created, outlining the findings and insights gained from the models, as well as any recommendations for future analysis.

Evaluate Model

Interpreting the models according to domain knowledge, data mining success criteria, and desired test design is a critical step in evaluating the success of modelling and discovery techniques. It is essential to assess the technical aspects of the models and rank them accordingly, while also considering the business objectives and success criteria.

The models should be assessed in terms of their qualities, such as accuracy, and ranked in relation to one another. The results of this task should be summarised, highlighting the strengths and limitations of the generated models.

Based on the model assessment, parameter settings may need to be revised and tuned for the next modelling run. This iterative process of model building and assessment should continue until the best possible model(s) are identified. All revisions and assessments should be thoroughly documented to ensure transparency and reproducibility.

Stage 5: Evaluation

Evaluate Results and Objectives

During this step, the evaluation phase assesses the extent to which the generated model meets the business objectives. This may involve testing the model(s) on real-world applications or identifying any deficiencies in the model that may impact its practical usefulness. The evaluation phase also includes an assessment of all other data mining results generated during the project, which may reveal additional challenges or insights for future directions.

The assessment of data mining results should be summarised in terms of business success criteria, including a final statement on whether the project has successfully achieved its initial business objectives.

Based on the assessment of models with respect to the business success criteria, the generated models that meet the selected criteria become the approved models.

Conduct Process Retrospective

After determining that the resulting models meet the business needs, it is necessary to conduct a more comprehensive review of the data mining engagement to ensure that no important factor or task has been overlooked. This review should also include quality assurance issues, such as whether the model was correctly built and whether only permissible attributes were used for analysis.

The process review should be summarised, highlighting any activities that were missed or overlooked, as well as any tasks that should be repeated to ensure that the data mining engagement was executed accurately and effectively. This review may also identify potential areas for improvement or refinement in the data mining process that could be implemented in future projects. Overall, the review should provide a comprehensive evaluation of the data mining engagement and ensure that all necessary steps were taken to achieve the project’s goals.

Assess Next Steps

After completing the assessment and process review, it is necessary to decide how to proceed with the project. This may involve finishing the project and moving on to deployment, initiating further iterations to improve the models or the process, or setting up new data mining projects. The remaining resources and budget should be taken into consideration when making this decision.

A list of potential further actions should be created, along with the reasons for and against each option. For example, continuing with the project may be the best option if the models meet the business needs and there are no additional insights to be gained from further iterations. On the other hand, initiating further iterations may be necessary if the models need to be refined or if there are still unanswered questions that need to be addressed.

The decision on how to proceed should be described in detail, along with the rationale for the chosen course of action. This decision should be based on a thorough evaluation of the data mining engagement, taking into account the results of the assessment, the process review, and the available resources and budget.

Stage 6: Deployment

Plan Deployment

The deployment stage involves taking the evaluation results and determining a strategy for deploying the models. If a general procedure has been identified for creating the relevant models, it should be documented for later deployment. It is important to consider the ways and means of deployment during the business understanding phase as well, as this is crucial to the success of the project and the operational side of the business.

The deployment plan should summarize the deployment strategy, including the necessary steps and how to perform them. This may involve integrating the models into existing systems or developing new applications to make use of the models. The plan should also identify any potential challenges or limitations in the deployment process and outline strategies for addressing them.

The deployment plan should be comprehensive and include all necessary details, such as timelines, resources, and key stakeholders involved in the deployment process. It should also be reviewed and updated regularly to ensure that it remains relevant and effective. Overall, a well-developed deployment plan is essential for maximizing the value of the data mining project and achieving the desired business outcomes.

Monitor Models

Monitoring and maintenance are crucial issues when data mining results become part of the day-to-day business environment. A well-prepared maintenance strategy is essential to ensure the continued accuracy and effectiveness of the data mining results and to avoid any unnecessary periods of incorrect usage.

To monitor the deployment of the data mining result(s), a detailed monitoring process plan should be developed, taking into account the specific type of deployment. This plan should summarise the monitoring and maintenance strategy, including the necessary steps and how to perform them.

The monitoring and maintenance plan should outline key performance indicators (KPIs) that will be used to evaluate the effectiveness of the data mining results and identify any potential issues or areas for improvement. It should also include a schedule for regular review and update of the models, as well as procedures for resolving any issues that may arise.

The plan should be reviewed and updated regularly to ensure that it remains relevant and effective. This will help to ensure the continued success of the data mining project and enable the business to maximise the value of the data mining results.

Write Final Report

At the end of the data mining project, it is important to prepare a final report that summarises and organises all the results and deliverables. Depending on the deployment plan, the final report may be a comprehensive presentation of the data mining results or a summary of the project experiences (if they have not already been documented as an ongoing activity).

The final report should include all the previous deliverables, such as the business understanding, data preparation, modelling, evaluation, and deployment plans. It should also provide an overview of the data mining process, including any challenges and limitations encountered, and highlight the key findings and insights gained.

In addition to the final report, there will often be a meeting at the conclusion of the project where the results are presented to the customer. This final presentation should provide a clear and concise overview of the data mining results, highlighting the most important findings and their potential implications for the business.

Overall, the final report and presentation are critical components of the data mining project and help to ensure that the business can fully leverage the insights gained from the project to achieve its goals and objectives.

Conduct Retrospective

Assessing the data mining project at its conclusion is an important step for identifying what went well and what could be improved. Experience documentation can help to capture important insights and lessons learned from the project that can be used to inform future projects and improve overall performance.

Experience documentation should summarize the important experiences gained during the project, including any pitfalls encountered, misleading approaches, or hints for selecting the best suited data mining techniques in similar situations. This documentation can also include any reports that were written by individual project members during previous phases of the project, as these may contain valuable insights and lessons learned.

It is important to identify both the successes and failures of the project in order to improve future performance. This may involve reflecting on the effectiveness of the data preparation and modelling techniques used, the quality of the data, the appropriateness of the evaluation criteria, and the success of the deployment strategy. By understanding what went well and what needs to be improved, future data mining projects can be more effective and efficient, leading to better business outcomes.

Summary

The CRISP-DM (Cross-Industry Standard Process for Data Mining) framework is a widely-used methodology for data mining projects. It consists of six phases: Business Understanding, Data Understanding, Data Preparation, Modeling, Evaluation, and Deployment. Each phase involves a set of tasks and objectives that help guide the project through its life cycle, from identifying the business problem to deploying the solution. The framework is iterative, allowing for adjustments and improvements at each stage, and emphasizes the importance of communication and collaboration between team members.


Files & Resources

All Files for Lesson 5.104

Errata

None collected yet. Let us know.


  1. Image by Kenneth Jensen, CC BY-SA 3.0 https://creativecommons.org/licenses/by-sa/3.0, via Wikimedia Commons↩︎

LS0tCnRpdGxlOiAiQ1JJU1AtRE0gUHJvY2VzcyBmb3IgRGF0YSBBbmFseXRpY3MgYW5kIERhdGEgTWluaW5nIgpwYXJhbXM6CiAgdHlwZTogbGVzc29uCiAgY2F0ZWdvcnk6IDUKICBzdGFja3M6ICIwLDAiCiAgbnVtYmVyOiAxMDQKICB0aW1lOiAxNQogIGxldmVsOiBiZWdpbm5lcgogIHRhZ3M6IGNyaXNwLWRtLG1hY2hpbmUgbGVhcm5pbmcsZGF0YSBtaW5pbmcsYW5hbHl0aWNzLHByb2Nlc3MKICBkZXNjcmlwdGlvbjogIkV4cGxhaW5zIHRoZSBDUklTUC1ETSBmcmFtZXdvcmsgZm9yIGRhdGEgYW5hbHl0aWNzCiAgICAgICAgICAgICAgICBhbmQgZGF0YSBtaW5pbmcgcHJvamVjdC4gRGlmZmVyZW50aWF0ZSBiZXR3ZWVuIHRoZSAKICAgICAgICAgICAgICAgIGRpZmZlcmVudCBwaGFzZXMgaW4gdGhlIENSSVNQLURNIGZyYW1ld29yay4iCmRhdGU6ICI8c21hbGw+YHIgU3lzLkRhdGUoKWA8L3NtYWxsPiIKYXV0aG9yOiAiPHNtYWxsPk1hcnRpbiBTY2hlZGxiYXVlcjwvc21hbGw+IgplbWFpbDogIm0uc2NoZWRsYmF1ZXJAbmV1LmVkdSIKYWZmaWxpdGF0aW9uOiAiTm9ydGhlYXN0ZXJuIFVuaXZlcnNpdHkiCm91dHB1dDogCiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRoZW1lOiBzcGFjZWxhYgogICAgaGlnaGxpZ2h0OiB0YW5nbwotLS0KCi0tLQp0aXRsZTogIjxzbWFsbD5gciBwYXJhbXMkY2F0ZWdvcnlgLmByIHBhcmFtcyRudW1iZXJgPC9zbWFsbD48YnIvPjxzcGFuIHN0eWxlPSdjb2xvcjogIzJFNDA1MzsgZm9udC1zaXplOiAwLjllbSc+YHIgcm1hcmtkb3duOjptZXRhZGF0YSR0aXRsZWA8L3NwYW4+IgotLS0KCmBgYHtyIGNvZGU9eGZ1bjo6cmVhZF91dGY4KHBhc3RlMChoZXJlOjpoZXJlKCksJy9SL19pbnNlcnQyREIuUicpKSwgaW5jbHVkZSA9IEZBTFNFfQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgT2JqZWN0aXZlcwoKVXBvbiBjb21wbGV0aW9uIG9mIHRoaXMgbGVzc29uLCB5b3Ugd2lsbCBiZSBhYmxlIHRvOgoKLSAgIGxpc3QgdGhlIHBoYXNlcyBvZiBDUklTUC1ETQotICAgdW5kZXJzdGFuZCB0aGUgd29yayBwcm9kdWN0cyBhbmQgYWN0aXZpdGllcyBvZiBlYWNoIHBoYXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIEludHJvZHVjdGlvbiB7I2ludHJvfQoKKkNSSVNQLURNKiBzdGFuZHMgZm9yIENyb3NzLUluZHVzdHJ5IFN0YW5kYXJkIFByb2Nlc3MgZm9yIERhdGEgTWluaW5nIGFuZCBkYXRhIG1pbmluZyBpbiB0aGlzIGNvbnRleHQgZW5jb21wYXNzZXMgbm90IG9ubHkgZGF0YSBtaW5pbmcgYnV0IGFsc28gZGF0YSBhbmFseXRpY3MgYW5kIG1hY2hpbmUgbGVhcm5pbmcuIEl0IGlzIGEgd2lkZWx5LXVzZWQgYW5kIHdlbGwtZXN0YWJsaXNoZWQgbWV0aG9kb2xvZ3kgZm9yIGRhdGEgbWluaW5nIHRoYXQgcHJvdmlkZXMgYSBzdHJ1Y3R1cmVkIGFwcHJvYWNoIHRvIHBsYW5uaW5nIGFuZCBleGVjdXRpbmcgZGF0YSBtaW5pbmcgKGFuZCBtYWNoaW5lIGxlYXJuaW5nIGFuZCBkYXRhIGFuYWx5dGljcykgcHJvamVjdHMuCgpUaGUgQ1JJU1AtRE0gZnJhbWV3b3JrIGNvbnNpc3RzIG9mIHNpeCBtYWpvciBwaGFzZXM6CgoyLiAgKipCdXNpbmVzcyBVbmRlcnN0YW5kaW5nKio6IEluIHRoaXMgcGhhc2UsIHRoZSBwcm9qZWN0IG9iamVjdGl2ZXMgYW5kIHJlcXVpcmVtZW50cyBhcmUgZGVmaW5lZCwgYW5kIHRoZSBkYXRhIG1pbmluZyBwcm9ibGVtIGlzIGZvcm11bGF0ZWQuCgozLiAgKipEYXRhIFVuZGVyc3RhbmRpbmcqKjogVGhpcyBwaGFzZSBpbnZvbHZlcyBjb2xsZWN0aW5nIGFuZCBhbmFseXppbmcgdGhlIGRhdGEgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIHRoZSBwcm9qZWN0LiBUaGlzIGluY2x1ZGVzIGlkZW50aWZ5aW5nIHRoZSBkYXRhIHNvdXJjZXMsIGV2YWx1YXRpbmcgZGF0YSBxdWFsaXR5LCBhbmQgZXhwbG9yaW5nIHRoZSBkYXRhIHRvIGdhaW4gaW5zaWdodHMuCgo0LiAgKipEYXRhIFByZXBhcmF0aW9uKio6IEluIHRoaXMgcGhhc2UsIHRoZSBkYXRhIGlzIGNsZWFuZWQsIHRyYW5zZm9ybWVkLCBhbmQgZm9ybWF0dGVkIGluIGEgd2F5IHRoYXQgbWFrZXMgaXQgc3VpdGFibGUgZm9yIGRhdGEgbWluaW5nLiBUaGlzIGNhbiBpbnZvbHZlIHNlbGVjdGluZyByZWxldmFudCB2YXJpYWJsZXMsIGRlYWxpbmcgd2l0aCBtaXNzaW5nIHZhbHVlcywgYW5kIGVuY29kaW5nIGNhdGVnb3JpY2FsIHZhcmlhYmxlcy4KCjUuICAqKk1vZGVsaW5nKio6IEluIHRoaXMgcGhhc2UsIHRoZSBkYXRhIGlzIGFuYWx5emVkIHVzaW5nIHZhcmlvdXMgbW9kZWxpbmcgdGVjaG5pcXVlcywgc3VjaCBhcyBjbGFzc2lmaWNhdGlvbiwgY2x1c3RlcmluZywgb3IgcmVncmVzc2lvbi4gVGhlIGFpbSBpcyB0byBkZXZlbG9wIGEgbW9kZWwgdGhhdCBjYW4gYWNjdXJhdGVseSBwcmVkaWN0IG9yIGV4cGxhaW4gdGhlIHRhcmdldCB2YXJpYWJsZS4KCjYuICAqKkV2YWx1YXRpb24qKjogVGhlIG1vZGVsIGlzIGV2YWx1YXRlZCB1c2luZyB2YXJpb3VzIHBlcmZvcm1hbmNlIG1ldHJpY3MgdG8gZGV0ZXJtaW5lIGl0cyBlZmZlY3RpdmVuZXNzIGFuZCBzdWl0YWJpbGl0eSBmb3IgdGhlIGludGVuZGVkIHB1cnBvc2UuCgo3LiAgKipEZXBsb3ltZW50Kio6IEluIHRoaXMgZmluYWwgcGhhc2UsIHRoZSBtb2RlbCBpcyBkZXBsb3llZCBpbiBhIHJlYWwtd29ybGQgc2V0dGluZywgYW5kIHRoZSByZXN1bHRzIGFyZSBtb25pdG9yZWQgdG8gZW5zdXJlIHRoYXQgdGhlIG1vZGVsIGlzIHBlcmZvcm1pbmcgYXMgZXhwZWN0ZWQuCgpUaGUgZ3JhcGhpYyBiZWxvdyBzaG93cyB0aGUgaXRlcmF0aXZlIG5hdHVyZSBvZiB0aGUgQ1JJU1AtRE0gZnJhbWV3b3JrW15sLTUtMTA0LTFdOgoKW15sLTUtMTA0LTFdOiBJbWFnZSBieSBLZW5uZXRoIEplbnNlbiwgQ0MgQlktU0EgMy4wIDxodHRwczovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvMy4wPiwgdmlhIFdpa2ltZWRpYSBDb21tb25zCgohW10oaHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9iL2I5L0NSSVNQLURNX1Byb2Nlc3NfRGlhZ3JhbS5wbmcpe3dpZHRoPSI1MCUiIHN0eWxlPSJkaXNwbGF5OiBibG9jazsgYWxpZ246IGNlbnRlcjsgbWFyZ2luOiAwIGF1dG8ifQoKVGhlIHNob3J0IHR1dG9yaWFsIGJlbG93IGJ5IERyLiBTb29mYXN0YWVpIG9mIFBlYXJzb24gRWR1Y2F0aW9uIHN1bW1hcml6ZXMgdGhlIHByb2Nlc3MuIFlvdSBtaWdodCB3YW50IHRvIHdhdGNoIGJlZm9yZSByZWFkaW5nIG1vcmUgYWJvdXQgQ1JJU1AtRE0uCgo8aWZyYW1lIHdpZHRoPSI0ODAiIGhlaWdodD0iMjcwIiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkL29Odm95NXJmZHlnP2NvbnRyb2xzPTAiIHRpdGxlPSJPdmVydmlldyBvZiBDUklTUC1ETSIgZnJhbWVib3JkZXI9IjEiIGFsbG93PSJhY2NlbGVyb21ldGVyOyBhdXRvcGxheTsgY2xpcGJvYXJkLXdyaXRlOyBlbmNyeXB0ZWQtbWVkaWE7IGd5cm9zY29wZTsgcGljdHVyZS1pbi1waWN0dXJlOyB3ZWItc2hhcmUiIGFsbG93ZnVsbHNjcmVlbiBkYXRhLWV4dGVybmFsPSIxIj4KCjwvaWZyYW1lPgoKIyMgV2h5IENSSVNQLURNPwoKVGhlIENSSVNQLURNIGZyYW1ld29yayBwcm92aWRlcyBhIHN0cnVjdHVyZWQgYW5kIGl0ZXJhdGl2ZSBhcHByb2FjaCB0byBkYXRhIG1pbmluZywgYWxsb3dpbmcgZm9yIGNvbnRpbnVvdXMgaW1wcm92ZW1lbnQgYW5kIHJlZmluZW1lbnQgdGhyb3VnaG91dCB0aGUgcHJvamVjdC4gSXQgcHJvdmlkZXMgYSBzdGFuZGFyZCBibHVlcHJpbnQgdG8gZ3VpZGUgZGF0YSBwcm9qZWN0cy4gQnkgdXNpbmcgYSBzdGFuZGFyZCBmcmFtZXdvcmssIHRoZSBkYXRhIG1pbmluZyBwcm9jZXNzIGJlY29tZXMgcmVsaWFibGUgYW5kIHJlcGVhdGFibGUsIHBhcnRpY3VsYXJseSBieSBhbmFseXN0cyB3aXRoIGZldyBkYXRhIG1pbmluZyBza2lsbHMuIEZ1cnRoZXJtb3JlLCBpdCByZWR1Y2VzIHJlbGlhbmNlIG9uICJoZXJvZXMiIGFuZCBwcm92aWRlcyBjb21mb3J0IGZvciB0aG9zZSBuZXcgdG8gZGF0YSBzY2llbmNlIGFuZCBkYXRhIG1pbmluZy4KCkluIG1vc3QgZGF0YSBtaW5pbmcgZW5kZWF2b3JzIDYwLTgwJSBvZiB0aGUgZWZmb3J0IGlzIGluIGRhdGEgZXh0cmFjdGlvbiwgdHJhbnNmb3JtYXRpb24sIGFuZCBsb2FkaW5nLCBpbmNsdWRpbmcgLS0gZGF0YSB1bmRlcnN0YW5kaW5nIGFuZCBkYXRhIHByZXBhcmF0aW9uLiBUaGVzZSBwaGFzZXMgYXJlICJzdGFuZGFyZCIgYW5kIHNob3VsZCBiZSBkb25lIGluIGEgcmVwZWF0YWJsZSBtYW5uZXIuIENSSVNQLURNIHByb3ZpZGVzIGEgZnJhbWV3b3JrIHRvIGRvIHNvLgoKIyMgQ1JJU1AtRE0gUGhhc2VzCgpUaGlzIHNlY3Rpb24gdGFrZXMgYSBtb3JlIGRldGFpbGVkIGxvb2sgYXQgdGhlIHZhcmlvdXMgc3RhZ2VzIG9mIHRoZSBwaXBlbGluZS4gVGhlIHZpZGVvIGJlbG93IHByb3ZpZGVzIGEgc3VtbWFyeSwgc2hvdWxkIHlvdSBmaW5kIGEgbmFycmF0ZWQgdHV0b3JpYWwgaGVscGZ1bC4KCjxpZnJhbWUgc3JjPSJodHRwczovL3BsYXllci52aW1lby5jb20vdmlkZW8vODE2OTI4NTczP2g9YjIzMzhkMjljYiZhbXA7dGl0bGU9MCZhbXA7YnlsaW5lPTAmYW1wO3BvcnRyYWl0PTAmYW1wO3NwZWVkPTAmYW1wO2JhZGdlPTAmYW1wO2F1dG9wYXVzZT0wJmFtcDtwbGF5ZXJfaWQ9MCZhbXA7YXBwX2lkPTU4NDc5IiB3aWR0aD0iNDgwIiBoZWlnaHQ9IjI3MCIgZnJhbWVib3JkZXI9IjAiIGFsbG93PSJhdXRvcGxheTsgZnVsbHNjcmVlbjsgcGljdHVyZS1pbi1waWN0dXJlIiBhbGxvd2Z1bGxzY3JlZW4gdGl0bGU9IkRhdGEgTWluaW5nIGFuZCBDUklTUC1ETSIgZGF0YS1leHRlcm5hbD0iMSI+Cgo8L2lmcmFtZT4KCiMjIyBTdGFnZSAxOiBCdXNpbmVzcyBVbmRlcnN0YW5kaW5nCgpBdCB0aGUgaW5pdGlhbCBzdGFnZSBvZiB0aGUgQ1JJU1AtRE0gcHJvY2VzcywgaXQgaXMgZXNzZW50aWFsIHRvIGRlZmluZSB0aGUgYnVzaW5lc3Mgb2JqZWN0aXZlcyBvZiB0aGUgZGF0YSBwcm9qZWN0IGFuZCB0byB1bmRlcnN0YW5kIGFueSBjb25zdHJhaW50cy4gVGhlIG9iamVjdGl2ZSBvZiB0aGlzIHBoYXNlIGlzIHRvIHJldmVhbCBrZXkgZmFjdG9ycyB0aGF0IG1pZ2h0IGltcGFjdCB0aGUgcHJvamVjdCdzIG91dGNvbWUuIEZhaWxpbmcgdG8gdW5kZXJ0YWtlIHRoaXMgc3RlcCBtYXkgbGVhZCB0byBleHBlbmRpbmcgc2lnbmlmaWNhbnQgZWZmb3J0IG9uIGdlbmVyYXRpbmcgY29ycmVjdCBhbnN3ZXJzIHRvIGlycmVsZXZhbnQgcXVlcmllcy4KCiMjIyMgRGVmaW5lIFByb2plY3QgT3V0Y29tZXMKCi0gICAqKlNldCBPYmplY3RpdmVzKio6IFRoaXMgaW52b2x2ZXMgZGVmaW5pbmcgeW91ciBwcmltYXJ5IGJ1c2luZXNzIG9iamVjdGl2ZXMsIHdoaWNoIGNvdWxkIGJlIGtlZXBpbmcgY3VycmVudCBjdXN0b21lcnMgYnkgcHJlZGljdGluZyB3aGVuIHRoZXkgbWF5IHN3aXRjaCB0byBhIGNvbXBldGl0b3IuIFlvdSBtYXkgYWxzbyBoYXZlIG90aGVyIHJlbGF0ZWQgcXVlc3Rpb25zIHRvIGFkZHJlc3MsIHN1Y2ggYXMgIkRvZXMgdGhlIG51bWJlciBvZiB0aW1lcyBhIGN1c3RvbWVyJ3MgdmlzaXRzIG91ciB3ZWJzaXRlIGltcGFjdCB0aGVpciBkZWNpc2lvbiB0byBhYmFuZG9uIHRoZWlyIHNob3BwaW5nIGNhcnQ/IiBvciAiV2lsbCByZWR1Y2luZyBzaGlwcGluZyBmZWVzIHNpZ25pZmljYW50bHkgaW5jcmVhc2UgdGhlIG51bWJlciBvZiBjdXN0b21lcnMgd2UgcmV0YWluPyIKCi0gICAqKlByb2R1Y2UgUHJvamVjdCBQbGFuKio6IEluIHRoaXMgcGhhc2UsIHRoZSBvdXRjb21lIGlzIGEgZGV0YWlsZWQgcGxhbiBmb3IgYXR0YWluaW5nIHRoZSBkYXRhIG1pbmluZyBhbmQgYnVzaW5lc3Mgb2JqZWN0aXZlcy4gVGhlIHBsYW4gc2hvdWxkIG91dGxpbmUgdGhlIHN0ZXBzIHRvIGJlIGV4ZWN1dGVkIHRocm91Z2hvdXQgdGhlIHJlbWFpbmRlciBvZiB0aGUgcHJvamVjdCwgaW5jbHVkaW5nIHRoZSBpbml0aWFsIHNlbGVjdGlvbiBvZiB0b29scyBhbmQgdGVjaG5pcXVlcy4gVGhpcyBpcyBjb21wYXJhYmxlIHRvIGEgcHJvamVjdCBwbGFuIGlzIHNvZnR3YXJlIHByb2plY3QgbWFuYWdlbWVudCBhbmQgY29tbW9ubHkgaW5jbHVkZXMgYSB0aW1lbGluZSwgdGFzayBsaXN0LCBhbmQgcGVyaGFwcyBjcml0aWNhbCBwYXRoIGFuYWx5c2lzLCB0YXNrIGFzc2lnbm1lbnRzLCBhbmQgY29zdCBhbmQgdGltZSBlc3RpbWF0ZXMuCgotICAgKipEZWZpbmUgU3VjY2VzcyBDcml0ZXJpYSoqOiBJbiB0aGUgIkJ1c2luZXNzIHN1Y2Nlc3MgY3JpdGVyaWEiIHN0YWdlLCB3ZSBkZWZpbmUgdGhlIGNyaXRlcmlhIHRoYXQgd2lsbCBiZSBhcHBsaWVkIHRvIGV2YWx1YXRlIHRoZSBwcm9qZWN0J3Mgc3VjY2VzcyBmcm9tIGEgYnVzaW5lc3MgcGVyc3BlY3RpdmUuIElkZWFsbHksIHRoZXNlIHNob3VsZCBiZSBwcmVjaXNlIGFuZCBxdWFudGlmaWFibGUsIHN1Y2ggYXMgYSBzcGVjaWZpYyBkZWNyZWFzZSBpbiBjdXN0b21lciBjaHVybiBieSBzb21lIHBvaW50IGluIHRpbWUuIFdoZW5ldmVyIHBvc3NpYmxlLCB0aGUgc3VjY2VzcyBjcml0ZXJpYSBtdXN0IGJlICpTTUFSVCosICppLmUuKiwgc3BlY2lmaWMsIG1lYXN1cmFibGUsIGF0dGFpbmFibGUsIHJlbGV2YW50LCBhbmQgdGltZS1iYXNlZC4gSG93ZXZlciwgaW4gc29tZSBjYXNlcywgc3ViamVjdGl2ZSBjcml0ZXJpYSBsaWtlICJwcm92aWRlIHZhbHVhYmxlIGluc2lnaHRzIGludG8gdGhlIHJlbGF0aW9uc2hpcHMiIG1heSBiZSBuZWNlc3NhcnkuIElmIHNvLCBpdCBpcyBjcnVjaWFsIHRvIHNwZWNpZnkgd2hvIHdpbGwgbWFrZSB0aGUgc3ViamVjdGl2ZSBhc3Nlc3NtZW50IGFuZCB3aGVuLgoKIyMjIyBBc3Nlc3MgQ3VycmVudCBTaXR1YXRpb24KClRoaXMgcGhhc2UgbmVjZXNzaXRhdGVzIGluLWRlcHRoIGluZm9ybWF0aW9uIGdhdGhlcmluZyBvbiBhbGwgcmVzb3VyY2VzLCByZXN0cmljdGlvbnMvY29uc3RyYWludHMsIGFzc3VtcHRpb25zLCBhbmQgb3RoZXIgdmFyaWFibGVzIHRoYXQgbXVzdCBiZSB0YWtlbiBpbnRvIGFjY291bnQgd2hpbGUgZXN0YWJsaXNoaW5nIHlvdXIgZGF0YSBhbmFseXNpcyBvYmplY3RpdmUgYW5kIHByb2plY3QgcGxhbi4KCjEuICAqKkludmVudG9yeSBvZiBSZXNvdXJjZXMqKjogSWRlbnRpZnkgdGhlIHJlc291cmNlcyBhdmFpbGFibGUgdG8gdGhlIHByb2plY3QgaW5jbHVkaW5nOgoKLSAgIFBlcnNvbm5lbCAoKmUuZy4qLCBzdWJqZWN0IG1hdHRlciBleHBlcnRzLCBkYXRhIHNjaWVudGlzdHMsIGRhdGEgZW5naW5lZXJzLCB0ZWNobmljYWwgc3VwcG9ydCkKLSAgIERhdGEgKCplLmcuKiwgdHJhbnNhY3Rpb25hbCBhbmQgYW5hbHl0aWNhbCBkYXRhYmFzZXMsIGRhdGEgZmlsZXMsIHRoaXJkLXBhcnR5IGRhdGEpCi0gICBDb21wdXRpbmcgUmVzb3VyY2VzICgqZS5nLiosIGhhcmR3YXJlIHBsYXRmb3JtcywgY2xvdWQgcGxhdGZvcm1zKQotICAgU29mdHdhcmUgKCplLmcuKiwgZGF0YSBtaW5pbmcgdG9vbHMsIG1hY2hpbmUgbGVhcm5pbmcgbW9kZWxzLCBkYXRhYmFzZSBtYW5hZ2VtZW50IHN5c3RlbXMsIHZpc3VhbGl6YXRpb24gcGFja2FnZXMpCgoyLiAgKipSZXF1aXJlbWVudHMsIEFzc3VtcHRpb25zIGFuZCBDb25zdHJhaW50cyoqOiBJZGVudGlmeSBhbGwgY3VycmVudCByZXF1aXJlbWVudHMgaW5jbHVkaW5nIHRoZSBzY2hlZHVsZSwgdXNlIGNhc2VzLCBxdWFsaXR5IG9mIHJlc3VsdHMsIGRhdGEgc2VjdXJpdHkgY29uY2VybnMsIGFzIHdlbGwgYXMgYW55IHBvdGVudGlhbCBsZWdhbCByYW1pZmljYXRpb25zLiBWZXJpZnkgb3duZXJzaGlwIG9mIG9yIGxpY2Vuc2UgdG8gdXNlIHRoZSBkYXRhLCBhbG9uZyB3aXRoIGFueSB1c2FnZSBjb25zdHJhaW50cy4gTGlzdCBhbnkgYXNzdW1wdGlvbnMgbWFkZSBieSB0aGUgcHJvamVjdCBzcG9uc29ycyBhbmQgc3Rha2Vob2xkZXJzLiBUaGVzZSBhc3N1bXB0aW9ucyBtYXkgcGVydGFpbiB0byB0aGUgZGF0YSwgd2hpY2ggY2FuIGJlIGNvbmZpcm1lZCBkdXJpbmcgZGF0YSBtaW5pbmcsIG9yIHRoZXkgbWF5IHJlbGF0ZSB0byB0aGUgYnVzaW5lc3MgYW5kIGNhbm5vdCBiZSB2ZXJpZmllZC4gSWYgdGhlIGxhdHRlciBhZmZlY3RzIHRoZSByZXN1bHRzJyB2YWxpZGl0eSwgaXQgaXMgY3J1Y2lhbCB0byBlbnVtZXJhdGUgdGhlbS4gRW51bWVyYXRlIHRoZSBwcm9qZWN0IGxpbWl0YXRpb25zLCB3aGljaCBjb3VsZCBiZSByZXN0cmljdGlvbnMgb24gcmVzb3VyY2UgYWNjZXNzaWJpbGl0eSBvciB0ZWNobm9sb2dpY2FsIGNvbnN0cmFpbnRzLCBzdWNoIGFzIHRoZSBwcmFjdGljYWxpdHkgb2YgdXNpbmcgYSBwYXJ0aWN1bGFyIGRhdGFzZXQgc2l6ZSBmb3IgbW9kZWxpbmcgcHVycG9zZXMuCgozLiAgKipSaXNrcyBhbmQgTWl0aWdhdGlvbioqOiBMaXN0IGFueSByaXNrcyBvciBhZHZlcnNlIGV2ZW50cyB0aGF0IG1pZ2h0IGRlbGF5IHRoZSBwcm9qZWN0IG9yIGNhdXNlIGl0IHRvIGZhaWwsIG9yIGltcGFjdCB0aGUgZGVsaXZlcmFibGUgb3Igc2NoZWR1bGUuIEZvciBlYWNoIGlkZW50aWZpZWQgcmlza3MsIGRlZmluZSBpdHMgbGlrZWxpaG9vZCBvZiBvY2N1cnJlbmNlIGFuZCBpdHMgaW1wYWN0IG9uIHRoZSBwcm9qZWN0LiBDcmVhdGUgcmlza3MgbWl0aWdhdGlvbiBzdHJhdGVnaWVzIGZvciBhbGwgaGlnaC1pbXBhY3Qgb3IgbGlrZWx5IHJpc2tzLiBEZWZpbmUgd2hhdCBhY3Rpb25zIHdvdWxkIG5lZWQgdG8gYmUgdGFrZW4gdG8gcmVkdWNlIGEgcmlzayBvciB0byBkZWFsIHdpdGggaXQgc2hvdWxkIGl0IG9jY3VyLgoKNC4gICoqVGVybWlub2xvZ3kqKjogQ29tcGlsZSBhIGdsb3NzYXJ5IG9mIHRlcm1zIHJlbGV2YW50IHRvIHRoZSBwcm9qZWN0IGFuZCBpdHMgc3Rha2Vob2xkZXJzLiBUaGUgZ2xvc3Nhcnkgc2hvdWxkIGVuY29tcGFzcyBhIGRlZmluaXRpb24gb2YgYWxsIHJlbGV2YW50IGJ1c2luZXNzIHRlcm1zLCB3aGljaCBmb3JtcyBwYXJ0IG9mIHRoZSBidXNpbmVzcyB1bmRlcnN0YW5kaW5nIGF2YWlsYWJsZSB0byB0aGUgcHJvamVjdC4gVGhlIGdsb3NzYXJ5IGlzIGdlbmVyYWxseSBhIGRlbGl2ZXJhYmxlIG9mIHRoZSByZXF1aXJlbWVudHMgZ2F0aGVyaW5nIGFuZCBlbGljaXRhdGlvbiBlZmZvcnRzLiBBZGRpdGlvbmFsbHksIHRoZSBwcm9qZWN0IHRlYW0gbXVzdCB3cml0ZSBhIGdsb3NzYXJ5IG9mIGRhdGEgbWluaW5nIHRlcm1zIHRvIGVuc3VyZSB0aGF0IGV2ZXJ5b25lIGhhcyB0aGUgc2FtZSB1bmRlcnN0YW5kaW5nIG9mIGRhdGEgbWluaW5nIHRlY2huaXF1ZXMgZW1wbG95ZWQgb24gdGhlIHByb2plY3QuCgo1LiAgKipDb3N0cyBhbmQgYmVuZWZpdHMqKjogQ3JlYXRlIGEgY29zdC1iZW5lZml0IGFuYWx5c2lzIHRoYXQgY29udHJhc3RzIHRoZSBwcm9qZWN0IGV4cGVuc2VzIHdpdGggdGhlIHBvdGVudGlhbCBidXNpbmVzcyBiZW5lZml0cyBpZiB0aGUgcHJvamVjdCBpcyBzdWNjZXNzZnVsLiBUaGlzIGNvbXBhcmlzb24gaXMgcGFydCBvZiB0aGUgYnVzaW5lc3MgY2FzZSBhbmQgc2hvdWxkIGJlIGFzIHByZWNpc2UgYXMgcG9zc2libGUsIHV0aWxpemluZyBmaW5hbmNpYWwgbWVhc3VyZXMuCgojIyMjIERldGVybWluZSBEYXRhIE1pbmluZyBPYmplY3RpdmVzCgpBIGJ1c2luZXNzIGdvYWwgc3RhdGVzIG9iamVjdGl2ZXMgdXNpbmcgbWVhc3VyZXMgdGhhdCBwcm92aWRlIGJ1c2luZXNzIHZhbHVlLiBUaGUgZGF0YSBtaW5pbmcgb2JqZWN0aXZlcyBleHByZXNzZXMgdGhlIHByb2plY3QncyB0ZWNobmljYWwgYWltcy4gRm9yIGluc3RhbmNlLCB0aGUgYnVzaW5lc3Mgb2JqZWN0aXZlIGNvdWxkIGJlICJFbmhhbmNlIGUtbWFpbCBtYXJrZXRpbmcgc2FsZXMgdG8gY3VycmVudCBjdXN0b21lcnMsIiB3aGVyZWFzIHRoZSBkYXRhIG1pbmluZyBvYmplY3RpdmUgbWlnaHQgYmUgIkZvcmVjYXN0IHRoZSBvcmRlciB0b3RhbCBmb3IgY3VzdG9tZXJzIGJhc2VkIG9uIHRoZWlyIHByZXZpb3VzIHRocmVlLXllYXIgcHVyY2hhc2UgaGlzdG9yeSwgZGVtb2dyYXBoaWMgZGF0YSAoKmUuZy4qLCBhZ2UsIHNhbGFyeSwgemlwIGNvZGUpLCBhbmQgaXRlbSBwcmljaW5nLiIgVGhlIGRhdGEgbWluaW5nIG9iamVjdGl2ZXMgYXJlIHVzZWQgdG8gcmVhbGl6ZSB0aGUgYnVzaW5lc3Mgb2JqZWN0aXZlcy4gRGF0YSBtaW5pbmcgc3VjY2VzcyBjcml0ZXJpYSBtaWdodCBpbmNsdWRlIGNlcnRhaW4gbGV2ZWxzIG9mIHByZWNpc2lvbiwgcmVjYWxsLCBhY2N1cmFjeSwgRjEtc2NvcmUsIGFtb25nIG90aGVyIHRlY2huaWNhbCBkYXRhIG1pbmluZyBtZXRyaWNzLgoKIyMjIyBQcm9qZWN0IFBsYW4KClRoZSBwcm9qZWN0IHBsYW4gZGVmaW5lcyBob3cgdGhlIHByb2plY3Qgd2lsbCBiZSBjYXJyaWVkIG91dCwgaW5jbHVkaW5nIHdoaWNoIHRlYW0gbWVtYmVycyB3aWxsIGRvIHdoaWNoIGFjdGl2aXRpZXMgYW5kIHRhc2tzLCB3aGljaCB0b29scyBhcmUgdG8gYmUgdXNlZCwgYW5kIHdoZW4gZGVsaXZlcmFibGVzIGFyZSBkdWUuCgpGb3IgdGhlIHByb2plY3QgdGFza3MsIGRlZmluZSB0aGVpciBkdXJhdGlvbiwgcmVxdWlyZWQgcmVzb3VyY2VzIGFuZCB0b29scywgaW5wdXRzLCBvdXRwdXRzLCBhbmQgdGFzayBkZXBlbmRlbmNpZXMuIFdoZXJlIHBvc3NpYmxlLCB0cnkgYW5kIG1ha2UgZXhwbGljaXQgdGhlIGxhcmdlLXNjYWxlIGl0ZXJhdGlvbnMgaW4gdGhlIGRhdGEgbWluaW5nIHByb2Nlc3MsIGZvciBleGFtcGxlLCByZXBldGl0aW9ucyBvZiB0aGUgbW9kZWxsaW5nIGFuZCBldmFsdWF0aW9uIHBoYXNlcy4gQXMgcGFydCBvZiB0aGUgcHJvamVjdCBwbGFuLCBpdCBpcyBhbHNvIGltcG9ydGFudCB0byBhbmFseXplIGRlcGVuZGVuY2llcyBiZXR3ZWVuIHRpbWUgc2NoZWR1bGUgYW5kIHJpc2tzLiBNYXJrIHJlc3VsdHMgb2YgdGhlc2UgYW5hbHlzZXMgZXhwbGljaXRseSBpbiB0aGUgcHJvamVjdCBwbGFuLCBpZGVhbGx5IHdpdGggYWN0aW9ucyBhbmQgcmVjb21tZW5kYXRpb25zIGlmIHRoZSByaXNrcyBhcmUgbWFuaWZlc3RlZC4gRGVjaWRlIGF0IHRoaXMgcG9pbnQgd2hpY2ggZXZhbHVhdGlvbiBzdHJhdGVneSB3aWxsIGJlIHVzZWQgaW4gdGhlIGV2YWx1YXRpb24gcGhhc2UuIFlvdXIgcHJvamVjdCBwbGFuIHdpbGwgYmUgYSBkeW5hbWljIGRvY3VtZW50LgoKQXQgdGhlIGVuZCBvZiBlYWNoIHBoYXNlIHlvdSdsbCByZXZpZXcgcHJvZ3Jlc3MgYW5kIGFjaGlldmVtZW50cyBhbmQgdXBkYXRlIHRoZSBwcm9qZWN0IHBsYW4gYWNjb3JkaW5nbHkuIFNwZWNpZmljIHJldmlldyBwb2ludHMgZm9yIHRoZXNlIHVwZGF0ZXMgc2hvdWxkIGJlIHBhcnQgb2YgdGhlIHByb2plY3QgcGxhbi4gSW5pdGlhbCBhc3Nlc3NtZW50IG9mIHRvb2xzIGFuZCB0ZWNobmlxdWVzIC0tIEF0IHRoZSBlbmQgb2YgdGhlIGZpcnN0IHBoYXNlIHlvdSBzaG91bGQgdW5kZXJ0YWtlIGFuIGluaXRpYWwgYXNzZXNzbWVudCBvZiB0b29scyBhbmQgdGVjaG5pcXVlcy4gSGVyZSwgZm9yIGV4YW1wbGUsIHlvdSBzZWxlY3QgYSBkYXRhIG1pbmluZyB0b29sIHRoYXQgc3VwcG9ydHMgdmFyaW91cyBtZXRob2RzIGZvciBkaWZmZXJlbnQgc3RhZ2VzIG9mIHRoZSBwcm9jZXNzLiBJdCBpcyBpbXBvcnRhbnQgdG8gYXNzZXNzIHRvb2xzIGFuZCB0ZWNobmlxdWVzIGVhcmx5IGluIHRoZSBwcm9jZXNzIHNpbmNlIHRoZSBzZWxlY3Rpb24gb2YgdG9vbHMgYW5kIHRlY2huaXF1ZXMgbWF5IGluZmx1ZW5jZSB0aGUgZW50aXJlIHByb2plY3QuCgojIyMgU3RhZ2UgMjogRGF0YSBVbmRlcnN0YW5kaW5nCgpUaGUgc2Vjb25kIHBoYXNlIG9mIHRoZSBDUklTUC1ETSBwcm9jZXNzIGVudGFpbHMgb2J0YWluaW5nIHRoZSBkYXRhIGluZGljYXRlZCBpbiB0aGUgcHJvamVjdCByZXNvdXJjZXMuIFRoaXMgaW5pdGlhbCBjb2xsZWN0aW9uIG1heSBpbnZvbHZlIGRhdGEgbG9hZGluZywgZXNwZWNpYWxseSBpZiBpdCBhaWRzIGluIGRhdGEgY29tcHJlaGVuc2lvbi4gRm9yIGluc3RhbmNlLCBpZiBhIHBhcnRpY3VsYXIgdG9vbCBpcyB1dGlsaXplZCBmb3IgZGF0YSB1bmRlcnN0YW5kaW5nLCBpdCBpcyBsb2dpY2FsIHRvIHVwbG9hZCB0aGUgZGF0YSBpbnRvIHRoYXQgdG9vbC4gSWYgdGhlcmUgYXJlIG11bHRpcGxlIGRhdGEgc291cmNlcywgaXQgaXMgY3J1Y2lhbCB0byBjb250ZW1wbGF0ZSBob3cgYW5kIHdoZW4gdGhleSB3aWxsIGJlIGludGVncmF0ZWQuCgpBIGtleSBkZWxpdmVyYWJsZSBpcyB0aGUgKipkYXRhIGNvbGxlY3Rpb24gcmVwb3J0Kiogd2hpY2ggaWRlbnRpZmllcyB0aGUgc291cmNlcyBvZiBkYXRhLCB0aGVpciBsb2NhdGlvbnMsIGFuZCB0aGUgbWV0aG9kcyBuZWNlc3NhcnkgdG8gcmV0cmlldmUgdGhlIGRhdGEsIGluIGFkZGl0aW9uIHRvIGFueSBkYXRhIGNvbGxlY3Rpb24gcmlza3MuCgojIyMjIERlc2NyaWJlIERhdGEKCkFtb25nIHRoZSBmaXJzdCBzdGVwcyBpbiB1bmRlcnN0YW5kaW5nIHRoZSBkYXRhIGlzIHRvIGV4YW1pbmUgdGhlIGRhdGEncyBwcm9wZXJ0aWVzLCAqaS5lLiosIGhvdyBtYW55IGluc3RhbmNlcywgaG93IG1hbnkgdmFyaWFibGVzLCB3aGF0IGtpbmRzIG9mIHZhcmlhYmxlcyAoY2F0ZWdvcmljYWwsIG51bWVyaWMsIHRleHR1YWwpLCBhbmQgdGhlIGZvcm1hdCBvZiB0aGUgZGF0YS4KCkEga2V5IGluc2lnaHQgZnJvbSB0aGlzIHN0ZXAgaXMgdG8ga25vdyB3aGV0aGVyIHRoZSByaWdodCBkYXRhIGlzIGF2YWlsYWJsZSB0byBhZGRyZXNzIHRoZSBidXNpbmVzcyBvYmplY3RpdmVzIGFuZCB3aGV0aGVyIHRoZXJlIGlzIHN1ZmZpY2llbnQgZGF0YSB0byBidWlsZCBwcmVkaWN0aXZlIG1vZGVscy4KCkV4YW1pbmUgdGhlICJncm9zcyIgb3IgInN1cmZhY2UiIHByb3BlcnRpZXMgb2YgdGhlIGFjcXVpcmVkIGRhdGEgYW5kIHJlcG9ydCBvbiB0aGUgcmVzdWx0cy4KCiMjIyMgRXhwbG9yZSBEYXRhCgpJbiB0aGlzIHN0YWdlIHRoZSBkYXRhIGFuYWx5c2lzIHRlYW0gYWRkcmVzc2VzIGluaXRpYWwsIGhpZ2gtbGV2ZWwgZGF0YSBtaW5pbmcgcXVlc3Rpb25zIHVzaW5nIGRhdGEgcXVlcmllcywgZGVzY3JpcHRpdmUgc3RhdGlzdGljcywgYW5kIGV4cGxvcmF0b3J5IGRhdGEgdmlzdWFsaXphdGlvbnMuIEV4cGxvcmF0b3J5IGFuYWx5c2lzIGZvY3VzZXMgY2hpZWZseSBvbiB0aGUgZGlzdHJpYnV0aW9uIG9mIHRhcmdldCBhbmQgcHJlZGljdG9yIHZhcmlhYmxlcyBhbmQgY29ycmVsYXRpb25zLiBPZnRlbiwgc2ltcGxlIGFnZ3JlZ2F0aW9ucyBzdWNoIGFzIHN1bXMgYW5kIG1lYW5zIGFyZSBleHBsb3JlZCwgYWxvbmcgd2l0aCB2YXJpYW5jZSBhbmQgY28tdmFyaWFuY2UuCgpBIGtleSBwcm9qZWN0IGRlbGl2ZXJhYmxlIGlzIHRoZSAqKkRhdGEgRXhwbG9yYXRpb24gUmVwb3J0Kiogd2hpY2ggY29udGFpbnMgdGhlIHJlc3VsdHMgb2YgdGhlIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMsIGluY2x1ZGluZyBrZXkgZmluZGluZ3MgYW5kIGluaXRpYWwgaHlwb3RoZXNpcyBhbmQgd2hldGhlciB0aG9zZSBtaWdodCBpbXBhY3QgdGhlIHJlbWFpbmRlciBvZiB0aGUgcHJvamVjdDsgb3IgZXZlbiBpZiB0aGUgcHJvamVjdCBzaG91bGQgYmUgdGVybWluYXRlZCBhdCB0aGlzIHBvaW50LiBUbyBzb21lIGV4dGVudCwgdGhpcyBzdGVwIGlzIGEgImdhdGUga2VlcGluZyIgYWN0IHdpdGggYSAiZ28vbm8tZ28iIGRlY2lzaW9uLgoKSXQgaXMgY29tbW9uIHRvIGluY2x1ZGUgaW5pdGlhbCBleHBsb3JhdG9yeSBhbmFseXNpcyByZXN1bHRzIGluIHRoZSByZXBvcnQsIGluY2x1ZGluZyBleHBsb3JhdG9yeSB2aXN1YWxpemF0aW9ucywgZ3JhcGhzIGFuZCBwbG90cyB0byBzaG93IGRhdGEgY2hhcmFjdGVyaXN0aWNzLCBhbmQgcG9zc2libGUgZnV0dXJlIGFyZWFzIG9mIG1vcmUgZGV0YWlsZWQgZXhhbWluYXRpb24gb2YgcmVsZXZhbnQgYW5kIGludGVyZXN0aW5nIHN1YnNldHMgb2YgdGhlIGRhdGEuCgojIyMjIEV2YWx1YXRlIERhdGEgUXVhbGl0eQoKSXQgaXMgZXNzZW50aWFsIHRvIGNvbmR1Y3QgYW4gZXZhbHVhdGlvbiBvZiBkYXRhIHF1YWxpdHksIHdoaWxlIGNvbnNpZGVyaW5nIHBlcnRpbmVudCBpc3N1ZXMgc3VjaCBhczoKCi0gICBEb2VzIHRoZSBkYXRhIGVuY29tcGFzcyBhbGwgdGhlIG5lY2Vzc2FyeSBjYXNlcywgb3IgaXMgaXQgaW5jb21wbGV0ZT8KLSAgIElzIHRoZSBkYXRhIGFjY3VyYXRlLCBvciBkb2VzIGl0IGNvbnRhaW4gbWlzdGFrZXM/IElmIHNvLCB3aGF0IGlzIHRoZSBleHRlbnQgb2YgdGhlc2UgZXJyb3JzPwotICAgQXJlIHRoZXJlIGFueSBvbWlzc2lvbnMgaW4gdGhlIGRhdGE/IElmIHByZXNlbnQsIGhvdyBhcmUgdGhleSBpbmRpY2F0ZWQsIHdoZXJlIGRvIHRoZXkgYXJpc2UsIGFuZCBob3cgZnJlcXVlbnQgYXJlIHRoZXk/CgpBbmFseXN0cyBnZW5lcmFsbHkgZW51bWVyYXRlIHRoZSBvdXRjb21lcyBvZiB0aGUgZGF0YSBxdWFsaXR5IHZhbGlkYXRpb24gaW4gYSByZXBvcnQuIEluIGNhc2VzIHdoZXJlIHF1YWxpdHkgaXNzdWVzIGFyZSBhcHBhcmVudCwgaXQgaXMgaGVscGZ1bCB0byByZWNvbW1lbmQgYXBwbGljYWJsZSBhbmQgYXBwcm9wcmlhdGUgcmVtZWRpZXMgYW5kIGltcHV0YXRpb24gc3RyYXRlZ2llcy4gQWRkcmVzc2luZyBkYXRhIHF1YWxpdHkgcHJvYmxlbXMgb3JkaW5hcmlseSByZWxpZXMgb24gYSBjb21iaW5hdGlvbiBvZiBleHBlcnRpc2UgaW4gZGF0YSBhbmFseXRpY3MgYW5kIHRoZSBidXNpbmVzcyBkb21haW4uCgojIyMgU3RhZ2UgMzogRGF0YSBQcmVwYXJhdGlvbgoKIyMjIyBTZWxlY3QgRGF0YQoKVGhlIGRhdGEgc2VsZWN0aW9uIHBoYXNlIG9mIGEgcHJvamVjdCBpbnZvbHZlcyBtYWtpbmcgaW5mb3JtZWQgY2hvaWNlcyBhYm91dCB0aGUgZGF0YXNldCB0byBiZSBhbmFseXplZCwgYmFzZWQgb24gdmFyaW91cyBmYWN0b3JzIGluY2x1ZGluZyB0aGUgcGVydGluZW5jZSBvZiB0aGUgZGF0YSB0byB0aGUgZGF0YSBtaW5pbmcgb2JqZWN0aXZlcywgdGhlIGRhdGEgcXVhbGl0eSwgYW5kIHRlY2huaWNhbCBjb25zdHJhaW50cyBzdWNoIGFzIGRhdGEgc2l6ZSBhbmQgZm9ybWF0LiBJdCBpcyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IGRhdGEgc2VsZWN0aW9uIGVuY29tcGFzc2VzIHRoZSBjaG9pY2Ugb2YgYm90aCBhdHRyaWJ1dGVzIChjb2x1bW5zKSBhbmQgcmVjb3JkcyAocm93cykgd2l0aGluIGEgdGFibGUuCgpUbyBqdXN0aWZ5IHRoZSBpbmNsdXNpb24gb3IgZXhjbHVzaW9uIG9mIGRhdGEsIGl0IGlzIG5lY2Vzc2FyeSB0byBwcm92aWRlIGEgcmF0aW9uYWxlIGZvciB0aGVzZSBkZWNpc2lvbnMuIFRoaXMgaW52b2x2ZXMgZG9jdW1lbnRpbmcgdGhlIGxpc3Qgb2Ygc2VsZWN0ZWQgYW5kIG9taXR0ZWQgZGF0YSwgYWxvbmcgd2l0aCB0aGUgcmVhc29ucyB0aGF0IGluZm9ybWVkIHRoZXNlIGRlY2lzaW9ucy4KCiMjIyMgQ2xlYW4gRGF0YQoKVGhlIG5leHQgdGFzayBmb2N1c2VzIG9uIGVuaGFuY2luZyB0aGUgcXVhbGl0eSBvZiB0aGUgZGF0YSB0byBtZWV0IHRoZSByZXF1aXJlbWVudHMgb2YgdGhlIHNlbGVjdGVkIGFuYWx5c2lzIHRlY2huaXF1ZXMgYW5kIGRhdGEgbWluaW5nIGFsZ29yaXRobXMuIFRoaXMgbWF5IGVudGFpbCBzZWxlY3RpbmcgY2xlYW4gc3Vic2V0cyBvZiB0aGUgZGF0YSwgaW50cm9kdWNpbmcgYXBwcm9wcmlhdGUgZGVmYXVsdCB2YWx1ZXMsIGlkZW50aWZ5aW5nIGNvcnJ1cHRlZCBkYXRhLCBvciBpbXBsZW1lbnRpbmcgbW9yZSBjb21wbGV4IHByb2NlZHVyZXMgc3VjaCBhcyBtb2RlbGxpbmcgdG8gaW1wdXRlIG1pc3NpbmcgZGF0YS4gVGhlIHByb2Nlc3MgbXVzdCBiZSByZXByb2R1Y2libGUuCgpUbyBkb2N1bWVudCB0aGUgc3RlcHMgdGFrZW4gdG8gYWRkcmVzcyBkYXRhIHF1YWxpdHkgaXNzdWVzLCBpdCBpcyBuZWNlc3NhcnkgdG8gY3JlYXRlIGEgcmVwb3J0IG91dGxpbmluZyB0aGUgZGVjaXNpb25zIGFuZCBhY3Rpb25zIHRha2VuIGluIHRlcm1zIG9mIGRhdGEgY2xlYW5pbmcuIFRoaXMgcmVwb3J0IHNob3VsZCBkZXRhaWwgYW55IHRyYW5zZm9ybWF0aW9ucyBhcHBsaWVkIHRvIHRoZSBkYXRhIGZvciB0aGUgcHVycG9zZXMgb2YgY2xlYW5pbmcgYW5kIHRoZWlyIHBvdGVudGlhbCBpbXBhY3Qgb24gdGhlIHJlc3VsdHMgb2YgdGhlIGFuYWx5c2lzLgoKIyMjIyBUcmFuc2Zvcm0gYW5kIERlcml2ZSBEYXRhCgpPbmNlIHRoZSBkYXRhIGhhcyBiZWVuIGNsZWFuLCBhZGRpdGlvbmFsIGRhdGEgcHJlcGFyYXRpb24gb3BlcmF0aW9ucyBjYW4gYmUgcGVyZm9ybWVkLCBpbmNsdWRpbmcgdGhlIGNyZWF0aW9uIG9mIGRlcml2ZWQgYXR0cmlidXRlcywgYWRkaXRpb25hbCByZWNvcmRzLCBvciB0cmFuc2Zvcm1lZCB2YWx1ZXMgZm9yIGV4aXN0aW5nIGF0dHJpYnV0ZXMuCgpEZXJpdmVkIGF0dHJpYnV0ZXMgcmVmZXIgdG8gbmV3IHZhcmlhYmxlcyBjb25zdHJ1Y3RlZCBmcm9tIG9uZSBvciBtb3JlIHByZS1leGlzdGluZyBhdHRyaWJ1dGVzIHdpdGhpbiB0aGUgc2FtZSByZWNvcmQgdXNpbmcgc29tZSBmb3JtdWxhIG9yIHJ1bGUuIEZvciBpbnN0YW5jZSwgdGhlIHZhcmlhYmxlcyBvZiAqbGVuZ3RoKiBhbmQgKndpZHRoKiBtaWdodCBiZSB1c2VkIHRvIGRlcml2ZSBhIG5ldyBhdHRyaWJ1dGUgb2YgKmFyZWEqLgoKR2VuZXJhdGVkIHJlY29yZHMgZGVzY3JpYmUgdGhlIHByb2Nlc3Mgb2YgY3JlYXRpbmcgZW50aXJlbHkgbmV3IHJlY29yZHMuIEZvciBpbnN0YW5jZSwgaXQgbWF5IGJlIG5lY2Vzc2FyeSB0byBjcmVhdGUgcmVjb3JkcyBmb3IgY3VzdG9tZXJzIHdobyBkaWQgbm90IG1ha2UgYW55IHB1cmNoYXNlcyBpbiB0aGUgcGFzdCB5ZWFyLCBldmVuIHRob3VnaCBzdWNoIHJlY29yZHMgd2VyZSBub3QgcHJlc2VudCBpbiB0aGUgcmF3IGRhdGEuIFJlcHJlc2VudGluZyB0aGUgZmFjdCB0aGF0IGNlcnRhaW4gY3VzdG9tZXJzIG1hZGUgemVybyBwdXJjaGFzZXMgbWF5IGJlIGNyaXRpY2FsIGZvciBtb2RlbGxpbmcgcHVycG9zZXMgYW5kIHRvIGVuc3VyZSB0aGF0IGRhdGEgbWluaW5nIGFsZ29yaXRobXMgcHJvZHVjZSByZWFzb25hYmxlIHZhbHVlcy4KCiMjIyMgSW50ZWdyYXRlIERhdGEKCkRhdGEgaW50ZWdyYXRpb24gaW52b2x2ZXMgY29tYmluaW5nIGluZm9ybWF0aW9uIGZyb20gbXVsdGlwbGUgZGF0YSBzb3VyY2VzLCBmaWxlcywgdGFibGVzLCBvciBleHRlcm5hbCBkYXRhYmFzZXMgdG8gY3JlYXRlIG5ldyB2YWx1ZXMgb3IgcmVjb3Jkcy4KCk1lcmdlZCBkYXRhIHJlZmVycyB0byB0aGUgcHJvY2VzcyBvZiBqb2luaW5nIHR3byBvciBtb3JlIHNvdXJjZXMgdGhhdCBjb250YWluIGRpZmZlcmVudCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc2FtZSBvYmplY3RzLiBGb3IgaW5zdGFuY2UsIGEgcmV0YWlsIGNoYWluIG1heSBoYXZlIHNlcGFyYXRlIGRhdGFiYXNlcyBjb250YWluaW5nIGluZm9ybWF0aW9uIGFib3V0IGVhY2ggc3RvcmUncyBjaGFyYWN0ZXJpc3RpY3MsIHN1bW1hcml6ZWQgc2FsZXMgZGF0YSwgYW5kIGRlbW9ncmFwaGljcyBvZiB0aGUgc3Vycm91bmRpbmcgYXJlYS4gVGhlc2UgZGF0YWJhc2VzIGNhbiBiZSBtZXJnZWQgaW50byBhIG5ldyBkYXRhYmFzZSB3aXRoIG9uZSByZWNvcmQgZm9yIGVhY2ggc3RvcmUsIGNvbWJpbmluZyByZWxldmFudCBmaWVsZHMgZnJvbSB0aGUgc291cmNlIGRhdGFiYXNlcy4KCkFnZ3JlZ2F0aW9ucyBpbnZvbHZlIGNvbXB1dGluZyBuZXcgdmFsdWVzIGJ5IHN1bW1hcml6aW5nIGluZm9ybWF0aW9uIGZyb20gbXVsdGlwbGUgcmVjb3JkcyBhbmQvb3IgdGFibGVzLiBGb3IgaW5zdGFuY2UsIGEgdGFibGUgb2YgY3VzdG9tZXIgcHVyY2hhc2VzIHdpdGggb25lIHJlY29yZCBmb3IgZWFjaCBwdXJjaGFzZSBjYW4gYmUgdHJhbnNmb3JtZWQgaW50byBhIG5ldyB0YWJsZSB3aXRoIG9uZSByZWNvcmQgZm9yIGVhY2ggY3VzdG9tZXIsIGNvbnRhaW5pbmcgZmllbGRzIHN1Y2ggYXMgbnVtYmVyIG9mIHB1cmNoYXNlcywgYXZlcmFnZSBwdXJjaGFzZSBhbW91bnQsIHBlcmNlbnRhZ2Ugb2Ygb3JkZXJzIGNoYXJnZWQgdG8gY3JlZGl0IGNhcmQsIGFuZCBwZXJjZW50YWdlIG9mIGl0ZW1zIHB1cmNoYXNlZCBkdXJpbmcgYSBwcm9tb3Rpb24uCgojIyMgU3RhZ2UgNDogTW9kZWwgU2VsZWN0aW9uCgpUaGUgaW5pdGlhbCBzdGFnZSBvZiBtb2RlbGluZyBpbnZvbHZlcyBzZWxlY3RpbmcgdGhlIHNwZWNpZmljIHRlY2huaXF1ZSB0aGF0IHdpbGwgYmUgdXNlZCBmb3IgYW5hbHlzaXMsIGV2ZW4gaWYgYSB0b29sIHdhcyBhbHJlYWR5IHNlbGVjdGVkIGluIHRoZSBCdXNpbmVzcyBVbmRlcnN0YW5kaW5nIHBoYXNlLiBBcyBhbiBleGFtcGxlLCB0aGUgYW5hbHlzaXMgdGVhbSBtYXkgbmVlZCB0byBjaG9vc2UgYSBwcm9wZXIgY2xhc3NpZmljYXRpb24gdGVjaG5pcXVlIGFuZCBuZWVkIHRvIGRldGVybWluZSB3aGV0aGVyIHRvIHVzZSBhIGRlY2lzaW9uLXRyZWUgY29uc3RydWN0ZWQgd2l0aCBDNS4wIG9yIGEgY2xhc3NpZmljYXRpb24gbW9kZWwgYnVpbHQgZnJvbSBuZXVyYWwgbmV0d29yayBnZW5lcmF0aW9uIHdpdGggYmFjayBwcm9wYWdhdGlvbi4gSXQgaXMgaW1wb3J0YW50IHRvIHBlcmZvcm0gdGhpcyB0YXNrIHNlcGFyYXRlbHkgZm9yIGVhY2ggbW9kZWxsaW5nIHRlY2huaXF1ZSB0aGF0IHdpbGwgYmUgYXBwbGllZC4KClRoZSBzZWxlY3RlZCBtb2RlbGxpbmcgdGVjaG5pcXVlcyBzaG91bGQgYmUgZG9jdW1lbnRlZCBpbiBkZXRhaWwgYW5kIHRoZWlyIHRyYWluaW5nIG11c3QgYmUgcmVwcm9kdWNpYmxlLgoKSXQgaXMgY3J1Y2lhbCB0byBjb25zaWRlciB0aGUgYXNzdW1wdGlvbnMgbWFkZSBieSB0aGUgY2hvc2VuIG1vZGVsbGluZyB0ZWNobmlxdWUgcmVnYXJkaW5nIHRoZSBkYXRhLiBNYW55IG1vZGVsbGluZyB0ZWNobmlxdWVzIG1ha2Ugc3BlY2lmaWMgYXNzdW1wdGlvbnMgYWJvdXQgdGhlIGRhdGEsIHN1Y2ggYXMgcmVxdWlyaW5nIGFsbCBhdHRyaWJ1dGVzIHRvIGhhdmUgbm9ybWFsIGRpc3RyaWJ1dGlvbnMsIGRpc2FsbG93aW5nIG1pc3NpbmcgdmFsdWVzLCBhbmQgcmVxdWlyaW5nIHRoZSBjbGFzcyBhdHRyaWJ1dGUgdG8gYmUgY2F0ZWdvcmljYWwuIEFsbCBtb2RlbGxpbmcgYXNzdW1wdGlvbnMgbWFkZSBtdXN0IGJlIHJlY29yZGVkLgoKIyMjIyBEZXNpZ24gTW9kZWwgVGVzdGluZyBhbmQgVmFsaWRhdGlvbgoKQmVmb3JlIGNvbnN0cnVjdGluZyBhIG1vZGVsLCBpdCBpcyBuZWNlc3NhcnkgdG8gZGV2ZWxvcCBhIG1lY2hhbmlzbSBvciBwcm9jZWR1cmUgdG8gZXZhbHVhdGUgaXRzIHF1YWxpdHkgYW5kIHZhbGlkaXR5LiBJbiBzdXBlcnZpc2VkIGRhdGEgbWluaW5nIHRhc2tzLCBzdWNoIGFzIGNsYXNzaWZpY2F0aW9uLCBlcnJvciByYXRlcyBhcmUgY29tbW9ubHkgdXNlZCBhcyBxdWFsaXR5IG1lYXN1cmVzIGZvciBkYXRhIG1pbmluZyBtb2RlbHMuIEFzIHN1Y2gsIGl0IGlzIGN1c3RvbWFyeSB0byBzcGxpdCB0aGUgZGF0YXNldCBpbnRvIHRyYWluaW5nIGFuZCB0ZXN0aW5nIHNldHMsIGNvbnN0cnVjdGluZyB0aGUgbW9kZWwgb24gdGhlIHRyYWluaW5nIHNldCwgYW5kIGFzc2Vzc2luZyBpdHMgcXVhbGl0eSBvbiB0aGUgc2VwYXJhdGUgdGVzdGluZyBzZXQuCgpUbyB0cmFpbiwgdGVzdCwgYW5kIGV2YWx1YXRlIHRoZSBtb2RlbHMgZWZmZWN0aXZlbHksIGEgY29tcHJlaGVuc2l2ZSBwbGFuIG11c3QgYmUgZXN0YWJsaXNoZWQuIEEga2V5IGNvbXBvbmVudCBvZiB0aGlzIHBsYW4gaXMgZGV0ZXJtaW5pbmcgaG93IHRvIHBhcnRpdGlvbiB0aGUgYXZhaWxhYmxlIGRhdGFzZXQgaW50byB0cmFpbmluZywgdGVzdGluZywgYW5kIHZhbGlkYXRpb24gZGF0YXNldHMuIFRoZSBwbGFuIHNob3VsZCBvdXRsaW5lIHRoZSBzcGVjaWZpYyBtZXRob2RzIGFuZCBtZXRyaWNzIHRoYXQgd2lsbCBiZSBlbXBsb3llZCB0byBhc3Nlc3MgdGhlIG1vZGVsJ3MgYWNjdXJhY3kgYW5kIHBlcmZvcm1hbmNlLiBJdCBzaG91bGQgYWxzbyBhZGRyZXNzIGFueSBwb3RlbnRpYWwgYmlhc2VzIG9yIGxpbWl0YXRpb25zIGluIHRoZSBkYXRhIGFuZCBlbnN1cmUgdGhhdCB0aGUgbW9kZWxzIGFyZSBldmFsdWF0ZWQgaW4gYSBmYWlyIGFuZCB1bmJpYXNlZCBtYW5uZXIuCgojIyMjIENvbnN0cnVjdCBNb2RlbAoKUnVubmluZyB0aGUgbW9kZWxsaW5nIHRvb2wgb24gdGhlIHByZXBhcmVkIGRhdGFzZXQgaW52b2x2ZXMgY3JlYXRpbmcgb25lIG9yIG1vcmUgbW9kZWxzIGZvciBhbmFseXNpcy4KClBhcmFtZXRlciBzZXR0aW5ncyBmb3IgdGhlIG1vZGVsbGluZyB0b29sIHNob3VsZCBiZSBkb2N1bWVudGVkLCBpbmNsdWRpbmcgdGhlIHZhbHVlcyBjaG9zZW4gZm9yIGVhY2ggcGFyYW1ldGVyIGFuZCB0aGUgcmVhc29uaW5nIGJlaGluZCB0aGVpciBzZWxlY3Rpb24uIFRoZSBwYXJhbWV0ZXIgc2V0dGluZ3Mgd2lsbCB2YXJ5IGRlcGVuZGluZyBvbiB0aGUgc3BlY2lmaWMgbW9kZWxsaW5nIHRvb2wgYW5kIHRlY2huaXF1ZSB1c2VkLgoKVGhlIHJlc3VsdGluZyBtb2RlbHMgY3JlYXRlZCBieSB0aGUgbW9kZWxsaW5nIHRvb2wgc2hvdWxkIGJlIGRvY3VtZW50ZWQsIGluY2x1ZGluZyBhbGwgcmVsZXZhbnQgZGV0YWlscyBhYm91dCB0aGUgbW9kZWxzLgoKTW9kZWwgZGVzY3JpcHRpb25zIHNob3VsZCBiZSBwcm92aWRlZCwgaW5jbHVkaW5nIGFueSBpbnRlcnByZXRhdGlvbiBvZiB0aGUgbW9kZWxzLCBkaWZmaWN1bHRpZXMgZW5jb3VudGVyZWQgZHVyaW5nIHRoZWlyIGFuYWx5c2lzLCBhbmQgcG90ZW50aWFsIGxpbWl0YXRpb25zIG9yIGJpYXNlcy4gQSBjb21wcmVoZW5zaXZlIHJlcG9ydCBzaG91bGQgYmUgY3JlYXRlZCwgb3V0bGluaW5nIHRoZSBmaW5kaW5ncyBhbmQgaW5zaWdodHMgZ2FpbmVkIGZyb20gdGhlIG1vZGVscywgYXMgd2VsbCBhcyBhbnkgcmVjb21tZW5kYXRpb25zIGZvciBmdXR1cmUgYW5hbHlzaXMuCgojIyMjIEV2YWx1YXRlIE1vZGVsCgpJbnRlcnByZXRpbmcgdGhlIG1vZGVscyBhY2NvcmRpbmcgdG8gZG9tYWluIGtub3dsZWRnZSwgZGF0YSBtaW5pbmcgc3VjY2VzcyBjcml0ZXJpYSwgYW5kIGRlc2lyZWQgdGVzdCBkZXNpZ24gaXMgYSBjcml0aWNhbCBzdGVwIGluIGV2YWx1YXRpbmcgdGhlIHN1Y2Nlc3Mgb2YgbW9kZWxsaW5nIGFuZCBkaXNjb3ZlcnkgdGVjaG5pcXVlcy4gSXQgaXMgZXNzZW50aWFsIHRvIGFzc2VzcyB0aGUgdGVjaG5pY2FsIGFzcGVjdHMgb2YgdGhlIG1vZGVscyBhbmQgcmFuayB0aGVtIGFjY29yZGluZ2x5LCB3aGlsZSBhbHNvIGNvbnNpZGVyaW5nIHRoZSBidXNpbmVzcyBvYmplY3RpdmVzIGFuZCBzdWNjZXNzIGNyaXRlcmlhLgoKVGhlIG1vZGVscyBzaG91bGQgYmUgYXNzZXNzZWQgaW4gdGVybXMgb2YgdGhlaXIgcXVhbGl0aWVzLCBzdWNoIGFzIGFjY3VyYWN5LCBhbmQgcmFua2VkIGluIHJlbGF0aW9uIHRvIG9uZSBhbm90aGVyLiBUaGUgcmVzdWx0cyBvZiB0aGlzIHRhc2sgc2hvdWxkIGJlIHN1bW1hcmlzZWQsIGhpZ2hsaWdodGluZyB0aGUgc3RyZW5ndGhzIGFuZCBsaW1pdGF0aW9ucyBvZiB0aGUgZ2VuZXJhdGVkIG1vZGVscy4KCkJhc2VkIG9uIHRoZSBtb2RlbCBhc3Nlc3NtZW50LCBwYXJhbWV0ZXIgc2V0dGluZ3MgbWF5IG5lZWQgdG8gYmUgcmV2aXNlZCBhbmQgdHVuZWQgZm9yIHRoZSBuZXh0IG1vZGVsbGluZyBydW4uIFRoaXMgaXRlcmF0aXZlIHByb2Nlc3Mgb2YgbW9kZWwgYnVpbGRpbmcgYW5kIGFzc2Vzc21lbnQgc2hvdWxkIGNvbnRpbnVlIHVudGlsIHRoZSBiZXN0IHBvc3NpYmxlIG1vZGVsKHMpIGFyZSBpZGVudGlmaWVkLiBBbGwgcmV2aXNpb25zIGFuZCBhc3Nlc3NtZW50cyBzaG91bGQgYmUgdGhvcm91Z2hseSBkb2N1bWVudGVkIHRvIGVuc3VyZSB0cmFuc3BhcmVuY3kgYW5kIHJlcHJvZHVjaWJpbGl0eS4KCiMjIyBTdGFnZSA1OiBFdmFsdWF0aW9uCgojIyMjIEV2YWx1YXRlIFJlc3VsdHMgYW5kIE9iamVjdGl2ZXMKCkR1cmluZyB0aGlzIHN0ZXAsIHRoZSBldmFsdWF0aW9uIHBoYXNlIGFzc2Vzc2VzIHRoZSBleHRlbnQgdG8gd2hpY2ggdGhlIGdlbmVyYXRlZCBtb2RlbCBtZWV0cyB0aGUgYnVzaW5lc3Mgb2JqZWN0aXZlcy4gVGhpcyBtYXkgaW52b2x2ZSB0ZXN0aW5nIHRoZSBtb2RlbChzKSBvbiByZWFsLXdvcmxkIGFwcGxpY2F0aW9ucyBvciBpZGVudGlmeWluZyBhbnkgZGVmaWNpZW5jaWVzIGluIHRoZSBtb2RlbCB0aGF0IG1heSBpbXBhY3QgaXRzIHByYWN0aWNhbCB1c2VmdWxuZXNzLiBUaGUgZXZhbHVhdGlvbiBwaGFzZSBhbHNvIGluY2x1ZGVzIGFuIGFzc2Vzc21lbnQgb2YgYWxsIG90aGVyIGRhdGEgbWluaW5nIHJlc3VsdHMgZ2VuZXJhdGVkIGR1cmluZyB0aGUgcHJvamVjdCwgd2hpY2ggbWF5IHJldmVhbCBhZGRpdGlvbmFsIGNoYWxsZW5nZXMgb3IgaW5zaWdodHMgZm9yIGZ1dHVyZSBkaXJlY3Rpb25zLgoKVGhlIGFzc2Vzc21lbnQgb2YgZGF0YSBtaW5pbmcgcmVzdWx0cyBzaG91bGQgYmUgc3VtbWFyaXNlZCBpbiB0ZXJtcyBvZiBidXNpbmVzcyBzdWNjZXNzIGNyaXRlcmlhLCBpbmNsdWRpbmcgYSBmaW5hbCBzdGF0ZW1lbnQgb24gd2hldGhlciB0aGUgcHJvamVjdCBoYXMgc3VjY2Vzc2Z1bGx5IGFjaGlldmVkIGl0cyBpbml0aWFsIGJ1c2luZXNzIG9iamVjdGl2ZXMuCgpCYXNlZCBvbiB0aGUgYXNzZXNzbWVudCBvZiBtb2RlbHMgd2l0aCByZXNwZWN0IHRvIHRoZSBidXNpbmVzcyBzdWNjZXNzIGNyaXRlcmlhLCB0aGUgZ2VuZXJhdGVkIG1vZGVscyB0aGF0IG1lZXQgdGhlIHNlbGVjdGVkIGNyaXRlcmlhIGJlY29tZSB0aGUgYXBwcm92ZWQgbW9kZWxzLgoKIyMjIyBDb25kdWN0IFByb2Nlc3MgUmV0cm9zcGVjdGl2ZQoKQWZ0ZXIgZGV0ZXJtaW5pbmcgdGhhdCB0aGUgcmVzdWx0aW5nIG1vZGVscyBtZWV0IHRoZSBidXNpbmVzcyBuZWVkcywgaXQgaXMgbmVjZXNzYXJ5IHRvIGNvbmR1Y3QgYSBtb3JlIGNvbXByZWhlbnNpdmUgcmV2aWV3IG9mIHRoZSBkYXRhIG1pbmluZyBlbmdhZ2VtZW50IHRvIGVuc3VyZSB0aGF0IG5vIGltcG9ydGFudCBmYWN0b3Igb3IgdGFzayBoYXMgYmVlbiBvdmVybG9va2VkLiBUaGlzIHJldmlldyBzaG91bGQgYWxzbyBpbmNsdWRlIHF1YWxpdHkgYXNzdXJhbmNlIGlzc3Vlcywgc3VjaCBhcyB3aGV0aGVyIHRoZSBtb2RlbCB3YXMgY29ycmVjdGx5IGJ1aWx0IGFuZCB3aGV0aGVyIG9ubHkgcGVybWlzc2libGUgYXR0cmlidXRlcyB3ZXJlIHVzZWQgZm9yIGFuYWx5c2lzLgoKVGhlIHByb2Nlc3MgcmV2aWV3IHNob3VsZCBiZSBzdW1tYXJpc2VkLCBoaWdobGlnaHRpbmcgYW55IGFjdGl2aXRpZXMgdGhhdCB3ZXJlIG1pc3NlZCBvciBvdmVybG9va2VkLCBhcyB3ZWxsIGFzIGFueSB0YXNrcyB0aGF0IHNob3VsZCBiZSByZXBlYXRlZCB0byBlbnN1cmUgdGhhdCB0aGUgZGF0YSBtaW5pbmcgZW5nYWdlbWVudCB3YXMgZXhlY3V0ZWQgYWNjdXJhdGVseSBhbmQgZWZmZWN0aXZlbHkuIFRoaXMgcmV2aWV3IG1heSBhbHNvIGlkZW50aWZ5IHBvdGVudGlhbCBhcmVhcyBmb3IgaW1wcm92ZW1lbnQgb3IgcmVmaW5lbWVudCBpbiB0aGUgZGF0YSBtaW5pbmcgcHJvY2VzcyB0aGF0IGNvdWxkIGJlIGltcGxlbWVudGVkIGluIGZ1dHVyZSBwcm9qZWN0cy4gT3ZlcmFsbCwgdGhlIHJldmlldyBzaG91bGQgcHJvdmlkZSBhIGNvbXByZWhlbnNpdmUgZXZhbHVhdGlvbiBvZiB0aGUgZGF0YSBtaW5pbmcgZW5nYWdlbWVudCBhbmQgZW5zdXJlIHRoYXQgYWxsIG5lY2Vzc2FyeSBzdGVwcyB3ZXJlIHRha2VuIHRvIGFjaGlldmUgdGhlIHByb2plY3QncyBnb2Fscy4KCiMjIyMgQXNzZXNzIE5leHQgU3RlcHMKCkFmdGVyIGNvbXBsZXRpbmcgdGhlIGFzc2Vzc21lbnQgYW5kIHByb2Nlc3MgcmV2aWV3LCBpdCBpcyBuZWNlc3NhcnkgdG8gZGVjaWRlIGhvdyB0byBwcm9jZWVkIHdpdGggdGhlIHByb2plY3QuIFRoaXMgbWF5IGludm9sdmUgZmluaXNoaW5nIHRoZSBwcm9qZWN0IGFuZCBtb3Zpbmcgb24gdG8gZGVwbG95bWVudCwgaW5pdGlhdGluZyBmdXJ0aGVyIGl0ZXJhdGlvbnMgdG8gaW1wcm92ZSB0aGUgbW9kZWxzIG9yIHRoZSBwcm9jZXNzLCBvciBzZXR0aW5nIHVwIG5ldyBkYXRhIG1pbmluZyBwcm9qZWN0cy4gVGhlIHJlbWFpbmluZyByZXNvdXJjZXMgYW5kIGJ1ZGdldCBzaG91bGQgYmUgdGFrZW4gaW50byBjb25zaWRlcmF0aW9uIHdoZW4gbWFraW5nIHRoaXMgZGVjaXNpb24uCgpBIGxpc3Qgb2YgcG90ZW50aWFsIGZ1cnRoZXIgYWN0aW9ucyBzaG91bGQgYmUgY3JlYXRlZCwgYWxvbmcgd2l0aCB0aGUgcmVhc29ucyBmb3IgYW5kIGFnYWluc3QgZWFjaCBvcHRpb24uIEZvciBleGFtcGxlLCBjb250aW51aW5nIHdpdGggdGhlIHByb2plY3QgbWF5IGJlIHRoZSBiZXN0IG9wdGlvbiBpZiB0aGUgbW9kZWxzIG1lZXQgdGhlIGJ1c2luZXNzIG5lZWRzIGFuZCB0aGVyZSBhcmUgbm8gYWRkaXRpb25hbCBpbnNpZ2h0cyB0byBiZSBnYWluZWQgZnJvbSBmdXJ0aGVyIGl0ZXJhdGlvbnMuIE9uIHRoZSBvdGhlciBoYW5kLCBpbml0aWF0aW5nIGZ1cnRoZXIgaXRlcmF0aW9ucyBtYXkgYmUgbmVjZXNzYXJ5IGlmIHRoZSBtb2RlbHMgbmVlZCB0byBiZSByZWZpbmVkIG9yIGlmIHRoZXJlIGFyZSBzdGlsbCB1bmFuc3dlcmVkIHF1ZXN0aW9ucyB0aGF0IG5lZWQgdG8gYmUgYWRkcmVzc2VkLgoKVGhlIGRlY2lzaW9uIG9uIGhvdyB0byBwcm9jZWVkIHNob3VsZCBiZSBkZXNjcmliZWQgaW4gZGV0YWlsLCBhbG9uZyB3aXRoIHRoZSByYXRpb25hbGUgZm9yIHRoZSBjaG9zZW4gY291cnNlIG9mIGFjdGlvbi4gVGhpcyBkZWNpc2lvbiBzaG91bGQgYmUgYmFzZWQgb24gYSB0aG9yb3VnaCBldmFsdWF0aW9uIG9mIHRoZSBkYXRhIG1pbmluZyBlbmdhZ2VtZW50LCB0YWtpbmcgaW50byBhY2NvdW50IHRoZSByZXN1bHRzIG9mIHRoZSBhc3Nlc3NtZW50LCB0aGUgcHJvY2VzcyByZXZpZXcsIGFuZCB0aGUgYXZhaWxhYmxlIHJlc291cmNlcyBhbmQgYnVkZ2V0LgoKIyMjIFN0YWdlIDY6IERlcGxveW1lbnQKCiMjIyMgUGxhbiBEZXBsb3ltZW50CgpUaGUgZGVwbG95bWVudCBzdGFnZSBpbnZvbHZlcyB0YWtpbmcgdGhlIGV2YWx1YXRpb24gcmVzdWx0cyBhbmQgZGV0ZXJtaW5pbmcgYSBzdHJhdGVneSBmb3IgZGVwbG95aW5nIHRoZSBtb2RlbHMuIElmIGEgZ2VuZXJhbCBwcm9jZWR1cmUgaGFzIGJlZW4gaWRlbnRpZmllZCBmb3IgY3JlYXRpbmcgdGhlIHJlbGV2YW50IG1vZGVscywgaXQgc2hvdWxkIGJlIGRvY3VtZW50ZWQgZm9yIGxhdGVyIGRlcGxveW1lbnQuIEl0IGlzIGltcG9ydGFudCB0byBjb25zaWRlciB0aGUgd2F5cyBhbmQgbWVhbnMgb2YgZGVwbG95bWVudCBkdXJpbmcgdGhlIGJ1c2luZXNzIHVuZGVyc3RhbmRpbmcgcGhhc2UgYXMgd2VsbCwgYXMgdGhpcyBpcyBjcnVjaWFsIHRvIHRoZSBzdWNjZXNzIG9mIHRoZSBwcm9qZWN0IGFuZCB0aGUgb3BlcmF0aW9uYWwgc2lkZSBvZiB0aGUgYnVzaW5lc3MuCgpUaGUgZGVwbG95bWVudCBwbGFuIHNob3VsZCBzdW1tYXJpemUgdGhlIGRlcGxveW1lbnQgc3RyYXRlZ3ksIGluY2x1ZGluZyB0aGUgbmVjZXNzYXJ5IHN0ZXBzIGFuZCBob3cgdG8gcGVyZm9ybSB0aGVtLiBUaGlzIG1heSBpbnZvbHZlIGludGVncmF0aW5nIHRoZSBtb2RlbHMgaW50byBleGlzdGluZyBzeXN0ZW1zIG9yIGRldmVsb3BpbmcgbmV3IGFwcGxpY2F0aW9ucyB0byBtYWtlIHVzZSBvZiB0aGUgbW9kZWxzLiBUaGUgcGxhbiBzaG91bGQgYWxzbyBpZGVudGlmeSBhbnkgcG90ZW50aWFsIGNoYWxsZW5nZXMgb3IgbGltaXRhdGlvbnMgaW4gdGhlIGRlcGxveW1lbnQgcHJvY2VzcyBhbmQgb3V0bGluZSBzdHJhdGVnaWVzIGZvciBhZGRyZXNzaW5nIHRoZW0uCgpUaGUgZGVwbG95bWVudCBwbGFuIHNob3VsZCBiZSBjb21wcmVoZW5zaXZlIGFuZCBpbmNsdWRlIGFsbCBuZWNlc3NhcnkgZGV0YWlscywgc3VjaCBhcyB0aW1lbGluZXMsIHJlc291cmNlcywgYW5kIGtleSBzdGFrZWhvbGRlcnMgaW52b2x2ZWQgaW4gdGhlIGRlcGxveW1lbnQgcHJvY2Vzcy4gSXQgc2hvdWxkIGFsc28gYmUgcmV2aWV3ZWQgYW5kIHVwZGF0ZWQgcmVndWxhcmx5IHRvIGVuc3VyZSB0aGF0IGl0IHJlbWFpbnMgcmVsZXZhbnQgYW5kIGVmZmVjdGl2ZS4gT3ZlcmFsbCwgYSB3ZWxsLWRldmVsb3BlZCBkZXBsb3ltZW50IHBsYW4gaXMgZXNzZW50aWFsIGZvciBtYXhpbWl6aW5nIHRoZSB2YWx1ZSBvZiB0aGUgZGF0YSBtaW5pbmcgcHJvamVjdCBhbmQgYWNoaWV2aW5nIHRoZSBkZXNpcmVkIGJ1c2luZXNzIG91dGNvbWVzLgoKIyMjIyBNb25pdG9yIE1vZGVscwoKTW9uaXRvcmluZyBhbmQgbWFpbnRlbmFuY2UgYXJlIGNydWNpYWwgaXNzdWVzIHdoZW4gZGF0YSBtaW5pbmcgcmVzdWx0cyBiZWNvbWUgcGFydCBvZiB0aGUgZGF5LXRvLWRheSBidXNpbmVzcyBlbnZpcm9ubWVudC4gQSB3ZWxsLXByZXBhcmVkIG1haW50ZW5hbmNlIHN0cmF0ZWd5IGlzIGVzc2VudGlhbCB0byBlbnN1cmUgdGhlIGNvbnRpbnVlZCBhY2N1cmFjeSBhbmQgZWZmZWN0aXZlbmVzcyBvZiB0aGUgZGF0YSBtaW5pbmcgcmVzdWx0cyBhbmQgdG8gYXZvaWQgYW55IHVubmVjZXNzYXJ5IHBlcmlvZHMgb2YgaW5jb3JyZWN0IHVzYWdlLgoKVG8gbW9uaXRvciB0aGUgZGVwbG95bWVudCBvZiB0aGUgZGF0YSBtaW5pbmcgcmVzdWx0KHMpLCBhIGRldGFpbGVkIG1vbml0b3JpbmcgcHJvY2VzcyBwbGFuIHNob3VsZCBiZSBkZXZlbG9wZWQsIHRha2luZyBpbnRvIGFjY291bnQgdGhlIHNwZWNpZmljIHR5cGUgb2YgZGVwbG95bWVudC4gVGhpcyBwbGFuIHNob3VsZCBzdW1tYXJpc2UgdGhlIG1vbml0b3JpbmcgYW5kIG1haW50ZW5hbmNlIHN0cmF0ZWd5LCBpbmNsdWRpbmcgdGhlIG5lY2Vzc2FyeSBzdGVwcyBhbmQgaG93IHRvIHBlcmZvcm0gdGhlbS4KClRoZSBtb25pdG9yaW5nIGFuZCBtYWludGVuYW5jZSBwbGFuIHNob3VsZCBvdXRsaW5lIGtleSBwZXJmb3JtYW5jZSBpbmRpY2F0b3JzIChLUElzKSB0aGF0IHdpbGwgYmUgdXNlZCB0byBldmFsdWF0ZSB0aGUgZWZmZWN0aXZlbmVzcyBvZiB0aGUgZGF0YSBtaW5pbmcgcmVzdWx0cyBhbmQgaWRlbnRpZnkgYW55IHBvdGVudGlhbCBpc3N1ZXMgb3IgYXJlYXMgZm9yIGltcHJvdmVtZW50LiBJdCBzaG91bGQgYWxzbyBpbmNsdWRlIGEgc2NoZWR1bGUgZm9yIHJlZ3VsYXIgcmV2aWV3IGFuZCB1cGRhdGUgb2YgdGhlIG1vZGVscywgYXMgd2VsbCBhcyBwcm9jZWR1cmVzIGZvciByZXNvbHZpbmcgYW55IGlzc3VlcyB0aGF0IG1heSBhcmlzZS4KClRoZSBwbGFuIHNob3VsZCBiZSByZXZpZXdlZCBhbmQgdXBkYXRlZCByZWd1bGFybHkgdG8gZW5zdXJlIHRoYXQgaXQgcmVtYWlucyByZWxldmFudCBhbmQgZWZmZWN0aXZlLiBUaGlzIHdpbGwgaGVscCB0byBlbnN1cmUgdGhlIGNvbnRpbnVlZCBzdWNjZXNzIG9mIHRoZSBkYXRhIG1pbmluZyBwcm9qZWN0IGFuZCBlbmFibGUgdGhlIGJ1c2luZXNzIHRvIG1heGltaXNlIHRoZSB2YWx1ZSBvZiB0aGUgZGF0YSBtaW5pbmcgcmVzdWx0cy4KCiMjIyMgV3JpdGUgRmluYWwgUmVwb3J0CgpBdCB0aGUgZW5kIG9mIHRoZSBkYXRhIG1pbmluZyBwcm9qZWN0LCBpdCBpcyBpbXBvcnRhbnQgdG8gcHJlcGFyZSBhIGZpbmFsIHJlcG9ydCB0aGF0IHN1bW1hcmlzZXMgYW5kIG9yZ2FuaXNlcyBhbGwgdGhlIHJlc3VsdHMgYW5kIGRlbGl2ZXJhYmxlcy4gRGVwZW5kaW5nIG9uIHRoZSBkZXBsb3ltZW50IHBsYW4sIHRoZSBmaW5hbCByZXBvcnQgbWF5IGJlIGEgY29tcHJlaGVuc2l2ZSBwcmVzZW50YXRpb24gb2YgdGhlIGRhdGEgbWluaW5nIHJlc3VsdHMgb3IgYSBzdW1tYXJ5IG9mIHRoZSBwcm9qZWN0IGV4cGVyaWVuY2VzIChpZiB0aGV5IGhhdmUgbm90IGFscmVhZHkgYmVlbiBkb2N1bWVudGVkIGFzIGFuIG9uZ29pbmcgYWN0aXZpdHkpLgoKVGhlIGZpbmFsIHJlcG9ydCBzaG91bGQgaW5jbHVkZSBhbGwgdGhlIHByZXZpb3VzIGRlbGl2ZXJhYmxlcywgc3VjaCBhcyB0aGUgYnVzaW5lc3MgdW5kZXJzdGFuZGluZywgZGF0YSBwcmVwYXJhdGlvbiwgbW9kZWxsaW5nLCBldmFsdWF0aW9uLCBhbmQgZGVwbG95bWVudCBwbGFucy4gSXQgc2hvdWxkIGFsc28gcHJvdmlkZSBhbiBvdmVydmlldyBvZiB0aGUgZGF0YSBtaW5pbmcgcHJvY2VzcywgaW5jbHVkaW5nIGFueSBjaGFsbGVuZ2VzIGFuZCBsaW1pdGF0aW9ucyBlbmNvdW50ZXJlZCwgYW5kIGhpZ2hsaWdodCB0aGUga2V5IGZpbmRpbmdzIGFuZCBpbnNpZ2h0cyBnYWluZWQuCgpJbiBhZGRpdGlvbiB0byB0aGUgZmluYWwgcmVwb3J0LCB0aGVyZSB3aWxsIG9mdGVuIGJlIGEgbWVldGluZyBhdCB0aGUgY29uY2x1c2lvbiBvZiB0aGUgcHJvamVjdCB3aGVyZSB0aGUgcmVzdWx0cyBhcmUgcHJlc2VudGVkIHRvIHRoZSBjdXN0b21lci4gVGhpcyBmaW5hbCBwcmVzZW50YXRpb24gc2hvdWxkIHByb3ZpZGUgYSBjbGVhciBhbmQgY29uY2lzZSBvdmVydmlldyBvZiB0aGUgZGF0YSBtaW5pbmcgcmVzdWx0cywgaGlnaGxpZ2h0aW5nIHRoZSBtb3N0IGltcG9ydGFudCBmaW5kaW5ncyBhbmQgdGhlaXIgcG90ZW50aWFsIGltcGxpY2F0aW9ucyBmb3IgdGhlIGJ1c2luZXNzLgoKT3ZlcmFsbCwgdGhlIGZpbmFsIHJlcG9ydCBhbmQgcHJlc2VudGF0aW9uIGFyZSBjcml0aWNhbCBjb21wb25lbnRzIG9mIHRoZSBkYXRhIG1pbmluZyBwcm9qZWN0IGFuZCBoZWxwIHRvIGVuc3VyZSB0aGF0IHRoZSBidXNpbmVzcyBjYW4gZnVsbHkgbGV2ZXJhZ2UgdGhlIGluc2lnaHRzIGdhaW5lZCBmcm9tIHRoZSBwcm9qZWN0IHRvIGFjaGlldmUgaXRzIGdvYWxzIGFuZCBvYmplY3RpdmVzLgoKIyMjIyBDb25kdWN0IFJldHJvc3BlY3RpdmUKCkFzc2Vzc2luZyB0aGUgZGF0YSBtaW5pbmcgcHJvamVjdCBhdCBpdHMgY29uY2x1c2lvbiBpcyBhbiBpbXBvcnRhbnQgc3RlcCBmb3IgaWRlbnRpZnlpbmcgd2hhdCB3ZW50IHdlbGwgYW5kIHdoYXQgY291bGQgYmUgaW1wcm92ZWQuIEV4cGVyaWVuY2UgZG9jdW1lbnRhdGlvbiBjYW4gaGVscCB0byBjYXB0dXJlIGltcG9ydGFudCBpbnNpZ2h0cyBhbmQgbGVzc29ucyBsZWFybmVkIGZyb20gdGhlIHByb2plY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBpbmZvcm0gZnV0dXJlIHByb2plY3RzIGFuZCBpbXByb3ZlIG92ZXJhbGwgcGVyZm9ybWFuY2UuCgpFeHBlcmllbmNlIGRvY3VtZW50YXRpb24gc2hvdWxkIHN1bW1hcml6ZSB0aGUgaW1wb3J0YW50IGV4cGVyaWVuY2VzIGdhaW5lZCBkdXJpbmcgdGhlIHByb2plY3QsIGluY2x1ZGluZyBhbnkgcGl0ZmFsbHMgZW5jb3VudGVyZWQsIG1pc2xlYWRpbmcgYXBwcm9hY2hlcywgb3IgaGludHMgZm9yIHNlbGVjdGluZyB0aGUgYmVzdCBzdWl0ZWQgZGF0YSBtaW5pbmcgdGVjaG5pcXVlcyBpbiBzaW1pbGFyIHNpdHVhdGlvbnMuIFRoaXMgZG9jdW1lbnRhdGlvbiBjYW4gYWxzbyBpbmNsdWRlIGFueSByZXBvcnRzIHRoYXQgd2VyZSB3cml0dGVuIGJ5IGluZGl2aWR1YWwgcHJvamVjdCBtZW1iZXJzIGR1cmluZyBwcmV2aW91cyBwaGFzZXMgb2YgdGhlIHByb2plY3QsIGFzIHRoZXNlIG1heSBjb250YWluIHZhbHVhYmxlIGluc2lnaHRzIGFuZCBsZXNzb25zIGxlYXJuZWQuCgpJdCBpcyBpbXBvcnRhbnQgdG8gaWRlbnRpZnkgYm90aCB0aGUgc3VjY2Vzc2VzIGFuZCBmYWlsdXJlcyBvZiB0aGUgcHJvamVjdCBpbiBvcmRlciB0byBpbXByb3ZlIGZ1dHVyZSBwZXJmb3JtYW5jZS4gVGhpcyBtYXkgaW52b2x2ZSByZWZsZWN0aW5nIG9uIHRoZSBlZmZlY3RpdmVuZXNzIG9mIHRoZSBkYXRhIHByZXBhcmF0aW9uIGFuZCBtb2RlbGxpbmcgdGVjaG5pcXVlcyB1c2VkLCB0aGUgcXVhbGl0eSBvZiB0aGUgZGF0YSwgdGhlIGFwcHJvcHJpYXRlbmVzcyBvZiB0aGUgZXZhbHVhdGlvbiBjcml0ZXJpYSwgYW5kIHRoZSBzdWNjZXNzIG9mIHRoZSBkZXBsb3ltZW50IHN0cmF0ZWd5LiBCeSB1bmRlcnN0YW5kaW5nIHdoYXQgd2VudCB3ZWxsIGFuZCB3aGF0IG5lZWRzIHRvIGJlIGltcHJvdmVkLCBmdXR1cmUgZGF0YSBtaW5pbmcgcHJvamVjdHMgY2FuIGJlIG1vcmUgZWZmZWN0aXZlIGFuZCBlZmZpY2llbnQsIGxlYWRpbmcgdG8gYmV0dGVyIGJ1c2luZXNzIG91dGNvbWVzLgoKIyMgU3VtbWFyeSB7I3N1bW1hcnl9CgpUaGUgQ1JJU1AtRE0gKENyb3NzLUluZHVzdHJ5IFN0YW5kYXJkIFByb2Nlc3MgZm9yIERhdGEgTWluaW5nKSBmcmFtZXdvcmsgaXMgYSB3aWRlbHktdXNlZCBtZXRob2RvbG9neSBmb3IgZGF0YSBtaW5pbmcgcHJvamVjdHMuIEl0IGNvbnNpc3RzIG9mIHNpeCBwaGFzZXM6IEJ1c2luZXNzIFVuZGVyc3RhbmRpbmcsIERhdGEgVW5kZXJzdGFuZGluZywgRGF0YSBQcmVwYXJhdGlvbiwgTW9kZWxpbmcsIEV2YWx1YXRpb24sIGFuZCBEZXBsb3ltZW50LiBFYWNoIHBoYXNlIGludm9sdmVzIGEgc2V0IG9mIHRhc2tzIGFuZCBvYmplY3RpdmVzIHRoYXQgaGVscCBndWlkZSB0aGUgcHJvamVjdCB0aHJvdWdoIGl0cyBsaWZlIGN5Y2xlLCBmcm9tIGlkZW50aWZ5aW5nIHRoZSBidXNpbmVzcyBwcm9ibGVtIHRvIGRlcGxveWluZyB0aGUgc29sdXRpb24uIFRoZSBmcmFtZXdvcmsgaXMgaXRlcmF0aXZlLCBhbGxvd2luZyBmb3IgYWRqdXN0bWVudHMgYW5kIGltcHJvdmVtZW50cyBhdCBlYWNoIHN0YWdlLCBhbmQgZW1waGFzaXplcyB0aGUgaW1wb3J0YW5jZSBvZiBjb21tdW5pY2F0aW9uIGFuZCBjb2xsYWJvcmF0aW9uIGJldHdlZW4gdGVhbSBtZW1iZXJzLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBGaWxlcyAmIFJlc291cmNlcwoKYGBge3IgemlwRmlsZXMsIGVjaG89RkFMU0V9CnppcE5hbWUgPSBzcHJpbnRmKCJMZXNzb25GaWxlcy0lcy0lcy56aXAiLCAKICAgICAgICAgICAgICAgICBwYXJhbXMkY2F0ZWdvcnksCiAgICAgICAgICAgICAgICAgcGFyYW1zJG51bWJlcikKCnRleHRBTGluayA9IHBhc3RlMCgiQWxsIEZpbGVzIGZvciBMZXNzb24gIiwgCiAgICAgICAgICAgICAgIHBhcmFtcyRjYXRlZ29yeSwiLiIscGFyYW1zJG51bWJlcikKCiMgZG93bmxvYWRGaWxlc0xpbmsoKSBpcyBpbmNsdWRlZCBmcm9tIF9pbnNlcnQyREIuUgprbml0cjo6cmF3X2h0bWwoZG93bmxvYWRGaWxlc0xpbmsoIi4iLCB6aXBOYW1lLCB0ZXh0QUxpbmspKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgUmVmZXJlbmNlcwoKW1NoZWFyZXIsIEMuICgyMDAwKS4gVGhlIENSSVNQLURNIG1vZGVsOiB0aGUgbmV3IGJsdWVwcmludCBmb3IgZGF0YSBtaW5pbmcuIEpvdXJuYWwgb2YgZGF0YSB3YXJlaG91c2luZywgNSg0KSwgMTMtMjIuXShodHRwczovL21pbmVyYWNhb2RlZGFkb3MuZmlsZXMud29yZHByZXNzLmNvbS8yMDEyLzA0L3RoZS1jcmlzcC1kbS1tb2RlbC10aGUtbmV3LWJsdWVwcmludC1mb3ItZGF0YS1taW5pbmctc2hlYXJlci1jb2xpbi5wZGYpCgojIyBFcnJhdGEKCk5vbmUgY29sbGVjdGVkIHlldC4gTGV0IHVzIGtub3cuCgpgYGB7PWh0bWx9CjxzY3JpcHQgc3JjPSJodHRwczovL2Zvcm0uam90Zm9ybS5jb20vc3RhdGljL2ZlZWRiYWNrMi5qcyIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4KICBuZXcgSm90Zm9ybUZlZWRiYWNrKHsKICAgIGZvcm1JZDogIjIxMjE4NzA3Mjc4NDE1NyIsCiAgICBidXR0b25UZXh0OiAiRmVlZGJhY2siLAogICAgYmFzZTogImh0dHBzOi8vZm9ybS5qb3Rmb3JtLmNvbS8iLAogICAgYmFja2dyb3VuZDogIiNGNTkyMDIiLAogICAgZm9udENvbG9yOiAiI0ZGRkZGRiIsCiAgICBidXR0b25TaWRlOiAibGVmdCIsCiAgICBidXR0b25BbGlnbjogImNlbnRlciIsCiAgICB0eXBlOiBmYWxzZSwKICAgIHdpZHRoOiA3MDAsCiAgICBoZWlnaHQ6IDUwMCwKICAgIGlzQ2FyZEZvcm06IGZhbHNlCiAgfSk7Cjwvc2NyaXB0PgpgYGAKYGBge3IgY29kZT14ZnVuOjpyZWFkX3V0ZjgocGFzdGUwKGhlcmU6OmhlcmUoKSwnL1IvX2RlcGxveUtuaXQuUicpKSwgaW5jbHVkZSA9IEZBTFNFfQpgYGAKCg==