RFM

RFM 모형은 거래량을 통해 고객들의 행동을 분석하는 것이다. R 은 recency ; 얼마나 최근에 고객들이 구매 했는가 F 은 frequency : 얼마나 자주 구매하는가 M 은 monetry : 얼만큼의 돈을 지불하는가

RFM 모형은 다양한 고객 카테고리 중 프로모션에 가장 잘 반응하는 고객을 파악하는데 유용하다.

rfm 에는 rfm_data_orders 데이터가 있음

unique id date of transaction/order : 거래 발생 날짜 transcation / order amount : 거래량

RFM Score 란?

  1. 가장 최근 구매 날짜의 고객들에게 할당하는 점수 - recency score 초기값 5을 기준으로 세분화시킨다. 예를 들어, 만약 4 까지의 범주형 변수를 만들기 위해서는 가장 최근에 구매한 사람에게 4 점을 할당하고 구매한지 오래된 고객에게는 1을 부여한다.

  2. Frequency rank 점수도 위와 같이 비슷하게 준다 (자주 구매하는 사람)

  3. Monetary score는 분석 기간에 대한 금액을 기준으로 할당한다. 금액이 많으면 높은 score 를 주고 금액이 낮으면 1을 준다

  4. fourch 점수, RFM 점수는 이 세 가지이 점수가 점접하는 하나의 점수를 말한다.

    RFM 점수가 높으면 프로모션 진행 시 반응 할 것으로 예상 하는 것이다.

rfm_table_order() 함수는 각 score를 계산해서 나타내준다.

## # A tibble: 995 x 9
##    customer_id date_most_recent recency_days transaction_cou~ amount
##    <chr>       <date>                  <dbl>            <dbl>  <dbl>
##  1 Abbey O'Re~ 2006-06-09                205                6    472
##  2 Add Senger  2006-08-13                140                3    340
##  3 Aden Lesch~ 2006-06-20                194                4    405
##  4 Admiral Se~ 2006-08-21                132                5    448
##  5 Agness O'K~ 2006-10-02                 90                9    843
##  6 Aileen Bar~ 2006-10-08                 84                9    763
##  7 Ailene Her~ 2006-03-25                281                8    699
##  8 Aiyanna Br~ 2006-04-29                246                4    157
##  9 Ala Schmid~ 2006-01-16                349                3    363
## 10 Alannah Bo~ 2005-04-21                619                4    196
## # ... with 985 more rows, and 4 more variables: recency_score <int>,
## #   frequency_score <int>, monetary_score <int>, rfm_score <dbl>

###HEAT MAP

최근 구매 기준과 freqency score 별 평균 구매 금액 (monetary)을 나타내준다.

Frequency Score가 높을 수록 (즉, 자주 구매하는 정도가 많을 수록) 평균 구매 금액이 높다는 부분이 heat map 의 어두운 부분이다.

###Bar Chart

각 Frequency Score (자주 구매 점수)와 Recent Score (가장 최근 구매 점수) 간의 비율을 확인 할 수 있다.

###Histogram

각 RFM 의 분포도를 확인 할 수 있다.

###Customer by Orders

각 고객들의 구매 분포를 알 수 있다.

###Scatter Plot

최근 구매하는 것과 돈을 쓰는 것의 관계성을 알아 볼 수 있다.

Recency VS Monetary

Frequecny VS Monetary

Recency VS Freqency

최근 방문한 사람들은 오래전 방문했던 사람들 보다 다시 돌아 오는 경향이 있다. 즉, 높은 빈도수는 얼마나 자주 방문하는가로 이해할 수 있다.

사진

사진

위의 표를 기준으로 전부 세분화 시켜주기 -

segment <- c(
  "Champions", "Loyal Customers", "Potential Loyalist",
  "New Customers", "Promising", "Need Attention",
  "About To Sleep", "At Risk", "Can't Lose Them", "Hibernating",
  "Lost")
description <- c(
  "Bought recently, buy often and spend the most",
  "Spend good money. Responsive to promotions",
  "Recent customers, spent good amount, bought more than once",
  "Bought more recently, but not often",
  "Recent shoppers, but haven't spent much",
  "Above average recency, frequency & monetary values",
  "Below average recency, frequency & monetary values",
  "Spent big money, purchased often but long time ago",
  "Made big purchases and often, but long time ago",
  "Low spenders, low frequency, purchased long time ago",
  "Lowest recency, frequency & monetary scores")
recency <- c("4 - 5", "2 - 5", "3 - 5", "4 - 5", "3 - 4", "2 - 3", "2 - 3", "<= 2", "<= 1", "1 - 2", "<= 2")
frequency <- c("4 - 5", "3 - 5", "1 - 3", "<= 1", "<= 1", "2 - 3", "<= 2", "2 - 5", "4 - 5", "1 - 2", "<= 2")
monetary <- c("4 - 5", "3 - 5", "1 - 3", "<= 1", "<= 1", "2 - 3", "<= 2", "2 - 5", "4 - 5", "1 - 2", "<= 2")
segments <- tibble(
  Segment = segment, Description = description,
  R = recency, `F` = frequency, M = monetary
)



segment_names <- c("Champions", "Loyal Customers", "Potential Loyalist",
  "New Customers", "Promising", "Need Attention", "About To Sleep",
  "At Risk", "Can't Lose Them", "Lost")
recency_lower <- c(4, 2, 3, 4, 3, 2, 2, 1, 1, 1)
recency_upper <- c(5, 5, 5, 5, 4, 3, 3, 2, 1, 2)
frequency_lower <- c(4, 3, 1, 1, 1, 2, 1, 2, 4, 1)
frequency_upper <- c(5, 5, 3, 1, 1, 3, 2, 5, 5, 2)
monetary_lower <- c(4, 3, 1, 1, 1, 2, 1, 2, 4, 1)
monetary_upper <- c(5, 5, 3, 1, 1, 3, 2, 5, 5, 2)
segments <- rfm_segment(rfm_table, segment_names, recency_lower, recency_upper,
frequency_lower, frequency_upper, monetary_lower, monetary_upper)

segments %>%
  datatable(
    filter = "top",
    options = list(pageLength = 5, autoWidth = TRUE),
    colnames = c(
      "Customer", "Segment", "RFM",
      "Orders", "Recency", "Total Spend"
    )
  )

i{r}

LS0tDQp0aXRsZTogIlJGTSBBbmF5bHNpcyINCmF1dGhvcjogIkRPRVVOIg0KZGF0ZTogIjIzLzAyLzIwMjEiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICAjIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGhpZ2hsaWdodDogemVuYnVybg0KICAgICMgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogImZsYXRseSINCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCi0tLQ0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBUUlVFKQ0KDQojaW5zdGFsbC5wYWNrYWdlcygiY2FyZXQiLCBkZXBlbmRlbmNpZXM9VFJVRSkgDQojaW5zdGFsbC5wYWNrYWdlcygicHN5Y2giKQ0KDQojaW5zdGFsbC5wYWNrYWdlcygicmZtIikNCiMgSW5zdGFsbCBkZXZlbG9wbWVudCB2ZXJzaW9uIGZyb20gR2l0SHViDQojIGluc3RhbGwucGFja2FnZXMoImRldnRvb2xzIikNCmxpYnJhcnkocmZtKQ0KbGlicmFyeShEVCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGRwbFIpDQojZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJyc3F1YXJlZGFjYWRlbXkvcmZtIikNCmBgYA0KDQojIFJGTSANCg0KUkZNIOuqqO2YleydgCDqsbDrnpjrn4nsnYQg7Ya17ZW0IOqzoOqwneuTpOydmCDtlonrj5nsnYQg67aE7ISd7ZWY64qUIOqyg+ydtOuLpC4gDQpSIOydgCByZWNlbmN5IDsg7Ja866eI64KYIOy1nOq3vOyXkCDqs6DqsJ3rk6TsnbQg6rWs66ekIO2WiOuKlOqwgCANCkYg7J2AIGZyZXF1ZW5jeSA6IOyWvOuniOuCmCDsnpDso7wg6rWs66ek7ZWY64qU6rCADQpNIOydgCBtb25ldHJ5IDog7Ja866eM7YG87J2YIOuPiOydhCDsp4DrtojtlZjripTqsIAgDQoNClJGTSDrqqjtmJXsnYAg64uk7JaR7ZWcIOqzoOqwnSDsubTthYzqs6Drpqwg7KSRIO2UhOuhnOuqqOyFmOyXkCDqsIDsnqUg7J6YIOuwmOydke2VmOuKlA0K6rOg6rCd7J2EIO2MjOyVhe2VmOuKlOuNsCDsnKDsmqntlZjri6QuIA0KDQoNCnJmbSDsl5DripQgcmZtX2RhdGFfb3JkZXJzIOuNsOydtO2EsOqwgCDsnojsnYwgDQoNCnVuaXF1ZSBpZCANCmRhdGUgb2YgdHJhbnNhY3Rpb24vb3JkZXIgOiDqsbDrnpgg67Cc7IOdIOuCoOynnCANCnRyYW5zY2F0aW9uIC8gb3JkZXIgYW1vdW50IDog6rGw656Y65+JIA0KIA0KDQpSRk0gU2NvcmUg656APyANCg0KMS4g6rCA7J6lIOy1nOq3vCDqtazrp6Qg64Kg7Kec7J2YIOqzoOqwneuTpOyXkOqyjCDtlaDri7ntlZjripQg7KCQ7IiYIC0gcmVjZW5jeSBzY29yZSANCiAgIOy0iOq4sOqwkiA17J2EIOq4sOykgOycvOuhnCDshLjrtoTtmZTsi5ztgqjri6QuIOyYiOulvCDrk6TslrQsIOunjOyVvSA0IOq5jOyngOydmCDrspTso7ztmJUgICAgICAgICAgICAg67OA7IiY66W8IOunjOuTpOq4sCDsnITtlbTshJzripQg6rCA7J6lIOy1nOq3vOyXkCDqtazrp6TtlZwg7IKs656M7JeQ6rKMIDQgIOygkOydhCDtlaDri7ntlZjqs6AgICAgICAgICAgIOq1rOunpO2VnOyngCDsmKTrnpjrkJwg6rOg6rCd7JeQ6rKM64qUIDHsnYQg67aA7Jes7ZWc64ukLiANCiAgIA0KICAgDQoyLiBGcmVxdWVuY3kgcmFuayDsoJDsiJjrj4Qg7JyE7JmAIOqwmeydtCDruYTsirftlZjqsowg7KSA64ukICjsnpDso7wg6rWs66ek7ZWY64qUIOyCrOuejCkNCg0KMy4gTW9uZXRhcnkgc2NvcmXripQg67aE7ISdIOq4sOqwhOyXkCDrjIDtlZwg6riI7JWh7J2EIOq4sOykgOycvOuhnCDtlaDri7ntlZzri6QuIA0KICAg6riI7JWh7J20IOunjuycvOuptCDrhpLsnYAgc2NvcmUg66W8IOyjvOqzoCDquIjslaHsnbQg64Ku7Jy866m0IDHsnYQg7KSA64ukIA0KICAgDQo0LiBmb3VyY2gg7KCQ7IiYLCBSRk0g7KCQ7IiY64qUIOydtCDshLgg6rCA7KeA7J20IOygkOyImOqwgCDsoJDsoJHtlZjripQg7ZWY64KY7J2YICAgICAgIOygkOyImOulvCDrp5DtlZzri6QuIA0KDQogICBSRk0g7KCQ7IiY6rCAIOuGkuycvOuptCDtlITroZzrqqjshZgg7KeE7ZaJIOyLnCDrsJjsnZEg7ZWgIOqyg+ycvOuhnCDsmIjsg4Eg7ZWY64qUIOqyg+ydtOuLpC4gDQoNCg0KDQpgYGB7ciBjYXJzfQ0KDQpEVDo6ZGF0YXRhYmxlKHJmbV9kYXRhX29yZGVycykNCmBgYA0KDQpyZm1fdGFibGVfb3JkZXIoKSDtlajsiJjripQg6rCBIHNjb3Jl66W8IOqzhOyCsO2VtOyEnCDrgpjtg4DrgrTspIDri6QuIA0KDQpgYGB7ciBwcmVzc3VyZSwgZWNobz1GQUxTRX0NCg0KIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAgU3RhZ2UgMSDrtoTshJ0g64Kg7KecIOyDneyEsSANCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KYW5hbHlzaXNfZGF0ZSA8LSBsdWJyaWRhdGU6OmFzX2RhdGUoIjIwMDYtMTItMzEiKQ0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojICBTdGFnZSAyIHJmbV90YWJsZV9vcmRlciDtlajsiJjroZwg6rCBIOuzgOyImCDsg53shLHtlbTso7zquLAgDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCg0KcmZtX3RhYmxlIDwtIHJmbV90YWJsZV9vcmRlcihyZm1fZGF0YV9vcmRlcnMsIGN1c3RvbWVyX2lkLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyX2RhdGUsIHJldmVudWUsIGFuYWx5c2lzX2RhdGUpDQoNCg0KDQpyZm1fdGFibGUNCg0KDQpgYGANCg0KDQojIyNIRUFUIE1BUCANCg0K7LWc6re8IOq1rOunpCDquLDspIDqs7wgZnJlcWVuY3kgc2NvcmUg67OEIO2Pieq3oCDqtazrp6Qg6riI7JWhIChtb25ldGFyeSnsnYQg64KY7YOA64K07KSA64ukLiANCg0KRnJlcXVlbmN5IFNjb3Jl6rCAIOuGkuydhCDsiJjroZ0gKOymiSwg7J6Q7KO8IOq1rOunpO2VmOuKlCDsoJXrj4TqsIAg66eO7J2EIOyImOuhnSkg7Y+J6regIOq1rOunpCDquIjslaHsnbQg64aS64uk64qUIOu2gOu2hOydtCBoZWF0IG1hcCDsnZgg7Ja065GQ7Jq0IOu2gOu2hOydtOuLpC4gDQoNCg0KYGBge3J9DQoNCnJmbV9oZWF0bWFwKHJmbV90YWJsZSkNCmBgYA0KDQojIyNCYXIgQ2hhcnQgDQoNCuqwgSBGcmVxdWVuY3kgU2NvcmUgKOyekOyjvCDqtazrp6Qg7KCQ7IiYKeyZgCBSZWNlbnQgU2NvcmUgKOqwgOyepSDstZzqt7wg6rWs66ekIOygkOyImCkNCuqwhOydmCDruYTsnKjsnYQg7ZmV7J24IO2VoCDsiJgg7J6I64ukLiANCg0KYGBge3J9DQoNCnJmbV9iYXJfY2hhcnQocmZtX3RhYmxlKQ0KYGBgDQojIyNIaXN0b2dyYW0gDQoNCuqwgSBSRk0g7J2YIOu2hO2PrOuPhOulvCDtmZXsnbgg7ZWgIOyImCDsnojri6QuIA0KDQpgYGB7cn0NCnJmbV9oaXN0b2dyYW1zKHJmbV90YWJsZSkNCmBgYA0KDQojIyNDdXN0b21lciBieSBPcmRlcnMgDQoNCuqwgSDqs6DqsJ3rk6TsnZgg6rWs66ekIOu2hO2PrOulvCDslYwg7IiYIOyeiOuLpC4gDQoNCg0KYGBge3J9DQoNCnJmbV9vcmRlcl9kaXN0KHJmbV90YWJsZSkNCmBgYA0KDQoNCiMjI1NjYXR0ZXIgUGxvdCANCg0K7LWc6re8IOq1rOunpO2VmOuKlCDqsoPqs7wg64+I7J2EIOyTsOuKlCDqsoPsnZgg6rSA6rOE7ISx7J2EIOyVjOyVhCDrs7wg7IiYIOyeiOuLpC4gDQoNClJlY2VuY3kgVlMgTW9uZXRhcnkNCg0KYGBge3J9DQpyZm1fcm1fcGxvdChyZm1fdGFibGUpDQpgYGANCg0KRnJlcXVlY255IFZTIE1vbmV0YXJ5IA0KDQpgYGB7cn0NCnJmbV9mbV9wbG90KHJmbV90YWJsZSkNCmBgYA0KDQpSZWNlbmN5IFZTIEZyZXFlbmN5IA0KDQrstZzqt7wg67Cp66y47ZWcIOyCrOuejOuTpOydgCDsmKTrnpjsoIQg67Cp66y47ZaI642YIOyCrOuejOuTpCDrs7Tri6Qg64uk7IucIOuPjOyVhCDsmKTripQg6rK97Zal7J20IOyeiOuLpC4gDQrspoksIOuGkuydgCDruYjrj4TsiJjripQg7Ja866eI64KYIOyekOyjvCDrsKnrrLjtlZjripTqsIDroZwg7J207ZW07ZWgIOyImCDsnojri6QuIA0KDQpgYGB7cn0NCg0KcmZtX3JmX3Bsb3QocmZtX3RhYmxlKQ0KYGBgDQoNCg0KIVvsgqzsp4RdKEM6L1VzZXJzLzEucG5nKQ0KDQrsnITsnZgg7ZGc66W8IOq4sOykgOycvOuhnCDsoITrtoAg7IS467aE7ZmUIOyLnOy8nOyjvOq4sCAtICANCg0KYGBge3J9DQoNCg0Kc2VnbWVudCA8LSBjKA0KICAiQ2hhbXBpb25zIiwgIkxveWFsIEN1c3RvbWVycyIsICJQb3RlbnRpYWwgTG95YWxpc3QiLA0KICAiTmV3IEN1c3RvbWVycyIsICJQcm9taXNpbmciLCAiTmVlZCBBdHRlbnRpb24iLA0KICAiQWJvdXQgVG8gU2xlZXAiLCAiQXQgUmlzayIsICJDYW4ndCBMb3NlIFRoZW0iLCAiSGliZXJuYXRpbmciLA0KICAiTG9zdCIpDQpkZXNjcmlwdGlvbiA8LSBjKA0KICAiQm91Z2h0IHJlY2VudGx5LCBidXkgb2Z0ZW4gYW5kIHNwZW5kIHRoZSBtb3N0IiwNCiAgIlNwZW5kIGdvb2QgbW9uZXkuIFJlc3BvbnNpdmUgdG8gcHJvbW90aW9ucyIsDQogICJSZWNlbnQgY3VzdG9tZXJzLCBzcGVudCBnb29kIGFtb3VudCwgYm91Z2h0IG1vcmUgdGhhbiBvbmNlIiwNCiAgIkJvdWdodCBtb3JlIHJlY2VudGx5LCBidXQgbm90IG9mdGVuIiwNCiAgIlJlY2VudCBzaG9wcGVycywgYnV0IGhhdmVuJ3Qgc3BlbnQgbXVjaCIsDQogICJBYm92ZSBhdmVyYWdlIHJlY2VuY3ksIGZyZXF1ZW5jeSAmIG1vbmV0YXJ5IHZhbHVlcyIsDQogICJCZWxvdyBhdmVyYWdlIHJlY2VuY3ksIGZyZXF1ZW5jeSAmIG1vbmV0YXJ5IHZhbHVlcyIsDQogICJTcGVudCBiaWcgbW9uZXksIHB1cmNoYXNlZCBvZnRlbiBidXQgbG9uZyB0aW1lIGFnbyIsDQogICJNYWRlIGJpZyBwdXJjaGFzZXMgYW5kIG9mdGVuLCBidXQgbG9uZyB0aW1lIGFnbyIsDQogICJMb3cgc3BlbmRlcnMsIGxvdyBmcmVxdWVuY3ksIHB1cmNoYXNlZCBsb25nIHRpbWUgYWdvIiwNCiAgIkxvd2VzdCByZWNlbmN5LCBmcmVxdWVuY3kgJiBtb25ldGFyeSBzY29yZXMiKQ0KcmVjZW5jeSA8LSBjKCI0IC0gNSIsICIyIC0gNSIsICIzIC0gNSIsICI0IC0gNSIsICIzIC0gNCIsICIyIC0gMyIsICIyIC0gMyIsICI8PSAyIiwgIjw9IDEiLCAiMSAtIDIiLCAiPD0gMiIpDQpmcmVxdWVuY3kgPC0gYygiNCAtIDUiLCAiMyAtIDUiLCAiMSAtIDMiLCAiPD0gMSIsICI8PSAxIiwgIjIgLSAzIiwgIjw9IDIiLCAiMiAtIDUiLCAiNCAtIDUiLCAiMSAtIDIiLCAiPD0gMiIpDQptb25ldGFyeSA8LSBjKCI0IC0gNSIsICIzIC0gNSIsICIxIC0gMyIsICI8PSAxIiwgIjw9IDEiLCAiMiAtIDMiLCAiPD0gMiIsICIyIC0gNSIsICI0IC0gNSIsICIxIC0gMiIsICI8PSAyIikNCnNlZ21lbnRzIDwtIHRpYmJsZSgNCiAgU2VnbWVudCA9IHNlZ21lbnQsIERlc2NyaXB0aW9uID0gZGVzY3JpcHRpb24sDQogIFIgPSByZWNlbmN5LCBgRmAgPSBmcmVxdWVuY3ksIE0gPSBtb25ldGFyeQ0KKQ0KDQoNCg0Kc2VnbWVudF9uYW1lcyA8LSBjKCJDaGFtcGlvbnMiLCAiTG95YWwgQ3VzdG9tZXJzIiwgIlBvdGVudGlhbCBMb3lhbGlzdCIsDQogICJOZXcgQ3VzdG9tZXJzIiwgIlByb21pc2luZyIsICJOZWVkIEF0dGVudGlvbiIsICJBYm91dCBUbyBTbGVlcCIsDQogICJBdCBSaXNrIiwgIkNhbid0IExvc2UgVGhlbSIsICJMb3N0IikNCnJlY2VuY3lfbG93ZXIgPC0gYyg0LCAyLCAzLCA0LCAzLCAyLCAyLCAxLCAxLCAxKQ0KcmVjZW5jeV91cHBlciA8LSBjKDUsIDUsIDUsIDUsIDQsIDMsIDMsIDIsIDEsIDIpDQpmcmVxdWVuY3lfbG93ZXIgPC0gYyg0LCAzLCAxLCAxLCAxLCAyLCAxLCAyLCA0LCAxKQ0KZnJlcXVlbmN5X3VwcGVyIDwtIGMoNSwgNSwgMywgMSwgMSwgMywgMiwgNSwgNSwgMikNCm1vbmV0YXJ5X2xvd2VyIDwtIGMoNCwgMywgMSwgMSwgMSwgMiwgMSwgMiwgNCwgMSkNCm1vbmV0YXJ5X3VwcGVyIDwtIGMoNSwgNSwgMywgMSwgMSwgMywgMiwgNSwgNSwgMikNCnNlZ21lbnRzIDwtIHJmbV9zZWdtZW50KHJmbV90YWJsZSwgc2VnbWVudF9uYW1lcywgcmVjZW5jeV9sb3dlciwgcmVjZW5jeV91cHBlciwNCmZyZXF1ZW5jeV9sb3dlciwgZnJlcXVlbmN5X3VwcGVyLCBtb25ldGFyeV9sb3dlciwgbW9uZXRhcnlfdXBwZXIpDQoNCnNlZ21lbnRzICU+JQ0KICBkYXRhdGFibGUoDQogICAgZmlsdGVyID0gInRvcCIsDQogICAgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IDUsIGF1dG9XaWR0aCA9IFRSVUUpLA0KICAgIGNvbG5hbWVzID0gYygNCiAgICAgICJDdXN0b21lciIsICJTZWdtZW50IiwgIlJGTSIsDQogICAgICAiT3JkZXJzIiwgIlJlY2VuY3kiLCAiVG90YWwgU3BlbmQiDQogICAgKQ0KICApDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQoNCnJmbV9wbG90X21lZGlhbl9yZWNlbmN5KHNlZ21lbnRzKSANCmBgYA0KDQoNCmBgYHtyfQ0KcmZtX3Bsb3RfbWVkaWFuX21vbmV0YXJ5KHNlZ21lbnRzKQ0KYGBgDQoNCg0KYGBge3J9DQpgYGANCg0KDQpgYGB7cn0NCmBgYA0KDQoNCmBgYHtyfQ0KYGBgDQoNCg0KYGBge3J9DQpgYGANCg0KDQpgYGB7cn0NCmBgYA0KDQoNCmBgYHtyfQ0KYGBgDQoNCg0KYGBge3J9DQpgYGANCg0KDQpgYGB7cn0NCmBgYA0KDQoNCmBgYHtyfQ0KYGBgDQoNCg0KYGBge3J9DQpgYGANCg0KDQpgYGB7cn0NCmBgYA0KDQoNCmBgYHtyfQ0KYGBgDQoNCg0KYGBge3J9DQpgYGANCg0KDQpgYGB7cn0NCmBgYA0KDQoNCmBgYHtyfQ0KYGBgDQoNCg0KYGBge3J9DQpgYGANCg0KDQpgYGB7cn0NCmBgYA0KDQoNCmBgYHtyfQ0KYGBgDQoNCg0KYGBge3J9DQpgYGANCg0KDQpgYGB7cn0NCmBgYA0KDQoNCmBgYHtyfQ0KYGBgDQoNCg0KYGBge3J9DQpgYGANCg0KDQpgYGB7cn0NCmBgYA0KDQoNCmBgYHtyfQ0KYGBgDQoNCg0KYGBge3J9DQpgYGANCg0KDQpgYGB7cn0NCmBgYA0KDQoNCmBgYHtyfQ0KYGBgDQoNCg0KYGBge3J9DQpgYGANCg0KDQppYGBge3J9DQpgYGANCg0K