gmailer 0.0.5
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.
- data/CHANGES +20 -0
- data/MANIFEST +6 -0
- data/README +513 -0
- metadata +42 -0
data/CHANGES
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
== 0.0.5 - 28-Aug-2005
|
2
|
+
* add edit label mothods
|
3
|
+
* add edit preference method
|
4
|
+
* fix some bugs
|
5
|
+
|
6
|
+
== 0.0.4 - 26-Aug-2005
|
7
|
+
* remove camelCase methods
|
8
|
+
* fix some bugs
|
9
|
+
* modify some key name
|
10
|
+
|
11
|
+
== 0.0.3 - 25-Aug-2005
|
12
|
+
* add some methods
|
13
|
+
* add support for proxy
|
14
|
+
|
15
|
+
== 0.0.2 - 20-Aug-2005
|
16
|
+
* add some methods
|
17
|
+
* make more compact and simple
|
18
|
+
|
19
|
+
== 0.0.1 - 17-Aug-2005
|
20
|
+
* Initial release
|
data/MANIFEST
ADDED
data/README
ADDED
@@ -0,0 +1,513 @@
|
|
1
|
+
== Description
|
2
|
+
A class for interface to Google's webmail service
|
3
|
+
|
4
|
+
|
5
|
+
== Synopsis
|
6
|
+
==== A typical code sequence for fetching gmails
|
7
|
+
|
8
|
+
gmail = GMailer.new
|
9
|
+
gmail.set_login_info(name, pwd)
|
10
|
+
if gmail.connect
|
11
|
+
gmail.fetch_box(GM_LABEL, "my_label", 0)
|
12
|
+
snapshot = gmail.get_snapshot(GM_LABEL)
|
13
|
+
if snapshot
|
14
|
+
puts "Total # of conversations of my_label = " + snapshot.box_total.to_s
|
15
|
+
end
|
16
|
+
gmail.disconnect
|
17
|
+
end
|
18
|
+
|
19
|
+
Or more simpler
|
20
|
+
|
21
|
+
GMailer.connect(name, pwd) do |gmail|
|
22
|
+
snapshot = gmail.fetch_box(GM_LABEL, "my_label", 0)
|
23
|
+
if snapshot
|
24
|
+
puts "Total # of conversations of my_label = " + snapshot.box_total.to_s
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Or even
|
29
|
+
|
30
|
+
GMailer.connect(name, pwd) do |g|
|
31
|
+
g.fetch(:label=>"my_label") {|snapshot|
|
32
|
+
puts "Total # of conversations of my_label = " + snapshot.box_total.to_s
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
=== Sending new gmails with gmailer
|
38
|
+
|
39
|
+
gmail = GMailer.new
|
40
|
+
gmail.set_login_info(name, pwd)
|
41
|
+
if gmail.connect
|
42
|
+
to = "who@what.com, my_friend@his_company.com, god@heaven.org"
|
43
|
+
cc = "foo@bar.com"
|
44
|
+
subject = "Hello There!"
|
45
|
+
message = "Hi...\n\nBlah blah blah~..."
|
46
|
+
attachments = ["./my_pic.jpg", "./my_cv.txt"]
|
47
|
+
gmail.send(to, subject, message, cc, '','', '', attachments, false, '')
|
48
|
+
end
|
49
|
+
|
50
|
+
Or shorter
|
51
|
+
|
52
|
+
GMailer.connect(name, pwd) do |g|
|
53
|
+
g.send(
|
54
|
+
:to => "who@what.com, my_friend@his_company.com, god@heaven.org"
|
55
|
+
:cc => "foo@bar.com"
|
56
|
+
:subject => "Hello There!",
|
57
|
+
:body => "Hi...\n\nBlah blah blah~...",
|
58
|
+
:files => ["./my_pic.jpg", "./my_cv.txt"])
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
=== Playing around with contact list
|
63
|
+
|
64
|
+
gmail = GMailer.new
|
65
|
+
gmail.set_login_info(name, pwd)
|
66
|
+
if gmail.connect
|
67
|
+
gmail.fetch_box(GM_CONTACT, "freq", 0)
|
68
|
+
snapshot = gmail.get_snapshot(GM_CONTACT)
|
69
|
+
puts "Your frequently used addresses:"
|
70
|
+
snapshot.contacts.each { |item|
|
71
|
+
puts "Name: " + item["name"] + ", Email: " + item["email"]
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
Or shorter
|
76
|
+
|
77
|
+
GMailer.connect(name, pwd) do |g|
|
78
|
+
puts "Your frequently used addresses:"
|
79
|
+
g.fetch(:contact=>"freq").each do |item|
|
80
|
+
puts "Name: #{item['name']} Email: #{item['email']}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
=== Get list of labels and get list of messages
|
85
|
+
|
86
|
+
GMailer.connect(:username=>name,:password=>pwd) do |g|
|
87
|
+
labels = g.get_labels
|
88
|
+
g.get_messages(:label=>labels[0]).each {|m|
|
89
|
+
puts "Subject: #{m['subject']} / Snippet: #{m['snippet']}" if m['new?']
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
=== Edit labels
|
94
|
+
|
95
|
+
GMailer.connect(:username=>name,:password=>pwd) do |g|
|
96
|
+
#creating new labels
|
97
|
+
g.create_label('label_name')
|
98
|
+
|
99
|
+
#renaming existing labels
|
100
|
+
g.rename_label('label_name','renamed_label')
|
101
|
+
|
102
|
+
#deleting labels
|
103
|
+
g.delete_label('label_name')
|
104
|
+
|
105
|
+
#applying a label to a message
|
106
|
+
g.apply_label(msgid,'label_name')
|
107
|
+
|
108
|
+
#removing a label from a message
|
109
|
+
g.remove_label(msgid,'label_name')
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
=== Update preferece
|
114
|
+
|
115
|
+
GMailer.connect(:username=>name,:password=>pwd) do |g|
|
116
|
+
g.update_preference(:max_page_size=>50,
|
117
|
+
:keyboard_shortcuts=>true,
|
118
|
+
:indicators=>true,
|
119
|
+
:display_language=>'en',
|
120
|
+
:signature=>'This is a signature',
|
121
|
+
:reply_to=>'return@foo.bar',
|
122
|
+
:snippets=>true,
|
123
|
+
:display_name=>'Display Name')
|
124
|
+
pref = g.get_preference
|
125
|
+
puts "Display language:#{pref['display_language']}, Max Page Size:#{pref['max_page_size']}"
|
126
|
+
end
|
127
|
+
|
128
|
+
== Class Methods
|
129
|
+
GMailer.new(charset='UTF-8')
|
130
|
+
Returns a new GMailer object and set up charset.
|
131
|
+
|
132
|
+
GMailer.new(name,pwd,charset='UTF-8')
|
133
|
+
Returns a new GMailer object and set up login information and charset.
|
134
|
+
|
135
|
+
== Instance Methods
|
136
|
+
set_login_Info(name, password, GMT_timezone=0)
|
137
|
+
To set the login information before connect.
|
138
|
+
|
139
|
+
connect()
|
140
|
+
To connect to GMail. It returns 1 if succeed, 0 otherwise.
|
141
|
+
|
142
|
+
connect(name,pwd,charset='UTF-8')
|
143
|
+
Returns a new GMailer object and set up login information and charset.
|
144
|
+
and connect to GMail.
|
145
|
+
|
146
|
+
connect(connet hash)
|
147
|
+
Returns a new GMailer object and set up login information and charset.
|
148
|
+
and proxy connect to GMail. proxy_port, proxy_user, proxy_pass can be omitted.
|
149
|
+
key - type simbol. One of :username,:password,:charset,:proxy_host,:proxy_user,:proxy_pass
|
150
|
+
value - each value of type
|
151
|
+
e.g. connect(:username=>'user',:password=>'pass',:proxy_host=>'proxy-host',
|
152
|
+
:proxy_port=>8080,:proxy_user=>'proxy_user',:proxy_pass=>'proxy_pass')
|
153
|
+
|
154
|
+
is_connected()
|
155
|
+
To check if connected.
|
156
|
+
|
157
|
+
fetch(action hash)
|
158
|
+
To fetch a result from GMail by given hash type=>box
|
159
|
+
key - type: symbol. One of :label,:standard,:conversation,:preference,:contact,:preference,:pos
|
160
|
+
value - box : name of "box" (e.g. Inbox, your_label, "all"/"freq" of contacts)
|
161
|
+
or position: cursor for paged result. used
|
162
|
+
e.g. fetch(:label=>'my_label',pos=>0)
|
163
|
+
It returns contact list in case key is :contact else returns sanpshot object
|
164
|
+
|
165
|
+
fetch_box(type,box,position)
|
166
|
+
To fetch a result from GMail by given:
|
167
|
+
type: Gmailer constant, e.g. GM_LABEL.
|
168
|
+
box: name of "box" (e.g. Inbox, your_label, "all"/"freq" of contacts)
|
169
|
+
position: cursor for paged result.
|
170
|
+
|
171
|
+
get_snapshot(type)
|
172
|
+
To get a "snapshot", an object (see GMailSnapshot below) for you to
|
173
|
+
access query result at ease.
|
174
|
+
|
175
|
+
get_labels()
|
176
|
+
To get list of labels.
|
177
|
+
|
178
|
+
get_preference()
|
179
|
+
To get hash of preference setting.
|
180
|
+
|
181
|
+
get_messages()
|
182
|
+
To get list of messages.
|
183
|
+
|
184
|
+
get_attachment(attachment_id,message_id,filename,zipped)
|
185
|
+
To download an attachment of a message. If zipped is true, download ALL
|
186
|
+
attachements of message_id in a zip file.
|
187
|
+
|
188
|
+
get_attachments_of(conv, path_to_store_files)
|
189
|
+
To download ALL files attached to a conversation. The full path of
|
190
|
+
downloaded files will be returned (as array).
|
191
|
+
|
192
|
+
create_label(label)
|
193
|
+
To create new label
|
194
|
+
|
195
|
+
rename_label(old_label,new_label)
|
196
|
+
To rename old_label to new_label
|
197
|
+
|
198
|
+
delete_label(label)
|
199
|
+
To delete a label
|
200
|
+
|
201
|
+
apply_label(msgid,label)
|
202
|
+
To apply a label to a message
|
203
|
+
|
204
|
+
remove_label(msgid,label)
|
205
|
+
To remove a label to a message
|
206
|
+
|
207
|
+
update_preference(preference hash)
|
208
|
+
To update preference setting
|
209
|
+
hash is one of :max_page_size(25,50,100),:keyboard_shortcuts(true,false),:indicators(true,false),
|
210
|
+
:display_language(two letter country code like 'en','ja','ko'...),:signature,:reply_to,
|
211
|
+
:snippets(true,false),:display_name
|
212
|
+
e.g update_preference(:max_page_size=>100,:display_language=>'en')
|
213
|
+
|
214
|
+
send(to,subject,body,cc,bcc,message_replying,thread_replying,attachments,draft_saving,draft_id)
|
215
|
+
To send gmail or save drafts. to, cc and bcc are comma-separated addresses.
|
216
|
+
attachments is an array of names of files to be attached.
|
217
|
+
|
218
|
+
send(hash argument)
|
219
|
+
To send gmail or save drafts. to, cc and bcc are comma-separated addresses.
|
220
|
+
attachments is an array of names of files to be attached. e.g
|
221
|
+
send(:to => "who@foo.bar" ,
|
222
|
+
:subject => "Hello There!",
|
223
|
+
:body => "Hi...\n\nBlah blah blah~...",
|
224
|
+
:files => ["./test.txt"])
|
225
|
+
|
226
|
+
perform_action(action_type,message_id,label)
|
227
|
+
To perform action on message. message_id can be a string if only one message
|
228
|
+
to be acted.
|
229
|
+
|
230
|
+
disconnect()
|
231
|
+
To disconnect from gmail.
|
232
|
+
|
233
|
+
dump(query)
|
234
|
+
To dump ALL it gets from URL query string, including headers.
|
235
|
+
|
236
|
+
get_standard_box()
|
237
|
+
To get an array of names of the "standard box" (Inbox, Starred, etc.)
|
238
|
+
|
239
|
+
invite(email)
|
240
|
+
To send invite to email.
|
241
|
+
|
242
|
+
|
243
|
+
== Constants
|
244
|
+
|
245
|
+
GM_STANDARD
|
246
|
+
All about "Standard Box" (Inbox, Sent, All, Starred, Spam, Trash).
|
247
|
+
|
248
|
+
GM_LABEL
|
249
|
+
All about labels.
|
250
|
+
|
251
|
+
GM_CONVERSATION
|
252
|
+
All about conversation.
|
253
|
+
|
254
|
+
GM_QUERY
|
255
|
+
All about search query.
|
256
|
+
|
257
|
+
GM_CONTACT
|
258
|
+
All about contact list.
|
259
|
+
|
260
|
+
GM_ACT_APPLYLABEL
|
261
|
+
GM_ACT_REMOVELABEL
|
262
|
+
Apply/remove label from message.
|
263
|
+
|
264
|
+
GM_ACT_STAR
|
265
|
+
GM_ACT_UNSTAR
|
266
|
+
Star/unstar a message.
|
267
|
+
|
268
|
+
GM_ACT_SPAM
|
269
|
+
GM_ACT_UNSPAM
|
270
|
+
Mark/unmark message as spam.
|
271
|
+
|
272
|
+
GM_ACT_READ
|
273
|
+
GM_ACT_UNREAD
|
274
|
+
Mark message as read/unread.
|
275
|
+
|
276
|
+
GM_ACT_ARCHIVE
|
277
|
+
GM_ACT_INBOX
|
278
|
+
Move message away from/to Inbox.
|
279
|
+
|
280
|
+
GM_ACT_TRASH
|
281
|
+
GM_ACT_UNTRASH
|
282
|
+
Move message to/away from Trash.
|
283
|
+
|
284
|
+
GM_ACT_DELFOREVER
|
285
|
+
Delete message forever.
|
286
|
+
|
287
|
+
GM_ACT_UNDRAFT
|
288
|
+
Discard a draft.
|
289
|
+
|
290
|
+
GM_ACT_TRASHMSG
|
291
|
+
Trash an individual message (not entire conversation).
|
292
|
+
|
293
|
+
GM_ACT_DELSPAM
|
294
|
+
Delete (forever) a spam.
|
295
|
+
|
296
|
+
GM_ACT_DELTRASHED
|
297
|
+
Delete (forever) a conversation in Trash.
|
298
|
+
|
299
|
+
=== Standard constants
|
300
|
+
VERSION
|
301
|
+
Returns the current version number of this package as a String.
|
302
|
+
|
303
|
+
== Instance variables available to snapshot type: all except GM_CONTACT
|
304
|
+
gmail_ver
|
305
|
+
Version of GMail javascript core program
|
306
|
+
|
307
|
+
quota_mb
|
308
|
+
Mailbox quota in MB
|
309
|
+
|
310
|
+
quota_per
|
311
|
+
Mailbox quota in percentage
|
312
|
+
|
313
|
+
std_box_new
|
314
|
+
An array of conversations. Number of unread mails in each standard boxes.
|
315
|
+
You may call GMailer::getStandardBox() to get an array of names of standard boxes.
|
316
|
+
|
317
|
+
have_invit
|
318
|
+
Number of invites you have. 0 = no invitation, etc.
|
319
|
+
|
320
|
+
label_list
|
321
|
+
An array of label names.
|
322
|
+
|
323
|
+
label_new
|
324
|
+
An array of label names. Number of unread mails in each labels.
|
325
|
+
|
326
|
+
== Instance variables available to snapshot type: GM_STANDARD, GM_LABEL, GM_QUERY
|
327
|
+
box_name
|
328
|
+
Name of the standard box/label or query string currently viewing.
|
329
|
+
|
330
|
+
box_total
|
331
|
+
Total number of conversations in current mailbox.
|
332
|
+
|
333
|
+
box_pos
|
334
|
+
Current starting position (for paged results).
|
335
|
+
|
336
|
+
box
|
337
|
+
An array of conversations in current mailbox.
|
338
|
+
|
339
|
+
=== keys of each conversation
|
340
|
+
id
|
341
|
+
Conversation ID
|
342
|
+
|
343
|
+
is_read
|
344
|
+
0 = read; 1 = not read yet.
|
345
|
+
|
346
|
+
new?
|
347
|
+
false = read; true = not read yet.
|
348
|
+
|
349
|
+
is_starred
|
350
|
+
0 = not starred; 1 = starred.
|
351
|
+
|
352
|
+
star?
|
353
|
+
false = not starred; true = starred.
|
354
|
+
|
355
|
+
date
|
356
|
+
Arrival date/time of the most recent message.
|
357
|
+
|
358
|
+
sender
|
359
|
+
Senders of message in this conversation.
|
360
|
+
|
361
|
+
flag
|
362
|
+
Flag.
|
363
|
+
|
364
|
+
subject
|
365
|
+
Subject of this conversation.
|
366
|
+
|
367
|
+
snippet
|
368
|
+
"Snippet", or preview of this conversation.
|
369
|
+
|
370
|
+
labels
|
371
|
+
Number-indexed Array. Name of labels that this conversation is bearing.
|
372
|
+
|
373
|
+
attachment
|
374
|
+
Number-indexed Array. Name of all attaching files of this conversation.
|
375
|
+
|
376
|
+
msgid
|
377
|
+
Message ID of the most recently received message of this conversation.
|
378
|
+
|
379
|
+
Example (to get the subject of 6-th conversation of current viewing box): snapshot.box[5]["subject"]
|
380
|
+
|
381
|
+
== Instance variables available to snapshot type: GM_CONVERSATION
|
382
|
+
conv_title
|
383
|
+
Subject (title) of this conversation.
|
384
|
+
|
385
|
+
conv_total
|
386
|
+
Total number of messages in this conversation.
|
387
|
+
|
388
|
+
conv_id
|
389
|
+
Conversation ID.
|
390
|
+
|
391
|
+
conv_labels
|
392
|
+
Number-indexed Array. Name of labels that this conversation is bearing.
|
393
|
+
|
394
|
+
conv_starred
|
395
|
+
Is the conversation starred? This is true if any of the messages of a conversation is starred.
|
396
|
+
|
397
|
+
conv
|
398
|
+
An array of messages of current conversation.
|
399
|
+
|
400
|
+
=== keys of each conversation
|
401
|
+
index
|
402
|
+
Index.
|
403
|
+
|
404
|
+
id
|
405
|
+
Message ID.
|
406
|
+
|
407
|
+
is_draft
|
408
|
+
Is draft or not.
|
409
|
+
|
410
|
+
draft_parent
|
411
|
+
Replying message ID of this draft.
|
412
|
+
|
413
|
+
sender
|
414
|
+
Name of sender of this message.
|
415
|
+
|
416
|
+
sender_email
|
417
|
+
Email address of the sender.
|
418
|
+
|
419
|
+
recv
|
420
|
+
Name of recevier of this message.
|
421
|
+
|
422
|
+
recv_email
|
423
|
+
Email address of the receiver.
|
424
|
+
|
425
|
+
reply_email
|
426
|
+
Replying address of this message.
|
427
|
+
|
428
|
+
cc_email
|
429
|
+
CC address of this message (draft).
|
430
|
+
|
431
|
+
bcc_email
|
432
|
+
BCC address of this message (draft).
|
433
|
+
|
434
|
+
dt_easy
|
435
|
+
Arrival date/time of this message in "easy" format, e.g. 9 Aug (2 days ago).
|
436
|
+
|
437
|
+
dt
|
438
|
+
Arrival date/time of this message in "long" format, e.g. Mon, 9 Aug 2004 19:34:03 +0800.
|
439
|
+
|
440
|
+
subject
|
441
|
+
Subject of this message.
|
442
|
+
|
443
|
+
is_starred
|
444
|
+
Is the message starred?
|
445
|
+
|
446
|
+
snippet
|
447
|
+
"Snippet", or preview of this message.
|
448
|
+
|
449
|
+
body
|
450
|
+
Message body.
|
451
|
+
|
452
|
+
attachment
|
453
|
+
An array of attachment-information.
|
454
|
+
|
455
|
+
=== keys of each attachment
|
456
|
+
id
|
457
|
+
Attachment ID.
|
458
|
+
|
459
|
+
filename
|
460
|
+
Filename of this attching file.
|
461
|
+
|
462
|
+
type
|
463
|
+
File type (e.g. JPG, GIF, PDF) of this attaching file.
|
464
|
+
|
465
|
+
size
|
466
|
+
Size in bytes of this file.
|
467
|
+
Example: snapshot.conv[3]["attachment"][1]["size"] (size of the 2nd attaching file
|
468
|
+
of the 4th messages of current conversation)
|
469
|
+
|
470
|
+
== Instance variables available to snapshot type: GM_CONTACT
|
471
|
+
contacts
|
472
|
+
An array of entries of your address book.
|
473
|
+
|
474
|
+
=== keys of each contact
|
475
|
+
name
|
476
|
+
Name (nickname).
|
477
|
+
|
478
|
+
email
|
479
|
+
Email address.
|
480
|
+
|
481
|
+
notes
|
482
|
+
Notes.
|
483
|
+
|
484
|
+
|
485
|
+
== Requirement
|
486
|
+
net/https
|
487
|
+
|
488
|
+
== Acknowledgements
|
489
|
+
This class was originally based on the libgmaier for PHP module by
|
490
|
+
Y.H.Gan (http://gmail-lite.sourceforge.net/)
|
491
|
+
|
492
|
+
== To Do
|
493
|
+
Proxy Setting
|
494
|
+
|
495
|
+
== Known Bugs
|
496
|
+
None that I know of. Please log any other bug reports on the RubyForge
|
497
|
+
project page at http://rubyforge.org/projects/gmailutils
|
498
|
+
|
499
|
+
== License
|
500
|
+
Ruby's
|
501
|
+
|
502
|
+
== Copyright
|
503
|
+
(C) 2005 Park Heesob, All Rights Reserved
|
504
|
+
|
505
|
+
== Warranty
|
506
|
+
This package is provided "as is" and without any express or
|
507
|
+
implied warranties, including, without limitation, the implied
|
508
|
+
warranties of merchantability and fitness for a particular purpose.
|
509
|
+
|
510
|
+
== Authors
|
511
|
+
Park Heesob
|
512
|
+
phasis at gmail dot com
|
513
|
+
phasis68 on IRC (freenode)
|
metadata
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.10
|
3
|
+
specification_version: 1
|
4
|
+
name: gmailer
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.5
|
7
|
+
date: 2005-08-29
|
8
|
+
summary: "An class interface of the Google's webmail service"
|
9
|
+
require_paths:
|
10
|
+
- ''
|
11
|
+
email: phasis_AT_gmail.com
|
12
|
+
homepage: http://rubyforge.org/projects/gmailutils
|
13
|
+
rubyforge_project:
|
14
|
+
description: "An class interface of the Google's webmail service"
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
authors:
|
28
|
+
- Park Heesob
|
29
|
+
files:
|
30
|
+
- CHANGES
|
31
|
+
- CVS
|
32
|
+
- MANIFEST
|
33
|
+
- README
|
34
|
+
test_files: []
|
35
|
+
rdoc_options: []
|
36
|
+
extra_rdoc_files:
|
37
|
+
- README
|
38
|
+
- CHANGES
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
requirements: []
|
42
|
+
dependencies: []
|