Flaxman et al. recently published a pre-print claiming covid-19 was near the top of the top-10 leading causes of death for children during the pandemic. Several have others have already pointed out numerous issues with this analysis, most notably Kelley of covid-georgia and @COVIDData3.

In rough order of priority:

Because Flaxman et al. presumably wish to include the most recent covid-19 deaths up through April 2022, the best way to handle this is to compare these covid deaths from March 2020 to April 2022 with other causes of deaths shifted back exactly one year so that we encompass the same times of year (seasons) and span the same number of days. This has the advantage of allowing us to get very close to an “apples-to-apples” comparison with the available data while still trying to reflect the most recent covid deaths.1

Although it’d certainly be even easier to do this in one query for the exact same time span, including the provisional estimates for other causes of death in such a manner would substantially inflate covid’s rank as many other causes of death are not yet available for the last few weeks of 2021 through 2022.2

More specifically, my approach is query this data spanning MMWR weeks like so:

Causes Start Week End Week Number of weeks
Covid-19 2020 Week 10
(ending March 07, 2020)
2022 Week 17
(ending April 30, 2022)
113
All other 2019 Week 10
(ending March 09, 2019)
2021 Week 17
(ending May 01, 2021)
113

One other advantage of using MMWR weeks is that CDC WONDER provides population and crude rates whereas that information is not provided with other sub-annual queries. All of which makes this analysis all that much more straight forward.3.



library(knitr)
library(tidyverse)
library(janitor)
library(stringr)
library(reshape2)
library(hrbrthemes)
library(ggrepel)
library(viridis)

readCDCRates=function(filename,period) {
  read_delim(filename,delim='\t',show_col_type=F) %>%
    clean_names() %>%
    transmute(
      age_group=str_trim(five_year_age_groups),
      cause=str_trim(ucd_icd_10_113_cause_list),
      deaths=as.integer(deaths),
      pop=as.integer(population),
      crude_rate=as.numeric(crude_rate),
      rate=deaths/pop*1e6, # per million
      rate_rounded=round(rate,1), 
      period=period
    ) %>%
    filter(
      !is.na(deaths),
      str_detect(cause,'^#') # only return 'rankable' items from the 113 cause list
    )
}



file_co='leading_cause_comp/2020_wk_10 through 2022_wk_17 only covid-19.txt'
lc_covid_only=readCDCRates(file_co,'MMWR weeks: 2020/10 through 2022/17')


file_cl='leading_cause_comp/2019_wk_10 through 2021_wk_17 all 113 cause list.txt'
lc_causelist=readCDCRates(file_cl,'MMWR weeks: 2019/10 through 2021/17')


# calculate annualized adjustment for CDCs crude rates and/or the population (exposures)
actual_weeks=113
possible_weeks=(3*52)+1 # 157 b/c 2020 has a leap week & it's included in both denominators
annualized_adj=possible_weeks/actual_weeks


lc_comb=bind_rows(lc_covid_only,lc_causelist) %>%
  filter(
    # remove covid-19 item from the period starting in 2019
    !( str_detect(period,'2019') & str_detect(cause,'COVID') )
  ) %>%
  mutate(
    age_only=str_trim(str_remove(age_group,"years?")),
    last_age=case_when(
      age_only == '< 1' ~ as.integer(0),
      age_only == '100+' ~ as.integer(100),
      TRUE ~ as.integer(str_extract(age_only,'\\d+$'))            
    ),
    age_group=reorder(age_group,last_age),
    age_only=reorder(age_only,last_age),

    
    # prettier names
    cause_simp=case_when(
      str_detect(cause,"#Congenital malformations") ~ 'Congenital Anomalies',
      str_detect(cause,"#Accidents") ~ 'Unintentional Injury',
      str_detect(cause,"#Assault") ~ 'Homicide',
      str_detect(cause,"#Intentional self-harm") ~ 'Suicide',
      str_detect(cause,"benign neoplasms") ~ 'Benign Neoplasms',
      T ~ str_remove_all(str_remove(cause,"#"),"\\(.*\\)")
    ),
    cause_simp=str_trim(cause_simp)
    
  ) %>%
  arrange(age_group,rate,cause) %>%
  group_by(age_group) %>%
  mutate(
    rank=rank(-rate,ties.method ='first'),
    rate_annualized=round(rate*annualized_adj,1),
    clab=sprintf("%s\n%0.1f",str_wrap(cause_simp,25),rate_annualized)
  ) %>%
  ungroup() 


lc_comb %>%
  filter(
    rank <= 10,
    last_age <= 19,
    T
  ) %>%
  mutate(
    type=ifelse(str_detect(cause,'COVID'),'COVID','Others')
  ) %>%
  ggplot(aes(age_group,rank,fill=rate)) +
    geom_tile(alpha=0.3,color='black',data=~filter(.,type!='COVID')) +
    geom_tile(color='red',alpha=0.3,size=1,data=~filter(.,type=='COVID')) +  
    scale_fill_viridis_c(trans='log10') +
    geom_text(aes(label=clab),size=4) +
    scale_y_reverse(breaks=seq(1,40,1)) +
    scale_x_discrete(position='top') +
    coord_cartesian(expand=F) +
    theme_ipsum() +
    theme(
      legend.position='none',
      panel.grid.minor = element_blank(),
      panel.grid.major = element_blank()
    ) +
    labs(
      x=NULL,
      y='Rank within age group',
      title='Leading causes of death for children: covid-19 since the start of the pandemic\nversus other causes shifted back one MMWR year.',
      subtitle='(the number below is annualized deaths per million)',
      caption=paste(
        'source: CDC WONDER, Provisional Mortality Statistics, 2018 through Last Month Results',
        'Underlying causes, all rankable items from 113 cause list, ranked by rates',
        'Covid-19: MMWR weeks 2020/10 through 2022/17',
        'Other causes: MMWR weeks, 2019/10 through 2021/17',
        'Same number of weeks and same seasons covered',
        sep='\n'
      )
    )



nformats=format.args = list(decimal.mark = ".", big.mark = ",")
lc_comb %>%
  filter(
    str_detect(cause,'COVID'),
    last_age < 85 # dont have population data to sort 85+ as rates, tho deaths will work
  ) %>%
  transmute(
    age_group,
    rank,
    deaths,
    `population`=round(pop),    
    #`population (100k)`=round(pop/1e5),
    `rate (as quoted)`=rate_rounded,
    `rate (annualized)`=rate_annualized
  ) %>% 
  kable(caption='COVID-19 deaths and rank within age group',format.args = nformats)
COVID-19 deaths and rank within age group
age_group rank deaths population rate (as quoted) rate (annualized)
< 1 year 9 172 11,205,030 15.4 21.3
1-4 years 9 103 46,698,846 2.2 3.1
5-9 years 7 106 60,713,133 1.7 2.4
10-14 years 8 143 62,263,269 2.3 3.2
15-19 years 6 564 62,882,787 9.0 12.5
20-24 years 5 1,630 64,784,265 25.2 35.0
25-29 years 4 3,335 69,693,729 47.9 66.5
30-34 years 4 6,279 68,515,209 91.6 127.3
35-39 years 2 9,660 65,484,912 147.5 205.0
40-44 years 3 15,317 60,923,664 251.4 349.3
45-49 years 4 24,214 59,911,818 404.2 561.5
50-54 years 3 37,272 61,186,581 609.2 846.3
55-59 years 3 55,512 64,809,297 856.5 1,190.1
60-64 years 3 79,350 62,401,734 1,271.6 1,766.7
65-69 years 3 95,764 53,621,001 1,785.9 2,481.4
70-74 years 3 114,144 44,027,193 2,592.6 3,602.1
75-79 years 3 116,598 29,960,499 3,891.7 5,407.1
80-84 years 3 113,423 19,394,142 5,848.3 8,125.5

While we are at it, we can also report these rates for adults.


lc_comb %>%
  filter(
    rank <= 10,
    last_age > 19,
    last_age <= 54,
    T
  ) %>%
  mutate(
    type=ifelse(str_detect(cause,'COVID'),'COVID','Others')
  ) %>%
  ggplot(aes(age_group,rank,fill=rate)) +
    geom_tile(alpha=0.3,color='black',data=~filter(.,type!='COVID')) +
    geom_tile(color='red',alpha=0.3,size=1,data=~filter(.,type=='COVID')) +  
    scale_fill_viridis_c(trans='log10') +
    geom_text(aes(label=clab),size=3) +
    scale_y_reverse(breaks=seq(1,40,1)) +
    scale_x_discrete(position='top') +
    coord_cartesian(expand=F) +
    theme_ipsum() +
    theme(
      legend.position='none',
      panel.grid.minor = element_blank(),
      panel.grid.major = element_blank()
    ) +
    labs(
      x=NULL,
      y='Rank within age group',
      title='Leading causes of death: covid-19 since the start of the pandemic\nversus other causes shifted back one MMWR year.',
      subtitle='(the number below is annualized deaths per million)',
      caption=paste(
        'source: CDC WONDER, Provisional Mortality Statistics, 2018 through Last Month Results',
        'Underlying causes, all rankable items from 113 cause list, ranked by rates',
        'Covid-19: MMWR weeks 2020/10 through 2022/17',
        'Other causes: MMWR weeks, 2019/10 through 2021/17',
        'Same number of weeks and same seasons covered',
        sep='\n'
      )
    )



lc_comb %>%
  filter(
    rank <= 10,
    last_age >= 55,
    last_age <= 84,
    T
  ) %>%
  mutate(
    type=ifelse(str_detect(cause,'COVID'),'COVID','Others')
  ) %>%
  ggplot(aes(age_group,rank,fill=rate)) +
    geom_tile(alpha=0.3,color='black',data=~filter(.,type!='COVID')) +
    geom_tile(color='red',alpha=0.3,size=1,data=~filter(.,type=='COVID')) +  
    scale_fill_viridis_c(trans='log10') +
    geom_text(aes(label=clab),size=3) +
    scale_y_reverse(breaks=seq(1,40,1)) +
    scale_x_discrete(position='top') +
    coord_cartesian(expand=F) +
    theme_ipsum() +
    theme(
      legend.position='none',
      panel.grid.minor = element_blank(),
      panel.grid.major = element_blank()
    ) +
    labs(
      x=NULL,
      y='Rank within age group',
      title='Leading causes of death: covid-19 since the start of the pandemic\nversus other causes shifted back one MMWR year.',
      subtitle='(the number below is annualized deaths per million)',
      caption=paste(
        'source: CDC WONDER, Provisional Mortality Statistics, 2018 through Last Month Results',
        'Underlying causes, all rankable items from 113 cause list, ranked by rates',
        'Covid-19: MMWR weeks 2020/10 through 2022/17',
        'Other causes: MMWR weeks, 2019/10 through 2021/17',
        'Same number of weeks and same seasons covered',
        sep='\n'
      )
    )


  1. Which isn’t to say one cannot quibble with this methodology either. For example, comparing March 2020-April 2022 may fail to reflect some of the seasonality in risk that would be better observed if we compared these statistics across entire years or in such as way as to ensure all seasons are equally weighted.↩︎

  2. As I understand it, this is because covid-19 was added some time ago to the National Notifiable Diseases Surveillance System whereas many other causes have to wait to work their way through for the usual/slower reporting process.↩︎

  3. On the other hand, the populations they provide are based on the sum of population estimates across each of the three years these MMWR weeks span, with the numerator (deaths) unadjusted, so the rates are not quite annualized either. This makes no difference for internal comparisons because each period is exactly 113 weeks long. They can be annualized by multiplying the rate by ~1.39 (157 / 113)↩︎

LS0tDQp0aXRsZTogIkxlYWRpbmcgY2F1c2VzIGNvbXBhcmlzb24iDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KLS0tDQoNCg0KDQpbRmxheG1hbiBldCBhbC5dKGh0dHBzOi8vdHdpdHRlci5jb20vZmxheHRlci9zdGF0dXMvMTUzODUzMzUzNzM1NTI4ODU3NykgcmVjZW50bHkgcHVibGlzaGVkIGEgW3ByZS1wcmludCBjbGFpbWluZyBjb3ZpZC0xOV0oaHR0cHM6Ly93d3cubWVkcnhpdi5vcmcvY29udGVudC8xMC4xMTAxLzIwMjIuMDUuMjMuMjIyNzU0NTh2Mikgd2FzIG5lYXIgdGhlIHRvcCBvZiB0aGUgdG9wLTEwIGxlYWRpbmcgY2F1c2VzIG9mIGRlYXRoIGZvciBjaGlsZHJlbiBkdXJpbmcgdGhlIHBhbmRlbWljLiAgU2V2ZXJhbCBoYXZlIG90aGVycyBoYXZlIGFscmVhZHkgcG9pbnRlZCBvdXQgbnVtZXJvdXMgaXNzdWVzIHdpdGggdGhpcyBhbmFseXNpcywgbW9zdCBub3RhYmx5IFtLZWxsZXkgb2YgY292aWQtZ2VvcmdpYV0oaHR0cHM6Ly93d3cuY292aWQtZ2VvcmdpYS5jb20vcGVkaWF0cmljLW5ld3MvZmFjdC1jaGVjay1jb3ZpZC1pcy1hLWxlYWRpbmctY2F1c2Utb2YtZGVhdGgtaW4tY2hpbGRyZW4vKSBhbmQgW0BDT1ZJRERhdGEzXShodHRwczovL3R3aXR0ZXIuY29tL0NPVklERGF0YTMvc3RhdHVzLzE1MzgzOTE5OTE1Nzg0MTEwMDkpLg0KDQpJbiByb3VnaCBvcmRlciBvZiBwcmlvcml0eToNCg0KLSBDb21wYXJpbmcgY292aWQtMTkgYXMgYSAqbXVsdGlwbGUqIGNhdXNlIG9mIGRlYXRoIHRvIG90aGVyIGNhdXNlcyBhcyAqdW5kZXJseWluZyogY2F1c2VzLg0KLSBDb21wYXJpbmcgY3VtdWxhdGl2ZSByYXRlcyBmcm9tIGNvdmlkLTE5IHRvIGFubnVhbGl6ZWQgcmF0ZSBmb3Igb3RoZXIgY2F1c2VzLg0KLSBDb21wYXJpbmcgcmF0ZXMgZm9yIGNvdmlkLTE5IGFjcm9zcyBtdWx0aXBsZSB5ZWFycyB0byBhIHNpbmdsZSB5ZWFyIGZvciBvdGhlciBjYXVzZXMNCiAgLSBUaGlzIG1heSBiZSBhZmZlY3RlZCBzZWFzb25hbGl0eSBhbmQgeWVhci10by15ZWFyIHZvbGF0aWxpdHkuDQoNCkJlY2F1c2UgRmxheG1hbiBldCBhbC4gcHJlc3VtYWJseSB3aXNoIHRvIGluY2x1ZGUgdGhlIG1vc3QgcmVjZW50IGNvdmlkLTE5IGRlYXRocyB1cCB0aHJvdWdoIEFwcmlsIDIwMjIsIHRoZSBiZXN0IHdheSB0byBoYW5kbGUgdGhpcyBpcyB0byBjb21wYXJlIHRoZXNlIGNvdmlkIGRlYXRocyBmcm9tIE1hcmNoIDIwMjAgdG8gQXByaWwgMjAyMiB3aXRoIG90aGVyIGNhdXNlcyBvZiBkZWF0aHMgc2hpZnRlZCBiYWNrIGV4YWN0bHkgb25lIHllYXIgc28gdGhhdCB3ZSBlbmNvbXBhc3MgdGhlIHNhbWUgdGltZXMgb2YgeWVhciAoc2Vhc29ucykgYW5kIHNwYW4gdGhlIHNhbWUgbnVtYmVyIG9mIGRheXMuICBUaGlzIGhhcyB0aGUgYWR2YW50YWdlIG9mIGFsbG93aW5nIHVzIHRvIGdldCB2ZXJ5IGNsb3NlIHRvIGFuICJhcHBsZXMtdG8tYXBwbGVzIiBjb21wYXJpc29uIHdpdGggdGhlIGF2YWlsYWJsZSBkYXRhIHdoaWxlIHN0aWxsICp0cnlpbmcqIHRvIHJlZmxlY3QgdGhlIG1vc3QgcmVjZW50IGNvdmlkIGRlYXRocy5eW1doaWNoIGlzbid0IHRvIHNheSBvbmUgY2Fubm90IHF1aWJibGUgd2l0aCB0aGlzIG1ldGhvZG9sb2d5IGVpdGhlci4gRm9yIGV4YW1wbGUsIGNvbXBhcmluZyBNYXJjaCAyMDIwLUFwcmlsIDIwMjIgbWF5IGZhaWwgdG8gcmVmbGVjdCBzb21lIG9mIHRoZSBzZWFzb25hbGl0eSBpbiByaXNrIHRoYXQgd291bGQgYmUgYmV0dGVyIG9ic2VydmVkIGlmIHdlIGNvbXBhcmVkIHRoZXNlIHN0YXRpc3RpY3MgYWNyb3NzIGVudGlyZSB5ZWFycyBvciBpbiBzdWNoIGFzIHdheSBhcyB0byBlbnN1cmUgYWxsIHNlYXNvbnMgYXJlIGVxdWFsbHkgd2VpZ2h0ZWQuXQ0KDQoNCkFsdGhvdWdoIGl0J2QgY2VydGFpbmx5IGJlIGV2ZW4gZWFzaWVyIHRvIGRvIHRoaXMgaW4gb25lIHF1ZXJ5IGZvciB0aGUgZXhhY3Qgc2FtZSB0aW1lIHNwYW4sIGluY2x1ZGluZyB0aGUgcHJvdmlzaW9uYWwgZXN0aW1hdGVzIGZvciBvdGhlciBjYXVzZXMgb2YgZGVhdGggaW4gc3VjaCBhIG1hbm5lciB3b3VsZCBzdWJzdGFudGlhbGx5IGluZmxhdGUgY292aWQncyByYW5rIGFzIG1hbnkgb3RoZXIgY2F1c2VzIG9mIGRlYXRoIGFyZSBbbm90IHlldCBhdmFpbGFibGVdKGh0dHBzOi8vd29uZGVyLmNkYy5nb3YvY29udHJvbGxlci9zYXZlZC9EMTc2L0QyOTZGMzg4KSBmb3IgdGhlIGxhc3QgZmV3IHdlZWtzIG9mIDIwMjEgdGhyb3VnaCAyMDIyLl5bQXMgSSB1bmRlcnN0YW5kIGl0LCB0aGlzIGlzIGJlY2F1c2UgW2NvdmlkLTE5IHdhcyBhZGRlZF0oaHR0cHM6Ly93d3cuY2RjLmdvdi9ubmRzcy9hY3Rpb24vc3Rvcmllcy9jb3ZpZC0xOS1yZXNwb25zZS5odG1sKSBzb21lIHRpbWUgYWdvIHRvIHRoZSBOYXRpb25hbCBOb3RpZmlhYmxlIERpc2Vhc2VzIFN1cnZlaWxsYW5jZSBTeXN0ZW0gd2hlcmVhcyBtYW55IG90aGVyIGNhdXNlcyBoYXZlIHRvIHdhaXQgdG8gd29yayB0aGVpciB3YXkgdGhyb3VnaCBmb3IgdGhlIHVzdWFsL3Nsb3dlciByZXBvcnRpbmcgcHJvY2Vzcy5dDQoNCk1vcmUgc3BlY2lmaWNhbGx5LCBteSBhcHByb2FjaCBpcyBxdWVyeSB0aGlzIGRhdGEgc3Bhbm5pbmcgW01NV1Igd2Vla3NdKGh0dHBzOi8vbmRjLnNlcnZpY2VzLmNkYy5nb3Yvd3AtY29udGVudC91cGxvYWRzL01NV1JfV2Vla19vdmVydmlldy5wZGYpIGxpa2Ugc286DQogIA0KfCBDYXVzZXMgfCBTdGFydCBXZWVrIHwgRW5kIFdlZWsgfCBOdW1iZXIgb2Ygd2Vla3MgfA0KfCAtLS0gfCAtLS0tLS0tLS0tLSB8IC0tLS0tLS0tLSB8IC0tLS0tLS0tLS0gfA0KfCBbQ292aWQtMTldKGh0dHBzOi8vd29uZGVyLmNkYy5nb3YvY29udHJvbGxlci9zYXZlZC9EMTc2L0QyOTZGMjE1KSB8IDIwMjAgV2VlayAxMDxiciAvPihlbmRpbmcgTWFyY2ggMDcsIDIwMjApICB8IDIwMjIgV2VlayAxNzxiciAvPihlbmRpbmcgQXByaWwgMzAsIDIwMjIpIHwgMTEzIA0KfCBbQWxsIG90aGVyXShodHRwczovL3dvbmRlci5jZGMuZ292L2NvbnRyb2xsZXIvc2F2ZWQvRDE3Ni9EMjk2RjIyMikgfCAyMDE5IFdlZWsgMTA8YnIgLz4oZW5kaW5nIE1hcmNoIDA5LCAyMDE5KSB8IDIwMjEgV2VlayAxNzxiciAvPihlbmRpbmcgTWF5IDAxLCAyMDIxKSB8IDExMw0KDQpPbmUgb3RoZXIgYWR2YW50YWdlIG9mIHVzaW5nIE1NV1Igd2Vla3MgaXMgdGhhdCBDREMgV09OREVSIHByb3ZpZGVzIHBvcHVsYXRpb24gYW5kIGNydWRlIHJhdGVzIHdoZXJlYXMgdGhhdCBpbmZvcm1hdGlvbiBpcyBub3QgcHJvdmlkZWQgd2l0aCBvdGhlciBzdWItYW5udWFsIHF1ZXJpZXMuICBBbGwgb2Ygd2hpY2ggbWFrZXMgdGhpcyBhbmFseXNpcyBhbGwgdGhhdCBtdWNoIG1vcmUgc3RyYWlnaHQgZm9yd2FyZC5eW09uIHRoZSBvdGhlciBoYW5kLCB0aGUgcG9wdWxhdGlvbnMgdGhleSBwcm92aWRlIGFyZSBiYXNlZCBvbiB0aGUgc3VtIG9mIHBvcHVsYXRpb24gZXN0aW1hdGVzIGFjcm9zcyBlYWNoIG9mIHRoZSB0aHJlZSB5ZWFycyB0aGVzZSBNTVdSIHdlZWtzIHNwYW4sIHdpdGggdGhlIG51bWVyYXRvciAoZGVhdGhzKSB1bmFkanVzdGVkLCBzbyB0aGUgcmF0ZXMgYXJlIG5vdCBxdWl0ZSBhbm51YWxpemVkIGVpdGhlci4gVGhpcyBtYWtlcyBubyBkaWZmZXJlbmNlIGZvciBpbnRlcm5hbCBjb21wYXJpc29ucyBiZWNhdXNlIGVhY2ggcGVyaW9kIGlzIGV4YWN0bHkgMTEzIHdlZWtzIGxvbmcuICBUaGV5IGNhbiBiZSBhbm51YWxpemVkIGJ5IG11bHRpcGx5aW5nIHRoZSByYXRlIGJ5IH4xLjM5ICgxNTcgLyAxMTMpXS4NCg0KDQoNCg0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHBhZ2VkLnByaW50PUZBTFNFfQ0KDQoNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoamFuaXRvcikNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KGhyYnJ0aGVtZXMpDQpsaWJyYXJ5KGdncmVwZWwpDQpsaWJyYXJ5KHZpcmlkaXMpDQoNCnJlYWRDRENSYXRlcz1mdW5jdGlvbihmaWxlbmFtZSxwZXJpb2QpIHsNCiAgcmVhZF9kZWxpbShmaWxlbmFtZSxkZWxpbT0nXHQnLHNob3dfY29sX3R5cGU9RikgJT4lDQogICAgY2xlYW5fbmFtZXMoKSAlPiUNCiAgICB0cmFuc211dGUoDQogICAgICBhZ2VfZ3JvdXA9c3RyX3RyaW0oZml2ZV95ZWFyX2FnZV9ncm91cHMpLA0KICAgICAgY2F1c2U9c3RyX3RyaW0odWNkX2ljZF8xMF8xMTNfY2F1c2VfbGlzdCksDQogICAgICBkZWF0aHM9YXMuaW50ZWdlcihkZWF0aHMpLA0KICAgICAgcG9wPWFzLmludGVnZXIocG9wdWxhdGlvbiksDQogICAgICBjcnVkZV9yYXRlPWFzLm51bWVyaWMoY3J1ZGVfcmF0ZSksDQogICAgICByYXRlPWRlYXRocy9wb3AqMWU2LCAjIHBlciBtaWxsaW9uDQogICAgICByYXRlX3JvdW5kZWQ9cm91bmQocmF0ZSwxKSwgDQogICAgICBwZXJpb2Q9cGVyaW9kDQogICAgKSAlPiUNCiAgICBmaWx0ZXIoDQogICAgICAhaXMubmEoZGVhdGhzKSwNCiAgICAgIHN0cl9kZXRlY3QoY2F1c2UsJ14jJykgIyBvbmx5IHJldHVybiAncmFua2FibGUnIGl0ZW1zIGZyb20gdGhlIDExMyBjYXVzZSBsaXN0DQogICAgKQ0KfQ0KDQoNCg0KZmlsZV9jbz0nbGVhZGluZ19jYXVzZV9jb21wLzIwMjBfd2tfMTAgdGhyb3VnaCAyMDIyX3drXzE3IG9ubHkgY292aWQtMTkudHh0Jw0KbGNfY292aWRfb25seT1yZWFkQ0RDUmF0ZXMoZmlsZV9jbywnTU1XUiB3ZWVrczogMjAyMC8xMCB0aHJvdWdoIDIwMjIvMTcnKQ0KDQoNCmZpbGVfY2w9J2xlYWRpbmdfY2F1c2VfY29tcC8yMDE5X3drXzEwIHRocm91Z2ggMjAyMV93a18xNyBhbGwgMTEzIGNhdXNlIGxpc3QudHh0Jw0KbGNfY2F1c2VsaXN0PXJlYWRDRENSYXRlcyhmaWxlX2NsLCdNTVdSIHdlZWtzOiAyMDE5LzEwIHRocm91Z2ggMjAyMS8xNycpDQoNCg0KIyBjYWxjdWxhdGUgYW5udWFsaXplZCBhZGp1c3RtZW50IGZvciBDRENzIGNydWRlIHJhdGVzIGFuZC9vciB0aGUgcG9wdWxhdGlvbiAoZXhwb3N1cmVzKQ0KYWN0dWFsX3dlZWtzPTExMw0KcG9zc2libGVfd2Vla3M9KDMqNTIpKzEgIyAxNTcgYi9jIDIwMjAgaGFzIGEgbGVhcCB3ZWVrICYgaXQncyBpbmNsdWRlZCBpbiBib3RoIGRlbm9taW5hdG9ycw0KYW5udWFsaXplZF9hZGo9cG9zc2libGVfd2Vla3MvYWN0dWFsX3dlZWtzDQoNCg0KbGNfY29tYj1iaW5kX3Jvd3MobGNfY292aWRfb25seSxsY19jYXVzZWxpc3QpICU+JQ0KICBmaWx0ZXIoDQogICAgIyByZW1vdmUgY292aWQtMTkgaXRlbSBmcm9tIHRoZSBwZXJpb2Qgc3RhcnRpbmcgaW4gMjAxOQ0KICAgICEoIHN0cl9kZXRlY3QocGVyaW9kLCcyMDE5JykgJiBzdHJfZGV0ZWN0KGNhdXNlLCdDT1ZJRCcpICkNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIGFnZV9vbmx5PXN0cl90cmltKHN0cl9yZW1vdmUoYWdlX2dyb3VwLCJ5ZWFycz8iKSksDQogICAgbGFzdF9hZ2U9Y2FzZV93aGVuKA0KICAgICAgYWdlX29ubHkgPT0gJzwgMScgfiBhcy5pbnRlZ2VyKDApLA0KICAgICAgYWdlX29ubHkgPT0gJzEwMCsnIH4gYXMuaW50ZWdlcigxMDApLA0KICAgICAgVFJVRSB+IGFzLmludGVnZXIoc3RyX2V4dHJhY3QoYWdlX29ubHksJ1xcZCskJykpICAgICAgICAgICAgDQogICAgKSwNCiAgICBhZ2VfZ3JvdXA9cmVvcmRlcihhZ2VfZ3JvdXAsbGFzdF9hZ2UpLA0KICAgIGFnZV9vbmx5PXJlb3JkZXIoYWdlX29ubHksbGFzdF9hZ2UpLA0KDQogICAgDQogICAgIyBwcmV0dGllciBuYW1lcw0KICAgIGNhdXNlX3NpbXA9Y2FzZV93aGVuKA0KICAgICAgc3RyX2RldGVjdChjYXVzZSwiI0Nvbmdlbml0YWwgbWFsZm9ybWF0aW9ucyIpIH4gJ0Nvbmdlbml0YWwgQW5vbWFsaWVzJywNCiAgICAgIHN0cl9kZXRlY3QoY2F1c2UsIiNBY2NpZGVudHMiKSB+ICdVbmludGVudGlvbmFsIEluanVyeScsDQogICAgICBzdHJfZGV0ZWN0KGNhdXNlLCIjQXNzYXVsdCIpIH4gJ0hvbWljaWRlJywNCiAgICAgIHN0cl9kZXRlY3QoY2F1c2UsIiNJbnRlbnRpb25hbCBzZWxmLWhhcm0iKSB+ICdTdWljaWRlJywNCiAgICAgIHN0cl9kZXRlY3QoY2F1c2UsImJlbmlnbiBuZW9wbGFzbXMiKSB+ICdCZW5pZ24gTmVvcGxhc21zJywNCiAgICAgIFQgfiBzdHJfcmVtb3ZlX2FsbChzdHJfcmVtb3ZlKGNhdXNlLCIjIiksIlxcKC4qXFwpIikNCiAgICApLA0KICAgIGNhdXNlX3NpbXA9c3RyX3RyaW0oY2F1c2Vfc2ltcCkNCiAgICANCiAgKSAlPiUNCiAgYXJyYW5nZShhZ2VfZ3JvdXAscmF0ZSxjYXVzZSkgJT4lDQogIGdyb3VwX2J5KGFnZV9ncm91cCkgJT4lDQogIG11dGF0ZSgNCiAgICByYW5rPXJhbmsoLXJhdGUsdGllcy5tZXRob2QgPSdmaXJzdCcpLA0KICAgIHJhdGVfYW5udWFsaXplZD1yb3VuZChyYXRlKmFubnVhbGl6ZWRfYWRqLDEpLA0KICAgIGNsYWI9c3ByaW50ZigiJXNcbiUwLjFmIixzdHJfd3JhcChjYXVzZV9zaW1wLDI1KSxyYXRlX2FubnVhbGl6ZWQpDQogICkgJT4lDQogIHVuZ3JvdXAoKSANCg0KDQoNCg0KYGBgDQoNCg0KDQoNCg0KYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQoNCmxjX2NvbWIgJT4lDQogIGZpbHRlcigNCiAgICByYW5rIDw9IDEwLA0KICAgIGxhc3RfYWdlIDw9IDE5LA0KICAgIFQNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIHR5cGU9aWZlbHNlKHN0cl9kZXRlY3QoY2F1c2UsJ0NPVklEJyksJ0NPVklEJywnT3RoZXJzJykNCiAgKSAlPiUNCiAgZ2dwbG90KGFlcyhhZ2VfZ3JvdXAscmFuayxmaWxsPXJhdGUpKSArDQogICAgZ2VvbV90aWxlKGFscGhhPTAuMyxjb2xvcj0nYmxhY2snLGRhdGE9fmZpbHRlciguLHR5cGUhPSdDT1ZJRCcpKSArDQogICAgZ2VvbV90aWxlKGNvbG9yPSdyZWQnLGFscGhhPTAuMyxzaXplPTEsZGF0YT1+ZmlsdGVyKC4sdHlwZT09J0NPVklEJykpICsgIA0KICAgIHNjYWxlX2ZpbGxfdmlyaWRpc19jKHRyYW5zPSdsb2cxMCcpICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPWNsYWIpLHNpemU9NCkgKw0KICAgIHNjYWxlX3lfcmV2ZXJzZShicmVha3M9c2VxKDEsNDAsMSkpICsNCiAgICBzY2FsZV94X2Rpc2NyZXRlKHBvc2l0aW9uPSd0b3AnKSArDQogICAgY29vcmRfY2FydGVzaWFuKGV4cGFuZD1GKSArDQogICAgdGhlbWVfaXBzdW0oKSArDQogICAgdGhlbWUoDQogICAgICBsZWdlbmQucG9zaXRpb249J25vbmUnLA0KICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCkNCiAgICApICsNCiAgICBsYWJzKA0KICAgICAgeD1OVUxMLA0KICAgICAgeT0nUmFuayB3aXRoaW4gYWdlIGdyb3VwJywNCiAgICAgIHRpdGxlPSdMZWFkaW5nIGNhdXNlcyBvZiBkZWF0aCBmb3IgY2hpbGRyZW46IGNvdmlkLTE5IHNpbmNlIHRoZSBzdGFydCBvZiB0aGUgcGFuZGVtaWNcbnZlcnN1cyBvdGhlciBjYXVzZXMgc2hpZnRlZCBiYWNrIG9uZSBNTVdSIHllYXIuJywNCiAgICAgIHN1YnRpdGxlPScodGhlIG51bWJlciBiZWxvdyBpcyBhbm51YWxpemVkIGRlYXRocyBwZXIgbWlsbGlvbiknLA0KICAgICAgY2FwdGlvbj1wYXN0ZSgNCiAgICAgICAgJ3NvdXJjZTogQ0RDIFdPTkRFUiwgUHJvdmlzaW9uYWwgTW9ydGFsaXR5IFN0YXRpc3RpY3MsIDIwMTggdGhyb3VnaCBMYXN0IE1vbnRoIFJlc3VsdHMnLA0KICAgICAgICAnVW5kZXJseWluZyBjYXVzZXMsIGFsbCByYW5rYWJsZSBpdGVtcyBmcm9tIDExMyBjYXVzZSBsaXN0LCByYW5rZWQgYnkgcmF0ZXMnLA0KICAgICAgICAnQ292aWQtMTk6IE1NV1Igd2Vla3MgMjAyMC8xMCB0aHJvdWdoIDIwMjIvMTcnLA0KICAgICAgICAnT3RoZXIgY2F1c2VzOiBNTVdSIHdlZWtzLCAyMDE5LzEwIHRocm91Z2ggMjAyMS8xNycsDQogICAgICAgICdTYW1lIG51bWJlciBvZiB3ZWVrcyBhbmQgc2FtZSBzZWFzb25zIGNvdmVyZWQnLA0KICAgICAgICBzZXA9J1xuJw0KICAgICAgKQ0KICAgICkNCg0KYGBgDQoNCg0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHBhZ2VkLnByaW50PUZBTFNFLHJlc3VsdHM9J2FzaXMnfQ0KDQoNCm5mb3JtYXRzPWZvcm1hdC5hcmdzID0gbGlzdChkZWNpbWFsLm1hcmsgPSAiLiIsIGJpZy5tYXJrID0gIiwiKQ0KbGNfY29tYiAlPiUNCiAgZmlsdGVyKA0KICAgIHN0cl9kZXRlY3QoY2F1c2UsJ0NPVklEJyksDQogICAgbGFzdF9hZ2UgPCA4NSAjIGRvbnQgaGF2ZSBwb3B1bGF0aW9uIGRhdGEgdG8gc29ydCA4NSsgYXMgcmF0ZXMsIHRobyBkZWF0aHMgd2lsbCB3b3JrDQogICkgJT4lDQogIHRyYW5zbXV0ZSgNCiAgICBhZ2VfZ3JvdXAsDQogICAgcmFuaywNCiAgICBkZWF0aHMsDQogICAgYHBvcHVsYXRpb25gPXJvdW5kKHBvcCksICAgIA0KICAgICNgcG9wdWxhdGlvbiAoMTAwaylgPXJvdW5kKHBvcC8xZTUpLA0KICAgIGByYXRlIChhcyBxdW90ZWQpYD1yYXRlX3JvdW5kZWQsDQogICAgYHJhdGUgKGFubnVhbGl6ZWQpYD1yYXRlX2FubnVhbGl6ZWQNCiAgKSAlPiUgDQogIGthYmxlKGNhcHRpb249J0NPVklELTE5IGRlYXRocyBhbmQgcmFuayB3aXRoaW4gYWdlIGdyb3VwJyxmb3JtYXQuYXJncyA9IG5mb3JtYXRzKQ0KDQpgYGANCg0KDQoNCg0KV2hpbGUgd2UgYXJlIGF0IGl0LCB3ZSBjYW4gYWxzbyByZXBvcnQgdGhlc2UgcmF0ZXMgZm9yIGFkdWx0cy4NCg0KYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0NCg0KbGNfY29tYiAlPiUNCiAgZmlsdGVyKA0KICAgIHJhbmsgPD0gMTAsDQogICAgbGFzdF9hZ2UgPiAxOSwNCiAgICBsYXN0X2FnZSA8PSA1NCwNCiAgICBUDQogICkgJT4lDQogIG11dGF0ZSgNCiAgICB0eXBlPWlmZWxzZShzdHJfZGV0ZWN0KGNhdXNlLCdDT1ZJRCcpLCdDT1ZJRCcsJ090aGVycycpDQogICkgJT4lDQogIGdncGxvdChhZXMoYWdlX2dyb3VwLHJhbmssZmlsbD1yYXRlKSkgKw0KICAgIGdlb21fdGlsZShhbHBoYT0wLjMsY29sb3I9J2JsYWNrJyxkYXRhPX5maWx0ZXIoLix0eXBlIT0nQ09WSUQnKSkgKw0KICAgIGdlb21fdGlsZShjb2xvcj0ncmVkJyxhbHBoYT0wLjMsc2l6ZT0xLGRhdGE9fmZpbHRlciguLHR5cGU9PSdDT1ZJRCcpKSArICANCiAgICBzY2FsZV9maWxsX3ZpcmlkaXNfYyh0cmFucz0nbG9nMTAnKSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1jbGFiKSxzaXplPTMpICsNCiAgICBzY2FsZV95X3JldmVyc2UoYnJlYWtzPXNlcSgxLDQwLDEpKSArDQogICAgc2NhbGVfeF9kaXNjcmV0ZShwb3NpdGlvbj0ndG9wJykgKw0KICAgIGNvb3JkX2NhcnRlc2lhbihleHBhbmQ9RikgKw0KICAgIHRoZW1lX2lwc3VtKCkgKw0KICAgIHRoZW1lKA0KICAgICAgbGVnZW5kLnBvc2l0aW9uPSdub25lJywNCiAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpDQogICAgKSArDQogICAgbGFicygNCiAgICAgIHg9TlVMTCwNCiAgICAgIHk9J1Jhbmsgd2l0aGluIGFnZSBncm91cCcsDQogICAgICB0aXRsZT0nTGVhZGluZyBjYXVzZXMgb2YgZGVhdGg6IGNvdmlkLTE5IHNpbmNlIHRoZSBzdGFydCBvZiB0aGUgcGFuZGVtaWNcbnZlcnN1cyBvdGhlciBjYXVzZXMgc2hpZnRlZCBiYWNrIG9uZSBNTVdSIHllYXIuJywNCiAgICAgIHN1YnRpdGxlPScodGhlIG51bWJlciBiZWxvdyBpcyBhbm51YWxpemVkIGRlYXRocyBwZXIgbWlsbGlvbiknLA0KICAgICAgY2FwdGlvbj1wYXN0ZSgNCiAgICAgICAgJ3NvdXJjZTogQ0RDIFdPTkRFUiwgUHJvdmlzaW9uYWwgTW9ydGFsaXR5IFN0YXRpc3RpY3MsIDIwMTggdGhyb3VnaCBMYXN0IE1vbnRoIFJlc3VsdHMnLA0KICAgICAgICAnVW5kZXJseWluZyBjYXVzZXMsIGFsbCByYW5rYWJsZSBpdGVtcyBmcm9tIDExMyBjYXVzZSBsaXN0LCByYW5rZWQgYnkgcmF0ZXMnLA0KICAgICAgICAnQ292aWQtMTk6IE1NV1Igd2Vla3MgMjAyMC8xMCB0aHJvdWdoIDIwMjIvMTcnLA0KICAgICAgICAnT3RoZXIgY2F1c2VzOiBNTVdSIHdlZWtzLCAyMDE5LzEwIHRocm91Z2ggMjAyMS8xNycsDQogICAgICAgICdTYW1lIG51bWJlciBvZiB3ZWVrcyBhbmQgc2FtZSBzZWFzb25zIGNvdmVyZWQnLA0KICAgICAgICBzZXA9J1xuJw0KICAgICAgKQ0KICAgICkNCmBgYA0KDQoNCg0KYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGNfY29tYiAlPiUNCiAgZmlsdGVyKA0KICAgIHJhbmsgPD0gMTAsDQogICAgbGFzdF9hZ2UgPj0gNTUsDQogICAgbGFzdF9hZ2UgPD0gODQsDQogICAgVA0KICApICU+JQ0KICBtdXRhdGUoDQogICAgdHlwZT1pZmVsc2Uoc3RyX2RldGVjdChjYXVzZSwnQ09WSUQnKSwnQ09WSUQnLCdPdGhlcnMnKQ0KICApICU+JQ0KICBnZ3Bsb3QoYWVzKGFnZV9ncm91cCxyYW5rLGZpbGw9cmF0ZSkpICsNCiAgICBnZW9tX3RpbGUoYWxwaGE9MC4zLGNvbG9yPSdibGFjaycsZGF0YT1+ZmlsdGVyKC4sdHlwZSE9J0NPVklEJykpICsNCiAgICBnZW9tX3RpbGUoY29sb3I9J3JlZCcsYWxwaGE9MC4zLHNpemU9MSxkYXRhPX5maWx0ZXIoLix0eXBlPT0nQ09WSUQnKSkgKyAgDQogICAgc2NhbGVfZmlsbF92aXJpZGlzX2ModHJhbnM9J2xvZzEwJykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWw9Y2xhYiksc2l6ZT0zKSArDQogICAgc2NhbGVfeV9yZXZlcnNlKGJyZWFrcz1zZXEoMSw0MCwxKSkgKw0KICAgIHNjYWxlX3hfZGlzY3JldGUocG9zaXRpb249J3RvcCcpICsNCiAgICBjb29yZF9jYXJ0ZXNpYW4oZXhwYW5kPUYpICsNCiAgICB0aGVtZV9pcHN1bSgpICsNCiAgICB0aGVtZSgNCiAgICAgIGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScsDQogICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKQ0KICAgICkgKw0KICAgIGxhYnMoDQogICAgICB4PU5VTEwsDQogICAgICB5PSdSYW5rIHdpdGhpbiBhZ2UgZ3JvdXAnLA0KICAgICAgdGl0bGU9J0xlYWRpbmcgY2F1c2VzIG9mIGRlYXRoOiBjb3ZpZC0xOSBzaW5jZSB0aGUgc3RhcnQgb2YgdGhlIHBhbmRlbWljXG52ZXJzdXMgb3RoZXIgY2F1c2VzIHNoaWZ0ZWQgYmFjayBvbmUgTU1XUiB5ZWFyLicsDQogICAgICBzdWJ0aXRsZT0nKHRoZSBudW1iZXIgYmVsb3cgaXMgYW5udWFsaXplZCBkZWF0aHMgcGVyIG1pbGxpb24pJywNCiAgICAgIGNhcHRpb249cGFzdGUoDQogICAgICAgICdzb3VyY2U6IENEQyBXT05ERVIsIFByb3Zpc2lvbmFsIE1vcnRhbGl0eSBTdGF0aXN0aWNzLCAyMDE4IHRocm91Z2ggTGFzdCBNb250aCBSZXN1bHRzJywNCiAgICAgICAgJ1VuZGVybHlpbmcgY2F1c2VzLCBhbGwgcmFua2FibGUgaXRlbXMgZnJvbSAxMTMgY2F1c2UgbGlzdCwgcmFua2VkIGJ5IHJhdGVzJywNCiAgICAgICAgJ0NvdmlkLTE5OiBNTVdSIHdlZWtzIDIwMjAvMTAgdGhyb3VnaCAyMDIyLzE3JywNCiAgICAgICAgJ090aGVyIGNhdXNlczogTU1XUiB3ZWVrcywgMjAxOS8xMCB0aHJvdWdoIDIwMjEvMTcnLA0KICAgICAgICAnU2FtZSBudW1iZXIgb2Ygd2Vla3MgYW5kIHNhbWUgc2Vhc29ucyBjb3ZlcmVkJywNCiAgICAgICAgc2VwPSdcbicNCiAgICAgICkNCiAgICApDQpgYGANCg0K