BUsinesss Process Analytics with R (BUPAR)
Introducing dataset
For this exercise, I have used production data from 4TU data repository. Data is available here
[1] "Case.ID" "Activity" "Resource" "Start.Timestamp"
[5] "Complete.Timestamp" "Span" "Work.Order..Qty" "Part.Desc."
[9] "Worker.ID" "Report.Type" "Qty.Completed" "Qty.Rejected"
[13] "Qty.for.MRB" "Rework"
The column names from the above data need to be mapped to the standard event log nomenclature. This is done by using the event log creating command. The standard nomencalture includes following column inputs
- case_id - which is a unique identifier for the whole process sequence,
- activity_id - a description on the individual activity within a process,
- activity_instance_id - which instances of activity should be treated as different from others,
- lifecycle_id - status/outcome of the process,
- timestamp - time at which logging was done,
- resource_id - machine/individual responsible for the instance of the process/activity.
However, before that the date time data needs to be brought to a proper date time format. For this, lubridate library is used.
At this point, an activity instance is added to the logs and an event log is created.
prod_data_with_instance<- prod_data %>%
group_by(Case.ID) %>%
mutate(activity_instance = as.character(row_number()))
prod_event = prod_data_with_instance %>%
eventlog(
case_id = "Case.ID",
activity_id = "Activity",
activity_instance_id = "activity_instance",
lifecycle_id = "Rework",
timestamp = "Complete.Timestamp",
resource_id = "Worker.ID"
)
prod_event %>% n_activities
[1] 55
prod_event %>% n_cases
[1] 225
prod_event %>% n_traces
[1] 221
prod_event %>% n_resources
[1] 49
There are a total of 55 activities, carried out for 225 cases, in 221 unique ways (traces) by 49 resources.
Activity Understanding & Analysis
Let us start what different level of activities are present and their relative frequency
activity_data<- prod_event %>%
activity_frequency(level = "activity")
activity_data_reduced<- activity_data[activity_data$relative>0.02,]
(plot(activity_data_reduced))

This shows that final inspection is the highest frequency activity, which is to be expected. After which the turning and milling quality checks are also high. Lapping and packaging follow up.
Visualizing process maps
Let us start by viewing one of the process maps.
event_reduced<- prod_event[prod_event$Case.ID %in% c("Case 1"),]
event_reduced %>% process_map(type = frequency("relative"))
This shows for one of the cases, how the steps involved in the process play out. As we add more data, we can start to see some of the possible iterations in the process play out. It appears that the steps for this case are 1. Turning and milling 2. Turning and milling Q.C 3. Laser Marking 4. Lapping 5. Round grinding 6. Final Inspection 7. Packing
Self loops represent that more than one logging of the same activity is observed, which might be due to error messages or logging discrepancy.
If we add two more cases to this, more insights start to appear, see below plot for 3 cases.
event_reduced<- prod_event[prod_event$Case.ID %in% c("Case 1","Case 111","Case 104"),]
event_reduced %>% process_map(type = frequency("relative"))
It is clear that one of the cases (1/3) went for turning rather than turning and milling, which also increased a turning Q.C point
Above plot also shows that about 20% of the components directly go from laser marking to end, 8% go from turning to end while about 20% go through the lapping and griding operation before going to packing and then ending.
If we add few more cases to the above plot, it starts to get cumbersome to understand.
Similar to process maps, resource maps are also another way of understanding flow.
event_reduced<- prod_event[prod_event$Case.ID %in% c("Case 1","Case 111","Case 104"),]
event_reduced %>% filter_trace_frequency(percentage = 0.2) %>% resource_map(type = frequency("absolute"))
There are further ways available for exploring processes.
Precedence Matrix
Another way to visualize the process is precdence matrix which shows which steps tend to happen together. In this case since logging seems to have duplication in activity, the plot is not very insightful.

Resource & activity Analysis
Resource specialization and utilization is another key activity which can be helped by process analytics
prod_event %>%
resource_specialisation("resource") %>% plot()

The above plot for instance shows that ID4932 and ID0937 are generalists, performing upto 15 activity types, ID3641, ID3719 are specialists.
prod_event %>%
resource_specialisation("activity") %>% plot()

Final inspection, packing, lapping, round griding and turning Q.C are specialized activities perfomred only by one resource.
In terms of activities, it would also be useful to understand which activities are always performed, and which are rare.
prod_event %>% activity_presence() %>% plot()

Trace analysis
Trace length and plots are used to see how much variation is there across cases.
prod_event %>% trace_length() %>% plot()

prod_event %>% trace_length()
min q1 median mean q3 max st_dev iqr
1.00000 8.00000 14.00000 20.19111 23.00000 175.00000 20.93024 15.00000
The plot shows that on an average, 75% of cases have between 8-23 steos, although a maximum of 175 steps have been observed as well. Median number of steps is 14, and average number of steps is 20.
Do all activities start and end at the same points? This can be visualized using bar plots as well
start_activities(prod_event, level = "activity") %>% plot()

While turning and milling seems to be the first operation, machine 6 sees highest rate of starting points.

As expected, most operations end with final inspection or packing.

The above plot shows how many cases can be described with a relatively small number of traces indicating the consistency in the process. Here we have seen that for 225 cases, as high as 221 traces exist, so there is just less consistency. However, this is due to machine number being part of activity description, which means that similar steps are also treated differently.
Consolidation of activities
Consolidation of activities allows relabeling and further high level view of the process.
event_reduced<- prod_event_united[prod_event_united$Case.ID %in% c("Case 1","Case 111","Case 104"),]
event_reduced %>% filter_trace_frequency(percentage = 0.8) %>% process_map(type = frequency("absolute"))
The 10% most infrequent traces are plotted below with united data.
prod_event_united %>% trace_explorer(coverage = 0.1, type = "infrequent")

LS0tDQp0aXRsZTogIlByb2Nlc3MgTWluaW5nIC0gUHJpbWVyIg0KYXV0aG9yOiAiUm9oaXQgUHJ1dGhpIC0gUjJETCINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50Og0KICAgIGRmX3ByaW50OiBwYWdlZA0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KYWx3YXlzX2FsbG93X2h0bWw6IHllcw0KLS0tDQoNCiMjIyBNb3RpdmF0aW9uIGZvciBzdHVkeWluZyBwcm9jZXNzIG1pbmluZw0KDQo8c3R5bGU+DQpib2R5IHsNCnRleHQtYWxpZ246IGp1c3RpZnl9DQo8L3N0eWxlPg0KDQojIyMjIFByb2Nlc3MgRGF0YSBpcyB1YmlxdWl0b3VzDQpFdmVyeSBidXNpbmVzcyBlbXBsb3lzIHByb2Nlc3NlcyBhbmQgY29sbGVjdHMgaW5mb3JtYXRpb24gcmVnYXJkaW5nIHZhcmlvdXMgYWN0aXZpdGllcywgYmUgaXQgc2FsZXMgJiBwcm9jdXJlbWVudCBvciByZWNydWl0bWVudCBvciBzZXJ2aWNlIHdvcmtmbG93cy4gSXQgaXMgaW1wZXJhdGl2ZSB0byB1c2Ugd29yayBmbG93cyAod2hldGhlciBtYW51YWwgb3IgSVQgZW5hYmxlZCkgdG8gdHJhY2sgdGhlc2UgcHJvY2Vzc2VzLiANCg0KIyMjIyBUaGVyZSBhcmUgdW5yZXNvbHZlZCBjb25jZXJucyBpbiBwcm9jZXNzIG1hbmFnZW1lbnQNCkluIHRlcm1zIG9mIGJ1c2luZXNzIHByb2Nlc3MgbWFuYWdlbWVudCwgdHdvIGtleSBxdWVzdGlvbnMgaGF2ZSBsb25nIHRyb3VibGVkIHRoZSBzdGFrZWhvbGRlcnMgc2luY2UgaW5jZXB0aW9uIG9mIGJ1c2luZXNzIHByb2Nlc3Nlcy4gDQoNCiogVGhlIGZpcnN0IG9mIHRoZXNlIGlzIHRoZSBjcmVhdGlvbiBvZiAiY3VycmVudCBzdGF0ZSIgcHJvY2Vzc2VzLiBNb3N0IHByb2Nlc3MgZXhlcmNpc2VzIGluIGxhcmdlIGNvcnBvcmF0aW9ucyBmb2N1cyBvbiB0aGUgInRvIGJlIiBwcm9jZXNzZXMsIHdoaWNoIGltcGxpZXMgaG93IHNvbWV0aGluZyBzaG91bGQgYmUgZG9uZSwgcmF0aGVyIHRoYW4gaG93IGl0IGlzIGJlaW5nIGRvbmUuIE1vcmVvdmVyLCB1bmRlcnN0YW5kaW5nIHRoZSAiYXMgaXMiIGlzIGp1c3RpZmlhYmx5IHNrZXB0aWNhbCBmb3IgdGhlIGV4ZWN1dGl2ZSBnaXZlbiB0aGUgc3RpY2t5LW5vdGUgaW50ZXJ2aWV3IGp1Z2dsaW5nIGl0IGlzIGJ1aWx0IHVwb24uIEFsdGhvdWdoIHRoZXJlIGhhcyB0cmFkaXRpb25hbGx5IGJlZW4gbm8gc3Vic2l0dXRlIHRvIGZpcnN0IGhhbmQgZXhwZXJpZW5jZSwgd2l0aCB0aGUgZGF0YSBjb2xsZWN0aW9uIHJvYnVzdG5lc3MgaW4gbW9kZXJuIHRpbWVzIHRoZXJlIG1pZ2h0IGJlIGEgYmV0dGVyIG9wdGlvbi4gDQoNCiogVGhpcyBicmluZ3MgdXMgdG8gdGhlIHNlY29uZCBxdWVzdGlvbiB3aGljaCBpcyB0aGUgbGFjayBvZiB0d28td2F5IGNvbm5lY3Rpb24gYmV0d2VlbiBidXNpbmVzcyBwcm9jZXNzZXMgYW5kIGVudGVycHJpc2UgaW5mb3JtYXRpb24gc3lzdGVtcy4gV2hpbGUgRVJQIHN5c3RlbXMgZG8gY2FwdHVyZSBwcm9jZXNzIGxvZ3MsIHRoZXkgcmFyZWx5IHByb3ZpZGUgaW50ZXJmYWNlcyB0byB3b3JrIHdpdGggdGhlc2UgbG9ncy4gDQoNCiMjIyMgRW5jb3VyYWdpbmcgZWNvc3lzdGVtIGFjdGl2aXR5IGluIHRoZSBmaWVsZA0KSW4gMjAxMSwgYSBtdW5pY2ggYmFzZWQgY29tcGFueSBjYWxsZWQgW0NlbG9uaXNdKGh0dHBzOi8vd3d3LmNlbG9uaXMuY29tLykgd2FzIGZvdW5kZWQgd2l0aCBWYW4gRGVyIEFsc3QgYXMgdGhlIHNjaWVudGlmaWMgYWR2aXNvci4gVmFuIGRlciBBbHN0IGhhcyBiZWVuIHRoZSBhY2FkZW1pYyBmb3JjZSBiZWhpbmQgcmVzZWFyY2ggb24gcHJvY2VzcyBtaW5pbmcgYW5kIGlzIHRoZSBpbnN0cnVjdG9yIGZvciBhcmd1YWJseSB0aGUgYmVzdCBzdHJ1Y3R1cmVkIE1PT0Mgb24gdGhlIHN1YmplY3QuIFRoZXJlIGFyZSBhbHNvIHJlc291cmNlcyBsaWtlIFtQcm9NXShodHRwOi8vd3d3LnByb2Nlc3NtaW5pbmcub3JnL3Byb20vc3RhcnQpIGFuZCBbZmx1eGljb25dKGh0dHBzOi8vd3d3LmZsdXhpY29uLmNvbS8pIHdoaWNoIGhhdmUgYmVlbiBhY3RpdmUgaW4gdGhlIGZpZWxkIHNpbmNlIDIwMTQuIA0KDQpTaW5jZSAyMDE2LCBJRUVFIGhhcyBiZWVuIG1haW50YWluaW5nIHRoZSBzdGFuZGFyZCBkYXRhIGZvcm1hdCBbWEVTXShodHRwOi8veGVzLXN0YW5kYXJkLm9yZy8pIGZvciBldmVudCBsb2dzIHRvIGVuYWJsZSBzdHJlYW1saW5lcyBwcm9jZXNzIGFuYWx5c2lzLiBJbiAyMDE4LCBHYXJ0bmVyIHB1Ymxpc2hlZCBhIG1hcmtldCBndWlkZSBmb3IgcHJvY2VzcyBtaW5pbmcgYW5kIGhhaWxlZCBpdCBhcyBhbiBlbmFibGVyIHRvd2FyZHMgZGlnaXRhbCB0cmFuc2Zvcm1hdGlvbi4gSW4gQXByaWwgMjAxOSwgSGFydmFyZCBidXNpbmVzcyByZXZpZXcgcHVibGlzaGVkIGFuIFthcnRpY2xlXShodHRwczovL2hici5vcmcvMjAxOS8wNC93aGF0LXByb2Nlc3MtbWluaW5nLWlzLWFuZC13aHktY29tcGFuaWVzLXNob3VsZC1kby1pdCkgd2hpY2ggZGVzY3JpYmVzIHRoZSBuZWVkIGZvciBtaW5pbmcgcHJvY2Vzc2VzIGFuZCBkZXJpdmluZyB1c2VmdWwgaW5zaWdodHMgZnJvbSBwcm9jZXNzIGRhdGEuIA0KDQpUaGlzIG1ha2VzIHByb2Nlc3MgbWluaW5nIGFuIGludGVyZXN0aW5nIGV4cGxvcmF0aW9uIGZvciBkYXRhIHNjaWVudGlzdHMuIA0KDQoNCiMjIyBXaGF0IGlzIFByb2Nlc3MgTWluaW5nPw0KDQo8c3R5bGU+DQpib2R5IHsNCnRleHQtYWxpZ246IGp1c3RpZnl9DQo8L3N0eWxlPg0KDQpQcm9jZXNzIG1pbmluZyBpcyB0aGUgYW5hbHl0aWNhbCBkaXNjaXBsaW5lIG9mIHVuZGVyc3RhbmRpbmcgcmVhbCBwcm9jZXNzZXMgKHZpcyBhIHZpcyBhc3N1bWVkIHByb2Nlc3NlcykgZnJvbSBldmVudCBsb2dzLCB0aGVyZWJ5IGVuYWJsaW5nIGNvbXBhcmlzb24gb2YgdGhlIGV4dHJhY3RlZCBwcm9jZXNzIHdpdGggaWRlYWwgcHJvY2Vzcy4gSXQgY2FuIHByb3ZpZGUgZGV0YWlsZWQgb2JqZWN0aXZlICYgZGF0YSBkcml2ZW4gdmlldyBvZiBob3cgdGhlIHByb2Nlc3NlcyBhcmUgcGVyZm9ybWluZyBhbmQgYW5zd2VyIGJvdGggcGVyZm9ybWFuY2UgYW5kIGNvbXBsaWFuY2UgcmVsYXRlZCBxdWVzdGlvbnMuIA0KDQpQcm9jZXNzIG1pbmluZyBjYW4gYmUgdXNlZCBhcyBhIHByZWN1cnNvciB0byBvcGVyYXRpb25hbCBlZmZpY2llbmN5IGVuaGFuY2VtZW50IHByb2dyYW1zLCByZXNvdXJjZSBhbGxvY2F0aW9uIGFuZCBwcm9jZXNzIGF1dG9tYXRpb24gZ3VpZGVsaW5lcy4gSXQgaXMgY2xvc2VseSByZWxhdGVkIHRvIGJ1c2luZXNzIHByb2Nlc3MgbWFuYWdlbWVudC4NCg0KDQpUaGlzIG5vdGVib29rIGlzIGludGVuZGVkIGZvciBnZXR0aW5nIGFuIGludHJvZHVjdGlvbiB0byBwcm9jZXNzIG1pbmluZywgdW5kZXJzdGFuZGluZyBpdHMgYmFzaWNzIGFuZCBwcm92aWRlIGJhc2ljIGdyb3VuZCB3b3JrIGZvciBzdGFydGluZyBwcm9jZXNzIG1pbmluZy4gDQoNCiMjIyBBdmFpbGFibGUgdG9vbHMNCg0KPHN0eWxlPg0KYm9keSB7DQp0ZXh0LWFsaWduOiBqdXN0aWZ5fQ0KPC9zdHlsZT4NCg0KQXMgc29mdHdhcmUgb2ZmZXJpbmdzLCBDZWxvbmlzLCBGbHV4aWNvbiBhbmQgUVBSIHByb3ZpZGUgc29sdXRpb25zIGZvciBwcm9jZXNzIGRpc2NvdmVyeS4gSW4gdGhlIG9wZW4gc291cmNlIGRhdGEgc2NpZW5jZSB3b3JsZCwgUiBhbmQgUHl0aG9uIGNvbW11bml0aWVzIGhhdmUgbGlicmFyaWVzIGJ1cGFSIGFuZCBwbTRweSByZXNwZWN0aXZlbHkgdG8gd29yayBvbiB0aGUgcHJvY2VzcyBkYXRhLiBXaGlsZSB0aGlzIG5vdGVib29rIGlzIGJ1aWx0IG9uIFIgYW5kIHdvcmtzIHdpdGggYnVwYVIsIHRoZSBmdW5kYW1lbnRhbCBwcmljaXBsZXMgYXJlIGNvbW1vbiB0byBvdGhlciB0b29scw0KDQojIyMgVW5kZXJzdGFuZGluZyBwcm9jZXNzIGRhdGENCg0KPHN0eWxlPg0KYm9keSB7DQp0ZXh0LWFsaWduOiBqdXN0aWZ5fQ0KPC9zdHlsZT4NCg0KVGhlIGVzc2VudGlhbCBkYXRhIGNhcHR1cmUgc2NoZW1hIGZvciBwcm9jZXNzIG1pbmluZyBpcyBhbiAqZXZlbnQgbG9nKi4gQmFzaWNhbGx5IHRocmVlIGFzcGVjdHMgdGhhdCBzaG91bGQgYmUgbmVjZXNzYXJpbHkgY2FwdHVyZWQgYXJlIA0KMS4gQWN0aXZpdHkgLSBhIHdlbGwgdW5kZXJzdG9vZCBzdGVwIGluIHRoZSBwcm9jZXNzLCBmb3IgaW5zdGFuY2UgaW4gYSBJVCBwcm9jZXNzLCAqY2FsbGluZyBoZWxwIGRlc2sqIGlzIGFuIGFjdGl2aXR5Lw0KMi4gQ2FzZSBpZGVudGlmaWVyIC0gdGhlIHVuaXF1ZSBpZGVudGlmaWVyIHRvIHdoaWNoIG11bHRpcGxlIGFjdGl2aXRpZXMgY2FuIGJlIHRhZ2dlZCBhbmQgdHJhY2tlZC4gSW4gdGhlIHNhbWUgZXhhbXBsZSBvZiBhbiBJVCBwcm9jZXNzLCBjYXNlIGlkZW50aWZpZXIgd291bGQgYmUgc2VyaWFsIG51bWJlciBhc3NpZ25lZCB0byB0aGUgY2FzZS4gDQozLiBBY3Rpdml0eSBpbnN0YW5jZSBpZGVudGlmaWVyIChvciBzZXF1ZW5jZSkgLSB0aGUgY29ubmVjdCBiZXR3ZWVuIDEpIGFuZCAyKSBhYm92ZSwgZm9yIGluc3RhbmNlIHRoZSBzdGFydGluZyBhbmQgZW5kaW5nIG9mIHBob25lIGNhbGwgd291bGQgYmUgdGFnZ2VkIHdpdGggdGhlIGluc3RhbmNlIGlkZW50aWZpZXIuIA0KDQpUaW1lIHN0YW1wLCByZXNvdXJjZSwgbG9jYXRpb24gYW5kIG90aGVyIGRldGFpbHMgYXJlIGFsc28gc29tZXRpbWVzIGF2YWlsYWJsZSBpbiBldmVudCBsb2dzIGFuZCBjYW4gYmUgdXNlZCBmb3Igc2VsZWN0aXZlIGZpbHRlcmluZy4gDQoNCiMjIyBCVXNpbmVzc3MgUHJvY2VzcyBBbmFseXRpY3Mgd2l0aCBSIChCVVBBUikNCg0KYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KHBseXIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoYnVwYVIpDQoNCmBgYA0KDQojIyMjIEludHJvZHVjaW5nIGRhdGFzZXQNCkZvciB0aGlzIGV4ZXJjaXNlLCBJIGhhdmUgdXNlZCBwcm9kdWN0aW9uIGRhdGEgZnJvbSA0VFUgZGF0YSByZXBvc2l0b3J5LiBEYXRhIGlzIGF2YWlsYWJsZSBbaGVyZV0oaHR0cHM6Ly9kYXRhLjR0dS5ubC9yZXBvc2l0b3J5L3V1aWQ6Njg3MjY5MjYtNWFjNS00ZmFiLWI4NzMtZWU3NmVhNDEyMzk5KSANCg0KYGBge3IsIGVjaG89RkFMU0V9DQoNCnByb2RfZGF0YTwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9QcnV0aGlSL0RvY3VtZW50cy8yMDIwL21Mb2dpYy9wcm9jZXNzbWluaW5nL0RhdGFzZXQgZmlsZXMgKDIuMSBNQikvZGF0YS9Qcm9kdWN0aW9uX0RhdGEuY3N2IikNCg0KcHJpbnQoY29sbmFtZXMocHJvZF9kYXRhKSkNCg0KYGBgDQoNClRoZSBjb2x1bW4gbmFtZXMgZnJvbSB0aGUgYWJvdmUgZGF0YSBuZWVkIHRvIGJlIG1hcHBlZCB0byB0aGUgc3RhbmRhcmQgZXZlbnQgbG9nIG5vbWVuY2xhdHVyZS4gVGhpcyBpcyBkb25lIGJ5IHVzaW5nIHRoZSBldmVudCBsb2cgY3JlYXRpbmcgY29tbWFuZC4gVGhlIHN0YW5kYXJkIG5vbWVuY2FsdHVyZSBpbmNsdWRlcyBmb2xsb3dpbmcgY29sdW1uIGlucHV0cw0KDQoqIGNhc2VfaWQgLSB3aGljaCBpcyBhIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgKndob2xlKiBwcm9jZXNzIHNlcXVlbmNlLA0KKiBhY3Rpdml0eV9pZCAtIGEgZGVzY3JpcHRpb24gb24gdGhlIGluZGl2aWR1YWwgYWN0aXZpdHkgd2l0aGluIGEgcHJvY2VzcywNCiogYWN0aXZpdHlfaW5zdGFuY2VfaWQgLSB3aGljaCBpbnN0YW5jZXMgb2YgYWN0aXZpdHkgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgZGlmZmVyZW50IGZyb20gb3RoZXJzLA0KKiBsaWZlY3ljbGVfaWQgLSBzdGF0dXMvb3V0Y29tZSBvZiB0aGUgcHJvY2VzcywNCiogdGltZXN0YW1wIC0gdGltZSBhdCB3aGljaCBsb2dnaW5nIHdhcyBkb25lLA0KKiByZXNvdXJjZV9pZCAtIG1hY2hpbmUvaW5kaXZpZHVhbCByZXNwb25zaWJsZSBmb3IgdGhlIGluc3RhbmNlIG9mIHRoZSBwcm9jZXNzL2FjdGl2aXR5Lg0KDQpIb3dldmVyLCBiZWZvcmUgdGhhdCB0aGUgZGF0ZSB0aW1lIGRhdGEgbmVlZHMgdG8gYmUgYnJvdWdodCB0byBhIHByb3BlciBkYXRlIHRpbWUgZm9ybWF0LiBGb3IgdGhpcywgbHVicmlkYXRlIGxpYnJhcnkgaXMgdXNlZC4gDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeShsdWJyaWRhdGUpDQoNCnByb2RfZGF0YSRDb21wbGV0ZS5UaW1lc3RhbXA8LSB5bWRfaG1zKHByb2RfZGF0YSRDb21wbGV0ZS5UaW1lc3RhbXApDQpwcm9kX2RhdGEkU3RhcnQuVGltZXN0YW1wPC0geW1kX2htcyhwcm9kX2RhdGEkU3RhcnQuVGltZXN0YW1wKQ0KYGBgDQoNCkF0IHRoaXMgcG9pbnQsIGFuIGFjdGl2aXR5IGluc3RhbmNlIGlzIGFkZGVkIHRvIHRoZSBsb2dzIGFuZCBhbiBldmVudCBsb2cgaXMgY3JlYXRlZC4gDQoNCmBgYHtyfQ0KcHJvZF9kYXRhX3dpdGhfaW5zdGFuY2U8LSBwcm9kX2RhdGEgJT4lIA0KICBtdXRhdGUoYWN0aXZpdHlfaW5zdGFuY2UgPSBhcy5jaGFyYWN0ZXIocm93X251bWJlcigpKSkNCmBgYA0KDQoNCmBgYHtyLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0V9DQpwcm9kX2V2ZW50ID0gcHJvZF9kYXRhX3dpdGhfaW5zdGFuY2UgJT4lDQogICAgZXZlbnRsb2coDQogICAgICAgIGNhc2VfaWQgPSAiQ2FzZS5JRCIsDQogICAgICAgIGFjdGl2aXR5X2lkID0gIkFjdGl2aXR5IiwNCiAgICAgICAgYWN0aXZpdHlfaW5zdGFuY2VfaWQgPSAiYWN0aXZpdHlfaW5zdGFuY2UiLA0KICAgICAgICBsaWZlY3ljbGVfaWQgPSAiUmV3b3JrIiwNCiAgICAgICAgdGltZXN0YW1wID0gIkNvbXBsZXRlLlRpbWVzdGFtcCIsDQogICAgICAgIHJlc291cmNlX2lkID0gIldvcmtlci5JRCINCiAgICApDQoNCnByb2RfZXZlbnQgJT4lIG5fYWN0aXZpdGllcw0KDQpwcm9kX2V2ZW50ICU+JSBuX2Nhc2VzDQoNCnByb2RfZXZlbnQgJT4lIG5fdHJhY2VzDQpwcm9kX2V2ZW50ICU+JSBuX3Jlc291cmNlcw0KDQpgYGANCg0KVGhlcmUgYXJlIGEgdG90YWwgb2YgNTUgYWN0aXZpdGllcywgY2FycmllZCBvdXQgZm9yIDIyNSBjYXNlcywgaW4gMjIxIHVuaXF1ZSB3YXlzICh0cmFjZXMpIGJ5IDQ5IHJlc291cmNlcy4gDQoNCiMjIyMgQWN0aXZpdHkgVW5kZXJzdGFuZGluZyAmIEFuYWx5c2lzDQpMZXQgdXMgc3RhcnQgd2hhdCBkaWZmZXJlbnQgbGV2ZWwgb2YgYWN0aXZpdGllcyBhcmUgcHJlc2VudCBhbmQgdGhlaXIgcmVsYXRpdmUgZnJlcXVlbmN5DQoNCmBgYHtyfQ0KDQphY3Rpdml0eV9kYXRhPC0gcHJvZF9ldmVudCAlPiUgDQogICBhY3Rpdml0eV9mcmVxdWVuY3kobGV2ZWwgPSAiYWN0aXZpdHkiKQ0KDQphY3Rpdml0eV9kYXRhX3JlZHVjZWQ8LSBhY3Rpdml0eV9kYXRhW2FjdGl2aXR5X2RhdGEkcmVsYXRpdmU+MC4wMixdDQoNCihwbG90KGFjdGl2aXR5X2RhdGFfcmVkdWNlZCkpDQpgYGANCg0KVGhpcyBzaG93cyB0aGF0IGZpbmFsIGluc3BlY3Rpb24gaXMgdGhlIGhpZ2hlc3QgZnJlcXVlbmN5IGFjdGl2aXR5LCB3aGljaCBpcyB0byBiZSBleHBlY3RlZC4gQWZ0ZXIgd2hpY2ggdGhlIHR1cm5pbmcgYW5kIG1pbGxpbmcgcXVhbGl0eSBjaGVja3MgYXJlIGFsc28gaGlnaC4gTGFwcGluZyBhbmQgcGFja2FnaW5nIGZvbGxvdyB1cC4gDQoNCiMjIyMgVmlzdWFsaXppbmcgcHJvY2VzcyBtYXBzDQpMZXQgdXMgc3RhcnQgYnkgdmlld2luZyBvbmUgb2YgdGhlIHByb2Nlc3MgbWFwcy4gDQoNCmBgYHtyfQ0KZXZlbnRfcmVkdWNlZDwtIHByb2RfZXZlbnRbcHJvZF9ldmVudCRDYXNlLklEICVpbiUgYygiQ2FzZSAxIiksXQ0KDQpldmVudF9yZWR1Y2VkICU+JSBwcm9jZXNzX21hcCh0eXBlID0gZnJlcXVlbmN5KCJyZWxhdGl2ZSIpKQ0KYGBgDQoNClRoaXMgc2hvd3MgZm9yIG9uZSBvZiB0aGUgY2FzZXMsIGhvdyB0aGUgc3RlcHMgaW52b2x2ZWQgaW4gdGhlIHByb2Nlc3MgcGxheSBvdXQuIEFzIHdlIGFkZCBtb3JlIGRhdGEsIHdlIGNhbiBzdGFydCB0byBzZWUgc29tZSBvZiB0aGUgcG9zc2libGUgaXRlcmF0aW9ucyBpbiB0aGUgcHJvY2VzcyBwbGF5IG91dC4gSXQgYXBwZWFycyB0aGF0IHRoZSBzdGVwcyBmb3IgdGhpcyBjYXNlIGFyZSANCjEuIFR1cm5pbmcgYW5kIG1pbGxpbmcNCjIuIFR1cm5pbmcgYW5kIG1pbGxpbmcgUS5DDQozLiBMYXNlciBNYXJraW5nDQo0LiBMYXBwaW5nDQo1LiBSb3VuZCBncmluZGluZw0KNi4gRmluYWwgSW5zcGVjdGlvbg0KNy4gUGFja2luZw0KDQpTZWxmIGxvb3BzIHJlcHJlc2VudCB0aGF0IG1vcmUgdGhhbiBvbmUgbG9nZ2luZyBvZiB0aGUgc2FtZSBhY3Rpdml0eSBpcyBvYnNlcnZlZCwgd2hpY2ggbWlnaHQgYmUgZHVlIHRvIGVycm9yIG1lc3NhZ2VzIG9yIGxvZ2dpbmcgZGlzY3JlcGFuY3kuIA0KDQpJZiB3ZSBhZGQgdHdvIG1vcmUgY2FzZXMgdG8gdGhpcywgbW9yZSBpbnNpZ2h0cyBzdGFydCB0byBhcHBlYXIsIHNlZSBiZWxvdyBwbG90IGZvciAzIGNhc2VzLiANCg0KYGBge3J9DQpldmVudF9yZWR1Y2VkPC0gcHJvZF9ldmVudFtwcm9kX2V2ZW50JENhc2UuSUQgJWluJSBjKCJDYXNlIDEiLCJDYXNlIDExMSIsIkNhc2UgMTA0IiksXQ0KDQpldmVudF9yZWR1Y2VkICU+JSBwcm9jZXNzX21hcCh0eXBlID0gZnJlcXVlbmN5KCJyZWxhdGl2ZSIpKQ0KYGBgDQpJdCBpcyBjbGVhciB0aGF0IG9uZSBvZiB0aGUgY2FzZXMgKDEvMykgd2VudCBmb3IgdHVybmluZyByYXRoZXIgdGhhbiB0dXJuaW5nIGFuZCBtaWxsaW5nLCB3aGljaCBhbHNvIGluY3JlYXNlZCBhIHR1cm5pbmcgUS5DIHBvaW50DQoNCkFib3ZlIHBsb3QgYWxzbyBzaG93cyB0aGF0IGFib3V0IDIwJSBvZiB0aGUgY29tcG9uZW50cyBkaXJlY3RseSBnbyBmcm9tIGxhc2VyIG1hcmtpbmcgdG8gZW5kLCA4JSBnbyBmcm9tIHR1cm5pbmcgdG8gZW5kIHdoaWxlIGFib3V0IDIwJSBnbyB0aHJvdWdoIHRoZSBsYXBwaW5nIGFuZCBncmlkaW5nIG9wZXJhdGlvbiBiZWZvcmUgZ29pbmcgdG8gcGFja2luZyBhbmQgdGhlbiBlbmRpbmcuIA0KDQpJZiB3ZSBhZGQgZmV3IG1vcmUgY2FzZXMgdG8gdGhlIGFib3ZlIHBsb3QsIGl0IHN0YXJ0cyB0byBnZXQgY3VtYmVyc29tZSB0byB1bmRlcnN0YW5kLiANCg0KU2ltaWxhciB0byBwcm9jZXNzIG1hcHMsIHJlc291cmNlIG1hcHMgYXJlIGFsc28gYW5vdGhlciB3YXkgb2YgdW5kZXJzdGFuZGluZyBmbG93LiANCg0KYGBge3J9DQpldmVudF9yZWR1Y2VkPC0gcHJvZF9ldmVudFtwcm9kX2V2ZW50JENhc2UuSUQgJWluJSBjKCJDYXNlIDEiLCJDYXNlIDExMSIsIkNhc2UgMTA0IiksXQ0KDQpldmVudF9yZWR1Y2VkICU+JSBmaWx0ZXJfdHJhY2VfZnJlcXVlbmN5KHBlcmNlbnRhZ2UgPSAwLjUpICU+JSByZXNvdXJjZV9tYXAodHlwZSA9IGZyZXF1ZW5jeSgiYWJzb2x1dGUiKSkNCmBgYA0KDQoNClRoZXJlIGFyZSBmdXJ0aGVyIHdheXMgYXZhaWxhYmxlIGZvciBleHBsb3JpbmcgcHJvY2Vzc2VzLiANCg0KDQojIyMjIFByZWNlZGVuY2UgTWF0cml4DQpBbm90aGVyIHdheSB0byB2aXN1YWxpemUgdGhlIHByb2Nlc3MgaXMgcHJlY2RlbmNlIG1hdHJpeCB3aGljaCBzaG93cyB3aGljaCBzdGVwcyB0ZW5kIHRvIGhhcHBlbiB0b2dldGhlci4gSW4gdGhpcyBjYXNlIHNpbmNlIGxvZ2dpbmcgc2VlbXMgdG8gaGF2ZSBkdXBsaWNhdGlvbiBpbiBhY3Rpdml0eSwgdGhlIHBsb3QgaXMgbm90IHZlcnkgaW5zaWdodGZ1bC4gDQoNCmBgYHtyfQ0KcHJlY2VkZW5jZV9tYXRyaXggPC0gcHJvZF9ldmVudCAlPiUNCiAgZmlsdGVyX2FjdGl2aXR5X2ZyZXF1ZW5jeShwZXJjZW50YWdlID0gMC45KSAlPiUgDQogIGZpbHRlcl90cmFjZV9mcmVxdWVuY3kocGVyY2VudGFnZSA9IC44MCkgJT4lICAgIA0KICBwcmVjZWRlbmNlX21hdHJpeCgpICU+JSANCiAgcGxvdCgpDQoNCnByZWNlZGVuY2VfbWF0cml4DQoNCmBgYA0KDQojIyMjIFJlc291cmNlICYgYWN0aXZpdHkgQW5hbHlzaXMNClJlc291cmNlIHNwZWNpYWxpemF0aW9uIGFuZCB1dGlsaXphdGlvbiBpcyBhbm90aGVyIGtleSBhY3Rpdml0eSB3aGljaCBjYW4gYmUgaGVscGVkIGJ5IHByb2Nlc3MgYW5hbHl0aWNzDQoNCmBgYHtyLCBmaWcuaGVpZ2h0PTh9DQpwcm9kX2V2ZW50ICU+JQ0KICAgIHJlc291cmNlX3NwZWNpYWxpc2F0aW9uKCJyZXNvdXJjZSIpICU+JSBwbG90KCkNCmBgYA0KDQpUaGUgYWJvdmUgcGxvdCBmb3IgaW5zdGFuY2Ugc2hvd3MgdGhhdCBJRDQ5MzIgYW5kIElEMDkzNyBhcmUgZ2VuZXJhbGlzdHMsIHBlcmZvcm1pbmcgdXB0byAxNSBhY3Rpdml0eSB0eXBlcywgSUQzNjQxLCBJRDM3MTkgYXJlIHNwZWNpYWxpc3RzLiANCg0KYGBge3IsIGZpZy5oZWlnaHQ9MTB9DQpwcm9kX2V2ZW50ICU+JQ0KICAgIHJlc291cmNlX3NwZWNpYWxpc2F0aW9uKCJhY3Rpdml0eSIpICU+JSBwbG90KCkNCmBgYA0KDQpGaW5hbCBpbnNwZWN0aW9uLCBwYWNraW5nLCBsYXBwaW5nLCByb3VuZCBncmlkaW5nIGFuZCB0dXJuaW5nIFEuQyBhcmUgc3BlY2lhbGl6ZWQgYWN0aXZpdGllcyBwZXJmb21yZWQgb25seSBieSBvbmUgcmVzb3VyY2UuICAgDQoNCkluIHRlcm1zIG9mIGFjdGl2aXRpZXMsIGl0IHdvdWxkIGFsc28gYmUgdXNlZnVsIHRvIHVuZGVyc3RhbmQgd2hpY2ggYWN0aXZpdGllcyBhcmUgYWx3YXlzIHBlcmZvcm1lZCwgYW5kIHdoaWNoIGFyZSByYXJlLiANCg0KYGBge3IsIGZpZy5oZWlnaHQ9OH0NCnByb2RfZXZlbnQgJT4lIGFjdGl2aXR5X3ByZXNlbmNlKCkgJT4lIHBsb3QoKQ0KYGBgDQoNCiMjIyMgVHJhY2UgYW5hbHlzaXMNClRyYWNlIGxlbmd0aCBhbmQgcGxvdHMgYXJlIHVzZWQgdG8gc2VlIGhvdyBtdWNoIHZhcmlhdGlvbiBpcyB0aGVyZSBhY3Jvc3MgY2FzZXMuIA0KDQpgYGB7cn0NCnByb2RfZXZlbnQgJT4lIHRyYWNlX2xlbmd0aCgpICU+JSBwbG90KCkNCiNwcm9kX2V2ZW50ICU+JSB0cmFjZV9sZW5ndGgoKQ0KYGBgDQoNClRoZSBwbG90IHNob3dzIHRoYXQgb24gYW4gYXZlcmFnZSwgNzUlIG9mIGNhc2VzIGhhdmUgYmV0d2VlbiA4LTIzIHN0ZW9zLCBhbHRob3VnaCBhIG1heGltdW0gb2YgMTc1IHN0ZXBzIGhhdmUgYmVlbiBvYnNlcnZlZCBhcyB3ZWxsLiBNZWRpYW4gbnVtYmVyIG9mIHN0ZXBzIGlzIDE0LCBhbmQgYXZlcmFnZSBudW1iZXIgb2Ygc3RlcHMgaXMgMjAuIA0KDQpEbyBhbGwgYWN0aXZpdGllcyBzdGFydCBhbmQgZW5kIGF0IHRoZSBzYW1lIHBvaW50cz8gVGhpcyBjYW4gYmUgdmlzdWFsaXplZCB1c2luZyBiYXIgcGxvdHMgYXMgd2VsbA0KDQpgYGB7cn0NCnN0YXJ0X2FjdGl2aXRpZXMocHJvZF9ldmVudCwgbGV2ZWwgPSAiYWN0aXZpdHkiKSAlPiUgcGxvdCgpDQoNCmBgYA0KDQpXaGlsZSB0dXJuaW5nIGFuZCBtaWxsaW5nIHNlZW1zIHRvIGJlIHRoZSBmaXJzdCBvcGVyYXRpb24sIG1hY2hpbmUgNiBzZWVzIGhpZ2hlc3QgcmF0ZSBvZiBzdGFydGluZyBwb2ludHMuIA0KDQpgYGB7cn0NCmVuZF9hY3Rpdml0aWVzKHByb2RfZXZlbnQsIGxldmVsID0gImFjdGl2aXR5IikgJT4lIHBsb3QoKQ0KYGBgDQoNCkFzIGV4cGVjdGVkLCBtb3N0IG9wZXJhdGlvbnMgZW5kIHdpdGggZmluYWwgaW5zcGVjdGlvbiBvciBwYWNraW5nLiANCg0KYGBge3J9DQpwcm9kX2V2ZW50ICU+JQ0KICB0cmFjZV9jb3ZlcmFnZShsZXZlbCA9ICJ0cmFjZSIpICU+JQ0KICBwbG90KCkNCmBgYA0KDQpUaGUgYWJvdmUgcGxvdCBzaG93cyBob3cgbWFueSBjYXNlcyBjYW4gYmUgZGVzY3JpYmVkIHdpdGggYSByZWxhdGl2ZWx5IHNtYWxsIG51bWJlciBvZiB0cmFjZXMgaW5kaWNhdGluZyB0aGUgY29uc2lzdGVuY3kgaW4gdGhlIHByb2Nlc3MuIEhlcmUgd2UgaGF2ZSBzZWVuIHRoYXQgZm9yIDIyNSBjYXNlcywgYXMgaGlnaCBhcyAyMjEgdHJhY2VzIGV4aXN0LCBzbyB0aGVyZSBpcyBqdXN0IGxlc3MgY29uc2lzdGVuY3kuIEhvd2V2ZXIsIHRoaXMgaXMgZHVlIHRvIG1hY2hpbmUgbnVtYmVyIGJlaW5nIHBhcnQgb2YgYWN0aXZpdHkgZGVzY3JpcHRpb24sIHdoaWNoIG1lYW5zIHRoYXQgc2ltaWxhciBzdGVwcyBhcmUgYWxzbyB0cmVhdGVkIGRpZmZlcmVudGx5LiANCg0KDQoNCiMjIyMgQ29uc29saWRhdGlvbiBvZiBhY3Rpdml0aWVzDQpDb25zb2xpZGF0aW9uIG9mIGFjdGl2aXRpZXMgYWxsb3dzIHJlbGFiZWxpbmcgYW5kIGZ1cnRoZXIgaGlnaCBsZXZlbCB2aWV3IG9mIHRoZSBwcm9jZXNzLiANCg0KYGBge3IsIGVjaG89RkFMU0V9DQpwcm9kX2V2ZW50X3VuaXRlZDwtIHByb2RfZXZlbnQgJT4lIGFjdF91bml0ZShUdXJuaW5nID0gYygiVHVybmluZyAtIE1hY2hpbmUgMjEiLCJUdXJuaW5nIC0gTWFjaGluZSA0IiwgIlR1cm5pbmcgLSBNYWNoaW5lIDUiLCAiVHVybmluZyAtIE1hY2hpbmUgOCIsICJUdXJuaW5nIC0gTWFjaGluZSA5IikpDQoNCnByb2RfZXZlbnRfdW5pdGVkPC0gcHJvZF9ldmVudF91bml0ZWQgJT4lIGFjdF91bml0ZSgiVHVybmluZyAmIE1pbGxpbmciID0gYygiVHVybmluZyAmIE1pbGxpbmcgLSBNYWNoaW5lIDEwIiwiVHVybmluZyAmIE1pbGxpbmcgLSBNYWNoaW5lIDQiLCJUdXJuaW5nICYgTWlsbGluZyAtIE1hY2hpbmUgNSIsIlR1cm5pbmcgJiBNaWxsaW5nIC0gTWFjaGluZSA2IiwiVHVybmluZyAmIE1pbGxpbmcgLSBNYWNoaW5lIDgiLCJUdXJuaW5nICYgTWlsbGluZyAtIE1hY2hpbmUgOSIgKSkNCg0KcHJvZF9ldmVudF91bml0ZWQ8LSBwcm9kX2V2ZW50X3VuaXRlZCAlPiUgYWN0X3VuaXRlKCJSb3VuZCBHcmlkbmluZyAtIE1hY2hpbmUiID0gYygiUm91bmQgR3JpbmRpbmcgLSBNYWNoaW5lIDEyIiwiUm91bmQgR3JpbmRpbmcgLSBNYWNoaW5lIDE5IiwgIlJvdW5kIEdyaW5kaW5nIC0gTWFjaGluZSAyIiwiUm91bmQgR3JpbmRpbmcgLSBNYWNoaW5lIDIzIiwiUm91bmQgR3JpbmRpbmcgLSBNYWNoaW5lIDMiKSkNCg0KcHJvZF9ldmVudF91bml0ZWQ8LSBwcm9kX2V2ZW50X3VuaXRlZCAlPiUgYWN0X3VuaXRlKCJNaWxsaW5nIiA9IGMoIk1pbGxpbmcgLSBNYWNoaW5lIDEwIiwiTWlsbGluZyAtIE1hY2hpbmUgMTQiLCJNaWxsaW5nIC0gTWFjaGluZSAxNiIsIk1pbGxpbmcgLSBNYWNoaW5lIDgiICkpDQoNCnByb2RfZXZlbnRfdW5pdGVkPC0gcHJvZF9ldmVudF91bml0ZWQgJT4lIGFjdF91bml0ZSgiR3JpbmRpbmcgUmV3b3JrIiA9IGMoIkdyaW5kaW5nIFJld29yayIsIkdyaW5kaW5nIFJld29yayAtIE1hY2hpbmUgMTIiLCAiR3JpbmRpbmcgUmV3b3JrIC0gTWFjaGluZSAyIiwiR3JpbmRpbmcgUmV3b3JrIC0gTWFjaGluZSAyNyIgKSkNCg0KcHJvZF9ldmVudF91bml0ZWQ8LSBwcm9kX2V2ZW50X3VuaXRlZCAlPiUgYWN0X3VuaXRlKCJTZXR1cCIgPSBjKCJTZXR1cCAtIE1hY2hpbmUgOCIsIlNldHVwIC0gTWFjaGluZSA0IikpDQoNCnByb2RfZXZlbnRfdW5pdGVkPC0gcHJvZF9ldmVudF91bml0ZWQgJT4lIGFjdF91bml0ZSgiRml4IiA9IGMoIkZpeCAtIE1hY2hpbmUgMyIsIkZpeCAtIE1hY2hpbmUgMTkiLCAiRml4IC0gTWFjaGluZSAxNSIsICJGaXggLSBNYWNoaW5lIDE1TSIpKQ0KDQpwcm9kX2V2ZW50X3VuaXRlZDwtIHByb2RfZXZlbnRfdW5pdGVkICU+JSBhY3RfdW5pdGUoIkZpeCIgPSBjKCJGaXgiLCJGaXggRURNIikpDQoNCnByb2RfZXZlbnRfdW5pdGVkPC0gcHJvZF9ldmVudF91bml0ZWQgJT4lIGFjdF91bml0ZSgiVHVybiAmIE1pbGwgYW5kIFNjcmV3IiA9IGMoIlR1cm4gJiBNaWxsLiAmIFNjcmV3IEFzc2VtIC0gTWFjaGluZSA5IiwiVHVybiAmIE1pbGwuICYgU2NyZXcgQXNzZW0gLSBNYWNoaW5lIDEwIikpDQoNCnByb2RfZXZlbnRfdW5pdGVkPC0gcHJvZF9ldmVudF91bml0ZWQgJT4lIGFjdF91bml0ZSgiV2lyZSBDdXQiID0gYygiV2lyZSBDdXQgLSBNYWNoaW5lIDE4IiwiV2lyZSBDdXQgLSBNYWNoaW5lIDEzIikpDQoNCnByb2RfZXZlbnRfdW5pdGVkPC0gcHJvZF9ldmVudF91bml0ZWQgJT4lIGFjdF91bml0ZSgiRmxhdCBHcmluZGluZyIgPSBjKCJGbGF0IEdyaW5kaW5nIC0gTWFjaGluZSAxMSIsIkZsYXQgR3JpbmRpbmcgLSBNYWNoaW5lIDI2IiApKQ0KDQpgYGANCg0KDQpgYGB7cn0NCmV2ZW50X3JlZHVjZWQ8LSBwcm9kX2V2ZW50X3VuaXRlZFtwcm9kX2V2ZW50X3VuaXRlZCRDYXNlLklEICVpbiUgYygiQ2FzZSAxIiwiQ2FzZSAxMTEiLCJDYXNlIDEwNCIpLF0NCg0KZXZlbnRfcmVkdWNlZCAlPiUgZmlsdGVyX3RyYWNlX2ZyZXF1ZW5jeShwZXJjZW50YWdlID0gMC44KSAlPiUgcHJvY2Vzc19tYXAodHlwZSA9IGZyZXF1ZW5jeSgiYWJzb2x1dGUiKSkNCmBgYA0KDQpUaGUgMTAlIG1vc3QgaW5mcmVxdWVudCB0cmFjZXMgYXJlIHBsb3R0ZWQgYmVsb3cgd2l0aCB1bml0ZWQgZGF0YS4gDQoNCmBgYHtyLCBmaWcud2lkdGg9MjV9DQpwcm9kX2V2ZW50X3VuaXRlZCAlPiUgdHJhY2VfZXhwbG9yZXIoY292ZXJhZ2UgPSAwLjEsIHR5cGUgPSAiaW5mcmVxdWVudCIpDQpgYGANCg0K