69 const SERVICE_ERROR_ACCOUNT_BLOCKED = 100; |
68 const SERVICE_ERROR_ACCOUNT_BLOCKED = 100; |
70 |
69 |
71 /** |
70 /** |
72 * Slide share Web service communication URIs |
71 * Slide share Web service communication URIs |
73 */ |
72 */ |
74 const SERVICE_UPLOAD_URI = 'http://www.slideshare.net/api/1/upload_slideshow'; |
73 const SERVICE_UPLOAD_URI = 'https://www.slideshare.net/api/2/upload_slideshow'; |
75 const SERVICE_GET_SHOW_URI = 'http://www.slideshare.net/api/1/get_slideshow'; |
74 const SERVICE_GET_SHOW_URI = 'https://www.slideshare.net/api/2/get_slideshow'; |
76 const SERVICE_GET_SHOW_BY_USER_URI = 'http://www.slideshare.net/api/1/get_slideshow_by_user'; |
75 const SERVICE_GET_SHOW_BY_USER_URI = 'https://www.slideshare.net/api/2/get_slideshows_by_user'; |
77 const SERVICE_GET_SHOW_BY_TAG_URI = 'http://www.slideshare.net/api/1/get_slideshow_by_tag'; |
76 const SERVICE_GET_SHOW_BY_TAG_URI = 'https://www.slideshare.net/api/2/get_slideshows_by_tag'; |
78 const SERVICE_GET_SHOW_BY_GROUP_URI = 'http://www.slideshare.net/api/1/get_slideshows_from_group'; |
77 const SERVICE_GET_SHOW_BY_GROUP_URI = 'https://www.slideshare.net/api/2/get_slideshows_by_group'; |
79 |
78 |
80 /** |
79 /** |
81 * The MIME type of Slideshow files |
80 * The MIME type of Slideshow files |
82 * |
81 * |
83 */ |
82 */ |
84 const POWERPOINT_MIME_TYPE = "application/vnd.ms-powerpoint"; |
83 const POWERPOINT_MIME_TYPE = "application/vnd.ms-powerpoint"; |
85 |
84 |
86 /** |
85 /** |
87 * The API key to use in requests |
86 * The API key to use in requests |
88 * |
87 * |
89 * @var string The API key |
88 * @var string The API key |
281 } |
291 } |
282 |
292 |
283 /** |
293 /** |
284 * The Constructor |
294 * The Constructor |
285 * |
295 * |
286 * @param string $apikey The API key |
296 * @param string $apikey The API key |
287 * @param string $sharedSecret The shared secret |
297 * @param string $sharedSecret The shared secret |
288 * @param string $username The username |
298 * @param string $username The username |
289 * @param string $password The password |
299 * @param string $password The password |
290 */ |
300 */ |
291 public function __construct($apikey, $sharedSecret, $username = null, $password = null) |
301 public function __construct( |
|
302 $apikey, $sharedSecret, $username = null, $password = null |
|
303 ) |
292 { |
304 { |
293 $this->setApiKey($apikey) |
305 $this->setApiKey($apikey) |
294 ->setSharedSecret($sharedSecret) |
306 ->setSharedSecret($sharedSecret) |
295 ->setUserName($username) |
307 ->setUserName($username) |
296 ->setPassword($password); |
308 ->setPassword($password); |
297 |
309 |
298 $this->_httpclient = new Zend_Http_Client(); |
310 $this->_httpclient = new Zend_Http_Client(); |
299 } |
311 } |
300 |
312 |
301 /** |
313 /** |
302 * Uploads the specified Slide show the the server |
314 * Uploads the specified Slide show the the server |
303 * |
315 * |
304 * @param Zend_Service_SlideShare_SlideShow $ss The slide show object representing the slide show to upload |
316 * @param Zend_Service_SlideShare_SlideShow $ss The slide show object representing the slide show to upload |
305 * @param boolean $make_src_public Determines if the the slide show's source file is public or not upon upload |
317 * @param boolean $makeSrcPublic Determines if the the slide show's source file is public or not upon upload |
306 * @return Zend_Service_SlideShare_SlideShow The passed Slide show object, with the new assigned ID provided |
318 * @return Zend_Service_SlideShare_SlideShow The passed Slide show object, with the new assigned ID provided |
307 */ |
319 * @throws Zend_Service_SlideShare_Exception |
308 public function uploadSlideShow(Zend_Service_SlideShare_SlideShow $ss, $make_src_public = true) |
320 */ |
309 { |
321 public function uploadSlideShow( |
310 |
322 Zend_Service_SlideShare_SlideShow $ss, $makeSrcPublic = true |
|
323 ) |
|
324 { |
311 $timestamp = time(); |
325 $timestamp = time(); |
312 |
326 |
313 $params = array('api_key' => $this->getApiKey(), |
327 $params = array( |
314 'ts' => $timestamp, |
328 'api_key' => $this->getApiKey(), |
315 'hash' => sha1($this->getSharedSecret().$timestamp), |
329 'ts' => $timestamp, |
316 'username' => $this->getUserName(), |
330 'hash' => sha1($this->getSharedSecret() . $timestamp), |
317 'password' => $this->getPassword(), |
331 'username' => $this->getUserName(), |
318 'slideshow_title' => $ss->getTitle()); |
332 'password' => $this->getPassword(), |
|
333 'slideshow_title' => $ss->getTitle() |
|
334 ); |
319 |
335 |
320 $description = $ss->getDescription(); |
336 $description = $ss->getDescription(); |
321 $tags = $ss->getTags(); |
337 $tags = $ss->getTags(); |
322 |
338 |
323 $filename = $ss->getFilename(); |
339 $filename = $ss->getFilename(); |
324 |
340 |
325 if(!file_exists($filename) || !is_readable($filename)) { |
341 if (!file_exists($filename) || !is_readable($filename)) { |
326 require_once 'Zend/Service/SlideShare/Exception.php'; |
342 require_once 'Zend/Service/SlideShare/Exception.php'; |
327 throw new Zend_Service_SlideShare_Exception("Specified Slideshow for upload not found or unreadable"); |
343 throw new Zend_Service_SlideShare_Exception( |
328 } |
344 'Specified Slideshow for upload not found or unreadable' |
329 |
345 ); |
330 if(!empty($description)) { |
346 } |
|
347 |
|
348 if (!empty($description)) { |
331 $params['slideshow_description'] = $description; |
349 $params['slideshow_description'] = $description; |
332 } else { |
350 } else { |
333 $params['slideshow_description'] = ""; |
351 $params['slideshow_description'] = ""; |
334 } |
352 } |
335 |
353 |
336 if(!empty($tags)) { |
354 if (!empty($tags)) { |
337 $tmp = array(); |
355 $tmp = array(); |
338 foreach($tags as $tag) { |
356 foreach ($tags as $tag) { |
339 $tmp[] = "\"$tag\""; |
357 $tmp[] = "\"$tag\""; |
340 } |
358 } |
341 $params['slideshow_tags'] = implode(' ', $tmp); |
359 $params['slideshow_tags'] = implode(' ', $tmp); |
342 } else { |
360 } else { |
343 $params['slideshow_tags'] = ""; |
361 $params['slideshow_tags'] = ""; |
344 } |
362 } |
345 |
|
346 |
363 |
347 $client = $this->getHttpClient(); |
364 $client = $this->getHttpClient(); |
348 $client->setUri(self::SERVICE_UPLOAD_URI); |
365 $client->setUri(self::SERVICE_UPLOAD_URI); |
349 $client->setParameterPost($params); |
366 $client->setParameterPost($params); |
350 $client->setFileUpload($filename, "slideshow_srcfile"); |
367 $client->setFileUpload($filename, "slideshow_srcfile"); |
351 |
368 |
352 require_once 'Zend/Http/Client/Exception.php'; |
369 require_once 'Zend/Http/Client/Exception.php'; |
353 try { |
370 try { |
354 $response = $client->request('POST'); |
371 $response = $client->request('POST'); |
355 } catch(Zend_Http_Client_Exception $e) { |
372 } catch (Zend_Http_Client_Exception $e) { |
356 require_once 'Zend/Service/SlideShare/Exception.php'; |
373 require_once 'Zend/Service/SlideShare/Exception.php'; |
357 throw new Zend_Service_SlideShare_Exception("Service Request Failed: {$e->getMessage()}", 0, $e); |
374 throw new Zend_Service_SlideShare_Exception( |
|
375 "Service Request Failed: {$e->getMessage()}", 0, $e |
|
376 ); |
358 } |
377 } |
359 |
378 |
360 $sxe = simplexml_load_string($response->getBody()); |
379 $sxe = simplexml_load_string($response->getBody()); |
361 |
380 |
362 if($sxe->getName() == "SlideShareServiceError") { |
381 if ($sxe->getName() == "SlideShareServiceError") { |
363 $message = (string)$sxe->Message[0]; |
382 $message = (string)$sxe->Message[0]; |
364 list($code, $error_str) = explode(':', $message); |
383 list($code, $error_str) = explode(':', $message); |
365 require_once 'Zend/Service/SlideShare/Exception.php'; |
384 require_once 'Zend/Service/SlideShare/Exception.php'; |
366 throw new Zend_Service_SlideShare_Exception(trim($error_str), $code); |
385 throw new Zend_Service_SlideShare_Exception(trim( |
367 } |
386 $error_str |
368 |
387 ), $code); |
369 if(!$sxe->getName() == "SlideShowUploaded") { |
388 } |
|
389 |
|
390 if (!$sxe->getName() == "SlideShowUploaded") { |
370 require_once 'Zend/Service/SlideShare/Exception.php'; |
391 require_once 'Zend/Service/SlideShare/Exception.php'; |
371 throw new Zend_Service_SlideShare_Exception("Unknown XML Respons Received"); |
392 throw new Zend_Service_SlideShare_Exception( |
|
393 'Unknown XML Respons Received' |
|
394 ); |
372 } |
395 } |
373 |
396 |
374 $ss->setId((int)(string)$sxe->SlideShowID); |
397 $ss->setId((int)(string)$sxe->SlideShowID); |
375 |
398 |
376 return $ss; |
399 return $ss; |
379 /** |
402 /** |
380 * Retrieves a slide show's information based on slide show ID |
403 * Retrieves a slide show's information based on slide show ID |
381 * |
404 * |
382 * @param int $ss_id The slide show ID |
405 * @param int $ss_id The slide show ID |
383 * @return Zend_Service_SlideShare_SlideShow the Slideshow object |
406 * @return Zend_Service_SlideShare_SlideShow the Slideshow object |
|
407 * @throws Zend_Service_SlideShare_Exception |
384 */ |
408 */ |
385 public function getSlideShow($ss_id) |
409 public function getSlideShow($ss_id) |
386 { |
410 { |
387 $timestamp = time(); |
411 $timestamp = time(); |
388 |
412 |
389 $params = array('api_key' => $this->getApiKey(), |
413 $params = array( |
390 'ts' => $timestamp, |
414 'api_key' => $this->getApiKey(), |
391 'hash' => sha1($this->getSharedSecret().$timestamp), |
415 'ts' => $timestamp, |
392 'slideshow_id' => $ss_id); |
416 'hash' => sha1($this->getSharedSecret() . $timestamp), |
|
417 'slideshow_id' => $ss_id |
|
418 ); |
393 |
419 |
394 $cache = $this->getCacheObject(); |
420 $cache = $this->getCacheObject(); |
395 |
421 |
396 $cache_key = md5("__zendslideshare_cache_$ss_id"); |
422 $cache_key = md5("__zendslideshare_cache_$ss_id"); |
397 |
423 |
398 if(!$retval = $cache->load($cache_key)) { |
424 if (!$retval = $cache->load($cache_key)) { |
399 $client = $this->getHttpClient(); |
425 $client = $this->getHttpClient(); |
400 |
426 |
401 $client->setUri(self::SERVICE_GET_SHOW_URI); |
427 $client->setUri(self::SERVICE_GET_SHOW_URI); |
402 $client->setParameterPost($params); |
428 $client->setParameterPost($params); |
403 |
429 |
404 require_once 'Zend/Http/Client/Exception.php'; |
430 require_once 'Zend/Http/Client/Exception.php'; |
405 try { |
431 try { |
406 $response = $client->request('POST'); |
432 $response = $client->request('POST'); |
407 } catch(Zend_Http_Client_Exception $e) { |
433 } catch (Zend_Http_Client_Exception $e) { |
408 require_once 'Zend/Service/SlideShare/Exception.php'; |
434 require_once 'Zend/Service/SlideShare/Exception.php'; |
409 throw new Zend_Service_SlideShare_Exception("Service Request Failed: {$e->getMessage()}", 0, $e); |
435 throw new Zend_Service_SlideShare_Exception( |
|
436 "Service Request Failed: {$e->getMessage()}", 0, $e |
|
437 ); |
410 } |
438 } |
411 |
439 |
412 $sxe = simplexml_load_string($response->getBody()); |
440 $sxe = simplexml_load_string($response->getBody()); |
413 |
441 |
414 if($sxe->getName() == "SlideShareServiceError") { |
442 if ($sxe->getName() == "SlideShareServiceError") { |
415 $message = (string)$sxe->Message[0]; |
443 $message = (string)$sxe->Message[0]; |
416 list($code, $error_str) = explode(':', $message); |
444 list($code, $error_str) = explode(':', $message); |
417 require_once 'Zend/Service/SlideShare/Exception.php'; |
445 require_once 'Zend/Service/SlideShare/Exception.php'; |
418 throw new Zend_Service_SlideShare_Exception(trim($error_str), $code); |
446 throw new Zend_Service_SlideShare_Exception(trim( |
419 } |
447 $error_str |
420 |
448 ), $code); |
421 if(!$sxe->getName() == 'Slideshows') { |
449 } |
|
450 |
|
451 if (!($sxe->getName() == 'Slideshow')) { |
422 require_once 'Zend/Service/SlideShare/Exception.php'; |
452 require_once 'Zend/Service/SlideShare/Exception.php'; |
423 throw new Zend_Service_SlideShare_Exception('Unknown XML Repsonse Received'); |
453 throw new Zend_Service_SlideShare_Exception( |
424 } |
454 'Unknown XML Repsonse Received' |
425 |
455 ); |
426 $retval = $this->_slideShowNodeToObject(clone $sxe->Slideshow[0]); |
456 } |
|
457 $retval = $this->_slideShowNodeToObject(clone $sxe); |
427 |
458 |
428 $cache->save($retval, $cache_key); |
459 $cache->save($retval, $cache_key); |
429 } |
460 } |
430 |
461 |
431 return $retval; |
462 return $retval; |
482 |
517 |
483 /** |
518 /** |
484 * Retrieves Zend_Service_SlideShare_SlideShow object arrays based on the type of |
519 * Retrieves Zend_Service_SlideShare_SlideShow object arrays based on the type of |
485 * list desired |
520 * list desired |
486 * |
521 * |
487 * @param string $key The type of slide show object to retrieve |
522 * @param string $key The type of slide show object to retrieve |
488 * @param string $value The specific search query for the slide show type to look up |
523 * @param string $value The specific search query for the slide show type to look up |
489 * @param int $offset The offset of the list to start retrieving from |
524 * @param int $offset The offset of the list to start retrieving from |
490 * @param int $limit The maximum number of slide shows to retrieve |
525 * @param int $limit The maximum number of slide shows to retrieve |
491 * @return array An array of Zend_Service_SlideShare_SlideShow objects |
526 * @return array An array of Zend_Service_SlideShare_SlideShow objects |
|
527 * @throws Zend_Service_SlideShare_Exception |
492 */ |
528 */ |
493 protected function _getSlideShowsByType($key, $value, $offset = null, $limit = null) |
529 protected function _getSlideShowsByType($key, $value, $offset = null, $limit = null) |
494 { |
530 { |
495 |
|
496 $key = strtolower($key); |
531 $key = strtolower($key); |
497 |
532 |
498 switch($key) { |
533 switch ($key) { |
499 case 'username_for': |
534 case 'username_for': |
500 $responseTag = 'User'; |
535 $responseTag = 'User'; |
501 $queryUri = self::SERVICE_GET_SHOW_BY_USER_URI; |
536 $queryUri = self::SERVICE_GET_SHOW_BY_USER_URI; |
502 break; |
537 break; |
503 case 'group_name': |
538 case 'group_name': |
504 $responseTag = 'Group'; |
539 $responseTag = 'Group'; |
505 $queryUri = self::SERVICE_GET_SHOW_BY_GROUP_URI; |
540 $queryUri = self::SERVICE_GET_SHOW_BY_GROUP_URI; |
506 break; |
541 break; |
507 case 'tag': |
542 case 'tag': |
508 $responseTag = 'Tag'; |
543 $responseTag = 'Tag'; |
509 $queryUri = self::SERVICE_GET_SHOW_BY_TAG_URI; |
544 $queryUri = self::SERVICE_GET_SHOW_BY_TAG_URI; |
510 break; |
545 break; |
511 default: |
546 default: |
512 require_once 'Zend/Service/SlideShare/Exception.php'; |
547 require_once 'Zend/Service/SlideShare/Exception.php'; |
513 throw new Zend_Service_SlideShare_Exception("Invalid SlideShare Query"); |
548 throw new Zend_Service_SlideShare_Exception( |
|
549 'Invalid SlideShare Query' |
|
550 ); |
514 } |
551 } |
515 |
552 |
516 $timestamp = time(); |
553 $timestamp = time(); |
517 |
554 |
518 $params = array('api_key' => $this->getApiKey(), |
555 $params = array('api_key' => $this->getApiKey(), |
519 'ts' => $timestamp, |
556 'ts' => $timestamp, |
520 'hash' => sha1($this->getSharedSecret().$timestamp), |
557 'hash' => sha1($this->getSharedSecret().$timestamp), |
521 $key => $value); |
558 $key => $value); |
522 |
559 |
523 if($offset !== null) { |
560 if ($offset !== null) { |
524 $params['offset'] = (int)$offset; |
561 $params['offset'] = (int)$offset; |
525 } |
562 } |
526 |
563 |
527 if($limit !== null) { |
564 if ($limit !== null) { |
528 $params['limit'] = (int)$limit; |
565 $params['limit'] = (int)$limit; |
529 } |
566 } |
530 |
567 |
531 $cache = $this->getCacheObject(); |
568 $cache = $this->getCacheObject(); |
532 |
569 |
533 $cache_key = md5($key.$value.$offset.$limit); |
570 $cache_key = md5($key.$value.$offset.$limit); |
534 |
571 |
535 if(!$retval = $cache->load($cache_key)) { |
572 if (!$retval = $cache->load($cache_key)) { |
536 |
|
537 $client = $this->getHttpClient(); |
573 $client = $this->getHttpClient(); |
538 |
574 |
539 $client->setUri($queryUri); |
575 $client->setUri($queryUri); |
540 $client->setParameterPost($params); |
576 $client->setParameterPost($params); |
541 |
577 |
542 require_once 'Zend/Http/Client/Exception.php'; |
578 require_once 'Zend/Http/Client/Exception.php'; |
543 try { |
579 try { |
544 $response = $client->request('POST'); |
580 $response = $client->request('POST'); |
545 } catch(Zend_Http_Client_Exception $e) { |
581 } catch (Zend_Http_Client_Exception $e) { |
546 require_once 'Zend/Service/SlideShare/Exception.php'; |
582 require_once 'Zend/Service/SlideShare/Exception.php'; |
547 throw new Zend_Service_SlideShare_Exception("Service Request Failed: {$e->getMessage()}", 0, $e); |
583 throw new Zend_Service_SlideShare_Exception( |
|
584 "Service Request Failed: {$e->getMessage()}", 0, $e |
|
585 ); |
548 } |
586 } |
549 |
587 |
550 $sxe = simplexml_load_string($response->getBody()); |
588 $sxe = simplexml_load_string($response->getBody()); |
551 |
589 |
552 if($sxe->getName() == "SlideShareServiceError") { |
590 if ($sxe->getName() == "SlideShareServiceError") { |
553 $message = (string)$sxe->Message[0]; |
591 $message = (string)$sxe->Message[0]; |
554 list($code, $error_str) = explode(':', $message); |
592 list($code, $error_str) = explode(':', $message); |
555 require_once 'Zend/Service/SlideShare/Exception.php'; |
593 require_once 'Zend/Service/SlideShare/Exception.php'; |
556 throw new Zend_Service_SlideShare_Exception(trim($error_str), $code); |
594 throw new Zend_Service_SlideShare_Exception( |
557 } |
595 trim($error_str), $code |
558 |
596 ); |
559 if(!$sxe->getName() == $responseTag) { |
597 } |
|
598 |
|
599 if (!$sxe->getName() == $responseTag) { |
560 require_once 'Zend/Service/SlideShare/Exception.php'; |
600 require_once 'Zend/Service/SlideShare/Exception.php'; |
561 throw new Zend_Service_SlideShare_Exception('Unknown or Invalid XML Repsonse Received'); |
601 throw new Zend_Service_SlideShare_Exception( |
|
602 'Unknown or Invalid XML Repsonse Received' |
|
603 ); |
562 } |
604 } |
563 |
605 |
564 $retval = array(); |
606 $retval = array(); |
565 |
607 |
566 foreach($sxe->children() as $node) { |
608 foreach ($sxe->children() as $node) { |
567 if($node->getName() == 'Slideshow') { |
609 if ($node->getName() == 'Slideshow') { |
568 $retval[] = $this->_slideShowNodeToObject($node); |
610 $retval[] = $this->_slideShowNodeToObject($node); |
569 } |
611 } |
570 } |
612 } |
571 |
613 |
572 $cache->save($retval, $cache_key); |
614 $cache->save($retval, $cache_key); |
579 * Converts a SimpleXMLElement object representing a response from the service |
621 * Converts a SimpleXMLElement object representing a response from the service |
580 * into a Zend_Service_SlideShare_SlideShow object |
622 * into a Zend_Service_SlideShare_SlideShow object |
581 * |
623 * |
582 * @param SimpleXMLElement $node The input XML from the slideshare.net service |
624 * @param SimpleXMLElement $node The input XML from the slideshare.net service |
583 * @return Zend_Service_SlideShare_SlideShow The resulting object |
625 * @return Zend_Service_SlideShare_SlideShow The resulting object |
|
626 * @throws Zend_Service_SlideShare_Exception |
584 */ |
627 */ |
585 protected function _slideShowNodeToObject(SimpleXMLElement $node) |
628 protected function _slideShowNodeToObject(SimpleXMLElement $node) |
586 { |
629 { |
587 |
630 |
588 if($node->getName() == 'Slideshow') { |
631 if($node->getName() == 'Slideshow') { |
589 |
|
590 $ss = new Zend_Service_SlideShare_SlideShow(); |
632 $ss = new Zend_Service_SlideShare_SlideShow(); |
591 |
633 |
592 $ss->setId((string)$node->ID); |
634 $ss->setId((string)$node->ID); |
593 $ss->setDescription((string)$node->Description); |
635 $ss->setDescription((string)$node->Description); |
594 $ss->setEmbedCode((string)$node->EmbedCode); |
636 $ss->setEmbedCode((string)$node->EmbedCode); |
595 $ss->setNumViews((string)$node->Views); |
637 $ss->setNumViews((string)$node->Views); |
596 $ss->setPermaLink((string)$node->Permalink); |
638 $ss->setPermaLink((string)$node->Permalink); |
597 $ss->setStatus((string)$node->Status); |
639 $ss->setStatus((string)$node->Status); |
598 $ss->setStatusDescription((string)$node->StatusDescription); |
640 $ss->setStatusDescription((string)$node->StatusDescription); |
599 |
641 |
600 foreach(explode(",", (string)$node->Tags) as $tag) { |
642 foreach (explode(",", (string)$node->Tags) as $tag) { |
601 |
643 if (!in_array($tag, $ss->getTags())) { |
602 if(!in_array($tag, $ss->getTags())) { |
|
603 $ss->addTag($tag); |
644 $ss->addTag($tag); |
604 } |
645 } |
605 } |
646 } |
606 |
647 |
607 $ss->setThumbnailUrl((string)$node->Thumbnail); |
648 $ss->setThumbnailUrl((string)$node->Thumbnail); |
608 $ss->setTitle((string)$node->Title); |
649 $ss->setTitle((string)$node->Title); |
609 $ss->setLocation((string)$node->Location); |
650 $ss->setLocation((string)$node->Location); |
610 $ss->setTranscript((string)$node->Transcript); |
651 $ss->setTranscript((string)$node->Transcript); |
611 |
652 |
612 return $ss; |
653 return $ss; |
613 |
|
614 } |
654 } |
615 |
655 |
616 require_once 'Zend/Service/SlideShare/Exception.php'; |
656 require_once 'Zend/Service/SlideShare/Exception.php'; |
617 throw new Zend_Service_SlideShare_Exception("Was not provided the expected XML Node for processing"); |
657 throw new Zend_Service_SlideShare_Exception( |
|
658 'Was not provided the expected XML Node for processing' |
|
659 ); |
618 } |
660 } |
619 } |
661 } |