~ubuntu-branches/ubuntu/trusty/unity-china-music-scope/trusty

« back to all changes in this revision

Viewing changes to src/musicbaidu-search.vala

  • Committer: Package Import Robot
  • Author(s): whzhang-kylin
  • Date: 2012-12-13 09:29:34 UTC
  • Revision ID: package-import@ubuntu.com-20121213092934-0z4qywr7i1fp6nsy
Tags: upstream-1.0.0
Import upstream version 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2012 Kylin Ltd
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License version 3 as
 
6
 * published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authored by Weihua Zhang <fly2high@126.com>
 
17
 * Authored by liuxing <liuxingcs@yeah.net>
 
18
 * Modified Information: 
 
19
 * 1. Add is_in_China to decide wether you are in China 
 
20
 * 2. Add MusicBaiduCollection.collection function to search China music from music.baidu.com
 
21
 */
 
22
 
 
23
/*
 
24
 * Copyright (C) 2011 Canonical Ltd
 
25
 *
 
26
 * This program is free software: you can redistribute it and/or modify
 
27
 * it under the terms of the GNU General Public License version 3 as
 
28
 * published by the Free Software Foundation.
 
29
 *
 
30
 * This program is distributed in the hope that it will be useful,
 
31
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
32
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
33
 * GNU General Public License for more details.
 
34
 *
 
35
 * You should have received a copy of the GNU General Public License
 
36
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
37
 *
 
38
 * Authored by Alex Launi <alex.launi@canonical.com>
 
39
 *
 
40
 */
 
41
 
 
42
using GLib;
 
43
 
 
44
 
 
45
namespace Unity.MusicLens
 
46
{
 
47
 
 
48
public class MusicBaiduCollection : Object
 
49
{
 
50
 
 
51
    private const string MUSICBAIDU_BASE_URI = "http://music.baidu.com/search/";
 
52
    private static string IS_IN_CHINA = "Unknown";
 
53
    private const string ASK_IP_SERVER_URI_ONE = "http://ip.chinaz.com/";
 
54
    private const string ASK_IP_SERVER_URI_TWO = "http://www.123myip.co.uk/";
 
55
 
 
56
    const string SONG_MISSING_ICON_PATH = "/usr/share/unity/themes/baidu_song_missing.png";
 
57
 
 
58
 
 
59
    public MusicBaiduCollection ()
 
60
    {
 
61
 
 
62
    }
 
63
 
 
64
    private  bool is_in_China (Cancellable? cancellable = null)
 
65
    {
 
66
 
 
67
        if(IS_IN_CHINA == "Unknown")
 
68
        {
 
69
 
 
70
 
 
71
            File file = File.new_for_uri (ASK_IP_SERVER_URI_ONE);
 
72
 
 
73
 
 
74
            uint8[] data;
 
75
            string content;
 
76
            string etag_out;
 
77
 
 
78
            
 
79
            if( file.load_contents(cancellable, out data, out etag_out))
 
80
            {
 
81
 
 
82
                //Convert uint8[] to string.
 
83
                content = (string) data;
 
84
 
 
85
                var location =  content.index_of("北京") + content.index_of("上海") + content.index_of("天津") + content.index_of("重庆") +
 
86
                                content.index_of("黑龙江") + content.index_of("吉林") + content.index_of("辽宁") + content.index_of("江苏") +
 
87
                                content.index_of("山东") + content.index_of("安徽") + content.index_of("河北") + content.index_of("河南") +
 
88
                                content.index_of("湖北") + content.index_of("湖南") + content.index_of("江西") + content.index_of("陕西") +
 
89
                                content.index_of("山西") + content.index_of("四川") + content.index_of("青海") + content.index_of("海南") +
 
90
                                content.index_of("广东") + content.index_of("贵州") + content.index_of("浙江") + content.index_of("福建") +
 
91
                                content.index_of("台湾") + content.index_of("甘肃") + content.index_of("云南") + content.index_of("内蒙古") +
 
92
                                content.index_of("宁夏") +content.index_of("新疆") + content.index_of("西藏") + content.index_of("广西") +
 
93
                                content.index_of("香港") + content.index_of("澳门");
 
94
 
 
95
 
 
96
 
 
97
                if(location <0 )
 
98
                {
 
99
                    //if ASK_IP_SERVER_URI_ONE server reposended failed,ask ASK_IP_SERVER_URI_TWO server. 
 
100
                    file = File.new_for_uri (ASK_IP_SERVER_URI_TWO);
 
101
 
 
102
                    try
 
103
                    {
 
104
 
 
105
                        if( file.load_contents(cancellable, out data, out etag_out))
 
106
                        {
 
107
 
 
108
                            //Convert uint8[] to string.
 
109
                            content = (string) data;
 
110
 
 
111
                            location =  content.index_of("China") ;
 
112
                            if(location > 0 )
 
113
                            {
 
114
                                IS_IN_CHINA = "Yes";
 
115
                                return true;
 
116
                            }
 
117
                        }
 
118
 
 
119
                    }
 
120
                    catch (Error e)
 
121
                    {
 
122
                        warning ("Error reading URL '%s': %s", file.get_uri (), e.message);
 
123
                    }
 
124
                }
 
125
                else
 
126
                {
 
127
                    IS_IN_CHINA = "Yes";
 
128
                    return true;
 
129
 
 
130
                }
 
131
 
 
132
            }
 
133
 
 
134
        }
 
135
        else
 
136
        {
 
137
            return true;
 
138
        }
 
139
 
 
140
        return false;
 
141
    }
 
142
 
 
143
 
 
144
    public async void search (LensSearch search, SearchType search_type,
 
145
                              owned List<FilterParser> filters, int max_results = -1, Cancellable cancellable) throws IOError
 
146
    {
 
147
        File song_file;
 
148
        File album_file;
 
149
        uint8[] song_data;
 
150
        uint8[] album_data;
 
151
        string uri;
 
152
        string etag_out;
 
153
 
 
154
        if(!is_in_China(cancellable))
 
155
        {
 
156
            warning("Error can not search music from Baidu !");
 
157
            return;
 
158
        }
 
159
 
 
160
        try {
 
161
            //Search the first page song from Baidu music
 
162
            uri = build_search_uri(search.search_string, filters, 0, 0);
 
163
            if(uri != null)
 
164
            {
 
165
                song_file = File.new_for_uri (uri);
 
166
                if(yield song_file.load_contents_async(cancellable, out song_data, out etag_out))
 
167
                    read_song_search_result_from_Baidu(search,song_data);
 
168
            }
 
169
            //Search the next page song from Baidu music
 
170
            uri = build_search_uri(search.search_string, filters, 0, 1);
 
171
            if(uri != null)
 
172
            {
 
173
                song_file = File.new_for_uri (uri);
 
174
                if(yield song_file.load_contents_async(cancellable, out song_data, out etag_out))
 
175
                    read_song_search_result_from_Baidu(search,song_data);
 
176
            }
 
177
 
 
178
            //Search the first page album from Baidu music 
 
179
            uri = build_search_uri(search.search_string, filters, 1, 0);
 
180
            if(uri != null)
 
181
            {
 
182
                album_file = File.new_for_uri (uri);
 
183
                if(yield album_file.load_contents_async(cancellable, out album_data, out etag_out))
 
184
                    read_album_search_result_from_Baidu(search,album_data);
 
185
            }
 
186
            //Search the next page album from Baidu music
 
187
            uri = build_search_uri(search.search_string, filters, 1, 1);
 
188
            if(uri != null)
 
189
            {
 
190
                album_file = File.new_for_uri (uri);
 
191
                if(yield album_file.load_contents_async(cancellable, out album_data, out etag_out))
 
192
                    read_album_search_result_from_Baidu(search,album_data);
 
193
            }
 
194
 
 
195
        }
 
196
        catch (Error e)
 
197
        {
 
198
            warning ("Error getting result from baidu: %s(Failed to Search music from Baidu)!", e.message);
 
199
        }
 
200
 
 
201
    }
 
202
 
 
203
    public void get_song_details (string uri, out Album album,out SList<Track> tracks,Cancellable? cancellable = null)
 
204
    {
 
205
 
 
206
        album = new Album ();
 
207
        tracks = new SList<Track> ();
 
208
        File song_file;
 
209
        uint8[] song_data;
 
210
        string http_uri = uri.substring (7);// strip off "song://" from the uri
 
211
        string etag_out;
 
212
 
 
213
 
 
214
        try
 
215
        {
 
216
 
 
217
            if(http_uri != null)
 
218
            {
 
219
                song_file = File.new_for_uri (http_uri);
 
220
                if(song_file.load_contents(cancellable, out song_data, out etag_out))
 
221
                {
 
222
 
 
223
 
 
224
                    string content;
 
225
                    //Convert uint8[] to string.
 
226
                    content = (string) song_data;
 
227
 
 
228
                    //Parse the contents to get results.
 
229
                    
 
230
                    var iIndex = content.index_of("<div class=\"song");
 
231
                    if( iIndex == -1)
 
232
                        return;
 
233
 
 
234
                    var iEnd = content.index_of("</div>");
 
235
                    string song_name = content.substring(iIndex, iEnd-iIndex);
 
236
                    iIndex=-1;
 
237
                    iEnd=-1;
 
238
                    iIndex = song_name.index_of("name") + 6;
 
239
                    iEnd = song_name.substring(iIndex).index_of("</span>");
 
240
                    if( iIndex == -1)
 
241
                        return;
 
242
 
 
243
                    album.title = song_name.substring(iIndex, iEnd);
 
244
                    //Maybe song name append like this '审批文号:WJXXXXX',so must deal with.
 
245
                    iEnd = album.title.index_of("审批文号");
 
246
                    if( iEnd != -1)
 
247
                        album.title = album.title.substring(0,iEnd);
 
248
 
 
249
 
 
250
                    iIndex=-1;
 
251
                    iEnd=-1;
 
252
                    iIndex = content.index_of("<span class=\"author_list");
 
253
                    if( iIndex == -1)
 
254
                        return;
 
255
 
 
256
                    iEnd = content.index_of("</span>");
 
257
                    content = content.substring(iIndex, iEnd-iIndex);
 
258
                    iIndex=-1;
 
259
                    iEnd=-1;
 
260
                    iIndex = content.index_of("title=") + 7;
 
261
                    iEnd = content.substring(iIndex).index_of("\"");
 
262
                    if( iIndex == -1)
 
263
                        return;
 
264
                    album.artist = content.substring(iIndex,iEnd);
 
265
 
 
266
                    //Because song icon_hint in Baidu no exist,so set SONG_MISSING_ICON_PATH.
 
267
                    album.artwork_path = SONG_MISSING_ICON_PATH;
 
268
                    
 
269
                    album.uri = uri;
 
270
 
 
271
                    var track = new Track ();
 
272
                    track.uri = uri;
 
273
                    track.title = album.title ;
 
274
                    tracks.append (track);
 
275
 
 
276
 
 
277
                }
 
278
            }
 
279
        }
 
280
        catch (Error e)
 
281
        {
 
282
            warning ("Error fetching details for '%s': %s", uri, e.message);
 
283
        }
 
284
 
 
285
    }
 
286
 
 
287
    public void get_album_details(string uri, out Album album, out SList<Track> tracks,Cancellable? cancellable = null)
 
288
    {
 
289
        album = new Album ();
 
290
        tracks = new SList<Track> ();
 
291
        File song_file;
 
292
        uint8[] song_data;
 
293
        string http_uri = uri.substring (8);// strip off "album://" from the uri
 
294
 
 
295
        string etag_out;
 
296
 
 
297
 
 
298
        try
 
299
        {
 
300
 
 
301
            if(http_uri != null)
 
302
            {
 
303
                song_file = File.new_for_uri (http_uri);
 
304
                if(song_file.load_contents(cancellable, out song_data, out etag_out))
 
305
                {
 
306
 
 
307
 
 
308
                    string content;
 
309
                    //Convert uint8[] to string.
 
310
                    content = (string) song_data;
 
311
 
 
312
                    //Parse the contents to get results.
 
313
                    string album_content=content;
 
314
 
 
315
                   
 
316
                    var iIndex = album_content.index_of("<div class=\"album-info");
 
317
                    if( iIndex == -1)
 
318
                        return;
 
319
 
 
320
                    var iEnd = album_content.substring(iIndex).index_of("</li>");
 
321
                    album_content = album_content.substring(iIndex, iEnd+5);
 
322
                    iIndex=-1;
 
323
                    iEnd=-1;
 
324
                    
 
325
                    iIndex = album_content.index_of("img src=") + 9;
 
326
                    iEnd = album_content.substring(iIndex).index_of("\"");
 
327
                    if( iIndex == -1)
 
328
                        return;
 
329
 
 
330
                    album.artwork_path = album_content.substring(iIndex,iEnd);
 
331
                    album_content= album_content.substring(iIndex);
 
332
 
 
333
                    
 
334
                    iIndex = album_content.index_of("album-name") + 12;
 
335
                    iEnd = album_content.substring(iIndex).index_of("</h2>");
 
336
                    if( iIndex == -1)
 
337
                        return;
 
338
                    album.title = album_content.substring(iIndex, iEnd);
 
339
                    
 
340
                    iIndex = album_content.index_of("title=") + 7;
 
341
                    iEnd = album_content.substring(iIndex).index_of("\"");
 
342
                    if( iIndex == -1)
 
343
                        return;
 
344
                    album.artist = album_content.substring(iIndex,iEnd);
 
345
 
 
346
                    iIndex=-1;
 
347
                    iEnd=-1;
 
348
                    iIndex = content.index_of("<li  data-songitem");
 
349
                    if( iIndex == -1)
 
350
                        return;
 
351
 
 
352
                    iEnd = content.last_index_of("<li  data-songitem");
 
353
                    content = content.substring(iIndex, iEnd+3500- iIndex);
 
354
                    List<string> lilist = new List<string> ();
 
355
                    var liIndex = content.index_of("</li>");
 
356
                    while(liIndex != -1)
 
357
                    {
 
358
                        lilist.append(content.substring(0,liIndex));
 
359
                        content = content.substring(liIndex+5);
 
360
                        liIndex = content.index_of("</li>");
 
361
                    }
 
362
 
 
363
                    
 
364
                    //Get album information.
 
365
                    foreach (string li in lilist)
 
366
                    {
 
367
                        //Get album uri.
 
368
                        iIndex = li.index_of("/song");
 
369
                        iEnd = li.substring(iIndex).index_of("\"");
 
370
                        if(iIndex==-1||iEnd==-1)
 
371
                            continue;
 
372
 
 
373
                        var track = new Track ();
 
374
                        //FIXME drag n drop uri needs to be the song:// link
 
375
                        track.uri = string.join("","song://http://music.baidu.com",li.substring(iIndex, iEnd));
 
376
                       
 
377
                        //Get album title.
 
378
                        li = li.substring(iIndex);
 
379
                        iIndex = li.index_of("title=") + 7;
 
380
                        iEnd = li.substring(iIndex).index_of("\"");
 
381
                        track.title = li.substring(iIndex,iEnd);
 
382
                        //Maybe song name append like this '审批文号:WJXXXXX',so must deal with.
 
383
                        iEnd = track.title.index_of("审批文号");
 
384
                        if( iEnd != -1)
 
385
                            track.title = track.title.substring(0,iEnd);
 
386
 
 
387
                        tracks.append (track);
 
388
                    }
 
389
 
 
390
                }
 
391
            }
 
392
        }
 
393
        catch (Error e)
 
394
        {
 
395
            warning ("Error fetching details for '%s': %s", uri, e.message);
 
396
        }
 
397
 
 
398
    }
 
399
 
 
400
 
 
401
 
 
402
    private void  read_song_search_result_from_Baidu(LensSearch search, uint8[] data)
 
403
    {
 
404
        var results_model = search.results_model;
 
405
 
 
406
            Track track = new Track ();
 
407
            string content;
 
408
            //Convert uint8[] to string)
 
409
            content = (string) data;
 
410
            //Parse the contents to get results
 
411
            var iIndex = content.index_of("<li data-songitem");
 
412
            if( iIndex == -1)
 
413
                return;
 
414
            var iEnd = content.last_index_of("<li data-songitem");
 
415
            content = content.substring(iIndex, iEnd+3500- iIndex);
 
416
 
 
417
            List<string> lilist = new List<string> ();
 
418
            var liIndex = content.index_of("</li>");
 
419
            while(liIndex != -1)
 
420
            {
 
421
                lilist.append(content.substring(0,liIndex));
 
422
                content = content.substring(liIndex+5);
 
423
                liIndex = content.index_of("</li>");
 
424
            }
 
425
 
 
426
            //Get song information.
 
427
            foreach (string li in lilist)
 
428
            {
 
429
                iIndex = li.index_of("/song");
 
430
                iEnd = li.substring(iIndex).index_of("\"");
 
431
                if(iIndex==-1||iEnd==-1)
 
432
                    continue;
 
433
                //FIXME drag n drop uri needs to be the song:// link
 
434
                track.uri = string.join("","song://http://music.baidu.com",li.substring(iIndex, iEnd));
 
435
                
 
436
                li = li.substring(iIndex);
 
437
                iIndex = li.index_of("title=") + 7;
 
438
                iEnd = li.substring(iIndex).index_of("\"");
 
439
                track.title = li.substring(iIndex,iEnd);
 
440
                //Maybe song name append like this '审批文号:WJXXXXX',so must deal with.
 
441
                iEnd = track.title.index_of("审批文号");
 
442
                if( iEnd != -1)
 
443
                    track.title = track.title.substring(0,iEnd);
 
444
                
 
445
                li = li.substring(iIndex);
 
446
                iIndex = li.index_of("title=") + 7;
 
447
                iEnd = li.substring(iIndex).index_of("\"");
 
448
                track.artist = li.substring(iIndex,iEnd);
 
449
 
 
450
                li = li.substring(iIndex);
 
451
                //Maybe song album no exist,so get album name between ">"  and "<".
 
452
                //Get album-title from behind the second ">".
 
453
                iIndex = li.index_of("album-title");
 
454
                li = li.substring(iIndex);
 
455
                li = li.substring(li.index_of(">")+1);
 
456
                iIndex = li.index_of(">") + 1;
 
457
                iEnd = li.substring(iIndex).index_of("<");
 
458
                var albumMaybe = li.substring(iIndex,iEnd);
 
459
                li = li.substring(iIndex);
 
460
                if(albumMaybe == null)
 
461
                {
 
462
                    iIndex = li.index_of(">") + 1;
 
463
                    iEnd = li.substring(iIndex).index_of("</span>");
 
464
                    track.album = li.substring(iIndex,iEnd);
 
465
                    li = li.substring(iIndex);
 
466
                }
 
467
                else
 
468
                    track.album = albumMaybe;
 
469
                
 
470
                var comment = string.join("",track.artist,track.album);
 
471
              
 
472
                //Because song icon_hint in Baidu no exist,so add SONG_MISSING_ICON_PATH. 
 
473
                var icon_hint = SONG_MISSING_ICON_PATH;
 
474
 
 
475
                if(track.title.up().index_of(search.search_string.up()) != -1)
 
476
                {
 
477
                    results_model.append (
 
478
                        track.uri,
 
479
                        icon_hint,
 
480
                        0,
 
481
                        "text/html",
 
482
                        track.title,
 
483
                        comment,
 
484
                        track.uri);
 
485
                }
 
486
            }
 
487
    }
 
488
 
 
489
    private void read_album_search_result_from_Baidu(LensSearch search, uint8[] data)
 
490
    {
 
491
        var results_model = search.results_model;
 
492
        Album album = new Album ();
 
493
 
 
494
        string content;
 
495
        //Convert uint8[] to string.
 
496
        content = (string) data;
 
497
        //Parse the contents to get results.
 
498
       
 
499
        //Get album icon_hint. 
 
500
        var iIndex = content.index_of("<img org_src=");
 
501
        if(iIndex == -1)
 
502
            return;
 
503
        var iEnd = content.last_index_of("<img org_src=");
 
504
        content = content.substring(iIndex,iEnd+3200-iIndex);
 
505
        List<string> lilist = new List<string> ();
 
506
        var liIndex = content.index_of("</li>");
 
507
        while(liIndex != -1)
 
508
        {
 
509
            lilist.append(content.substring(0,liIndex));
 
510
            content = content.substring(liIndex+5);
 
511
            liIndex = content.index_of("</li>");
 
512
        }
 
513
        
 
514
        //Get album information.
 
515
        foreach (string li in lilist)
 
516
        {
 
517
            //Get album uri.    
 
518
            iIndex = li.index_of("img org_src=") + 13;
 
519
            iEnd = li.substring(iIndex).index_of("\"");
 
520
            var icon_hint = li.substring(iIndex,iEnd);
 
521
            li = li.substring(iIndex);
 
522
            
 
523
            iIndex = li.index_of("/album");
 
524
            iEnd = li.substring(iIndex).index_of("\"");
 
525
            // no found album
 
526
            if(iIndex==-1||iEnd==-1)
 
527
                continue;
 
528
 
 
529
            //FIXME drag n drop uri needs to be the u1ms:// link.
 
530
            album.uri = string.join("","album://http://music.baidu.com",li.substring(iIndex,iEnd));
 
531
            li = li.substring(iIndex);
 
532
           
 
533
            //Get album title.
 
534
            iIndex = li.index_of("title=") + 7;
 
535
            iEnd = li.substring(iIndex).index_of("\"");
 
536
            album.title = li.substring(iIndex, iEnd);
 
537
            //Maybe album title append like this '审批文号:WJXXXXX',so must deal with.
 
538
            iEnd = album.title.index_of("审批文号");
 
539
            if(iIndex != -1)
 
540
            {
 
541
                album.title = album.title.substring(0,iEnd);
 
542
            }
 
543
            li = li.substring(iIndex);
 
544
           
 
545
            //Get album artist. 
 
546
            iIndex = li.index_of("title=") + 7;
 
547
            iEnd = li.substring(iIndex).index_of("\"");
 
548
            album.artist = li.substring(iIndex,iEnd);
 
549
            li = li.substring(iIndex);
 
550
            
 
551
            if(album.title.up().index_of(search.search_string.up()) != -1)
 
552
            {
 
553
                results_model.append (album.uri,
 
554
                                      icon_hint,
 
555
                                      1,
 
556
                                      "audio-x-generic",
 
557
                                      album.title,
 
558
                                      album.artist,
 
559
                                      album.uri);
 
560
            }
 
561
        }
 
562
    }
 
563
 
 
564
    /*
 
565
       * Index = 0, songs
 
566
       * Indes = 1, albums
 
567
    */
 
568
    private string? build_search_uri (string query, List<FilterParser> filters, int index, int page)
 
569
    {
 
570
 
 
571
        if(query.strip() == "")
 
572
            return null;
 
573
 
 
574
        string musicbaidu_base_uri = MUSICBAIDU_BASE_URI;
 
575
        if (GLib.Environment.get_variable("MUSICBAIDU_URI") != null)
 
576
            musicbaidu_base_uri = GLib.Environment.get_variable("MUSICBAIDU_URI");
 
577
 
 
578
        StringBuilder uri = new StringBuilder (musicbaidu_base_uri);
 
579
        if (index == 0)
 
580
            uri.append ("song?key=");
 
581
        else
 
582
            uri.append ("album?key=");
 
583
 
 
584
        //add query key
 
585
        uri.append (Uri.escape_string (query, "", false));
 
586
 
 
587
        //TODO: add filters of Chinese music
 
588
        // no implement.
 
589
 
 
590
        //At this moment, Baidu doesn't release API for filter and more search results
 
591
        //20 results each time
 
592
        if(page < 0)
 
593
        {
 
594
            uri.append ("&start=0&size=20");
 
595
        }
 
596
        else
 
597
        {
 
598
            string? str="";
 
599
            str = "&start=%d&size=20".printf(page*20);
 
600
            uri.append(str);
 
601
        }
 
602
 
 
603
        return uri.str;
 
604
    }
 
605
}
 
606
 
 
607
}