diff --git a/Common/EntityBuilder.cs b/Common/EntityBuilder.cs index d2870856bb0d8aa109aadd331bb15451489d7271..b0582761544a10ae340e119b96b14775f5cd443c 100644 --- a/Common/EntityBuilder.cs +++ b/Common/EntityBuilder.cs @@ -28,7 +28,6 @@ namespace Dos.Tools private bool _isView = false; private bool _isSZMDX = false; - private bool _isNewModel = false; public EntityBuilder(string tableName, string nameSpace, string className, List columns, bool isView) : this(tableName, nameSpace, className, columns, isView, false) @@ -36,14 +35,13 @@ namespace Dos.Tools } - public EntityBuilder(string tableName, string nameSpace, string className, List columns, bool isView, bool isSZMDX, string dbType = null, bool isNewModel = false) + public EntityBuilder(string tableName, string nameSpace, string className, List columns, bool isView, bool isSZMDX, string dbType = null) { _isSZMDX = isSZMDX; _className = Utils.ReplaceSpace(className); _nameSpace = Utils.ReplaceSpace(nameSpace); _tableName = tableName; _dbType = dbType; - _isNewModel = isNewModel; if (_isSZMDX) { _className = Utils.ToUpperFirstword(_className); @@ -104,7 +102,12 @@ namespace Dos.Tools } } - public string Builder(string tplContent = "") + /// + /// 使用模板生成代码 + /// + /// 模板文件的内容 + /// + public string Builder(string tplContent) { Columns = DbToCS.DbtoCSColumns(Columns, DbType); if (!string.IsNullOrWhiteSpace(tplContent)) @@ -139,60 +142,7 @@ namespace Dos.Tools return plus.ToString() + result; #endregion } - else { - #region 老版本 - StringPlus plus = new StringPlus(); - plus.AppendLine("//------------------------------------------------------------------------------"); - plus.AppendLine("// "); - plus.AppendLine("// 此代码由工具生成。"); - plus.AppendLine("// 运行时版本:" + Environment.Version.ToString()); - plus.AppendLine("// Website: http://ITdos.com/Dos/ORM/Index.html"); - plus.AppendLine("// 对此文件的更改可能会导致不正确的行为,并且如果"); - plus.AppendLine("// 重新生成代码,这些更改将会丢失。"); - plus.AppendLine("// "); - plus.AppendLine("//------------------------------------------------------------------------------"); - plus.AppendLine(); - plus.AppendLine(); - plus.AppendLine("using System;"); - plus.AppendLine("using System.Data;"); - plus.AppendLine("using System.Data.Common;"); - plus.AppendLine("using Dos.ORM;"); - plus.AppendLine("using Dos.ORM.Common;"); - plus.AppendLine(); - plus.AppendLine("namespace " + NameSpace); - plus.AppendLine("{"); - plus.AppendLine(); - plus.AppendSpaceLine(1, "/// "); - plus.AppendSpaceLine(1, "/// 实体类" + ClassName + " 。(属性说明自动提取数据库字段的描述信息)"); - plus.AppendSpaceLine(1, "/// "); - if (!_isNewModel) - { - //plus.AppendSpaceLine(1, "[Serializable]"); - } - else - { - plus.AppendSpaceLine(1, "[Table(\"" + TableName + "\")]"); - } - plus.AppendSpaceLine(1, "[Serializable]"); - plus.AppendSpaceLine(1, "public partial class " + ClassName + " : Entity "); - plus.AppendSpaceLine(1, "{"); - if (!_isNewModel) - { - plus.AppendSpaceLine(2, "public " + ClassName + "():base(\"" + TableName + "\") {}"); - plus.AppendLine(); - } - else - { - //plus.AppendSpaceLine(2, "public " + ClassName + "() { }"); - } - plus.AppendLine(BuilderModel()); - plus.AppendLine(BuilderMethod()); - plus.AppendSpaceLine(1, "}"); - plus.AppendLine("}"); - plus.AppendLine(""); - return plus.ToString(); - #endregion - } + return "请使用模板生成方式"; } private string BuilderModel() diff --git a/Common/Utils.cs b/Common/Utils.cs index 3e7ee6d39e8566f528657009627c94b678605fa8..527c0be0ddc4179562c5adedc716db2e3a01dd42 100644 --- a/Common/Utils.cs +++ b/Common/Utils.cs @@ -370,6 +370,54 @@ namespace Dos.Tools } - + /** + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:HELLO_WORLD->HelloWorld + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + /// + /// 转换为驼峰命名 + /// + /// + /// + public static string ToCamelName(string name) + { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || string.IsNullOrEmpty(name)) + { + // 没必要转换 + return ""; + } + else if (!name.Contains("_")) + { + // 不含下划线,仅将首字母大写 + return name.Substring(0, 1).ToUpper() + name.Substring(1).ToLower(); + } + // 用下划线将原始字符串分割 + string[] camels = name.Split('_'); + foreach (string camel in camels) + { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (string.IsNullOrEmpty(camel)) + { + continue; + } + // 处理真正的驼峰片段 + //if (result.Length == 0) + //{ + // // 第一个驼峰片段,全部字母都小写 + // result.Append(camel.ToLower()); + //} + //else + //{ + // 其他的驼峰片段,首字母大写 + result.Append(camel.Substring(0, 1).ToUpper()); + result.Append(camel.Substring(1).ToLower()); + //} + } + return result.ToString(); + } } } diff --git a/Dos.Tool.csproj b/Dos.Tool.csproj index 082286f26a84a1b36f0b393c102e28f6c54dbe77..003eb1283ce67e4b5f9e5bd5a9ea9608abb4672b 100644 --- a/Dos.Tool.csproj +++ b/Dos.Tool.csproj @@ -200,6 +200,9 @@ Always + + Always + Always diff --git a/Forms/BatchForm.Designer.cs b/Forms/BatchForm.Designer.cs index 303e299d634fa69407b7157aafa58188b810a01e..bdde22a197f2f969705094d685cddd40c2967d5c 100644 --- a/Forms/BatchForm.Designer.cs +++ b/Forms/BatchForm.Designer.cs @@ -46,10 +46,12 @@ this.btnback = new System.Windows.Forms.Button(); this.lbright = new System.Windows.Forms.ListBox(); this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.txt_wjj = new System.Windows.Forms.TextBox(); + this.label9 = new System.Windows.Forms.Label(); + this.label10 = new System.Windows.Forms.Label(); this.txtTableStar = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.label8 = new System.Windows.Forms.Label(); - this.cbEntityTableName = new System.Windows.Forms.CheckBox(); this.cbToupperFrstword = new System.Windows.Forms.CheckBox(); this.button2 = new System.Windows.Forms.Button(); this.txtNamaspace = new System.Windows.Forms.TextBox(); @@ -61,9 +63,8 @@ this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); this.pbar = new System.Windows.Forms.ProgressBar(); this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); - this.txt_wjj = new System.Windows.Forms.TextBox(); //创建类子文件夹 例com_aa 这里填写com 生成com文件夹 - this.label9 = new System.Windows.Forms.Label(); - this.label10 = new System.Windows.Forms.Label(); + this.tplComboBox = new System.Windows.Forms.ComboBox(); + this.label11 = new System.Windows.Forms.Label(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); this.panelbtns.SuspendLayout(); @@ -235,13 +236,14 @@ // // groupBox3 // + this.groupBox3.Controls.Add(this.tplComboBox); + this.groupBox3.Controls.Add(this.label11); this.groupBox3.Controls.Add(this.txt_wjj); this.groupBox3.Controls.Add(this.label9); this.groupBox3.Controls.Add(this.label10); this.groupBox3.Controls.Add(this.txtTableStar); this.groupBox3.Controls.Add(this.label2); this.groupBox3.Controls.Add(this.label8); - this.groupBox3.Controls.Add(this.cbEntityTableName); this.groupBox3.Controls.Add(this.cbToupperFrstword); this.groupBox3.Controls.Add(this.button2); this.groupBox3.Controls.Add(this.txtNamaspace); @@ -258,9 +260,33 @@ this.groupBox3.TabStop = false; this.groupBox3.Text = "参数设置"; // + // txt_wjj + // + this.txt_wjj.Location = new System.Drawing.Point(285, 32); + this.txt_wjj.Name = "txt_wjj"; + this.txt_wjj.Size = new System.Drawing.Size(120, 21); + this.txt_wjj.TabIndex = 15; + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(338, 29); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(0, 12); + this.label9.TabIndex = 17; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(210, 35); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(71, 12); + this.label10.TabIndex = 16; + this.label10.Text = "子文件夹名:"; + // // txtTableStar // - this.txtTableStar.Location = new System.Drawing.Point(111, 64); //去除表头 列数据库表Com_aa 填写Com_ 生成的文件将是aa + this.txtTableStar.Location = new System.Drawing.Point(111, 64); this.txtTableStar.Name = "txtTableStar"; this.txtTableStar.Size = new System.Drawing.Size(170, 21); this.txtTableStar.TabIndex = 12; @@ -278,22 +304,10 @@ this.label8.AutoSize = true; this.label8.Location = new System.Drawing.Point(6, 67); this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(83, 12); + this.label8.Size = new System.Drawing.Size(95, 12); this.label8.TabIndex = 13; this.label8.Text = "去掉表名中字符:"; // - // cbEntityTableName - // - this.cbEntityTableName.AutoSize = true; - this.cbEntityTableName.Checked = true; - this.cbEntityTableName.CheckState = System.Windows.Forms.CheckState.Checked; - this.cbEntityTableName.Location = new System.Drawing.Point(389, 67); - this.cbEntityTableName.Name = "cbEntityTableName"; - this.cbEntityTableName.Size = new System.Drawing.Size(174, 16); - this.cbEntityTableName.TabIndex = 11; - this.cbEntityTableName.Text = "生成v1.10.3及以上版本实体"; - this.cbEntityTableName.UseVisualStyleBackColor = true; - // // cbToupperFrstword // this.cbToupperFrstword.AutoSize = true; @@ -381,29 +395,24 @@ this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); // - // txt_wjj + // tplComboBox // - this.txt_wjj.Location = new System.Drawing.Point(285, 32); - this.txt_wjj.Name = "txt_wjj"; - this.txt_wjj.Size = new System.Drawing.Size(120, 21); - this.txt_wjj.TabIndex = 15; + this.tplComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.tplComboBox.FormattingEnabled = true; + this.tplComboBox.Location = new System.Drawing.Point(354, 66); + this.tplComboBox.Name = "tplComboBox"; + this.tplComboBox.Size = new System.Drawing.Size(209, 20); + this.tplComboBox.TabIndex = 19; + this.tplComboBox.SelectedIndexChanged += new System.EventHandler(this.tplComboBox_SelectedIndexChanged); // - // label9 + // label11 // - this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(338, 29); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(0, 12); - this.label9.TabIndex = 17; - // - // label10 - // - this.label10.AutoSize = true; - this.label10.Location = new System.Drawing.Point(210, 35); - this.label10.Name = "label10"; - this.label10.Size = new System.Drawing.Size(71, 12); - this.label10.TabIndex = 16; - this.label10.Text = "子文件夹名:"; + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(307, 69); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(41, 12); + this.label11.TabIndex = 18; + this.label11.Text = "模板:"; // // BatchForm // @@ -466,12 +475,13 @@ private System.Windows.Forms.Panel panelbtns; private System.Windows.Forms.CheckBox chbView; private System.Windows.Forms.CheckBox cbToupperFrstword; - private System.Windows.Forms.CheckBox cbEntityTableName; private System.Windows.Forms.TextBox txtTableStar; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label8; private System.Windows.Forms.TextBox txt_wjj; private System.Windows.Forms.Label label9; private System.Windows.Forms.Label label10; + private System.Windows.Forms.ComboBox tplComboBox; + private System.Windows.Forms.Label label11; } } \ No newline at end of file diff --git a/Forms/BatchForm.cs b/Forms/BatchForm.cs index 9592f1e0046ff995998c3abe0d942f0e4b89a5f9..8f713f82d80c04b07445091ed5d672f853dedfbf 100644 --- a/Forms/BatchForm.cs +++ b/Forms/BatchForm.cs @@ -7,6 +7,7 @@ using System.Text; using System.Windows.Forms; using System.IO; using Dos.DbObjects; +using Dos.Common; namespace Dos.Tools { @@ -15,8 +16,29 @@ namespace Dos.Tools public BatchForm() { InitializeComponent(); + #region 加载模板 + var tpls = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template")).GetFiles("*.tpl", SearchOption.AllDirectories); + foreach (var fileInfo in tpls) + { + if (fileInfo.Name.Contains("实体类_最新")) + { + tplComboBox.Items.Insert(0, fileInfo.Name); + continue; + } + tplComboBox.Items.Add(fileInfo.Name); + } + tplComboBox.SelectedIndex = 0; + var tpl = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template", tplComboBox.SelectedText); + if (File.Exists(tpl)) + { + TplContent = FileHelper.Read(tpl); + } + #endregion } - + /// + /// 模板选择变化时存储模板的内容 + /// + private string TplContent { get; set; } private string databaseName; public string DatabaseName @@ -241,7 +263,14 @@ namespace Dos.Tools backgroundWorker1.RunWorkerAsync(); } - + private void tplComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + var tpl = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template", tplComboBox.SelectedItem.ToString()); + if (File.Exists(tpl)) + { + TplContent = FileHelper.Read(tpl); + } + } /// /// 开始 @@ -252,7 +281,7 @@ namespace Dos.Tools { EntityBuilder builder; - + foreach (string o in lbright.Items) { var ro = !string.IsNullOrWhiteSpace(txtTableStar.Text.Trim()) @@ -266,8 +295,7 @@ namespace Dos.Tools Utils.GetColumnInfos(dbObject.GetColumnInfoList(DatabaseName, o)), tableview[o], cbToupperFrstword.Checked, - ConnectionModel.DbType, - cbEntityTableName.Checked); + ConnectionModel.DbType); var path = txtPath.Text + "\\" + txt_wjj.Text.Trim(); //修改后效果:自动生成路劲文件夹 by kelyljk 2016-2-2 if (!Directory.Exists(path)) @@ -279,7 +307,7 @@ namespace Dos.Tools false, Encoding.UTF8)) { - sw.Write(builder.Builder()); + sw.Write(builder.Builder(TplContent)); sw.Close(); } @@ -403,5 +431,7 @@ namespace Dos.Tools } } + + } } diff --git a/Forms/ContentForm.Designer.cs b/Forms/ContentForm.Designer.cs index 2dff4981b67fa5de05afdef51b454410ed4123f2..f78936559ed7adb740c5ab978a9b78ce8e58e41e 100644 --- a/Forms/ContentForm.Designer.cs +++ b/Forms/ContentForm.Designer.cs @@ -38,7 +38,6 @@ this.groupBox1 = new System.Windows.Forms.GroupBox(); this.tplComboBox = new System.Windows.Forms.ComboBox(); this.label4 = new System.Windows.Forms.Label(); - this.cbEntityTableName = new System.Windows.Forms.CheckBox(); this.button1 = new System.Windows.Forms.Button(); this.cbToupperFrstword = new System.Windows.Forms.CheckBox(); this.btnRemovePrimarykey = new System.Windows.Forms.Button(); @@ -121,7 +120,6 @@ // this.groupBox1.Controls.Add(this.tplComboBox); this.groupBox1.Controls.Add(this.label4); - this.groupBox1.Controls.Add(this.cbEntityTableName); this.groupBox1.Controls.Add(this.button1); this.groupBox1.Controls.Add(this.cbToupperFrstword); this.groupBox1.Controls.Add(this.btnRemovePrimarykey); @@ -159,19 +157,6 @@ this.label4.TabIndex = 8; this.label4.Text = "模板:"; // - // cbEntityTableName - // - this.cbEntityTableName.AutoSize = true; - this.cbEntityTableName.Checked = true; - this.cbEntityTableName.CheckState = System.Windows.Forms.CheckState.Checked; - this.cbEntityTableName.Location = new System.Drawing.Point(684, 11); - this.cbEntityTableName.Name = "cbEntityTableName"; - this.cbEntityTableName.Size = new System.Drawing.Size(174, 16); - this.cbEntityTableName.TabIndex = 7; - this.cbEntityTableName.Text = "生成v1.10.3及以上版本实体"; - this.cbEntityTableName.UseVisualStyleBackColor = true; - this.cbEntityTableName.Visible = false; - // // button1 // this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); @@ -353,7 +338,6 @@ private System.Windows.Forms.SaveFileDialog saveEntity; private System.Windows.Forms.ImageList imageList1; private System.Windows.Forms.CheckBox cbToupperFrstword; - private System.Windows.Forms.CheckBox cbEntityTableName; private System.Windows.Forms.RichTextBox tplContent; private System.Windows.Forms.Label label4; private System.Windows.Forms.ComboBox tplComboBox; diff --git a/Forms/ContentForm.cs b/Forms/ContentForm.cs index d3b0a4b7ac3e8b97b2018a8a756627c6a408885c..c1204bc0ebe79674b34a3c5016d5ad978d425d84 100644 --- a/Forms/ContentForm.cs +++ b/Forms/ContentForm.cs @@ -215,7 +215,7 @@ namespace Dos.Tools } } - EntityBuilder builder = new EntityBuilder(TableName, txtnamespace.Text, txtClassName.Text, columns, IsView, cbToupperFrstword.Checked, ConnectionModel.DbType, cbEntityTableName.Checked); + EntityBuilder builder = new EntityBuilder(TableName, txtnamespace.Text, txtClassName.Text, columns, IsView, cbToupperFrstword.Checked, ConnectionModel.DbType); txtContent.Text = builder.Builder(tplContent.Text); diff --git a/Forms/ContentForm.resx b/Forms/ContentForm.resx index be36419e532ca1047abb135a7b71ae01566544d8..21abe7e46d42fe4588b903c63df2b9ee9ac583ff 100644 --- a/Forms/ContentForm.resx +++ b/Forms/ContentForm.resx @@ -128,7 +128,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABY - CQAAAk1TRnQBSQFMAgEBAgEAAWQBAAFkAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + CQAAAk1TRnQBSQFMAgEBAgEAAWwBAAFsAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git "a/bin/Debug/Template/\345\256\236\344\275\223\347\261\273_\346\234\200\346\226\260_2016-07-06-WCF\347\224\250.tpl" "b/bin/Debug/Template/\345\256\236\344\275\223\347\261\273_\346\234\200\346\226\260_2016-07-06-WCF\347\224\250.tpl" new file mode 100644 index 0000000000000000000000000000000000000000..aa26b4b7858c236578c7ecf1f730f7319e1c9d5c --- /dev/null +++ "b/bin/Debug/Template/\345\256\236\344\275\223\347\261\273_\346\234\200\346\226\260_2016-07-06-WCF\347\224\250.tpl" @@ -0,0 +1,117 @@ +using System; +using System.Runtime.Serialization; +using Dos.ORM; + +namespace @Model.NameSpace +{ + /// + /// 实体类@(Model.ClassName)。(属性说明自动提取数据库字段的描述信息) + /// + [Table("@Model.TableName")] + [Serializable] + [DataContract] + public partial class @Model.ClassName : Entity + { + #region Model +@foreach(var item in Model.Columns) +{ + @:private @item.TypeName _@item.ColumnName; +} + +@foreach(var item in Model.Columns) +{ + @:/// + @:/// @(item.DeText) + @:/// + @:[Field("@item.ColumnNameRealName")] + @:[DataMember] + @:public @item.TypeName @item.ColumnName + @:{ + @:get{ return _@item.ColumnName; } + @:set + @:{ + @:this.OnPropertyValueChange("@item.ColumnName"); + @:this._@item.ColumnName = value; + @:} + @:} +} + #endregion + + #region Method + /// + /// 获取实体中的主键列 + /// + public override Field[] GetPrimaryKeyFields() + { + return new Field[] { +@foreach(var item in Model.PrimaryKeyColumns) +{ + @:_.@item.ColumnName, +} + }; + } +@if(Model.IdentityColumn != null) +{ + @:/// + @:/// 获取实体中的标识列 + @:/// + @:public override Field GetIdentityField() + @:{ + @:return _.@Model.IdentityColumn.ColumnName; + @:} +} + /// + /// 获取列信息 + /// + public override Field[] GetFields() + { + return new Field[] { +@foreach(var item in Model.Columns) +{ + @:_.@item.ColumnName, +} + }; + } + /// + /// 获取值信息 + /// + public override object[] GetValues() + { + return new object[] { +@foreach(var item in Model.Columns) +{ + @:this._@item.ColumnName, +} + }; + } + /// + /// 是否是v1.10.5.6及以上版本实体。 + /// + /// + public override bool V1_10_5_6_Plus() + { + return true; + } + #endregion + + #region _Field + /// + /// 字段信息 + /// + public class _ + { + /// + /// * + /// + public readonly static Field All = new Field("*", "@Model.TableName"); +@foreach(var item in Model.Columns) +{ + @:/// + @:/// @item.DeText + @:/// + @:public readonly static Field @item.ColumnName = new Field("@item.ColumnNameRealName", "@Model.TableName", "@item.DeText"); +} + } + #endregion + } +} \ No newline at end of file