@ofocus/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -0
- package/api-report/ofocus-sdk.api.md +564 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/applescript.d.ts +30 -0
- package/dist/applescript.d.ts.map +1 -0
- package/dist/applescript.js +142 -0
- package/dist/applescript.js.map +1 -0
- package/dist/commands/batch.d.ts +23 -0
- package/dist/commands/batch.d.ts.map +1 -0
- package/dist/commands/batch.js +324 -0
- package/dist/commands/batch.js.map +1 -0
- package/dist/commands/complete.d.ts +14 -0
- package/dist/commands/complete.d.ts.map +1 -0
- package/dist/commands/complete.js +37 -0
- package/dist/commands/complete.js.map +1 -0
- package/dist/commands/create-project.d.ts +6 -0
- package/dist/commands/create-project.d.ts.map +1 -0
- package/dist/commands/create-project.js +124 -0
- package/dist/commands/create-project.js.map +1 -0
- package/dist/commands/drop.d.ts +26 -0
- package/dist/commands/drop.d.ts.map +1 -0
- package/dist/commands/drop.js +62 -0
- package/dist/commands/drop.js.map +1 -0
- package/dist/commands/folders.d.ts +10 -0
- package/dist/commands/folders.d.ts.map +1 -0
- package/dist/commands/folders.js +150 -0
- package/dist/commands/folders.js.map +1 -0
- package/dist/commands/inbox.d.ts +6 -0
- package/dist/commands/inbox.d.ts.map +1 -0
- package/dist/commands/inbox.js +124 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/perspectives.d.ts +20 -0
- package/dist/commands/perspectives.d.ts.map +1 -0
- package/dist/commands/perspectives.js +166 -0
- package/dist/commands/perspectives.js.map +1 -0
- package/dist/commands/projects.d.ts +6 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +113 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/repetition.d.ts +17 -0
- package/dist/commands/repetition.d.ts.map +1 -0
- package/dist/commands/repetition.js +59 -0
- package/dist/commands/repetition.js.map +1 -0
- package/dist/commands/review.d.ts +10 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +132 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/search.d.ts +6 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +150 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/subtasks.d.ts +14 -0
- package/dist/commands/subtasks.d.ts.map +1 -0
- package/dist/commands/subtasks.js +370 -0
- package/dist/commands/subtasks.js.map +1 -0
- package/dist/commands/tags-crud.d.ts +22 -0
- package/dist/commands/tags-crud.d.ts.map +1 -0
- package/dist/commands/tags-crud.js +187 -0
- package/dist/commands/tags-crud.js.map +1 -0
- package/dist/commands/tags.d.ts +6 -0
- package/dist/commands/tags.d.ts.map +1 -0
- package/dist/commands/tags.js +61 -0
- package/dist/commands/tags.js.map +1 -0
- package/dist/commands/tasks.d.ts +6 -0
- package/dist/commands/tasks.d.ts.map +1 -0
- package/dist/commands/tasks.js +160 -0
- package/dist/commands/tasks.js.map +1 -0
- package/dist/commands/update.d.ts +6 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +179 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/errors.d.ts +38 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +77 -0
- package/dist/errors.js.map +1 -0
- package/dist/escape.d.ts +6 -0
- package/dist/escape.d.ts.map +1 -0
- package/dist/escape.js +8 -0
- package/dist/escape.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/ofocus-sdk.d.ts +608 -0
- package/dist/result.d.ts +15 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +29 -0
- package/dist/result.js.map +1 -0
- package/dist/types.d.ts +228 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +57 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +172 -0
- package/dist/validation.js.map +1 -0
- package/docs/index.md +30 -0
- package/docs/sdk.addtoinbox.md +68 -0
- package/docs/sdk.applescriptresult.data.md +11 -0
- package/docs/sdk.applescriptresult.error.md +11 -0
- package/docs/sdk.applescriptresult.md +92 -0
- package/docs/sdk.applescriptresult.success.md +11 -0
- package/docs/sdk.clierror.code.md +11 -0
- package/docs/sdk.clierror.details.md +11 -0
- package/docs/sdk.clierror.md +92 -0
- package/docs/sdk.clierror.message.md +11 -0
- package/docs/sdk.clioutput.data.md +11 -0
- package/docs/sdk.clioutput.error.md +11 -0
- package/docs/sdk.clioutput.md +90 -0
- package/docs/sdk.clioutput.success.md +11 -0
- package/docs/sdk.commandinfo.description.md +11 -0
- package/docs/sdk.commandinfo.md +90 -0
- package/docs/sdk.commandinfo.name.md +11 -0
- package/docs/sdk.commandinfo.usage.md +11 -0
- package/docs/sdk.completeresult.completed.md +11 -0
- package/docs/sdk.completeresult.md +90 -0
- package/docs/sdk.completeresult.taskid.md +11 -0
- package/docs/sdk.completeresult.taskname.md +11 -0
- package/docs/sdk.completetask.md +52 -0
- package/docs/sdk.createerror.md +82 -0
- package/docs/sdk.errorcode.md +24 -0
- package/docs/sdk.escapeapplescript.md +52 -0
- package/docs/sdk.failure.md +52 -0
- package/docs/sdk.failuremessage.md +52 -0
- package/docs/sdk.inboxoptions.defer.md +11 -0
- package/docs/sdk.inboxoptions.due.md +11 -0
- package/docs/sdk.inboxoptions.flag.md +11 -0
- package/docs/sdk.inboxoptions.md +134 -0
- package/docs/sdk.inboxoptions.note.md +11 -0
- package/docs/sdk.inboxoptions.tags.md +11 -0
- package/docs/sdk.jsonhelpers.md +13 -0
- package/docs/sdk.md +471 -0
- package/docs/sdk.ofperspective.id.md +11 -0
- package/docs/sdk.ofperspective.md +73 -0
- package/docs/sdk.ofperspective.name.md +11 -0
- package/docs/sdk.ofproject.folderid.md +11 -0
- package/docs/sdk.ofproject.foldername.md +11 -0
- package/docs/sdk.ofproject.id.md +11 -0
- package/docs/sdk.ofproject.md +192 -0
- package/docs/sdk.ofproject.name.md +11 -0
- package/docs/sdk.ofproject.note.md +11 -0
- package/docs/sdk.ofproject.remainingtaskcount.md +11 -0
- package/docs/sdk.ofproject.sequential.md +11 -0
- package/docs/sdk.ofproject.status.md +11 -0
- package/docs/sdk.ofproject.taskcount.md +11 -0
- package/docs/sdk.oftag.availabletaskcount.md +11 -0
- package/docs/sdk.oftag.id.md +11 -0
- package/docs/sdk.oftag.md +124 -0
- package/docs/sdk.oftag.name.md +11 -0
- package/docs/sdk.oftag.parentid.md +11 -0
- package/docs/sdk.oftag.parentname.md +11 -0
- package/docs/sdk.oftask.completed.md +11 -0
- package/docs/sdk.oftask.completiondate.md +11 -0
- package/docs/sdk.oftask.deferdate.md +11 -0
- package/docs/sdk.oftask.duedate.md +11 -0
- package/docs/sdk.oftask.flagged.md +11 -0
- package/docs/sdk.oftask.id.md +11 -0
- package/docs/sdk.oftask.md +226 -0
- package/docs/sdk.oftask.name.md +11 -0
- package/docs/sdk.oftask.note.md +11 -0
- package/docs/sdk.oftask.projectid.md +11 -0
- package/docs/sdk.oftask.projectname.md +11 -0
- package/docs/sdk.oftask.tags.md +11 -0
- package/docs/sdk.omnifocusscript.md +52 -0
- package/docs/sdk.omnifocusscriptwithhelpers.md +52 -0
- package/docs/sdk.parseapplescripterror.md +52 -0
- package/docs/sdk.projectqueryoptions.folder.md +11 -0
- package/docs/sdk.projectqueryoptions.md +96 -0
- package/docs/sdk.projectqueryoptions.sequential.md +11 -0
- package/docs/sdk.projectqueryoptions.status.md +11 -0
- package/docs/sdk.queryprojects.md +54 -0
- package/docs/sdk.querytags.md +54 -0
- package/docs/sdk.querytasks.md +54 -0
- package/docs/sdk.runapplescript.md +52 -0
- package/docs/sdk.runapplescriptfile.md +68 -0
- package/docs/sdk.success.md +52 -0
- package/docs/sdk.tagqueryoptions.md +58 -0
- package/docs/sdk.tagqueryoptions.parent.md +11 -0
- package/docs/sdk.taskqueryoptions.available.md +11 -0
- package/docs/sdk.taskqueryoptions.completed.md +11 -0
- package/docs/sdk.taskqueryoptions.dueafter.md +11 -0
- package/docs/sdk.taskqueryoptions.duebefore.md +11 -0
- package/docs/sdk.taskqueryoptions.flagged.md +11 -0
- package/docs/sdk.taskqueryoptions.md +172 -0
- package/docs/sdk.taskqueryoptions.project.md +11 -0
- package/docs/sdk.taskqueryoptions.tag.md +11 -0
- package/docs/sdk.taskupdateoptions.defer.md +11 -0
- package/docs/sdk.taskupdateoptions.due.md +11 -0
- package/docs/sdk.taskupdateoptions.flag.md +11 -0
- package/docs/sdk.taskupdateoptions.md +172 -0
- package/docs/sdk.taskupdateoptions.note.md +11 -0
- package/docs/sdk.taskupdateoptions.project.md +11 -0
- package/docs/sdk.taskupdateoptions.tags.md +11 -0
- package/docs/sdk.taskupdateoptions.title.md +11 -0
- package/docs/sdk.updatetask.md +66 -0
- package/docs/sdk.validatedatestring.md +54 -0
- package/docs/sdk.validateid.md +66 -0
- package/docs/sdk.validateprojectname.md +52 -0
- package/docs/sdk.validatetags.md +52 -0
- package/package.json +51 -0
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import { success, failure } from "../result.js";
|
|
2
|
+
import { ErrorCode, createError } from "../errors.js";
|
|
3
|
+
import { validateId, validateDateString, validateTags, validateEstimatedMinutes, validateRepetitionRule, } from "../validation.js";
|
|
4
|
+
import { escapeAppleScript } from "../escape.js";
|
|
5
|
+
import { runAppleScript, omniFocusScriptWithHelpers, } from "../applescript.js";
|
|
6
|
+
import { buildRepetitionRuleScript } from "./repetition.js";
|
|
7
|
+
/**
|
|
8
|
+
* Create a subtask under a parent task in OmniFocus.
|
|
9
|
+
*/
|
|
10
|
+
export async function createSubtask(title, parentTaskId, options = {}) {
|
|
11
|
+
// Validate inputs
|
|
12
|
+
const idError = validateId(parentTaskId, "task");
|
|
13
|
+
if (idError)
|
|
14
|
+
return failure(idError);
|
|
15
|
+
if (!title || title.trim() === "") {
|
|
16
|
+
return failure(createError(ErrorCode.VALIDATION_ERROR, "Task title cannot be empty"));
|
|
17
|
+
}
|
|
18
|
+
if (options.due !== undefined) {
|
|
19
|
+
const dueError = validateDateString(options.due);
|
|
20
|
+
if (dueError)
|
|
21
|
+
return failure(dueError);
|
|
22
|
+
}
|
|
23
|
+
if (options.defer !== undefined) {
|
|
24
|
+
const deferError = validateDateString(options.defer);
|
|
25
|
+
if (deferError)
|
|
26
|
+
return failure(deferError);
|
|
27
|
+
}
|
|
28
|
+
const tagsError = validateTags(options.tags);
|
|
29
|
+
if (tagsError)
|
|
30
|
+
return failure(tagsError);
|
|
31
|
+
const estimateError = validateEstimatedMinutes(options.estimatedMinutes);
|
|
32
|
+
if (estimateError)
|
|
33
|
+
return failure(estimateError);
|
|
34
|
+
const repeatError = validateRepetitionRule(options.repeat);
|
|
35
|
+
if (repeatError)
|
|
36
|
+
return failure(repeatError);
|
|
37
|
+
// Build properties for the new subtask
|
|
38
|
+
const properties = [`name:"${escapeAppleScript(title)}"`];
|
|
39
|
+
if (options.note !== undefined) {
|
|
40
|
+
properties.push(`note:"${escapeAppleScript(options.note)}"`);
|
|
41
|
+
}
|
|
42
|
+
if (options.flag === true) {
|
|
43
|
+
properties.push("flagged:true");
|
|
44
|
+
}
|
|
45
|
+
if (options.due !== undefined) {
|
|
46
|
+
properties.push(`due date:date "${options.due}"`);
|
|
47
|
+
}
|
|
48
|
+
if (options.defer !== undefined) {
|
|
49
|
+
properties.push(`defer date:date "${options.defer}"`);
|
|
50
|
+
}
|
|
51
|
+
if (options.estimatedMinutes !== undefined) {
|
|
52
|
+
properties.push(`estimated minutes:${String(options.estimatedMinutes)}`);
|
|
53
|
+
}
|
|
54
|
+
// Build repetition rule script if provided
|
|
55
|
+
const repetitionScript = options.repeat
|
|
56
|
+
? buildRepetitionRuleScript("newTask", options.repeat)
|
|
57
|
+
: "";
|
|
58
|
+
let tagScript = "";
|
|
59
|
+
if (options.tags && options.tags.length > 0) {
|
|
60
|
+
for (const tagName of options.tags) {
|
|
61
|
+
tagScript += `
|
|
62
|
+
try
|
|
63
|
+
set theTag to first flattened tag whose name is "${escapeAppleScript(tagName)}"
|
|
64
|
+
add theTag to tags of newTask
|
|
65
|
+
end try
|
|
66
|
+
`;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const script = `
|
|
70
|
+
set parentTask to first flattened task whose id is "${escapeAppleScript(parentTaskId)}"
|
|
71
|
+
set newTask to make new task at end of tasks of parentTask with properties {${properties.join(", ")}}
|
|
72
|
+
|
|
73
|
+
${tagScript}
|
|
74
|
+
${repetitionScript}
|
|
75
|
+
|
|
76
|
+
-- Return the created task info
|
|
77
|
+
set taskId to id of newTask
|
|
78
|
+
set taskName to name of newTask
|
|
79
|
+
set taskNote to note of newTask
|
|
80
|
+
set taskFlagged to flagged of newTask
|
|
81
|
+
set taskCompleted to completed of newTask
|
|
82
|
+
|
|
83
|
+
set dueStr to ""
|
|
84
|
+
try
|
|
85
|
+
set dueStr to (due date of newTask) as string
|
|
86
|
+
end try
|
|
87
|
+
|
|
88
|
+
set deferStr to ""
|
|
89
|
+
try
|
|
90
|
+
set deferStr to (defer date of newTask) as string
|
|
91
|
+
end try
|
|
92
|
+
|
|
93
|
+
set projId to ""
|
|
94
|
+
set projName to ""
|
|
95
|
+
try
|
|
96
|
+
set proj to containing project of newTask
|
|
97
|
+
set projId to id of proj
|
|
98
|
+
set projName to name of proj
|
|
99
|
+
end try
|
|
100
|
+
|
|
101
|
+
set tagNames to {}
|
|
102
|
+
repeat with t in tags of newTask
|
|
103
|
+
set end of tagNames to name of t
|
|
104
|
+
end repeat
|
|
105
|
+
|
|
106
|
+
set estMinutes to 0
|
|
107
|
+
try
|
|
108
|
+
set estMinutes to estimated minutes of newTask
|
|
109
|
+
if estMinutes is missing value then set estMinutes to 0
|
|
110
|
+
end try
|
|
111
|
+
|
|
112
|
+
set parentId to ""
|
|
113
|
+
set parentName to ""
|
|
114
|
+
try
|
|
115
|
+
set pTask to container of newTask
|
|
116
|
+
if class of pTask is task then
|
|
117
|
+
set parentId to id of pTask
|
|
118
|
+
set parentName to name of pTask
|
|
119
|
+
end if
|
|
120
|
+
end try
|
|
121
|
+
|
|
122
|
+
set childCount to count of tasks of newTask
|
|
123
|
+
set isGroup to childCount > 0
|
|
124
|
+
|
|
125
|
+
return "{" & ¬
|
|
126
|
+
"\\"id\\": \\"" & taskId & "\\"," & ¬
|
|
127
|
+
"\\"name\\": \\"" & (my escapeJson(taskName)) & "\\"," & ¬
|
|
128
|
+
"\\"note\\": " & (my jsonString(taskNote)) & "," & ¬
|
|
129
|
+
"\\"flagged\\": " & taskFlagged & "," & ¬
|
|
130
|
+
"\\"completed\\": " & taskCompleted & "," & ¬
|
|
131
|
+
"\\"dueDate\\": " & (my jsonString(dueStr)) & "," & ¬
|
|
132
|
+
"\\"deferDate\\": " & (my jsonString(deferStr)) & "," & ¬
|
|
133
|
+
"\\"completionDate\\": null," & ¬
|
|
134
|
+
"\\"projectId\\": " & (my jsonString(projId)) & "," & ¬
|
|
135
|
+
"\\"projectName\\": " & (my jsonString(projName)) & "," & ¬
|
|
136
|
+
"\\"tags\\": " & (my jsonArray(tagNames)) & "," & ¬
|
|
137
|
+
"\\"estimatedMinutes\\": " & estMinutes & "," & ¬
|
|
138
|
+
"\\"parentTaskId\\": " & (my jsonString(parentId)) & "," & ¬
|
|
139
|
+
"\\"parentTaskName\\": " & (my jsonString(parentName)) & "," & ¬
|
|
140
|
+
"\\"childTaskCount\\": " & childCount & "," & ¬
|
|
141
|
+
"\\"isActionGroup\\": " & isGroup & ¬
|
|
142
|
+
"}"
|
|
143
|
+
`;
|
|
144
|
+
const result = await runAppleScript(omniFocusScriptWithHelpers(script));
|
|
145
|
+
if (!result.success) {
|
|
146
|
+
return failure(result.error ??
|
|
147
|
+
createError(ErrorCode.UNKNOWN_ERROR, "Failed to create subtask"));
|
|
148
|
+
}
|
|
149
|
+
if (result.data === undefined) {
|
|
150
|
+
return failure(createError(ErrorCode.UNKNOWN_ERROR, "No task data returned"));
|
|
151
|
+
}
|
|
152
|
+
return success(result.data);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Query subtasks of a parent task in OmniFocus.
|
|
156
|
+
*/
|
|
157
|
+
export async function querySubtasks(parentTaskId, options = {}) {
|
|
158
|
+
// Validate parent task ID
|
|
159
|
+
const idError = validateId(parentTaskId, "task");
|
|
160
|
+
if (idError)
|
|
161
|
+
return failure(idError);
|
|
162
|
+
// Build filter conditions
|
|
163
|
+
const conditions = [];
|
|
164
|
+
if (options.completed === true) {
|
|
165
|
+
conditions.push("completed is true");
|
|
166
|
+
}
|
|
167
|
+
else if (options.completed === false) {
|
|
168
|
+
conditions.push("completed is false");
|
|
169
|
+
}
|
|
170
|
+
if (options.flagged === true) {
|
|
171
|
+
conditions.push("flagged is true");
|
|
172
|
+
}
|
|
173
|
+
else if (options.flagged === false) {
|
|
174
|
+
conditions.push("flagged is false");
|
|
175
|
+
}
|
|
176
|
+
const whereClause = conditions.length > 0 ? ` where ${conditions.join(" and ")}` : "";
|
|
177
|
+
const script = `
|
|
178
|
+
set parentTask to first flattened task whose id is "${escapeAppleScript(parentTaskId)}"
|
|
179
|
+
set output to "["
|
|
180
|
+
set isFirst to true
|
|
181
|
+
|
|
182
|
+
set childTasks to tasks of parentTask${whereClause}
|
|
183
|
+
|
|
184
|
+
repeat with t in childTasks
|
|
185
|
+
if not isFirst then set output to output & ","
|
|
186
|
+
set isFirst to false
|
|
187
|
+
|
|
188
|
+
set taskId to id of t
|
|
189
|
+
set taskName to name of t
|
|
190
|
+
set taskNote to note of t
|
|
191
|
+
set taskFlagged to flagged of t
|
|
192
|
+
set taskCompleted to completed of t
|
|
193
|
+
|
|
194
|
+
set dueStr to ""
|
|
195
|
+
try
|
|
196
|
+
set dueStr to (due date of t) as string
|
|
197
|
+
end try
|
|
198
|
+
|
|
199
|
+
set deferStr to ""
|
|
200
|
+
try
|
|
201
|
+
set deferStr to (defer date of t) as string
|
|
202
|
+
end try
|
|
203
|
+
|
|
204
|
+
set completionStr to ""
|
|
205
|
+
try
|
|
206
|
+
set completionStr to (completion date of t) as string
|
|
207
|
+
end try
|
|
208
|
+
|
|
209
|
+
set projId to ""
|
|
210
|
+
set projName to ""
|
|
211
|
+
try
|
|
212
|
+
set proj to containing project of t
|
|
213
|
+
set projId to id of proj
|
|
214
|
+
set projName to name of proj
|
|
215
|
+
end try
|
|
216
|
+
|
|
217
|
+
set tagNames to {}
|
|
218
|
+
repeat with tg in tags of t
|
|
219
|
+
set end of tagNames to name of tg
|
|
220
|
+
end repeat
|
|
221
|
+
|
|
222
|
+
set estMinutes to 0
|
|
223
|
+
try
|
|
224
|
+
set estMinutes to estimated minutes of t
|
|
225
|
+
if estMinutes is missing value then set estMinutes to 0
|
|
226
|
+
end try
|
|
227
|
+
|
|
228
|
+
set pTaskId to ""
|
|
229
|
+
set pTaskName to ""
|
|
230
|
+
try
|
|
231
|
+
set pTask to container of t
|
|
232
|
+
if class of pTask is task then
|
|
233
|
+
set pTaskId to id of pTask
|
|
234
|
+
set pTaskName to name of pTask
|
|
235
|
+
end if
|
|
236
|
+
end try
|
|
237
|
+
|
|
238
|
+
set childCount to count of tasks of t
|
|
239
|
+
set isGroup to childCount > 0
|
|
240
|
+
|
|
241
|
+
set output to output & "{" & ¬
|
|
242
|
+
"\\"id\\": \\"" & taskId & "\\"," & ¬
|
|
243
|
+
"\\"name\\": \\"" & (my escapeJson(taskName)) & "\\"," & ¬
|
|
244
|
+
"\\"note\\": " & (my jsonString(taskNote)) & "," & ¬
|
|
245
|
+
"\\"flagged\\": " & taskFlagged & "," & ¬
|
|
246
|
+
"\\"completed\\": " & taskCompleted & "," & ¬
|
|
247
|
+
"\\"dueDate\\": " & (my jsonString(dueStr)) & "," & ¬
|
|
248
|
+
"\\"deferDate\\": " & (my jsonString(deferStr)) & "," & ¬
|
|
249
|
+
"\\"completionDate\\": " & (my jsonString(completionStr)) & "," & ¬
|
|
250
|
+
"\\"projectId\\": " & (my jsonString(projId)) & "," & ¬
|
|
251
|
+
"\\"projectName\\": " & (my jsonString(projName)) & "," & ¬
|
|
252
|
+
"\\"tags\\": " & (my jsonArray(tagNames)) & "," & ¬
|
|
253
|
+
"\\"estimatedMinutes\\": " & estMinutes & "," & ¬
|
|
254
|
+
"\\"parentTaskId\\": " & (my jsonString(pTaskId)) & "," & ¬
|
|
255
|
+
"\\"parentTaskName\\": " & (my jsonString(pTaskName)) & "," & ¬
|
|
256
|
+
"\\"childTaskCount\\": " & childCount & "," & ¬
|
|
257
|
+
"\\"isActionGroup\\": " & isGroup & ¬
|
|
258
|
+
"}"
|
|
259
|
+
end repeat
|
|
260
|
+
|
|
261
|
+
return output & "]"
|
|
262
|
+
`;
|
|
263
|
+
const result = await runAppleScript(omniFocusScriptWithHelpers(script));
|
|
264
|
+
if (!result.success) {
|
|
265
|
+
return failure(result.error ??
|
|
266
|
+
createError(ErrorCode.UNKNOWN_ERROR, "Failed to query subtasks"));
|
|
267
|
+
}
|
|
268
|
+
return success(result.data ?? []);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Move a task to become a subtask of another task.
|
|
272
|
+
*/
|
|
273
|
+
export async function moveTaskToParent(taskId, parentTaskId) {
|
|
274
|
+
// Validate task IDs
|
|
275
|
+
const taskIdError = validateId(taskId, "task");
|
|
276
|
+
if (taskIdError)
|
|
277
|
+
return failure(taskIdError);
|
|
278
|
+
const parentIdError = validateId(parentTaskId, "task");
|
|
279
|
+
if (parentIdError)
|
|
280
|
+
return failure(parentIdError);
|
|
281
|
+
const script = `
|
|
282
|
+
set theTask to first flattened task whose id is "${escapeAppleScript(taskId)}"
|
|
283
|
+
set parentTask to first flattened task whose id is "${escapeAppleScript(parentTaskId)}"
|
|
284
|
+
|
|
285
|
+
move theTask to end of tasks of parentTask
|
|
286
|
+
|
|
287
|
+
-- Return updated task info
|
|
288
|
+
set taskId to id of theTask
|
|
289
|
+
set taskName to name of theTask
|
|
290
|
+
set taskNote to note of theTask
|
|
291
|
+
set taskFlagged to flagged of theTask
|
|
292
|
+
set taskCompleted to completed of theTask
|
|
293
|
+
|
|
294
|
+
set dueStr to ""
|
|
295
|
+
try
|
|
296
|
+
set dueStr to (due date of theTask) as string
|
|
297
|
+
end try
|
|
298
|
+
|
|
299
|
+
set deferStr to ""
|
|
300
|
+
try
|
|
301
|
+
set deferStr to (defer date of theTask) as string
|
|
302
|
+
end try
|
|
303
|
+
|
|
304
|
+
set completionStr to ""
|
|
305
|
+
try
|
|
306
|
+
set completionStr to (completion date of theTask) as string
|
|
307
|
+
end try
|
|
308
|
+
|
|
309
|
+
set projId to ""
|
|
310
|
+
set projName to ""
|
|
311
|
+
try
|
|
312
|
+
set proj to containing project of theTask
|
|
313
|
+
set projId to id of proj
|
|
314
|
+
set projName to name of proj
|
|
315
|
+
end try
|
|
316
|
+
|
|
317
|
+
set tagNames to {}
|
|
318
|
+
repeat with t in tags of theTask
|
|
319
|
+
set end of tagNames to name of t
|
|
320
|
+
end repeat
|
|
321
|
+
|
|
322
|
+
set estMinutes to 0
|
|
323
|
+
try
|
|
324
|
+
set estMinutes to estimated minutes of theTask
|
|
325
|
+
if estMinutes is missing value then set estMinutes to 0
|
|
326
|
+
end try
|
|
327
|
+
|
|
328
|
+
set pTaskId to ""
|
|
329
|
+
set pTaskName to ""
|
|
330
|
+
try
|
|
331
|
+
set pTask to container of theTask
|
|
332
|
+
if class of pTask is task then
|
|
333
|
+
set pTaskId to id of pTask
|
|
334
|
+
set pTaskName to name of pTask
|
|
335
|
+
end if
|
|
336
|
+
end try
|
|
337
|
+
|
|
338
|
+
set childCount to count of tasks of theTask
|
|
339
|
+
set isGroup to childCount > 0
|
|
340
|
+
|
|
341
|
+
return "{" & ¬
|
|
342
|
+
"\\"id\\": \\"" & taskId & "\\"," & ¬
|
|
343
|
+
"\\"name\\": \\"" & (my escapeJson(taskName)) & "\\"," & ¬
|
|
344
|
+
"\\"note\\": " & (my jsonString(taskNote)) & "," & ¬
|
|
345
|
+
"\\"flagged\\": " & taskFlagged & "," & ¬
|
|
346
|
+
"\\"completed\\": " & taskCompleted & "," & ¬
|
|
347
|
+
"\\"dueDate\\": " & (my jsonString(dueStr)) & "," & ¬
|
|
348
|
+
"\\"deferDate\\": " & (my jsonString(deferStr)) & "," & ¬
|
|
349
|
+
"\\"completionDate\\": " & (my jsonString(completionStr)) & "," & ¬
|
|
350
|
+
"\\"projectId\\": " & (my jsonString(projId)) & "," & ¬
|
|
351
|
+
"\\"projectName\\": " & (my jsonString(projName)) & "," & ¬
|
|
352
|
+
"\\"tags\\": " & (my jsonArray(tagNames)) & "," & ¬
|
|
353
|
+
"\\"estimatedMinutes\\": " & estMinutes & "," & ¬
|
|
354
|
+
"\\"parentTaskId\\": " & (my jsonString(pTaskId)) & "," & ¬
|
|
355
|
+
"\\"parentTaskName\\": " & (my jsonString(pTaskName)) & "," & ¬
|
|
356
|
+
"\\"childTaskCount\\": " & childCount & "," & ¬
|
|
357
|
+
"\\"isActionGroup\\": " & isGroup & ¬
|
|
358
|
+
"}"
|
|
359
|
+
`;
|
|
360
|
+
const result = await runAppleScript(omniFocusScriptWithHelpers(script));
|
|
361
|
+
if (!result.success) {
|
|
362
|
+
return failure(result.error ??
|
|
363
|
+
createError(ErrorCode.UNKNOWN_ERROR, "Failed to move task"));
|
|
364
|
+
}
|
|
365
|
+
if (result.data === undefined) {
|
|
366
|
+
return failure(createError(ErrorCode.UNKNOWN_ERROR, "No task data returned"));
|
|
367
|
+
}
|
|
368
|
+
return success(result.data);
|
|
369
|
+
}
|
|
370
|
+
//# sourceMappingURL=subtasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subtasks.js","sourceRoot":"","sources":["../../src/commands/subtasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CliOutput, CreateTagOptions, UpdateTagOptions, OFTag } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Result from deleting a tag.
|
|
4
|
+
*/
|
|
5
|
+
export interface DeleteTagResult {
|
|
6
|
+
tagId: string;
|
|
7
|
+
deleted: true;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create a new tag in OmniFocus.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createTag(name: string, options?: CreateTagOptions): Promise<CliOutput<OFTag>>;
|
|
13
|
+
/**
|
|
14
|
+
* Update an existing tag in OmniFocus.
|
|
15
|
+
*/
|
|
16
|
+
export declare function updateTag(tagId: string, options: UpdateTagOptions): Promise<CliOutput<OFTag>>;
|
|
17
|
+
/**
|
|
18
|
+
* Delete a tag from OmniFocus.
|
|
19
|
+
* Note: This cannot be undone.
|
|
20
|
+
*/
|
|
21
|
+
export declare function deleteTag(tagId: string): Promise<CliOutput<DeleteTagResult>>;
|
|
22
|
+
//# sourceMappingURL=tags-crud.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags-crud.d.ts","sourceRoot":"","sources":["../../src/commands/tags-crud.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,EACN,MAAM,aAAa,CAAC;AAUrB;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CA8E3B;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CA6F3B;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CA4BrC"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { success, failure } from "../result.js";
|
|
2
|
+
import { ErrorCode, createError } from "../errors.js";
|
|
3
|
+
import { validateId, validateTagName } from "../validation.js";
|
|
4
|
+
import { escapeAppleScript } from "../escape.js";
|
|
5
|
+
import { runAppleScript, omniFocusScriptWithHelpers, } from "../applescript.js";
|
|
6
|
+
/**
|
|
7
|
+
* Create a new tag in OmniFocus.
|
|
8
|
+
*/
|
|
9
|
+
export async function createTag(name, options = {}) {
|
|
10
|
+
// Validate tag name (required for create)
|
|
11
|
+
const nameError = validateTagName(name);
|
|
12
|
+
if (nameError)
|
|
13
|
+
return failure(nameError);
|
|
14
|
+
// Validate optional inputs
|
|
15
|
+
if (options.parentTagId !== undefined) {
|
|
16
|
+
const parentIdError = validateId(options.parentTagId, "tag");
|
|
17
|
+
if (parentIdError)
|
|
18
|
+
return failure(parentIdError);
|
|
19
|
+
}
|
|
20
|
+
if (options.parentTagName !== undefined) {
|
|
21
|
+
const parentNameError = validateTagName(options.parentTagName);
|
|
22
|
+
if (parentNameError)
|
|
23
|
+
return failure(parentNameError);
|
|
24
|
+
}
|
|
25
|
+
// Build script based on whether we're placing under a parent tag
|
|
26
|
+
let findParent = "";
|
|
27
|
+
let makeTag = "";
|
|
28
|
+
if (options.parentTagId) {
|
|
29
|
+
findParent = `set parentTag to first flattened tag whose id is "${escapeAppleScript(options.parentTagId)}"`;
|
|
30
|
+
makeTag = `set newTag to make new tag at end of tags of parentTag with properties {name:"${escapeAppleScript(name)}"}`;
|
|
31
|
+
}
|
|
32
|
+
else if (options.parentTagName) {
|
|
33
|
+
findParent = `set parentTag to first flattened tag whose name is "${escapeAppleScript(options.parentTagName)}"`;
|
|
34
|
+
makeTag = `set newTag to make new tag at end of tags of parentTag with properties {name:"${escapeAppleScript(name)}"}`;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
findParent = "";
|
|
38
|
+
makeTag = `set newTag to make new tag with properties {name:"${escapeAppleScript(name)}"}`;
|
|
39
|
+
}
|
|
40
|
+
const script = `
|
|
41
|
+
${findParent}
|
|
42
|
+
${makeTag}
|
|
43
|
+
|
|
44
|
+
-- Return the created tag info
|
|
45
|
+
set tagId to id of newTag
|
|
46
|
+
set tagName to name of newTag
|
|
47
|
+
|
|
48
|
+
set parentId to ""
|
|
49
|
+
set parentName to ""
|
|
50
|
+
try
|
|
51
|
+
set p to container of newTag
|
|
52
|
+
if class of p is tag then
|
|
53
|
+
set parentId to id of p
|
|
54
|
+
set parentName to name of p
|
|
55
|
+
end if
|
|
56
|
+
end try
|
|
57
|
+
|
|
58
|
+
set availCount to count of (flattened tasks whose primary tag is newTag and completed is false)
|
|
59
|
+
|
|
60
|
+
return "{" & ¬
|
|
61
|
+
"\\"id\\": \\"" & tagId & "\\"," & ¬
|
|
62
|
+
"\\"name\\": \\"" & (my escapeJson(tagName)) & "\\"," & ¬
|
|
63
|
+
"\\"parentId\\": " & (my jsonString(parentId)) & "," & ¬
|
|
64
|
+
"\\"parentName\\": " & (my jsonString(parentName)) & "," & ¬
|
|
65
|
+
"\\"availableTaskCount\\": " & availCount & ¬
|
|
66
|
+
"}"
|
|
67
|
+
`;
|
|
68
|
+
const result = await runAppleScript(omniFocusScriptWithHelpers(script));
|
|
69
|
+
if (!result.success) {
|
|
70
|
+
return failure(result.error ??
|
|
71
|
+
createError(ErrorCode.UNKNOWN_ERROR, "Failed to create tag"));
|
|
72
|
+
}
|
|
73
|
+
if (result.data === undefined) {
|
|
74
|
+
return failure(createError(ErrorCode.UNKNOWN_ERROR, "No tag data returned"));
|
|
75
|
+
}
|
|
76
|
+
return success(result.data);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Update an existing tag in OmniFocus.
|
|
80
|
+
*/
|
|
81
|
+
export async function updateTag(tagId, options) {
|
|
82
|
+
// Validate tag ID
|
|
83
|
+
const idError = validateId(tagId, "tag");
|
|
84
|
+
if (idError)
|
|
85
|
+
return failure(idError);
|
|
86
|
+
// Validate optional inputs
|
|
87
|
+
if (options.name !== undefined) {
|
|
88
|
+
const nameError = validateTagName(options.name);
|
|
89
|
+
if (nameError)
|
|
90
|
+
return failure(nameError);
|
|
91
|
+
}
|
|
92
|
+
if (options.parentTagId !== undefined) {
|
|
93
|
+
const parentIdError = validateId(options.parentTagId, "tag");
|
|
94
|
+
if (parentIdError)
|
|
95
|
+
return failure(parentIdError);
|
|
96
|
+
}
|
|
97
|
+
if (options.parentTagName !== undefined) {
|
|
98
|
+
const parentNameError = validateTagName(options.parentTagName);
|
|
99
|
+
if (parentNameError)
|
|
100
|
+
return failure(parentNameError);
|
|
101
|
+
}
|
|
102
|
+
// Build the update statements
|
|
103
|
+
const updates = [];
|
|
104
|
+
if (options.name !== undefined) {
|
|
105
|
+
updates.push(`set name of theTag to "${escapeAppleScript(options.name)}"`);
|
|
106
|
+
}
|
|
107
|
+
// Handle reparenting
|
|
108
|
+
let reparentScript = "";
|
|
109
|
+
if (options.parentTagId !== undefined) {
|
|
110
|
+
reparentScript = `
|
|
111
|
+
set newParent to first flattened tag whose id is "${escapeAppleScript(options.parentTagId)}"
|
|
112
|
+
move theTag to end of tags of newParent
|
|
113
|
+
`;
|
|
114
|
+
}
|
|
115
|
+
else if (options.parentTagName !== undefined) {
|
|
116
|
+
reparentScript = `
|
|
117
|
+
set newParent to first flattened tag whose name is "${escapeAppleScript(options.parentTagName)}"
|
|
118
|
+
move theTag to end of tags of newParent
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
const updateScript = updates.join("\n ");
|
|
122
|
+
const script = `
|
|
123
|
+
set theTag to first flattened tag whose id is "${escapeAppleScript(tagId)}"
|
|
124
|
+
|
|
125
|
+
${updateScript}
|
|
126
|
+
${reparentScript}
|
|
127
|
+
|
|
128
|
+
-- Return updated tag info
|
|
129
|
+
set tagId to id of theTag
|
|
130
|
+
set tagName to name of theTag
|
|
131
|
+
|
|
132
|
+
set parentId to ""
|
|
133
|
+
set parentName to ""
|
|
134
|
+
try
|
|
135
|
+
set p to container of theTag
|
|
136
|
+
if class of p is tag then
|
|
137
|
+
set parentId to id of p
|
|
138
|
+
set parentName to name of p
|
|
139
|
+
end if
|
|
140
|
+
end try
|
|
141
|
+
|
|
142
|
+
set availCount to count of (flattened tasks whose primary tag is theTag and completed is false)
|
|
143
|
+
|
|
144
|
+
return "{" & ¬
|
|
145
|
+
"\\"id\\": \\"" & tagId & "\\"," & ¬
|
|
146
|
+
"\\"name\\": \\"" & (my escapeJson(tagName)) & "\\"," & ¬
|
|
147
|
+
"\\"parentId\\": " & (my jsonString(parentId)) & "," & ¬
|
|
148
|
+
"\\"parentName\\": " & (my jsonString(parentName)) & "," & ¬
|
|
149
|
+
"\\"availableTaskCount\\": " & availCount & ¬
|
|
150
|
+
"}"
|
|
151
|
+
`;
|
|
152
|
+
const result = await runAppleScript(omniFocusScriptWithHelpers(script));
|
|
153
|
+
if (!result.success) {
|
|
154
|
+
return failure(result.error ??
|
|
155
|
+
createError(ErrorCode.UNKNOWN_ERROR, "Failed to update tag"));
|
|
156
|
+
}
|
|
157
|
+
if (result.data === undefined) {
|
|
158
|
+
return failure(createError(ErrorCode.UNKNOWN_ERROR, "No tag data returned"));
|
|
159
|
+
}
|
|
160
|
+
return success(result.data);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Delete a tag from OmniFocus.
|
|
164
|
+
* Note: This cannot be undone.
|
|
165
|
+
*/
|
|
166
|
+
export async function deleteTag(tagId) {
|
|
167
|
+
// Validate tag ID
|
|
168
|
+
const idError = validateId(tagId, "tag");
|
|
169
|
+
if (idError)
|
|
170
|
+
return failure(idError);
|
|
171
|
+
const script = `
|
|
172
|
+
set theTag to first flattened tag whose id is "${escapeAppleScript(tagId)}"
|
|
173
|
+
delete theTag
|
|
174
|
+
|
|
175
|
+
return "{\\"tagId\\": \\"${escapeAppleScript(tagId)}\\", \\"deleted\\": true}"
|
|
176
|
+
`;
|
|
177
|
+
const result = await runAppleScript(omniFocusScriptWithHelpers(script));
|
|
178
|
+
if (!result.success) {
|
|
179
|
+
return failure(result.error ??
|
|
180
|
+
createError(ErrorCode.UNKNOWN_ERROR, "Failed to delete tag"));
|
|
181
|
+
}
|
|
182
|
+
if (result.data === undefined) {
|
|
183
|
+
return failure(createError(ErrorCode.UNKNOWN_ERROR, "No result returned"));
|
|
184
|
+
}
|
|
185
|
+
return success(result.data);
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=tags-crud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags-crud.js","sourceRoot":"","sources":["../../src/commands/tags-crud.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../src/commands/tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AASrE;;GAEG;AACH,wBAAsB,SAAS,CAC7B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CA2D7B"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { success, failure } from "../result.js";
|
|
2
|
+
import { ErrorCode, createError } from "../errors.js";
|
|
3
|
+
import { escapeAppleScript } from "../escape.js";
|
|
4
|
+
import { runAppleScript, omniFocusScriptWithHelpers, } from "../applescript.js";
|
|
5
|
+
/**
|
|
6
|
+
* Query tags from OmniFocus with optional filters.
|
|
7
|
+
*/
|
|
8
|
+
export async function queryTags(options = {}) {
|
|
9
|
+
const script = `
|
|
10
|
+
set output to "["
|
|
11
|
+
set isFirst to true
|
|
12
|
+
|
|
13
|
+
set allTags to flattened tags
|
|
14
|
+
|
|
15
|
+
repeat with theTag in allTags
|
|
16
|
+
${options.parent ? `set parentMatch to false` : ""}
|
|
17
|
+
${options.parent ? `try` : ""}
|
|
18
|
+
${options.parent ? ` set theContainer to container of theTag` : ""}
|
|
19
|
+
${options.parent ? ` if name of theContainer is "${escapeAppleScript(options.parent)}" then set parentMatch to true` : ""}
|
|
20
|
+
${options.parent ? `end try` : ""}
|
|
21
|
+
${options.parent ? `if parentMatch then` : ""}
|
|
22
|
+
|
|
23
|
+
if not isFirst then set output to output & ","
|
|
24
|
+
set isFirst to false
|
|
25
|
+
|
|
26
|
+
set tagId to id of theTag
|
|
27
|
+
set tagName to name of theTag
|
|
28
|
+
|
|
29
|
+
set parentId to ""
|
|
30
|
+
set parentName to ""
|
|
31
|
+
try
|
|
32
|
+
set theContainer to container of theTag
|
|
33
|
+
set parentId to id of theContainer
|
|
34
|
+
set parentName to name of theContainer
|
|
35
|
+
on error
|
|
36
|
+
-- No parent or container is not a tag
|
|
37
|
+
end try
|
|
38
|
+
|
|
39
|
+
set availCount to count of (available tasks of theTag)
|
|
40
|
+
|
|
41
|
+
set output to output & "{" & ¬
|
|
42
|
+
"\\"id\\": \\"" & tagId & "\\"," & ¬
|
|
43
|
+
"\\"name\\": \\"" & (my escapeJson(tagName)) & "\\"," & ¬
|
|
44
|
+
"\\"parentId\\": " & (my jsonString(parentId)) & "," & ¬
|
|
45
|
+
"\\"parentName\\": " & (my jsonString(parentName)) & "," & ¬
|
|
46
|
+
"\\"availableTaskCount\\": " & availCount & ¬
|
|
47
|
+
"}"
|
|
48
|
+
|
|
49
|
+
${options.parent ? "end if" : ""}
|
|
50
|
+
end repeat
|
|
51
|
+
|
|
52
|
+
return output & "]"
|
|
53
|
+
`;
|
|
54
|
+
const result = await runAppleScript(omniFocusScriptWithHelpers(script));
|
|
55
|
+
if (!result.success) {
|
|
56
|
+
return failure(result.error ??
|
|
57
|
+
createError(ErrorCode.UNKNOWN_ERROR, "Failed to query tags"));
|
|
58
|
+
}
|
|
59
|
+
return success(result.data ?? []);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=tags.js.map
|