this repo has no description
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: new command parser

It's not fully hooked up to the react app, and it's not quite complete
either, but it's a start.
Currently, it will parse filter implicitly, and there's also the done
and add command. For now, all commands must place the command name in
the right location.

Additionally, I've hooked up the react table's selection state to the
command parser. Filter based on _ids_ explicitly does work. Manually
selecting an ID will also place it in the input field for
discoverability. It does not remove ids that were manually deselected
yet, nor does filter based on any other attribute work.

The command parser also parses times, but it does so very poorly
currently. More work will need to go into that, for now it's basically a
stub. I'll also need to convert the parser to Go.

The react table conviently handles virtual tables based on it's internal
`row.id`. I'm still wondering how to implement virtual ids, but at least
on the web app, they are constantly updated since the view is always
visible, which is different to the CLI (though perhaps the same as a
TUI?)

Notably, there's no semantics for the difference between selection and
filtering. I think perhaps the implicit filter command should default to
selection, but the explicit filter command should be handled
differently, and actually execute filtering. I haven't yet looked into
how the TanStack Table handles filtering, but I am aware that it does.

I think for an MVP, once done is implemented, I can deploy this, the web
socket server, and try and start using it.

+1508 -9
+67 -9
mast-react-vite/src/App.tsx
··· 8 8 } from "@tanstack/react-table" 9 9 import { DataTable } from "@/components/ui/data-table" 10 10 import * as addParser from '../../parser/add_parser.js'; 11 + import * as commandParser from '../../parser/command_parser.js'; 11 12 import { Checkbox } from "@/components/ui/checkbox" 12 13 import { Input } from "@/components/ui/input" 13 14 ··· 49 50 className="translate-y-[2px]" 50 51 /> 51 52 ), 52 - cell: ({ row }) => ( 53 - <Checkbox 54 - checked={row.getIsSelected()} 55 - onCheckedChange={(value) => row.toggleSelected(!!value)} 56 - aria-label="Select row" 57 - className="translate-y-[2px]" 58 - /> 53 + cell: ({ row, table }) => ( 54 + <div className="flex items-center gap-2"> 55 + <p>{row.index+1}</p> 56 + <Checkbox 57 + checked={row.getIsSelected()} 58 + onCheckedChange={(value) => { 59 + row.toggleSelected(!!value); 60 + // Get setNewText from table meta 61 + const setNewText = table.options.meta?.setNewText; 62 + const NewText = table.options.meta?.newText; 63 + if (setNewText && value === true) { 64 + const calculatedRowId = row.index+1 65 + setNewText(NewText+calculatedRowId+","); 66 + } else { 67 + // TODO: 68 + // We need to _remove_ the value here 69 + // That probably means taking the NewText 70 + // Removing the first instance of "row.index," 71 + // And then setting that with setNewText 72 + } 73 + }} 74 + aria-label="Select row" 75 + className="translate-y-[2px]" 76 + /> 77 + </div> 59 78 ), 60 79 enableSorting: false, 61 80 enableHiding: false, ··· 82 101 function App({ ctx }) { 83 102 const todos = useQuery(ctx, "SELECT * FROM todos").data; 84 103 const [newText, setNewText] = useState(""); 104 + const [rowSelection, setRowSelection] = useState({}); 85 105 86 106 const addTodo = (e) => { 87 107 if (e.key === "Enter" && e.target.value.trim() !== "") { ··· 97 117 } 98 118 } 99 119 120 + const parseTodos = (e) => { 121 + if (e.target.value.trim() !== "") { 122 + try { 123 + const parsed = commandParser.parse(e.target.value); 124 + 125 + console.log(parsed) 126 + if (parsed.filters && parsed.filters.length > 0) { 127 + const idFilters = parsed.filters.filter(f => f.type === "id"); 128 + console.log(idFilters) 129 + 130 + // Create new selection state 131 + const newSelection = {}; 132 + idFilters.forEach(filter => { 133 + filter.ids.forEach(id => { 134 + newSelection[id-1] = true; 135 + }) 136 + }); 137 + 138 + setRowSelection(newSelection); 139 + } 140 + } catch (error) { 141 + console.log("Unable to parse field") 142 + return; 143 + } 144 + } else { 145 + setRowSelection({}); 146 + } 147 + } 148 + 100 149 return ( 101 150 <> 102 151 <section className="pt-8 container"> 103 152 <Input type="text" 104 153 className="bg-background p-4" 105 - onKeyUp={addTodo} 154 + placeholder="..." 155 + value={newText} 156 + onKeyUp={parseTodos} 106 157 onChange={(e) => setNewText(e.target.value)} 107 158 /> 108 159 <div className="p-2"/> 109 - <DataTable columns={columns} data={todos} /> 160 + <DataTable 161 + columns={columns} 162 + data={todos} 163 + rowSelection={rowSelection} 164 + setRowSelection={setRowSelection} 165 + setNewText={setNewText} 166 + newText={newText} 167 + /> 110 168 </section> 111 169 </> 112 170 )
+13
mast-react-vite/src/components/ui/data-table.tsx
··· 5 5 import { 6 6 ColumnDef, 7 7 ColumnSizingState, 8 + RowSelectionState, 8 9 flexRender, 9 10 getCoreRowModel, 10 11 useReactTable, ··· 22 23 interface DataTableProps<TData, TValue> { 23 24 columns: ColumnDef<TData, TValue>[] 24 25 data: TData[] 26 + rowSelection: {} 27 + setRowSelection: (value: {}) => void 25 28 } 26 29 27 30 export function DataTable<TData, TValue>({ 28 31 columns, 29 32 data, 33 + rowSelection, 34 + setNewText, 35 + newText, 36 + setRowSelection, 30 37 }: DataTableProps<TData, TValue>) { 31 38 const [colSizing, setColSizing] = useState<ColumnSizingState>({}); 32 39 const table = useReactTable({ ··· 36 43 columnResizeMode: "onChange", 37 44 getCoreRowModel: getCoreRowModel(), 38 45 onColumnSizingChange: setColSizing, 46 + onRowSelectionChange: setRowSelection, 39 47 state: { 40 48 columnSizing: colSizing, 49 + rowSelection: rowSelection, 41 50 }, 51 + meta: { 52 + setNewText, 53 + newText, 54 + } 42 55 }) 43 56 44 57 return (
+143
parser/command_js.peg
··· 1 + { 2 + function makeCommand(type, filters, parts) { 3 + 4 + const validParts = parts || []; 5 + // Extract pure description (without attributes) 6 + const description = validParts 7 + .filter(part => typeof part === 'string') 8 + .join(' ') 9 + .trim(); 10 + 11 + // Collect all attributes 12 + const attributes = validParts 13 + .filter(part => typeof part === 'object') 14 + .filter(part => part !== null); 15 + 16 + // Store original parts for reconstruction 17 + const originalParts = validParts.filter(part => part !== null); 18 + 19 + 20 + return { 21 + type: type, 22 + filters: filters.flat() || [], 23 + description: description || [], 24 + attributes: attributes || [], 25 + parts: parts || [], 26 + reconstruct: function() { 27 + const filterStr = this.filters.map(f => f.reconstruct()).join(','); 28 + const partsStr = this.parts.map(p => p.reconstruct()).join(' '); 29 + return [filterStr, this.type, partsStr].filter(Boolean).join(' '); 30 + } 31 + }; 32 + } 33 + } 34 + 35 + Start = AddCommand / DoneCommand / ExplicitFilterCommand / ImplicitFilterCommand 36 + 37 + // ADD COMMAND 38 + AddCommand = "add" _ parts:(Part / _)+ EOF { 39 + return makeCommand('add', null, parts.filter(p => p !== null)); 40 + } 41 + 42 + // DONE COMMAND 43 + DoneCommand = filters:Filters _ "done" EOF { 44 + return makeCommand('done', filters, null); 45 + } 46 + 47 + ExplicitFilterCommand = filters:Filters _ "filter" _* moreFilters:Filters* EOF { 48 + return makeCommand('filter', [...filters, ...moreFilters], null); 49 + } 50 + 51 + ImplicitFilterCommand = filters:Filters+ EOF { 52 + return makeCommand('filter', filters, null); 53 + } 54 + 55 + Filters = first:Filter rest:(_ Filter)* { 56 + return [first, ...rest.map(r => r[1])]; 57 + } 58 + 59 + 60 + IdRange = start:Integer "-" end:Integer { 61 + const ids = []; 62 + for (let i = start; i <= end; i++) { 63 + ids.push(i); 64 + } 65 + return ids; 66 + } 67 + 68 + SingleId = id:Integer { 69 + return [id]; 70 + } 71 + 72 + Filter = IdFilter / Tag / Project / Priority / Due 73 + 74 + IdFilter = first:(IdRange / SingleId) rest:("," (IdRange / SingleId))* trailing:"," ? { 75 + const ids = [first, ...rest.map(r => r[1])].flat(); 76 + return { 77 + type: 'id', 78 + ids: ids, 79 + reconstruct: function() { return this.ids.join(','); } 80 + }; 81 + } 82 + 83 + Part = Attribute / TextPart 84 + 85 + TextPart = chars:Word { 86 + return { 87 + type: "text", 88 + value: chars, 89 + reconstruct: function() { return this.value; } 90 + }; 91 + } 92 + 93 + Attribute = Due / Tag / Project / Priority 94 + 95 + Due = "@" value:TimeValue { 96 + return { 97 + type: "due", 98 + value: value, 99 + reconstruct: function() { return `@${this.value}`; } 100 + }; 101 + } 102 + 103 + Project = ("pro:" / "project:" / "+") value:Word { 104 + return { 105 + type: "project", 106 + value: value, 107 + reconstruct: function() { return `+${this.value}`; } 108 + }; 109 + } 110 + 111 + Priority = "priority:" value:[HML] { 112 + return { 113 + type: "priority", 114 + value: value, 115 + reconstruct: function() { return `priority:${this.value}`; } 116 + }; 117 + } 118 + 119 + Tag = "#" value:Word { 120 + return { 121 + type: "tag", 122 + value: value, 123 + reconstruct: function() { return `#${this.value}`; } 124 + }; 125 + } 126 + 127 + Integer = digits:[0-9]+ { 128 + return parseInt(digits.join(''), 10); 129 + } 130 + 131 + TimeValue = chars:[0-9:]+ ("am" / "pm")? { 132 + return chars.join('') + (text() || ''); 133 + } 134 + 135 + Word = chars:[a-zA-Z0-9_-]+ { 136 + return chars.join(''); 137 + } 138 + 139 + _ = [ \t]+ { 140 + return null; 141 + } 142 + 143 + EOF = !.
+1285
parser/command_parser.js
··· 1 + // @generated by Peggy 4.1.1. 2 + // 3 + // https://peggyjs.org/ 4 + 5 + 6 + function peg$subclass(child, parent) { 7 + function C() { this.constructor = child; } 8 + C.prototype = parent.prototype; 9 + child.prototype = new C(); 10 + } 11 + 12 + function peg$SyntaxError(message, expected, found, location) { 13 + var self = Error.call(this, message); 14 + // istanbul ignore next Check is a necessary evil to support older environments 15 + if (Object.setPrototypeOf) { 16 + Object.setPrototypeOf(self, peg$SyntaxError.prototype); 17 + } 18 + self.expected = expected; 19 + self.found = found; 20 + self.location = location; 21 + self.name = "SyntaxError"; 22 + return self; 23 + } 24 + 25 + peg$subclass(peg$SyntaxError, Error); 26 + 27 + function peg$padEnd(str, targetLength, padString) { 28 + padString = padString || " "; 29 + if (str.length > targetLength) { return str; } 30 + targetLength -= str.length; 31 + padString += padString.repeat(targetLength); 32 + return str + padString.slice(0, targetLength); 33 + } 34 + 35 + peg$SyntaxError.prototype.format = function(sources) { 36 + var str = "Error: " + this.message; 37 + if (this.location) { 38 + var src = null; 39 + var k; 40 + for (k = 0; k < sources.length; k++) { 41 + if (sources[k].source === this.location.source) { 42 + src = sources[k].text.split(/\r\n|\n|\r/g); 43 + break; 44 + } 45 + } 46 + var s = this.location.start; 47 + var offset_s = (this.location.source && (typeof this.location.source.offset === "function")) 48 + ? this.location.source.offset(s) 49 + : s; 50 + var loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column; 51 + if (src) { 52 + var e = this.location.end; 53 + var filler = peg$padEnd("", offset_s.line.toString().length, ' '); 54 + var line = src[s.line - 1]; 55 + var last = s.line === e.line ? e.column : line.length + 1; 56 + var hatLen = (last - s.column) || 1; 57 + str += "\n --> " + loc + "\n" 58 + + filler + " |\n" 59 + + offset_s.line + " | " + line + "\n" 60 + + filler + " | " + peg$padEnd("", s.column - 1, ' ') 61 + + peg$padEnd("", hatLen, "^"); 62 + } else { 63 + str += "\n at " + loc; 64 + } 65 + } 66 + return str; 67 + }; 68 + 69 + peg$SyntaxError.buildMessage = function(expected, found) { 70 + var DESCRIBE_EXPECTATION_FNS = { 71 + literal: function(expectation) { 72 + return "\"" + literalEscape(expectation.text) + "\""; 73 + }, 74 + 75 + class: function(expectation) { 76 + var escapedParts = expectation.parts.map(function(part) { 77 + return Array.isArray(part) 78 + ? classEscape(part[0]) + "-" + classEscape(part[1]) 79 + : classEscape(part); 80 + }); 81 + 82 + return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]"; 83 + }, 84 + 85 + any: function() { 86 + return "any character"; 87 + }, 88 + 89 + end: function() { 90 + return "end of input"; 91 + }, 92 + 93 + other: function(expectation) { 94 + return expectation.description; 95 + } 96 + }; 97 + 98 + function hex(ch) { 99 + return ch.charCodeAt(0).toString(16).toUpperCase(); 100 + } 101 + 102 + function literalEscape(s) { 103 + return s 104 + .replace(/\\/g, "\\\\") 105 + .replace(/"/g, "\\\"") 106 + .replace(/\0/g, "\\0") 107 + .replace(/\t/g, "\\t") 108 + .replace(/\n/g, "\\n") 109 + .replace(/\r/g, "\\r") 110 + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) 111 + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); 112 + } 113 + 114 + function classEscape(s) { 115 + return s 116 + .replace(/\\/g, "\\\\") 117 + .replace(/\]/g, "\\]") 118 + .replace(/\^/g, "\\^") 119 + .replace(/-/g, "\\-") 120 + .replace(/\0/g, "\\0") 121 + .replace(/\t/g, "\\t") 122 + .replace(/\n/g, "\\n") 123 + .replace(/\r/g, "\\r") 124 + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) 125 + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); 126 + } 127 + 128 + function describeExpectation(expectation) { 129 + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); 130 + } 131 + 132 + function describeExpected(expected) { 133 + var descriptions = expected.map(describeExpectation); 134 + var i, j; 135 + 136 + descriptions.sort(); 137 + 138 + if (descriptions.length > 0) { 139 + for (i = 1, j = 1; i < descriptions.length; i++) { 140 + if (descriptions[i - 1] !== descriptions[i]) { 141 + descriptions[j] = descriptions[i]; 142 + j++; 143 + } 144 + } 145 + descriptions.length = j; 146 + } 147 + 148 + switch (descriptions.length) { 149 + case 1: 150 + return descriptions[0]; 151 + 152 + case 2: 153 + return descriptions[0] + " or " + descriptions[1]; 154 + 155 + default: 156 + return descriptions.slice(0, -1).join(", ") 157 + + ", or " 158 + + descriptions[descriptions.length - 1]; 159 + } 160 + } 161 + 162 + function describeFound(found) { 163 + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; 164 + } 165 + 166 + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; 167 + }; 168 + 169 + function peg$parse(input, options) { 170 + options = options !== undefined ? options : {}; 171 + 172 + var peg$FAILED = {}; 173 + var peg$source = options.grammarSource; 174 + 175 + var peg$startRuleFunctions = { Start: peg$parseStart }; 176 + var peg$startRuleFunction = peg$parseStart; 177 + 178 + var peg$c0 = "add"; 179 + var peg$c1 = "done"; 180 + var peg$c2 = "filter"; 181 + var peg$c3 = "-"; 182 + var peg$c4 = ","; 183 + var peg$c5 = "@"; 184 + var peg$c6 = "pro:"; 185 + var peg$c7 = "project:"; 186 + var peg$c8 = "+"; 187 + var peg$c9 = "priority:"; 188 + var peg$c10 = "#"; 189 + var peg$c11 = "am"; 190 + var peg$c12 = "pm"; 191 + 192 + var peg$r0 = /^[HML]/; 193 + var peg$r1 = /^[0-9]/; 194 + var peg$r2 = /^[0-9:]/; 195 + var peg$r3 = /^[a-zA-Z0-9_\-]/; 196 + var peg$r4 = /^[ \t]/; 197 + 198 + var peg$e0 = peg$literalExpectation("add", false); 199 + var peg$e1 = peg$literalExpectation("done", false); 200 + var peg$e2 = peg$literalExpectation("filter", false); 201 + var peg$e3 = peg$literalExpectation("-", false); 202 + var peg$e4 = peg$literalExpectation(",", false); 203 + var peg$e5 = peg$literalExpectation("@", false); 204 + var peg$e6 = peg$literalExpectation("pro:", false); 205 + var peg$e7 = peg$literalExpectation("project:", false); 206 + var peg$e8 = peg$literalExpectation("+", false); 207 + var peg$e9 = peg$literalExpectation("priority:", false); 208 + var peg$e10 = peg$classExpectation(["H", "M", "L"], false, false); 209 + var peg$e11 = peg$literalExpectation("#", false); 210 + var peg$e12 = peg$classExpectation([["0", "9"]], false, false); 211 + var peg$e13 = peg$classExpectation([["0", "9"], ":"], false, false); 212 + var peg$e14 = peg$literalExpectation("am", false); 213 + var peg$e15 = peg$literalExpectation("pm", false); 214 + var peg$e16 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "-"], false, false); 215 + var peg$e17 = peg$classExpectation([" ", "\t"], false, false); 216 + var peg$e18 = peg$anyExpectation(); 217 + 218 + var peg$f0 = function(parts) { 219 + return makeCommand('add', null, parts.filter(p => p !== null)); 220 + }; 221 + var peg$f1 = function(filters) { 222 + return makeCommand('done', filters, null); 223 + }; 224 + var peg$f2 = function(filters, moreFilters) { 225 + return makeCommand('filter', [...filters, ...moreFilters], null); 226 + }; 227 + var peg$f3 = function(filters) { 228 + return makeCommand('filter', filters, null); 229 + }; 230 + var peg$f4 = function(first, rest) { 231 + return [first, ...rest.map(r => r[1])]; 232 + }; 233 + var peg$f5 = function(start, end) { 234 + const ids = []; 235 + for (let i = start; i <= end; i++) { 236 + ids.push(i); 237 + } 238 + return ids; 239 + }; 240 + var peg$f6 = function(id) { 241 + return [id]; 242 + }; 243 + var peg$f7 = function(first, rest, trailing) { 244 + const ids = [first, ...rest.map(r => r[1])].flat(); 245 + return { 246 + type: 'id', 247 + ids: ids, 248 + reconstruct: function() { return this.ids.join(','); } 249 + }; 250 + }; 251 + var peg$f8 = function(chars) { 252 + return { 253 + type: "text", 254 + value: chars, 255 + reconstruct: function() { return this.value; } 256 + }; 257 + }; 258 + var peg$f9 = function(value) { 259 + return { 260 + type: "due", 261 + value: value, 262 + reconstruct: function() { return `@${this.value}`; } 263 + }; 264 + }; 265 + var peg$f10 = function(value) { 266 + return { 267 + type: "project", 268 + value: value, 269 + reconstruct: function() { return `+${this.value}`; } 270 + }; 271 + }; 272 + var peg$f11 = function(value) { 273 + return { 274 + type: "priority", 275 + value: value, 276 + reconstruct: function() { return `priority:${this.value}`; } 277 + }; 278 + }; 279 + var peg$f12 = function(value) { 280 + return { 281 + type: "tag", 282 + value: value, 283 + reconstruct: function() { return `#${this.value}`; } 284 + }; 285 + }; 286 + var peg$f13 = function(digits) { 287 + return parseInt(digits.join(''), 10); 288 + }; 289 + var peg$f14 = function(chars) { 290 + return chars.join('') + (text() || ''); 291 + }; 292 + var peg$f15 = function(chars) { 293 + return chars.join(''); 294 + }; 295 + var peg$f16 = function() { 296 + return null; 297 + }; 298 + var peg$currPos = options.peg$currPos | 0; 299 + var peg$savedPos = peg$currPos; 300 + var peg$posDetailsCache = [{ line: 1, column: 1 }]; 301 + var peg$maxFailPos = peg$currPos; 302 + var peg$maxFailExpected = options.peg$maxFailExpected || []; 303 + var peg$silentFails = options.peg$silentFails | 0; 304 + 305 + var peg$result; 306 + 307 + if (options.startRule) { 308 + if (!(options.startRule in peg$startRuleFunctions)) { 309 + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); 310 + } 311 + 312 + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; 313 + } 314 + 315 + function text() { 316 + return input.substring(peg$savedPos, peg$currPos); 317 + } 318 + 319 + function offset() { 320 + return peg$savedPos; 321 + } 322 + 323 + function range() { 324 + return { 325 + source: peg$source, 326 + start: peg$savedPos, 327 + end: peg$currPos 328 + }; 329 + } 330 + 331 + function location() { 332 + return peg$computeLocation(peg$savedPos, peg$currPos); 333 + } 334 + 335 + function expected(description, location) { 336 + location = location !== undefined 337 + ? location 338 + : peg$computeLocation(peg$savedPos, peg$currPos); 339 + 340 + throw peg$buildStructuredError( 341 + [peg$otherExpectation(description)], 342 + input.substring(peg$savedPos, peg$currPos), 343 + location 344 + ); 345 + } 346 + 347 + function error(message, location) { 348 + location = location !== undefined 349 + ? location 350 + : peg$computeLocation(peg$savedPos, peg$currPos); 351 + 352 + throw peg$buildSimpleError(message, location); 353 + } 354 + 355 + function peg$literalExpectation(text, ignoreCase) { 356 + return { type: "literal", text: text, ignoreCase: ignoreCase }; 357 + } 358 + 359 + function peg$classExpectation(parts, inverted, ignoreCase) { 360 + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; 361 + } 362 + 363 + function peg$anyExpectation() { 364 + return { type: "any" }; 365 + } 366 + 367 + function peg$endExpectation() { 368 + return { type: "end" }; 369 + } 370 + 371 + function peg$otherExpectation(description) { 372 + return { type: "other", description: description }; 373 + } 374 + 375 + function peg$computePosDetails(pos) { 376 + var details = peg$posDetailsCache[pos]; 377 + var p; 378 + 379 + if (details) { 380 + return details; 381 + } else { 382 + if (pos >= peg$posDetailsCache.length) { 383 + p = peg$posDetailsCache.length - 1; 384 + } else { 385 + p = pos; 386 + while (!peg$posDetailsCache[--p]) {} 387 + } 388 + 389 + details = peg$posDetailsCache[p]; 390 + details = { 391 + line: details.line, 392 + column: details.column 393 + }; 394 + 395 + while (p < pos) { 396 + if (input.charCodeAt(p) === 10) { 397 + details.line++; 398 + details.column = 1; 399 + } else { 400 + details.column++; 401 + } 402 + 403 + p++; 404 + } 405 + 406 + peg$posDetailsCache[pos] = details; 407 + 408 + return details; 409 + } 410 + } 411 + 412 + function peg$computeLocation(startPos, endPos, offset) { 413 + var startPosDetails = peg$computePosDetails(startPos); 414 + var endPosDetails = peg$computePosDetails(endPos); 415 + 416 + var res = { 417 + source: peg$source, 418 + start: { 419 + offset: startPos, 420 + line: startPosDetails.line, 421 + column: startPosDetails.column 422 + }, 423 + end: { 424 + offset: endPos, 425 + line: endPosDetails.line, 426 + column: endPosDetails.column 427 + } 428 + }; 429 + if (offset && peg$source && (typeof peg$source.offset === "function")) { 430 + res.start = peg$source.offset(res.start); 431 + res.end = peg$source.offset(res.end); 432 + } 433 + return res; 434 + } 435 + 436 + function peg$fail(expected) { 437 + if (peg$currPos < peg$maxFailPos) { return; } 438 + 439 + if (peg$currPos > peg$maxFailPos) { 440 + peg$maxFailPos = peg$currPos; 441 + peg$maxFailExpected = []; 442 + } 443 + 444 + peg$maxFailExpected.push(expected); 445 + } 446 + 447 + function peg$buildSimpleError(message, location) { 448 + return new peg$SyntaxError(message, null, null, location); 449 + } 450 + 451 + function peg$buildStructuredError(expected, found, location) { 452 + return new peg$SyntaxError( 453 + peg$SyntaxError.buildMessage(expected, found), 454 + expected, 455 + found, 456 + location 457 + ); 458 + } 459 + 460 + function peg$parseStart() { 461 + var s0; 462 + 463 + s0 = peg$parseAddCommand(); 464 + if (s0 === peg$FAILED) { 465 + s0 = peg$parseDoneCommand(); 466 + if (s0 === peg$FAILED) { 467 + s0 = peg$parseExplicitFilterCommand(); 468 + if (s0 === peg$FAILED) { 469 + s0 = peg$parseImplicitFilterCommand(); 470 + } 471 + } 472 + } 473 + 474 + return s0; 475 + } 476 + 477 + function peg$parseAddCommand() { 478 + var s0, s1, s2, s3, s4; 479 + 480 + s0 = peg$currPos; 481 + if (input.substr(peg$currPos, 3) === peg$c0) { 482 + s1 = peg$c0; 483 + peg$currPos += 3; 484 + } else { 485 + s1 = peg$FAILED; 486 + if (peg$silentFails === 0) { peg$fail(peg$e0); } 487 + } 488 + if (s1 !== peg$FAILED) { 489 + s2 = peg$parse_(); 490 + if (s2 !== peg$FAILED) { 491 + s3 = []; 492 + s4 = peg$parsePart(); 493 + if (s4 === peg$FAILED) { 494 + s4 = peg$parse_(); 495 + } 496 + if (s4 !== peg$FAILED) { 497 + while (s4 !== peg$FAILED) { 498 + s3.push(s4); 499 + s4 = peg$parsePart(); 500 + if (s4 === peg$FAILED) { 501 + s4 = peg$parse_(); 502 + } 503 + } 504 + } else { 505 + s3 = peg$FAILED; 506 + } 507 + if (s3 !== peg$FAILED) { 508 + s4 = peg$parseEOF(); 509 + if (s4 !== peg$FAILED) { 510 + peg$savedPos = s0; 511 + s0 = peg$f0(s3); 512 + } else { 513 + peg$currPos = s0; 514 + s0 = peg$FAILED; 515 + } 516 + } else { 517 + peg$currPos = s0; 518 + s0 = peg$FAILED; 519 + } 520 + } else { 521 + peg$currPos = s0; 522 + s0 = peg$FAILED; 523 + } 524 + } else { 525 + peg$currPos = s0; 526 + s0 = peg$FAILED; 527 + } 528 + 529 + return s0; 530 + } 531 + 532 + function peg$parseDoneCommand() { 533 + var s0, s1, s2, s3, s4; 534 + 535 + s0 = peg$currPos; 536 + s1 = peg$parseFilters(); 537 + if (s1 !== peg$FAILED) { 538 + s2 = peg$parse_(); 539 + if (s2 !== peg$FAILED) { 540 + if (input.substr(peg$currPos, 4) === peg$c1) { 541 + s3 = peg$c1; 542 + peg$currPos += 4; 543 + } else { 544 + s3 = peg$FAILED; 545 + if (peg$silentFails === 0) { peg$fail(peg$e1); } 546 + } 547 + if (s3 !== peg$FAILED) { 548 + s4 = peg$parseEOF(); 549 + if (s4 !== peg$FAILED) { 550 + peg$savedPos = s0; 551 + s0 = peg$f1(s1); 552 + } else { 553 + peg$currPos = s0; 554 + s0 = peg$FAILED; 555 + } 556 + } else { 557 + peg$currPos = s0; 558 + s0 = peg$FAILED; 559 + } 560 + } else { 561 + peg$currPos = s0; 562 + s0 = peg$FAILED; 563 + } 564 + } else { 565 + peg$currPos = s0; 566 + s0 = peg$FAILED; 567 + } 568 + 569 + return s0; 570 + } 571 + 572 + function peg$parseExplicitFilterCommand() { 573 + var s0, s1, s2, s3, s4, s5, s6; 574 + 575 + s0 = peg$currPos; 576 + s1 = peg$parseFilters(); 577 + if (s1 !== peg$FAILED) { 578 + s2 = peg$parse_(); 579 + if (s2 !== peg$FAILED) { 580 + if (input.substr(peg$currPos, 6) === peg$c2) { 581 + s3 = peg$c2; 582 + peg$currPos += 6; 583 + } else { 584 + s3 = peg$FAILED; 585 + if (peg$silentFails === 0) { peg$fail(peg$e2); } 586 + } 587 + if (s3 !== peg$FAILED) { 588 + s4 = []; 589 + s5 = peg$parse_(); 590 + while (s5 !== peg$FAILED) { 591 + s4.push(s5); 592 + s5 = peg$parse_(); 593 + } 594 + s5 = []; 595 + s6 = peg$parseFilters(); 596 + while (s6 !== peg$FAILED) { 597 + s5.push(s6); 598 + s6 = peg$parseFilters(); 599 + } 600 + s6 = peg$parseEOF(); 601 + if (s6 !== peg$FAILED) { 602 + peg$savedPos = s0; 603 + s0 = peg$f2(s1, s5); 604 + } else { 605 + peg$currPos = s0; 606 + s0 = peg$FAILED; 607 + } 608 + } else { 609 + peg$currPos = s0; 610 + s0 = peg$FAILED; 611 + } 612 + } else { 613 + peg$currPos = s0; 614 + s0 = peg$FAILED; 615 + } 616 + } else { 617 + peg$currPos = s0; 618 + s0 = peg$FAILED; 619 + } 620 + 621 + return s0; 622 + } 623 + 624 + function peg$parseImplicitFilterCommand() { 625 + var s0, s1, s2; 626 + 627 + s0 = peg$currPos; 628 + s1 = []; 629 + s2 = peg$parseFilters(); 630 + if (s2 !== peg$FAILED) { 631 + while (s2 !== peg$FAILED) { 632 + s1.push(s2); 633 + s2 = peg$parseFilters(); 634 + } 635 + } else { 636 + s1 = peg$FAILED; 637 + } 638 + if (s1 !== peg$FAILED) { 639 + s2 = peg$parseEOF(); 640 + if (s2 !== peg$FAILED) { 641 + peg$savedPos = s0; 642 + s0 = peg$f3(s1); 643 + } else { 644 + peg$currPos = s0; 645 + s0 = peg$FAILED; 646 + } 647 + } else { 648 + peg$currPos = s0; 649 + s0 = peg$FAILED; 650 + } 651 + 652 + return s0; 653 + } 654 + 655 + function peg$parseFilters() { 656 + var s0, s1, s2, s3, s4, s5; 657 + 658 + s0 = peg$currPos; 659 + s1 = peg$parseFilter(); 660 + if (s1 !== peg$FAILED) { 661 + s2 = []; 662 + s3 = peg$currPos; 663 + s4 = peg$parse_(); 664 + if (s4 !== peg$FAILED) { 665 + s5 = peg$parseFilter(); 666 + if (s5 !== peg$FAILED) { 667 + s4 = [s4, s5]; 668 + s3 = s4; 669 + } else { 670 + peg$currPos = s3; 671 + s3 = peg$FAILED; 672 + } 673 + } else { 674 + peg$currPos = s3; 675 + s3 = peg$FAILED; 676 + } 677 + while (s3 !== peg$FAILED) { 678 + s2.push(s3); 679 + s3 = peg$currPos; 680 + s4 = peg$parse_(); 681 + if (s4 !== peg$FAILED) { 682 + s5 = peg$parseFilter(); 683 + if (s5 !== peg$FAILED) { 684 + s4 = [s4, s5]; 685 + s3 = s4; 686 + } else { 687 + peg$currPos = s3; 688 + s3 = peg$FAILED; 689 + } 690 + } else { 691 + peg$currPos = s3; 692 + s3 = peg$FAILED; 693 + } 694 + } 695 + peg$savedPos = s0; 696 + s0 = peg$f4(s1, s2); 697 + } else { 698 + peg$currPos = s0; 699 + s0 = peg$FAILED; 700 + } 701 + 702 + return s0; 703 + } 704 + 705 + function peg$parseIdRange() { 706 + var s0, s1, s2, s3; 707 + 708 + s0 = peg$currPos; 709 + s1 = peg$parseInteger(); 710 + if (s1 !== peg$FAILED) { 711 + if (input.charCodeAt(peg$currPos) === 45) { 712 + s2 = peg$c3; 713 + peg$currPos++; 714 + } else { 715 + s2 = peg$FAILED; 716 + if (peg$silentFails === 0) { peg$fail(peg$e3); } 717 + } 718 + if (s2 !== peg$FAILED) { 719 + s3 = peg$parseInteger(); 720 + if (s3 !== peg$FAILED) { 721 + peg$savedPos = s0; 722 + s0 = peg$f5(s1, s3); 723 + } else { 724 + peg$currPos = s0; 725 + s0 = peg$FAILED; 726 + } 727 + } else { 728 + peg$currPos = s0; 729 + s0 = peg$FAILED; 730 + } 731 + } else { 732 + peg$currPos = s0; 733 + s0 = peg$FAILED; 734 + } 735 + 736 + return s0; 737 + } 738 + 739 + function peg$parseSingleId() { 740 + var s0, s1; 741 + 742 + s0 = peg$currPos; 743 + s1 = peg$parseInteger(); 744 + if (s1 !== peg$FAILED) { 745 + peg$savedPos = s0; 746 + s1 = peg$f6(s1); 747 + } 748 + s0 = s1; 749 + 750 + return s0; 751 + } 752 + 753 + function peg$parseFilter() { 754 + var s0; 755 + 756 + s0 = peg$parseIdFilter(); 757 + if (s0 === peg$FAILED) { 758 + s0 = peg$parseTag(); 759 + if (s0 === peg$FAILED) { 760 + s0 = peg$parseProject(); 761 + if (s0 === peg$FAILED) { 762 + s0 = peg$parsePriority(); 763 + if (s0 === peg$FAILED) { 764 + s0 = peg$parseDue(); 765 + } 766 + } 767 + } 768 + } 769 + 770 + return s0; 771 + } 772 + 773 + function peg$parseIdFilter() { 774 + var s0, s1, s2, s3, s4, s5; 775 + 776 + s0 = peg$currPos; 777 + s1 = peg$parseIdRange(); 778 + if (s1 === peg$FAILED) { 779 + s1 = peg$parseSingleId(); 780 + } 781 + if (s1 !== peg$FAILED) { 782 + s2 = []; 783 + s3 = peg$currPos; 784 + if (input.charCodeAt(peg$currPos) === 44) { 785 + s4 = peg$c4; 786 + peg$currPos++; 787 + } else { 788 + s4 = peg$FAILED; 789 + if (peg$silentFails === 0) { peg$fail(peg$e4); } 790 + } 791 + if (s4 !== peg$FAILED) { 792 + s5 = peg$parseIdRange(); 793 + if (s5 === peg$FAILED) { 794 + s5 = peg$parseSingleId(); 795 + } 796 + if (s5 !== peg$FAILED) { 797 + s4 = [s4, s5]; 798 + s3 = s4; 799 + } else { 800 + peg$currPos = s3; 801 + s3 = peg$FAILED; 802 + } 803 + } else { 804 + peg$currPos = s3; 805 + s3 = peg$FAILED; 806 + } 807 + while (s3 !== peg$FAILED) { 808 + s2.push(s3); 809 + s3 = peg$currPos; 810 + if (input.charCodeAt(peg$currPos) === 44) { 811 + s4 = peg$c4; 812 + peg$currPos++; 813 + } else { 814 + s4 = peg$FAILED; 815 + if (peg$silentFails === 0) { peg$fail(peg$e4); } 816 + } 817 + if (s4 !== peg$FAILED) { 818 + s5 = peg$parseIdRange(); 819 + if (s5 === peg$FAILED) { 820 + s5 = peg$parseSingleId(); 821 + } 822 + if (s5 !== peg$FAILED) { 823 + s4 = [s4, s5]; 824 + s3 = s4; 825 + } else { 826 + peg$currPos = s3; 827 + s3 = peg$FAILED; 828 + } 829 + } else { 830 + peg$currPos = s3; 831 + s3 = peg$FAILED; 832 + } 833 + } 834 + if (input.charCodeAt(peg$currPos) === 44) { 835 + s3 = peg$c4; 836 + peg$currPos++; 837 + } else { 838 + s3 = peg$FAILED; 839 + if (peg$silentFails === 0) { peg$fail(peg$e4); } 840 + } 841 + if (s3 === peg$FAILED) { 842 + s3 = null; 843 + } 844 + peg$savedPos = s0; 845 + s0 = peg$f7(s1, s2, s3); 846 + } else { 847 + peg$currPos = s0; 848 + s0 = peg$FAILED; 849 + } 850 + 851 + return s0; 852 + } 853 + 854 + function peg$parsePart() { 855 + var s0; 856 + 857 + s0 = peg$parseAttribute(); 858 + if (s0 === peg$FAILED) { 859 + s0 = peg$parseTextPart(); 860 + } 861 + 862 + return s0; 863 + } 864 + 865 + function peg$parseTextPart() { 866 + var s0, s1; 867 + 868 + s0 = peg$currPos; 869 + s1 = peg$parseWord(); 870 + if (s1 !== peg$FAILED) { 871 + peg$savedPos = s0; 872 + s1 = peg$f8(s1); 873 + } 874 + s0 = s1; 875 + 876 + return s0; 877 + } 878 + 879 + function peg$parseAttribute() { 880 + var s0; 881 + 882 + s0 = peg$parseDue(); 883 + if (s0 === peg$FAILED) { 884 + s0 = peg$parseTag(); 885 + if (s0 === peg$FAILED) { 886 + s0 = peg$parseProject(); 887 + if (s0 === peg$FAILED) { 888 + s0 = peg$parsePriority(); 889 + } 890 + } 891 + } 892 + 893 + return s0; 894 + } 895 + 896 + function peg$parseDue() { 897 + var s0, s1, s2; 898 + 899 + s0 = peg$currPos; 900 + if (input.charCodeAt(peg$currPos) === 64) { 901 + s1 = peg$c5; 902 + peg$currPos++; 903 + } else { 904 + s1 = peg$FAILED; 905 + if (peg$silentFails === 0) { peg$fail(peg$e5); } 906 + } 907 + if (s1 !== peg$FAILED) { 908 + s2 = peg$parseTimeValue(); 909 + if (s2 !== peg$FAILED) { 910 + peg$savedPos = s0; 911 + s0 = peg$f9(s2); 912 + } else { 913 + peg$currPos = s0; 914 + s0 = peg$FAILED; 915 + } 916 + } else { 917 + peg$currPos = s0; 918 + s0 = peg$FAILED; 919 + } 920 + 921 + return s0; 922 + } 923 + 924 + function peg$parseProject() { 925 + var s0, s1, s2; 926 + 927 + s0 = peg$currPos; 928 + if (input.substr(peg$currPos, 4) === peg$c6) { 929 + s1 = peg$c6; 930 + peg$currPos += 4; 931 + } else { 932 + s1 = peg$FAILED; 933 + if (peg$silentFails === 0) { peg$fail(peg$e6); } 934 + } 935 + if (s1 === peg$FAILED) { 936 + if (input.substr(peg$currPos, 8) === peg$c7) { 937 + s1 = peg$c7; 938 + peg$currPos += 8; 939 + } else { 940 + s1 = peg$FAILED; 941 + if (peg$silentFails === 0) { peg$fail(peg$e7); } 942 + } 943 + if (s1 === peg$FAILED) { 944 + if (input.charCodeAt(peg$currPos) === 43) { 945 + s1 = peg$c8; 946 + peg$currPos++; 947 + } else { 948 + s1 = peg$FAILED; 949 + if (peg$silentFails === 0) { peg$fail(peg$e8); } 950 + } 951 + } 952 + } 953 + if (s1 !== peg$FAILED) { 954 + s2 = peg$parseWord(); 955 + if (s2 !== peg$FAILED) { 956 + peg$savedPos = s0; 957 + s0 = peg$f10(s2); 958 + } else { 959 + peg$currPos = s0; 960 + s0 = peg$FAILED; 961 + } 962 + } else { 963 + peg$currPos = s0; 964 + s0 = peg$FAILED; 965 + } 966 + 967 + return s0; 968 + } 969 + 970 + function peg$parsePriority() { 971 + var s0, s1, s2; 972 + 973 + s0 = peg$currPos; 974 + if (input.substr(peg$currPos, 9) === peg$c9) { 975 + s1 = peg$c9; 976 + peg$currPos += 9; 977 + } else { 978 + s1 = peg$FAILED; 979 + if (peg$silentFails === 0) { peg$fail(peg$e9); } 980 + } 981 + if (s1 !== peg$FAILED) { 982 + s2 = input.charAt(peg$currPos); 983 + if (peg$r0.test(s2)) { 984 + peg$currPos++; 985 + } else { 986 + s2 = peg$FAILED; 987 + if (peg$silentFails === 0) { peg$fail(peg$e10); } 988 + } 989 + if (s2 !== peg$FAILED) { 990 + peg$savedPos = s0; 991 + s0 = peg$f11(s2); 992 + } else { 993 + peg$currPos = s0; 994 + s0 = peg$FAILED; 995 + } 996 + } else { 997 + peg$currPos = s0; 998 + s0 = peg$FAILED; 999 + } 1000 + 1001 + return s0; 1002 + } 1003 + 1004 + function peg$parseTag() { 1005 + var s0, s1, s2; 1006 + 1007 + s0 = peg$currPos; 1008 + if (input.charCodeAt(peg$currPos) === 35) { 1009 + s1 = peg$c10; 1010 + peg$currPos++; 1011 + } else { 1012 + s1 = peg$FAILED; 1013 + if (peg$silentFails === 0) { peg$fail(peg$e11); } 1014 + } 1015 + if (s1 !== peg$FAILED) { 1016 + s2 = peg$parseWord(); 1017 + if (s2 !== peg$FAILED) { 1018 + peg$savedPos = s0; 1019 + s0 = peg$f12(s2); 1020 + } else { 1021 + peg$currPos = s0; 1022 + s0 = peg$FAILED; 1023 + } 1024 + } else { 1025 + peg$currPos = s0; 1026 + s0 = peg$FAILED; 1027 + } 1028 + 1029 + return s0; 1030 + } 1031 + 1032 + function peg$parseInteger() { 1033 + var s0, s1, s2; 1034 + 1035 + s0 = peg$currPos; 1036 + s1 = []; 1037 + s2 = input.charAt(peg$currPos); 1038 + if (peg$r1.test(s2)) { 1039 + peg$currPos++; 1040 + } else { 1041 + s2 = peg$FAILED; 1042 + if (peg$silentFails === 0) { peg$fail(peg$e12); } 1043 + } 1044 + if (s2 !== peg$FAILED) { 1045 + while (s2 !== peg$FAILED) { 1046 + s1.push(s2); 1047 + s2 = input.charAt(peg$currPos); 1048 + if (peg$r1.test(s2)) { 1049 + peg$currPos++; 1050 + } else { 1051 + s2 = peg$FAILED; 1052 + if (peg$silentFails === 0) { peg$fail(peg$e12); } 1053 + } 1054 + } 1055 + } else { 1056 + s1 = peg$FAILED; 1057 + } 1058 + if (s1 !== peg$FAILED) { 1059 + peg$savedPos = s0; 1060 + s1 = peg$f13(s1); 1061 + } 1062 + s0 = s1; 1063 + 1064 + return s0; 1065 + } 1066 + 1067 + function peg$parseTimeValue() { 1068 + var s0, s1, s2; 1069 + 1070 + s0 = peg$currPos; 1071 + s1 = []; 1072 + s2 = input.charAt(peg$currPos); 1073 + if (peg$r2.test(s2)) { 1074 + peg$currPos++; 1075 + } else { 1076 + s2 = peg$FAILED; 1077 + if (peg$silentFails === 0) { peg$fail(peg$e13); } 1078 + } 1079 + if (s2 !== peg$FAILED) { 1080 + while (s2 !== peg$FAILED) { 1081 + s1.push(s2); 1082 + s2 = input.charAt(peg$currPos); 1083 + if (peg$r2.test(s2)) { 1084 + peg$currPos++; 1085 + } else { 1086 + s2 = peg$FAILED; 1087 + if (peg$silentFails === 0) { peg$fail(peg$e13); } 1088 + } 1089 + } 1090 + } else { 1091 + s1 = peg$FAILED; 1092 + } 1093 + if (s1 !== peg$FAILED) { 1094 + if (input.substr(peg$currPos, 2) === peg$c11) { 1095 + s2 = peg$c11; 1096 + peg$currPos += 2; 1097 + } else { 1098 + s2 = peg$FAILED; 1099 + if (peg$silentFails === 0) { peg$fail(peg$e14); } 1100 + } 1101 + if (s2 === peg$FAILED) { 1102 + if (input.substr(peg$currPos, 2) === peg$c12) { 1103 + s2 = peg$c12; 1104 + peg$currPos += 2; 1105 + } else { 1106 + s2 = peg$FAILED; 1107 + if (peg$silentFails === 0) { peg$fail(peg$e15); } 1108 + } 1109 + } 1110 + if (s2 === peg$FAILED) { 1111 + s2 = null; 1112 + } 1113 + peg$savedPos = s0; 1114 + s0 = peg$f14(s1); 1115 + } else { 1116 + peg$currPos = s0; 1117 + s0 = peg$FAILED; 1118 + } 1119 + 1120 + return s0; 1121 + } 1122 + 1123 + function peg$parseWord() { 1124 + var s0, s1, s2; 1125 + 1126 + s0 = peg$currPos; 1127 + s1 = []; 1128 + s2 = input.charAt(peg$currPos); 1129 + if (peg$r3.test(s2)) { 1130 + peg$currPos++; 1131 + } else { 1132 + s2 = peg$FAILED; 1133 + if (peg$silentFails === 0) { peg$fail(peg$e16); } 1134 + } 1135 + if (s2 !== peg$FAILED) { 1136 + while (s2 !== peg$FAILED) { 1137 + s1.push(s2); 1138 + s2 = input.charAt(peg$currPos); 1139 + if (peg$r3.test(s2)) { 1140 + peg$currPos++; 1141 + } else { 1142 + s2 = peg$FAILED; 1143 + if (peg$silentFails === 0) { peg$fail(peg$e16); } 1144 + } 1145 + } 1146 + } else { 1147 + s1 = peg$FAILED; 1148 + } 1149 + if (s1 !== peg$FAILED) { 1150 + peg$savedPos = s0; 1151 + s1 = peg$f15(s1); 1152 + } 1153 + s0 = s1; 1154 + 1155 + return s0; 1156 + } 1157 + 1158 + function peg$parse_() { 1159 + var s0, s1, s2; 1160 + 1161 + s0 = peg$currPos; 1162 + s1 = []; 1163 + s2 = input.charAt(peg$currPos); 1164 + if (peg$r4.test(s2)) { 1165 + peg$currPos++; 1166 + } else { 1167 + s2 = peg$FAILED; 1168 + if (peg$silentFails === 0) { peg$fail(peg$e17); } 1169 + } 1170 + if (s2 !== peg$FAILED) { 1171 + while (s2 !== peg$FAILED) { 1172 + s1.push(s2); 1173 + s2 = input.charAt(peg$currPos); 1174 + if (peg$r4.test(s2)) { 1175 + peg$currPos++; 1176 + } else { 1177 + s2 = peg$FAILED; 1178 + if (peg$silentFails === 0) { peg$fail(peg$e17); } 1179 + } 1180 + } 1181 + } else { 1182 + s1 = peg$FAILED; 1183 + } 1184 + if (s1 !== peg$FAILED) { 1185 + peg$savedPos = s0; 1186 + s1 = peg$f16(); 1187 + } 1188 + s0 = s1; 1189 + 1190 + return s0; 1191 + } 1192 + 1193 + function peg$parseEOF() { 1194 + var s0, s1; 1195 + 1196 + s0 = peg$currPos; 1197 + peg$silentFails++; 1198 + if (input.length > peg$currPos) { 1199 + s1 = input.charAt(peg$currPos); 1200 + peg$currPos++; 1201 + } else { 1202 + s1 = peg$FAILED; 1203 + if (peg$silentFails === 0) { peg$fail(peg$e18); } 1204 + } 1205 + peg$silentFails--; 1206 + if (s1 === peg$FAILED) { 1207 + s0 = undefined; 1208 + } else { 1209 + peg$currPos = s0; 1210 + s0 = peg$FAILED; 1211 + } 1212 + 1213 + return s0; 1214 + } 1215 + 1216 + 1217 + function makeCommand(type, filters, parts) { 1218 + 1219 + const validParts = parts || []; 1220 + // Extract pure description (without attributes) 1221 + const description = validParts 1222 + .filter(part => typeof part === 'string') 1223 + .join(' ') 1224 + .trim(); 1225 + 1226 + // Collect all attributes 1227 + const attributes = validParts 1228 + .filter(part => typeof part === 'object') 1229 + .filter(part => part !== null); 1230 + 1231 + // Store original parts for reconstruction 1232 + const originalParts = validParts.filter(part => part !== null); 1233 + 1234 + 1235 + return { 1236 + type: type, 1237 + filters: filters.flat() || [], 1238 + description: description || [], 1239 + attributes: attributes || [], 1240 + parts: parts || [], 1241 + reconstruct: function() { 1242 + const filterStr = this.filters.map(f => f.reconstruct()).join(','); 1243 + const partsStr = this.parts.map(p => p.reconstruct()).join(' '); 1244 + return [filterStr, this.type, partsStr].filter(Boolean).join(' '); 1245 + } 1246 + }; 1247 + } 1248 + 1249 + peg$result = peg$startRuleFunction(); 1250 + 1251 + if (options.peg$library) { 1252 + return /** @type {any} */ ({ 1253 + peg$result, 1254 + peg$currPos, 1255 + peg$FAILED, 1256 + peg$maxFailExpected, 1257 + peg$maxFailPos 1258 + }); 1259 + } 1260 + if (peg$result !== peg$FAILED && peg$currPos === input.length) { 1261 + return peg$result; 1262 + } else { 1263 + if (peg$result !== peg$FAILED && peg$currPos < input.length) { 1264 + peg$fail(peg$endExpectation()); 1265 + } 1266 + 1267 + throw peg$buildStructuredError( 1268 + peg$maxFailExpected, 1269 + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, 1270 + peg$maxFailPos < input.length 1271 + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) 1272 + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) 1273 + ); 1274 + } 1275 + } 1276 + 1277 + const peg$allowedStartRules = [ 1278 + "Start" 1279 + ]; 1280 + 1281 + export { 1282 + peg$allowedStartRules as StartRules, 1283 + peg$SyntaxError as SyntaxError, 1284 + peg$parse as parse 1285 + };