1 Introduction

Data science is a dynamic field that focuses on gathering, analyzing, and interpreting large datasets to uncover valuable insights through the use of statistical techniques and machine learning methods. However, the ultimate value of data science work lies not only in the quality of the analysis but also in how effectively the results are communicated. Effective technical communication is essential in ensuring that complex findings are understood, acted upon, and used to make informed decisions. This note outlines the key elements of effective technical communication in data science, focusing on reporting, presentations, and discussions.

Clarity and Simplicity in Reporting

One of the most critical elements of effective communication in data science is clarity. Data science reports often deal with intricate algorithms, statistical models, and large datasets, which can overwhelm readers if presented poorly. Technical reports must avoid jargon and complex terminology that might alienate non-expert audiences. While technical accuracy is vital, the language should be accessible to a wide audience, including stakeholders who may not have a deep understanding of the methods used.

Clear communication can be achieved by structuring reports logically. Each report should begin with an executive summary, outlining key findings and their implications. This is followed by detailed sections that explain the methodology, results, and conclusions. Finally, recommendations should be presented clearly, based on the data’s insights. To avoid information overload, the report should be concise, with a focus on the most important points, using bullet points or tables to summarize key findings.

Visualization: Making Complex Data Accessible

Effective data science communication relies heavily on the use of visualizations. Data, in its raw form, can be challenging to interpret. Charts, graphs, and other visual tools help to present data in a way that is intuitive and comprehensible. Whether it’s a time series graph, a heatmap, or a scatter plot, visualizations can highlight trends, correlations, and outliers more effectively than raw numbers.

However, visualizations must be designed carefully to convey the correct message. Poorly designed visuals can mislead or confuse the audience. It’s essential to choose the right type of graph for the data, use clear labels, and avoid unnecessary clutter. For example, when presenting a correlation matrix, a heatmap with clear color gradients can quickly communicate which variables are most closely related, making it easier for the audience to understand the relationships within the data.

Tailoring Communication to the Audience

Another important factor in effective technical communication is knowing your audience. Data scientists often communicate their findings to diverse groups, including executives, technical teams, and non-technical stakeholders. Tailoring the depth and style of communication according to the audience is crucial for ensuring that the message is understood.

For business executives, the emphasis should be on actionable insights rather than the technical details of the analysis. A summary of the key findings, along with clear recommendations, is more valuable than a deep dive into the algorithms used. On the other hand, for a technical audience, the focus should be on the methods, assumptions, and results of the analysis, allowing them to assess the validity of the work themselves.

Understanding the audience’s needs also helps in choosing the appropriate level of detail. Executives may only need a high-level overview of the outcomes, while technical teams require a deeper understanding of the data’s structure, modeling techniques, and validation processes.

Storytelling: Framing Data Within a Narrative

In addition to clarity and audience awareness, storytelling is a powerful technique in data science communication. Numbers and models may seem abstract, but when framed within a narrative, they become more relatable and memorable. Storytelling helps to connect the findings with real-world problems and illustrates their implications in a way that resonates with the audience.

A compelling data story begins by presenting the problem or challenge that the data analysis seeks to address. The narrative should then outline how the data was gathered, processed, and analyzed, before leading into the key findings. Finally, the story should close with a conclusion or recommendation that ties everything back to the initial problem, showing how the insights can be used to make informed decisions.

Precision and Accuracy

The importance of precision and accuracy in technical communication cannot be overstated. Data science relies on the correct application of mathematical models and statistical techniques, and any miscommunication of these methods can lead to incorrect conclusions and, potentially, harmful decisions. Whether in written reports, presentations, or discussions, data scientists must ensure that the results are accurate, and the assumptions behind their analysis are clearly stated.

It’s also important to emphasize the limitations of the analysis. No model is perfect, and acknowledging potential errors or areas of uncertainty can help build trust with the audience. For example, discussing the confidence intervals around predictions or the assumptions underlying a regression model provides context and allows the audience to assess the reliability of the results.

Engaging Discussions

Finally, effective communication in data science extends beyond written reports and presentations to interactive discussions. In these settings, data scientists must be prepared to explain their work in a conversational manner, answering questions, clarifying doubts, and engaging with the audience. Active listening is critical here, as it allows the communicator to address the audience’s concerns and adjust the explanation accordingly.

Moreover, discussions provide an opportunity for feedback, which is essential for improving the analysis. During discussions, data scientists can clarify misunderstandings, explain complex concepts in simpler terms, and fine-tune their message to ensure that it is understood by all parties involved. This two-way communication helps to ensure that the findings are interpreted correctly and can guide future decisions.

2 Data Analysis Workflow

The data science analysis workflow refers to the series of steps or stages that data scientists follow to gather, process, analyze, and interpret data in order to extract actionable insights. This workflow can vary slightly depending on the specific project, but it typically includes the following key stages.

2.1 Define Objectives and Questions

In data science and machine learning projects, defining objectives and questions accurately is crucial as they set the foundation for the entire analysis and model development process. Clear objectives and well-formulated questions guide data collection, feature engineering, model selection, and result interpretation. Here’s how to define them accurately.

Projects Objectives

Objectives describe the overall goal or purpose of the project. They are the desired outcomes that the analysis or machine learning model aims to achieve. In data science and machine learning projects, objectives should be:

  • Clear and Specific: The objective should be well-defined, leaving no ambiguity about what is to be achieved. For example, predicting the likelihood of customer churn in the next quarter.

  • Measurable: The objective should be quantifiable so that progress can be tracked and success can be evaluated. For example, Increasing prediction accuracy of churn rate by 15% over baseline models.

  • Feasible: Ensure that the objective can be realistically achieved within the constraints of data, time, and resources available. For example, Building a model with at least 80% accuracy based on available data sources.

  • Aligned Business Needs: The objective should address the business problem or requirement of the stakeholders, whether they are business leaders, researchers, or clients. For example, Providing actionable insights to reduce customer churn in a subscription-based business.

Formulating Analytic Questions

Analytic Questions are the specific inquiries that guide the analysis or modeling process. These are more detailed than objectives and often help in formulating hypotheses and defining the scope of the project. Well-crafted questions should:

  • Be Relevant to the Problem: Analytic Questions should directly relate to the problem you are solving or the objective you aim to achieve. For example, What factors are most strongly correlated with customer churn in the current dataset?

  • Be Actionable: Analytic Questions should lead to findings or decisions that can be acted upon. For example, can we identify potential high-risk customers who are likely to churn within the next 3 months?

  • Be Clear and Focused: Analytic Questions should be concise and precise. Avoid vague or broad questions that may be difficult to address. For example, what are the top predictors of house price variation in the market? (instead of What determines house prices?)

  • Be Hypothesis-Driven: In many cases, analytic questions will be based on a hypothesis you want to test through the data. For example: Does the number of bedrooms in a house significantly impact its price?

  • Be Testable with Data: Analytic Questions should be formulated in a way that they can be addressed using the available data and analysis techniques. For example: Can we use customer demographic data to predict purchasing behavior?

  • Account for Constraints: Consider whether the questions can be answered within the available time, data, and resources. For example, hHow can we predict the likelihood of loan approval based on income, credit score, and employment history, given the available data?

Some Well-crafted Example Analytic Questions

  • What are the key drivers of customer satisfaction in our online retail platform?

  • Is there a significant relationship between income and spending patterns in different demographic groups?

  • How can we improve the accuracy of fraud detection in credit card transactions using machine learning models?

2.2 Data Collection and Preparation

Data collection and preparation are crucial steps in the machine learning (ML) pipeline, serving as the foundation for building effective and reliable models. Without high-quality, relevant data, even the most advanced machine learning algorithms are unlikely to deliver meaningful or accurate results. This subsection explores the importance of data collection and preparation in the context of machine learning, outlining the processes involved, challenges faced, and best practices for ensuring that data is suitable for analysis.

2.2.1 Data Collection

Data collection is the first and most critical step in the machine learning pipeline. It involves acquiring the data needed to solve a specific problem. This step must focus on gathering data that is relevant, diverse, and representative of the problem domain. The following are key considerations during data collection:

  • Source Identification: The first step is identifying the data sources. These can include internal databases, public datasets, APIs, or third-party providers. The quality of the data depends on the credibility and relevance of the sources. For example, in the customer churn prediction modeling, data could be collected from customer databases, transaction records, customer support interactions, and web analytics.

  • Data Volume and Variety: A common challenge in machine learning is collecting enough data to accurately represent the problem. Machine learning models often perform better with large, diverse datasets that capture the full range of possible inputs and scenarios.

  • Data Relevance: The data collected must be directly relevant to the task at hand. Irrelevant data not only adds unnecessary complexity but can also introduce noise that hinders model performance.

  • Data Privacy and Ethics: Collecting data must be done ethically, ensuring that personal and sensitive information is handled responsibly. This includes adhering to data protection regulations like GDPR and obtaining informed consent from individuals where necessary.

  • Data Integration: In many cases, data may come from multiple sources, each with its own structure and format. Integrating disparate datasets while ensuring consistency and integrity is a vital part of the collection phase.

2.2.2 Data Preparation

Once data has been collected, the next critical step is preparing it for analysis. Data preparation encompasses several processes, including cleaning, transformation, and feature engineering. The goal is to ensure that the data is clean, complete, and in a format that is compatible with machine learning algorithms. Key steps in data preparation include:

Data Cleaning

Raw data is often messy and incomplete, containing errors, inconsistencies, or missing values. Cleaning the data involves:

  • Handling Missing Values: Data may have missing or null values due to errors in data collection or user behavior. These missing values can be handled by removing rows, imputing missing values based on other data points, or using algorithms that handle missing data naturally.

  • Removing Duplicates: Duplicate records can skew analysis and negatively affect model training. Identifying and removing duplicates is a crucial step.

  • Fixing Errors: Errors in data, such as incorrect labels, misformatted dates, or outliers, must be addressed to ensure data quality.

  • Data Transformation: Data transformation involves converting data into a usable format. This includes scaling, normalizing, or encoding features to ensure that the machine learning algorithm can process the data effectively.


Scaling and Normalization

Machine learning algorithms, especially those that rely on distance metrics like k-nearest neighbors (KNN) or gradient descent, require features to be on similar scales. Normalizing or standardizing the data ensures that all features contribute equally to the model.

  • Encoding Categorical Variables: Many machine learning algorithms cannot work directly with categorical variables (e.g., gender, country, or product category). Techniques like one-hot encoding or label encoding are used to convert these variables into numerical form.

  • Feature Engineering: This process involves creating new features or modifying existing ones to improve model performance. For example, combining date and time fields into a “day of the week” feature or calculating the difference between two timestamp columns can provide more meaningful inputs for the model.

Data Splitting

To assess model performance and prevent overfitting, the dataset is usually split into training, validation, and testing sets. The training set is used to build the model, the validation set helps tune hyperparameters, and the testing set evaluates the model’s generalization ability.

Outlier Detection

Outliers are data points that differ significantly from others and can distort the results of a model. Detecting and handling outliers is crucial for preventing these values from negatively influencing the model’s predictions.

Data Augmentation

In some cases, especially when working with images or text, data augmentation techniques like rotation, cropping, or text paraphrasing can be used to artificially expand the dataset and improve model robustness.

2.2.3 Best Practices

To overcome these challenges and ensure successful machine learning projects, the following best practices should be followed:

  • Understand the Problem Domain: Collaborate with domain experts to ensure the data collected is relevant and useful for the problem being solved.

  • Automate Data Collection: Whenever possible, automate the data collection process to improve efficiency and consistency.

  • Iterate and Refine: Data preparation is not a one-time task. It’s important to iterate and refine the dataset as the model is developed and as new data becomes available.

  • Document the Process: Keep detailed records of the data collection and preparation steps. This ensures transparency and reproducibility, which is especially important for collaborative and regulatory compliance.

  • Test for Bias: Regularly test the data for bias and ensure that the model is trained on representative and diverse datasets.


In summary, data collection and preparation are foundational steps in machine learning, directly influencing the quality and effectiveness of the resulting models. Ensuring the data is relevant, clean, and properly formatted is critical for developing models that can make accurate predictions and provide valuable insights. By carefully managing these stages, data scientists can build reliable, scalable models that perform well in real-world applications. As machine learning continues to evolve, mastering data collection and preparation will remain an essential skill for data scientists and machine learning practitioners.


2.3 Exploratory Data Analysis (EDA)

Exploratory Data Analysis (EDA) is a crucial step in the machine learning workflow, serving as an initial investigation into the dataset to uncover underlying patterns, relationships, and potential issues. EDA involves analyzing the data’s structure and distribution, generating hypotheses, and identifying trends or anomalies that might influence subsequent modeling decisions. It helps data scientists and machine learning practitioners understand the data before diving into complex algorithms, ensuring a better understanding of the dataset, improved data preprocessing, and more effective model selection.

2.3.1 The Role of EDA in Machine Learning

EDA provides a foundational understanding of the dataset, ensuring that data scientists can make informed decisions during the modeling phase. By exploring the data visually and statistically, EDA helps identify key insights, detect errors, and reveal aspects of the data that might otherwise remain hidden. This step is vital because the quality of the data used in machine learning directly affects the model’s performance, and the insights gained during EDA can guide further data cleaning, feature engineering, and model refinement.

We next list some of the key steps in EDA.

1. Understanding the Dataset Structure

The first step in EDA is understanding the structure of the dataset. This involves checking the number of rows (data points) and columns (features), and understanding the data types of each feature (e.g., categorical, numerical, text). This step is fundamental for determining how the data can be processed or transformed for analysis.

Example: A dataset with customer information may include features like “age,” “income,” and “gender.” Understanding whether these features are numerical or categorical helps in choosing the right statistical techniques or machine learning algorithms.

2. Descriptive Statistics

Descriptive statistics summarize the central tendencies, variability, and distribution of the data. Key metrics include the mean, median, standard deviation, minimum, and maximum values for numerical features, and frequency counts for categorical features. These statistics offer an initial overview of the data’s characteristics, helping identify any obvious data issues or skewed distributions.

Example: For a numerical feature like “age,” checking the mean and standard deviation can highlight if there are extreme outliers or if the data is heavily skewed.

3. Data Visualization

Visualizations are an essential part of EDA, allowing data scientists to identify patterns, trends, and relationships between features more intuitively. Common visualizations used in EDA include:

  • Histograms: Show the distribution of numerical data, helping to understand the spread and skewness of variables.

  • Box Plots: Help identify outliers and the spread of data, showing the median, quartiles, and any extreme values.

  • Scatter Plots: Show relationships between two numerical variables and can highlight correlations or the absence of them.

  • Correlation Heatmaps: Show the relationships between different numerical features, highlighting correlations that could be important for predictive modeling.

Example: A scatter plot of “age” vs. “income” might reveal a trend where younger customers have lower income, while older customers earn higher salaries. This insight could influence model feature selection or transformation.

4. Handling Missing Data

One of the most common issues encountered in real-world data sets is missing data. EDA helps identify which features have missing values, and the extent of missingness. We will use a week to discuss various imputation methods. No details will be provided in this note.

5. Identifying Outliers

Outliers are data points that differ significantly from the rest of the dataset. EDA helps in identifying outliers that could skew model performance or lead to incorrect predictions. Techniques such as box plots or Z-scores are often used to detect these extreme values. In some cases, outliers are genuine observations, while in others, they may be errors that need to be addressed.

Example: In a dataset of house prices, an outlier could be a mansion priced far below the market rate. This could either be a rare but valid instance or an error in the data entry process that requires correction.

6. Exploring Relationships Between Variables

EDA also involves investigating the relationships between variables. This helps identify whether any features are correlated or if certain variables influence others. For example, examining correlations between independent variables and the target variable (in supervised learning) can guide feature selection and help improve model performance.

Example: In a dataset predicting house prices, variables such as “square footage” and “number of bedrooms” are likely to have a strong positive correlation with the target variable, “price.”

7. Feature Engineering and Transformation

During EDA, data scientists often begin to think about how to transform features or create new ones. This might involve encoding categorical variables, normalizing numerical features, or combining features to extract new insights. EDA provides the context needed to determine which transformations are necessary and how they should be applied to the data.

Example: If “date” is a feature, it could be transformed into multiple features such as “day of the week,” “month,” or “season,” depending on the problem.

2.3.2 Importance of EDA

Guiding Data Cleaning: EDA helps identify inconsistencies, missing values, and outliers in the data that need to be addressed before model training. By cleaning the data based on insights from EDA, model performance can be significantly improved.

Improving Model Accuracy: Understanding the data’s structure, relationships, and distributions helps select the right machine learning model. For instance, knowing the target variable’s distribution might help choose between regression and classification models or influence the decision to use specific algorithms like decision trees, random forests, or neural networks.

Preventing Overfitting: By visualizing the relationships between features, EDA helps data scientists understand the complexity of the model they are building. It allows them to decide whether certain features should be included or whether some variables might lead to overfitting.

Improving Interpretability: Visualizations and statistical summaries created during EDA provide insights that can improve the interpretability of the machine learning model. Clear visualizations help stakeholders better understand the model and the results it generates.

In summary, EDA is an essential process in the machine learning pipeline, providing data scientists with a deep understanding of the dataset before building models. By summarizing the data through descriptive statistics, visualizing key relationships, and addressing potential issues such as missing data and outliers, EDA ensures that machine learning models are based on a solid foundation. Through effective EDA, practitioners can improve model accuracy, prevent biases, and make more informed decisions about data preprocessing, feature engineering, and model selection. Ultimately, EDA enhances the reliability and success of machine learning projects.

2.4 Optimal Model Identification

Identifying the right model and algorithm is essential for achieving high-performance results. The process of identifying the optimal models and algorithms is a fundamental task that can significantly influence the accuracy, efficiency, and interpretability of machine learning solutions. This subsection explores the importance of model and algorithm selection, the factors that influence these decisions, and the process of identifying the best model for a given task.

Machine learning encompasses a wide variety of tasks, such as classification, regression, clustering, and reinforcement learning, each requiring different approaches and algorithms. Given the broad range of available models and algorithms, it is essential to choose the most suitable one for the problem at hand. The right model or algorithm can help to uncover patterns in the data, make accurate predictions, and deliver actionable insights.

However, choosing the optimal model is not always straightforward. It requires an understanding of the problem domain, the nature of the data, and the performance metrics that matter most to stakeholders. Incorrectly selecting a model or algorithm can lead to overfitting, underfitting, or inefficient computation, which in turn can affect the overall quality of the model’s predictions or performance.

2.4.1 Factors Influencing Model Selection

Several factors play a role in determining which machine learning model or algorithm is most suitable for a given problem.

1. Problem Type

The nature of the problem is perhaps the most critical factor. Is it a classification task (predicting categories), regression task (predicting continuous values), clustering task (grouping data), or something else? Different problems require different algorithms.

Example. For a classification task, algorithms like logistic regression, support vector machines (SVM), decision trees, or neural networks might be considered. For a regression task, algorithms like linear regression or random forests might be more suitable.

2. Data Characteristics

The type of data, its size, and its quality all influence model selection. For instance, if the dataset is large and high-dimensional, models like deep neural networks might be more effective. Conversely, if the data is small or contains many missing values, simpler models like decision trees or k-nearest neighbors (KNN) may perform better.

Example: In cases where data is sparse or contains missing values, simpler models such as logistic regression or decision trees might be preferred over complex models like neural networks.

3. Accuracy vs. Interpretability

Some models offer high predictive accuracy but are difficult to interpret (e.g., deep neural networks), while others may provide less accuracy but offer greater interpretability (e.g., decision trees or linear regression). Depending on the application, stakeholders might prioritize one over the other.

Example: In medical applications where explainability is crucial, decision trees or logistic regression might be chosen for their transparency, even if they offer slightly lower accuracy compared to a neural network.

4. Computational Resources and Time Constraints

The computational resources required for training and deploying models should also be considered. More complex models, such as deep learning models, may require significant computing power and time to train, while simpler models can be trained more quickly and with fewer resources.

Example: In a real-time system where speed is essential, a simpler model like logistic regression may be preferred due to its lower computational cost compared to a more complex model like a deep neural network.

5. Performance Metrics

The performance metric being optimized also plays a key role in algorithm selection. Different models excel at different evaluation criteria, such as accuracy, precision, recall, F1 score, or area under the ROC curve (AUC). The choice of metric depends on the task and the specific goals of the project.

Example: In a fraud detection system, precision and recall might be prioritized over accuracy to ensure that fraudulent activities are detected with minimal false negatives.

2.4.2 Process of Model Identification

Selecting the optimal model and algorithm typically involves several key steps in the machine learning pipeline. These steps help guide the practitioner through the process of experimentation, evaluation, and refinement.

1. Data Preprocessing

Before selecting a model, it is essential to preprocess the data. This includes handling missing values, encoding categorical variables, scaling numerical features, and performing any necessary transformations. Proper data preparation ensures that the chosen model receives clean, structured input, improving its ability to make accurate predictions.

2. Model Selection Based on Problem Type

The first step in identifying the optimal algorithm is to select a model based on the problem type. For supervised learning tasks like classification and regression, a wide array of models may be tested. These include:

  • For Classification: Logistic regression, decision trees, support vector machines, k-nearest neighbors, and ensemble methods like random forests and gradient boosting.

  • For Regression: Linear regression, decision trees, random forests, support vector regression, and neural networks.

  • For Clustering: K-means, hierarchical clustering, DBSCAN, and Gaussian mixture models.

3. Model Training and Evaluation

Once the models are selected, they are trained on the available dataset. It is essential to split the dataset into training, validation, and test sets to avoid overfitting and ensure that the model generalizes well to unseen data. Model evaluation is done using appropriate performance metrics (e.g., accuracy, precision, recall, etc.).

Cross-validation techniques, such as k-fold cross-validation, are often used to further assess model performance and stability. This process helps determine how well the model will perform on unseen data and prevents overfitting by ensuring the model generalizes well.

4. Hyperparameter Tuning

Many machine learning algorithms have hyperparameters that need to be tuned for optimal performance. These hyperparameters control various aspects of the model, such as the learning rate, regularization strength, and the depth of decision trees. Hyperparameter tuning is typically done using grid search or randomized search techniques, which involve training the model multiple times with different hyperparameter values and selecting the set that results in the best performance.

5. Model Comparison

After training and tuning several models, the performance of each model is compared using the selected metrics. This comparison allows practitioners to evaluate the trade-offs between models in terms of accuracy, interpretability, and computational efficiency.

Example: If a decision tree model offers high interpretability but lower accuracy compared to a random forest model, a decision might be made to prioritize accuracy over interpretability, depending on the project’s needs.

6. Model Deployment and Monitoring

Once the optimal model has been identified, it is deployed into production. Continuous monitoring is essential to ensure that the model continues to perform well as new data is collected. If performance drops over time, the model may need to be retrained or updated.

2.4.3 Challenges in Model Selection

The process of identifying the optimal model is not without challenges. Some of the key difficulties include:

Model Complexity vs. Performance: More complex models may achieve higher accuracy but require more computational resources and are more prone to overfitting. Balancing complexity with performance is a common challenge.

Data Quality: Poor data quality, including missing values, imbalanced classes, or noisy data, can make it difficult to identify the optimal model, as the model’s performance may be affected by the underlying issues in the data.

Overfitting: Selecting a model that performs well on training data but poorly on test data due to overfitting can be a significant challenge. Techniques such as cross-validation and regularization are used to mitigate this issue.


In summary, identifying the optimal models and algorithms in machine learning is a crucial task that requires careful consideration of various factors, including the problem type, data characteristics, available resources, and performance metrics. The process involves experimenting with different models, training and evaluating them, tuning their hyperparameters, and selecting the best-performing model. While the selection process can be challenging due to issues like data quality, overfitting, and model complexity, following a structured approach can lead to the identification of the most suitable model for the task at hand. As machine learning continues to evolve, selecting the right model will remain a critical factor in delivering accurate, efficient, and impactful solutions

2.5 Validation and Testing

Validation and testing are critical phases in the machine learning (ML) workflow. These steps ensure that the model built on the training data is not only accurate but also generalizes well to new, unseen data. Without effective validation and testing, a model might appear to perform well during training but fail to deliver reliable results in real-world applications. This subsection explores the importance of validation and testing, the methods commonly used, and their role in building robust machine learning models.

2.5.1 The Importance of Validation and Testing

Machine learning models are trained on a specific dataset, known as the training dataset, which contains examples used to teach the model. However, the ultimate goal is to develop a model that can make accurate predictions on new data—data it has not encountered before. This is where validation and testing come into play.

  • Validation is used to tune model hyperparameters and assess the model’s performance during training. It helps in selecting the best model configuration before final testing, ensuring that the model does not simply memorize the training data (a phenomenon known as overfitting).

  • Testing evaluates the model’s final performance on an independent set of data, known as the test dataset, that was not used in any part of the model’s training or validation. This final evaluation ensures that the model generalizes well to new data.

Without proper validation and testing, there is a risk of developing a model that works well on the training data but fails to generalize, leading to poor real-world performance. Thus, these steps are crucial to model reliability and accuracy.

2.5.2 Validation Techniques

Validation methods are used to assess the model’s performance during the training process, before it is tested on unseen data. Several techniques are commonly employed for this purpose:

Holdout Method

The simplest form of validation, the holdout method involves splitting the data into two or three sets: a training set, a validation set, and sometimes a test set. The model is trained on the training set and validated on the validation set to evaluate its performance. The test set remains completely untouched during training and validation.

Example: A typical split might involve using 70% of the data for training, 15% for validation, and 15% for testing. The model is trained on the 70%, tuned using the 15% validation set, and finally tested on the remaining 15%.

K-Fold Cross-Validation

One of the most popular techniques, k-fold cross-validation divides the data into k equal parts, or “folds.” The model is trained k times, each time using k-1 folds for training and the remaining fold for validation. This process is repeated until each fold has been used as the validation set once. K-fold cross-validation is particularly useful when the dataset is small, as it allows the model to be validated on different portions of the data.

Example: In 5-fold cross-validation, the data is divided into five parts. The model is trained on four parts and validated on the remaining one, and this process is repeated five times, ensuring that every data point is used for validation.

Stratified K-Fold Cross-Validation

A variation of k-fold cross-validation, stratified k-fold cross-validation ensures that each fold has the same proportion of each class as the entire dataset. This is particularly useful when the dataset is imbalanced, as it ensures that the training and validation sets represent the data distribution accurately.

Example: In a binary classification task where the data is imbalanced (e.g., 90% class A, 10% class B), stratified k-fold ensures that each fold contains a similar ratio of class A to class B.

Leave-One-Out Cross-Validation (LOOCV)

In leave-one-out cross-validation, each data point is used as a separate validation set while the rest of the data points are used for training. This process is repeated for each data point in the dataset, which is particularly useful when the dataset is small.

Example: For a dataset of 100 data points, LOOCV trains the model 100 times, each time leaving out a different single data point for validation.

These validation techniques help prevent overfitting, ensure that the model is well-tuned, and make the most out of available data.

2.5.3 Testing the Model

Once the model has been trained and validated, it is crucial to evaluate its performance on a separate test dataset. The test set is used to assess how well the model generalizes to new, unseen data. This evaluation provides an estimate of how the model will perform in production or on new incoming data.

Test Dataset

The test dataset should never be used in any part of the model-building process, including during training or validation. Its sole purpose is to serve as an independent assessment of the model’s generalization capability.

Performance Metrics

The performance of the model is measured using various metrics, which depend on the type of problem (e.g., classification, regression). Common metrics include:

  • For Classification: Accuracy, precision, recall, F1 score, area under the ROC curve (AUC), confusion matrix.

  • For Regression: Mean squared error (MSE), root mean squared error (RMSE), mean absolute error (MAE), R-squared.

These metrics allow practitioners to evaluate how well the model makes predictions, detect biases, and understand areas where the model may require improvement.

Example For a classification problem, accuracy alone might not be sufficient, especially if the classes are imbalanced. In this case, metrics like precision, recall, and F1 score can provide more insight into model performance.

Model Comparison

Once the model is tested, it can be compared to baseline models or other competing models to determine whether it provides a significant improvement. If multiple models are considered, statistical tests like paired t-tests or cross-validation results can be used to determine which model performs best.

Example: A decision tree model might be compared to a random forest model or a support vector machine. The model with the highest performance metrics and generalization ability would be chosen for deployment.

Overfitting and Underfitting

After testing the model, it’s important to ensure that it is not overfitting (i.e., performing exceptionally well on the training data but poorly on unseen data) or underfitting (i.e., not capturing the underlying patterns in the data well enough). These issues can be diagnosed using the difference between performance on the training set, validation set, and test set.

Example: A model that shows high performance on the training set but performs poorly on the test set may be overfitting, indicating the need for regularization or more data.


In summary, both validation and testing play a key role in model optimization. Validation helps fine-tune the model during the training process, ensuring that it is not overfitting or underfitting the data. Once a model is finalized, testing provides the final evaluation of its ability to generalize to new data. By using proper validation techniques, machine learning practitioners can build models that are robust, accurate, and capable of delivering reliable results on real-world data.

2.6 Reporting Actionable Results

Translating statistical or model outputs into actionable insights is crucial. Interpreting results in terms of their real-world implications adds value to the report.

  • Actionable Insights: Discuss how stakeholders can use the findings to make informed decisions or address challenges.

  • Policy or Strategy Recommendations: Suggest specific policies, strategies, or interventions based on the results.

  • Scalability and Generalizability: Explain whether the findings can be applied beyond the analyzed sample or context.

For example, in an environmental impact study, interpreting results might involve recommending changes in agricultural practices to reduce carbon emissions.

3 Drafting Effective Reports

Technical report writing is a vital skill for data scientists, enabling them to communicate complex findings and analyses to various stakeholders effectively. A well-structured technical report ensures clarity, precision, and relevance, making it easier for readers to understand and act upon the information provided. Below are guidelines and best practices for crafting effective technical reports in data science.

3.1 What to Report

In statistics and data science, effective reporting is crucial for transparency, reproducibility, and actionable insights. The way findings are communicated can significantly influence decision-making and the ability of others to understand, replicate, and build upon the work. Proper reporting ensures that the analysis is credible, meaningful, and useful to stakeholders. This subsection discusses the key components that should be reported in statistics and data science projects, emphasizing clarity, accuracy, and ethical considerations.

3.1.1 Problem Definition and Objectives

Every data science or statistical report should begin with a clear articulation of the problem being addressed. This includes:

  • Research Questions: What specific questions or hypotheses is the analysis trying to answer or test?

  • Objectives: What are the goals of the analysis, such as making predictions, understanding relationships, or identifying trends?

  • Context: Background information about the domain, industry, or problem being addressed to provide stakeholders with a comprehensive understanding.

3.2 Data Description and Sources

Understanding the data is fundamental to the credibility of the analysis. Include:

  • Data Sources: The origin of the data, whether collected internally, scraped from the web, or sourced from publicly available repositories.

  • Data Characteristics: Description of the dataset, including size, number of variables, data types, and whether the data is structured or unstructured.

  • Data Collection Methods: How the data was collected (e.g., surveys, sensors, experiments) and any sampling methods used.

  • Ethics and Privacy: A discussion of ethical considerations, including how data privacy was ensured and whether appropriate permissions or consents were obtained.

3.2.1 Data Cleaning and Preprocessing

Before analysis, data often requires cleaning and preprocessing. Report:

  • Handling of Missing Data: Methods used to address missing values (e.g., imputation, removal).

  • Outlier Treatment: Identification and handling of outliers.

  • Data Transformation: Any transformations applied to make the data suitable for analysis, such as scaling, encoding, or normalizing.

  • Data Quality Issues: Challenges encountered, such as inconsistencies, duplicates, or biases in the data.

3.2.2 Exploratory Data Analysis (EDA)

EDA provides insights into the data’s structure and relationships. Report:

  • Descriptive Statistics: Summary statistics such as mean, median, standard deviation, and frequency distributions.

  • Visualization: Key visualizations that reveal trends, patterns, or anomalies (e.g., histograms, scatter plots, correlation heatmaps).

  • Initial Insights: Observations from the data, such as relationships between variables or potential challenges for the modeling phase.

  • Feature Engineering: Additional feature creation and extraction based on models and algorithms.

3.2.3 Methodology

Transparency in the methods used ensures reproducibility and aids interpretation.

  • Statistical Methods or Models: A detailed explanation of the statistical methods or machine learning models used.

  • Assumptions: Assumptions underlying the chosen methods and whether they were tested (e.g., normality, linearity, independence).

  • Hyperparameters and Tuning: Specific parameters of the models and the process for optimizing them.

3.2.4 Validation and Testing

To ensure reliability, describe the validation and testing process:

  • Train-Test Split: How the data was divided into training, validation, and test sets, including proportions and methods (e.g., random sampling, stratified sampling).

  • Validation Techniques: Approaches used, such as k-fold cross-validation or holdout validation.

  • Performance Metrics: Metrics used to evaluate model performance (e.g., accuracy, precision, recall, F1 score, AUC, mean squared error).

3.2.5 Results, Interpretatons, and Discussions

The results should be presented clearly and objectively, including:

Key Findings: Highlight the most important insights derived from the analysis and avoid reporting everything the outputs of the final models. The intermediate candidate models that are not cited to support your arguments should not be discussed in the report.

Model Performance: Detailed performance metrics, including comparisons between candidate models or methods. Make sure the performance metrics are at the same scale and comparable.

Statistical Significance: Report p-values, confidence intervals, and effect sizes, if applicable, of the final model(s) to be recommended to clients and/or to be deployed in production environment.

Visualizations: Charts, graphs, or tables that effectively communicate the results. Try interactive visual representations whenever possible and follow best practices in visual design.

Discussion and Interpretation Discuss the results and their practical implications.

  • Insights: Explain the meaning of the findings and how they address the research questions or objectives.

  • Limitations: Acknowledge any limitations in the data, methodology, or generalizability of the results.

  • Contextual Relevance: Discuss how the findings relate to the problem domain and contribute to decision-making.

3.2.6 Ethical Considerations and Reproducibility

Ethical transparency is a growing priority in data science.

  • Bias and Fairness: Assess and address biases in the data or models.
  • Privacy and Security: Measures taken to protect sensitive data.
  • Impact of Results: Consider potential consequences of the analysis, especially if it influences policy or business decisions.

Reproducibility ensures that others can replicate the analysis by reporting

  • Code and Tools: The programming languages, libraries, and software tools used.
  • Parameters and Settings: Specific settings, configurations, or seeds used in the analysis.
  • Access to Data and Code: Whether the data and code are available and how they can be accessed (while adhering to privacy and copyright restrictions).

3.2.7 Conclusion and Recommendations

Summarize and provide actionable insights:

Summary: Recap the problem, approach, and key findings.

Recommendations: Offer suggestions for stakeholders, such as policy changes, further analysis, or business strategies.

Future Work: Highlight areas for additional exploration or improvement.


In summary, effective reporting in statistics and data science requires clarity, accuracy, and thoroughness. By addressing the problem, data, methods, results, and implications, analysts can ensure that their findings are understandable, actionable, and reproducible. Additionally, ethical considerations and reproducibility are integral to building trust and fostering responsible data science practices. A comprehensive report not only showcases the technical rigor of the analysis but also bridges the gap between complex data science processes and actionable insights for stakeholders.

3.3 Structure of a Technical Report

In the fields of statistics and data science, effective communication of findings is paramount. A well-structured report allows stakeholders to understand the analysis, evaluate its reliability, and derive actionable insights. The structure of such a report must balance technical rigor with clarity to cater to both technical and non-technical audiences.

3.3.1 Title and Abstract

The title and abstract are the first components of the report that readers encounter.

Title: A concise and descriptive title should accurately reflect the content of the report. It should include key terms relevant to the analysis to immediately inform readers about the scope of the work.

Abstract: The abstract provides a brief summary of the report, typically in 150–250 words. It outlines the problem, methodology, key results, and main conclusions. The abstract helps readers quickly determine the report’s relevance to their needs. Abstract is an optional component of all reports in this class. However, you are encouraged to include the abstaract in yout report

3.3.2 Introduction

The introduction sets the stage for the report by providing context and defining its objectives.

Background: Explain the problem domain and why the analysis is important. This includes a discussion of any prior work or challenges that necessitated the analysis.

Objectives: Clearly state the goals of the report, such as answering specific research questions, testing hypotheses, or developing predictive models.

Scope: Define the boundaries of the analysis, including any assumptions or limitations known at the outset.

Clear Problem Statements: The research/practical questions must clearly defined and are translate to analytic questions accurately.

3.3.3 Data Description

This section provides detailed information about the data used in the analysis.

Data Sources: Describe where the data originated, whether from internal systems, external repositories, or experimental collection methods.

Data Characteristics: Provide an overview of the dataset, including the number of observations, variables, and types of data (e.g., categorical, numerical, text).

Ethical Considerations: Highlight any measures taken to ensure ethical use of the data, such as anonymization or obtaining consent.

3.3.4 Methodology

The methodology section outlines the steps taken to process and analyze the data.

Data Preprocessing: Describe how missing values, outliers, or inconsistencies were handled, along with any transformations or feature engineering performed.

Exploratory Data Analysis (EDA): Summarize the key exploratory steps, such as identifying distributions, relationships, and patterns. Include relevant visualizations and descriptive statistics.

Feature Engineering: Summarize all feature engineering procedures that are justified and performed in the analysis.

Modeling and Analysis: Specify the statistical methods, machine learning algorithms, or analytical frameworks used. Include details about parameter tuning, feature selection, and any assumptions tested.

3.3.5 Reporting Results

The results section presents the findings of the analysis in an organized and interpretable manner.

Descriptive Results: Highlight key statistics, trends, and relationships discovered during EDA.

Model Performance: Provide metrics evaluating the performance of models, such as accuracy, precision, recall, or R-squared, depending on the task.

Visualizations: Include charts, graphs, or tables that effectively communicate findings. Use annotations and captions for clarity.

3.3.6 Discussion and Recommendations

The discussion interprets the results and connects them to the original objectives.

Interpretation of Results: Explain what the findings mean in the context of the problem. Discuss whether the results answered the research questions or hypotheses.

Comparison with Prior Work: If applicable, compare the findings to previous studies or analyses to highlight similarities, differences, or improvements.

Limitations: Acknowledge any limitations in the data, methods, or generalizability of the results. For example, discuss potential biases or assumptions that may have influenced the analysis.

Recommendations: Offer suggestions for decision-makers based on the results, such as changes to policies, strategies, or further research.

Conclusions: Recap the key points of the report, emphasizing the problem, major findings, and their implications.

###. References and Appendices

Cite all sources of data, tools, methods, and prior research used in the report. Use a standard citation format (e.g., APA, IEEE) to ensure proper attribution. Appendices provide additional details that support the main report but are not essential to the primary narrative.


In summary, a statistics and data science report is more than just a collection of numbers and charts; it is a structured narrative that guides readers through the analysis process and its findings. By adhering to a clear structure—including an abstract, introduction, data description, methodology, results, discussion, recommendations, and appendices—analysts can effectively communicate complex ideas. This structured approach ensures that the report is comprehensive, transparent, and accessible to a diverse audience, ultimately enabling data-driven decision-making.

3.4 Reporting Formatting Guidelines

In the field of statistics and data science, how information is presented can be as important as the analysis itself. Proper formatting ensures that reports are clear, organized, and professional, making them accessible to diverse audiences. Effective formatting enhances readability, facilitates understanding, and ensures that key findings are not lost in a sea of data or technical jargon. This subsection outlines the essential formatting guidelines for statistics and data science reporting, covering structural organization, visual aids, and stylistic elements.

1. Structural Organization

A well-structured report follows a logical flow, guiding readers from problem definition to actionable insights.

  • Sections and Subsections: Use headings and subheadings to organize content into distinct sections, such as Introduction, Data Description, Methodology, Results, and Conclusions. Number sections for easy reference (e.g., 1.0, 1.1, 2.0).

  • Table of Contents: For longer reports, include a table of contents to provide an overview and enable quick navigation.

  • Consistency: Ensure consistent placement and formatting of titles, subtitles, and section breaks throughout the document.

2. Visual Aids and Data Representation

Visual representation is a cornerstone of effective communication in statistics and data science.

  • Tables: Use tables to summarize numerical data, making it easy for readers to compare values. Ensure tables have clear headings and appropriate alignment (e.g., right-align for numbers, left-align for text).

  • Charts and Graphs: Include charts such as histograms, scatter plots, and bar graphs to visualize trends, distributions, and relationships. Choose chart types that best convey the intended message and avoid cluttered or overly complex visuals.

  • Labels and Captions: Label all figures and tables clearly, and provide descriptive captions that explain their relevance to the analysis.

  • Color and Accessibility: Use colors sparingly and ensure accessibility by selecting colorblind-friendly palettes and patterns.

3. Typography

Legible and professional typography enhances readability and maintains audience engagement.

  • Font Style and Size: Use simple, professional fonts such as Times New Roman, Arial, or Calibri, with a standard size (e.g., 11–12 pt for body text, 14–16 pt for headings).

  • Spacing: Apply appropriate line spacing (1.15 or 1.5) and margins (e.g., 1 inch) to make the text easy to read and avoid overcrowding.

  • Bold and Italics: Use bold for section headings and italics for emphasis or referencing technical terms, but avoid excessive use.

4. Writing Style

Clarity and conciseness are vital for statistical and data science reports.

  • Technical Language: Use precise language appropriate for the target audience. For non-technical readers, explain jargon and technical terms in a glossary or footnotes.

  • Active Voice: Write in an active voice to make statements more direct and engaging (e.g., “We analyzed the data,” instead of “The data was analyzed”).

  • Paragraph Length: Keep paragraphs concise, focusing on one main idea at a time. Use bullet points or numbered lists to summarize key points.

  • Opening Paragraphs:

3.5 Writing Best Practices

Effective communication is integral to the success of statistics and data science projects. A well-crafted report bridges the gap between complex analyses and actionable insights, enabling stakeholders to make informed decisions. Best practices in report writing focus on clarity, transparency, accuracy, and accessibility.

1. Begin with a Clear Structure

The foundation of a great report lies in its structure. Organizing the content in a logical and predictable format helps readers navigate the document effortlessly.

  • Title and Abstract: Start with a descriptive title and a concise abstract summarizing the problem, methodology, key findings, and conclusions.

  • Section Headings: Use well-defined sections such as Introduction, Data Description, Methodology, Results, Discussion, and Recommendations. These sections create a roadmap for the report.

  • Appendices: Include supplementary materials such as detailed tables, charts, or code in appendices to avoid cluttering the main text.

2. Know Your Audience

Understanding the target audience is crucial for effective communication.

  • Tailor Content: Adjust the level of detail and technical complexity to suit the audience. For technical readers, include in-depth explanations, algorithms, and code. For non-technical stakeholders, focus on key insights and business implications.

  • Define Terms: Avoid assuming familiarity with jargon or technical terms. Provide clear definitions or include a glossary for unfamiliar concepts.

3. Prioritize Clarity and Simplicity

A report should communicate complex ideas in a way that is easy to understand.

  • Concise Writing: Avoid verbosity by presenting ideas succinctly. Use bullet points and numbered lists to summarize key points.

  • Active Voice: Use active voice for direct and engaging sentences (e.g., “We analyzed the data,” instead of “The data was analyzed”).

  • Logical Flow: Present the content in a logical sequence, leading readers step-by-step through the analysis.

4. Ensure Transparency and Reproducibility

Transparency builds trust in the findings, while reproducibility allows others to validate the work.

  • Data Description: Provide detailed information about the dataset, including sources, collection methods, and characteristics.

  • Methodology: Clearly explain the steps taken in preprocessing, exploratory analysis, modeling, and validation. Mention any assumptions or limitations of the methods used.

  • Code and Tools: Share the programming tools, libraries, and code snippets used in the analysis, adhering to any applicable data-sharing and privacy constraints.

5. Emphasize Visual Communication

Visual elements enhance understanding and make the report more engaging.

  • Data Visualizations: Use charts, graphs, and plots to represent data and findings. Ensure each visualization is labeled, captioned, and easy to interpret.

  • Clarity in Design: Avoid overcrowding visuals with excessive information. Use clean, minimalist designs with color schemes accessible to colorblind readers.

  • Comparative Analysis: When presenting multiple models or scenarios, use side-by-side visual comparisons to highlight differences.

6. Present Results Objectively

Objectivity in presenting results is critical for credibility.

  • Report All Results: Include both positive and negative findings. Acknowledge any inconsistencies or unexpected outcomes.

  • Performance Metrics: Clearly explain the metrics used to evaluate models (e.g., accuracy, precision, recall, F1 score, ROC and AUC, etc.) and why they were chosen.

  • Statistical Significance: Highlight statistical significance, confidence intervals, and effect sizes to provide context for the results.

7. Address Ethical Considerations

Ethics are an integral part of statistics and data science reporting.

  • Bias and Fairness: Discuss potential biases in the data or methods and their implications for the results.

  • Privacy and Consent: Explain how privacy concerns were addressed, including measures for anonymization or secure data handling.

  • Impact Analysis: Consider the broader implications of the findings, especially if they influence policy or decision-making.

8. Focus on Actionable Insights

A key goal of data science reports is to provide insights that stakeholders can act upon.

  • Business Relevance: Relate findings back to the original problem or objectives.

  • Recommendations: Offer clear, evidence-based recommendations for next steps or decisions.

  • Future Work: Suggest areas for further research or potential improvements in methodology.


4 Web-based Effective Presentation

In an increasingly digital world, web-based presentations have become a critical tool for communication, education, and business. Unlike traditional formats, web-based presentations must cater to the dynamics of online platforms, ensuring they engage audiences and convey messages effectively in a virtual environment. This essay outlines key principles and strategies for designing effective web-based presentations, focusing on content structure, visual appeal, interactivity, and accessibility.

4.1 Clear and Logical Structure

An effective web-based presentation begins with a well-organized structure to guide the audience through the content seamlessly.

Define Objectives: Start by identifying the purpose of the presentation and the key takeaways for the audience. This helps in aligning the content with the goals.

Outline the Flow: Arrange slides in a logical sequence—beginning with an introduction, followed by the main content, and ending with a strong conclusion or call to action.

Chunk Information: Break complex information into smaller, digestible sections to maintain the audience’s focus and avoid cognitive overload.

For instance, a presentation on data analytics might start with an overview of the field, proceed to methods and tools, and conclude with real-world applications.

4.2 Visual Design and Aesthetics

The visual design and aesthetics of presentation slides play a critical role in capturing attention, conveying information effectively, and maintaining audience engagement. Good design ensures that the message is not only clear but also memorable. This subsection explores key principles and strategies for achieving effective visual design and aesthetics in presentation slides, emphasizing clarity, consistency, and audience-centered design.

1. The Role of Visual Design in Presentations

Visual design is not just about making slides look appealing—it serves to enhance communication and understanding.

  • Attracting Attention: Well-designed slides can immediately capture the audience’s interest and set a positive tone for the presentation.

  • Improving Comprehension: Visual elements like charts, diagrams, and color-coded highlights make complex information easier to understand.

  • Maintaining Engagement: Aesthetic and dynamic design keeps the audience focused and prevents monotony. Reinforcing Messaging: Consistent and thoughtful design choices strengthen the impact of the presented message.

For example, a presentation on renewable energy benefits from visually appealing graphs and images of wind turbines and solar panels to highlight key points effectively.

2. Key Principles of Slide Design

Achieving strong visual design involves adhering to fundamental design principles that prioritize clarity and coherence.

  • Simplicity: Keep slides clean and uncluttered. Focus on one main idea per slide to avoid overwhelming the audience.

  • Hierarchy: Use visual hierarchy to guide the audience’s attention. Larger fonts, bold text, and contrasting colors can emphasize key points.

  • Balance: Arrange elements symmetrically or asymmetrically to create harmony and avoid a cluttered appearance.

  • Alignment: Align text, images, and other elements for a polished and professional look. Misaligned objects can appear unprofessional and distract from the message.

  • Contrast: Ensure sufficient contrast between text and background colors to enhance readability, especially in low-light settings.

For instance, using a bold, large font for headings and smaller, lighter text for supporting details creates a clear visual hierarchy.

3. Effective Use of Colors

Colors are a powerful tool for setting the tone and enhancing the readability of slides.

  • Consistent Color Scheme: Stick to a limited palette of 2–4 colors that align with the presentation’s theme or brand identity.

  • Purposeful Colors: Use colors to emphasize specific points, such as red for warnings or green for positive outcomes.

  • Readable Combinations: Avoid low-contrast combinations like light text on a light background. Dark text on a light background or vice versa is generally more legible.

  • Psychological Impact: Consider the emotional and psychological associations of colors. For example, blue conveys trust and professionalism, while orange suggests energy and creativity.

For example, a healthcare presentation might use calming blues and whites to instill trust and professionalism.

4. Less Text, More Storytelling

Slides overloaded with text can disengage audiences and obscure the core message. Instead, embracing storytelling with visuals can create a more impactful and memorable experience. This approach transforms slides from static reading material into a dynamic tool that supports the presenter’s narrative, engaging the audience on a deeper emotional and intellectual level. Minimizing text on slides forces the presenter to engage the audience directly and focus on key points.

  • One Idea Per Slide: Limit each slide to a single concept to avoid overwhelming the audience.

  • Bullet Point Reduction: Replace long lists of bullet points with succinct phrases, visuals, or icons.

  • Presenter-Centered Delivery: Use the slides as prompts for speaking rather than as a script.

5. Incorporating Visual Elements

Visual elements like images, icons, and charts can enhance slides by making abstract concepts tangible and data more relatable.

  • High-Quality Images: Use sharp, relevant images that align with the presentation’s topic. Avoid pixelated or generic stock photos.

  • Infographics and Charts: Use well-designed charts and infographics to present data clearly. Select the right type of chart (e.g., bar, line, pie) for the data.

  • Icons: Add icons to illustrate points and break up text. Use a consistent icon style for visual harmony.

  • White Space: Allow for white space around visuals to prevent overcrowding and maintain a clean, organized appearance.

For example, a financial report presentation could include a line graph showing trends over time, accompanied by icons representing key milestones.

6. Animations and Transitions

Animations and transitions can enhance the flow of a presentation but must be used judiciously.

  • Subtle Animations: Use animations sparingly to draw attention to important elements without distracting the audience.

  • Consistent Transitions: Apply a uniform transition style across slides to maintain visual continuity.

  • Avoid Overuse: Excessive or flashy animations can detract from the message and appear unprofessional.

For instance, using a fade-in animation to introduce bullet points one by one helps maintain audience focus without being distracting.

7. Designing for Accessibility

Aesthetic design should also account for the diverse needs of the audience, ensuring accessibility for all.

  • Readable Fonts: Choose fonts that are legible for viewers with visual impairments, avoiding overly ornate or narrow typefaces.

  • Colorblind-Friendly Palette: Use color combinations that are distinguishable for individuals with color vision deficiencies.

  • Alt Text: Add alt text descriptions to images for audiences relying on screen readers.

  • Responsive Design: Optimize slides for various devices, especially in virtual presentations where viewers may use smartphones or tablets.

For example, a presentation on public policy should use distinct patterns or labels in charts instead of relying solely on color differentiation.

4.3 Interactive and Dynamic Elements

Interactive content in presentation slides can significantly enhance audience engagement and comprehension by transforming a passive experience into an active one. It allows presenters to tailor the delivery to audience interests, foster participation, and provide a more dynamic presentation. To maximize the effectiveness of interactive content, adhere to the following principles:

  • Purposeful Interactivity: Ensure every interactive element has a clear purpose that supports the presentation’s goals. Avoid adding features just for novelty.

  • Simplicity: Keep interactive elements intuitive and easy to use. Overly complex designs can confuse and disengage the audience.

  • Test Functionality: Verify that all interactive features work as intended, especially when presenting on unfamiliar equipment or platforms.

  • Balance with Content: Interactivity should complement, not overshadow, the core message of the presentation.

4.4 Accessibility and Inclusivity

Designing presentation slides with accessibility and inclusivity in mind ensures that all audience members, regardless of their abilities or backgrounds, can fully engage with and understand the content. This approach not only reflects respect and consideration but also broadens the reach and impact of the presentation.

1. Text Accessibility

Text content should be clear, legible, and structured for all viewers.

  • Readable Fonts: Use simple, sans-serif fonts like Arial or Calibri, avoiding decorative styles.

  • Sufficient Font Size: Ensure text is large enough to be read from a distance, typically 24–36 points for body text and 36–44 points for headings.

  • Contrast: Use high contrast between text and background, such as dark text on a light background or vice versa.

  • Text Hierarchy: Use headings, subheadings, and bullet points to organize content logically and make it scannable.

2. Visual and Graphic Accessibility

Images, charts, and other visuals should be accessible and inclusive.

  • Alt Text for Images: Provide alternative text descriptions for images to support audience members using screen readers.

  • Colorblind-Friendly Design: Avoid relying solely on color to convey information. Use patterns, labels, or text annotations in graphs and charts.

  • Simple Visuals: Avoid overly complex graphics that may overwhelm or confuse the audience. White Space: Use sufficient white space to avoid visual clutter and make content easier to focus on.

3. Inclusive Language and Content

Inclusivity goes beyond technical design to encompass the presentation’s tone and language.

  • Avoid Jargon: Use clear, straightforward language to ensure the content is accessible to people with varying levels of expertise.

  • Cultural Sensitivity: Avoid idioms, metaphors, or references that may not translate well across cultures.

  • Representation: Include diverse examples, images, and perspectives to reflect the audience’s varied backgrounds.


In summary, designing effective web-based presentations requires a thoughtful approach that integrates clear structure, engaging visuals, interactivity, accessibility, and practical delivery strategies. By focusing on these elements, presenters can create impactful online experiences that resonate with diverse audiences. As virtual communication continues to grow, mastering the art of web-based presentation design will be an essential skill for professionals across industries.

LS0tDQp0aXRsZTogJ0RhdGEgQW5hbHlzaXMsIFJlcG9ydGluZywgYW5kIFByZXNlbnRhdGlvbiBXb3JrZmxvdycNCmF1dGhvcjogIkNoZW5nIFBlbmciDQpkYXRlOiAiV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7PWh0bWx9DQoNCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoNCi8qIENhc2NhZGluZyBTdHlsZSBTaGVldHMgKENTUykgaXMgYSBzdHlsZXNoZWV0IGxhbmd1YWdlIHVzZWQgdG8gZGVzY3JpYmUgdGhlIHByZXNlbnRhdGlvbiBvZiBhIGRvY3VtZW50IHdyaXR0ZW4gaW4gSFRNTCBvciBYTUwuIGl0IGlzIGEgc2ltcGxlIG1lY2hhbmlzbSBmb3IgYWRkaW5nIHN0eWxlIChlLmcuLCBmb250cywgY29sb3JzLCBzcGFjaW5nKSB0byBXZWIgZG9jdW1lbnRzLiAqLw0KDQpoMS50aXRsZSB7ICAvKiBUaXRsZSAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgdGhlIHJlcG9ydCB0aXRsZSAqLw0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGF1dGhvcnMgICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IG5hdnk7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciB0aGUgZGF0ZSAgKi8NCiAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQp9DQpoMSB7IC8qIEhlYWRlciAxIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgbGV2ZWwgMSBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDIgeyAvKiBIZWFkZXIgMiAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGxldmVsIDIgc2VjdGlvbiB0aXRsZSAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgbGV2ZWwgMyBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgbGV2ZWwgNCBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMTRweDsNCiAgICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCn0NCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KPC9zdHlsZT4NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJHR2FsbHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiR0dhbGx5IikNCmxpYnJhcnkoR0dhbGx5KQ0KfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KYGBgDQoNClwNCg0KIyBJbnRyb2R1Y3Rpb24NCg0KRGF0YSBzY2llbmNlIGlzIGEgZHluYW1pYyBmaWVsZCB0aGF0IGZvY3VzZXMgb24gZ2F0aGVyaW5nLCBhbmFseXppbmcsIGFuZCBpbnRlcnByZXRpbmcgbGFyZ2UgZGF0YXNldHMgdG8gdW5jb3ZlciB2YWx1YWJsZSBpbnNpZ2h0cyB0aHJvdWdoIHRoZSB1c2Ugb2Ygc3RhdGlzdGljYWwgdGVjaG5pcXVlcyBhbmQgbWFjaGluZSBsZWFybmluZyBtZXRob2RzLiBIb3dldmVyLCB0aGUgdWx0aW1hdGUgdmFsdWUgb2YgZGF0YSBzY2llbmNlIHdvcmsgbGllcyBub3Qgb25seSBpbiB0aGUgcXVhbGl0eSBvZiB0aGUgYW5hbHlzaXMgYnV0IGFsc28gaW4gaG93IGVmZmVjdGl2ZWx5IHRoZSByZXN1bHRzIGFyZSBjb21tdW5pY2F0ZWQuIEVmZmVjdGl2ZSB0ZWNobmljYWwgY29tbXVuaWNhdGlvbiBpcyBlc3NlbnRpYWwgaW4gZW5zdXJpbmcgdGhhdCBjb21wbGV4IGZpbmRpbmdzIGFyZSB1bmRlcnN0b29kLCBhY3RlZCB1cG9uLCBhbmQgdXNlZCB0byBtYWtlIGluZm9ybWVkIGRlY2lzaW9ucy4gVGhpcyBub3RlIG91dGxpbmVzIHRoZSBrZXkgZWxlbWVudHMgb2YgZWZmZWN0aXZlIHRlY2huaWNhbCBjb21tdW5pY2F0aW9uIGluIGRhdGEgc2NpZW5jZSwgZm9jdXNpbmcgb24gcmVwb3J0aW5nLCBwcmVzZW50YXRpb25zLCBhbmQgZGlzY3Vzc2lvbnMuDQoNCioqQ2xhcml0eSBhbmQgU2ltcGxpY2l0eSBpbiBSZXBvcnRpbmcqKg0KDQpPbmUgb2YgdGhlIG1vc3QgY3JpdGljYWwgZWxlbWVudHMgb2YgZWZmZWN0aXZlIGNvbW11bmljYXRpb24gaW4gZGF0YSBzY2llbmNlIGlzIGNsYXJpdHkuIERhdGEgc2NpZW5jZSByZXBvcnRzIG9mdGVuIGRlYWwgd2l0aCBpbnRyaWNhdGUgYWxnb3JpdGhtcywgc3RhdGlzdGljYWwgbW9kZWxzLCBhbmQgbGFyZ2UgZGF0YXNldHMsIHdoaWNoIGNhbiBvdmVyd2hlbG0gcmVhZGVycyBpZiBwcmVzZW50ZWQgcG9vcmx5LiBUZWNobmljYWwgcmVwb3J0cyBtdXN0IGF2b2lkIGphcmdvbiBhbmQgY29tcGxleCB0ZXJtaW5vbG9neSB0aGF0IG1pZ2h0IGFsaWVuYXRlIG5vbi1leHBlcnQgYXVkaWVuY2VzLiBXaGlsZSB0ZWNobmljYWwgYWNjdXJhY3kgaXMgdml0YWwsIHRoZSBsYW5ndWFnZSBzaG91bGQgYmUgYWNjZXNzaWJsZSB0byBhIHdpZGUgYXVkaWVuY2UsIGluY2x1ZGluZyBzdGFrZWhvbGRlcnMgd2hvIG1heSBub3QgaGF2ZSBhIGRlZXAgdW5kZXJzdGFuZGluZyBvZiB0aGUgbWV0aG9kcyB1c2VkLg0KDQpDbGVhciBjb21tdW5pY2F0aW9uIGNhbiBiZSBhY2hpZXZlZCBieSBzdHJ1Y3R1cmluZyByZXBvcnRzIGxvZ2ljYWxseS4gRWFjaCByZXBvcnQgc2hvdWxkIGJlZ2luIHdpdGggYW4gZXhlY3V0aXZlIHN1bW1hcnksIG91dGxpbmluZyBrZXkgZmluZGluZ3MgYW5kIHRoZWlyIGltcGxpY2F0aW9ucy4gVGhpcyBpcyBmb2xsb3dlZCBieSBkZXRhaWxlZCBzZWN0aW9ucyB0aGF0IGV4cGxhaW4gdGhlIG1ldGhvZG9sb2d5LCByZXN1bHRzLCBhbmQgY29uY2x1c2lvbnMuIEZpbmFsbHksIHJlY29tbWVuZGF0aW9ucyBzaG91bGQgYmUgcHJlc2VudGVkIGNsZWFybHksIGJhc2VkIG9uIHRoZSBkYXRhJ3MgaW5zaWdodHMuIFRvIGF2b2lkIGluZm9ybWF0aW9uIG92ZXJsb2FkLCB0aGUgcmVwb3J0IHNob3VsZCBiZSBjb25jaXNlLCB3aXRoIGEgZm9jdXMgb24gdGhlIG1vc3QgaW1wb3J0YW50IHBvaW50cywgdXNpbmcgYnVsbGV0IHBvaW50cyBvciB0YWJsZXMgdG8gc3VtbWFyaXplIGtleSBmaW5kaW5ncy4NCg0KKipWaXN1YWxpemF0aW9uOiBNYWtpbmcgQ29tcGxleCBEYXRhIEFjY2Vzc2libGUqKg0KDQpFZmZlY3RpdmUgZGF0YSBzY2llbmNlIGNvbW11bmljYXRpb24gcmVsaWVzIGhlYXZpbHkgb24gdGhlIHVzZSBvZiB2aXN1YWxpemF0aW9ucy4gRGF0YSwgaW4gaXRzIHJhdyBmb3JtLCBjYW4gYmUgY2hhbGxlbmdpbmcgdG8gaW50ZXJwcmV0LiBDaGFydHMsIGdyYXBocywgYW5kIG90aGVyIHZpc3VhbCB0b29scyBoZWxwIHRvIHByZXNlbnQgZGF0YSBpbiBhIHdheSB0aGF0IGlzIGludHVpdGl2ZSBhbmQgY29tcHJlaGVuc2libGUuIFdoZXRoZXIgaXTigJlzIGEgdGltZSBzZXJpZXMgZ3JhcGgsIGEgaGVhdG1hcCwgb3IgYSBzY2F0dGVyIHBsb3QsIHZpc3VhbGl6YXRpb25zIGNhbiBoaWdobGlnaHQgdHJlbmRzLCBjb3JyZWxhdGlvbnMsIGFuZCBvdXRsaWVycyBtb3JlIGVmZmVjdGl2ZWx5IHRoYW4gcmF3IG51bWJlcnMuDQoNCkhvd2V2ZXIsIHZpc3VhbGl6YXRpb25zIG11c3QgYmUgZGVzaWduZWQgY2FyZWZ1bGx5IHRvIGNvbnZleSB0aGUgY29ycmVjdCBtZXNzYWdlLiBQb29ybHkgZGVzaWduZWQgdmlzdWFscyBjYW4gbWlzbGVhZCBvciBjb25mdXNlIHRoZSBhdWRpZW5jZS4gSXTigJlzIGVzc2VudGlhbCB0byBjaG9vc2UgdGhlIHJpZ2h0IHR5cGUgb2YgZ3JhcGggZm9yIHRoZSBkYXRhLCB1c2UgY2xlYXIgbGFiZWxzLCBhbmQgYXZvaWQgdW5uZWNlc3NhcnkgY2x1dHRlci4gRm9yIGV4YW1wbGUsIHdoZW4gcHJlc2VudGluZyBhIGNvcnJlbGF0aW9uIG1hdHJpeCwgYSBoZWF0bWFwIHdpdGggY2xlYXIgY29sb3IgZ3JhZGllbnRzIGNhbiBxdWlja2x5IGNvbW11bmljYXRlIHdoaWNoIHZhcmlhYmxlcyBhcmUgbW9zdCBjbG9zZWx5IHJlbGF0ZWQsIG1ha2luZyBpdCBlYXNpZXIgZm9yIHRoZSBhdWRpZW5jZSB0byB1bmRlcnN0YW5kIHRoZSByZWxhdGlvbnNoaXBzIHdpdGhpbiB0aGUgZGF0YS4NCg0KKipUYWlsb3JpbmcgQ29tbXVuaWNhdGlvbiB0byB0aGUgQXVkaWVuY2UqKg0KDQpBbm90aGVyIGltcG9ydGFudCBmYWN0b3IgaW4gZWZmZWN0aXZlIHRlY2huaWNhbCBjb21tdW5pY2F0aW9uIGlzIGtub3dpbmcgeW91ciBhdWRpZW5jZS4gRGF0YSBzY2llbnRpc3RzIG9mdGVuIGNvbW11bmljYXRlIHRoZWlyIGZpbmRpbmdzIHRvIGRpdmVyc2UgZ3JvdXBzLCBpbmNsdWRpbmcgZXhlY3V0aXZlcywgdGVjaG5pY2FsIHRlYW1zLCBhbmQgbm9uLXRlY2huaWNhbCBzdGFrZWhvbGRlcnMuIFRhaWxvcmluZyB0aGUgZGVwdGggYW5kIHN0eWxlIG9mIGNvbW11bmljYXRpb24gYWNjb3JkaW5nIHRvIHRoZSBhdWRpZW5jZSBpcyBjcnVjaWFsIGZvciBlbnN1cmluZyB0aGF0IHRoZSBtZXNzYWdlIGlzIHVuZGVyc3Rvb2QuDQoNCkZvciBidXNpbmVzcyBleGVjdXRpdmVzLCB0aGUgZW1waGFzaXMgc2hvdWxkIGJlIG9uIGFjdGlvbmFibGUgaW5zaWdodHMgcmF0aGVyIHRoYW4gdGhlIHRlY2huaWNhbCBkZXRhaWxzIG9mIHRoZSBhbmFseXNpcy4gQSBzdW1tYXJ5IG9mIHRoZSBrZXkgZmluZGluZ3MsIGFsb25nIHdpdGggY2xlYXIgcmVjb21tZW5kYXRpb25zLCBpcyBtb3JlIHZhbHVhYmxlIHRoYW4gYSBkZWVwIGRpdmUgaW50byB0aGUgYWxnb3JpdGhtcyB1c2VkLiBPbiB0aGUgb3RoZXIgaGFuZCwgZm9yIGEgdGVjaG5pY2FsIGF1ZGllbmNlLCB0aGUgZm9jdXMgc2hvdWxkIGJlIG9uIHRoZSBtZXRob2RzLCBhc3N1bXB0aW9ucywgYW5kIHJlc3VsdHMgb2YgdGhlIGFuYWx5c2lzLCBhbGxvd2luZyB0aGVtIHRvIGFzc2VzcyB0aGUgdmFsaWRpdHkgb2YgdGhlIHdvcmsgdGhlbXNlbHZlcy4NCg0KVW5kZXJzdGFuZGluZyB0aGUgYXVkaWVuY2XigJlzIG5lZWRzIGFsc28gaGVscHMgaW4gY2hvb3NpbmcgdGhlIGFwcHJvcHJpYXRlIGxldmVsIG9mIGRldGFpbC4gRXhlY3V0aXZlcyBtYXkgb25seSBuZWVkIGEgaGlnaC1sZXZlbCBvdmVydmlldyBvZiB0aGUgb3V0Y29tZXMsIHdoaWxlIHRlY2huaWNhbCB0ZWFtcyByZXF1aXJlIGEgZGVlcGVyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIGRhdGHigJlzIHN0cnVjdHVyZSwgbW9kZWxpbmcgdGVjaG5pcXVlcywgYW5kIHZhbGlkYXRpb24gcHJvY2Vzc2VzLg0KDQoqKlN0b3J5dGVsbGluZzogRnJhbWluZyBEYXRhIFdpdGhpbiBhIE5hcnJhdGl2ZSoqDQoNCkluIGFkZGl0aW9uIHRvIGNsYXJpdHkgYW5kIGF1ZGllbmNlIGF3YXJlbmVzcywgc3Rvcnl0ZWxsaW5nIGlzIGEgcG93ZXJmdWwgdGVjaG5pcXVlIGluIGRhdGEgc2NpZW5jZSBjb21tdW5pY2F0aW9uLiBOdW1iZXJzIGFuZCBtb2RlbHMgbWF5IHNlZW0gYWJzdHJhY3QsIGJ1dCB3aGVuIGZyYW1lZCB3aXRoaW4gYSBuYXJyYXRpdmUsIHRoZXkgYmVjb21lIG1vcmUgcmVsYXRhYmxlIGFuZCBtZW1vcmFibGUuIFN0b3J5dGVsbGluZyBoZWxwcyB0byBjb25uZWN0IHRoZSBmaW5kaW5ncyB3aXRoIHJlYWwtd29ybGQgcHJvYmxlbXMgYW5kIGlsbHVzdHJhdGVzIHRoZWlyIGltcGxpY2F0aW9ucyBpbiBhIHdheSB0aGF0IHJlc29uYXRlcyB3aXRoIHRoZSBhdWRpZW5jZS4NCg0KQSBjb21wZWxsaW5nIGRhdGEgc3RvcnkgYmVnaW5zIGJ5IHByZXNlbnRpbmcgdGhlIHByb2JsZW0gb3IgY2hhbGxlbmdlIHRoYXQgdGhlIGRhdGEgYW5hbHlzaXMgc2Vla3MgdG8gYWRkcmVzcy4gVGhlIG5hcnJhdGl2ZSBzaG91bGQgdGhlbiBvdXRsaW5lIGhvdyB0aGUgZGF0YSB3YXMgZ2F0aGVyZWQsIHByb2Nlc3NlZCwgYW5kIGFuYWx5emVkLCBiZWZvcmUgbGVhZGluZyBpbnRvIHRoZSBrZXkgZmluZGluZ3MuIEZpbmFsbHksIHRoZSBzdG9yeSBzaG91bGQgY2xvc2Ugd2l0aCBhIGNvbmNsdXNpb24gb3IgcmVjb21tZW5kYXRpb24gdGhhdCB0aWVzIGV2ZXJ5dGhpbmcgYmFjayB0byB0aGUgaW5pdGlhbCBwcm9ibGVtLCBzaG93aW5nIGhvdyB0aGUgaW5zaWdodHMgY2FuIGJlIHVzZWQgdG8gbWFrZSBpbmZvcm1lZCBkZWNpc2lvbnMuDQoNCioqUHJlY2lzaW9uIGFuZCBBY2N1cmFjeSoqDQoNClRoZSBpbXBvcnRhbmNlIG9mIHByZWNpc2lvbiBhbmQgYWNjdXJhY3kgaW4gdGVjaG5pY2FsIGNvbW11bmljYXRpb24gY2Fubm90IGJlIG92ZXJzdGF0ZWQuIERhdGEgc2NpZW5jZSByZWxpZXMgb24gdGhlIGNvcnJlY3QgYXBwbGljYXRpb24gb2YgbWF0aGVtYXRpY2FsIG1vZGVscyBhbmQgc3RhdGlzdGljYWwgdGVjaG5pcXVlcywgYW5kIGFueSBtaXNjb21tdW5pY2F0aW9uIG9mIHRoZXNlIG1ldGhvZHMgY2FuIGxlYWQgdG8gaW5jb3JyZWN0IGNvbmNsdXNpb25zIGFuZCwgcG90ZW50aWFsbHksIGhhcm1mdWwgZGVjaXNpb25zLiBXaGV0aGVyIGluIHdyaXR0ZW4gcmVwb3J0cywgcHJlc2VudGF0aW9ucywgb3IgZGlzY3Vzc2lvbnMsIGRhdGEgc2NpZW50aXN0cyBtdXN0IGVuc3VyZSB0aGF0IHRoZSByZXN1bHRzIGFyZSBhY2N1cmF0ZSwgYW5kIHRoZSBhc3N1bXB0aW9ucyBiZWhpbmQgdGhlaXIgYW5hbHlzaXMgYXJlIGNsZWFybHkgc3RhdGVkLg0KDQpJdOKAmXMgYWxzbyBpbXBvcnRhbnQgdG8gZW1waGFzaXplIHRoZSBsaW1pdGF0aW9ucyBvZiB0aGUgYW5hbHlzaXMuIE5vIG1vZGVsIGlzIHBlcmZlY3QsIGFuZCBhY2tub3dsZWRnaW5nIHBvdGVudGlhbCBlcnJvcnMgb3IgYXJlYXMgb2YgdW5jZXJ0YWludHkgY2FuIGhlbHAgYnVpbGQgdHJ1c3Qgd2l0aCB0aGUgYXVkaWVuY2UuIEZvciBleGFtcGxlLCBkaXNjdXNzaW5nIHRoZSBjb25maWRlbmNlIGludGVydmFscyBhcm91bmQgcHJlZGljdGlvbnMgb3IgdGhlIGFzc3VtcHRpb25zIHVuZGVybHlpbmcgYSByZWdyZXNzaW9uIG1vZGVsIHByb3ZpZGVzIGNvbnRleHQgYW5kIGFsbG93cyB0aGUgYXVkaWVuY2UgdG8gYXNzZXNzIHRoZSByZWxpYWJpbGl0eSBvZiB0aGUgcmVzdWx0cy4NCg0KKipFbmdhZ2luZyBEaXNjdXNzaW9ucyoqDQoNCkZpbmFsbHksIGVmZmVjdGl2ZSBjb21tdW5pY2F0aW9uIGluIGRhdGEgc2NpZW5jZSBleHRlbmRzIGJleW9uZCB3cml0dGVuIHJlcG9ydHMgYW5kIHByZXNlbnRhdGlvbnMgdG8gaW50ZXJhY3RpdmUgZGlzY3Vzc2lvbnMuIEluIHRoZXNlIHNldHRpbmdzLCBkYXRhIHNjaWVudGlzdHMgbXVzdCBiZSBwcmVwYXJlZCB0byBleHBsYWluIHRoZWlyIHdvcmsgaW4gYSBjb252ZXJzYXRpb25hbCBtYW5uZXIsIGFuc3dlcmluZyBxdWVzdGlvbnMsIGNsYXJpZnlpbmcgZG91YnRzLCBhbmQgZW5nYWdpbmcgd2l0aCB0aGUgYXVkaWVuY2UuIEFjdGl2ZSBsaXN0ZW5pbmcgaXMgY3JpdGljYWwgaGVyZSwgYXMgaXQgYWxsb3dzIHRoZSBjb21tdW5pY2F0b3IgdG8gYWRkcmVzcyB0aGUgYXVkaWVuY2UncyBjb25jZXJucyBhbmQgYWRqdXN0IHRoZSBleHBsYW5hdGlvbiBhY2NvcmRpbmdseS4NCg0KTW9yZW92ZXIsIGRpc2N1c3Npb25zIHByb3ZpZGUgYW4gb3Bwb3J0dW5pdHkgZm9yIGZlZWRiYWNrLCB3aGljaCBpcyBlc3NlbnRpYWwgZm9yIGltcHJvdmluZyB0aGUgYW5hbHlzaXMuIER1cmluZyBkaXNjdXNzaW9ucywgZGF0YSBzY2llbnRpc3RzIGNhbiBjbGFyaWZ5IG1pc3VuZGVyc3RhbmRpbmdzLCBleHBsYWluIGNvbXBsZXggY29uY2VwdHMgaW4gc2ltcGxlciB0ZXJtcywgYW5kIGZpbmUtdHVuZSB0aGVpciBtZXNzYWdlIHRvIGVuc3VyZSB0aGF0IGl0IGlzIHVuZGVyc3Rvb2QgYnkgYWxsIHBhcnRpZXMgaW52b2x2ZWQuIFRoaXMgdHdvLXdheSBjb21tdW5pY2F0aW9uIGhlbHBzIHRvIGVuc3VyZSB0aGF0IHRoZSBmaW5kaW5ncyBhcmUgaW50ZXJwcmV0ZWQgY29ycmVjdGx5IGFuZCBjYW4gZ3VpZGUgZnV0dXJlIGRlY2lzaW9ucy4NCg0KDQoNCiMgRGF0YSBBbmFseXNpcyBXb3JrZmxvdw0KDQpUaGUgZGF0YSBzY2llbmNlIGFuYWx5c2lzIHdvcmtmbG93IHJlZmVycyB0byB0aGUgc2VyaWVzIG9mIHN0ZXBzIG9yIHN0YWdlcyB0aGF0IGRhdGEgc2NpZW50aXN0cyBmb2xsb3cgdG8gZ2F0aGVyLCBwcm9jZXNzLCBhbmFseXplLCBhbmQgaW50ZXJwcmV0IGRhdGEgaW4gb3JkZXIgdG8gZXh0cmFjdCBhY3Rpb25hYmxlIGluc2lnaHRzLiBUaGlzIHdvcmtmbG93IGNhbiB2YXJ5IHNsaWdodGx5IGRlcGVuZGluZyBvbiB0aGUgc3BlY2lmaWMgcHJvamVjdCwgYnV0IGl0IHR5cGljYWxseSBpbmNsdWRlcyB0aGUgZm9sbG93aW5nIGtleSBzdGFnZXMuDQoNCiMjIERlZmluZSBPYmplY3RpdmVzIGFuZCBRdWVzdGlvbnMNCg0KSW4gZGF0YSBzY2llbmNlIGFuZCBtYWNoaW5lIGxlYXJuaW5nIHByb2plY3RzLCBkZWZpbmluZyBvYmplY3RpdmVzIGFuZCBxdWVzdGlvbnMgYWNjdXJhdGVseSBpcyBjcnVjaWFsIGFzIHRoZXkgc2V0IHRoZSBmb3VuZGF0aW9uIGZvciB0aGUgZW50aXJlIGFuYWx5c2lzIGFuZCBtb2RlbCBkZXZlbG9wbWVudCBwcm9jZXNzLiBDbGVhciBvYmplY3RpdmVzIGFuZCB3ZWxsLWZvcm11bGF0ZWQgcXVlc3Rpb25zIGd1aWRlIGRhdGEgY29sbGVjdGlvbiwgZmVhdHVyZSBlbmdpbmVlcmluZywgbW9kZWwgc2VsZWN0aW9uLCBhbmQgcmVzdWx0IGludGVycHJldGF0aW9uLiBIZXJl4oCZcyBob3cgdG8gZGVmaW5lIHRoZW0gYWNjdXJhdGVseS4NCg0KKipQcm9qZWN0cyBPYmplY3RpdmVzKioNCg0KT2JqZWN0aXZlcyBkZXNjcmliZSB0aGUgb3ZlcmFsbCBnb2FsIG9yIHB1cnBvc2Ugb2YgdGhlIHByb2plY3QuIFRoZXkgYXJlIHRoZSBkZXNpcmVkIG91dGNvbWVzIHRoYXQgdGhlIGFuYWx5c2lzIG9yIG1hY2hpbmUgbGVhcm5pbmcgbW9kZWwgYWltcyB0byBhY2hpZXZlLiBJbiBkYXRhIHNjaWVuY2UgYW5kIG1hY2hpbmUgbGVhcm5pbmcgcHJvamVjdHMsIG9iamVjdGl2ZXMgc2hvdWxkIGJlOg0KDQoqICpDbGVhciBhbmQgU3BlY2lmaWMqOiBUaGUgb2JqZWN0aXZlIHNob3VsZCBiZSB3ZWxsLWRlZmluZWQsIGxlYXZpbmcgbm8gYW1iaWd1aXR5IGFib3V0IHdoYXQgaXMgdG8gYmUgYWNoaWV2ZWQuIEZvciBleGFtcGxlLCBwcmVkaWN0aW5nIHRoZSBsaWtlbGlob29kIG9mIGN1c3RvbWVyIGNodXJuIGluIHRoZSBuZXh0IHF1YXJ0ZXIuDQoNCiogKk1lYXN1cmFibGUqOiBUaGUgb2JqZWN0aXZlIHNob3VsZCBiZSBxdWFudGlmaWFibGUgc28gdGhhdCBwcm9ncmVzcyBjYW4gYmUgdHJhY2tlZCBhbmQgc3VjY2VzcyBjYW4gYmUgZXZhbHVhdGVkLiBGb3IgZXhhbXBsZSwgSW5jcmVhc2luZyBwcmVkaWN0aW9uIGFjY3VyYWN5IG9mIGNodXJuIHJhdGUgYnkgMTUlIG92ZXIgYmFzZWxpbmUgbW9kZWxzLg0KDQoqICoqRmVhc2libGUqKjogRW5zdXJlIHRoYXQgdGhlIG9iamVjdGl2ZSBjYW4gYmUgcmVhbGlzdGljYWxseSBhY2hpZXZlZCB3aXRoaW4gdGhlIGNvbnN0cmFpbnRzIG9mIGRhdGEsIHRpbWUsIGFuZCByZXNvdXJjZXMgYXZhaWxhYmxlLiBGb3IgZXhhbXBsZSwgQnVpbGRpbmcgYSBtb2RlbCB3aXRoIGF0IGxlYXN0IDgwJSBhY2N1cmFjeSBiYXNlZCBvbiBhdmFpbGFibGUgZGF0YSBzb3VyY2VzLg0KDQoqICpBbGlnbmVkIEJ1c2luZXNzIE5lZWRzKjogVGhlIG9iamVjdGl2ZSBzaG91bGQgYWRkcmVzcyB0aGUgYnVzaW5lc3MgcHJvYmxlbSBvciByZXF1aXJlbWVudCBvZiB0aGUgc3Rha2Vob2xkZXJzLCB3aGV0aGVyIHRoZXkgYXJlIGJ1c2luZXNzIGxlYWRlcnMsIHJlc2VhcmNoZXJzLCBvciBjbGllbnRzLiBGb3IgZXhhbXBsZSwgUHJvdmlkaW5nIGFjdGlvbmFibGUgaW5zaWdodHMgdG8gcmVkdWNlIGN1c3RvbWVyIGNodXJuIGluIGEgc3Vic2NyaXB0aW9uLWJhc2VkIGJ1c2luZXNzLg0KDQoNCioqRm9ybXVsYXRpbmcgQW5hbHl0aWMgUXVlc3Rpb25zKioNCg0KKkFuYWx5dGljIFF1ZXN0aW9ucyogYXJlIHRoZSBzcGVjaWZpYyBpbnF1aXJpZXMgdGhhdCBndWlkZSB0aGUgYW5hbHlzaXMgb3IgbW9kZWxpbmcgcHJvY2Vzcy4gVGhlc2UgYXJlIG1vcmUgZGV0YWlsZWQgdGhhbiBvYmplY3RpdmVzIGFuZCBvZnRlbiBoZWxwIGluIGZvcm11bGF0aW5nIGh5cG90aGVzZXMgYW5kIGRlZmluaW5nIHRoZSBzY29wZSBvZiB0aGUgcHJvamVjdC4gV2VsbC1jcmFmdGVkIHF1ZXN0aW9ucyBzaG91bGQ6DQoNCiogKkJlIFJlbGV2YW50IHRvIHRoZSBQcm9ibGVtKjogKipBbmFseXRpYyBRdWVzdGlvbnMqKiBzaG91bGQgZGlyZWN0bHkgcmVsYXRlIHRvIHRoZSBwcm9ibGVtIHlvdSBhcmUgc29sdmluZyBvciB0aGUgb2JqZWN0aXZlIHlvdSBhaW0gdG8gYWNoaWV2ZS4gRm9yIGV4YW1wbGUsIFdoYXQgZmFjdG9ycyBhcmUgbW9zdCBzdHJvbmdseSBjb3JyZWxhdGVkIHdpdGggY3VzdG9tZXIgY2h1cm4gaW4gdGhlIGN1cnJlbnQgZGF0YXNldD8NCg0KKiAqQmUgQWN0aW9uYWJsZSo6ICoqQW5hbHl0aWMgUXVlc3Rpb25zKiogc2hvdWxkIGxlYWQgdG8gZmluZGluZ3Mgb3IgZGVjaXNpb25zIHRoYXQgY2FuIGJlIGFjdGVkIHVwb24uIEZvciBleGFtcGxlLCBjYW4gd2UgaWRlbnRpZnkgcG90ZW50aWFsIGhpZ2gtcmlzayBjdXN0b21lcnMgd2hvIGFyZSBsaWtlbHkgdG8gY2h1cm4gd2l0aGluIHRoZSBuZXh0IDMgbW9udGhzPw0KDQoqICpCZSBDbGVhciBhbmQgRm9jdXNlZCo6ICoqQW5hbHl0aWMgUXVlc3Rpb25zKiogc2hvdWxkIGJlIGNvbmNpc2UgYW5kIHByZWNpc2UuIEF2b2lkIHZhZ3VlIG9yIGJyb2FkIHF1ZXN0aW9ucyB0aGF0IG1heSBiZSBkaWZmaWN1bHQgdG8gYWRkcmVzcy4gRm9yIGV4YW1wbGUsIHdoYXQgYXJlIHRoZSB0b3AgcHJlZGljdG9ycyBvZiBob3VzZSBwcmljZSB2YXJpYXRpb24gaW4gdGhlIG1hcmtldD8gKGluc3RlYWQgb2YgV2hhdCBkZXRlcm1pbmVzIGhvdXNlIHByaWNlcz8pDQoNCiogKkJlIEh5cG90aGVzaXMtRHJpdmVuKjogSW4gbWFueSBjYXNlcywgKiphbmFseXRpYyBxdWVzdGlvbnMqKiB3aWxsIGJlIGJhc2VkIG9uIGEgaHlwb3RoZXNpcyB5b3Ugd2FudCB0byB0ZXN0IHRocm91Z2ggdGhlIGRhdGEuIEZvciBleGFtcGxlOiBEb2VzIHRoZSBudW1iZXIgb2YgYmVkcm9vbXMgaW4gYSBob3VzZSBzaWduaWZpY2FudGx5IGltcGFjdCBpdHMgcHJpY2U/DQoNCiogKkJlIFRlc3RhYmxlIHdpdGggRGF0YSo6ICoqQW5hbHl0aWMgUXVlc3Rpb25zKiogc2hvdWxkIGJlIGZvcm11bGF0ZWQgaW4gYSB3YXkgdGhhdCB0aGV5IGNhbiBiZSBhZGRyZXNzZWQgdXNpbmcgdGhlIGF2YWlsYWJsZSBkYXRhIGFuZCBhbmFseXNpcyB0ZWNobmlxdWVzLiBGb3IgZXhhbXBsZTogQ2FuIHdlIHVzZSBjdXN0b21lciBkZW1vZ3JhcGhpYyBkYXRhIHRvIHByZWRpY3QgcHVyY2hhc2luZyBiZWhhdmlvcj8NCg0KKiAqQWNjb3VudCBmb3IgQ29uc3RyYWludHMqOiBDb25zaWRlciB3aGV0aGVyIHRoZSBxdWVzdGlvbnMgY2FuIGJlIGFuc3dlcmVkIHdpdGhpbiB0aGUgYXZhaWxhYmxlIHRpbWUsIGRhdGEsIGFuZCByZXNvdXJjZXMuIEZvciBleGFtcGxlLCBoSG93IGNhbiB3ZSBwcmVkaWN0IHRoZSBsaWtlbGlob29kIG9mIGxvYW4gYXBwcm92YWwgYmFzZWQgb24gaW5jb21lLCBjcmVkaXQgc2NvcmUsIGFuZCBlbXBsb3ltZW50IGhpc3RvcnksIGdpdmVuIHRoZSBhdmFpbGFibGUgZGF0YT8NCg0KKipTb21lIFdlbGwtY3JhZnRlZCBFeGFtcGxlIEFuYWx5dGljIFF1ZXN0aW9ucyoqDQoNCiogV2hhdCBhcmUgdGhlIGtleSBkcml2ZXJzIG9mIGN1c3RvbWVyIHNhdGlzZmFjdGlvbiBpbiBvdXIgb25saW5lIHJldGFpbCBwbGF0Zm9ybT8NCg0KKiBJcyB0aGVyZSBhIHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGluY29tZSBhbmQgc3BlbmRpbmcgcGF0dGVybnMgaW4gZGlmZmVyZW50IGRlbW9ncmFwaGljIGdyb3Vwcz8NCg0KKiBIb3cgY2FuIHdlIGltcHJvdmUgdGhlIGFjY3VyYWN5IG9mIGZyYXVkIGRldGVjdGlvbiBpbiBjcmVkaXQgY2FyZCB0cmFuc2FjdGlvbnMgdXNpbmcgbWFjaGluZSBsZWFybmluZyBtb2RlbHM/DQoNCg0KIyMgRGF0YSBDb2xsZWN0aW9uIGFuZCBQcmVwYXJhdGlvbg0KDQpEYXRhIGNvbGxlY3Rpb24gYW5kIHByZXBhcmF0aW9uIGFyZSBjcnVjaWFsIHN0ZXBzIGluIHRoZSBtYWNoaW5lIGxlYXJuaW5nIChNTCkgcGlwZWxpbmUsIHNlcnZpbmcgYXMgdGhlIGZvdW5kYXRpb24gZm9yIGJ1aWxkaW5nIGVmZmVjdGl2ZSBhbmQgcmVsaWFibGUgbW9kZWxzLiBXaXRob3V0IGhpZ2gtcXVhbGl0eSwgcmVsZXZhbnQgZGF0YSwgZXZlbiB0aGUgbW9zdCBhZHZhbmNlZCBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobXMgYXJlIHVubGlrZWx5IHRvIGRlbGl2ZXIgbWVhbmluZ2Z1bCBvciBhY2N1cmF0ZSByZXN1bHRzLiBUaGlzIHN1YnNlY3Rpb24gZXhwbG9yZXMgdGhlIGltcG9ydGFuY2Ugb2YgZGF0YSBjb2xsZWN0aW9uIGFuZCBwcmVwYXJhdGlvbiBpbiB0aGUgY29udGV4dCBvZiBtYWNoaW5lIGxlYXJuaW5nLCBvdXRsaW5pbmcgdGhlIHByb2Nlc3NlcyBpbnZvbHZlZCwgY2hhbGxlbmdlcyBmYWNlZCwgYW5kIGJlc3QgcHJhY3RpY2VzIGZvciBlbnN1cmluZyB0aGF0IGRhdGEgaXMgc3VpdGFibGUgZm9yIGFuYWx5c2lzLg0KDQojIyMgRGF0YSBDb2xsZWN0aW9uDQoNCkRhdGEgY29sbGVjdGlvbiBpcyB0aGUgZmlyc3QgYW5kIG1vc3QgY3JpdGljYWwgc3RlcCBpbiB0aGUgbWFjaGluZSBsZWFybmluZyBwaXBlbGluZS4gSXQgaW52b2x2ZXMgYWNxdWlyaW5nIHRoZSBkYXRhIG5lZWRlZCB0byBzb2x2ZSBhIHNwZWNpZmljIHByb2JsZW0uIFRoaXMgc3RlcCBtdXN0IGZvY3VzIG9uIGdhdGhlcmluZyBkYXRhIHRoYXQgaXMgcmVsZXZhbnQsIGRpdmVyc2UsIGFuZCByZXByZXNlbnRhdGl2ZSBvZiB0aGUgcHJvYmxlbSBkb21haW4uIFRoZSBmb2xsb3dpbmcgYXJlIGtleSBjb25zaWRlcmF0aW9ucyBkdXJpbmcgZGF0YSBjb2xsZWN0aW9uOg0KDQoqICoqU291cmNlIElkZW50aWZpY2F0aW9uKio6IFRoZSBmaXJzdCBzdGVwIGlzIGlkZW50aWZ5aW5nIHRoZSBkYXRhIHNvdXJjZXMuIFRoZXNlIGNhbiBpbmNsdWRlIGludGVybmFsIGRhdGFiYXNlcywgcHVibGljIGRhdGFzZXRzLCBBUElzLCBvciB0aGlyZC1wYXJ0eSBwcm92aWRlcnMuIFRoZSBxdWFsaXR5IG9mIHRoZSBkYXRhIGRlcGVuZHMgb24gdGhlIGNyZWRpYmlsaXR5IGFuZCByZWxldmFuY2Ugb2YgdGhlIHNvdXJjZXMuICBGb3IgZXhhbXBsZSwgaW4gdGhlIGN1c3RvbWVyIGNodXJuIHByZWRpY3Rpb24gbW9kZWxpbmcsIGRhdGEgY291bGQgYmUgY29sbGVjdGVkIGZyb20gY3VzdG9tZXIgZGF0YWJhc2VzLCB0cmFuc2FjdGlvbiByZWNvcmRzLCBjdXN0b21lciBzdXBwb3J0IGludGVyYWN0aW9ucywgYW5kIHdlYiBhbmFseXRpY3MuDQoNCiogKipEYXRhIFZvbHVtZSBhbmQgVmFyaWV0eSoqOiBBIGNvbW1vbiBjaGFsbGVuZ2UgaW4gbWFjaGluZSBsZWFybmluZyBpcyBjb2xsZWN0aW5nIGVub3VnaCBkYXRhIHRvIGFjY3VyYXRlbHkgcmVwcmVzZW50IHRoZSBwcm9ibGVtLiBNYWNoaW5lIGxlYXJuaW5nIG1vZGVscyBvZnRlbiBwZXJmb3JtIGJldHRlciB3aXRoIGxhcmdlLCBkaXZlcnNlIGRhdGFzZXRzIHRoYXQgY2FwdHVyZSB0aGUgZnVsbCByYW5nZSBvZiBwb3NzaWJsZSBpbnB1dHMgYW5kIHNjZW5hcmlvcy4NCg0KKiAqKkRhdGEgUmVsZXZhbmNlKio6IFRoZSBkYXRhIGNvbGxlY3RlZCBtdXN0IGJlIGRpcmVjdGx5IHJlbGV2YW50IHRvIHRoZSB0YXNrIGF0IGhhbmQuIElycmVsZXZhbnQgZGF0YSBub3Qgb25seSBhZGRzIHVubmVjZXNzYXJ5IGNvbXBsZXhpdHkgYnV0IGNhbiBhbHNvIGludHJvZHVjZSBub2lzZSB0aGF0IGhpbmRlcnMgbW9kZWwgcGVyZm9ybWFuY2UuDQoNCiogKipEYXRhIFByaXZhY3kgYW5kIEV0aGljcyoqOiBDb2xsZWN0aW5nIGRhdGEgbXVzdCBiZSBkb25lIGV0aGljYWxseSwgZW5zdXJpbmcgdGhhdCBwZXJzb25hbCBhbmQgc2Vuc2l0aXZlIGluZm9ybWF0aW9uIGlzIGhhbmRsZWQgcmVzcG9uc2libHkuIFRoaXMgaW5jbHVkZXMgYWRoZXJpbmcgdG8gZGF0YSBwcm90ZWN0aW9uIHJlZ3VsYXRpb25zIGxpa2UgR0RQUiBhbmQgb2J0YWluaW5nIGluZm9ybWVkIGNvbnNlbnQgZnJvbSBpbmRpdmlkdWFscyB3aGVyZSBuZWNlc3NhcnkuDQoNCiogKipEYXRhIEludGVncmF0aW9uKio6IEluIG1hbnkgY2FzZXMsIGRhdGEgbWF5IGNvbWUgZnJvbSBtdWx0aXBsZSBzb3VyY2VzLCBlYWNoIHdpdGggaXRzIG93biBzdHJ1Y3R1cmUgYW5kIGZvcm1hdC4gSW50ZWdyYXRpbmcgZGlzcGFyYXRlIGRhdGFzZXRzIHdoaWxlIGVuc3VyaW5nIGNvbnNpc3RlbmN5IGFuZCBpbnRlZ3JpdHkgaXMgYSB2aXRhbCBwYXJ0IG9mIHRoZSBjb2xsZWN0aW9uIHBoYXNlLg0KDQoNCiMjIyBEYXRhIFByZXBhcmF0aW9uDQoNCk9uY2UgZGF0YSBoYXMgYmVlbiBjb2xsZWN0ZWQsIHRoZSBuZXh0IGNyaXRpY2FsIHN0ZXAgaXMgcHJlcGFyaW5nIGl0IGZvciBhbmFseXNpcy4gRGF0YSBwcmVwYXJhdGlvbiBlbmNvbXBhc3NlcyBzZXZlcmFsIHByb2Nlc3NlcywgaW5jbHVkaW5nIGNsZWFuaW5nLCB0cmFuc2Zvcm1hdGlvbiwgYW5kIGZlYXR1cmUgZW5naW5lZXJpbmcuIFRoZSBnb2FsIGlzIHRvIGVuc3VyZSB0aGF0IHRoZSBkYXRhIGlzIGNsZWFuLCBjb21wbGV0ZSwgYW5kIGluIGEgZm9ybWF0IHRoYXQgaXMgY29tcGF0aWJsZSB3aXRoIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtcy4gS2V5IHN0ZXBzIGluIGRhdGEgcHJlcGFyYXRpb24gaW5jbHVkZToNCg0KKipEYXRhIENsZWFuaW5nKiogDQoNClJhdyBkYXRhIGlzIG9mdGVuIG1lc3N5IGFuZCBpbmNvbXBsZXRlLCBjb250YWluaW5nIGVycm9ycywgaW5jb25zaXN0ZW5jaWVzLCBvciBtaXNzaW5nIHZhbHVlcy4gQ2xlYW5pbmcgdGhlIGRhdGEgaW52b2x2ZXM6DQoNCiogKipIYW5kbGluZyBNaXNzaW5nIFZhbHVlcyoqOiBEYXRhIG1heSBoYXZlIG1pc3Npbmcgb3IgbnVsbCB2YWx1ZXMgZHVlIHRvIGVycm9ycyBpbiBkYXRhIGNvbGxlY3Rpb24gb3IgdXNlciBiZWhhdmlvci4gVGhlc2UgbWlzc2luZyB2YWx1ZXMgY2FuIGJlIGhhbmRsZWQgYnkgcmVtb3Zpbmcgcm93cywgaW1wdXRpbmcgbWlzc2luZyB2YWx1ZXMgYmFzZWQgb24gb3RoZXIgZGF0YSBwb2ludHMsIG9yIHVzaW5nIGFsZ29yaXRobXMgdGhhdCBoYW5kbGUgbWlzc2luZyBkYXRhIG5hdHVyYWxseS4NCg0KKiAqKlJlbW92aW5nIER1cGxpY2F0ZXMqKjogRHVwbGljYXRlIHJlY29yZHMgY2FuIHNrZXcgYW5hbHlzaXMgYW5kIG5lZ2F0aXZlbHkgYWZmZWN0IG1vZGVsIHRyYWluaW5nLiBJZGVudGlmeWluZyBhbmQgcmVtb3ZpbmcgZHVwbGljYXRlcyBpcyBhIGNydWNpYWwgc3RlcC4NCg0KKiAqKkZpeGluZyBFcnJvcnMqKjogRXJyb3JzIGluIGRhdGEsIHN1Y2ggYXMgaW5jb3JyZWN0IGxhYmVscywgbWlzZm9ybWF0dGVkIGRhdGVzLCBvciBvdXRsaWVycywgbXVzdCBiZSBhZGRyZXNzZWQgdG8gZW5zdXJlIGRhdGEgcXVhbGl0eS4NCg0KKiAqKkRhdGEgVHJhbnNmb3JtYXRpb24qKjogRGF0YSB0cmFuc2Zvcm1hdGlvbiBpbnZvbHZlcyBjb252ZXJ0aW5nIGRhdGEgaW50byBhIHVzYWJsZSBmb3JtYXQuIFRoaXMgaW5jbHVkZXMgc2NhbGluZywgbm9ybWFsaXppbmcsIG9yIGVuY29kaW5nIGZlYXR1cmVzIHRvIGVuc3VyZSB0aGF0IHRoZSBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobSBjYW4gcHJvY2VzcyB0aGUgZGF0YSBlZmZlY3RpdmVseS4NCg0KXA0KDQoqKlNjYWxpbmcgYW5kIE5vcm1hbGl6YXRpb24qKiANCg0KTWFjaGluZSBsZWFybmluZyBhbGdvcml0aG1zLCBlc3BlY2lhbGx5IHRob3NlIHRoYXQgcmVseSBvbiBkaXN0YW5jZSBtZXRyaWNzIGxpa2Ugay1uZWFyZXN0IG5laWdoYm9ycyAoS05OKSBvciBncmFkaWVudCBkZXNjZW50LCByZXF1aXJlIGZlYXR1cmVzIHRvIGJlIG9uIHNpbWlsYXIgc2NhbGVzLiBOb3JtYWxpemluZyBvciBzdGFuZGFyZGl6aW5nIHRoZSBkYXRhIGVuc3VyZXMgdGhhdCBhbGwgZmVhdHVyZXMgY29udHJpYnV0ZSBlcXVhbGx5IHRvIHRoZSBtb2RlbC4NCg0KKiAqKkVuY29kaW5nIENhdGVnb3JpY2FsIFZhcmlhYmxlcyoqOiBNYW55IG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtcyBjYW5ub3Qgd29yayBkaXJlY3RseSB3aXRoIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyAoZS5nLiwgZ2VuZGVyLCBjb3VudHJ5LCBvciBwcm9kdWN0IGNhdGVnb3J5KS4gVGVjaG5pcXVlcyBsaWtlIG9uZS1ob3QgZW5jb2Rpbmcgb3IgbGFiZWwgZW5jb2RpbmcgYXJlIHVzZWQgdG8gY29udmVydCB0aGVzZSB2YXJpYWJsZXMgaW50byBudW1lcmljYWwgZm9ybS4NCg0KKiAqKkZlYXR1cmUgRW5naW5lZXJpbmcqKjogVGhpcyBwcm9jZXNzIGludm9sdmVzIGNyZWF0aW5nIG5ldyBmZWF0dXJlcyBvciBtb2RpZnlpbmcgZXhpc3Rpbmcgb25lcyB0byBpbXByb3ZlIG1vZGVsIHBlcmZvcm1hbmNlLiBGb3IgZXhhbXBsZSwgY29tYmluaW5nIGRhdGUgYW5kIHRpbWUgZmllbGRzIGludG8gYSAiZGF5IG9mIHRoZSB3ZWVrIiBmZWF0dXJlIG9yIGNhbGN1bGF0aW5nIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIHRpbWVzdGFtcCBjb2x1bW5zIGNhbiBwcm92aWRlIG1vcmUgbWVhbmluZ2Z1bCBpbnB1dHMgZm9yIHRoZSBtb2RlbC4NCg0KKipEYXRhIFNwbGl0dGluZyoqDQoNClRvIGFzc2VzcyBtb2RlbCBwZXJmb3JtYW5jZSBhbmQgcHJldmVudCBvdmVyZml0dGluZywgdGhlIGRhdGFzZXQgaXMgdXN1YWxseSBzcGxpdCBpbnRvIHRyYWluaW5nLCB2YWxpZGF0aW9uLCBhbmQgdGVzdGluZyBzZXRzLiBUaGUgdHJhaW5pbmcgc2V0IGlzIHVzZWQgdG8gYnVpbGQgdGhlIG1vZGVsLCB0aGUgdmFsaWRhdGlvbiBzZXQgaGVscHMgdHVuZSBoeXBlcnBhcmFtZXRlcnMsIGFuZCB0aGUgdGVzdGluZyBzZXQgZXZhbHVhdGVzIHRoZSBtb2RlbOKAmXMgZ2VuZXJhbGl6YXRpb24gYWJpbGl0eS4NCg0KKipPdXRsaWVyIERldGVjdGlvbioqDQoNCk91dGxpZXJzIGFyZSBkYXRhIHBvaW50cyB0aGF0IGRpZmZlciBzaWduaWZpY2FudGx5IGZyb20gb3RoZXJzIGFuZCBjYW4gZGlzdG9ydCB0aGUgcmVzdWx0cyBvZiBhIG1vZGVsLiBEZXRlY3RpbmcgYW5kIGhhbmRsaW5nIG91dGxpZXJzIGlzIGNydWNpYWwgZm9yIHByZXZlbnRpbmcgdGhlc2UgdmFsdWVzIGZyb20gbmVnYXRpdmVseSBpbmZsdWVuY2luZyB0aGUgbW9kZWwncyBwcmVkaWN0aW9ucy4NCg0KKipEYXRhIEF1Z21lbnRhdGlvbioqDQoNCkluIHNvbWUgY2FzZXMsIGVzcGVjaWFsbHkgd2hlbiB3b3JraW5nIHdpdGggaW1hZ2VzIG9yIHRleHQsIGRhdGEgYXVnbWVudGF0aW9uIHRlY2huaXF1ZXMgbGlrZSByb3RhdGlvbiwgY3JvcHBpbmcsIG9yIHRleHQgcGFyYXBocmFzaW5nIGNhbiBiZSB1c2VkIHRvIGFydGlmaWNpYWxseSBleHBhbmQgdGhlIGRhdGFzZXQgYW5kIGltcHJvdmUgbW9kZWwgcm9idXN0bmVzcy4NCg0KDQojIyMgQmVzdCBQcmFjdGljZXMNCg0KVG8gb3ZlcmNvbWUgdGhlc2UgY2hhbGxlbmdlcyBhbmQgZW5zdXJlIHN1Y2Nlc3NmdWwgbWFjaGluZSBsZWFybmluZyBwcm9qZWN0cywgdGhlIGZvbGxvd2luZyBiZXN0IHByYWN0aWNlcyBzaG91bGQgYmUgZm9sbG93ZWQ6DQoNCiogKipVbmRlcnN0YW5kIHRoZSBQcm9ibGVtIERvbWFpbioqOiBDb2xsYWJvcmF0ZSB3aXRoIGRvbWFpbiBleHBlcnRzIHRvIGVuc3VyZSB0aGUgZGF0YSBjb2xsZWN0ZWQgaXMgcmVsZXZhbnQgYW5kIHVzZWZ1bCBmb3IgdGhlIHByb2JsZW0gYmVpbmcgc29sdmVkLg0KDQoqICoqQXV0b21hdGUgRGF0YSBDb2xsZWN0aW9uKio6IFdoZW5ldmVyIHBvc3NpYmxlLCBhdXRvbWF0ZSB0aGUgZGF0YSBjb2xsZWN0aW9uIHByb2Nlc3MgdG8gaW1wcm92ZSBlZmZpY2llbmN5IGFuZCBjb25zaXN0ZW5jeS4NCg0KKiAqKkl0ZXJhdGUgYW5kIFJlZmluZSoqOiBEYXRhIHByZXBhcmF0aW9uIGlzIG5vdCBhIG9uZS10aW1lIHRhc2suIEl04oCZcyBpbXBvcnRhbnQgdG8gaXRlcmF0ZSBhbmQgcmVmaW5lIHRoZSBkYXRhc2V0IGFzIHRoZSBtb2RlbCBpcyBkZXZlbG9wZWQgYW5kIGFzIG5ldyBkYXRhIGJlY29tZXMgYXZhaWxhYmxlLg0KDQoqICoqRG9jdW1lbnQgdGhlIFByb2Nlc3MqKjogS2VlcCBkZXRhaWxlZCByZWNvcmRzIG9mIHRoZSBkYXRhIGNvbGxlY3Rpb24gYW5kIHByZXBhcmF0aW9uIHN0ZXBzLiBUaGlzIGVuc3VyZXMgdHJhbnNwYXJlbmN5IGFuZCByZXByb2R1Y2liaWxpdHksIHdoaWNoIGlzIGVzcGVjaWFsbHkgaW1wb3J0YW50IGZvciBjb2xsYWJvcmF0aXZlIGFuZCByZWd1bGF0b3J5IGNvbXBsaWFuY2UuDQoNCiogKipUZXN0IGZvciBCaWFzKio6IFJlZ3VsYXJseSB0ZXN0IHRoZSBkYXRhIGZvciBiaWFzIGFuZCBlbnN1cmUgdGhhdCB0aGUgbW9kZWwgaXMgdHJhaW5lZCBvbiByZXByZXNlbnRhdGl2ZSBhbmQgZGl2ZXJzZSBkYXRhc2V0cy4NCg0KXA0KDQoqKkluIHN1bW1hcnkqKiwgZGF0YSBjb2xsZWN0aW9uIGFuZCBwcmVwYXJhdGlvbiBhcmUgZm91bmRhdGlvbmFsIHN0ZXBzIGluIG1hY2hpbmUgbGVhcm5pbmcsIGRpcmVjdGx5IGluZmx1ZW5jaW5nIHRoZSBxdWFsaXR5IGFuZCBlZmZlY3RpdmVuZXNzIG9mIHRoZSByZXN1bHRpbmcgbW9kZWxzLiBFbnN1cmluZyB0aGUgZGF0YSBpcyByZWxldmFudCwgY2xlYW4sIGFuZCBwcm9wZXJseSBmb3JtYXR0ZWQgaXMgY3JpdGljYWwgZm9yIGRldmVsb3BpbmcgbW9kZWxzIHRoYXQgY2FuIG1ha2UgYWNjdXJhdGUgcHJlZGljdGlvbnMgYW5kIHByb3ZpZGUgdmFsdWFibGUgaW5zaWdodHMuIEJ5IGNhcmVmdWxseSBtYW5hZ2luZyB0aGVzZSBzdGFnZXMsIGRhdGEgc2NpZW50aXN0cyBjYW4gYnVpbGQgcmVsaWFibGUsIHNjYWxhYmxlIG1vZGVscyB0aGF0IHBlcmZvcm0gd2VsbCBpbiByZWFsLXdvcmxkIGFwcGxpY2F0aW9ucy4gQXMgbWFjaGluZSBsZWFybmluZyBjb250aW51ZXMgdG8gZXZvbHZlLCBtYXN0ZXJpbmcgZGF0YSBjb2xsZWN0aW9uIGFuZCBwcmVwYXJhdGlvbiB3aWxsIHJlbWFpbiBhbiBlc3NlbnRpYWwgc2tpbGwgZm9yIGRhdGEgc2NpZW50aXN0cyBhbmQgbWFjaGluZSBsZWFybmluZyBwcmFjdGl0aW9uZXJzLg0KDQpcDQoNCiMjIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMgKEVEQSkNCg0KRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyAoRURBKSBpcyBhIGNydWNpYWwgc3RlcCBpbiB0aGUgbWFjaGluZSBsZWFybmluZyB3b3JrZmxvdywgc2VydmluZyBhcyBhbiBpbml0aWFsIGludmVzdGlnYXRpb24gaW50byB0aGUgZGF0YXNldCB0byB1bmNvdmVyIHVuZGVybHlpbmcgcGF0dGVybnMsIHJlbGF0aW9uc2hpcHMsIGFuZCBwb3RlbnRpYWwgaXNzdWVzLiBFREEgaW52b2x2ZXMgYW5hbHl6aW5nIHRoZSBkYXRhJ3Mgc3RydWN0dXJlIGFuZCBkaXN0cmlidXRpb24sIGdlbmVyYXRpbmcgaHlwb3RoZXNlcywgYW5kIGlkZW50aWZ5aW5nIHRyZW5kcyBvciBhbm9tYWxpZXMgdGhhdCBtaWdodCBpbmZsdWVuY2Ugc3Vic2VxdWVudCBtb2RlbGluZyBkZWNpc2lvbnMuIEl0IGhlbHBzIGRhdGEgc2NpZW50aXN0cyBhbmQgbWFjaGluZSBsZWFybmluZyBwcmFjdGl0aW9uZXJzIHVuZGVyc3RhbmQgdGhlIGRhdGEgYmVmb3JlIGRpdmluZyBpbnRvIGNvbXBsZXggYWxnb3JpdGhtcywgZW5zdXJpbmcgYSBiZXR0ZXIgdW5kZXJzdGFuZGluZyBvZiB0aGUgZGF0YXNldCwgaW1wcm92ZWQgZGF0YSBwcmVwcm9jZXNzaW5nLCBhbmQgbW9yZSBlZmZlY3RpdmUgbW9kZWwgc2VsZWN0aW9uLg0KDQojIyMgVGhlIFJvbGUgb2YgRURBIGluIE1hY2hpbmUgTGVhcm5pbmcNCg0KRURBIHByb3ZpZGVzIGEgZm91bmRhdGlvbmFsIHVuZGVyc3RhbmRpbmcgb2YgdGhlIGRhdGFzZXQsIGVuc3VyaW5nIHRoYXQgZGF0YSBzY2llbnRpc3RzIGNhbiBtYWtlIGluZm9ybWVkIGRlY2lzaW9ucyBkdXJpbmcgdGhlIG1vZGVsaW5nIHBoYXNlLiBCeSBleHBsb3JpbmcgdGhlIGRhdGEgdmlzdWFsbHkgYW5kIHN0YXRpc3RpY2FsbHksIEVEQSBoZWxwcyBpZGVudGlmeSBrZXkgaW5zaWdodHMsIGRldGVjdCBlcnJvcnMsIGFuZCByZXZlYWwgYXNwZWN0cyBvZiB0aGUgZGF0YSB0aGF0IG1pZ2h0IG90aGVyd2lzZSByZW1haW4gaGlkZGVuLiBUaGlzIHN0ZXAgaXMgdml0YWwgYmVjYXVzZSB0aGUgcXVhbGl0eSBvZiB0aGUgZGF0YSB1c2VkIGluIG1hY2hpbmUgbGVhcm5pbmcgZGlyZWN0bHkgYWZmZWN0cyB0aGUgbW9kZWwncyBwZXJmb3JtYW5jZSwgYW5kIHRoZSBpbnNpZ2h0cyBnYWluZWQgZHVyaW5nIEVEQSBjYW4gZ3VpZGUgZnVydGhlciBkYXRhIGNsZWFuaW5nLCBmZWF0dXJlIGVuZ2luZWVyaW5nLCBhbmQgbW9kZWwgcmVmaW5lbWVudC4NCg0KV2UgbmV4dCBsaXN0IHNvbWUgb2YgdGhlIGtleSBzdGVwcyBpbiBFREEuDQoNCg0KKioxLiBVbmRlcnN0YW5kaW5nIHRoZSBEYXRhc2V0IFN0cnVjdHVyZSoqDQoNClRoZSBmaXJzdCBzdGVwIGluIEVEQSBpcyB1bmRlcnN0YW5kaW5nIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGFzZXQuIFRoaXMgaW52b2x2ZXMgY2hlY2tpbmcgdGhlIG51bWJlciBvZiByb3dzIChkYXRhIHBvaW50cykgYW5kIGNvbHVtbnMgKGZlYXR1cmVzKSwgYW5kIHVuZGVyc3RhbmRpbmcgdGhlIGRhdGEgdHlwZXMgb2YgZWFjaCBmZWF0dXJlIChlLmcuLCBjYXRlZ29yaWNhbCwgbnVtZXJpY2FsLCB0ZXh0KS4gVGhpcyBzdGVwIGlzIGZ1bmRhbWVudGFsIGZvciBkZXRlcm1pbmluZyBob3cgdGhlIGRhdGEgY2FuIGJlIHByb2Nlc3NlZCBvciB0cmFuc2Zvcm1lZCBmb3IgYW5hbHlzaXMuDQoNCioqRXhhbXBsZSoqOiBBIGRhdGFzZXQgd2l0aCBjdXN0b21lciBpbmZvcm1hdGlvbiBtYXkgaW5jbHVkZSBmZWF0dXJlcyBsaWtlICJhZ2UsIiAiaW5jb21lLCIgYW5kICJnZW5kZXIuIiBVbmRlcnN0YW5kaW5nIHdoZXRoZXIgdGhlc2UgZmVhdHVyZXMgYXJlIG51bWVyaWNhbCBvciBjYXRlZ29yaWNhbCBoZWxwcyBpbiBjaG9vc2luZyB0aGUgcmlnaHQgc3RhdGlzdGljYWwgdGVjaG5pcXVlcyBvciBtYWNoaW5lIGxlYXJuaW5nIGFsZ29yaXRobXMuDQoNCioqMi4gRGVzY3JpcHRpdmUgU3RhdGlzdGljcyoqIA0KDQpEZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIHN1bW1hcml6ZSB0aGUgY2VudHJhbCB0ZW5kZW5jaWVzLCB2YXJpYWJpbGl0eSwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGF0YS4gS2V5IG1ldHJpY3MgaW5jbHVkZSB0aGUgbWVhbiwgbWVkaWFuLCBzdGFuZGFyZCBkZXZpYXRpb24sIG1pbmltdW0sIGFuZCBtYXhpbXVtIHZhbHVlcyBmb3IgbnVtZXJpY2FsIGZlYXR1cmVzLCBhbmQgZnJlcXVlbmN5IGNvdW50cyBmb3IgY2F0ZWdvcmljYWwgZmVhdHVyZXMuIFRoZXNlIHN0YXRpc3RpY3Mgb2ZmZXIgYW4gaW5pdGlhbCBvdmVydmlldyBvZiB0aGUgZGF0YSdzIGNoYXJhY3RlcmlzdGljcywgaGVscGluZyBpZGVudGlmeSBhbnkgb2J2aW91cyBkYXRhIGlzc3VlcyBvciBza2V3ZWQgZGlzdHJpYnV0aW9ucy4NCg0KKipFeGFtcGxlKio6IEZvciBhIG51bWVyaWNhbCBmZWF0dXJlIGxpa2UgImFnZSwiIGNoZWNraW5nIHRoZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gY2FuIGhpZ2hsaWdodCBpZiB0aGVyZSBhcmUgZXh0cmVtZSBvdXRsaWVycyBvciBpZiB0aGUgZGF0YSBpcyBoZWF2aWx5IHNrZXdlZC4NCg0KKiozLiBEYXRhIFZpc3VhbGl6YXRpb24qKiANCg0KVmlzdWFsaXphdGlvbnMgYXJlIGFuIGVzc2VudGlhbCBwYXJ0IG9mIEVEQSwgYWxsb3dpbmcgZGF0YSBzY2llbnRpc3RzIHRvIGlkZW50aWZ5IHBhdHRlcm5zLCB0cmVuZHMsIGFuZCByZWxhdGlvbnNoaXBzIGJldHdlZW4gZmVhdHVyZXMgbW9yZSBpbnR1aXRpdmVseS4gQ29tbW9uIHZpc3VhbGl6YXRpb25zIHVzZWQgaW4gRURBIGluY2x1ZGU6DQoNCiogKkhpc3RvZ3JhbXMqOiBTaG93IHRoZSBkaXN0cmlidXRpb24gb2YgbnVtZXJpY2FsIGRhdGEsIGhlbHBpbmcgdG8gdW5kZXJzdGFuZCB0aGUgc3ByZWFkIGFuZCBza2V3bmVzcyBvZiB2YXJpYWJsZXMuDQoNCiogKkJveCBQbG90cyo6IEhlbHAgaWRlbnRpZnkgb3V0bGllcnMgYW5kIHRoZSBzcHJlYWQgb2YgZGF0YSwgc2hvd2luZyB0aGUgbWVkaWFuLCBxdWFydGlsZXMsIGFuZCBhbnkgZXh0cmVtZSB2YWx1ZXMuDQoNCiogKlNjYXR0ZXIgUGxvdHMqOiBTaG93IHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB0d28gbnVtZXJpY2FsIHZhcmlhYmxlcyBhbmQgY2FuIGhpZ2hsaWdodCBjb3JyZWxhdGlvbnMgb3IgdGhlIGFic2VuY2Ugb2YgdGhlbS4NCg0KKiAqQ29ycmVsYXRpb24gSGVhdG1hcHMqOiBTaG93IHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gZGlmZmVyZW50IG51bWVyaWNhbCBmZWF0dXJlcywgaGlnaGxpZ2h0aW5nIGNvcnJlbGF0aW9ucyB0aGF0IGNvdWxkIGJlIGltcG9ydGFudCBmb3IgcHJlZGljdGl2ZSBtb2RlbGluZy4NCg0KKipFeGFtcGxlKio6IEEgc2NhdHRlciBwbG90IG9mICJhZ2UiIHZzLiAiaW5jb21lIiBtaWdodCByZXZlYWwgYSB0cmVuZCB3aGVyZSB5b3VuZ2VyIGN1c3RvbWVycyBoYXZlIGxvd2VyIGluY29tZSwgd2hpbGUgb2xkZXIgY3VzdG9tZXJzIGVhcm4gaGlnaGVyIHNhbGFyaWVzLiBUaGlzIGluc2lnaHQgY291bGQgaW5mbHVlbmNlIG1vZGVsIGZlYXR1cmUgc2VsZWN0aW9uIG9yIHRyYW5zZm9ybWF0aW9uLg0KDQoNCioqNC4gSGFuZGxpbmcgTWlzc2luZyBEYXRhKiogDQoNCk9uZSBvZiB0aGUgbW9zdCBjb21tb24gaXNzdWVzIGVuY291bnRlcmVkIGluIHJlYWwtd29ybGQgZGF0YSBzZXRzIGlzIG1pc3NpbmcgZGF0YS4gRURBIGhlbHBzIGlkZW50aWZ5IHdoaWNoIGZlYXR1cmVzIGhhdmUgbWlzc2luZyB2YWx1ZXMsIGFuZCB0aGUgZXh0ZW50IG9mIG1pc3NpbmduZXNzLiBXZSB3aWxsIHVzZSBhIHdlZWsgdG8gZGlzY3VzcyB2YXJpb3VzIGltcHV0YXRpb24gbWV0aG9kcy4gTm8gZGV0YWlscyB3aWxsIGJlIHByb3ZpZGVkIGluIHRoaXMgbm90ZS4NCg0KDQoqKjUuIElkZW50aWZ5aW5nIE91dGxpZXJzKioNCg0KT3V0bGllcnMgYXJlIGRhdGEgcG9pbnRzIHRoYXQgZGlmZmVyIHNpZ25pZmljYW50bHkgZnJvbSB0aGUgcmVzdCBvZiB0aGUgZGF0YXNldC4gRURBIGhlbHBzIGluIGlkZW50aWZ5aW5nIG91dGxpZXJzIHRoYXQgY291bGQgc2tldyBtb2RlbCBwZXJmb3JtYW5jZSBvciBsZWFkIHRvIGluY29ycmVjdCBwcmVkaWN0aW9ucy4gVGVjaG5pcXVlcyBzdWNoIGFzIGJveCBwbG90cyBvciBaLXNjb3JlcyBhcmUgb2Z0ZW4gdXNlZCB0byBkZXRlY3QgdGhlc2UgZXh0cmVtZSB2YWx1ZXMuIEluIHNvbWUgY2FzZXMsIG91dGxpZXJzIGFyZSBnZW51aW5lIG9ic2VydmF0aW9ucywgd2hpbGUgaW4gb3RoZXJzLCB0aGV5IG1heSBiZSBlcnJvcnMgdGhhdCBuZWVkIHRvIGJlIGFkZHJlc3NlZC4NCg0KKipFeGFtcGxlKio6IEluIGEgZGF0YXNldCBvZiBob3VzZSBwcmljZXMsIGFuIG91dGxpZXIgY291bGQgYmUgYSBtYW5zaW9uIHByaWNlZCBmYXIgYmVsb3cgdGhlIG1hcmtldCByYXRlLiBUaGlzIGNvdWxkIGVpdGhlciBiZSBhIHJhcmUgYnV0IHZhbGlkIGluc3RhbmNlIG9yIGFuIGVycm9yIGluIHRoZSBkYXRhIGVudHJ5IHByb2Nlc3MgdGhhdCByZXF1aXJlcyBjb3JyZWN0aW9uLg0KDQoqKjYuIEV4cGxvcmluZyBSZWxhdGlvbnNoaXBzIEJldHdlZW4gVmFyaWFibGVzKiogDQoNCkVEQSBhbHNvIGludm9sdmVzIGludmVzdGlnYXRpbmcgdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB2YXJpYWJsZXMuIFRoaXMgaGVscHMgaWRlbnRpZnkgd2hldGhlciBhbnkgZmVhdHVyZXMgYXJlIGNvcnJlbGF0ZWQgb3IgaWYgY2VydGFpbiB2YXJpYWJsZXMgaW5mbHVlbmNlIG90aGVycy4gRm9yIGV4YW1wbGUsIGV4YW1pbmluZyBjb3JyZWxhdGlvbnMgYmV0d2VlbiBpbmRlcGVuZGVudCB2YXJpYWJsZXMgYW5kIHRoZSB0YXJnZXQgdmFyaWFibGUgKGluIHN1cGVydmlzZWQgbGVhcm5pbmcpIGNhbiBndWlkZSBmZWF0dXJlIHNlbGVjdGlvbiBhbmQgaGVscCBpbXByb3ZlIG1vZGVsIHBlcmZvcm1hbmNlLg0KDQoNCioqRXhhbXBsZSoqOiBJbiBhIGRhdGFzZXQgcHJlZGljdGluZyBob3VzZSBwcmljZXMsIHZhcmlhYmxlcyBzdWNoIGFzICJzcXVhcmUgZm9vdGFnZSIgYW5kICJudW1iZXIgb2YgYmVkcm9vbXMiIGFyZSBsaWtlbHkgdG8gaGF2ZSBhIHN0cm9uZyBwb3NpdGl2ZSBjb3JyZWxhdGlvbiB3aXRoIHRoZSB0YXJnZXQgdmFyaWFibGUsICJwcmljZS4iDQoNCg0KKio3LiBGZWF0dXJlIEVuZ2luZWVyaW5nIGFuZCBUcmFuc2Zvcm1hdGlvbioqIA0KDQpEdXJpbmcgRURBLCBkYXRhIHNjaWVudGlzdHMgb2Z0ZW4gYmVnaW4gdG8gdGhpbmsgYWJvdXQgaG93IHRvIHRyYW5zZm9ybSBmZWF0dXJlcyBvciBjcmVhdGUgbmV3IG9uZXMuIFRoaXMgbWlnaHQgaW52b2x2ZSBlbmNvZGluZyBjYXRlZ29yaWNhbCB2YXJpYWJsZXMsIG5vcm1hbGl6aW5nIG51bWVyaWNhbCBmZWF0dXJlcywgb3IgY29tYmluaW5nIGZlYXR1cmVzIHRvIGV4dHJhY3QgbmV3IGluc2lnaHRzLiBFREEgcHJvdmlkZXMgdGhlIGNvbnRleHQgbmVlZGVkIHRvIGRldGVybWluZSB3aGljaCB0cmFuc2Zvcm1hdGlvbnMgYXJlIG5lY2Vzc2FyeSBhbmQgaG93IHRoZXkgc2hvdWxkIGJlIGFwcGxpZWQgdG8gdGhlIGRhdGEuDQoNCioqRXhhbXBsZSoqOiBJZiAiZGF0ZSIgaXMgYSBmZWF0dXJlLCBpdCBjb3VsZCBiZSB0cmFuc2Zvcm1lZCBpbnRvIG11bHRpcGxlIGZlYXR1cmVzIHN1Y2ggYXMgImRheSBvZiB0aGUgd2VlaywiICJtb250aCwiIG9yICJzZWFzb24sIiBkZXBlbmRpbmcgb24gdGhlIHByb2JsZW0uDQoNCg0KIyMjIEltcG9ydGFuY2Ugb2YgRURBDQoNCioqR3VpZGluZyBEYXRhIENsZWFuaW5nKio6IEVEQSBoZWxwcyBpZGVudGlmeSBpbmNvbnNpc3RlbmNpZXMsIG1pc3NpbmcgdmFsdWVzLCBhbmQgb3V0bGllcnMgaW4gdGhlIGRhdGEgdGhhdCBuZWVkIHRvIGJlIGFkZHJlc3NlZCBiZWZvcmUgbW9kZWwgdHJhaW5pbmcuIEJ5IGNsZWFuaW5nIHRoZSBkYXRhIGJhc2VkIG9uIGluc2lnaHRzIGZyb20gRURBLCBtb2RlbCBwZXJmb3JtYW5jZSBjYW4gYmUgc2lnbmlmaWNhbnRseSBpbXByb3ZlZC4NCg0KKipJbXByb3ZpbmcgTW9kZWwgQWNjdXJhY3kqKjogVW5kZXJzdGFuZGluZyB0aGUgZGF0YeKAmXMgc3RydWN0dXJlLCByZWxhdGlvbnNoaXBzLCBhbmQgZGlzdHJpYnV0aW9ucyBoZWxwcyBzZWxlY3QgdGhlIHJpZ2h0IG1hY2hpbmUgbGVhcm5pbmcgbW9kZWwuIEZvciBpbnN0YW5jZSwga25vd2luZyB0aGUgdGFyZ2V0IHZhcmlhYmxl4oCZcyBkaXN0cmlidXRpb24gbWlnaHQgaGVscCBjaG9vc2UgYmV0d2VlbiByZWdyZXNzaW9uIGFuZCBjbGFzc2lmaWNhdGlvbiBtb2RlbHMgb3IgaW5mbHVlbmNlIHRoZSBkZWNpc2lvbiB0byB1c2Ugc3BlY2lmaWMgYWxnb3JpdGhtcyBsaWtlIGRlY2lzaW9uIHRyZWVzLCByYW5kb20gZm9yZXN0cywgb3IgbmV1cmFsIG5ldHdvcmtzLg0KDQoqKlByZXZlbnRpbmcgT3ZlcmZpdHRpbmcqKjogQnkgdmlzdWFsaXppbmcgdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBmZWF0dXJlcywgRURBIGhlbHBzIGRhdGEgc2NpZW50aXN0cyB1bmRlcnN0YW5kIHRoZSBjb21wbGV4aXR5IG9mIHRoZSBtb2RlbCB0aGV5IGFyZSBidWlsZGluZy4gSXQgYWxsb3dzIHRoZW0gdG8gZGVjaWRlIHdoZXRoZXIgY2VydGFpbiBmZWF0dXJlcyBzaG91bGQgYmUgaW5jbHVkZWQgb3Igd2hldGhlciBzb21lIHZhcmlhYmxlcyBtaWdodCBsZWFkIHRvIG92ZXJmaXR0aW5nLg0KDQoqKkltcHJvdmluZyBJbnRlcnByZXRhYmlsaXR5Kio6IFZpc3VhbGl6YXRpb25zIGFuZCBzdGF0aXN0aWNhbCBzdW1tYXJpZXMgY3JlYXRlZCBkdXJpbmcgRURBIHByb3ZpZGUgaW5zaWdodHMgdGhhdCBjYW4gaW1wcm92ZSB0aGUgaW50ZXJwcmV0YWJpbGl0eSBvZiB0aGUgbWFjaGluZSBsZWFybmluZyBtb2RlbC4gQ2xlYXIgdmlzdWFsaXphdGlvbnMgaGVscCBzdGFrZWhvbGRlcnMgYmV0dGVyIHVuZGVyc3RhbmQgdGhlIG1vZGVsIGFuZCB0aGUgcmVzdWx0cyBpdCBnZW5lcmF0ZXMuDQoNCg0KSW4gc3VtbWFyeSwgRURBIGlzIGFuIGVzc2VudGlhbCBwcm9jZXNzIGluIHRoZSBtYWNoaW5lIGxlYXJuaW5nIHBpcGVsaW5lLCBwcm92aWRpbmcgZGF0YSBzY2llbnRpc3RzIHdpdGggYSBkZWVwIHVuZGVyc3RhbmRpbmcgb2YgdGhlIGRhdGFzZXQgYmVmb3JlIGJ1aWxkaW5nIG1vZGVscy4gQnkgc3VtbWFyaXppbmcgdGhlIGRhdGEgdGhyb3VnaCBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzLCB2aXN1YWxpemluZyBrZXkgcmVsYXRpb25zaGlwcywgYW5kIGFkZHJlc3NpbmcgcG90ZW50aWFsIGlzc3VlcyBzdWNoIGFzIG1pc3NpbmcgZGF0YSBhbmQgb3V0bGllcnMsIEVEQSBlbnN1cmVzIHRoYXQgbWFjaGluZSBsZWFybmluZyBtb2RlbHMgYXJlIGJhc2VkIG9uIGEgc29saWQgZm91bmRhdGlvbi4gVGhyb3VnaCBlZmZlY3RpdmUgRURBLCBwcmFjdGl0aW9uZXJzIGNhbiBpbXByb3ZlIG1vZGVsIGFjY3VyYWN5LCBwcmV2ZW50IGJpYXNlcywgYW5kIG1ha2UgbW9yZSBpbmZvcm1lZCBkZWNpc2lvbnMgYWJvdXQgZGF0YSBwcmVwcm9jZXNzaW5nLCBmZWF0dXJlIGVuZ2luZWVyaW5nLCBhbmQgbW9kZWwgc2VsZWN0aW9uLiBVbHRpbWF0ZWx5LCBFREEgZW5oYW5jZXMgdGhlIHJlbGlhYmlsaXR5IGFuZCBzdWNjZXNzIG9mIG1hY2hpbmUgbGVhcm5pbmcgcHJvamVjdHMuDQoNCg0KDQoNCiMjIE9wdGltYWwgTW9kZWwgSWRlbnRpZmljYXRpb24NCg0KSWRlbnRpZnlpbmcgdGhlIHJpZ2h0IG1vZGVsIGFuZCBhbGdvcml0aG0gaXMgZXNzZW50aWFsIGZvciBhY2hpZXZpbmcgaGlnaC1wZXJmb3JtYW5jZSByZXN1bHRzLiBUaGUgcHJvY2VzcyBvZiBpZGVudGlmeWluZyB0aGUgb3B0aW1hbCBtb2RlbHMgYW5kIGFsZ29yaXRobXMgaXMgYSBmdW5kYW1lbnRhbCB0YXNrIHRoYXQgY2FuIHNpZ25pZmljYW50bHkgaW5mbHVlbmNlIHRoZSBhY2N1cmFjeSwgZWZmaWNpZW5jeSwgYW5kIGludGVycHJldGFiaWxpdHkgb2YgbWFjaGluZSBsZWFybmluZyBzb2x1dGlvbnMuIFRoaXMgc3Vic2VjdGlvbiBleHBsb3JlcyB0aGUgaW1wb3J0YW5jZSBvZiBtb2RlbCBhbmQgYWxnb3JpdGhtIHNlbGVjdGlvbiwgdGhlIGZhY3RvcnMgdGhhdCBpbmZsdWVuY2UgdGhlc2UgZGVjaXNpb25zLCBhbmQgdGhlIHByb2Nlc3Mgb2YgaWRlbnRpZnlpbmcgdGhlIGJlc3QgbW9kZWwgZm9yIGEgZ2l2ZW4gdGFzay4NCg0KTWFjaGluZSBsZWFybmluZyBlbmNvbXBhc3NlcyBhIHdpZGUgdmFyaWV0eSBvZiB0YXNrcywgc3VjaCBhcyBjbGFzc2lmaWNhdGlvbiwgcmVncmVzc2lvbiwgY2x1c3RlcmluZywgYW5kIHJlaW5mb3JjZW1lbnQgbGVhcm5pbmcsIGVhY2ggcmVxdWlyaW5nIGRpZmZlcmVudCBhcHByb2FjaGVzIGFuZCBhbGdvcml0aG1zLiBHaXZlbiB0aGUgYnJvYWQgcmFuZ2Ugb2YgYXZhaWxhYmxlIG1vZGVscyBhbmQgYWxnb3JpdGhtcywgaXQgaXMgZXNzZW50aWFsIHRvIGNob29zZSB0aGUgbW9zdCBzdWl0YWJsZSBvbmUgZm9yIHRoZSBwcm9ibGVtIGF0IGhhbmQuIFRoZSByaWdodCBtb2RlbCBvciBhbGdvcml0aG0gY2FuIGhlbHAgdG8gdW5jb3ZlciBwYXR0ZXJucyBpbiB0aGUgZGF0YSwgbWFrZSBhY2N1cmF0ZSBwcmVkaWN0aW9ucywgYW5kIGRlbGl2ZXIgYWN0aW9uYWJsZSBpbnNpZ2h0cy4NCg0KSG93ZXZlciwgY2hvb3NpbmcgdGhlIG9wdGltYWwgbW9kZWwgaXMgbm90IGFsd2F5cyBzdHJhaWdodGZvcndhcmQuIEl0IHJlcXVpcmVzIGFuIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHByb2JsZW0gZG9tYWluLCB0aGUgbmF0dXJlIG9mIHRoZSBkYXRhLCBhbmQgdGhlIHBlcmZvcm1hbmNlIG1ldHJpY3MgdGhhdCBtYXR0ZXIgbW9zdCB0byBzdGFrZWhvbGRlcnMuIEluY29ycmVjdGx5IHNlbGVjdGluZyBhIG1vZGVsIG9yIGFsZ29yaXRobSBjYW4gbGVhZCB0byBvdmVyZml0dGluZywgdW5kZXJmaXR0aW5nLCBvciBpbmVmZmljaWVudCBjb21wdXRhdGlvbiwgd2hpY2ggaW4gdHVybiBjYW4gYWZmZWN0IHRoZSBvdmVyYWxsIHF1YWxpdHkgb2YgdGhlIG1vZGVsJ3MgcHJlZGljdGlvbnMgb3IgcGVyZm9ybWFuY2UuDQoNCiMjIyBGYWN0b3JzIEluZmx1ZW5jaW5nIE1vZGVsIFNlbGVjdGlvbg0KDQpTZXZlcmFsIGZhY3RvcnMgcGxheSBhIHJvbGUgaW4gZGV0ZXJtaW5pbmcgd2hpY2ggbWFjaGluZSBsZWFybmluZyBtb2RlbCBvciBhbGdvcml0aG0gaXMgbW9zdCBzdWl0YWJsZSBmb3IgYSBnaXZlbiBwcm9ibGVtLg0KDQoNCioqMS4gUHJvYmxlbSBUeXBlKiogDQoNClRoZSBuYXR1cmUgb2YgdGhlIHByb2JsZW0gaXMgcGVyaGFwcyB0aGUgbW9zdCBjcml0aWNhbCBmYWN0b3IuIElzIGl0IGEgY2xhc3NpZmljYXRpb24gdGFzayAocHJlZGljdGluZyBjYXRlZ29yaWVzKSwgcmVncmVzc2lvbiB0YXNrIChwcmVkaWN0aW5nIGNvbnRpbnVvdXMgdmFsdWVzKSwgY2x1c3RlcmluZyB0YXNrIChncm91cGluZyBkYXRhKSwgb3Igc29tZXRoaW5nIGVsc2U/IERpZmZlcmVudCBwcm9ibGVtcyByZXF1aXJlIGRpZmZlcmVudCBhbGdvcml0aG1zLg0KDQoqKkV4YW1wbGUqKi4gRm9yIGEgY2xhc3NpZmljYXRpb24gdGFzaywgYWxnb3JpdGhtcyBsaWtlIGxvZ2lzdGljIHJlZ3Jlc3Npb24sIHN1cHBvcnQgdmVjdG9yIG1hY2hpbmVzIChTVk0pLCBkZWNpc2lvbiB0cmVlcywgb3IgbmV1cmFsIG5ldHdvcmtzIG1pZ2h0IGJlIGNvbnNpZGVyZWQuIEZvciBhIHJlZ3Jlc3Npb24gdGFzaywgYWxnb3JpdGhtcyBsaWtlIGxpbmVhciByZWdyZXNzaW9uIG9yIHJhbmRvbSBmb3Jlc3RzIG1pZ2h0IGJlIG1vcmUgc3VpdGFibGUuDQoNCioqMi4gRGF0YSBDaGFyYWN0ZXJpc3RpY3MqKiANCg0KVGhlIHR5cGUgb2YgZGF0YSwgaXRzIHNpemUsIGFuZCBpdHMgcXVhbGl0eSBhbGwgaW5mbHVlbmNlIG1vZGVsIHNlbGVjdGlvbi4gRm9yIGluc3RhbmNlLCBpZiB0aGUgZGF0YXNldCBpcyBsYXJnZSBhbmQgaGlnaC1kaW1lbnNpb25hbCwgbW9kZWxzIGxpa2UgZGVlcCBuZXVyYWwgbmV0d29ya3MgbWlnaHQgYmUgbW9yZSBlZmZlY3RpdmUuIENvbnZlcnNlbHksIGlmIHRoZSBkYXRhIGlzIHNtYWxsIG9yIGNvbnRhaW5zIG1hbnkgbWlzc2luZyB2YWx1ZXMsIHNpbXBsZXIgbW9kZWxzIGxpa2UgZGVjaXNpb24gdHJlZXMgb3Igay1uZWFyZXN0IG5laWdoYm9ycyAoS05OKSBtYXkgcGVyZm9ybSBiZXR0ZXIuDQoNCioqRXhhbXBsZSoqOiBJbiBjYXNlcyB3aGVyZSBkYXRhIGlzIHNwYXJzZSBvciBjb250YWlucyBtaXNzaW5nIHZhbHVlcywgc2ltcGxlciBtb2RlbHMgc3VjaCBhcyBsb2dpc3RpYyByZWdyZXNzaW9uIG9yIGRlY2lzaW9uIHRyZWVzIG1pZ2h0IGJlIHByZWZlcnJlZCBvdmVyIGNvbXBsZXggbW9kZWxzIGxpa2UgbmV1cmFsIG5ldHdvcmtzLg0KDQoNCioqMy4gQWNjdXJhY3kgdnMuIEludGVycHJldGFiaWxpdHkqKiANCg0KU29tZSBtb2RlbHMgb2ZmZXIgaGlnaCBwcmVkaWN0aXZlIGFjY3VyYWN5IGJ1dCBhcmUgZGlmZmljdWx0IHRvIGludGVycHJldCAoZS5nLiwgZGVlcCBuZXVyYWwgbmV0d29ya3MpLCB3aGlsZSBvdGhlcnMgbWF5IHByb3ZpZGUgbGVzcyBhY2N1cmFjeSBidXQgb2ZmZXIgZ3JlYXRlciBpbnRlcnByZXRhYmlsaXR5IChlLmcuLCBkZWNpc2lvbiB0cmVlcyBvciBsaW5lYXIgcmVncmVzc2lvbikuIERlcGVuZGluZyBvbiB0aGUgYXBwbGljYXRpb24sIHN0YWtlaG9sZGVycyBtaWdodCBwcmlvcml0aXplIG9uZSBvdmVyIHRoZSBvdGhlci4NCg0KKipFeGFtcGxlKio6IEluIG1lZGljYWwgYXBwbGljYXRpb25zIHdoZXJlIGV4cGxhaW5hYmlsaXR5IGlzIGNydWNpYWwsIGRlY2lzaW9uIHRyZWVzIG9yIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbWlnaHQgYmUgY2hvc2VuIGZvciB0aGVpciB0cmFuc3BhcmVuY3ksIGV2ZW4gaWYgdGhleSBvZmZlciBzbGlnaHRseSBsb3dlciBhY2N1cmFjeSBjb21wYXJlZCB0byBhIG5ldXJhbCBuZXR3b3JrLg0KDQoqKjQuIENvbXB1dGF0aW9uYWwgUmVzb3VyY2VzIGFuZCBUaW1lIENvbnN0cmFpbnRzKiogDQoNClRoZSBjb21wdXRhdGlvbmFsIHJlc291cmNlcyByZXF1aXJlZCBmb3IgdHJhaW5pbmcgYW5kIGRlcGxveWluZyBtb2RlbHMgc2hvdWxkIGFsc28gYmUgY29uc2lkZXJlZC4gTW9yZSBjb21wbGV4IG1vZGVscywgc3VjaCBhcyBkZWVwIGxlYXJuaW5nIG1vZGVscywgbWF5IHJlcXVpcmUgc2lnbmlmaWNhbnQgY29tcHV0aW5nIHBvd2VyIGFuZCB0aW1lIHRvIHRyYWluLCB3aGlsZSBzaW1wbGVyIG1vZGVscyBjYW4gYmUgdHJhaW5lZCBtb3JlIHF1aWNrbHkgYW5kIHdpdGggZmV3ZXIgcmVzb3VyY2VzLg0KDQoqKkV4YW1wbGUqKjogSW4gYSByZWFsLXRpbWUgc3lzdGVtIHdoZXJlIHNwZWVkIGlzIGVzc2VudGlhbCwgYSBzaW1wbGVyIG1vZGVsIGxpa2UgbG9naXN0aWMgcmVncmVzc2lvbiBtYXkgYmUgcHJlZmVycmVkIGR1ZSB0byBpdHMgbG93ZXIgY29tcHV0YXRpb25hbCBjb3N0IGNvbXBhcmVkIHRvIGEgbW9yZSBjb21wbGV4IG1vZGVsIGxpa2UgYSBkZWVwIG5ldXJhbCBuZXR3b3JrLg0KDQoNCioqNS4gUGVyZm9ybWFuY2UgTWV0cmljcyoqIA0KDQpUaGUgcGVyZm9ybWFuY2UgbWV0cmljIGJlaW5nIG9wdGltaXplZCBhbHNvIHBsYXlzIGEga2V5IHJvbGUgaW4gYWxnb3JpdGhtIHNlbGVjdGlvbi4gRGlmZmVyZW50IG1vZGVscyBleGNlbCBhdCBkaWZmZXJlbnQgZXZhbHVhdGlvbiBjcml0ZXJpYSwgc3VjaCBhcyBhY2N1cmFjeSwgcHJlY2lzaW9uLCByZWNhbGwsIEYxIHNjb3JlLCBvciBhcmVhIHVuZGVyIHRoZSBST0MgY3VydmUgKEFVQykuIFRoZSBjaG9pY2Ugb2YgbWV0cmljIGRlcGVuZHMgb24gdGhlIHRhc2sgYW5kIHRoZSBzcGVjaWZpYyBnb2FscyBvZiB0aGUgcHJvamVjdC4NCg0KKipFeGFtcGxlKio6IEluIGEgZnJhdWQgZGV0ZWN0aW9uIHN5c3RlbSwgcHJlY2lzaW9uIGFuZCByZWNhbGwgbWlnaHQgYmUgcHJpb3JpdGl6ZWQgb3ZlciBhY2N1cmFjeSB0byBlbnN1cmUgdGhhdCBmcmF1ZHVsZW50IGFjdGl2aXRpZXMgYXJlIGRldGVjdGVkIHdpdGggbWluaW1hbCBmYWxzZSBuZWdhdGl2ZXMuDQoNCg0KIyMjIFByb2Nlc3Mgb2YgTW9kZWwgSWRlbnRpZmljYXRpb24gDQoNClNlbGVjdGluZyB0aGUgb3B0aW1hbCBtb2RlbCBhbmQgYWxnb3JpdGhtIHR5cGljYWxseSBpbnZvbHZlcyBzZXZlcmFsIGtleSBzdGVwcyBpbiB0aGUgbWFjaGluZSBsZWFybmluZyBwaXBlbGluZS4gVGhlc2Ugc3RlcHMgaGVscCBndWlkZSB0aGUgcHJhY3RpdGlvbmVyIHRocm91Z2ggdGhlIHByb2Nlc3Mgb2YgZXhwZXJpbWVudGF0aW9uLCBldmFsdWF0aW9uLCBhbmQgcmVmaW5lbWVudC4NCg0KKioxLiBEYXRhIFByZXByb2Nlc3NpbmcqKiANCg0KQmVmb3JlIHNlbGVjdGluZyBhIG1vZGVsLCBpdCBpcyBlc3NlbnRpYWwgdG8gcHJlcHJvY2VzcyB0aGUgZGF0YS4gVGhpcyBpbmNsdWRlcyBoYW5kbGluZyBtaXNzaW5nIHZhbHVlcywgZW5jb2RpbmcgY2F0ZWdvcmljYWwgdmFyaWFibGVzLCBzY2FsaW5nIG51bWVyaWNhbCBmZWF0dXJlcywgYW5kIHBlcmZvcm1pbmcgYW55IG5lY2Vzc2FyeSB0cmFuc2Zvcm1hdGlvbnMuIFByb3BlciBkYXRhIHByZXBhcmF0aW9uIGVuc3VyZXMgdGhhdCB0aGUgY2hvc2VuIG1vZGVsIHJlY2VpdmVzIGNsZWFuLCBzdHJ1Y3R1cmVkIGlucHV0LCBpbXByb3ZpbmcgaXRzIGFiaWxpdHkgdG8gbWFrZSBhY2N1cmF0ZSBwcmVkaWN0aW9ucy4NCg0KKioyLiBNb2RlbCBTZWxlY3Rpb24gQmFzZWQgb24gUHJvYmxlbSBUeXBlKioNCg0KVGhlIGZpcnN0IHN0ZXAgaW4gaWRlbnRpZnlpbmcgdGhlIG9wdGltYWwgYWxnb3JpdGhtIGlzIHRvIHNlbGVjdCBhIG1vZGVsIGJhc2VkIG9uIHRoZSBwcm9ibGVtIHR5cGUuIEZvciBzdXBlcnZpc2VkIGxlYXJuaW5nIHRhc2tzIGxpa2UgY2xhc3NpZmljYXRpb24gYW5kIHJlZ3Jlc3Npb24sIGEgd2lkZSBhcnJheSBvZiBtb2RlbHMgbWF5IGJlIHRlc3RlZC4gVGhlc2UgaW5jbHVkZToNCg0KKiAqKkZvciBDbGFzc2lmaWNhdGlvbioqOiBMb2dpc3RpYyByZWdyZXNzaW9uLCBkZWNpc2lvbiB0cmVlcywgc3VwcG9ydCB2ZWN0b3IgbWFjaGluZXMsIGstbmVhcmVzdCBuZWlnaGJvcnMsIGFuZCBlbnNlbWJsZSBtZXRob2RzIGxpa2UgcmFuZG9tIGZvcmVzdHMgYW5kIGdyYWRpZW50IGJvb3N0aW5nLg0KDQoqICoqRm9yIFJlZ3Jlc3Npb24qKjogTGluZWFyIHJlZ3Jlc3Npb24sIGRlY2lzaW9uIHRyZWVzLCByYW5kb20gZm9yZXN0cywgc3VwcG9ydCB2ZWN0b3IgcmVncmVzc2lvbiwgYW5kIG5ldXJhbCBuZXR3b3Jrcy4NCg0KKiAqKkZvciBDbHVzdGVyaW5nKio6IEstbWVhbnMsIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nLCBEQlNDQU4sIGFuZCBHYXVzc2lhbiBtaXh0dXJlIG1vZGVscy4NCg0KDQoqKjMuIE1vZGVsIFRyYWluaW5nIGFuZCBFdmFsdWF0aW9uKioNCg0KT25jZSB0aGUgbW9kZWxzIGFyZSBzZWxlY3RlZCwgdGhleSBhcmUgdHJhaW5lZCBvbiB0aGUgYXZhaWxhYmxlIGRhdGFzZXQuIEl0IGlzIGVzc2VudGlhbCB0byBzcGxpdCB0aGUgZGF0YXNldCBpbnRvIHRyYWluaW5nLCB2YWxpZGF0aW9uLCBhbmQgdGVzdCBzZXRzIHRvIGF2b2lkIG92ZXJmaXR0aW5nIGFuZCBlbnN1cmUgdGhhdCB0aGUgbW9kZWwgZ2VuZXJhbGl6ZXMgd2VsbCB0byB1bnNlZW4gZGF0YS4gTW9kZWwgZXZhbHVhdGlvbiBpcyBkb25lIHVzaW5nIGFwcHJvcHJpYXRlIHBlcmZvcm1hbmNlIG1ldHJpY3MgKGUuZy4sIGFjY3VyYWN5LCBwcmVjaXNpb24sIHJlY2FsbCwgZXRjLikuDQoNCkNyb3NzLXZhbGlkYXRpb24gdGVjaG5pcXVlcywgc3VjaCBhcyBrLWZvbGQgY3Jvc3MtdmFsaWRhdGlvbiwgYXJlIG9mdGVuIHVzZWQgdG8gZnVydGhlciBhc3Nlc3MgbW9kZWwgcGVyZm9ybWFuY2UgYW5kIHN0YWJpbGl0eS4gVGhpcyBwcm9jZXNzIGhlbHBzIGRldGVybWluZSBob3cgd2VsbCB0aGUgbW9kZWwgd2lsbCBwZXJmb3JtIG9uIHVuc2VlbiBkYXRhIGFuZCBwcmV2ZW50cyBvdmVyZml0dGluZyBieSBlbnN1cmluZyB0aGUgbW9kZWwgZ2VuZXJhbGl6ZXMgd2VsbC4NCg0KKio0LiBIeXBlcnBhcmFtZXRlciBUdW5pbmcqKg0KDQpNYW55IG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtcyBoYXZlIGh5cGVycGFyYW1ldGVycyB0aGF0IG5lZWQgdG8gYmUgdHVuZWQgZm9yIG9wdGltYWwgcGVyZm9ybWFuY2UuIFRoZXNlIGh5cGVycGFyYW1ldGVycyBjb250cm9sIHZhcmlvdXMgYXNwZWN0cyBvZiB0aGUgbW9kZWwsIHN1Y2ggYXMgdGhlIGxlYXJuaW5nIHJhdGUsIHJlZ3VsYXJpemF0aW9uIHN0cmVuZ3RoLCBhbmQgdGhlIGRlcHRoIG9mIGRlY2lzaW9uIHRyZWVzLiBIeXBlcnBhcmFtZXRlciB0dW5pbmcgaXMgdHlwaWNhbGx5IGRvbmUgdXNpbmcgZ3JpZCBzZWFyY2ggb3IgcmFuZG9taXplZCBzZWFyY2ggdGVjaG5pcXVlcywgd2hpY2ggaW52b2x2ZSB0cmFpbmluZyB0aGUgbW9kZWwgbXVsdGlwbGUgdGltZXMgd2l0aCBkaWZmZXJlbnQgaHlwZXJwYXJhbWV0ZXIgdmFsdWVzIGFuZCBzZWxlY3RpbmcgdGhlIHNldCB0aGF0IHJlc3VsdHMgaW4gdGhlIGJlc3QgcGVyZm9ybWFuY2UuDQoNCioqNS4gTW9kZWwgQ29tcGFyaXNvbioqDQoNCkFmdGVyIHRyYWluaW5nIGFuZCB0dW5pbmcgc2V2ZXJhbCBtb2RlbHMsIHRoZSBwZXJmb3JtYW5jZSBvZiBlYWNoIG1vZGVsIGlzIGNvbXBhcmVkIHVzaW5nIHRoZSBzZWxlY3RlZCBtZXRyaWNzLiBUaGlzIGNvbXBhcmlzb24gYWxsb3dzIHByYWN0aXRpb25lcnMgdG8gZXZhbHVhdGUgdGhlIHRyYWRlLW9mZnMgYmV0d2VlbiBtb2RlbHMgaW4gdGVybXMgb2YgYWNjdXJhY3ksIGludGVycHJldGFiaWxpdHksIGFuZCBjb21wdXRhdGlvbmFsIGVmZmljaWVuY3kuDQoNCioqRXhhbXBsZSoqOiBJZiBhIGRlY2lzaW9uIHRyZWUgbW9kZWwgb2ZmZXJzIGhpZ2ggaW50ZXJwcmV0YWJpbGl0eSBidXQgbG93ZXIgYWNjdXJhY3kgY29tcGFyZWQgdG8gYSByYW5kb20gZm9yZXN0IG1vZGVsLCBhIGRlY2lzaW9uIG1pZ2h0IGJlIG1hZGUgdG8gcHJpb3JpdGl6ZSBhY2N1cmFjeSBvdmVyIGludGVycHJldGFiaWxpdHksIGRlcGVuZGluZyBvbiB0aGUgcHJvamVjdCdzIG5lZWRzLg0KDQoqKjYuIE1vZGVsIERlcGxveW1lbnQgYW5kIE1vbml0b3JpbmcqKg0KDQpPbmNlIHRoZSBvcHRpbWFsIG1vZGVsIGhhcyBiZWVuIGlkZW50aWZpZWQsIGl0IGlzIGRlcGxveWVkIGludG8gcHJvZHVjdGlvbi4gQ29udGludW91cyBtb25pdG9yaW5nIGlzIGVzc2VudGlhbCB0byBlbnN1cmUgdGhhdCB0aGUgbW9kZWwgY29udGludWVzIHRvIHBlcmZvcm0gd2VsbCBhcyBuZXcgZGF0YSBpcyBjb2xsZWN0ZWQuIElmIHBlcmZvcm1hbmNlIGRyb3BzIG92ZXIgdGltZSwgdGhlIG1vZGVsIG1heSBuZWVkIHRvIGJlIHJldHJhaW5lZCBvciB1cGRhdGVkLg0KDQojIyMgQ2hhbGxlbmdlcyBpbiBNb2RlbCBTZWxlY3Rpb24NCg0KVGhlIHByb2Nlc3Mgb2YgaWRlbnRpZnlpbmcgdGhlIG9wdGltYWwgbW9kZWwgaXMgbm90IHdpdGhvdXQgY2hhbGxlbmdlcy4gU29tZSBvZiB0aGUga2V5IGRpZmZpY3VsdGllcyBpbmNsdWRlOg0KDQoqKk1vZGVsIENvbXBsZXhpdHkgdnMuIFBlcmZvcm1hbmNlKio6IE1vcmUgY29tcGxleCBtb2RlbHMgbWF5IGFjaGlldmUgaGlnaGVyIGFjY3VyYWN5IGJ1dCByZXF1aXJlIG1vcmUgY29tcHV0YXRpb25hbCByZXNvdXJjZXMgYW5kIGFyZSBtb3JlIHByb25lIHRvIG92ZXJmaXR0aW5nLiBCYWxhbmNpbmcgY29tcGxleGl0eSB3aXRoIHBlcmZvcm1hbmNlIGlzIGEgY29tbW9uIGNoYWxsZW5nZS4NCg0KKipEYXRhIFF1YWxpdHkqKjogUG9vciBkYXRhIHF1YWxpdHksIGluY2x1ZGluZyBtaXNzaW5nIHZhbHVlcywgaW1iYWxhbmNlZCBjbGFzc2VzLCBvciBub2lzeSBkYXRhLCBjYW4gbWFrZSBpdCBkaWZmaWN1bHQgdG8gaWRlbnRpZnkgdGhlIG9wdGltYWwgbW9kZWwsIGFzIHRoZSBtb2RlbCdzIHBlcmZvcm1hbmNlIG1heSBiZSBhZmZlY3RlZCBieSB0aGUgdW5kZXJseWluZyBpc3N1ZXMgaW4gdGhlIGRhdGEuDQoNCioqT3ZlcmZpdHRpbmcqKjogU2VsZWN0aW5nIGEgbW9kZWwgdGhhdCBwZXJmb3JtcyB3ZWxsIG9uIHRyYWluaW5nIGRhdGEgYnV0IHBvb3JseSBvbiB0ZXN0IGRhdGEgZHVlIHRvIG92ZXJmaXR0aW5nIGNhbiBiZSBhIHNpZ25pZmljYW50IGNoYWxsZW5nZS4gVGVjaG5pcXVlcyBzdWNoIGFzIGNyb3NzLXZhbGlkYXRpb24gYW5kIHJlZ3VsYXJpemF0aW9uIGFyZSB1c2VkIHRvIG1pdGlnYXRlIHRoaXMgaXNzdWUuDQoNClwNCg0KSW4gc3VtbWFyeSwgaWRlbnRpZnlpbmcgdGhlIG9wdGltYWwgbW9kZWxzIGFuZCBhbGdvcml0aG1zIGluIG1hY2hpbmUgbGVhcm5pbmcgaXMgYSBjcnVjaWFsIHRhc2sgdGhhdCByZXF1aXJlcyBjYXJlZnVsIGNvbnNpZGVyYXRpb24gb2YgdmFyaW91cyBmYWN0b3JzLCBpbmNsdWRpbmcgdGhlIHByb2JsZW0gdHlwZSwgZGF0YSBjaGFyYWN0ZXJpc3RpY3MsIGF2YWlsYWJsZSByZXNvdXJjZXMsIGFuZCBwZXJmb3JtYW5jZSBtZXRyaWNzLiBUaGUgcHJvY2VzcyBpbnZvbHZlcyBleHBlcmltZW50aW5nIHdpdGggZGlmZmVyZW50IG1vZGVscywgdHJhaW5pbmcgYW5kIGV2YWx1YXRpbmcgdGhlbSwgdHVuaW5nIHRoZWlyIGh5cGVycGFyYW1ldGVycywgYW5kIHNlbGVjdGluZyB0aGUgYmVzdC1wZXJmb3JtaW5nIG1vZGVsLiBXaGlsZSB0aGUgc2VsZWN0aW9uIHByb2Nlc3MgY2FuIGJlIGNoYWxsZW5naW5nIGR1ZSB0byBpc3N1ZXMgbGlrZSBkYXRhIHF1YWxpdHksIG92ZXJmaXR0aW5nLCBhbmQgbW9kZWwgY29tcGxleGl0eSwgZm9sbG93aW5nIGEgc3RydWN0dXJlZCBhcHByb2FjaCBjYW4gbGVhZCB0byB0aGUgaWRlbnRpZmljYXRpb24gb2YgdGhlIG1vc3Qgc3VpdGFibGUgbW9kZWwgZm9yIHRoZSB0YXNrIGF0IGhhbmQuIEFzIG1hY2hpbmUgbGVhcm5pbmcgY29udGludWVzIHRvIGV2b2x2ZSwgc2VsZWN0aW5nIHRoZSByaWdodCBtb2RlbCB3aWxsIHJlbWFpbiBhIGNyaXRpY2FsIGZhY3RvciBpbiBkZWxpdmVyaW5nIGFjY3VyYXRlLCBlZmZpY2llbnQsIGFuZCBpbXBhY3RmdWwgc29sdXRpb25zDQoNCg0KDQojIyBWYWxpZGF0aW9uIGFuZCBUZXN0aW5nDQoNClZhbGlkYXRpb24gYW5kIHRlc3RpbmcgYXJlIGNyaXRpY2FsIHBoYXNlcyBpbiB0aGUgbWFjaGluZSBsZWFybmluZyAoTUwpIHdvcmtmbG93LiBUaGVzZSBzdGVwcyBlbnN1cmUgdGhhdCB0aGUgbW9kZWwgYnVpbHQgb24gdGhlIHRyYWluaW5nIGRhdGEgaXMgbm90IG9ubHkgYWNjdXJhdGUgYnV0IGFsc28gZ2VuZXJhbGl6ZXMgd2VsbCB0byBuZXcsIHVuc2VlbiBkYXRhLiBXaXRob3V0IGVmZmVjdGl2ZSB2YWxpZGF0aW9uIGFuZCB0ZXN0aW5nLCBhIG1vZGVsIG1pZ2h0IGFwcGVhciB0byBwZXJmb3JtIHdlbGwgZHVyaW5nIHRyYWluaW5nIGJ1dCBmYWlsIHRvIGRlbGl2ZXIgcmVsaWFibGUgcmVzdWx0cyBpbiByZWFsLXdvcmxkIGFwcGxpY2F0aW9ucy4gVGhpcyBzdWJzZWN0aW9uIGV4cGxvcmVzIHRoZSBpbXBvcnRhbmNlIG9mIHZhbGlkYXRpb24gYW5kIHRlc3RpbmcsIHRoZSBtZXRob2RzIGNvbW1vbmx5IHVzZWQsIGFuZCB0aGVpciByb2xlIGluIGJ1aWxkaW5nIHJvYnVzdCBtYWNoaW5lIGxlYXJuaW5nIG1vZGVscy4NCg0KDQojIyMgVGhlIEltcG9ydGFuY2Ugb2YgVmFsaWRhdGlvbiBhbmQgVGVzdGluZw0KDQpNYWNoaW5lIGxlYXJuaW5nIG1vZGVscyBhcmUgdHJhaW5lZCBvbiBhIHNwZWNpZmljIGRhdGFzZXQsIGtub3duIGFzIHRoZSB0cmFpbmluZyBkYXRhc2V0LCB3aGljaCBjb250YWlucyBleGFtcGxlcyB1c2VkIHRvIHRlYWNoIHRoZSBtb2RlbC4gSG93ZXZlciwgdGhlIHVsdGltYXRlIGdvYWwgaXMgdG8gZGV2ZWxvcCBhIG1vZGVsIHRoYXQgY2FuIG1ha2UgYWNjdXJhdGUgcHJlZGljdGlvbnMgb24gbmV3IGRhdGHigJRkYXRhIGl0IGhhcyBub3QgZW5jb3VudGVyZWQgYmVmb3JlLiBUaGlzIGlzIHdoZXJlIHZhbGlkYXRpb24gYW5kIHRlc3RpbmcgY29tZSBpbnRvIHBsYXkuDQoNCiogKipWYWxpZGF0aW9uKiogaXMgdXNlZCB0byB0dW5lIG1vZGVsIGh5cGVycGFyYW1ldGVycyBhbmQgYXNzZXNzIHRoZSBtb2RlbOKAmXMgcGVyZm9ybWFuY2UgZHVyaW5nIHRyYWluaW5nLiBJdCBoZWxwcyBpbiBzZWxlY3RpbmcgdGhlIGJlc3QgbW9kZWwgY29uZmlndXJhdGlvbiBiZWZvcmUgZmluYWwgdGVzdGluZywgZW5zdXJpbmcgdGhhdCB0aGUgbW9kZWwgZG9lcyBub3Qgc2ltcGx5IG1lbW9yaXplIHRoZSB0cmFpbmluZyBkYXRhIChhIHBoZW5vbWVub24ga25vd24gYXMgb3ZlcmZpdHRpbmcpLg0KDQoqICoqVGVzdGluZyBldmFsdWF0ZXMqKiB0aGUgbW9kZWwncyBmaW5hbCBwZXJmb3JtYW5jZSBvbiBhbiBpbmRlcGVuZGVudCBzZXQgb2YgZGF0YSwga25vd24gYXMgdGhlIHRlc3QgZGF0YXNldCwgdGhhdCB3YXMgbm90IHVzZWQgaW4gYW55IHBhcnQgb2YgdGhlIG1vZGVs4oCZcyB0cmFpbmluZyBvciB2YWxpZGF0aW9uLiBUaGlzIGZpbmFsIGV2YWx1YXRpb24gZW5zdXJlcyB0aGF0IHRoZSBtb2RlbCBnZW5lcmFsaXplcyB3ZWxsIHRvIG5ldyBkYXRhLg0KDQpXaXRob3V0IHByb3BlciB2YWxpZGF0aW9uIGFuZCB0ZXN0aW5nLCB0aGVyZSBpcyBhIHJpc2sgb2YgZGV2ZWxvcGluZyBhIG1vZGVsIHRoYXQgd29ya3Mgd2VsbCBvbiB0aGUgdHJhaW5pbmcgZGF0YSBidXQgZmFpbHMgdG8gZ2VuZXJhbGl6ZSwgbGVhZGluZyB0byBwb29yIHJlYWwtd29ybGQgcGVyZm9ybWFuY2UuIFRodXMsIHRoZXNlIHN0ZXBzIGFyZSBjcnVjaWFsIHRvIG1vZGVsIHJlbGlhYmlsaXR5IGFuZCBhY2N1cmFjeS4NCg0KDQojIyMgVmFsaWRhdGlvbiBUZWNobmlxdWVzDQoNClZhbGlkYXRpb24gbWV0aG9kcyBhcmUgdXNlZCB0byBhc3Nlc3MgdGhlIG1vZGVs4oCZcyBwZXJmb3JtYW5jZSBkdXJpbmcgdGhlIHRyYWluaW5nIHByb2Nlc3MsIGJlZm9yZSBpdCBpcyB0ZXN0ZWQgb24gdW5zZWVuIGRhdGEuIFNldmVyYWwgdGVjaG5pcXVlcyBhcmUgY29tbW9ubHkgZW1wbG95ZWQgZm9yIHRoaXMgcHVycG9zZToNCg0KKipIb2xkb3V0IE1ldGhvZCoqIA0KDQpUaGUgc2ltcGxlc3QgZm9ybSBvZiB2YWxpZGF0aW9uLCB0aGUgaG9sZG91dCBtZXRob2QgaW52b2x2ZXMgc3BsaXR0aW5nIHRoZSBkYXRhIGludG8gdHdvIG9yIHRocmVlIHNldHM6IGEgdHJhaW5pbmcgc2V0LCBhIHZhbGlkYXRpb24gc2V0LCBhbmQgc29tZXRpbWVzIGEgdGVzdCBzZXQuIFRoZSBtb2RlbCBpcyB0cmFpbmVkIG9uIHRoZSB0cmFpbmluZyBzZXQgYW5kIHZhbGlkYXRlZCBvbiB0aGUgdmFsaWRhdGlvbiBzZXQgdG8gZXZhbHVhdGUgaXRzIHBlcmZvcm1hbmNlLiBUaGUgdGVzdCBzZXQgcmVtYWlucyBjb21wbGV0ZWx5IHVudG91Y2hlZCBkdXJpbmcgdHJhaW5pbmcgYW5kIHZhbGlkYXRpb24uDQoNCioqRXhhbXBsZSoqOiBBIHR5cGljYWwgc3BsaXQgbWlnaHQgaW52b2x2ZSB1c2luZyA3MCUgb2YgdGhlIGRhdGEgZm9yIHRyYWluaW5nLCAxNSUgZm9yIHZhbGlkYXRpb24sIGFuZCAxNSUgZm9yIHRlc3RpbmcuIFRoZSBtb2RlbCBpcyB0cmFpbmVkIG9uIHRoZSA3MCUsIHR1bmVkIHVzaW5nIHRoZSAxNSUgdmFsaWRhdGlvbiBzZXQsIGFuZCBmaW5hbGx5IHRlc3RlZCBvbiB0aGUgcmVtYWluaW5nIDE1JS4NCg0KDQoqKkstRm9sZCBDcm9zcy1WYWxpZGF0aW9uKiogDQoNCk9uZSBvZiB0aGUgbW9zdCBwb3B1bGFyIHRlY2huaXF1ZXMsIGstZm9sZCBjcm9zcy12YWxpZGF0aW9uIGRpdmlkZXMgdGhlIGRhdGEgaW50byBrIGVxdWFsIHBhcnRzLCBvciAiZm9sZHMuIiBUaGUgbW9kZWwgaXMgdHJhaW5lZCBrIHRpbWVzLCBlYWNoIHRpbWUgdXNpbmcgay0xIGZvbGRzIGZvciB0cmFpbmluZyBhbmQgdGhlIHJlbWFpbmluZyBmb2xkIGZvciB2YWxpZGF0aW9uLiBUaGlzIHByb2Nlc3MgaXMgcmVwZWF0ZWQgdW50aWwgZWFjaCBmb2xkIGhhcyBiZWVuIHVzZWQgYXMgdGhlIHZhbGlkYXRpb24gc2V0IG9uY2UuIEstZm9sZCBjcm9zcy12YWxpZGF0aW9uIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiB0aGUgZGF0YXNldCBpcyBzbWFsbCwgYXMgaXQgYWxsb3dzIHRoZSBtb2RlbCB0byBiZSB2YWxpZGF0ZWQgb24gZGlmZmVyZW50IHBvcnRpb25zIG9mIHRoZSBkYXRhLg0KDQoqKkV4YW1wbGUqKjogSW4gNS1mb2xkIGNyb3NzLXZhbGlkYXRpb24sIHRoZSBkYXRhIGlzIGRpdmlkZWQgaW50byBmaXZlIHBhcnRzLiBUaGUgbW9kZWwgaXMgdHJhaW5lZCBvbiBmb3VyIHBhcnRzIGFuZCB2YWxpZGF0ZWQgb24gdGhlIHJlbWFpbmluZyBvbmUsIGFuZCB0aGlzIHByb2Nlc3MgaXMgcmVwZWF0ZWQgZml2ZSB0aW1lcywgZW5zdXJpbmcgdGhhdCBldmVyeSBkYXRhIHBvaW50IGlzIHVzZWQgZm9yIHZhbGlkYXRpb24uDQoNCioqU3RyYXRpZmllZCBLLUZvbGQgQ3Jvc3MtVmFsaWRhdGlvbioqDQoNCkEgdmFyaWF0aW9uIG9mIGstZm9sZCBjcm9zcy12YWxpZGF0aW9uLCBzdHJhdGlmaWVkIGstZm9sZCBjcm9zcy12YWxpZGF0aW9uIGVuc3VyZXMgdGhhdCBlYWNoIGZvbGQgaGFzIHRoZSBzYW1lIHByb3BvcnRpb24gb2YgZWFjaCBjbGFzcyBhcyB0aGUgZW50aXJlIGRhdGFzZXQuIFRoaXMgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCB3aGVuIHRoZSBkYXRhc2V0IGlzIGltYmFsYW5jZWQsIGFzIGl0IGVuc3VyZXMgdGhhdCB0aGUgdHJhaW5pbmcgYW5kIHZhbGlkYXRpb24gc2V0cyByZXByZXNlbnQgdGhlIGRhdGEgZGlzdHJpYnV0aW9uIGFjY3VyYXRlbHkuDQoNCioqRXhhbXBsZSoqOiBJbiBhIGJpbmFyeSBjbGFzc2lmaWNhdGlvbiB0YXNrIHdoZXJlIHRoZSBkYXRhIGlzIGltYmFsYW5jZWQgKGUuZy4sIDkwJSBjbGFzcyBBLCAxMCUgY2xhc3MgQiksIHN0cmF0aWZpZWQgay1mb2xkIGVuc3VyZXMgdGhhdCBlYWNoIGZvbGQgY29udGFpbnMgYSBzaW1pbGFyIHJhdGlvIG9mIGNsYXNzIEEgdG8gY2xhc3MgQi4NCg0KKipMZWF2ZS1PbmUtT3V0IENyb3NzLVZhbGlkYXRpb24gKExPT0NWKSoqDQoNCkluIGxlYXZlLW9uZS1vdXQgY3Jvc3MtdmFsaWRhdGlvbiwgZWFjaCBkYXRhIHBvaW50IGlzIHVzZWQgYXMgYSBzZXBhcmF0ZSB2YWxpZGF0aW9uIHNldCB3aGlsZSB0aGUgcmVzdCBvZiB0aGUgZGF0YSBwb2ludHMgYXJlIHVzZWQgZm9yIHRyYWluaW5nLiBUaGlzIHByb2Nlc3MgaXMgcmVwZWF0ZWQgZm9yIGVhY2ggZGF0YSBwb2ludCBpbiB0aGUgZGF0YXNldCwgd2hpY2ggaXMgcGFydGljdWxhcmx5IHVzZWZ1bCB3aGVuIHRoZSBkYXRhc2V0IGlzIHNtYWxsLg0KDQoqKkV4YW1wbGUqKjogRm9yIGEgZGF0YXNldCBvZiAxMDAgZGF0YSBwb2ludHMsIExPT0NWIHRyYWlucyB0aGUgbW9kZWwgMTAwIHRpbWVzLCBlYWNoIHRpbWUgbGVhdmluZyBvdXQgYSBkaWZmZXJlbnQgc2luZ2xlIGRhdGEgcG9pbnQgZm9yIHZhbGlkYXRpb24uDQoNClRoZXNlIHZhbGlkYXRpb24gdGVjaG5pcXVlcyBoZWxwIHByZXZlbnQgb3ZlcmZpdHRpbmcsIGVuc3VyZSB0aGF0IHRoZSBtb2RlbCBpcyB3ZWxsLXR1bmVkLCBhbmQgbWFrZSB0aGUgbW9zdCBvdXQgb2YgYXZhaWxhYmxlIGRhdGEuDQoNCg0KIyMjIFRlc3RpbmcgdGhlIE1vZGVsDQoNCk9uY2UgdGhlIG1vZGVsIGhhcyBiZWVuIHRyYWluZWQgYW5kIHZhbGlkYXRlZCwgaXQgaXMgY3J1Y2lhbCB0byBldmFsdWF0ZSBpdHMgcGVyZm9ybWFuY2Ugb24gYSBzZXBhcmF0ZSB0ZXN0IGRhdGFzZXQuIFRoZSB0ZXN0IHNldCBpcyB1c2VkIHRvIGFzc2VzcyBob3cgd2VsbCB0aGUgbW9kZWwgZ2VuZXJhbGl6ZXMgdG8gbmV3LCB1bnNlZW4gZGF0YS4gVGhpcyBldmFsdWF0aW9uIHByb3ZpZGVzIGFuIGVzdGltYXRlIG9mIGhvdyB0aGUgbW9kZWwgd2lsbCBwZXJmb3JtIGluIHByb2R1Y3Rpb24gb3Igb24gbmV3IGluY29taW5nIGRhdGEuDQoNCioqVGVzdCBEYXRhc2V0KioNCg0KVGhlIHRlc3QgZGF0YXNldCBzaG91bGQgbmV2ZXIgYmUgdXNlZCBpbiBhbnkgcGFydCBvZiB0aGUgbW9kZWwtYnVpbGRpbmcgcHJvY2VzcywgaW5jbHVkaW5nIGR1cmluZyB0cmFpbmluZyBvciB2YWxpZGF0aW9uLiBJdHMgc29sZSBwdXJwb3NlIGlzIHRvIHNlcnZlIGFzIGFuIGluZGVwZW5kZW50IGFzc2Vzc21lbnQgb2YgdGhlIG1vZGVs4oCZcyBnZW5lcmFsaXphdGlvbiBjYXBhYmlsaXR5Lg0KDQoqKlBlcmZvcm1hbmNlIE1ldHJpY3MqKg0KDQpUaGUgcGVyZm9ybWFuY2Ugb2YgdGhlIG1vZGVsIGlzIG1lYXN1cmVkIHVzaW5nIHZhcmlvdXMgbWV0cmljcywgd2hpY2ggZGVwZW5kIG9uIHRoZSB0eXBlIG9mIHByb2JsZW0gKGUuZy4sIGNsYXNzaWZpY2F0aW9uLCByZWdyZXNzaW9uKS4gQ29tbW9uIG1ldHJpY3MgaW5jbHVkZToNCg0KKiAqKkZvciBDbGFzc2lmaWNhdGlvbioqOiBBY2N1cmFjeSwgcHJlY2lzaW9uLCByZWNhbGwsIEYxIHNjb3JlLCBhcmVhIHVuZGVyIHRoZSBST0MgY3VydmUgKEFVQyksIGNvbmZ1c2lvbiBtYXRyaXguDQoNCiogKipGb3IgUmVncmVzc2lvbioqOiBNZWFuIHNxdWFyZWQgZXJyb3IgKE1TRSksIHJvb3QgbWVhbiBzcXVhcmVkIGVycm9yIChSTVNFKSwgbWVhbiBhYnNvbHV0ZSBlcnJvciAoTUFFKSwgUi1zcXVhcmVkLg0KDQpUaGVzZSBtZXRyaWNzIGFsbG93IHByYWN0aXRpb25lcnMgdG8gZXZhbHVhdGUgaG93IHdlbGwgdGhlIG1vZGVsIG1ha2VzIHByZWRpY3Rpb25zLCBkZXRlY3QgYmlhc2VzLCBhbmQgdW5kZXJzdGFuZCBhcmVhcyB3aGVyZSB0aGUgbW9kZWwgbWF5IHJlcXVpcmUgaW1wcm92ZW1lbnQuDQoNCioqRXhhbXBsZSoqIEZvciBhIGNsYXNzaWZpY2F0aW9uIHByb2JsZW0sIGFjY3VyYWN5IGFsb25lIG1pZ2h0IG5vdCBiZSBzdWZmaWNpZW50LCBlc3BlY2lhbGx5IGlmIHRoZSBjbGFzc2VzIGFyZSBpbWJhbGFuY2VkLiBJbiB0aGlzIGNhc2UsIG1ldHJpY3MgbGlrZSBwcmVjaXNpb24sIHJlY2FsbCwgYW5kIEYxIHNjb3JlIGNhbiBwcm92aWRlIG1vcmUgaW5zaWdodCBpbnRvIG1vZGVsIHBlcmZvcm1hbmNlLg0KDQoqKk1vZGVsIENvbXBhcmlzb24qKg0KDQpPbmNlIHRoZSBtb2RlbCBpcyB0ZXN0ZWQsIGl0IGNhbiBiZSBjb21wYXJlZCB0byBiYXNlbGluZSBtb2RlbHMgb3Igb3RoZXIgY29tcGV0aW5nIG1vZGVscyB0byBkZXRlcm1pbmUgd2hldGhlciBpdCBwcm92aWRlcyBhIHNpZ25pZmljYW50IGltcHJvdmVtZW50LiBJZiBtdWx0aXBsZSBtb2RlbHMgYXJlIGNvbnNpZGVyZWQsIHN0YXRpc3RpY2FsIHRlc3RzIGxpa2UgcGFpcmVkIHQtdGVzdHMgb3IgY3Jvc3MtdmFsaWRhdGlvbiByZXN1bHRzIGNhbiBiZSB1c2VkIHRvIGRldGVybWluZSB3aGljaCBtb2RlbCBwZXJmb3JtcyBiZXN0Lg0KDQoqKkV4YW1wbGUqKjogQSBkZWNpc2lvbiB0cmVlIG1vZGVsIG1pZ2h0IGJlIGNvbXBhcmVkIHRvIGEgcmFuZG9tIGZvcmVzdCBtb2RlbCBvciBhIHN1cHBvcnQgdmVjdG9yIG1hY2hpbmUuIFRoZSBtb2RlbCB3aXRoIHRoZSBoaWdoZXN0IHBlcmZvcm1hbmNlIG1ldHJpY3MgYW5kIGdlbmVyYWxpemF0aW9uIGFiaWxpdHkgd291bGQgYmUgY2hvc2VuIGZvciBkZXBsb3ltZW50Lg0KDQoqKk92ZXJmaXR0aW5nIGFuZCBVbmRlcmZpdHRpbmcqKiANCg0KQWZ0ZXIgdGVzdGluZyB0aGUgbW9kZWwsIGl04oCZcyBpbXBvcnRhbnQgdG8gZW5zdXJlIHRoYXQgaXQgaXMgbm90IG92ZXJmaXR0aW5nIChpLmUuLCBwZXJmb3JtaW5nIGV4Y2VwdGlvbmFsbHkgd2VsbCBvbiB0aGUgdHJhaW5pbmcgZGF0YSBidXQgcG9vcmx5IG9uIHVuc2VlbiBkYXRhKSBvciB1bmRlcmZpdHRpbmcgKGkuZS4sIG5vdCBjYXB0dXJpbmcgdGhlIHVuZGVybHlpbmcgcGF0dGVybnMgaW4gdGhlIGRhdGEgd2VsbCBlbm91Z2gpLiBUaGVzZSBpc3N1ZXMgY2FuIGJlIGRpYWdub3NlZCB1c2luZyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHBlcmZvcm1hbmNlIG9uIHRoZSB0cmFpbmluZyBzZXQsIHZhbGlkYXRpb24gc2V0LCBhbmQgdGVzdCBzZXQuDQoNCioqRXhhbXBsZSoqOiBBIG1vZGVsIHRoYXQgc2hvd3MgaGlnaCBwZXJmb3JtYW5jZSBvbiB0aGUgdHJhaW5pbmcgc2V0IGJ1dCBwZXJmb3JtcyBwb29ybHkgb24gdGhlIHRlc3Qgc2V0IG1heSBiZSBvdmVyZml0dGluZywgaW5kaWNhdGluZyB0aGUgbmVlZCBmb3IgcmVndWxhcml6YXRpb24gb3IgbW9yZSBkYXRhLg0KDQpcDQoNCkluIHN1bW1hcnksIGJvdGggdmFsaWRhdGlvbiBhbmQgdGVzdGluZyBwbGF5IGEga2V5IHJvbGUgaW4gbW9kZWwgb3B0aW1pemF0aW9uLiBWYWxpZGF0aW9uIGhlbHBzIGZpbmUtdHVuZSB0aGUgbW9kZWwgZHVyaW5nIHRoZSB0cmFpbmluZyBwcm9jZXNzLCBlbnN1cmluZyB0aGF0IGl0IGlzIG5vdCBvdmVyZml0dGluZyBvciB1bmRlcmZpdHRpbmcgdGhlIGRhdGEuIE9uY2UgYSBtb2RlbCBpcyBmaW5hbGl6ZWQsIHRlc3RpbmcgcHJvdmlkZXMgdGhlIGZpbmFsIGV2YWx1YXRpb24gb2YgaXRzIGFiaWxpdHkgdG8gZ2VuZXJhbGl6ZSB0byBuZXcgZGF0YS4gQnkgdXNpbmcgcHJvcGVyIHZhbGlkYXRpb24gdGVjaG5pcXVlcywgbWFjaGluZSBsZWFybmluZyBwcmFjdGl0aW9uZXJzIGNhbiBidWlsZCBtb2RlbHMgdGhhdCBhcmUgcm9idXN0LCBhY2N1cmF0ZSwgYW5kIGNhcGFibGUgb2YgZGVsaXZlcmluZyByZWxpYWJsZSByZXN1bHRzIG9uIHJlYWwtd29ybGQgZGF0YS4NCg0KDQojIyBSZXBvcnRpbmcgQWN0aW9uYWJsZSBSZXN1bHRzDQoNClRyYW5zbGF0aW5nIHN0YXRpc3RpY2FsIG9yIG1vZGVsIG91dHB1dHMgaW50byBhY3Rpb25hYmxlIGluc2lnaHRzIGlzIGNydWNpYWwuIEludGVycHJldGluZyByZXN1bHRzIGluIHRlcm1zIG9mIHRoZWlyIHJlYWwtd29ybGQgaW1wbGljYXRpb25zIGFkZHMgdmFsdWUgdG8gdGhlIHJlcG9ydC4NCg0KKiAqKkFjdGlvbmFibGUgSW5zaWdodHMqKjogRGlzY3VzcyBob3cgc3Rha2Vob2xkZXJzIGNhbiB1c2UgdGhlIGZpbmRpbmdzIHRvIG1ha2UgaW5mb3JtZWQgZGVjaXNpb25zIG9yIGFkZHJlc3MgY2hhbGxlbmdlcy4NCg0KKiAqKlBvbGljeSBvciBTdHJhdGVneSBSZWNvbW1lbmRhdGlvbnMqKjogU3VnZ2VzdCBzcGVjaWZpYyBwb2xpY2llcywgc3RyYXRlZ2llcywgb3IgaW50ZXJ2ZW50aW9ucyBiYXNlZCBvbiB0aGUgcmVzdWx0cy4NCg0KKiAqKlNjYWxhYmlsaXR5IGFuZCBHZW5lcmFsaXphYmlsaXR5Kio6IEV4cGxhaW4gd2hldGhlciB0aGUgZmluZGluZ3MgY2FuIGJlIGFwcGxpZWQgYmV5b25kIHRoZSBhbmFseXplZCBzYW1wbGUgb3IgY29udGV4dC4NCg0KDQpGb3IgZXhhbXBsZSwgaW4gYW4gZW52aXJvbm1lbnRhbCBpbXBhY3Qgc3R1ZHksIGludGVycHJldGluZyByZXN1bHRzIG1pZ2h0IGludm9sdmUgcmVjb21tZW5kaW5nIGNoYW5nZXMgaW4gYWdyaWN1bHR1cmFsIHByYWN0aWNlcyB0byByZWR1Y2UgY2FyYm9uIGVtaXNzaW9ucy4NCg0KDQoNCiMgRHJhZnRpbmcgRWZmZWN0aXZlIFJlcG9ydHMNCg0KVGVjaG5pY2FsIHJlcG9ydCB3cml0aW5nIGlzIGEgdml0YWwgc2tpbGwgZm9yIGRhdGEgc2NpZW50aXN0cywgZW5hYmxpbmcgdGhlbSB0byBjb21tdW5pY2F0ZSBjb21wbGV4IGZpbmRpbmdzIGFuZCBhbmFseXNlcyB0byB2YXJpb3VzIHN0YWtlaG9sZGVycyBlZmZlY3RpdmVseS4gQSB3ZWxsLXN0cnVjdHVyZWQgdGVjaG5pY2FsIHJlcG9ydCBlbnN1cmVzIGNsYXJpdHksIHByZWNpc2lvbiwgYW5kIHJlbGV2YW5jZSwgbWFraW5nIGl0IGVhc2llciBmb3IgcmVhZGVycyB0byB1bmRlcnN0YW5kIGFuZCBhY3QgdXBvbiB0aGUgaW5mb3JtYXRpb24gcHJvdmlkZWQuIEJlbG93IGFyZSBndWlkZWxpbmVzIGFuZCBiZXN0IHByYWN0aWNlcyBmb3IgY3JhZnRpbmcgZWZmZWN0aXZlIHRlY2huaWNhbCByZXBvcnRzIGluIGRhdGEgc2NpZW5jZS4NCg0KIyMgV2hhdCB0byBSZXBvcnQNCg0KSW4gc3RhdGlzdGljcyBhbmQgZGF0YSBzY2llbmNlLCBlZmZlY3RpdmUgcmVwb3J0aW5nIGlzIGNydWNpYWwgZm9yIHRyYW5zcGFyZW5jeSwgcmVwcm9kdWNpYmlsaXR5LCBhbmQgYWN0aW9uYWJsZSBpbnNpZ2h0cy4gVGhlIHdheSBmaW5kaW5ncyBhcmUgY29tbXVuaWNhdGVkIGNhbiBzaWduaWZpY2FudGx5IGluZmx1ZW5jZSBkZWNpc2lvbi1tYWtpbmcgYW5kIHRoZSBhYmlsaXR5IG9mIG90aGVycyB0byB1bmRlcnN0YW5kLCByZXBsaWNhdGUsIGFuZCBidWlsZCB1cG9uIHRoZSB3b3JrLiBQcm9wZXIgcmVwb3J0aW5nIGVuc3VyZXMgdGhhdCB0aGUgYW5hbHlzaXMgaXMgY3JlZGlibGUsIG1lYW5pbmdmdWwsIGFuZCB1c2VmdWwgdG8gc3Rha2Vob2xkZXJzLiBUaGlzIHN1YnNlY3Rpb24gZGlzY3Vzc2VzIHRoZSBrZXkgY29tcG9uZW50cyB0aGF0IHNob3VsZCBiZSByZXBvcnRlZCBpbiBzdGF0aXN0aWNzIGFuZCBkYXRhIHNjaWVuY2UgcHJvamVjdHMsIGVtcGhhc2l6aW5nIGNsYXJpdHksIGFjY3VyYWN5LCBhbmQgZXRoaWNhbCBjb25zaWRlcmF0aW9ucy4NCg0KDQojIyMgUHJvYmxlbSBEZWZpbml0aW9uIGFuZCBPYmplY3RpdmVzDQoNCkV2ZXJ5IGRhdGEgc2NpZW5jZSBvciBzdGF0aXN0aWNhbCByZXBvcnQgc2hvdWxkIGJlZ2luIHdpdGggYSBjbGVhciBhcnRpY3VsYXRpb24gb2YgdGhlIHByb2JsZW0gYmVpbmcgYWRkcmVzc2VkLiBUaGlzIGluY2x1ZGVzOg0KDQoqICoqUmVzZWFyY2ggUXVlc3Rpb25zKio6IFdoYXQgc3BlY2lmaWMgcXVlc3Rpb25zIG9yIGh5cG90aGVzZXMgaXMgdGhlIGFuYWx5c2lzIHRyeWluZyB0byBhbnN3ZXIgb3IgdGVzdD8NCg0KKiAqKk9iamVjdGl2ZXMqKjogV2hhdCBhcmUgdGhlIGdvYWxzIG9mIHRoZSBhbmFseXNpcywgc3VjaCBhcyBtYWtpbmcgcHJlZGljdGlvbnMsIHVuZGVyc3RhbmRpbmcgcmVsYXRpb25zaGlwcywgb3IgaWRlbnRpZnlpbmcgdHJlbmRzPw0KDQoqICoqQ29udGV4dCoqOiBCYWNrZ3JvdW5kIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkb21haW4sIGluZHVzdHJ5LCBvciBwcm9ibGVtIGJlaW5nIGFkZHJlc3NlZCB0byBwcm92aWRlIHN0YWtlaG9sZGVycyB3aXRoIGEgY29tcHJlaGVuc2l2ZSB1bmRlcnN0YW5kaW5nLg0KDQojIyBEYXRhIERlc2NyaXB0aW9uIGFuZCBTb3VyY2VzDQoNClVuZGVyc3RhbmRpbmcgdGhlIGRhdGEgaXMgZnVuZGFtZW50YWwgdG8gdGhlIGNyZWRpYmlsaXR5IG9mIHRoZSBhbmFseXNpcy4gSW5jbHVkZToNCg0KKiAqKkRhdGEgU291cmNlcyoqOiBUaGUgb3JpZ2luIG9mIHRoZSBkYXRhLCB3aGV0aGVyIGNvbGxlY3RlZCBpbnRlcm5hbGx5LCBzY3JhcGVkIGZyb20gdGhlIHdlYiwgb3Igc291cmNlZCBmcm9tIHB1YmxpY2x5IGF2YWlsYWJsZSByZXBvc2l0b3JpZXMuDQoNCiogKipEYXRhIENoYXJhY3RlcmlzdGljcyoqOiBEZXNjcmlwdGlvbiBvZiB0aGUgZGF0YXNldCwgaW5jbHVkaW5nIHNpemUsIG51bWJlciBvZiB2YXJpYWJsZXMsIGRhdGEgdHlwZXMsIGFuZCB3aGV0aGVyIHRoZSBkYXRhIGlzIHN0cnVjdHVyZWQgb3IgdW5zdHJ1Y3R1cmVkLg0KDQoqICoqRGF0YSBDb2xsZWN0aW9uIE1ldGhvZHMqKjogSG93IHRoZSBkYXRhIHdhcyBjb2xsZWN0ZWQgKGUuZy4sIHN1cnZleXMsIHNlbnNvcnMsIGV4cGVyaW1lbnRzKSBhbmQgYW55IHNhbXBsaW5nIG1ldGhvZHMgdXNlZC4NCg0KKiAqKkV0aGljcyBhbmQgUHJpdmFjeSoqOiBBIGRpc2N1c3Npb24gb2YgZXRoaWNhbCBjb25zaWRlcmF0aW9ucywgaW5jbHVkaW5nIGhvdyBkYXRhIHByaXZhY3kgd2FzIGVuc3VyZWQgYW5kIHdoZXRoZXIgYXBwcm9wcmlhdGUgcGVybWlzc2lvbnMgb3IgY29uc2VudHMgd2VyZSBvYnRhaW5lZC4NCg0KIyMjIERhdGEgQ2xlYW5pbmcgYW5kIFByZXByb2Nlc3NpbmcNCg0KQmVmb3JlIGFuYWx5c2lzLCBkYXRhIG9mdGVuIHJlcXVpcmVzIGNsZWFuaW5nIGFuZCBwcmVwcm9jZXNzaW5nLiBSZXBvcnQ6DQoNCiogKipIYW5kbGluZyBvZiBNaXNzaW5nIERhdGEqKjogTWV0aG9kcyB1c2VkIHRvIGFkZHJlc3MgbWlzc2luZyB2YWx1ZXMgKGUuZy4sIGltcHV0YXRpb24sIHJlbW92YWwpLg0KDQoqICoqT3V0bGllciBUcmVhdG1lbnQqKjogSWRlbnRpZmljYXRpb24gYW5kIGhhbmRsaW5nIG9mIG91dGxpZXJzLg0KDQoqICoqRGF0YSBUcmFuc2Zvcm1hdGlvbioqOiBBbnkgdHJhbnNmb3JtYXRpb25zIGFwcGxpZWQgdG8gbWFrZSB0aGUgZGF0YSBzdWl0YWJsZSBmb3IgYW5hbHlzaXMsIHN1Y2ggYXMgc2NhbGluZywgZW5jb2RpbmcsIG9yIG5vcm1hbGl6aW5nLg0KDQoqICoqRGF0YSBRdWFsaXR5IElzc3VlcyoqOiBDaGFsbGVuZ2VzIGVuY291bnRlcmVkLCBzdWNoIGFzIGluY29uc2lzdGVuY2llcywgZHVwbGljYXRlcywgb3IgYmlhc2VzIGluIHRoZSBkYXRhLg0KDQojIyMgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyAoRURBKQ0KDQpFREEgcHJvdmlkZXMgaW5zaWdodHMgaW50byB0aGUgZGF0YSdzIHN0cnVjdHVyZSBhbmQgcmVsYXRpb25zaGlwcy4gUmVwb3J0Og0KDQoqICoqRGVzY3JpcHRpdmUgU3RhdGlzdGljcyoqOiBTdW1tYXJ5IHN0YXRpc3RpY3Mgc3VjaCBhcyBtZWFuLCBtZWRpYW4sIHN0YW5kYXJkIGRldmlhdGlvbiwgYW5kIGZyZXF1ZW5jeSBkaXN0cmlidXRpb25zLg0KDQoqICoqVmlzdWFsaXphdGlvbioqOiBLZXkgdmlzdWFsaXphdGlvbnMgdGhhdCByZXZlYWwgdHJlbmRzLCBwYXR0ZXJucywgb3IgYW5vbWFsaWVzIChlLmcuLCBoaXN0b2dyYW1zLCBzY2F0dGVyIHBsb3RzLCBjb3JyZWxhdGlvbiBoZWF0bWFwcykuDQoNCiogKipJbml0aWFsIEluc2lnaHRzKio6IE9ic2VydmF0aW9ucyBmcm9tIHRoZSBkYXRhLCBzdWNoIGFzIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB2YXJpYWJsZXMgb3IgcG90ZW50aWFsIGNoYWxsZW5nZXMgZm9yIHRoZSBtb2RlbGluZyBwaGFzZS4NCg0KKiAqKkZlYXR1cmUgRW5naW5lZXJpbmcqKjogQWRkaXRpb25hbCBmZWF0dXJlIGNyZWF0aW9uIGFuZCBleHRyYWN0aW9uIGJhc2VkIG9uIG1vZGVscyBhbmQgYWxnb3JpdGhtcy4NCg0KDQojIyMgTWV0aG9kb2xvZ3kNCg0KVHJhbnNwYXJlbmN5IGluIHRoZSBtZXRob2RzIHVzZWQgZW5zdXJlcyByZXByb2R1Y2liaWxpdHkgYW5kIGFpZHMgaW50ZXJwcmV0YXRpb24uIA0KDQoqICoqU3RhdGlzdGljYWwgTWV0aG9kcyBvciBNb2RlbHMqKjogQSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiB0aGUgc3RhdGlzdGljYWwgbWV0aG9kcyBvciBtYWNoaW5lIGxlYXJuaW5nIG1vZGVscyB1c2VkLg0KDQoNCiogKipBc3N1bXB0aW9ucyoqOiBBc3N1bXB0aW9ucyB1bmRlcmx5aW5nIHRoZSBjaG9zZW4gbWV0aG9kcyBhbmQgd2hldGhlciB0aGV5IHdlcmUgdGVzdGVkIChlLmcuLCBub3JtYWxpdHksIGxpbmVhcml0eSwgaW5kZXBlbmRlbmNlKS4NCg0KKiAqKkh5cGVycGFyYW1ldGVycyBhbmQgVHVuaW5nKio6IFNwZWNpZmljIHBhcmFtZXRlcnMgb2YgdGhlIG1vZGVscyBhbmQgdGhlIHByb2Nlc3MgZm9yIG9wdGltaXppbmcgdGhlbS4NCg0KDQojIyMgVmFsaWRhdGlvbiBhbmQgVGVzdGluZw0KDQpUbyBlbnN1cmUgcmVsaWFiaWxpdHksIGRlc2NyaWJlIHRoZSB2YWxpZGF0aW9uIGFuZCB0ZXN0aW5nIHByb2Nlc3M6DQoNCiogKipUcmFpbi1UZXN0IFNwbGl0Kio6IEhvdyB0aGUgZGF0YSB3YXMgZGl2aWRlZCBpbnRvIHRyYWluaW5nLCB2YWxpZGF0aW9uLCBhbmQgdGVzdCBzZXRzLCBpbmNsdWRpbmcgcHJvcG9ydGlvbnMgYW5kIG1ldGhvZHMgKGUuZy4sIHJhbmRvbSBzYW1wbGluZywgc3RyYXRpZmllZCBzYW1wbGluZykuDQoNCiogKipWYWxpZGF0aW9uIFRlY2huaXF1ZXMqKjogQXBwcm9hY2hlcyB1c2VkLCBzdWNoIGFzIGstZm9sZCBjcm9zcy12YWxpZGF0aW9uIG9yIGhvbGRvdXQgdmFsaWRhdGlvbi4NCg0KKiAqKlBlcmZvcm1hbmNlIE1ldHJpY3MqKjogTWV0cmljcyB1c2VkIHRvIGV2YWx1YXRlIG1vZGVsIHBlcmZvcm1hbmNlIChlLmcuLCBhY2N1cmFjeSwgcHJlY2lzaW9uLCByZWNhbGwsIEYxIHNjb3JlLCBBVUMsIG1lYW4gc3F1YXJlZCBlcnJvcikuDQoNCg0KIyMjIFJlc3VsdHMsIEludGVycHJldGF0b25zLCBhbmQgRGlzY3Vzc2lvbnMNCg0KVGhlIHJlc3VsdHMgc2hvdWxkIGJlIHByZXNlbnRlZCBjbGVhcmx5IGFuZCBvYmplY3RpdmVseSwgaW5jbHVkaW5nOg0KDQoqKktleSBGaW5kaW5ncyoqOiBIaWdobGlnaHQgdGhlIG1vc3QgaW1wb3J0YW50IGluc2lnaHRzIGRlcml2ZWQgZnJvbSB0aGUgYW5hbHlzaXMgYW5kIGF2b2lkIHJlcG9ydGluZyBldmVyeXRoaW5nIHRoZSBvdXRwdXRzIG9mIHRoZSAqKmZpbmFsIG1vZGVscyoqLiBUaGUgaW50ZXJtZWRpYXRlIGNhbmRpZGF0ZSBtb2RlbHMgdGhhdCBhcmUgbm90IGNpdGVkIHRvIHN1cHBvcnQgeW91ciBhcmd1bWVudHMgc2hvdWxkIG5vdCBiZSBkaXNjdXNzZWQgaW4gdGhlIHJlcG9ydC4NCg0KDQoqKk1vZGVsIFBlcmZvcm1hbmNlKio6IERldGFpbGVkIHBlcmZvcm1hbmNlIG1ldHJpY3MsIGluY2x1ZGluZyBjb21wYXJpc29ucyBiZXR3ZWVuIGNhbmRpZGF0ZSBtb2RlbHMgb3IgbWV0aG9kcy4gIE1ha2Ugc3VyZSB0aGUgcGVyZm9ybWFuY2UgbWV0cmljcyBhcmUgYXQgdGhlIHNhbWUgc2NhbGUgYW5kIGNvbXBhcmFibGUuIA0KDQoNCioqU3RhdGlzdGljYWwgU2lnbmlmaWNhbmNlKio6IFJlcG9ydCBwLXZhbHVlcywgY29uZmlkZW5jZSBpbnRlcnZhbHMsIGFuZCBlZmZlY3Qgc2l6ZXMsIGlmIGFwcGxpY2FibGUsIG9mIHRoZSBmaW5hbCBtb2RlbChzKSB0byBiZSByZWNvbW1lbmRlZCB0byBjbGllbnRzIGFuZC9vciB0byBiZSBkZXBsb3llZCBpbiBwcm9kdWN0aW9uIGVudmlyb25tZW50Lg0KDQoqKlZpc3VhbGl6YXRpb25zKio6IENoYXJ0cywgZ3JhcGhzLCBvciB0YWJsZXMgdGhhdCBlZmZlY3RpdmVseSBjb21tdW5pY2F0ZSB0aGUgcmVzdWx0cy4gVHJ5IGludGVyYWN0aXZlIHZpc3VhbCByZXByZXNlbnRhdGlvbnMgd2hlbmV2ZXIgcG9zc2libGUgYW5kIGZvbGxvdyBiZXN0IHByYWN0aWNlcyBpbiB2aXN1YWwgZGVzaWduLg0KDQoNCioqRGlzY3Vzc2lvbiBhbmQgSW50ZXJwcmV0YXRpb24qKiBEaXNjdXNzIHRoZSByZXN1bHRzIGFuZCB0aGVpciBwcmFjdGljYWwgaW1wbGljYXRpb25zLiANCg0KKiAqKkluc2lnaHRzKio6IEV4cGxhaW4gdGhlIG1lYW5pbmcgb2YgdGhlIGZpbmRpbmdzIGFuZCBob3cgdGhleSBhZGRyZXNzIHRoZSByZXNlYXJjaCBxdWVzdGlvbnMgb3Igb2JqZWN0aXZlcy4NCg0KKiAqKkxpbWl0YXRpb25zKio6IEFja25vd2xlZGdlIGFueSBsaW1pdGF0aW9ucyBpbiB0aGUgZGF0YSwgbWV0aG9kb2xvZ3ksIG9yIGdlbmVyYWxpemFiaWxpdHkgb2YgdGhlIHJlc3VsdHMuDQoNCiogKipDb250ZXh0dWFsIFJlbGV2YW5jZSoqOiBEaXNjdXNzIGhvdyB0aGUgZmluZGluZ3MgcmVsYXRlIHRvIHRoZSBwcm9ibGVtIGRvbWFpbiBhbmQgY29udHJpYnV0ZSB0byBkZWNpc2lvbi1tYWtpbmcuDQoNCg0KDQojIyMgRXRoaWNhbCBDb25zaWRlcmF0aW9ucyBhbmQgUmVwcm9kdWNpYmlsaXR5DQoNCioqRXRoaWNhbCB0cmFuc3BhcmVuY3kqKiBpcyBhIGdyb3dpbmcgcHJpb3JpdHkgaW4gZGF0YSBzY2llbmNlLiANCg0KKiAqKkJpYXMgYW5kIEZhaXJuZXNzKio6IEFzc2VzcyBhbmQgYWRkcmVzcyBiaWFzZXMgaW4gdGhlIGRhdGEgb3IgbW9kZWxzLg0KKiAqKlByaXZhY3kgYW5kIFNlY3VyaXR5Kio6IE1lYXN1cmVzIHRha2VuIHRvIHByb3RlY3Qgc2Vuc2l0aXZlIGRhdGEuDQoqICoqSW1wYWN0IG9mIFJlc3VsdHMqKjogQ29uc2lkZXIgcG90ZW50aWFsIGNvbnNlcXVlbmNlcyBvZiB0aGUgYW5hbHlzaXMsIGVzcGVjaWFsbHkgaWYgaXQgaW5mbHVlbmNlcyBwb2xpY3kgb3IgYnVzaW5lc3MgZGVjaXNpb25zLg0KDQoNCg0KKipSZXByb2R1Y2liaWxpdHkqKiBlbnN1cmVzIHRoYXQgb3RoZXJzIGNhbiByZXBsaWNhdGUgdGhlIGFuYWx5c2lzIGJ5IHJlcG9ydGluZyANCg0KKiAqKkNvZGUgYW5kIFRvb2xzKio6IFRoZSBwcm9ncmFtbWluZyBsYW5ndWFnZXMsIGxpYnJhcmllcywgYW5kIHNvZnR3YXJlIHRvb2xzIHVzZWQuDQoqICoqUGFyYW1ldGVycyBhbmQgU2V0dGluZ3MqKjogU3BlY2lmaWMgc2V0dGluZ3MsIGNvbmZpZ3VyYXRpb25zLCBvciBzZWVkcyB1c2VkIGluIHRoZSBhbmFseXNpcy4NCiogKipBY2Nlc3MgdG8gRGF0YSBhbmQgQ29kZSoqOiBXaGV0aGVyIHRoZSBkYXRhIGFuZCBjb2RlIGFyZSBhdmFpbGFibGUgYW5kIGhvdyB0aGV5IGNhbiBiZSBhY2Nlc3NlZCAod2hpbGUgYWRoZXJpbmcgdG8gcHJpdmFjeSBhbmQgY29weXJpZ2h0IHJlc3RyaWN0aW9ucykuDQoNCg0KDQojIyMgQ29uY2x1c2lvbiBhbmQgUmVjb21tZW5kYXRpb25zDQoNClN1bW1hcml6ZSBhbmQgcHJvdmlkZSBhY3Rpb25hYmxlIGluc2lnaHRzOg0KDQoqKlN1bW1hcnkqKjogUmVjYXAgdGhlIHByb2JsZW0sIGFwcHJvYWNoLCBhbmQga2V5IGZpbmRpbmdzLg0KDQoqKlJlY29tbWVuZGF0aW9ucyoqOiBPZmZlciBzdWdnZXN0aW9ucyBmb3Igc3Rha2Vob2xkZXJzLCBzdWNoIGFzIHBvbGljeSBjaGFuZ2VzLCBmdXJ0aGVyIGFuYWx5c2lzLCBvciBidXNpbmVzcyBzdHJhdGVnaWVzLg0KDQoqKkZ1dHVyZSBXb3JrKio6IEhpZ2hsaWdodCBhcmVhcyBmb3IgYWRkaXRpb25hbCBleHBsb3JhdGlvbiBvciBpbXByb3ZlbWVudC4NCg0KXA0KDQpJbiBzdW1tYXJ5LCBlZmZlY3RpdmUgcmVwb3J0aW5nIGluIHN0YXRpc3RpY3MgYW5kIGRhdGEgc2NpZW5jZSByZXF1aXJlcyBjbGFyaXR5LCBhY2N1cmFjeSwgYW5kIHRob3JvdWdobmVzcy4gQnkgYWRkcmVzc2luZyB0aGUgcHJvYmxlbSwgZGF0YSwgbWV0aG9kcywgcmVzdWx0cywgYW5kIGltcGxpY2F0aW9ucywgYW5hbHlzdHMgY2FuIGVuc3VyZSB0aGF0IHRoZWlyIGZpbmRpbmdzIGFyZSB1bmRlcnN0YW5kYWJsZSwgYWN0aW9uYWJsZSwgYW5kIHJlcHJvZHVjaWJsZS4gQWRkaXRpb25hbGx5LCBldGhpY2FsIGNvbnNpZGVyYXRpb25zIGFuZCByZXByb2R1Y2liaWxpdHkgYXJlIGludGVncmFsIHRvIGJ1aWxkaW5nIHRydXN0IGFuZCBmb3N0ZXJpbmcgcmVzcG9uc2libGUgZGF0YSBzY2llbmNlIHByYWN0aWNlcy4gQSBjb21wcmVoZW5zaXZlIHJlcG9ydCBub3Qgb25seSBzaG93Y2FzZXMgdGhlIHRlY2huaWNhbCByaWdvciBvZiB0aGUgYW5hbHlzaXMgYnV0IGFsc28gYnJpZGdlcyB0aGUgZ2FwIGJldHdlZW4gY29tcGxleCBkYXRhIHNjaWVuY2UgcHJvY2Vzc2VzIGFuZCBhY3Rpb25hYmxlIGluc2lnaHRzIGZvciBzdGFrZWhvbGRlcnMuDQoNCg0KDQojIyBTdHJ1Y3R1cmUgb2YgYSBUZWNobmljYWwgUmVwb3J0DQoNCkluIHRoZSBmaWVsZHMgb2Ygc3RhdGlzdGljcyBhbmQgZGF0YSBzY2llbmNlLCBlZmZlY3RpdmUgY29tbXVuaWNhdGlvbiBvZiBmaW5kaW5ncyBpcyBwYXJhbW91bnQuIEEgd2VsbC1zdHJ1Y3R1cmVkIHJlcG9ydCBhbGxvd3Mgc3Rha2Vob2xkZXJzIHRvIHVuZGVyc3RhbmQgdGhlIGFuYWx5c2lzLCBldmFsdWF0ZSBpdHMgcmVsaWFiaWxpdHksIGFuZCBkZXJpdmUgYWN0aW9uYWJsZSBpbnNpZ2h0cy4gVGhlIHN0cnVjdHVyZSBvZiBzdWNoIGEgcmVwb3J0IG11c3QgYmFsYW5jZSB0ZWNobmljYWwgcmlnb3Igd2l0aCBjbGFyaXR5IHRvIGNhdGVyIHRvIGJvdGggdGVjaG5pY2FsIGFuZCBub24tdGVjaG5pY2FsIGF1ZGllbmNlcy4gDQoNCiMjIyBUaXRsZSBhbmQgQWJzdHJhY3QNCg0KVGhlIHRpdGxlIGFuZCBhYnN0cmFjdCBhcmUgdGhlIGZpcnN0IGNvbXBvbmVudHMgb2YgdGhlIHJlcG9ydCB0aGF0IHJlYWRlcnMgZW5jb3VudGVyLiANCg0KKipUaXRsZSoqOiBBIGNvbmNpc2UgYW5kIGRlc2NyaXB0aXZlIHRpdGxlIHNob3VsZCBhY2N1cmF0ZWx5IHJlZmxlY3QgdGhlIGNvbnRlbnQgb2YgdGhlIHJlcG9ydC4gSXQgc2hvdWxkIGluY2x1ZGUga2V5IHRlcm1zIHJlbGV2YW50IHRvIHRoZSBhbmFseXNpcyB0byBpbW1lZGlhdGVseSBpbmZvcm0gcmVhZGVycyBhYm91dCB0aGUgc2NvcGUgb2YgdGhlIHdvcmsuDQoNCioqQWJzdHJhY3QqKjogVGhlIGFic3RyYWN0IHByb3ZpZGVzIGEgYnJpZWYgc3VtbWFyeSBvZiB0aGUgcmVwb3J0LCB0eXBpY2FsbHkgaW4gMTUw4oCTMjUwIHdvcmRzLiBJdCBvdXRsaW5lcyB0aGUgcHJvYmxlbSwgbWV0aG9kb2xvZ3ksIGtleSByZXN1bHRzLCBhbmQgbWFpbiBjb25jbHVzaW9ucy4gVGhlIGFic3RyYWN0IGhlbHBzIHJlYWRlcnMgcXVpY2tseSBkZXRlcm1pbmUgdGhlIHJlcG9ydOKAmXMgcmVsZXZhbmNlIHRvIHRoZWlyIG5lZWRzLiA8Zm9udCBjb2xvciA9ICJyZWQiPioqXGNvbG9ye3JlZH0gQWJzdHJhY3QgaXMgYW4gb3B0aW9uYWwgY29tcG9uZW50IG9mIGFsbCByZXBvcnRzIGluIHRoaXMgY2xhc3MuIEhvd2V2ZXIsIHlvdSBhcmUgZW5jb3VyYWdlZCB0byBpbmNsdWRlIHRoZSBhYnN0YXJhY3QgaW4geW91dCByZXBvcnQqKjwvZm9udD4NCg0KIyMjIEludHJvZHVjdGlvbg0KDQpUaGUgaW50cm9kdWN0aW9uIHNldHMgdGhlIHN0YWdlIGZvciB0aGUgcmVwb3J0IGJ5IHByb3ZpZGluZyBjb250ZXh0IGFuZCBkZWZpbmluZyBpdHMgb2JqZWN0aXZlcy4NCg0KKipCYWNrZ3JvdW5kKio6IEV4cGxhaW4gdGhlIHByb2JsZW0gZG9tYWluIGFuZCB3aHkgdGhlIGFuYWx5c2lzIGlzIGltcG9ydGFudC4gVGhpcyBpbmNsdWRlcyBhIGRpc2N1c3Npb24gb2YgYW55IHByaW9yIHdvcmsgb3IgY2hhbGxlbmdlcyB0aGF0IG5lY2Vzc2l0YXRlZCB0aGUgYW5hbHlzaXMuDQoNCioqT2JqZWN0aXZlcyoqOiBDbGVhcmx5IHN0YXRlIHRoZSBnb2FscyBvZiB0aGUgcmVwb3J0LCBzdWNoIGFzIGFuc3dlcmluZyBzcGVjaWZpYyByZXNlYXJjaCBxdWVzdGlvbnMsIHRlc3RpbmcgaHlwb3RoZXNlcywgb3IgZGV2ZWxvcGluZyBwcmVkaWN0aXZlIG1vZGVscy4NCg0KKipTY29wZSoqOiBEZWZpbmUgdGhlIGJvdW5kYXJpZXMgb2YgdGhlIGFuYWx5c2lzLCBpbmNsdWRpbmcgYW55IGFzc3VtcHRpb25zIG9yIGxpbWl0YXRpb25zIGtub3duIGF0IHRoZSBvdXRzZXQuDQoNCioqQ2xlYXIgUHJvYmxlbSBTdGF0ZW1lbnRzKio6IFRoZSByZXNlYXJjaC9wcmFjdGljYWwgcXVlc3Rpb25zIG11c3QgY2xlYXJseSBkZWZpbmVkIGFuZCBhcmUgdHJhbnNsYXRlIHRvIGFuYWx5dGljIHF1ZXN0aW9ucyBhY2N1cmF0ZWx5LiANCg0KDQojIyMgRGF0YSBEZXNjcmlwdGlvbg0KDQpUaGlzIHNlY3Rpb24gcHJvdmlkZXMgZGV0YWlsZWQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGRhdGEgdXNlZCBpbiB0aGUgYW5hbHlzaXMuDQoNCioqRGF0YSBTb3VyY2VzKio6IERlc2NyaWJlIHdoZXJlIHRoZSBkYXRhIG9yaWdpbmF0ZWQsIHdoZXRoZXIgZnJvbSBpbnRlcm5hbCBzeXN0ZW1zLCBleHRlcm5hbCByZXBvc2l0b3JpZXMsIG9yIGV4cGVyaW1lbnRhbCBjb2xsZWN0aW9uIG1ldGhvZHMuDQoNCioqRGF0YSBDaGFyYWN0ZXJpc3RpY3MqKjogUHJvdmlkZSBhbiBvdmVydmlldyBvZiB0aGUgZGF0YXNldCwgaW5jbHVkaW5nIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zLCB2YXJpYWJsZXMsIGFuZCB0eXBlcyBvZiBkYXRhIChlLmcuLCBjYXRlZ29yaWNhbCwgbnVtZXJpY2FsLCB0ZXh0KS4NCg0KKipFdGhpY2FsIENvbnNpZGVyYXRpb25zKio6IEhpZ2hsaWdodCBhbnkgbWVhc3VyZXMgdGFrZW4gdG8gZW5zdXJlIGV0aGljYWwgdXNlIG9mIHRoZSBkYXRhLCBzdWNoIGFzIGFub255bWl6YXRpb24gb3Igb2J0YWluaW5nIGNvbnNlbnQuDQoNCg0KIyMjIE1ldGhvZG9sb2d5DQoNClRoZSBtZXRob2RvbG9neSBzZWN0aW9uIG91dGxpbmVzIHRoZSBzdGVwcyB0YWtlbiB0byBwcm9jZXNzIGFuZCBhbmFseXplIHRoZSBkYXRhLg0KDQoqKkRhdGEgUHJlcHJvY2Vzc2luZyoqOiBEZXNjcmliZSBob3cgbWlzc2luZyB2YWx1ZXMsIG91dGxpZXJzLCBvciBpbmNvbnNpc3RlbmNpZXMgd2VyZSBoYW5kbGVkLCBhbG9uZyB3aXRoIGFueSB0cmFuc2Zvcm1hdGlvbnMgb3IgZmVhdHVyZSBlbmdpbmVlcmluZyBwZXJmb3JtZWQuDQoNCioqRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcyAoRURBKSoqOiBTdW1tYXJpemUgdGhlIGtleSBleHBsb3JhdG9yeSBzdGVwcywgc3VjaCBhcyBpZGVudGlmeWluZyBkaXN0cmlidXRpb25zLCByZWxhdGlvbnNoaXBzLCBhbmQgcGF0dGVybnMuIEluY2x1ZGUgcmVsZXZhbnQgdmlzdWFsaXphdGlvbnMgYW5kIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MuDQoNCioqRmVhdHVyZSBFbmdpbmVlcmluZyoqOiBTdW1tYXJpemUgYWxsIGZlYXR1cmUgZW5naW5lZXJpbmcgcHJvY2VkdXJlcyB0aGF0IGFyZSBqdXN0aWZpZWQgYW5kIHBlcmZvcm1lZCBpbiB0aGUgYW5hbHlzaXMuDQoNCioqTW9kZWxpbmcgYW5kIEFuYWx5c2lzKio6IFNwZWNpZnkgdGhlIHN0YXRpc3RpY2FsIG1ldGhvZHMsIG1hY2hpbmUgbGVhcm5pbmcgYWxnb3JpdGhtcywgb3IgYW5hbHl0aWNhbCBmcmFtZXdvcmtzIHVzZWQuIEluY2x1ZGUgZGV0YWlscyBhYm91dCBwYXJhbWV0ZXIgdHVuaW5nLCBmZWF0dXJlIHNlbGVjdGlvbiwgYW5kIGFueSBhc3N1bXB0aW9ucyB0ZXN0ZWQuDQoNCg0KIyMjIFJlcG9ydGluZyBSZXN1bHRzDQoNClRoZSByZXN1bHRzIHNlY3Rpb24gcHJlc2VudHMgdGhlIGZpbmRpbmdzIG9mIHRoZSBhbmFseXNpcyBpbiBhbiBvcmdhbml6ZWQgYW5kIGludGVycHJldGFibGUgbWFubmVyLg0KDQoqKkRlc2NyaXB0aXZlIFJlc3VsdHMqKjogSGlnaGxpZ2h0IGtleSBzdGF0aXN0aWNzLCB0cmVuZHMsIGFuZCByZWxhdGlvbnNoaXBzIGRpc2NvdmVyZWQgZHVyaW5nIEVEQS4NCg0KKipNb2RlbCBQZXJmb3JtYW5jZSoqOiBQcm92aWRlIG1ldHJpY3MgZXZhbHVhdGluZyB0aGUgcGVyZm9ybWFuY2Ugb2YgbW9kZWxzLCBzdWNoIGFzIGFjY3VyYWN5LCBwcmVjaXNpb24sIHJlY2FsbCwgb3IgUi1zcXVhcmVkLCBkZXBlbmRpbmcgb24gdGhlIHRhc2suDQoNCioqVmlzdWFsaXphdGlvbnMqKjogSW5jbHVkZSBjaGFydHMsIGdyYXBocywgb3IgdGFibGVzIHRoYXQgZWZmZWN0aXZlbHkgY29tbXVuaWNhdGUgZmluZGluZ3MuIFVzZSBhbm5vdGF0aW9ucyBhbmQgY2FwdGlvbnMgZm9yIGNsYXJpdHkuDQoNCg0KDQojIyMgRGlzY3Vzc2lvbiBhbmQgUmVjb21tZW5kYXRpb25zDQoNClRoZSBkaXNjdXNzaW9uIGludGVycHJldHMgdGhlIHJlc3VsdHMgYW5kIGNvbm5lY3RzIHRoZW0gdG8gdGhlIG9yaWdpbmFsIG9iamVjdGl2ZXMuDQoNCioqSW50ZXJwcmV0YXRpb24gb2YgUmVzdWx0cyoqOiBFeHBsYWluIHdoYXQgdGhlIGZpbmRpbmdzIG1lYW4gaW4gdGhlIGNvbnRleHQgb2YgdGhlIHByb2JsZW0uIERpc2N1c3Mgd2hldGhlciB0aGUgcmVzdWx0cyBhbnN3ZXJlZCB0aGUgcmVzZWFyY2ggcXVlc3Rpb25zIG9yIGh5cG90aGVzZXMuDQoNCioqQ29tcGFyaXNvbiB3aXRoIFByaW9yIFdvcmsqKjogSWYgYXBwbGljYWJsZSwgY29tcGFyZSB0aGUgZmluZGluZ3MgdG8gcHJldmlvdXMgc3R1ZGllcyBvciBhbmFseXNlcyB0byBoaWdobGlnaHQgc2ltaWxhcml0aWVzLCBkaWZmZXJlbmNlcywgb3IgaW1wcm92ZW1lbnRzLg0KDQoqKkxpbWl0YXRpb25zKio6IEFja25vd2xlZGdlIGFueSBsaW1pdGF0aW9ucyBpbiB0aGUgZGF0YSwgbWV0aG9kcywgb3IgZ2VuZXJhbGl6YWJpbGl0eSBvZiB0aGUgcmVzdWx0cy4gRm9yIGV4YW1wbGUsIGRpc2N1c3MgcG90ZW50aWFsIGJpYXNlcyBvciBhc3N1bXB0aW9ucyB0aGF0IG1heSBoYXZlIGluZmx1ZW5jZWQgdGhlIGFuYWx5c2lzLg0KDQoNCioqUmVjb21tZW5kYXRpb25zKio6IE9mZmVyIHN1Z2dlc3Rpb25zIGZvciBkZWNpc2lvbi1tYWtlcnMgYmFzZWQgb24gdGhlIHJlc3VsdHMsIHN1Y2ggYXMgY2hhbmdlcyB0byBwb2xpY2llcywgc3RyYXRlZ2llcywgb3IgZnVydGhlciByZXNlYXJjaC4NCg0KKipDb25jbHVzaW9ucyoqOiBSZWNhcCB0aGUga2V5IHBvaW50cyBvZiB0aGUgcmVwb3J0LCBlbXBoYXNpemluZyB0aGUgcHJvYmxlbSwgbWFqb3IgZmluZGluZ3MsIGFuZCB0aGVpciBpbXBsaWNhdGlvbnMuDQoNCiMjIy4gUmVmZXJlbmNlcyBhbmQgQXBwZW5kaWNlcw0KDQpDaXRlIGFsbCBzb3VyY2VzIG9mIGRhdGEsIHRvb2xzLCBtZXRob2RzLCBhbmQgcHJpb3IgcmVzZWFyY2ggdXNlZCBpbiB0aGUgcmVwb3J0LiBVc2UgYSBzdGFuZGFyZCBjaXRhdGlvbiBmb3JtYXQgKGUuZy4sIEFQQSwgSUVFRSkgdG8gZW5zdXJlIHByb3BlciBhdHRyaWJ1dGlvbi4gQXBwZW5kaWNlcyBwcm92aWRlIGFkZGl0aW9uYWwgZGV0YWlscyB0aGF0IHN1cHBvcnQgdGhlIG1haW4gcmVwb3J0IGJ1dCBhcmUgbm90IGVzc2VudGlhbCB0byB0aGUgcHJpbWFyeSBuYXJyYXRpdmUuDQoNClwNCg0KSW4gc3VtbWFyeSwgYSBzdGF0aXN0aWNzIGFuZCBkYXRhIHNjaWVuY2UgcmVwb3J0IGlzIG1vcmUgdGhhbiBqdXN0IGEgY29sbGVjdGlvbiBvZiBudW1iZXJzIGFuZCBjaGFydHM7IGl0IGlzIGEgc3RydWN0dXJlZCBuYXJyYXRpdmUgdGhhdCBndWlkZXMgcmVhZGVycyB0aHJvdWdoIHRoZSBhbmFseXNpcyBwcm9jZXNzIGFuZCBpdHMgZmluZGluZ3MuIEJ5IGFkaGVyaW5nIHRvIGEgY2xlYXIgc3RydWN0dXJl4oCUaW5jbHVkaW5nIGFuIGFic3RyYWN0LCBpbnRyb2R1Y3Rpb24sIGRhdGEgZGVzY3JpcHRpb24sIG1ldGhvZG9sb2d5LCByZXN1bHRzLCBkaXNjdXNzaW9uLCByZWNvbW1lbmRhdGlvbnMsIGFuZCBhcHBlbmRpY2Vz4oCUYW5hbHlzdHMgY2FuIGVmZmVjdGl2ZWx5IGNvbW11bmljYXRlIGNvbXBsZXggaWRlYXMuIFRoaXMgc3RydWN0dXJlZCBhcHByb2FjaCBlbnN1cmVzIHRoYXQgdGhlIHJlcG9ydCBpcyBjb21wcmVoZW5zaXZlLCB0cmFuc3BhcmVudCwgYW5kIGFjY2Vzc2libGUgdG8gYSBkaXZlcnNlIGF1ZGllbmNlLCB1bHRpbWF0ZWx5IGVuYWJsaW5nIGRhdGEtZHJpdmVuIGRlY2lzaW9uLW1ha2luZy4NCg0KDQoNCiMjICBSZXBvcnRpbmcgRm9ybWF0dGluZyBHdWlkZWxpbmVzDQoNCkluIHRoZSBmaWVsZCBvZiBzdGF0aXN0aWNzIGFuZCBkYXRhIHNjaWVuY2UsIGhvdyBpbmZvcm1hdGlvbiBpcyBwcmVzZW50ZWQgY2FuIGJlIGFzIGltcG9ydGFudCBhcyB0aGUgYW5hbHlzaXMgaXRzZWxmLiBQcm9wZXIgZm9ybWF0dGluZyBlbnN1cmVzIHRoYXQgcmVwb3J0cyBhcmUgY2xlYXIsIG9yZ2FuaXplZCwgYW5kIHByb2Zlc3Npb25hbCwgbWFraW5nIHRoZW0gYWNjZXNzaWJsZSB0byBkaXZlcnNlIGF1ZGllbmNlcy4gRWZmZWN0aXZlIGZvcm1hdHRpbmcgZW5oYW5jZXMgcmVhZGFiaWxpdHksIGZhY2lsaXRhdGVzIHVuZGVyc3RhbmRpbmcsIGFuZCBlbnN1cmVzIHRoYXQga2V5IGZpbmRpbmdzIGFyZSBub3QgbG9zdCBpbiBhIHNlYSBvZiBkYXRhIG9yIHRlY2huaWNhbCBqYXJnb24uIFRoaXMgc3Vic2VjdGlvbiBvdXRsaW5lcyB0aGUgZXNzZW50aWFsIGZvcm1hdHRpbmcgZ3VpZGVsaW5lcyBmb3Igc3RhdGlzdGljcyBhbmQgZGF0YSBzY2llbmNlIHJlcG9ydGluZywgY292ZXJpbmcgc3RydWN0dXJhbCBvcmdhbml6YXRpb24sIHZpc3VhbCBhaWRzLCBhbmQgc3R5bGlzdGljIGVsZW1lbnRzLg0KDQoqKjEuIFN0cnVjdHVyYWwgT3JnYW5pemF0aW9uKioNCg0KQSB3ZWxsLXN0cnVjdHVyZWQgcmVwb3J0IGZvbGxvd3MgYSBsb2dpY2FsIGZsb3csIGd1aWRpbmcgcmVhZGVycyBmcm9tIHByb2JsZW0gZGVmaW5pdGlvbiB0byBhY3Rpb25hYmxlIGluc2lnaHRzLg0KDQoqICoqU2VjdGlvbnMgYW5kIFN1YnNlY3Rpb25zKio6IFVzZSBoZWFkaW5ncyBhbmQgc3ViaGVhZGluZ3MgdG8gb3JnYW5pemUgY29udGVudCBpbnRvIGRpc3RpbmN0IHNlY3Rpb25zLCBzdWNoIGFzIEludHJvZHVjdGlvbiwgRGF0YSBEZXNjcmlwdGlvbiwgTWV0aG9kb2xvZ3ksIFJlc3VsdHMsIGFuZCBDb25jbHVzaW9ucy4gTnVtYmVyIHNlY3Rpb25zIGZvciBlYXN5IHJlZmVyZW5jZSAoZS5nLiwgMS4wLCAxLjEsIDIuMCkuDQoNCiogKipUYWJsZSBvZiBDb250ZW50cyoqOiBGb3IgbG9uZ2VyIHJlcG9ydHMsIGluY2x1ZGUgYSB0YWJsZSBvZiBjb250ZW50cyB0byBwcm92aWRlIGFuIG92ZXJ2aWV3IGFuZCBlbmFibGUgcXVpY2sgbmF2aWdhdGlvbi4NCg0KKiAqKkNvbnNpc3RlbmN5Kio6IEVuc3VyZSBjb25zaXN0ZW50IHBsYWNlbWVudCBhbmQgZm9ybWF0dGluZyBvZiB0aXRsZXMsIHN1YnRpdGxlcywgYW5kIHNlY3Rpb24gYnJlYWtzIHRocm91Z2hvdXQgdGhlIGRvY3VtZW50Lg0KDQoNCioqMi4gVmlzdWFsIEFpZHMgYW5kIERhdGEgUmVwcmVzZW50YXRpb24qKg0KDQpWaXN1YWwgcmVwcmVzZW50YXRpb24gaXMgYSBjb3JuZXJzdG9uZSBvZiBlZmZlY3RpdmUgY29tbXVuaWNhdGlvbiBpbiBzdGF0aXN0aWNzIGFuZCBkYXRhIHNjaWVuY2UuDQoNCiogKipUYWJsZXMqKjogVXNlIHRhYmxlcyB0byBzdW1tYXJpemUgbnVtZXJpY2FsIGRhdGEsIG1ha2luZyBpdCBlYXN5IGZvciByZWFkZXJzIHRvIGNvbXBhcmUgdmFsdWVzLiBFbnN1cmUgdGFibGVzIGhhdmUgY2xlYXIgaGVhZGluZ3MgYW5kIGFwcHJvcHJpYXRlIGFsaWdubWVudCAoZS5nLiwgcmlnaHQtYWxpZ24gZm9yIG51bWJlcnMsIGxlZnQtYWxpZ24gZm9yIHRleHQpLg0KDQoqICoqQ2hhcnRzIGFuZCBHcmFwaHMqKjogSW5jbHVkZSBjaGFydHMgc3VjaCBhcyBoaXN0b2dyYW1zLCBzY2F0dGVyIHBsb3RzLCBhbmQgYmFyIGdyYXBocyB0byB2aXN1YWxpemUgdHJlbmRzLCBkaXN0cmlidXRpb25zLCBhbmQgcmVsYXRpb25zaGlwcy4gQ2hvb3NlIGNoYXJ0IHR5cGVzIHRoYXQgYmVzdCBjb252ZXkgdGhlIGludGVuZGVkIG1lc3NhZ2UgYW5kIGF2b2lkIGNsdXR0ZXJlZCBvciBvdmVybHkgY29tcGxleCB2aXN1YWxzLg0KDQoqICoqTGFiZWxzIGFuZCBDYXB0aW9ucyoqOiBMYWJlbCBhbGwgZmlndXJlcyBhbmQgdGFibGVzIGNsZWFybHksIGFuZCBwcm92aWRlIGRlc2NyaXB0aXZlIGNhcHRpb25zIHRoYXQgZXhwbGFpbiB0aGVpciByZWxldmFuY2UgdG8gdGhlIGFuYWx5c2lzLg0KDQoqICoqQ29sb3IgYW5kIEFjY2Vzc2liaWxpdHkqKjogVXNlIGNvbG9ycyBzcGFyaW5nbHkgYW5kIGVuc3VyZSBhY2Nlc3NpYmlsaXR5IGJ5IHNlbGVjdGluZyBjb2xvcmJsaW5kLWZyaWVuZGx5IHBhbGV0dGVzIGFuZCBwYXR0ZXJucy4NCg0KDQoqKjMuIFR5cG9ncmFwaHkqKg0KDQpMZWdpYmxlIGFuZCBwcm9mZXNzaW9uYWwgdHlwb2dyYXBoeSBlbmhhbmNlcyByZWFkYWJpbGl0eSBhbmQgbWFpbnRhaW5zIGF1ZGllbmNlIGVuZ2FnZW1lbnQuDQoNCiogKipGb250IFN0eWxlIGFuZCBTaXplKio6IFVzZSBzaW1wbGUsIHByb2Zlc3Npb25hbCBmb250cyBzdWNoIGFzIFRpbWVzIE5ldyBSb21hbiwgQXJpYWwsIG9yIENhbGlicmksIHdpdGggYSBzdGFuZGFyZCBzaXplIChlLmcuLCAxMeKAkzEyIHB0IGZvciBib2R5IHRleHQsIDE04oCTMTYgcHQgZm9yIGhlYWRpbmdzKS4NCg0KKiAqKlNwYWNpbmcqKjogQXBwbHkgYXBwcm9wcmlhdGUgbGluZSBzcGFjaW5nICgxLjE1IG9yIDEuNSkgYW5kIG1hcmdpbnMgKGUuZy4sIDEgaW5jaCkgdG8gbWFrZSB0aGUgdGV4dCBlYXN5IHRvIHJlYWQgYW5kIGF2b2lkIG92ZXJjcm93ZGluZy4NCg0KKiAqKkJvbGQgYW5kIEl0YWxpY3MqKjogVXNlIGJvbGQgZm9yIHNlY3Rpb24gaGVhZGluZ3MgYW5kIGl0YWxpY3MgZm9yIGVtcGhhc2lzIG9yIHJlZmVyZW5jaW5nIHRlY2huaWNhbCB0ZXJtcywgYnV0IGF2b2lkIGV4Y2Vzc2l2ZSB1c2UuDQoNCg0KKio0LiBXcml0aW5nIFN0eWxlKioNCg0KQ2xhcml0eSBhbmQgY29uY2lzZW5lc3MgYXJlIHZpdGFsIGZvciBzdGF0aXN0aWNhbCBhbmQgZGF0YSBzY2llbmNlIHJlcG9ydHMuDQoNCiogKipUZWNobmljYWwgTGFuZ3VhZ2UqKjogVXNlIHByZWNpc2UgbGFuZ3VhZ2UgYXBwcm9wcmlhdGUgZm9yIHRoZSB0YXJnZXQgYXVkaWVuY2UuIEZvciBub24tdGVjaG5pY2FsIHJlYWRlcnMsIGV4cGxhaW4gamFyZ29uIGFuZCB0ZWNobmljYWwgdGVybXMgaW4gYSBnbG9zc2FyeSBvciBmb290bm90ZXMuDQoNCiogKipBY3RpdmUgVm9pY2UqKjogV3JpdGUgaW4gYW4gYWN0aXZlIHZvaWNlIHRvIG1ha2Ugc3RhdGVtZW50cyBtb3JlIGRpcmVjdCBhbmQgZW5nYWdpbmcgKGUuZy4sIOKAnFdlIGFuYWx5emVkIHRoZSBkYXRhLOKAnSBpbnN0ZWFkIG9mIOKAnFRoZSBkYXRhIHdhcyBhbmFseXplZOKAnSkuDQoNCiogKipQYXJhZ3JhcGggTGVuZ3RoKio6IEtlZXAgcGFyYWdyYXBocyBjb25jaXNlLCBmb2N1c2luZyBvbiBvbmUgbWFpbiBpZGVhIGF0IGEgdGltZS4gVXNlIGJ1bGxldCBwb2ludHMgb3IgbnVtYmVyZWQgbGlzdHMgdG8gc3VtbWFyaXplIGtleSBwb2ludHMuDQoNCiogKipPcGVuaW5nIFBhcmFncmFwaHMqKjogDQoNCiMjIFdyaXRpbmcgQmVzdCBQcmFjdGljZXMNCg0KRWZmZWN0aXZlIGNvbW11bmljYXRpb24gaXMgaW50ZWdyYWwgdG8gdGhlIHN1Y2Nlc3Mgb2Ygc3RhdGlzdGljcyBhbmQgZGF0YSBzY2llbmNlIHByb2plY3RzLiBBIHdlbGwtY3JhZnRlZCByZXBvcnQgYnJpZGdlcyB0aGUgZ2FwIGJldHdlZW4gY29tcGxleCBhbmFseXNlcyBhbmQgYWN0aW9uYWJsZSBpbnNpZ2h0cywgZW5hYmxpbmcgc3Rha2Vob2xkZXJzIHRvIG1ha2UgaW5mb3JtZWQgZGVjaXNpb25zLiBCZXN0IHByYWN0aWNlcyBpbiByZXBvcnQgd3JpdGluZyBmb2N1cyBvbiBjbGFyaXR5LCB0cmFuc3BhcmVuY3ksIGFjY3VyYWN5LCBhbmQgYWNjZXNzaWJpbGl0eS4gDQoNCioqMS4gQmVnaW4gd2l0aCBhIENsZWFyIFN0cnVjdHVyZSoqDQoNClRoZSBmb3VuZGF0aW9uIG9mIGEgZ3JlYXQgcmVwb3J0IGxpZXMgaW4gaXRzIHN0cnVjdHVyZS4gT3JnYW5pemluZyB0aGUgY29udGVudCBpbiBhIGxvZ2ljYWwgYW5kIHByZWRpY3RhYmxlIGZvcm1hdCBoZWxwcyByZWFkZXJzIG5hdmlnYXRlIHRoZSBkb2N1bWVudCBlZmZvcnRsZXNzbHkuDQoNCiogKipUaXRsZSBhbmQgQWJzdHJhY3QqKjogU3RhcnQgd2l0aCBhIGRlc2NyaXB0aXZlIHRpdGxlIGFuZCBhIGNvbmNpc2UgYWJzdHJhY3Qgc3VtbWFyaXppbmcgdGhlIHByb2JsZW0sIG1ldGhvZG9sb2d5LCBrZXkgZmluZGluZ3MsIGFuZCBjb25jbHVzaW9ucy4NCg0KKiAqKlNlY3Rpb24gSGVhZGluZ3MqKjogVXNlIHdlbGwtZGVmaW5lZCBzZWN0aW9ucyBzdWNoIGFzIEludHJvZHVjdGlvbiwgRGF0YSBEZXNjcmlwdGlvbiwgTWV0aG9kb2xvZ3ksIFJlc3VsdHMsIERpc2N1c3Npb24sIGFuZCBSZWNvbW1lbmRhdGlvbnMuIFRoZXNlIHNlY3Rpb25zIGNyZWF0ZSBhIHJvYWRtYXAgZm9yIHRoZSByZXBvcnQuDQoNCiogKipBcHBlbmRpY2VzKio6IEluY2x1ZGUgc3VwcGxlbWVudGFyeSBtYXRlcmlhbHMgc3VjaCBhcyBkZXRhaWxlZCB0YWJsZXMsIGNoYXJ0cywgb3IgY29kZSBpbiBhcHBlbmRpY2VzIHRvIGF2b2lkIGNsdXR0ZXJpbmcgdGhlIG1haW4gdGV4dC4NCg0KDQoqKjIuIEtub3cgWW91ciBBdWRpZW5jZSoqDQoNClVuZGVyc3RhbmRpbmcgdGhlIHRhcmdldCBhdWRpZW5jZSBpcyBjcnVjaWFsIGZvciBlZmZlY3RpdmUgY29tbXVuaWNhdGlvbi4NCg0KKiAqKlRhaWxvciBDb250ZW50Kio6IEFkanVzdCB0aGUgbGV2ZWwgb2YgZGV0YWlsIGFuZCB0ZWNobmljYWwgY29tcGxleGl0eSB0byBzdWl0IHRoZSBhdWRpZW5jZS4gRm9yIHRlY2huaWNhbCByZWFkZXJzLCBpbmNsdWRlIGluLWRlcHRoIGV4cGxhbmF0aW9ucywgYWxnb3JpdGhtcywgYW5kIGNvZGUuIEZvciBub24tdGVjaG5pY2FsIHN0YWtlaG9sZGVycywgZm9jdXMgb24ga2V5IGluc2lnaHRzIGFuZCBidXNpbmVzcyBpbXBsaWNhdGlvbnMuDQoNCiogKipEZWZpbmUgVGVybXMqKjogQXZvaWQgYXNzdW1pbmcgZmFtaWxpYXJpdHkgd2l0aCBqYXJnb24gb3IgdGVjaG5pY2FsIHRlcm1zLiBQcm92aWRlIGNsZWFyIGRlZmluaXRpb25zIG9yIGluY2x1ZGUgYSBnbG9zc2FyeSBmb3IgdW5mYW1pbGlhciBjb25jZXB0cy4NCg0KKiozLiBQcmlvcml0aXplIENsYXJpdHkgYW5kIFNpbXBsaWNpdHkqKg0KDQpBIHJlcG9ydCBzaG91bGQgY29tbXVuaWNhdGUgY29tcGxleCBpZGVhcyBpbiBhIHdheSB0aGF0IGlzIGVhc3kgdG8gdW5kZXJzdGFuZC4NCg0KKiAqKkNvbmNpc2UgV3JpdGluZyoqOiBBdm9pZCB2ZXJib3NpdHkgYnkgcHJlc2VudGluZyBpZGVhcyBzdWNjaW5jdGx5LiBVc2UgYnVsbGV0IHBvaW50cyBhbmQgbnVtYmVyZWQgbGlzdHMgdG8gc3VtbWFyaXplIGtleSBwb2ludHMuDQoNCiogKipBY3RpdmUgVm9pY2UqKjogVXNlIGFjdGl2ZSB2b2ljZSBmb3IgZGlyZWN0IGFuZCBlbmdhZ2luZyBzZW50ZW5jZXMgKGUuZy4sICJXZSBhbmFseXplZCB0aGUgZGF0YSwiIGluc3RlYWQgb2YgIlRoZSBkYXRhIHdhcyBhbmFseXplZCIpLg0KDQoqICoqTG9naWNhbCBGbG93Kio6IFByZXNlbnQgdGhlIGNvbnRlbnQgaW4gYSBsb2dpY2FsIHNlcXVlbmNlLCBsZWFkaW5nIHJlYWRlcnMgc3RlcC1ieS1zdGVwIHRocm91Z2ggdGhlIGFuYWx5c2lzLg0KDQoNCioqNC4gRW5zdXJlIFRyYW5zcGFyZW5jeSBhbmQgUmVwcm9kdWNpYmlsaXR5KioNCg0KVHJhbnNwYXJlbmN5IGJ1aWxkcyB0cnVzdCBpbiB0aGUgZmluZGluZ3MsIHdoaWxlIHJlcHJvZHVjaWJpbGl0eSBhbGxvd3Mgb3RoZXJzIHRvIHZhbGlkYXRlIHRoZSB3b3JrLg0KDQoqICoqRGF0YSBEZXNjcmlwdGlvbioqOiBQcm92aWRlIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkYXRhc2V0LCBpbmNsdWRpbmcgc291cmNlcywgY29sbGVjdGlvbiBtZXRob2RzLCBhbmQgY2hhcmFjdGVyaXN0aWNzLg0KDQoqICoqTWV0aG9kb2xvZ3kqKjogQ2xlYXJseSBleHBsYWluIHRoZSBzdGVwcyB0YWtlbiBpbiBwcmVwcm9jZXNzaW5nLCBleHBsb3JhdG9yeSBhbmFseXNpcywgbW9kZWxpbmcsIGFuZCB2YWxpZGF0aW9uLiBNZW50aW9uIGFueSBhc3N1bXB0aW9ucyBvciBsaW1pdGF0aW9ucyBvZiB0aGUgbWV0aG9kcyB1c2VkLg0KDQoqICoqQ29kZSBhbmQgVG9vbHMqKjogU2hhcmUgdGhlIHByb2dyYW1taW5nIHRvb2xzLCBsaWJyYXJpZXMsIGFuZCBjb2RlIHNuaXBwZXRzIHVzZWQgaW4gdGhlIGFuYWx5c2lzLCBhZGhlcmluZyB0byBhbnkgYXBwbGljYWJsZSBkYXRhLXNoYXJpbmcgYW5kIHByaXZhY3kgY29uc3RyYWludHMuDQoNCg0KKio1LiBFbXBoYXNpemUgVmlzdWFsIENvbW11bmljYXRpb24qKg0KDQpWaXN1YWwgZWxlbWVudHMgZW5oYW5jZSB1bmRlcnN0YW5kaW5nIGFuZCBtYWtlIHRoZSByZXBvcnQgbW9yZSBlbmdhZ2luZy4NCg0KKiAqKkRhdGEgVmlzdWFsaXphdGlvbnMqKjogVXNlIGNoYXJ0cywgZ3JhcGhzLCBhbmQgcGxvdHMgdG8gcmVwcmVzZW50IGRhdGEgYW5kIGZpbmRpbmdzLiBFbnN1cmUgZWFjaCB2aXN1YWxpemF0aW9uIGlzIGxhYmVsZWQsIGNhcHRpb25lZCwgYW5kIGVhc3kgdG8gaW50ZXJwcmV0Lg0KDQoqICoqQ2xhcml0eSBpbiBEZXNpZ24qKjogQXZvaWQgb3ZlcmNyb3dkaW5nIHZpc3VhbHMgd2l0aCBleGNlc3NpdmUgaW5mb3JtYXRpb24uIFVzZSBjbGVhbiwgbWluaW1hbGlzdCBkZXNpZ25zIHdpdGggY29sb3Igc2NoZW1lcyBhY2Nlc3NpYmxlIHRvIGNvbG9yYmxpbmQgcmVhZGVycy4NCg0KKiAqKkNvbXBhcmF0aXZlIEFuYWx5c2lzKio6IFdoZW4gcHJlc2VudGluZyBtdWx0aXBsZSBtb2RlbHMgb3Igc2NlbmFyaW9zLCB1c2Ugc2lkZS1ieS1zaWRlIHZpc3VhbCBjb21wYXJpc29ucyB0byBoaWdobGlnaHQgZGlmZmVyZW5jZXMuDQoNCg0KKio2LiBQcmVzZW50IFJlc3VsdHMgT2JqZWN0aXZlbHkqKg0KDQpPYmplY3Rpdml0eSBpbiBwcmVzZW50aW5nIHJlc3VsdHMgaXMgY3JpdGljYWwgZm9yIGNyZWRpYmlsaXR5Lg0KDQoqICoqUmVwb3J0IEFsbCBSZXN1bHRzKio6IEluY2x1ZGUgYm90aCBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgZmluZGluZ3MuIEFja25vd2xlZGdlIGFueSBpbmNvbnNpc3RlbmNpZXMgb3IgdW5leHBlY3RlZCBvdXRjb21lcy4NCg0KKiAqKlBlcmZvcm1hbmNlIE1ldHJpY3MqKjogQ2xlYXJseSBleHBsYWluIHRoZSBtZXRyaWNzIHVzZWQgdG8gZXZhbHVhdGUgbW9kZWxzIChlLmcuLCBhY2N1cmFjeSwgcHJlY2lzaW9uLCByZWNhbGwsIEYxIHNjb3JlLCBST0MgYW5kIEFVQywgZXRjLikgYW5kIHdoeSB0aGV5IHdlcmUgY2hvc2VuLg0KDQoqICoqU3RhdGlzdGljYWwgU2lnbmlmaWNhbmNlKio6IEhpZ2hsaWdodCBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2UsIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLCBhbmQgZWZmZWN0IHNpemVzIHRvIHByb3ZpZGUgY29udGV4dCBmb3IgdGhlIHJlc3VsdHMuDQoNCg0KKio3LiBBZGRyZXNzIEV0aGljYWwgQ29uc2lkZXJhdGlvbnMqKg0KDQpFdGhpY3MgYXJlIGFuIGludGVncmFsIHBhcnQgb2Ygc3RhdGlzdGljcyBhbmQgZGF0YSBzY2llbmNlIHJlcG9ydGluZy4NCg0KKiAqKkJpYXMgYW5kIEZhaXJuZXNzKio6IERpc2N1c3MgcG90ZW50aWFsIGJpYXNlcyBpbiB0aGUgZGF0YSBvciBtZXRob2RzIGFuZCB0aGVpciBpbXBsaWNhdGlvbnMgZm9yIHRoZSByZXN1bHRzLg0KDQoqICoqUHJpdmFjeSBhbmQgQ29uc2VudCoqOiBFeHBsYWluIGhvdyBwcml2YWN5IGNvbmNlcm5zIHdlcmUgYWRkcmVzc2VkLCBpbmNsdWRpbmcgbWVhc3VyZXMgZm9yIGFub255bWl6YXRpb24gb3Igc2VjdXJlIGRhdGEgaGFuZGxpbmcuDQoNCiogKipJbXBhY3QgQW5hbHlzaXMqKjogQ29uc2lkZXIgdGhlIGJyb2FkZXIgaW1wbGljYXRpb25zIG9mIHRoZSBmaW5kaW5ncywgZXNwZWNpYWxseSBpZiB0aGV5IGluZmx1ZW5jZSBwb2xpY3kgb3IgZGVjaXNpb24tbWFraW5nLg0KDQoNCioqOC4gRm9jdXMgb24gQWN0aW9uYWJsZSBJbnNpZ2h0cyoqDQoNCkEga2V5IGdvYWwgb2YgZGF0YSBzY2llbmNlIHJlcG9ydHMgaXMgdG8gcHJvdmlkZSBpbnNpZ2h0cyB0aGF0IHN0YWtlaG9sZGVycyBjYW4gYWN0IHVwb24uDQoNCiogKipCdXNpbmVzcyBSZWxldmFuY2UqKjogUmVsYXRlIGZpbmRpbmdzIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHByb2JsZW0gb3Igb2JqZWN0aXZlcy4NCg0KKiAqKlJlY29tbWVuZGF0aW9ucyoqOiBPZmZlciBjbGVhciwgZXZpZGVuY2UtYmFzZWQgcmVjb21tZW5kYXRpb25zIGZvciBuZXh0IHN0ZXBzIG9yIGRlY2lzaW9ucy4NCg0KKiAqKkZ1dHVyZSBXb3JrKio6IFN1Z2dlc3QgYXJlYXMgZm9yIGZ1cnRoZXIgcmVzZWFyY2ggb3IgcG90ZW50aWFsIGltcHJvdmVtZW50cyBpbiBtZXRob2RvbG9neS4NCg0KDQpcDQoNCiMgV2ViLWJhc2VkIEVmZmVjdGl2ZSBQcmVzZW50YXRpb24NCg0KSW4gYW4gaW5jcmVhc2luZ2x5IGRpZ2l0YWwgd29ybGQsIHdlYi1iYXNlZCBwcmVzZW50YXRpb25zIGhhdmUgYmVjb21lIGEgY3JpdGljYWwgdG9vbCBmb3IgY29tbXVuaWNhdGlvbiwgZWR1Y2F0aW9uLCBhbmQgYnVzaW5lc3MuIFVubGlrZSB0cmFkaXRpb25hbCBmb3JtYXRzLCB3ZWItYmFzZWQgcHJlc2VudGF0aW9ucyBtdXN0IGNhdGVyIHRvIHRoZSBkeW5hbWljcyBvZiBvbmxpbmUgcGxhdGZvcm1zLCBlbnN1cmluZyB0aGV5IGVuZ2FnZSBhdWRpZW5jZXMgYW5kIGNvbnZleSBtZXNzYWdlcyBlZmZlY3RpdmVseSBpbiBhIHZpcnR1YWwgZW52aXJvbm1lbnQuIFRoaXMgZXNzYXkgb3V0bGluZXMga2V5IHByaW5jaXBsZXMgYW5kIHN0cmF0ZWdpZXMgZm9yIGRlc2lnbmluZyBlZmZlY3RpdmUgd2ViLWJhc2VkIHByZXNlbnRhdGlvbnMsIGZvY3VzaW5nIG9uIGNvbnRlbnQgc3RydWN0dXJlLCB2aXN1YWwgYXBwZWFsLCBpbnRlcmFjdGl2aXR5LCBhbmQgYWNjZXNzaWJpbGl0eS4NCg0KIyMgQ2xlYXIgYW5kIExvZ2ljYWwgU3RydWN0dXJlDQoNCkFuIGVmZmVjdGl2ZSB3ZWItYmFzZWQgcHJlc2VudGF0aW9uIGJlZ2lucyB3aXRoIGEgd2VsbC1vcmdhbml6ZWQgc3RydWN0dXJlIHRvIGd1aWRlIHRoZSBhdWRpZW5jZSB0aHJvdWdoIHRoZSBjb250ZW50IHNlYW1sZXNzbHkuDQoNCioqRGVmaW5lIE9iamVjdGl2ZXMqKjogU3RhcnQgYnkgaWRlbnRpZnlpbmcgdGhlIHB1cnBvc2Ugb2YgdGhlIHByZXNlbnRhdGlvbiBhbmQgdGhlIGtleSB0YWtlYXdheXMgZm9yIHRoZSBhdWRpZW5jZS4gVGhpcyBoZWxwcyBpbiBhbGlnbmluZyB0aGUgY29udGVudCB3aXRoIHRoZSBnb2Fscy4NCg0KKipPdXRsaW5lIHRoZSBGbG93Kio6IEFycmFuZ2Ugc2xpZGVzIGluIGEgbG9naWNhbCBzZXF1ZW5jZeKAlGJlZ2lubmluZyB3aXRoIGFuIGludHJvZHVjdGlvbiwgZm9sbG93ZWQgYnkgdGhlIG1haW4gY29udGVudCwgYW5kIGVuZGluZyB3aXRoIGEgc3Ryb25nIGNvbmNsdXNpb24gb3IgY2FsbCB0byBhY3Rpb24uDQoNCioqQ2h1bmsgSW5mb3JtYXRpb24qKjogQnJlYWsgY29tcGxleCBpbmZvcm1hdGlvbiBpbnRvIHNtYWxsZXIsIGRpZ2VzdGlibGUgc2VjdGlvbnMgdG8gbWFpbnRhaW4gdGhlIGF1ZGllbmNl4oCZcyBmb2N1cyBhbmQgYXZvaWQgY29nbml0aXZlIG92ZXJsb2FkLg0KDQpGb3IgaW5zdGFuY2UsIGEgcHJlc2VudGF0aW9uIG9uIGRhdGEgYW5hbHl0aWNzIG1pZ2h0IHN0YXJ0IHdpdGggYW4gb3ZlcnZpZXcgb2YgdGhlIGZpZWxkLCBwcm9jZWVkIHRvIG1ldGhvZHMgYW5kIHRvb2xzLCBhbmQgY29uY2x1ZGUgd2l0aCByZWFsLXdvcmxkIGFwcGxpY2F0aW9ucy4NCg0KDQojIyBWaXN1YWwgRGVzaWduIGFuZCBBZXN0aGV0aWNzDQoNClRoZSB2aXN1YWwgZGVzaWduIGFuZCBhZXN0aGV0aWNzIG9mIHByZXNlbnRhdGlvbiBzbGlkZXMgcGxheSBhIGNyaXRpY2FsIHJvbGUgaW4gY2FwdHVyaW5nIGF0dGVudGlvbiwgY29udmV5aW5nIGluZm9ybWF0aW9uIGVmZmVjdGl2ZWx5LCBhbmQgbWFpbnRhaW5pbmcgYXVkaWVuY2UgZW5nYWdlbWVudC4gR29vZCBkZXNpZ24gZW5zdXJlcyB0aGF0IHRoZSBtZXNzYWdlIGlzIG5vdCBvbmx5IGNsZWFyIGJ1dCBhbHNvIG1lbW9yYWJsZS4gVGhpcyBzdWJzZWN0aW9uIGV4cGxvcmVzIGtleSBwcmluY2lwbGVzIGFuZCBzdHJhdGVnaWVzIGZvciBhY2hpZXZpbmcgZWZmZWN0aXZlIHZpc3VhbCBkZXNpZ24gYW5kIGFlc3RoZXRpY3MgaW4gcHJlc2VudGF0aW9uIHNsaWRlcywgZW1waGFzaXppbmcgY2xhcml0eSwgY29uc2lzdGVuY3ksIGFuZCBhdWRpZW5jZS1jZW50ZXJlZCBkZXNpZ24uDQoNCioqMS4gVGhlIFJvbGUgb2YgVmlzdWFsIERlc2lnbiBpbiBQcmVzZW50YXRpb25zKioNCg0KVmlzdWFsIGRlc2lnbiBpcyBub3QganVzdCBhYm91dCBtYWtpbmcgc2xpZGVzIGxvb2sgYXBwZWFsaW5n4oCUaXQgc2VydmVzIHRvIGVuaGFuY2UgY29tbXVuaWNhdGlvbiBhbmQgdW5kZXJzdGFuZGluZy4NCg0KKiAqKkF0dHJhY3RpbmcgQXR0ZW50aW9uKio6IFdlbGwtZGVzaWduZWQgc2xpZGVzIGNhbiBpbW1lZGlhdGVseSBjYXB0dXJlIHRoZSBhdWRpZW5jZeKAmXMgaW50ZXJlc3QgYW5kIHNldCBhIHBvc2l0aXZlIHRvbmUgZm9yIHRoZSBwcmVzZW50YXRpb24uDQoNCiogKipJbXByb3ZpbmcgQ29tcHJlaGVuc2lvbioqOiBWaXN1YWwgZWxlbWVudHMgbGlrZSBjaGFydHMsIGRpYWdyYW1zLCBhbmQgY29sb3ItY29kZWQgaGlnaGxpZ2h0cyBtYWtlIGNvbXBsZXggaW5mb3JtYXRpb24gZWFzaWVyIHRvIHVuZGVyc3RhbmQuDQoNCiogKipNYWludGFpbmluZyBFbmdhZ2VtZW50Kio6IEFlc3RoZXRpYyBhbmQgZHluYW1pYyBkZXNpZ24ga2VlcHMgdGhlIGF1ZGllbmNlIGZvY3VzZWQgYW5kIHByZXZlbnRzIG1vbm90b255Lg0KUmVpbmZvcmNpbmcgTWVzc2FnaW5nOiBDb25zaXN0ZW50IGFuZCB0aG91Z2h0ZnVsIGRlc2lnbiBjaG9pY2VzIHN0cmVuZ3RoZW4gdGhlIGltcGFjdCBvZiB0aGUgcHJlc2VudGVkIG1lc3NhZ2UuDQoNCkZvciBleGFtcGxlLCBhIHByZXNlbnRhdGlvbiBvbiByZW5ld2FibGUgZW5lcmd5IGJlbmVmaXRzIGZyb20gdmlzdWFsbHkgYXBwZWFsaW5nIGdyYXBocyBhbmQgaW1hZ2VzIG9mIHdpbmQgdHVyYmluZXMgYW5kIHNvbGFyIHBhbmVscyB0byBoaWdobGlnaHQga2V5IHBvaW50cyBlZmZlY3RpdmVseS4NCg0KKioyLiBLZXkgUHJpbmNpcGxlcyBvZiBTbGlkZSBEZXNpZ24qKg0KDQpBY2hpZXZpbmcgc3Ryb25nIHZpc3VhbCBkZXNpZ24gaW52b2x2ZXMgYWRoZXJpbmcgdG8gZnVuZGFtZW50YWwgZGVzaWduIHByaW5jaXBsZXMgdGhhdCBwcmlvcml0aXplIGNsYXJpdHkgYW5kIGNvaGVyZW5jZS4NCg0KKiAqKlNpbXBsaWNpdHkqKjogS2VlcCBzbGlkZXMgY2xlYW4gYW5kIHVuY2x1dHRlcmVkLiBGb2N1cyBvbiBvbmUgbWFpbiBpZGVhIHBlciBzbGlkZSB0byBhdm9pZCBvdmVyd2hlbG1pbmcgdGhlIGF1ZGllbmNlLg0KDQoqICoqSGllcmFyY2h5Kio6IFVzZSB2aXN1YWwgaGllcmFyY2h5IHRvIGd1aWRlIHRoZSBhdWRpZW5jZeKAmXMgYXR0ZW50aW9uLiBMYXJnZXIgZm9udHMsIGJvbGQgdGV4dCwgYW5kIGNvbnRyYXN0aW5nIGNvbG9ycyBjYW4gZW1waGFzaXplIGtleSBwb2ludHMuDQoNCiogKipCYWxhbmNlKio6IEFycmFuZ2UgZWxlbWVudHMgc3ltbWV0cmljYWxseSBvciBhc3ltbWV0cmljYWxseSB0byBjcmVhdGUgaGFybW9ueSBhbmQgYXZvaWQgYSBjbHV0dGVyZWQgYXBwZWFyYW5jZS4NCg0KKiAqKkFsaWdubWVudCoqOiBBbGlnbiB0ZXh0LCBpbWFnZXMsIGFuZCBvdGhlciBlbGVtZW50cyBmb3IgYSBwb2xpc2hlZCBhbmQgcHJvZmVzc2lvbmFsIGxvb2suIE1pc2FsaWduZWQgb2JqZWN0cyBjYW4gYXBwZWFyIHVucHJvZmVzc2lvbmFsIGFuZCBkaXN0cmFjdCBmcm9tIHRoZSBtZXNzYWdlLg0KDQoqICoqQ29udHJhc3QqKjogRW5zdXJlIHN1ZmZpY2llbnQgY29udHJhc3QgYmV0d2VlbiB0ZXh0IGFuZCBiYWNrZ3JvdW5kIGNvbG9ycyB0byBlbmhhbmNlIHJlYWRhYmlsaXR5LCBlc3BlY2lhbGx5IGluIGxvdy1saWdodCBzZXR0aW5ncy4NCg0KRm9yIGluc3RhbmNlLCB1c2luZyBhIGJvbGQsIGxhcmdlIGZvbnQgZm9yIGhlYWRpbmdzIGFuZCBzbWFsbGVyLCBsaWdodGVyIHRleHQgZm9yIHN1cHBvcnRpbmcgZGV0YWlscyBjcmVhdGVzIGEgY2xlYXIgdmlzdWFsIGhpZXJhcmNoeS4NCg0KKiozLiBFZmZlY3RpdmUgVXNlIG9mIENvbG9ycyoqDQoNCkNvbG9ycyBhcmUgYSBwb3dlcmZ1bCB0b29sIGZvciBzZXR0aW5nIHRoZSB0b25lIGFuZCBlbmhhbmNpbmcgdGhlIHJlYWRhYmlsaXR5IG9mIHNsaWRlcy4NCg0KKiAqKkNvbnNpc3RlbnQgQ29sb3IgU2NoZW1lKio6IFN0aWNrIHRvIGEgbGltaXRlZCBwYWxldHRlIG9mIDLigJM0IGNvbG9ycyB0aGF0IGFsaWduIHdpdGggdGhlIHByZXNlbnRhdGlvbuKAmXMgdGhlbWUgb3IgYnJhbmQgaWRlbnRpdHkuDQoNCiogKipQdXJwb3NlZnVsIENvbG9ycyoqOiBVc2UgY29sb3JzIHRvIGVtcGhhc2l6ZSBzcGVjaWZpYyBwb2ludHMsIHN1Y2ggYXMgcmVkIGZvciB3YXJuaW5ncyBvciBncmVlbiBmb3IgcG9zaXRpdmUgb3V0Y29tZXMuDQoNCiogKipSZWFkYWJsZSBDb21iaW5hdGlvbnMqKjogQXZvaWQgbG93LWNvbnRyYXN0IGNvbWJpbmF0aW9ucyBsaWtlIGxpZ2h0IHRleHQgb24gYSBsaWdodCBiYWNrZ3JvdW5kLiBEYXJrIHRleHQgb24gYSBsaWdodCBiYWNrZ3JvdW5kIG9yIHZpY2UgdmVyc2EgaXMgZ2VuZXJhbGx5IG1vcmUgbGVnaWJsZS4NCg0KKiAqKlBzeWNob2xvZ2ljYWwgSW1wYWN0Kio6IENvbnNpZGVyIHRoZSBlbW90aW9uYWwgYW5kIHBzeWNob2xvZ2ljYWwgYXNzb2NpYXRpb25zIG9mIGNvbG9ycy4gRm9yIGV4YW1wbGUsIGJsdWUgY29udmV5cyB0cnVzdCBhbmQgcHJvZmVzc2lvbmFsaXNtLCB3aGlsZSBvcmFuZ2Ugc3VnZ2VzdHMgZW5lcmd5IGFuZCBjcmVhdGl2aXR5Lg0KDQpGb3IgZXhhbXBsZSwgYSBoZWFsdGhjYXJlIHByZXNlbnRhdGlvbiBtaWdodCB1c2UgY2FsbWluZyBibHVlcyBhbmQgd2hpdGVzIHRvIGluc3RpbGwgdHJ1c3QgYW5kIHByb2Zlc3Npb25hbGlzbS4NCg0KDQoqKjQuIExlc3MgVGV4dCwgTW9yZSBTdG9yeXRlbGxpbmcqKg0KDQpTbGlkZXMgb3ZlcmxvYWRlZCB3aXRoIHRleHQgY2FuIGRpc2VuZ2FnZSBhdWRpZW5jZXMgYW5kIG9ic2N1cmUgdGhlIGNvcmUgbWVzc2FnZS4gSW5zdGVhZCwgZW1icmFjaW5nIHN0b3J5dGVsbGluZyB3aXRoIHZpc3VhbHMgY2FuIGNyZWF0ZSBhIG1vcmUgaW1wYWN0ZnVsIGFuZCBtZW1vcmFibGUgZXhwZXJpZW5jZS4gVGhpcyBhcHByb2FjaCB0cmFuc2Zvcm1zIHNsaWRlcyBmcm9tIHN0YXRpYyByZWFkaW5nIG1hdGVyaWFsIGludG8gYSBkeW5hbWljIHRvb2wgdGhhdCBzdXBwb3J0cyB0aGUgcHJlc2VudGVy4oCZcyBuYXJyYXRpdmUsIGVuZ2FnaW5nIHRoZSBhdWRpZW5jZSBvbiBhIGRlZXBlciBlbW90aW9uYWwgYW5kIGludGVsbGVjdHVhbCBsZXZlbC4gTWluaW1pemluZyB0ZXh0IG9uIHNsaWRlcyBmb3JjZXMgdGhlIHByZXNlbnRlciB0byBlbmdhZ2UgdGhlIGF1ZGllbmNlIGRpcmVjdGx5IGFuZCBmb2N1cyBvbiBrZXkgcG9pbnRzLg0KDQoqICoqT25lIElkZWEgUGVyIFNsaWRlKio6IExpbWl0IGVhY2ggc2xpZGUgdG8gYSBzaW5nbGUgY29uY2VwdCB0byBhdm9pZCBvdmVyd2hlbG1pbmcgdGhlIGF1ZGllbmNlLg0KDQoqICoqQnVsbGV0IFBvaW50IFJlZHVjdGlvbioqOiBSZXBsYWNlIGxvbmcgbGlzdHMgb2YgYnVsbGV0IHBvaW50cyB3aXRoIHN1Y2NpbmN0IHBocmFzZXMsIHZpc3VhbHMsIG9yIGljb25zLg0KDQoqICoqUHJlc2VudGVyLUNlbnRlcmVkIERlbGl2ZXJ5Kio6IFVzZSB0aGUgc2xpZGVzIGFzIHByb21wdHMgZm9yIHNwZWFraW5nIHJhdGhlciB0aGFuIGFzIGEgc2NyaXB0Lg0KDQoNCg0KKio1LiBJbmNvcnBvcmF0aW5nIFZpc3VhbCBFbGVtZW50cyoqDQoNClZpc3VhbCBlbGVtZW50cyBsaWtlIGltYWdlcywgaWNvbnMsIGFuZCBjaGFydHMgY2FuIGVuaGFuY2Ugc2xpZGVzIGJ5IG1ha2luZyBhYnN0cmFjdCBjb25jZXB0cyB0YW5naWJsZSBhbmQgZGF0YSBtb3JlIHJlbGF0YWJsZS4NCg0KKiAqKkhpZ2gtUXVhbGl0eSBJbWFnZXMqKjogVXNlIHNoYXJwLCByZWxldmFudCBpbWFnZXMgdGhhdCBhbGlnbiB3aXRoIHRoZSBwcmVzZW50YXRpb27igJlzIHRvcGljLiBBdm9pZCBwaXhlbGF0ZWQgb3IgZ2VuZXJpYyBzdG9jayBwaG90b3MuDQoNCiogKipJbmZvZ3JhcGhpY3MgYW5kIENoYXJ0cyoqOiBVc2Ugd2VsbC1kZXNpZ25lZCBjaGFydHMgYW5kIGluZm9ncmFwaGljcyB0byBwcmVzZW50IGRhdGEgY2xlYXJseS4gU2VsZWN0IHRoZSByaWdodCB0eXBlIG9mIGNoYXJ0IChlLmcuLCBiYXIsIGxpbmUsIHBpZSkgZm9yIHRoZSBkYXRhLg0KDQoqICoqSWNvbnMqKjogQWRkIGljb25zIHRvIGlsbHVzdHJhdGUgcG9pbnRzIGFuZCBicmVhayB1cCB0ZXh0LiBVc2UgYSBjb25zaXN0ZW50IGljb24gc3R5bGUgZm9yIHZpc3VhbCBoYXJtb255Lg0KDQoqICoqV2hpdGUgU3BhY2UqKjogQWxsb3cgZm9yIHdoaXRlIHNwYWNlIGFyb3VuZCB2aXN1YWxzIHRvIHByZXZlbnQgb3ZlcmNyb3dkaW5nIGFuZCBtYWludGFpbiBhIGNsZWFuLCBvcmdhbml6ZWQgYXBwZWFyYW5jZS4NCg0KDQpGb3IgZXhhbXBsZSwgYSBmaW5hbmNpYWwgcmVwb3J0IHByZXNlbnRhdGlvbiBjb3VsZCBpbmNsdWRlIGEgbGluZSBncmFwaCBzaG93aW5nIHRyZW5kcyBvdmVyIHRpbWUsIGFjY29tcGFuaWVkIGJ5IGljb25zIHJlcHJlc2VudGluZyBrZXkgbWlsZXN0b25lcy4NCg0KKio2LiBBbmltYXRpb25zIGFuZCBUcmFuc2l0aW9ucyoqDQoNCkFuaW1hdGlvbnMgYW5kIHRyYW5zaXRpb25zIGNhbiBlbmhhbmNlIHRoZSBmbG93IG9mIGEgcHJlc2VudGF0aW9uIGJ1dCBtdXN0IGJlIHVzZWQganVkaWNpb3VzbHkuDQoNCiogKipTdWJ0bGUgQW5pbWF0aW9ucyoqOiBVc2UgYW5pbWF0aW9ucyBzcGFyaW5nbHkgdG8gZHJhdyBhdHRlbnRpb24gdG8gaW1wb3J0YW50IGVsZW1lbnRzIHdpdGhvdXQgZGlzdHJhY3RpbmcgdGhlIGF1ZGllbmNlLg0KDQoqICoqQ29uc2lzdGVudCBUcmFuc2l0aW9ucyoqOiBBcHBseSBhIHVuaWZvcm0gdHJhbnNpdGlvbiBzdHlsZSBhY3Jvc3Mgc2xpZGVzIHRvIG1haW50YWluIHZpc3VhbCBjb250aW51aXR5Lg0KDQoqICoqQXZvaWQgT3ZlcnVzZSoqOiBFeGNlc3NpdmUgb3IgZmxhc2h5IGFuaW1hdGlvbnMgY2FuIGRldHJhY3QgZnJvbSB0aGUgbWVzc2FnZSBhbmQgYXBwZWFyIHVucHJvZmVzc2lvbmFsLg0KDQoNCkZvciBpbnN0YW5jZSwgdXNpbmcgYSBmYWRlLWluIGFuaW1hdGlvbiB0byBpbnRyb2R1Y2UgYnVsbGV0IHBvaW50cyBvbmUgYnkgb25lIGhlbHBzIG1haW50YWluIGF1ZGllbmNlIGZvY3VzIHdpdGhvdXQgYmVpbmcgZGlzdHJhY3RpbmcuDQoNCioqNy4gRGVzaWduaW5nIGZvciBBY2Nlc3NpYmlsaXR5KioNCg0KQWVzdGhldGljIGRlc2lnbiBzaG91bGQgYWxzbyBhY2NvdW50IGZvciB0aGUgZGl2ZXJzZSBuZWVkcyBvZiB0aGUgYXVkaWVuY2UsIGVuc3VyaW5nIGFjY2Vzc2liaWxpdHkgZm9yIGFsbC4NCg0KKiAqKlJlYWRhYmxlIEZvbnRzKio6IENob29zZSBmb250cyB0aGF0IGFyZSBsZWdpYmxlIGZvciB2aWV3ZXJzIHdpdGggdmlzdWFsIGltcGFpcm1lbnRzLCBhdm9pZGluZyBvdmVybHkgb3JuYXRlIG9yIG5hcnJvdyB0eXBlZmFjZXMuDQoNCiogKipDb2xvcmJsaW5kLUZyaWVuZGx5IFBhbGV0dGUqKjogVXNlIGNvbG9yIGNvbWJpbmF0aW9ucyB0aGF0IGFyZSBkaXN0aW5ndWlzaGFibGUgZm9yIGluZGl2aWR1YWxzIHdpdGggY29sb3IgdmlzaW9uIGRlZmljaWVuY2llcy4NCg0KKiAqKkFsdCBUZXh0Kio6IEFkZCBhbHQgdGV4dCBkZXNjcmlwdGlvbnMgdG8gaW1hZ2VzIGZvciBhdWRpZW5jZXMgcmVseWluZyBvbiBzY3JlZW4gcmVhZGVycy4NCg0KKiAqKlJlc3BvbnNpdmUgRGVzaWduKio6IE9wdGltaXplIHNsaWRlcyBmb3IgdmFyaW91cyBkZXZpY2VzLCBlc3BlY2lhbGx5IGluIHZpcnR1YWwgcHJlc2VudGF0aW9ucyB3aGVyZSB2aWV3ZXJzIG1heSB1c2Ugc21hcnRwaG9uZXMgb3IgdGFibGV0cy4NCg0KDQpGb3IgZXhhbXBsZSwgYSBwcmVzZW50YXRpb24gb24gcHVibGljIHBvbGljeSBzaG91bGQgdXNlIGRpc3RpbmN0IHBhdHRlcm5zIG9yIGxhYmVscyBpbiBjaGFydHMgaW5zdGVhZCBvZiByZWx5aW5nIHNvbGVseSBvbiBjb2xvciBkaWZmZXJlbnRpYXRpb24uDQoNCg0KIyMgSW50ZXJhY3RpdmUgYW5kIER5bmFtaWMgRWxlbWVudHMNCg0KSW50ZXJhY3RpdmUgY29udGVudCBpbiBwcmVzZW50YXRpb24gc2xpZGVzIGNhbiBzaWduaWZpY2FudGx5IGVuaGFuY2UgYXVkaWVuY2UgZW5nYWdlbWVudCBhbmQgY29tcHJlaGVuc2lvbiBieSB0cmFuc2Zvcm1pbmcgYSBwYXNzaXZlIGV4cGVyaWVuY2UgaW50byBhbiBhY3RpdmUgb25lLiBJdCBhbGxvd3MgcHJlc2VudGVycyB0byB0YWlsb3IgdGhlIGRlbGl2ZXJ5IHRvIGF1ZGllbmNlIGludGVyZXN0cywgZm9zdGVyIHBhcnRpY2lwYXRpb24sIGFuZCBwcm92aWRlIGEgbW9yZSBkeW5hbWljIHByZXNlbnRhdGlvbi4gVG8gbWF4aW1pemUgdGhlIGVmZmVjdGl2ZW5lc3Mgb2YgaW50ZXJhY3RpdmUgY29udGVudCwgYWRoZXJlIHRvIHRoZSBmb2xsb3dpbmcgcHJpbmNpcGxlczoNCg0KKiAqKlB1cnBvc2VmdWwgSW50ZXJhY3Rpdml0eSoqOiBFbnN1cmUgZXZlcnkgaW50ZXJhY3RpdmUgZWxlbWVudCBoYXMgYSBjbGVhciBwdXJwb3NlIHRoYXQgc3VwcG9ydHMgdGhlIHByZXNlbnRhdGlvbuKAmXMgZ29hbHMuIEF2b2lkIGFkZGluZyBmZWF0dXJlcyBqdXN0IGZvciBub3ZlbHR5Lg0KDQoqICoqU2ltcGxpY2l0eSoqOiBLZWVwIGludGVyYWN0aXZlIGVsZW1lbnRzIGludHVpdGl2ZSBhbmQgZWFzeSB0byB1c2UuIE92ZXJseSBjb21wbGV4IGRlc2lnbnMgY2FuIGNvbmZ1c2UgYW5kIGRpc2VuZ2FnZSB0aGUgYXVkaWVuY2UuDQoNCiogKipUZXN0IEZ1bmN0aW9uYWxpdHkqKjogVmVyaWZ5IHRoYXQgYWxsIGludGVyYWN0aXZlIGZlYXR1cmVzIHdvcmsgYXMgaW50ZW5kZWQsIGVzcGVjaWFsbHkgd2hlbiBwcmVzZW50aW5nIG9uIHVuZmFtaWxpYXIgZXF1aXBtZW50IG9yIHBsYXRmb3Jtcy4NCg0KKiAqKkJhbGFuY2Ugd2l0aCBDb250ZW50Kio6IEludGVyYWN0aXZpdHkgc2hvdWxkIGNvbXBsZW1lbnQsIG5vdCBvdmVyc2hhZG93LCB0aGUgY29yZSBtZXNzYWdlIG9mIHRoZSBwcmVzZW50YXRpb24uDQoNCg0KIyMgQWNjZXNzaWJpbGl0eSBhbmQgSW5jbHVzaXZpdHkNCg0KRGVzaWduaW5nIHByZXNlbnRhdGlvbiBzbGlkZXMgd2l0aCBhY2Nlc3NpYmlsaXR5IGFuZCBpbmNsdXNpdml0eSBpbiBtaW5kIGVuc3VyZXMgdGhhdCBhbGwgYXVkaWVuY2UgbWVtYmVycywgcmVnYXJkbGVzcyBvZiB0aGVpciBhYmlsaXRpZXMgb3IgYmFja2dyb3VuZHMsIGNhbiBmdWxseSBlbmdhZ2Ugd2l0aCBhbmQgdW5kZXJzdGFuZCB0aGUgY29udGVudC4gVGhpcyBhcHByb2FjaCBub3Qgb25seSByZWZsZWN0cyByZXNwZWN0IGFuZCBjb25zaWRlcmF0aW9uIGJ1dCBhbHNvIGJyb2FkZW5zIHRoZSByZWFjaCBhbmQgaW1wYWN0IG9mIHRoZSBwcmVzZW50YXRpb24uDQoNCioqMS4gVGV4dCBBY2Nlc3NpYmlsaXR5KioNCg0KVGV4dCBjb250ZW50IHNob3VsZCBiZSBjbGVhciwgbGVnaWJsZSwgYW5kIHN0cnVjdHVyZWQgZm9yIGFsbCB2aWV3ZXJzLg0KDQoqICoqUmVhZGFibGUgRm9udHMqKjogVXNlIHNpbXBsZSwgc2Fucy1zZXJpZiBmb250cyBsaWtlIEFyaWFsIG9yIENhbGlicmksIGF2b2lkaW5nIGRlY29yYXRpdmUgc3R5bGVzLg0KDQoqICoqU3VmZmljaWVudCBGb250IFNpemUqKjogRW5zdXJlIHRleHQgaXMgbGFyZ2UgZW5vdWdoIHRvIGJlIHJlYWQgZnJvbSBhIGRpc3RhbmNlLCB0eXBpY2FsbHkgMjTigJMzNiBwb2ludHMgZm9yIGJvZHkgdGV4dCBhbmQgMzbigJM0NCBwb2ludHMgZm9yIGhlYWRpbmdzLg0KDQoqICoqQ29udHJhc3QqKjogVXNlIGhpZ2ggY29udHJhc3QgYmV0d2VlbiB0ZXh0IGFuZCBiYWNrZ3JvdW5kLCBzdWNoIGFzIGRhcmsgdGV4dCBvbiBhIGxpZ2h0IGJhY2tncm91bmQgb3IgdmljZSB2ZXJzYS4NCg0KKiAqKlRleHQgSGllcmFyY2h5Kio6IFVzZSBoZWFkaW5ncywgc3ViaGVhZGluZ3MsIGFuZCBidWxsZXQgcG9pbnRzIHRvIG9yZ2FuaXplIGNvbnRlbnQgbG9naWNhbGx5IGFuZCBtYWtlIGl0IHNjYW5uYWJsZS4NCg0KDQoNCioqMi4gVmlzdWFsIGFuZCBHcmFwaGljIEFjY2Vzc2liaWxpdHkqKg0KDQpJbWFnZXMsIGNoYXJ0cywgYW5kIG90aGVyIHZpc3VhbHMgc2hvdWxkIGJlIGFjY2Vzc2libGUgYW5kIGluY2x1c2l2ZS4NCg0KKiAqKkFsdCBUZXh0IGZvciBJbWFnZXMqKjogUHJvdmlkZSBhbHRlcm5hdGl2ZSB0ZXh0IGRlc2NyaXB0aW9ucyBmb3IgaW1hZ2VzIHRvIHN1cHBvcnQgYXVkaWVuY2UgbWVtYmVycyB1c2luZyBzY3JlZW4gcmVhZGVycy4NCg0KKiAqKkNvbG9yYmxpbmQtRnJpZW5kbHkgRGVzaWduKio6IEF2b2lkIHJlbHlpbmcgc29sZWx5IG9uIGNvbG9yIHRvIGNvbnZleSBpbmZvcm1hdGlvbi4gVXNlIHBhdHRlcm5zLCBsYWJlbHMsIG9yIHRleHQgYW5ub3RhdGlvbnMgaW4gZ3JhcGhzIGFuZCBjaGFydHMuDQoNCiogKipTaW1wbGUgVmlzdWFscyoqOiBBdm9pZCBvdmVybHkgY29tcGxleCBncmFwaGljcyB0aGF0IG1heSBvdmVyd2hlbG0gb3IgY29uZnVzZSB0aGUgYXVkaWVuY2UuDQpXaGl0ZSBTcGFjZTogVXNlIHN1ZmZpY2llbnQgd2hpdGUgc3BhY2UgdG8gYXZvaWQgdmlzdWFsIGNsdXR0ZXIgYW5kIG1ha2UgY29udGVudCBlYXNpZXIgdG8gZm9jdXMgb24uDQoNCg0KKiozLiBJbmNsdXNpdmUgTGFuZ3VhZ2UgYW5kIENvbnRlbnQqKg0KDQpJbmNsdXNpdml0eSBnb2VzIGJleW9uZCB0ZWNobmljYWwgZGVzaWduIHRvIGVuY29tcGFzcyB0aGUgcHJlc2VudGF0aW9u4oCZcyB0b25lIGFuZCBsYW5ndWFnZS4NCg0KKiAqKkF2b2lkIEphcmdvbioqOiBVc2UgY2xlYXIsIHN0cmFpZ2h0Zm9yd2FyZCBsYW5ndWFnZSB0byBlbnN1cmUgdGhlIGNvbnRlbnQgaXMgYWNjZXNzaWJsZSB0byBwZW9wbGUgd2l0aCB2YXJ5aW5nIGxldmVscyBvZiBleHBlcnRpc2UuDQoNCiogKipDdWx0dXJhbCBTZW5zaXRpdml0eSoqOiBBdm9pZCBpZGlvbXMsIG1ldGFwaG9ycywgb3IgcmVmZXJlbmNlcyB0aGF0IG1heSBub3QgdHJhbnNsYXRlIHdlbGwgYWNyb3NzIGN1bHR1cmVzLg0KDQoqICoqUmVwcmVzZW50YXRpb24qKjogSW5jbHVkZSBkaXZlcnNlIGV4YW1wbGVzLCBpbWFnZXMsIGFuZCBwZXJzcGVjdGl2ZXMgdG8gcmVmbGVjdCB0aGUgYXVkaWVuY2XigJlzIHZhcmllZCBiYWNrZ3JvdW5kcy4NCg0KDQpcDQoNCkluIHN1bW1hcnksIGRlc2lnbmluZyBlZmZlY3RpdmUgd2ViLWJhc2VkIHByZXNlbnRhdGlvbnMgcmVxdWlyZXMgYSB0aG91Z2h0ZnVsIGFwcHJvYWNoIHRoYXQgaW50ZWdyYXRlcyBjbGVhciBzdHJ1Y3R1cmUsIGVuZ2FnaW5nIHZpc3VhbHMsIGludGVyYWN0aXZpdHksIGFjY2Vzc2liaWxpdHksIGFuZCBwcmFjdGljYWwgZGVsaXZlcnkgc3RyYXRlZ2llcy4gQnkgZm9jdXNpbmcgb24gdGhlc2UgZWxlbWVudHMsIHByZXNlbnRlcnMgY2FuIGNyZWF0ZSBpbXBhY3RmdWwgb25saW5lIGV4cGVyaWVuY2VzIHRoYXQgcmVzb25hdGUgd2l0aCBkaXZlcnNlIGF1ZGllbmNlcy4gQXMgdmlydHVhbCBjb21tdW5pY2F0aW9uIGNvbnRpbnVlcyB0byBncm93LCBtYXN0ZXJpbmcgdGhlIGFydCBvZiB3ZWItYmFzZWQgcHJlc2VudGF0aW9uIGRlc2lnbiB3aWxsIGJlIGFuIGVzc2VudGlhbCBza2lsbCBmb3IgcHJvZmVzc2lvbmFscyBhY3Jvc3MgaW5kdXN0cmllcy4NCg0KDQoNCg0KDQoNCg==