@cratis/screenplay-language 4.56.0 → 4.57.0

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.
@@ -1,13 +0,0 @@
1
- var languageId="screenplay",languageExtensionPoint={id:languageId,extensions:[".play"],aliases:["Screenplay","screenplay","play"],mimetypes:["text/x-screenplay"]},constructKeywords=["domain","import","concept","type","policy","persona","authentication","module","layout","theme","ui","feature","slice","event","command","query","projection","capture","reaction","reducer","trigger","screen","dialog","form","contribute","constraint","specification","seed","behavior"];var clauseKeywords=["description","template","profile","require","authenticated","role","claim","subject","authorize","validate","produces","reads","as","handler","performer","observable","identifier","reason","from","when","given","then","arguments","result","clock","exactly","error","message","not","empty","rule","matches","all","max","min","length","today","true","false","and","or","by","filter","data","via","action","navigate","to","label","section","table","summary","title","column","field","on","unique","file","concurrency","eventSource","sourceType","streamType","streamId","tag","for","readmodel","no","when","every","at","where","invokes","contains","starts","with","provider","uses","parameter","order","execute","open","close","refresh","set","notify","confirm","raise","interval","success","failure","click","double","select","submit","change","load","unload","enter","leave","info","warning"],codeBlockTags=["csharp","typescript","react","html","sql"],contextRoots=["command","arguments","tenant","causedBy","causation","occurred","identity"],causedByProperties=["subject","name","userName"],identityProperties=["id","name","userName","isAuthenticated","roles","claims"],sliceTypes=["StateChange","StateView","Automation","Translate"],primitiveTypes=["Uuid","String","Int","Decimal","Bool","Date","DateTime"],conceptAttributes=["@pii","@sensitive"],languageConfiguration={comments:{lineComment:"//"},brackets:[["(",")"],["[","]"]],autoClosingPairs:[{open:"(",close:")"},{open:"[",close:"]"},{open:'"',close:'"'}],surroundingPairs:[{open:"(",close:")"},{open:"[",close:"]"},{open:'"',close:'"'}],folding:{offSide:!0},indentationRules:{increaseIndentPattern:/^\s*(module|feature|slice|policy|persona|authentication|provider|event|command|query|type|screen|projection|capture|reaction|trigger|constraint|specification|layout|template|validate|produces|handler|performer|rule|section|concurrency|seed|for|when|then|arguments|result|every|at)\b.*$/,decreaseIndentPattern:/(?!)/}};function typeReferenceSymbol(text){let match=/^([\w.]+)(\[\])?(\?|\s+optional)?$/.exec(text);return{name:match?.[1]??text,isCollection:match?.[2]!==void 0,isOptional:match?.[3]!==void 0}}function typeReferenceText(type){return`${type.name}${type.isCollection?"[]":""}${type.isOptional?" optional":""}`}function withoutComment(line){let inString=!1,inTemplate=!1;for(let index=0;index<line.length;index++){let character=line[index];if(character==="\\"&&inString&&index+1<line.length)index++;else if(character==='"'&&!inTemplate)inString=!inString;else if(character==="`"&&!inString)inTemplate=!inTemplate;else if(!inString&&!inTemplate&&character==="/"&&line[index+1]==="/")return line.slice(0,index)}return line}function indentOf(line){return line.length-line.trimStart().length}function firstWord(line){return line.trim().split(/\s+/)[0]??""}function fenceMap(lines){let map=new Array(lines.length).fill(!1),open=!1;for(let index=0;index<lines.length;index++){if(/^\s*```(?:[a-z]+)?\s*$/.test(lines[index])&&(!open||/^\s*```\s*$/.test(lines[index]))){map[index]=!0,open=!open;continue}map[index]=open}return map}function enclosingChain(lines,fences,lineIndex,indent){let chain=[],currentIndent=indent;for(let index=lineIndex-1;index>=0&&currentIndent>0;index--){if(fences[index])continue;let line=withoutComment(lines[index]);if(line.trim().length===0)continue;let lineIndent=indentOf(line);lineIndent<currentIndent&&(chain.push(firstWord(line)),currentIndent=lineIndent)}return chain}function nearestEnclosingLine(lines,fences,lineIndex,indent){for(let index=lineIndex-1;index>=0&&indent>0;index--){if(fences[index])continue;let line=withoutComment(lines[index]);if(line.trim().length!==0&&indentOf(line)<indent)return line.trim()}}var DiagnosticCodes={InvalidProducesDeclaration:"PLAY0042",ProducesWhenWithoutEvent:"PLAY0043",InvalidPropertyMapping:"PLAY0044",DuplicateProducesTarget:"PLAY0193",EventSourceIdInPayload:"PLAY0469",ExplicitProducesTargetsRequired:"PLAY0470",RedundantEventId:"PLAY0471",InvalidEventId:"PLAY0472",InlineEventCollision:"PLAY0473",InlineEventOutsideCommand:"PLAY0474",InlineEventGeneration:"PLAY0475",ReservedProductionMetadata:"PLAY0476",InvalidEventDocumentation:"PLAY0477",UnknownTopLevelConstruct:"PLAY0001",InvalidDomainDeclaration:"PLAY0002",DuplicateDomain:"PLAY0003",DomainNotFirst:"PLAY0004",InvalidImportDeclaration:"PLAY0005",TabIndentation:"PLAY0006",InvalidConceptDeclaration:"PLAY0007",UnknownPrimitiveType:"PLAY0008",InvalidEnumerationValue:"PLAY0009",UnknownConceptDirective:"PLAY0010",ValidateReadAsEnumerationBlock:"PLAY0011",AttributeReasonWithoutAttribute:"PLAY0012",DuplicateAttributeReason:"PLAY0013",InvalidTypeDeclaration:"PLAY0014",TypeWithoutProperties:"PLAY0015",InvalidPropertyDeclaration:"PLAY0016",IdentifierOutsideCommand:"PLAY0017",InvalidEventDeclaration:"PLAY0018",IdentifierOnEventProperty:"PLAY0019",TagPropertyReadAsTag:"PLAY0020",InvalidModuleDeclaration:"PLAY0021",UnknownModuleDirective:"PLAY0022",InvalidFeatureDeclaration:"PLAY0023",UnknownFeatureDirective:"PLAY0024",InvalidSliceDeclaration:"PLAY0027",UnknownSliceType:"PLAY0028",UnknownSliceDirective:"PLAY0029",InvalidPersonaDeclaration:"PLAY0030",InvalidPersonaPolicyReference:"PLAY0031",UnknownPersonaDirective:"PLAY0032",InvalidCommandDeclaration:"PLAY0033",UnknownCommandDirective:"PLAY0034",DuplicateCommandIdentifier:"PLAY0036",InvalidQueryDeclaration:"PLAY0047",UnknownQueryDirective:"PLAY0048",InvalidQueryParameter:"PLAY0049",InvalidProjectionDeclaration:"PLAY0056",EmptyProjection:"PLAY0057",UnknownProjectionDirective:"PLAY0058",FromWithoutEvent:"PLAY0061",InvalidEventReference:"PLAY0062",InvalidJoinDeclaration:"PLAY0063",JoinWithoutEvent:"PLAY0064",InvalidChildrenDeclaration:"PLAY0065",InvalidNestedDeclaration:"PLAY0066",NestedBlockWithoutFrom:"PLAY0067",InvalidRemoveDeclaration:"PLAY0068",UnknownRemoveDirective:"PLAY0069",InvalidClearDeclaration:"PLAY0070",ClearWithOutsideNestedBlock:"PLAY0071",InvalidSpecificationDeclaration:"PLAY0094",UnknownSpecificationDirective:"PLAY0095",InvalidSpecificationWhen:"PLAY0096",DuplicateSpecificationWhen:"PLAY0097",InvalidThenError:"PLAY0098",InvalidReadModelStep:"PLAY0099",InvalidEventStep:"PLAY0100",InvalidSpecificationValue:"PLAY0101",InvalidScreenDeclaration:"PLAY0102",UnknownScreenDirective:"PLAY0103",InvalidDataDirective:"PLAY0104",InvalidActionDirective:"PLAY0105",UnknownActionDirective:"PLAY0106",InvalidNavigation:"PLAY0107",InvalidScreenLayoutSlot:"PLAY0108",InvalidTitleDirective:"PLAY0109",UnknownTableDirective:"PLAY0110",UnknownSummaryDirective:"PLAY0111",AuthorizeWithoutPolicy:"PLAY0122",InvalidPolicyReference:"PLAY0123",InvalidConstraintDeclaration:"PLAY0132",ConstraintWithoutRule:"PLAY0133",InvalidConstraintBody:"PLAY0134",DuplicateConstraintBody:"PLAY0135",InvalidReactionDeclaration:"PLAY0136",InvalidReactionTrigger:"PLAY0137",ReactionWithoutTrigger:"PLAY0138",InvalidValidateDeclaration:"PLAY0140",InvalidValidationRule:"PLAY0141",InvalidRuleName:"PLAY0143",InvalidDescription:"PLAY0145",EmptyDescription:"PLAY0146",DuplicateDescription:"PLAY0147",TagWithoutValue:"PLAY0148",InvalidTagValue:"PLAY0149",UnknownContextPath:"PLAY0153",UnknownContextCausedByProperty:"PLAY0154",UnknownContextIdentityProperty:"PLAY0155",ExpectedCodeFence:"PLAY0163",UnclosedCodeBlock:"PLAY0164",DuplicateDeclaration:"PLAY0168",RepeatedSingularDeclarationAcrossFiles:"PLAY0172",RepeatedDeclarationAcrossFiles:"PLAY0173",ConflictingDescriptionAcrossFiles:"PLAY0174",UnexpectedTokenInAuthorize:"PLAY0184",UnclosedAuthorizeGroup:"PLAY0185",InvalidReadModelDeclaration:"PLAY0186",InvalidInvokesDeclaration:"PLAY0194",InvalidScopeDeclaration:"PLAY0199",DuplicateScope:"PLAY0200",InvalidIntervalTrigger:"PLAY0249",InvalidScheduleTrigger:"PLAY0250",DuplicateReactionTrigger:"PLAY0253",InvalidSpecificationEventSource:"PLAY0275",DuplicateSpecificationEventSource:"PLAY0276",InvalidProjectionVariantDeclaration:"PLAY0277",InvalidEntersOnDeclaration:"PLAY0279",NestedProjectionVariantNotAllowed:"PLAY0280",InvalidStructuredValue:"PLAY0291",DuplicateStructuredValueMember:"PLAY0294",ConflictingSpecificationActions:"PLAY0358",InvalidSpecificationEventOrder:"PLAY0359",InvalidValidationSeverity:"PLAY0368",VariantRequiresEnteringEvent:"PLAY0382",DuplicateProjectionVariant:"PLAY0384",DuplicateVariantEnteringEvent:"PLAY0385",InvalidSpecificationDenied:"PLAY0388",DuplicateAuthorizationAcrossFiles:"PLAY0394",FileConstraintOnlySupportsUniqueness:"PLAY0396",LegacyInlineCodeFence:"PLAY0397",InvalidEventGeneration:"PLAY0446",InvalidFileImport:"PLAY0454",FileImportMatchesNothing:"PLAY0455",ImportedFileNotFound:"PLAY0456",ConflictingImportPlacement:"PLAY0457",ImportCycle:"PLAY0458",ModuleInPlacedFile:"PLAY0459",UnexpectedInPlacedFile:"PLAY0460",InvalidSpecificationClock:"PLAY0461",InvalidSpecificationTrigger:"PLAY0462",InvalidSpecificationCapture:"PLAY0463",InvalidSpecificationQueryAction:"PLAY0464",LegacyOptionalSuffix:"PLAY0479",InvalidOptionalModifierOrder:"PLAY0480",OptionalReadsNotSupported:"PLAY0481",DuplicateSpecificationCallerOrDenied:"PLAY0387",GeneratedPropertyOutsideCommand:"PLAY0482",InvalidGeneratedType:"PLAY0483",InvalidGeneratedModifierOrder:"PLAY0484",GeneratedPropertySuppliedAsInput:"PLAY0485",InvalidCommandResponse:"PLAY0486",InvalidResponseSource:"PLAY0487",DuplicateResponseField:"PLAY0488",InvalidResponseShape:"PLAY0489",InvalidGeneratedFixture:"PLAY0490",InvalidReturnExpectation:"PLAY0491",InvalidTriggerData:"PLAY0246"};function splitLines(source,hashComments=!1,path){let result=[],number=0,offset=0;for(let raw of source.split(`
2
- `)){number++;let line=raw.endsWith("\r")?raw.replace(/\r+$/,""):raw,indent=line.length-line.trimStart().length,content=stripComment(line.substring(indent),hashComments).trimEnd();result.push(path===void 0?{number,raw:line,indent,content,startOffset:offset}:{number,raw:line,indent,content,path,startOffset:offset}),offset+=raw.length+1}return result}function commentStart(text,hashComments=!1){let inString=!1,inTemplate=!1;for(let index=0;index<text.length;index++){let current=text[index];if(current==="\\"&&inString&&index+1<text.length)index++;else if(current==='"'&&!inTemplate)inString=!inString;else if(current==="`"&&!inString)inTemplate=!inTemplate;else if(!inString&&!inTemplate&&(current==="/"&&index+1<text.length&&text[index+1]==="/"||hashComments&&current==="#"))return index}return-1}function stripComment(text,hashComments){let comment=commentStart(text,hashComments);return comment<0?text:text.substring(0,comment)}var documentPlacement=[],isDocumentPlacement=placement=>placement.length===0;function describePlacement(placement){return placement.length===0?"the application":placement.length===1?`module '${placement[0]}'`:`feature '${placement.join(".")}'`}var wordCharacters="\\p{L}\\p{Mn}\\p{Nd}\\p{Pc}";function pattern(source){let result="",inClass=!1;for(let index=0;index<source.length;index++){let current=source[index];if(current==="\\"&&index+1<source.length){let next=source[index+1];index++,next==="w"?result+=inClass?wordCharacters:`[${wordCharacters}]`:next==="d"?result+="\\p{Nd}":result+=`\\${next}`;continue}current==="["&&!inClass?inClass=!0:current==="]"&&inClass&&(inClass=!1),result+=current}return new RegExp(result,"u")}var sourceLocation=(line,column2,path)=>path===void 0?{line,column:column2}:{line,column:column2,path};var isBlank=line=>line.content.length===0,locationOf=line=>sourceLocation(line.number,line.indent+1,line.path),startOf=line=>sourceLocation(line.number,1,line.path);var continuationPattern=pattern("^(?:(?:or|and)\\s+)?[A-Za-z_(][\\w\\s()]*$"),tokenPattern=new RegExp(pattern("\\(|\\)|[A-Za-z_]\\w*").source,"gu"),namePattern=pattern("^[A-Z]\\w*$");function parseAuthorize(context,line){let text=line.content.substring(9);for(let child=context.peekChild(line.indent);child!==void 0&&continuationPattern.test(child.content);child=context.peekChild(line.indent))context.reader.takeSignificant(),text+=` ${child.content}`;let tokens=tokenize(text),location=locationOf(line);if(tokens.length===0)return context.error(DiagnosticCodes.AuthorizeWithoutPolicy,"Expected at least one policy after 'authorize'",location),null;let requirement=new RequirementParser(context,tokens,location).parse();return requirement===null?null:{kind:"AuthorizeSyntax",requirement,location}}function combineAuthorize(first,next){return first===null?next:next===null?first:{kind:"AuthorizeSyntax",requirement:{kind:"LogicalPolicyRequirementSyntax",left:first.requirement,operator:"And",right:next.requirement,location:first.location},location:first.location}}function tokenize(text){let tokens=[];for(let token of text.match(tokenPattern)??[])tokens.length>0&&isOperandEnd(tokens[tokens.length-1])&&isOperandStart(token)&&tokens.push("and"),tokens.push(token);return tokens}var isName=token=>token!=="("&&token!==")"&&token!=="and"&&token!=="or",isOperandEnd=token=>token===")"||isName(token),isOperandStart=token=>token==="("||isName(token),RequirementParser=class{context;tokens;location;#position=0;constructor(context,tokens,location){this.context=context,this.tokens=tokens,this.location=location}parse(){let requirement=this.#or();return requirement!==null&&this.#position<this.tokens.length&&this.context.error(DiagnosticCodes.UnexpectedTokenInAuthorize,`Unexpected '${this.tokens[this.#position]}' in authorize`,this.location),requirement}#or(){return this.#chain("or","Or",()=>this.#and())}#and(){return this.#chain("and","And",()=>this.#groupOrReference())}#chain(token,operator,operand2){let left=operand2();for(;left!==null&&this.tokens[this.#position]===token;){this.#position++;let right=operand2();if(right===null)return null;left={kind:"LogicalPolicyRequirementSyntax",left,operator,right,location:this.location}}return left}#groupOrReference(){if(this.tokens[this.#position]!=="(")return this.#reference();this.#position++;let requirement=this.#or();return this.tokens[this.#position]===")"?this.#position++:this.context.error(DiagnosticCodes.UnclosedAuthorizeGroup,"Expected ')' in authorize",this.location),requirement}#reference(){if(this.#position>=this.tokens.length)return this.context.error(DiagnosticCodes.AuthorizeWithoutPolicy,"Expected a policy name",this.location),null;let token=this.tokens[this.#position++];return namePattern.test(token)?{kind:"PolicyReferenceSyntax",name:token,location:this.location}:(this.context.error(DiagnosticCodes.InvalidPolicyReference,`Invalid policy reference '${token}' - policy names are PascalCase identifiers`,this.location),null)}};var stringBodyPattern='(?:[^"\\\\]|\\\\.)*',escapes={"\\":"\\",'"':'"',n:`
3
- `,r:"\r",t:" "};function unescapeString(value){if(!value.includes("\\"))return value;let result="";for(let index=0;index<value.length;index++){let escaped=index+1<value.length?escapes[value[index+1]]:void 0;value[index]==="\\"&&escaped!==void 0?(result+=escaped,index++):result+=value[index]}return result}function parseFencedText(context,opener,tagLine,allowMarkdown=!1){let open=tagLine.content.startsWith("```")?tagLine:context.reader.peekSignificant(),expectedFence=opener==="description"?"```text":`\`\`\`${opener}`;if(open===void 0||open!==tagLine&&open.indent<=tagLine.indent||open.content!==expectedFence&&!(allowMarkdown&&opener==="description"&&open.content==="```markdown")&&!(open.content==="```"&&open!==tagLine))return context.error(DiagnosticCodes.ExpectedCodeFence,`Expected an opening \`\`\`${opener==="description"?"text":opener} fence after '${opener}'`,locationOf(tagLine)),null;open!==tagLine&&context.reader.takeSignificant(),opener==="description"&&open.content==="```"&&context.warning(DiagnosticCodes.LegacyInlineCodeFence,"A bare description fence is deprecated - use '```text' instead",locationOf(open));let code=[];for(;;){let line=context.reader.takeRaw();if(line===void 0){context.error(DiagnosticCodes.UnclosedCodeBlock,"Unclosed inline code block - expected a closing ``` line",locationOf(open));break}if(line.raw.trim()==="```")break;let strip=0;for(;strip<open.indent&&strip<line.raw.length&&line.raw[strip]===" ";)strip++;code.push(line.raw.substring(strip))}return code.join(`
4
- `)}var descriptionPattern=pattern(`^description\\s+"(${stringBodyPattern})"$`);function parseDescription(context,line,existing,owner,allowMarkdown=!1){if(line.content==="description"){let text=parseFencedText(context,"description",line,allowMarkdown);return text===null?existing:text.trim().length===0?(context.error(DiagnosticCodes.EmptyDescription,`${owner} declares an empty description - the fenced block must contain text`,locationOf(line)),existing):keep(context,line,existing,owner,text)}let match=descriptionPattern.exec(line.content);return match===null?(context.error(DiagnosticCodes.InvalidDescription,`Invalid description '${line.content}' - expected 'description "<text>"'`,locationOf(line)),existing):keep(context,line,existing,owner,unescapeString(match[1]))}function keep(context,line,existing,owner,description){return existing!==null?(context.error(DiagnosticCodes.DuplicateDescription,`${owner} already declares a description - at most one is allowed`,locationOf(line)),existing):description}var fileImportPattern=pattern('^import\\s+"([^"\\\\]+)"$'),quotedPattern=pattern('^import\\s+"'),isFileImport=content=>quotedPattern.test(content);function tryParseFileImport(line){let match=fileImportPattern.exec(line.content);return match===null?void 0:{kind:"FileImportSyntax",pattern:match[1],location:locationOf(line)}}function parseFileImport(context,line,imports){let fileImport=tryParseFileImport(line);if(fileImport!==void 0){imports.push(fileImport);return}context.error(DiagnosticCodes.InvalidFileImport,`Invalid import '${line.content}' - inside a module or feature, import names files: 'import "<path or glob>"'`,locationOf(line)),context.skipBlock(line.indent)}var firstWord2=content=>{let space=content.indexOf(" ");return space===-1?content:content.substring(0,space)},unescapeIdentifier=identifier=>identifier.replaceAll("@","");function splitTopLevel(text,separator){let parts=[],start=0,inString=!1,inTemplate=!1;for(let index=0;index<text.length;index++){let current=text[index];current==="\\"&&inString&&index+1<text.length?index++:current==='"'&&!inTemplate?inString=!inString:current==="`"&&!inString?inTemplate=!inTemplate:current===separator&&!inString&&!inTemplate&&(parts.push(text.substring(start,index)),start=index+1)}return parts.push(text.substring(start)),parts}var form=pattern("^form\\s+[A-Za-z_]\\w*\\s+for\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$"),execution=pattern("^(execute|invokes)\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$"),field=pattern("^field\\s+([\\w.]+)(?:\\s|$)"),argument=pattern("^with\\s+([A-Za-z_]\\w*)\\s+from\\s+.+$"),mapping=pattern("^(@?[\\w.]+)\\s*=(?!=|>)\\s*.+$"),parameter=pattern("^parameter\\s+([A-Za-z_]\\w*)(?:\\s+([\\w.]+(?:\\[\\])?))?$"),actionBoundaries=new Set(["refresh","navigate","open","close","set","notify","confirm","raise","on"]);function collectInputUses(context,header10){let owners=[],parameters=new Set,inputs=[],isBehavior=firstWord2(header10.content)==="behavior",recognize=line=>{for(;owners.length>0&&owners[owners.length-1].indent>=line.indent;)owners.pop();let declared=isBehavior&&owners.length===0?parameter.exec(line.content):null;declared!==null&&parameters.add(declared[1]);let formMatch=form.exec(line.content),execute=execution.exec(line.content);if(formMatch!==null)owners.push({command:formMatch[1],kind:"form",indent:line.indent});else if(execute!==null)owners.push({command:execute[2],kind:execute[1],indent:line.indent});else if(actionBoundaries.has(firstWord2(line.content)))owners.push({command:"",kind:"other",indent:line.indent});else{let owner=owners.at(-1);if(owner===void 0||owner.kind==="other")return;let supplied=(owner.kind==="form"?field:owner.kind==="execute"?argument:mapping).exec(line.content);supplied!==null&&inputs.push({command:owner.command,property:unescapeIdentifier(supplied[1]),scope:context.scope,location:locationOf(line)})}};recognize(header10);for(let child=context.peekChild(header10.indent);child!==void 0;child=context.peekChild(header10.indent))context.reader.takeSignificant(),child.content.startsWith("```")?context.skipFencedBody():recognize(child);for(let input of inputs)context.inputUses.push(parameters.has(input.command)?{...input,isParameter:!0}:input)}var sliceTypes2=["StateChange","StateView","Automation","Translate"];var header=pattern("^capture\\s+([A-Za-z_]\\w*)$"),appendPattern=pattern("^append\\s+([A-Z]\\w*)$"),childrenPattern=pattern("^children\\s+([a-z_]\\w*)\\s+identified\\s+by\\s+([\\w.]+)$"),nestedPattern=pattern("^nested\\s+([\\w.]+)$");function parseCapture(context,line){let name=header.exec(line.content)?.[1]??"",source=null,key=null,appends=[],children=[],nested=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent))switch(context.reader.takeSignificant(),firstWord2(child.content)){case"source":source=parseSource(context,child);break;case"key":key=child.content.substring(3).trim();break;case"append":pushAppend(context,child,appends);break;case"children":{let match=childrenPattern.exec(child.content),blockAppends=appendsOf(context,child);match!==null&&children.push({kind:"CaptureChildrenSyntax",property:match[1],identifiedBy:match[2],appends:blockAppends,location:locationOf(child)});break}case"nested":{let match=nestedPattern.exec(child.content),blockAppends=appendsOf(context,child);match!==null&&nested.push({kind:"CaptureNestedSyntax",property:match[1],appends:blockAppends,location:locationOf(child)});break}default:context.skipOpaqueBlock(child.indent)}return{kind:"CaptureSyntax",name,source,key,appends,children,nested,location:locationOf(line)}}function parseSource(context,line){let settings=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let settingName=firstWord2(child.content);settings.push({kind:"CaptureSourceSettingSyntax",name:settingName,value:child.content.substring(settingName.length).trim(),location:locationOf(child)})}return{kind:"CaptureSourceSyntax",syntaxKind:line.content.substring(6).trim(),settings,location:locationOf(line)}}function appendsOf(context,line){let appends=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent))context.reader.takeSignificant(),firstWord2(child.content)==="append"?pushAppend(context,child,appends):context.skipOpaqueBlock(child.indent);return appends}function pushAppend(context,line,appends){let match=appendPattern.exec(line.content);context.skipOpaqueBlock(line.indent),match!==null&&appends.push({kind:"CaptureAppendSyntax",event:match[1],location:locationOf(line)})}var propertyPattern=pattern("^(@?[a-z_]\\w*)\\s+([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?)(?:\\s+(generated))?(?:\\s+(identifier))?$"),invalidGeneratedModifiers=pattern("^@?[a-z_]\\w*\\s+[\\w.]+(?:\\[\\])?\\??\\s+((?:optional|generated|identifier)(?:\\s+(?:optional|generated|identifier))*)$"),reversedModifiers=pattern("^@?[a-z_]\\w*\\s+[\\w.]+(?:\\[\\])?\\s+identifier\\s+optional(?:\\s*=.*)?$");function tryParseProperty(line){let match=propertyPattern.exec(line.content);if(match===null)return;let location=locationOf(line);return{kind:"PropertySyntax",name:unescapeIdentifier(match[1]),type:parseTypeRef(match[2],{...location,column:location.column+line.content.indexOf(match[2],match[1].length)}),isGenerated:match[3]!==void 0,isIdentifier:match[4]!==void 0,location}}function parseTypeRef(text,location){let legacy=text.endsWith("?"),canonical=/\soptional$/.test(text),isOptional=legacy||canonical;isOptional&&(text=text.substring(0,text.length-(legacy?1:8)).trimEnd());let isCollection=text.endsWith("[]");return isCollection&&(text=text.substring(0,text.length-2)),{kind:"TypeRefSyntax",name:text,isCollection,isOptional,location}}function parseProperty(context,line){let property=tryParseProperty(line);return property!==void 0?reportLegacyOptionalSuffix(context,property.type,line):reportInvalidModifierOrder(context,line),property}function reportLegacyOptionalSuffix(context,type,line){let length=type.name.length+(type.isCollection?2:0),offset=type.location.column-line.indent-1+length;if(type.isOptional&&line.content[offset]==="?"){let name=type.name+(type.isCollection?"[]":"");context.information(DiagnosticCodes.LegacyOptionalSuffix,`Write '${name} optional' instead of '${name}?'.`,type.location)}}function reportInvalidModifierOrder(context,line){if(reversedModifiers.test(line.content))return context.error(DiagnosticCodes.InvalidOptionalModifierOrder,"Write 'optional' before 'identifier': '<name> <Type> optional identifier'.",locationOf(line)),!0;{let modifiers=invalidGeneratedModifiers.exec(line.content);if(modifiers!==null&&modifiers[1].split(/\s+/).some(modifier=>modifier==="generated"||modifier==="identifier"))return context.error(DiagnosticCodes.InvalidGeneratedModifierOrder,"Write each modifier once in order: '<name> <Type> optional generated identifier'.",locationOf(line)),!0}return!1}var scalarResponsePattern=pattern("^returns\\s+(@?[A-Za-z_]\\w*)$"),fieldPattern=pattern("^(@?[a-z_]\\w*)(?:\\s+([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?))?\\s*=(?!=|>)\\s*(@?[a-z_]\\w*)$");function parseCommandResponse(context,line){let location=locationOf(line);if(line.content!=="returns"){let match=scalarResponsePattern.exec(line.content);if(match===null)return context.error(DiagnosticCodes.InvalidCommandResponse,"Expected 'returns <property>' or an unconditional 'returns' block.",location),context.skipBlock(line.indent),null;let child=context.peekChild(line.indent);child!==void 0&&(context.error(DiagnosticCodes.InvalidCommandResponse,"A scalar response cannot have child directives.",locationOf(child)),context.skipBlock(line.indent));let sourceOffset=match.index+match[0].length-match[1].length;return{kind:"ScalarCommandResponseSyntax",source:{kind:"PropertyResponseSourceSyntax",property:unescapeIdentifier(match[1]),location:{...location,column:location.column+sourceOffset}},location}}let fields=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let match=fieldPattern.exec(child.content);if(match===null){context.error(DiagnosticCodes.InvalidCommandResponse,"Expected '<field> [<Type>] = <property>' in a response block.",locationOf(child)),context.skipBlock(child.indent);continue}let fieldLocation=locationOf(child),type=match[2]===void 0?null:parseTypeRef(match[2],{...fieldLocation,column:fieldLocation.column+child.content.indexOf(match[2],match[1].length)});type!==null&&reportLegacyOptionalSuffix(context,type,child),fields.push({kind:"ResponseFieldSyntax",name:unescapeIdentifier(match[1]),type,source:{kind:"PropertyResponseSourceSyntax",property:unescapeIdentifier(match[3]),location:{...fieldLocation,column:fieldLocation.column+child.content.lastIndexOf(match[3])}},location:fieldLocation});let nested=context.peekChild(child.indent);nested!==void 0&&(context.error(DiagnosticCodes.InvalidCommandResponse,"A response field cannot have child directives.",locationOf(nested)),context.skipBlock(child.indent))}return{kind:"RecordCommandResponseSyntax",fields,location}}var maximumDepth=64,InvalidStructuredValue=class extends Error{},StructuredValueParser=class{text;start;context;#position=0;constructor(text,start,context){this.text=text,this.start=start,this.context=context}parse(){let value=this.#value(0);if(this.#whitespace(),this.#position<this.text.length)throw new InvalidStructuredValue(`'${this.text[this.#position]}' is invalid after a single JSON value.`);return value}#value(depth){this.#whitespace();let location=this.#at(),current=this.text[this.#position];if(current==="["||current==="{"){if(depth>=maximumDepth)throw new InvalidStructuredValue(`The value nests deeper than ${maximumDepth} levels.`);return current==="["?this.#list(depth,location):this.#object(depth,location)}if(current==='"')return{kind:"LiteralExpressionSyntax",value:this.#string(),location};for(let[word,value]of[["true",!0],["false",!1],["null",null]])if(this.text.startsWith(word,this.#position))return this.#position+=word.length,{kind:"LiteralExpressionSyntax",value,location};return{kind:"LiteralExpressionSyntax",value:this.#number(),location}}#list(depth,location){this.#position++;let items=[];if(this.#whitespace(),this.#take("]"))return{kind:"ListExpressionSyntax",items,location};for(;;){if(items.push(this.#value(depth+1)),this.#whitespace(),this.#take("]"))return{kind:"ListExpressionSyntax",items,location};this.#expect(",")}}#object(depth,location){this.#position++;let members=[],names=new Set;if(this.#whitespace(),this.#take("}"))return{kind:"ObjectExpressionSyntax",members,location};for(;;){this.#whitespace();let keyLocation=this.#at();if(this.text[this.#position]!=='"')throw new InvalidStructuredValue("Expected a property name in double quotes.");let name=this.#string();this.#whitespace(),this.#expect(":");let value=this.#value(depth+1);if(names.has(name)?this.context?.error(DiagnosticCodes.DuplicateStructuredValueMember,`Duplicate property '${name}' in structured value`,keyLocation):(names.add(name),members.push({kind:"ObjectMemberSyntax",name,value,location:keyLocation})),this.#whitespace(),this.#take("}"))return{kind:"ObjectExpressionSyntax",members,location};this.#expect(",")}}#string(){let end=this.#stringEnd(this.#position),raw=this.text.substring(this.#position,end);this.#position=end;try{return JSON.parse(raw)}catch{throw new InvalidStructuredValue(`${raw} is not a valid JSON string.`)}}#stringEnd(from){for(let index=from+1;index<this.text.length;index++)if(this.text[index]==="\\")index++;else if(this.text[index]==='"')return index+1;throw new InvalidStructuredValue("A string is not closed.")}#number(){let match=/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/.exec(this.text.substring(this.#position));if(match===null)throw new InvalidStructuredValue(`'${this.text[this.#position]??""}' is an invalid start of a value.`);this.#position+=match[0].length;let number=Number(match[0]);if(!Number.isFinite(number))throw new InvalidStructuredValue("JSON number is outside the finite Double range.");return number}#at(){return{...this.start,column:this.start.column+this.#position}}#whitespace(){for(;this.#position<this.text.length&&`
5
- \r`.includes(this.text[this.#position]);)this.#position++}#take(character){return this.text[this.#position]!==character?!1:(this.#position++,!0)}#expect(character){if(!this.#take(character))throw new InvalidStructuredValue(`Expected '${character}' at position ${this.#position}.`)}};var pathPattern=pattern("^@?[A-Za-z_]\\w*(\\.@?[A-Za-z_$]\\w*)*$"),numberPattern=pattern("^-?\\d+(\\.\\d+)?$"),contextRoots2=["command","arguments","tenant","causedBy","causation","occurred","identity"],causedByProperties2=["subject","name","userName"],identityProperties2=["id","name","userName","isAuthenticated","roles","claims"];function parseMappingSource(text,location,context){if(text=text.trim(),text.startsWith("$context.")){let path=text.substring(9);return warnOnUnknownContextPath(path,location,context),{kind:"ContextExpressionSyntax",path,location}}if(text.startsWith("$env."))return{kind:"EnvironmentExpressionSyntax",name:text.substring(5),location};if(text.startsWith("$strings."))return{kind:"StringsExpressionSyntax",key:text.substring(9),location};if(text.startsWith("$."))return{kind:"SourceItemExpressionSyntax",path:text.substring(2),location};if(text.startsWith("{")||text.startsWith("["))try{return new StructuredValueParser(text,location,context).parse()}catch(error2){if(!(error2 instanceof InvalidStructuredValue))throw error2;return context?.error(DiagnosticCodes.InvalidStructuredValue,`Invalid inline structured value: ${error2.message}`,location),{kind:"RawExpressionSyntax",text,location}}let literal=parseLiteral(text,location);return literal!==void 0?literal:pathPattern.test(text)?{kind:"PathExpressionSyntax",path:text,location}:{kind:"RawExpressionSyntax",text,location}}function warnOnUnknownContextPath(path,location,context){let[root,member]=path.split(".");contextRoots2.includes(root)?member!==void 0&&root==="causedBy"&&!causedByProperties2.includes(member)?context?.warning(DiagnosticCodes.UnknownContextCausedByProperty,`Unknown $context.causedBy property '${member}' - expected ${causedByProperties2.join(", ")}`,location):member!==void 0&&root==="identity"&&!identityProperties2.includes(member)&&context?.warning(DiagnosticCodes.UnknownContextIdentityProperty,`Unknown $context.identity property '${member}' - expected ${identityProperties2.join(", ")}`,location):context?.warning(DiagnosticCodes.UnknownContextPath,`Unknown $context path '${path}' - expected one of ${contextRoots2.join(", ")}`,location)}function parseLiteral(text,location){let literal=value=>({kind:"LiteralExpressionSyntax",value,location});switch(text){case"true":return literal(!0);case"false":return literal(!1);case"null":return literal(null)}if(text.length>=2&&(text.startsWith('"')&&text.endsWith('"')||text.startsWith("'")&&text.endsWith("'")))return literal(unescapeString(text.substring(1,text.length-1)));if(numberPattern.test(text)&&!Number.isNaN(Number(text)))return literal(Number(text))}var ParserContext=class{reader;path;#diagnostics=[];triggerData=[];inputUses=[];scope=[];constructor(reader,path){this.reader=reader,this.path=path}get start(){return sourceLocation(1,1,this.path)}get diagnostics(){return this.#diagnostics}information(code,message,location){this.#diagnostics.push({severity:"information",code,message,location})}error(code,message,location){this.#diagnostics.push({severity:"error",code,message,location})}warning(code,message,location){this.#diagnostics.push({severity:"warning",code,message,location})}peekChild(parentIndent){let line=this.reader.peekSignificant();return line!==void 0&&line.indent>parentIndent?line:void 0}skipBlock(parentIndent){for(;this.peekChild(parentIndent)!==void 0;)this.reader.takeSignificant()}skipOpaqueBlock(parentIndent){let child=this.peekChild(parentIndent);for(;child!==void 0;)this.reader.takeSignificant(),child.content.startsWith("```")&&this.skipFencedBody(),child=this.peekChild(parentIndent)}skipFencedBody(){for(let line=this.reader.takeRaw();line!==void 0;line=this.reader.takeRaw())if(line.raw.trim()==="```")return}};var eventBodyReservedWords=["tag"];var idPattern=pattern(`^id\\s+"(${stringBodyPattern})"$`),EventMetadataParser=class{name;value={id:null,description:null,documentation:null};constructor(name){this.name=name}tryParse(context,line){let location=locationOf(line);switch(firstWord2(line.content)){case"id":{let match=idPattern.exec(line.content),id=match===null?"":unescapeString(match[1]);return id.trim().length===0||this.value.id!==null?context.error(DiagnosticCodes.InvalidEventId,`Event '${this.name}' accepts one nonempty 'id "<old-name>"'`,location):(this.value.id=id,id===this.name&&context.information(DiagnosticCodes.RedundantEventId,`Event '${this.name}' already has this name as its identity - remove the redundant id`,location)),!0}case"description":return this.value.description=parseDescription(context,line,this.value.description,`Event '${this.name}'`,!0),!0;case"documentation":{if(line.content!=="documentation"||context.peekChild(line.indent)?.content!=="```markdown")return context.error(DiagnosticCodes.InvalidEventDocumentation,`Event '${this.name}' documentation requires a fenced markdown block`,location),context.skipOpaqueBlock(line.indent),!0;let text=parseFencedText(context,"markdown",line);return text===null||text.trim().length===0||this.value.documentation!==null?context.error(DiagnosticCodes.InvalidEventDocumentation,`Event '${this.name}' accepts one nonempty documentation block`,location):this.value.documentation=text,!0}default:return!1}}};var typeReferencePattern=pattern("^[A-Za-z_]\\w*(?:\\[\\])?(?:\\?|\\s+optional)?$"),pathOf=line=>firstWord2(line.content)==="file"?line.content.substring(4).trim():"",isFileDirective=line=>pathOf(line).length>0,isFileDirectiveAmongProperties=line=>isFileDirective(line)&&!typeReferencePattern.test(pathOf(line));var typeHeader=pattern("^type\\s+([A-Za-z_]\\w*)$"),eventHeader=pattern("^event\\s+([A-Za-z_]\\w*)(?:\\s+generation\\s+([0-9]+))?$"),readModelHeader=pattern("^readmodel\\s+([A-Za-z_]\\w*)$"),maximumGeneration=4294967295,typeShapedPattern=pattern("^[A-Z]\\w*(?:\\[\\])?(?:\\?|\\s+optional)?$"),tagIdentifierPattern=pattern("^[A-Za-z_]\\w*$"),isDescription=line=>firstWord2(line.content)==="description"&&tryParseProperty(line)===void 0;function withoutIdentifier(context,property,line,code,message){return property.isIdentifier?(context.error(code,message,locationOf(line)),{...property,isIdentifier:!1}):property}function parseType(context,header10){let name=typeHeader.exec(header10.content)?.[1]??"";name===""&&context.error(DiagnosticCodes.InvalidTypeDeclaration,`Invalid type declaration '${header10.content}' - expected 'type <Name>'`,locationOf(header10));let properties=[],description=null;for(let line=context.peekChild(header10.indent);line!==void 0;line=context.peekChild(header10.indent)){if(context.reader.takeSignificant(),isDescription(line)){description=parseDescription(context,line,description,`Type '${name}'`);continue}if(isFileDirectiveAmongProperties(line))continue;let property=parseProperty(context,line);if(property===void 0){context.error(DiagnosticCodes.InvalidPropertyDeclaration,`Invalid property '${line.content}' - expected '<name> <Type>'`,locationOf(line));continue}properties.push(withoutIdentifier(context,property,line,DiagnosticCodes.IdentifierOutsideCommand,`Property '${property.name}' of type '${name}' cannot be marked identifier - only a command property can be`))}return properties.length===0&&context.error(DiagnosticCodes.TypeWithoutProperties,`Type '${name}' must declare at least one property`,locationOf(header10)),{kind:"TypeSyntax",name,properties,description,location:locationOf(header10)}}function parseEvent(context,header10){let match=eventHeader.exec(header10.content),name=match?.[1]??"";match===null&&context.error(DiagnosticCodes.InvalidEventDeclaration,`Invalid event declaration '${header10.content}' - expected 'event <Name> [generation <N>]'`,locationOf(header10));let hasGenerationMarker=match?.[2]!==void 0,generation=1;if(hasGenerationMarker){let declared=Number(match[2]);!Number.isSafeInteger(declared)||declared===0||declared>=maximumGeneration?context.error(DiagnosticCodes.InvalidEventGeneration,`Event '${name}' must declare a generation between 1 and ${maximumGeneration-1}`,locationOf(header10)):generation=declared}let properties=[],tags=[],metadata=new EventMetadataParser(name);for(let line=context.peekChild(header10.indent);line!==void 0;line=context.peekChild(header10.indent)){if(context.reader.takeSignificant(),isFileDirectiveAmongProperties(line))continue;if(eventBodyReservedWords.includes(firstWord2(line.content))){let tag=parseTag(context,line);tag!==void 0&&tags.push(tag);continue}let property=parseProperty(context,line);if(property===void 0){metadata.tryParse(context,line)||context.error(DiagnosticCodes.InvalidPropertyDeclaration,`Invalid property '${line.content}' - expected '<name> <Type>'`,locationOf(line));continue}properties.push(withoutIdentifier(context,property,line,DiagnosticCodes.IdentifierOnEventProperty,`Property '${property.name}' of event '${name}' cannot be marked identifier - an event never carries its event source id`))}return{kind:"EventSyntax",name,properties,tags,generation,hasGenerationMarker,...metadata.value,location:locationOf(header10)}}function parseTag(context,line,eventDeclaration=!0){let value=line.content.substring(3).trim();if(eventDeclaration&&typeShapedPattern.test(value)&&context.warning(DiagnosticCodes.TagPropertyReadAsTag,`'${line.content}' declares a static tag with the value '${value}', not a property named 'tag' - write 'tag "${value}"' for the tag, or '@${line.content}' for the property`,locationOf(line)),value.length===0){context.error(DiagnosticCodes.TagWithoutValue,"Expected a value after 'tag' - an identifier, a string literal or a context expression",locationOf(line));return}if(tagIdentifierPattern.test(value))return{kind:"TagSyntax",value:{kind:"LiteralExpressionSyntax",value,location:locationOf(line)},location:locationOf(line)};let expression=parseMappingSource(value,locationOf(line),context);if(expression.kind==="RawExpressionSyntax"){context.error(DiagnosticCodes.InvalidTagValue,`Invalid tag value '${value}' - expected an identifier, a string literal or a context expression`,locationOf(line));return}return{kind:"TagSyntax",value:expression,location:locationOf(line)}}function parseReadModel(context,header10){let name=readModelHeader.exec(header10.content)?.[1]??"";name===""&&context.error(DiagnosticCodes.InvalidReadModelDeclaration,`Invalid read model declaration '${header10.content}' - expected 'readmodel <Name>'`,locationOf(header10));let properties=[],description=null;for(let line=context.peekChild(header10.indent);line!==void 0;line=context.peekChild(header10.indent))if(context.reader.takeSignificant(),isDescription(line))description=parseDescription(context,line,description,`Read model '${name}'`);else{if(isFileDirectiveAmongProperties(line))continue;{let property=parseProperty(context,line);if(property===void 0){context.error(DiagnosticCodes.InvalidPropertyDeclaration,`Invalid property '${line.content}' - expected '<name> <Type>'`,locationOf(line));continue}properties.push(withoutIdentifier(context,property,line,DiagnosticCodes.IdentifierOutsideCommand,`Property '${property.name}' of read model '${name}' cannot be marked identifier - only a command property can be`))}}return{kind:"ReadModelSyntax",name,properties,description,location:locationOf(header10)}}var inlineHeader=pattern("^produces\\s+event\\s+([A-Za-z_]\\w*)(?:\\s+(generation)(?:\\s+.*)?)?$"),plainHeader=pattern("^produces\\s+([A-Z]\\w*)$"),conditional=pattern("^produces\\s+when\\s+(.+)$"),eventName=pattern("^[A-Z]\\w*$"),targetPattern=pattern("^for\\s+(\\S.*)$"),mappingPattern=pattern("^(@?[\\w.]+)\\s*=(?!=|>)\\s*(.+)$"),typedMappingPattern=pattern("^(.+?)\\s*=(?!=|>)\\s*(.+)$"),reserved=new Set(["namespace","sequence","correlation","causation","causedBy","occurred"]);function parseProduces(context,header10,inCommand=!1){let inline=inlineHeader.exec(header10.content),parent=header10,name;if(inline!==null){if(!inCommand){context.error(DiagnosticCodes.InlineEventOutsideCommand,"Inline events can only be declared inside commands",locationOf(header10)),context.skipOpaqueBlock(header10.indent);return}inline[2]!==void 0&&context.error(DiagnosticCodes.InlineEventGeneration,"Inline events are generation 1 - extract the event before declaring generations",locationOf(header10)),name=inline[1]}else if(conditional.test(header10.content)){let child=context.peekChild(header10.indent);if(child===void 0||!eventName.test(child.content)){context.error(DiagnosticCodes.ProducesWhenWithoutEvent,"Expected an event name on the line after 'produces when'",locationOf(header10)),context.skipOpaqueBlock(header10.indent);return}context.reader.takeSignificant(),parent=child,name=child.content}else{let plain=plainHeader.exec(header10.content);if(plain===null){context.error(DiagnosticCodes.InvalidProducesDeclaration,`Invalid produces declaration '${header10.content}' - expected 'produces <EventType>' or 'produces when <condition>'`,locationOf(header10)),context.skipOpaqueBlock(header10.indent);return}name=plain[1]}let properties=[],propertyNames=new Set,mappings=[],tags=[],metadata=new EventMetadataParser(name),target=null;for(let line=context.peekChild(parent.indent);line!==void 0;line=context.peekChild(parent.indent)){context.reader.takeSignificant();let keyword=firstWord2(line.content),location=locationOf(line);if(reserved.has(keyword)){context.error(DiagnosticCodes.ReservedProductionMetadata,`'${keyword}' is system-assigned production metadata and cannot be supplied here`,location),context.skipOpaqueBlock(line.indent);continue}if(inline!==null&&(keyword==="generation"||keyword==="origin")){context.error(keyword==="generation"?DiagnosticCodes.InlineEventGeneration:DiagnosticCodes.ReservedProductionMetadata,keyword==="generation"?"Inline events are generation 1 - extract the event before declaring generations":"An inline event is local to its command and cannot declare origin",location),context.skipOpaqueBlock(line.indent);continue}if(keyword==="tag"){let tag=parseTag(context,line,!1);tag!==void 0&&tags.push(tag);continue}let forMatch=targetPattern.exec(line.content);if(forMatch!==null){target!==null?context.error(DiagnosticCodes.DuplicateProducesTarget,`'${parent.content}' already declares where it lands - an event is appended to one event source`,location):target=parseMappingSource(forMatch[1],location,context);continue}let match=(inline===null?mappingPattern:typedMappingPattern).exec(line.content),property=match===null||inline===null?void 0:parseProperty(context,{...line,content:match[1].trimEnd()});if(match!==null&&(inline===null||property!==void 0)){if(property!==void 0){property.isIdentifier&&(context.error(DiagnosticCodes.IdentifierOnEventProperty,`Property '${property.name}' of event '${name}' cannot be marked identifier - an event never carries its event source id`,location),property={...property,isIdentifier:!1});let propertyName=property.name;propertyNames.has(propertyName)&&context.error(DiagnosticCodes.DuplicateDeclaration,`Event '${name}' already declares property '${property.name}'`,location),propertyNames.add(propertyName),properties.push(property)}mappings.push({kind:"PropertyMappingSyntax",property:property?.name??unescapeIdentifier(match[1]),source:parseMappingSource(match[2],location,context),location})}else(inline===null||!metadata.tryParse(context,line))&&context.error(DiagnosticCodes.InvalidPropertyMapping,`Invalid ${inline===null?"":"inline "}property mapping '${line.content}' - expected '<property>${inline===null?"":" <Type>"} = <source>'`,location)}return parent!==header10&&context.skipBlock(header10.indent),{kind:"ProducesSyntax",event:name,mappings,for:target,tags:inline===null?tags:[],location:locationOf(header10),inlineEvent:inline===null?null:{kind:"EventSyntax",name,properties,tags,generation:1,hasGenerationMarker:!1,...metadata.value,location:locationOf(header10)}}}var header2=pattern("^command\\s+([A-Za-z_]\\w*)$"),severityPattern=pattern("\\bseverity\\s+(\\S+)$"),messagePattern=pattern(`\\bmessage\\s+(?:"(${stringBodyPattern})"|(\\$strings\\.\\S*))$`),rulePattern=pattern("^([\\w.]+)\\s+(.+)$"),operandPattern=pattern("^(not empty|length ==|all >=|all >|matches|max|min|rule|>=|<=|==|!=|>|<)\\s*(.*)$"),ruleNamePattern=pattern("^[A-Za-z_]\\w*$"),optionalReads=pattern("^reads\\s+[A-Z]\\w*\\s+optional(?:\\s|$)"),operandKinds={max:"Max",min:"Min",">":"GreaterThan",">=":"GreaterThanOrEqual","<":"LessThan","<=":"LessThanOrEqual","==":"Equal","!=":"NotEqual","length ==":"Length",matches:"Matches","all >":"AllGreaterThan","all >=":"AllGreaterThanOrEqual"},severities={information:"Information",warning:"Warning",error:"Error"},opaqueDirectives=new Set(["reads","handler","concurrency"]),propertyShapedDirectives=new Set(["description","handler","concurrency"]);function parseCommand(context,line){let names=new Set;return parseCommandBody(new ParserContext(context.reader.fork(),context.path),line,void 0,names),parseCommandBody(context,line,names)}function parseCommandBody(context,line,responseNames,discoveredNames){let name=header2.exec(line.content)?.[1]??"";name===""&&context.error(DiagnosticCodes.InvalidCommandDeclaration,`Invalid command declaration '${line.content}' - expected 'command <Name>'`,locationOf(line));let properties=[],responses=[],identifier,validations=[],produces=[],description=null,authorize=null;for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let keyword=firstWord2(child.content),asProperty=tryParseProperty(child);if(asProperty!==void 0&&(propertyShapedDirectives.has(keyword)||keyword==="validate"&&child.content!=="validate csharp"))identifier=addProperty(context,properties,asProperty,name,child,identifier);else if(keyword==="returns"){let scalar=scalarResponsePattern.exec(child.content);scalar!==null&&!scalar[1].startsWith("@")&&asProperty!==void 0?responseNames===void 0?(properties.push(asProperty),responses.push({line:child,candidate:asProperty,response:null})):responseNames.has(asProperty.type.name)?responses.push({line:child,candidate:null,response:parseCommandResponse(context,child)}):identifier=addProperty(context,properties,asProperty,name,child,identifier):asProperty!==void 0?identifier=addProperty(context,properties,asProperty,name,child,identifier):reportInvalidModifierOrder(context,child)?context.skipBlock(child.indent):responses.push({line:child,candidate:null,response:parseCommandResponse(context,child)})}else if(keyword==="description")description=parseDescription(context,child,description,`Command '${name}'`);else if(keyword==="authorize")authorize=combineAuthorize(authorize,parseAuthorize(context,child));else if(keyword==="validate"){let validate=parseValidate(context,child);validate!==void 0&&validations.push(validate)}else if(keyword==="produces"){let production=parseProduces(context,child,!0);production!==void 0&&produces.push(production)}else opaqueDirectives.has(keyword)?(optionalReads.test(child.content)&&context.error(DiagnosticCodes.OptionalReadsNotSupported,"Optional reads are not yet supported (see #308).",locationOf(child)),context.skipOpaqueBlock(child.indent)):asProperty!==void 0?identifier=addProperty(context,properties,asProperty,name,child,identifier):(reportInvalidModifierOrder(context,child),context.error(DiagnosticCodes.UnknownCommandDirective,`Unexpected '${child.content}' in command body`,locationOf(child)),context.skipBlock(child.indent))}let candidates=new Set(responses.flatMap(entry=>entry.candidate===null?[]:[entry.candidate])),names=new Set(properties.filter(property=>!candidates.has(property)).map(property=>property.name));responses.some(entry=>entry.candidate!==null&&!names.has(entry.candidate.type.name)&&entry.candidate.type.name!=="returns")&&names.add("returns");for(let name2 of names)discoveredNames?.add(name2);let response=null,removed=new Set;for(let entry of responses){let parsed=entry.response;if(entry.candidate!==null){if(!names.has(entry.candidate.type.name))continue;removed.add(entry.candidate),parsed={kind:"ScalarCommandResponseSyntax",source:{kind:"PropertyResponseSourceSyntax",property:entry.candidate.type.name,location:entry.candidate.type.location},location:locationOf(entry.line)}}parsed!==null&&(response!==null?context.error(DiagnosticCodes.InvalidCommandResponse,"A command declares at most one unconditional response.",locationOf(entry.line)):response=parsed)}return{kind:"CommandSyntax",name,description,authorize,properties:properties.filter(property=>!removed.has(property)),validations,produces,response,location:locationOf(line)}}function addProperty(context,properties,property,commandName,line,identifier){return reportLegacyOptionalSuffix(context,property.type,line),property.isIdentifier&&identifier!==void 0&&(context.error(DiagnosticCodes.DuplicateCommandIdentifier,`Command '${commandName}' already marks '${identifier.name}' as identifier - only one property can be the identifier`,property.location),property={...property,isIdentifier:!1}),properties.push(property),identifier??(property.isIdentifier?property:void 0)}function parseValidate(context,line){if(line.content==="validate"){let fence=context.peekChild(line.indent);if(fence!==void 0&&fence.content.startsWith("```"))return context.reader.takeSignificant(),context.skipFencedBody(),{kind:"CodeValidateSyntax",location:locationOf(line)};let rules=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){if(context.reader.takeSignificant(),firstWord2(child.content)==="require"){context.skipOpaqueBlock(child.indent);continue}let rule2=parseValidationRule(context,child);rule2!==void 0&&rules.push(rule2)}return{kind:"DeclarativeValidateSyntax",rules,location:locationOf(line)}}if(line.content==="validate csharp")return context.skipOpaqueBlock(line.indent),{kind:"CodeValidateSyntax",location:locationOf(line)};context.error(DiagnosticCodes.InvalidValidateDeclaration,`Invalid validate declaration '${line.content}' - expected 'validate' or 'validate csharp'`,locationOf(line)),context.skipBlock(line.indent)}function parseValidationRule(context,line){let{content:withSeverity,message}=splitMessage(line.content),severity=splitSeverity(context,line,withSeverity);if(severity===void 0)return;let match=rulePattern.exec(severity.content);if(match===null){context.error(DiagnosticCodes.InvalidValidationRule,`Invalid validation rule '${line.content}'`,locationOf(line));return}let parsed=parseRule(context,match[2],line);if(parsed!==void 0)return parsed.kind==="Rule"&&context.skipOpaqueBlock(line.indent),{kind:"ValidationRuleSyntax",property:match[1],rule:parsed.kind,value:parsed.value,message,severity:severity.severity,location:locationOf(line)}}function splitMessage(content){let match=messagePattern.exec(content);if(match===null)return{content,message:null};let message=match[1]!==void 0?unescapeString(match[1]):match[2];return{content:content.substring(0,match.index).trimEnd(),message}}function splitSeverity(context,line,text){let match=severityPattern.exec(text);if(match===null)return{content:text,severity:"Error"};let severity=severities[match[1]];if(severity===void 0){context.error(DiagnosticCodes.InvalidValidationSeverity,`Unknown validation severity '${match[1]}' - expected information, warning or error`,locationOf(line));return}return{content:text.substring(0,match.index).trimEnd(),severity}}function parseRule(context,rule2,line){if(rule2==="not empty")return{kind:"NotEmpty",value:null};let operand2=operandPattern.exec(rule2);if(operand2===null){context.error(DiagnosticCodes.InvalidValidationRule,`Invalid validation rule '${line.content}'`,locationOf(line));return}if(operand2[1]==="rule"){let name=operand2[2].trim();if(!ruleNamePattern.test(name)){context.error(DiagnosticCodes.InvalidRuleName,`Invalid rule name '${name}' in '${line.content}' - expected 'rule <Name>' with an identifier`,locationOf(line));return}return{kind:"Rule",value:{kind:"PathExpressionSyntax",path:name,location:locationOf(line)}}}return{kind:operandKinds[operand2[1]],value:parseMappingSource(operand2[2],locationOf(line),context)}}var header3=pattern("^constraint\\s+([A-Za-z_]\\w*)$"),uniqueEventPattern=pattern("^unique\\s+event\\s+([A-Z]\\w*)$"),uniquePropertyPattern=pattern("^unique\\s+([a-z_][\\w.]*(?:\\s*,\\s*[a-z_][\\w.]*)*)\\s+on\\s+([A-Z]\\w*)$"),releasePattern=pattern("^released\\s+by\\s+([A-Z]\\w*)$"),messagePattern2=pattern(`^message\\s+"(${stringBodyPattern})"$`),targetOf=rule2=>rule2.kind==="FileConstraintSyntax"?void 0:rule2.event;function parseConstraint(context,line){let headerMatch=header3.exec(line.content);headerMatch===null&&context.error(DiagnosticCodes.InvalidConstraintDeclaration,`Invalid constraint declaration '${line.content}' - expected 'constraint <Name>'`,locationOf(line));let name=headerMatch?.[1]??firstWord2(line.content),rules=[],releases=[],releasedEvents=new Set,targets=new Set,message=null,ignoreCasing=!1;for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let release=releasePattern.exec(child.content),text=messagePattern2.exec(child.content);release!==null?releasedEvents.has(release[1])?context.error(DiagnosticCodes.DuplicateConstraintBody,`Constraint '${name}' already releases with event '${release[1]}'`,locationOf(child)):(releases.push(release[1]),releasedEvents.add(release[1])):text!==null?message!==null?context.error(DiagnosticCodes.DuplicateConstraintBody,`Constraint '${name}' already has a message`,locationOf(child)):message=unescapeString(text[1]):child.content==="ignore casing"?(ignoreCasing&&context.error(DiagnosticCodes.DuplicateConstraintBody,`Constraint '${name}' already ignores casing`,locationOf(child)),ignoreCasing=!0):addRule(context,name,child,rules,targets)}for(let release of releases.filter(release2=>targets.has(release2)))context.error(DiagnosticCodes.DuplicateConstraintBody,`Constraint '${name}' cannot target and release event '${release}'`,locationOf(line));return rules.length===0&&(context.error(DiagnosticCodes.ConstraintWithoutRule,`Constraint '${name}' must declare 'unique ... on ...', 'unique event ...' or 'file ...'`,locationOf(line)),rules.push(rule(name,locationOf(line),{kind:"UniqueEventConstraintSyntax",event:""}))),rules[0].kind==="FileConstraintSyntax"&&(releases.length>0||message!==null||ignoreCasing)&&context.error(DiagnosticCodes.InvalidConstraintBody,`File constraint '${name}' cannot have declarative options`,locationOf(line)),{...rules[0],additionalRules:rules.slice(1),releasedBy:releases,message,ignoreCasing}}function addRule(context,name,line,rules,targets){let parsed=parseRule2(context,name,line);if(parsed===void 0)return;if(rules.length>0&&(parsed.kind==="FileConstraintSyntax"||rules[0].kind==="FileConstraintSyntax"||parsed.kind==="UniqueEventConstraintSyntax"!=(rules[0].kind==="UniqueEventConstraintSyntax"))){context.error(DiagnosticCodes.DuplicateConstraintBody,`Constraint '${name}' cannot mix constraint kinds`,locationOf(line));return}let target=targetOf(parsed);if(target!==void 0&&targets.has(target)){context.error(DiagnosticCodes.DuplicateConstraintBody,`Constraint '${name}' already targets event '${target}'`,locationOf(line));return}target!==void 0&&targets.add(target),rules.push(parsed)}function parseRule2(context,name,line){let location=locationOf(line),uniqueEvent=uniqueEventPattern.exec(line.content);if(uniqueEvent!==null)return rule(name,location,{kind:"UniqueEventConstraintSyntax",event:uniqueEvent[1]});let uniqueProperty=uniquePropertyPattern.exec(line.content);if(uniqueProperty!==null){let properties=uniqueProperty[1].split(",").map(property=>property.trim());if(new Set(properties).size!==properties.length){context.error(DiagnosticCodes.DuplicateConstraintBody,`Constraint '${name}' repeats a property in its composite key`,location);return}return rule(name,location,{kind:"UniquePropertyConstraintSyntax",property:properties[0],additionalProperties:properties.slice(1),event:uniqueProperty[2]})}if(isFileDirective(line)){context.warning(DiagnosticCodes.FileConstraintOnlySupportsUniqueness,"A file constraint can only declare unique constraints in Chronicle - declare them with 'unique ...' so they are portable; a rule that is not uniqueness belongs in command validation or a 'require' condition",location);let path=line.content.substring(4).trim();return rule(name,location,{kind:"FileConstraintSyntax",file:{kind:"FileReferenceSyntax",path,location}})}context.error(DiagnosticCodes.InvalidConstraintBody,`Invalid constraint body '${line.content}'`,location)}function rule(name,location,shape){return{...shape,name,additionalRules:[],releasedBy:[],ignoreCasing:!1,message:null,location}}var header4=pattern("^projection\\s+(@?[\\w.]+)\\s*(?:=>\\s*([\\w.]+))?$"),eventSpecPattern=pattern("^(@?[\\w.]+)(?:\\s+key\\s+(.+))?$"),joinPattern=pattern("^join\\s+(@?[\\w.]+)\\s+on\\s+(@?[\\w.]+)$"),withPattern=pattern("^with\\s+(@?[\\w.]+)$"),childrenPattern2=pattern("^children\\s+(@?[\\w.]+)\\s+identified\\s+by\\s+(.+)$"),nestedPattern2=pattern("^nested\\s+(@?[\\w.]+)$"),removeWithPattern=pattern("^remove\\s+with\\s+(@?[\\w.]+)(?:\\s+key\\s+(.+))?$"),removeViaJoinPattern=pattern("^remove\\s+via\\s+join\\s+on\\s+(@?[\\w.]+)(?:\\s+key\\s+(.+))?$"),clearWithPattern=pattern("^clear\\s+with\\s+(@?[\\w.]+)$"),variantPattern=pattern("^variant\\s+(@?[\\w.]+)\\s*$"),entersOnPattern=pattern("^enters\\s+on\\s+(@?[\\w.]+)(?:\\s+key\\s+(.+))?$"),keywordMappingPattern=pattern("^(increment|decrement|count|clear)\\s+(@?[$\\w.]+)$"),arithmeticPattern=pattern("^(add|subtract)\\s+(@?[$\\w.]+)\\s+by\\s+(.+)$"),setPattern=pattern("^set\\s+(@?[$\\w.]+)\\s+(?:=|to)\\s+(.+)$"),assignmentPattern=pattern("^(@?[$\\w.@]+)\\s*=(?!=|>)\\s*(.+)$"),keywordMappings={increment:"IncrementMappingSyntax",decrement:"DecrementMappingSyntax",clear:"ClearMappingSyntax",count:"CountMappingSyntax"};function parseProjection(context,line){let match=header4.exec(line.content);if(match===null)return context.error(DiagnosticCodes.InvalidProjectionDeclaration,`Invalid projection declaration '${line.content}' - expected 'projection <Name> [=> <ReadModel>]'`,locationOf(line)),context.skipBlock(line.indent),{kind:"ProjectionSyntax",name:firstWord2(line.content),readModel:null,sequence:null,autoMap:"Inherit",blocks:[],location:locationOf(line)};let name=match[1],sequence=null,autoMap="Inherit",blocks=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){if(context.reader.takeSignificant(),isFileDirective(child))continue;let keyword=firstWord2(child.content);if(keyword==="sequence")sequence=child.content.substring(8).trim();else if(keyword==="automap")autoMap="Enabled";else if(child.content==="no automap")autoMap="Disabled";else if(keyword==="key")skipKey(context,child);else if(keyword==="variant")blocks.push(parseVariant(context,child));else{let block=parseBlock(context,child,!1);block!==void 0&&blocks.push(block)}}return reportVariantConflicts(context,blocks,name),blocks.length===0&&context.error(DiagnosticCodes.EmptyProjection,`Projection '${name}' must contain at least one directive`,locationOf(line)),{kind:"ProjectionSyntax",name,readModel:match[2]??null,sequence,autoMap,blocks,location:locationOf(line)}}function reportVariantConflicts(context,blocks,name){let variants=blocks.filter(block=>block.kind==="ProjectionVariantSyntax"),byName=new Map;variants.forEach(variant=>byName.set(variant.name,[...byName.get(variant.name)??[],variant]));for(let duplicate of[...byName.values()].flatMap(group=>group.slice(1)))context.error(DiagnosticCodes.DuplicateProjectionVariant,`Duplicate variant '${duplicate.name}' - a variant name is declared once`,duplicate.location);let entering=new Set;for(let entry of blocks.flatMap(block=>block.kind==="ProjectionVariantSyntax"?block.entersOn:[]))entry.event.length>0&&entering.has(entry.event)&&context.error(DiagnosticCodes.DuplicateVariantEnteringEvent,`Entering event '${entry.event}' is claimed more than once in projection '${name}'`,entry.location),entering.add(entry.event)}function parseBlock(context,line,nestedScope){let location=locationOf(line);switch(firstWord2(line.content)){case"from":return parseFrom(context,line);case"every":{let includeChildren=!0,{autoMap,mappings}=parseMappingBlock(context,line,child=>child.content!=="exclude children"?!1:(includeChildren=!1,!0));return{kind:"EverySyntax",includeChildren,autoMap,mappings,location}}case"all":{let{autoMap,mappings}=parseMappingBlock(context,line);return{kind:"AllSyntax",autoMap,mappings,location}}case"join":return parseJoin(context,line);case"children":return parseChildren(context,line);case"nested":return parseNested(context,line);case"remove":return parseRemove(context,line);case"clear":return nestedScope||context.error(DiagnosticCodes.ClearWithOutsideNestedBlock,"'clear with' is only valid inside a nested block",location),parseClearWith(context,line);default:context.error(DiagnosticCodes.UnknownProjectionDirective,`Unexpected '${firstWord2(line.content)}' in projection body`,location),context.skipBlock(line.indent);return}}function parseFrom(context,line){let events=[];for(let spec of splitTopLevel(line.content.substring(4),",")){let text=spec.trim();if(text.length===0){context.error(DiagnosticCodes.FromWithoutEvent,"Expected an event type after 'from'",locationOf(line));continue}let match=eventSpecPattern.exec(text);if(match===null){context.error(DiagnosticCodes.InvalidEventReference,`Invalid event reference '${text}'`,locationOf(line));continue}events.push({kind:"EventSpecSyntax",event:unescapeIdentifier(match[1]),location:locationOf(line)})}let mappings=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let keyword=firstWord2(child.content);keyword==="key"?skipKey(context,child):keyword!=="parent"&&pushMapping(child,mappings)}return{kind:"FromSyntax",events,mappings,location:locationOf(line)}}function parseJoin(context,line){let match=joinPattern.exec(line.content);if(match===null)return context.error(DiagnosticCodes.InvalidJoinDeclaration,`Invalid join declaration '${line.content}' - expected 'join <property> on <key>'`,locationOf(line)),context.skipBlock(line.indent),{kind:"JoinSyntax",property:"",on:"",events:[],location:locationOf(line)};let events=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let withMatch=withPattern.exec(child.content);if(withMatch===null){context.error(DiagnosticCodes.JoinWithoutEvent,`Expected 'with <EventType>' in join block, got '${child.content}'`,locationOf(child)),context.skipBlock(child.indent);continue}let{autoMap,mappings}=parseMappingBlock(context,child);events.push({kind:"JoinEventSyntax",event:unescapeIdentifier(withMatch[1]),autoMap,mappings,location:locationOf(child)})}return{kind:"JoinSyntax",property:unescapeIdentifier(match[1]),on:unescapeIdentifier(match[2]),events,location:locationOf(line)}}function parseChildren(context,line){let match=childrenPattern2.exec(line.content);if(match===null)return context.error(DiagnosticCodes.InvalidChildrenDeclaration,`Invalid children declaration '${line.content}' - expected 'children <collection> identified by <key>'`,locationOf(line)),context.skipBlock(line.indent),{kind:"ChildrenSyntax",property:"",autoMap:"Inherit",blocks:[],location:locationOf(line)};let{autoMap,blocks}=parseChildBlocks(context,line);return{kind:"ChildrenSyntax",property:unescapeIdentifier(match[1]),autoMap,blocks,location:locationOf(line)}}function parseNested(context,line){let match=nestedPattern2.exec(line.content);if(match===null)return context.error(DiagnosticCodes.InvalidNestedDeclaration,`Invalid nested declaration '${line.content}' - expected 'nested <property>'`,locationOf(line)),context.skipBlock(line.indent),{kind:"NestedSyntax",property:"",autoMap:"Inherit",blocks:[],location:locationOf(line)};let property=unescapeIdentifier(match[1]),{autoMap,blocks}=parseChildBlocks(context,line);return blocks.some(block=>block.kind==="FromSyntax")||context.error(DiagnosticCodes.NestedBlockWithoutFrom,`Nested block '${property}' must contain at least one 'from' directive`,locationOf(line)),{kind:"NestedSyntax",property,autoMap,blocks,location:locationOf(line)}}function parseChildBlocks(context,line){let blocks=[],autoMap="Inherit";for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){if(context.reader.takeSignificant(),child.content==="automap"){autoMap="Enabled";continue}if(child.content==="no automap"){autoMap="Disabled";continue}let block=parseBlock(context,child,!0);block!==void 0&&blocks.push(block)}return{autoMap,blocks}}function parseRemove(context,line){let viaJoin=removeViaJoinPattern.exec(line.content);if(viaJoin!==null)return{kind:"RemoveViaJoinSyntax",event:unescapeIdentifier(viaJoin[1]),location:locationOf(line)};let match=removeWithPattern.exec(line.content);if(match===null){context.error(DiagnosticCodes.InvalidRemoveDeclaration,`Invalid remove declaration '${line.content}' - expected 'remove with <EventType>' or 'remove via join on <EventType>'`,locationOf(line)),context.skipBlock(line.indent);return}for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent))context.reader.takeSignificant(),firstWord2(child.content)!=="parent"&&context.error(DiagnosticCodes.UnknownRemoveDirective,`Unexpected '${child.content}' in remove block - only 'parent' is allowed`,locationOf(child));return{kind:"RemoveWithSyntax",event:unescapeIdentifier(match[1]),location:locationOf(line)}}function parseClearWith(context,line){let match=clearWithPattern.exec(line.content);return match===null?(context.error(DiagnosticCodes.InvalidClearDeclaration,`Invalid clear declaration '${line.content}' - expected 'clear with <EventType>'`,locationOf(line)),{kind:"ClearWithSyntax",event:"",location:locationOf(line)}):{kind:"ClearWithSyntax",event:unescapeIdentifier(match[1]),location:locationOf(line)}}function parseVariant(context,line){let match=variantPattern.exec(line.content);if(match===null)return context.error(DiagnosticCodes.InvalidProjectionVariantDeclaration,`Invalid variant declaration '${line.content}' - expected 'variant <Name>'`,locationOf(line)),context.skipBlock(line.indent),{kind:"ProjectionVariantSyntax",name:firstWord2(line.content),entersOn:[],blocks:[],location:locationOf(line)};let name=unescapeIdentifier(match[1]),entersOn=[],blocks=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let keyword=firstWord2(child.content);if(keyword==="enters")entersOn.push(parseEntersOn(context,child));else if(keyword==="variant")context.error(DiagnosticCodes.NestedProjectionVariantNotAllowed,"A variant cannot be declared inside another variant",locationOf(child)),context.skipBlock(child.indent);else{let block=parseBlock(context,child,!1);block!==void 0&&blocks.push(block)}}return entersOn.length===0&&context.error(DiagnosticCodes.VariantRequiresEnteringEvent,`Variant '${name}' must declare at least one 'enters on' event`,locationOf(line)),{kind:"ProjectionVariantSyntax",name,entersOn,blocks,location:locationOf(line)}}function parseEntersOn(context,line){let match=entersOnPattern.exec(line.content);return match===null?(context.error(DiagnosticCodes.InvalidEntersOnDeclaration,`Invalid 'enters on' declaration '${line.content}' - expected 'enters on <EventType> [key <expression>]'`,locationOf(line)),context.skipBlock(line.indent),{kind:"ProjectionEntersOnSyntax",event:"",location:locationOf(line)}):{kind:"ProjectionEntersOnSyntax",event:unescapeIdentifier(match[1]),location:locationOf(line)}}function skipKey(context,line){if(context.peekChild(line.indent)===void 0)return;context.skipBlock(line.indent);let closing=context.reader.peekSignificant();closing!==void 0&&closing.indent===line.indent&&closing.content==="}"&&context.reader.takeSignificant()}function parseMappingBlock(context,line,extra=()=>!1){let autoMap="Inherit",mappings=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent))context.reader.takeSignificant(),child.content==="automap"?autoMap="Enabled":child.content==="no automap"?autoMap="Disabled":extra(child)||pushMapping(child,mappings);return{autoMap,mappings}}function pushMapping(line,mappings){let location=locationOf(line),keyword=keywordMappingPattern.exec(line.content);if(keyword!==null){(keyword[1]!=="clear"||keyword[2]!=="with")&&mappings.push({kind:keywordMappings[keyword[1]],property:unescapeIdentifier(keyword[2]),location});return}let arithmetic=arithmeticPattern.exec(line.content);if(arithmetic!==null){mappings.push({kind:arithmetic[1]==="add"?"AddMappingSyntax":"SubtractMappingSyntax",property:unescapeIdentifier(arithmetic[2]),location});return}let assigned=setPattern.exec(line.content)??assignmentPattern.exec(line.content);assigned!==null&&mappings.push({kind:"SetMappingSyntax",property:unescapeIdentifier(assigned[1]),location})}var header5=pattern("^query\\s+([A-Za-z_]\\w*)\\s*=>\\s*(observable\\s+)?([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?)$"),parameterPattern=pattern("^([a-z_]\\w*)\\s+([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?)(?:\\s+from\\s+(.+))?$"),scopePattern=pattern("^scoped\\s+to\\s+([a-z_]\\w*)$"),opaqueDirectives2=new Set(["performer"]);function parseQuery(context,line){let match=header5.exec(line.content);if(match===null)return context.error(DiagnosticCodes.InvalidQueryDeclaration,`Invalid query declaration '${line.content}' - expected 'query <Name> => [observable] <ReadModel>'`,locationOf(line)),context.skipBlock(line.indent),{kind:"QuerySyntax",name:firstWord2(line.content),returnType:parseTypeRef("",locationOf(line)),by:null,filters:[],description:null,isObservable:!1,scope:null,authorize:null,location:locationOf(line)};let name=match[1],returnType=parseTypeRef(match[3],{...locationOf(line),column:line.indent+1+match[0].length-match[3].length});match[2]===void 0&&returnType.name==="observable"&&returnType.isOptional&&!returnType.isCollection||reportLegacyOptionalSuffix(context,returnType,line);let by=null,filters=[],description=null,scope=null,authorize=null;for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let keyword=firstWord2(child.content);if(keyword==="description")description=parseDescription(context,child,description,`Query '${name}'`);else if(keyword==="by"){let parameter2=parseParameter(context,child,"by");parameter2!==void 0&&(by!==null&&context.error(DiagnosticCodes.InvalidQueryParameter,`Query '${name}' already declares 'by' - a query can have at most one key parameter`,locationOf(child)),by=parameter2)}else if(keyword==="filter"){let filter=parseParameter(context,child,"filter");filter!==void 0&&filters.push(filter)}else keyword==="authorize"?authorize=combineAuthorize(authorize,parseAuthorize(context,child)):keyword==="scoped"?scope=parseScope(context,child,scope,name)??scope:opaqueDirectives2.has(keyword)?context.skipOpaqueBlock(child.indent):(context.error(DiagnosticCodes.UnknownQueryDirective,`Unexpected '${child.content}' in query body - expected description, by, filter, authorize, scoped or performer`,locationOf(child)),context.skipBlock(child.indent))}return{kind:"QuerySyntax",name,returnType,by,filters,description,isObservable:match[2]!==void 0,scope,authorize,location:locationOf(line)}}function parseParameter(context,line,keyword){let match=parameterPattern.exec(line.content.substring(keyword.length).trim());if(match===null){context.error(DiagnosticCodes.InvalidQueryParameter,`Invalid '${keyword}' parameter '${line.content}' - expected '${keyword} <name> <Type> [from <source>]'`,locationOf(line));return}let nameOffset=line.content.indexOf(match[1],keyword.length),type=parseTypeRef(match[2],{...locationOf(line),column:line.indent+1+line.content.indexOf(match[2],nameOffset+match[1].length)});return reportLegacyOptionalSuffix(context,type,line),{kind:"QueryParameterSyntax",name:match[1],type,location:locationOf(line)}}function parseScope(context,line,existing,queryName){let match=scopePattern.exec(line.content);if(match===null){context.error(DiagnosticCodes.InvalidScopeDeclaration,`Invalid scope declaration '${line.content}' - expected 'scoped to <scope>'`,locationOf(line));return}if(existing!==null){context.error(DiagnosticCodes.DuplicateScope,`Query '${queryName}' already declares a scope - results are narrowed one way`,locationOf(line));return}return match[1]}var typedValue=pattern("^@?[a-z_]\\w*\\s+[\\w.]+");function parseTriggerData(context,line){let property=parseProperty(context,line);if(property!==void 0){property.isGenerated&&context.error(DiagnosticCodes.GeneratedPropertyOutsideCommand,"Generated properties can only be declared on commands.",property.location),context.triggerData.push(property);return}typedValue.test(line.content)&&/\?|\boptional\b/.test(line.content)&&context.error(DiagnosticCodes.InvalidTriggerData,`Invalid trigger value '${line.content}' - expected '<name>' or '<name> <Type>'`,locationOf(line)),context.skipOpaqueBlock(line.indent)}function parseTriggerDeclaration(context,header10){for(let line=context.peekChild(header10.indent);line!==void 0;line=context.peekChild(header10.indent))context.reader.takeSignificant(),firstWord2(line.content)==="description"?parseDescription(context,line,null,`Trigger '${header10.content}'`):isFileDirective(line)||parseTriggerData(context,line)}var header6=pattern("^reaction\\s+([A-Za-z_]\\w*)$"),whenPattern=pattern("^when\\s+([A-Za-z_]\\w*)$"),everyPattern=pattern("^every\\s+(\\d+)\\s+(seconds?|minutes?|hours?|days?)$"),atPattern=pattern("^at\\s+(\\d{2}:\\d{2})(?:\\s+on\\s+(?:(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)|day\\s+(\\d{1,2})))?$"),clauseKeywords2=new Set(["when","every","at"]),invokesPattern=pattern("^invokes\\s+([A-Z]\\w*)$"),optionalReads2=pattern("^reads\\s+[A-Z]\\w*\\s+optional(?:\\s|$)");function parseReaction(context,line){let name=header6.exec(line.content)?.[1]??"";name===""&&context.error(DiagnosticCodes.InvalidReactionDeclaration,`Invalid reaction declaration '${line.content}' - expected 'reaction <Name>'`,locationOf(line));let description=null,triggers=[],sources=new Set,reported=!1;for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let keyword=firstWord2(child.content);if(keyword==="description"){description=parseDescription(context,child,description,`Reaction '${name}'`);continue}if(keyword==="where")continue;if(!clauseKeywords2.has(keyword)){context.error(DiagnosticCodes.InvalidReactionTrigger,`Expected a trigger in reaction body, got '${child.content}' - a reaction is set off by 'when <Name>', 'every <n> <unit>' or 'at <HH:mm>'`,locationOf(child)),context.skipBlock(child.indent),reported=!0;continue}let source=parseTriggerSource(context,child);if(source===void 0){reported=!0;continue}let key=sourceKey(source);if(sources.has(key)){context.error(DiagnosticCodes.DuplicateReactionTrigger,`Reaction '${name}' already declares '${child.content}' - a second says nothing the first did not`,locationOf(child)),context.skipBlock(child.indent);continue}sources.add(key),triggers.push(parseTrigger(context,child,source))}return triggers.length===0&&!reported&&context.error(DiagnosticCodes.ReactionWithoutTrigger,`Reaction '${name}' must declare at least one trigger - nothing sets it off`,locationOf(line)),{kind:"ReactionSyntax",name,description,triggers,location:locationOf(line)}}function parseTrigger(context,line,source){let description=null,produces=[],invokes=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let keyword=firstWord2(child.content);if(keyword==="description")description=parseDescription(context,child,description,`Trigger '${child.content}'`);else if(keyword==="produces"){let produced=parseProduces(context,child);produced!==void 0&&produces.push(produced)}else if(keyword==="invokes"){let match=invokesPattern.exec(child.content);match===null?(context.error(DiagnosticCodes.InvalidInvokesDeclaration,`Invalid invokes declaration '${child.content}' - expected 'invokes <Command>'`,locationOf(child)),context.skipBlock(child.indent)):(invokes.push({kind:"InvokesSyntax",command:match[1],location:locationOf(child)}),collectInputUses(context,child))}else keyword==="reads"||keyword==="file"||child.content==="csharp"||child.content.startsWith("```")?(optionalReads2.test(child.content)&&context.error(DiagnosticCodes.OptionalReadsNotSupported,"Optional reads are not yet supported (see #308).",locationOf(child)),child.content.startsWith("```")&&context.skipFencedBody(),context.skipOpaqueBlock(child.indent)):parseTriggerData(context,child)}return{kind:"ReactionTriggerSyntax",source,description,produces,invokes,location:locationOf(line)}}function sourceKey(source){switch(source.kind){case"NamedTriggerSourceSyntax":return JSON.stringify([source.kind,source.name]);case"IntervalTriggerSourceSyntax":return JSON.stringify([source.kind,source.amount,source.unit]);case"ScheduleTriggerSourceSyntax":return JSON.stringify([source.kind,source.time,source.dayOfWeek,source.dayOfMonth])}}function parseTriggerSource(context,line){let location=locationOf(line);switch(firstWord2(line.content)){case"when":{let match=whenPattern.exec(line.content);if(match===null){context.error(DiagnosticCodes.InvalidReactionTrigger,`Invalid trigger '${line.content}' - expected 'when <Name>'`,location),context.skipBlock(line.indent);return}return{kind:"NamedTriggerSourceSyntax",name:match[1],location}}case"every":{let match=everyPattern.exec(line.content),amount=match===null?NaN:Number(match[1]);if(match===null||!Number.isInteger(amount)||amount<1||amount>2147483647){context.error(DiagnosticCodes.InvalidIntervalTrigger,`Invalid interval '${line.content}' - expected 'every <n> <seconds|minutes|hours|days>'`,location),context.skipBlock(line.indent);return}return{kind:"IntervalTriggerSourceSyntax",amount,unit:unitOf(match[2]),location}}default:return parseSchedule(context,line)}}function parseSchedule(context,line){let location=locationOf(line),match=atPattern.exec(line.content),time=match===null?void 0:timeOf(match[1]);if(match===null||time===void 0){context.error(DiagnosticCodes.InvalidScheduleTrigger,`Invalid schedule '${line.content}' - expected 'at <HH:mm>', optionally followed by 'on <Weekday>' or 'on day <n>'`,location),context.skipBlock(line.indent);return}if(match[3]!==void 0){let day=Number(match[3]);if(day<1||day>31){context.error(DiagnosticCodes.InvalidScheduleTrigger,`Invalid day of month '${day}' in '${line.content}' - a day of the month is between 1 and 31`,location),context.skipBlock(line.indent);return}return{kind:"ScheduleTriggerSourceSyntax",time,dayOfWeek:null,dayOfMonth:day,location}}return{kind:"ScheduleTriggerSourceSyntax",time,dayOfWeek:match[2]??null,dayOfMonth:null,location}}function timeOf(text){let[hours,minutes]=text.split(":").map(Number);if(hours>=0&&hours<=23&&minutes>=0&&minutes<=59)return`${text}:00.0000000`}function unitOf(text){switch(text.replace(/s+$/,"")){case"second":return"Seconds";case"minute":return"Minutes";case"hour":return"Hours";default:return"Days"}}var operand=`(?:"(${stringBodyPattern})"|(\\$strings\\.\\w+(?:\\.\\w+)*))`,header7=pattern("^screen\\s+([A-Za-z_]\\w*)$"),data=pattern("^data\\s+([\\w.]+(?:\\[\\])?)\\s+via\\s+query\\s+(\\w+(?:\\.\\w+)*)(?:\\s+by\\s+(\\w+))?$"),action=pattern("^action\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$"),label=pattern(`^label\\s+${operand}$`),navigate=pattern("^navigate\\s+to\\s+(\\w+(?:\\.\\w+)*)(?:\\s+by\\s+(\\w+))?$"),slot=pattern("^[a-z_]\\w*$"),title=pattern(`^title\\s+${operand}$`),column=pattern(`^column\\s+([\\w.]+)(?:\\s+label\\s+${operand})?$`),rowClick=pattern("^on\\s+row-click\\s+(navigate\\s+to\\s+.+)$"),field2=pattern(`^field\\s+([\\w.]+)\\s+label\\s+${operand}$`),inlineLanguages=new Set(["csharp","typescript","react","html","sql"]),operandText=(match,quotedGroup)=>match[quotedGroup]!==void 0?unescapeString(match[quotedGroup]):match[quotedGroup+1],isInteraction=line=>["on","uses"].includes(firstWord2(line.content)),isCodeLine=line=>line.content.startsWith("```")||inlineLanguages.has(line.content);function parseScreen(context,line){let match=header7.exec(line.content);match===null&&context.error(DiagnosticCodes.InvalidScreenDeclaration,`Invalid screen declaration '${line.content}' - expected 'screen <Name>'`,locationOf(line));let directives=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent))context.reader.takeSignificant(),isFileDirective(child)||pushDirective(context,child,directives);return{kind:"ScreenSyntax",name:match?.[1]??"",directives,location:locationOf(line)}}function pushDirective(context,line,directives){let directive=parseDirective(context,line);directive!==void 0&&directives.push(directive)}function parseDirectives(context,parent){let directives=[];for(let child=context.peekChild(parent.indent);child!==void 0;child=context.peekChild(parent.indent))context.reader.takeSignificant(),pushDirective(context,child,directives);return directives}function parseDirective(context,line){switch(firstWord2(line.content)){case"data":return parseData(context,line);case"action":return parseAction(context,line);case"template":return parseTemplateReference(context,line);case"section":return parseSection(context,line);case"title":return parseTitle(context,line);case"table":return parseTable(context,line);case"summary":return parseSummary(context,line);case"navigate":return parseNavigate(context,line.content,line);case"on":return collectInputUses(context,line),{kind:"ScreenBehaviorSyntax",location:locationOf(line)};case"uses":return context.skipOpaqueBlock(line.indent),{kind:"ScreenUsesBehaviorSyntax",location:locationOf(line)};default:if(isCodeLine(line))return parseCode(context,line);context.error(DiagnosticCodes.UnknownScreenDirective,`Unexpected '${line.content}' in screen body`,locationOf(line)),context.skipBlock(line.indent);return}}function parseData(context,line){let match=data.exec(line.content);if(match===null){context.error(DiagnosticCodes.InvalidDataDirective,`Invalid data directive '${line.content}' - expected 'data <ReadModel> via query <Query> [by <param>]'`,locationOf(line));return}return{kind:"ScreenDataSyntax",type:parseTypeRef(match[1],locationOf(line)),query:match[2],by:match[3]??null,location:locationOf(line)}}function parseAction(context,line){let match=action.exec(line.content);if(match===null){context.error(DiagnosticCodes.InvalidActionDirective,`Invalid action directive '${line.content}' - expected 'action <Command>'`,locationOf(line)),context.skipBlock(line.indent);return}let text=null,target=null;for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let labelMatch=label.exec(child.content);labelMatch!==null?text=operandText(labelMatch,1):firstWord2(child.content)==="navigate"?target=parseNavigate(context,child.content,child)??null:context.error(DiagnosticCodes.UnknownActionDirective,`Unexpected '${child.content}' in action - expected 'label "..."' or 'navigate to ...'`,locationOf(child))}return{kind:"ScreenActionSyntax",command:match[1],label:text,navigate:target,location:locationOf(line)}}function parseNavigate(context,text,line){let match=navigate.exec(text);if(match===null){context.error(DiagnosticCodes.InvalidNavigation,`Invalid navigation '${text}' - expected 'navigate to <Screen> [by <param>]'`,locationOf(line));return}return{kind:"ScreenNavigateSyntax",screen:match[1],by:match[2]??null,location:locationOf(line)}}function parseTemplateReference(context,line){let name=line.content.substring(8).trim(),slots=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){if(context.reader.takeSignificant(),!slot.test(child.content)){context.error(DiagnosticCodes.InvalidScreenLayoutSlot,`Expected a slot name in template '${name}', got '${child.content}'`,locationOf(child)),context.skipBlock(child.indent);continue}slots.push({kind:"ScreenSlotSyntax",name:child.content,directives:parseDirectives(context,child),location:locationOf(child)})}return{kind:"ScreenTemplateReferenceSyntax",name,slots,location:locationOf(line)}}function parseSection(context,line){return{kind:"ScreenSectionSyntax",name:line.content.substring(7).trim(),directives:parseDirectives(context,line),location:locationOf(line)}}function parseTitle(context,line){let match=title.exec(line.content);return match===null?(context.error(DiagnosticCodes.InvalidTitleDirective,`Invalid title directive '${line.content}' - expected 'title "..."'`,locationOf(line)),{kind:"ScreenTitleSyntax",text:"",location:locationOf(line)}):{kind:"ScreenTitleSyntax",text:operandText(match,1),location:locationOf(line)}}function parseTable(context,line){let target=line.content.substring(5).trim(),columns=[],click=null;for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let columnMatch=column.exec(child.content),clickMatch=rowClick.exec(child.content);if(columnMatch!==null){let labelled=columnMatch[2]!==void 0||columnMatch[3]!==void 0;columns.push({kind:"ScreenColumnSyntax",property:columnMatch[1],label:labelled?operandText(columnMatch,2):null,location:locationOf(child)})}else clickMatch!==null?click=parseNavigate(context,clickMatch[1],child)??null:firstWord2(child.content)==="on"?collectInputUses(context,child):isInteraction(child)?context.skipOpaqueBlock(child.indent):context.error(DiagnosticCodes.UnknownTableDirective,`Unexpected '${child.content}' in table - expected 'column ...', 'on row-click navigate to ...', 'on <trigger>' or 'uses <Behavior>'`,locationOf(child))}return{kind:"ScreenTableSyntax",target,columns,rowClick:click,location:locationOf(line)}}function parseSummary(context,line){let target=line.content.substring(7).trim(),fields=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let match=field2.exec(child.content);if(match===null){context.error(DiagnosticCodes.UnknownSummaryDirective,`Unexpected '${child.content}' in summary - expected 'field <property> label "..."'`,locationOf(child));continue}fields.push({kind:"ScreenFieldSyntax",property:match[1],label:operandText(match,2),location:locationOf(child)})}return{kind:"ScreenSummarySyntax",target,fields,location:locationOf(line)}}function parseCode(context,line){let language=line.content.startsWith("```")?line.content.substring(3):line.content;if(!inlineLanguages.has(language)){context.error(DiagnosticCodes.ExpectedCodeFence,`Expected a registered language on the opening fence, not '${line.content}'`,locationOf(line));return}line.content.startsWith("```")||context.warning(DiagnosticCodes.LegacyInlineCodeFence,`'${language}' on its own line is deprecated - use '\`\`\`${language}' instead`,locationOf(line));let code=parseFencedText(context,language,line);return code===null?void 0:{kind:"ScreenCodeSyntax",code:{kind:"CodeBlockSyntax",language,code,location:locationOf(line)},location:locationOf(line)}}var thenReturnsPrefix=pattern("^then\\s+returns\\b"),generatedFixturePrefix=pattern("^generated\\s+(?=\\S)(?![=])"),generatedFixturePattern=pattern("^generated\\s+([a-z_]\\w*)\\s*=(?!=|>)\\s*(.+)$"),fieldPattern2=pattern("^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$"),quotedValue=pattern(`^(?:"${stringBodyPattern}"|'(?:[^'\\\\]|\\\\.)*')$`);function parseConcrete(context,text,location,code){if((text.startsWith('"')||text.startsWith("'"))&&!quotedValue.test(text))return context.error(code,"Expected exactly one concrete value.",location),null;let expression=parseMappingSource(text,location,context);return!["LiteralExpressionSyntax","ObjectExpressionSyntax","ListExpressionSyntax"].includes(expression.kind)||expression.kind==="LiteralExpressionSyntax"&&typeof expression.value=="number"&&!Number.isFinite(expression.value)?(context.error(code,"Expected exactly one concrete literal or structured value, not an expression.",location),null):expression}function parseConcreteMapping(context,line,regex,code){let match=regex.exec(line.content);if(match===null)return context.error(code,"Expected a named fixture or assertion with exactly one concrete value.",locationOf(line)),context.skipBlock(line.indent),null;let location=locationOf(line),source=parseConcrete(context,match[2],{...location,column:location.column+line.content.indexOf(match[2],line.content.indexOf("=")+1)},code),child=context.peekChild(line.indent);return child!==void 0&&(context.error(code,"A fixture or return field cannot have child directives.",locationOf(child)),context.skipBlock(line.indent)),source===null?null:{kind:"PropertyMappingSyntax",property:match[1],source,location}}function parseReturn(context,line){let prefix=thenReturnsPrefix.exec(line.content)[0].length,value=line.content.substring(prefix).trim(),location=locationOf(line);if(value.length>0){let concrete=parseConcrete(context,value,{...location,column:location.column+line.content.indexOf(value,prefix)},DiagnosticCodes.InvalidReturnExpectation),child=context.peekChild(line.indent);return child!==void 0&&(context.error(DiagnosticCodes.InvalidReturnExpectation,"A scalar return expectation cannot have child assertions.",locationOf(child)),context.skipBlock(line.indent)),concrete===null?null:{kind:"ScalarSpecificationReturnSyntax",value:concrete,location}}let fields=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let field3=parseConcreteMapping(context,child,fieldPattern2,DiagnosticCodes.InvalidReturnExpectation);field3!==null&&fields.push(field3)}return{kind:"RecordSpecificationReturnSyntax",fields,location}}var header8=pattern("^specification\\s+([A-Za-z_]\\w*)$"),givenPattern=pattern("^given\\s+([A-Z]\\w*)$"),whenAppendPattern=pattern("^when\\s+append\\s+([A-Z]\\w*)$"),whenPattern2=pattern("^when\\s+([A-Z]\\w*)$"),thenEventPattern=pattern("^then\\s+([A-Z]\\w*)$"),thenQueryPrefix=pattern("^then\\s+query\\b"),readModelPrefix=pattern("^(?:given|then)\\s+readmodel\\b"),givenReadModelPattern=pattern("^given\\s+readmodel\\s+([A-Z]\\w*)$"),thenReadModelPattern=pattern("^then\\s+readmodel\\s+([A-Z]\\w*)(\\s+exactly)?$"),thenNoPrefix=pattern("^then\\s+no\\b"),thenErrorPattern=pattern(`^then\\s+error\\s+"(${stringBodyPattern})"$`),mappingPattern2=pattern("^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$"),givenClockPrefix=pattern("^given\\s+clock\\b"),givenCapturePrefix=pattern("^given\\s+capture\\b"),whenClockPrefix=pattern("^when\\s+clock\\b"),whenTriggerPrefix=pattern("^when\\s+trigger\\b"),whenCapturePrefix=pattern("^when\\s+capture\\b"),whenQueryPrefix=pattern("^when\\s+query\\b"),thenResultPrefix=pattern("^then\\s+result\\b"),noResultPrefix=pattern("^then\\s+no\\s+result\\b"),clockPattern=pattern('^(given|when)\\s+clock\\s+"(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:\\d{2}))"$'),whenTriggerPattern=pattern("^when\\s+trigger\\s+([A-Za-z_]\\w*)$"),capturePattern=pattern("^(?:given|when)\\s+capture\\s+([A-Za-z_]\\w*)$"),whenQueryPattern=pattern("^when\\s+query\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$"),thenResultPattern=pattern("^then\\s+result(\\s+exactly)?$");function parseSpecification(context,line){let name=header8.exec(line.content)?.[1]??"";name===""&&context.error(DiagnosticCodes.InvalidSpecificationDeclaration,`Invalid specification declaration '${line.content}' - expected 'specification <Name>'`,locationOf(line));let body={given:[],givenReadModels:[],when:null,whenAppended:null,whenDeclared:!1,thenEvents:[],thenEventsInAnyOrder:!1,thenReadModels:[],thenErrors:[],givenClock:null,givenCaptures:[],whenClock:null,whenTrigger:null,whenCapture:null,whenQuery:null,thenResults:[],thenNoResult:null,thenDenied:null,thenReturns:null};for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){if(context.reader.takeSignificant(),isFileDirective(child))continue;let keyword=thenNoPrefix.test(child.content)?"then":firstWord2(child.content);keyword==="given"?parseGiven(context,child,body):keyword==="when"?parseWhen(context,child,body,name):keyword==="then"?parseThen(context,child,body):(context.error(DiagnosticCodes.UnknownSpecificationDirective,`Unexpected '${firstWord2(child.content)}' in specification body`,locationOf(child)),context.skipBlock(child.indent))}let{whenDeclared:_,...members}=body;return{kind:"SpecificationSyntax",name,...members,location:locationOf(line)}}function parseGiven(context,line,body){if(givenClockPrefix.test(line.content))body.givenClock!==null?(context.error(DiagnosticCodes.InvalidSpecificationClock,"A specification states its clock at most once.",locationOf(line)),context.skipBlock(line.indent)):body.givenClock=parseClock(context,line,"given");else if(givenCapturePrefix.test(line.content)){let capture=parseCapture2(context,line,"given");capture!==null&&body.givenCaptures.push(capture)}else if(line.content.startsWith("given caller"))context.skipOpaqueBlock(line.indent);else if(readModelPrefix.test(line.content)){let readModel=parseReadModelStep(context,line,givenReadModelPattern,"given");readModel!==void 0&&body.givenReadModels.push(readModel)}else{let event=parseEventStep(context,line,givenPattern,"given");event!==void 0&&body.given.push(event)}}function parseWhen(context,line,body,name){let appends=line.content.startsWith("when append");if(body.whenDeclared){let code=body.whenAppended!==null||appends?DiagnosticCodes.ConflictingSpecificationActions:DiagnosticCodes.DuplicateSpecificationWhen;context.error(code,`Specification '${name}' already declares a 'when' - a specification can have at most one`,locationOf(line)),context.skipBlock(line.indent);return}if(body.whenDeclared=!0,appends){body.whenAppended=parseEventStep(context,line,whenAppendPattern,"when append")??null;return}if(whenClockPrefix.test(line.content)){body.whenClock=parseClock(context,line,"when");return}if(whenTriggerPrefix.test(line.content)){body.whenTrigger=parseNamedStep(context,line,whenTriggerPattern,DiagnosticCodes.InvalidSpecificationTrigger,"when trigger","when trigger <Trigger>",(trigger,values2)=>({kind:"SpecificationTriggerSyntax",trigger,values:values2,location:locationOf(line)}));return}if(whenCapturePrefix.test(line.content)){body.whenCapture=parseCapture2(context,line,"when");return}if(whenQueryPrefix.test(line.content)){body.whenQuery=parseNamedStep(context,line,whenQueryPattern,DiagnosticCodes.InvalidSpecificationQueryAction,"when query","when query <Query>",(query,values2)=>({kind:"SpecificationWhenQuerySyntax",query,arguments:values2,location:locationOf(line)}));return}let match=whenPattern2.exec(line.content);if(match===null){context.error(DiagnosticCodes.InvalidSpecificationWhen,`Invalid 'when' declaration '${line.content}' - expected 'when <CommandType>' or 'when append <EventType>'`,locationOf(line)),context.skipBlock(line.indent);return}let generatedValues=[],values=parseValuesWithEventSource(context,line,generatedValues);body.when={kind:"SpecificationCommandSyntax",commandType:match[1],...values,generatedValues,location:locationOf(line)}}function parseThen(context,line,body){if(thenReturnsPrefix.test(line.content)){let expectation=parseReturn(context,line);body.thenReturns!==null?context.error(DiagnosticCodes.InvalidReturnExpectation,"A specification declares at most one return expectation.",locationOf(line)):body.thenReturns=expectation;return}if(line.content.startsWith("then events")){line.content!=="then events in any order"||body.thenEventsInAnyOrder?context.error(DiagnosticCodes.InvalidSpecificationEventOrder,"Expected one 'then events in any order' directive.",locationOf(line)):body.thenEventsInAnyOrder=!0,context.skipBlock(line.indent);return}if(thenResultPrefix.test(line.content)){parseResult(context,line,body);return}if(noResultPrefix.test(line.content)){line.content!=="then no result"||body.thenNoResult!==null?context.error(DiagnosticCodes.InvalidSpecificationQueryAction,"Expected one 'then no result' directive.",locationOf(line)):body.thenNoResult={kind:"SpecificationNoResultSyntax",location:locationOf(line)},context.skipBlock(line.indent);return}if(line.content.startsWith("then denied")){line.content!=="then denied"?(context.error(DiagnosticCodes.InvalidSpecificationDenied,"Expected exactly 'then denied'.",locationOf(line)),context.skipBlock(line.indent)):body.thenDenied!==null?context.error(DiagnosticCodes.DuplicateSpecificationCallerOrDenied,"A specification has at most one 'then denied' outcome.",locationOf(line)):body.thenDenied={kind:"SpecificationDeniedSyntax",location:locationOf(line)};return}if(line.content==="then error"){body.thenErrors.push({kind:"SpecificationErrorSyntax",name:null,location:locationOf(line)});return}let error2=thenErrorPattern.exec(line.content);if(error2!==null){body.thenErrors.push({kind:"SpecificationErrorSyntax",name:unescapeString(error2[1]),location:locationOf(line)});return}if(firstWord2(line.content.substring(4).trim())==="error"){context.error(DiagnosticCodes.InvalidThenError,`Invalid 'then error' declaration '${line.content}' - expected 'then error' or 'then error "<reason>"'`,locationOf(line)),context.skipBlock(line.indent);return}if(thenNoPrefix.test(line.content)||thenQueryPrefix.test(line.content)){context.skipOpaqueBlock(line.indent);return}if(readModelPrefix.test(line.content)){let readModel=parseReadModelStep(context,line,thenReadModelPattern,"then");readModel!==void 0&&body.thenReadModels.push(readModel);return}let event=parseEventStep(context,line,thenEventPattern,"then");event!==void 0&&body.thenEvents.push(event)}function parseClock(context,line,keyword){let match=clockPattern.exec(line.content);return context.skipBlock(line.indent),match===null||match[1]!==keyword?(context.error(DiagnosticCodes.InvalidSpecificationClock,`Invalid '${keyword} clock' - expected '${keyword} clock "<ISO 8601 instant>"', such as '${keyword} clock "2026-10-05T08:00:00Z"'`,locationOf(line)),null):{kind:"SpecificationClockSyntax",instant:match[2],location:locationOf(line)}}function parseCapture2(context,line,keyword){return parseNamedStep(context,line,capturePattern,DiagnosticCodes.InvalidSpecificationCapture,`${keyword} capture`,`${keyword} capture <Capture>`,(capture,record)=>({kind:"SpecificationCaptureSyntax",capture,record,location:locationOf(line)}))}function parseNamedStep(context,line,regex,code,keyword,expected,create){let match=regex.exec(line.content);return match===null?(context.error(code,`Invalid '${keyword}' declaration '${line.content}' - expected '${expected}'`,locationOf(line)),context.skipBlock(line.indent),null):create(match[1],parseValues(context,line))}function parseResult(context,line,body){let match=thenResultPattern.exec(line.content);if(match===null){context.error(DiagnosticCodes.InvalidSpecificationQueryAction,`Invalid 'then result' declaration '${line.content}' - expected 'then result [exactly]'`,locationOf(line)),context.skipBlock(line.indent);return}body.thenResults.push({kind:"SpecificationQueryResultSyntax",properties:parseValues(context,line),exactly:match[1]!==void 0,location:locationOf(line)})}function parseReadModelStep(context,line,regex,keyword){let match=regex.exec(line.content);if(match===null){context.error(DiagnosticCodes.InvalidReadModelStep,`Invalid '${keyword} readmodel' declaration '${line.content}' - expected '${keyword} readmodel <ReadModelType>'`,locationOf(line)),context.skipBlock(line.indent);return}return{kind:"SpecificationReadModelSyntax",name:match[1],properties:parseValues(context,line),exactly:keyword==="then"&&match[2]!==void 0,location:locationOf(line)}}function parseEventStep(context,line,regex,keyword){let match=regex.exec(line.content);if(match===null){context.error(DiagnosticCodes.InvalidEventStep,`Invalid '${keyword}' declaration '${line.content}' - expected '${keyword} <EventType>'`,locationOf(line)),context.skipBlock(line.indent);return}return{kind:"SpecificationEventSyntax",eventType:match[1],...parseValuesWithEventSource(context,line),location:locationOf(line)}}function parseValuesWithEventSource(context,parent,generated){let values=[],eventSource=null;for(let child=context.peekChild(parent.indent);child!==void 0;child=context.peekChild(parent.indent)){if(context.reader.takeSignificant(),generated!==void 0&&generatedFixturePrefix.test(child.content)){let fixture=parseConcreteMapping(context,child,generatedFixturePattern,DiagnosticCodes.InvalidGeneratedFixture);fixture!==null&&generated.push(fixture);continue}let mapping2=mappingPattern2.exec(child.content);if(mapping2!==null)values.push(mappingOf(context,child,mapping2));else if(firstWord2(child.content)==="for"){let source=child.content.substring(3).trim();source.length===0?context.error(DiagnosticCodes.InvalidSpecificationEventSource,"Invalid event-source assertion 'for' - expected 'for <value>'",locationOf(child)):eventSource!==null?context.error(DiagnosticCodes.DuplicateSpecificationEventSource,"A specification step can declare its event-source assertion only once",locationOf(child)):eventSource=parseMappingSource(source,locationOf(child),context)}else context.error(DiagnosticCodes.InvalidSpecificationValue,`Invalid property mapping '${child.content}' - expected '<property> = <value>'`,locationOf(child))}return{values,for:eventSource}}function parseValues(context,parent){let values=[];for(let child=context.peekChild(parent.indent);child!==void 0;child=context.peekChild(parent.indent)){context.reader.takeSignificant();let mapping2=mappingPattern2.exec(child.content);if(mapping2===null){context.error(DiagnosticCodes.InvalidSpecificationValue,`Invalid property mapping '${child.content}' - expected '<property> = <value>'`,locationOf(child));continue}values.push(mappingOf(context,child,mapping2))}return values}function mappingOf(context,line,match){return{kind:"PropertyMappingSyntax",property:match[1],source:parseMappingSource(match[2],locationOf(line),context),location:locationOf(line)}}var header9=pattern("^slice\\s+([A-Za-z]\\w*)\\s+([A-Za-z_]\\w*)$"),opaqueMembers=new Set(["reducer"]);function parseSlice(context,line){let match=header9.exec(line.content),type="StateChange",name="";match===null?context.error(DiagnosticCodes.InvalidSliceDeclaration,`Invalid slice declaration '${line.content}' - expected 'slice <Type> <Name>'`,locationOf(line)):(name=match[2],sliceTypes2.includes(match[1])?type=match[1]:context.error(DiagnosticCodes.UnknownSliceType,`Unknown slice type '${match[1]}' - expected StateChange, StateView, Automation or Translate`,locationOf(line)));let previous=context.scope;context.scope=[...previous,name];let description=null,events=[],commands=[],queries=[],projections=[],reactions=[],captures=[],constraints=[],specifications=[],readModels=[],screens=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){if(context.reader.takeSignificant(),isFileDirective(child))continue;let keyword=firstWord2(child.content);keyword==="description"?description=parseDescription(context,child,description,`Slice '${name}'`):keyword==="event"?events.push(parseEvent(context,child)):keyword==="command"?commands.push(parseCommand(context,child)):keyword==="query"?queries.push(parseQuery(context,child)):keyword==="projection"?projections.push(parseProjection(context,child)):keyword==="capture"?captures.push(parseCapture(context,child)):keyword==="reaction"?reactions.push(parseReaction(context,child)):keyword==="constraint"?constraints.push(parseConstraint(context,child)):keyword==="specification"?specifications.push(parseSpecification(context,child)):keyword==="readmodel"?readModels.push(parseReadModel(context,child)):keyword==="screen"?screens.push(parseScreen(context,child)):opaqueMembers.has(keyword)?context.skipOpaqueBlock(child.indent):(context.warning(DiagnosticCodes.UnknownSliceDirective,`Unknown construct '${keyword}' in slice '${name}'`,locationOf(child)),context.skipBlock(child.indent))}return context.scope=previous,{kind:"SliceSyntax",type,name,description,events,commands,queries,projections,captures,reactions,constraints,specifications,readModels,screens,location:locationOf(line)}}var featurePattern=pattern("^feature\\s+([A-Za-z_]\\w*)$"),opaqueFeatureMembers=new Set(["on","uses","contribute"]),featureBodyExpected="description, authorize, import, feature, slice, contribute, 'on <trigger>' or 'uses <Behavior>'",FeatureBody=class{name;#features=[];#slices=[];#fileImports=[];#description=null;#authorize=null;constructor(name){this.name=name}tryParse(context,line){let keyword=firstWord2(line.content);switch(keyword){case"description":return this.#description=parseDescription(context,line,this.#description,`Feature '${this.name}'`),!0;case"authorize":return this.#authorize=combineAuthorize(this.#authorize,parseAuthorize(context,line)),!0;case"import":return parseFileImport(context,line,this.#fileImports),!0;case"feature":return this.#features.push(parseFeature(context,line)),!0;case"slice":return this.#slices.push(parseSlice(context,line)),!0;default:return opaqueFeatureMembers.has(keyword)?(collectInputUses(context,line),!0):!1}}build(location,isPlacement=!1){return{kind:"FeatureSyntax",name:this.name,description:this.#description,authorize:this.#authorize,features:this.#features,slices:this.#slices,fileImports:this.#fileImports,isPlacement,location}}};function parseFeature(context,line){let name=featurePattern.exec(line.content)?.[1]??"";name===""&&context.error(DiagnosticCodes.InvalidFeatureDeclaration,`Invalid feature declaration '${line.content}' - expected 'feature <Name>'`,locationOf(line));let body=new FeatureBody(name),previous=context.scope;context.scope=[...previous,name];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent))context.reader.takeSignificant(),body.tryParse(context,child)||(context.error(DiagnosticCodes.UnknownFeatureDirective,`Unexpected '${firstWord2(child.content)}' in feature body - expected ${featureBodyExpected}`,locationOf(child)),context.skipBlock(child.indent));return context.scope=previous,body.build(locationOf(line))}var modulePattern=pattern("^module\\s+([A-Za-z_]\\w*)$"),opaqueModuleMembers=new Set(["on","uses","screen","dialog","form","contribute"]),moduleBodyExpected="description, authorize, import, screen template, dialog template, form, contribute, feature, 'on <trigger>' or 'uses <Behavior>'",ModuleBody=class{name;#features=[];#fileImports=[];#description=null;#authorize=null;constructor(name){this.name=name}tryParse(context,line){let keyword=firstWord2(line.content);switch(keyword){case"description":return this.#description=parseDescription(context,line,this.#description,`Module '${this.name}'`),!0;case"authorize":return this.#authorize=combineAuthorize(this.#authorize,parseAuthorize(context,line)),!0;case"import":return parseFileImport(context,line,this.#fileImports),!0;case"feature":return this.#features.push(parseFeature(context,line)),!0;default:return opaqueModuleMembers.has(keyword)?(collectInputUses(context,line),!0):!1}}parseChildren(context,line){for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent))context.reader.takeSignificant(),this.tryParse(context,child)||(context.error(DiagnosticCodes.UnknownModuleDirective,`Unexpected '${firstWord2(child.content)}' in module body - expected ${moduleBodyExpected}`,locationOf(child)),context.skipBlock(child.indent))}build(location,isPlacement=!1){return{kind:"ModuleSyntax",name:this.name,description:this.#description,authorize:this.#authorize,features:this.#features,fileImports:this.#fileImports,isPlacement,location}}};function parseModule(context,line){let name=modulePattern.exec(line.content)?.[1]??"";name===""&&context.error(DiagnosticCodes.InvalidModuleDeclaration,`Invalid module declaration '${line.content}' - expected 'module <Name>'`,locationOf(line));let body=new ModuleBody(name),previous=context.scope;return context.scope=[name],body.parseChildren(context,line),context.scope=previous,body.build(locationOf(line))}var date=/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/,dateTime=/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:\.[0-9]{1,7})?(?:Z|[+-]([0-9]{2}):([0-9]{2}))$/;function responseDateValue(text,includeTime){let match=(includeTime?dateTime:date).exec(text);if(match===null||match[0].length!==text.length)return!1;let year=Number(match[1]),month=Number(match[2]),day=Number(match[3]),days=[31,year%4===0&&(year%100!==0||year%400===0)?29:28,31,30,31,30,31,31,30,31,30,31];if(year<1||month<1||month>12||day<1||day>days[month-1])return!1;if(!includeTime)return!0;if(Number(match[4])>23||Number(match[5])>59||Number(match[6])>59)return!1;if(match[7]===void 0)return!0;let hours=Number(match[7]),minutes=Number(match[8]);return hours<=14&&minutes<=59&&(hours!==14||minutes===0)}var primitiveTypes2=new Set(["Uuid","String","Int","Decimal","Bool","Date","DateTime"]);function validateResponses(application,context,inputs=context.inputUses){let slices=[],collect=(feature,parent)=>{let scope=[...parent,feature.name];feature.slices.forEach(slice=>slices.push({slice,scope:[...scope,slice.name]})),feature.features.forEach(child=>collect(child,scope))};application.modules.forEach(module=>module.features.forEach(feature=>collect(feature,[module.name])));let commands=new Map,properties=new Map,responseFields=new Map;for(let{slice,scope}of slices)for(let command of slice.commands){let entries=commands.get(command.name)??[];entries.push({command,scope}),commands.set(command.name,entries),properties.set(command,uniqueByName(command.properties)),command.response?.kind==="RecordCommandResponseSyntax"&&responseFields.set(command,uniqueByName(command.response.fields))}let imports=new Map;for(let imported of application.imports){let name=imported.qualifiedName.split(".").at(-1);imports.set(name,[...imports.get(name)??[],imported.qualifiedName])}let resolved=new Map,resolve=(name,from)=>{let key=`${from.join(".")}|${name}`;if(resolved.has(key))return resolved.get(key);let imported=imports.get(name)??[],segments=((commands.get(name.split(".").at(-1))??[]).length===0&&imported.length===1?imported[0]:name).split("."),candidates=commands.get(segments.at(-1))??[];if(segments.length>1){let qualifiers=segments.slice(0,-1);candidates=candidates.filter(entry=>qualifiers.length<=entry.scope.length&&qualifiers.every((value,index)=>entry.scope[entry.scope.length-qualifiers.length+index]===value))}else for(let depth=from.length;depth>=0;depth--){let visible=candidates.filter(entry=>depth<=entry.scope.length&&from.slice(0,depth).every((value,index)=>entry.scope[index]===value));if(visible.length>0){candidates=visible;break}}let command=candidates.length===1?candidates[0].command:null;return resolved.set(key,command),command},concepts=uniqueByName(application.concepts),conceptNames=new Set(application.concepts.map(concept=>concept.name)),composites=new Map([...uniqueByName(application.types)].map(([name,type])=>[name,uniqueByName(type.properties)])),readModels=new Set(slices.flatMap(entry=>entry.slice.readModels.map(model=>model.name))),commandProperties=new Set([...properties.keys()].flatMap(command=>[...command.properties])),checkDeclarations=declared=>{for(let property of declared)property.isGenerated&&!commandProperties.has(property)&&context.error(DiagnosticCodes.GeneratedPropertyOutsideCommand,"Generated properties can only be declared on commands.",property.location)},checkFeature=feature=>{feature.features.forEach(checkFeature);for(let slice of feature.slices){for(let command of slice.commands)for(let production of command.produces)production.inlineEvent!==null&&checkDeclarations(production.inlineEvent.properties);slice.events.forEach(event=>checkDeclarations(event.properties)),slice.readModels.forEach(model=>checkDeclarations(model.properties));for(let reaction of slice.reactions)for(let trigger of reaction.triggers)for(let production of trigger.produces)production.inlineEvent!==null&&checkDeclarations(production.inlineEvent.properties)}};application.types.forEach(type=>checkDeclarations(type.properties)),application.modules.forEach(module=>module.features.forEach(checkFeature));let validateSource=(source,explicit,command)=>{let property=properties.get(command).get(source.property);if(property===void 0){context.error(DiagnosticCodes.InvalidResponseSource,`Response source '${source.property}' must reference one direct command property.`,source.location);return}let type=property.type;(type.isCollection||readModels.has(type.name))&&context.error(DiagnosticCodes.InvalidResponseShape,"Collection and whole-read-model responses are not supported.",source.location),explicit!==null&&(explicit.name!==type.name||explicit.isCollection!==type.isCollection||explicit.isOptional!==type.isOptional)&&context.error(DiagnosticCodes.InvalidResponseShape,"An explicit response field type must match its source's declared type, collection shape and optionality.",explicit.location)};for(let command of properties.keys()){for(let property of command.properties){if(!property.isGenerated)continue;let concept=concepts.get(property.type.name);(property.type.isOptional||property.type.isCollection||(concept===void 0?primitiveTypes2.has(property.type.name)||composites.has(property.type.name)||conceptNames.has(property.type.name)||readModels.has(property.type.name):concept.type!=="Uuid"))&&context.error(DiagnosticCodes.InvalidGeneratedType,"A generated property must be a required, noncollection concept backed by Uuid.",property.location)}let response=command.response;if(response?.kind==="ScalarCommandResponseSyntax")validateSource(response.source,null,command);else if(response?.kind==="RecordCommandResponseSyntax"){response.fields.length===0&&context.error(DiagnosticCodes.InvalidCommandResponse,"A response block requires at least one field.",response.location);let names=new Set;for(let field3 of response.fields)names.has(field3.name)&&context.error(DiagnosticCodes.DuplicateResponseField,`Duplicate response field '${field3.name}'.`,field3.location),names.add(field3.name),validateSource(field3.source,field3.type,command)}}let validateSpecification=(specification,scope)=>{let action2=specification.when,command=action2===null?null:resolve(action2.commandType,scope);if(action2!==null&&command!==null){let declared2=properties.get(command);for(let input of action2.values)declared2.get(input.property.split(".")[0])?.isGenerated&&context.error(DiagnosticCodes.GeneratedPropertySuppliedAsInput,`Generated property '${input.property}' cannot be supplied as request or form input.`,input.location);let identifiers=[...declared2.values()].filter(property=>property.isIdentifier);if(action2.for!==null&&identifiers.length===1&&identifiers[0].isGenerated){let type=identifiers[0].type;(primitiveTypes2.has(type.name)||concepts.has(type.name)||composites.has(type.name))&&(type.isOptional||type.isCollection||concepts.get(type.name)?.type!=="Uuid"||action2.for.kind!=="LiteralExpressionSyntax"||typeof action2.for.value!="string"||!uuidValue(action2.for.value))&&context.error(DiagnosticCodes.InvalidGeneratedFixture,"A generated identifier fixture must supply one compatible concrete UUID value through 'for'.",action2.for.location)}let names=new Set;for(let fixture of action2.generatedValues??[]){let property=declared2.get(fixture.property);(names.has(fixture.property)||property===void 0||!property.isGenerated||property.isIdentifier||!compatibleValue(fixture.source,property.type,concepts,composites))&&context.error(DiagnosticCodes.InvalidGeneratedFixture,"A generated fixture must uniquely supply a compatible value for a nonidentifier generated command property.",fixture.location),names.add(fixture.property)}}let expectation=specification.thenReturns;if(expectation==null||((action2===null||specification.thenErrors.length>0||specification.thenDenied!=null)&&context.error(DiagnosticCodes.InvalidReturnExpectation,"A return expectation requires a command action and cannot accompany an error or denial.",expectation.location),command===null))return;let response=command.response,declared=properties.get(command);if(expectation.kind==="ScalarSpecificationReturnSyntax"&&response?.kind==="ScalarCommandResponseSyntax"&&declared.has(response.source.property))compatibleValue(expectation.value,declared.get(response.source.property).type,concepts,composites)||context.error(DiagnosticCodes.InvalidReturnExpectation,"The expected return value must match the response source's type.",expectation.location);else if(expectation.kind==="RecordSpecificationReturnSyntax"&&response?.kind==="RecordCommandResponseSyntax"){expectation.fields.length===0&&context.error(DiagnosticCodes.InvalidReturnExpectation,"A record return expectation requires at least one field.",expectation.location);let fields=responseFields.get(command),asserted=new Set;for(let field3 of expectation.fields){let contract=fields.get(field3.property),property=contract===void 0?void 0:declared.get(contract.source.property);(asserted.has(field3.property)||property===void 0||!compatibleValue(field3.source,property.type,concepts,composites))&&context.error(DiagnosticCodes.InvalidReturnExpectation,"A return assertion must uniquely name a response field and supply a compatible concrete value.",field3.location),asserted.add(field3.property)}}else context.error(DiagnosticCodes.InvalidReturnExpectation,"The return expectation must match the command's scalar or record response shape.",expectation.location)};for(let{slice,scope}of slices)slice.specifications.forEach(specification=>validateSpecification(specification,scope));for(let input of inputs){if(input.isParameter===!0)continue;let command=resolve(input.command,input.scope);command!==null&&properties.get(command).get(input.property.split(".")[0])?.isGenerated&&context.error(DiagnosticCodes.GeneratedPropertySuppliedAsInput,`Generated property '${input.property}' cannot be supplied as request or form input.`,input.location)}}function uniqueByName(items){let result=new Map,duplicates=new Set;for(let item of items)result.has(item.name)&&duplicates.add(item.name),result.set(item.name,item);return duplicates.forEach(name=>result.delete(name)),result}function compatibleValue(value,type,concepts,composites){if(value.kind==="LiteralExpressionSyntax"&&value.value===null)return type.isOptional;if(type.isCollection)return value.kind==="ListExpressionSyntax"&&value.items.every(item=>compatibleValue(item,{...type,isCollection:!1,isOptional:!1},concepts,composites));let properties=composites.get(type.name);if(properties!==void 0)return value.kind==="ObjectExpressionSyntax"&&value.members.every(member=>{let property=properties.get(member.name);return property!==void 0&&compatibleValue(member.value,property.type,concepts,composites)});let concept=concepts.get(type.name),primitive=concept?.type??type.name;if(concept?.type==="Enum")return value.kind==="LiteralExpressionSyntax"&&typeof value.value=="string"&&concept.values.includes(value.value);if(value.kind==="LiteralExpressionSyntax")switch(primitive){case"Uuid":return typeof value.value=="string"&&uuidValue(value.value);case"String":return typeof value.value=="string";case"Bool":return typeof value.value=="boolean";case"Int":return typeof value.value=="number"&&Number.isFinite(value.value)&&Number.isInteger(value.value);case"Decimal":return typeof value.value=="number"&&Number.isFinite(value.value);case"Date":return typeof value.value=="string"&&responseDateValue(value.value,!1);case"DateTime":return typeof value.value=="string"&&responseDateValue(value.value,!0);default:return!primitiveTypes2.has(primitive)}return!primitiveTypes2.has(primitive)&&concept===void 0}var uuidValuePattern=/^(?:[0-9a-f]{32}|[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}|\{[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\}|\([0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\))(?![\s\S])/i;function uuidValue(text){return uuidValuePattern.test(text)}var LineReader=class _LineReader{lines;#index=0;constructor(lines){this.lines=lines}fork(){let reader=new _LineReader(this.lines);return reader.#index=this.#index,reader}peekSignificant(){for(;this.#index<this.lines.length&&isBlank(this.lines[this.#index]);)this.#index++;return this.#index<this.lines.length?this.lines[this.#index]:void 0}takeSignificant(){let line=this.peekSignificant();if(line===void 0)throw new Error("There is no significant line left to take");return this.#index++,line}takeRaw(){return this.#index<this.lines.length?this.lines[this.#index++]:void 0}};function eventDeclarations(slice){return[...slice.events,...slice.commands.flatMap(command=>command.produces).flatMap(produced=>produced.inlineEvent===null?[]:[produced.inlineEvent])]}function requiresExplicitDestinations(command){let identifier=command.properties.find(property=>property.isIdentifier)?.name;return command.produces.some(produced=>produced.for!==null&&(produced.for.kind!=="PathExpressionSyntax"||produced.for.path!==identifier))||command.produces.some(produced=>produced.inlineEvent!==null&&produced.for===null)&&command.produces.some(produced=>produced.inlineEvent===null&&produced.for===null)}function validateInlineEvents(application,context){let slices=[],inFeature=feature=>{slices.push(...feature.slices),feature.features.forEach(inFeature)};application.modules.forEach(module=>module.features.forEach(inFeature));let eventCounts=new Map;for(let event of slices.flatMap(eventDeclarations))eventCounts.set(event.name,(eventCounts.get(event.name)??0)+1);let importedNames=new Set(application.imports.map(value=>value.qualifiedName.split(".").at(-1)));for(let command of slices.flatMap(slice=>slice.commands)){let identifier=command.properties.find(property=>property.isIdentifier)?.name,mixed=requiresExplicitDestinations(command);for(let production of command.produces){let inline=production.inlineEvent;inline!==null&&((eventCounts.get(inline.name)??0)>1||importedNames.has(inline.name))&&context.error(DiagnosticCodes.InlineEventCollision,`Inline event '${inline.name}' collides with another event declaration or import`,production.location),mixed&&production.for===null&&context.error(DiagnosticCodes.ExplicitProducesTargetsRequired,`Production '${production.event}' in command '${command.name}' must state 'for' explicitly - every production must state 'for' when destinations differ`,production.location);let destination=production.for?.kind==="PathExpressionSyntax"?production.for.path:production.for===null&&inline!==null?identifier:void 0;if(!(identifier===void 0||destination!==identifier))for(let mapping2 of production.mappings.filter(mapping3=>mapping3.source.kind==="PathExpressionSyntax"&&mapping3.source.path===identifier)){let message=`Event '${production.event}' copies command identifier '${identifier}' into payload property '${mapping2.property}' although it already identifies the event source`;inline===null?context.information(DiagnosticCodes.EventSourceIdInPayload,message,mapping2.location):context.warning(DiagnosticCodes.EventSourceIdInPayload,message,mapping2.location)}}}}var domainPattern=pattern("^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$"),importPattern=pattern("^import\\s+([\\w.]+)$"),conceptPattern=pattern("^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@\\w+)*)$"),enumValuePattern=pattern("^@?[a-z_]\\w*$"),attributeReasonPattern=pattern(`^([a-z_]\\w*)\\s+reason\\s+"(${stringBodyPattern})"$`),personaPattern=pattern("^persona\\s+([A-Za-z_]\\w*)$"),personaPolicyPattern=pattern("^policy\\s+([A-Za-z_]\\w*)$"),tabIndentPattern=/^[ ]*\t/,primitiveTypes3=["Uuid","String","Int","Decimal","Bool","Date","DateTime"],opaqueTopLevel=new Set(["policy","authentication","seed","ui","theme","trigger","layout","behavior"]),bodyKeywords=new Set(["slice","feature","description","authorize","screen","dialog","form","contribute","on","uses"]);function parseApplication(context,lines,placement=documentPlacement){warnOnTabIndentation(context,lines);let moduleBody=placement.length===1?new ModuleBody(placement[0]):void 0,featureBody=placement.length>1?new FeatureBody(placement[placement.length-1]):void 0,placedBody=moduleBody??featureBody,domain=null,imports=[],fileImports2=[],concepts=[],types=[],modules=[],personas=[],sawOtherConstruct=!1;for(let line=context.reader.peekSignificant();line!==void 0;line=context.reader.peekSignificant()){context.reader.takeSignificant();let keyword=firstWord2(line.content);if(keyword==="domain"){domain=parseDomain(context,line,domain,sawOtherConstruct);continue}if(sawOtherConstruct||=declaresConstruct(keyword,line,placement),keyword==="import"&&isFileImport(line.content))placedBody!==void 0?placedBody.tryParse(context,line):parseFileImport(context,line,fileImports2);else if(keyword==="import"){let match=importPattern.exec(line.content);match===null?context.error(DiagnosticCodes.InvalidImportDeclaration,`Invalid import '${line.content}' - expected 'import <Qualified.Name>'`,locationOf(line)):imports.push({kind:"ImportSyntax",qualifiedName:match[1],location:locationOf(line)})}else keyword==="concept"?concepts.push(parseConcept(context,line)):keyword==="type"?types.push(parseType(context,line)):keyword==="module"&&!isDocumentPlacement(placement)?parseModuleInPlacedFile(context,line,placement,moduleBody):keyword==="module"?modules.push(parseModule(context,line)):keyword==="persona"?personas.push(parsePersona(context,line)):keyword==="trigger"?parseTriggerDeclaration(context,line):opaqueTopLevel.has(keyword)?keyword==="behavior"||keyword==="layout"?collectInputUses(context,line):context.skipOpaqueBlock(line.indent):placedBody?.tryParse(context,line)!==!0&&reportUnexpectedTopLevel(context,line,placement)}return moduleBody!==void 0?modules.unshift(moduleBody.build(context.start,!0)):featureBody!==void 0&&modules.unshift(place(placement,featureBody.build(context.start,!0),context.start)),{kind:"ApplicationSyntax",domain,imports,concepts,types,modules,personas,fileImports:fileImports2,location:context.start}}function declaresConstruct(keyword,line,placement){return keyword==="import"?importPattern.test(line.content):keyword==="module"?isDocumentPlacement(placement):keyword==="concept"||keyword==="type"||keyword==="persona"||opaqueTopLevel.has(keyword)}function parseModuleInPlacedFile(context,line,placement,moduleBody){let name=modulePattern.exec(line.content)?.[1]??"";if(moduleBody!==void 0&&name===placement[0]){moduleBody.parseChildren(context,line);return}context.error(DiagnosticCodes.ModuleInPlacedFile,`This file is imported into ${describePlacement(placement)}, so it cannot declare module '${name}' - import it at the top level of a document instead`,locationOf(line)),context.skipBlock(line.indent)}function reportUnexpectedTopLevel(context,line,placement){let word=firstWord2(line.content);if(isDocumentPlacement(placement)){let hint=bodyKeywords.has(word)?` - '${word}' belongs in a module or feature; wrap it in one, or import this file from inside one`:" - expected domain, import, concept, type, policy, persona, authentication, module, seed, trigger, behavior, ui profile, theme or layout";context.error(DiagnosticCodes.UnknownTopLevelConstruct,`Unexpected '${word}' at the top level${hint}`,locationOf(line))}else{let expected=placement.length===1?moduleBodyExpected:featureBodyExpected;context.error(DiagnosticCodes.UnexpectedInPlacedFile,`Unexpected '${word}' in a file imported into ${describePlacement(placement)} - expected an application declaration or ${expected}`,locationOf(line))}context.skipBlock(line.indent)}function place(placement,innermost,start){let feature=innermost;for(let index=placement.length-2;index>=1;index--)feature={kind:"FeatureSyntax",name:placement[index],description:null,authorize:null,features:[feature],slices:[],fileImports:[],isPlacement:!0,location:start};return{kind:"ModuleSyntax",name:placement[0],description:null,authorize:null,features:[feature],fileImports:[],isPlacement:!0,location:start}}function parseDomain(context,line,existing,sawOtherConstruct){let match=domainPattern.exec(line.content);return match===null?(context.error(DiagnosticCodes.InvalidDomainDeclaration,`Invalid domain declaration '${line.content}' - expected 'domain <Qualified.Name>'`,locationOf(line)),existing):existing!==null?(context.error(DiagnosticCodes.DuplicateDomain,"The document already declares a domain - a document can have at most one",locationOf(line)),existing):(sawOtherConstruct&&context.error(DiagnosticCodes.DomainNotFirst,"'domain' must be declared before any other construct",locationOf(line)),{kind:"DomainSyntax",name:match[1],location:locationOf(line)})}function warnOnTabIndentation(context,lines){let inFence=!1;for(let line of lines){if(line.raw.trimStart().startsWith("```")){inFence=!inFence;continue}!inFence&&tabIndentPattern.test(line.raw)&&context.warning(DiagnosticCodes.TabIndentation,"Screenplay is indentation based - use spaces, not tabs",startOf(line))}}function parseConcept(context,line){let match=conceptPattern.exec(line.content);if(match===null)return context.error(DiagnosticCodes.InvalidConceptDeclaration,`Invalid concept declaration '${line.content}' - expected 'concept <Name> : <Type>'`,locationOf(line)),context.skipBlock(line.indent),{kind:"ConceptSyntax",name:firstWord2(line.content),type:"",attributes:[],values:[],location:locationOf(line)};let[,name,type,attributeText]=match,attributes=attributeText.split(" ").filter(attribute=>attribute.length>0).map(attribute=>({kind:"ConceptAttributeSyntax",name:attribute.replace(/^@+/,""),reason:null,location:locationOf(line)}));type!=="Enum"&&!primitiveTypes3.includes(type)&&context.error(DiagnosticCodes.UnknownPrimitiveType,`Unknown primitive type '${type}' - expected ${primitiveTypes3.join(", ")} or Enum`,locationOf(line));let attributeIndices=new Map;attributes.forEach((attribute,index)=>{attributeIndices.has(attribute.name)||attributeIndices.set(attribute.name,index)});let values=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let reason=attributeReasonPattern.exec(child.content);isFileDirective(child)||(firstWord2(child.content)==="validate"?(type==="Enum"&&child.content==="validate"&&context.peekChild(child.indent)===void 0&&context.warning(DiagnosticCodes.ValidateReadAsEnumerationBlock,`'validate' in enumeration concept '${name}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,locationOf(child)),context.skipOpaqueBlock(child.indent)):reason!==null?applyAttributeReason(context,child,name,attributes,attributeIndices,reason[1],unescapeString(reason[2])):type==="Enum"&&enumValuePattern.test(child.content)?values.push(unescapeIdentifier(child.content)):type==="Enum"?context.error(DiagnosticCodes.InvalidEnumerationValue,`Invalid enum value '${child.content}' - expected an identifier`,locationOf(child)):(context.error(DiagnosticCodes.UnknownConceptDirective,`Unexpected '${child.content}' in concept body - expected validate, 'file <path>' or '<attribute> reason "<text>"'`,locationOf(child)),context.skipBlock(child.indent)))}return{kind:"ConceptSyntax",name,type,attributes,values,location:locationOf(line)}}function applyAttributeReason(context,line,concept,attributes,indices,attribute,reason){let index=indices.get(attribute);index===void 0?context.error(DiagnosticCodes.AttributeReasonWithoutAttribute,`Concept '${concept}' declares a reason for '${attribute}' without the attribute - write 'concept ${concept} : <Type> @${attribute}'`,locationOf(line)):attributes[index].reason!==null?context.error(DiagnosticCodes.DuplicateAttributeReason,`Concept '${concept}' already declares a reason for '${attribute}' - at most one is allowed`,locationOf(line)):attributes[index]={...attributes[index],reason}}function parsePersona(context,line){let name=personaPattern.exec(line.content)?.[1]??"";name===""&&context.error(DiagnosticCodes.InvalidPersonaDeclaration,`Invalid persona declaration '${line.content}' - expected 'persona <Name>'`,locationOf(line));let description=null,policies=[];for(let child=context.peekChild(line.indent);child!==void 0;child=context.peekChild(line.indent)){context.reader.takeSignificant();let keyword=firstWord2(child.content);if(keyword==="description")description=parseDescription(context,child,description,`Persona '${name}'`);else if(keyword==="policy"){let policy=personaPolicyPattern.exec(child.content);policy===null?context.error(DiagnosticCodes.InvalidPersonaPolicyReference,`Invalid policy reference '${child.content}' - expected 'policy <Name>'`,locationOf(child)):policies.push(policy[1])}else context.error(DiagnosticCodes.UnknownPersonaDirective,`Unexpected '${keyword}' in persona body - expected description or policy`,locationOf(child)),context.skipBlock(child.indent)}return{kind:"PersonaSyntax",name,description,policies,location:locationOf(line)}}function parse(source,path,placement=documentPlacement){let{value,diagnostics,success}=parseForAuthoring(source,path,placement);return{value,diagnostics,success}}function parseForAuthoring(source,path,placement=documentPlacement,validateResponseContracts=!0){let lines=splitLines(source,!1,path),context=new ParserContext(new LineReader(lines),path);context.scope=placement;let value=parseApplication(context,lines,placement);return validateInlineEvents(value,context),validateResponseContracts&&validateResponses(value,context),{value,diagnostics:context.diagnostics,triggerData:context.triggerData,inputUses:context.inputUses,success:!context.diagnostics.some(diagnostic=>diagnostic.severity==="error")}}var ScreenplaySyntaxWalker=class{visitNode(_node){}visitApplication(syntax){this.visitNode(syntax),syntax.domain!==null&&this.visitDomain(syntax.domain),syntax.imports.forEach(node=>this.visitImport(node)),syntax.fileImports.forEach(node=>this.visitFileImport(node)),syntax.concepts.forEach(node=>this.visitConcept(node)),syntax.types.forEach(node=>this.visitType(node)),syntax.personas.forEach(node=>this.visitPersona(node)),syntax.modules.forEach(node=>this.visitModule(node))}visitPersona(syntax){this.visitNode(syntax)}visitAuthorize(syntax){this.visitNode(syntax),this.visitPolicyRequirement(syntax.requirement)}visitPolicyRequirement(syntax){this.visitNode(syntax),syntax.kind==="LogicalPolicyRequirementSyntax"&&(this.visitPolicyRequirement(syntax.left),this.visitPolicyRequirement(syntax.right))}visitDomain(syntax){this.visitNode(syntax)}visitImport(syntax){this.visitNode(syntax)}visitFileImport(syntax){this.visitNode(syntax)}visitConcept(syntax){this.visitNode(syntax),syntax.attributes.forEach(node=>this.visitNode(node))}visitType(syntax){this.visitNode(syntax),syntax.properties.forEach(node=>this.visitProperty(node))}visitModule(syntax){this.visitNode(syntax),syntax.fileImports.forEach(node=>this.visitFileImport(node)),syntax.authorize!==null&&this.visitAuthorize(syntax.authorize),syntax.features.forEach(node=>this.visitFeature(node))}visitFeature(syntax){this.visitNode(syntax),syntax.fileImports.forEach(node=>this.visitFileImport(node)),syntax.authorize!==null&&this.visitAuthorize(syntax.authorize),syntax.features.forEach(node=>this.visitFeature(node)),syntax.slices.forEach(node=>this.visitSlice(node))}visitSlice(syntax){this.visitNode(syntax),syntax.commands.forEach(node=>this.visitCommand(node)),syntax.events.forEach(node=>this.visitEvent(node)),syntax.constraints.forEach(node=>this.visitConstraint(node)),syntax.queries.forEach(node=>this.visitQuery(node)),syntax.projections.forEach(node=>this.visitProjection(node)),syntax.readModels.forEach(node=>this.visitReadModel(node)),syntax.captures.forEach(node=>this.visitCapture(node)),syntax.reactions.forEach(node=>this.visitReaction(node)),syntax.screens.forEach(node=>this.visitScreen(node)),syntax.specifications.forEach(node=>this.visitSpecification(node))}visitCommand(syntax){this.visitNode(syntax),syntax.properties.forEach(node=>this.visitProperty(node)),syntax.authorize!==null&&this.visitAuthorize(syntax.authorize),syntax.validations.forEach(node=>this.visitValidate(node)),syntax.produces.forEach(node=>this.visitProduces(node)),syntax.response!=null&&this.visitCommandResponse(syntax.response)}visitCommandResponse(syntax){syntax.kind==="ScalarCommandResponseSyntax"?this.visitScalarCommandResponse(syntax):this.visitRecordCommandResponse(syntax)}visitScalarCommandResponse(syntax){this.visitNode(syntax),this.visitPropertyResponseSource(syntax.source)}visitRecordCommandResponse(syntax){this.visitNode(syntax),syntax.fields.forEach(field3=>this.visitResponseField(field3))}visitResponseField(syntax){this.visitNode(syntax),syntax.type!==null&&this.visitTypeRef(syntax.type),this.visitPropertyResponseSource(syntax.source)}visitPropertyResponseSource(syntax){this.visitNode(syntax)}visitSpecificationReturn(syntax){syntax.kind==="ScalarSpecificationReturnSyntax"?this.visitScalarSpecificationReturn(syntax):this.visitRecordSpecificationReturn(syntax)}visitScalarSpecificationReturn(syntax){this.visitNode(syntax),this.visitExpression(syntax.value)}visitRecordSpecificationReturn(syntax){this.visitNode(syntax),syntax.fields.forEach(field3=>this.visitPropertyMapping(field3))}visitValidate(syntax){this.visitNode(syntax),syntax.kind==="DeclarativeValidateSyntax"&&syntax.rules.forEach(node=>this.visitValidationRule(node))}visitValidationRule(syntax){this.visitNode(syntax),syntax.value!==null&&this.visitExpression(syntax.value)}visitEvent(syntax){this.visitNode(syntax),syntax.properties.forEach(node=>this.visitProperty(node)),syntax.tags.forEach(node=>this.visitTag(node))}visitTag(syntax){this.visitNode(syntax),this.visitExpression(syntax.value)}visitReadModel(syntax){this.visitNode(syntax),syntax.properties.forEach(node=>this.visitProperty(node))}visitConstraint(syntax){this.visitNode(syntax),syntax.kind==="FileConstraintSyntax"&&this.visitNode(syntax.file),syntax.additionalRules.forEach(node=>this.visitConstraint(node))}visitQuery(syntax){this.visitNode(syntax),this.visitTypeRef(syntax.returnType),syntax.by!==null&&this.visitQueryParameter(syntax.by),syntax.filters.forEach(node=>this.visitQueryParameter(node)),syntax.authorize!==null&&this.visitAuthorize(syntax.authorize)}visitQueryParameter(syntax){this.visitNode(syntax),this.visitTypeRef(syntax.type)}visitProjection(syntax){this.visitNode(syntax),syntax.blocks.forEach(node=>this.visitProjectionBlock(node))}visitProjectionBlock(syntax){switch(this.visitNode(syntax),syntax.kind){case"FromSyntax":syntax.events.forEach(node=>this.visitNode(node)),syntax.mappings.forEach(node=>this.visitMapping(node));break;case"EverySyntax":case"AllSyntax":syntax.mappings.forEach(node=>this.visitMapping(node));break;case"JoinSyntax":syntax.events.forEach(node=>this.visitJoinEvent(node));break;case"ProjectionVariantSyntax":syntax.entersOn.forEach(node=>this.visitNode(node)),syntax.blocks.forEach(node=>this.visitProjectionBlock(node));break;case"ChildrenSyntax":case"NestedSyntax":syntax.blocks.forEach(node=>this.visitProjectionBlock(node));break}}visitJoinEvent(syntax){this.visitNode(syntax),syntax.mappings.forEach(node=>this.visitMapping(node))}visitMapping(syntax){this.visitNode(syntax)}visitReaction(syntax){this.visitNode(syntax),syntax.triggers.forEach(node=>this.visitReactionTrigger(node))}visitReactionTrigger(syntax){this.visitNode(syntax),this.visitTriggerSource(syntax.source),syntax.produces.forEach(node=>this.visitProduces(node)),syntax.invokes.forEach(node=>this.visitInvokes(node))}visitProduces(syntax){this.visitNode(syntax),syntax.inlineEvent!==null&&this.visitEvent(syntax.inlineEvent),syntax.for!==null&&this.visitExpression(syntax.for),syntax.mappings.forEach(node=>this.visitPropertyMapping(node)),syntax.tags.forEach(node=>this.visitTag(node))}visitInvokes(syntax){this.visitNode(syntax)}visitCapture(syntax){this.visitNode(syntax),syntax.source!==null&&this.visitCaptureSource(syntax.source),syntax.appends.forEach(node=>this.visitCaptureAppend(node)),syntax.children.forEach(node=>this.visitCaptureChildren(node)),syntax.nested.forEach(node=>this.visitCaptureNested(node))}visitCaptureSource(syntax){this.visitNode(syntax),syntax.settings.forEach(node=>this.visitCaptureSourceSetting(node))}visitCaptureSourceSetting(syntax){this.visitNode(syntax)}visitCaptureAppend(syntax){this.visitNode(syntax)}visitCaptureChildren(syntax){this.visitNode(syntax),syntax.appends.forEach(node=>this.visitCaptureAppend(node))}visitCaptureNested(syntax){this.visitNode(syntax),syntax.appends.forEach(node=>this.visitCaptureAppend(node))}visitTriggerSource(syntax){this.visitNode(syntax)}visitScreen(syntax){this.visitNode(syntax),syntax.directives.forEach(node=>this.visitScreenDirective(node))}visitScreenDirective(syntax){switch(this.visitNode(syntax),syntax.kind){case"ScreenDataSyntax":this.visitTypeRef(syntax.type);break;case"ScreenActionSyntax":syntax.navigate!==null&&this.visitScreenDirective(syntax.navigate);break;case"ScreenTemplateReferenceSyntax":syntax.slots.forEach(slot2=>{this.visitNode(slot2),slot2.directives.forEach(node=>this.visitScreenDirective(node))});break;case"ScreenSectionSyntax":syntax.directives.forEach(node=>this.visitScreenDirective(node));break;case"ScreenTableSyntax":syntax.columns.forEach(node=>this.visitNode(node)),syntax.rowClick!==null&&this.visitScreenDirective(syntax.rowClick);break;case"ScreenSummarySyntax":syntax.fields.forEach(node=>this.visitNode(node));break;case"ScreenCodeSyntax":this.visitNode(syntax.code);break}}visitSpecification(syntax){this.visitNode(syntax),syntax.givenClock!==null&&this.visitSpecificationClock(syntax.givenClock),syntax.given.forEach(node=>this.visitSpecificationEvent(node)),syntax.givenReadModels.forEach(node=>this.visitSpecificationReadModel(node)),syntax.when!==null&&this.visitSpecificationCommand(syntax.when),syntax.givenCaptures.forEach(node=>this.visitSpecificationCapture(node)),syntax.whenAppended!==null&&this.visitSpecificationEvent(syntax.whenAppended),syntax.whenClock!==null&&this.visitSpecificationClock(syntax.whenClock),syntax.whenTrigger!==null&&this.visitSpecificationTrigger(syntax.whenTrigger),syntax.whenCapture!==null&&this.visitSpecificationCapture(syntax.whenCapture),syntax.whenQuery!==null&&this.visitSpecificationWhenQuery(syntax.whenQuery),syntax.thenEvents.forEach(node=>this.visitSpecificationEvent(node)),syntax.thenReadModels.forEach(node=>this.visitSpecificationReadModel(node)),syntax.thenResults.forEach(node=>this.visitSpecificationQueryResult(node)),syntax.thenNoResult!==null&&this.visitNode(syntax.thenNoResult),syntax.thenDenied!=null&&this.visitNode(syntax.thenDenied),syntax.thenReturns!=null&&this.visitSpecificationReturn(syntax.thenReturns),syntax.thenErrors.forEach(node=>this.visitNode(node))}visitSpecificationClock(syntax){this.visitNode(syntax)}visitSpecificationTrigger(syntax){this.visitNode(syntax),syntax.values.forEach(node=>this.visitPropertyMapping(node))}visitSpecificationCapture(syntax){this.visitNode(syntax),syntax.record.forEach(node=>this.visitPropertyMapping(node))}visitSpecificationWhenQuery(syntax){this.visitNode(syntax),syntax.arguments.forEach(node=>this.visitPropertyMapping(node))}visitSpecificationQueryResult(syntax){this.visitNode(syntax),syntax.properties.forEach(node=>this.visitPropertyMapping(node))}visitSpecificationEvent(syntax){this.visitNode(syntax),syntax.values.forEach(node=>this.visitPropertyMapping(node)),syntax.for!==null&&this.visitExpression(syntax.for)}visitSpecificationCommand(syntax){this.visitNode(syntax),(syntax.generatedValues??[]).forEach(fixture=>this.visitPropertyMapping(fixture)),syntax.values.forEach(node=>this.visitPropertyMapping(node)),syntax.for!==null&&this.visitExpression(syntax.for)}visitSpecificationReadModel(syntax){this.visitNode(syntax),syntax.properties.forEach(node=>this.visitPropertyMapping(node))}visitPropertyMapping(syntax){this.visitNode(syntax),this.visitExpression(syntax.source)}visitProperty(syntax){this.visitNode(syntax),this.visitTypeRef(syntax.type)}visitTypeRef(syntax){this.visitNode(syntax)}visitExpression(syntax){this.visitNode(syntax),syntax.kind==="ListExpressionSyntax"?syntax.items.forEach(item=>this.visitExpression(item)):syntax.kind==="ObjectExpressionSyntax"&&syntax.members.forEach(member=>this.visitObjectMember(member))}visitObjectMember(syntax){this.visitNode(syntax),this.visitExpression(syntax.value)}};function isQuickFixDiagnostic(code){return code===DiagnosticCodes.LegacyOptionalSuffix||code===DiagnosticCodes.RedundantEventId}function legacyOptionalTypeLength(line,diagnostic){return diagnostic.code!==DiagnosticCodes.LegacyOptionalSuffix?0:/^[\p{L}\p{Mn}\p{Nd}\p{Pc}.]+(?:\[\])?\?/u.exec(line.slice(diagnostic.location.column-1))?.[0].length??0}function prepareQuickFixes(source,options={}){let original=parseForAuthoring(source,void 0,options.placement);if(!original.success)return()=>[];let lines=splitLines(source),eventsByLine=new Map;new class extends ScreenplaySyntaxWalker{visitEvent(event2){eventsByLine.set(event2.location.line,event2)}}().visitApplication(original.value);let counts=new Map,byLine=new Map,events=new Map,event;for(let line of lines)event=eventsByLine.get(line.number)??event,event!==void 0&&events.set(line.number,event);for(let diagnostic of original.diagnostics){counts.set(diagnostic.code,(counts.get(diagnostic.code)??0)+1);let line=lines[diagnostic.location.line-1],length=legacyOptionalTypeLength(line.raw,diagnostic);if(length>0)byLine.set(line.number,{line:line.number,fix:{diagnosticCode:diagnostic.code,title:"Use 'optional' instead of '?'",scope:"occurrence",edits:[{start:line.startOffset+diagnostic.location.column+length-2,length:1,text:" optional"}]}});else if(diagnostic.code===DiagnosticCodes.RedundantEventId&&commentStart(line.raw)<0){let declaration=events.get(line.number);if(declaration?.id!==declaration?.name||declaration===void 0)continue;byLine.set(line.number,{line:line.number,fix:{diagnosticCode:diagnostic.code,title:"Remove the redundant event id",scope:"occurrence",edits:[{start:line.startOffset,length:(lines[line.number]?.startOffset??source.length)-line.startOffset,text:""}]},change:{node:declaration,replacement:{...declaration,id:null}}})}}let optional=[...byLine.values()].filter(candidate=>candidate.fix.diagnosticCode===DiagnosticCodes.LegacyOptionalSuffix),syntax=verificationShape(original),verified=new Map,rangeVerdicts,documentChecked=!1,documentFix,verify=(fix,change)=>{let candidate=applyQuickFixEdits(source,fix.edits);if(candidate===void 0)return;let parsed=parseForAuthoring(candidate,void 0,options.placement);if(!(!parsed.success||verificationShape(parsed)!==(change===void 0?syntax:verificationShape(original,[change]))))return parsed.diagnostics.filter(diagnostic=>diagnostic.code===fix.diagnosticCode).length===(counts.get(fix.diagnosticCode)??0)-fix.edits.length?fix:void 0};return(line,diagnosticCode)=>{let requests=typeof line=="number"||line===void 0?void 0:line,includeDocument=requests===void 0?diagnosticCode===void 0||diagnosticCode===DiagnosticCodes.LegacyOptionalSuffix:requests.some(request=>request.diagnosticCode===DiagnosticCodes.LegacyOptionalSuffix);if(includeDocument&&!documentChecked&&(optional.length>0&&(documentFix=verify({diagnosticCode:DiagnosticCodes.LegacyOptionalSuffix,title:"Use 'optional' throughout this document",scope:"document",edits:optional.flatMap(candidate=>candidate.fix.edits)})),documentChecked=!0),requests!==void 0){if(rangeVerdicts===void 0){rangeVerdicts=new Map;let candidates=lines.flatMap(line2=>byLine.has(line2.number)?[byLine.get(line2.number)]:[]),edits=candidates.flatMap(candidate=>candidate.fix.edits),candidateSource=applyQuickFixEdits(source,edits);if(edits.length>0&&candidateSource!==void 0){let parsed=parseForAuthoring(candidateSource,void 0,options.placement),changes=candidates.flatMap(candidate=>candidate.change===void 0?[]:[candidate.change]);if(parsed.success&&verificationShape(parsed)===verificationShape(original,changes)){let remaining=new Map,removed=new Map;for(let diagnostic of parsed.diagnostics)remaining.set(diagnostic.code,(remaining.get(diagnostic.code)??0)+1);for(let candidate of candidates)removed.set(candidate.fix.diagnosticCode,(removed.get(candidate.fix.diagnosticCode)??0)+candidate.fix.edits.length);if([...removed].every(([code,count])=>(remaining.get(code)??0)===(counts.get(code)??0)-count))for(let candidate of candidates)rangeVerdicts.set(candidate.line,candidate.fix)}}}let selected2=new Map;for(let request of requests){let fix=rangeVerdicts.get(request.line);fix?.diagnosticCode===request.diagnosticCode&&selected2.set(request.line,fix)}return[...selected2.values(),...includeDocument&&documentFix!==void 0?[documentFix]:[]]}let occurrenceLine=typeof line=="number"?line:void 0,selected=occurrenceLine===void 0?void 0:byLine.get(occurrenceLine),occurrenceFix;return selected!==void 0&&occurrenceLine!==void 0&&(diagnosticCode===void 0||selected.fix.diagnosticCode===diagnosticCode)&&(verified.has(occurrenceLine)||(verified.size===32&&verified.delete(verified.keys().next().value),verified.set(occurrenceLine,verify(selected.fix,selected.change))),occurrenceFix=verified.get(occurrenceLine)),[occurrenceFix,includeDocument?documentFix:void 0].filter(fix=>fix!==void 0)}}function verificationShape(parsed,changes=[]){let replacements=new Map(changes.map(change=>[change.node,change.replacement]));return JSON.stringify([parsed.value,parsed.triggerData],(key,value)=>key==="location"?void 0:replacements.get(value)??value)}function applyQuickFixEdits(source,edits){let parts=[],end=0;for(let edit of edits){if(edit.start<end||edit.start<0||edit.length<0||edit.start+edit.length>source.length)return;parts.push(source.slice(end,edit.start),edit.text),end=edit.start+edit.length}return parts.push(source.slice(end)),parts.join("")}var isNode=value=>typeof value=="object"&&value!==null&&typeof value.kind=="string";function toSyntaxJson(node){return write(node)}function write(value){if(Array.isArray(value))return value.map(write);if(isNode(value)){let result={kind:value.kind},members=Object.keys(value).filter(member=>member!=="kind"&&member!=="location").sort(ordinal);for(let member of members)result[member]=write(value[member]);return result}return value===void 0?null:value}function ordinal(left,right){return left<right?-1:left>right?1:0}function mergeDocuments(documents){let diagnostics=[],applications=documents.map(document=>document.value),named=new Map,concepts=declaredInOneFile(applications.flatMap(application=>application.concepts),"declaration of",diagnostics,void 0,named),types=declaredInOneFile(applications.flatMap(application=>application.types),"declaration of",diagnostics,void 0,named),domains=applications.map(application=>application.domain).filter(domain=>domain!==null);for(let extra of domains.slice(1))diagnostics.push(error(DiagnosticCodes.RepeatedSingularDeclarationAcrossFiles,`The folder already declares a domain in '${describe(domains[0].location.path)}' - a folder compiles to one application, which can have at most one`,extra.location));let modules=mergeModules(applications.flatMap(application=>application.modules),diagnostics),personas=declaredInOneFile(applications.flatMap(application=>application.personas),"persona",diagnostics),value={kind:"ApplicationSyntax",domain:domains[0]??null,imports:firstOfEach(applications.flatMap(application=>application.imports),item=>item.qualifiedName),concepts,types,modules,personas,fileImports:applications.flatMap(application=>application.fileImports),location:applications[0]?.location??{line:1,column:1}},all=[...documents.flatMap(document=>document.diagnostics),...diagnostics];return{value,diagnostics:all,success:!all.some(diagnostic=>diagnostic.severity==="error")}}function mergeModules(modules,diagnostics){return groupByName(modules).map(placedLast).map(parts=>parts.length===1?{...parts[0],isPlacement:!1,features:parts[0].features.map(unplaced)}:{...parts[0],isPlacement:!1,fileImports:parts.flatMap(part=>part.fileImports),description:firstDescription(parts,`module '${parts[0].name}'`,diagnostics),authorize:combineAuthorization(parts.map(part=>part.authorize),`module '${parts[0].name}'`,diagnostics),features:mergeFeatures(parts.flatMap(part=>part.features),diagnostics)})}function mergeFeatures(features,diagnostics){return groupByName(features).map(placedLast).map(parts=>parts.length===1?unplaced(parts[0]):{...parts[0],isPlacement:!1,fileImports:parts.flatMap(part=>part.fileImports),description:firstDescription(parts,`feature '${parts[0].name}'`,diagnostics),authorize:combineAuthorization(parts.map(part=>part.authorize),`feature '${parts[0].name}'`,diagnostics),features:mergeFeatures(parts.flatMap(part=>part.features),diagnostics),slices:declaredInOneFile(parts.flatMap(part=>part.slices),"slice",diagnostics,`feature '${parts[0].name}'`)})}function placedLast(parts){return[...parts.filter(part=>!part.isPlacement),...parts.filter(part=>part.isPlacement)]}function unplaced(feature){return{...feature,isPlacement:!1,features:feature.features.map(unplaced)}}function combineAuthorization(declarations,owner,diagnostics){let kept=[];for(let authorization of declarations.filter(declaration=>declaration!==null)){let first=kept.find(earlier=>earlier.location.path!==authorization.location.path&&JSON.stringify(toSyntaxJson(earlier))===JSON.stringify(toSyntaxJson(authorization)));if(first!==void 0){diagnostics.push(warning(DiagnosticCodes.DuplicateAuthorizationAcrossFiles,`An identical authorization is already declared on the ${owner} in '${describe(first.location.path)}' - this repeated gate is ignored`,authorization.location));continue}kept.push(authorization)}return kept.reduce((combined,next)=>combineAuthorize(combined,next),null)}function firstOfEach(items,key){let seen=new Set;return items.filter(item=>!seen.has(key(item))&&seen.add(key(item))!==void 0)}function groupByName(items){let groups=new Map;for(let item of items)groups.set(item.name,[...groups.get(item.name)??[],item]);return[...groups.values()]}function firstDescription(parts,owner,diagnostics){let described=parts.filter(part=>part.description!==null);for(let disagreeing of described.slice(1).filter(part=>part.description!==described[0].description))diagnostics.push(warning(DiagnosticCodes.ConflictingDescriptionAcrossFiles,`The ${owner} is already described in '${describe(described[0].location.path)}' - keeping that description`,disagreeing.location));return described[0]?.description??null}function declaredInOneFile(declarations,keyword,diagnostics,within,claimed=new Map){let kept=[];for(let declaration of declarations){let first=claimed.get(declaration.name);if(first!==void 0&&first.path!==declaration.location.path){diagnostics.push(error(DiagnosticCodes.RepeatedDeclarationAcrossFiles,`Duplicate ${keyword} '${declaration.name}'${within===void 0?"":` in ${within}`} - already declared in '${describe(first.path)}'`,declaration.location));continue}first===void 0&&claimed.set(declaration.name,declaration.location),kept.push(declaration)}return kept}var describe=path=>path??"another file",error=(code,message,location)=>({severity:"error",code,message,location}),warning=(code,message,location)=>({severity:"warning",code,message,location});function parsePlacedDocuments(documents){let parsed=documents.map(document=>parseForAuthoring(document.source,document.path,document.placement,!1)),merged=mergeDocuments(parsed),context=new ParserContext(new LineReader([]));validateInlineEvents(merged.value,context),validateResponses(merged.value,context,parsed.flatMap(document=>document.inputUses));let existing=merged.diagnostics,reported=new Set(existing.map(diagnosticKey)),all=[...existing,...context.diagnostics.filter(diagnostic=>!reported.has(diagnosticKey(diagnostic)))];return{...merged,diagnostics:all,success:!all.some(diagnostic=>diagnostic.severity==="error")}}function diagnosticKey(diagnostic){return JSON.stringify([diagnostic.code,diagnostic.location.path,diagnostic.location.line,diagnostic.location.column])}var responseAvailability="Syntax-only; execution unavailable until ESM v8 (PLAY0268). No response type is emitted.",revisions=new Map;function authoringSource(lines,headers){let fences=fenceMap(lines),roots=lines.flatMap((line,index)=>!fences[index]&&indentOf(line)===0&&/^\w/.test(line)?[line.split(/\s+/)[0]]:[]);if(roots.includes("module")||!roots.some(root=>["feature","slice","command","event","specification"].includes(root)))return{source:lines.join(`
6
- `),locations:lines.map((_,index)=>({line:index+1,column:0}))};let globals=[],body=[],global=!1;lines.forEach((line,index)=>{!fences[index]&&indentOf(line)===0&&/^\w/.test(line)&&(global=/^(?:concept|type|import|domain)\b/.test(line)),(global?globals:body).push(index)});let depth=roots.includes("feature")?1:roots.includes("slice")?2:3,wrappers=headers.slice(0,depth),source=[...globals.map(index=>lines[index]),...wrappers,...body.map(index=>" ".repeat(depth*2)+lines[index])].join(`
7
- `),locations=[...globals.map(index=>({line:index+1,column:0})),...wrappers.map(()=>({line:0,column:0})),...body.map(index=>({line:index+1,column:depth*2}))];return{source,locations}}function analyze(lines,otherSources,placement,path="current.play"){let others=otherSources.map((document,index)=>typeof document=="string"?{path:`other-${index}.play`,source:document}:document).filter(document=>document.path!==path),documents=[{path,source:lines.join(`
8
- `),placement},...others],names=new Set(documents.flatMap(document=>[...document.source.matchAll(/\w+/g)].map(match=>match[0]).concat(document.placement??[]))),fresh=prefix=>{let name=prefix;for(let suffix=1;names.has(name);suffix++)name=`${prefix}${suffix}`;return names.add(name),name},module=fresh("EditorAuthoring"),feature=fresh("FragmentFeature"),preparedDocuments=documents.map((document,index)=>{let sourceLines=index===0?lines:document.source.split(`
9
- `),prepared2=document.placement?.length?{source:document.source,locations:sourceLines.map((_,line)=>({line:line+1,column:0}))}:authoringSource(sourceLines,[`module ${module}`,` feature ${feature}`,` slice StateChange ${fresh(`Fragment${index}`)}`]);return{...document,...prepared2,placement:document.placement??[]}}),prepared=preparedDocuments[0],parsed=others.length===0?parse(prepared.source,path,placement):parsePlacedDocuments([...preparedDocuments.slice(1),prepared]),commands=new Map,specifications=new Map,walk=value=>{if(value===null||typeof value!="object")return;if(Array.isArray(value)){value.forEach(walk);return}let node=value,location=node.location;if(location?.path===path){let original=prepared.locations[location.line-1];original&&(node.location={...location,line:original.line,column:Math.max(1,location.column-original.column)})}node.location?.path===path&&(node.kind==="CommandSyntax"&&commands.set(node.location.line-1,value),node.kind==="SpecificationSyntax"&&specifications.set(node.location.line-1,value));for(let[key,child]of Object.entries(node))key!=="location"&&walk(child)};walk(parsed.value);let diagnostics=parsed.diagnostics.filter(diagnostic=>diagnostic.location.path===path).flatMap(diagnostic=>{let original=prepared.locations[diagnostic.location.line-1];return original?.line?[{...diagnostic,location:{...diagnostic.location,line:original.line,column:Math.max(1,diagnostic.location.column-original.column)}}]:[]});return{commands,specifications,diagnostics}}function responseAnalysis(lines,otherSources=[],placement,path="current.play"){let key=JSON.stringify([lines,otherSources,placement,path]),analysis=revisions.get(key);return analysis===void 0&&(analysis=analyze(lines,otherSources,placement,path),revisions.size>=16&&revisions.delete(revisions.keys().next().value),revisions.set(key,analysis)),analysis}var fileReferenceKeyword="file",typeReferencePattern2=/^[A-Za-z_]\w*(?:\[\])?(?:\?|\s+optional)?$/,absolutePathPattern=/^(?:[/\\]|[A-Za-z]:[/\\]|~[/\\])/;function isAbsoluteFileReferencePath(path){return absolutePathPattern.test(path)}function withoutComment2(text){let inString=!1,inTemplate=!1;for(let index=0;index<text.length;index++){let current=text[index];if(current==="\\"&&inString&&index+1<text.length)index++;else if(current==='"'&&!inTemplate)inString=!inString;else if(current==="`"&&!inString)inTemplate=!inTemplate;else if(!inString&&!inTemplate&&current==="/"&&text[index+1]==="/")return text.slice(0,index)}return text}function fileReferenceOn(line,lineIndex){let indent=indentOf(line),content=withoutComment2(line.slice(indent)).trimEnd();if(firstWord(content)!==fileReferenceKeyword)return;let afterKeyword=content.slice(fileReferenceKeyword.length),path=afterKeyword.trim();if(path.length===0||typeReferencePattern2.test(path))return;let separatorLength=afterKeyword.length-afterKeyword.trimStart().length,startColumn=indent+fileReferenceKeyword.length+separatorLength+1;return{path,line:lineIndex,startColumn,endColumn:startColumn+path.length}}function fileReferences(lines){let fences=fenceMap(lines),references=[];for(let index=0;index<lines.length;index++){if(fences[index])continue;let reference=fileReferenceOn(lines[index],index);reference&&references.push(reference)}return references}function eventAnalysisSource(lines){let fenced=!1;return lines.map(line=>{if(fenced)return line.trim()==="```"&&(fenced=!1),line;let text=withoutComment(line);return/^\s*```(?:[a-z]+)?\s*$/.test(text)&&(fenced=!0),text.trimEnd()})}var conceptPattern2=/^concept\s+(\w+)\s*:\s*(\w+)((?:\s+@\w+)*)\s*$/,propertyPattern2=/^\s*(@?[a-z_]\w*)\s+([\w.]+(?:\[\])?(?:\?|\s+optional)?)(\s+generated)?(\s+identifier)?\s*$/,attributeReasonPattern2=/^([a-z_]\w*)\s+reason\s+"((?:[^"\\]|\\.)*)"\s*$/,readPattern=/^\s*reads\s+([A-Z]\w*)(?:\s+as\s+([a-z_]\w*))?(?:\s+by\s+([a-z_]\w*))?\s*$/,commandReserved=["authorize","produces","reads"],authorizationContinuation=/^(?:(?:or|and)\s+)?[A-Za-z_(][\p{L}\p{Mn}\p{Nd}\p{Pc}\s()]*$/u,eventReserved=eventBodyReservedWords,inlineEventReserved=["tag","for","generation","origin","namespace","sequence","correlation","causation","causedBy","occurred"],queryParameterPattern=/^\s*(?:by|filter)\s+([a-z_]\w*)\s+([\w.]+(?:\[\])?(?:\?|\s+optional)?)(?:\s+from\s+.+)?\s*$/;function propertyTypeReference(property){return property.typeReference??typeReferenceSymbol(property.type)}function sourceTypeAt(line,startColumn){let text=line.slice(startColumn-1).match(/^[\p{L}\p{Mn}\p{Nd}\p{Pc}.]+(?:\[\])?(?:\?|\s+optional\b)?/u)?.[0]??"";return{text,startColumn,endColumn:startColumn+text.length}}function propertiesIn(lines,body,reserved3){return body.map(index=>({index,match:lines[index].match(propertyPattern2)})).filter(entry=>entry.match!==null).filter(({match})=>match[1].startsWith("@")||match[1]==="as"||!reserved3.includes(match[1])).map(({index,match})=>({name:match[1].replace(/^@/,""),type:match[2],typeReference:typeReferenceSymbol(match[2]),sourceType:sourceTypeAt(lines[index],lines[index].match(/^\s*\S+\s+/)[0].length+1),isIdentifier:match[4]!==void 0,...match[3]!==void 0?{isGenerated:!0}:{},line:index}))}function collectBody(lines,fences,start,indent){let body=[];for(let index=start+1;index<lines.length;index++){if(fences[index])continue;let line=lines[index];if(line.trim().length!==0){if(indentOf(line)<=indent)break;body.push(index)}}return body}function directBody(lines,fences,start,indent){let body=collectBody(lines,fences,start,indent).filter(index=>!fences[index]&&!/^\s*(?:\/\/|#)/.test(lines[index]));if(!/^\s*command\b/.test(lines[start]))return body;let blockIndent,authorization=!1;return body.filter(index=>{let childIndent=indentOf(lines[index]),text=lines[index].trim();return blockIndent!==void 0&&childIndent>blockIndent&&(!authorization||authorizationContinuation.test(text))?!1:(blockIndent=text!=="validate csharp"&&propertiesIn(lines,[index],commandReserved).length>0||/^description(?:\s|$)/.test(text)?void 0:childIndent,authorization=/^authorize(?:\s|$)/.test(text),!0)})}var symbolRevisions=new Map;function scanDocument(lines){let source=lines.join(`
10
- `),cached=symbolRevisions.get(source);if(cached)return cached;let analysis=responseAnalysis(lines),symbols={authoringSources:[source],imports:[],concepts:[],types:[],policies:[],events:[],commands:[],queries:[],screens:[],triggers:[]};lines=eventAnalysisSource(lines);let fences=fenceMap(lines),eventLines=lines,eventFences=fences,eventPropertyLines=lines.map(line=>line.replace(/\s*=(?!=|>).*/,""));for(let index=0;index<lines.length;index++){if(fences[index])continue;let line=lines[index],trimmed=line.trim(),indent=indentOf(line),importMatch=eventLines[index].trim().match(/^import\s+([\w.]+)\s*$/);if(importMatch&&indent===0){let qualifiedName=importMatch[1],shortName=qualifiedName.split(".").pop()??qualifiedName;symbols.imports.push({qualifiedName,shortName,line:index});continue}let conceptMatch=trimmed.match(conceptPattern2);if(conceptMatch){let body=collectBody(lines,fences,index,indent).map(i=>lines[i].trim()),attributeReasons={};for(let line2 of body){let reason=line2.match(attributeReasonPattern2);reason&&attributeReasons[reason[1]]===void 0&&(attributeReasons[reason[1]]=reason[2])}let enumValues=conceptMatch[2]==="Enum"?body.filter(line2=>!attributeReasonPattern2.test(line2)):[];symbols.concepts.push({name:conceptMatch[1],primitive:conceptMatch[2],attributes:conceptMatch[3].trim().split(/\s+/).filter(Boolean),attributeReasons,enumValues,line:index});continue}let typeMatch=trimmed.match(/^type\s+(\w+)\s*$/);if(typeMatch){symbols.types.push({name:typeMatch[1],properties:propertiesIn(lines,collectBody(lines,fences,index,indent),clauseKeywords),line:index});continue}let policyMatch=trimmed.match(/^policy\s+(\w+)\s*$/);if(policyMatch){let requires=collectBody(lines,fences,index,indent).filter(i=>!fences[i]).map(i=>lines[i].trim());symbols.policies.push({name:policyMatch[1],requires,line:index});continue}let eventMatch=eventLines[index].trim().match(/^(?:produces\s+)?event\s+(\w+)(?:\s+generation\s+(\d+))?\s*$/);if(eventMatch){let inline=trimmed.startsWith("produces "),body=directBody(eventLines,eventFences,index,indent),propertyBody=inline?body:body.filter(line2=>fileReferenceOn(eventLines[line2],line2)===void 0);symbols.events.push({name:eventMatch[1],...eventMatch[2]?{generation:Number(eventMatch[2])}:{},inline,properties:propertiesIn(inline?eventPropertyLines:eventLines,propertyBody,inline?inlineEventReserved:eventReserved),line:index});continue}let command=analysis.commands.get(index);if(command){let body=directBody(lines,fences,index,indent),productionHeaders=body.filter(line2=>/^\s*produces\b/.test(lines[line2]));symbols.commands.push({name:command.name,properties:command.properties.map(property=>({name:property.name,type:`${property.type.name}${property.type.isCollection?"[]":""}${property.type.isOptional?" optional":""}`,typeReference:{name:property.type.name,isCollection:property.type.isCollection,isOptional:property.type.isOptional},sourceType:sourceTypeAt(lines[property.type.location.line-1],property.type.location.column),isIdentifier:property.isIdentifier||/\sidentifier\s*$/.test(lines[property.location.line-1]),...property.isGenerated?{isGenerated:!0}:{},line:property.location.line-1})),response:command.response,productionHeaders,produces:productionHeaders.flatMap(line2=>{let header10=eventLines[line2].trim(),inline=/^produces\s+event\b/.test(header10),conditional2=/^produces\s+when\b/.test(header10),eventLine=conditional2?directBody(eventLines,eventFences,line2,indentOf(eventLines[line2]))[0]:line2;if(eventLine===void 0)return[];let name=conditional2?eventLines[eventLine].trim():header10.match(inline?/^produces\s+event\s+([A-Za-z_]\w*)(?:\s+generation\s+\d+)?\s*$/:/^produces\s+([A-Z]\w*)\s*$/)?.[1];if(name===void 0||!/^[A-Za-z_]\w*$/.test(name))return[];let children=directBody(eventLines,eventFences,eventLine,indentOf(eventLines[eventLine])),targets=children.map(index2=>eventLines[index2].trim().match(/^for(?:\s+(.*))?$/)).filter(match=>match!==null),target=targets.length===0?void 0:targets.length===1?targets[0][1]??"":"",mappings=children.flatMap(index2=>{let match=eventLines[index2].trim().match(inline?/^(@?[a-z_]\w*)\s+[\w.]+(?:\[\])?(?:\?|\s+optional)?\s*=(?!=|>)\s*(.+)$/:/^(@?[\w.]+)\s*=(?!=|>)\s*(.+)$/);return match===null?[]:[{name:match[1].replace(/^@/,""),source:match[2],line:index2}]});return[{name,inline,conditional:conditional2,line:line2,target,mappings}]}),reads:body.filter(line2=>!fences[line2]).map(line2=>({line:line2,match:lines[line2].match(readPattern)})).filter(entry=>entry.match!==null).map(({line:line2,match})=>({view:match[1],...match[2]?{alias:match[2]}:{},...match[3]?{by:match[3]}:{},line:line2})),line:index});continue}let queryMatch=trimmed.match(/^query\s+(\w+)\s*=>\s*(?:observable\s+)?([\w.]+(?:\[\])?(?:\?|\s+optional)?)\s*$/);if(queryMatch){let parameters=collectBody(lines,fences,index,indent).map(i=>({index:i,match:lines[i].match(queryParameterPattern)})).filter(entry=>entry.match!==null).map(({index:line2,match})=>({name:match[1],type:match[2],typeReference:typeReferenceSymbol(match[2]),sourceType:sourceTypeAt(lines[line2],lines[line2].match(/^\s*(?:by|filter)\s+\S+\s+/)[0].length+1),isIdentifier:!1,line:line2}));symbols.queries.push({name:queryMatch[1],returnType:queryMatch[2],returnTypeReference:typeReferenceSymbol(queryMatch[2]),parameters,line:index});continue}let screenMatch=trimmed.match(/^screen\s+(\w+)\s*$/);if(screenMatch){symbols.screens.push({name:screenMatch[1],line:index});continue}let triggerMatch=trimmed.match(/^trigger\s+(\w+)\s*$/);triggerMatch&&indent===0&&symbols.triggers.push({name:triggerMatch[1],line:index})}return symbolRevisions.size>=16&&symbolRevisions.delete(symbolRevisions.keys().next().value),symbolRevisions.set(source,symbols),symbols}function mergeSymbols(...documents){return{authoringSources:documents.flatMap(document=>document.authoringSources??[]),...documents.some(document=>document.authoringDocuments)?{authoringDocuments:documents.flatMap(document=>document.authoringDocuments??(document.authoringSources??[]).map((source,index)=>({path:`other-${index}.play`,source})))}:{},imports:documents.flatMap(document=>document.imports),concepts:documents.flatMap(document=>document.concepts),types:documents.flatMap(document=>document.types),policies:documents.flatMap(document=>document.policies),events:documents.flatMap(document=>document.events),commands:documents.flatMap(document=>document.commands),queries:documents.flatMap(document=>document.queries),screens:documents.flatMap(document=>document.screens),triggers:documents.flatMap(document=>document.triggers)}}function knownEventNames(symbols){return[...symbols.events.map(event=>event.name),...symbols.imports.map(imported=>imported.shortName)]}var builtInTriggerNames=["Startup","Shutdown"];function knownTriggerNames(symbols){return[...knownEventNames(symbols),...symbols.triggers.map(trigger=>trigger.name),...builtInTriggerNames]}function knownTypeNames(symbols,primitives){return[...primitives,...symbols.concepts.map(concept=>concept.name),...symbols.types.map(type=>type.name),...symbols.imports.map(imported=>imported.shortName)]}var eventContextRootType="EventContext",eventContextTypes={EventContext:[{name:"eventType",type:"EventType",kind:"composite",description:"The type of the event - its identifier, generation and whether it is a tombstone."},{name:"eventSourceType",type:"EventSourceType",kind:"value",description:"The type of the event source the event was appended to."},{name:"eventSourceId",type:"EventSourceId",kind:"value",description:"The identifier of the event source the event was appended to - the value $eventSourceId resolves."},{name:"eventStreamType",type:"EventStreamType",kind:"value",description:"The type of the event stream the event belongs to."},{name:"eventStreamId",type:"EventStreamId",kind:"value",description:"The identifier of the event stream the event belongs to."},{name:"sequenceNumber",type:"EventSequenceNumber",kind:"value",description:"The position of the event in its event sequence."},{name:"occurred",type:"DateTimeOffset",kind:"value",description:"When the event occurred - the time it was appended unless one was given."},{name:"eventStore",type:"EventStoreName",kind:"value",description:"The name of the event store the event belongs to."},{name:"namespace",type:"EventStoreNamespaceName",kind:"value",description:"The namespace within the event store the event belongs to."},{name:"correlationId",type:"CorrelationId",kind:"value",description:"The correlation identifier the event was appended with."},{name:"causation",type:"IEnumerable<Causation>",kind:"collection",description:"The chain of causes that led to the event - a collection, not addressable below."},{name:"causedBy",type:"Identity",kind:"composite",description:"The identity that caused the event."},{name:"tags",type:"IEnumerable<Tag>",kind:"collection",description:"The tags the event was appended with - a collection, not addressable below."},{name:"hash",type:"EventHash",kind:"value",description:"The hash of the event content."},{name:"observationState",type:"EventObservationState",kind:"value",description:"Whether the observer sees the event for the first time or again on replay - differs between live processing and replay."},{name:"subject",type:"Subject",kind:"value",description:"The compliance subject the event is about - the event source identifier unless one was given."},{name:"subjectIsEventSourceId",type:"bool",kind:"value",description:"Whether the subject is the event source identifier."}],EventType:[{name:"id",type:"EventTypeId",kind:"value",description:"The identifier of the event type."},{name:"generation",type:"EventTypeGeneration",kind:"value",description:"The generation of the event type."},{name:"tombstone",type:"bool",kind:"value",description:"Whether the event is a tombstone event."}],EventSourceType:[{name:"value",type:"string",kind:"value",description:"The underlying string value."}],EventSourceId:[{name:"value",type:"string",kind:"value",description:"The underlying string value."}],EventStreamType:[{name:"value",type:"string",kind:"value",description:"The underlying string value."}],EventStreamId:[{name:"value",type:"string",kind:"value",description:"The underlying string value."}],EventSequenceNumber:[{name:"value",type:"ulong",kind:"value",description:"The underlying ulong value."}],DateTimeOffset:[{name:"Week",type:"int",kind:"function",description:"The ISO 8601 week of the year the value falls in."}],EventStoreName:[{name:"value",type:"string",kind:"value",description:"The underlying string value."}],EventStoreNamespaceName:[{name:"value",type:"string",kind:"value",description:"The underlying string value."}],CorrelationId:[{name:"value",type:"Guid",kind:"value",description:"The underlying Guid value."}],Identity:[{name:"subject",type:"string",kind:"value",description:"The subject identifier of the identity."},{name:"name",type:"string",kind:"value",description:"The display name of the identity."},{name:"userName",type:"string",kind:"value",description:"The user name of the identity."},{name:"onBehalfOf",type:"Identity",kind:"composite",description:"The identity this identity acted on behalf of, if any - an identity with the same members."}],EventHash:[{name:"value",type:"string",kind:"value",description:"The underlying string value."}],Subject:[{name:"value",type:"string",kind:"value",description:"The underlying string value."}],EventTypeId:[{name:"value",type:"string",kind:"value",description:"The underlying string value."}],EventTypeGeneration:[{name:"value",type:"uint",kind:"value",description:"The underlying uint value."}]},eventContextPaths=[{path:"eventType",name:"eventType",type:"EventType",kind:"composite",description:"The type of the event - its identifier, generation and whether it is a tombstone."},{path:"eventType.id",name:"id",type:"EventTypeId",kind:"value",description:"The identifier of the event type."},{path:"eventType.id.value",name:"value",type:"string",kind:"value",description:"The underlying string value."},{path:"eventType.generation",name:"generation",type:"EventTypeGeneration",kind:"value",description:"The generation of the event type."},{path:"eventType.generation.value",name:"value",type:"uint",kind:"value",description:"The underlying uint value."},{path:"eventType.tombstone",name:"tombstone",type:"bool",kind:"value",description:"Whether the event is a tombstone event."},{path:"eventSourceType",name:"eventSourceType",type:"EventSourceType",kind:"value",description:"The type of the event source the event was appended to."},{path:"eventSourceType.value",name:"value",type:"string",kind:"value",description:"The underlying string value."},{path:"eventSourceId",name:"eventSourceId",type:"EventSourceId",kind:"value",description:"The identifier of the event source the event was appended to - the value $eventSourceId resolves."},{path:"eventSourceId.value",name:"value",type:"string",kind:"value",description:"The underlying string value."},{path:"eventStreamType",name:"eventStreamType",type:"EventStreamType",kind:"value",description:"The type of the event stream the event belongs to."},{path:"eventStreamType.value",name:"value",type:"string",kind:"value",description:"The underlying string value."},{path:"eventStreamId",name:"eventStreamId",type:"EventStreamId",kind:"value",description:"The identifier of the event stream the event belongs to."},{path:"eventStreamId.value",name:"value",type:"string",kind:"value",description:"The underlying string value."},{path:"sequenceNumber",name:"sequenceNumber",type:"EventSequenceNumber",kind:"value",description:"The position of the event in its event sequence."},{path:"sequenceNumber.value",name:"value",type:"ulong",kind:"value",description:"The underlying ulong value."},{path:"occurred",name:"occurred",type:"DateTimeOffset",kind:"value",description:"When the event occurred - the time it was appended unless one was given."},{path:"occurred.Week",name:"Week",type:"int",kind:"function",description:"The ISO 8601 week of the year the value falls in."},{path:"eventStore",name:"eventStore",type:"EventStoreName",kind:"value",description:"The name of the event store the event belongs to."},{path:"eventStore.value",name:"value",type:"string",kind:"value",description:"The underlying string value."},{path:"namespace",name:"namespace",type:"EventStoreNamespaceName",kind:"value",description:"The namespace within the event store the event belongs to."},{path:"namespace.value",name:"value",type:"string",kind:"value",description:"The underlying string value."},{path:"correlationId",name:"correlationId",type:"CorrelationId",kind:"value",description:"The correlation identifier the event was appended with."},{path:"correlationId.value",name:"value",type:"Guid",kind:"value",description:"The underlying Guid value."},{path:"causation",name:"causation",type:"IEnumerable<Causation>",kind:"collection",description:"The chain of causes that led to the event - a collection, not addressable below."},{path:"causedBy",name:"causedBy",type:"Identity",kind:"composite",description:"The identity that caused the event."},{path:"causedBy.subject",name:"subject",type:"string",kind:"value",description:"The subject identifier of the identity."},{path:"causedBy.name",name:"name",type:"string",kind:"value",description:"The display name of the identity."},{path:"causedBy.userName",name:"userName",type:"string",kind:"value",description:"The user name of the identity."},{path:"causedBy.onBehalfOf",name:"onBehalfOf",type:"Identity",kind:"composite",description:"The identity this identity acted on behalf of, if any - an identity with the same members."},{path:"tags",name:"tags",type:"IEnumerable<Tag>",kind:"collection",description:"The tags the event was appended with - a collection, not addressable below."},{path:"hash",name:"hash",type:"EventHash",kind:"value",description:"The hash of the event content."},{path:"hash.value",name:"value",type:"string",kind:"value",description:"The underlying string value."},{path:"observationState",name:"observationState",type:"EventObservationState",kind:"value",description:"Whether the observer sees the event for the first time or again on replay - differs between live processing and replay."},{path:"subject",name:"subject",type:"Subject",kind:"value",description:"The compliance subject the event is about - the event source identifier unless one was given."},{path:"subject.value",name:"value",type:"string",kind:"value",description:"The underlying string value."},{path:"subjectIsEventSourceId",name:"subjectIsEventSourceId",type:"bool",kind:"value",description:"Whether the subject is the event source identifier."}];function namesEventContextMember(member,segment){if(member.kind==="function")return segment===member.name||segment===`${member.name}()`;let declared=member.name[0].toUpperCase()+member.name.slice(1);return segment===declared||segment.length>0&&segment[0].toUpperCase()+segment.slice(1)===declared}var eventContextMembers=eventContextTypes[eventContextRootType];function eventContextMembersAfter(segments){let members=eventContextMembers;for(let segment of segments){let member=members.find(candidate=>namesEventContextMember(candidate,segment));if(!member||member.kind==="collection"||member.kind==="function")return;members=eventContextTypes[member.type]??[]}return members}function eventContextMemberAt(segments){return segments.length===0?void 0:eventContextMembersAfter(segments.slice(0,-1))?.find(member=>namesEventContextMember(member,segments[segments.length-1]))}function resolveEventContextPath(path){let current,expected=eventContextMembers;for(let segment of path.split(".")){if(segment.length===0)return{status:"missing",member:current,expected};if(current?.kind==="collection")return{status:"belowCollection",member:current,segment,expected:[]};let next=expected.find(member=>namesEventContextMember(member,segment));if(!next)return{status:current?"unknownSubPath":"unknownMember",member:current,segment,expected};current=next,expected=next.kind==="function"?[]:eventContextTypes[next.type]??[]}return{status:"known",member:current,expected:[]}}function describeEventContext(){return["**$eventContext**","","Metadata about the event being projected. Paths are checked against the event-context catalog; `causation` and `tags` are collections and cannot be addressed below.","","**Members:**",...eventContextMembers.map(member=>`- \`${member.name}\` (${member.type}) - ${member.description}`)].join(`
11
- `)}function describeEventContextMember(path,member){let below=member.kind==="collection"||member.kind==="function"?[]:eventContextTypes[member.type]??[],lines=[`**$eventContext.${path}**: \`${member.type}\``,"",member.description];return below.length>0&&lines.push("",`**Members:** ${below.map(child=>`\`${child.name}\``).join(", ")}`),lines.join(`
12
- `)}function productionDestinations(command){let identifiers=command.properties.filter(property=>property.isIdentifier&&!propertyTypeReference(property).isOptional&&!propertyTypeReference(property).isCollection),identifier=identifiers.length===1?identifiers[0].name:void 0,productions=command.produces??[],mixed=productions.some(production=>production.target!==void 0&&production.target!==identifier)||productions.some(production=>production.inline&&production.target===void 0)&&productions.some(production=>!production.inline&&production.target===void 0);return{identifier,mixed}}function destinationHints(lines){let source=eventAnalysisSource(lines);return scanDocument(source).commands.flatMap(command=>{let{identifier,mixed}=productionDestinations(command);if(mixed||command.productionHeaders?.length!==command.produces?.length)return[];let hasPromotedDestination=command.produces?.some(sibling=>sibling.target!==void 0||sibling.inline);return(command.produces??[]).flatMap(production=>production.target!==void 0||production.inline&&(identifier===void 0||/\bgeneration\b/.test(source[production.line]))?[]:!production.inline&&hasPromotedDestination?[]:[{line:production.line,column:source[production.line].length+1,label:production.inline?`for ${identifier}`:"for <new event source>"}])})}var diagnosticCodes={eventSourceIdInPayload:"PLAY0469",explicitProducesTargetsRequired:"PLAY0470",redundantEventId:"PLAY0471",invalidEventId:"PLAY0472",inlineEventCollision:"PLAY0473",inlineEventOutsideCommand:"PLAY0474",inlineEventGeneration:"PLAY0475",reservedProductionMetadata:"PLAY0476",invalidEventDocumentation:"PLAY0477",tabIndentation:"PLAY0006",unknownPrimitiveType:"PLAY0008",unknownSliceType:"PLAY0028",duplicateCommandIdentifier:"PLAY0036",unknownContextPath:"PLAY0153",unknownContextCausedByProperty:"PLAY0154",unknownContextIdentityProperty:"PLAY0155",unclosedCodeBlock:"PLAY0164",unknownType:"PLAY0165",unknownEvent:"PLAY0166",unknownPolicy:"PLAY0167",duplicateDeclaration:"PLAY0168",unknownEventContextMember:"PLAY0295",unknownEventContextPath:"PLAY0296",eventContextPathBelowCollection:"PLAY0297",missingEventContextPath:"PLAY0298",unresolvedDynamicKeySource:"PLAY0299",invalidFileImport:"PLAY0454",omittedProductionDestination:"PLAY0478",legacyOptionalSuffix:"PLAY0479",invalidOptionalModifierOrder:"PLAY0480",optionalReadsNotSupported:"PLAY0481",unavailableResponseExecution:"PLAY0268",generatedPropertyOutsideCommand:"PLAY0482",invalidGeneratedType:"PLAY0483",invalidGeneratedModifierOrder:"PLAY0484",generatedPropertyInput:"PLAY0485",invalidCommandResponse:"PLAY0486",invalidResponseSource:"PLAY0487",duplicateResponseField:"PLAY0488",invalidResponseShape:"PLAY0489",invalidGeneratedFixture:"PLAY0490",invalidReturnExpectation:"PLAY0491"};var fileImportPattern2=/^import(\s+)"([^"\\]+)"\s*(?:\/\/.*)?$/,quotedImportPattern=/^import\s+"/;function isFileImportLine(line){return quotedImportPattern.test(line.trim())}function fileImportOn(line,lineIndex){let indent=indentOf(line),match=line.slice(indent).match(fileImportPattern2);if(!match)return;let startColumn=indent+6+match[1].length+2;return{pattern:match[2],line:lineIndex,startColumn,endColumn:startColumn+match[2].length}}function fileImports(lines){let fences=fenceMap(lines),found=[];for(let index=0;index<lines.length;index++){if(fences[index])continue;let fileImport=fileImportOn(lines[index],index);fileImport&&found.push(fileImport)}return found}var folderOf=path=>path.split("/").slice(0,-1);function relativeTo(from,path){let segments=path.split("/"),common=0;for(;common<from.length&&common<segments.length-1&&from[common]===segments[common];)common++;return[...from.slice(common).map(()=>".."),...segments.slice(common)].join("/")}function importablePaths(documentPath,files){let from=folderOf(documentPath),paths=new Set;for(let file of files.filter(candidate=>candidate!==documentPath&&candidate.toLowerCase().endsWith(".play"))){let relative=relativeTo(from,file),folders=folderOf(relative);paths.add(relative),paths.add([...folders,"*.play"].join("/"));for(let depth=0;depth<=folders.length;depth++)paths.add([...folders.slice(0,depth),"**","*.play"].join("/"))}return[...paths].sort()}var reserved2=new Set(["namespace","sequence","correlation","causation","causedBy","occurred"]),quotedId=/^id\s+"((?:[^"\\]|\\.)*)"$/;function validateInlineEvents2(lines,symbols,application){lines=eventAnalysisSource(lines);let issues=[],fences=fenceMap(lines),documentationBlocks=nonemptyMarkdownBlocks(lines,fences),commandProductions=new Set(symbols.commands.flatMap(command=>command.productionHeaders??[])),eventCounts=new Map,importedNames=new Set;for(let document of[symbols,application]){for(let event of document.events)eventCounts.set(event.name,(eventCounts.get(event.name)??0)+1);for(let imported of document.imports)importedNames.add(imported.shortName)}let report=(line,code,message,severity="error")=>{issues.push({line,startColumn:indentOf(lines[line])+1,endColumn:lines[line].length+1,code,message,severity})};for(let event of symbols.events){let body=directBody(lines,fences,event.line,indentOf(lines[event.line]));if(event.inline){let properties=new Set;for(let property of event.properties)properties.has(property.name)&&report(property.line,diagnosticCodes.duplicateDeclaration,`Event '${event.name}' already declares property '${property.name}'.`),properties.add(property.name);commandProductions.has(event.line)||report(event.line,diagnosticCodes.inlineEventOutsideCommand,"Inline events can only be declared inside commands."),event.generation!==void 0&&report(event.line,diagnosticCodes.inlineEventGeneration,"Inline events are generation 1; extract the event before declaring generations."),((eventCounts.get(event.name)??0)>1||importedNames.has(event.name))&&report(event.line,diagnosticCodes.inlineEventCollision,`Inline event '${event.name}' collides with another declaration or import.`)}let hasId=!1,hasDocumentation=!1;for(let index of body){let text=lines[index].trim(),keyword=text.split(/\s+/)[0];if(event.inline&&keyword==="generation"&&report(index,diagnosticCodes.inlineEventGeneration,"Inline events are generation 1; extract the event before declaring generations."),event.inline&&keyword==="origin"&&report(index,diagnosticCodes.reservedProductionMetadata,"An inline event is local to its command and cannot declare origin."),!/^(?:id|description|documentation)\s+[\w.]+(?:\[\])?(?:\?|\s+optional)?(?:\s*=.*)?$/.test(text)){if(keyword==="id"){let match=text.match(quotedId);hasId||match===null||match[1].trim().length===0?report(index,diagnosticCodes.invalidEventId,'Expected one nonempty id "<old-name>".'):match[1]===event.name&&report(index,diagnosticCodes.redundantEventId,"This id repeats the event name; remove it.","information"),hasId=!0}if(keyword==="documentation"){let next=index+1;for(;next<lines.length&&lines[next].trim().length===0;)next++;(hasDocumentation||text!=="documentation"||lines[next]?.trim()!=="```markdown"||indentOf(lines[next])<=indentOf(lines[index])||!documentationBlocks.has(next))&&report(index,diagnosticCodes.invalidEventDocumentation,"Expected one nonempty fenced markdown documentation block."),hasDocumentation=!0}}}}let productionIndents=[];for(let index=0;index<lines.length;index++){if(fences[index]||lines[index].trim().length===0)continue;let indent=indentOf(lines[index]);for(;productionIndents.length>0&&productionIndents[productionIndents.length-1]>=indent;)productionIndents.pop();let keyword=lines[index].trim().split(/\s+/)[0];reserved2.has(keyword)&&productionIndents.length>0&&report(index,diagnosticCodes.reservedProductionMetadata,`'${keyword}' is system-assigned production metadata.`),keyword==="produces"&&productionIndents.push(indent)}for(let command of symbols.commands){let{identifier,mixed}=productionDestinations(command);for(let production of command.produces??[]){mixed&&production.target===void 0&&report(production.line,diagnosticCodes.explicitProducesTargetsRequired,`Production '${production.name}' must state for explicitly when destinations differ.`);let destination=production.target??(production.inline?identifier:void 0);if(!(identifier===void 0||destination!==identifier))for(let mapping2 of production.mappings.filter(mapping3=>mapping3.source===identifier))report(mapping2.line,diagnosticCodes.eventSourceIdInPayload,`The payload copies '${identifier}', which already identifies the event source.`,production.inline?"warning":"information")}}return issues}function nonemptyMarkdownBlocks(lines,fences){let blocks=new Set,opening,content=!1;for(let index=0;index<lines.length;index++){if(!fences[index])continue;let text=lines[index].trim();opening===void 0?(opening=index,content=!1):text==="```"?(content&&lines[opening].trim()==="```markdown"&&blocks.add(opening),opening=void 0):text.length>0&&(content=!0)}return blocks}function issue(severity,line,startColumn,length,message,code){return{severity,message,line,startColumn,endColumn:startColumn+length,code}}function tokenIssue(severity,line,text,token,message,code){let column2=text.indexOf(token)+1;return issue(severity,line,column2,token.length,message,code)}function validateDeclarations(lines,symbols,application){let issues=[],types=new Set([...knownTypeNames(symbols,primitiveTypes),...knownTypeNames(application,[])]),checkProperties=(properties,owner)=>{for(let property of properties.filter(candidate=>!types.has(propertyTypeReference(candidate).name))){let bare=propertyTypeReference(property).name;issues.push(issue("warning",property.line,property.sourceType.startColumn,property.sourceType.text.length,bare==="optional"?`Unknown type 'optional' on '${property.name}' of ${owner} \u2014 did you forget the type before 'optional'?`:`Unknown type '${bare}' on '${property.name}' of ${owner} \u2014 declare it with 'concept ${bare} : <Primitive>' or 'type ${bare}'.`,diagnosticCodes.unknownType))}};for(let type of symbols.types)checkProperties(type.properties,`type '${type.name}'`);for(let event of symbols.events)checkProperties(event.properties,`event '${event.name}'`);for(let query of symbols.queries)checkProperties(query.parameters,`query '${query.name}'`);for(let command of symbols.commands){checkProperties(command.properties,`command '${command.name}'`);let identifiers=command.properties.filter(property=>property.isIdentifier);for(let extra of identifiers.slice(1))issues.push(tokenIssue("error",extra.line,lines[extra.line],"identifier",`Command '${command.name}' already marks '${identifiers[0].name}' as identifier \u2014 only one property can be the identifier.`,diagnosticCodes.duplicateCommandIdentifier))}let declared=new Map;for(let declaration of[...symbols.concepts,...symbols.types]){if(declared.get(declaration.name)===void 0){declared.set(declaration.name,declaration.line);continue}issues.push(tokenIssue("error",declaration.line,lines[declaration.line],declaration.name,`Duplicate declaration of '${declaration.name}' \u2014 concept and type names must be unique.`,diagnosticCodes.duplicateDeclaration))}return issues}function validateLines(lines,context={}){let fences=fenceMap(lines),symbols=scanDocument(lines),application=context.application??mergeSymbols(),events=new Set([...knownEventNames(symbols),...knownEventNames(application)]),policies=new Set([...symbols.policies,...application.policies].map(policy=>policy.name)),issues=validateDeclarations(lines,symbols,application);issues.push(...validateProductionDestinations(lines,symbols));let optionalCodes=new Set([DiagnosticCodes.LegacyOptionalSuffix,DiagnosticCodes.InvalidOptionalModifierOrder,DiagnosticCodes.OptionalReadsNotSupported]),analysis=responseAnalysis(lines,application.authoringDocuments??application.authoringSources,context.placement,context.path);for(let diagnostic of context.compilerDiagnostics??analysis.diagnostics){if(!optionalCodes.has(diagnostic.code)&&diagnostic.code!==DiagnosticCodes.RepeatedDeclarationAcrossFiles&&!/^PLAY049[01]$|^PLAY048[2-9]$/.test(diagnostic.code))continue;let line=diagnostic.location.line-1,length=legacyOptionalTypeLength(lines[line],diagnostic)||lines[line].length-diagnostic.location.column+1;issues.push(issue(diagnostic.severity,line,diagnostic.location.column,length,diagnostic.message,diagnostic.code))}for(let command of analysis.commands.values()){for(let property of command.properties.filter(property2=>property2.isGenerated))issues.push(issue("information",property.location.line-1,property.location.column,property.name.length,`Generated value '${property.name}' is not a request or form input. ${responseAvailability}`,diagnosticCodes.unavailableResponseExecution));command.response&&issues.push(issue("information",command.response.location.line-1,command.response.location.column,7,responseAvailability,diagnosticCodes.unavailableResponseExecution))}for(let specification of analysis.specifications.values()){for(let fixture of specification.when?.generatedValues??[])issues.push(issue("information",fixture.location.line-1,fixture.location.column,9,responseAvailability,diagnosticCodes.unavailableResponseExecution));specification.thenReturns&&issues.push(issue("information",specification.thenReturns.location.line-1,specification.thenReturns.location.column,12,responseAvailability,diagnosticCodes.unavailableResponseExecution))}let checkEvent=(line,text,name)=>{events.has(name)||issues.push(tokenIssue("warning",line,text,name,`Unknown event type '${name}' \u2014 declare it in a slice or import it.`,diagnosticCodes.unknownEvent))},authorizeIndent=-1;for(let index=0;index<lines.length;index++){let line=lines[index],trimmed=line.trim();if(fences[index]||trimmed.length===0)continue;let leading=line.match(/^[ ]*(\t+)/);if(leading&&issues.push(issue("warning",index,leading[0].length-leading[1].length+1,leading[1].length,"Screenplay is indentation-based \u2014 use spaces, not tabs.",diagnosticCodes.tabIndentation)),authorizeIndent>=0){if(indentOf(line)>authorizeIndent&&/^(?:or\s+)?[A-Z]\w*(?:\s+or\s+[A-Z]\w*)*$/.test(trimmed)){for(let name of trimmed.split(/\s+/).filter(token=>token!=="or"))policies.has(name)||issues.push(tokenIssue("warning",index,line,name,`Unknown policy '${name}' \u2014 declare it with 'policy ${name}'.`,diagnosticCodes.unknownPolicy));continue}authorizeIndent=-1}let fileImportIssue=validateImport(lines,fences,index);fileImportIssue&&issues.push(fileImportIssue);let slice=trimmed.match(/^slice\s+(\w+)/);slice&&!sliceTypes.includes(slice[1])&&issues.push(tokenIssue("error",index,line,slice[1],`Unknown slice type '${slice[1]}' \u2014 expected ${sliceTypes.join(", ")}.`,diagnosticCodes.unknownSliceType));let concept=trimmed.match(/^concept\s+\w+\s*:\s*(\w+)/);concept&&concept[1]!=="Enum"&&!primitiveTypes.includes(concept[1])&&issues.push(tokenIssue("error",index,line,concept[1],`Unknown primitive type '${concept[1]}' \u2014 expected ${primitiveTypes.join(", ")} or Enum.`,diagnosticCodes.unknownPrimitiveType));let authorize=trimmed.match(/^authorize\s+(.*)$/);if(authorize){authorizeIndent=indentOf(line);for(let name of authorize[1].split(/\s+/).filter(token=>token!=="or"&&token.length>0))policies.has(name)||issues.push(tokenIssue("warning",index,line,name,`Unknown policy '${name}' \u2014 declare it with 'policy ${name}'.`,diagnosticCodes.unknownPolicy))}let reactsOn=trimmed.match(/^on\s+([A-Z]\w*)\s*$/);reactsOn&&checkEvent(index,line,reactsOn[1]);let produces=trimmed.match(/^produces\s+([A-Z]\w*)\s*$/);if(produces&&checkEvent(index,line,produces[1]),/^produces\s+when\b/.test(trimmed))for(let next=index+1;next<lines.length;next++){let candidate=lines[next];if(!(fences[next]||candidate.trim().length===0)){if(indentOf(candidate)>indentOf(line)){let name=candidate.trim().match(/^([A-Z]\w*)\s*$/);name&&checkEvent(next,candidate,name[1])}break}}let uniqueEvent=trimmed.match(/^unique\s+event\s+([A-Z]\w*)/);uniqueEvent&&checkEvent(index,line,uniqueEvent[1]);let uniqueProperty=trimmed.match(/^unique\s+[a-z_]\w*\s+on\s+([A-Z]\w*)/);uniqueProperty&&checkEvent(index,line,uniqueProperty[1]);for(let path of line.match(/\$context\.[\w.]+/g)??[]){let segments=path.substring(9).split(".");contextRoots.includes(segments[0])?segments[0]==="causedBy"&&segments.length>1&&!causedByProperties.includes(segments[1])?issues.push(tokenIssue("warning",index,line,path,`Unknown $context.causedBy property '${segments[1]}' \u2014 expected ${causedByProperties.join(", ")}.`,diagnosticCodes.unknownContextCausedByProperty)):segments[0]==="identity"&&segments.length>1&&!identityProperties.includes(segments[1])&&issues.push(tokenIssue("warning",index,line,path,`Unknown $context.identity property '${segments[1]}' \u2014 expected ${identityProperties.join(", ")}.`,diagnosticCodes.unknownContextIdentityProperty)):issues.push(tokenIssue("warning",index,line,path,`Unknown $context path '${segments.join(".")}' \u2014 expected one of ${contextRoots.join(", ")}.`,diagnosticCodes.unknownContextPath))}}issues.push(...validateEventContextPaths(lines,fences)),issues.push(...validateInlineEvents2(lines,symbols,application));let fenceLines=lines.map((line,index)=>({line,index})).filter(({line})=>/^\s*```(?:[a-z]+)?\s*$/.test(line));if(fenceLines.length%2===1){let last=fenceLines[fenceLines.length-1];issues.push(issue("error",last.index,1,last.line.length+1,"Unclosed inline code block \u2014 expected a closing ``` line.",diagnosticCodes.unclosedCodeBlock))}return issues}function validateProductionDestinations(lines,symbols){let issues=[];lines=eventAnalysisSource(lines);for(let command of symbols.commands){let identifiers=command.properties.filter(property=>property.isIdentifier&&!propertyTypeReference(property).isOptional&&!propertyTypeReference(property).isCollection);if(identifiers.length===1)for(let production of command.produces??[]){if(production.inline||production.conditional||production.target!==void 0)continue;let line=production.line;issues.push(issue("information",line,indentOf(lines[line])+1,lines[line].trim().length,`Plain 'produces ${production.name}' omits its destination \u2014 use 'for ${identifiers[0].name}' to explicitly select the command's identifier.`,diagnosticCodes.omittedProductionDestination))}}return issues}function validateImport(lines,fences,index){let line=lines[index],trimmed=line.trim().replace(/\s*\/\/.*$/,"");if(!/^import\b/.test(trimmed)||fileImportOn(line,index))return;let indent=indentOf(line);if(!(!(indent>0&&["module","feature"].includes(enclosingChain(lines,fences,index,indent)[0]))&&!isFileImportLine(line)))return issue("error",index,indent+1,trimmed.length,`Invalid import '${trimmed}' \u2014 inside a module or feature, import names files: 'import "<path or glob>"'.`,diagnosticCodes.invalidFileImport)}var mappingTarget=/^(?:(?:increment|decrement|count|clear|add|subtract|set)\s+)?@?([$\w.]+)(?=\s|=|$)/;function validateEventContextPaths(lines,fences){let issues=[],names=members=>members.map(member=>member.name).join(", ");for(let index=0;index<lines.length;index++){let line=lines[index];if(fences[index])continue;for(let match of line.matchAll(/(\.)?\$eventContext((?:\.(?:\w+(?:\(\))?)?)*)/g)){let token=match[0].substring(match[1]?.length??0),written=match[2];if(written.length===0){match[1]&&issues.push(issue("error",index,(match.index??0)+2,token.length,`'$eventContext' names no member - expected one of ${names(resolveEventContextPath("").expected)}.`,diagnosticCodes.missingEventContextPath));continue}let path=written.substring(1),resolution=resolveEventContextPath(path),column2=(match.index??0)+(match[1]?.length??0)+1;switch(resolution.status){case"missing":issues.push(issue("error",index,column2,token.length,`'$eventContext.${path}' names no member - expected one of ${names(resolution.expected)}.`,diagnosticCodes.missingEventContextPath));break;case"unknownMember":issues.push(issue("warning",index,column2,token.length,`Unknown event context member '${resolution.segment}' in '$eventContext.${path}' - expected one of ${names(resolution.expected)}.`,diagnosticCodes.unknownEventContextMember));break;case"unknownSubPath":{let has=resolution.expected.length===0?"no members to address":`members ${names(resolution.expected)}`;issues.push(issue("warning",index,column2,token.length,`Unknown event context path '$eventContext.${path}' - '${resolution.member?.name}' (${resolution.member?.type}) has ${has}.`,diagnosticCodes.unknownEventContextPath));break}case"belowCollection":issues.push(issue("error",index,column2,token.length,`'$eventContext.${path}' cannot resolve - '${resolution.member?.name}' is a collection (${resolution.member?.type}) and cannot be addressed below.`,diagnosticCodes.eventContextPathBelowCollection));break}}let target=line.trim().match(mappingTarget)?.[1],source=target?.match(/\.\$(\w+)/)?.[1];target&&source&&source!=="eventContext"&&issues.push(tokenIssue("warning",index,line,target,`Dynamic dictionary key '$${source}' in '${target}' is never resolved - only '$eventContext.<path>' is, so the literal text '$${source}' becomes the key.`,diagnosticCodes.unresolvedDynamicKeySource))}return issues}export{languageId,languageExtensionPoint,constructKeywords,clauseKeywords,codeBlockTags,contextRoots,causedByProperties,sliceTypes,primitiveTypes,conceptAttributes,languageConfiguration,typeReferenceSymbol,typeReferenceText,DiagnosticCodes,isQuickFixDiagnostic,prepareQuickFixes,withoutComment,indentOf,firstWord,fenceMap,enclosingChain,nearestEnclosingLine,eventAnalysisSource,responseAvailability,responseAnalysis,fileReferenceKeyword,isAbsoluteFileReferencePath,fileReferenceOn,fileReferences,propertyTypeReference,directBody,scanDocument,mergeSymbols,knownEventNames,builtInTriggerNames,knownTriggerNames,knownTypeNames,eventContextPaths,namesEventContextMember,eventContextMembers,eventContextMembersAfter,eventContextMemberAt,describeEventContext,describeEventContextMember,productionDestinations,destinationHints,diagnosticCodes,isFileImportLine,fileImportOn,fileImports,importablePaths,validateLines,validateEventContextPaths};
13
- //# sourceMappingURL=chunk-TWF2T5S4.js.map