[{"data":1,"prerenderedAt":7643},["ShallowReactive",2],{"api-nav":3,"api-guide:\u002Fapi\u002Ftutorials\u002Fcollect-results":351,"api-spec:guide:\u002Fapi\u002Ftutorials\u002Fcollect-results":7618},[4,28,57,95,115,301,317,331],{"id":5,"title":6,"links":7,"groups":27},"start","Start here",[8,11,15,18,21,24],{"title":9,"to":10},"Overview","\u002Fapi",{"title":12,"to":13,"status":14},"Quickstart","\u002Fapi\u002Fquickstart","available",{"title":16,"to":17,"status":14},"Environments","\u002Fapi\u002Fenvironments",{"title":19,"to":20,"status":14},"Authentication","\u002Fapi\u002Fauthentication",{"title":22,"to":23,"status":14},"Organizations","\u002Fapi\u002Forganizations",{"title":25,"to":26,"status":14},"Permissions","\u002Fapi\u002Fpermissions",[],{"id":29,"title":30,"links":31,"groups":56},"concepts","Concepts",[32,35,38,41,44,47,50,53],{"title":33,"to":34,"status":14},"Requests and responses","\u002Fapi\u002Frequests-and-responses",{"title":36,"to":37,"status":14},"Identifiers","\u002Fapi\u002Fidentifiers",{"title":39,"to":40,"status":14},"Pagination","\u002Fapi\u002Fpagination",{"title":42,"to":43},"Errors","\u002Fapi\u002Ferrors",{"title":45,"to":46,"status":14},"Rate limits","\u002Fapi\u002Frate-limits",{"title":48,"to":49,"status":14},"Retries","\u002Fapi\u002Fretries-and-idempotency",{"title":51,"to":52,"status":14},"Security","\u002Fapi\u002Fsecurity",{"title":54,"to":55,"status":14},"Versioning","\u002Fapi\u002Fversioning",[],{"id":58,"title":59,"links":60,"groups":94},"resources","Guides",[61,64,67,70,73,76,79,82,85,88,91],{"title":62,"to":63,"status":14},"Students","\u002Fapi\u002Fguides\u002Fstudents",{"title":65,"to":66,"status":14},"Bulk registration","\u002Fapi\u002Fguides\u002Fbulk-registration",{"title":68,"to":69,"status":14},"Passwords","\u002Fapi\u002Fguides\u002Fpasswords",{"title":71,"to":72,"status":14},"Supervisors","\u002Fapi\u002Fguides\u002Fsupervisors",{"title":74,"to":75,"status":14},"Reference data","\u002Fapi\u002Fguides\u002Freference-data",{"title":77,"to":78,"status":14},"API account","\u002Fapi\u002Fguides\u002Fapi-account",{"title":80,"to":81,"status":14},"Sign-in links","\u002Fapi\u002Fguides\u002Fsign-in-links",{"title":83,"to":84,"status":14},"Exams","\u002Fapi\u002Fguides\u002Fexams",{"title":86,"to":87,"status":14},"Applications","\u002Fapi\u002Fguides\u002Fapplications",{"title":89,"to":90,"status":14},"Group challenges","\u002Fapi\u002Fguides\u002Fgroup-challenges",{"title":92,"to":93,"status":14},"Certificates and reports","\u002Fapi\u002Fguides\u002Fcertificates-and-reports",[],{"id":96,"title":97,"links":98,"groups":114},"tutorials","Tutorials",[99,102,105,108,111],{"title":100,"to":101,"status":14},"Register and apply","\u002Fapi\u002Ftutorials\u002Fregister-and-apply",{"title":103,"to":104,"status":14},"Send a student to the panel","\u002Fapi\u002Ftutorials\u002Fsend-student-to-panel",{"title":106,"to":107,"status":14},"Change an application","\u002Fapi\u002Ftutorials\u002Fchange-an-application",{"title":109,"to":110,"status":14},"Collect results","\u002Fapi\u002Ftutorials\u002Fcollect-results",{"title":112,"to":113,"status":14},"Token handling","\u002Fapi\u002Ftutorials\u002Ftoken-handling",[],{"id":116,"title":117,"links":118,"groups":125},"reference","Reference",[119,122],{"title":120,"to":121},"All endpoints","\u002Fapi\u002Freference",{"title":123,"to":124},"Sandbox console","\u002Fapi\u002Fconsole",[126,135,145,166,206,212,230,255,271],{"tag":127,"slug":128,"links":129},"Health","health",[130],{"title":131,"to":132,"method":133,"deprecated":134},"Check that the API is up","\u002Fapi\u002Freference\u002Fget-health","GET",false,{"tag":77,"slug":136,"links":137},"api-account",[138,142],{"title":139,"to":140,"method":141,"deprecated":134},"Revoke the token you send, before it expires","\u002Fapi\u002Freference\u002Frevoke-token","POST",{"title":143,"to":144,"method":133,"deprecated":134},"Fetch the API account your token belongs to","\u002Fapi\u002Freference\u002Fget-current-api-account",{"tag":74,"slug":146,"links":147},"reference-data",[148,151,154,157,160,163],{"title":149,"to":150,"method":133,"deprecated":134},"List the countries a student can be registered in","\u002Fapi\u002Freference\u002Flist-countries",{"title":152,"to":153,"method":133,"deprecated":134},"Fetch one country by its id","\u002Fapi\u002Freference\u002Fget-country",{"title":155,"to":156,"method":133,"deprecated":134},"List the grades a student can be registered with","\u002Fapi\u002Freference\u002Flist-grades",{"title":158,"to":159,"method":133,"deprecated":134},"Fetch one grade by its id","\u002Fapi\u002Freference\u002Fget-grade",{"title":161,"to":162,"method":133,"deprecated":134},"List the organizations and their ids","\u002Fapi\u002Freference\u002Flist-organizations",{"title":164,"to":165,"method":133,"deprecated":134},"Fetch one organization by its id","\u002Fapi\u002Freference\u002Fget-organization",{"tag":62,"slug":167,"links":168},"students",[169,172,175,178,181,184,187,191,194,197,200,203],{"title":170,"to":171,"method":133,"deprecated":134},"List your students","\u002Fapi\u002Freference\u002Flist-students",{"title":173,"to":174,"method":141,"deprecated":134},"Register a student","\u002Fapi\u002Freference\u002Fregister-student",{"title":176,"to":177,"method":141,"deprecated":134},"Check a registration without registering the student","\u002Fapi\u002Freference\u002Fcheck-student-registration",{"title":179,"to":180,"method":141,"deprecated":134},"Register many students at once","\u002Fapi\u002Freference\u002Fcreate-student-import",{"title":182,"to":183,"method":133,"deprecated":134},"Follow a batch of students you sent","\u002Fapi\u002Freference\u002Fget-student-import",{"title":185,"to":186,"method":133,"deprecated":134},"Fetch one of your students","\u002Fapi\u002Freference\u002Fget-student",{"title":188,"to":189,"method":190,"deprecated":134},"Update one of your students","\u002Fapi\u002Freference\u002Fupdate-student","PUT",{"title":192,"to":193,"method":190,"deprecated":134},"Set the sign-in password of one of your students","\u002Fapi\u002Freference\u002Fset-student-password",{"title":195,"to":196,"method":133,"deprecated":134},"List your students who can use this organization","\u002Fapi\u002Freference\u002Flist-org-students",{"title":198,"to":199,"method":133,"deprecated":134},"Fetch one of your students, if they can use this organization","\u002Fapi\u002Freference\u002Fget-org-student",{"title":201,"to":202,"method":190,"deprecated":134},"Update one of your students and give them access to this organization","\u002Fapi\u002Freference\u002Fupdate-org-student",{"title":204,"to":205,"method":190,"deprecated":134},"Link one of your students to a supervisor on this organization","\u002Fapi\u002Freference\u002Flink-student-supervisor",{"tag":80,"slug":207,"links":208},"sign-in-links",[209],{"title":210,"to":211,"method":141,"deprecated":134},"Create a single-use sign-in link for one of your students","\u002Fapi\u002Freference\u002Fcreate-signin-link",{"tag":83,"slug":213,"links":214},"exams",[215,218,221,224,227],{"title":216,"to":217,"method":133,"deprecated":134},"List the exams open for applications","\u002Fapi\u002Freference\u002Flist-exams",{"title":219,"to":220,"method":133,"deprecated":134},"List an organization’s exam categories","\u002Fapi\u002Freference\u002Flist-exam-categories",{"title":222,"to":223,"method":133,"deprecated":134},"Fetch one exam category","\u002Fapi\u002Freference\u002Fget-exam-category",{"title":225,"to":226,"method":133,"deprecated":134},"List the exams one of your students can apply to","\u002Fapi\u002Freference\u002Flist-available-exams",{"title":228,"to":229,"method":133,"deprecated":134},"Fetch one exam that is open for applications","\u002Fapi\u002Freference\u002Fget-exam",{"tag":86,"slug":231,"links":232},"applications",[233,236,239,242,245,248,251],{"title":234,"to":235,"method":133,"deprecated":134},"List your students’ applications in this organization","\u002Fapi\u002Freference\u002Flist-applications",{"title":237,"to":238,"method":141,"deprecated":134},"Enter one of your students for an exam","\u002Fapi\u002Freference\u002Fcreate-application",{"title":240,"to":241,"method":133,"deprecated":134},"List your students’ applications for one exam","\u002Fapi\u002Freference\u002Flist-exam-applications",{"title":243,"to":244,"method":133,"deprecated":134},"List one of your students’ applications in this organization","\u002Fapi\u002Freference\u002Flist-student-applications",{"title":246,"to":247,"method":133,"deprecated":134},"Fetch one of your students’ applications","\u002Fapi\u002Freference\u002Fget-application",{"title":249,"to":250,"method":190,"deprecated":134},"Move one of your students’ applications to another exam","\u002Fapi\u002Freference\u002Fmove-application",{"title":252,"to":253,"method":254,"deprecated":134},"Withdraw one of your students from an exam","\u002Fapi\u002Freference\u002Fdelete-application","DELETE",{"tag":256,"slug":257,"links":258},"Documents","documents",[259,262,265,268],{"title":260,"to":261,"method":133,"deprecated":134},"Download a certificate file","\u002Fapi\u002Freference\u002Fdownload-certificate",{"title":263,"to":264,"method":133,"deprecated":134},"List one of your students’ released certificates","\u002Fapi\u002Freference\u002Flist-student-certificates",{"title":266,"to":267,"method":133,"deprecated":134},"Download a result report file","\u002Fapi\u002Freference\u002Fdownload-report",{"title":269,"to":270,"method":133,"deprecated":134},"List one of your students’ released result reports","\u002Fapi\u002Freference\u002Flist-student-reports",{"tag":89,"slug":272,"links":273},"group-challenges",[274,277,280,283,286,289,292,295,298],{"title":275,"to":276,"method":133,"deprecated":134},"List the group challenges an organization runs","\u002Fapi\u002Freference\u002Flist-group-challenges",{"title":278,"to":279,"method":133,"deprecated":134},"Fetch one group challenge","\u002Fapi\u002Freference\u002Fget-group-challenge",{"title":281,"to":282,"method":133,"deprecated":134},"List the groups your students are in for a group challenge","\u002Fapi\u002Freference\u002Flist-group-challenge-groups",{"title":284,"to":285,"method":133,"deprecated":134},"Fetch one group, with its steps and files","\u002Fapi\u002Freference\u002Fget-group-challenge-group",{"title":287,"to":288,"method":133,"deprecated":134},"List what has happened in one group","\u002Fapi\u002Freference\u002Flist-group-challenge-activity",{"title":290,"to":291,"method":141,"deprecated":134},"Send a group’s finished work for one of your students","\u002Fapi\u002Freference\u002Fsubmit-group-challenge-work",{"title":293,"to":294,"method":141,"deprecated":134},"Submit one step of a group for one of your students","\u002Fapi\u002Freference\u002Fsubmit-group-challenge-step",{"title":296,"to":297,"method":133,"deprecated":134},"List your students’ eligibility and groups for a group challenge","\u002Fapi\u002Freference\u002Flist-group-challenge-students",{"title":299,"to":300,"method":133,"deprecated":134},"Fetch one of your students’ eligibility and group for a group challenge","\u002Fapi\u002Freference\u002Fget-group-challenge-student",{"id":302,"title":303,"links":304,"groups":316},"clients","Clients",[305,307,310,313],{"title":9,"to":306,"status":14},"\u002Fapi\u002Fclients",{"title":308,"to":309,"status":14},"Node.js","\u002Fapi\u002Fclients\u002Fnode",{"title":311,"to":312,"status":14},"PHP","\u002Fapi\u002Fclients\u002Fphp",{"title":314,"to":315,"status":14},"Build your own","\u002Fapi\u002Fclients\u002Fbuild-your-own",[],{"id":318,"title":319,"links":320,"groups":330},"agents","AI agents",[321,324,327],{"title":322,"to":323},"AI connections","\u002Fapi\u002Fmcp",{"title":325,"to":326},"What it can do","\u002Fapi\u002Fmcp\u002Ftools",{"title":328,"to":329},"Agent skills","\u002Fapi\u002Fskills",[],{"id":332,"title":333,"links":334,"groups":350},"help","Help",[335,338,341,344,347],{"title":336,"to":337,"status":14},"Glossary","\u002Fapi\u002Fglossary",{"title":339,"to":340,"status":14},"FAQ","\u002Fapi\u002Ffaq",{"title":342,"to":343,"status":14},"Troubleshooting","\u002Fapi\u002Ftroubleshooting",{"title":345,"to":346,"status":14},"Support","\u002Fapi\u002Fsupport",{"title":348,"to":349},"Changelog","\u002Fapi\u002Fchangelog",[],{"id":352,"title":353,"body":354,"description":7608,"extension":7609,"meta":7610,"navTitle":109,"navigation":1840,"operations":7611,"order":7614,"path":110,"section":96,"seo":7615,"status":14,"stem":7616,"__hash__":7617},"apiGuides\u002Fapi\u002Ftutorials\u002Fcollect-results.md","Collect certificates and reports every night",{"type":355,"value":356,"toc":7589},"minimark",[357,361,366,459,463,490,497,501,508,584,590,614,621,625,671,675,721,911,924,928,954,1113,1122,1125,1198,1206,1210,1236,1390,1393,1397,1454,1520,1523,1576,1580,1583,1703,1722,1726,1730,4270,4273,7320,7324,7327,7335,7338,7344,7351,7355,7358,7416,7419,7423,7547,7551,7585],[358,359,360],"p",{},"When an organization publishes results, each of your students gains certificates and reports: PDF\nfiles you probably want in your own system. In this tutorial you build a job that runs every night,\nfinds what has been released since the last run, downloads it, and remembers what it has. It\npaces itself under the rate limit, and if it is interrupted it resumes where it stopped.",[362,363,365],"h2",{"id":364},"what-the-api-gives-you","What the API gives you",[367,368,369,377,396,406,426,446],"ul",{},[370,371,372,376],"li",{},[373,374,375],"strong",{},"Only released documents."," An organization releases certificates and reports when it publishes\nresults. Before that they are neither listed nor downloadable. A report that is later withdrawn stops\nbeing listed and served too.",[370,378,379,382,383,387,388,391,392,395],{},[373,380,381],{},"Per organization, per student."," ",[384,385,386],"code",{},"GET \u002Fv1\u002F\u003CorganizationId>\u002Fcertificate\u002F\u003CstudentId>"," and\n",[384,389,390],{},"GET \u002Fv1\u002F\u003CorganizationId>\u002Freport\u002F\u003CstudentId>"," list one student's documents on one organization.\n",[384,393,394],{},"\u003CstudentId>"," is the core id you registered the student with.",[370,397,398,401,402,405],{},[373,399,400],{},"Only after a first sign-in."," Both lists need the organization's copy of the student, which the\nstudent's first sign-in creates. Until then they answer ",[384,403,404],{},"409 conflict",". For this job that simply\nmeans \"nothing to collect yet\".",[370,407,408,382,411,414,415,418,419,421,422,425],{},[373,409,410],{},"Paginated.",[384,412,413],{},"page"," starts at 1, and ",[384,416,417],{},"limit"," defaults to 20 with a maximum of 100. A larger ",[384,420,417],{},"\nis lowered to 100 rather than refused. See ",[423,424,39],"a",{"href":40},".",[370,427,428,382,431,434,435,438,439,442,443,425],{},[373,429,430],{},"Downloads are files, not JSON.",[384,432,433],{},"GET \u002Fv1\u002F\u003CorganizationId>\u002Fcertificate\u002Fdownload\u002F\u003CcertificateId>","\nand ",[384,436,437],{},"GET \u002Fv1\u002F\u003CorganizationId>\u002Freport\u002Fdownload\u002F\u003CreportId>"," stream the file. Either takes the\ndocument's ",[384,440,441],{},"_id"," or its ",[384,444,445],{},"shortId",[370,447,448,451,452,455,456,425],{},[373,449,450],{},"One answer for everything you cannot have."," A download of a document that does not exist, is not\nreleased, belongs to another account's student, or has no file answers the same\n",[384,453,454],{},"404 not_found",", ",[384,457,458],{},"Not found!",[362,460,462],{"id":461},"plan-the-run","Plan the run",[464,465,466,473,480,483],"ol",{},[370,467,468,469,472],{},"List all your students once: ",[384,470,471],{},"GET \u002Fv1\u002Fstudent",", 100 per page.",[370,474,475,476,479],{},"List the organizations once: ",[384,477,478],{},"GET \u002Fv1\u002Forganization",". It returns the five organizations that run\nexams, which is where certificates and reports live.",[370,481,482],{},"For each organization, go through every student.",[370,484,485,486,489],{},"For each student, list certificates, then reports. A ",[384,487,488],{},"409"," on the certificates means the student has\nnever signed in to that organization. Skip their reports too, which need the same copy, and move on.",[358,491,492,493,496],{},"Do not narrow the students by ",[384,494,495],{},"activatedPlatformsThisSeason",". That list describes the current season,\nwhile certificates and reports from earlier seasons stay listed. A student who is no longer entered on\nan organization can still have results there.\n5. For each listed document you do not have yet, download it, save it, and record it.\n6. Record each finished student and organization pair, so an interrupted run can resume.",[362,498,500],{"id":499},"budget-the-rate-limit","Budget the rate limit",[358,502,503,504,507],{},"Each account may make ",[373,505,506],{},"100 requests per 60 seconds to each operation",", counted across all your\nservers. Operations are counted separately, and one operation means one kind of request: listing\ncertificates is one operation whichever organization or student is in the path.",[509,510,511,524],"table",{},[512,513,514],"thead",{},[515,516,517,521],"tr",{},[518,519,520],"th",{},"Request this job makes",[518,522,523],{},"Calls per run",[525,526,527,537,546,555,564,574],"tbody",{},[515,528,529,534],{},[530,531,532],"td",{},[384,533,471],{},[530,535,536],{},"Your students ÷ 100",[515,538,539,543],{},[530,540,541],{},[384,542,478],{},[530,544,545],{},"1",[515,547,548,552],{},[530,549,550],{},[384,551,386],{},[530,553,554],{},"One per student and organization pair (more if a student has over 100)",[515,556,557,561],{},[530,558,559],{},[384,560,390],{},[530,562,563],{},"The same",[515,565,566,571],{},[530,567,568],{},[384,569,570],{},"GET …\u002Fcertificate\u002Fdownload\u002F\u003CcertificateId>",[530,572,573],{},"One per new certificate",[515,575,576,581],{},[530,577,578],{},[384,579,580],{},"GET …\u002Freport\u002Fdownload\u002F\u003CreportId>",[530,582,583],{},"One per new report",[358,585,586,587,589],{},"The job below spaces calls to the same operation at least 650 ms apart, which keeps it at about 92\na minute per operation, under the limit. The two listings take turns, so they overlap. With 500 students and\nfive organizations, that is 2,500 student and organization pairs, and the listing pass takes about\n2,500 × 0.65 s ≈ 27 minutes. A pair whose certificate list answers ",[384,588,488],{}," costs one call, not two.\nDownloads add 0.65 s per new file. The first run downloads everything\nreleased so far; later runs fetch only what is new.",[358,591,592,593,596,597,600,601,455,604,607,608,611,612,425],{},"If you still get ",[384,594,595],{},"429 too_many_requests",", another part of your system is using the same operation. Wait\nfor the number of seconds in ",[384,598,599],{},"Retry-After","; the helper does this for you. Every counted response also\ncarries ",[384,602,603],{},"X-RateLimit-Limit",[384,605,606],{},"X-RateLimit-Remaining"," and ",[384,609,610],{},"X-RateLimit-Reset",". See\n",[423,613,45],{"href":46},[615,616,618],"callout",{"type":617},"note",[358,619,620],{},"Run the job on one machine only. The budget belongs to your account, so two copies of the job share it\nand each runs half as fast, while also downloading the same files twice.",[362,622,624],{"id":623},"before-you-start","Before you start",[367,626,627,652,668],{},[370,628,629,382,632,607,635,638,639,642,643,387,646,649,650,425],{},[373,630,631],{},"Permissions:",[384,633,634],{},"student\u002Fread",[384,636,637],{},"organization\u002Fread"," on ",[384,640,641],{},"mto",", plus ",[384,644,645],{},"certificate\u002Fread",[384,647,648],{},"report\u002Fread"," on each organization you collect from. The job skips an organization where it lacks\nthem. See ",[423,651,25],{"href":26},[370,653,654,382,657,660,661,664,665,425],{},[373,655,656],{},"The helper file",[384,658,659],{},"mainteam.mjs"," or ",[384,662,663],{},"mainteam.php"," from\n",[423,666,100],{"href":667},"\u002Fapi\u002Ftutorials\u002Fregister-and-apply#the-helper-file",[370,669,670],{},"A directory to write to.",[362,672,674],{"id":673},"step-1-list-your-students","Step 1: list your students",[676,677,683],"pre",{"className":678,"code":679,"filename":680,"language":681,"meta":682,"style":682},"language-bash shiki shiki-themes github-light-high-contrast github-dark-high-contrast","curl -s \"https:\u002F\u002Fapi.main-team.org\u002Fv1\u002Fstudent?page=1&limit=100\" \\\n  -H \"Authorization: Bearer $TOKEN\"\n","curl","bash","",[384,684,685,705],{"__ignoreMap":682},[686,687,690,693,697,701],"span",{"class":688,"line":689},"line",1,[686,691,680],{"class":692},"soyes",[686,694,696],{"class":695},"s-5SL"," -s",[686,698,700],{"class":699},"sT6z2"," \"https:\u002F\u002Fapi.main-team.org\u002Fv1\u002Fstudent?page=1&limit=100\"",[686,702,704],{"class":703},"sHUrx"," \\\n",[686,706,708,711,714,718],{"class":688,"line":707},2,[686,709,710],{"class":695},"  -H",[686,712,713],{"class":699}," \"Authorization: Bearer ",[686,715,717],{"class":716},"suds8","$TOKEN",[686,719,720],{"class":699},"\"\n",[676,722,727],{"className":723,"code":724,"filename":725,"language":726,"meta":682,"style":682},"language-json shiki shiki-themes github-light-high-contrast github-dark-high-contrast","{\n  \"success\": true,\n  \"message\": \"Students fetched successfully.\",\n  \"data\": [\n    {\n      \"_id\": \"66e6a3f5c1d2b30012a4f9c1\",\n      \"username\": \"XXB1045\",\n      \"firstName\": \"Jane\",\n      \"lastName\": \"Doe\",\n      \"activatedPlatformsThisSeason\": [\"common\"]\n    }\n  ],\n  \"pagination\": { \"page\": 1, \"limit\": 100, \"total\": 512, \"totalPages\": 6 }\n}\n","Response 200 (abridged)","json",[384,728,729,734,749,762,771,777,790,803,816,829,844,850,856,905],{"__ignoreMap":682},[686,730,731],{"class":688,"line":689},[686,732,733],{"class":716},"{\n",[686,735,736,740,743,746],{"class":688,"line":707},[686,737,739],{"class":738},"sne4z","  \"success\"",[686,741,742],{"class":716},": ",[686,744,745],{"class":695},"true",[686,747,748],{"class":716},",\n",[686,750,752,755,757,760],{"class":688,"line":751},3,[686,753,754],{"class":738},"  \"message\"",[686,756,742],{"class":716},[686,758,759],{"class":699},"\"Students fetched successfully.\"",[686,761,748],{"class":716},[686,763,765,768],{"class":688,"line":764},4,[686,766,767],{"class":738},"  \"data\"",[686,769,770],{"class":716},": [\n",[686,772,774],{"class":688,"line":773},5,[686,775,776],{"class":716},"    {\n",[686,778,780,783,785,788],{"class":688,"line":779},6,[686,781,782],{"class":738},"      \"_id\"",[686,784,742],{"class":716},[686,786,787],{"class":699},"\"66e6a3f5c1d2b30012a4f9c1\"",[686,789,748],{"class":716},[686,791,793,796,798,801],{"class":688,"line":792},7,[686,794,795],{"class":738},"      \"username\"",[686,797,742],{"class":716},[686,799,800],{"class":699},"\"XXB1045\"",[686,802,748],{"class":716},[686,804,806,809,811,814],{"class":688,"line":805},8,[686,807,808],{"class":738},"      \"firstName\"",[686,810,742],{"class":716},[686,812,813],{"class":699},"\"Jane\"",[686,815,748],{"class":716},[686,817,819,822,824,827],{"class":688,"line":818},9,[686,820,821],{"class":738},"      \"lastName\"",[686,823,742],{"class":716},[686,825,826],{"class":699},"\"Doe\"",[686,828,748],{"class":716},[686,830,832,835,838,841],{"class":688,"line":831},10,[686,833,834],{"class":738},"      \"activatedPlatformsThisSeason\"",[686,836,837],{"class":716},": [",[686,839,840],{"class":699},"\"common\"",[686,842,843],{"class":716},"]\n",[686,845,847],{"class":688,"line":846},11,[686,848,849],{"class":716},"    }\n",[686,851,853],{"class":688,"line":852},12,[686,854,855],{"class":716},"  ],\n",[686,857,859,862,865,868,870,872,874,877,879,882,884,887,889,892,894,897,899,902],{"class":688,"line":858},13,[686,860,861],{"class":738},"  \"pagination\"",[686,863,864],{"class":716},": { ",[686,866,867],{"class":738},"\"page\"",[686,869,742],{"class":716},[686,871,545],{"class":695},[686,873,455],{"class":716},[686,875,876],{"class":738},"\"limit\"",[686,878,742],{"class":716},[686,880,881],{"class":695},"100",[686,883,455],{"class":716},[686,885,886],{"class":738},"\"total\"",[686,888,742],{"class":716},[686,890,891],{"class":695},"512",[686,893,455],{"class":716},[686,895,896],{"class":738},"\"totalPages\"",[686,898,742],{"class":716},[686,900,901],{"class":695},"6",[686,903,904],{"class":716}," }\n",[686,906,908],{"class":688,"line":907},14,[686,909,910],{"class":716},"}\n",[358,912,913,914,916,917,920,921,923],{},"Keep requesting pages until ",[384,915,413],{}," reaches ",[384,918,919],{},"totalPages",". An empty list has ",[384,922,919],{}," 0. The list is\noffset-paginated, so a student registered while you page through may shift others by one position. The\nnext night's run catches anything missed.",[362,925,927],{"id":926},"step-2-list-a-students-certificates","Step 2: list a student's certificates",[676,929,931],{"className":678,"code":930,"filename":680,"language":681,"meta":682,"style":682},"curl -s \"https:\u002F\u002Fapi.main-team.org\u002Fv1\u002F\u003CorganizationId>\u002Fcertificate\u002F66e6a3f5c1d2b30012a4f9c1?limit=100\" \\\n  -H \"Authorization: Bearer $TOKEN\"\n",[384,932,933,944],{"__ignoreMap":682},[686,934,935,937,939,942],{"class":688,"line":689},[686,936,680],{"class":692},[686,938,696],{"class":695},[686,940,941],{"class":699}," \"https:\u002F\u002Fapi.main-team.org\u002Fv1\u002F\u003CorganizationId>\u002Fcertificate\u002F66e6a3f5c1d2b30012a4f9c1?limit=100\"",[686,943,704],{"class":703},[686,945,946,948,950,952],{"class":688,"line":707},[686,947,710],{"class":695},[686,949,713],{"class":699},[686,951,717],{"class":716},[686,953,720],{"class":699},[676,955,957],{"className":723,"code":956,"filename":725,"language":726,"meta":682,"style":682},"{\n  \"success\": true,\n  \"message\": \"Certificates fetched successfully.\",\n  \"data\": [\n    {\n      \"_id\": \"66f1c0d2e3f4a5b6c7d8e9f0\",\n      \"application\": \"66e6a4b1c1d2b30012a4fa07\",\n      \"title\": \"Certificate of Achievement\",\n      \"shortId\": \"K7Q2M9X4TB\",\n      \"active\": true,\n      \"createdAt\": \"2026-12-02T08:00:00.000Z\"\n    }\n  ],\n  \"pagination\": { \"page\": 1, \"limit\": 100, \"total\": 1, \"totalPages\": 1 }\n}\n",[384,958,959,963,973,984,990,994,1005,1017,1029,1041,1052,1062,1066,1070,1108],{"__ignoreMap":682},[686,960,961],{"class":688,"line":689},[686,962,733],{"class":716},[686,964,965,967,969,971],{"class":688,"line":707},[686,966,739],{"class":738},[686,968,742],{"class":716},[686,970,745],{"class":695},[686,972,748],{"class":716},[686,974,975,977,979,982],{"class":688,"line":751},[686,976,754],{"class":738},[686,978,742],{"class":716},[686,980,981],{"class":699},"\"Certificates fetched successfully.\"",[686,983,748],{"class":716},[686,985,986,988],{"class":688,"line":764},[686,987,767],{"class":738},[686,989,770],{"class":716},[686,991,992],{"class":688,"line":773},[686,993,776],{"class":716},[686,995,996,998,1000,1003],{"class":688,"line":779},[686,997,782],{"class":738},[686,999,742],{"class":716},[686,1001,1002],{"class":699},"\"66f1c0d2e3f4a5b6c7d8e9f0\"",[686,1004,748],{"class":716},[686,1006,1007,1010,1012,1015],{"class":688,"line":792},[686,1008,1009],{"class":738},"      \"application\"",[686,1011,742],{"class":716},[686,1013,1014],{"class":699},"\"66e6a4b1c1d2b30012a4fa07\"",[686,1016,748],{"class":716},[686,1018,1019,1022,1024,1027],{"class":688,"line":805},[686,1020,1021],{"class":738},"      \"title\"",[686,1023,742],{"class":716},[686,1025,1026],{"class":699},"\"Certificate of Achievement\"",[686,1028,748],{"class":716},[686,1030,1031,1034,1036,1039],{"class":688,"line":818},[686,1032,1033],{"class":738},"      \"shortId\"",[686,1035,742],{"class":716},[686,1037,1038],{"class":699},"\"K7Q2M9X4TB\"",[686,1040,748],{"class":716},[686,1042,1043,1046,1048,1050],{"class":688,"line":831},[686,1044,1045],{"class":738},"      \"active\"",[686,1047,742],{"class":716},[686,1049,745],{"class":695},[686,1051,748],{"class":716},[686,1053,1054,1057,1059],{"class":688,"line":846},[686,1055,1056],{"class":738},"      \"createdAt\"",[686,1058,742],{"class":716},[686,1060,1061],{"class":699},"\"2026-12-02T08:00:00.000Z\"\n",[686,1063,1064],{"class":688,"line":852},[686,1065,849],{"class":716},[686,1067,1068],{"class":688,"line":858},[686,1069,855],{"class":716},[686,1071,1072,1074,1076,1078,1080,1082,1084,1086,1088,1090,1092,1094,1096,1098,1100,1102,1104,1106],{"class":688,"line":907},[686,1073,861],{"class":738},[686,1075,864],{"class":716},[686,1077,867],{"class":738},[686,1079,742],{"class":716},[686,1081,545],{"class":695},[686,1083,455],{"class":716},[686,1085,876],{"class":738},[686,1087,742],{"class":716},[686,1089,881],{"class":695},[686,1091,455],{"class":716},[686,1093,886],{"class":738},[686,1095,742],{"class":716},[686,1097,545],{"class":695},[686,1099,455],{"class":716},[686,1101,896],{"class":738},[686,1103,742],{"class":716},[686,1105,545],{"class":695},[686,1107,904],{"class":716},[686,1109,1111],{"class":688,"line":1110},15,[686,1112,910],{"class":716},[358,1114,1115,1116,1118,1119,1121],{},"A certificate is listed whether it is tied to one of the student's applications or to the student\ndirectly, and every listed certificate can be downloaded. ",[384,1117,445],{}," is a short uppercase code that\nidentifies the document as well as its ",[384,1120,441],{}," does.",[358,1123,1124],{},"If the student has never signed in to this organization:",[676,1126,1129],{"className":723,"code":1127,"filename":1128,"language":726,"meta":682,"style":682},"{\n  \"error\": {\n    \"code\": \"conflict\",\n    \"message\": \"Student has never signed in to stem, so stem holds no record for them. Generate a sign-in link first with POST \u002F:organizationId\u002Fauth\u002Fsignin.\",\n    \"documentation_url\": \"https:\u002F\u002Fhub.main-team.org\u002Fapi\u002Ferrors#conflict\",\n    \"request_id\": \"c1a7e9d2-4b3f-4e5a-8d6c-7f8e9a0b1c2d\"\n  }\n}\n","Response 409",[384,1130,1131,1135,1143,1155,1167,1179,1189,1194],{"__ignoreMap":682},[686,1132,1133],{"class":688,"line":689},[686,1134,733],{"class":716},[686,1136,1137,1140],{"class":688,"line":707},[686,1138,1139],{"class":738},"  \"error\"",[686,1141,1142],{"class":716},": {\n",[686,1144,1145,1148,1150,1153],{"class":688,"line":751},[686,1146,1147],{"class":738},"    \"code\"",[686,1149,742],{"class":716},[686,1151,1152],{"class":699},"\"conflict\"",[686,1154,748],{"class":716},[686,1156,1157,1160,1162,1165],{"class":688,"line":764},[686,1158,1159],{"class":738},"    \"message\"",[686,1161,742],{"class":716},[686,1163,1164],{"class":699},"\"Student has never signed in to stem, so stem holds no record for them. Generate a sign-in link first with POST \u002F:organizationId\u002Fauth\u002Fsignin.\"",[686,1166,748],{"class":716},[686,1168,1169,1172,1174,1177],{"class":688,"line":773},[686,1170,1171],{"class":738},"    \"documentation_url\"",[686,1173,742],{"class":716},[686,1175,1176],{"class":699},"\"https:\u002F\u002Fhub.main-team.org\u002Fapi\u002Ferrors#conflict\"",[686,1178,748],{"class":716},[686,1180,1181,1184,1186],{"class":688,"line":779},[686,1182,1183],{"class":738},"    \"request_id\"",[686,1185,742],{"class":716},[686,1187,1188],{"class":699},"\"c1a7e9d2-4b3f-4e5a-8d6c-7f8e9a0b1c2d\"\n",[686,1190,1191],{"class":688,"line":792},[686,1192,1193],{"class":716},"  }\n",[686,1195,1196],{"class":688,"line":805},[686,1197,910],{"class":716},[358,1199,1200,1201,455,1203,425],{},"A student who is not yours answers ",[384,1202,454],{},[384,1204,1205],{},"Student not found!",[362,1207,1209],{"id":1208},"step-3-list-a-students-reports","Step 3: list a student's reports",[676,1211,1213],{"className":678,"code":1212,"filename":680,"language":681,"meta":682,"style":682},"curl -s \"https:\u002F\u002Fapi.main-team.org\u002Fv1\u002F\u003CorganizationId>\u002Freport\u002F66e6a3f5c1d2b30012a4f9c1?limit=100\" \\\n  -H \"Authorization: Bearer $TOKEN\"\n",[384,1214,1215,1226],{"__ignoreMap":682},[686,1216,1217,1219,1221,1224],{"class":688,"line":689},[686,1218,680],{"class":692},[686,1220,696],{"class":695},[686,1222,1223],{"class":699}," \"https:\u002F\u002Fapi.main-team.org\u002Fv1\u002F\u003CorganizationId>\u002Freport\u002F66e6a3f5c1d2b30012a4f9c1?limit=100\"",[686,1225,704],{"class":703},[686,1227,1228,1230,1232,1234],{"class":688,"line":707},[686,1229,710],{"class":695},[686,1231,713],{"class":699},[686,1233,717],{"class":716},[686,1235,720],{"class":699},[676,1237,1239],{"className":723,"code":1238,"filename":725,"language":726,"meta":682,"style":682},"{\n  \"success\": true,\n  \"message\": \"Reports fetched successfully.\",\n  \"data\": [\n    {\n      \"_id\": \"66f1c0d2e3f4a5b6c7d8ea01\",\n      \"application\": \"66e6a4b1c1d2b30012a4fa07\",\n      \"shortId\": \"P3W8R2N6ZD\",\n      \"isActive\": true,\n      \"isCanceled\": false,\n      \"createdAt\": \"2026-12-02T08:05:00.000Z\"\n    }\n  ],\n  \"pagination\": { \"page\": 1, \"limit\": 100, \"total\": 1, \"totalPages\": 1 }\n}\n",[384,1240,1241,1245,1255,1266,1272,1276,1287,1297,1308,1319,1331,1340,1344,1348,1386],{"__ignoreMap":682},[686,1242,1243],{"class":688,"line":689},[686,1244,733],{"class":716},[686,1246,1247,1249,1251,1253],{"class":688,"line":707},[686,1248,739],{"class":738},[686,1250,742],{"class":716},[686,1252,745],{"class":695},[686,1254,748],{"class":716},[686,1256,1257,1259,1261,1264],{"class":688,"line":751},[686,1258,754],{"class":738},[686,1260,742],{"class":716},[686,1262,1263],{"class":699},"\"Reports fetched successfully.\"",[686,1265,748],{"class":716},[686,1267,1268,1270],{"class":688,"line":764},[686,1269,767],{"class":738},[686,1271,770],{"class":716},[686,1273,1274],{"class":688,"line":773},[686,1275,776],{"class":716},[686,1277,1278,1280,1282,1285],{"class":688,"line":779},[686,1279,782],{"class":738},[686,1281,742],{"class":716},[686,1283,1284],{"class":699},"\"66f1c0d2e3f4a5b6c7d8ea01\"",[686,1286,748],{"class":716},[686,1288,1289,1291,1293,1295],{"class":688,"line":792},[686,1290,1009],{"class":738},[686,1292,742],{"class":716},[686,1294,1014],{"class":699},[686,1296,748],{"class":716},[686,1298,1299,1301,1303,1306],{"class":688,"line":805},[686,1300,1033],{"class":738},[686,1302,742],{"class":716},[686,1304,1305],{"class":699},"\"P3W8R2N6ZD\"",[686,1307,748],{"class":716},[686,1309,1310,1313,1315,1317],{"class":688,"line":818},[686,1311,1312],{"class":738},"      \"isActive\"",[686,1314,742],{"class":716},[686,1316,745],{"class":695},[686,1318,748],{"class":716},[686,1320,1321,1324,1326,1329],{"class":688,"line":831},[686,1322,1323],{"class":738},"      \"isCanceled\"",[686,1325,742],{"class":716},[686,1327,1328],{"class":695},"false",[686,1330,748],{"class":716},[686,1332,1333,1335,1337],{"class":688,"line":846},[686,1334,1056],{"class":738},[686,1336,742],{"class":716},[686,1338,1339],{"class":699},"\"2026-12-02T08:05:00.000Z\"\n",[686,1341,1342],{"class":688,"line":852},[686,1343,849],{"class":716},[686,1345,1346],{"class":688,"line":858},[686,1347,855],{"class":716},[686,1349,1350,1352,1354,1356,1358,1360,1362,1364,1366,1368,1370,1372,1374,1376,1378,1380,1382,1384],{"class":688,"line":907},[686,1351,861],{"class":738},[686,1353,864],{"class":716},[686,1355,867],{"class":738},[686,1357,742],{"class":716},[686,1359,545],{"class":695},[686,1361,455],{"class":716},[686,1363,876],{"class":738},[686,1365,742],{"class":716},[686,1367,881],{"class":695},[686,1369,455],{"class":716},[686,1371,886],{"class":738},[686,1373,742],{"class":716},[686,1375,545],{"class":695},[686,1377,455],{"class":716},[686,1379,896],{"class":738},[686,1381,742],{"class":716},[686,1383,545],{"class":695},[686,1385,904],{"class":716},[686,1387,1388],{"class":688,"line":1110},[686,1389,910],{"class":716},[358,1391,1392],{},"Reports from every season are listed, not only the current one.",[362,1394,1396],{"id":1395},"step-4-download-a-file","Step 4: download a file",[676,1398,1400],{"className":678,"code":1399,"filename":680,"language":681,"meta":682,"style":682},"curl -s -D - -o certificate.pdf \\\n  https:\u002F\u002Fapi.main-team.org\u002Fv1\u002F\u003CorganizationId>\u002Fcertificate\u002Fdownload\u002F66f1c0d2e3f4a5b6c7d8e9f0 \\\n  -H \"Authorization: Bearer $TOKEN\"\n",[384,1401,1402,1422,1444],{"__ignoreMap":682},[686,1403,1404,1406,1408,1411,1414,1417,1420],{"class":688,"line":689},[686,1405,680],{"class":692},[686,1407,696],{"class":695},[686,1409,1410],{"class":695}," -D",[686,1412,1413],{"class":699}," -",[686,1415,1416],{"class":695}," -o",[686,1418,1419],{"class":699}," certificate.pdf",[686,1421,704],{"class":703},[686,1423,1424,1427,1430,1433,1436,1439,1442],{"class":688,"line":707},[686,1425,1426],{"class":699},"  https:\u002F\u002Fapi.main-team.org\u002Fv1\u002F",[686,1428,1429],{"class":703},"\u003C",[686,1431,1432],{"class":699},"organizationI",[686,1434,1435],{"class":716},"d",[686,1437,1438],{"class":703},">",[686,1440,1441],{"class":699},"\u002Fcertificate\u002Fdownload\u002F66f1c0d2e3f4a5b6c7d8e9f0",[686,1443,704],{"class":703},[686,1445,1446,1448,1450,1452],{"class":688,"line":751},[686,1447,710],{"class":695},[686,1449,713],{"class":699},[686,1451,717],{"class":716},[686,1453,720],{"class":699},[676,1455,1460],{"className":1456,"code":1457,"filename":1458,"language":1459,"meta":682,"style":682},"language-http shiki shiki-themes github-light-high-contrast github-dark-high-contrast","HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fpdf\nContent-Length: 184213\nContent-Disposition: attachment; filename=\"Ogrenci Sukru.pdf\"; filename*=UTF-8''%C3%96%C4%9Frenci%20%C5%9E%C3%BCkr%C3%BC.pdf\nX-Request-Id: 8e2f4a6c-1b3d-4f5e-9a7c-0d2e4f6a8b1c\n","Response headers","http",[384,1461,1462,1479,1490,1500,1510],{"__ignoreMap":682},[686,1463,1464,1467,1470,1473,1476],{"class":688,"line":689},[686,1465,1466],{"class":703},"HTTP",[686,1468,1469],{"class":716},"\u002F",[686,1471,1472],{"class":695},"1.1",[686,1474,1475],{"class":695}," 200",[686,1477,1478],{"class":699}," OK\n",[686,1480,1481,1484,1487],{"class":688,"line":707},[686,1482,1483],{"class":738},"Content-Type",[686,1485,1486],{"class":703},":",[686,1488,1489],{"class":699}," application\u002Fpdf\n",[686,1491,1492,1495,1497],{"class":688,"line":751},[686,1493,1494],{"class":738},"Content-Length",[686,1496,1486],{"class":703},[686,1498,1499],{"class":699}," 184213\n",[686,1501,1502,1505,1507],{"class":688,"line":764},[686,1503,1504],{"class":738},"Content-Disposition",[686,1506,1486],{"class":703},[686,1508,1509],{"class":699}," attachment; filename=\"Ogrenci Sukru.pdf\"; filename*=UTF-8''%C3%96%C4%9Frenci%20%C5%9E%C3%BCkr%C3%BC.pdf\n",[686,1511,1512,1515,1517],{"class":688,"line":773},[686,1513,1514],{"class":738},"X-Request-Id",[686,1516,1486],{"class":703},[686,1518,1519],{"class":699}," 8e2f4a6c-1b3d-4f5e-9a7c-0d2e4f6a8b1c\n",[358,1521,1522],{},"How to handle the response:",[367,1524,1525,1531,1546,1561,1567],{},[370,1526,1527,1530],{},[373,1528,1529],{},"The body is the file."," There is no JSON envelope.",[370,1532,1533,1541,1542,1545],{},[373,1534,1535,1537,1538,425],{},[384,1536,1483],{}," is not always ",[384,1539,1540],{},"application\u002Fpdf"," It is whatever the file was stored with, and\n",[384,1543,1544],{},"application\u002Foctet-stream"," when none was. Do not reject a download on its content type.",[370,1547,1548,1554,1555,1558,1559,425],{},[373,1549,1550,1551,425],{},"Take the name from ",[384,1552,1553],{},"filename*"," It holds the real name, percent-encoded as UTF-8, accents\nincluded. ",[384,1556,1557],{},"filename"," is a plain-ASCII fallback for clients that cannot read ",[384,1560,1553],{},[370,1562,1563,1566],{},[373,1564,1565],{},"Errors arrive before the file."," A refusal comes as the usual JSON error body with an error status,\nbefore any file bytes.",[370,1568,1569,1572,1573,1575],{},[373,1570,1571],{},"A transfer that stops early is a failure, not a short file."," Compare the bytes you received with\n",[384,1574,1494],{}," when it is present, and discard a partial file.",[362,1577,1579],{"id":1578},"step-5-remember-what-you-have","Step 5: remember what you have",[358,1581,1582],{},"The job keeps one JSON file next to the downloads:",[676,1584,1587],{"className":723,"code":1585,"filename":1586,"language":726,"meta":682,"style":682},"{\n  \"documents\": {\n    \"stem\u002Fcertificate\u002F66f1c0d2e3f4a5b6c7d8e9f0\": {\n      \"shortId\": \"K7Q2M9X4TB\",\n      \"file\": \"results\u002Fstem\u002F66e6a3f5c1d2b30012a4f9c1\u002Fcertificate-K7Q2M9X4TB.pdf\",\n      \"serverName\": \"Öğrenci Şükrü.pdf\",\n      \"at\": \"2026-12-03T02:15:41.220Z\"\n    }\n  },\n  \"run\": {\n    \"startedAt\": \"2026-12-03T02:15:00.004Z\",\n    \"finished\": { \"stem:66e6a3f5c1d2b30012a4f9c1\": true }\n  }\n}\n","results\u002Fstate.json",[384,1588,1589,1593,1600,1607,1617,1629,1641,1651,1655,1660,1667,1679,1695,1699],{"__ignoreMap":682},[686,1590,1591],{"class":688,"line":689},[686,1592,733],{"class":716},[686,1594,1595,1598],{"class":688,"line":707},[686,1596,1597],{"class":738},"  \"documents\"",[686,1599,1142],{"class":716},[686,1601,1602,1605],{"class":688,"line":751},[686,1603,1604],{"class":738},"    \"stem\u002Fcertificate\u002F66f1c0d2e3f4a5b6c7d8e9f0\"",[686,1606,1142],{"class":716},[686,1608,1609,1611,1613,1615],{"class":688,"line":764},[686,1610,1033],{"class":738},[686,1612,742],{"class":716},[686,1614,1038],{"class":699},[686,1616,748],{"class":716},[686,1618,1619,1622,1624,1627],{"class":688,"line":773},[686,1620,1621],{"class":738},"      \"file\"",[686,1623,742],{"class":716},[686,1625,1626],{"class":699},"\"results\u002Fstem\u002F66e6a3f5c1d2b30012a4f9c1\u002Fcertificate-K7Q2M9X4TB.pdf\"",[686,1628,748],{"class":716},[686,1630,1631,1634,1636,1639],{"class":688,"line":779},[686,1632,1633],{"class":738},"      \"serverName\"",[686,1635,742],{"class":716},[686,1637,1638],{"class":699},"\"Öğrenci Şükrü.pdf\"",[686,1640,748],{"class":716},[686,1642,1643,1646,1648],{"class":688,"line":792},[686,1644,1645],{"class":738},"      \"at\"",[686,1647,742],{"class":716},[686,1649,1650],{"class":699},"\"2026-12-03T02:15:41.220Z\"\n",[686,1652,1653],{"class":688,"line":805},[686,1654,849],{"class":716},[686,1656,1657],{"class":688,"line":818},[686,1658,1659],{"class":716},"  },\n",[686,1661,1662,1665],{"class":688,"line":831},[686,1663,1664],{"class":738},"  \"run\"",[686,1666,1142],{"class":716},[686,1668,1669,1672,1674,1677],{"class":688,"line":846},[686,1670,1671],{"class":738},"    \"startedAt\"",[686,1673,742],{"class":716},[686,1675,1676],{"class":699},"\"2026-12-03T02:15:00.004Z\"",[686,1678,748],{"class":716},[686,1680,1681,1684,1686,1689,1691,1693],{"class":688,"line":852},[686,1682,1683],{"class":738},"    \"finished\"",[686,1685,864],{"class":716},[686,1687,1688],{"class":738},"\"stem:66e6a3f5c1d2b30012a4f9c1\"",[686,1690,742],{"class":716},[686,1692,745],{"class":695},[686,1694,904],{"class":716},[686,1696,1697],{"class":688,"line":858},[686,1698,1193],{"class":716},[686,1700,1701],{"class":688,"line":907},[686,1702,910],{"class":716},[367,1704,1705,1713,1719],{},[370,1706,1707,1709,1710,1712],{},[384,1708,257],{}," is keyed by organization, kind and ",[384,1711,441],{},", so a document is never downloaded twice, even\nif it appears on a later page or in a later run.",[370,1714,1715,1718],{},[384,1716,1717],{},"run"," records which student and organization pairs the current run has finished. If the job stops\nhalfway, the next start within 20 hours skips those pairs. A finished run clears it.",[370,1720,1721],{},"The file is rewritten atomically (write a temporary file, then rename) after each download, so a\ncrash never leaves it half-written.",[362,1723,1725],{"id":1724},"the-complete-job","The complete job",[1727,1728,308],"h3",{"id":1729},"nodejs",[676,1731,1736],{"className":1732,"code":1733,"filename":1734,"language":1735,"meta":682,"style":682},"language-js shiki shiki-themes github-light-high-contrast github-dark-high-contrast","\u002F\u002F collect-results.mjs: download newly released certificates and reports for all your students.\n\u002F\u002F Usage: node collect-results.mjs .\u002Fresults\nimport { createWriteStream } from 'node:fs';\nimport { mkdir, readFile, rename, rm, stat, writeFile } from 'node:fs\u002Fpromises';\nimport { dirname, extname, join } from 'node:path';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream\u002Fpromises';\nimport { api, ApiError } from '.\u002Fmainteam.mjs';\n\nconst OUT_DIR = process.argv[2] ?? '.\u002Fresults';\nconst STATE_FILE = join(OUT_DIR, 'state.json');\nconst MIN_INTERVAL_MS = 650; \u002F\u002F per operation: about 92 calls a minute, under the 100 allowed\nconst RESUME_WINDOW_MS = 20 * 60 * 60 * 1000;\n\n\u002F\u002F ---- checkpoint -------------------------------------------------------------\nasync function loadState() {\n  try {\n    return JSON.parse(await readFile(STATE_FILE, 'utf8'));\n  } catch {\n    return { documents: {}, run: null };\n  }\n}\n\nasync function saveState(state) {\n  await mkdir(OUT_DIR, { recursive: true });\n  await writeFile(`${STATE_FILE}.tmp`, JSON.stringify(state, null, 2));\n  await rename(`${STATE_FILE}.tmp`, STATE_FILE);\n}\n\n\u002F\u002F ---- pacing: one lane per operation ---------------------------------------\nconst lastCall = new Map();\nasync function paced(route, send) {\n  const wait = (lastCall.get(route) ?? 0) + MIN_INTERVAL_MS - Date.now();\n  if (wait > 0) await new Promise((resolve) => setTimeout(resolve, wait));\n  lastCall.set(route, Date.now());\n  return send();\n}\n\n\u002F\u002F ---- every item of a paginated list -----------------------------------------\nasync function* allPages(route, path) {\n  for (let page = 1; ; page++) {\n    const separator = path.includes('?') ? '&' : '?';\n    const res = await paced(route, () => api('GET', `${path}${separator}page=${page}&limit=100`));\n    yield* res.data;\n    if (page >= res.pagination.totalPages) return;\n  }\n}\n\n\u002F\u002F ---- downloads ----------------------------------------------------------------\nfunction serverFileName(header) {\n  const encoded = \u002Ffilename\\*=UTF-8''([^;]+)\u002Fi.exec(header ?? '');\n  if (encoded) return decodeURIComponent(encoded[1]);\n  const plain = \u002Ffilename=\"([^\"]*)\"\u002Fi.exec(header ?? '');\n  return plain ? plain[1] : null;\n}\n\nasync function download(route, path, target) {\n  const res = await paced(route, () => api('GET', path, undefined, { raw: true, timeoutMs: 300_000 }));\n  const serverName = serverFileName(res.headers.get('content-disposition'));\n  const file = target + (extname(serverName ?? '') || '.pdf');\n  const part = `${file}.part`;\n  await mkdir(dirname(file), { recursive: true });\n  try {\n    await pipeline(Readable.fromWeb(res.body), createWriteStream(part));\n    const expected = Number(res.headers.get('content-length'));\n    if (expected && (await stat(part)).size !== expected) throw new Error('truncated download');\n    await rename(part, file);\n  } catch (error) {\n    await rm(part, { force: true });\n    throw error;\n  }\n  return { file, serverName };\n}\n\nconst describe = (error) =>\n  error instanceof ApiError ? `${error.status} ${error.code} (request ${error.requestId})` : error.message;\n\n\u002F\u002F ---- the run -------------------------------------------------------------------\nasync function main() {\n  const state = await loadState();\n  if (state.run && Date.now() - Date.parse(state.run.startedAt) \u003C RESUME_WINDOW_MS) {\n    console.log(`Resuming the run started at ${state.run.startedAt}`);\n  } else {\n    state.run = { startedAt: new Date().toISOString(), finished: {} };\n  }\n\n  const students = [];\n  for await (const student of allPages('students', '\u002Fstudent')) students.push(student);\n  const organizations = (await api('GET', '\u002Forganization?limit=100')).data;\n  const counts = { downloaded: 0, known: 0, notYet: 0, failed: 0 };\n\n  for (const org of organizations) {\n    console.log(`${org.slug}: ${students.length} students`);\n\n    for (const student of students) {\n      const pair = `${org.slug}:${student._id}`;\n      if (state.run.finished[pair]) continue;\n      try {\n        for (const kind of ['certificate', 'report']) {\n          for await (const doc of allPages(`${kind}-list`, `\u002F${org._id}\u002F${kind}\u002F${student._id}`)) {\n            const key = `${org.slug}\u002F${kind}\u002F${doc._id}`;\n            if (state.documents[key]) {\n              counts.known++;\n              continue;\n            }\n            try {\n              const target = join(OUT_DIR, org.slug, student._id, `${kind}-${doc.shortId ?? doc._id}`);\n              const { file, serverName } = await download(\n                `${kind}-download`,\n                `\u002F${org._id}\u002F${kind}\u002Fdownload\u002F${doc._id}`,\n                target,\n              );\n              state.documents[key] = { shortId: doc.shortId, file, serverName, at: new Date().toISOString() };\n              await saveState(state);\n              counts.downloaded++;\n              console.log(`  + ${key} -> ${file}`);\n            } catch (error) {\n              counts.failed++; \u002F\u002F not recorded, so the next run tries again\n              console.warn(`  ! ${key}: ${describe(error)}`);\n            }\n          }\n        }\n      } catch (error) {\n        if (error instanceof ApiError && error.status === 409) {\n          counts.notYet++; \u002F\u002F never signed in to this organization: nothing to collect yet\n        } else if (error instanceof ApiError && error.status === 403) {\n          console.warn(`  ! ${org.slug}: ${describe(error)}; skipping this organization`);\n          break;\n        } else {\n          throw error; \u002F\u002F the next start resumes from the last finished pair\n        }\n      }\n      state.run.finished[pair] = true;\n      await saveState(state);\n    }\n  }\n\n  state.run = null;\n  await saveState(state);\n  console.log(\n    `Done: ${counts.downloaded} downloaded, ${counts.known} already had, ` +\n      `${counts.notYet} pairs without a sign-in, ${counts.failed} failed.`,\n  );\n}\n\nmain().catch((error) => {\n  console.error(`Stopped: ${describe(error)}`);\n  process.exitCode = 1;\n});\n","collect-results.mjs","js",[384,1737,1738,1744,1749,1766,1780,1794,1808,1822,1836,1842,1870,1897,1915,1944,1948,1953,1968,1977,2012,2023,2037,2042,2047,2052,2070,2091,2130,2152,2157,2162,2168,2187,2209,2252,2291,2308,2319,2324,2329,2335,2357,2386,2424,2474,2483,2503,2508,2513,2518,2524,2540,2592,2613,2653,2677,2682,2687,2712,2755,2779,2816,2837,2856,2863,2887,2911,2953,2963,2973,2988,2997,3002,3010,3015,3020,3040,3091,3096,3102,3114,3130,3163,3193,3203,3229,3234,3239,3252,3290,3318,3351,3356,3373,3407,3412,3429,3462,3476,3484,3513,3571,3607,3616,3626,3634,3640,3648,3694,3721,3734,3763,3769,3775,3797,3808,3818,3843,3853,3866,3897,3902,3908,3914,3924,3951,3964,3992,4025,4033,4042,4054,4059,4065,4078,4088,4093,4098,4103,4115,4124,4134,4164,4192,4198,4203,4208,4228,4252,4264],{"__ignoreMap":682},[686,1739,1740],{"class":688,"line":689},[686,1741,1743],{"class":1742},"sLBg1","\u002F\u002F collect-results.mjs: download newly released certificates and reports for all your students.\n",[686,1745,1746],{"class":688,"line":707},[686,1747,1748],{"class":1742},"\u002F\u002F Usage: node collect-results.mjs .\u002Fresults\n",[686,1750,1751,1754,1757,1760,1763],{"class":688,"line":751},[686,1752,1753],{"class":703},"import",[686,1755,1756],{"class":716}," { createWriteStream } ",[686,1758,1759],{"class":703},"from",[686,1761,1762],{"class":699}," 'node:fs'",[686,1764,1765],{"class":716},";\n",[686,1767,1768,1770,1773,1775,1778],{"class":688,"line":764},[686,1769,1753],{"class":703},[686,1771,1772],{"class":716}," { mkdir, readFile, rename, rm, stat, writeFile } ",[686,1774,1759],{"class":703},[686,1776,1777],{"class":699}," 'node:fs\u002Fpromises'",[686,1779,1765],{"class":716},[686,1781,1782,1784,1787,1789,1792],{"class":688,"line":773},[686,1783,1753],{"class":703},[686,1785,1786],{"class":716}," { dirname, extname, join } ",[686,1788,1759],{"class":703},[686,1790,1791],{"class":699}," 'node:path'",[686,1793,1765],{"class":716},[686,1795,1796,1798,1801,1803,1806],{"class":688,"line":779},[686,1797,1753],{"class":703},[686,1799,1800],{"class":716}," { Readable } ",[686,1802,1759],{"class":703},[686,1804,1805],{"class":699}," 'node:stream'",[686,1807,1765],{"class":716},[686,1809,1810,1812,1815,1817,1820],{"class":688,"line":792},[686,1811,1753],{"class":703},[686,1813,1814],{"class":716}," { pipeline } ",[686,1816,1759],{"class":703},[686,1818,1819],{"class":699}," 'node:stream\u002Fpromises'",[686,1821,1765],{"class":716},[686,1823,1824,1826,1829,1831,1834],{"class":688,"line":805},[686,1825,1753],{"class":703},[686,1827,1828],{"class":716}," { api, ApiError } ",[686,1830,1759],{"class":703},[686,1832,1833],{"class":699}," '.\u002Fmainteam.mjs'",[686,1835,1765],{"class":716},[686,1837,1838],{"class":688,"line":818},[686,1839,1841],{"emptyLinePlaceholder":1840},true,"\n",[686,1843,1844,1847,1850,1853,1856,1859,1862,1865,1868],{"class":688,"line":831},[686,1845,1846],{"class":703},"const",[686,1848,1849],{"class":695}," OUT_DIR",[686,1851,1852],{"class":703}," =",[686,1854,1855],{"class":716}," process.argv[",[686,1857,1858],{"class":695},"2",[686,1860,1861],{"class":716},"] ",[686,1863,1864],{"class":703},"??",[686,1866,1867],{"class":699}," '.\u002Fresults'",[686,1869,1765],{"class":716},[686,1871,1872,1874,1877,1879,1883,1886,1889,1891,1894],{"class":688,"line":846},[686,1873,1846],{"class":703},[686,1875,1876],{"class":695}," STATE_FILE",[686,1878,1852],{"class":703},[686,1880,1882],{"class":1881},"sKwhi"," join",[686,1884,1885],{"class":716},"(",[686,1887,1888],{"class":695},"OUT_DIR",[686,1890,455],{"class":716},[686,1892,1893],{"class":699},"'state.json'",[686,1895,1896],{"class":716},");\n",[686,1898,1899,1901,1904,1906,1909,1912],{"class":688,"line":852},[686,1900,1846],{"class":703},[686,1902,1903],{"class":695}," MIN_INTERVAL_MS",[686,1905,1852],{"class":703},[686,1907,1908],{"class":695}," 650",[686,1910,1911],{"class":716},"; ",[686,1913,1914],{"class":1742},"\u002F\u002F per operation: about 92 calls a minute, under the 100 allowed\n",[686,1916,1917,1919,1922,1924,1927,1930,1933,1935,1937,1939,1942],{"class":688,"line":858},[686,1918,1846],{"class":703},[686,1920,1921],{"class":695}," RESUME_WINDOW_MS",[686,1923,1852],{"class":703},[686,1925,1926],{"class":695}," 20",[686,1928,1929],{"class":703}," *",[686,1931,1932],{"class":695}," 60",[686,1934,1929],{"class":703},[686,1936,1932],{"class":695},[686,1938,1929],{"class":703},[686,1940,1941],{"class":695}," 1000",[686,1943,1765],{"class":716},[686,1945,1946],{"class":688,"line":907},[686,1947,1841],{"emptyLinePlaceholder":1840},[686,1949,1950],{"class":688,"line":1110},[686,1951,1952],{"class":1742},"\u002F\u002F ---- checkpoint -------------------------------------------------------------\n",[686,1954,1956,1959,1962,1965],{"class":688,"line":1955},16,[686,1957,1958],{"class":703},"async",[686,1960,1961],{"class":703}," function",[686,1963,1964],{"class":1881}," loadState",[686,1966,1967],{"class":716},"() {\n",[686,1969,1971,1974],{"class":688,"line":1970},17,[686,1972,1973],{"class":703},"  try",[686,1975,1976],{"class":716}," {\n",[686,1978,1980,1983,1986,1988,1991,1993,1996,1999,2001,2004,2006,2009],{"class":688,"line":1979},18,[686,1981,1982],{"class":703},"    return",[686,1984,1985],{"class":695}," JSON",[686,1987,425],{"class":716},[686,1989,1990],{"class":1881},"parse",[686,1992,1885],{"class":716},[686,1994,1995],{"class":703},"await",[686,1997,1998],{"class":1881}," readFile",[686,2000,1885],{"class":716},[686,2002,2003],{"class":695},"STATE_FILE",[686,2005,455],{"class":716},[686,2007,2008],{"class":699},"'utf8'",[686,2010,2011],{"class":716},"));\n",[686,2013,2015,2018,2021],{"class":688,"line":2014},19,[686,2016,2017],{"class":716},"  } ",[686,2019,2020],{"class":703},"catch",[686,2022,1976],{"class":716},[686,2024,2026,2028,2031,2034],{"class":688,"line":2025},20,[686,2027,1982],{"class":703},[686,2029,2030],{"class":716}," { documents: {}, run: ",[686,2032,2033],{"class":695},"null",[686,2035,2036],{"class":716}," };\n",[686,2038,2040],{"class":688,"line":2039},21,[686,2041,1193],{"class":716},[686,2043,2045],{"class":688,"line":2044},22,[686,2046,910],{"class":716},[686,2048,2050],{"class":688,"line":2049},23,[686,2051,1841],{"emptyLinePlaceholder":1840},[686,2053,2055,2057,2059,2062,2064,2067],{"class":688,"line":2054},24,[686,2056,1958],{"class":703},[686,2058,1961],{"class":703},[686,2060,2061],{"class":1881}," saveState",[686,2063,1885],{"class":716},[686,2065,2066],{"class":692},"state",[686,2068,2069],{"class":716},") {\n",[686,2071,2073,2076,2079,2081,2083,2086,2088],{"class":688,"line":2072},25,[686,2074,2075],{"class":703},"  await",[686,2077,2078],{"class":1881}," mkdir",[686,2080,1885],{"class":716},[686,2082,1888],{"class":695},[686,2084,2085],{"class":716},", { recursive: ",[686,2087,745],{"class":695},[686,2089,2090],{"class":716}," });\n",[686,2092,2094,2096,2099,2101,2104,2106,2109,2111,2114,2116,2119,2122,2124,2126,2128],{"class":688,"line":2093},26,[686,2095,2075],{"class":703},[686,2097,2098],{"class":1881}," writeFile",[686,2100,1885],{"class":716},[686,2102,2103],{"class":699},"`${",[686,2105,2003],{"class":695},[686,2107,2108],{"class":699},"}.tmp`",[686,2110,455],{"class":716},[686,2112,2113],{"class":695},"JSON",[686,2115,425],{"class":716},[686,2117,2118],{"class":1881},"stringify",[686,2120,2121],{"class":716},"(state, ",[686,2123,2033],{"class":695},[686,2125,455],{"class":716},[686,2127,1858],{"class":695},[686,2129,2011],{"class":716},[686,2131,2133,2135,2138,2140,2142,2144,2146,2148,2150],{"class":688,"line":2132},27,[686,2134,2075],{"class":703},[686,2136,2137],{"class":1881}," rename",[686,2139,1885],{"class":716},[686,2141,2103],{"class":699},[686,2143,2003],{"class":695},[686,2145,2108],{"class":699},[686,2147,455],{"class":716},[686,2149,2003],{"class":695},[686,2151,1896],{"class":716},[686,2153,2155],{"class":688,"line":2154},28,[686,2156,910],{"class":716},[686,2158,2160],{"class":688,"line":2159},29,[686,2161,1841],{"emptyLinePlaceholder":1840},[686,2163,2165],{"class":688,"line":2164},30,[686,2166,2167],{"class":1742},"\u002F\u002F ---- pacing: one lane per operation ---------------------------------------\n",[686,2169,2171,2173,2176,2178,2181,2184],{"class":688,"line":2170},31,[686,2172,1846],{"class":703},[686,2174,2175],{"class":695}," lastCall",[686,2177,1852],{"class":703},[686,2179,2180],{"class":703}," new",[686,2182,2183],{"class":1881}," Map",[686,2185,2186],{"class":716},"();\n",[686,2188,2190,2192,2194,2197,2199,2202,2204,2207],{"class":688,"line":2189},32,[686,2191,1958],{"class":703},[686,2193,1961],{"class":703},[686,2195,2196],{"class":1881}," paced",[686,2198,1885],{"class":716},[686,2200,2201],{"class":692},"route",[686,2203,455],{"class":716},[686,2205,2206],{"class":692},"send",[686,2208,2069],{"class":716},[686,2210,2212,2215,2218,2220,2223,2226,2229,2231,2234,2237,2240,2242,2244,2247,2250],{"class":688,"line":2211},33,[686,2213,2214],{"class":703},"  const",[686,2216,2217],{"class":695}," wait",[686,2219,1852],{"class":703},[686,2221,2222],{"class":716}," (lastCall.",[686,2224,2225],{"class":1881},"get",[686,2227,2228],{"class":716},"(route) ",[686,2230,1864],{"class":703},[686,2232,2233],{"class":695}," 0",[686,2235,2236],{"class":716},") ",[686,2238,2239],{"class":703},"+",[686,2241,1903],{"class":695},[686,2243,1413],{"class":703},[686,2245,2246],{"class":716}," Date.",[686,2248,2249],{"class":1881},"now",[686,2251,2186],{"class":716},[686,2253,2255,2258,2261,2263,2265,2267,2269,2271,2274,2277,2280,2282,2285,2288],{"class":688,"line":2254},34,[686,2256,2257],{"class":703},"  if",[686,2259,2260],{"class":716}," (wait ",[686,2262,1438],{"class":703},[686,2264,2233],{"class":695},[686,2266,2236],{"class":716},[686,2268,1995],{"class":703},[686,2270,2180],{"class":703},[686,2272,2273],{"class":695}," Promise",[686,2275,2276],{"class":716},"((",[686,2278,2279],{"class":692},"resolve",[686,2281,2236],{"class":716},[686,2283,2284],{"class":703},"=>",[686,2286,2287],{"class":1881}," setTimeout",[686,2289,2290],{"class":716},"(resolve, wait));\n",[686,2292,2294,2297,2300,2303,2305],{"class":688,"line":2293},35,[686,2295,2296],{"class":716},"  lastCall.",[686,2298,2299],{"class":1881},"set",[686,2301,2302],{"class":716},"(route, Date.",[686,2304,2249],{"class":1881},[686,2306,2307],{"class":716},"());\n",[686,2309,2311,2314,2317],{"class":688,"line":2310},36,[686,2312,2313],{"class":703},"  return",[686,2315,2316],{"class":1881}," send",[686,2318,2186],{"class":716},[686,2320,2322],{"class":688,"line":2321},37,[686,2323,910],{"class":716},[686,2325,2327],{"class":688,"line":2326},38,[686,2328,1841],{"emptyLinePlaceholder":1840},[686,2330,2332],{"class":688,"line":2331},39,[686,2333,2334],{"class":1742},"\u002F\u002F ---- every item of a paginated list -----------------------------------------\n",[686,2336,2338,2340,2343,2346,2348,2350,2352,2355],{"class":688,"line":2337},40,[686,2339,1958],{"class":703},[686,2341,2342],{"class":703}," function*",[686,2344,2345],{"class":1881}," allPages",[686,2347,1885],{"class":716},[686,2349,2201],{"class":692},[686,2351,455],{"class":716},[686,2353,2354],{"class":692},"path",[686,2356,2069],{"class":716},[686,2358,2360,2363,2366,2369,2372,2375,2378,2381,2384],{"class":688,"line":2359},41,[686,2361,2362],{"class":703},"  for",[686,2364,2365],{"class":716}," (",[686,2367,2368],{"class":703},"let",[686,2370,2371],{"class":716}," page ",[686,2373,2374],{"class":703},"=",[686,2376,2377],{"class":695}," 1",[686,2379,2380],{"class":716},"; ; page",[686,2382,2383],{"class":703},"++",[686,2385,2069],{"class":716},[686,2387,2389,2392,2395,2397,2400,2403,2405,2408,2410,2413,2416,2419,2422],{"class":688,"line":2388},42,[686,2390,2391],{"class":703},"    const",[686,2393,2394],{"class":695}," separator",[686,2396,1852],{"class":703},[686,2398,2399],{"class":716}," path.",[686,2401,2402],{"class":1881},"includes",[686,2404,1885],{"class":716},[686,2406,2407],{"class":699},"'?'",[686,2409,2236],{"class":716},[686,2411,2412],{"class":703},"?",[686,2414,2415],{"class":699}," '&'",[686,2417,2418],{"class":703}," :",[686,2420,2421],{"class":699}," '?'",[686,2423,1765],{"class":716},[686,2425,2427,2429,2432,2434,2437,2439,2442,2444,2447,2449,2452,2454,2456,2458,2461,2464,2467,2469,2472],{"class":688,"line":2426},43,[686,2428,2391],{"class":703},[686,2430,2431],{"class":695}," res",[686,2433,1852],{"class":703},[686,2435,2436],{"class":703}," await",[686,2438,2196],{"class":1881},[686,2440,2441],{"class":716},"(route, () ",[686,2443,2284],{"class":703},[686,2445,2446],{"class":1881}," api",[686,2448,1885],{"class":716},[686,2450,2451],{"class":699},"'GET'",[686,2453,455],{"class":716},[686,2455,2103],{"class":699},[686,2457,2354],{"class":716},[686,2459,2460],{"class":699},"}${",[686,2462,2463],{"class":716},"separator",[686,2465,2466],{"class":699},"}page=${",[686,2468,413],{"class":716},[686,2470,2471],{"class":699},"}&limit=100`",[686,2473,2011],{"class":716},[686,2475,2477,2480],{"class":688,"line":2476},44,[686,2478,2479],{"class":703},"    yield*",[686,2481,2482],{"class":716}," res.data;\n",[686,2484,2486,2489,2492,2495,2498,2501],{"class":688,"line":2485},45,[686,2487,2488],{"class":703},"    if",[686,2490,2491],{"class":716}," (page ",[686,2493,2494],{"class":703},">=",[686,2496,2497],{"class":716}," res.pagination.totalPages) ",[686,2499,2500],{"class":703},"return",[686,2502,1765],{"class":716},[686,2504,2506],{"class":688,"line":2505},46,[686,2507,1193],{"class":716},[686,2509,2511],{"class":688,"line":2510},47,[686,2512,910],{"class":716},[686,2514,2516],{"class":688,"line":2515},48,[686,2517,1841],{"emptyLinePlaceholder":1840},[686,2519,2521],{"class":688,"line":2520},49,[686,2522,2523],{"class":1742},"\u002F\u002F ---- downloads ----------------------------------------------------------------\n",[686,2525,2527,2530,2533,2535,2538],{"class":688,"line":2526},50,[686,2528,2529],{"class":703},"function",[686,2531,2532],{"class":1881}," serverFileName",[686,2534,1885],{"class":716},[686,2536,2537],{"class":692},"header",[686,2539,2069],{"class":716},[686,2541,2543,2545,2548,2550,2553,2557,2560,2563,2566,2569,2571,2574,2577,2579,2582,2585,2587,2590],{"class":688,"line":2542},51,[686,2544,2214],{"class":703},[686,2546,2547],{"class":695}," encoded",[686,2549,1852],{"class":703},[686,2551,2552],{"class":699}," \u002Ffilename",[686,2554,2556],{"class":2555},"sJaa3","\\*",[686,2558,2559],{"class":699},"=UTF-8''(",[686,2561,2562],{"class":695},"[",[686,2564,2565],{"class":703},"^",[686,2567,2568],{"class":695},";]",[686,2570,2239],{"class":703},[686,2572,2573],{"class":699},")\u002F",[686,2575,2576],{"class":703},"i",[686,2578,425],{"class":716},[686,2580,2581],{"class":1881},"exec",[686,2583,2584],{"class":716},"(header ",[686,2586,1864],{"class":703},[686,2588,2589],{"class":699}," ''",[686,2591,1896],{"class":716},[686,2593,2595,2597,2600,2602,2605,2608,2610],{"class":688,"line":2594},52,[686,2596,2257],{"class":703},[686,2598,2599],{"class":716}," (encoded) ",[686,2601,2500],{"class":703},[686,2603,2604],{"class":1881}," decodeURIComponent",[686,2606,2607],{"class":716},"(encoded[",[686,2609,545],{"class":695},[686,2611,2612],{"class":716},"]);\n",[686,2614,2616,2618,2621,2623,2626,2628,2630,2633,2636,2639,2641,2643,2645,2647,2649,2651],{"class":688,"line":2615},53,[686,2617,2214],{"class":703},[686,2619,2620],{"class":695}," plain",[686,2622,1852],{"class":703},[686,2624,2625],{"class":699}," \u002Ffilename=\"(",[686,2627,2562],{"class":695},[686,2629,2565],{"class":703},[686,2631,2632],{"class":695},"\"]",[686,2634,2635],{"class":703},"*",[686,2637,2638],{"class":699},")\"\u002F",[686,2640,2576],{"class":703},[686,2642,425],{"class":716},[686,2644,2581],{"class":1881},[686,2646,2584],{"class":716},[686,2648,1864],{"class":703},[686,2650,2589],{"class":699},[686,2652,1896],{"class":716},[686,2654,2656,2658,2661,2663,2666,2668,2670,2672,2675],{"class":688,"line":2655},54,[686,2657,2313],{"class":703},[686,2659,2660],{"class":716}," plain ",[686,2662,2412],{"class":703},[686,2664,2665],{"class":716}," plain[",[686,2667,545],{"class":695},[686,2669,1861],{"class":716},[686,2671,1486],{"class":703},[686,2673,2674],{"class":695}," null",[686,2676,1765],{"class":716},[686,2678,2680],{"class":688,"line":2679},55,[686,2681,910],{"class":716},[686,2683,2685],{"class":688,"line":2684},56,[686,2686,1841],{"emptyLinePlaceholder":1840},[686,2688,2690,2692,2694,2697,2699,2701,2703,2705,2707,2710],{"class":688,"line":2689},57,[686,2691,1958],{"class":703},[686,2693,1961],{"class":703},[686,2695,2696],{"class":1881}," download",[686,2698,1885],{"class":716},[686,2700,2201],{"class":692},[686,2702,455],{"class":716},[686,2704,2354],{"class":692},[686,2706,455],{"class":716},[686,2708,2709],{"class":692},"target",[686,2711,2069],{"class":716},[686,2713,2715,2717,2719,2721,2723,2725,2727,2729,2731,2733,2735,2738,2741,2744,2746,2749,2752],{"class":688,"line":2714},58,[686,2716,2214],{"class":703},[686,2718,2431],{"class":695},[686,2720,1852],{"class":703},[686,2722,2436],{"class":703},[686,2724,2196],{"class":1881},[686,2726,2441],{"class":716},[686,2728,2284],{"class":703},[686,2730,2446],{"class":1881},[686,2732,1885],{"class":716},[686,2734,2451],{"class":699},[686,2736,2737],{"class":716},", path, ",[686,2739,2740],{"class":695},"undefined",[686,2742,2743],{"class":716},", { raw: ",[686,2745,745],{"class":695},[686,2747,2748],{"class":716},", timeoutMs: ",[686,2750,2751],{"class":695},"300_000",[686,2753,2754],{"class":716}," }));\n",[686,2756,2758,2760,2763,2765,2767,2770,2772,2774,2777],{"class":688,"line":2757},59,[686,2759,2214],{"class":703},[686,2761,2762],{"class":695}," serverName",[686,2764,1852],{"class":703},[686,2766,2532],{"class":1881},[686,2768,2769],{"class":716},"(res.headers.",[686,2771,2225],{"class":1881},[686,2773,1885],{"class":716},[686,2775,2776],{"class":699},"'content-disposition'",[686,2778,2011],{"class":716},[686,2780,2782,2784,2787,2789,2792,2794,2796,2799,2802,2804,2806,2808,2811,2814],{"class":688,"line":2781},60,[686,2783,2214],{"class":703},[686,2785,2786],{"class":695}," file",[686,2788,1852],{"class":703},[686,2790,2791],{"class":716}," target ",[686,2793,2239],{"class":703},[686,2795,2365],{"class":716},[686,2797,2798],{"class":1881},"extname",[686,2800,2801],{"class":716},"(serverName ",[686,2803,1864],{"class":703},[686,2805,2589],{"class":699},[686,2807,2236],{"class":716},[686,2809,2810],{"class":703},"||",[686,2812,2813],{"class":699}," '.pdf'",[686,2815,1896],{"class":716},[686,2817,2819,2821,2824,2826,2829,2832,2835],{"class":688,"line":2818},61,[686,2820,2214],{"class":703},[686,2822,2823],{"class":695}," part",[686,2825,1852],{"class":703},[686,2827,2828],{"class":699}," `${",[686,2830,2831],{"class":716},"file",[686,2833,2834],{"class":699},"}.part`",[686,2836,1765],{"class":716},[686,2838,2840,2842,2844,2846,2849,2852,2854],{"class":688,"line":2839},62,[686,2841,2075],{"class":703},[686,2843,2078],{"class":1881},[686,2845,1885],{"class":716},[686,2847,2848],{"class":1881},"dirname",[686,2850,2851],{"class":716},"(file), { recursive: ",[686,2853,745],{"class":695},[686,2855,2090],{"class":716},[686,2857,2859,2861],{"class":688,"line":2858},63,[686,2860,1973],{"class":703},[686,2862,1976],{"class":716},[686,2864,2866,2869,2872,2875,2878,2881,2884],{"class":688,"line":2865},64,[686,2867,2868],{"class":703},"    await",[686,2870,2871],{"class":1881}," pipeline",[686,2873,2874],{"class":716},"(Readable.",[686,2876,2877],{"class":1881},"fromWeb",[686,2879,2880],{"class":716},"(res.body), ",[686,2882,2883],{"class":1881},"createWriteStream",[686,2885,2886],{"class":716},"(part));\n",[686,2888,2890,2892,2895,2897,2900,2902,2904,2906,2909],{"class":688,"line":2889},65,[686,2891,2391],{"class":703},[686,2893,2894],{"class":695}," expected",[686,2896,1852],{"class":703},[686,2898,2899],{"class":1881}," Number",[686,2901,2769],{"class":716},[686,2903,2225],{"class":1881},[686,2905,1885],{"class":716},[686,2907,2908],{"class":699},"'content-length'",[686,2910,2011],{"class":716},[686,2912,2914,2916,2919,2922,2924,2926,2929,2932,2935,2938,2941,2943,2946,2948,2951],{"class":688,"line":2913},66,[686,2915,2488],{"class":703},[686,2917,2918],{"class":716}," (expected ",[686,2920,2921],{"class":703},"&&",[686,2923,2365],{"class":716},[686,2925,1995],{"class":703},[686,2927,2928],{"class":1881}," stat",[686,2930,2931],{"class":716},"(part)).size ",[686,2933,2934],{"class":703},"!==",[686,2936,2937],{"class":716}," expected) ",[686,2939,2940],{"class":703},"throw",[686,2942,2180],{"class":703},[686,2944,2945],{"class":1881}," Error",[686,2947,1885],{"class":716},[686,2949,2950],{"class":699},"'truncated download'",[686,2952,1896],{"class":716},[686,2954,2956,2958,2960],{"class":688,"line":2955},67,[686,2957,2868],{"class":703},[686,2959,2137],{"class":1881},[686,2961,2962],{"class":716},"(part, file);\n",[686,2964,2966,2968,2970],{"class":688,"line":2965},68,[686,2967,2017],{"class":716},[686,2969,2020],{"class":703},[686,2971,2972],{"class":716}," (error) {\n",[686,2974,2976,2978,2981,2984,2986],{"class":688,"line":2975},69,[686,2977,2868],{"class":703},[686,2979,2980],{"class":1881}," rm",[686,2982,2983],{"class":716},"(part, { force: ",[686,2985,745],{"class":695},[686,2987,2090],{"class":716},[686,2989,2991,2994],{"class":688,"line":2990},70,[686,2992,2993],{"class":703},"    throw",[686,2995,2996],{"class":716}," error;\n",[686,2998,3000],{"class":688,"line":2999},71,[686,3001,1193],{"class":716},[686,3003,3005,3007],{"class":688,"line":3004},72,[686,3006,2313],{"class":703},[686,3008,3009],{"class":716}," { file, serverName };\n",[686,3011,3013],{"class":688,"line":3012},73,[686,3014,910],{"class":716},[686,3016,3018],{"class":688,"line":3017},74,[686,3019,1841],{"emptyLinePlaceholder":1840},[686,3021,3023,3025,3028,3030,3032,3035,3037],{"class":688,"line":3022},75,[686,3024,1846],{"class":703},[686,3026,3027],{"class":1881}," describe",[686,3029,1852],{"class":703},[686,3031,2365],{"class":716},[686,3033,3034],{"class":692},"error",[686,3036,2236],{"class":716},[686,3038,3039],{"class":703},"=>\n",[686,3041,3043,3046,3049,3052,3055,3057,3059,3061,3064,3067,3069,3071,3073,3076,3078,3080,3083,3086,3088],{"class":688,"line":3042},76,[686,3044,3045],{"class":716},"  error ",[686,3047,3048],{"class":703},"instanceof",[686,3050,3051],{"class":692}," ApiError",[686,3053,3054],{"class":703}," ?",[686,3056,2828],{"class":699},[686,3058,3034],{"class":716},[686,3060,425],{"class":699},[686,3062,3063],{"class":716},"status",[686,3065,3066],{"class":699},"} ${",[686,3068,3034],{"class":716},[686,3070,425],{"class":699},[686,3072,384],{"class":716},[686,3074,3075],{"class":699},"} (request ${",[686,3077,3034],{"class":716},[686,3079,425],{"class":699},[686,3081,3082],{"class":716},"requestId",[686,3084,3085],{"class":699},"})`",[686,3087,2418],{"class":703},[686,3089,3090],{"class":716}," error.message;\n",[686,3092,3094],{"class":688,"line":3093},77,[686,3095,1841],{"emptyLinePlaceholder":1840},[686,3097,3099],{"class":688,"line":3098},78,[686,3100,3101],{"class":1742},"\u002F\u002F ---- the run -------------------------------------------------------------------\n",[686,3103,3105,3107,3109,3112],{"class":688,"line":3104},79,[686,3106,1958],{"class":703},[686,3108,1961],{"class":703},[686,3110,3111],{"class":1881}," main",[686,3113,1967],{"class":716},[686,3115,3117,3119,3122,3124,3126,3128],{"class":688,"line":3116},80,[686,3118,2214],{"class":703},[686,3120,3121],{"class":695}," state",[686,3123,1852],{"class":703},[686,3125,2436],{"class":703},[686,3127,1964],{"class":1881},[686,3129,2186],{"class":716},[686,3131,3133,3135,3138,3140,3142,3144,3147,3150,3152,3154,3157,3159,3161],{"class":688,"line":3132},81,[686,3134,2257],{"class":703},[686,3136,3137],{"class":716}," (state.run ",[686,3139,2921],{"class":703},[686,3141,2246],{"class":716},[686,3143,2249],{"class":1881},[686,3145,3146],{"class":716},"() ",[686,3148,3149],{"class":703},"-",[686,3151,2246],{"class":716},[686,3153,1990],{"class":1881},[686,3155,3156],{"class":716},"(state.run.startedAt) ",[686,3158,1429],{"class":703},[686,3160,1921],{"class":695},[686,3162,2069],{"class":716},[686,3164,3166,3169,3172,3174,3177,3179,3181,3183,3185,3188,3191],{"class":688,"line":3165},82,[686,3167,3168],{"class":716},"    console.",[686,3170,3171],{"class":1881},"log",[686,3173,1885],{"class":716},[686,3175,3176],{"class":699},"`Resuming the run started at ${",[686,3178,2066],{"class":716},[686,3180,425],{"class":699},[686,3182,1717],{"class":716},[686,3184,425],{"class":699},[686,3186,3187],{"class":716},"startedAt",[686,3189,3190],{"class":699},"}`",[686,3192,1896],{"class":716},[686,3194,3196,3198,3201],{"class":688,"line":3195},83,[686,3197,2017],{"class":716},[686,3199,3200],{"class":703},"else",[686,3202,1976],{"class":716},[686,3204,3206,3209,3211,3214,3217,3220,3223,3226],{"class":688,"line":3205},84,[686,3207,3208],{"class":716},"    state.run ",[686,3210,2374],{"class":703},[686,3212,3213],{"class":716}," { startedAt: ",[686,3215,3216],{"class":703},"new",[686,3218,3219],{"class":1881}," Date",[686,3221,3222],{"class":716},"().",[686,3224,3225],{"class":1881},"toISOString",[686,3227,3228],{"class":716},"(), finished: {} };\n",[686,3230,3232],{"class":688,"line":3231},85,[686,3233,1193],{"class":716},[686,3235,3237],{"class":688,"line":3236},86,[686,3238,1841],{"emptyLinePlaceholder":1840},[686,3240,3242,3244,3247,3249],{"class":688,"line":3241},87,[686,3243,2214],{"class":703},[686,3245,3246],{"class":695}," students",[686,3248,1852],{"class":703},[686,3250,3251],{"class":716}," [];\n",[686,3253,3255,3257,3259,3261,3263,3266,3269,3271,3273,3276,3278,3281,3284,3287],{"class":688,"line":3254},88,[686,3256,2362],{"class":703},[686,3258,2436],{"class":703},[686,3260,2365],{"class":716},[686,3262,1846],{"class":703},[686,3264,3265],{"class":695}," student",[686,3267,3268],{"class":703}," of",[686,3270,2345],{"class":1881},[686,3272,1885],{"class":716},[686,3274,3275],{"class":699},"'students'",[686,3277,455],{"class":716},[686,3279,3280],{"class":699},"'\u002Fstudent'",[686,3282,3283],{"class":716},")) students.",[686,3285,3286],{"class":1881},"push",[686,3288,3289],{"class":716},"(student);\n",[686,3291,3293,3295,3298,3300,3302,3304,3306,3308,3310,3312,3315],{"class":688,"line":3292},89,[686,3294,2214],{"class":703},[686,3296,3297],{"class":695}," organizations",[686,3299,1852],{"class":703},[686,3301,2365],{"class":716},[686,3303,1995],{"class":703},[686,3305,2446],{"class":1881},[686,3307,1885],{"class":716},[686,3309,2451],{"class":699},[686,3311,455],{"class":716},[686,3313,3314],{"class":699},"'\u002Forganization?limit=100'",[686,3316,3317],{"class":716},")).data;\n",[686,3319,3321,3323,3326,3328,3331,3334,3337,3339,3342,3344,3347,3349],{"class":688,"line":3320},90,[686,3322,2214],{"class":703},[686,3324,3325],{"class":695}," counts",[686,3327,1852],{"class":703},[686,3329,3330],{"class":716}," { downloaded: ",[686,3332,3333],{"class":695},"0",[686,3335,3336],{"class":716},", known: ",[686,3338,3333],{"class":695},[686,3340,3341],{"class":716},", notYet: ",[686,3343,3333],{"class":695},[686,3345,3346],{"class":716},", failed: ",[686,3348,3333],{"class":695},[686,3350,2036],{"class":716},[686,3352,3354],{"class":688,"line":3353},91,[686,3355,1841],{"emptyLinePlaceholder":1840},[686,3357,3359,3361,3363,3365,3368,3370],{"class":688,"line":3358},92,[686,3360,2362],{"class":703},[686,3362,2365],{"class":716},[686,3364,1846],{"class":703},[686,3366,3367],{"class":695}," org",[686,3369,3268],{"class":703},[686,3371,3372],{"class":716}," organizations) {\n",[686,3374,3376,3378,3380,3382,3384,3387,3389,3392,3395,3397,3399,3402,3405],{"class":688,"line":3375},93,[686,3377,3168],{"class":716},[686,3379,3171],{"class":1881},[686,3381,1885],{"class":716},[686,3383,2103],{"class":699},[686,3385,3386],{"class":716},"org",[686,3388,425],{"class":699},[686,3390,3391],{"class":716},"slug",[686,3393,3394],{"class":699},"}: ${",[686,3396,167],{"class":716},[686,3398,425],{"class":699},[686,3400,3401],{"class":695},"length",[686,3403,3404],{"class":699},"} students`",[686,3406,1896],{"class":716},[686,3408,3410],{"class":688,"line":3409},94,[686,3411,1841],{"emptyLinePlaceholder":1840},[686,3413,3415,3418,3420,3422,3424,3426],{"class":688,"line":3414},95,[686,3416,3417],{"class":703},"    for",[686,3419,2365],{"class":716},[686,3421,1846],{"class":703},[686,3423,3265],{"class":695},[686,3425,3268],{"class":703},[686,3427,3428],{"class":716}," students) {\n",[686,3430,3432,3435,3438,3440,3442,3444,3446,3448,3451,3454,3456,3458,3460],{"class":688,"line":3431},96,[686,3433,3434],{"class":703},"      const",[686,3436,3437],{"class":695}," pair",[686,3439,1852],{"class":703},[686,3441,2828],{"class":699},[686,3443,3386],{"class":716},[686,3445,425],{"class":699},[686,3447,3391],{"class":716},[686,3449,3450],{"class":699},"}:${",[686,3452,3453],{"class":716},"student",[686,3455,425],{"class":699},[686,3457,441],{"class":716},[686,3459,3190],{"class":699},[686,3461,1765],{"class":716},[686,3463,3465,3468,3471,3474],{"class":688,"line":3464},97,[686,3466,3467],{"class":703},"      if",[686,3469,3470],{"class":716}," (state.run.finished[pair]) ",[686,3472,3473],{"class":703},"continue",[686,3475,1765],{"class":716},[686,3477,3479,3482],{"class":688,"line":3478},98,[686,3480,3481],{"class":703},"      try",[686,3483,1976],{"class":716},[686,3485,3487,3490,3492,3494,3497,3499,3502,3505,3507,3510],{"class":688,"line":3486},99,[686,3488,3489],{"class":703},"        for",[686,3491,2365],{"class":716},[686,3493,1846],{"class":703},[686,3495,3496],{"class":695}," kind",[686,3498,3268],{"class":703},[686,3500,3501],{"class":716}," [",[686,3503,3504],{"class":699},"'certificate'",[686,3506,455],{"class":716},[686,3508,3509],{"class":699},"'report'",[686,3511,3512],{"class":716},"]) {\n",[686,3514,3516,3519,3521,3523,3525,3528,3530,3532,3534,3536,3539,3542,3544,3547,3549,3551,3553,3556,3558,3560,3562,3564,3566,3568],{"class":688,"line":3515},100,[686,3517,3518],{"class":703},"          for",[686,3520,2436],{"class":703},[686,3522,2365],{"class":716},[686,3524,1846],{"class":703},[686,3526,3527],{"class":695}," doc",[686,3529,3268],{"class":703},[686,3531,2345],{"class":1881},[686,3533,1885],{"class":716},[686,3535,2103],{"class":699},[686,3537,3538],{"class":716},"kind",[686,3540,3541],{"class":699},"}-list`",[686,3543,455],{"class":716},[686,3545,3546],{"class":699},"`\u002F${",[686,3548,3386],{"class":716},[686,3550,425],{"class":699},[686,3552,441],{"class":716},[686,3554,3555],{"class":699},"}\u002F${",[686,3557,3538],{"class":716},[686,3559,3555],{"class":699},[686,3561,3453],{"class":716},[686,3563,425],{"class":699},[686,3565,441],{"class":716},[686,3567,3190],{"class":699},[686,3569,3570],{"class":716},")) {\n",[686,3572,3574,3577,3580,3582,3584,3586,3588,3590,3592,3594,3596,3599,3601,3603,3605],{"class":688,"line":3573},101,[686,3575,3576],{"class":703},"            const",[686,3578,3579],{"class":695}," key",[686,3581,1852],{"class":703},[686,3583,2828],{"class":699},[686,3585,3386],{"class":716},[686,3587,425],{"class":699},[686,3589,3391],{"class":716},[686,3591,3555],{"class":699},[686,3593,3538],{"class":716},[686,3595,3555],{"class":699},[686,3597,3598],{"class":716},"doc",[686,3600,425],{"class":699},[686,3602,441],{"class":716},[686,3604,3190],{"class":699},[686,3606,1765],{"class":716},[686,3608,3610,3613],{"class":688,"line":3609},102,[686,3611,3612],{"class":703},"            if",[686,3614,3615],{"class":716}," (state.documents[key]) {\n",[686,3617,3619,3622,3624],{"class":688,"line":3618},103,[686,3620,3621],{"class":716},"              counts.known",[686,3623,2383],{"class":703},[686,3625,1765],{"class":716},[686,3627,3629,3632],{"class":688,"line":3628},104,[686,3630,3631],{"class":703},"              continue",[686,3633,1765],{"class":716},[686,3635,3637],{"class":688,"line":3636},105,[686,3638,3639],{"class":716},"            }\n",[686,3641,3643,3646],{"class":688,"line":3642},106,[686,3644,3645],{"class":703},"            try",[686,3647,1976],{"class":716},[686,3649,3651,3654,3657,3659,3661,3663,3665,3668,3670,3672,3675,3677,3679,3681,3684,3686,3688,3690,3692],{"class":688,"line":3650},107,[686,3652,3653],{"class":703},"              const",[686,3655,3656],{"class":695}," target",[686,3658,1852],{"class":703},[686,3660,1882],{"class":1881},[686,3662,1885],{"class":716},[686,3664,1888],{"class":695},[686,3666,3667],{"class":716},", org.slug, student._id, ",[686,3669,2103],{"class":699},[686,3671,3538],{"class":716},[686,3673,3674],{"class":699},"}-${",[686,3676,3598],{"class":716},[686,3678,425],{"class":699},[686,3680,445],{"class":716},[686,3682,3683],{"class":703}," ??",[686,3685,3527],{"class":716},[686,3687,425],{"class":699},[686,3689,441],{"class":716},[686,3691,3190],{"class":699},[686,3693,1896],{"class":716},[686,3695,3697,3699,3702,3704,3706,3709,3712,3714,3716,3718],{"class":688,"line":3696},108,[686,3698,3653],{"class":703},[686,3700,3701],{"class":716}," { ",[686,3703,2831],{"class":695},[686,3705,455],{"class":716},[686,3707,3708],{"class":695},"serverName",[686,3710,3711],{"class":716}," } ",[686,3713,2374],{"class":703},[686,3715,2436],{"class":703},[686,3717,2696],{"class":1881},[686,3719,3720],{"class":716},"(\n",[686,3722,3724,3727,3729,3732],{"class":688,"line":3723},109,[686,3725,3726],{"class":699},"                `${",[686,3728,3538],{"class":716},[686,3730,3731],{"class":699},"}-download`",[686,3733,748],{"class":716},[686,3735,3737,3740,3742,3744,3746,3748,3750,3753,3755,3757,3759,3761],{"class":688,"line":3736},110,[686,3738,3739],{"class":699},"                `\u002F${",[686,3741,3386],{"class":716},[686,3743,425],{"class":699},[686,3745,441],{"class":716},[686,3747,3555],{"class":699},[686,3749,3538],{"class":716},[686,3751,3752],{"class":699},"}\u002Fdownload\u002F${",[686,3754,3598],{"class":716},[686,3756,425],{"class":699},[686,3758,441],{"class":716},[686,3760,3190],{"class":699},[686,3762,748],{"class":716},[686,3764,3766],{"class":688,"line":3765},111,[686,3767,3768],{"class":716},"                target,\n",[686,3770,3772],{"class":688,"line":3771},112,[686,3773,3774],{"class":716},"              );\n",[686,3776,3778,3781,3783,3786,3788,3790,3792,3794],{"class":688,"line":3777},113,[686,3779,3780],{"class":716},"              state.documents[key] ",[686,3782,2374],{"class":703},[686,3784,3785],{"class":716}," { shortId: doc.shortId, file, serverName, at: ",[686,3787,3216],{"class":703},[686,3789,3219],{"class":1881},[686,3791,3222],{"class":716},[686,3793,3225],{"class":1881},[686,3795,3796],{"class":716},"() };\n",[686,3798,3800,3803,3805],{"class":688,"line":3799},114,[686,3801,3802],{"class":703},"              await",[686,3804,2061],{"class":1881},[686,3806,3807],{"class":716},"(state);\n",[686,3809,3811,3814,3816],{"class":688,"line":3810},115,[686,3812,3813],{"class":716},"              counts.downloaded",[686,3815,2383],{"class":703},[686,3817,1765],{"class":716},[686,3819,3821,3824,3826,3828,3831,3834,3837,3839,3841],{"class":688,"line":3820},116,[686,3822,3823],{"class":716},"              console.",[686,3825,3171],{"class":1881},[686,3827,1885],{"class":716},[686,3829,3830],{"class":699},"`  + ${",[686,3832,3833],{"class":716},"key",[686,3835,3836],{"class":699},"} -> ${",[686,3838,2831],{"class":716},[686,3840,3190],{"class":699},[686,3842,1896],{"class":716},[686,3844,3846,3849,3851],{"class":688,"line":3845},117,[686,3847,3848],{"class":716},"            } ",[686,3850,2020],{"class":703},[686,3852,2972],{"class":716},[686,3854,3856,3859,3861,3863],{"class":688,"line":3855},118,[686,3857,3858],{"class":716},"              counts.failed",[686,3860,2383],{"class":703},[686,3862,1911],{"class":716},[686,3864,3865],{"class":1742},"\u002F\u002F not recorded, so the next run tries again\n",[686,3867,3869,3871,3874,3876,3879,3881,3883,3886,3888,3890,3893,3895],{"class":688,"line":3868},119,[686,3870,3823],{"class":716},[686,3872,3873],{"class":1881},"warn",[686,3875,1885],{"class":716},[686,3877,3878],{"class":699},"`  ! ${",[686,3880,3833],{"class":716},[686,3882,3394],{"class":699},[686,3884,3885],{"class":1881},"describe",[686,3887,1885],{"class":699},[686,3889,3034],{"class":716},[686,3891,3892],{"class":699},")",[686,3894,3190],{"class":699},[686,3896,1896],{"class":716},[686,3898,3900],{"class":688,"line":3899},120,[686,3901,3639],{"class":716},[686,3903,3905],{"class":688,"line":3904},121,[686,3906,3907],{"class":716},"          }\n",[686,3909,3911],{"class":688,"line":3910},122,[686,3912,3913],{"class":716},"        }\n",[686,3915,3917,3920,3922],{"class":688,"line":3916},123,[686,3918,3919],{"class":716},"      } ",[686,3921,2020],{"class":703},[686,3923,2972],{"class":716},[686,3925,3927,3930,3933,3935,3937,3940,3943,3946,3949],{"class":688,"line":3926},124,[686,3928,3929],{"class":703},"        if",[686,3931,3932],{"class":716}," (error ",[686,3934,3048],{"class":703},[686,3936,3051],{"class":692},[686,3938,3939],{"class":703}," &&",[686,3941,3942],{"class":716}," error.status ",[686,3944,3945],{"class":703},"===",[686,3947,3948],{"class":695}," 409",[686,3950,2069],{"class":716},[686,3952,3954,3957,3959,3961],{"class":688,"line":3953},125,[686,3955,3956],{"class":716},"          counts.notYet",[686,3958,2383],{"class":703},[686,3960,1911],{"class":716},[686,3962,3963],{"class":1742},"\u002F\u002F never signed in to this organization: nothing to collect yet\n",[686,3965,3967,3970,3972,3975,3977,3979,3981,3983,3985,3987,3990],{"class":688,"line":3966},126,[686,3968,3969],{"class":716},"        } ",[686,3971,3200],{"class":703},[686,3973,3974],{"class":703}," if",[686,3976,3932],{"class":716},[686,3978,3048],{"class":703},[686,3980,3051],{"class":692},[686,3982,3939],{"class":703},[686,3984,3942],{"class":716},[686,3986,3945],{"class":703},[686,3988,3989],{"class":695}," 403",[686,3991,2069],{"class":716},[686,3993,3995,3998,4000,4002,4004,4006,4008,4010,4012,4014,4016,4018,4020,4023],{"class":688,"line":3994},127,[686,3996,3997],{"class":716},"          console.",[686,3999,3873],{"class":1881},[686,4001,1885],{"class":716},[686,4003,3878],{"class":699},[686,4005,3386],{"class":716},[686,4007,425],{"class":699},[686,4009,3391],{"class":716},[686,4011,3394],{"class":699},[686,4013,3885],{"class":1881},[686,4015,1885],{"class":699},[686,4017,3034],{"class":716},[686,4019,3892],{"class":699},[686,4021,4022],{"class":699},"}; skipping this organization`",[686,4024,1896],{"class":716},[686,4026,4028,4031],{"class":688,"line":4027},128,[686,4029,4030],{"class":703},"          break",[686,4032,1765],{"class":716},[686,4034,4036,4038,4040],{"class":688,"line":4035},129,[686,4037,3969],{"class":716},[686,4039,3200],{"class":703},[686,4041,1976],{"class":716},[686,4043,4045,4048,4051],{"class":688,"line":4044},130,[686,4046,4047],{"class":703},"          throw",[686,4049,4050],{"class":716}," error; ",[686,4052,4053],{"class":1742},"\u002F\u002F the next start resumes from the last finished pair\n",[686,4055,4057],{"class":688,"line":4056},131,[686,4058,3913],{"class":716},[686,4060,4062],{"class":688,"line":4061},132,[686,4063,4064],{"class":716},"      }\n",[686,4066,4068,4071,4073,4076],{"class":688,"line":4067},133,[686,4069,4070],{"class":716},"      state.run.finished[pair] ",[686,4072,2374],{"class":703},[686,4074,4075],{"class":695}," true",[686,4077,1765],{"class":716},[686,4079,4081,4084,4086],{"class":688,"line":4080},134,[686,4082,4083],{"class":703},"      await",[686,4085,2061],{"class":1881},[686,4087,3807],{"class":716},[686,4089,4091],{"class":688,"line":4090},135,[686,4092,849],{"class":716},[686,4094,4096],{"class":688,"line":4095},136,[686,4097,1193],{"class":716},[686,4099,4101],{"class":688,"line":4100},137,[686,4102,1841],{"emptyLinePlaceholder":1840},[686,4104,4106,4109,4111,4113],{"class":688,"line":4105},138,[686,4107,4108],{"class":716},"  state.run ",[686,4110,2374],{"class":703},[686,4112,2674],{"class":695},[686,4114,1765],{"class":716},[686,4116,4118,4120,4122],{"class":688,"line":4117},139,[686,4119,2075],{"class":703},[686,4121,2061],{"class":1881},[686,4123,3807],{"class":716},[686,4125,4127,4130,4132],{"class":688,"line":4126},140,[686,4128,4129],{"class":716},"  console.",[686,4131,3171],{"class":1881},[686,4133,3720],{"class":716},[686,4135,4137,4140,4143,4145,4148,4151,4153,4155,4158,4161],{"class":688,"line":4136},141,[686,4138,4139],{"class":699},"    `Done: ${",[686,4141,4142],{"class":716},"counts",[686,4144,425],{"class":699},[686,4146,4147],{"class":716},"downloaded",[686,4149,4150],{"class":699},"} downloaded, ${",[686,4152,4142],{"class":716},[686,4154,425],{"class":699},[686,4156,4157],{"class":716},"known",[686,4159,4160],{"class":699},"} already had, `",[686,4162,4163],{"class":703}," +\n",[686,4165,4167,4170,4172,4174,4177,4180,4182,4184,4187,4190],{"class":688,"line":4166},142,[686,4168,4169],{"class":699},"      `${",[686,4171,4142],{"class":716},[686,4173,425],{"class":699},[686,4175,4176],{"class":716},"notYet",[686,4178,4179],{"class":699},"} pairs without a sign-in, ${",[686,4181,4142],{"class":716},[686,4183,425],{"class":699},[686,4185,4186],{"class":716},"failed",[686,4188,4189],{"class":699},"} failed.`",[686,4191,748],{"class":716},[686,4193,4195],{"class":688,"line":4194},143,[686,4196,4197],{"class":716},"  );\n",[686,4199,4201],{"class":688,"line":4200},144,[686,4202,910],{"class":716},[686,4204,4206],{"class":688,"line":4205},145,[686,4207,1841],{"emptyLinePlaceholder":1840},[686,4209,4211,4214,4216,4218,4220,4222,4224,4226],{"class":688,"line":4210},146,[686,4212,4213],{"class":1881},"main",[686,4215,3222],{"class":716},[686,4217,2020],{"class":1881},[686,4219,2276],{"class":716},[686,4221,3034],{"class":692},[686,4223,2236],{"class":716},[686,4225,2284],{"class":703},[686,4227,1976],{"class":716},[686,4229,4231,4233,4235,4237,4240,4242,4244,4246,4248,4250],{"class":688,"line":4230},147,[686,4232,4129],{"class":716},[686,4234,3034],{"class":1881},[686,4236,1885],{"class":716},[686,4238,4239],{"class":699},"`Stopped: ${",[686,4241,3885],{"class":1881},[686,4243,1885],{"class":699},[686,4245,3034],{"class":716},[686,4247,3892],{"class":699},[686,4249,3190],{"class":699},[686,4251,1896],{"class":716},[686,4253,4255,4258,4260,4262],{"class":688,"line":4254},148,[686,4256,4257],{"class":716},"  process.exitCode ",[686,4259,2374],{"class":703},[686,4261,2377],{"class":695},[686,4263,1765],{"class":716},[686,4265,4267],{"class":688,"line":4266},149,[686,4268,4269],{"class":716},"});\n",[1727,4271,311],{"id":4272},"php",[676,4274,4278],{"className":4275,"code":4276,"filename":4277,"language":4272,"meta":682,"style":682},"language-php shiki shiki-themes github-light-high-contrast github-dark-high-contrast","\u003C?php\n\u002F\u002F collect-results.php: download newly released certificates and reports for all your students.\n\u002F\u002F Usage: php collect-results.php .\u002Fresults\ndeclare(strict_types=1);\nrequire __DIR__ . '\u002Fmainteam.php';\n\nconst MIN_INTERVAL_US = 650000;   \u002F\u002F per operation: about 92 calls a minute, under the 100 allowed\nconst RESUME_WINDOW_S = 20 * 3600;\n\n$outDir = rtrim($argv[1] ?? '.\u002Fresults', '\u002F');\n$stateFile = \"$outDir\u002Fstate.json\";\n$api = MainTeam::fromEnv();\n\n\u002F\u002F ---- checkpoint -------------------------------------------------------------\nfunction loadState(string $file): array\n{\n    $text = @file_get_contents($file);\n    $state = $text === false ? null : json_decode($text, true);\n    return is_array($state) ? $state : ['documents' => [], 'run' => null];\n}\n\nfunction saveState(string $file, array $state): void\n{\n    @mkdir(dirname($file), 0775, true);\n    file_put_contents(\"$file.tmp\", json_encode($state, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));\n    rename(\"$file.tmp\", $file);\n}\n\n\u002F\u002F ---- pacing: one lane per operation ---------------------------------------\nfunction paced(string $route): void\n{\n    static $last = [];\n    $wait = ($last[$route] ?? 0) + MIN_INTERVAL_US - (int) (microtime(true) * 1e6);\n    if ($wait > 0) {\n        usleep($wait);\n    }\n    $last[$route] = (int) (microtime(true) * 1e6);\n}\n\n\u002F\u002F ---- every item of a paginated list -----------------------------------------\nfunction allPages(MainTeam $api, string $route, string $path): Generator\n{\n    for ($page = 1; ; $page++) {\n        paced($route);\n        $separator = str_contains($path, '?') ? '&' : '?';\n        $res = $api->call('GET', \"$path{$separator}page=$page&limit=100\");\n        foreach ($res['data'] as $item) {\n            yield $item;\n        }\n        if ($page >= $res['pagination']['totalPages']) {\n            return;\n        }\n    }\n}\n\n\u002F\u002F ---- downloads ----------------------------------------------------------------\nfunction serverFileName(string $header): ?string\n{\n    if (preg_match(\"\u002Ffilename\\\\*=UTF-8''([^;]+)\u002Fi\", $header, $m)) {\n        return rawurldecode($m[1]);\n    }\n    if (preg_match('\u002Ffilename=\"([^\"]*)\"\u002Fi', $header, $m)) {\n        return $m[1];\n    }\n    return null;\n}\n\n\u002F** Streams one file to $target plus its extension. Returns [path, server name]. *\u002F\nfunction download(MainTeam $api, string $route, string $path, string $target): array\n{\n    @mkdir(dirname($target), 0775, true);\n    $part = \"$target.part\";\n    for ($attempt = 1; ; $attempt++) {\n        paced($route);\n        $headers = [];\n        $fh = fopen($part, 'wb');\n        $ch = curl_init(MainTeam::BASE_URL . $path);\n        curl_setopt_array($ch, [\n            CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $api->token(), 'X-Request-Id: ' . bin2hex(random_bytes(16))],\n            CURLOPT_FILE => $fh,\n            CURLOPT_CONNECTTIMEOUT => 5,\n            CURLOPT_TIMEOUT => 300,\n            CURLOPT_HEADERFUNCTION => function ($ch, string $line) use (&$headers): int {\n                $parts = explode(':', $line, 2);\n                if (count($parts) === 2) {\n                    $headers[strtolower(trim($parts[0]))] = trim($parts[1]);\n                }\n                return strlen($line);\n            },\n        ]);\n        $ok = curl_exec($ch);\n        $status = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);\n        $error = curl_error($ch);\n        curl_close($ch);\n        fclose($fh);\n        clearstatcache(true, $part);\n\n        if ($ok === false) {\n            @unlink($part);\n            throw new RuntimeException(\"Download failed: $error\");\n        }\n        if ($status === 429 && $attempt \u003C= 3) {\n            @unlink($part);\n            sleep(max(1, (int) ($headers['retry-after'] ?? '1')));\n            continue;\n        }\n        if ($status !== 200) {\n            $body = json_decode((string) file_get_contents($part), true);\n            @unlink($part);\n            $err = is_array($body) ? ($body['error'] ?? []) : [];\n            throw new ApiError(\n                $status,\n                $err['code'] ?? 'unknown',\n                $err['message'] ?? \"HTTP $status\",\n                $err['request_id'] ?? ($headers['x-request-id'] ?? null),\n            );\n        }\n        if (isset($headers['content-length']) && filesize($part) !== (int) $headers['content-length']) {\n            @unlink($part);\n            throw new RuntimeException('Truncated download');\n        }\n        $serverName = serverFileName($headers['content-disposition'] ?? '');\n        $extension = pathinfo($serverName ?? '', PATHINFO_EXTENSION);\n        $file = $target . '.' . ($extension !== '' ? $extension : 'pdf');\n        rename($part, $file);\n        return [$file, $serverName];\n    }\n}\n\nfunction describe(Throwable $e): string\n{\n    return $e instanceof ApiError ? \"{$e->status} {$e->errorCode} (request {$e->requestId})\" : $e->getMessage();\n}\n\n\u002F\u002F ---- the run -------------------------------------------------------------------\ntry {\n    $state = loadState($stateFile);\n    if ($state['run'] !== null && time() - strtotime($state['run']['startedAt']) \u003C RESUME_WINDOW_S) {\n        echo \"Resuming the run started at {$state['run']['startedAt']}\\n\";\n    } else {\n        $state['run'] = ['startedAt' => gmdate('c'), 'finished' => []];\n    }\n\n    $students = [];\n    foreach (allPages($api, 'students', '\u002Fstudent') as $student) {\n        $students[] = $student;\n    }\n    $organizations = $api->call('GET', '\u002Forganization?limit=100')['data'];\n    $counts = ['downloaded' => 0, 'known' => 0, 'notYet' => 0, 'failed' => 0];\n\n    foreach ($organizations as $org) {\n        echo \"{$org['slug']}: \" . count($students) . \" students\\n\";\n\n        foreach ($students as $student) {\n            $pair = \"{$org['slug']}:{$student['_id']}\";\n            if (!empty($state['run']['finished'][$pair])) {\n                continue;\n            }\n            try {\n                foreach (['certificate', 'report'] as $kind) {\n                    foreach (allPages($api, \"$kind-list\", \"\u002F{$org['_id']}\u002F$kind\u002F{$student['_id']}\") as $doc) {\n                        $key = \"{$org['slug']}\u002F$kind\u002F{$doc['_id']}\";\n                        if (isset($state['documents'][$key])) {\n                            $counts['known']++;\n                            continue;\n                        }\n                        try {\n                            $label = $doc['shortId'] ?? $doc['_id'];\n                            $target = \"$outDir\u002F{$org['slug']}\u002F{$student['_id']}\u002F$kind-$label\";\n                            [$file, $serverName] = download($api, \"$kind-download\", \"\u002F{$org['_id']}\u002F$kind\u002Fdownload\u002F{$doc['_id']}\", $target);\n                            $state['documents'][$key] = [\n                                'shortId' => $doc['shortId'] ?? null,\n                                'file' => $file,\n                                'serverName' => $serverName,\n                                'at' => gmdate('c'),\n                            ];\n                            saveState($stateFile, $state);\n                            $counts['downloaded']++;\n                            echo \"  + $key -> $file\\n\";\n                        } catch (Throwable $e) {\n                            $counts['failed']++; \u002F\u002F not recorded, so the next run tries again\n                            echo \"  ! $key: \" . describe($e) . \"\\n\";\n                        }\n                    }\n                }\n            } catch (ApiError $e) {\n                if ($e->status === 409) {\n                    $counts['notYet']++; \u002F\u002F never signed in to this organization: nothing to collect yet\n                } elseif ($e->status === 403) {\n                    echo \"  ! {$org['slug']}: \" . describe($e) . \"; skipping this organization\\n\";\n                    break;\n                } else {\n                    throw $e; \u002F\u002F the next start resumes from the last finished pair\n                }\n            }\n            $state['run']['finished'][$pair] = true;\n            saveState($stateFile, $state);\n        }\n    }\n\n    $state['run'] = null;\n    saveState($stateFile, $state);\n    echo \"Done: {$counts['downloaded']} downloaded, {$counts['known']} already had, \"\n        . \"{$counts['notYet']} pairs without a sign-in, {$counts['failed']} failed.\\n\";\n} catch (Throwable $e) {\n    fwrite(STDERR, 'Stopped: ' . describe($e) . \"\\n\");\n    exit(1);\n}\n","collect-results.php",[384,4279,4280,4288,4293,4298,4314,4330,4334,4351,4369,4373,4401,4419,4437,4441,4445,4464,4468,4484,4515,4553,4557,4561,4585,4589,4613,4653,4669,4673,4677,4681,4698,4702,4714,4760,4773,4781,4785,4812,4816,4820,4824,4853,4857,4875,4883,4910,4954,4973,4981,4985,5007,5014,5018,5022,5026,5030,5034,5052,5056,5086,5101,5105,5125,5136,5140,5148,5152,5156,5161,5191,5195,5216,5233,5251,5257,5266,5284,5308,5316,5361,5371,5383,5395,5430,5452,5472,5504,5509,5520,5525,5530,5543,5567,5579,5586,5594,5606,5610,5623,5634,5656,5660,5685,5693,5728,5735,5739,5751,5775,5783,5814,5824,5829,5846,5867,5893,5898,5902,5940,5948,5963,5967,5988,6012,6048,6056,6063,6067,6071,6075,6094,6098,6155,6159,6163,6167,6174,6185,6230,6251,6260,6296,6300,6304,6313,6339,6349,6353,6381,6426,6431,6444,6476,6481,6493,6516,6540,6548,6553,6560,6582,6628,6654,6671,6686,6694,6700,6708,6733,6767,6806,6822,6842,6853,6864,6880,6886,6895,6908,6931,6946,6961,6991,6996,7002,7007,7021,7040,7056,7077,7107,7115,7124,7135,7140,7145,7166,7174,7179,7184,7189,7205,7213,7233,7257,7271,7303,7315],{"__ignoreMap":682},[686,4281,4282,4285],{"class":688,"line":689},[686,4283,4284],{"class":703},"\u003C?",[686,4286,4287],{"class":695},"php\n",[686,4289,4290],{"class":688,"line":707},[686,4291,4292],{"class":1742},"\u002F\u002F collect-results.php: download newly released certificates and reports for all your students.\n",[686,4294,4295],{"class":688,"line":751},[686,4296,4297],{"class":1742},"\u002F\u002F Usage: php collect-results.php .\u002Fresults\n",[686,4299,4300,4303,4305,4308,4310,4312],{"class":688,"line":764},[686,4301,4302],{"class":703},"declare",[686,4304,1885],{"class":716},[686,4306,4307],{"class":695},"strict_types",[686,4309,2374],{"class":703},[686,4311,545],{"class":695},[686,4313,1896],{"class":716},[686,4315,4316,4319,4322,4325,4328],{"class":688,"line":773},[686,4317,4318],{"class":703},"require",[686,4320,4321],{"class":695}," __DIR__",[686,4323,4324],{"class":703}," .",[686,4326,4327],{"class":699}," '\u002Fmainteam.php'",[686,4329,1765],{"class":716},[686,4331,4332],{"class":688,"line":779},[686,4333,1841],{"emptyLinePlaceholder":1840},[686,4335,4336,4338,4341,4343,4346,4349],{"class":688,"line":792},[686,4337,1846],{"class":703},[686,4339,4340],{"class":695}," MIN_INTERVAL_US",[686,4342,1852],{"class":703},[686,4344,4345],{"class":695}," 650000",[686,4347,4348],{"class":716},";   ",[686,4350,1914],{"class":1742},[686,4352,4353,4355,4358,4360,4362,4364,4367],{"class":688,"line":805},[686,4354,1846],{"class":703},[686,4356,4357],{"class":695}," RESUME_WINDOW_S",[686,4359,1852],{"class":703},[686,4361,1926],{"class":695},[686,4363,1929],{"class":703},[686,4365,4366],{"class":695}," 3600",[686,4368,1765],{"class":716},[686,4370,4371],{"class":688,"line":818},[686,4372,1841],{"emptyLinePlaceholder":1840},[686,4374,4375,4378,4380,4383,4386,4388,4390,4392,4394,4396,4399],{"class":688,"line":831},[686,4376,4377],{"class":716},"$outDir ",[686,4379,2374],{"class":703},[686,4381,4382],{"class":695}," rtrim",[686,4384,4385],{"class":716},"($argv[",[686,4387,545],{"class":695},[686,4389,1861],{"class":716},[686,4391,1864],{"class":703},[686,4393,1867],{"class":699},[686,4395,455],{"class":716},[686,4397,4398],{"class":699},"'\u002F'",[686,4400,1896],{"class":716},[686,4402,4403,4406,4408,4411,4414,4417],{"class":688,"line":846},[686,4404,4405],{"class":716},"$stateFile ",[686,4407,2374],{"class":703},[686,4409,4410],{"class":699}," \"",[686,4412,4413],{"class":716},"$outDir",[686,4415,4416],{"class":699},"\u002Fstate.json\"",[686,4418,1765],{"class":716},[686,4420,4421,4424,4426,4429,4432,4435],{"class":688,"line":852},[686,4422,4423],{"class":716},"$api ",[686,4425,2374],{"class":703},[686,4427,4428],{"class":695}," MainTeam",[686,4430,4431],{"class":703},"::",[686,4433,4434],{"class":1881},"fromEnv",[686,4436,2186],{"class":716},[686,4438,4439],{"class":688,"line":858},[686,4440,1841],{"emptyLinePlaceholder":1840},[686,4442,4443],{"class":688,"line":907},[686,4444,1952],{"class":1742},[686,4446,4447,4449,4451,4453,4456,4459,4461],{"class":688,"line":1110},[686,4448,2529],{"class":703},[686,4450,1964],{"class":1881},[686,4452,1885],{"class":716},[686,4454,4455],{"class":703},"string",[686,4457,4458],{"class":716}," $file)",[686,4460,1486],{"class":703},[686,4462,4463],{"class":703}," array\n",[686,4465,4466],{"class":688,"line":1955},[686,4467,733],{"class":716},[686,4469,4470,4473,4475,4478,4481],{"class":688,"line":1970},[686,4471,4472],{"class":716},"    $text ",[686,4474,2374],{"class":703},[686,4476,4477],{"class":703}," @",[686,4479,4480],{"class":695},"file_get_contents",[686,4482,4483],{"class":716},"($file);\n",[686,4485,4486,4489,4491,4494,4496,4499,4501,4503,4505,4508,4511,4513],{"class":688,"line":1979},[686,4487,4488],{"class":716},"    $state ",[686,4490,2374],{"class":703},[686,4492,4493],{"class":716}," $text ",[686,4495,3945],{"class":703},[686,4497,4498],{"class":695}," false",[686,4500,3054],{"class":703},[686,4502,2674],{"class":695},[686,4504,2418],{"class":703},[686,4506,4507],{"class":695}," json_decode",[686,4509,4510],{"class":716},"($text, ",[686,4512,745],{"class":695},[686,4514,1896],{"class":716},[686,4516,4517,4519,4522,4525,4527,4530,4532,4534,4537,4540,4543,4546,4548,4550],{"class":688,"line":2014},[686,4518,1982],{"class":703},[686,4520,4521],{"class":695}," is_array",[686,4523,4524],{"class":716},"($state) ",[686,4526,2412],{"class":703},[686,4528,4529],{"class":716}," $state ",[686,4531,1486],{"class":703},[686,4533,3501],{"class":716},[686,4535,4536],{"class":699},"'documents'",[686,4538,4539],{"class":703}," =>",[686,4541,4542],{"class":716}," [], ",[686,4544,4545],{"class":699},"'run'",[686,4547,4539],{"class":703},[686,4549,2674],{"class":695},[686,4551,4552],{"class":716},"];\n",[686,4554,4555],{"class":688,"line":2025},[686,4556,910],{"class":716},[686,4558,4559],{"class":688,"line":2039},[686,4560,1841],{"emptyLinePlaceholder":1840},[686,4562,4563,4565,4567,4569,4571,4574,4577,4580,4582],{"class":688,"line":2044},[686,4564,2529],{"class":703},[686,4566,2061],{"class":1881},[686,4568,1885],{"class":716},[686,4570,4455],{"class":703},[686,4572,4573],{"class":716}," $file, ",[686,4575,4576],{"class":703},"array",[686,4578,4579],{"class":716}," $state)",[686,4581,1486],{"class":703},[686,4583,4584],{"class":703}," void\n",[686,4586,4587],{"class":688,"line":2049},[686,4588,733],{"class":716},[686,4590,4591,4594,4597,4599,4601,4604,4607,4609,4611],{"class":688,"line":2054},[686,4592,4593],{"class":703},"    @",[686,4595,4596],{"class":695},"mkdir",[686,4598,1885],{"class":716},[686,4600,2848],{"class":695},[686,4602,4603],{"class":716},"($file), ",[686,4605,4606],{"class":695},"0775",[686,4608,455],{"class":716},[686,4610,745],{"class":695},[686,4612,1896],{"class":716},[686,4614,4615,4618,4620,4623,4626,4629,4631,4634,4637,4640,4643,4646,4648,4651],{"class":688,"line":2072},[686,4616,4617],{"class":695},"    file_put_contents",[686,4619,1885],{"class":716},[686,4621,4622],{"class":699},"\"",[686,4624,4625],{"class":716},"$file",[686,4627,4628],{"class":699},".tmp\"",[686,4630,455],{"class":716},[686,4632,4633],{"class":695},"json_encode",[686,4635,4636],{"class":716},"($state, ",[686,4638,4639],{"class":695},"JSON_PRETTY_PRINT",[686,4641,4642],{"class":703}," |",[686,4644,4645],{"class":695}," JSON_UNESCAPED_SLASHES",[686,4647,4642],{"class":703},[686,4649,4650],{"class":695}," JSON_UNESCAPED_UNICODE",[686,4652,2011],{"class":716},[686,4654,4655,4658,4660,4662,4664,4666],{"class":688,"line":2093},[686,4656,4657],{"class":695},"    rename",[686,4659,1885],{"class":716},[686,4661,4622],{"class":699},[686,4663,4625],{"class":716},[686,4665,4628],{"class":699},[686,4667,4668],{"class":716},", $file);\n",[686,4670,4671],{"class":688,"line":2132},[686,4672,910],{"class":716},[686,4674,4675],{"class":688,"line":2154},[686,4676,1841],{"emptyLinePlaceholder":1840},[686,4678,4679],{"class":688,"line":2159},[686,4680,2167],{"class":1742},[686,4682,4683,4685,4687,4689,4691,4694,4696],{"class":688,"line":2164},[686,4684,2529],{"class":703},[686,4686,2196],{"class":1881},[686,4688,1885],{"class":716},[686,4690,4455],{"class":703},[686,4692,4693],{"class":716}," $route)",[686,4695,1486],{"class":703},[686,4697,4584],{"class":703},[686,4699,4700],{"class":688,"line":2170},[686,4701,733],{"class":716},[686,4703,4704,4707,4710,4712],{"class":688,"line":2189},[686,4705,4706],{"class":703},"    static",[686,4708,4709],{"class":716}," $last ",[686,4711,2374],{"class":703},[686,4713,3251],{"class":716},[686,4715,4716,4719,4721,4724,4726,4728,4730,4732,4734,4736,4738,4741,4744,4747,4749,4751,4753,4755,4758],{"class":688,"line":2211},[686,4717,4718],{"class":716},"    $wait ",[686,4720,2374],{"class":703},[686,4722,4723],{"class":716}," ($last[$route] ",[686,4725,1864],{"class":703},[686,4727,2233],{"class":695},[686,4729,2236],{"class":716},[686,4731,2239],{"class":703},[686,4733,4340],{"class":695},[686,4735,1413],{"class":703},[686,4737,2365],{"class":716},[686,4739,4740],{"class":703},"int",[686,4742,4743],{"class":716},") (",[686,4745,4746],{"class":695},"microtime",[686,4748,1885],{"class":716},[686,4750,745],{"class":695},[686,4752,2236],{"class":716},[686,4754,2635],{"class":703},[686,4756,4757],{"class":695}," 1e6",[686,4759,1896],{"class":716},[686,4761,4762,4764,4767,4769,4771],{"class":688,"line":2254},[686,4763,2488],{"class":703},[686,4765,4766],{"class":716}," ($wait ",[686,4768,1438],{"class":703},[686,4770,2233],{"class":695},[686,4772,2069],{"class":716},[686,4774,4775,4778],{"class":688,"line":2293},[686,4776,4777],{"class":695},"        usleep",[686,4779,4780],{"class":716},"($wait);\n",[686,4782,4783],{"class":688,"line":2310},[686,4784,849],{"class":716},[686,4786,4787,4790,4792,4794,4796,4798,4800,4802,4804,4806,4808,4810],{"class":688,"line":2321},[686,4788,4789],{"class":716},"    $last[$route] ",[686,4791,2374],{"class":703},[686,4793,2365],{"class":716},[686,4795,4740],{"class":703},[686,4797,4743],{"class":716},[686,4799,4746],{"class":695},[686,4801,1885],{"class":716},[686,4803,745],{"class":695},[686,4805,2236],{"class":716},[686,4807,2635],{"class":703},[686,4809,4757],{"class":695},[686,4811,1896],{"class":716},[686,4813,4814],{"class":688,"line":2326},[686,4815,910],{"class":716},[686,4817,4818],{"class":688,"line":2331},[686,4819,1841],{"emptyLinePlaceholder":1840},[686,4821,4822],{"class":688,"line":2337},[686,4823,2334],{"class":1742},[686,4825,4826,4828,4830,4832,4835,4838,4840,4843,4845,4848,4850],{"class":688,"line":2359},[686,4827,2529],{"class":703},[686,4829,2345],{"class":1881},[686,4831,1885],{"class":716},[686,4833,4834],{"class":695},"MainTeam",[686,4836,4837],{"class":716}," $api, ",[686,4839,4455],{"class":703},[686,4841,4842],{"class":716}," $route, ",[686,4844,4455],{"class":703},[686,4846,4847],{"class":716}," $path)",[686,4849,1486],{"class":703},[686,4851,4852],{"class":695}," Generator\n",[686,4854,4855],{"class":688,"line":2388},[686,4856,733],{"class":716},[686,4858,4859,4861,4864,4866,4868,4871,4873],{"class":688,"line":2426},[686,4860,3417],{"class":703},[686,4862,4863],{"class":716}," ($page ",[686,4865,2374],{"class":703},[686,4867,2377],{"class":695},[686,4869,4870],{"class":716},"; ; $page",[686,4872,2383],{"class":703},[686,4874,2069],{"class":716},[686,4876,4877,4880],{"class":688,"line":2476},[686,4878,4879],{"class":1881},"        paced",[686,4881,4882],{"class":716},"($route);\n",[686,4884,4885,4888,4890,4893,4896,4898,4900,4902,4904,4906,4908],{"class":688,"line":2485},[686,4886,4887],{"class":716},"        $separator ",[686,4889,2374],{"class":703},[686,4891,4892],{"class":695}," str_contains",[686,4894,4895],{"class":716},"($path, ",[686,4897,2407],{"class":699},[686,4899,2236],{"class":716},[686,4901,2412],{"class":703},[686,4903,2415],{"class":699},[686,4905,2418],{"class":703},[686,4907,2421],{"class":699},[686,4909,1765],{"class":716},[686,4911,4912,4915,4917,4920,4923,4926,4928,4930,4932,4934,4937,4940,4943,4946,4949,4952],{"class":688,"line":2505},[686,4913,4914],{"class":716},"        $res ",[686,4916,2374],{"class":703},[686,4918,4919],{"class":716}," $api",[686,4921,4922],{"class":703},"->",[686,4924,4925],{"class":1881},"call",[686,4927,1885],{"class":716},[686,4929,2451],{"class":699},[686,4931,455],{"class":716},[686,4933,4622],{"class":699},[686,4935,4936],{"class":716},"$path",[686,4938,4939],{"class":699},"{",[686,4941,4942],{"class":716},"$separator",[686,4944,4945],{"class":699},"}page=",[686,4947,4948],{"class":716},"$page",[686,4950,4951],{"class":699},"&limit=100\"",[686,4953,1896],{"class":716},[686,4955,4956,4959,4962,4965,4967,4970],{"class":688,"line":2510},[686,4957,4958],{"class":703},"        foreach",[686,4960,4961],{"class":716}," ($res[",[686,4963,4964],{"class":699},"'data'",[686,4966,1861],{"class":716},[686,4968,4969],{"class":703},"as",[686,4971,4972],{"class":716}," $item) {\n",[686,4974,4975,4978],{"class":688,"line":2515},[686,4976,4977],{"class":703},"            yield",[686,4979,4980],{"class":716}," $item;\n",[686,4982,4983],{"class":688,"line":2520},[686,4984,3913],{"class":716},[686,4986,4987,4989,4991,4993,4996,4999,5002,5005],{"class":688,"line":2526},[686,4988,3929],{"class":703},[686,4990,4863],{"class":716},[686,4992,2494],{"class":703},[686,4994,4995],{"class":716}," $res[",[686,4997,4998],{"class":699},"'pagination'",[686,5000,5001],{"class":716},"][",[686,5003,5004],{"class":699},"'totalPages'",[686,5006,3512],{"class":716},[686,5008,5009,5012],{"class":688,"line":2542},[686,5010,5011],{"class":703},"            return",[686,5013,1765],{"class":716},[686,5015,5016],{"class":688,"line":2594},[686,5017,3913],{"class":716},[686,5019,5020],{"class":688,"line":2615},[686,5021,849],{"class":716},[686,5023,5024],{"class":688,"line":2655},[686,5025,910],{"class":716},[686,5027,5028],{"class":688,"line":2679},[686,5029,1841],{"emptyLinePlaceholder":1840},[686,5031,5032],{"class":688,"line":2684},[686,5033,2523],{"class":1742},[686,5035,5036,5038,5040,5042,5044,5047,5049],{"class":688,"line":2689},[686,5037,2529],{"class":703},[686,5039,2532],{"class":1881},[686,5041,1885],{"class":716},[686,5043,4455],{"class":703},[686,5045,5046],{"class":716}," $header)",[686,5048,1486],{"class":703},[686,5050,5051],{"class":703}," ?string\n",[686,5053,5054],{"class":688,"line":2714},[686,5055,733],{"class":716},[686,5057,5058,5060,5062,5065,5067,5070,5073,5075,5078,5080,5083],{"class":688,"line":2757},[686,5059,2488],{"class":703},[686,5061,2365],{"class":716},[686,5063,5064],{"class":695},"preg_match",[686,5066,1885],{"class":716},[686,5068,5069],{"class":699},"\"\u002Ffilename",[686,5071,5072],{"class":2555},"\\\\",[686,5074,2635],{"class":703},[686,5076,5077],{"class":699},"=UTF-8''([^;]",[686,5079,2239],{"class":703},[686,5081,5082],{"class":699},")\u002Fi\"",[686,5084,5085],{"class":716},", $header, $m)) {\n",[686,5087,5088,5091,5094,5097,5099],{"class":688,"line":2781},[686,5089,5090],{"class":703},"        return",[686,5092,5093],{"class":695}," rawurldecode",[686,5095,5096],{"class":716},"($m[",[686,5098,545],{"class":695},[686,5100,2612],{"class":716},[686,5102,5103],{"class":688,"line":2818},[686,5104,849],{"class":716},[686,5106,5107,5109,5111,5113,5115,5118,5120,5123],{"class":688,"line":2839},[686,5108,2488],{"class":703},[686,5110,2365],{"class":716},[686,5112,5064],{"class":695},[686,5114,1885],{"class":716},[686,5116,5117],{"class":699},"'\u002Ffilename=\"([^\"]",[686,5119,2635],{"class":703},[686,5121,5122],{"class":699},")\"\u002Fi'",[686,5124,5085],{"class":716},[686,5126,5127,5129,5132,5134],{"class":688,"line":2858},[686,5128,5090],{"class":703},[686,5130,5131],{"class":716}," $m[",[686,5133,545],{"class":695},[686,5135,4552],{"class":716},[686,5137,5138],{"class":688,"line":2865},[686,5139,849],{"class":716},[686,5141,5142,5144,5146],{"class":688,"line":2889},[686,5143,1982],{"class":703},[686,5145,2674],{"class":695},[686,5147,1765],{"class":716},[686,5149,5150],{"class":688,"line":2913},[686,5151,910],{"class":716},[686,5153,5154],{"class":688,"line":2955},[686,5155,1841],{"emptyLinePlaceholder":1840},[686,5157,5158],{"class":688,"line":2965},[686,5159,5160],{"class":1742},"\u002F** Streams one file to $target plus its extension. Returns [path, server name]. *\u002F\n",[686,5162,5163,5165,5167,5169,5171,5173,5175,5177,5179,5182,5184,5187,5189],{"class":688,"line":2975},[686,5164,2529],{"class":703},[686,5166,2696],{"class":1881},[686,5168,1885],{"class":716},[686,5170,4834],{"class":695},[686,5172,4837],{"class":716},[686,5174,4455],{"class":703},[686,5176,4842],{"class":716},[686,5178,4455],{"class":703},[686,5180,5181],{"class":716}," $path, ",[686,5183,4455],{"class":703},[686,5185,5186],{"class":716}," $target)",[686,5188,1486],{"class":703},[686,5190,4463],{"class":703},[686,5192,5193],{"class":688,"line":2990},[686,5194,733],{"class":716},[686,5196,5197,5199,5201,5203,5205,5208,5210,5212,5214],{"class":688,"line":2999},[686,5198,4593],{"class":703},[686,5200,4596],{"class":695},[686,5202,1885],{"class":716},[686,5204,2848],{"class":695},[686,5206,5207],{"class":716},"($target), ",[686,5209,4606],{"class":695},[686,5211,455],{"class":716},[686,5213,745],{"class":695},[686,5215,1896],{"class":716},[686,5217,5218,5221,5223,5225,5228,5231],{"class":688,"line":3004},[686,5219,5220],{"class":716},"    $part ",[686,5222,2374],{"class":703},[686,5224,4410],{"class":699},[686,5226,5227],{"class":716},"$target",[686,5229,5230],{"class":699},".part\"",[686,5232,1765],{"class":716},[686,5234,5235,5237,5240,5242,5244,5247,5249],{"class":688,"line":3012},[686,5236,3417],{"class":703},[686,5238,5239],{"class":716}," ($attempt ",[686,5241,2374],{"class":703},[686,5243,2377],{"class":695},[686,5245,5246],{"class":716},"; ; $attempt",[686,5248,2383],{"class":703},[686,5250,2069],{"class":716},[686,5252,5253,5255],{"class":688,"line":3017},[686,5254,4879],{"class":1881},[686,5256,4882],{"class":716},[686,5258,5259,5262,5264],{"class":688,"line":3022},[686,5260,5261],{"class":716},"        $headers ",[686,5263,2374],{"class":703},[686,5265,3251],{"class":716},[686,5267,5268,5271,5273,5276,5279,5282],{"class":688,"line":3042},[686,5269,5270],{"class":716},"        $fh ",[686,5272,2374],{"class":703},[686,5274,5275],{"class":695}," fopen",[686,5277,5278],{"class":716},"($part, ",[686,5280,5281],{"class":699},"'wb'",[686,5283,1896],{"class":716},[686,5285,5286,5289,5291,5294,5296,5298,5300,5303,5305],{"class":688,"line":3093},[686,5287,5288],{"class":716},"        $ch ",[686,5290,2374],{"class":703},[686,5292,5293],{"class":695}," curl_init",[686,5295,1885],{"class":716},[686,5297,4834],{"class":695},[686,5299,4431],{"class":703},[686,5301,5302],{"class":695},"BASE_URL",[686,5304,4324],{"class":703},[686,5306,5307],{"class":716}," $path);\n",[686,5309,5310,5313],{"class":688,"line":3098},[686,5311,5312],{"class":695},"        curl_setopt_array",[686,5314,5315],{"class":716},"($ch, [\n",[686,5317,5318,5321,5323,5325,5328,5330,5332,5334,5337,5340,5343,5345,5348,5350,5353,5355,5358],{"class":688,"line":3104},[686,5319,5320],{"class":695},"            CURLOPT_HTTPHEADER",[686,5322,4539],{"class":703},[686,5324,3501],{"class":716},[686,5326,5327],{"class":699},"'Authorization: Bearer '",[686,5329,4324],{"class":703},[686,5331,4919],{"class":716},[686,5333,4922],{"class":703},[686,5335,5336],{"class":1881},"token",[686,5338,5339],{"class":716},"(), ",[686,5341,5342],{"class":699},"'X-Request-Id: '",[686,5344,4324],{"class":703},[686,5346,5347],{"class":695}," bin2hex",[686,5349,1885],{"class":716},[686,5351,5352],{"class":1881},"random_bytes",[686,5354,1885],{"class":716},[686,5356,5357],{"class":695},"16",[686,5359,5360],{"class":716},"))],\n",[686,5362,5363,5366,5368],{"class":688,"line":3116},[686,5364,5365],{"class":695},"            CURLOPT_FILE",[686,5367,4539],{"class":703},[686,5369,5370],{"class":716}," $fh,\n",[686,5372,5373,5376,5378,5381],{"class":688,"line":3132},[686,5374,5375],{"class":695},"            CURLOPT_CONNECTTIMEOUT",[686,5377,4539],{"class":703},[686,5379,5380],{"class":695}," 5",[686,5382,748],{"class":716},[686,5384,5385,5388,5390,5393],{"class":688,"line":3165},[686,5386,5387],{"class":695},"            CURLOPT_TIMEOUT",[686,5389,4539],{"class":703},[686,5391,5392],{"class":695}," 300",[686,5394,748],{"class":716},[686,5396,5397,5400,5402,5404,5407,5409,5412,5415,5417,5420,5423,5425,5428],{"class":688,"line":3195},[686,5398,5399],{"class":695},"            CURLOPT_HEADERFUNCTION",[686,5401,4539],{"class":703},[686,5403,1961],{"class":703},[686,5405,5406],{"class":716}," ($ch, ",[686,5408,4455],{"class":703},[686,5410,5411],{"class":716}," $line) ",[686,5413,5414],{"class":703},"use",[686,5416,2365],{"class":716},[686,5418,5419],{"class":703},"&",[686,5421,5422],{"class":716},"$headers)",[686,5424,1486],{"class":703},[686,5426,5427],{"class":703}," int",[686,5429,1976],{"class":716},[686,5431,5432,5435,5437,5440,5442,5445,5448,5450],{"class":688,"line":3205},[686,5433,5434],{"class":716},"                $parts ",[686,5436,2374],{"class":703},[686,5438,5439],{"class":695}," explode",[686,5441,1885],{"class":716},[686,5443,5444],{"class":699},"':'",[686,5446,5447],{"class":716},", $line, ",[686,5449,1858],{"class":695},[686,5451,1896],{"class":716},[686,5453,5454,5457,5459,5462,5465,5467,5470],{"class":688,"line":3231},[686,5455,5456],{"class":703},"                if",[686,5458,2365],{"class":716},[686,5460,5461],{"class":695},"count",[686,5463,5464],{"class":716},"($parts) ",[686,5466,3945],{"class":703},[686,5468,5469],{"class":695}," 2",[686,5471,2069],{"class":716},[686,5473,5474,5477,5480,5482,5485,5488,5490,5493,5495,5498,5500,5502],{"class":688,"line":3236},[686,5475,5476],{"class":716},"                    $headers[",[686,5478,5479],{"class":695},"strtolower",[686,5481,1885],{"class":716},[686,5483,5484],{"class":695},"trim",[686,5486,5487],{"class":716},"($parts[",[686,5489,3333],{"class":695},[686,5491,5492],{"class":716},"]))] ",[686,5494,2374],{"class":703},[686,5496,5497],{"class":695}," trim",[686,5499,5487],{"class":716},[686,5501,545],{"class":695},[686,5503,2612],{"class":716},[686,5505,5506],{"class":688,"line":3241},[686,5507,5508],{"class":716},"                }\n",[686,5510,5511,5514,5517],{"class":688,"line":3254},[686,5512,5513],{"class":703},"                return",[686,5515,5516],{"class":695}," strlen",[686,5518,5519],{"class":716},"($line);\n",[686,5521,5522],{"class":688,"line":3292},[686,5523,5524],{"class":716},"            },\n",[686,5526,5527],{"class":688,"line":3320},[686,5528,5529],{"class":716},"        ]);\n",[686,5531,5532,5535,5537,5540],{"class":688,"line":3353},[686,5533,5534],{"class":716},"        $ok ",[686,5536,2374],{"class":703},[686,5538,5539],{"class":695}," curl_exec",[686,5541,5542],{"class":716},"($ch);\n",[686,5544,5545,5548,5550,5552,5554,5556,5559,5562,5565],{"class":688,"line":3358},[686,5546,5547],{"class":716},"        $status ",[686,5549,2374],{"class":703},[686,5551,2365],{"class":716},[686,5553,4740],{"class":703},[686,5555,2236],{"class":716},[686,5557,5558],{"class":695},"curl_getinfo",[686,5560,5561],{"class":716},"($ch, ",[686,5563,5564],{"class":695},"CURLINFO_RESPONSE_CODE",[686,5566,1896],{"class":716},[686,5568,5569,5572,5574,5577],{"class":688,"line":3375},[686,5570,5571],{"class":716},"        $error ",[686,5573,2374],{"class":703},[686,5575,5576],{"class":695}," curl_error",[686,5578,5542],{"class":716},[686,5580,5581,5584],{"class":688,"line":3409},[686,5582,5583],{"class":695},"        curl_close",[686,5585,5542],{"class":716},[686,5587,5588,5591],{"class":688,"line":3414},[686,5589,5590],{"class":695},"        fclose",[686,5592,5593],{"class":716},"($fh);\n",[686,5595,5596,5599,5601,5603],{"class":688,"line":3431},[686,5597,5598],{"class":695},"        clearstatcache",[686,5600,1885],{"class":716},[686,5602,745],{"class":695},[686,5604,5605],{"class":716},", $part);\n",[686,5607,5608],{"class":688,"line":3464},[686,5609,1841],{"emptyLinePlaceholder":1840},[686,5611,5612,5614,5617,5619,5621],{"class":688,"line":3478},[686,5613,3929],{"class":703},[686,5615,5616],{"class":716}," ($ok ",[686,5618,3945],{"class":703},[686,5620,4498],{"class":695},[686,5622,2069],{"class":716},[686,5624,5625,5628,5631],{"class":688,"line":3486},[686,5626,5627],{"class":703},"            @",[686,5629,5630],{"class":695},"unlink",[686,5632,5633],{"class":716},"($part);\n",[686,5635,5636,5639,5641,5644,5646,5649,5652,5654],{"class":688,"line":3515},[686,5637,5638],{"class":703},"            throw",[686,5640,2180],{"class":703},[686,5642,5643],{"class":695}," RuntimeException",[686,5645,1885],{"class":716},[686,5647,5648],{"class":699},"\"Download failed: ",[686,5650,5651],{"class":716},"$error",[686,5653,4622],{"class":699},[686,5655,1896],{"class":716},[686,5657,5658],{"class":688,"line":3573},[686,5659,3913],{"class":716},[686,5661,5662,5664,5667,5669,5672,5674,5677,5680,5683],{"class":688,"line":3609},[686,5663,3929],{"class":703},[686,5665,5666],{"class":716}," ($status ",[686,5668,3945],{"class":703},[686,5670,5671],{"class":695}," 429",[686,5673,3939],{"class":703},[686,5675,5676],{"class":716}," $attempt ",[686,5678,5679],{"class":703},"\u003C=",[686,5681,5682],{"class":695}," 3",[686,5684,2069],{"class":716},[686,5686,5687,5689,5691],{"class":688,"line":3618},[686,5688,5627],{"class":703},[686,5690,5630],{"class":695},[686,5692,5633],{"class":716},[686,5694,5695,5698,5700,5703,5705,5707,5710,5712,5715,5718,5720,5722,5725],{"class":688,"line":3628},[686,5696,5697],{"class":695},"            sleep",[686,5699,1885],{"class":716},[686,5701,5702],{"class":695},"max",[686,5704,1885],{"class":716},[686,5706,545],{"class":695},[686,5708,5709],{"class":716},", (",[686,5711,4740],{"class":703},[686,5713,5714],{"class":716},") ($headers[",[686,5716,5717],{"class":699},"'retry-after'",[686,5719,1861],{"class":716},[686,5721,1864],{"class":703},[686,5723,5724],{"class":699}," '1'",[686,5726,5727],{"class":716},")));\n",[686,5729,5730,5733],{"class":688,"line":3636},[686,5731,5732],{"class":703},"            continue",[686,5734,1765],{"class":716},[686,5736,5737],{"class":688,"line":3642},[686,5738,3913],{"class":716},[686,5740,5741,5743,5745,5747,5749],{"class":688,"line":3650},[686,5742,3929],{"class":703},[686,5744,5666],{"class":716},[686,5746,2934],{"class":703},[686,5748,1475],{"class":695},[686,5750,2069],{"class":716},[686,5752,5753,5756,5758,5760,5762,5764,5766,5768,5771,5773],{"class":688,"line":3696},[686,5754,5755],{"class":716},"            $body ",[686,5757,2374],{"class":703},[686,5759,4507],{"class":695},[686,5761,2276],{"class":716},[686,5763,4455],{"class":703},[686,5765,2236],{"class":716},[686,5767,4480],{"class":695},[686,5769,5770],{"class":716},"($part), ",[686,5772,745],{"class":695},[686,5774,1896],{"class":716},[686,5776,5777,5779,5781],{"class":688,"line":3723},[686,5778,5627],{"class":703},[686,5780,5630],{"class":695},[686,5782,5633],{"class":716},[686,5784,5785,5788,5790,5792,5795,5797,5800,5803,5805,5807,5810,5812],{"class":688,"line":3736},[686,5786,5787],{"class":716},"            $err ",[686,5789,2374],{"class":703},[686,5791,4521],{"class":695},[686,5793,5794],{"class":716},"($body) ",[686,5796,2412],{"class":703},[686,5798,5799],{"class":716}," ($body[",[686,5801,5802],{"class":699},"'error'",[686,5804,1861],{"class":716},[686,5806,1864],{"class":703},[686,5808,5809],{"class":716}," []) ",[686,5811,1486],{"class":703},[686,5813,3251],{"class":716},[686,5815,5816,5818,5820,5822],{"class":688,"line":3765},[686,5817,5638],{"class":703},[686,5819,2180],{"class":703},[686,5821,3051],{"class":695},[686,5823,3720],{"class":716},[686,5825,5826],{"class":688,"line":3771},[686,5827,5828],{"class":716},"                $status,\n",[686,5830,5831,5834,5837,5839,5841,5844],{"class":688,"line":3777},[686,5832,5833],{"class":716},"                $err[",[686,5835,5836],{"class":699},"'code'",[686,5838,1861],{"class":716},[686,5840,1864],{"class":703},[686,5842,5843],{"class":699}," 'unknown'",[686,5845,748],{"class":716},[686,5847,5848,5850,5853,5855,5857,5860,5863,5865],{"class":688,"line":3799},[686,5849,5833],{"class":716},[686,5851,5852],{"class":699},"'message'",[686,5854,1861],{"class":716},[686,5856,1864],{"class":703},[686,5858,5859],{"class":699}," \"HTTP ",[686,5861,5862],{"class":716},"$status",[686,5864,4622],{"class":699},[686,5866,748],{"class":716},[686,5868,5869,5871,5874,5876,5878,5881,5884,5886,5888,5890],{"class":688,"line":3810},[686,5870,5833],{"class":716},[686,5872,5873],{"class":699},"'request_id'",[686,5875,1861],{"class":716},[686,5877,1864],{"class":703},[686,5879,5880],{"class":716}," ($headers[",[686,5882,5883],{"class":699},"'x-request-id'",[686,5885,1861],{"class":716},[686,5887,1864],{"class":703},[686,5889,2674],{"class":695},[686,5891,5892],{"class":716},"),\n",[686,5894,5895],{"class":688,"line":3820},[686,5896,5897],{"class":716},"            );\n",[686,5899,5900],{"class":688,"line":3845},[686,5901,3913],{"class":716},[686,5903,5904,5906,5908,5911,5914,5916,5919,5921,5924,5927,5929,5931,5933,5936,5938],{"class":688,"line":3855},[686,5905,3929],{"class":703},[686,5907,2365],{"class":716},[686,5909,5910],{"class":695},"isset",[686,5912,5913],{"class":716},"($headers[",[686,5915,2908],{"class":699},[686,5917,5918],{"class":716},"]) ",[686,5920,2921],{"class":703},[686,5922,5923],{"class":695}," filesize",[686,5925,5926],{"class":716},"($part) ",[686,5928,2934],{"class":703},[686,5930,2365],{"class":716},[686,5932,4740],{"class":703},[686,5934,5935],{"class":716},") $headers[",[686,5937,2908],{"class":699},[686,5939,3512],{"class":716},[686,5941,5942,5944,5946],{"class":688,"line":3868},[686,5943,5627],{"class":703},[686,5945,5630],{"class":695},[686,5947,5633],{"class":716},[686,5949,5950,5952,5954,5956,5958,5961],{"class":688,"line":3899},[686,5951,5638],{"class":703},[686,5953,2180],{"class":703},[686,5955,5643],{"class":695},[686,5957,1885],{"class":716},[686,5959,5960],{"class":699},"'Truncated download'",[686,5962,1896],{"class":716},[686,5964,5965],{"class":688,"line":3904},[686,5966,3913],{"class":716},[686,5968,5969,5972,5974,5976,5978,5980,5982,5984,5986],{"class":688,"line":3910},[686,5970,5971],{"class":716},"        $serverName ",[686,5973,2374],{"class":703},[686,5975,2532],{"class":1881},[686,5977,5913],{"class":716},[686,5979,2776],{"class":699},[686,5981,1861],{"class":716},[686,5983,1864],{"class":703},[686,5985,2589],{"class":699},[686,5987,1896],{"class":716},[686,5989,5990,5993,5995,5998,6001,6003,6005,6007,6010],{"class":688,"line":3916},[686,5991,5992],{"class":716},"        $extension ",[686,5994,2374],{"class":703},[686,5996,5997],{"class":695}," pathinfo",[686,5999,6000],{"class":716},"($serverName ",[686,6002,1864],{"class":703},[686,6004,2589],{"class":699},[686,6006,455],{"class":716},[686,6008,6009],{"class":695},"PATHINFO_EXTENSION",[686,6011,1896],{"class":716},[686,6013,6014,6017,6019,6022,6024,6027,6029,6032,6034,6036,6038,6041,6043,6046],{"class":688,"line":3926},[686,6015,6016],{"class":716},"        $file ",[686,6018,2374],{"class":703},[686,6020,6021],{"class":716}," $target ",[686,6023,425],{"class":703},[686,6025,6026],{"class":699}," '.'",[686,6028,4324],{"class":703},[686,6030,6031],{"class":716}," ($extension ",[686,6033,2934],{"class":703},[686,6035,2589],{"class":699},[686,6037,3054],{"class":703},[686,6039,6040],{"class":716}," $extension ",[686,6042,1486],{"class":703},[686,6044,6045],{"class":699}," 'pdf'",[686,6047,1896],{"class":716},[686,6049,6050,6053],{"class":688,"line":3953},[686,6051,6052],{"class":695},"        rename",[686,6054,6055],{"class":716},"($part, $file);\n",[686,6057,6058,6060],{"class":688,"line":3966},[686,6059,5090],{"class":703},[686,6061,6062],{"class":716}," [$file, $serverName];\n",[686,6064,6065],{"class":688,"line":3994},[686,6066,849],{"class":716},[686,6068,6069],{"class":688,"line":4027},[686,6070,910],{"class":716},[686,6072,6073],{"class":688,"line":4035},[686,6074,1841],{"emptyLinePlaceholder":1840},[686,6076,6077,6079,6081,6083,6086,6089,6091],{"class":688,"line":4044},[686,6078,2529],{"class":703},[686,6080,3027],{"class":1881},[686,6082,1885],{"class":716},[686,6084,6085],{"class":695},"Throwable",[686,6087,6088],{"class":716}," $e)",[686,6090,1486],{"class":703},[686,6092,6093],{"class":703}," string\n",[686,6095,6096],{"class":688,"line":4056},[686,6097,733],{"class":716},[686,6099,6100,6102,6105,6107,6109,6111,6114,6117,6119,6121,6124,6126,6128,6131,6134,6136,6138,6140,6143,6145,6148,6150,6153],{"class":688,"line":4061},[686,6101,1982],{"class":703},[686,6103,6104],{"class":716}," $e ",[686,6106,3048],{"class":703},[686,6108,3051],{"class":695},[686,6110,3054],{"class":703},[686,6112,6113],{"class":699}," \"{",[686,6115,6116],{"class":716},"$e",[686,6118,4922],{"class":703},[686,6120,3063],{"class":716},[686,6122,6123],{"class":699},"} {",[686,6125,6116],{"class":716},[686,6127,4922],{"class":703},[686,6129,6130],{"class":716},"errorCode",[686,6132,6133],{"class":699},"} (request {",[686,6135,6116],{"class":716},[686,6137,4922],{"class":703},[686,6139,3082],{"class":716},[686,6141,6142],{"class":699},"})\"",[686,6144,2418],{"class":703},[686,6146,6147],{"class":716}," $e",[686,6149,4922],{"class":703},[686,6151,6152],{"class":1881},"getMessage",[686,6154,2186],{"class":716},[686,6156,6157],{"class":688,"line":4067},[686,6158,910],{"class":716},[686,6160,6161],{"class":688,"line":4080},[686,6162,1841],{"emptyLinePlaceholder":1840},[686,6164,6165],{"class":688,"line":4090},[686,6166,3101],{"class":1742},[686,6168,6169,6172],{"class":688,"line":4095},[686,6170,6171],{"class":703},"try",[686,6173,1976],{"class":716},[686,6175,6176,6178,6180,6182],{"class":688,"line":4100},[686,6177,4488],{"class":716},[686,6179,2374],{"class":703},[686,6181,1964],{"class":1881},[686,6183,6184],{"class":716},"($stateFile);\n",[686,6186,6187,6189,6192,6194,6196,6198,6200,6202,6205,6207,6209,6212,6215,6217,6219,6222,6224,6226,6228],{"class":688,"line":4105},[686,6188,2488],{"class":703},[686,6190,6191],{"class":716}," ($state[",[686,6193,4545],{"class":699},[686,6195,1861],{"class":716},[686,6197,2934],{"class":703},[686,6199,2674],{"class":695},[686,6201,3939],{"class":703},[686,6203,6204],{"class":695}," time",[686,6206,3146],{"class":716},[686,6208,3149],{"class":703},[686,6210,6211],{"class":695}," strtotime",[686,6213,6214],{"class":716},"($state[",[686,6216,4545],{"class":699},[686,6218,5001],{"class":716},[686,6220,6221],{"class":699},"'startedAt'",[686,6223,5918],{"class":716},[686,6225,1429],{"class":703},[686,6227,4357],{"class":695},[686,6229,2069],{"class":716},[686,6231,6232,6235,6238,6241,6244,6247,6249],{"class":688,"line":4117},[686,6233,6234],{"class":695},"        echo",[686,6236,6237],{"class":699}," \"Resuming the run started at {",[686,6239,6240],{"class":716},"$state",[686,6242,6243],{"class":699},"['run']['startedAt']}",[686,6245,6246],{"class":703},"\\n",[686,6248,4622],{"class":699},[686,6250,1765],{"class":716},[686,6252,6253,6256,6258],{"class":688,"line":4126},[686,6254,6255],{"class":716},"    } ",[686,6257,3200],{"class":703},[686,6259,1976],{"class":716},[686,6261,6262,6265,6267,6269,6271,6273,6275,6277,6280,6282,6285,6288,6291,6293],{"class":688,"line":4136},[686,6263,6264],{"class":716},"        $state[",[686,6266,4545],{"class":699},[686,6268,1861],{"class":716},[686,6270,2374],{"class":703},[686,6272,3501],{"class":716},[686,6274,6221],{"class":699},[686,6276,4539],{"class":703},[686,6278,6279],{"class":695}," gmdate",[686,6281,1885],{"class":716},[686,6283,6284],{"class":699},"'c'",[686,6286,6287],{"class":716},"), ",[686,6289,6290],{"class":699},"'finished'",[686,6292,4539],{"class":703},[686,6294,6295],{"class":716}," []];\n",[686,6297,6298],{"class":688,"line":4166},[686,6299,849],{"class":716},[686,6301,6302],{"class":688,"line":4194},[686,6303,1841],{"emptyLinePlaceholder":1840},[686,6305,6306,6309,6311],{"class":688,"line":4200},[686,6307,6308],{"class":716},"    $students ",[686,6310,2374],{"class":703},[686,6312,3251],{"class":716},[686,6314,6315,6318,6320,6323,6326,6328,6330,6332,6334,6336],{"class":688,"line":4205},[686,6316,6317],{"class":703},"    foreach",[686,6319,2365],{"class":716},[686,6321,6322],{"class":1881},"allPages",[686,6324,6325],{"class":716},"($api, ",[686,6327,3275],{"class":699},[686,6329,455],{"class":716},[686,6331,3280],{"class":699},[686,6333,2236],{"class":716},[686,6335,4969],{"class":703},[686,6337,6338],{"class":716}," $student) {\n",[686,6340,6341,6344,6346],{"class":688,"line":4210},[686,6342,6343],{"class":716},"        $students[] ",[686,6345,2374],{"class":703},[686,6347,6348],{"class":716}," $student;\n",[686,6350,6351],{"class":688,"line":4230},[686,6352,849],{"class":716},[686,6354,6355,6358,6360,6362,6364,6366,6368,6370,6372,6374,6377,6379],{"class":688,"line":4254},[686,6356,6357],{"class":716},"    $organizations ",[686,6359,2374],{"class":703},[686,6361,4919],{"class":716},[686,6363,4922],{"class":703},[686,6365,4925],{"class":1881},[686,6367,1885],{"class":716},[686,6369,2451],{"class":699},[686,6371,455],{"class":716},[686,6373,3314],{"class":699},[686,6375,6376],{"class":716},")[",[686,6378,4964],{"class":699},[686,6380,4552],{"class":716},[686,6382,6383,6386,6388,6390,6393,6395,6397,6399,6402,6404,6406,6408,6411,6413,6415,6417,6420,6422,6424],{"class":688,"line":4266},[686,6384,6385],{"class":716},"    $counts ",[686,6387,2374],{"class":703},[686,6389,3501],{"class":716},[686,6391,6392],{"class":699},"'downloaded'",[686,6394,4539],{"class":703},[686,6396,2233],{"class":695},[686,6398,455],{"class":716},[686,6400,6401],{"class":699},"'known'",[686,6403,4539],{"class":703},[686,6405,2233],{"class":695},[686,6407,455],{"class":716},[686,6409,6410],{"class":699},"'notYet'",[686,6412,4539],{"class":703},[686,6414,2233],{"class":695},[686,6416,455],{"class":716},[686,6418,6419],{"class":699},"'failed'",[686,6421,4539],{"class":703},[686,6423,2233],{"class":695},[686,6425,4552],{"class":716},[686,6427,6429],{"class":688,"line":6428},150,[686,6430,1841],{"emptyLinePlaceholder":1840},[686,6432,6434,6436,6439,6441],{"class":688,"line":6433},151,[686,6435,6317],{"class":703},[686,6437,6438],{"class":716}," ($organizations ",[686,6440,4969],{"class":703},[686,6442,6443],{"class":716}," $org) {\n",[686,6445,6447,6449,6451,6454,6457,6459,6462,6465,6467,6470,6472,6474],{"class":688,"line":6446},152,[686,6448,6234],{"class":695},[686,6450,6113],{"class":699},[686,6452,6453],{"class":716},"$org",[686,6455,6456],{"class":699},"['slug']}: \"",[686,6458,4324],{"class":703},[686,6460,6461],{"class":695}," count",[686,6463,6464],{"class":716},"($students) ",[686,6466,425],{"class":703},[686,6468,6469],{"class":699}," \" students",[686,6471,6246],{"class":703},[686,6473,4622],{"class":699},[686,6475,1765],{"class":716},[686,6477,6479],{"class":688,"line":6478},153,[686,6480,1841],{"emptyLinePlaceholder":1840},[686,6482,6484,6486,6489,6491],{"class":688,"line":6483},154,[686,6485,4958],{"class":703},[686,6487,6488],{"class":716}," ($students ",[686,6490,4969],{"class":703},[686,6492,6338],{"class":716},[686,6494,6496,6499,6501,6503,6505,6508,6511,6514],{"class":688,"line":6495},155,[686,6497,6498],{"class":716},"            $pair ",[686,6500,2374],{"class":703},[686,6502,6113],{"class":699},[686,6504,6453],{"class":716},[686,6506,6507],{"class":699},"['slug']}:{",[686,6509,6510],{"class":716},"$student",[686,6512,6513],{"class":699},"['_id']}\"",[686,6515,1765],{"class":716},[686,6517,6519,6521,6523,6526,6529,6531,6533,6535,6537],{"class":688,"line":6518},156,[686,6520,3612],{"class":703},[686,6522,2365],{"class":716},[686,6524,6525],{"class":703},"!",[686,6527,6528],{"class":695},"empty",[686,6530,6214],{"class":716},[686,6532,4545],{"class":699},[686,6534,5001],{"class":716},[686,6536,6290],{"class":699},[686,6538,6539],{"class":716},"][$pair])) {\n",[686,6541,6543,6546],{"class":688,"line":6542},157,[686,6544,6545],{"class":703},"                continue",[686,6547,1765],{"class":716},[686,6549,6551],{"class":688,"line":6550},158,[686,6552,3639],{"class":716},[686,6554,6556,6558],{"class":688,"line":6555},159,[686,6557,3645],{"class":703},[686,6559,1976],{"class":716},[686,6561,6563,6566,6569,6571,6573,6575,6577,6579],{"class":688,"line":6562},160,[686,6564,6565],{"class":703},"                foreach",[686,6567,6568],{"class":716}," ([",[686,6570,3504],{"class":699},[686,6572,455],{"class":716},[686,6574,3509],{"class":699},[686,6576,1861],{"class":716},[686,6578,4969],{"class":703},[686,6580,6581],{"class":716}," $kind) {\n",[686,6583,6585,6588,6590,6592,6594,6596,6599,6602,6604,6607,6609,6612,6614,6617,6619,6621,6623,6625],{"class":688,"line":6584},161,[686,6586,6587],{"class":703},"                    foreach",[686,6589,2365],{"class":716},[686,6591,6322],{"class":1881},[686,6593,6325],{"class":716},[686,6595,4622],{"class":699},[686,6597,6598],{"class":716},"$kind",[686,6600,6601],{"class":699},"-list\"",[686,6603,455],{"class":716},[686,6605,6606],{"class":699},"\"\u002F{",[686,6608,6453],{"class":716},[686,6610,6611],{"class":699},"['_id']}\u002F",[686,6613,6598],{"class":716},[686,6615,6616],{"class":699},"\u002F{",[686,6618,6510],{"class":716},[686,6620,6513],{"class":699},[686,6622,2236],{"class":716},[686,6624,4969],{"class":703},[686,6626,6627],{"class":716}," $doc) {\n",[686,6629,6631,6634,6636,6638,6640,6643,6645,6647,6650,6652],{"class":688,"line":6630},162,[686,6632,6633],{"class":716},"                        $key ",[686,6635,2374],{"class":703},[686,6637,6113],{"class":699},[686,6639,6453],{"class":716},[686,6641,6642],{"class":699},"['slug']}\u002F",[686,6644,6598],{"class":716},[686,6646,6616],{"class":699},[686,6648,6649],{"class":716},"$doc",[686,6651,6513],{"class":699},[686,6653,1765],{"class":716},[686,6655,6657,6660,6662,6664,6666,6668],{"class":688,"line":6656},163,[686,6658,6659],{"class":703},"                        if",[686,6661,2365],{"class":716},[686,6663,5910],{"class":695},[686,6665,6214],{"class":716},[686,6667,4536],{"class":699},[686,6669,6670],{"class":716},"][$key])) {\n",[686,6672,6674,6677,6679,6682,6684],{"class":688,"line":6673},164,[686,6675,6676],{"class":716},"                            $counts[",[686,6678,6401],{"class":699},[686,6680,6681],{"class":716},"]",[686,6683,2383],{"class":703},[686,6685,1765],{"class":716},[686,6687,6689,6692],{"class":688,"line":6688},165,[686,6690,6691],{"class":703},"                            continue",[686,6693,1765],{"class":716},[686,6695,6697],{"class":688,"line":6696},166,[686,6698,6699],{"class":716},"                        }\n",[686,6701,6703,6706],{"class":688,"line":6702},167,[686,6704,6705],{"class":703},"                        try",[686,6707,1976],{"class":716},[686,6709,6711,6714,6716,6719,6722,6724,6726,6728,6731],{"class":688,"line":6710},168,[686,6712,6713],{"class":716},"                            $label ",[686,6715,2374],{"class":703},[686,6717,6718],{"class":716}," $doc[",[686,6720,6721],{"class":699},"'shortId'",[686,6723,1861],{"class":716},[686,6725,1864],{"class":703},[686,6727,6718],{"class":716},[686,6729,6730],{"class":699},"'_id'",[686,6732,4552],{"class":716},[686,6734,6736,6739,6741,6743,6745,6747,6749,6752,6754,6756,6758,6760,6763,6765],{"class":688,"line":6735},169,[686,6737,6738],{"class":716},"                            $target ",[686,6740,2374],{"class":703},[686,6742,4410],{"class":699},[686,6744,4413],{"class":716},[686,6746,6616],{"class":699},[686,6748,6453],{"class":716},[686,6750,6751],{"class":699},"['slug']}\u002F{",[686,6753,6510],{"class":716},[686,6755,6611],{"class":699},[686,6757,6598],{"class":716},[686,6759,3149],{"class":699},[686,6761,6762],{"class":716},"$label",[686,6764,4622],{"class":699},[686,6766,1765],{"class":716},[686,6768,6770,6773,6775,6777,6779,6781,6783,6786,6788,6790,6792,6794,6796,6799,6801,6803],{"class":688,"line":6769},170,[686,6771,6772],{"class":716},"                            [$file, $serverName] ",[686,6774,2374],{"class":703},[686,6776,2696],{"class":1881},[686,6778,6325],{"class":716},[686,6780,4622],{"class":699},[686,6782,6598],{"class":716},[686,6784,6785],{"class":699},"-download\"",[686,6787,455],{"class":716},[686,6789,6606],{"class":699},[686,6791,6453],{"class":716},[686,6793,6611],{"class":699},[686,6795,6598],{"class":716},[686,6797,6798],{"class":699},"\u002Fdownload\u002F{",[686,6800,6649],{"class":716},[686,6802,6513],{"class":699},[686,6804,6805],{"class":716},", $target);\n",[686,6807,6809,6812,6814,6817,6819],{"class":688,"line":6808},171,[686,6810,6811],{"class":716},"                            $state[",[686,6813,4536],{"class":699},[686,6815,6816],{"class":716},"][$key] ",[686,6818,2374],{"class":703},[686,6820,6821],{"class":716}," [\n",[686,6823,6825,6828,6830,6832,6834,6836,6838,6840],{"class":688,"line":6824},172,[686,6826,6827],{"class":699},"                                'shortId'",[686,6829,4539],{"class":703},[686,6831,6718],{"class":716},[686,6833,6721],{"class":699},[686,6835,1861],{"class":716},[686,6837,1864],{"class":703},[686,6839,2674],{"class":695},[686,6841,748],{"class":716},[686,6843,6845,6848,6850],{"class":688,"line":6844},173,[686,6846,6847],{"class":699},"                                'file'",[686,6849,4539],{"class":703},[686,6851,6852],{"class":716}," $file,\n",[686,6854,6856,6859,6861],{"class":688,"line":6855},174,[686,6857,6858],{"class":699},"                                'serverName'",[686,6860,4539],{"class":703},[686,6862,6863],{"class":716}," $serverName,\n",[686,6865,6867,6870,6872,6874,6876,6878],{"class":688,"line":6866},175,[686,6868,6869],{"class":699},"                                'at'",[686,6871,4539],{"class":703},[686,6873,6279],{"class":695},[686,6875,1885],{"class":716},[686,6877,6284],{"class":699},[686,6879,5892],{"class":716},[686,6881,6883],{"class":688,"line":6882},176,[686,6884,6885],{"class":716},"                            ];\n",[686,6887,6889,6892],{"class":688,"line":6888},177,[686,6890,6891],{"class":1881},"                            saveState",[686,6893,6894],{"class":716},"($stateFile, $state);\n",[686,6896,6898,6900,6902,6904,6906],{"class":688,"line":6897},178,[686,6899,6676],{"class":716},[686,6901,6392],{"class":699},[686,6903,6681],{"class":716},[686,6905,2383],{"class":703},[686,6907,1765],{"class":716},[686,6909,6911,6914,6917,6920,6923,6925,6927,6929],{"class":688,"line":6910},179,[686,6912,6913],{"class":695},"                            echo",[686,6915,6916],{"class":699}," \"  + ",[686,6918,6919],{"class":716},"$key",[686,6921,6922],{"class":699}," -> ",[686,6924,4625],{"class":716},[686,6926,6246],{"class":703},[686,6928,4622],{"class":699},[686,6930,1765],{"class":716},[686,6932,6934,6937,6939,6941,6943],{"class":688,"line":6933},180,[686,6935,6936],{"class":716},"                        } ",[686,6938,2020],{"class":703},[686,6940,2365],{"class":716},[686,6942,6085],{"class":695},[686,6944,6945],{"class":716}," $e) {\n",[686,6947,6949,6951,6953,6955,6957,6959],{"class":688,"line":6948},181,[686,6950,6676],{"class":716},[686,6952,6419],{"class":699},[686,6954,6681],{"class":716},[686,6956,2383],{"class":703},[686,6958,1911],{"class":716},[686,6960,3865],{"class":1742},[686,6962,6964,6966,6969,6971,6974,6976,6978,6981,6983,6985,6987,6989],{"class":688,"line":6963},182,[686,6965,6913],{"class":695},[686,6967,6968],{"class":699}," \"  ! ",[686,6970,6919],{"class":716},[686,6972,6973],{"class":699},": \"",[686,6975,4324],{"class":703},[686,6977,3027],{"class":1881},[686,6979,6980],{"class":716},"($e) ",[686,6982,425],{"class":703},[686,6984,4410],{"class":699},[686,6986,6246],{"class":703},[686,6988,4622],{"class":699},[686,6990,1765],{"class":716},[686,6992,6994],{"class":688,"line":6993},183,[686,6995,6699],{"class":716},[686,6997,6999],{"class":688,"line":6998},184,[686,7000,7001],{"class":716},"                    }\n",[686,7003,7005],{"class":688,"line":7004},185,[686,7006,5508],{"class":716},[686,7008,7010,7012,7014,7016,7019],{"class":688,"line":7009},186,[686,7011,3848],{"class":716},[686,7013,2020],{"class":703},[686,7015,2365],{"class":716},[686,7017,7018],{"class":695},"ApiError",[686,7020,6945],{"class":716},[686,7022,7024,7026,7029,7031,7034,7036,7038],{"class":688,"line":7023},187,[686,7025,5456],{"class":703},[686,7027,7028],{"class":716}," ($e",[686,7030,4922],{"class":703},[686,7032,7033],{"class":716},"status ",[686,7035,3945],{"class":703},[686,7037,3948],{"class":695},[686,7039,2069],{"class":716},[686,7041,7043,7046,7048,7050,7052,7054],{"class":688,"line":7042},188,[686,7044,7045],{"class":716},"                    $counts[",[686,7047,6410],{"class":699},[686,7049,6681],{"class":716},[686,7051,2383],{"class":703},[686,7053,1911],{"class":716},[686,7055,3963],{"class":1742},[686,7057,7059,7062,7065,7067,7069,7071,7073,7075],{"class":688,"line":7058},189,[686,7060,7061],{"class":716},"                } ",[686,7063,7064],{"class":703},"elseif",[686,7066,7028],{"class":716},[686,7068,4922],{"class":703},[686,7070,7033],{"class":716},[686,7072,3945],{"class":703},[686,7074,3989],{"class":695},[686,7076,2069],{"class":716},[686,7078,7080,7083,7086,7088,7090,7092,7094,7096,7098,7101,7103,7105],{"class":688,"line":7079},190,[686,7081,7082],{"class":695},"                    echo",[686,7084,7085],{"class":699}," \"  ! {",[686,7087,6453],{"class":716},[686,7089,6456],{"class":699},[686,7091,4324],{"class":703},[686,7093,3027],{"class":1881},[686,7095,6980],{"class":716},[686,7097,425],{"class":703},[686,7099,7100],{"class":699}," \"; skipping this organization",[686,7102,6246],{"class":703},[686,7104,4622],{"class":699},[686,7106,1765],{"class":716},[686,7108,7110,7113],{"class":688,"line":7109},191,[686,7111,7112],{"class":703},"                    break",[686,7114,1765],{"class":716},[686,7116,7118,7120,7122],{"class":688,"line":7117},192,[686,7119,7061],{"class":716},[686,7121,3200],{"class":703},[686,7123,1976],{"class":716},[686,7125,7127,7130,7133],{"class":688,"line":7126},193,[686,7128,7129],{"class":703},"                    throw",[686,7131,7132],{"class":716}," $e; ",[686,7134,4053],{"class":1742},[686,7136,7138],{"class":688,"line":7137},194,[686,7139,5508],{"class":716},[686,7141,7143],{"class":688,"line":7142},195,[686,7144,3639],{"class":716},[686,7146,7148,7151,7153,7155,7157,7160,7162,7164],{"class":688,"line":7147},196,[686,7149,7150],{"class":716},"            $state[",[686,7152,4545],{"class":699},[686,7154,5001],{"class":716},[686,7156,6290],{"class":699},[686,7158,7159],{"class":716},"][$pair] ",[686,7161,2374],{"class":703},[686,7163,4075],{"class":695},[686,7165,1765],{"class":716},[686,7167,7169,7172],{"class":688,"line":7168},197,[686,7170,7171],{"class":1881},"            saveState",[686,7173,6894],{"class":716},[686,7175,7177],{"class":688,"line":7176},198,[686,7178,3913],{"class":716},[686,7180,7182],{"class":688,"line":7181},199,[686,7183,849],{"class":716},[686,7185,7187],{"class":688,"line":7186},200,[686,7188,1841],{"emptyLinePlaceholder":1840},[686,7190,7192,7195,7197,7199,7201,7203],{"class":688,"line":7191},201,[686,7193,7194],{"class":716},"    $state[",[686,7196,4545],{"class":699},[686,7198,1861],{"class":716},[686,7200,2374],{"class":703},[686,7202,2674],{"class":695},[686,7204,1765],{"class":716},[686,7206,7208,7211],{"class":688,"line":7207},202,[686,7209,7210],{"class":1881},"    saveState",[686,7212,6894],{"class":716},[686,7214,7216,7219,7222,7225,7228,7230],{"class":688,"line":7215},203,[686,7217,7218],{"class":695},"    echo",[686,7220,7221],{"class":699}," \"Done: {",[686,7223,7224],{"class":716},"$counts",[686,7226,7227],{"class":699},"['downloaded']} downloaded, {",[686,7229,7224],{"class":716},[686,7231,7232],{"class":699},"['known']} already had, \"\n",[686,7234,7236,7239,7241,7243,7246,7248,7251,7253,7255],{"class":688,"line":7235},204,[686,7237,7238],{"class":703},"        .",[686,7240,6113],{"class":699},[686,7242,7224],{"class":716},[686,7244,7245],{"class":699},"['notYet']} pairs without a sign-in, {",[686,7247,7224],{"class":716},[686,7249,7250],{"class":699},"['failed']} failed.",[686,7252,6246],{"class":703},[686,7254,4622],{"class":699},[686,7256,1765],{"class":716},[686,7258,7260,7263,7265,7267,7269],{"class":688,"line":7259},205,[686,7261,7262],{"class":716},"} ",[686,7264,2020],{"class":703},[686,7266,2365],{"class":716},[686,7268,6085],{"class":695},[686,7270,6945],{"class":716},[686,7272,7274,7277,7279,7282,7284,7287,7289,7291,7293,7295,7297,7299,7301],{"class":688,"line":7273},206,[686,7275,7276],{"class":695},"    fwrite",[686,7278,1885],{"class":716},[686,7280,7281],{"class":695},"STDERR",[686,7283,455],{"class":716},[686,7285,7286],{"class":699},"'Stopped: '",[686,7288,4324],{"class":703},[686,7290,3027],{"class":1881},[686,7292,6980],{"class":716},[686,7294,425],{"class":703},[686,7296,4410],{"class":699},[686,7298,6246],{"class":703},[686,7300,4622],{"class":699},[686,7302,1896],{"class":716},[686,7304,7306,7309,7311,7313],{"class":688,"line":7305},207,[686,7307,7308],{"class":703},"    exit",[686,7310,1885],{"class":716},[686,7312,545],{"class":695},[686,7314,1896],{"class":716},[686,7316,7318],{"class":688,"line":7317},208,[686,7319,910],{"class":716},[1727,7321,7323],{"id":7322},"expected-output","Expected output",[358,7325,7326],{},"The first run after results are published:",[676,7328,7333],{"className":7329,"code":7331,"language":7332,"meta":682},[7330],"language-text","$ node collect-results.mjs .\u002Fresults\nstem: 512 students\n  + stem\u002Fcertificate\u002F66f1c0d2e3f4a5b6c7d8e9f0 -> results\u002Fstem\u002F66e6a3f5c1d2b30012a4f9c1\u002Fcertificate-K7Q2M9X4TB.pdf\n  + stem\u002Freport\u002F66f1c0d2e3f4a5b6c7d8ea01 -> results\u002Fstem\u002F66e6a3f5c1d2b30012a4f9c1\u002Freport-P3W8R2N6ZD.pdf\n  ! stem\u002Freport\u002F66f1c0d2e3f4a5b6c7d8ea3c: 404 not_found (request 0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d)\nneo: 512 students\n…\nDone: 1284 downloaded, 0 already had, 1466 pairs without a sign-in, 1 failed.\n","text",[384,7334,7331],{"__ignoreMap":682},[358,7336,7337],{},"The next night, with nothing new released:",[676,7339,7342],{"className":7340,"code":7341,"language":7332,"meta":682},[7330],"Done: 0 downloaded, 1284 already had, 1463 pairs without a sign-in, 0 failed.\n",[384,7343,7341],{"__ignoreMap":682},[358,7345,7346,7347,7350],{},"The failed report is not in the state file, so the next run tries it again. A ",[384,7348,7349],{},"404"," on a document that\nwas just listed usually means it was withdrawn or has no file yet.",[362,7352,7354],{"id":7353},"schedule-it","Schedule it",[358,7356,7357],{},"Run the job once a night from cron or your scheduler, with the credentials in its environment. Cron\ndoes not load your shell profile, so read them from a file only the job's user can read:",[676,7359,7362],{"className":678,"code":7360,"filename":7361,"language":681,"meta":682,"style":682},"# 02:15 every night\n15 2 * * * cd \u002Fsrv\u002Fresults-job && . .\u002Fcredentials.env && node collect-results.mjs \u002Fsrv\u002Fresults >> \u002Fvar\u002Flog\u002Fresults-job.log 2>&1\n","crontab",[384,7363,7364,7369],{"__ignoreMap":682},[686,7365,7366],{"class":688,"line":689},[686,7367,7368],{"class":1742},"# 02:15 every night\n",[686,7370,7371,7374,7376,7378,7380,7382,7385,7388,7391,7393,7396,7398,7401,7404,7407,7410,7413],{"class":688,"line":707},[686,7372,7373],{"class":692},"15",[686,7375,5469],{"class":695},[686,7377,1929],{"class":695},[686,7379,1929],{"class":695},[686,7381,1929],{"class":695},[686,7383,7384],{"class":699}," cd",[686,7386,7387],{"class":699}," \u002Fsrv\u002Fresults-job",[686,7389,7390],{"class":716}," && ",[686,7392,425],{"class":695},[686,7394,7395],{"class":699}," .\u002Fcredentials.env",[686,7397,7390],{"class":716},[686,7399,7400],{"class":692},"node",[686,7402,7403],{"class":699}," collect-results.mjs",[686,7405,7406],{"class":699}," \u002Fsrv\u002Fresults",[686,7408,7409],{"class":703}," >>",[686,7411,7412],{"class":699}," \u002Fvar\u002Flog\u002Fresults-job.log",[686,7414,7415],{"class":703}," 2>&1\n",[358,7417,7418],{},"The job prints no secrets and no tokens, so its log is safe to keep.",[362,7420,7422],{"id":7421},"handling-failures","Handling failures",[509,7424,7425,7438],{},[512,7426,7427],{},[515,7428,7429,7432,7435],{},[518,7430,7431],{},"What happens",[518,7433,7434],{},"What the job does",[518,7436,7437],{},"What you do",[525,7439,7440,7453,7471,7491,7506,7517,7533],{},[515,7441,7442,7447,7450],{},[530,7443,7444,7446],{},[384,7445,404],{}," on a list",[530,7448,7449],{},"Counts the pair as without a sign-in, and moves on",[530,7451,7452],{},"Nothing. Their documents appear after their first sign-in there",[515,7454,7455,7460,7463],{},[530,7456,7457,7446],{},[384,7458,7459],{},"403 forbidden",[530,7461,7462],{},"Skips the organization for this run",[530,7464,7465,7466,607,7468,7470],{},"Ask your operator for ",[384,7467,645],{},[384,7469,648],{}," there",[515,7472,7473,7478,7481],{},[530,7474,7475,7477],{},[384,7476,454],{}," on a download",[530,7479,7480],{},"Logs it, does not record it, tries again next run",[530,7482,7483,7484,7487,7488],{},"Nothing, unless it persists. Then send the ",[384,7485,7486],{},"request_id"," to ",[423,7489,7490],{"href":346},"support",[515,7492,7493,7497,7503],{},[530,7494,7495],{},[384,7496,595],{},[530,7498,7499,7500,7502],{},"Waits for ",[384,7501,599],{}," seconds, up to three times",[530,7504,7505],{},"Check whether something else uses the same route at the same time",[515,7507,7508,7511,7514],{},[530,7509,7510],{},"A truncated transfer",[530,7512,7513],{},"Deletes the partial file; tries again next run",[530,7515,7516],{},"Nothing",[515,7518,7519,7524,7527],{},[530,7520,7521],{},[384,7522,7523],{},"401 unauthorized",[530,7525,7526],{},"Signs a fresh token and retries once, then stops",[530,7528,7529,7530],{},"See ",[423,7531,7532],{"href":113},"Handle tokens in production",[515,7534,7535,7541,7544],{},[530,7536,7537,7540],{},[384,7538,7539],{},"5xx",", or a network error on a list",[530,7542,7543],{},"Stops; the next start resumes at the last finished pair",[530,7545,7546],{},"Rerun later",[362,7548,7550],{"id":7549},"next-steps","Next steps",[367,7552,7553,7558,7565,7570],{},[370,7554,7555,7557],{},[423,7556,92],{"href":93},": every rule for listing and\ndownloading.",[370,7559,7560,607,7562,7564],{},[423,7561,39],{"href":40},[423,7563,45],{"href":46},": the numbers this job is built on.",[370,7566,7567,7569],{},[423,7568,36],{"href":37},": why every request here takes the core student id.",[370,7571,7572,7573,748,7576,748,7579,748,7582,425],{},"Reference: ",[423,7574,7575],{"href":264},"listStudentCertificates",[423,7577,7578],{"href":261},"downloadCertificate",[423,7580,7581],{"href":270},"listStudentReports",[423,7583,7584],{"href":267},"downloadReport",[7586,7587,7588],"style",{},"html pre.shiki code .soyes, html code.shiki .soyes{--shiki-default:#702C00;--shiki-dark:#FFB757}html pre.shiki code .s-5SL, html code.shiki .s-5SL{--shiki-default:#023B95;--shiki-dark:#91CBFF}html pre.shiki code .sT6z2, html code.shiki .sT6z2{--shiki-default:#032563;--shiki-dark:#ADDCFF}html pre.shiki code .sHUrx, html code.shiki .sHUrx{--shiki-default:#A0111F;--shiki-dark:#FF9492}html pre.shiki code .suds8, html code.shiki .suds8{--shiki-default:#0E1116;--shiki-dark:#F0F3F6}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sne4z, html code.shiki .sne4z{--shiki-default:#024C1A;--shiki-dark:#72F088}html pre.shiki code .sLBg1, html code.shiki .sLBg1{--shiki-default:#66707B;--shiki-dark:#BDC4CC}html pre.shiki code .sKwhi, html code.shiki .sKwhi{--shiki-default:#622CBC;--shiki-dark:#DBB7FF}html pre.shiki code .sJaa3, html code.shiki .sJaa3{--shiki-default:#024C1A;--shiki-default-font-weight:bold;--shiki-dark:#72F088;--shiki-dark-font-weight:bold}",{"title":682,"searchDepth":707,"depth":751,"links":7590},[7591,7592,7593,7594,7595,7596,7597,7598,7599,7600,7605,7606,7607],{"id":364,"depth":707,"text":365},{"id":461,"depth":707,"text":462},{"id":499,"depth":707,"text":500},{"id":623,"depth":707,"text":624},{"id":673,"depth":707,"text":674},{"id":926,"depth":707,"text":927},{"id":1208,"depth":707,"text":1209},{"id":1395,"depth":707,"text":1396},{"id":1578,"depth":707,"text":1579},{"id":1724,"depth":707,"text":1725,"children":7601},[7602,7603,7604],{"id":1729,"depth":751,"text":308},{"id":4272,"depth":751,"text":311},{"id":7322,"depth":751,"text":7323},{"id":7353,"depth":707,"text":7354},{"id":7421,"depth":707,"text":7422},{"id":7549,"depth":707,"text":7550},"A resumable nightly job that finds newly released certificates and reports for your students, downloads the files and stays inside the rate limit.","md",{},[7612,7613,7575,7578,7581,7584],"listOrganizations","listStudents","40",{"title":353,"description":7608},"api\u002Ftutorials\u002Fcollect-results","_zzvh0vQXcQcSs5zvxw_vATHhs-TAj9YtvgjEwWaGG4",[7619,7624,7628,7633,7636,7640],{"operationId":7612,"slug":7620,"method":133,"path":7621,"tag":74,"summary":161,"deprecated":134,"public":134,"permission":7622,"scope":7623,"order":805},"list-organizations","\u002Fv1\u002Forganization","organization\u002Fread:$org:$ID","flat",{"operationId":7613,"slug":7625,"method":133,"path":7626,"tag":62,"summary":170,"deprecated":134,"public":134,"permission":7627,"scope":7623,"order":831},"list-students","\u002Fv1\u002Fstudent","student\u002Fread:$org:$ID",{"operationId":7575,"slug":7629,"method":133,"path":7630,"tag":256,"summary":263,"deprecated":134,"public":134,"permission":7631,"scope":7632,"order":2310},"list-student-certificates","\u002Fv1\u002F{organizationId}\u002Fcertificate\u002F{userId}","certificate\u002Fread:$org:$ID","organization",{"operationId":7578,"slug":7634,"method":133,"path":7635,"tag":256,"summary":260,"deprecated":134,"public":134,"permission":7631,"scope":7632,"order":2293},"download-certificate","\u002Fv1\u002F{organizationId}\u002Fcertificate\u002Fdownload\u002F{certificateId}",{"operationId":7581,"slug":7637,"method":133,"path":7638,"tag":256,"summary":269,"deprecated":134,"public":134,"permission":7639,"scope":7632,"order":2326},"list-student-reports","\u002Fv1\u002F{organizationId}\u002Freport\u002F{userId}","report\u002Fread:$org:$ID",{"operationId":7584,"slug":7641,"method":133,"path":7642,"tag":256,"summary":266,"deprecated":134,"public":134,"permission":7639,"scope":7632,"order":2321},"download-report","\u002Fv1\u002F{organizationId}\u002Freport\u002Fdownload\u002F{reportId}",1791554615308]