Introduction

After describing domain ontology using a conceptual data model, commonly expressed in a UML Class Diagram, that model must be mapped to an actual representation. This lesson shows patterns and practices for mapping a UML Class Diagram to an XML representation.

The presented patterns provide a framework for expressing ontologies in a DTD for the purpose of defining an XML data store. They are best practices but much of the integrity and constraint enforcement is not possible through neither the DTD nor XML and must thus be relegated to application logic.

The use of attributes versus elements is suggestive rather than prescriptive. Other representations are possible and generally equally valid. The representational patterns shown in this lesson are based on experience and their demonstrated usefulness rather than being based on standards.

Prerequisites

This lesson presumes that you are familiar with the structure of XML and how to construct a DTD and that you can read a UML Class Diagram. The lessons below provide the necessary background:

Mapping Patterns

This section presents a series of patterns for expressing various elements of a conceptual data model in XML.

Pattern 1: Entity

A single entity has its instances represented as elements with:

  • entity name as element name
  • attributes as child elements
  • key attribute(s) as element attributes
  • references and links as attributes

Note that a DTD has no explicit data types, only PCDATA, so we cannot represent integer, date, or any other data type.

Class representing an entity
Class representing an entity

The DTD to represent an entity would look as follows for the above class.

<!DOCTYPE root [
  <!ELEMENT root (Author*)>
  <!ELEMENT Author
      (authorID,name,org,email)>
  <!ELEMENT authorID (#PCDATA)>   
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT org (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>

XML instances based on the above DTD would look as follows:

<root>
  <Author>
    <authorID>101</authorID>
    <name>Chloe Parker</name>
    <org>Northeastern University</org>
    <email>c.parker@neu.edu</email>
  </Author>
  <Author>
    <authorID>102</authorID>
    <name>Alison Chan</name>
    <org>PWC Toronto</org>
    <email>chan.alison@pwc.com</email>
  </Author>
  <!-- ... -->
</root>

Pattern 2: Optional Attribute

Entities might have attributes that are optional and may not be valid for some instances, although one might argue that this is a modeling mistake and that the optionality is better represented with a subclass.

Class representing an entity
Class representing an entity

The DTD to represent an entity would look as follows for the above class. Note the use of the ? to indicate that there are zero or one elements of org.

<!DOCTYPE root [
  <!ELEMENT root (Author*)>
  <!ELEMENT Author
      (authorID,name,org?,email)>
  <!ELEMENT authorID (#PCDATA)>   
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT org (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>

XML instances based on the above DTD would look as follows, the second of which doesn’t have a value for org. Note that at most one value for org is allowed.

<root>
  <Author>
    <authorID>101</authorID>
    <name>Chloe Parker</name>
    <org>Northeastern University</org>
    <email>c.parker@neu.edu</email>
  </Author>
  ...
  <Author>
    <authorID>102</authorID>
    <name>Alison Chan</name>
    <email>chan.alison@pwc.com</email>
  </Author>
</root>

Pattern 3: Key Attribute

Every entity should have a key attribute that uniquely identifies each instance. Key attributes should be represented as element attributes rather than child elements.

Key Attributes
Key Attributes
<!DOCTYPE root [
  <!ELEMENT root (Author*)>
  <!ELEMENT Author
      (name,org?,email)>
  <!ATTLIST Author authorID CDATA #IMPLIED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT org (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>

The key attribute is represented as an XML attribute on an element. The terminology can be confusing as an XML attribute is not the same as an entity attribute in UML or an ontology. In this example, the entity attribute authorID is represented as an XML element attribute, while the entity attribute name is represented as a child node of Author.

<root>
  <Author authorID="101">
    <name>Chloe Parker</name>
    <org>Northeastern University</org>
    <email>c.parker@neu.edu</email>
  </Author>
  <Author>
    <name>Alison Chan</name>
    <email>chan.alison@pwc.com</email>
  </Author>
  …
</root>

Pattern 4: Required Key Attribute

The tag #REQUIRED ensures that a value is provided for the attribute authorID, although since it is CDATA there is no assurance that it is unique.

Key attributes should be mandatory (required). In XML, element attributes can have the following constraints:

  • #REQUIRED – a value for the attribute must be provided
  • #FIXED – a fixed value that cannot be changed and all attributes for all element instances have that value; a value must be specified after this keyword
  • #IMPLIED – an optional attribute that may or may not be present

Note that these keywords must be in upper case and only one can be specified.

<!DOCTYPE root [
  <!ELEMENT root (Author*)>
  <!ELEMENT Author
      (name,org?,email)>
  <!ATTLIST Author authorID CDATA #REQUIRED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT org (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>
<root>
  <Author authorID="101">
    <name>Chloe Parker</name>
    <org>Northeastern University</org>
    <email>c.parker@neu.edu</email>
  </Author>
  <Author authorID="102">
    <name>Alison Chan</name>
    <email>chan.alison@pwc.com</email>
  </Author>
  …
</root>

Pattern 5: Optional Key Attribute

This pattern is not often used as key value should not be empty. Note the use of #IMPLIED instead of #REQUIRED.

<!DOCTYPE root [
  <!ELEMENT root (Author*)>
  <!ELEMENT Author
      (name,org,email)>
  <!ATTLIST Author authorID CDATA #IMPLIED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT org (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>
<root>
  <Author authorID="101">
    <name>Chloe Parker</name>
    <org>Northeastern University</org>
    <email>c.parker@neu.edu</email>
  </Author>
  <Author>
    <name>Alison Chan</name>
    <org>PWC Toronto</org>
    <email>chan.alison@pwc.com</email>
  </Author>
  …
</root>

Pattern 6: Unique Key Attribute

The value of an attribute can be either CDATA (any character string) or ID (a unique value that starts with a letter). Key attributes should be unique and it is often best to use ID rather than CDATA. However, unlike databases and UML, in XML, the value must be unique within the entire document or data store and not simply be unique for each entity type. So, while that it may often be desirable for the parser to ensure that key attributes are unique, this may not be feasible if data is exported from a database where duplicates can occur. For example, the table Author can have a primary key column value of 1001, while the table Lesson might also have a lesson with a primary key value of 1001. Not an issue in the database as the primary key values are unique within each table, but definitely an issue for XML – aside from the issue that it must start with a letter. So, to export, we would either not use XML element attributes, we would use CDATA, or we might use ID but prefix each primary key value with the table name, e.g., 1001 for an author would become the ID attribute value “author1001”.

So, to summarize, the DTD can be used to enforce uniqueness when the key attribute is represented as an XML element attribute. ID, IDREF, and ENTITY are tokenized attribute types that allow restrictions on values and enforced uniqueness rules.

The value of an ID attribute type must start with a letter.

<!DOCTYPE root [
  <!ELEMENT root (Author*)>
  <!ELEMENT Author
      (name,org?,email)>
  <!ATTLIST Author authorID ID #REQUIRED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT org (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>
<root>
  <Author authorID="author101">
    <name>Chloe Parker</name>
    <org>Northeastern University</org>
    <email>c.parker@neu.edu</email>
  </Author>
  <Author authorID="author102">
    <name>Alison Chan</name>
    <email>chan.alison@pwc.com</email>
  </Author>
  …
</root>

Pattern 7: Boolean Flags

Some elements may be empty in which case there is only a beginning and an end tag but no content. These are often used to represent Boolean (true/false) values. Empty elements can be defined using the shortcut xml <tag/>.

Boolean Flags
Boolean Flags
<!DOCTYPE root [
  <!ELEMENT root (LearningAsset*)>
  <!ELEMENT LearningAsset
      (title,difficulty,isDeployed?)>
  <!ATTLIST LearningAsset assetID ID #REQUIRED>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT difficulty (#PCDATA)>
  <!ELEMENT isDeployed EMPTY>
]>

Note the use of self-closing tags to represent a Boolean attribute. Its mere presence in the XML indicates TRUE, while its absence would then indicate FALSE.

<root>
  <LearningAsset assetID="la101">
    <title>Introduction to XML</title>
    <difficulty>easy</difficulty>
  </LearningAsset>
  <LearningAsset assetID ="la102">
    <title>Unions in C</title>
    <difficulty>intermediate</difficulty>
    <isDeployed />
  </LearningAsset>
  …
</root>

Learning Checkpoint I

Create a DTD for the XML below assuming the following “rules”:

  • There is at least one section per course but no limit
  • time and location may appear in any order and location is optional
  • courseNumber and crn are required key attributes that must be unique
  • each course may or may not run and whether it’s running should be signaled with a Boolean attribute
Learning Checkpoint I
Learning Checkpoint I

Pattern 8: One-to-One Embedded

This pattern is one of two patterns for representing a one-to-one relationship between two entities. The pattern below embeds the dependent entity within the independent entity and is preferred when one entity is “part-of” another (a “partonomy” in ontology speak).

Naturally, sharing of elements is not possible, so it is most appropriate for composition relationships and “tight” associations.

<!DOCTYPE root [
  <!ELEMENT root (Lesson*)>
  <!ELEMENT Lesson
      (timeToComplete,title,Memo)>
  <!ELEMENT timeToComplete (#PCDATA)>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT Memo (contents,attachment*)>
  <!ELEMENT contents (#PCDATA)>
  <!ELEMENT attachment (#PCDATA)>
]>

In this representation, an XML element is embedded within another.

<root>
  <Lesson>
    <timeToComplete>2.5</timeToComplete>
    <title>File System Architecture</title>
    <Memo>
      <contents>contents of memo</contents>
      <attachment>http://foo.bar.com/slides.pptx</attachment>
      <attachment>http://foo.bar.com/demo.c</attachment>
    </Memo>
  </Lesson>
  <!-- ... -->
</root>

Pattern 9: One-to-One Linked

This pattern also implements a one-to-one relationships, sich as an association, an aggregation, or a composition, but does so via linking. This is more appropriate when the linked objects are shared or both are independent entities.

Note the use of the IDREF mechanism to essentially implement a foreign key. Values used in IDREF are checked to ensure they point to a valid ID in the document at the time the XML document is read (parsed). Recall that ID values must be unique in the document rather than for a type of entity.

IDREF must have the constraint #REQUIRED or #IMPLIED (if the attribute is not mandatory which would imply that the multiplicity is 0..1 rather than 1).

<!DOCTYPE root [
  <!ELEMENT root (Lesson*, Memo*)>
  <!ELEMENT Lesson
      (timeToComplete,title)>
  <!ATTLIST Lesson lessonID ID #REQUIRED>
  <!ELEMENT timeToComplete (#PCDATA)>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT Memo (contents,attachment*)>
  <!ELEMENT contents (#PCDATA)>
  <!ELEMENT attachment (#PCDATA)>
  <!ATTLIST Memo lessonIDFK IDREF #REQUIRED>
]>
<root>
  <Lesson lessonID="lesson334">
    <timeToComplete>2.5</timeToComplete>
    <title>File System Architecture</title>
  </Lesson>
  <Lesson lessonID="lesson138">
    <timeToComplete>4.5</timeToComplete>
    <title>Ontology Design and Representation</title>
  </Lesson>
  <!-- ... -->
 <Memo lessonIDFK = "lesson334">
   <contents>
     Lorem ipsum dolor sit amet, consectetur adipiscing elit.
   </contents>
   <attachment>http://foo.bar.com/slides293.ppts</attachment>
   <attachment>http://foo.bar.com/allfiles293.zip</attachment>
  </Memo>
  <Memo lessonIDFK = "lesson138">
    <contents>
      Nam vitae ligula vehicula, imperdiet ex nec, condimentum turpis.
    </contents>
  </Memo>
</root>

Pattern 10: One-to-Many Back-Linked

This pattern is one of two that is used to represent a one-to-many relationship for an association, aggregation, or composition.

<!DOCTYPE root [
  <!ELEMENT root (LearningAsset*, Author*)>
  <!ELEMENT LearningAsset (title,difficulty,isDeployed)>
  <!ATTLIST LearningAsset assetID ID #REQUIRED>
  <!ATTLIST LearningAsset authorIDFK IDREF #REQUIRED>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT difficulty (#PCDATA)>
  <!ELEMENT isDeployed (#PCDATA)>
  <!ELEMENT Author (name,org?,email)>
  <!ATTLIST Author authorID ID #REQUIRED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT org (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>
<root>
  <LearningAsset assetID="i100" authorIDFK="a1">
    <title>Ontology Design</title>
    <difficulty>medium</difficulty>
    <isDeployed>true</isDeployed>
  </LearningAsset>
  <LearningAsset assetID="i200" authorIDFK="a1">
    <title>Relational Calculus</title>
    <difficulty>advanced</difficulty>
    <isDeployed>false</isDeployed>
  </LearningAsset>
  <!-- more LearningAsset elements -->
  <Author authorID="a1">
    <name>Cohen, W.</name>
    <email>cohen.w@learningguild.com</email>
  </Author>
  <Author authorID="a3">
    <name>Patel, P.</name>
    <email>patelp7@ufsp.edu.br</email>
  </Author>
  <!-- more Author elements -->
</root>

Pattern 11: One-to-Many Forward-Linked

This is the second of the two patterns on representing one-to-many relationships in XML. Pattern 10 was similar to how a relational database would represent a one-to-many relationship – as a foreign key. This pattern uses more of an approach that might be used in Java or other object-oriented programming languages that supports lists. Here, one entity has a list of references to the other. So, each author has a list of IDs for the lessons they authored, while Pattern 10 had the ID of the author linked to from the lesson.

<!DOCTYPE root [
  <!ELEMENT root (LearningAsset*, Author*)>
  <!ELEMENT LearningAsset (title,difficulty,isDeployed)>
  <!ATTLIST LearningAsset assetID ID #REQUIRED>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT difficulty (#PCDATA)>
  <!ELEMENT isDeployed (#PCDATA)>
  <!ELEMENT Author (name,org?,email)>
  <!ATTLIST Author authorID ID #REQUIRED>
  <!ATTLIST Author assetIDs IDREFS #IMPLIED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT org (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>
<root>
  <LearningAsset assetID="i100">
    <title>Ontology Design</title>
    <difficulty>medium</difficulty>
    <isDeployed>true</isDeployed>
  </LearningAsset>
  <LearningAsset assetID="i200">
    <title>Relational Calculus</title>
    <difficulty>advanced</difficulty>
    <isDeployed>false</isDeployed>
  </LearningAsset>
  <!-- more LearningAsset elements -->
  <Author authorID="a1" assetIDs="i100 i200">
    <name>Cohen, W.</name>
    <email>cohen.w@learningguild.com</email>
  </Author>
  <Author authorID="a3">
    <name>Patel, P.</name>
    <email>patelp7@ufsp.edu.br</email>
  </Author>
  <!-- more Author elements -->
</root>

Note that the IDREFS attribute is #IMPLIED so that there can be authors that did not author any learning assets, i.e., they do not have a reference to a learning asset.

Pattern 12: Many-to-Many Junction

This pattern implements many-to-many relationships using a junction entity similar to a junction table used in the relational model.

<!DOCTYPE root [
 <!ELEMENT root (LearningUnit+,Lesson+,Content*)>
 <!ELEMENT LearningUnit (timeToCover,title,overview)>
 <!ATTLIST LearningUnit unitID ID #REQUIRED>
 <!ELEMENT timeToCover (#PCDATA)>
 <!ELEMENT title (#PCDATA)>
 <!ELEMENT overview (#PCDATA)>
 <!ELEMENT Lesson (timeToComplete,title)>
 <!ATTLIST Lesson lessonID ID #REQUIRED>
 <!ELEMENT timeToComplete (#PCDATA)>
 <!ELEMENT Content EMPTY>
 <!ATTLIST Content lessonID IDREF #REQUIRED>
 <!ATTLIST Content unitID IDREF #REQUIRED>
]>

Note the use of a new “junction element” that maps one LearningUnit to one Lesson, similar to a junction table in a relational database. It has two primary key identifiers, one for each entity.

<root>
  <LearningUnit unitID="i100">
    <timeToCover>3.5</timeToCover>
    <title>File System Access</title>
    <overview>Lorem ipsum orem tacitum</overview>
  </LearningUnit>
  <LearningUnit unitID="i200">
    <timeToCover>2</timeToCover>
    <title>Dynamic Memory Allocation</title>
    <overview>Lorem ipsum orem tacitum</overview>
  </LearningUnit>
  <!-- more LearningUnit elements -->
  <Lesson lessonID="i1">
    <timeToComplete>30</timeToComplete>
    <title>Directories and Files</title>
  </Lesson>
  <Lesson lessonID="i2">
    <timeToComplete>20</timeToComplete>
    <title>Allocating Dynamic Buffers</title>
  </Lesson>
  <!-- more Lesson elements -->
  <Content lessonID = "i1" unitID = "i200" />
  <Content lessonID = "i2" unitID = "i200" />
  <Content lessonID = "i2" unitID = "i100" />
  <!-- ... -->
</root>

Pattern 13: Taxonomy / Repeated Attributes

This pattern represents taxonomy/generalization (inheritance) relationships. This is the first of two patterns: it assumes that the superclass is abstract and only represents the subclasses by duplicating common attributes.

<!DOCTYPE root [
  <!ELEMENT root ((SlideDeck|Video)*, Author*)>
  
  <!ELEMENT Video (title,difficulty,isDeployed,url,runTime,type,platform)>
  <!ATTLIST Video assetID ID #REQUIRED>
  <!ATTLIST Video authorIDFK IDREF #REQUIRED>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT difficulty (#PCDATA)>
  <!ELEMENT isDeployed (#PCDATA)>
  <!ELEMENT url (#PCDATA)>
  <!ELEMENT runTime (#PCDATA)>
  <!ELEMENT type (#PCDATA)>
  <!ELEMENT platform (#PCDATA)>
  
  <!ELEMENT SlideDeck (title,difficulty,isDeployed,url,fileType)>
  <!ATTLIST SlideDeck assetID ID #REQUIRED>
  <!ATTLIST SlideDeck authorIDFK IDREF #REQUIRED>
  <!ELEMENT fileType (#PCDATA)>
  
  <!ELEMENT Author (name,org?,email?)>
  <!ATTLIST Author authorID ID #REQUIRED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT org (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>

LearningAsset is an abstract class which means that there are no instances of that class and only instances of the subclasses. So, there is no LearningAsset element needed in the XML. The relationship to Author is implemented in each subclass element.

<root>
  <Video assetID = "v100" authorIDFK = "a387">
    <title>Loading XML into R</title>
    <difficulty>medium</difficulty>
    <isDeployed>true</isDeployed>
    <url>youtu.be/Hg44Xjh3</url>
    <runTime>16:23</runTime>
    <type>Tutorial</type>
    <platform>YouTube</platform>
  </Video>
  <!-- more Video elements -->
  
  <SlideDeck assetID = "s100" authorIDFK = "a387">
    <title>Information Discovery</title>
    <difficulty>easy</difficulty>
    <isDeployed>true</isDeployed>
    <url>drv.co/Hddj87za</url>
    <fileType>pptx</fileType>
  </SlideDeck>
  <!-- more SlideDeck elements -->
  
  <Author authorID = "a387">
    <name>Kerner, I.</name>
  </Author>
  <!-- more Author elements -->
</root>

Pattern 14: Taxonomy / Connected Classes

The second approach to representing generalization hierarchies (aka, taxonomies or inheritance hierarchies) is to create an instance for the super class and one for the subclass and then use a foreign key link to connect them. This is similar to the approach used for relational databases and works particularly well if the superclass is concrete rather than abstract.

<!DOCTYPE root [
  <!ELEMENT root (((LearningAsset,SlideDeck)|
                   (LearningAsset,Video))*,
                    Author*)>
  <!ELEMENT LearningAsset (title,difficulty,isDeployed)>
  <!ATTLIST LearningAsset assetID ID #REQUIRED>
  <!ATTLIST LearningAsset authorIDFK IDREF #REQUIRED>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT difficulty (#PCDATA)>
  <!ELEMENT isDeployed (#PCDATA)>
    
  <!ELEMENT Video (url,runTime,type,platform)>
  <!ATTLIST Video assetID IDREF #REQUIRED>
  <!ELEMENT url (#PCDATA)>
  <!ELEMENT runTime (#PCDATA)>
  <!ELEMENT type (#PCDATA)>
  <!ELEMENT platform (#PCDATA)>
  
  <!ELEMENT SlideDeck (url,fileType)>
  <!ATTLIST SlideDeck assetID IDREF #REQUIRED>
  <!ELEMENT fileType (#PCDATA)>
  
  <!ELEMENT Author (name,org?,email?)>
  <!ATTLIST Author authorID ID #REQUIRED>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT org (#PCDATA)>
  <!ELEMENT email (#PCDATA)>
]>

Note that the superclass and subclass elements have the same ID (primary key) so they can be connected, but in the subclass it is an IDREF that connects the subclass to the superclass.

<root>
  <LearningAsset assetID = "la100" authorIDFK = "a387">
    <title>Loading XML into R</title>
    <difficulty>medium</difficulty>
    <isDeployed>true</isDeployed>
  </LearningAsset>
  <Video assetID = "la100">
    <url>youtu.be/Hg44Xjh3</url>
    <runTime>16:23</runTime>
    <type>Tutorial</type>
    <platform>YouTube</platform>
  </Video>
  <!-- more Video elements -->
  
  <LearningAsset assetID = "la102" authorIDFK = "a387">
    <title>Information Discovery</title>
    <difficulty>easy</difficulty>
    <isDeployed>true</isDeployed>    
  </LearningAsset>
  <SlideDeck assetID = "la102">
    <url>drv.co/Hddj87za</url>
    <fileType>pptx</fileType>
  </SlideDeck>
  <!-- more SlideDeck elements -->
  
  <Author authorID = "a387">
    <name>Kerner, I.</name>
  </Author>
  <!-- more Author elements -->
</root>

Pattern 15: Value Set with Default Value

This final pattern implements value sets or categorical attributes which draw their values from a predefined set of values. To enforce a value set (enumerated type) it must be defined as an attribute as no validation can occur for parsed character data (#PCDATA).

<!DOCTYPE root [
  <!ELEMENT root (LearningAsset*)>
  <!ELEMENT LearningAsset
      (title,isDeployed?)>
  <!ATTLIST LearningAsset assetID ID #REQUIRED>
  
  <!ATTLIST LearningAsset difficulty 
     (easy|medium|difficult) "easy">

  <!ELEMENT title (#PCDATA)>
  <!ELEMENT isDeployed EMPTY>
]>

A default value is required for a enumerated type.

<root>
  <LearningAsset assetID="la101" difficulty = "medium">
    <title>Introduction to XML</title>
  </LearningAsset>
  
  <LearningAsset assetID ="la102">
    <title>Unions in C</title>
    <isDeployed />
  </LearningAsset>
  
  <!-- ... -->
</root>

Best Practices

  1. The use of XML element attributes for elements should be restricted to: Primary keys, Foreign keys, and Value sets (categorical). All other entity attributes should be represented as child element.
  2. The use of these representational patterns is suggestive rather than prescriptive, so deviate and adjust as necessary for specify use cases.

Summary

This lesson provided numerous patterns for mapping different conceptual modeling elements to an XML representation. Many of the patterns are similar to those used in mapping conceptual data models to relational models.

Tutorial I: Mapping to XML

In this video tutorial, Khoury Boston’s Prof. Schedlbauer explains how to use a set of representational patterns to map a conceptual data model into an XML datastore and define its structure in a DTD.

Slide Deck: Mapping Patterns for XML

Note that the video presents an older version of the slide deck that has ID values that start with a digit, which is not correct. An ID value must start with a letter. Furthermore, an IDREF must have a #REQUIRED constraint; the slides in the video incorrectly show an IDREF without that.

While most parsers will gloss over these errors, many will not. Consequently, the XML file would not validate as the DTD is incorrect. Use tools such as http://xmlvalidation.com to help validate your XML documents and their DTD.

Tutorial II: Primary vs Foreign Keys in UML and XML

In this narrated chalk-talk, Khoury Boston’s Prof. Schedlbauer explains the difference between primary and foreign keys in UML, XML, and in general.


Files & Resources

All Files for Lesson 80.106

References

No references.

Errata

None collected yet. Let us know.

LS0tCnRpdGxlOiAiUGF0dGVybnMgZm9yIE1hcHBpbmcgT250b2xvZ2llcyB0byBYTUwiCnBhcmFtczoKICBjYXRlZ29yeTogODAKICBudW1iZXI6IDEwNgogIHRpbWU6IDQ1CiAgbGV2ZWw6IGludGVybWVkaWF0ZQogIHRhZ3M6ICJ4bWwsZHRkIgogIGRlc2NyaXB0aW9uOiAiVGhpcyBsZXNzb24gcHJlc2VudHMgYSBzZXQgb2YgcGF0dGVybnMgZm9yIG1hcHBpbmcgYQogICAgICAgICAgICAgICAgY29uY2VwdHVhbCBkYXRhIG1vZGVsIGV4cHJlc3NpbmcgYSBkb21haW4gb250b2xvZ3kgdG8KICAgICAgICAgICAgICAgIGFuIFhNTCBzdHJ1Y3R1cmUuIgpkYXRlOiAiPHNtYWxsPmByIFN5cy5EYXRlKClgPC9zbWFsbD4iCmF1dGhvcjogIjxzbWFsbD5NYXJ0aW4gU2NoZWRsYmF1ZXI8L3NtYWxsPiIKZW1haWw6ICJtLnNjaGVkbGJhdWVyQG5ldS5lZHUiCmFmZmlsaXRhdGlvbjogIk5vcnRoZWFzdGVybiBVbml2ZXJzaXR5IgpvdXRwdXQ6IAogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0aGVtZTogc3BhY2VsYWIKICAgIGhpZ2hsaWdodDogdGFuZ28KLS0tCgotLS0KdGl0bGU6ICI8c21hbGw+YHIgcGFyYW1zJGNhdGVnb3J5YC5gciBwYXJhbXMkbnVtYmVyYDwvc21hbGw+PGJyLz48c3BhbiBzdHlsZT0nY29sb3I6ICMyRTQwNTM7IGZvbnQtc2l6ZTogMC45ZW0nPmByIHJtYXJrZG93bjo6bWV0YWRhdGEkdGl0bGVgPC9zcGFuPiIKLS0tCgpgYGB7ciBjb2RlPXhmdW46OnJlYWRfdXRmOChwYXN0ZTAoaGVyZTo6aGVyZSgpLCcvUi9faW5zZXJ0MkRCLlInKSksIGluY2x1ZGUgPSBGQUxTRX0KYGBgCgpgYGB7ciBlY2hvPUYsIGluY2x1ZGU9Rn0KbGlicmFyeShYTUwpCmBgYAoKIyMgSW50cm9kdWN0aW9uCgpBZnRlciBkZXNjcmliaW5nIGRvbWFpbiBvbnRvbG9neSB1c2luZyBhIGNvbmNlcHR1YWwgZGF0YSBtb2RlbCwgY29tbW9ubHkgZXhwcmVzc2VkIGluIGEgVU1MIENsYXNzIERpYWdyYW0sIHRoYXQgbW9kZWwgbXVzdCBiZSBtYXBwZWQgdG8gYW4gYWN0dWFsIHJlcHJlc2VudGF0aW9uLiBUaGlzIGxlc3NvbiBzaG93cyBwYXR0ZXJucyBhbmQgcHJhY3RpY2VzIGZvciBtYXBwaW5nIGEgVU1MIENsYXNzIERpYWdyYW0gdG8gYW4gWE1MIHJlcHJlc2VudGF0aW9uLgoKVGhlIHByZXNlbnRlZCBwYXR0ZXJucyBwcm92aWRlIGEgZnJhbWV3b3JrIGZvciBleHByZXNzaW5nIG9udG9sb2dpZXMgaW4gYSBEVEQgZm9yIHRoZSBwdXJwb3NlIG9mIGRlZmluaW5nIGFuIFhNTCBkYXRhIHN0b3JlLiBUaGV5IGFyZSBiZXN0IHByYWN0aWNlcyBidXQgbXVjaCBvZiB0aGUgaW50ZWdyaXR5IGFuZCBjb25zdHJhaW50IGVuZm9yY2VtZW50IGlzIG5vdCBwb3NzaWJsZSB0aHJvdWdoIG5laXRoZXIgdGhlIERURCBub3IgWE1MIGFuZCBtdXN0IHRodXMgYmUgcmVsZWdhdGVkIHRvIGFwcGxpY2F0aW9uIGxvZ2ljLgoKVGhlIHVzZSBvZiBhdHRyaWJ1dGVzIHZlcnN1cyBlbGVtZW50cyBpcyBzdWdnZXN0aXZlIHJhdGhlciB0aGFuIHByZXNjcmlwdGl2ZS4gT3RoZXIgcmVwcmVzZW50YXRpb25zIGFyZSBwb3NzaWJsZSBhbmQgZ2VuZXJhbGx5IGVxdWFsbHkgdmFsaWQuIFRoZSByZXByZXNlbnRhdGlvbmFsIHBhdHRlcm5zIHNob3duIGluIHRoaXMgbGVzc29uIGFyZSBiYXNlZCBvbiBleHBlcmllbmNlIGFuZCB0aGVpciBkZW1vbnN0cmF0ZWQgdXNlZnVsbmVzcyByYXRoZXIgdGhhbiBiZWluZyBiYXNlZCBvbiBzdGFuZGFyZHMuCgojIyBQcmVyZXF1aXNpdGVzCgpUaGlzIGxlc3NvbiBwcmVzdW1lcyB0aGF0IHlvdSBhcmUgZmFtaWxpYXIgd2l0aCB0aGUgc3RydWN0dXJlIG9mIFhNTCBhbmQgaG93IHRvIGNvbnN0cnVjdCBhIERURCBhbmQgdGhhdCB5b3UgY2FuIHJlYWQgYSBVTUwgQ2xhc3MgRGlhZ3JhbS4gVGhlIGxlc3NvbnMgYmVsb3cgcHJvdmlkZSB0aGUgbmVjZXNzYXJ5IGJhY2tncm91bmQ6CgotICAgWzgwLjEwMSBCYXNpY3Mgb2YgWE1MIGFuZCBEVERdKGh0dHA6Ly9hcnRpZmljaXVtLnVzL2xlc3NvbnMvODAueG1sL2wtODAtMTAxLWJhc2ljLXhtbC9sLTgwLTEwMS5odG1sKQotICAgWzMwLjE1MiBEb21haW4gTW9kZWxpbmcgd2l0aCBVTUwgQ2xhc3MgRGlhZ3JhbXNdKGh0dHA6Ly9hcnRpZmljaXVtLnVzL2xlc3NvbnMvMzAudmlzbW9kZWxpbmcvbC0zMC0xNTItdW1sLWNsYXNzLWRpYWdzL2wtMzAtMTUyLmh0bWwpCgojIyBNYXBwaW5nIFBhdHRlcm5zCgpUaGlzIHNlY3Rpb24gcHJlc2VudHMgYSBzZXJpZXMgb2YgcGF0dGVybnMgZm9yIGV4cHJlc3NpbmcgdmFyaW91cyBlbGVtZW50cyBvZiBhIGNvbmNlcHR1YWwgZGF0YSBtb2RlbCBpbiBYTUwuCgojIyBQYXR0ZXJuIDE6IEVudGl0eQoKQSBzaW5nbGUgZW50aXR5IGhhcyBpdHMgaW5zdGFuY2VzIHJlcHJlc2VudGVkIGFzIGVsZW1lbnRzIHdpdGg6CgotICAgZW50aXR5IG5hbWUgYXMgZWxlbWVudCBuYW1lCi0gICBhdHRyaWJ1dGVzIGFzIGNoaWxkIGVsZW1lbnRzCi0gICBrZXkgYXR0cmlidXRlKHMpIGFzIGVsZW1lbnQgYXR0cmlidXRlcwotICAgcmVmZXJlbmNlcyBhbmQgbGlua3MgYXMgYXR0cmlidXRlcwoKTm90ZSB0aGF0IGEgRFREIGhhcyBubyBleHBsaWNpdCBkYXRhIHR5cGVzLCBvbmx5ICpQQ0RBVEEqLCBzbyB3ZSBjYW5ub3QgcmVwcmVzZW50ICppbnRlZ2VyKiwgKmRhdGUqLCBvciBhbnkgb3RoZXIgZGF0YSB0eXBlLgoKIVtDbGFzcyByZXByZXNlbnRpbmcgYW4gZW50aXR5XShwYXR0ZXJuLTEtZW50aXR5LmpwZyl7d2lkdGg9IjUwJSJ9CgpUaGUgRFREIHRvIHJlcHJlc2VudCBhbiBlbnRpdHkgd291bGQgbG9vayBhcyBmb2xsb3dzIGZvciB0aGUgYWJvdmUgY2xhc3MuCgpgYGB7ciBlY2hvPUYsIGluY2x1ZGU9Rn0KeG1sRE9NIDwtIHhtbFBhcnNlKCJ4bWwvZW50aXR5LnhtbCIsIHZhbGlkYXRlPVQpCmBgYAoKYGBgIHhtbAo8IURPQ1RZUEUgcm9vdCBbCiAgPCFFTEVNRU5UIHJvb3QgKEF1dGhvciopPgogIDwhRUxFTUVOVCBBdXRob3IKICAgICAgKGF1dGhvcklELG5hbWUsb3JnLGVtYWlsKT4KICA8IUVMRU1FTlQgYXV0aG9ySUQgKCNQQ0RBVEEpPiAgIAogIDwhRUxFTUVOVCBuYW1lICgjUENEQVRBKT4KICA8IUVMRU1FTlQgb3JnICgjUENEQVRBKT4KICA8IUVMRU1FTlQgZW1haWwgKCNQQ0RBVEEpPgpdPgpgYGAKClhNTCBpbnN0YW5jZXMgYmFzZWQgb24gdGhlIGFib3ZlIERURCB3b3VsZCBsb29rIGFzIGZvbGxvd3M6CgpgYGAgeG1sCjxyb290PgogIDxBdXRob3I+CiAgICA8YXV0aG9ySUQ+MTAxPC9hdXRob3JJRD4KICAgIDxuYW1lPkNobG9lIFBhcmtlcjwvbmFtZT4KICAgIDxvcmc+Tm9ydGhlYXN0ZXJuIFVuaXZlcnNpdHk8L29yZz4KICAgIDxlbWFpbD5jLnBhcmtlckBuZXUuZWR1PC9lbWFpbD4KICA8L0F1dGhvcj4KICA8QXV0aG9yPgogICAgPGF1dGhvcklEPjEwMjwvYXV0aG9ySUQ+CiAgICA8bmFtZT5BbGlzb24gQ2hhbjwvbmFtZT4KICAgIDxvcmc+UFdDIFRvcm9udG88L29yZz4KICAgIDxlbWFpbD5jaGFuLmFsaXNvbkBwd2MuY29tPC9lbWFpbD4KICA8L0F1dGhvcj4KICA8IS0tIC4uLiAtLT4KPC9yb290PgpgYGAKCiMjIFBhdHRlcm4gMjogT3B0aW9uYWwgQXR0cmlidXRlCgpFbnRpdGllcyBtaWdodCBoYXZlIGF0dHJpYnV0ZXMgdGhhdCBhcmUgb3B0aW9uYWwgYW5kIG1heSBub3QgYmUgdmFsaWQgZm9yIHNvbWUgaW5zdGFuY2VzLCBhbHRob3VnaCBvbmUgbWlnaHQgYXJndWUgdGhhdCB0aGlzIGlzIGEgbW9kZWxpbmcgbWlzdGFrZSBhbmQgdGhhdCB0aGUgb3B0aW9uYWxpdHkgaXMgYmV0dGVyIHJlcHJlc2VudGVkIHdpdGggYSBzdWJjbGFzcy4KCiFbQ2xhc3MgcmVwcmVzZW50aW5nIGFuIGVudGl0eV0ocGF0dGVybi0yLW9wdGlvbmFsLWF0dHJpYnV0ZS5qcGcpe3dpZHRoPSI1MCUifQoKVGhlIERURCB0byByZXByZXNlbnQgYW4gZW50aXR5IHdvdWxkIGxvb2sgYXMgZm9sbG93cyBmb3IgdGhlIGFib3ZlIGNsYXNzLiBOb3RlIHRoZSB1c2Ugb2YgdGhlICo/KiB0byBpbmRpY2F0ZSB0aGF0IHRoZXJlIGFyZSB6ZXJvIG9yIG9uZSBlbGVtZW50cyBvZiAqb3JnKi4KCmBgYHtyIGVjaG89RiwgaW5jbHVkZT1GfQp4bWxET00gPC0geG1sUGFyc2UoInhtbC9vcHRpb25hbGF0dHJpYnV0ZS54bWwiLCB2YWxpZGF0ZT1UKQpgYGAKCmBgYCB4bWwKPCFET0NUWVBFIHJvb3QgWwogIDwhRUxFTUVOVCByb290IChBdXRob3IqKT4KICA8IUVMRU1FTlQgQXV0aG9yCiAgICAgIChhdXRob3JJRCxuYW1lLG9yZz8sZW1haWwpPgogIDwhRUxFTUVOVCBhdXRob3JJRCAoI1BDREFUQSk+ICAgCiAgPCFFTEVNRU5UIG5hbWUgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBvcmcgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBlbWFpbCAoI1BDREFUQSk+Cl0+CmBgYAoKWE1MIGluc3RhbmNlcyBiYXNlZCBvbiB0aGUgYWJvdmUgRFREIHdvdWxkIGxvb2sgYXMgZm9sbG93cywgdGhlIHNlY29uZCBvZiB3aGljaCBkb2Vzbid0IGhhdmUgYSB2YWx1ZSBmb3IgKm9yZyouIE5vdGUgdGhhdCBhdCBtb3N0IG9uZSB2YWx1ZSBmb3IgKm9yZyogaXMgYWxsb3dlZC4KCmBgYCB4bWwKPHJvb3Q+CiAgPEF1dGhvcj4KICAgIDxhdXRob3JJRD4xMDE8L2F1dGhvcklEPgogICAgPG5hbWU+Q2hsb2UgUGFya2VyPC9uYW1lPgogICAgPG9yZz5Ob3J0aGVhc3Rlcm4gVW5pdmVyc2l0eTwvb3JnPgogICAgPGVtYWlsPmMucGFya2VyQG5ldS5lZHU8L2VtYWlsPgogIDwvQXV0aG9yPgogIC4uLgogIDxBdXRob3I+CiAgICA8YXV0aG9ySUQ+MTAyPC9hdXRob3JJRD4KICAgIDxuYW1lPkFsaXNvbiBDaGFuPC9uYW1lPgogICAgPGVtYWlsPmNoYW4uYWxpc29uQHB3Yy5jb208L2VtYWlsPgogIDwvQXV0aG9yPgo8L3Jvb3Q+CmBgYAoKIyMgUGF0dGVybiAzOiBLZXkgQXR0cmlidXRlCgpFdmVyeSBlbnRpdHkgc2hvdWxkIGhhdmUgYSBrZXkgYXR0cmlidXRlIHRoYXQgdW5pcXVlbHkgaWRlbnRpZmllcyBlYWNoIGluc3RhbmNlLiBLZXkgYXR0cmlidXRlcyBzaG91bGQgYmUgcmVwcmVzZW50ZWQgYXMgZWxlbWVudCBhdHRyaWJ1dGVzIHJhdGhlciB0aGFuIGNoaWxkIGVsZW1lbnRzLgoKYGBge3IgZWNobz1GLCBpbmNsdWRlPUZ9CnhtbERPTSA8LSB4bWxQYXJzZSgieG1sL2tleWF0dHJpYnV0ZS54bWwiLCB2YWxpZGF0ZT1UKQpgYGAKCiFbS2V5IEF0dHJpYnV0ZXNdKHBhdHRlcm4tMy1rZXktYXR0cmlidXRlLmpwZyl7d2lkdGg9IjUwJSJ9CgpgYGAgeG1sCjwhRE9DVFlQRSByb290IFsKICA8IUVMRU1FTlQgcm9vdCAoQXV0aG9yKik+CiAgPCFFTEVNRU5UIEF1dGhvcgogICAgICAobmFtZSxvcmc/LGVtYWlsKT4KICA8IUFUVExJU1QgQXV0aG9yIGF1dGhvcklEIENEQVRBICNJTVBMSUVEPgogIDwhRUxFTUVOVCBuYW1lICgjUENEQVRBKT4KICA8IUVMRU1FTlQgb3JnICgjUENEQVRBKT4KICA8IUVMRU1FTlQgZW1haWwgKCNQQ0RBVEEpPgpdPgpgYGAKClRoZSBrZXkgYXR0cmlidXRlIGlzIHJlcHJlc2VudGVkIGFzIGFuIFhNTCBhdHRyaWJ1dGUgb24gYW4gZWxlbWVudC4gVGhlIHRlcm1pbm9sb2d5IGNhbiBiZSBjb25mdXNpbmcgYXMgYW4gWE1MIGF0dHJpYnV0ZSBpcyBub3QgdGhlIHNhbWUgYXMgYW4gZW50aXR5IGF0dHJpYnV0ZSBpbiBVTUwgb3IgYW4gb250b2xvZ3kuIEluIHRoaXMgZXhhbXBsZSwgdGhlIGVudGl0eSBhdHRyaWJ1dGUgKmF1dGhvcklEKiBpcyByZXByZXNlbnRlZCBhcyBhbiBYTUwgZWxlbWVudCBhdHRyaWJ1dGUsIHdoaWxlIHRoZSBlbnRpdHkgYXR0cmlidXRlICpuYW1lKiBpcyByZXByZXNlbnRlZCBhcyBhIGNoaWxkIG5vZGUgb2YgKkF1dGhvciouCgpgYGAgeG1sCjxyb290PgogIDxBdXRob3IgYXV0aG9ySUQ9IjEwMSI+CiAgICA8bmFtZT5DaGxvZSBQYXJrZXI8L25hbWU+CiAgICA8b3JnPk5vcnRoZWFzdGVybiBVbml2ZXJzaXR5PC9vcmc+CiAgICA8ZW1haWw+Yy5wYXJrZXJAbmV1LmVkdTwvZW1haWw+CiAgPC9BdXRob3I+CiAgPEF1dGhvcj4KICAgIDxuYW1lPkFsaXNvbiBDaGFuPC9uYW1lPgogICAgPGVtYWlsPmNoYW4uYWxpc29uQHB3Yy5jb208L2VtYWlsPgogIDwvQXV0aG9yPgogIOKApgo8L3Jvb3Q+CmBgYAoKIyMgUGF0dGVybiA0OiBSZXF1aXJlZCBLZXkgQXR0cmlidXRlCgpUaGUgdGFnICojUkVRVUlSRUQqIGVuc3VyZXMgdGhhdCBhIHZhbHVlIGlzIHByb3ZpZGVkIGZvciB0aGUgYXR0cmlidXRlICphdXRob3JJRCosIGFsdGhvdWdoIHNpbmNlIGl0IGlzICpDREFUQSogdGhlcmUgaXMgbm8gYXNzdXJhbmNlIHRoYXQgaXQgaXMgdW5pcXVlLgoKS2V5IGF0dHJpYnV0ZXMgc2hvdWxkIGJlIG1hbmRhdG9yeSAocmVxdWlyZWQpLiBJbiBYTUwsIGVsZW1lbnQgYXR0cmlidXRlcyBjYW4gaGF2ZSB0aGUgZm9sbG93aW5nIGNvbnN0cmFpbnRzOgoKLSAgICojUkVRVUlSRUQqIC0tIGEgdmFsdWUgZm9yIHRoZSBhdHRyaWJ1dGUgbXVzdCBiZSBwcm92aWRlZAotICAgKiNGSVhFRCogLS0gYSBmaXhlZCB2YWx1ZSB0aGF0IGNhbm5vdCBiZSBjaGFuZ2VkIGFuZCBhbGwgYXR0cmlidXRlcyBmb3IgYWxsIGVsZW1lbnQgaW5zdGFuY2VzIGhhdmUgdGhhdCB2YWx1ZTsgYSB2YWx1ZSBtdXN0IGJlIHNwZWNpZmllZCBhZnRlciB0aGlzIGtleXdvcmQKLSAgICojSU1QTElFRCogLS0gYW4gb3B0aW9uYWwgYXR0cmlidXRlIHRoYXQgbWF5IG9yIG1heSBub3QgYmUgcHJlc2VudAoKTm90ZSB0aGF0IHRoZXNlIGtleXdvcmRzIG11c3QgYmUgaW4gdXBwZXIgY2FzZSBhbmQgb25seSBvbmUgY2FuIGJlIHNwZWNpZmllZC4KCmBgYCB4bWwKPCFET0NUWVBFIHJvb3QgWwogIDwhRUxFTUVOVCByb290IChBdXRob3IqKT4KICA8IUVMRU1FTlQgQXV0aG9yCiAgICAgIChuYW1lLG9yZz8sZW1haWwpPgogIDwhQVRUTElTVCBBdXRob3IgYXV0aG9ySUQgQ0RBVEEgI1JFUVVJUkVEPgogIDwhRUxFTUVOVCBuYW1lICgjUENEQVRBKT4KICA8IUVMRU1FTlQgb3JnICgjUENEQVRBKT4KICA8IUVMRU1FTlQgZW1haWwgKCNQQ0RBVEEpPgpdPgpgYGAKCmBgYCB4bWwKPHJvb3Q+CiAgPEF1dGhvciBhdXRob3JJRD0iMTAxIj4KICAgIDxuYW1lPkNobG9lIFBhcmtlcjwvbmFtZT4KICAgIDxvcmc+Tm9ydGhlYXN0ZXJuIFVuaXZlcnNpdHk8L29yZz4KICAgIDxlbWFpbD5jLnBhcmtlckBuZXUuZWR1PC9lbWFpbD4KICA8L0F1dGhvcj4KICA8QXV0aG9yIGF1dGhvcklEPSIxMDIiPgogICAgPG5hbWU+QWxpc29uIENoYW48L25hbWU+CiAgICA8ZW1haWw+Y2hhbi5hbGlzb25AcHdjLmNvbTwvZW1haWw+CiAgPC9BdXRob3I+CiAg4oCmCjwvcm9vdD4KYGBgCgojIyBQYXR0ZXJuIDU6IE9wdGlvbmFsIEtleSBBdHRyaWJ1dGUKClRoaXMgcGF0dGVybiBpcyBub3Qgb2Z0ZW4gdXNlZCBhcyBrZXkgdmFsdWUgc2hvdWxkIG5vdCBiZSBlbXB0eS4gTm90ZSB0aGUgdXNlIG9mICojSU1QTElFRCogaW5zdGVhZCBvZiAqI1JFUVVJUkVEKi4KCmBgYCB4bWwKPCFET0NUWVBFIHJvb3QgWwogIDwhRUxFTUVOVCByb290IChBdXRob3IqKT4KICA8IUVMRU1FTlQgQXV0aG9yCiAgICAgIChuYW1lLG9yZyxlbWFpbCk+CiAgPCFBVFRMSVNUIEF1dGhvciBhdXRob3JJRCBDREFUQSAjSU1QTElFRD4KICA8IUVMRU1FTlQgbmFtZSAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIG9yZyAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIGVtYWlsICgjUENEQVRBKT4KXT4KYGBgCgpgYGAgeG1sCjxyb290PgogIDxBdXRob3IgYXV0aG9ySUQ9IjEwMSI+CiAgICA8bmFtZT5DaGxvZSBQYXJrZXI8L25hbWU+CiAgICA8b3JnPk5vcnRoZWFzdGVybiBVbml2ZXJzaXR5PC9vcmc+CiAgICA8ZW1haWw+Yy5wYXJrZXJAbmV1LmVkdTwvZW1haWw+CiAgPC9BdXRob3I+CiAgPEF1dGhvcj4KICAgIDxuYW1lPkFsaXNvbiBDaGFuPC9uYW1lPgogICAgPG9yZz5QV0MgVG9yb250bzwvb3JnPgogICAgPGVtYWlsPmNoYW4uYWxpc29uQHB3Yy5jb208L2VtYWlsPgogIDwvQXV0aG9yPgogIOKApgo8L3Jvb3Q+CmBgYAoKIyMgUGF0dGVybiA2OiBVbmlxdWUgS2V5IEF0dHJpYnV0ZQoKVGhlIHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSBjYW4gYmUgZWl0aGVyICpDREFUQSogKGFueSBjaGFyYWN0ZXIgc3RyaW5nKSBvciAqSUQqIChhIHVuaXF1ZSB2YWx1ZSB0aGF0IHN0YXJ0cyB3aXRoIGEgbGV0dGVyKS4gS2V5IGF0dHJpYnV0ZXMgc2hvdWxkIGJlIHVuaXF1ZSBhbmQgaXQgaXMgb2Z0ZW4gYmVzdCB0byB1c2UgKklEKiByYXRoZXIgdGhhbiAqQ0RBVEEqLiBIb3dldmVyLCB1bmxpa2UgZGF0YWJhc2VzIGFuZCBVTUwsIGluIFhNTCwgdGhlIHZhbHVlIG11c3QgYmUgdW5pcXVlIHdpdGhpbiB0aGUgZW50aXJlIGRvY3VtZW50IG9yIGRhdGEgc3RvcmUgYW5kIG5vdCBzaW1wbHkgYmUgdW5pcXVlIGZvciBlYWNoIGVudGl0eSB0eXBlLiBTbywgd2hpbGUgdGhhdCBpdCBtYXkgb2Z0ZW4gYmUgZGVzaXJhYmxlIGZvciB0aGUgcGFyc2VyIHRvIGVuc3VyZSB0aGF0IGtleSBhdHRyaWJ1dGVzIGFyZSB1bmlxdWUsIHRoaXMgbWF5IG5vdCBiZSBmZWFzaWJsZSBpZiBkYXRhIGlzIGV4cG9ydGVkIGZyb20gYSBkYXRhYmFzZSB3aGVyZSBkdXBsaWNhdGVzIGNhbiBvY2N1ci4gRm9yIGV4YW1wbGUsIHRoZSB0YWJsZSAqQXV0aG9yKiBjYW4gaGF2ZSBhIHByaW1hcnkga2V5IGNvbHVtbiB2YWx1ZSBvZiAxMDAxLCB3aGlsZSB0aGUgdGFibGUgKkxlc3NvbiogbWlnaHQgYWxzbyBoYXZlIGEgbGVzc29uIHdpdGggYSBwcmltYXJ5IGtleSB2YWx1ZSBvZiAxMDAxLiBOb3QgYW4gaXNzdWUgaW4gdGhlIGRhdGFiYXNlIGFzIHRoZSBwcmltYXJ5IGtleSB2YWx1ZXMgYXJlIHVuaXF1ZSB3aXRoaW4gZWFjaCB0YWJsZSwgYnV0IGRlZmluaXRlbHkgYW4gaXNzdWUgZm9yIFhNTCAtLSBhc2lkZSBmcm9tIHRoZSBpc3N1ZSB0aGF0IGl0IG11c3Qgc3RhcnQgd2l0aCBhIGxldHRlci4gU28sIHRvIGV4cG9ydCwgd2Ugd291bGQgZWl0aGVyIG5vdCB1c2UgWE1MIGVsZW1lbnQgYXR0cmlidXRlcywgd2Ugd291bGQgdXNlICpDREFUQSosIG9yIHdlIG1pZ2h0IHVzZSAqSUQqIGJ1dCBwcmVmaXggZWFjaCBwcmltYXJ5IGtleSB2YWx1ZSB3aXRoIHRoZSB0YWJsZSBuYW1lLCAqZS5nLiosIDEwMDEgZm9yIGFuIGF1dGhvciB3b3VsZCBiZWNvbWUgdGhlICpJRCogYXR0cmlidXRlIHZhbHVlICJhdXRob3IxMDAxIi4KClNvLCB0byBzdW1tYXJpemUsIHRoZSBEVEQgY2FuIGJlIHVzZWQgdG8gZW5mb3JjZSB1bmlxdWVuZXNzIHdoZW4gdGhlIGtleSBhdHRyaWJ1dGUgaXMgcmVwcmVzZW50ZWQgYXMgYW4gWE1MIGVsZW1lbnQgYXR0cmlidXRlLiAqSUQqLCAqSURSRUYqLCBhbmQgKkVOVElUWSogYXJlIHRva2VuaXplZCBhdHRyaWJ1dGUgdHlwZXMgdGhhdCBhbGxvdyByZXN0cmljdGlvbnMgb24gdmFsdWVzIGFuZCBlbmZvcmNlZCB1bmlxdWVuZXNzIHJ1bGVzLgoKPiBUaGUgdmFsdWUgb2YgYW4gKklEKiBhdHRyaWJ1dGUgdHlwZSBtdXN0IHN0YXJ0IHdpdGggYSBsZXR0ZXIuCgpgYGB7ciBlY2hvPUYsIGluY2x1ZGU9Rn0KeG1sRE9NIDwtIHhtbFBhcnNlKCJ4bWwvaWRrZXlhdHRyaWJ1dGUueG1sIiwgdmFsaWRhdGU9VCkKYGBgCgpgYGAgeG1sCjwhRE9DVFlQRSByb290IFsKICA8IUVMRU1FTlQgcm9vdCAoQXV0aG9yKik+CiAgPCFFTEVNRU5UIEF1dGhvcgogICAgICAobmFtZSxvcmc/LGVtYWlsKT4KICA8IUFUVExJU1QgQXV0aG9yIGF1dGhvcklEIElEICNSRVFVSVJFRD4KICA8IUVMRU1FTlQgbmFtZSAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIG9yZyAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIGVtYWlsICgjUENEQVRBKT4KXT4KYGBgCgpgYGAgeG1sCjxyb290PgogIDxBdXRob3IgYXV0aG9ySUQ9ImF1dGhvcjEwMSI+CiAgICA8bmFtZT5DaGxvZSBQYXJrZXI8L25hbWU+CiAgICA8b3JnPk5vcnRoZWFzdGVybiBVbml2ZXJzaXR5PC9vcmc+CiAgICA8ZW1haWw+Yy5wYXJrZXJAbmV1LmVkdTwvZW1haWw+CiAgPC9BdXRob3I+CiAgPEF1dGhvciBhdXRob3JJRD0iYXV0aG9yMTAyIj4KICAgIDxuYW1lPkFsaXNvbiBDaGFuPC9uYW1lPgogICAgPGVtYWlsPmNoYW4uYWxpc29uQHB3Yy5jb208L2VtYWlsPgogIDwvQXV0aG9yPgogIOKApgo8L3Jvb3Q+CmBgYAoKIyMgUGF0dGVybiA3OiBCb29sZWFuIEZsYWdzCgpTb21lIGVsZW1lbnRzIG1heSBiZSBlbXB0eSBpbiB3aGljaCBjYXNlIHRoZXJlIGlzIG9ubHkgYSBiZWdpbm5pbmcgYW5kIGFuIGVuZCB0YWcgYnV0IG5vIGNvbnRlbnQuIFRoZXNlIGFyZSBvZnRlbiB1c2VkIHRvIHJlcHJlc2VudCBCb29sZWFuICh0cnVlL2ZhbHNlKSB2YWx1ZXMuIEVtcHR5IGVsZW1lbnRzIGNhbiBiZSBkZWZpbmVkIHVzaW5nIHRoZSBzaG9ydGN1dCBgeG1sIDx0YWcvPmAuCgohW0Jvb2xlYW4gRmxhZ3NdKHBhdHRlcm4tYm9vbGVhbnMuanBnKXt3aWR0aD0iNTAlIn0KCmBgYHtyIGVjaG89RiwgaW5jbHVkZT1GfQp4bWxET00gPC0geG1sUGFyc2UoInhtbC9ib29sYXR0cmlidXRlLnhtbCIsIHZhbGlkYXRlPVQpCmBgYAoKYGBgIHhtbAo8IURPQ1RZUEUgcm9vdCBbCiAgPCFFTEVNRU5UIHJvb3QgKExlYXJuaW5nQXNzZXQqKT4KICA8IUVMRU1FTlQgTGVhcm5pbmdBc3NldAogICAgICAodGl0bGUsZGlmZmljdWx0eSxpc0RlcGxveWVkPyk+CiAgPCFBVFRMSVNUIExlYXJuaW5nQXNzZXQgYXNzZXRJRCBJRCAjUkVRVUlSRUQ+CiAgPCFFTEVNRU5UIHRpdGxlICgjUENEQVRBKT4KICA8IUVMRU1FTlQgZGlmZmljdWx0eSAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIGlzRGVwbG95ZWQgRU1QVFk+Cl0+CmBgYAoKTm90ZSB0aGUgdXNlIG9mIHNlbGYtY2xvc2luZyB0YWdzIHRvIHJlcHJlc2VudCBhIEJvb2xlYW4gYXR0cmlidXRlLiBJdHMgbWVyZSBwcmVzZW5jZSBpbiB0aGUgWE1MIGluZGljYXRlcyAqVFJVRSosIHdoaWxlIGl0cyBhYnNlbmNlIHdvdWxkIHRoZW4gaW5kaWNhdGUgKkZBTFNFKi4KCmBgYCB4bWwKPHJvb3Q+CiAgPExlYXJuaW5nQXNzZXQgYXNzZXRJRD0ibGExMDEiPgogICAgPHRpdGxlPkludHJvZHVjdGlvbiB0byBYTUw8L3RpdGxlPgogICAgPGRpZmZpY3VsdHk+ZWFzeTwvZGlmZmljdWx0eT4KICA8L0xlYXJuaW5nQXNzZXQ+CiAgPExlYXJuaW5nQXNzZXQgYXNzZXRJRCA9ImxhMTAyIj4KICAgIDx0aXRsZT5VbmlvbnMgaW4gQzwvdGl0bGU+CiAgICA8ZGlmZmljdWx0eT5pbnRlcm1lZGlhdGU8L2RpZmZpY3VsdHk+CiAgICA8aXNEZXBsb3llZCAvPgogIDwvTGVhcm5pbmdBc3NldD4KICDigKYKPC9yb290PgpgYGAKCiMjIExlYXJuaW5nIENoZWNrcG9pbnQgSQoKQ3JlYXRlIGEgRFREIGZvciB0aGUgWE1MIGJlbG93IGFzc3VtaW5nIHRoZSBmb2xsb3dpbmcgInJ1bGVzIjoKCi0gICBUaGVyZSBpcyBhdCBsZWFzdCBvbmUgc2VjdGlvbiBwZXIgY291cnNlIGJ1dCBubyBsaW1pdAotICAgKnRpbWUqIGFuZCAqbG9jYXRpb24qIG1heSBhcHBlYXIgaW4gYW55IG9yZGVyIGFuZCAqbG9jYXRpb24qIGlzIG9wdGlvbmFsCi0gICAqY291cnNlTnVtYmVyKiBhbmQgKmNybiogYXJlIHJlcXVpcmVkIGtleSBhdHRyaWJ1dGVzIHRoYXQgbXVzdCBiZSB1bmlxdWUKLSAgIGVhY2ggY291cnNlIG1heSBvciBtYXkgbm90IHJ1biBhbmQgd2hldGhlciBpdCdzIHJ1bm5pbmcgc2hvdWxkIGJlIHNpZ25hbGVkIHdpdGggYSBCb29sZWFuIGF0dHJpYnV0ZQoKIVtMZWFybmluZyBDaGVja3BvaW50IEldKGxlYXJuaW5nLWNoZWNrcG9pbnQteG1sLTEuanBnKXt3aWR0aD0iNzUlIn0KCiMjIFBhdHRlcm4gODogT25lLXRvLU9uZSBFbWJlZGRlZAoKVGhpcyBwYXR0ZXJuIGlzIG9uZSBvZiB0d28gcGF0dGVybnMgZm9yIHJlcHJlc2VudGluZyBhIG9uZS10by1vbmUgcmVsYXRpb25zaGlwIGJldHdlZW4gdHdvIGVudGl0aWVzLiBUaGUgcGF0dGVybiBiZWxvdyBlbWJlZHMgdGhlIGRlcGVuZGVudCBlbnRpdHkgd2l0aGluIHRoZSBpbmRlcGVuZGVudCBlbnRpdHkgYW5kIGlzIHByZWZlcnJlZCB3aGVuIG9uZSBlbnRpdHkgaXMgInBhcnQtb2YiIGFub3RoZXIgKGEgInBhcnRvbm9teSIgaW4gb250b2xvZ3kgc3BlYWspLgoKTmF0dXJhbGx5LCBzaGFyaW5nIG9mIGVsZW1lbnRzIGlzIG5vdCBwb3NzaWJsZSwgc28gaXQgaXMgbW9zdCBhcHByb3ByaWF0ZSBmb3IgY29tcG9zaXRpb24gcmVsYXRpb25zaGlwcyBhbmQgInRpZ2h0IiBhc3NvY2lhdGlvbnMuCgohW10ocGF0dGVybnMtYXNzb2Mtb25lMm9uZS1lbWIuanBnKXt3aWR0aD0iNTAlIn0KCmBgYHtyIGVjaG89RiwgaW5jbHVkZT1GfQp4bWxET00gPC0geG1sUGFyc2UoInhtbC9vbmUyb25lZW1iZWRkZWQueG1sIiwgdmFsaWRhdGU9VCkKYGBgCgpgYGAgeG1sCjwhRE9DVFlQRSByb290IFsKICA8IUVMRU1FTlQgcm9vdCAoTGVzc29uKik+CiAgPCFFTEVNRU5UIExlc3NvbgogICAgICAodGltZVRvQ29tcGxldGUsdGl0bGUsTWVtbyk+CiAgPCFFTEVNRU5UIHRpbWVUb0NvbXBsZXRlICgjUENEQVRBKT4KICA8IUVMRU1FTlQgdGl0bGUgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBNZW1vIChjb250ZW50cyxhdHRhY2htZW50Kik+CiAgPCFFTEVNRU5UIGNvbnRlbnRzICgjUENEQVRBKT4KICA8IUVMRU1FTlQgYXR0YWNobWVudCAoI1BDREFUQSk+Cl0+CmBgYAoKSW4gdGhpcyByZXByZXNlbnRhdGlvbiwgYW4gWE1MIGVsZW1lbnQgaXMgZW1iZWRkZWQgd2l0aGluIGFub3RoZXIuCgpgYGAgeG1sCjxyb290PgogIDxMZXNzb24+CiAgICA8dGltZVRvQ29tcGxldGU+Mi41PC90aW1lVG9Db21wbGV0ZT4KICAgIDx0aXRsZT5GaWxlIFN5c3RlbSBBcmNoaXRlY3R1cmU8L3RpdGxlPgogICAgPE1lbW8+CiAgICAgIDxjb250ZW50cz5jb250ZW50cyBvZiBtZW1vPC9jb250ZW50cz4KICAgICAgPGF0dGFjaG1lbnQ+aHR0cDovL2Zvby5iYXIuY29tL3NsaWRlcy5wcHR4PC9hdHRhY2htZW50PgogICAgICA8YXR0YWNobWVudD5odHRwOi8vZm9vLmJhci5jb20vZGVtby5jPC9hdHRhY2htZW50PgogICAgPC9NZW1vPgogIDwvTGVzc29uPgogIDwhLS0gLi4uIC0tPgo8L3Jvb3Q+CmBgYAoKIyMgUGF0dGVybiA5OiBPbmUtdG8tT25lIExpbmtlZAoKVGhpcyBwYXR0ZXJuIGFsc28gaW1wbGVtZW50cyBhIG9uZS10by1vbmUgcmVsYXRpb25zaGlwcywgc2ljaCBhcyBhbiBhc3NvY2lhdGlvbiwgYW4gYWdncmVnYXRpb24sIG9yIGEgY29tcG9zaXRpb24sIGJ1dCBkb2VzIHNvIHZpYSBsaW5raW5nLiBUaGlzIGlzIG1vcmUgYXBwcm9wcmlhdGUgd2hlbiB0aGUgbGlua2VkIG9iamVjdHMgYXJlIHNoYXJlZCBvciBib3RoIGFyZSBpbmRlcGVuZGVudCBlbnRpdGllcy4KCk5vdGUgdGhlIHVzZSBvZiB0aGUgKklEUkVGKiBtZWNoYW5pc20gdG8gZXNzZW50aWFsbHkgaW1wbGVtZW50IGEgZm9yZWlnbiBrZXkuIFZhbHVlcyB1c2VkIGluICpJRFJFRiogYXJlIGNoZWNrZWQgdG8gZW5zdXJlIHRoZXkgcG9pbnQgdG8gYSB2YWxpZCAqSUQqIGluIHRoZSBkb2N1bWVudCBhdCB0aGUgdGltZSB0aGUgWE1MIGRvY3VtZW50IGlzIHJlYWQgKHBhcnNlZCkuIFJlY2FsbCB0aGF0ICpJRCogdmFsdWVzIG11c3QgYmUgdW5pcXVlIGluIHRoZSBkb2N1bWVudCByYXRoZXIgdGhhbiBmb3IgYSB0eXBlIG9mIGVudGl0eS4KCipJRFJFRiogbXVzdCBoYXZlIHRoZSBjb25zdHJhaW50ICojUkVRVUlSRUQqIG9yICojSU1QTElFRCogKGlmIHRoZSBhdHRyaWJ1dGUgaXMgbm90IG1hbmRhdG9yeSB3aGljaCB3b3VsZCBpbXBseSB0aGF0IHRoZSBtdWx0aXBsaWNpdHkgaXMgMC4uMSByYXRoZXIgdGhhbiAxKS4KCmBgYHtyIGVjaG89RiwgaW5jbHVkZT1GfQp4bWxET00gPC0geG1sUGFyc2UoInhtbC9vbmUyb25lbGlua2VkLnhtbCIsIHZhbGlkYXRlPVQpCmBgYAoKYGBgIHhtbAo8IURPQ1RZUEUgcm9vdCBbCiAgPCFFTEVNRU5UIHJvb3QgKExlc3NvbiosIE1lbW8qKT4KICA8IUVMRU1FTlQgTGVzc29uCiAgICAgICh0aW1lVG9Db21wbGV0ZSx0aXRsZSk+CiAgPCFBVFRMSVNUIExlc3NvbiBsZXNzb25JRCBJRCAjUkVRVUlSRUQ+CiAgPCFFTEVNRU5UIHRpbWVUb0NvbXBsZXRlICgjUENEQVRBKT4KICA8IUVMRU1FTlQgdGl0bGUgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBNZW1vIChjb250ZW50cyxhdHRhY2htZW50Kik+CiAgPCFFTEVNRU5UIGNvbnRlbnRzICgjUENEQVRBKT4KICA8IUVMRU1FTlQgYXR0YWNobWVudCAoI1BDREFUQSk+CiAgPCFBVFRMSVNUIE1lbW8gbGVzc29uSURGSyBJRFJFRiAjUkVRVUlSRUQ+Cl0+CmBgYAoKYGBgIHhtbAo8cm9vdD4KICA8TGVzc29uIGxlc3NvbklEPSJsZXNzb24zMzQiPgogICAgPHRpbWVUb0NvbXBsZXRlPjIuNTwvdGltZVRvQ29tcGxldGU+CiAgICA8dGl0bGU+RmlsZSBTeXN0ZW0gQXJjaGl0ZWN0dXJlPC90aXRsZT4KICA8L0xlc3Nvbj4KICA8TGVzc29uIGxlc3NvbklEPSJsZXNzb24xMzgiPgogICAgPHRpbWVUb0NvbXBsZXRlPjQuNTwvdGltZVRvQ29tcGxldGU+CiAgICA8dGl0bGU+T250b2xvZ3kgRGVzaWduIGFuZCBSZXByZXNlbnRhdGlvbjwvdGl0bGU+CiAgPC9MZXNzb24+CiAgPCEtLSAuLi4gLS0+CiA8TWVtbyBsZXNzb25JREZLID0gImxlc3NvbjMzNCI+CiAgIDxjb250ZW50cz4KICAgICBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dXIgYWRpcGlzY2luZyBlbGl0LgogICA8L2NvbnRlbnRzPgogICA8YXR0YWNobWVudD5odHRwOi8vZm9vLmJhci5jb20vc2xpZGVzMjkzLnBwdHM8L2F0dGFjaG1lbnQ+CiAgIDxhdHRhY2htZW50Pmh0dHA6Ly9mb28uYmFyLmNvbS9hbGxmaWxlczI5My56aXA8L2F0dGFjaG1lbnQ+CiAgPC9NZW1vPgogIDxNZW1vIGxlc3NvbklERksgPSAibGVzc29uMTM4Ij4KICAgIDxjb250ZW50cz4KICAgICAgTmFtIHZpdGFlIGxpZ3VsYSB2ZWhpY3VsYSwgaW1wZXJkaWV0IGV4IG5lYywgY29uZGltZW50dW0gdHVycGlzLgogICAgPC9jb250ZW50cz4KICA8L01lbW8+Cjwvcm9vdD4KYGBgCgojIyBQYXR0ZXJuIDEwOiBPbmUtdG8tTWFueSBCYWNrLUxpbmtlZAoKVGhpcyBwYXR0ZXJuIGlzIG9uZSBvZiB0d28gdGhhdCBpcyB1c2VkIHRvIHJlcHJlc2VudCBhIG9uZS10by1tYW55IHJlbGF0aW9uc2hpcCBmb3IgYW4gYXNzb2NpYXRpb24sIGFnZ3JlZ2F0aW9uLCBvciBjb21wb3NpdGlvbi4KCiFbXShwYXR0ZXJuLW9uZS10by1tYW55LmpwZyl7d2lkdGg9IjMwJSJ9CgpgYGB7ciBlY2hvPUYsIGluY2x1ZGU9Rn0KeG1sRE9NIDwtIHhtbFBhcnNlKCJ4bWwvb25lMm1hbnliYWNrbGlua2VkLnhtbCIsIHZhbGlkYXRlPVQpCmBgYAoKYGBgIHhtbAo8IURPQ1RZUEUgcm9vdCBbCiAgPCFFTEVNRU5UIHJvb3QgKExlYXJuaW5nQXNzZXQqLCBBdXRob3IqKT4KICA8IUVMRU1FTlQgTGVhcm5pbmdBc3NldCAodGl0bGUsZGlmZmljdWx0eSxpc0RlcGxveWVkKT4KICA8IUFUVExJU1QgTGVhcm5pbmdBc3NldCBhc3NldElEIElEICNSRVFVSVJFRD4KICA8IUFUVExJU1QgTGVhcm5pbmdBc3NldCBhdXRob3JJREZLIElEUkVGICNSRVFVSVJFRD4KICA8IUVMRU1FTlQgdGl0bGUgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBkaWZmaWN1bHR5ICgjUENEQVRBKT4KICA8IUVMRU1FTlQgaXNEZXBsb3llZCAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIEF1dGhvciAobmFtZSxvcmc/LGVtYWlsKT4KICA8IUFUVExJU1QgQXV0aG9yIGF1dGhvcklEIElEICNSRVFVSVJFRD4KICA8IUVMRU1FTlQgbmFtZSAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIG9yZyAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIGVtYWlsICgjUENEQVRBKT4KXT4KYGBgCgpgYGAgeG1sCjxyb290PgogIDxMZWFybmluZ0Fzc2V0IGFzc2V0SUQ9ImkxMDAiIGF1dGhvcklERks9ImExIj4KICAgIDx0aXRsZT5PbnRvbG9neSBEZXNpZ248L3RpdGxlPgogICAgPGRpZmZpY3VsdHk+bWVkaXVtPC9kaWZmaWN1bHR5PgogICAgPGlzRGVwbG95ZWQ+dHJ1ZTwvaXNEZXBsb3llZD4KICA8L0xlYXJuaW5nQXNzZXQ+CiAgPExlYXJuaW5nQXNzZXQgYXNzZXRJRD0iaTIwMCIgYXV0aG9ySURGSz0iYTEiPgogICAgPHRpdGxlPlJlbGF0aW9uYWwgQ2FsY3VsdXM8L3RpdGxlPgogICAgPGRpZmZpY3VsdHk+YWR2YW5jZWQ8L2RpZmZpY3VsdHk+CiAgICA8aXNEZXBsb3llZD5mYWxzZTwvaXNEZXBsb3llZD4KICA8L0xlYXJuaW5nQXNzZXQ+CiAgPCEtLSBtb3JlIExlYXJuaW5nQXNzZXQgZWxlbWVudHMgLS0+CiAgPEF1dGhvciBhdXRob3JJRD0iYTEiPgogICAgPG5hbWU+Q29oZW4sIFcuPC9uYW1lPgogICAgPGVtYWlsPmNvaGVuLndAbGVhcm5pbmdndWlsZC5jb208L2VtYWlsPgogIDwvQXV0aG9yPgogIDxBdXRob3IgYXV0aG9ySUQ9ImEzIj4KICAgIDxuYW1lPlBhdGVsLCBQLjwvbmFtZT4KICAgIDxlbWFpbD5wYXRlbHA3QHVmc3AuZWR1LmJyPC9lbWFpbD4KICA8L0F1dGhvcj4KICA8IS0tIG1vcmUgQXV0aG9yIGVsZW1lbnRzIC0tPgo8L3Jvb3Q+CmBgYAoKIyMgUGF0dGVybiAxMTogT25lLXRvLU1hbnkgRm9yd2FyZC1MaW5rZWQKClRoaXMgaXMgdGhlIHNlY29uZCBvZiB0aGUgdHdvIHBhdHRlcm5zIG9uIHJlcHJlc2VudGluZyBvbmUtdG8tbWFueSByZWxhdGlvbnNoaXBzIGluIFhNTC4gUGF0dGVybiAxMCB3YXMgc2ltaWxhciB0byBob3cgYSByZWxhdGlvbmFsIGRhdGFiYXNlIHdvdWxkIHJlcHJlc2VudCBhIG9uZS10by1tYW55IHJlbGF0aW9uc2hpcCAtLSBhcyBhIGZvcmVpZ24ga2V5LiBUaGlzIHBhdHRlcm4gdXNlcyBtb3JlIG9mIGFuIGFwcHJvYWNoIHRoYXQgbWlnaHQgYmUgdXNlZCBpbiBKYXZhIG9yIG90aGVyIG9iamVjdC1vcmllbnRlZCBwcm9ncmFtbWluZyBsYW5ndWFnZXMgdGhhdCBzdXBwb3J0cyBsaXN0cy4gSGVyZSwgb25lIGVudGl0eSBoYXMgYSBsaXN0IG9mIHJlZmVyZW5jZXMgdG8gdGhlIG90aGVyLiBTbywgZWFjaCBhdXRob3IgaGFzIGEgbGlzdCBvZiBJRHMgZm9yIHRoZSBsZXNzb25zIHRoZXkgYXV0aG9yZWQsIHdoaWxlIFBhdHRlcm4gMTAgaGFkIHRoZSBJRCBvZiB0aGUgYXV0aG9yIGxpbmtlZCB0byBmcm9tIHRoZSBsZXNzb24uCgpgYGB7ciBlY2hvPUYsIGluY2x1ZGU9Rn0KeG1sRE9NIDwtIHhtbFBhcnNlKCJ4bWwvb25lMm1hbnlmd2RsaW5rZWQueG1sIiwgdmFsaWRhdGU9VCkKYGBgCgpgYGAgeG1sCjwhRE9DVFlQRSByb290IFsKICA8IUVMRU1FTlQgcm9vdCAoTGVhcm5pbmdBc3NldCosIEF1dGhvciopPgogIDwhRUxFTUVOVCBMZWFybmluZ0Fzc2V0ICh0aXRsZSxkaWZmaWN1bHR5LGlzRGVwbG95ZWQpPgogIDwhQVRUTElTVCBMZWFybmluZ0Fzc2V0IGFzc2V0SUQgSUQgI1JFUVVJUkVEPgogIDwhRUxFTUVOVCB0aXRsZSAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIGRpZmZpY3VsdHkgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBpc0RlcGxveWVkICgjUENEQVRBKT4KICA8IUVMRU1FTlQgQXV0aG9yIChuYW1lLG9yZz8sZW1haWwpPgogIDwhQVRUTElTVCBBdXRob3IgYXV0aG9ySUQgSUQgI1JFUVVJUkVEPgogIDwhQVRUTElTVCBBdXRob3IgYXNzZXRJRHMgSURSRUZTICNJTVBMSUVEPgogIDwhRUxFTUVOVCBuYW1lICgjUENEQVRBKT4KICA8IUVMRU1FTlQgb3JnICgjUENEQVRBKT4KICA8IUVMRU1FTlQgZW1haWwgKCNQQ0RBVEEpPgpdPgpgYGAKCmBgYCB4bWwKPHJvb3Q+CiAgPExlYXJuaW5nQXNzZXQgYXNzZXRJRD0iaTEwMCI+CiAgICA8dGl0bGU+T250b2xvZ3kgRGVzaWduPC90aXRsZT4KICAgIDxkaWZmaWN1bHR5Pm1lZGl1bTwvZGlmZmljdWx0eT4KICAgIDxpc0RlcGxveWVkPnRydWU8L2lzRGVwbG95ZWQ+CiAgPC9MZWFybmluZ0Fzc2V0PgogIDxMZWFybmluZ0Fzc2V0IGFzc2V0SUQ9ImkyMDAiPgogICAgPHRpdGxlPlJlbGF0aW9uYWwgQ2FsY3VsdXM8L3RpdGxlPgogICAgPGRpZmZpY3VsdHk+YWR2YW5jZWQ8L2RpZmZpY3VsdHk+CiAgICA8aXNEZXBsb3llZD5mYWxzZTwvaXNEZXBsb3llZD4KICA8L0xlYXJuaW5nQXNzZXQ+CiAgPCEtLSBtb3JlIExlYXJuaW5nQXNzZXQgZWxlbWVudHMgLS0+CiAgPEF1dGhvciBhdXRob3JJRD0iYTEiIGFzc2V0SURzPSJpMTAwIGkyMDAiPgogICAgPG5hbWU+Q29oZW4sIFcuPC9uYW1lPgogICAgPGVtYWlsPmNvaGVuLndAbGVhcm5pbmdndWlsZC5jb208L2VtYWlsPgogIDwvQXV0aG9yPgogIDxBdXRob3IgYXV0aG9ySUQ9ImEzIj4KICAgIDxuYW1lPlBhdGVsLCBQLjwvbmFtZT4KICAgIDxlbWFpbD5wYXRlbHA3QHVmc3AuZWR1LmJyPC9lbWFpbD4KICA8L0F1dGhvcj4KICA8IS0tIG1vcmUgQXV0aG9yIGVsZW1lbnRzIC0tPgo8L3Jvb3Q+CmBgYAoKTm90ZSB0aGF0IHRoZSAqSURSRUZTKiBhdHRyaWJ1dGUgaXMgKiNJTVBMSUVEKiBzbyB0aGF0IHRoZXJlIGNhbiBiZSBhdXRob3JzIHRoYXQgZGlkIG5vdCBhdXRob3IgYW55IGxlYXJuaW5nIGFzc2V0cywgKmkuZS4qLCB0aGV5IGRvIG5vdCBoYXZlIGEgcmVmZXJlbmNlIHRvIGEgbGVhcm5pbmcgYXNzZXQuCgojIyBQYXR0ZXJuIDEyOiBNYW55LXRvLU1hbnkgSnVuY3Rpb24KClRoaXMgcGF0dGVybiBpbXBsZW1lbnRzIG1hbnktdG8tbWFueSByZWxhdGlvbnNoaXBzIHVzaW5nIGEganVuY3Rpb24gZW50aXR5IHNpbWlsYXIgdG8gYSBqdW5jdGlvbiB0YWJsZSB1c2VkIGluIHRoZSByZWxhdGlvbmFsIG1vZGVsLgoKIVtdKHBhdHRlcm4tbWFueS10by1tYW55LmpwZyl7d2lkdGg9IjUwJSJ9CgpgYGB7ciBlY2hvPUYsIGluY2x1ZGU9RkFMU0V9CnhtbERPTSA8LSB4bWxQYXJzZSgieG1sL21hbnkybWFueS1qdW5jdGlvbi54bWwiLCB2YWxpZGF0ZT1UKQpgYGAKCmBgYCB4bWwKPCFET0NUWVBFIHJvb3QgWwogPCFFTEVNRU5UIHJvb3QgKExlYXJuaW5nVW5pdCssTGVzc29uKyxDb250ZW50Kik+CiA8IUVMRU1FTlQgTGVhcm5pbmdVbml0ICh0aW1lVG9Db3Zlcix0aXRsZSxvdmVydmlldyk+CiA8IUFUVExJU1QgTGVhcm5pbmdVbml0IHVuaXRJRCBJRCAjUkVRVUlSRUQ+CiA8IUVMRU1FTlQgdGltZVRvQ292ZXIgKCNQQ0RBVEEpPgogPCFFTEVNRU5UIHRpdGxlICgjUENEQVRBKT4KIDwhRUxFTUVOVCBvdmVydmlldyAoI1BDREFUQSk+CiA8IUVMRU1FTlQgTGVzc29uICh0aW1lVG9Db21wbGV0ZSx0aXRsZSk+CiA8IUFUVExJU1QgTGVzc29uIGxlc3NvbklEIElEICNSRVFVSVJFRD4KIDwhRUxFTUVOVCB0aW1lVG9Db21wbGV0ZSAoI1BDREFUQSk+CiA8IUVMRU1FTlQgQ29udGVudCBFTVBUWT4KIDwhQVRUTElTVCBDb250ZW50IGxlc3NvbklEIElEUkVGICNSRVFVSVJFRD4KIDwhQVRUTElTVCBDb250ZW50IHVuaXRJRCBJRFJFRiAjUkVRVUlSRUQ+Cl0+CmBgYAoKTm90ZSB0aGUgdXNlIG9mIGEgbmV3ICJqdW5jdGlvbiBlbGVtZW50IiB0aGF0IG1hcHMgb25lICpMZWFybmluZ1VuaXQqIHRvIG9uZSAqTGVzc29uKiwgc2ltaWxhciB0byBhIGp1bmN0aW9uIHRhYmxlIGluIGEgcmVsYXRpb25hbCBkYXRhYmFzZS4gSXQgaGFzIHR3byBwcmltYXJ5IGtleSBpZGVudGlmaWVycywgb25lIGZvciBlYWNoIGVudGl0eS4KCmBgYCB4bWwKPHJvb3Q+CiAgPExlYXJuaW5nVW5pdCB1bml0SUQ9ImkxMDAiPgogICAgPHRpbWVUb0NvdmVyPjMuNTwvdGltZVRvQ292ZXI+CiAgICA8dGl0bGU+RmlsZSBTeXN0ZW0gQWNjZXNzPC90aXRsZT4KICAgIDxvdmVydmlldz5Mb3JlbSBpcHN1bSBvcmVtIHRhY2l0dW08L292ZXJ2aWV3PgogIDwvTGVhcm5pbmdVbml0PgogIDxMZWFybmluZ1VuaXQgdW5pdElEPSJpMjAwIj4KICAgIDx0aW1lVG9Db3Zlcj4yPC90aW1lVG9Db3Zlcj4KICAgIDx0aXRsZT5EeW5hbWljIE1lbW9yeSBBbGxvY2F0aW9uPC90aXRsZT4KICAgIDxvdmVydmlldz5Mb3JlbSBpcHN1bSBvcmVtIHRhY2l0dW08L292ZXJ2aWV3PgogIDwvTGVhcm5pbmdVbml0PgogIDwhLS0gbW9yZSBMZWFybmluZ1VuaXQgZWxlbWVudHMgLS0+CiAgPExlc3NvbiBsZXNzb25JRD0iaTEiPgogICAgPHRpbWVUb0NvbXBsZXRlPjMwPC90aW1lVG9Db21wbGV0ZT4KICAgIDx0aXRsZT5EaXJlY3RvcmllcyBhbmQgRmlsZXM8L3RpdGxlPgogIDwvTGVzc29uPgogIDxMZXNzb24gbGVzc29uSUQ9ImkyIj4KICAgIDx0aW1lVG9Db21wbGV0ZT4yMDwvdGltZVRvQ29tcGxldGU+CiAgICA8dGl0bGU+QWxsb2NhdGluZyBEeW5hbWljIEJ1ZmZlcnM8L3RpdGxlPgogIDwvTGVzc29uPgogIDwhLS0gbW9yZSBMZXNzb24gZWxlbWVudHMgLS0+CiAgPENvbnRlbnQgbGVzc29uSUQgPSAiaTEiIHVuaXRJRCA9ICJpMjAwIiAvPgogIDxDb250ZW50IGxlc3NvbklEID0gImkyIiB1bml0SUQgPSAiaTIwMCIgLz4KICA8Q29udGVudCBsZXNzb25JRCA9ICJpMiIgdW5pdElEID0gImkxMDAiIC8+CiAgPCEtLSAuLi4gLS0+Cjwvcm9vdD4KYGBgCgojIyBQYXR0ZXJuIDEzOiBUYXhvbm9teSAvIFJlcGVhdGVkIEF0dHJpYnV0ZXMKClRoaXMgcGF0dGVybiByZXByZXNlbnRzIHRheG9ub215L2dlbmVyYWxpemF0aW9uIChpbmhlcml0YW5jZSkgcmVsYXRpb25zaGlwcy4gVGhpcyBpcyB0aGUgZmlyc3Qgb2YgdHdvIHBhdHRlcm5zOiBpdCBhc3N1bWVzIHRoYXQgdGhlIHN1cGVyY2xhc3MgaXMgYWJzdHJhY3QgYW5kIG9ubHkgcmVwcmVzZW50cyB0aGUgc3ViY2xhc3NlcyBieSBkdXBsaWNhdGluZyBjb21tb24gYXR0cmlidXRlcy4KCiFbXShwYXR0ZXJuLWluaGVyaXRhbmNlLXJlcGVhdGVkLmpwZyl7d2lkdGg9IjUwJSJ9CgpgYGB7ciBlY2hvPUYsIGluY2x1ZGU9RkFMU0V9CnhtbERPTSA8LSB4bWxQYXJzZSgieG1sL3RheG9ub215LXJlcGVhdGVkLnhtbCIsIHZhbGlkYXRlPVQpCmBgYAoKYGBgIHhtbAo8IURPQ1RZUEUgcm9vdCBbCiAgPCFFTEVNRU5UIHJvb3QgKChTbGlkZURlY2t8VmlkZW8pKiwgQXV0aG9yKik+CiAgCiAgPCFFTEVNRU5UIFZpZGVvICh0aXRsZSxkaWZmaWN1bHR5LGlzRGVwbG95ZWQsdXJsLHJ1blRpbWUsdHlwZSxwbGF0Zm9ybSk+CiAgPCFBVFRMSVNUIFZpZGVvIGFzc2V0SUQgSUQgI1JFUVVJUkVEPgogIDwhQVRUTElTVCBWaWRlbyBhdXRob3JJREZLIElEUkVGICNSRVFVSVJFRD4KICA8IUVMRU1FTlQgdGl0bGUgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBkaWZmaWN1bHR5ICgjUENEQVRBKT4KICA8IUVMRU1FTlQgaXNEZXBsb3llZCAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIHVybCAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIHJ1blRpbWUgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCB0eXBlICgjUENEQVRBKT4KICA8IUVMRU1FTlQgcGxhdGZvcm0gKCNQQ0RBVEEpPgogIAogIDwhRUxFTUVOVCBTbGlkZURlY2sgKHRpdGxlLGRpZmZpY3VsdHksaXNEZXBsb3llZCx1cmwsZmlsZVR5cGUpPgogIDwhQVRUTElTVCBTbGlkZURlY2sgYXNzZXRJRCBJRCAjUkVRVUlSRUQ+CiAgPCFBVFRMSVNUIFNsaWRlRGVjayBhdXRob3JJREZLIElEUkVGICNSRVFVSVJFRD4KICA8IUVMRU1FTlQgZmlsZVR5cGUgKCNQQ0RBVEEpPgogIAogIDwhRUxFTUVOVCBBdXRob3IgKG5hbWUsb3JnPyxlbWFpbD8pPgogIDwhQVRUTElTVCBBdXRob3IgYXV0aG9ySUQgSUQgI1JFUVVJUkVEPgogIDwhRUxFTUVOVCBuYW1lICgjUENEQVRBKT4KICA8IUVMRU1FTlQgb3JnICgjUENEQVRBKT4KICA8IUVMRU1FTlQgZW1haWwgKCNQQ0RBVEEpPgpdPgpgYGAKCipMZWFybmluZ0Fzc2V0KiBpcyBhbiBhYnN0cmFjdCBjbGFzcyB3aGljaCBtZWFucyB0aGF0IHRoZXJlIGFyZSBubyBpbnN0YW5jZXMgb2YgdGhhdCBjbGFzcyBhbmQgb25seSBpbnN0YW5jZXMgb2YgdGhlIHN1YmNsYXNzZXMuIFNvLCB0aGVyZSBpcyBubyAqTGVhcm5pbmdBc3NldCogZWxlbWVudCBuZWVkZWQgaW4gdGhlIFhNTC4gVGhlIHJlbGF0aW9uc2hpcCB0byAqQXV0aG9yKiBpcyBpbXBsZW1lbnRlZCBpbiBlYWNoIHN1YmNsYXNzIGVsZW1lbnQuCgpgYGAgeG1sCjxyb290PgogIDxWaWRlbyBhc3NldElEID0gInYxMDAiIGF1dGhvcklERksgPSAiYTM4NyI+CiAgICA8dGl0bGU+TG9hZGluZyBYTUwgaW50byBSPC90aXRsZT4KICAgIDxkaWZmaWN1bHR5Pm1lZGl1bTwvZGlmZmljdWx0eT4KICAgIDxpc0RlcGxveWVkPnRydWU8L2lzRGVwbG95ZWQ+CiAgICA8dXJsPnlvdXR1LmJlL0hnNDRYamgzPC91cmw+CiAgICA8cnVuVGltZT4xNjoyMzwvcnVuVGltZT4KICAgIDx0eXBlPlR1dG9yaWFsPC90eXBlPgogICAgPHBsYXRmb3JtPllvdVR1YmU8L3BsYXRmb3JtPgogIDwvVmlkZW8+CiAgPCEtLSBtb3JlIFZpZGVvIGVsZW1lbnRzIC0tPgogIAogIDxTbGlkZURlY2sgYXNzZXRJRCA9ICJzMTAwIiBhdXRob3JJREZLID0gImEzODciPgogICAgPHRpdGxlPkluZm9ybWF0aW9uIERpc2NvdmVyeTwvdGl0bGU+CiAgICA8ZGlmZmljdWx0eT5lYXN5PC9kaWZmaWN1bHR5PgogICAgPGlzRGVwbG95ZWQ+dHJ1ZTwvaXNEZXBsb3llZD4KICAgIDx1cmw+ZHJ2LmNvL0hkZGo4N3phPC91cmw+CiAgICA8ZmlsZVR5cGU+cHB0eDwvZmlsZVR5cGU+CiAgPC9TbGlkZURlY2s+CiAgPCEtLSBtb3JlIFNsaWRlRGVjayBlbGVtZW50cyAtLT4KICAKICA8QXV0aG9yIGF1dGhvcklEID0gImEzODciPgogICAgPG5hbWU+S2VybmVyLCBJLjwvbmFtZT4KICA8L0F1dGhvcj4KICA8IS0tIG1vcmUgQXV0aG9yIGVsZW1lbnRzIC0tPgo8L3Jvb3Q+CmBgYAoKIyMgUGF0dGVybiAxNDogVGF4b25vbXkgLyBDb25uZWN0ZWQgQ2xhc3NlcwoKVGhlIHNlY29uZCBhcHByb2FjaCB0byByZXByZXNlbnRpbmcgZ2VuZXJhbGl6YXRpb24gaGllcmFyY2hpZXMgKCpha2EqLCB0YXhvbm9taWVzIG9yIGluaGVyaXRhbmNlIGhpZXJhcmNoaWVzKSBpcyB0byBjcmVhdGUgYW4gaW5zdGFuY2UgZm9yIHRoZSBzdXBlciBjbGFzcyBhbmQgb25lIGZvciB0aGUgc3ViY2xhc3MgYW5kIHRoZW4gdXNlIGEgZm9yZWlnbiBrZXkgbGluayB0byBjb25uZWN0IHRoZW0uIFRoaXMgaXMgc2ltaWxhciB0byB0aGUgYXBwcm9hY2ggdXNlZCBmb3IgcmVsYXRpb25hbCBkYXRhYmFzZXMgYW5kIHdvcmtzIHBhcnRpY3VsYXJseSB3ZWxsIGlmIHRoZSBzdXBlcmNsYXNzIGlzIGNvbmNyZXRlIHJhdGhlciB0aGFuIGFic3RyYWN0LgoKYGBge3IgZWNobz1GLCBpbmNsdWRlPUZBTFNFfQp4bWxET00gPC0geG1sUGFyc2UoInhtbC90YXhvbm9teS1jb25uZWN0ZWQueG1sIiwgdmFsaWRhdGU9VCkKYGBgCgpgYGAgeG1sCjwhRE9DVFlQRSByb290IFsKICA8IUVMRU1FTlQgcm9vdCAoKChMZWFybmluZ0Fzc2V0LFNsaWRlRGVjayl8CiAgICAgICAgICAgICAgICAgICAoTGVhcm5pbmdBc3NldCxWaWRlbykpKiwKICAgICAgICAgICAgICAgICAgICBBdXRob3IqKT4KICA8IUVMRU1FTlQgTGVhcm5pbmdBc3NldCAodGl0bGUsZGlmZmljdWx0eSxpc0RlcGxveWVkKT4KICA8IUFUVExJU1QgTGVhcm5pbmdBc3NldCBhc3NldElEIElEICNSRVFVSVJFRD4KICA8IUFUVExJU1QgTGVhcm5pbmdBc3NldCBhdXRob3JJREZLIElEUkVGICNSRVFVSVJFRD4KICA8IUVMRU1FTlQgdGl0bGUgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBkaWZmaWN1bHR5ICgjUENEQVRBKT4KICA8IUVMRU1FTlQgaXNEZXBsb3llZCAoI1BDREFUQSk+CiAgICAKICA8IUVMRU1FTlQgVmlkZW8gKHVybCxydW5UaW1lLHR5cGUscGxhdGZvcm0pPgogIDwhQVRUTElTVCBWaWRlbyBhc3NldElEIElEUkVGICNSRVFVSVJFRD4KICA8IUVMRU1FTlQgdXJsICgjUENEQVRBKT4KICA8IUVMRU1FTlQgcnVuVGltZSAoI1BDREFUQSk+CiAgPCFFTEVNRU5UIHR5cGUgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBwbGF0Zm9ybSAoI1BDREFUQSk+CiAgCiAgPCFFTEVNRU5UIFNsaWRlRGVjayAodXJsLGZpbGVUeXBlKT4KICA8IUFUVExJU1QgU2xpZGVEZWNrIGFzc2V0SUQgSURSRUYgI1JFUVVJUkVEPgogIDwhRUxFTUVOVCBmaWxlVHlwZSAoI1BDREFUQSk+CiAgCiAgPCFFTEVNRU5UIEF1dGhvciAobmFtZSxvcmc/LGVtYWlsPyk+CiAgPCFBVFRMSVNUIEF1dGhvciBhdXRob3JJRCBJRCAjUkVRVUlSRUQ+CiAgPCFFTEVNRU5UIG5hbWUgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBvcmcgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBlbWFpbCAoI1BDREFUQSk+Cl0+CmBgYAoKTm90ZSB0aGF0IHRoZSBzdXBlcmNsYXNzIGFuZCBzdWJjbGFzcyBlbGVtZW50cyBoYXZlIHRoZSBzYW1lICpJRCogKHByaW1hcnkga2V5KSBzbyB0aGV5IGNhbiBiZSBjb25uZWN0ZWQsIGJ1dCBpbiB0aGUgc3ViY2xhc3MgaXQgaXMgYW4gKklEUkVGKiB0aGF0IGNvbm5lY3RzIHRoZSBzdWJjbGFzcyB0byB0aGUgc3VwZXJjbGFzcy4KCmBgYCB4bWwKPHJvb3Q+CiAgPExlYXJuaW5nQXNzZXQgYXNzZXRJRCA9ICJsYTEwMCIgYXV0aG9ySURGSyA9ICJhMzg3Ij4KICAgIDx0aXRsZT5Mb2FkaW5nIFhNTCBpbnRvIFI8L3RpdGxlPgogICAgPGRpZmZpY3VsdHk+bWVkaXVtPC9kaWZmaWN1bHR5PgogICAgPGlzRGVwbG95ZWQ+dHJ1ZTwvaXNEZXBsb3llZD4KICA8L0xlYXJuaW5nQXNzZXQ+CiAgPFZpZGVvIGFzc2V0SUQgPSAibGExMDAiPgogICAgPHVybD55b3V0dS5iZS9IZzQ0WGpoMzwvdXJsPgogICAgPHJ1blRpbWU+MTY6MjM8L3J1blRpbWU+CiAgICA8dHlwZT5UdXRvcmlhbDwvdHlwZT4KICAgIDxwbGF0Zm9ybT5Zb3VUdWJlPC9wbGF0Zm9ybT4KICA8L1ZpZGVvPgogIDwhLS0gbW9yZSBWaWRlbyBlbGVtZW50cyAtLT4KICAKICA8TGVhcm5pbmdBc3NldCBhc3NldElEID0gImxhMTAyIiBhdXRob3JJREZLID0gImEzODciPgogICAgPHRpdGxlPkluZm9ybWF0aW9uIERpc2NvdmVyeTwvdGl0bGU+CiAgICA8ZGlmZmljdWx0eT5lYXN5PC9kaWZmaWN1bHR5PgogICAgPGlzRGVwbG95ZWQ+dHJ1ZTwvaXNEZXBsb3llZD4gICAgCiAgPC9MZWFybmluZ0Fzc2V0PgogIDxTbGlkZURlY2sgYXNzZXRJRCA9ICJsYTEwMiI+CiAgICA8dXJsPmRydi5jby9IZGRqODd6YTwvdXJsPgogICAgPGZpbGVUeXBlPnBwdHg8L2ZpbGVUeXBlPgogIDwvU2xpZGVEZWNrPgogIDwhLS0gbW9yZSBTbGlkZURlY2sgZWxlbWVudHMgLS0+CiAgCiAgPEF1dGhvciBhdXRob3JJRCA9ICJhMzg3Ij4KICAgIDxuYW1lPktlcm5lciwgSS48L25hbWU+CiAgPC9BdXRob3I+CiAgPCEtLSBtb3JlIEF1dGhvciBlbGVtZW50cyAtLT4KPC9yb290PgpgYGAKCiMjIFBhdHRlcm4gMTU6IFZhbHVlIFNldCB3aXRoIERlZmF1bHQgVmFsdWUKClRoaXMgZmluYWwgcGF0dGVybiBpbXBsZW1lbnRzIHZhbHVlIHNldHMgb3IgY2F0ZWdvcmljYWwgYXR0cmlidXRlcyB3aGljaCBkcmF3IHRoZWlyIHZhbHVlcyBmcm9tIGEgcHJlZGVmaW5lZCBzZXQgb2YgdmFsdWVzLiBUbyBlbmZvcmNlIGEgdmFsdWUgc2V0IChlbnVtZXJhdGVkIHR5cGUpIGl0IG11c3QgYmUgZGVmaW5lZCBhcyBhbiBhdHRyaWJ1dGUgYXMgbm8gdmFsaWRhdGlvbiBjYW4gb2NjdXIgZm9yIHBhcnNlZCBjaGFyYWN0ZXIgZGF0YSAoKiNQQ0RBVEEqKS4KCiFbXShwYXR0ZXJuLWJvb2xlYW5zLmpwZyl7d2lkdGg9IjUwJSJ9CgpgYGB7ciBlY2hvPUYsIGluY2x1ZGU9RkFMU0V9CnhtbERPTSA8LSB4bWxQYXJzZSgieG1sL3ZhbHVlc2V0LnhtbCIsIHZhbGlkYXRlPVQpCmBgYAoKYGBgIHhtbAo8IURPQ1RZUEUgcm9vdCBbCiAgPCFFTEVNRU5UIHJvb3QgKExlYXJuaW5nQXNzZXQqKT4KICA8IUVMRU1FTlQgTGVhcm5pbmdBc3NldAogICAgICAodGl0bGUsaXNEZXBsb3llZD8pPgogIDwhQVRUTElTVCBMZWFybmluZ0Fzc2V0IGFzc2V0SUQgSUQgI1JFUVVJUkVEPgogIAogIDwhQVRUTElTVCBMZWFybmluZ0Fzc2V0IGRpZmZpY3VsdHkgCiAgICAgKGVhc3l8bWVkaXVtfGRpZmZpY3VsdCkgImVhc3kiPgoKICA8IUVMRU1FTlQgdGl0bGUgKCNQQ0RBVEEpPgogIDwhRUxFTUVOVCBpc0RlcGxveWVkIEVNUFRZPgpdPgpgYGAKCkEgZGVmYXVsdCB2YWx1ZSBpcyByZXF1aXJlZCBmb3IgYSBlbnVtZXJhdGVkIHR5cGUuCgpgYGAgeG1sCjxyb290PgogIDxMZWFybmluZ0Fzc2V0IGFzc2V0SUQ9ImxhMTAxIiBkaWZmaWN1bHR5ID0gIm1lZGl1bSI+CiAgICA8dGl0bGU+SW50cm9kdWN0aW9uIHRvIFhNTDwvdGl0bGU+CiAgPC9MZWFybmluZ0Fzc2V0PgogIAogIDxMZWFybmluZ0Fzc2V0IGFzc2V0SUQgPSJsYTEwMiI+CiAgICA8dGl0bGU+VW5pb25zIGluIEM8L3RpdGxlPgogICAgPGlzRGVwbG95ZWQgLz4KICA8L0xlYXJuaW5nQXNzZXQ+CiAgCiAgPCEtLSAuLi4gLS0+Cjwvcm9vdD4KYGBgCgojIyBCZXN0IFByYWN0aWNlcwoKMS4gIFRoZSB1c2Ugb2YgWE1MIGVsZW1lbnQgYXR0cmlidXRlcyBmb3IgZWxlbWVudHMgc2hvdWxkIGJlIHJlc3RyaWN0ZWQgdG86IFByaW1hcnkga2V5cywgRm9yZWlnbiBrZXlzLCBhbmQgVmFsdWUgc2V0cyAoY2F0ZWdvcmljYWwpLiBBbGwgb3RoZXIgZW50aXR5IGF0dHJpYnV0ZXMgc2hvdWxkIGJlIHJlcHJlc2VudGVkIGFzIGNoaWxkIGVsZW1lbnQuCjIuICBUaGUgdXNlIG9mIHRoZXNlIHJlcHJlc2VudGF0aW9uYWwgcGF0dGVybnMgaXMgc3VnZ2VzdGl2ZSByYXRoZXIgdGhhbiBwcmVzY3JpcHRpdmUsIHNvIGRldmlhdGUgYW5kIGFkanVzdCBhcyBuZWNlc3NhcnkgZm9yIHNwZWNpZnkgdXNlIGNhc2VzLgoKIyMgU3VtbWFyeQoKVGhpcyBsZXNzb24gcHJvdmlkZWQgbnVtZXJvdXMgcGF0dGVybnMgZm9yIG1hcHBpbmcgZGlmZmVyZW50IGNvbmNlcHR1YWwgbW9kZWxpbmcgZWxlbWVudHMgdG8gYW4gWE1MIHJlcHJlc2VudGF0aW9uLiBNYW55IG9mIHRoZSBwYXR0ZXJucyBhcmUgc2ltaWxhciB0byB0aG9zZSB1c2VkIGluIG1hcHBpbmcgY29uY2VwdHVhbCBkYXRhIG1vZGVscyB0byByZWxhdGlvbmFsIG1vZGVscy4KCiMjIFR1dG9yaWFsIEk6IE1hcHBpbmcgdG8gWE1MCgpJbiB0aGlzIHZpZGVvIHR1dG9yaWFsLCBLaG91cnkgQm9zdG9uJ3MgUHJvZi4gU2NoZWRsYmF1ZXIgZXhwbGFpbnMgaG93IHRvIHVzZSBhIHNldCBvZiByZXByZXNlbnRhdGlvbmFsIHBhdHRlcm5zIHRvIG1hcCBhIGNvbmNlcHR1YWwgZGF0YSBtb2RlbCBpbnRvIGFuIFhNTCBkYXRhc3RvcmUgYW5kIGRlZmluZSBpdHMgc3RydWN0dXJlIGluIGEgRFRELgoKKipTbGlkZSBEZWNrKio6IFtNYXBwaW5nIFBhdHRlcm5zIGZvciBYTUxdKHMtODAtMTA2LXhtbC1tYXBwaW5nLXBhdHRlcm5zLnBwdHgpCgpOb3RlIHRoYXQgdGhlIHZpZGVvIHByZXNlbnRzIGFuIG9sZGVyIHZlcnNpb24gb2YgdGhlIHNsaWRlIGRlY2sgdGhhdCBoYXMgSUQgdmFsdWVzIHRoYXQgc3RhcnQgd2l0aCBhIGRpZ2l0LCB3aGljaCBpcyBub3QgY29ycmVjdC4gQW4gKklEKiB2YWx1ZSBtdXN0IHN0YXJ0IHdpdGggYSBsZXR0ZXIuIEZ1cnRoZXJtb3JlLCBhbiAqSURSRUYqIG11c3QgaGF2ZSBhICojUkVRVUlSRUQqIGNvbnN0cmFpbnQ7IHRoZSBzbGlkZXMgaW4gdGhlIHZpZGVvIGluY29ycmVjdGx5IHNob3cgYW4gKklEUkVGKiB3aXRob3V0IHRoYXQuCgpXaGlsZSBtb3N0IHBhcnNlcnMgd2lsbCBnbG9zcyBvdmVyIHRoZXNlIGVycm9ycywgbWFueSB3aWxsIG5vdC4gQ29uc2VxdWVudGx5LCB0aGUgWE1MIGZpbGUgd291bGQgbm90IHZhbGlkYXRlIGFzIHRoZSBEVEQgaXMgaW5jb3JyZWN0LiBVc2UgdG9vbHMgc3VjaCBhcyA8aHR0cDovL3htbHZhbGlkYXRpb24uY29tPiB0byBoZWxwIHZhbGlkYXRlIHlvdXIgWE1MIGRvY3VtZW50cyBhbmQgdGhlaXIgRFRELgoKYGBgez1odG1sfQo8aWZyYW1lIHN0eWxlPSJib3JkZXI6IDFweCBzb2xpZCAjNDY0NjQ2OyIgc3JjPSJodHRwczovL25vcnRoZWFzdGVybi5ob3N0ZWQucGFub3B0by5jb20vUGFub3B0by9QYWdlcy9FbWJlZC5hc3B4P2lkPTJjN2ZiMTY0LTk1MzItNDBmOC04OGExLWFjMGYwMTJmYTJhMiZhbXA7YXV0b3BsYXk9ZmFsc2UmYW1wO29mZmVydmlld2VyPWZhbHNlJmFtcDtzaG93dGl0bGU9ZmFsc2UmYW1wO3Nob3dicmFuZD1mYWxzZSZhbXA7c3RhcnQ9MCZhbXA7aW50ZXJhY3Rpdml0eT1hbGwiIHdpZHRoPSI0ODAiIGhlaWdodD0iMjcwIiBhbGxvd2Z1bGxzY3JlZW49ImFsbG93ZnVsbHNjcmVlbiIgYWxsb3c9ImF1dG9wbGF5IiBkYXRhLWV4dGVybmFsPSIxIj48L2lmcmFtZT4KYGBgCiMjIFR1dG9yaWFsIElJOiBQcmltYXJ5IHZzIEZvcmVpZ24gS2V5cyBpbiBVTUwgYW5kIFhNTAoKSW4gdGhpcyBuYXJyYXRlZCBjaGFsay10YWxrLCBLaG91cnkgQm9zdG9uJ3MgUHJvZi4gU2NoZWRsYmF1ZXIgZXhwbGFpbnMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBwcmltYXJ5IGFuZCBmb3JlaWduIGtleXMgaW4gVU1MLCBYTUwsIGFuZCBpbiBnZW5lcmFsLgoKYGBgez1odG1sfQo8aWZyYW1lIHN0eWxlPSJib3JkZXI6IDFweCBzb2xpZCAjNDY0NjQ2OyIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9nMGdvU1VwSGZFayIgd2lkdGg9IjQ4MCIgaGVpZ2h0PSIyNzAiIGFsbG93ZnVsbHNjcmVlbj0iYWxsb3dmdWxsc2NyZWVuIiBhbGxvdz0iYWNjZWxlcm9tZXRlcjsgYXV0b3BsYXk7IGNsaXBib2FyZC13cml0ZTsgZW5jcnlwdGVkLW1lZGlhOyBneXJvc2NvcGU7IHBpY3R1cmUtaW4tcGljdHVyZSIgZGF0YS1leHRlcm5hbD0iMSI+PC9pZnJhbWU+CmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBGaWxlcyAmIFJlc291cmNlcwoKYGBge3IgemlwRmlsZXMsIGVjaG89RkFMU0V9CnppcE5hbWUgPSBzcHJpbnRmKCJMZXNzb25GaWxlcy0lcy0lcy56aXAiLCAKICAgICAgICAgICAgICAgICBwYXJhbXMkY2F0ZWdvcnksCiAgICAgICAgICAgICAgICAgcGFyYW1zJG51bWJlcikKCnRleHRBTGluayA9IHBhc3RlMCgiQWxsIEZpbGVzIGZvciBMZXNzb24gIiwgCiAgICAgICAgICAgICAgIHBhcmFtcyRjYXRlZ29yeSwiLiIscGFyYW1zJG51bWJlcikKCiMgZG93bmxvYWRGaWxlc0xpbmsoKSBpcyBpbmNsdWRlZCBmcm9tIF9pbnNlcnQyREIuUgprbml0cjo6cmF3X2h0bWwoZG93bmxvYWRGaWxlc0xpbmsoIi4iLCB6aXBOYW1lLCB0ZXh0QUxpbmspKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgUmVmZXJlbmNlcwoKTm8gcmVmZXJlbmNlcy4KCiMjIEVycmF0YQoKTm9uZSBjb2xsZWN0ZWQgeWV0LiBMZXQgdXMga25vdy4KCmBgYHs9aHRtbH0KPHNjcmlwdCBzcmM9Imh0dHBzOi8vZm9ybS5qb3Rmb3JtLmNvbS9zdGF0aWMvZmVlZGJhY2syLmpzIiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgogIG5ldyBKb3Rmb3JtRmVlZGJhY2soewogICAgZm9ybUlkOiAiMjEyMTg3MDcyNzg0MTU3IiwKICAgIGJ1dHRvblRleHQ6ICJGZWVkYmFjayIsCiAgICBiYXNlOiAiaHR0cHM6Ly9mb3JtLmpvdGZvcm0uY29tLyIsCiAgICBiYWNrZ3JvdW5kOiAiI0Y1OTIwMiIsCiAgICBmb250Q29sb3I6ICIjRkZGRkZGIiwKICAgIGJ1dHRvblNpZGU6ICJsZWZ0IiwKICAgIGJ1dHRvbkFsaWduOiAiY2VudGVyIiwKICAgIHR5cGU6IGZhbHNlLAogICAgd2lkdGg6IDcwMCwKICAgIGhlaWdodDogNTAwLAogICAgaXNDYXJkRm9ybTogZmFsc2UKICB9KTsKPC9zY3JpcHQ+CmBgYApgYGB7ciBjb2RlPXhmdW46OnJlYWRfdXRmOChwYXN0ZTAoaGVyZTo6aGVyZSgpLCcvUi9fZGVwbG95S25pdC5SJykpLCBpbmNsdWRlID0gRkFMU0V9CmBgYAo=