Identifying Consumer Segments
Loading required packages and dataset…
Loading required package: grid
examine the structure of the bank data frame
'data.frame': 4521 obs. of 17 variables:
$ age : int 30 33 35 30 59 35 36 39 41 43 ...
$ job : chr "unemployed" "services" "management" "management" ...
$ marital : chr "married" "married" "single" "married" ...
$ education: chr "primary" "secondary" "tertiary" "tertiary" ...
$ default : chr "no" "no" "no" "no" ...
$ balance : int 1787 4789 1350 1476 0 747 307 147 221 -88 ...
$ housing : chr "no" "yes" "yes" "yes" ...
$ loan : chr "no" "yes" "no" "yes" ...
$ contact : chr "cellular" "cellular" "cellular" "unknown" ...
$ day : int 19 11 16 3 5 23 14 6 14 17 ...
$ month : chr "oct" "may" "apr" "jun" ...
$ duration : int 79 220 185 199 226 141 341 151 57 313 ...
$ campaign : int 1 1 1 4 1 2 1 2 2 1 ...
$ pdays : int -1 339 330 -1 -1 176 330 -1 -1 147 ...
$ previous : int 0 4 1 0 0 3 2 0 0 2 ...
$ poutcome : chr "unknown" "failure" "failure" "unknown" ...
$ response : chr "no" "no" "no" "no" ...
NULL
Printing first few rows
admin. blue-collar entrepreneur housemaid management retired
478 946 168 112 969 230
self-employed services student technician unemployed unknown
183 417 84 768 128 38
<NA>
0
divorced married single <NA>
528 2797 1196 0
primary secondary tertiary unknown <NA>
678 2306 1350 187 0
no yes <NA>
4445 76 0
no yes <NA>
1962 2559 0
no yes <NA>
3830 691 0
jobtype
job White Collar Blue Collar Other/Unknown <NA>
admin. 478 0 0 0
blue-collar 0 946 0 0
entrepreneur 168 0 0 0
housemaid 0 0 112 0
management 969 0 0 0
retired 0 0 230 0
self-employed 183 0 0 0
services 0 417 0 0
student 0 0 84 0
technician 0 768 0 0
unemployed 0 0 128 0
unknown 0 0 38 0
<NA> 0 0 0 0
bluecollar
whitecollar 0 1
0 592 2131
1 1798 0
jobtype
White Collar Blue Collar Other/Unknown
1798 2131 592
married
divorced 0 1
0 1196 2797
1 528 0
marital
Divorced Married Single
528 2797 1196
, , tertiary = 0
secondary
primary 0 1
0 187 2306
1 678 0
, , tertiary = 1
secondary
primary 0 1
0 1350 0
1 0 0
education
Primary Secondary Tertiary Unknown
678 2306 1350 187
'data.frame': 3705 obs. of 16 variables:
$ response : chr "no" "no" "no" "no" ...
$ age : int 30 30 59 39 41 39 43 36 20 40 ...
$ jobtype : Factor w/ 3 levels "White Collar",..: 3 1 2 2 1 2 1 2 3 1 ...
$ marital : Factor w/ 3 levels "Divorced","Married",..: 2 2 2 2 2 2 2 2 3 2 ...
$ education : Factor w/ 4 levels "Primary","Secondary",..: 1 3 2 2 3 2 2 3 2 3 ...
$ default : chr "no" "no" "no" "no" ...
$ balance : int 1787 1476 0 147 221 9374 264 1109 502 194 ...
$ housing : chr "no" "yes" "yes" "yes" ...
$ loan : chr "no" "yes" "no" "no" ...
$ whitecollar: num 0 1 0 0 1 0 1 0 0 1 ...
$ bluecollar : num 0 0 1 1 0 1 0 1 0 0 ...
$ divorced : num 0 0 0 0 0 0 0 0 0 0 ...
$ married : num 1 1 1 1 1 1 1 1 0 1 ...
$ primary : num 1 0 0 0 0 0 0 0 0 0 ...
$ secondary : num 0 0 1 1 0 1 1 0 1 0 ...
$ tertiary : num 0 1 0 0 1 0 0 1 0 1 ...
NULL





































null device
1
Examine the cluster solution results, look for average silhouette width > 0.5 and look for last big jump in average silhoutte width
provide a single summary plot for the clustering solutions

select clustering solution and examine it


From the silhouette plot, the first five of the seven clusters appear to be large and well-defined
look at demographics across the clusters/segments (age Age in years). Examine relationship between age and response to promotion
cluster: A
[1] 45.9057
----------------------------------------------------------------------
cluster: B
[1] 41.6633
----------------------------------------------------------------------
cluster: C
[1] 43.04649
----------------------------------------------------------------------
cluster: D
[1] 40.03083
----------------------------------------------------------------------
cluster: E
[1] 32.29765
Plot lattice. responders tend to be older

Level of education (unknown, secondary, primary, tertiary)
education
cluster Primary Secondary Tertiary Unknown
A 509 0 0 0
B 0 0 594 0
C 0 826 0 56
D 0 485 0 34
E 0 354 0 29
Table of job status using jobtype
jobtype
cluster White Collar Blue Collar Other/Unknown
A 70 313 126
B 470 81 43
C 0 768 114
D 488 0 31
E 0 314 69
marital
cluster Divorced Married Single
A 0 449 60
B 0 594 0
C 0 882 0
D 0 380 139
E 0 0 383
look at bank client history across the clusters/segments. default Has credit in default? (yes, no)
default
cluster no yes
A 502 7
B 590 4
C 868 14
D 508 11
E 372 11
balance Average yearly balance (in Euros)
cluster: A
[1] 1446.106
----------------------------------------------------------------------
cluster: B
[1] 1882.47
----------------------------------------------------------------------
cluster: C
[1] 1273.861
----------------------------------------------------------------------
cluster: D
[1] 1331.609
----------------------------------------------------------------------
cluster: E
[1] 1018.661
Plot lattice. responders tend to be older
null device
1
housing Has housing loan? (yes, no)
housing
cluster no yes
A 225 284
B 310 284
C 322 560
D 208 311
E 194 189
loan Has personal loan? (yes, no)
response Response to term deposit offer (yes, no)
response
cluster no yes
A 473 36
B 535 59
C 824 58
D 489 30
E 333 50
Plot mosaic Response to Term Deposit Offer

Computation percentage of yes responses to term deposit offer
Percentage Responses
A 7.1
B 9.9
C 6.6
D 5.8
E 13.1
Note the percentage of the customers receiving offers for the first time falling into each of the clusters/segments
1 2 3 4 5 6 7 8
13.7 16.0 23.8 14.0 10.3 3.9 8.1 10.1
LS0tDQp0aXRsZTogIkZpbmRpbmcgTmV3IEN1c3RvbWVycyAtIFRhcmdldCBNYXJrZXRpbmciDQphdXRob3I6IEhvYSBRdWFjaA0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyBJZGVudGlmeWluZyBDb25zdW1lciBTZWdtZW50cw0KDQpMb2FkaW5nIHJlcXVpcmVkIHBhY2thZ2VzIGFuZCBkYXRhc2V0Li4uDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgY2FsbCBpbiBSIHBhY2thZ2VzIGZvciB1c2UgaW4gdGhpcyBzdHVkeQ0KbGlicmFyeShsYXR0aWNlKSAgIyBtdWx0aXZhcmlhdGUgZGF0YSB2aXN1YWxpemF0aW9uDQpsaWJyYXJ5KHZjZCkgICMgZGF0YSB2aXN1YWxpemF0aW9uIGZvciBjYXRlZ29yaWNhbCB2YXJpYWJsZXMNCmxpYnJhcnkoY2x1c3RlcikgICMgY2x1c3RlciBhbmFseXNpcyBtZXRob2RzDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KIyByZWFkIGJhbmsgZGF0YSBpbnRvIFIsIGNyZWF0aW5nIGRhdGEgZnJhbWUgYmFuaw0KIyBub3RlIHRoYXQgdGhpcyBpcyBhIHNlbWljb2xvbi1kZWxpbWl0ZWQgZmlsZQ0KYmFuayA8LSByZWFkLmNzdigiYmFuay5jc3YiLCBzZXAgPSAiOyIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCmBgYA0KDQpleGFtaW5lIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGJhbmsgZGF0YSBmcmFtZQ0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQojIGV4YW1pbmUgdGhlIHN0cnVjdHVyZSBvZiB0aGUgYmFuayBkYXRhIGZyYW1lDQpwcmludChzdHIoYmFuaykpDQpgYGANCg0KUHJpbnRpbmcgZmlyc3QgZmV3IHJvd3MNCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KcHJpbnQoaGVhZChiYW5rKSkNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQpwcmludCh0YWJsZShiYW5rJGpvYiAsIHVzZU5BID0gYygiYWx3YXlzIikpKQ0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCnByaW50KHRhYmxlKGJhbmskbWFyaXRhbCAsIHVzZU5BID0gYygiYWx3YXlzIikpKQ0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCnByaW50KHRhYmxlKGJhbmskZWR1Y2F0aW9uICwgdXNlTkEgPSBjKCJhbHdheXMiKSkpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KcHJpbnQodGFibGUoYmFuayRkZWZhdWx0ICwgdXNlTkEgPSBjKCJhbHdheXMiKSkpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KcHJpbnQodGFibGUoYmFuayRob3VzaW5nICwgdXNlTkEgPSBjKCJhbHdheXMiKSkpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KcHJpbnQodGFibGUoYmFuayRsb2FuICwgdXNlTkEgPSBjKCJhbHdheXMiKSkpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KIyBUeXBlIG9mIGpvYiAoYWRtaW4uLCB1bmtub3duLCB1bmVtcGxveWVkLCBtYW5hZ2VtZW50LA0KIyBob3VzZW1haWQsIGVudHJlcHJlbmV1ciwgc3R1ZGVudCwgYmx1ZS1jb2xsYXIsIHNlbGYtZW1wbG95ZWQsDQojIHJldGlyZWQsIHRlY2huaWNpYW4sIHNlcnZpY2VzKQ0KIyBwdXQgam9iIGludG8gdGhyZWUgbWFqb3IgY2F0ZWdvcmllcyBkZWZpbmluZyB0aGUgZmFjdG9yIHZhcmlhYmxlIGpvYnR5cGUNCiMgdGhlICJ1bmtub3duIiBjYXRlZ29yeSBpcyBob3cgbWlzc2luZyBkYXRhIHdlcmUgY29kZWQgZm9yIGpvYi4uLiANCiMgaW5jbHVkZSB0aGVzZSBpbiAiT3RoZXIvVW5rbm93biIgY2F0ZWdvcnkvbGV2ZWwNCndoaXRlX2NvbGxhcl9saXN0IDwtIGMoImFkbWluLiIsImVudHJlcHJlbmV1ciIsIm1hbmFnZW1lbnQiLCJzZWxmLWVtcGxveWVkIikgIA0KYmx1ZV9jb2xsYXJfbGlzdCA8LSBjKCJibHVlLWNvbGxhciIsInNlcnZpY2VzIiwidGVjaG5pY2lhbiIpDQpiYW5rJGpvYnR5cGUgPC0gcmVwKDMsIGxlbmd0aCA9IG5yb3coYmFuaykpDQpiYW5rJGpvYnR5cGUgPC0gaWZlbHNlKChiYW5rJGpvYiAlaW4lIHdoaXRlX2NvbGxhcl9saXN0KSwgMSwgYmFuayRqb2J0eXBlKSANCmJhbmskam9idHlwZSA8LSBpZmVsc2UoKGJhbmskam9iICVpbiUgYmx1ZV9jb2xsYXJfbGlzdCksIDIsIGJhbmskam9idHlwZSkgDQpiYW5rJGpvYnR5cGUgPC0gZmFjdG9yKGJhbmskam9idHlwZSwgbGV2ZWxzID0gYygxLCAyLCAzKSwgDQogICAgbGFiZWxzID0gYygiV2hpdGUgQ29sbGFyIiwgIkJsdWUgQ29sbGFyIiwgIk90aGVyL1Vua25vd24iKSkNCndpdGgoYmFuaywgdGFibGUoam9iLCBqb2J0eXBlLCB1c2VOQSA9IGMoImFsd2F5cyIpKSkgICMgY2hlY2sgZGVmaW5pdGlvbiAgIA0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgZGVmaW5lIGJpbmFyeSBpbmRpY2F0b3IgdmFyaWFibGVzIGFzIG51bWVyaWMgMC8xIHZhcmlhYmxlcw0KYmFuayR3aGl0ZWNvbGxhciA8LSBpZmVsc2UoKGJhbmskam9idHlwZSA9PSAiV2hpdGUgQ29sbGFyIiksIDEsIDApDQpiYW5rJGJsdWVjb2xsYXIgPC0gaWZlbHNlKChiYW5rJGpvYnR5cGUgPT0gIkJsdWUgQ29sbGFyIiksIDEsIDApDQp3aXRoKGJhbmssIHByaW50KHRhYmxlKHdoaXRlY29sbGFyLCBibHVlY29sbGFyKSkpICAjIGNoZWNrIGRlZmluaXRpb24NCmBgYA0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQp3aXRoKGJhbmssIHByaW50KHRhYmxlKGpvYnR5cGUpKSkgICMgY2hlY2sgZGVmaW5pdGlvbg0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgZGVmaW5lIGZhY3RvciB2YXJpYWJsZXMgd2l0aCBsYWJlbHMgZm9yIHBsb3R0aW5nIGFuZCBiaW5hcnkgZmFjdG9ycw0KYmFuayRtYXJpdGFsIDwtIGZhY3RvcihiYW5rJG1hcml0YWwsIA0KICAgIGxhYmVscyA9IGMoIkRpdm9yY2VkIiwgIk1hcnJpZWQiLCAiU2luZ2xlIikpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KIyBkZWZpbmUgYmluYXJ5IGluZGljYXRvciB2YXJpYWJsZXMgYXMgbnVtZXJpYyAwLzEgdmFyaWFibGVzDQpiYW5rJGRpdm9yY2VkIDwtIGlmZWxzZSgoYmFuayRtYXJpdGFsID09ICJEaXZvcmNlZCIpLCAxLCAwKQ0KYmFuayRtYXJyaWVkIDwtIGlmZWxzZSgoYmFuayRtYXJpdGFsID09ICJNYXJyaWVkIiksIDEsIDApICAgIA0Kd2l0aChiYW5rLCBwcmludCh0YWJsZShkaXZvcmNlZCwgbWFycmllZCkpKSAgIyBjaGVjayBkZWZpbml0aW9uDQoNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQp3aXRoKGJhbmssIHByaW50KHRhYmxlKG1hcml0YWwpKSkgICMgY2hlY2sgZGVmaW5pdGlvbiAgICANCmBgYA0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQpiYW5rJGVkdWNhdGlvbiA8LSBmYWN0b3IoYmFuayRlZHVjYXRpb24sIA0KICAgIGxhYmVscyA9IGMoIlByaW1hcnkiLCAiU2Vjb25kYXJ5IiwgIlRlcnRpYXJ5IiwgIlVua25vd24iKSkNCg0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgZGVmaW5lIGJpbmFyeSBpbmRpY2F0b3IgdmFyaWFibGVzIGFzIG51bWVyaWMgMC8xIHZhcmlhYmxlcw0KYmFuayRwcmltYXJ5IDwtIGlmZWxzZSgoYmFuayRlZHVjYXRpb24gPT0gIlByaW1hcnkiKSwgMSwgMCkNCmJhbmskc2Vjb25kYXJ5IDwtIGlmZWxzZSgoYmFuayRlZHVjYXRpb24gPT0gIlNlY29uZGFyeSIpLCAxLCAwKSAgICAgICAgDQpiYW5rJHRlcnRpYXJ5IDwtIGlmZWxzZSgoYmFuayRlZHVjYXRpb24gPT0gIlRlcnRpYXJ5IiksIDEsIDApICAgICANCndpdGgoYmFuaywgcHJpbnQodGFibGUocHJpbWFyeSwgc2Vjb25kYXJ5LCB0ZXJ0aWFyeSkpKSAgIyBjaGVjayBkZWZpbml0aW9uDQoNCmBgYA0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0Kd2l0aChiYW5rLCBwcmludCh0YWJsZShlZHVjYXRpb24pKSkgICMgY2hlY2sgZGVmaW5pdGlvbiAgICANCmBgYA0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQojIGNsaWVudCBleHBlcmllbmNlIHZhcmlhYmxlcyB3aWxsIG5vdCBiZSB1c2VmdWwgZm9yIHNlZ21lbnRhdGlvbiANCiMgYnV0IGNhbiBiZSByZWZlcnJlZCB0byBhZnRlciBzZWdtZW50cyBoYXZlIGJlZW4gZGVmaW5lZA0KYmFuayRkZWZhdWx0IDwtIGZhY3RvcihiYW5rJGRlZmF1bHQsIGxhYmVscyA9IGMoIk5vIiwgIlllcyIpKQ0KYmFuayRob3VzaW5nIDwtIGZhY3RvcihiYW5rJGhvdXNpbmcsIGxhYmVscyA9IGMoIk5vIiwgIlllcyIpKQ0KYmFuayRsb2FuIDwtIGZhY3RvcihiYW5rJGxvYW4sIGxhYmVscyA9IGMoIk5vIiwgIlllcyIpKQ0KYmFuayRyZXNwb25zZSA8LSBmYWN0b3IoYmFuayRyZXNwb25zZSwgbGFiZWxzID0gYygiTm8iLCAiWWVzIikpDQoNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQojIHNlbGVjdCBzdWJzZXQgb2YgY2FzZXMgbmV2ZXIgcGVydmlvdXNseSBjb250YWN0ZWQgYnkgc2FsZXMNCiMga2VlcGluZyB2YXJpYWJsZXMgbmVlZGVkIGZvciBjbHVzdGVyIGFuYWx5c2lzIGFuZCBwb3N0LWFuYWx5c2lzDQpiYW5rZnVsbCA8LSBzdWJzZXQoYmFuaywgc3Vic2V0ID0gKHByZXZpb3VzID09IDApLA0KICAgIHNlbGVjdCA9IGMoInJlc3BvbnNlIiwgImFnZSIsICJqb2J0eXBlIiwgIm1hcml0YWwiLCAiZWR1Y2F0aW9uIiwgDQogICAgICAgICAgICAgICAiZGVmYXVsdCIsICJiYWxhbmNlIiwgImhvdXNpbmciLCAibG9hbiIsIA0KICAgICAgICAgICAgICAgIndoaXRlY29sbGFyIiwgImJsdWVjb2xsYXIiLCAiZGl2b3JjZWQiLCAibWFycmllZCIsDQogICAgICAgICAgICAgICAicHJpbWFyeSIsICJzZWNvbmRhcnkiLCAidGVydGlhcnkiKSkNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQojIGV4YW1pbmUgdGhlIHN0cnVjdHVyZSBvZiB0aGUgZnVsbCBiYW5rIGRhdGEgZnJhbWUNCnByaW50KHN0cihiYW5rZnVsbCkpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KcHJpbnQoaGVhZChiYW5rZnVsbCkpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KIyBzZWxlY3Qgc3Vic2V0IG9mIHZhcmlhYmxlcyBmb3IgaW5wdXQgdG8gY2x1c3RlciBhbmFseXNpcw0KZGF0YV9mb3JfY2x1c3RlcmluZyA8LSBzdWJzZXQoYmFua2Z1bGwsDQogICAgc2VsZWN0ID0gYygiYWdlIiwgDQogICAgICAgICAgICAgICAid2hpdGVjb2xsYXIiLCAiYmx1ZWNvbGxhciIsIA0KICAgICAgICAgICAgICAgImRpdm9yY2VkIiwgIm1hcnJpZWQiLA0KICAgICAgICAgICAgICAgInByaW1hcnkiLCAic2Vjb25kYXJ5IiwgInRlcnRpYXJ5IikpICAgIA0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgY2x1c3RlcmluZyBzb2x1dGlvbnMgKG1pbl9jbHVzdGVycyB0byBtYXhfY2x1c3RlcnMpDQojIHRoaXMgc3RlcCBtYXkgdGFrZSAxMCBtaW51dGVzIG9yIG1vcmUgdG8gY29tcGxldGUNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgc2V0IGZpbGUgZm9yIGdyYXBoaWNhbCBvdXRwdXQgZnJvbSB0aGUgY2x1c3RlcmluZyBzb2x1dGlvbnMNCnBkZihmaWxlID0gImZpZ19maW5kaW5nX25ld19jdXN0b21lcnNfY2x1c3Rlcl9zZWFyY2gucGRmIiwNCiAgICAgICAgd2lkdGggPSA4LjUsIGhlaWdodCA9IDExKQ0KbWluX2NsdXN0ZXJzIDwtIDINCm1heF9jbHVzdGVycyA8LSAyMA0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgZXZhbHVhdGUgYWx0ZXJuYXRpdmUgbnVtYmVycyBvZiBjbHVzdGVycy9zZWdtZW50cw0KIyB3ZSB1c2UgdGhlIGF2ZXJhZ2Ugc2lsaG91ZXR0ZSB3aWR0aCBhcyBhIHN0YXRpc3RpY2FsIGNyaXRlcmlvbg0KZXZhbHVhdGlvbl92ZWN0b3IgPC0gTlVMTCAgIyBpbml0aWFsaXplIGV2YWx1YXRpb24gdmVjdG9yIA0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgc2VsZWN0ZWQgYWxnb3JpdGhtIGlzIHBhbSAocGFydGl0aW9uaW5nIGFyb3VuZCBtZWRvaWRzKQ0KIyB3aXRoIHNvIG1hbnkgYmluYXJ5IHZhcmlhYmxlcywgbWFuaGF0dGFuIGRpc3RhbmNlcyBzZWVtZWQgDQojIHRvIHdvcmsgYmV0dGVyIHRoYW4gRXVjbGlkZWFuIGRpc3RhbmNlcw0KZm9yIChudW1iZXJfb2ZfY2x1c3RlcnMgaW4gbWluX2NsdXN0ZXJzOm1heF9jbHVzdGVycykgew0KICAgIHRyeV9jbHVzdGVyaW5nIDwtIHBhbShkYXRhX2Zvcl9jbHVzdGVyaW5nLCBrID0gbnVtYmVyX29mX2NsdXN0ZXJzLA0KICAgICAgICBtZXRyaWMgPSAibWFuaGF0dGFuIiwgc3RhbmQgPSBUUlVFKQ0KICAgIGV2YWx1YXRpb25fdmVjdG9yIDwtIHJiaW5kKGV2YWx1YXRpb25fdmVjdG9yLA0KICAgICAgICBkYXRhLmZyYW1lKG51bWJlcl9vZl9jbHVzdGVycywgDQogICAgICAgICAgICBhdmVyYWdlX3NpbGhvdWV0dGVfd2lkdGggPSANCiAgICAgICAgICAgICAgICB0cnlfY2x1c3RlcmluZyRzaWxpbmZvJGF2Zy53aWR0aCkpDQogICAgIyBzaG93IHBsb3QgZm9yIHRoaXMgY2x1c3RlcmluZyBzb2x1dGlvbg0KICAgIHBsb3QodHJ5X2NsdXN0ZXJpbmcpICAjIGFkZCB0aGlzIGNsdXN0ZXJpbmcgc29sdXRpb24gdG8gcmVzdWx0cyBmaWxlICAgICAgICAgDQogICAgfSAgICAgICAgDQpkZXYub2ZmKCkgICMgY2xvc2UgdGhlIHBkZiByZXN1bHRzIGZpbGUgZm9yIHRoZSBjbHVzdGVyaW5nIHNvbHV0aW9uICAgIA0KYGBgDQoNCkV4YW1pbmUgdGhlIGNsdXN0ZXIgc29sdXRpb24gcmVzdWx0cywgbG9vayBmb3IgYXZlcmFnZSBzaWxob3VldHRlIHdpZHRoID4gMC41IGFuZCBsb29rIGZvciBsYXN0IGJpZyBqdW1wIGluIGF2ZXJhZ2Ugc2lsaG91dHRlIHdpZHRoDQogICAgDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQojIGV4YW1pbmUgdGhlIGNsdXN0ZXIgc29sdXRpb24gcmVzdWx0cywgDQojIGxvb2sgZm9yIGF2ZXJhZ2Ugc2lsaG91ZXR0ZSB3aWR0aCA+IDAuNQ0KIyBsb29rIGZvciBsYXN0IGJpZyBqdW1wIGluIGF2ZXJhZ2Ugc2lsaG91dHRlIHdpZHRoDQpwcmludChldmFsdWF0aW9uX3ZlY3RvcikNCmBgYA0KDQpwcm92aWRlIGEgc2luZ2xlIHN1bW1hcnkgcGxvdCBmb3IgdGhlIGNsdXN0ZXJpbmcgc29sdXRpb25zDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgcHJvdmlkZSBhIHNpbmdsZSBzdW1tYXJ5IHBsb3QgZm9yIHRoZSBjbHVzdGVyaW5nIHNvbHV0aW9ucw0KcGRmKGZpbGUgPSAiZmlnX2ZpbmRpbmdfbmV3X2N1c3RvbWVyc19jbHVzdGVyX3N1bW1hcnkucGRmIiwNCiAgICAgICAgd2lkdGggPSA4LjUsIGhlaWdodCA9IDguNSkNCg0Kd2l0aChldmFsdWF0aW9uX3ZlY3RvciwgcGxvdChudW1iZXJfb2ZfY2x1c3RlcnMsIA0KICAgIGF2ZXJhZ2Vfc2lsaG91ZXR0ZV93aWR0aCkpDQoNCmRldi5vZmYoKSAgIyBjbG9zZSBzdW1tYXJ5IHJlc3VsdHMgZmlsZQ0KYGBgDQoNCnNlbGVjdCBjbHVzdGVyaW5nIHNvbHV0aW9uIGFuZCBleGFtaW5lIGl0DQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgc2VsZWN0IGNsdXN0ZXJpbmcgc29sdXRpb24gYW5kIGV4YW1pbmUgaXQNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgZXhhbWluZSB0aGUgc2V2ZW4tY2x1c3RlciBzb2x1dGlvbiBpbiBtb3JlIGRldGFpbA0Kc2V2ZW5fY2x1c3Rlcl9zb2x1dGlvbiA8LSBwYW0oZGF0YV9mb3JfY2x1c3RlcmluZywgayA9IDgsDQogICAgICAgIG1ldHJpYyA9ICJtYW5oYXR0YW4iLCBzdGFuZCA9IFRSVUUpDQoNCnBkZihmaWxlID0gImZpZ19maW5kaW5nX25ld19jdXN0b21lcnNfc2V2ZW5fY2x1c3Rlcl9zb2x1dGlvbi5wZGYiLA0KICAgIHdpZHRoID0gOC41LCBoZWlnaHQgPSA4LjUpDQoNCnBsb3Qoc2V2ZW5fY2x1c3Rlcl9zb2x1dGlvbikNCg0KZGV2Lm9mZigpDQpgYGANCg0KRnJvbSB0aGUgc2lsaG91ZXR0ZSBwbG90LCB0aGUgZmlyc3QgZml2ZSBvZiB0aGUgc2V2ZW4gY2x1c3RlcnMgYXBwZWFyIHRvIGJlIGxhcmdlIGFuZCB3ZWxsLWRlZmluZWQNCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KIyBmcm9tIHRoZSBzaWxob3VldHRlIHBsb3QsIHRoZSBmaXJzdCBmaXZlIG9mIHRoZSBzZXZlbg0KIyBjbHVzdGVycyBhcHBlYXIgdG8gYmUgbGFyZ2UgYW5kIHdlbGwtZGVmaW5lZA0KDQojIGFkZCB0aGUgY2x1c3RlciBtZW1iZXJzaGlwIGluZm9ybWF0aW9uIGFuZCBzZWxlY3QgZmlyc3QgZml2ZQ0KYmFua2Z1bGwkY2x1c3RlciA8LSBzZXZlbl9jbHVzdGVyX3NvbHV0aW9uJGNsdXN0ZXJpbmcNCmJhbmtwYXJ0IDwtIHN1YnNldChiYW5rZnVsbCwgc3Vic2V0ID0gKGNsdXN0ZXIgPCA2KSkNCmJhbmtwYXJ0JGNsdXN0ZXIgPC0gZmFjdG9yKGJhbmtwYXJ0JGNsdXN0ZXIsDQogICAgbGFiZWxzID0gYygiQSIsICJCIiwgIkMiLCAiRCIsICJFIikpDQpgYGANCg0KbG9vayBhdCBkZW1vZ3JhcGhpY3MgYWNyb3NzIHRoZSBjbHVzdGVycy9zZWdtZW50cyAoYWdlICBBZ2UgaW4geWVhcnMpLiBFeGFtaW5lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGFnZSBhbmQgcmVzcG9uc2UgdG8gcHJvbW90aW9uDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgbG9vayBhdCBkZW1vZ3JhcGhpY3MgYWNyb3NzIHRoZSBjbHVzdGVycy9zZWdtZW50cw0KIyAtLS0tLS0tLS0tLS0tLS0tLQ0KIyBhZ2UgIEFnZSBpbiB5ZWFycw0KIyAtLS0tLS0tLS0tLS0tLS0tLQ0KIyBleGFtaW5lIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGFnZSBhbmQgcmVzcG9uc2UgdG8gcHJvbW90aW9uDQp3aXRoKGJhbmtwYXJ0LCBwcmludChieShhZ2UsIGNsdXN0ZXIsIG1lYW4pKSkNCmBgYA0KDQpQbG90IGxhdHRpY2UuIHJlc3BvbmRlcnMgdGVuZCB0byBiZSBvbGRlcg0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQpwZGYoZmlsZSA9ICJmaWdfZmluZGluZ19uZXdfY3VzdG9tZXJzX2FnZV9sYXR0aWNlLnBkZiIsICAgICANCiAgICB3aWR0aCA9IDguNSwgaGVpZ2h0ID0gMTEpDQoNCmxhdHRpY2VfcGxvdF9vYmplY3QgPC0gaGlzdG9ncmFtKH5hZ2UgfCBjbHVzdGVyLCBkYXRhID0gYmFua3BhcnQsDQogICAgdHlwZSA9ICJkZW5zaXR5IiwgDQogICAgeGxhYiA9ICJBZ2Ugb2YgQmFuayBDbGllbnQiLCBsYXlvdXQgPSBjKDEsNSkpDQoNCnByaW50KGxhdHRpY2VfcGxvdF9vYmplY3QpICAjIHJlc3BvbmRlcnMgdGVuZCB0byBiZSBvbGRlcg0KDQpkZXYub2ZmKCkNCmBgYA0KDQpMZXZlbCBvZiBlZHVjYXRpb24gKHVua25vd24sIHNlY29uZGFyeSwgcHJpbWFyeSwgdGVydGlhcnkpDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgZWR1Y2F0aW9uDQojIExldmVsIG9mIGVkdWNhdGlvbiAodW5rbm93biwgc2Vjb25kYXJ5LCBwcmltYXJ5LCB0ZXJ0aWFyeSkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCndpdGgoYmFua3BhcnQsIHByaW50KHRhYmxlKGNsdXN0ZXIsIGVkdWNhdGlvbikpKQ0KYGBgDQoNClRhYmxlIG9mIGpvYiBzdGF0dXMgdXNpbmcgam9idHlwZQ0KICAgICAgICAgICAgICAgDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGpvYiBzdGF0dXMgdXNpbmcgam9idHlwZQ0KIyBXaGl0ZSBDb2xsYXI6IGFkbWluLiwgZW50cmVwcmVuZXVyLCBtYW5hZ2VtZW50LCBzZWxmLWVtcGxveWVkICANCiMgQmx1ZSBDb2xsYXI6IGJsdWUtY29sbGFyLCBzZXJ2aWNlcywgdGVjaG5pY2lhbg0KIyBPdGhlci9Vbmtub3duDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0Kd2l0aChiYW5rcGFydCwgcHJpbnQodGFibGUoY2x1c3Rlciwgam9idHlwZSkpKQ0KDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIG1hcml0YWwgc3RhdHVzDQojIE1hcml0YWwgc3RhdHVzIChtYXJyaWVkLCBkaXZvcmNlZCwgc2luZ2xlKQ0KIyBbTm90ZTogYGBkaXZvcmNlZCcnIG1lYW5zIGRpdm9yY2VkIG9yIHdpZG93ZWRdDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCndpdGgoYmFua3BhcnQsIHByaW50KHRhYmxlKGNsdXN0ZXIsIG1hcml0YWwpKSkNCg0KYGBgDQoNCmxvb2sgYXQgYmFuayBjbGllbnQgaGlzdG9yeSBhY3Jvc3MgdGhlIGNsdXN0ZXJzL3NlZ21lbnRzLiBkZWZhdWx0ICBIYXMgY3JlZGl0IGluIGRlZmF1bHQ/ICh5ZXMsIG5vKQ0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQojIGxvb2sgYXQgYmFuayBjbGllbnQgaGlzdG9yeSBhY3Jvc3MgdGhlIGNsdXN0ZXJzL3NlZ21lbnRzDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgZGVmYXVsdCAgSGFzIGNyZWRpdCBpbiBkZWZhdWx0PyAoeWVzLCBubykNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCndpdGgoYmFua3BhcnQsIHByaW50KHRhYmxlKGNsdXN0ZXIsIGRlZmF1bHQpKSkNCg0KYGBgDQoNCmJhbGFuY2UgIEF2ZXJhZ2UgeWVhcmx5IGJhbGFuY2UgKGluIEV1cm9zKQ0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBiYWxhbmNlICBBdmVyYWdlIHllYXJseSBiYWxhbmNlIChpbiBFdXJvcykNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQp3aXRoKGJhbmtwYXJ0LCBwcmludChieShiYWxhbmNlLCBjbHVzdGVyLCBtZWFuKSkpDQpgYGANCg0KUGxvdCBsYXR0aWNlLiByZXNwb25kZXJzIHRlbmQgdG8gYmUgb2xkZXINCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KcGRmKGZpbGUgPSAiZmlnX2ZpbmRpbmdfbmV3X2N1c3RvbWVyc19ibGFuY2VfbGF0dGljZS5wZGYiLCAgICAgDQogICAgd2lkdGggPSA4LjUsIGhlaWdodCA9IDExKQ0KDQpsYXR0aWNlX3Bsb3Rfb2JqZWN0IDwtIGhpc3RvZ3JhbSh+YmFsYW5jZSB8IGNsdXN0ZXIsIGRhdGEgPSBiYW5rcGFydCwNCiAgICB0eXBlID0gImRlbnNpdHkiLCB4bGFiID0gIkFnZSBvZiBCYW5rIENsaWVudCIsIA0KICAgIGxheW91dCA9IGMoMSw1KSkNCg0KcHJpbnQobGF0dGljZV9wbG90X29iamVjdCkgICMgcmVzcG9uZGVycyB0ZW5kIHRvIGJlIG9sZGVyDQoNCmRldi5vZmYoKQ0KDQpgYGANCg0KaG91c2luZyAgSGFzIGhvdXNpbmcgbG9hbj8gKHllcywgbm8pDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGhvdXNpbmcgIEhhcyBob3VzaW5nIGxvYW4/ICh5ZXMsIG5vKQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCndpdGgoYmFua3BhcnQsIHByaW50KHRhYmxlKGNsdXN0ZXIsIGhvdXNpbmcpKSkNCg0KYGBgDQoNCmxvYW4gIEhhcyBwZXJzb25hbCBsb2FuPyAoeWVzLCBubykNCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIGxvYW4gIEhhcyBwZXJzb25hbCBsb2FuPyAoeWVzLCBubykNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0Kd2l0aChiYW5rcGFydCwgcHJpbnQodGFibGUoY2x1c3RlciwgbG9hbikpKQ0KDQpgYGANCg0KIHJlc3BvbnNlICBSZXNwb25zZSB0byB0ZXJtIGRlcG9zaXQgb2ZmZXIgKHllcywgbm8pDQogDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyByZXNwb25zZSAgUmVzcG9uc2UgdG8gdGVybSBkZXBvc2l0IG9mZmVyICh5ZXMsIG5vKQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQp3aXRoKGJhbmtwYXJ0LCBwcmludCh0YWJsZShjbHVzdGVyLCByZXNwb25zZSkpKQ0KDQpgYGANCg0KUGxvdCBtb3NhaWMgUmVzcG9uc2UgdG8gVGVybSBEZXBvc2l0IE9mZmVyDQoNCmBgYHtyIGV2YWw9VFJVRSwgZWNobz1GQUxTRX0NCnBkZihmaWxlID0gImZpZ19maW5kaW5nX25ld19jdXN0b21lcnNfcmVzcG9uc2VfbW9zYWljLnBkZiIsIA0KICAgIHdpZHRoID0gOC41LCBoZWlnaHQgPSA4LjUpDQoNCm1vc2FpYyggfiByZXNwb25zZSArIGNsdXN0ZXIsIGRhdGEgPSBiYW5rcGFydCwNCiAgbGFiZWxpbmdfYXJncyA9IGxpc3Qoc2V0X3Zhcm5hbWVzID0gYyhyZXNwb25zZSA9ICJSZXNwb25zZSB0byBUZXJtIERlcG9zaXQgT2ZmZXIiLCANCiAgY2x1c3RlciA9ICJTZWdtZW50IE1lbWJlcnNoaXAiKSksDQogIGhpZ2hsaWdodGluZyA9ICJyZXNwb25zZSIsDQogIGhpZ2hsaWdodGluZ19maWxsID0gYygiY29ybnNpbGsiLCJ2aW9sZXQiKSwNCiAgcm90X2xhYmVscyA9IGMobGVmdCA9IDAsIHRvcCA9IDApLA0KICBwb3NfbGFiZWxzID0gYygiY2VudGVyIiwiY2VudGVyIiksDQogIG9mZnNldF9sYWJlbHMgPSBjKDAuMCwwLjYpKQ0KDQpkZXYub2ZmKCkNCg0KDQpgYGANCg0KQ29tcHV0YXRpb24gcGVyY2VudGFnZSBvZiB5ZXMgcmVzcG9uc2VzIHRvIHRlcm0gZGVwb3NpdCBvZmZlcg0KDQpgYGB7ciBldmFsPVRSVUUsIGVjaG89RkFMU0V9DQojIGNvbXB1dGUgcGVyY2VudGFnZSBvZiB5ZXMgcmVzcG9uc2VzIHRvIHRlcm0gZGVwb3NpdCBvZmZlcg0KcmVzcG9uc2VfdGFibGUgPC0gdGFibGUoYmFua3BhcnQkY2x1c3RlciwgYmFua3BhcnQkcmVzcG9uc2UpDQpjYXQoIlxuUGVyY2VudGFnZSBSZXNwb25zZXNcbiIpDQpmb3IgKGkgaW4gMTo1KSANCiAgICAgY2F0KCJcbiIsIHRvdXBwZXIobGV0dGVyc1tpXSksIA0KICAgICAgICAgcm91bmQoMTAwICogcmVzcG9uc2VfdGFibGVbaSwyXSAvIA0KICAgICAgICAgICAgIHN1bShyZXNwb25zZV90YWJsZVtpLF0pLCBkaWdpdHMgPSAxKSkNCg0KYGBgDQoNCk5vdGUgdGhlIHBlcmNlbnRhZ2Ugb2YgdGhlIGN1c3RvbWVycyByZWNlaXZpbmcgb2ZmZXJzIGZvciB0aGUgZmlyc3QgdGltZSBmYWxsaW5nIGludG8gZWFjaCBvZiB0aGUgY2x1c3RlcnMvc2VnbWVudHMNCg0KYGBge3IgZXZhbD1UUlVFLCBlY2hvPUZBTFNFfQ0KIyBub3RlIHRoZSBwZXJjZW50YWdlIG9mIHRoZSBjdXN0b21lcnMgcmVjZWl2aW5nIG9mZmVycw0KIyBmb3IgdGhlIGZpcnN0IHRpbWUgZmFsbGluZyBpbnRvIGVhY2ggb2YgdGhlIGNsdXN0ZXJzL3NlZ21lbnRzDQojIEEgPSAxIC4uLiBFID0gNSAuLi4NCnByaW50KHJvdW5kKDEwMCAqIHRhYmxlKGJhbmtmdWxsJGNsdXN0ZXIpIC8gbnJvdyhiYW5rZnVsbCksIGRpZ2l0cyA9IDEpKQ0KYGBgDQo=