sample-aws-pricing-calculator-mcp 1.3.7 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mcp-server.js +4 -4
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -82,7 +82,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
82
82
|
## ${n.name||"Group"}
|
|
83
83
|
`),n.totalCost?.monthly!=null&&t.push(`**Group Monthly:** $${n.totalCost.monthly.toFixed(2)}
|
|
84
84
|
`),n.services&&i(n.services);return t.join(`
|
|
85
|
-
`)}xk.exports={PARTITIONS:Fr,resolvePartition:jce,loadManifest:Ace,loadRegionList:Tce,findService:Dce,findServiceCandidates:Rce,searchServices:Mce,fetchServiceDefinition:Nce,saveEstimate:zce,extractInputFields:Lce,enrichFieldsWithMetadata:Fce,loadSelectorAggregations:kce,loadSelectorDefaults:Cce,parseDoubleEncodedResponse:v_,fetchEstimate:Vce,estimateToMarkdown:Jce,extractCostsFromSavedBlob:Hce}});var Pk=_((jxe,Ok)=>{var Gce=Iu(),{GetCommand:Kce,PutCommand:Wce,DeleteCommand:Xce,DynamoDBDocumentClient:Yce}=require("@aws-sdk/lib-dynamodb"),{DynamoDBClient:Qce}=require("@aws-sdk/client-dynamodb"),__=class{constructor({tableName:t,region:r,docClient:i,ttlSeconds:n}={}){if(!t)throw new Error("DynamoEstimateStore: tableName is required");this.tableName=t,this.ttlSeconds=n,this._docClient=i||Yce.from(new Qce({region:r}))}async get(t){let r=await this._docClient.send(new Kce({TableName:this.tableName,Key:{id:t}}));if(!r.Item||!r.Item.snapshot)return null;let i=JSON.parse(r.Item.snapshot);return Gce.fromJSON(i)}async put(t){let r={id:t.id,snapshot:JSON.stringify(t.toJSON())};this.ttlSeconds&&this.ttlSeconds>0&&(r.expiresAt=Math.floor(Date.now()/1e3)+this.ttlSeconds),await this._docClient.send(new Wce({TableName:this.tableName,Item:r}))}async delete(t){await this._docClient.send(new Xce({TableName:this.tableName,Key:{id:t}}))}};Ok.exports={DynamoEstimateStore:__}});var jk=_((Exe,Ik)=>{var eue=Iu(),hm=class{constructor(){this._snapshots=new Map}async get(t){let r=this._snapshots.get(t);return r?eue.fromJSON(JSON.parse(JSON.stringify(r))):null}async put(t){this._snapshots.set(t.id,t.toJSON())}async delete(t){this._snapshots.delete(t)}};function tue(e=process.env){let t=(e.ESTIMATES_STORE||"memory").toLowerCase();if(t==="memory")return new hm;if(t==="dynamodb"){let{DynamoEstimateStore:r}=Pk();return new r({tableName:e.ESTIMATES_TABLE,region:e.AWS_REGION||e.AWS_DEFAULT_REGION,ttlSeconds:e.ESTIMATES_TTL_SECONDS?Number(e.ESTIMATES_TTL_SECONDS):void 0})}throw new Error(`Unknown ESTIMATES_STORE: "${t}". Valid: "memory", "dynamodb".`)}Ik.exports={MemoryEstimateStore:hm,createEstimateStore:tue}});var Ek=_((Txe,rue)=>{rue.exports={$schema:"http://json-schema.org/draft-07/schema#",title:"AWS Pricing Calculator Service Catalog Entry",type:"object",required:["serviceCode","displayName","status","minimalConfig"],properties:{$schema:{type:"string"},serviceCode:{type:"string",pattern:"^[a-zA-Z][a-zA-Z0-9]*$",description:"Canonical service code from manifest/en_US.json (e.g. aWSLambda, ec2Enhancement)."},displayName:{type:"string",minLength:1},templateId:{type:"string",description:"The estimateFor value the calculator expects. Optional for parent envelopes whose children carry their own template ids."},status:{type:"string",enum:["verified","partial","unverified","broken"],description:"verified = round-trip test passes; partial = saves+renders but with Required-input; unverified = not yet probed; broken = known to fail."},lastVerifiedAt:{type:"string",format:"date",description:"ISO date of the most recent successful round-trip. Required when status is 'verified' or 'partial'."},verifiedEstimateId:{type:"string",pattern:"^[a-f0-9]{40}$",description:"SHA1 estimate id from the most recent successful round-trip. Required when status is 'verified' or 'partial'."},required:{type:"array",items:{$ref:"#/definitions/field"},default:[]},traps:{type:"array",items:{type:"string",minLength:1},description:"Human-readable gotchas an agent or author should know. Free-form prose.",default:[]},subServices:{type:"array",items:{$ref:"#/definitions/subService"},description:"For parent envelopes only \u2014 describes each child's serviceCode, estimateFor, and required fields.",default:[]},minimalConfig:{type:"object",description:"The smallest config that produces an editable estimate. For parent envelopes, keyed by sub-service code; for plain services, the config object itself."},defaultFields:{type:"object",additionalProperties:!0,description:"Per-field literal saved-blob shapes injected at add_service time when the agent omits the key. Use for fields the calculator silently demands but the manifest does NOT mark validations.required (the case where get_service_fields doesn't expose them and the lint can't refuse without them). Authors declare the canonical envelope; lib/mcp/handler-helpers.js#applyDefaultFields merges any missing keys into the user's config before estimate.addService."}},allOf:[{if:{required:["status"],properties:{status:{enum:["verified","partial"]}}},then:{required:["lastVerifiedAt","verifiedEstimateId"]}}],definitions:{field:{type:"object",required:["field","hint"],properties:{field:{type:"string",minLength:1},hint:{type:"string",minLength:1},shape:{type:"string"},enum:{type:"array",items:{type:"string"}},default:{},example:{}}},subService:{type:"object",required:["serviceCode","estimateFor"],properties:{serviceCode:{type:"string",minLength:1},estimateFor:{type:"string",minLength:1},required:{type:"array",items:{$ref:"#/definitions/field"},default:[]},productCodes:{type:"array",items:{type:"string",minLength:1},description:"Manifest service codes (subType:'subService') that route under this provider but are not in the parent's templates[]. Lets the lint hint redirect agents from a product code (e.g. titanTextEmbeddingsV2) to the provider code (e.g. amazon) that the calculator's parent envelope actually claims."}}}}}});var gm=_((kxe,Ak)=>{var w_=require("node:fs"),nue=require("node:path"),iue=em(),aue=Lb(),oue=Ek(),kk=new iue({allErrors:!0});aue(kk);var Tk=kk.compile(oue);function Ck(e){return Tk(e)?null:Tk.errors.map(r=>({path:r.instancePath,keyword:r.keyword,message:r.message,params:r.params}))}function sue(e,{strict:t=!0}={}){let r=new Map;if(!w_.existsSync(e))return r;let i=w_.readdirSync(e).filter(n=>n.endsWith(".json"));for(let n of i){let a=nue.join(e,n),o;try{o=w_.readFileSync(a,"utf8")}catch(u){if(u.code==="ENOENT")continue;throw u}let s=JSON.parse(o),c=Ck(s);if(c){let u=`Invalid catalog entry ${n}: ${c.map(l=>`${l.path} ${l.message}`).join("; ")}`;if(t)throw new Error(u);console.error(u);continue}r.set(s.serviceCode,s)}return r}function cue(e,t){return e.get(t)}function uue(e){return[...e.values()].filter(t=>t.status==="verified")}Ak.exports={loadCatalog:sue,getEntry:cue,listVerified:uue,validateAgainstSchema:Ck}});var bm=_((Cxe,zk)=>{"use strict";var lue=/_generated_\d+$/;function Dk(e){return!Array.isArray(e)||e.length===0?!1:e.every(t=>lue.test(t))}var due=3;function Rk(e){let t=new Map;if(!e)return t;for(let r of e.values())for(let i of r.subServices||[]){i.serviceCode&&t.set(i.serviceCode,r);for(let n of i.productCodes||[])n&&t.set(n,{...r,_redirectVia:i.serviceCode})}return t}function vm(e){let t=e?.traps||[];return t.length===0?"":` Catalog hint: ${t[0]}`}function ym(e){return(e?.subServices||[]).map(r=>r.serviceCode).filter(Boolean)}function Ao(e,t){if(!e||!t)return null;let r=e.get(t);if(r)return r;let i=t.toLowerCase();for(let a of e.values())for(let o of a.subServices||[])if(o.serviceCode?.toLowerCase().startsWith(i))return a;let n=i.replace(/^amazon/,"");for(let a of e.values())if((a.displayName||"").toLowerCase().includes(n)&&n.length>=due)return a;return null}function fue(e,t,r,i){let n=t.context||{},a=n.serviceCode;if(e==="empty-estimate")return"This estimate has no services. Call add_service with at least one service before validating or exporting.";if(e==="tenancy-pricing-mismatch"){let o=n.selectedOption;return`Service ${a}: pricingStrategy "${o}" is invalid under tenancy "shared" \u2014 Standard/Convertible Reserved Instances are hidden by the calculator under shared tenancy, so the saved estimate renders Read-only. Two recovery paths: (a) set tenancy: "dedicated" or "host" to keep ${o} reserved instances, OR (b) switch to instance-savings (the shared-tenancy equivalent of standard) or compute-savings (the equivalent of convertible). Re-add via add_service with the corrected combination.`}if(e==="ec2-pricing-invalid-value"){let o=Array.isArray(n.invalid)?n.invalid.join("; "):"";return`Service ${a}: the saved blob's pricingStrategy carries invalid ${o}. The calculator will NOT honor these values \u2014 it silently prices as On-Demand / 1 Year. This blob was built outside the normal add_service path (add_service rejects these values). Recovery: re-add the service via add_service with pricingStrategy in the accepted form, e.g. {"model":"instanceSavings","term":"3 Year","upfrontPayment":"None"}.`}if(e==="template-existence"){let o=n.estimateFor,s=n.availableTemplates||[],c=a?Ao(r,a):null,u=ym(c);if(!o){let l=u.length>0?u:s,d=c?vm(c):"";return l.length>0?`Service ${a} has no estimateFor \u2014 it is a parent envelope, not something to add directly. Call add_service using one of its child service codes: ${l.join(", ")}.${d}`:`Service ${a} has no estimateFor. It is likely a parent envelope. Call search_services with the service name to find a concrete child service code, then add_service that one.${d}`}return s.length>0?`Service ${a}: estimateFor "${o}" is not valid. Re-add via add_service with one of: ${s.join(", ")}. Tip: get_service_fields lists the correct templates per service.`:`Service ${a}: estimateFor "${o}" not recognized. Re-add via add_service after checking get_service_fields for the correct template.`}if(e==="required-field-presence"){let o=n.componentId;if(o&&/_generated_\d+$/.test(o)){let c=a?Ao(r,a):null,u=ym(c),l=c?vm(c):"";return u.length>0?`Service ${a} is a parent envelope \u2014 its "${o}" slot expects a sub-service, not a literal value. Call add_service with one of these child codes instead of "${a}": ${u.join(", ")}.${l}`:`Service ${a} has a synthetic "_generated_" slot which means it is a parent envelope. Don't add it directly \u2014 use search_services to find the concrete child service code.${l}`}if(o){let u=((a?Ao(r,a):null)?.required||[]).find(d=>d.field===o),l=u?.example!==void 0?` Example: ${typeof u.example=="string"?`"${u.example}"`:JSON.stringify(u.example)}.`:"";return`Service ${a} is missing required field "${o}". Re-add this service via add_service with "${o}" populated.${l} Use get_service_fields for full field details.`}return`Service ${a} is missing required fields. Re-add via add_service; check get_service_fields for the required set.`}if(e==="value-parsability"){let o=n.componentId;return`Service ${a} field "${o}" has an unparseable value. Re-add via add_service with the correct shape; get_service_fields shows the expected value type for each field.`}if(e==="sub-service-active-list"){let o=n.parentServiceCode,s=n.childServiceCode,c=n.allowedActiveList;if(a&&!o){let u=i.get(a);if(u){if(u._redirectVia){let p=u._redirectVia,m=vm(u);return`Service "${a}" is a product under the "${p}" provider in ${u.serviceCode}. ${u.serviceCode} is structured per-provider, not per-product \u2014 the calculator does not accept "${a}" as a top-level service. Call add_service with service="${p}" instead \u2014 the server nests it under ${u.serviceCode} automatically. Use get_service_fields("${p}") to discover the model selection field IDs for the specific product.${m}`}let l=ym(u).filter(p=>p!==a),d=vm(u),f=l.length>0?` Other valid children: ${l.join(", ")}.`:"";return`Service "${a}" is a sub-service of ${u.serviceCode}. Call add_service with service="${a}" (the child code) \u2014 the server nests it under ${u.serviceCode} automatically.${f}${d}`}return`Service "${a}" is a sub-service. Re-add via add_service using a parent envelope's child code (e.g. "amazonS3:Standard" rather than "amazonS3" alone). Use search_services to find the right key.`}return Array.isArray(c)&&c.length>0?`Sub-service "${s}" is not allowed under parent "${o}". Allowed children: ${c.join(", ")}. Re-add via add_service using one of those.`:`Sub-service entry under ${o} is malformed. Re-add via add_service with a valid sub-service code; check search_services.`}if(e==="column-form-default-trap"){let o=n.componentId,s=n.defaultCount,c=n.defaultInstanceType||"(unspecified)",u=n.tableLabel||o,l=n.countRowLabel||"count";return`Service ${a}'s columnFormIPM "${o}" (${u}) is missing \u2014 the calculator would silently default it to ${s} \xD7 "${c}" and add cost the user did not authorize. To suppress: add "${o}" to calculationComponents with the count row "${l}" set to "0" (or populate it explicitly if the user actually wants those nodes). Use get_service_fields(${a}) to see the row column structure.`}return e==="definition-unavailable"?`Service code "${a||"unknown"}" is not in the manifest. Use search_services to find the correct service code, then re-add via add_service.`:`Lint failure: ${t.message}. Re-add the affected service via add_service after consulting get_service_fields.`}function pue(e,t){if(!e||e.status==="editable")return null;let r=Rk(t),i=e.status==="read-only"||e.status==="required-input",n=[];for(let s of e.services||[])for(let c of s.failures||[])!i&&c.severity==="required-only"||n.push(c);if(n.length===0)return null;if(n.length>1&&n.every(s=>s.predicate==="required-field-presence")&&n.every(s=>s.context?.serviceCode===n[0].context?.serviceCode)){let s=n[0].context.serviceCode,c=n.map(u=>u.context?.componentId).filter(Boolean);return`Service ${s} is missing ${c.length} required fields: ${c.map(u=>`"${u}"`).join(", ")}. Re-add via add_service with ALL of them populated in one call. Use get_service_fields(${s}) for value shapes.`}let o=fue(n[0].predicate,n[0],t,r);return n.length>1?o+` (${n.length-1} more issue${n.length>2?"s":""} to fix; full list in lint_services.)`:o}var Mk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Nk=/^[0-9a-f]{40}$/i;function mue(e){let t=String(e||""),r=Mk.test(t),i=Nk.test(t);return r?"The id is in the right shape but the estimate is not in storage \u2014 estimates expire after 24h. Call create_estimate (or build_estimate) to start a new one and re-add the services.":i?"That looks like a calculator save id (the 40-char hex from export_estimate's sharable_url), not the id this tool expects. If you want to read an existing public estimate, use import_estimate. To build a new one, call create_estimate and use the id it returns.":"That looks like a name or free text, not an estimate id. The estimate_id argument expects the id returned by create_estimate or build_estimate (a 36-char hyphenated string). Call create_estimate to get one."}function hue({serviceKey:e,validIds:t,catalog:r}){if(!t||t.length===0||Dk(t)){let o=Ao(r,e),s=ym(o);return s.length>0?`Service "${e}" is a parent envelope with no fields of its own. Call add_service / build_estimate with one of its child service codes: ${s.join(", ")}. `+(o.traps?.[0]?`Catalog hint: ${o.traps[0]}`:""):`Service "${e}" has no input fields \u2014 it's likely a parent envelope. Call search_services to find concrete child service codes (e.g. for "${e}"-shaped names, the actual codes often differ in capitalization or have suffixes like "Standard" / "OnDemand").`}let n=t.slice(0,12),a=t.length>n.length?` (and ${t.length-n.length} more \u2014 call get_service_fields for the full list)`:"";return`Valid field IDs for ${e}: ${n.join(", ")}${a}.`}function gue({serviceKey:e,missingFields:t,catalog:r}){let i=Ao(r,e);if(t.length===1){let n=t[0],a=(i?.required||[]).find(s=>s.field===n),o=a?.example!==void 0?` Example: ${typeof a.example=="string"?`"${a.example}"`:JSON.stringify(a.example)}.`:"";return`Service ${e} is missing required field "${n}". Re-add this service via add_service with "${n}" populated.${o} Use get_service_fields(${e}) for full field details.`}return`Service ${e} is missing ${t.length} required fields: ${t.map(n=>`"${n}"`).join(", ")}. Re-add via add_service with ALL of them populated in one call. Use get_service_fields(${e}) for value shapes.`}zk.exports={nextStepFor:pue,notFoundHintFor:mue,invalidFieldIdsHintFor:hue,partialEntryHintFor:gue,allFieldsAreSyntheticSlots:Dk,findCatalogEntry:Ao,_internals:{buildChildToParent:Rk,findCatalogEntry:Ao,ESTIMATE_ID_RE:Mk,CALCULATOR_SAVE_ID_RE:Nk}}});var S_=_((Axe,Zk)=>{"use strict";var vue={ec2Enhancement:[{id:"utilization",type:"numericInput",label:"Utilization (% of month, 1\u2013100)",helpText:'Percent of the month the instance is running (1\u2013100, default 100). Pass as a top-level string, e.g. utilization: "80". The transform routes it into pricingStrategy.value.utilizationValue. The PCT does not surface this field directly because it is nested inside the pricingStrategy component \u2014 pass it at the top level of your config.',default:"100",_synthetic:!0}]},yue={ec2Enhancement:{pricingStrategy:{helpText:'Pricing model. Accepts a string shorthand ("ondemand", "spot", "instanceSavings3yrAllUpfront") or an object {"model":"instanceSavings","term":"3 Year","upfrontPayment":"None"}. Display labels like "EC2 Instance Savings Plans" are also accepted. Invalid values are rejected at add_service \u2014 nothing silently falls back to On-Demand. Note: reserved/convertible require tenancy "dedicated" or "host"; under shared tenancy they are remapped to instanceSavings/computeSavings.',validModels:["ondemand","instanceSavings","computeSavings","reserved","convertible","spot"],validTerms:["1 Year","3 Year"],validUpfrontPayments:["None","Partial","All"]}}};function bue(e,t){let r=vue[e],i=yue[e];if((!r||r.length===0)&&!i)return t;let n=t;if(i){let a=!1,o=t.map(s=>{let c=i[s.id];return c?(a=!0,{...s,...c}):s});a&&(n=o)}if(r&&r.length>0){let a=new Set(n.map(s=>s.id)),o=r.filter(s=>!a.has(s.id));o.length>0&&(n=n===t?[...t,...o]:[...n,...o])}return n}Zk.exports={synthesizeAgentFields:bue}});var x_=_((Dxe,Fk)=>{var ht={TEMPLATE_EXISTENCE:"template-existence",REQUIRED_FIELD_PRESENCE:"required-field-presence",VALUE_PARSABILITY:"value-parsability",SUB_SERVICE_ACTIVE_LIST:"sub-service-active-list",DEFINITION_UNAVAILABLE:"definition-unavailable",EMPTY_ESTIMATE:"empty-estimate",ONE_OF_MUTEX:"one-of-mutex",UNKNOWN_FIELD_ID:"unknown-field-id",INVALID_OPTION_ID:"invalid-option-id",INVALID_REGION:"invalid-region",COLUMN_FORM_DEFAULT_TRAP:"column-form-default-trap",COLUMN_FORM_UNREMAPPED_VALUE:"column-form-unremapped-value",COLUMN_FORM_DETERMINED_SELECTOR_OMITTED:"column-form-determined-selector-omitted",COLUMN_FORM_TUPLE_INVALID:"column-form-tuple-invalid",TENANCY_PRICING_MISMATCH:"tenancy-pricing-mismatch",EC2_PRICING_INVALID_VALUE:"ec2-pricing-invalid-value"},dr={EDITABLE:"editable",REQUIRED_INPUT:"required-input",READ_ONLY:"read-only",UNKNOWN:"unknown"};function*_ue(e){let t=function*(i,n,a=null){yield{id:i,svc:n,parentId:a};for(let o of n.subServices||[])yield{id:`${i}/${o.serviceCode}`,svc:o,parentId:i}};for(let[i,n]of Object.entries(e.services||{}))yield*t(i,n);let r=function*(i){for(let[n,a]of Object.entries(i.services||{}))yield*t(n,a);for(let[,n]of Object.entries(i.groups||{}))yield*r(n)};for(let[,i]of Object.entries(e.groups||{}))yield*r(i)}function wue(e,t){let r=e.estimateFor;if(!r)return{predicate:ht.TEMPLATE_EXISTENCE,severity:"other",message:`service "${e.serviceCode}" has no estimateFor`,context:{serviceCode:e.serviceCode}};if(t&&t.templateId===r)return null;let i=t&&t.templates||[];for(let a of i)if(typeof a=="string"){if(a===r)return null}else if(a&&typeof a=="object"&&(a.id===r||a.mappingFromTemplate===r))return null;let n=i.map(a=>typeof a=="string"?a:a&&a.id).filter(Boolean);return t&&t.templateId&&n.unshift(t.templateId),{predicate:ht.TEMPLATE_EXISTENCE,severity:"other",message:`estimateFor "${r}" not in service "${e.serviceCode}" templates [${n.join(", ")}]`,context:{serviceCode:e.serviceCode,estimateFor:r,availableTemplates:n}}}function Sue(e){return Object.prototype.hasOwnProperty.call(e||{},"displayIf")}function Lk(e){return Object.prototype.hasOwnProperty.call(e||{},"displayIf")}function $ue(e){return!!(e&&e.validations&&e.validations.required)}function ju(e,t,r){if(!e||typeof e!="object")return null;if(Array.isArray(e.and)){let i=!1;for(let n of e.and){let a=ju(n,t,r);if(a===!1)return!1;a===null&&(i=!0)}return i?null:!0}if(Array.isArray(e.or)){let i=!1;for(let n of e.or){let a=ju(n,t,r);if(a===!0)return!0;a===null&&(i=!0)}return i?null:!1}if(e.not!==void 0){let i=ju(e.not,t,r);return i===null?null:!i}if(e.exists!==void 0)return!0;for(let i of["==","!=",">=","<=",">","<"])if(Array.isArray(e[i])&&e[i].length===2){let n=qk(e[i][0],t,r),a=qk(e[i][1],t,r);return n===void 0||a===void 0?null:xue(i,n,a)}return null}function qk(e,t,r){if(e==null||typeof e!="object")return e;if(e.type==="component"&&typeof e.id=="string"){let i=t&&t[e.id];return i!==void 0?i&&typeof i=="object"&&"value"in i?i.value:i:typeof r=="function"?r(e.id):void 0}if(Object.prototype.hasOwnProperty.call(e,"value"))return e.value}function xue(e,t,r){if(e==="==")return String(t)===String(r);if(e==="!=")return String(t)!==String(r);let i=Number(t),n=Number(r);return Number.isNaN(i)||Number.isNaN(n)?null:e===">="?i>=n:e==="<="?i<=n:e===">"?i>n:e==="<"?i<n:null}function Yi(e,t){for(let r of e.templates||[])if(typeof r!="string"&&r&&typeof r=="object"&&(r.id===t||r.mappingFromTemplate===t))return r;return null}function $_(e,t,r,i={}){let{skipMathWalk:n=!1}=i,a=[],o=new Set,s=l=>{!l||typeof l!="string"||o.has(l)||(o.add(l),a.push(l))},c=(l,d)=>{if(!l||typeof l!="object")return;let f=d||Sue(l);if(Array.isArray(l)){for(let p of l)c(p,f);return}l.id&&typeof l.id=="string"&&!f&&!Lk(l)&&$ue(l)&&s(l.id);for(let p of Object.values(l))p&&typeof p=="object"&&c(p,f)};if(c(e,!1),(!t||!t.templateId||!e||e.id===t.templateId||e.mappingFromTemplate===t.templateId)&&t&&Array.isArray(t.required))for(let l of t.required)l&&typeof l.field=="string"&&s(l.field);if(!n)for(let l of Oue(e,r))s(l);return a}function Oue(e,t){if(!e)return[];let r=t||{},i=new Map,n=d=>{if(!(!d||typeof d!="object")){if(Array.isArray(d)){for(let f of d)n(f);return}d.type==="input"&&typeof d.id=="string"&&i.set(d.id,d);for(let f of Object.values(d))n(f)}};n(e);let a=d=>{let f=i.get(d);return f&&f.defaultValue!==void 0?f.defaultValue:void 0},o=d=>{let f=i.get(d);return!f||!f.displayIf?!0:ju(f.displayIf,r,a)===!0},s=[],c=d=>{let f=s.length;s.push({inputs:new Set,expressions:[]});let p=m=>{if(!(!m||typeof m!="object")){if(Array.isArray(m)){for(let g of m)p(g);return}m.type==="input"&&typeof m.id=="string"&&s[f].inputs.add(m.id),m.type==="maths"&&m.subType==="basicMaths"&&Array.isArray(m.operands)&&s[f].expressions.push(m);for(let g of Object.values(m))p(g)}};p(d)};if(Array.isArray(e.cards)&&e.cards.length>0)for(let d of e.cards)c(d);else c(e);let u=d=>{if(!(d in r))return!1;let f=i.get(d);if(!f||f.defaultValue===void 0)return!0;let p=r[d],m=p&&typeof p=="object"&&"value"in p?p.value:p;return String(m)!==String(f.defaultValue)},l=new Set;for(let d of s){let f=new Map;for(let $ of d.expressions)typeof $.id=="string"&&f.set($.id,$);let p=new Set,m=new Set,g=!0,w=0;for(;g&&w<50;){g=!1,w++;for(let[$,O]of f){if(p.has($))continue;let I=!0,k=!1;for(let T of O.operands)if(!(!T||typeof T.variableId!="string"))if(i.has(T.variableId)){if(T.required===!0&&!d.inputs.has(T.variableId)){I=!1;break}if(T.required===!0&&!u(T.variableId)){I=!1;break}d.inputs.has(T.variableId)&&u(T.variableId)&&(k=!0)}else{if(!f.has(T.variableId)){I=!1;break}if(!p.has(T.variableId)){I=!1;break}m.has(T.variableId)&&(k=!0)}I&&k&&(p.add($),m.add($),g=!0)}}for(let $ of d.expressions){let O=$.operands.filter(N=>N&&typeof N.variableId=="string"&&N.required===!0&&i.has(N.variableId));if(O.length===0)continue;let I=O.filter(N=>d.inputs.has(N.variableId)&&u(N.variableId)),k=$.operands.some(N=>N&&typeof N.variableId=="string"&&!i.has(N.variableId)&&f.has(N.variableId)&&m.has(N.variableId));if(I.length>=2||k)for(let N of O)d.inputs.has(N.variableId)&&o(N.variableId)&&(u(N.variableId)||l.add(N.variableId))}}return[...l]}function Pue(e){if(!e||typeof e!="object")return null;if(Array.isArray(e["=="])){let[t,r]=e["=="];return t&&t.type==="component"&&typeof t.id=="string"&&(typeof r=="string"||typeof r=="number")?{field:t.id,values:new Set([String(r)])}:null}if(Array.isArray(e.or)){let t=null,r=new Set;for(let i of e.or){if(!Array.isArray(i["=="]))return null;let[n,a]=i["=="];if(!(n&&n.type==="component"&&typeof n.id=="string")||typeof a!="string"&&typeof a!="number"||t&&t!==n.id)return null;t=n.id,r.add(String(a))}return t?{field:t,values:r}:null}return null}function Iue(e){if(!e)return[];let t=new Map,r=new Map,i=s=>{if(!(!s||typeof s!="object")){if(Array.isArray(s)){for(let c of s)i(c);return}s.type==="input"&&typeof s.id=="string"&&t.set(s.id,{displayIf:s.displayIf,required:s.validations&&s.validations.required}),s.type==="maths"&&s.subType==="variable"&&typeof s.id=="string"&&typeof s.refer=="string"&&r.set(s.id,s.refer);for(let c of Object.values(s))i(c)}};i(e);let n=s=>r.get(s)||s,a=[],o=s=>{if(!(!s||typeof s!="object")){if(Array.isArray(s)){for(let c of s)o(c);return}if(s.operation==="addition"&&Array.isArray(s.operands)){let c=[],u=!1;for(let l of s.operands){if(!l||typeof l.variableId!="string")continue;let d=n(l.variableId),f=t.get(d);if(!f||!f.displayIf){u=!0;break}let p=Pue(f.displayIf);if(!p){u=!0;break}if(f.required===!0){u=!0;break}c.push({inputId:d,gate:p})}if(!u&&c.length>=2){let l=c[0].gate.field;if(c.every(d=>d.gate.field===l)){let d=new Set,f=!0;for(let p of c)for(let m of p.gate.values){if(d.has(m)){f=!1;break}d.add(m)}f&&a.push({gatingField:l,members:c.map(p=>({id:p.inputId,values:p.gate.values}))})}}}for(let c of Object.values(s))o(c)}};return o(e),a}function jue(e,t){let r=Yi(t,e.estimateFor);if(!r)return[];let i=e.calculationComponents||{},n=[];for(let a of Iue(r)){let o=i[a.gatingField];if(o===void 0)continue;let s=typeof o=="object"&&o!==null&&"value"in o?o.value:o;if(s==null)continue;let c=String(s),u=a.members.find(l=>l.values.has(c));u&&(u.id in i||n.push({predicate:ht.ONE_OF_MUTEX,severity:"required-only",message:`gating field "${a.gatingField}"=${c} requires variant "${u.id}" to be populated for ${e.serviceCode}`,context:{serviceCode:e.serviceCode,gatingField:a.gatingField,gatingValue:c,expectedComponentId:u.id,availableMembers:a.members.map(l=>l.id)}}))}return n}function Eue(e){if(e==null)return!1;if(typeof e=="string")return e.trim().length>0;if(typeof e=="object"){if(Object.keys(e).length===0)return!1;if("value"in e){let t=e.value;if(t==null||typeof t=="string"&&t.trim().length===0)return!1}}return!0}function Tue(e,t,r){let i=Yi(t,e.estimateFor);if(!i)return[];let n=$_(i,r,e.calculationComponents),a=e.calculationComponents||{},o=[];for(let s of n)s in a&&(Eue(a[s])||o.push({predicate:ht.VALUE_PARSABILITY,severity:"other",message:`required component "${s}" has unparseable value: ${JSON.stringify(a[s])}`,context:{serviceCode:e.serviceCode,componentId:s,savedValue:a[s]}}));return o}function kue(e,t){let r=Yi(t,e.estimateFor);if(!r)return[];let i=e.calculationComponents||{},n=Object.keys(i);if(n.length===0)return[];let a=new Set,o=u=>{if(!(!u||typeof u!="object")){if(Array.isArray(u)){for(let l of u)o(l);return}u.type==="input"&&typeof u.id=="string"&&a.add(u.id);for(let l of Object.values(u))o(l)}};if(o(r),a.size===0)return[];let s=[...a],c=[];for(let u of n){if(a.has(u))continue;let l=Cue(u,s),d=l.length?` Did you mean: ${l.map(f=>`"${f}"`).join(", ")}?`:"";c.push({predicate:ht.UNKNOWN_FIELD_ID,severity:"required-only",message:`unknown component "${u}" in calculationComponents for ${e.serviceCode}.${d}`,context:{serviceCode:e.serviceCode,componentId:u,suggestions:l}})}return c}function Cue(e,t,r=3){let i=e.toLowerCase();return t.map(n=>({id:n,dist:Aue(i,n.toLowerCase())})).filter(n=>n.dist<=Math.max(Math.floor(e.length*.6),3)).sort((n,a)=>n.dist-a.dist).slice(0,r).map(n=>n.id)}function Aue(e,t){let r=e.length,i=t.length;if(r===0)return i;if(i===0)return r;let n=new Array(i+1),a=new Array(i+1);for(let o=0;o<=i;o++)n[o]=o;for(let o=1;o<=r;o++){a[0]=o;for(let s=1;s<=i;s++){let c=e[o-1]===t[s-1]?0:1;a[s]=Math.min(a[s-1]+1,n[s]+1,n[s-1]+c)}for(let s=0;s<=i;s++)n[s]=a[s]}return n[i]}function Due(e,t){let r=Yi(t,e.estimateFor);if(!r)return[];let i=e.calculationComponents||{};if(Object.keys(i).length===0)return[];let n=new Map,a=s=>{if(!(!s||typeof s!="object")){if(Array.isArray(s)){for(let c of s)a(c);return}s.type==="input"&&typeof s.id=="string"&&Array.isArray(s.options)&&s.options.length>0&&(s.subType==="dropdown"||s.subType==="frequency")&&n.set(s.id,{subType:s.subType,optionIds:new Set(s.options.map(c=>c&&c.id).filter(Boolean).map(String))});for(let c of Object.values(s))a(c)}};if(a(r),n.size===0)return[];let o=[];for(let[s,c]of Object.entries(i)){let u=n.get(s);if(!u)continue;let l,d;if(u.subType==="dropdown"?(l="value",d=c&&typeof c=="object"&&"value"in c?c.value:c):(l="unit",d=c&&typeof c=="object"?c.unit:void 0),d==null)continue;let f=String(d);if(u.optionIds.has(f))continue;let p=[...u.optionIds].slice(0,5),m=u.optionIds.size>5?`, ... (${u.optionIds.size} total)`:"";o.push({predicate:ht.INVALID_OPTION_ID,severity:"required-only",message:`field "${s}" ${l} "${f}" not in options [${p.join(", ")}${m}] for ${e.serviceCode}`,context:{serviceCode:e.serviceCode,componentId:s,slot:l,observed:f,validOptions:[...u.optionIds]}})}return o}function Rue(e,t){if(!t)return[];if(!e.region)return[];let r=t[e.serviceCode];if(!Array.isArray(r)||r.length===0)return[];if(r.includes(e.region))return[];let i=r.slice(0,5),n=r.length>5?`, ... (${r.length} total)`:"";return[{predicate:ht.INVALID_REGION,severity:"required-only",message:`region "${e.region}" not supported for ${e.serviceCode}. Supported: ${i.join(", ")}${n}`,context:{serviceCode:e.serviceCode,observed:e.region,validRegions:r}}]}function Mue(e,t){let r=Yi(t,e.estimateFor);if(!r)return[];let i=e.calculationComponents||{},n=Fue(r),a=s=>{let c=n.componentsById?.get(s);return!c||!Lk(c)?!0:ju(c.displayIf,i,l=>n.defaultsById?.get(l))!==!1},o=[];for(let s of Bs(r)){if(s.subType!=="columnFormIPM"||!a(s.id))continue;let c=s.row||[],u=null,l=null;for(let m of c)u==null&&(m.type==="textInput"||m.type==="numericInput")&&m.defaultValue!==void 0&&m.defaultValue!==""&&Number(m.defaultValue)>0&&(u=m),l==null&&m.type==="autoSuggest"&&(l=m);if(!u||s.id in i)continue;let d=Number(u.defaultValue),f=l?.defaultValue||"(unspecified)",p=u.selectorId||u.label||"count";o.push({predicate:ht.COLUMN_FORM_DEFAULT_TRAP,severity:"required-only",message:`columnFormIPM "${s.id}" (${s.label||"unnamed table"}) is absent \u2014 calculator will silently default to ${d} \xD7 "${f}" and add cost the agent did not authorize`,context:{serviceCode:e.serviceCode,componentId:s.id,tableLabel:s.label||null,countRowLabel:p,defaultCount:d,defaultInstanceType:f}})}return o}function Nue(e,t){let r=Yi(t,e.estimateFor);if(!r)return[];let i=e.calculationComponents||{},n=[];for(let a of Bs(r)){if(a.subType!=="columnFormIPM"&&a.type!=="columnFormIPM")continue;let o=a.remap&&a.remap.keyValue;if(!o||typeof o!="object")continue;let s=new Set(Object.keys(o));if(s.size===0)continue;let c=new Set(Object.values(o).map(String)),u=i[a.id],l=u&&u.value;if(Array.isArray(l)){for(let d of l)if(!(!d||typeof d!="object"))for(let[f,p]of Object.entries(d)){if(!p||typeof p!="object")continue;let m=p.value&&typeof p.value=="object"?p.value.selectedId:p.value;typeof m=="string"&&s.has(m)&&(c.has(m)||n.push({predicate:ht.COLUMN_FORM_UNREMAPPED_VALUE,severity:"other",message:`columnFormIPM "${a.id}" cell "${f}" holds un-remapped selector value "${m}" for ${e.serviceCode} \u2014 calculator stores the remapped value "${o[m]}"; the raw value rehydrates read-only at $0`,context:{serviceCode:e.serviceCode,componentId:a.id,cellKey:f,observed:m,expectedRemapped:o[m]}}))}}}return n}function zue(e,t,r,i){if(!r||typeof r.get!="function")return[];let n=r.get(e.serviceCode);if(!Array.isArray(n)||n.length===0)return[];let a=i&&typeof i.get=="function"&&i.get(e.serviceCode)||null,o=Yi(t,e.estimateFor);if(!o)return[];let s=e.calculationComponents||{},c=new Set;for(let d of n)if(d&&typeof d=="object")for(let f of Object.keys(d))c.add(f);if(c.size===0)return[];let u=new Set;for(let d of n)d&&typeof d=="object"&&d.TermType!=null&&u.add(String(d.TermType));let l=[];for(let d of Bs(o)){if(d.subType!=="columnFormIPM"&&d.type!=="columnFormIPM")continue;let f=d.remap&&d.remap.keyValue;if(!f||typeof f!="object")continue;let p={};for(let[$,O]of Object.entries(f))p[String(O)]=$;let m=$=>Object.prototype.hasOwnProperty.call(p,$)?p[$]:$,g=s[d.id],w=g&&g.value;if(Array.isArray(w))for(let $ of w){if(!$||typeof $!="object")continue;let O={};for(let W of c){let re=$[W];if(!re||typeof re!="object")continue;let xe=re.value&&typeof re.value=="object"?re.value.selectedId:re.value;typeof xe=="string"&&(O[W]=m(xe))}let I=Object.keys(O);if(I.length===0)continue;let k=Array.isArray(d.row)?d.row.map(W=>W&&W.selectorId).filter(Boolean):[];if(k.length>0){let W=n.filter(re=>I.every(xe=>String(re[xe])===String(O[xe])));if(W.length>0)for(let re of c){if(!k.includes(re)||re in O||re in $||new Set(n.map(pe=>pe[re]).filter(pe=>pe!==void 0)).size<2)continue;let ne=[...new Set(W.map(pe=>pe[re]).filter(pe=>pe!==void 0))];if(ne.length!==1)continue;let fe=a?a[re]:void 0;fe!==void 0&&String(ne[0])!==String(fe)&&l.push({predicate:ht.COLUMN_FORM_DETERMINED_SELECTOR_OMITTED,severity:"required-only",message:`columnFormIPM "${d.id}" is missing selector "${re}", which is fixed to "${ne[0]}" for this row in region "${e.region||e.regionName||"unknown"}". The calculator silently defaults it and the saved line misprices \u2014 add {"${re}": {"value": "${ne[0]}"}} to the row.`,context:{serviceCode:e.serviceCode,componentId:d.id,selector:re,requiredValue:ne[0],region:e.region||null}})}}"TermType"in O&&u.size>0&&!u.has(String(O.TermType))&&delete O.TermType;let T=Object.keys(O);T.length===0||n.some(W=>T.every(re=>String(W[re])===String(O[re])))||l.push({predicate:ht.COLUMN_FORM_TUPLE_INVALID,severity:"other",message:`columnFormIPM "${d.id}" row tuple ${JSON.stringify(O)} is not a valid combination for ${e.serviceCode} in region "${e.region||e.regionName||"unknown"}" \u2014 it misprices silently (renders a wrong rate or $0)`,context:{serviceCode:e.serviceCode,componentId:d.id,region:e.region||null,regionName:e.regionName||null,observedTuple:O,comparedKeys:[...c]}})}}return l}function Zue(e){let t=e.calculationComponents||{},r=t.tenancy?.value,i=t.pricingStrategy?.value?.selectedOption;return r!=="shared"?[]:i!=="standard"&&i!=="convertible"?[]:[{predicate:ht.TENANCY_PRICING_MISMATCH,severity:"required-only",message:`${e.serviceCode}: pricingStrategy "${i}" is invalid under shared tenancy \u2014 calculator hides Standard/Convertible Reserved Instances and renders Read-only`,context:{serviceCode:e.serviceCode,tenancy:r,selectedOption:i}}]}var Uk=new Set(["on-demand","standard","convertible","instance-savings","compute-savings","spot"]),que=new Set(["1 Year","3 Year"]),Uue=new Set(["None","Partial","All"]);function Lue(e){if((e.serviceCode||"").toLowerCase()!=="ec2enhancement")return[];let t=e.calculationComponents?.pricingStrategy?.value;if(!t||typeof t!="object")return[];let r=[];return"selectedOption"in t&&!Uk.has(t.selectedOption)&&r.push(`selectedOption "${t.selectedOption}" (valid: ${[...Uk].join(", ")})`),"term"in t&&!que.has(t.term)&&r.push(`term "${t.term}" (valid: 1 Year, 3 Year)`),"upfrontPayment"in t&&!Uue.has(t.upfrontPayment)&&r.push(`upfrontPayment "${t.upfrontPayment}" (valid: None, Partial, All)`),r.length===0?[]:[{predicate:ht.EC2_PRICING_INVALID_VALUE,severity:"required-only",message:`${e.serviceCode}: pricingStrategy carries invalid ${r.join("; ")} \u2014 the calculator silently prices this as On-Demand / 1 Year instead of what the blob claims`,context:{serviceCode:e.serviceCode,invalid:r,selectedOption:t.selectedOption,term:t.term,upfrontPayment:t.upfrontPayment}}]}function*Bs(e){if(!(!e||typeof e!="object")){if(Array.isArray(e)){for(let t of e)yield*Bs(t);return}e.type==="input"&&e.id&&(yield e);for(let t of Object.values(e))yield*Bs(t)}}function Fue(e){let t=new Map,r=new Map;for(let i of Bs(e))t.set(i.id,i),i.defaultValue!==void 0&&r.set(i.id,i.defaultValue);return{componentsById:t,defaultsById:r}}function Bue(e,t,r){let i=Yi(t,e.estimateFor);if(!i)return[];let n=$_(i,r,e.calculationComponents),a=e.calculationComponents||{},o=[];for(let s of n)s in a||o.push({predicate:ht.REQUIRED_FIELD_PRESENCE,severity:"required-only",message:`required component "${s}" missing from calculationComponents for ${e.serviceCode}`,context:{serviceCode:e.serviceCode,componentId:s}});return o}function Vue(e){let t=new Set;for(let r of e.templates||[])typeof r=="string"?t.add(r):r&&typeof r=="object"&&r.id&&t.add(r.id);if(e.mappingDefinitions){let r=e.mappingDefinitions;if(Array.isArray(r.children))for(let i of r.children)t.add(i)}return t}function Hue(e,t){let r=[];if(!Array.isArray(e.subServices)||e.subServices.length===0)return r;let i=t.get(e.serviceCode);if(!i)return r;let n=Vue(i);for(let a of e.subServices){if(!a.serviceCode){r.push({predicate:ht.SUB_SERVICE_ACTIVE_LIST,severity:"other",message:`sub-service entry under ${e.serviceCode} has no serviceCode`,context:{parentServiceCode:e.serviceCode}});continue}n.size>0&&!n.has(a.serviceCode)&&!n.has(a.estimateFor)&&r.push({predicate:ht.SUB_SERVICE_ACTIVE_LIST,severity:"other",message:`sub-service "${a.serviceCode}" not in parent ${e.serviceCode}'s active list [${[...n].join(", ")}]`,context:{parentServiceCode:e.serviceCode,childServiceCode:a.serviceCode,allowedActiveList:[...n]}})}return r}function Jue(e,t){let r=t.get(e.serviceCode);return r&&r.subType==="subService"?[{predicate:ht.SUB_SERVICE_ACTIVE_LIST,severity:"other",message:`service "${e.serviceCode}" is a sub-service but appears at top-level peer position; expected inside parent's subServices envelope`,context:{serviceCode:e.serviceCode}}]:[]}function Gue(e){return e.length===0?dr.EDITABLE:e.some(r=>r.severity==="other")?dr.READ_ONLY:dr.REQUIRED_INPUT}function Kue(e){return e.includes(dr.READ_ONLY)?dr.READ_ONLY:e.includes(dr.REQUIRED_INPUT)?dr.REQUIRED_INPUT:e.includes(dr.UNKNOWN)?dr.UNKNOWN:dr.EDITABLE}function Wue({savedBlob:e,manifest:t,perServiceDefinitions:r,catalog:i,regionList:n,aggregations:a,selectorDefaults:o}){let s=[],c=[..._ue(e)];if(c.length===0)return{status:dr.READ_ONLY,services:[{id:"(no services)",parentId:null,serviceCode:null,estimateFor:null,status:dr.READ_ONLY,failures:[{predicate:ht.EMPTY_ESTIMATE,severity:"other",message:"estimate has no services \u2014 saved blob would rehydrate as a blank read-only calculator",context:{}}]}]};for(let{id:u,svc:l,parentId:d}of c){let f=r.get(l.serviceCode);if(!f){s.push({id:u,parentId:d,serviceCode:l.serviceCode,estimateFor:l.estimateFor,status:dr.UNKNOWN,failures:[{predicate:ht.DEFINITION_UNAVAILABLE,severity:"unknown",message:`no PCT definition provided for serviceCode "${l.serviceCode}"`,context:{serviceCode:l.serviceCode}}]});continue}let p=[],m=wue(l,f);m&&p.push(m);let g=i&&typeof i.get=="function"?i.get(l.serviceCode):void 0;m||(p.push(...Bue(l,f,g)),p.push(...Tue(l,f,g)),p.push(...jue(l,f)),p.push(...kue(l,f)),p.push(...Due(l,f)),p.push(...Rue(l,n)),p.push(...Mue(l,f)),p.push(...Nue(l,f)),p.push(...zue(l,f,a,o)),p.push(...Zue(l)),p.push(...Lue(l)),d===null&&p.push(...Hue(l,r))),d===null&&p.push(...Jue(l,t)),s.push({id:u,parentId:d,serviceCode:l.serviceCode,estimateFor:l.estimateFor,status:Gue(p),failures:p})}return{status:Kue(s.map(u=>u.status)),services:s}}Fk.exports={canRehydrate:Wue,PREDICATES:ht,STATUS:dr,findRequiredComponentIds:$_,findTemplate:Yi}});var Jk=_((Rxe,Hk)=>{var{loadManifest:Xue,loadRegionList:Yue,findService:Que,findServiceCandidates:ele,fetchServiceDefinition:tle,extractInputFields:rle,enrichFieldsWithMetadata:nle}=Fs(),{invalidFieldIdsHintFor:ile}=bm(),{synthesizeAgentFields:ale}=S_(),{validatePricingStrategy:ole}=u_(),{findRequiredComponentIds:sle,findTemplate:cle}=x_(),{getEntry:ule}=gm(),Bk=new Set(["region","description"]),lle=new Set(["tenancy","vcpu","physicalCores","storageTypeDH","storageAmountDH","gp3IopsDH","gp3ThroughputDH","iopsDH","iops2DH"]),dle=20;function P_(e,t){let r=e.length,i=t.length,n=Array.from({length:r+1},(a,o)=>o);for(let a=1;a<=i;a++){let o=n[0];n[0]=a;for(let s=1;s<=r;s++){let c=n[s];n[s]=e[s-1]===t[a-1]?o:1+Math.min(o,n[s],n[s-1]),o=c}}return n[r]}function Eu(e,t,r=3){let i=e.toLowerCase();return t.map(n=>({id:n,dist:P_(i,n.toLowerCase())})).filter(n=>n.dist<=Math.max(Math.floor(e.length*.6),3)).sort((n,a)=>n.dist-a.dist).slice(0,r).map(n=>n.id)}var O_=new Set;function fle(e){let t=new Map;for(let r of e){let i=String(r.id).toLowerCase();if(t.has(i)&&t.get(i)!==r.id)return!0;t.set(i,r.id)}return!1}function Vk(e,t,r={}){if(!e||!e.type)return{ok:!0};let i=r.cacheKey||`${r.serviceCode||""}:${e.id}`;if(e.type==="dropdown"&&Array.isArray(e.options)){let n=t&&typeof t=="object"&&"value"in t,a=n?t.value:t;if(typeof a!="string")return{ok:!1,error:`Field "${e.id}": expected a string option id, got ${typeof a}.`};let o=e.options.map(m=>m.id);if(o.includes(a))return{ok:!0};if(!O_.has(i)&&fle(e.options)&&O_.add(i),!O_.has(i)){let m=a.toLowerCase(),g=o.find(w=>w.toLowerCase()===m);if(g)return{ok:"corrected",correctedValue:n?{...t,value:g}:g,reason:"case mismatch"}}let c=null;for(let m of o)if(P_(a,m)<=1){c=m;break}if(c&&c!==a)return{ok:"corrected",correctedValue:n?{...t,value:c}:c,reason:"single-character typo"};let u=Eu(a,o,3),l=o.length>10,d=o.slice(0,10).join(", "),f=l?` ...(${o.length} total)`:"",p=u.length?` Did you mean: ${u.map(m=>`"${m}"`).join(", ")}?`:"";return{ok:!1,error:`Field "${e.id}": "${a}" is not a valid option.${p} Allowed: ${d}${f}`}}if(e.type==="fileSize"){if(!t||typeof t!="object"||typeof t.unit!="string"||!("value"in t))return{ok:!1,error:`Field "${e.id}": expected { value, unit } object${e.defaultUnit?` (e.g. unit "${e.defaultUnit}")`:""}.`};let n=t.unit,a=n.split("|");if(a.length!==2)return{ok:!1,error:`Field "${e.id}": unit "${n}" must be "<size>|<freq>"${e.defaultUnit?` (e.g. "${e.defaultUnit}")`:""}.`};let[o,s]=a,c=e.validSizes||[];if(c.length>0&&c.includes(o))return{ok:!0};let u=o.trim().toLowerCase();return c.includes(u)?{ok:"corrected",correctedValue:{...t,unit:`${u}|${s}`},reason:"size casing/whitespace"}:{ok:!1,error:`Field "${e.id}": size "${o}" is not valid. Allowed sizes: [${c.join(", ")}]${e.defaultUnit?`, default "${e.defaultUnit}"`:""}.`}}if(e.type==="numericInput"){let n=null;typeof t=="number"&&Number.isFinite(t)&&(n=String(t));let a=n||t;if(typeof a!="string")return{ok:!1,error:`Field "${e.id}": expected a string numeric value, got ${t===null?"null":typeof t}.`};let o=Number(a);if(Number.isFinite(o)){if(e.minValue!=null&&o<e.minValue)return{ok:!1,error:`Field "${e.id}": value ${o} is below minimum ${e.minValue}.`};if(e.maxValue!=null&&o>e.maxValue)return{ok:!1,error:`Field "${e.id}": value ${o} exceeds maximum ${e.maxValue}.`};if(e.allowDecimals===!1&&!Number.isInteger(o))return{ok:!1,error:`Field "${e.id}": decimals are not allowed, got ${o}.`}}return n?{ok:"corrected",correctedValue:n,reason:"number coerced to string"}:{ok:!0}}if(e.type==="frequency"||e.type==="durationInput"){if(!t||typeof t!="object"||Array.isArray(t))return{ok:!1,error:`Field "${e.id}": expected { value, unit } object, got ${t===null?"null":typeof t}.`};if(!("value"in t))return{ok:!1,error:`Field "${e.id}": missing inner "value".`};let n=t;if(typeof t.value=="number"&&Number.isFinite(t.value))n={...t,value:String(t.value)};else if(typeof t.value!="string")return{ok:!1,error:`Field "${e.id}": inner "value" must be a string, got ${t.value===null?"null":typeof t.value}.`};let a=(e.options||[]).map(o=>o.id).filter(Boolean);if(a.length>0&&typeof n.unit=="string"&&!a.includes(n.unit)){let o=Eu(n.unit,a,3),s=o.length?` Did you mean: ${o.map(c=>`"${c}"`).join(", ")}?`:"";return{ok:!1,error:`Field "${e.id}": unit "${n.unit}" is not a valid option.${s} Allowed: ${a.join(", ")}.`}}return n!==t?{ok:"corrected",correctedValue:n,reason:"inner value coerced to string"}:{ok:!0}}return{ok:!0}}async function ple(e,t,r,i,n){let a=Object.keys(t).filter(o=>!Bk.has(o));try{let o=await Xue(r||"aws"),s=Que(o,e);if(!s){let ne=ele(o,e,6);if(ne.length===0)return{error:`Service "${e}" not found in manifest. Use search_services to discover the correct service key.`,correctedConfig:t,corrections:[]};let fe=ne.map(pe=>` ${pe.key} \u2014 ${pe.name}`).join(`
|
|
85
|
+
`)}xk.exports={PARTITIONS:Fr,resolvePartition:jce,loadManifest:Ace,loadRegionList:Tce,findService:Dce,findServiceCandidates:Rce,searchServices:Mce,fetchServiceDefinition:Nce,saveEstimate:zce,extractInputFields:Lce,enrichFieldsWithMetadata:Fce,loadSelectorAggregations:kce,loadSelectorDefaults:Cce,parseDoubleEncodedResponse:v_,fetchEstimate:Vce,estimateToMarkdown:Jce,extractCostsFromSavedBlob:Hce}});var Pk=_((jxe,Ok)=>{var Gce=Iu(),{GetCommand:Kce,PutCommand:Wce,DeleteCommand:Xce,DynamoDBDocumentClient:Yce}=require("@aws-sdk/lib-dynamodb"),{DynamoDBClient:Qce}=require("@aws-sdk/client-dynamodb"),__=class{constructor({tableName:t,region:r,docClient:i,ttlSeconds:n}={}){if(!t)throw new Error("DynamoEstimateStore: tableName is required");this.tableName=t,this.ttlSeconds=n,this._docClient=i||Yce.from(new Qce({region:r}))}async get(t){let r=await this._docClient.send(new Kce({TableName:this.tableName,Key:{id:t}}));if(!r.Item||!r.Item.snapshot)return null;let i=JSON.parse(r.Item.snapshot);return Gce.fromJSON(i)}async put(t){let r={id:t.id,snapshot:JSON.stringify(t.toJSON())};this.ttlSeconds&&this.ttlSeconds>0&&(r.expiresAt=Math.floor(Date.now()/1e3)+this.ttlSeconds),await this._docClient.send(new Wce({TableName:this.tableName,Item:r}))}async delete(t){await this._docClient.send(new Xce({TableName:this.tableName,Key:{id:t}}))}};Ok.exports={DynamoEstimateStore:__}});var jk=_((Exe,Ik)=>{var eue=Iu(),hm=class{constructor(){this._snapshots=new Map}async get(t){let r=this._snapshots.get(t);return r?eue.fromJSON(JSON.parse(JSON.stringify(r))):null}async put(t){this._snapshots.set(t.id,t.toJSON())}async delete(t){this._snapshots.delete(t)}};function tue(e=process.env){let t=(e.ESTIMATES_STORE||"memory").toLowerCase();if(t==="memory")return new hm;if(t==="dynamodb"){let{DynamoEstimateStore:r}=Pk();return new r({tableName:e.ESTIMATES_TABLE,region:e.AWS_REGION||e.AWS_DEFAULT_REGION,ttlSeconds:e.ESTIMATES_TTL_SECONDS?Number(e.ESTIMATES_TTL_SECONDS):void 0})}throw new Error(`Unknown ESTIMATES_STORE: "${t}". Valid: "memory", "dynamodb".`)}Ik.exports={MemoryEstimateStore:hm,createEstimateStore:tue}});var Ek=_((Txe,rue)=>{rue.exports={$schema:"http://json-schema.org/draft-07/schema#",title:"AWS Pricing Calculator Service Catalog Entry",type:"object",required:["serviceCode","displayName","status","minimalConfig"],properties:{$schema:{type:"string"},serviceCode:{type:"string",pattern:"^[a-zA-Z][a-zA-Z0-9]*$",description:"Canonical service code from manifest/en_US.json (e.g. aWSLambda, ec2Enhancement)."},displayName:{type:"string",minLength:1},templateId:{type:"string",description:"The estimateFor value the calculator expects. Optional for parent envelopes whose children carry their own template ids."},status:{type:"string",enum:["verified","partial","unverified","broken"],description:"verified = round-trip test passes; partial = saves+renders but with Required-input; unverified = not yet probed; broken = known to fail."},lastVerifiedAt:{type:"string",format:"date",description:"ISO date of the most recent successful round-trip. Required when status is 'verified' or 'partial'."},verifiedEstimateId:{type:"string",pattern:"^[a-f0-9]{40}$",description:"SHA1 estimate id from the most recent successful round-trip. Required when status is 'verified' or 'partial'."},required:{type:"array",items:{$ref:"#/definitions/field"},default:[]},traps:{type:"array",items:{type:"string",minLength:1},description:"Human-readable gotchas an agent or author should know. Free-form prose.",default:[]},subServices:{type:"array",items:{$ref:"#/definitions/subService"},description:"For parent envelopes only \u2014 describes each child's serviceCode, estimateFor, and required fields.",default:[]},minimalConfig:{type:"object",description:"The smallest config that produces an editable estimate. For parent envelopes, keyed by sub-service code; for plain services, the config object itself."},defaultFields:{type:"object",additionalProperties:!0,description:"Per-field literal saved-blob shapes injected at add_service time when the agent omits the key. Use for fields the calculator silently demands but the manifest does NOT mark validations.required (the case where get_service_fields doesn't expose them and the lint can't refuse without them). Authors declare the canonical envelope; lib/mcp/handler-helpers.js#applyDefaultFields merges any missing keys into the user's config before estimate.addService."}},allOf:[{if:{required:["status"],properties:{status:{enum:["verified","partial"]}}},then:{required:["lastVerifiedAt","verifiedEstimateId"]}}],definitions:{field:{type:"object",required:["field","hint"],properties:{field:{type:"string",minLength:1},hint:{type:"string",minLength:1},shape:{type:"string"},enum:{type:"array",items:{type:"string"}},default:{},example:{}}},subService:{type:"object",required:["serviceCode","estimateFor"],properties:{serviceCode:{type:"string",minLength:1},estimateFor:{type:"string",minLength:1},required:{type:"array",items:{$ref:"#/definitions/field"},default:[]},productCodes:{type:"array",items:{type:"string",minLength:1},description:"Manifest service codes (subType:'subService') that route under this provider but are not in the parent's templates[]. Lets the lint hint redirect agents from a product code (e.g. titanTextEmbeddingsV2) to the provider code (e.g. amazon) that the calculator's parent envelope actually claims."}}}}}});var gm=_((kxe,Ak)=>{var w_=require("node:fs"),nue=require("node:path"),iue=em(),aue=Lb(),oue=Ek(),kk=new iue({allErrors:!0});aue(kk);var Tk=kk.compile(oue);function Ck(e){return Tk(e)?null:Tk.errors.map(r=>({path:r.instancePath,keyword:r.keyword,message:r.message,params:r.params}))}function sue(e,{strict:t=!0}={}){let r=new Map;if(!w_.existsSync(e))return r;let i=w_.readdirSync(e).filter(n=>n.endsWith(".json"));for(let n of i){let a=nue.join(e,n),o;try{o=w_.readFileSync(a,"utf8")}catch(u){if(u.code==="ENOENT")continue;throw u}let s=JSON.parse(o),c=Ck(s);if(c){let u=`Invalid catalog entry ${n}: ${c.map(l=>`${l.path} ${l.message}`).join("; ")}`;if(t)throw new Error(u);console.error(u);continue}r.set(s.serviceCode,s)}return r}function cue(e,t){return e.get(t)}function uue(e){return[...e.values()].filter(t=>t.status==="verified")}Ak.exports={loadCatalog:sue,getEntry:cue,listVerified:uue,validateAgainstSchema:Ck}});var bm=_((Cxe,zk)=>{"use strict";var lue=/_generated_\d+$/;function Dk(e){return!Array.isArray(e)||e.length===0?!1:e.every(t=>lue.test(t))}var due=3;function Rk(e){let t=new Map;if(!e)return t;for(let r of e.values())for(let i of r.subServices||[]){i.serviceCode&&t.set(i.serviceCode,r);for(let n of i.productCodes||[])n&&t.set(n,{...r,_redirectVia:i.serviceCode})}return t}function vm(e){let t=e?.traps||[];return t.length===0?"":` Catalog hint: ${t[0]}`}function ym(e){return(e?.subServices||[]).map(r=>r.serviceCode).filter(Boolean)}function Ao(e,t){if(!e||!t)return null;let r=e.get(t);if(r)return r;let i=t.toLowerCase();for(let a of e.values())for(let o of a.subServices||[])if(o.serviceCode?.toLowerCase().startsWith(i))return a;let n=i.replace(/^amazon/,"");for(let a of e.values())if((a.displayName||"").toLowerCase().includes(n)&&n.length>=due)return a;return null}function fue(e,t,r,i){let n=t.context||{},a=n.serviceCode;if(e==="empty-estimate")return"This estimate has no services. Call add_service with at least one service before validating or exporting.";if(e==="tenancy-pricing-mismatch"){let o=n.selectedOption;return`Service ${a}: pricingStrategy "${o}" is invalid under tenancy "shared" \u2014 Standard/Convertible Reserved Instances are hidden by the calculator under shared tenancy, so the saved estimate renders Read-only. Two recovery paths: (a) set tenancy: "dedicated" or "host" to keep ${o} reserved instances, OR (b) switch to instance-savings (the shared-tenancy equivalent of standard) or compute-savings (the equivalent of convertible). Re-add via add_service with the corrected combination.`}if(e==="ec2-pricing-invalid-value"){let o=Array.isArray(n.invalid)?n.invalid.join("; "):"";return`Service ${a}: the saved blob's pricingStrategy carries invalid ${o}. The calculator will NOT honor these values \u2014 it silently prices as On-Demand / 1 Year. This blob was built outside the normal add_service path (add_service rejects these values). Recovery: re-add the service via add_service with pricingStrategy in the accepted form, e.g. {"model":"instanceSavings","term":"3 Year","upfrontPayment":"None"}.`}if(e==="template-existence"){let o=n.estimateFor,s=n.availableTemplates||[],c=a?Ao(r,a):null,u=ym(c);if(!o){let l=u.length>0?u:s,d=c?vm(c):"";return l.length>0?`Service ${a} has no estimateFor \u2014 it is a parent envelope, not something to add directly. Call add_service using one of its child service codes: ${l.join(", ")}.${d}`:`Service ${a} has no estimateFor. It is likely a parent envelope. Call search_services with the service name to find a concrete child service code, then add_service that one.${d}`}return s.length>0?`Service ${a}: estimateFor "${o}" is not valid. Re-add via add_service with one of: ${s.join(", ")}. Tip: get_service_fields lists the correct templates per service.`:`Service ${a}: estimateFor "${o}" not recognized. Re-add via add_service after checking get_service_fields for the correct template.`}if(e==="required-field-presence"){let o=n.componentId;if(o&&/_generated_\d+$/.test(o)){let c=a?Ao(r,a):null,u=ym(c),l=c?vm(c):"";return u.length>0?`Service ${a} is a parent envelope \u2014 its "${o}" slot expects a sub-service, not a literal value. Call add_service with one of these child codes instead of "${a}": ${u.join(", ")}.${l}`:`Service ${a} has a synthetic "_generated_" slot which means it is a parent envelope. Don't add it directly \u2014 use search_services to find the concrete child service code.${l}`}if(o){let u=((a?Ao(r,a):null)?.required||[]).find(d=>d.field===o),l=u?.example!==void 0?` Example: ${typeof u.example=="string"?`"${u.example}"`:JSON.stringify(u.example)}.`:"";return`Service ${a} is missing required field "${o}". Re-add this service via add_service with "${o}" populated.${l} Use get_service_fields for full field details.`}return`Service ${a} is missing required fields. Re-add via add_service; check get_service_fields for the required set.`}if(e==="value-parsability"){let o=n.componentId;return`Service ${a} field "${o}" has an unparseable value. Re-add via add_service with the correct shape; get_service_fields shows the expected value type for each field.`}if(e==="sub-service-active-list"){let o=n.parentServiceCode,s=n.childServiceCode,c=n.allowedActiveList;if(a&&!o){let u=i.get(a);if(u){if(u._redirectVia){let p=u._redirectVia,m=vm(u);return`Service "${a}" is a product under the "${p}" provider in ${u.serviceCode}. ${u.serviceCode} is structured per-provider, not per-product \u2014 the calculator does not accept "${a}" as a top-level service. Call add_service with service="${p}" instead \u2014 the server nests it under ${u.serviceCode} automatically. Use get_service_fields("${p}") to discover the model selection field IDs for the specific product.${m}`}let l=ym(u).filter(p=>p!==a),d=vm(u),f=l.length>0?` Other valid children: ${l.join(", ")}.`:"";return`Service "${a}" is a sub-service of ${u.serviceCode}. Call add_service with service="${a}" (the child code) \u2014 the server nests it under ${u.serviceCode} automatically.${f}${d}`}return`Service "${a}" is a sub-service. Re-add via add_service using a parent envelope's child code (e.g. "amazonS3:Standard" rather than "amazonS3" alone). Use search_services to find the right key.`}return Array.isArray(c)&&c.length>0?`Sub-service "${s}" is not allowed under parent "${o}". Allowed children: ${c.join(", ")}. Re-add via add_service using one of those.`:`Sub-service entry under ${o} is malformed. Re-add via add_service with a valid sub-service code; check search_services.`}if(e==="column-form-default-trap"){let o=n.componentId,s=n.defaultCount,c=n.defaultInstanceType||"(unspecified)",u=n.tableLabel||o,l=n.countRowLabel||"count";return`Service ${a}'s columnFormIPM "${o}" (${u}) is missing \u2014 the calculator would silently default it to ${s} \xD7 "${c}" and add cost the user did not authorize. To suppress: add "${o}" to calculationComponents with the count row "${l}" set to "0" (or populate it explicitly if the user actually wants those nodes). Use get_service_fields(${a}) to see the row column structure.`}return e==="definition-unavailable"?`Could not fetch a PCT definition for service code "${a||"unknown"}" while linting \u2014 this can mean the code is wrong, or that the fetch was skipped/failed for an otherwise-valid code (e.g. a transient network error). If "${a||"unknown"}" was just added via add_service, it should be valid; retry validate_estimate once before assuming the code itself is wrong. If it still fails, use search_services to confirm the correct service code, then re-add via add_service.`:`Lint failure: ${t.message}. Re-add the affected service via add_service after consulting get_service_fields.`}function pue(e,t){if(!e||e.status==="editable")return null;let r=Rk(t),i=e.status==="read-only"||e.status==="required-input",n=[];for(let s of e.services||[])for(let c of s.failures||[])!i&&c.severity==="required-only"||n.push(c);if(n.length===0)return null;if(n.length>1&&n.every(s=>s.predicate==="required-field-presence")&&n.every(s=>s.context?.serviceCode===n[0].context?.serviceCode)){let s=n[0].context.serviceCode,c=n.map(u=>u.context?.componentId).filter(Boolean);return`Service ${s} is missing ${c.length} required fields: ${c.map(u=>`"${u}"`).join(", ")}. Re-add via add_service with ALL of them populated in one call. Use get_service_fields(${s}) for value shapes.`}let o=fue(n[0].predicate,n[0],t,r);return n.length>1?o+` (${n.length-1} more issue${n.length>2?"s":""} to fix; full list in lint_services.)`:o}var Mk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Nk=/^[0-9a-f]{40}$/i;function mue(e){let t=String(e||""),r=Mk.test(t),i=Nk.test(t);return r?"The id is in the right shape but the estimate is not in storage \u2014 estimates expire after 24h. Call create_estimate (or build_estimate) to start a new one and re-add the services.":i?"That looks like a calculator save id (the 40-char hex from export_estimate's sharable_url), not the id this tool expects. If you want to read an existing public estimate, use import_estimate. To build a new one, call create_estimate and use the id it returns.":"That looks like a name or free text, not an estimate id. The estimate_id argument expects the id returned by create_estimate or build_estimate (a 36-char hyphenated string). Call create_estimate to get one."}function hue({serviceKey:e,validIds:t,catalog:r}){if(!t||t.length===0||Dk(t)){let o=Ao(r,e),s=ym(o);return s.length>0?`Service "${e}" is a parent envelope with no fields of its own. Call add_service / build_estimate with one of its child service codes: ${s.join(", ")}. `+(o.traps?.[0]?`Catalog hint: ${o.traps[0]}`:""):`Service "${e}" has no input fields \u2014 it's likely a parent envelope. Call search_services to find concrete child service codes (e.g. for "${e}"-shaped names, the actual codes often differ in capitalization or have suffixes like "Standard" / "OnDemand").`}let n=t.slice(0,12),a=t.length>n.length?` (and ${t.length-n.length} more \u2014 call get_service_fields for the full list)`:"";return`Valid field IDs for ${e}: ${n.join(", ")}${a}.`}function gue({serviceKey:e,missingFields:t,catalog:r}){let i=Ao(r,e);if(t.length===1){let n=t[0],a=(i?.required||[]).find(s=>s.field===n),o=a?.example!==void 0?` Example: ${typeof a.example=="string"?`"${a.example}"`:JSON.stringify(a.example)}.`:"";return`Service ${e} is missing required field "${n}". Re-add this service via add_service with "${n}" populated.${o} Use get_service_fields(${e}) for full field details.`}return`Service ${e} is missing ${t.length} required fields: ${t.map(n=>`"${n}"`).join(", ")}. Re-add via add_service with ALL of them populated in one call. Use get_service_fields(${e}) for value shapes.`}zk.exports={nextStepFor:pue,notFoundHintFor:mue,invalidFieldIdsHintFor:hue,partialEntryHintFor:gue,allFieldsAreSyntheticSlots:Dk,findCatalogEntry:Ao,_internals:{buildChildToParent:Rk,findCatalogEntry:Ao,ESTIMATE_ID_RE:Mk,CALCULATOR_SAVE_ID_RE:Nk}}});var S_=_((Axe,Zk)=>{"use strict";var vue={ec2Enhancement:[{id:"utilization",type:"numericInput",label:"Utilization (% of month, 1\u2013100)",helpText:'Percent of the month the instance is running (1\u2013100, default 100). Pass as a top-level string, e.g. utilization: "80". The transform routes it into pricingStrategy.value.utilizationValue. The PCT does not surface this field directly because it is nested inside the pricingStrategy component \u2014 pass it at the top level of your config.',default:"100",_synthetic:!0}]},yue={ec2Enhancement:{pricingStrategy:{helpText:'Pricing model. Accepts a string shorthand ("ondemand", "spot", "instanceSavings3yrAllUpfront") or an object {"model":"instanceSavings","term":"3 Year","upfrontPayment":"None"}. Display labels like "EC2 Instance Savings Plans" are also accepted. Invalid values are rejected at add_service \u2014 nothing silently falls back to On-Demand. Note: reserved/convertible require tenancy "dedicated" or "host"; under shared tenancy they are remapped to instanceSavings/computeSavings.',validModels:["ondemand","instanceSavings","computeSavings","reserved","convertible","spot"],validTerms:["1 Year","3 Year"],validUpfrontPayments:["None","Partial","All"]}}};function bue(e,t){let r=vue[e],i=yue[e];if((!r||r.length===0)&&!i)return t;let n=t;if(i){let a=!1,o=t.map(s=>{let c=i[s.id];return c?(a=!0,{...s,...c}):s});a&&(n=o)}if(r&&r.length>0){let a=new Set(n.map(s=>s.id)),o=r.filter(s=>!a.has(s.id));o.length>0&&(n=n===t?[...t,...o]:[...n,...o])}return n}Zk.exports={synthesizeAgentFields:bue}});var x_=_((Dxe,Fk)=>{var ht={TEMPLATE_EXISTENCE:"template-existence",REQUIRED_FIELD_PRESENCE:"required-field-presence",VALUE_PARSABILITY:"value-parsability",SUB_SERVICE_ACTIVE_LIST:"sub-service-active-list",DEFINITION_UNAVAILABLE:"definition-unavailable",EMPTY_ESTIMATE:"empty-estimate",ONE_OF_MUTEX:"one-of-mutex",UNKNOWN_FIELD_ID:"unknown-field-id",INVALID_OPTION_ID:"invalid-option-id",INVALID_REGION:"invalid-region",COLUMN_FORM_DEFAULT_TRAP:"column-form-default-trap",COLUMN_FORM_UNREMAPPED_VALUE:"column-form-unremapped-value",COLUMN_FORM_DETERMINED_SELECTOR_OMITTED:"column-form-determined-selector-omitted",COLUMN_FORM_TUPLE_INVALID:"column-form-tuple-invalid",TENANCY_PRICING_MISMATCH:"tenancy-pricing-mismatch",EC2_PRICING_INVALID_VALUE:"ec2-pricing-invalid-value"},dr={EDITABLE:"editable",REQUIRED_INPUT:"required-input",READ_ONLY:"read-only",UNKNOWN:"unknown"};function*_ue(e){let t=function*(i,n,a=null){yield{id:i,svc:n,parentId:a};for(let o of n.subServices||[])yield{id:`${i}/${o.serviceCode}`,svc:o,parentId:i}};for(let[i,n]of Object.entries(e.services||{}))yield*t(i,n);let r=function*(i){for(let[n,a]of Object.entries(i.services||{}))yield*t(n,a);for(let[,n]of Object.entries(i.groups||{}))yield*r(n)};for(let[,i]of Object.entries(e.groups||{}))yield*r(i)}function wue(e,t){let r=e.estimateFor;if(!r)return{predicate:ht.TEMPLATE_EXISTENCE,severity:"other",message:`service "${e.serviceCode}" has no estimateFor`,context:{serviceCode:e.serviceCode}};if(t&&t.templateId===r)return null;let i=t&&t.templates||[];for(let a of i)if(typeof a=="string"){if(a===r)return null}else if(a&&typeof a=="object"&&(a.id===r||a.mappingFromTemplate===r))return null;let n=i.map(a=>typeof a=="string"?a:a&&a.id).filter(Boolean);return t&&t.templateId&&n.unshift(t.templateId),{predicate:ht.TEMPLATE_EXISTENCE,severity:"other",message:`estimateFor "${r}" not in service "${e.serviceCode}" templates [${n.join(", ")}]`,context:{serviceCode:e.serviceCode,estimateFor:r,availableTemplates:n}}}function Sue(e){return Object.prototype.hasOwnProperty.call(e||{},"displayIf")}function Lk(e){return Object.prototype.hasOwnProperty.call(e||{},"displayIf")}function $ue(e){return!!(e&&e.validations&&e.validations.required)}function ju(e,t,r){if(!e||typeof e!="object")return null;if(Array.isArray(e.and)){let i=!1;for(let n of e.and){let a=ju(n,t,r);if(a===!1)return!1;a===null&&(i=!0)}return i?null:!0}if(Array.isArray(e.or)){let i=!1;for(let n of e.or){let a=ju(n,t,r);if(a===!0)return!0;a===null&&(i=!0)}return i?null:!1}if(e.not!==void 0){let i=ju(e.not,t,r);return i===null?null:!i}if(e.exists!==void 0)return!0;for(let i of["==","!=",">=","<=",">","<"])if(Array.isArray(e[i])&&e[i].length===2){let n=qk(e[i][0],t,r),a=qk(e[i][1],t,r);return n===void 0||a===void 0?null:xue(i,n,a)}return null}function qk(e,t,r){if(e==null||typeof e!="object")return e;if(e.type==="component"&&typeof e.id=="string"){let i=t&&t[e.id];return i!==void 0?i&&typeof i=="object"&&"value"in i?i.value:i:typeof r=="function"?r(e.id):void 0}if(Object.prototype.hasOwnProperty.call(e,"value"))return e.value}function xue(e,t,r){if(e==="==")return String(t)===String(r);if(e==="!=")return String(t)!==String(r);let i=Number(t),n=Number(r);return Number.isNaN(i)||Number.isNaN(n)?null:e===">="?i>=n:e==="<="?i<=n:e===">"?i>n:e==="<"?i<n:null}function Yi(e,t){for(let r of e.templates||[])if(typeof r!="string"&&r&&typeof r=="object"&&(r.id===t||r.mappingFromTemplate===t))return r;return null}function $_(e,t,r,i={}){let{skipMathWalk:n=!1}=i,a=[],o=new Set,s=l=>{!l||typeof l!="string"||o.has(l)||(o.add(l),a.push(l))},c=(l,d)=>{if(!l||typeof l!="object")return;let f=d||Sue(l);if(Array.isArray(l)){for(let p of l)c(p,f);return}l.id&&typeof l.id=="string"&&!f&&!Lk(l)&&$ue(l)&&s(l.id);for(let p of Object.values(l))p&&typeof p=="object"&&c(p,f)};if(c(e,!1),(!t||!t.templateId||!e||e.id===t.templateId||e.mappingFromTemplate===t.templateId)&&t&&Array.isArray(t.required))for(let l of t.required)l&&typeof l.field=="string"&&s(l.field);if(!n)for(let l of Oue(e,r))s(l);return a}function Oue(e,t){if(!e)return[];let r=t||{},i=new Map,n=d=>{if(!(!d||typeof d!="object")){if(Array.isArray(d)){for(let f of d)n(f);return}d.type==="input"&&typeof d.id=="string"&&i.set(d.id,d);for(let f of Object.values(d))n(f)}};n(e);let a=d=>{let f=i.get(d);return f&&f.defaultValue!==void 0?f.defaultValue:void 0},o=d=>{let f=i.get(d);return!f||!f.displayIf?!0:ju(f.displayIf,r,a)===!0},s=[],c=d=>{let f=s.length;s.push({inputs:new Set,expressions:[]});let p=m=>{if(!(!m||typeof m!="object")){if(Array.isArray(m)){for(let g of m)p(g);return}m.type==="input"&&typeof m.id=="string"&&s[f].inputs.add(m.id),m.type==="maths"&&m.subType==="basicMaths"&&Array.isArray(m.operands)&&s[f].expressions.push(m);for(let g of Object.values(m))p(g)}};p(d)};if(Array.isArray(e.cards)&&e.cards.length>0)for(let d of e.cards)c(d);else c(e);let u=d=>{if(!(d in r))return!1;let f=i.get(d);if(!f||f.defaultValue===void 0)return!0;let p=r[d],m=p&&typeof p=="object"&&"value"in p?p.value:p;return String(m)!==String(f.defaultValue)},l=new Set;for(let d of s){let f=new Map;for(let $ of d.expressions)typeof $.id=="string"&&f.set($.id,$);let p=new Set,m=new Set,g=!0,w=0;for(;g&&w<50;){g=!1,w++;for(let[$,O]of f){if(p.has($))continue;let I=!0,k=!1;for(let T of O.operands)if(!(!T||typeof T.variableId!="string"))if(i.has(T.variableId)){if(T.required===!0&&!d.inputs.has(T.variableId)){I=!1;break}if(T.required===!0&&!u(T.variableId)){I=!1;break}d.inputs.has(T.variableId)&&u(T.variableId)&&(k=!0)}else{if(!f.has(T.variableId)){I=!1;break}if(!p.has(T.variableId)){I=!1;break}m.has(T.variableId)&&(k=!0)}I&&k&&(p.add($),m.add($),g=!0)}}for(let $ of d.expressions){let O=$.operands.filter(N=>N&&typeof N.variableId=="string"&&N.required===!0&&i.has(N.variableId));if(O.length===0)continue;let I=O.filter(N=>d.inputs.has(N.variableId)&&u(N.variableId)),k=$.operands.some(N=>N&&typeof N.variableId=="string"&&!i.has(N.variableId)&&f.has(N.variableId)&&m.has(N.variableId));if(I.length>=2||k)for(let N of O)d.inputs.has(N.variableId)&&o(N.variableId)&&(u(N.variableId)||l.add(N.variableId))}}return[...l]}function Pue(e){if(!e||typeof e!="object")return null;if(Array.isArray(e["=="])){let[t,r]=e["=="];return t&&t.type==="component"&&typeof t.id=="string"&&(typeof r=="string"||typeof r=="number")?{field:t.id,values:new Set([String(r)])}:null}if(Array.isArray(e.or)){let t=null,r=new Set;for(let i of e.or){if(!Array.isArray(i["=="]))return null;let[n,a]=i["=="];if(!(n&&n.type==="component"&&typeof n.id=="string")||typeof a!="string"&&typeof a!="number"||t&&t!==n.id)return null;t=n.id,r.add(String(a))}return t?{field:t,values:r}:null}return null}function Iue(e){if(!e)return[];let t=new Map,r=new Map,i=s=>{if(!(!s||typeof s!="object")){if(Array.isArray(s)){for(let c of s)i(c);return}s.type==="input"&&typeof s.id=="string"&&t.set(s.id,{displayIf:s.displayIf,required:s.validations&&s.validations.required}),s.type==="maths"&&s.subType==="variable"&&typeof s.id=="string"&&typeof s.refer=="string"&&r.set(s.id,s.refer);for(let c of Object.values(s))i(c)}};i(e);let n=s=>r.get(s)||s,a=[],o=s=>{if(!(!s||typeof s!="object")){if(Array.isArray(s)){for(let c of s)o(c);return}if(s.operation==="addition"&&Array.isArray(s.operands)){let c=[],u=!1;for(let l of s.operands){if(!l||typeof l.variableId!="string")continue;let d=n(l.variableId),f=t.get(d);if(!f||!f.displayIf){u=!0;break}let p=Pue(f.displayIf);if(!p){u=!0;break}if(f.required===!0){u=!0;break}c.push({inputId:d,gate:p})}if(!u&&c.length>=2){let l=c[0].gate.field;if(c.every(d=>d.gate.field===l)){let d=new Set,f=!0;for(let p of c)for(let m of p.gate.values){if(d.has(m)){f=!1;break}d.add(m)}f&&a.push({gatingField:l,members:c.map(p=>({id:p.inputId,values:p.gate.values}))})}}}for(let c of Object.values(s))o(c)}};return o(e),a}function jue(e,t){let r=Yi(t,e.estimateFor);if(!r)return[];let i=e.calculationComponents||{},n=[];for(let a of Iue(r)){let o=i[a.gatingField];if(o===void 0)continue;let s=typeof o=="object"&&o!==null&&"value"in o?o.value:o;if(s==null)continue;let c=String(s),u=a.members.find(l=>l.values.has(c));u&&(u.id in i||n.push({predicate:ht.ONE_OF_MUTEX,severity:"required-only",message:`gating field "${a.gatingField}"=${c} requires variant "${u.id}" to be populated for ${e.serviceCode}`,context:{serviceCode:e.serviceCode,gatingField:a.gatingField,gatingValue:c,expectedComponentId:u.id,availableMembers:a.members.map(l=>l.id)}}))}return n}function Eue(e){if(e==null)return!1;if(typeof e=="string")return e.trim().length>0;if(typeof e=="object"){if(Object.keys(e).length===0)return!1;if("value"in e){let t=e.value;if(t==null||typeof t=="string"&&t.trim().length===0)return!1}}return!0}function Tue(e,t,r){let i=Yi(t,e.estimateFor);if(!i)return[];let n=$_(i,r,e.calculationComponents),a=e.calculationComponents||{},o=[];for(let s of n)s in a&&(Eue(a[s])||o.push({predicate:ht.VALUE_PARSABILITY,severity:"other",message:`required component "${s}" has unparseable value: ${JSON.stringify(a[s])}`,context:{serviceCode:e.serviceCode,componentId:s,savedValue:a[s]}}));return o}function kue(e,t){let r=Yi(t,e.estimateFor);if(!r)return[];let i=e.calculationComponents||{},n=Object.keys(i);if(n.length===0)return[];let a=new Set,o=u=>{if(!(!u||typeof u!="object")){if(Array.isArray(u)){for(let l of u)o(l);return}u.type==="input"&&typeof u.id=="string"&&a.add(u.id);for(let l of Object.values(u))o(l)}};if(o(r),a.size===0)return[];let s=[...a],c=[];for(let u of n){if(a.has(u))continue;let l=Cue(u,s),d=l.length?` Did you mean: ${l.map(f=>`"${f}"`).join(", ")}?`:"";c.push({predicate:ht.UNKNOWN_FIELD_ID,severity:"required-only",message:`unknown component "${u}" in calculationComponents for ${e.serviceCode}.${d}`,context:{serviceCode:e.serviceCode,componentId:u,suggestions:l}})}return c}function Cue(e,t,r=3){let i=e.toLowerCase();return t.map(n=>({id:n,dist:Aue(i,n.toLowerCase())})).filter(n=>n.dist<=Math.max(Math.floor(e.length*.6),3)).sort((n,a)=>n.dist-a.dist).slice(0,r).map(n=>n.id)}function Aue(e,t){let r=e.length,i=t.length;if(r===0)return i;if(i===0)return r;let n=new Array(i+1),a=new Array(i+1);for(let o=0;o<=i;o++)n[o]=o;for(let o=1;o<=r;o++){a[0]=o;for(let s=1;s<=i;s++){let c=e[o-1]===t[s-1]?0:1;a[s]=Math.min(a[s-1]+1,n[s]+1,n[s-1]+c)}for(let s=0;s<=i;s++)n[s]=a[s]}return n[i]}function Due(e,t){let r=Yi(t,e.estimateFor);if(!r)return[];let i=e.calculationComponents||{};if(Object.keys(i).length===0)return[];let n=new Map,a=s=>{if(!(!s||typeof s!="object")){if(Array.isArray(s)){for(let c of s)a(c);return}s.type==="input"&&typeof s.id=="string"&&Array.isArray(s.options)&&s.options.length>0&&(s.subType==="dropdown"||s.subType==="frequency")&&n.set(s.id,{subType:s.subType,optionIds:new Set(s.options.map(c=>c&&c.id).filter(Boolean).map(String))});for(let c of Object.values(s))a(c)}};if(a(r),n.size===0)return[];let o=[];for(let[s,c]of Object.entries(i)){let u=n.get(s);if(!u)continue;let l,d;if(u.subType==="dropdown"?(l="value",d=c&&typeof c=="object"&&"value"in c?c.value:c):(l="unit",d=c&&typeof c=="object"?c.unit:void 0),d==null)continue;let f=String(d);if(u.optionIds.has(f))continue;let p=[...u.optionIds].slice(0,5),m=u.optionIds.size>5?`, ... (${u.optionIds.size} total)`:"";o.push({predicate:ht.INVALID_OPTION_ID,severity:"required-only",message:`field "${s}" ${l} "${f}" not in options [${p.join(", ")}${m}] for ${e.serviceCode}`,context:{serviceCode:e.serviceCode,componentId:s,slot:l,observed:f,validOptions:[...u.optionIds]}})}return o}function Rue(e,t){if(!t)return[];if(!e.region)return[];let r=t[e.serviceCode];if(!Array.isArray(r)||r.length===0)return[];if(r.includes(e.region))return[];let i=r.slice(0,5),n=r.length>5?`, ... (${r.length} total)`:"";return[{predicate:ht.INVALID_REGION,severity:"required-only",message:`region "${e.region}" not supported for ${e.serviceCode}. Supported: ${i.join(", ")}${n}`,context:{serviceCode:e.serviceCode,observed:e.region,validRegions:r}}]}function Mue(e,t){let r=Yi(t,e.estimateFor);if(!r)return[];let i=e.calculationComponents||{},n=Fue(r),a=s=>{let c=n.componentsById?.get(s);return!c||!Lk(c)?!0:ju(c.displayIf,i,l=>n.defaultsById?.get(l))!==!1},o=[];for(let s of Bs(r)){if(s.subType!=="columnFormIPM"||!a(s.id))continue;let c=s.row||[],u=null,l=null;for(let m of c)u==null&&(m.type==="textInput"||m.type==="numericInput")&&m.defaultValue!==void 0&&m.defaultValue!==""&&Number(m.defaultValue)>0&&(u=m),l==null&&m.type==="autoSuggest"&&(l=m);if(!u||s.id in i)continue;let d=Number(u.defaultValue),f=l?.defaultValue||"(unspecified)",p=u.selectorId||u.label||"count";o.push({predicate:ht.COLUMN_FORM_DEFAULT_TRAP,severity:"required-only",message:`columnFormIPM "${s.id}" (${s.label||"unnamed table"}) is absent \u2014 calculator will silently default to ${d} \xD7 "${f}" and add cost the agent did not authorize`,context:{serviceCode:e.serviceCode,componentId:s.id,tableLabel:s.label||null,countRowLabel:p,defaultCount:d,defaultInstanceType:f}})}return o}function Nue(e,t){let r=Yi(t,e.estimateFor);if(!r)return[];let i=e.calculationComponents||{},n=[];for(let a of Bs(r)){if(a.subType!=="columnFormIPM"&&a.type!=="columnFormIPM")continue;let o=a.remap&&a.remap.keyValue;if(!o||typeof o!="object")continue;let s=new Set(Object.keys(o));if(s.size===0)continue;let c=new Set(Object.values(o).map(String)),u=i[a.id],l=u&&u.value;if(Array.isArray(l)){for(let d of l)if(!(!d||typeof d!="object"))for(let[f,p]of Object.entries(d)){if(!p||typeof p!="object")continue;let m=p.value&&typeof p.value=="object"?p.value.selectedId:p.value;typeof m=="string"&&s.has(m)&&(c.has(m)||n.push({predicate:ht.COLUMN_FORM_UNREMAPPED_VALUE,severity:"other",message:`columnFormIPM "${a.id}" cell "${f}" holds un-remapped selector value "${m}" for ${e.serviceCode} \u2014 calculator stores the remapped value "${o[m]}"; the raw value rehydrates read-only at $0`,context:{serviceCode:e.serviceCode,componentId:a.id,cellKey:f,observed:m,expectedRemapped:o[m]}}))}}}return n}function zue(e,t,r,i){if(!r||typeof r.get!="function")return[];let n=r.get(e.serviceCode);if(!Array.isArray(n)||n.length===0)return[];let a=i&&typeof i.get=="function"&&i.get(e.serviceCode)||null,o=Yi(t,e.estimateFor);if(!o)return[];let s=e.calculationComponents||{},c=new Set;for(let d of n)if(d&&typeof d=="object")for(let f of Object.keys(d))c.add(f);if(c.size===0)return[];let u=new Set;for(let d of n)d&&typeof d=="object"&&d.TermType!=null&&u.add(String(d.TermType));let l=[];for(let d of Bs(o)){if(d.subType!=="columnFormIPM"&&d.type!=="columnFormIPM")continue;let f=d.remap&&d.remap.keyValue;if(!f||typeof f!="object")continue;let p={};for(let[$,O]of Object.entries(f))p[String(O)]=$;let m=$=>Object.prototype.hasOwnProperty.call(p,$)?p[$]:$,g=s[d.id],w=g&&g.value;if(Array.isArray(w))for(let $ of w){if(!$||typeof $!="object")continue;let O={};for(let W of c){let re=$[W];if(!re||typeof re!="object")continue;let xe=re.value&&typeof re.value=="object"?re.value.selectedId:re.value;typeof xe=="string"&&(O[W]=m(xe))}let I=Object.keys(O);if(I.length===0)continue;let k=Array.isArray(d.row)?d.row.map(W=>W&&W.selectorId).filter(Boolean):[];if(k.length>0){let W=n.filter(re=>I.every(xe=>String(re[xe])===String(O[xe])));if(W.length>0)for(let re of c){if(!k.includes(re)||re in O||re in $||new Set(n.map(pe=>pe[re]).filter(pe=>pe!==void 0)).size<2)continue;let ne=[...new Set(W.map(pe=>pe[re]).filter(pe=>pe!==void 0))];if(ne.length!==1)continue;let fe=a?a[re]:void 0;fe!==void 0&&String(ne[0])!==String(fe)&&l.push({predicate:ht.COLUMN_FORM_DETERMINED_SELECTOR_OMITTED,severity:"required-only",message:`columnFormIPM "${d.id}" is missing selector "${re}", which is fixed to "${ne[0]}" for this row in region "${e.region||e.regionName||"unknown"}". The calculator silently defaults it and the saved line misprices \u2014 add {"${re}": {"value": "${ne[0]}"}} to the row.`,context:{serviceCode:e.serviceCode,componentId:d.id,selector:re,requiredValue:ne[0],region:e.region||null}})}}"TermType"in O&&u.size>0&&!u.has(String(O.TermType))&&delete O.TermType;let T=Object.keys(O);T.length===0||n.some(W=>T.every(re=>String(W[re])===String(O[re])))||l.push({predicate:ht.COLUMN_FORM_TUPLE_INVALID,severity:"other",message:`columnFormIPM "${d.id}" row tuple ${JSON.stringify(O)} is not a valid combination for ${e.serviceCode} in region "${e.region||e.regionName||"unknown"}" \u2014 it misprices silently (renders a wrong rate or $0)`,context:{serviceCode:e.serviceCode,componentId:d.id,region:e.region||null,regionName:e.regionName||null,observedTuple:O,comparedKeys:[...c]}})}}return l}function Zue(e){let t=e.calculationComponents||{},r=t.tenancy?.value,i=t.pricingStrategy?.value?.selectedOption;return r!=="shared"?[]:i!=="standard"&&i!=="convertible"?[]:[{predicate:ht.TENANCY_PRICING_MISMATCH,severity:"required-only",message:`${e.serviceCode}: pricingStrategy "${i}" is invalid under shared tenancy \u2014 calculator hides Standard/Convertible Reserved Instances and renders Read-only`,context:{serviceCode:e.serviceCode,tenancy:r,selectedOption:i}}]}var Uk=new Set(["on-demand","standard","convertible","instance-savings","compute-savings","spot"]),que=new Set(["1 Year","3 Year"]),Uue=new Set(["None","Partial","All"]);function Lue(e){if((e.serviceCode||"").toLowerCase()!=="ec2enhancement")return[];let t=e.calculationComponents?.pricingStrategy?.value;if(!t||typeof t!="object")return[];let r=[];return"selectedOption"in t&&!Uk.has(t.selectedOption)&&r.push(`selectedOption "${t.selectedOption}" (valid: ${[...Uk].join(", ")})`),"term"in t&&!que.has(t.term)&&r.push(`term "${t.term}" (valid: 1 Year, 3 Year)`),"upfrontPayment"in t&&!Uue.has(t.upfrontPayment)&&r.push(`upfrontPayment "${t.upfrontPayment}" (valid: None, Partial, All)`),r.length===0?[]:[{predicate:ht.EC2_PRICING_INVALID_VALUE,severity:"required-only",message:`${e.serviceCode}: pricingStrategy carries invalid ${r.join("; ")} \u2014 the calculator silently prices this as On-Demand / 1 Year instead of what the blob claims`,context:{serviceCode:e.serviceCode,invalid:r,selectedOption:t.selectedOption,term:t.term,upfrontPayment:t.upfrontPayment}}]}function*Bs(e){if(!(!e||typeof e!="object")){if(Array.isArray(e)){for(let t of e)yield*Bs(t);return}e.type==="input"&&e.id&&(yield e);for(let t of Object.values(e))yield*Bs(t)}}function Fue(e){let t=new Map,r=new Map;for(let i of Bs(e))t.set(i.id,i),i.defaultValue!==void 0&&r.set(i.id,i.defaultValue);return{componentsById:t,defaultsById:r}}function Bue(e,t,r){let i=Yi(t,e.estimateFor);if(!i)return[];let n=$_(i,r,e.calculationComponents),a=e.calculationComponents||{},o=[];for(let s of n)s in a||o.push({predicate:ht.REQUIRED_FIELD_PRESENCE,severity:"required-only",message:`required component "${s}" missing from calculationComponents for ${e.serviceCode}`,context:{serviceCode:e.serviceCode,componentId:s}});return o}function Vue(e){let t=new Set;for(let r of e.templates||[])typeof r=="string"?t.add(r):r&&typeof r=="object"&&r.id&&t.add(r.id);if(e.mappingDefinitions){let r=e.mappingDefinitions;if(Array.isArray(r.children))for(let i of r.children)t.add(i)}return t}function Hue(e,t){let r=[];if(!Array.isArray(e.subServices)||e.subServices.length===0)return r;let i=t.get(e.serviceCode);if(!i)return r;let n=Vue(i);for(let a of e.subServices){if(!a.serviceCode){r.push({predicate:ht.SUB_SERVICE_ACTIVE_LIST,severity:"other",message:`sub-service entry under ${e.serviceCode} has no serviceCode`,context:{parentServiceCode:e.serviceCode}});continue}n.size>0&&!n.has(a.serviceCode)&&!n.has(a.estimateFor)&&r.push({predicate:ht.SUB_SERVICE_ACTIVE_LIST,severity:"other",message:`sub-service "${a.serviceCode}" not in parent ${e.serviceCode}'s active list [${[...n].join(", ")}]`,context:{parentServiceCode:e.serviceCode,childServiceCode:a.serviceCode,allowedActiveList:[...n]}})}return r}function Jue(e,t){let r=t.get(e.serviceCode);return r&&r.subType==="subService"?[{predicate:ht.SUB_SERVICE_ACTIVE_LIST,severity:"other",message:`service "${e.serviceCode}" is a sub-service but appears at top-level peer position; expected inside parent's subServices envelope`,context:{serviceCode:e.serviceCode}}]:[]}function Gue(e){return e.length===0?dr.EDITABLE:e.some(r=>r.severity==="other")?dr.READ_ONLY:dr.REQUIRED_INPUT}function Kue(e){return e.includes(dr.READ_ONLY)?dr.READ_ONLY:e.includes(dr.REQUIRED_INPUT)?dr.REQUIRED_INPUT:e.includes(dr.UNKNOWN)?dr.UNKNOWN:dr.EDITABLE}function Wue({savedBlob:e,manifest:t,perServiceDefinitions:r,catalog:i,regionList:n,aggregations:a,selectorDefaults:o}){let s=[],c=[..._ue(e)];if(c.length===0)return{status:dr.READ_ONLY,services:[{id:"(no services)",parentId:null,serviceCode:null,estimateFor:null,status:dr.READ_ONLY,failures:[{predicate:ht.EMPTY_ESTIMATE,severity:"other",message:"estimate has no services \u2014 saved blob would rehydrate as a blank read-only calculator",context:{}}]}]};for(let{id:u,svc:l,parentId:d}of c){let f=r.get(l.serviceCode);if(!f){s.push({id:u,parentId:d,serviceCode:l.serviceCode,estimateFor:l.estimateFor,status:dr.UNKNOWN,failures:[{predicate:ht.DEFINITION_UNAVAILABLE,severity:"unknown",message:`no PCT definition provided for serviceCode "${l.serviceCode}"`,context:{serviceCode:l.serviceCode}}]});continue}let p=[],m=wue(l,f);m&&p.push(m);let g=i&&typeof i.get=="function"?i.get(l.serviceCode):void 0;m||(p.push(...Bue(l,f,g)),p.push(...Tue(l,f,g)),p.push(...jue(l,f)),p.push(...kue(l,f)),p.push(...Due(l,f)),p.push(...Rue(l,n)),p.push(...Mue(l,f)),p.push(...Nue(l,f)),p.push(...zue(l,f,a,o)),p.push(...Zue(l)),p.push(...Lue(l)),d===null&&p.push(...Hue(l,r))),d===null&&p.push(...Jue(l,t)),s.push({id:u,parentId:d,serviceCode:l.serviceCode,estimateFor:l.estimateFor,status:Gue(p),failures:p})}return{status:Kue(s.map(u=>u.status)),services:s}}Fk.exports={canRehydrate:Wue,PREDICATES:ht,STATUS:dr,findRequiredComponentIds:$_,findTemplate:Yi}});var Jk=_((Rxe,Hk)=>{var{loadManifest:Xue,loadRegionList:Yue,findService:Que,findServiceCandidates:ele,fetchServiceDefinition:tle,extractInputFields:rle,enrichFieldsWithMetadata:nle}=Fs(),{invalidFieldIdsHintFor:ile}=bm(),{synthesizeAgentFields:ale}=S_(),{validatePricingStrategy:ole}=u_(),{findRequiredComponentIds:sle,findTemplate:cle}=x_(),{getEntry:ule}=gm(),Bk=new Set(["region","description"]),lle=new Set(["tenancy","vcpu","physicalCores","storageTypeDH","storageAmountDH","gp3IopsDH","gp3ThroughputDH","iopsDH","iops2DH"]),dle=20;function P_(e,t){let r=e.length,i=t.length,n=Array.from({length:r+1},(a,o)=>o);for(let a=1;a<=i;a++){let o=n[0];n[0]=a;for(let s=1;s<=r;s++){let c=n[s];n[s]=e[s-1]===t[a-1]?o:1+Math.min(o,n[s],n[s-1]),o=c}}return n[r]}function Eu(e,t,r=3){let i=e.toLowerCase();return t.map(n=>({id:n,dist:P_(i,n.toLowerCase())})).filter(n=>n.dist<=Math.max(Math.floor(e.length*.6),3)).sort((n,a)=>n.dist-a.dist).slice(0,r).map(n=>n.id)}var O_=new Set;function fle(e){let t=new Map;for(let r of e){let i=String(r.id).toLowerCase();if(t.has(i)&&t.get(i)!==r.id)return!0;t.set(i,r.id)}return!1}function Vk(e,t,r={}){if(!e||!e.type)return{ok:!0};let i=r.cacheKey||`${r.serviceCode||""}:${e.id}`;if(e.type==="dropdown"&&Array.isArray(e.options)){let n=t&&typeof t=="object"&&"value"in t,a=n?t.value:t;if(typeof a!="string")return{ok:!1,error:`Field "${e.id}": expected a string option id, got ${typeof a}.`};let o=e.options.map(m=>m.id);if(o.includes(a))return{ok:!0};if(!O_.has(i)&&fle(e.options)&&O_.add(i),!O_.has(i)){let m=a.toLowerCase(),g=o.find(w=>w.toLowerCase()===m);if(g)return{ok:"corrected",correctedValue:n?{...t,value:g}:g,reason:"case mismatch"}}let c=null;for(let m of o)if(P_(a,m)<=1){c=m;break}if(c&&c!==a)return{ok:"corrected",correctedValue:n?{...t,value:c}:c,reason:"single-character typo"};let u=Eu(a,o,3),l=o.length>10,d=o.slice(0,10).join(", "),f=l?` ...(${o.length} total)`:"",p=u.length?` Did you mean: ${u.map(m=>`"${m}"`).join(", ")}?`:"";return{ok:!1,error:`Field "${e.id}": "${a}" is not a valid option.${p} Allowed: ${d}${f}`}}if(e.type==="fileSize"){if(!t||typeof t!="object"||typeof t.unit!="string"||!("value"in t))return{ok:!1,error:`Field "${e.id}": expected { value, unit } object${e.defaultUnit?` (e.g. unit "${e.defaultUnit}")`:""}.`};let n=t.unit,a=n.split("|");if(a.length!==2)return{ok:!1,error:`Field "${e.id}": unit "${n}" must be "<size>|<freq>"${e.defaultUnit?` (e.g. "${e.defaultUnit}")`:""}.`};let[o,s]=a,c=e.validSizes||[];if(c.length>0&&c.includes(o))return{ok:!0};let u=o.trim().toLowerCase();return c.includes(u)?{ok:"corrected",correctedValue:{...t,unit:`${u}|${s}`},reason:"size casing/whitespace"}:{ok:!1,error:`Field "${e.id}": size "${o}" is not valid. Allowed sizes: [${c.join(", ")}]${e.defaultUnit?`, default "${e.defaultUnit}"`:""}.`}}if(e.type==="numericInput"){let n=null;typeof t=="number"&&Number.isFinite(t)&&(n=String(t));let a=n||t;if(typeof a!="string")return{ok:!1,error:`Field "${e.id}": expected a string numeric value, got ${t===null?"null":typeof t}.`};let o=Number(a);if(Number.isFinite(o)){if(e.minValue!=null&&o<e.minValue)return{ok:!1,error:`Field "${e.id}": value ${o} is below minimum ${e.minValue}.`};if(e.maxValue!=null&&o>e.maxValue)return{ok:!1,error:`Field "${e.id}": value ${o} exceeds maximum ${e.maxValue}.`};if(e.allowDecimals===!1&&!Number.isInteger(o))return{ok:!1,error:`Field "${e.id}": decimals are not allowed, got ${o}.`}}return n?{ok:"corrected",correctedValue:n,reason:"number coerced to string"}:{ok:!0}}if(e.type==="frequency"||e.type==="durationInput"){if(!t||typeof t!="object"||Array.isArray(t))return{ok:!1,error:`Field "${e.id}": expected { value, unit } object, got ${t===null?"null":typeof t}.`};if(!("value"in t))return{ok:!1,error:`Field "${e.id}": missing inner "value".`};let n=t;if(typeof t.value=="number"&&Number.isFinite(t.value))n={...t,value:String(t.value)};else if(typeof t.value!="string")return{ok:!1,error:`Field "${e.id}": inner "value" must be a string, got ${t.value===null?"null":typeof t.value}.`};let a=(e.options||[]).map(o=>o.id).filter(Boolean);if(a.length>0&&typeof n.unit=="string"&&!a.includes(n.unit)){let o=Eu(n.unit,a,3),s=o.length?` Did you mean: ${o.map(c=>`"${c}"`).join(", ")}?`:"";return{ok:!1,error:`Field "${e.id}": unit "${n.unit}" is not a valid option.${s} Allowed: ${a.join(", ")}.`}}return n!==t?{ok:"corrected",correctedValue:n,reason:"inner value coerced to string"}:{ok:!0}}return{ok:!0}}async function ple(e,t,r,i,n){let a=Object.keys(t).filter(o=>!Bk.has(o));try{let o=await Xue(r||"aws"),s=Que(o,e);if(!s){let ne=ele(o,e,6);if(ne.length===0)return{error:`Service "${e}" not found in manifest. Use search_services to discover the correct service key.`,correctedConfig:t,corrections:[]};let fe=ne.map(pe=>` ${pe.key} \u2014 ${pe.name}`).join(`
|
|
86
86
|
`);return{error:`Service "${e}" did not resolve to a unique manifest entry. Candidates:
|
|
87
87
|
${fe}
|
|
88
88
|
Re-call add_service with the exact service key from this list.`,correctedConfig:t,corrections:[]}}if(t.region&&(r||"aws")==="aws")try{let fe=(await Yue("aws"))?.[s.key];if(Array.isArray(fe)&&fe.length>0&&!fe.includes(t.region))return{error:`Region "${t.region}" is not supported for ${s.key}. Supported regions: ${fe.slice(0,8).join(", ")}`+(fe.length>8?`, ... (${fe.length} total)`:"")+". Re-add via add_service with a supported region.",correctedConfig:t,corrections:[]}}catch{}let c=await tle(o,s.key,r||"aws");if(!c)return{error:null,correctedConfig:t,corrections:[]};let u=ale(s.key,rle(c)),l=u.map(ne=>ne.id),d=new Set(l),f=s.key.toLowerCase()==="ec2enhancement"||e.toLowerCase()==="ec2next",p=a.filter(ne=>!d.has(ne)&&!(f&&lle.has(ne)));if(p.length>0){let ne=p.map(pe=>{let Ye=Eu(pe,l);return Ye.length?` "${pe}" \u2014 did you mean: ${Ye.map(gt=>`"${gt}"`).join(", ")}?`:` "${pe}" \u2014 no close match found`}),fe=ile({serviceKey:s.key,validIds:l,catalog:i});return{error:`Invalid field IDs for ${s.key}:
|
|
@@ -96,13 +96,13 @@ ${w.join(`
|
|
|
96
96
|
Use get_service_fields to discover valid values.`,correctedConfig:t,corrections:[]};let I=await nle(c,u),k=[];for(let ne of I){if(ne.type!=="columnFormIPM"||!ne.selectorValues)continue;let fe=t[ne.id];if(!(!fe||!fe.value||!Array.isArray(fe.value)))for(let pe of fe.value)for(let[Ye,gt]of Object.entries(ne.selectorValues)){if(!gt||gt.length===0)continue;let pr=pe[Ye];if(!pr)continue;let Xr=typeof pr=="object"&&pr.value!==void 0?pr.value:pr;if(typeof Xr=="string"&&!gt.includes(Xr)){let fn=Eu(Xr,gt),dl=fn.length?` Did you mean: ${fn.map(gc=>`"${gc}"`).join(", ")}?`:"";k.push(` Field "${ne.id}", selector "${Ye}": "${Xr}" is not valid.${dl}
|
|
97
97
|
Allowed: ${gt.slice(0,10).join(", ")}${gt.length>10?` ... (${gt.length} total)`:""}`)}}}if(k.length>0)return{error:`Invalid selector values for ${s.key}:
|
|
98
98
|
${k.join(`
|
|
99
|
-
`)}`,correctedConfig:t,corrections:[]};let T=i&&typeof i.get=="function"?ule(i,s.key):void 0,W=(typeof n=="string"&&n.trim()?n.trim():null)||T?.templateId||(typeof c.templates?.[0]=="object"?c.templates[0]?.id:null),re=W?cle(c,W):null,xe=mle({template:re,catalogEntry:T,configKeys:new Set(a)});return{error:null,correctedConfig:m,corrections:g,...$?{truncated:!0}:{},...xe.length>0?{missingRequired:xe}:{}}}catch{return{error:null,correctedConfig:t,corrections:[]}}}function mle({template:e,catalogEntry:t,configKeys:r}){return e?sle(e,t,{},{skipMathWalk:!0}).filter(n=>!r.has(n)):[]}Hk.exports={META_KEYS:Bk,levenshtein:P_,suggestMatch:Eu,validateConfigKeys:ple,validateFieldValue:Vk}});var Xk=_((Mxe,Wk)=>{var{canRehydrate:hle}=x_();function Gk(e){let t=new Set;for(let r of Kk(e))r.serviceCode&&t.add(r.serviceCode);return t}function*Kk(e){let t=Object.values(
|
|
99
|
+
`)}`,correctedConfig:t,corrections:[]};let T=i&&typeof i.get=="function"?ule(i,s.key):void 0,W=(typeof n=="string"&&n.trim()?n.trim():null)||T?.templateId||(typeof c.templates?.[0]=="object"?c.templates[0]?.id:null),re=W?cle(c,W):null,xe=mle({template:re,catalogEntry:T,configKeys:new Set(a)});return{error:null,correctedConfig:m,corrections:g,...$?{truncated:!0}:{},...xe.length>0?{missingRequired:xe}:{}}}catch{return{error:null,correctedConfig:t,corrections:[]}}}function mle({template:e,catalogEntry:t,configKeys:r}){return e?sle(e,t,{},{skipMathWalk:!0}).filter(n=>!r.has(n)):[]}Hk.exports={META_KEYS:Bk,levenshtein:P_,suggestMatch:Eu,validateConfigKeys:ple,validateFieldValue:Vk}});var Xk=_((Mxe,Wk)=>{var{canRehydrate:hle}=x_();function Gk(e){let t=new Set;for(let r of Kk(e))r.serviceCode&&t.add(r.serviceCode);return t}function*Kk(e){let t=function*(r){for(let i of Object.values(r.services||{})){yield i;for(let n of i.subServices||[])yield n}for(let i of Object.values(r.groups||{}))yield*t(i)};for(let r of Object.values(e.services||{})){yield r;for(let i of r.subServices||[])yield i}for(let r of Object.values(e.groups||{}))yield*t(r)}function gle(e){let t=null,r=i=>{if(!(t||!i||typeof i!="object")){if(i.subType==="columnFormIPM"&&i.mappingDefinitionName){t=i;return}for(let n of Object.values(i))n&&typeof n=="object"&&r(n)}};return r(e),t}async function vle({savedBlob:e,partition:t="aws",catalog:r}={}){if(!e||typeof e!="object")throw new TypeError("canRehydrateFetch requires a savedBlob object");let i=Fs(),n=await i.loadManifest(t),a=Gk(e),o=new Map;for(let l of a)try{let d=await i.fetchServiceDefinition(n,l,t);d&&o.set(l,d)}catch{}let s=null;try{s=await i.loadRegionList(t)}catch{}let c=new Map,u=new Map;try{for(let l of Kk(e)){if(!l.serviceCode||c.has(l.serviceCode))continue;let d=o.get(l.serviceCode);if(!d)continue;let f=gle(d);if(!f)continue;let p=l.region;if(p)try{let m=await i.loadSelectorAggregations(d,f,p);m&&c.set(l.serviceCode,m);let g=await i.loadSelectorDefaults(d,f);g&&u.set(l.serviceCode,g)}catch{}}}catch{}return hle({savedBlob:e,manifest:n,perServiceDefinitions:o,catalog:r,regionList:s,aggregations:c,selectorDefaults:u})}Wk.exports={canRehydrateFetch:vle,collectServiceCodes:Gk}});var iC=_((Nxe,nC)=>{"use strict";var{PARTITIONS:Yk,loadManifest:_m,fetchServiceDefinition:Qk,extractInputFields:yle,enrichFieldsWithMetadata:ble,findService:I_}=Fs(),{validateConfigKeys:_le}=Jk(),{canRehydrateFetch:wle}=Xk(),{nextStepFor:Sle,notFoundHintFor:$le,allFieldsAreSyntheticSlots:xle,findCatalogEntry:Ole,partialEntryHintFor:Ple}=bm(),{getEntry:j_}=gm(),{synthesizeAgentFields:Ile}=S_(),wm=Pu();function eC(e){return{content:[{type:"text",text:e}]}}function Sm(e){return{content:[{type:"text",text:e}],isError:!0}}function jle(e){return eC(JSON.stringify(e,null,2))}function Ele(e,{requireExplicit:t=!1}={}){return!e&&!t||Yk[e]?null:Sm(`Unknown partition '${e}'. Valid partitions: ${Object.keys(Yk).join(", ")}`)}function Tle(e){try{let t=JSON.parse(e);return Array.isArray(t)||(t=[t]),{entries:t}}catch{return{error:Sm("Invalid JSON in services parameter.")}}}function tC(e,t){let r=t?.defaultFields;if(!r||typeof r!="object")return e;let i=null;for(let[n,a]of Object.entries(r))n in e||(i===null&&(i={...e}),i[n]=a);return i===null?e:i}function C_(e){return(e&&Array.isArray(e.templates)?e.templates:[]).map(r=>typeof r=="string"?r:r&&r.id).filter(Boolean)}function E_(e){let t=C_(e),r=t.find(n=>/withoutfreetier/i.test(n)),i=t.find(n=>/withfreetier/i.test(n)&&!/withoutfreetier/i.test(n));return i&&r?{includeFreeTier:i,excludeFreeTier:r}:null}var kle=/^amazon(rds|aurora)/i,Cle=/backup|outposts/i;function T_(e){return typeof e=="string"&&kle.test(e)&&!Cle.test(e)}var k_=`AWS Database Savings Plans are only available on Gen 7+ instance families (e.g. m7g/r7g, m8g/r8g, m9g). T-class instances (t3, t4g) and anything Gen 6 or older (m5, r5, m6, r6, ...) are NOT eligible at all \u2014 on any RDS engine. They are also only sold as a 1-year term (LeaseContractLength "1yr") \u2014 there is no 3-year Database Savings Plan. Neither constraint is enforced by the save-time lint, so picking "Database Savings Plans" as TermType on an ineligible instance, or with a 3-year LeaseContractLength, saves and rehydrates without error but silently misprices. Confirm the instance family's generation and use a 1-year term with the user before setting TermType to "Database Savings Plans".`;function rC(e){try{return JSON.stringify(e).toLowerCase().includes("database savings plans")}catch{return!1}}function Ale(e,t,r,i){if(typeof r!="string"||!r)return null;let n=i||null,a=n?(e.groups||{})[n]?.services:e.services;if(!a)return null;for(let[o,s]of Object.entries(a))if(o.split(":")[0]===t&&s&&s.description===r)return{service:t,description:r,group:n};return null}function Dle({catalog:e}){async function t(d,f){let p=[];for(let m of f){let{service:g,instance:w,group:$}=m,O=m.config;if(!g||!O){p.push({error:'Missing "service" or "config" in entry',entry:m});continue}if(typeof O=="string")try{O=JSON.parse(O)}catch{p.push({error:"Invalid JSON in config",service:g});continue}let I=w?`${g}:${w}`:g,k=await _le(g,O,d.partition,e,m.estimateFor);if(k.error){p.push({error:k.error,service:I});continue}O=k.correctedConfig;let T=j_(e,g);O=tC(O,T);let N=null;try{let pe=await _m(d.partition||"aws"),Ye=I_(pe,g);Ye&&(N=await Qk(pe,Ye.key,d.partition||"aws"))}catch{}let W=E_(N),re=typeof m.estimateFor=="string"&&m.estimateFor.trim()?m.estimateFor.trim():null;if(re&&N){let pe=C_(N);if(pe.length>0&&!pe.includes(re)){p.push({error:`estimateFor "${re}" is not a valid template for ${g}. Valid templates: ${pe.join(", ")}.`,service:I});continue}}let xe=re||T?.templateId||void 0;!re&&xe&&T.status==="unverified"&&wm.templateHint.unverified({serviceCode:g,templateId:xe,estimateId:d.id});let ne=Ale(d,g,O.description,$);d.addService(I,O,{group:$,templateIdHint:xe});let fe={success:!0,service:I,group:$||"(ungrouped)"};T_(g)&&rC(O)&&(fe.pricing_model_hint=k_),W&&!re&&(fe.free_tier_choice={applied:W.includeFreeTier,includeFreeTier:W.includeFreeTier,excludeFreeTier:W.excludeFreeTier,action_required:`${g} offers an AWS Free Tier choice and DEFAULTED to include it (${W.includeFreeTier}). Free Tier allowances are subtracted, which understates production/steady-state cost. Ask the user whether to include or exclude the Free Tier; to exclude it, re-add this service with estimateFor: "${W.excludeFreeTier}".`}),ne&&(fe.existing_entry=ne,fe.warning=`An entry with service="${g}" and description="${O.description}" already exists in this estimate (group: "${ne.group||"(ungrouped)"}"). add_service has appended a duplicate row \u2014 this inflates the cost. If you intended to replace the previous attempt (e.g. retrying after an error), call create_estimate to start fresh instead.`),k.corrections.length>0&&(fe.corrections=k.corrections,k.truncated&&(fe.truncated=!0)),k.missingRequired&&k.missingRequired.length>0&&(fe.partial=!0,fe.missing_required_fields=k.missingRequired,fe.next_step=Ple({serviceKey:g,missingFields:k.missingRequired,catalog:e})),p.push(fe)}return p}async function r(d){let f=await d.toAWSPayload(),p=await wle({savedBlob:f,partition:d.partition||void 0,catalog:e});return{blob:f,lintResult:p}}function i(d){return Sm(`Estimate "${d}" not found.
|
|
100
100
|
|
|
101
101
|
Next step: ${$le(d)}`)}function n(d,f){let p=d.status,m=p==="required-input"?k=>k.severity==="required-only":()=>!0,g=d.services.map(k=>k.failures.filter(m).map(T=>T.message).join("; ")).filter(Boolean).join(" | "),w=d.services.flatMap(k=>k.failures.filter(m).map(T=>T.predicate)).filter((k,T,N)=>N.indexOf(k)===T).join(", "),$=Sle(d,e),O=$?`
|
|
102
102
|
|
|
103
103
|
Next step: ${$}`:"";return`${f} ${p==="required-input"?"the saved estimate is missing required fields the calculator would silently default":"the saved estimate would rehydrate as read-only"}. ${g}${O}
|
|
104
104
|
|
|
105
|
-
Predicate names: ${w}.`}async function a(d){let{lintResult:f}=await r(d);if(wm.lint({verdict:f.status,services:f.services,estimateId:d.id}),f.status==="read-only"||f.status==="required-input")return{isError:!0,text:n(f,"Export refused \u2014")};let p=await d.export();return{isError:!1,sharable_url:p.shareableUrl,aws_estimate_id:p.estimateId}}async function o(d,f){let p=await _m(f),m=await Qk(p,d.key,f);if(!m)return null;let g=yle(m),w=await ble(m,g),$=Ile(d.key,w),O={serviceCode:d.key,serviceName:d.name,fields:$},I=E_(m);if(I){let T=j_(e,d.key);O.freeTierChoice={includeFreeTier:I.includeFreeTier,excludeFreeTier:I.excludeFreeTier,default:T?.templateId||I.includeFreeTier,note:"This service exposes an AWS Free Tier template choice. ASK THE USER whether to include or exclude the Free Tier, then set estimateFor on the add_service/build_estimate entry to includeFreeTier or excludeFreeTier above. If unspecified it defaults to including the Free Tier, which understates steady-state/production cost."}}let k=j_(e,d.key);return k&&(O.catalog={status:k.status,templateId:k.templateId,required:k.required,traps:k.traps,subServices:k.subServices,minimalConfig:k.minimalConfig,lastVerifiedAt:k.lastVerifiedAt}),T_(d.key)&&(O.pricingModelHint=k_),O}let s=new Map;if(e)for(let d of e.values())for(let f of d.subServices||[])for(let p of f.productCodes||[])p&&s.set(p,{parentEntry:d,providerCode:f.serviceCode});async function c({svc:d,partition:f}){let p=s.get(d.key);if(!p)return null;let{parentEntry:m,providerCode:g}=p,w=null,$=await _m(f),O=I_($,g);if(O)try{w=await o(O,f)}catch{}return wm.getServiceFields.redirectToParent({serviceCode:d.key,redirectTo:g,childCodes:[g],previewServiceCode:w?.serviceCode||null}),{serviceCode:d.key,serviceName:d.name,status:"redirect_to_provider",next_step:`Service "${d.key}" is a product under the "${g}" provider in ${m.serviceCode}. ${m.serviceCode} is structured per-provider, not per-product \u2014 the calculator does not accept "${d.key}" as a top-level service. Use service code "${g}" with add_service / build_estimate; select the specific model via modelSelection in the provider's field set (previewed below).`,redirect_to:g,parent_service_code:m.serviceCode,catalog:{status:m.status,traps:m.traps},...w?{preview_fields_for:w}:{}}}function u(d){if(!s.size)return d;let f=m=>{let g=s.get(m.key);return g?{...m,redirect_to:g.providerCode,note:`Product under "${g.providerCode}" provider in ${g.parentEntry.serviceCode}; use service code "${g.providerCode}" in add_service / build_estimate.`}:m};if(Array.isArray(d))return d.map(f);let p={};for(let[m,g]of Object.entries(d))p[m]=Array.isArray(g)?g.map(f):g;return p}async function l({svc:d,fields:f,partition:p}){let m=f.map(T=>T.id),g=d.isActive==="false",w=xle(m);if(!g||!w)return null;let $=Ole(e,d.key);if(!$||$.serviceCode===d.key)return null;let O=($.subServices||[]).map(T=>T.serviceCode).filter(Boolean),I=null;if(O[0]){let T=await _m(p),N=I_(T,O[0]);if(N)try{I=await o(N,p)}catch{}}wm.getServiceFields.redirectToParent({serviceCode:d.key,redirectTo:$.serviceCode,childCodes:O,previewServiceCode:I?.serviceCode||null});let k={serviceCode:d.key,serviceName:d.name,status:"redirect_to_parent",next_step:`Service "${d.key}" is a deprecated parent envelope with no real input fields. Use one of the verified child service codes instead: ${O.join(", ")}. `+(O.length>1?`Pick the one matching the user's intent \u2014 fields for "${O[0]}" are previewed below; if a different child fits better, call get_service_fields with that code.`:`Fields for "${O[0]}" are previewed below; use that code in add_service.`),redirect_to:$.serviceCode,child_service_codes:O,catalog:{status:$.status,traps:$.traps,subServices:$.subServices}};return I&&(k.preview_fields_for=I),k}return{addEntries:t,lintEstimate:r,estimateNotFoundResult:i,formatLintRefusal:n,exportWithLint:a,buildFieldsResult:o,maybeBuildRedirectResult:l,maybeBuildProductRedirect:c,annotateSearchResults:u}}nC.exports={createHandlerHelpers:Dle,mcpTextOk:eC,mcpTextErr:Sm,mcpJsonOk:jle,checkPartition:Ele,parseServicesArg:Tle,applyDefaultFields:tC,detectFreeTierChoice:E_,templateIdList:C_,isRdsFamilyService:T_,configMentionsDatabaseSavingsPlans:rC,DATABASE_SAVINGS_PLANS_HINT:k_}});var uC=_((zxe,cC)=>{var Do;try{Do=require("playwright").chromium}catch{Do=null}var Rle=require("node:fs"),aC=6e4,D_=3e4,Mle=2e4,Nle=250,zle=2e4,Zle=1e4,qle=2e4,Ule=['button:has-text("Export")','button:has-text("Export estimate")','a:has-text("Export")','[data-testid*="export"]','[aria-label*="Export"]'];function oC(e,t){if(!e)return{available:!1,reason:"playwright-missing",message:"The Playwright library is not installed. It is an on-demand dependency used only to render calculator-computed costs.",install:["npm install playwright","npx playwright install chromium","npx playwright install-deps chromium"]};let r=null;try{r=e.executablePath()}catch{r=null}return!r||!t(r)?{available:!1,reason:"chromium-missing",message:"Playwright is installed but the Chromium browser binary is not. It is an on-demand ~150MB download.",install:["npx playwright install chromium"]}:{available:!0}}function Lle(){return oC(Do,Rle.existsSync)}async function Fle(e){if(!Do)throw new Error("Playwright is not installed. Run: npm install --save-dev playwright && npx playwright install chromium");let t=await Do.launch({headless:!0});try{let r=await t.newContext({viewport:{width:1440,height:900}});try{let i=await r.newPage();await i.goto(e,{waitUntil:"networkidle",timeout:aC});let n=await Vle(i,Ule,D_);if(!n)throw new Error("Export button not found on page");if(!await Hle(i,n))throw new Error("rehydration failed: calculator disabled the Export button (estimate is in Read-only mode)");let o=await i.locator("text=/USD/").all(),s=await Promise.all(o.map(g=>g.innerText())),c=s.length>=2?R_(s[1]):null,u=await i.locator('tr, [role="row"]').all(),l=[];for(let g of u){let w=await g.locator('td, [role="cell"]').all().catch(()=>[]);w.length<6||l.push(await Promise.all(w.map($=>$.innerText().catch(()=>""))))}let d=sC(l),f=new Map,p=new Map;for(let{service:g,monthly:w,config:$}of d)f.set(g,w),p.set(g,$);let m=d.length?d.reduce((g,w)=>g+w.monthly,0):null;return{monthlyCost:c,monthlyByService:f,configByService:p,rows:d,rowsTotal:m}}finally{await r.close()}}finally{await t.close()}}async function A_(e,t){let r=Date.now()+t;for(;Date.now()<r;){if(await e.isVisible().catch(()=>!1)&&!await e.isDisabled().catch(()=>!0))return!0;await new Promise(n=>setTimeout(n,250))}return!1}async function Ble(e,{update:t=!0}={}){if(!Do)throw new Error("Playwright is not installed. Run: npm install --save-dev playwright && npx playwright install chromium");let r=await Do.launch({headless:!0});try{let i=await r.newContext({viewport:{width:1440,height:900}});try{let n=await i.newPage();await n.goto(e,{waitUntil:"networkidle",timeout:aC});let a=n.getByRole("button",{name:/Accept all cookies/i}).first();await a.isVisible().catch(()=>!1)&&(await a.click().catch(()=>{}),await n.waitForTimeout(500));let o=n.getByRole("button",{name:"Export"}).first();if(!await A_(o,D_))throw new Error("rehydration failed: the estimate never became ready (it may be read-only or broken)");let s=n.getByRole("button",{name:"Share"}).first();if(t){let f=n.getByRole("button",{name:/Update estimate/}).first();await f.count().
|
|
105
|
+
Predicate names: ${w}.`}async function a(d){let{lintResult:f}=await r(d);if(wm.lint({verdict:f.status,services:f.services,estimateId:d.id}),f.status==="read-only"||f.status==="required-input")return{isError:!0,text:n(f,"Export refused \u2014")};let p=await d.export();return{isError:!1,sharable_url:p.shareableUrl,aws_estimate_id:p.estimateId}}async function o(d,f){let p=await _m(f),m=await Qk(p,d.key,f);if(!m)return null;let g=yle(m),w=await ble(m,g),$=Ile(d.key,w),O={serviceCode:d.key,serviceName:d.name,fields:$},I=E_(m);if(I){let T=j_(e,d.key);O.freeTierChoice={includeFreeTier:I.includeFreeTier,excludeFreeTier:I.excludeFreeTier,default:T?.templateId||I.includeFreeTier,note:"This service exposes an AWS Free Tier template choice. ASK THE USER whether to include or exclude the Free Tier, then set estimateFor on the add_service/build_estimate entry to includeFreeTier or excludeFreeTier above. If unspecified it defaults to including the Free Tier, which understates steady-state/production cost."}}let k=j_(e,d.key);return k&&(O.catalog={status:k.status,templateId:k.templateId,required:k.required,traps:k.traps,subServices:k.subServices,minimalConfig:k.minimalConfig,lastVerifiedAt:k.lastVerifiedAt}),T_(d.key)&&(O.pricingModelHint=k_),O}let s=new Map;if(e)for(let d of e.values())for(let f of d.subServices||[])for(let p of f.productCodes||[])p&&s.set(p,{parentEntry:d,providerCode:f.serviceCode});async function c({svc:d,partition:f}){let p=s.get(d.key);if(!p)return null;let{parentEntry:m,providerCode:g}=p,w=null,$=await _m(f),O=I_($,g);if(O)try{w=await o(O,f)}catch{}return wm.getServiceFields.redirectToParent({serviceCode:d.key,redirectTo:g,childCodes:[g],previewServiceCode:w?.serviceCode||null}),{serviceCode:d.key,serviceName:d.name,status:"redirect_to_provider",next_step:`Service "${d.key}" is a product under the "${g}" provider in ${m.serviceCode}. ${m.serviceCode} is structured per-provider, not per-product \u2014 the calculator does not accept "${d.key}" as a top-level service. Use service code "${g}" with add_service / build_estimate; select the specific model via modelSelection in the provider's field set (previewed below).`,redirect_to:g,parent_service_code:m.serviceCode,catalog:{status:m.status,traps:m.traps},...w?{preview_fields_for:w}:{}}}function u(d){if(!s.size)return d;let f=m=>{let g=s.get(m.key);return g?{...m,redirect_to:g.providerCode,note:`Product under "${g.providerCode}" provider in ${g.parentEntry.serviceCode}; use service code "${g.providerCode}" in add_service / build_estimate.`}:m};if(Array.isArray(d))return d.map(f);let p={};for(let[m,g]of Object.entries(d))p[m]=Array.isArray(g)?g.map(f):g;return p}async function l({svc:d,fields:f,partition:p}){let m=f.map(T=>T.id),g=d.isActive==="false",w=xle(m);if(!g||!w)return null;let $=Ole(e,d.key);if(!$||$.serviceCode===d.key)return null;let O=($.subServices||[]).map(T=>T.serviceCode).filter(Boolean),I=null;if(O[0]){let T=await _m(p),N=I_(T,O[0]);if(N)try{I=await o(N,p)}catch{}}wm.getServiceFields.redirectToParent({serviceCode:d.key,redirectTo:$.serviceCode,childCodes:O,previewServiceCode:I?.serviceCode||null});let k={serviceCode:d.key,serviceName:d.name,status:"redirect_to_parent",next_step:`Service "${d.key}" is a deprecated parent envelope with no real input fields. Use one of the verified child service codes instead: ${O.join(", ")}. `+(O.length>1?`Pick the one matching the user's intent \u2014 fields for "${O[0]}" are previewed below; if a different child fits better, call get_service_fields with that code.`:`Fields for "${O[0]}" are previewed below; use that code in add_service.`),redirect_to:$.serviceCode,child_service_codes:O,catalog:{status:$.status,traps:$.traps,subServices:$.subServices}};return I&&(k.preview_fields_for=I),k}return{addEntries:t,lintEstimate:r,estimateNotFoundResult:i,formatLintRefusal:n,exportWithLint:a,buildFieldsResult:o,maybeBuildRedirectResult:l,maybeBuildProductRedirect:c,annotateSearchResults:u}}nC.exports={createHandlerHelpers:Dle,mcpTextOk:eC,mcpTextErr:Sm,mcpJsonOk:jle,checkPartition:Ele,parseServicesArg:Tle,applyDefaultFields:tC,detectFreeTierChoice:E_,templateIdList:C_,isRdsFamilyService:T_,configMentionsDatabaseSavingsPlans:rC,DATABASE_SAVINGS_PLANS_HINT:k_}});var uC=_((zxe,cC)=>{var Do;try{Do=require("playwright").chromium}catch{Do=null}var Rle=require("node:fs"),aC=6e4,D_=3e4,Mle=2e4,Nle=250,zle=2e4,Zle=1e4,qle=2e4,Ule=['button:has-text("Export")','button:has-text("Export estimate")','a:has-text("Export")','[data-testid*="export"]','[aria-label*="Export"]'];function oC(e,t){if(!e)return{available:!1,reason:"playwright-missing",message:"The Playwright library is not installed. It is an on-demand dependency used only to render calculator-computed costs.",install:["npm install playwright","npx playwright install chromium","npx playwright install-deps chromium"]};let r=null;try{r=e.executablePath()}catch{r=null}return!r||!t(r)?{available:!1,reason:"chromium-missing",message:"Playwright is installed but the Chromium browser binary is not. It is an on-demand ~150MB download.",install:["npx playwright install chromium"]}:{available:!0}}function Lle(){return oC(Do,Rle.existsSync)}async function Fle(e){if(!Do)throw new Error("Playwright is not installed. Run: npm install --save-dev playwright && npx playwright install chromium");let t=await Do.launch({headless:!0});try{let r=await t.newContext({viewport:{width:1440,height:900},locale:"en-US"});try{let i=await r.newPage();await i.goto(e,{waitUntil:"networkidle",timeout:aC});let n=await Vle(i,Ule,D_);if(!n)throw new Error("Export button not found on page");if(!await Hle(i,n))throw new Error("rehydration failed: calculator disabled the Export button (estimate is in Read-only mode)");let o=await i.locator("text=/USD/").all(),s=await Promise.all(o.map(g=>g.innerText())),c=s.length>=2?R_(s[1]):null,u=await i.locator('tr, [role="row"]').all(),l=[];for(let g of u){let w=await g.locator('td, [role="cell"]').all().catch(()=>[]);w.length<6||l.push(await Promise.all(w.map($=>$.innerText().catch(()=>""))))}let d=sC(l),f=new Map,p=new Map;for(let{service:g,monthly:w,config:$}of d)f.set(g,w),p.set(g,$);let m=d.length?d.reduce((g,w)=>g+w.monthly,0):null;return{monthlyCost:c,monthlyByService:f,configByService:p,rows:d,rowsTotal:m}}finally{await r.close()}}finally{await t.close()}}async function A_(e,t){let r=Date.now()+t;for(;Date.now()<r;){if(await e.isVisible().catch(()=>!1)&&!await e.isDisabled().catch(()=>!0))return!0;await new Promise(n=>setTimeout(n,250))}return!1}async function Ble(e,{update:t=!0}={}){if(!Do)throw new Error("Playwright is not installed. Run: npm install --save-dev playwright && npx playwright install chromium");let r=await Do.launch({headless:!0});try{let i=await r.newContext({viewport:{width:1440,height:900},locale:"en-US"});try{let n=await i.newPage();await n.goto(e,{waitUntil:"networkidle",timeout:aC});let a=n.getByRole("button",{name:/Accept all cookies/i}).first();await a.isVisible().catch(()=>!1)&&(await a.click().catch(()=>{}),await n.waitForTimeout(500));let o=n.getByRole("button",{name:"Export"}).first();if(!await A_(o,D_))throw new Error("rehydration failed: the estimate never became ready (it may be read-only or broken)");let s=n.getByRole("button",{name:"Share"}).first();if(t){let f=n.getByRole("button",{name:/Update estimate/}).first();if(await f.count().catch(()=>0)===0)throw new Error("Update estimate button not found (UI language or layout changed)");await f.click().catch(()=>{}),await A_(s,zle),await n.waitForTimeout(1500)}if(!await A_(s,D_))throw new Error("Share button never became available");await s.click();let c=n.getByRole("button",{name:/Agree and continue/i}).first();await c.waitFor({state:"visible",timeout:Zle}).then(()=>!0).catch(()=>!1)&&await c.click().catch(()=>{});let u=null,l=Date.now()+qle;for(;Date.now()<l&&!u;)u=(await n.locator("input").evaluateAll(p=>p.map(m=>m.value).filter(Boolean)).catch(()=>[])).find(p=>/[?&]id=[a-f0-9]+/.test(p))||null,u||await n.waitForTimeout(400);if(!u)throw new Error("could not read the public share link after sharing");return{estimateId:u.match(/[?&]id=([a-f0-9]+)/)[1],shareUrl:u}}finally{await i.close()}}finally{await r.close()}}function sC(e){let t=[];for(let r of e){if(!Array.isArray(r)||r.length<6||r.filter(c=>/USD/.test(c)).length<2)continue;let i=r.findIndex(c=>/USD/.test(c));if(i<1)continue;let n=r[i-1].trim(),a=R_(r[i+1]||""),o=(r[i+4]||"").trim(),s=o&&o!=="-"?o:null;n&&Number.isFinite(a)&&t.push({service:n,monthly:a,config:s})}return t}async function Vle(e,t,r){for(let i of t){let n=r?{timeout:r}:void 0;if(await e.locator(i).first().isVisible(n).catch(()=>!1))return i}return null}async function Hle(e,t){let r=e.locator(t).first(),i=Date.now()+Mle;for(;Date.now()<i;){if(!await r.isDisabled().catch(()=>!0))return!0;await e.waitForTimeout(Nle)}return!1}function R_(e){if(typeof e!="string")return null;let t=e.match(/([\d,]+(?:\.\d+)?)/);if(!t)return null;let r=Number(t[1].replace(/,/g,""));return Number.isFinite(r)?r:null}cC.exports={fetchCostFromDOM:Fle,fetchPricedEstimateId:Ble,parseDetailRows:sC,parseUsd:R_,classifyPlaywright:oC,checkPlaywrightAvailability:Lle}});var lC=_(cn=>{"use strict";var $m=`
|
|
106
106
|
|
|
107
107
|
If you encounter unexpected errors or bugs, direct the user to report them at: https://github.com/aws-samples/sample-aws-pricing-calculator-mcp/issues`;cn.GET_SERVER_INFO="Get version and capability information about this MCP server."+$m;cn.SEARCH_SERVICES='Search AWS services available in the calculator. Returns service keys and names. Use this to find the correct service key before adding it to an estimate. Supports multiple comma-separated search terms in a single call (e.g. "Lambda, S3, API Gateway, CloudWatch"). Note: add_service also accepts display names (e.g. "AWS Lambda") directly, so searching is not always required if the service name is already known.';cn.GET_SERVICE_FIELDS='Get the input fields for one or more AWS services. Returns field IDs, types, labels, and valid options. Use this to discover what configuration a service accepts before adding it to an estimate. The field IDs returned here are the exact keys to use in add_service config. Accepts multiple comma-separated service keys. IMPORTANT: When duplicate fields exist with version suffixes (e.g. fieldName and fieldName_v2), ALWAYS use the highest version \u2014 it maps to the latest configuration path. Ignore lower versions. For curated services (status: verified or partial), the response also includes a `catalog` object with a known-working `minimalConfig`, required field hints with examples, and `traps[]` listing service-specific gotchas. Prefer using `minimalConfig` as a starting point for `add_service`. If the response carries `status: "redirect_to_parent"`, the service code you passed is a deprecated parent service code \u2014 re-call get_service_fields with one of the codes in `child_service_codes` and use that instead. If the response includes a `freeTierChoice` object, the service offers an AWS Free Tier template choice (e.g. AWS Lambda): you MUST ask the user whether to include or exclude the Free Tier, then pass the chosen template id as `estimateFor` on the add_service/build_estimate entry. For any Amazon RDS or Aurora engine (MySQL, PostgreSQL, MariaDB, Oracle, SQL Server, Db2, Aurora MySQL/PostgreSQL-Compatible \u2014 curated or not), the response includes a `pricingModelHint`: AWS Database Savings Plans are only sold on Gen 7+ instance families (m7g/r7g, m8g/r8g, m9g, ...) \u2014 T-class (t3, t4g) and Gen 6-or-older (m5, r5, m6, r6, ...) are NOT eligible at all \u2014 and only as a 1-year term (no 3-year option). The calculator does not refuse an ineligible instance or a 3-year term at save time. Pass this along to the user before setting TermType to "Database Savings Plans".';cn.CREATE_ESTIMATE="Create a new empty estimate. Returns an estimate ID to use with add_service and export_estimate.";cn.ADD_SERVICE=`Add one or more AWS services to an estimate. Accepts a single service or a JSON array of services in the "services" parameter.
|
|
108
108
|
|
|
@@ -166,7 +166,7 @@ Returns upfront_cost, monthly_cost, total_12_months_cost (derived as upfront + 1
|
|
|
166
166
|
|
|
167
167
|
SIDE EFFECT: pressing Update+Share saves a FRESH copy of the estimate under a NEW id, returned as priced_estimate_url. The original id is unchanged. (This is why the tool is not marked read-only.)
|
|
168
168
|
|
|
169
|
-
ON-DEMAND DEPENDENCY: this tool requires Playwright AND the Chromium browser binary, which are NOT installed by default (Chromium is a ~150MB download). The tool checks for them first and, when either is missing, returns cost_available:false with reason and the exact install_commands instead of failing. Do NOT install them silently \u2014 surface the commands and ask the user to confirm before running them, then retry.`+$m});var dC=_((qxe,Jle)=>{Jle.exports={name:"sample-aws-pricing-calculator-mcp",version:"1.3.7",bin:"dist/mcp-server.js",files:["dist/mcp-server.js","catalog/schema.json","catalog/services/*.json"],description:"MCP server for creating, reading, updating AWS Pricing Calculator estimates through natural language.",license:"MIT-0",main:"mcp-server.js",scripts:{test:"npm run validate-catalog && SKIP_NETWORK=1 node --test test/*.test.js","test:network":"npm run validate-catalog && node --test test/*.test.js","test:roundtrip":"node --test test/catalog-roundtrip.test.js",mcp:"node mcp-server.js","validate-catalog":"node scripts/validate-catalog.js","validate-catalog:cost":"node scripts/validate-verified-catalog.js",build:"esbuild mcp-server.js --bundle --platform=node --outfile=dist/mcp-server.js --format=cjs --minify --external:@aws-sdk/client-dynamodb --external:@aws-sdk/lib-dynamodb --external:playwright --external:playwright-core && node scripts/emit-bundle-contract.js && rm -f dist/aws-calculator.zip && zip dist/aws-calculator.zip mcp-server.js lib/aws/aws-client.js lib/aws/fetch-resilience.js lib/aws/estimate-builder.js lib/aws/ec2.js lib/dom-cost.js package.json"},dependencies:{"@modelcontextprotocol/sdk":"1.32.1",express:"5.2.1"},peerDependencies:{"@aws-sdk/client-dynamodb":">=3.700.0","@aws-sdk/lib-dynamodb":">=3.700.0"},peerDependenciesMeta:{"@aws-sdk/client-dynamodb":{optional:!0},"@aws-sdk/lib-dynamodb":{optional:!0}},devDependencies:{"@aws-sdk/client-dynamodb":"3.1046.0","@aws-sdk/lib-dynamodb":"3.1046.0",ajv:"8.20.0","ajv-formats":"3.0.1",esbuild:"0.28.2",playwright:"1.63.0"}}});var pC=_(fC=>{var Gle="x-hono-already-sent";Object.defineProperty(fC,"X_ALREADY_SENT",{enumerable:!0,get:function(){return Gle}})});var mC=_(Tu=>{Object.defineProperty(Tu,Symbol.toStringTag,{value:"Module"});var Kle=class{#e;constructor(e){this.#e=e,this.raw=e.raw,this.url=e.url?new URL(e.url):null,this.protocol=e.protocol??null}send(e,t){this.#e.send(e,t??{})}raw;binaryType="arraybuffer";get readyState(){return this.#e.readyState}url;protocol;close(e,t){this.#e.close(e,t)}},Wle=e=>new MessageEvent("message",{data:e}),Xle=e=>((...t)=>{if(typeof t[0]=="function"){let[r,i]=t;return async function(a,o){let s=await e(a,await r(a),i);if(s)return s;await o()}}else{let[r,i,n]=t;return(async()=>{let a=await e(r,i,n);if(!a)throw new Error("Failed to upgrade WebSocket");return a})()}});Tu.WSContext=Kle;Tu.createWSMessageEvent=Wle;Tu.defineWebSocketHelper=Xle});var BC=_(Mo=>{Object.defineProperty(Mo,Symbol.toStringTag,{value:"Module"});var Yle=pC(),B_=require("node:http"),Ei=require("node:http2"),hC=require("node:stream"),Qle=mC(),wr=class extends Error{constructor(e,t){super(e,t),this.name="RequestError"}},ede=new Set(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","server","user-agent"]),tde=/^[!#$%&'*+\-.^_`|~\dA-Za-z]+$/,xm=e=>e===9||e===10||e===13||e===32,gC=e=>{if(!xm(e.charCodeAt(0))&&!xm(e.charCodeAt(e.length-1)))return e;let t=0,r=e.length;for(;t<r&&xm(e.charCodeAt(t));)t++;for(;r>t&&xm(e.charCodeAt(r-1));)r--;return e.slice(t,r)},vC=/[\0\r\n]/,V_=globalThis.Headers,OC=(e,t=V_)=>{let r=new t;for(let i=0;i<e.length;i+=2){let n=e[i];n.startsWith(":")||r.append(n,e[i+1])}return r},H_=class{#e;#t;#n;#i;constructor(e){this.#e=e,e instanceof Ei.Http2ServerRequest&&(this.#t=e.rawHeaders.slice())}get#a(){return this.#t??=this.#e.rawHeaders.slice()}get#r(){return this.#n||(this.#n=OC(this.#a),this.#t=void 0),this.#n}#o(e){if(typeof e=="string"){if(!tde.test(e))throw new TypeError(`Invalid header name: ${e}`);return e.toLowerCase()}}#s(e){let t=this.#e instanceof Ei.Http2ServerRequest?void 0:this.#e.headers;if(!t||ede.has(e)||e==="set-cookie"||e==="__proto__")return;if(!Object.hasOwn(t,e))return null;let r=t[e];if(typeof r=="string"){let i=gC(r);return vC.test(i)?void 0:i}}#c(e,t){let r=t==="cookie"?"; ":", ",i=null;for(let n=0;n<e.length;n+=2){let a=e[n];if(a.length===t.length&&a.toLowerCase()===t){let o=gC(e[n+1]);if(vC.test(o)){this.#i=!0;return}i=i===null?o:i+r+o}}return i}append(e,t){this.#r.append(e,t)}delete(e){this.#r.delete(e)}get(e){let t=this.#o(e);if(t&&!this.#n&&!this.#i){let r=this.#s(t);if(r!==void 0)return r;let i=this.#c(this.#a,t);if(i!==void 0)return i}return this.#r.get(e)}has(e){let t=this.#o(e);if(t&&!this.#n&&!this.#i){let r=this.#s(t);if(r!==void 0)return r!==null;let i=this.#c(this.#a,t);if(i!==void 0)return i!==null}return this.#r.has(e)}set(e,t){this.#r.set(e,t)}getSetCookie(){return this.#r.getSetCookie()}keys(){return this.#r.keys()}values(){return this.#r.values()}entries(){return this.#r.entries()}forEach(e,t){this.#r.forEach((r,i)=>{e.call(t,r,i,this)})}[Symbol.iterator](){return this.entries()}};Object.defineProperty(H_.prototype,Symbol.for("nodejs.util.inspect.custom"),{value:function(e,t,r){return`Headers (lightweight) ${r(Object.fromEntries(this),{...t,depth:e==null?null:e-1})}`}});Object.setPrototypeOf(H_.prototype,V_.prototype);var PC=e=>globalThis.Headers===V_?new H_(e):OC(e.rawHeaders,globalThis.Headers),rde=/^\/[!#$&-;=?-\[\]_a-z~]*$/,nde=/\/\.\.?(?:[/?#]|$)/,ide=/^[a-z0-9._-]+(?::(?:[1-5]\d{3,4}|[6-9]\d{3}))?$/,Pm=e=>{let t=e.indexOf("\\");if(t!==-1){let r=e.indexOf("?");if(r===-1||t<r)throw new wr("Backslash in request path")}},IC=(e,t,r)=>{let i=`${e}://${t}${r}`;if(ide.test(t)){if(r.length===0)return i+"/";if(r.charCodeAt(0)!==47)throw new wr("Invalid URL");return!rde.test(r)||nde.test(r)?(Pm(r),new URL(i).href):i}else{Pm(r);let n=new URL(i);if(n.hostname.length!==t.length&&n.hostname!==(t.includes(":")?t.replace(/:\d+$/,""):t).toLowerCase())throw new wr("Invalid host header");return n.href}},ade=e=>e instanceof wr?e:new wr(e.message,{cause:e}),ode=global.Request,Hs=class extends ode{constructor(e,t){if(typeof e=="object"&&Ma in e){let r=t!==void 0&&"body"in t&&t.body!=null;if(e[ta]&&!r)throw new TypeError("Cannot construct a Request with a Request object that has already been used.");e=e[Ma]()}typeof t?.body?.getReader<"u"&&(t.duplex??="half"),super(e,t)}},jC=Symbol("wrapBodyStream"),sde=new Set(["latin1","binary","hex","base64","base64url"]),cde=e=>e===null||sde.has(e),M_=Symbol("bodyBufferedBeforeDisconnect"),z_=Symbol("bodyBufferedLengthBeforeDisconnect"),EC=(e,t)=>Buffer.isBuffer(e)?e:Buffer.from(e,t??"utf8"),J_=e=>!(e instanceof Ei.Http2ServerRequest)&&!!e.complete&&!!e.readableAborted&&typeof e.read=="function"&&cde(e.readableEncoding),yC=e=>{if(e.readableDidRead||!J_(e))return;let t=e;t[z_]??=e.readableLength},Im=(e,t)=>{if(e.readableDidRead&&!t||!J_(e))return;let r=e;if(r[M_]!==void 0)return r[M_];let i,n=e.errored;if(n&&n.code!=="ECONNRESET")i=n;else if(r[z_]!==void 0&&e.readableLength!==r[z_])i=jm();else{let a=t??[],o=e.read();o!==null&&a.push(EC(o,e.readableEncoding));let s=a.length===1?a[0]:Buffer.concat(a);i=s;let c=e.headers["content-length"];if(typeof c=="string"&&/^\d+$/.test(c)){let u=Number(c);Number.isSafeInteger(u)&&s.length!==u&&(i=jm())}}return r[M_]=i,i},bC=(e,t)=>{if(t instanceof Error){e.error(t);return}t.length>0&&e.enqueue(t),e.close()},ude=(e,t,r,i,n)=>{let a={method:e,headers:r,signal:n.signal};if(e==="TRACE"){a.method="GET";let o=new Hs(t,a);return Object.defineProperty(o,"method",{get(){return"TRACE"}}),o}if(!(e==="GET"||e==="HEAD"))if("rawBody"in i&&i.rawBody instanceof Buffer)a.body=new ReadableStream({start(o){o.enqueue(i.rawBody),o.close()}});else if(i[jC]){let o;a.body=new ReadableStream({async pull(s){try{if(!o){let l=Im(i);if(l!==void 0){bC(s,l);return}}o||=hC.Readable.toWeb(i).getReader();let{done:c,value:u}=await o.read();c?s.close():s.enqueue(u)}catch(c){s.error(c)}}})}else{let o=Im(i);o!==void 0?a.body=new ReadableStream({start(s){bC(s,o)}}):a.body=hC.Readable.toWeb(i)}return new Hs(t,a)},Ma=Symbol("getRequestCache"),Qi=Symbol("requestCache"),Js=Symbol("incomingKey"),Au=Symbol("urlKey"),TC=Symbol("methodKey"),kC=Symbol("headersKey"),ku=Symbol("abortControllerKey"),Z_=Symbol("getAbortController"),q_=Symbol("abortRequest"),Ra=Symbol("bodyBuffer"),Om=Symbol("bodyReadPromise"),ta=Symbol("bodyConsumedDirectly"),_C=Symbol("bodyLockReader"),Cu=Symbol("abortReason"),jm=()=>new TypeError("Body is unusable"),Du=()=>Promise.reject(jm()),lde=new TextDecoder,dde=e=>{if(e[ta])return Du();e[ta]=!0},fde=e=>e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),pde=e=>(e[kC]||=PC(e[Js])).get("content-type")||"",mde=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,hde=e=>{if(typeof e!="string"||e.length===0)return"GET";switch(e){case"DELETE":case"GET":case"HEAD":case"OPTIONS":case"PATCH":case"POST":case"PUT":case"QUERY":return e}let t=e.toUpperCase();switch(t){case"DELETE":case"GET":case"HEAD":case"OPTIONS":case"POST":case"PUT":return t;default:return e}},gde=e=>{if(!mde.test(e))return new TypeError(`'${e}' is not a valid HTTP method.`);let t=e.toUpperCase();if(t==="CONNECT"||t==="TRACK"||t==="TRACE"&&e!=="TRACE")return new TypeError(`'${e}' HTTP method is unsupported.`)},G_=(e,t,r)=>{if(e[ta])return Du();let i=e.method;if(i==="GET"||i==="HEAD")return e[Ma]()[t]();let n=gde(i);if(n)return Promise.reject(n);if(e[Qi]&&i!=="TRACE")return e[Qi][t]();let a=dde(e);if(a)return a;let o=vde(e);if(o){let s=Promise.resolve(r(o,e));return e[Ra]=void 0,s}return yde(e).then(s=>{let c=r(s,e);return e[Ra]=void 0,c})},vde=e=>{let t=e[Js];if("rawBody"in t&&t.rawBody instanceof Buffer)return t.rawBody},wC=(e,t)=>{if(t.errored)return t.errored;let r=e[Cu];return r!==void 0?r instanceof Error?r:new Error(String(r)):new Error("Client connection prematurely closed.")},yde=e=>{if(e[Ra])return Promise.resolve(e[Ra]);if(e[Om])return e[Om];let t=e[Js];if(t.readableDidRead)return Du();let r=Im(t);if(r!==void 0)return r instanceof Error?Promise.reject(r):(e[Ra]=r,Promise.resolve(r));let i=new Promise((n,a)=>{let o=[],s=!1,c=g=>{s||(s=!0,m(),g())},u=g=>{let w=t.errored??g;return!J_(t)||w&&w.code!=="ECONNRESET"?!1:(c(()=>{let $=Im(t,o);$ instanceof Error?a($):$===void 0?a(g??wC(e,t)):(e[Ra]=$,n($))}),!0)},l=g=>{o.push(EC(g,t.readableEncoding))},d=()=>{c(()=>{let g=o.length===1?o[0]:Buffer.concat(o);e[Ra]=g,n(g)})},f=g=>{u(g)||c(()=>{a(g)})},p=()=>{if(t.readableEnded){d();return}u()||c(()=>{a(wC(e,t))})},m=()=>{t.off("data",l),t.off("end",d),t.off("error",f),t.off("close",p),e[Om]=void 0};t.on("data",l),t.on("end",d),t.on("error",f),t.on("close",p),queueMicrotask(()=>{s||(t.readableEnded?d():t.errored?f(t.errored):t.destroyed&&p())})});return e[Om]=i,i},ki={get method(){return this[TC]},get url(){return this[Au]},get headers(){return this[kC]||=PC(this[Js])},[q_](e){this[Cu]===void 0&&(this[Cu]=e);let t=this[ku];t&&!t.signal.aborted&&t.abort(e)},[Z_](){return this[ku]||=new AbortController,this[Cu]!==void 0&&!this[ku].signal.aborted&&this[ku].abort(this[Cu]),this[ku]},[Ma](){let e=this[Z_]();if(this[Qi])return this[Qi];let t=this.method;if(this[ta]&&!(t==="GET"||t==="HEAD")){this[Ra]=void 0;let r={method:t==="TRACE"?"GET":t,headers:this.headers,signal:e.signal};t!=="TRACE"&&(r.body=new ReadableStream({start(n){n.close()}}),r.duplex="half");let i=new Hs(this[Au],r);return t==="TRACE"&&Object.defineProperty(i,"method",{get(){return"TRACE"}}),this[Qi]=i}return this[Qi]=ude(this.method,this[Au],this.headers,this[Js],e)},get body(){if(!this[ta])return this[Ma]().body;let e=this[Ma]();return!this[_C]&&e.body&&(this[_C]=e.body.getReader()),e.body},get bodyUsed(){return this[ta]?!0:this[Qi]?this[Qi].bodyUsed:!1}};Object.defineProperty(ki,"signal",{get(){return this[Z_]().signal}});["cache","credentials","destination","integrity","mode","redirect","referrer","referrerPolicy","keepalive"].forEach(e=>{Object.defineProperty(ki,e,{get(){return this[Ma]()[e]}})});["clone","formData"].forEach(e=>{Object.defineProperty(ki,e,{value:function(){if(this[ta]){if(e==="clone")throw jm();return Du()}return this[Ma]()[e]()}})});Object.defineProperty(ki,"text",{value:function(){return G_(this,"text",e=>lde.decode(e))}});Object.defineProperty(ki,"arrayBuffer",{value:function(){return G_(this,"arrayBuffer",e=>fde(e))}});Object.defineProperty(ki,"blob",{value:function(){return G_(this,"blob",(e,t)=>{let r=pde(t),i=r?{headers:{"content-type":r}}:void 0;return new Response(e,i).blob()})}});Object.defineProperty(ki,"json",{value:function(){return this[ta]?Du():this.text().then(JSON.parse)}});Object.defineProperty(ki,Symbol.for("nodejs.util.inspect.custom"),{value:function(e,t,r){return`Request (lightweight) ${r({method:this.method,url:this.url,headers:this.headers,nativeRequest:this[Qi]},{...t,depth:e==null?null:e-1})}`}});Object.setPrototypeOf(ki,Hs.prototype);var bde=(e,t)=>{let r=Object.create(ki);r[Js]=e,r[TC]=hde(e.method);let i=e.url||"";if(i[0]!=="/"&&(i.startsWith("http://")||i.startsWith("https://"))){if(e instanceof Ei.Http2ServerRequest)throw new wr("Absolute URL for :path is not allowed in HTTP/2");try{Pm(i),r[Au]=new URL(i).href}catch(o){throw new wr("Invalid absolute URL",{cause:o})}return r}let n=(e instanceof Ei.Http2ServerRequest?e.authority:e.headers.host)||t;if(!n)throw new wr("Missing host header");let a;if(e instanceof Ei.Http2ServerRequest){if(a=e.scheme,!(a==="http"||a==="https"))throw new wr("Unsupported scheme")}else a=e.socket&&e.socket.encrypted?"https":"http";try{r[Au]=IC(a,n,i)}catch(o){throw o instanceof wr?o:new wr("Invalid URL",{cause:o})}return r},Ro="text/plain; charset=UTF-8",U_=Symbol("responseCache"),Vs=Symbol("getResponseCache"),ea=Symbol("cache"),Em=global.Response,Ti=class CC{#e;#t;[Vs](){let t=this[ea],r=t&&t[2]instanceof Headers?t[2]:void 0;return delete this[ea],this[U_]||=new Em(this.#e,r?{status:this.#t?.status,statusText:this.#t?.statusText,headers:r}:this.#t)}constructor(t,r){let i;if(this.#e=t,r instanceof Em){let n=r[U_];if(n){this.#t=n,this[Vs]();return}this.#t=r instanceof CC?r.#t:r,i=new Headers(r.headers)}else this.#t=r;(t==null||typeof t=="string"||typeof t?.getReader<"u"||t instanceof Blob||t instanceof Uint8Array)&&(this[ea]=[r?.status||200,t??null,i||r?.headers])}get headers(){let t=this[ea];return t?(t[2]instanceof Headers||(t[2]=new Headers(t[2]||(t[1]===null?void 0:{"content-type":Ro}))),t[2]):this[Vs]().headers}get status(){return this[ea]?.[0]??this[Vs]().status}get ok(){let t=this.status;return t>=200&&t<300}};["body","bodyUsed","redirected","statusText","trailers","type","url"].forEach(e=>{Object.defineProperty(Ti.prototype,e,{get(){return this[Vs]()[e]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach(e=>{Object.defineProperty(Ti.prototype,e,{value:function(){return this[Vs]()[e]()}})});Object.defineProperty(Ti.prototype,Symbol.for("nodejs.util.inspect.custom"),{value:function(e,t,r){return`Response (lightweight) ${r({status:this.status,headers:this.headers,ok:this.ok,nativeResponse:this[U_]},{...t,depth:e==null?null:e-1})}`}});Object.setPrototypeOf(Ti,Em);Object.setPrototypeOf(Ti.prototype,Em.prototype);var _de=/^https?:\/\/[!#-;=?-[\]_a-z~A-Z]+$/,wde=e=>e instanceof URL?e.href:_de.test(e)?e:new URL(e).href,Sde=new Set([301,302,303,307,308]);Object.defineProperty(Ti,"redirect",{value:function(t,r=302){if(!Sde.has(r))throw new RangeError("Invalid status code");return new Ti(null,{status:r,headers:{location:wde(t)}})},writable:!0,configurable:!0});Object.defineProperty(Ti,"json",{value:function(t,r){let i=JSON.stringify(t);if(i===void 0)throw new TypeError("The data is not JSON serializable");let n=r?.headers,a;return n?(a=new Headers(n),a.has("content-type")||a.set("content-type","application/json")):a={"content-type":"application/json"},new Ti(i,{status:r?.status??200,statusText:r?.statusText,headers:a})},writable:!0,configurable:!0});async function $de(e){return Promise.race([e,Promise.resolve().then(()=>Promise.resolve(void 0))])}function AC(e,t,r){let i=s=>{e.cancel(s).catch(()=>{})};return t.on("close",i),t.on("error",i),(r??e.read()).then(o,n),e.closed.finally(()=>{t.off("close",i),t.off("error",i)});function n(s){s&&t.destroy(s)}function a(){e.read().then(o,n)}function o({done:s,value:c}){try{if(s)t.end();else if(!t.write(c))t.once("drain",a);else return e.read().then(o,n)}catch(u){n(u)}}}function SC(e,t){if(e.locked)throw new TypeError("ReadableStream is locked.");return t.destroyed?void 0:AC(e.getReader(),t)}var L_=(e,t)=>{let r={};if(e instanceof Headers||(e=new Headers(e??void 0)),e.has("set-cookie")){let i=[];for(let[n,a]of e)n==="set-cookie"?i.push(a):r[n]=a;i.length>0&&(r["set-cookie"]=i)}else for(let[i,n]of e)r[i]=n;return t&&(r["content-type"]??=t),r},Tm=Symbol("outgoingEnded"),$C=Symbol("incomingDraining"),xde=500,Ode=64*1024*1024,DC=e=>{let t=e;if(e.destroyed||t[$C])return;if(t[$C]=!0,e instanceof Ei.Http2ServerRequest){try{e.stream?.close?.(Ei.constants.NGHTTP2_NO_ERROR)}catch{}return}let r=0,i=()=>{clearTimeout(a),e.off("data",o),e.off("end",i),e.off("error",i)},n=()=>{i();let s=e.socket;s&&!s.destroyed&&(typeof s.destroySoon=="function"?s.destroySoon():typeof s.destroy=="function"&&s.destroy())},a=setTimeout(n,xde);a.unref?.();let o=s=>{r+=s.length,r>Ode&&n()};e.on("data",o),e.on("end",i),e.on("error",i),e.resume()},Pde=(e,t,r,i)=>()=>{t.errored?(yC(t),e[q_](t.errored.toString())):(!r.writableFinished||t instanceof Ei.Http2ServerRequest&&t.aborted)&&(yC(t),e[q_]("Client connection prematurely closed.")),i&&!t.readableEnded&&setTimeout(()=>{t.readableEnded||setTimeout(()=>{DC(t)})})},Ide=e=>{if(!(ea in e))return!1;let t=e[ea][1];return t===null||typeof t=="string"||t instanceof Uint8Array},jde=()=>new Response(null,{status:400}),RC=e=>new Response(null,{status:e instanceof Error&&(e.name==="TimeoutError"||e.constructor.name==="TimeoutError")?504:500}),km=(e,t)=>{let r=e instanceof Error?e:new Error("unknown error",{cause:e});r.code==="ERR_STREAM_PREMATURE_CLOSE"?console.info("The user aborted a request."):(console.error(e),t.headersSent||(t instanceof B_.ServerResponse&&(t._contentLength=null),t.writeHead(500,{"Content-Type":"text/plain"})),t.end(`Error: ${r.message}`),t.destroy(r))},F_=e=>{"flushHeaders"in e&&e.writable&&e.flushHeaders()},MC=(e,t,r)=>{let i=e;return i._contentLength===null&&i._hasBody&&i.useChunkedEncodingByDefault&&!i._removedContLen&&t>=200&&t!==204&&t!==304&&!e.hasHeader("content-length")&&!e.hasHeader("transfer-encoding")&&!e.hasHeader("trailer")?(i._contentLength=r,!0):!1},N_=(e,t,r)=>{MC(e,t,r)?e.writeHead(t,{"Content-Type":Ro}):e.writeHead(t,{"Content-Type":Ro,"Content-Length":r})},NC=async(e,t)=>{let[r,i,n]=e[ea];if(!n){i===null?(t.writeHead(r),t.end()):typeof i=="string"?(N_(t,r,Buffer.byteLength(i)),t.end(i)):i instanceof Uint8Array?(N_(t,r,i.byteLength),t.end(i)):i instanceof Blob?(N_(t,r,i.size),t.end(new Uint8Array(await i.arrayBuffer()))):(t.writeHead(r,{"Content-Type":Ro}),F_(t),await SC(i,t)?.catch(c=>km(c,t))),t[Tm]?.();return}let a=!1,o=!1,s=!0;if(n instanceof Headers)a=n.has("content-length"),n=L_(n,i===null?void 0:Ro);else if(Array.isArray(n)){let c=new Headers(n);a=c.has("content-length"),n=L_(c,i===null?void 0:Ro)}else{o=!0;for(let c in n){if(c.length===14&&c.toLowerCase()==="content-length"){a=!0;break}(c.length===17&&c.toLowerCase()==="transfer-encoding"||c.length===7&&c.toLowerCase()==="trailer")&&(s=!1)}}if(!a){let c;typeof i=="string"?c=Buffer.byteLength(i):i instanceof Uint8Array?c=i.byteLength:i instanceof Blob&&(c=i.size),c!==void 0&&(!o||!s||!MC(t,r,c))&&(o&&(n={...n}),n["Content-Length"]=c)}t.writeHead(r,n),i==null?t.end():typeof i=="string"||i instanceof Uint8Array?t.end(i):i instanceof Blob?t.end(new Uint8Array(await i.arrayBuffer())):(F_(t),await SC(i,t)?.catch(c=>km(c,t))),t[Tm]?.()},zC=e=>typeof e.then=="function",Ede=async(e,t,r={})=>{if(zC(e))if(r.errorHandler)try{e=await e}catch(n){let a=await r.errorHandler(n);if(!a)return;e=a}else e=await e.catch(RC);if(ea in e)return NC(e,t);let i=L_(e.headers,e.body===null?void 0:Ro);if(e.body){let n=e.body.getReader(),a=[],o=!1,s;if(i["transfer-encoding"]!=="chunked"){let c=2;for(let u=0;u<c;u++){s||=n.read();let l=await $de(s).catch(d=>{console.error(d),o=!0});if(!l){if(u===1){await new Promise(d=>setTimeout(d)),c=3;continue}break}if(s=void 0,l.value&&a.push(l.value),l.done){o=!0;break}}o&&!("content-length"in i)&&(i["content-length"]=a.reduce((u,l)=>u+l.length,0))}t.writeHead(e.status,i),a.forEach(c=>{t.write(c)}),o?t.end():(a.length===0&&F_(t),await AC(n,t,s))}else i[Yle.X_ALREADY_SENT]||(t.writeHead(e.status,i),t.end());t[Tm]?.()},ZC=(e,t={})=>{let r=t.autoCleanupIncoming??!0;return t.overrideGlobalObjects!==!1&&global.Request!==Hs&&(Object.defineProperty(global,"Request",{value:Hs}),Object.defineProperty(global,"Response",{value:Ti})),async(i,n)=>{let a,o,s=!1,c=!1,u=()=>{!o||c||(c=!0,n.on("close",Pde(o,i,n,s)))};try{if(o=bde(i,t.hostname),s=r&&!(i.method==="GET"||i.method==="HEAD"),s&&(i[jC]=!0,i instanceof Ei.Http2ServerRequest&&(n[Tm]=()=>{i.readableEnded||setTimeout(()=>{i.readableEnded||setTimeout(()=>{i.destroy(),n.destroy()})})})),a=e(o,{incoming:i,outgoing:n}),!zC(a)&&Ide(a))return s&&!i.readableEnded&&n.once("finish",()=>{i.readableEnded||DC(i)}),NC(a,n);u()}catch(l){if(a)return km(l,n);if(t.errorHandler){if(u(),a=await t.errorHandler(o?l:ade(l)),!a)return}else o?a=RC(l):a=jde()}try{return await Ede(a,n,t)}catch(l){return km(l,n)}}},Tde=globalThis.CloseEvent??class extends Event{#e;constructor(e,t={}){super(e,t),this.#e=t}get wasClean(){return this.#e.wasClean??!1}get code(){return this.#e.code??0}get reason(){return this.#e.reason??""}},kde=globalThis.ErrorEvent??class extends Event{#e;constructor(e,t={}){super(e,t),this.#e=t}get message(){return this.#e.message??""}get filename(){return this.#e.filename??""}get lineno(){return this.#e.lineno??0}get colno(){return this.#e.colno??0}get error(){return this.#e.error??null}},Cde=()=>Symbol("connection"),qC=Symbol("CONNECTION_SYMBOL_KEY"),UC=Symbol("WAIT_FOR_WEBSOCKET_SYMBOL"),Ade=new Set(["connection","content-length","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","sec-websocket-accept","sec-websocket-extensions","sec-websocket-protocol"]),LC=(e,t)=>{t&&t.forEach((r,i)=>{Ade.has(i.toLowerCase())||e.push(`${i}: ${r}`)})},xC=(e,t,r)=>{if(e.destroyed)return;let i=["Connection: close","Content-Length: 0"];LC(i,r),e.end(`HTTP/1.1 ${t.toString()} ${B_.STATUS_CODES[t]??""}\r
|
|
169
|
+
ON-DEMAND DEPENDENCY: this tool requires Playwright AND the Chromium browser binary, which are NOT installed by default (Chromium is a ~150MB download). The tool checks for them first and, when either is missing, returns cost_available:false with reason and the exact install_commands instead of failing. Do NOT install them silently \u2014 surface the commands and ask the user to confirm before running them, then retry.`+$m});var dC=_((qxe,Jle)=>{Jle.exports={name:"sample-aws-pricing-calculator-mcp",version:"1.3.8",bin:"dist/mcp-server.js",files:["dist/mcp-server.js","catalog/schema.json","catalog/services/*.json"],description:"MCP server for creating, reading, updating AWS Pricing Calculator estimates through natural language.",license:"MIT-0",main:"mcp-server.js",scripts:{test:"npm run validate-catalog && SKIP_NETWORK=1 node --test test/*.test.js","test:network":"npm run validate-catalog && node --test test/*.test.js","test:roundtrip":"node --test test/catalog-roundtrip.test.js",mcp:"node mcp-server.js","validate-catalog":"node scripts/validate-catalog.js","validate-catalog:cost":"node scripts/validate-verified-catalog.js",build:"esbuild mcp-server.js --bundle --platform=node --outfile=dist/mcp-server.js --format=cjs --minify --external:@aws-sdk/client-dynamodb --external:@aws-sdk/lib-dynamodb --external:playwright --external:playwright-core && node scripts/emit-bundle-contract.js && rm -f dist/aws-calculator.zip && zip dist/aws-calculator.zip mcp-server.js lib/aws/aws-client.js lib/aws/fetch-resilience.js lib/aws/estimate-builder.js lib/aws/ec2.js lib/dom-cost.js package.json"},dependencies:{"@modelcontextprotocol/sdk":"1.32.1",express:"5.2.1"},peerDependencies:{"@aws-sdk/client-dynamodb":">=3.700.0","@aws-sdk/lib-dynamodb":">=3.700.0"},peerDependenciesMeta:{"@aws-sdk/client-dynamodb":{optional:!0},"@aws-sdk/lib-dynamodb":{optional:!0}},devDependencies:{"@aws-sdk/client-dynamodb":"3.1046.0","@aws-sdk/lib-dynamodb":"3.1046.0",ajv:"8.20.0","ajv-formats":"3.0.1",esbuild:"0.28.2",playwright:"1.63.0"}}});var pC=_(fC=>{var Gle="x-hono-already-sent";Object.defineProperty(fC,"X_ALREADY_SENT",{enumerable:!0,get:function(){return Gle}})});var mC=_(Tu=>{Object.defineProperty(Tu,Symbol.toStringTag,{value:"Module"});var Kle=class{#e;constructor(e){this.#e=e,this.raw=e.raw,this.url=e.url?new URL(e.url):null,this.protocol=e.protocol??null}send(e,t){this.#e.send(e,t??{})}raw;binaryType="arraybuffer";get readyState(){return this.#e.readyState}url;protocol;close(e,t){this.#e.close(e,t)}},Wle=e=>new MessageEvent("message",{data:e}),Xle=e=>((...t)=>{if(typeof t[0]=="function"){let[r,i]=t;return async function(a,o){let s=await e(a,await r(a),i);if(s)return s;await o()}}else{let[r,i,n]=t;return(async()=>{let a=await e(r,i,n);if(!a)throw new Error("Failed to upgrade WebSocket");return a})()}});Tu.WSContext=Kle;Tu.createWSMessageEvent=Wle;Tu.defineWebSocketHelper=Xle});var BC=_(Mo=>{Object.defineProperty(Mo,Symbol.toStringTag,{value:"Module"});var Yle=pC(),B_=require("node:http"),Ei=require("node:http2"),hC=require("node:stream"),Qle=mC(),wr=class extends Error{constructor(e,t){super(e,t),this.name="RequestError"}},ede=new Set(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","server","user-agent"]),tde=/^[!#$%&'*+\-.^_`|~\dA-Za-z]+$/,xm=e=>e===9||e===10||e===13||e===32,gC=e=>{if(!xm(e.charCodeAt(0))&&!xm(e.charCodeAt(e.length-1)))return e;let t=0,r=e.length;for(;t<r&&xm(e.charCodeAt(t));)t++;for(;r>t&&xm(e.charCodeAt(r-1));)r--;return e.slice(t,r)},vC=/[\0\r\n]/,V_=globalThis.Headers,OC=(e,t=V_)=>{let r=new t;for(let i=0;i<e.length;i+=2){let n=e[i];n.startsWith(":")||r.append(n,e[i+1])}return r},H_=class{#e;#t;#n;#i;constructor(e){this.#e=e,e instanceof Ei.Http2ServerRequest&&(this.#t=e.rawHeaders.slice())}get#a(){return this.#t??=this.#e.rawHeaders.slice()}get#r(){return this.#n||(this.#n=OC(this.#a),this.#t=void 0),this.#n}#o(e){if(typeof e=="string"){if(!tde.test(e))throw new TypeError(`Invalid header name: ${e}`);return e.toLowerCase()}}#s(e){let t=this.#e instanceof Ei.Http2ServerRequest?void 0:this.#e.headers;if(!t||ede.has(e)||e==="set-cookie"||e==="__proto__")return;if(!Object.hasOwn(t,e))return null;let r=t[e];if(typeof r=="string"){let i=gC(r);return vC.test(i)?void 0:i}}#c(e,t){let r=t==="cookie"?"; ":", ",i=null;for(let n=0;n<e.length;n+=2){let a=e[n];if(a.length===t.length&&a.toLowerCase()===t){let o=gC(e[n+1]);if(vC.test(o)){this.#i=!0;return}i=i===null?o:i+r+o}}return i}append(e,t){this.#r.append(e,t)}delete(e){this.#r.delete(e)}get(e){let t=this.#o(e);if(t&&!this.#n&&!this.#i){let r=this.#s(t);if(r!==void 0)return r;let i=this.#c(this.#a,t);if(i!==void 0)return i}return this.#r.get(e)}has(e){let t=this.#o(e);if(t&&!this.#n&&!this.#i){let r=this.#s(t);if(r!==void 0)return r!==null;let i=this.#c(this.#a,t);if(i!==void 0)return i!==null}return this.#r.has(e)}set(e,t){this.#r.set(e,t)}getSetCookie(){return this.#r.getSetCookie()}keys(){return this.#r.keys()}values(){return this.#r.values()}entries(){return this.#r.entries()}forEach(e,t){this.#r.forEach((r,i)=>{e.call(t,r,i,this)})}[Symbol.iterator](){return this.entries()}};Object.defineProperty(H_.prototype,Symbol.for("nodejs.util.inspect.custom"),{value:function(e,t,r){return`Headers (lightweight) ${r(Object.fromEntries(this),{...t,depth:e==null?null:e-1})}`}});Object.setPrototypeOf(H_.prototype,V_.prototype);var PC=e=>globalThis.Headers===V_?new H_(e):OC(e.rawHeaders,globalThis.Headers),rde=/^\/[!#$&-;=?-\[\]_a-z~]*$/,nde=/\/\.\.?(?:[/?#]|$)/,ide=/^[a-z0-9._-]+(?::(?:[1-5]\d{3,4}|[6-9]\d{3}))?$/,Pm=e=>{let t=e.indexOf("\\");if(t!==-1){let r=e.indexOf("?");if(r===-1||t<r)throw new wr("Backslash in request path")}},IC=(e,t,r)=>{let i=`${e}://${t}${r}`;if(ide.test(t)){if(r.length===0)return i+"/";if(r.charCodeAt(0)!==47)throw new wr("Invalid URL");return!rde.test(r)||nde.test(r)?(Pm(r),new URL(i).href):i}else{Pm(r);let n=new URL(i);if(n.hostname.length!==t.length&&n.hostname!==(t.includes(":")?t.replace(/:\d+$/,""):t).toLowerCase())throw new wr("Invalid host header");return n.href}},ade=e=>e instanceof wr?e:new wr(e.message,{cause:e}),ode=global.Request,Hs=class extends ode{constructor(e,t){if(typeof e=="object"&&Ma in e){let r=t!==void 0&&"body"in t&&t.body!=null;if(e[ta]&&!r)throw new TypeError("Cannot construct a Request with a Request object that has already been used.");e=e[Ma]()}typeof t?.body?.getReader<"u"&&(t.duplex??="half"),super(e,t)}},jC=Symbol("wrapBodyStream"),sde=new Set(["latin1","binary","hex","base64","base64url"]),cde=e=>e===null||sde.has(e),M_=Symbol("bodyBufferedBeforeDisconnect"),z_=Symbol("bodyBufferedLengthBeforeDisconnect"),EC=(e,t)=>Buffer.isBuffer(e)?e:Buffer.from(e,t??"utf8"),J_=e=>!(e instanceof Ei.Http2ServerRequest)&&!!e.complete&&!!e.readableAborted&&typeof e.read=="function"&&cde(e.readableEncoding),yC=e=>{if(e.readableDidRead||!J_(e))return;let t=e;t[z_]??=e.readableLength},Im=(e,t)=>{if(e.readableDidRead&&!t||!J_(e))return;let r=e;if(r[M_]!==void 0)return r[M_];let i,n=e.errored;if(n&&n.code!=="ECONNRESET")i=n;else if(r[z_]!==void 0&&e.readableLength!==r[z_])i=jm();else{let a=t??[],o=e.read();o!==null&&a.push(EC(o,e.readableEncoding));let s=a.length===1?a[0]:Buffer.concat(a);i=s;let c=e.headers["content-length"];if(typeof c=="string"&&/^\d+$/.test(c)){let u=Number(c);Number.isSafeInteger(u)&&s.length!==u&&(i=jm())}}return r[M_]=i,i},bC=(e,t)=>{if(t instanceof Error){e.error(t);return}t.length>0&&e.enqueue(t),e.close()},ude=(e,t,r,i,n)=>{let a={method:e,headers:r,signal:n.signal};if(e==="TRACE"){a.method="GET";let o=new Hs(t,a);return Object.defineProperty(o,"method",{get(){return"TRACE"}}),o}if(!(e==="GET"||e==="HEAD"))if("rawBody"in i&&i.rawBody instanceof Buffer)a.body=new ReadableStream({start(o){o.enqueue(i.rawBody),o.close()}});else if(i[jC]){let o;a.body=new ReadableStream({async pull(s){try{if(!o){let l=Im(i);if(l!==void 0){bC(s,l);return}}o||=hC.Readable.toWeb(i).getReader();let{done:c,value:u}=await o.read();c?s.close():s.enqueue(u)}catch(c){s.error(c)}}})}else{let o=Im(i);o!==void 0?a.body=new ReadableStream({start(s){bC(s,o)}}):a.body=hC.Readable.toWeb(i)}return new Hs(t,a)},Ma=Symbol("getRequestCache"),Qi=Symbol("requestCache"),Js=Symbol("incomingKey"),Au=Symbol("urlKey"),TC=Symbol("methodKey"),kC=Symbol("headersKey"),ku=Symbol("abortControllerKey"),Z_=Symbol("getAbortController"),q_=Symbol("abortRequest"),Ra=Symbol("bodyBuffer"),Om=Symbol("bodyReadPromise"),ta=Symbol("bodyConsumedDirectly"),_C=Symbol("bodyLockReader"),Cu=Symbol("abortReason"),jm=()=>new TypeError("Body is unusable"),Du=()=>Promise.reject(jm()),lde=new TextDecoder,dde=e=>{if(e[ta])return Du();e[ta]=!0},fde=e=>e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength),pde=e=>(e[kC]||=PC(e[Js])).get("content-type")||"",mde=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,hde=e=>{if(typeof e!="string"||e.length===0)return"GET";switch(e){case"DELETE":case"GET":case"HEAD":case"OPTIONS":case"PATCH":case"POST":case"PUT":case"QUERY":return e}let t=e.toUpperCase();switch(t){case"DELETE":case"GET":case"HEAD":case"OPTIONS":case"POST":case"PUT":return t;default:return e}},gde=e=>{if(!mde.test(e))return new TypeError(`'${e}' is not a valid HTTP method.`);let t=e.toUpperCase();if(t==="CONNECT"||t==="TRACK"||t==="TRACE"&&e!=="TRACE")return new TypeError(`'${e}' HTTP method is unsupported.`)},G_=(e,t,r)=>{if(e[ta])return Du();let i=e.method;if(i==="GET"||i==="HEAD")return e[Ma]()[t]();let n=gde(i);if(n)return Promise.reject(n);if(e[Qi]&&i!=="TRACE")return e[Qi][t]();let a=dde(e);if(a)return a;let o=vde(e);if(o){let s=Promise.resolve(r(o,e));return e[Ra]=void 0,s}return yde(e).then(s=>{let c=r(s,e);return e[Ra]=void 0,c})},vde=e=>{let t=e[Js];if("rawBody"in t&&t.rawBody instanceof Buffer)return t.rawBody},wC=(e,t)=>{if(t.errored)return t.errored;let r=e[Cu];return r!==void 0?r instanceof Error?r:new Error(String(r)):new Error("Client connection prematurely closed.")},yde=e=>{if(e[Ra])return Promise.resolve(e[Ra]);if(e[Om])return e[Om];let t=e[Js];if(t.readableDidRead)return Du();let r=Im(t);if(r!==void 0)return r instanceof Error?Promise.reject(r):(e[Ra]=r,Promise.resolve(r));let i=new Promise((n,a)=>{let o=[],s=!1,c=g=>{s||(s=!0,m(),g())},u=g=>{let w=t.errored??g;return!J_(t)||w&&w.code!=="ECONNRESET"?!1:(c(()=>{let $=Im(t,o);$ instanceof Error?a($):$===void 0?a(g??wC(e,t)):(e[Ra]=$,n($))}),!0)},l=g=>{o.push(EC(g,t.readableEncoding))},d=()=>{c(()=>{let g=o.length===1?o[0]:Buffer.concat(o);e[Ra]=g,n(g)})},f=g=>{u(g)||c(()=>{a(g)})},p=()=>{if(t.readableEnded){d();return}u()||c(()=>{a(wC(e,t))})},m=()=>{t.off("data",l),t.off("end",d),t.off("error",f),t.off("close",p),e[Om]=void 0};t.on("data",l),t.on("end",d),t.on("error",f),t.on("close",p),queueMicrotask(()=>{s||(t.readableEnded?d():t.errored?f(t.errored):t.destroyed&&p())})});return e[Om]=i,i},ki={get method(){return this[TC]},get url(){return this[Au]},get headers(){return this[kC]||=PC(this[Js])},[q_](e){this[Cu]===void 0&&(this[Cu]=e);let t=this[ku];t&&!t.signal.aborted&&t.abort(e)},[Z_](){return this[ku]||=new AbortController,this[Cu]!==void 0&&!this[ku].signal.aborted&&this[ku].abort(this[Cu]),this[ku]},[Ma](){let e=this[Z_]();if(this[Qi])return this[Qi];let t=this.method;if(this[ta]&&!(t==="GET"||t==="HEAD")){this[Ra]=void 0;let r={method:t==="TRACE"?"GET":t,headers:this.headers,signal:e.signal};t!=="TRACE"&&(r.body=new ReadableStream({start(n){n.close()}}),r.duplex="half");let i=new Hs(this[Au],r);return t==="TRACE"&&Object.defineProperty(i,"method",{get(){return"TRACE"}}),this[Qi]=i}return this[Qi]=ude(this.method,this[Au],this.headers,this[Js],e)},get body(){if(!this[ta])return this[Ma]().body;let e=this[Ma]();return!this[_C]&&e.body&&(this[_C]=e.body.getReader()),e.body},get bodyUsed(){return this[ta]?!0:this[Qi]?this[Qi].bodyUsed:!1}};Object.defineProperty(ki,"signal",{get(){return this[Z_]().signal}});["cache","credentials","destination","integrity","mode","redirect","referrer","referrerPolicy","keepalive"].forEach(e=>{Object.defineProperty(ki,e,{get(){return this[Ma]()[e]}})});["clone","formData"].forEach(e=>{Object.defineProperty(ki,e,{value:function(){if(this[ta]){if(e==="clone")throw jm();return Du()}return this[Ma]()[e]()}})});Object.defineProperty(ki,"text",{value:function(){return G_(this,"text",e=>lde.decode(e))}});Object.defineProperty(ki,"arrayBuffer",{value:function(){return G_(this,"arrayBuffer",e=>fde(e))}});Object.defineProperty(ki,"blob",{value:function(){return G_(this,"blob",(e,t)=>{let r=pde(t),i=r?{headers:{"content-type":r}}:void 0;return new Response(e,i).blob()})}});Object.defineProperty(ki,"json",{value:function(){return this[ta]?Du():this.text().then(JSON.parse)}});Object.defineProperty(ki,Symbol.for("nodejs.util.inspect.custom"),{value:function(e,t,r){return`Request (lightweight) ${r({method:this.method,url:this.url,headers:this.headers,nativeRequest:this[Qi]},{...t,depth:e==null?null:e-1})}`}});Object.setPrototypeOf(ki,Hs.prototype);var bde=(e,t)=>{let r=Object.create(ki);r[Js]=e,r[TC]=hde(e.method);let i=e.url||"";if(i[0]!=="/"&&(i.startsWith("http://")||i.startsWith("https://"))){if(e instanceof Ei.Http2ServerRequest)throw new wr("Absolute URL for :path is not allowed in HTTP/2");try{Pm(i),r[Au]=new URL(i).href}catch(o){throw new wr("Invalid absolute URL",{cause:o})}return r}let n=(e instanceof Ei.Http2ServerRequest?e.authority:e.headers.host)||t;if(!n)throw new wr("Missing host header");let a;if(e instanceof Ei.Http2ServerRequest){if(a=e.scheme,!(a==="http"||a==="https"))throw new wr("Unsupported scheme")}else a=e.socket&&e.socket.encrypted?"https":"http";try{r[Au]=IC(a,n,i)}catch(o){throw o instanceof wr?o:new wr("Invalid URL",{cause:o})}return r},Ro="text/plain; charset=UTF-8",U_=Symbol("responseCache"),Vs=Symbol("getResponseCache"),ea=Symbol("cache"),Em=global.Response,Ti=class CC{#e;#t;[Vs](){let t=this[ea],r=t&&t[2]instanceof Headers?t[2]:void 0;return delete this[ea],this[U_]||=new Em(this.#e,r?{status:this.#t?.status,statusText:this.#t?.statusText,headers:r}:this.#t)}constructor(t,r){let i;if(this.#e=t,r instanceof Em){let n=r[U_];if(n){this.#t=n,this[Vs]();return}this.#t=r instanceof CC?r.#t:r,i=new Headers(r.headers)}else this.#t=r;(t==null||typeof t=="string"||typeof t?.getReader<"u"||t instanceof Blob||t instanceof Uint8Array)&&(this[ea]=[r?.status||200,t??null,i||r?.headers])}get headers(){let t=this[ea];return t?(t[2]instanceof Headers||(t[2]=new Headers(t[2]||(t[1]===null?void 0:{"content-type":Ro}))),t[2]):this[Vs]().headers}get status(){return this[ea]?.[0]??this[Vs]().status}get ok(){let t=this.status;return t>=200&&t<300}};["body","bodyUsed","redirected","statusText","trailers","type","url"].forEach(e=>{Object.defineProperty(Ti.prototype,e,{get(){return this[Vs]()[e]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach(e=>{Object.defineProperty(Ti.prototype,e,{value:function(){return this[Vs]()[e]()}})});Object.defineProperty(Ti.prototype,Symbol.for("nodejs.util.inspect.custom"),{value:function(e,t,r){return`Response (lightweight) ${r({status:this.status,headers:this.headers,ok:this.ok,nativeResponse:this[U_]},{...t,depth:e==null?null:e-1})}`}});Object.setPrototypeOf(Ti,Em);Object.setPrototypeOf(Ti.prototype,Em.prototype);var _de=/^https?:\/\/[!#-;=?-[\]_a-z~A-Z]+$/,wde=e=>e instanceof URL?e.href:_de.test(e)?e:new URL(e).href,Sde=new Set([301,302,303,307,308]);Object.defineProperty(Ti,"redirect",{value:function(t,r=302){if(!Sde.has(r))throw new RangeError("Invalid status code");return new Ti(null,{status:r,headers:{location:wde(t)}})},writable:!0,configurable:!0});Object.defineProperty(Ti,"json",{value:function(t,r){let i=JSON.stringify(t);if(i===void 0)throw new TypeError("The data is not JSON serializable");let n=r?.headers,a;return n?(a=new Headers(n),a.has("content-type")||a.set("content-type","application/json")):a={"content-type":"application/json"},new Ti(i,{status:r?.status??200,statusText:r?.statusText,headers:a})},writable:!0,configurable:!0});async function $de(e){return Promise.race([e,Promise.resolve().then(()=>Promise.resolve(void 0))])}function AC(e,t,r){let i=s=>{e.cancel(s).catch(()=>{})};return t.on("close",i),t.on("error",i),(r??e.read()).then(o,n),e.closed.finally(()=>{t.off("close",i),t.off("error",i)});function n(s){s&&t.destroy(s)}function a(){e.read().then(o,n)}function o({done:s,value:c}){try{if(s)t.end();else if(!t.write(c))t.once("drain",a);else return e.read().then(o,n)}catch(u){n(u)}}}function SC(e,t){if(e.locked)throw new TypeError("ReadableStream is locked.");return t.destroyed?void 0:AC(e.getReader(),t)}var L_=(e,t)=>{let r={};if(e instanceof Headers||(e=new Headers(e??void 0)),e.has("set-cookie")){let i=[];for(let[n,a]of e)n==="set-cookie"?i.push(a):r[n]=a;i.length>0&&(r["set-cookie"]=i)}else for(let[i,n]of e)r[i]=n;return t&&(r["content-type"]??=t),r},Tm=Symbol("outgoingEnded"),$C=Symbol("incomingDraining"),xde=500,Ode=64*1024*1024,DC=e=>{let t=e;if(e.destroyed||t[$C])return;if(t[$C]=!0,e instanceof Ei.Http2ServerRequest){try{e.stream?.close?.(Ei.constants.NGHTTP2_NO_ERROR)}catch{}return}let r=0,i=()=>{clearTimeout(a),e.off("data",o),e.off("end",i),e.off("error",i)},n=()=>{i();let s=e.socket;s&&!s.destroyed&&(typeof s.destroySoon=="function"?s.destroySoon():typeof s.destroy=="function"&&s.destroy())},a=setTimeout(n,xde);a.unref?.();let o=s=>{r+=s.length,r>Ode&&n()};e.on("data",o),e.on("end",i),e.on("error",i),e.resume()},Pde=(e,t,r,i)=>()=>{t.errored?(yC(t),e[q_](t.errored.toString())):(!r.writableFinished||t instanceof Ei.Http2ServerRequest&&t.aborted)&&(yC(t),e[q_]("Client connection prematurely closed.")),i&&!t.readableEnded&&setTimeout(()=>{t.readableEnded||setTimeout(()=>{DC(t)})})},Ide=e=>{if(!(ea in e))return!1;let t=e[ea][1];return t===null||typeof t=="string"||t instanceof Uint8Array},jde=()=>new Response(null,{status:400}),RC=e=>new Response(null,{status:e instanceof Error&&(e.name==="TimeoutError"||e.constructor.name==="TimeoutError")?504:500}),km=(e,t)=>{let r=e instanceof Error?e:new Error("unknown error",{cause:e});r.code==="ERR_STREAM_PREMATURE_CLOSE"?console.info("The user aborted a request."):(console.error(e),t.headersSent||(t instanceof B_.ServerResponse&&(t._contentLength=null),t.writeHead(500,{"Content-Type":"text/plain"})),t.end(`Error: ${r.message}`),t.destroy(r))},F_=e=>{"flushHeaders"in e&&e.writable&&e.flushHeaders()},MC=(e,t,r)=>{let i=e;return i._contentLength===null&&i._hasBody&&i.useChunkedEncodingByDefault&&!i._removedContLen&&t>=200&&t!==204&&t!==304&&!e.hasHeader("content-length")&&!e.hasHeader("transfer-encoding")&&!e.hasHeader("trailer")?(i._contentLength=r,!0):!1},N_=(e,t,r)=>{MC(e,t,r)?e.writeHead(t,{"Content-Type":Ro}):e.writeHead(t,{"Content-Type":Ro,"Content-Length":r})},NC=async(e,t)=>{let[r,i,n]=e[ea];if(!n){i===null?(t.writeHead(r),t.end()):typeof i=="string"?(N_(t,r,Buffer.byteLength(i)),t.end(i)):i instanceof Uint8Array?(N_(t,r,i.byteLength),t.end(i)):i instanceof Blob?(N_(t,r,i.size),t.end(new Uint8Array(await i.arrayBuffer()))):(t.writeHead(r,{"Content-Type":Ro}),F_(t),await SC(i,t)?.catch(c=>km(c,t))),t[Tm]?.();return}let a=!1,o=!1,s=!0;if(n instanceof Headers)a=n.has("content-length"),n=L_(n,i===null?void 0:Ro);else if(Array.isArray(n)){let c=new Headers(n);a=c.has("content-length"),n=L_(c,i===null?void 0:Ro)}else{o=!0;for(let c in n){if(c.length===14&&c.toLowerCase()==="content-length"){a=!0;break}(c.length===17&&c.toLowerCase()==="transfer-encoding"||c.length===7&&c.toLowerCase()==="trailer")&&(s=!1)}}if(!a){let c;typeof i=="string"?c=Buffer.byteLength(i):i instanceof Uint8Array?c=i.byteLength:i instanceof Blob&&(c=i.size),c!==void 0&&(!o||!s||!MC(t,r,c))&&(o&&(n={...n}),n["Content-Length"]=c)}t.writeHead(r,n),i==null?t.end():typeof i=="string"||i instanceof Uint8Array?t.end(i):i instanceof Blob?t.end(new Uint8Array(await i.arrayBuffer())):(F_(t),await SC(i,t)?.catch(c=>km(c,t))),t[Tm]?.()},zC=e=>typeof e.then=="function",Ede=async(e,t,r={})=>{if(zC(e))if(r.errorHandler)try{e=await e}catch(n){let a=await r.errorHandler(n);if(!a)return;e=a}else e=await e.catch(RC);if(ea in e)return NC(e,t);let i=L_(e.headers,e.body===null?void 0:Ro);if(e.body){let n=e.body.getReader(),a=[],o=!1,s;if(i["transfer-encoding"]!=="chunked"){let c=2;for(let u=0;u<c;u++){s||=n.read();let l=await $de(s).catch(d=>{console.error(d),o=!0});if(!l){if(u===1){await new Promise(d=>setTimeout(d)),c=3;continue}break}if(s=void 0,l.value&&a.push(l.value),l.done){o=!0;break}}o&&!("content-length"in i)&&(i["content-length"]=a.reduce((u,l)=>u+l.length,0))}t.writeHead(e.status,i),a.forEach(c=>{t.write(c)}),o?t.end():(a.length===0&&F_(t),await AC(n,t,s))}else i[Yle.X_ALREADY_SENT]||(t.writeHead(e.status,i),t.end());t[Tm]?.()},ZC=(e,t={})=>{let r=t.autoCleanupIncoming??!0;return t.overrideGlobalObjects!==!1&&global.Request!==Hs&&(Object.defineProperty(global,"Request",{value:Hs}),Object.defineProperty(global,"Response",{value:Ti})),async(i,n)=>{let a,o,s=!1,c=!1,u=()=>{!o||c||(c=!0,n.on("close",Pde(o,i,n,s)))};try{if(o=bde(i,t.hostname),s=r&&!(i.method==="GET"||i.method==="HEAD"),s&&(i[jC]=!0,i instanceof Ei.Http2ServerRequest&&(n[Tm]=()=>{i.readableEnded||setTimeout(()=>{i.readableEnded||setTimeout(()=>{i.destroy(),n.destroy()})})})),a=e(o,{incoming:i,outgoing:n}),!zC(a)&&Ide(a))return s&&!i.readableEnded&&n.once("finish",()=>{i.readableEnded||DC(i)}),NC(a,n);u()}catch(l){if(a)return km(l,n);if(t.errorHandler){if(u(),a=await t.errorHandler(o?l:ade(l)),!a)return}else o?a=RC(l):a=jde()}try{return await Ede(a,n,t)}catch(l){return km(l,n)}}},Tde=globalThis.CloseEvent??class extends Event{#e;constructor(e,t={}){super(e,t),this.#e=t}get wasClean(){return this.#e.wasClean??!1}get code(){return this.#e.code??0}get reason(){return this.#e.reason??""}},kde=globalThis.ErrorEvent??class extends Event{#e;constructor(e,t={}){super(e,t),this.#e=t}get message(){return this.#e.message??""}get filename(){return this.#e.filename??""}get lineno(){return this.#e.lineno??0}get colno(){return this.#e.colno??0}get error(){return this.#e.error??null}},Cde=()=>Symbol("connection"),qC=Symbol("CONNECTION_SYMBOL_KEY"),UC=Symbol("WAIT_FOR_WEBSOCKET_SYMBOL"),Ade=new Set(["connection","content-length","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","sec-websocket-accept","sec-websocket-extensions","sec-websocket-protocol"]),LC=(e,t)=>{t&&t.forEach((r,i)=>{Ade.has(i.toLowerCase())||e.push(`${i}: ${r}`)})},xC=(e,t,r)=>{if(e.destroyed)return;let i=["Connection: close","Content-Length: 0"];LC(i,r),e.end(`HTTP/1.1 ${t.toString()} ${B_.STATUS_CODES[t]??""}\r
|
|
170
170
|
${i.join(`\r
|
|
171
171
|
`)}\r
|
|
172
172
|
\r
|