
Introduction
In Session 2a, we read in bulk-rna seq data that was obtained from
our previously published study on bladder cancer muscle invasiveness
into cytoscape and got familiar with how Cytoscape can
be used for analyzing and interpreting next-generation sequencing data
sets. Here we will perform functional enrichment analysis to retrieve
networks and pathways, integrate and explore biological data, perform
functional enrichment analysis and interpret our data to display it in
publications.
Background
Cytoscape is an open source software platform for
integrating, visualizing, and analyzing measurement data in the context
of networks.
Learning Objectives
Retrieve Networks and Pathways
Integrate and Explore Your Data
Perform Functional Enrichment Analysis
Functional Interpretation and Display
Load TCGA data
Create the network
- Download BCLA-all.tsv.
- Import the file to create a network using File → Import →
Network from File..
- Alternatively, drag and drop the data file directly onto the
Node Table.
- This will bring up the Import Network From Table
dialog.
- Click on Select None to disable all columns.
- Click only on the GeneName column and set this
column as the Source Node column (green circle).
- Click OK. You’ll see a warning about no edges, but
that’s OK. This will create a grid of 1500 unconnected nodes, where each
node represents a gene.
Add data to our nodes
- Open the file again, but now use File → Import → Table from
File…
- This will bring up the Import Columns From Table
dialog.
- It turns out that all of the defaults are correct for just importing
the data, so click on OK.
- This will import all of the data in the spreadsheet and associate
each row with the corresponding node.
- You should be able to see this in the Table
Panel.
Find significant expression changes
We’ll use the Filter tab in the Control Panel to
find the significant overall expression changes.
- Open the Filter tab and click on the +
button to add a new condition. In this case we’re going to add
a Column Filter. Select the “Mean log2FC” column and
set the values to be between -3 and -0.5. This will
select all genes that are significantly underexpressed on average,
across all samples (only one gene should be
selected).
- Repeat the same process as above, but set the values to be between
0.5 and 3. You’ll also need to change the type of match
(at the top of the panel) to Match any (OR). No
additional genes will be selected in this case (but this approach will
be reused later).

30 genes shows significant average expression
changes across all samples, some genes in the list has been shown to be
linked to bladder cancer, but it’s still a relatively unsatisfying
result that only a 30 proteins change expression in bladder cancer
patients. A closer examination might be in order…
Cluster to see expression patterns
Let’s cluster all of the data to see if there are any significant
patterns that have been averaged out by looking at all samples in the
aggregate. clusterMaker2 is a Cytoscape app that
provides a number of clustering algorithms including
hierarchical and k-means.
Re-import expression data.
First, we need to re-import the expression data for the new network
created by the stringApp. Similar to the initial
import, start by doing File → Import → Table from File.
Again, select the BCLA-all.tsv file. However, now we need to use a
different network column to match our names. Change the Key
Column for Network: from shared name to
query term. STRING uses Ensembl identifiers, but
retains the original query term so we can match data against. Now select
OK.
Disable structure image.
STRING provides some nice images of the 3D structure
of the proteins, but we need to disable those to be able to see our
expression values clearly. Disable the images by going to Apps →
STRING → untick show structure images.
Create color gradient for expression data.
To show the expression data, go the Style tab of the
Control Panel and click on the middle square
(Map.) of the three Fill Color
controls. Set the Column to “Cluster 1 Mean log2FC” and set the
Mapping Type to “Continuous Mapping”.
Double-click on the gradient to show the Continuous Mapping
Editor. The default gradient is a Blue/Red color gradient, with
blue representing underexpressed genes and red representing
overexpressed genes. We can keep this default gradient as is.
Add styling to show mutations
In addition to expression fold change, the imported data also
includes information about mutation, both across all patients and
subdivided by cluster. It might be informative to add that information
to our visualization.
Lock node width and height.
By default, the stringApp provides separate values
for Node Width and Node Height. In our case, we just want to lock them
to be the same so we only have to modify the Node Size. The Lock
node width and height is a checkbox at the bottom of the
Node tab in the Style tab of the
Control Panel. Make sure that it’s checked.
Set the default node size.
Click on the leftmost (Def.) box next to Size. Set
the default size to “45.0”.
Map mutation to node size.
Click on the middle (Map.) box next to Size. Choose
“Cluster 1 Mutations” for the Column and “Continuous Mapping” for the
Mapping Type. Then double-click on the ramp that
appears to bring up the Continuous Mapping Editor.
Click on the leftmost triangle and set the Node Size to
“45”. Then click on the right-most triangle and set the Node
Size to “90”. Then check OK.
Examine the network.
Examining the main connected component of the network, we immediately
see that there is a group of overexpressed genes, COL6A3,
COL1A1, COL1A2, etc., that also exhibit some mutations. There
is also a group of genes, MMP7, MMP9, TIMP4 and MMP2
that show some mixed expression changes. Finally, there is a group of
genes, including NCAN, BCAN SDC3, and GABBR1, in
between these groups that show predominantly underexpression. 
At this point in our workflow, we have some options:
One typical path might be to find all of the overexpressing genes,
use the Diffusion app to perform heat diffusion through the network to
grow the selection and then perform functional enrichment analysis on
that set of genes and then repeat for underexpressing genes (see step
Smooth the network using Diffusion below).
Another approach is suggested by the topology of the network, which
strongly suggests groupings in the interactions. We can use clustering
based on the network topology and to perform functional enrichment on
each cluster (see step Topologically cluster the
network). We’ll take each of those in turns.
Smooth the network using Diffusion.
When we created the STRING network, we added nodes
to make sure that well connected nodes that might be silent (i.e. not
exhibit changes in expression) could be included. Well connected genes
might play a significant role in the biology even if their expression
doesn’t change due to changes in the expression of their interaction
partners. The Diffusion app supports the ability to find those genes by
simulating the diffusion of heat through network connections.
Create subnetwork of the main connected component.
Select all of the nodes and edges in the main connected component by
holding mouse button 1 down and sweeping over the nodes. Alternatively,
you could select a single node and then repeatedly hitting
Control-6 (or ⌘6 on the Mac) to continually select the
first neighbors of selected nodes until all of the nodes in the
connected component are selected. Once the entire component is selected,
create a new network by doing File → New Network → From Selected
Nodes, All Edges.
Select overexpressed genes.
Go back to the Filter tab and disable (click on the
X) the filter for underexpressed genes, then click
Apply.
Diffuse the selection.
In the diffusion app we can diffuse either based on the heat (column
value) or just based on the selection. We’re going to diffuse based on
our expression values, so select Tools → Diffuse → Selected
Nodes with Options and in the dialog select “Cluster 1
Mean log2FC” as the Heat Column and set a
short time of 0.001 seconds. Then click
OK.

Create subnetwork.
- Change the Node Rank to about 40 and create a
subnetwork by selecting File → New Network → From Selected
Nodes, All Edges.
* Once the network is created, execute an
unweighted Prefuse Force Directed Layout (Layout → Prefuse Force
Directed Layout → All Nodes (none)).

- Repeat for underexpressed genes. For underexpressed
genes, repeat the previous steps above, except choose all genes with a
“Cluster 1 Mean log2FC” less than -1
and in the diffusion app set the time to 0.01 seconds. Unfortunately the
Diffusion Output assumes positive diffusion values, so to select the
diffused nodes of interest, you’ll need to go to the Table Panel and
sort the diffusion_output_heat column, select the negative values less
than -0.5, right-click on the column and select Select
nodes from selected rows. Then you can create the subnetwork.

Exercise:
Repeat for underexpressed network.
Also color the nodes based on the functionally enriched values.
For example “ECM-Pathways”, etc.
Topologically cluster the network.
Looking at the protein-protein interaction network (below), we see
that there appear to be strong connections between groups of nodes (see
discussion in “Adding styling to show mutations”
above). One approach to explore the functional interactions of the
network is to use a topological clustering algorithm to partition the
network based on the interactions. The clusterMaker2 app provides a set
of topological (network) cluster algorithms. One commonly used one is
MCL, which performs a Markov-based flow simulation to determine
clusters.

- Cluster using MCL. Make sure the network is
connected, then go to Apps → clusterMaker Cluster Network → MCL
Cluster.
- This will bring up the MCL settings dialog. There are a number of
options, but most of these don’t require any changes for our uses. We’re
going to treat the network as unweighted so we don’t need to provide any
Array Sources. We do want to check the Create new clustered
network however so we can visualize the results. Then click
OK.
Determine functional enrichment of the clusters.
The results of the clustering should look something like the figure
below, which is a close-up of the largest components. Of particular
interest are the largest 4 components, which we’ll perform functional
enrichment.
- Set network as a STRING network. The first step is
to inform the stringApp that this is a STRING-derived
network. A menu item is available for that purpose: Apps →
STRING → Set as STRING network.
- Retrieve functional enrichment of a component. In
the subnetwork, there are four connected components of any size. Select
all of the nodes in the second largest one (the one with a number of
overexpressed genes and the bulk of the mutations) and retrieve the
functional enrichment through the Apps → STRING Enrichment →
Retrieve functional enrichment..
- This will bring up a new Table Panel tab for STRING
Enrichment. There is a pull-down menu that switches the
ontology or pathway displayed. Looking at the results we see that there
is a significant overexpression of genes involved in the GO Biological
Processes: extracellular matrix organization, collagen catabolic
process, and other development processes; they are also associated with
the KEGG pathways IL-17 Signaling Pathway and absorption, PI3K-AKT
Signaling pathway and ECM-receptor interaction.
Exercise:
Repeat for underexpressed network.
Also color the nodes based on the functionally enriched values.
For example “ECM-Pathways”, etc.
Next Session:
We will now go to the next Session
(3) to work with integrating pathway resources using ClueGO and
CluePedia.
LS0tDQp0aXRsZTogIkZ1bmN0aW9uYWwgRW5yaWNobWVudCBBbmFseXNpcyB1c2luZyBDeXRvc2NhcGUgLSBTZXNzaW9uIDItQiINCmF1dGhvcjogIkRyLiBBa3NoYXkgQmhhdCINCmRhdGU6ICdgciBmb3JtYXQoU3lzLnRpbWUoKSwgIkxhc3QgbW9kaWZpZWQ6ICVkICViICVZIilgJw0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBjc3M6IHN0eWxlc2hlZXRzL3N0eWxlcy5jc3MNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfSANCmtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkgDQpgYGAgDQo8aW1nIHNyYz0iaW1hZ2VzL2xvZ28tc20ucG5nIiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7dG9wOjQwcHg7cmlnaHQ6MTBweDsiIHdpZHRoPSIyMDAiIC8+DQoNCiMgSW50cm9kdWN0aW9uDQoNCkluIFNlc3Npb24gMmEsIHdlIHJlYWQgaW4gYnVsay1ybmEgc2VxIGRhdGEgdGhhdCB3YXMgb2J0YWluZWQgZnJvbSBvdXIgcHJldmlvdXNseSBwdWJsaXNoZWQgc3R1ZHkgb24gYmxhZGRlciBjYW5jZXIgbXVzY2xlIGludmFzaXZlbmVzcyBpbnRvIGN5dG9zY2FwZSBhbmQgZ290IGZhbWlsaWFyIHdpdGggaG93ICoqQ3l0b3NjYXBlKiogY2FuIGJlIHVzZWQgZm9yIGFuYWx5emluZyBhbmQgaW50ZXJwcmV0aW5nIG5leHQtZ2VuZXJhdGlvbiBzZXF1ZW5jaW5nIGRhdGEgc2V0cy4gSGVyZSB3ZSB3aWxsIHBlcmZvcm0gZnVuY3Rpb25hbCBlbnJpY2htZW50IGFuYWx5c2lzIHRvIHJldHJpZXZlIG5ldHdvcmtzIGFuZCBwYXRod2F5cywgaW50ZWdyYXRlIGFuZCBleHBsb3JlIGJpb2xvZ2ljYWwgZGF0YSwgcGVyZm9ybSBmdW5jdGlvbmFsIGVucmljaG1lbnQgYW5hbHlzaXMgYW5kIGludGVycHJldCBvdXIgZGF0YSB0byBkaXNwbGF5IGl0IGluIHB1YmxpY2F0aW9ucy4NCg0KIyBCYWNrZ3JvdW5kIA0KKipDeXRvc2NhcGUqKiBpcyBhbiBvcGVuIHNvdXJjZSBzb2Z0d2FyZSBwbGF0Zm9ybSBmb3IgaW50ZWdyYXRpbmcsIHZpc3VhbGl6aW5nLCBhbmQgYW5hbHl6aW5nIG1lYXN1cmVtZW50IGRhdGEgaW4gdGhlIGNvbnRleHQgb2YgbmV0d29ya3MuDQoNCiMgTGVhcm5pbmcgT2JqZWN0aXZlcw0KDQoqIFJldHJpZXZlIE5ldHdvcmtzIGFuZCBQYXRod2F5cw0KDQoqIEludGVncmF0ZSBhbmQgRXhwbG9yZSBZb3VyIERhdGENCg0KKiBQZXJmb3JtIEZ1bmN0aW9uYWwgRW5yaWNobWVudCBBbmFseXNpcw0KDQoqIEZ1bmN0aW9uYWwgSW50ZXJwcmV0YXRpb24gYW5kIERpc3BsYXkgDQoNCjxkaXYgY2xhc3M9ImluZm9ybWF0aW9uIj4NCg0KIyBTZXR1cA0KDQoNCiogSW5zdGFsbCBhbmQgbGF1bmNoIFtDeXRvc2NhcGUuXShodHRwczovL2N5dG9zY2FwZS5vcmcvKSBJZiB0aGlzIGlzIHlvdXIgZmlyc3QgdGltZSBsYXVuY2hpbmcgQ3l0b3NjYXBlLCByZWZlciB0aGUgW21hbnVhbF0oaHR0cHM6Ly9tYW51YWwuY3l0b3NjYXBlLm9yZy9lbi9zdGFibGUvKSBvciB0dXRvcmlhbCBpbiBbU2Vzc2lvbiAxXShodHRwczovL2ExYWtzLmdpdGh1Yi5pby9DeXRvc2NhcGVfQ291cnNlL3Nlc3Npb24xLm5iLmh0bWwpIGZvciBhIGJhc2ljIGludHJvZHVjdGlvbi4gPGJyPjwvYnI+DQoqIEdvIHRvIHRoZSBhcHAgc3RvcmUgdG8gaW5zdGFsbCB0aGUgW0Z1bmN0aW9uYWwgRW5yaWNobWVudCBDb2xsZWN0aW9uLl0oaHR0cHM6Ly9hcHBzLmN5dG9zY2FwZS5vcmcvYXBwcy9mdW5jdGlvbmFsZW5yaWNobWVudGNvbGxlY3Rpb24pDQoNCjwvZGl2PiA8YnI+PC9icj4gDQoNCg0KIyBMb2FkIFRDR0EgZGF0YQ0KDQojIyBDcmVhdGUgdGhlIG5ldHdvcmsNCg0KKiBEb3dubG9hZCBbQkNMQS1hbGwudHN2Ll0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL21hcmtkdW5uaW5nL0N5dG9zY2FwZV9Db3Vyc2UvcGF0Y2gtMS9EYXRhX0ZpbGVzL0JDTEEtYWxsLnRzdikNCiogSW1wb3J0IHRoZSBmaWxlIHRvIGNyZWF0ZSBhIG5ldHdvcmsgdXNpbmcgKipGaWxlIOKGkiBJbXBvcnQg4oaSIE5ldHdvcmsgZnJvbSBGaWxlLi4qKiANCiogQWx0ZXJuYXRpdmVseSwgZHJhZyBhbmQgZHJvcCB0aGUgZGF0YSBmaWxlIGRpcmVjdGx5IG9udG8gdGhlICoqTm9kZSBUYWJsZSoqLg0KKiBUaGlzIHdpbGwgYnJpbmcgdXAgdGhlICoqSW1wb3J0IE5ldHdvcmsgRnJvbSBUYWJsZSoqIGRpYWxvZy4NCiAgKiBDbGljayBvbiAqKlNlbGVjdCBOb25lKiogdG8gZGlzYWJsZSBhbGwgY29sdW1ucy4NCiAgKiBDbGljayBvbmx5IG9uIHRoZSAqKkdlbmVOYW1lIGNvbHVtbioqIGFuZCBzZXQgdGhpcyBjb2x1bW4gYXMgdGhlICoqU291cmNlIE5vZGUgY29sdW1uKiogKGdyZWVuIGNpcmNsZSkuDQogICogQ2xpY2sgKipPSy4qKiBZb3XigJlsbCBzZWUgYSB3YXJuaW5nIGFib3V0IG5vIGVkZ2VzLCBidXQgdGhhdOKAmXMgT0suIFRoaXMgd2lsbCBjcmVhdGUgYSBncmlkIG9mIDE1MDAgdW5jb25uZWN0ZWQgbm9kZXMsIHdoZXJlIGVhY2ggbm9kZSByZXByZXNlbnRzIGEgZ2VuZS4NCiAgDQojIyBBZGQgZGF0YSB0byBvdXIgbm9kZXMNCg0KICAqIE9wZW4gdGhlIGZpbGUgYWdhaW4sIGJ1dCBub3cgdXNlICoqRmlsZSDihpIgSW1wb3J0IOKGkiBUYWJsZSBmcm9tIEZpbGUuLi4qKg0KICAqIFRoaXMgd2lsbCBicmluZyB1cCB0aGUgKipJbXBvcnQgQ29sdW1ucyoqIEZyb20gVGFibGUgZGlhbG9nLg0KICAgICogSXQgdHVybnMgb3V0IHRoYXQgYWxsIG9mIHRoZSBkZWZhdWx0cyBhcmUgY29ycmVjdCBmb3IganVzdCBpbXBvcnRpbmcgdGhlIGRhdGEsIHNvIGNsaWNrIG9uICoqT0suKioNCiAgICAqIFRoaXMgd2lsbCBpbXBvcnQgYWxsIG9mIHRoZSBkYXRhIGluIHRoZSBzcHJlYWRzaGVldCBhbmQgYXNzb2NpYXRlIGVhY2ggcm93IHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgbm9kZS4NCiAgICAqIFlvdSBzaG91bGQgYmUgYWJsZSB0byBzZWUgdGhpcyBpbiB0aGUgKipUYWJsZSBQYW5lbCoqLg0KICANCg0KIyMgRmluZCBzaWduaWZpY2FudCBleHByZXNzaW9uIGNoYW5nZXMNCg0KV2XigJlsbCB1c2UgdGhlICoqRmlsdGVyIHRhYioqIGluIHRoZSBDb250cm9sIFBhbmVsIHRvIGZpbmQgdGhlIHNpZ25pZmljYW50IG92ZXJhbGwgZXhwcmVzc2lvbiBjaGFuZ2VzLg0KDQoNCiAgKiBPcGVuIHRoZSAqKkZpbHRlciB0YWIqKiBhbmQgY2xpY2sgb24gdGhlICoqKyBidXR0b24qKiB0byBhZGQgYSBuZXcgY29uZGl0aW9uLiBJbiB0aGlzIGNhc2Ugd2XigJlyZSBnb2luZyB0byBhZGQgYSBDb2x1bW4gRmlsdGVyLiBTZWxlY3QgdGhlICoqIk1lYW4gbG9nMkZDIioqIGNvbHVtbiBhbmQgc2V0IHRoZSB2YWx1ZXMgdG8gYmUgYmV0d2VlbiAqKi0zIGFuZCAtMC41KiouIFRoaXMgd2lsbCBzZWxlY3QgYWxsIGdlbmVzIHRoYXQgYXJlIHNpZ25pZmljYW50bHkgdW5kZXJleHByZXNzZWQgb24gYXZlcmFnZSwgYWNyb3NzIGFsbCBzYW1wbGVzICgqKm9ubHkgb25lIGdlbmUgc2hvdWxkIGJlIHNlbGVjdGVkKiopLg0KICAqIFJlcGVhdCB0aGUgc2FtZSBwcm9jZXNzIGFzIGFib3ZlLCBidXQgc2V0IHRoZSB2YWx1ZXMgdG8gYmUgYmV0d2VlbiAqKjAuNSBhbmQgMyoqLiBZb3XigJlsbCBhbHNvIG5lZWQgdG8gY2hhbmdlIHRoZSB0eXBlIG9mIG1hdGNoIChhdCB0aGUgdG9wIG9mIHRoZSBwYW5lbCkgdG8gKipNYXRjaCBhbnkgKE9SKSoqLiBObyBhZGRpdGlvbmFsIGdlbmVzIHdpbGwgYmUgc2VsZWN0ZWQgaW4gdGhpcyBjYXNlIChidXQgdGhpcyBhcHByb2FjaCB3aWxsIGJlIHJldXNlZCBsYXRlcikuDQoNCiFbXShpbWFnZXMvRmlsdGVyLnBuZykNCg0KPGJyPjwvYnI+DQoNCioqMzAgZ2VuZXMqKiBzaG93cyBzaWduaWZpY2FudCBhdmVyYWdlIGV4cHJlc3Npb24gY2hhbmdlcyBhY3Jvc3MgYWxsIHNhbXBsZXMsIHNvbWUgZ2VuZXMgaW4gdGhlIGxpc3QgaGFzIGJlZW4gc2hvd24gdG8gYmUgbGlua2VkIHRvIGJsYWRkZXIgY2FuY2VyLCBidXQgaXTigJlzIHN0aWxsIGEgcmVsYXRpdmVseSB1bnNhdGlzZnlpbmcgcmVzdWx0IHRoYXQgb25seSBhIDMwIHByb3RlaW5zIGNoYW5nZSBleHByZXNzaW9uIGluIGJsYWRkZXIgY2FuY2VyIHBhdGllbnRzLiBBIGNsb3NlciBleGFtaW5hdGlvbiBtaWdodCBiZSBpbiBvcmRlci4uLg0KDQoNCjxicj48L2JyPg0KDQojIENsdXN0ZXIgdG8gc2VlIGV4cHJlc3Npb24gcGF0dGVybnMNCkxldOKAmXMgY2x1c3RlciBhbGwgb2YgdGhlIGRhdGEgdG8gc2VlIGlmIHRoZXJlIGFyZSBhbnkgc2lnbmlmaWNhbnQgcGF0dGVybnMgdGhhdCBoYXZlIGJlZW4gYXZlcmFnZWQgb3V0IGJ5IGxvb2tpbmcgYXQgYWxsIHNhbXBsZXMgaW4gdGhlIGFnZ3JlZ2F0ZS4gKipjbHVzdGVyTWFrZXIyKiogaXMgYSBDeXRvc2NhcGUgYXBwIHRoYXQgcHJvdmlkZXMgYSBudW1iZXIgb2YgY2x1c3RlcmluZyBhbGdvcml0aG1zIGluY2x1ZGluZyAqKmhpZXJhcmNoaWNhbCBhbmQgay1tZWFucyoqLg0KDQojIyBQZXJmb3JtIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nLiANCg0KSW4gQ3l0b3NjYXBlLCAqKnNlbGVjdCBBcHBzIOKGkiBjbHVzdGVyTWFrZXIgQ2x1c3RlciBBdHRyaWJ1aXRlcyDihpIgSGllcmFyY2hpY2FsIGNsdXN0ZXIuKiogVGhpcyB3aWxsIGJyaW5nIHRoZSBzZXR0aW5ncyBmb3IgaGllcmFyY2hpY2FsIGNsdXN0ZXJpbmcuICoqU2VsZWN0IFBlYXJzb24gY29ycmVsYXRpb24qKiBmb3IgRGlzdGFuY2UgbWV0cmljIGFuZCAqKlNlbGVjdCBhbGwgb2YgdGhlIHNhbXBsZXMgKGNvbHVtbnMgYmVnaW5uaW5nIHdpdGggKipUQ0dBLSoqKSoqIGluIHRoZSAqKk5vZGUgYXR0cmlidXRlcyBmb3IgY2x1c3RlcioqIGxpc3QuIFRoZSBjaGVja2JveGVzICoqQ2x1c3RlciBhdHRyaWJ1dGVzIGFzIHdlbGwgYXMgbm9kZXMsIElnbm9yZSBub2Rlcy9lZGdlcyB3aXRoIG5vIGRhdGEqKiwgYW5kICoqU2hvdyBUcmVlVmlldyB3aGVuIGNvbXBsZXRlKiogc2hvdWxkIGFsbCBiZSBjaGVja2VkLiBUaGVuIGNsaWNrICoqT0sqKi4gVGhlIHJlc3VsdGluZyBUcmVlVmlldyBzaG91bGQgbG9vayBsaWtlIHRoZSBmaWd1cmUgYmVsb3cuDQoNCiFbXShpbWFnZXMvSGllcmFyY2hpYWxfQ2x1c3Rlci5wbmcpDQoNCg0KPGJyPjwvYnI+DQoNClVzZXJzIGNhbiB1c2Ugc29tZSBvZiB0aGUgb3B0aW9ucyBiZWxvdyBpbiB0aGUgcGFuZWwgKGxpa2UgKipGbGlwIFRyZWUgTm9kZSBvciBNYXBwIENvbG9ycyBvbnRvIE5ldHdvcmsqKikgdG8gZWRpdCB0aGUgaGVhdG1hcCBhbmQvb3Igc2VsZWN0IHN0cmluZ2VudCBzdGF0aXN0aWNzIHRvIHNlbGVjdCBmZXcgc2V0cyBvZiBnZW5lcy4gDQoNCkxvb2tpbmcgYXQgdGhlIHJlc3VsdCwgaXMgc2VlbXMgbGlrZSB0aGVyZSBhcmUgZGVmaW5pdGUgYmFuZHMgb2YgZXhwcmVzc2lvbiBkYXRhIHRoYXQgbG9vayBzaW1pbGFyIGFjcm9zcyBhIGdyb3VwIG9mIHBhdGllbnRzLCBidXQgZGlmZmVyIGJldHdlZW4gZ3JvdXBzLCBob3dldmVyLCB0aGUgZXhhY3QgbnVtYmVyIG9mIGNsdXN0ZXJzIGFuZCBkaXZpc2lvbnMgYmV0d2VlbiB0aGVtIGFyZW4ndCBjb21wbGV0ZWx5IGNsZWFyLiBCYXNlZCBvbiBwcmV2aW91c2x5IHJlcG9ydGVkIHJlc3VsdHMsIGl0IGhhcyBiZWVuIHN1Z2dlc3RlZCB0aGF0IHRoZXJlIGFyZSA0IGRpZmZlcmVudCBzdWJ0eXBlcyBvZiBibGFkZGVyIGNhbmNlciwgaG93ZXZlciwgdGhlc2Ugc3VidHlwZXMgaGF2ZSBiZWVuIHVwZGF0ZWQgdG8gNiBvciBtb3JlIGluIHJlY2VudCBzdHVkaWVzLiBMZXTigJlzIHRha2UgdGhhdCBrbm93biBkYXRhIGFuZCBzZWUgaWYgd2UgY2FuIHN1YnNldCB0aGUgZGF0YSBpbnRvIDQgc3VidHlwZXMgYXMgYW4gZXhhbXBsZS4NCg0KDQoqICoqUGVyZm9ybSBrLW1lYW5zIGNsdXN0ZXJpbmcqKi4gSW4gQ3l0b3NjYXBlLCBzZWxlY3QgKipBcHBzIOKGkiBjbHVzdGVyTWFrZXIgQ2x1c3RlciBBdHRyaWJ1aXRlcyDihpIgSy1NZWFucyBjbHVzdGVyKiouIEluIHRoZSByZXN1bHRpbmcgc2V0dGluZ3MgZGlhbG9nLCBzZXQgdGhlIG51bWJlciBvZiBjbHVzdGVyIHRvICoqNCoqLCB3aGljaCBpcyB0aGUgbnVtYmVyIG9mIGtub3duIHN1YnR5cGVzIG9mIGJsYWRkZXIgY2FuY2VyLCBhcyB3aXRoIHRoZSBoaWVyYXJjaGljYWwgY2x1c3RlciwgKipzZWxlY3QgYWxsIG9mIHRoZSBzYW1wbGVzIChUQ0dBLSkqKiwgY2hlY2sgQ2x1c3RlciBhdHRyaWJ1dGVzIGFzIHdlbGwgYXMgbm9kZXMgYW5kIFNob3cgSGVhdE1hcCB3aGVuIGNvbXBsZXRlLiBUaGlzIHdpbGwgcmVzdWx0IGluIGEgaGVhdCBtYXAgc2ltaWxhciB0byB0aGUgb25lIGluIHRoZSBmaWd1cmUgYmVsb3cuDQoNCiFbXShpbWFnZXMvSy1NZWFuX0NsdXN0ZXJNYWtlci5wbmcpDQo8YnI+PC9icj4NCg0KKiBOb3RlIHRoYXQgdGhlcmUgYXJlIGZvdXIgZGlzdGluY3QgdmVydGljYWwgYmFuZHMgKHlvdXIgcmVzdWx0cyBtaWdodCB2YXJ5IGluIHRoZSBvcmRlcmluZyBpbiBlaXRoZXIgdGhlIHZlcnRpY2FsIG9yIGhvcml6b250YWwgZGltZW5zaW9ucykuIEluIGZhY3QsIHRoZSBmaXJlaG9zZSBhbmFseXNlcyBpZGVudGlmaWVkIHRoZSBzYW1lIGZvdXIgZ3JvdXBpbmdzIG9mIHBhdGllbnRzLiBJbiB0aGUgc3ByZWFkc2hlZXQgbG9hZGVkIG9yaWdpbmFsbHksIHdl4oCZdmUgY2FsY3VsYXRlZCB0aGUgbWVhbiBMb2cyKGZvbGQgY2hhbmdlKSBmb3IgZWFjaCBvZiB0aGUgZm91ciBzdWJ0eXBlcy4NCg0KDQo8ZGl2IGNsYXNzPSJpbmZvcm1hdGlvbiI+DQojIEV4Y2VyY2lzZSANCg0KIyMjIGEuIEZpbmQgc2lnbmlmaWNhbnQgZXhwcmVzc2lvbiBjaGFuZ2VzIGluICoqQ2x1c3RlciAxKiogPGJyPjwvYnI+DQoqKkhpbnQ6KiogV2UgYXJlIGdvaW5nIHRvIHJlcGVhdCBzdGVwIDQgd2l0aCAiQ2x1c3RlciAxIE1lYW4gbG9nMkZDIiBhcyB0aGUgY29sdW1uLiBUaGlzIHJlcHJlc2VudHMgdGhlIG1lYW4gZXhwcmVzc2lvbiBhY3Jvc3MgdGhlIHNhbXBsZXMgaW4gY2x1c3RlciAxICh0aGUgbGVmdG1vc3QgY2x1c3RlciBpbiB0aGUgcHJldmlvdXMgZmlndXJlKS4NCg0KKiBEb3dubG9hZCB0aGUgUFBJIGZyb20gU1RSSU5HDQpGcm9tIHRoZSBhYm92ZSBzZWxlY3Rpb24gZmlsdGVyLCB3ZeKAmXZlIGlkZW50aWZpZWQgMTkyIG5vZGVzIHRoYXQgc2hvdyBhbiBhdmVyYWdlICoqTG9nMkZDIGdyZWF0ZXIgdGhhbiA1IG9yIGxlc3MgdGhhbiAxKiosIGFuZCBzZWxlY3RlZCB0aG9zZSBub2Rlcy4gTm93LCB3ZSBjcmVhdGUgYSBzZXBhcmF0ZSBuZXR3b3JrIHRoYXQgaW5jbHVkZXMgYWxsIG9mIHRob3NlIDE5MiBub2RlcyBieSBzZWxlY3RpbmcgdGhlICoqIkNyZWF0ZSBOZXR3b3JrIGZyb20gc2VsZWN0ZWQgbm9kZXMgYW5kIGVkZ2VzIG9wdGlvbiIqKiBhbmQgdGhlbiBsb2FkIHRoZSBwcm90ZWluLXByb3RlaW4gaW50ZXJhY3Rpb24gZGF0YSBmcm9tICoqU1RSSU5HLioqIE5vdGUgdGhhdCBvbmx5IHRoZSBzZWxlY3RlZCBub2RlcyBhcmUgc2hvd24gaW4gdGhlICoqVGFibGUgUGFuZWwqKi4NCg0KDQojIyMgYi4gKipTZWxlY3QgZ2VuZSBuYW1lcyBmcm9tIFRhYmxlIFBhbmVsLioqIA0KKiBTZWxlY3QgZXZlcnl0aGluZyBpbiB0aGUgKipuYW1lKiogY29sdW1uIGJ5IGNsaWNraW5nIGludG8gdGhlIGZpcnN0IGNlbGwgYW5kIHRoZW4gZHJhZ2dpbmcgZG93biB1bnRpbCB5b3UgZ2V0IHRvIHRoZSBib3R0b20uIFRoZW4sIGRvIGEgY29weSAqKihDb250cm9sLUMgb3IgQXBwbGUtQykuKioNCg0KKiAqKlBhc3RlIGdlbmUgbmFtZXMgaW50byBTVFJJTkcgbmV0d29yayBzZWFyY2gqKi4gDQo8YnI+PC9icj4NCg0KKiAqKlNldCBTVFJJTkcgc2VhcmNoIHBhcmFtZXRlcnMuKiogU2VhcmNoIG9ubHkgaGlnaCBxdWFsaXR5IHJlc3VsdHMgKDgwJSBjb25maWRlbmNlKSBhbmQgYWRkIDMwIGV4dHJhIHByb3RlaW5zIHRvIHRoZSBuZXR3b3JrLg0KPGJyPjwvYnI+DQoNCiMjIGMuICoqQ3JlYXRlIHRoZSBuZXR3b3JrLioqIA0KQ2xpY2sgb24gdGhlIHNlYXJjaCBpY29uIChtYWduaWZ5aW5nIGdsYXNzKSB0byBsb2FkIHRoZSBuZXR3b3JrLiBIb3cgZG9lcyB0aGUgbmV0d29yayBsb29rIGxpa2UuIA0KDQoqIFN0eWxlIHRoZSBuZXR3b3JrIHRvIHNob3cgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24uDQo8L2Rpdj4gPGJyPjwvYnI+DQoNCiMjICoqUmUtaW1wb3J0IGV4cHJlc3Npb24gZGF0YSoqLg0KRmlyc3QsIHdlIG5lZWQgdG8gcmUtaW1wb3J0IHRoZSBleHByZXNzaW9uIGRhdGEgZm9yIHRoZSBuZXcgbmV0d29yayBjcmVhdGVkIGJ5IHRoZSAqKnN0cmluZ0FwcC4qKiBTaW1pbGFyIHRvIHRoZSBpbml0aWFsIGltcG9ydCwgc3RhcnQgYnkgZG9pbmcgKipGaWxlIOKGkiBJbXBvcnQg4oaSIFRhYmxlIGZyb20gRmlsZS4qKiBBZ2Fpbiwgc2VsZWN0IHRoZSBCQ0xBLWFsbC50c3YgZmlsZS4gSG93ZXZlciwgbm93IHdlIG5lZWQgdG8gdXNlIGEgZGlmZmVyZW50IG5ldHdvcmsgY29sdW1uIHRvIG1hdGNoIG91ciBuYW1lcy4gQ2hhbmdlIHRoZSAqKktleSBDb2x1bW4gZm9yIE5ldHdvcms6KiogZnJvbSAqKnNoYXJlZCBuYW1lKiogdG8gKipxdWVyeSB0ZXJtKiouIFNUUklORyB1c2VzIEVuc2VtYmwgaWRlbnRpZmllcnMsIGJ1dCByZXRhaW5zIHRoZSBvcmlnaW5hbCBxdWVyeSB0ZXJtIHNvIHdlIGNhbiBtYXRjaCBkYXRhIGFnYWluc3QuIE5vdyBzZWxlY3QgKipPSy4qKg0KDQohW10oaW1hZ2VzL1JlX2ltcG9ydF9FeHByX0RhdGEucG5nKSA8YnI+PC9icj4NCg0KIyMgKipEaXNhYmxlIHN0cnVjdHVyZSBpbWFnZS4qKiANCioqU1RSSU5HKiogcHJvdmlkZXMgc29tZSBuaWNlIGltYWdlcyBvZiB0aGUgM0Qgc3RydWN0dXJlIG9mIHRoZSBwcm90ZWlucywgYnV0IHdlIG5lZWQgdG8gZGlzYWJsZSB0aG9zZSB0byBiZSBhYmxlIHRvIHNlZSBvdXIgZXhwcmVzc2lvbiB2YWx1ZXMgY2xlYXJseS4gRGlzYWJsZSB0aGUgaW1hZ2VzIGJ5IGdvaW5nIHRvICoqQXBwcyDihpIgU1RSSU5HIOKGkiAqKiB1bnRpY2sgKipzaG93IHN0cnVjdHVyZSBpbWFnZXMuKioNCg0KIyMgKipDcmVhdGUgY29sb3IgZ3JhZGllbnQgZm9yIGV4cHJlc3Npb24gZGF0YS4qKiANClRvIHNob3cgdGhlIGV4cHJlc3Npb24gZGF0YSwgZ28gdGhlICoqU3R5bGUqKiB0YWIgb2YgdGhlICoqQ29udHJvbCBQYW5lbCoqIGFuZCBjbGljayBvbiB0aGUgbWlkZGxlIHNxdWFyZSAqKihNYXAuKSoqIG9mIHRoZSAqKnRocmVlIEZpbGwgQ29sb3IgY29udHJvbHMuKiogU2V0IHRoZSBDb2x1bW4gdG8gIkNsdXN0ZXIgMSBNZWFuIGxvZzJGQyIgYW5kIHNldCB0aGUgKipNYXBwaW5nIFR5cGUqKiB0byAqKiJDb250aW51b3VzIE1hcHBpbmciKiouIERvdWJsZS1jbGljayBvbiB0aGUgZ3JhZGllbnQgdG8gc2hvdyB0aGUgKipDb250aW51b3VzIE1hcHBpbmcgRWRpdG9yKiouIFRoZSBkZWZhdWx0IGdyYWRpZW50IGlzIGEgQmx1ZS9SZWQgY29sb3IgZ3JhZGllbnQsIHdpdGggYmx1ZSByZXByZXNlbnRpbmcgdW5kZXJleHByZXNzZWQgZ2VuZXMgYW5kIHJlZCByZXByZXNlbnRpbmcgb3ZlcmV4cHJlc3NlZCBnZW5lcy4gV2UgY2FuIGtlZXAgdGhpcyBkZWZhdWx0IGdyYWRpZW50IGFzIGlzLg0KDQohW10oaW1hZ2VzL1N0eWxpbmdfU1RSSU5HLnBuZykgPGJyPjwvYnI+PGJyPjwvYnI+DQohW10oaW1hZ2VzL1N0eWxlX05vZGVfU1RSSU5HLnBuZykgPGJyPjwvYnI+DQoNCiA8YnI+PC9icj4NCg0KDQoNCiMgQWRkIHN0eWxpbmcgdG8gc2hvdyBtdXRhdGlvbnMNCg0KSW4gYWRkaXRpb24gdG8gZXhwcmVzc2lvbiBmb2xkIGNoYW5nZSwgdGhlIGltcG9ydGVkIGRhdGEgYWxzbyBpbmNsdWRlcyBpbmZvcm1hdGlvbiBhYm91dCBtdXRhdGlvbiwgYm90aCBhY3Jvc3MgYWxsIHBhdGllbnRzIGFuZCBzdWJkaXZpZGVkIGJ5IGNsdXN0ZXIuIEl0IG1pZ2h0IGJlIGluZm9ybWF0aXZlIHRvIGFkZCB0aGF0IGluZm9ybWF0aW9uIHRvIG91ciB2aXN1YWxpemF0aW9uLg0KDQojIyAqKkxvY2sgbm9kZSB3aWR0aCBhbmQgaGVpZ2h0LioqIA0KQnkgZGVmYXVsdCwgdGhlICoqc3RyaW5nQXBwKiogcHJvdmlkZXMgc2VwYXJhdGUgdmFsdWVzIGZvciBOb2RlIFdpZHRoIGFuZCBOb2RlIEhlaWdodC4gSW4gb3VyIGNhc2UsIHdlIGp1c3Qgd2FudCB0byBsb2NrIHRoZW0gdG8gYmUgdGhlIHNhbWUgc28gd2Ugb25seSBoYXZlIHRvIG1vZGlmeSB0aGUgTm9kZSBTaXplLiBUaGUgKipMb2NrIG5vZGUgd2lkdGggYW5kIGhlaWdodCoqIGlzIGEgY2hlY2tib3ggYXQgdGhlIGJvdHRvbSBvZiB0aGUgKipOb2RlKiogdGFiIGluIHRoZSAqKlN0eWxlKiogdGFiIG9mIHRoZSAqKkNvbnRyb2wgUGFuZWwqKi4gTWFrZSBzdXJlIHRoYXQgaXTigJlzIGNoZWNrZWQuDQoNCiMjICoqU2V0IHRoZSBkZWZhdWx0IG5vZGUgc2l6ZS4qKiANCkNsaWNrIG9uIHRoZSBsZWZ0bW9zdCAoRGVmLikgYm94IG5leHQgdG8gKipTaXplKiouIFNldCB0aGUgZGVmYXVsdCBzaXplIHRvICI0NS4wIi4NCiFbXShpbWFnZXMvTm9kZV9TaXplX1N0eWxlLnBuZykgDQo8YnI+PC9icj4NCjxicj48L2JyPg0KDQoNCiMjICoqTWFwIG11dGF0aW9uIHRvIG5vZGUgc2l6ZS4qKiANCkNsaWNrIG9uIHRoZSBtaWRkbGUgKE1hcC4pIGJveCBuZXh0IHRvICoqU2l6ZSoqLiBDaG9vc2UgIkNsdXN0ZXIgMSBNdXRhdGlvbnMiIGZvciB0aGUgQ29sdW1uIGFuZCAiQ29udGludW91cyBNYXBwaW5nIiBmb3IgdGhlICoqTWFwcGluZyBUeXBlKiouIFRoZW4gZG91YmxlLWNsaWNrIG9uIHRoZSByYW1wIHRoYXQgYXBwZWFycyB0byBicmluZyB1cCB0aGUgKipDb250aW51b3VzIE1hcHBpbmcgRWRpdG9yKiouIENsaWNrIG9uIHRoZSBsZWZ0bW9zdCB0cmlhbmdsZSBhbmQgc2V0IHRoZSAqKk5vZGUgU2l6ZSoqIHRvICI0NSIuIFRoZW4gY2xpY2sgb24gdGhlIHJpZ2h0LW1vc3QgdHJpYW5nbGUgYW5kIHNldCB0aGUgKipOb2RlIFNpemUqKiB0byAiOTAiLiBUaGVuIGNoZWNrICoqT0sqKi4NCg0KPGJyPjwvYnI+DQohW10oaW1hZ2VzL1N0eWxlX01hcHBpbmdfTXV0YXRpb24ucG5nKSANCjxicj48L2JyPg0KPGJyPjwvYnI+DQoNCg0KIyAqKkV4YW1pbmUgdGhlIG5ldHdvcmsuKiogDQpFeGFtaW5pbmcgdGhlIG1haW4gY29ubmVjdGVkIGNvbXBvbmVudCBvZiB0aGUgbmV0d29yaywgd2UgaW1tZWRpYXRlbHkgc2VlIHRoYXQgdGhlcmUgaXMgYSBncm91cCBvZiBvdmVyZXhwcmVzc2VkIGdlbmVzLCAqKkNPTDZBMywgQ09MMUExLCBDT0wxQTIsIGV0Yy4qKiwgdGhhdCBhbHNvIGV4aGliaXQgc29tZSBtdXRhdGlvbnMuIFRoZXJlIGlzIGFsc28gYSBncm91cCBvZiBnZW5lcywgKipNTVA3LCBNTVA5LCBUSU1QNCBhbmQgTU1QMioqIHRoYXQgc2hvdyBzb21lIG1peGVkIGV4cHJlc3Npb24gY2hhbmdlcy4gRmluYWxseSwgdGhlcmUgaXMgYSBncm91cCBvZiBnZW5lcywgaW5jbHVkaW5nICoqTkNBTiwgQkNBTiBTREMzLCBhbmQgR0FCQlIxKiosIGluIGJldHdlZW4gdGhlc2UgZ3JvdXBzIHRoYXQgc2hvdyBwcmVkb21pbmFudGx5IHVuZGVyZXhwcmVzc2lvbi4NCiFbXShpbWFnZXMvU3R5bGVfU1RSSU5HX0dlbmVzLnBuZykgDQoNCjxicj48L2JyPg0KPGJyPjwvYnI+DQoNCiMjIEF0IHRoaXMgcG9pbnQgaW4gb3VyIHdvcmtmbG93LCB3ZSBoYXZlIHNvbWUgb3B0aW9uczoNCg0KT25lIHR5cGljYWwgcGF0aCBtaWdodCBiZSB0byBmaW5kIGFsbCBvZiB0aGUgb3ZlcmV4cHJlc3NpbmcgZ2VuZXMsIHVzZSB0aGUgRGlmZnVzaW9uIGFwcCB0byBwZXJmb3JtIGhlYXQgZGlmZnVzaW9uIHRocm91Z2ggdGhlIG5ldHdvcmsgdG8gZ3JvdyB0aGUgc2VsZWN0aW9uIGFuZCB0aGVuIHBlcmZvcm0gZnVuY3Rpb25hbCBlbnJpY2htZW50IGFuYWx5c2lzIG9uIHRoYXQgc2V0IG9mIGdlbmVzIGFuZCB0aGVuIHJlcGVhdCBmb3IgdW5kZXJleHByZXNzaW5nIGdlbmVzIChzZWUgc3RlcCAqKlNtb290aCB0aGUgbmV0d29yayB1c2luZyBEaWZmdXNpb24qKiBiZWxvdykuDQoNCkFub3RoZXIgYXBwcm9hY2ggaXMgc3VnZ2VzdGVkIGJ5IHRoZSB0b3BvbG9neSBvZiB0aGUgbmV0d29yaywgd2hpY2ggc3Ryb25nbHkgc3VnZ2VzdHMgZ3JvdXBpbmdzIGluIHRoZSBpbnRlcmFjdGlvbnMuIFdlIGNhbiB1c2UgY2x1c3RlcmluZyBiYXNlZCBvbiB0aGUgbmV0d29yayB0b3BvbG9neSBhbmQgdG8gcGVyZm9ybSBmdW5jdGlvbmFsIGVucmljaG1lbnQgb24gZWFjaCBjbHVzdGVyIChzZWUgc3RlcCAqKlRvcG9sb2dpY2FsbHkgY2x1c3RlciB0aGUgbmV0d29yayoqKS4gV2XigJlsbCB0YWtlIGVhY2ggb2YgdGhvc2UgaW4gdHVybnMuDQoNCiMgU21vb3RoIHRoZSBuZXR3b3JrIHVzaW5nIERpZmZ1c2lvbi4NCldoZW4gd2UgY3JlYXRlZCB0aGUgKipTVFJJTkcqKiBuZXR3b3JrLCB3ZSBhZGRlZCBub2RlcyB0byBtYWtlIHN1cmUgdGhhdCB3ZWxsIGNvbm5lY3RlZCBub2RlcyB0aGF0IG1pZ2h0IGJlIHNpbGVudCAoaS5lLiBub3QgZXhoaWJpdCBjaGFuZ2VzIGluIGV4cHJlc3Npb24pIGNvdWxkIGJlIGluY2x1ZGVkLiBXZWxsIGNvbm5lY3RlZCBnZW5lcyBtaWdodCBwbGF5IGEgc2lnbmlmaWNhbnQgcm9sZSBpbiB0aGUgYmlvbG9neSBldmVuIGlmIHRoZWlyIGV4cHJlc3Npb24gZG9lc27igJl0IGNoYW5nZSBkdWUgdG8gY2hhbmdlcyBpbiB0aGUgZXhwcmVzc2lvbiBvZiB0aGVpciBpbnRlcmFjdGlvbiBwYXJ0bmVycy4gVGhlIERpZmZ1c2lvbiBhcHAgc3VwcG9ydHMgdGhlIGFiaWxpdHkgdG8gZmluZCB0aG9zZSBnZW5lcyBieSBzaW11bGF0aW5nIHRoZSBkaWZmdXNpb24gb2YgaGVhdCB0aHJvdWdoIG5ldHdvcmsgY29ubmVjdGlvbnMuDQoNCiMjIENyZWF0ZSBzdWJuZXR3b3JrIG9mIHRoZSBtYWluIGNvbm5lY3RlZCBjb21wb25lbnQuIA0KU2VsZWN0IGFsbCBvZiB0aGUgbm9kZXMgYW5kIGVkZ2VzIGluIHRoZSBtYWluIGNvbm5lY3RlZCBjb21wb25lbnQgYnkgaG9sZGluZyBtb3VzZSBidXR0b24gMSBkb3duIGFuZCBzd2VlcGluZyBvdmVyIHRoZSBub2Rlcy4gQWx0ZXJuYXRpdmVseSwgeW91IGNvdWxkIHNlbGVjdCBhIHNpbmdsZSBub2RlIGFuZCB0aGVuIHJlcGVhdGVkbHkgaGl0dGluZyAqKkNvbnRyb2wtNiAob3Ig4oyYNiBvbiB0aGUgTWFjKSoqIHRvIGNvbnRpbnVhbGx5IHNlbGVjdCB0aGUgZmlyc3QgbmVpZ2hib3JzIG9mIHNlbGVjdGVkIG5vZGVzIHVudGlsIGFsbCBvZiB0aGUgbm9kZXMgaW4gdGhlIGNvbm5lY3RlZCBjb21wb25lbnQgYXJlIHNlbGVjdGVkLiBPbmNlIHRoZSBlbnRpcmUgY29tcG9uZW50IGlzIHNlbGVjdGVkLCBjcmVhdGUgYSBuZXcgbmV0d29yayBieSBkb2luZyAqKkZpbGUg4oaSIE5ldyBOZXR3b3JrIOKGkiBGcm9tIFNlbGVjdGVkIE5vZGVzLCBBbGwgRWRnZXMuKioNCg0KIyMgU2VsZWN0IG92ZXJleHByZXNzZWQgZ2VuZXMuIA0KR28gYmFjayB0byB0aGUgKipGaWx0ZXIgdGFiICoqIGFuZCBkaXNhYmxlIChjbGljayBvbiB0aGUgWCkgdGhlIGZpbHRlciBmb3IgdW5kZXJleHByZXNzZWQgZ2VuZXMsIHRoZW4gY2xpY2sgKipBcHBseSoqLg0KDQojIyBEaWZmdXNlIHRoZSBzZWxlY3Rpb24uIA0KSW4gdGhlIGRpZmZ1c2lvbiBhcHAgd2UgY2FuIGRpZmZ1c2UgZWl0aGVyIGJhc2VkIG9uIHRoZSBoZWF0IChjb2x1bW4gdmFsdWUpIG9yIGp1c3QgYmFzZWQgb24gdGhlIHNlbGVjdGlvbi4gV2XigJlyZSBnb2luZyB0byBkaWZmdXNlIGJhc2VkIG9uIG91ciBleHByZXNzaW9uIHZhbHVlcywgc28gKipzZWxlY3QgVG9vbHMg4oaSIERpZmZ1c2Ug4oaSIFNlbGVjdGVkIE5vZGVzIHdpdGggT3B0aW9ucyoqIGFuZCBpbiB0aGUgZGlhbG9nIHNlbGVjdCAqKiJDbHVzdGVyIDEgTWVhbiBsb2cyRkMiKiogYXMgdGhlICoqSGVhdCBDb2x1bW4qKiBhbmQgc2V0IGEgc2hvcnQgdGltZSBvZiAqKjAuMDAxIHNlY29uZHMqKi4gVGhlbiBjbGljayAqKk9LLioqDQoNCiFbXShpbWFnZXMvRGlmZnVzZV9wYXJhbS5wbmcpIA0KDQo8YnI+PC9icj4NCg0KIyMgQ3JlYXRlIHN1Ym5ldHdvcmsuIA0KKiBDaGFuZ2UgdGhlICoqTm9kZSBSYW5rKiogdG8gYWJvdXQgNDAgYW5kIGNyZWF0ZSBhIHN1Ym5ldHdvcmsgYnkgKipzZWxlY3RpbmcgRmlsZSDihpIgTmV3IE5ldHdvcmsg4oaSIEZyb20gU2VsZWN0ZWQgTm9kZXMsIEFsbCBFZGdlcy4qKiANCg0KIVtdKGltYWdlcy9Ob2RlX1JhbmtfRGlmZnVzaW9uX091dHB1dC5wbmcpIA0KPGJyPjwvYnI+PGJyPjwvYnI+PGJyPjwvYnI+DQoqIE9uY2UgdGhlIG5ldHdvcmsgaXMgY3JlYXRlZCwgZXhlY3V0ZSBhbiB1bndlaWdodGVkIFByZWZ1c2UgRm9yY2UgRGlyZWN0ZWQgTGF5b3V0ICoqKExheW91dCDihpIgUHJlZnVzZSBGb3JjZSBEaXJlY3RlZCBMYXlvdXQg4oaSIEFsbCBOb2RlcyAobm9uZSkpKiouDQo8YnI+PC9icj48YnI+PC9icj4NCiFbXShpbWFnZXMvTGF5b3V0LUZvcmVEaXJlY3RlZC5wbmcpIA0KDQo8YnI+PC9icj4NCg0KKiAqKlJlcGVhdCBmb3IgdW5kZXJleHByZXNzZWQgZ2VuZXMuKiogRm9yIHVuZGVyZXhwcmVzc2VkIGdlbmVzLCByZXBlYXQgdGhlIHByZXZpb3VzIHN0ZXBzIGFib3ZlLCBleGNlcHQgY2hvb3NlIGFsbCBnZW5lcyB3aXRoIGEgKioiQ2x1c3RlciAxIE1lYW4gbG9nMkZDIioqIGxlc3MgdGhhbiAqKi0xKiogYW5kIGluIHRoZSBkaWZmdXNpb24gYXBwIHNldCB0aGUgdGltZSB0byAwLjAxIHNlY29uZHMuIFVuZm9ydHVuYXRlbHkgdGhlIERpZmZ1c2lvbiBPdXRwdXQgYXNzdW1lcyBwb3NpdGl2ZSBkaWZmdXNpb24gdmFsdWVzLCBzbyB0byBzZWxlY3QgdGhlIGRpZmZ1c2VkIG5vZGVzIG9mIGludGVyZXN0LCB5b3XigJlsbCBuZWVkIHRvIGdvIHRvIHRoZSBUYWJsZSBQYW5lbCBhbmQgc29ydCB0aGUgZGlmZnVzaW9uX291dHB1dF9oZWF0IGNvbHVtbiwgc2VsZWN0IHRoZSBuZWdhdGl2ZSB2YWx1ZXMgbGVzcyB0aGFuICoqLTAuNSoqLCByaWdodC1jbGljayBvbiB0aGUgY29sdW1uIGFuZCBzZWxlY3QgU2VsZWN0IG5vZGVzIGZyb20gc2VsZWN0ZWQgcm93cy4gVGhlbiB5b3UgY2FuIGNyZWF0ZSB0aGUgc3VibmV0d29yay4NCjxicj48L2JyPjxicj48L2JyPg0KDQoNCiFbXShpbWFnZXMvRGlmZnVzaWlvbl9IZWF0X3VuZGVyZXhwLnBuZykgDQoNCjxicj48L2JyPjxicj48L2JyPg0KDQojIyBQZXJmb3JtIGVucmljaG1lbnQgYW5hbHlzaXMgb24gdGhlIGRpZmZ1c2VkIHN1Ym5ldHdvcmtzLiANCg0KVGhlcmUgYXJlIG1hbnkgdG9vbHMgYXZhaWxhYmxlIGluICoqQ3l0b3NjYXBlKiogdG8gcGVyZm9ybSBmdW5jdGlvbmFsIGVucmljaG1lbnQuIEZvciBzaW1wbGljaXR5IHdl4oCZcmUgZ29pbmcgdG8gdXNlIHRoZSBidWlsdC1pbiAqKmZ1bmN0aW9uYWwgZW5yaWNobWVudCoqIGF2YWlsYWJsZSBmcm9tIHRoZSBzdHJpbmdBcHAuIFRoZSBkZXNjcmlwdGlvbiBiZWxvdyB3YWxrcyB0aHJvdWdoIGNhbGN1bGF0aW5nIGZ1bmN0aW9uIGVucmljaG1lbnQgb2YgdGhlIG92ZXJleHByZXNzZWQgc3VibmV0d29yaywgYnV0IHRoZSBzYW1lIGFwcHJvYWNoIHdpbGwgd29yayBmb3IgdGhlIHVuZGVyZXhwcmVzc2VkIG5ldHdvcmsuDQoNCiogKipTZXQgbmV0d29yayBhcyBhIFNUUklORyBuZXR3b3JrLioqIEluIG9yZGVyIHRvIHJldHJpZXZlIHRoZSBmdW5jdGlvbiBlbnJpY2htZW50IHNjb3JlcyB0aGUgc3RyaW5nQXBwIG5lZWRzIHRvIGJlIHRvbGQgdGhhdCB0aGlzIGlzIGEgU1RSSU5HIG5ldHdvcmsuIEEgbWVudSBpdGVtIGlzIGF2YWlsYWJsZSBmb3IgdGhhdCBwdXJwb3NlOiAqKkFwcHMg4oaSIFNUUklORyDihpIgU2V0IGFzIFNUUklORyBuZXR3b3JrLioqDQoNCg0KIVtdKGltYWdlcy9TZXRTdHJpbmdfTmV0d29yay5wbmcpIA0KPGJyPjwvYnI+PGJyPjwvYnI+DQoqICoqUmV0cmlldmUgZnVuY3Rpb25hbCBlbnJpY2htZW50IG9mIGEgY29tcG9uZW50LioqIEluIHRoZSBzdWJuZXR3b3JrLCB0aGVyZSBhcmUgdHdvIGNvbm5lY3RlZCBjb21wb25lbnRzIG9mIGFueSBzaXplLiBTZWxlY3QgYWxsIG9mIHRoZSBub2RlcyBpbiB0aGUgbGFyZ2VzdCBvbmUgYW5kIHJldHJpZXZlIHRoZSBmdW5jdGlvbmFsIGVucmljaG1lbnQgdGhyb3VnaCB0aGUgKipBcHBzIOKGkiBTVFJJTkcg4oaSIFJldHJpZXZlIGZ1bmN0aW9uYWwgZW5yaWNobWVudC4qKiBUaGlzIHdpbGwgYnJpbmcgdXAgYSBuZXcgVGFibGUgUGFuZWwgdGFiIGZvciAqKuKAnFNUUklORyBFbnJpY2htZW504oCdKiouDQoNCiogVGhlcmUgaXMgYSBmaWx0ZXIgaWNvbiB3aGljaCBicmluZyB1cCBhIG1lbnUgdG8gc3dpdGNoIHRoZSBvbnRvbG9neSBvciBwYXRod2F5IGRpc3BsYXllZC4gSW4gdGhlIGNhc2Ugb2YgdGhlIGxhcmdlc3QgY29tcG9uZW50LCB3ZSBzZWUgdGhhdCB0aGVyZSBpcyBhIHNpZ25pZmljYW50IG92ZXJleHByZXNzaW9uIG9mIGdlbmVzIGludm9sdmVkIGluIHRoZSAqKkdPIEJpb2xvZ2ljYWwgUHJvY2Vzc2VzOioqIGV4dHJhY2VsbHVsYXIgbWF0cml4IG9yZ2FuaXphdGlvbiwgY29sbGFnZW4gY2F0YWJvbGljIHByb2Nlc3MsIGFuZCBvdGhlciBkZXZlbG9wbWVudCBwcm9jZXNzZXM7IHRoZXkgYXJlIGFsc28gYXNzb2NpYXRlZCB3aXRoIHRoZSBLRUdHIHBhdGh3YXlzIFByb3RlaW4gZGlnZXN0aW9uIGFuZCBhYnNvcnB0aW9uIGFuZCBFQ00tcmVjZXB0b3IgaW50ZXJhY3Rpb24uDQoNCg0KIVtdKGltYWdlcy9TVFJJTkdfRW5yaWNobWVudC5wbmcpIA0KDQo8YnI+PC9icj48YnI+PC9icj4NCg0KDQo8ZGl2IGNsYXNzPSJleGVyY2lzZSI+DQojIyBFeGVyY2lzZToNCiogKipSZXBlYXQgZm9yIHVuZGVyZXhwcmVzc2VkIG5ldHdvcmsuKioNCg0KKiBBbHNvIGNvbG9yIHRoZSBub2RlcyBiYXNlZCBvbiB0aGUgZnVuY3Rpb25hbGx5IGVucmljaGVkIHZhbHVlcy4gRm9yIGV4YW1wbGUgKioiRUNNLVBhdGh3YXlzIioqLCBldGMuIA0KPC9kaXY+DQoNCg0KIyBUb3BvbG9naWNhbGx5IGNsdXN0ZXIgdGhlIG5ldHdvcmsuIA0KDQpMb29raW5nIGF0IHRoZSBwcm90ZWluLXByb3RlaW4gaW50ZXJhY3Rpb24gbmV0d29yayAoYmVsb3cpLCB3ZSBzZWUgdGhhdCB0aGVyZSBhcHBlYXIgdG8gYmUgc3Ryb25nIGNvbm5lY3Rpb25zIGJldHdlZW4gZ3JvdXBzIG9mIG5vZGVzIChzZWUgZGlzY3Vzc2lvbiBpbiAqKiJBZGRpbmcgc3R5bGluZyB0byBzaG93IG11dGF0aW9ucyIqKiBhYm92ZSkuIE9uZSBhcHByb2FjaCB0byBleHBsb3JlIHRoZSBmdW5jdGlvbmFsIGludGVyYWN0aW9ucyBvZiB0aGUgbmV0d29yayBpcyB0byB1c2UgYSB0b3BvbG9naWNhbCBjbHVzdGVyaW5nIGFsZ29yaXRobSB0byBwYXJ0aXRpb24gdGhlIG5ldHdvcmsgYmFzZWQgb24gdGhlIGludGVyYWN0aW9ucy4gVGhlIGNsdXN0ZXJNYWtlcjIgYXBwIHByb3ZpZGVzIGEgc2V0IG9mIHRvcG9sb2dpY2FsIChuZXR3b3JrKSBjbHVzdGVyIGFsZ29yaXRobXMuIE9uZSBjb21tb25seSB1c2VkIG9uZSBpcyBNQ0wsIHdoaWNoIHBlcmZvcm1zIGEgTWFya292LWJhc2VkIGZsb3cgc2ltdWxhdGlvbiB0byBkZXRlcm1pbmUgY2x1c3RlcnMuDQoNCiFbXShpbWFnZXMvVG9wb2xvZ3lfQ2x1c3Rlci5wbmcpIA0KDQo8YnI+PC9icj48YnI+PC9icj4NCg0KKiAqKkNsdXN0ZXIgdXNpbmcgTUNMKiouIE1ha2Ugc3VyZSB0aGUgbmV0d29yayBpcyBjb25uZWN0ZWQsIHRoZW4gZ28gdG8gKipBcHBzIOKGkiBjbHVzdGVyTWFrZXIgQ2x1c3RlciBOZXR3b3JrIOKGkiBNQ0wgQ2x1c3RlcioqLiANCg0KDQohW10oaW1hZ2VzL01DTF9DbHVzdGVyT3B0aW9ucy5wbmcpIA0KPGJyPjwvYnI+PGJyPjwvYnI+DQoNCiogVGhpcyB3aWxsIGJyaW5nIHVwIHRoZSBNQ0wgc2V0dGluZ3MgZGlhbG9nLiBUaGVyZSBhcmUgYSBudW1iZXIgb2Ygb3B0aW9ucywgYnV0IG1vc3Qgb2YgdGhlc2UgZG9u4oCZdCByZXF1aXJlIGFueSBjaGFuZ2VzIGZvciBvdXIgdXNlcy4gV2XigJlyZSBnb2luZyB0byB0cmVhdCB0aGUgbmV0d29yayBhcyB1bndlaWdodGVkIHNvIHdlIGRvbuKAmXQgbmVlZCB0byBwcm92aWRlIGFueSBBcnJheSBTb3VyY2VzLiBXZSBkbyB3YW50IHRvIGNoZWNrIHRoZSAqKkNyZWF0ZSBuZXcgY2x1c3RlcmVkIG5ldHdvcmsqKiBob3dldmVyIHNvIHdlIGNhbiB2aXN1YWxpemUgdGhlIHJlc3VsdHMuIFRoZW4gY2xpY2sgKipPSyoqLg0KDQoNCiMgRGV0ZXJtaW5lIGZ1bmN0aW9uYWwgZW5yaWNobWVudCBvZiB0aGUgY2x1c3RlcnMuDQpUaGUgcmVzdWx0cyBvZiB0aGUgY2x1c3RlcmluZyBzaG91bGQgbG9vayBzb21ldGhpbmcgbGlrZSB0aGUgZmlndXJlIGJlbG93LCB3aGljaCBpcyBhIGNsb3NlLXVwIG9mIHRoZSBsYXJnZXN0IGNvbXBvbmVudHMuIE9mIHBhcnRpY3VsYXIgaW50ZXJlc3QgYXJlIHRoZSBsYXJnZXN0IDQgY29tcG9uZW50cywgd2hpY2ggd2XigJlsbCBwZXJmb3JtIGZ1bmN0aW9uYWwgZW5yaWNobWVudC4NCiAgDQogIA0KIVtdKGltYWdlcy9DbHVzdGVyZWRfdG9wb2xvZ3lfbmV0d29yay5wbmcpIA0KPGJyPjwvYnI+PGJyPjwvYnI+DQoNCiogKipTZXQgbmV0d29yayBhcyBhIFNUUklORyBuZXR3b3JrLioqIFRoZSBmaXJzdCBzdGVwIGlzIHRvIGluZm9ybSB0aGUgKipzdHJpbmdBcHAqKiB0aGF0IHRoaXMgaXMgYSBTVFJJTkctZGVyaXZlZCBuZXR3b3JrLiBBIG1lbnUgaXRlbSBpcyBhdmFpbGFibGUgZm9yIHRoYXQgcHVycG9zZTogKipBcHBzIOKGkiBTVFJJTkcg4oaSIFNldCBhcyBTVFJJTkcgbmV0d29yay4qKg0KKiAqKlJldHJpZXZlIGZ1bmN0aW9uYWwgZW5yaWNobWVudCBvZiBhIGNvbXBvbmVudC4qKiBJbiB0aGUgc3VibmV0d29yaywgdGhlcmUgYXJlIGZvdXIgY29ubmVjdGVkIGNvbXBvbmVudHMgb2YgYW55IHNpemUuIFNlbGVjdCBhbGwgb2YgdGhlIG5vZGVzIGluIHRoZSBzZWNvbmQgbGFyZ2VzdCBvbmUgKHRoZSBvbmUgd2l0aCBhIG51bWJlciBvZiBvdmVyZXhwcmVzc2VkIGdlbmVzIGFuZCB0aGUgYnVsayBvZiB0aGUgbXV0YXRpb25zKSBhbmQgcmV0cmlldmUgdGhlIGZ1bmN0aW9uYWwgZW5yaWNobWVudCB0aHJvdWdoIHRoZSAqKkFwcHMg4oaSIFNUUklORyBFbnJpY2htZW50IOKGkiBSZXRyaWV2ZSBmdW5jdGlvbmFsIGVucmljaG1lbnQuKiouDQoNCg0KIVtdKGltYWdlcy9TdHJpbmctcmV0RnVuY0VucmljaC5wbmcpIA0KPGJyPjwvYnI+PGJyPjwvYnI+DQoNCiogVGhpcyB3aWxsIGJyaW5nIHVwIGEgbmV3IFRhYmxlIFBhbmVsIHRhYiBmb3IgKipTVFJJTkcgRW5yaWNobWVudC4qKiBUaGVyZSBpcyBhIHB1bGwtZG93biBtZW51IHRoYXQgc3dpdGNoZXMgdGhlIG9udG9sb2d5IG9yIHBhdGh3YXkgZGlzcGxheWVkLiBMb29raW5nIGF0IHRoZSByZXN1bHRzIHdlIHNlZSB0aGF0IHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgb3ZlcmV4cHJlc3Npb24gb2YgZ2VuZXMgaW52b2x2ZWQgaW4gdGhlIEdPIEJpb2xvZ2ljYWwgUHJvY2Vzc2VzOiBleHRyYWNlbGx1bGFyIG1hdHJpeCBvcmdhbml6YXRpb24sIGNvbGxhZ2VuIGNhdGFib2xpYyBwcm9jZXNzLCBhbmQgb3RoZXIgZGV2ZWxvcG1lbnQgcHJvY2Vzc2VzOyB0aGV5IGFyZSBhbHNvIGFzc29jaWF0ZWQgd2l0aCB0aGUgS0VHRyBwYXRod2F5cyBJTC0xNyBTaWduYWxpbmcgUGF0aHdheSBhbmQgYWJzb3JwdGlvbiwgUEkzSy1BS1QgU2lnbmFsaW5nIHBhdGh3YXkgYW5kIEVDTS1yZWNlcHRvciBpbnRlcmFjdGlvbi4NCg0KIVtdKGltYWdlcy9UYWJsZVBhbmUtRnVuY0VucmljaG1lbnQucG5nKSANCjxicj48L2JyPjxicj48L2JyPg0KDQo8ZGl2IGNsYXNzPSJleGVyY2lzZSI+DQojIyBFeGVyY2lzZToNCiogKipSZXBlYXQgZm9yIHVuZGVyZXhwcmVzc2VkIG5ldHdvcmsuKioNCg0KKiBBbHNvIGNvbG9yIHRoZSBub2RlcyBiYXNlZCBvbiB0aGUgZnVuY3Rpb25hbGx5IGVucmljaGVkIHZhbHVlcy4gRm9yIGV4YW1wbGUgKioiRUNNLVBhdGh3YXlzIioqLCBldGMuIA0KPC9kaXY+DQoNCg0KDQo8YnI+DQo8L2JyPg0KDQoNCg0KIyMgTmV4dCBTZXNzaW9uOiANCg0KPGRpdiBjbGFzcz0iaW5mb3JtYXRpb24iPg0KKiBJbiB0aGUgbmV4dCBzZXNzaW9uICoqU2Vzc2lvbiAzKiosIHdlIHdpbGwgbGVhcm4gbW9yZSBvbiBob3cgdG8gcGVyZm9ybSBwYXRod2F5IGVucmljaG1lbnQgYnkgY29tcGFyaW5nIGdlbmUgc2V0cy9ncm91cHMgKCoqYS5rLmEgR1NFQSoqKSB1c2luZyB0aGUgZmxhdm9ycyBmcm9tICoqQ2x1ZUdPKiogYW5kICoqQ2x1ZVBlZGlhKiogKGJvdGggQ3l0b3NjYXBlIHBsdWdpbnMpIGFuZCBob3cgdG8gY3JlYXRlIHZpc3VhbGl6YXRpb25zIHVzaW5nIHJlc3VsdHMgZm9yIHBlZXItcmV2aWV3IHB1YmxpY2F0aW9ucyBhbmQgZ3JhbnQgYXBwbGljYXRpb25zLiANCjwvZGl2Pg0KDQo8YnI+DQo8L2JyPjxicj4NCjwvYnI+DQoNCiMjIyBXZSB3aWxsIG5vdyBnbyB0byB0aGUgbmV4dCBbU2Vzc2lvbiAoMyldKHNlc3Npb24zLm5iLmh0bWwpIHRvIHdvcmsgd2l0aCBpbnRlZ3JhdGluZyBwYXRod2F5IHJlc291cmNlcyB1c2luZyBDbHVlR08gYW5kIENsdWVQZWRpYS4gICANCg==