示例#1
0
        public string Apply(string parameters, StaccatoParserContext context)
        {
            StringBuilder buddy = new StringBuilder();

            foreach (string noteString in parameters.Split(' '))
            {
                try
                {
                    Note note = NoteProviderFactory.GetNoteProvider().CreateNote(noteString);
                    int  n    = (int)(note.Duration / ThirtySecondDuration);
                    for (int i = 0; i < n / 2; i++)
                    {
                        buddy.Append(Note.GetToneString(note.Value));
                        buddy.Append("t ");
                        // This function could really be more intelligent. For example,
                        // in the following line, the value of the trill note should actually
                        // be consistent with the scale that is being used, and the note that
                        // is being played. In a C-Major scale with an E note, F would be the
                        // trill note, and that is only +1 from E. Also, the trill could become
                        // increasingly quick.
                        buddy.Append(Note.GetToneString((note.Value + 2)));
                        buddy.Append("t ");
                    }
                }
                catch (Exception)
                {
                    // Nothing to do
                }
            }
            return(buddy.ToString().Trim());
        }
示例#2
0
        public string Preprocess(string musicString, StaccatoParserContext context)
        {
            var sb      = new StringBuilder();
            int posPrev = 0;

            foreach (Match match in functionPattern.Matches(musicString))
            {
                string functionName = null;
                string parameters   = null;

                foreach (Match nameMatch in namePattern.Matches(match.Groups[0].ToString()))
                {
                    functionName = nameMatch.Groups[0].ToString().Substring(1, nameMatch.Groups[0].Length - 2);
                }

                var function = FunctionManager.Instance.GetPreprocessorFunction(functionName);
                if (function == null)
                {
                    return(musicString);
                }
                foreach (Match paramMatch in paramPattern.Matches(match.Groups[0].ToString()))
                {
                    parameters = paramMatch.Groups[0].ToString().Substring(1, paramMatch.Groups[0].Length - 2);
                }
                sb.Append(musicString.Substring(posPrev, match.Index - posPrev));
                sb.Append(function.Apply(parameters, context));
                posPrev = match.Index + match.Length;
            }
            sb.Append(musicString.Substring(posPrev, musicString.Length - posPrev));
            return(sb.ToString());
        }
示例#3
0
        public void Apply(string parameters, StaccatoParserContext context)
        {
            var splittedParams = parameters.Split(',');

            if (splittedParams.Length == 2)
            {
                int    controllerNumber = 0;
                string controllerId     = splittedParams[0].Trim();
                if (Regex.IsMatch(controllerId, @"\d+"))
                {
                    controllerNumber = int.Parse(controllerId);
                }
                else
                {
                    if (controllerId[0] == '[')
                    {
                        controllerId = controllerId.Substring(1, controllerId.Length - 2);
                    }
                    controllerNumber = (int)context.Dictionary[controllerId];
                }
                if (controllerNumber > sbyte.MaxValue)
                {
                    context.Parser.OnControllerEventParsed(MidiTools.GetLSB(controllerNumber),
                                                           MidiTools.GetLSB(int.Parse(splittedParams[1].Trim())));
                    context.Parser.OnControllerEventParsed(MidiTools.GetMSB(controllerNumber),
                                                           MidiTools.GetMSB(int.Parse(splittedParams[1].Trim())));
                }
                else
                {
                    context.Parser.OnControllerEventParsed(controllerNumber,
                                                           int.Parse(splittedParams[1].Trim()));
                }
            }
        }
示例#4
0
        public int Parse(string music, StaccatoParserContext context)
        {
            if (!Matches(music))
            {
                return(0);
            }

            int posNextSpace = music.FindNextOrEnd(' ');

            music = music.Substring(1, posNextSpace - 1); // Remove the initial character
            var quarks       = music.Split(QuarkSeparator);
            var ivlSubparser = new IVLSubparser();

            foreach (string quark in quarks)
            {
                if (ivlSubparser.Matches(quark))
                {
                    ivlSubparser.Parse(quark, context);
                }
                else if (NoteSubparser.NoteSubparser.Instance.Matches(quark))
                {
                    NoteSubparser.NoteSubparser.Instance.Parse(quark, context);
                }
            }

            return(posNextSpace + 1);
        }
示例#5
0
        public string Preprocess(string s, StaccatoParserContext context)
        {
            StringBuilder sb  = new StringBuilder();
            int           pos = 0;

            while (pos < s.Length)
            {
                int keepSpacesUntil = s.FindNextOrEnd('(', pos);
                int endParen        = s.FindNextOrEnd(')', keepSpacesUntil);
                sb.Append(s.Substring(pos, keepSpacesUntil - pos));
                for (int i = keepSpacesUntil; i < endParen; i++)
                {
                    if (s[i] == ' ')
                    {
                        sb.Append('_');
                    }
                    else
                    {
                        sb.Append(s[i]);
                    }
                }
                pos = endParen;
            }
            return(sb.ToString());
        }
示例#6
0
        public Chord CreateChord(StaccatoParserContext parserContext)
        {
            if (NoteValueAsString != null)
            {
                NoteNumber = (int)parserContext.Dictionary[NoteValueAsString];
            }
            if (DurationValueAsString != null)
            {
                DecimalDuration = (double)parserContext.Dictionary[DurationValueAsString];
            }
            Note rootNote = CreateNote(parserContext);

            if (IsChord)
            {
                Chord chord = new Chord(rootNote, Intervals);
                if (InversionBassNote != null)
                {
                    chord.SetBassNote(InversionBassNote);
                }
                else if (InversionCount > 0)
                {
                    chord.Inversion = InversionCount;
                }
                return(chord);
            }
            return(null);
        }
示例#7
0
 public int Parse(string music, StaccatoParserContext context)
 {
     if (MatchesKeySignature(music))
     {
         int posNextSpace = music.FindNextOrEnd(' ');
         Key key          = CreateKey(music.Substring(KeySignatureString.Length, posNextSpace - KeySignatureString.Length));
         context.Key = key;
         context.Parser.OnKeySignatureParsed(key.Root.PositionInOctave, (int)key.Scale.Type);
         return(posNextSpace + 1);
     }
     if (MatchesTimeSignature(music))
     {
         int    posNextSpace = music.FindNextOrEnd(' ');
         string timeString   = music.Substring(TimeSignatureString.Length,
                                               posNextSpace - TimeSignatureString.Length);
         int posOfSlash = timeString.IndexOf(SeparatorString, StringComparison.Ordinal);
         if (posOfSlash == -1)
         {
             throw new ParserException(StaccatoMessages.NoTimeSignatureSeparator + timeString);
         }
         int numerator     = int.Parse(timeString.Substring(0, posOfSlash));
         int denominator   = int.Parse(timeString.Substring(posOfSlash + 1, timeString.Length - posOfSlash - 1));
         var timeSignature = new TimeSignature(numerator, denominator);
         context.TimeSignature = timeSignature;
         context.Parser.OnTimeSignatureParsed(numerator, denominator);
         return(posNextSpace + 1);
     }
     return(0);
 }
示例#8
0
        public int Parse(string music, StaccatoParserContext context)
        {
            if (!Matches(music))
            {
                return(0);
            }
            int posNextSpace = music.FindNextOrEnd(' ');
            int tempo        = -1;

            if (posNextSpace > 1)
            {
                string tempoId = music.Substring(1, posNextSpace - 1);
                if (Regex.IsMatch(tempoId, @"\d+"))
                {
                    tempo = int.Parse(tempoId);
                }
                else
                {
                    if (tempoId[0] == '[')
                    {
                        tempoId = tempoId.Substring(1, tempoId.Length - 2);
                    }
                    tempo = (int)context.Dictionary[tempoId];
                }
            }
            context.Parser.OnTempoChanged(tempo);
            return(posNextSpace + 1);
        }
 public int Parse(string music, StaccatoParserContext context)
 {
     if (music[0] == LyricChar || music[0] == MarkerChar)
     {
         string lyricOrMarker = null;
         int    posNext       = 0;
         if (music[1] == '(')
         {
             posNext = music.FindNextOrEnd(')');
         }
         else
         {
             posNext = music.FindNextOrEnd(' ');
         }
         int startPos = music[1] == '(' ? 2 : 1;
         lyricOrMarker = music.Substring(startPos, posNext - startPos);
         lyricOrMarker = ParenSpacesPreprocessor.Unprocess(lyricOrMarker);
         if (music[0] == LyricChar)
         {
             context.Parser.OnLyricParsed(lyricOrMarker);
         }
         else
         {
             context.Parser.OnTrackBeatTimeBookmarked(lyricOrMarker);
             context.Parser.OnMarkerParsed(lyricOrMarker);
         }
         return(Math.Max(1, Math.Min(posNext + 1, music.Length)));
     }
     return(0);
 }
示例#10
0
        public string Preprocess(string s, StaccatoParserContext context)
        {
            string iteratingString = s;

            for (int i = 0; i < Iterations; i++)
            {
                StringBuilder sb      = new StringBuilder();
                int           posPrev = 0;
                foreach (Match match in GetReplacementRegex().Matches(iteratingString))
                {
                    string foundKey = RequiresAngleBrackets
                        ? match.Groups[0].Value.Substring(1, match.Groups[0].Length - 2)
                        : match.Groups[0].Value;
                    sb.Append(iteratingString.Substring(posPrev, match.Index - posPrev));
                    string lookupKey = IsCaseSensitive ? foundKey : foundKey.ToUpper();
                    string replacementValue;
                    if (ReplacementMap.TryGetValue(lookupKey, out replacementValue) && replacementValue != null)
                    {
                        sb.Append(ReplacementMap[lookupKey]);
                    }
                    else
                    {
                        sb.Append(foundKey); // If the key doesn't have a value, just put the key back - it might be intended for another parser or purpose
                    }
                    posPrev = match.Index + match.Length;
                }
                sb.Append(iteratingString.Substring(posPrev, iteratingString.Length - posPrev));
                iteratingString = sb.ToString();
            }
            return(iteratingString);
        }
示例#11
0
        private int ParseDuration(string s, int index, NoteContext noteContext, StaccatoParserContext parserContext)
        {
            if (index < s.Length)
            {
                switch (s[index])
                {
                case '/': index = ParseNumericDuration(s, index, noteContext); break;

                case 'W':
                case 'H':
                case 'Q':
                case 'I':
                case 'S':
                case 'T':
                case 'X':
                case 'O':
                case '-': index = ParseLetterDuration(s, index, noteContext, parserContext); break;

                default:
                    noteContext.DecimalDuration         = DefaultNoteSettings.DefaultDuration;
                    noteContext.IsDurationExplicitlySet = false;
                    break;     // Could get here if the next character is a velocity char ("a" or "d")
                }
                index = ParseTuplet(s, index, noteContext);
            }
            else
            {
                noteContext.DecimalDuration         = DefaultNoteSettings.DefaultDuration;
                noteContext.IsDurationExplicitlySet = false;
            }
            return(index);
        }
示例#12
0
        public Note CreateNote(string noteString)
        {
            StaccatoParserContext parserContext = new StaccatoParserContext(new StaccatoParser());
            NoteContext           noteContext   = new NoteContext();

            ParseNoteElement(noteString, 0, noteContext, parserContext);
            return(noteContext.CreateNote(parserContext));
        }
示例#13
0
        public double GetDurationForString(string s)
        {
            NoteContext           noteContext   = new NoteContext();
            StaccatoParserContext parserContext = new StaccatoParserContext(new StaccatoParser());

            ParseDuration(s, 0, noteContext, parserContext);
            return(noteContext.DecimalDuration);
        }
        public void Apply(string parameters, StaccatoParserContext context)
        {
            var splittedParams = parameters.Split(',');

            if (splittedParams.Length == 1)
            {
                context.Parser.OnChannelPressureParsed(int.Parse(splittedParams[0].Trim()));
            }
        }
示例#15
0
        public void Apply(string parameters, StaccatoParserContext context)
        {
            var splittedParams = parameters.Split(',');
            var bytes          = new byte[splittedParams.Length];

            for (int i = 0; i < splittedParams.Length; i++)
            {
                bytes[i] = byte.Parse(splittedParams[i].Trim());
            }
            context.Parser.OnSystemExclusiveParsed(bytes);
        }
示例#16
0
文件: Atom.cs 项目: kurena-777/NFugue
        public Atom(string voice, string layer, string instrument, Note note)
        {
            var context = new StaccatoParserContext(null);

            IVLSubparser.PopulateContext(context);
            var subparser = new IVLSubparser();

            CreateAtom(subparser.GetValue(voice.ToUpper(), context),
                       subparser.GetValue(layer.ToUpper(), context),
                       (Instrument)subparser.GetValue(instrument.ToUpper(), context),
                       new Note(note));
        }
示例#17
0
        public static void PopulateContext(StaccatoParserContext context)
        {
            foreach (PercussionInstrument percussionInstrument in Enum.GetValues(typeof(PercussionInstrument))
                     .OfType <PercussionInstrument>())
            {
                context.Dictionary[percussionInstrument.GetDescription()] = (int)percussionInstrument;
            }

            foreach (string key in Chord.ChordMap.Keys)
            {
                context.Dictionary[key] = Chord.ChordMap[key];
            }
        }
示例#18
0
        public static void PopulateContext(StaccatoParserContext context)
        {
            // Voices
            context.Dictionary["PERCUSSION"] = (byte)9;

            // Instruments
            context.Dictionary.AddRange(Enum.GetValues(typeof(Instrument)).OfType <Instrument>()
                                        .ToDictionary(item => item.GetDescription().ToUpper(), item =>
            {
                var @byte = (byte)item;
                return((object)@byte);
            }));
        }
示例#19
0
        public Chord CreateChord(string chordString)
        {
            // If the user requested a chord like "C" or "Ab" without providing any additional details, assume it's MAJOR
            if (chordString.Length <= 2)
            {
                chordString = chordString + "MAJ";
            }

            StaccatoParserContext parserContext = new StaccatoParserContext(new StaccatoParser());
            NoteContext           noteContext   = new NoteContext();

            ParseNoteElement(chordString, 0, noteContext, parserContext);
            return(noteContext.CreateChord(parserContext));
        }
        public string Apply(string parameters, StaccatoParserContext context)
        {
            string[] defaultSettings = parameters.Split(',');
            foreach (string defaultSetting in defaultSettings)
            {
                string[] defaultValues = defaultSetting.Split('=');
                if (defaultValues.Length != 2)
                {
                    throw new ApplicationException("DefaultProcessor found this setting, which is not in the form KEY=VALUE: " + defaultSetting);
                }
                string key   = defaultValues[0];
                string value = defaultValues[1];

                if (key.Equals(Octave, StringComparison.OrdinalIgnoreCase))
                {
                    DefaultNoteSettings.DefaultOctave = int.Parse(value);
                }
                else if (key.Equals(BaseOctave, StringComparison.OrdinalIgnoreCase))
                {
                    DefaultNoteSettings.DefaultBassOctave = int.Parse(value);
                }
                else if (key.Equals(Duration, StringComparison.OrdinalIgnoreCase))
                {
                    double dur = 0.0d;
                    if (double.TryParse(value, out dur))
                    {
                        DefaultNoteSettings.DefaultDuration = dur;
                    }
                    else
                    {
                        throw new ApplicationException("Currently, default duration must be specified as a decimal. For example, please use 0.5 for 'h', 0.25 for 'q', and so on. You had entered: " + value);
                    }
                }
                else if (key.Equals(Attack, StringComparison.OrdinalIgnoreCase))
                {
                    DefaultNoteSettings.DefaultOnVelocity = int.Parse(value);
                }
                else if (key.Equals(Decay, StringComparison.OrdinalIgnoreCase))
                {
                    DefaultNoteSettings.DefaultOffVelocity = int.Parse(value);
                }
                else
                {
                    throw new ApplicationException("DefaultProcessor found this setting where the key is not recognized: " + defaultSetting + " (key should be one of the following: " + Octave + ", " + BaseOctave + ", " + Duration + ", " + Attack + ", or " + Decay);
                }
            }

            return("");
        }
示例#21
0
        /** Given a string like "V0" or "I[Piano]", this method will return the value of the token */
        public byte GetValue(string ivl, StaccatoParserContext context)
        {
            string instrumentId = ivl.Substring(1, ivl.Length - 1);

            if (Regex.IsMatch(instrumentId, "\\d+"))
            {
                return(byte.Parse(instrumentId));
            }

            if (instrumentId[0] == '[')
            {
                instrumentId = instrumentId.Substring(1, instrumentId.Length - 2);
            }
            return((byte)context.Dictionary[instrumentId]);
        }
示例#22
0
        public void Apply(string parameters, StaccatoParserContext context)
        {
            var splittedParams = parameters.Split(',');

            if (splittedParams.Length == 2)
            {
                context.Parser.OnPitchWheelParsed(int.Parse(splittedParams[0].Trim()),
                                                  int.Parse(splittedParams[1].Trim()));
            }
            else if (splittedParams.Length == 1)
            {
                int pitch = int.Parse(splittedParams[0]);
                context.Parser.OnPitchWheelParsed(MidiTools.GetLSB(pitch), MidiTools.GetMSB(pitch));
            }
        }
        public string Apply(string parameters, StaccatoParserContext context)
        {
            var    chord           = new Chord(parameters);
            var    notes           = chord.GetNotes();
            double duration        = chord.Root.Duration;
            double durationPerNote = duration / notes.Length;
            var    sb = new StringBuilder();

            foreach (var note in notes)
            {
                sb.Append(Note.GetToneString(note.Value));
                sb.Append("/");
                sb.Append(durationPerNote);
                sb.Append(" ");
            }
            return(sb.ToString().Trim());
        }
示例#24
0
        public string Preprocess(string s, StaccatoParserContext context)
        {
            var sb       = new StringBuilder();
            int posStart = 0;

            foreach (Match match in parenPattern.Matches(s))
            {
                // First, add the text that occurs before the parenthesis group starts. That text is
                // meant to be added to the result without any modifications.
                int    posStartOfGroup = match.Index;
                string sub             = s.Substring(posStart, posStartOfGroup - posStart);
                sb.Append(sub);
                posStart = s.FindNextOrEnd(' ', match.Index + match.Length);

                // Now, get the notes that are collected between parentheses. The "replicand" is the
                // thing that immediately follows the closing parenthesis and is the thing that should
                // be applied to each note within the parentheses.
                int    posCloseParen = s.IndexOf(')', posStartOfGroup);
                string replicand     = s.Substring(posCloseParen + 1,
                                                   s.FindNextOrEnd(new List <char> {
                    ' ', '+'
                }, posCloseParen + 1) - posCloseParen - 1);
                string parenContents = s.Substring(posStartOfGroup + 1, posCloseParen - posStartOfGroup - 1);

                // Split the items in parentheses
                int subindex = 0;
                while (subindex < parenContents.Length)
                {
                    var posSomething = parenContents.FindNextOrEnd(new List <char> {
                        ' ', '+'
                    }, subindex);
                    sb.Append(parenContents.Substring(subindex, posSomething - subindex));
                    sb.Append(replicand);
                    if (posSomething != parenContents.Length)
                    {
                        sb.Append(parenContents.Substring(posSomething, 1));
                    }
                    subindex = posSomething + 1;
                }
            }
            sb.Append(s.Substring(posStart, s.Length - posStart));
            return(sb.ToString());
        }
示例#25
0
        public int Parse(string music, StaccatoParserContext context)
        {
            if (!Matches(music))
            {
                return(0);
            }
            int posNextSpace = music.FindNextOrEnd(' ');
            int value        = -1;

            if (posNextSpace > 1)
            {
                string instrumentId = music.Substring(1, posNextSpace - 1);
                if (Regex.IsMatch(instrumentId, @"\d+"))
                {
                    value = int.Parse(instrumentId);
                }
                else
                {
                    if (instrumentId[0] == '[')
                    {
                        instrumentId = instrumentId.Substring(1, instrumentId.Length - 2);
                    }

                    value = Convert.ToInt32(context.Dictionary[instrumentId]);
                }
            }
            switch (music[0])
            {
            case InstrumentChar:
                context.Parser.OnInstrumentParsed(value);
                break;

            case LayerChar:
                context.Parser.OnLayerChanged(value);
                break;

            case VoiceChar:
                context.Parser.OnTrackChanged(value);
                break;
            }
            return(posNextSpace + 1);
        }
示例#26
0
        public int Parse(string music, StaccatoParserContext context)
        {
            if (music[0] != FunctionChar)
            {
                return(0);
            }
            int    posOpenParen  = music.FindNextOrEnd('(');
            int    posCloseParen = music.FindNextOrEnd(')', posOpenParen);
            string functionName  = music.Substring(1, posOpenParen - 1);
            string parameters    = music.Substring(posOpenParen + 1, posCloseParen - posOpenParen - 1);

            parameters = ParenSpacesPreprocessor.Unprocess(parameters);
            var function = FunctionManager.Instance.GetSubparserFunction(functionName);

            if (function != null)
            {
                context.Parser.OnFunctionParsed(functionName, parameters);
                function.Apply(parameters, context);
            }
            return(Math.Min(posCloseParen + 1, music.Length));
        }
示例#27
0
        public string Preprocess(string musicString, StaccatoParserContext context)
        {
            StringBuilder sb      = new StringBuilder();
            int           posPrev = 0;

            // Sort all of the instruction keys by length, so we'll deal with the longer ones first
            string[] sizeSortedInstructions = instructions.Keys.OrderByDescending(k => k.Length).ToArray();
            bool     matchFound             = false;

            foreach (Match match in keyPattern.Matches(musicString))
            {
                string key = match.Groups[0].Value;
                key = key.Substring(1, key.Length - 2);
                foreach (string possibleMatch in sizeSortedInstructions)
                {
                    if (!matchFound)
                    {
                        if (key.StartsWith(possibleMatch))
                        {
                            IInstruction instruction;
                            string       value = key;
                            if (instructions.TryGetValue(possibleMatch, out instruction))
                            {
                                value = instruction.OnInstructionReceived(key.Split(' '));
                            }
                            sb.Append(musicString.Substring(posPrev, match.Index - posPrev));
                            sb.Append(value);
                            posPrev    = match.Index + match.Length;
                            matchFound = true;
                        }
                    }
                }
                if (!matchFound)
                {
                    posPrev = match.Index + match.Length;
                }
            }
            sb.Append(musicString.Substring(posPrev, musicString.Length - posPrev));
            return(sb.ToString());
        }
示例#28
0
        private int ParseNoteElement(string music, int index, StaccatoParserContext parserContext)
        {
            bool repeat      = false;
            var  noteContext = new NoteContext();

            do
            {
                index = ParseNoteElement(music, index, noteContext, parserContext);
                if (noteContext.IsChord)
                {
                    var chord = noteContext.CreateChord(parserContext);
                    parserContext.Parser.OnChordParsed(chord);
                }
                else
                {
                    var note = noteContext.CreateNote(parserContext);
                    parserContext.Parser.OnNoteParsed(note);
                }
                repeat      = noteContext.IsThereAnother;
                noteContext = noteContext.CreateNextNoteContext();
            } while (repeat);
            return(index);
        }
示例#29
0
 public int Parse(string music, StaccatoParserContext context)
 {
     if (music[0] == Barline)
     {
         int  posNextSpace = music.FindNextOrEnd(' ');
         long measure      = -1;
         if (posNextSpace > 1)
         {
             string barId = music.Substring(1, posNextSpace - 1);
             if (Regex.IsMatch(barId, @"\d+"))
             {
                 measure = long.Parse(barId);
             }
             else
             {
                 measure = (long)context.Dictionary[barId];
             }
         }
         context.Parser.OnBarLineParsed(measure);
         return(Math.Max(1, posNextSpace));
     }
     return(0);
 }
示例#30
0
        public string Preprocess(string s, StaccatoParserContext context)
        {
            StringBuilder buddy = new StringBuilder();
            int           pos   = 0;

            while (pos < s.Length)
            {
                int upperUntil = s.FindNextOrEnd(SafeChars, pos);
                if ((upperUntil == 0) || (s[upperUntil - 1] == ' '))
                {
                    buddy.Append(s.Substring(pos, upperUntil - pos).ToUpper());
                    if (upperUntil < s.Length)
                    {
                        int lowerUntil = upperUntil;
                        if ((s[upperUntil + 1] == '(') || (s[upperUntil] == ':'))
                        {
                            lowerUntil = s.IndexOf(')', upperUntil + 1);
                            buddy.Append(s.Substring(upperUntil, lowerUntil - upperUntil));
                        }
                        else
                        {
                            lowerUntil = s.FindNextOrEnd(' ', upperUntil);
                            buddy.Append(s.Substring(upperUntil, lowerUntil - upperUntil));
                        }
                        upperUntil = lowerUntil;
                    }
                    pos = upperUntil;
                }
                else
                {
                    int min = Math.Min(s.Length, upperUntil + 1);
                    buddy.Append(s.Substring(pos, min - pos).ToUpper());
                    pos = min;
                }
            }
            return(buddy.ToString());
        }