[{"data":1,"prerenderedAt":1151},["ShallowReactive",2],{"layout-sidebar-lab-terraform_aws_lambda_01":3,"lab-terraform_aws_lambda_01":672},{"id":4,"title":5,"body":6,"date":654,"description":655,"doc":656,"extension":659,"git":660,"image":661,"isExperimentation":132,"meta":662,"navigation":132,"path":663,"seo":664,"stem":665,"tags":666,"type":667,"updatedAt":660,"website":660,"__hash__":671},"laboratoire\u002Flaboratoire\u002Fterraform_aws_lambda_01.md","Terraform - AWS Lambda",{"type":7,"value":8,"toc":642},"minimark",[9,13,17,20,33,38,41,44,48,53,56,60,63,66,72,75,78,238,242,245,248,251,280,284,287,290,341,345,369,372,514,518,521,535,541,544,546,631,635,638],[10,11,5],"h1",{"id":12},"terraform-aws-lambda",[14,15,16],"p",{},"Cette expérimentation consiste à mettre en place une fonction Lambda sur AWS avec Terraform.",[14,18,19],{},"L'infrastructure est composée de :",[21,22,23,27,30],"ul",{},[24,25,26],"li",{},"Une fonction Lambda",[24,28,29],{},"Un lien URL pour accéder à la fonction Lambda",[24,31,32],{},"Un budget pour surveiller les coûts de la Lambda",[34,35,37],"h2",{"id":36},"objectif","Objectif",[14,39,40],{},"L'objectif est de comprendre les fonctions Lambda et leur intérêt dans une architecture serverless.",[14,42,43],{},"Ainsi que de mettre en place un budget pour surveiller les coûts de la Lambda.",[34,45,47],{"id":46},"technique","Technique",[49,50,52],"h3",{"id":51},"lambda","Lambda",[14,54,55],{},"Je vais détailler dans ce post les étapes mises en place pour créer une fonction Lambda sur AWS avec Terraform.",[49,57,59],{"id":58},"budget","Budget",[14,61,62],{},"Commençons par le budget, j'ai choisi de mettre en place un budget de 1$ par mois pour surveiller les coûts de la Lambda. Même si l'utilisation de la Lambda est gratuite, il est toujours intéressant de mettre en place un budget pour surveiller les coûts.",[14,64,65],{},"D'autant plus que la version que j'ai mise en place est une version gratuite non restreinte d'accès : aucun VPC n'a été mis en place ni aucun groupe de sécurité.",[67,68,69],"warning",{},[14,70,71],{},"N'importe qui peut accéder à la Lambda via l'URL. Je précise que l'objectif était pédagogique et l'instance a été détruite instantanément.",[14,73,74],{},"Les alertes sont envoyées par e-mail à l'adresse configurée dans le code.\nJ'ai fixé à 50% la première alerte et une prévision de 100% pour la seconde alerte.",[14,76,77],{},"Voici un extrait du code Terraform qui m'a permis de créer un budget :",[79,80,85],"pre",{"className":81,"code":82,"language":83,"meta":84,"style":84},"language-yaml shiki shiki-themes material-theme-lighter github-light monokai","resource \"aws_budgets_budget\" \"ec2_budget\" {\n  name         = \"budget-lambda-alerte\"\n  budget_type  = \"COST\"\n  limit_amount = \"1\"\n  limit_unit   = \"USD\"\n  time_unit    = \"MONTHLY\"\n\n  # Alerte 1 : 50% du budget réel consommé\n  notification {\n    comparison_operator        = \"GREATER_THAN\"\n    threshold                  = 50\n    threshold_type             = \"PERCENTAGE\"\n    notification_type          = \"ACTUAL\"\n    subscriber_email_addresses = [\"contact@kernellab.fr\"]\n  }\n\n  # Alerte 2 : Prévision de dépassement de 100%\n  notification {\n    comparison_operator        = \"GREATER_THAN\"\n    threshold                  = 100\n    threshold_type             = \"PERCENTAGE\"\n    notification_type          = \"FORECASTED\"\n    subscriber_email_addresses = [\"contact@kernellab.fr\"]\n  }\n}\n","yaml","",[86,87,88,97,103,109,115,121,127,134,141,147,153,159,165,171,177,184,189,195,200,205,211,216,222,227,232],"code",{"__ignoreMap":84},[89,90,93],"span",{"class":91,"line":92},"line",1,[89,94,96],{"class":95},"sqNgn","resource \"aws_budgets_budget\" \"ec2_budget\" {\n",[89,98,100],{"class":91,"line":99},2,[89,101,102],{"class":95},"  name         = \"budget-lambda-alerte\"\n",[89,104,106],{"class":91,"line":105},3,[89,107,108],{"class":95},"  budget_type  = \"COST\"\n",[89,110,112],{"class":91,"line":111},4,[89,113,114],{"class":95},"  limit_amount = \"1\"\n",[89,116,118],{"class":91,"line":117},5,[89,119,120],{"class":95},"  limit_unit   = \"USD\"\n",[89,122,124],{"class":91,"line":123},6,[89,125,126],{"class":95},"  time_unit    = \"MONTHLY\"\n",[89,128,130],{"class":91,"line":129},7,[89,131,133],{"emptyLinePlaceholder":132},true,"\n",[89,135,137],{"class":91,"line":136},8,[89,138,140],{"class":139},"skxtS","  # Alerte 1 : 50% du budget réel consommé\n",[89,142,144],{"class":91,"line":143},9,[89,145,146],{"class":95},"  notification {\n",[89,148,150],{"class":91,"line":149},10,[89,151,152],{"class":95},"    comparison_operator        = \"GREATER_THAN\"\n",[89,154,156],{"class":91,"line":155},11,[89,157,158],{"class":95},"    threshold                  = 50\n",[89,160,162],{"class":91,"line":161},12,[89,163,164],{"class":95},"    threshold_type             = \"PERCENTAGE\"\n",[89,166,168],{"class":91,"line":167},13,[89,169,170],{"class":95},"    notification_type          = \"ACTUAL\"\n",[89,172,174],{"class":91,"line":173},14,[89,175,176],{"class":95},"    subscriber_email_addresses = [\"contact@kernellab.fr\"]\n",[89,178,180],{"class":91,"line":179},15,[89,181,183],{"class":182},"s_bef","  }\n",[89,185,187],{"class":91,"line":186},16,[89,188,133],{"emptyLinePlaceholder":132},[89,190,192],{"class":91,"line":191},17,[89,193,194],{"class":139},"  # Alerte 2 : Prévision de dépassement de 100%\n",[89,196,198],{"class":91,"line":197},18,[89,199,146],{"class":95},[89,201,203],{"class":91,"line":202},19,[89,204,152],{"class":95},[89,206,208],{"class":91,"line":207},20,[89,209,210],{"class":95},"    threshold                  = 100\n",[89,212,214],{"class":91,"line":213},21,[89,215,164],{"class":95},[89,217,219],{"class":91,"line":218},22,[89,220,221],{"class":95},"    notification_type          = \"FORECASTED\"\n",[89,223,225],{"class":91,"line":224},23,[89,226,176],{"class":95},[89,228,230],{"class":91,"line":229},24,[89,231,183],{"class":182},[89,233,235],{"class":91,"line":234},25,[89,236,237],{"class":182},"}\n",[49,239,241],{"id":240},"fonction-python","Fonction Python",[14,243,244],{},"Pour pouvoir envoyer le code Python sur AWS, il faut le compresser dans un fichier zip.",[14,246,247],{},"Pour ce faire, j'ai mis une ressource en place qui va compresser le code Python qui se situe à la racine du repository dans un fichier zip.",[14,249,250],{},"Voici un extrait du code Terraform qui m'a permis de créer un fichier zip :",[79,252,254],{"className":81,"code":253,"language":83,"meta":84,"style":84},"data \"archive_file\" \"lambda\" {\n  type        = \"zip\"\n  source_file = \"${path.module}\u002F..\u002Fmain.py\"\n  output_path = \"${path.module}\u002F..\u002Ffunction.zip\"\n}\n",[86,255,256,261,266,271,276],{"__ignoreMap":84},[89,257,258],{"class":91,"line":92},[89,259,260],{"class":95},"data \"archive_file\" \"lambda\" {\n",[89,262,263],{"class":91,"line":99},[89,264,265],{"class":95},"  type        = \"zip\"\n",[89,267,268],{"class":91,"line":105},[89,269,270],{"class":95},"  source_file = \"${path.module}\u002F..\u002Fmain.py\"\n",[89,272,273],{"class":91,"line":111},[89,274,275],{"class":95},"  output_path = \"${path.module}\u002F..\u002Ffunction.zip\"\n",[89,277,278],{"class":91,"line":117},[89,279,237],{"class":182},[49,281,283],{"id":282},"logs-et-metrics","Logs et metrics",[14,285,286],{},"Pour pouvoir surveiller les logs et les métriques de la Lambda, j'ai mis une ressource en place qui va créer un log group et un dashboard.",[14,288,289],{},"Voici un extrait du code Terraform qui m'a permis de créer un log group sur CloudWatch :",[79,291,293],{"className":81,"code":292,"language":83,"meta":84,"style":84},"resource \"aws_cloudwatch_log_group\" \"example\" {\n  name              = \"\u002Faws\u002Flambda\u002Flambda_function_python\"\n  retention_in_days = 14\n\n  tags = {\n    Environment = \"production\"\n    Application = \"example\"\n  }\n\n}\n",[86,294,295,300,305,310,314,319,324,329,333,337],{"__ignoreMap":84},[89,296,297],{"class":91,"line":92},[89,298,299],{"class":95},"resource \"aws_cloudwatch_log_group\" \"example\" {\n",[89,301,302],{"class":91,"line":99},[89,303,304],{"class":95},"  name              = \"\u002Faws\u002Flambda\u002Flambda_function_python\"\n",[89,306,307],{"class":91,"line":105},[89,308,309],{"class":95},"  retention_in_days = 14\n",[89,311,312],{"class":91,"line":111},[89,313,133],{"emptyLinePlaceholder":132},[89,315,316],{"class":91,"line":117},[89,317,318],{"class":95},"  tags = {\n",[89,320,321],{"class":91,"line":123},[89,322,323],{"class":95},"    Environment = \"production\"\n",[89,325,326],{"class":91,"line":129},[89,327,328],{"class":95},"    Application = \"example\"\n",[89,330,331],{"class":91,"line":136},[89,332,183],{"class":182},[89,334,335],{"class":91,"line":143},[89,336,133],{"emptyLinePlaceholder":132},[89,338,339],{"class":91,"line":149},[89,340,237],{"class":182},[49,342,344],{"id":343},"création-de-la-lambda","Création de la lambda",[14,346,347,348,352,353,356,357,360,361,364,365,368],{},"Cet extrait de code permet de créer la fonction Lambda sur AWS. On peut remarquer l'utilisation de la variable ",[349,350,351],"strong",{},"filename"," qui est le chemin du fichier zip créé précédemment. On utilise également la variable ",[349,354,355],{},"function_name"," qui est le nom de la fonction Lambda, ainsi que le ",[349,358,359],{},"role"," IAM qui sera utilisé pour son exécution. Le ",[349,362,363],{},"handler"," définit le point d'entrée du code et ",[349,366,367],{},"code_sha256"," assure l'intégrité du fichier zip.",[14,370,371],{},"Voici un exemple du code:",[79,373,375],{"className":81,"code":374,"language":83,"meta":84,"style":84},"resource \"aws_lambda_function\" \"example\" {\n  filename      = data.archive_file.lambda.output_path\n  function_name = \"example_lambda_function\"\n  role          = aws_iam_role.example.arn\n  handler       = \"main.lambda_handler\"\n  code_sha256   = data.archive_file.lambda.output_base64sha256\n\n  runtime = \"python3.10\"\n\n  environment {\n    variables = {\n      ENVIRONMENT = \"production\"\n      LOG_LEVEL   = \"info\"\n    }\n  }\n\n  tags = {\n    Environment = \"production\"\n    Application = \"example\"\n  }\n\n  logging_config {\n    log_format            = \"JSON\"\n    application_log_level = \"INFO\"\n    system_log_level      = \"WARN\"\n  }\n\n  depends_on = [aws_cloudwatch_log_group.example]\n}\n",[86,376,377,382,387,392,397,402,407,411,416,420,425,430,435,440,445,449,453,457,461,465,469,473,478,483,488,493,498,503,509],{"__ignoreMap":84},[89,378,379],{"class":91,"line":92},[89,380,381],{"class":95},"resource \"aws_lambda_function\" \"example\" {\n",[89,383,384],{"class":91,"line":99},[89,385,386],{"class":95},"  filename      = data.archive_file.lambda.output_path\n",[89,388,389],{"class":91,"line":105},[89,390,391],{"class":95},"  function_name = \"example_lambda_function\"\n",[89,393,394],{"class":91,"line":111},[89,395,396],{"class":95},"  role          = aws_iam_role.example.arn\n",[89,398,399],{"class":91,"line":117},[89,400,401],{"class":95},"  handler       = \"main.lambda_handler\"\n",[89,403,404],{"class":91,"line":123},[89,405,406],{"class":95},"  code_sha256   = data.archive_file.lambda.output_base64sha256\n",[89,408,409],{"class":91,"line":129},[89,410,133],{"emptyLinePlaceholder":132},[89,412,413],{"class":91,"line":136},[89,414,415],{"class":95},"  runtime = \"python3.10\"\n",[89,417,418],{"class":91,"line":143},[89,419,133],{"emptyLinePlaceholder":132},[89,421,422],{"class":91,"line":149},[89,423,424],{"class":95},"  environment {\n",[89,426,427],{"class":91,"line":155},[89,428,429],{"class":95},"    variables = {\n",[89,431,432],{"class":91,"line":161},[89,433,434],{"class":95},"      ENVIRONMENT = \"production\"\n",[89,436,437],{"class":91,"line":167},[89,438,439],{"class":95},"      LOG_LEVEL   = \"info\"\n",[89,441,442],{"class":91,"line":173},[89,443,444],{"class":182},"    }\n",[89,446,447],{"class":91,"line":179},[89,448,183],{"class":182},[89,450,451],{"class":91,"line":186},[89,452,133],{"emptyLinePlaceholder":132},[89,454,455],{"class":91,"line":191},[89,456,318],{"class":95},[89,458,459],{"class":91,"line":197},[89,460,323],{"class":95},[89,462,463],{"class":91,"line":202},[89,464,328],{"class":95},[89,466,467],{"class":91,"line":207},[89,468,183],{"class":182},[89,470,471],{"class":91,"line":213},[89,472,133],{"emptyLinePlaceholder":132},[89,474,475],{"class":91,"line":218},[89,476,477],{"class":95},"  logging_config {\n",[89,479,480],{"class":91,"line":224},[89,481,482],{"class":95},"    log_format            = \"JSON\"\n",[89,484,485],{"class":91,"line":229},[89,486,487],{"class":95},"    application_log_level = \"INFO\"\n",[89,489,490],{"class":91,"line":234},[89,491,492],{"class":95},"    system_log_level      = \"WARN\"\n",[89,494,496],{"class":91,"line":495},26,[89,497,183],{"class":182},[89,499,501],{"class":91,"line":500},27,[89,502,133],{"emptyLinePlaceholder":132},[89,504,506],{"class":91,"line":505},28,[89,507,508],{"class":95},"  depends_on = [aws_cloudwatch_log_group.example]\n",[89,510,512],{"class":91,"line":511},29,[89,513,237],{"class":182},[49,515,517],{"id":516},"url-daccès-à-la-lambda","URL d'accès à la Lambda",[14,519,520],{},"Pour pouvoir déclencher la fonction, j'ai décidé de l'utiliser via une URL. J'ai donc mis en place une ressource qui va créer une URL d'accès public.",[14,522,523,524,526,527,530,531,534],{},"On peut remarquer l'utilisation de la variable ",[349,525,355],{}," et du type d'autorisation (",[349,528,529],{},"authorization_type","). On configure également les paramètres ",[349,532,533],{},"cors"," pour l'accès.",[536,537,538],"note",{},[14,539,540],{},"Le CORS est volontairement configuré sur \"*\" pour permettre l'accès à n'importe qui. Dans un contexte de production, il faudrait mettre en place une authentification et restreindre les origines.",[14,542,543],{},"L'output permet également de récupérer l'URL directement dans le terminal après la construction.",[14,545,371],{},[79,547,549],{"className":81,"code":548,"language":83,"meta":84,"style":84},"resource \"aws_lambda_function_url\" \"example\" {\n  function_name      = aws_lambda_function.example.function_name\n  authorization_type = \"NONE\"\n\n  cors {\n    allow_credentials = true\n    allow_origins     = [\"*\"]\n    allow_methods     = [\"GET\"]\n    allow_headers     = [\"date\", \"keep-alive\"]\n    expose_headers    = [\"keep-alive\", \"date\"]\n    max_age           = 86400\n  }\n}\n\noutput \"lambda_url\" {\n  value = aws_lambda_function_url.example.function_url\n}\n",[86,550,551,556,561,566,570,575,580,585,590,595,600,605,609,613,617,622,627],{"__ignoreMap":84},[89,552,553],{"class":91,"line":92},[89,554,555],{"class":95},"resource \"aws_lambda_function_url\" \"example\" {\n",[89,557,558],{"class":91,"line":99},[89,559,560],{"class":95},"  function_name      = aws_lambda_function.example.function_name\n",[89,562,563],{"class":91,"line":105},[89,564,565],{"class":95},"  authorization_type = \"NONE\"\n",[89,567,568],{"class":91,"line":111},[89,569,133],{"emptyLinePlaceholder":132},[89,571,572],{"class":91,"line":117},[89,573,574],{"class":95},"  cors {\n",[89,576,577],{"class":91,"line":123},[89,578,579],{"class":95},"    allow_credentials = true\n",[89,581,582],{"class":91,"line":129},[89,583,584],{"class":95},"    allow_origins     = [\"*\"]\n",[89,586,587],{"class":91,"line":136},[89,588,589],{"class":95},"    allow_methods     = [\"GET\"]\n",[89,591,592],{"class":91,"line":143},[89,593,594],{"class":95},"    allow_headers     = [\"date\", \"keep-alive\"]\n",[89,596,597],{"class":91,"line":149},[89,598,599],{"class":95},"    expose_headers    = [\"keep-alive\", \"date\"]\n",[89,601,602],{"class":91,"line":155},[89,603,604],{"class":95},"    max_age           = 86400\n",[89,606,607],{"class":91,"line":161},[89,608,183],{"class":182},[89,610,611],{"class":91,"line":167},[89,612,237],{"class":182},[89,614,615],{"class":91,"line":173},[89,616,133],{"emptyLinePlaceholder":132},[89,618,619],{"class":91,"line":179},[89,620,621],{"class":95},"output \"lambda_url\" {\n",[89,623,624],{"class":91,"line":186},[89,625,626],{"class":95},"  value = aws_lambda_function_url.example.function_url\n",[89,628,629],{"class":91,"line":191},[89,630,237],{"class":182},[34,632,634],{"id":633},"conclusion","Conclusion",[14,636,637],{},"Cette expérimentation m'a permis de comprendre les fonctions Lambda et leur intérêt dans une architecture serverless, tout en mettant en place un monitoring des coûts via un budget AWS.",[639,640,641],"style",{},"html pre.shiki code .sqNgn, html code.shiki .sqNgn{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#E6DB74}html pre.shiki code .skxtS, html code.shiki .skxtS{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#88846F;--shiki-dark-font-style:inherit}html pre.shiki code .s_bef, html code.shiki .s_bef{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#F8F8F2}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);}",{"title":84,"searchDepth":99,"depth":99,"links":643},[644,645,653],{"id":36,"depth":99,"text":37},{"id":46,"depth":99,"text":47,"children":646},[647,648,649,650,651,652],{"id":51,"depth":105,"text":52},{"id":58,"depth":105,"text":59},{"id":240,"depth":105,"text":241},{"id":282,"depth":105,"text":283},{"id":343,"depth":105,"text":344},{"id":516,"depth":105,"text":517},{"id":633,"depth":99,"text":634},"2026-04-09","Création d'une fonction Lambda Python sur AWS avec Terraform",[657,658],"https:\u002F\u002Fregistry.terraform.io\u002Fproviders\u002F-\u002Faws\u002Flatest\u002Fdocs\u002Fresources\u002Flambda_function_url","https:\u002F\u002Fdeveloper.hashicorp.com\u002Fterraform\u002Ftutorials\u002Faws-get-started\u002Faws-create","md",null,"\u002Flaboratoire\u002Fterraform_aws_lambda_01.png",{},"\u002Flaboratoire\u002Fterraform_aws_lambda_01",{"title":5,"description":655},"laboratoire\u002Fterraform_aws_lambda_01",[667,668,669,670,51,58],"devops","terraform","aws","python","dIBE-Ro7KrbtMnM9EiRnSlP2X5qgqmgfbl5P_bTKzik",{"id":4,"title":5,"body":673,"date":654,"description":655,"doc":1147,"extension":659,"git":660,"image":661,"isExperimentation":132,"meta":1148,"navigation":132,"path":663,"seo":1149,"stem":665,"tags":1150,"type":667,"updatedAt":660,"website":660,"__hash__":671},{"type":7,"value":674,"toc":1135},[675,677,679,681,689,691,693,695,697,699,701,703,705,707,711,713,715,819,821,823,825,827,851,853,855,857,901,903,915,917,1037,1039,1041,1049,1053,1055,1057,1129,1131,1133],[10,676,5],{"id":12},[14,678,16],{},[14,680,19],{},[21,682,683,685,687],{},[24,684,26],{},[24,686,29],{},[24,688,32],{},[34,690,37],{"id":36},[14,692,40],{},[14,694,43],{},[34,696,47],{"id":46},[49,698,52],{"id":51},[14,700,55],{},[49,702,59],{"id":58},[14,704,62],{},[14,706,65],{},[67,708,709],{},[14,710,71],{},[14,712,74],{},[14,714,77],{},[79,716,717],{"className":81,"code":82,"language":83,"meta":84,"style":84},[86,718,719,723,727,731,735,739,743,747,751,755,759,763,767,771,775,779,783,787,791,795,799,803,807,811,815],{"__ignoreMap":84},[89,720,721],{"class":91,"line":92},[89,722,96],{"class":95},[89,724,725],{"class":91,"line":99},[89,726,102],{"class":95},[89,728,729],{"class":91,"line":105},[89,730,108],{"class":95},[89,732,733],{"class":91,"line":111},[89,734,114],{"class":95},[89,736,737],{"class":91,"line":117},[89,738,120],{"class":95},[89,740,741],{"class":91,"line":123},[89,742,126],{"class":95},[89,744,745],{"class":91,"line":129},[89,746,133],{"emptyLinePlaceholder":132},[89,748,749],{"class":91,"line":136},[89,750,140],{"class":139},[89,752,753],{"class":91,"line":143},[89,754,146],{"class":95},[89,756,757],{"class":91,"line":149},[89,758,152],{"class":95},[89,760,761],{"class":91,"line":155},[89,762,158],{"class":95},[89,764,765],{"class":91,"line":161},[89,766,164],{"class":95},[89,768,769],{"class":91,"line":167},[89,770,170],{"class":95},[89,772,773],{"class":91,"line":173},[89,774,176],{"class":95},[89,776,777],{"class":91,"line":179},[89,778,183],{"class":182},[89,780,781],{"class":91,"line":186},[89,782,133],{"emptyLinePlaceholder":132},[89,784,785],{"class":91,"line":191},[89,786,194],{"class":139},[89,788,789],{"class":91,"line":197},[89,790,146],{"class":95},[89,792,793],{"class":91,"line":202},[89,794,152],{"class":95},[89,796,797],{"class":91,"line":207},[89,798,210],{"class":95},[89,800,801],{"class":91,"line":213},[89,802,164],{"class":95},[89,804,805],{"class":91,"line":218},[89,806,221],{"class":95},[89,808,809],{"class":91,"line":224},[89,810,176],{"class":95},[89,812,813],{"class":91,"line":229},[89,814,183],{"class":182},[89,816,817],{"class":91,"line":234},[89,818,237],{"class":182},[49,820,241],{"id":240},[14,822,244],{},[14,824,247],{},[14,826,250],{},[79,828,829],{"className":81,"code":253,"language":83,"meta":84,"style":84},[86,830,831,835,839,843,847],{"__ignoreMap":84},[89,832,833],{"class":91,"line":92},[89,834,260],{"class":95},[89,836,837],{"class":91,"line":99},[89,838,265],{"class":95},[89,840,841],{"class":91,"line":105},[89,842,270],{"class":95},[89,844,845],{"class":91,"line":111},[89,846,275],{"class":95},[89,848,849],{"class":91,"line":117},[89,850,237],{"class":182},[49,852,283],{"id":282},[14,854,286],{},[14,856,289],{},[79,858,859],{"className":81,"code":292,"language":83,"meta":84,"style":84},[86,860,861,865,869,873,877,881,885,889,893,897],{"__ignoreMap":84},[89,862,863],{"class":91,"line":92},[89,864,299],{"class":95},[89,866,867],{"class":91,"line":99},[89,868,304],{"class":95},[89,870,871],{"class":91,"line":105},[89,872,309],{"class":95},[89,874,875],{"class":91,"line":111},[89,876,133],{"emptyLinePlaceholder":132},[89,878,879],{"class":91,"line":117},[89,880,318],{"class":95},[89,882,883],{"class":91,"line":123},[89,884,323],{"class":95},[89,886,887],{"class":91,"line":129},[89,888,328],{"class":95},[89,890,891],{"class":91,"line":136},[89,892,183],{"class":182},[89,894,895],{"class":91,"line":143},[89,896,133],{"emptyLinePlaceholder":132},[89,898,899],{"class":91,"line":149},[89,900,237],{"class":182},[49,902,344],{"id":343},[14,904,347,905,352,907,356,909,360,911,364,913,368],{},[349,906,351],{},[349,908,355],{},[349,910,359],{},[349,912,363],{},[349,914,367],{},[14,916,371],{},[79,918,919],{"className":81,"code":374,"language":83,"meta":84,"style":84},[86,920,921,925,929,933,937,941,945,949,953,957,961,965,969,973,977,981,985,989,993,997,1001,1005,1009,1013,1017,1021,1025,1029,1033],{"__ignoreMap":84},[89,922,923],{"class":91,"line":92},[89,924,381],{"class":95},[89,926,927],{"class":91,"line":99},[89,928,386],{"class":95},[89,930,931],{"class":91,"line":105},[89,932,391],{"class":95},[89,934,935],{"class":91,"line":111},[89,936,396],{"class":95},[89,938,939],{"class":91,"line":117},[89,940,401],{"class":95},[89,942,943],{"class":91,"line":123},[89,944,406],{"class":95},[89,946,947],{"class":91,"line":129},[89,948,133],{"emptyLinePlaceholder":132},[89,950,951],{"class":91,"line":136},[89,952,415],{"class":95},[89,954,955],{"class":91,"line":143},[89,956,133],{"emptyLinePlaceholder":132},[89,958,959],{"class":91,"line":149},[89,960,424],{"class":95},[89,962,963],{"class":91,"line":155},[89,964,429],{"class":95},[89,966,967],{"class":91,"line":161},[89,968,434],{"class":95},[89,970,971],{"class":91,"line":167},[89,972,439],{"class":95},[89,974,975],{"class":91,"line":173},[89,976,444],{"class":182},[89,978,979],{"class":91,"line":179},[89,980,183],{"class":182},[89,982,983],{"class":91,"line":186},[89,984,133],{"emptyLinePlaceholder":132},[89,986,987],{"class":91,"line":191},[89,988,318],{"class":95},[89,990,991],{"class":91,"line":197},[89,992,323],{"class":95},[89,994,995],{"class":91,"line":202},[89,996,328],{"class":95},[89,998,999],{"class":91,"line":207},[89,1000,183],{"class":182},[89,1002,1003],{"class":91,"line":213},[89,1004,133],{"emptyLinePlaceholder":132},[89,1006,1007],{"class":91,"line":218},[89,1008,477],{"class":95},[89,1010,1011],{"class":91,"line":224},[89,1012,482],{"class":95},[89,1014,1015],{"class":91,"line":229},[89,1016,487],{"class":95},[89,1018,1019],{"class":91,"line":234},[89,1020,492],{"class":95},[89,1022,1023],{"class":91,"line":495},[89,1024,183],{"class":182},[89,1026,1027],{"class":91,"line":500},[89,1028,133],{"emptyLinePlaceholder":132},[89,1030,1031],{"class":91,"line":505},[89,1032,508],{"class":95},[89,1034,1035],{"class":91,"line":511},[89,1036,237],{"class":182},[49,1038,517],{"id":516},[14,1040,520],{},[14,1042,523,1043,526,1045,530,1047,534],{},[349,1044,355],{},[349,1046,529],{},[349,1048,533],{},[536,1050,1051],{},[14,1052,540],{},[14,1054,543],{},[14,1056,371],{},[79,1058,1059],{"className":81,"code":548,"language":83,"meta":84,"style":84},[86,1060,1061,1065,1069,1073,1077,1081,1085,1089,1093,1097,1101,1105,1109,1113,1117,1121,1125],{"__ignoreMap":84},[89,1062,1063],{"class":91,"line":92},[89,1064,555],{"class":95},[89,1066,1067],{"class":91,"line":99},[89,1068,560],{"class":95},[89,1070,1071],{"class":91,"line":105},[89,1072,565],{"class":95},[89,1074,1075],{"class":91,"line":111},[89,1076,133],{"emptyLinePlaceholder":132},[89,1078,1079],{"class":91,"line":117},[89,1080,574],{"class":95},[89,1082,1083],{"class":91,"line":123},[89,1084,579],{"class":95},[89,1086,1087],{"class":91,"line":129},[89,1088,584],{"class":95},[89,1090,1091],{"class":91,"line":136},[89,1092,589],{"class":95},[89,1094,1095],{"class":91,"line":143},[89,1096,594],{"class":95},[89,1098,1099],{"class":91,"line":149},[89,1100,599],{"class":95},[89,1102,1103],{"class":91,"line":155},[89,1104,604],{"class":95},[89,1106,1107],{"class":91,"line":161},[89,1108,183],{"class":182},[89,1110,1111],{"class":91,"line":167},[89,1112,237],{"class":182},[89,1114,1115],{"class":91,"line":173},[89,1116,133],{"emptyLinePlaceholder":132},[89,1118,1119],{"class":91,"line":179},[89,1120,621],{"class":95},[89,1122,1123],{"class":91,"line":186},[89,1124,626],{"class":95},[89,1126,1127],{"class":91,"line":191},[89,1128,237],{"class":182},[34,1130,634],{"id":633},[14,1132,637],{},[639,1134,641],{},{"title":84,"searchDepth":99,"depth":99,"links":1136},[1137,1138,1146],{"id":36,"depth":99,"text":37},{"id":46,"depth":99,"text":47,"children":1139},[1140,1141,1142,1143,1144,1145],{"id":51,"depth":105,"text":52},{"id":58,"depth":105,"text":59},{"id":240,"depth":105,"text":241},{"id":282,"depth":105,"text":283},{"id":343,"depth":105,"text":344},{"id":516,"depth":105,"text":517},{"id":633,"depth":99,"text":634},[657,658],{},{"title":5,"description":655},[667,668,669,670,51,58],1777912144559]