public override void Compile(ICompileContext context, IProjectItem projectItem) { var serializationFile = projectItem as SerializationFile; Assert.Cast(serializationFile, nameof(serializationFile)); var textDocument = (ITextSnapshot)serializationFile.Snapshot; var rootTextNode = textDocument.Root; if (rootTextNode == TextNode.Empty) { Trace.TraceError(Msg.C1050, Texts.Document_is_not_valid, textDocument.SourceFile.AbsoluteFileName, TextSpan.Empty); return; } var lines = textDocument.SourceFile.ReadAsLines(); var itemBuilder = new ItemBuilder(Factory); ParseItem(context, textDocument, itemBuilder, lines); var item = itemBuilder.Build(serializationFile.Project, rootTextNode); item.IsEmittable = false; item.References.AddRange(ReferenceParser.ParseReferences(item, item.TemplateIdOrPathProperty)); foreach (var field in item.Fields) { item.References.AddRange(ReferenceParser.ParseReferences(field)); } var addedItem = context.Project.AddOrMerge(item); serializationFile.SerializationItemUri = addedItem.Uri; }
/// <summary> /// This Operation is called, when the module shall initialize itself. /// </summary> /// <param name="typeRegistry">The type registry for service requests or registrations.</param> /// <inheritdoc/> public void Initialize(ITypeRegistry typeRegistry) { var modelBuilderFactory = typeRegistry.GetObject <IModelBuilderFactory>(); var dataTypeRegistry = typeRegistry.GetObject <IDataTypeRegistry>(); var modelItemNamingService = typeRegistry.GetObject <IModelItemNamingService>(); var odataObjectFactory = typeRegistry.GetObject <IODataObjectFactory>(); var structuralPropertyBinder = new StructuralPropertyBinder(); var navigationPropertyBinder = new NavigationPropertyBinder(); var entityReader = new EntityReader(); var referenceParser = new ReferenceParser(entityReader); var uncontainedNavigationPropertyParser = new UncontainedNavigationPropertyParser(referenceParser); var dependencyResolver = new DependencyResolver(uncontainedNavigationPropertyParser); var entityCreator = new EntityCreator( structuralPropertyBinder, navigationPropertyBinder, uncontainedNavigationPropertyParser, dependencyResolver); var entityUpdater = new EntityUpdater(structuralPropertyBinder, navigationPropertyBinder, uncontainedNavigationPropertyParser); uncontainedNavigationPropertyParser.SetUncontainedEntitiesFactory(entityCreator.CreateInUncontainedNavigationProperty); typeRegistry.RegisterInstance <IBindableModelBuilderFactory>(new BindableModelBuilderFactory(modelBuilderFactory)); typeRegistry.RegisterInstance <IEntityCreator>(entityCreator); typeRegistry.RegisterInstance <IEntityReader>(entityReader); typeRegistry.RegisterInstance <IEntityUpdater>(entityUpdater); typeRegistry.RegisterInstance <IFactonQueryService>(CreateQueryService(typeRegistry)); typeRegistry.RegisterInstance <IStructuralPropertyFactory>(new StructuralPropertyFactory(dataTypeRegistry, modelItemNamingService)); typeRegistry.RegisterInstance <IODataEntityDtoBuilderFactory>(new ODataEntityDtoBuilderFactory(odataObjectFactory)); }
protected virtual void ParseFieldTextNode([NotNull] ItemParseContext context, [NotNull] Item item, [NotNull] LanguageVersionContext languageVersionContext, [NotNull] ITextNode fieldTextNode) { SchemaService.ValidateTextNodeSchema(fieldTextNode, "Field"); var fieldName = fieldTextNode.Key.UnescapeXmlElementName(); if (fieldName == "Name" || fieldName == "Id" || fieldName == "Database" || fieldName == "TemplateName" || fieldName == "ItemPath" || fieldName == "ParentItemPath" || fieldName == Constants.Fields.IsEmittable || fieldName == Constants.Fields.IsImport) { return; } var field = Factory.Field(item).With(fieldTextNode); field.FieldNameProperty.SetValue(new AttributeNameTextNode(fieldTextNode)); field.LanguageProperty.SetValue(languageVersionContext.LanguageProperty); field.VersionProperty.SetValue(languageVersionContext.VersionProperty); field.ValueProperty.SetValue(fieldTextNode); // check if field is already defined var duplicate = item.Fields.FirstOrDefault(f => string.Equals(f.FieldName, field.FieldName, StringComparison.OrdinalIgnoreCase) && f.Language == field.Language && f.Version == field.Version); if (duplicate == null) { item.Fields.Add(field); } else { Trace.TraceError(Msg.P1008, Texts.Field_is_already_defined, fieldTextNode, duplicate.FieldName); } if (!item.IsImport) { item.References.AddRange(ReferenceParser.ParseReferences(field)); } }
public ExtensionParser(char marker, string substitution, Parser innerParser) { ExtensionMarker = new CharacterParser (marker); ReferenceParser = new ReferenceParser (); InnerParser = innerParser; Substitution = substitution; }
protected virtual void ParseField([NotNull] ItemParseContext context, [NotNull] Template template, [NotNull] TemplateSection templateSection, [NotNull] ITextNode templateFieldTextNode, ref int nextSortOrder) { SchemaService.ValidateTextNodeSchema(templateFieldTextNode, "TemplateField"); GetName(context.ParseContext, templateFieldTextNode, out var fieldName, out var fieldNameTextNode, "Field", "Name"); if (string.IsNullOrEmpty(fieldName)) { Trace.TraceError(Msg.P1005, Texts._Field__element_must_have_a__Name__attribute, templateFieldTextNode.Snapshot.SourceFile.AbsoluteFileName, templateFieldTextNode.TextSpan); return; } var templateField = templateSection.Fields.FirstOrDefault(f => string.Equals(f.FieldName, fieldName, StringComparison.OrdinalIgnoreCase)); if (templateField == null) { var itemIdOrPath = template.ItemIdOrPath + "/" + templateSection.SectionName + "/" + fieldName; var guid = StringHelper.GetGuid(template.Project, templateFieldTextNode.GetAttributeValue("Id", itemIdOrPath)); templateField = Factory.TemplateField(template, guid).With(templateFieldTextNode); templateSection.Fields.Add(templateField); templateField.FieldNameProperty.SetValue(fieldNameTextNode); templateField.FieldName = fieldName; } templateField.TypeProperty.Parse(templateFieldTextNode, "Single-Line Text"); templateField.Shared = string.Equals(templateFieldTextNode.GetAttributeValue("Sharing"), "Shared", StringComparison.OrdinalIgnoreCase); templateField.Unversioned = string.Equals(templateFieldTextNode.GetAttributeValue("Sharing"), "Unversioned", StringComparison.OrdinalIgnoreCase); templateField.SourceProperty.Parse(templateFieldTextNode); templateField.ShortHelpProperty.Parse(templateFieldTextNode); templateField.LongHelpProperty.Parse(templateFieldTextNode); templateField.SortorderProperty.Parse(templateFieldTextNode, nextSortOrder); nextSortOrder = templateField.Sortorder + 100; // set field standard value var standardValueTextNode = templateFieldTextNode.GetAttribute("StandardValue"); if (standardValueTextNode != null && !string.IsNullOrEmpty(standardValueTextNode.Value)) { if (template.StandardValuesItem == null) { Trace.TraceError(Msg.P1006, Texts.Template_does_not_a_standard_values_item, standardValueTextNode); } else { var field = template.StandardValuesItem.Fields.GetField(templateField.FieldName); if (field == null) { field = Factory.Field(template.StandardValuesItem).With(standardValueTextNode); field.FieldNameProperty.SetValue(fieldNameTextNode); template.StandardValuesItem.Fields.Add(field); } field.ValueProperty.SetValue(standardValueTextNode); } } template.References.AddRange(ReferenceParser.ParseReferences(template, templateField.SourceProperty)); }
public void BibleReferenceTestBasicSingleVerse() { string t = "2 Samuel 12:7"; List <Reference> theRefs = ReferenceParser.ParseReference(t); Assert.AreEqual("2 Samuel", theRefs.First().Book.Name); Assert.AreEqual("12", theRefs.First().ChapterAndVerses.First().StartChapter); Assert.AreEqual("7", theRefs.First().ChapterAndVerses.First().StartVerse); Assert.AreEqual("12", theRefs.First().ChapterAndVerses.First().EndChapter); Assert.AreEqual("7", theRefs.First().ChapterAndVerses.First().EndVerse); }
public void BibleReferenceTestBasicWithSubVerse() { string t = "2 Samuel 12:1–7a"; List <Reference> theRefs = ReferenceParser.ParseReference(t); Assert.AreEqual(theRefs.First().Book.Name, "2 Samuel"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().StartChapter, "12"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().StartVerse, "1"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().EndChapter, "12"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().EndVerse, "7"); }
public void BibleReferenceTestBasicMultipleVerses() { string t = "John 12:1–7"; List <Reference> theRefs = ReferenceParser.ParseReference(t); Assert.AreEqual("John", theRefs.First().Book.Name); Assert.AreEqual("12", theRefs.First().ChapterAndVerses.First().StartChapter); Assert.AreEqual("1", theRefs.First().ChapterAndVerses.First().StartVerse); Assert.AreEqual("12", theRefs.First().ChapterAndVerses.First().EndChapter); Assert.AreEqual("7", theRefs.First().ChapterAndVerses.First().EndVerse); }
private static List <CSharpReference> ParseReferences(XmlNode[] propertyGroups) { List <CSharpReference> ret = new List <CSharpReference>(); for (int i = 0; i < propertyGroups.Length; i++) { List <XmlNode> children = GetChildren(propertyGroups[i]); for (int childIndex = 0; childIndex < children.Count; childIndex++) { ret.Add(ReferenceParser.Parse(children[childIndex])); } } return(ret); }
public void BibleReferenceTestCommad() { string t = "Psalm 139:1-12, 23-24"; List <Reference> theRefs = ReferenceParser.ParseReference(t); Assert.AreEqual(theRefs.First().Book.Name, "Psalm"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().StartChapter, "139"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().StartVerse, "1"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().EndChapter, "139"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().EndVerse, "12"); Assert.AreEqual(theRefs.First().ChapterAndVerses[1].StartChapter, "139"); Assert.AreEqual(theRefs.First().ChapterAndVerses[1].StartVerse, "23"); Assert.AreEqual(theRefs.First().ChapterAndVerses[1].EndChapter, "139"); Assert.AreEqual(theRefs.First().ChapterAndVerses[1].EndVerse, "24"); }
public void BibleReferenceTestCommadWithTwoChapters() { string t = "Psalm 139:1-12, 140:2-141:3"; List <Reference> theRefs = ReferenceParser.ParseReference(t); Assert.AreEqual(theRefs.First().Book.Name, "Psalm"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().StartChapter, "139"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().StartVerse, "1"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().EndChapter, "139"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().EndVerse, "12"); Assert.AreEqual(theRefs[0].ChapterAndVerses[1].StartChapter, "140"); Assert.AreEqual(theRefs[0].ChapterAndVerses[1].StartVerse, "2"); Assert.AreEqual(theRefs[0].ChapterAndVerses[1].EndChapter, "141"); Assert.AreEqual(theRefs[0].ChapterAndVerses[1].EndVerse, "3"); }
public void BibleReferenceTestBasicTwo() { string t = "2 Samuel 12:1–7;Matthew 2:23-34"; List <Reference> theRefs = ReferenceParser.ParseReference(t); Assert.AreEqual(theRefs.First().Book.Name, "2 Samuel"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().StartChapter, "12"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().StartVerse, "1"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().EndChapter, "12"); Assert.AreEqual(theRefs.First().ChapterAndVerses.First().EndVerse, "7"); Assert.AreEqual(theRefs[1].Book.Name, "Matthew"); Assert.AreEqual(theRefs[1].ChapterAndVerses.First().StartChapter, "2"); Assert.AreEqual(theRefs[1].ChapterAndVerses.First().StartVerse, "23"); Assert.AreEqual(theRefs[1].ChapterAndVerses.First().EndChapter, "2"); Assert.AreEqual(theRefs[1].ChapterAndVerses.First().EndVerse, "34"); }
public void Simple(string input, string expectedValue) { // Create the lexer. IrLexer lexer = new IrLexer(input); // Invoke the lexer and create the corresponding stream. TokenStream stream = new TokenStream(lexer.Tokenize()); // Create the parser context. ParserContext context = new ParserContext(stream); // Invoke the parser. Reference result = new ReferenceParser().Parse(context); // Compare resulting value. Assert.AreEqual(expectedValue, result.Value); }
public override void Parse(ItemParseContext context, ITextNode textNode) { SchemaService.ValidateTextNodeSchema(textNode, "Item"); var itemNameTextNode = GetItemNameTextNode(context.ParseContext, textNode); var parentItemPath = textNode.GetAttributeValue("ParentItemPath", context.ParentItemPath); var itemIdOrPath = textNode.GetAttributeValue("ItemPath"); if (string.IsNullOrEmpty(itemIdOrPath)) { itemIdOrPath = PathHelper.CombineItemPath(parentItemPath, itemNameTextNode.Value); } else if (itemNameTextNode.Value != Path.GetFileName(itemIdOrPath)) { Trace.TraceError(Msg.P1027, "Item name in 'ItemPath' and 'Name' does not match. Using 'Name'"); } var guid = StringHelper.GetGuid(context.ParseContext.Project, textNode.GetAttributeValue("Id", itemIdOrPath)); var databaseName = textNode.GetAttributeValue("Database", context.Database.DatabaseName); var database = context.ParseContext.Project.GetDatabase(databaseName); var templateIdOrPath = textNode.GetAttributeValue("TemplateName", textNode.Key.UnescapeXmlElementName()); var item = Factory.Item(database, guid, itemNameTextNode.Value, itemIdOrPath, templateIdOrPath).With(textNode); item.ItemNameProperty.AddSourceTextNode(itemNameTextNode); item.TemplateIdOrPathProperty.AddSourceTextNode(new AttributeNameTextNode(textNode)); item.SortorderProperty.Parse(textNode, context.Sortorder); item.IsEmittable = textNode.GetAttributeBool(Constants.Fields.IsEmittable, true); item.IsImport = textNode.GetAttributeBool(Constants.Fields.IsImport, context.IsImport); if (!item.IsImport) { item.References.AddRange(ReferenceParser.ParseReferences(item, item.TemplateIdOrPathProperty)); } // parse shared fields var fieldContext = new LanguageVersionContext(); ParseAttributes(context, item, fieldContext, textNode); // parse Fields, Layout and Items child text nodes ParseChildNodes(context, item, textNode); context.ParseContext.Project.AddOrMerge(item); }
public CreationResult Create( int parentElementId, double startTime, double endTime, double watchPoint, ViewMode viewMode, bool shouldDisplay) { var html = ContentEx.GetFirstHtmlCtrl(); var refs = ReferenceParser.GetReferences(html); if (refs == null) { return(CreationResult.FailUnknown); } var ytEl = new YouTubeMediaElement { Id = this.Id, StartTime = startTime, EndTime = endTime, WatchPoint = watchPoint, ViewMode = viewMode, }; refs.Title += $": {startTime} -> {endTime}"; string elementHtml = string.Format(CultureInfo.InvariantCulture, MediaPlayerConst.YouTubeElementFormat, refs.Title, ytEl.GetJsonB64()); var contents = new List <ContentBase> { new TextContent(true, elementHtml) }; var priority = MediaPlayerConst.DefaultExtractPriority; return(ContentEx.CreateSMElement(parentElementId, priority, contents, refs, shouldDisplay)); }
public NuggetPalaceWdw(string content, int elementId) { if (string.IsNullOrEmpty(content)) { return; } var root = Svc.SM.Registry.Element[elementId]; if (root == null) { return; } RootElement = new ObservableCollection <IElement> { new ElementWrapper(root) }; References references = ReferenceParser.GetReferences(content); if (references == null) { return; } Url = references.Link ?? string.Empty; NuggetTitle = references.Title ?? string.Empty; Author = references.Author ?? string.Empty; Source = references.Source ?? string.Empty; InitializeComponent(); Closing += NuggetPalaceWdw_Closing; Svc <NuggetPalacePlugin> .Plugin.WdwOpen = true; DataContext = this; }
public override void Parse(ItemParseContext context, ITextNode textNode) { SchemaService.ValidateTextNodeSchema(textNode, "Template"); var itemNameTextNode = GetItemNameTextNode(context.ParseContext, textNode); var parentItemPath = textNode.GetAttributeValue("ParentItemPath", context.ParentItemPath); var itemIdOrPath = textNode.GetAttributeValue("ItemPath"); if (string.IsNullOrEmpty(itemIdOrPath)) { itemIdOrPath = PathHelper.CombineItemPath(parentItemPath, itemNameTextNode.Value); } else if (itemNameTextNode.Value != Path.GetFileName(itemIdOrPath)) { Trace.TraceError(Msg.P1034, "Item name in 'ItemPath' and 'Name' does not match. Using 'Name'"); } var guid = StringHelper.GetGuid(context.ParseContext.Project, textNode.GetAttributeValue("Id", itemIdOrPath)); var databaseName = textNode.GetAttributeValue("Database", context.Database.DatabaseName); var database = context.ParseContext.Project.GetDatabase(databaseName); var template = Factory.Template(database, guid, itemNameTextNode.Value, itemIdOrPath); template.ItemNameProperty.AddSourceTextNode(itemNameTextNode); template.BaseTemplatesProperty.Parse(textNode, Constants.Templates.StandardTemplateId); template.IconProperty.Parse(textNode); template.ShortHelpProperty.Parse(textNode); template.LongHelpProperty.Parse(textNode); template.IsEmittable = textNode.GetAttributeBool(Constants.Fields.IsEmittable, true); template.IsImport = textNode.GetAttributeBool(Constants.Fields.IsImport, context.IsImport); template.References.AddRange(ReferenceParser.ParseReferences(template, template.BaseTemplatesProperty)); Item standardValuesItem; var standardValuesTextNode = textNode.ChildNodes.FirstOrDefault(n => string.Equals(n.Value, "__Standard Values", StringComparison.OrdinalIgnoreCase)); if (standardValuesTextNode != null) { var newContext = Factory.ItemParseContext(context.ParseContext, context.Parser, template.Database, template.ItemIdOrPath, template.IsImport); context.Parser.ParseTextNode(newContext, standardValuesTextNode); standardValuesItem = template.Database.GetItem(template.ItemIdOrPath + "/__Standard Values"); if (standardValuesItem == null) { Trace.TraceError(Msg.C1137, "'__Standard Values' item not parsed correctly", standardValuesTextNode); } } else { // create standard values item var standardValuesItemIdOrPath = itemIdOrPath + "/__Standard Values"; var standardValuesGuid = StringHelper.GetGuid(context.ParseContext.Project, standardValuesItemIdOrPath); standardValuesItem = Factory.Item(database, standardValuesGuid, "__Standard Values", standardValuesItemIdOrPath, itemIdOrPath).With(textNode); context.ParseContext.Project.AddOrMerge(standardValuesItem); } if (standardValuesItem != null) { // todo: should be Uri template.StandardValuesItem = standardValuesItem; standardValuesItem.IsImport = template.IsImport; } // parse fields and sections foreach (var sectionTreeNode in textNode.ChildNodes) { ParseSection(context, template, sectionTreeNode); } Pipelines.GetPipeline <TemplateParserPipeline>().Execute(context, template, textNode); context.ParseContext.Project.AddOrMerge(template); }
public override void Compile(ICompileContext context, IProjectItem projectItem) { var item = projectItem as Item; Assert.Cast(item, nameof(item)); var standardTemplate = item.Database.FindQualifiedItem <Template>(Constants.Templates.StandardTemplateId); if (standardTemplate == null) { Trace.TraceWarning(Msg.C1135, "Standard Template not found - are you missing a reference?"); return; } var standardFields = standardTemplate.GetAllFields().ToArray(); var templateIdOrPathTextNode = item.GetTextNodes().Select(n => n.GetAttribute("Template")).FirstOrDefault(t => t != null); if (templateIdOrPathTextNode == null) { Trace.TraceError(Msg.C1051, Texts.The__Template__attribute_must_be_specified_when__Template_CreateFromFields__equals_true_, TraceHelper.GetTextNode(item)); } var itemTextNode = item.SourceTextNode; var itemIdOrPath = item.TemplateIdOrPath; var itemName = itemIdOrPath.Mid(itemIdOrPath.LastIndexOf('/') + 1); var guid = StringHelper.GetGuid(item.Project, itemTextNode.GetAttributeValue("Template.Id", itemIdOrPath)); var template = Factory.Template(item.Database, guid, itemName, itemIdOrPath).With(itemTextNode); template.ItemNameProperty.AddSourceTextNode(templateIdOrPathTextNode); template.ItemNameProperty.Flags = SourcePropertyFlags.IsQualified; template.IconProperty.Parse("Template.Icon", itemTextNode); template.BaseTemplatesProperty.Parse("Template.BaseTemplates", itemTextNode, Constants.Templates.StandardTemplateId); template.ShortHelpProperty.Parse("Template.ShortHelp", itemTextNode); template.LongHelpProperty.Parse("Template.LongHelp", itemTextNode); template.IsEmittable = item.IsEmittable; template.IsImport = item.IsImport || string.Equals(itemTextNode.GetAttributeValue(Constants.Fields.IsImport), "True", StringComparison.OrdinalIgnoreCase); if (!template.IsImport) { template.References.AddRange(ReferenceParser.ParseReferences(template, template.BaseTemplatesProperty)); } if (item.Fields.Any()) { var templateSectionGuid = StringHelper.GetGuid(projectItem.Project, template.ItemIdOrPath + "/Fields"); // section var templateSection = Factory.TemplateSection(template, templateSectionGuid); template.Sections.Add(templateSection); templateSection.SectionNameProperty.SetValue("Fields"); templateSection.IconProperty.SetValue("Applications/16x16/form_blue.png"); // fields var nextSortOrder = 0; foreach (var field in item.Fields) { var childNode = field.SourceTextNode; // ignore standard fields if (standardFields.Any(f => string.Equals(f.FieldName, field.FieldName, StringComparison.OrdinalIgnoreCase))) { continue; } var templateField = template.Sections.SelectMany(s => s.Fields).FirstOrDefault(f => f.FieldName == field.FieldName); if (templateField == null) { var templateFieldGuid = StringHelper.GetGuid(projectItem.Project, template.ItemIdOrPath + "/Fields/" + field.FieldName); templateField = Factory.TemplateField(template, templateFieldGuid).With(childNode); templateSection.Fields.Add(templateField); templateField.FieldNameProperty.SetValue(field.FieldNameProperty); templateField.TypeProperty.Parse("Field.Type", childNode, "Single-Line Text"); templateField.SortorderProperty.Parse("Field.SortOrder", childNode, nextSortOrder); } else { // todo: multiple sources? templateField.FieldNameProperty.AddSourceTextNode(field.FieldNameProperty.SourceTextNode); templateField.TypeProperty.ParseIfHasAttribute("Field.Type", childNode); templateField.SortorderProperty.ParseIfHasAttribute("Field.SortOrder", childNode); } templateField.Shared |= string.Equals(childNode.GetAttributeValue("Field.Sharing"), "Shared", StringComparison.OrdinalIgnoreCase); templateField.Unversioned |= string.Equals(childNode.GetAttributeValue("Field.Sharing"), "Unversioned", StringComparison.OrdinalIgnoreCase); templateField.SourceProperty.ParseIfHasAttribute("Field.Source", childNode); templateField.ShortHelpProperty.ParseIfHasAttribute("Field.ShortHelp", childNode); templateField.LongHelpProperty.ParseIfHasAttribute("Field.LongHelp", childNode); nextSortOrder = templateField.Sortorder + 100; // todo: added multiple times if merged template.References.AddRange(ReferenceParser.ParseReferences(template, templateField.SourceProperty)); } } context.Project.AddOrMerge(template); }