OSDN Git Service

client is version0.4.23, added async logic for getJson.
authoritozyun <itozyun@gmail.com>
Thu, 19 Apr 2012 23:29:42 +0000 (08:29 +0900)
committeritozyun <itozyun@gmail.com>
Thu, 19 Apr 2012 23:29:42 +0000 (08:29 +0900)
app/assets/stylesheets/common.css
app/assets/stylesheets/work.css
app/views/layouts/application.html.erb
public/assets/common.js
public/assets/system.js
public/assets/work.js

index 515fcbc..5b12c93 100644 (file)
@@ -146,6 +146,8 @@ version: 2.7.0
                line-height:            1.4em;\r
                margin:                         0 2px 1em;\r
                text-shadow:            1px 1px 3px rgba(0, 0, 0, 0.6);\r
+               -moz-text-shadow:       1px 1px 3px rgba(0, 0, 0, 0.6);\r
+               -webkit-text-shadow:1px 1px 3px rgba(0, 0, 0, 0.6);\r
     }\r
 \r
        h3 {\r
@@ -238,12 +240,12 @@ version: 2.7.0
 /*  Loading\r
 --------------------------------------------------------------------------------------*/\r
        .loading {\r
-               background-image:               url( ../images/loading.gif);\r
+               background-image:               url( loading.gif);\r
                background-position:    50% 50%;\r
                background-repeat:              no-repeat;\r
        }\r
        .error {\r
-               background-image:               url( ../images/error.png);\r
+               background-image:               url( error.png);\r
                background-position:    50% 50%;\r
                background-repeat:              no-repeat;\r
        }\r
@@ -344,6 +346,8 @@ version: 2.7.0
                font-size:                              1.4em;\r
                font-weight:                    normal;\r
                text-shadow:                    1px 1px 3px rgba(0, 0, 0, 0.6);\r
+               -moz-text-shadow:               1px 1px 3px rgba(0, 0, 0, 0.6);\r
+               -webkit-text-shadow:    1px 1px 3px rgba(0, 0, 0, 0.6);\r
        }       \r
 \r
 /*  base-content-width\r
index dc5a515..5a8e9eb 100644 (file)
        \r
                /*  Image Group\r
                --------------------------------------------------------------------------------------*/\r
-                       #image-gruop-wrapper {\r
+                       #image-group-wrapper {\r
                                position:                       absolute;\r
                                top:                            0;\r
                                left:                           0;\r
                        }\r
-                               #image-icon-container {\r
+                               #image-group-icon-container {\r
                                        position:                       absolute;\r
                                        top:                            0;\r
                                        left:                           0;\r
                                        border:                         #fff solid;\r
                                        border-width:           0;                              \r
                                }\r
-                               #image-gruop-button {\r
-                                       width:                  200px;\r
-                                       position:               absolute;\r
-                                       left:                   0;\r
-                                       bottom:                 -40px;\r
-                                       _bottom:                0;\r
+                               #image-group-name {\r
+                                       padding:                        20px 0 10px 20px;\r
+                                       border-bottom:          1px solid #eee;\r
+                                       color:                          #eee;\r
+                                       font-size:                      20px;\r
+                                       line-height:            20px;\r
+                                       font-weight:            bold;\r
+                                       text-shadow:            1px 1px 3px #ccc;\r
+                                       -moz-text-shadow:       1px 1px 3px #ccc;\r
+                                       -webkit-text-shadow:1px 1px 3px #ccc;\r
+                                       box-shadow:                     0 4px 9px #333;\r
+                                       -moz-box-shadow:        0 4px 9px #333;\r
+                                       -webkit-box-shadow:     0 4px 9px #333;\r
                                }\r
-                               .image-gruop-item {\r
-                                       width:                  150px;\r
-                                       height:                 200px;\r
-                                       position:               absolute;\r
-                                       top:                    0;\r
-                                       left:                   0;\r
-                                       text-align:             center;\r
+                               #image-group-button {\r
+                                       width:                          200px;\r
+                                       position:                       absolute;\r
+                                       left:                           0;\r
+                                       bottom:                         -40px;\r
+                                       _bottom:                        0;\r
                                }\r
-                               .image-gruop-item .reversible-image-container {\r
-                                       width:                  150px;\r
-                                       height:                 200px;\r
+                               .image-group-item {\r
+                                       width:                          150px;\r
+                                       height:                         200px;\r
+                                       position:                       absolute;\r
+                                       top:                            0;\r
+                                       left:                           0;\r
+                                       text-align:                     center;\r
                                }\r
-                               .image-gruop-item .reversible-image-container img {\r
-                                       width:                  100%;\r
-                                       height:                 100%;\r
+                               .image-group-item .reversible-image-container {\r
+                                       width:                          150px;\r
+                                       height:                         200px;\r
                                }\r
-                               .image-gruop-item-title {\r
-                                       position:               absolute;\r
-                                       bottom:                 0;\r
-                                       left:                   0;\r
-                                       text-align:             center;\r
-                                       width:                  100%;\r
-                                       height:                 30px;\r
+                               .image-group-item .reversible-image-container img {\r
+                                       width:                          100%;\r
+                                       height:                         100%;\r
+                               }\r
+                               .image-group-item-title {\r
+                                       position:                       absolute;\r
+                                       bottom:                         0;\r
+                                       left:                           0;\r
+                                       text-align:                     center;\r
+                                       width:                          100%;\r
+                                       height:                         30px;\r
                                }\r
        \r
 \r
index ecde3d3..c9ef40a 100644 (file)
                                </div>\r
                        </script>\r
                        \r
-                       <script id="imageGruopItemTemplete" type="text/x-jquery-tmpl">\r
-                               <div class="image-gruop-item">\r
-                                       <div class="image-gruop-item-title">img-title</div>\r
+                       <script id="imageGroupItemTemplete" type="text/x-jquery-tmpl">\r
+                               <div class="image-group-item">\r
+                                       <div class="image-group-item-title">img-title</div>\r
                                </div>                          \r
                        </script>\r
                        \r
                </div>\r
 \r
        <!-- 画像グループから画像を選択 -->\r
-               <div id="image-gruop-wrapper">\r
-                       <div id="image-icon-container"></div>\r
-                       <div id="gruop-name-display">Group Name</div>\r
-                       <div id="image-gruop-button" class="button">close</div>\r
+               <div id="image-group-wrapper">\r
+                       <div id="image-group-icon-container"></div>\r
+                       <div id="image-group-name">Group Name</div>\r
+                       <div id="image-group-button" class="button">close</div>\r
                </div>\r
 \r
        <!-- 作家登録 -->\r
index 3ce68ba..1d6a8b5 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
  * pettanR common.js\r
- *   version 0.4.22\r
+ *   version 0.4.23\r
  * \r
  * author: itozyun\r
  */\r
index fea9d40..9ffc788 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * pettanR system.js
- *   version 0.4.22
+ *   version 0.4.23
  *   
  * author:
  *   itozyun
@@ -46,6 +46,8 @@ pettanr.file = ( function(){
        
        var REQUEST_CONTROLER = ( function(){
                var REQUEST_TICKET_RESISTER = [],
+                       currentTicket = null,
+                       currentData = null,
                        DATA_TYPE_ARRAY = 'json,xml,html,text'.split( ','),
                        DATA_IS_JSON = 0,
                        DATA_IS_XML = 1,
@@ -63,21 +65,34 @@ pettanr.file = ( function(){
                };
                
                function request(){
-                       if( REQUEST_TICKET_RESISTER.length === 0) return;
-                       var _ticket = REQUEST_TICKET_RESISTER.shift();
+                       if( currentTicket !== null ) return;
+                       currentTicket = REQUEST_TICKET_RESISTER.shift();
                        $.ajax({
-                               url:            _ticket.url,
-                               dataType:       _ticket.type,
-                               success:        function( _data){
-                                       _ticket.onLoad( _ticket.data, _data);
-                               },
-                               error:          function(){
-                                       ++numError;
-                                       _ticket.onError( _ticket.data);
-                               }
+                               url:            currentTicket.url,
+                               dataType:       currentTicket.type,
+                               success:        onSuccess,
+                               error:          onError
                        });
                }
+               function onSuccess( _data ){
+                       currentData = _data;
+                       window.setTimeout( asyncSuccess, 0 );
+               }
+                       function asyncSuccess(){
+                               currentTicket.onLoad( currentTicket.data, currentData );
+                               currentTicket = currentData = null;
+                               REQUEST_TICKET_RESISTER.length !== 0 && window.setTimeout( request, 0 );
+                       }
                
+               function onError(){
+                       ++numError;
+                       window.setTimeout( asyncError, 0 );
+               }
+                       function asyncError(){
+                               currentTicket.onError( currentTicket.data );
+                               currentTicket = null;
+                               REQUEST_TICKET_RESISTER.length !== 0 && window.setTimeout( request, 0 );
+                       }
                return {
                        getNumTask: function(){
                                return REQUEST_TICKET_RESISTER.length;
@@ -85,9 +100,9 @@ pettanr.file = ( function(){
                        getNumError: function(){
                                return numError;
                        },
-                       getJson: function( _data, _url, _onLoad, _onError){
+                       getJson: function( _data, _url, _onLoad, _onError ){
                                REQUEST_TICKET_RESISTER.push( new RequestTicketClass( DATA_IS_JSON, _data, _url, _onLoad, _onError));
-                               request();
+                               currentTicket === null && request();
                        }
                }
        })();
@@ -166,11 +181,11 @@ pettanr.file = ( function(){
                replace: function( _uid, _file, _newIndex){
                        
                },
-               addEventListener: function( FILEorNULL, _eventType, _callback){
+               addEventListener: function( FILEorNULL, _eventType, _callback ){
                        var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL;
                        EVENT_LISTENER_REGISTER.push( new FileEventTicketClass( _uid, _eventType, _callback));
                },
-               removeEventListener: function( FILEorNULL, _eventType, _callback){
+               removeEventListener: function( FILEorNULL, _eventType, _callback ){
                        var _uid = FILEorNULL instanceof FileClass ? FILEorNULL.getUID() : FILEorNULL,
                                _ticket;
                        for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i){
@@ -204,7 +219,31 @@ pettanr.file = ( function(){
                        }
                }
        }
-
+       
+       var AsyncEventDispatcher = ( function(){
+               var STACK_LIST = [];
+               
+               function dispatch(){
+                       var _stack = STACK_LIST.shift();
+                       _stack[ 0 ]( _stack[ 1 ], _stack[ 2 ], _stack[ 3 ], _stack[ 4 ] );
+                       
+                       while( _stack.length > 0 ){
+                               _stack.shift();
+                       }
+                       if( STACK_LIST.length !== 0 ){
+                               window.setTimeout( dispatch, 0 );
+                       }
+               }
+               return {
+                       addEvent: function( _callback, _eventType, _targetFile, _key, _value ){
+                               if( STACK_LIST.length === 0 ){
+                                       window.setTimeout( dispatch, 0 );
+                               }
+                               STACK_LIST.push( [ _callback, _eventType, _targetFile, _key, _value ] );
+                       }
+               }
+       })();
+       
        var TreeClass = function( rootFileData ){
                var PARENT_FILE_RESITER = [],
                        ACCESS = {
@@ -222,15 +261,15 @@ pettanr.file = ( function(){
                                _targetFile = e.targetFile,
                                _uid = _targetFile.getUID(),
                                _ticket, _type, _callback;
-                       for(var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
+                       for( var i=0, l = EVENT_LISTENER_REGISTER.length; i<l; ++i ){
                                _ticket = EVENT_LISTENER_REGISTER[ i ];
                                _type = _ticket.eventType;
                                _callback = _ticket.callBack;
                                if( _eventType === _type && _uid === _ticket.fileUID ){
-                                       _callback( _eventType, _targetFile, e.key, e.value );
+                                       AsyncEventDispatcher.addEvent( _callback, _eventType, _targetFile, e.key, e.value );
                                } else
                                if( _type === pettanr.file.TREE_EVENT.UPDATE && _eventType === pettanr.file.FILE_EVENT.GET_SEQENTIAL_FILES ){
-                                       _callback( _eventType, _targetFile );
+                                       AsyncEventDispatcher.addEvent( _callback, _eventType, _targetFile );
                                }
                        }
                }
@@ -1014,6 +1053,7 @@ pettanr.finder = ( function(){
                        } else {
                                elmBody.className = 'finder-body';
                        }
+                       
                        elmBody.style.height = bodyH + 'px';
                        
                        while( l < ICON_ARRAY.length){
@@ -1164,10 +1204,10 @@ pettanr.driver = ( function(){
                                        return _data.title;
                                } else
                                if( _type === pettanr.driver.FILE_TYPE.ARTIST ){
-                                       return [ _data.id , ':', _data.name, '画伯' ].join( '');
+                                       return [ _data.name, '画伯' ].join( '');
                                } else
                                if( _type === pettanr.driver.FILE_TYPE.AUTHOR ){
-                                       return [ _data.id , ':', _data.name, '先生' ].join( '');
+                                       return [ _data.name, '先生' ].join( '');
                                }
                                return _data.name;
                        },
@@ -1207,16 +1247,16 @@ pettanr.driver = ( function(){
                                        return 'cabinet file';
                                }
                                if( _type === pettanr.driver.FILE_TYPE.COMIC){
-                                       return 'comic file';
+                                       return 'comic file, id:' + _data.id;
                                }
                                if( _type === pettanr.driver.FILE_TYPE.PANEL){
                                        return [ _data.width, 'x', _data.height ].join( '' );
                                }
                                if( _type === pettanr.driver.FILE_TYPE.AUTHOR){
-                                       return 'author file';
+                                       return 'author file, id:' + _data.id;
                                }
                                if( _type === pettanr.driver.FILE_TYPE.ARTIST){
-                                       return [ 'Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
+                                       return [ 'id:', _data.id, ' Email:', _data.email || 'empty' , ', HP:', _data.homepage_url || 'empty' ].join( '' );
                                }
                                if( _type === pettanr.file.FILE_TYPE.FOLDER){
                                        return 'pettanR folder';
@@ -1554,6 +1594,9 @@ pettanr.driver = ( function(){
                _getAPI: function(){
                        return FileAPI;
                },
+               _getPictureRootData: function(){
+                       return FILE_DATA_PICTURE_ROOT;
+               },
                _getMyPicturesData: function(){
                        return FILE_DATA_MY_PICTURES_ROOT;
                },
@@ -1718,27 +1761,28 @@ pettanr.premiumSatge = pettanr.view.registerApplication( function(){
                instance = this,
                winW, winH,
                wrapX,
-               elmWrap = document.getElementById( 'image-gruop-wrapper' ),
-               elmContainer = document.getElementById( 'image-icon-container' ),
+               elmWrap = document.getElementById( 'image-group-wrapper' ),
+               elmContainer = document.getElementById( 'image-group-icon-container' ),
                containerW,
                containerH = pettanr.util.getElementSize( elmContainer ).height,                
                elmIconOrigin = ( function(){
                        var ret = document.createElement( 'div' ),
                                data = document.createElement( 'div' );
                        ret.appendChild( data );
-                       ret.className = 'image-gruop-item';
-                       data.className = 'image-gruop-item-title';
+                       ret.className = 'image-group-item';
+                       data.className = 'image-group-item-title';
                        return ret;
                })(),
                jqContainer,
                size = pettanr.util.getElementSize( elmIconOrigin ),
                itemW = size.width,
                itemH = size.height,
-               elmName = document.getElementById( 'gruop-name-display' ),
-               elmButton = document.getElementById( 'image-gruop-button' ),
+               elmName = document.getElementById( 'image-group-name' ),
+               elmButton = document.getElementById( 'image-group-button' ),
                buttonW = pettanr.util.getElementSize( elmButton ).width,
                //onUpdateFunction,
                _g_onUpdateFunction,
+               artistID = -1,
                onEnterInterval = null;
 
        elmButton.onclick = clickOK;
@@ -1749,7 +1793,7 @@ pettanr.premiumSatge = pettanr.view.registerApplication( function(){
 
        var ImageGroupIconClass = function( INDEX, file ){
                var elmIconWrap = elmIconOrigin.cloneNode( true ),
-                       elmIconTitle = pettanr.util.getElementsByClassName( elmIconWrap, 'image-gruop-item-title' )[ 0 ],
+                       elmIconTitle = pettanr.util.getElementsByClassName( elmIconWrap, 'image-group-item-title' )[ 0 ],
                        data = pettanr.driver._getAPI().getFileData( file ),
                        SRC = [ BASE_PATH, data.id, '.', data.ext ].join( ''),
                        LOW_SRC = data.filesize && data.filesize > LIMIT_FILESIZE ? [ THUMB_PATH, data.id, '.', data.ext ].join( '') : null,
@@ -1758,7 +1802,7 @@ pettanr.premiumSatge = pettanr.view.registerApplication( function(){
                        imgW, imgH;
                elmContainer.appendChild( elmIconWrap );
                elmIconWrap.style.left = ( INDEX * itemW ) + 'px';
-               elmIconTitle.appendChild( document.createTextNode( data.filesize + 'bytes' ));
+               elmIconTitle.appendChild( document.createTextNode( data.filesize + 'bytes' ) );
 
                function onImageLoad( url, _imgW, _imgH ){
                        if( reversibleImage === null) {
@@ -1783,32 +1827,14 @@ pettanr.premiumSatge = pettanr.view.registerApplication( function(){
                
                function onClick( e ){
                        if( _g_onUpdateFunction ) {
-                               //if( LOW_SRC === null){
-                                       window[ _g_onUpdateFunction]( data );
-                                       window[ _g_onUpdateFunction] = null;
-                               /*
-                               } else {
-                                       var _onLoad = pettanr.util.createGlobalFunc( [
-                                                       'function( url, w, h ){',
-                                                               'window["', _g_onUpdateFunction, '"]( url, w || ', data.width,',  h || ', data.height,');',
-                                                               'window["', _g_onUpdateFunction, '"] = null;',
-                                                       '}'
-                                               ].join( '')),
-                                               _onError = pettanr.util.createGlobalFunc( [
-                                                       'function( url){',
-                                                               'window["', _g_onUpdateFunction, '"]( url, ', data.width || 64 ,', ', data.height || 64,');',
-                                                               'window["', _g_onUpdateFunction, '"] = null;',
-                                                       '}'
-                                               ].join( ''));
-                                       pettanr.util.loadImage( SRC, window[ _onLoad], window[ _onError]);
-                                       window[ _onLoad] = window[ _onError] = undefined;
-                               }*/
+                               window[ _g_onUpdateFunction ]( data );
+                               window[ _g_onUpdateFunction ] = null;
                        }
                        pettanr.premiumSatge.shutdown();
                }
                
                this.onEnter = function(){
-                       if( onEnterFlag === true ) return;
+                       if( onEnterFlag === true || data === null ) return; // data === null : destroyed
                        reversibleImage = pettanr.image.createReversibleImage( LOW_SRC || SRC, itemW, itemH, onImageLoad );
                        elmIconWrap.appendChild( reversibleImage.elm );
                        onEnterFlag = true;
@@ -1828,7 +1854,7 @@ pettanr.premiumSatge = pettanr.view.registerApplication( function(){
                        _start = -wrapX /itemW -1,
                        _end = _start + winW /itemW +1;
                for( var i=0; i<l; ++i){
-                       _start < i && i < _end && ICON_ARRAY[ i].onEnter();
+                       _start < i && i < _end && setTimeout( ICON_ARRAY[ i ].onEnter, i * 100 );
                }
                onEnterInterval !== null && window.clearTimeout( onEnterInterval );
                onEnterInterval = null;
@@ -1843,12 +1869,31 @@ pettanr.premiumSatge = pettanr.view.registerApplication( function(){
                        jqContainer.css( { left: wrapX});
                        
                        onEnterInterval !== null && window.clearTimeout( onEnterInterval );
-                       onEnterInterval = window.setTimeout( onEnterShowImage, 500);
+                       onEnterInterval = window.setTimeout( onEnterShowImage, 500 );
                }
                //e.stopPropagation();
                return false;                   
        }
        
+       function drawIcons(){
+               while( ICON_ARRAY.length > 0 ){
+                       ICON_ARRAY.shift().destroy();
+               }
+               
+               var _index = ARTIST_ROOT_FILE.search( {
+                               id:   artistID,
+                               type: pettanr.driver.FILE_TYPE.ARTIST
+                       })[ 0 ],
+                       _artistFile = ARTIST_ROOT_FILE.getChildFileByIndex( _index );
+               if( _artistFile !== null ){
+                       for(var i=0, l=_artistFile.getChildFileLength(); i<l; ++i ){
+                               ICON_ARRAY.push( new ImageGroupIconClass( i, _artistFile.getChildFileByIndex( i ) ));
+                       }
+                       elmName.firstChild.data = _artistFile.getName();
+                       _artistFile.destroy();
+               }
+       }
+       
        /* grobal method */
        // this.rootElement = elmWrap;
        this.displayName = 'premiumStage';
@@ -1858,46 +1903,37 @@ pettanr.premiumSatge = pettanr.view.registerApplication( function(){
        this.MIN_HEIGHT  = 320;
        this.init = function(){
                jqContainer = $( elmContainer ).mousewheel( onMouseWheel );
+               
+               // よくない! 一時的な処理,,,
+               //var tree = pettanr.driver.createPictureTree();
+               //tree.addTreeEventListener( pettanr.file.TREE_EVENT.UPDATE, drawIcons );
+               
                delete instance.init;
        }
        this.onOpen = function( _windowW, _windowH, _ARTISTIDorFILE, _onUpdateFunction ){
                instance.init && instance.init();
                
-               var _data, _artistID = -1;
-               
                if( pettanr.driver.isPettanrFileInstance( _ARTISTIDorFILE ) === true ){
-                       _data = pettanr.driver._getAPI().getFileData( _ARTISTIDorFILE );
+                       var _data = pettanr.driver._getAPI().getFileData( _ARTISTIDorFILE );
                        if( _ARTISTIDorFILE.getType() === pettanr.driver.FILE_TYPE.ARTIST || pettanr.driver._getMyPicturesData() === _data ){
-                               _artistID = _data.id || -1;
+                               artistID = _data.id || -1;
                        }
                } else
                if( Type.isNumber( _ARTISTIDorFILE ) === true ){
-                       _artistID = _ARTISTIDorFILE;
+                       artistID = _ARTISTIDorFILE;
                }
                
                //onUpdateFunction = _onUpdateFunction;
                if( _onUpdateFunction ){
-                       _g_onUpdateFunction = pettanr.util.createGlobalFunction( _onUpdateFunction);
+                       _g_onUpdateFunction = pettanr.util.createGlobalFunction( _onUpdateFunction );
                } else {
                        _g_onUpdateFunction = null;
                }
                
-               var _index = ARTIST_ROOT_FILE.search( {
-                               id:   _artistID,
-                               type: pettanr.driver.FILE_TYPE.ARTIST
-                       } )[ 0 ],
-                       _artistFile = ARTIST_ROOT_FILE.getChildFileByIndex( _index ),
-                       i, l = 0;
-               if( _artistFile !== null ){
-                       for( i=0, l=_artistFile.getChildFileLength(); i<l; ++i ){
-                               ICON_ARRAY.push( new ImageGroupIconClass( i, _artistFile.getChildFileByIndex( i ) ));
-                       }
-                       elmName.firstChild.data = _artistFile.getName() + l;
-                       _artistFile.destroy();
-               }
+               drawIcons();
                
                wrapX = 0;
-               containerW = l * itemW;
+               containerW = ICON_ARRAY.length * itemW;
                
                winW = _windowW;
                winH = _windowH;
@@ -1905,8 +1941,6 @@ pettanr.premiumSatge = pettanr.view.registerApplication( function(){
                        h = _windowH > containerH ? containerH : _windowH,
                        MATH_FLOOR = Math.floor;
                
-               onEnterShowImage();
-               
                jqContainer.css( {
                        width:          w,
                        height:         0,
@@ -1915,7 +1949,7 @@ pettanr.premiumSatge = pettanr.view.registerApplication( function(){
                }).stop().animate( {
                        height:         h,
                        top:            MATH_FLOOR( _windowH /2 -h /2)
-               });
+               }, onEnterShowImage );
                
                elmButton.style.cssText = [
                        'left:', MATH_FLOOR( winW /2 - buttonW /2), 'px;',
index 733d313..7239a90 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
  * pettanR work.js\r
- *   version 0.4.22\r
+ *   version 0.4.23\r
  *   \r
  * author:\r
  *   itozyun\r