This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Instacart - Stacked Bar charts

This is still an exploratory phase of the project. We are trying to understand further the distributions of the different types of items ordered by looking at the barcharts within departments, aisles and product name and the percentage of reorders for each. The data used is all the orders (prior + latest) from the sampled train users (35000 users) and the exporation covers the following:

  1. Distribution of items ordered by departments
  2. Distribution of items ordered by top 20 aisles, by volume (no of orders)
  3. Distribution of items of top 3 departments, broken down by aisles
  4. Distribution of items of top 20 product names
  5. Distribution of items of top 3 aisles, broken down by product names

Distribution of items ordered by departments

There are altogether 21 departments. Below is the distribution of these departments in volume of items ordered.

There is a total of 5820204 rows of ordered items in departments. Conversion to percentage is 100/5820204 = 0.0000171815


Attaching package: 㤼㸱dplyr㤼㸲

The following objects are masked from 㤼㸱package:stats㤼㸲:

    filter, lag

The following objects are masked from 㤼㸱package:base㤼㸲:

    intersect, setdiff, setequal, union

data.table 1.10.4
  The fastest way to learn (by data.table authors): https://www.datacamp.com/courses/data-analysis-the-data-table-way
  Documentation: ?data.table, example(data.table) and browseVignettes("data.table")
  Release notes, videos and slides: http://r-datatable.com

Attaching package: 㤼㸱data.table㤼㸲

The following objects are masked from 㤼㸱package:dplyr㤼㸲:

    between, first, last


Attaching package: 㤼㸱reshape2㤼㸲

The following objects are masked from 㤼㸱package:data.table㤼㸲:

    dcast, melt


Attaching package: 㤼㸱scales㤼㸲

The following object is masked from 㤼㸱package:plotrix㤼㸲:

    rescale

Creating a generic function for 㤼㸱toJSON㤼㸲 from package 㤼㸱jsonlite㤼㸲 in package 㤼㸱googleVis㤼㸲

Welcome to googleVis version 0.6.2

Please read Google's Terms of Use
before you start using the package:
https://developers.google.com/terms/

Note, the plot method of googleVis will by default use
the standard browser to display its output.

See the googleVis package vignettes for more details,
or visit http://github.com/mages/googleVis.

To suppress this message use:
suppressPackageStartupMessages(library(googleVis))


TraMineR stable version 2.0-6 (Built: 2017-06-25)
Website: http://traminer.unige.ch
Please type 'citation("TraMineR")' for citation information.

Read 0.0% of 5820204 rows
Read 8.9% of 5820204 rows
Read 20.4% of 5820204 rows
Read 32.1% of 5820204 rows
Read 47.9% of 5820204 rows
Read 64.6% of 5820204 rows
Read 75.9% of 5820204 rows
Read 92.6% of 5820204 rows
Read 5820204 rows and 15 (of 15) columns from 0.527 GB file in 00:00:11

The top 3 departments comes from produce, dairy eggs followed by snacks. Next we are going to be looking at the distribution of aisles as well as individual aisles within departments. Percentage of reorders within each department is also higher than non-reorders (around 60% within departments). One reason could be these are daily necessities, which would explain the high reorders.

Distribution of items ordered by top 20 aisles, by volume (no of orders)

Since there is a total of 134 aisles, we will not be looking at all the aisles. Instead we will only be looking at the distribution of items ordered for the top 20 aisles.

There is a total of 5820204 rows of ordered items in departments. Conversion to percentage is 100/5820204 = 0.0000171815

Notice that the top 2 aisles (fresh fruits, fresh vegetables) are higher than the rest and account for more than 20% of all aisles. Reorders is also significantly higher (72%) in fresh fruits compared to other aisles.

How does the aisle distribution look like for the top 3 departments (produce, dairy eggs, snacks)?

Distribution of items of top 3 departments, broken down by aisles

The top 3 departments (produce, dairy eggs and snacks) have 1702405, 967650 and 507960 rows of items corresponding to a conversion ratio to percentage of 0.0000587404289, 0.000103343 and 0.000196865 respectively.

Both fresh fruits and fresh vegetables which are the 2 highest aisles within produce department (around 75% of produce department) help to explain the main bulk of ALL orders in which 29% comes from produce department.

Notice the reorder ratio for milk is much higher than the rest within dairy eggs department. One reason could be the very short shelf life of milk, hence within the one year period of the recorded data, more milk will be reordered compared to other aisles.

We will next look at individual products and the most commonly ordered ones.

Distribution of items of top 20 product names

We will now look at the top 20 most ordered products and their reorder ratio.

From the graph above, the most popular products ordered are bananas and organic bananas, accounting for around 2.5% of all orders. Notice that the reorder ratio is also significantly higher than the rest (85%).

The commonly ordered products are mainly fruits and some items for cooking ingredients such as garlic, zucchini, cucumber.

Another interesting thing to note is the large number of organic items in the top 20 popular products (14 out of 20 are organic). We can conclude that quite a substantial segment of the customers are health conscious through their choice of organic products.

We shall next proceed to see the distribution of products within the top 3 aisles (fresh fruits, fresh vegetables, packaged vegetables fruits)

Distribution of items of top 3 aisles, broken down by product names

As indicated above, the top 3 aisles are fresh fruits, fresh vegetables and packaged vegetables fruits.

Most of the products that we are seeing already falls in the previous plot for most commonly ordered products.

Conclusion

This exploratory phase helps us in understanding what are the most commonly ordered items and give us insight on customers’ buying habits. However, it does not show any relation between the types of products ordered within a basket or between orders. We will explore such relationship further using Sanskey diagrams and some sequence mining R packages to see the most common sequence of items.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KIyBJbnN0YWNhcnQgLSBTdGFja2VkIEJhciBjaGFydHMNCg0KVGhpcyBpcyBzdGlsbCBhbiBleHBsb3JhdG9yeSBwaGFzZSBvZiB0aGUgcHJvamVjdC4gV2UgYXJlIHRyeWluZyB0byB1bmRlcnN0YW5kIGZ1cnRoZXIgdGhlIGRpc3RyaWJ1dGlvbnMgb2YgdGhlIGRpZmZlcmVudCB0eXBlcyBvZiBpdGVtcyBvcmRlcmVkIGJ5IGxvb2tpbmcgYXQgdGhlIGJhcmNoYXJ0cyB3aXRoaW4gZGVwYXJ0bWVudHMsIGFpc2xlcyBhbmQgcHJvZHVjdCBuYW1lIGFuZCB0aGUgcGVyY2VudGFnZSBvZiByZW9yZGVycyBmb3IgZWFjaC4gVGhlIGRhdGEgdXNlZCBpcyBhbGwgdGhlIG9yZGVycyAocHJpb3IgKyBsYXRlc3QpIGZyb20gdGhlIHNhbXBsZWQgdHJhaW4gdXNlcnMgKDM1MDAwIHVzZXJzKSBhbmQgdGhlIGV4cG9yYXRpb24gY292ZXJzIHRoZSBmb2xsb3dpbmc6DQoNCjEpIERpc3RyaWJ1dGlvbiBvZiBpdGVtcyBvcmRlcmVkIGJ5IGRlcGFydG1lbnRzDQoyKSBEaXN0cmlidXRpb24gb2YgaXRlbXMgb3JkZXJlZCBieSB0b3AgMjAgYWlzbGVzLCBieSB2b2x1bWUgKG5vIG9mIG9yZGVycykgDQozKSBEaXN0cmlidXRpb24gb2YgaXRlbXMgb2YgdG9wIDMgZGVwYXJ0bWVudHMsIGJyb2tlbiBkb3duIGJ5IGFpc2xlcw0KNCkgRGlzdHJpYnV0aW9uIG9mIGl0ZW1zIG9mIHRvcCAyMCBwcm9kdWN0IG5hbWVzDQo1KSBEaXN0cmlidXRpb24gb2YgaXRlbXMgb2YgdG9wIDMgYWlzbGVzLCBicm9rZW4gZG93biBieSBwcm9kdWN0IG5hbWVzDQoNCg0KIyMgRGlzdHJpYnV0aW9uIG9mIGl0ZW1zIG9yZGVyZWQgYnkgZGVwYXJ0bWVudHMNCg0KVGhlcmUgYXJlIGFsdG9nZXRoZXIgMjEgZGVwYXJ0bWVudHMuIEJlbG93IGlzIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlc2UgZGVwYXJ0bWVudHMgaW4gdm9sdW1lIG9mIGl0ZW1zIG9yZGVyZWQuDQoNClRoZXJlIGlzIGEgdG90YWwgb2YgNTgyMDIwNCByb3dzIG9mIG9yZGVyZWQgaXRlbXMgaW4gZGVwYXJ0bWVudHMuIENvbnZlcnNpb24gdG8gcGVyY2VudGFnZSBpcyAxMDAvNTgyMDIwNCA9IDAuMDAwMDE3MTgxNQ0KDQpgYGB7ciBlY2hvID0gRkFMU0V9DQoNCiMgTG9hZCBsaWJyYXJpZXMNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeShwbG90cml4KQ0KbGlicmFyeShzY2FsZXMpDQpsaWJyYXJ5KGdvb2dsZVZpcykNCmxpYnJhcnkoVHJhTWluZVIpDQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgc2V0d2QoIn4vRGF0YSBBbmFseXRpY3MvUENQIHByb2plY3QgLSBJbnN0YWNhcnQvMTAwX1N0YWdlcy8wMDFfSm9pbl90YWJsZXMvIikNCmpvaW5fdGFibGUgPC0gZnJlYWQoIn4vRGF0YSBBbmFseXRpY3MvUENQIHByb2plY3QgLSBJbnN0YWNhcnQvMTAwX1N0YWdlcy8wMDFfSm9pbl90YWJsZXMvam9pbl90YWJsZV90cmFpbi5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gVCkNCg0KZGF0YSA8LSBqb2luX3RhYmxlICU+JSBzZWxlY3QocHJvZHVjdF9uYW1lLCBkZXBhcnRtZW50LCBhaXNsZSwgcmVvcmRlcmVkLCBhZGRfdG9fY2FydF9vcmRlciwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyX251bWJlciwgb3JkZXJfZG93LCBvcmRlcl9ob3VyX29mX2RheSkNCmRhdGEgJT4lIGdyb3VwX2J5KGRlcGFydG1lbnQsIHJlb3JkZXJlZCkgJT4lIHN1bW1hcmlzZShmcmVxID0gbigpKSAlPiUgDQogIGdyb3VwX2J5KGRlcGFydG1lbnQpICU+JSBtdXRhdGUocGVyY2VudGFnZSA9IHBlcmNlbnQoZnJlcS9zdW0oZnJlcSkpLCB0b3QgPSBzdW0oZnJlcSkpICU+JQ0KICBhcnJhbmdlKGRlc2ModG90KSkgJT4lDQogIGdncGxvdChhZXMocmVvcmRlcihkZXBhcnRtZW50LCB0b3QpLCBmcmVxLCBmaWxsID0gZmFjdG9yKHJlb3JkZXJlZCkpKSArIHNjYWxlX3lfY29udGludW91cyhzZWMuYXhpcyA9IHNlY19heGlzKH4uKjAuMDAwMDE3MTgxNSwgbmFtZSA9ICIlIG9mIGRlcGFydG1lbnQiKSkgKyBnZW9tX2NvbCgpICsgY29vcmRfZmxpcCgpICsgZ2d0aXRsZSgiSXRlbXMgb3JkZXJlZCBieSBEZXBhcnRtZW50cyIpICsgDQogIGxhYnMoeSA9ICJGcmVxdWVuY3kgb2YgaXRlbXMiLCB4ID0gIkRlcGFydG1lbnRzIikgKw0KICB0aGVtZV9idygpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwgDQogICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50YWdlKSwgaGp1c3QgPSAyLCBzaXplID0gMywgcG9zaXRpb24gPSJzdGFjayIpDQpgYGANCg0KVGhlIHRvcCAzIGRlcGFydG1lbnRzIGNvbWVzIGZyb20gcHJvZHVjZSwgZGFpcnkgZWdncyBmb2xsb3dlZCBieSBzbmFja3MuIE5leHQgd2UgYXJlIGdvaW5nIHRvIGJlIGxvb2tpbmcgYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBhaXNsZXMgYXMgd2VsbCBhcyBpbmRpdmlkdWFsIGFpc2xlcyB3aXRoaW4gZGVwYXJ0bWVudHMuIFBlcmNlbnRhZ2Ugb2YgcmVvcmRlcnMgd2l0aGluIGVhY2ggZGVwYXJ0bWVudCBpcyBhbHNvIGhpZ2hlciB0aGFuIG5vbi1yZW9yZGVycyAoYXJvdW5kIDYwJSB3aXRoaW4gZGVwYXJ0bWVudHMpLiBPbmUgcmVhc29uIGNvdWxkIGJlIHRoZXNlIGFyZSBkYWlseSBuZWNlc3NpdGllcywgd2hpY2ggd291bGQgZXhwbGFpbiB0aGUgaGlnaCByZW9yZGVycy4NCg0KDQojIyBEaXN0cmlidXRpb24gb2YgaXRlbXMgb3JkZXJlZCBieSB0b3AgMjAgYWlzbGVzLCBieSB2b2x1bWUgKG5vIG9mIG9yZGVycykNCg0KU2luY2UgdGhlcmUgaXMgYSB0b3RhbCBvZiAxMzQgYWlzbGVzLCB3ZSB3aWxsIG5vdCBiZSBsb29raW5nIGF0IGFsbCB0aGUgYWlzbGVzLiBJbnN0ZWFkIHdlIHdpbGwgb25seSBiZSBsb29raW5nIGF0IHRoZSBkaXN0cmlidXRpb24gb2YgaXRlbXMgb3JkZXJlZCBmb3IgdGhlIHRvcCAyMCBhaXNsZXMuDQoNClRoZXJlIGlzIGEgdG90YWwgb2YgNTgyMDIwNCByb3dzIG9mIG9yZGVyZWQgaXRlbXMgaW4gZGVwYXJ0bWVudHMuIENvbnZlcnNpb24gdG8gcGVyY2VudGFnZSBpcyAxMDAvNTgyMDIwNCA9IDAuMDAwMDE3MTgxNQ0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmRhdGEgJT4lIGdyb3VwX2J5KGFpc2xlLCByZW9yZGVyZWQpICU+JSBzdW1tYXJpc2UoZnJlcSA9IG4oKSkgJT4lIA0KICBncm91cF9ieShhaXNsZSkgJT4lIG11dGF0ZShwZXJjZW50YWdlID0gcGVyY2VudChmcmVxL3N1bShmcmVxKSksIHRvdCA9IHN1bShmcmVxKSkgJT4lIA0KICBhcnJhbmdlKGRlc2ModG90KSkgJT4lIGhlYWQoNDApICU+JSANCiAgZ2dwbG90KGFlcyhyZW9yZGVyKGFpc2xlLCB0b3QpLCBmcmVxLCBmaWxsID0gZmFjdG9yKHJlb3JkZXJlZCkpKSArIA0KICBzY2FsZV95X2NvbnRpbnVvdXMoc2VjLmF4aXMgPSBzZWNfYXhpcyh+LiowLjAwMDAxNzE4MTUsIG5hbWUgPSAiJSBvZiBhaXNsZXMiKSkgKyANCiAgZ2VvbV9jb2woKSArIGNvb3JkX2ZsaXAoKSArDQogIGdndGl0bGUoIkl0ZW1zIG9yZGVyZWQgYnkgdG9wIDIwIEFpc2xlcyIpICsgbGFicyh5ID0gIkZyZXF1ZW5jeSBvZiBpdGVtcyIsIHggPSAiQWlzbGVzIikgKw0KICB0aGVtZV9idygpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwNCiAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnRhZ2UpLCBoanVzdCA9IDIsIHNpemUgPSAzLCBwb3NpdGlvbiA9InN0YWNrIikNCmBgYA0KDQpOb3RpY2UgdGhhdCB0aGUgdG9wIDIgYWlzbGVzIChmcmVzaCBmcnVpdHMsIGZyZXNoIHZlZ2V0YWJsZXMpIGFyZSBoaWdoZXIgdGhhbiB0aGUgcmVzdCBhbmQgYWNjb3VudCBmb3IgbW9yZSB0aGFuIDIwJSBvZiBhbGwgYWlzbGVzLiBSZW9yZGVycyBpcyBhbHNvIHNpZ25pZmljYW50bHkgaGlnaGVyICg3MiUpIGluIGZyZXNoIGZydWl0cyBjb21wYXJlZCB0byBvdGhlciBhaXNsZXMuDQoNCkhvdyBkb2VzIHRoZSBhaXNsZSBkaXN0cmlidXRpb24gbG9vayBsaWtlIGZvciB0aGUgdG9wIDMgZGVwYXJ0bWVudHMgKHByb2R1Y2UsIGRhaXJ5IGVnZ3MsIHNuYWNrcyk/DQoNCg0KIyMgRGlzdHJpYnV0aW9uIG9mIGl0ZW1zIG9mIHRvcCAzIGRlcGFydG1lbnRzLCBicm9rZW4gZG93biBieSBhaXNsZXMNCg0KVGhlIHRvcCAzIGRlcGFydG1lbnRzIChwcm9kdWNlLCBkYWlyeSBlZ2dzIGFuZCBzbmFja3MpIGhhdmUgMTcwMjQwNSwgOTY3NjUwIGFuZCA1MDc5NjAgcm93cyBvZiBpdGVtcyBjb3JyZXNwb25kaW5nIHRvIGEgY29udmVyc2lvbiByYXRpbyB0byBwZXJjZW50YWdlIG9mIDAuMDAwMDU4NzQwNDI4OSwgMC4wMDAxMDMzNDMgYW5kIDAuMDAwMTk2ODY1IHJlc3BlY3RpdmVseS4NCg0KYGBge3IsIGVjaG8gPSBGfQ0KIyBucm93cyBpbiBwcm9kdWNlID0gMTcwMjQwNS4gQ29udmVyc2lvbiB0byBwZXJjZW50YWdlID0gMTAwLzE3MDI0MDUNCmRhdGEgJT4lIGZpbHRlcihkZXBhcnRtZW50ID09ICJwcm9kdWNlIikgJT4lIGdyb3VwX2J5KGFpc2xlLCByZW9yZGVyZWQpICU+JSBzdW1tYXJpc2UoZnJlcSA9IG4oKSkgJT4lIA0KICBncm91cF9ieShhaXNsZSkgJT4lIG11dGF0ZShwZXJjZW50YWdlID0gcGVyY2VudChmcmVxL3N1bShmcmVxKSksIHRvdCA9IHN1bShmcmVxKSkgJT4lIA0KICBhcnJhbmdlKGRlc2ModG90KSkgJT4lIGhlYWQoNDApICU+JQ0KICBnZ3Bsb3QoYWVzKHJlb3JkZXIoYWlzbGUsIHRvdCksIGZyZXEsIGZpbGwgPSBmYWN0b3IocmVvcmRlcmVkKSkpICsgDQogIHNjYWxlX3lfY29udGludW91cyhzZWMuYXhpcyA9IHNlY19heGlzKH4uKjAuMDAwMDU4NzQwNDI4OSwgbmFtZSA9ICIlIG9mIHByb2R1Y2UgZGVwdCIpKSArDQogIGdlb21fY29sKCkgKyBjb29yZF9mbGlwKCkgKw0KICBnZ3RpdGxlKCJJdGVtcyBvZiBQcm9kdWNlIERlcHQgb3JkZXJlZCBieSBBaXNsZXMiKSArIGxhYnMoeSA9ICJGcmVxdWVuY3kgb2YgaXRlbXMiLCB4ID0gIkFpc2xlcyIpICsNCiAgdGhlbWVfYncoKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksDQogICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50YWdlKSwgaGp1c3QgPSAyLCBzaXplID0gMywgcG9zaXRpb24gPSJzdGFjayIpDQoNCiMgbnJvd3MgaW4gcHJvZHVjZSA9IDk2NzY1MC4gQ29udmVyc2lvbiB0byBwZXJjZW50YWdlID0gMTAwLzk2NzY1MA0KZGF0YSAlPiUgZmlsdGVyKGRlcGFydG1lbnQgPT0gImRhaXJ5IGVnZ3MiKSAlPiUgZ3JvdXBfYnkoYWlzbGUsIHJlb3JkZXJlZCkgJT4lIHN1bW1hcmlzZShmcmVxID0gbigpKSAlPiUgDQogIGdyb3VwX2J5KGFpc2xlKSAlPiUgbXV0YXRlKHBlcmNlbnRhZ2UgPSBwZXJjZW50KGZyZXEvc3VtKGZyZXEpKSwgdG90ID0gc3VtKGZyZXEpKSAlPiUgIA0KICBhcnJhbmdlKGRlc2ModG90KSkgJT4lIGhlYWQoNDApICU+JQ0KICBnZ3Bsb3QoYWVzKHJlb3JkZXIoYWlzbGUsIHRvdCksIGZyZXEsIGZpbGwgPSBmYWN0b3IocmVvcmRlcmVkKSkpICsgDQogIHNjYWxlX3lfY29udGludW91cyhzZWMuYXhpcyA9IHNlY19heGlzKH4uKjAuMDAwMTAzMzQzLCBuYW1lID0gIiUgb2YgZGFpcnkgZWdncyBkZXB0IikpICsNCiAgZ2VvbV9jb2woKSArIGNvb3JkX2ZsaXAoKSArDQogIGdndGl0bGUoIkl0ZW1zIG9mIERhaXJ5IEVnZ3MgRGVwdCBvcmRlcmVkIGJ5IEFpc2xlcyIpICsgbGFicyh5ID0gIkZyZXF1ZW5jeSBvZiBpdGVtcyIsIHggPSAiQWlzbGVzIikgKw0KICB0aGVtZV9idygpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwNCiAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnRhZ2UpLCBoanVzdCA9IDIsIHNpemUgPSAzLCBwb3NpdGlvbiA9InN0YWNrIikNCg0KIyBucm93cyBpbiBzbmFja3MgPSA1MDc5NjAgQ29udmVyc2lvbiB0byBwZXJjZW50YWdlID0gMTAwLzUwNzk2MA0KZGF0YSAlPiUgZmlsdGVyKGRlcGFydG1lbnQgPT0gInNuYWNrcyIpICU+JSBncm91cF9ieShhaXNsZSwgcmVvcmRlcmVkKSAlPiUgc3VtbWFyaXNlKGZyZXEgPSBuKCkpICU+JSANCiAgZ3JvdXBfYnkoYWlzbGUpICU+JSBtdXRhdGUocGVyY2VudGFnZSA9IHBlcmNlbnQoZnJlcS9zdW0oZnJlcSkpLCB0b3QgPSBzdW0oZnJlcSkpICU+JSAgDQogIGFycmFuZ2UoZGVzYyh0b3QpKSAlPiUgaGVhZCg0MCkgJT4lDQogIGdncGxvdChhZXMocmVvcmRlcihhaXNsZSwgdG90KSwgZnJlcSwgZmlsbCA9IGZhY3RvcihyZW9yZGVyZWQpKSkgKyANCiAgc2NhbGVfeV9jb250aW51b3VzKHNlYy5heGlzID0gc2VjX2F4aXMofi4qMC4wMDAxOTY4NjUsIG5hbWUgPSAiJSBvZiBzbmFja3MgZGVwdCIpKSArDQogIGdlb21fY29sKCkgKyBjb29yZF9mbGlwKCkgKw0KICBnZ3RpdGxlKCJJdGVtcyBvZiBTbmFja3MgRGVwdCBvcmRlcmVkIGJ5IEFpc2xlcyIpICsgbGFicyh5ID0gIkZyZXF1ZW5jeSBvZiBpdGVtcyIsIHggPSAiQWlzbGVzIikgKw0KICB0aGVtZV9idygpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwNCiAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnRhZ2UpLCBoanVzdCA9IDIsIHNpemUgPSAzLCBwb3NpdGlvbiA9InN0YWNrIikNCmBgYA0KDQpCb3RoIGZyZXNoIGZydWl0cyBhbmQgZnJlc2ggdmVnZXRhYmxlcyB3aGljaCBhcmUgdGhlIDIgaGlnaGVzdCBhaXNsZXMgd2l0aGluIHByb2R1Y2UgZGVwYXJ0bWVudCAoYXJvdW5kIDc1JSBvZiBwcm9kdWNlIGRlcGFydG1lbnQpIGhlbHAgdG8gZXhwbGFpbiB0aGUgbWFpbiBidWxrIG9mICpBTEwqIG9yZGVycyBpbiB3aGljaCAyOSUgY29tZXMgZnJvbSBwcm9kdWNlIGRlcGFydG1lbnQuIA0KDQpOb3RpY2UgdGhlIHJlb3JkZXIgcmF0aW8gZm9yIG1pbGsgaXMgbXVjaCBoaWdoZXIgdGhhbiB0aGUgcmVzdCB3aXRoaW4gZGFpcnkgZWdncyBkZXBhcnRtZW50LiBPbmUgcmVhc29uIGNvdWxkIGJlIHRoZSB2ZXJ5IHNob3J0IHNoZWxmIGxpZmUgb2YgbWlsaywgaGVuY2Ugd2l0aGluIHRoZSBvbmUgeWVhciBwZXJpb2Qgb2YgdGhlIHJlY29yZGVkIGRhdGEsIG1vcmUgbWlsayB3aWxsIGJlIHJlb3JkZXJlZCBjb21wYXJlZCB0byBvdGhlciBhaXNsZXMuDQoNCldlIHdpbGwgbmV4dCBsb29rIGF0IGluZGl2aWR1YWwgcHJvZHVjdHMgYW5kIHRoZSBtb3N0IGNvbW1vbmx5IG9yZGVyZWQgb25lcy4NCg0KIyMgRGlzdHJpYnV0aW9uIG9mIGl0ZW1zIG9mIHRvcCAyMCBwcm9kdWN0IG5hbWVzDQoNCldlIHdpbGwgbm93IGxvb2sgYXQgdGhlIHRvcCAyMCBtb3N0IG9yZGVyZWQgcHJvZHVjdHMgYW5kIHRoZWlyIHJlb3JkZXIgcmF0aW8uDQoNCmBgYHtyLCBlY2hvID0gRn0NCiMgbnJvd3MgaW4gcHJvZHVjdHMgPSA1ODIwMjA0LiBDb252ZXJzaW9uIHRvIHBlcmNlbnRhZ2UgPSAxMDAvNTgyMDIwNA0KdG1wIDwtIGRhdGEgJT4lIGdyb3VwX2J5KHByb2R1Y3RfbmFtZSwgcmVvcmRlcmVkKSAlPiUgc3VtbWFyaXNlKGZyZXEgPSBuKCkpICU+JQ0KICBncm91cF9ieShwcm9kdWN0X25hbWUpICU+JSBtdXRhdGUocGVyY2VudGFnZSA9IHBlcmNlbnQoZnJlcS9zdW0oZnJlcSkpLHRvdCA9IHN1bShmcmVxKSkgJT4lDQogIGFycmFuZ2UoZGVzYyh0b3QpKSAlPiUgaGVhZCg0MCkNCiMgZGF0YSAlPiUgZ3JvdXBfYnkocHJvZHVjdF9uYW1lLCByZW9yZGVyZWQpICU+JSBzdW1tYXJpc2UoZnJlcSA9IG4oKSkgJT4lDQojICAgZ3JvdXBfYnkocHJvZHVjdF9uYW1lKSAlPiUgbXV0YXRlKHBlcmNlbnRhZ2UgPSBwZXJjZW50KGZyZXEvc3VtKGZyZXEpKSx0b3QgPSBzdW0oZnJlcSkpICU+JSBhcnJhbmdlKGRlc2ModG90KSkgJT4lIGhlYWQoNDApICU+JQ0KdG1wICU+JSANCiAgZ2dwbG90KGFlcyhyZW9yZGVyKHByb2R1Y3RfbmFtZSwgdG90KSwgZnJlcSwgZmlsbCA9IGZhY3RvcihyZW9yZGVyZWQpKSkgKyANCiAgc2NhbGVfeV9jb250aW51b3VzKHNlYy5heGlzID0gc2VjX2F4aXMofi4qMC4wMDAwMTcxODE1LCBuYW1lID0gIiUgb2YgcHJvZHVjdHMiKSkgKw0KICBnZW9tX2NvbCgpICsgY29vcmRfZmxpcCgpICsNCiAgZ2d0aXRsZSgiSXRlbXMgb3JkZXJlZCBieSB0b3AgMjAgUHJvZHVjdHMiKSArIGxhYnMoeSA9ICJGcmVxdWVuY3kgb2YgaXRlbXMiLCB4ID0gIlByb2R1Y3RzIikgKw0KICB0aGVtZV9idygpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwNCiAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnRhZ2UpLCBoanVzdCA9IDIsIHNpemUgPSAzLCBwb3NpdGlvbiA9InN0YWNrIikNCmBgYA0KDQpGcm9tIHRoZSBncmFwaCBhYm92ZSwgdGhlIG1vc3QgcG9wdWxhciBwcm9kdWN0cyBvcmRlcmVkIGFyZSBiYW5hbmFzIGFuZCBvcmdhbmljIGJhbmFuYXMsIGFjY291bnRpbmcgZm9yIGFyb3VuZCAyLjUlIG9mIGFsbCBvcmRlcnMuIE5vdGljZSB0aGF0IHRoZSByZW9yZGVyIHJhdGlvIGlzIGFsc28gc2lnbmlmaWNhbnRseSBoaWdoZXIgdGhhbiB0aGUgcmVzdCAoODUlKS4gDQoNClRoZSBjb21tb25seSBvcmRlcmVkIHByb2R1Y3RzIGFyZSBtYWlubHkgZnJ1aXRzIGFuZCBzb21lIGl0ZW1zIGZvciBjb29raW5nIGluZ3JlZGllbnRzIHN1Y2ggYXMgZ2FybGljLCB6dWNjaGluaSwgY3VjdW1iZXIuDQoNCkFub3RoZXIgaW50ZXJlc3RpbmcgdGhpbmcgdG8gbm90ZSBpcyB0aGUgbGFyZ2UgbnVtYmVyIG9mIG9yZ2FuaWMgaXRlbXMgaW4gdGhlIHRvcCAyMCBwb3B1bGFyIHByb2R1Y3RzICgxNCBvdXQgb2YgMjAgYXJlIG9yZ2FuaWMpLiBXZSBjYW4gY29uY2x1ZGUgdGhhdCBxdWl0ZSBhIHN1YnN0YW50aWFsIHNlZ21lbnQgb2YgdGhlIGN1c3RvbWVycyBhcmUgaGVhbHRoIGNvbnNjaW91cyB0aHJvdWdoIHRoZWlyIGNob2ljZSBvZiBvcmdhbmljIHByb2R1Y3RzLg0KDQpXZSBzaGFsbCBuZXh0IHByb2NlZWQgdG8gc2VlIHRoZSBkaXN0cmlidXRpb24gb2YgcHJvZHVjdHMgd2l0aGluIHRoZSB0b3AgMyBhaXNsZXMgKGZyZXNoIGZydWl0cywgZnJlc2ggdmVnZXRhYmxlcywgcGFja2FnZWQgdmVnZXRhYmxlcyBmcnVpdHMpDQoNCiMjIERpc3RyaWJ1dGlvbiBvZiBpdGVtcyBvZiB0b3AgMyBhaXNsZXMsIGJyb2tlbiBkb3duIGJ5IHByb2R1Y3QgbmFtZXMNCg0KQXMgaW5kaWNhdGVkIGFib3ZlLCB0aGUgdG9wIDMgYWlzbGVzIGFyZSBmcmVzaCBmcnVpdHMsIGZyZXNoIHZlZ2V0YWJsZXMgYW5kIHBhY2thZ2VkIHZlZ2V0YWJsZXMgZnJ1aXRzLiANCg0KYGBge3IsIGVjaG8gPSBGfQ0KIyBucm93cyBpbiBhaXNsZSBmcmVzaCBmcnVpdHMgPSA2NTA2NzQuIENvbnZlcnNpb24gdG8gcGVyY2VudGFnZSA9IDEwMC82NTA2NzQNCmRhdGEgJT4lIGZpbHRlcihhaXNsZSA9PSAiZnJlc2ggZnJ1aXRzIikgJT4lIGdyb3VwX2J5KHByb2R1Y3RfbmFtZSwgcmVvcmRlcmVkKSAlPiUgc3VtbWFyaXNlKGZyZXEgPSBuKCkpICU+JQ0KICBncm91cF9ieShwcm9kdWN0X25hbWUpICU+JSBtdXRhdGUocGVyY2VudGFnZSA9IHBlcmNlbnQoZnJlcS9zdW0oZnJlcSkpLHRvdCA9IHN1bShmcmVxKSkgJT4lDQogIGFycmFuZ2UoZGVzYyh0b3QpKSAlPiUgaGVhZCg0MCkgJT4lDQogIGdncGxvdChhZXMocmVvcmRlcihwcm9kdWN0X25hbWUsIHRvdCksIGZyZXEsIGZpbGwgPSBmYWN0b3IocmVvcmRlcmVkKSkpICsgDQogIHNjYWxlX3lfY29udGludW91cyhzZWMuYXhpcyA9IHNlY19heGlzKH4uKjAuMDAwMTUzNjg2LCBuYW1lID0gIiUgb2YgZnJlc2ggZnJ1aXQgYWlzbGUiKSkgKw0KICBnZW9tX2NvbCgpICsgY29vcmRfZmxpcCgpICsNCiAgZ2d0aXRsZSgiSXRlbXMgb3JkZXJlZCBieSB0b3AgMjAgUHJvZHVjdHMiKSArIGxhYnMoeSA9ICJGcmVxdWVuY3kgb2YgaXRlbXMiLCB4ID0gIlByb2R1Y3RzIikgKw0KICB0aGVtZV9idygpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwNCiAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKyANCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBlcmNlbnRhZ2UpLCBoanVzdCA9IDIsIHNpemUgPSAzLCBwb3NpdGlvbiA9InN0YWNrIikNCg0KIyBucm93cyBpbiBhaXNsZSBmcmVzaCB2ZWdldGFibGVzID0gNjE2NTQ3LiBDb252ZXJzaW9uIHRvIHBlcmNlbnRhZ2UgPSAxMDAvNjE2NTQ3DQpkYXRhICU+JSBmaWx0ZXIoYWlzbGUgPT0gImZyZXNoIHZlZ2V0YWJsZXMiKSAlPiUgZ3JvdXBfYnkocHJvZHVjdF9uYW1lLCByZW9yZGVyZWQpICU+JSBzdW1tYXJpc2UoZnJlcSA9IG4oKSkgJT4lDQogIGdyb3VwX2J5KHByb2R1Y3RfbmFtZSkgJT4lIG11dGF0ZShwZXJjZW50YWdlID0gcGVyY2VudChmcmVxL3N1bShmcmVxKSksdG90ID0gc3VtKGZyZXEpKSAlPiUNCiAgYXJyYW5nZShkZXNjKHRvdCkpICU+JSBoZWFkKDQwKSAlPiUNCiAgZ2dwbG90KGFlcyhyZW9yZGVyKHByb2R1Y3RfbmFtZSwgdG90KSwgZnJlcSwgZmlsbCA9IGZhY3RvcihyZW9yZGVyZWQpKSkgKyANCiAgc2NhbGVfeV9jb250aW51b3VzKHNlYy5heGlzID0gc2VjX2F4aXMofi4qMC4wMDAxNjIxOTM2NCwgbmFtZSA9ICIlIG9mIGZyZXNoIHZlZ2V0YWJsZSBhaXNsZSIpKSArDQogIGdlb21fY29sKCkgKyBjb29yZF9mbGlwKCkgKw0KICBnZ3RpdGxlKCJJdGVtcyBvcmRlcmVkIGJ5IHRvcCAyMCBQcm9kdWN0cyIpICsgbGFicyh5ID0gIkZyZXF1ZW5jeSBvZiBpdGVtcyIsIHggPSAiUHJvZHVjdHMiKSArDQogIHRoZW1lX2J3KCkgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSwgZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAwLjUpLA0KICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArIA0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudGFnZSksIGhqdXN0ID0gMiwgc2l6ZSA9IDMsIHBvc2l0aW9uID0ic3RhY2siKQ0KDQojIG5yb3dzIGluIGFpc2xlIHBhY2thZ2VkIHZlZ2V0YWJsZXMgZnJ1aXRzID0gMzE2ODg1LiBDb252ZXJzaW9uIHRvIHBlcmNlbnRhZ2UgPSAxMDAvMzE2ODg1DQpkYXRhICU+JSBmaWx0ZXIoYWlzbGUgPT0gInBhY2thZ2VkIHZlZ2V0YWJsZXMgZnJ1aXRzIikgJT4lIGdyb3VwX2J5KHByb2R1Y3RfbmFtZSwgcmVvcmRlcmVkKSAlPiUgc3VtbWFyaXNlKGZyZXEgPSBuKCkpICU+JQ0KICBncm91cF9ieShwcm9kdWN0X25hbWUpICU+JSBtdXRhdGUocGVyY2VudGFnZSA9IHBlcmNlbnQoZnJlcS9zdW0oZnJlcSkpLHRvdCA9IHN1bShmcmVxKSkgJT4lDQogIGFycmFuZ2UoZGVzYyh0b3QpKSAlPiUgaGVhZCg0MCkgJT4lDQogIGdncGxvdChhZXMocmVvcmRlcihwcm9kdWN0X25hbWUsIHRvdCksIGZyZXEsIGZpbGwgPSBmYWN0b3IocmVvcmRlcmVkKSkpICsgDQogIHNjYWxlX3lfY29udGludW91cyhzZWMuYXhpcyA9IHNlY19heGlzKH4uKjAuMDAwMzE1NTcxOSwgbmFtZSA9ICIlIG9mIHBhY2thZ2VkIHZlZ2V0YWJsZXMgZnJ1aXRzIGFpc2xlIikpICsNCiAgZ2VvbV9jb2woKSArIGNvb3JkX2ZsaXAoKSArDQogIGdndGl0bGUoIkl0ZW1zIG9yZGVyZWQgYnkgdG9wIDIwIFByb2R1Y3RzIikgKyBsYWJzKHkgPSAiRnJlcXVlbmN5IG9mIGl0ZW1zIiwgeCA9ICJQcm9kdWN0cyIpICsNCiAgdGhlbWVfYncoKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksDQogICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsgDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50YWdlKSwgaGp1c3QgPSAyLCBzaXplID0gMywgcG9zaXRpb24gPSJzdGFjayIpDQpgYGANCg0KTW9zdCBvZiB0aGUgcHJvZHVjdHMgdGhhdCB3ZSBhcmUgc2VlaW5nIGFscmVhZHkgZmFsbHMgaW4gdGhlIHByZXZpb3VzIHBsb3QgZm9yIG1vc3QgY29tbW9ubHkgb3JkZXJlZCBwcm9kdWN0cy4gDQoNCiMjIENvbmNsdXNpb24NCg0KVGhpcyBleHBsb3JhdG9yeSBwaGFzZSBoZWxwcyB1cyBpbiB1bmRlcnN0YW5kaW5nIHdoYXQgYXJlIHRoZSBtb3N0IGNvbW1vbmx5IG9yZGVyZWQgaXRlbXMgYW5kIGdpdmUgdXMgaW5zaWdodCBvbiBjdXN0b21lcnMnIGJ1eWluZyBoYWJpdHMuIEhvd2V2ZXIsIGl0IGRvZXMgbm90IHNob3cgYW55IHJlbGF0aW9uIGJldHdlZW4gdGhlIHR5cGVzIG9mIHByb2R1Y3RzIG9yZGVyZWQgd2l0aGluIGEgYmFza2V0IG9yIGJldHdlZW4gb3JkZXJzLiBXZSB3aWxsIGV4cGxvcmUgc3VjaCByZWxhdGlvbnNoaXAgZnVydGhlciB1c2luZyBTYW5za2V5IGRpYWdyYW1zIGFuZCBzb21lIHNlcXVlbmNlIG1pbmluZyBSIHBhY2thZ2VzIHRvIHNlZSB0aGUgbW9zdCBjb21tb24gc2VxdWVuY2Ugb2YgaXRlbXMuDQoNCg==