From cc126f4970f5469fa6f43b5405019c9221facc8b Mon Sep 17 00:00:00 2001 From: simosathan9 Date: Sat, 14 Sep 2024 13:17:59 +0300 Subject: [PATCH] New blocks and enhancenments on existing ones --- index.html | 8 +---- public/blocks/catBlock.js | 22 ++++++++++++-- public/blocks/lnBlock.js | 57 +++++++++++++++++++++++++++++------ public/blocks/mvBlock.js | 27 +++++++++-------- public/js/el.js | 45 ++++++++++++++++++++++++---- public/js/en.js | 63 +++++++++++++++++++++++++++++---------- public/main.js | 7 +---- 7 files changed, 171 insertions(+), 58 deletions(-) diff --git a/index.html b/index.html index 4b8838c..6a9db30 100644 --- a/index.html +++ b/index.html @@ -384,19 +384,13 @@ contents: [ { kind: 'block', type: 'ls' }, { kind: 'block', type: 'find' }, - { kind: 'block', type: 'cd' }, { kind: 'block', type: 'mkdir' }, { kind: 'block', type: 'gzip' }, { kind: 'block', type: 'cat' }, { kind: 'block', type: 'touch' }, - { kind: 'block', type: 'chmod' }, - { kind: 'block', type: 'chown' }, { kind: 'block', type: 'ln' }, { kind: 'block', type: 'mv' }, - { kind: 'block', type: 'cp' }, - { kind: 'block', type: 'rm' }, - { kind: 'block', type: 'tar' }, - { kind: 'block', type: 'unzip' } + { kind: 'block', type: 'rm' } ] }, { diff --git a/public/blocks/catBlock.js b/public/blocks/catBlock.js index 00a5129..5015d4b 100644 --- a/public/blocks/catBlock.js +++ b/public/blocks/catBlock.js @@ -4,11 +4,13 @@ var catBlock = { unix_description: [ { lineNumbers: '-n', - nonBlank_lineNumbers: '-b' + nonBlank_lineNumbers: '-b', + squeezeEmptyLines: '-s', + end_of_line_with_dollar: '-e' } ], message0: '%{BKY_CAT}\n', - message1: '%{BKY_CAT_LINE_NUMBERS} %1', + message1: '%{BKY_CAT_LINE_NUMBERS} %1 \n', args1: [ { type: 'field_dropdown', @@ -20,6 +22,22 @@ var catBlock = { ] } ], + message2: '%{BKY_CAT_SQUEEZE_EMPTY_LINES} \n', + args2: [ + { + type: 'field_checkbox', + name: 'squeezeEmptyLines', + checked: false + } + ], + message3: '%{BKY_CAT_END_OF_LINE_WITH_DOLLAR}', + args3: [ + { + type: 'field_checkbox', + name: 'end_of_line_with_dollar', + checked: false + } + ], style: 'File and Directory Operations', previousStatement: 'Action', nextStatement: 'Action', diff --git a/public/blocks/lnBlock.js b/public/blocks/lnBlock.js index ef30327..d36d119 100644 --- a/public/blocks/lnBlock.js +++ b/public/blocks/lnBlock.js @@ -1,30 +1,69 @@ var lnBlock = { type: 'ln', category: 'File and Directory Operations', - message0: 'ln %1 %2', + message0: '%{BKY_LN_MESSAGE}', unix_description: [ { - command: 'ln %TARGET %LINK' + command: 'ln', + symbolic: '-s', + force: '-f', + interactive: '-i', + verbose: '-v', + follow_symlink: '-L', + no_symlink_follow: '-P' } ], - args0: [ + message1: '%{BKY_LN_SYMBOLIC_LINK}', + args1: [ + { + type: 'field_checkbox', + name: 'symbolic', + checked: false // by default it's disabled + } + ], + message2: '%{BKY_LN_FORCE}', + args2: [ + { + type: 'field_checkbox', + name: 'force', + checked: false // by default it's disabled + } + ], + message3: '%{BKY_LN_INTERACTIVE}', + args3: [ + { + type: 'field_checkbox', + name: 'interactive', + checked: false // by default it's disabled + } + ], + message4: '%{BKY_LN_VERBOSE}', + args4: [ + { + type: 'field_checkbox', + name: 'verbose', + checked: false // by default it's disabled + } + ], + + message5: '%{BKY_LN_SOURCE}: %1 %{BKY_LN_TARGET}: %2', + args5: [ { type: 'field_input', - name: 'TARGET', - text: 'target' // default target + name: 'SOURCE', + text: 'source' // default source }, { type: 'field_input', - name: 'LINK', - text: 'link' // default link + name: 'TARGET', + text: 'target' // default target } ], style: 'File and Directory Operations', previousStatement: 'Action', nextStatement: 'Action', - tooltip: 'Δημιουργεί συνδέσμους (links) μεταξύ αρχείων.', + tooltip: '%{BKY_LN_TOOLTIP}', helpUrl: 'https://linux.die.net/man/1/ln' }; Blockly.defineBlocksWithJsonArray([lnBlock]); -// diff --git a/public/blocks/mvBlock.js b/public/blocks/mvBlock.js index ce6e8b6..0e2cb58 100644 --- a/public/blocks/mvBlock.js +++ b/public/blocks/mvBlock.js @@ -1,7 +1,7 @@ var mvBlock = { type: 'mv', category: 'File and Directory Operations', - message0: 'Move %1 to %2', // Correctly references %1 (SOURCE) and %2 (DEST) + message0: '%{BKY_MV_MESSAGE}', // Correctly references %1 (SOURCE) and %2 (DEST) unix_description: [ { not_prompt_confirmation: '-f', @@ -10,18 +10,6 @@ var mvBlock = { not_overwrite: '-n' } ], - args0: [ - { - type: 'field_input', - name: 'SOURCE', - text: 'source' // default source - }, - { - type: 'field_input', - name: 'DEST', - text: 'dest' // default destination - } - ], message1: '%{BKY_MV_NOT_PROMPT_CONFIRMATION}', args1: [ { @@ -54,6 +42,19 @@ var mvBlock = { checked: false } ], + message5: '%{BKY_MV_SOURCE}: %1 %{BKY_MV_DEST}: %2', + args5: [ + { + type: 'field_input', + name: 'SOURCE', + text: 'source' + }, + { + type: 'field_input', + name: 'DEST', + text: 'destination' + } + ], style: 'File and Directory Operations', previousStatement: 'Action', nextStatement: 'Action', diff --git a/public/js/el.js b/public/js/el.js index 9280a00..fa8a125 100644 --- a/public/js/el.js +++ b/public/js/el.js @@ -32,6 +32,9 @@ Blockly.Msg['BEGIN_END_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['CAT'] = 'Εμφάνιση αρχείου'; Blockly.Msg['CAT_LINE_NUMBERS'] = 'Με αριθμούς γραμμών'; Blockly.Msg['CAT_TOOLTIP'] = 'Συνένωση και εκτύπωση αρχείων'; +Blockly.Msg['CAT_SQUEEZE_EMPTY_LINES'] = 'Συμπίεση κενών γραμμών %1'; +Blockly.Msg['CAT_END_OF_LINE_WITH_DOLLAR'] = + 'Εμφάνιση μη εκτυπώσιμων χαρακτήρων \n και επισήμανση τέλους γραμμής με $ %1'; Blockly.Msg['CAT_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['CD'] = 'Αλλαγή καταλόγου σε'; Blockly.Msg['CD_TOOLTIP'] = 'Συνένωση και εκτύπωση αρχείων'; @@ -88,7 +91,7 @@ Blockly.Msg['FIND_EXECUTE_COMMAND'] = Blockly.Msg['FIND_TOOLTIP'] = 'Εύρεση αρχείων σε καταλόγους και υποκαταλόγους'; Blockly.Msg['FIND_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['GREP'] = 'Αναζήτηση σε αρχείο ή κατάλογο '; -Blockly.Msg['GREP_PATTERN_DEFINE'] = 'το μοτίβο %1'; +Blockly.Msg['GREP_PATTERN_DEFINE'] = 'Το μοτίβο %1'; Blockly.Msg['GREP_REGULAR_EXPRESSION_CHECK'] = 'Κανονική έκφραση %1'; Blockly.Msg['GREP_CASE_INSENSITIVE'] = 'Χωρίς διάκριση πεζών-κεφαλαίων %1'; Blockly.Msg['GREP_WHOLE_WORD_SEARCH'] = 'Αναζήτηση πλήρους λέξης %1'; @@ -121,11 +124,20 @@ Blockly.Msg['HEAD_TOOLTIP'] = 'Εμφάνιση του πρώτου μέρους Blockly.Msg['HEAD_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['LS_MESSAGE'] = 'Λίστα αρχείων & καταλόγων'; Blockly.Msg['LS_SHOW_DETAILS'] = 'Εμφάνιση λεπτομερειών %1'; -Blockly.Msg['LS_SUBDIRECTORIES'] = '%1 Αναζήτηση σε όλους τους υποκαταλόγους'; +Blockly.Msg['LS_SUBDIRECTORIES'] = 'Αναζήτηση σε όλους τους υποκαταλόγους %1'; Blockly.Msg['LS_HIDDEN'] = 'Εμφάνιση κρυφών αρχείων %1'; Blockly.Msg['LS_REVERSE_ORDER'] = '%1 Εμφάνιση σε αντίστροφη σειρά'; Blockly.Msg['LS_TOOLTIP'] = 'Λίστα περιεχομένων καταλόγου'; Blockly.Msg['LS_HELPURL'] = 'https://www.google.com/'; +Blockly.Msg['LN_MESSAGE'] = 'Σύνδεση αρχείων'; +Blockly.Msg['LN_SYMBOLIC_LINK'] = 'Δημιουργία συμβολικού συνδέσμου %1'; +Blockly.Msg['LN_SOURCE'] = 'Αρχείο προέλευσης'; +Blockly.Msg['LN_TARGET'] = 'Αρχείο προορισμού'; +Blockly.Msg['LN_FORCE'] = 'Αναγκαστική αντικατάσταση %1'; +Blockly.Msg['LN_INTERACTIVE'] = 'Προτροπή πριν από την αντικατάσταση %1'; +Blockly.Msg['LN_VERBOSE'] = 'Εμφάνιση των αρχείων κατά την επεξεργασία %1'; +Blockly.Msg['LN_TOOLTIP'] = + 'Δημιουργεί συνδέσμους αρχείων. Υποστηρίζει συμβολικούς συνδέσμους, αναγκαστική αντικατάσταση και λεπτομερή έξοδο.'; Blockly.Msg['MKDIR_MESSAGE'] = 'Δημιουργία καταλόγου'; Blockly.Msg['MKDIR_MULTIPLE_DIRECTORIES'] = 'Για πολλαπλούς καταλόγους χωρίστε με κενό'; @@ -135,13 +147,14 @@ Blockly.Msg['MKDIR_LIST_DIRECTORIES'] = 'Λίστα δημιουργημένων Blockly.Msg['MKDIR_WRITE_DIRECTORY'] = 'Γράψτε όνομα καταλόγου ή διαδρομή %1'; Blockly.Msg['MKDIR_TOOLTIP'] = 'Δημιουργία καταλόγου'; Blockly.Msg['MKDIR_HELPURL'] = 'https://www.google.com/'; - +Blockly.Msg['MV_MESSAGE'] = 'Μετακίνηση αρχείων'; Blockly.Msg['MV_NOT_PROMPT_CONFIRMATION'] = 'Μην ζητήσεις επιβεβαίωση %1'; Blockly.Msg['MV_PROMPT_CONFIRMATION'] = - 'Ζήτα επιβεβαίωση προτού εκτελέστεί η εντολή %1'; + 'Ζήτα επιβεβαίωση προτού εκτελεστεί η εντολή %1'; Blockly.Msg['MV_VERBOSE'] = 'Λεπτομερής αναφορά %1'; Blockly.Msg['MV_NOT_OVERWRITE'] = 'Μη αντικατάσταση αρχείου %1'; - +Blockly.Msg['MV_SOURCE'] = 'Αρχείο προέλευσης'; +Blockly.Msg['MV_DEST'] = 'Τοποθεσία προορισμού'; Blockly.Msg['RECORD_NUMBER'] = 'Τρέχων εγγραφή'; Blockly.Msg['RECORD_NUMBER_TOOLTIP'] = 'Αντιπροσωπεύει τον τρέχοντα αριθμό εγγραφής (γραμμής)'; @@ -880,7 +893,27 @@ Blockly.Msg['TOUCH_PROPOSE_OTHER_FORMAT'] = 'ή'; Blockly.Msg['TOUCH_SPECIFY_TIME_FORMAT_D'] = 'με προσθήκη ημερομηνίας στη μορφή YYYY-MM-DDThh:mm:SS[.frac][Z (για UTC)] %1'; Blockly.Msg['TOUCH_TOOLTIP'] = - 'Όρισε την ώρα πρόσβασης και τροποποίησης ενός αρχείου. Αν το αρχείο δεν υπάρχει, δημιούργησε ένα κενό αρχείο.'; + 'Ορίστε την ημερομηνία και ώρα πρόσβασης και τροποποίησης ενός αρχείου. Εάν το αρχείο δεν υπάρχει, δημιουργεί ένα κενό αρχείο.' + + ' Οι χρονικές στιγμές μπορούν να δοθούν σε δύο μορφές. Η πρώτη είναι η μορφή [[CC]YY]MMDDhhmm[.SS], όπου:' + + '\n- CC: Τα δύο πρώτα ψηφία του αιώνα (προαιρετικό)' + + '\n- YY: Τα δύο τελευταία ψηφία του έτους (προαιρετικό)' + + '\n- MM: Ο αριθμός του μήνα (01-12)' + + '\n- DD: Η ημέρα του μήνα (01-31)' + + '\n- hh: Η ώρα (00-23)' + + '\n- mm: Τα λεπτά (00-59)' + + '\n- SS: Τα δευτερόλεπτα (00-59, προαιρετικό)' + + '\nΠαράδειγμα: Για 12 Ιανουαρίου 2024, ώρα 14:30 και 45 δευτερόλεπτα, η μορφή θα είναι: 20240112143045.' + + '\nΕναλλακτικά, μπορείτε να χρησιμοποιήσετε τη μορφή ISO 8601: YYYY-MM-DDThh:mm:SS[.frac][Z (για UTC)], όπου:' + + '\n- YYYY: Το έτος (π.χ., 2024)' + + '\n- MM: Ο αριθμός του μήνα (01-12)' + + '\n- DD: Η ημέρα του μήνα (01-31)' + + '\n- T: Ο διαχωριστής μεταξύ ημερομηνίας και ώρας' + + '\n- hh: Η ώρα (00-23)' + + '\n- mm: Τα λεπτά (00-59)' + + '\n- SS: Τα δευτερόλεπτα (00-59, προαιρετικό)' + + '\n- .frac: Δεκαδικά για τα δευτερόλεπτα (προαιρετικό)' + + '\n- Z: Αντιπροσωπεύει το συντονισμένο παγκόσμιο χρόνο (UTC, προαιρετικό).' + + '\nΠαράδειγμα: Για 12 Ιανουαρίου 2024, ώρα 14:30 UTC, η μορφή θα είναι: 2024-01-12T14:30:00Z.'; Blockly.Msg['TOUCH_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['UNIQ'] = 'Αφαίρεση διπλότυπων γραμμών στο αρχείο\n'; diff --git a/public/js/en.js b/public/js/en.js index 7c227df..084f00d 100644 --- a/public/js/en.js +++ b/public/js/en.js @@ -31,6 +31,9 @@ Blockly.Msg['BEGIN_END_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['CAT'] = 'Show file'; Blockly.Msg['CAT_LINE_NUMBERS'] = 'With line numbers'; Blockly.Msg['CAT_TOOLTIP'] = 'Concatenate and print files'; +Blockly.Msg['CAT_SQUEEZE_EMPTY_LINES'] = 'Squeeze empty lines %1'; +Blockly.Msg['CAT_END_OF_LINE_WITH_DOLLAR'] = + 'Display non-printing characters \n and display a dollar sign at the end of each line %1'; Blockly.Msg['CAT_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['CD'] = 'Change directory to'; Blockly.Msg['CD_TOOLTIP'] = 'Concatenate and print files'; @@ -86,22 +89,22 @@ Blockly.Msg['FIND_EXECUTE_COMMAND'] = Blockly.Msg['FIND_TOOLTIP'] = 'Find files in directories and subdirectories'; Blockly.Msg['FIND_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['GREP'] = 'Search in file or directory '; -Blockly.Msg['GREP_PATTERN_DEFINE'] = 'the pattern %1'; -Blockly.Msg['GREP_REGULAR_EXPRESSION_CHECK'] = 'regular expression %1'; -Blockly.Msg['GREP_CASE_INSENSITIVE'] = 'case insensitive %1'; -Blockly.Msg['GREP_WHOLE_WORD_SEARCH'] = 'whole word search %1'; -Blockly.Msg['GREP_COUNT_MATCHES'] = 'count the matches %1'; -Blockly.Msg['GREP_PATTERN_NEGATION'] = "show lines that don't match pattern %1"; -Blockly.Msg['GREP_RECURSIVE_SEARCH'] = 'search recursively %1'; -Blockly.Msg['GREP_DISPLAY_LINE_NUMBERS'] = 'show line numbers %1'; -Blockly.Msg['GREP_STOP_AFTER_NUM_MATCHES'] = 'stop after %1 matches'; +Blockly.Msg['GREP_PATTERN_DEFINE'] = 'The pattern %1'; +Blockly.Msg['GREP_REGULAR_EXPRESSION_CHECK'] = 'Regular expression %1'; +Blockly.Msg['GREP_CASE_INSENSITIVE'] = 'Case insensitive %1'; +Blockly.Msg['GREP_WHOLE_WORD_SEARCH'] = 'Whole word search %1'; +Blockly.Msg['GREP_COUNT_MATCHES'] = 'Count the matches %1'; +Blockly.Msg['GREP_PATTERN_NEGATION'] = "Show lines that don't match pattern %1"; +Blockly.Msg['GREP_RECURSIVE_SEARCH'] = 'Search recursively %1'; +Blockly.Msg['GREP_DISPLAY_LINE_NUMBERS'] = 'Show line numbers %1'; +Blockly.Msg['GREP_STOP_AFTER_NUM_MATCHES'] = 'Stop after %1 matches'; Blockly.Msg['GREP_MULTIPLE_PATTERN_SEARCH'] = 'Search with multiple patterns %1'; Blockly.Msg['GREP_SHOW_FILENAME'] = 'Show filename %1'; Blockly.Msg['GREP_PRINT_CONTEXT_BEFORE_MATCH'] = - 'Print %1 lines of context before match %2'; + 'Output %1 lines of context before match %2'; Blockly.Msg['GREP_PRINT_CONTEXT_AFTER_MATCH'] = - 'Print %1 lines of context after match %2'; + 'Output %1 lines of context after match %2'; Blockly.Msg['GREP_TOOLTIP'] = 'search in a file with a pattern'; Blockly.Msg['GREP_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['GZIP_FILE'] = '%1 file'; @@ -118,11 +121,20 @@ Blockly.Msg['HEAD_TOOLTIP'] = 'Output the first part of files'; Blockly.Msg['HEAD_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['LS_MESSAGE'] = 'List files & directories'; Blockly.Msg['LS_SHOW_DETAILS'] = 'Show details %1'; -Blockly.Msg['LS_SUBDIRECTORIES'] = '%1 Search in all subdirectories'; +Blockly.Msg['LS_SUBDIRECTORIES'] = 'Search in all subdirectories %1'; Blockly.Msg['LS_HIDDEN'] = 'Show hidden files %1'; Blockly.Msg['LS_REVERSE_ORDER'] = '%1 Show in reverse order'; Blockly.Msg['LS_TOOLTIP'] = 'List directory contents'; Blockly.Msg['LS_HELPURL'] = 'https://www.google.com/'; +Blockly.Msg['LN_MESSAGE'] = 'Link files'; +Blockly.Msg['LN_SYMBOLIC_LINK'] = 'Create symbolic link %1'; +Blockly.Msg['LN_FORCE'] = 'Force overwrite %1'; +Blockly.Msg['LN_INTERACTIVE'] = 'Prompt before overwrite %1'; +Blockly.Msg['LN_VERBOSE'] = 'Show files as they are processed %1'; +Blockly.Msg['LN_SOURCE'] = 'Source'; +Blockly.Msg['LN_TARGET'] = 'Target'; +Blockly.Msg['LN_TOOLTIP'] = + 'Creates file links. Supports symbolic links, force overwrite, and verbose output.'; Blockly.Msg['MKDIR_MESSAGE'] = 'Create directory'; Blockly.Msg['MKDIR_MULTIPLE_DIRECTORIES'] = 'For multiple directories separate with space'; @@ -132,12 +144,13 @@ Blockly.Msg['MKDIR_LIST_DIRECTORIES'] = 'List directories created %1'; Blockly.Msg['MKDIR_WRITE_DIRECTORY'] = 'Write directory or path %1'; Blockly.Msg['MKDIR_TOOLTIP'] = 'Create directory'; Blockly.Msg['MKDIR_HELPURL'] = 'https://www.google.com/'; - +Blockly.Msg['MV_MESSAGE'] = 'Move files'; Blockly.Msg['MV_NOT_PROMPT_CONFIRMATION'] = 'Do not prompt for confirmation %1'; Blockly.Msg['MV_PROMPT_CONFIRMATION'] = 'Prompt for confirmation %1'; Blockly.Msg['MV_VERBOSE'] = 'Verbose mode %1'; Blockly.Msg['MV_NOT_OVERWRITE'] = 'Do not overwrite %1'; - +Blockly.Msg['MV_SOURCE'] = 'Source'; +Blockly.Msg['MV_DEST'] = 'Destination'; Blockly.Msg['RECORD_NUMBER'] = 'Current record'; Blockly.Msg['RECORD_NUMBER_TOOLTIP'] = 'Represents the current record or (line) number'; @@ -851,7 +864,27 @@ Blockly.Msg['TOUCH_PROPOSE_OTHER_FORMAT'] = 'or'; Blockly.Msg['TOUCH_SPECIFY_TIME_FORMAT_D'] = 'with date in YYYY-MM-DDThh:mm:SS[.frac][Z (UTC)] %1'; Blockly.Msg['TOUCH_TOOLTIP'] = - 'Set the modification and access times of files. If any file does not exist, it is created with default permissions. '; + 'Set the access and modification time of a file. If the file does not exist, it creates an empty file.' + + ' Time stamps can be given in two formats. The first format is [[CC]YY]MMDDhhmm[.SS], where:' + + '\n- CC: The first two digits of the century (optional)' + + '\n- YY: The last two digits of the year (optional)' + + '\n- MM: The month number (01-12)' + + '\n- DD: The day of the month (01-31)' + + '\n- hh: The hour (00-23)' + + '\n- mm: The minutes (00-59)' + + '\n- SS: The seconds (00-59, optional)' + + '\nExample: For January 12, 2024, at 14:30 and 45 seconds, the format would be: 20240112143045.' + + '\nAlternatively, you can use the ISO 8601 format: YYYY-MM-DDThh:mm:SS[.frac][Z (for UTC)], where:' + + '\n- YYYY: The year (e.g., 2024)' + + '\n- MM: The month number (01-12)' + + '\n- DD: The day of the month (01-31)' + + '\n- T: The separator between date and time' + + '\n- hh: The hour (00-23)' + + '\n- mm: The minutes (00-59)' + + '\n- SS: The seconds (00-59, optional)' + + '\n- .frac: Fractional seconds (optional)' + + '\n- Z: Represents Coordinated Universal Time (UTC, optional).' + + '\nExample: For January 12, 2024, at 14:30 UTC, the format would be: 2024-01-12T14:30:00Z.'; Blockly.Msg['TOUCH_HELPURL'] = 'https://www.google.com/'; Blockly.Msg['UNIQ'] = 'Remove duplicate lines in file\n'; diff --git a/public/main.js b/public/main.js index ced23f7..90f226a 100644 --- a/public/main.js +++ b/public/main.js @@ -1649,12 +1649,7 @@ Blockly.Extensions.register('validate_touch_time_d', function () { // Define regex patterns to match different valid formats var patterns = [ /^$/, // Empty string pattern - /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])([T\s])(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z)?$/, // YYYY-MM-DDThh:mm:SS[.frac][tz] or YYYY-MM-DD hh:mm:SS[.frac][tz] - /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])([T\s])(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/, // YYYY-MM-DDThh:mm:SS or YYYY-MM-DD hh:mm:SS - /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])([T\s])(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])$/, // YYYY-MM-DDThh:mm or YYYY-MM-DD hh:mm - /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/, // YYYY-MM-DD - /^(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])([T\s])(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])$/, // MM-DDThh:mm or MM-DD hh:mm - /^(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])([T\s])(0[0-9]|1[0-9]|2[0-3])$/ // MM-DDThh or MM-DD hh + /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])([T\s])(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z)?$/ // YYYY-MM-DDThh:mm:SS[.frac][tz] or YYYY-MM-DD hh:mm:SS[.frac][tz] ]; // Check if input matches one of the valid patterns