This lab journal demonstrates how academic fields are assigned to researchers based on their publications.


1 Custom functions

  • fpackage.check: Check if packages are installed (and install if not) in R (source).
fpackage.check <- function(packages) {
    lapply(packages, FUN = function(x) {
        if (!require(x, character.only = TRUE)) {
            install.packages(x, dependencies = TRUE)
            library(x, character.only = TRUE)
        }
    })
}

2 Packages

  • tidyverse: some tidy data crunching later on

  • data.table: the reduce computing time, especially using the unique function with big data

  • kableExtra: to make HTML tables

packages = c("tidyverse", "data.table", "kableExtra")

fpackage.check(packages)

3 Input

We use four datasets in this file:

  • journals_wos: Journals in WoS and associated disciplines (example)
    • Name: journals_wos
  • pubs_metadf: Publication metadata for three PhDs from the example dataset
    • Name: pubs_metadf
  • pubs_field: Matched publication and field dataset for the three PhDs in [(pubs_metadf)]
    • Name: pubs_metadf
  • phdgender: Processed PhD data including gender and ethnicity variables
    • Name: phdgender
# example of WoS journal-field list
load("data/journals_discipline/journals_wos.rda")

# Load publication metadata
load("data/pubs_metadf.rda")

# Publications with fields attached
load("data/journals_discipline/pubs_field.rda")

# Load PhD dataset
load("data/processed/phdgender.rda")
phd_df <- phdgender

4 Publications data

In order to assign a field to individual researchers, we look at their publications, and specifically at the journal outlets in which people publish. For this, we use the publications listed on researchers’ personal NARCIS profiles.

For three PhD’s in our example data frame, we have compiled a (fictional) publication track record, to show what this publication data looks like.

The id variable references the personal identifiers, which can also be found in the PhD dataset so that PhDs can be matched to their own publications. Furthermore, the data provide information on the type of publication and the date in which the publication was published (date.issued). Lastly, the journal name (journame) is used alongside ISSN codes (not pictured in this example dataframe) to match publications to academic disciplines.

knitr::kable(pubs_metadf, format = "markdown")

5 Matching journal names to fields

To match publications with academic disciplines based on journal names, we use a list of Web of Science indexed journals with associated fields and subfields, according to the field classification by the U.S. National Research Council.

Each journal is associated with one or more specific academic disciplines (subfields), which fall under a broader disciplinary categorization (fields). In the example here, the entry for the “Journal of Ecclesiastical History” is associated with the subfields “history” and “religion”, both of which fall under “humanities”. Since we only look at the broader discipline, this does not matter for our field variable, and we can simply assign “humanities” as the field.

knitr::kable(journals_wos[journals_wos$ISSN == "0022-0469", ], format = "markdown")

In some cases, however, a journal is associated with multiple broader fields. We then assign the field which occurs most frequently within the journal.

In the case of the journal “ACS Photonics”, this implies that we assign “engineering” as the broader field.

In the case of the “International Labour Review”, it is more tricky: the journal is split 50/50 between “social and behavioral sciences” and “humanities”. In these cases, we randomly pick one of the fields.

knitr::kable(journals_wos[(journals_wos$ISSN == "2330-4022" | journals_wos$ISSN == "0020-7780"), ], format = "markdown")

Next, we match the journals in the Web of Science list to the publication outlet information in our own publication dataset. We first match on ISSN, which provides us information on the field of 70% of the unique journals in our data. Next, we match on journal names, which increases the recall on our field indicator to 75% of the unique journals.

In this example dataframe, we randomly picked journals from the Web of Science list, meaning all publications with a journal can be matched to a field.

knitr::kable(pubs_field, format = "markdown")

6 Creating a time-invariant field variable for each PhD

We determine a researcher’s field based on their publications during and right after their PhD. Thus, we first exclude publications from more than 5 years before, or more than three years after they received doctorate. Next, we tally up the fields across all these publications, and take the field which occurs most frequently.

# first, we add the publications data to our phd dataframe
phdfield <- left_join(pubs_field, phd_df, by = "id")


# then we clean the date.issued variable
phdfield$pubyear <- as.numeric(substr(phdfield$date.issued, 1, 4))

# selecting publications from during and right after the PhD
phdfield %>%
    filter((pubyear < (phd_year + 3)) & (pubyear > (phd_year - 5))) -> phdfield

# field = field which the majority of one's publication fall under
phdfield %>%
    group_by(id) %>%
    add_count(nrc_field) %>%
    slice_max(n) %>%
    ungroup() -> phdfield

# maintain a single line per id/field combo
phdfield %>%
    group_by(id, nrc_field) %>%
    slice_head() %>%
    ungroup() -> phdfield

As we see from the results below, one of the three researchers was assigned a single field. The other two (f and g) are split evenly between two fields. In this case, we take one of the fields at random.

knitr::kable(phdfield[, c(1, 5, 16)], format = "markdown")

Selecting a field at random for those who are split exactly evenly between multiple fields.

phdfield %>%
    group_by(id) %>%
    slice_sample(n = 1) -> phdfield

Finally, we omit the ‘business’ and ‘law’ fields because they are small and scientists in these fields tend to have atypical career paths. Furthermore, we combine ‘social and behavioral sciences’ and ‘education’ under a single category.

phdfield$field2 <- phdfield$field <- phdfield$nrc_field

phdfield$field2 <- fct_collapse(phdfield$field2, `Agricultural Sciences` = "Agricultural Sciences", `Biological and Health Sciences` = "Biological and Health Sciences",
    other = c("Business", "Law"), Engineering = "Engineering", Humanities = "Humanities", `Social and Behavioral Sciences` = c("Social and Behavioral Sciences",
        "Education"), `Physical and Mathematical Sciences` = "Physical and Mathematical Sciences")


levels(phdfield$field2)[levels(phdfield$field2) == "other"] <- NA
levels(phdfield$field2)


# create and explicit 'missing' category
phdfield <- phdfield %>%
    mutate(field = fct_explicit_na(field, na_level = "missing"), field2 = fct_explicit_na(field2, na_level = "missing"))


phdfield$field <- factor(phdfield$field, levels = c("Biological and Health Sciences", "Physical and Mathematical Sciences",
    "Social and Behavioral Sciences", "Engineering", "Agricultural Sciences", "Humanities", "Business",
    "Education", "Law", "missing"))

phdfield$field2 <- factor(phdfield$field2, levels = c("Biological and Health Sciences", "Physical and Mathematical Sciences",
    "Social and Behavioral Sciences", "Engineering", "Agricultural Sciences", "Humanities", "missing"))

7 Output

After this, we are left with a dataset of PhDs + fields for each PhD with publications in the specified timeframe.


LS0tDQp0aXRsZTogIkFjYWRlbWljIGZpZWxkcyINCmRhdGU6ICJMYXN0IGNvbXBpbGVkIG9uIGByIGZvcm1hdChTeXMudGltZSgpLCAnJUIsICVZJylgIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjc3M6IHR3ZWFrcy5jc3MNCiAgICB0b2M6ICB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBzaG93DQogICAgY29kZV9kb3dubG9hZDogeWVzDQotLS0NCg0KDQoNCmBgYHtyLCBnbG9iYWxzZXR0aW5ncywgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgcmVzdWx0cz0iaGlkZSJ9DQoNCnJlcXVpcmUoa25pdHIpDQpvcHRzX2NodW5rJHNldCh0aWR5Lm9wdHM9bGlzdCh3aWR0aC5jdXRvZmY9MTAwKSx0aWR5PVRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLGNvbW1lbnQgPSAiIz4iLCBjYWNoZT1UUlVFLCBjbGFzcy5zb3VyY2U9YygidGVzdCIpLCBjbGFzcy5vdXRwdXQ9YygidGVzdDIiKSwgY2FjaGUubGF6eSA9IEZBTFNFLCBldmFsID0gRkFMU0UpDQpvcHRpb25zKHdpZHRoID0gMTAwKQ0KcmdsOjpzZXR1cEtuaXRyKCkNCg0KY29sb3JpemUgPC0gZnVuY3Rpb24oeCwgY29sb3IpIHtzcHJpbnRmKCI8c3BhbiBzdHlsZT0nY29sb3I6ICVzOyc+JXM8L3NwYW4+IiwgY29sb3IsIHgpIH0NCg0KYGBgDQoNCmBgYHtyIGtsaXBweSwgZWNobz1GQUxTRSwgaW5jbHVkZT1UUlVFLCBldmFsPVRSVUV9DQprbGlwcHk6OmtsaXBweShwb3NpdGlvbiA9IGMoJ3RvcCcsICdyaWdodCcpKQ0KI2tsaXBweTo6a2xpcHB5KGNvbG9yID0gJ2RhcmtyZWQnKQ0KI2tsaXBweTo6a2xpcHB5KHRvb2x0aXBfbWVzc2FnZSA9ICdDbGljayB0byBjb3B5JywgdG9vbHRpcF9zdWNjZXNzID0gJ0RvbmUnKQ0KYGBgDQoNCi0tLS0NCg0KVGhpcyBsYWIgam91cm5hbCBkZW1vbnN0cmF0ZXMgaG93IGFjYWRlbWljIGZpZWxkcyBhcmUgYXNzaWduZWQgdG8gcmVzZWFyY2hlcnMgYmFzZWQgb24gdGhlaXIgcHVibGljYXRpb25zLiAgICANCiAgDQotLS0tDQoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQoNCnJtKGxpc3QgPSBscygpKQ0KDQpgYGANCg0KDQoNCiMgQ3VzdG9tIGZ1bmN0aW9ucw0KDQotIGBmcGFja2FnZS5jaGVja2A6IENoZWNrIGlmIHBhY2thZ2VzIGFyZSBpbnN0YWxsZWQgKGFuZCBpbnN0YWxsIGlmIG5vdCkgaW4gUiAoW3NvdXJjZV0oaHR0cHM6Ly92YmFsaWdhLmdpdGh1Yi5pby92ZXJpZnktdGhhdC1yLXBhY2thZ2VzLWFyZS1pbnN0YWxsZWQtYW5kLWxvYWRlZC8pKS4gIA0KDQpgYGB7ciBjdXN0b21mdW5jdGlvbnMsIHJlc3VsdHM9J2hpZGUnfQ0KDQpmcGFja2FnZS5jaGVjayA8LSBmdW5jdGlvbihwYWNrYWdlcykgew0KICBsYXBwbHkocGFja2FnZXMsIEZVTiA9IGZ1bmN0aW9uKHgpIHsNCiAgICBpZiAoIXJlcXVpcmUoeCwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKSkgew0KICAgICAgaW5zdGFsbC5wYWNrYWdlcyh4LCBkZXBlbmRlbmNpZXMgPSBUUlVFKQ0KICAgICAgbGlicmFyeSh4LCBjaGFyYWN0ZXIub25seSA9IFRSVUUpDQogICAgfQ0KICB9KQ0KfQ0KDQpgYGANCg0KLS0tICANCg0KIyBQYWNrYWdlcw0KDQotIGB0aWR5dmVyc2VgOiBzb21lIHRpZHkgZGF0YSBjcnVuY2hpbmcgbGF0ZXIgb24NCg0KLSBgZGF0YS50YWJsZWA6IHRoZSByZWR1Y2UgY29tcHV0aW5nIHRpbWUsIGVzcGVjaWFsbHkgdXNpbmcgdGhlIGB1bmlxdWVgIGZ1bmN0aW9uIHdpdGggYmlnIGRhdGENCg0KLSBga2FibGVFeHRyYWA6IHRvIG1ha2UgSFRNTCB0YWJsZXMNCg0KYGBge3IsIHJlc3VsdHM9J2hpZGUnfQ0KDQpwYWNrYWdlcyA9IGMoInRpZHl2ZXJzZSIsICJkYXRhLnRhYmxlIiwgImthYmxlRXh0cmEiKQ0KDQpmcGFja2FnZS5jaGVjayhwYWNrYWdlcykNCg0KYGBgDQoNCi0tLSANCg0KIyBJbnB1dA0KDQpXZSB1c2UgZm91ciBkYXRhc2V0cyBpbiB0aGlzIGZpbGU6DQoNCiogW2pvdXJuYWxzX3dvc10oaHR0cHM6Ly9naXRodWIuY29tL2FtbXVsZGVycy9hbWF0dGVyb2Z0aW1lL2RhdGEvam91cm5hbHNfZGlzY2lwbGluZS9qb3VybmFsc193b3MucmRhKTogSm91cm5hbHMgaW4gV29TIGFuZCBhc3NvY2lhdGVkIGRpc2NpcGxpbmVzIChleGFtcGxlKQ0KICAgIC0gTmFtZTogYGpvdXJuYWxzX3dvc2AgIA0KICANCiogW3B1YnNfbWV0YWRmXShodHRwczovL2dpdGh1Yi5jb20vYW1tdWxkZXJzL2FtYXR0ZXJvZnRpbWUvZGF0YS9wdWJzX21ldGFkZi5yZGEpOiBQdWJsaWNhdGlvbiBtZXRhZGF0YSBmb3IgdGhyZWUgUGhEcyBmcm9tIHRoZSBleGFtcGxlIGRhdGFzZXQNCiAgICAtIE5hbWU6IGBwdWJzX21ldGFkZmANCg0KKiBbcHVic19maWVsZF0oaHR0cHM6Ly9naXRodWIuY29tL2FtbXVsZGVycy9hbWF0dGVyb2Z0aW1lL2RhdGEvam91cm5hbHNfZGlzY2lwbGluZS9wdWJzX2ZpZWxkLnJkYSk6IE1hdGNoZWQgcHVibGljYXRpb24gYW5kIGZpZWxkIGRhdGFzZXQgZm9yIHRoZSB0aHJlZSBQaERzIGluIFsocHVic19tZXRhZGYpXQ0KICAgIC0gTmFtZTogYHB1YnNfbWV0YWRmYA0KICAgIA0KKiBbcGhkZ2VuZGVyXShodHRwczovL2dpdGh1Yi5jb20vYW1tdWxkZXJzL2FtYXR0ZXJvZnRpbWUvZGF0YS9wcm9jZXNzZWQvcGhkZ2VuZGVyLnJkYSk6IFByb2Nlc3NlZCBQaEQgZGF0YSBpbmNsdWRpbmcgZ2VuZGVyIGFuZCBldGhuaWNpdHkgdmFyaWFibGVzDQogICAgLSBOYW1lOiBgcGhkZ2VuZGVyYCAgDQogDQoNCmBgYCB7ciBkYXRhIGxvYWRpbmcsIGNhY2hlID0gVFJVRX0NCg0KIyBleGFtcGxlIG9mIFdvUyBqb3VybmFsLWZpZWxkIGxpc3QNCmxvYWQoImRhdGEvam91cm5hbHNfZGlzY2lwbGluZS9qb3VybmFsc193b3MucmRhIikNCg0KIyBMb2FkIHB1YmxpY2F0aW9uIG1ldGFkYXRhIA0KbG9hZCgiZGF0YS9wdWJzX21ldGFkZi5yZGEiKQ0KDQojIFB1YmxpY2F0aW9ucyB3aXRoIGZpZWxkcyBhdHRhY2hlZA0KbG9hZCgiZGF0YS9qb3VybmFsc19kaXNjaXBsaW5lL3B1YnNfZmllbGQucmRhIikNCg0KIyBMb2FkIFBoRCBkYXRhc2V0DQpsb2FkKCJkYXRhL3Byb2Nlc3NlZC9waGRnZW5kZXIucmRhIikNCnBoZF9kZiA8LSBwaGRnZW5kZXINCg0KYGBgDQoNCi0tLQ0KDQoNCiMgUHVibGljYXRpb25zIGRhdGENCg0KSW4gb3JkZXIgdG8gYXNzaWduIGEgZmllbGQgdG8gaW5kaXZpZHVhbCByZXNlYXJjaGVycywgd2UgbG9vayBhdCB0aGVpciBwdWJsaWNhdGlvbnMsIGFuZCBzcGVjaWZpY2FsbHkgYXQgdGhlIGpvdXJuYWwgb3V0bGV0cyBpbiB3aGljaCBwZW9wbGUgcHVibGlzaC4gRm9yIHRoaXMsIHdlIHVzZSB0aGUgcHVibGljYXRpb25zIGxpc3RlZCBvbiByZXNlYXJjaGVycycgcGVyc29uYWwgTkFSQ0lTIHByb2ZpbGVzLiANCg0KRm9yIHRocmVlIFBoRCdzIGluIG91ciBleGFtcGxlIGRhdGEgZnJhbWUsIHdlIGhhdmUgY29tcGlsZWQgYSAoZmljdGlvbmFsKSBwdWJsaWNhdGlvbiB0cmFjayByZWNvcmQsIHRvIHNob3cgd2hhdCB0aGlzIHB1YmxpY2F0aW9uIGRhdGEgbG9va3MgbGlrZS4NCg0KVGhlIGBpZGAgdmFyaWFibGUgcmVmZXJlbmNlcyB0aGUgcGVyc29uYWwgaWRlbnRpZmllcnMsIHdoaWNoIGNhbiBhbHNvIGJlIGZvdW5kIGluIHRoZSBQaEQgZGF0YXNldCBzbyB0aGF0IFBoRHMgY2FuIGJlIG1hdGNoZWQgdG8gdGhlaXIgb3duIHB1YmxpY2F0aW9ucy4gRnVydGhlcm1vcmUsIHRoZSBkYXRhIHByb3ZpZGUgaW5mb3JtYXRpb24gb24gdGhlIGB0eXBlYCBvZiBwdWJsaWNhdGlvbiBhbmQgdGhlIGRhdGUgaW4gd2hpY2ggdGhlIHB1YmxpY2F0aW9uIHdhcyBwdWJsaXNoZWQgKGBkYXRlLmlzc3VlZGApLiBMYXN0bHksIHRoZSBqb3VybmFsIG5hbWUgKGBqb3VybmFtZWApIGlzIHVzZWQgYWxvbmdzaWRlIElTU04gY29kZXMgKG5vdCBwaWN0dXJlZCBpbiB0aGlzIGV4YW1wbGUgZGF0YWZyYW1lKSB0byBtYXRjaCBwdWJsaWNhdGlvbnMgdG8gYWNhZGVtaWMgZGlzY2lwbGluZXMuIA0KDQoNCmBgYHtyfQ0KDQprbml0cjo6a2FibGUocHVic19tZXRhZGYsIGZvcm1hdD0ibWFya2Rvd24iKQ0KDQoNCmBgYA0KDQoNCg0KIyBNYXRjaGluZyBqb3VybmFsIG5hbWVzIHRvIGZpZWxkcw0KDQpUbyBtYXRjaCBwdWJsaWNhdGlvbnMgd2l0aCBhY2FkZW1pYyBkaXNjaXBsaW5lcyBiYXNlZCBvbiBqb3VybmFsIG5hbWVzLCB3ZSB1c2UgYSBsaXN0IG9mIFdlYiBvZiBTY2llbmNlIGluZGV4ZWQgam91cm5hbHMgd2l0aCBhc3NvY2lhdGVkIGZpZWxkcyBhbmQgc3ViZmllbGRzLCBhY2NvcmRpbmcgdG8gdGhlIGZpZWxkIGNsYXNzaWZpY2F0aW9uIGJ5IHRoZSBVLlMuIE5hdGlvbmFsIFJlc2VhcmNoIENvdW5jaWwuIA0KDQpFYWNoIGpvdXJuYWwgaXMgYXNzb2NpYXRlZCB3aXRoIG9uZSBvciBtb3JlIHNwZWNpZmljIGFjYWRlbWljIGRpc2NpcGxpbmVzIChzdWJmaWVsZHMpLCB3aGljaCBmYWxsIHVuZGVyIGEgYnJvYWRlciBkaXNjaXBsaW5hcnkgY2F0ZWdvcml6YXRpb24gKGZpZWxkcykuIEluIHRoZSBleGFtcGxlIGhlcmUsIHRoZSBlbnRyeSBmb3IgdGhlICJKb3VybmFsIG9mIEVjY2xlc2lhc3RpY2FsIEhpc3RvcnkiIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3ViZmllbGRzICJoaXN0b3J5IiBhbmQgInJlbGlnaW9uIiwgYm90aCBvZiB3aGljaCBmYWxsIHVuZGVyICJodW1hbml0aWVzIi4gU2luY2Ugd2Ugb25seSBsb29rIGF0IHRoZSBicm9hZGVyIGRpc2NpcGxpbmUsIHRoaXMgZG9lcyBub3QgbWF0dGVyIGZvciBvdXIgZmllbGQgdmFyaWFibGUsIGFuZCB3ZSBjYW4gc2ltcGx5IGFzc2lnbiAiaHVtYW5pdGllcyIgYXMgdGhlIGZpZWxkLiANCg0KDQpgYGB7cn0NCg0Ka25pdHI6OmthYmxlKGpvdXJuYWxzX3dvc1tqb3VybmFsc193b3MkSVNTTj09IjAwMjItMDQ2OSIsXSwgZm9ybWF0PSJtYXJrZG93biIpDQoNCmBgYA0KDQoNCkluIHNvbWUgY2FzZXMsIGhvd2V2ZXIsIGEgam91cm5hbCBpcyBhc3NvY2lhdGVkIHdpdGggbXVsdGlwbGUgYnJvYWRlciBmaWVsZHMuIFdlIHRoZW4gYXNzaWduIHRoZSBmaWVsZCB3aGljaCBvY2N1cnMgbW9zdCBmcmVxdWVudGx5IHdpdGhpbiB0aGUgam91cm5hbC4gDQoNCkluIHRoZSBjYXNlIG9mIHRoZSBqb3VybmFsICJBQ1MgUGhvdG9uaWNzIiwgdGhpcyBpbXBsaWVzIHRoYXQgd2UgYXNzaWduICJlbmdpbmVlcmluZyIgYXMgdGhlIGJyb2FkZXIgZmllbGQuDQoNCkluIHRoZSBjYXNlIG9mIHRoZSAiSW50ZXJuYXRpb25hbCBMYWJvdXIgUmV2aWV3IiwgaXQgaXMgbW9yZSB0cmlja3k6IHRoZSBqb3VybmFsIGlzIHNwbGl0IDUwLzUwIGJldHdlZW4gInNvY2lhbCBhbmQgYmVoYXZpb3JhbCBzY2llbmNlcyIgYW5kICJodW1hbml0aWVzIi4gSW4gdGhlc2UgY2FzZXMsIHdlIHJhbmRvbWx5IHBpY2sgb25lIG9mIHRoZSBmaWVsZHMuIA0KDQpgYGB7cn0NCg0KDQprbml0cjo6a2FibGUoam91cm5hbHNfd29zWyhqb3VybmFsc193b3MkSVNTTj09IjIzMzAtNDAyMiJ8am91cm5hbHNfd29zJElTU049PSIwMDIwLTc3ODAiKSxdLCBmb3JtYXQ9Im1hcmtkb3duIikNCg0KYGBgDQoNCg0KTmV4dCwgd2UgbWF0Y2ggdGhlIGpvdXJuYWxzIGluIHRoZSBXZWIgb2YgU2NpZW5jZSBsaXN0IHRvIHRoZSBwdWJsaWNhdGlvbiBvdXRsZXQgaW5mb3JtYXRpb24gaW4gb3VyIG93biBwdWJsaWNhdGlvbiBkYXRhc2V0LiBXZSBmaXJzdCBtYXRjaCBvbiBJU1NOLCB3aGljaCBwcm92aWRlcyB1cyBpbmZvcm1hdGlvbiBvbiB0aGUgZmllbGQgb2YgNzAlIG9mIHRoZSB1bmlxdWUgam91cm5hbHMgaW4gb3VyIGRhdGEuIE5leHQsIHdlIG1hdGNoIG9uIGpvdXJuYWwgbmFtZXMsIHdoaWNoIGluY3JlYXNlcyB0aGUgcmVjYWxsIG9uIG91ciBmaWVsZCBpbmRpY2F0b3IgdG8gNzUlIG9mIHRoZSB1bmlxdWUgam91cm5hbHMuIA0KDQpJbiB0aGlzIGV4YW1wbGUgZGF0YWZyYW1lLCB3ZSByYW5kb21seSBwaWNrZWQgam91cm5hbHMgZnJvbSB0aGUgV2ViIG9mIFNjaWVuY2UgbGlzdCwgbWVhbmluZyBhbGwgcHVibGljYXRpb25zIHdpdGggYSBqb3VybmFsIGNhbiBiZSBtYXRjaGVkIHRvIGEgZmllbGQuIA0KDQpgYGB7cn0NCg0Ka25pdHI6OmthYmxlKHB1YnNfZmllbGQsIGZvcm1hdD0ibWFya2Rvd24iKQ0KDQoNCmBgYA0KDQoNCiMgQ3JlYXRpbmcgYSB0aW1lLWludmFyaWFudCBmaWVsZCB2YXJpYWJsZSBmb3IgZWFjaCBQaEQNCg0KV2UgZGV0ZXJtaW5lIGEgcmVzZWFyY2hlcidzIGZpZWxkIGJhc2VkIG9uIHRoZWlyIHB1YmxpY2F0aW9ucyBkdXJpbmcgYW5kIHJpZ2h0IGFmdGVyIHRoZWlyIFBoRC4gVGh1cywgd2UgZmlyc3QgZXhjbHVkZSBwdWJsaWNhdGlvbnMgZnJvbSBtb3JlIHRoYW4gNSB5ZWFycyBiZWZvcmUsIG9yIG1vcmUgdGhhbiB0aHJlZSB5ZWFycyBhZnRlciB0aGV5IHJlY2VpdmVkIGRvY3RvcmF0ZS4gTmV4dCwgd2UgdGFsbHkgdXAgdGhlIGZpZWxkcyBhY3Jvc3MgYWxsIHRoZXNlIHB1YmxpY2F0aW9ucywgYW5kIHRha2UgdGhlIGZpZWxkIHdoaWNoIG9jY3VycyBtb3N0IGZyZXF1ZW50bHkuIA0KDQpgYGB7cn0NCg0KIyBmaXJzdCwgd2UgYWRkIHRoZSBwdWJsaWNhdGlvbnMgZGF0YSB0byBvdXIgcGhkIGRhdGFmcmFtZQ0KcGhkZmllbGQgPC0gbGVmdF9qb2luKHB1YnNfZmllbGQsIHBoZF9kZiwgYnk9ImlkIikNCg0KDQojIHRoZW4gd2UgY2xlYW4gdGhlIGRhdGUuaXNzdWVkIHZhcmlhYmxlDQpwaGRmaWVsZCRwdWJ5ZWFyIDwtIGFzLm51bWVyaWMoc3Vic3RyKHBoZGZpZWxkJGRhdGUuaXNzdWVkLCAxLCA0KSkNCg0KIyBzZWxlY3RpbmcgcHVibGljYXRpb25zIGZyb20gZHVyaW5nIGFuZCByaWdodCBhZnRlciB0aGUgUGhEDQpwaGRmaWVsZCAlPiUNCiAgZmlsdGVyKChwdWJ5ZWFyIDwgKHBoZF95ZWFyICsgMykpICYgKHB1YnllYXIgPiAocGhkX3llYXItNSkpKSAtPiBwaGRmaWVsZA0KDQojIGZpZWxkID0gZmllbGQgd2hpY2ggdGhlIG1ham9yaXR5IG9mIG9uZSdzIHB1YmxpY2F0aW9uIGZhbGwgdW5kZXINCnBoZGZpZWxkICU+JQ0KICBncm91cF9ieShpZCkgJT4lDQogIGFkZF9jb3VudChucmNfZmllbGQpICU+JQ0KICBzbGljZV9tYXgobikgJT4lDQogIHVuZ3JvdXAoKSAtPiBwaGRmaWVsZA0KDQojIG1haW50YWluIGEgc2luZ2xlIGxpbmUgcGVyIGlkL2ZpZWxkIGNvbWJvDQpwaGRmaWVsZCAlPiUNCiAgZ3JvdXBfYnkoaWQsIG5yY19maWVsZCkgJT4lDQogIHNsaWNlX2hlYWQoKSAlPiUgdW5ncm91cCgpIC0+IHBoZGZpZWxkDQoNCmBgYA0KDQpBcyB3ZSBzZWUgZnJvbSB0aGUgcmVzdWx0cyBiZWxvdywgb25lIG9mIHRoZSB0aHJlZSByZXNlYXJjaGVycyB3YXMgYXNzaWduZWQgYSBzaW5nbGUgZmllbGQuIFRoZSBvdGhlciB0d28gKGYgYW5kIGcpIGFyZSBzcGxpdCBldmVubHkgYmV0d2VlbiB0d28gZmllbGRzLiBJbiB0aGlzIGNhc2UsIHdlIHRha2Ugb25lIG9mIHRoZSBmaWVsZHMgYXQgcmFuZG9tLg0KDQpgYGB7cn0NCg0Ka25pdHI6OmthYmxlKHBoZGZpZWxkWyxjKDEsNSwxNildLCBmb3JtYXQ9Im1hcmtkb3duIikNCg0KYGBgDQoNClNlbGVjdGluZyBhIGZpZWxkIGF0IHJhbmRvbSBmb3IgdGhvc2Ugd2hvIGFyZSBzcGxpdCBleGFjdGx5IGV2ZW5seSBiZXR3ZWVuIG11bHRpcGxlIGZpZWxkcy4gDQoNCmBgYHtyfQ0KDQpwaGRmaWVsZCAlPiUNCiAgZ3JvdXBfYnkoaWQpICU+JQ0KICBzbGljZV9zYW1wbGUobiA9IDEpIC0+IHBoZGZpZWxkDQoNCg0KYGBgDQoNCg0KRmluYWxseSwgd2Ugb21pdCB0aGUgJ2J1c2luZXNzJyBhbmQgJ2xhdycgZmllbGRzIGJlY2F1c2UgdGhleSBhcmUgc21hbGwgYW5kIHNjaWVudGlzdHMgaW4gdGhlc2UgZmllbGRzIHRlbmQgdG8gaGF2ZSBhdHlwaWNhbCBjYXJlZXIgcGF0aHMuIEZ1cnRoZXJtb3JlLCB3ZSBjb21iaW5lICdzb2NpYWwgYW5kIGJlaGF2aW9yYWwgc2NpZW5jZXMnIGFuZCAnZWR1Y2F0aW9uJyB1bmRlciBhIHNpbmdsZSBjYXRlZ29yeS4gIA0KDQpgYGB7cn0NCg0KDQpwaGRmaWVsZCRmaWVsZDIgPC0gcGhkZmllbGQkZmllbGQgPC0gcGhkZmllbGQkbnJjX2ZpZWxkDQoNCnBoZGZpZWxkJGZpZWxkMiA8LSBmY3RfY29sbGFwc2UocGhkZmllbGQkZmllbGQyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdBZ3JpY3VsdHVyYWwgU2NpZW5jZXMnID0gIkFncmljdWx0dXJhbCBTY2llbmNlcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0Jpb2xvZ2ljYWwgYW5kIEhlYWx0aCBTY2llbmNlcycgPSAiQmlvbG9naWNhbCBhbmQgSGVhbHRoIFNjaWVuY2VzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib3RoZXIiID0gYygiQnVzaW5lc3MiLCAiTGF3IiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW5naW5lZXJpbmcgPSAiRW5naW5lZXJpbmciLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEh1bWFuaXRpZXMgPSAiSHVtYW5pdGllcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1NvY2lhbCBhbmQgQmVoYXZpb3JhbCBTY2llbmNlcycgPSBjKCJTb2NpYWwgYW5kIEJlaGF2aW9yYWwgU2NpZW5jZXMiLCAiRWR1Y2F0aW9uIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BoeXNpY2FsIGFuZCBNYXRoZW1hdGljYWwgU2NpZW5jZXMnID0gIlBoeXNpY2FsIGFuZCBNYXRoZW1hdGljYWwgU2NpZW5jZXMiKQ0KDQoNCmxldmVscyhwaGRmaWVsZCRmaWVsZDIpW2xldmVscyhwaGRmaWVsZCRmaWVsZDIpPT0ib3RoZXIiXSA8LSBOQQ0KbGV2ZWxzKHBoZGZpZWxkJGZpZWxkMikNCg0KDQojIGNyZWF0ZSBhbmQgZXhwbGljaXQgJ21pc3NpbmcnIGNhdGVnb3J5DQpwaGRmaWVsZCA8LSBwaGRmaWVsZCAlPiUgDQogIG11dGF0ZShmaWVsZCA9IGZjdF9leHBsaWNpdF9uYShmaWVsZCwgbmFfbGV2ZWw9Im1pc3NpbmciKSwNCiAgICAgICAgIGZpZWxkMiA9IGZjdF9leHBsaWNpdF9uYShmaWVsZDIsIG5hX2xldmVsPSJtaXNzaW5nIikpIA0KDQoNCnBoZGZpZWxkJGZpZWxkIDwtIGZhY3RvcihwaGRmaWVsZCRmaWVsZCwgbGV2ZWxzID0gYygiQmlvbG9naWNhbCBhbmQgSGVhbHRoIFNjaWVuY2VzIiwgIlBoeXNpY2FsIGFuZCBNYXRoZW1hdGljYWwgU2NpZW5jZXMiLCAiU29jaWFsIGFuZCBCZWhhdmlvcmFsIFNjaWVuY2VzIiwgIkVuZ2luZWVyaW5nIiwgIkFncmljdWx0dXJhbCBTY2llbmNlcyIsICJIdW1hbml0aWVzIiwgIkJ1c2luZXNzIiwgIkVkdWNhdGlvbiIsICJMYXciLCAibWlzc2luZyIpKQ0KDQpwaGRmaWVsZCRmaWVsZDIgPC0gZmFjdG9yKHBoZGZpZWxkJGZpZWxkMiwgbGV2ZWxzID0gYygiQmlvbG9naWNhbCBhbmQgSGVhbHRoIFNjaWVuY2VzIiwgIlBoeXNpY2FsIGFuZCBNYXRoZW1hdGljYWwgU2NpZW5jZXMiLCAiU29jaWFsIGFuZCBCZWhhdmlvcmFsIFNjaWVuY2VzIiwgIkVuZ2luZWVyaW5nIiwgIkFncmljdWx0dXJhbCBTY2llbmNlcyIsICJIdW1hbml0aWVzIiwgIm1pc3NpbmciKSkNCg0KDQoNCmBgYA0KDQoNCg0KIyBPdXRwdXQgIA0KDQpBZnRlciB0aGlzLCB3ZSBhcmUgbGVmdCB3aXRoIGEgZGF0YXNldCBvZiBQaERzICsgZmllbGRzIGZvciBlYWNoIFBoRCB3aXRoIHB1YmxpY2F0aW9ucyBpbiB0aGUgc3BlY2lmaWVkIHRpbWVmcmFtZS4gDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KDQpwaGRmaWVsZCA8LSBzdWJzZXQocGhkZmllbGQsIHNlbGVjdD1jKGlkLCBmaXJzdG5hbWUsIGxhc3RuYW1lX2Z1bGwsIGZpZWxkLCBmaWVsZDIsIGdlbmRlciwgZXRobmljaXR5LCBldGhuaWNpdHkyLCB1bmksIHBoZF95ZWFyKSkNCg0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KDQpwaGRmaWVsZCAlPiUNCiAga2FibGUoKSAlPiUNCiAga2FibGVfc3R5bGluZygpICU+JQ0KICBzY3JvbGxfYm94KHdpZHRoPSIxMDAlIikNCg0KDQpgYGANCg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQ0KDQpzYXZlKHBoZGZpZWxkLCBmaWxlPSJkYXRhL3Byb2Nlc3NlZC9waGRmaWVsZC5yZGEiKQ0KDQpgYGANCg0KLS0tICANCg0K


Copyright © 2023