[{"data":1,"prerenderedAt":6014},["ShallowReactive",2],{"docs-\u002Fdocs\u002Ftechnical-onboarding":3,"docs-nav":3417},{"id":4,"title":5,"body":6,"category":3405,"description":3406,"extension":3407,"head":3408,"meta":3409,"navLabel":5,"navigation":931,"ogImage":3408,"order":3410,"path":3411,"robots":3408,"schemaOrg":3408,"seo":3412,"sitemap":3413,"stem":3415,"updatedAt":3414,"__hash__":3416},"docs\u002Fdocs\u002Ftechnical-onboarding.md","Technical Onboarding",{"type":7,"value":8,"toc":3382},"minimark",[9,14,18,22,25,30,33,58,62,65,189,200,204,288,292,295,300,311,350,426,429,433,574,2336,3031,3045,3049,3052,3100,3114,3144,3193,3210,3214,3217,3221,3224,3241,3244,3248,3252,3263,3269,3275,3293,3297,3324,3333,3337,3345,3351,3357,3371,3375,3378],[10,11,13],"h2",{"id":12},"overview","Overview",[15,16,17],"p",{},"This document provides the technical requirements and guidance for onboarding data to Deducta. It outlines the data required, available delivery methods, submission cadence, security requirements, and key responsibilities to support successful implementation and ongoing data refreshes.",[10,19,21],{"id":20},"what-to-send","What to send",[15,23,24],{},"The ingestion pipeline is designed to accept a variety of file structures, formats and field combinations as they come out of your source systems. We support Parquet, Excel workbooks and CSV files. Multiple files can also be zipped together into a single upload.",[26,27,29],"h3",{"id":28},"datasets","Datasets",[15,31,32],{},"Typical datasets are:",[34,35,36,40,43,46,49,52,55],"ul",{},[37,38,39],"li",{},"Invoice transactions",[37,41,42],{},"Purchase orders",[37,44,45],{},"Supplier master",[37,47,48],{},"Payment terms",[37,50,51],{},"Business hierarchies",[37,53,54],{},"Contracts",[37,56,57],{},"Taxonomy and other procurement reference data, where available",[26,59,61],{"id":60},"data-schema","Data schema",[15,63,64],{},"While we don't require a fixed ingestion schema, we do require the fields below to be represented accurately in the dataset. Providing these fields is the minimum that allows you to see the benefits of the Deducta platform. However, there is no limit on the amount of contextual spend information that we can ingest. The more we have, the better the platform performs.",[66,67,68,81],"table",{},[69,70,71],"thead",{},[72,73,74,78],"tr",{},[75,76,77],"th",{},"Field",[75,79,80],{},"Description",[82,83,84,93,101,109,117,125,133,141,149,157,165,173,181],"tbody",{},[72,85,86,90],{},[87,88,89],"td",{},"Net Spend Amount",[87,91,92],{},"Monetary value of the transaction or payment, excluding taxes",[72,94,95,98],{},[87,96,97],{},"Currency \u002F Currency Code",[87,99,100],{},"Currency the transaction is recorded in, for example GBP, USD, EUR",[72,102,103,106],{},[87,104,105],{},"Supplier Name",[87,107,108],{},"Supplier associated with the transaction",[72,110,111,114],{},[87,112,113],{},"Payment Date",[87,115,116],{},"Date the supplier payment was made (i.e., the clearing date)",[72,118,119,122],{},[87,120,121],{},"Payment Terms",[87,123,124],{},"When payment is due to the supplier, for example Net 30",[72,126,127,130],{},[87,128,129],{},"Article Description",[87,131,132],{},"Description of the material, product or service purchased",[72,134,135,138],{},[87,136,137],{},"Article ID \u002F Material Code",[87,139,140],{},"Identifier of the material, product or service in the source system, plus any further article attributes",[72,142,143,146],{},[87,144,145],{},"Purchasing Business Unit",[87,147,148],{},"Business unit or division responsible for the spend",[72,150,151,154],{},[87,152,153],{},"Buying Entity",[87,155,156],{},"Legal entity purchasing the goods or services",[72,158,159,162],{},[87,160,161],{},"Site",[87,163,164],{},"Location, facility or operating site associated with the spend",[72,166,167,170],{},[87,168,169],{},"Unit of Measure",[87,171,172],{},"Standard quantity measure, for example kg, liters, units, cases",[72,174,175,178],{},[87,176,177],{},"Unit Cost",[87,179,180],{},"Cost per unit",[72,182,183,186],{},[87,184,185],{},"Quantity",[87,187,188],{},"Quantity purchased",[190,191,193],"d-docs-details",{"summary":192},"How Deducta defines spend",[15,194,195,196,199],{},"Spend is dated by ",[197,198,113],"strong",{},", the date the payment to the supplier is cleared. Invoice date, purchase order date and goods receipt date are not used as the spend date. If your extract has several dates, include them all and make sure Payment Date is present.",[26,201,203],{"id":202},"formats","Formats",[66,205,206,219],{},[69,207,208],{},[72,209,210,213,216],{},[75,211,212],{},"Format",[75,214,215],{},"Extension",[75,217,218],{},"Notes",[82,220,221,235,248,260,273],{},[72,222,223,226,232],{},[87,224,225],{},"Parquet",[87,227,228],{},[229,230,231],"code",{},".parquet",[87,233,234],{},"Preferred. Best performance and fidelity for large extracts",[72,236,237,240,245],{},[87,238,239],{},"Excel",[87,241,242],{},[229,243,244],{},".xlsx",[87,246,247],{},"Accepted",[72,249,250,253,258],{},[87,251,252],{},"CSV",[87,254,255],{},[229,256,257],{},".csv",[87,259,247],{},[72,261,262,265,270],{},[87,263,264],{},"ZIP",[87,266,267],{},[229,268,269],{},".zip",[87,271,272],{},"Archive of any of the above, for sending a batch at once",[72,274,275,278,283],{},[87,276,277],{},"PDF",[87,279,280],{},[229,281,282],{},".pdf",[87,284,285,286],{},"Contracts only, up to 256 MB per file. Sent one file at a time through the API, and not part of a ",[229,287,269],{},[26,289,291],{"id":290},"file-naming-convention","File naming convention",[15,293,294],{},"To help Deducta identify and process each file, we recommend you name files using the following format:",[15,296,297],{},[229,298,299],{},"{CompanyName}_{BusinessUnitName}_{DataType}_{TimeFrame}.{ext}",[15,301,302,303,306,307,310],{},"For example, ",[229,304,305],{},"ACME_fireworks_spend_FY25.xlsx"," or ",[229,308,309],{},"ACME_fireworks_contracts_202608.csv",".",[34,312,313,316,323,329,344],{},[37,314,315],{},"Separate segments with underscores. Do not use spaces inside a segment.",[37,317,318,319,322],{},"Use hyphens only inside a ",[229,320,321],{},"{TimeFrame}"," range.",[37,324,325,326,310],{},"Use the company name or abbreviation agreed with Deducta for ",[229,327,328],{},"{CompanyName}",[37,330,331,332,335,336,339,340,343],{},"Write ",[229,333,334],{},"{DataType}"," in lowercase (e.g., ",[229,337,338],{},"spend",", ",[229,341,342],{},"contracts",").",[37,345,346,347,349],{},"For ",[229,348,321],{},", use the smallest unit that covers the data:",[66,351,352,364],{},[69,353,354],{},[72,355,356,359,361],{},[75,357,358],{},"Period",[75,360,212],{},[75,362,363],{},"Example",[82,365,366,381,396,411],{},[72,367,368,371,376],{},[87,369,370],{},"Month",[87,372,373],{},[229,374,375],{},"YYYYMM",[87,377,378],{},[229,379,380],{},"202608",[72,382,383,386,391],{},[87,384,385],{},"Quarter",[87,387,388],{},[229,389,390],{},"FYyyQn",[87,392,393],{},[229,394,395],{},"FY25Q3",[72,397,398,401,406],{},[87,399,400],{},"Fiscal year",[87,402,403],{},[229,404,405],{},"FYyy",[87,407,408],{},[229,409,410],{},"FY25",[72,412,413,416,421],{},[87,414,415],{},"Range",[87,417,418],{},[229,419,420],{},"{start}-{end}",[87,422,423],{},[229,424,425],{},"202601-202608",[15,427,428],{},"Fiscal year refers to your fiscal year, not the calendar year. Where the two differ and it matters, use the month or range format instead.",[10,430,432],{"id":431},"choose-a-delivery-method","Choose a delivery method",[66,434,435,457],{},[69,436,437],{},[72,438,439,441,447,452],{},[75,440],{},[75,442,443,446],{},[197,444,445],{},"HTTP API Upload"," (recommended)",[75,448,449],{},[197,450,451],{},"Shared storage account",[75,453,454],{},[197,455,456],{},"Deducta platform",[82,458,459,473,502,516,533,546,560],{},[72,460,461,464,467,470],{},[87,462,463],{},"Best for",[87,465,466],{},"Scheduled, automated feeds",[87,468,469],{},"Large files, backfills and rolling uploads",[87,471,472],{},"One-off, ad hoc uploads",[72,474,475,477,487,497],{},[87,476,203],{},[87,478,479,339,481,339,483,339,485],{},[229,480,244],{},[229,482,231],{},[229,484,257],{},[229,486,269],{},[87,488,489,339,491,339,493,339,495],{},[229,490,244],{},[229,492,231],{},[229,494,257],{},[229,496,269],{},[87,498,499,501],{},[229,500,244],{}," only",[72,503,504,507,510,513],{},[87,505,506],{},"Cadence",[87,508,509],{},"Daily, weekly or monthly",[87,511,512],{},"Manual or automated",[87,514,515],{},"Manual",[72,517,518,521,527,530],{},[87,519,520],{},"Max size",[87,522,523,524,526],{},"50 MB per request (compressed size for a ",[229,525,269],{},"); higher limits on request",[87,528,529],{},"No Deducta limit; 5,000 MiB per single REST request, larger via AzCopy or the SDK",[87,531,532],{},"Not specified",[72,534,535,538,541,544],{},[87,536,537],{},"Data scope",[87,539,540],{},"Net-new data only",[87,542,543],{},"No restriction",[87,545,540],{},[72,547,548,551,554,557],{},[87,549,550],{},"You need",[87,552,553],{},"API key, business unit ID",[87,555,556],{},"Client ID and secret, container URL",[87,558,559],{},"A platform login",[72,561,562,565,568,571],{},[87,563,564],{},"Works from",[87,566,567],{},"Anywhere that can make an HTTPS request",[87,569,570],{},"Any environment, including Google Cloud, AWS and on-premises",[87,572,573],{},"Browser",[575,576,577,585,592,597,641,646,700,705,730,747,752,759,850,856,911,1069,1632,2303,2308],"d-docs-section",{},[578,579,581],"template",{"v-slot:title":580},"",[26,582,584],{"id":583},"option-1-http-api-upload","Option 1: HTTP API Upload",[15,586,587,588,591],{},"A scheduled job can export data from your source systems and call an HTTP ",[229,589,590],{},"PUT"," endpoint to upload the file to our system.",[15,593,594],{},[197,595,596],{},"What we send you",[66,598,599,609],{},[69,600,601],{},[72,602,603,606],{},[75,604,605],{},"Item",[75,607,608],{},"Detail",[82,610,611,623,631],{},[72,612,613,616],{},[87,614,615],{},"API key",[87,617,618,619,622],{},"Sent by your Deducta representative. Passed in the ",[229,620,621],{},"X-API-Key"," header",[72,624,625,628],{},[87,626,627],{},"Business unit ID",[87,629,630],{},"GUID that identifies where the data belongs",[72,632,633,636],{},[87,634,635],{},"Base URL",[87,637,638],{},[229,639,640],{},"https:\u002F\u002Fapi-data-ingestion.deducta.ai\u002Fm2m",[15,642,643],{},[197,644,645],{},"Request",[66,647,648,656],{},[69,649,650],{},[72,651,652,654],{},[75,653],{},[75,655],{},[82,657,658,668,678,689],{},[72,659,660,663],{},[87,661,662],{},"Endpoint",[87,664,665],{},[229,666,667],{},"PUT \u002Fapi\u002Ffile\u002Fupload",[72,669,670,673],{},[87,671,672],{},"Content type",[87,674,675],{},[229,676,677],{},"multipart\u002Fform-data",[72,679,680,686],{},[87,681,682,685],{},[229,683,684],{},"file"," (form data, required)",[87,687,688],{},"The data file or ZIP archive to upload",[72,690,691,697],{},[87,692,693,696],{},[229,694,695],{},"businessUnitId"," (query string, required)",[87,698,699],{},"Your business unit GUID. It can't be empty or the all-zero GUID",[15,701,702],{},[197,703,704],{},"Limits",[34,706,707,718,724,727],{},[37,708,709,710,339,712,339,714,306,716,310],{},"Formats: ",[229,711,244],{},[229,713,231],{},[229,715,257],{},[229,717,269],{},[37,719,720,721,723],{},"Size: 50 MB by default. For a ",[229,722,269],{}," the limit applies to the compressed archive, not its contents. Higher limits can be arranged on request.",[37,725,726],{},"The file must not be empty.",[37,728,729],{},"Net-new data only. Don't resend data you have already submitted, because it will not be de-duplicated and will be ingested as new data.",[15,731,732,733,735,736,339,738,306,740,742,743,310],{},"A ",[229,734,269],{}," can hold one or more ",[229,737,244],{},[229,739,231],{},[229,741,257],{}," files. Deducta expands it on receipt, and the file names inside identify the data, so name them as described in ",[744,745,291],"a",{"href":746},"#file-naming-convention",[15,748,749],{},[197,750,751],{},"Response",[15,753,754,755,758],{},"Files are ingested asynchronously, but once a file has been accepted you will receive a ",[229,756,757],{},"200 OK",". The stored file name has a processing timestamp appended, so you don't need to add one yourself.",[760,761,765],"pre",{"className":762,"code":763,"language":764,"meta":580,"style":580},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"fileId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"fileName\": \"your_file_uploaded_20260119T143025.xlsx\",\n  \"businessUnitId\": \"7d9e4b2a-8c3f-4e1d-9a6b-5f8c2d1e3a4b\"\n}\n","json",[229,766,767,776,804,825,844],{"__ignoreMap":580},[768,769,772],"span",{"class":770,"line":771},"line",1,[768,773,775],{"class":774},"sMK4o","{\n",[768,777,779,782,786,789,792,795,799,801],{"class":770,"line":778},2,[768,780,781],{"class":774},"  \"",[768,783,785],{"class":784},"spNyl","fileId",[768,787,788],{"class":774},"\"",[768,790,791],{"class":774},":",[768,793,794],{"class":774}," \"",[768,796,798],{"class":797},"sfazB","3fa85f64-5717-4562-b3fc-2c963f66afa6",[768,800,788],{"class":774},[768,802,803],{"class":774},",\n",[768,805,807,809,812,814,816,818,821,823],{"class":770,"line":806},3,[768,808,781],{"class":774},[768,810,811],{"class":784},"fileName",[768,813,788],{"class":774},[768,815,791],{"class":774},[768,817,794],{"class":774},[768,819,820],{"class":797},"your_file_uploaded_20260119T143025.xlsx",[768,822,788],{"class":774},[768,824,803],{"class":774},[768,826,828,830,832,834,836,838,841],{"class":770,"line":827},4,[768,829,781],{"class":774},[768,831,695],{"class":784},[768,833,788],{"class":774},[768,835,791],{"class":774},[768,837,794],{"class":774},[768,839,840],{"class":797},"7d9e4b2a-8c3f-4e1d-9a6b-5f8c2d1e3a4b",[768,842,843],{"class":774},"\"\n",[768,845,847],{"class":770,"line":846},5,[768,848,849],{"class":774},"}\n",[15,851,852,853,791],{},"Errors return a JSON body such as ",[229,854,855],{},"{ \"error\": \"...\" }",[66,857,858,868],{},[69,859,860],{},[72,861,862,865],{},[75,863,864],{},"Status",[75,866,867],{},"Meaning and fix",[82,869,870,887,897],{},[72,871,872,877],{},[87,873,874],{},[229,875,876],{},"400 Bad Request",[87,878,879,880,883,884,886],{},"A validation failure. The ",[229,881,882],{},"error"," message says which: missing or empty ",[229,885,695],{},", no file or an empty file, size over the limit, or an unsupported file type.",[72,888,889,894],{},[87,890,891],{},[229,892,893],{},"401 Unauthorized",[87,895,896],{},"The API key is invalid or missing.",[72,898,899,904],{},[87,900,901],{},[229,902,903],{},"500 Internal Server Error",[87,905,906,907,910],{},"The file couldn't be processed. The body includes a ",[229,908,909],{},"details"," message. Retry with backoff, and contact your Deducta representative if it persists.",[190,912,914],{"summary":913},"cURL",[760,915,919],{"className":916,"code":917,"language":918,"meta":580,"style":580},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","#!\u002Fbin\u002Fbash\n\nAPI_KEY=\"your-api-key-here\"\nBUSINESS_UNIT_ID=\"your-business-unit-id-here\"\nFILE_PATH=\"\u002Fpath\u002Fto\u002Fyour\u002Ffile.xlsx\"\nAPI_URL=\"https:\u002F\u002Fapi-data-ingestion.deducta.ai\u002Fm2m\u002Fapi\u002Ffile\u002Fupload\"\n\ncurl -X PUT \"${API_URL}?businessUnitId=${BUSINESS_UNIT_ID}\" \\\n  -H \"X-API-Key: ${API_KEY}\" \\\n  -F \"file=@${FILE_PATH}\"\n","bash",[229,920,921,927,933,949,963,977,992,997,1032,1051],{"__ignoreMap":580},[768,922,923],{"class":770,"line":771},[768,924,926],{"class":925},"sHwdD","#!\u002Fbin\u002Fbash\n",[768,928,929],{"class":770,"line":778},[768,930,932],{"emptyLinePlaceholder":931},true,"\n",[768,934,935,939,942,944,947],{"class":770,"line":806},[768,936,938],{"class":937},"sTEyZ","API_KEY",[768,940,941],{"class":774},"=",[768,943,788],{"class":774},[768,945,946],{"class":797},"your-api-key-here",[768,948,843],{"class":774},[768,950,951,954,956,958,961],{"class":770,"line":827},[768,952,953],{"class":937},"BUSINESS_UNIT_ID",[768,955,941],{"class":774},[768,957,788],{"class":774},[768,959,960],{"class":797},"your-business-unit-id-here",[768,962,843],{"class":774},[768,964,965,968,970,972,975],{"class":770,"line":846},[768,966,967],{"class":937},"FILE_PATH",[768,969,941],{"class":774},[768,971,788],{"class":774},[768,973,974],{"class":797},"\u002Fpath\u002Fto\u002Fyour\u002Ffile.xlsx",[768,976,843],{"class":774},[768,978,980,983,985,987,990],{"class":770,"line":979},6,[768,981,982],{"class":937},"API_URL",[768,984,941],{"class":774},[768,986,788],{"class":774},[768,988,989],{"class":797},"https:\u002F\u002Fapi-data-ingestion.deducta.ai\u002Fm2m\u002Fapi\u002Ffile\u002Fupload",[768,991,843],{"class":774},[768,993,995],{"class":770,"line":994},7,[768,996,932],{"emptyLinePlaceholder":931},[768,998,1000,1004,1007,1010,1013,1015,1018,1021,1024,1026,1029],{"class":770,"line":999},8,[768,1001,1003],{"class":1002},"sBMFI","curl",[768,1005,1006],{"class":797}," -X",[768,1008,1009],{"class":797}," PUT",[768,1011,1012],{"class":774}," \"${",[768,1014,982],{"class":937},[768,1016,1017],{"class":774},"}",[768,1019,1020],{"class":797},"?businessUnitId=",[768,1022,1023],{"class":774},"${",[768,1025,953],{"class":937},[768,1027,1028],{"class":774},"}\"",[768,1030,1031],{"class":937}," \\\n",[768,1033,1035,1038,1040,1043,1045,1047,1049],{"class":770,"line":1034},9,[768,1036,1037],{"class":797},"  -H",[768,1039,794],{"class":774},[768,1041,1042],{"class":797},"X-API-Key: ",[768,1044,1023],{"class":774},[768,1046,938],{"class":937},[768,1048,1028],{"class":774},[768,1050,1031],{"class":937},[768,1052,1054,1057,1059,1062,1064,1066],{"class":770,"line":1053},10,[768,1055,1056],{"class":797},"  -F",[768,1058,794],{"class":774},[768,1060,1061],{"class":797},"file=@",[768,1063,1023],{"class":774},[768,1065,967],{"class":937},[768,1067,1068],{"class":774},"}\"\n",[190,1070,1072],{"summary":1071},"Python",[760,1073,1077],{"className":1074,"code":1075,"language":1076,"meta":580,"style":580},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import mimetypes\nimport requests\nfrom pathlib import Path\n\n# Configuration\nAPI_KEY = \"your-api-key-here\"\nBUSINESS_UNIT_ID = \"your-business-unit-id-here\"\nFILE_PATH = \"\u002Fpath\u002Fto\u002Fyour\u002Ffile.xlsx\"\nAPI_URL = \"https:\u002F\u002Fapi-data-ingestion.deducta.ai\u002Fm2m\u002Fapi\u002Ffile\u002Fupload\"\n\nACCEPTED_EXTENSIONS = {\".xlsx\", \".parquet\", \".csv\", \".zip\"}\nMAX_FILE_SIZE_MB = 50\n\ndef upload_file(file_path, business_unit_id, api_key):\n    \"\"\"\n    Upload a data file to the Deducta Data Ingestion API.\n\n    Accepts .xlsx, .parquet, .csv, and .zip files; Excel and Parquet are\n    preferred. Use a .zip archive to upload a batch of files in one request.\n\n    Args:\n        file_path (str): Path to the file to upload\n        business_unit_id (str): GUID of the business unit\n        api_key (str): API key for authentication\n\n    Returns:\n        dict: Response containing fileId, fileName, and businessUnitId\n\n    Raises:\n        requests.exceptions.HTTPError: If the request fails\n    \"\"\"\n    # Validate file exists\n    file = Path(file_path)\n    if not file.exists():\n        raise FileNotFoundError(f\"File not found: {file_path}\")\n\n    # Validate file format\n    if file.suffix.lower() not in ACCEPTED_EXTENSIONS:\n        raise ValueError(f\"Unsupported file format: {file.suffix}\")\n\n    # Check file size — for a .zip this is the size of the compressed archive\n    file_size_mb = file.stat().st_size \u002F (1024 * 1024)\n    if file_size_mb > MAX_FILE_SIZE_MB:\n        raise ValueError(\n            f\"File size ({file_size_mb:.2f}MB) exceeds maximum allowed size of {MAX_FILE_SIZE_MB}MB\"\n        )\n\n    # Prepare the request\n    headers = {\n        \"X-API-Key\": api_key\n    }\n\n    params = {\n        \"businessUnitId\": business_unit_id\n    }\n\n    # Open and upload the file (content type is inferred from the file name)\n    content_type = mimetypes.guess_type(file.name)[0] or 'application\u002Foctet-stream'\n    with open(file_path, 'rb') as f:\n        files = {\n            'file': (file.name, f, content_type)\n        }\n\n        response = requests.put(\n            API_URL,\n            headers=headers,\n            params=params,\n            files=files\n        )\n\n    # Raise exception for HTTP errors\n    response.raise_for_status()\n\n    return response.json()\n\n# Example usage\nif __name__ == \"__main__\":\n    try:\n        result = upload_file(FILE_PATH, BUSINESS_UNIT_ID, API_KEY)\n        print(\"Upload successful!\")\n        print(f\"File ID: {result['fileId']}\")\n        print(f\"File Name: {result['fileName']}\")\n        print(f\"Business Unit ID: {result['businessUnitId']}\")\n    except FileNotFoundError as e:\n        print(f\"Error: {e}\")\n    except ValueError as e:\n        print(f\"Validation Error: {e}\")\n    except requests.exceptions.HTTPError as e:\n        print(f\"HTTP Error: {e}\")\n        if e.response.status_code == 400:\n            print(f\"Validation failed: {e.response.json()}\")\n        elif e.response.status_code == 401:\n            print(\"Authentication failed - check your API key\")\n        elif e.response.status_code == 500:\n            print(f\"Server error: {e.response.json()}\")\n    except Exception as e:\n        print(f\"Unexpected error: {e}\")\n","python",[229,1078,1079,1084,1089,1094,1098,1103,1108,1113,1118,1123,1127,1133,1139,1144,1150,1156,1162,1167,1173,1179,1184,1190,1196,1202,1208,1213,1219,1225,1230,1236,1242,1247,1253,1259,1265,1271,1276,1282,1288,1294,1299,1305,1311,1317,1323,1329,1335,1340,1346,1352,1358,1364,1369,1375,1381,1386,1391,1397,1403,1409,1415,1421,1427,1432,1438,1444,1450,1456,1462,1467,1472,1478,1484,1489,1495,1500,1506,1512,1518,1524,1530,1536,1542,1548,1554,1560,1566,1572,1578,1584,1590,1596,1602,1608,1614,1620,1626],{"__ignoreMap":580},[768,1080,1081],{"class":770,"line":771},[768,1082,1083],{},"import mimetypes\n",[768,1085,1086],{"class":770,"line":778},[768,1087,1088],{},"import requests\n",[768,1090,1091],{"class":770,"line":806},[768,1092,1093],{},"from pathlib import Path\n",[768,1095,1096],{"class":770,"line":827},[768,1097,932],{"emptyLinePlaceholder":931},[768,1099,1100],{"class":770,"line":846},[768,1101,1102],{},"# Configuration\n",[768,1104,1105],{"class":770,"line":979},[768,1106,1107],{},"API_KEY = \"your-api-key-here\"\n",[768,1109,1110],{"class":770,"line":994},[768,1111,1112],{},"BUSINESS_UNIT_ID = \"your-business-unit-id-here\"\n",[768,1114,1115],{"class":770,"line":999},[768,1116,1117],{},"FILE_PATH = \"\u002Fpath\u002Fto\u002Fyour\u002Ffile.xlsx\"\n",[768,1119,1120],{"class":770,"line":1034},[768,1121,1122],{},"API_URL = \"https:\u002F\u002Fapi-data-ingestion.deducta.ai\u002Fm2m\u002Fapi\u002Ffile\u002Fupload\"\n",[768,1124,1125],{"class":770,"line":1053},[768,1126,932],{"emptyLinePlaceholder":931},[768,1128,1130],{"class":770,"line":1129},11,[768,1131,1132],{},"ACCEPTED_EXTENSIONS = {\".xlsx\", \".parquet\", \".csv\", \".zip\"}\n",[768,1134,1136],{"class":770,"line":1135},12,[768,1137,1138],{},"MAX_FILE_SIZE_MB = 50\n",[768,1140,1142],{"class":770,"line":1141},13,[768,1143,932],{"emptyLinePlaceholder":931},[768,1145,1147],{"class":770,"line":1146},14,[768,1148,1149],{},"def upload_file(file_path, business_unit_id, api_key):\n",[768,1151,1153],{"class":770,"line":1152},15,[768,1154,1155],{},"    \"\"\"\n",[768,1157,1159],{"class":770,"line":1158},16,[768,1160,1161],{},"    Upload a data file to the Deducta Data Ingestion API.\n",[768,1163,1165],{"class":770,"line":1164},17,[768,1166,932],{"emptyLinePlaceholder":931},[768,1168,1170],{"class":770,"line":1169},18,[768,1171,1172],{},"    Accepts .xlsx, .parquet, .csv, and .zip files; Excel and Parquet are\n",[768,1174,1176],{"class":770,"line":1175},19,[768,1177,1178],{},"    preferred. Use a .zip archive to upload a batch of files in one request.\n",[768,1180,1182],{"class":770,"line":1181},20,[768,1183,932],{"emptyLinePlaceholder":931},[768,1185,1187],{"class":770,"line":1186},21,[768,1188,1189],{},"    Args:\n",[768,1191,1193],{"class":770,"line":1192},22,[768,1194,1195],{},"        file_path (str): Path to the file to upload\n",[768,1197,1199],{"class":770,"line":1198},23,[768,1200,1201],{},"        business_unit_id (str): GUID of the business unit\n",[768,1203,1205],{"class":770,"line":1204},24,[768,1206,1207],{},"        api_key (str): API key for authentication\n",[768,1209,1211],{"class":770,"line":1210},25,[768,1212,932],{"emptyLinePlaceholder":931},[768,1214,1216],{"class":770,"line":1215},26,[768,1217,1218],{},"    Returns:\n",[768,1220,1222],{"class":770,"line":1221},27,[768,1223,1224],{},"        dict: Response containing fileId, fileName, and businessUnitId\n",[768,1226,1228],{"class":770,"line":1227},28,[768,1229,932],{"emptyLinePlaceholder":931},[768,1231,1233],{"class":770,"line":1232},29,[768,1234,1235],{},"    Raises:\n",[768,1237,1239],{"class":770,"line":1238},30,[768,1240,1241],{},"        requests.exceptions.HTTPError: If the request fails\n",[768,1243,1245],{"class":770,"line":1244},31,[768,1246,1155],{},[768,1248,1250],{"class":770,"line":1249},32,[768,1251,1252],{},"    # Validate file exists\n",[768,1254,1256],{"class":770,"line":1255},33,[768,1257,1258],{},"    file = Path(file_path)\n",[768,1260,1262],{"class":770,"line":1261},34,[768,1263,1264],{},"    if not file.exists():\n",[768,1266,1268],{"class":770,"line":1267},35,[768,1269,1270],{},"        raise FileNotFoundError(f\"File not found: {file_path}\")\n",[768,1272,1274],{"class":770,"line":1273},36,[768,1275,932],{"emptyLinePlaceholder":931},[768,1277,1279],{"class":770,"line":1278},37,[768,1280,1281],{},"    # Validate file format\n",[768,1283,1285],{"class":770,"line":1284},38,[768,1286,1287],{},"    if file.suffix.lower() not in ACCEPTED_EXTENSIONS:\n",[768,1289,1291],{"class":770,"line":1290},39,[768,1292,1293],{},"        raise ValueError(f\"Unsupported file format: {file.suffix}\")\n",[768,1295,1297],{"class":770,"line":1296},40,[768,1298,932],{"emptyLinePlaceholder":931},[768,1300,1302],{"class":770,"line":1301},41,[768,1303,1304],{},"    # Check file size — for a .zip this is the size of the compressed archive\n",[768,1306,1308],{"class":770,"line":1307},42,[768,1309,1310],{},"    file_size_mb = file.stat().st_size \u002F (1024 * 1024)\n",[768,1312,1314],{"class":770,"line":1313},43,[768,1315,1316],{},"    if file_size_mb > MAX_FILE_SIZE_MB:\n",[768,1318,1320],{"class":770,"line":1319},44,[768,1321,1322],{},"        raise ValueError(\n",[768,1324,1326],{"class":770,"line":1325},45,[768,1327,1328],{},"            f\"File size ({file_size_mb:.2f}MB) exceeds maximum allowed size of {MAX_FILE_SIZE_MB}MB\"\n",[768,1330,1332],{"class":770,"line":1331},46,[768,1333,1334],{},"        )\n",[768,1336,1338],{"class":770,"line":1337},47,[768,1339,932],{"emptyLinePlaceholder":931},[768,1341,1343],{"class":770,"line":1342},48,[768,1344,1345],{},"    # Prepare the request\n",[768,1347,1349],{"class":770,"line":1348},49,[768,1350,1351],{},"    headers = {\n",[768,1353,1355],{"class":770,"line":1354},50,[768,1356,1357],{},"        \"X-API-Key\": api_key\n",[768,1359,1361],{"class":770,"line":1360},51,[768,1362,1363],{},"    }\n",[768,1365,1367],{"class":770,"line":1366},52,[768,1368,932],{"emptyLinePlaceholder":931},[768,1370,1372],{"class":770,"line":1371},53,[768,1373,1374],{},"    params = {\n",[768,1376,1378],{"class":770,"line":1377},54,[768,1379,1380],{},"        \"businessUnitId\": business_unit_id\n",[768,1382,1384],{"class":770,"line":1383},55,[768,1385,1363],{},[768,1387,1389],{"class":770,"line":1388},56,[768,1390,932],{"emptyLinePlaceholder":931},[768,1392,1394],{"class":770,"line":1393},57,[768,1395,1396],{},"    # Open and upload the file (content type is inferred from the file name)\n",[768,1398,1400],{"class":770,"line":1399},58,[768,1401,1402],{},"    content_type = mimetypes.guess_type(file.name)[0] or 'application\u002Foctet-stream'\n",[768,1404,1406],{"class":770,"line":1405},59,[768,1407,1408],{},"    with open(file_path, 'rb') as f:\n",[768,1410,1412],{"class":770,"line":1411},60,[768,1413,1414],{},"        files = {\n",[768,1416,1418],{"class":770,"line":1417},61,[768,1419,1420],{},"            'file': (file.name, f, content_type)\n",[768,1422,1424],{"class":770,"line":1423},62,[768,1425,1426],{},"        }\n",[768,1428,1430],{"class":770,"line":1429},63,[768,1431,932],{"emptyLinePlaceholder":931},[768,1433,1435],{"class":770,"line":1434},64,[768,1436,1437],{},"        response = requests.put(\n",[768,1439,1441],{"class":770,"line":1440},65,[768,1442,1443],{},"            API_URL,\n",[768,1445,1447],{"class":770,"line":1446},66,[768,1448,1449],{},"            headers=headers,\n",[768,1451,1453],{"class":770,"line":1452},67,[768,1454,1455],{},"            params=params,\n",[768,1457,1459],{"class":770,"line":1458},68,[768,1460,1461],{},"            files=files\n",[768,1463,1465],{"class":770,"line":1464},69,[768,1466,1334],{},[768,1468,1470],{"class":770,"line":1469},70,[768,1471,932],{"emptyLinePlaceholder":931},[768,1473,1475],{"class":770,"line":1474},71,[768,1476,1477],{},"    # Raise exception for HTTP errors\n",[768,1479,1481],{"class":770,"line":1480},72,[768,1482,1483],{},"    response.raise_for_status()\n",[768,1485,1487],{"class":770,"line":1486},73,[768,1488,932],{"emptyLinePlaceholder":931},[768,1490,1492],{"class":770,"line":1491},74,[768,1493,1494],{},"    return response.json()\n",[768,1496,1498],{"class":770,"line":1497},75,[768,1499,932],{"emptyLinePlaceholder":931},[768,1501,1503],{"class":770,"line":1502},76,[768,1504,1505],{},"# Example usage\n",[768,1507,1509],{"class":770,"line":1508},77,[768,1510,1511],{},"if __name__ == \"__main__\":\n",[768,1513,1515],{"class":770,"line":1514},78,[768,1516,1517],{},"    try:\n",[768,1519,1521],{"class":770,"line":1520},79,[768,1522,1523],{},"        result = upload_file(FILE_PATH, BUSINESS_UNIT_ID, API_KEY)\n",[768,1525,1527],{"class":770,"line":1526},80,[768,1528,1529],{},"        print(\"Upload successful!\")\n",[768,1531,1533],{"class":770,"line":1532},81,[768,1534,1535],{},"        print(f\"File ID: {result['fileId']}\")\n",[768,1537,1539],{"class":770,"line":1538},82,[768,1540,1541],{},"        print(f\"File Name: {result['fileName']}\")\n",[768,1543,1545],{"class":770,"line":1544},83,[768,1546,1547],{},"        print(f\"Business Unit ID: {result['businessUnitId']}\")\n",[768,1549,1551],{"class":770,"line":1550},84,[768,1552,1553],{},"    except FileNotFoundError as e:\n",[768,1555,1557],{"class":770,"line":1556},85,[768,1558,1559],{},"        print(f\"Error: {e}\")\n",[768,1561,1563],{"class":770,"line":1562},86,[768,1564,1565],{},"    except ValueError as e:\n",[768,1567,1569],{"class":770,"line":1568},87,[768,1570,1571],{},"        print(f\"Validation Error: {e}\")\n",[768,1573,1575],{"class":770,"line":1574},88,[768,1576,1577],{},"    except requests.exceptions.HTTPError as e:\n",[768,1579,1581],{"class":770,"line":1580},89,[768,1582,1583],{},"        print(f\"HTTP Error: {e}\")\n",[768,1585,1587],{"class":770,"line":1586},90,[768,1588,1589],{},"        if e.response.status_code == 400:\n",[768,1591,1593],{"class":770,"line":1592},91,[768,1594,1595],{},"            print(f\"Validation failed: {e.response.json()}\")\n",[768,1597,1599],{"class":770,"line":1598},92,[768,1600,1601],{},"        elif e.response.status_code == 401:\n",[768,1603,1605],{"class":770,"line":1604},93,[768,1606,1607],{},"            print(\"Authentication failed - check your API key\")\n",[768,1609,1611],{"class":770,"line":1610},94,[768,1612,1613],{},"        elif e.response.status_code == 500:\n",[768,1615,1617],{"class":770,"line":1616},95,[768,1618,1619],{},"            print(f\"Server error: {e.response.json()}\")\n",[768,1621,1623],{"class":770,"line":1622},96,[768,1624,1625],{},"    except Exception as e:\n",[768,1627,1629],{"class":770,"line":1628},97,[768,1630,1631],{},"        print(f\"Unexpected error: {e}\")\n",[190,1633,1635],{"summary":1634},"C#",[760,1636,1640],{"className":1637,"code":1638,"language":1639,"meta":580,"style":580},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Threading.Tasks;\nusing System.Text.Json;\n\npublic class FileUploadClient\n{\n    private readonly HttpClient _httpClient;\n    private readonly string _apiKey;\n    private const long MaxFileSizeBytes = 50 * 1024 * 1024; \u002F\u002F 50MB\n\n    private static readonly HashSet\u003Cstring> AcceptedExtensions = new(StringComparer.OrdinalIgnoreCase)\n    {\n        \".xlsx\", \".parquet\", \".csv\", \".zip\"\n    };\n\n    public FileUploadClient(string baseUrl, string apiKey)\n    {\n        _httpClient = new HttpClient { BaseAddress = new Uri(baseUrl) };\n        _apiKey = apiKey;\n    }\n\n    public async Task\u003CFileUploadResponse> UploadFileAsync(\n        string filePath,\n        Guid businessUnitId)\n    {\n        \u002F\u002F Validate file exists\n        if (!File.Exists(filePath))\n        {\n            throw new FileNotFoundException(\"File not found\", filePath);\n        }\n\n        \u002F\u002F Validate file format\n        var extension = Path.GetExtension(filePath);\n        if (!AcceptedExtensions.Contains(extension))\n        {\n            throw new ArgumentException($\"Unsupported file format: {extension}\");\n        }\n\n        \u002F\u002F Validate file size — for a .zip this is the size of the compressed archive\n        var fileInfo = new FileInfo(filePath);\n        if (fileInfo.Length > MaxFileSizeBytes)\n        {\n            throw new ArgumentException(\n                $\"File size ({fileInfo.Length \u002F 1024 \u002F 1024}MB) exceeds maximum allowed size of 50MB\");\n        }\n\n        \u002F\u002F Validate businessUnitId\n        if (businessUnitId == Guid.Empty)\n        {\n            throw new ArgumentException(\"businessUnitId cannot be empty\");\n        }\n\n        \u002F\u002F Prepare the multipart form data\n        using var content = new MultipartFormDataContent();\n        using var fileStream = File.OpenRead(filePath);\n        using var streamContent = new StreamContent(fileStream);\n\n        streamContent.Headers.ContentType = new MediaTypeHeaderValue(\"application\u002Foctet-stream\");\n\n        content.Add(streamContent, \"file\", Path.GetFileName(filePath));\n\n        \u002F\u002F Prepare the request\n        var requestUri = $\"\u002Fapi\u002Ffile\u002Fupload?businessUnitId={businessUnitId}\";\n        var request = new HttpRequestMessage(HttpMethod.Put, requestUri)\n        {\n            Content = content\n        };\n        request.Headers.Add(\"X-API-Key\", _apiKey);\n\n        \u002F\u002F Send the request\n        var response = await _httpClient.SendAsync(request);\n\n        \u002F\u002F Parse response\n        var responseContent = await response.Content.ReadAsStringAsync();\n\n        if (!response.IsSuccessStatusCode)\n        {\n            throw new HttpRequestException(\n                $\"Upload failed with status {response.StatusCode}: {responseContent}\");\n        }\n\n        return JsonSerializer.Deserialize\u003CFileUploadResponse>(responseContent);\n    }\n}\n\npublic class FileUploadResponse\n{\n    public Guid FileId { get; set; }\n    public string FileName { get; set; }\n    public Guid BusinessUnitId { get; set; }\n}\n\n\u002F\u002F Example usage\npublic class Program\n{\n    public static async Task Main(string[] args)\n    {\n        var apiKey = \"your-api-key-here\";\n        var businessUnitId = Guid.Parse(\"your-business-unit-id-here\");\n        var filePath = @\"C:\\path\\to\\your\\file.xlsx\";\n        var apiUrl = \"https:\u002F\u002Fapi-data-ingestion.deducta.ai\u002Fm2m\";\n\n        var client = new FileUploadClient(apiUrl, apiKey);\n\n        try\n        {\n            var result = await client.UploadFileAsync(filePath, businessUnitId);\n\n            Console.WriteLine(\"Upload successful!\");\n            Console.WriteLine($\"File ID: {result.FileId}\");\n            Console.WriteLine($\"File Name: {result.FileName}\");\n            Console.WriteLine($\"Business Unit ID: {result.BusinessUnitId}\");\n        }\n        catch (FileNotFoundException ex)\n        {\n            Console.WriteLine($\"Error: {ex.Message}\");\n        }\n        catch (ArgumentException ex)\n        {\n            Console.WriteLine($\"Validation Error: {ex.Message}\");\n        }\n        catch (HttpRequestException ex)\n        {\n            Console.WriteLine($\"HTTP Error: {ex.Message}\");\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($\"Unexpected error: {ex.Message}\");\n        }\n    }\n}\n","csharp",[229,1641,1642,1647,1652,1657,1662,1667,1672,1677,1681,1686,1690,1695,1700,1705,1709,1714,1719,1724,1729,1733,1738,1742,1747,1752,1756,1760,1765,1770,1775,1779,1784,1789,1794,1799,1803,1807,1812,1817,1822,1826,1831,1835,1839,1844,1849,1854,1858,1863,1868,1872,1876,1881,1886,1890,1895,1899,1903,1908,1913,1918,1923,1927,1932,1936,1941,1945,1950,1955,1960,1964,1969,1974,1979,1983,1988,1993,1997,2002,2007,2011,2016,2020,2025,2030,2034,2038,2043,2047,2051,2055,2060,2064,2069,2074,2079,2083,2087,2092,2098,2103,2109,2114,2120,2126,2132,2138,2143,2149,2154,2160,2165,2171,2176,2182,2188,2194,2200,2205,2211,2216,2222,2227,2233,2238,2244,2249,2255,2260,2266,2271,2277,2282,2288,2293,2298],{"__ignoreMap":580},[768,1643,1644],{"class":770,"line":771},[768,1645,1646],{},"using System;\n",[768,1648,1649],{"class":770,"line":778},[768,1650,1651],{},"using System.Collections.Generic;\n",[768,1653,1654],{"class":770,"line":806},[768,1655,1656],{},"using System.IO;\n",[768,1658,1659],{"class":770,"line":827},[768,1660,1661],{},"using System.Net.Http;\n",[768,1663,1664],{"class":770,"line":846},[768,1665,1666],{},"using System.Net.Http.Headers;\n",[768,1668,1669],{"class":770,"line":979},[768,1670,1671],{},"using System.Threading.Tasks;\n",[768,1673,1674],{"class":770,"line":994},[768,1675,1676],{},"using System.Text.Json;\n",[768,1678,1679],{"class":770,"line":999},[768,1680,932],{"emptyLinePlaceholder":931},[768,1682,1683],{"class":770,"line":1034},[768,1684,1685],{},"public class FileUploadClient\n",[768,1687,1688],{"class":770,"line":1053},[768,1689,775],{},[768,1691,1692],{"class":770,"line":1129},[768,1693,1694],{},"    private readonly HttpClient _httpClient;\n",[768,1696,1697],{"class":770,"line":1135},[768,1698,1699],{},"    private readonly string _apiKey;\n",[768,1701,1702],{"class":770,"line":1141},[768,1703,1704],{},"    private const long MaxFileSizeBytes = 50 * 1024 * 1024; \u002F\u002F 50MB\n",[768,1706,1707],{"class":770,"line":1146},[768,1708,932],{"emptyLinePlaceholder":931},[768,1710,1711],{"class":770,"line":1152},[768,1712,1713],{},"    private static readonly HashSet\u003Cstring> AcceptedExtensions = new(StringComparer.OrdinalIgnoreCase)\n",[768,1715,1716],{"class":770,"line":1158},[768,1717,1718],{},"    {\n",[768,1720,1721],{"class":770,"line":1164},[768,1722,1723],{},"        \".xlsx\", \".parquet\", \".csv\", \".zip\"\n",[768,1725,1726],{"class":770,"line":1169},[768,1727,1728],{},"    };\n",[768,1730,1731],{"class":770,"line":1175},[768,1732,932],{"emptyLinePlaceholder":931},[768,1734,1735],{"class":770,"line":1181},[768,1736,1737],{},"    public FileUploadClient(string baseUrl, string apiKey)\n",[768,1739,1740],{"class":770,"line":1186},[768,1741,1718],{},[768,1743,1744],{"class":770,"line":1192},[768,1745,1746],{},"        _httpClient = new HttpClient { BaseAddress = new Uri(baseUrl) };\n",[768,1748,1749],{"class":770,"line":1198},[768,1750,1751],{},"        _apiKey = apiKey;\n",[768,1753,1754],{"class":770,"line":1204},[768,1755,1363],{},[768,1757,1758],{"class":770,"line":1210},[768,1759,932],{"emptyLinePlaceholder":931},[768,1761,1762],{"class":770,"line":1215},[768,1763,1764],{},"    public async Task\u003CFileUploadResponse> UploadFileAsync(\n",[768,1766,1767],{"class":770,"line":1221},[768,1768,1769],{},"        string filePath,\n",[768,1771,1772],{"class":770,"line":1227},[768,1773,1774],{},"        Guid businessUnitId)\n",[768,1776,1777],{"class":770,"line":1232},[768,1778,1718],{},[768,1780,1781],{"class":770,"line":1238},[768,1782,1783],{},"        \u002F\u002F Validate file exists\n",[768,1785,1786],{"class":770,"line":1244},[768,1787,1788],{},"        if (!File.Exists(filePath))\n",[768,1790,1791],{"class":770,"line":1249},[768,1792,1793],{},"        {\n",[768,1795,1796],{"class":770,"line":1255},[768,1797,1798],{},"            throw new FileNotFoundException(\"File not found\", filePath);\n",[768,1800,1801],{"class":770,"line":1261},[768,1802,1426],{},[768,1804,1805],{"class":770,"line":1267},[768,1806,932],{"emptyLinePlaceholder":931},[768,1808,1809],{"class":770,"line":1273},[768,1810,1811],{},"        \u002F\u002F Validate file format\n",[768,1813,1814],{"class":770,"line":1278},[768,1815,1816],{},"        var extension = Path.GetExtension(filePath);\n",[768,1818,1819],{"class":770,"line":1284},[768,1820,1821],{},"        if (!AcceptedExtensions.Contains(extension))\n",[768,1823,1824],{"class":770,"line":1290},[768,1825,1793],{},[768,1827,1828],{"class":770,"line":1296},[768,1829,1830],{},"            throw new ArgumentException($\"Unsupported file format: {extension}\");\n",[768,1832,1833],{"class":770,"line":1301},[768,1834,1426],{},[768,1836,1837],{"class":770,"line":1307},[768,1838,932],{"emptyLinePlaceholder":931},[768,1840,1841],{"class":770,"line":1313},[768,1842,1843],{},"        \u002F\u002F Validate file size — for a .zip this is the size of the compressed archive\n",[768,1845,1846],{"class":770,"line":1319},[768,1847,1848],{},"        var fileInfo = new FileInfo(filePath);\n",[768,1850,1851],{"class":770,"line":1325},[768,1852,1853],{},"        if (fileInfo.Length > MaxFileSizeBytes)\n",[768,1855,1856],{"class":770,"line":1331},[768,1857,1793],{},[768,1859,1860],{"class":770,"line":1337},[768,1861,1862],{},"            throw new ArgumentException(\n",[768,1864,1865],{"class":770,"line":1342},[768,1866,1867],{},"                $\"File size ({fileInfo.Length \u002F 1024 \u002F 1024}MB) exceeds maximum allowed size of 50MB\");\n",[768,1869,1870],{"class":770,"line":1348},[768,1871,1426],{},[768,1873,1874],{"class":770,"line":1354},[768,1875,932],{"emptyLinePlaceholder":931},[768,1877,1878],{"class":770,"line":1360},[768,1879,1880],{},"        \u002F\u002F Validate businessUnitId\n",[768,1882,1883],{"class":770,"line":1366},[768,1884,1885],{},"        if (businessUnitId == Guid.Empty)\n",[768,1887,1888],{"class":770,"line":1371},[768,1889,1793],{},[768,1891,1892],{"class":770,"line":1377},[768,1893,1894],{},"            throw new ArgumentException(\"businessUnitId cannot be empty\");\n",[768,1896,1897],{"class":770,"line":1383},[768,1898,1426],{},[768,1900,1901],{"class":770,"line":1388},[768,1902,932],{"emptyLinePlaceholder":931},[768,1904,1905],{"class":770,"line":1393},[768,1906,1907],{},"        \u002F\u002F Prepare the multipart form data\n",[768,1909,1910],{"class":770,"line":1399},[768,1911,1912],{},"        using var content = new MultipartFormDataContent();\n",[768,1914,1915],{"class":770,"line":1405},[768,1916,1917],{},"        using var fileStream = File.OpenRead(filePath);\n",[768,1919,1920],{"class":770,"line":1411},[768,1921,1922],{},"        using var streamContent = new StreamContent(fileStream);\n",[768,1924,1925],{"class":770,"line":1417},[768,1926,932],{"emptyLinePlaceholder":931},[768,1928,1929],{"class":770,"line":1423},[768,1930,1931],{},"        streamContent.Headers.ContentType = new MediaTypeHeaderValue(\"application\u002Foctet-stream\");\n",[768,1933,1934],{"class":770,"line":1429},[768,1935,932],{"emptyLinePlaceholder":931},[768,1937,1938],{"class":770,"line":1434},[768,1939,1940],{},"        content.Add(streamContent, \"file\", Path.GetFileName(filePath));\n",[768,1942,1943],{"class":770,"line":1440},[768,1944,932],{"emptyLinePlaceholder":931},[768,1946,1947],{"class":770,"line":1446},[768,1948,1949],{},"        \u002F\u002F Prepare the request\n",[768,1951,1952],{"class":770,"line":1452},[768,1953,1954],{},"        var requestUri = $\"\u002Fapi\u002Ffile\u002Fupload?businessUnitId={businessUnitId}\";\n",[768,1956,1957],{"class":770,"line":1458},[768,1958,1959],{},"        var request = new HttpRequestMessage(HttpMethod.Put, requestUri)\n",[768,1961,1962],{"class":770,"line":1464},[768,1963,1793],{},[768,1965,1966],{"class":770,"line":1469},[768,1967,1968],{},"            Content = content\n",[768,1970,1971],{"class":770,"line":1474},[768,1972,1973],{},"        };\n",[768,1975,1976],{"class":770,"line":1480},[768,1977,1978],{},"        request.Headers.Add(\"X-API-Key\", _apiKey);\n",[768,1980,1981],{"class":770,"line":1486},[768,1982,932],{"emptyLinePlaceholder":931},[768,1984,1985],{"class":770,"line":1491},[768,1986,1987],{},"        \u002F\u002F Send the request\n",[768,1989,1990],{"class":770,"line":1497},[768,1991,1992],{},"        var response = await _httpClient.SendAsync(request);\n",[768,1994,1995],{"class":770,"line":1502},[768,1996,932],{"emptyLinePlaceholder":931},[768,1998,1999],{"class":770,"line":1508},[768,2000,2001],{},"        \u002F\u002F Parse response\n",[768,2003,2004],{"class":770,"line":1514},[768,2005,2006],{},"        var responseContent = await response.Content.ReadAsStringAsync();\n",[768,2008,2009],{"class":770,"line":1520},[768,2010,932],{"emptyLinePlaceholder":931},[768,2012,2013],{"class":770,"line":1526},[768,2014,2015],{},"        if (!response.IsSuccessStatusCode)\n",[768,2017,2018],{"class":770,"line":1532},[768,2019,1793],{},[768,2021,2022],{"class":770,"line":1538},[768,2023,2024],{},"            throw new HttpRequestException(\n",[768,2026,2027],{"class":770,"line":1544},[768,2028,2029],{},"                $\"Upload failed with status {response.StatusCode}: {responseContent}\");\n",[768,2031,2032],{"class":770,"line":1550},[768,2033,1426],{},[768,2035,2036],{"class":770,"line":1556},[768,2037,932],{"emptyLinePlaceholder":931},[768,2039,2040],{"class":770,"line":1562},[768,2041,2042],{},"        return JsonSerializer.Deserialize\u003CFileUploadResponse>(responseContent);\n",[768,2044,2045],{"class":770,"line":1568},[768,2046,1363],{},[768,2048,2049],{"class":770,"line":1574},[768,2050,849],{},[768,2052,2053],{"class":770,"line":1580},[768,2054,932],{"emptyLinePlaceholder":931},[768,2056,2057],{"class":770,"line":1586},[768,2058,2059],{},"public class FileUploadResponse\n",[768,2061,2062],{"class":770,"line":1592},[768,2063,775],{},[768,2065,2066],{"class":770,"line":1598},[768,2067,2068],{},"    public Guid FileId { get; set; }\n",[768,2070,2071],{"class":770,"line":1604},[768,2072,2073],{},"    public string FileName { get; set; }\n",[768,2075,2076],{"class":770,"line":1610},[768,2077,2078],{},"    public Guid BusinessUnitId { get; set; }\n",[768,2080,2081],{"class":770,"line":1616},[768,2082,849],{},[768,2084,2085],{"class":770,"line":1622},[768,2086,932],{"emptyLinePlaceholder":931},[768,2088,2089],{"class":770,"line":1628},[768,2090,2091],{},"\u002F\u002F Example usage\n",[768,2093,2095],{"class":770,"line":2094},98,[768,2096,2097],{},"public class Program\n",[768,2099,2101],{"class":770,"line":2100},99,[768,2102,775],{},[768,2104,2106],{"class":770,"line":2105},100,[768,2107,2108],{},"    public static async Task Main(string[] args)\n",[768,2110,2112],{"class":770,"line":2111},101,[768,2113,1718],{},[768,2115,2117],{"class":770,"line":2116},102,[768,2118,2119],{},"        var apiKey = \"your-api-key-here\";\n",[768,2121,2123],{"class":770,"line":2122},103,[768,2124,2125],{},"        var businessUnitId = Guid.Parse(\"your-business-unit-id-here\");\n",[768,2127,2129],{"class":770,"line":2128},104,[768,2130,2131],{},"        var filePath = @\"C:\\path\\to\\your\\file.xlsx\";\n",[768,2133,2135],{"class":770,"line":2134},105,[768,2136,2137],{},"        var apiUrl = \"https:\u002F\u002Fapi-data-ingestion.deducta.ai\u002Fm2m\";\n",[768,2139,2141],{"class":770,"line":2140},106,[768,2142,932],{"emptyLinePlaceholder":931},[768,2144,2146],{"class":770,"line":2145},107,[768,2147,2148],{},"        var client = new FileUploadClient(apiUrl, apiKey);\n",[768,2150,2152],{"class":770,"line":2151},108,[768,2153,932],{"emptyLinePlaceholder":931},[768,2155,2157],{"class":770,"line":2156},109,[768,2158,2159],{},"        try\n",[768,2161,2163],{"class":770,"line":2162},110,[768,2164,1793],{},[768,2166,2168],{"class":770,"line":2167},111,[768,2169,2170],{},"            var result = await client.UploadFileAsync(filePath, businessUnitId);\n",[768,2172,2174],{"class":770,"line":2173},112,[768,2175,932],{"emptyLinePlaceholder":931},[768,2177,2179],{"class":770,"line":2178},113,[768,2180,2181],{},"            Console.WriteLine(\"Upload successful!\");\n",[768,2183,2185],{"class":770,"line":2184},114,[768,2186,2187],{},"            Console.WriteLine($\"File ID: {result.FileId}\");\n",[768,2189,2191],{"class":770,"line":2190},115,[768,2192,2193],{},"            Console.WriteLine($\"File Name: {result.FileName}\");\n",[768,2195,2197],{"class":770,"line":2196},116,[768,2198,2199],{},"            Console.WriteLine($\"Business Unit ID: {result.BusinessUnitId}\");\n",[768,2201,2203],{"class":770,"line":2202},117,[768,2204,1426],{},[768,2206,2208],{"class":770,"line":2207},118,[768,2209,2210],{},"        catch (FileNotFoundException ex)\n",[768,2212,2214],{"class":770,"line":2213},119,[768,2215,1793],{},[768,2217,2219],{"class":770,"line":2218},120,[768,2220,2221],{},"            Console.WriteLine($\"Error: {ex.Message}\");\n",[768,2223,2225],{"class":770,"line":2224},121,[768,2226,1426],{},[768,2228,2230],{"class":770,"line":2229},122,[768,2231,2232],{},"        catch (ArgumentException ex)\n",[768,2234,2236],{"class":770,"line":2235},123,[768,2237,1793],{},[768,2239,2241],{"class":770,"line":2240},124,[768,2242,2243],{},"            Console.WriteLine($\"Validation Error: {ex.Message}\");\n",[768,2245,2247],{"class":770,"line":2246},125,[768,2248,1426],{},[768,2250,2252],{"class":770,"line":2251},126,[768,2253,2254],{},"        catch (HttpRequestException ex)\n",[768,2256,2258],{"class":770,"line":2257},127,[768,2259,1793],{},[768,2261,2263],{"class":770,"line":2262},128,[768,2264,2265],{},"            Console.WriteLine($\"HTTP Error: {ex.Message}\");\n",[768,2267,2269],{"class":770,"line":2268},129,[768,2270,1426],{},[768,2272,2274],{"class":770,"line":2273},130,[768,2275,2276],{},"        catch (Exception ex)\n",[768,2278,2280],{"class":770,"line":2279},131,[768,2281,1793],{},[768,2283,2285],{"class":770,"line":2284},132,[768,2286,2287],{},"            Console.WriteLine($\"Unexpected error: {ex.Message}\");\n",[768,2289,2291],{"class":770,"line":2290},133,[768,2292,1426],{},[768,2294,2296],{"class":770,"line":2295},134,[768,2297,1363],{},[768,2299,2301],{"class":770,"line":2300},135,[768,2302,849],{},[15,2304,2305],{},[197,2306,2307],{},"Best practices",[34,2309,2310,2313,2316,2322,2333],{},[37,2311,2312],{},"Keep the API key out of source code. Load it from an environment variable or a secrets manager.",[37,2314,2315],{},"Validate the format and size, and check the file is not empty, before uploading.",[37,2317,2318,2319,2321],{},"Send a ",[229,2320,269],{}," instead of many single-file requests when you have several files for the same business unit.",[37,2323,2324,2325,2328,2329,2332],{},"Retry ",[229,2326,2327],{},"5xx"," responses with exponential backoff. ",[229,2330,2331],{},"4xx"," responses are validation or authentication problems that retrying won't fix.",[37,2334,2335],{},"Set timeouts for large uploads.",[575,2337,2338,2344,2347,2351,2408,2414,2419,2430,2439,2442,2584,2718,2949,2954],{},[578,2339,2340],{"v-slot:title":580},[26,2341,2343],{"id":2342},"option-2-shared-storage-account","Option 2: Shared storage account",[15,2345,2346],{},"Deducta provisions a container in an Azure Blob Storage account for your organization. You authenticate with a client ID and secret, request a short-lived token, and upload over HTTPS.",[15,2348,2349],{},[197,2350,596],{},[66,2352,2353,2361],{},[69,2354,2355],{},[72,2356,2357,2359],{},[75,2358,605],{},[75,2360,608],{},[82,2362,2363,2371,2379,2387,2398],{},[72,2364,2365,2368],{},[87,2366,2367],{},"Tenant ID",[87,2369,2370],{},"Identifies the Microsoft Entra tenant to authenticate against",[72,2372,2373,2376],{},[87,2374,2375],{},"Client ID",[87,2377,2378],{},"Identifies your credential",[72,2380,2381,2384],{},[87,2382,2383],{},"Client secret",[87,2385,2386],{},"Sent separately through a one-time link",[72,2388,2389,2392],{},[87,2390,2391],{},"Storage account and container",[87,2393,2394,2395],{},"The upload URL: ",[229,2396,2397],{},"https:\u002F\u002F\u003Cstorage-account>.blob.core.windows.net\u002F\u003Ccontainer>\u002F",[72,2399,2400,2403],{},[87,2401,2402],{},"Token scope",[87,2404,2405],{},[229,2406,2407],{},"https:\u002F\u002Fstorage.azure.com\u002F.default",[15,2409,2410,2411,310],{},"Your credentials can read, write and delete files in ",[197,2412,2413],{},"your isolated container only",[15,2415,2416],{},[197,2417,2418],{},"What we need from you",[34,2420,2421,2424,2427],{},[37,2422,2423],{},"Name and email of your technical contact for uploads.",[37,2425,2426],{},"If we have agreed to restrict access by IP address, the static public IP address or addresses your uploads come from.",[37,2428,2429],{},"A message once your first upload is in, so we can confirm we can read it.",[15,2431,2432,2435,2436,310],{},[197,2433,2434],{},"Handle the secret like any other production credential."," Store it in a secrets manager such as Google Secret Manager, AWS Secrets Manager or Azure Key Vault, and load it at runtime. Never put it in code, configuration files or version control. The examples below read it from an environment variable named ",[229,2437,2438],{},"DEDUCTA_CLIENT_SECRET",[15,2440,2441],{},"Uploads never overwrite an existing file, so give each file a new name, for example by including the date.",[190,2443,2445,2454],{"summary":2444},"AzCopy (recommended)",[15,2446,2447,2453],{},[744,2448,2452],{"href":2449,"rel":2450},"https:\u002F\u002Flearn.microsoft.com\u002Fazure\u002Fstorage\u002Fcommon\u002Fstorage-use-azcopy-v10",[2451],"nofollow","AzCopy"," is Microsoft's command-line tool for Azure Storage. It handles large files, retries and parallel uploads, so it suits backfills and scheduled jobs. It signs in from the environment variables below, so there is no separate login step.",[760,2455,2457],{"className":916,"code":2456,"language":918,"meta":580,"style":580},"export AZCOPY_AUTO_LOGIN_TYPE=SPN\nexport AZCOPY_TENANT_ID=\"\u003Ctenant-id>\"\nexport AZCOPY_SPA_APPLICATION_ID=\"\u003Cclient-id>\"\nexport AZCOPY_SPA_CLIENT_SECRET=\"$DEDUCTA_CLIENT_SECRET\"\n\n# Upload a file without overwriting an existing one\nazcopy copy \"acme_spend_2026-09.parquet\" \\\n  \"https:\u002F\u002F\u003Cstorage-account>.blob.core.windows.net\u002F\u003Ccontainer>\u002F\" \\\n  --overwrite=false\n\n# List what is in the container\nazcopy list \"https:\u002F\u002F\u003Cstorage-account>.blob.core.windows.net\u002F\u003Ccontainer>\"\n",[229,2458,2459,2472,2488,2504,2520,2524,2529,2546,2556,2561,2565,2570],{"__ignoreMap":580},[768,2460,2461,2464,2467,2469],{"class":770,"line":771},[768,2462,2463],{"class":784},"export",[768,2465,2466],{"class":937}," AZCOPY_AUTO_LOGIN_TYPE",[768,2468,941],{"class":774},[768,2470,2471],{"class":937},"SPN\n",[768,2473,2474,2476,2479,2481,2483,2486],{"class":770,"line":778},[768,2475,2463],{"class":784},[768,2477,2478],{"class":937}," AZCOPY_TENANT_ID",[768,2480,941],{"class":774},[768,2482,788],{"class":774},[768,2484,2485],{"class":797},"\u003Ctenant-id>",[768,2487,843],{"class":774},[768,2489,2490,2492,2495,2497,2499,2502],{"class":770,"line":806},[768,2491,2463],{"class":784},[768,2493,2494],{"class":937}," AZCOPY_SPA_APPLICATION_ID",[768,2496,941],{"class":774},[768,2498,788],{"class":774},[768,2500,2501],{"class":797},"\u003Cclient-id>",[768,2503,843],{"class":774},[768,2505,2506,2508,2511,2513,2515,2518],{"class":770,"line":827},[768,2507,2463],{"class":784},[768,2509,2510],{"class":937}," AZCOPY_SPA_CLIENT_SECRET",[768,2512,941],{"class":774},[768,2514,788],{"class":774},[768,2516,2517],{"class":937},"$DEDUCTA_CLIENT_SECRET",[768,2519,843],{"class":774},[768,2521,2522],{"class":770,"line":846},[768,2523,932],{"emptyLinePlaceholder":931},[768,2525,2526],{"class":770,"line":979},[768,2527,2528],{"class":925},"# Upload a file without overwriting an existing one\n",[768,2530,2531,2534,2537,2539,2542,2544],{"class":770,"line":994},[768,2532,2533],{"class":1002},"azcopy",[768,2535,2536],{"class":797}," copy",[768,2538,794],{"class":774},[768,2540,2541],{"class":797},"acme_spend_2026-09.parquet",[768,2543,788],{"class":774},[768,2545,1031],{"class":937},[768,2547,2548,2550,2552,2554],{"class":770,"line":999},[768,2549,781],{"class":774},[768,2551,2397],{"class":797},[768,2553,788],{"class":774},[768,2555,1031],{"class":937},[768,2557,2558],{"class":770,"line":1034},[768,2559,2560],{"class":797},"  --overwrite=false\n",[768,2562,2563],{"class":770,"line":1053},[768,2564,932],{"emptyLinePlaceholder":931},[768,2566,2567],{"class":770,"line":1129},[768,2568,2569],{"class":925},"# List what is in the container\n",[768,2571,2572,2574,2577,2579,2582],{"class":770,"line":1135},[768,2573,2533],{"class":1002},[768,2575,2576],{"class":797}," list",[768,2578,794],{"class":774},[768,2580,2581],{"class":797},"https:\u002F\u002F\u003Cstorage-account>.blob.core.windows.net\u002F\u003Ccontainer>",[768,2583,843],{"class":774},[190,2585,2586,2589,2608],{"summary":1071},[15,2587,2588],{},"The SDK requests and refreshes tokens for you and splits large files into blocks automatically.",[760,2590,2592],{"className":916,"code":2591,"language":918,"meta":580,"style":580},"pip install azure-identity azure-storage-blob\n",[229,2593,2594],{"__ignoreMap":580},[768,2595,2596,2599,2602,2605],{"class":770,"line":771},[768,2597,2598],{"class":1002},"pip",[768,2600,2601],{"class":797}," install",[768,2603,2604],{"class":797}," azure-identity",[768,2606,2607],{"class":797}," azure-storage-blob\n",[760,2609,2611],{"className":1074,"code":2610,"language":1076,"meta":580,"style":580},"import os\n\nfrom azure.identity import ClientSecretCredential\nfrom azure.storage.blob import ContainerClient\n\ncredential = ClientSecretCredential(\n    tenant_id=\"\u003Ctenant-id>\",\n    client_id=\"\u003Cclient-id>\",\n    client_secret=os.environ[\"DEDUCTA_CLIENT_SECRET\"],\n)\ncontainer = ContainerClient(\n    account_url=\"https:\u002F\u002F\u003Cstorage-account>.blob.core.windows.net\",\n    container_name=\"\u003Ccontainer>\",\n    credential=credential,\n)\n\nlocal_path = \"acme_spend_2026-09.parquet\"\nwith open(local_path, \"rb\") as data:\n    container.upload_blob(name=os.path.basename(local_path), data=data, overwrite=False)\n\nfor blob in container.list_blobs():\n    print(blob.name, blob.size)\n",[229,2612,2613,2618,2622,2627,2632,2636,2641,2646,2651,2656,2661,2666,2671,2676,2681,2685,2689,2694,2699,2704,2708,2713],{"__ignoreMap":580},[768,2614,2615],{"class":770,"line":771},[768,2616,2617],{},"import os\n",[768,2619,2620],{"class":770,"line":778},[768,2621,932],{"emptyLinePlaceholder":931},[768,2623,2624],{"class":770,"line":806},[768,2625,2626],{},"from azure.identity import ClientSecretCredential\n",[768,2628,2629],{"class":770,"line":827},[768,2630,2631],{},"from azure.storage.blob import ContainerClient\n",[768,2633,2634],{"class":770,"line":846},[768,2635,932],{"emptyLinePlaceholder":931},[768,2637,2638],{"class":770,"line":979},[768,2639,2640],{},"credential = ClientSecretCredential(\n",[768,2642,2643],{"class":770,"line":994},[768,2644,2645],{},"    tenant_id=\"\u003Ctenant-id>\",\n",[768,2647,2648],{"class":770,"line":999},[768,2649,2650],{},"    client_id=\"\u003Cclient-id>\",\n",[768,2652,2653],{"class":770,"line":1034},[768,2654,2655],{},"    client_secret=os.environ[\"DEDUCTA_CLIENT_SECRET\"],\n",[768,2657,2658],{"class":770,"line":1053},[768,2659,2660],{},")\n",[768,2662,2663],{"class":770,"line":1129},[768,2664,2665],{},"container = ContainerClient(\n",[768,2667,2668],{"class":770,"line":1135},[768,2669,2670],{},"    account_url=\"https:\u002F\u002F\u003Cstorage-account>.blob.core.windows.net\",\n",[768,2672,2673],{"class":770,"line":1141},[768,2674,2675],{},"    container_name=\"\u003Ccontainer>\",\n",[768,2677,2678],{"class":770,"line":1146},[768,2679,2680],{},"    credential=credential,\n",[768,2682,2683],{"class":770,"line":1152},[768,2684,2660],{},[768,2686,2687],{"class":770,"line":1158},[768,2688,932],{"emptyLinePlaceholder":931},[768,2690,2691],{"class":770,"line":1164},[768,2692,2693],{},"local_path = \"acme_spend_2026-09.parquet\"\n",[768,2695,2696],{"class":770,"line":1169},[768,2697,2698],{},"with open(local_path, \"rb\") as data:\n",[768,2700,2701],{"class":770,"line":1175},[768,2702,2703],{},"    container.upload_blob(name=os.path.basename(local_path), data=data, overwrite=False)\n",[768,2705,2706],{"class":770,"line":1181},[768,2707,932],{"emptyLinePlaceholder":931},[768,2709,2710],{"class":770,"line":1186},[768,2711,2712],{},"for blob in container.list_blobs():\n",[768,2714,2715],{"class":770,"line":1192},[768,2716,2717],{},"    print(blob.name, blob.size)\n",[190,2719,2721,2724,2727,2831,2846],{"summary":2720},"REST (curl)",[15,2722,2723],{},"Use this if you can't install AzCopy or the SDK. A single request uploads up to 5,000 MiB; use AzCopy or the SDK for anything larger.",[15,2725,2726],{},"Step 1: request an access token, valid for about an hour.",[760,2728,2730],{"className":916,"code":2729,"language":918,"meta":580,"style":580},"TOKEN=$(curl -s -X POST \\\n  \"https:\u002F\u002Flogin.microsoftonline.com\u002F\u003Ctenant-id>\u002Foauth2\u002Fv2.0\u002Ftoken\" \\\n  -d \"grant_type=client_credentials\" \\\n  -d \"client_id=\u003Cclient-id>\" \\\n  --data-urlencode \"client_secret=$DEDUCTA_CLIENT_SECRET\" \\\n  -d \"scope=https:\u002F\u002Fstorage.azure.com\u002F.default\" | jq -r .access_token)\n",[229,2731,2732,2752,2763,2777,2790,2806],{"__ignoreMap":580},[768,2733,2734,2737,2740,2742,2745,2747,2750],{"class":770,"line":771},[768,2735,2736],{"class":937},"TOKEN",[768,2738,2739],{"class":774},"=$(",[768,2741,1003],{"class":1002},[768,2743,2744],{"class":797}," -s",[768,2746,1006],{"class":797},[768,2748,2749],{"class":797}," POST",[768,2751,1031],{"class":937},[768,2753,2754,2756,2759,2761],{"class":770,"line":778},[768,2755,781],{"class":774},[768,2757,2758],{"class":797},"https:\u002F\u002Flogin.microsoftonline.com\u002F\u003Ctenant-id>\u002Foauth2\u002Fv2.0\u002Ftoken",[768,2760,788],{"class":774},[768,2762,1031],{"class":937},[768,2764,2765,2768,2770,2773,2775],{"class":770,"line":806},[768,2766,2767],{"class":797},"  -d",[768,2769,794],{"class":774},[768,2771,2772],{"class":797},"grant_type=client_credentials",[768,2774,788],{"class":774},[768,2776,1031],{"class":937},[768,2778,2779,2781,2783,2786,2788],{"class":770,"line":827},[768,2780,2767],{"class":797},[768,2782,794],{"class":774},[768,2784,2785],{"class":797},"client_id=\u003Cclient-id>",[768,2787,788],{"class":774},[768,2789,1031],{"class":937},[768,2791,2792,2795,2797,2800,2802,2804],{"class":770,"line":846},[768,2793,2794],{"class":797},"  --data-urlencode",[768,2796,794],{"class":774},[768,2798,2799],{"class":797},"client_secret=",[768,2801,2517],{"class":937},[768,2803,788],{"class":774},[768,2805,1031],{"class":937},[768,2807,2808,2810,2812,2815,2817,2820,2823,2826,2829],{"class":770,"line":979},[768,2809,2767],{"class":797},[768,2811,794],{"class":774},[768,2813,2814],{"class":797},"scope=https:\u002F\u002Fstorage.azure.com\u002F.default",[768,2816,788],{"class":774},[768,2818,2819],{"class":774}," |",[768,2821,2822],{"class":1002}," jq",[768,2824,2825],{"class":797}," -r",[768,2827,2828],{"class":797}," .access_token",[768,2830,2660],{"class":774},[15,2832,2833,2834,2837,2838,2841,2842,2845],{},"Step 2: upload the file. ",[229,2835,2836],{},"201"," means success; ",[229,2839,2840],{},"409"," means a file with that name already exists, which is what the ",[229,2843,2844],{},"If-None-Match"," header enforces.",[760,2847,2849],{"className":916,"code":2848,"language":918,"meta":580,"style":580},"curl -X PUT \\\n  \"https:\u002F\u002F\u003Cstorage-account>.blob.core.windows.net\u002F\u003Ccontainer>\u002Facme_spend_2026-09.parquet\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"x-ms-version: 2023-11-03\" \\\n  -H \"x-ms-blob-type: BlockBlob\" \\\n  -H \"If-None-Match: *\" \\\n  --data-binary @acme_spend_2026-09.parquet \\\n  -w \"%{http_code}\\n\"\n",[229,2850,2851,2861,2872,2888,2901,2914,2927,2937],{"__ignoreMap":580},[768,2852,2853,2855,2857,2859],{"class":770,"line":771},[768,2854,1003],{"class":1002},[768,2856,1006],{"class":797},[768,2858,1009],{"class":797},[768,2860,1031],{"class":937},[768,2862,2863,2865,2868,2870],{"class":770,"line":778},[768,2864,781],{"class":774},[768,2866,2867],{"class":797},"https:\u002F\u002F\u003Cstorage-account>.blob.core.windows.net\u002F\u003Ccontainer>\u002Facme_spend_2026-09.parquet",[768,2869,788],{"class":774},[768,2871,1031],{"class":937},[768,2873,2874,2876,2878,2881,2884,2886],{"class":770,"line":806},[768,2875,1037],{"class":797},[768,2877,794],{"class":774},[768,2879,2880],{"class":797},"Authorization: Bearer ",[768,2882,2883],{"class":937},"$TOKEN",[768,2885,788],{"class":774},[768,2887,1031],{"class":937},[768,2889,2890,2892,2894,2897,2899],{"class":770,"line":827},[768,2891,1037],{"class":797},[768,2893,794],{"class":774},[768,2895,2896],{"class":797},"x-ms-version: 2023-11-03",[768,2898,788],{"class":774},[768,2900,1031],{"class":937},[768,2902,2903,2905,2907,2910,2912],{"class":770,"line":846},[768,2904,1037],{"class":797},[768,2906,794],{"class":774},[768,2908,2909],{"class":797},"x-ms-blob-type: BlockBlob",[768,2911,788],{"class":774},[768,2913,1031],{"class":937},[768,2915,2916,2918,2920,2923,2925],{"class":770,"line":979},[768,2917,1037],{"class":797},[768,2919,794],{"class":774},[768,2921,2922],{"class":797},"If-None-Match: *",[768,2924,788],{"class":774},[768,2926,1031],{"class":937},[768,2928,2929,2932,2935],{"class":770,"line":994},[768,2930,2931],{"class":797},"  --data-binary",[768,2933,2934],{"class":797}," @acme_spend_2026-09.parquet",[768,2936,1031],{"class":937},[768,2938,2939,2942,2944,2947],{"class":770,"line":999},[768,2940,2941],{"class":797},"  -w",[768,2943,794],{"class":774},[768,2945,2946],{"class":797},"%{http_code}\\n",[768,2948,843],{"class":774},[15,2950,2951],{},[197,2952,2953],{},"Troubleshooting",[66,2955,2956,2965],{},[69,2957,2958],{},[72,2959,2960,2963],{},[75,2961,2962],{},"Error",[75,2964,867],{},[82,2966,2967,2978,2989,3001,3011,3021],{},[72,2968,2969,2975],{},[87,2970,2971,2974],{},[229,2972,2973],{},"AADSTS7000215"," Invalid client secret",[87,2976,2977],{},"The secret value is wrong. Check for missing characters or extra whitespace.",[72,2979,2980,2986],{},[87,2981,2982,2985],{},[229,2983,2984],{},"AADSTS7000222"," Client secret expired",[87,2987,2988],{},"Ask your Deducta representative for a new secret.",[72,2990,2991,2996],{},[87,2992,2993],{},[229,2994,2995],{},"401 InvalidAuthenticationInfo",[87,2997,2998,2999,310],{},"The token expired (they last about an hour) or was requested for the wrong scope. Request a new one with ",[229,3000,2407],{},[72,3002,3003,3008],{},[87,3004,3005],{},[229,3006,3007],{},"403 AuthorizationPermissionMismatch",[87,3009,3010],{},"You are writing outside your container. Check the URL.",[72,3012,3013,3018],{},[87,3014,3015],{},[229,3016,3017],{},"403 AuthorizationFailure",[87,3019,3020],{},"The request came from an IP address we don't allow. Send us the public IP you upload from.",[72,3022,3023,3028],{},[87,3024,3025],{},[229,3026,3027],{},"409 BlobAlreadyExists",[87,3029,3030],{},"A file with that name was already uploaded. Use a different name.",[575,3032,3033,3039],{},[578,3034,3035],{"v-slot:title":580},[26,3036,3038],{"id":3037},"option-3-deducta-platform","Option 3: Deducta platform",[15,3040,3041,3042,3044],{},"For ad hoc events, sign in to the Deducta platform and upload an ",[229,3043,244],{}," file manually. Use this for one-off files; for anything recurring, prefer the API or the storage account.",[10,3046,3048],{"id":3047},"uploading-contracts","Uploading contracts",[15,3050,3051],{},"Contracts are sent as PDF documents through the same HTTP API as your data files, using the same API key and base URL. Unlike data files, a contract belongs to your organization, so no business unit ID is needed.",[66,3053,3054,3062],{},[69,3055,3056],{},[72,3057,3058,3060],{},[75,3059],{},[75,3061],{},[82,3063,3064,3073,3081,3093],{},[72,3065,3066,3068],{},[87,3067,662],{},[87,3069,3070],{},[229,3071,3072],{},"PUT \u002Fapi\u002Fcontract\u002Fupload",[72,3074,3075,3077],{},[87,3076,672],{},[87,3078,3079],{},[229,3080,677],{},[72,3082,3083,3087],{},[87,3084,3085,685],{},[229,3086,684],{},[87,3088,3089,3090,3092],{},"One ",[229,3091,282],{}," contract",[72,3094,3095,3097],{},[87,3096,520],{},[87,3098,3099],{},"256 MB per file",[34,3101,3102,3105,3108,3111],{},[37,3103,3104],{},"Send one contract per request. Contracts can't be zipped.",[37,3106,3107],{},"Scanned PDFs are fine.",[37,3109,3110],{},"Encrypted or password-protected PDFs are rejected, as are PDFs that contain embedded JavaScript, file attachments, launch actions, rich media or form submit actions.",[37,3112,3113],{},"The file name you send is kept as the contract's name, so use a descriptive one.",[15,3115,3116,3117,3119,3120,3122,3123,3125,3126,3128,3129,3131,3132,3134,3135,3122,3137,3139,3140,310],{},"A successful upload returns ",[229,3118,757],{}," with the ",[229,3121,785],{}," and ",[229,3124,811],{},", and the contract is processed asynchronously. A ",[229,3127,876],{}," means the file was empty, wasn't a ",[229,3130,282],{},", was over the size limit or failed the checks above, and the ",[229,3133,882],{}," message says which. ",[229,3136,893],{},[229,3138,903],{}," behave as they do for ",[744,3141,3143],{"href":3142},"#option-1-http-api-upload","data file uploads",[760,3145,3147],{"className":916,"code":3146,"language":918,"meta":580,"style":580},"curl -X PUT \"https:\u002F\u002Fapi-data-ingestion.deducta.ai\u002Fm2m\u002Fapi\u002Fcontract\u002Fupload\" \\\n  -H \"X-API-Key: ${API_KEY}\" \\\n  -F \"file=@\u002Fpath\u002Fto\u002Fcontract.pdf\"\n",[229,3148,3149,3166,3182],{"__ignoreMap":580},[768,3150,3151,3153,3155,3157,3159,3162,3164],{"class":770,"line":771},[768,3152,1003],{"class":1002},[768,3154,1006],{"class":797},[768,3156,1009],{"class":797},[768,3158,794],{"class":774},[768,3160,3161],{"class":797},"https:\u002F\u002Fapi-data-ingestion.deducta.ai\u002Fm2m\u002Fapi\u002Fcontract\u002Fupload",[768,3163,788],{"class":774},[768,3165,1031],{"class":937},[768,3167,3168,3170,3172,3174,3176,3178,3180],{"class":770,"line":778},[768,3169,1037],{"class":797},[768,3171,794],{"class":774},[768,3173,1042],{"class":797},[768,3175,1023],{"class":774},[768,3177,938],{"class":937},[768,3179,1028],{"class":774},[768,3181,1031],{"class":937},[768,3183,3184,3186,3188,3191],{"class":770,"line":806},[768,3185,1056],{"class":797},[768,3187,794],{"class":774},[768,3189,3190],{"class":797},"file=@\u002Fpath\u002Fto\u002Fcontract.pdf",[768,3192,843],{"class":774},[15,3194,3195,3196,3119,3199,3201,3202,3205,3206,3209],{},"To remove a contract, call ",[229,3197,3198],{},"DELETE \u002Fapi\u002Fcontract\u002F{fileId}",[229,3200,785],{}," from the upload response. It returns ",[229,3203,3204],{},"204 No Content",", or ",[229,3207,3208],{},"404 Not Found"," if there is no such contract.",[10,3211,3213],{"id":3212},"cadence-and-reporting-period","Cadence and reporting period",[15,3215,3216],{},"Deducta supports your preferred submission frequency: daily, weekly, monthly or quarterly. Monthly is the most common cadence. The schedule is agreed during onboarding.",[10,3218,3220],{"id":3219},"security-and-privacy","Security and privacy",[15,3222,3223],{},"Standard controls:",[34,3225,3226,3229,3232,3235,3238],{},[37,3227,3228],{},"Role-based access control (RBAC)",[37,3230,3231],{},"Encryption of data in transit and at rest",[37,3233,3234],{},"Audit logging and monitoring",[37,3236,3237],{},"Data retention and lifecycle management controls",[37,3239,3240],{},"Compliance with shared policies and regulatory requirements",[15,3242,3243],{},"Please reach out to your Deducta representative with any specific questions.",[10,3245,3247],{"id":3246},"faq","FAQ",[26,3249,3251],{"id":3250},"data","Data",[190,3253,3255],{"summary":3254},"Do we need to transform or clean our data before sending it?",[15,3256,3257,3258,3262],{},"No. Send it as it comes out of your source system, in any of the accepted formats. The ingestion pipeline handles a variety of structures and field combinations. The main thing to check is that the fields in the ",[744,3259,3261],{"href":3260},"#data-schema","data schema"," are present.",[190,3264,3266],{"summary":3265},"We can't supply every field in the data schema. Can we still start?",[15,3267,3268],{},"Yes. We work closely with every organization to understand what data they have available and come up with a solution that tries to maximize the utility of the platform.",[190,3270,3272],{"summary":3271},"Which date should we use for spend?",[15,3273,3274],{},"We use the payment (clearing) date as the date for all spend. Deducta does not use invoice date, PO date or goods receipt date as the spend date. They can still be provided, but they are not actively used in any analysis on the platform.",[190,3276,3278],{"summary":3277},"Which file format should we use?",[15,3279,3280,3281,3283,3284,3286,3287,3289,3290,310],{},"Parquet is preferred, especially for large extracts. Excel and CSV are accepted. Use ",[229,3282,269],{}," to send several files in one go. The platform upload accepts ",[229,3285,244],{}," only. Contracts are the exception: send them as ",[229,3288,282],{},", as described in ",[744,3291,3048],{"href":3292},"#uploading-contracts",[26,3294,3296],{"id":3295},"delivery","Delivery",[190,3298,3300],{"summary":3299},"How do we know an upload worked?",[15,3301,3302,3303,3306,3307,339,3309,3122,3311,3313,3314,3316,3317,306,3320,3323],{},"API: a ",[229,3304,3305],{},"200"," response with a ",[229,3308,785],{},[229,3310,811],{},[229,3312,695],{},". Storage account: ",[229,3315,2836],{}," from the REST call, or the file shows up in ",[229,3318,3319],{},"azcopy list",[229,3321,3322],{},"list_blobs()",". For your first upload, also message your Deducta representative so we can confirm the file is readable.",[190,3325,3327],{"summary":3326},"What happens if we upload a file with the same name twice?",[15,3328,3329,3330,3332],{},"Storage account: the upload is rejected with ",[229,3331,3027],{},", and nothing is overwritten. Use a new name, for example with the date. API: the stored file name gets a processing timestamp appended, so you don't need to add one.",[26,3334,3336],{"id":3335},"security-and-access","Security and access",[190,3338,3340],{"summary":3339},"Can we restrict uploads to specific IP addresses?",[15,3341,3342,3343,310],{},"For the storage account, yes. If we agree an IP restriction, send us the static public IP addresses your uploads come from. Requests from other addresses fail with ",[229,3344,3017],{},[190,3346,3348],{"summary":3347},"Do credentials expire?",[15,3349,3350],{},"Storage client secrets have an expiry date. We send a replacement before then, and both work during the changeover. Access tokens last about an hour; AzCopy and the SDK refresh them automatically. API keys are issued by your Deducta representative.",[190,3352,3354],{"summary":3353},"What if a key or secret is exposed?",[15,3355,3356],{},"Tell your Deducta representative immediately and we will revoke it and issue a new one.",[190,3358,3360],{"summary":3359},"How is data protected?",[15,3361,3362,3363,3366,3367,310],{},"Data is encrypted in transit (HTTPS) and at rest, access is role-based and limited to authorized users, and activity is audit logged. See ",[744,3364,3220],{"href":3365},"#security-and-privacy"," and our ",[744,3368,3370],{"href":3369},"\u002Fsecurity","security page",[10,3372,3374],{"id":3373},"support","Support",[15,3376,3377],{},"For API keys, storage credentials, or any question on this page, contact your Deducta representative.",[3379,3380,3381],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":580,"searchDepth":806,"depth":806,"links":3383},[3384,3385,3391,3396,3397,3398,3399,3404],{"id":12,"depth":778,"text":13},{"id":20,"depth":778,"text":21,"children":3386},[3387,3388,3389,3390],{"id":28,"depth":806,"text":29},{"id":60,"depth":806,"text":61},{"id":202,"depth":806,"text":203},{"id":290,"depth":806,"text":291},{"id":431,"depth":778,"text":432,"children":3392},[3393,3394,3395],{"id":583,"depth":806,"text":584},{"id":2342,"depth":806,"text":2343},{"id":3037,"depth":806,"text":3038},{"id":3047,"depth":778,"text":3048},{"id":3212,"depth":778,"text":3213},{"id":3219,"depth":778,"text":3220},{"id":3246,"depth":778,"text":3247,"children":3400},[3401,3402,3403],{"id":3250,"depth":806,"text":3251},{"id":3295,"depth":806,"text":3296},{"id":3335,"depth":806,"text":3336},{"id":3373,"depth":778,"text":3374},"Getting Started","How Deducta and your IT systems can work together.","md",null,{},0,"\u002Fdocs\u002Ftechnical-onboarding",{"title":5,"description":3406},{"loc":3411,"lastmod":3414},"2026-10-14","docs\u002Ftechnical-onboarding","7EAIxh8f7D2TmzZ_fEnJqX7u5eGA1jJN4CeUbHrUUi4",[3418],{"id":4,"title":5,"body":3419,"category":3405,"description":3406,"extension":3407,"head":3408,"meta":6011,"navLabel":5,"navigation":931,"ogImage":3408,"order":3410,"path":3411,"robots":3408,"schemaOrg":3408,"seo":6012,"sitemap":6013,"stem":3415,"updatedAt":3414,"__hash__":3416},{"type":7,"value":3420,"toc":5988},[3421,3423,3425,3427,3429,3431,3433,3449,3451,3453,3543,3549,3551,3617,3619,3621,3625,3631,3655,3717,3719,3721,3833,5165,5736,5746,5748,5750,5794,5804,5824,5870,5880,5882,5884,5886,5888,5900,5902,5904,5906,5912,5916,5920,5932,5934,5952,5958,5960,5966,5970,5974,5982,5984,5986],[10,3422,13],{"id":12},[15,3424,17],{},[10,3426,21],{"id":20},[15,3428,24],{},[26,3430,29],{"id":28},[15,3432,32],{},[34,3434,3435,3437,3439,3441,3443,3445,3447],{},[37,3436,39],{},[37,3438,42],{},[37,3440,45],{},[37,3442,48],{},[37,3444,51],{},[37,3446,54],{},[37,3448,57],{},[26,3450,61],{"id":60},[15,3452,64],{},[66,3454,3455,3463],{},[69,3456,3457],{},[72,3458,3459,3461],{},[75,3460,77],{},[75,3462,80],{},[82,3464,3465,3471,3477,3483,3489,3495,3501,3507,3513,3519,3525,3531,3537],{},[72,3466,3467,3469],{},[87,3468,89],{},[87,3470,92],{},[72,3472,3473,3475],{},[87,3474,97],{},[87,3476,100],{},[72,3478,3479,3481],{},[87,3480,105],{},[87,3482,108],{},[72,3484,3485,3487],{},[87,3486,113],{},[87,3488,116],{},[72,3490,3491,3493],{},[87,3492,121],{},[87,3494,124],{},[72,3496,3497,3499],{},[87,3498,129],{},[87,3500,132],{},[72,3502,3503,3505],{},[87,3504,137],{},[87,3506,140],{},[72,3508,3509,3511],{},[87,3510,145],{},[87,3512,148],{},[72,3514,3515,3517],{},[87,3516,153],{},[87,3518,156],{},[72,3520,3521,3523],{},[87,3522,161],{},[87,3524,164],{},[72,3526,3527,3529],{},[87,3528,169],{},[87,3530,172],{},[72,3532,3533,3535],{},[87,3534,177],{},[87,3536,180],{},[72,3538,3539,3541],{},[87,3540,185],{},[87,3542,188],{},[190,3544,3545],{"summary":192},[15,3546,195,3547,199],{},[197,3548,113],{},[26,3550,203],{"id":202},[66,3552,3553,3563],{},[69,3554,3555],{},[72,3556,3557,3559,3561],{},[75,3558,212],{},[75,3560,215],{},[75,3562,218],{},[82,3564,3565,3575,3585,3595,3605],{},[72,3566,3567,3569,3573],{},[87,3568,225],{},[87,3570,3571],{},[229,3572,231],{},[87,3574,234],{},[72,3576,3577,3579,3583],{},[87,3578,239],{},[87,3580,3581],{},[229,3582,244],{},[87,3584,247],{},[72,3586,3587,3589,3593],{},[87,3588,252],{},[87,3590,3591],{},[229,3592,257],{},[87,3594,247],{},[72,3596,3597,3599,3603],{},[87,3598,264],{},[87,3600,3601],{},[229,3602,269],{},[87,3604,272],{},[72,3606,3607,3609,3613],{},[87,3608,277],{},[87,3610,3611],{},[229,3612,282],{},[87,3614,285,3615],{},[229,3616,269],{},[26,3618,291],{"id":290},[15,3620,294],{},[15,3622,3623],{},[229,3624,299],{},[15,3626,302,3627,306,3629,310],{},[229,3628,305],{},[229,3630,309],{},[34,3632,3633,3635,3639,3643,3651],{},[37,3634,315],{},[37,3636,318,3637,322],{},[229,3638,321],{},[37,3640,325,3641,310],{},[229,3642,328],{},[37,3644,331,3645,335,3647,339,3649,343],{},[229,3646,334],{},[229,3648,338],{},[229,3650,342],{},[37,3652,346,3653,349],{},[229,3654,321],{},[66,3656,3657,3667],{},[69,3658,3659],{},[72,3660,3661,3663,3665],{},[75,3662,358],{},[75,3664,212],{},[75,3666,363],{},[82,3668,3669,3681,3693,3705],{},[72,3670,3671,3673,3677],{},[87,3672,370],{},[87,3674,3675],{},[229,3676,375],{},[87,3678,3679],{},[229,3680,380],{},[72,3682,3683,3685,3689],{},[87,3684,385],{},[87,3686,3687],{},[229,3688,390],{},[87,3690,3691],{},[229,3692,395],{},[72,3694,3695,3697,3701],{},[87,3696,400],{},[87,3698,3699],{},[229,3700,405],{},[87,3702,3703],{},[229,3704,410],{},[72,3706,3707,3709,3713],{},[87,3708,415],{},[87,3710,3711],{},[229,3712,420],{},[87,3714,3715],{},[229,3716,425],{},[15,3718,428],{},[10,3720,432],{"id":431},[66,3722,3723,3741],{},[69,3724,3725],{},[72,3726,3727,3729,3733,3737],{},[75,3728],{},[75,3730,3731,446],{},[197,3732,445],{},[75,3734,3735],{},[197,3736,451],{},[75,3738,3739],{},[197,3740,456],{},[82,3742,3743,3753,3781,3791,3803,3813,3823],{},[72,3744,3745,3747,3749,3751],{},[87,3746,463],{},[87,3748,466],{},[87,3750,469],{},[87,3752,472],{},[72,3754,3755,3757,3767,3777],{},[87,3756,203],{},[87,3758,3759,339,3761,339,3763,339,3765],{},[229,3760,244],{},[229,3762,231],{},[229,3764,257],{},[229,3766,269],{},[87,3768,3769,339,3771,339,3773,339,3775],{},[229,3770,244],{},[229,3772,231],{},[229,3774,257],{},[229,3776,269],{},[87,3778,3779,501],{},[229,3780,244],{},[72,3782,3783,3785,3787,3789],{},[87,3784,506],{},[87,3786,509],{},[87,3788,512],{},[87,3790,515],{},[72,3792,3793,3795,3799,3801],{},[87,3794,520],{},[87,3796,523,3797,526],{},[229,3798,269],{},[87,3800,529],{},[87,3802,532],{},[72,3804,3805,3807,3809,3811],{},[87,3806,537],{},[87,3808,540],{},[87,3810,543],{},[87,3812,540],{},[72,3814,3815,3817,3819,3821],{},[87,3816,550],{},[87,3818,553],{},[87,3820,556],{},[87,3822,559],{},[72,3824,3825,3827,3829,3831],{},[87,3826,564],{},[87,3828,567],{},[87,3830,570],{},[87,3832,573],{},[575,3834,3835,3839,3843,3847,3881,3885,3929,3933,3953,3965,3969,3973,4037,4041,4083,4203,4597,5143,5147],{},[578,3836,3837],{"v-slot:title":580},[26,3838,584],{"id":583},[15,3840,587,3841,591],{},[229,3842,590],{},[15,3844,3845],{},[197,3846,596],{},[66,3848,3849,3857],{},[69,3850,3851],{},[72,3852,3853,3855],{},[75,3854,605],{},[75,3856,608],{},[82,3858,3859,3867,3873],{},[72,3860,3861,3863],{},[87,3862,615],{},[87,3864,618,3865,622],{},[229,3866,621],{},[72,3868,3869,3871],{},[87,3870,627],{},[87,3872,630],{},[72,3874,3875,3877],{},[87,3876,635],{},[87,3878,3879],{},[229,3880,640],{},[15,3882,3883],{},[197,3884,645],{},[66,3886,3887,3895],{},[69,3888,3889],{},[72,3890,3891,3893],{},[75,3892],{},[75,3894],{},[82,3896,3897,3905,3913,3921],{},[72,3898,3899,3901],{},[87,3900,662],{},[87,3902,3903],{},[229,3904,667],{},[72,3906,3907,3909],{},[87,3908,672],{},[87,3910,3911],{},[229,3912,677],{},[72,3914,3915,3919],{},[87,3916,3917,685],{},[229,3918,684],{},[87,3920,688],{},[72,3922,3923,3927],{},[87,3924,3925,696],{},[229,3926,695],{},[87,3928,699],{},[15,3930,3931],{},[197,3932,704],{},[34,3934,3935,3945,3949,3951],{},[37,3936,709,3937,339,3939,339,3941,306,3943,310],{},[229,3938,244],{},[229,3940,231],{},[229,3942,257],{},[229,3944,269],{},[37,3946,720,3947,723],{},[229,3948,269],{},[37,3950,726],{},[37,3952,729],{},[15,3954,732,3955,735,3957,339,3959,306,3961,742,3963,310],{},[229,3956,269],{},[229,3958,244],{},[229,3960,231],{},[229,3962,257],{},[744,3964,291],{"href":746},[15,3966,3967],{},[197,3968,751],{},[15,3970,754,3971,758],{},[229,3972,757],{},[760,3974,3975],{"className":762,"code":763,"language":764,"meta":580,"style":580},[229,3976,3977,3981,3999,4017,4033],{"__ignoreMap":580},[768,3978,3979],{"class":770,"line":771},[768,3980,775],{"class":774},[768,3982,3983,3985,3987,3989,3991,3993,3995,3997],{"class":770,"line":778},[768,3984,781],{"class":774},[768,3986,785],{"class":784},[768,3988,788],{"class":774},[768,3990,791],{"class":774},[768,3992,794],{"class":774},[768,3994,798],{"class":797},[768,3996,788],{"class":774},[768,3998,803],{"class":774},[768,4000,4001,4003,4005,4007,4009,4011,4013,4015],{"class":770,"line":806},[768,4002,781],{"class":774},[768,4004,811],{"class":784},[768,4006,788],{"class":774},[768,4008,791],{"class":774},[768,4010,794],{"class":774},[768,4012,820],{"class":797},[768,4014,788],{"class":774},[768,4016,803],{"class":774},[768,4018,4019,4021,4023,4025,4027,4029,4031],{"class":770,"line":827},[768,4020,781],{"class":774},[768,4022,695],{"class":784},[768,4024,788],{"class":774},[768,4026,791],{"class":774},[768,4028,794],{"class":774},[768,4030,840],{"class":797},[768,4032,843],{"class":774},[768,4034,4035],{"class":770,"line":846},[768,4036,849],{"class":774},[15,4038,852,4039,791],{},[229,4040,855],{},[66,4042,4043,4051],{},[69,4044,4045],{},[72,4046,4047,4049],{},[75,4048,864],{},[75,4050,867],{},[82,4052,4053,4065,4073],{},[72,4054,4055,4059],{},[87,4056,4057],{},[229,4058,876],{},[87,4060,879,4061,883,4063,886],{},[229,4062,882],{},[229,4064,695],{},[72,4066,4067,4071],{},[87,4068,4069],{},[229,4070,893],{},[87,4072,896],{},[72,4074,4075,4079],{},[87,4076,4077],{},[229,4078,903],{},[87,4080,906,4081,910],{},[229,4082,909],{},[190,4084,4085],{"summary":913},[760,4086,4087],{"className":916,"code":917,"language":918,"meta":580,"style":580},[229,4088,4089,4093,4097,4109,4121,4133,4145,4149,4173,4189],{"__ignoreMap":580},[768,4090,4091],{"class":770,"line":771},[768,4092,926],{"class":925},[768,4094,4095],{"class":770,"line":778},[768,4096,932],{"emptyLinePlaceholder":931},[768,4098,4099,4101,4103,4105,4107],{"class":770,"line":806},[768,4100,938],{"class":937},[768,4102,941],{"class":774},[768,4104,788],{"class":774},[768,4106,946],{"class":797},[768,4108,843],{"class":774},[768,4110,4111,4113,4115,4117,4119],{"class":770,"line":827},[768,4112,953],{"class":937},[768,4114,941],{"class":774},[768,4116,788],{"class":774},[768,4118,960],{"class":797},[768,4120,843],{"class":774},[768,4122,4123,4125,4127,4129,4131],{"class":770,"line":846},[768,4124,967],{"class":937},[768,4126,941],{"class":774},[768,4128,788],{"class":774},[768,4130,974],{"class":797},[768,4132,843],{"class":774},[768,4134,4135,4137,4139,4141,4143],{"class":770,"line":979},[768,4136,982],{"class":937},[768,4138,941],{"class":774},[768,4140,788],{"class":774},[768,4142,989],{"class":797},[768,4144,843],{"class":774},[768,4146,4147],{"class":770,"line":994},[768,4148,932],{"emptyLinePlaceholder":931},[768,4150,4151,4153,4155,4157,4159,4161,4163,4165,4167,4169,4171],{"class":770,"line":999},[768,4152,1003],{"class":1002},[768,4154,1006],{"class":797},[768,4156,1009],{"class":797},[768,4158,1012],{"class":774},[768,4160,982],{"class":937},[768,4162,1017],{"class":774},[768,4164,1020],{"class":797},[768,4166,1023],{"class":774},[768,4168,953],{"class":937},[768,4170,1028],{"class":774},[768,4172,1031],{"class":937},[768,4174,4175,4177,4179,4181,4183,4185,4187],{"class":770,"line":1034},[768,4176,1037],{"class":797},[768,4178,794],{"class":774},[768,4180,1042],{"class":797},[768,4182,1023],{"class":774},[768,4184,938],{"class":937},[768,4186,1028],{"class":774},[768,4188,1031],{"class":937},[768,4190,4191,4193,4195,4197,4199,4201],{"class":770,"line":1053},[768,4192,1056],{"class":797},[768,4194,794],{"class":774},[768,4196,1061],{"class":797},[768,4198,1023],{"class":774},[768,4200,967],{"class":937},[768,4202,1068],{"class":774},[190,4204,4205],{"summary":1071},[760,4206,4207],{"className":1074,"code":1075,"language":1076,"meta":580,"style":580},[229,4208,4209,4213,4217,4221,4225,4229,4233,4237,4241,4245,4249,4253,4257,4261,4265,4269,4273,4277,4281,4285,4289,4293,4297,4301,4305,4309,4313,4317,4321,4325,4329,4333,4337,4341,4345,4349,4353,4357,4361,4365,4369,4373,4377,4381,4385,4389,4393,4397,4401,4405,4409,4413,4417,4421,4425,4429,4433,4437,4441,4445,4449,4453,4457,4461,4465,4469,4473,4477,4481,4485,4489,4493,4497,4501,4505,4509,4513,4517,4521,4525,4529,4533,4537,4541,4545,4549,4553,4557,4561,4565,4569,4573,4577,4581,4585,4589,4593],{"__ignoreMap":580},[768,4210,4211],{"class":770,"line":771},[768,4212,1083],{},[768,4214,4215],{"class":770,"line":778},[768,4216,1088],{},[768,4218,4219],{"class":770,"line":806},[768,4220,1093],{},[768,4222,4223],{"class":770,"line":827},[768,4224,932],{"emptyLinePlaceholder":931},[768,4226,4227],{"class":770,"line":846},[768,4228,1102],{},[768,4230,4231],{"class":770,"line":979},[768,4232,1107],{},[768,4234,4235],{"class":770,"line":994},[768,4236,1112],{},[768,4238,4239],{"class":770,"line":999},[768,4240,1117],{},[768,4242,4243],{"class":770,"line":1034},[768,4244,1122],{},[768,4246,4247],{"class":770,"line":1053},[768,4248,932],{"emptyLinePlaceholder":931},[768,4250,4251],{"class":770,"line":1129},[768,4252,1132],{},[768,4254,4255],{"class":770,"line":1135},[768,4256,1138],{},[768,4258,4259],{"class":770,"line":1141},[768,4260,932],{"emptyLinePlaceholder":931},[768,4262,4263],{"class":770,"line":1146},[768,4264,1149],{},[768,4266,4267],{"class":770,"line":1152},[768,4268,1155],{},[768,4270,4271],{"class":770,"line":1158},[768,4272,1161],{},[768,4274,4275],{"class":770,"line":1164},[768,4276,932],{"emptyLinePlaceholder":931},[768,4278,4279],{"class":770,"line":1169},[768,4280,1172],{},[768,4282,4283],{"class":770,"line":1175},[768,4284,1178],{},[768,4286,4287],{"class":770,"line":1181},[768,4288,932],{"emptyLinePlaceholder":931},[768,4290,4291],{"class":770,"line":1186},[768,4292,1189],{},[768,4294,4295],{"class":770,"line":1192},[768,4296,1195],{},[768,4298,4299],{"class":770,"line":1198},[768,4300,1201],{},[768,4302,4303],{"class":770,"line":1204},[768,4304,1207],{},[768,4306,4307],{"class":770,"line":1210},[768,4308,932],{"emptyLinePlaceholder":931},[768,4310,4311],{"class":770,"line":1215},[768,4312,1218],{},[768,4314,4315],{"class":770,"line":1221},[768,4316,1224],{},[768,4318,4319],{"class":770,"line":1227},[768,4320,932],{"emptyLinePlaceholder":931},[768,4322,4323],{"class":770,"line":1232},[768,4324,1235],{},[768,4326,4327],{"class":770,"line":1238},[768,4328,1241],{},[768,4330,4331],{"class":770,"line":1244},[768,4332,1155],{},[768,4334,4335],{"class":770,"line":1249},[768,4336,1252],{},[768,4338,4339],{"class":770,"line":1255},[768,4340,1258],{},[768,4342,4343],{"class":770,"line":1261},[768,4344,1264],{},[768,4346,4347],{"class":770,"line":1267},[768,4348,1270],{},[768,4350,4351],{"class":770,"line":1273},[768,4352,932],{"emptyLinePlaceholder":931},[768,4354,4355],{"class":770,"line":1278},[768,4356,1281],{},[768,4358,4359],{"class":770,"line":1284},[768,4360,1287],{},[768,4362,4363],{"class":770,"line":1290},[768,4364,1293],{},[768,4366,4367],{"class":770,"line":1296},[768,4368,932],{"emptyLinePlaceholder":931},[768,4370,4371],{"class":770,"line":1301},[768,4372,1304],{},[768,4374,4375],{"class":770,"line":1307},[768,4376,1310],{},[768,4378,4379],{"class":770,"line":1313},[768,4380,1316],{},[768,4382,4383],{"class":770,"line":1319},[768,4384,1322],{},[768,4386,4387],{"class":770,"line":1325},[768,4388,1328],{},[768,4390,4391],{"class":770,"line":1331},[768,4392,1334],{},[768,4394,4395],{"class":770,"line":1337},[768,4396,932],{"emptyLinePlaceholder":931},[768,4398,4399],{"class":770,"line":1342},[768,4400,1345],{},[768,4402,4403],{"class":770,"line":1348},[768,4404,1351],{},[768,4406,4407],{"class":770,"line":1354},[768,4408,1357],{},[768,4410,4411],{"class":770,"line":1360},[768,4412,1363],{},[768,4414,4415],{"class":770,"line":1366},[768,4416,932],{"emptyLinePlaceholder":931},[768,4418,4419],{"class":770,"line":1371},[768,4420,1374],{},[768,4422,4423],{"class":770,"line":1377},[768,4424,1380],{},[768,4426,4427],{"class":770,"line":1383},[768,4428,1363],{},[768,4430,4431],{"class":770,"line":1388},[768,4432,932],{"emptyLinePlaceholder":931},[768,4434,4435],{"class":770,"line":1393},[768,4436,1396],{},[768,4438,4439],{"class":770,"line":1399},[768,4440,1402],{},[768,4442,4443],{"class":770,"line":1405},[768,4444,1408],{},[768,4446,4447],{"class":770,"line":1411},[768,4448,1414],{},[768,4450,4451],{"class":770,"line":1417},[768,4452,1420],{},[768,4454,4455],{"class":770,"line":1423},[768,4456,1426],{},[768,4458,4459],{"class":770,"line":1429},[768,4460,932],{"emptyLinePlaceholder":931},[768,4462,4463],{"class":770,"line":1434},[768,4464,1437],{},[768,4466,4467],{"class":770,"line":1440},[768,4468,1443],{},[768,4470,4471],{"class":770,"line":1446},[768,4472,1449],{},[768,4474,4475],{"class":770,"line":1452},[768,4476,1455],{},[768,4478,4479],{"class":770,"line":1458},[768,4480,1461],{},[768,4482,4483],{"class":770,"line":1464},[768,4484,1334],{},[768,4486,4487],{"class":770,"line":1469},[768,4488,932],{"emptyLinePlaceholder":931},[768,4490,4491],{"class":770,"line":1474},[768,4492,1477],{},[768,4494,4495],{"class":770,"line":1480},[768,4496,1483],{},[768,4498,4499],{"class":770,"line":1486},[768,4500,932],{"emptyLinePlaceholder":931},[768,4502,4503],{"class":770,"line":1491},[768,4504,1494],{},[768,4506,4507],{"class":770,"line":1497},[768,4508,932],{"emptyLinePlaceholder":931},[768,4510,4511],{"class":770,"line":1502},[768,4512,1505],{},[768,4514,4515],{"class":770,"line":1508},[768,4516,1511],{},[768,4518,4519],{"class":770,"line":1514},[768,4520,1517],{},[768,4522,4523],{"class":770,"line":1520},[768,4524,1523],{},[768,4526,4527],{"class":770,"line":1526},[768,4528,1529],{},[768,4530,4531],{"class":770,"line":1532},[768,4532,1535],{},[768,4534,4535],{"class":770,"line":1538},[768,4536,1541],{},[768,4538,4539],{"class":770,"line":1544},[768,4540,1547],{},[768,4542,4543],{"class":770,"line":1550},[768,4544,1553],{},[768,4546,4547],{"class":770,"line":1556},[768,4548,1559],{},[768,4550,4551],{"class":770,"line":1562},[768,4552,1565],{},[768,4554,4555],{"class":770,"line":1568},[768,4556,1571],{},[768,4558,4559],{"class":770,"line":1574},[768,4560,1577],{},[768,4562,4563],{"class":770,"line":1580},[768,4564,1583],{},[768,4566,4567],{"class":770,"line":1586},[768,4568,1589],{},[768,4570,4571],{"class":770,"line":1592},[768,4572,1595],{},[768,4574,4575],{"class":770,"line":1598},[768,4576,1601],{},[768,4578,4579],{"class":770,"line":1604},[768,4580,1607],{},[768,4582,4583],{"class":770,"line":1610},[768,4584,1613],{},[768,4586,4587],{"class":770,"line":1616},[768,4588,1619],{},[768,4590,4591],{"class":770,"line":1622},[768,4592,1625],{},[768,4594,4595],{"class":770,"line":1628},[768,4596,1631],{},[190,4598,4599],{"summary":1634},[760,4600,4601],{"className":1637,"code":1638,"language":1639,"meta":580,"style":580},[229,4602,4603,4607,4611,4615,4619,4623,4627,4631,4635,4639,4643,4647,4651,4655,4659,4663,4667,4671,4675,4679,4683,4687,4691,4695,4699,4703,4707,4711,4715,4719,4723,4727,4731,4735,4739,4743,4747,4751,4755,4759,4763,4767,4771,4775,4779,4783,4787,4791,4795,4799,4803,4807,4811,4815,4819,4823,4827,4831,4835,4839,4843,4847,4851,4855,4859,4863,4867,4871,4875,4879,4883,4887,4891,4895,4899,4903,4907,4911,4915,4919,4923,4927,4931,4935,4939,4943,4947,4951,4955,4959,4963,4967,4971,4975,4979,4983,4987,4991,4995,4999,5003,5007,5011,5015,5019,5023,5027,5031,5035,5039,5043,5047,5051,5055,5059,5063,5067,5071,5075,5079,5083,5087,5091,5095,5099,5103,5107,5111,5115,5119,5123,5127,5131,5135,5139],{"__ignoreMap":580},[768,4604,4605],{"class":770,"line":771},[768,4606,1646],{},[768,4608,4609],{"class":770,"line":778},[768,4610,1651],{},[768,4612,4613],{"class":770,"line":806},[768,4614,1656],{},[768,4616,4617],{"class":770,"line":827},[768,4618,1661],{},[768,4620,4621],{"class":770,"line":846},[768,4622,1666],{},[768,4624,4625],{"class":770,"line":979},[768,4626,1671],{},[768,4628,4629],{"class":770,"line":994},[768,4630,1676],{},[768,4632,4633],{"class":770,"line":999},[768,4634,932],{"emptyLinePlaceholder":931},[768,4636,4637],{"class":770,"line":1034},[768,4638,1685],{},[768,4640,4641],{"class":770,"line":1053},[768,4642,775],{},[768,4644,4645],{"class":770,"line":1129},[768,4646,1694],{},[768,4648,4649],{"class":770,"line":1135},[768,4650,1699],{},[768,4652,4653],{"class":770,"line":1141},[768,4654,1704],{},[768,4656,4657],{"class":770,"line":1146},[768,4658,932],{"emptyLinePlaceholder":931},[768,4660,4661],{"class":770,"line":1152},[768,4662,1713],{},[768,4664,4665],{"class":770,"line":1158},[768,4666,1718],{},[768,4668,4669],{"class":770,"line":1164},[768,4670,1723],{},[768,4672,4673],{"class":770,"line":1169},[768,4674,1728],{},[768,4676,4677],{"class":770,"line":1175},[768,4678,932],{"emptyLinePlaceholder":931},[768,4680,4681],{"class":770,"line":1181},[768,4682,1737],{},[768,4684,4685],{"class":770,"line":1186},[768,4686,1718],{},[768,4688,4689],{"class":770,"line":1192},[768,4690,1746],{},[768,4692,4693],{"class":770,"line":1198},[768,4694,1751],{},[768,4696,4697],{"class":770,"line":1204},[768,4698,1363],{},[768,4700,4701],{"class":770,"line":1210},[768,4702,932],{"emptyLinePlaceholder":931},[768,4704,4705],{"class":770,"line":1215},[768,4706,1764],{},[768,4708,4709],{"class":770,"line":1221},[768,4710,1769],{},[768,4712,4713],{"class":770,"line":1227},[768,4714,1774],{},[768,4716,4717],{"class":770,"line":1232},[768,4718,1718],{},[768,4720,4721],{"class":770,"line":1238},[768,4722,1783],{},[768,4724,4725],{"class":770,"line":1244},[768,4726,1788],{},[768,4728,4729],{"class":770,"line":1249},[768,4730,1793],{},[768,4732,4733],{"class":770,"line":1255},[768,4734,1798],{},[768,4736,4737],{"class":770,"line":1261},[768,4738,1426],{},[768,4740,4741],{"class":770,"line":1267},[768,4742,932],{"emptyLinePlaceholder":931},[768,4744,4745],{"class":770,"line":1273},[768,4746,1811],{},[768,4748,4749],{"class":770,"line":1278},[768,4750,1816],{},[768,4752,4753],{"class":770,"line":1284},[768,4754,1821],{},[768,4756,4757],{"class":770,"line":1290},[768,4758,1793],{},[768,4760,4761],{"class":770,"line":1296},[768,4762,1830],{},[768,4764,4765],{"class":770,"line":1301},[768,4766,1426],{},[768,4768,4769],{"class":770,"line":1307},[768,4770,932],{"emptyLinePlaceholder":931},[768,4772,4773],{"class":770,"line":1313},[768,4774,1843],{},[768,4776,4777],{"class":770,"line":1319},[768,4778,1848],{},[768,4780,4781],{"class":770,"line":1325},[768,4782,1853],{},[768,4784,4785],{"class":770,"line":1331},[768,4786,1793],{},[768,4788,4789],{"class":770,"line":1337},[768,4790,1862],{},[768,4792,4793],{"class":770,"line":1342},[768,4794,1867],{},[768,4796,4797],{"class":770,"line":1348},[768,4798,1426],{},[768,4800,4801],{"class":770,"line":1354},[768,4802,932],{"emptyLinePlaceholder":931},[768,4804,4805],{"class":770,"line":1360},[768,4806,1880],{},[768,4808,4809],{"class":770,"line":1366},[768,4810,1885],{},[768,4812,4813],{"class":770,"line":1371},[768,4814,1793],{},[768,4816,4817],{"class":770,"line":1377},[768,4818,1894],{},[768,4820,4821],{"class":770,"line":1383},[768,4822,1426],{},[768,4824,4825],{"class":770,"line":1388},[768,4826,932],{"emptyLinePlaceholder":931},[768,4828,4829],{"class":770,"line":1393},[768,4830,1907],{},[768,4832,4833],{"class":770,"line":1399},[768,4834,1912],{},[768,4836,4837],{"class":770,"line":1405},[768,4838,1917],{},[768,4840,4841],{"class":770,"line":1411},[768,4842,1922],{},[768,4844,4845],{"class":770,"line":1417},[768,4846,932],{"emptyLinePlaceholder":931},[768,4848,4849],{"class":770,"line":1423},[768,4850,1931],{},[768,4852,4853],{"class":770,"line":1429},[768,4854,932],{"emptyLinePlaceholder":931},[768,4856,4857],{"class":770,"line":1434},[768,4858,1940],{},[768,4860,4861],{"class":770,"line":1440},[768,4862,932],{"emptyLinePlaceholder":931},[768,4864,4865],{"class":770,"line":1446},[768,4866,1949],{},[768,4868,4869],{"class":770,"line":1452},[768,4870,1954],{},[768,4872,4873],{"class":770,"line":1458},[768,4874,1959],{},[768,4876,4877],{"class":770,"line":1464},[768,4878,1793],{},[768,4880,4881],{"class":770,"line":1469},[768,4882,1968],{},[768,4884,4885],{"class":770,"line":1474},[768,4886,1973],{},[768,4888,4889],{"class":770,"line":1480},[768,4890,1978],{},[768,4892,4893],{"class":770,"line":1486},[768,4894,932],{"emptyLinePlaceholder":931},[768,4896,4897],{"class":770,"line":1491},[768,4898,1987],{},[768,4900,4901],{"class":770,"line":1497},[768,4902,1992],{},[768,4904,4905],{"class":770,"line":1502},[768,4906,932],{"emptyLinePlaceholder":931},[768,4908,4909],{"class":770,"line":1508},[768,4910,2001],{},[768,4912,4913],{"class":770,"line":1514},[768,4914,2006],{},[768,4916,4917],{"class":770,"line":1520},[768,4918,932],{"emptyLinePlaceholder":931},[768,4920,4921],{"class":770,"line":1526},[768,4922,2015],{},[768,4924,4925],{"class":770,"line":1532},[768,4926,1793],{},[768,4928,4929],{"class":770,"line":1538},[768,4930,2024],{},[768,4932,4933],{"class":770,"line":1544},[768,4934,2029],{},[768,4936,4937],{"class":770,"line":1550},[768,4938,1426],{},[768,4940,4941],{"class":770,"line":1556},[768,4942,932],{"emptyLinePlaceholder":931},[768,4944,4945],{"class":770,"line":1562},[768,4946,2042],{},[768,4948,4949],{"class":770,"line":1568},[768,4950,1363],{},[768,4952,4953],{"class":770,"line":1574},[768,4954,849],{},[768,4956,4957],{"class":770,"line":1580},[768,4958,932],{"emptyLinePlaceholder":931},[768,4960,4961],{"class":770,"line":1586},[768,4962,2059],{},[768,4964,4965],{"class":770,"line":1592},[768,4966,775],{},[768,4968,4969],{"class":770,"line":1598},[768,4970,2068],{},[768,4972,4973],{"class":770,"line":1604},[768,4974,2073],{},[768,4976,4977],{"class":770,"line":1610},[768,4978,2078],{},[768,4980,4981],{"class":770,"line":1616},[768,4982,849],{},[768,4984,4985],{"class":770,"line":1622},[768,4986,932],{"emptyLinePlaceholder":931},[768,4988,4989],{"class":770,"line":1628},[768,4990,2091],{},[768,4992,4993],{"class":770,"line":2094},[768,4994,2097],{},[768,4996,4997],{"class":770,"line":2100},[768,4998,775],{},[768,5000,5001],{"class":770,"line":2105},[768,5002,2108],{},[768,5004,5005],{"class":770,"line":2111},[768,5006,1718],{},[768,5008,5009],{"class":770,"line":2116},[768,5010,2119],{},[768,5012,5013],{"class":770,"line":2122},[768,5014,2125],{},[768,5016,5017],{"class":770,"line":2128},[768,5018,2131],{},[768,5020,5021],{"class":770,"line":2134},[768,5022,2137],{},[768,5024,5025],{"class":770,"line":2140},[768,5026,932],{"emptyLinePlaceholder":931},[768,5028,5029],{"class":770,"line":2145},[768,5030,2148],{},[768,5032,5033],{"class":770,"line":2151},[768,5034,932],{"emptyLinePlaceholder":931},[768,5036,5037],{"class":770,"line":2156},[768,5038,2159],{},[768,5040,5041],{"class":770,"line":2162},[768,5042,1793],{},[768,5044,5045],{"class":770,"line":2167},[768,5046,2170],{},[768,5048,5049],{"class":770,"line":2173},[768,5050,932],{"emptyLinePlaceholder":931},[768,5052,5053],{"class":770,"line":2178},[768,5054,2181],{},[768,5056,5057],{"class":770,"line":2184},[768,5058,2187],{},[768,5060,5061],{"class":770,"line":2190},[768,5062,2193],{},[768,5064,5065],{"class":770,"line":2196},[768,5066,2199],{},[768,5068,5069],{"class":770,"line":2202},[768,5070,1426],{},[768,5072,5073],{"class":770,"line":2207},[768,5074,2210],{},[768,5076,5077],{"class":770,"line":2213},[768,5078,1793],{},[768,5080,5081],{"class":770,"line":2218},[768,5082,2221],{},[768,5084,5085],{"class":770,"line":2224},[768,5086,1426],{},[768,5088,5089],{"class":770,"line":2229},[768,5090,2232],{},[768,5092,5093],{"class":770,"line":2235},[768,5094,1793],{},[768,5096,5097],{"class":770,"line":2240},[768,5098,2243],{},[768,5100,5101],{"class":770,"line":2246},[768,5102,1426],{},[768,5104,5105],{"class":770,"line":2251},[768,5106,2254],{},[768,5108,5109],{"class":770,"line":2257},[768,5110,1793],{},[768,5112,5113],{"class":770,"line":2262},[768,5114,2265],{},[768,5116,5117],{"class":770,"line":2268},[768,5118,1426],{},[768,5120,5121],{"class":770,"line":2273},[768,5122,2276],{},[768,5124,5125],{"class":770,"line":2279},[768,5126,1793],{},[768,5128,5129],{"class":770,"line":2284},[768,5130,2287],{},[768,5132,5133],{"class":770,"line":2290},[768,5134,1426],{},[768,5136,5137],{"class":770,"line":2295},[768,5138,1363],{},[768,5140,5141],{"class":770,"line":2300},[768,5142,849],{},[15,5144,5145],{},[197,5146,2307],{},[34,5148,5149,5151,5153,5157,5163],{},[37,5150,2312],{},[37,5152,2315],{},[37,5154,2318,5155,2321],{},[229,5156,269],{},[37,5158,2324,5159,2328,5161,2332],{},[229,5160,2327],{},[229,5162,2331],{},[37,5164,2335],{},[575,5166,5167,5171,5173,5177,5223,5227,5231,5239,5245,5247,5366,5476,5670,5674],{},[578,5168,5169],{"v-slot:title":580},[26,5170,2343],{"id":2342},[15,5172,2346],{},[15,5174,5175],{},[197,5176,596],{},[66,5178,5179,5187],{},[69,5180,5181],{},[72,5182,5183,5185],{},[75,5184,605],{},[75,5186,608],{},[82,5188,5189,5195,5201,5207,5215],{},[72,5190,5191,5193],{},[87,5192,2367],{},[87,5194,2370],{},[72,5196,5197,5199],{},[87,5198,2375],{},[87,5200,2378],{},[72,5202,5203,5205],{},[87,5204,2383],{},[87,5206,2386],{},[72,5208,5209,5211],{},[87,5210,2391],{},[87,5212,2394,5213],{},[229,5214,2397],{},[72,5216,5217,5219],{},[87,5218,2402],{},[87,5220,5221],{},[229,5222,2407],{},[15,5224,2410,5225,310],{},[197,5226,2413],{},[15,5228,5229],{},[197,5230,2418],{},[34,5232,5233,5235,5237],{},[37,5234,2423],{},[37,5236,2426],{},[37,5238,2429],{},[15,5240,5241,2435,5243,310],{},[197,5242,2434],{},[229,5244,2438],{},[15,5246,2441],{},[190,5248,5249,5254],{"summary":2444},[15,5250,5251,2453],{},[744,5252,2452],{"href":2449,"rel":5253},[2451],[760,5255,5256],{"className":916,"code":2456,"language":918,"meta":580,"style":580},[229,5257,5258,5268,5282,5296,5310,5314,5318,5332,5342,5346,5350,5354],{"__ignoreMap":580},[768,5259,5260,5262,5264,5266],{"class":770,"line":771},[768,5261,2463],{"class":784},[768,5263,2466],{"class":937},[768,5265,941],{"class":774},[768,5267,2471],{"class":937},[768,5269,5270,5272,5274,5276,5278,5280],{"class":770,"line":778},[768,5271,2463],{"class":784},[768,5273,2478],{"class":937},[768,5275,941],{"class":774},[768,5277,788],{"class":774},[768,5279,2485],{"class":797},[768,5281,843],{"class":774},[768,5283,5284,5286,5288,5290,5292,5294],{"class":770,"line":806},[768,5285,2463],{"class":784},[768,5287,2494],{"class":937},[768,5289,941],{"class":774},[768,5291,788],{"class":774},[768,5293,2501],{"class":797},[768,5295,843],{"class":774},[768,5297,5298,5300,5302,5304,5306,5308],{"class":770,"line":827},[768,5299,2463],{"class":784},[768,5301,2510],{"class":937},[768,5303,941],{"class":774},[768,5305,788],{"class":774},[768,5307,2517],{"class":937},[768,5309,843],{"class":774},[768,5311,5312],{"class":770,"line":846},[768,5313,932],{"emptyLinePlaceholder":931},[768,5315,5316],{"class":770,"line":979},[768,5317,2528],{"class":925},[768,5319,5320,5322,5324,5326,5328,5330],{"class":770,"line":994},[768,5321,2533],{"class":1002},[768,5323,2536],{"class":797},[768,5325,794],{"class":774},[768,5327,2541],{"class":797},[768,5329,788],{"class":774},[768,5331,1031],{"class":937},[768,5333,5334,5336,5338,5340],{"class":770,"line":999},[768,5335,781],{"class":774},[768,5337,2397],{"class":797},[768,5339,788],{"class":774},[768,5341,1031],{"class":937},[768,5343,5344],{"class":770,"line":1034},[768,5345,2560],{"class":797},[768,5347,5348],{"class":770,"line":1053},[768,5349,932],{"emptyLinePlaceholder":931},[768,5351,5352],{"class":770,"line":1129},[768,5353,2569],{"class":925},[768,5355,5356,5358,5360,5362,5364],{"class":770,"line":1135},[768,5357,2533],{"class":1002},[768,5359,2576],{"class":797},[768,5361,794],{"class":774},[768,5363,2581],{"class":797},[768,5365,843],{"class":774},[190,5367,5368,5370,5384],{"summary":1071},[15,5369,2588],{},[760,5371,5372],{"className":916,"code":2591,"language":918,"meta":580,"style":580},[229,5373,5374],{"__ignoreMap":580},[768,5375,5376,5378,5380,5382],{"class":770,"line":771},[768,5377,2598],{"class":1002},[768,5379,2601],{"class":797},[768,5381,2604],{"class":797},[768,5383,2607],{"class":797},[760,5385,5386],{"className":1074,"code":2610,"language":1076,"meta":580,"style":580},[229,5387,5388,5392,5396,5400,5404,5408,5412,5416,5420,5424,5428,5432,5436,5440,5444,5448,5452,5456,5460,5464,5468,5472],{"__ignoreMap":580},[768,5389,5390],{"class":770,"line":771},[768,5391,2617],{},[768,5393,5394],{"class":770,"line":778},[768,5395,932],{"emptyLinePlaceholder":931},[768,5397,5398],{"class":770,"line":806},[768,5399,2626],{},[768,5401,5402],{"class":770,"line":827},[768,5403,2631],{},[768,5405,5406],{"class":770,"line":846},[768,5407,932],{"emptyLinePlaceholder":931},[768,5409,5410],{"class":770,"line":979},[768,5411,2640],{},[768,5413,5414],{"class":770,"line":994},[768,5415,2645],{},[768,5417,5418],{"class":770,"line":999},[768,5419,2650],{},[768,5421,5422],{"class":770,"line":1034},[768,5423,2655],{},[768,5425,5426],{"class":770,"line":1053},[768,5427,2660],{},[768,5429,5430],{"class":770,"line":1129},[768,5431,2665],{},[768,5433,5434],{"class":770,"line":1135},[768,5435,2670],{},[768,5437,5438],{"class":770,"line":1141},[768,5439,2675],{},[768,5441,5442],{"class":770,"line":1146},[768,5443,2680],{},[768,5445,5446],{"class":770,"line":1152},[768,5447,2660],{},[768,5449,5450],{"class":770,"line":1158},[768,5451,932],{"emptyLinePlaceholder":931},[768,5453,5454],{"class":770,"line":1164},[768,5455,2693],{},[768,5457,5458],{"class":770,"line":1169},[768,5459,2698],{},[768,5461,5462],{"class":770,"line":1175},[768,5463,2703],{},[768,5465,5466],{"class":770,"line":1181},[768,5467,932],{"emptyLinePlaceholder":931},[768,5469,5470],{"class":770,"line":1186},[768,5471,2712],{},[768,5473,5474],{"class":770,"line":1192},[768,5475,2717],{},[190,5477,5478,5480,5482,5570,5578],{"summary":2720},[15,5479,2723],{},[15,5481,2726],{},[760,5483,5484],{"className":916,"code":2729,"language":918,"meta":580,"style":580},[229,5485,5486,5502,5512,5524,5536,5550],{"__ignoreMap":580},[768,5487,5488,5490,5492,5494,5496,5498,5500],{"class":770,"line":771},[768,5489,2736],{"class":937},[768,5491,2739],{"class":774},[768,5493,1003],{"class":1002},[768,5495,2744],{"class":797},[768,5497,1006],{"class":797},[768,5499,2749],{"class":797},[768,5501,1031],{"class":937},[768,5503,5504,5506,5508,5510],{"class":770,"line":778},[768,5505,781],{"class":774},[768,5507,2758],{"class":797},[768,5509,788],{"class":774},[768,5511,1031],{"class":937},[768,5513,5514,5516,5518,5520,5522],{"class":770,"line":806},[768,5515,2767],{"class":797},[768,5517,794],{"class":774},[768,5519,2772],{"class":797},[768,5521,788],{"class":774},[768,5523,1031],{"class":937},[768,5525,5526,5528,5530,5532,5534],{"class":770,"line":827},[768,5527,2767],{"class":797},[768,5529,794],{"class":774},[768,5531,2785],{"class":797},[768,5533,788],{"class":774},[768,5535,1031],{"class":937},[768,5537,5538,5540,5542,5544,5546,5548],{"class":770,"line":846},[768,5539,2794],{"class":797},[768,5541,794],{"class":774},[768,5543,2799],{"class":797},[768,5545,2517],{"class":937},[768,5547,788],{"class":774},[768,5549,1031],{"class":937},[768,5551,5552,5554,5556,5558,5560,5562,5564,5566,5568],{"class":770,"line":979},[768,5553,2767],{"class":797},[768,5555,794],{"class":774},[768,5557,2814],{"class":797},[768,5559,788],{"class":774},[768,5561,2819],{"class":774},[768,5563,2822],{"class":1002},[768,5565,2825],{"class":797},[768,5567,2828],{"class":797},[768,5569,2660],{"class":774},[15,5571,2833,5572,2837,5574,2841,5576,2845],{},[229,5573,2836],{},[229,5575,2840],{},[229,5577,2844],{},[760,5579,5580],{"className":916,"code":2848,"language":918,"meta":580,"style":580},[229,5581,5582,5592,5602,5616,5628,5640,5652,5660],{"__ignoreMap":580},[768,5583,5584,5586,5588,5590],{"class":770,"line":771},[768,5585,1003],{"class":1002},[768,5587,1006],{"class":797},[768,5589,1009],{"class":797},[768,5591,1031],{"class":937},[768,5593,5594,5596,5598,5600],{"class":770,"line":778},[768,5595,781],{"class":774},[768,5597,2867],{"class":797},[768,5599,788],{"class":774},[768,5601,1031],{"class":937},[768,5603,5604,5606,5608,5610,5612,5614],{"class":770,"line":806},[768,5605,1037],{"class":797},[768,5607,794],{"class":774},[768,5609,2880],{"class":797},[768,5611,2883],{"class":937},[768,5613,788],{"class":774},[768,5615,1031],{"class":937},[768,5617,5618,5620,5622,5624,5626],{"class":770,"line":827},[768,5619,1037],{"class":797},[768,5621,794],{"class":774},[768,5623,2896],{"class":797},[768,5625,788],{"class":774},[768,5627,1031],{"class":937},[768,5629,5630,5632,5634,5636,5638],{"class":770,"line":846},[768,5631,1037],{"class":797},[768,5633,794],{"class":774},[768,5635,2909],{"class":797},[768,5637,788],{"class":774},[768,5639,1031],{"class":937},[768,5641,5642,5644,5646,5648,5650],{"class":770,"line":979},[768,5643,1037],{"class":797},[768,5645,794],{"class":774},[768,5647,2922],{"class":797},[768,5649,788],{"class":774},[768,5651,1031],{"class":937},[768,5653,5654,5656,5658],{"class":770,"line":994},[768,5655,2931],{"class":797},[768,5657,2934],{"class":797},[768,5659,1031],{"class":937},[768,5661,5662,5664,5666,5668],{"class":770,"line":999},[768,5663,2941],{"class":797},[768,5665,794],{"class":774},[768,5667,2946],{"class":797},[768,5669,843],{"class":774},[15,5671,5672],{},[197,5673,2953],{},[66,5675,5676,5684],{},[69,5677,5678],{},[72,5679,5680,5682],{},[75,5681,2962],{},[75,5683,867],{},[82,5685,5686,5694,5702,5712,5720,5728],{},[72,5687,5688,5692],{},[87,5689,5690,2974],{},[229,5691,2973],{},[87,5693,2977],{},[72,5695,5696,5700],{},[87,5697,5698,2985],{},[229,5699,2984],{},[87,5701,2988],{},[72,5703,5704,5708],{},[87,5705,5706],{},[229,5707,2995],{},[87,5709,2998,5710,310],{},[229,5711,2407],{},[72,5713,5714,5718],{},[87,5715,5716],{},[229,5717,3007],{},[87,5719,3010],{},[72,5721,5722,5726],{},[87,5723,5724],{},[229,5725,3017],{},[87,5727,3020],{},[72,5729,5730,5734],{},[87,5731,5732],{},[229,5733,3027],{},[87,5735,3030],{},[575,5737,5738,5742],{},[578,5739,5740],{"v-slot:title":580},[26,5741,3038],{"id":3037},[15,5743,3041,5744,3044],{},[229,5745,244],{},[10,5747,3048],{"id":3047},[15,5749,3051],{},[66,5751,5752,5760],{},[69,5753,5754],{},[72,5755,5756,5758],{},[75,5757],{},[75,5759],{},[82,5761,5762,5770,5778,5788],{},[72,5763,5764,5766],{},[87,5765,662],{},[87,5767,5768],{},[229,5769,3072],{},[72,5771,5772,5774],{},[87,5773,672],{},[87,5775,5776],{},[229,5777,677],{},[72,5779,5780,5784],{},[87,5781,5782,685],{},[229,5783,684],{},[87,5785,3089,5786,3092],{},[229,5787,282],{},[72,5789,5790,5792],{},[87,5791,520],{},[87,5793,3099],{},[34,5795,5796,5798,5800,5802],{},[37,5797,3104],{},[37,5799,3107],{},[37,5801,3110],{},[37,5803,3113],{},[15,5805,3116,5806,3119,5808,3122,5810,3125,5812,3128,5814,3131,5816,3134,5818,3122,5820,3139,5822,310],{},[229,5807,757],{},[229,5809,785],{},[229,5811,811],{},[229,5813,876],{},[229,5815,282],{},[229,5817,882],{},[229,5819,893],{},[229,5821,903],{},[744,5823,3143],{"href":3142},[760,5825,5826],{"className":916,"code":3146,"language":918,"meta":580,"style":580},[229,5827,5828,5844,5860],{"__ignoreMap":580},[768,5829,5830,5832,5834,5836,5838,5840,5842],{"class":770,"line":771},[768,5831,1003],{"class":1002},[768,5833,1006],{"class":797},[768,5835,1009],{"class":797},[768,5837,794],{"class":774},[768,5839,3161],{"class":797},[768,5841,788],{"class":774},[768,5843,1031],{"class":937},[768,5845,5846,5848,5850,5852,5854,5856,5858],{"class":770,"line":778},[768,5847,1037],{"class":797},[768,5849,794],{"class":774},[768,5851,1042],{"class":797},[768,5853,1023],{"class":774},[768,5855,938],{"class":937},[768,5857,1028],{"class":774},[768,5859,1031],{"class":937},[768,5861,5862,5864,5866,5868],{"class":770,"line":806},[768,5863,1056],{"class":797},[768,5865,794],{"class":774},[768,5867,3190],{"class":797},[768,5869,843],{"class":774},[15,5871,3195,5872,3119,5874,3201,5876,3205,5878,3209],{},[229,5873,3198],{},[229,5875,785],{},[229,5877,3204],{},[229,5879,3208],{},[10,5881,3213],{"id":3212},[15,5883,3216],{},[10,5885,3220],{"id":3219},[15,5887,3223],{},[34,5889,5890,5892,5894,5896,5898],{},[37,5891,3228],{},[37,5893,3231],{},[37,5895,3234],{},[37,5897,3237],{},[37,5899,3240],{},[15,5901,3243],{},[10,5903,3247],{"id":3246},[26,5905,3251],{"id":3250},[190,5907,5908],{"summary":3254},[15,5909,3257,5910,3262],{},[744,5911,3261],{"href":3260},[190,5913,5914],{"summary":3265},[15,5915,3268],{},[190,5917,5918],{"summary":3271},[15,5919,3274],{},[190,5921,5922],{"summary":3277},[15,5923,3280,5924,3283,5926,3286,5928,3289,5930,310],{},[229,5925,269],{},[229,5927,244],{},[229,5929,282],{},[744,5931,3048],{"href":3292},[26,5933,3296],{"id":3295},[190,5935,5936],{"summary":3299},[15,5937,3302,5938,3306,5940,339,5942,3122,5944,3313,5946,3316,5948,306,5950,3323],{},[229,5939,3305],{},[229,5941,785],{},[229,5943,811],{},[229,5945,695],{},[229,5947,2836],{},[229,5949,3319],{},[229,5951,3322],{},[190,5953,5954],{"summary":3326},[15,5955,3329,5956,3332],{},[229,5957,3027],{},[26,5959,3336],{"id":3335},[190,5961,5962],{"summary":3339},[15,5963,3342,5964,310],{},[229,5965,3017],{},[190,5967,5968],{"summary":3347},[15,5969,3350],{},[190,5971,5972],{"summary":3353},[15,5973,3356],{},[190,5975,5976],{"summary":3359},[15,5977,3362,5978,3366,5980,310],{},[744,5979,3220],{"href":3365},[744,5981,3370],{"href":3369},[10,5983,3374],{"id":3373},[15,5985,3377],{},[3379,5987,3381],{},{"title":580,"searchDepth":806,"depth":806,"links":5989},[5990,5991,5997,6002,6003,6004,6005,6010],{"id":12,"depth":778,"text":13},{"id":20,"depth":778,"text":21,"children":5992},[5993,5994,5995,5996],{"id":28,"depth":806,"text":29},{"id":60,"depth":806,"text":61},{"id":202,"depth":806,"text":203},{"id":290,"depth":806,"text":291},{"id":431,"depth":778,"text":432,"children":5998},[5999,6000,6001],{"id":583,"depth":806,"text":584},{"id":2342,"depth":806,"text":2343},{"id":3037,"depth":806,"text":3038},{"id":3047,"depth":778,"text":3048},{"id":3212,"depth":778,"text":3213},{"id":3219,"depth":778,"text":3220},{"id":3246,"depth":778,"text":3247,"children":6006},[6007,6008,6009],{"id":3250,"depth":806,"text":3251},{"id":3295,"depth":806,"text":3296},{"id":3335,"depth":806,"text":3336},{"id":3373,"depth":778,"text":3374},{},{"title":5,"description":3406},{"loc":3411,"lastmod":3414},1792411539419]